syndicate-2017/dist/syndicate.js

31772 lines
2.2 MiB
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Syndicate = f()}})(function(){var define,module,exports;return (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){
},{}],2:[function(require,module,exports){
(function (global){
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
/* eslint-disable no-proto */
'use strict'
var base64 = require('base64-js')
var ieee754 = require('ieee754')
var isArray = require('isarray')
exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50
/**
* 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+.
*
* Due to various browser bugs, sometimes the Object implementation will be used even
* when the browser supports typed arrays.
*
* Note:
*
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
* 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
* get the Object implementation, which is slower but behaves correctly.
*/
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
? global.TYPED_ARRAY_SUPPORT
: typedArraySupport()
/*
* Export kMaxLength after typed array support is determined.
*/
exports.kMaxLength = kMaxLength()
function typedArraySupport () {
try {
var arr = new Uint8Array(1)
arr.foo = function () { return 42 }
return arr.foo() === 42 && // typed array instances can be augmented
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
} catch (e) {
return false
}
}
function kMaxLength () {
return Buffer.TYPED_ARRAY_SUPPORT
? 0x7fffffff
: 0x3fffffff
}
function createBuffer (that, length) {
if (kMaxLength() < length) {
throw new RangeError('Invalid typed array length')
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = new Uint8Array(length)
that.__proto__ = Buffer.prototype
} else {
// Fallback: Return an object instance of the Buffer class
if (that === null) {
that = new Buffer(length)
}
that.length = length
}
return that
}
/**
* The Buffer constructor returns instances of `Uint8Array` that have their
* prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
* `Uint8Array`, so the returned instances will have all the node `Buffer` methods
* and the `Uint8Array` methods. Square bracket notation works as expected -- it
* returns a single octet.
*
* The `Uint8Array` prototype remains unmodified.
*/
function Buffer (arg, encodingOrOffset, length) {
if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
return new Buffer(arg, encodingOrOffset, length)
}
// Common case.
if (typeof arg === 'number') {
if (typeof encodingOrOffset === 'string') {
throw new Error(
'If encoding is specified then the first argument must be a string'
)
}
return allocUnsafe(this, arg)
}
return from(this, arg, encodingOrOffset, length)
}
Buffer.poolSize = 8192 // not used by this implementation
// TODO: Legacy, not needed anymore. Remove in next major version.
Buffer._augment = function (arr) {
arr.__proto__ = Buffer.prototype
return arr
}
function from (that, value, encodingOrOffset, length) {
if (typeof value === 'number') {
throw new TypeError('"value" argument must not be a number')
}
if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
return fromArrayBuffer(that, value, encodingOrOffset, length)
}
if (typeof value === 'string') {
return fromString(that, value, encodingOrOffset)
}
return fromObject(that, value)
}
/**
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
* if value is a number.
* Buffer.from(str[, encoding])
* Buffer.from(array)
* Buffer.from(buffer)
* Buffer.from(arrayBuffer[, byteOffset[, length]])
**/
Buffer.from = function (value, encodingOrOffset, length) {
return from(null, value, encodingOrOffset, length)
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
Buffer.prototype.__proto__ = Uint8Array.prototype
Buffer.__proto__ = Uint8Array
if (typeof Symbol !== 'undefined' && Symbol.species &&
Buffer[Symbol.species] === Buffer) {
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
Object.defineProperty(Buffer, Symbol.species, {
value: null,
configurable: true
})
}
}
function assertSize (size) {
if (typeof size !== 'number') {
throw new TypeError('"size" argument must be a number')
}
}
function alloc (that, size, fill, encoding) {
assertSize(size)
if (size <= 0) {
return createBuffer(that, size)
}
if (fill !== undefined) {
// Only pay attention to encoding if it's a string. This
// prevents accidentally sending in a number that would
// be interpretted as a start offset.
return typeof encoding === 'string'
? createBuffer(that, size).fill(fill, encoding)
: createBuffer(that, size).fill(fill)
}
return createBuffer(that, size)
}
/**
* Creates a new filled Buffer instance.
* alloc(size[, fill[, encoding]])
**/
Buffer.alloc = function (size, fill, encoding) {
return alloc(null, size, fill, encoding)
}
function allocUnsafe (that, size) {
assertSize(size)
that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) {
for (var i = 0; i < size; i++) {
that[i] = 0
}
}
return that
}
/**
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
* */
Buffer.allocUnsafe = function (size) {
return allocUnsafe(null, size)
}
/**
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
*/
Buffer.allocUnsafeSlow = function (size) {
return allocUnsafe(null, size)
}
function fromString (that, string, encoding) {
if (typeof encoding !== 'string' || encoding === '') {
encoding = 'utf8'
}
if (!Buffer.isEncoding(encoding)) {
throw new TypeError('"encoding" must be a valid string encoding')
}
var length = byteLength(string, encoding) | 0
that = createBuffer(that, length)
that.write(string, encoding)
return that
}
function fromArrayLike (that, array) {
var length = checked(array.length) | 0
that = createBuffer(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
function fromArrayBuffer (that, array, byteOffset, length) {
array.byteLength // this throws if `array` is not a valid ArrayBuffer
if (byteOffset < 0 || array.byteLength < byteOffset) {
throw new RangeError('\'offset\' is out of bounds')
}
if (array.byteLength < byteOffset + (length || 0)) {
throw new RangeError('\'length\' is out of bounds')
}
if (length === undefined) {
array = new Uint8Array(array, byteOffset)
} else {
array = new Uint8Array(array, byteOffset, length)
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = array
that.__proto__ = Buffer.prototype
} else {
// Fallback: Return an object instance of the Buffer class
that = fromArrayLike(that, array)
}
return that
}
function fromObject (that, obj) {
if (Buffer.isBuffer(obj)) {
var len = checked(obj.length) | 0
that = createBuffer(that, len)
if (that.length === 0) {
return that
}
obj.copy(that, 0, 0, len)
return that
}
if (obj) {
if ((typeof ArrayBuffer !== 'undefined' &&
obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
if (typeof obj.length !== 'number' || isnan(obj.length)) {
return createBuffer(that, 0)
}
return fromArrayLike(that, obj)
}
if (obj.type === 'Buffer' && isArray(obj.data)) {
return fromArrayLike(that, obj.data)
}
}
throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
}
function checked (length) {
// Note: cannot use `length < kMaxLength` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if (length >= kMaxLength()) {
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
'size: 0x' + kMaxLength().toString(16) + ' bytes')
}
return length | 0
}
function SlowBuffer (length) {
if (+length != length) { // eslint-disable-line eqeqeq
length = 0
}
return Buffer.alloc(+length)
}
Buffer.isBuffer = function isBuffer (b) {
return !!(b != null && b._isBuffer)
}
Buffer.compare = function compare (a, b) {
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
throw new TypeError('Arguments must be Buffers')
}
if (a === b) return 0
var x = a.length
var y = b.length
for (var i = 0, len = Math.min(x, y); i < len; ++i) {
if (a[i] !== b[i]) {
x = a[i]
y = b[i]
break
}
}
if (x < y) return -1
if (y < x) return 1
return 0
}
Buffer.isEncoding = function isEncoding (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 concat (list, length) {
if (!isArray(list)) {
throw new TypeError('"list" argument must be an Array of Buffers')
}
if (list.length === 0) {
return Buffer.alloc(0)
}
var i
if (length === undefined) {
length = 0
for (i = 0; i < list.length; i++) {
length += list[i].length
}
}
var buffer = Buffer.allocUnsafe(length)
var pos = 0
for (i = 0; i < list.length; i++) {
var buf = list[i]
if (!Buffer.isBuffer(buf)) {
throw new TypeError('"list" argument must be an Array of Buffers')
}
buf.copy(buffer, pos)
pos += buf.length
}
return buffer
}
function byteLength (string, encoding) {
if (Buffer.isBuffer(string)) {
return string.length
}
if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
(ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
return string.byteLength
}
if (typeof string !== 'string') {
string = '' + string
}
var len = string.length
if (len === 0) return 0
// Use a for loop to avoid recursion
var loweredCase = false
for (;;) {
switch (encoding) {
case 'ascii':
case 'binary':
// Deprecated
case 'raw':
case 'raws':
return len
case 'utf8':
case 'utf-8':
case undefined:
return utf8ToBytes(string).length
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return len * 2
case 'hex':
return len >>> 1
case 'base64':
return base64ToBytes(string).length
default:
if (loweredCase) return utf8ToBytes(string).length // assume utf8
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.byteLength = byteLength
function slowToString (encoding, start, end) {
var loweredCase = false
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
// property of a typed array.
// This behaves neither like String nor Uint8Array in that we set start/end
// to their upper/lower bounds if the value passed is out of range.
// undefined is handled specially as per ECMA-262 6th Edition,
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
if (start === undefined || start < 0) {
start = 0
}
// Return early if start > this.length. Done here to prevent potential uint32
// coercion fail below.
if (start > this.length) {
return ''
}
if (end === undefined || end > this.length) {
end = this.length
}
if (end <= 0) {
return ''
}
// Force coersion to uint32. This will also coerce falsey/NaN values to 0.
end >>>= 0
start >>>= 0
if (end <= start) {
return ''
}
if (!encoding) encoding = 'utf8'
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
}
}
}
// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
// Buffer instances.
Buffer.prototype._isBuffer = true
function swap (b, n, m) {
var i = b[n]
b[n] = b[m]
b[m] = i
}
Buffer.prototype.swap16 = function swap16 () {
var len = this.length
if (len % 2 !== 0) {
throw new RangeError('Buffer size must be a multiple of 16-bits')
}
for (var i = 0; i < len; i += 2) {
swap(this, i, i + 1)
}
return this
}
Buffer.prototype.swap32 = function swap32 () {
var len = this.length
if (len % 4 !== 0) {
throw new RangeError('Buffer size must be a multiple of 32-bits')
}
for (var i = 0; i < len; i += 4) {
swap(this, i, i + 3)
swap(this, i + 1, i + 2)
}
return this
}
Buffer.prototype.toString = function toString () {
var length = this.length | 0
if (length === 0) return ''
if (arguments.length === 0) return utf8Slice(this, 0, length)
return slowToString.apply(this, arguments)
}
Buffer.prototype.equals = function equals (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return true
return Buffer.compare(this, b) === 0
}
Buffer.prototype.inspect = function inspect () {
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 compare (target, start, end, thisStart, thisEnd) {
if (!Buffer.isBuffer(target)) {
throw new TypeError('Argument must be a Buffer')
}
if (start === undefined) {
start = 0
}
if (end === undefined) {
end = target ? target.length : 0
}
if (thisStart === undefined) {
thisStart = 0
}
if (thisEnd === undefined) {
thisEnd = this.length
}
if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
throw new RangeError('out of range index')
}
if (thisStart >= thisEnd && start >= end) {
return 0
}
if (thisStart >= thisEnd) {
return -1
}
if (start >= end) {
return 1
}
start >>>= 0
end >>>= 0
thisStart >>>= 0
thisEnd >>>= 0
if (this === target) return 0
var x = thisEnd - thisStart
var y = end - start
var len = Math.min(x, y)
var thisCopy = this.slice(thisStart, thisEnd)
var targetCopy = target.slice(start, end)
for (var i = 0; i < len; ++i) {
if (thisCopy[i] !== targetCopy[i]) {
x = thisCopy[i]
y = targetCopy[i]
break
}
}
if (x < y) return -1
if (y < x) return 1
return 0
}
function arrayIndexOf (arr, val, byteOffset, encoding) {
var indexSize = 1
var arrLength = arr.length
var valLength = val.length
if (encoding !== undefined) {
encoding = String(encoding).toLowerCase()
if (encoding === 'ucs2' || encoding === 'ucs-2' ||
encoding === 'utf16le' || encoding === 'utf-16le') {
if (arr.length < 2 || val.length < 2) {
return -1
}
indexSize = 2
arrLength /= 2
valLength /= 2
byteOffset /= 2
}
}
function read (buf, i) {
if (indexSize === 1) {
return buf[i]
} else {
return buf.readUInt16BE(i * indexSize)
}
}
var foundIndex = -1
for (var i = 0; byteOffset + i < arrLength; i++) {
if (read(arr, byteOffset + i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
if (foundIndex === -1) foundIndex = i
if (i - foundIndex + 1 === valLength) return (byteOffset + foundIndex) * indexSize
} else {
if (foundIndex !== -1) i -= i - foundIndex
foundIndex = -1
}
}
return -1
}
Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
if (typeof byteOffset === 'string') {
encoding = byteOffset
byteOffset = 0
} else if (byteOffset > 0x7fffffff) {
byteOffset = 0x7fffffff
} else if (byteOffset < -0x80000000) {
byteOffset = -0x80000000
}
byteOffset >>= 0
if (this.length === 0) return -1
if (byteOffset >= this.length) return -1
// Negative offsets start from the end of the buffer
if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
if (typeof val === 'string') {
val = Buffer.from(val, encoding)
}
if (Buffer.isBuffer(val)) {
// special case: looking for empty string/buffer always fails
if (val.length === 0) {
return -1
}
return arrayIndexOf(this, val, byteOffset, encoding)
}
if (typeof val === 'number') {
if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
}
return arrayIndexOf(this, [ val ], byteOffset, encoding)
}
throw new TypeError('val must be string, number or Buffer')
}
Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
return this.indexOf(val, byteOffset, encoding) !== -1
}
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 parsed = parseInt(string.substr(i * 2, 2), 16)
if (isNaN(parsed)) return i
buf[offset + i] = parsed
}
return i
}
function utf8Write (buf, string, offset, length) {
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
}
function asciiWrite (buf, string, offset, length) {
return blitBuffer(asciiToBytes(string), buf, offset, length)
}
function binaryWrite (buf, string, offset, length) {
return asciiWrite(buf, string, offset, length)
}
function base64Write (buf, string, offset, length) {
return blitBuffer(base64ToBytes(string), buf, offset, length)
}
function ucs2Write (buf, string, offset, length) {
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
}
Buffer.prototype.write = function write (string, offset, length, encoding) {
// Buffer#write(string)
if (offset === undefined) {
encoding = 'utf8'
length = this.length
offset = 0
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
encoding = offset
length = this.length
offset = 0
// Buffer#write(string, offset[, length][, encoding])
} else if (isFinite(offset)) {
offset = offset | 0
if (isFinite(length)) {
length = length | 0
if (encoding === undefined) encoding = 'utf8'
} else {
encoding = length
length = undefined
}
// legacy write(string, encoding, offset, length) - remove in v0.13
} else {
throw new Error(
'Buffer.write(string, encoding, offset[, length]) is no longer supported'
)
}
var remaining = this.length - offset
if (length === undefined || length > remaining) length = remaining
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
throw new RangeError('Attempt to write outside buffer bounds')
}
if (!encoding) encoding = 'utf8'
var loweredCase = false
for (;;) {
switch (encoding) {
case 'hex':
return hexWrite(this, string, offset, length)
case 'utf8':
case 'utf-8':
return utf8Write(this, string, offset, length)
case 'ascii':
return asciiWrite(this, string, offset, length)
case 'binary':
return binaryWrite(this, string, offset, length)
case 'base64':
// Warning: maxLength not taken into account in base64Write
return base64Write(this, string, offset, length)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return ucs2Write(this, string, offset, length)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.prototype.toJSON = function toJSON () {
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) {
end = Math.min(buf.length, end)
var res = []
var i = start
while (i < end) {
var firstByte = buf[i]
var codePoint = null
var bytesPerSequence = (firstByte > 0xEF) ? 4
: (firstByte > 0xDF) ? 3
: (firstByte > 0xBF) ? 2
: 1
if (i + bytesPerSequence <= end) {
var secondByte, thirdByte, fourthByte, tempCodePoint
switch (bytesPerSequence) {
case 1:
if (firstByte < 0x80) {
codePoint = firstByte
}
break
case 2:
secondByte = buf[i + 1]
if ((secondByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
if (tempCodePoint > 0x7F) {
codePoint = tempCodePoint
}
}
break
case 3:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
codePoint = tempCodePoint
}
}
break
case 4:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
fourthByte = buf[i + 3]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
codePoint = tempCodePoint
}
}
}
}
if (codePoint === null) {
// we did not generate a valid codePoint so insert a
// replacement char (U+FFFD) and advance only 1 byte
codePoint = 0xFFFD
bytesPerSequence = 1
} else if (codePoint > 0xFFFF) {
// encode to utf16 (surrogate pair dance)
codePoint -= 0x10000
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
codePoint = 0xDC00 | codePoint & 0x3FF
}
res.push(codePoint)
i += bytesPerSequence
}
return decodeCodePointsArray(res)
}
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000
function decodeCodePointsArray (codePoints) {
var len = codePoints.length
if (len <= MAX_ARGUMENTS_LENGTH) {
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
}
// Decode in chunks to avoid "call stack size exceeded".
var res = ''
var i = 0
while (i < len) {
res += String.fromCharCode.apply(
String,
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
)
}
return res
}
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 slice (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 = this.subarray(start, end)
newBuf.__proto__ = Buffer.prototype
} else {
var sliceLen = end - start
newBuf = new Buffer(sliceLen, undefined)
for (var i = 0; i < sliceLen; i++) {
newBuf[i] = this[i + start]
}
}
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 readUIntLE (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 readUIntBE (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 readUInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
return this[offset]
}
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return this[offset] | (this[offset + 1] << 8)
}
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return (this[offset] << 8) | this[offset + 1]
}
Buffer.prototype.readUInt32LE = function readUInt32LE (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 readUInt32BE (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 readIntLE (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 readIntBE (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 readInt8 (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 readInt16LE (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 readInt16BE (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 readInt32LE (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 readInt32BE (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 readFloatLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, true, 23, 4)
}
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, false, 23, 4)
}
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, true, 52, 8)
}
Buffer.prototype.readDoubleBE = function readDoubleBE (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" argument must be a Buffer instance')
if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
if (offset + ext > buf.length) throw new RangeError('Index out of range')
}
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1
checkInt(this, value, offset, byteLength, maxBytes, 0)
}
var mul = 1
var i = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1
checkInt(this, value, offset, byteLength, maxBytes, 0)
}
var i = byteLength - 1
var mul = 1
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUInt8 = function writeUInt8 (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 & 0xff)
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 writeUInt16LE (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 & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeUInt16BE = function writeUInt16BE (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 & 0xff)
} 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 writeUInt32LE (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 & 0xff)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeUInt32BE = function writeUInt32BE (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 & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = 0
var mul = 1
var sub = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
sub = 1
}
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = byteLength - 1
var mul = 1
var sub = 0
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
sub = 1
}
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeInt8 = function writeInt8 (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 & 0xff)
return offset + 1
}
Buffer.prototype.writeInt16LE = function writeInt16LE (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 & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeInt16BE = function writeInt16BE (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 & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
Buffer.prototype.writeInt32LE = function writeInt32LE (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 & 0xff)
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 writeInt32BE (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 & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
function checkIEEE754 (buf, value, offset, ext, max, min) {
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 writeFloatLE (value, offset, noAssert) {
return writeFloat(this, value, offset, true, noAssert)
}
Buffer.prototype.writeFloatBE = function writeFloatBE (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 writeDoubleLE (value, offset, noAssert) {
return writeDouble(this, value, offset, true, noAssert)
}
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
return writeDouble(this, value, offset, false, noAssert)
}
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
if (!start) start = 0
if (!end && end !== 0) end = this.length
if (targetStart >= target.length) targetStart = target.length
if (!targetStart) targetStart = 0
if (end > 0 && end < start) end = start
// Copy 0 bytes; we're done
if (end === start) return 0
if (target.length === 0 || this.length === 0) return 0
// Fatal error conditions
if (targetStart < 0) {
throw new RangeError('targetStart out of bounds')
}
if (start < 0 || start >= this.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 - targetStart < end - start) {
end = target.length - targetStart + start
}
var len = end - start
var i
if (this === target && start < targetStart && targetStart < end) {
// descending copy from end
for (i = len - 1; i >= 0; i--) {
target[i + targetStart] = this[i + start]
}
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
// ascending copy from start
for (i = 0; i < len; i++) {
target[i + targetStart] = this[i + start]
}
} else {
Uint8Array.prototype.set.call(
target,
this.subarray(start, start + len),
targetStart
)
}
return len
}
// Usage:
// buffer.fill(number[, offset[, end]])
// buffer.fill(buffer[, offset[, end]])
// buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill (val, start, end, encoding) {
// Handle string cases:
if (typeof val === 'string') {
if (typeof start === 'string') {
encoding = start
start = 0
end = this.length
} else if (typeof end === 'string') {
encoding = end
end = this.length
}
if (val.length === 1) {
var code = val.charCodeAt(0)
if (code < 256) {
val = code
}
}
if (encoding !== undefined && typeof encoding !== 'string') {
throw new TypeError('encoding must be a string')
}
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
throw new TypeError('Unknown encoding: ' + encoding)
}
} else if (typeof val === 'number') {
val = val & 255
}
// Invalid ranges are not set to a default, so can range check early.
if (start < 0 || this.length < start || this.length < end) {
throw new RangeError('Out of range index')
}
if (end <= start) {
return this
}
start = start >>> 0
end = end === undefined ? this.length : end >>> 0
if (!val) val = 0
var i
if (typeof val === 'number') {
for (i = start; i < end; i++) {
this[i] = val
}
} else {
var bytes = Buffer.isBuffer(val)
? val
: utf8ToBytes(new Buffer(val, encoding).toString())
var len = bytes.length
for (i = 0; i < end - start; i++) {
this[i + start] = bytes[i % len]
}
}
return this
}
// HELPER FUNCTIONS
// ================
var INVALID_BASE64_RE = /[^+\/0-9A-Za-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 toHex (n) {
if (n < 16) return '0' + n.toString(16)
return n.toString(16)
}
function utf8ToBytes (string, units) {
units = units || Infinity
var codePoint
var length = string.length
var leadSurrogate = null
var bytes = []
for (var i = 0; i < length; i++) {
codePoint = string.charCodeAt(i)
// is surrogate component
if (codePoint > 0xD7FF && codePoint < 0xE000) {
// last char was a lead
if (!leadSurrogate) {
// no lead yet
if (codePoint > 0xDBFF) {
// unexpected trail
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
} else if (i + 1 === length) {
// unpaired lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
}
// valid lead
leadSurrogate = codePoint
continue
}
// 2 leads in a row
if (codePoint < 0xDC00) {
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
leadSurrogate = codePoint
continue
}
// valid surrogate pair
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
} else if (leadSurrogate) {
// valid bmp char, but last char was a lead
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 < 0x110000) {
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) {
for (var i = 0; i < length; i++) {
if ((i + offset >= dst.length) || (i >= src.length)) break
dst[i + offset] = src[i]
}
return i
}
function isnan (val) {
return val !== val // eslint-disable-line no-self-compare
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"base64-js":3,"ieee754":4,"isarray":5}],3:[function(require,module,exports){
'use strict'
exports.toByteArray = toByteArray
exports.fromByteArray = fromByteArray
var lookup = []
var revLookup = []
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
function init () {
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
for (var i = 0, len = code.length; i < len; ++i) {
lookup[i] = code[i]
revLookup[code.charCodeAt(i)] = i
}
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63
}
init()
function toByteArray (b64) {
var i, j, l, tmp, placeHolders, arr
var len = b64.length
if (len % 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
placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
// base64 is 4/3 + up to two characters of the original data
arr = new Arr(len * 3 / 4 - placeHolders)
// if there are placeholders, only get up to the last complete 4 chars
l = placeHolders > 0 ? len - 4 : len
var L = 0
for (i = 0, j = 0; i < l; i += 4, j += 3) {
tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
arr[L++] = (tmp >> 16) & 0xFF
arr[L++] = (tmp >> 8) & 0xFF
arr[L++] = tmp & 0xFF
}
if (placeHolders === 2) {
tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
arr[L++] = tmp & 0xFF
} else if (placeHolders === 1) {
tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
arr[L++] = (tmp >> 8) & 0xFF
arr[L++] = tmp & 0xFF
}
return arr
}
function tripletToBase64 (num) {
return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
}
function encodeChunk (uint8, start, end) {
var tmp
var output = []
for (var i = start; i < end; i += 3) {
tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
output.push(tripletToBase64(tmp))
}
return output.join('')
}
function fromByteArray (uint8) {
var tmp
var len = uint8.length
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
var output = ''
var parts = []
var maxChunkLength = 16383 // must be multiple of 3
// go through the array every three bytes, we'll deal with trailing stuff later
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
}
// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 1) {
tmp = uint8[len - 1]
output += lookup[tmp >> 2]
output += lookup[(tmp << 4) & 0x3F]
output += '=='
} else if (extraBytes === 2) {
tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
output += lookup[tmp >> 10]
output += lookup[(tmp >> 4) & 0x3F]
output += lookup[(tmp << 2) & 0x3F]
output += '='
}
parts.push(output)
return parts.join('')
}
},{}],4:[function(require,module,exports){
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
var e, m
var eLen = nBytes * 8 - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var nBits = -7
var i = isLE ? (nBytes - 1) : 0
var d = isLE ? -1 : 1
var 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
var eLen = nBytes * 8 - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
var i = isLE ? 0 : (nBytes - 1)
var d = isLE ? 1 : -1
var 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
}
},{}],5:[function(require,module,exports){
var toString = {}.toString;
module.exports = Array.isArray || function (arr) {
return toString.call(arr) == '[object Array]';
};
},{}],6:[function(require,module,exports){
'use strict'
exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = require('randombytes')
exports.createHash = exports.Hash = require('create-hash')
exports.createHmac = exports.Hmac = require('create-hmac')
var hashes = ['sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'md5', 'rmd160'].concat(Object.keys(require('browserify-sign/algos')))
exports.getHashes = function () {
return hashes
}
var p = require('pbkdf2')
exports.pbkdf2 = p.pbkdf2
exports.pbkdf2Sync = p.pbkdf2Sync
var aes = require('browserify-cipher')
;[
'Cipher',
'createCipher',
'Cipheriv',
'createCipheriv',
'Decipher',
'createDecipher',
'Decipheriv',
'createDecipheriv',
'getCiphers',
'listCiphers'
].forEach(function (key) {
exports[key] = aes[key]
})
var dh = require('diffie-hellman')
;[
'DiffieHellmanGroup',
'createDiffieHellmanGroup',
'getDiffieHellman',
'createDiffieHellman',
'DiffieHellman'
].forEach(function (key) {
exports[key] = dh[key]
})
var sign = require('browserify-sign')
;[
'createSign',
'Sign',
'createVerify',
'Verify'
].forEach(function (key) {
exports[key] = sign[key]
})
exports.createECDH = require('create-ecdh')
var publicEncrypt = require('public-encrypt')
;[
'publicEncrypt',
'privateEncrypt',
'publicDecrypt',
'privateDecrypt'
].forEach(function (key) {
exports[key] = publicEncrypt[key]
})
// the least I can do is make error messages for the rest of the node.js/crypto api.
;[
'createCredentials'
].forEach(function (name) {
exports[name] = function () {
throw new Error([
'sorry, ' + name + ' is not implemented yet',
'we accept pull requests',
'https://github.com/crypto-browserify/crypto-browserify'
].join('\n'))
}
})
},{"browserify-cipher":7,"browserify-sign":37,"browserify-sign/algos":36,"create-ecdh":104,"create-hash":130,"create-hmac":143,"diffie-hellman":144,"pbkdf2":151,"public-encrypt":152,"randombytes":197}],7:[function(require,module,exports){
var ebtk = require('evp_bytestokey')
var aes = require('browserify-aes/browser')
var DES = require('browserify-des')
var desModes = require('browserify-des/modes')
var aesModes = require('browserify-aes/modes')
function createCipher (suite, password) {
var keyLen, ivLen
suite = suite.toLowerCase()
if (aesModes[suite]) {
keyLen = aesModes[suite].key
ivLen = aesModes[suite].iv
} else if (desModes[suite]) {
keyLen = desModes[suite].key * 8
ivLen = desModes[suite].iv
} else {
throw new TypeError('invalid suite type')
}
var keys = ebtk(password, false, keyLen, ivLen)
return createCipheriv(suite, keys.key, keys.iv)
}
function createDecipher (suite, password) {
var keyLen, ivLen
suite = suite.toLowerCase()
if (aesModes[suite]) {
keyLen = aesModes[suite].key
ivLen = aesModes[suite].iv
} else if (desModes[suite]) {
keyLen = desModes[suite].key * 8
ivLen = desModes[suite].iv
} else {
throw new TypeError('invalid suite type')
}
var keys = ebtk(password, false, keyLen, ivLen)
return createDecipheriv(suite, keys.key, keys.iv)
}
function createCipheriv (suite, key, iv) {
suite = suite.toLowerCase()
if (aesModes[suite]) {
return aes.createCipheriv(suite, key, iv)
} else if (desModes[suite]) {
return new DES({
key: key,
iv: iv,
mode: suite
})
} else {
throw new TypeError('invalid suite type')
}
}
function createDecipheriv (suite, key, iv) {
suite = suite.toLowerCase()
if (aesModes[suite]) {
return aes.createDecipheriv(suite, key, iv)
} else if (desModes[suite]) {
return new DES({
key: key,
iv: iv,
mode: suite,
decrypt: true
})
} else {
throw new TypeError('invalid suite type')
}
}
exports.createCipher = exports.Cipher = createCipher
exports.createCipheriv = exports.Cipheriv = createCipheriv
exports.createDecipher = exports.Decipher = createDecipher
exports.createDecipheriv = exports.Decipheriv = createDecipheriv
function getCiphers () {
return Object.keys(desModes).concat(aes.getCiphers())
}
exports.listCiphers = exports.getCiphers = getCiphers
},{"browserify-aes/browser":10,"browserify-aes/modes":14,"browserify-des":25,"browserify-des/modes":26,"evp_bytestokey":35}],8:[function(require,module,exports){
(function (Buffer){
// based on the aes implimentation in triple sec
// https://github.com/keybase/triplesec
// which is in turn based on the one from crypto-js
// https://code.google.com/p/crypto-js/
var uint_max = Math.pow(2, 32)
function fixup_uint32 (x) {
var ret, x_pos
ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x
return ret
}
function scrub_vec (v) {
for (var i = 0; i < v.length; v++) {
v[i] = 0
}
return false
}
function Global () {
this.SBOX = []
this.INV_SBOX = []
this.SUB_MIX = [[], [], [], []]
this.INV_SUB_MIX = [[], [], [], []]
this.init()
this.RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]
}
Global.prototype.init = function () {
var d, i, sx, t, x, x2, x4, x8, xi, _i
d = (function () {
var _i, _results
_results = []
for (i = _i = 0; _i < 256; i = ++_i) {
if (i < 128) {
_results.push(i << 1)
} else {
_results.push((i << 1) ^ 0x11b)
}
}
return _results
})()
x = 0
xi = 0
for (i = _i = 0; _i < 256; i = ++_i) {
sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4)
sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63
this.SBOX[x] = sx
this.INV_SBOX[sx] = x
x2 = d[x]
x4 = d[x2]
x8 = d[x4]
t = (d[sx] * 0x101) ^ (sx * 0x1010100)
this.SUB_MIX[0][x] = (t << 24) | (t >>> 8)
this.SUB_MIX[1][x] = (t << 16) | (t >>> 16)
this.SUB_MIX[2][x] = (t << 8) | (t >>> 24)
this.SUB_MIX[3][x] = t
t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100)
this.INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8)
this.INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16)
this.INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24)
this.INV_SUB_MIX[3][sx] = t
if (x === 0) {
x = xi = 1
} else {
x = x2 ^ d[d[d[x8 ^ x2]]]
xi ^= d[d[xi]]
}
}
return true
}
var G = new Global()
AES.blockSize = 4 * 4
AES.prototype.blockSize = AES.blockSize
AES.keySize = 256 / 8
AES.prototype.keySize = AES.keySize
function bufferToArray (buf) {
var len = buf.length / 4
var out = new Array(len)
var i = -1
while (++i < len) {
out[i] = buf.readUInt32BE(i * 4)
}
return out
}
function AES (key) {
this._key = bufferToArray(key)
this._doReset()
}
AES.prototype._doReset = function () {
var invKsRow, keySize, keyWords, ksRow, ksRows, t
keyWords = this._key
keySize = keyWords.length
this._nRounds = keySize + 6
ksRows = (this._nRounds + 1) * 4
this._keySchedule = []
for (ksRow = 0; ksRow < ksRows; ksRow++) {
this._keySchedule[ksRow] = ksRow < keySize ? keyWords[ksRow] : (t = this._keySchedule[ksRow - 1], (ksRow % keySize) === 0 ? (t = (t << 8) | (t >>> 24), t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff], t ^= G.RCON[(ksRow / keySize) | 0] << 24) : keySize > 6 && ksRow % keySize === 4 ? t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff] : void 0, this._keySchedule[ksRow - keySize] ^ t)
}
this._invKeySchedule = []
for (invKsRow = 0; invKsRow < ksRows; invKsRow++) {
ksRow = ksRows - invKsRow
t = this._keySchedule[ksRow - (invKsRow % 4 ? 0 : 4)]
this._invKeySchedule[invKsRow] = invKsRow < 4 || ksRow <= 4 ? t : G.INV_SUB_MIX[0][G.SBOX[t >>> 24]] ^ G.INV_SUB_MIX[1][G.SBOX[(t >>> 16) & 0xff]] ^ G.INV_SUB_MIX[2][G.SBOX[(t >>> 8) & 0xff]] ^ G.INV_SUB_MIX[3][G.SBOX[t & 0xff]]
}
return true
}
AES.prototype.encryptBlock = function (M) {
M = bufferToArray(new Buffer(M))
var out = this._doCryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX)
var buf = new Buffer(16)
buf.writeUInt32BE(out[0], 0)
buf.writeUInt32BE(out[1], 4)
buf.writeUInt32BE(out[2], 8)
buf.writeUInt32BE(out[3], 12)
return buf
}
AES.prototype.decryptBlock = function (M) {
M = bufferToArray(new Buffer(M))
var temp = [M[3], M[1]]
M[1] = temp[0]
M[3] = temp[1]
var out = this._doCryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX)
var buf = new Buffer(16)
buf.writeUInt32BE(out[0], 0)
buf.writeUInt32BE(out[3], 4)
buf.writeUInt32BE(out[2], 8)
buf.writeUInt32BE(out[1], 12)
return buf
}
AES.prototype.scrub = function () {
scrub_vec(this._keySchedule)
scrub_vec(this._invKeySchedule)
scrub_vec(this._key)
}
AES.prototype._doCryptBlock = function (M, keySchedule, SUB_MIX, SBOX) {
var ksRow, s0, s1, s2, s3, t0, t1, t2, t3
s0 = M[0] ^ keySchedule[0]
s1 = M[1] ^ keySchedule[1]
s2 = M[2] ^ keySchedule[2]
s3 = M[3] ^ keySchedule[3]
ksRow = 4
for (var round = 1; round < this._nRounds; round++) {
t0 = SUB_MIX[0][s0 >>> 24] ^ SUB_MIX[1][(s1 >>> 16) & 0xff] ^ SUB_MIX[2][(s2 >>> 8) & 0xff] ^ SUB_MIX[3][s3 & 0xff] ^ keySchedule[ksRow++]
t1 = SUB_MIX[0][s1 >>> 24] ^ SUB_MIX[1][(s2 >>> 16) & 0xff] ^ SUB_MIX[2][(s3 >>> 8) & 0xff] ^ SUB_MIX[3][s0 & 0xff] ^ keySchedule[ksRow++]
t2 = SUB_MIX[0][s2 >>> 24] ^ SUB_MIX[1][(s3 >>> 16) & 0xff] ^ SUB_MIX[2][(s0 >>> 8) & 0xff] ^ SUB_MIX[3][s1 & 0xff] ^ keySchedule[ksRow++]
t3 = SUB_MIX[0][s3 >>> 24] ^ SUB_MIX[1][(s0 >>> 16) & 0xff] ^ SUB_MIX[2][(s1 >>> 8) & 0xff] ^ SUB_MIX[3][s2 & 0xff] ^ keySchedule[ksRow++]
s0 = t0
s1 = t1
s2 = t2
s3 = t3
}
t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]
t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]
t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]
t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]
return [
fixup_uint32(t0),
fixup_uint32(t1),
fixup_uint32(t2),
fixup_uint32(t3)
]
}
exports.AES = AES
}).call(this,require("buffer").Buffer)
},{"buffer":2}],9:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
var GHASH = require('./ghash')
var xor = require('buffer-xor')
inherits(StreamCipher, Transform)
module.exports = StreamCipher
function StreamCipher (mode, key, iv, decrypt) {
if (!(this instanceof StreamCipher)) {
return new StreamCipher(mode, key, iv)
}
Transform.call(this)
this._finID = Buffer.concat([iv, new Buffer([0, 0, 0, 1])])
iv = Buffer.concat([iv, new Buffer([0, 0, 0, 2])])
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
this._cache = new Buffer('')
this._secCache = new Buffer('')
this._decrypt = decrypt
this._alen = 0
this._len = 0
iv.copy(this._prev)
this._mode = mode
var h = new Buffer(4)
h.fill(0)
this._ghash = new GHASH(this._cipher.encryptBlock(h))
this._authTag = null
this._called = false
}
StreamCipher.prototype._update = function (chunk) {
if (!this._called && this._alen) {
var rump = 16 - (this._alen % 16)
if (rump < 16) {
rump = new Buffer(rump)
rump.fill(0)
this._ghash.update(rump)
}
}
this._called = true
var out = this._mode.encrypt(this, chunk)
if (this._decrypt) {
this._ghash.update(chunk)
} else {
this._ghash.update(out)
}
this._len += chunk.length
return out
}
StreamCipher.prototype._final = function () {
if (this._decrypt && !this._authTag) {
throw new Error('Unsupported state or unable to authenticate data')
}
var tag = xor(this._ghash.final(this._alen * 8, this._len * 8), this._cipher.encryptBlock(this._finID))
if (this._decrypt) {
if (xorTest(tag, this._authTag)) {
throw new Error('Unsupported state or unable to authenticate data')
}
} else {
this._authTag = tag
}
this._cipher.scrub()
}
StreamCipher.prototype.getAuthTag = function getAuthTag () {
if (!this._decrypt && Buffer.isBuffer(this._authTag)) {
return this._authTag
} else {
throw new Error('Attempting to get auth tag in unsupported state')
}
}
StreamCipher.prototype.setAuthTag = function setAuthTag (tag) {
if (this._decrypt) {
this._authTag = tag
} else {
throw new Error('Attempting to set auth tag in unsupported state')
}
}
StreamCipher.prototype.setAAD = function setAAD (buf) {
if (!this._called) {
this._ghash.update(buf)
this._alen += buf.length
} else {
throw new Error('Attempting to set AAD in unsupported state')
}
}
function xorTest (a, b) {
var out = 0
if (a.length !== b.length) {
out++
}
var len = Math.min(a.length, b.length)
var i = -1
while (++i < len) {
out += (a[i] ^ b[i])
}
return out
}
}).call(this,require("buffer").Buffer)
},{"./aes":8,"./ghash":13,"buffer":2,"buffer-xor":22,"cipher-base":23,"inherits":199}],10:[function(require,module,exports){
var ciphers = require('./encrypter')
exports.createCipher = exports.Cipher = ciphers.createCipher
exports.createCipheriv = exports.Cipheriv = ciphers.createCipheriv
var deciphers = require('./decrypter')
exports.createDecipher = exports.Decipher = deciphers.createDecipher
exports.createDecipheriv = exports.Decipheriv = deciphers.createDecipheriv
var modes = require('./modes')
function getCiphers () {
return Object.keys(modes)
}
exports.listCiphers = exports.getCiphers = getCiphers
},{"./decrypter":11,"./encrypter":12,"./modes":14}],11:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
var modes = require('./modes')
var StreamCipher = require('./streamCipher')
var AuthCipher = require('./authCipher')
var ebtk = require('evp_bytestokey')
inherits(Decipher, Transform)
function Decipher (mode, key, iv) {
if (!(this instanceof Decipher)) {
return new Decipher(mode, key, iv)
}
Transform.call(this)
this._cache = new Splitter()
this._last = void 0
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
iv.copy(this._prev)
this._mode = mode
this._autopadding = true
}
Decipher.prototype._update = function (data) {
this._cache.add(data)
var chunk
var thing
var out = []
while ((chunk = this._cache.get(this._autopadding))) {
thing = this._mode.decrypt(this, chunk)
out.push(thing)
}
return Buffer.concat(out)
}
Decipher.prototype._final = function () {
var chunk = this._cache.flush()
if (this._autopadding) {
return unpad(this._mode.decrypt(this, chunk))
} else if (chunk) {
throw new Error('data not multiple of block length')
}
}
Decipher.prototype.setAutoPadding = function (setTo) {
this._autopadding = !!setTo
return this
}
function Splitter () {
if (!(this instanceof Splitter)) {
return new Splitter()
}
this.cache = new Buffer('')
}
Splitter.prototype.add = function (data) {
this.cache = Buffer.concat([this.cache, data])
}
Splitter.prototype.get = function (autoPadding) {
var out
if (autoPadding) {
if (this.cache.length > 16) {
out = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
return out
}
} else {
if (this.cache.length >= 16) {
out = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
return out
}
}
return null
}
Splitter.prototype.flush = function () {
if (this.cache.length) {
return this.cache
}
}
function unpad (last) {
var padded = last[15]
var i = -1
while (++i < padded) {
if (last[(i + (16 - padded))] !== padded) {
throw new Error('unable to decrypt data')
}
}
if (padded === 16) {
return
}
return last.slice(0, 16 - padded)
}
var modelist = {
ECB: require('./modes/ecb'),
CBC: require('./modes/cbc'),
CFB: require('./modes/cfb'),
CFB8: require('./modes/cfb8'),
CFB1: require('./modes/cfb1'),
OFB: require('./modes/ofb'),
CTR: require('./modes/ctr'),
GCM: require('./modes/ctr')
}
function createDecipheriv (suite, password, iv) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
if (typeof iv === 'string') {
iv = new Buffer(iv)
}
if (typeof password === 'string') {
password = new Buffer(password)
}
if (password.length !== config.key / 8) {
throw new TypeError('invalid key length ' + password.length)
}
if (iv.length !== config.iv) {
throw new TypeError('invalid iv length ' + iv.length)
}
if (config.type === 'stream') {
return new StreamCipher(modelist[config.mode], password, iv, true)
} else if (config.type === 'auth') {
return new AuthCipher(modelist[config.mode], password, iv, true)
}
return new Decipher(modelist[config.mode], password, iv)
}
function createDecipher (suite, password) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
var keys = ebtk(password, false, config.key, config.iv)
return createDecipheriv(suite, keys.key, keys.iv)
}
exports.createDecipher = createDecipher
exports.createDecipheriv = createDecipheriv
}).call(this,require("buffer").Buffer)
},{"./aes":8,"./authCipher":9,"./modes":14,"./modes/cbc":15,"./modes/cfb":16,"./modes/cfb1":17,"./modes/cfb8":18,"./modes/ctr":19,"./modes/ecb":20,"./modes/ofb":21,"./streamCipher":24,"buffer":2,"cipher-base":23,"evp_bytestokey":35,"inherits":199}],12:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
var modes = require('./modes')
var ebtk = require('evp_bytestokey')
var StreamCipher = require('./streamCipher')
var AuthCipher = require('./authCipher')
inherits(Cipher, Transform)
function Cipher (mode, key, iv) {
if (!(this instanceof Cipher)) {
return new Cipher(mode, key, iv)
}
Transform.call(this)
this._cache = new Splitter()
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
iv.copy(this._prev)
this._mode = mode
this._autopadding = true
}
Cipher.prototype._update = function (data) {
this._cache.add(data)
var chunk
var thing
var out = []
while ((chunk = this._cache.get())) {
thing = this._mode.encrypt(this, chunk)
out.push(thing)
}
return Buffer.concat(out)
}
Cipher.prototype._final = function () {
var chunk = this._cache.flush()
if (this._autopadding) {
chunk = this._mode.encrypt(this, chunk)
this._cipher.scrub()
return chunk
} else if (chunk.toString('hex') !== '10101010101010101010101010101010') {
this._cipher.scrub()
throw new Error('data not multiple of block length')
}
}
Cipher.prototype.setAutoPadding = function (setTo) {
this._autopadding = !!setTo
return this
}
function Splitter () {
if (!(this instanceof Splitter)) {
return new Splitter()
}
this.cache = new Buffer('')
}
Splitter.prototype.add = function (data) {
this.cache = Buffer.concat([this.cache, data])
}
Splitter.prototype.get = function () {
if (this.cache.length > 15) {
var out = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
return out
}
return null
}
Splitter.prototype.flush = function () {
var len = 16 - this.cache.length
var padBuff = new Buffer(len)
var i = -1
while (++i < len) {
padBuff.writeUInt8(len, i)
}
var out = Buffer.concat([this.cache, padBuff])
return out
}
var modelist = {
ECB: require('./modes/ecb'),
CBC: require('./modes/cbc'),
CFB: require('./modes/cfb'),
CFB8: require('./modes/cfb8'),
CFB1: require('./modes/cfb1'),
OFB: require('./modes/ofb'),
CTR: require('./modes/ctr'),
GCM: require('./modes/ctr')
}
function createCipheriv (suite, password, iv) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
if (typeof iv === 'string') {
iv = new Buffer(iv)
}
if (typeof password === 'string') {
password = new Buffer(password)
}
if (password.length !== config.key / 8) {
throw new TypeError('invalid key length ' + password.length)
}
if (iv.length !== config.iv) {
throw new TypeError('invalid iv length ' + iv.length)
}
if (config.type === 'stream') {
return new StreamCipher(modelist[config.mode], password, iv)
} else if (config.type === 'auth') {
return new AuthCipher(modelist[config.mode], password, iv)
}
return new Cipher(modelist[config.mode], password, iv)
}
function createCipher (suite, password) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
var keys = ebtk(password, false, config.key, config.iv)
return createCipheriv(suite, keys.key, keys.iv)
}
exports.createCipheriv = createCipheriv
exports.createCipher = createCipher
}).call(this,require("buffer").Buffer)
},{"./aes":8,"./authCipher":9,"./modes":14,"./modes/cbc":15,"./modes/cfb":16,"./modes/cfb1":17,"./modes/cfb8":18,"./modes/ctr":19,"./modes/ecb":20,"./modes/ofb":21,"./streamCipher":24,"buffer":2,"cipher-base":23,"evp_bytestokey":35,"inherits":199}],13:[function(require,module,exports){
(function (Buffer){
var zeros = new Buffer(16)
zeros.fill(0)
module.exports = GHASH
function GHASH (key) {
this.h = key
this.state = new Buffer(16)
this.state.fill(0)
this.cache = new Buffer('')
}
// from http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_gcm.js.html
// by Juho Vähä-Herttua
GHASH.prototype.ghash = function (block) {
var i = -1
while (++i < block.length) {
this.state[i] ^= block[i]
}
this._multiply()
}
GHASH.prototype._multiply = function () {
var Vi = toArray(this.h)
var Zi = [0, 0, 0, 0]
var j, xi, lsb_Vi
var i = -1
while (++i < 128) {
xi = (this.state[~~(i / 8)] & (1 << (7 - i % 8))) !== 0
if (xi) {
// Z_i+1 = Z_i ^ V_i
Zi = xor(Zi, Vi)
}
// Store the value of LSB(V_i)
lsb_Vi = (Vi[3] & 1) !== 0
// V_i+1 = V_i >> 1
for (j = 3; j > 0; j--) {
Vi[j] = (Vi[j] >>> 1) | ((Vi[j - 1] & 1) << 31)
}
Vi[0] = Vi[0] >>> 1
// If LSB(V_i) is 1, V_i+1 = (V_i >> 1) ^ R
if (lsb_Vi) {
Vi[0] = Vi[0] ^ (0xe1 << 24)
}
}
this.state = fromArray(Zi)
}
GHASH.prototype.update = function (buf) {
this.cache = Buffer.concat([this.cache, buf])
var chunk
while (this.cache.length >= 16) {
chunk = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
this.ghash(chunk)
}
}
GHASH.prototype.final = function (abl, bl) {
if (this.cache.length) {
this.ghash(Buffer.concat([this.cache, zeros], 16))
}
this.ghash(fromArray([
0, abl,
0, bl
]))
return this.state
}
function toArray (buf) {
return [
buf.readUInt32BE(0),
buf.readUInt32BE(4),
buf.readUInt32BE(8),
buf.readUInt32BE(12)
]
}
function fromArray (out) {
out = out.map(fixup_uint32)
var buf = new Buffer(16)
buf.writeUInt32BE(out[0], 0)
buf.writeUInt32BE(out[1], 4)
buf.writeUInt32BE(out[2], 8)
buf.writeUInt32BE(out[3], 12)
return buf
}
var uint_max = Math.pow(2, 32)
function fixup_uint32 (x) {
var ret, x_pos
ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x
return ret
}
function xor (a, b) {
return [
a[0] ^ b[0],
a[1] ^ b[1],
a[2] ^ b[2],
a[3] ^ b[3]
]
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],14:[function(require,module,exports){
exports['aes-128-ecb'] = {
cipher: 'AES',
key: 128,
iv: 0,
mode: 'ECB',
type: 'block'
}
exports['aes-192-ecb'] = {
cipher: 'AES',
key: 192,
iv: 0,
mode: 'ECB',
type: 'block'
}
exports['aes-256-ecb'] = {
cipher: 'AES',
key: 256,
iv: 0,
mode: 'ECB',
type: 'block'
}
exports['aes-128-cbc'] = {
cipher: 'AES',
key: 128,
iv: 16,
mode: 'CBC',
type: 'block'
}
exports['aes-192-cbc'] = {
cipher: 'AES',
key: 192,
iv: 16,
mode: 'CBC',
type: 'block'
}
exports['aes-256-cbc'] = {
cipher: 'AES',
key: 256,
iv: 16,
mode: 'CBC',
type: 'block'
}
exports['aes128'] = exports['aes-128-cbc']
exports['aes192'] = exports['aes-192-cbc']
exports['aes256'] = exports['aes-256-cbc']
exports['aes-128-cfb'] = {
cipher: 'AES',
key: 128,
iv: 16,
mode: 'CFB',
type: 'stream'
}
exports['aes-192-cfb'] = {
cipher: 'AES',
key: 192,
iv: 16,
mode: 'CFB',
type: 'stream'
}
exports['aes-256-cfb'] = {
cipher: 'AES',
key: 256,
iv: 16,
mode: 'CFB',
type: 'stream'
}
exports['aes-128-cfb8'] = {
cipher: 'AES',
key: 128,
iv: 16,
mode: 'CFB8',
type: 'stream'
}
exports['aes-192-cfb8'] = {
cipher: 'AES',
key: 192,
iv: 16,
mode: 'CFB8',
type: 'stream'
}
exports['aes-256-cfb8'] = {
cipher: 'AES',
key: 256,
iv: 16,
mode: 'CFB8',
type: 'stream'
}
exports['aes-128-cfb1'] = {
cipher: 'AES',
key: 128,
iv: 16,
mode: 'CFB1',
type: 'stream'
}
exports['aes-192-cfb1'] = {
cipher: 'AES',
key: 192,
iv: 16,
mode: 'CFB1',
type: 'stream'
}
exports['aes-256-cfb1'] = {
cipher: 'AES',
key: 256,
iv: 16,
mode: 'CFB1',
type: 'stream'
}
exports['aes-128-ofb'] = {
cipher: 'AES',
key: 128,
iv: 16,
mode: 'OFB',
type: 'stream'
}
exports['aes-192-ofb'] = {
cipher: 'AES',
key: 192,
iv: 16,
mode: 'OFB',
type: 'stream'
}
exports['aes-256-ofb'] = {
cipher: 'AES',
key: 256,
iv: 16,
mode: 'OFB',
type: 'stream'
}
exports['aes-128-ctr'] = {
cipher: 'AES',
key: 128,
iv: 16,
mode: 'CTR',
type: 'stream'
}
exports['aes-192-ctr'] = {
cipher: 'AES',
key: 192,
iv: 16,
mode: 'CTR',
type: 'stream'
}
exports['aes-256-ctr'] = {
cipher: 'AES',
key: 256,
iv: 16,
mode: 'CTR',
type: 'stream'
}
exports['aes-128-gcm'] = {
cipher: 'AES',
key: 128,
iv: 12,
mode: 'GCM',
type: 'auth'
}
exports['aes-192-gcm'] = {
cipher: 'AES',
key: 192,
iv: 12,
mode: 'GCM',
type: 'auth'
}
exports['aes-256-gcm'] = {
cipher: 'AES',
key: 256,
iv: 12,
mode: 'GCM',
type: 'auth'
}
},{}],15:[function(require,module,exports){
var xor = require('buffer-xor')
exports.encrypt = function (self, block) {
var data = xor(block, self._prev)
self._prev = self._cipher.encryptBlock(data)
return self._prev
}
exports.decrypt = function (self, block) {
var pad = self._prev
self._prev = block
var out = self._cipher.decryptBlock(block)
return xor(out, pad)
}
},{"buffer-xor":22}],16:[function(require,module,exports){
(function (Buffer){
var xor = require('buffer-xor')
exports.encrypt = function (self, data, decrypt) {
var out = new Buffer('')
var len
while (data.length) {
if (self._cache.length === 0) {
self._cache = self._cipher.encryptBlock(self._prev)
self._prev = new Buffer('')
}
if (self._cache.length <= data.length) {
len = self._cache.length
out = Buffer.concat([out, encryptStart(self, data.slice(0, len), decrypt)])
data = data.slice(len)
} else {
out = Buffer.concat([out, encryptStart(self, data, decrypt)])
break
}
}
return out
}
function encryptStart (self, data, decrypt) {
var len = data.length
var out = xor(data, self._cache)
self._cache = self._cache.slice(len)
self._prev = Buffer.concat([self._prev, decrypt ? data : out])
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"buffer-xor":22}],17:[function(require,module,exports){
(function (Buffer){
function encryptByte (self, byteParam, decrypt) {
var pad
var i = -1
var len = 8
var out = 0
var bit, value
while (++i < len) {
pad = self._cipher.encryptBlock(self._prev)
bit = (byteParam & (1 << (7 - i))) ? 0x80 : 0
value = pad[0] ^ bit
out += ((value & 0x80) >> (i % 8))
self._prev = shiftIn(self._prev, decrypt ? bit : value)
}
return out
}
exports.encrypt = function (self, chunk, decrypt) {
var len = chunk.length
var out = new Buffer(len)
var i = -1
while (++i < len) {
out[i] = encryptByte(self, chunk[i], decrypt)
}
return out
}
function shiftIn (buffer, value) {
var len = buffer.length
var i = -1
var out = new Buffer(buffer.length)
buffer = Buffer.concat([buffer, new Buffer([value])])
while (++i < len) {
out[i] = buffer[i] << 1 | buffer[i + 1] >> (7)
}
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],18:[function(require,module,exports){
(function (Buffer){
function encryptByte (self, byteParam, decrypt) {
var pad = self._cipher.encryptBlock(self._prev)
var out = pad[0] ^ byteParam
self._prev = Buffer.concat([self._prev.slice(1), new Buffer([decrypt ? byteParam : out])])
return out
}
exports.encrypt = function (self, chunk, decrypt) {
var len = chunk.length
var out = new Buffer(len)
var i = -1
while (++i < len) {
out[i] = encryptByte(self, chunk[i], decrypt)
}
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],19:[function(require,module,exports){
(function (Buffer){
var xor = require('buffer-xor')
function incr32 (iv) {
var len = iv.length
var item
while (len--) {
item = iv.readUInt8(len)
if (item === 255) {
iv.writeUInt8(0, len)
} else {
item++
iv.writeUInt8(item, len)
break
}
}
}
function getBlock (self) {
var out = self._cipher.encryptBlock(self._prev)
incr32(self._prev)
return out
}
exports.encrypt = function (self, chunk) {
while (self._cache.length < chunk.length) {
self._cache = Buffer.concat([self._cache, getBlock(self)])
}
var pad = self._cache.slice(0, chunk.length)
self._cache = self._cache.slice(chunk.length)
return xor(chunk, pad)
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"buffer-xor":22}],20:[function(require,module,exports){
exports.encrypt = function (self, block) {
return self._cipher.encryptBlock(block)
}
exports.decrypt = function (self, block) {
return self._cipher.decryptBlock(block)
}
},{}],21:[function(require,module,exports){
(function (Buffer){
var xor = require('buffer-xor')
function getBlock (self) {
self._prev = self._cipher.encryptBlock(self._prev)
return self._prev
}
exports.encrypt = function (self, chunk) {
while (self._cache.length < chunk.length) {
self._cache = Buffer.concat([self._cache, getBlock(self)])
}
var pad = self._cache.slice(0, chunk.length)
self._cache = self._cache.slice(chunk.length)
return xor(chunk, pad)
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"buffer-xor":22}],22:[function(require,module,exports){
(function (Buffer){
module.exports = function xor (a, b) {
var length = Math.min(a.length, b.length)
var buffer = new Buffer(length)
for (var i = 0; i < length; ++i) {
buffer[i] = a[i] ^ b[i]
}
return buffer
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],23:[function(require,module,exports){
(function (Buffer){
var Transform = require('stream').Transform
var inherits = require('inherits')
var StringDecoder = require('string_decoder').StringDecoder
module.exports = CipherBase
inherits(CipherBase, Transform)
function CipherBase (hashMode) {
Transform.call(this)
this.hashMode = typeof hashMode === 'string'
if (this.hashMode) {
this[hashMode] = this._finalOrDigest
} else {
this.final = this._finalOrDigest
}
this._decoder = null
this._encoding = null
}
CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
if (typeof data === 'string') {
data = new Buffer(data, inputEnc)
}
var outData = this._update(data)
if (this.hashMode) {
return this
}
if (outputEnc) {
outData = this._toString(outData, outputEnc)
}
return outData
}
CipherBase.prototype.setAutoPadding = function () {}
CipherBase.prototype.getAuthTag = function () {
throw new Error('trying to get auth tag in unsupported state')
}
CipherBase.prototype.setAuthTag = function () {
throw new Error('trying to set auth tag in unsupported state')
}
CipherBase.prototype.setAAD = function () {
throw new Error('trying to set aad in unsupported state')
}
CipherBase.prototype._transform = function (data, _, next) {
var err
try {
if (this.hashMode) {
this._update(data)
} else {
this.push(this._update(data))
}
} catch (e) {
err = e
} finally {
next(err)
}
}
CipherBase.prototype._flush = function (done) {
var err
try {
this.push(this._final())
} catch (e) {
err = e
} finally {
done(err)
}
}
CipherBase.prototype._finalOrDigest = function (outputEnc) {
var outData = this._final() || new Buffer('')
if (outputEnc) {
outData = this._toString(outData, outputEnc, true)
}
return outData
}
CipherBase.prototype._toString = function (value, enc, final) {
if (!this._decoder) {
this._decoder = new StringDecoder(enc)
this._encoding = enc
}
if (this._encoding !== enc) {
throw new Error('can\'t switch encodings')
}
var out = this._decoder.write(value)
if (final) {
out += this._decoder.end()
}
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"inherits":199,"stream":216,"string_decoder":217}],24:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
inherits(StreamCipher, Transform)
module.exports = StreamCipher
function StreamCipher (mode, key, iv, decrypt) {
if (!(this instanceof StreamCipher)) {
return new StreamCipher(mode, key, iv)
}
Transform.call(this)
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
this._cache = new Buffer('')
this._secCache = new Buffer('')
this._decrypt = decrypt
iv.copy(this._prev)
this._mode = mode
}
StreamCipher.prototype._update = function (chunk) {
return this._mode.encrypt(this, chunk, this._decrypt)
}
StreamCipher.prototype._final = function () {
this._cipher.scrub()
}
}).call(this,require("buffer").Buffer)
},{"./aes":8,"buffer":2,"cipher-base":23,"inherits":199}],25:[function(require,module,exports){
(function (Buffer){
var CipherBase = require('cipher-base')
var des = require('des.js')
var inherits = require('inherits')
var modes = {
'des-ede3-cbc': des.CBC.instantiate(des.EDE),
'des-ede3': des.EDE,
'des-ede-cbc': des.CBC.instantiate(des.EDE),
'des-ede': des.EDE,
'des-cbc': des.CBC.instantiate(des.DES),
'des-ecb': des.DES
}
modes.des = modes['des-cbc']
modes.des3 = modes['des-ede3-cbc']
module.exports = DES
inherits(DES, CipherBase)
function DES (opts) {
CipherBase.call(this)
var modeName = opts.mode.toLowerCase()
var mode = modes[modeName]
var type
if (opts.decrypt) {
type = 'decrypt'
} else {
type = 'encrypt'
}
var key = opts.key
if (modeName === 'des-ede' || modeName === 'des-ede-cbc') {
key = Buffer.concat([key, key.slice(0, 8)])
}
var iv = opts.iv
this._des = mode.create({
key: key,
iv: iv,
type: type
})
}
DES.prototype._update = function (data) {
return new Buffer(this._des.update(data))
}
DES.prototype._final = function () {
return new Buffer(this._des.final())
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"cipher-base":27,"des.js":28,"inherits":199}],26:[function(require,module,exports){
exports['des-ecb'] = {
key: 8,
iv: 0
}
exports['des-cbc'] = exports.des = {
key: 8,
iv: 8
}
exports['des-ede3-cbc'] = exports.des3 = {
key: 24,
iv: 8
}
exports['des-ede3'] = {
key: 24,
iv: 0
}
exports['des-ede-cbc'] = {
key: 16,
iv: 8
}
exports['des-ede'] = {
key: 16,
iv: 0
}
},{}],27:[function(require,module,exports){
(function (Buffer){
var Transform = require('stream').Transform
var inherits = require('inherits')
var StringDecoder = require('string_decoder').StringDecoder
module.exports = CipherBase
inherits(CipherBase, Transform)
function CipherBase (hashMode) {
Transform.call(this)
this.hashMode = typeof hashMode === 'string'
if (this.hashMode) {
this[hashMode] = this._finalOrDigest
} else {
this.final = this._finalOrDigest
}
this._decoder = null
this._encoding = null
}
CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
if (typeof data === 'string') {
data = new Buffer(data, inputEnc)
}
var outData = this._update(data)
if (this.hashMode) {
return this
}
if (outputEnc) {
outData = this._toString(outData, outputEnc)
}
return outData
}
CipherBase.prototype.setAutoPadding = function () {}
CipherBase.prototype.getAuthTag = function () {
throw new Error('trying to get auth tag in unsupported state')
}
CipherBase.prototype.setAuthTag = function () {
throw new Error('trying to set auth tag in unsupported state')
}
CipherBase.prototype.setAAD = function () {
throw new Error('trying to set aad in unsupported state')
}
CipherBase.prototype._transform = function (data, _, next) {
var err
try {
if (this.hashMode) {
this._update(data)
} else {
this.push(this._update(data))
}
} catch (e) {
err = e
} finally {
next(err)
}
}
CipherBase.prototype._flush = function (done) {
var err
try {
this.push(this._final())
} catch (e) {
err = e
} finally {
done(err)
}
}
CipherBase.prototype._finalOrDigest = function (outputEnc) {
var outData = this._final() || new Buffer('')
if (outputEnc) {
outData = this._toString(outData, outputEnc, true)
}
return outData
}
CipherBase.prototype._toString = function (value, enc, final) {
if (!this._decoder) {
this._decoder = new StringDecoder(enc)
this._encoding = enc
}
if (this._encoding !== enc) {
throw new Error('can\'t switch encodings')
}
var out = this._decoder.write(value)
if (final) {
out += this._decoder.end()
}
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"inherits":199,"stream":216,"string_decoder":217}],28:[function(require,module,exports){
'use strict';
exports.utils = require('./des/utils');
exports.Cipher = require('./des/cipher');
exports.DES = require('./des/des');
exports.CBC = require('./des/cbc');
exports.EDE = require('./des/ede');
},{"./des/cbc":29,"./des/cipher":30,"./des/des":31,"./des/ede":32,"./des/utils":33}],29:[function(require,module,exports){
'use strict';
var assert = require('minimalistic-assert');
var inherits = require('inherits');
var proto = {};
function CBCState(iv) {
assert.equal(iv.length, 8, 'Invalid IV length');
this.iv = new Array(8);
for (var i = 0; i < this.iv.length; i++)
this.iv[i] = iv[i];
}
function instantiate(Base) {
function CBC(options) {
Base.call(this, options);
this._cbcInit();
}
inherits(CBC, Base);
var keys = Object.keys(proto);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
CBC.prototype[key] = proto[key];
}
CBC.create = function create(options) {
return new CBC(options);
};
return CBC;
}
exports.instantiate = instantiate;
proto._cbcInit = function _cbcInit() {
var state = new CBCState(this.options.iv);
this._cbcState = state;
};
proto._update = function _update(inp, inOff, out, outOff) {
var state = this._cbcState;
var superProto = this.constructor.super_.prototype;
var iv = state.iv;
if (this.type === 'encrypt') {
for (var i = 0; i < this.blockSize; i++)
iv[i] ^= inp[inOff + i];
superProto._update.call(this, iv, 0, out, outOff);
for (var i = 0; i < this.blockSize; i++)
iv[i] = out[outOff + i];
} else {
superProto._update.call(this, inp, inOff, out, outOff);
for (var i = 0; i < this.blockSize; i++)
out[outOff + i] ^= iv[i];
for (var i = 0; i < this.blockSize; i++)
iv[i] = inp[inOff + i];
}
};
},{"inherits":199,"minimalistic-assert":34}],30:[function(require,module,exports){
'use strict';
var assert = require('minimalistic-assert');
function Cipher(options) {
this.options = options;
this.type = this.options.type;
this.blockSize = 8;
this._init();
this.buffer = new Array(this.blockSize);
this.bufferOff = 0;
}
module.exports = Cipher;
Cipher.prototype._init = function _init() {
// Might be overrided
};
Cipher.prototype.update = function update(data) {
if (data.length === 0)
return [];
if (this.type === 'decrypt')
return this._updateDecrypt(data);
else
return this._updateEncrypt(data);
};
Cipher.prototype._buffer = function _buffer(data, off) {
// Append data to buffer
var min = Math.min(this.buffer.length - this.bufferOff, data.length - off);
for (var i = 0; i < min; i++)
this.buffer[this.bufferOff + i] = data[off + i];
this.bufferOff += min;
// Shift next
return min;
};
Cipher.prototype._flushBuffer = function _flushBuffer(out, off) {
this._update(this.buffer, 0, out, off);
this.bufferOff = 0;
return this.blockSize;
};
Cipher.prototype._updateEncrypt = function _updateEncrypt(data) {
var inputOff = 0;
var outputOff = 0;
var count = ((this.bufferOff + data.length) / this.blockSize) | 0;
var out = new Array(count * this.blockSize);
if (this.bufferOff !== 0) {
inputOff += this._buffer(data, inputOff);
if (this.bufferOff === this.buffer.length)
outputOff += this._flushBuffer(out, outputOff);
}
// Write blocks
var max = data.length - ((data.length - inputOff) % this.blockSize);
for (; inputOff < max; inputOff += this.blockSize) {
this._update(data, inputOff, out, outputOff);
outputOff += this.blockSize;
}
// Queue rest
for (; inputOff < data.length; inputOff++, this.bufferOff++)
this.buffer[this.bufferOff] = data[inputOff];
return out;
};
Cipher.prototype._updateDecrypt = function _updateDecrypt(data) {
var inputOff = 0;
var outputOff = 0;
var count = Math.ceil((this.bufferOff + data.length) / this.blockSize) - 1;
var out = new Array(count * this.blockSize);
// TODO(indutny): optimize it, this is far from optimal
for (; count > 0; count--) {
inputOff += this._buffer(data, inputOff);
outputOff += this._flushBuffer(out, outputOff);
}
// Buffer rest of the input
inputOff += this._buffer(data, inputOff);
return out;
};
Cipher.prototype.final = function final(buffer) {
var first;
if (buffer)
first = this.update(buffer);
var last;
if (this.type === 'encrypt')
last = this._finalEncrypt();
else
last = this._finalDecrypt();
if (first)
return first.concat(last);
else
return last;
};
Cipher.prototype._pad = function _pad(buffer, off) {
if (off === 0)
return false;
while (off < buffer.length)
buffer[off++] = 0;
return true;
};
Cipher.prototype._finalEncrypt = function _finalEncrypt() {
if (!this._pad(this.buffer, this.bufferOff))
return [];
var out = new Array(this.blockSize);
this._update(this.buffer, 0, out, 0);
return out;
};
Cipher.prototype._unpad = function _unpad(buffer) {
return buffer;
};
Cipher.prototype._finalDecrypt = function _finalDecrypt() {
assert.equal(this.bufferOff, this.blockSize, 'Not enough data to decrypt');
var out = new Array(this.blockSize);
this._flushBuffer(out, 0);
return this._unpad(out);
};
},{"minimalistic-assert":34}],31:[function(require,module,exports){
'use strict';
var assert = require('minimalistic-assert');
var inherits = require('inherits');
var des = require('../des');
var utils = des.utils;
var Cipher = des.Cipher;
function DESState() {
this.tmp = new Array(2);
this.keys = null;
}
function DES(options) {
Cipher.call(this, options);
var state = new DESState();
this._desState = state;
this.deriveKeys(state, options.key);
}
inherits(DES, Cipher);
module.exports = DES;
DES.create = function create(options) {
return new DES(options);
};
var shiftTable = [
1, 1, 2, 2, 2, 2, 2, 2,
1, 2, 2, 2, 2, 2, 2, 1
];
DES.prototype.deriveKeys = function deriveKeys(state, key) {
state.keys = new Array(16 * 2);
assert.equal(key.length, this.blockSize, 'Invalid key length');
var kL = utils.readUInt32BE(key, 0);
var kR = utils.readUInt32BE(key, 4);
utils.pc1(kL, kR, state.tmp, 0);
kL = state.tmp[0];
kR = state.tmp[1];
for (var i = 0; i < state.keys.length; i += 2) {
var shift = shiftTable[i >>> 1];
kL = utils.r28shl(kL, shift);
kR = utils.r28shl(kR, shift);
utils.pc2(kL, kR, state.keys, i);
}
};
DES.prototype._update = function _update(inp, inOff, out, outOff) {
var state = this._desState;
var l = utils.readUInt32BE(inp, inOff);
var r = utils.readUInt32BE(inp, inOff + 4);
// Initial Permutation
utils.ip(l, r, state.tmp, 0);
l = state.tmp[0];
r = state.tmp[1];
if (this.type === 'encrypt')
this._encrypt(state, l, r, state.tmp, 0);
else
this._decrypt(state, l, r, state.tmp, 0);
l = state.tmp[0];
r = state.tmp[1];
utils.writeUInt32BE(out, l, outOff);
utils.writeUInt32BE(out, r, outOff + 4);
};
DES.prototype._pad = function _pad(buffer, off) {
var value = buffer.length - off;
for (var i = off; i < buffer.length; i++)
buffer[i] = value;
return true;
};
DES.prototype._unpad = function _unpad(buffer) {
var pad = buffer[buffer.length - 1];
for (var i = buffer.length - pad; i < buffer.length; i++)
assert.equal(buffer[i], pad);
return buffer.slice(0, buffer.length - pad);
};
DES.prototype._encrypt = function _encrypt(state, lStart, rStart, out, off) {
var l = lStart;
var r = rStart;
// Apply f() x16 times
for (var i = 0; i < state.keys.length; i += 2) {
var keyL = state.keys[i];
var keyR = state.keys[i + 1];
// f(r, k)
utils.expand(r, state.tmp, 0);
keyL ^= state.tmp[0];
keyR ^= state.tmp[1];
var s = utils.substitute(keyL, keyR);
var f = utils.permute(s);
var t = r;
r = (l ^ f) >>> 0;
l = t;
}
// Reverse Initial Permutation
utils.rip(r, l, out, off);
};
DES.prototype._decrypt = function _decrypt(state, lStart, rStart, out, off) {
var l = rStart;
var r = lStart;
// Apply f() x16 times
for (var i = state.keys.length - 2; i >= 0; i -= 2) {
var keyL = state.keys[i];
var keyR = state.keys[i + 1];
// f(r, k)
utils.expand(l, state.tmp, 0);
keyL ^= state.tmp[0];
keyR ^= state.tmp[1];
var s = utils.substitute(keyL, keyR);
var f = utils.permute(s);
var t = l;
l = (r ^ f) >>> 0;
r = t;
}
// Reverse Initial Permutation
utils.rip(l, r, out, off);
};
},{"../des":28,"inherits":199,"minimalistic-assert":34}],32:[function(require,module,exports){
'use strict';
var assert = require('minimalistic-assert');
var inherits = require('inherits');
var des = require('../des');
var Cipher = des.Cipher;
var DES = des.DES;
function EDEState(type, key) {
assert.equal(key.length, 24, 'Invalid key length');
var k1 = key.slice(0, 8);
var k2 = key.slice(8, 16);
var k3 = key.slice(16, 24);
if (type === 'encrypt') {
this.ciphers = [
DES.create({ type: 'encrypt', key: k1 }),
DES.create({ type: 'decrypt', key: k2 }),
DES.create({ type: 'encrypt', key: k3 })
];
} else {
this.ciphers = [
DES.create({ type: 'decrypt', key: k3 }),
DES.create({ type: 'encrypt', key: k2 }),
DES.create({ type: 'decrypt', key: k1 })
];
}
}
function EDE(options) {
Cipher.call(this, options);
var state = new EDEState(this.type, this.options.key);
this._edeState = state;
}
inherits(EDE, Cipher);
module.exports = EDE;
EDE.create = function create(options) {
return new EDE(options);
};
EDE.prototype._update = function _update(inp, inOff, out, outOff) {
var state = this._edeState;
state.ciphers[0]._update(inp, inOff, out, outOff);
state.ciphers[1]._update(out, outOff, out, outOff);
state.ciphers[2]._update(out, outOff, out, outOff);
};
EDE.prototype._pad = DES.prototype._pad;
EDE.prototype._unpad = DES.prototype._unpad;
},{"../des":28,"inherits":199,"minimalistic-assert":34}],33:[function(require,module,exports){
'use strict';
exports.readUInt32BE = function readUInt32BE(bytes, off) {
var res = (bytes[0 + off] << 24) |
(bytes[1 + off] << 16) |
(bytes[2 + off] << 8) |
bytes[3 + off];
return res >>> 0;
};
exports.writeUInt32BE = function writeUInt32BE(bytes, value, off) {
bytes[0 + off] = value >>> 24;
bytes[1 + off] = (value >>> 16) & 0xff;
bytes[2 + off] = (value >>> 8) & 0xff;
bytes[3 + off] = value & 0xff;
};
exports.ip = function ip(inL, inR, out, off) {
var outL = 0;
var outR = 0;
for (var i = 6; i >= 0; i -= 2) {
for (var j = 0; j <= 24; j += 8) {
outL <<= 1;
outL |= (inR >>> (j + i)) & 1;
}
for (var j = 0; j <= 24; j += 8) {
outL <<= 1;
outL |= (inL >>> (j + i)) & 1;
}
}
for (var i = 6; i >= 0; i -= 2) {
for (var j = 1; j <= 25; j += 8) {
outR <<= 1;
outR |= (inR >>> (j + i)) & 1;
}
for (var j = 1; j <= 25; j += 8) {
outR <<= 1;
outR |= (inL >>> (j + i)) & 1;
}
}
out[off + 0] = outL >>> 0;
out[off + 1] = outR >>> 0;
};
exports.rip = function rip(inL, inR, out, off) {
var outL = 0;
var outR = 0;
for (var i = 0; i < 4; i++) {
for (var j = 24; j >= 0; j -= 8) {
outL <<= 1;
outL |= (inR >>> (j + i)) & 1;
outL <<= 1;
outL |= (inL >>> (j + i)) & 1;
}
}
for (var i = 4; i < 8; i++) {
for (var j = 24; j >= 0; j -= 8) {
outR <<= 1;
outR |= (inR >>> (j + i)) & 1;
outR <<= 1;
outR |= (inL >>> (j + i)) & 1;
}
}
out[off + 0] = outL >>> 0;
out[off + 1] = outR >>> 0;
};
exports.pc1 = function pc1(inL, inR, out, off) {
var outL = 0;
var outR = 0;
// 7, 15, 23, 31, 39, 47, 55, 63
// 6, 14, 22, 30, 39, 47, 55, 63
// 5, 13, 21, 29, 39, 47, 55, 63
// 4, 12, 20, 28
for (var i = 7; i >= 5; i--) {
for (var j = 0; j <= 24; j += 8) {
outL <<= 1;
outL |= (inR >> (j + i)) & 1;
}
for (var j = 0; j <= 24; j += 8) {
outL <<= 1;
outL |= (inL >> (j + i)) & 1;
}
}
for (var j = 0; j <= 24; j += 8) {
outL <<= 1;
outL |= (inR >> (j + i)) & 1;
}
// 1, 9, 17, 25, 33, 41, 49, 57
// 2, 10, 18, 26, 34, 42, 50, 58
// 3, 11, 19, 27, 35, 43, 51, 59
// 36, 44, 52, 60
for (var i = 1; i <= 3; i++) {
for (var j = 0; j <= 24; j += 8) {
outR <<= 1;
outR |= (inR >> (j + i)) & 1;
}
for (var j = 0; j <= 24; j += 8) {
outR <<= 1;
outR |= (inL >> (j + i)) & 1;
}
}
for (var j = 0; j <= 24; j += 8) {
outR <<= 1;
outR |= (inL >> (j + i)) & 1;
}
out[off + 0] = outL >>> 0;
out[off + 1] = outR >>> 0;
};
exports.r28shl = function r28shl(num, shift) {
return ((num << shift) & 0xfffffff) | (num >>> (28 - shift));
};
var pc2table = [
// inL => outL
14, 11, 17, 4, 27, 23, 25, 0,
13, 22, 7, 18, 5, 9, 16, 24,
2, 20, 12, 21, 1, 8, 15, 26,
// inR => outR
15, 4, 25, 19, 9, 1, 26, 16,
5, 11, 23, 8, 12, 7, 17, 0,
22, 3, 10, 14, 6, 20, 27, 24
];
exports.pc2 = function pc2(inL, inR, out, off) {
var outL = 0;
var outR = 0;
var len = pc2table.length >>> 1;
for (var i = 0; i < len; i++) {
outL <<= 1;
outL |= (inL >>> pc2table[i]) & 0x1;
}
for (var i = len; i < pc2table.length; i++) {
outR <<= 1;
outR |= (inR >>> pc2table[i]) & 0x1;
}
out[off + 0] = outL >>> 0;
out[off + 1] = outR >>> 0;
};
exports.expand = function expand(r, out, off) {
var outL = 0;
var outR = 0;
outL = ((r & 1) << 5) | (r >>> 27);
for (var i = 23; i >= 15; i -= 4) {
outL <<= 6;
outL |= (r >>> i) & 0x3f;
}
for (var i = 11; i >= 3; i -= 4) {
outR |= (r >>> i) & 0x3f;
outR <<= 6;
}
outR |= ((r & 0x1f) << 1) | (r >>> 31);
out[off + 0] = outL >>> 0;
out[off + 1] = outR >>> 0;
};
var sTable = [
14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13,
15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9,
10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12,
7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14,
2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3,
12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13,
4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12,
13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
];
exports.substitute = function substitute(inL, inR) {
var out = 0;
for (var i = 0; i < 4; i++) {
var b = (inL >>> (18 - i * 6)) & 0x3f;
var sb = sTable[i * 0x40 + b];
out <<= 4;
out |= sb;
}
for (var i = 0; i < 4; i++) {
var b = (inR >>> (18 - i * 6)) & 0x3f;
var sb = sTable[4 * 0x40 + i * 0x40 + b];
out <<= 4;
out |= sb;
}
return out >>> 0;
};
var permuteTable = [
16, 25, 12, 11, 3, 20, 4, 15, 31, 17, 9, 6, 27, 14, 1, 22,
30, 24, 8, 18, 0, 5, 29, 23, 13, 19, 2, 26, 10, 21, 28, 7
];
exports.permute = function permute(num) {
var out = 0;
for (var i = 0; i < permuteTable.length; i++) {
out <<= 1;
out |= (num >>> permuteTable[i]) & 0x1;
}
return out >>> 0;
};
exports.padSplit = function padSplit(num, size, group) {
var str = num.toString(2);
while (str.length < size)
str = '0' + str;
var out = [];
for (var i = 0; i < size; i += group)
out.push(str.slice(i, i + group));
return out.join(' ');
};
},{}],34:[function(require,module,exports){
module.exports = assert;
function assert(val, msg) {
if (!val)
throw new Error(msg || 'Assertion failed');
}
assert.equal = function assertEqual(l, r, msg) {
if (l != r)
throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));
};
},{}],35:[function(require,module,exports){
(function (Buffer){
var md5 = require('create-hash/md5')
module.exports = EVP_BytesToKey
function EVP_BytesToKey (password, salt, keyLen, ivLen) {
if (!Buffer.isBuffer(password)) {
password = new Buffer(password, 'binary')
}
if (salt && !Buffer.isBuffer(salt)) {
salt = new Buffer(salt, 'binary')
}
keyLen = keyLen / 8
ivLen = ivLen || 0
var ki = 0
var ii = 0
var key = new Buffer(keyLen)
var iv = new Buffer(ivLen)
var addmd = 0
var md_buf
var i
var bufs = []
while (true) {
if (addmd++ > 0) {
bufs.push(md_buf)
}
bufs.push(password)
if (salt) {
bufs.push(salt)
}
md_buf = md5(Buffer.concat(bufs))
bufs = []
i = 0
if (keyLen > 0) {
while (true) {
if (keyLen === 0) {
break
}
if (i === md_buf.length) {
break
}
key[ki++] = md_buf[i]
keyLen--
i++
}
}
if (ivLen > 0 && i !== md_buf.length) {
while (true) {
if (ivLen === 0) {
break
}
if (i === md_buf.length) {
break
}
iv[ii++] = md_buf[i]
ivLen--
i++
}
}
if (keyLen === 0 && ivLen === 0) {
break
}
}
for (i = 0; i < md_buf.length; i++) {
md_buf[i] = 0
}
return {
key: key,
iv: iv
}
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"create-hash/md5":132}],36:[function(require,module,exports){
(function (Buffer){
'use strict'
exports['RSA-SHA224'] = exports.sha224WithRSAEncryption = {
sign: 'rsa',
hash: 'sha224',
id: new Buffer('302d300d06096086480165030402040500041c', 'hex')
}
exports['RSA-SHA256'] = exports.sha256WithRSAEncryption = {
sign: 'rsa',
hash: 'sha256',
id: new Buffer('3031300d060960864801650304020105000420', 'hex')
}
exports['RSA-SHA384'] = exports.sha384WithRSAEncryption = {
sign: 'rsa',
hash: 'sha384',
id: new Buffer('3041300d060960864801650304020205000430', 'hex')
}
exports['RSA-SHA512'] = exports.sha512WithRSAEncryption = {
sign: 'rsa',
hash: 'sha512',
id: new Buffer('3051300d060960864801650304020305000440', 'hex')
}
exports['RSA-SHA1'] = {
sign: 'rsa',
hash: 'sha1',
id: new Buffer('3021300906052b0e03021a05000414', 'hex')
}
exports['ecdsa-with-SHA1'] = {
sign: 'ecdsa',
hash: 'sha1',
id: new Buffer('', 'hex')
}
exports.DSA = exports['DSA-SHA1'] = exports['DSA-SHA'] = {
sign: 'dsa',
hash: 'sha1',
id: new Buffer('', 'hex')
}
exports['DSA-SHA224'] = exports['DSA-WITH-SHA224'] = {
sign: 'dsa',
hash: 'sha224',
id: new Buffer('', 'hex')
}
exports['DSA-SHA256'] = exports['DSA-WITH-SHA256'] = {
sign: 'dsa',
hash: 'sha256',
id: new Buffer('', 'hex')
}
exports['DSA-SHA384'] = exports['DSA-WITH-SHA384'] = {
sign: 'dsa',
hash: 'sha384',
id: new Buffer('', 'hex')
}
exports['DSA-SHA512'] = exports['DSA-WITH-SHA512'] = {
sign: 'dsa',
hash: 'sha512',
id: new Buffer('', 'hex')
}
exports['DSA-RIPEMD160'] = {
sign: 'dsa',
hash: 'rmd160',
id: new Buffer('', 'hex')
}
exports['RSA-RIPEMD160'] = exports.ripemd160WithRSA = {
sign: 'rsa',
hash: 'rmd160',
id: new Buffer('3021300906052b2403020105000414', 'hex')
}
exports['RSA-MD5'] = exports.md5WithRSAEncryption = {
sign: 'rsa',
hash: 'md5',
id: new Buffer('3020300c06082a864886f70d020505000410', 'hex')
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],37:[function(require,module,exports){
(function (Buffer){
var _algos = require('./algos')
var createHash = require('create-hash')
var inherits = require('inherits')
var sign = require('./sign')
var stream = require('stream')
var verify = require('./verify')
var algos = {}
Object.keys(_algos).forEach(function (key) {
algos[key] = algos[key.toLowerCase()] = _algos[key]
})
function Sign (algorithm) {
stream.Writable.call(this)
var data = algos[algorithm]
if (!data) {
throw new Error('Unknown message digest')
}
this._hashType = data.hash
this._hash = createHash(data.hash)
this._tag = data.id
this._signType = data.sign
}
inherits(Sign, stream.Writable)
Sign.prototype._write = function _write (data, _, done) {
this._hash.update(data)
done()
}
Sign.prototype.update = function update (data, enc) {
if (typeof data === 'string') {
data = new Buffer(data, enc)
}
this._hash.update(data)
return this
}
Sign.prototype.sign = function signMethod (key, enc) {
this.end()
var hash = this._hash.digest()
var sig = sign(Buffer.concat([this._tag, hash]), key, this._hashType, this._signType)
return enc ? sig.toString(enc) : sig
}
function Verify (algorithm) {
stream.Writable.call(this)
var data = algos[algorithm]
if (!data) {
throw new Error('Unknown message digest')
}
this._hash = createHash(data.hash)
this._tag = data.id
this._signType = data.sign
}
inherits(Verify, stream.Writable)
Verify.prototype._write = function _write (data, _, done) {
this._hash.update(data)
done()
}
Verify.prototype.update = function update (data, enc) {
if (typeof data === 'string') {
data = new Buffer(data, enc)
}
this._hash.update(data)
return this
}
Verify.prototype.verify = function verifyMethod (key, sig, enc) {
if (typeof sig === 'string') {
sig = new Buffer(sig, enc)
}
this.end()
var hash = this._hash.digest()
return verify(sig, Buffer.concat([this._tag, hash]), key, this._signType)
}
function createSign (algorithm) {
return new Sign(algorithm)
}
function createVerify (algorithm) {
return new Verify(algorithm)
}
module.exports = {
Sign: createSign,
Verify: createVerify,
createSign: createSign,
createVerify: createVerify
}
}).call(this,require("buffer").Buffer)
},{"./algos":36,"./sign":102,"./verify":103,"buffer":2,"create-hash":130,"inherits":199,"stream":216}],38:[function(require,module,exports){
'use strict'
exports['1.3.132.0.10'] = 'secp256k1'
exports['1.3.132.0.33'] = 'p224'
exports['1.2.840.10045.3.1.1'] = 'p192'
exports['1.2.840.10045.3.1.7'] = 'p256'
exports['1.3.132.0.34'] = 'p384'
exports['1.3.132.0.35'] = 'p521'
},{}],39:[function(require,module,exports){
(function (module, exports) {
'use strict';
// Utils
function assert (val, msg) {
if (!val) throw new Error(msg || 'Assertion failed');
}
// Could use `inherits` module, but don't want to move from single file
// architecture yet.
function inherits (ctor, superCtor) {
ctor.super_ = superCtor;
var TempCtor = function () {};
TempCtor.prototype = superCtor.prototype;
ctor.prototype = new TempCtor();
ctor.prototype.constructor = ctor;
}
// BN
function BN (number, base, endian) {
if (BN.isBN(number)) {
return number;
}
this.negative = 0;
this.words = null;
this.length = 0;
// Reduction context
this.red = null;
if (number !== null) {
if (base === 'le' || base === 'be') {
endian = base;
base = 10;
}
this._init(number || 0, base || 10, endian || 'be');
}
}
if (typeof module === 'object') {
module.exports = BN;
} else {
exports.BN = BN;
}
BN.BN = BN;
BN.wordSize = 26;
var Buffer;
try {
Buffer = require('buf' + 'fer').Buffer;
} catch (e) {
}
BN.isBN = function isBN (num) {
return num !== null && typeof num === 'object' &&
num.constructor.name === 'BN' && Array.isArray(num.words);
};
BN.max = function max (left, right) {
if (left.cmp(right) > 0) return left;
return right;
};
BN.min = function min (left, right) {
if (left.cmp(right) < 0) return left;
return right;
};
BN.prototype._init = function init (number, base, endian) {
if (typeof number === 'number') {
return this._initNumber(number, base, endian);
}
if (typeof number === 'object') {
return this._initArray(number, base, endian);
}
if (base === 'hex') {
base = 16;
}
assert(base === (base | 0) && base >= 2 && base <= 36);
number = number.toString().replace(/\s+/g, '');
var start = 0;
if (number[0] === '-') {
start++;
}
if (base === 16) {
this._parseHex(number, start);
} else {
this._parseBase(number, base, start);
}
if (number[0] === '-') {
this.negative = 1;
}
this.strip();
if (endian !== 'le') return;
this._initArray(this.toArray(), base, endian);
};
BN.prototype._initNumber = function _initNumber (number, base, endian) {
if (number < 0) {
this.negative = 1;
number = -number;
}
if (number < 0x4000000) {
this.words = [ number & 0x3ffffff ];
this.length = 1;
} else if (number < 0x10000000000000) {
this.words = [
number & 0x3ffffff,
(number / 0x4000000) & 0x3ffffff
];
this.length = 2;
} else {
assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
this.words = [
number & 0x3ffffff,
(number / 0x4000000) & 0x3ffffff,
1
];
this.length = 3;
}
if (endian !== 'le') return;
// Reverse the bytes
this._initArray(this.toArray(), base, endian);
};
BN.prototype._initArray = function _initArray (number, base, endian) {
// Perhaps a Uint8Array
assert(typeof number.length === 'number');
if (number.length <= 0) {
this.words = [ 0 ];
this.length = 1;
return this;
}
this.length = Math.ceil(number.length / 3);
this.words = new Array(this.length);
for (var i = 0; i < this.length; i++) {
this.words[i] = 0;
}
var j, w;
var off = 0;
if (endian === 'be') {
for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
this.words[j] |= (w << off) & 0x3ffffff;
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
off += 24;
if (off >= 26) {
off -= 26;
j++;
}
}
} else if (endian === 'le') {
for (i = 0, j = 0; i < number.length; i += 3) {
w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
this.words[j] |= (w << off) & 0x3ffffff;
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
off += 24;
if (off >= 26) {
off -= 26;
j++;
}
}
}
return this.strip();
};
function parseHex (str, start, end) {
var r = 0;
var len = Math.min(str.length, end);
for (var i = start; i < len; i++) {
var c = str.charCodeAt(i) - 48;
r <<= 4;
// 'a' - 'f'
if (c >= 49 && c <= 54) {
r |= c - 49 + 0xa;
// 'A' - 'F'
} else if (c >= 17 && c <= 22) {
r |= c - 17 + 0xa;
// '0' - '9'
} else {
r |= c & 0xf;
}
}
return r;
}
BN.prototype._parseHex = function _parseHex (number, start) {
// Create possibly bigger array to ensure that it fits the number
this.length = Math.ceil((number.length - start) / 6);
this.words = new Array(this.length);
for (var i = 0; i < this.length; i++) {
this.words[i] = 0;
}
var j, w;
// Scan 24-bit chunks and add them to the number
var off = 0;
for (i = number.length - 6, j = 0; i >= start; i -= 6) {
w = parseHex(number, i, i + 6);
this.words[j] |= (w << off) & 0x3ffffff;
// NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
off += 24;
if (off >= 26) {
off -= 26;
j++;
}
}
if (i + 6 !== start) {
w = parseHex(number, start, i + 6);
this.words[j] |= (w << off) & 0x3ffffff;
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
}
this.strip();
};
function parseBase (str, start, end, mul) {
var r = 0;
var len = Math.min(str.length, end);
for (var i = start; i < len; i++) {
var c = str.charCodeAt(i) - 48;
r *= mul;
// 'a'
if (c >= 49) {
r += c - 49 + 0xa;
// 'A'
} else if (c >= 17) {
r += c - 17 + 0xa;
// '0' - '9'
} else {
r += c;
}
}
return r;
}
BN.prototype._parseBase = function _parseBase (number, base, start) {
// Initialize as zero
this.words = [ 0 ];
this.length = 1;
// Find length of limb in base
for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
limbLen++;
}
limbLen--;
limbPow = (limbPow / base) | 0;
var total = number.length - start;
var mod = total % limbLen;
var end = Math.min(total, total - mod) + start;
var word = 0;
for (var i = start; i < end; i += limbLen) {
word = parseBase(number, i, i + limbLen, base);
this.imuln(limbPow);
if (this.words[0] + word < 0x4000000) {
this.words[0] += word;
} else {
this._iaddn(word);
}
}
if (mod !== 0) {
var pow = 1;
word = parseBase(number, i, number.length, base);
for (i = 0; i < mod; i++) {
pow *= base;
}
this.imuln(pow);
if (this.words[0] + word < 0x4000000) {
this.words[0] += word;
} else {
this._iaddn(word);
}
}
};
BN.prototype.copy = function copy (dest) {
dest.words = new Array(this.length);
for (var i = 0; i < this.length; i++) {
dest.words[i] = this.words[i];
}
dest.length = this.length;
dest.negative = this.negative;
dest.red = this.red;
};
BN.prototype.clone = function clone () {
var r = new BN(null);
this.copy(r);
return r;
};
BN.prototype._expand = function _expand (size) {
while (this.length < size) {
this.words[this.length++] = 0;
}
return this;
};
// Remove leading `0` from `this`
BN.prototype.strip = function strip () {
while (this.length > 1 && this.words[this.length - 1] === 0) {
this.length--;
}
return this._normSign();
};
BN.prototype._normSign = function _normSign () {
// -0 = 0
if (this.length === 1 && this.words[0] === 0) {
this.negative = 0;
}
return this;
};
BN.prototype.inspect = function inspect () {
return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
};
/*
var zeros = [];
var groupSizes = [];
var groupBases = [];
var s = '';
var i = -1;
while (++i < BN.wordSize) {
zeros[i] = s;
s += '0';
}
groupSizes[0] = 0;
groupSizes[1] = 0;
groupBases[0] = 0;
groupBases[1] = 0;
var base = 2 - 1;
while (++base < 36 + 1) {
var groupSize = 0;
var groupBase = 1;
while (groupBase < (1 << BN.wordSize) / base) {
groupBase *= base;
groupSize += 1;
}
groupSizes[base] = groupSize;
groupBases[base] = groupBase;
}
*/
var zeros = [
'',
'0',
'00',
'000',
'0000',
'00000',
'000000',
'0000000',
'00000000',
'000000000',
'0000000000',
'00000000000',
'000000000000',
'0000000000000',
'00000000000000',
'000000000000000',
'0000000000000000',
'00000000000000000',
'000000000000000000',
'0000000000000000000',
'00000000000000000000',
'000000000000000000000',
'0000000000000000000000',
'00000000000000000000000',
'000000000000000000000000',
'0000000000000000000000000'
];
var groupSizes = [
0, 0,
25, 16, 12, 11, 10, 9, 8,
8, 7, 7, 7, 7, 6, 6,
6, 6, 6, 6, 6, 5, 5,
5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5
];
var groupBases = [
0, 0,
33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
];
BN.prototype.toString = function toString (base, padding) {
base = base || 10;
padding = padding | 0 || 1;
var out;
if (base === 16 || base === 'hex') {
out = '';
var off = 0;
var carry = 0;
for (var i = 0; i < this.length; i++) {
var w = this.words[i];
var word = (((w << off) | carry) & 0xffffff).toString(16);
carry = (w >>> (24 - off)) & 0xffffff;
if (carry !== 0 || i !== this.length - 1) {
out = zeros[6 - word.length] + word + out;
} else {
out = word + out;
}
off += 2;
if (off >= 26) {
off -= 26;
i--;
}
}
if (carry !== 0) {
out = carry.toString(16) + out;
}
while (out.length % padding !== 0) {
out = '0' + out;
}
if (this.negative !== 0) {
out = '-' + out;
}
return out;
}
if (base === (base | 0) && base >= 2 && base <= 36) {
// var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
var groupSize = groupSizes[base];
// var groupBase = Math.pow(base, groupSize);
var groupBase = groupBases[base];
out = '';
var c = this.clone();
c.negative = 0;
while (!c.isZero()) {
var r = c.modn(groupBase).toString(base);
c = c.idivn(groupBase);
if (!c.isZero()) {
out = zeros[groupSize - r.length] + r + out;
} else {
out = r + out;
}
}
if (this.isZero()) {
out = '0' + out;
}
while (out.length % padding !== 0) {
out = '0' + out;
}
if (this.negative !== 0) {
out = '-' + out;
}
return out;
}
assert(false, 'Base should be between 2 and 36');
};
BN.prototype.toNumber = function toNumber () {
var ret = this.words[0];
if (this.length === 2) {
ret += this.words[1] * 0x4000000;
} else if (this.length === 3 && this.words[2] === 0x01) {
// NOTE: at this stage it is known that the top bit is set
ret += 0x10000000000000 + (this.words[1] * 0x4000000);
} else if (this.length > 2) {
assert(false, 'Number can only safely store up to 53 bits');
}
return (this.negative !== 0) ? -ret : ret;
};
BN.prototype.toJSON = function toJSON () {
return this.toString(16);
};
BN.prototype.toBuffer = function toBuffer (endian, length) {
assert(typeof Buffer !== 'undefined');
return this.toArrayLike(Buffer, endian, length);
};
BN.prototype.toArray = function toArray (endian, length) {
return this.toArrayLike(Array, endian, length);
};
BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
var byteLength = this.byteLength();
var reqLength = length || Math.max(1, byteLength);
assert(byteLength <= reqLength, 'byte array longer than desired length');
assert(reqLength > 0, 'Requested array length <= 0');
this.strip();
var littleEndian = endian === 'le';
var res = new ArrayType(reqLength);
var b, i;
var q = this.clone();
if (!littleEndian) {
// Assume big-endian
for (i = 0; i < reqLength - byteLength; i++) {
res[i] = 0;
}
for (i = 0; !q.isZero(); i++) {
b = q.andln(0xff);
q.iushrn(8);
res[reqLength - i - 1] = b;
}
} else {
for (i = 0; !q.isZero(); i++) {
b = q.andln(0xff);
q.iushrn(8);
res[i] = b;
}
for (; i < reqLength; i++) {
res[i] = 0;
}
}
return res;
};
if (Math.clz32) {
BN.prototype._countBits = function _countBits (w) {
return 32 - Math.clz32(w);
};
} else {
BN.prototype._countBits = function _countBits (w) {
var t = w;
var r = 0;
if (t >= 0x1000) {
r += 13;
t >>>= 13;
}
if (t >= 0x40) {
r += 7;
t >>>= 7;
}
if (t >= 0x8) {
r += 4;
t >>>= 4;
}
if (t >= 0x02) {
r += 2;
t >>>= 2;
}
return r + t;
};
}
BN.prototype._zeroBits = function _zeroBits (w) {
// Short-cut
if (w === 0) return 26;
var t = w;
var r = 0;
if ((t & 0x1fff) === 0) {
r += 13;
t >>>= 13;
}
if ((t & 0x7f) === 0) {
r += 7;
t >>>= 7;
}
if ((t & 0xf) === 0) {
r += 4;
t >>>= 4;
}
if ((t & 0x3) === 0) {
r += 2;
t >>>= 2;
}
if ((t & 0x1) === 0) {
r++;
}
return r;
};
// Return number of used bits in a BN
BN.prototype.bitLength = function bitLength () {
var w = this.words[this.length - 1];
var hi = this._countBits(w);
return (this.length - 1) * 26 + hi;
};
function toBitArray (num) {
var w = new Array(num.bitLength());
for (var bit = 0; bit < w.length; bit++) {
var off = (bit / 26) | 0;
var wbit = bit % 26;
w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
}
return w;
}
// Number of trailing zero bits
BN.prototype.zeroBits = function zeroBits () {
if (this.isZero()) return 0;
var r = 0;
for (var i = 0; i < this.length; i++) {
var b = this._zeroBits(this.words[i]);
r += b;
if (b !== 26) break;
}
return r;
};
BN.prototype.byteLength = function byteLength () {
return Math.ceil(this.bitLength() / 8);
};
BN.prototype.toTwos = function toTwos (width) {
if (this.negative !== 0) {
return this.abs().inotn(width).iaddn(1);
}
return this.clone();
};
BN.prototype.fromTwos = function fromTwos (width) {
if (this.testn(width - 1)) {
return this.notn(width).iaddn(1).ineg();
}
return this.clone();
};
BN.prototype.isNeg = function isNeg () {
return this.negative !== 0;
};
// Return negative clone of `this`
BN.prototype.neg = function neg () {
return this.clone().ineg();
};
BN.prototype.ineg = function ineg () {
if (!this.isZero()) {
this.negative ^= 1;
}
return this;
};
// Or `num` with `this` in-place
BN.prototype.iuor = function iuor (num) {
while (this.length < num.length) {
this.words[this.length++] = 0;
}
for (var i = 0; i < num.length; i++) {
this.words[i] = this.words[i] | num.words[i];
}
return this.strip();
};
BN.prototype.ior = function ior (num) {
assert((this.negative | num.negative) === 0);
return this.iuor(num);
};
// Or `num` with `this`
BN.prototype.or = function or (num) {
if (this.length > num.length) return this.clone().ior(num);
return num.clone().ior(this);
};
BN.prototype.uor = function uor (num) {
if (this.length > num.length) return this.clone().iuor(num);
return num.clone().iuor(this);
};
// And `num` with `this` in-place
BN.prototype.iuand = function iuand (num) {
// b = min-length(num, this)
var b;
if (this.length > num.length) {
b = num;
} else {
b = this;
}
for (var i = 0; i < b.length; i++) {
this.words[i] = this.words[i] & num.words[i];
}
this.length = b.length;
return this.strip();
};
BN.prototype.iand = function iand (num) {
assert((this.negative | num.negative) === 0);
return this.iuand(num);
};
// And `num` with `this`
BN.prototype.and = function and (num) {
if (this.length > num.length) return this.clone().iand(num);
return num.clone().iand(this);
};
BN.prototype.uand = function uand (num) {
if (this.length > num.length) return this.clone().iuand(num);
return num.clone().iuand(this);
};
// Xor `num` with `this` in-place
BN.prototype.iuxor = function iuxor (num) {
// a.length > b.length
var a;
var b;
if (this.length > num.length) {
a = this;
b = num;
} else {
a = num;
b = this;
}
for (var i = 0; i < b.length; i++) {
this.words[i] = a.words[i] ^ b.words[i];
}
if (this !== a) {
for (; i < a.length; i++) {
this.words[i] = a.words[i];
}
}
this.length = a.length;
return this.strip();
};
BN.prototype.ixor = function ixor (num) {
assert((this.negative | num.negative) === 0);
return this.iuxor(num);
};
// Xor `num` with `this`
BN.prototype.xor = function xor (num) {
if (this.length > num.length) return this.clone().ixor(num);
return num.clone().ixor(this);
};
BN.prototype.uxor = function uxor (num) {
if (this.length > num.length) return this.clone().iuxor(num);
return num.clone().iuxor(this);
};
// Not ``this`` with ``width`` bitwidth
BN.prototype.inotn = function inotn (width) {
assert(typeof width === 'number' && width >= 0);
var bytesNeeded = Math.ceil(width / 26) | 0;
var bitsLeft = width % 26;
// Extend the buffer with leading zeroes
this._expand(bytesNeeded);
if (bitsLeft > 0) {
bytesNeeded--;
}
// Handle complete words
for (var i = 0; i < bytesNeeded; i++) {
this.words[i] = ~this.words[i] & 0x3ffffff;
}
// Handle the residue
if (bitsLeft > 0) {
this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
}
// And remove leading zeroes
return this.strip();
};
BN.prototype.notn = function notn (width) {
return this.clone().inotn(width);
};
// Set `bit` of `this`
BN.prototype.setn = function setn (bit, val) {
assert(typeof bit === 'number' && bit >= 0);
var off = (bit / 26) | 0;
var wbit = bit % 26;
this._expand(off + 1);
if (val) {
this.words[off] = this.words[off] | (1 << wbit);
} else {
this.words[off] = this.words[off] & ~(1 << wbit);
}
return this.strip();
};
// Add `num` to `this` in-place
BN.prototype.iadd = function iadd (num) {
var r;
// negative + positive
if (this.negative !== 0 && num.negative === 0) {
this.negative = 0;
r = this.isub(num);
this.negative ^= 1;
return this._normSign();
// positive + negative
} else if (this.negative === 0 && num.negative !== 0) {
num.negative = 0;
r = this.isub(num);
num.negative = 1;
return r._normSign();
}
// a.length > b.length
var a, b;
if (this.length > num.length) {
a = this;
b = num;
} else {
a = num;
b = this;
}
var carry = 0;
for (var i = 0; i < b.length; i++) {
r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
this.words[i] = r & 0x3ffffff;
carry = r >>> 26;
}
for (; carry !== 0 && i < a.length; i++) {
r = (a.words[i] | 0) + carry;
this.words[i] = r & 0x3ffffff;
carry = r >>> 26;
}
this.length = a.length;
if (carry !== 0) {
this.words[this.length] = carry;
this.length++;
// Copy the rest of the words
} else if (a !== this) {
for (; i < a.length; i++) {
this.words[i] = a.words[i];
}
}
return this;
};
// Add `num` to `this`
BN.prototype.add = function add (num) {
var res;
if (num.negative !== 0 && this.negative === 0) {
num.negative = 0;
res = this.sub(num);
num.negative ^= 1;
return res;
} else if (num.negative === 0 && this.negative !== 0) {
this.negative = 0;
res = num.sub(this);
this.negative = 1;
return res;
}
if (this.length > num.length) return this.clone().iadd(num);
return num.clone().iadd(this);
};
// Subtract `num` from `this` in-place
BN.prototype.isub = function isub (num) {
// this - (-num) = this + num
if (num.negative !== 0) {
num.negative = 0;
var r = this.iadd(num);
num.negative = 1;
return r._normSign();
// -this - num = -(this + num)
} else if (this.negative !== 0) {
this.negative = 0;
this.iadd(num);
this.negative = 1;
return this._normSign();
}
// At this point both numbers are positive
var cmp = this.cmp(num);
// Optimization - zeroify
if (cmp === 0) {
this.negative = 0;
this.length = 1;
this.words[0] = 0;
return this;
}
// a > b
var a, b;
if (cmp > 0) {
a = this;
b = num;
} else {
a = num;
b = this;
}
var carry = 0;
for (var i = 0; i < b.length; i++) {
r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
carry = r >> 26;
this.words[i] = r & 0x3ffffff;
}
for (; carry !== 0 && i < a.length; i++) {
r = (a.words[i] | 0) + carry;
carry = r >> 26;
this.words[i] = r & 0x3ffffff;
}
// Copy rest of the words
if (carry === 0 && i < a.length && a !== this) {
for (; i < a.length; i++) {
this.words[i] = a.words[i];
}
}
this.length = Math.max(this.length, i);
if (a !== this) {
this.negative = 1;
}
return this.strip();
};
// Subtract `num` from `this`
BN.prototype.sub = function sub (num) {
return this.clone().isub(num);
};
function smallMulTo (self, num, out) {
out.negative = num.negative ^ self.negative;
var len = (self.length + num.length) | 0;
out.length = len;
len = (len - 1) | 0;
// Peel one iteration (compiler can't do it, because of code complexity)
var a = self.words[0] | 0;
var b = num.words[0] | 0;
var r = a * b;
var lo = r & 0x3ffffff;
var carry = (r / 0x4000000) | 0;
out.words[0] = lo;
for (var k = 1; k < len; k++) {
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
// note that ncarry could be >= 0x3ffffff
var ncarry = carry >>> 26;
var rword = carry & 0x3ffffff;
var maxJ = Math.min(k, num.length - 1);
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
var i = (k - j) | 0;
a = self.words[i] | 0;
b = num.words[j] | 0;
r = a * b + rword;
ncarry += (r / 0x4000000) | 0;
rword = r & 0x3ffffff;
}
out.words[k] = rword | 0;
carry = ncarry | 0;
}
if (carry !== 0) {
out.words[k] = carry | 0;
} else {
out.length--;
}
return out.strip();
}
// TODO(indutny): it may be reasonable to omit it for users who don't need
// to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
// multiplication (like elliptic secp256k1).
var comb10MulTo = function comb10MulTo (self, num, out) {
var a = self.words;
var b = num.words;
var o = out.words;
var c = 0;
var lo;
var mid;
var hi;
var a0 = a[0] | 0;
var al0 = a0 & 0x1fff;
var ah0 = a0 >>> 13;
var a1 = a[1] | 0;
var al1 = a1 & 0x1fff;
var ah1 = a1 >>> 13;
var a2 = a[2] | 0;
var al2 = a2 & 0x1fff;
var ah2 = a2 >>> 13;
var a3 = a[3] | 0;
var al3 = a3 & 0x1fff;
var ah3 = a3 >>> 13;
var a4 = a[4] | 0;
var al4 = a4 & 0x1fff;
var ah4 = a4 >>> 13;
var a5 = a[5] | 0;
var al5 = a5 & 0x1fff;
var ah5 = a5 >>> 13;
var a6 = a[6] | 0;
var al6 = a6 & 0x1fff;
var ah6 = a6 >>> 13;
var a7 = a[7] | 0;
var al7 = a7 & 0x1fff;
var ah7 = a7 >>> 13;
var a8 = a[8] | 0;
var al8 = a8 & 0x1fff;
var ah8 = a8 >>> 13;
var a9 = a[9] | 0;
var al9 = a9 & 0x1fff;
var ah9 = a9 >>> 13;
var b0 = b[0] | 0;
var bl0 = b0 & 0x1fff;
var bh0 = b0 >>> 13;
var b1 = b[1] | 0;
var bl1 = b1 & 0x1fff;
var bh1 = b1 >>> 13;
var b2 = b[2] | 0;
var bl2 = b2 & 0x1fff;
var bh2 = b2 >>> 13;
var b3 = b[3] | 0;
var bl3 = b3 & 0x1fff;
var bh3 = b3 >>> 13;
var b4 = b[4] | 0;
var bl4 = b4 & 0x1fff;
var bh4 = b4 >>> 13;
var b5 = b[5] | 0;
var bl5 = b5 & 0x1fff;
var bh5 = b5 >>> 13;
var b6 = b[6] | 0;
var bl6 = b6 & 0x1fff;
var bh6 = b6 >>> 13;
var b7 = b[7] | 0;
var bl7 = b7 & 0x1fff;
var bh7 = b7 >>> 13;
var b8 = b[8] | 0;
var bl8 = b8 & 0x1fff;
var bh8 = b8 >>> 13;
var b9 = b[9] | 0;
var bl9 = b9 & 0x1fff;
var bh9 = b9 >>> 13;
out.negative = self.negative ^ num.negative;
out.length = 19;
/* k = 0 */
lo = Math.imul(al0, bl0);
mid = Math.imul(al0, bh0);
mid += Math.imul(ah0, bl0);
hi = Math.imul(ah0, bh0);
var w0 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w0 >>> 26);
w0 &= 0x3ffffff;
/* k = 1 */
lo = Math.imul(al1, bl0);
mid = Math.imul(al1, bh0);
mid += Math.imul(ah1, bl0);
hi = Math.imul(ah1, bh0);
lo += Math.imul(al0, bl1);
mid += Math.imul(al0, bh1);
mid += Math.imul(ah0, bl1);
hi += Math.imul(ah0, bh1);
var w1 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w1 >>> 26);
w1 &= 0x3ffffff;
/* k = 2 */
lo = Math.imul(al2, bl0);
mid = Math.imul(al2, bh0);
mid += Math.imul(ah2, bl0);
hi = Math.imul(ah2, bh0);
lo += Math.imul(al1, bl1);
mid += Math.imul(al1, bh1);
mid += Math.imul(ah1, bl1);
hi += Math.imul(ah1, bh1);
lo += Math.imul(al0, bl2);
mid += Math.imul(al0, bh2);
mid += Math.imul(ah0, bl2);
hi += Math.imul(ah0, bh2);
var w2 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w2 >>> 26);
w2 &= 0x3ffffff;
/* k = 3 */
lo = Math.imul(al3, bl0);
mid = Math.imul(al3, bh0);
mid += Math.imul(ah3, bl0);
hi = Math.imul(ah3, bh0);
lo += Math.imul(al2, bl1);
mid += Math.imul(al2, bh1);
mid += Math.imul(ah2, bl1);
hi += Math.imul(ah2, bh1);
lo += Math.imul(al1, bl2);
mid += Math.imul(al1, bh2);
mid += Math.imul(ah1, bl2);
hi += Math.imul(ah1, bh2);
lo += Math.imul(al0, bl3);
mid += Math.imul(al0, bh3);
mid += Math.imul(ah0, bl3);
hi += Math.imul(ah0, bh3);
var w3 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w3 >>> 26);
w3 &= 0x3ffffff;
/* k = 4 */
lo = Math.imul(al4, bl0);
mid = Math.imul(al4, bh0);
mid += Math.imul(ah4, bl0);
hi = Math.imul(ah4, bh0);
lo += Math.imul(al3, bl1);
mid += Math.imul(al3, bh1);
mid += Math.imul(ah3, bl1);
hi += Math.imul(ah3, bh1);
lo += Math.imul(al2, bl2);
mid += Math.imul(al2, bh2);
mid += Math.imul(ah2, bl2);
hi += Math.imul(ah2, bh2);
lo += Math.imul(al1, bl3);
mid += Math.imul(al1, bh3);
mid += Math.imul(ah1, bl3);
hi += Math.imul(ah1, bh3);
lo += Math.imul(al0, bl4);
mid += Math.imul(al0, bh4);
mid += Math.imul(ah0, bl4);
hi += Math.imul(ah0, bh4);
var w4 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w4 >>> 26);
w4 &= 0x3ffffff;
/* k = 5 */
lo = Math.imul(al5, bl0);
mid = Math.imul(al5, bh0);
mid += Math.imul(ah5, bl0);
hi = Math.imul(ah5, bh0);
lo += Math.imul(al4, bl1);
mid += Math.imul(al4, bh1);
mid += Math.imul(ah4, bl1);
hi += Math.imul(ah4, bh1);
lo += Math.imul(al3, bl2);
mid += Math.imul(al3, bh2);
mid += Math.imul(ah3, bl2);
hi += Math.imul(ah3, bh2);
lo += Math.imul(al2, bl3);
mid += Math.imul(al2, bh3);
mid += Math.imul(ah2, bl3);
hi += Math.imul(ah2, bh3);
lo += Math.imul(al1, bl4);
mid += Math.imul(al1, bh4);
mid += Math.imul(ah1, bl4);
hi += Math.imul(ah1, bh4);
lo += Math.imul(al0, bl5);
mid += Math.imul(al0, bh5);
mid += Math.imul(ah0, bl5);
hi += Math.imul(ah0, bh5);
var w5 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w5 >>> 26);
w5 &= 0x3ffffff;
/* k = 6 */
lo = Math.imul(al6, bl0);
mid = Math.imul(al6, bh0);
mid += Math.imul(ah6, bl0);
hi = Math.imul(ah6, bh0);
lo += Math.imul(al5, bl1);
mid += Math.imul(al5, bh1);
mid += Math.imul(ah5, bl1);
hi += Math.imul(ah5, bh1);
lo += Math.imul(al4, bl2);
mid += Math.imul(al4, bh2);
mid += Math.imul(ah4, bl2);
hi += Math.imul(ah4, bh2);
lo += Math.imul(al3, bl3);
mid += Math.imul(al3, bh3);
mid += Math.imul(ah3, bl3);
hi += Math.imul(ah3, bh3);
lo += Math.imul(al2, bl4);
mid += Math.imul(al2, bh4);
mid += Math.imul(ah2, bl4);
hi += Math.imul(ah2, bh4);
lo += Math.imul(al1, bl5);
mid += Math.imul(al1, bh5);
mid += Math.imul(ah1, bl5);
hi += Math.imul(ah1, bh5);
lo += Math.imul(al0, bl6);
mid += Math.imul(al0, bh6);
mid += Math.imul(ah0, bl6);
hi += Math.imul(ah0, bh6);
var w6 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w6 >>> 26);
w6 &= 0x3ffffff;
/* k = 7 */
lo = Math.imul(al7, bl0);
mid = Math.imul(al7, bh0);
mid += Math.imul(ah7, bl0);
hi = Math.imul(ah7, bh0);
lo += Math.imul(al6, bl1);
mid += Math.imul(al6, bh1);
mid += Math.imul(ah6, bl1);
hi += Math.imul(ah6, bh1);
lo += Math.imul(al5, bl2);
mid += Math.imul(al5, bh2);
mid += Math.imul(ah5, bl2);
hi += Math.imul(ah5, bh2);
lo += Math.imul(al4, bl3);
mid += Math.imul(al4, bh3);
mid += Math.imul(ah4, bl3);
hi += Math.imul(ah4, bh3);
lo += Math.imul(al3, bl4);
mid += Math.imul(al3, bh4);
mid += Math.imul(ah3, bl4);
hi += Math.imul(ah3, bh4);
lo += Math.imul(al2, bl5);
mid += Math.imul(al2, bh5);
mid += Math.imul(ah2, bl5);
hi += Math.imul(ah2, bh5);
lo += Math.imul(al1, bl6);
mid += Math.imul(al1, bh6);
mid += Math.imul(ah1, bl6);
hi += Math.imul(ah1, bh6);
lo += Math.imul(al0, bl7);
mid += Math.imul(al0, bh7);
mid += Math.imul(ah0, bl7);
hi += Math.imul(ah0, bh7);
var w7 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w7 >>> 26);
w7 &= 0x3ffffff;
/* k = 8 */
lo = Math.imul(al8, bl0);
mid = Math.imul(al8, bh0);
mid += Math.imul(ah8, bl0);
hi = Math.imul(ah8, bh0);
lo += Math.imul(al7, bl1);
mid += Math.imul(al7, bh1);
mid += Math.imul(ah7, bl1);
hi += Math.imul(ah7, bh1);
lo += Math.imul(al6, bl2);
mid += Math.imul(al6, bh2);
mid += Math.imul(ah6, bl2);
hi += Math.imul(ah6, bh2);
lo += Math.imul(al5, bl3);
mid += Math.imul(al5, bh3);
mid += Math.imul(ah5, bl3);
hi += Math.imul(ah5, bh3);
lo += Math.imul(al4, bl4);
mid += Math.imul(al4, bh4);
mid += Math.imul(ah4, bl4);
hi += Math.imul(ah4, bh4);
lo += Math.imul(al3, bl5);
mid += Math.imul(al3, bh5);
mid += Math.imul(ah3, bl5);
hi += Math.imul(ah3, bh5);
lo += Math.imul(al2, bl6);
mid += Math.imul(al2, bh6);
mid += Math.imul(ah2, bl6);
hi += Math.imul(ah2, bh6);
lo += Math.imul(al1, bl7);
mid += Math.imul(al1, bh7);
mid += Math.imul(ah1, bl7);
hi += Math.imul(ah1, bh7);
lo += Math.imul(al0, bl8);
mid += Math.imul(al0, bh8);
mid += Math.imul(ah0, bl8);
hi += Math.imul(ah0, bh8);
var w8 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w8 >>> 26);
w8 &= 0x3ffffff;
/* k = 9 */
lo = Math.imul(al9, bl0);
mid = Math.imul(al9, bh0);
mid += Math.imul(ah9, bl0);
hi = Math.imul(ah9, bh0);
lo += Math.imul(al8, bl1);
mid += Math.imul(al8, bh1);
mid += Math.imul(ah8, bl1);
hi += Math.imul(ah8, bh1);
lo += Math.imul(al7, bl2);
mid += Math.imul(al7, bh2);
mid += Math.imul(ah7, bl2);
hi += Math.imul(ah7, bh2);
lo += Math.imul(al6, bl3);
mid += Math.imul(al6, bh3);
mid += Math.imul(ah6, bl3);
hi += Math.imul(ah6, bh3);
lo += Math.imul(al5, bl4);
mid += Math.imul(al5, bh4);
mid += Math.imul(ah5, bl4);
hi += Math.imul(ah5, bh4);
lo += Math.imul(al4, bl5);
mid += Math.imul(al4, bh5);
mid += Math.imul(ah4, bl5);
hi += Math.imul(ah4, bh5);
lo += Math.imul(al3, bl6);
mid += Math.imul(al3, bh6);
mid += Math.imul(ah3, bl6);
hi += Math.imul(ah3, bh6);
lo += Math.imul(al2, bl7);
mid += Math.imul(al2, bh7);
mid += Math.imul(ah2, bl7);
hi += Math.imul(ah2, bh7);
lo += Math.imul(al1, bl8);
mid += Math.imul(al1, bh8);
mid += Math.imul(ah1, bl8);
hi += Math.imul(ah1, bh8);
lo += Math.imul(al0, bl9);
mid += Math.imul(al0, bh9);
mid += Math.imul(ah0, bl9);
hi += Math.imul(ah0, bh9);
var w9 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w9 >>> 26);
w9 &= 0x3ffffff;
/* k = 10 */
lo = Math.imul(al9, bl1);
mid = Math.imul(al9, bh1);
mid += Math.imul(ah9, bl1);
hi = Math.imul(ah9, bh1);
lo += Math.imul(al8, bl2);
mid += Math.imul(al8, bh2);
mid += Math.imul(ah8, bl2);
hi += Math.imul(ah8, bh2);
lo += Math.imul(al7, bl3);
mid += Math.imul(al7, bh3);
mid += Math.imul(ah7, bl3);
hi += Math.imul(ah7, bh3);
lo += Math.imul(al6, bl4);
mid += Math.imul(al6, bh4);
mid += Math.imul(ah6, bl4);
hi += Math.imul(ah6, bh4);
lo += Math.imul(al5, bl5);
mid += Math.imul(al5, bh5);
mid += Math.imul(ah5, bl5);
hi += Math.imul(ah5, bh5);
lo += Math.imul(al4, bl6);
mid += Math.imul(al4, bh6);
mid += Math.imul(ah4, bl6);
hi += Math.imul(ah4, bh6);
lo += Math.imul(al3, bl7);
mid += Math.imul(al3, bh7);
mid += Math.imul(ah3, bl7);
hi += Math.imul(ah3, bh7);
lo += Math.imul(al2, bl8);
mid += Math.imul(al2, bh8);
mid += Math.imul(ah2, bl8);
hi += Math.imul(ah2, bh8);
lo += Math.imul(al1, bl9);
mid += Math.imul(al1, bh9);
mid += Math.imul(ah1, bl9);
hi += Math.imul(ah1, bh9);
var w10 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w10 >>> 26);
w10 &= 0x3ffffff;
/* k = 11 */
lo = Math.imul(al9, bl2);
mid = Math.imul(al9, bh2);
mid += Math.imul(ah9, bl2);
hi = Math.imul(ah9, bh2);
lo += Math.imul(al8, bl3);
mid += Math.imul(al8, bh3);
mid += Math.imul(ah8, bl3);
hi += Math.imul(ah8, bh3);
lo += Math.imul(al7, bl4);
mid += Math.imul(al7, bh4);
mid += Math.imul(ah7, bl4);
hi += Math.imul(ah7, bh4);
lo += Math.imul(al6, bl5);
mid += Math.imul(al6, bh5);
mid += Math.imul(ah6, bl5);
hi += Math.imul(ah6, bh5);
lo += Math.imul(al5, bl6);
mid += Math.imul(al5, bh6);
mid += Math.imul(ah5, bl6);
hi += Math.imul(ah5, bh6);
lo += Math.imul(al4, bl7);
mid += Math.imul(al4, bh7);
mid += Math.imul(ah4, bl7);
hi += Math.imul(ah4, bh7);
lo += Math.imul(al3, bl8);
mid += Math.imul(al3, bh8);
mid += Math.imul(ah3, bl8);
hi += Math.imul(ah3, bh8);
lo += Math.imul(al2, bl9);
mid += Math.imul(al2, bh9);
mid += Math.imul(ah2, bl9);
hi += Math.imul(ah2, bh9);
var w11 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w11 >>> 26);
w11 &= 0x3ffffff;
/* k = 12 */
lo = Math.imul(al9, bl3);
mid = Math.imul(al9, bh3);
mid += Math.imul(ah9, bl3);
hi = Math.imul(ah9, bh3);
lo += Math.imul(al8, bl4);
mid += Math.imul(al8, bh4);
mid += Math.imul(ah8, bl4);
hi += Math.imul(ah8, bh4);
lo += Math.imul(al7, bl5);
mid += Math.imul(al7, bh5);
mid += Math.imul(ah7, bl5);
hi += Math.imul(ah7, bh5);
lo += Math.imul(al6, bl6);
mid += Math.imul(al6, bh6);
mid += Math.imul(ah6, bl6);
hi += Math.imul(ah6, bh6);
lo += Math.imul(al5, bl7);
mid += Math.imul(al5, bh7);
mid += Math.imul(ah5, bl7);
hi += Math.imul(ah5, bh7);
lo += Math.imul(al4, bl8);
mid += Math.imul(al4, bh8);
mid += Math.imul(ah4, bl8);
hi += Math.imul(ah4, bh8);
lo += Math.imul(al3, bl9);
mid += Math.imul(al3, bh9);
mid += Math.imul(ah3, bl9);
hi += Math.imul(ah3, bh9);
var w12 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w12 >>> 26);
w12 &= 0x3ffffff;
/* k = 13 */
lo = Math.imul(al9, bl4);
mid = Math.imul(al9, bh4);
mid += Math.imul(ah9, bl4);
hi = Math.imul(ah9, bh4);
lo += Math.imul(al8, bl5);
mid += Math.imul(al8, bh5);
mid += Math.imul(ah8, bl5);
hi += Math.imul(ah8, bh5);
lo += Math.imul(al7, bl6);
mid += Math.imul(al7, bh6);
mid += Math.imul(ah7, bl6);
hi += Math.imul(ah7, bh6);
lo += Math.imul(al6, bl7);
mid += Math.imul(al6, bh7);
mid += Math.imul(ah6, bl7);
hi += Math.imul(ah6, bh7);
lo += Math.imul(al5, bl8);
mid += Math.imul(al5, bh8);
mid += Math.imul(ah5, bl8);
hi += Math.imul(ah5, bh8);
lo += Math.imul(al4, bl9);
mid += Math.imul(al4, bh9);
mid += Math.imul(ah4, bl9);
hi += Math.imul(ah4, bh9);
var w13 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w13 >>> 26);
w13 &= 0x3ffffff;
/* k = 14 */
lo = Math.imul(al9, bl5);
mid = Math.imul(al9, bh5);
mid += Math.imul(ah9, bl5);
hi = Math.imul(ah9, bh5);
lo += Math.imul(al8, bl6);
mid += Math.imul(al8, bh6);
mid += Math.imul(ah8, bl6);
hi += Math.imul(ah8, bh6);
lo += Math.imul(al7, bl7);
mid += Math.imul(al7, bh7);
mid += Math.imul(ah7, bl7);
hi += Math.imul(ah7, bh7);
lo += Math.imul(al6, bl8);
mid += Math.imul(al6, bh8);
mid += Math.imul(ah6, bl8);
hi += Math.imul(ah6, bh8);
lo += Math.imul(al5, bl9);
mid += Math.imul(al5, bh9);
mid += Math.imul(ah5, bl9);
hi += Math.imul(ah5, bh9);
var w14 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w14 >>> 26);
w14 &= 0x3ffffff;
/* k = 15 */
lo = Math.imul(al9, bl6);
mid = Math.imul(al9, bh6);
mid += Math.imul(ah9, bl6);
hi = Math.imul(ah9, bh6);
lo += Math.imul(al8, bl7);
mid += Math.imul(al8, bh7);
mid += Math.imul(ah8, bl7);
hi += Math.imul(ah8, bh7);
lo += Math.imul(al7, bl8);
mid += Math.imul(al7, bh8);
mid += Math.imul(ah7, bl8);
hi += Math.imul(ah7, bh8);
lo += Math.imul(al6, bl9);
mid += Math.imul(al6, bh9);
mid += Math.imul(ah6, bl9);
hi += Math.imul(ah6, bh9);
var w15 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w15 >>> 26);
w15 &= 0x3ffffff;
/* k = 16 */
lo = Math.imul(al9, bl7);
mid = Math.imul(al9, bh7);
mid += Math.imul(ah9, bl7);
hi = Math.imul(ah9, bh7);
lo += Math.imul(al8, bl8);
mid += Math.imul(al8, bh8);
mid += Math.imul(ah8, bl8);
hi += Math.imul(ah8, bh8);
lo += Math.imul(al7, bl9);
mid += Math.imul(al7, bh9);
mid += Math.imul(ah7, bl9);
hi += Math.imul(ah7, bh9);
var w16 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w16 >>> 26);
w16 &= 0x3ffffff;
/* k = 17 */
lo = Math.imul(al9, bl8);
mid = Math.imul(al9, bh8);
mid += Math.imul(ah9, bl8);
hi = Math.imul(ah9, bh8);
lo += Math.imul(al8, bl9);
mid += Math.imul(al8, bh9);
mid += Math.imul(ah8, bl9);
hi += Math.imul(ah8, bh9);
var w17 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w17 >>> 26);
w17 &= 0x3ffffff;
/* k = 18 */
lo = Math.imul(al9, bl9);
mid = Math.imul(al9, bh9);
mid += Math.imul(ah9, bl9);
hi = Math.imul(ah9, bh9);
var w18 = c + lo + ((mid & 0x1fff) << 13);
c = hi + (mid >>> 13) + (w18 >>> 26);
w18 &= 0x3ffffff;
o[0] = w0;
o[1] = w1;
o[2] = w2;
o[3] = w3;
o[4] = w4;
o[5] = w5;
o[6] = w6;
o[7] = w7;
o[8] = w8;
o[9] = w9;
o[10] = w10;
o[11] = w11;
o[12] = w12;
o[13] = w13;
o[14] = w14;
o[15] = w15;
o[16] = w16;
o[17] = w17;
o[18] = w18;
if (c !== 0) {
o[19] = c;
out.length++;
}
return out;
};
// Polyfill comb
if (!Math.imul) {
comb10MulTo = smallMulTo;
}
function bigMulTo (self, num, out) {
out.negative = num.negative ^ self.negative;
out.length = self.length + num.length;
var carry = 0;
var hncarry = 0;
for (var k = 0; k < out.length - 1; k++) {
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
// note that ncarry could be >= 0x3ffffff
var ncarry = hncarry;
hncarry = 0;
var rword = carry & 0x3ffffff;
var maxJ = Math.min(k, num.length - 1);
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
var i = k - j;
var a = self.words[i] | 0;
var b = num.words[j] | 0;
var r = a * b;
var lo = r & 0x3ffffff;
ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
lo = (lo + rword) | 0;
rword = lo & 0x3ffffff;
ncarry = (ncarry + (lo >>> 26)) | 0;
hncarry += ncarry >>> 26;
ncarry &= 0x3ffffff;
}
out.words[k] = rword;
carry = ncarry;
ncarry = hncarry;
}
if (carry !== 0) {
out.words[k] = carry;
} else {
out.length--;
}
return out.strip();
}
function jumboMulTo (self, num, out) {
var fftm = new FFTM();
return fftm.mulp(self, num, out);
}
BN.prototype.mulTo = function mulTo (num, out) {
var res;
var len = this.length + num.length;
if (this.length === 10 && num.length === 10) {
res = comb10MulTo(this, num, out);
} else if (len < 63) {
res = smallMulTo(this, num, out);
} else if (len < 1024) {
res = bigMulTo(this, num, out);
} else {
res = jumboMulTo(this, num, out);
}
return res;
};
// Cooley-Tukey algorithm for FFT
// slightly revisited to rely on looping instead of recursion
function FFTM (x, y) {
this.x = x;
this.y = y;
}
FFTM.prototype.makeRBT = function makeRBT (N) {
var t = new Array(N);
var l = BN.prototype._countBits(N) - 1;
for (var i = 0; i < N; i++) {
t[i] = this.revBin(i, l, N);
}
return t;
};
// Returns binary-reversed representation of `x`
FFTM.prototype.revBin = function revBin (x, l, N) {
if (x === 0 || x === N - 1) return x;
var rb = 0;
for (var i = 0; i < l; i++) {
rb |= (x & 1) << (l - i - 1);
x >>= 1;
}
return rb;
};
// Performs "tweedling" phase, therefore 'emulating'
// behaviour of the recursive algorithm
FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
for (var i = 0; i < N; i++) {
rtws[i] = rws[rbt[i]];
itws[i] = iws[rbt[i]];
}
};
FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
this.permute(rbt, rws, iws, rtws, itws, N);
for (var s = 1; s < N; s <<= 1) {
var l = s << 1;
var rtwdf = Math.cos(2 * Math.PI / l);
var itwdf = Math.sin(2 * Math.PI / l);
for (var p = 0; p < N; p += l) {
var rtwdf_ = rtwdf;
var itwdf_ = itwdf;
for (var j = 0; j < s; j++) {
var re = rtws[p + j];
var ie = itws[p + j];
var ro = rtws[p + j + s];
var io = itws[p + j + s];
var rx = rtwdf_ * ro - itwdf_ * io;
io = rtwdf_ * io + itwdf_ * ro;
ro = rx;
rtws[p + j] = re + ro;
itws[p + j] = ie + io;
rtws[p + j + s] = re - ro;
itws[p + j + s] = ie - io;
/* jshint maxdepth : false */
if (j !== l) {
rx = rtwdf * rtwdf_ - itwdf * itwdf_;
itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
rtwdf_ = rx;
}
}
}
}
};
FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
var N = Math.max(m, n) | 1;
var odd = N & 1;
var i = 0;
for (N = N / 2 | 0; N; N = N >>> 1) {
i++;
}
return 1 << i + 1 + odd;
};
FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
if (N <= 1) return;
for (var i = 0; i < N / 2; i++) {
var t = rws[i];
rws[i] = rws[N - i - 1];
rws[N - i - 1] = t;
t = iws[i];
iws[i] = -iws[N - i - 1];
iws[N - i - 1] = -t;
}
};
FFTM.prototype.normalize13b = function normalize13b (ws, N) {
var carry = 0;
for (var i = 0; i < N / 2; i++) {
var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
Math.round(ws[2 * i] / N) +
carry;
ws[i] = w & 0x3ffffff;
if (w < 0x4000000) {
carry = 0;
} else {
carry = w / 0x4000000 | 0;
}
}
return ws;
};
FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
var carry = 0;
for (var i = 0; i < len; i++) {
carry = carry + (ws[i] | 0);
rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
}
// Pad with zeroes
for (i = 2 * len; i < N; ++i) {
rws[i] = 0;
}
assert(carry === 0);
assert((carry & ~0x1fff) === 0);
};
FFTM.prototype.stub = function stub (N) {
var ph = new Array(N);
for (var i = 0; i < N; i++) {
ph[i] = 0;
}
return ph;
};
FFTM.prototype.mulp = function mulp (x, y, out) {
var N = 2 * this.guessLen13b(x.length, y.length);
var rbt = this.makeRBT(N);
var _ = this.stub(N);
var rws = new Array(N);
var rwst = new Array(N);
var iwst = new Array(N);
var nrws = new Array(N);
var nrwst = new Array(N);
var niwst = new Array(N);
var rmws = out.words;
rmws.length = N;
this.convert13b(x.words, x.length, rws, N);
this.convert13b(y.words, y.length, nrws, N);
this.transform(rws, _, rwst, iwst, N, rbt);
this.transform(nrws, _, nrwst, niwst, N, rbt);
for (var i = 0; i < N; i++) {
var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
rwst[i] = rx;
}
this.conjugate(rwst, iwst, N);
this.transform(rwst, iwst, rmws, _, N, rbt);
this.conjugate(rmws, _, N);
this.normalize13b(rmws, N);
out.negative = x.negative ^ y.negative;
out.length = x.length + y.length;
return out.strip();
};
// Multiply `this` by `num`
BN.prototype.mul = function mul (num) {
var out = new BN(null);
out.words = new Array(this.length + num.length);
return this.mulTo(num, out);
};
// Multiply employing FFT
BN.prototype.mulf = function mulf (num) {
var out = new BN(null);
out.words = new Array(this.length + num.length);
return jumboMulTo(this, num, out);
};
// In-place Multiplication
BN.prototype.imul = function imul (num) {
return this.clone().mulTo(num, this);
};
BN.prototype.imuln = function imuln (num) {
assert(typeof num === 'number');
assert(num < 0x4000000);
// Carry
var carry = 0;
for (var i = 0; i < this.length; i++) {
var w = (this.words[i] | 0) * num;
var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
carry >>= 26;
carry += (w / 0x4000000) | 0;
// NOTE: lo is 27bit maximum
carry += lo >>> 26;
this.words[i] = lo & 0x3ffffff;
}
if (carry !== 0) {
this.words[i] = carry;
this.length++;
}
return this;
};
BN.prototype.muln = function muln (num) {
return this.clone().imuln(num);
};
// `this` * `this`
BN.prototype.sqr = function sqr () {
return this.mul(this);
};
// `this` * `this` in-place
BN.prototype.isqr = function isqr () {
return this.imul(this.clone());
};
// Math.pow(`this`, `num`)
BN.prototype.pow = function pow (num) {
var w = toBitArray(num);
if (w.length === 0) return new BN(1);
// Skip leading zeroes
var res = this;
for (var i = 0; i < w.length; i++, res = res.sqr()) {
if (w[i] !== 0) break;
}
if (++i < w.length) {
for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
if (w[i] === 0) continue;
res = res.mul(q);
}
}
return res;
};
// Shift-left in-place
BN.prototype.iushln = function iushln (bits) {
assert(typeof bits === 'number' && bits >= 0);
var r = bits % 26;
var s = (bits - r) / 26;
var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
var i;
if (r !== 0) {
var carry = 0;
for (i = 0; i < this.length; i++) {
var newCarry = this.words[i] & carryMask;
var c = ((this.words[i] | 0) - newCarry) << r;
this.words[i] = c | carry;
carry = newCarry >>> (26 - r);
}
if (carry) {
this.words[i] = carry;
this.length++;
}
}
if (s !== 0) {
for (i = this.length - 1; i >= 0; i--) {
this.words[i + s] = this.words[i];
}
for (i = 0; i < s; i++) {
this.words[i] = 0;
}
this.length += s;
}
return this.strip();
};
BN.prototype.ishln = function ishln (bits) {
// TODO(indutny): implement me
assert(this.negative === 0);
return this.iushln(bits);
};
// Shift-right in-place
// NOTE: `hint` is a lowest bit before trailing zeroes
// NOTE: if `extended` is present - it will be filled with destroyed bits
BN.prototype.iushrn = function iushrn (bits, hint, extended) {
assert(typeof bits === 'number' && bits >= 0);
var h;
if (hint) {
h = (hint - (hint % 26)) / 26;
} else {
h = 0;
}
var r = bits % 26;
var s = Math.min((bits - r) / 26, this.length);
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
var maskedWords = extended;
h -= s;
h = Math.max(0, h);
// Extended mode, copy masked part
if (maskedWords) {
for (var i = 0; i < s; i++) {
maskedWords.words[i] = this.words[i];
}
maskedWords.length = s;
}
if (s === 0) {
// No-op, we should not move anything at all
} else if (this.length > s) {
this.length -= s;
for (i = 0; i < this.length; i++) {
this.words[i] = this.words[i + s];
}
} else {
this.words[0] = 0;
this.length = 1;
}
var carry = 0;
for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
var word = this.words[i] | 0;
this.words[i] = (carry << (26 - r)) | (word >>> r);
carry = word & mask;
}
// Push carried bits as a mask
if (maskedWords && carry !== 0) {
maskedWords.words[maskedWords.length++] = carry;
}
if (this.length === 0) {
this.words[0] = 0;
this.length = 1;
}
return this.strip();
};
BN.prototype.ishrn = function ishrn (bits, hint, extended) {
// TODO(indutny): implement me
assert(this.negative === 0);
return this.iushrn(bits, hint, extended);
};
// Shift-left
BN.prototype.shln = function shln (bits) {
return this.clone().ishln(bits);
};
BN.prototype.ushln = function ushln (bits) {
return this.clone().iushln(bits);
};
// Shift-right
BN.prototype.shrn = function shrn (bits) {
return this.clone().ishrn(bits);
};
BN.prototype.ushrn = function ushrn (bits) {
return this.clone().iushrn(bits);
};
// Test if n bit is set
BN.prototype.testn = function testn (bit) {
assert(typeof bit === 'number' && bit >= 0);
var r = bit % 26;
var s = (bit - r) / 26;
var q = 1 << r;
// Fast case: bit is much higher than all existing words
if (this.length <= s) return false;
// Check bit and return
var w = this.words[s];
return !!(w & q);
};
// Return only lowers bits of number (in-place)
BN.prototype.imaskn = function imaskn (bits) {
assert(typeof bits === 'number' && bits >= 0);
var r = bits % 26;
var s = (bits - r) / 26;
assert(this.negative === 0, 'imaskn works only with positive numbers');
if (r !== 0) {
s++;
}
this.length = Math.min(s, this.length);
if (r !== 0) {
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
this.words[this.length - 1] &= mask;
}
return this.strip();
};
// Return only lowers bits of number
BN.prototype.maskn = function maskn (bits) {
return this.clone().imaskn(bits);
};
// Add plain number `num` to `this`
BN.prototype.iaddn = function iaddn (num) {
assert(typeof num === 'number');
assert(num < 0x4000000);
if (num < 0) return this.isubn(-num);
// Possible sign change
if (this.negative !== 0) {
if (this.length === 1 && (this.words[0] | 0) < num) {
this.words[0] = num - (this.words[0] | 0);
this.negative = 0;
return this;
}
this.negative = 0;
this.isubn(num);
this.negative = 1;
return this;
}
// Add without checks
return this._iaddn(num);
};
BN.prototype._iaddn = function _iaddn (num) {
this.words[0] += num;
// Carry
for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
this.words[i] -= 0x4000000;
if (i === this.length - 1) {
this.words[i + 1] = 1;
} else {
this.words[i + 1]++;
}
}
this.length = Math.max(this.length, i + 1);
return this;
};
// Subtract plain number `num` from `this`
BN.prototype.isubn = function isubn (num) {
assert(typeof num === 'number');
assert(num < 0x4000000);
if (num < 0) return this.iaddn(-num);
if (this.negative !== 0) {
this.negative = 0;
this.iaddn(num);
this.negative = 1;
return this;
}
this.words[0] -= num;
if (this.length === 1 && this.words[0] < 0) {
this.words[0] = -this.words[0];
this.negative = 1;
} else {
// Carry
for (var i = 0; i < this.length && this.words[i] < 0; i++) {
this.words[i] += 0x4000000;
this.words[i + 1] -= 1;
}
}
return this.strip();
};
BN.prototype.addn = function addn (num) {
return this.clone().iaddn(num);
};
BN.prototype.subn = function subn (num) {
return this.clone().isubn(num);
};
BN.prototype.iabs = function iabs () {
this.negative = 0;
return this;
};
BN.prototype.abs = function abs () {
return this.clone().iabs();
};
BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
var len = num.length + shift;
var i;
this._expand(len);
var w;
var carry = 0;
for (i = 0; i < num.length; i++) {
w = (this.words[i + shift] | 0) + carry;
var right = (num.words[i] | 0) * mul;
w -= right & 0x3ffffff;
carry = (w >> 26) - ((right / 0x4000000) | 0);
this.words[i + shift] = w & 0x3ffffff;
}
for (; i < this.length - shift; i++) {
w = (this.words[i + shift] | 0) + carry;
carry = w >> 26;
this.words[i + shift] = w & 0x3ffffff;
}
if (carry === 0) return this.strip();
// Subtraction overflow
assert(carry === -1);
carry = 0;
for (i = 0; i < this.length; i++) {
w = -(this.words[i] | 0) + carry;
carry = w >> 26;
this.words[i] = w & 0x3ffffff;
}
this.negative = 1;
return this.strip();
};
BN.prototype._wordDiv = function _wordDiv (num, mode) {
var shift = this.length - num.length;
var a = this.clone();
var b = num;
// Normalize
var bhi = b.words[b.length - 1] | 0;
var bhiBits = this._countBits(bhi);
shift = 26 - bhiBits;
if (shift !== 0) {
b = b.ushln(shift);
a.iushln(shift);
bhi = b.words[b.length - 1] | 0;
}
// Initialize quotient
var m = a.length - b.length;
var q;
if (mode !== 'mod') {
q = new BN(null);
q.length = m + 1;
q.words = new Array(q.length);
for (var i = 0; i < q.length; i++) {
q.words[i] = 0;
}
}
var diff = a.clone()._ishlnsubmul(b, 1, m);
if (diff.negative === 0) {
a = diff;
if (q) {
q.words[m] = 1;
}
}
for (var j = m - 1; j >= 0; j--) {
var qj = (a.words[b.length + j] | 0) * 0x4000000 +
(a.words[b.length + j - 1] | 0);
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
// (0x7ffffff)
qj = Math.min((qj / bhi) | 0, 0x3ffffff);
a._ishlnsubmul(b, qj, j);
while (a.negative !== 0) {
qj--;
a.negative = 0;
a._ishlnsubmul(b, 1, j);
if (!a.isZero()) {
a.negative ^= 1;
}
}
if (q) {
q.words[j] = qj;
}
}
if (q) {
q.strip();
}
a.strip();
// Denormalize
if (mode !== 'div' && shift !== 0) {
a.iushrn(shift);
}
return {
div: q || null,
mod: a
};
};
// NOTE: 1) `mode` can be set to `mod` to request mod only,
// to `div` to request div only, or be absent to
// request both div & mod
// 2) `positive` is true if unsigned mod is requested
BN.prototype.divmod = function divmod (num, mode, positive) {
assert(!num.isZero());
if (this.isZero()) {
return {
div: new BN(0),
mod: new BN(0)
};
}
var div, mod, res;
if (this.negative !== 0 && num.negative === 0) {
res = this.neg().divmod(num, mode);
if (mode !== 'mod') {
div = res.div.neg();
}
if (mode !== 'div') {
mod = res.mod.neg();
if (positive && mod.negative !== 0) {
mod.iadd(num);
}
}
return {
div: div,
mod: mod
};
}
if (this.negative === 0 && num.negative !== 0) {
res = this.divmod(num.neg(), mode);
if (mode !== 'mod') {
div = res.div.neg();
}
return {
div: div,
mod: res.mod
};
}
if ((this.negative & num.negative) !== 0) {
res = this.neg().divmod(num.neg(), mode);
if (mode !== 'div') {
mod = res.mod.neg();
if (positive && mod.negative !== 0) {
mod.isub(num);
}
}
return {
div: res.div,
mod: mod
};
}
// Both numbers are positive at this point
// Strip both numbers to approximate shift value
if (num.length > this.length || this.cmp(num) < 0) {
return {
div: new BN(0),
mod: this
};
}
// Very short reduction
if (num.length === 1) {
if (mode === 'div') {
return {
div: this.divn(num.words[0]),
mod: null
};
}
if (mode === 'mod') {
return {
div: null,
mod: new BN(this.modn(num.words[0]))
};
}
return {
div: this.divn(num.words[0]),
mod: new BN(this.modn(num.words[0]))
};
}
return this._wordDiv(num, mode);
};
// Find `this` / `num`
BN.prototype.div = function div (num) {
return this.divmod(num, 'div', false).div;
};
// Find `this` % `num`
BN.prototype.mod = function mod (num) {
return this.divmod(num, 'mod', false).mod;
};
BN.prototype.umod = function umod (num) {
return this.divmod(num, 'mod', true).mod;
};
// Find Round(`this` / `num`)
BN.prototype.divRound = function divRound (num) {
var dm = this.divmod(num);
// Fast case - exact division
if (dm.mod.isZero()) return dm.div;
var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
var half = num.ushrn(1);
var r2 = num.andln(1);
var cmp = mod.cmp(half);
// Round down
if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
// Round up
return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
};
BN.prototype.modn = function modn (num) {
assert(num <= 0x3ffffff);
var p = (1 << 26) % num;
var acc = 0;
for (var i = this.length - 1; i >= 0; i--) {
acc = (p * acc + (this.words[i] | 0)) % num;
}
return acc;
};
// In-place division by number
BN.prototype.idivn = function idivn (num) {
assert(num <= 0x3ffffff);
var carry = 0;
for (var i = this.length - 1; i >= 0; i--) {
var w = (this.words[i] | 0) + carry * 0x4000000;
this.words[i] = (w / num) | 0;
carry = w % num;
}
return this.strip();
};
BN.prototype.divn = function divn (num) {
return this.clone().idivn(num);
};
BN.prototype.egcd = function egcd (p) {
assert(p.negative === 0);
assert(!p.isZero());
var x = this;
var y = p.clone();
if (x.negative !== 0) {
x = x.umod(p);
} else {
x = x.clone();
}
// A * x + B * y = x
var A = new BN(1);
var B = new BN(0);
// C * x + D * y = y
var C = new BN(0);
var D = new BN(1);
var g = 0;
while (x.isEven() && y.isEven()) {
x.iushrn(1);
y.iushrn(1);
++g;
}
var yp = y.clone();
var xp = x.clone();
while (!x.isZero()) {
for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
if (i > 0) {
x.iushrn(i);
while (i-- > 0) {
if (A.isOdd() || B.isOdd()) {
A.iadd(yp);
B.isub(xp);
}
A.iushrn(1);
B.iushrn(1);
}
}
for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
if (j > 0) {
y.iushrn(j);
while (j-- > 0) {
if (C.isOdd() || D.isOdd()) {
C.iadd(yp);
D.isub(xp);
}
C.iushrn(1);
D.iushrn(1);
}
}
if (x.cmp(y) >= 0) {
x.isub(y);
A.isub(C);
B.isub(D);
} else {
y.isub(x);
C.isub(A);
D.isub(B);
}
}
return {
a: C,
b: D,
gcd: y.iushln(g)
};
};
// This is reduced incarnation of the binary EEA
// above, designated to invert members of the
// _prime_ fields F(p) at a maximal speed
BN.prototype._invmp = function _invmp (p) {
assert(p.negative === 0);
assert(!p.isZero());
var a = this;
var b = p.clone();
if (a.negative !== 0) {
a = a.umod(p);
} else {
a = a.clone();
}
var x1 = new BN(1);
var x2 = new BN(0);
var delta = b.clone();
while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
if (i > 0) {
a.iushrn(i);
while (i-- > 0) {
if (x1.isOdd()) {
x1.iadd(delta);
}
x1.iushrn(1);
}
}
for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
if (j > 0) {
b.iushrn(j);
while (j-- > 0) {
if (x2.isOdd()) {
x2.iadd(delta);
}
x2.iushrn(1);
}
}
if (a.cmp(b) >= 0) {
a.isub(b);
x1.isub(x2);
} else {
b.isub(a);
x2.isub(x1);
}
}
var res;
if (a.cmpn(1) === 0) {
res = x1;
} else {
res = x2;
}
if (res.cmpn(0) < 0) {
res.iadd(p);
}
return res;
};
BN.prototype.gcd = function gcd (num) {
if (this.isZero()) return num.abs();
if (num.isZero()) return this.abs();
var a = this.clone();
var b = num.clone();
a.negative = 0;
b.negative = 0;
// Remove common factor of two
for (var shift = 0; a.isEven() && b.isEven(); shift++) {
a.iushrn(1);
b.iushrn(1);
}
do {
while (a.isEven()) {
a.iushrn(1);
}
while (b.isEven()) {
b.iushrn(1);
}
var r = a.cmp(b);
if (r < 0) {
// Swap `a` and `b` to make `a` always bigger than `b`
var t = a;
a = b;
b = t;
} else if (r === 0 || b.cmpn(1) === 0) {
break;
}
a.isub(b);
} while (true);
return b.iushln(shift);
};
// Invert number in the field F(num)
BN.prototype.invm = function invm (num) {
return this.egcd(num).a.umod(num);
};
BN.prototype.isEven = function isEven () {
return (this.words[0] & 1) === 0;
};
BN.prototype.isOdd = function isOdd () {
return (this.words[0] & 1) === 1;
};
// And first word and num
BN.prototype.andln = function andln (num) {
return this.words[0] & num;
};
// Increment at the bit position in-line
BN.prototype.bincn = function bincn (bit) {
assert(typeof bit === 'number');
var r = bit % 26;
var s = (bit - r) / 26;
var q = 1 << r;
// Fast case: bit is much higher than all existing words
if (this.length <= s) {
this._expand(s + 1);
this.words[s] |= q;
return this;
}
// Add bit and propagate, if needed
var carry = q;
for (var i = s; carry !== 0 && i < this.length; i++) {
var w = this.words[i] | 0;
w += carry;
carry = w >>> 26;
w &= 0x3ffffff;
this.words[i] = w;
}
if (carry !== 0) {
this.words[i] = carry;
this.length++;
}
return this;
};
BN.prototype.isZero = function isZero () {
return this.length === 1 && this.words[0] === 0;
};
BN.prototype.cmpn = function cmpn (num) {
var negative = num < 0;
if (this.negative !== 0 && !negative) return -1;
if (this.negative === 0 && negative) return 1;
this.strip();
var res;
if (this.length > 1) {
res = 1;
} else {
if (negative) {
num = -num;
}
assert(num <= 0x3ffffff, 'Number is too big');
var w = this.words[0] | 0;
res = w === num ? 0 : w < num ? -1 : 1;
}
if (this.negative !== 0) return -res | 0;
return res;
};
// Compare two numbers and return:
// 1 - if `this` > `num`
// 0 - if `this` == `num`
// -1 - if `this` < `num`
BN.prototype.cmp = function cmp (num) {
if (this.negative !== 0 && num.negative === 0) return -1;
if (this.negative === 0 && num.negative !== 0) return 1;
var res = this.ucmp(num);
if (this.negative !== 0) return -res | 0;
return res;
};
// Unsigned comparison
BN.prototype.ucmp = function ucmp (num) {
// At this point both numbers have the same sign
if (this.length > num.length) return 1;
if (this.length < num.length) return -1;
var res = 0;
for (var i = this.length - 1; i >= 0; i--) {
var a = this.words[i] | 0;
var b = num.words[i] | 0;
if (a === b) continue;
if (a < b) {
res = -1;
} else if (a > b) {
res = 1;
}
break;
}
return res;
};
BN.prototype.gtn = function gtn (num) {
return this.cmpn(num) === 1;
};
BN.prototype.gt = function gt (num) {
return this.cmp(num) === 1;
};
BN.prototype.gten = function gten (num) {
return this.cmpn(num) >= 0;
};
BN.prototype.gte = function gte (num) {
return this.cmp(num) >= 0;
};
BN.prototype.ltn = function ltn (num) {
return this.cmpn(num) === -1;
};
BN.prototype.lt = function lt (num) {
return this.cmp(num) === -1;
};
BN.prototype.lten = function lten (num) {
return this.cmpn(num) <= 0;
};
BN.prototype.lte = function lte (num) {
return this.cmp(num) <= 0;
};
BN.prototype.eqn = function eqn (num) {
return this.cmpn(num) === 0;
};
BN.prototype.eq = function eq (num) {
return this.cmp(num) === 0;
};
//
// A reduce context, could be using montgomery or something better, depending
// on the `m` itself.
//
BN.red = function red (num) {
return new Red(num);
};
BN.prototype.toRed = function toRed (ctx) {
assert(!this.red, 'Already a number in reduction context');
assert(this.negative === 0, 'red works only with positives');
return ctx.convertTo(this)._forceRed(ctx);
};
BN.prototype.fromRed = function fromRed () {
assert(this.red, 'fromRed works only with numbers in reduction context');
return this.red.convertFrom(this);
};
BN.prototype._forceRed = function _forceRed (ctx) {
this.red = ctx;
return this;
};
BN.prototype.forceRed = function forceRed (ctx) {
assert(!this.red, 'Already a number in reduction context');
return this._forceRed(ctx);
};
BN.prototype.redAdd = function redAdd (num) {
assert(this.red, 'redAdd works only with red numbers');
return this.red.add(this, num);
};
BN.prototype.redIAdd = function redIAdd (num) {
assert(this.red, 'redIAdd works only with red numbers');
return this.red.iadd(this, num);
};
BN.prototype.redSub = function redSub (num) {
assert(this.red, 'redSub works only with red numbers');
return this.red.sub(this, num);
};
BN.prototype.redISub = function redISub (num) {
assert(this.red, 'redISub works only with red numbers');
return this.red.isub(this, num);
};
BN.prototype.redShl = function redShl (num) {
assert(this.red, 'redShl works only with red numbers');
return this.red.shl(this, num);
};
BN.prototype.redMul = function redMul (num) {
assert(this.red, 'redMul works only with red numbers');
this.red._verify2(this, num);
return this.red.mul(this, num);
};
BN.prototype.redIMul = function redIMul (num) {
assert(this.red, 'redMul works only with red numbers');
this.red._verify2(this, num);
return this.red.imul(this, num);
};
BN.prototype.redSqr = function redSqr () {
assert(this.red, 'redSqr works only with red numbers');
this.red._verify1(this);
return this.red.sqr(this);
};
BN.prototype.redISqr = function redISqr () {
assert(this.red, 'redISqr works only with red numbers');
this.red._verify1(this);
return this.red.isqr(this);
};
// Square root over p
BN.prototype.redSqrt = function redSqrt () {
assert(this.red, 'redSqrt works only with red numbers');
this.red._verify1(this);
return this.red.sqrt(this);
};
BN.prototype.redInvm = function redInvm () {
assert(this.red, 'redInvm works only with red numbers');
this.red._verify1(this);
return this.red.invm(this);
};
// Return negative clone of `this` % `red modulo`
BN.prototype.redNeg = function redNeg () {
assert(this.red, 'redNeg works only with red numbers');
this.red._verify1(this);
return this.red.neg(this);
};
BN.prototype.redPow = function redPow (num) {
assert(this.red && !num.red, 'redPow(normalNum)');
this.red._verify1(this);
return this.red.pow(this, num);
};
// Prime numbers with efficient reduction
var primes = {
k256: null,
p224: null,
p192: null,
p25519: null
};
// Pseudo-Mersenne prime
function MPrime (name, p) {
// P = 2 ^ N - K
this.name = name;
this.p = new BN(p, 16);
this.n = this.p.bitLength();
this.k = new BN(1).iushln(this.n).isub(this.p);
this.tmp = this._tmp();
}
MPrime.prototype._tmp = function _tmp () {
var tmp = new BN(null);
tmp.words = new Array(Math.ceil(this.n / 13));
return tmp;
};
MPrime.prototype.ireduce = function ireduce (num) {
// Assumes that `num` is less than `P^2`
// num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
var r = num;
var rlen;
do {
this.split(r, this.tmp);
r = this.imulK(r);
r = r.iadd(this.tmp);
rlen = r.bitLength();
} while (rlen > this.n);
var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
if (cmp === 0) {
r.words[0] = 0;
r.length = 1;
} else if (cmp > 0) {
r.isub(this.p);
} else {
r.strip();
}
return r;
};
MPrime.prototype.split = function split (input, out) {
input.iushrn(this.n, 0, out);
};
MPrime.prototype.imulK = function imulK (num) {
return num.imul(this.k);
};
function K256 () {
MPrime.call(
this,
'k256',
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
}
inherits(K256, MPrime);
K256.prototype.split = function split (input, output) {
// 256 = 9 * 26 + 22
var mask = 0x3fffff;
var outLen = Math.min(input.length, 9);
for (var i = 0; i < outLen; i++) {
output.words[i] = input.words[i];
}
output.length = outLen;
if (input.length <= 9) {
input.words[0] = 0;
input.length = 1;
return;
}
// Shift by 9 limbs
var prev = input.words[9];
output.words[output.length++] = prev & mask;
for (i = 10; i < input.length; i++) {
var next = input.words[i] | 0;
input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
prev = next;
}
prev >>>= 22;
input.words[i - 10] = prev;
if (prev === 0 && input.length > 10) {
input.length -= 10;
} else {
input.length -= 9;
}
};
K256.prototype.imulK = function imulK (num) {
// K = 0x1000003d1 = [ 0x40, 0x3d1 ]
num.words[num.length] = 0;
num.words[num.length + 1] = 0;
num.length += 2;
// bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
var lo = 0;
for (var i = 0; i < num.length; i++) {
var w = num.words[i] | 0;
lo += w * 0x3d1;
num.words[i] = lo & 0x3ffffff;
lo = w * 0x40 + ((lo / 0x4000000) | 0);
}
// Fast length reduction
if (num.words[num.length - 1] === 0) {
num.length--;
if (num.words[num.length - 1] === 0) {
num.length--;
}
}
return num;
};
function P224 () {
MPrime.call(
this,
'p224',
'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
}
inherits(P224, MPrime);
function P192 () {
MPrime.call(
this,
'p192',
'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
}
inherits(P192, MPrime);
function P25519 () {
// 2 ^ 255 - 19
MPrime.call(
this,
'25519',
'7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
}
inherits(P25519, MPrime);
P25519.prototype.imulK = function imulK (num) {
// K = 0x13
var carry = 0;
for (var i = 0; i < num.length; i++) {
var hi = (num.words[i] | 0) * 0x13 + carry;
var lo = hi & 0x3ffffff;
hi >>>= 26;
num.words[i] = lo;
carry = hi;
}
if (carry !== 0) {
num.words[num.length++] = carry;
}
return num;
};
// Exported mostly for testing purposes, use plain name instead
BN._prime = function prime (name) {
// Cached version of prime
if (primes[name]) return primes[name];
var prime;
if (name === 'k256') {
prime = new K256();
} else if (name === 'p224') {
prime = new P224();
} else if (name === 'p192') {
prime = new P192();
} else if (name === 'p25519') {
prime = new P25519();
} else {
throw new Error('Unknown prime ' + name);
}
primes[name] = prime;
return prime;
};
//
// Base reduction engine
//
function Red (m) {
if (typeof m === 'string') {
var prime = BN._prime(m);
this.m = prime.p;
this.prime = prime;
} else {
assert(m.gtn(1), 'modulus must be greater than 1');
this.m = m;
this.prime = null;
}
}
Red.prototype._verify1 = function _verify1 (a) {
assert(a.negative === 0, 'red works only with positives');
assert(a.red, 'red works only with red numbers');
};
Red.prototype._verify2 = function _verify2 (a, b) {
assert((a.negative | b.negative) === 0, 'red works only with positives');
assert(a.red && a.red === b.red,
'red works only with red numbers');
};
Red.prototype.imod = function imod (a) {
if (this.prime) return this.prime.ireduce(a)._forceRed(this);
return a.umod(this.m)._forceRed(this);
};
Red.prototype.neg = function neg (a) {
if (a.isZero()) {
return a.clone();
}
return this.m.sub(a)._forceRed(this);
};
Red.prototype.add = function add (a, b) {
this._verify2(a, b);
var res = a.add(b);
if (res.cmp(this.m) >= 0) {
res.isub(this.m);
}
return res._forceRed(this);
};
Red.prototype.iadd = function iadd (a, b) {
this._verify2(a, b);
var res = a.iadd(b);
if (res.cmp(this.m) >= 0) {
res.isub(this.m);
}
return res;
};
Red.prototype.sub = function sub (a, b) {
this._verify2(a, b);
var res = a.sub(b);
if (res.cmpn(0) < 0) {
res.iadd(this.m);
}
return res._forceRed(this);
};
Red.prototype.isub = function isub (a, b) {
this._verify2(a, b);
var res = a.isub(b);
if (res.cmpn(0) < 0) {
res.iadd(this.m);
}
return res;
};
Red.prototype.shl = function shl (a, num) {
this._verify1(a);
return this.imod(a.ushln(num));
};
Red.prototype.imul = function imul (a, b) {
this._verify2(a, b);
return this.imod(a.imul(b));
};
Red.prototype.mul = function mul (a, b) {
this._verify2(a, b);
return this.imod(a.mul(b));
};
Red.prototype.isqr = function isqr (a) {
return this.imul(a, a.clone());
};
Red.prototype.sqr = function sqr (a) {
return this.mul(a, a);
};
Red.prototype.sqrt = function sqrt (a) {
if (a.isZero()) return a.clone();
var mod3 = this.m.andln(3);
assert(mod3 % 2 === 1);
// Fast case
if (mod3 === 3) {
var pow = this.m.add(new BN(1)).iushrn(2);
return this.pow(a, pow);
}
// Tonelli-Shanks algorithm (Totally unoptimized and slow)
//
// Find Q and S, that Q * 2 ^ S = (P - 1)
var q = this.m.subn(1);
var s = 0;
while (!q.isZero() && q.andln(1) === 0) {
s++;
q.iushrn(1);
}
assert(!q.isZero());
var one = new BN(1).toRed(this);
var nOne = one.redNeg();
// Find quadratic non-residue
// NOTE: Max is such because of generalized Riemann hypothesis.
var lpow = this.m.subn(1).iushrn(1);
var z = this.m.bitLength();
z = new BN(2 * z * z).toRed(this);
while (this.pow(z, lpow).cmp(nOne) !== 0) {
z.redIAdd(nOne);
}
var c = this.pow(z, q);
var r = this.pow(a, q.addn(1).iushrn(1));
var t = this.pow(a, q);
var m = s;
while (t.cmp(one) !== 0) {
var tmp = t;
for (var i = 0; tmp.cmp(one) !== 0; i++) {
tmp = tmp.redSqr();
}
assert(i < m);
var b = this.pow(c, new BN(1).iushln(m - i - 1));
r = r.redMul(b);
c = b.redSqr();
t = t.redMul(c);
m = i;
}
return r;
};
Red.prototype.invm = function invm (a) {
var inv = a._invmp(this.m);
if (inv.negative !== 0) {
inv.negative = 0;
return this.imod(inv).redNeg();
} else {
return this.imod(inv);
}
};
Red.prototype.pow = function pow (a, num) {
if (num.isZero()) return new BN(1);
if (num.cmpn(1) === 0) return a.clone();
var windowSize = 4;
var wnd = new Array(1 << windowSize);
wnd[0] = new BN(1).toRed(this);
wnd[1] = a;
for (var i = 2; i < wnd.length; i++) {
wnd[i] = this.mul(wnd[i - 1], a);
}
var res = wnd[0];
var current = 0;
var currentLen = 0;
var start = num.bitLength() % 26;
if (start === 0) {
start = 26;
}
for (i = num.length - 1; i >= 0; i--) {
var word = num.words[i];
for (var j = start - 1; j >= 0; j--) {
var bit = (word >> j) & 1;
if (res !== wnd[0]) {
res = this.sqr(res);
}
if (bit === 0 && current === 0) {
currentLen = 0;
continue;
}
current <<= 1;
current |= bit;
currentLen++;
if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
res = this.mul(res, wnd[current]);
currentLen = 0;
current = 0;
}
start = 26;
}
return res;
};
Red.prototype.convertTo = function convertTo (num) {
var r = num.umod(this.m);
return r === num ? r.clone() : r;
};
Red.prototype.convertFrom = function convertFrom (num) {
var res = num.clone();
res.red = null;
return res;
};
//
// Montgomery method engine
//
BN.mont = function mont (num) {
return new Mont(num);
};
function Mont (m) {
Red.call(this, m);
this.shift = this.m.bitLength();
if (this.shift % 26 !== 0) {
this.shift += 26 - (this.shift % 26);
}
this.r = new BN(1).iushln(this.shift);
this.r2 = this.imod(this.r.sqr());
this.rinv = this.r._invmp(this.m);
this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
this.minv = this.minv.umod(this.r);
this.minv = this.r.sub(this.minv);
}
inherits(Mont, Red);
Mont.prototype.convertTo = function convertTo (num) {
return this.imod(num.ushln(this.shift));
};
Mont.prototype.convertFrom = function convertFrom (num) {
var r = this.imod(num.mul(this.rinv));
r.red = null;
return r;
};
Mont.prototype.imul = function imul (a, b) {
if (a.isZero() || b.isZero()) {
a.words[0] = 0;
a.length = 1;
return a;
}
var t = a.imul(b);
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
var u = t.isub(c).iushrn(this.shift);
var res = u;
if (u.cmp(this.m) >= 0) {
res = u.isub(this.m);
} else if (u.cmpn(0) < 0) {
res = u.iadd(this.m);
}
return res._forceRed(this);
};
Mont.prototype.mul = function mul (a, b) {
if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
var t = a.mul(b);
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
var u = t.isub(c).iushrn(this.shift);
var res = u;
if (u.cmp(this.m) >= 0) {
res = u.isub(this.m);
} else if (u.cmpn(0) < 0) {
res = u.iadd(this.m);
}
return res._forceRed(this);
};
Mont.prototype.invm = function invm (a) {
// (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
var res = this.imod(a._invmp(this.m).mul(this.r2));
return res._forceRed(this);
};
})(typeof module === 'undefined' || module, this);
},{}],40:[function(require,module,exports){
(function (Buffer){
var bn = require('bn.js');
var randomBytes = require('randombytes');
module.exports = crt;
function blind(priv) {
var r = getr(priv);
var blinder = r.toRed(bn.mont(priv.modulus))
.redPow(new bn(priv.publicExponent)).fromRed();
return {
blinder: blinder,
unblinder:r.invm(priv.modulus)
};
}
function crt(msg, priv) {
var blinds = blind(priv);
var len = priv.modulus.byteLength();
var mod = bn.mont(priv.modulus);
var blinded = new bn(msg).mul(blinds.blinder).umod(priv.modulus);
var c1 = blinded.toRed(bn.mont(priv.prime1));
var c2 = blinded.toRed(bn.mont(priv.prime2));
var qinv = priv.coefficient;
var p = priv.prime1;
var q = priv.prime2;
var m1 = c1.redPow(priv.exponent1);
var m2 = c2.redPow(priv.exponent2);
m1 = m1.fromRed();
m2 = m2.fromRed();
var h = m1.isub(m2).imul(qinv).umod(p);
h.imul(q);
m2.iadd(h);
return new Buffer(m2.imul(blinds.unblinder).umod(priv.modulus).toArray(false, len));
}
crt.getr = getr;
function getr(priv) {
var len = priv.modulus.byteLength();
var r = new bn(randomBytes(len));
while (r.cmp(priv.modulus) >= 0 || !r.umod(priv.prime1) || !r.umod(priv.prime2)) {
r = new bn(randomBytes(len));
}
return r;
}
}).call(this,require("buffer").Buffer)
},{"bn.js":39,"buffer":2,"randombytes":197}],41:[function(require,module,exports){
'use strict';
var elliptic = exports;
elliptic.version = require('../package.json').version;
elliptic.utils = require('./elliptic/utils');
elliptic.rand = require('brorand');
elliptic.hmacDRBG = require('./elliptic/hmac-drbg');
elliptic.curve = require('./elliptic/curve');
elliptic.curves = require('./elliptic/curves');
// Protocols
elliptic.ec = require('./elliptic/ec');
elliptic.eddsa = require('./elliptic/eddsa');
},{"../package.json":64,"./elliptic/curve":44,"./elliptic/curves":47,"./elliptic/ec":48,"./elliptic/eddsa":51,"./elliptic/hmac-drbg":54,"./elliptic/utils":56,"brorand":57}],42:[function(require,module,exports){
'use strict';
var BN = require('bn.js');
var elliptic = require('../../elliptic');
var utils = elliptic.utils;
var getNAF = utils.getNAF;
var getJSF = utils.getJSF;
var assert = utils.assert;
function BaseCurve(type, conf) {
this.type = type;
this.p = new BN(conf.p, 16);
// Use Montgomery, when there is no fast reduction for the prime
this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p);
// Useful for many curves
this.zero = new BN(0).toRed(this.red);
this.one = new BN(1).toRed(this.red);
this.two = new BN(2).toRed(this.red);
// Curve configuration, optional
this.n = conf.n && new BN(conf.n, 16);
this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);
// Temporary arrays
this._wnafT1 = new Array(4);
this._wnafT2 = new Array(4);
this._wnafT3 = new Array(4);
this._wnafT4 = new Array(4);
}
module.exports = BaseCurve;
BaseCurve.prototype.point = function point() {
throw new Error('Not implemented');
};
BaseCurve.prototype.validate = function validate() {
throw new Error('Not implemented');
};
BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {
assert(p.precomputed);
var doubles = p._getDoubles();
var naf = getNAF(k, 1);
var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);
I /= 3;
// Translate into more windowed form
var repr = [];
for (var j = 0; j < naf.length; j += doubles.step) {
var nafW = 0;
for (var k = j + doubles.step - 1; k >= j; k--)
nafW = (nafW << 1) + naf[k];
repr.push(nafW);
}
var a = this.jpoint(null, null, null);
var b = this.jpoint(null, null, null);
for (var i = I; i > 0; i--) {
for (var j = 0; j < repr.length; j++) {
var nafW = repr[j];
if (nafW === i)
b = b.mixedAdd(doubles.points[j]);
else if (nafW === -i)
b = b.mixedAdd(doubles.points[j].neg());
}
a = a.add(b);
}
return a.toP();
};
BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {
var w = 4;
// Precompute window
var nafPoints = p._getNAFPoints(w);
w = nafPoints.wnd;
var wnd = nafPoints.points;
// Get NAF form
var naf = getNAF(k, w);
// Add `this`*(N+1) for every w-NAF index
var acc = this.jpoint(null, null, null);
for (var i = naf.length - 1; i >= 0; i--) {
// Count zeroes
for (var k = 0; i >= 0 && naf[i] === 0; i--)
k++;
if (i >= 0)
k++;
acc = acc.dblp(k);
if (i < 0)
break;
var z = naf[i];
assert(z !== 0);
if (p.type === 'affine') {
// J +- P
if (z > 0)
acc = acc.mixedAdd(wnd[(z - 1) >> 1]);
else
acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());
} else {
// J +- J
if (z > 0)
acc = acc.add(wnd[(z - 1) >> 1]);
else
acc = acc.add(wnd[(-z - 1) >> 1].neg());
}
}
return p.type === 'affine' ? acc.toP() : acc;
};
BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,
points,
coeffs,
len) {
var wndWidth = this._wnafT1;
var wnd = this._wnafT2;
var naf = this._wnafT3;
// Fill all arrays
var max = 0;
for (var i = 0; i < len; i++) {
var p = points[i];
var nafPoints = p._getNAFPoints(defW);
wndWidth[i] = nafPoints.wnd;
wnd[i] = nafPoints.points;
}
// Comb small window NAFs
for (var i = len - 1; i >= 1; i -= 2) {
var a = i - 1;
var b = i;
if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {
naf[a] = getNAF(coeffs[a], wndWidth[a]);
naf[b] = getNAF(coeffs[b], wndWidth[b]);
max = Math.max(naf[a].length, max);
max = Math.max(naf[b].length, max);
continue;
}
var comb = [
points[a], /* 1 */
null, /* 3 */
null, /* 5 */
points[b] /* 7 */
];
// Try to avoid Projective points, if possible
if (points[a].y.cmp(points[b].y) === 0) {
comb[1] = points[a].add(points[b]);
comb[2] = points[a].toJ().mixedAdd(points[b].neg());
} else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {
comb[1] = points[a].toJ().mixedAdd(points[b]);
comb[2] = points[a].add(points[b].neg());
} else {
comb[1] = points[a].toJ().mixedAdd(points[b]);
comb[2] = points[a].toJ().mixedAdd(points[b].neg());
}
var index = [
-3, /* -1 -1 */
-1, /* -1 0 */
-5, /* -1 1 */
-7, /* 0 -1 */
0, /* 0 0 */
7, /* 0 1 */
5, /* 1 -1 */
1, /* 1 0 */
3 /* 1 1 */
];
var jsf = getJSF(coeffs[a], coeffs[b]);
max = Math.max(jsf[0].length, max);
naf[a] = new Array(max);
naf[b] = new Array(max);
for (var j = 0; j < max; j++) {
var ja = jsf[0][j] | 0;
var jb = jsf[1][j] | 0;
naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];
naf[b][j] = 0;
wnd[a] = comb;
}
}
var acc = this.jpoint(null, null, null);
var tmp = this._wnafT4;
for (var i = max; i >= 0; i--) {
var k = 0;
while (i >= 0) {
var zero = true;
for (var j = 0; j < len; j++) {
tmp[j] = naf[j][i] | 0;
if (tmp[j] !== 0)
zero = false;
}
if (!zero)
break;
k++;
i--;
}
if (i >= 0)
k++;
acc = acc.dblp(k);
if (i < 0)
break;
for (var j = 0; j < len; j++) {
var z = tmp[j];
var p;
if (z === 0)
continue;
else if (z > 0)
p = wnd[j][(z - 1) >> 1];
else if (z < 0)
p = wnd[j][(-z - 1) >> 1].neg();
if (p.type === 'affine')
acc = acc.mixedAdd(p);
else
acc = acc.add(p);
}
}
// Zeroify references
for (var i = 0; i < len; i++)
wnd[i] = null;
return acc.toP();
};
function BasePoint(curve, type) {
this.curve = curve;
this.type = type;
this.precomputed = null;
}
BaseCurve.BasePoint = BasePoint;
BasePoint.prototype.eq = function eq(/*other*/) {
throw new Error('Not implemented');
};
BasePoint.prototype.validate = function validate() {
return this.curve.validate(this);
};
BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
bytes = utils.toArray(bytes, enc);
var len = this.p.byteLength();
if (bytes[0] === 0x04 && bytes.length - 1 === 2 * len) {
return this.point(bytes.slice(1, 1 + len),
bytes.slice(1 + len, 1 + 2 * len));
} else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
bytes.length - 1 === len) {
return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);
}
throw new Error('Unknown point format');
};
BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {
return this.encode(enc, true);
};
BasePoint.prototype._encode = function _encode(compact) {
var len = this.curve.p.byteLength();
var x = this.getX().toArray('be', len);
if (compact)
return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);
return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ;
};
BasePoint.prototype.encode = function encode(enc, compact) {
return utils.encode(this._encode(compact), enc);
};
BasePoint.prototype.precompute = function precompute(power) {
if (this.precomputed)
return this;
var precomputed = {
doubles: null,
naf: null,
beta: null
};
precomputed.naf = this._getNAFPoints(8);
precomputed.doubles = this._getDoubles(4, power);
precomputed.beta = this._getBeta();
this.precomputed = precomputed;
return this;
};
BasePoint.prototype._hasDoubles = function _hasDoubles(k) {
if (!this.precomputed)
return false;
var doubles = this.precomputed.doubles;
if (!doubles)
return false;
return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);
};
BasePoint.prototype._getDoubles = function _getDoubles(step, power) {
if (this.precomputed && this.precomputed.doubles)
return this.precomputed.doubles;
var doubles = [ this ];
var acc = this;
for (var i = 0; i < power; i += step) {
for (var j = 0; j < step; j++)
acc = acc.dbl();
doubles.push(acc);
}
return {
step: step,
points: doubles
};
};
BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {
if (this.precomputed && this.precomputed.naf)
return this.precomputed.naf;
var res = [ this ];
var max = (1 << wnd) - 1;
var dbl = max === 1 ? null : this.dbl();
for (var i = 1; i < max; i++)
res[i] = res[i - 1].add(dbl);
return {
wnd: wnd,
points: res
};
};
BasePoint.prototype._getBeta = function _getBeta() {
return null;
};
BasePoint.prototype.dblp = function dblp(k) {
var r = this;
for (var i = 0; i < k; i++)
r = r.dbl();
return r;
};
},{"../../elliptic":41,"bn.js":39}],43:[function(require,module,exports){
'use strict';
var curve = require('../curve');
var elliptic = require('../../elliptic');
var BN = require('bn.js');
var inherits = require('inherits');
var Base = curve.base;
var assert = elliptic.utils.assert;
function EdwardsCurve(conf) {
// NOTE: Important as we are creating point in Base.call()
this.twisted = (conf.a | 0) !== 1;
this.mOneA = this.twisted && (conf.a | 0) === -1;
this.extended = this.mOneA;
Base.call(this, 'edwards', conf);
this.a = new BN(conf.a, 16).umod(this.red.m);
this.a = this.a.toRed(this.red);
this.c = new BN(conf.c, 16).toRed(this.red);
this.c2 = this.c.redSqr();
this.d = new BN(conf.d, 16).toRed(this.red);
this.dd = this.d.redAdd(this.d);
assert(!this.twisted || this.c.fromRed().cmpn(1) === 0);
this.oneC = (conf.c | 0) === 1;
}
inherits(EdwardsCurve, Base);
module.exports = EdwardsCurve;
EdwardsCurve.prototype._mulA = function _mulA(num) {
if (this.mOneA)
return num.redNeg();
else
return this.a.redMul(num);
};
EdwardsCurve.prototype._mulC = function _mulC(num) {
if (this.oneC)
return num;
else
return this.c.redMul(num);
};
// Just for compatibility with Short curve
EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {
return this.point(x, y, z, t);
};
EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
x = new BN(x, 16);
if (!x.red)
x = x.toRed(this.red);
var x2 = x.redSqr();
var rhs = this.c2.redSub(this.a.redMul(x2));
var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));
var y2 = rhs.redMul(lhs.redInvm());
var y = y2.redSqrt();
if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
throw new Error('invalid point');
var isOdd = y.fromRed().isOdd();
if (odd && !isOdd || !odd && isOdd)
y = y.redNeg();
return this.point(x, y);
};
EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {
y = new BN(y, 16);
if (!y.red)
y = y.toRed(this.red);
// x^2 = (y^2 - 1) / (d y^2 + 1)
var y2 = y.redSqr();
var lhs = y2.redSub(this.one);
var rhs = y2.redMul(this.d).redAdd(this.one);
var x2 = lhs.redMul(rhs.redInvm());
if (x2.cmp(this.zero) === 0) {
if (odd)
throw new Error('invalid point');
else
return this.point(this.zero, y);
}
var x = x2.redSqrt();
if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)
throw new Error('invalid point');
if (x.isOdd() !== odd)
x = x.redNeg();
return this.point(x, y);
};
EdwardsCurve.prototype.validate = function validate(point) {
if (point.isInfinity())
return true;
// Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)
point.normalize();
var x2 = point.x.redSqr();
var y2 = point.y.redSqr();
var lhs = x2.redMul(this.a).redAdd(y2);
var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2)));
return lhs.cmp(rhs) === 0;
};
function Point(curve, x, y, z, t) {
Base.BasePoint.call(this, curve, 'projective');
if (x === null && y === null && z === null) {
this.x = this.curve.zero;
this.y = this.curve.one;
this.z = this.curve.one;
this.t = this.curve.zero;
this.zOne = true;
} else {
this.x = new BN(x, 16);
this.y = new BN(y, 16);
this.z = z ? new BN(z, 16) : this.curve.one;
this.t = t && new BN(t, 16);
if (!this.x.red)
this.x = this.x.toRed(this.curve.red);
if (!this.y.red)
this.y = this.y.toRed(this.curve.red);
if (!this.z.red)
this.z = this.z.toRed(this.curve.red);
if (this.t && !this.t.red)
this.t = this.t.toRed(this.curve.red);
this.zOne = this.z === this.curve.one;
// Use extended coordinates
if (this.curve.extended && !this.t) {
this.t = this.x.redMul(this.y);
if (!this.zOne)
this.t = this.t.redMul(this.z.redInvm());
}
}
}
inherits(Point, Base.BasePoint);
EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
return Point.fromJSON(this, obj);
};
EdwardsCurve.prototype.point = function point(x, y, z, t) {
return new Point(this, x, y, z, t);
};
Point.fromJSON = function fromJSON(curve, obj) {
return new Point(curve, obj[0], obj[1], obj[2]);
};
Point.prototype.inspect = function inspect() {
if (this.isInfinity())
return '<EC Point Infinity>';
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
' y: ' + this.y.fromRed().toString(16, 2) +
' z: ' + this.z.fromRed().toString(16, 2) + '>';
};
Point.prototype.isInfinity = function isInfinity() {
// XXX This code assumes that zero is always zero in red
return this.x.cmpn(0) === 0 &&
this.y.cmp(this.z) === 0;
};
Point.prototype._extDbl = function _extDbl() {
// hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
// #doubling-dbl-2008-hwcd
// 4M + 4S
// A = X1^2
var a = this.x.redSqr();
// B = Y1^2
var b = this.y.redSqr();
// C = 2 * Z1^2
var c = this.z.redSqr();
c = c.redIAdd(c);
// D = a * A
var d = this.curve._mulA(a);
// E = (X1 + Y1)^2 - A - B
var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b);
// G = D + B
var g = d.redAdd(b);
// F = G - C
var f = g.redSub(c);
// H = D - B
var h = d.redSub(b);
// X3 = E * F
var nx = e.redMul(f);
// Y3 = G * H
var ny = g.redMul(h);
// T3 = E * H
var nt = e.redMul(h);
// Z3 = F * G
var nz = f.redMul(g);
return this.curve.point(nx, ny, nz, nt);
};
Point.prototype._projDbl = function _projDbl() {
// hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
// #doubling-dbl-2008-bbjlp
// #doubling-dbl-2007-bl
// and others
// Generally 3M + 4S or 2M + 4S
// B = (X1 + Y1)^2
var b = this.x.redAdd(this.y).redSqr();
// C = X1^2
var c = this.x.redSqr();
// D = Y1^2
var d = this.y.redSqr();
var nx;
var ny;
var nz;
if (this.curve.twisted) {
// E = a * C
var e = this.curve._mulA(c);
// F = E + D
var f = e.redAdd(d);
if (this.zOne) {
// X3 = (B - C - D) * (F - 2)
nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two));
// Y3 = F * (E - D)
ny = f.redMul(e.redSub(d));
// Z3 = F^2 - 2 * F
nz = f.redSqr().redSub(f).redSub(f);
} else {
// H = Z1^2
var h = this.z.redSqr();
// J = F - 2 * H
var j = f.redSub(h).redISub(h);
// X3 = (B-C-D)*J
nx = b.redSub(c).redISub(d).redMul(j);
// Y3 = F * (E - D)
ny = f.redMul(e.redSub(d));
// Z3 = F * J
nz = f.redMul(j);
}
} else {
// E = C + D
var e = c.redAdd(d);
// H = (c * Z1)^2
var h = this.curve._mulC(this.c.redMul(this.z)).redSqr();
// J = E - 2 * H
var j = e.redSub(h).redSub(h);
// X3 = c * (B - E) * J
nx = this.curve._mulC(b.redISub(e)).redMul(j);
// Y3 = c * E * (C - D)
ny = this.curve._mulC(e).redMul(c.redISub(d));
// Z3 = E * J
nz = e.redMul(j);
}
return this.curve.point(nx, ny, nz);
};
Point.prototype.dbl = function dbl() {
if (this.isInfinity())
return this;
// Double in extended coordinates
if (this.curve.extended)
return this._extDbl();
else
return this._projDbl();
};
Point.prototype._extAdd = function _extAdd(p) {
// hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
// #addition-add-2008-hwcd-3
// 8M
// A = (Y1 - X1) * (Y2 - X2)
var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x));
// B = (Y1 + X1) * (Y2 + X2)
var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x));
// C = T1 * k * T2
var c = this.t.redMul(this.curve.dd).redMul(p.t);
// D = Z1 * 2 * Z2
var d = this.z.redMul(p.z.redAdd(p.z));
// E = B - A
var e = b.redSub(a);
// F = D - C
var f = d.redSub(c);
// G = D + C
var g = d.redAdd(c);
// H = B + A
var h = b.redAdd(a);
// X3 = E * F
var nx = e.redMul(f);
// Y3 = G * H
var ny = g.redMul(h);
// T3 = E * H
var nt = e.redMul(h);
// Z3 = F * G
var nz = f.redMul(g);
return this.curve.point(nx, ny, nz, nt);
};
Point.prototype._projAdd = function _projAdd(p) {
// hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
// #addition-add-2008-bbjlp
// #addition-add-2007-bl
// 10M + 1S
// A = Z1 * Z2
var a = this.z.redMul(p.z);
// B = A^2
var b = a.redSqr();
// C = X1 * X2
var c = this.x.redMul(p.x);
// D = Y1 * Y2
var d = this.y.redMul(p.y);
// E = d * C * D
var e = this.curve.d.redMul(c).redMul(d);
// F = B - E
var f = b.redSub(e);
// G = B + E
var g = b.redAdd(e);
// X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d);
var nx = a.redMul(f).redMul(tmp);
var ny;
var nz;
if (this.curve.twisted) {
// Y3 = A * G * (D - a * C)
ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c)));
// Z3 = F * G
nz = f.redMul(g);
} else {
// Y3 = A * G * (D - C)
ny = a.redMul(g).redMul(d.redSub(c));
// Z3 = c * F * G
nz = this.curve._mulC(f).redMul(g);
}
return this.curve.point(nx, ny, nz);
};
Point.prototype.add = function add(p) {
if (this.isInfinity())
return p;
if (p.isInfinity())
return this;
if (this.curve.extended)
return this._extAdd(p);
else
return this._projAdd(p);
};
Point.prototype.mul = function mul(k) {
if (this._hasDoubles(k))
return this.curve._fixedNafMul(this, k);
else
return this.curve._wnafMul(this, k);
};
Point.prototype.mulAdd = function mulAdd(k1, p, k2) {
return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2);
};
Point.prototype.normalize = function normalize() {
if (this.zOne)
return this;
// Normalize coordinates
var zi = this.z.redInvm();
this.x = this.x.redMul(zi);
this.y = this.y.redMul(zi);
if (this.t)
this.t = this.t.redMul(zi);
this.z = this.curve.one;
this.zOne = true;
return this;
};
Point.prototype.neg = function neg() {
return this.curve.point(this.x.redNeg(),
this.y,
this.z,
this.t && this.t.redNeg());
};
Point.prototype.getX = function getX() {
this.normalize();
return this.x.fromRed();
};
Point.prototype.getY = function getY() {
this.normalize();
return this.y.fromRed();
};
Point.prototype.eq = function eq(other) {
return this === other ||
this.getX().cmp(other.getX()) === 0 &&
this.getY().cmp(other.getY()) === 0;
};
// Compatibility with BaseCurve
Point.prototype.toP = Point.prototype.normalize;
Point.prototype.mixedAdd = Point.prototype.add;
},{"../../elliptic":41,"../curve":44,"bn.js":39,"inherits":199}],44:[function(require,module,exports){
'use strict';
var curve = exports;
curve.base = require('./base');
curve.short = require('./short');
curve.mont = require('./mont');
curve.edwards = require('./edwards');
},{"./base":42,"./edwards":43,"./mont":45,"./short":46}],45:[function(require,module,exports){
'use strict';
var curve = require('../curve');
var BN = require('bn.js');
var inherits = require('inherits');
var Base = curve.base;
var elliptic = require('../../elliptic');
var utils = elliptic.utils;
function MontCurve(conf) {
Base.call(this, 'mont', conf);
this.a = new BN(conf.a, 16).toRed(this.red);
this.b = new BN(conf.b, 16).toRed(this.red);
this.i4 = new BN(4).toRed(this.red).redInvm();
this.two = new BN(2).toRed(this.red);
this.a24 = this.i4.redMul(this.a.redAdd(this.two));
}
inherits(MontCurve, Base);
module.exports = MontCurve;
MontCurve.prototype.validate = function validate(point) {
var x = point.normalize().x;
var x2 = x.redSqr();
var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);
var y = rhs.redSqrt();
return y.redSqr().cmp(rhs) === 0;
};
function Point(curve, x, z) {
Base.BasePoint.call(this, curve, 'projective');
if (x === null && z === null) {
this.x = this.curve.one;
this.z = this.curve.zero;
} else {
this.x = new BN(x, 16);
this.z = new BN(z, 16);
if (!this.x.red)
this.x = this.x.toRed(this.curve.red);
if (!this.z.red)
this.z = this.z.toRed(this.curve.red);
}
}
inherits(Point, Base.BasePoint);
MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
return this.point(utils.toArray(bytes, enc), 1);
};
MontCurve.prototype.point = function point(x, z) {
return new Point(this, x, z);
};
MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
return Point.fromJSON(this, obj);
};
Point.prototype.precompute = function precompute() {
// No-op
};
Point.prototype._encode = function _encode() {
return this.getX().toArray('be', this.curve.p.byteLength());
};
Point.fromJSON = function fromJSON(curve, obj) {
return new Point(curve, obj[0], obj[1] || curve.one);
};
Point.prototype.inspect = function inspect() {
if (this.isInfinity())
return '<EC Point Infinity>';
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
' z: ' + this.z.fromRed().toString(16, 2) + '>';
};
Point.prototype.isInfinity = function isInfinity() {
// XXX This code assumes that zero is always zero in red
return this.z.cmpn(0) === 0;
};
Point.prototype.dbl = function dbl() {
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
// 2M + 2S + 4A
// A = X1 + Z1
var a = this.x.redAdd(this.z);
// AA = A^2
var aa = a.redSqr();
// B = X1 - Z1
var b = this.x.redSub(this.z);
// BB = B^2
var bb = b.redSqr();
// C = AA - BB
var c = aa.redSub(bb);
// X3 = AA * BB
var nx = aa.redMul(bb);
// Z3 = C * (BB + A24 * C)
var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));
return this.curve.point(nx, nz);
};
Point.prototype.add = function add() {
throw new Error('Not supported on Montgomery curve');
};
Point.prototype.diffAdd = function diffAdd(p, diff) {
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
// 4M + 2S + 6A
// A = X2 + Z2
var a = this.x.redAdd(this.z);
// B = X2 - Z2
var b = this.x.redSub(this.z);
// C = X3 + Z3
var c = p.x.redAdd(p.z);
// D = X3 - Z3
var d = p.x.redSub(p.z);
// DA = D * A
var da = d.redMul(a);
// CB = C * B
var cb = c.redMul(b);
// X5 = Z1 * (DA + CB)^2
var nx = diff.z.redMul(da.redAdd(cb).redSqr());
// Z5 = X1 * (DA - CB)^2
var nz = diff.x.redMul(da.redISub(cb).redSqr());
return this.curve.point(nx, nz);
};
Point.prototype.mul = function mul(k) {
var t = k.clone();
var a = this; // (N / 2) * Q + Q
var b = this.curve.point(null, null); // (N / 2) * Q
var c = this; // Q
for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))
bits.push(t.andln(1));
for (var i = bits.length - 1; i >= 0; i--) {
if (bits[i] === 0) {
// N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
a = a.diffAdd(b, c);
// N * Q = 2 * ((N / 2) * Q + Q))
b = b.dbl();
} else {
// N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
b = a.diffAdd(b, c);
// N * Q + Q = 2 * ((N / 2) * Q + Q)
a = a.dbl();
}
}
return b;
};
Point.prototype.mulAdd = function mulAdd() {
throw new Error('Not supported on Montgomery curve');
};
Point.prototype.eq = function eq(other) {
return this.getX().cmp(other.getX()) === 0;
};
Point.prototype.normalize = function normalize() {
this.x = this.x.redMul(this.z.redInvm());
this.z = this.curve.one;
return this;
};
Point.prototype.getX = function getX() {
// Normalize coordinates
this.normalize();
return this.x.fromRed();
};
},{"../../elliptic":41,"../curve":44,"bn.js":39,"inherits":199}],46:[function(require,module,exports){
'use strict';
var curve = require('../curve');
var elliptic = require('../../elliptic');
var BN = require('bn.js');
var inherits = require('inherits');
var Base = curve.base;
var assert = elliptic.utils.assert;
function ShortCurve(conf) {
Base.call(this, 'short', conf);
this.a = new BN(conf.a, 16).toRed(this.red);
this.b = new BN(conf.b, 16).toRed(this.red);
this.tinv = this.two.redInvm();
this.zeroA = this.a.fromRed().cmpn(0) === 0;
this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;
// If the curve is endomorphic, precalculate beta and lambda
this.endo = this._getEndomorphism(conf);
this._endoWnafT1 = new Array(4);
this._endoWnafT2 = new Array(4);
}
inherits(ShortCurve, Base);
module.exports = ShortCurve;
ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
// No efficient endomorphism
if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
return;
// Compute beta and lambda, that lambda * P = (beta * Px; Py)
var beta;
var lambda;
if (conf.beta) {
beta = new BN(conf.beta, 16).toRed(this.red);
} else {
var betas = this._getEndoRoots(this.p);
// Choose the smallest beta
beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];
beta = beta.toRed(this.red);
}
if (conf.lambda) {
lambda = new BN(conf.lambda, 16);
} else {
// Choose the lambda that is matching selected beta
var lambdas = this._getEndoRoots(this.n);
if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {
lambda = lambdas[0];
} else {
lambda = lambdas[1];
assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);
}
}
// Get basis vectors, used for balanced length-two representation
var basis;
if (conf.basis) {
basis = conf.basis.map(function(vec) {
return {
a: new BN(vec.a, 16),
b: new BN(vec.b, 16)
};
});
} else {
basis = this._getEndoBasis(lambda);
}
return {
beta: beta,
lambda: lambda,
basis: basis
};
};
ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {
// Find roots of for x^2 + x + 1 in F
// Root = (-1 +- Sqrt(-3)) / 2
//
var red = num === this.p ? this.red : BN.mont(num);
var tinv = new BN(2).toRed(red).redInvm();
var ntinv = tinv.redNeg();
var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv);
var l1 = ntinv.redAdd(s).fromRed();
var l2 = ntinv.redSub(s).fromRed();
return [ l1, l2 ];
};
ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {
// aprxSqrt >= sqrt(this.n)
var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));
// 3.74
// Run EGCD, until r(L + 1) < aprxSqrt
var u = lambda;
var v = this.n.clone();
var x1 = new BN(1);
var y1 = new BN(0);
var x2 = new BN(0);
var y2 = new BN(1);
// NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
var a0;
var b0;
// First vector
var a1;
var b1;
// Second vector
var a2;
var b2;
var prevR;
var i = 0;
var r;
var x;
while (u.cmpn(0) !== 0) {
var q = v.div(u);
r = v.sub(q.mul(u));
x = x2.sub(q.mul(x1));
var y = y2.sub(q.mul(y1));
if (!a1 && r.cmp(aprxSqrt) < 0) {
a0 = prevR.neg();
b0 = x1;
a1 = r.neg();
b1 = x;
} else if (a1 && ++i === 2) {
break;
}
prevR = r;
v = u;
u = r;
x2 = x1;
x1 = x;
y2 = y1;
y1 = y;
}
a2 = r.neg();
b2 = x;
var len1 = a1.sqr().add(b1.sqr());
var len2 = a2.sqr().add(b2.sqr());
if (len2.cmp(len1) >= 0) {
a2 = a0;
b2 = b0;
}
// Normalize signs
if (a1.negative) {
a1 = a1.neg();
b1 = b1.neg();
}
if (a2.negative) {
a2 = a2.neg();
b2 = b2.neg();
}
return [
{ a: a1, b: b1 },
{ a: a2, b: b2 }
];
};
ShortCurve.prototype._endoSplit = function _endoSplit(k) {
var basis = this.endo.basis;
var v1 = basis[0];
var v2 = basis[1];
var c1 = v2.b.mul(k).divRound(this.n);
var c2 = v1.b.neg().mul(k).divRound(this.n);
var p1 = c1.mul(v1.a);
var p2 = c2.mul(v2.a);
var q1 = c1.mul(v1.b);
var q2 = c2.mul(v2.b);
// Calculate answer
var k1 = k.sub(p1).sub(p2);
var k2 = q1.add(q2).neg();
return { k1: k1, k2: k2 };
};
ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
x = new BN(x, 16);
if (!x.red)
x = x.toRed(this.red);
var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
var y = y2.redSqrt();
if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
throw new Error('invalid point');
// XXX Is there any way to tell if the number is odd without converting it
// to non-red form?
var isOdd = y.fromRed().isOdd();
if (odd && !isOdd || !odd && isOdd)
y = y.redNeg();
return this.point(x, y);
};
ShortCurve.prototype.validate = function validate(point) {
if (point.inf)
return true;
var x = point.x;
var y = point.y;
var ax = this.a.redMul(x);
var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);
return y.redSqr().redISub(rhs).cmpn(0) === 0;
};
ShortCurve.prototype._endoWnafMulAdd =
function _endoWnafMulAdd(points, coeffs) {
var npoints = this._endoWnafT1;
var ncoeffs = this._endoWnafT2;
for (var i = 0; i < points.length; i++) {
var split = this._endoSplit(coeffs[i]);
var p = points[i];
var beta = p._getBeta();
if (split.k1.negative) {
split.k1.ineg();
p = p.neg(true);
}
if (split.k2.negative) {
split.k2.ineg();
beta = beta.neg(true);
}
npoints[i * 2] = p;
npoints[i * 2 + 1] = beta;
ncoeffs[i * 2] = split.k1;
ncoeffs[i * 2 + 1] = split.k2;
}
var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2);
// Clean-up references to points and coefficients
for (var j = 0; j < i * 2; j++) {
npoints[j] = null;
ncoeffs[j] = null;
}
return res;
};
function Point(curve, x, y, isRed) {
Base.BasePoint.call(this, curve, 'affine');
if (x === null && y === null) {
this.x = null;
this.y = null;
this.inf = true;
} else {
this.x = new BN(x, 16);
this.y = new BN(y, 16);
// Force redgomery representation when loading from JSON
if (isRed) {
this.x.forceRed(this.curve.red);
this.y.forceRed(this.curve.red);
}
if (!this.x.red)
this.x = this.x.toRed(this.curve.red);
if (!this.y.red)
this.y = this.y.toRed(this.curve.red);
this.inf = false;
}
}
inherits(Point, Base.BasePoint);
ShortCurve.prototype.point = function point(x, y, isRed) {
return new Point(this, x, y, isRed);
};
ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {
return Point.fromJSON(this, obj, red);
};
Point.prototype._getBeta = function _getBeta() {
if (!this.curve.endo)
return;
var pre = this.precomputed;
if (pre && pre.beta)
return pre.beta;
var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);
if (pre) {
var curve = this.curve;
var endoMul = function(p) {
return curve.point(p.x.redMul(curve.endo.beta), p.y);
};
pre.beta = beta;
beta.precomputed = {
beta: null,
naf: pre.naf && {
wnd: pre.naf.wnd,
points: pre.naf.points.map(endoMul)
},
doubles: pre.doubles && {
step: pre.doubles.step,
points: pre.doubles.points.map(endoMul)
}
};
}
return beta;
};
Point.prototype.toJSON = function toJSON() {
if (!this.precomputed)
return [ this.x, this.y ];
return [ this.x, this.y, this.precomputed && {
doubles: this.precomputed.doubles && {
step: this.precomputed.doubles.step,
points: this.precomputed.doubles.points.slice(1)
},
naf: this.precomputed.naf && {
wnd: this.precomputed.naf.wnd,
points: this.precomputed.naf.points.slice(1)
}
} ];
};
Point.fromJSON = function fromJSON(curve, obj, red) {
if (typeof obj === 'string')
obj = JSON.parse(obj);
var res = curve.point(obj[0], obj[1], red);
if (!obj[2])
return res;
function obj2point(obj) {
return curve.point(obj[0], obj[1], red);
}
var pre = obj[2];
res.precomputed = {
beta: null,
doubles: pre.doubles && {
step: pre.doubles.step,
points: [ res ].concat(pre.doubles.points.map(obj2point))
},
naf: pre.naf && {
wnd: pre.naf.wnd,
points: [ res ].concat(pre.naf.points.map(obj2point))
}
};
return res;
};
Point.prototype.inspect = function inspect() {
if (this.isInfinity())
return '<EC Point Infinity>';
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
' y: ' + this.y.fromRed().toString(16, 2) + '>';
};
Point.prototype.isInfinity = function isInfinity() {
return this.inf;
};
Point.prototype.add = function add(p) {
// O + P = P
if (this.inf)
return p;
// P + O = P
if (p.inf)
return this;
// P + P = 2P
if (this.eq(p))
return this.dbl();
// P + (-P) = O
if (this.neg().eq(p))
return this.curve.point(null, null);
// P + Q = O
if (this.x.cmp(p.x) === 0)
return this.curve.point(null, null);
var c = this.y.redSub(p.y);
if (c.cmpn(0) !== 0)
c = c.redMul(this.x.redSub(p.x).redInvm());
var nx = c.redSqr().redISub(this.x).redISub(p.x);
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
return this.curve.point(nx, ny);
};
Point.prototype.dbl = function dbl() {
if (this.inf)
return this;
// 2P = O
var ys1 = this.y.redAdd(this.y);
if (ys1.cmpn(0) === 0)
return this.curve.point(null, null);
var a = this.curve.a;
var x2 = this.x.redSqr();
var dyinv = ys1.redInvm();
var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);
var nx = c.redSqr().redISub(this.x.redAdd(this.x));
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
return this.curve.point(nx, ny);
};
Point.prototype.getX = function getX() {
return this.x.fromRed();
};
Point.prototype.getY = function getY() {
return this.y.fromRed();
};
Point.prototype.mul = function mul(k) {
k = new BN(k, 16);
if (this._hasDoubles(k))
return this.curve._fixedNafMul(this, k);
else if (this.curve.endo)
return this.curve._endoWnafMulAdd([ this ], [ k ]);
else
return this.curve._wnafMul(this, k);
};
Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {
var points = [ this, p2 ];
var coeffs = [ k1, k2 ];
if (this.curve.endo)
return this.curve._endoWnafMulAdd(points, coeffs);
else
return this.curve._wnafMulAdd(1, points, coeffs, 2);
};
Point.prototype.eq = function eq(p) {
return this === p ||
this.inf === p.inf &&
(this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);
};
Point.prototype.neg = function neg(_precompute) {
if (this.inf)
return this;
var res = this.curve.point(this.x, this.y.redNeg());
if (_precompute && this.precomputed) {
var pre = this.precomputed;
var negate = function(p) {
return p.neg();
};
res.precomputed = {
naf: pre.naf && {
wnd: pre.naf.wnd,
points: pre.naf.points.map(negate)
},
doubles: pre.doubles && {
step: pre.doubles.step,
points: pre.doubles.points.map(negate)
}
};
}
return res;
};
Point.prototype.toJ = function toJ() {
if (this.inf)
return this.curve.jpoint(null, null, null);
var res = this.curve.jpoint(this.x, this.y, this.curve.one);
return res;
};
function JPoint(curve, x, y, z) {
Base.BasePoint.call(this, curve, 'jacobian');
if (x === null && y === null && z === null) {
this.x = this.curve.one;
this.y = this.curve.one;
this.z = new BN(0);
} else {
this.x = new BN(x, 16);
this.y = new BN(y, 16);
this.z = new BN(z, 16);
}
if (!this.x.red)
this.x = this.x.toRed(this.curve.red);
if (!this.y.red)
this.y = this.y.toRed(this.curve.red);
if (!this.z.red)
this.z = this.z.toRed(this.curve.red);
this.zOne = this.z === this.curve.one;
}
inherits(JPoint, Base.BasePoint);
ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
return new JPoint(this, x, y, z);
};
JPoint.prototype.toP = function toP() {
if (this.isInfinity())
return this.curve.point(null, null);
var zinv = this.z.redInvm();
var zinv2 = zinv.redSqr();
var ax = this.x.redMul(zinv2);
var ay = this.y.redMul(zinv2).redMul(zinv);
return this.curve.point(ax, ay);
};
JPoint.prototype.neg = function neg() {
return this.curve.jpoint(this.x, this.y.redNeg(), this.z);
};
JPoint.prototype.add = function add(p) {
// O + P = P
if (this.isInfinity())
return p;
// P + O = P
if (p.isInfinity())
return this;
// 12M + 4S + 7A
var pz2 = p.z.redSqr();
var z2 = this.z.redSqr();
var u1 = this.x.redMul(pz2);
var u2 = p.x.redMul(z2);
var s1 = this.y.redMul(pz2.redMul(p.z));
var s2 = p.y.redMul(z2.redMul(this.z));
var h = u1.redSub(u2);
var r = s1.redSub(s2);
if (h.cmpn(0) === 0) {
if (r.cmpn(0) !== 0)
return this.curve.jpoint(null, null, null);
else
return this.dbl();
}
var h2 = h.redSqr();
var h3 = h2.redMul(h);
var v = u1.redMul(h2);
var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
var nz = this.z.redMul(p.z).redMul(h);
return this.curve.jpoint(nx, ny, nz);
};
JPoint.prototype.mixedAdd = function mixedAdd(p) {
// O + P = P
if (this.isInfinity())
return p.toJ();
// P + O = P
if (p.isInfinity())
return this;
// 8M + 3S + 7A
var z2 = this.z.redSqr();
var u1 = this.x;
var u2 = p.x.redMul(z2);
var s1 = this.y;
var s2 = p.y.redMul(z2).redMul(this.z);
var h = u1.redSub(u2);
var r = s1.redSub(s2);
if (h.cmpn(0) === 0) {
if (r.cmpn(0) !== 0)
return this.curve.jpoint(null, null, null);
else
return this.dbl();
}
var h2 = h.redSqr();
var h3 = h2.redMul(h);
var v = u1.redMul(h2);
var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
var nz = this.z.redMul(h);
return this.curve.jpoint(nx, ny, nz);
};
JPoint.prototype.dblp = function dblp(pow) {
if (pow === 0)
return this;
if (this.isInfinity())
return this;
if (!pow)
return this.dbl();
if (this.curve.zeroA || this.curve.threeA) {
var r = this;
for (var i = 0; i < pow; i++)
r = r.dbl();
return r;
}
// 1M + 2S + 1A + N * (4S + 5M + 8A)
// N = 1 => 6M + 6S + 9A
var a = this.curve.a;
var tinv = this.curve.tinv;
var jx = this.x;
var jy = this.y;
var jz = this.z;
var jz4 = jz.redSqr().redSqr();
// Reuse results
var jyd = jy.redAdd(jy);
for (var i = 0; i < pow; i++) {
var jx2 = jx.redSqr();
var jyd2 = jyd.redSqr();
var jyd4 = jyd2.redSqr();
var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
var t1 = jx.redMul(jyd2);
var nx = c.redSqr().redISub(t1.redAdd(t1));
var t2 = t1.redISub(nx);
var dny = c.redMul(t2);
dny = dny.redIAdd(dny).redISub(jyd4);
var nz = jyd.redMul(jz);
if (i + 1 < pow)
jz4 = jz4.redMul(jyd4);
jx = nx;
jz = nz;
jyd = dny;
}
return this.curve.jpoint(jx, jyd.redMul(tinv), jz);
};
JPoint.prototype.dbl = function dbl() {
if (this.isInfinity())
return this;
if (this.curve.zeroA)
return this._zeroDbl();
else if (this.curve.threeA)
return this._threeDbl();
else
return this._dbl();
};
JPoint.prototype._zeroDbl = function _zeroDbl() {
var nx;
var ny;
var nz;
// Z = 1
if (this.zOne) {
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
// #doubling-mdbl-2007-bl
// 1M + 5S + 14A
// XX = X1^2
var xx = this.x.redSqr();
// YY = Y1^2
var yy = this.y.redSqr();
// YYYY = YY^2
var yyyy = yy.redSqr();
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
s = s.redIAdd(s);
// M = 3 * XX + a; a = 0
var m = xx.redAdd(xx).redIAdd(xx);
// T = M ^ 2 - 2*S
var t = m.redSqr().redISub(s).redISub(s);
// 8 * YYYY
var yyyy8 = yyyy.redIAdd(yyyy);
yyyy8 = yyyy8.redIAdd(yyyy8);
yyyy8 = yyyy8.redIAdd(yyyy8);
// X3 = T
nx = t;
// Y3 = M * (S - T) - 8 * YYYY
ny = m.redMul(s.redISub(t)).redISub(yyyy8);
// Z3 = 2*Y1
nz = this.y.redAdd(this.y);
} else {
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
// #doubling-dbl-2009-l
// 2M + 5S + 13A
// A = X1^2
var a = this.x.redSqr();
// B = Y1^2
var b = this.y.redSqr();
// C = B^2
var c = b.redSqr();
// D = 2 * ((X1 + B)^2 - A - C)
var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);
d = d.redIAdd(d);
// E = 3 * A
var e = a.redAdd(a).redIAdd(a);
// F = E^2
var f = e.redSqr();
// 8 * C
var c8 = c.redIAdd(c);
c8 = c8.redIAdd(c8);
c8 = c8.redIAdd(c8);
// X3 = F - 2 * D
nx = f.redISub(d).redISub(d);
// Y3 = E * (D - X3) - 8 * C
ny = e.redMul(d.redISub(nx)).redISub(c8);
// Z3 = 2 * Y1 * Z1
nz = this.y.redMul(this.z);
nz = nz.redIAdd(nz);
}
return this.curve.jpoint(nx, ny, nz);
};
JPoint.prototype._threeDbl = function _threeDbl() {
var nx;
var ny;
var nz;
// Z = 1
if (this.zOne) {
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
// #doubling-mdbl-2007-bl
// 1M + 5S + 15A
// XX = X1^2
var xx = this.x.redSqr();
// YY = Y1^2
var yy = this.y.redSqr();
// YYYY = YY^2
var yyyy = yy.redSqr();
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
s = s.redIAdd(s);
// M = 3 * XX + a
var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);
// T = M^2 - 2 * S
var t = m.redSqr().redISub(s).redISub(s);
// X3 = T
nx = t;
// Y3 = M * (S - T) - 8 * YYYY
var yyyy8 = yyyy.redIAdd(yyyy);
yyyy8 = yyyy8.redIAdd(yyyy8);
yyyy8 = yyyy8.redIAdd(yyyy8);
ny = m.redMul(s.redISub(t)).redISub(yyyy8);
// Z3 = 2 * Y1
nz = this.y.redAdd(this.y);
} else {
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
// 3M + 5S
// delta = Z1^2
var delta = this.z.redSqr();
// gamma = Y1^2
var gamma = this.y.redSqr();
// beta = X1 * gamma
var beta = this.x.redMul(gamma);
// alpha = 3 * (X1 - delta) * (X1 + delta)
var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));
alpha = alpha.redAdd(alpha).redIAdd(alpha);
// X3 = alpha^2 - 8 * beta
var beta4 = beta.redIAdd(beta);
beta4 = beta4.redIAdd(beta4);
var beta8 = beta4.redAdd(beta4);
nx = alpha.redSqr().redISub(beta8);
// Z3 = (Y1 + Z1)^2 - gamma - delta
nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);
// Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
var ggamma8 = gamma.redSqr();
ggamma8 = ggamma8.redIAdd(ggamma8);
ggamma8 = ggamma8.redIAdd(ggamma8);
ggamma8 = ggamma8.redIAdd(ggamma8);
ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);
}
return this.curve.jpoint(nx, ny, nz);
};
JPoint.prototype._dbl = function _dbl() {
var a = this.curve.a;
// 4M + 6S + 10A
var jx = this.x;
var jy = this.y;
var jz = this.z;
var jz4 = jz.redSqr().redSqr();
var jx2 = jx.redSqr();
var jy2 = jy.redSqr();
var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
var jxd4 = jx.redAdd(jx);
jxd4 = jxd4.redIAdd(jxd4);
var t1 = jxd4.redMul(jy2);
var nx = c.redSqr().redISub(t1.redAdd(t1));
var t2 = t1.redISub(nx);
var jyd8 = jy2.redSqr();
jyd8 = jyd8.redIAdd(jyd8);
jyd8 = jyd8.redIAdd(jyd8);
jyd8 = jyd8.redIAdd(jyd8);
var ny = c.redMul(t2).redISub(jyd8);
var nz = jy.redAdd(jy).redMul(jz);
return this.curve.jpoint(nx, ny, nz);
};
JPoint.prototype.trpl = function trpl() {
if (!this.curve.zeroA)
return this.dbl().add(this);
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
// 5M + 10S + ...
// XX = X1^2
var xx = this.x.redSqr();
// YY = Y1^2
var yy = this.y.redSqr();
// ZZ = Z1^2
var zz = this.z.redSqr();
// YYYY = YY^2
var yyyy = yy.redSqr();
// M = 3 * XX + a * ZZ2; a = 0
var m = xx.redAdd(xx).redIAdd(xx);
// MM = M^2
var mm = m.redSqr();
// E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
e = e.redIAdd(e);
e = e.redAdd(e).redIAdd(e);
e = e.redISub(mm);
// EE = E^2
var ee = e.redSqr();
// T = 16*YYYY
var t = yyyy.redIAdd(yyyy);
t = t.redIAdd(t);
t = t.redIAdd(t);
t = t.redIAdd(t);
// U = (M + E)^2 - MM - EE - T
var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);
// X3 = 4 * (X1 * EE - 4 * YY * U)
var yyu4 = yy.redMul(u);
yyu4 = yyu4.redIAdd(yyu4);
yyu4 = yyu4.redIAdd(yyu4);
var nx = this.x.redMul(ee).redISub(yyu4);
nx = nx.redIAdd(nx);
nx = nx.redIAdd(nx);
// Y3 = 8 * Y1 * (U * (T - U) - E * EE)
var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));
ny = ny.redIAdd(ny);
ny = ny.redIAdd(ny);
ny = ny.redIAdd(ny);
// Z3 = (Z1 + E)^2 - ZZ - EE
var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);
return this.curve.jpoint(nx, ny, nz);
};
JPoint.prototype.mul = function mul(k, kbase) {
k = new BN(k, kbase);
return this.curve._wnafMul(this, k);
};
JPoint.prototype.eq = function eq(p) {
if (p.type === 'affine')
return this.eq(p.toJ());
if (this === p)
return true;
// x1 * z2^2 == x2 * z1^2
var z2 = this.z.redSqr();
var pz2 = p.z.redSqr();
if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)
return false;
// y1 * z2^3 == y2 * z1^3
var z3 = z2.redMul(this.z);
var pz3 = pz2.redMul(p.z);
return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;
};
JPoint.prototype.inspect = function inspect() {
if (this.isInfinity())
return '<EC JPoint Infinity>';
return '<EC JPoint x: ' + this.x.toString(16, 2) +
' y: ' + this.y.toString(16, 2) +
' z: ' + this.z.toString(16, 2) + '>';
};
JPoint.prototype.isInfinity = function isInfinity() {
// XXX This code assumes that zero is always zero in red
return this.z.cmpn(0) === 0;
};
},{"../../elliptic":41,"../curve":44,"bn.js":39,"inherits":199}],47:[function(require,module,exports){
'use strict';
var curves = exports;
var hash = require('hash.js');
var elliptic = require('../elliptic');
var assert = elliptic.utils.assert;
function PresetCurve(options) {
if (options.type === 'short')
this.curve = new elliptic.curve.short(options);
else if (options.type === 'edwards')
this.curve = new elliptic.curve.edwards(options);
else
this.curve = new elliptic.curve.mont(options);
this.g = this.curve.g;
this.n = this.curve.n;
this.hash = options.hash;
assert(this.g.validate(), 'Invalid curve');
assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O');
}
curves.PresetCurve = PresetCurve;
function defineCurve(name, options) {
Object.defineProperty(curves, name, {
configurable: true,
enumerable: true,
get: function() {
var curve = new PresetCurve(options);
Object.defineProperty(curves, name, {
configurable: true,
enumerable: true,
value: curve
});
return curve;
}
});
}
defineCurve('p192', {
type: 'short',
prime: 'p192',
p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff',
a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc',
b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1',
n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831',
hash: hash.sha256,
gRed: false,
g: [
'188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012',
'07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811'
]
});
defineCurve('p224', {
type: 'short',
prime: 'p224',
p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001',
a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe',
b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4',
n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d',
hash: hash.sha256,
gRed: false,
g: [
'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21',
'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34'
]
});
defineCurve('p256', {
type: 'short',
prime: null,
p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff',
a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc',
b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b',
n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551',
hash: hash.sha256,
gRed: false,
g: [
'6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296',
'4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5'
]
});
defineCurve('p384', {
type: 'short',
prime: null,
p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
'fffffffe ffffffff 00000000 00000000 ffffffff',
a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
'fffffffe ffffffff 00000000 00000000 fffffffc',
b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' +
'5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef',
n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' +
'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973',
hash: hash.sha384,
gRed: false,
g: [
'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' +
'5502f25d bf55296c 3a545e38 72760ab7',
'3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' +
'0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'
]
});
defineCurve('p521', {
type: 'short',
prime: null,
p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
'ffffffff ffffffff ffffffff ffffffff ffffffff',
a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
'ffffffff ffffffff ffffffff ffffffff fffffffc',
b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' +
'99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' +
'3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00',
n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' +
'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409',
hash: hash.sha512,
gRed: false,
g: [
'000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' +
'053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' +
'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66',
'00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' +
'579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' +
'3fad0761 353c7086 a272c240 88be9476 9fd16650'
]
});
defineCurve('curve25519', {
type: 'mont',
prime: 'p25519',
p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
a: '76d06',
b: '0',
n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
hash: hash.sha256,
gRed: false,
g: [
'9'
]
});
defineCurve('ed25519', {
type: 'edwards',
prime: 'p25519',
p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
a: '-1',
c: '1',
// -121665 * (121666^(-1)) (mod P)
d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3',
n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
hash: hash.sha256,
gRed: false,
g: [
'216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',
// 4/5
'6666666666666666666666666666666666666666666666666666666666666658'
]
});
var pre;
try {
pre = require('./precomputed/secp256k1');
} catch (e) {
pre = undefined;
}
defineCurve('secp256k1', {
type: 'short',
prime: 'k256',
p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f',
a: '0',
b: '7',
n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141',
h: '1',
hash: hash.sha256,
// Precomputed endomorphism
beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',
lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',
basis: [
{
a: '3086d221a7d46bcde86c90e49284eb15',
b: '-e4437ed6010e88286f547fa90abfe4c3'
},
{
a: '114ca50f7a8e2f3f657c1108d9d44cfd8',
b: '3086d221a7d46bcde86c90e49284eb15'
}
],
gRed: false,
g: [
'79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
'483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
pre
]
});
},{"../elliptic":41,"./precomputed/secp256k1":55,"hash.js":58}],48:[function(require,module,exports){
'use strict';
var BN = require('bn.js');
var elliptic = require('../../elliptic');
var utils = elliptic.utils;
var assert = utils.assert;
var KeyPair = require('./key');
var Signature = require('./signature');
function EC(options) {
if (!(this instanceof EC))
return new EC(options);
// Shortcut `elliptic.ec(curve-name)`
if (typeof options === 'string') {
assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options);
options = elliptic.curves[options];
}
// Shortcut for `elliptic.ec(elliptic.curves.curveName)`
if (options instanceof elliptic.curves.PresetCurve)
options = { curve: options };
this.curve = options.curve.curve;
this.n = this.curve.n;
this.nh = this.n.ushrn(1);
this.g = this.curve.g;
// Point on curve
this.g = options.curve.g;
this.g.precompute(options.curve.n.bitLength() + 1);
// Hash for function for DRBG
this.hash = options.hash || options.curve.hash;
}
module.exports = EC;
EC.prototype.keyPair = function keyPair(options) {
return new KeyPair(this, options);
};
EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
return KeyPair.fromPrivate(this, priv, enc);
};
EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
return KeyPair.fromPublic(this, pub, enc);
};
EC.prototype.genKeyPair = function genKeyPair(options) {
if (!options)
options = {};
// Instantiate Hmac_DRBG
var drbg = new elliptic.hmacDRBG({
hash: this.hash,
pers: options.pers,
entropy: options.entropy || elliptic.rand(this.hash.hmacStrength),
nonce: this.n.toArray()
});
var bytes = this.n.byteLength();
var ns2 = this.n.sub(new BN(2));
do {
var priv = new BN(drbg.generate(bytes));
if (priv.cmp(ns2) > 0)
continue;
priv.iaddn(1);
return this.keyFromPrivate(priv);
} while (true);
};
EC.prototype._truncateToN = function truncateToN(msg, truncOnly) {
var delta = msg.byteLength() * 8 - this.n.bitLength();
if (delta > 0)
msg = msg.ushrn(delta);
if (!truncOnly && msg.cmp(this.n) >= 0)
return msg.sub(this.n);
else
return msg;
};
EC.prototype.sign = function sign(msg, key, enc, options) {
if (typeof enc === 'object') {
options = enc;
enc = null;
}
if (!options)
options = {};
key = this.keyFromPrivate(key, enc);
msg = this._truncateToN(new BN(msg, 16));
// Zero-extend key to provide enough entropy
var bytes = this.n.byteLength();
var bkey = key.getPrivate().toArray('be', bytes);
// Zero-extend nonce to have the same byte size as N
var nonce = msg.toArray('be', bytes);
// Instantiate Hmac_DRBG
var drbg = new elliptic.hmacDRBG({
hash: this.hash,
entropy: bkey,
nonce: nonce,
pers: options.pers,
persEnc: options.persEnc
});
// Number of bytes to generate
var ns1 = this.n.sub(new BN(1));
for (var iter = 0; true; iter++) {
var k = options.k ?
options.k(iter) :
new BN(drbg.generate(this.n.byteLength()));
k = this._truncateToN(k, true);
if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0)
continue;
var kp = this.g.mul(k);
if (kp.isInfinity())
continue;
var kpX = kp.getX();
var r = kpX.umod(this.n);
if (r.cmpn(0) === 0)
continue;
var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg));
s = s.umod(this.n);
if (s.cmpn(0) === 0)
continue;
var recoveryParam = (kp.getY().isOdd() ? 1 : 0) |
(kpX.cmp(r) !== 0 ? 2 : 0);
// Use complement of `s`, if it is > `n / 2`
if (options.canonical && s.cmp(this.nh) > 0) {
s = this.n.sub(s);
recoveryParam ^= 1;
}
return new Signature({ r: r, s: s, recoveryParam: recoveryParam });
}
};
EC.prototype.verify = function verify(msg, signature, key, enc) {
msg = this._truncateToN(new BN(msg, 16));
key = this.keyFromPublic(key, enc);
signature = new Signature(signature, 'hex');
// Perform primitive values validation
var r = signature.r;
var s = signature.s;
if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0)
return false;
if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0)
return false;
// Validate signature
var sinv = s.invm(this.n);
var u1 = sinv.mul(msg).umod(this.n);
var u2 = sinv.mul(r).umod(this.n);
var p = this.g.mulAdd(u1, key.getPublic(), u2);
if (p.isInfinity())
return false;
return p.getX().umod(this.n).cmp(r) === 0;
};
EC.prototype.recoverPubKey = function(msg, signature, j, enc) {
assert((3 & j) === j, 'The recovery param is more than two bits');
signature = new Signature(signature, enc);
var n = this.n;
var e = new BN(msg);
var r = signature.r;
var s = signature.s;
// A set LSB signifies that the y-coordinate is odd
var isYOdd = j & 1;
var isSecondKey = j >> 1;
if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey)
throw new Error('Unable to find sencond key candinate');
// 1.1. Let x = r + jn.
if (isSecondKey)
r = this.curve.pointFromX(r.add(this.curve.n), isYOdd);
else
r = this.curve.pointFromX(r, isYOdd);
var eNeg = n.sub(e);
// 1.6.1 Compute Q = r^-1 (sR - eG)
// Q = r^-1 (sR + -eG)
var rInv = signature.r.invm(n);
return this.g.mulAdd(eNeg, r, s).mul(rInv);
};
EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {
signature = new Signature(signature, enc);
if (signature.recoveryParam !== null)
return signature.recoveryParam;
for (var i = 0; i < 4; i++) {
var Qprime;
try {
Qprime = this.recoverPubKey(e, signature, i);
} catch (e) {
continue;
}
if (Qprime.eq(Q))
return i;
}
throw new Error('Unable to find valid recovery factor');
};
},{"../../elliptic":41,"./key":49,"./signature":50,"bn.js":39}],49:[function(require,module,exports){
'use strict';
var BN = require('bn.js');
function KeyPair(ec, options) {
this.ec = ec;
this.priv = null;
this.pub = null;
// KeyPair(ec, { priv: ..., pub: ... })
if (options.priv)
this._importPrivate(options.priv, options.privEnc);
if (options.pub)
this._importPublic(options.pub, options.pubEnc);
}
module.exports = KeyPair;
KeyPair.fromPublic = function fromPublic(ec, pub, enc) {
if (pub instanceof KeyPair)
return pub;
return new KeyPair(ec, {
pub: pub,
pubEnc: enc
});
};
KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {
if (priv instanceof KeyPair)
return priv;
return new KeyPair(ec, {
priv: priv,
privEnc: enc
});
};
KeyPair.prototype.validate = function validate() {
var pub = this.getPublic();
if (pub.isInfinity())
return { result: false, reason: 'Invalid public key' };
if (!pub.validate())
return { result: false, reason: 'Public key is not a point' };
if (!pub.mul(this.ec.curve.n).isInfinity())
return { result: false, reason: 'Public key * N != O' };
return { result: true, reason: null };
};
KeyPair.prototype.getPublic = function getPublic(compact, enc) {
// compact is optional argument
if (typeof compact === 'string') {
enc = compact;
compact = null;
}
if (!this.pub)
this.pub = this.ec.g.mul(this.priv);
if (!enc)
return this.pub;
return this.pub.encode(enc, compact);
};
KeyPair.prototype.getPrivate = function getPrivate(enc) {
if (enc === 'hex')
return this.priv.toString(16, 2);
else
return this.priv;
};
KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {
this.priv = new BN(key, enc || 16);
// Ensure that the priv won't be bigger than n, otherwise we may fail
// in fixed multiplication method
this.priv = this.priv.umod(this.ec.curve.n);
};
KeyPair.prototype._importPublic = function _importPublic(key, enc) {
if (key.x || key.y) {
this.pub = this.ec.curve.point(key.x, key.y);
return;
}
this.pub = this.ec.curve.decodePoint(key, enc);
};
// ECDH
KeyPair.prototype.derive = function derive(pub) {
return pub.mul(this.priv).getX();
};
// ECDSA
KeyPair.prototype.sign = function sign(msg, enc, options) {
return this.ec.sign(msg, this, enc, options);
};
KeyPair.prototype.verify = function verify(msg, signature) {
return this.ec.verify(msg, signature, this);
};
KeyPair.prototype.inspect = function inspect() {
return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
' pub: ' + (this.pub && this.pub.inspect()) + ' >';
};
},{"bn.js":39}],50:[function(require,module,exports){
'use strict';
var BN = require('bn.js');
var elliptic = require('../../elliptic');
var utils = elliptic.utils;
var assert = utils.assert;
function Signature(options, enc) {
if (options instanceof Signature)
return options;
if (this._importDER(options, enc))
return;
assert(options.r && options.s, 'Signature without r or s');
this.r = new BN(options.r, 16);
this.s = new BN(options.s, 16);
if (options.recoveryParam === undefined)
this.recoveryParam = null;
else
this.recoveryParam = options.recoveryParam;
}
module.exports = Signature;
function Position() {
this.place = 0;
}
function getLength(buf, p) {
var initial = buf[p.place++];
if (!(initial & 0x80)) {
return initial;
}
var octetLen = initial & 0xf;
var val = 0;
for (var i = 0, off = p.place; i < octetLen; i++, off++) {
val <<= 8;
val |= buf[off];
}
p.place = off;
return val;
}
function rmPadding(buf) {
var i = 0;
var len = buf.length - 1;
while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) {
i++;
}
if (i === 0) {
return buf;
}
return buf.slice(i);
}
Signature.prototype._importDER = function _importDER(data, enc) {
data = utils.toArray(data, enc);
var p = new Position();
if (data[p.place++] !== 0x30) {
return false;
}
var len = getLength(data, p);
if ((len + p.place) !== data.length) {
return false;
}
if (data[p.place++] !== 0x02) {
return false;
}
var rlen = getLength(data, p);
var r = data.slice(p.place, rlen + p.place);
p.place += rlen;
if (data[p.place++] !== 0x02) {
return false;
}
var slen = getLength(data, p);
if (data.length !== slen + p.place) {
return false;
}
var s = data.slice(p.place, slen + p.place);
if (r[0] === 0 && (r[1] & 0x80)) {
r = r.slice(1);
}
if (s[0] === 0 && (s[1] & 0x80)) {
s = s.slice(1);
}
this.r = new BN(r);
this.s = new BN(s);
this.recoveryParam = null;
return true;
};
function constructLength(arr, len) {
if (len < 0x80) {
arr.push(len);
return;
}
var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);
arr.push(octets | 0x80);
while (--octets) {
arr.push((len >>> (octets << 3)) & 0xff);
}
arr.push(len);
}
Signature.prototype.toDER = function toDER(enc) {
var r = this.r.toArray();
var s = this.s.toArray();
// Pad values
if (r[0] & 0x80)
r = [ 0 ].concat(r);
// Pad values
if (s[0] & 0x80)
s = [ 0 ].concat(s);
r = rmPadding(r);
s = rmPadding(s);
while (!s[0] && !(s[1] & 0x80)) {
s = s.slice(1);
}
var arr = [ 0x02 ];
constructLength(arr, r.length);
arr = arr.concat(r);
arr.push(0x02);
constructLength(arr, s.length);
var backHalf = arr.concat(s);
var res = [ 0x30 ];
constructLength(res, backHalf.length);
res = res.concat(backHalf);
return utils.encode(res, enc);
};
},{"../../elliptic":41,"bn.js":39}],51:[function(require,module,exports){
'use strict';
var hash = require('hash.js');
var elliptic = require('../../elliptic');
var utils = elliptic.utils;
var assert = utils.assert;
var parseBytes = utils.parseBytes;
var KeyPair = require('./key');
var Signature = require('./signature');
function EDDSA(curve) {
assert(curve === 'ed25519', 'only tested with ed25519 so far');
if (!(this instanceof EDDSA))
return new EDDSA(curve);
var curve = elliptic.curves[curve].curve;
this.curve = curve;
this.g = curve.g;
this.g.precompute(curve.n.bitLength() + 1);
this.pointClass = curve.point().constructor;
this.encodingLength = Math.ceil(curve.n.bitLength() / 8);
this.hash = hash.sha512;
}
module.exports = EDDSA;
/**
* @param {Array|String} message - message bytes
* @param {Array|String|KeyPair} secret - secret bytes or a keypair
* @returns {Signature} - signature
*/
EDDSA.prototype.sign = function sign(message, secret) {
message = parseBytes(message);
var key = this.keyFromSecret(secret);
var r = this.hashInt(key.messagePrefix(), message);
var R = this.g.mul(r);
var Rencoded = this.encodePoint(R);
var s_ = this.hashInt(Rencoded, key.pubBytes(), message)
.mul(key.priv());
var S = r.add(s_).umod(this.curve.n);
return this.makeSignature({ R: R, S: S, Rencoded: Rencoded });
};
/**
* @param {Array} message - message bytes
* @param {Array|String|Signature} sig - sig bytes
* @param {Array|String|Point|KeyPair} pub - public key
* @returns {Boolean} - true if public key matches sig of message
*/
EDDSA.prototype.verify = function verify(message, sig, pub) {
message = parseBytes(message);
sig = this.makeSignature(sig);
var key = this.keyFromPublic(pub);
var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);
var SG = this.g.mul(sig.S());
var RplusAh = sig.R().add(key.pub().mul(h));
return RplusAh.eq(SG);
};
EDDSA.prototype.hashInt = function hashInt() {
var hash = this.hash();
for (var i = 0; i < arguments.length; i++)
hash.update(arguments[i]);
return utils.intFromLE(hash.digest()).umod(this.curve.n);
};
EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {
return KeyPair.fromPublic(this, pub);
};
EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {
return KeyPair.fromSecret(this, secret);
};
EDDSA.prototype.makeSignature = function makeSignature(sig) {
if (sig instanceof Signature)
return sig;
return new Signature(this, sig);
};
/**
* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2
*
* EDDSA defines methods for encoding and decoding points and integers. These are
* helper convenience methods, that pass along to utility functions implied
* parameters.
*
*/
EDDSA.prototype.encodePoint = function encodePoint(point) {
var enc = point.getY().toArray('le', this.encodingLength);
enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0;
return enc;
};
EDDSA.prototype.decodePoint = function decodePoint(bytes) {
bytes = utils.parseBytes(bytes);
var lastIx = bytes.length - 1;
var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80);
var xIsOdd = (bytes[lastIx] & 0x80) !== 0;
var y = utils.intFromLE(normed);
return this.curve.pointFromY(y, xIsOdd);
};
EDDSA.prototype.encodeInt = function encodeInt(num) {
return num.toArray('le', this.encodingLength);
};
EDDSA.prototype.decodeInt = function decodeInt(bytes) {
return utils.intFromLE(bytes);
};
EDDSA.prototype.isPoint = function isPoint(val) {
return val instanceof this.pointClass;
};
},{"../../elliptic":41,"./key":52,"./signature":53,"hash.js":58}],52:[function(require,module,exports){
'use strict';
var elliptic = require('../../elliptic');
var utils = elliptic.utils;
var assert = utils.assert;
var parseBytes = utils.parseBytes;
var cachedProperty = utils.cachedProperty;
/**
* @param {EDDSA} eddsa - instance
* @param {Object} params - public/private key parameters
*
* @param {Array<Byte>} [params.secret] - secret seed bytes
* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
* @param {Array<Byte>} [params.pub] - public key point encoded as bytes
*
*/
function KeyPair(eddsa, params) {
this.eddsa = eddsa;
this._secret = parseBytes(params.secret);
if (eddsa.isPoint(params.pub))
this._pub = params.pub;
else
this._pubBytes = parseBytes(params.pub);
}
KeyPair.fromPublic = function fromPublic(eddsa, pub) {
if (pub instanceof KeyPair)
return pub;
return new KeyPair(eddsa, { pub: pub });
};
KeyPair.fromSecret = function fromSecret(eddsa, secret) {
if (secret instanceof KeyPair)
return secret;
return new KeyPair(eddsa, { secret: secret });
};
KeyPair.prototype.secret = function secret() {
return this._secret;
};
cachedProperty(KeyPair, function pubBytes() {
return this.eddsa.encodePoint(this.pub());
});
cachedProperty(KeyPair, function pub() {
if (this._pubBytes)
return this.eddsa.decodePoint(this._pubBytes);
return this.eddsa.g.mul(this.priv());
});
cachedProperty(KeyPair, function privBytes() {
var eddsa = this.eddsa;
var hash = this.hash();
var lastIx = eddsa.encodingLength - 1;
var a = hash.slice(0, eddsa.encodingLength);
a[0] &= 248;
a[lastIx] &= 127;
a[lastIx] |= 64;
return a;
});
cachedProperty(KeyPair, function priv() {
return this.eddsa.decodeInt(this.privBytes());
});
cachedProperty(KeyPair, function hash() {
return this.eddsa.hash().update(this.secret()).digest();
});
cachedProperty(KeyPair, function messagePrefix() {
return this.hash().slice(this.eddsa.encodingLength);
});
KeyPair.prototype.sign = function sign(message) {
assert(this._secret, 'KeyPair can only verify');
return this.eddsa.sign(message, this);
};
KeyPair.prototype.verify = function verify(message, sig) {
return this.eddsa.verify(message, sig, this);
};
KeyPair.prototype.getSecret = function getSecret(enc) {
assert(this._secret, 'KeyPair is public only');
return utils.encode(this.secret(), enc);
};
KeyPair.prototype.getPublic = function getPublic(enc) {
return utils.encode(this.pubBytes(), enc);
};
module.exports = KeyPair;
},{"../../elliptic":41}],53:[function(require,module,exports){
'use strict';
var BN = require('bn.js');
var elliptic = require('../../elliptic');
var utils = elliptic.utils;
var assert = utils.assert;
var cachedProperty = utils.cachedProperty;
var parseBytes = utils.parseBytes;
/**
* @param {EDDSA} eddsa - eddsa instance
* @param {Array<Bytes>|Object} sig -
* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
* @param {Array<Bytes>} [sig.Rencoded] - R point encoded
* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
*/
function Signature(eddsa, sig) {
this.eddsa = eddsa;
if (typeof sig !== 'object')
sig = parseBytes(sig);
if (Array.isArray(sig)) {
sig = {
R: sig.slice(0, eddsa.encodingLength),
S: sig.slice(eddsa.encodingLength)
};
}
assert(sig.R && sig.S, 'Signature without R or S');
if (eddsa.isPoint(sig.R))
this._R = sig.R;
if (sig.S instanceof BN)
this._S = sig.S;
this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;
this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;
}
cachedProperty(Signature, function S() {
return this.eddsa.decodeInt(this.Sencoded());
});
cachedProperty(Signature, function R() {
return this.eddsa.decodePoint(this.Rencoded());
});
cachedProperty(Signature, function Rencoded() {
return this.eddsa.encodePoint(this.R());
});
cachedProperty(Signature, function Sencoded() {
return this.eddsa.encodeInt(this.S());
});
Signature.prototype.toBytes = function toBytes() {
return this.Rencoded().concat(this.Sencoded());
};
Signature.prototype.toHex = function toHex() {
return utils.encode(this.toBytes(), 'hex').toUpperCase();
};
module.exports = Signature;
},{"../../elliptic":41,"bn.js":39}],54:[function(require,module,exports){
'use strict';
var hash = require('hash.js');
var elliptic = require('../elliptic');
var utils = elliptic.utils;
var assert = utils.assert;
function HmacDRBG(options) {
if (!(this instanceof HmacDRBG))
return new HmacDRBG(options);
this.hash = options.hash;
this.predResist = !!options.predResist;
this.outLen = this.hash.outSize;
this.minEntropy = options.minEntropy || this.hash.hmacStrength;
this.reseed = null;
this.reseedInterval = null;
this.K = null;
this.V = null;
var entropy = utils.toArray(options.entropy, options.entropyEnc);
var nonce = utils.toArray(options.nonce, options.nonceEnc);
var pers = utils.toArray(options.pers, options.persEnc);
assert(entropy.length >= (this.minEntropy / 8),
'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
this._init(entropy, nonce, pers);
}
module.exports = HmacDRBG;
HmacDRBG.prototype._init = function init(entropy, nonce, pers) {
var seed = entropy.concat(nonce).concat(pers);
this.K = new Array(this.outLen / 8);
this.V = new Array(this.outLen / 8);
for (var i = 0; i < this.V.length; i++) {
this.K[i] = 0x00;
this.V[i] = 0x01;
}
this._update(seed);
this.reseed = 1;
this.reseedInterval = 0x1000000000000; // 2^48
};
HmacDRBG.prototype._hmac = function hmac() {
return new hash.hmac(this.hash, this.K);
};
HmacDRBG.prototype._update = function update(seed) {
var kmac = this._hmac()
.update(this.V)
.update([ 0x00 ]);
if (seed)
kmac = kmac.update(seed);
this.K = kmac.digest();
this.V = this._hmac().update(this.V).digest();
if (!seed)
return;
this.K = this._hmac()
.update(this.V)
.update([ 0x01 ])
.update(seed)
.digest();
this.V = this._hmac().update(this.V).digest();
};
HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) {
// Optional entropy enc
if (typeof entropyEnc !== 'string') {
addEnc = add;
add = entropyEnc;
entropyEnc = null;
}
entropy = utils.toBuffer(entropy, entropyEnc);
add = utils.toBuffer(add, addEnc);
assert(entropy.length >= (this.minEntropy / 8),
'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
this._update(entropy.concat(add || []));
this.reseed = 1;
};
HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) {
if (this.reseed > this.reseedInterval)
throw new Error('Reseed is required');
// Optional encoding
if (typeof enc !== 'string') {
addEnc = add;
add = enc;
enc = null;
}
// Optional additional data
if (add) {
add = utils.toArray(add, addEnc);
this._update(add);
}
var temp = [];
while (temp.length < len) {
this.V = this._hmac().update(this.V).digest();
temp = temp.concat(this.V);
}
var res = temp.slice(0, len);
this._update(add);
this.reseed++;
return utils.encode(res, enc);
};
},{"../elliptic":41,"hash.js":58}],55:[function(require,module,exports){
module.exports = {
doubles: {
step: 4,
points: [
[
'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a',
'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821'
],
[
'8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508',
'11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf'
],
[
'175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739',
'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695'
],
[
'363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640',
'4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9'
],
[
'8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c',
'4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36'
],
[
'723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda',
'96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f'
],
[
'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa',
'5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999'
],
[
'100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0',
'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09'
],
[
'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d',
'9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d'
],
[
'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d',
'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088'
],
[
'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1',
'9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d'
],
[
'53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0',
'5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8'
],
[
'8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047',
'10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a'
],
[
'385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862',
'283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453'
],
[
'6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7',
'7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160'
],
[
'3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd',
'56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0'
],
[
'85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83',
'7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6'
],
[
'948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a',
'53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589'
],
[
'6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8',
'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17'
],
[
'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d',
'4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda'
],
[
'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725',
'7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd'
],
[
'213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754',
'4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2'
],
[
'4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c',
'17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6'
],
[
'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6',
'6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f'
],
[
'76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39',
'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01'
],
[
'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891',
'893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3'
],
[
'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b',
'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f'
],
[
'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03',
'2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7'
],
[
'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d',
'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78'
],
[
'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070',
'7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1'
],
[
'90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4',
'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150'
],
[
'8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da',
'662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82'
],
[
'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11',
'1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc'
],
[
'8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e',
'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b'
],
[
'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41',
'2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51'
],
[
'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef',
'67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45'
],
[
'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8',
'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120'
],
[
'324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d',
'648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84'
],
[
'4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96',
'35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d'
],
[
'9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd',
'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d'
],
[
'6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5',
'9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8'
],
[
'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266',
'40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8'
],
[
'7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71',
'34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac'
],
[
'928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac',
'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f'
],
[
'85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751',
'1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962'
],
[
'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e',
'493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907'
],
[
'827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241',
'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec'
],
[
'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3',
'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d'
],
[
'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f',
'4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414'
],
[
'1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19',
'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd'
],
[
'146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be',
'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0'
],
[
'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9',
'6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811'
],
[
'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2',
'8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1'
],
[
'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13',
'7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c'
],
[
'174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c',
'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73'
],
[
'959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba',
'2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd'
],
[
'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151',
'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405'
],
[
'64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073',
'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589'
],
[
'8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458',
'38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e'
],
[
'13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b',
'69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27'
],
[
'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366',
'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1'
],
[
'8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa',
'40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482'
],
[
'8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0',
'620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945'
],
[
'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787',
'7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573'
],
[
'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e',
'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82'
]
]
},
naf: {
wnd: 7,
points: [
[
'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9',
'388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672'
],
[
'2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4',
'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6'
],
[
'5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc',
'6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da'
],
[
'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe',
'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37'
],
[
'774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb',
'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b'
],
[
'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8',
'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81'
],
[
'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e',
'581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58'
],
[
'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34',
'4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77'
],
[
'2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c',
'85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a'
],
[
'352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5',
'321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c'
],
[
'2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f',
'2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67'
],
[
'9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714',
'73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402'
],
[
'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729',
'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55'
],
[
'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db',
'2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482'
],
[
'6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4',
'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82'
],
[
'1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5',
'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396'
],
[
'605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479',
'2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49'
],
[
'62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d',
'80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf'
],
[
'80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f',
'1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a'
],
[
'7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb',
'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7'
],
[
'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9',
'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933'
],
[
'49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963',
'758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a'
],
[
'77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74',
'958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6'
],
[
'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530',
'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37'
],
[
'463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b',
'5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e'
],
[
'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247',
'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6'
],
[
'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1',
'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476'
],
[
'2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120',
'4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40'
],
[
'7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435',
'91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61'
],
[
'754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18',
'673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683'
],
[
'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8',
'59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5'
],
[
'186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb',
'3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b'
],
[
'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f',
'55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417'
],
[
'5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143',
'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868'
],
[
'290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba',
'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a'
],
[
'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45',
'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6'
],
[
'766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a',
'744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996'
],
[
'59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e',
'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e'
],
[
'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8',
'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d'
],
[
'7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c',
'30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2'
],
[
'948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519',
'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e'
],
[
'7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab',
'100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437'
],
[
'3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca',
'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311'
],
[
'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf',
'8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4'
],
[
'1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610',
'68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575'
],
[
'733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4',
'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d'
],
[
'15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c',
'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d'
],
[
'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940',
'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629'
],
[
'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980',
'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06'
],
[
'311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3',
'66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374'
],
[
'34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf',
'9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee'
],
[
'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63',
'4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1'
],
[
'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448',
'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b'
],
[
'32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf',
'5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661'
],
[
'7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5',
'8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6'
],
[
'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6',
'8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e'
],
[
'16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5',
'5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d'
],
[
'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99',
'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc'
],
[
'78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51',
'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4'
],
[
'494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5',
'42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c'
],
[
'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5',
'204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b'
],
[
'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997',
'4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913'
],
[
'841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881',
'73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154'
],
[
'5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5',
'39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865'
],
[
'36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66',
'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc'
],
[
'336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726',
'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224'
],
[
'8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede',
'6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e'
],
[
'1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94',
'60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6'
],
[
'85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31',
'3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511'
],
[
'29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51',
'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b'
],
[
'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252',
'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2'
],
[
'4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5',
'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c'
],
[
'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b',
'6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3'
],
[
'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4',
'322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d'
],
[
'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f',
'6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700'
],
[
'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889',
'2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4'
],
[
'591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246',
'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196'
],
[
'11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984',
'998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4'
],
[
'3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a',
'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257'
],
[
'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030',
'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13'
],
[
'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197',
'6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096'
],
[
'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593',
'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38'
],
[
'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef',
'21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f'
],
[
'347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38',
'60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448'
],
[
'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a',
'49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a'
],
[
'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111',
'5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4'
],
[
'4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502',
'7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437'
],
[
'3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea',
'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7'
],
[
'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26',
'8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d'
],
[
'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986',
'39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a'
],
[
'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e',
'62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54'
],
[
'48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4',
'25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77'
],
[
'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda',
'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517'
],
[
'6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859',
'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10'
],
[
'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f',
'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125'
],
[
'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c',
'6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e'
],
[
'13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942',
'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1'
],
[
'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a',
'1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2'
],
[
'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80',
'5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423'
],
[
'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d',
'438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8'
],
[
'8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1',
'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758'
],
[
'52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63',
'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375'
],
[
'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352',
'6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d'
],
[
'7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193',
'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec'
],
[
'5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00',
'9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0'
],
[
'32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58',
'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c'
],
[
'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7',
'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4'
],
[
'8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8',
'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f'
],
[
'4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e',
'67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649'
],
[
'3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d',
'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826'
],
[
'674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b',
'299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5'
],
[
'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f',
'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87'
],
[
'30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6',
'462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b'
],
[
'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297',
'62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc'
],
[
'93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a',
'7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c'
],
[
'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c',
'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f'
],
[
'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52',
'4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a'
],
[
'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb',
'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46'
],
[
'463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065',
'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f'
],
[
'7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917',
'603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03'
],
[
'74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9',
'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08'
],
[
'30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3',
'553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8'
],
[
'9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57',
'712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373'
],
[
'176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66',
'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3'
],
[
'75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8',
'9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8'
],
[
'809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721',
'9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1'
],
[
'1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180',
'4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9'
]
]
}
};
},{}],56:[function(require,module,exports){
'use strict';
var utils = exports;
var BN = require('bn.js');
utils.assert = function assert(val, msg) {
if (!val)
throw new Error(msg || 'Assertion failed');
};
function toArray(msg, enc) {
if (Array.isArray(msg))
return msg.slice();
if (!msg)
return [];
var res = [];
if (typeof msg !== 'string') {
for (var i = 0; i < msg.length; i++)
res[i] = msg[i] | 0;
return res;
}
if (!enc) {
for (var i = 0; i < msg.length; i++) {
var c = msg.charCodeAt(i);
var hi = c >> 8;
var lo = c & 0xff;
if (hi)
res.push(hi, lo);
else
res.push(lo);
}
} else if (enc === 'hex') {
msg = msg.replace(/[^a-z0-9]+/ig, '');
if (msg.length % 2 !== 0)
msg = '0' + msg;
for (var i = 0; i < msg.length; i += 2)
res.push(parseInt(msg[i] + msg[i + 1], 16));
}
return res;
}
utils.toArray = toArray;
function zero2(word) {
if (word.length === 1)
return '0' + word;
else
return word;
}
utils.zero2 = zero2;
function toHex(msg) {
var res = '';
for (var i = 0; i < msg.length; i++)
res += zero2(msg[i].toString(16));
return res;
}
utils.toHex = toHex;
utils.encode = function encode(arr, enc) {
if (enc === 'hex')
return toHex(arr);
else
return arr;
};
// Represent num in a w-NAF form
function getNAF(num, w) {
var naf = [];
var ws = 1 << (w + 1);
var k = num.clone();
while (k.cmpn(1) >= 0) {
var z;
if (k.isOdd()) {
var mod = k.andln(ws - 1);
if (mod > (ws >> 1) - 1)
z = (ws >> 1) - mod;
else
z = mod;
k.isubn(z);
} else {
z = 0;
}
naf.push(z);
// Optimization, shift by word if possible
var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1;
for (var i = 1; i < shift; i++)
naf.push(0);
k.iushrn(shift);
}
return naf;
}
utils.getNAF = getNAF;
// Represent k1, k2 in a Joint Sparse Form
function getJSF(k1, k2) {
var jsf = [
[],
[]
];
k1 = k1.clone();
k2 = k2.clone();
var d1 = 0;
var d2 = 0;
while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {
// First phase
var m14 = (k1.andln(3) + d1) & 3;
var m24 = (k2.andln(3) + d2) & 3;
if (m14 === 3)
m14 = -1;
if (m24 === 3)
m24 = -1;
var u1;
if ((m14 & 1) === 0) {
u1 = 0;
} else {
var m8 = (k1.andln(7) + d1) & 7;
if ((m8 === 3 || m8 === 5) && m24 === 2)
u1 = -m14;
else
u1 = m14;
}
jsf[0].push(u1);
var u2;
if ((m24 & 1) === 0) {
u2 = 0;
} else {
var m8 = (k2.andln(7) + d2) & 7;
if ((m8 === 3 || m8 === 5) && m14 === 2)
u2 = -m24;
else
u2 = m24;
}
jsf[1].push(u2);
// Second phase
if (2 * d1 === u1 + 1)
d1 = 1 - d1;
if (2 * d2 === u2 + 1)
d2 = 1 - d2;
k1.iushrn(1);
k2.iushrn(1);
}
return jsf;
}
utils.getJSF = getJSF;
function cachedProperty(obj, computer) {
var name = computer.name;
var key = '_' + name;
obj.prototype[name] = function cachedProperty() {
return this[key] !== undefined ? this[key] :
this[key] = computer.call(this);
};
}
utils.cachedProperty = cachedProperty;
function parseBytes(bytes) {
return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
bytes;
}
utils.parseBytes = parseBytes;
function intFromLE(bytes) {
return new BN(bytes, 'hex', 'le');
}
utils.intFromLE = intFromLE;
},{"bn.js":39}],57:[function(require,module,exports){
var r;
module.exports = function rand(len) {
if (!r)
r = new Rand(null);
return r.generate(len);
};
function Rand(rand) {
this.rand = rand;
}
module.exports.Rand = Rand;
Rand.prototype.generate = function generate(len) {
return this._rand(len);
};
if (typeof window === 'object') {
if (window.crypto && window.crypto.getRandomValues) {
// Modern browsers
Rand.prototype._rand = function _rand(n) {
var arr = new Uint8Array(n);
window.crypto.getRandomValues(arr);
return arr;
};
} else if (window.msCrypto && window.msCrypto.getRandomValues) {
// IE
Rand.prototype._rand = function _rand(n) {
var arr = new Uint8Array(n);
window.msCrypto.getRandomValues(arr);
return arr;
};
} else {
// Old junk
Rand.prototype._rand = function() {
throw new Error('Not implemented yet');
};
}
} else {
// Node.js or Web worker
try {
var crypto = require('cry' + 'pto');
Rand.prototype._rand = function _rand(n) {
return crypto.randomBytes(n);
};
} catch (e) {
// Emulate crypto API using randy
Rand.prototype._rand = function _rand(n) {
var res = new Uint8Array(n);
for (var i = 0; i < res.length; i++)
res[i] = this.rand.getByte();
return res;
};
}
}
},{}],58:[function(require,module,exports){
var hash = exports;
hash.utils = require('./hash/utils');
hash.common = require('./hash/common');
hash.sha = require('./hash/sha');
hash.ripemd = require('./hash/ripemd');
hash.hmac = require('./hash/hmac');
// Proxy hash functions to the main object
hash.sha1 = hash.sha.sha1;
hash.sha256 = hash.sha.sha256;
hash.sha224 = hash.sha.sha224;
hash.sha384 = hash.sha.sha384;
hash.sha512 = hash.sha.sha512;
hash.ripemd160 = hash.ripemd.ripemd160;
},{"./hash/common":59,"./hash/hmac":60,"./hash/ripemd":61,"./hash/sha":62,"./hash/utils":63}],59:[function(require,module,exports){
var hash = require('../hash');
var utils = hash.utils;
var assert = utils.assert;
function BlockHash() {
this.pending = null;
this.pendingTotal = 0;
this.blockSize = this.constructor.blockSize;
this.outSize = this.constructor.outSize;
this.hmacStrength = this.constructor.hmacStrength;
this.padLength = this.constructor.padLength / 8;
this.endian = 'big';
this._delta8 = this.blockSize / 8;
this._delta32 = this.blockSize / 32;
}
exports.BlockHash = BlockHash;
BlockHash.prototype.update = function update(msg, enc) {
// Convert message to array, pad it, and join into 32bit blocks
msg = utils.toArray(msg, enc);
if (!this.pending)
this.pending = msg;
else
this.pending = this.pending.concat(msg);
this.pendingTotal += msg.length;
// Enough data, try updating
if (this.pending.length >= this._delta8) {
msg = this.pending;
// Process pending data in blocks
var r = msg.length % this._delta8;
this.pending = msg.slice(msg.length - r, msg.length);
if (this.pending.length === 0)
this.pending = null;
msg = utils.join32(msg, 0, msg.length - r, this.endian);
for (var i = 0; i < msg.length; i += this._delta32)
this._update(msg, i, i + this._delta32);
}
return this;
};
BlockHash.prototype.digest = function digest(enc) {
this.update(this._pad());
assert(this.pending === null);
return this._digest(enc);
};
BlockHash.prototype._pad = function pad() {
var len = this.pendingTotal;
var bytes = this._delta8;
var k = bytes - ((len + this.padLength) % bytes);
var res = new Array(k + this.padLength);
res[0] = 0x80;
for (var i = 1; i < k; i++)
res[i] = 0;
// Append length
len <<= 3;
if (this.endian === 'big') {
for (var t = 8; t < this.padLength; t++)
res[i++] = 0;
res[i++] = 0;
res[i++] = 0;
res[i++] = 0;
res[i++] = 0;
res[i++] = (len >>> 24) & 0xff;
res[i++] = (len >>> 16) & 0xff;
res[i++] = (len >>> 8) & 0xff;
res[i++] = len & 0xff;
} else {
res[i++] = len & 0xff;
res[i++] = (len >>> 8) & 0xff;
res[i++] = (len >>> 16) & 0xff;
res[i++] = (len >>> 24) & 0xff;
res[i++] = 0;
res[i++] = 0;
res[i++] = 0;
res[i++] = 0;
for (var t = 8; t < this.padLength; t++)
res[i++] = 0;
}
return res;
};
},{"../hash":58}],60:[function(require,module,exports){
var hmac = exports;
var hash = require('../hash');
var utils = hash.utils;
var assert = utils.assert;
function Hmac(hash, key, enc) {
if (!(this instanceof Hmac))
return new Hmac(hash, key, enc);
this.Hash = hash;
this.blockSize = hash.blockSize / 8;
this.outSize = hash.outSize / 8;
this.inner = null;
this.outer = null;
this._init(utils.toArray(key, enc));
}
module.exports = Hmac;
Hmac.prototype._init = function init(key) {
// Shorten key, if needed
if (key.length > this.blockSize)
key = new this.Hash().update(key).digest();
assert(key.length <= this.blockSize);
// Add padding to key
for (var i = key.length; i < this.blockSize; i++)
key.push(0);
for (var i = 0; i < key.length; i++)
key[i] ^= 0x36;
this.inner = new this.Hash().update(key);
// 0x36 ^ 0x5c = 0x6a
for (var i = 0; i < key.length; i++)
key[i] ^= 0x6a;
this.outer = new this.Hash().update(key);
};
Hmac.prototype.update = function update(msg, enc) {
this.inner.update(msg, enc);
return this;
};
Hmac.prototype.digest = function digest(enc) {
this.outer.update(this.inner.digest());
return this.outer.digest(enc);
};
},{"../hash":58}],61:[function(require,module,exports){
var hash = require('../hash');
var utils = hash.utils;
var rotl32 = utils.rotl32;
var sum32 = utils.sum32;
var sum32_3 = utils.sum32_3;
var sum32_4 = utils.sum32_4;
var BlockHash = hash.common.BlockHash;
function RIPEMD160() {
if (!(this instanceof RIPEMD160))
return new RIPEMD160();
BlockHash.call(this);
this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
this.endian = 'little';
}
utils.inherits(RIPEMD160, BlockHash);
exports.ripemd160 = RIPEMD160;
RIPEMD160.blockSize = 512;
RIPEMD160.outSize = 160;
RIPEMD160.hmacStrength = 192;
RIPEMD160.padLength = 64;
RIPEMD160.prototype._update = function update(msg, start) {
var A = this.h[0];
var B = this.h[1];
var C = this.h[2];
var D = this.h[3];
var E = this.h[4];
var Ah = A;
var Bh = B;
var Ch = C;
var Dh = D;
var Eh = E;
for (var j = 0; j < 80; j++) {
var T = sum32(
rotl32(
sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),
s[j]),
E);
A = E;
E = D;
D = rotl32(C, 10);
C = B;
B = T;
T = sum32(
rotl32(
sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),
sh[j]),
Eh);
Ah = Eh;
Eh = Dh;
Dh = rotl32(Ch, 10);
Ch = Bh;
Bh = T;
}
T = sum32_3(this.h[1], C, Dh);
this.h[1] = sum32_3(this.h[2], D, Eh);
this.h[2] = sum32_3(this.h[3], E, Ah);
this.h[3] = sum32_3(this.h[4], A, Bh);
this.h[4] = sum32_3(this.h[0], B, Ch);
this.h[0] = T;
};
RIPEMD160.prototype._digest = function digest(enc) {
if (enc === 'hex')
return utils.toHex32(this.h, 'little');
else
return utils.split32(this.h, 'little');
};
function f(j, x, y, z) {
if (j <= 15)
return x ^ y ^ z;
else if (j <= 31)
return (x & y) | ((~x) & z);
else if (j <= 47)
return (x | (~y)) ^ z;
else if (j <= 63)
return (x & z) | (y & (~z));
else
return x ^ (y | (~z));
}
function K(j) {
if (j <= 15)
return 0x00000000;
else if (j <= 31)
return 0x5a827999;
else if (j <= 47)
return 0x6ed9eba1;
else if (j <= 63)
return 0x8f1bbcdc;
else
return 0xa953fd4e;
}
function Kh(j) {
if (j <= 15)
return 0x50a28be6;
else if (j <= 31)
return 0x5c4dd124;
else if (j <= 47)
return 0x6d703ef3;
else if (j <= 63)
return 0x7a6d76e9;
else
return 0x00000000;
}
var r = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
];
var rh = [
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
];
var s = [
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
];
var sh = [
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
];
},{"../hash":58}],62:[function(require,module,exports){
var hash = require('../hash');
var utils = hash.utils;
var assert = utils.assert;
var rotr32 = utils.rotr32;
var rotl32 = utils.rotl32;
var sum32 = utils.sum32;
var sum32_4 = utils.sum32_4;
var sum32_5 = utils.sum32_5;
var rotr64_hi = utils.rotr64_hi;
var rotr64_lo = utils.rotr64_lo;
var shr64_hi = utils.shr64_hi;
var shr64_lo = utils.shr64_lo;
var sum64 = utils.sum64;
var sum64_hi = utils.sum64_hi;
var sum64_lo = utils.sum64_lo;
var sum64_4_hi = utils.sum64_4_hi;
var sum64_4_lo = utils.sum64_4_lo;
var sum64_5_hi = utils.sum64_5_hi;
var sum64_5_lo = utils.sum64_5_lo;
var BlockHash = hash.common.BlockHash;
var sha256_K = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
];
var sha512_K = [
0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
];
var sha1_K = [
0x5A827999, 0x6ED9EBA1,
0x8F1BBCDC, 0xCA62C1D6
];
function SHA256() {
if (!(this instanceof SHA256))
return new SHA256();
BlockHash.call(this);
this.h = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ];
this.k = sha256_K;
this.W = new Array(64);
}
utils.inherits(SHA256, BlockHash);
exports.sha256 = SHA256;
SHA256.blockSize = 512;
SHA256.outSize = 256;
SHA256.hmacStrength = 192;
SHA256.padLength = 64;
SHA256.prototype._update = function _update(msg, start) {
var W = this.W;
for (var i = 0; i < 16; i++)
W[i] = msg[start + i];
for (; i < W.length; i++)
W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);
var a = this.h[0];
var b = this.h[1];
var c = this.h[2];
var d = this.h[3];
var e = this.h[4];
var f = this.h[5];
var g = this.h[6];
var h = this.h[7];
assert(this.k.length === W.length);
for (var i = 0; i < W.length; i++) {
var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);
var T2 = sum32(s0_256(a), maj32(a, b, c));
h = g;
g = f;
f = e;
e = sum32(d, T1);
d = c;
c = b;
b = a;
a = sum32(T1, T2);
}
this.h[0] = sum32(this.h[0], a);
this.h[1] = sum32(this.h[1], b);
this.h[2] = sum32(this.h[2], c);
this.h[3] = sum32(this.h[3], d);
this.h[4] = sum32(this.h[4], e);
this.h[5] = sum32(this.h[5], f);
this.h[6] = sum32(this.h[6], g);
this.h[7] = sum32(this.h[7], h);
};
SHA256.prototype._digest = function digest(enc) {
if (enc === 'hex')
return utils.toHex32(this.h, 'big');
else
return utils.split32(this.h, 'big');
};
function SHA224() {
if (!(this instanceof SHA224))
return new SHA224();
SHA256.call(this);
this.h = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
}
utils.inherits(SHA224, SHA256);
exports.sha224 = SHA224;
SHA224.blockSize = 512;
SHA224.outSize = 224;
SHA224.hmacStrength = 192;
SHA224.padLength = 64;
SHA224.prototype._digest = function digest(enc) {
// Just truncate output
if (enc === 'hex')
return utils.toHex32(this.h.slice(0, 7), 'big');
else
return utils.split32(this.h.slice(0, 7), 'big');
};
function SHA512() {
if (!(this instanceof SHA512))
return new SHA512();
BlockHash.call(this);
this.h = [ 0x6a09e667, 0xf3bcc908,
0xbb67ae85, 0x84caa73b,
0x3c6ef372, 0xfe94f82b,
0xa54ff53a, 0x5f1d36f1,
0x510e527f, 0xade682d1,
0x9b05688c, 0x2b3e6c1f,
0x1f83d9ab, 0xfb41bd6b,
0x5be0cd19, 0x137e2179 ];
this.k = sha512_K;
this.W = new Array(160);
}
utils.inherits(SHA512, BlockHash);
exports.sha512 = SHA512;
SHA512.blockSize = 1024;
SHA512.outSize = 512;
SHA512.hmacStrength = 192;
SHA512.padLength = 128;
SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {
var W = this.W;
// 32 x 32bit words
for (var i = 0; i < 32; i++)
W[i] = msg[start + i];
for (; i < W.length; i += 2) {
var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2
var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);
var c1_hi = W[i - 14]; // i - 7
var c1_lo = W[i - 13];
var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15
var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);
var c3_hi = W[i - 32]; // i - 16
var c3_lo = W[i - 31];
W[i] = sum64_4_hi(c0_hi, c0_lo,
c1_hi, c1_lo,
c2_hi, c2_lo,
c3_hi, c3_lo);
W[i + 1] = sum64_4_lo(c0_hi, c0_lo,
c1_hi, c1_lo,
c2_hi, c2_lo,
c3_hi, c3_lo);
}
};
SHA512.prototype._update = function _update(msg, start) {
this._prepareBlock(msg, start);
var W = this.W;
var ah = this.h[0];
var al = this.h[1];
var bh = this.h[2];
var bl = this.h[3];
var ch = this.h[4];
var cl = this.h[5];
var dh = this.h[6];
var dl = this.h[7];
var eh = this.h[8];
var el = this.h[9];
var fh = this.h[10];
var fl = this.h[11];
var gh = this.h[12];
var gl = this.h[13];
var hh = this.h[14];
var hl = this.h[15];
assert(this.k.length === W.length);
for (var i = 0; i < W.length; i += 2) {
var c0_hi = hh;
var c0_lo = hl;
var c1_hi = s1_512_hi(eh, el);
var c1_lo = s1_512_lo(eh, el);
var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);
var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);
var c3_hi = this.k[i];
var c3_lo = this.k[i + 1];
var c4_hi = W[i];
var c4_lo = W[i + 1];
var T1_hi = sum64_5_hi(c0_hi, c0_lo,
c1_hi, c1_lo,
c2_hi, c2_lo,
c3_hi, c3_lo,
c4_hi, c4_lo);
var T1_lo = sum64_5_lo(c0_hi, c0_lo,
c1_hi, c1_lo,
c2_hi, c2_lo,
c3_hi, c3_lo,
c4_hi, c4_lo);
var c0_hi = s0_512_hi(ah, al);
var c0_lo = s0_512_lo(ah, al);
var c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);
var c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);
var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);
var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);
hh = gh;
hl = gl;
gh = fh;
gl = fl;
fh = eh;
fl = el;
eh = sum64_hi(dh, dl, T1_hi, T1_lo);
el = sum64_lo(dl, dl, T1_hi, T1_lo);
dh = ch;
dl = cl;
ch = bh;
cl = bl;
bh = ah;
bl = al;
ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);
al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);
}
sum64(this.h, 0, ah, al);
sum64(this.h, 2, bh, bl);
sum64(this.h, 4, ch, cl);
sum64(this.h, 6, dh, dl);
sum64(this.h, 8, eh, el);
sum64(this.h, 10, fh, fl);
sum64(this.h, 12, gh, gl);
sum64(this.h, 14, hh, hl);
};
SHA512.prototype._digest = function digest(enc) {
if (enc === 'hex')
return utils.toHex32(this.h, 'big');
else
return utils.split32(this.h, 'big');
};
function SHA384() {
if (!(this instanceof SHA384))
return new SHA384();
SHA512.call(this);
this.h = [ 0xcbbb9d5d, 0xc1059ed8,
0x629a292a, 0x367cd507,
0x9159015a, 0x3070dd17,
0x152fecd8, 0xf70e5939,
0x67332667, 0xffc00b31,
0x8eb44a87, 0x68581511,
0xdb0c2e0d, 0x64f98fa7,
0x47b5481d, 0xbefa4fa4 ];
}
utils.inherits(SHA384, SHA512);
exports.sha384 = SHA384;
SHA384.blockSize = 1024;
SHA384.outSize = 384;
SHA384.hmacStrength = 192;
SHA384.padLength = 128;
SHA384.prototype._digest = function digest(enc) {
if (enc === 'hex')
return utils.toHex32(this.h.slice(0, 12), 'big');
else
return utils.split32(this.h.slice(0, 12), 'big');
};
function SHA1() {
if (!(this instanceof SHA1))
return new SHA1();
BlockHash.call(this);
this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe,
0x10325476, 0xc3d2e1f0 ];
this.W = new Array(80);
}
utils.inherits(SHA1, BlockHash);
exports.sha1 = SHA1;
SHA1.blockSize = 512;
SHA1.outSize = 160;
SHA1.hmacStrength = 80;
SHA1.padLength = 64;
SHA1.prototype._update = function _update(msg, start) {
var W = this.W;
for (var i = 0; i < 16; i++)
W[i] = msg[start + i];
for(; i < W.length; i++)
W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
var a = this.h[0];
var b = this.h[1];
var c = this.h[2];
var d = this.h[3];
var e = this.h[4];
for (var i = 0; i < W.length; i++) {
var s = ~~(i / 20);
var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);
e = d;
d = c;
c = rotl32(b, 30);
b = a;
a = t;
}
this.h[0] = sum32(this.h[0], a);
this.h[1] = sum32(this.h[1], b);
this.h[2] = sum32(this.h[2], c);
this.h[3] = sum32(this.h[3], d);
this.h[4] = sum32(this.h[4], e);
};
SHA1.prototype._digest = function digest(enc) {
if (enc === 'hex')
return utils.toHex32(this.h, 'big');
else
return utils.split32(this.h, 'big');
};
function ch32(x, y, z) {
return (x & y) ^ ((~x) & z);
}
function maj32(x, y, z) {
return (x & y) ^ (x & z) ^ (y & z);
}
function p32(x, y, z) {
return x ^ y ^ z;
}
function s0_256(x) {
return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
}
function s1_256(x) {
return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
}
function g0_256(x) {
return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);
}
function g1_256(x) {
return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);
}
function ft_1(s, x, y, z) {
if (s === 0)
return ch32(x, y, z);
if (s === 1 || s === 3)
return p32(x, y, z);
if (s === 2)
return maj32(x, y, z);
}
function ch64_hi(xh, xl, yh, yl, zh, zl) {
var r = (xh & yh) ^ ((~xh) & zh);
if (r < 0)
r += 0x100000000;
return r;
}
function ch64_lo(xh, xl, yh, yl, zh, zl) {
var r = (xl & yl) ^ ((~xl) & zl);
if (r < 0)
r += 0x100000000;
return r;
}
function maj64_hi(xh, xl, yh, yl, zh, zl) {
var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);
if (r < 0)
r += 0x100000000;
return r;
}
function maj64_lo(xh, xl, yh, yl, zh, zl) {
var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);
if (r < 0)
r += 0x100000000;
return r;
}
function s0_512_hi(xh, xl) {
var c0_hi = rotr64_hi(xh, xl, 28);
var c1_hi = rotr64_hi(xl, xh, 2); // 34
var c2_hi = rotr64_hi(xl, xh, 7); // 39
var r = c0_hi ^ c1_hi ^ c2_hi;
if (r < 0)
r += 0x100000000;
return r;
}
function s0_512_lo(xh, xl) {
var c0_lo = rotr64_lo(xh, xl, 28);
var c1_lo = rotr64_lo(xl, xh, 2); // 34
var c2_lo = rotr64_lo(xl, xh, 7); // 39
var r = c0_lo ^ c1_lo ^ c2_lo;
if (r < 0)
r += 0x100000000;
return r;
}
function s1_512_hi(xh, xl) {
var c0_hi = rotr64_hi(xh, xl, 14);
var c1_hi = rotr64_hi(xh, xl, 18);
var c2_hi = rotr64_hi(xl, xh, 9); // 41
var r = c0_hi ^ c1_hi ^ c2_hi;
if (r < 0)
r += 0x100000000;
return r;
}
function s1_512_lo(xh, xl) {
var c0_lo = rotr64_lo(xh, xl, 14);
var c1_lo = rotr64_lo(xh, xl, 18);
var c2_lo = rotr64_lo(xl, xh, 9); // 41
var r = c0_lo ^ c1_lo ^ c2_lo;
if (r < 0)
r += 0x100000000;
return r;
}
function g0_512_hi(xh, xl) {
var c0_hi = rotr64_hi(xh, xl, 1);
var c1_hi = rotr64_hi(xh, xl, 8);
var c2_hi = shr64_hi(xh, xl, 7);
var r = c0_hi ^ c1_hi ^ c2_hi;
if (r < 0)
r += 0x100000000;
return r;
}
function g0_512_lo(xh, xl) {
var c0_lo = rotr64_lo(xh, xl, 1);
var c1_lo = rotr64_lo(xh, xl, 8);
var c2_lo = shr64_lo(xh, xl, 7);
var r = c0_lo ^ c1_lo ^ c2_lo;
if (r < 0)
r += 0x100000000;
return r;
}
function g1_512_hi(xh, xl) {
var c0_hi = rotr64_hi(xh, xl, 19);
var c1_hi = rotr64_hi(xl, xh, 29); // 61
var c2_hi = shr64_hi(xh, xl, 6);
var r = c0_hi ^ c1_hi ^ c2_hi;
if (r < 0)
r += 0x100000000;
return r;
}
function g1_512_lo(xh, xl) {
var c0_lo = rotr64_lo(xh, xl, 19);
var c1_lo = rotr64_lo(xl, xh, 29); // 61
var c2_lo = shr64_lo(xh, xl, 6);
var r = c0_lo ^ c1_lo ^ c2_lo;
if (r < 0)
r += 0x100000000;
return r;
}
},{"../hash":58}],63:[function(require,module,exports){
var utils = exports;
var inherits = require('inherits');
function toArray(msg, enc) {
if (Array.isArray(msg))
return msg.slice();
if (!msg)
return [];
var res = [];
if (typeof msg === 'string') {
if (!enc) {
for (var i = 0; i < msg.length; i++) {
var c = msg.charCodeAt(i);
var hi = c >> 8;
var lo = c & 0xff;
if (hi)
res.push(hi, lo);
else
res.push(lo);
}
} else if (enc === 'hex') {
msg = msg.replace(/[^a-z0-9]+/ig, '');
if (msg.length % 2 !== 0)
msg = '0' + msg;
for (var i = 0; i < msg.length; i += 2)
res.push(parseInt(msg[i] + msg[i + 1], 16));
}
} else {
for (var i = 0; i < msg.length; i++)
res[i] = msg[i] | 0;
}
return res;
}
utils.toArray = toArray;
function toHex(msg) {
var res = '';
for (var i = 0; i < msg.length; i++)
res += zero2(msg[i].toString(16));
return res;
}
utils.toHex = toHex;
function htonl(w) {
var res = (w >>> 24) |
((w >>> 8) & 0xff00) |
((w << 8) & 0xff0000) |
((w & 0xff) << 24);
return res >>> 0;
}
utils.htonl = htonl;
function toHex32(msg, endian) {
var res = '';
for (var i = 0; i < msg.length; i++) {
var w = msg[i];
if (endian === 'little')
w = htonl(w);
res += zero8(w.toString(16));
}
return res;
}
utils.toHex32 = toHex32;
function zero2(word) {
if (word.length === 1)
return '0' + word;
else
return word;
}
utils.zero2 = zero2;
function zero8(word) {
if (word.length === 7)
return '0' + word;
else if (word.length === 6)
return '00' + word;
else if (word.length === 5)
return '000' + word;
else if (word.length === 4)
return '0000' + word;
else if (word.length === 3)
return '00000' + word;
else if (word.length === 2)
return '000000' + word;
else if (word.length === 1)
return '0000000' + word;
else
return word;
}
utils.zero8 = zero8;
function join32(msg, start, end, endian) {
var len = end - start;
assert(len % 4 === 0);
var res = new Array(len / 4);
for (var i = 0, k = start; i < res.length; i++, k += 4) {
var w;
if (endian === 'big')
w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
else
w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
res[i] = w >>> 0;
}
return res;
}
utils.join32 = join32;
function split32(msg, endian) {
var res = new Array(msg.length * 4);
for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
var m = msg[i];
if (endian === 'big') {
res[k] = m >>> 24;
res[k + 1] = (m >>> 16) & 0xff;
res[k + 2] = (m >>> 8) & 0xff;
res[k + 3] = m & 0xff;
} else {
res[k + 3] = m >>> 24;
res[k + 2] = (m >>> 16) & 0xff;
res[k + 1] = (m >>> 8) & 0xff;
res[k] = m & 0xff;
}
}
return res;
}
utils.split32 = split32;
function rotr32(w, b) {
return (w >>> b) | (w << (32 - b));
}
utils.rotr32 = rotr32;
function rotl32(w, b) {
return (w << b) | (w >>> (32 - b));
}
utils.rotl32 = rotl32;
function sum32(a, b) {
return (a + b) >>> 0;
}
utils.sum32 = sum32;
function sum32_3(a, b, c) {
return (a + b + c) >>> 0;
}
utils.sum32_3 = sum32_3;
function sum32_4(a, b, c, d) {
return (a + b + c + d) >>> 0;
}
utils.sum32_4 = sum32_4;
function sum32_5(a, b, c, d, e) {
return (a + b + c + d + e) >>> 0;
}
utils.sum32_5 = sum32_5;
function assert(cond, msg) {
if (!cond)
throw new Error(msg || 'Assertion failed');
}
utils.assert = assert;
utils.inherits = inherits;
function sum64(buf, pos, ah, al) {
var bh = buf[pos];
var bl = buf[pos + 1];
var lo = (al + bl) >>> 0;
var hi = (lo < al ? 1 : 0) + ah + bh;
buf[pos] = hi >>> 0;
buf[pos + 1] = lo;
}
exports.sum64 = sum64;
function sum64_hi(ah, al, bh, bl) {
var lo = (al + bl) >>> 0;
var hi = (lo < al ? 1 : 0) + ah + bh;
return hi >>> 0;
};
exports.sum64_hi = sum64_hi;
function sum64_lo(ah, al, bh, bl) {
var lo = al + bl;
return lo >>> 0;
};
exports.sum64_lo = sum64_lo;
function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
var carry = 0;
var lo = al;
lo = (lo + bl) >>> 0;
carry += lo < al ? 1 : 0;
lo = (lo + cl) >>> 0;
carry += lo < cl ? 1 : 0;
lo = (lo + dl) >>> 0;
carry += lo < dl ? 1 : 0;
var hi = ah + bh + ch + dh + carry;
return hi >>> 0;
};
exports.sum64_4_hi = sum64_4_hi;
function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
var lo = al + bl + cl + dl;
return lo >>> 0;
};
exports.sum64_4_lo = sum64_4_lo;
function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
var carry = 0;
var lo = al;
lo = (lo + bl) >>> 0;
carry += lo < al ? 1 : 0;
lo = (lo + cl) >>> 0;
carry += lo < cl ? 1 : 0;
lo = (lo + dl) >>> 0;
carry += lo < dl ? 1 : 0;
lo = (lo + el) >>> 0;
carry += lo < el ? 1 : 0;
var hi = ah + bh + ch + dh + eh + carry;
return hi >>> 0;
};
exports.sum64_5_hi = sum64_5_hi;
function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
var lo = al + bl + cl + dl + el;
return lo >>> 0;
};
exports.sum64_5_lo = sum64_5_lo;
function rotr64_hi(ah, al, num) {
var r = (al << (32 - num)) | (ah >>> num);
return r >>> 0;
};
exports.rotr64_hi = rotr64_hi;
function rotr64_lo(ah, al, num) {
var r = (ah << (32 - num)) | (al >>> num);
return r >>> 0;
};
exports.rotr64_lo = rotr64_lo;
function shr64_hi(ah, al, num) {
return ah >>> num;
};
exports.shr64_hi = shr64_hi;
function shr64_lo(ah, al, num) {
var r = (ah << (32 - num)) | (al >>> num);
return r >>> 0;
};
exports.shr64_lo = shr64_lo;
},{"inherits":199}],64:[function(require,module,exports){
module.exports={
"name": "elliptic",
"version": "6.2.3",
"description": "EC cryptography",
"main": "lib/elliptic.js",
"files": [
"lib"
],
"scripts": {
"coverage": "npm run unit --coverage",
"coveralls": "npm run coverage && cat ./coverage/lcov.info | coveralls",
"jscs": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/*.js",
"jshint": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/*.js",
"lint": "npm run jscs && npm run jshint",
"test": "npm run lint && npm run unit",
"unit": "istanbul test _mocha --reporter=spec test/*-test.js"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/indutny/elliptic.git"
},
"keywords": [
"EC",
"Elliptic",
"curve",
"Cryptography"
],
"author": {
"name": "Fedor Indutny",
"email": "fedor@indutny.com"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/indutny/elliptic/issues"
},
"homepage": "https://github.com/indutny/elliptic",
"devDependencies": {
"coveralls": "^2.11.3",
"istanbul": "^0.4.2",
"jscs": "^2.9.0",
"jshint": "^2.6.0",
"mocha": "^2.1.0"
},
"dependencies": {
"bn.js": "^4.0.0",
"brorand": "^1.0.1",
"hash.js": "^1.0.0",
"inherits": "^2.0.1"
},
"gitHead": "c32f20b22b420eb6af3c6dda28963deb7facf823",
"_id": "elliptic@6.2.3",
"_shasum": "18e46d7306b0951275a2d42063270a14b74ebe99",
"_from": "elliptic@^6.0.0",
"_npmVersion": "3.3.12",
"_nodeVersion": "5.4.1",
"_npmUser": {
"name": "indutny",
"email": "fedor@indutny.com"
},
"dist": {
"shasum": "18e46d7306b0951275a2d42063270a14b74ebe99",
"tarball": "http://registry.npmjs.org/elliptic/-/elliptic-6.2.3.tgz"
},
"maintainers": [
{
"name": "indutny",
"email": "fedor@indutny.com"
}
],
"directories": {},
"_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.2.3.tgz",
"readme": "ERROR: No README data found!"
}
},{}],65:[function(require,module,exports){
module.exports={"2.16.840.1.101.3.4.1.1": "aes-128-ecb",
"2.16.840.1.101.3.4.1.2": "aes-128-cbc",
"2.16.840.1.101.3.4.1.3": "aes-128-ofb",
"2.16.840.1.101.3.4.1.4": "aes-128-cfb",
"2.16.840.1.101.3.4.1.21": "aes-192-ecb",
"2.16.840.1.101.3.4.1.22": "aes-192-cbc",
"2.16.840.1.101.3.4.1.23": "aes-192-ofb",
"2.16.840.1.101.3.4.1.24": "aes-192-cfb",
"2.16.840.1.101.3.4.1.41": "aes-256-ecb",
"2.16.840.1.101.3.4.1.42": "aes-256-cbc",
"2.16.840.1.101.3.4.1.43": "aes-256-ofb",
"2.16.840.1.101.3.4.1.44": "aes-256-cfb"
}
},{}],66:[function(require,module,exports){
// from https://github.com/indutny/self-signed/blob/gh-pages/lib/asn1.js
// Fedor, you are amazing.
var asn1 = require('asn1.js')
var RSAPrivateKey = asn1.define('RSAPrivateKey', function () {
this.seq().obj(
this.key('version').int(),
this.key('modulus').int(),
this.key('publicExponent').int(),
this.key('privateExponent').int(),
this.key('prime1').int(),
this.key('prime2').int(),
this.key('exponent1').int(),
this.key('exponent2').int(),
this.key('coefficient').int()
)
})
exports.RSAPrivateKey = RSAPrivateKey
var RSAPublicKey = asn1.define('RSAPublicKey', function () {
this.seq().obj(
this.key('modulus').int(),
this.key('publicExponent').int()
)
})
exports.RSAPublicKey = RSAPublicKey
var PublicKey = asn1.define('SubjectPublicKeyInfo', function () {
this.seq().obj(
this.key('algorithm').use(AlgorithmIdentifier),
this.key('subjectPublicKey').bitstr()
)
})
exports.PublicKey = PublicKey
var AlgorithmIdentifier = asn1.define('AlgorithmIdentifier', function () {
this.seq().obj(
this.key('algorithm').objid(),
this.key('none').null_().optional(),
this.key('curve').objid().optional(),
this.key('params').seq().obj(
this.key('p').int(),
this.key('q').int(),
this.key('g').int()
).optional()
)
})
var PrivateKeyInfo = asn1.define('PrivateKeyInfo', function () {
this.seq().obj(
this.key('version').int(),
this.key('algorithm').use(AlgorithmIdentifier),
this.key('subjectPrivateKey').octstr()
)
})
exports.PrivateKey = PrivateKeyInfo
var EncryptedPrivateKeyInfo = asn1.define('EncryptedPrivateKeyInfo', function () {
this.seq().obj(
this.key('algorithm').seq().obj(
this.key('id').objid(),
this.key('decrypt').seq().obj(
this.key('kde').seq().obj(
this.key('id').objid(),
this.key('kdeparams').seq().obj(
this.key('salt').octstr(),
this.key('iters').int()
)
),
this.key('cipher').seq().obj(
this.key('algo').objid(),
this.key('iv').octstr()
)
)
),
this.key('subjectPrivateKey').octstr()
)
})
exports.EncryptedPrivateKey = EncryptedPrivateKeyInfo
var DSAPrivateKey = asn1.define('DSAPrivateKey', function () {
this.seq().obj(
this.key('version').int(),
this.key('p').int(),
this.key('q').int(),
this.key('g').int(),
this.key('pub_key').int(),
this.key('priv_key').int()
)
})
exports.DSAPrivateKey = DSAPrivateKey
exports.DSAparam = asn1.define('DSAparam', function () {
this.int()
})
var ECPrivateKey = asn1.define('ECPrivateKey', function () {
this.seq().obj(
this.key('version').int(),
this.key('privateKey').octstr(),
this.key('parameters').optional().explicit(0).use(ECParameters),
this.key('publicKey').optional().explicit(1).bitstr()
)
})
exports.ECPrivateKey = ECPrivateKey
var ECParameters = asn1.define('ECParameters', function () {
this.choice({
namedCurve: this.objid()
})
})
exports.signature = asn1.define('signature', function () {
this.seq().obj(
this.key('r').int(),
this.key('s').int()
)
})
},{"asn1.js":69}],67:[function(require,module,exports){
(function (Buffer){
// adapted from https://github.com/apatil/pemstrip
var findProc = /Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)\r?\n\r?\n([0-9A-z\n\r\+\/\=]+)\r?\n/m
var startRegex = /^-----BEGIN (.*) KEY-----\r?\n/m
var fullRegex = /^-----BEGIN (.*) KEY-----\r?\n([0-9A-z\n\r\+\/\=]+)\r?\n-----END \1 KEY-----$/m
var evp = require('evp_bytestokey')
var ciphers = require('browserify-aes')
module.exports = function (okey, password) {
var key = okey.toString()
var match = key.match(findProc)
var decrypted
if (!match) {
var match2 = key.match(fullRegex)
decrypted = new Buffer(match2[2].replace(/\r?\n/g, ''), 'base64')
} else {
var suite = 'aes' + match[1]
var iv = new Buffer(match[2], 'hex')
var cipherText = new Buffer(match[3].replace(/\r?\n/g, ''), 'base64')
var cipherKey = evp(password, iv.slice(0, 8), parseInt(match[1], 10)).key
var out = []
var cipher = ciphers.createDecipheriv(suite, cipherKey, iv)
out.push(cipher.update(cipherText))
out.push(cipher.final())
decrypted = Buffer.concat(out)
}
var tag = key.match(startRegex)[1] + ' KEY'
return {
tag: tag,
data: decrypted
}
}
}).call(this,require("buffer").Buffer)
},{"browserify-aes":86,"buffer":2,"evp_bytestokey":101}],68:[function(require,module,exports){
(function (Buffer){
var asn1 = require('./asn1')
var aesid = require('./aesid.json')
var fixProc = require('./fixProc')
var ciphers = require('browserify-aes')
var compat = require('pbkdf2')
module.exports = parseKeys
function parseKeys (buffer) {
var password
if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) {
password = buffer.passphrase
buffer = buffer.key
}
if (typeof buffer === 'string') {
buffer = new Buffer(buffer)
}
var stripped = fixProc(buffer, password)
var type = stripped.tag
var data = stripped.data
var subtype, ndata
switch (type) {
case 'PUBLIC KEY':
ndata = asn1.PublicKey.decode(data, 'der')
subtype = ndata.algorithm.algorithm.join('.')
switch (subtype) {
case '1.2.840.113549.1.1.1':
return asn1.RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der')
case '1.2.840.10045.2.1':
ndata.subjectPrivateKey = ndata.subjectPublicKey
return {
type: 'ec',
data: ndata
}
case '1.2.840.10040.4.1':
ndata.algorithm.params.pub_key = asn1.DSAparam.decode(ndata.subjectPublicKey.data, 'der')
return {
type: 'dsa',
data: ndata.algorithm.params
}
default: throw new Error('unknown key id ' + subtype)
}
throw new Error('unknown key type ' + type)
case 'ENCRYPTED PRIVATE KEY':
data = asn1.EncryptedPrivateKey.decode(data, 'der')
data = decrypt(data, password)
// falls through
case 'PRIVATE KEY':
ndata = asn1.PrivateKey.decode(data, 'der')
subtype = ndata.algorithm.algorithm.join('.')
switch (subtype) {
case '1.2.840.113549.1.1.1':
return asn1.RSAPrivateKey.decode(ndata.subjectPrivateKey, 'der')
case '1.2.840.10045.2.1':
return {
curve: ndata.algorithm.curve,
privateKey: asn1.ECPrivateKey.decode(ndata.subjectPrivateKey, 'der').privateKey
}
case '1.2.840.10040.4.1':
ndata.algorithm.params.priv_key = asn1.DSAparam.decode(ndata.subjectPrivateKey, 'der')
return {
type: 'dsa',
params: ndata.algorithm.params
}
default: throw new Error('unknown key id ' + subtype)
}
throw new Error('unknown key type ' + type)
case 'RSA PUBLIC KEY':
return asn1.RSAPublicKey.decode(data, 'der')
case 'RSA PRIVATE KEY':
return asn1.RSAPrivateKey.decode(data, 'der')
case 'DSA PRIVATE KEY':
return {
type: 'dsa',
params: asn1.DSAPrivateKey.decode(data, 'der')
}
case 'EC PRIVATE KEY':
data = asn1.ECPrivateKey.decode(data, 'der')
return {
curve: data.parameters.value,
privateKey: data.privateKey
}
default: throw new Error('unknown key type ' + type)
}
}
parseKeys.signature = asn1.signature
function decrypt (data, password) {
var salt = data.algorithm.decrypt.kde.kdeparams.salt
var iters = parseInt(data.algorithm.decrypt.kde.kdeparams.iters.toString(), 10)
var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')]
var iv = data.algorithm.decrypt.cipher.iv
var cipherText = data.subjectPrivateKey
var keylen = parseInt(algo.split('-')[1], 10) / 8
var key = compat.pbkdf2Sync(password, salt, iters, keylen)
var cipher = ciphers.createDecipheriv(algo, key, iv)
var out = []
out.push(cipher.update(cipherText))
out.push(cipher.final())
return Buffer.concat(out)
}
}).call(this,require("buffer").Buffer)
},{"./aesid.json":65,"./asn1":66,"./fixProc":67,"browserify-aes":86,"buffer":2,"pbkdf2":151}],69:[function(require,module,exports){
var asn1 = exports;
asn1.bignum = require('bn.js');
asn1.define = require('./asn1/api').define;
asn1.base = require('./asn1/base');
asn1.constants = require('./asn1/constants');
asn1.decoders = require('./asn1/decoders');
asn1.encoders = require('./asn1/encoders');
},{"./asn1/api":70,"./asn1/base":72,"./asn1/constants":76,"./asn1/decoders":78,"./asn1/encoders":81,"bn.js":39}],70:[function(require,module,exports){
var asn1 = require('../asn1');
var inherits = require('inherits');
var api = exports;
api.define = function define(name, body) {
return new Entity(name, body);
};
function Entity(name, body) {
this.name = name;
this.body = body;
this.decoders = {};
this.encoders = {};
};
Entity.prototype._createNamed = function createNamed(base) {
var named;
try {
named = require('vm').runInThisContext(
'(function ' + this.name + '(entity) {\n' +
' this._initNamed(entity);\n' +
'})'
);
} catch (e) {
named = function (entity) {
this._initNamed(entity);
};
}
inherits(named, base);
named.prototype._initNamed = function initnamed(entity) {
base.call(this, entity);
};
return new named(this);
};
Entity.prototype._getDecoder = function _getDecoder(enc) {
enc = enc || 'der';
// Lazily create decoder
if (!this.decoders.hasOwnProperty(enc))
this.decoders[enc] = this._createNamed(asn1.decoders[enc]);
return this.decoders[enc];
};
Entity.prototype.decode = function decode(data, enc, options) {
return this._getDecoder(enc).decode(data, options);
};
Entity.prototype._getEncoder = function _getEncoder(enc) {
enc = enc || 'der';
// Lazily create encoder
if (!this.encoders.hasOwnProperty(enc))
this.encoders[enc] = this._createNamed(asn1.encoders[enc]);
return this.encoders[enc];
};
Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) {
return this._getEncoder(enc).encode(data, reporter);
};
},{"../asn1":69,"inherits":199,"vm":218}],71:[function(require,module,exports){
var inherits = require('inherits');
var Reporter = require('../base').Reporter;
var Buffer = require('buffer').Buffer;
function DecoderBuffer(base, options) {
Reporter.call(this, options);
if (!Buffer.isBuffer(base)) {
this.error('Input not Buffer');
return;
}
this.base = base;
this.offset = 0;
this.length = base.length;
}
inherits(DecoderBuffer, Reporter);
exports.DecoderBuffer = DecoderBuffer;
DecoderBuffer.prototype.save = function save() {
return { offset: this.offset, reporter: Reporter.prototype.save.call(this) };
};
DecoderBuffer.prototype.restore = function restore(save) {
// Return skipped data
var res = new DecoderBuffer(this.base);
res.offset = save.offset;
res.length = this.offset;
this.offset = save.offset;
Reporter.prototype.restore.call(this, save.reporter);
return res;
};
DecoderBuffer.prototype.isEmpty = function isEmpty() {
return this.offset === this.length;
};
DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) {
if (this.offset + 1 <= this.length)
return this.base.readUInt8(this.offset++, true);
else
return this.error(fail || 'DecoderBuffer overrun');
}
DecoderBuffer.prototype.skip = function skip(bytes, fail) {
if (!(this.offset + bytes <= this.length))
return this.error(fail || 'DecoderBuffer overrun');
var res = new DecoderBuffer(this.base);
// Share reporter state
res._reporterState = this._reporterState;
res.offset = this.offset;
res.length = this.offset + bytes;
this.offset += bytes;
return res;
}
DecoderBuffer.prototype.raw = function raw(save) {
return this.base.slice(save ? save.offset : this.offset, this.length);
}
function EncoderBuffer(value, reporter) {
if (Array.isArray(value)) {
this.length = 0;
this.value = value.map(function(item) {
if (!(item instanceof EncoderBuffer))
item = new EncoderBuffer(item, reporter);
this.length += item.length;
return item;
}, this);
} else if (typeof value === 'number') {
if (!(0 <= value && value <= 0xff))
return reporter.error('non-byte EncoderBuffer value');
this.value = value;
this.length = 1;
} else if (typeof value === 'string') {
this.value = value;
this.length = Buffer.byteLength(value);
} else if (Buffer.isBuffer(value)) {
this.value = value;
this.length = value.length;
} else {
return reporter.error('Unsupported type: ' + typeof value);
}
}
exports.EncoderBuffer = EncoderBuffer;
EncoderBuffer.prototype.join = function join(out, offset) {
if (!out)
out = new Buffer(this.length);
if (!offset)
offset = 0;
if (this.length === 0)
return out;
if (Array.isArray(this.value)) {
this.value.forEach(function(item) {
item.join(out, offset);
offset += item.length;
});
} else {
if (typeof this.value === 'number')
out[offset] = this.value;
else if (typeof this.value === 'string')
out.write(this.value, offset);
else if (Buffer.isBuffer(this.value))
this.value.copy(out, offset);
offset += this.length;
}
return out;
};
},{"../base":72,"buffer":2,"inherits":199}],72:[function(require,module,exports){
var base = exports;
base.Reporter = require('./reporter').Reporter;
base.DecoderBuffer = require('./buffer').DecoderBuffer;
base.EncoderBuffer = require('./buffer').EncoderBuffer;
base.Node = require('./node');
},{"./buffer":71,"./node":73,"./reporter":74}],73:[function(require,module,exports){
var Reporter = require('../base').Reporter;
var EncoderBuffer = require('../base').EncoderBuffer;
var DecoderBuffer = require('../base').DecoderBuffer;
var assert = require('minimalistic-assert');
// Supported tags
var tags = [
'seq', 'seqof', 'set', 'setof', 'objid', 'bool',
'gentime', 'utctime', 'null_', 'enum', 'int',
'bitstr', 'bmpstr', 'charstr', 'genstr', 'graphstr', 'ia5str', 'iso646str',
'numstr', 'octstr', 'printstr', 't61str', 'unistr', 'utf8str', 'videostr'
];
// Public methods list
var methods = [
'key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice',
'any', 'contains'
].concat(tags);
// Overrided methods list
var overrided = [
'_peekTag', '_decodeTag', '_use',
'_decodeStr', '_decodeObjid', '_decodeTime',
'_decodeNull', '_decodeInt', '_decodeBool', '_decodeList',
'_encodeComposite', '_encodeStr', '_encodeObjid', '_encodeTime',
'_encodeNull', '_encodeInt', '_encodeBool'
];
function Node(enc, parent) {
var state = {};
this._baseState = state;
state.enc = enc;
state.parent = parent || null;
state.children = null;
// State
state.tag = null;
state.args = null;
state.reverseArgs = null;
state.choice = null;
state.optional = false;
state.any = false;
state.obj = false;
state.use = null;
state.useDecoder = null;
state.key = null;
state['default'] = null;
state.explicit = null;
state.implicit = null;
state.contains = null;
// Should create new instance on each method
if (!state.parent) {
state.children = [];
this._wrap();
}
}
module.exports = Node;
var stateProps = [
'enc', 'parent', 'children', 'tag', 'args', 'reverseArgs', 'choice',
'optional', 'any', 'obj', 'use', 'alteredUse', 'key', 'default', 'explicit',
'implicit'
];
Node.prototype.clone = function clone() {
var state = this._baseState;
var cstate = {};
stateProps.forEach(function(prop) {
cstate[prop] = state[prop];
});
var res = new this.constructor(cstate.parent);
res._baseState = cstate;
return res;
};
Node.prototype._wrap = function wrap() {
var state = this._baseState;
methods.forEach(function(method) {
this[method] = function _wrappedMethod() {
var clone = new this.constructor(this);
state.children.push(clone);
return clone[method].apply(clone, arguments);
};
}, this);
};
Node.prototype._init = function init(body) {
var state = this._baseState;
assert(state.parent === null);
body.call(this);
// Filter children
state.children = state.children.filter(function(child) {
return child._baseState.parent === this;
}, this);
assert.equal(state.children.length, 1, 'Root node can have only one child');
};
Node.prototype._useArgs = function useArgs(args) {
var state = this._baseState;
// Filter children and args
var children = args.filter(function(arg) {
return arg instanceof this.constructor;
}, this);
args = args.filter(function(arg) {
return !(arg instanceof this.constructor);
}, this);
if (children.length !== 0) {
assert(state.children === null);
state.children = children;
// Replace parent to maintain backward link
children.forEach(function(child) {
child._baseState.parent = this;
}, this);
}
if (args.length !== 0) {
assert(state.args === null);
state.args = args;
state.reverseArgs = args.map(function(arg) {
if (typeof arg !== 'object' || arg.constructor !== Object)
return arg;
var res = {};
Object.keys(arg).forEach(function(key) {
if (key == (key | 0))
key |= 0;
var value = arg[key];
res[value] = key;
});
return res;
});
}
};
//
// Overrided methods
//
overrided.forEach(function(method) {
Node.prototype[method] = function _overrided() {
var state = this._baseState;
throw new Error(method + ' not implemented for encoding: ' + state.enc);
};
});
//
// Public methods
//
tags.forEach(function(tag) {
Node.prototype[tag] = function _tagMethod() {
var state = this._baseState;
var args = Array.prototype.slice.call(arguments);
assert(state.tag === null);
state.tag = tag;
this._useArgs(args);
return this;
};
});
Node.prototype.use = function use(item) {
var state = this._baseState;
assert(state.use === null);
state.use = item;
return this;
};
Node.prototype.optional = function optional() {
var state = this._baseState;
state.optional = true;
return this;
};
Node.prototype.def = function def(val) {
var state = this._baseState;
assert(state['default'] === null);
state['default'] = val;
state.optional = true;
return this;
};
Node.prototype.explicit = function explicit(num) {
var state = this._baseState;
assert(state.explicit === null && state.implicit === null);
state.explicit = num;
return this;
};
Node.prototype.implicit = function implicit(num) {
var state = this._baseState;
assert(state.explicit === null && state.implicit === null);
state.implicit = num;
return this;
};
Node.prototype.obj = function obj() {
var state = this._baseState;
var args = Array.prototype.slice.call(arguments);
state.obj = true;
if (args.length !== 0)
this._useArgs(args);
return this;
};
Node.prototype.key = function key(newKey) {
var state = this._baseState;
assert(state.key === null);
state.key = newKey;
return this;
};
Node.prototype.any = function any() {
var state = this._baseState;
state.any = true;
return this;
};
Node.prototype.choice = function choice(obj) {
var state = this._baseState;
assert(state.choice === null);
state.choice = obj;
this._useArgs(Object.keys(obj).map(function(key) {
return obj[key];
}));
return this;
};
Node.prototype.contains = function contains(item) {
var state = this._baseState;
assert(state.use === null);
state.contains = item;
return this;
};
//
// Decoding
//
Node.prototype._decode = function decode(input) {
var state = this._baseState;
// Decode root node
if (state.parent === null)
return input.wrapResult(state.children[0]._decode(input));
var result = state['default'];
var present = true;
var prevKey;
if (state.key !== null)
prevKey = input.enterKey(state.key);
// Check if tag is there
if (state.optional) {
var tag = null;
if (state.explicit !== null)
tag = state.explicit;
else if (state.implicit !== null)
tag = state.implicit;
else if (state.tag !== null)
tag = state.tag;
if (tag === null && !state.any) {
// Trial and Error
var save = input.save();
try {
if (state.choice === null)
this._decodeGeneric(state.tag, input);
else
this._decodeChoice(input);
present = true;
} catch (e) {
present = false;
}
input.restore(save);
} else {
present = this._peekTag(input, tag, state.any);
if (input.isError(present))
return present;
}
}
// Push object on stack
var prevObj;
if (state.obj && present)
prevObj = input.enterObject();
if (present) {
// Unwrap explicit values
if (state.explicit !== null) {
var explicit = this._decodeTag(input, state.explicit);
if (input.isError(explicit))
return explicit;
input = explicit;
}
// Unwrap implicit and normal values
if (state.use === null && state.choice === null) {
if (state.any)
var save = input.save();
var body = this._decodeTag(
input,
state.implicit !== null ? state.implicit : state.tag,
state.any
);
if (input.isError(body))
return body;
if (state.any)
result = input.raw(save);
else
input = body;
}
// Select proper method for tag
if (state.any)
result = result;
else if (state.choice === null)
result = this._decodeGeneric(state.tag, input);
else
result = this._decodeChoice(input);
if (input.isError(result))
return result;
// Decode children
if (!state.any && state.choice === null && state.children !== null) {
state.children.forEach(function decodeChildren(child) {
// NOTE: We are ignoring errors here, to let parser continue with other
// parts of encoded data
child._decode(input);
});
}
// Decode contained/encoded by schema, only in bit or octet strings
if (state.contains && (state.tag === 'octstr' || state.tag === 'bitstr')) {
var data = new DecoderBuffer(result);
result = this._getUse(state.contains, input._reporterState.obj)._decode(data);
}
}
// Pop object
if (state.obj && present)
result = input.leaveObject(prevObj);
// Set key
if (state.key !== null && (result !== null || present === true))
input.leaveKey(prevKey, state.key, result);
return result;
};
Node.prototype._decodeGeneric = function decodeGeneric(tag, input) {
var state = this._baseState;
if (tag === 'seq' || tag === 'set')
return null;
if (tag === 'seqof' || tag === 'setof')
return this._decodeList(input, tag, state.args[0]);
else if (/str$/.test(tag))
return this._decodeStr(input, tag);
else if (tag === 'objid' && state.args)
return this._decodeObjid(input, state.args[0], state.args[1]);
else if (tag === 'objid')
return this._decodeObjid(input, null, null);
else if (tag === 'gentime' || tag === 'utctime')
return this._decodeTime(input, tag);
else if (tag === 'null_')
return this._decodeNull(input);
else if (tag === 'bool')
return this._decodeBool(input);
else if (tag === 'int' || tag === 'enum')
return this._decodeInt(input, state.args && state.args[0]);
else if (state.use !== null)
return this._getUse(state.use, input._reporterState.obj)._decode(input);
else
return input.error('unknown tag: ' + tag);
};
Node.prototype._getUse = function _getUse(entity, obj) {
var state = this._baseState;
// Create altered use decoder if implicit is set
state.useDecoder = this._use(entity, obj);
assert(state.useDecoder._baseState.parent === null);
state.useDecoder = state.useDecoder._baseState.children[0];
if (state.implicit !== state.useDecoder._baseState.implicit) {
state.useDecoder = state.useDecoder.clone();
state.useDecoder._baseState.implicit = state.implicit;
}
return state.useDecoder;
};
Node.prototype._decodeChoice = function decodeChoice(input) {
var state = this._baseState;
var result = null;
var match = false;
Object.keys(state.choice).some(function(key) {
var save = input.save();
var node = state.choice[key];
try {
var value = node._decode(input);
if (input.isError(value))
return false;
result = { type: key, value: value };
match = true;
} catch (e) {
input.restore(save);
return false;
}
return true;
}, this);
if (!match)
return input.error('Choice not matched');
return result;
};
//
// Encoding
//
Node.prototype._createEncoderBuffer = function createEncoderBuffer(data) {
return new EncoderBuffer(data, this.reporter);
};
Node.prototype._encode = function encode(data, reporter, parent) {
var state = this._baseState;
if (state['default'] !== null && state['default'] === data)
return;
var result = this._encodeValue(data, reporter, parent);
if (result === undefined)
return;
if (this._skipDefault(result, reporter, parent))
return;
return result;
};
Node.prototype._encodeValue = function encode(data, reporter, parent) {
var state = this._baseState;
// Decode root node
if (state.parent === null)
return state.children[0]._encode(data, reporter || new Reporter());
var result = null;
// Set reporter to share it with a child class
this.reporter = reporter;
// Check if data is there
if (state.optional && data === undefined) {
if (state['default'] !== null)
data = state['default']
else
return;
}
// Encode children first
var content = null;
var primitive = false;
if (state.any) {
// Anything that was given is translated to buffer
result = this._createEncoderBuffer(data);
} else if (state.choice) {
result = this._encodeChoice(data, reporter);
} else if (state.contains) {
content = this._getUse(state.contains, parent)._encode(data, reporter);
primitive = true;
} else if (state.children) {
content = state.children.map(function(child) {
if (child._baseState.tag === 'null_')
return child._encode(null, reporter, data);
if (child._baseState.key === null)
return reporter.error('Child should have a key');
var prevKey = reporter.enterKey(child._baseState.key);
if (typeof data !== 'object')
return reporter.error('Child expected, but input is not object');
var res = child._encode(data[child._baseState.key], reporter, data);
reporter.leaveKey(prevKey);
return res;
}, this).filter(function(child) {
return child;
});
content = this._createEncoderBuffer(content);
} else {
if (state.tag === 'seqof' || state.tag === 'setof') {
// TODO(indutny): this should be thrown on DSL level
if (!(state.args && state.args.length === 1))
return reporter.error('Too many args for : ' + state.tag);
if (!Array.isArray(data))
return reporter.error('seqof/setof, but data is not Array');
var child = this.clone();
child._baseState.implicit = null;
content = this._createEncoderBuffer(data.map(function(item) {
var state = this._baseState;
return this._getUse(state.args[0], data)._encode(item, reporter);
}, child));
} else if (state.use !== null) {
result = this._getUse(state.use, parent)._encode(data, reporter);
} else {
content = this._encodePrimitive(state.tag, data);
primitive = true;
}
}
// Encode data itself
var result;
if (!state.any && state.choice === null) {
var tag = state.implicit !== null ? state.implicit : state.tag;
var cls = state.implicit === null ? 'universal' : 'context';
if (tag === null) {
if (state.use === null)
reporter.error('Tag could be ommited only for .use()');
} else {
if (state.use === null)
result = this._encodeComposite(tag, primitive, cls, content);
}
}
// Wrap in explicit
if (state.explicit !== null)
result = this._encodeComposite(state.explicit, false, 'context', result);
return result;
};
Node.prototype._encodeChoice = function encodeChoice(data, reporter) {
var state = this._baseState;
var node = state.choice[data.type];
if (!node) {
assert(
false,
data.type + ' not found in ' +
JSON.stringify(Object.keys(state.choice)));
}
return node._encode(data.value, reporter);
};
Node.prototype._encodePrimitive = function encodePrimitive(tag, data) {
var state = this._baseState;
if (/str$/.test(tag))
return this._encodeStr(data, tag);
else if (tag === 'objid' && state.args)
return this._encodeObjid(data, state.reverseArgs[0], state.args[1]);
else if (tag === 'objid')
return this._encodeObjid(data, null, null);
else if (tag === 'gentime' || tag === 'utctime')
return this._encodeTime(data, tag);
else if (tag === 'null_')
return this._encodeNull();
else if (tag === 'int' || tag === 'enum')
return this._encodeInt(data, state.args && state.reverseArgs[0]);
else if (tag === 'bool')
return this._encodeBool(data);
else
throw new Error('Unsupported tag: ' + tag);
};
Node.prototype._isNumstr = function isNumstr(str) {
return /^[0-9 ]*$/.test(str);
};
Node.prototype._isPrintstr = function isPrintstr(str) {
return /^[A-Za-z0-9 '\(\)\+,\-\.\/:=\?]*$/.test(str);
};
},{"../base":72,"minimalistic-assert":83}],74:[function(require,module,exports){
var inherits = require('inherits');
function Reporter(options) {
this._reporterState = {
obj: null,
path: [],
options: options || {},
errors: []
};
}
exports.Reporter = Reporter;
Reporter.prototype.isError = function isError(obj) {
return obj instanceof ReporterError;
};
Reporter.prototype.save = function save() {
var state = this._reporterState;
return { obj: state.obj, pathLen: state.path.length };
};
Reporter.prototype.restore = function restore(data) {
var state = this._reporterState;
state.obj = data.obj;
state.path = state.path.slice(0, data.pathLen);
};
Reporter.prototype.enterKey = function enterKey(key) {
return this._reporterState.path.push(key);
};
Reporter.prototype.leaveKey = function leaveKey(index, key, value) {
var state = this._reporterState;
state.path = state.path.slice(0, index - 1);
if (state.obj !== null)
state.obj[key] = value;
};
Reporter.prototype.enterObject = function enterObject() {
var state = this._reporterState;
var prev = state.obj;
state.obj = {};
return prev;
};
Reporter.prototype.leaveObject = function leaveObject(prev) {
var state = this._reporterState;
var now = state.obj;
state.obj = prev;
return now;
};
Reporter.prototype.error = function error(msg) {
var err;
var state = this._reporterState;
var inherited = msg instanceof ReporterError;
if (inherited) {
err = msg;
} else {
err = new ReporterError(state.path.map(function(elem) {
return '[' + JSON.stringify(elem) + ']';
}).join(''), msg.message || msg, msg.stack);
}
if (!state.options.partial)
throw err;
if (!inherited)
state.errors.push(err);
return err;
};
Reporter.prototype.wrapResult = function wrapResult(result) {
var state = this._reporterState;
if (!state.options.partial)
return result;
return {
result: this.isError(result) ? null : result,
errors: state.errors
};
};
function ReporterError(path, msg) {
this.path = path;
this.rethrow(msg);
};
inherits(ReporterError, Error);
ReporterError.prototype.rethrow = function rethrow(msg) {
this.message = msg + ' at: ' + (this.path || '(shallow)');
Error.captureStackTrace(this, ReporterError);
return this;
};
},{"inherits":199}],75:[function(require,module,exports){
var constants = require('../constants');
exports.tagClass = {
0: 'universal',
1: 'application',
2: 'context',
3: 'private'
};
exports.tagClassByName = constants._reverse(exports.tagClass);
exports.tag = {
0x00: 'end',
0x01: 'bool',
0x02: 'int',
0x03: 'bitstr',
0x04: 'octstr',
0x05: 'null_',
0x06: 'objid',
0x07: 'objDesc',
0x08: 'external',
0x09: 'real',
0x0a: 'enum',
0x0b: 'embed',
0x0c: 'utf8str',
0x0d: 'relativeOid',
0x10: 'seq',
0x11: 'set',
0x12: 'numstr',
0x13: 'printstr',
0x14: 't61str',
0x15: 'videostr',
0x16: 'ia5str',
0x17: 'utctime',
0x18: 'gentime',
0x19: 'graphstr',
0x1a: 'iso646str',
0x1b: 'genstr',
0x1c: 'unistr',
0x1d: 'charstr',
0x1e: 'bmpstr'
};
exports.tagByName = constants._reverse(exports.tag);
},{"../constants":76}],76:[function(require,module,exports){
var constants = exports;
// Helper
constants._reverse = function reverse(map) {
var res = {};
Object.keys(map).forEach(function(key) {
// Convert key to integer if it is stringified
if ((key | 0) == key)
key = key | 0;
var value = map[key];
res[value] = key;
});
return res;
};
constants.der = require('./der');
},{"./der":75}],77:[function(require,module,exports){
var inherits = require('inherits');
var asn1 = require('../../asn1');
var base = asn1.base;
var bignum = asn1.bignum;
// Import DER constants
var der = asn1.constants.der;
function DERDecoder(entity) {
this.enc = 'der';
this.name = entity.name;
this.entity = entity;
// Construct base tree
this.tree = new DERNode();
this.tree._init(entity.body);
};
module.exports = DERDecoder;
DERDecoder.prototype.decode = function decode(data, options) {
if (!(data instanceof base.DecoderBuffer))
data = new base.DecoderBuffer(data, options);
return this.tree._decode(data, options);
};
// Tree methods
function DERNode(parent) {
base.Node.call(this, 'der', parent);
}
inherits(DERNode, base.Node);
DERNode.prototype._peekTag = function peekTag(buffer, tag, any) {
if (buffer.isEmpty())
return false;
var state = buffer.save();
var decodedTag = derDecodeTag(buffer, 'Failed to peek tag: "' + tag + '"');
if (buffer.isError(decodedTag))
return decodedTag;
buffer.restore(state);
return decodedTag.tag === tag || decodedTag.tagStr === tag ||
(decodedTag.tagStr + 'of') === tag || any;
};
DERNode.prototype._decodeTag = function decodeTag(buffer, tag, any) {
var decodedTag = derDecodeTag(buffer,
'Failed to decode tag of "' + tag + '"');
if (buffer.isError(decodedTag))
return decodedTag;
var len = derDecodeLen(buffer,
decodedTag.primitive,
'Failed to get length of "' + tag + '"');
// Failure
if (buffer.isError(len))
return len;
if (!any &&
decodedTag.tag !== tag &&
decodedTag.tagStr !== tag &&
decodedTag.tagStr + 'of' !== tag) {
return buffer.error('Failed to match tag: "' + tag + '"');
}
if (decodedTag.primitive || len !== null)
return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
// Indefinite length... find END tag
var state = buffer.save();
var res = this._skipUntilEnd(
buffer,
'Failed to skip indefinite length body: "' + this.tag + '"');
if (buffer.isError(res))
return res;
len = buffer.offset - state.offset;
buffer.restore(state);
return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
};
DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer, fail) {
while (true) {
var tag = derDecodeTag(buffer, fail);
if (buffer.isError(tag))
return tag;
var len = derDecodeLen(buffer, tag.primitive, fail);
if (buffer.isError(len))
return len;
var res;
if (tag.primitive || len !== null)
res = buffer.skip(len)
else
res = this._skipUntilEnd(buffer, fail);
// Failure
if (buffer.isError(res))
return res;
if (tag.tagStr === 'end')
break;
}
};
DERNode.prototype._decodeList = function decodeList(buffer, tag, decoder) {
var result = [];
while (!buffer.isEmpty()) {
var possibleEnd = this._peekTag(buffer, 'end');
if (buffer.isError(possibleEnd))
return possibleEnd;
var res = decoder.decode(buffer, 'der');
if (buffer.isError(res) && possibleEnd)
break;
result.push(res);
}
return result;
};
DERNode.prototype._decodeStr = function decodeStr(buffer, tag) {
if (tag === 'bitstr') {
var unused = buffer.readUInt8();
if (buffer.isError(unused))
return unused;
return { unused: unused, data: buffer.raw() };
} else if (tag === 'bmpstr') {
var raw = buffer.raw();
if (raw.length % 2 === 1)
return buffer.error('Decoding of string type: bmpstr length mismatch');
var str = '';
for (var i = 0; i < raw.length / 2; i++) {
str += String.fromCharCode(raw.readUInt16BE(i * 2));
}
return str;
} else if (tag === 'numstr') {
var numstr = buffer.raw().toString('ascii');
if (!this._isNumstr(numstr)) {
return buffer.error('Decoding of string type: ' +
'numstr unsupported characters');
}
return numstr;
} else if (tag === 'octstr') {
return buffer.raw();
} else if (tag === 'printstr') {
var printstr = buffer.raw().toString('ascii');
if (!this._isPrintstr(printstr)) {
return buffer.error('Decoding of string type: ' +
'printstr unsupported characters');
}
return printstr;
} else if (/str$/.test(tag)) {
return buffer.raw().toString();
} else {
return buffer.error('Decoding of string type: ' + tag + ' unsupported');
}
};
DERNode.prototype._decodeObjid = function decodeObjid(buffer, values, relative) {
var result;
var identifiers = [];
var ident = 0;
while (!buffer.isEmpty()) {
var subident = buffer.readUInt8();
ident <<= 7;
ident |= subident & 0x7f;
if ((subident & 0x80) === 0) {
identifiers.push(ident);
ident = 0;
}
}
if (subident & 0x80)
identifiers.push(ident);
var first = (identifiers[0] / 40) | 0;
var second = identifiers[0] % 40;
if (relative)
result = identifiers;
else
result = [first, second].concat(identifiers.slice(1));
if (values) {
var tmp = values[result.join(' ')];
if (tmp === undefined)
tmp = values[result.join('.')];
if (tmp !== undefined)
result = tmp;
}
return result;
};
DERNode.prototype._decodeTime = function decodeTime(buffer, tag) {
var str = buffer.raw().toString();
if (tag === 'gentime') {
var year = str.slice(0, 4) | 0;
var mon = str.slice(4, 6) | 0;
var day = str.slice(6, 8) | 0;
var hour = str.slice(8, 10) | 0;
var min = str.slice(10, 12) | 0;
var sec = str.slice(12, 14) | 0;
} else if (tag === 'utctime') {
var year = str.slice(0, 2) | 0;
var mon = str.slice(2, 4) | 0;
var day = str.slice(4, 6) | 0;
var hour = str.slice(6, 8) | 0;
var min = str.slice(8, 10) | 0;
var sec = str.slice(10, 12) | 0;
if (year < 70)
year = 2000 + year;
else
year = 1900 + year;
} else {
return buffer.error('Decoding ' + tag + ' time is not supported yet');
}
return Date.UTC(year, mon - 1, day, hour, min, sec, 0);
};
DERNode.prototype._decodeNull = function decodeNull(buffer) {
return null;
};
DERNode.prototype._decodeBool = function decodeBool(buffer) {
var res = buffer.readUInt8();
if (buffer.isError(res))
return res;
else
return res !== 0;
};
DERNode.prototype._decodeInt = function decodeInt(buffer, values) {
// Bigint, return as it is (assume big endian)
var raw = buffer.raw();
var res = new bignum(raw);
if (values)
res = values[res.toString(10)] || res;
return res;
};
DERNode.prototype._use = function use(entity, obj) {
if (typeof entity === 'function')
entity = entity(obj);
return entity._getDecoder('der').tree;
};
// Utility methods
function derDecodeTag(buf, fail) {
var tag = buf.readUInt8(fail);
if (buf.isError(tag))
return tag;
var cls = der.tagClass[tag >> 6];
var primitive = (tag & 0x20) === 0;
// Multi-octet tag - load
if ((tag & 0x1f) === 0x1f) {
var oct = tag;
tag = 0;
while ((oct & 0x80) === 0x80) {
oct = buf.readUInt8(fail);
if (buf.isError(oct))
return oct;
tag <<= 7;
tag |= oct & 0x7f;
}
} else {
tag &= 0x1f;
}
var tagStr = der.tag[tag];
return {
cls: cls,
primitive: primitive,
tag: tag,
tagStr: tagStr
};
}
function derDecodeLen(buf, primitive, fail) {
var len = buf.readUInt8(fail);
if (buf.isError(len))
return len;
// Indefinite form
if (!primitive && len === 0x80)
return null;
// Definite form
if ((len & 0x80) === 0) {
// Short form
return len;
}
// Long form
var num = len & 0x7f;
if (num >= 4)
return buf.error('length octect is too long');
len = 0;
for (var i = 0; i < num; i++) {
len <<= 8;
var j = buf.readUInt8(fail);
if (buf.isError(j))
return j;
len |= j;
}
return len;
}
},{"../../asn1":69,"inherits":199}],78:[function(require,module,exports){
var decoders = exports;
decoders.der = require('./der');
decoders.pem = require('./pem');
},{"./der":77,"./pem":79}],79:[function(require,module,exports){
var inherits = require('inherits');
var Buffer = require('buffer').Buffer;
var DERDecoder = require('./der');
function PEMDecoder(entity) {
DERDecoder.call(this, entity);
this.enc = 'pem';
};
inherits(PEMDecoder, DERDecoder);
module.exports = PEMDecoder;
PEMDecoder.prototype.decode = function decode(data, options) {
var lines = data.toString().split(/[\r\n]+/g);
var label = options.label.toUpperCase();
var re = /^-----(BEGIN|END) ([^-]+)-----$/;
var start = -1;
var end = -1;
for (var i = 0; i < lines.length; i++) {
var match = lines[i].match(re);
if (match === null)
continue;
if (match[2] !== label)
continue;
if (start === -1) {
if (match[1] !== 'BEGIN')
break;
start = i;
} else {
if (match[1] !== 'END')
break;
end = i;
break;
}
}
if (start === -1 || end === -1)
throw new Error('PEM section not found for: ' + label);
var base64 = lines.slice(start + 1, end).join('');
// Remove excessive symbols
base64.replace(/[^a-z0-9\+\/=]+/gi, '');
var input = new Buffer(base64, 'base64');
return DERDecoder.prototype.decode.call(this, input, options);
};
},{"./der":77,"buffer":2,"inherits":199}],80:[function(require,module,exports){
var inherits = require('inherits');
var Buffer = require('buffer').Buffer;
var asn1 = require('../../asn1');
var base = asn1.base;
// Import DER constants
var der = asn1.constants.der;
function DEREncoder(entity) {
this.enc = 'der';
this.name = entity.name;
this.entity = entity;
// Construct base tree
this.tree = new DERNode();
this.tree._init(entity.body);
};
module.exports = DEREncoder;
DEREncoder.prototype.encode = function encode(data, reporter) {
return this.tree._encode(data, reporter).join();
};
// Tree methods
function DERNode(parent) {
base.Node.call(this, 'der', parent);
}
inherits(DERNode, base.Node);
DERNode.prototype._encodeComposite = function encodeComposite(tag,
primitive,
cls,
content) {
var encodedTag = encodeTag(tag, primitive, cls, this.reporter);
// Short form
if (content.length < 0x80) {
var header = new Buffer(2);
header[0] = encodedTag;
header[1] = content.length;
return this._createEncoderBuffer([ header, content ]);
}
// Long form
// Count octets required to store length
var lenOctets = 1;
for (var i = content.length; i >= 0x100; i >>= 8)
lenOctets++;
var header = new Buffer(1 + 1 + lenOctets);
header[0] = encodedTag;
header[1] = 0x80 | lenOctets;
for (var i = 1 + lenOctets, j = content.length; j > 0; i--, j >>= 8)
header[i] = j & 0xff;
return this._createEncoderBuffer([ header, content ]);
};
DERNode.prototype._encodeStr = function encodeStr(str, tag) {
if (tag === 'bitstr') {
return this._createEncoderBuffer([ str.unused | 0, str.data ]);
} else if (tag === 'bmpstr') {
var buf = new Buffer(str.length * 2);
for (var i = 0; i < str.length; i++) {
buf.writeUInt16BE(str.charCodeAt(i), i * 2);
}
return this._createEncoderBuffer(buf);
} else if (tag === 'numstr') {
if (!this._isNumstr(str)) {
return this.reporter.error('Encoding of string type: numstr supports ' +
'only digits and space');
}
return this._createEncoderBuffer(str);
} else if (tag === 'printstr') {
if (!this._isPrintstr(str)) {
return this.reporter.error('Encoding of string type: printstr supports ' +
'only latin upper and lower case letters, ' +
'digits, space, apostrophe, left and rigth ' +
'parenthesis, plus sign, comma, hyphen, ' +
'dot, slash, colon, equal sign, ' +
'question mark');
}
return this._createEncoderBuffer(str);
} else if (/str$/.test(tag)) {
return this._createEncoderBuffer(str);
} else {
return this.reporter.error('Encoding of string type: ' + tag +
' unsupported');
}
};
DERNode.prototype._encodeObjid = function encodeObjid(id, values, relative) {
if (typeof id === 'string') {
if (!values)
return this.reporter.error('string objid given, but no values map found');
if (!values.hasOwnProperty(id))
return this.reporter.error('objid not found in values map');
id = values[id].split(/[\s\.]+/g);
for (var i = 0; i < id.length; i++)
id[i] |= 0;
} else if (Array.isArray(id)) {
id = id.slice();
for (var i = 0; i < id.length; i++)
id[i] |= 0;
}
if (!Array.isArray(id)) {
return this.reporter.error('objid() should be either array or string, ' +
'got: ' + JSON.stringify(id));
}
if (!relative) {
if (id[1] >= 40)
return this.reporter.error('Second objid identifier OOB');
id.splice(0, 2, id[0] * 40 + id[1]);
}
// Count number of octets
var size = 0;
for (var i = 0; i < id.length; i++) {
var ident = id[i];
for (size++; ident >= 0x80; ident >>= 7)
size++;
}
var objid = new Buffer(size);
var offset = objid.length - 1;
for (var i = id.length - 1; i >= 0; i--) {
var ident = id[i];
objid[offset--] = ident & 0x7f;
while ((ident >>= 7) > 0)
objid[offset--] = 0x80 | (ident & 0x7f);
}
return this._createEncoderBuffer(objid);
};
function two(num) {
if (num < 10)
return '0' + num;
else
return num;
}
DERNode.prototype._encodeTime = function encodeTime(time, tag) {
var str;
var date = new Date(time);
if (tag === 'gentime') {
str = [
two(date.getFullYear()),
two(date.getUTCMonth() + 1),
two(date.getUTCDate()),
two(date.getUTCHours()),
two(date.getUTCMinutes()),
two(date.getUTCSeconds()),
'Z'
].join('');
} else if (tag === 'utctime') {
str = [
two(date.getFullYear() % 100),
two(date.getUTCMonth() + 1),
two(date.getUTCDate()),
two(date.getUTCHours()),
two(date.getUTCMinutes()),
two(date.getUTCSeconds()),
'Z'
].join('');
} else {
this.reporter.error('Encoding ' + tag + ' time is not supported yet');
}
return this._encodeStr(str, 'octstr');
};
DERNode.prototype._encodeNull = function encodeNull() {
return this._createEncoderBuffer('');
};
DERNode.prototype._encodeInt = function encodeInt(num, values) {
if (typeof num === 'string') {
if (!values)
return this.reporter.error('String int or enum given, but no values map');
if (!values.hasOwnProperty(num)) {
return this.reporter.error('Values map doesn\'t contain: ' +
JSON.stringify(num));
}
num = values[num];
}
// Bignum, assume big endian
if (typeof num !== 'number' && !Buffer.isBuffer(num)) {
var numArray = num.toArray();
if (!num.sign && numArray[0] & 0x80) {
numArray.unshift(0);
}
num = new Buffer(numArray);
}
if (Buffer.isBuffer(num)) {
var size = num.length;
if (num.length === 0)
size++;
var out = new Buffer(size);
num.copy(out);
if (num.length === 0)
out[0] = 0
return this._createEncoderBuffer(out);
}
if (num < 0x80)
return this._createEncoderBuffer(num);
if (num < 0x100)
return this._createEncoderBuffer([0, num]);
var size = 1;
for (var i = num; i >= 0x100; i >>= 8)
size++;
var out = new Array(size);
for (var i = out.length - 1; i >= 0; i--) {
out[i] = num & 0xff;
num >>= 8;
}
if(out[0] & 0x80) {
out.unshift(0);
}
return this._createEncoderBuffer(new Buffer(out));
};
DERNode.prototype._encodeBool = function encodeBool(value) {
return this._createEncoderBuffer(value ? 0xff : 0);
};
DERNode.prototype._use = function use(entity, obj) {
if (typeof entity === 'function')
entity = entity(obj);
return entity._getEncoder('der').tree;
};
DERNode.prototype._skipDefault = function skipDefault(dataBuffer, reporter, parent) {
var state = this._baseState;
var i;
if (state['default'] === null)
return false;
var data = dataBuffer.join();
if (state.defaultBuffer === undefined)
state.defaultBuffer = this._encodeValue(state['default'], reporter, parent).join();
if (data.length !== state.defaultBuffer.length)
return false;
for (i=0; i < data.length; i++)
if (data[i] !== state.defaultBuffer[i])
return false;
return true;
};
// Utility methods
function encodeTag(tag, primitive, cls, reporter) {
var res;
if (tag === 'seqof')
tag = 'seq';
else if (tag === 'setof')
tag = 'set';
if (der.tagByName.hasOwnProperty(tag))
res = der.tagByName[tag];
else if (typeof tag === 'number' && (tag | 0) === tag)
res = tag;
else
return reporter.error('Unknown tag: ' + tag);
if (res >= 0x1f)
return reporter.error('Multi-octet tag encoding unsupported');
if (!primitive)
res |= 0x20;
res |= (der.tagClassByName[cls || 'universal'] << 6);
return res;
}
},{"../../asn1":69,"buffer":2,"inherits":199}],81:[function(require,module,exports){
var encoders = exports;
encoders.der = require('./der');
encoders.pem = require('./pem');
},{"./der":80,"./pem":82}],82:[function(require,module,exports){
var inherits = require('inherits');
var DEREncoder = require('./der');
function PEMEncoder(entity) {
DEREncoder.call(this, entity);
this.enc = 'pem';
};
inherits(PEMEncoder, DEREncoder);
module.exports = PEMEncoder;
PEMEncoder.prototype.encode = function encode(data, options) {
var buf = DEREncoder.prototype.encode.call(this, data);
var p = buf.toString('base64');
var out = [ '-----BEGIN ' + options.label + '-----' ];
for (var i = 0; i < p.length; i += 64)
out.push(p.slice(i, i + 64));
out.push('-----END ' + options.label + '-----');
return out.join('\n');
};
},{"./der":80,"inherits":199}],83:[function(require,module,exports){
arguments[4][34][0].apply(exports,arguments)
},{"dup":34}],84:[function(require,module,exports){
(function (Buffer){
// based on the aes implimentation in triple sec
// https://github.com/keybase/triplesec
// which is in turn based on the one from crypto-js
// https://code.google.com/p/crypto-js/
var uint_max = Math.pow(2, 32)
function fixup_uint32 (x) {
var ret, x_pos
ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x
return ret
}
function scrub_vec (v) {
for (var i = 0; i < v.length; v++) {
v[i] = 0
}
return false
}
function Global () {
this.SBOX = []
this.INV_SBOX = []
this.SUB_MIX = [[], [], [], []]
this.INV_SUB_MIX = [[], [], [], []]
this.init()
this.RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]
}
Global.prototype.init = function () {
var d, i, sx, t, x, x2, x4, x8, xi, _i
d = (function () {
var _i, _results
_results = []
for (i = _i = 0; _i < 256; i = ++_i) {
if (i < 128) {
_results.push(i << 1)
} else {
_results.push((i << 1) ^ 0x11b)
}
}
return _results
})()
x = 0
xi = 0
for (i = _i = 0; _i < 256; i = ++_i) {
sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4)
sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63
this.SBOX[x] = sx
this.INV_SBOX[sx] = x
x2 = d[x]
x4 = d[x2]
x8 = d[x4]
t = (d[sx] * 0x101) ^ (sx * 0x1010100)
this.SUB_MIX[0][x] = (t << 24) | (t >>> 8)
this.SUB_MIX[1][x] = (t << 16) | (t >>> 16)
this.SUB_MIX[2][x] = (t << 8) | (t >>> 24)
this.SUB_MIX[3][x] = t
t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100)
this.INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8)
this.INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16)
this.INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24)
this.INV_SUB_MIX[3][sx] = t
if (x === 0) {
x = xi = 1
} else {
x = x2 ^ d[d[d[x8 ^ x2]]]
xi ^= d[d[xi]]
}
}
return true
}
var G = new Global()
AES.blockSize = 4 * 4
AES.prototype.blockSize = AES.blockSize
AES.keySize = 256 / 8
AES.prototype.keySize = AES.keySize
function bufferToArray (buf) {
var len = buf.length / 4
var out = new Array(len)
var i = -1
while (++i < len) {
out[i] = buf.readUInt32BE(i * 4)
}
return out
}
function AES (key) {
this._key = bufferToArray(key)
this._doReset()
}
AES.prototype._doReset = function () {
var invKsRow, keySize, keyWords, ksRow, ksRows, t
keyWords = this._key
keySize = keyWords.length
this._nRounds = keySize + 6
ksRows = (this._nRounds + 1) * 4
this._keySchedule = []
for (ksRow = 0; ksRow < ksRows; ksRow++) {
this._keySchedule[ksRow] = ksRow < keySize ? keyWords[ksRow] : (t = this._keySchedule[ksRow - 1], (ksRow % keySize) === 0 ? (t = (t << 8) | (t >>> 24), t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff], t ^= G.RCON[(ksRow / keySize) | 0] << 24) : keySize > 6 && ksRow % keySize === 4 ? t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff] : void 0, this._keySchedule[ksRow - keySize] ^ t)
}
this._invKeySchedule = []
for (invKsRow = 0; invKsRow < ksRows; invKsRow++) {
ksRow = ksRows - invKsRow
t = this._keySchedule[ksRow - (invKsRow % 4 ? 0 : 4)]
this._invKeySchedule[invKsRow] = invKsRow < 4 || ksRow <= 4 ? t : G.INV_SUB_MIX[0][G.SBOX[t >>> 24]] ^ G.INV_SUB_MIX[1][G.SBOX[(t >>> 16) & 0xff]] ^ G.INV_SUB_MIX[2][G.SBOX[(t >>> 8) & 0xff]] ^ G.INV_SUB_MIX[3][G.SBOX[t & 0xff]]
}
return true
}
AES.prototype.encryptBlock = function (M) {
M = bufferToArray(new Buffer(M))
var out = this._doCryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX)
var buf = new Buffer(16)
buf.writeUInt32BE(out[0], 0)
buf.writeUInt32BE(out[1], 4)
buf.writeUInt32BE(out[2], 8)
buf.writeUInt32BE(out[3], 12)
return buf
}
AES.prototype.decryptBlock = function (M) {
M = bufferToArray(new Buffer(M))
var temp = [M[3], M[1]]
M[1] = temp[0]
M[3] = temp[1]
var out = this._doCryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX)
var buf = new Buffer(16)
buf.writeUInt32BE(out[0], 0)
buf.writeUInt32BE(out[3], 4)
buf.writeUInt32BE(out[2], 8)
buf.writeUInt32BE(out[1], 12)
return buf
}
AES.prototype.scrub = function () {
scrub_vec(this._keySchedule)
scrub_vec(this._invKeySchedule)
scrub_vec(this._key)
}
AES.prototype._doCryptBlock = function (M, keySchedule, SUB_MIX, SBOX) {
var ksRow, s0, s1, s2, s3, t0, t1, t2, t3
s0 = M[0] ^ keySchedule[0]
s1 = M[1] ^ keySchedule[1]
s2 = M[2] ^ keySchedule[2]
s3 = M[3] ^ keySchedule[3]
ksRow = 4
for (var round = 1; round < this._nRounds; round++) {
t0 = SUB_MIX[0][s0 >>> 24] ^ SUB_MIX[1][(s1 >>> 16) & 0xff] ^ SUB_MIX[2][(s2 >>> 8) & 0xff] ^ SUB_MIX[3][s3 & 0xff] ^ keySchedule[ksRow++]
t1 = SUB_MIX[0][s1 >>> 24] ^ SUB_MIX[1][(s2 >>> 16) & 0xff] ^ SUB_MIX[2][(s3 >>> 8) & 0xff] ^ SUB_MIX[3][s0 & 0xff] ^ keySchedule[ksRow++]
t2 = SUB_MIX[0][s2 >>> 24] ^ SUB_MIX[1][(s3 >>> 16) & 0xff] ^ SUB_MIX[2][(s0 >>> 8) & 0xff] ^ SUB_MIX[3][s1 & 0xff] ^ keySchedule[ksRow++]
t3 = SUB_MIX[0][s3 >>> 24] ^ SUB_MIX[1][(s0 >>> 16) & 0xff] ^ SUB_MIX[2][(s1 >>> 8) & 0xff] ^ SUB_MIX[3][s2 & 0xff] ^ keySchedule[ksRow++]
s0 = t0
s1 = t1
s2 = t2
s3 = t3
}
t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]
t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]
t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]
t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]
return [
fixup_uint32(t0),
fixup_uint32(t1),
fixup_uint32(t2),
fixup_uint32(t3)
]
}
exports.AES = AES
}).call(this,require("buffer").Buffer)
},{"buffer":2}],85:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
var GHASH = require('./ghash')
var xor = require('buffer-xor')
inherits(StreamCipher, Transform)
module.exports = StreamCipher
function StreamCipher (mode, key, iv, decrypt) {
if (!(this instanceof StreamCipher)) {
return new StreamCipher(mode, key, iv)
}
Transform.call(this)
this._finID = Buffer.concat([iv, new Buffer([0, 0, 0, 1])])
iv = Buffer.concat([iv, new Buffer([0, 0, 0, 2])])
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
this._cache = new Buffer('')
this._secCache = new Buffer('')
this._decrypt = decrypt
this._alen = 0
this._len = 0
iv.copy(this._prev)
this._mode = mode
var h = new Buffer(4)
h.fill(0)
this._ghash = new GHASH(this._cipher.encryptBlock(h))
this._authTag = null
this._called = false
}
StreamCipher.prototype._update = function (chunk) {
if (!this._called && this._alen) {
var rump = 16 - (this._alen % 16)
if (rump < 16) {
rump = new Buffer(rump)
rump.fill(0)
this._ghash.update(rump)
}
}
this._called = true
var out = this._mode.encrypt(this, chunk)
if (this._decrypt) {
this._ghash.update(chunk)
} else {
this._ghash.update(out)
}
this._len += chunk.length
return out
}
StreamCipher.prototype._final = function () {
if (this._decrypt && !this._authTag) {
throw new Error('Unsupported state or unable to authenticate data')
}
var tag = xor(this._ghash.final(this._alen * 8, this._len * 8), this._cipher.encryptBlock(this._finID))
if (this._decrypt) {
if (xorTest(tag, this._authTag)) {
throw new Error('Unsupported state or unable to authenticate data')
}
} else {
this._authTag = tag
}
this._cipher.scrub()
}
StreamCipher.prototype.getAuthTag = function getAuthTag () {
if (!this._decrypt && Buffer.isBuffer(this._authTag)) {
return this._authTag
} else {
throw new Error('Attempting to get auth tag in unsupported state')
}
}
StreamCipher.prototype.setAuthTag = function setAuthTag (tag) {
if (this._decrypt) {
this._authTag = tag
} else {
throw new Error('Attempting to set auth tag in unsupported state')
}
}
StreamCipher.prototype.setAAD = function setAAD (buf) {
if (!this._called) {
this._ghash.update(buf)
this._alen += buf.length
} else {
throw new Error('Attempting to set AAD in unsupported state')
}
}
function xorTest (a, b) {
var out = 0
if (a.length !== b.length) {
out++
}
var len = Math.min(a.length, b.length)
var i = -1
while (++i < len) {
out += (a[i] ^ b[i])
}
return out
}
}).call(this,require("buffer").Buffer)
},{"./aes":84,"./ghash":89,"buffer":2,"buffer-xor":98,"cipher-base":99,"inherits":199}],86:[function(require,module,exports){
arguments[4][10][0].apply(exports,arguments)
},{"./decrypter":87,"./encrypter":88,"./modes":90,"dup":10}],87:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
var modes = require('./modes')
var StreamCipher = require('./streamCipher')
var AuthCipher = require('./authCipher')
var ebtk = require('evp_bytestokey')
inherits(Decipher, Transform)
function Decipher (mode, key, iv) {
if (!(this instanceof Decipher)) {
return new Decipher(mode, key, iv)
}
Transform.call(this)
this._cache = new Splitter()
this._last = void 0
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
iv.copy(this._prev)
this._mode = mode
this._autopadding = true
}
Decipher.prototype._update = function (data) {
this._cache.add(data)
var chunk
var thing
var out = []
while ((chunk = this._cache.get(this._autopadding))) {
thing = this._mode.decrypt(this, chunk)
out.push(thing)
}
return Buffer.concat(out)
}
Decipher.prototype._final = function () {
var chunk = this._cache.flush()
if (this._autopadding) {
return unpad(this._mode.decrypt(this, chunk))
} else if (chunk) {
throw new Error('data not multiple of block length')
}
}
Decipher.prototype.setAutoPadding = function (setTo) {
this._autopadding = !!setTo
return this
}
function Splitter () {
if (!(this instanceof Splitter)) {
return new Splitter()
}
this.cache = new Buffer('')
}
Splitter.prototype.add = function (data) {
this.cache = Buffer.concat([this.cache, data])
}
Splitter.prototype.get = function (autoPadding) {
var out
if (autoPadding) {
if (this.cache.length > 16) {
out = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
return out
}
} else {
if (this.cache.length >= 16) {
out = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
return out
}
}
return null
}
Splitter.prototype.flush = function () {
if (this.cache.length) {
return this.cache
}
}
function unpad (last) {
var padded = last[15]
var i = -1
while (++i < padded) {
if (last[(i + (16 - padded))] !== padded) {
throw new Error('unable to decrypt data')
}
}
if (padded === 16) {
return
}
return last.slice(0, 16 - padded)
}
var modelist = {
ECB: require('./modes/ecb'),
CBC: require('./modes/cbc'),
CFB: require('./modes/cfb'),
CFB8: require('./modes/cfb8'),
CFB1: require('./modes/cfb1'),
OFB: require('./modes/ofb'),
CTR: require('./modes/ctr'),
GCM: require('./modes/ctr')
}
function createDecipheriv (suite, password, iv) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
if (typeof iv === 'string') {
iv = new Buffer(iv)
}
if (typeof password === 'string') {
password = new Buffer(password)
}
if (password.length !== config.key / 8) {
throw new TypeError('invalid key length ' + password.length)
}
if (iv.length !== config.iv) {
throw new TypeError('invalid iv length ' + iv.length)
}
if (config.type === 'stream') {
return new StreamCipher(modelist[config.mode], password, iv, true)
} else if (config.type === 'auth') {
return new AuthCipher(modelist[config.mode], password, iv, true)
}
return new Decipher(modelist[config.mode], password, iv)
}
function createDecipher (suite, password) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
var keys = ebtk(password, false, config.key, config.iv)
return createDecipheriv(suite, keys.key, keys.iv)
}
exports.createDecipher = createDecipher
exports.createDecipheriv = createDecipheriv
}).call(this,require("buffer").Buffer)
},{"./aes":84,"./authCipher":85,"./modes":90,"./modes/cbc":91,"./modes/cfb":92,"./modes/cfb1":93,"./modes/cfb8":94,"./modes/ctr":95,"./modes/ecb":96,"./modes/ofb":97,"./streamCipher":100,"buffer":2,"cipher-base":99,"evp_bytestokey":101,"inherits":199}],88:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
var modes = require('./modes')
var ebtk = require('evp_bytestokey')
var StreamCipher = require('./streamCipher')
var AuthCipher = require('./authCipher')
inherits(Cipher, Transform)
function Cipher (mode, key, iv) {
if (!(this instanceof Cipher)) {
return new Cipher(mode, key, iv)
}
Transform.call(this)
this._cache = new Splitter()
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
iv.copy(this._prev)
this._mode = mode
this._autopadding = true
}
Cipher.prototype._update = function (data) {
this._cache.add(data)
var chunk
var thing
var out = []
while ((chunk = this._cache.get())) {
thing = this._mode.encrypt(this, chunk)
out.push(thing)
}
return Buffer.concat(out)
}
Cipher.prototype._final = function () {
var chunk = this._cache.flush()
if (this._autopadding) {
chunk = this._mode.encrypt(this, chunk)
this._cipher.scrub()
return chunk
} else if (chunk.toString('hex') !== '10101010101010101010101010101010') {
this._cipher.scrub()
throw new Error('data not multiple of block length')
}
}
Cipher.prototype.setAutoPadding = function (setTo) {
this._autopadding = !!setTo
return this
}
function Splitter () {
if (!(this instanceof Splitter)) {
return new Splitter()
}
this.cache = new Buffer('')
}
Splitter.prototype.add = function (data) {
this.cache = Buffer.concat([this.cache, data])
}
Splitter.prototype.get = function () {
if (this.cache.length > 15) {
var out = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
return out
}
return null
}
Splitter.prototype.flush = function () {
var len = 16 - this.cache.length
var padBuff = new Buffer(len)
var i = -1
while (++i < len) {
padBuff.writeUInt8(len, i)
}
var out = Buffer.concat([this.cache, padBuff])
return out
}
var modelist = {
ECB: require('./modes/ecb'),
CBC: require('./modes/cbc'),
CFB: require('./modes/cfb'),
CFB8: require('./modes/cfb8'),
CFB1: require('./modes/cfb1'),
OFB: require('./modes/ofb'),
CTR: require('./modes/ctr'),
GCM: require('./modes/ctr')
}
function createCipheriv (suite, password, iv) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
if (typeof iv === 'string') {
iv = new Buffer(iv)
}
if (typeof password === 'string') {
password = new Buffer(password)
}
if (password.length !== config.key / 8) {
throw new TypeError('invalid key length ' + password.length)
}
if (iv.length !== config.iv) {
throw new TypeError('invalid iv length ' + iv.length)
}
if (config.type === 'stream') {
return new StreamCipher(modelist[config.mode], password, iv)
} else if (config.type === 'auth') {
return new AuthCipher(modelist[config.mode], password, iv)
}
return new Cipher(modelist[config.mode], password, iv)
}
function createCipher (suite, password) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
var keys = ebtk(password, false, config.key, config.iv)
return createCipheriv(suite, keys.key, keys.iv)
}
exports.createCipheriv = createCipheriv
exports.createCipher = createCipher
}).call(this,require("buffer").Buffer)
},{"./aes":84,"./authCipher":85,"./modes":90,"./modes/cbc":91,"./modes/cfb":92,"./modes/cfb1":93,"./modes/cfb8":94,"./modes/ctr":95,"./modes/ecb":96,"./modes/ofb":97,"./streamCipher":100,"buffer":2,"cipher-base":99,"evp_bytestokey":101,"inherits":199}],89:[function(require,module,exports){
(function (Buffer){
var zeros = new Buffer(16)
zeros.fill(0)
module.exports = GHASH
function GHASH (key) {
this.h = key
this.state = new Buffer(16)
this.state.fill(0)
this.cache = new Buffer('')
}
// from http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_gcm.js.html
// by Juho Vähä-Herttua
GHASH.prototype.ghash = function (block) {
var i = -1
while (++i < block.length) {
this.state[i] ^= block[i]
}
this._multiply()
}
GHASH.prototype._multiply = function () {
var Vi = toArray(this.h)
var Zi = [0, 0, 0, 0]
var j, xi, lsb_Vi
var i = -1
while (++i < 128) {
xi = (this.state[~~(i / 8)] & (1 << (7 - i % 8))) !== 0
if (xi) {
// Z_i+1 = Z_i ^ V_i
Zi = xor(Zi, Vi)
}
// Store the value of LSB(V_i)
lsb_Vi = (Vi[3] & 1) !== 0
// V_i+1 = V_i >> 1
for (j = 3; j > 0; j--) {
Vi[j] = (Vi[j] >>> 1) | ((Vi[j - 1] & 1) << 31)
}
Vi[0] = Vi[0] >>> 1
// If LSB(V_i) is 1, V_i+1 = (V_i >> 1) ^ R
if (lsb_Vi) {
Vi[0] = Vi[0] ^ (0xe1 << 24)
}
}
this.state = fromArray(Zi)
}
GHASH.prototype.update = function (buf) {
this.cache = Buffer.concat([this.cache, buf])
var chunk
while (this.cache.length >= 16) {
chunk = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
this.ghash(chunk)
}
}
GHASH.prototype.final = function (abl, bl) {
if (this.cache.length) {
this.ghash(Buffer.concat([this.cache, zeros], 16))
}
this.ghash(fromArray([
0, abl,
0, bl
]))
return this.state
}
function toArray (buf) {
return [
buf.readUInt32BE(0),
buf.readUInt32BE(4),
buf.readUInt32BE(8),
buf.readUInt32BE(12)
]
}
function fromArray (out) {
out = out.map(fixup_uint32)
var buf = new Buffer(16)
buf.writeUInt32BE(out[0], 0)
buf.writeUInt32BE(out[1], 4)
buf.writeUInt32BE(out[2], 8)
buf.writeUInt32BE(out[3], 12)
return buf
}
var uint_max = Math.pow(2, 32)
function fixup_uint32 (x) {
var ret, x_pos
ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x
return ret
}
function xor (a, b) {
return [
a[0] ^ b[0],
a[1] ^ b[1],
a[2] ^ b[2],
a[3] ^ b[3]
]
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],90:[function(require,module,exports){
arguments[4][14][0].apply(exports,arguments)
},{"dup":14}],91:[function(require,module,exports){
arguments[4][15][0].apply(exports,arguments)
},{"buffer-xor":98,"dup":15}],92:[function(require,module,exports){
(function (Buffer){
var xor = require('buffer-xor')
exports.encrypt = function (self, data, decrypt) {
var out = new Buffer('')
var len
while (data.length) {
if (self._cache.length === 0) {
self._cache = self._cipher.encryptBlock(self._prev)
self._prev = new Buffer('')
}
if (self._cache.length <= data.length) {
len = self._cache.length
out = Buffer.concat([out, encryptStart(self, data.slice(0, len), decrypt)])
data = data.slice(len)
} else {
out = Buffer.concat([out, encryptStart(self, data, decrypt)])
break
}
}
return out
}
function encryptStart (self, data, decrypt) {
var len = data.length
var out = xor(data, self._cache)
self._cache = self._cache.slice(len)
self._prev = Buffer.concat([self._prev, decrypt ? data : out])
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"buffer-xor":98}],93:[function(require,module,exports){
(function (Buffer){
function encryptByte (self, byteParam, decrypt) {
var pad
var i = -1
var len = 8
var out = 0
var bit, value
while (++i < len) {
pad = self._cipher.encryptBlock(self._prev)
bit = (byteParam & (1 << (7 - i))) ? 0x80 : 0
value = pad[0] ^ bit
out += ((value & 0x80) >> (i % 8))
self._prev = shiftIn(self._prev, decrypt ? bit : value)
}
return out
}
exports.encrypt = function (self, chunk, decrypt) {
var len = chunk.length
var out = new Buffer(len)
var i = -1
while (++i < len) {
out[i] = encryptByte(self, chunk[i], decrypt)
}
return out
}
function shiftIn (buffer, value) {
var len = buffer.length
var i = -1
var out = new Buffer(buffer.length)
buffer = Buffer.concat([buffer, new Buffer([value])])
while (++i < len) {
out[i] = buffer[i] << 1 | buffer[i + 1] >> (7)
}
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],94:[function(require,module,exports){
(function (Buffer){
function encryptByte (self, byteParam, decrypt) {
var pad = self._cipher.encryptBlock(self._prev)
var out = pad[0] ^ byteParam
self._prev = Buffer.concat([self._prev.slice(1), new Buffer([decrypt ? byteParam : out])])
return out
}
exports.encrypt = function (self, chunk, decrypt) {
var len = chunk.length
var out = new Buffer(len)
var i = -1
while (++i < len) {
out[i] = encryptByte(self, chunk[i], decrypt)
}
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],95:[function(require,module,exports){
(function (Buffer){
var xor = require('buffer-xor')
function incr32 (iv) {
var len = iv.length
var item
while (len--) {
item = iv.readUInt8(len)
if (item === 255) {
iv.writeUInt8(0, len)
} else {
item++
iv.writeUInt8(item, len)
break
}
}
}
function getBlock (self) {
var out = self._cipher.encryptBlock(self._prev)
incr32(self._prev)
return out
}
exports.encrypt = function (self, chunk) {
while (self._cache.length < chunk.length) {
self._cache = Buffer.concat([self._cache, getBlock(self)])
}
var pad = self._cache.slice(0, chunk.length)
self._cache = self._cache.slice(chunk.length)
return xor(chunk, pad)
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"buffer-xor":98}],96:[function(require,module,exports){
arguments[4][20][0].apply(exports,arguments)
},{"dup":20}],97:[function(require,module,exports){
(function (Buffer){
var xor = require('buffer-xor')
function getBlock (self) {
self._prev = self._cipher.encryptBlock(self._prev)
return self._prev
}
exports.encrypt = function (self, chunk) {
while (self._cache.length < chunk.length) {
self._cache = Buffer.concat([self._cache, getBlock(self)])
}
var pad = self._cache.slice(0, chunk.length)
self._cache = self._cache.slice(chunk.length)
return xor(chunk, pad)
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"buffer-xor":98}],98:[function(require,module,exports){
(function (Buffer){
module.exports = function xor (a, b) {
var length = Math.min(a.length, b.length)
var buffer = new Buffer(length)
for (var i = 0; i < length; ++i) {
buffer[i] = a[i] ^ b[i]
}
return buffer
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],99:[function(require,module,exports){
(function (Buffer){
var Transform = require('stream').Transform
var inherits = require('inherits')
var StringDecoder = require('string_decoder').StringDecoder
module.exports = CipherBase
inherits(CipherBase, Transform)
function CipherBase (hashMode) {
Transform.call(this)
this.hashMode = typeof hashMode === 'string'
if (this.hashMode) {
this[hashMode] = this._finalOrDigest
} else {
this.final = this._finalOrDigest
}
this._decoder = null
this._encoding = null
}
CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
if (typeof data === 'string') {
data = new Buffer(data, inputEnc)
}
var outData = this._update(data)
if (this.hashMode) {
return this
}
if (outputEnc) {
outData = this._toString(outData, outputEnc)
}
return outData
}
CipherBase.prototype.setAutoPadding = function () {}
CipherBase.prototype.getAuthTag = function () {
throw new Error('trying to get auth tag in unsupported state')
}
CipherBase.prototype.setAuthTag = function () {
throw new Error('trying to set auth tag in unsupported state')
}
CipherBase.prototype.setAAD = function () {
throw new Error('trying to set aad in unsupported state')
}
CipherBase.prototype._transform = function (data, _, next) {
var err
try {
if (this.hashMode) {
this._update(data)
} else {
this.push(this._update(data))
}
} catch (e) {
err = e
} finally {
next(err)
}
}
CipherBase.prototype._flush = function (done) {
var err
try {
this.push(this._final())
} catch (e) {
err = e
} finally {
done(err)
}
}
CipherBase.prototype._finalOrDigest = function (outputEnc) {
var outData = this._final() || new Buffer('')
if (outputEnc) {
outData = this._toString(outData, outputEnc, true)
}
return outData
}
CipherBase.prototype._toString = function (value, enc, final) {
if (!this._decoder) {
this._decoder = new StringDecoder(enc)
this._encoding = enc
}
if (this._encoding !== enc) {
throw new Error('can\'t switch encodings')
}
var out = this._decoder.write(value)
if (final) {
out += this._decoder.end()
}
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"inherits":199,"stream":216,"string_decoder":217}],100:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
inherits(StreamCipher, Transform)
module.exports = StreamCipher
function StreamCipher (mode, key, iv, decrypt) {
if (!(this instanceof StreamCipher)) {
return new StreamCipher(mode, key, iv)
}
Transform.call(this)
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
this._cache = new Buffer('')
this._secCache = new Buffer('')
this._decrypt = decrypt
iv.copy(this._prev)
this._mode = mode
}
StreamCipher.prototype._update = function (chunk) {
return this._mode.encrypt(this, chunk, this._decrypt)
}
StreamCipher.prototype._final = function () {
this._cipher.scrub()
}
}).call(this,require("buffer").Buffer)
},{"./aes":84,"buffer":2,"cipher-base":99,"inherits":199}],101:[function(require,module,exports){
(function (Buffer){
var md5 = require('create-hash/md5')
module.exports = EVP_BytesToKey
function EVP_BytesToKey (password, salt, keyLen, ivLen) {
if (!Buffer.isBuffer(password)) {
password = new Buffer(password, 'binary')
}
if (salt && !Buffer.isBuffer(salt)) {
salt = new Buffer(salt, 'binary')
}
keyLen = keyLen / 8
ivLen = ivLen || 0
var ki = 0
var ii = 0
var key = new Buffer(keyLen)
var iv = new Buffer(ivLen)
var addmd = 0
var md_buf
var i
var bufs = []
while (true) {
if (addmd++ > 0) {
bufs.push(md_buf)
}
bufs.push(password)
if (salt) {
bufs.push(salt)
}
md_buf = md5(Buffer.concat(bufs))
bufs = []
i = 0
if (keyLen > 0) {
while (true) {
if (keyLen === 0) {
break
}
if (i === md_buf.length) {
break
}
key[ki++] = md_buf[i]
keyLen--
i++
}
}
if (ivLen > 0 && i !== md_buf.length) {
while (true) {
if (ivLen === 0) {
break
}
if (i === md_buf.length) {
break
}
iv[ii++] = md_buf[i]
ivLen--
i++
}
}
if (keyLen === 0 && ivLen === 0) {
break
}
}
for (i = 0; i < md_buf.length; i++) {
md_buf[i] = 0
}
return {
key: key,
iv: iv
}
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"create-hash/md5":132}],102:[function(require,module,exports){
(function (Buffer){
// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js
var createHmac = require('create-hmac')
var crt = require('browserify-rsa')
var curves = require('./curves')
var elliptic = require('elliptic')
var parseKeys = require('parse-asn1')
var BN = require('bn.js')
var EC = elliptic.ec
function sign (hash, key, hashType, signType) {
var priv = parseKeys(key)
if (priv.curve) {
if (signType !== 'ecdsa') throw new Error('wrong private key type')
return ecSign(hash, priv)
} else if (priv.type === 'dsa') {
if (signType !== 'dsa') {
throw new Error('wrong private key type')
}
return dsaSign(hash, priv, hashType)
} else {
if (signType !== 'rsa') throw new Error('wrong private key type')
}
var len = priv.modulus.byteLength()
var pad = [ 0, 1 ]
while (hash.length + pad.length + 1 < len) {
pad.push(0xff)
}
pad.push(0x00)
var i = -1
while (++i < hash.length) {
pad.push(hash[i])
}
var out = crt(pad, priv)
return out
}
function ecSign (hash, priv) {
var curveId = curves[priv.curve.join('.')]
if (!curveId) throw new Error('unknown curve ' + priv.curve.join('.'))
var curve = new EC(curveId)
var key = curve.genKeyPair()
key._importPrivate(priv.privateKey)
var out = key.sign(hash)
return new Buffer(out.toDER())
}
function dsaSign (hash, priv, algo) {
var x = priv.params.priv_key
var p = priv.params.p
var q = priv.params.q
var g = priv.params.g
var r = new BN(0)
var k
var H = bits2int(hash, q).mod(q)
var s = false
var kv = getKey(x, q, hash, algo)
while (s === false) {
k = makeKey(q, kv, algo)
r = makeR(g, k, p, q)
s = k.invm(q).imul(H.add(x.mul(r))).mod(q)
if (!s.cmpn(0)) {
s = false
r = new BN(0)
}
}
return toDER(r, s)
}
function toDER (r, s) {
r = r.toArray()
s = s.toArray()
// Pad values
if (r[0] & 0x80) {
r = [ 0 ].concat(r)
}
// Pad values
if (s[0] & 0x80) {
s = [0].concat(s)
}
var total = r.length + s.length + 4
var res = [ 0x30, total, 0x02, r.length ]
res = res.concat(r, [ 0x02, s.length ], s)
return new Buffer(res)
}
function getKey (x, q, hash, algo) {
x = new Buffer(x.toArray())
if (x.length < q.byteLength()) {
var zeros = new Buffer(q.byteLength() - x.length)
zeros.fill(0)
x = Buffer.concat([zeros, x])
}
var hlen = hash.length
var hbits = bits2octets(hash, q)
var v = new Buffer(hlen)
v.fill(1)
var k = new Buffer(hlen)
k.fill(0)
k = createHmac(algo, k)
.update(v)
.update(new Buffer([0]))
.update(x)
.update(hbits)
.digest()
v = createHmac(algo, k)
.update(v)
.digest()
k = createHmac(algo, k)
.update(v)
.update(new Buffer([1]))
.update(x)
.update(hbits)
.digest()
v = createHmac(algo, k)
.update(v)
.digest()
return {
k: k,
v: v
}
}
function bits2int (obits, q) {
var bits = new BN(obits)
var shift = (obits.length << 3) - q.bitLength()
if (shift > 0) {
bits.ishrn(shift)
}
return bits
}
function bits2octets (bits, q) {
bits = bits2int(bits, q)
bits = bits.mod(q)
var out = new Buffer(bits.toArray())
if (out.length < q.byteLength()) {
var zeros = new Buffer(q.byteLength() - out.length)
zeros.fill(0)
out = Buffer.concat([zeros, out])
}
return out
}
function makeKey (q, kv, algo) {
var t, k
do {
t = new Buffer('')
while (t.length * 8 < q.bitLength()) {
kv.v = createHmac(algo, kv.k)
.update(kv.v)
.digest()
t = Buffer.concat([t, kv.v])
}
k = bits2int(t, q)
kv.k = createHmac(algo, kv.k)
.update(kv.v)
.update(new Buffer([0]))
.digest()
kv.v = createHmac(algo, kv.k)
.update(kv.v)
.digest()
} while (k.cmp(q) !== -1)
return k
}
function makeR (g, k, p, q) {
return g.toRed(BN.mont(p)).redPow(k).fromRed().mod(q)
}
module.exports = sign
module.exports.getKey = getKey
module.exports.makeKey = makeKey
}).call(this,require("buffer").Buffer)
},{"./curves":38,"bn.js":39,"browserify-rsa":40,"buffer":2,"create-hmac":143,"elliptic":41,"parse-asn1":68}],103:[function(require,module,exports){
(function (Buffer){
// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js
var curves = require('./curves')
var elliptic = require('elliptic')
var parseKeys = require('parse-asn1')
var BN = require('bn.js')
var EC = elliptic.ec
function verify (sig, hash, key, signType) {
var pub = parseKeys(key)
if (pub.type === 'ec') {
if (signType !== 'ecdsa') {
throw new Error('wrong public key type')
}
return ecVerify(sig, hash, pub)
} else if (pub.type === 'dsa') {
if (signType !== 'dsa') {
throw new Error('wrong public key type')
}
return dsaVerify(sig, hash, pub)
} else {
if (signType !== 'rsa') {
throw new Error('wrong public key type')
}
}
var len = pub.modulus.byteLength()
var pad = [ 1 ]
var padNum = 0
while (hash.length + pad.length + 2 < len) {
pad.push(0xff)
padNum++
}
pad.push(0x00)
var i = -1
while (++i < hash.length) {
pad.push(hash[i])
}
pad = new Buffer(pad)
var red = BN.mont(pub.modulus)
sig = new BN(sig).toRed(red)
sig = sig.redPow(new BN(pub.publicExponent))
sig = new Buffer(sig.fromRed().toArray())
var out = 0
if (padNum < 8) {
out = 1
}
len = Math.min(sig.length, pad.length)
if (sig.length !== pad.length) {
out = 1
}
i = -1
while (++i < len) {
out |= (sig[i] ^ pad[i])
}
return out === 0
}
function ecVerify (sig, hash, pub) {
var curveId = curves[pub.data.algorithm.curve.join('.')]
if (!curveId) throw new Error('unknown curve ' + pub.data.algorithm.curve.join('.'))
var curve = new EC(curveId)
var pubkey = pub.data.subjectPrivateKey.data
return curve.verify(hash, sig, pubkey)
}
function dsaVerify (sig, hash, pub) {
var p = pub.data.p
var q = pub.data.q
var g = pub.data.g
var y = pub.data.pub_key
var unpacked = parseKeys.signature.decode(sig, 'der')
var s = unpacked.s
var r = unpacked.r
checkValue(s, q)
checkValue(r, q)
var montp = BN.mont(p)
var w = s.invm(q)
var v = g.toRed(montp)
.redPow(new BN(hash).mul(w).mod(q))
.fromRed()
.mul(
y.toRed(montp)
.redPow(r.mul(w).mod(q))
.fromRed()
).mod(p).mod(q)
return !v.cmp(r)
}
function checkValue (b, q) {
if (b.cmpn(0) <= 0) {
throw new Error('invalid sig')
}
if (b.cmp(q) >= q) {
throw new Error('invalid sig')
}
}
module.exports = verify
}).call(this,require("buffer").Buffer)
},{"./curves":38,"bn.js":39,"buffer":2,"elliptic":41,"parse-asn1":68}],104:[function(require,module,exports){
(function (Buffer){
var elliptic = require('elliptic');
var BN = require('bn.js');
module.exports = function createECDH(curve) {
return new ECDH(curve);
};
var aliases = {
secp256k1: {
name: 'secp256k1',
byteLength: 32
},
secp224r1: {
name: 'p224',
byteLength: 28
},
prime256v1: {
name: 'p256',
byteLength: 32
},
prime192v1: {
name: 'p192',
byteLength: 24
},
ed25519: {
name: 'ed25519',
byteLength: 32
},
secp384r1: {
name: 'p384',
byteLength: 48
},
secp521r1: {
name: 'p521',
byteLength: 66
}
};
aliases.p224 = aliases.secp224r1;
aliases.p256 = aliases.secp256r1 = aliases.prime256v1;
aliases.p192 = aliases.secp192r1 = aliases.prime192v1;
aliases.p384 = aliases.secp384r1;
aliases.p521 = aliases.secp521r1;
function ECDH(curve) {
this.curveType = aliases[curve];
if (!this.curveType ) {
this.curveType = {
name: curve
};
}
this.curve = new elliptic.ec(this.curveType.name);
this.keys = void 0;
}
ECDH.prototype.generateKeys = function (enc, format) {
this.keys = this.curve.genKeyPair();
return this.getPublicKey(enc, format);
};
ECDH.prototype.computeSecret = function (other, inenc, enc) {
inenc = inenc || 'utf8';
if (!Buffer.isBuffer(other)) {
other = new Buffer(other, inenc);
}
var otherPub = this.curve.keyFromPublic(other).getPublic();
var out = otherPub.mul(this.keys.getPrivate()).getX();
return formatReturnValue(out, enc, this.curveType.byteLength);
};
ECDH.prototype.getPublicKey = function (enc, format) {
var key = this.keys.getPublic(format === 'compressed', true);
if (format === 'hybrid') {
if (key[key.length - 1] % 2) {
key[0] = 7;
} else {
key [0] = 6;
}
}
return formatReturnValue(key, enc);
};
ECDH.prototype.getPrivateKey = function (enc) {
return formatReturnValue(this.keys.getPrivate(), enc);
};
ECDH.prototype.setPublicKey = function (pub, enc) {
enc = enc || 'utf8';
if (!Buffer.isBuffer(pub)) {
pub = new Buffer(pub, enc);
}
this.keys._importPublic(pub);
return this;
};
ECDH.prototype.setPrivateKey = function (priv, enc) {
enc = enc || 'utf8';
if (!Buffer.isBuffer(priv)) {
priv = new Buffer(priv, enc);
}
var _priv = new BN(priv);
_priv = _priv.toString(16);
this.keys._importPrivate(_priv);
return this;
};
function formatReturnValue(bn, enc, len) {
if (!Array.isArray(bn)) {
bn = bn.toArray();
}
var buf = new Buffer(bn);
if (len && buf.length < len) {
var zeros = new Buffer(len - buf.length);
zeros.fill(0);
buf = Buffer.concat([zeros, buf]);
}
if (!enc) {
return buf;
} else {
return buf.toString(enc);
}
}
}).call(this,require("buffer").Buffer)
},{"bn.js":105,"buffer":2,"elliptic":106}],105:[function(require,module,exports){
arguments[4][39][0].apply(exports,arguments)
},{"dup":39}],106:[function(require,module,exports){
arguments[4][41][0].apply(exports,arguments)
},{"../package.json":129,"./elliptic/curve":109,"./elliptic/curves":112,"./elliptic/ec":113,"./elliptic/eddsa":116,"./elliptic/hmac-drbg":119,"./elliptic/utils":121,"brorand":122,"dup":41}],107:[function(require,module,exports){
arguments[4][42][0].apply(exports,arguments)
},{"../../elliptic":106,"bn.js":105,"dup":42}],108:[function(require,module,exports){
arguments[4][43][0].apply(exports,arguments)
},{"../../elliptic":106,"../curve":109,"bn.js":105,"dup":43,"inherits":199}],109:[function(require,module,exports){
arguments[4][44][0].apply(exports,arguments)
},{"./base":107,"./edwards":108,"./mont":110,"./short":111,"dup":44}],110:[function(require,module,exports){
arguments[4][45][0].apply(exports,arguments)
},{"../../elliptic":106,"../curve":109,"bn.js":105,"dup":45,"inherits":199}],111:[function(require,module,exports){
arguments[4][46][0].apply(exports,arguments)
},{"../../elliptic":106,"../curve":109,"bn.js":105,"dup":46,"inherits":199}],112:[function(require,module,exports){
arguments[4][47][0].apply(exports,arguments)
},{"../elliptic":106,"./precomputed/secp256k1":120,"dup":47,"hash.js":123}],113:[function(require,module,exports){
arguments[4][48][0].apply(exports,arguments)
},{"../../elliptic":106,"./key":114,"./signature":115,"bn.js":105,"dup":48}],114:[function(require,module,exports){
arguments[4][49][0].apply(exports,arguments)
},{"bn.js":105,"dup":49}],115:[function(require,module,exports){
arguments[4][50][0].apply(exports,arguments)
},{"../../elliptic":106,"bn.js":105,"dup":50}],116:[function(require,module,exports){
arguments[4][51][0].apply(exports,arguments)
},{"../../elliptic":106,"./key":117,"./signature":118,"dup":51,"hash.js":123}],117:[function(require,module,exports){
arguments[4][52][0].apply(exports,arguments)
},{"../../elliptic":106,"dup":52}],118:[function(require,module,exports){
arguments[4][53][0].apply(exports,arguments)
},{"../../elliptic":106,"bn.js":105,"dup":53}],119:[function(require,module,exports){
arguments[4][54][0].apply(exports,arguments)
},{"../elliptic":106,"dup":54,"hash.js":123}],120:[function(require,module,exports){
arguments[4][55][0].apply(exports,arguments)
},{"dup":55}],121:[function(require,module,exports){
arguments[4][56][0].apply(exports,arguments)
},{"bn.js":105,"dup":56}],122:[function(require,module,exports){
arguments[4][57][0].apply(exports,arguments)
},{"dup":57}],123:[function(require,module,exports){
arguments[4][58][0].apply(exports,arguments)
},{"./hash/common":124,"./hash/hmac":125,"./hash/ripemd":126,"./hash/sha":127,"./hash/utils":128,"dup":58}],124:[function(require,module,exports){
arguments[4][59][0].apply(exports,arguments)
},{"../hash":123,"dup":59}],125:[function(require,module,exports){
arguments[4][60][0].apply(exports,arguments)
},{"../hash":123,"dup":60}],126:[function(require,module,exports){
arguments[4][61][0].apply(exports,arguments)
},{"../hash":123,"dup":61}],127:[function(require,module,exports){
arguments[4][62][0].apply(exports,arguments)
},{"../hash":123,"dup":62}],128:[function(require,module,exports){
arguments[4][63][0].apply(exports,arguments)
},{"dup":63,"inherits":199}],129:[function(require,module,exports){
arguments[4][64][0].apply(exports,arguments)
},{"dup":64}],130:[function(require,module,exports){
(function (Buffer){
'use strict';
var inherits = require('inherits')
var md5 = require('./md5')
var rmd160 = require('ripemd160')
var sha = require('sha.js')
var Base = require('cipher-base')
function HashNoConstructor(hash) {
Base.call(this, 'digest')
this._hash = hash
this.buffers = []
}
inherits(HashNoConstructor, Base)
HashNoConstructor.prototype._update = function (data) {
this.buffers.push(data)
}
HashNoConstructor.prototype._final = function () {
var buf = Buffer.concat(this.buffers)
var r = this._hash(buf)
this.buffers = null
return r
}
function Hash(hash) {
Base.call(this, 'digest')
this._hash = hash
}
inherits(Hash, Base)
Hash.prototype._update = function (data) {
this._hash.update(data)
}
Hash.prototype._final = function () {
return this._hash.digest()
}
module.exports = function createHash (alg) {
alg = alg.toLowerCase()
if ('md5' === alg) return new HashNoConstructor(md5)
if ('rmd160' === alg || 'ripemd160' === alg) return new HashNoConstructor(rmd160)
return new Hash(sha(alg))
}
}).call(this,require("buffer").Buffer)
},{"./md5":132,"buffer":2,"cipher-base":133,"inherits":199,"ripemd160":134,"sha.js":136}],131:[function(require,module,exports){
(function (Buffer){
'use strict';
var intSize = 4;
var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0);
var chrsz = 8;
function toArray(buf, bigEndian) {
if ((buf.length % intSize) !== 0) {
var len = buf.length + (intSize - (buf.length % intSize));
buf = Buffer.concat([buf, zeroBuffer], len);
}
var arr = [];
var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE;
for (var i = 0; i < buf.length; i += intSize) {
arr.push(fn.call(buf, i));
}
return arr;
}
function toBuffer(arr, size, bigEndian) {
var buf = new Buffer(size);
var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE;
for (var i = 0; i < arr.length; i++) {
fn.call(buf, arr[i], i * 4, true);
}
return buf;
}
function hash(buf, fn, hashSize, bigEndian) {
if (!Buffer.isBuffer(buf)) buf = new Buffer(buf);
var arr = fn(toArray(buf, bigEndian), buf.length * chrsz);
return toBuffer(arr, hashSize, bigEndian);
}
exports.hash = hash;
}).call(this,require("buffer").Buffer)
},{"buffer":2}],132:[function(require,module,exports){
'use strict';
/*
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
var helpers = require('./helpers');
/*
* Calculate the MD5 of an array of little-endian words, and a bit length
*/
function core_md5(x, len)
{
/* append padding */
x[len >> 5] |= 0x80 << ((len) % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
for(var i = 0; i < x.length; i += 16)
{
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
}
return Array(a, b, c, d);
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
function md5_cmn(q, a, b, x, s, t)
{
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function bit_rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}
module.exports = function md5(buf) {
return helpers.hash(buf, core_md5, 16);
};
},{"./helpers":131}],133:[function(require,module,exports){
(function (Buffer){
var Transform = require('stream').Transform
var inherits = require('inherits')
var StringDecoder = require('string_decoder').StringDecoder
module.exports = CipherBase
inherits(CipherBase, Transform)
function CipherBase (hashMode) {
Transform.call(this)
this.hashMode = typeof hashMode === 'string'
if (this.hashMode) {
this[hashMode] = this._finalOrDigest
} else {
this.final = this._finalOrDigest
}
this._decoder = null
this._encoding = null
}
CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
if (typeof data === 'string') {
data = new Buffer(data, inputEnc)
}
var outData = this._update(data)
if (this.hashMode) {
return this
}
if (outputEnc) {
outData = this._toString(outData, outputEnc)
}
return outData
}
CipherBase.prototype.setAutoPadding = function () {}
CipherBase.prototype.getAuthTag = function () {
throw new Error('trying to get auth tag in unsupported state')
}
CipherBase.prototype.setAuthTag = function () {
throw new Error('trying to set auth tag in unsupported state')
}
CipherBase.prototype.setAAD = function () {
throw new Error('trying to set aad in unsupported state')
}
CipherBase.prototype._transform = function (data, _, next) {
var err
try {
if (this.hashMode) {
this._update(data)
} else {
this.push(this._update(data))
}
} catch (e) {
err = e
} finally {
next(err)
}
}
CipherBase.prototype._flush = function (done) {
var err
try {
this.push(this._final())
} catch (e) {
err = e
} finally {
done(err)
}
}
CipherBase.prototype._finalOrDigest = function (outputEnc) {
var outData = this._final() || new Buffer('')
if (outputEnc) {
outData = this._toString(outData, outputEnc, true)
}
return outData
}
CipherBase.prototype._toString = function (value, enc, final) {
if (!this._decoder) {
this._decoder = new StringDecoder(enc)
this._encoding = enc
}
if (this._encoding !== enc) {
throw new Error('can\'t switch encodings')
}
var out = this._decoder.write(value)
if (final) {
out += this._decoder.end()
}
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"inherits":199,"stream":216,"string_decoder":217}],134:[function(require,module,exports){
(function (Buffer){
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
/** @preserve
(c) 2012 by Cédric Mesnil. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// constants table
var zl = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
]
var zr = [
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
]
var sl = [
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
]
var sr = [
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
]
var hl = [0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]
var hr = [0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000]
function bytesToWords (bytes) {
var words = []
for (var i = 0, b = 0; i < bytes.length; i++, b += 8) {
words[b >>> 5] |= bytes[i] << (24 - b % 32)
}
return words
}
function wordsToBytes (words) {
var bytes = []
for (var b = 0; b < words.length * 32; b += 8) {
bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF)
}
return bytes
}
function processBlock (H, M, offset) {
// swap endian
for (var i = 0; i < 16; i++) {
var offset_i = offset + i
var M_offset_i = M[offset_i]
// Swap
M[offset_i] = (
(((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
(((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
)
}
// Working variables
var al, bl, cl, dl, el
var ar, br, cr, dr, er
ar = al = H[0]
br = bl = H[1]
cr = cl = H[2]
dr = dl = H[3]
er = el = H[4]
// computation
var t
for (i = 0; i < 80; i += 1) {
t = (al + M[offset + zl[i]]) | 0
if (i < 16) {
t += f1(bl, cl, dl) + hl[0]
} else if (i < 32) {
t += f2(bl, cl, dl) + hl[1]
} else if (i < 48) {
t += f3(bl, cl, dl) + hl[2]
} else if (i < 64) {
t += f4(bl, cl, dl) + hl[3]
} else {// if (i<80) {
t += f5(bl, cl, dl) + hl[4]
}
t = t | 0
t = rotl(t, sl[i])
t = (t + el) | 0
al = el
el = dl
dl = rotl(cl, 10)
cl = bl
bl = t
t = (ar + M[offset + zr[i]]) | 0
if (i < 16) {
t += f5(br, cr, dr) + hr[0]
} else if (i < 32) {
t += f4(br, cr, dr) + hr[1]
} else if (i < 48) {
t += f3(br, cr, dr) + hr[2]
} else if (i < 64) {
t += f2(br, cr, dr) + hr[3]
} else {// if (i<80) {
t += f1(br, cr, dr) + hr[4]
}
t = t | 0
t = rotl(t, sr[i])
t = (t + er) | 0
ar = er
er = dr
dr = rotl(cr, 10)
cr = br
br = t
}
// intermediate hash value
t = (H[1] + cl + dr) | 0
H[1] = (H[2] + dl + er) | 0
H[2] = (H[3] + el + ar) | 0
H[3] = (H[4] + al + br) | 0
H[4] = (H[0] + bl + cr) | 0
H[0] = t
}
function f1 (x, y, z) {
return ((x) ^ (y) ^ (z))
}
function f2 (x, y, z) {
return (((x) & (y)) | ((~x) & (z)))
}
function f3 (x, y, z) {
return (((x) | (~(y))) ^ (z))
}
function f4 (x, y, z) {
return (((x) & (z)) | ((y) & (~(z))))
}
function f5 (x, y, z) {
return ((x) ^ ((y) | (~(z))))
}
function rotl (x, n) {
return (x << n) | (x >>> (32 - n))
}
function ripemd160 (message) {
var H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]
if (typeof message === 'string') {
message = new Buffer(message, 'utf8')
}
var m = bytesToWords(message)
var nBitsLeft = message.length * 8
var nBitsTotal = message.length * 8
// Add padding
m[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32)
m[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
(((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) |
(((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00)
)
for (var i = 0; i < m.length; i += 16) {
processBlock(H, m, i)
}
// swap endian
for (i = 0; i < 5; i++) {
// shortcut
var H_i = H[i]
// Swap
H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) |
(((H_i << 24) | (H_i >>> 8)) & 0xff00ff00)
}
var digestbytes = wordsToBytes(H)
return new Buffer(digestbytes)
}
module.exports = ripemd160
}).call(this,require("buffer").Buffer)
},{"buffer":2}],135:[function(require,module,exports){
(function (Buffer){
// prototype class for hash functions
function Hash (blockSize, finalSize) {
this._block = new Buffer(blockSize)
this._finalSize = finalSize
this._blockSize = blockSize
this._len = 0
this._s = 0
}
Hash.prototype.update = function (data, enc) {
if (typeof data === 'string') {
enc = enc || 'utf8'
data = new Buffer(data, enc)
}
var l = this._len += data.length
var s = this._s || 0
var f = 0
var buffer = this._block
while (s < l) {
var t = Math.min(data.length, f + this._blockSize - (s % this._blockSize))
var ch = (t - f)
for (var i = 0; i < ch; i++) {
buffer[(s % this._blockSize) + i] = data[i + f]
}
s += ch
f += ch
if ((s % this._blockSize) === 0) {
this._update(buffer)
}
}
this._s = s
return this
}
Hash.prototype.digest = function (enc) {
// Suppose the length of the message M, in bits, is l
var l = this._len * 8
// Append the bit 1 to the end of the message
this._block[this._len % this._blockSize] = 0x80
// and then k zero bits, where k is the smallest non-negative solution to the equation (l + 1 + k) === finalSize mod blockSize
this._block.fill(0, this._len % this._blockSize + 1)
if (l % (this._blockSize * 8) >= this._finalSize * 8) {
this._update(this._block)
this._block.fill(0)
}
// to this append the block which is equal to the number l written in binary
// TODO: handle case where l is > Math.pow(2, 29)
this._block.writeInt32BE(l, this._blockSize - 4)
var hash = this._update(this._block) || this._hash()
return enc ? hash.toString(enc) : hash
}
Hash.prototype._update = function () {
throw new Error('_update must be implemented by subclass')
}
module.exports = Hash
}).call(this,require("buffer").Buffer)
},{"buffer":2}],136:[function(require,module,exports){
var exports = module.exports = function SHA (algorithm) {
algorithm = algorithm.toLowerCase()
var Algorithm = exports[algorithm]
if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)')
return new Algorithm()
}
exports.sha = require('./sha')
exports.sha1 = require('./sha1')
exports.sha224 = require('./sha224')
exports.sha256 = require('./sha256')
exports.sha384 = require('./sha384')
exports.sha512 = require('./sha512')
},{"./sha":137,"./sha1":138,"./sha224":139,"./sha256":140,"./sha384":141,"./sha512":142}],137:[function(require,module,exports){
(function (Buffer){
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined
* in FIPS PUB 180-1
* This source code is derived from sha1.js of the same repository.
* The difference between SHA-0 and SHA-1 is just a bitwise rotate left
* operation was added.
*/
var inherits = require('inherits')
var Hash = require('./hash')
var K = [
0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
]
var W = new Array(80)
function Sha () {
this.init()
this._w = W
Hash.call(this, 64, 56)
}
inherits(Sha, Hash)
Sha.prototype.init = function () {
this._a = 0x67452301
this._b = 0xefcdab89
this._c = 0x98badcfe
this._d = 0x10325476
this._e = 0xc3d2e1f0
return this
}
function rotl5 (num) {
return (num << 5) | (num >>> 27)
}
function rotl30 (num) {
return (num << 30) | (num >>> 2)
}
function ft (s, b, c, d) {
if (s === 0) return (b & c) | ((~b) & d)
if (s === 2) return (b & c) | (b & d) | (c & d)
return b ^ c ^ d
}
Sha.prototype._update = function (M) {
var W = this._w
var a = this._a | 0
var b = this._b | 0
var c = this._c | 0
var d = this._d | 0
var e = this._e | 0
for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]
for (var j = 0; j < 80; ++j) {
var s = ~~(j / 20)
var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
e = d
d = c
c = rotl30(b)
b = a
a = t
}
this._a = (a + this._a) | 0
this._b = (b + this._b) | 0
this._c = (c + this._c) | 0
this._d = (d + this._d) | 0
this._e = (e + this._e) | 0
}
Sha.prototype._hash = function () {
var H = new Buffer(20)
H.writeInt32BE(this._a | 0, 0)
H.writeInt32BE(this._b | 0, 4)
H.writeInt32BE(this._c | 0, 8)
H.writeInt32BE(this._d | 0, 12)
H.writeInt32BE(this._e | 0, 16)
return H
}
module.exports = Sha
}).call(this,require("buffer").Buffer)
},{"./hash":135,"buffer":2,"inherits":199}],138:[function(require,module,exports){
(function (Buffer){
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
* in FIPS PUB 180-1
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
*/
var inherits = require('inherits')
var Hash = require('./hash')
var K = [
0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
]
var W = new Array(80)
function Sha1 () {
this.init()
this._w = W
Hash.call(this, 64, 56)
}
inherits(Sha1, Hash)
Sha1.prototype.init = function () {
this._a = 0x67452301
this._b = 0xefcdab89
this._c = 0x98badcfe
this._d = 0x10325476
this._e = 0xc3d2e1f0
return this
}
function rotl1 (num) {
return (num << 1) | (num >>> 31)
}
function rotl5 (num) {
return (num << 5) | (num >>> 27)
}
function rotl30 (num) {
return (num << 30) | (num >>> 2)
}
function ft (s, b, c, d) {
if (s === 0) return (b & c) | ((~b) & d)
if (s === 2) return (b & c) | (b & d) | (c & d)
return b ^ c ^ d
}
Sha1.prototype._update = function (M) {
var W = this._w
var a = this._a | 0
var b = this._b | 0
var c = this._c | 0
var d = this._d | 0
var e = this._e | 0
for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16])
for (var j = 0; j < 80; ++j) {
var s = ~~(j / 20)
var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
e = d
d = c
c = rotl30(b)
b = a
a = t
}
this._a = (a + this._a) | 0
this._b = (b + this._b) | 0
this._c = (c + this._c) | 0
this._d = (d + this._d) | 0
this._e = (e + this._e) | 0
}
Sha1.prototype._hash = function () {
var H = new Buffer(20)
H.writeInt32BE(this._a | 0, 0)
H.writeInt32BE(this._b | 0, 4)
H.writeInt32BE(this._c | 0, 8)
H.writeInt32BE(this._d | 0, 12)
H.writeInt32BE(this._e | 0, 16)
return H
}
module.exports = Sha1
}).call(this,require("buffer").Buffer)
},{"./hash":135,"buffer":2,"inherits":199}],139:[function(require,module,exports){
(function (Buffer){
/**
* A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
* in FIPS 180-2
* Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
*
*/
var inherits = require('inherits')
var Sha256 = require('./sha256')
var Hash = require('./hash')
var W = new Array(64)
function Sha224 () {
this.init()
this._w = W // new Array(64)
Hash.call(this, 64, 56)
}
inherits(Sha224, Sha256)
Sha224.prototype.init = function () {
this._a = 0xc1059ed8
this._b = 0x367cd507
this._c = 0x3070dd17
this._d = 0xf70e5939
this._e = 0xffc00b31
this._f = 0x68581511
this._g = 0x64f98fa7
this._h = 0xbefa4fa4
return this
}
Sha224.prototype._hash = function () {
var H = new Buffer(28)
H.writeInt32BE(this._a, 0)
H.writeInt32BE(this._b, 4)
H.writeInt32BE(this._c, 8)
H.writeInt32BE(this._d, 12)
H.writeInt32BE(this._e, 16)
H.writeInt32BE(this._f, 20)
H.writeInt32BE(this._g, 24)
return H
}
module.exports = Sha224
}).call(this,require("buffer").Buffer)
},{"./hash":135,"./sha256":140,"buffer":2,"inherits":199}],140:[function(require,module,exports){
(function (Buffer){
/**
* A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
* in FIPS 180-2
* Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
*
*/
var inherits = require('inherits')
var Hash = require('./hash')
var K = [
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
]
var W = new Array(64)
function Sha256 () {
this.init()
this._w = W // new Array(64)
Hash.call(this, 64, 56)
}
inherits(Sha256, Hash)
Sha256.prototype.init = function () {
this._a = 0x6a09e667
this._b = 0xbb67ae85
this._c = 0x3c6ef372
this._d = 0xa54ff53a
this._e = 0x510e527f
this._f = 0x9b05688c
this._g = 0x1f83d9ab
this._h = 0x5be0cd19
return this
}
function ch (x, y, z) {
return z ^ (x & (y ^ z))
}
function maj (x, y, z) {
return (x & y) | (z & (x | y))
}
function sigma0 (x) {
return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10)
}
function sigma1 (x) {
return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7)
}
function gamma0 (x) {
return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3)
}
function gamma1 (x) {
return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10)
}
Sha256.prototype._update = function (M) {
var W = this._w
var a = this._a | 0
var b = this._b | 0
var c = this._c | 0
var d = this._d | 0
var e = this._e | 0
var f = this._f | 0
var g = this._g | 0
var h = this._h | 0
for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0
for (var j = 0; j < 64; ++j) {
var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0
var T2 = (sigma0(a) + maj(a, b, c)) | 0
h = g
g = f
f = e
e = (d + T1) | 0
d = c
c = b
b = a
a = (T1 + T2) | 0
}
this._a = (a + this._a) | 0
this._b = (b + this._b) | 0
this._c = (c + this._c) | 0
this._d = (d + this._d) | 0
this._e = (e + this._e) | 0
this._f = (f + this._f) | 0
this._g = (g + this._g) | 0
this._h = (h + this._h) | 0
}
Sha256.prototype._hash = function () {
var H = new Buffer(32)
H.writeInt32BE(this._a, 0)
H.writeInt32BE(this._b, 4)
H.writeInt32BE(this._c, 8)
H.writeInt32BE(this._d, 12)
H.writeInt32BE(this._e, 16)
H.writeInt32BE(this._f, 20)
H.writeInt32BE(this._g, 24)
H.writeInt32BE(this._h, 28)
return H
}
module.exports = Sha256
}).call(this,require("buffer").Buffer)
},{"./hash":135,"buffer":2,"inherits":199}],141:[function(require,module,exports){
(function (Buffer){
var inherits = require('inherits')
var SHA512 = require('./sha512')
var Hash = require('./hash')
var W = new Array(160)
function Sha384 () {
this.init()
this._w = W
Hash.call(this, 128, 112)
}
inherits(Sha384, SHA512)
Sha384.prototype.init = function () {
this._ah = 0xcbbb9d5d
this._bh = 0x629a292a
this._ch = 0x9159015a
this._dh = 0x152fecd8
this._eh = 0x67332667
this._fh = 0x8eb44a87
this._gh = 0xdb0c2e0d
this._hh = 0x47b5481d
this._al = 0xc1059ed8
this._bl = 0x367cd507
this._cl = 0x3070dd17
this._dl = 0xf70e5939
this._el = 0xffc00b31
this._fl = 0x68581511
this._gl = 0x64f98fa7
this._hl = 0xbefa4fa4
return this
}
Sha384.prototype._hash = function () {
var H = new Buffer(48)
function writeInt64BE (h, l, offset) {
H.writeInt32BE(h, offset)
H.writeInt32BE(l, offset + 4)
}
writeInt64BE(this._ah, this._al, 0)
writeInt64BE(this._bh, this._bl, 8)
writeInt64BE(this._ch, this._cl, 16)
writeInt64BE(this._dh, this._dl, 24)
writeInt64BE(this._eh, this._el, 32)
writeInt64BE(this._fh, this._fl, 40)
return H
}
module.exports = Sha384
}).call(this,require("buffer").Buffer)
},{"./hash":135,"./sha512":142,"buffer":2,"inherits":199}],142:[function(require,module,exports){
(function (Buffer){
var inherits = require('inherits')
var Hash = require('./hash')
var K = [
0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
]
var W = new Array(160)
function Sha512 () {
this.init()
this._w = W
Hash.call(this, 128, 112)
}
inherits(Sha512, Hash)
Sha512.prototype.init = function () {
this._ah = 0x6a09e667
this._bh = 0xbb67ae85
this._ch = 0x3c6ef372
this._dh = 0xa54ff53a
this._eh = 0x510e527f
this._fh = 0x9b05688c
this._gh = 0x1f83d9ab
this._hh = 0x5be0cd19
this._al = 0xf3bcc908
this._bl = 0x84caa73b
this._cl = 0xfe94f82b
this._dl = 0x5f1d36f1
this._el = 0xade682d1
this._fl = 0x2b3e6c1f
this._gl = 0xfb41bd6b
this._hl = 0x137e2179
return this
}
function Ch (x, y, z) {
return z ^ (x & (y ^ z))
}
function maj (x, y, z) {
return (x & y) | (z & (x | y))
}
function sigma0 (x, xl) {
return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25)
}
function sigma1 (x, xl) {
return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23)
}
function Gamma0 (x, xl) {
return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7)
}
function Gamma0l (x, xl) {
return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25)
}
function Gamma1 (x, xl) {
return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6)
}
function Gamma1l (x, xl) {
return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26)
}
function getCarry (a, b) {
return (a >>> 0) < (b >>> 0) ? 1 : 0
}
Sha512.prototype._update = function (M) {
var W = this._w
var ah = this._ah | 0
var bh = this._bh | 0
var ch = this._ch | 0
var dh = this._dh | 0
var eh = this._eh | 0
var fh = this._fh | 0
var gh = this._gh | 0
var hh = this._hh | 0
var al = this._al | 0
var bl = this._bl | 0
var cl = this._cl | 0
var dl = this._dl | 0
var el = this._el | 0
var fl = this._fl | 0
var gl = this._gl | 0
var hl = this._hl | 0
for (var i = 0; i < 32; i += 2) {
W[i] = M.readInt32BE(i * 4)
W[i + 1] = M.readInt32BE(i * 4 + 4)
}
for (; i < 160; i += 2) {
var xh = W[i - 15 * 2]
var xl = W[i - 15 * 2 + 1]
var gamma0 = Gamma0(xh, xl)
var gamma0l = Gamma0l(xl, xh)
xh = W[i - 2 * 2]
xl = W[i - 2 * 2 + 1]
var gamma1 = Gamma1(xh, xl)
var gamma1l = Gamma1l(xl, xh)
// W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]
var Wi7h = W[i - 7 * 2]
var Wi7l = W[i - 7 * 2 + 1]
var Wi16h = W[i - 16 * 2]
var Wi16l = W[i - 16 * 2 + 1]
var Wil = (gamma0l + Wi7l) | 0
var Wih = (gamma0 + Wi7h + getCarry(Wil, gamma0l)) | 0
Wil = (Wil + gamma1l) | 0
Wih = (Wih + gamma1 + getCarry(Wil, gamma1l)) | 0
Wil = (Wil + Wi16l) | 0
Wih = (Wih + Wi16h + getCarry(Wil, Wi16l)) | 0
W[i] = Wih
W[i + 1] = Wil
}
for (var j = 0; j < 160; j += 2) {
Wih = W[j]
Wil = W[j + 1]
var majh = maj(ah, bh, ch)
var majl = maj(al, bl, cl)
var sigma0h = sigma0(ah, al)
var sigma0l = sigma0(al, ah)
var sigma1h = sigma1(eh, el)
var sigma1l = sigma1(el, eh)
// t1 = h + sigma1 + ch + K[j] + W[j]
var Kih = K[j]
var Kil = K[j + 1]
var chh = Ch(eh, fh, gh)
var chl = Ch(el, fl, gl)
var t1l = (hl + sigma1l) | 0
var t1h = (hh + sigma1h + getCarry(t1l, hl)) | 0
t1l = (t1l + chl) | 0
t1h = (t1h + chh + getCarry(t1l, chl)) | 0
t1l = (t1l + Kil) | 0
t1h = (t1h + Kih + getCarry(t1l, Kil)) | 0
t1l = (t1l + Wil) | 0
t1h = (t1h + Wih + getCarry(t1l, Wil)) | 0
// t2 = sigma0 + maj
var t2l = (sigma0l + majl) | 0
var t2h = (sigma0h + majh + getCarry(t2l, sigma0l)) | 0
hh = gh
hl = gl
gh = fh
gl = fl
fh = eh
fl = el
el = (dl + t1l) | 0
eh = (dh + t1h + getCarry(el, dl)) | 0
dh = ch
dl = cl
ch = bh
cl = bl
bh = ah
bl = al
al = (t1l + t2l) | 0
ah = (t1h + t2h + getCarry(al, t1l)) | 0
}
this._al = (this._al + al) | 0
this._bl = (this._bl + bl) | 0
this._cl = (this._cl + cl) | 0
this._dl = (this._dl + dl) | 0
this._el = (this._el + el) | 0
this._fl = (this._fl + fl) | 0
this._gl = (this._gl + gl) | 0
this._hl = (this._hl + hl) | 0
this._ah = (this._ah + ah + getCarry(this._al, al)) | 0
this._bh = (this._bh + bh + getCarry(this._bl, bl)) | 0
this._ch = (this._ch + ch + getCarry(this._cl, cl)) | 0
this._dh = (this._dh + dh + getCarry(this._dl, dl)) | 0
this._eh = (this._eh + eh + getCarry(this._el, el)) | 0
this._fh = (this._fh + fh + getCarry(this._fl, fl)) | 0
this._gh = (this._gh + gh + getCarry(this._gl, gl)) | 0
this._hh = (this._hh + hh + getCarry(this._hl, hl)) | 0
}
Sha512.prototype._hash = function () {
var H = new Buffer(64)
function writeInt64BE (h, l, offset) {
H.writeInt32BE(h, offset)
H.writeInt32BE(l, offset + 4)
}
writeInt64BE(this._ah, this._al, 0)
writeInt64BE(this._bh, this._bl, 8)
writeInt64BE(this._ch, this._cl, 16)
writeInt64BE(this._dh, this._dl, 24)
writeInt64BE(this._eh, this._el, 32)
writeInt64BE(this._fh, this._fl, 40)
writeInt64BE(this._gh, this._gl, 48)
writeInt64BE(this._hh, this._hl, 56)
return H
}
module.exports = Sha512
}).call(this,require("buffer").Buffer)
},{"./hash":135,"buffer":2,"inherits":199}],143:[function(require,module,exports){
(function (Buffer){
'use strict';
var createHash = require('create-hash/browser');
var inherits = require('inherits')
var Transform = require('stream').Transform
var ZEROS = new Buffer(128)
ZEROS.fill(0)
function Hmac(alg, key) {
Transform.call(this)
alg = alg.toLowerCase()
if (typeof key === 'string') {
key = new Buffer(key)
}
var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64
this._alg = alg
this._key = key
if (key.length > blocksize) {
key = createHash(alg).update(key).digest()
} else if (key.length < blocksize) {
key = Buffer.concat([key, ZEROS], blocksize)
}
var ipad = this._ipad = new Buffer(blocksize)
var opad = this._opad = new Buffer(blocksize)
for (var i = 0; i < blocksize; i++) {
ipad[i] = key[i] ^ 0x36
opad[i] = key[i] ^ 0x5C
}
this._hash = createHash(alg).update(ipad)
}
inherits(Hmac, Transform)
Hmac.prototype.update = function (data, enc) {
this._hash.update(data, enc)
return this
}
Hmac.prototype._transform = function (data, _, next) {
this._hash.update(data)
next()
}
Hmac.prototype._flush = function (next) {
this.push(this.digest())
next()
}
Hmac.prototype.digest = function (enc) {
var h = this._hash.digest()
return createHash(this._alg).update(this._opad).update(h).digest(enc)
}
module.exports = function createHmac(alg, key) {
return new Hmac(alg, key)
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"create-hash/browser":130,"inherits":199,"stream":216}],144:[function(require,module,exports){
(function (Buffer){
var generatePrime = require('./lib/generatePrime')
var primes = require('./lib/primes.json')
var DH = require('./lib/dh')
function getDiffieHellman (mod) {
var prime = new Buffer(primes[mod].prime, 'hex')
var gen = new Buffer(primes[mod].gen, 'hex')
return new DH(prime, gen)
}
var ENCODINGS = {
'binary': true, 'hex': true, 'base64': true
}
function createDiffieHellman (prime, enc, generator, genc) {
if (Buffer.isBuffer(enc) || ENCODINGS[enc] === undefined) {
return createDiffieHellman(prime, 'binary', enc, generator)
}
enc = enc || 'binary'
genc = genc || 'binary'
generator = generator || new Buffer([2])
if (!Buffer.isBuffer(generator)) {
generator = new Buffer(generator, genc)
}
if (typeof prime === 'number') {
return new DH(generatePrime(prime, generator), generator, true)
}
if (!Buffer.isBuffer(prime)) {
prime = new Buffer(prime, enc)
}
return new DH(prime, generator, true)
}
exports.DiffieHellmanGroup = exports.createDiffieHellmanGroup = exports.getDiffieHellman = getDiffieHellman
exports.createDiffieHellman = exports.DiffieHellman = createDiffieHellman
}).call(this,require("buffer").Buffer)
},{"./lib/dh":145,"./lib/generatePrime":146,"./lib/primes.json":147,"buffer":2}],145:[function(require,module,exports){
(function (Buffer){
var BN = require('bn.js');
var MillerRabin = require('miller-rabin');
var millerRabin = new MillerRabin();
var TWENTYFOUR = new BN(24);
var ELEVEN = new BN(11);
var TEN = new BN(10);
var THREE = new BN(3);
var SEVEN = new BN(7);
var primes = require('./generatePrime');
var randomBytes = require('randombytes');
module.exports = DH;
function setPublicKey(pub, enc) {
enc = enc || 'utf8';
if (!Buffer.isBuffer(pub)) {
pub = new Buffer(pub, enc);
}
this._pub = new BN(pub);
return this;
}
function setPrivateKey(priv, enc) {
enc = enc || 'utf8';
if (!Buffer.isBuffer(priv)) {
priv = new Buffer(priv, enc);
}
this._priv = new BN(priv);
return this;
}
var primeCache = {};
function checkPrime(prime, generator) {
var gen = generator.toString('hex');
var hex = [gen, prime.toString(16)].join('_');
if (hex in primeCache) {
return primeCache[hex];
}
var error = 0;
if (prime.isEven() ||
!primes.simpleSieve ||
!primes.fermatTest(prime) ||
!millerRabin.test(prime)) {
//not a prime so +1
error += 1;
if (gen === '02' || gen === '05') {
// we'd be able to check the generator
// it would fail so +8
error += 8;
} else {
//we wouldn't be able to test the generator
// so +4
error += 4;
}
primeCache[hex] = error;
return error;
}
if (!millerRabin.test(prime.shrn(1))) {
//not a safe prime
error += 2;
}
var rem;
switch (gen) {
case '02':
if (prime.mod(TWENTYFOUR).cmp(ELEVEN)) {
// unsuidable generator
error += 8;
}
break;
case '05':
rem = prime.mod(TEN);
if (rem.cmp(THREE) && rem.cmp(SEVEN)) {
// prime mod 10 needs to equal 3 or 7
error += 8;
}
break;
default:
error += 4;
}
primeCache[hex] = error;
return error;
}
function DH(prime, generator, malleable) {
this.setGenerator(generator);
this.__prime = new BN(prime);
this._prime = BN.mont(this.__prime);
this._primeLen = prime.length;
this._pub = undefined;
this._priv = undefined;
this._primeCode = undefined;
if (malleable) {
this.setPublicKey = setPublicKey;
this.setPrivateKey = setPrivateKey;
} else {
this._primeCode = 8;
}
}
Object.defineProperty(DH.prototype, 'verifyError', {
enumerable: true,
get: function () {
if (typeof this._primeCode !== 'number') {
this._primeCode = checkPrime(this.__prime, this.__gen);
}
return this._primeCode;
}
});
DH.prototype.generateKeys = function () {
if (!this._priv) {
this._priv = new BN(randomBytes(this._primeLen));
}
this._pub = this._gen.toRed(this._prime).redPow(this._priv).fromRed();
return this.getPublicKey();
};
DH.prototype.computeSecret = function (other) {
other = new BN(other);
other = other.toRed(this._prime);
var secret = other.redPow(this._priv).fromRed();
var out = new Buffer(secret.toArray());
var prime = this.getPrime();
if (out.length < prime.length) {
var front = new Buffer(prime.length - out.length);
front.fill(0);
out = Buffer.concat([front, out]);
}
return out;
};
DH.prototype.getPublicKey = function getPublicKey(enc) {
return formatReturnValue(this._pub, enc);
};
DH.prototype.getPrivateKey = function getPrivateKey(enc) {
return formatReturnValue(this._priv, enc);
};
DH.prototype.getPrime = function (enc) {
return formatReturnValue(this.__prime, enc);
};
DH.prototype.getGenerator = function (enc) {
return formatReturnValue(this._gen, enc);
};
DH.prototype.setGenerator = function (gen, enc) {
enc = enc || 'utf8';
if (!Buffer.isBuffer(gen)) {
gen = new Buffer(gen, enc);
}
this.__gen = gen;
this._gen = new BN(gen);
return this;
};
function formatReturnValue(bn, enc) {
var buf = new Buffer(bn.toArray());
if (!enc) {
return buf;
} else {
return buf.toString(enc);
}
}
}).call(this,require("buffer").Buffer)
},{"./generatePrime":146,"bn.js":148,"buffer":2,"miller-rabin":149,"randombytes":197}],146:[function(require,module,exports){
var randomBytes = require('randombytes');
module.exports = findPrime;
findPrime.simpleSieve = simpleSieve;
findPrime.fermatTest = fermatTest;
var BN = require('bn.js');
var TWENTYFOUR = new BN(24);
var MillerRabin = require('miller-rabin');
var millerRabin = new MillerRabin();
var ONE = new BN(1);
var TWO = new BN(2);
var FIVE = new BN(5);
var SIXTEEN = new BN(16);
var EIGHT = new BN(8);
var TEN = new BN(10);
var THREE = new BN(3);
var SEVEN = new BN(7);
var ELEVEN = new BN(11);
var FOUR = new BN(4);
var TWELVE = new BN(12);
var primes = null;
function _getPrimes() {
if (primes !== null)
return primes;
var limit = 0x100000;
var res = [];
res[0] = 2;
for (var i = 1, k = 3; k < limit; k += 2) {
var sqrt = Math.ceil(Math.sqrt(k));
for (var j = 0; j < i && res[j] <= sqrt; j++)
if (k % res[j] === 0)
break;
if (i !== j && res[j] <= sqrt)
continue;
res[i++] = k;
}
primes = res;
return res;
}
function simpleSieve(p) {
var primes = _getPrimes();
for (var i = 0; i < primes.length; i++)
if (p.modn(primes[i]) === 0) {
if (p.cmpn(primes[i]) === 0) {
return true;
} else {
return false;
}
}
return true;
}
function fermatTest(p) {
var red = BN.mont(p);
return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0;
}
function findPrime(bits, gen) {
if (bits < 16) {
// this is what openssl does
if (gen === 2 || gen === 5) {
return new BN([0x8c, 0x7b]);
} else {
return new BN([0x8c, 0x27]);
}
}
gen = new BN(gen);
var num, n2;
while (true) {
num = new BN(randomBytes(Math.ceil(bits / 8)));
while (num.bitLength() > bits) {
num.ishrn(1);
}
if (num.isEven()) {
num.iadd(ONE);
}
if (!num.testn(1)) {
num.iadd(TWO);
}
if (!gen.cmp(TWO)) {
while (num.mod(TWENTYFOUR).cmp(ELEVEN)) {
num.iadd(FOUR);
}
} else if (!gen.cmp(FIVE)) {
while (num.mod(TEN).cmp(THREE)) {
num.iadd(FOUR);
}
}
n2 = num.shrn(1);
if (simpleSieve(n2) && simpleSieve(num) &&
fermatTest(n2) && fermatTest(num) &&
millerRabin.test(n2) && millerRabin.test(num)) {
return num;
}
}
}
},{"bn.js":148,"miller-rabin":149,"randombytes":197}],147:[function(require,module,exports){
module.exports={
"modp1": {
"gen": "02",
"prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff"
},
"modp2": {
"gen": "02",
"prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff"
},
"modp5": {
"gen": "02",
"prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff"
},
"modp14": {
"gen": "02",
"prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff"
},
"modp15": {
"gen": "02",
"prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff"
},
"modp16": {
"gen": "02",
"prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff"
},
"modp17": {
"gen": "02",
"prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff"
},
"modp18": {
"gen": "02",
"prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff"
}
}
},{}],148:[function(require,module,exports){
arguments[4][39][0].apply(exports,arguments)
},{"dup":39}],149:[function(require,module,exports){
var bn = require('bn.js');
var brorand = require('brorand');
function MillerRabin(rand) {
this.rand = rand || new brorand.Rand();
}
module.exports = MillerRabin;
MillerRabin.create = function create(rand) {
return new MillerRabin(rand);
};
MillerRabin.prototype._rand = function _rand(n) {
var len = n.bitLength();
var buf = this.rand.generate(Math.ceil(len / 8));
// Set low bits
buf[0] |= 3;
// Mask high bits
var mask = len & 0x7;
if (mask !== 0)
buf[buf.length - 1] >>= 7 - mask;
return new bn(buf);
}
MillerRabin.prototype.test = function test(n, k, cb) {
var len = n.bitLength();
var red = bn.mont(n);
var rone = new bn(1).toRed(red);
if (!k)
k = Math.max(1, (len / 48) | 0);
// Find d and s, (n - 1) = (2 ^ s) * d;
var n1 = n.subn(1);
var n2 = n1.subn(1);
for (var s = 0; !n1.testn(s); s++) {}
var d = n.shrn(s);
var rn1 = n1.toRed(red);
var prime = true;
for (; k > 0; k--) {
var a = this._rand(n2);
if (cb)
cb(a);
var x = a.toRed(red).redPow(d);
if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
continue;
for (var i = 1; i < s; i++) {
x = x.redSqr();
if (x.cmp(rone) === 0)
return false;
if (x.cmp(rn1) === 0)
break;
}
if (i === s)
return false;
}
return prime;
};
MillerRabin.prototype.getDivisor = function getDivisor(n, k) {
var len = n.bitLength();
var red = bn.mont(n);
var rone = new bn(1).toRed(red);
if (!k)
k = Math.max(1, (len / 48) | 0);
// Find d and s, (n - 1) = (2 ^ s) * d;
var n1 = n.subn(1);
var n2 = n1.subn(1);
for (var s = 0; !n1.testn(s); s++) {}
var d = n.shrn(s);
var rn1 = n1.toRed(red);
for (; k > 0; k--) {
var a = this._rand(n2);
var g = n.gcd(a);
if (g.cmpn(1) !== 0)
return g;
var x = a.toRed(red).redPow(d);
if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
continue;
for (var i = 1; i < s; i++) {
x = x.redSqr();
if (x.cmp(rone) === 0)
return x.fromRed().subn(1).gcd(n);
if (x.cmp(rn1) === 0)
break;
}
if (i === s) {
x = x.redSqr();
return x.fromRed().subn(1).gcd(n);
}
}
return false;
};
},{"bn.js":148,"brorand":150}],150:[function(require,module,exports){
arguments[4][57][0].apply(exports,arguments)
},{"dup":57}],151:[function(require,module,exports){
(function (Buffer){
var createHmac = require('create-hmac')
var MAX_ALLOC = Math.pow(2, 30) - 1 // default in iojs
exports.pbkdf2 = pbkdf2
function pbkdf2 (password, salt, iterations, keylen, digest, callback) {
if (typeof digest === 'function') {
callback = digest
digest = undefined
}
if (typeof callback !== 'function') {
throw new Error('No callback provided to pbkdf2')
}
var result = pbkdf2Sync(password, salt, iterations, keylen, digest)
setTimeout(function () {
callback(undefined, result)
})
}
exports.pbkdf2Sync = pbkdf2Sync
function pbkdf2Sync (password, salt, iterations, keylen, digest) {
if (typeof iterations !== 'number') {
throw new TypeError('Iterations not a number')
}
if (iterations < 0) {
throw new TypeError('Bad iterations')
}
if (typeof keylen !== 'number') {
throw new TypeError('Key length not a number')
}
if (keylen < 0 || keylen > MAX_ALLOC) {
throw new TypeError('Bad key length')
}
digest = digest || 'sha1'
if (!Buffer.isBuffer(password)) password = new Buffer(password, 'binary')
if (!Buffer.isBuffer(salt)) salt = new Buffer(salt, 'binary')
var hLen
var l = 1
var DK = new Buffer(keylen)
var block1 = new Buffer(salt.length + 4)
salt.copy(block1, 0, 0, salt.length)
var r
var T
for (var i = 1; i <= l; i++) {
block1.writeUInt32BE(i, salt.length)
var U = createHmac(digest, password).update(block1).digest()
if (!hLen) {
hLen = U.length
T = new Buffer(hLen)
l = Math.ceil(keylen / hLen)
r = keylen - (l - 1) * hLen
}
U.copy(T, 0, 0, hLen)
for (var j = 1; j < iterations; j++) {
U = createHmac(digest, password).update(U).digest()
for (var k = 0; k < hLen; k++) {
T[k] ^= U[k]
}
}
var destPos = (i - 1) * hLen
var len = (i === l ? r : hLen)
T.copy(DK, destPos, 0, len)
}
return DK
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"create-hmac":143}],152:[function(require,module,exports){
exports.publicEncrypt = require('./publicEncrypt');
exports.privateDecrypt = require('./privateDecrypt');
exports.privateEncrypt = function privateEncrypt(key, buf) {
return exports.publicEncrypt(key, buf, true);
};
exports.publicDecrypt = function publicDecrypt(key, buf) {
return exports.privateDecrypt(key, buf, true);
};
},{"./privateDecrypt":193,"./publicEncrypt":194}],153:[function(require,module,exports){
(function (Buffer){
var createHash = require('create-hash');
module.exports = function (seed, len) {
var t = new Buffer('');
var i = 0, c;
while (t.length < len) {
c = i2ops(i++);
t = Buffer.concat([t, createHash('sha1').update(seed).update(c).digest()]);
}
return t.slice(0, len);
};
function i2ops(c) {
var out = new Buffer(4);
out.writeUInt32BE(c,0);
return out;
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"create-hash":130}],154:[function(require,module,exports){
arguments[4][39][0].apply(exports,arguments)
},{"dup":39}],155:[function(require,module,exports){
(function (Buffer){
var bn = require('bn.js');
var randomBytes = require('randombytes');
module.exports = crt;
function blind(priv) {
var r = getr(priv);
var blinder = r.toRed(bn.mont(priv.modulus))
.redPow(new bn(priv.publicExponent)).fromRed();
return {
blinder: blinder,
unblinder:r.invm(priv.modulus)
};
}
function crt(msg, priv) {
var blinds = blind(priv);
var len = priv.modulus.byteLength();
var mod = bn.mont(priv.modulus);
var blinded = new bn(msg).mul(blinds.blinder).umod(priv.modulus);
var c1 = blinded.toRed(bn.mont(priv.prime1));
var c2 = blinded.toRed(bn.mont(priv.prime2));
var qinv = priv.coefficient;
var p = priv.prime1;
var q = priv.prime2;
var m1 = c1.redPow(priv.exponent1);
var m2 = c2.redPow(priv.exponent2);
m1 = m1.fromRed();
m2 = m2.fromRed();
var h = m1.isub(m2).imul(qinv).umod(p);
h.imul(q);
m2.iadd(h);
return new Buffer(m2.imul(blinds.unblinder).umod(priv.modulus).toArray(false, len));
}
crt.getr = getr;
function getr(priv) {
var len = priv.modulus.byteLength();
var r = new bn(randomBytes(len));
while (r.cmp(priv.modulus) >= 0 || !r.umod(priv.prime1) || !r.umod(priv.prime2)) {
r = new bn(randomBytes(len));
}
return r;
}
}).call(this,require("buffer").Buffer)
},{"bn.js":154,"buffer":2,"randombytes":197}],156:[function(require,module,exports){
arguments[4][65][0].apply(exports,arguments)
},{"dup":65}],157:[function(require,module,exports){
arguments[4][66][0].apply(exports,arguments)
},{"asn1.js":160,"dup":66}],158:[function(require,module,exports){
(function (Buffer){
// adapted from https://github.com/apatil/pemstrip
var findProc = /Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)\r?\n\r?\n([0-9A-z\n\r\+\/\=]+)\r?\n/m
var startRegex = /^-----BEGIN (.*) KEY-----\r?\n/m
var fullRegex = /^-----BEGIN (.*) KEY-----\r?\n([0-9A-z\n\r\+\/\=]+)\r?\n-----END \1 KEY-----$/m
var evp = require('evp_bytestokey')
var ciphers = require('browserify-aes')
module.exports = function (okey, password) {
var key = okey.toString()
var match = key.match(findProc)
var decrypted
if (!match) {
var match2 = key.match(fullRegex)
decrypted = new Buffer(match2[2].replace(/\r?\n/g, ''), 'base64')
} else {
var suite = 'aes' + match[1]
var iv = new Buffer(match[2], 'hex')
var cipherText = new Buffer(match[3].replace(/\r?\n/g, ''), 'base64')
var cipherKey = evp(password, iv.slice(0, 8), parseInt(match[1], 10)).key
var out = []
var cipher = ciphers.createDecipheriv(suite, cipherKey, iv)
out.push(cipher.update(cipherText))
out.push(cipher.final())
decrypted = Buffer.concat(out)
}
var tag = key.match(startRegex)[1] + ' KEY'
return {
tag: tag,
data: decrypted
}
}
}).call(this,require("buffer").Buffer)
},{"browserify-aes":177,"buffer":2,"evp_bytestokey":192}],159:[function(require,module,exports){
(function (Buffer){
var asn1 = require('./asn1')
var aesid = require('./aesid.json')
var fixProc = require('./fixProc')
var ciphers = require('browserify-aes')
var compat = require('pbkdf2')
module.exports = parseKeys
function parseKeys (buffer) {
var password
if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) {
password = buffer.passphrase
buffer = buffer.key
}
if (typeof buffer === 'string') {
buffer = new Buffer(buffer)
}
var stripped = fixProc(buffer, password)
var type = stripped.tag
var data = stripped.data
var subtype, ndata
switch (type) {
case 'PUBLIC KEY':
ndata = asn1.PublicKey.decode(data, 'der')
subtype = ndata.algorithm.algorithm.join('.')
switch (subtype) {
case '1.2.840.113549.1.1.1':
return asn1.RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der')
case '1.2.840.10045.2.1':
ndata.subjectPrivateKey = ndata.subjectPublicKey
return {
type: 'ec',
data: ndata
}
case '1.2.840.10040.4.1':
ndata.algorithm.params.pub_key = asn1.DSAparam.decode(ndata.subjectPublicKey.data, 'der')
return {
type: 'dsa',
data: ndata.algorithm.params
}
default: throw new Error('unknown key id ' + subtype)
}
throw new Error('unknown key type ' + type)
case 'ENCRYPTED PRIVATE KEY':
data = asn1.EncryptedPrivateKey.decode(data, 'der')
data = decrypt(data, password)
// falls through
case 'PRIVATE KEY':
ndata = asn1.PrivateKey.decode(data, 'der')
subtype = ndata.algorithm.algorithm.join('.')
switch (subtype) {
case '1.2.840.113549.1.1.1':
return asn1.RSAPrivateKey.decode(ndata.subjectPrivateKey, 'der')
case '1.2.840.10045.2.1':
return {
curve: ndata.algorithm.curve,
privateKey: asn1.ECPrivateKey.decode(ndata.subjectPrivateKey, 'der').privateKey
}
case '1.2.840.10040.4.1':
ndata.algorithm.params.priv_key = asn1.DSAparam.decode(ndata.subjectPrivateKey, 'der')
return {
type: 'dsa',
params: ndata.algorithm.params
}
default: throw new Error('unknown key id ' + subtype)
}
throw new Error('unknown key type ' + type)
case 'RSA PUBLIC KEY':
return asn1.RSAPublicKey.decode(data, 'der')
case 'RSA PRIVATE KEY':
return asn1.RSAPrivateKey.decode(data, 'der')
case 'DSA PRIVATE KEY':
return {
type: 'dsa',
params: asn1.DSAPrivateKey.decode(data, 'der')
}
case 'EC PRIVATE KEY':
data = asn1.ECPrivateKey.decode(data, 'der')
return {
curve: data.parameters.value,
privateKey: data.privateKey
}
default: throw new Error('unknown key type ' + type)
}
}
parseKeys.signature = asn1.signature
function decrypt (data, password) {
var salt = data.algorithm.decrypt.kde.kdeparams.salt
var iters = parseInt(data.algorithm.decrypt.kde.kdeparams.iters.toString(), 10)
var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')]
var iv = data.algorithm.decrypt.cipher.iv
var cipherText = data.subjectPrivateKey
var keylen = parseInt(algo.split('-')[1], 10) / 8
var key = compat.pbkdf2Sync(password, salt, iters, keylen)
var cipher = ciphers.createDecipheriv(algo, key, iv)
var out = []
out.push(cipher.update(cipherText))
out.push(cipher.final())
return Buffer.concat(out)
}
}).call(this,require("buffer").Buffer)
},{"./aesid.json":156,"./asn1":157,"./fixProc":158,"browserify-aes":177,"buffer":2,"pbkdf2":151}],160:[function(require,module,exports){
arguments[4][69][0].apply(exports,arguments)
},{"./asn1/api":161,"./asn1/base":163,"./asn1/constants":167,"./asn1/decoders":169,"./asn1/encoders":172,"bn.js":154,"dup":69}],161:[function(require,module,exports){
arguments[4][70][0].apply(exports,arguments)
},{"../asn1":160,"dup":70,"inherits":199,"vm":218}],162:[function(require,module,exports){
arguments[4][71][0].apply(exports,arguments)
},{"../base":163,"buffer":2,"dup":71,"inherits":199}],163:[function(require,module,exports){
arguments[4][72][0].apply(exports,arguments)
},{"./buffer":162,"./node":164,"./reporter":165,"dup":72}],164:[function(require,module,exports){
arguments[4][73][0].apply(exports,arguments)
},{"../base":163,"dup":73,"minimalistic-assert":174}],165:[function(require,module,exports){
arguments[4][74][0].apply(exports,arguments)
},{"dup":74,"inherits":199}],166:[function(require,module,exports){
arguments[4][75][0].apply(exports,arguments)
},{"../constants":167,"dup":75}],167:[function(require,module,exports){
arguments[4][76][0].apply(exports,arguments)
},{"./der":166,"dup":76}],168:[function(require,module,exports){
arguments[4][77][0].apply(exports,arguments)
},{"../../asn1":160,"dup":77,"inherits":199}],169:[function(require,module,exports){
arguments[4][78][0].apply(exports,arguments)
},{"./der":168,"./pem":170,"dup":78}],170:[function(require,module,exports){
arguments[4][79][0].apply(exports,arguments)
},{"./der":168,"buffer":2,"dup":79,"inherits":199}],171:[function(require,module,exports){
arguments[4][80][0].apply(exports,arguments)
},{"../../asn1":160,"buffer":2,"dup":80,"inherits":199}],172:[function(require,module,exports){
arguments[4][81][0].apply(exports,arguments)
},{"./der":171,"./pem":173,"dup":81}],173:[function(require,module,exports){
arguments[4][82][0].apply(exports,arguments)
},{"./der":171,"dup":82,"inherits":199}],174:[function(require,module,exports){
arguments[4][34][0].apply(exports,arguments)
},{"dup":34}],175:[function(require,module,exports){
(function (Buffer){
// based on the aes implimentation in triple sec
// https://github.com/keybase/triplesec
// which is in turn based on the one from crypto-js
// https://code.google.com/p/crypto-js/
var uint_max = Math.pow(2, 32)
function fixup_uint32 (x) {
var ret, x_pos
ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x
return ret
}
function scrub_vec (v) {
for (var i = 0; i < v.length; v++) {
v[i] = 0
}
return false
}
function Global () {
this.SBOX = []
this.INV_SBOX = []
this.SUB_MIX = [[], [], [], []]
this.INV_SUB_MIX = [[], [], [], []]
this.init()
this.RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]
}
Global.prototype.init = function () {
var d, i, sx, t, x, x2, x4, x8, xi, _i
d = (function () {
var _i, _results
_results = []
for (i = _i = 0; _i < 256; i = ++_i) {
if (i < 128) {
_results.push(i << 1)
} else {
_results.push((i << 1) ^ 0x11b)
}
}
return _results
})()
x = 0
xi = 0
for (i = _i = 0; _i < 256; i = ++_i) {
sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4)
sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63
this.SBOX[x] = sx
this.INV_SBOX[sx] = x
x2 = d[x]
x4 = d[x2]
x8 = d[x4]
t = (d[sx] * 0x101) ^ (sx * 0x1010100)
this.SUB_MIX[0][x] = (t << 24) | (t >>> 8)
this.SUB_MIX[1][x] = (t << 16) | (t >>> 16)
this.SUB_MIX[2][x] = (t << 8) | (t >>> 24)
this.SUB_MIX[3][x] = t
t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100)
this.INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8)
this.INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16)
this.INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24)
this.INV_SUB_MIX[3][sx] = t
if (x === 0) {
x = xi = 1
} else {
x = x2 ^ d[d[d[x8 ^ x2]]]
xi ^= d[d[xi]]
}
}
return true
}
var G = new Global()
AES.blockSize = 4 * 4
AES.prototype.blockSize = AES.blockSize
AES.keySize = 256 / 8
AES.prototype.keySize = AES.keySize
function bufferToArray (buf) {
var len = buf.length / 4
var out = new Array(len)
var i = -1
while (++i < len) {
out[i] = buf.readUInt32BE(i * 4)
}
return out
}
function AES (key) {
this._key = bufferToArray(key)
this._doReset()
}
AES.prototype._doReset = function () {
var invKsRow, keySize, keyWords, ksRow, ksRows, t
keyWords = this._key
keySize = keyWords.length
this._nRounds = keySize + 6
ksRows = (this._nRounds + 1) * 4
this._keySchedule = []
for (ksRow = 0; ksRow < ksRows; ksRow++) {
this._keySchedule[ksRow] = ksRow < keySize ? keyWords[ksRow] : (t = this._keySchedule[ksRow - 1], (ksRow % keySize) === 0 ? (t = (t << 8) | (t >>> 24), t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff], t ^= G.RCON[(ksRow / keySize) | 0] << 24) : keySize > 6 && ksRow % keySize === 4 ? t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff] : void 0, this._keySchedule[ksRow - keySize] ^ t)
}
this._invKeySchedule = []
for (invKsRow = 0; invKsRow < ksRows; invKsRow++) {
ksRow = ksRows - invKsRow
t = this._keySchedule[ksRow - (invKsRow % 4 ? 0 : 4)]
this._invKeySchedule[invKsRow] = invKsRow < 4 || ksRow <= 4 ? t : G.INV_SUB_MIX[0][G.SBOX[t >>> 24]] ^ G.INV_SUB_MIX[1][G.SBOX[(t >>> 16) & 0xff]] ^ G.INV_SUB_MIX[2][G.SBOX[(t >>> 8) & 0xff]] ^ G.INV_SUB_MIX[3][G.SBOX[t & 0xff]]
}
return true
}
AES.prototype.encryptBlock = function (M) {
M = bufferToArray(new Buffer(M))
var out = this._doCryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX)
var buf = new Buffer(16)
buf.writeUInt32BE(out[0], 0)
buf.writeUInt32BE(out[1], 4)
buf.writeUInt32BE(out[2], 8)
buf.writeUInt32BE(out[3], 12)
return buf
}
AES.prototype.decryptBlock = function (M) {
M = bufferToArray(new Buffer(M))
var temp = [M[3], M[1]]
M[1] = temp[0]
M[3] = temp[1]
var out = this._doCryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX)
var buf = new Buffer(16)
buf.writeUInt32BE(out[0], 0)
buf.writeUInt32BE(out[3], 4)
buf.writeUInt32BE(out[2], 8)
buf.writeUInt32BE(out[1], 12)
return buf
}
AES.prototype.scrub = function () {
scrub_vec(this._keySchedule)
scrub_vec(this._invKeySchedule)
scrub_vec(this._key)
}
AES.prototype._doCryptBlock = function (M, keySchedule, SUB_MIX, SBOX) {
var ksRow, s0, s1, s2, s3, t0, t1, t2, t3
s0 = M[0] ^ keySchedule[0]
s1 = M[1] ^ keySchedule[1]
s2 = M[2] ^ keySchedule[2]
s3 = M[3] ^ keySchedule[3]
ksRow = 4
for (var round = 1; round < this._nRounds; round++) {
t0 = SUB_MIX[0][s0 >>> 24] ^ SUB_MIX[1][(s1 >>> 16) & 0xff] ^ SUB_MIX[2][(s2 >>> 8) & 0xff] ^ SUB_MIX[3][s3 & 0xff] ^ keySchedule[ksRow++]
t1 = SUB_MIX[0][s1 >>> 24] ^ SUB_MIX[1][(s2 >>> 16) & 0xff] ^ SUB_MIX[2][(s3 >>> 8) & 0xff] ^ SUB_MIX[3][s0 & 0xff] ^ keySchedule[ksRow++]
t2 = SUB_MIX[0][s2 >>> 24] ^ SUB_MIX[1][(s3 >>> 16) & 0xff] ^ SUB_MIX[2][(s0 >>> 8) & 0xff] ^ SUB_MIX[3][s1 & 0xff] ^ keySchedule[ksRow++]
t3 = SUB_MIX[0][s3 >>> 24] ^ SUB_MIX[1][(s0 >>> 16) & 0xff] ^ SUB_MIX[2][(s1 >>> 8) & 0xff] ^ SUB_MIX[3][s2 & 0xff] ^ keySchedule[ksRow++]
s0 = t0
s1 = t1
s2 = t2
s3 = t3
}
t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]
t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]
t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]
t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]
return [
fixup_uint32(t0),
fixup_uint32(t1),
fixup_uint32(t2),
fixup_uint32(t3)
]
}
exports.AES = AES
}).call(this,require("buffer").Buffer)
},{"buffer":2}],176:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
var GHASH = require('./ghash')
var xor = require('buffer-xor')
inherits(StreamCipher, Transform)
module.exports = StreamCipher
function StreamCipher (mode, key, iv, decrypt) {
if (!(this instanceof StreamCipher)) {
return new StreamCipher(mode, key, iv)
}
Transform.call(this)
this._finID = Buffer.concat([iv, new Buffer([0, 0, 0, 1])])
iv = Buffer.concat([iv, new Buffer([0, 0, 0, 2])])
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
this._cache = new Buffer('')
this._secCache = new Buffer('')
this._decrypt = decrypt
this._alen = 0
this._len = 0
iv.copy(this._prev)
this._mode = mode
var h = new Buffer(4)
h.fill(0)
this._ghash = new GHASH(this._cipher.encryptBlock(h))
this._authTag = null
this._called = false
}
StreamCipher.prototype._update = function (chunk) {
if (!this._called && this._alen) {
var rump = 16 - (this._alen % 16)
if (rump < 16) {
rump = new Buffer(rump)
rump.fill(0)
this._ghash.update(rump)
}
}
this._called = true
var out = this._mode.encrypt(this, chunk)
if (this._decrypt) {
this._ghash.update(chunk)
} else {
this._ghash.update(out)
}
this._len += chunk.length
return out
}
StreamCipher.prototype._final = function () {
if (this._decrypt && !this._authTag) {
throw new Error('Unsupported state or unable to authenticate data')
}
var tag = xor(this._ghash.final(this._alen * 8, this._len * 8), this._cipher.encryptBlock(this._finID))
if (this._decrypt) {
if (xorTest(tag, this._authTag)) {
throw new Error('Unsupported state or unable to authenticate data')
}
} else {
this._authTag = tag
}
this._cipher.scrub()
}
StreamCipher.prototype.getAuthTag = function getAuthTag () {
if (!this._decrypt && Buffer.isBuffer(this._authTag)) {
return this._authTag
} else {
throw new Error('Attempting to get auth tag in unsupported state')
}
}
StreamCipher.prototype.setAuthTag = function setAuthTag (tag) {
if (this._decrypt) {
this._authTag = tag
} else {
throw new Error('Attempting to set auth tag in unsupported state')
}
}
StreamCipher.prototype.setAAD = function setAAD (buf) {
if (!this._called) {
this._ghash.update(buf)
this._alen += buf.length
} else {
throw new Error('Attempting to set AAD in unsupported state')
}
}
function xorTest (a, b) {
var out = 0
if (a.length !== b.length) {
out++
}
var len = Math.min(a.length, b.length)
var i = -1
while (++i < len) {
out += (a[i] ^ b[i])
}
return out
}
}).call(this,require("buffer").Buffer)
},{"./aes":175,"./ghash":180,"buffer":2,"buffer-xor":189,"cipher-base":190,"inherits":199}],177:[function(require,module,exports){
arguments[4][10][0].apply(exports,arguments)
},{"./decrypter":178,"./encrypter":179,"./modes":181,"dup":10}],178:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
var modes = require('./modes')
var StreamCipher = require('./streamCipher')
var AuthCipher = require('./authCipher')
var ebtk = require('evp_bytestokey')
inherits(Decipher, Transform)
function Decipher (mode, key, iv) {
if (!(this instanceof Decipher)) {
return new Decipher(mode, key, iv)
}
Transform.call(this)
this._cache = new Splitter()
this._last = void 0
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
iv.copy(this._prev)
this._mode = mode
this._autopadding = true
}
Decipher.prototype._update = function (data) {
this._cache.add(data)
var chunk
var thing
var out = []
while ((chunk = this._cache.get(this._autopadding))) {
thing = this._mode.decrypt(this, chunk)
out.push(thing)
}
return Buffer.concat(out)
}
Decipher.prototype._final = function () {
var chunk = this._cache.flush()
if (this._autopadding) {
return unpad(this._mode.decrypt(this, chunk))
} else if (chunk) {
throw new Error('data not multiple of block length')
}
}
Decipher.prototype.setAutoPadding = function (setTo) {
this._autopadding = !!setTo
return this
}
function Splitter () {
if (!(this instanceof Splitter)) {
return new Splitter()
}
this.cache = new Buffer('')
}
Splitter.prototype.add = function (data) {
this.cache = Buffer.concat([this.cache, data])
}
Splitter.prototype.get = function (autoPadding) {
var out
if (autoPadding) {
if (this.cache.length > 16) {
out = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
return out
}
} else {
if (this.cache.length >= 16) {
out = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
return out
}
}
return null
}
Splitter.prototype.flush = function () {
if (this.cache.length) {
return this.cache
}
}
function unpad (last) {
var padded = last[15]
var i = -1
while (++i < padded) {
if (last[(i + (16 - padded))] !== padded) {
throw new Error('unable to decrypt data')
}
}
if (padded === 16) {
return
}
return last.slice(0, 16 - padded)
}
var modelist = {
ECB: require('./modes/ecb'),
CBC: require('./modes/cbc'),
CFB: require('./modes/cfb'),
CFB8: require('./modes/cfb8'),
CFB1: require('./modes/cfb1'),
OFB: require('./modes/ofb'),
CTR: require('./modes/ctr'),
GCM: require('./modes/ctr')
}
function createDecipheriv (suite, password, iv) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
if (typeof iv === 'string') {
iv = new Buffer(iv)
}
if (typeof password === 'string') {
password = new Buffer(password)
}
if (password.length !== config.key / 8) {
throw new TypeError('invalid key length ' + password.length)
}
if (iv.length !== config.iv) {
throw new TypeError('invalid iv length ' + iv.length)
}
if (config.type === 'stream') {
return new StreamCipher(modelist[config.mode], password, iv, true)
} else if (config.type === 'auth') {
return new AuthCipher(modelist[config.mode], password, iv, true)
}
return new Decipher(modelist[config.mode], password, iv)
}
function createDecipher (suite, password) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
var keys = ebtk(password, false, config.key, config.iv)
return createDecipheriv(suite, keys.key, keys.iv)
}
exports.createDecipher = createDecipher
exports.createDecipheriv = createDecipheriv
}).call(this,require("buffer").Buffer)
},{"./aes":175,"./authCipher":176,"./modes":181,"./modes/cbc":182,"./modes/cfb":183,"./modes/cfb1":184,"./modes/cfb8":185,"./modes/ctr":186,"./modes/ecb":187,"./modes/ofb":188,"./streamCipher":191,"buffer":2,"cipher-base":190,"evp_bytestokey":192,"inherits":199}],179:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
var modes = require('./modes')
var ebtk = require('evp_bytestokey')
var StreamCipher = require('./streamCipher')
var AuthCipher = require('./authCipher')
inherits(Cipher, Transform)
function Cipher (mode, key, iv) {
if (!(this instanceof Cipher)) {
return new Cipher(mode, key, iv)
}
Transform.call(this)
this._cache = new Splitter()
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
iv.copy(this._prev)
this._mode = mode
this._autopadding = true
}
Cipher.prototype._update = function (data) {
this._cache.add(data)
var chunk
var thing
var out = []
while ((chunk = this._cache.get())) {
thing = this._mode.encrypt(this, chunk)
out.push(thing)
}
return Buffer.concat(out)
}
Cipher.prototype._final = function () {
var chunk = this._cache.flush()
if (this._autopadding) {
chunk = this._mode.encrypt(this, chunk)
this._cipher.scrub()
return chunk
} else if (chunk.toString('hex') !== '10101010101010101010101010101010') {
this._cipher.scrub()
throw new Error('data not multiple of block length')
}
}
Cipher.prototype.setAutoPadding = function (setTo) {
this._autopadding = !!setTo
return this
}
function Splitter () {
if (!(this instanceof Splitter)) {
return new Splitter()
}
this.cache = new Buffer('')
}
Splitter.prototype.add = function (data) {
this.cache = Buffer.concat([this.cache, data])
}
Splitter.prototype.get = function () {
if (this.cache.length > 15) {
var out = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
return out
}
return null
}
Splitter.prototype.flush = function () {
var len = 16 - this.cache.length
var padBuff = new Buffer(len)
var i = -1
while (++i < len) {
padBuff.writeUInt8(len, i)
}
var out = Buffer.concat([this.cache, padBuff])
return out
}
var modelist = {
ECB: require('./modes/ecb'),
CBC: require('./modes/cbc'),
CFB: require('./modes/cfb'),
CFB8: require('./modes/cfb8'),
CFB1: require('./modes/cfb1'),
OFB: require('./modes/ofb'),
CTR: require('./modes/ctr'),
GCM: require('./modes/ctr')
}
function createCipheriv (suite, password, iv) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
if (typeof iv === 'string') {
iv = new Buffer(iv)
}
if (typeof password === 'string') {
password = new Buffer(password)
}
if (password.length !== config.key / 8) {
throw new TypeError('invalid key length ' + password.length)
}
if (iv.length !== config.iv) {
throw new TypeError('invalid iv length ' + iv.length)
}
if (config.type === 'stream') {
return new StreamCipher(modelist[config.mode], password, iv)
} else if (config.type === 'auth') {
return new AuthCipher(modelist[config.mode], password, iv)
}
return new Cipher(modelist[config.mode], password, iv)
}
function createCipher (suite, password) {
var config = modes[suite.toLowerCase()]
if (!config) {
throw new TypeError('invalid suite type')
}
var keys = ebtk(password, false, config.key, config.iv)
return createCipheriv(suite, keys.key, keys.iv)
}
exports.createCipheriv = createCipheriv
exports.createCipher = createCipher
}).call(this,require("buffer").Buffer)
},{"./aes":175,"./authCipher":176,"./modes":181,"./modes/cbc":182,"./modes/cfb":183,"./modes/cfb1":184,"./modes/cfb8":185,"./modes/ctr":186,"./modes/ecb":187,"./modes/ofb":188,"./streamCipher":191,"buffer":2,"cipher-base":190,"evp_bytestokey":192,"inherits":199}],180:[function(require,module,exports){
(function (Buffer){
var zeros = new Buffer(16)
zeros.fill(0)
module.exports = GHASH
function GHASH (key) {
this.h = key
this.state = new Buffer(16)
this.state.fill(0)
this.cache = new Buffer('')
}
// from http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_gcm.js.html
// by Juho Vähä-Herttua
GHASH.prototype.ghash = function (block) {
var i = -1
while (++i < block.length) {
this.state[i] ^= block[i]
}
this._multiply()
}
GHASH.prototype._multiply = function () {
var Vi = toArray(this.h)
var Zi = [0, 0, 0, 0]
var j, xi, lsb_Vi
var i = -1
while (++i < 128) {
xi = (this.state[~~(i / 8)] & (1 << (7 - i % 8))) !== 0
if (xi) {
// Z_i+1 = Z_i ^ V_i
Zi = xor(Zi, Vi)
}
// Store the value of LSB(V_i)
lsb_Vi = (Vi[3] & 1) !== 0
// V_i+1 = V_i >> 1
for (j = 3; j > 0; j--) {
Vi[j] = (Vi[j] >>> 1) | ((Vi[j - 1] & 1) << 31)
}
Vi[0] = Vi[0] >>> 1
// If LSB(V_i) is 1, V_i+1 = (V_i >> 1) ^ R
if (lsb_Vi) {
Vi[0] = Vi[0] ^ (0xe1 << 24)
}
}
this.state = fromArray(Zi)
}
GHASH.prototype.update = function (buf) {
this.cache = Buffer.concat([this.cache, buf])
var chunk
while (this.cache.length >= 16) {
chunk = this.cache.slice(0, 16)
this.cache = this.cache.slice(16)
this.ghash(chunk)
}
}
GHASH.prototype.final = function (abl, bl) {
if (this.cache.length) {
this.ghash(Buffer.concat([this.cache, zeros], 16))
}
this.ghash(fromArray([
0, abl,
0, bl
]))
return this.state
}
function toArray (buf) {
return [
buf.readUInt32BE(0),
buf.readUInt32BE(4),
buf.readUInt32BE(8),
buf.readUInt32BE(12)
]
}
function fromArray (out) {
out = out.map(fixup_uint32)
var buf = new Buffer(16)
buf.writeUInt32BE(out[0], 0)
buf.writeUInt32BE(out[1], 4)
buf.writeUInt32BE(out[2], 8)
buf.writeUInt32BE(out[3], 12)
return buf
}
var uint_max = Math.pow(2, 32)
function fixup_uint32 (x) {
var ret, x_pos
ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x
return ret
}
function xor (a, b) {
return [
a[0] ^ b[0],
a[1] ^ b[1],
a[2] ^ b[2],
a[3] ^ b[3]
]
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],181:[function(require,module,exports){
arguments[4][14][0].apply(exports,arguments)
},{"dup":14}],182:[function(require,module,exports){
arguments[4][15][0].apply(exports,arguments)
},{"buffer-xor":189,"dup":15}],183:[function(require,module,exports){
(function (Buffer){
var xor = require('buffer-xor')
exports.encrypt = function (self, data, decrypt) {
var out = new Buffer('')
var len
while (data.length) {
if (self._cache.length === 0) {
self._cache = self._cipher.encryptBlock(self._prev)
self._prev = new Buffer('')
}
if (self._cache.length <= data.length) {
len = self._cache.length
out = Buffer.concat([out, encryptStart(self, data.slice(0, len), decrypt)])
data = data.slice(len)
} else {
out = Buffer.concat([out, encryptStart(self, data, decrypt)])
break
}
}
return out
}
function encryptStart (self, data, decrypt) {
var len = data.length
var out = xor(data, self._cache)
self._cache = self._cache.slice(len)
self._prev = Buffer.concat([self._prev, decrypt ? data : out])
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"buffer-xor":189}],184:[function(require,module,exports){
(function (Buffer){
function encryptByte (self, byteParam, decrypt) {
var pad
var i = -1
var len = 8
var out = 0
var bit, value
while (++i < len) {
pad = self._cipher.encryptBlock(self._prev)
bit = (byteParam & (1 << (7 - i))) ? 0x80 : 0
value = pad[0] ^ bit
out += ((value & 0x80) >> (i % 8))
self._prev = shiftIn(self._prev, decrypt ? bit : value)
}
return out
}
exports.encrypt = function (self, chunk, decrypt) {
var len = chunk.length
var out = new Buffer(len)
var i = -1
while (++i < len) {
out[i] = encryptByte(self, chunk[i], decrypt)
}
return out
}
function shiftIn (buffer, value) {
var len = buffer.length
var i = -1
var out = new Buffer(buffer.length)
buffer = Buffer.concat([buffer, new Buffer([value])])
while (++i < len) {
out[i] = buffer[i] << 1 | buffer[i + 1] >> (7)
}
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],185:[function(require,module,exports){
(function (Buffer){
function encryptByte (self, byteParam, decrypt) {
var pad = self._cipher.encryptBlock(self._prev)
var out = pad[0] ^ byteParam
self._prev = Buffer.concat([self._prev.slice(1), new Buffer([decrypt ? byteParam : out])])
return out
}
exports.encrypt = function (self, chunk, decrypt) {
var len = chunk.length
var out = new Buffer(len)
var i = -1
while (++i < len) {
out[i] = encryptByte(self, chunk[i], decrypt)
}
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],186:[function(require,module,exports){
(function (Buffer){
var xor = require('buffer-xor')
function incr32 (iv) {
var len = iv.length
var item
while (len--) {
item = iv.readUInt8(len)
if (item === 255) {
iv.writeUInt8(0, len)
} else {
item++
iv.writeUInt8(item, len)
break
}
}
}
function getBlock (self) {
var out = self._cipher.encryptBlock(self._prev)
incr32(self._prev)
return out
}
exports.encrypt = function (self, chunk) {
while (self._cache.length < chunk.length) {
self._cache = Buffer.concat([self._cache, getBlock(self)])
}
var pad = self._cache.slice(0, chunk.length)
self._cache = self._cache.slice(chunk.length)
return xor(chunk, pad)
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"buffer-xor":189}],187:[function(require,module,exports){
arguments[4][20][0].apply(exports,arguments)
},{"dup":20}],188:[function(require,module,exports){
(function (Buffer){
var xor = require('buffer-xor')
function getBlock (self) {
self._prev = self._cipher.encryptBlock(self._prev)
return self._prev
}
exports.encrypt = function (self, chunk) {
while (self._cache.length < chunk.length) {
self._cache = Buffer.concat([self._cache, getBlock(self)])
}
var pad = self._cache.slice(0, chunk.length)
self._cache = self._cache.slice(chunk.length)
return xor(chunk, pad)
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"buffer-xor":189}],189:[function(require,module,exports){
(function (Buffer){
module.exports = function xor (a, b) {
var length = Math.min(a.length, b.length)
var buffer = new Buffer(length)
for (var i = 0; i < length; ++i) {
buffer[i] = a[i] ^ b[i]
}
return buffer
}
}).call(this,require("buffer").Buffer)
},{"buffer":2}],190:[function(require,module,exports){
(function (Buffer){
var Transform = require('stream').Transform
var inherits = require('inherits')
var StringDecoder = require('string_decoder').StringDecoder
module.exports = CipherBase
inherits(CipherBase, Transform)
function CipherBase (hashMode) {
Transform.call(this)
this.hashMode = typeof hashMode === 'string'
if (this.hashMode) {
this[hashMode] = this._finalOrDigest
} else {
this.final = this._finalOrDigest
}
this._decoder = null
this._encoding = null
}
CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
if (typeof data === 'string') {
data = new Buffer(data, inputEnc)
}
var outData = this._update(data)
if (this.hashMode) {
return this
}
if (outputEnc) {
outData = this._toString(outData, outputEnc)
}
return outData
}
CipherBase.prototype.setAutoPadding = function () {}
CipherBase.prototype.getAuthTag = function () {
throw new Error('trying to get auth tag in unsupported state')
}
CipherBase.prototype.setAuthTag = function () {
throw new Error('trying to set auth tag in unsupported state')
}
CipherBase.prototype.setAAD = function () {
throw new Error('trying to set aad in unsupported state')
}
CipherBase.prototype._transform = function (data, _, next) {
var err
try {
if (this.hashMode) {
this._update(data)
} else {
this.push(this._update(data))
}
} catch (e) {
err = e
} finally {
next(err)
}
}
CipherBase.prototype._flush = function (done) {
var err
try {
this.push(this._final())
} catch (e) {
err = e
} finally {
done(err)
}
}
CipherBase.prototype._finalOrDigest = function (outputEnc) {
var outData = this._final() || new Buffer('')
if (outputEnc) {
outData = this._toString(outData, outputEnc, true)
}
return outData
}
CipherBase.prototype._toString = function (value, enc, final) {
if (!this._decoder) {
this._decoder = new StringDecoder(enc)
this._encoding = enc
}
if (this._encoding !== enc) {
throw new Error('can\'t switch encodings')
}
var out = this._decoder.write(value)
if (final) {
out += this._decoder.end()
}
return out
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"inherits":199,"stream":216,"string_decoder":217}],191:[function(require,module,exports){
(function (Buffer){
var aes = require('./aes')
var Transform = require('cipher-base')
var inherits = require('inherits')
inherits(StreamCipher, Transform)
module.exports = StreamCipher
function StreamCipher (mode, key, iv, decrypt) {
if (!(this instanceof StreamCipher)) {
return new StreamCipher(mode, key, iv)
}
Transform.call(this)
this._cipher = new aes.AES(key)
this._prev = new Buffer(iv.length)
this._cache = new Buffer('')
this._secCache = new Buffer('')
this._decrypt = decrypt
iv.copy(this._prev)
this._mode = mode
}
StreamCipher.prototype._update = function (chunk) {
return this._mode.encrypt(this, chunk, this._decrypt)
}
StreamCipher.prototype._final = function () {
this._cipher.scrub()
}
}).call(this,require("buffer").Buffer)
},{"./aes":175,"buffer":2,"cipher-base":190,"inherits":199}],192:[function(require,module,exports){
(function (Buffer){
var md5 = require('create-hash/md5')
module.exports = EVP_BytesToKey
function EVP_BytesToKey (password, salt, keyLen, ivLen) {
if (!Buffer.isBuffer(password)) {
password = new Buffer(password, 'binary')
}
if (salt && !Buffer.isBuffer(salt)) {
salt = new Buffer(salt, 'binary')
}
keyLen = keyLen / 8
ivLen = ivLen || 0
var ki = 0
var ii = 0
var key = new Buffer(keyLen)
var iv = new Buffer(ivLen)
var addmd = 0
var md_buf
var i
var bufs = []
while (true) {
if (addmd++ > 0) {
bufs.push(md_buf)
}
bufs.push(password)
if (salt) {
bufs.push(salt)
}
md_buf = md5(Buffer.concat(bufs))
bufs = []
i = 0
if (keyLen > 0) {
while (true) {
if (keyLen === 0) {
break
}
if (i === md_buf.length) {
break
}
key[ki++] = md_buf[i]
keyLen--
i++
}
}
if (ivLen > 0 && i !== md_buf.length) {
while (true) {
if (ivLen === 0) {
break
}
if (i === md_buf.length) {
break
}
iv[ii++] = md_buf[i]
ivLen--
i++
}
}
if (keyLen === 0 && ivLen === 0) {
break
}
}
for (i = 0; i < md_buf.length; i++) {
md_buf[i] = 0
}
return {
key: key,
iv: iv
}
}
}).call(this,require("buffer").Buffer)
},{"buffer":2,"create-hash/md5":132}],193:[function(require,module,exports){
(function (Buffer){
var parseKeys = require('parse-asn1');
var mgf = require('./mgf');
var xor = require('./xor');
var bn = require('bn.js');
var crt = require('browserify-rsa');
var createHash = require('create-hash');
var withPublic = require('./withPublic');
module.exports = function privateDecrypt(private_key, enc, reverse) {
var padding;
if (private_key.padding) {
padding = private_key.padding;
} else if (reverse) {
padding = 1;
} else {
padding = 4;
}
var key = parseKeys(private_key);
var k = key.modulus.byteLength();
if (enc.length > k || new bn(enc).cmp(key.modulus) >= 0) {
throw new Error('decryption error');
}
var msg;
if (reverse) {
msg = withPublic(new bn(enc), key);
} else {
msg = crt(enc, key);
}
var zBuffer = new Buffer(k - msg.length);
zBuffer.fill(0);
msg = Buffer.concat([zBuffer, msg], k);
if (padding === 4) {
return oaep(key, msg);
} else if (padding === 1) {
return pkcs1(key, msg, reverse);
} else if (padding === 3) {
return msg;
} else {
throw new Error('unknown padding');
}
};
function oaep(key, msg){
var n = key.modulus;
var k = key.modulus.byteLength();
var mLen = msg.length;
var iHash = createHash('sha1').update(new Buffer('')).digest();
var hLen = iHash.length;
var hLen2 = 2 * hLen;
if (msg[0] !== 0) {
throw new Error('decryption error');
}
var maskedSeed = msg.slice(1, hLen + 1);
var maskedDb = msg.slice(hLen + 1);
var seed = xor(maskedSeed, mgf(maskedDb, hLen));
var db = xor(maskedDb, mgf(seed, k - hLen - 1));
if (compare(iHash, db.slice(0, hLen))) {
throw new Error('decryption error');
}
var i = hLen;
while (db[i] === 0) {
i++;
}
if (db[i++] !== 1) {
throw new Error('decryption error');
}
return db.slice(i);
}
function pkcs1(key, msg, reverse){
var p1 = msg.slice(0, 2);
var i = 2;
var status = 0;
while (msg[i++] !== 0) {
if (i >= msg.length) {
status++;
break;
}
}
var ps = msg.slice(2, i - 1);
var p2 = msg.slice(i - 1, i);
if ((p1.toString('hex') !== '0002' && !reverse) || (p1.toString('hex') !== '0001' && reverse)){
status++;
}
if (ps.length < 8) {
status++;
}
if (status) {
throw new Error('decryption error');
}
return msg.slice(i);
}
function compare(a, b){
a = new Buffer(a);
b = new Buffer(b);
var dif = 0;
var len = a.length;
if (a.length !== b.length) {
dif++;
len = Math.min(a.length, b.length);
}
var i = -1;
while (++i < len) {
dif += (a[i] ^ b[i]);
}
return dif;
}
}).call(this,require("buffer").Buffer)
},{"./mgf":153,"./withPublic":195,"./xor":196,"bn.js":154,"browserify-rsa":155,"buffer":2,"create-hash":130,"parse-asn1":159}],194:[function(require,module,exports){
(function (Buffer){
var parseKeys = require('parse-asn1');
var randomBytes = require('randombytes');
var createHash = require('create-hash');
var mgf = require('./mgf');
var xor = require('./xor');
var bn = require('bn.js');
var withPublic = require('./withPublic');
var crt = require('browserify-rsa');
var constants = {
RSA_PKCS1_OAEP_PADDING: 4,
RSA_PKCS1_PADDIN: 1,
RSA_NO_PADDING: 3
};
module.exports = function publicEncrypt(public_key, msg, reverse) {
var padding;
if (public_key.padding) {
padding = public_key.padding;
} else if (reverse) {
padding = 1;
} else {
padding = 4;
}
var key = parseKeys(public_key);
var paddedMsg;
if (padding === 4) {
paddedMsg = oaep(key, msg);
} else if (padding === 1) {
paddedMsg = pkcs1(key, msg, reverse);
} else if (padding === 3) {
paddedMsg = new bn(msg);
if (paddedMsg.cmp(key.modulus) >= 0) {
throw new Error('data too long for modulus');
}
} else {
throw new Error('unknown padding');
}
if (reverse) {
return crt(paddedMsg, key);
} else {
return withPublic(paddedMsg, key);
}
};
function oaep(key, msg){
var k = key.modulus.byteLength();
var mLen = msg.length;
var iHash = createHash('sha1').update(new Buffer('')).digest();
var hLen = iHash.length;
var hLen2 = 2 * hLen;
if (mLen > k - hLen2 - 2) {
throw new Error('message too long');
}
var ps = new Buffer(k - mLen - hLen2 - 2);
ps.fill(0);
var dblen = k - hLen - 1;
var seed = randomBytes(hLen);
var maskedDb = xor(Buffer.concat([iHash, ps, new Buffer([1]), msg], dblen), mgf(seed, dblen));
var maskedSeed = xor(seed, mgf(maskedDb, hLen));
return new bn(Buffer.concat([new Buffer([0]), maskedSeed, maskedDb], k));
}
function pkcs1(key, msg, reverse){
var mLen = msg.length;
var k = key.modulus.byteLength();
if (mLen > k - 11) {
throw new Error('message too long');
}
var ps;
if (reverse) {
ps = new Buffer(k - mLen - 3);
ps.fill(0xff);
} else {
ps = nonZero(k - mLen - 3);
}
return new bn(Buffer.concat([new Buffer([0, reverse?1:2]), ps, new Buffer([0]), msg], k));
}
function nonZero(len, crypto) {
var out = new Buffer(len);
var i = 0;
var cache = randomBytes(len*2);
var cur = 0;
var num;
while (i < len) {
if (cur === cache.length) {
cache = randomBytes(len*2);
cur = 0;
}
num = cache[cur++];
if (num) {
out[i++] = num;
}
}
return out;
}
}).call(this,require("buffer").Buffer)
},{"./mgf":153,"./withPublic":195,"./xor":196,"bn.js":154,"browserify-rsa":155,"buffer":2,"create-hash":130,"parse-asn1":159,"randombytes":197}],195:[function(require,module,exports){
(function (Buffer){
var bn = require('bn.js');
function withPublic(paddedMsg, key) {
return new Buffer(paddedMsg
.toRed(bn.mont(key.modulus))
.redPow(new bn(key.publicExponent))
.fromRed()
.toArray());
}
module.exports = withPublic;
}).call(this,require("buffer").Buffer)
},{"bn.js":154,"buffer":2}],196:[function(require,module,exports){
module.exports = function xor(a, b) {
var len = a.length;
var i = -1;
while (++i < len) {
a[i] ^= b[i];
}
return a
};
},{}],197:[function(require,module,exports){
(function (process,global,Buffer){
'use strict'
function oldBrowser () {
throw new Error('secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11')
}
var crypto = global.crypto || global.msCrypto
if (crypto && crypto.getRandomValues) {
module.exports = randomBytes
} else {
module.exports = oldBrowser
}
function randomBytes (size, cb) {
// phantomjs needs to throw
if (size > 65536) throw new Error('requested too many random bytes')
// in case browserify isn't using the Uint8Array version
var rawBytes = new global.Uint8Array(size)
// This will not work in older browsers.
// See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
if (size > 0) { // getRandomValues fails on IE if size == 0
crypto.getRandomValues(rawBytes)
}
// phantomjs doesn't like a buffer being passed here
var bytes = new Buffer(rawBytes.buffer)
if (typeof cb === 'function') {
return process.nextTick(function () {
cb(null, bytes)
})
}
return bytes
}
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer)
},{"_process":201,"buffer":2}],198:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
function EventEmitter() {
this._events = this._events || {};
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
EventEmitter.defaultMaxListeners = 10;
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function(n) {
if (!isNumber(n) || n < 0 || isNaN(n))
throw TypeError('n must be a positive number');
this._maxListeners = n;
return this;
};
EventEmitter.prototype.emit = function(type) {
var er, handler, len, args, i, listeners;
if (!this._events)
this._events = {};
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events.error ||
(isObject(this._events.error) && !this._events.error.length)) {
er = arguments[1];
if (er instanceof Error) {
throw er; // Unhandled 'error' event
}
throw TypeError('Uncaught, unspecified "error" event.');
}
}
handler = this._events[type];
if (isUndefined(handler))
return false;
if (isFunction(handler)) {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
args = Array.prototype.slice.call(arguments, 1);
handler.apply(this, args);
}
} else if (isObject(handler)) {
args = Array.prototype.slice.call(arguments, 1);
listeners = handler.slice();
len = listeners.length;
for (i = 0; i < len; i++)
listeners[i].apply(this, args);
}
return true;
};
EventEmitter.prototype.addListener = function(type, listener) {
var m;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events)
this._events = {};
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (this._events.newListener)
this.emit('newListener', type,
isFunction(listener.listener) ?
listener.listener : listener);
if (!this._events[type])
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
else if (isObject(this._events[type]))
// If we've already got an array, just append.
this._events[type].push(listener);
else
// Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener];
// Check for listener leak
if (isObject(this._events[type]) && !this._events[type].warned) {
if (!isUndefined(this._maxListeners)) {
m = this._maxListeners;
} else {
m = EventEmitter.defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
if (typeof console.trace === 'function') {
// not supported in IE 10
console.trace();
}
}
}
return this;
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.once = function(type, listener) {
if (!isFunction(listener))
throw TypeError('listener must be a function');
var fired = false;
function g() {
this.removeListener(type, g);
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
g.listener = listener;
this.on(type, g);
return this;
};
// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function(type, listener) {
var list, position, length, i;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events || !this._events[type])
return this;
list = this._events[type];
length = list.length;
position = -1;
if (list === listener ||
(isFunction(list.listener) && list.listener === listener)) {
delete this._events[type];
if (this._events.removeListener)
this.emit('removeListener', type, listener);
} else if (isObject(list)) {
for (i = length; i-- > 0;) {
if (list[i] === listener ||
(list[i].listener && list[i].listener === listener)) {
position = i;
break;
}
}
if (position < 0)
return this;
if (list.length === 1) {
list.length = 0;
delete this._events[type];
} else {
list.splice(position, 1);
}
if (this._events.removeListener)
this.emit('removeListener', type, listener);
}
return this;
};
EventEmitter.prototype.removeAllListeners = function(type) {
var key, listeners;
if (!this._events)
return this;
// not listening for removeListener, no need to emit
if (!this._events.removeListener) {
if (arguments.length === 0)
this._events = {};
else if (this._events[type])
delete this._events[type];
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
for (key in this._events) {
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = {};
return this;
}
listeners = this._events[type];
if (isFunction(listeners)) {
this.removeListener(type, listeners);
} else if (listeners) {
// LIFO order
while (listeners.length)
this.removeListener(type, listeners[listeners.length - 1]);
}
delete this._events[type];
return this;
};
EventEmitter.prototype.listeners = function(type) {
var ret;
if (!this._events || !this._events[type])
ret = [];
else if (isFunction(this._events[type]))
ret = [this._events[type]];
else
ret = this._events[type].slice();
return ret;
};
EventEmitter.prototype.listenerCount = function(type) {
if (this._events) {
var evlistener = this._events[type];
if (isFunction(evlistener))
return 1;
else if (evlistener)
return evlistener.length;
}
return 0;
};
EventEmitter.listenerCount = function(emitter, type) {
return emitter.listenerCount(type);
};
function isFunction(arg) {
return typeof arg === 'function';
}
function isNumber(arg) {
return typeof arg === 'number';
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
function isUndefined(arg) {
return arg === void 0;
}
},{}],199:[function(require,module,exports){
if (typeof Object.create === 'function') {
// implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
} else {
// old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}
},{}],200:[function(require,module,exports){
/**
* Determine if an object is Buffer
*
* Author: Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* License: MIT
*
* `npm install is-buffer`
*/
module.exports = function (obj) {
return !!(obj != null &&
(obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor)
(obj.constructor &&
typeof obj.constructor.isBuffer === 'function' &&
obj.constructor.isBuffer(obj))
))
}
},{}],201:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = setTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
clearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
setTimeout(drainQueue, 0);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
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');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
},{}],202:[function(require,module,exports){
module.exports = require("./lib/_stream_duplex.js")
},{"./lib/_stream_duplex.js":203}],203:[function(require,module,exports){
// a duplex stream is just a stream that is both readable and writable.
// Since JS doesn't have multiple prototypal inheritance, this class
// prototypally inherits from Readable, and then parasitically from
// Writable.
'use strict';
/*<replacement>*/
var objectKeys = Object.keys || function (obj) {
var keys = [];
for (var key in obj) {
keys.push(key);
}return keys;
};
/*</replacement>*/
module.exports = Duplex;
/*<replacement>*/
var processNextTick = require('process-nextick-args');
/*</replacement>*/
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
var Readable = require('./_stream_readable');
var Writable = require('./_stream_writable');
util.inherits(Duplex, Readable);
var keys = objectKeys(Writable.prototype);
for (var v = 0; v < keys.length; v++) {
var method = keys[v];
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
}
function Duplex(options) {
if (!(this instanceof Duplex)) return new Duplex(options);
Readable.call(this, options);
Writable.call(this, options);
if (options && options.readable === false) this.readable = false;
if (options && options.writable === false) this.writable = false;
this.allowHalfOpen = true;
if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
this.once('end', onend);
}
// the no-half-open enforcer
function onend() {
// if we allow half-open state, or if the writable side ended,
// then we're ok.
if (this.allowHalfOpen || this._writableState.ended) return;
// no more data can be written.
// But allow more writes to happen in this tick.
processNextTick(onEndNT, this);
}
function onEndNT(self) {
self.end();
}
function forEach(xs, f) {
for (var i = 0, l = xs.length; i < l; i++) {
f(xs[i], i);
}
}
},{"./_stream_readable":205,"./_stream_writable":207,"core-util-is":208,"inherits":199,"process-nextick-args":210}],204:[function(require,module,exports){
// a passthrough stream.
// basically just the most minimal sort of Transform stream.
// Every written chunk gets output as-is.
'use strict';
module.exports = PassThrough;
var Transform = require('./_stream_transform');
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
util.inherits(PassThrough, Transform);
function PassThrough(options) {
if (!(this instanceof PassThrough)) return new PassThrough(options);
Transform.call(this, options);
}
PassThrough.prototype._transform = function (chunk, encoding, cb) {
cb(null, chunk);
};
},{"./_stream_transform":206,"core-util-is":208,"inherits":199}],205:[function(require,module,exports){
(function (process){
'use strict';
module.exports = Readable;
/*<replacement>*/
var processNextTick = require('process-nextick-args');
/*</replacement>*/
/*<replacement>*/
var isArray = require('isarray');
/*</replacement>*/
/*<replacement>*/
var Buffer = require('buffer').Buffer;
/*</replacement>*/
Readable.ReadableState = ReadableState;
var EE = require('events');
/*<replacement>*/
var EElistenerCount = function (emitter, type) {
return emitter.listeners(type).length;
};
/*</replacement>*/
/*<replacement>*/
var Stream;
(function () {
try {
Stream = require('st' + 'ream');
} catch (_) {} finally {
if (!Stream) Stream = require('events').EventEmitter;
}
})();
/*</replacement>*/
var Buffer = require('buffer').Buffer;
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
/*<replacement>*/
var debugUtil = require('util');
var debug = undefined;
if (debugUtil && debugUtil.debuglog) {
debug = debugUtil.debuglog('stream');
} else {
debug = function () {};
}
/*</replacement>*/
var StringDecoder;
util.inherits(Readable, Stream);
var Duplex;
function ReadableState(options, stream) {
Duplex = Duplex || require('./_stream_duplex');
options = options || {};
// object stream flag. Used to make read(n) ignore n and to
// make all the buffer merging and length checks go away
this.objectMode = !!options.objectMode;
if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
// the point at which it stops calling _read() to fill the buffer
// Note: 0 is a valid value, means "don't call _read preemptively ever"
var hwm = options.highWaterMark;
var defaultHwm = this.objectMode ? 16 : 16 * 1024;
this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
// cast to ints.
this.highWaterMark = ~ ~this.highWaterMark;
this.buffer = [];
this.length = 0;
this.pipes = null;
this.pipesCount = 0;
this.flowing = null;
this.ended = false;
this.endEmitted = false;
this.reading = false;
// a flag to be able to tell if the onwrite cb is called immediately,
// or on a later tick. We set this to true at first, because any
// actions that shouldn't happen until "later" should generally also
// not happen before the first write call.
this.sync = true;
// whenever we return null, then we set a flag to say
// that we're awaiting a 'readable' event emission.
this.needReadable = false;
this.emittedReadable = false;
this.readableListening = false;
this.resumeScheduled = false;
// Crypto is kind of old and crusty. Historically, its default string
// encoding is 'binary' so we have to make this configurable.
// Everything else in the universe uses 'utf8', though.
this.defaultEncoding = options.defaultEncoding || 'utf8';
// when piping, we only care about 'readable' events that happen
// after read()ing all the bytes and not getting any pushback.
this.ranOut = false;
// the number of writers that are awaiting a drain event in .pipe()s
this.awaitDrain = 0;
// if true, a maybeReadMore has been scheduled
this.readingMore = false;
this.decoder = null;
this.encoding = null;
if (options.encoding) {
if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
this.decoder = new StringDecoder(options.encoding);
this.encoding = options.encoding;
}
}
var Duplex;
function Readable(options) {
Duplex = Duplex || require('./_stream_duplex');
if (!(this instanceof Readable)) return new Readable(options);
this._readableState = new ReadableState(options, this);
// legacy
this.readable = true;
if (options && typeof options.read === 'function') this._read = options.read;
Stream.call(this);
}
// Manually shove something into the read() buffer.
// This returns true if the highWaterMark has not been hit yet,
// similar to how Writable.write() returns true if you should
// write() some more.
Readable.prototype.push = function (chunk, encoding) {
var state = this._readableState;
if (!state.objectMode && typeof chunk === 'string') {
encoding = encoding || state.defaultEncoding;
if (encoding !== state.encoding) {
chunk = new Buffer(chunk, encoding);
encoding = '';
}
}
return readableAddChunk(this, state, chunk, encoding, false);
};
// Unshift should *always* be something directly out of read()
Readable.prototype.unshift = function (chunk) {
var state = this._readableState;
return readableAddChunk(this, state, chunk, '', true);
};
Readable.prototype.isPaused = function () {
return this._readableState.flowing === false;
};
function readableAddChunk(stream, state, chunk, encoding, addToFront) {
var er = chunkInvalid(state, chunk);
if (er) {
stream.emit('error', er);
} else if (chunk === null) {
state.reading = false;
onEofChunk(stream, state);
} else if (state.objectMode || chunk && chunk.length > 0) {
if (state.ended && !addToFront) {
var e = new Error('stream.push() after EOF');
stream.emit('error', e);
} else if (state.endEmitted && addToFront) {
var e = new Error('stream.unshift() after end event');
stream.emit('error', e);
} else {
var skipAdd;
if (state.decoder && !addToFront && !encoding) {
chunk = state.decoder.write(chunk);
skipAdd = !state.objectMode && chunk.length === 0;
}
if (!addToFront) state.reading = false;
// Don't add to the buffer if we've decoded to an empty string chunk and
// we're not in object mode
if (!skipAdd) {
// if we want the data now, just emit it.
if (state.flowing && state.length === 0 && !state.sync) {
stream.emit('data', chunk);
stream.read(0);
} else {
// update the buffer info.
state.length += state.objectMode ? 1 : chunk.length;
if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
if (state.needReadable) emitReadable(stream);
}
}
maybeReadMore(stream, state);
}
} else if (!addToFront) {
state.reading = false;
}
return needMoreData(state);
}
// if it's past the high water mark, we can push in some more.
// Also, if we have no data yet, we can stand some
// more bytes. This is to work around cases where hwm=0,
// such as the repl. Also, if the push() triggered a
// readable event, and the user called read(largeNumber) such that
// needReadable was set, then we ought to push more, so that another
// 'readable' event will be triggered.
function needMoreData(state) {
return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
}
// backwards compatibility.
Readable.prototype.setEncoding = function (enc) {
if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
this._readableState.decoder = new StringDecoder(enc);
this._readableState.encoding = enc;
return this;
};
// Don't raise the hwm > 8MB
var MAX_HWM = 0x800000;
function computeNewHighWaterMark(n) {
if (n >= MAX_HWM) {
n = MAX_HWM;
} else {
// Get the next highest power of 2
n--;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
n++;
}
return n;
}
function howMuchToRead(n, state) {
if (state.length === 0 && state.ended) return 0;
if (state.objectMode) return n === 0 ? 0 : 1;
if (n === null || isNaN(n)) {
// only flow one buffer at a time
if (state.flowing && state.buffer.length) return state.buffer[0].length;else return state.length;
}
if (n <= 0) return 0;
// If we're asking for more than the target buffer level,
// then raise the water mark. Bump up to the next highest
// power of 2, to prevent increasing it excessively in tiny
// amounts.
if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
// don't have that much. return null, unless we've ended.
if (n > state.length) {
if (!state.ended) {
state.needReadable = true;
return 0;
} else {
return state.length;
}
}
return n;
}
// you can override either this method, or the async _read(n) below.
Readable.prototype.read = function (n) {
debug('read', n);
var state = this._readableState;
var nOrig = n;
if (typeof n !== 'number' || n > 0) state.emittedReadable = false;
// if we're doing read(0) to trigger a readable event, but we
// already have a bunch of data in the buffer, then just trigger
// the 'readable' event and move on.
if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
debug('read: emitReadable', state.length, state.ended);
if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
return null;
}
n = howMuchToRead(n, state);
// if we've ended, and we're now clear, then finish it up.
if (n === 0 && state.ended) {
if (state.length === 0) endReadable(this);
return null;
}
// All the actual chunk generation logic needs to be
// *below* the call to _read. The reason is that in certain
// synthetic stream cases, such as passthrough streams, _read
// may be a completely synchronous operation which may change
// the state of the read buffer, providing enough data when
// before there was *not* enough.
//
// So, the steps are:
// 1. Figure out what the state of things will be after we do
// a read from the buffer.
//
// 2. If that resulting state will trigger a _read, then call _read.
// Note that this may be asynchronous, or synchronous. Yes, it is
// deeply ugly to write APIs this way, but that still doesn't mean
// that the Readable class should behave improperly, as streams are
// designed to be sync/async agnostic.
// Take note if the _read call is sync or async (ie, if the read call
// has returned yet), so that we know whether or not it's safe to emit
// 'readable' etc.
//
// 3. Actually pull the requested chunks out of the buffer and return.
// if we need a readable event, then we need to do some reading.
var doRead = state.needReadable;
debug('need readable', doRead);
// if we currently have less than the highWaterMark, then also read some
if (state.length === 0 || state.length - n < state.highWaterMark) {
doRead = true;
debug('length less than watermark', doRead);
}
// however, if we've ended, then there's no point, and if we're already
// reading, then it's unnecessary.
if (state.ended || state.reading) {
doRead = false;
debug('reading or ended', doRead);
}
if (doRead) {
debug('do read');
state.reading = true;
state.sync = true;
// if the length is currently zero, then we *need* a readable event.
if (state.length === 0) state.needReadable = true;
// call internal read method
this._read(state.highWaterMark);
state.sync = false;
}
// If _read pushed data synchronously, then `reading` will be false,
// and we need to re-evaluate how much data we can return to the user.
if (doRead && !state.reading) n = howMuchToRead(nOrig, state);
var ret;
if (n > 0) ret = fromList(n, state);else ret = null;
if (ret === null) {
state.needReadable = true;
n = 0;
}
state.length -= n;
// If we have nothing in the buffer, then we want to know
// as soon as we *do* get something into the buffer.
if (state.length === 0 && !state.ended) state.needReadable = true;
// If we tried to read() past the EOF, then emit end on the next tick.
if (nOrig !== n && state.ended && state.length === 0) endReadable(this);
if (ret !== null) this.emit('data', ret);
return ret;
};
function chunkInvalid(state, chunk) {
var er = null;
if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
er = new TypeError('Invalid non-string/buffer chunk');
}
return er;
}
function onEofChunk(stream, state) {
if (state.ended) return;
if (state.decoder) {
var chunk = state.decoder.end();
if (chunk && chunk.length) {
state.buffer.push(chunk);
state.length += state.objectMode ? 1 : chunk.length;
}
}
state.ended = true;
// emit 'readable' now to make sure it gets picked up.
emitReadable(stream);
}
// Don't emit readable right away in sync mode, because this can trigger
// another read() call => stack overflow. This way, it might trigger
// a nextTick recursion warning, but that's not so bad.
function emitReadable(stream) {
var state = stream._readableState;
state.needReadable = false;
if (!state.emittedReadable) {
debug('emitReadable', state.flowing);
state.emittedReadable = true;
if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);
}
}
function emitReadable_(stream) {
debug('emit readable');
stream.emit('readable');
flow(stream);
}
// at this point, the user has presumably seen the 'readable' event,
// and called read() to consume some data. that may have triggered
// in turn another _read(n) call, in which case reading = true if
// it's in progress.
// However, if we're not ended, or reading, and the length < hwm,
// then go ahead and try to read some more preemptively.
function maybeReadMore(stream, state) {
if (!state.readingMore) {
state.readingMore = true;
processNextTick(maybeReadMore_, stream, state);
}
}
function maybeReadMore_(stream, state) {
var len = state.length;
while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
debug('maybeReadMore read 0');
stream.read(0);
if (len === state.length)
// didn't get any data, stop spinning.
break;else len = state.length;
}
state.readingMore = false;
}
// abstract method. to be overridden in specific implementation classes.
// call cb(er, data) where data is <= n in length.
// for virtual (non-string, non-buffer) streams, "length" is somewhat
// arbitrary, and perhaps not very meaningful.
Readable.prototype._read = function (n) {
this.emit('error', new Error('not implemented'));
};
Readable.prototype.pipe = function (dest, pipeOpts) {
var src = this;
var state = this._readableState;
switch (state.pipesCount) {
case 0:
state.pipes = dest;
break;
case 1:
state.pipes = [state.pipes, dest];
break;
default:
state.pipes.push(dest);
break;
}
state.pipesCount += 1;
debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
var endFn = doEnd ? onend : cleanup;
if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);
dest.on('unpipe', onunpipe);
function onunpipe(readable) {
debug('onunpipe');
if (readable === src) {
cleanup();
}
}
function onend() {
debug('onend');
dest.end();
}
// when the dest drains, it reduces the awaitDrain counter
// on the source. This would be more elegant with a .once()
// handler in flow(), but adding and removing repeatedly is
// too slow.
var ondrain = pipeOnDrain(src);
dest.on('drain', ondrain);
var cleanedUp = false;
function cleanup() {
debug('cleanup');
// cleanup event handlers once the pipe is broken
dest.removeListener('close', onclose);
dest.removeListener('finish', onfinish);
dest.removeListener('drain', ondrain);
dest.removeListener('error', onerror);
dest.removeListener('unpipe', onunpipe);
src.removeListener('end', onend);
src.removeListener('end', cleanup);
src.removeListener('data', ondata);
cleanedUp = true;
// if the reader is waiting for a drain event from this
// specific writer, then it would cause it to never start
// flowing again.
// So, if this is awaiting a drain, then we just call it now.
// If we don't know, then assume that we are waiting for one.
if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
}
src.on('data', ondata);
function ondata(chunk) {
debug('ondata');
var ret = dest.write(chunk);
if (false === ret) {
// If the user unpiped during `dest.write()`, it is possible
// to get stuck in a permanently paused state if that write
// also returned false.
if (state.pipesCount === 1 && state.pipes[0] === dest && src.listenerCount('data') === 1 && !cleanedUp) {
debug('false write response, pause', src._readableState.awaitDrain);
src._readableState.awaitDrain++;
}
src.pause();
}
}
// if the dest has an error, then stop piping into it.
// however, don't suppress the throwing behavior for this.
function onerror(er) {
debug('onerror', er);
unpipe();
dest.removeListener('error', onerror);
if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
}
// This is a brutally ugly hack to make sure that our error handler
// is attached before any userland ones. NEVER DO THIS.
if (!dest._events || !dest._events.error) dest.on('error', onerror);else if (isArray(dest._events.error)) dest._events.error.unshift(onerror);else dest._events.error = [onerror, dest._events.error];
// Both close and finish should trigger unpipe, but only once.
function onclose() {
dest.removeListener('finish', onfinish);
unpipe();
}
dest.once('close', onclose);
function onfinish() {
debug('onfinish');
dest.removeListener('close', onclose);
unpipe();
}
dest.once('finish', onfinish);
function unpipe() {
debug('unpipe');
src.unpipe(dest);
}
// tell the dest that it's being piped to
dest.emit('pipe', src);
// start the flow if it hasn't been started already.
if (!state.flowing) {
debug('pipe resume');
src.resume();
}
return dest;
};
function pipeOnDrain(src) {
return function () {
var state = src._readableState;
debug('pipeOnDrain', state.awaitDrain);
if (state.awaitDrain) state.awaitDrain--;
if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
state.flowing = true;
flow(src);
}
};
}
Readable.prototype.unpipe = function (dest) {
var state = this._readableState;
// if we're not piping anywhere, then do nothing.
if (state.pipesCount === 0) return this;
// just one destination. most common case.
if (state.pipesCount === 1) {
// passed in one, but it's not the right one.
if (dest && dest !== state.pipes) return this;
if (!dest) dest = state.pipes;
// got a match.
state.pipes = null;
state.pipesCount = 0;
state.flowing = false;
if (dest) dest.emit('unpipe', this);
return this;
}
// slow case. multiple pipe destinations.
if (!dest) {
// remove all.
var dests = state.pipes;
var len = state.pipesCount;
state.pipes = null;
state.pipesCount = 0;
state.flowing = false;
for (var _i = 0; _i < len; _i++) {
dests[_i].emit('unpipe', this);
}return this;
}
// try to find the right one.
var i = indexOf(state.pipes, dest);
if (i === -1) return this;
state.pipes.splice(i, 1);
state.pipesCount -= 1;
if (state.pipesCount === 1) state.pipes = state.pipes[0];
dest.emit('unpipe', this);
return this;
};
// set up data events if they are asked for
// Ensure readable listeners eventually get something
Readable.prototype.on = function (ev, fn) {
var res = Stream.prototype.on.call(this, ev, fn);
// If listening to data, and it has not explicitly been paused,
// then call resume to start the flow of data on the next tick.
if (ev === 'data' && false !== this._readableState.flowing) {
this.resume();
}
if (ev === 'readable' && !this._readableState.endEmitted) {
var state = this._readableState;
if (!state.readableListening) {
state.readableListening = true;
state.emittedReadable = false;
state.needReadable = true;
if (!state.reading) {
processNextTick(nReadingNextTick, this);
} else if (state.length) {
emitReadable(this, state);
}
}
}
return res;
};
Readable.prototype.addListener = Readable.prototype.on;
function nReadingNextTick(self) {
debug('readable nexttick read 0');
self.read(0);
}
// pause() and resume() are remnants of the legacy readable stream API
// If the user uses them, then switch into old mode.
Readable.prototype.resume = function () {
var state = this._readableState;
if (!state.flowing) {
debug('resume');
state.flowing = true;
resume(this, state);
}
return this;
};
function resume(stream, state) {
if (!state.resumeScheduled) {
state.resumeScheduled = true;
processNextTick(resume_, stream, state);
}
}
function resume_(stream, state) {
if (!state.reading) {
debug('resume read 0');
stream.read(0);
}
state.resumeScheduled = false;
stream.emit('resume');
flow(stream);
if (state.flowing && !state.reading) stream.read(0);
}
Readable.prototype.pause = function () {
debug('call pause flowing=%j', this._readableState.flowing);
if (false !== this._readableState.flowing) {
debug('pause');
this._readableState.flowing = false;
this.emit('pause');
}
return this;
};
function flow(stream) {
var state = stream._readableState;
debug('flow', state.flowing);
if (state.flowing) {
do {
var chunk = stream.read();
} while (null !== chunk && state.flowing);
}
}
// wrap an old-style stream as the async data source.
// This is *not* part of the readable stream interface.
// It is an ugly unfortunate mess of history.
Readable.prototype.wrap = function (stream) {
var state = this._readableState;
var paused = false;
var self = this;
stream.on('end', function () {
debug('wrapped end');
if (state.decoder && !state.ended) {
var chunk = state.decoder.end();
if (chunk && chunk.length) self.push(chunk);
}
self.push(null);
});
stream.on('data', function (chunk) {
debug('wrapped data');
if (state.decoder) chunk = state.decoder.write(chunk);
// don't skip over falsy values in objectMode
if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
var ret = self.push(chunk);
if (!ret) {
paused = true;
stream.pause();
}
});
// proxy all the other methods.
// important when wrapping filters and duplexes.
for (var i in stream) {
if (this[i] === undefined && typeof stream[i] === 'function') {
this[i] = function (method) {
return function () {
return stream[method].apply(stream, arguments);
};
}(i);
}
}
// proxy certain important events.
var events = ['error', 'close', 'destroy', 'pause', 'resume'];
forEach(events, function (ev) {
stream.on(ev, self.emit.bind(self, ev));
});
// when we try to consume some more bytes, simply unpause the
// underlying stream.
self._read = function (n) {
debug('wrapped _read', n);
if (paused) {
paused = false;
stream.resume();
}
};
return self;
};
// exposed for testing purposes only.
Readable._fromList = fromList;
// Pluck off n bytes from an array of buffers.
// Length is the combined lengths of all the buffers in the list.
function fromList(n, state) {
var list = state.buffer;
var length = state.length;
var stringMode = !!state.decoder;
var objectMode = !!state.objectMode;
var ret;
// nothing in the list, definitely empty.
if (list.length === 0) return null;
if (length === 0) ret = null;else if (objectMode) ret = list.shift();else if (!n || n >= length) {
// read it all, truncate the array.
if (stringMode) ret = list.join('');else if (list.length === 1) ret = list[0];else ret = Buffer.concat(list, length);
list.length = 0;
} else {
// read just some of it.
if (n < list[0].length) {
// just take a part of the first list item.
// slice is the same for buffers and strings.
var buf = list[0];
ret = buf.slice(0, n);
list[0] = buf.slice(n);
} else if (n === list[0].length) {
// first list is a perfect match
ret = list.shift();
} else {
// complex case.
// we have enough to cover it, but it spans past the first buffer.
if (stringMode) ret = '';else ret = new Buffer(n);
var c = 0;
for (var i = 0, l = list.length; i < l && c < n; i++) {
var buf = list[0];
var cpy = Math.min(n - c, buf.length);
if (stringMode) ret += buf.slice(0, cpy);else buf.copy(ret, c, 0, cpy);
if (cpy < buf.length) list[0] = buf.slice(cpy);else list.shift();
c += cpy;
}
}
}
return ret;
}
function endReadable(stream) {
var state = stream._readableState;
// If we get here before consuming all the bytes, then that is a
// bug in node. Should never happen.
if (state.length > 0) throw new Error('endReadable called on non-empty stream');
if (!state.endEmitted) {
state.ended = true;
processNextTick(endReadableNT, state, stream);
}
}
function endReadableNT(state, stream) {
// Check that we didn't get one last unshift.
if (!state.endEmitted && state.length === 0) {
state.endEmitted = true;
stream.readable = false;
stream.emit('end');
}
}
function forEach(xs, f) {
for (var i = 0, l = xs.length; i < l; i++) {
f(xs[i], i);
}
}
function indexOf(xs, x) {
for (var i = 0, l = xs.length; i < l; i++) {
if (xs[i] === x) return i;
}
return -1;
}
}).call(this,require('_process'))
},{"./_stream_duplex":203,"_process":201,"buffer":2,"core-util-is":208,"events":198,"inherits":199,"isarray":209,"process-nextick-args":210,"string_decoder/":217,"util":1}],206:[function(require,module,exports){
// a transform stream is a readable/writable stream where you do
// something with the data. Sometimes it's called a "filter",
// but that's not a great name for it, since that implies a thing where
// some bits pass through, and others are simply ignored. (That would
// be a valid example of a transform, of course.)
//
// While the output is causally related to the input, it's not a
// necessarily symmetric or synchronous transformation. For example,
// a zlib stream might take multiple plain-text writes(), and then
// emit a single compressed chunk some time in the future.
//
// Here's how this works:
//
// The Transform stream has all the aspects of the readable and writable
// stream classes. When you write(chunk), that calls _write(chunk,cb)
// internally, and returns false if there's a lot of pending writes
// buffered up. When you call read(), that calls _read(n) until
// there's enough pending readable data buffered up.
//
// In a transform stream, the written data is placed in a buffer. When
// _read(n) is called, it transforms the queued up data, calling the
// buffered _write cb's as it consumes chunks. If consuming a single
// written chunk would result in multiple output chunks, then the first
// outputted bit calls the readcb, and subsequent chunks just go into
// the read buffer, and will cause it to emit 'readable' if necessary.
//
// This way, back-pressure is actually determined by the reading side,
// since _read has to be called to start processing a new chunk. However,
// a pathological inflate type of transform can cause excessive buffering
// here. For example, imagine a stream where every byte of input is
// interpreted as an integer from 0-255, and then results in that many
// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in
// 1kb of data being output. In this case, you could write a very small
// amount of input, and end up with a very large amount of output. In
// such a pathological inflating mechanism, there'd be no way to tell
// the system to stop doing the transform. A single 4MB write could
// cause the system to run out of memory.
//
// However, even in such a pathological case, only a single written chunk
// would be consumed, and then the rest would wait (un-transformed) until
// the results of the previous transformed chunk were consumed.
'use strict';
module.exports = Transform;
var Duplex = require('./_stream_duplex');
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
util.inherits(Transform, Duplex);
function TransformState(stream) {
this.afterTransform = function (er, data) {
return afterTransform(stream, er, data);
};
this.needTransform = false;
this.transforming = false;
this.writecb = null;
this.writechunk = null;
this.writeencoding = null;
}
function afterTransform(stream, er, data) {
var ts = stream._transformState;
ts.transforming = false;
var cb = ts.writecb;
if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));
ts.writechunk = null;
ts.writecb = null;
if (data !== null && data !== undefined) stream.push(data);
cb(er);
var rs = stream._readableState;
rs.reading = false;
if (rs.needReadable || rs.length < rs.highWaterMark) {
stream._read(rs.highWaterMark);
}
}
function Transform(options) {
if (!(this instanceof Transform)) return new Transform(options);
Duplex.call(this, options);
this._transformState = new TransformState(this);
// when the writable side finishes, then flush out anything remaining.
var stream = this;
// start out asking for a readable event once data is transformed.
this._readableState.needReadable = true;
// we have implemented the _read method, and done the other things
// that Readable wants before the first _read call, so unset the
// sync guard flag.
this._readableState.sync = false;
if (options) {
if (typeof options.transform === 'function') this._transform = options.transform;
if (typeof options.flush === 'function') this._flush = options.flush;
}
this.once('prefinish', function () {
if (typeof this._flush === 'function') this._flush(function (er) {
done(stream, er);
});else done(stream);
});
}
Transform.prototype.push = function (chunk, encoding) {
this._transformState.needTransform = false;
return Duplex.prototype.push.call(this, chunk, encoding);
};
// This is the part where you do stuff!
// override this function in implementation classes.
// 'chunk' is an input chunk.
//
// Call `push(newChunk)` to pass along transformed output
// to the readable side. You may call 'push' zero or more times.
//
// Call `cb(err)` when you are done with this chunk. If you pass
// an error, then that'll put the hurt on the whole operation. If you
// never call cb(), then you'll never get another chunk.
Transform.prototype._transform = function (chunk, encoding, cb) {
throw new Error('not implemented');
};
Transform.prototype._write = function (chunk, encoding, cb) {
var ts = this._transformState;
ts.writecb = cb;
ts.writechunk = chunk;
ts.writeencoding = encoding;
if (!ts.transforming) {
var rs = this._readableState;
if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
}
};
// Doesn't matter what the args are here.
// _transform does all the work.
// That we got here means that the readable side wants more data.
Transform.prototype._read = function (n) {
var ts = this._transformState;
if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
ts.transforming = true;
this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
} else {
// mark that we need a transform, so that any data that comes in
// will get processed, now that we've asked for it.
ts.needTransform = true;
}
};
function done(stream, er) {
if (er) return stream.emit('error', er);
// if there's nothing in the write buffer, then that means
// that nothing more will ever be provided
var ws = stream._writableState;
var ts = stream._transformState;
if (ws.length) throw new Error('calling transform done when ws.length != 0');
if (ts.transforming) throw new Error('calling transform done when still transforming');
return stream.push(null);
}
},{"./_stream_duplex":203,"core-util-is":208,"inherits":199}],207:[function(require,module,exports){
(function (process){
// A bit simpler than readable streams.
// Implement an async ._write(chunk, encoding, cb), and it'll handle all
// the drain event emission and buffering.
'use strict';
module.exports = Writable;
/*<replacement>*/
var processNextTick = require('process-nextick-args');
/*</replacement>*/
/*<replacement>*/
var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
/*</replacement>*/
/*<replacement>*/
var Buffer = require('buffer').Buffer;
/*</replacement>*/
Writable.WritableState = WritableState;
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
/*<replacement>*/
var internalUtil = {
deprecate: require('util-deprecate')
};
/*</replacement>*/
/*<replacement>*/
var Stream;
(function () {
try {
Stream = require('st' + 'ream');
} catch (_) {} finally {
if (!Stream) Stream = require('events').EventEmitter;
}
})();
/*</replacement>*/
var Buffer = require('buffer').Buffer;
util.inherits(Writable, Stream);
function nop() {}
function WriteReq(chunk, encoding, cb) {
this.chunk = chunk;
this.encoding = encoding;
this.callback = cb;
this.next = null;
}
var Duplex;
function WritableState(options, stream) {
Duplex = Duplex || require('./_stream_duplex');
options = options || {};
// object stream flag to indicate whether or not this stream
// contains buffers or objects.
this.objectMode = !!options.objectMode;
if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
// the point at which write() starts returning false
// Note: 0 is a valid value, means that we always return false if
// the entire buffer is not flushed immediately on write()
var hwm = options.highWaterMark;
var defaultHwm = this.objectMode ? 16 : 16 * 1024;
this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
// cast to ints.
this.highWaterMark = ~ ~this.highWaterMark;
this.needDrain = false;
// at the start of calling end()
this.ending = false;
// when end() has been called, and returned
this.ended = false;
// when 'finish' is emitted
this.finished = false;
// should we decode strings into buffers before passing to _write?
// this is here so that some node-core streams can optimize string
// handling at a lower level.
var noDecode = options.decodeStrings === false;
this.decodeStrings = !noDecode;
// Crypto is kind of old and crusty. Historically, its default string
// encoding is 'binary' so we have to make this configurable.
// Everything else in the universe uses 'utf8', though.
this.defaultEncoding = options.defaultEncoding || 'utf8';
// not an actual buffer we keep track of, but a measurement
// of how much we're waiting to get pushed to some underlying
// socket or file.
this.length = 0;
// a flag to see when we're in the middle of a write.
this.writing = false;
// when true all writes will be buffered until .uncork() call
this.corked = 0;
// a flag to be able to tell if the onwrite cb is called immediately,
// or on a later tick. We set this to true at first, because any
// actions that shouldn't happen until "later" should generally also
// not happen before the first write call.
this.sync = true;
// a flag to know if we're processing previously buffered items, which
// may call the _write() callback in the same tick, so that we don't
// end up in an overlapped onwrite situation.
this.bufferProcessing = false;
// the callback that's passed to _write(chunk,cb)
this.onwrite = function (er) {
onwrite(stream, er);
};
// the callback that the user supplies to write(chunk,encoding,cb)
this.writecb = null;
// the amount that is being written when _write is called.
this.writelen = 0;
this.bufferedRequest = null;
this.lastBufferedRequest = null;
// number of pending user-supplied write callbacks
// this must be 0 before 'finish' can be emitted
this.pendingcb = 0;
// emit prefinish if the only thing we're waiting for is _write cbs
// This is relevant for synchronous Transform streams
this.prefinished = false;
// True if the error was already emitted and should not be thrown again
this.errorEmitted = false;
// count buffered requests
this.bufferedRequestCount = 0;
// create the two objects needed to store the corked requests
// they are not a linked list, as no new elements are inserted in there
this.corkedRequestsFree = new CorkedRequest(this);
this.corkedRequestsFree.next = new CorkedRequest(this);
}
WritableState.prototype.getBuffer = function writableStateGetBuffer() {
var current = this.bufferedRequest;
var out = [];
while (current) {
out.push(current);
current = current.next;
}
return out;
};
(function () {
try {
Object.defineProperty(WritableState.prototype, 'buffer', {
get: internalUtil.deprecate(function () {
return this.getBuffer();
}, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
});
} catch (_) {}
})();
var Duplex;
function Writable(options) {
Duplex = Duplex || require('./_stream_duplex');
// Writable ctor is applied to Duplexes, though they're not
// instanceof Writable, they're instanceof Readable.
if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);
this._writableState = new WritableState(options, this);
// legacy.
this.writable = true;
if (options) {
if (typeof options.write === 'function') this._write = options.write;
if (typeof options.writev === 'function') this._writev = options.writev;
}
Stream.call(this);
}
// Otherwise people can pipe Writable streams, which is just wrong.
Writable.prototype.pipe = function () {
this.emit('error', new Error('Cannot pipe. Not readable.'));
};
function writeAfterEnd(stream, cb) {
var er = new Error('write after end');
// TODO: defer error events consistently everywhere, not just the cb
stream.emit('error', er);
processNextTick(cb, er);
}
// If we get something that is not a buffer, string, null, or undefined,
// and we're not in objectMode, then that's an error.
// Otherwise stream chunks are all considered to be of length=1, and the
// watermarks determine how many objects to keep in the buffer, rather than
// how many bytes or characters.
function validChunk(stream, state, chunk, cb) {
var valid = true;
if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
var er = new TypeError('Invalid non-string/buffer chunk');
stream.emit('error', er);
processNextTick(cb, er);
valid = false;
}
return valid;
}
Writable.prototype.write = function (chunk, encoding, cb) {
var state = this._writableState;
var ret = false;
if (typeof encoding === 'function') {
cb = encoding;
encoding = null;
}
if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
if (typeof cb !== 'function') cb = nop;
if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {
state.pendingcb++;
ret = writeOrBuffer(this, state, chunk, encoding, cb);
}
return ret;
};
Writable.prototype.cork = function () {
var state = this._writableState;
state.corked++;
};
Writable.prototype.uncork = function () {
var state = this._writableState;
if (state.corked) {
state.corked--;
if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
}
};
Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
// node::ParseEncoding() requires lower case.
if (typeof encoding === 'string') encoding = encoding.toLowerCase();
if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
this._writableState.defaultEncoding = encoding;
};
function decodeChunk(state, chunk, encoding) {
if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
chunk = new Buffer(chunk, encoding);
}
return chunk;
}
// if we're already writing something, then just put this
// in the queue, and wait our turn. Otherwise, call _write
// If we return false, then we need a drain event, so set that flag.
function writeOrBuffer(stream, state, chunk, encoding, cb) {
chunk = decodeChunk(state, chunk, encoding);
if (Buffer.isBuffer(chunk)) encoding = 'buffer';
var len = state.objectMode ? 1 : chunk.length;
state.length += len;
var ret = state.length < state.highWaterMark;
// we must ensure that previous needDrain will not be reset to false.
if (!ret) state.needDrain = true;
if (state.writing || state.corked) {
var last = state.lastBufferedRequest;
state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
if (last) {
last.next = state.lastBufferedRequest;
} else {
state.bufferedRequest = state.lastBufferedRequest;
}
state.bufferedRequestCount += 1;
} else {
doWrite(stream, state, false, len, chunk, encoding, cb);
}
return ret;
}
function doWrite(stream, state, writev, len, chunk, encoding, cb) {
state.writelen = len;
state.writecb = cb;
state.writing = true;
state.sync = true;
if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
state.sync = false;
}
function onwriteError(stream, state, sync, er, cb) {
--state.pendingcb;
if (sync) processNextTick(cb, er);else cb(er);
stream._writableState.errorEmitted = true;
stream.emit('error', er);
}
function onwriteStateUpdate(state) {
state.writing = false;
state.writecb = null;
state.length -= state.writelen;
state.writelen = 0;
}
function onwrite(stream, er) {
var state = stream._writableState;
var sync = state.sync;
var cb = state.writecb;
onwriteStateUpdate(state);
if (er) onwriteError(stream, state, sync, er, cb);else {
// Check if we're actually ready to finish, but don't emit yet
var finished = needFinish(state);
if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
clearBuffer(stream, state);
}
if (sync) {
/*<replacement>*/
asyncWrite(afterWrite, stream, state, finished, cb);
/*</replacement>*/
} else {
afterWrite(stream, state, finished, cb);
}
}
}
function afterWrite(stream, state, finished, cb) {
if (!finished) onwriteDrain(stream, state);
state.pendingcb--;
cb();
finishMaybe(stream, state);
}
// Must force callback to be called on nextTick, so that we don't
// emit 'drain' before the write() consumer gets the 'false' return
// value, and has a chance to attach a 'drain' listener.
function onwriteDrain(stream, state) {
if (state.length === 0 && state.needDrain) {
state.needDrain = false;
stream.emit('drain');
}
}
// if there's something in the buffer waiting, then process it
function clearBuffer(stream, state) {
state.bufferProcessing = true;
var entry = state.bufferedRequest;
if (stream._writev && entry && entry.next) {
// Fast case, write everything using _writev()
var l = state.bufferedRequestCount;
var buffer = new Array(l);
var holder = state.corkedRequestsFree;
holder.entry = entry;
var count = 0;
while (entry) {
buffer[count] = entry;
entry = entry.next;
count += 1;
}
doWrite(stream, state, true, state.length, buffer, '', holder.finish);
// doWrite is always async, defer these to save a bit of time
// as the hot path ends with doWrite
state.pendingcb++;
state.lastBufferedRequest = null;
state.corkedRequestsFree = holder.next;
holder.next = null;
} else {
// Slow case, write chunks one-by-one
while (entry) {
var chunk = entry.chunk;
var encoding = entry.encoding;
var cb = entry.callback;
var len = state.objectMode ? 1 : chunk.length;
doWrite(stream, state, false, len, chunk, encoding, cb);
entry = entry.next;
// if we didn't call the onwrite immediately, then
// it means that we need to wait until it does.
// also, that means that the chunk and cb are currently
// being processed, so move the buffer counter past them.
if (state.writing) {
break;
}
}
if (entry === null) state.lastBufferedRequest = null;
}
state.bufferedRequestCount = 0;
state.bufferedRequest = entry;
state.bufferProcessing = false;
}
Writable.prototype._write = function (chunk, encoding, cb) {
cb(new Error('not implemented'));
};
Writable.prototype._writev = null;
Writable.prototype.end = function (chunk, encoding, cb) {
var state = this._writableState;
if (typeof chunk === 'function') {
cb = chunk;
chunk = null;
encoding = null;
} else if (typeof encoding === 'function') {
cb = encoding;
encoding = null;
}
if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
// .end() fully uncorks
if (state.corked) {
state.corked = 1;
this.uncork();
}
// ignore unnecessary end() calls.
if (!state.ending && !state.finished) endWritable(this, state, cb);
};
function needFinish(state) {
return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
}
function prefinish(stream, state) {
if (!state.prefinished) {
state.prefinished = true;
stream.emit('prefinish');
}
}
function finishMaybe(stream, state) {
var need = needFinish(state);
if (need) {
if (state.pendingcb === 0) {
prefinish(stream, state);
state.finished = true;
stream.emit('finish');
} else {
prefinish(stream, state);
}
}
return need;
}
function endWritable(stream, state, cb) {
state.ending = true;
finishMaybe(stream, state);
if (cb) {
if (state.finished) processNextTick(cb);else stream.once('finish', cb);
}
state.ended = true;
stream.writable = false;
}
// It seems a linked list but it is not
// there will be only 2 of these for each stream
function CorkedRequest(state) {
var _this = this;
this.next = null;
this.entry = null;
this.finish = function (err) {
var entry = _this.entry;
_this.entry = null;
while (entry) {
var cb = entry.callback;
state.pendingcb--;
cb(err);
entry = entry.next;
}
if (state.corkedRequestsFree) {
state.corkedRequestsFree.next = _this;
} else {
state.corkedRequestsFree = _this;
}
};
}
}).call(this,require('_process'))
},{"./_stream_duplex":203,"_process":201,"buffer":2,"core-util-is":208,"events":198,"inherits":199,"process-nextick-args":210,"util-deprecate":211}],208:[function(require,module,exports){
(function (Buffer){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(arg) {
if (Array.isArray) {
return Array.isArray(arg);
}
return objectToString(arg) === '[object Array]';
}
exports.isArray = isArray;
function isBoolean(arg) {
return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;
function isNull(arg) {
return arg === null;
}
exports.isNull = isNull;
function isNullOrUndefined(arg) {
return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;
function isNumber(arg) {
return typeof arg === 'number';
}
exports.isNumber = isNumber;
function isString(arg) {
return typeof arg === 'string';
}
exports.isString = isString;
function isSymbol(arg) {
return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;
function isUndefined(arg) {
return arg === void 0;
}
exports.isUndefined = isUndefined;
function isRegExp(re) {
return objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;
function isDate(d) {
return objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
function isError(e) {
return (objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;
function isFunction(arg) {
return typeof arg === 'function';
}
exports.isFunction = isFunction;
function isPrimitive(arg) {
return arg === null ||
typeof arg === 'boolean' ||
typeof arg === 'number' ||
typeof arg === 'string' ||
typeof arg === 'symbol' || // ES6 symbol
typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;
exports.isBuffer = Buffer.isBuffer;
function objectToString(o) {
return Object.prototype.toString.call(o);
}
}).call(this,{"isBuffer":require("../../../../insert-module-globals/node_modules/is-buffer/index.js")})
},{"../../../../insert-module-globals/node_modules/is-buffer/index.js":200}],209:[function(require,module,exports){
arguments[4][5][0].apply(exports,arguments)
},{"dup":5}],210:[function(require,module,exports){
(function (process){
'use strict';
if (!process.version ||
process.version.indexOf('v0.') === 0 ||
process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
module.exports = nextTick;
} else {
module.exports = process.nextTick;
}
function nextTick(fn) {
var args = new Array(arguments.length - 1);
var i = 0;
while (i < args.length) {
args[i++] = arguments[i];
}
process.nextTick(function afterTick() {
fn.apply(null, args);
});
}
}).call(this,require('_process'))
},{"_process":201}],211:[function(require,module,exports){
(function (global){
/**
* Module exports.
*/
module.exports = deprecate;
/**
* Mark that a method should not be used.
* Returns a modified function which warns once by default.
*
* If `localStorage.noDeprecation = true` is set, then it is a no-op.
*
* If `localStorage.throwDeprecation = true` is set, then deprecated functions
* will throw an Error when invoked.
*
* If `localStorage.traceDeprecation = true` is set, then deprecated functions
* will invoke `console.trace()` instead of `console.error()`.
*
* @param {Function} fn - the function to deprecate
* @param {String} msg - the string to print to the console when `fn` is invoked
* @returns {Function} a new "deprecated" version of `fn`
* @api public
*/
function deprecate (fn, msg) {
if (config('noDeprecation')) {
return fn;
}
var warned = false;
function deprecated() {
if (!warned) {
if (config('throwDeprecation')) {
throw new Error(msg);
} else if (config('traceDeprecation')) {
console.trace(msg);
} else {
console.warn(msg);
}
warned = true;
}
return fn.apply(this, arguments);
}
return deprecated;
}
/**
* Checks `localStorage` for boolean values for the given `name`.
*
* @param {String} name
* @returns {Boolean}
* @api private
*/
function config (name) {
// accessing global.localStorage can trigger a DOMException in sandboxed iframes
try {
if (!global.localStorage) return false;
} catch (_) {
return false;
}
var val = global.localStorage[name];
if (null == val) return false;
return String(val).toLowerCase() === 'true';
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],212:[function(require,module,exports){
module.exports = require("./lib/_stream_passthrough.js")
},{"./lib/_stream_passthrough.js":204}],213:[function(require,module,exports){
(function (process){
var Stream = (function (){
try {
return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify
} catch(_){}
}());
exports = module.exports = require('./lib/_stream_readable.js');
exports.Stream = Stream || exports;
exports.Readable = exports;
exports.Writable = require('./lib/_stream_writable.js');
exports.Duplex = require('./lib/_stream_duplex.js');
exports.Transform = require('./lib/_stream_transform.js');
exports.PassThrough = require('./lib/_stream_passthrough.js');
if (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) {
module.exports = Stream;
}
}).call(this,require('_process'))
},{"./lib/_stream_duplex.js":203,"./lib/_stream_passthrough.js":204,"./lib/_stream_readable.js":205,"./lib/_stream_transform.js":206,"./lib/_stream_writable.js":207,"_process":201}],214:[function(require,module,exports){
module.exports = require("./lib/_stream_transform.js")
},{"./lib/_stream_transform.js":206}],215:[function(require,module,exports){
module.exports = require("./lib/_stream_writable.js")
},{"./lib/_stream_writable.js":207}],216:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
module.exports = Stream;
var EE = require('events').EventEmitter;
var inherits = require('inherits');
inherits(Stream, EE);
Stream.Readable = require('readable-stream/readable.js');
Stream.Writable = require('readable-stream/writable.js');
Stream.Duplex = require('readable-stream/duplex.js');
Stream.Transform = require('readable-stream/transform.js');
Stream.PassThrough = require('readable-stream/passthrough.js');
// Backwards-compat with node 0.4.x
Stream.Stream = Stream;
// old-style streams. Note that the pipe method (the only relevant
// part of this class) is overridden in the Readable class.
function Stream() {
EE.call(this);
}
Stream.prototype.pipe = function(dest, options) {
var source = this;
function ondata(chunk) {
if (dest.writable) {
if (false === dest.write(chunk) && source.pause) {
source.pause();
}
}
}
source.on('data', ondata);
function ondrain() {
if (source.readable && source.resume) {
source.resume();
}
}
dest.on('drain', ondrain);
// If the 'end' option is not supplied, dest.end() will be called when
// source gets the 'end' or 'close' events. Only dest.end() once.
if (!dest._isStdio && (!options || options.end !== false)) {
source.on('end', onend);
source.on('close', onclose);
}
var didOnEnd = false;
function onend() {
if (didOnEnd) return;
didOnEnd = true;
dest.end();
}
function onclose() {
if (didOnEnd) return;
didOnEnd = true;
if (typeof dest.destroy === 'function') dest.destroy();
}
// don't leave dangling pipes when there are errors.
function onerror(er) {
cleanup();
if (EE.listenerCount(this, 'error') === 0) {
throw er; // Unhandled stream error in pipe.
}
}
source.on('error', onerror);
dest.on('error', onerror);
// remove all the event listeners that were added.
function cleanup() {
source.removeListener('data', ondata);
dest.removeListener('drain', ondrain);
source.removeListener('end', onend);
source.removeListener('close', onclose);
source.removeListener('error', onerror);
dest.removeListener('error', onerror);
source.removeListener('end', cleanup);
source.removeListener('close', cleanup);
dest.removeListener('close', cleanup);
}
source.on('end', cleanup);
source.on('close', cleanup);
dest.on('close', cleanup);
dest.emit('pipe', source);
// Allow for unix-like usage: A.pipe(B).pipe(C)
return dest;
};
},{"events":198,"inherits":199,"readable-stream/duplex.js":202,"readable-stream/passthrough.js":212,"readable-stream/readable.js":213,"readable-stream/transform.js":214,"readable-stream/writable.js":215}],217:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var Buffer = require('buffer').Buffer;
var isBufferEncoding = Buffer.isEncoding
|| function(encoding) {
switch (encoding && encoding.toLowerCase()) {
case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
default: return false;
}
}
function assertEncoding(encoding) {
if (encoding && !isBufferEncoding(encoding)) {
throw new Error('Unknown encoding: ' + encoding);
}
}
// StringDecoder provides an interface for efficiently splitting a series of
// buffers into a series of JS strings without breaking apart multi-byte
// characters. CESU-8 is handled as part of the UTF-8 encoding.
//
// @TODO Handling all encodings inside a single object makes it very difficult
// to reason about this code, so it should be split up in the future.
// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
// points as used by CESU-8.
var StringDecoder = exports.StringDecoder = function(encoding) {
this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
assertEncoding(encoding);
switch (this.encoding) {
case 'utf8':
// CESU-8 represents each of Surrogate Pair by 3-bytes
this.surrogateSize = 3;
break;
case 'ucs2':
case 'utf16le':
// UTF-16 represents each of Surrogate Pair by 2-bytes
this.surrogateSize = 2;
this.detectIncompleteChar = utf16DetectIncompleteChar;
break;
case 'base64':
// Base-64 stores 3 bytes in 4 chars, and pads the remainder.
this.surrogateSize = 3;
this.detectIncompleteChar = base64DetectIncompleteChar;
break;
default:
this.write = passThroughWrite;
return;
}
// Enough space to store all bytes of a single character. UTF-8 needs 4
// bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
this.charBuffer = new Buffer(6);
// Number of bytes received for the current incomplete multi-byte character.
this.charReceived = 0;
// Number of bytes expected for the current incomplete multi-byte character.
this.charLength = 0;
};
// write decodes the given buffer and returns it as JS string that is
// guaranteed to not contain any partial multi-byte characters. Any partial
// character found at the end of the buffer is buffered up, and will be
// returned when calling write again with the remaining bytes.
//
// Note: Converting a Buffer containing an orphan surrogate to a String
// currently works, but converting a String to a Buffer (via `new Buffer`, or
// Buffer#write) will replace incomplete surrogates with the unicode
// replacement character. See https://codereview.chromium.org/121173009/ .
StringDecoder.prototype.write = function(buffer) {
var charStr = '';
// if our last write ended with an incomplete multibyte character
while (this.charLength) {
// determine how many remaining bytes this buffer has to offer for this char
var available = (buffer.length >= this.charLength - this.charReceived) ?
this.charLength - this.charReceived :
buffer.length;
// add the new bytes to the char buffer
buffer.copy(this.charBuffer, this.charReceived, 0, available);
this.charReceived += available;
if (this.charReceived < this.charLength) {
// still not enough chars in this buffer? wait for more ...
return '';
}
// remove bytes belonging to the current character from the buffer
buffer = buffer.slice(available, buffer.length);
// get the character that was split
charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
// CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
var charCode = charStr.charCodeAt(charStr.length - 1);
if (charCode >= 0xD800 && charCode <= 0xDBFF) {
this.charLength += this.surrogateSize;
charStr = '';
continue;
}
this.charReceived = this.charLength = 0;
// if there are no more bytes in this buffer, just emit our char
if (buffer.length === 0) {
return charStr;
}
break;
}
// determine and set charLength / charReceived
this.detectIncompleteChar(buffer);
var end = buffer.length;
if (this.charLength) {
// buffer the incomplete character bytes we got
buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
end -= this.charReceived;
}
charStr += buffer.toString(this.encoding, 0, end);
var end = charStr.length - 1;
var charCode = charStr.charCodeAt(end);
// CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
if (charCode >= 0xD800 && charCode <= 0xDBFF) {
var size = this.surrogateSize;
this.charLength += size;
this.charReceived += size;
this.charBuffer.copy(this.charBuffer, size, 0, size);
buffer.copy(this.charBuffer, 0, 0, size);
return charStr.substring(0, end);
}
// or just emit the charStr
return charStr;
};
// detectIncompleteChar determines if there is an incomplete UTF-8 character at
// the end of the given buffer. If so, it sets this.charLength to the byte
// length that character, and sets this.charReceived to the number of bytes
// that are available for this character.
StringDecoder.prototype.detectIncompleteChar = function(buffer) {
// determine how many bytes we have to check at the end of this buffer
var i = (buffer.length >= 3) ? 3 : buffer.length;
// Figure out if one of the last i bytes of our buffer announces an
// incomplete char.
for (; i > 0; i--) {
var c = buffer[buffer.length - i];
// See http://en.wikipedia.org/wiki/UTF-8#Description
// 110XXXXX
if (i == 1 && c >> 5 == 0x06) {
this.charLength = 2;
break;
}
// 1110XXXX
if (i <= 2 && c >> 4 == 0x0E) {
this.charLength = 3;
break;
}
// 11110XXX
if (i <= 3 && c >> 3 == 0x1E) {
this.charLength = 4;
break;
}
}
this.charReceived = i;
};
StringDecoder.prototype.end = function(buffer) {
var res = '';
if (buffer && buffer.length)
res = this.write(buffer);
if (this.charReceived) {
var cr = this.charReceived;
var buf = this.charBuffer;
var enc = this.encoding;
res += buf.slice(0, cr).toString(enc);
}
return res;
};
function passThroughWrite(buffer) {
return buffer.toString(this.encoding);
}
function utf16DetectIncompleteChar(buffer) {
this.charReceived = buffer.length % 2;
this.charLength = this.charReceived ? 2 : 0;
}
function base64DetectIncompleteChar(buffer) {
this.charReceived = buffer.length % 3;
this.charLength = this.charReceived ? 3 : 0;
}
},{"buffer":2}],218:[function(require,module,exports){
var indexOf = require('indexof');
var Object_keys = function (obj) {
if (Object.keys) return Object.keys(obj)
else {
var res = [];
for (var key in obj) res.push(key)
return res;
}
};
var forEach = function (xs, fn) {
if (xs.forEach) return xs.forEach(fn)
else for (var i = 0; i < xs.length; i++) {
fn(xs[i], i, xs);
}
};
var defineProp = (function() {
try {
Object.defineProperty({}, '_', {});
return function(obj, name, value) {
Object.defineProperty(obj, name, {
writable: true,
enumerable: false,
configurable: true,
value: value
})
};
} catch(e) {
return function(obj, name, value) {
obj[name] = value;
};
}
}());
var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function',
'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError',
'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError',
'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape',
'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape'];
function Context() {}
Context.prototype = {};
var Script = exports.Script = function NodeScript (code) {
if (!(this instanceof Script)) return new Script(code);
this.code = code;
};
Script.prototype.runInContext = function (context) {
if (!(context instanceof Context)) {
throw new TypeError("needs a 'context' argument.");
}
var iframe = document.createElement('iframe');
if (!iframe.style) iframe.style = {};
iframe.style.display = 'none';
document.body.appendChild(iframe);
var win = iframe.contentWindow;
var wEval = win.eval, wExecScript = win.execScript;
if (!wEval && wExecScript) {
// win.eval() magically appears when this is called in IE:
wExecScript.call(win, 'null');
wEval = win.eval;
}
forEach(Object_keys(context), function (key) {
win[key] = context[key];
});
forEach(globals, function (key) {
if (context[key]) {
win[key] = context[key];
}
});
var winKeys = Object_keys(win);
var res = wEval.call(win, this.code);
forEach(Object_keys(win), function (key) {
// Avoid copying circular objects like `top` and `window` by only
// updating existing context properties or new properties in the `win`
// that was only introduced after the eval.
if (key in context || indexOf(winKeys, key) === -1) {
context[key] = win[key];
}
});
forEach(globals, function (key) {
if (!(key in context)) {
defineProp(context, key, win[key]);
}
});
document.body.removeChild(iframe);
return res;
};
Script.prototype.runInThisContext = function () {
return eval(this.code); // maybe...
};
Script.prototype.runInNewContext = function (context) {
var ctx = Script.createContext(context);
var res = this.runInContext(ctx);
forEach(Object_keys(ctx), function (key) {
context[key] = ctx[key];
});
return res;
};
forEach(Object_keys(Script.prototype), function (name) {
exports[name] = Script[name] = function (code) {
var s = Script(code);
return s[name].apply(s, [].slice.call(arguments, 1));
};
});
exports.createScript = function (code) {
return exports.Script(code);
};
exports.createContext = Script.createContext = function (context) {
var copy = new Context();
if(typeof context === 'object') {
forEach(Object_keys(context), function (key) {
copy[key] = context[key];
});
}
return copy;
};
},{"indexof":219}],219:[function(require,module,exports){
var indexOf = [].indexOf;
module.exports = function(arr, obj){
if (indexOf) return arr.indexOf(obj);
for (var i = 0; i < arr.length; ++i) {
if (arr[i] === obj) return i;
}
return -1;
};
},{}],220:[function(require,module,exports){
/**
* Copyright (c) 2014-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.Immutable = factory());
}(this, function () { 'use strict';var SLICE$0 = Array.prototype.slice;
function createClass(ctor, superClass) {
if (superClass) {
ctor.prototype = Object.create(superClass.prototype);
}
ctor.prototype.constructor = ctor;
}
function Iterable(value) {
return isIterable(value) ? value : Seq(value);
}
createClass(KeyedIterable, Iterable);
function KeyedIterable(value) {
return isKeyed(value) ? value : KeyedSeq(value);
}
createClass(IndexedIterable, Iterable);
function IndexedIterable(value) {
return isIndexed(value) ? value : IndexedSeq(value);
}
createClass(SetIterable, Iterable);
function SetIterable(value) {
return isIterable(value) && !isAssociative(value) ? value : SetSeq(value);
}
function isIterable(maybeIterable) {
return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]);
}
function isKeyed(maybeKeyed) {
return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL]);
}
function isIndexed(maybeIndexed) {
return !!(maybeIndexed && maybeIndexed[IS_INDEXED_SENTINEL]);
}
function isAssociative(maybeAssociative) {
return isKeyed(maybeAssociative) || isIndexed(maybeAssociative);
}
function isOrdered(maybeOrdered) {
return !!(maybeOrdered && maybeOrdered[IS_ORDERED_SENTINEL]);
}
Iterable.isIterable = isIterable;
Iterable.isKeyed = isKeyed;
Iterable.isIndexed = isIndexed;
Iterable.isAssociative = isAssociative;
Iterable.isOrdered = isOrdered;
Iterable.Keyed = KeyedIterable;
Iterable.Indexed = IndexedIterable;
Iterable.Set = SetIterable;
var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@';
var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';
var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@';
var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';
// Used for setting prototype methods that IE8 chokes on.
var DELETE = 'delete';
// Constants describing the size of trie nodes.
var SHIFT = 5; // Resulted in best performance after ______?
var SIZE = 1 << SHIFT;
var MASK = SIZE - 1;
// A consistent shared value representing "not set" which equals nothing other
// than itself, and nothing that could be provided externally.
var NOT_SET = {};
// Boolean references, Rough equivalent of `bool &`.
var CHANGE_LENGTH = { value: false };
var DID_ALTER = { value: false };
function MakeRef(ref) {
ref.value = false;
return ref;
}
function SetRef(ref) {
ref && (ref.value = true);
}
// A function which returns a value representing an "owner" for transient writes
// to tries. The return value will only ever equal itself, and will not equal
// the return of any subsequent call of this function.
function OwnerID() {}
// http://jsperf.com/copy-array-inline
function arrCopy(arr, offset) {
offset = offset || 0;
var len = Math.max(0, arr.length - offset);
var newArr = new Array(len);
for (var ii = 0; ii < len; ii++) {
newArr[ii] = arr[ii + offset];
}
return newArr;
}
function ensureSize(iter) {
if (iter.size === undefined) {
iter.size = iter.__iterate(returnTrue);
}
return iter.size;
}
function wrapIndex(iter, index) {
// This implements "is array index" which the ECMAString spec defines as:
//
// A String property name P is an array index if and only if
// ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal
// to 2^321.
//
// http://www.ecma-international.org/ecma-262/6.0/#sec-array-exotic-objects
if (typeof index !== 'number') {
var uint32Index = index >>> 0; // N >>> 0 is shorthand for ToUint32
if ('' + uint32Index !== index || uint32Index === 4294967295) {
return NaN;
}
index = uint32Index;
}
return index < 0 ? ensureSize(iter) + index : index;
}
function returnTrue() {
return true;
}
function wholeSlice(begin, end, size) {
return (begin === 0 || (size !== undefined && begin <= -size)) &&
(end === undefined || (size !== undefined && end >= size));
}
function resolveBegin(begin, size) {
return resolveIndex(begin, size, 0);
}
function resolveEnd(end, size) {
return resolveIndex(end, size, size);
}
function resolveIndex(index, size, defaultIndex) {
return index === undefined ?
defaultIndex :
index < 0 ?
Math.max(0, size + index) :
size === undefined ?
index :
Math.min(size, index);
}
/* global Symbol */
var ITERATE_KEYS = 0;
var ITERATE_VALUES = 1;
var ITERATE_ENTRIES = 2;
var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
var FAUX_ITERATOR_SYMBOL = '@@iterator';
var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL;
function Iterator(next) {
this.next = next;
}
Iterator.prototype.toString = function() {
return '[Iterator]';
};
Iterator.KEYS = ITERATE_KEYS;
Iterator.VALUES = ITERATE_VALUES;
Iterator.ENTRIES = ITERATE_ENTRIES;
Iterator.prototype.inspect =
Iterator.prototype.toSource = function () { return this.toString(); }
Iterator.prototype[ITERATOR_SYMBOL] = function () {
return this;
};
function iteratorValue(type, k, v, iteratorResult) {
var value = type === 0 ? k : type === 1 ? v : [k, v];
iteratorResult ? (iteratorResult.value = value) : (iteratorResult = {
value: value, done: false
});
return iteratorResult;
}
function iteratorDone() {
return { value: undefined, done: true };
}
function hasIterator(maybeIterable) {
return !!getIteratorFn(maybeIterable);
}
function isIterator(maybeIterator) {
return maybeIterator && typeof maybeIterator.next === 'function';
}
function getIterator(iterable) {
var iteratorFn = getIteratorFn(iterable);
return iteratorFn && iteratorFn.call(iterable);
}
function getIteratorFn(iterable) {
var iteratorFn = iterable && (
(REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) ||
iterable[FAUX_ITERATOR_SYMBOL]
);
if (typeof iteratorFn === 'function') {
return iteratorFn;
}
}
function isArrayLike(value) {
return value && typeof value.length === 'number';
}
createClass(Seq, Iterable);
function Seq(value) {
return value === null || value === undefined ? emptySequence() :
isIterable(value) ? value.toSeq() : seqFromValue(value);
}
Seq.of = function(/*...values*/) {
return Seq(arguments);
};
Seq.prototype.toSeq = function() {
return this;
};
Seq.prototype.toString = function() {
return this.__toString('Seq {', '}');
};
Seq.prototype.cacheResult = function() {
if (!this._cache && this.__iterateUncached) {
this._cache = this.entrySeq().toArray();
this.size = this._cache.length;
}
return this;
};
// abstract __iterateUncached(fn, reverse)
Seq.prototype.__iterate = function(fn, reverse) {
return seqIterate(this, fn, reverse, true);
};
// abstract __iteratorUncached(type, reverse)
Seq.prototype.__iterator = function(type, reverse) {
return seqIterator(this, type, reverse, true);
};
createClass(KeyedSeq, Seq);
function KeyedSeq(value) {
return value === null || value === undefined ?
emptySequence().toKeyedSeq() :
isIterable(value) ?
(isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) :
keyedSeqFromValue(value);
}
KeyedSeq.prototype.toKeyedSeq = function() {
return this;
};
createClass(IndexedSeq, Seq);
function IndexedSeq(value) {
return value === null || value === undefined ? emptySequence() :
!isIterable(value) ? indexedSeqFromValue(value) :
isKeyed(value) ? value.entrySeq() : value.toIndexedSeq();
}
IndexedSeq.of = function(/*...values*/) {
return IndexedSeq(arguments);
};
IndexedSeq.prototype.toIndexedSeq = function() {
return this;
};
IndexedSeq.prototype.toString = function() {
return this.__toString('Seq [', ']');
};
IndexedSeq.prototype.__iterate = function(fn, reverse) {
return seqIterate(this, fn, reverse, false);
};
IndexedSeq.prototype.__iterator = function(type, reverse) {
return seqIterator(this, type, reverse, false);
};
createClass(SetSeq, Seq);
function SetSeq(value) {
return (
value === null || value === undefined ? emptySequence() :
!isIterable(value) ? indexedSeqFromValue(value) :
isKeyed(value) ? value.entrySeq() : value
).toSetSeq();
}
SetSeq.of = function(/*...values*/) {
return SetSeq(arguments);
};
SetSeq.prototype.toSetSeq = function() {
return this;
};
Seq.isSeq = isSeq;
Seq.Keyed = KeyedSeq;
Seq.Set = SetSeq;
Seq.Indexed = IndexedSeq;
var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@';
Seq.prototype[IS_SEQ_SENTINEL] = true;
createClass(ArraySeq, IndexedSeq);
function ArraySeq(array) {
this._array = array;
this.size = array.length;
}
ArraySeq.prototype.get = function(index, notSetValue) {
return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue;
};
ArraySeq.prototype.__iterate = function(fn, reverse) {
var array = this._array;
var maxIndex = array.length - 1;
for (var ii = 0; ii <= maxIndex; ii++) {
if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) {
return ii + 1;
}
}
return ii;
};
ArraySeq.prototype.__iterator = function(type, reverse) {
var array = this._array;
var maxIndex = array.length - 1;
var ii = 0;
return new Iterator(function()
{return ii > maxIndex ?
iteratorDone() :
iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++])}
);
};
createClass(ObjectSeq, KeyedSeq);
function ObjectSeq(object) {
var keys = Object.keys(object);
this._object = object;
this._keys = keys;
this.size = keys.length;
}
ObjectSeq.prototype.get = function(key, notSetValue) {
if (notSetValue !== undefined && !this.has(key)) {
return notSetValue;
}
return this._object[key];
};
ObjectSeq.prototype.has = function(key) {
return this._object.hasOwnProperty(key);
};
ObjectSeq.prototype.__iterate = function(fn, reverse) {
var object = this._object;
var keys = this._keys;
var maxIndex = keys.length - 1;
for (var ii = 0; ii <= maxIndex; ii++) {
var key = keys[reverse ? maxIndex - ii : ii];
if (fn(object[key], key, this) === false) {
return ii + 1;
}
}
return ii;
};
ObjectSeq.prototype.__iterator = function(type, reverse) {
var object = this._object;
var keys = this._keys;
var maxIndex = keys.length - 1;
var ii = 0;
return new Iterator(function() {
var key = keys[reverse ? maxIndex - ii : ii];
return ii++ > maxIndex ?
iteratorDone() :
iteratorValue(type, key, object[key]);
});
};
ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true;
createClass(IterableSeq, IndexedSeq);
function IterableSeq(iterable) {
this._iterable = iterable;
this.size = iterable.length || iterable.size;
}
IterableSeq.prototype.__iterateUncached = function(fn, reverse) {
if (reverse) {
return this.cacheResult().__iterate(fn, reverse);
}
var iterable = this._iterable;
var iterator = getIterator(iterable);
var iterations = 0;
if (isIterator(iterator)) {
var step;
while (!(step = iterator.next()).done) {
if (fn(step.value, iterations++, this) === false) {
break;
}
}
}
return iterations;
};
IterableSeq.prototype.__iteratorUncached = function(type, reverse) {
if (reverse) {
return this.cacheResult().__iterator(type, reverse);
}
var iterable = this._iterable;
var iterator = getIterator(iterable);
if (!isIterator(iterator)) {
return new Iterator(iteratorDone);
}
var iterations = 0;
return new Iterator(function() {
var step = iterator.next();
return step.done ? step : iteratorValue(type, iterations++, step.value);
});
};
createClass(IteratorSeq, IndexedSeq);
function IteratorSeq(iterator) {
this._iterator = iterator;
this._iteratorCache = [];
}
IteratorSeq.prototype.__iterateUncached = function(fn, reverse) {
if (reverse) {
return this.cacheResult().__iterate(fn, reverse);
}
var iterator = this._iterator;
var cache = this._iteratorCache;
var iterations = 0;
while (iterations < cache.length) {
if (fn(cache[iterations], iterations++, this) === false) {
return iterations;
}
}
var step;
while (!(step = iterator.next()).done) {
var val = step.value;
cache[iterations] = val;
if (fn(val, iterations++, this) === false) {
break;
}
}
return iterations;
};
IteratorSeq.prototype.__iteratorUncached = function(type, reverse) {
if (reverse) {
return this.cacheResult().__iterator(type, reverse);
}
var iterator = this._iterator;
var cache = this._iteratorCache;
var iterations = 0;
return new Iterator(function() {
if (iterations >= cache.length) {
var step = iterator.next();
if (step.done) {
return step;
}
cache[iterations] = step.value;
}
return iteratorValue(type, iterations, cache[iterations++]);
});
};
// # pragma Helper functions
function isSeq(maybeSeq) {
return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]);
}
var EMPTY_SEQ;
function emptySequence() {
return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([]));
}
function keyedSeqFromValue(value) {
var seq =
Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() :
isIterator(value) ? new IteratorSeq(value).fromEntrySeq() :
hasIterator(value) ? new IterableSeq(value).fromEntrySeq() :
typeof value === 'object' ? new ObjectSeq(value) :
undefined;
if (!seq) {
throw new TypeError(
'Expected Array or iterable object of [k, v] entries, '+
'or keyed object: ' + value
);
}
return seq;
}
function indexedSeqFromValue(value) {
var seq = maybeIndexedSeqFromValue(value);
if (!seq) {
throw new TypeError(
'Expected Array or iterable object of values: ' + value
);
}
return seq;
}
function seqFromValue(value) {
var seq = maybeIndexedSeqFromValue(value) ||
(typeof value === 'object' && new ObjectSeq(value));
if (!seq) {
throw new TypeError(
'Expected Array or iterable object of values, or keyed object: ' + value
);
}
return seq;
}
function maybeIndexedSeqFromValue(value) {
return (
isArrayLike(value) ? new ArraySeq(value) :
isIterator(value) ? new IteratorSeq(value) :
hasIterator(value) ? new IterableSeq(value) :
undefined
);
}
function seqIterate(seq, fn, reverse, useKeys) {
var cache = seq._cache;
if (cache) {
var maxIndex = cache.length - 1;
for (var ii = 0; ii <= maxIndex; ii++) {
var entry = cache[reverse ? maxIndex - ii : ii];
if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) {
return ii + 1;
}
}
return ii;
}
return seq.__iterateUncached(fn, reverse);
}
function seqIterator(seq, type, reverse, useKeys) {
var cache = seq._cache;
if (cache) {
var maxIndex = cache.length - 1;
var ii = 0;
return new Iterator(function() {
var entry = cache[reverse ? maxIndex - ii : ii];
return ii++ > maxIndex ?
iteratorDone() :
iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]);
});
}
return seq.__iteratorUncached(type, reverse);
}
function fromJS(json, converter) {
return converter ?
fromJSWith(converter, json, '', {'': json}) :
fromJSDefault(json);
}
function fromJSWith(converter, json, key, parentJSON) {
if (Array.isArray(json)) {
return converter.call(parentJSON, key, IndexedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)}));
}
if (isPlainObj(json)) {
return converter.call(parentJSON, key, KeyedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)}));
}
return json;
}
function fromJSDefault(json) {
if (Array.isArray(json)) {
return IndexedSeq(json).map(fromJSDefault).toList();
}
if (isPlainObj(json)) {
return KeyedSeq(json).map(fromJSDefault).toMap();
}
return json;
}
function isPlainObj(value) {
return value && (value.constructor === Object || value.constructor === undefined);
}
/**
* An extension of the "same-value" algorithm as [described for use by ES6 Map
* and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality)
*
* NaN is considered the same as NaN, however -0 and 0 are considered the same
* value, which is different from the algorithm described by
* [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
*
* This is extended further to allow Objects to describe the values they
* represent, by way of `valueOf` or `equals` (and `hashCode`).
*
* Note: because of this extension, the key equality of Immutable.Map and the
* value equality of Immutable.Set will differ from ES6 Map and Set.
*
* ### Defining custom values
*
* The easiest way to describe the value an object represents is by implementing
* `valueOf`. For example, `Date` represents a value by returning a unix
* timestamp for `valueOf`:
*
* var date1 = new Date(1234567890000); // Fri Feb 13 2009 ...
* var date2 = new Date(1234567890000);
* date1.valueOf(); // 1234567890000
* assert( date1 !== date2 );
* assert( Immutable.is( date1, date2 ) );
*
* Note: overriding `valueOf` may have other implications if you use this object
* where JavaScript expects a primitive, such as implicit string coercion.
*
* For more complex types, especially collections, implementing `valueOf` may
* not be performant. An alternative is to implement `equals` and `hashCode`.
*
* `equals` takes another object, presumably of similar type, and returns true
* if the it is equal. Equality is symmetrical, so the same result should be
* returned if this and the argument are flipped.
*
* assert( a.equals(b) === b.equals(a) );
*
* `hashCode` returns a 32bit integer number representing the object which will
* be used to determine how to store the value object in a Map or Set. You must
* provide both or neither methods, one must not exist without the other.
*
* Also, an important relationship between these methods must be upheld: if two
* values are equal, they *must* return the same hashCode. If the values are not
* equal, they might have the same hashCode; this is called a hash collision,
* and while undesirable for performance reasons, it is acceptable.
*
* if (a.equals(b)) {
* assert( a.hashCode() === b.hashCode() );
* }
*
* All Immutable collections implement `equals` and `hashCode`.
*
*/
function is(valueA, valueB) {
if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {
return true;
}
if (!valueA || !valueB) {
return false;
}
if (typeof valueA.valueOf === 'function' &&
typeof valueB.valueOf === 'function') {
valueA = valueA.valueOf();
valueB = valueB.valueOf();
if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {
return true;
}
if (!valueA || !valueB) {
return false;
}
}
if (typeof valueA.equals === 'function' &&
typeof valueB.equals === 'function' &&
valueA.equals(valueB)) {
return true;
}
return false;
}
function deepEqual(a, b) {
if (a === b) {
return true;
}
if (
!isIterable(b) ||
a.size !== undefined && b.size !== undefined && a.size !== b.size ||
a.__hash !== undefined && b.__hash !== undefined && a.__hash !== b.__hash ||
isKeyed(a) !== isKeyed(b) ||
isIndexed(a) !== isIndexed(b) ||
isOrdered(a) !== isOrdered(b)
) {
return false;
}
if (a.size === 0 && b.size === 0) {
return true;
}
var notAssociative = !isAssociative(a);
if (isOrdered(a)) {
var entries = a.entries();
return b.every(function(v, k) {
var entry = entries.next().value;
return entry && is(entry[1], v) && (notAssociative || is(entry[0], k));
}) && entries.next().done;
}
var flipped = false;
if (a.size === undefined) {
if (b.size === undefined) {
if (typeof a.cacheResult === 'function') {
a.cacheResult();
}
} else {
flipped = true;
var _ = a;
a = b;
b = _;
}
}
var allEqual = true;
var bSize = b.__iterate(function(v, k) {
if (notAssociative ? !a.has(v) :
flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) {
allEqual = false;
return false;
}
});
return allEqual && a.size === bSize;
}
createClass(Repeat, IndexedSeq);
function Repeat(value, times) {
if (!(this instanceof Repeat)) {
return new Repeat(value, times);
}
this._value = value;
this.size = times === undefined ? Infinity : Math.max(0, times);
if (this.size === 0) {
if (EMPTY_REPEAT) {
return EMPTY_REPEAT;
}
EMPTY_REPEAT = this;
}
}
Repeat.prototype.toString = function() {
if (this.size === 0) {
return 'Repeat []';
}
return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]';
};
Repeat.prototype.get = function(index, notSetValue) {
return this.has(index) ? this._value : notSetValue;
};
Repeat.prototype.includes = function(searchValue) {
return is(this._value, searchValue);
};
Repeat.prototype.slice = function(begin, end) {
var size = this.size;
return wholeSlice(begin, end, size) ? this :
new Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size));
};
Repeat.prototype.reverse = function() {
return this;
};
Repeat.prototype.indexOf = function(searchValue) {
if (is(this._value, searchValue)) {
return 0;
}
return -1;
};
Repeat.prototype.lastIndexOf = function(searchValue) {
if (is(this._value, searchValue)) {
return this.size;
}
return -1;
};
Repeat.prototype.__iterate = function(fn, reverse) {
for (var ii = 0; ii < this.size; ii++) {
if (fn(this._value, ii, this) === false) {
return ii + 1;
}
}
return ii;
};
Repeat.prototype.__iterator = function(type, reverse) {var this$0 = this;
var ii = 0;
return new Iterator(function()
{return ii < this$0.size ? iteratorValue(type, ii++, this$0._value) : iteratorDone()}
);
};
Repeat.prototype.equals = function(other) {
return other instanceof Repeat ?
is(this._value, other._value) :
deepEqual(other);
};
var EMPTY_REPEAT;
function invariant(condition, error) {
if (!condition) throw new Error(error);
}
createClass(Range, IndexedSeq);
function Range(start, end, step) {
if (!(this instanceof Range)) {
return new Range(start, end, step);
}
invariant(step !== 0, 'Cannot step a Range by 0');
start = start || 0;
if (end === undefined) {
end = Infinity;
}
step = step === undefined ? 1 : Math.abs(step);
if (end < start) {
step = -step;
}
this._start = start;
this._end = end;
this._step = step;
this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1);
if (this.size === 0) {
if (EMPTY_RANGE) {
return EMPTY_RANGE;
}
EMPTY_RANGE = this;
}
}
Range.prototype.toString = function() {
if (this.size === 0) {
return 'Range []';
}
return 'Range [ ' +
this._start + '...' + this._end +
(this._step !== 1 ? ' by ' + this._step : '') +
' ]';
};
Range.prototype.get = function(index, notSetValue) {
return this.has(index) ?
this._start + wrapIndex(this, index) * this._step :
notSetValue;
};
Range.prototype.includes = function(searchValue) {
var possibleIndex = (searchValue - this._start) / this._step;
return possibleIndex >= 0 &&
possibleIndex < this.size &&
possibleIndex === Math.floor(possibleIndex);
};
Range.prototype.slice = function(begin, end) {
if (wholeSlice(begin, end, this.size)) {
return this;
}
begin = resolveBegin(begin, this.size);
end = resolveEnd(end, this.size);
if (end <= begin) {
return new Range(0, 0);
}
return new Range(this.get(begin, this._end), this.get(end, this._end), this._step);
};
Range.prototype.indexOf = function(searchValue) {
var offsetValue = searchValue - this._start;
if (offsetValue % this._step === 0) {
var index = offsetValue / this._step;
if (index >= 0 && index < this.size) {
return index
}
}
return -1;
};
Range.prototype.lastIndexOf = function(searchValue) {
return this.indexOf(searchValue);
};
Range.prototype.__iterate = function(fn, reverse) {
var maxIndex = this.size - 1;
var step = this._step;
var value = reverse ? this._start + maxIndex * step : this._start;
for (var ii = 0; ii <= maxIndex; ii++) {
if (fn(value, ii, this) === false) {
return ii + 1;
}
value += reverse ? -step : step;
}
return ii;
};
Range.prototype.__iterator = function(type, reverse) {
var maxIndex = this.size - 1;
var step = this._step;
var value = reverse ? this._start + maxIndex * step : this._start;
var ii = 0;
return new Iterator(function() {
var v = value;
value += reverse ? -step : step;
return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v);
});
};
Range.prototype.equals = function(other) {
return other instanceof Range ?
this._start === other._start &&
this._end === other._end &&
this._step === other._step :
deepEqual(this, other);
};
var EMPTY_RANGE;
createClass(Collection, Iterable);
function Collection() {
throw TypeError('Abstract');
}
createClass(KeyedCollection, Collection);function KeyedCollection() {}
createClass(IndexedCollection, Collection);function IndexedCollection() {}
createClass(SetCollection, Collection);function SetCollection() {}
Collection.Keyed = KeyedCollection;
Collection.Indexed = IndexedCollection;
Collection.Set = SetCollection;
var imul =
typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 ?
Math.imul :
function imul(a, b) {
a = a | 0; // int
b = b | 0; // int
var c = a & 0xffff;
var d = b & 0xffff;
// Shift by 0 fixes the sign on the high part.
return (c * d) + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0) | 0; // int
};
// v8 has an optimization for storing 31-bit signed numbers.
// Values which have either 00 or 11 as the high order bits qualify.
// This function drops the highest order bit in a signed number, maintaining
// the sign bit.
function smi(i32) {
return ((i32 >>> 1) & 0x40000000) | (i32 & 0xBFFFFFFF);
}
function hash(o) {
if (o === false || o === null || o === undefined) {
return 0;
}
if (typeof o.valueOf === 'function') {
o = o.valueOf();
if (o === false || o === null || o === undefined) {
return 0;
}
}
if (o === true) {
return 1;
}
var type = typeof o;
if (type === 'number') {
if (o !== o || o === Infinity) {
return 0;
}
var h = o | 0;
if (h !== o) {
h ^= o * 0xFFFFFFFF;
}
while (o > 0xFFFFFFFF) {
o /= 0xFFFFFFFF;
h ^= o;
}
return smi(h);
}
if (type === 'string') {
return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o);
}
if (typeof o.hashCode === 'function') {
return o.hashCode();
}
if (type === 'object') {
return hashJSObj(o);
}
if (typeof o.toString === 'function') {
return hashString(o.toString());
}
throw new Error('Value type ' + type + ' cannot be hashed.');
}
function cachedHashString(string) {
var hash = stringHashCache[string];
if (hash === undefined) {
hash = hashString(string);
if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) {
STRING_HASH_CACHE_SIZE = 0;
stringHashCache = {};
}
STRING_HASH_CACHE_SIZE++;
stringHashCache[string] = hash;
}
return hash;
}
// http://jsperf.com/hashing-strings
function hashString(string) {
// This is the hash from JVM
// The hash code for a string is computed as
// s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1],
// where s[i] is the ith character of the string and n is the length of
// the string. We "mod" the result to make it between 0 (inclusive) and 2^31
// (exclusive) by dropping high bits.
var hash = 0;
for (var ii = 0; ii < string.length; ii++) {
hash = 31 * hash + string.charCodeAt(ii) | 0;
}
return smi(hash);
}
function hashJSObj(obj) {
var hash;
if (usingWeakMap) {
hash = weakMap.get(obj);
if (hash !== undefined) {
return hash;
}
}
hash = obj[UID_HASH_KEY];
if (hash !== undefined) {
return hash;
}
if (!canDefineProperty) {
hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY];
if (hash !== undefined) {
return hash;
}
hash = getIENodeHash(obj);
if (hash !== undefined) {
return hash;
}
}
hash = ++objHashUID;
if (objHashUID & 0x40000000) {
objHashUID = 0;
}
if (usingWeakMap) {
weakMap.set(obj, hash);
} else if (isExtensible !== undefined && isExtensible(obj) === false) {
throw new Error('Non-extensible objects are not allowed as keys.');
} else if (canDefineProperty) {
Object.defineProperty(obj, UID_HASH_KEY, {
'enumerable': false,
'configurable': false,
'writable': false,
'value': hash
});
} else if (obj.propertyIsEnumerable !== undefined &&
obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) {
// Since we can't define a non-enumerable property on the object
// we'll hijack one of the less-used non-enumerable properties to
// save our hash on it. Since this is a function it will not show up in
// `JSON.stringify` which is what we want.
obj.propertyIsEnumerable = function() {
return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments);
};
obj.propertyIsEnumerable[UID_HASH_KEY] = hash;
} else if (obj.nodeType !== undefined) {
// At this point we couldn't get the IE `uniqueID` to use as a hash
// and we couldn't use a non-enumerable property to exploit the
// dontEnum bug so we simply add the `UID_HASH_KEY` on the node
// itself.
obj[UID_HASH_KEY] = hash;
} else {
throw new Error('Unable to set a non-enumerable property on object.');
}
return hash;
}
// Get references to ES5 object methods.
var isExtensible = Object.isExtensible;
// True if Object.defineProperty works as expected. IE8 fails this test.
var canDefineProperty = (function() {
try {
Object.defineProperty({}, '@', {});
return true;
} catch (e) {
return false;
}
}());
// IE has a `uniqueID` property on DOM nodes. We can construct the hash from it
// and avoid memory leaks from the IE cloneNode bug.
function getIENodeHash(node) {
if (node && node.nodeType > 0) {
switch (node.nodeType) {
case 1: // Element
return node.uniqueID;
case 9: // Document
return node.documentElement && node.documentElement.uniqueID;
}
}
}
// If possible, use a WeakMap.
var usingWeakMap = typeof WeakMap === 'function';
var weakMap;
if (usingWeakMap) {
weakMap = new WeakMap();
}
var objHashUID = 0;
var UID_HASH_KEY = '__immutablehash__';
if (typeof Symbol === 'function') {
UID_HASH_KEY = Symbol(UID_HASH_KEY);
}
var STRING_HASH_CACHE_MIN_STRLEN = 16;
var STRING_HASH_CACHE_MAX_SIZE = 255;
var STRING_HASH_CACHE_SIZE = 0;
var stringHashCache = {};
function assertNotInfinite(size) {
invariant(
size !== Infinity,
'Cannot perform this action with an infinite size.'
);
}
createClass(Map, KeyedCollection);
// @pragma Construction
function Map(value) {
return value === null || value === undefined ? emptyMap() :
isMap(value) && !isOrdered(value) ? value :
emptyMap().withMutations(function(map ) {
var iter = KeyedIterable(value);
assertNotInfinite(iter.size);
iter.forEach(function(v, k) {return map.set(k, v)});
});
}
Map.of = function() {var keyValues = SLICE$0.call(arguments, 0);
return emptyMap().withMutations(function(map ) {
for (var i = 0; i < keyValues.length; i += 2) {
if (i + 1 >= keyValues.length) {
throw new Error('Missing value for key: ' + keyValues[i]);
}
map.set(keyValues[i], keyValues[i + 1]);
}
});
};
Map.prototype.toString = function() {
return this.__toString('Map {', '}');
};
// @pragma Access
Map.prototype.get = function(k, notSetValue) {
return this._root ?
this._root.get(0, undefined, k, notSetValue) :
notSetValue;
};
// @pragma Modification
Map.prototype.set = function(k, v) {
return updateMap(this, k, v);
};
Map.prototype.setIn = function(keyPath, v) {
return this.updateIn(keyPath, NOT_SET, function() {return v});
};
Map.prototype.remove = function(k) {
return updateMap(this, k, NOT_SET);
};
Map.prototype.deleteIn = function(keyPath) {
return this.updateIn(keyPath, function() {return NOT_SET});
};
Map.prototype.update = function(k, notSetValue, updater) {
return arguments.length === 1 ?
k(this) :
this.updateIn([k], notSetValue, updater);
};
Map.prototype.updateIn = function(keyPath, notSetValue, updater) {
if (!updater) {
updater = notSetValue;
notSetValue = undefined;
}
var updatedValue = updateInDeepMap(
this,
forceIterator(keyPath),
notSetValue,
updater
);
return updatedValue === NOT_SET ? undefined : updatedValue;
};
Map.prototype.clear = function() {
if (this.size === 0) {
return this;
}
if (this.__ownerID) {
this.size = 0;
this._root = null;
this.__hash = undefined;
this.__altered = true;
return this;
}
return emptyMap();
};
// @pragma Composition
Map.prototype.merge = function(/*...iters*/) {
return mergeIntoMapWith(this, undefined, arguments);
};
Map.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
return mergeIntoMapWith(this, merger, iters);
};
Map.prototype.mergeIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);
return this.updateIn(
keyPath,
emptyMap(),
function(m ) {return typeof m.merge === 'function' ?
m.merge.apply(m, iters) :
iters[iters.length - 1]}
);
};
Map.prototype.mergeDeep = function(/*...iters*/) {
return mergeIntoMapWith(this, deepMerger, arguments);
};
Map.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
return mergeIntoMapWith(this, deepMergerWith(merger), iters);
};
Map.prototype.mergeDeepIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);
return this.updateIn(
keyPath,
emptyMap(),
function(m ) {return typeof m.mergeDeep === 'function' ?
m.mergeDeep.apply(m, iters) :
iters[iters.length - 1]}
);
};
Map.prototype.sort = function(comparator) {
// Late binding
return OrderedMap(sortFactory(this, comparator));
};
Map.prototype.sortBy = function(mapper, comparator) {
// Late binding
return OrderedMap(sortFactory(this, comparator, mapper));
};
// @pragma Mutability
Map.prototype.withMutations = function(fn) {
var mutable = this.asMutable();
fn(mutable);
return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this;
};
Map.prototype.asMutable = function() {
return this.__ownerID ? this : this.__ensureOwner(new OwnerID());
};
Map.prototype.asImmutable = function() {
return this.__ensureOwner();
};
Map.prototype.wasAltered = function() {
return this.__altered;
};
Map.prototype.__iterator = function(type, reverse) {
return new MapIterator(this, type, reverse);
};
Map.prototype.__iterate = function(fn, reverse) {var this$0 = this;
var iterations = 0;
this._root && this._root.iterate(function(entry ) {
iterations++;
return fn(entry[1], entry[0], this$0);
}, reverse);
return iterations;
};
Map.prototype.__ensureOwner = function(ownerID) {
if (ownerID === this.__ownerID) {
return this;
}
if (!ownerID) {
this.__ownerID = ownerID;
this.__altered = false;
return this;
}
return makeMap(this.size, this._root, ownerID, this.__hash);
};
function isMap(maybeMap) {
return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]);
}
Map.isMap = isMap;
var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@';
var MapPrototype = Map.prototype;
MapPrototype[IS_MAP_SENTINEL] = true;
MapPrototype[DELETE] = MapPrototype.remove;
MapPrototype.removeIn = MapPrototype.deleteIn;
// #pragma Trie Nodes
function ArrayMapNode(ownerID, entries) {
this.ownerID = ownerID;
this.entries = entries;
}
ArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {
var entries = this.entries;
for (var ii = 0, len = entries.length; ii < len; ii++) {
if (is(key, entries[ii][0])) {
return entries[ii][1];
}
}
return notSetValue;
};
ArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
var removed = value === NOT_SET;
var entries = this.entries;
var idx = 0;
for (var len = entries.length; idx < len; idx++) {
if (is(key, entries[idx][0])) {
break;
}
}
var exists = idx < len;
if (exists ? entries[idx][1] === value : removed) {
return this;
}
SetRef(didAlter);
(removed || !exists) && SetRef(didChangeSize);
if (removed && entries.length === 1) {
return; // undefined
}
if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) {
return createNodes(ownerID, entries, key, value);
}
var isEditable = ownerID && ownerID === this.ownerID;
var newEntries = isEditable ? entries : arrCopy(entries);
if (exists) {
if (removed) {
idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());
} else {
newEntries[idx] = [key, value];
}
} else {
newEntries.push([key, value]);
}
if (isEditable) {
this.entries = newEntries;
return this;
}
return new ArrayMapNode(ownerID, newEntries);
};
function BitmapIndexedNode(ownerID, bitmap, nodes) {
this.ownerID = ownerID;
this.bitmap = bitmap;
this.nodes = nodes;
}
BitmapIndexedNode.prototype.get = function(shift, keyHash, key, notSetValue) {
if (keyHash === undefined) {
keyHash = hash(key);
}
var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK));
var bitmap = this.bitmap;
return (bitmap & bit) === 0 ? notSetValue :
this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue);
};
BitmapIndexedNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
if (keyHash === undefined) {
keyHash = hash(key);
}
var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
var bit = 1 << keyHashFrag;
var bitmap = this.bitmap;
var exists = (bitmap & bit) !== 0;
if (!exists && value === NOT_SET) {
return this;
}
var idx = popCount(bitmap & (bit - 1));
var nodes = this.nodes;
var node = exists ? nodes[idx] : undefined;
var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);
if (newNode === node) {
return this;
}
if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) {
return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode);
}
if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) {
return nodes[idx ^ 1];
}
if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) {
return newNode;
}
var isEditable = ownerID && ownerID === this.ownerID;
var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit;
var newNodes = exists ? newNode ?
setIn(nodes, idx, newNode, isEditable) :
spliceOut(nodes, idx, isEditable) :
spliceIn(nodes, idx, newNode, isEditable);
if (isEditable) {
this.bitmap = newBitmap;
this.nodes = newNodes;
return this;
}
return new BitmapIndexedNode(ownerID, newBitmap, newNodes);
};
function HashArrayMapNode(ownerID, count, nodes) {
this.ownerID = ownerID;
this.count = count;
this.nodes = nodes;
}
HashArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {
if (keyHash === undefined) {
keyHash = hash(key);
}
var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
var node = this.nodes[idx];
return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue;
};
HashArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
if (keyHash === undefined) {
keyHash = hash(key);
}
var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
var removed = value === NOT_SET;
var nodes = this.nodes;
var node = nodes[idx];
if (removed && !node) {
return this;
}
var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);
if (newNode === node) {
return this;
}
var newCount = this.count;
if (!node) {
newCount++;
} else if (!newNode) {
newCount--;
if (newCount < MIN_HASH_ARRAY_MAP_SIZE) {
return packNodes(ownerID, nodes, newCount, idx);
}
}
var isEditable = ownerID && ownerID === this.ownerID;
var newNodes = setIn(nodes, idx, newNode, isEditable);
if (isEditable) {
this.count = newCount;
this.nodes = newNodes;
return this;
}
return new HashArrayMapNode(ownerID, newCount, newNodes);
};
function HashCollisionNode(ownerID, keyHash, entries) {
this.ownerID = ownerID;
this.keyHash = keyHash;
this.entries = entries;
}
HashCollisionNode.prototype.get = function(shift, keyHash, key, notSetValue) {
var entries = this.entries;
for (var ii = 0, len = entries.length; ii < len; ii++) {
if (is(key, entries[ii][0])) {
return entries[ii][1];
}
}
return notSetValue;
};
HashCollisionNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
if (keyHash === undefined) {
keyHash = hash(key);
}
var removed = value === NOT_SET;
if (keyHash !== this.keyHash) {
if (removed) {
return this;
}
SetRef(didAlter);
SetRef(didChangeSize);
return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]);
}
var entries = this.entries;
var idx = 0;
for (var len = entries.length; idx < len; idx++) {
if (is(key, entries[idx][0])) {
break;
}
}
var exists = idx < len;
if (exists ? entries[idx][1] === value : removed) {
return this;
}
SetRef(didAlter);
(removed || !exists) && SetRef(didChangeSize);
if (removed && len === 2) {
return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]);
}
var isEditable = ownerID && ownerID === this.ownerID;
var newEntries = isEditable ? entries : arrCopy(entries);
if (exists) {
if (removed) {
idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());
} else {
newEntries[idx] = [key, value];
}
} else {
newEntries.push([key, value]);
}
if (isEditable) {
this.entries = newEntries;
return this;
}
return new HashCollisionNode(ownerID, this.keyHash, newEntries);
};
function ValueNode(ownerID, keyHash, entry) {
this.ownerID = ownerID;
this.keyHash = keyHash;
this.entry = entry;
}
ValueNode.prototype.get = function(shift, keyHash, key, notSetValue) {
return is(key, this.entry[0]) ? this.entry[1] : notSetValue;
};
ValueNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
var removed = value === NOT_SET;
var keyMatch = is(key, this.entry[0]);
if (keyMatch ? value === this.entry[1] : removed) {
return this;
}
SetRef(didAlter);
if (removed) {
SetRef(didChangeSize);
return; // undefined
}
if (keyMatch) {
if (ownerID && ownerID === this.ownerID) {
this.entry[1] = value;
return this;
}
return new ValueNode(ownerID, this.keyHash, [key, value]);
}
SetRef(didChangeSize);
return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]);
};
// #pragma Iterators
ArrayMapNode.prototype.iterate =
HashCollisionNode.prototype.iterate = function (fn, reverse) {
var entries = this.entries;
for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) {
if (fn(entries[reverse ? maxIndex - ii : ii]) === false) {
return false;
}
}
}
BitmapIndexedNode.prototype.iterate =
HashArrayMapNode.prototype.iterate = function (fn, reverse) {
var nodes = this.nodes;
for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) {
var node = nodes[reverse ? maxIndex - ii : ii];
if (node && node.iterate(fn, reverse) === false) {
return false;
}
}
}
ValueNode.prototype.iterate = function (fn, reverse) {
return fn(this.entry);
}
createClass(MapIterator, Iterator);
function MapIterator(map, type, reverse) {
this._type = type;
this._reverse = reverse;
this._stack = map._root && mapIteratorFrame(map._root);
}
MapIterator.prototype.next = function() {
var type = this._type;
var stack = this._stack;
while (stack) {
var node = stack.node;
var index = stack.index++;
var maxIndex;
if (node.entry) {
if (index === 0) {
return mapIteratorValue(type, node.entry);
}
} else if (node.entries) {
maxIndex = node.entries.length - 1;
if (index <= maxIndex) {
return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]);
}
} else {
maxIndex = node.nodes.length - 1;
if (index <= maxIndex) {
var subNode = node.nodes[this._reverse ? maxIndex - index : index];
if (subNode) {
if (subNode.entry) {
return mapIteratorValue(type, subNode.entry);
}
stack = this._stack = mapIteratorFrame(subNode, stack);
}
continue;
}
}
stack = this._stack = this._stack.__prev;
}
return iteratorDone();
};
function mapIteratorValue(type, entry) {
return iteratorValue(type, entry[0], entry[1]);
}
function mapIteratorFrame(node, prev) {
return {
node: node,
index: 0,
__prev: prev
};
}
function makeMap(size, root, ownerID, hash) {
var map = Object.create(MapPrototype);
map.size = size;
map._root = root;
map.__ownerID = ownerID;
map.__hash = hash;
map.__altered = false;
return map;
}
var EMPTY_MAP;
function emptyMap() {
return EMPTY_MAP || (EMPTY_MAP = makeMap(0));
}
function updateMap(map, k, v) {
var newRoot;
var newSize;
if (!map._root) {
if (v === NOT_SET) {
return map;
}
newSize = 1;
newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]);
} else {
var didChangeSize = MakeRef(CHANGE_LENGTH);
var didAlter = MakeRef(DID_ALTER);
newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter);
if (!didAlter.value) {
return map;
}
newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0);
}
if (map.__ownerID) {
map.size = newSize;
map._root = newRoot;
map.__hash = undefined;
map.__altered = true;
return map;
}
return newRoot ? makeMap(newSize, newRoot) : emptyMap();
}
function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
if (!node) {
if (value === NOT_SET) {
return node;
}
SetRef(didAlter);
SetRef(didChangeSize);
return new ValueNode(ownerID, keyHash, [key, value]);
}
return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter);
}
function isLeafNode(node) {
return node.constructor === ValueNode || node.constructor === HashCollisionNode;
}
function mergeIntoNode(node, ownerID, shift, keyHash, entry) {
if (node.keyHash === keyHash) {
return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]);
}
var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK;
var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
var newNode;
var nodes = idx1 === idx2 ?
[mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] :
((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]);
return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes);
}
function createNodes(ownerID, entries, key, value) {
if (!ownerID) {
ownerID = new OwnerID();
}
var node = new ValueNode(ownerID, hash(key), [key, value]);
for (var ii = 0; ii < entries.length; ii++) {
var entry = entries[ii];
node = node.update(ownerID, 0, undefined, entry[0], entry[1]);
}
return node;
}
function packNodes(ownerID, nodes, count, excluding) {
var bitmap = 0;
var packedII = 0;
var packedNodes = new Array(count);
for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) {
var node = nodes[ii];
if (node !== undefined && ii !== excluding) {
bitmap |= bit;
packedNodes[packedII++] = node;
}
}
return new BitmapIndexedNode(ownerID, bitmap, packedNodes);
}
function expandNodes(ownerID, nodes, bitmap, including, node) {
var count = 0;
var expandedNodes = new Array(SIZE);
for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) {
expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined;
}
expandedNodes[including] = node;
return new HashArrayMapNode(ownerID, count + 1, expandedNodes);
}
function mergeIntoMapWith(map, merger, iterables) {
var iters = [];
for (var ii = 0; ii < iterables.length; ii++) {
var value = iterables[ii];
var iter = KeyedIterable(value);
if (!isIterable(value)) {
iter = iter.map(function(v ) {return fromJS(v)});
}
iters.push(iter);
}
return mergeIntoCollectionWith(map, merger, iters);
}
function deepMerger(existing, value, key) {
return existing && existing.mergeDeep && isIterable(value) ?
existing.mergeDeep(value) :
is(existing, value) ? existing : value;
}
function deepMergerWith(merger) {
return function(existing, value, key) {
if (existing && existing.mergeDeepWith && isIterable(value)) {
return existing.mergeDeepWith(merger, value);
}
var nextValue = merger(existing, value, key);
return is(existing, nextValue) ? existing : nextValue;
};
}
function mergeIntoCollectionWith(collection, merger, iters) {
iters = iters.filter(function(x ) {return x.size !== 0});
if (iters.length === 0) {
return collection;
}
if (collection.size === 0 && !collection.__ownerID && iters.length === 1) {
return collection.constructor(iters[0]);
}
return collection.withMutations(function(collection ) {
var mergeIntoMap = merger ?
function(value, key) {
collection.update(key, NOT_SET, function(existing )
{return existing === NOT_SET ? value : merger(existing, value, key)}
);
} :
function(value, key) {
collection.set(key, value);
}
for (var ii = 0; ii < iters.length; ii++) {
iters[ii].forEach(mergeIntoMap);
}
});
}
function updateInDeepMap(existing, keyPathIter, notSetValue, updater) {
var isNotSet = existing === NOT_SET;
var step = keyPathIter.next();
if (step.done) {
var existingValue = isNotSet ? notSetValue : existing;
var newValue = updater(existingValue);
return newValue === existingValue ? existing : newValue;
}
invariant(
isNotSet || (existing && existing.set),
'invalid keyPath'
);
var key = step.value;
var nextExisting = isNotSet ? NOT_SET : existing.get(key, NOT_SET);
var nextUpdated = updateInDeepMap(
nextExisting,
keyPathIter,
notSetValue,
updater
);
return nextUpdated === nextExisting ? existing :
nextUpdated === NOT_SET ? existing.remove(key) :
(isNotSet ? emptyMap() : existing).set(key, nextUpdated);
}
function popCount(x) {
x = x - ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0f0f0f0f;
x = x + (x >> 8);
x = x + (x >> 16);
return x & 0x7f;
}
function setIn(array, idx, val, canEdit) {
var newArray = canEdit ? array : arrCopy(array);
newArray[idx] = val;
return newArray;
}
function spliceIn(array, idx, val, canEdit) {
var newLen = array.length + 1;
if (canEdit && idx + 1 === newLen) {
array[idx] = val;
return array;
}
var newArray = new Array(newLen);
var after = 0;
for (var ii = 0; ii < newLen; ii++) {
if (ii === idx) {
newArray[ii] = val;
after = -1;
} else {
newArray[ii] = array[ii + after];
}
}
return newArray;
}
function spliceOut(array, idx, canEdit) {
var newLen = array.length - 1;
if (canEdit && idx === newLen) {
array.pop();
return array;
}
var newArray = new Array(newLen);
var after = 0;
for (var ii = 0; ii < newLen; ii++) {
if (ii === idx) {
after = 1;
}
newArray[ii] = array[ii + after];
}
return newArray;
}
var MAX_ARRAY_MAP_SIZE = SIZE / 4;
var MAX_BITMAP_INDEXED_SIZE = SIZE / 2;
var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4;
createClass(List, IndexedCollection);
// @pragma Construction
function List(value) {
var empty = emptyList();
if (value === null || value === undefined) {
return empty;
}
if (isList(value)) {
return value;
}
var iter = IndexedIterable(value);
var size = iter.size;
if (size === 0) {
return empty;
}
assertNotInfinite(size);
if (size > 0 && size < SIZE) {
return makeList(0, size, SHIFT, null, new VNode(iter.toArray()));
}
return empty.withMutations(function(list ) {
list.setSize(size);
iter.forEach(function(v, i) {return list.set(i, v)});
});
}
List.of = function(/*...values*/) {
return this(arguments);
};
List.prototype.toString = function() {
return this.__toString('List [', ']');
};
// @pragma Access
List.prototype.get = function(index, notSetValue) {
index = wrapIndex(this, index);
if (index >= 0 && index < this.size) {
index += this._origin;
var node = listNodeFor(this, index);
return node && node.array[index & MASK];
}
return notSetValue;
};
// @pragma Modification
List.prototype.set = function(index, value) {
return updateList(this, index, value);
};
List.prototype.remove = function(index) {
return !this.has(index) ? this :
index === 0 ? this.shift() :
index === this.size - 1 ? this.pop() :
this.splice(index, 1);
};
List.prototype.insert = function(index, value) {
return this.splice(index, 0, value);
};
List.prototype.clear = function() {
if (this.size === 0) {
return this;
}
if (this.__ownerID) {
this.size = this._origin = this._capacity = 0;
this._level = SHIFT;
this._root = this._tail = null;
this.__hash = undefined;
this.__altered = true;
return this;
}
return emptyList();
};
List.prototype.push = function(/*...values*/) {
var values = arguments;
var oldSize = this.size;
return this.withMutations(function(list ) {
setListBounds(list, 0, oldSize + values.length);
for (var ii = 0; ii < values.length; ii++) {
list.set(oldSize + ii, values[ii]);
}
});
};
List.prototype.pop = function() {
return setListBounds(this, 0, -1);
};
List.prototype.unshift = function(/*...values*/) {
var values = arguments;
return this.withMutations(function(list ) {
setListBounds(list, -values.length);
for (var ii = 0; ii < values.length; ii++) {
list.set(ii, values[ii]);
}
});
};
List.prototype.shift = function() {
return setListBounds(this, 1);
};
// @pragma Composition
List.prototype.merge = function(/*...iters*/) {
return mergeIntoListWith(this, undefined, arguments);
};
List.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
return mergeIntoListWith(this, merger, iters);
};
List.prototype.mergeDeep = function(/*...iters*/) {
return mergeIntoListWith(this, deepMerger, arguments);
};
List.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
return mergeIntoListWith(this, deepMergerWith(merger), iters);
};
List.prototype.setSize = function(size) {
return setListBounds(this, 0, size);
};
// @pragma Iteration
List.prototype.slice = function(begin, end) {
var size = this.size;
if (wholeSlice(begin, end, size)) {
return this;
}
return setListBounds(
this,
resolveBegin(begin, size),
resolveEnd(end, size)
);
};
List.prototype.__iterator = function(type, reverse) {
var index = 0;
var values = iterateList(this, reverse);
return new Iterator(function() {
var value = values();
return value === DONE ?
iteratorDone() :
iteratorValue(type, index++, value);
});
};
List.prototype.__iterate = function(fn, reverse) {
var index = 0;
var values = iterateList(this, reverse);
var value;
while ((value = values()) !== DONE) {
if (fn(value, index++, this) === false) {
break;
}
}
return index;
};
List.prototype.__ensureOwner = function(ownerID) {
if (ownerID === this.__ownerID) {
return this;
}
if (!ownerID) {
this.__ownerID = ownerID;
return this;
}
return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash);
};
function isList(maybeList) {
return !!(maybeList && maybeList[IS_LIST_SENTINEL]);
}
List.isList = isList;
var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@';
var ListPrototype = List.prototype;
ListPrototype[IS_LIST_SENTINEL] = true;
ListPrototype[DELETE] = ListPrototype.remove;
ListPrototype.setIn = MapPrototype.setIn;
ListPrototype.deleteIn =
ListPrototype.removeIn = MapPrototype.removeIn;
ListPrototype.update = MapPrototype.update;
ListPrototype.updateIn = MapPrototype.updateIn;
ListPrototype.mergeIn = MapPrototype.mergeIn;
ListPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;
ListPrototype.withMutations = MapPrototype.withMutations;
ListPrototype.asMutable = MapPrototype.asMutable;
ListPrototype.asImmutable = MapPrototype.asImmutable;
ListPrototype.wasAltered = MapPrototype.wasAltered;
function VNode(array, ownerID) {
this.array = array;
this.ownerID = ownerID;
}
// TODO: seems like these methods are very similar
VNode.prototype.removeBefore = function(ownerID, level, index) {
if (index === level ? 1 << level : 0 || this.array.length === 0) {
return this;
}
var originIndex = (index >>> level) & MASK;
if (originIndex >= this.array.length) {
return new VNode([], ownerID);
}
var removingFirst = originIndex === 0;
var newChild;
if (level > 0) {
var oldChild = this.array[originIndex];
newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index);
if (newChild === oldChild && removingFirst) {
return this;
}
}
if (removingFirst && !newChild) {
return this;
}
var editable = editableVNode(this, ownerID);
if (!removingFirst) {
for (var ii = 0; ii < originIndex; ii++) {
editable.array[ii] = undefined;
}
}
if (newChild) {
editable.array[originIndex] = newChild;
}
return editable;
};
VNode.prototype.removeAfter = function(ownerID, level, index) {
if (index === (level ? 1 << level : 0) || this.array.length === 0) {
return this;
}
var sizeIndex = ((index - 1) >>> level) & MASK;
if (sizeIndex >= this.array.length) {
return this;
}
var newChild;
if (level > 0) {
var oldChild = this.array[sizeIndex];
newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index);
if (newChild === oldChild && sizeIndex === this.array.length - 1) {
return this;
}
}
var editable = editableVNode(this, ownerID);
editable.array.splice(sizeIndex + 1);
if (newChild) {
editable.array[sizeIndex] = newChild;
}
return editable;
};
var DONE = {};
function iterateList(list, reverse) {
var left = list._origin;
var right = list._capacity;
var tailPos = getTailOffset(right);
var tail = list._tail;
return iterateNodeOrLeaf(list._root, list._level, 0);
function iterateNodeOrLeaf(node, level, offset) {
return level === 0 ?
iterateLeaf(node, offset) :
iterateNode(node, level, offset);
}
function iterateLeaf(node, offset) {
var array = offset === tailPos ? tail && tail.array : node && node.array;
var from = offset > left ? 0 : left - offset;
var to = right - offset;
if (to > SIZE) {
to = SIZE;
}
return function() {
if (from === to) {
return DONE;
}
var idx = reverse ? --to : from++;
return array && array[idx];
};
}
function iterateNode(node, level, offset) {
var values;
var array = node && node.array;
var from = offset > left ? 0 : (left - offset) >> level;
var to = ((right - offset) >> level) + 1;
if (to > SIZE) {
to = SIZE;
}
return function() {
do {
if (values) {
var value = values();
if (value !== DONE) {
return value;
}
values = null;
}
if (from === to) {
return DONE;
}
var idx = reverse ? --to : from++;
values = iterateNodeOrLeaf(
array && array[idx], level - SHIFT, offset + (idx << level)
);
} while (true);
};
}
}
function makeList(origin, capacity, level, root, tail, ownerID, hash) {
var list = Object.create(ListPrototype);
list.size = capacity - origin;
list._origin = origin;
list._capacity = capacity;
list._level = level;
list._root = root;
list._tail = tail;
list.__ownerID = ownerID;
list.__hash = hash;
list.__altered = false;
return list;
}
var EMPTY_LIST;
function emptyList() {
return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT));
}
function updateList(list, index, value) {
index = wrapIndex(list, index);
if (index !== index) {
return list;
}
if (index >= list.size || index < 0) {
return list.withMutations(function(list ) {
index < 0 ?
setListBounds(list, index).set(0, value) :
setListBounds(list, 0, index + 1).set(index, value)
});
}
index += list._origin;
var newTail = list._tail;
var newRoot = list._root;
var didAlter = MakeRef(DID_ALTER);
if (index >= getTailOffset(list._capacity)) {
newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter);
} else {
newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter);
}
if (!didAlter.value) {
return list;
}
if (list.__ownerID) {
list._root = newRoot;
list._tail = newTail;
list.__hash = undefined;
list.__altered = true;
return list;
}
return makeList(list._origin, list._capacity, list._level, newRoot, newTail);
}
function updateVNode(node, ownerID, level, index, value, didAlter) {
var idx = (index >>> level) & MASK;
var nodeHas = node && idx < node.array.length;
if (!nodeHas && value === undefined) {
return node;
}
var newNode;
if (level > 0) {
var lowerNode = node && node.array[idx];
var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter);
if (newLowerNode === lowerNode) {
return node;
}
newNode = editableVNode(node, ownerID);
newNode.array[idx] = newLowerNode;
return newNode;
}
if (nodeHas && node.array[idx] === value) {
return node;
}
SetRef(didAlter);
newNode = editableVNode(node, ownerID);
if (value === undefined && idx === newNode.array.length - 1) {
newNode.array.pop();
} else {
newNode.array[idx] = value;
}
return newNode;
}
function editableVNode(node, ownerID) {
if (ownerID && node && ownerID === node.ownerID) {
return node;
}
return new VNode(node ? node.array.slice() : [], ownerID);
}
function listNodeFor(list, rawIndex) {
if (rawIndex >= getTailOffset(list._capacity)) {
return list._tail;
}
if (rawIndex < 1 << (list._level + SHIFT)) {
var node = list._root;
var level = list._level;
while (node && level > 0) {
node = node.array[(rawIndex >>> level) & MASK];
level -= SHIFT;
}
return node;
}
}
function setListBounds(list, begin, end) {
// Sanitize begin & end using this shorthand for ToInt32(argument)
// http://www.ecma-international.org/ecma-262/6.0/#sec-toint32
if (begin !== undefined) {
begin = begin | 0;
}
if (end !== undefined) {
end = end | 0;
}
var owner = list.__ownerID || new OwnerID();
var oldOrigin = list._origin;
var oldCapacity = list._capacity;
var newOrigin = oldOrigin + begin;
var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end;
if (newOrigin === oldOrigin && newCapacity === oldCapacity) {
return list;
}
// If it's going to end after it starts, it's empty.
if (newOrigin >= newCapacity) {
return list.clear();
}
var newLevel = list._level;
var newRoot = list._root;
// New origin might need creating a higher root.
var offsetShift = 0;
while (newOrigin + offsetShift < 0) {
newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner);
newLevel += SHIFT;
offsetShift += 1 << newLevel;
}
if (offsetShift) {
newOrigin += offsetShift;
oldOrigin += offsetShift;
newCapacity += offsetShift;
oldCapacity += offsetShift;
}
var oldTailOffset = getTailOffset(oldCapacity);
var newTailOffset = getTailOffset(newCapacity);
// New size might need creating a higher root.
while (newTailOffset >= 1 << (newLevel + SHIFT)) {
newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner);
newLevel += SHIFT;
}
// Locate or create the new tail.
var oldTail = list._tail;
var newTail = newTailOffset < oldTailOffset ?
listNodeFor(list, newCapacity - 1) :
newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail;
// Merge Tail into tree.
if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) {
newRoot = editableVNode(newRoot, owner);
var node = newRoot;
for (var level = newLevel; level > SHIFT; level -= SHIFT) {
var idx = (oldTailOffset >>> level) & MASK;
node = node.array[idx] = editableVNode(node.array[idx], owner);
}
node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail;
}
// If the size has been reduced, there's a chance the tail needs to be trimmed.
if (newCapacity < oldCapacity) {
newTail = newTail && newTail.removeAfter(owner, 0, newCapacity);
}
// If the new origin is within the tail, then we do not need a root.
if (newOrigin >= newTailOffset) {
newOrigin -= newTailOffset;
newCapacity -= newTailOffset;
newLevel = SHIFT;
newRoot = null;
newTail = newTail && newTail.removeBefore(owner, 0, newOrigin);
// Otherwise, if the root has been trimmed, garbage collect.
} else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) {
offsetShift = 0;
// Identify the new top root node of the subtree of the old root.
while (newRoot) {
var beginIndex = (newOrigin >>> newLevel) & MASK;
if (beginIndex !== (newTailOffset >>> newLevel) & MASK) {
break;
}
if (beginIndex) {
offsetShift += (1 << newLevel) * beginIndex;
}
newLevel -= SHIFT;
newRoot = newRoot.array[beginIndex];
}
// Trim the new sides of the new root.
if (newRoot && newOrigin > oldOrigin) {
newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift);
}
if (newRoot && newTailOffset < oldTailOffset) {
newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift);
}
if (offsetShift) {
newOrigin -= offsetShift;
newCapacity -= offsetShift;
}
}
if (list.__ownerID) {
list.size = newCapacity - newOrigin;
list._origin = newOrigin;
list._capacity = newCapacity;
list._level = newLevel;
list._root = newRoot;
list._tail = newTail;
list.__hash = undefined;
list.__altered = true;
return list;
}
return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail);
}
function mergeIntoListWith(list, merger, iterables) {
var iters = [];
var maxSize = 0;
for (var ii = 0; ii < iterables.length; ii++) {
var value = iterables[ii];
var iter = IndexedIterable(value);
if (iter.size > maxSize) {
maxSize = iter.size;
}
if (!isIterable(value)) {
iter = iter.map(function(v ) {return fromJS(v)});
}
iters.push(iter);
}
if (maxSize > list.size) {
list = list.setSize(maxSize);
}
return mergeIntoCollectionWith(list, merger, iters);
}
function getTailOffset(size) {
return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT);
}
createClass(OrderedMap, Map);
// @pragma Construction
function OrderedMap(value) {
return value === null || value === undefined ? emptyOrderedMap() :
isOrderedMap(value) ? value :
emptyOrderedMap().withMutations(function(map ) {
var iter = KeyedIterable(value);
assertNotInfinite(iter.size);
iter.forEach(function(v, k) {return map.set(k, v)});
});
}
OrderedMap.of = function(/*...values*/) {
return this(arguments);
};
OrderedMap.prototype.toString = function() {
return this.__toString('OrderedMap {', '}');
};
// @pragma Access
OrderedMap.prototype.get = function(k, notSetValue) {
var index = this._map.get(k);
return index !== undefined ? this._list.get(index)[1] : notSetValue;
};
// @pragma Modification
OrderedMap.prototype.clear = function() {
if (this.size === 0) {
return this;
}
if (this.__ownerID) {
this.size = 0;
this._map.clear();
this._list.clear();
return this;
}
return emptyOrderedMap();
};
OrderedMap.prototype.set = function(k, v) {
return updateOrderedMap(this, k, v);
};
OrderedMap.prototype.remove = function(k) {
return updateOrderedMap(this, k, NOT_SET);
};
OrderedMap.prototype.wasAltered = function() {
return this._map.wasAltered() || this._list.wasAltered();
};
OrderedMap.prototype.__iterate = function(fn, reverse) {var this$0 = this;
return this._list.__iterate(
function(entry ) {return entry && fn(entry[1], entry[0], this$0)},
reverse
);
};
OrderedMap.prototype.__iterator = function(type, reverse) {
return this._list.fromEntrySeq().__iterator(type, reverse);
};
OrderedMap.prototype.__ensureOwner = function(ownerID) {
if (ownerID === this.__ownerID) {
return this;
}
var newMap = this._map.__ensureOwner(ownerID);
var newList = this._list.__ensureOwner(ownerID);
if (!ownerID) {
this.__ownerID = ownerID;
this._map = newMap;
this._list = newList;
return this;
}
return makeOrderedMap(newMap, newList, ownerID, this.__hash);
};
function isOrderedMap(maybeOrderedMap) {
return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap);
}
OrderedMap.isOrderedMap = isOrderedMap;
OrderedMap.prototype[IS_ORDERED_SENTINEL] = true;
OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove;
function makeOrderedMap(map, list, ownerID, hash) {
var omap = Object.create(OrderedMap.prototype);
omap.size = map ? map.size : 0;
omap._map = map;
omap._list = list;
omap.__ownerID = ownerID;
omap.__hash = hash;
return omap;
}
var EMPTY_ORDERED_MAP;
function emptyOrderedMap() {
return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList()));
}
function updateOrderedMap(omap, k, v) {
var map = omap._map;
var list = omap._list;
var i = map.get(k);
var has = i !== undefined;
var newMap;
var newList;
if (v === NOT_SET) { // removed
if (!has) {
return omap;
}
if (list.size >= SIZE && list.size >= map.size * 2) {
newList = list.filter(function(entry, idx) {return entry !== undefined && i !== idx});
newMap = newList.toKeyedSeq().map(function(entry ) {return entry[0]}).flip().toMap();
if (omap.__ownerID) {
newMap.__ownerID = newList.__ownerID = omap.__ownerID;
}
} else {
newMap = map.remove(k);
newList = i === list.size - 1 ? list.pop() : list.set(i, undefined);
}
} else {
if (has) {
if (v === list.get(i)[1]) {
return omap;
}
newMap = map;
newList = list.set(i, [k, v]);
} else {
newMap = map.set(k, list.size);
newList = list.set(list.size, [k, v]);
}
}
if (omap.__ownerID) {
omap.size = newMap.size;
omap._map = newMap;
omap._list = newList;
omap.__hash = undefined;
return omap;
}
return makeOrderedMap(newMap, newList);
}
createClass(ToKeyedSequence, KeyedSeq);
function ToKeyedSequence(indexed, useKeys) {
this._iter = indexed;
this._useKeys = useKeys;
this.size = indexed.size;
}
ToKeyedSequence.prototype.get = function(key, notSetValue) {
return this._iter.get(key, notSetValue);
};
ToKeyedSequence.prototype.has = function(key) {
return this._iter.has(key);
};
ToKeyedSequence.prototype.valueSeq = function() {
return this._iter.valueSeq();
};
ToKeyedSequence.prototype.reverse = function() {var this$0 = this;
var reversedSequence = reverseFactory(this, true);
if (!this._useKeys) {
reversedSequence.valueSeq = function() {return this$0._iter.toSeq().reverse()};
}
return reversedSequence;
};
ToKeyedSequence.prototype.map = function(mapper, context) {var this$0 = this;
var mappedSequence = mapFactory(this, mapper, context);
if (!this._useKeys) {
mappedSequence.valueSeq = function() {return this$0._iter.toSeq().map(mapper, context)};
}
return mappedSequence;
};
ToKeyedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
var ii;
return this._iter.__iterate(
this._useKeys ?
function(v, k) {return fn(v, k, this$0)} :
((ii = reverse ? resolveSize(this) : 0),
function(v ) {return fn(v, reverse ? --ii : ii++, this$0)}),
reverse
);
};
ToKeyedSequence.prototype.__iterator = function(type, reverse) {
if (this._useKeys) {
return this._iter.__iterator(type, reverse);
}
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
var ii = reverse ? resolveSize(this) : 0;
return new Iterator(function() {
var step = iterator.next();
return step.done ? step :
iteratorValue(type, reverse ? --ii : ii++, step.value, step);
});
};
ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true;
createClass(ToIndexedSequence, IndexedSeq);
function ToIndexedSequence(iter) {
this._iter = iter;
this.size = iter.size;
}
ToIndexedSequence.prototype.includes = function(value) {
return this._iter.includes(value);
};
ToIndexedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
var iterations = 0;
return this._iter.__iterate(function(v ) {return fn(v, iterations++, this$0)}, reverse);
};
ToIndexedSequence.prototype.__iterator = function(type, reverse) {
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
var iterations = 0;
return new Iterator(function() {
var step = iterator.next();
return step.done ? step :
iteratorValue(type, iterations++, step.value, step)
});
};
createClass(ToSetSequence, SetSeq);
function ToSetSequence(iter) {
this._iter = iter;
this.size = iter.size;
}
ToSetSequence.prototype.has = function(key) {
return this._iter.includes(key);
};
ToSetSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
return this._iter.__iterate(function(v ) {return fn(v, v, this$0)}, reverse);
};
ToSetSequence.prototype.__iterator = function(type, reverse) {
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
return new Iterator(function() {
var step = iterator.next();
return step.done ? step :
iteratorValue(type, step.value, step.value, step);
});
};
createClass(FromEntriesSequence, KeyedSeq);
function FromEntriesSequence(entries) {
this._iter = entries;
this.size = entries.size;
}
FromEntriesSequence.prototype.entrySeq = function() {
return this._iter.toSeq();
};
FromEntriesSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
return this._iter.__iterate(function(entry ) {
// Check if entry exists first so array access doesn't throw for holes
// in the parent iteration.
if (entry) {
validateEntry(entry);
var indexedIterable = isIterable(entry);
return fn(
indexedIterable ? entry.get(1) : entry[1],
indexedIterable ? entry.get(0) : entry[0],
this$0
);
}
}, reverse);
};
FromEntriesSequence.prototype.__iterator = function(type, reverse) {
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
return new Iterator(function() {
while (true) {
var step = iterator.next();
if (step.done) {
return step;
}
var entry = step.value;
// Check if entry exists first so array access doesn't throw for holes
// in the parent iteration.
if (entry) {
validateEntry(entry);
var indexedIterable = isIterable(entry);
return iteratorValue(
type,
indexedIterable ? entry.get(0) : entry[0],
indexedIterable ? entry.get(1) : entry[1],
step
);
}
}
});
};
ToIndexedSequence.prototype.cacheResult =
ToKeyedSequence.prototype.cacheResult =
ToSetSequence.prototype.cacheResult =
FromEntriesSequence.prototype.cacheResult =
cacheResultThrough;
function flipFactory(iterable) {
var flipSequence = makeSequence(iterable);
flipSequence._iter = iterable;
flipSequence.size = iterable.size;
flipSequence.flip = function() {return iterable};
flipSequence.reverse = function () {
var reversedSequence = iterable.reverse.apply(this); // super.reverse()
reversedSequence.flip = function() {return iterable.reverse()};
return reversedSequence;
};
flipSequence.has = function(key ) {return iterable.includes(key)};
flipSequence.includes = function(key ) {return iterable.has(key)};
flipSequence.cacheResult = cacheResultThrough;
flipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
return iterable.__iterate(function(v, k) {return fn(k, v, this$0) !== false}, reverse);
}
flipSequence.__iteratorUncached = function(type, reverse) {
if (type === ITERATE_ENTRIES) {
var iterator = iterable.__iterator(type, reverse);
return new Iterator(function() {
var step = iterator.next();
if (!step.done) {
var k = step.value[0];
step.value[0] = step.value[1];
step.value[1] = k;
}
return step;
});
}
return iterable.__iterator(
type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES,
reverse
);
}
return flipSequence;
}
function mapFactory(iterable, mapper, context) {
var mappedSequence = makeSequence(iterable);
mappedSequence.size = iterable.size;
mappedSequence.has = function(key ) {return iterable.has(key)};
mappedSequence.get = function(key, notSetValue) {
var v = iterable.get(key, NOT_SET);
return v === NOT_SET ?
notSetValue :
mapper.call(context, v, key, iterable);
};
mappedSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
return iterable.__iterate(
function(v, k, c) {return fn(mapper.call(context, v, k, c), k, this$0) !== false},
reverse
);
}
mappedSequence.__iteratorUncached = function (type, reverse) {
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
return new Iterator(function() {
var step = iterator.next();
if (step.done) {
return step;
}
var entry = step.value;
var key = entry[0];
return iteratorValue(
type,
key,
mapper.call(context, entry[1], key, iterable),
step
);
});
}
return mappedSequence;
}
function reverseFactory(iterable, useKeys) {
var reversedSequence = makeSequence(iterable);
reversedSequence._iter = iterable;
reversedSequence.size = iterable.size;
reversedSequence.reverse = function() {return iterable};
if (iterable.flip) {
reversedSequence.flip = function () {
var flipSequence = flipFactory(iterable);
flipSequence.reverse = function() {return iterable.flip()};
return flipSequence;
};
}
reversedSequence.get = function(key, notSetValue)
{return iterable.get(useKeys ? key : -1 - key, notSetValue)};
reversedSequence.has = function(key )
{return iterable.has(useKeys ? key : -1 - key)};
reversedSequence.includes = function(value ) {return iterable.includes(value)};
reversedSequence.cacheResult = cacheResultThrough;
reversedSequence.__iterate = function (fn, reverse) {var this$0 = this;
return iterable.__iterate(function(v, k) {return fn(v, k, this$0)}, !reverse);
};
reversedSequence.__iterator =
function(type, reverse) {return iterable.__iterator(type, !reverse)};
return reversedSequence;
}
function filterFactory(iterable, predicate, context, useKeys) {
var filterSequence = makeSequence(iterable);
if (useKeys) {
filterSequence.has = function(key ) {
var v = iterable.get(key, NOT_SET);
return v !== NOT_SET && !!predicate.call(context, v, key, iterable);
};
filterSequence.get = function(key, notSetValue) {
var v = iterable.get(key, NOT_SET);
return v !== NOT_SET && predicate.call(context, v, key, iterable) ?
v : notSetValue;
};
}
filterSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
var iterations = 0;
iterable.__iterate(function(v, k, c) {
if (predicate.call(context, v, k, c)) {
iterations++;
return fn(v, useKeys ? k : iterations - 1, this$0);
}
}, reverse);
return iterations;
};
filterSequence.__iteratorUncached = function (type, reverse) {
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
var iterations = 0;
return new Iterator(function() {
while (true) {
var step = iterator.next();
if (step.done) {
return step;
}
var entry = step.value;
var key = entry[0];
var value = entry[1];
if (predicate.call(context, value, key, iterable)) {
return iteratorValue(type, useKeys ? key : iterations++, value, step);
}
}
});
}
return filterSequence;
}
function countByFactory(iterable, grouper, context) {
var groups = Map().asMutable();
iterable.__iterate(function(v, k) {
groups.update(
grouper.call(context, v, k, iterable),
0,
function(a ) {return a + 1}
);
});
return groups.asImmutable();
}
function groupByFactory(iterable, grouper, context) {
var isKeyedIter = isKeyed(iterable);
var groups = (isOrdered(iterable) ? OrderedMap() : Map()).asMutable();
iterable.__iterate(function(v, k) {
groups.update(
grouper.call(context, v, k, iterable),
function(a ) {return (a = a || [], a.push(isKeyedIter ? [k, v] : v), a)}
);
});
var coerce = iterableClass(iterable);
return groups.map(function(arr ) {return reify(iterable, coerce(arr))});
}
function sliceFactory(iterable, begin, end, useKeys) {
var originalSize = iterable.size;
// Sanitize begin & end using this shorthand for ToInt32(argument)
// http://www.ecma-international.org/ecma-262/6.0/#sec-toint32
if (begin !== undefined) {
begin = begin | 0;
}
if (end !== undefined) {
if (end === Infinity) {
end = originalSize;
} else {
end = end | 0;
}
}
if (wholeSlice(begin, end, originalSize)) {
return iterable;
}
var resolvedBegin = resolveBegin(begin, originalSize);
var resolvedEnd = resolveEnd(end, originalSize);
// begin or end will be NaN if they were provided as negative numbers and
// this iterable's size is unknown. In that case, cache first so there is
// a known size and these do not resolve to NaN.
if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) {
return sliceFactory(iterable.toSeq().cacheResult(), begin, end, useKeys);
}
// Note: resolvedEnd is undefined when the original sequence's length is
// unknown and this slice did not supply an end and should contain all
// elements after resolvedBegin.
// In that case, resolvedSize will be NaN and sliceSize will remain undefined.
var resolvedSize = resolvedEnd - resolvedBegin;
var sliceSize;
if (resolvedSize === resolvedSize) {
sliceSize = resolvedSize < 0 ? 0 : resolvedSize;
}
var sliceSeq = makeSequence(iterable);
// If iterable.size is undefined, the size of the realized sliceSeq is
// unknown at this point unless the number of items to slice is 0
sliceSeq.size = sliceSize === 0 ? sliceSize : iterable.size && sliceSize || undefined;
if (!useKeys && isSeq(iterable) && sliceSize >= 0) {
sliceSeq.get = function (index, notSetValue) {
index = wrapIndex(this, index);
return index >= 0 && index < sliceSize ?
iterable.get(index + resolvedBegin, notSetValue) :
notSetValue;
}
}
sliceSeq.__iterateUncached = function(fn, reverse) {var this$0 = this;
if (sliceSize === 0) {
return 0;
}
if (reverse) {
return this.cacheResult().__iterate(fn, reverse);
}
var skipped = 0;
var isSkipping = true;
var iterations = 0;
iterable.__iterate(function(v, k) {
if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) {
iterations++;
return fn(v, useKeys ? k : iterations - 1, this$0) !== false &&
iterations !== sliceSize;
}
});
return iterations;
};
sliceSeq.__iteratorUncached = function(type, reverse) {
if (sliceSize !== 0 && reverse) {
return this.cacheResult().__iterator(type, reverse);
}
// Don't bother instantiating parent iterator if taking 0.
var iterator = sliceSize !== 0 && iterable.__iterator(type, reverse);
var skipped = 0;
var iterations = 0;
return new Iterator(function() {
while (skipped++ < resolvedBegin) {
iterator.next();
}
if (++iterations > sliceSize) {
return iteratorDone();
}
var step = iterator.next();
if (useKeys || type === ITERATE_VALUES) {
return step;
} else if (type === ITERATE_KEYS) {
return iteratorValue(type, iterations - 1, undefined, step);
} else {
return iteratorValue(type, iterations - 1, step.value[1], step);
}
});
}
return sliceSeq;
}
function takeWhileFactory(iterable, predicate, context) {
var takeSequence = makeSequence(iterable);
takeSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;
if (reverse) {
return this.cacheResult().__iterate(fn, reverse);
}
var iterations = 0;
iterable.__iterate(function(v, k, c)
{return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$0)}
);
return iterations;
};
takeSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;
if (reverse) {
return this.cacheResult().__iterator(type, reverse);
}
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
var iterating = true;
return new Iterator(function() {
if (!iterating) {
return iteratorDone();
}
var step = iterator.next();
if (step.done) {
return step;
}
var entry = step.value;
var k = entry[0];
var v = entry[1];
if (!predicate.call(context, v, k, this$0)) {
iterating = false;
return iteratorDone();
}
return type === ITERATE_ENTRIES ? step :
iteratorValue(type, k, v, step);
});
};
return takeSequence;
}
function skipWhileFactory(iterable, predicate, context, useKeys) {
var skipSequence = makeSequence(iterable);
skipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
if (reverse) {
return this.cacheResult().__iterate(fn, reverse);
}
var isSkipping = true;
var iterations = 0;
iterable.__iterate(function(v, k, c) {
if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) {
iterations++;
return fn(v, useKeys ? k : iterations - 1, this$0);
}
});
return iterations;
};
skipSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;
if (reverse) {
return this.cacheResult().__iterator(type, reverse);
}
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
var skipping = true;
var iterations = 0;
return new Iterator(function() {
var step, k, v;
do {
step = iterator.next();
if (step.done) {
if (useKeys || type === ITERATE_VALUES) {
return step;
} else if (type === ITERATE_KEYS) {
return iteratorValue(type, iterations++, undefined, step);
} else {
return iteratorValue(type, iterations++, step.value[1], step);
}
}
var entry = step.value;
k = entry[0];
v = entry[1];
skipping && (skipping = predicate.call(context, v, k, this$0));
} while (skipping);
return type === ITERATE_ENTRIES ? step :
iteratorValue(type, k, v, step);
});
};
return skipSequence;
}
function concatFactory(iterable, values) {
var isKeyedIterable = isKeyed(iterable);
var iters = [iterable].concat(values).map(function(v ) {
if (!isIterable(v)) {
v = isKeyedIterable ?
keyedSeqFromValue(v) :
indexedSeqFromValue(Array.isArray(v) ? v : [v]);
} else if (isKeyedIterable) {
v = KeyedIterable(v);
}
return v;
}).filter(function(v ) {return v.size !== 0});
if (iters.length === 0) {
return iterable;
}
if (iters.length === 1) {
var singleton = iters[0];
if (singleton === iterable ||
isKeyedIterable && isKeyed(singleton) ||
isIndexed(iterable) && isIndexed(singleton)) {
return singleton;
}
}
var concatSeq = new ArraySeq(iters);
if (isKeyedIterable) {
concatSeq = concatSeq.toKeyedSeq();
} else if (!isIndexed(iterable)) {
concatSeq = concatSeq.toSetSeq();
}
concatSeq = concatSeq.flatten(true);
concatSeq.size = iters.reduce(
function(sum, seq) {
if (sum !== undefined) {
var size = seq.size;
if (size !== undefined) {
return sum + size;
}
}
},
0
);
return concatSeq;
}
function flattenFactory(iterable, depth, useKeys) {
var flatSequence = makeSequence(iterable);
flatSequence.__iterateUncached = function(fn, reverse) {
var iterations = 0;
var stopped = false;
function flatDeep(iter, currentDepth) {var this$0 = this;
iter.__iterate(function(v, k) {
if ((!depth || currentDepth < depth) && isIterable(v)) {
flatDeep(v, currentDepth + 1);
} else if (fn(v, useKeys ? k : iterations++, this$0) === false) {
stopped = true;
}
return !stopped;
}, reverse);
}
flatDeep(iterable, 0);
return iterations;
}
flatSequence.__iteratorUncached = function(type, reverse) {
var iterator = iterable.__iterator(type, reverse);
var stack = [];
var iterations = 0;
return new Iterator(function() {
while (iterator) {
var step = iterator.next();
if (step.done !== false) {
iterator = stack.pop();
continue;
}
var v = step.value;
if (type === ITERATE_ENTRIES) {
v = v[1];
}
if ((!depth || stack.length < depth) && isIterable(v)) {
stack.push(iterator);
iterator = v.__iterator(type, reverse);
} else {
return useKeys ? step : iteratorValue(type, iterations++, v, step);
}
}
return iteratorDone();
});
}
return flatSequence;
}
function flatMapFactory(iterable, mapper, context) {
var coerce = iterableClass(iterable);
return iterable.toSeq().map(
function(v, k) {return coerce(mapper.call(context, v, k, iterable))}
).flatten(true);
}
function interposeFactory(iterable, separator) {
var interposedSequence = makeSequence(iterable);
interposedSequence.size = iterable.size && iterable.size * 2 -1;
interposedSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;
var iterations = 0;
iterable.__iterate(function(v, k)
{return (!iterations || fn(separator, iterations++, this$0) !== false) &&
fn(v, iterations++, this$0) !== false},
reverse
);
return iterations;
};
interposedSequence.__iteratorUncached = function(type, reverse) {
var iterator = iterable.__iterator(ITERATE_VALUES, reverse);
var iterations = 0;
var step;
return new Iterator(function() {
if (!step || iterations % 2) {
step = iterator.next();
if (step.done) {
return step;
}
}
return iterations % 2 ?
iteratorValue(type, iterations++, separator) :
iteratorValue(type, iterations++, step.value, step);
});
};
return interposedSequence;
}
function sortFactory(iterable, comparator, mapper) {
if (!comparator) {
comparator = defaultComparator;
}
var isKeyedIterable = isKeyed(iterable);
var index = 0;
var entries = iterable.toSeq().map(
function(v, k) {return [k, v, index++, mapper ? mapper(v, k, iterable) : v]}
).toArray();
entries.sort(function(a, b) {return comparator(a[3], b[3]) || a[2] - b[2]}).forEach(
isKeyedIterable ?
function(v, i) { entries[i].length = 2; } :
function(v, i) { entries[i] = v[1]; }
);
return isKeyedIterable ? KeyedSeq(entries) :
isIndexed(iterable) ? IndexedSeq(entries) :
SetSeq(entries);
}
function maxFactory(iterable, comparator, mapper) {
if (!comparator) {
comparator = defaultComparator;
}
if (mapper) {
var entry = iterable.toSeq()
.map(function(v, k) {return [v, mapper(v, k, iterable)]})
.reduce(function(a, b) {return maxCompare(comparator, a[1], b[1]) ? b : a});
return entry && entry[0];
} else {
return iterable.reduce(function(a, b) {return maxCompare(comparator, a, b) ? b : a});
}
}
function maxCompare(comparator, a, b) {
var comp = comparator(b, a);
// b is considered the new max if the comparator declares them equal, but
// they are not equal and b is in fact a nullish value.
return (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || comp > 0;
}
function zipWithFactory(keyIter, zipper, iters) {
var zipSequence = makeSequence(keyIter);
zipSequence.size = new ArraySeq(iters).map(function(i ) {return i.size}).min();
// Note: this a generic base implementation of __iterate in terms of
// __iterator which may be more generically useful in the future.
zipSequence.__iterate = function(fn, reverse) {
/* generic:
var iterator = this.__iterator(ITERATE_ENTRIES, reverse);
var step;
var iterations = 0;
while (!(step = iterator.next()).done) {
iterations++;
if (fn(step.value[1], step.value[0], this) === false) {
break;
}
}
return iterations;
*/
// indexed:
var iterator = this.__iterator(ITERATE_VALUES, reverse);
var step;
var iterations = 0;
while (!(step = iterator.next()).done) {
if (fn(step.value, iterations++, this) === false) {
break;
}
}
return iterations;
};
zipSequence.__iteratorUncached = function(type, reverse) {
var iterators = iters.map(function(i )
{return (i = Iterable(i), getIterator(reverse ? i.reverse() : i))}
);
var iterations = 0;
var isDone = false;
return new Iterator(function() {
var steps;
if (!isDone) {
steps = iterators.map(function(i ) {return i.next()});
isDone = steps.some(function(s ) {return s.done});
}
if (isDone) {
return iteratorDone();
}
return iteratorValue(
type,
iterations++,
zipper.apply(null, steps.map(function(s ) {return s.value}))
);
});
};
return zipSequence
}
// #pragma Helper Functions
function reify(iter, seq) {
return isSeq(iter) ? seq : iter.constructor(seq);
}
function validateEntry(entry) {
if (entry !== Object(entry)) {
throw new TypeError('Expected [K, V] tuple: ' + entry);
}
}
function resolveSize(iter) {
assertNotInfinite(iter.size);
return ensureSize(iter);
}
function iterableClass(iterable) {
return isKeyed(iterable) ? KeyedIterable :
isIndexed(iterable) ? IndexedIterable :
SetIterable;
}
function makeSequence(iterable) {
return Object.create(
(
isKeyed(iterable) ? KeyedSeq :
isIndexed(iterable) ? IndexedSeq :
SetSeq
).prototype
);
}
function cacheResultThrough() {
if (this._iter.cacheResult) {
this._iter.cacheResult();
this.size = this._iter.size;
return this;
} else {
return Seq.prototype.cacheResult.call(this);
}
}
function defaultComparator(a, b) {
return a > b ? 1 : a < b ? -1 : 0;
}
function forceIterator(keyPath) {
var iter = getIterator(keyPath);
if (!iter) {
// Array might not be iterable in this environment, so we need a fallback
// to our wrapped type.
if (!isArrayLike(keyPath)) {
throw new TypeError('Expected iterable or array-like: ' + keyPath);
}
iter = getIterator(Iterable(keyPath));
}
return iter;
}
createClass(Record, KeyedCollection);
function Record(defaultValues, name) {
var hasInitialized;
var RecordType = function Record(values) {
if (values instanceof RecordType) {
return values;
}
if (!(this instanceof RecordType)) {
return new RecordType(values);
}
if (!hasInitialized) {
hasInitialized = true;
var keys = Object.keys(defaultValues);
setProps(RecordTypePrototype, keys);
RecordTypePrototype.size = keys.length;
RecordTypePrototype._name = name;
RecordTypePrototype._keys = keys;
RecordTypePrototype._defaultValues = defaultValues;
}
this._map = Map(values);
};
var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype);
RecordTypePrototype.constructor = RecordType;
return RecordType;
}
Record.prototype.toString = function() {
return this.__toString(recordName(this) + ' {', '}');
};
// @pragma Access
Record.prototype.has = function(k) {
return this._defaultValues.hasOwnProperty(k);
};
Record.prototype.get = function(k, notSetValue) {
if (!this.has(k)) {
return notSetValue;
}
var defaultVal = this._defaultValues[k];
return this._map ? this._map.get(k, defaultVal) : defaultVal;
};
// @pragma Modification
Record.prototype.clear = function() {
if (this.__ownerID) {
this._map && this._map.clear();
return this;
}
var RecordType = this.constructor;
return RecordType._empty || (RecordType._empty = makeRecord(this, emptyMap()));
};
Record.prototype.set = function(k, v) {
if (!this.has(k)) {
throw new Error('Cannot set unknown key "' + k + '" on ' + recordName(this));
}
if (this._map && !this._map.has(k)) {
var defaultVal = this._defaultValues[k];
if (v === defaultVal) {
return this;
}
}
var newMap = this._map && this._map.set(k, v);
if (this.__ownerID || newMap === this._map) {
return this;
}
return makeRecord(this, newMap);
};
Record.prototype.remove = function(k) {
if (!this.has(k)) {
return this;
}
var newMap = this._map && this._map.remove(k);
if (this.__ownerID || newMap === this._map) {
return this;
}
return makeRecord(this, newMap);
};
Record.prototype.wasAltered = function() {
return this._map.wasAltered();
};
Record.prototype.__iterator = function(type, reverse) {var this$0 = this;
return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterator(type, reverse);
};
Record.prototype.__iterate = function(fn, reverse) {var this$0 = this;
return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterate(fn, reverse);
};
Record.prototype.__ensureOwner = function(ownerID) {
if (ownerID === this.__ownerID) {
return this;
}
var newMap = this._map && this._map.__ensureOwner(ownerID);
if (!ownerID) {
this.__ownerID = ownerID;
this._map = newMap;
return this;
}
return makeRecord(this, newMap, ownerID);
};
var RecordPrototype = Record.prototype;
RecordPrototype[DELETE] = RecordPrototype.remove;
RecordPrototype.deleteIn =
RecordPrototype.removeIn = MapPrototype.removeIn;
RecordPrototype.merge = MapPrototype.merge;
RecordPrototype.mergeWith = MapPrototype.mergeWith;
RecordPrototype.mergeIn = MapPrototype.mergeIn;
RecordPrototype.mergeDeep = MapPrototype.mergeDeep;
RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith;
RecordPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;
RecordPrototype.setIn = MapPrototype.setIn;
RecordPrototype.update = MapPrototype.update;
RecordPrototype.updateIn = MapPrototype.updateIn;
RecordPrototype.withMutations = MapPrototype.withMutations;
RecordPrototype.asMutable = MapPrototype.asMutable;
RecordPrototype.asImmutable = MapPrototype.asImmutable;
function makeRecord(likeRecord, map, ownerID) {
var record = Object.create(Object.getPrototypeOf(likeRecord));
record._map = map;
record.__ownerID = ownerID;
return record;
}
function recordName(record) {
return record._name || record.constructor.name || 'Record';
}
function setProps(prototype, names) {
try {
names.forEach(setProp.bind(undefined, prototype));
} catch (error) {
// Object.defineProperty failed. Probably IE8.
}
}
function setProp(prototype, name) {
Object.defineProperty(prototype, name, {
get: function() {
return this.get(name);
},
set: function(value) {
invariant(this.__ownerID, 'Cannot set on an immutable record.');
this.set(name, value);
}
});
}
createClass(Set, SetCollection);
// @pragma Construction
function Set(value) {
return value === null || value === undefined ? emptySet() :
isSet(value) && !isOrdered(value) ? value :
emptySet().withMutations(function(set ) {
var iter = SetIterable(value);
assertNotInfinite(iter.size);
iter.forEach(function(v ) {return set.add(v)});
});
}
Set.of = function(/*...values*/) {
return this(arguments);
};
Set.fromKeys = function(value) {
return this(KeyedIterable(value).keySeq());
};
Set.prototype.toString = function() {
return this.__toString('Set {', '}');
};
// @pragma Access
Set.prototype.has = function(value) {
return this._map.has(value);
};
// @pragma Modification
Set.prototype.add = function(value) {
return updateSet(this, this._map.set(value, true));
};
Set.prototype.remove = function(value) {
return updateSet(this, this._map.remove(value));
};
Set.prototype.clear = function() {
return updateSet(this, this._map.clear());
};
// @pragma Composition
Set.prototype.union = function() {var iters = SLICE$0.call(arguments, 0);
iters = iters.filter(function(x ) {return x.size !== 0});
if (iters.length === 0) {
return this;
}
if (this.size === 0 && !this.__ownerID && iters.length === 1) {
return this.constructor(iters[0]);
}
return this.withMutations(function(set ) {
for (var ii = 0; ii < iters.length; ii++) {
SetIterable(iters[ii]).forEach(function(value ) {return set.add(value)});
}
});
};
Set.prototype.intersect = function() {var iters = SLICE$0.call(arguments, 0);
if (iters.length === 0) {
return this;
}
iters = iters.map(function(iter ) {return SetIterable(iter)});
var originalSet = this;
return this.withMutations(function(set ) {
originalSet.forEach(function(value ) {
if (!iters.every(function(iter ) {return iter.includes(value)})) {
set.remove(value);
}
});
});
};
Set.prototype.subtract = function() {var iters = SLICE$0.call(arguments, 0);
if (iters.length === 0) {
return this;
}
iters = iters.map(function(iter ) {return SetIterable(iter)});
var originalSet = this;
return this.withMutations(function(set ) {
originalSet.forEach(function(value ) {
if (iters.some(function(iter ) {return iter.includes(value)})) {
set.remove(value);
}
});
});
};
Set.prototype.merge = function() {
return this.union.apply(this, arguments);
};
Set.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
return this.union.apply(this, iters);
};
Set.prototype.sort = function(comparator) {
// Late binding
return OrderedSet(sortFactory(this, comparator));
};
Set.prototype.sortBy = function(mapper, comparator) {
// Late binding
return OrderedSet(sortFactory(this, comparator, mapper));
};
Set.prototype.wasAltered = function() {
return this._map.wasAltered();
};
Set.prototype.__iterate = function(fn, reverse) {var this$0 = this;
return this._map.__iterate(function(_, k) {return fn(k, k, this$0)}, reverse);
};
Set.prototype.__iterator = function(type, reverse) {
return this._map.map(function(_, k) {return k}).__iterator(type, reverse);
};
Set.prototype.__ensureOwner = function(ownerID) {
if (ownerID === this.__ownerID) {
return this;
}
var newMap = this._map.__ensureOwner(ownerID);
if (!ownerID) {
this.__ownerID = ownerID;
this._map = newMap;
return this;
}
return this.__make(newMap, ownerID);
};
function isSet(maybeSet) {
return !!(maybeSet && maybeSet[IS_SET_SENTINEL]);
}
Set.isSet = isSet;
var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@';
var SetPrototype = Set.prototype;
SetPrototype[IS_SET_SENTINEL] = true;
SetPrototype[DELETE] = SetPrototype.remove;
SetPrototype.mergeDeep = SetPrototype.merge;
SetPrototype.mergeDeepWith = SetPrototype.mergeWith;
SetPrototype.withMutations = MapPrototype.withMutations;
SetPrototype.asMutable = MapPrototype.asMutable;
SetPrototype.asImmutable = MapPrototype.asImmutable;
SetPrototype.__empty = emptySet;
SetPrototype.__make = makeSet;
function updateSet(set, newMap) {
if (set.__ownerID) {
set.size = newMap.size;
set._map = newMap;
return set;
}
return newMap === set._map ? set :
newMap.size === 0 ? set.__empty() :
set.__make(newMap);
}
function makeSet(map, ownerID) {
var set = Object.create(SetPrototype);
set.size = map ? map.size : 0;
set._map = map;
set.__ownerID = ownerID;
return set;
}
var EMPTY_SET;
function emptySet() {
return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap()));
}
createClass(OrderedSet, Set);
// @pragma Construction
function OrderedSet(value) {
return value === null || value === undefined ? emptyOrderedSet() :
isOrderedSet(value) ? value :
emptyOrderedSet().withMutations(function(set ) {
var iter = SetIterable(value);
assertNotInfinite(iter.size);
iter.forEach(function(v ) {return set.add(v)});
});
}
OrderedSet.of = function(/*...values*/) {
return this(arguments);
};
OrderedSet.fromKeys = function(value) {
return this(KeyedIterable(value).keySeq());
};
OrderedSet.prototype.toString = function() {
return this.__toString('OrderedSet {', '}');
};
function isOrderedSet(maybeOrderedSet) {
return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet);
}
OrderedSet.isOrderedSet = isOrderedSet;
var OrderedSetPrototype = OrderedSet.prototype;
OrderedSetPrototype[IS_ORDERED_SENTINEL] = true;
OrderedSetPrototype.__empty = emptyOrderedSet;
OrderedSetPrototype.__make = makeOrderedSet;
function makeOrderedSet(map, ownerID) {
var set = Object.create(OrderedSetPrototype);
set.size = map ? map.size : 0;
set._map = map;
set.__ownerID = ownerID;
return set;
}
var EMPTY_ORDERED_SET;
function emptyOrderedSet() {
return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap()));
}
createClass(Stack, IndexedCollection);
// @pragma Construction
function Stack(value) {
return value === null || value === undefined ? emptyStack() :
isStack(value) ? value :
emptyStack().unshiftAll(value);
}
Stack.of = function(/*...values*/) {
return this(arguments);
};
Stack.prototype.toString = function() {
return this.__toString('Stack [', ']');
};
// @pragma Access
Stack.prototype.get = function(index, notSetValue) {
var head = this._head;
index = wrapIndex(this, index);
while (head && index--) {
head = head.next;
}
return head ? head.value : notSetValue;
};
Stack.prototype.peek = function() {
return this._head && this._head.value;
};
// @pragma Modification
Stack.prototype.push = function(/*...values*/) {
if (arguments.length === 0) {
return this;
}
var newSize = this.size + arguments.length;
var head = this._head;
for (var ii = arguments.length - 1; ii >= 0; ii--) {
head = {
value: arguments[ii],
next: head
};
}
if (this.__ownerID) {
this.size = newSize;
this._head = head;
this.__hash = undefined;
this.__altered = true;
return this;
}
return makeStack(newSize, head);
};
Stack.prototype.pushAll = function(iter) {
iter = IndexedIterable(iter);
if (iter.size === 0) {
return this;
}
assertNotInfinite(iter.size);
var newSize = this.size;
var head = this._head;
iter.reverse().forEach(function(value ) {
newSize++;
head = {
value: value,
next: head
};
});
if (this.__ownerID) {
this.size = newSize;
this._head = head;
this.__hash = undefined;
this.__altered = true;
return this;
}
return makeStack(newSize, head);
};
Stack.prototype.pop = function() {
return this.slice(1);
};
Stack.prototype.unshift = function(/*...values*/) {
return this.push.apply(this, arguments);
};
Stack.prototype.unshiftAll = function(iter) {
return this.pushAll(iter);
};
Stack.prototype.shift = function() {
return this.pop.apply(this, arguments);
};
Stack.prototype.clear = function() {
if (this.size === 0) {
return this;
}
if (this.__ownerID) {
this.size = 0;
this._head = undefined;
this.__hash = undefined;
this.__altered = true;
return this;
}
return emptyStack();
};
Stack.prototype.slice = function(begin, end) {
if (wholeSlice(begin, end, this.size)) {
return this;
}
var resolvedBegin = resolveBegin(begin, this.size);
var resolvedEnd = resolveEnd(end, this.size);
if (resolvedEnd !== this.size) {
// super.slice(begin, end);
return IndexedCollection.prototype.slice.call(this, begin, end);
}
var newSize = this.size - resolvedBegin;
var head = this._head;
while (resolvedBegin--) {
head = head.next;
}
if (this.__ownerID) {
this.size = newSize;
this._head = head;
this.__hash = undefined;
this.__altered = true;
return this;
}
return makeStack(newSize, head);
};
// @pragma Mutability
Stack.prototype.__ensureOwner = function(ownerID) {
if (ownerID === this.__ownerID) {
return this;
}
if (!ownerID) {
this.__ownerID = ownerID;
this.__altered = false;
return this;
}
return makeStack(this.size, this._head, ownerID, this.__hash);
};
// @pragma Iteration
Stack.prototype.__iterate = function(fn, reverse) {
if (reverse) {
return this.reverse().__iterate(fn);
}
var iterations = 0;
var node = this._head;
while (node) {
if (fn(node.value, iterations++, this) === false) {
break;
}
node = node.next;
}
return iterations;
};
Stack.prototype.__iterator = function(type, reverse) {
if (reverse) {
return this.reverse().__iterator(type);
}
var iterations = 0;
var node = this._head;
return new Iterator(function() {
if (node) {
var value = node.value;
node = node.next;
return iteratorValue(type, iterations++, value);
}
return iteratorDone();
});
};
function isStack(maybeStack) {
return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]);
}
Stack.isStack = isStack;
var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@';
var StackPrototype = Stack.prototype;
StackPrototype[IS_STACK_SENTINEL] = true;
StackPrototype.withMutations = MapPrototype.withMutations;
StackPrototype.asMutable = MapPrototype.asMutable;
StackPrototype.asImmutable = MapPrototype.asImmutable;
StackPrototype.wasAltered = MapPrototype.wasAltered;
function makeStack(size, head, ownerID, hash) {
var map = Object.create(StackPrototype);
map.size = size;
map._head = head;
map.__ownerID = ownerID;
map.__hash = hash;
map.__altered = false;
return map;
}
var EMPTY_STACK;
function emptyStack() {
return EMPTY_STACK || (EMPTY_STACK = makeStack(0));
}
/**
* Contributes additional methods to a constructor
*/
function mixin(ctor, methods) {
var keyCopier = function(key ) { ctor.prototype[key] = methods[key]; };
Object.keys(methods).forEach(keyCopier);
Object.getOwnPropertySymbols &&
Object.getOwnPropertySymbols(methods).forEach(keyCopier);
return ctor;
}
Iterable.Iterator = Iterator;
mixin(Iterable, {
// ### Conversion to other types
toArray: function() {
assertNotInfinite(this.size);
var array = new Array(this.size || 0);
this.valueSeq().__iterate(function(v, i) { array[i] = v; });
return array;
},
toIndexedSeq: function() {
return new ToIndexedSequence(this);
},
toJS: function() {
return this.toSeq().map(
function(value ) {return value && typeof value.toJS === 'function' ? value.toJS() : value}
).__toJS();
},
toJSON: function() {
return this.toSeq().map(
function(value ) {return value && typeof value.toJSON === 'function' ? value.toJSON() : value}
).__toJS();
},
toKeyedSeq: function() {
return new ToKeyedSequence(this, true);
},
toMap: function() {
// Use Late Binding here to solve the circular dependency.
return Map(this.toKeyedSeq());
},
toObject: function() {
assertNotInfinite(this.size);
var object = {};
this.__iterate(function(v, k) { object[k] = v; });
return object;
},
toOrderedMap: function() {
// Use Late Binding here to solve the circular dependency.
return OrderedMap(this.toKeyedSeq());
},
toOrderedSet: function() {
// Use Late Binding here to solve the circular dependency.
return OrderedSet(isKeyed(this) ? this.valueSeq() : this);
},
toSet: function() {
// Use Late Binding here to solve the circular dependency.
return Set(isKeyed(this) ? this.valueSeq() : this);
},
toSetSeq: function() {
return new ToSetSequence(this);
},
toSeq: function() {
return isIndexed(this) ? this.toIndexedSeq() :
isKeyed(this) ? this.toKeyedSeq() :
this.toSetSeq();
},
toStack: function() {
// Use Late Binding here to solve the circular dependency.
return Stack(isKeyed(this) ? this.valueSeq() : this);
},
toList: function() {
// Use Late Binding here to solve the circular dependency.
return List(isKeyed(this) ? this.valueSeq() : this);
},
// ### Common JavaScript methods and properties
toString: function() {
return '[Iterable]';
},
__toString: function(head, tail) {
if (this.size === 0) {
return head + tail;
}
return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail;
},
// ### ES6 Collection methods (ES6 Array and Map)
concat: function() {var values = SLICE$0.call(arguments, 0);
return reify(this, concatFactory(this, values));
},
includes: function(searchValue) {
return this.some(function(value ) {return is(value, searchValue)});
},
entries: function() {
return this.__iterator(ITERATE_ENTRIES);
},
every: function(predicate, context) {
assertNotInfinite(this.size);
var returnValue = true;
this.__iterate(function(v, k, c) {
if (!predicate.call(context, v, k, c)) {
returnValue = false;
return false;
}
});
return returnValue;
},
filter: function(predicate, context) {
return reify(this, filterFactory(this, predicate, context, true));
},
find: function(predicate, context, notSetValue) {
var entry = this.findEntry(predicate, context);
return entry ? entry[1] : notSetValue;
},
forEach: function(sideEffect, context) {
assertNotInfinite(this.size);
return this.__iterate(context ? sideEffect.bind(context) : sideEffect);
},
join: function(separator) {
assertNotInfinite(this.size);
separator = separator !== undefined ? '' + separator : ',';
var joined = '';
var isFirst = true;
this.__iterate(function(v ) {
isFirst ? (isFirst = false) : (joined += separator);
joined += v !== null && v !== undefined ? v.toString() : '';
});
return joined;
},
keys: function() {
return this.__iterator(ITERATE_KEYS);
},
map: function(mapper, context) {
return reify(this, mapFactory(this, mapper, context));
},
reduce: function(reducer, initialReduction, context) {
assertNotInfinite(this.size);
var reduction;
var useFirst;
if (arguments.length < 2) {
useFirst = true;
} else {
reduction = initialReduction;
}
this.__iterate(function(v, k, c) {
if (useFirst) {
useFirst = false;
reduction = v;
} else {
reduction = reducer.call(context, reduction, v, k, c);
}
});
return reduction;
},
reduceRight: function(reducer, initialReduction, context) {
var reversed = this.toKeyedSeq().reverse();
return reversed.reduce.apply(reversed, arguments);
},
reverse: function() {
return reify(this, reverseFactory(this, true));
},
slice: function(begin, end) {
return reify(this, sliceFactory(this, begin, end, true));
},
some: function(predicate, context) {
return !this.every(not(predicate), context);
},
sort: function(comparator) {
return reify(this, sortFactory(this, comparator));
},
values: function() {
return this.__iterator(ITERATE_VALUES);
},
// ### More sequential methods
butLast: function() {
return this.slice(0, -1);
},
isEmpty: function() {
return this.size !== undefined ? this.size === 0 : !this.some(function() {return true});
},
count: function(predicate, context) {
return ensureSize(
predicate ? this.toSeq().filter(predicate, context) : this
);
},
countBy: function(grouper, context) {
return countByFactory(this, grouper, context);
},
equals: function(other) {
return deepEqual(this, other);
},
entrySeq: function() {
var iterable = this;
if (iterable._cache) {
// We cache as an entries array, so we can just return the cache!
return new ArraySeq(iterable._cache);
}
var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq();
entriesSequence.fromEntrySeq = function() {return iterable.toSeq()};
return entriesSequence;
},
filterNot: function(predicate, context) {
return this.filter(not(predicate), context);
},
findEntry: function(predicate, context, notSetValue) {
var found = notSetValue;
this.__iterate(function(v, k, c) {
if (predicate.call(context, v, k, c)) {
found = [k, v];
return false;
}
});
return found;
},
findKey: function(predicate, context) {
var entry = this.findEntry(predicate, context);
return entry && entry[0];
},
findLast: function(predicate, context, notSetValue) {
return this.toKeyedSeq().reverse().find(predicate, context, notSetValue);
},
findLastEntry: function(predicate, context, notSetValue) {
return this.toKeyedSeq().reverse().findEntry(predicate, context, notSetValue);
},
findLastKey: function(predicate, context) {
return this.toKeyedSeq().reverse().findKey(predicate, context);
},
first: function() {
return this.find(returnTrue);
},
flatMap: function(mapper, context) {
return reify(this, flatMapFactory(this, mapper, context));
},
flatten: function(depth) {
return reify(this, flattenFactory(this, depth, true));
},
fromEntrySeq: function() {
return new FromEntriesSequence(this);
},
get: function(searchKey, notSetValue) {
return this.find(function(_, key) {return is(key, searchKey)}, undefined, notSetValue);
},
getIn: function(searchKeyPath, notSetValue) {
var nested = this;
// Note: in an ES6 environment, we would prefer:
// for (var key of searchKeyPath) {
var iter = forceIterator(searchKeyPath);
var step;
while (!(step = iter.next()).done) {
var key = step.value;
nested = nested && nested.get ? nested.get(key, NOT_SET) : NOT_SET;
if (nested === NOT_SET) {
return notSetValue;
}
}
return nested;
},
groupBy: function(grouper, context) {
return groupByFactory(this, grouper, context);
},
has: function(searchKey) {
return this.get(searchKey, NOT_SET) !== NOT_SET;
},
hasIn: function(searchKeyPath) {
return this.getIn(searchKeyPath, NOT_SET) !== NOT_SET;
},
isSubset: function(iter) {
iter = typeof iter.includes === 'function' ? iter : Iterable(iter);
return this.every(function(value ) {return iter.includes(value)});
},
isSuperset: function(iter) {
iter = typeof iter.isSubset === 'function' ? iter : Iterable(iter);
return iter.isSubset(this);
},
keyOf: function(searchValue) {
return this.findKey(function(value ) {return is(value, searchValue)});
},
keySeq: function() {
return this.toSeq().map(keyMapper).toIndexedSeq();
},
last: function() {
return this.toSeq().reverse().first();
},
lastKeyOf: function(searchValue) {
return this.toKeyedSeq().reverse().keyOf(searchValue);
},
max: function(comparator) {
return maxFactory(this, comparator);
},
maxBy: function(mapper, comparator) {
return maxFactory(this, comparator, mapper);
},
min: function(comparator) {
return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator);
},
minBy: function(mapper, comparator) {
return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper);
},
rest: function() {
return this.slice(1);
},
skip: function(amount) {
return this.slice(Math.max(0, amount));
},
skipLast: function(amount) {
return reify(this, this.toSeq().reverse().skip(amount).reverse());
},
skipWhile: function(predicate, context) {
return reify(this, skipWhileFactory(this, predicate, context, true));
},
skipUntil: function(predicate, context) {
return this.skipWhile(not(predicate), context);
},
sortBy: function(mapper, comparator) {
return reify(this, sortFactory(this, comparator, mapper));
},
take: function(amount) {
return this.slice(0, Math.max(0, amount));
},
takeLast: function(amount) {
return reify(this, this.toSeq().reverse().take(amount).reverse());
},
takeWhile: function(predicate, context) {
return reify(this, takeWhileFactory(this, predicate, context));
},
takeUntil: function(predicate, context) {
return this.takeWhile(not(predicate), context);
},
valueSeq: function() {
return this.toIndexedSeq();
},
// ### Hashable Object
hashCode: function() {
return this.__hash || (this.__hash = hashIterable(this));
}
// ### Internal
// abstract __iterate(fn, reverse)
// abstract __iterator(type, reverse)
});
// var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@';
// var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';
// var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@';
// var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';
var IterablePrototype = Iterable.prototype;
IterablePrototype[IS_ITERABLE_SENTINEL] = true;
IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values;
IterablePrototype.__toJS = IterablePrototype.toArray;
IterablePrototype.__toStringMapper = quoteString;
IterablePrototype.inspect =
IterablePrototype.toSource = function() { return this.toString(); };
IterablePrototype.chain = IterablePrototype.flatMap;
IterablePrototype.contains = IterablePrototype.includes;
mixin(KeyedIterable, {
// ### More sequential methods
flip: function() {
return reify(this, flipFactory(this));
},
mapEntries: function(mapper, context) {var this$0 = this;
var iterations = 0;
return reify(this,
this.toSeq().map(
function(v, k) {return mapper.call(context, [k, v], iterations++, this$0)}
).fromEntrySeq()
);
},
mapKeys: function(mapper, context) {var this$0 = this;
return reify(this,
this.toSeq().flip().map(
function(k, v) {return mapper.call(context, k, v, this$0)}
).flip()
);
}
});
var KeyedIterablePrototype = KeyedIterable.prototype;
KeyedIterablePrototype[IS_KEYED_SENTINEL] = true;
KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries;
KeyedIterablePrototype.__toJS = IterablePrototype.toObject;
KeyedIterablePrototype.__toStringMapper = function(v, k) {return JSON.stringify(k) + ': ' + quoteString(v)};
mixin(IndexedIterable, {
// ### Conversion to other types
toKeyedSeq: function() {
return new ToKeyedSequence(this, false);
},
// ### ES6 Collection methods (ES6 Array and Map)
filter: function(predicate, context) {
return reify(this, filterFactory(this, predicate, context, false));
},
findIndex: function(predicate, context) {
var entry = this.findEntry(predicate, context);
return entry ? entry[0] : -1;
},
indexOf: function(searchValue) {
var key = this.keyOf(searchValue);
return key === undefined ? -1 : key;
},
lastIndexOf: function(searchValue) {
var key = this.lastKeyOf(searchValue);
return key === undefined ? -1 : key;
},
reverse: function() {
return reify(this, reverseFactory(this, false));
},
slice: function(begin, end) {
return reify(this, sliceFactory(this, begin, end, false));
},
splice: function(index, removeNum /*, ...values*/) {
var numArgs = arguments.length;
removeNum = Math.max(removeNum | 0, 0);
if (numArgs === 0 || (numArgs === 2 && !removeNum)) {
return this;
}
// If index is negative, it should resolve relative to the size of the
// collection. However size may be expensive to compute if not cached, so
// only call count() if the number is in fact negative.
index = resolveBegin(index, index < 0 ? this.count() : this.size);
var spliced = this.slice(0, index);
return reify(
this,
numArgs === 1 ?
spliced :
spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum))
);
},
// ### More collection methods
findLastIndex: function(predicate, context) {
var entry = this.findLastEntry(predicate, context);
return entry ? entry[0] : -1;
},
first: function() {
return this.get(0);
},
flatten: function(depth) {
return reify(this, flattenFactory(this, depth, false));
},
get: function(index, notSetValue) {
index = wrapIndex(this, index);
return (index < 0 || (this.size === Infinity ||
(this.size !== undefined && index > this.size))) ?
notSetValue :
this.find(function(_, key) {return key === index}, undefined, notSetValue);
},
has: function(index) {
index = wrapIndex(this, index);
return index >= 0 && (this.size !== undefined ?
this.size === Infinity || index < this.size :
this.indexOf(index) !== -1
);
},
interpose: function(separator) {
return reify(this, interposeFactory(this, separator));
},
interleave: function(/*...iterables*/) {
var iterables = [this].concat(arrCopy(arguments));
var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, iterables);
var interleaved = zipped.flatten(true);
if (zipped.size) {
interleaved.size = zipped.size * iterables.length;
}
return reify(this, interleaved);
},
keySeq: function() {
return Range(0, this.size);
},
last: function() {
return this.get(-1);
},
skipWhile: function(predicate, context) {
return reify(this, skipWhileFactory(this, predicate, context, false));
},
zip: function(/*, ...iterables */) {
var iterables = [this].concat(arrCopy(arguments));
return reify(this, zipWithFactory(this, defaultZipper, iterables));
},
zipWith: function(zipper/*, ...iterables */) {
var iterables = arrCopy(arguments);
iterables[0] = this;
return reify(this, zipWithFactory(this, zipper, iterables));
}
});
IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true;
IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true;
mixin(SetIterable, {
// ### ES6 Collection methods (ES6 Array and Map)
get: function(value, notSetValue) {
return this.has(value) ? value : notSetValue;
},
includes: function(value) {
return this.has(value);
},
// ### More sequential methods
keySeq: function() {
return this.valueSeq();
}
});
SetIterable.prototype.has = IterablePrototype.includes;
SetIterable.prototype.contains = SetIterable.prototype.includes;
// Mixin subclasses
mixin(KeyedSeq, KeyedIterable.prototype);
mixin(IndexedSeq, IndexedIterable.prototype);
mixin(SetSeq, SetIterable.prototype);
mixin(KeyedCollection, KeyedIterable.prototype);
mixin(IndexedCollection, IndexedIterable.prototype);
mixin(SetCollection, SetIterable.prototype);
// #pragma Helper functions
function keyMapper(v, k) {
return k;
}
function entryMapper(v, k) {
return [k, v];
}
function not(predicate) {
return function() {
return !predicate.apply(this, arguments);
}
}
function neg(predicate) {
return function() {
return -predicate.apply(this, arguments);
}
}
function quoteString(value) {
return typeof value === 'string' ? JSON.stringify(value) : String(value);
}
function defaultZipper() {
return arrCopy(arguments);
}
function defaultNegComparator(a, b) {
return a < b ? 1 : a > b ? -1 : 0;
}
function hashIterable(iterable) {
if (iterable.size === Infinity) {
return 0;
}
var ordered = isOrdered(iterable);
var keyed = isKeyed(iterable);
var h = ordered ? 1 : 0;
var size = iterable.__iterate(
keyed ?
ordered ?
function(v, k) { h = 31 * h + hashMerge(hash(v), hash(k)) | 0; } :
function(v, k) { h = h + hashMerge(hash(v), hash(k)) | 0; } :
ordered ?
function(v ) { h = 31 * h + hash(v) | 0; } :
function(v ) { h = h + hash(v) | 0; }
);
return murmurHashOfSize(size, h);
}
function murmurHashOfSize(size, h) {
h = imul(h, 0xCC9E2D51);
h = imul(h << 15 | h >>> -15, 0x1B873593);
h = imul(h << 13 | h >>> -13, 5);
h = (h + 0xE6546B64 | 0) ^ size;
h = imul(h ^ h >>> 16, 0x85EBCA6B);
h = imul(h ^ h >>> 13, 0xC2B2AE35);
h = smi(h ^ h >>> 16);
return h;
}
function hashMerge(a, b) {
return a ^ b + 0x9E3779B9 + (a << 6) + (a >> 2) | 0; // int
}
var Immutable = {
Iterable: Iterable,
Seq: Seq,
Collection: Collection,
Map: Map,
OrderedMap: OrderedMap,
List: List,
Stack: Stack,
Set: Set,
OrderedSet: OrderedSet,
Record: Record,
Range: Range,
Repeat: Repeat,
is: is,
fromJS: fromJS
};
return Immutable;
}));
},{}],221:[function(require,module,exports){
// Utility protocol for measuring when a stateChange takes effect.
var RandomID = require('./randomid.js');
var Dataspace = require('./dataspace.js').Dataspace;
var Struct = require('./struct.js');
var Patch = require('./patch.js');
var ack = Struct.makeConstructor('ack', ['id']);
function Ack(metaLevel, id) {
this.metaLevel = metaLevel || 0;
this.id = id || RandomID.randomId(16);
this.done = false;
}
Ack.prototype.arm = function () {
Dataspace.stateChange(Patch.sub(ack(this.id), this.metaLevel));
Dataspace.send(ack(this.id), this.metaLevel);
};
Ack.prototype.disarm = function () {
Dataspace.stateChange(Patch.unsub(ack(this.id), this.metaLevel));
};
Ack.prototype.check = function (e) {
if (!this.done) {
if (e.type === 'message') {
var m = Patch.stripAtMeta(e.message, this.metaLevel);
if (ack.isClassOf(m) && m[0] === this.id) {
this.disarm();
this.done = true;
}
}
}
return this.done;
};
///////////////////////////////////////////////////////////////////////////
module.exports.ack = ack;
module.exports.Ack = Ack;
},{"./dataspace.js":225,"./patch.js":230,"./randomid.js":231,"./struct.js":235}],222:[function(require,module,exports){
'use strict';
var Immutable = require('immutable');
var _Dataspace = require('./dataspace.js');
var Dataspace = _Dataspace.Dataspace;
var __ = _Dataspace.__;
var Mux = require('./mux.js');
var Patch = require('./patch.js');
var Trie = require('./trie.js');
var Util = require('./util.js');
//---------------------------------------------------------------------------
function spawnActor(state, bootFn, optName) {
Dataspace.spawn(new Actor(state, bootFn, optName));
}
function Actor(state, bootFn, optName) {
this.state = state;
this.facets = Immutable.Set();
this.mux = new Mux.Mux();
this.previousKnowledge = Trie.emptyTrie;
this.knowledge = Trie.emptyTrie;
this.pendingActions = [];
if (typeof optName !== 'undefined') {
this.name = optName;
}
this.boot = function() {
var self = this;
withCurrentFacet(null, function () {
bootFn.call(self.state);
});
self.checkForTermination();
};
}
Actor.prototype.handleEvent = function(e) {
if (e.type === 'stateChange') {
this.previousKnowledge = this.knowledge;
this.knowledge = e.patch.updateInterests(this.knowledge);
}
if (this.pendingActions.length > 0) {
throw new Error('Syndicate: pendingActions must not be nonempty at start of handleEvent');
}
this.facets.forEach(function (f) {
withCurrentFacet(f, function () { f.handleEvent(e); });
});
while (this.pendingActions.length) {
var entry = this.pendingActions.shift();
withCurrentFacet(entry.facet, entry.action);
}
this.facets.forEach(function (f) {
withCurrentFacet(f, function () { f.refresh(); });
});
this.checkForTermination();
};
Actor.prototype.pushAction = function (a) {
this.pendingActions.push({facet: Facet.current, action: a});
};
Actor.prototype.addFacet = function(facet) {
this.facets = this.facets.add(facet);
};
Actor.prototype.removeFacet = function(facet) {
this.facets = this.facets.remove(facet);
};
Actor.prototype.checkForTermination = function() {
if (this.facets.isEmpty()) {
Dataspace.exit();
}
};
//---------------------------------------------------------------------------
function createFacet() {
return new Facet(Dataspace.activeBehavior());
}
function Facet(actor) {
this.actor = actor;
this.endpoints = Immutable.Map();
this.initBlocks = Immutable.List();
this.doneBlocks = Immutable.List();
this.children = Immutable.Set();
this.parent = Facet.current;
this.terminated = false;
}
Facet.current = null;
function withCurrentFacet(facet, f) {
var previous = Facet.current;
Facet.current = facet;
var result;
try {
result = f();
} catch (e) {
Facet.current = previous;
throw e;
}
Facet.current = previous;
return result;
}
Facet.prototype.handleEvent = function(e) {
var facet = this;
facet.endpoints.forEach(function(endpoint) {
endpoint.handlerFn.call(facet.actor.state, e);
});
};
Facet.prototype.addAssertion = function(assertionFn) {
return this.addEndpoint(new Endpoint(assertionFn, function(e) {}));
};
Facet.prototype.addOnEventHandler = function(handler) {
var facet = this;
return this.addEndpoint(new Endpoint(function () { return Patch.emptyPatch; }, function (e) {
facet.actor.pushAction(function () { handler(e); });
}));
};
Facet.prototype.onEvent = function(isTerminal, eventType, subscriptionFn, projectionFn, handlerFn) {
var facet = this;
switch (eventType) {
case 'message':
return this.addEndpoint(new Endpoint(subscriptionFn, function(e) {
if (e.type === 'message') {
var proj = projectionFn.call(facet.actor.state);
var spec = Patch.prependAtMeta(proj.assertion, proj.metalevel);
var match = Trie.matchPattern(e.message, spec);
// console.log(match);
if (match) {
if (isTerminal) { facet.terminate(); }
facet.actor.pushAction(function () { Util.kwApply(handlerFn, facet.actor.state, match); });
}
}
}));
case 'asserted': /* fall through */
case 'retracted':
return this.addEndpoint(new Endpoint(subscriptionFn, function(e) {
if (e.type === 'stateChange') {
var proj = projectionFn.call(facet.actor.state);
var spec = Patch.prependAtMeta(proj.assertion, proj.metalevel);
var objects = Trie.projectObjects(eventType === 'asserted'
? e.patch.added
: e.patch.removed,
spec);
if (objects && objects.size > 0) {
var shouldTerminate = isTerminal;
objects.forEach(function (o) {
var instantiated = Trie.instantiateProjection(spec, o);
if (facet.interestWas(eventType, instantiated)) {
if (shouldTerminate) {
shouldTerminate = false;
facet.terminate();
}
facet.actor.pushAction(function () {
Util.kwApply(handlerFn, facet.actor.state, o);
});
}
});
}
}
}));
case 'risingEdge':
var endpoint = new Endpoint(function() { return Patch.emptyPatch; },
function(e) {
var newValue = subscriptionFn.call(facet.actor.state);
if (newValue && !this.currentValue) {
if (isTerminal) { facet.terminate(); }
facet.actor.pushAction(function () {
handlerFn.call(facet.actor.state);
});
}
this.currentValue = newValue;
});
endpoint.currentValue = false;
return this.addEndpoint(endpoint);
default:
throw new Error("Unsupported Facet eventType: " + eventType);
}
};
Facet.prototype.interestWas = function(assertedOrRetracted, pat) {
function orStar(a, b) { return (a || b); }
var oldExists = Trie.matchValue(this.actor.previousKnowledge, pat, false, orStar);
var newExists = Trie.matchValue(this.actor.knowledge, pat, false, orStar);
switch (assertedOrRetracted) {
case 'asserted':
return !oldExists && newExists;
case 'retracted':
return oldExists && !newExists;
default:
throw new Error("Unexpected assertedOrRetracted in Facet.interestWas: " + assertedOrRetracted);
}
};
Facet.prototype.addEndpoint = function(endpoint) {
var patch = endpoint.subscriptionFn.call(this.actor.state);
var r = this.actor.mux.addStream(patch);
this.endpoints = this.endpoints.set(r.pid, endpoint);
Dataspace.stateChange(r.deltaAggregate);
return this; // for chaining
};
Facet.prototype.addInitBlock = function(thunk) {
this.initBlocks = this.initBlocks.push(thunk);
return this;
};
Facet.prototype.addDoneBlock = function(thunk) {
this.doneBlocks = this.doneBlocks.push(thunk);
return this;
};
Facet.prototype.refresh = function() {
var facet = this;
var aggregate = Patch.emptyPatch;
this.endpoints.forEach(function(endpoint, eid) {
var patch = Patch.retract(__).andThen(endpoint.subscriptionFn.call(facet.actor.state));
var r = facet.actor.mux.updateStream(eid, patch);
aggregate = aggregate.andThen(r.deltaAggregate);
});
Dataspace.stateChange(aggregate);
};
Facet.prototype.completeBuild = function() {
var facet = this;
this.actor.addFacet(this);
if (this.parent) {
this.parent.children = this.parent.children.add(this);
}
withCurrentFacet(facet, function () {
facet.initBlocks.forEach(function(b) { b.call(facet.actor.state); });
});
var initialEvent = _Dataspace.stateChange(new Patch.Patch(facet.actor.knowledge, Trie.emptyTrie));
withCurrentFacet(facet, function () { facet.handleEvent(initialEvent); });
};
Facet.prototype.terminate = function() {
var facet = this;
if (facet.terminated) return;
facet.terminated = true;
var aggregate = Patch.emptyPatch;
this.endpoints.forEach(function(endpoint, eid) {
var r = facet.actor.mux.removeStream(eid);
aggregate = aggregate.andThen(r.deltaAggregate);
});
Dataspace.stateChange(aggregate);
this.endpoints = Immutable.Map();
if (this.parent) {
this.parent.children = this.parent.children.remove(this);
}
this.actor.removeFacet(this);
withCurrentFacet(facet, function () {
facet.doneBlocks.forEach(function(b) { b.call(facet.actor.state); });
});
this.children.forEach(function (child) {
child.terminate();
});
};
//---------------------------------------------------------------------------
function Endpoint(subscriptionFn, handlerFn) {
this.subscriptionFn = subscriptionFn;
this.handlerFn = handlerFn;
}
//---------------------------------------------------------------------------
module.exports.spawnActor = spawnActor;
module.exports.createFacet = createFacet;
},{"./dataspace.js":225,"./mux.js":229,"./patch.js":230,"./trie.js":237,"./util.js":239,"immutable":220}],223:[function(require,module,exports){
"use strict";
// WebSocket-based Syndicate broker client
var Immutable = require('immutable');
var Trie = require('./trie.js');
var Patch = require('./patch.js');
var Struct = require('./struct.js');
var DemandMatcher = require('./demand-matcher.js').DemandMatcher;
var Codec = require('./codec');
var Dataspace_ = require("./dataspace.js");
var Dataspace = Dataspace_.Dataspace;
var __ = Dataspace_.__;
var _$ = Dataspace_._$;
var DEFAULT_RECONNECT_DELAY = 100; // ms
var MAX_RECONNECT_DELAY = 30000; // ms
var DEFAULT_IDLE_TIMEOUT = 300000; // ms; i.e., 5 minutes
var DEFAULT_PING_INTERVAL = DEFAULT_IDLE_TIMEOUT - 10000; // ms
var toBroker = Struct.makeConstructor('toBroker', ['url', 'assertion']);
var fromBroker = Struct.makeConstructor('fromBroker', ['url', 'assertion']);
var brokerConnection = Struct.makeConstructor('brokerConnection', ['url']);
var brokerConnected = Struct.makeConstructor('brokerConnected', ['url']);
var forceBrokerDisconnect = Struct.makeConstructor('forceBrokerDisconnect', ['url']);
function spawnBrokerClientDriver() {
var URL = _$('url'); // capture used to extract URL
Dataspace.spawn(
new Dataspace(function () {
Dataspace.spawn(
new DemandMatcher([brokerConnection(URL)],
[brokerConnection(URL)],
function (c) {
Dataspace.spawn(new BrokerClientConnection(c.url));
},
{
demandMetaLevel: 1,
supplyMetaLevel: 0
}));
}));
}
function BrokerClientConnection(wsurl) {
this.wsurl = wsurl;
this.sock = null;
this.sendsAttempted = 0;
this.sendsTransmitted = 0;
this.receiveCount = 0;
this.connectionCount = 0;
this.reconnectDelay = DEFAULT_RECONNECT_DELAY;
this.idleTimeout = DEFAULT_IDLE_TIMEOUT;
this.pingInterval = DEFAULT_PING_INTERVAL;
this.localAssertions = Trie.emptyTrie;
this.connectionInterrupted = false;
this.activityTimestamp = 0;
this.idleTimer = null;
this.pingTimer = null;
}
BrokerClientConnection.prototype.clearHeartbeatTimers = function () {
if (this.idleTimer) { clearTimeout(this.idleTimer); this.idleTimer = null; }
if (this.pingTimer) { clearTimeout(this.pingTimer); this.pingTimer = null; }
};
BrokerClientConnection.prototype.recordActivity = function () {
var self = this;
this.activityTimestamp = +(new Date());
this.clearHeartbeatTimers();
this.idleTimer = setTimeout(function () { self.forceclose(); }, this.idleTimeout);
this.pingTimer = setTimeout(function () { self.safeSend(JSON.stringify("ping")) },
this.pingInterval);
};
BrokerClientConnection.prototype.boot = function () {
this.reconnect();
var initialAssertions =
Patch.sub(toBroker(this.wsurl, __), 1) // read assertions to go out
.andThen(Patch.sub(Patch.observe(fromBroker(this.wsurl, __)), 1)) // and monitor interests
.andThen(Patch.assert(brokerConnection(this.wsurl))) // signal to DemandMatcher that we exist
.andThen(Patch.sub(brokerConnection(this.wsurl), 1)) // track demand
.andThen(Patch.sub(forceBrokerDisconnect(this.wsurl), 1))
;
return initialAssertions;
};
BrokerClientConnection.prototype.trapexit = function () {
this.forceclose();
};
BrokerClientConnection.prototype.isConnected = function () {
return this.sock && this.sock.readyState === this.sock.OPEN;
};
BrokerClientConnection.prototype.safeSend = function (m) {
// console.log('safeSend', m);
try {
this.sendsAttempted++;
if (this.isConnected()) {
this.sock.send(m);
this.sendsTransmitted++;
}
} catch (e) {
console.warn("Trapped exn while sending", e);
}
};
BrokerClientConnection.prototype.sendPatch = function (p) {
var j = JSON.stringify(Codec.encodeEvent(Syndicate.stateChange(p)));
this.safeSend(j);
};
BrokerClientConnection.prototype.handleEvent = function (e) {
// console.log("BrokerClientConnection.handleEvent", e);
switch (e.type) {
case "stateChange":
if (e.patch.project(Patch.atMeta(brokerConnection(_$))).hasRemoved()) {
// console.log("Client is no longer interested in this connection", this.wsurl);
Dataspace.exit();
}
var pTo = e.patch.project(Patch.atMeta(toBroker(__, _$)));
var pObsFrom = e.patch.project(Patch.atMeta(Patch.observe(fromBroker(__, _$))));
pObsFrom = new Patch.Patch(
Trie.compilePattern(true, Patch.observe(Trie.embeddedTrie(pObsFrom.added))),
Trie.compilePattern(true, Patch.observe(Trie.embeddedTrie(pObsFrom.removed))));
var newLocalAssertions = this.localAssertions;
newLocalAssertions = pTo.label(Immutable.Set.of("to")).applyTo(newLocalAssertions);
newLocalAssertions = pObsFrom.label(Immutable.Set.of("obsFrom")).applyTo(newLocalAssertions);
var trueSet = Immutable.Set.of(true);
var alwaysTrueSet = function (v) { return trueSet; };
var p = Patch.computePatch(Trie.relabel(this.localAssertions, alwaysTrueSet),
Trie.relabel(newLocalAssertions, alwaysTrueSet));
this.localAssertions = newLocalAssertions;
// console.log("localAssertions");
// console.log(Trie.prettyTrie(this.localAssertions));
// console.log(p.pretty());
this.sendPatch(p);
break;
case "message":
var m = e.message;
if (Patch.atMeta.isClassOf(m)) {
m = m[0];
if (toBroker.isClassOf(m)) {
var j = JSON.stringify(Codec.encodeEvent(Syndicate.message(m[1])));
this.safeSend(j);
} else if (forceBrokerDisconnect.isClassOf(m)) {
this.forceclose();
}
}
break;
}
};
BrokerClientConnection.prototype.forceclose = function (keepReconnectDelay) {
if (!keepReconnectDelay) {
this.reconnectDelay = DEFAULT_RECONNECT_DELAY;
}
this.clearHeartbeatTimers();
if (this.sock) {
console.log("BrokerClientConnection.forceclose called");
this.sock.close();
this.sock = null;
}
};
BrokerClientConnection.prototype.reconnect = function () {
var self = this;
this.forceclose(true);
this.connectionCount++;
this.sock = new WebSocket(this.wsurl);
this.sock.onopen = Dataspace.wrap(function (e) { return self.onopen(e); });
this.sock.onmessage = Dataspace.wrap(function (e) {
self.receiveCount++;
return self.onmessage(e);
});
this.sock.onclose = Dataspace.wrap(function (e) { return self.onclose(e); });
};
BrokerClientConnection.prototype.onopen = function (e) {
console.log("connected to " + this.sock.url);
this.recordActivity();
Dataspace.stateChange(Patch.assert(brokerConnected(this.wsurl), 1));
this.reconnectDelay = DEFAULT_RECONNECT_DELAY;
this.sendPatch((new Patch.Patch(this.localAssertions, Trie.emptyTrie)).strip());
};
BrokerClientConnection.prototype.onmessage = function (wse) {
// console.log("onmessage", wse);
this.recordActivity();
var j = JSON.parse(wse.data, Struct.reviver);
if (j === "ping") {
this.safeSend(JSON.stringify("pong"));
return;
} else if (j === "pong") {
return; // recordActivity already took care of our timers
}
var e = Codec.decodeAction(j);
switch (e.type) {
case "stateChange": {
var added = fromBroker(this.wsurl, Trie.embeddedTrie(e.patch.added));
var removed = fromBroker(this.wsurl, Trie.embeddedTrie(e.patch.removed));
var p = Patch.assert(added, 1).andThen(Patch.retract(removed, 1));
if (!p.isEmpty()) {
if (this.connectionInterrupted) {
p = Patch.retract(fromBroker(this.wsurl, __), 1).andThen(p);
this.connectionInterrupted = false;
}
// console.log('applying incoming stateChange');
// console.log(p.pretty());
Dataspace.stateChange(p);
}
break;
}
case "message": {
Dataspace.send(fromBroker(this.wsurl, e.message), 1);
break;
}
}
};
BrokerClientConnection.prototype.onclose = function (e) {
var self = this;
// console.log("onclose", e);
Dataspace.stateChange(Patch.retract(brokerConnected(this.wsurl), 1));
this.connectionInterrupted = true;
console.log("reconnecting to " + this.wsurl + " in " + this.reconnectDelay + "ms");
setTimeout(Dataspace.wrap(function () { self.reconnect(); }), this.reconnectDelay);
this.reconnectDelay = this.reconnectDelay * 1.618 + (Math.random() * 1000);
this.reconnectDelay =
this.reconnectDelay > MAX_RECONNECT_DELAY
? MAX_RECONNECT_DELAY + (Math.random() * 1000)
: this.reconnectDelay;
};
///////////////////////////////////////////////////////////////////////////
module.exports.toBroker = toBroker;
module.exports.fromBroker = fromBroker;
module.exports.brokerConnection = brokerConnection;
module.exports.brokerConnected = brokerConnected;
module.exports.forceBrokerDisconnect = forceBrokerDisconnect;
module.exports.spawnBrokerClientDriver = spawnBrokerClientDriver;
module.exports.BrokerClientConnection = BrokerClientConnection;
},{"./codec":224,"./dataspace.js":225,"./demand-matcher.js":226,"./patch.js":230,"./struct.js":235,"./trie.js":237,"immutable":220}],224:[function(require,module,exports){
"use strict";
// Wire protocol representation of events and actions
var Trie = require('./trie.js');
var Patch = require('./patch.js');
var Struct = require('./struct.js');
function _encode(e) {
switch (e.type) {
case "stateChange":
return ["patch", e.patch.toJSON()];
case "message":
return ["message", e.message];
}
}
function _decode(what) {
return function (j) {
switch (j[0]) {
case "patch":
return Syndicate.stateChange(Patch.fromJSON(j[1]));
case "message":
return Syndicate.message(j[1]);
default:
throw new Error("Invalid JSON-encoded " + what + ": " + JSON.stringify(j));
}
};
}
///////////////////////////////////////////////////////////////////////////
module.exports.encodeEvent = _encode;
module.exports.decodeEvent = _decode("event");
module.exports.encodeAction = _encode;
module.exports.decodeAction = _decode("action");
},{"./patch.js":230,"./struct.js":235,"./trie.js":237}],225:[function(require,module,exports){
"use strict";
var Immutable = require('immutable');
var Patch = require('./patch.js');
var Mux = require('./mux.js');
/*---------------------------------------------------------------------------*/
/* Events and Actions */
function stateChange(patch) {
return { type: 'stateChange', patch: patch };
}
function message(body) {
return { type: 'message', message: body };
}
function spawn(behavior) {
return { type: 'spawn', behavior: behavior };
}
function terminate() {
return { type: 'terminate' };
}
function terminateDataspace() {
return { type: 'terminateDataspace' };
}
/*---------------------------------------------------------------------------*/
/* Dataspace */
function Dataspace(bootFn) {
this.pendingActions = Immutable.List(); // of [pid, Action]
this.processTable = Immutable.Map(); // pid -> Behavior
this.runnablePids = Immutable.Set(); // of pid
this.mux = new Mux.Mux();
this.onStateChange = function (mux, deltaAggregate) {};
this.asChild('meta', function () { return bootFn() }, true);
}
// Class state and methods
Dataspace.noisy = false;
Dataspace.stack = Immutable.List();
Dataspace.current = function () {
return Dataspace.stack.last().dataspace;
};
Dataspace.activePid = function () {
return Dataspace.stack.last().activePid;
};
Dataspace.activeBehavior = function () {
var entry = Dataspace.stack.last();
var p = entry.dataspace.processTable.get(entry.activePid);
return p ? p.behavior : null;
};
Dataspace.withDataspaceStack = function (stack, f) {
var oldStack = Dataspace.stack;
Dataspace.stack = stack;
var result;
try {
result = f();
} catch (e) {
Dataspace.stack = oldStack;
throw e;
}
Dataspace.stack = oldStack;
return result;
};
Dataspace.wrap = function (f) {
var savedStack = Dataspace.stack;
return function () {
var actuals = arguments;
return Dataspace.withDataspaceStack(savedStack, function () {
var result = Dataspace.current().asChild(Dataspace.activePid(), function () {
return f.apply(null, actuals);
});
Dataspace.stack.reverse().forEach(function (entry) {
entry.dataspace.markRunnable(entry.activePid);
});
return result;
});
};
};
Dataspace.enqueueAction = function (action) {
var entry = Dataspace.stack.last();
entry.dataspace.enqueueAction(entry.activePid, action);
};
Dataspace.send = function (body, metaLevel) {
Dataspace.enqueueAction(message(Patch.prependAtMeta(body, metaLevel || 0)));
};
Dataspace.stateChange = function (patch) {
Dataspace.enqueueAction(stateChange(patch));
};
Dataspace.spawn = function (behavior) {
Dataspace.enqueueAction(spawn(behavior));
};
Dataspace.exit = function (exn) {
Dataspace.current().kill(Dataspace.activePid(), exn);
};
Dataspace.exitDataspace = function () {
Dataspace.enqueueAction(terminateDataspace());
};
Dataspace.inertBehavior = function (oldBehavior) {
var b = { handleEvent: function (e) {} };
if ('name' in oldBehavior) {
b.name = oldBehavior.name;
}
return b;
};
// Instance methods
Dataspace.prototype.debugName = function (pid) {
var p = this.processTable.get(pid, null);
if (p === null) {
return '(dead)[' + pid + ']';
}
if ('name' in p.behavior) {
return JSON.stringify(p.behavior.name) + '[' + pid + ']';
}
return '(anon)[' + pid + ']';
};
Dataspace.prototype.asChild = function (pid, f, omitLivenessCheck) {
var self = this;
var p = this.processTable.get(pid, null);
if (!omitLivenessCheck && (p === null)) {
console.warn("Dataspace.asChild eliding invocation of dead process", this.debugName(pid));
return;
}
return Dataspace.withDataspaceStack(
Dataspace.stack.push({ dataspace: this, activePid: pid }),
function () {
try {
return f(p);
} catch (e) {
self.kill(pid, e);
}
});
};
Dataspace.prototype.kill = function (pid, exn) {
if (exn) {
if (exn.stack) {
console.error("Process crashed", this.debugName(pid), exn, exn.stack);
} else {
console.error("Process crashed", this.debugName(pid), exn);
}
} else if (Dataspace.noisy) {
console.log("Process exiting", this.debugName(pid));
}
var p = this.processTable.get(pid);
this.processTable = this.processTable.set(pid, {
behavior: Dataspace.inertBehavior(p.behavior)
});
if (p) {
if (p.behavior.trapexit) {
this.asChild(pid, function () { return p.behavior.trapexit(exn); }, true);
}
this.enqueueAction(pid, terminate());
}
};
Dataspace.prototype.boot = function () {
// Needed in order for a new Dataspace to be marked as "runnable", so
// its initial actions get performed.
};
Dataspace.prototype.handleEvent = function (e) {
switch (e.type) {
case 'stateChange':
this.enqueueAction('meta', stateChange(e.patch.lift()));
break;
case 'message':
this.enqueueAction('meta', message(Patch.atMeta(e.message)));
break;
default:
var exn = new Error("Event type " + e.type + " not understood");
exn.event = e;
throw exn;
}
return true;
};
Dataspace.prototype.step = function () {
return this.dispatchActions()
&& this.runRunnablePids()
&& ((this.pendingActions.size > 0) || (this.runnablePids.size > 0));
};
Dataspace.prototype.enqueueAction = function (pid, action) {
this.pendingActions = this.pendingActions.push([pid, action]);
};
Dataspace.prototype.dispatchActions = function () {
var self = this;
var actionQueue = this.pendingActions;
this.pendingActions = Immutable.List();
var alive = true;
actionQueue.forEach(function (entry) {
var pid = entry[0];
var action = entry[1];
if (!self.interpretAction(pid, action)) {
alive = false;
return false;
}
});
return alive;
};
Dataspace.prototype.markRunnable = function (pid) {
this.runnablePids = this.runnablePids.add(pid);
};
Dataspace.prototype.runRunnablePids = function () {
var self = this;
var pidSet = this.runnablePids;
this.runnablePids = Immutable.Set();
pidSet.forEach(function (pid) {
var childBusy = self.asChild(pid, function (p) {
return p.behavior.step // exists, haven't called it yet
&& p.behavior.step();
});
if (childBusy) self.markRunnable(pid);
});
return true;
};
Dataspace.prototype.interpretAction = function (pid, action) {
var self = this;
switch (action.type) {
case 'stateChange':
var oldMux = this.mux.shallowCopy();
this.deliverPatches(oldMux, this.mux.updateStream(pid, action.patch));
return true;
case 'message':
if (Patch.observe.isClassOf(action.message)) {
console.warn('Process ' + this.debugName(pid) + ' sent message containing query',
action.message);
}
if (pid !== 'meta' && Patch.atMeta.isClassOf(action.message)) {
Dataspace.send(action.message[0]);
} else {
this.mux.routeMessage(action.message).forEach(function (pid) {
self.deliverEvent(pid, action);
});
}
return true;
case 'spawn':
var oldMux = this.mux.shallowCopy();
var p = { behavior: action.behavior };
var pid = this.mux.nextPid;
this.processTable = this.processTable.set(pid, p);
var initialPatch = Patch.emptyPatch;
if (p.behavior.boot) {
initialPatch = this.asChild(pid, function () { return p.behavior.boot() });
initialPatch = initialPatch || Patch.emptyPatch;
this.markRunnable(pid);
}
this.deliverPatches(oldMux, this.mux.addStream(initialPatch));
return true;
case 'terminate':
var oldMux = this.mux.shallowCopy();
this.deliverPatches(oldMux, this.mux.removeStream(pid));
if (Dataspace.noisy) console.log("Process exit complete", this.debugName(pid));
this.processTable = this.processTable.remove(pid);
return true;
case 'terminateDataspace':
Dataspace.exit();
return false;
default:
var exn = new Error("Action type " + action.type + " not understood");
exn.action = action;
throw exn;
}
};
Dataspace.prototype.deliverPatches = function (oldMux, updateStreamResult) {
var self = this;
var events = Mux.computeEvents(oldMux, this.mux, updateStreamResult);
events.eventMap.forEach(function (patch, pid) {
self.deliverEvent(pid, stateChange(patch));
});
events.metaEvents.forEach(Dataspace.stateChange);
if (!updateStreamResult.deltaAggregate.isEmpty()) {
this.onStateChange(this.mux, updateStreamResult.deltaAggregate);
}
};
Dataspace.prototype.deliverEvent = function (pid, event) {
var childBusy = this.asChild(pid, function (p) { return p.behavior.handleEvent(event); });
if (childBusy) this.markRunnable(pid);
};
Dataspace.prototype.setOnStateChange = function (handler) {
this.onStateChange = handler;
this.onStateChange(this.mux, Patch.emptyPatch);
};
///////////////////////////////////////////////////////////////////////////
module.exports.stateChange = stateChange;
module.exports.message = message;
module.exports.spawn = spawn;
module.exports.terminate = terminate;
module.exports.terminateDataspace = terminateDataspace;
module.exports.Dataspace = Dataspace;
},{"./mux.js":229,"./patch.js":230,"immutable":220}],226:[function(require,module,exports){
var Immutable = require('immutable');
var Trie = require('./trie.js');
var Patch = require('./patch.js');
var Util = require('./util.js');
///////////////////////////////////////////////////////////////////////////
// Protocol between DemandMatcher and taskSupervisor functions
// Bits:
var IS_CHANGING = 1;
var IS_PRESENT = 2;
// Bit combinations:
var LOW = 0 ;
var RISING = IS_CHANGING ;
var HIGH = IS_PRESENT ;
var FALLING = IS_PRESENT | IS_CHANGING ;
///////////////////////////////////////////////////////////////////////////
// Default task supervision strategy. See syndicate/doc/demand-matcher.md.
function defaultTaskSupervisor(demandState, supplyState, supervisionState, taskFn, onTaskExit) {
var oldESI = supervisionState ? supervisionState.expectSupplyIncrease : false;
var oldESD = supervisionState ? supervisionState.expectSupplyDecrease : false;
var newESI = oldESI;
var newESD = oldESD;
if ((demandState === FALLING) && ((supplyState === RISING) ||
(supplyState === HIGH) ||
oldESI)) {
newESD = true;
}
if (!oldESI && ((demandState === RISING) ||
(demandState === HIGH)) && ((supplyState === LOW) ||
(supplyState === FALLING))) {
if ((demandState === HIGH) && !oldESD) {
onTaskExit();
} else {
taskFn();
newESI = true;
}
}
if (supplyState === FALLING) newESD = false;
if (supplyState === RISING) newESI = false;
if (newESI || newESD) {
return { expectSupplyIncrease: newESI, expectSupplyDecrease: newESD };
} else {
return null;
}
}
function defaultOnTaskExit(captures) {
console.error("Syndicate: DemandMatcher detected unexpected drop in supply", captures);
}
///////////////////////////////////////////////////////////////////////////
// DemandMatcher itself
function DemandMatcher(demandSpecs, supplySpecs, startTask, options) {
options = Util.extend({
metaLevel: 0,
demandMetaLevel: null,
supplyMetaLevel: null,
taskSupervisor: defaultTaskSupervisor,
onTaskExit: defaultOnTaskExit
}, options);
if (typeof startTask !== 'function') {
throw new Error("Syndicate: DemandMatcher expects 'startTask' function as third argument");
}
this.demandProjectionNames = ensureMatchingProjectionNames(demandSpecs);
this.supplyProjectionNames = ensureMatchingProjectionNames(supplySpecs);
ensureMatchingProjectionNames([demandSpecs[0], supplySpecs[0]]);
this.demandSpecs = demandSpecs;
this.supplySpecs = supplySpecs;
this.demandPatterns = demandSpecs.map(function (s) { return Trie.projectionToPattern(s); });
this.supplyPatterns = supplySpecs.map(function (s) { return Trie.projectionToPattern(s); });
this.demandMetaLevel =
(options.demandMetaLevel === null) ? options.metaLevel : options.demandMetaLevel;
this.supplyMetaLevel =
(options.supplyMetaLevel === null) ? options.metaLevel : options.supplyMetaLevel;
function metaWrap(n) {
return function (s) { return Patch.prependAtMeta(s, n); };
}
this.demandProjections = demandSpecs.map(metaWrap(this.demandMetaLevel));
this.supplyProjections = supplySpecs.map(metaWrap(this.supplyMetaLevel));
this.taskSupervisor = options.taskSupervisor;
this.startTask = startTask;
this.onTaskExit = options.onTaskExit;
this.currentDemand = Immutable.Set();
this.currentSupply = Immutable.Set();
this.supervisionStates = Immutable.Map();
if ('name' in options) {
this.name = options.name;
}
}
function ensureMatchingProjectionNames(specs) {
if (!(specs.length > 0)) {
throw new Error("Syndicate: DemandMatcher needs at least one spec");
}
var names = null;
specs.forEach(function (spec) {
if (names === null) {
names = Trie.projectionNames(spec);
} else {
if (JSON.stringify(names) !== JSON.stringify(Trie.projectionNames(spec))) {
throw new Error("Syndicate: DemandMatcher needs identical capture names");
}
}
});
return names;
}
DemandMatcher.prototype.boot = function () {
var p = Patch.emptyPatch;
function extend(ml) {
return function (pat) { p = p.andThen(Patch.sub(pat, ml)); };
}
this.demandPatterns.forEach(extend(this.demandMetaLevel));
this.supplyPatterns.forEach(extend(this.supplyMetaLevel));
return p;
};
DemandMatcher.prototype.handleEvent = function (e) {
if (e.type === "stateChange") {
this.handlePatch(e.patch);
}
};
DemandMatcher.prototype.handlePatch = function (p) {
var self = this;
var dN = self.demandProjectionNames.length;
var sN = self.supplyProjectionNames.length;
var addedDemand = self.extractKeys(p.added, self.demandProjections, dN, 'demand');
var removedDemand = self.extractKeys(p.removed, self.demandProjections, dN, 'demand');
var addedSupply = self.extractKeys(p.added, self.supplyProjections, sN, 'supply');
var removedSupply = self.extractKeys(p.removed, self.supplyProjections, sN, 'supply');
// Though the added and removed sets of patches are always disjoint,
// *after projection* this may not hold. Cancel out any overlaps.
var demandOverlap = addedDemand.intersect(removedDemand);
var supplyOverlap = addedSupply.intersect(removedSupply);
addedDemand = addedDemand.subtract(demandOverlap);
removedDemand = removedDemand.subtract(demandOverlap);
addedSupply = addedSupply.subtract(supplyOverlap);
removedSupply = removedSupply.subtract(supplyOverlap);
var allTasks = addedDemand.union(addedSupply).union(removedDemand).union(removedSupply);
allTasks.forEach(function (captures) {
function taskFn() {
self.startTask(Trie.captureToObject(captures, self.demandProjectionNames));
}
function onTaskExit() {
self.onTaskExit(Trie.captureToObject(captures, self.demandProjectionNames));
}
var demandState = computeState(self.currentDemand, addedDemand, removedDemand, captures);
var supplyState = computeState(self.currentSupply, addedSupply, removedSupply, captures);
var oldSupervisionState = self.supervisionStates.get(captures, null);
var newSupervisionState = self.taskSupervisor(demandState,
supplyState,
oldSupervisionState,
taskFn,
onTaskExit);
if (newSupervisionState === null) {
self.supervisionStates = self.supervisionStates.remove(captures);
} else {
self.supervisionStates = self.supervisionStates.set(captures, newSupervisionState);
}
});
self.currentSupply = self.currentSupply.union(addedSupply).subtract(removedSupply);
self.currentDemand = self.currentDemand.union(addedDemand).subtract(removedDemand);
};
DemandMatcher.prototype.extractKeys = function (trie, projections, keyCount, whichSide) {
var ks = Immutable.Set();
projections.forEach(function (proj) {
var moreKs = Trie.trieKeys(Trie.project(trie, proj), keyCount);
if (!moreKs) {
throw new Error("Syndicate: wildcard "+whichSide+" detected:\n" +
JSON.stringify(proj) + "\n" +
Trie.prettyTrie(trie));
}
ks = ks.union(moreKs);
});
return ks;
};
function computeState(current, added, removed, captures) {
var isPresent = current.has(captures);
var isChanging = added.has(captures) || removed.has(captures);
return (isPresent ? IS_PRESENT : 0) | (isChanging ? IS_CHANGING : 0);
}
///////////////////////////////////////////////////////////////////////////
module.exports.DemandMatcher = DemandMatcher;
},{"./patch.js":230,"./trie.js":237,"./util.js":239,"immutable":220}],227:[function(require,module,exports){
"use strict";
var Immutable = require('immutable');
var Dataspace = require('./dataspace.js').Dataspace;
function Ground(bootFn) {
var self = this;
this.stepperId = null;
this.stepping = false;
this.startingFuel = 100;
this.baseStack = Immutable.List.of({ dataspace: this, activePid: -1 });
Dataspace.withDataspaceStack(this.baseStack, function () {
self.dataspace = new Dataspace(bootFn);
});
}
Ground.prototype.step = function () {
var self = this;
return Dataspace.withDataspaceStack(this.baseStack, function () {
return self.dataspace.step();
});
};
Ground.prototype.checkPid = function (pid) {
if (pid !== -1) console.error('Weird pid in Ground', pid);
};
Ground.prototype.markRunnable = function (pid) {
this.checkPid(pid);
this.startStepping();
};
Ground.prototype.startStepping = function () {
var self = this;
if (this.stepperId) return;
if (this.stepping) return;
this.stepping = true;
try {
var stillBusy = false;
for (var fuel = this.startingFuel; fuel > 0; fuel--) {
stillBusy = this.step();
if (!stillBusy) break;
}
if (stillBusy) {
this.stepperId = setTimeout(function () {
self.stepperId = null;
self.startStepping();
}, 0);
}
} catch (e) {
this.stepping = false;
throw e;
}
this.stepping = false;
return this; // because the syndicatec compiler chains startStepping after the ctor
};
Ground.prototype.stopStepping = function () {
if (this.stepperId) {
clearTimeout(this.stepperId);
this.stepperId = null;
}
};
Ground.prototype.kill = function (pid, exn) {
this.checkPid(pid);
console.log("Ground dataspace terminated");
this.stopStepping();
};
Ground.prototype.enqueueAction = function (pid, action) {
this.checkPid(pid);
switch (action.type) {
case 'stateChange':
if (action.patch.isNonEmpty()) {
console.error('You have subscribed to a nonexistent event source.',
action.patch.pretty());
}
break;
case 'message':
console.error('You have sent a message into the outer void.', action);
break;
default:
console.error('Internal error: unexpected action at ground level', action);
break;
}
};
///////////////////////////////////////////////////////////////////////////
module.exports.Ground = Ground;
},{"./dataspace.js":225,"immutable":220}],228:[function(require,module,exports){
"use strict";
function copyKeys(keys, to, from) {
for (var i = 0; i < keys.length; i++) {
to[keys[i]] = from[keys[i]];
}
}
module.exports = require("./dataspace.js");
module.exports.Trie = require("./trie.js");
copyKeys(['__', '_$', '$Capture', '$Special',
'is_emptyTrie', 'emptyTrie',
'embeddedTrie', 'compilePattern',
'project', 'projectObjects',
'prettyTrie'],
module.exports,
module.exports.Trie);
module.exports.Struct = require('./struct.js');
var Seal = require('./seal.js')
copyKeys(['Seal', 'seal'],
module.exports,
Seal);
module.exports.DemandMatcher = require('./demand-matcher.js').DemandMatcher;
module.exports.Ack = require('./ack.js').Ack;
module.exports.RandomID = require('./randomid.js');
module.exports.UI = require('./ui.js');
module.exports.Timer = require("./timer-driver.js");
module.exports.Reflect = require("./reflect.js");
module.exports.WakeDetector = require("./wake-detector-driver.js");
module.exports.Codec = require("./codec.js");
module.exports.Broker = require("./broker.js");
module.exports.Patch = require("./patch.js");
copyKeys(['emptyPatch',
'observe', 'atMeta', 'advertise',
'assert', 'retract', 'sub', 'unsub', 'pub', 'unpub',
'patchSeq'],
module.exports,
module.exports.Patch);
module.exports.Ground = require("./ground.js").Ground;
module.exports.Actor = require("./actor.js");
// module.exports.Spy = require("./spy.js").Spy;
// module.exports.WakeDetector = require("./wake-detector.js").WakeDetector;
// var Worker = require("./worker.js");
// module.exports.Worker = Worker.Worker;
// module.exports.WorkerGround = Worker.WorkerGround;
},{"./ack.js":221,"./actor.js":222,"./broker.js":223,"./codec.js":224,"./dataspace.js":225,"./demand-matcher.js":226,"./ground.js":227,"./patch.js":230,"./randomid.js":231,"./reflect.js":232,"./seal.js":233,"./struct.js":235,"./timer-driver.js":236,"./trie.js":237,"./ui.js":238,"./wake-detector-driver.js":240}],229:[function(require,module,exports){
"use strict";
var Immutable = require('immutable');
var Trie = require('./trie.js');
var Patch = require('./patch.js');
function Mux(nextPid, routingTable, interestTable) {
this.nextPid = nextPid || 0;
this.routingTable = routingTable || Trie.emptyTrie;
this.interestTable = interestTable || Immutable.Map(); // pid -> Trie
}
Mux.prototype.shallowCopy = function () {
return new Mux(this.nextPid, this.routingTable, this.interestTable);
};
Mux.prototype.addStream = function (initialPatch) {
var newPid = this.nextPid++;
return this.updateStream(newPid, initialPatch);
};
Mux.prototype.removeStream = function (pid) {
return this.updateStream(pid, Patch.removeEverythingPatch);
};
Mux.prototype.updateStream = function (pid, unclampedPatch) {
var oldInterests = this.interestsOf(pid);
var oldRoutingTable = this.routingTable;
var delta = unclampedPatch.label(Immutable.Set.of(pid)).limit(oldInterests);
var deltaAggregate = delta.computeAggregate(pid, oldRoutingTable);
var newInterests = delta.applyTo(oldInterests);
var newRoutingTable = delta.applyTo(oldRoutingTable);
this.routingTable = newRoutingTable;
if (Trie.is_emptyTrie(newInterests)) {
this.interestTable = this.interestTable.remove(pid);
} else {
this.interestTable = this.interestTable.set(pid, newInterests);
}
return { pid: pid,
delta: delta,
deltaAggregate: deltaAggregate };
};
var atMetaEverything = Trie.compilePattern(true, Patch.atMeta(Trie.__));
var atMetaBranchKeys = Immutable.List([[Patch.atMeta.meta.arity, Patch.atMeta.meta]]);
var onlyMeta = Trie.trieSuccess(Immutable.Set.of("meta"));
function echoCancelledTrie(t) {
return Trie.subtract(t, atMetaEverything, function (v1, v2) {
return v1.has("meta") ? onlyMeta : Trie.emptyTrie;
});
}
function computeEvents(oldMux, newMux, updateStreamResult) {
var actingPid = updateStreamResult.pid;
var delta = updateStreamResult.delta;
var deltaAggregate = updateStreamResult.deltaAggregate;
var deltaAggregateNoEcho = (actingPid === "meta")
? delta // because echo-cancellation means that meta-SCNs are always new information
: deltaAggregate.withoutAtMeta();
var oldRoutingTable = oldMux.routingTable;
var newRoutingTable = newMux.routingTable;
var affectedPids =
computeAffectedPids(oldRoutingTable, deltaAggregateNoEcho).add(actingPid).remove("meta");
return {
eventMap: Immutable.Map().withMutations(function (result) {
affectedPids.forEach(function (pid) {
var patchForPid;
if (pid === actingPid) {
var part1 = new Patch.Patch(
echoCancelledTrie(Patch.biasedIntersection(newRoutingTable, delta.added)),
echoCancelledTrie(Patch.biasedIntersection(oldRoutingTable, delta.removed)));
var part2 = new Patch.Patch(Patch.biasedIntersection(deltaAggregateNoEcho.added,
newMux.interestsOf(pid)),
Patch.biasedIntersection(deltaAggregateNoEcho.removed,
oldMux.interestsOf(pid)));
patchForPid = part1.unsafeUnion(part2);
} else {
patchForPid = deltaAggregateNoEcho.viewFrom(oldMux.interestsOf(pid));
}
if (patchForPid.isNonEmpty()) {
result.set(pid, patchForPid);
}
});
}),
metaEvents: (actingPid === "meta")
? Immutable.List()
: Immutable.List.of(delta.computeAggregate(actingPid, oldRoutingTable, true).drop())
};
}
function computeAffectedPids(routingTable, delta) {
var cover = Trie._union(delta.added, delta.removed);
routingTable = Trie.trieStep(routingTable, Patch.observe.meta.arity, Patch.observe.meta);
return Trie.matchTrie(cover, routingTable, Immutable.Set(),
function (v1, v2, acc) { return acc.union(v2); });
}
Mux.prototype.routeMessage = function (body) {
if (Trie.matchValue(this.routingTable, body, null, function(a, b) { return a||b }) === null) {
return Trie.matchValue(this.routingTable, Patch.observe(body), Immutable.Set(),
function (a, b) { return a.union(b) });
} else {
// Some other stream has declared body
return Immutable.Set();
}
};
Mux.prototype.interestsOf = function (pid) {
return this.interestTable.get(pid, Trie.emptyTrie);
};
///////////////////////////////////////////////////////////////////////////
module.exports.Mux = Mux;
module.exports.computeEvents = computeEvents;
module.exports.computeAffectedPids = computeAffectedPids;
},{"./patch.js":230,"./trie.js":237,"immutable":220}],230:[function(require,module,exports){
"use strict";
var Trie = require("./trie.js");
var Struct = require("./struct.js");
var Immutable = require("immutable");
var __ = Trie.__;
var _$ = Trie._$;
function Patch(added, removed) {
this.added = added;
this.removed = removed;
}
var emptyPatch = new Patch(Trie.emptyTrie, Trie.emptyTrie);
var removeEverythingPatch = new Patch(Trie.emptyTrie, Trie.compilePattern(true, __));
var trueLabel = Trie.trieSuccess(true);
var observe = Struct.makeConstructor('observe', ['assertion']);
var atMeta = Struct.makeConstructor('at-meta', ['assertion']);
var advertise = Struct.makeConstructor('advertise', ['assertion']);
function prependAtMeta(p, level) {
while (level--) {
p = atMeta(p);
}
return p;
}
function stripAtMeta(p, level) {
while (level--) {
if (atMeta.isClassOf(p)) {
p = p[0];
} else {
return null;
}
}
return p;
}
function observeAtMeta(p, level) {
if (level === 0) {
return Trie.compilePattern(true, observe(p));
} else {
return Trie._union(
Trie.compilePattern(true, observe(prependAtMeta(p, level))),
Trie.compilePattern(true, atMeta(Trie.embeddedTrie(observeAtMeta(p, level - 1)))));
}
}
function _check(p) {
if (p instanceof Patch) {
throw new Error("Cannot construct patch pattern using an embedded patch");
}
return p;
}
function assert(p, metaLevel) {
return new Patch(Trie.compilePattern(true, prependAtMeta(_check(p), metaLevel || 0)),
Trie.emptyTrie);
}
function retract(p, metaLevel) {
return new Patch(Trie.emptyTrie,
Trie.compilePattern(true, prependAtMeta(_check(p), metaLevel || 0)));
}
function sub(p, metaLevel) {
return new Patch(observeAtMeta(_check(p), metaLevel || 0), Trie.emptyTrie);
}
function unsub(p, metaLevel) {
return new Patch(Trie.emptyTrie, observeAtMeta(_check(p), metaLevel || 0));
}
function pub(p, metaLevel) {
return assert(advertise(_check(p)), metaLevel);
}
function unpub(p, metaLevel) {
return retract(advertise(_check(p)), metaLevel);
}
///////////////////////////////////////////////////////////////////////////
Patch.prototype.equals = function (other) {
if (!(other instanceof Patch)) return false;
return Immutable.is(this.added, other.added) && Immutable.is(this.removed, other.removed);
};
Patch.prototype.isEmpty = function () {
return this.added === Trie.emptyTrie && this.removed === Trie.emptyTrie;
};
Patch.prototype.isNonEmpty = function () {
return !this.isEmpty();
};
Patch.prototype.hasAdded = function () {
return !Trie.is_emptyTrie(this.added);
};
Patch.prototype.hasRemoved = function () {
return !Trie.is_emptyTrie(this.removed);
};
Patch.prototype.lift = function () {
return new Patch(Trie.compilePattern(true, atMeta(Trie.embeddedTrie(this.added))),
Trie.compilePattern(true, atMeta(Trie.embeddedTrie(this.removed))));
};
var atMetaProj = atMeta(_$);
Patch.prototype.drop = function () {
return new Patch(Trie.project(this.added, atMetaProj),
Trie.project(this.removed, atMetaProj));
};
Patch.prototype.strip = function () {
return new Patch(Trie.relabel(this.added, function (v) { return true; }),
Trie.relabel(this.removed, function (v) { return true; }));
};
Patch.prototype.label = function (labelValue) {
return new Patch(Trie.relabel(this.added, function (v) { return labelValue; }),
Trie.relabel(this.removed, function (v) { return labelValue; }));
};
Patch.prototype.limit = function (bound) {
return new Patch(Trie.subtract(this.added, bound, function (v1, v2) { return Trie.emptyTrie; }),
Trie.intersect(this.removed, bound,
function (v1, v2) { return Trie.trieSuccess(v1); }));
};
var metaLabelSet = Immutable.Set(["meta"]);
Patch.prototype.computeAggregate = function (label, base, removeMeta /* optional flag */) {
return new Patch(Trie.subtract(this.added, base, addCombiner),
Trie.subtract(this.removed, base, removeCombiner));
function addCombiner(v1, v2) {
if (removeMeta && Immutable.is(v2, metaLabelSet)) {
return Trie.trieSuccess(v1);
} else {
return Trie.emptyTrie;
}
}
function removeCombiner(v1, v2) {
if (v2.size === 1) {
return Trie.trieSuccess(v1);
} else {
if (removeMeta && v2.size === 2 && v2.has("meta")) {
return Trie.trieSuccess(v1);
} else {
return Trie.emptyTrie;
}
}
}
};
Patch.prototype.applyTo = function (base) {
return Trie._union(Trie.subtract(base, this.removed), this.added);
};
Patch.prototype.updateInterests = function (base) {
return Trie._union(Trie.subtract(base,
this.removed,
function (v1, v2) { return Trie.emptyTrie; }),
this.added,
function (v1, v2) { return trueLabel; });
};
Patch.prototype.unapplyTo = function (base) {
return Trie._union(Trie.subtract(base, this.added), this.removed);
};
Patch.prototype.andThen = function (nextPatch) {
return new Patch(nextPatch.updateInterests(this.added),
Trie._union(Trie.subtract(this.removed,
nextPatch.added,
function (v1, v2) { return Trie.emptyTrie; }),
nextPatch.removed,
function (v1, v2) { return trueLabel; }));
};
function patchSeq(/* patch, patch, ... */) {
var p = emptyPatch;
for (var i = 0; i < arguments.length; i++) {
p = p.andThen(arguments[i]);
}
return p;
}
function computePatch(oldBase, newBase) {
return new Patch(Trie.subtract(newBase, oldBase),
Trie.subtract(oldBase, newBase));
}
function biasedIntersection(object, subject) {
subject = Trie.trieStep(subject, observe.meta.arity, observe.meta);
return Trie.intersect(object, subject, function (v1, v2) { return Trie.trieSuccess(v1); });
}
Patch.prototype.viewFrom = function (interests) {
return new Patch(biasedIntersection(this.added, interests),
biasedIntersection(this.removed, interests));
};
Patch.prototype.unsafeUnion = function (other) {
// Unsafe because does not necessarily preserve invariant that added
// and removed are disjoint.
return new Patch(Trie._union(this.added, other.added),
Trie._union(this.removed, other.removed));
};
Patch.prototype.project = function (compiledProjection) {
return new Patch(Trie.project(this.added, compiledProjection),
Trie.project(this.removed, compiledProjection));
};
Patch.prototype.projectObjects = function (compiledProjection) {
return [Trie.projectObjects(this.added, compiledProjection),
Trie.projectObjects(this.removed, compiledProjection)];
};
Patch.prototype.pretty = function () {
return ("<<<<<<<< Removed:\n" + Trie.prettyTrie(this.removed) + "\n" +
"======== Added:\n" + Trie.prettyTrie(this.added) + "\n" +
">>>>>>>>");
};
// Completely ignores success-values in t.
Patch.prototype.prunedBy = function (t) {
return new Patch(Trie.subtract(this.added, t, function (v1, v2) { return Trie.emptyTrie; }),
Trie.subtract(this.removed, t, function (v1, v2) { return Trie.emptyTrie; }));
};
var atMetaEverything = Trie.compilePattern(true, atMeta.pattern);
Patch.prototype.withoutAtMeta = function () {
return this.prunedBy(atMetaEverything);
};
///////////////////////////////////////////////////////////////////////////
Patch.prototype.toJSON = function () {
return [Trie.trieToJSON(this.added), Trie.trieToJSON(this.removed)];
};
function fromJSON(j) {
return new Patch(Trie.trieFromJSON(j[0]), Trie.trieFromJSON(j[1]));
}
///////////////////////////////////////////////////////////////////////////
module.exports.Patch = Patch;
module.exports.emptyPatch = emptyPatch;
module.exports.removeEverythingPatch = removeEverythingPatch;
module.exports.observe = observe;
module.exports.atMeta = atMeta;
module.exports.advertise = advertise;
module.exports.prependAtMeta = prependAtMeta;
module.exports.stripAtMeta = stripAtMeta;
module.exports.observeAtMeta = observeAtMeta;
module.exports.assert = assert;
module.exports.retract = retract;
module.exports.sub = sub;
module.exports.unsub = unsub;
module.exports.pub = pub;
module.exports.unpub = unpub;
module.exports.patchSeq = patchSeq;
module.exports.computePatch = computePatch;
module.exports.biasedIntersection = biasedIntersection;
module.exports.fromJSON = fromJSON;
},{"./struct.js":235,"./trie.js":237,"immutable":220}],231:[function(require,module,exports){
var randomId;
if ((typeof window !== 'undefined') &&
(typeof window.crypto !== 'undefined') &&
(typeof window.crypto.getRandomValues !== 'undefined')) {
randomId = function (byteCount, hexOutput) {
var buf = new Uint8Array(byteCount);
window.crypto.getRandomValues(buf);
if (hexOutput) {
var encoded = [];
for (var i = 0; i < buf.length; i++) {
encoded.push("0123456789abcdef"[(buf[i] >> 4) & 15]);
encoded.push("0123456789abcdef"[buf[i] & 15]);
}
return encoded.join('');
} else {
return btoa(String.fromCharCode.apply(null, buf)).replace(/=/g,'');
}
};
} else {
var crypto;
try {
crypto = require('crypto');
} catch (e) {}
if ((typeof crypto !== 'undefined') &&
(typeof crypto.randomBytes !== 'undefined')) {
randomId = function (byteCount, hexOutput) {
if (hexOutput) {
return crypto.randomBytes(byteCount).hexSlice().replace(/=/g,'');
} else {
return crypto.randomBytes(byteCount).base64Slice().replace(/=/g,'');
}
};
} else {
console.warn('No suitable implementation for RandomID.randomId available.');
}
}
module.exports.randomId = randomId;
},{"crypto":6}],232:[function(require,module,exports){
"use strict";
// Reflection on function formal parameter lists.
// This module is based on Angular's "injector" code,
// https://github.com/angular/angular.js/blob/master/src/auto/injector.js,
// MIT licensed, and hence:
// Copyright (c) 2010-2014 Google, Inc. http://angularjs.org
// Copyright (c) 2014 Tony Garnock-Jones
var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
function formalParameters(fn) {
var result = [];
var fnText = fn.toString().replace(STRIP_COMMENTS, '');
var argDecl = fnText.match(FN_ARGS);
var args = argDecl[1].split(FN_ARG_SPLIT);
for (var i = 0; i < args.length; i++) {
var trimmed = args[i].trim();
if (trimmed) { result.push(trimmed); }
}
return result;
}
module.exports.formalParameters = formalParameters;
},{}],233:[function(require,module,exports){
var Immutable = require('immutable');
function Seal(contents) {
this.sealContents = contents;
Object.freeze(this);
}
Seal.prototype.equals = function (other) {
if (!(other instanceof Seal)) return false;
return Immutable.is(this.sealContents, other.sealContents);
};
function seal(contents) {
return new Seal(contents);
}
module.exports.Seal = Seal;
module.exports.seal = seal;
},{"immutable":220}],234:[function(require,module,exports){
"use strict";
// $Special: Builder of singleton "atoms".
function $Special(name) {
this.name = name;
}
module.exports = $Special;
},{}],235:[function(require,module,exports){
"use strict";
// "Structures": Simple named-tuple-like records.
var Immutable = require("immutable");
var $Special = require('./special.js');
/* Defined here rather than in trie.js because we need it in makeConstructor. */
var __ = new $Special("wildcard"); /* wildcard marker */
function StructureType(label, arity) {
this.label = label;
this.arity = arity;
this.pattern = this.instantiate(Immutable.Repeat(__, arity).toArray());
var self = this;
this.ctor = function () {
return self.instantiate(Array.prototype.slice.call(arguments));
};
this.ctor.meta = this;
this.ctor.pattern = this.pattern;
this.ctor.isClassOf = function (v) { return self.isClassOf(v); };
}
function makeConstructor(label, fieldNames) {
return new StructureType(label, fieldNames.length).ctor;
}
StructureType.prototype.equals = function (other) {
if (!(other instanceof StructureType)) return false;
return this.arity === other.arity && this.label === other.label;
};
StructureType.prototype.instantiate = function (fields) {
return new Structure(this, fields);
};
StructureType.prototype.isClassOf = function (v) {
return v && (v instanceof Structure) && (v.meta.equals(this));
};
function Structure(meta, fields) {
if (!isStructureType(meta)) {
throw new Error("Structure: requires structure type");
}
if (fields.length !== meta.arity) {
throw new Error("Structure: cannot instantiate meta "+JSON.stringify(meta.label)+
" expecting "+meta.arity+" fields with "+fields.length+" fields");
}
this.meta = meta;
this.length = meta.arity;
this.fields = fields.slice(0);
for (var i = 0; i < fields.length; i++) {
this[i] = fields[i];
}
}
function reviveStructs(j) {
if (Array.isArray(j)) {
return j.map(reviveStructs);
}
if ((j !== null) && typeof j === 'object') {
if ((typeof j['@type'] === 'string') && Array.isArray(j['fields'])) {
return (new StructureType(j['@type'], j['fields'].length)).instantiate(j['fields']);
} else {
for (var k in j) {
if (Object.prototype.hasOwnProperty.call(j, k)) {
j[k] = reviveStructs(j[k]);
}
}
return j;
}
}
return j;
}
function reviver(k, v) {
if (k === '') {
return reviveStructs(v);
}
return v;
};
Structure.prototype.toJSON = function () {
return { '@type': this.meta.label, 'fields': this.fields };
};
function isStructureType(v) {
return v && (v instanceof StructureType);
}
function isStructure(v) {
return v && (v instanceof Structure);
}
///////////////////////////////////////////////////////////////////////////
module.exports.__ = __;
module.exports.StructureType = StructureType;
module.exports.makeConstructor = makeConstructor;
module.exports.Structure = Structure;
module.exports.reviveStructs = reviveStructs;
module.exports.reviver = reviver;
module.exports.isStructureType = isStructureType;
module.exports.isStructure = isStructure;
},{"./special.js":234,"immutable":220}],236:[function(require,module,exports){
// Timer event driver
var Patch = require("./patch.js");
var DemandMatcher = require('./demand-matcher.js').DemandMatcher;
var Struct = require('./struct.js');
var Dataspace_ = require("./dataspace.js");
var Dataspace = Dataspace_.Dataspace;
var __ = Dataspace_.__;
var _$ = Dataspace_._$;
var periodicTick = Struct.makeConstructor('periodicTick', ['intervalMS']); // message
var timeLaterThan = Struct.makeConstructor('timeLaterThan', ['deadlineMS']); // assertion
function spawnTimerDriver() {
Dataspace.spawn(
new DemandMatcher([Patch.observe(periodicTick(_$('intervalMS')))],
[Patch.advertise(periodicTick(_$('intervalMS')))],
function (c) {
Dataspace.spawn(new Tick(c.intervalMS));
}));
Dataspace.spawn(
new DemandMatcher([Patch.observe(timeLaterThan(_$('deadlineMS')))],
[Patch.advertise(timeLaterThan(_$('deadlineMS')))],
function (c) {
Dataspace.spawn(new Alarm(c.deadlineMS));
}));
}
function Tick(intervalMS) {
this.intervalMS = intervalMS;
this.handle = null;
}
Tick.prototype.boot = function () {
var self = this;
this.handle = setInterval(Dataspace.wrap(function () {
Dataspace.send(periodicTick(self.intervalMS));
}), this.intervalMS);
return Patch.sub(Patch.observe(periodicTick(this.intervalMS))) // monitor interest
.andThen(Patch.pub(periodicTick(this.intervalMS))) // signal we exist to DemandMatcher
;
};
Tick.prototype.trapexit = function () {
this.cancelTimer();
};
Tick.prototype.cancelTimer = function () {
if (this.handle !== null) {
clearInterval(this.handle);
this.handle = null;
}
};
Tick.prototype.handleEvent = function (e) {
if (e.type === 'stateChange' && e.patch.hasRemoved()) {
Dataspace.exit();
}
};
function Alarm(deadlineMS) {
this.deadlineMS = deadlineMS;
this.handle = null;
}
Alarm.prototype.boot = function () {
this.checkTimeout();
return Patch.sub(Patch.observe(timeLaterThan(this.deadlineMS))) // monitor interest
.andThen(Patch.pub(timeLaterThan(this.deadlineMS))) // signal we exist to DemandMatcher
;
};
Alarm.prototype.checkTimeout = function () {
var now = +(new Date());
var delta = this.deadlineMS - now;
if (delta <= 0) {
Dataspace.stateChange(Patch.assert(timeLaterThan(this.deadlineMS)));
this.cancelTimer();
} else if (this.handle === null) {
var self = this;
this.handle = setTimeout(Dataspace.wrap(function () { self.checkTimeout(); }), delta);
}
};
Alarm.prototype.cancelTimer = function () {
if (this.handle !== null) {
clearTimeout(this.handle);
this.handle = null;
}
};
Alarm.prototype.trapexit = function () {
this.cancelTimer();
};
Alarm.prototype.handleEvent = function (e) {
if (e.type === 'stateChange' && e.patch.hasRemoved()) {
Dataspace.exit();
}
};
///////////////////////////////////////////////////////////////////////////
module.exports.spawnTimerDriver = spawnTimerDriver;
module.exports.periodicTick = periodicTick;
module.exports.timeLaterThan = timeLaterThan;
module.exports.Tick = Tick;
module.exports.Alarm = Alarm;
},{"./dataspace.js":225,"./demand-matcher.js":226,"./patch.js":230,"./struct.js":235}],237:[function(require,module,exports){
"use strict";
var Immutable = require("immutable");
var Struct = require('./struct.js');
var $Special = require('./special.js');
function die(message) {
throw new Error(message);
}
///////////////////////////////////////////////////////////////////////////
// Trie representations
//
// A Trie is one of
// - emptyTrie
// - an instance of $Success
// - an instance of $Branch
var emptyTrie = new $Special("Mt");
function is_emptyTrie(m) {
return m === emptyTrie;
}
function $Success(value) {
this.value = value;
}
$Success.prototype.equals = function (other) {
if (!(other instanceof $Success)) return false;
return Immutable.is(this.value, other.value);
};
function $Branch(wild, edges, count) {
this.wild = wild || emptyTrie; // Trie
this.edges = edges || Immutable.Map(); // Map from arity to Map from key-like-thing to Trie
// (Sigmas are 0-ary.)
this.count = count || 0;
}
$Branch.prototype.equals = function (other) {
if (!(other instanceof $Branch)) return false;
return (this.count === other.count) && Immutable.is(this.wild, other.wild) && Immutable.is(this.edges, other.edges);
};
///////////////////////////////////////////////////////////////////////////
// Patterns, projections and captures
var __ = Struct.__; /* imported rather than defined here because of cyclic dep in Struct */
var SOA = new $Special("array"); /* key for start-of-array */
function $Embedded(trie, arrayLength) {
this.trie = trie;
this.arrayLength = arrayLength;
}
function embeddedTrie(trie) {
return new $Embedded(trie, null);
}
function embeddedTrieArray(trie, arrayLength) {
return new $Embedded(trie, arrayLength);
}
// The name argument should be a string or null; it defaults to null.
// The pattern argument defaults to wildcard, __.
function $Capture(name, pattern) {
this.name = name || null;
this.pattern = (typeof pattern === 'undefined' ? __ : pattern);
}
// Abbreviation: _$(...) <==> new $Capture(...)
function _$(name, pattern) {
return new $Capture(name, pattern);
}
function isCapture(x) { return x instanceof $Capture || x === _$; }
function captureName(x) { return x instanceof $Capture ? x.name : null; }
function capturePattern(x) { return x instanceof $Capture ? x.pattern : __; }
///////////////////////////////////////////////////////////////////////////
// Constructors
function rsuccess(v) {
return new $Success(v);
}
function rseq(arity, key, r) {
if (is_emptyTrie(r)) return emptyTrie;
return new $Branch(emptyTrie, Immutable.Map.of(arity, Immutable.Map.of(key, r)), 1);
}
function rwild(r) {
if (is_emptyTrie(r)) return emptyTrie;
return new $Branch(r, Immutable.Map(), 0);
}
function rcopybranch(r) {
return new $Branch(r.wild, r.edges, r.count);
}
function prepend_wilds(n, r) {
while (n-- > 0) { r = rwild(r); }
return r;
}
// true iff r1 could have been the output of prepend_wilds(n, r2).
function equal_upto_wilds(n, r1, r2) {
while (true) {
if (n === 0 || is_emptyTrie(r1)) {
return Immutable.is(r1, r2);
}
if (!(r1 instanceof $Branch) || r1.count > 0) {
return false;
}
n = n - 1;
r1 = r1.wild;
}
}
function rupdate_inplace(r, arity, key, k) {
if (equal_upto_wilds(arity, k, r.wild)) {
var m = r.edges.get(arity);
if (!m) return;
if (m.has(key)) r.count--;
m = m.remove(key);
r.edges = m.isEmpty() ? r.edges.remove(arity) : r.edges.set(arity, m);
} else {
var m = r.edges.get(arity) || Immutable.Map();
if (!m.has(key)) r.count++;
r.edges = r.edges.set(arity, m.set(key, k));
}
}
function rlookup(r, arity, key) {
var m = r.edges.get(arity);
m = m && m.get(key);
return m || prepend_wilds(arity, r.wild);
}
///////////////////////////////////////////////////////////////////////////
function collapse(r) {
if ((r instanceof $Branch) && is_emptyTrie(r.wild) && (r.count === 0)) {
return emptyTrie;
} else {
return r;
}
}
// use with extreme care
function newEmptyBranch() {
return new $Branch(emptyTrie, Immutable.Map(), 0);
}
var canonicalExpandedEmpty = newEmptyBranch();
function expand(r) {
if (is_emptyTrie(r)) {
return canonicalExpandedEmpty;
} else {
return r;
}
}
///////////////////////////////////////////////////////////////////////////
function compilePattern(v, p) {
if (!p) die("compilePattern: missing pattern");
return walk(p, rsuccess(v));
function walk(p, acc) {
if (p === __) return rwild(acc);
if (Array.isArray(p)) {
for (var i = p.length - 1; i >= 0; i--) {
acc = walk(p[i], acc);
}
return rseq(p.length, SOA, acc);
}
if (Immutable.List.isList(p)) {
p.reverse().forEach(function (element) {
acc = walk(element, acc);
});
return rseq(p.size, SOA, acc);
}
if (Struct.isStructure(p)) {
for (var i = p.meta.arity - 1; i >= 0; i--) {
acc = walk(p[i], acc);
}
return rseq(p.meta.arity, p.meta, acc);
}
if (p instanceof $Embedded) {
acc = appendTrie(p.trie, function (v) { return acc; });
if (p.arrayLength !== null) {
acc = rseq(p.arrayLength, SOA, acc);
}
return acc;
} else {
return rseq(0, p, acc);
}
}
}
function matchPattern(v, p) {
var captureCount = 0;
var result = {};
try {
walk(v, p);
} catch (e) {
if (e.matchPatternFailed) return null;
throw e;
}
result.length = captureCount;
return result;
function walk(v, p) {
if (p === v) return;
if (p === __) return;
if (Struct.isStructure(p) && Struct.isStructure(v) && (p.meta.equals(v.meta)))
{
for (var i = 0; i < p.meta.arity; i++) {
walk(v[i], p[i]);
}
return;
}
if (Array.isArray(p) && Array.isArray(v) && p.length === v.length) {
for (var i = 0; i < p.length; i++) {
walk(v[i], p[i]);
}
return;
}
if (isCapture(p)) {
var thisCapture = captureCount++;
walk(v, capturePattern(p));
result[captureName(p) || ('$' + thisCapture)] = v;
return;
}
if (p instanceof $Embedded) {
die("$Embedded patterns not supported in matchPattern()");
}
throw {matchPatternFailed: true};
}
}
///////////////////////////////////////////////////////////////////////////
function combine(combineSuccess, leftEmpty, rightEmpty, leftBase, rightBase, r1, r2) {
return walk(r1, r2);
function walk(r1, r2) {
if (is_emptyTrie(r1)) return collapse(leftEmpty(r2));
if (is_emptyTrie(r2)) return collapse(rightEmpty(r1));
if ((r1 instanceof $Success) || (r2 instanceof $Success)) {
return collapse(combineSuccess(r1, r2));
}
if (!(r1 instanceof $Branch) || !(r2 instanceof $Branch)) {
die("Invalid trie given to combine");
}
/* fold-over-keys */
var w = walk(r1.wild, r2.wild);
var acc;
if (!is_emptyTrie(r1.wild) && !is_emptyTrie(r2.wild)) {
acc = rcopybranch(expand(rwild(w)));
var seen = Immutable.Map();
r1.edges.forEach(function (keymap, arity) {
keymap.forEach(function (r1v, key) {
var r2v = rlookup(r2, arity, key);
rupdate_inplace(acc, arity, key, walk(r1v, r2v));
seen = seen.set(arity, (seen.get(arity) || Immutable.Set()).add(key));
});
});
r2.edges.forEach(function (keymap, arity) {
keymap.forEach(function (r2v, key) {
var r1v = rlookup(r1, arity, key);
var s = seen.get(arity);
s = s && s.has(key);
if (!s) rupdate_inplace(acc, arity, key, walk(r1v, r2v));
});
});
} else if (!is_emptyTrie(r1.wild) || (is_emptyTrie(r2.wild) && (r1.count > r2.count))) {
acc = rcopybranch(expand(leftBase(r1)));
acc.wild = w;
r2.edges.forEach(function (keymap, arity) {
keymap.forEach(function (r2v, key) {
var r1v = rlookup(r1, arity, key);
rupdate_inplace(acc, arity, key, walk(r1v, r2v));
});
});
} else {
acc = rcopybranch(expand(rightBase(r2)));
acc.wild = w;
r1.edges.forEach(function (keymap, arity) {
keymap.forEach(function (r1v, key) {
var r2v = rlookup(r2, arity, key);
rupdate_inplace(acc, arity, key, walk(r1v, r2v));
});
});
}
return collapse(acc);
}
}
function asymmetricTrieError(r1, r2) {
die("Asymmetric tries: " + r1 + ", " + r2);
}
///////////////////////////////////////////////////////////////////////////
var unionSuccessesDefault = function (v1, v2) {
return rsuccess(v1.union(v2));
};
function union(o1, o2, unionSuccessesOpt) {
var unionSuccesses = unionSuccessesOpt || unionSuccessesDefault;
return combine(unionCombiner,
function (x) { return x; },
function (x) { return x; },
function (x) { return x; },
function (x) { return x; },
o1,
o2);
function unionCombiner(r1, r2) {
if ((r1 instanceof $Success) && (r2 instanceof $Success))
return unionSuccesses(r1.value, r2.value);
if (is_emptyTrie(r1)) return r2;
if (is_emptyTrie(r2)) return r1;
asymmetricTrieError(r1, r2);
}
}
function unionN() {
var acc = emptyTrie;
for (var i = 0; i < arguments.length; i++) {
acc = union(acc, arguments[i]);
}
return acc;
}
///////////////////////////////////////////////////////////////////////////
var intersectSuccessesDefault = unionSuccessesDefault;
function intersect(o1, o2, intersectSuccessesOpt) {
var intersectSuccesses = intersectSuccessesOpt || intersectSuccessesDefault;
return combine(intersectCombiner,
function (x) { return emptyTrie; },
function (x) { return emptyTrie; },
function (x) { return emptyTrie; },
function (x) { return emptyTrie; },
o1,
o2);
function intersectCombiner(r1, r2) {
if ((r1 instanceof $Success) && (r2 instanceof $Success))
return intersectSuccesses(r1.value, r2.value);
if (is_emptyTrie(r1)) return emptyTrie;
if (is_emptyTrie(r2)) return emptyTrie;
asymmetricTrieError(r1, r2);
}
}
///////////////////////////////////////////////////////////////////////////
var subtractSuccessesDefault = function (v1, v2) {
var r = v1.subtract(v2);
if (r.isEmpty()) return emptyTrie;
return rsuccess(r);
};
function subtract(o1, o2, subtractSuccessesOpt) {
var subtractSuccesses = subtractSuccessesOpt || subtractSuccessesDefault;
return combine(subtractCombiner,
function (x) { return emptyTrie; },
function (x) { return x; },
function (x) { return x; },
function (x) { return emptyTrie; },
o1,
o2);
function subtractCombiner(r1, r2) {
if ((r1 instanceof $Success) && (r2 instanceof $Success))
return subtractSuccesses(r1.value, r2.value);
if (is_emptyTrie(r1)) return emptyTrie;
if (is_emptyTrie(r2)) return r1;
asymmetricTrieError(r1, r2);
}
}
///////////////////////////////////////////////////////////////////////////
// Returns failureResult on failed match, otherwise the appropriate
// success value contained in the trie r. If wildcardUnionOpt
// non-falsy, allows wildcards in "messages" v.
function matchValue(r, v, failureResult, wildcardUnionOpt) {
return walk(Immutable.List.of(v), r);
function walk(vs, r) {
while (!is_emptyTrie(r)) {
if (r instanceof $Success) {
return vs.isEmpty() ? r.value : failureResult;
}
if (vs.isEmpty()) return failureResult;
var v = vs.first();
vs = vs.rest();
if (v === __) {
if (!wildcardUnionOpt) {
die("Cannot match wildcard in value unless wildcardUnionOpt non-falsy");
}
var seed = walk(vs, r.wild);
r.edges.forEach(function (keymap, arity) {
keymap.forEach(function (k, key) {
seed = wildcardUnionOpt(walk(Immutable.Repeat(__, arity).concat(vs), k), seed);
});
});
return seed;
}
if (typeof v === 'string' && v.substring(0, 2) === '__') {
die("Cannot match special string starting with __");
}
if (Array.isArray(v)) {
r = rlookup(r, v.length, SOA);
vs = Immutable.List(v).concat(vs);
} else if (Struct.isStructure(v)) {
r = rlookup(r, v.meta.arity, v.meta);
vs = Immutable.List(v.fields).concat(vs);
} else {
r = rlookup(r, 0, v);
}
}
return failureResult;
}
}
function matchTrie(o1, o2, seed, combiner) {
var acc = typeof seed === 'undefined' ? Immutable.Set() : seed; // variable updated imperatively
walk(o1, o2);
return acc;
function walk(r1, r2) {
if (is_emptyTrie(r1) || is_emptyTrie(r2)) return;
if ((r1 instanceof $Success) && (r2 instanceof $Success)) {
acc = combiner(r1.value, r2.value, acc);
return;
}
if (!(r1 instanceof $Branch) || !(r2 instanceof $Branch)) {
asymmetricTrieError(r1, r2);
}
walk(r1.wild, r2.wild);
function examineKeys(keymap, arity) {
keymap.forEach(function (_val, key) {
walk(rlookup(r1, arity, key), rlookup(r2, arity, key));
});
}
if (is_emptyTrie(r1.wild)) {
if (is_emptyTrie(r2.wild)) {
(r1.count < r2.count ? r1 : r2).edges.forEach(examineKeys);
} else {
r1.edges.forEach(examineKeys);
}
} else {
if (is_emptyTrie(r2.wild)) {
r2.edges.forEach(examineKeys);
} else {
r1.edges.forEach(examineKeys);
r2.edges.forEach(examineKeys);
}
}
}
}
function appendTrie(m, mTailFn) {
return walk(m);
function walk(m) {
if (is_emptyTrie(m)) return emptyTrie;
if (m instanceof $Success) return mTailFn(m.value);
var target = newEmptyBranch();
target.wild = walk(m.wild);
m.edges.forEach(function (keymap, arity) {
keymap.forEach(function (k, key) {
rupdate_inplace(target, arity, key, walk(k));
});
});
return collapse(target);
}
}
// DANGEROUS: prefer subtract() instead.
//
// function triePruneBranch(m, arityKeys) {
// if (arityKeys.isEmpty()) return emptyTrie;
// if (!(m instanceof $Branch)) return m;
// var arityKey = arityKeys.first();
// var rest = arityKeys.shift();
// var arity = arityKey[0];
// var key = arityKey[1];
// m = rcopybranch(m);
// rupdate_inplace(m, arity, key, triePruneBranch(rlookup(m, arity, key), rest));
// return collapse(m);
// }
function trieStep(m, arity, key) {
if (typeof key === 'undefined') {
// Cope with API change which would otherwise silently cause problems
die("trieStep: missing 'key' argument");
}
if (is_emptyTrie(m)) return emptyTrie;
if (m instanceof $Success) return emptyTrie;
return rlookup(m, arity, key);
}
function relabel(m, f) {
return appendTrie(m, function (v) {
var v1 = f(v);
return v1 ? rsuccess(v1) : emptyTrie;
});
}
///////////////////////////////////////////////////////////////////////////
function projectionNames(p) {
var names = [];
walk(p);
return names;
function walk(p) {
if (isCapture(p)) {
names.push(captureName(p));
walk(capturePattern(p));
return;
}
if (Array.isArray(p)) {
for (var i = 0; i < p.length; i++) walk(p[i]);
return;
}
if (Struct.isStructure(p)) {
for (var i = 0; i < p.meta.arity; i++) walk(p[i]);
return;
}
}
}
function projectionArity(p) {
return projectionNames(p).length;
}
function projectionToPattern(p) {
return walk(p);
function walk(p) {
if (isCapture(p)) return walk(capturePattern(p));
if (Array.isArray(p)) {
var result = [];
for (var i = 0; i < p.length; i++) {
result.push(walk(p[i]));
}
return result;
}
if (Struct.isStructure(p)) {
var resultFields = [];
for (var i = 0; i < p.meta.arity; i++) {
resultFields[i] = walk(p[i]);
}
return new Struct.Structure(p.meta, resultFields);
}
return p;
}
}
function project(t, wholeSpec, projectSuccessOpt, combinerOpt) {
return projectMany(t, Immutable.List.of(wholeSpec), projectSuccessOpt, combinerOpt);
}
function projectMany(t, wholeSpecs, projectSuccessOpt, combinerOpt) {
var projectSuccess = projectSuccessOpt || rsuccess;
var combiner = combinerOpt || unionSuccessesDefault;
return walk(false, t, Immutable.List(wholeSpecs), function (t) {
if (t instanceof $Success) {
return projectSuccess(t.value);
} else {
return emptyTrie;
}
});
function walk(isCapturing, t, specs, kont) {
if (specs.isEmpty()) return kont(t);
if (!(t instanceof $Branch)) return emptyTrie;
var spec = specs.first();
var specsRest = specs.rest();
if (isCapture(spec)) {
if (isCapturing) {
die("projectMany: nested capture in projection: " + wholeSpecs);
}
return walk(true, t, Immutable.List.of(capturePattern(spec)), function (intermediate) {
return walk(false, intermediate, specsRest, kont);
});
}
if (spec === __) {
if (isCapturing) {
var target = newEmptyBranch();
target.wild = walk(isCapturing, t.wild, specsRest, kont);
t.edges.forEach(function (keymap, arity) {
var innerSpecs = Immutable.Repeat(__, arity);
keymap.forEach(function (k, key) {
rupdate_inplace(target, arity, key,
walk(isCapturing, k, innerSpecs, function (intermediate) {
return walk(isCapturing, intermediate, specsRest, kont);
}));
});
});
return collapse(target);
} else {
var seed = walk(isCapturing, t.wild, specsRest, kont);
t.edges.forEach(function (keymap, arity) {
var innerSpecs = Immutable.Repeat(__, arity);
keymap.forEach(function (k, key) {
seed = union(seed,
walk(isCapturing, k, innerSpecs, function (intermediate) {
return walk(isCapturing, intermediate, specsRest, kont);
}),
combiner);
});
});
return seed;
}
return target;
}
if (Struct.isStructure(spec)) {
var intermediate = walk(isCapturing,
rlookup(t, spec.meta.arity, spec.meta),
Immutable.List(spec.fields),
function (intermediate) {
return walk(isCapturing, intermediate, specsRest, kont);
});
return isCapturing ? rseq(spec.meta.arity, spec.meta, intermediate) : intermediate;
}
if (Array.isArray(spec)) {
var intermediate = walk(isCapturing,
rlookup(t, spec.length, SOA),
Immutable.List(spec),
function (intermediate) {
return walk(isCapturing, intermediate, specsRest, kont);
});
return isCapturing ? rseq(spec.length, SOA, intermediate) : intermediate;
}
if (spec instanceof $Embedded) {
die("$Embedded patterns not supported in projectMany()");
}
/* It is a normal atom */
var intermediate = walk(isCapturing, rlookup(t, 0, spec), specsRest, kont);
return isCapturing ? rseq(0, spec, intermediate) : intermediate;
}
}
function reconstructSequence(key, items) {
if (key === SOA) {
return items.toArray();
} else {
return key.instantiate(items.toArray());
}
}
function trieKeys(m, takeCount0) {
if (typeof takeCount0 !== 'number') {
// Cope with API change which would otherwise silently cause problems
die("Missing mandatory argument 'takeCount' to Trie.trieKeys");
}
if (is_emptyTrie(m)) return Immutable.Set();
return walk(m, takeCount0, Immutable.List(),
function (items, tail) {
if (is_emptyTrie(tail)) return Immutable.Set();
if (tail instanceof $Success) return Immutable.Set.of(items);
die("Trie contains more than the requested "+takeCount0+" items");
});
function walk(m, takeCount, valsRev, kont) {
if (takeCount === 0) return kont(valsRev.reverse(), m);
if (is_emptyTrie(m)) return Immutable.Set();
if (m instanceof $Success) {
die("Trie contains fewer than the requested "+takeCount0+" items");
}
if (!is_emptyTrie(m.wild)) return false;
var result = Immutable.Set();
m.edges.forEach(function (keymap, arity) {
if (result === false) return false; // break out of iteration
keymap.forEach(function (k, key) {
if (result === false) return false; // break out of iteration
var piece;
if (Struct.isStructureType(key) || key === SOA) {
piece = walk(k, arity, Immutable.List(), function (items, m1) {
var item = reconstructSequence(key, items);
return walk(m1, takeCount - 1, valsRev.unshift(item), kont);
});
} else {
piece = walk(k, takeCount - 1, valsRev.unshift(key), kont);
}
result = (piece === false) ? false : result.union(piece);
});
});
return result;
}
}
function captureToObject(captures, names) {
var d = {};
captures.forEach(function (key, index) {
d[names[index] || ('$' + index)] = key;
});
return d;
}
function trieKeysToObjects(trieKeysResult, names) {
if (trieKeysResult === false) return false;
return trieKeysResult.toList().map(function (e) { return captureToObject(e, names); });
}
function projectObjects(m, projection) {
var names = projectionNames(projection);
return trieKeysToObjects(trieKeys(project(m, projection), names.length), names);
}
// (Projection, CaptureObject) -> Pattern
function instantiateProjection(p, obj) {
var captureCount = 0;
return walk(p);
function walk(p) {
if (isCapture(p)) {
var thisCapture = captureCount++;
var name = captureName(p);
return (name !== null) ? obj[name] : obj['$' + thisCapture];
}
if (Array.isArray(p)) {
var result = [];
for (var i = 0; i < p.length; i++) {
result.push(walk(p[i]));
}
return result;
}
if (Struct.isStructure(p)) {
var resultFields = [];
for (var i = 0; i < p.meta.arity; i++) {
resultFields[i] = walk(p[i]);
}
return new Struct.Structure(p.meta, resultFields);
}
return p;
}
}
function prettyTrie(m, optionsOpt) {
var acc = [];
var options = optionsOpt || {};
walk(options.initialIndent || 0, m);
return acc.join('');
function walk(i, m) {
if (m instanceof $Success) {
var v = m.value;
if ('prettySuccess' in options) {
acc.push(" " + options.prettySuccess(v));
} else {
if (Immutable.Set.isSet(v)) { v = v.toArray(); }
acc.push(" {" + JSON.stringify(v) + "}");
}
return;
}
if (is_emptyTrie(m)) {
acc.push(" ::: nothing");
return;
}
var needSep = false;
if (!is_emptyTrie(m.wild)) {
var key = "★";
needSep = true;
acc.push(" ");
acc.push(key);
walk(i + key.length + 1, m.wild);
}
m.edges
.toOrderedMap()
.sortBy(function (keymap, arity) { return arity })
.forEach(function (keymap, arity) {
keymap
.toOrderedMap()
.sortBy(function (k, key) { return key })
.forEach(function (k, key) {
if (needSep) {
acc.push("\n");
acc.push(indentStr(i));
} else {
needSep = true;
}
acc.push(" ");
if (key === SOA) key = '<' + arity + '>';
else if (Struct.isStructureType(key)) key = key.label + '<' + arity + '>';
else if (key instanceof $Special) key = key.name;
else key = JSON.stringify(key);
if (typeof key === 'undefined') key = 'undefined';
acc.push(key);
walk(i + key.length + 1, k);
});
});
}
function indentStr(i) {
return new Array(i + 1).join(' '); // eww
}
}
///////////////////////////////////////////////////////////////////////////
function parenTypeToString(key) {
if (Struct.isStructureType(key)) {
return ':' + key.label;
} else {
return 'L';
}
}
function stringToParenType(arity, key) {
if (key[0] === ':') {
return new Struct.StructureType(key.slice(1), arity);
} else if (key === 'L') {
return SOA;
}
throw new Error("Unsupported JSON trie paren type: "+key);
}
function trieToJSON(t) {
if (is_emptyTrie(t)) { return []; }
if (t instanceof $Success) { return [true]; } // TODO: consider generalizing
// It's a $Branch.
var jParens = [];
var jAtoms = [];
t.edges.forEach(function (keymap, arity) {
keymap.forEach(function (k, key) {
var jk = trieToJSON(k);
if (Struct.isStructureType(key) || key === SOA) {
jParens.push([arity, parenTypeToString(key), jk]);
} else {
jAtoms.push([key, jk]);
}
});
});
return [jParens, trieToJSON(t.wild), jAtoms];
}
function badJSON(j) {
die("Cannot deserialize JSON trie: " + JSON.stringify(j));
}
function trieFromJSON(j) {
return decode(j);
function decode(j) {
if (!Array.isArray(j)) badJSON(j);
switch (j.length) {
case 0: return emptyTrie;
case 1: return rsuccess(true); // TODO: consider generalizing
case 3: {
var result = rcopybranch(expand(rwild(decode(j[1]))));
j[0].forEach(function (entry) {
var arity = entry[0];
if (typeof arity !== 'number') badJSON(j);
var key = stringToParenType(arity, entry[1]);
rupdate_inplace(result, arity, key, decode(entry[2]));
});
j[2].forEach(function (entry) {
var key = entry[0];
rupdate_inplace(result, 0, key, decode(entry[1]));
});
return collapse(result);
}
default: badJSON(j);
}
}
}
///////////////////////////////////////////////////////////////////////////
module.exports.__ = __;
module.exports.SOA = SOA;
module.exports.$Capture = $Capture;
module.exports.$Special = $Special;
module.exports._$ = _$;
module.exports.is_emptyTrie = is_emptyTrie;
module.exports.emptyTrie = emptyTrie;
module.exports.embeddedTrie = embeddedTrie;
module.exports.embeddedTrieArray = embeddedTrieArray;
module.exports.compilePattern = compilePattern;
module.exports.matchPattern = matchPattern;
module.exports._union = union;
module.exports.union = unionN;
module.exports.intersect = intersect;
module.exports.subtract = subtract;
module.exports.matchValue = matchValue;
module.exports.matchTrie = matchTrie;
module.exports.appendTrie = appendTrie;
// module.exports.triePruneBranch = triePruneBranch;
module.exports.trieStep = trieStep;
module.exports.trieSuccess = rsuccess;
module.exports.relabel = relabel;
module.exports.projectionNames = projectionNames;
module.exports.projectionArity = projectionArity;
module.exports.projectionToPattern = projectionToPattern;
module.exports.project = project;
module.exports.projectMany = projectMany;
module.exports.trieKeys = trieKeys;
module.exports.captureToObject = captureToObject;
module.exports.trieKeysToObjects = trieKeysToObjects;
module.exports.projectObjects = projectObjects;
module.exports.instantiateProjection = instantiateProjection;
module.exports.prettyTrie = prettyTrie;
module.exports.trieToJSON = trieToJSON;
module.exports.trieFromJSON = trieFromJSON;
// For testing
module.exports._testing = {
rsuccess: rsuccess,
rseq: rseq,
rwild: rwild
};
},{"./special.js":234,"./struct.js":235,"immutable":220}],238:[function(require,module,exports){
"use strict";
// UI (DOM + event) support for Syndicate
//
// The previous dom-driver.js + jquery-driver.js approach worked kind
// of OK, but started to fall down in a couple of areas: Added UI
// fragments lacked identity, so would sometimes move around the tree
// unexpectedly as they were updated; and there was no convenient
// means of scoping event selectors to within a particular UI
// fragment, despite various attempts at this.
//
// The design of this module aims to take these lessons into account.
var Immutable = require('immutable');
var Patch = require("./patch.js");
var Trie = require("./trie.js");
var DemandMatcher = require('./demand-matcher.js').DemandMatcher;
var Struct = require('./struct.js');
var RandomID = require('./randomid.js');
var Dataspace_ = require("./dataspace.js");
var Dataspace = Dataspace_.Dataspace;
var __ = Dataspace_.__;
var _$ = Dataspace_._$;
///////////////////////////////////////////////////////////////////////////
// Protocol
// Message. Interest in this causes event listeners to be added for
// the given eventType to all nodes matching the given selector *at
// the time of the subscription*. As nodes *from this library* come
// and go, they will have event handlers installed and removed as
// well. WARNING: The simple implementation below currently scans the
// whole document anytime a change is signalled; in future, it may not
// do such a scan.
var globalEvent = Struct.makeConstructor('global-event', ['selector', 'eventType', 'event']);
// Message. As globalEvent, but instead of using a selector to choose
// target DOM nodes, attaches an event handler to the browser "window"
// object itself.
var windowEvent = Struct.makeConstructor('window-event', ['eventType', 'event']);
// Message. Like globalEvent, but applies only within the scope of the
// UI fragment identified.
var uiEvent = Struct.makeConstructor('ui-event', ['fragmentId', 'selector', 'eventType', 'event']);
// Assertion. Causes the setup of DOM nodes corresponding to the given
// HTML fragment, as immediate children of all nodes named by the
// given selector that exist at the time of assertion. The orderBy
// field should be null, a string, or a number. Fragments are ordered
// primarily by orderBy, and secondarily by fragmentId.
var uiFragment = Struct.makeConstructor('ui-fragment',
['fragmentId', 'selector', 'html', 'orderBy']);
// Assertion. Asserted by respondent to a given uiFragment.
var uiFragmentExists = Struct.makeConstructor('ui-fragment-exists', ['fragmentId']);
// Assertion. Causes the setup of DOM attributes on all nodes named by
// the given selector that exist at the time of assertion.
//
// NOTE: Attribute "class" is a special case: it treats the value of
// the attribute as a (string encoding of a) set. The given value is
// split on whitespace, and each piece is added to the set of things
// already present. (See the implementation for details.)
var uiAttribute = Struct.makeConstructor('ui-attribute', ['selector', 'attribute', 'value']);
// Assertion. Similar to uiAttribute, but for properties of DOM nodes.
var uiProperty = Struct.makeConstructor('ui-property', ['selector', 'property', 'value']);
// Messages.
// NOTE: These do not treat "class" specially!
var setAttribute = Struct.makeConstructor('set-ui-attribute', ['selector', 'attribute', 'value']);
var removeAttribute = Struct.makeConstructor('remove-ui-attribute', ['selector', 'attribute']);
var setProperty = Struct.makeConstructor('set-ui-property', ['selector', 'property', 'value']);
var removeProperty = Struct.makeConstructor('remove-ui-property', ['selector', 'property']);
// Assertion. Current "location hash" -- the "#/path/part" fragment at
// the end of window.location.
var locationHash = Struct.makeConstructor('locationHash', ['value']);
// Message. Causes window.location to be updated to have the given new
// "location hash" value.
var setLocationHash = Struct.makeConstructor('setLocationHash', ['value']);
///////////////////////////////////////////////////////////////////////////
// ID allocators
var moduleInstance = RandomID.randomId(16, true);
var nextFragmentIdNumber = 0;
function newFragmentId() {
return 'ui_' + moduleInstance + '_' + (nextFragmentIdNumber++);
}
///////////////////////////////////////////////////////////////////////////
function spawnUIDriver(options) {
options = options || {};
var globalEventProj = globalEvent(_$('selector'), _$('eventType'), __);
Dataspace.spawn(
new DemandMatcher([Patch.observe(globalEventProj)],
[Patch.advertise(globalEventProj)],
function (c) {
Dataspace.spawn(new GlobalEventSupply(c.selector, c.eventType));
}, { name: 'globalEventSupervisor' }));
var windowEventProj = windowEvent(_$('eventType'), __);
Dataspace.spawn(
new DemandMatcher([Patch.observe(windowEventProj)],
[Patch.advertise(windowEventProj)],
function (c) {
Dataspace.spawn(new WindowEventSupply(c.eventType));
}, { name: 'windowEventSupervisor' }));
Dataspace.spawn(
new DemandMatcher([uiFragment(_$('fragmentId'), __, __, __)],
[uiFragmentExists(_$('fragmentId'))],
function (c) {
Dataspace.spawn(new UIFragment(c.fragmentId));
}, { name: 'uiFragmentSupervisor' }));
Dataspace.spawn(
new DemandMatcher([uiAttribute(_$('selector'), _$('attribute'), _$('value'))],
[Patch.advertise(uiAttribute(_$('selector'), _$('attribute'), _$('value')))],
function (c) {
Dataspace.spawn(new UIAttribute(
c.selector, c.attribute, c.value, 'attribute'));
}, { name: 'uiAttributeSupervisor' }));
Dataspace.spawn(
new DemandMatcher([uiProperty(_$('selector'), _$('property'), _$('value'))],
[Patch.advertise(uiProperty(_$('selector'), _$('property'), _$('value')))],
function (c) {
Dataspace.spawn(new UIAttribute(
c.selector, c.property, c.value, 'property'));
}, { name: 'uiPropertySupervisor' }));
Dataspace.spawn(new AttributeUpdater());
Dataspace.spawn(new LocationHashTracker(options.defaultLocationHash || '/'));
}
///////////////////////////////////////////////////////////////////////////
function GlobalEventSupply(selector, eventType) {
this.selector = selector;
this.eventType = eventType;
this.demandPat = Patch.observe(globalEvent(this.selector, this.eventType, __));
this.name = ['globalEvent', selector, eventType];
}
GlobalEventSupply.prototype.boot = function () {
var self = this;
this.handlerClosure = Dataspace.wrap(function(e) { return self.handleDomEvent(e); });
this.updateEventListeners(true);
return Patch.sub(this.demandPat) // track demand
.andThen(Patch.sub(uiFragmentExists(__))) // track new fragments
.andThen(Patch.pub(globalEvent(this.selector, this.eventType, __))) // indicate our presence
;
};
GlobalEventSupply.prototype.updateEventListeners = function (install) {
selectorMatch(document, this.selector).forEach(
eventUpdater(cleanEventType(this.eventType), this.handlerClosure, install));
};
GlobalEventSupply.prototype.trapexit = function () {
console.log('GlobalEventSupply trapexit running', this.selector, this.eventType);
this.updateEventListeners(false);
};
GlobalEventSupply.prototype.handleDomEvent = function (event) {
Dataspace.send(globalEvent(this.selector, this.eventType, event));
return dealWithPreventDefault(this.eventType, event);
};
GlobalEventSupply.prototype.handleEvent = function (e) {
this.updateEventListeners(true);
// TODO: don't be so crude about this ^. On the one hand, this lets
// us ignore uiFragmentExists records coming and going; on the other
// hand, we do potentially a lot of redundant work.
if (e.type === 'stateChange' && e.patch.project(this.demandPat).hasRemoved()) {
Dataspace.exit(); // trapexit will uninstall event listeners
}
};
///////////////////////////////////////////////////////////////////////////
function WindowEventSupply(eventType) {
this.eventType = eventType;
this.demandPat = Patch.observe(windowEvent(this.eventType, __));
this.name = ['windowEvent', eventType];
}
WindowEventSupply.prototype.boot = function () {
var self = this;
this.handlerClosure = Dataspace.wrap(function(e) { return self.handleDomEvent(e); });
this.updateEventListeners(true);
return Patch.sub(this.demandPat) // track demand
.andThen(Patch.pub(windowEvent(this.eventType, __))) // indicate our presence
;
};
WindowEventSupply.prototype.updateEventListeners = function (install) {
if (install) {
window.addEventListener(cleanEventType(this.eventType), this.handlerClosure);
} else {
window.removeEventListener(cleanEventType(this.eventType), this.handlerClosure);
}
};
WindowEventSupply.prototype.trapexit = function () {
console.log('WindowEventSupply trapexit running', this.eventType);
this.updateEventListeners(false);
};
WindowEventSupply.prototype.handleDomEvent = function (event) {
Dataspace.send(windowEvent(this.eventType, event));
return dealWithPreventDefault(this.eventType, event);
};
WindowEventSupply.prototype.handleEvent = function (e) {
if (e.type === 'stateChange' && e.patch.project(this.demandPat).hasRemoved()) {
Dataspace.exit(); // trapexit will uninstall event listeners
}
};
///////////////////////////////////////////////////////////////////////////
function UIFragment(fragmentId) {
this.fragmentId = fragmentId;
this.demandProj = uiFragment(this.fragmentId, _$('selector'), _$('html'), _$('orderBy'));
this.eventDemandProj =
Patch.observe(uiEvent(this.fragmentId, _$('selector'), _$('eventType'), __));
this.currentAnchorNodes = [];
this.currentSelector = null;
this.currentHtml = null;
this.currentOrderBy = null;
this.currentEventRegistrations = Immutable.Map();
// ^ Map from (Map of selector/eventType) to closure.
this.name = ['uiFragment', fragmentId];
}
UIFragment.prototype.boot = function () {
return Patch.sub(Trie.projectionToPattern(this.demandProj)) // track demand
.andThen(Patch.assert(uiFragmentExists(this.fragmentId))) // assert presence
.andThen(Patch.sub(Trie.projectionToPattern(this.eventDemandProj)))
// ^ track demand for fragment-specific events
;
};
UIFragment.prototype.trapexit = function () {
console.log('UIFragment trapexit running', this.fragmentId);
this.updateContent(null, null, null);
};
var SYNDICATE_SORT_KEY = '__syndicate_sort_key';
function setSortKey(n, orderBy, fragmentId) {
var v = JSON.stringify([orderBy, fragmentId]);
if ('dataset' in n) {
// html element nodes etc.
n.dataset[SYNDICATE_SORT_KEY] = v;
} else {
// text nodes, svg nodes, etc etc.
n[SYNDICATE_SORT_KEY] = v;
}
}
function getSortKey(n) {
if ('dataset' in n && n.dataset[SYNDICATE_SORT_KEY]) {
return JSON.parse(n.dataset[SYNDICATE_SORT_KEY]);
}
if (n[SYNDICATE_SORT_KEY]) {
return JSON.parse(n[SYNDICATE_SORT_KEY]);
}
return null;
}
function hasSortKey(n, orderBy, fragmentId) {
var v = getSortKey(n);
if (!v) return false;
if (v[0] !== orderBy) return false;
if (v[1] !== fragmentId) return false;
return true;
}
function firstChildNodeIndex_withSortKey(n) {
for (var i = 0; i < n.childNodes.length; i++) {
if (getSortKey(n.childNodes[i])) return i;
}
return n.childNodes.length;
}
// If *no* nodes have a sort key, returns a value that yields an empty
// range in conjunction with firstChildNodeIndex_withSortKey.
function lastChildNodeIndex_withSortKey(n) {
for (var i = n.childNodes.length - 1; i >= 0; i--) {
if (getSortKey(n.childNodes[i])) return i;
}
return n.childNodes.length - 1;
}
function isGreaterThan(a, b) {
if (typeof a > typeof b) return true;
if (typeof a < typeof b) return false;
return a > b;
}
function findInsertionPoint(n, orderBy, fragmentId) {
var lo = firstChildNodeIndex_withSortKey(n);
var hi = lastChildNodeIndex_withSortKey(n) + 1;
// lo <= hi, and [lo, hi) have sort keys.
while (lo < hi) { // when lo === hi, there's nothing more to examine.
var probe = (lo + hi) >> 1;
var probeSortKey = getSortKey(n.childNodes[probe]);
if ((isGreaterThan(probeSortKey[0], orderBy))
|| ((probeSortKey[0] === orderBy) && (probeSortKey[1] > fragmentId)))
{
hi = probe;
} else {
lo = probe + 1;
}
}
// lo === hi now.
if (lo < n.childNodes.length) {
return n.childNodes[lo];
} else {
return null;
}
}
UIFragment.prototype.removeNodes = function () {
var self = this;
self.currentAnchorNodes.forEach(function (anchorNode) {
var insertionPoint = findInsertionPoint(anchorNode, self.currentOrderBy, self.fragmentId);
while (1) {
var n = insertionPoint ? insertionPoint.previousSibling : anchorNode.lastChild;
if (!(n && hasSortKey(n, self.currentOrderBy, self.fragmentId))) break;
n.parentNode.removeChild(n); // auto-updates previousSibling/lastChild
}
});
};
function htmlToNodes(parent, html) {
var e = parent.cloneNode(false);
e.innerHTML = html;
return Array.prototype.slice.call(e.childNodes);
}
function configureNode(n) {
// Runs post-insertion configuration of nodes.
// TODO: review this design.
selectorMatch(n, '.-syndicate-focus').forEach(function (n) {
if ('focus' in n && 'setSelectionRange' in n) {
n.focus();
n.setSelectionRange(n.value.length, n.value.length);
}
});
}
UIFragment.prototype.updateContent = function (newSelector, newHtml, newOrderBy) {
var self = this;
self.removeNodes();
var newAnchors = (newSelector !== null) ? selectorMatch(document, newSelector) : [];
newAnchors.forEach(function (anchorNode) {
var insertionPoint = findInsertionPoint(anchorNode, newOrderBy, self.fragmentId);
htmlToNodes(anchorNode, newHtml).forEach(function (newNode) {
setSortKey(newNode, newOrderBy, self.fragmentId);
anchorNode.insertBefore(newNode, insertionPoint);
configureNode(newNode);
});
});
self.currentAnchorNodes = newAnchors;
self.currentSelector = newSelector;
self.currentHtml = newHtml;
self.currentOrderBy = newOrderBy;
self.currentEventRegistrations.forEach(function (_handlerClosure, key) {
self.updateEventListeners(key.toObject(), true); // (re)install event listeners
});
};
UIFragment.prototype.handleEvent = function (e) {
var self = this;
if (e.type === 'stateChange') {
var fragmentChanges = e.patch.projectObjects(self.demandProj);
fragmentChanges[0].forEach(function (c) { self.updateContent(c.selector, c.html, c.orderBy); });
fragmentChanges[1].forEach(function (c) {
if (c.selector === self.currentSelector
&& c.html === self.currentHtml
&& c.orderBy === self.currentOrderBy)
{
Dataspace.exit(); // trapexit will remove nodes
}
});
var eventDemand = e.patch.projectObjects(self.eventDemandProj);
eventDemand[0].forEach(function (c) { self.updateEventListeners(c, true); })
eventDemand[1].forEach(function (c) { self.updateEventListeners(c, false); })
}
};
UIFragment.prototype.getEventClosure = function (c) {
var self = this;
var key = Immutable.Map(c);
if (!self.currentEventRegistrations.has(key)) {
var handlerClosure = Dataspace.wrap(function (e) { return self.handleDomEvent(c, e); });
self.currentEventRegistrations = self.currentEventRegistrations.set(key, handlerClosure);
}
return self.currentEventRegistrations.get(key);
};
UIFragment.prototype.clearEventClosure = function (c) {
var key = Immutable.Map(c);
this.currentEventRegistrations = this.currentEventRegistrations.remove(key);
};
UIFragment.prototype.updateEventListeners = function (c, install) {
var self = this;
var handlerClosure = self.getEventClosure(c);
self.currentAnchorNodes.forEach(function (anchorNode) {
var insertionPoint = findInsertionPoint(anchorNode, self.currentOrderBy, self.fragmentId);
while (1) {
var uiNode = insertionPoint ? insertionPoint.previousSibling : anchorNode.lastChild;
if (!(uiNode && hasSortKey(uiNode, self.currentOrderBy, self.fragmentId))) break;
if ('querySelectorAll' in uiNode) {
selectorMatch(uiNode, c.selector).forEach(
eventUpdater(cleanEventType(c.eventType), handlerClosure, install));
}
insertionPoint = uiNode;
}
});
if (!install) {
this.clearEventClosure(c);
}
};
UIFragment.prototype.handleDomEvent = function (c, e) {
Dataspace.send(uiEvent(this.fragmentId, c.selector, c.eventType, e));
return dealWithPreventDefault(c.eventType, e);
};
///////////////////////////////////////////////////////////////////////////
function UIAttribute(selector, key, value, kind) {
if (['attribute', 'property'].indexOf(kind) === -1) {
throw new Error("UIAttribute: kind must be 'attribute' or 'property'; got " + kind);
}
this.selector = selector;
this.key = key;
this.value = value;
this.kind = kind;
this.savedValues = [];
// ^ Array of {node: DOMNode, value: (U Null String)},
// when attribute !== 'class' or kind !== 'attribute'.
// ^ Array of {node: DOMNode},
// when attribute === 'class' and kind === 'attribute'.
this.name = ['uiAttribute', selector, key, value, kind];
}
UIAttribute.prototype.boot = function () {
var a = ((this.kind === 'attribute') ? uiAttribute : uiProperty)(this.selector, this.key, this.value);
this.install();
return Patch.sub(a).andThen(Patch.pub(a));
};
UIAttribute.prototype.trapexit = function () {
console.log('UIAttribute trapexit running', this.selector, this.key, this.value, this.kind);
this.restoreSavedValues();
};
function splitClassValue(v) {
v = (v || '').trim();
return v ? v.split(/ +/) : [];
}
UIAttribute.prototype.install = function () {
var self = this;
selectorMatch(document, self.selector).forEach(function (node) {
switch (self.kind) {
case 'attribute':
if (self.key === 'class') {
// Deliberately maintains duplicates, so we don't interfere
// with potential other UIAttribute instances on the same
// objects for the same attribute. See also
// restoreSavedValues.
var existing = splitClassValue(node.getAttribute('class'));
var toAdd = splitClassValue(self.value);
self.savedValues.push({node: node});
node.setAttribute('class', existing.concat(toAdd).join(' '));
} else {
self.savedValues.push({node: node, value: node.getAttribute(self.key)});
node.setAttribute(self.key, self.value);
}
break;
case 'property':
self.savedValues.push({node: node, value: node[self.key]});
node[self.key] = self.value;
break;
}
});
};
UIAttribute.prototype.restoreSavedValues = function () {
var self = this;
self.savedValues.forEach(function (entry) {
switch (self.kind) {
case 'attribute':
if (self.key === 'class') {
var existing = splitClassValue(entry.node.getAttribute('class'));
var toRemove = splitClassValue(self.value);
toRemove.forEach(function (v) {
var i = existing.indexOf(v);
if (i !== -1) { existing.splice(i, 1); }
});
if (existing.length === 0) {
entry.node.removeAttribute('class');
} else {
entry.node.setAttribute('class', existing.join(' '));
}
} else {
if (entry.value === null) {
entry.node.removeAttribute(self.key);
} else {
entry.node.setAttribute(self.key, entry.value);
}
}
break;
case 'property':
if (typeof entry.value === 'undefined') {
delete entry.node[self.key];
} else {
entry.node[self.key] = entry.value;
}
break;
}
});
self.savedValues = [];
};
UIAttribute.prototype.handleEvent = function (e) {
if (e.type === 'stateChange' && e.patch.hasRemoved()) {
Dataspace.exit(); // trapexit will restore attributes
}
};
///////////////////////////////////////////////////////////////////////////
function escapeDataAttributeName(s) {
// Per https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset,
// the rules seem to be:
//
// 1. Must not contain a dash immediately followed by an ASCII lowercase letter
// 2. Must not contain anything other than:
// - letters
// - numbers
// - dash, dot, colon, underscore
//
// I'm not implementing this exactly - I'm escaping some things that
// don't absolutely need escaping, because it's simpler and I don't
// yet need to undo this transformation.
if (typeof s !== 'string') {
s = JSON.stringify(s);
}
var result = '';
for (var i = 0; i < s.length; i++) {
var c = s[i];
if (c >= 'a' && c <= 'z') { result = result + c; continue; }
if (c >= 'A' && c <= 'Z') { result = result + c; continue; }
if (c >= '0' && c <= '9') { result = result + c; continue; }
if (c === '.' || c === ':') { result = result + c; continue; }
c = c.charCodeAt(0);
result = result + '_' + c + '_';
}
return result;
}
function dealWithPreventDefault(eventType, event) {
var shouldPreventDefault = eventType.charAt(0) !== '+';
if (shouldPreventDefault) event.preventDefault();
return !shouldPreventDefault;
}
function cleanEventType(eventType) {
return (eventType.charAt(0) === '+') ? eventType.slice(1) : eventType;
}
function selectorMatch(n, selector) {
if (n && typeof n === 'object' && 'querySelectorAll' in n) {
if (selector === '.') {
return [n];
} else {
return Array.prototype.slice.call(n.querySelectorAll(selector));
}
} else {
return [];
}
}
function eventUpdater(eventType, handlerClosure, install) {
return function (n) {
// addEventListener and removeEventListener are idempotent.
if (install) {
n.addEventListener(eventType, handlerClosure);
} else {
n.removeEventListener(eventType, handlerClosure);
}
};
}
///////////////////////////////////////////////////////////////////////////
function Anchor(explicitFragmentId) {
this.fragmentId =
(typeof explicitFragmentId === 'undefined') ? newFragmentId() : explicitFragmentId;
this.htmlPattern = uiFragment(this.fragmentId, __, __, __);
this.eventPattern = uiEvent(this.fragmentId, __, __, __);
}
Anchor.prototype.context = function (/* ... */) {
var extn = Array.prototype.slice.call(arguments).map(escapeDataAttributeName).join('__');
return new Anchor(this.fragmentId + '__' + extn);
};
Anchor.prototype.html = function (selector, html, orderBy) {
return uiFragment(this.fragmentId,
selector,
html,
typeof orderBy === 'undefined' ? null : orderBy);
};
Anchor.prototype.event = function (selector, eventType, event) {
return uiEvent(this.fragmentId, selector, eventType, event);
};
///////////////////////////////////////////////////////////////////////////
function LocationHashTracker(defaultLocationHash) {
this.defaultLocationHash = defaultLocationHash;
this.hashValue = null;
this.name = 'LocationHashTracker';
}
LocationHashTracker.prototype.boot = function () {
var self = this;
this.loadHash();
this.handlerClosure = Dataspace.wrap(function (e) { self.handleDomEvent(e); });
window.addEventListener('hashchange', this.handlerClosure);
return Patch.assert(locationHash(this.hashValue))
.andThen(Patch.sub(setLocationHash(__)));
};
LocationHashTracker.prototype.trapexit = function () {
window.removeEventListener('hashchange', this.handlerClosure);
};
LocationHashTracker.prototype.loadHash = function () {
this.hashValue = window.location.hash;
if (this.hashValue.length && this.hashValue[0] === '#') {
this.hashValue = this.hashValue.slice(1);
}
if (!this.hashValue) {
this.hashValue = this.defaultLocationHash;
}
};
LocationHashTracker.prototype.handleDomEvent = function (e) {
this.loadHash();
Dataspace.stateChange(Patch.retract(locationHash(__))
.andThen(Patch.assert(locationHash(this.hashValue))));
};
LocationHashTracker.prototype.handleEvent = function (e) {
if (e.type === 'message' && setLocationHash.isClassOf(e.message)) {
window.location.hash = e.message[0];
}
};
///////////////////////////////////////////////////////////////////////////
function AttributeUpdater() {
this.name = 'AttributeUpdater';
}
AttributeUpdater.prototype.boot = function () {
return Patch.sub(setAttribute(__, __, __))
.andThen(Patch.sub(removeAttribute(__, __)))
.andThen(Patch.sub(setProperty(__, __, __)))
.andThen(Patch.sub(removeProperty(__, __)))
;
};
AttributeUpdater.prototype.handleEvent = function (e) {
if (e.type === 'message') {
var f = false;
if (setAttribute.isClassOf(e.message)) {
f = function (n, k) { n.setAttribute(k, e.message[2]); };
} else if (removeAttribute.isClassOf(e.message)) {
f = function (n, k) { n.removeAttribute(k); };
} else if (setProperty.isClassOf(e.message)) {
f = function (n, k) { n[k] = e.message[2]; };
} else if (removeProperty.isClassOf(e.message)) {
f = function (n, k) { delete n[k]; };
}
if (f) {
selectorMatch(document, e.message[0]).forEach(function (n) {
f(n, e.message[1]);
});
}
}
};
///////////////////////////////////////////////////////////////////////////
module.exports.newFragmentId = newFragmentId;
module.exports.spawnUIDriver = spawnUIDriver;
module.exports.Anchor = Anchor;
module.exports.globalEvent = globalEvent;
module.exports.windowEvent = windowEvent;
module.exports.uiEvent = uiEvent;
module.exports.uiFragment = uiFragment;
module.exports.uiFragmentExists = uiFragmentExists;
module.exports.uiAttribute = uiAttribute;
module.exports.uiProperty = uiProperty;
module.exports.setAttribute = setAttribute;
module.exports.removeAttribute = removeAttribute;
module.exports.setProperty = setProperty;
module.exports.removeProperty = removeProperty;
module.exports.locationHash = locationHash;
module.exports.setLocationHash = setLocationHash;
},{"./dataspace.js":225,"./demand-matcher.js":226,"./patch.js":230,"./randomid.js":231,"./struct.js":235,"./trie.js":237,"immutable":220}],239:[function(require,module,exports){
"use strict";
var Reflect = require("./reflect.js");
module.exports.extend = function (what, _with) {
for (var prop in _with) {
if (_with.hasOwnProperty(prop)) {
what[prop] = _with[prop];
}
}
return what;
};
module.exports.kwApply = function (f, thisArg, args) {
var formals = Reflect.formalParameters(f);
var actuals = []
for (var i = 0; i < formals.length; i++) {
var formal = formals[i];
if (!(formal in args)) {
throw new Error("Function parameter '"+formal+"' not present in args");
}
actuals.push(args[formal]);
}
return f.apply(thisArg, actuals);
};
},{"./reflect.js":232}],240:[function(require,module,exports){
"use strict";
// Wake detector - notices when something (such as
// suspension/sleeping!) has caused periodic activities to be
// interrupted, and warns others about it
// Inspired by http://blog.alexmaccaw.com/javascript-wake-event
var Patch = require("./patch.js");
var Struct = require('./struct.js');
var Dataspace_ = require("./dataspace.js");
var Dataspace = Dataspace_.Dataspace;
var __ = Dataspace_.__;
var _$ = Dataspace_._$;
var wakeEvent = Struct.makeConstructor('wakeEvent', []);
function spawnWakeDetector(periodOpt) {
Dataspace.spawn(new WakeDetector(periodOpt));
}
function WakeDetector(periodOpt) {
this.period = periodOpt || 10000;
this.mostRecentTrigger = +(new Date());
this.timerId = null;
}
WakeDetector.prototype.boot = function () {
var self = this;
this.timerId = setInterval(Dataspace.wrap(function () { self.trigger(); }), this.period);
return Patch.pub(wakeEvent());
};
WakeDetector.prototype.handleEvent = function (e) {};
WakeDetector.prototype.trigger = function () {
var now = +(new Date());
if (now - this.mostRecentTrigger > this.period * 1.5) {
Dataspace.send(wakeEvent());
}
this.mostRecentTrigger = now;
};
///////////////////////////////////////////////////////////////////////////
module.exports.spawnWakeDetector = spawnWakeDetector;
module.exports.WakeDetector = WakeDetector;
module.exports.wakeEvent = wakeEvent;
},{"./dataspace.js":225,"./patch.js":230,"./struct.js":235}]},{},[228])(228)
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9hZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9hdXRoQ2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2RlY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2VuY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2doYXNoLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jYmMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jZmIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jZmIxLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiOC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2N0ci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2VjYi5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL29mYi5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9idWZmZXIteG9yL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbm9kZV9tb2R1bGVzL2NpcGhlci1iYXNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvc3RyZWFtQ2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1kZXMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9tb2Rlcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy9jYmMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9ub2RlX21vZHVsZXMvZGVzLmpzL2xpYi9kZXMvY2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1kZXMvbm9kZV9tb2R1bGVzL2Rlcy5qcy9saWIvZGVzL2Rlcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy9lZGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9ub2RlX21vZHVsZXMvZGVzLmpzL2xpYi9kZXMvdXRpbHMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9ub2RlX21vZHVsZXMvZGVzLmpzL25vZGVfbW9kdWxlcy9taW5pbWFsaXN0aWMtYXNzZXJ0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvZXZwX2J5dGVzdG9rZXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9hbGdvcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9jdXJ2ZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvYm4uanMvbGliL2JuLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktcnNhL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvY3VydmUvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvY3VydmUvZWR3YXJkcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvY3VydmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL21vbnQuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL3Nob3J0LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9jdXJ2ZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VjL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9lYy9rZXkuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VjL3NpZ25hdHVyZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvZWRkc2EvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VkZHNhL2tleS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvZWRkc2Evc2lnbmF0dXJlLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9obWFjLWRyYmcuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL3ByZWNvbXB1dGVkL3NlY3AyNTZrMS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvdXRpbHMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2Jyb3JhbmQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2guanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL2htYWMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvcmlwZW1kLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC91dGlscy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9wYWNrYWdlLmpzb24iLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9hZXNpZC5qc29uIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvYXNuMS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2ZpeFByb2MuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYXBpLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYmFzZS9idWZmZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9iYXNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYmFzZS9ub2RlLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYmFzZS9yZXBvcnRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2NvbnN0YW50cy9kZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9jb25zdGFudHMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9kZWNvZGVycy9kZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9kZWNvZGVycy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2RlY29kZXJzL3BlbS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2VuY29kZXJzL2Rlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2VuY29kZXJzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvZW5jb2RlcnMvcGVtLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2Flcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9hdXRoQ2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2RlY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9lbmNyeXB0ZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvZ2hhc2guanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2NmYjEuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiOC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jdHIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvb2ZiLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9idWZmZXIteG9yL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9zdHJlYW1DaXBoZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvZXZwX2J5dGVzdG9rZXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9zaWduLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vdmVyaWZ5LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtZWNkaC9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9oZWxwZXJzLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9tZDUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvbm9kZV9tb2R1bGVzL3JpcGVtZDE2MC9saWIvcmlwZW1kMTYwLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9ub2RlX21vZHVsZXMvc2hhLmpzL2hhc2guanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvc2hhLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9ub2RlX21vZHVsZXMvc2hhLmpzL3NoYTEuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvc2hhMjI0LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9ub2RlX21vZHVsZXMvc2hhLmpzL3NoYTI1Ni5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvbm9kZV9tb2R1bGVzL3NoYS5qcy9zaGEzODQuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvc2hhNTEyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaG1hYy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9kaWZmaWUtaGVsbG1hbi9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9kaWZmaWUtaGVsbG1hbi9saWIvZGguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2RpZmZpZS1oZWxsbWFuL2xpYi9nZW5lcmF0ZVByaW1lLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9kaWZmaWUtaGVsbG1hbi9saWIvcHJpbWVzLmpzb24iLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2RpZmZpZS1oZWxsbWFuL25vZGVfbW9kdWxlcy9taWxsZXItcmFiaW4vbGliL21yLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wYmtkZjIvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbWdmLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1yc2EvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2ZpeFByb2MuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvYWVzLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvYXV0aENpcGhlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2RlY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2VuY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2doYXNoLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiMS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2NmYjguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jdHIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9vZmIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9ub2RlX21vZHVsZXMvYnVmZmVyLXhvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL3N0cmVhbUNpcGhlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2V2cF9ieXRlc3Rva2V5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9wcml2YXRlRGVjcnlwdC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvcHVibGljRW5jcnlwdC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvd2l0aFB1YmxpYy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQveG9yLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yYW5kb21ieXRlcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9pbnNlcnQtbW9kdWxlLWdsb2JhbHMvbm9kZV9tb2R1bGVzL2lzLWJ1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2R1cGxleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fZHVwbGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcmVhZGFibGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fd3JpdGFibGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL25vZGVfbW9kdWxlcy9jb3JlLXV0aWwtaXMvbGliL3V0aWwuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL25vZGVfbW9kdWxlcy9wcm9jZXNzLW5leHRpY2stYXJncy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbm9kZV9tb2R1bGVzL3V0aWwtZGVwcmVjYXRlL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3Bhc3N0aHJvdWdoLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS93cml0YWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9zdHJpbmdfZGVjb2Rlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy92bS1icm93c2VyaWZ5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3ZtLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2luZGV4b2YvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaW1tdXRhYmxlL2Rpc3QvaW1tdXRhYmxlLmpzIiwic3JjL2Fjay5qcyIsInNyYy9hY3Rvci5qcyIsInNyYy9icm9rZXIuanMiLCJzcmMvY29kZWMuanMiLCJzcmMvZGF0YXNwYWNlLmpzIiwic3JjL2RlbWFuZC1tYXRjaGVyLmpzIiwic3JjL2dyb3VuZC5qcyIsInNyYy9tYWluLmpzIiwic3JjL211eC5qcyIsInNyYy9wYXRjaC5qcyIsInNyYy9yYW5kb21pZC5qcyIsInNyYy9yZWZsZWN0LmpzIiwic3JjL3NlYWwuanMiLCJzcmMvc3BlY2lhbC5qcyIsInNyYy9zdHJ1Y3QuanMiLCJzcmMvdGltZXItZHJpdmVyLmpzIiwic3JjL3RyaWUuanMiLCJzcmMvdWkuanMiLCJzcmMvdXRpbC5qcyIsInNyYy93YWtlLWRldGVjdG9yLWRyaXZlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBOzs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL3FEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDekVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2pMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2xHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDeEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN2R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMzMUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9WQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMVpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzc0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOU5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzV3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3JIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDckdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdm1CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDakxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNqR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDekxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDdkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUM3RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2xHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDdElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNuUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDcEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDakhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNyR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDakxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNqR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDM0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0ZBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMvMkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbkxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNuZ0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQzNHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNuRUE7QUFDQTs7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2hCQTtBQUNBOztBQ0RBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsM0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ROQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2w5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDanZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiIiwiLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBTbG93QnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcblxuLyoqXG4gKiBJZiBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgOlxuICogICA9PT0gdHJ1ZSAgICBVc2UgVWludDhBcnJheSBpbXBsZW1lbnRhdGlvbiAoZmFzdGVzdClcbiAqICAgPT09IGZhbHNlICAgVXNlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiAobW9zdCBjb21wYXRpYmxlLCBldmVuIElFNilcbiAqXG4gKiBCcm93c2VycyB0aGF0IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGFyZSBJRSAxMCssIEZpcmVmb3ggNCssIENocm9tZSA3KywgU2FmYXJpIDUuMSssXG4gKiBPcGVyYSAxMS42KywgaU9TIDQuMisuXG4gKlxuICogRHVlIHRvIHZhcmlvdXMgYnJvd3NlciBidWdzLCBzb21ldGltZXMgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiB3aWxsIGJlIHVzZWQgZXZlblxuICogd2hlbiB0aGUgYnJvd3NlciBzdXBwb3J0cyB0eXBlZCBhcnJheXMuXG4gKlxuICogTm90ZTpcbiAqXG4gKiAgIC0gRmlyZWZveCA0LTI5IGxhY2tzIHN1cHBvcnQgZm9yIGFkZGluZyBuZXcgcHJvcGVydGllcyB0byBgVWludDhBcnJheWAgaW5zdGFuY2VzLFxuICogICAgIFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4LlxuICpcbiAqICAgLSBDaHJvbWUgOS0xMCBpcyBtaXNzaW5nIHRoZSBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uLlxuICpcbiAqICAgLSBJRTEwIGhhcyBhIGJyb2tlbiBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYXJyYXlzIG9mXG4gKiAgICAgaW5jb3JyZWN0IGxlbmd0aCBpbiBzb21lIHNpdHVhdGlvbnMuXG5cbiAqIFdlIGRldGVjdCB0aGVzZSBidWdneSBicm93c2VycyBhbmQgc2V0IGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGAgdG8gYGZhbHNlYCBzbyB0aGV5XG4gKiBnZXQgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaXMgc2xvd2VyIGJ1dCBiZWhhdmVzIGNvcnJlY3RseS5cbiAqL1xuQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgPSBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVCAhPT0gdW5kZWZpbmVkXG4gID8gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgOiB0eXBlZEFycmF5U3VwcG9ydCgpXG5cbi8qXG4gKiBFeHBvcnQga01heExlbmd0aCBhZnRlciB0eXBlZCBhcnJheSBzdXBwb3J0IGlzIGRldGVybWluZWQuXG4gKi9cbmV4cG9ydHMua01heExlbmd0aCA9IGtNYXhMZW5ndGgoKVxuXG5mdW5jdGlvbiB0eXBlZEFycmF5U3VwcG9ydCAoKSB7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLmZvbyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MiAmJiAvLyB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG5mdW5jdGlvbiBjcmVhdGVCdWZmZXIgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoa01heExlbmd0aCgpIDwgbGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgdHlwZWQgYXJyYXkgbGVuZ3RoJylcbiAgfVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICBpZiAodGhhdCA9PT0gbnVsbCkge1xuICAgICAgdGhhdCA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICAgIH1cbiAgICB0aGF0Lmxlbmd0aCA9IGxlbmd0aFxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGhhdmUgdGhlaXJcbiAqIHByb3RvdHlwZSBjaGFuZ2VkIHRvIGBCdWZmZXIucHJvdG90eXBlYC4gRnVydGhlcm1vcmUsIGBCdWZmZXJgIGlzIGEgc3ViY2xhc3Mgb2ZcbiAqIGBVaW50OEFycmF5YCwgc28gdGhlIHJldHVybmVkIGluc3RhbmNlcyB3aWxsIGhhdmUgYWxsIHRoZSBub2RlIGBCdWZmZXJgIG1ldGhvZHNcbiAqIGFuZCB0aGUgYFVpbnQ4QXJyYXlgIG1ldGhvZHMuIFNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0XG4gKiByZXR1cm5zIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIFRoZSBgVWludDhBcnJheWAgcHJvdG90eXBlIHJlbWFpbnMgdW5tb2RpZmllZC5cbiAqL1xuXG5mdW5jdGlvbiBCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0lmIGVuY29kaW5nIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUodGhpcywgYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKHRoaXMsIGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuLy8gVE9ETzogTGVnYWN5LCBub3QgbmVlZGVkIGFueW1vcmUuIFJlbW92ZSBpbiBuZXh0IG1ham9yIHZlcnNpb24uXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIGFyci5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gZnJvbSAodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldClcbiAgfVxuXG4gIHJldHVybiBmcm9tT2JqZWN0KHRoYXQsIHZhbHVlKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKG51bGwsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbmlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICBCdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG4gIEJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG4gIGlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAmJlxuICAgICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gICAgLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLCBTeW1ib2wuc3BlY2llcywge1xuICAgICAgdmFsdWU6IG51bGwsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jICh0aGF0LCBzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybiBhbGxvYyhudWxsLCBzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHRoYXQsIHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogRXF1aXZhbGVudCB0byBCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqICovXG5CdWZmZXIuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cbi8qKlxuICogRXF1aXZhbGVudCB0byBTbG93QnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAodGhhdCwgc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImVuY29kaW5nXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBlbmNvZGluZycpXG4gIH1cblxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG5cbiAgdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gY2hlY2tlZChhcnJheS5sZW5ndGgpIHwgMFxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICBhcnJheS5ieXRlTGVuZ3RoIC8vIHRoaXMgdGhyb3dzIGlmIGBhcnJheWAgaXMgbm90IGEgdmFsaWQgQXJyYXlCdWZmZXJcblxuICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnb2Zmc2V0XFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0ICsgKGxlbmd0aCB8fCAwKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdsZW5ndGhcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBhcnJheVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbUFycmF5TGlrZSh0aGF0LCBhcnJheSlcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmopIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmopKSB7XG4gICAgdmFyIGxlbiA9IGNoZWNrZWQob2JqLmxlbmd0aCkgfCAwXG4gICAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW4pXG5cbiAgICBpZiAodGhhdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0aGF0XG4gICAgfVxuXG4gICAgb2JqLmNvcHkodGhhdCwgMCwgMCwgbGVuKVxuICAgIHJldHVybiB0aGF0XG4gIH1cblxuICBpZiAob2JqKSB7XG4gICAgaWYgKCh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIG9iai5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgJ2xlbmd0aCcgaW4gb2JqKSB7XG4gICAgICBpZiAodHlwZW9mIG9iai5sZW5ndGggIT09ICdudW1iZXInIHx8IGlzbmFuKG9iai5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgMClcbiAgICAgIH1cbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iailcbiAgICB9XG5cbiAgICBpZiAob2JqLnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkob2JqLmRhdGEpKSB7XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmouZGF0YSlcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuJylcbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IGtNYXhMZW5ndGhgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0ga01heExlbmd0aCgpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIGtNYXhMZW5ndGgoKS50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKCtsZW5ndGggIT0gbGVuZ3RoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG4gICAgbGVuZ3RoID0gMFxuICB9XG4gIHJldHVybiBCdWZmZXIuYWxsb2MoK2xlbmd0aClcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldXG4gICAgICB5ID0gYltpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3Jhdyc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYnVmID0gbGlzdFtpXVxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gICAgfVxuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKVxuICAgIHBvcyArPSBidWYubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmcubGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldyA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpIHx8IHN0cmluZyBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xuICAgIHJldHVybiBzdHJpbmcuYnl0ZUxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgIHN0cmluZyA9ICcnICsgc3RyaW5nXG4gIH1cblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIC8vIERlcHJlY2F0ZWRcbiAgICAgIGNhc2UgJ3Jhdyc6XG4gICAgICBjYXNlICdyYXdzJzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG90ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGJpbmFyeVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9IChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG4vLyBUaGUgcHJvcGVydHkgaXMgdXNlZCBieSBgQnVmZmVyLmlzQnVmZmVyYCBhbmQgYGlzLWJ1ZmZlcmAgKGluIFNhZmFyaSA1LTcpIHRvIGRldGVjdFxuLy8gQnVmZmVyIGluc3RhbmNlcy5cbkJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyID0gdHJ1ZVxuXG5mdW5jdGlvbiBzd2FwIChiLCBuLCBtKSB7XG4gIHZhciBpID0gYltuXVxuICBiW25dID0gYlttXVxuICBiW21dID0gaVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAxNiA9IGZ1bmN0aW9uIHN3YXAxNiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gMikge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDEpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMzIgPSBmdW5jdGlvbiBzd2FwMzIgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDQgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDMyLWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAzKVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyAyKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlICh0YXJnZXQsIHN0YXJ0LCBlbmQsIHRoaXNTdGFydCwgdGhpc0VuZCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIH1cblxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuZCA9IHRhcmdldCA/IHRhcmdldC5sZW5ndGggOiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc1N0YXJ0ID0gMFxuICB9XG4gIGlmICh0aGlzRW5kID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzRW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChzdGFydCA8IDAgfHwgZW5kID4gdGFyZ2V0Lmxlbmd0aCB8fCB0aGlzU3RhcnQgPCAwIHx8IHRoaXNFbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdvdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kICYmIHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kKSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cbiAgaWYgKHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAxXG4gIH1cblxuICBzdGFydCA+Pj49IDBcbiAgZW5kID4+Pj0gMFxuICB0aGlzU3RhcnQgPj4+PSAwXG4gIHRoaXNFbmQgPj4+PSAwXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCkgcmV0dXJuIDBcblxuICB2YXIgeCA9IHRoaXNFbmQgLSB0aGlzU3RhcnRcbiAgdmFyIHkgPSBlbmQgLSBzdGFydFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcblxuICB2YXIgdGhpc0NvcHkgPSB0aGlzLnNsaWNlKHRoaXNTdGFydCwgdGhpc0VuZClcbiAgdmFyIHRhcmdldENvcHkgPSB0YXJnZXQuc2xpY2Uoc3RhcnQsIGVuZClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKHRoaXNDb3B5W2ldICE9PSB0YXJnZXRDb3B5W2ldKSB7XG4gICAgICB4ID0gdGhpc0NvcHlbaV1cbiAgICAgIHkgPSB0YXJnZXRDb3B5W2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgdmFyIGluZGV4U2l6ZSA9IDFcbiAgdmFyIGFyckxlbmd0aCA9IGFyci5sZW5ndGhcbiAgdmFyIHZhbExlbmd0aCA9IHZhbC5sZW5ndGhcblxuICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKGVuY29kaW5nID09PSAndWNzMicgfHwgZW5jb2RpbmcgPT09ICd1Y3MtMicgfHxcbiAgICAgICAgZW5jb2RpbmcgPT09ICd1dGYxNmxlJyB8fCBlbmNvZGluZyA9PT0gJ3V0Zi0xNmxlJykge1xuICAgICAgaWYgKGFyci5sZW5ndGggPCAyIHx8IHZhbC5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAtMVxuICAgICAgfVxuICAgICAgaW5kZXhTaXplID0gMlxuICAgICAgYXJyTGVuZ3RoIC89IDJcbiAgICAgIHZhbExlbmd0aCAvPSAyXG4gICAgICBieXRlT2Zmc2V0IC89IDJcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZWFkIChidWYsIGkpIHtcbiAgICBpZiAoaW5kZXhTaXplID09PSAxKSB7XG4gICAgICByZXR1cm4gYnVmW2ldXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBidWYucmVhZFVJbnQxNkJFKGkgKiBpbmRleFNpemUpXG4gICAgfVxuICB9XG5cbiAgdmFyIGZvdW5kSW5kZXggPSAtMVxuICBmb3IgKHZhciBpID0gMDsgYnl0ZU9mZnNldCArIGkgPCBhcnJMZW5ndGg7IGkrKykge1xuICAgIGlmIChyZWFkKGFyciwgYnl0ZU9mZnNldCArIGkpID09PSByZWFkKHZhbCwgZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXgpKSB7XG4gICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICBpZiAoaSAtIGZvdW5kSW5kZXggKyAxID09PSB2YWxMZW5ndGgpIHJldHVybiAoYnl0ZU9mZnNldCArIGZvdW5kSW5kZXgpICogaW5kZXhTaXplXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChmb3VuZEluZGV4ICE9PSAtMSkgaSAtPSBpIC0gZm91bmRJbmRleFxuICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgfVxuICB9XG4gIHJldHVybiAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2YgYnl0ZU9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGJ5dGVPZmZzZXRcbiAgICBieXRlT2Zmc2V0ID0gMFxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSB7XG4gICAgYnl0ZU9mZnNldCA9IDB4N2ZmZmZmZmZcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIHtcbiAgICBieXRlT2Zmc2V0ID0gLTB4ODAwMDAwMDBcbiAgfVxuICBieXRlT2Zmc2V0ID4+PSAwXG5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gdGhpcy5sZW5ndGgpIHJldHVybiAtMVxuXG4gIC8vIE5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gTWF0aC5tYXgodGhpcy5sZW5ndGggKyBieXRlT2Zmc2V0LCAwKVxuXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIHZhbCA9IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gIH1cblxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICAvLyBzcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZy9idWZmZXIgYWx3YXlzIGZhaWxzXG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpXG4gIH1cbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKHRoaXMsIFsgdmFsIF0sIGJ5dGVPZmZzZXQsIGVuY29kaW5nKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uIGluY2x1ZGVzICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiB0aGlzLmluZGV4T2YodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykgIT09IC0xXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgcmV0dXJuIGlcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJpbmFyeVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoIHwgMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIC8vIGxlZ2FjeSB3cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aCkgLSByZW1vdmUgaW4gdjAuMTNcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQnXG4gICAgKVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBiaW5hcnlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICAvLyBXYXJuaW5nOiBtYXhMZW5ndGggbm90IHRha2VuIGludG8gYWNjb3VudCBpbiBiYXNlNjRXcml0ZVxuICAgICAgICByZXR1cm4gYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHVjczJXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiB1dGY4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG4gIHZhciByZXMgPSBbXVxuXG4gIHZhciBpID0gc3RhcnRcbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgZmlyc3RCeXRlID0gYnVmW2ldXG4gICAgdmFyIGNvZGVQb2ludCA9IG51bGxcbiAgICB2YXIgYnl0ZXNQZXJTZXF1ZW5jZSA9IChmaXJzdEJ5dGUgPiAweEVGKSA/IDRcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4REYpID8gM1xuICAgICAgOiAoZmlyc3RCeXRlID4gMHhCRikgPyAyXG4gICAgICA6IDFcblxuICAgIGlmIChpICsgYnl0ZXNQZXJTZXF1ZW5jZSA8PSBlbmQpIHtcbiAgICAgIHZhciBzZWNvbmRCeXRlLCB0aGlyZEJ5dGUsIGZvdXJ0aEJ5dGUsIHRlbXBDb2RlUG9pbnRcblxuICAgICAgc3dpdGNoIChieXRlc1BlclNlcXVlbmNlKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZmlyc3RCeXRlIDwgMHg4MCkge1xuICAgICAgICAgICAgY29kZVBvaW50ID0gZmlyc3RCeXRlXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4MUYpIDw8IDB4NiB8IChzZWNvbmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3Rikge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweEMgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4NiB8ICh0aGlyZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGRiAmJiAodGVtcENvZGVQb2ludCA8IDB4RDgwMCB8fCB0ZW1wQ29kZVBvaW50ID4gMHhERkZGKSkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBmb3VydGhCeXRlID0gYnVmW2kgKyAzXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAoZm91cnRoQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHgxMiB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHhDIHwgKHRoaXJkQnl0ZSAmIDB4M0YpIDw8IDB4NiB8IChmb3VydGhCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHhGRkZGICYmIHRlbXBDb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb2RlUG9pbnQgPT09IG51bGwpIHtcbiAgICAgIC8vIHdlIGRpZCBub3QgZ2VuZXJhdGUgYSB2YWxpZCBjb2RlUG9pbnQgc28gaW5zZXJ0IGFcbiAgICAgIC8vIHJlcGxhY2VtZW50IGNoYXIgKFUrRkZGRCkgYW5kIGFkdmFuY2Ugb25seSAxIGJ5dGVcbiAgICAgIGNvZGVQb2ludCA9IDB4RkZGRFxuICAgICAgYnl0ZXNQZXJTZXF1ZW5jZSA9IDFcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA+IDB4RkZGRikge1xuICAgICAgLy8gZW5jb2RlIHRvIHV0ZjE2IChzdXJyb2dhdGUgcGFpciBkYW5jZSlcbiAgICAgIGNvZGVQb2ludCAtPSAweDEwMDAwXG4gICAgICByZXMucHVzaChjb2RlUG9pbnQgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApXG4gICAgICBjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRlxuICAgIH1cblxuICAgIHJlcy5wdXNoKGNvZGVQb2ludClcbiAgICBpICs9IGJ5dGVzUGVyU2VxdWVuY2VcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkocmVzKVxufVxuXG4vLyBCYXNlZCBvbiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjc0NzI3Mi82ODA3NDIsIHRoZSBicm93c2VyIHdpdGhcbi8vIHRoZSBsb3dlc3QgbGltaXQgaXMgQ2hyb21lLCB3aXRoIDB4MTAwMDAgYXJncy5cbi8vIFdlIGdvIDEgbWFnbml0dWRlIGxlc3MsIGZvciBzYWZldHlcbnZhciBNQVhfQVJHVU1FTlRTX0xFTkdUSCA9IDB4MTAwMFxuXG5mdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkgKGNvZGVQb2ludHMpIHtcbiAgdmFyIGxlbiA9IGNvZGVQb2ludHMubGVuZ3RoXG4gIGlmIChsZW4gPD0gTUFYX0FSR1VNRU5UU19MRU5HVEgpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNvZGVQb2ludHMpIC8vIGF2b2lkIGV4dHJhIHNsaWNlKClcbiAgfVxuXG4gIC8vIERlY29kZSBpbiBjaHVua3MgdG8gYXZvaWQgXCJjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIi5cbiAgdmFyIHJlcyA9ICcnXG4gIHZhciBpID0gMFxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFxuICAgICAgU3RyaW5nLFxuICAgICAgY29kZVBvaW50cy5zbGljZShpLCBpICs9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKVxuICAgIClcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldICYgMHg3RilcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGJpbmFyeVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGhleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYnVmLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHZhciByZXMgPSAnJ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0gKyBieXRlc1tpICsgMV0gKiAyNTYpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gc2xpY2UgKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gfn5zdGFydFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IH5+ZW5kXG5cbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ICs9IGxlblxuICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gMFxuICB9IGVsc2UgaWYgKHN0YXJ0ID4gbGVuKSB7XG4gICAgc3RhcnQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlblxuICAgIGlmIChlbmQgPCAwKSBlbmQgPSAwXG4gIH0gZWxzZSBpZiAoZW5kID4gbGVuKSB7XG4gICAgZW5kID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgdmFyIG5ld0J1ZlxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBuZXdCdWYgPSB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpXG4gICAgbmV3QnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xpY2VMZW4gPSBlbmQgLSBzdGFydFxuICAgIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZClcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyBpKyspIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXdCdWZcbn1cblxuLypcbiAqIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYnVmZmVyIGlzbid0IHRyeWluZyB0byB3cml0ZSBvdXQgb2YgYm91bmRzLlxuICovXG5mdW5jdGlvbiBjaGVja09mZnNldCAob2Zmc2V0LCBleHQsIGxlbmd0aCkge1xuICBpZiAoKG9mZnNldCAlIDEpICE9PSAwIHx8IG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdvZmZzZXQgaXMgbm90IHVpbnQnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gbGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRSA9IGZ1bmN0aW9uIHJlYWRVSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRSA9IGZ1bmN0aW9uIHJlYWRVSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG4gIH1cblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdXG4gIHZhciBtdWwgPSAxXG4gIHdoaWxlIChieXRlTGVuZ3RoID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiByZWFkVUludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgOCkgfCB0aGlzW29mZnNldCArIDFdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICgodGhpc1tvZmZzZXRdKSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikpICtcbiAgICAgICh0aGlzW29mZnNldCArIDNdICogMHgxMDAwMDAwKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgKCh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gcmVhZEludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludEJFID0gZnVuY3Rpb24gcmVhZEludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoXG4gIHZhciBtdWwgPSAxXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0taV1cbiAgd2hpbGUgKGkgPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1pXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiByZWFkSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICBpZiAoISh0aGlzW29mZnNldF0gJiAweDgwKSkgcmV0dXJuICh0aGlzW29mZnNldF0pXG4gIHJldHVybiAoKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gcmVhZEludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIDFdIHwgKHRoaXNbb2Zmc2V0XSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiByZWFkSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdKSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10gPDwgMjQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbiByZWFkSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDI0KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiByZWFkRmxvYXRMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiByZWFkRmxvYXRCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gcmVhZERvdWJsZUJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgNTIsIDgpXG59XG5cbmZ1bmN0aW9uIGNoZWNrSW50IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZmZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgLSAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgKyAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uIHdyaXRlSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuZnVuY3Rpb24gY2hlY2tJRUVFNzU0IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoXG4gICAgICB0YXJnZXQsXG4gICAgICB0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksXG4gICAgICB0YXJnZXRTdGFydFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gVXNhZ2U6XG4vLyAgICBidWZmZXIuZmlsbChudW1iZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKGJ1ZmZlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoc3RyaW5nWywgb2Zmc2V0WywgZW5kXV1bLCBlbmNvZGluZ10pXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWwsIHN0YXJ0LCBlbmQsIGVuY29kaW5nKSB7XG4gIC8vIEhhbmRsZSBzdHJpbmcgY2FzZXM6XG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh0eXBlb2Ygc3RhcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IHN0YXJ0XG4gICAgICBzdGFydCA9IDBcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZW5kID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmRcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIGlmICh2YWwubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgY29kZSA9IHZhbC5jaGFyQ29kZUF0KDApXG4gICAgICBpZiAoY29kZSA8IDI1Nikge1xuICAgICAgICB2YWwgPSBjb2RlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2VuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMjU1XG4gIH1cblxuICAvLyBJbnZhbGlkIHJhbmdlcyBhcmUgbm90IHNldCB0byBhIGRlZmF1bHQsIHNvIGNhbiByYW5nZSBjaGVjayBlYXJseS5cbiAgaWYgKHN0YXJ0IDwgMCB8fCB0aGlzLmxlbmd0aCA8IHN0YXJ0IHx8IHRoaXMubGVuZ3RoIDwgZW5kKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ091dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHN0YXJ0ID0gc3RhcnQgPj4+IDBcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghdmFsKSB2YWwgPSAwXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdGhpc1tpXSA9IHZhbFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSBCdWZmZXIuaXNCdWZmZXIodmFsKVxuICAgICAgPyB2YWxcbiAgICAgIDogdXRmOFRvQnl0ZXMobmV3IEJ1ZmZlcih2YWwsIGVuY29kaW5nKS50b1N0cmluZygpKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBmb3IgKGkgPSAwOyBpIDwgZW5kIC0gc3RhcnQ7IGkrKykge1xuICAgICAgdGhpc1tpICsgc3RhcnRdID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbnZhciBJTlZBTElEX0JBU0U2NF9SRSA9IC9bXitcXC8wLTlBLVphLXotX10vZ1xuXG5mdW5jdGlvbiBiYXNlNjRjbGVhbiAoc3RyKSB7XG4gIC8vIE5vZGUgc3RyaXBzIG91dCBpbnZhbGlkIGNoYXJhY3RlcnMgbGlrZSBcXG4gYW5kIFxcdCBmcm9tIHRoZSBzdHJpbmcsIGJhc2U2NC1qcyBkb2VzIG5vdFxuICBzdHIgPSBzdHJpbmd0cmltKHN0cikucmVwbGFjZShJTlZBTElEX0JBU0U2NF9SRSwgJycpXG4gIC8vIE5vZGUgY29udmVydHMgc3RyaW5ncyB3aXRoIGxlbmd0aCA8IDIgdG8gJydcbiAgaWYgKHN0ci5sZW5ndGggPCAyKSByZXR1cm4gJydcbiAgLy8gTm9kZSBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgYmFzZTY0IHN0cmluZ3MgKG1pc3NpbmcgdHJhaWxpbmcgPT09KSwgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHdoaWxlIChzdHIubGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHN0ciA9IHN0ciArICc9J1xuICB9XG4gIHJldHVybiBzdHJcbn1cblxuZnVuY3Rpb24gc3RyaW5ndHJpbSAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKClcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJylcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyaW5nLCB1bml0cykge1xuICB1bml0cyA9IHVuaXRzIHx8IEluZmluaXR5XG4gIHZhciBjb2RlUG9pbnRcbiAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gIHZhciBieXRlcyA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGNvZGVQb2ludCA9IHN0cmluZy5jaGFyQ29kZUF0KGkpXG5cbiAgICAvLyBpcyBzdXJyb2dhdGUgY29tcG9uZW50XG4gICAgaWYgKGNvZGVQb2ludCA+IDB4RDdGRiAmJiBjb2RlUG9pbnQgPCAweEUwMDApIHtcbiAgICAgIC8vIGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoIWxlYWRTdXJyb2dhdGUpIHtcbiAgICAgICAgLy8gbm8gbGVhZCB5ZXRcbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZhbGlkIGxlYWRcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIDIgbGVhZHMgaW4gYSByb3dcbiAgICAgIGlmIChjb2RlUG9pbnQgPCAweERDMDApIHtcbiAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gdmFsaWQgc3Vycm9nYXRlIHBhaXJcbiAgICAgIGNvZGVQb2ludCA9IChsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwKSArIDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBpc25hbiAodmFsKSB7XG4gIHJldHVybiB2YWwgIT09IHZhbCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxufVxuIiwiJ3VzZSBzdHJpY3QnXG5cbmV4cG9ydHMudG9CeXRlQXJyYXkgPSB0b0J5dGVBcnJheVxuZXhwb3J0cy5mcm9tQnl0ZUFycmF5ID0gZnJvbUJ5dGVBcnJheVxuXG52YXIgbG9va3VwID0gW11cbnZhciByZXZMb29rdXAgPSBbXVxudmFyIEFyciA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyA/IFVpbnQ4QXJyYXkgOiBBcnJheVxuXG5mdW5jdGlvbiBpbml0ICgpIHtcbiAgdmFyIGNvZGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLydcbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNvZGUubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gICAgcmV2TG9va3VwW2NvZGUuY2hhckNvZGVBdChpKV0gPSBpXG4gIH1cblxuICByZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbiAgcmV2TG9va3VwWydfJy5jaGFyQ29kZUF0KDApXSA9IDYzXG59XG5cbmluaXQoKVxuXG5mdW5jdGlvbiB0b0J5dGVBcnJheSAoYjY0KSB7XG4gIHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyXG4gIHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cbiAgaWYgKGxlbiAlIDQgPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0JylcbiAgfVxuXG4gIC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG4gIC8vIGlmIHRoZXJlIGFyZSB0d28gcGxhY2Vob2xkZXJzLCB0aGFuIHRoZSB0d28gY2hhcmFjdGVycyBiZWZvcmUgaXRcbiAgLy8gcmVwcmVzZW50IG9uZSBieXRlXG4gIC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuICAvLyB0aGlzIGlzIGp1c3QgYSBjaGVhcCBoYWNrIHRvIG5vdCBkbyBpbmRleE9mIHR3aWNlXG4gIHBsYWNlSG9sZGVycyA9IGI2NFtsZW4gLSAyXSA9PT0gJz0nID8gMiA6IGI2NFtsZW4gLSAxXSA9PT0gJz0nID8gMSA6IDBcblxuICAvLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcbiAgYXJyID0gbmV3IEFycihsZW4gKiAzIC8gNCAtIHBsYWNlSG9sZGVycylcblxuICAvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG4gIGwgPSBwbGFjZUhvbGRlcnMgPiAwID8gbGVuIC0gNCA6IGxlblxuXG4gIHZhciBMID0gMFxuXG4gIGZvciAoaSA9IDAsIGogPSAwOyBpIDwgbDsgaSArPSA0LCBqICs9IDMpIHtcbiAgICB0bXAgPSAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxOCkgfCAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHwgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHwgcmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAzKV1cbiAgICBhcnJbTCsrXSA9ICh0bXAgPj4gMTYpICYgMHhGRlxuICAgIGFycltMKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbTCsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnMgPT09IDIpIHtcbiAgICB0bXAgPSAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltMKytdID0gdG1wICYgMHhGRlxuICB9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuICAgIHRtcCA9IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDEwKSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltMKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbTCsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArIGxvb2t1cFtudW0gPj4gNiAmIDB4M0ZdICsgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9ICh1aW50OFtpXSA8PCAxNikgKyAodWludDhbaSArIDFdIDw8IDgpICsgKHVpbnQ4W2kgKyAyXSlcbiAgICBvdXRwdXQucHVzaCh0cmlwbGV0VG9CYXNlNjQodG1wKSlcbiAgfVxuICByZXR1cm4gb3V0cHV0LmpvaW4oJycpXG59XG5cbmZ1bmN0aW9uIGZyb21CeXRlQXJyYXkgKHVpbnQ4KSB7XG4gIHZhciB0bXBcbiAgdmFyIGxlbiA9IHVpbnQ4Lmxlbmd0aFxuICB2YXIgZXh0cmFCeXRlcyA9IGxlbiAlIDMgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcbiAgdmFyIG91dHB1dCA9ICcnXG4gIHZhciBwYXJ0cyA9IFtdXG4gIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzIC8vIG11c3QgYmUgbXVsdGlwbGUgb2YgM1xuXG4gIC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbjIgPSBsZW4gLSBleHRyYUJ5dGVzOyBpIDwgbGVuMjsgaSArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgIHBhcnRzLnB1c2goZW5jb2RlQ2h1bmsodWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKSkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBvdXRwdXQgKz0gbG9va3VwW3RtcCA+PiAyXVxuICAgIG91dHB1dCArPSBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdXG4gICAgb3V0cHV0ICs9ICc9PSdcbiAgfSBlbHNlIGlmIChleHRyYUJ5dGVzID09PSAyKSB7XG4gICAgdG1wID0gKHVpbnQ4W2xlbiAtIDJdIDw8IDgpICsgKHVpbnQ4W2xlbiAtIDFdKVxuICAgIG91dHB1dCArPSBsb29rdXBbdG1wID4+IDEwXVxuICAgIG91dHB1dCArPSBsb29rdXBbKHRtcCA+PiA0KSAmIDB4M0ZdXG4gICAgb3V0cHV0ICs9IGxvb2t1cFsodG1wIDw8IDIpICYgMHgzRl1cbiAgICBvdXRwdXQgKz0gJz0nXG4gIH1cblxuICBwYXJ0cy5wdXNoKG91dHB1dClcblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiIsImV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSBtICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwidmFyIHRvU3RyaW5nID0ge30udG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKGFycikgPT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5yYW5kb21CeXRlcyA9IGV4cG9ydHMucm5nID0gZXhwb3J0cy5wc2V1ZG9SYW5kb21CeXRlcyA9IGV4cG9ydHMucHJuZyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJylcbmV4cG9ydHMuY3JlYXRlSGFzaCA9IGV4cG9ydHMuSGFzaCA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoJylcbmV4cG9ydHMuY3JlYXRlSG1hYyA9IGV4cG9ydHMuSG1hYyA9IHJlcXVpcmUoJ2NyZWF0ZS1obWFjJylcblxudmFyIGhhc2hlcyA9IFsnc2hhMScsICdzaGEyMjQnLCAnc2hhMjU2JywgJ3NoYTM4NCcsICdzaGE1MTInLCAnbWQ1JywgJ3JtZDE2MCddLmNvbmNhdChPYmplY3Qua2V5cyhyZXF1aXJlKCdicm93c2VyaWZ5LXNpZ24vYWxnb3MnKSkpXG5leHBvcnRzLmdldEhhc2hlcyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIGhhc2hlc1xufVxuXG52YXIgcCA9IHJlcXVpcmUoJ3Bia2RmMicpXG5leHBvcnRzLnBia2RmMiA9IHAucGJrZGYyXG5leHBvcnRzLnBia2RmMlN5bmMgPSBwLnBia2RmMlN5bmNcblxudmFyIGFlcyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktY2lwaGVyJylcbjtbXG4gICdDaXBoZXInLFxuICAnY3JlYXRlQ2lwaGVyJyxcbiAgJ0NpcGhlcml2JyxcbiAgJ2NyZWF0ZUNpcGhlcml2JyxcbiAgJ0RlY2lwaGVyJyxcbiAgJ2NyZWF0ZURlY2lwaGVyJyxcbiAgJ0RlY2lwaGVyaXYnLFxuICAnY3JlYXRlRGVjaXBoZXJpdicsXG4gICdnZXRDaXBoZXJzJyxcbiAgJ2xpc3RDaXBoZXJzJ1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgZXhwb3J0c1trZXldID0gYWVzW2tleV1cbn0pXG5cbnZhciBkaCA9IHJlcXVpcmUoJ2RpZmZpZS1oZWxsbWFuJylcbjtbXG4gICdEaWZmaWVIZWxsbWFuR3JvdXAnLFxuICAnY3JlYXRlRGlmZmllSGVsbG1hbkdyb3VwJyxcbiAgJ2dldERpZmZpZUhlbGxtYW4nLFxuICAnY3JlYXRlRGlmZmllSGVsbG1hbicsXG4gICdEaWZmaWVIZWxsbWFuJ1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgZXhwb3J0c1trZXldID0gZGhba2V5XVxufSlcblxudmFyIHNpZ24gPSByZXF1aXJlKCdicm93c2VyaWZ5LXNpZ24nKVxuO1tcbiAgJ2NyZWF0ZVNpZ24nLFxuICAnU2lnbicsXG4gICdjcmVhdGVWZXJpZnknLFxuICAnVmVyaWZ5J1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgZXhwb3J0c1trZXldID0gc2lnbltrZXldXG59KVxuXG5leHBvcnRzLmNyZWF0ZUVDREggPSByZXF1aXJlKCdjcmVhdGUtZWNkaCcpXG5cbnZhciBwdWJsaWNFbmNyeXB0ID0gcmVxdWlyZSgncHVibGljLWVuY3J5cHQnKVxuXG47W1xuICAncHVibGljRW5jcnlwdCcsXG4gICdwcml2YXRlRW5jcnlwdCcsXG4gICdwdWJsaWNEZWNyeXB0JyxcbiAgJ3ByaXZhdGVEZWNyeXB0J1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgZXhwb3J0c1trZXldID0gcHVibGljRW5jcnlwdFtrZXldXG59KVxuXG4vLyB0aGUgbGVhc3QgSSBjYW4gZG8gaXMgbWFrZSBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIHJlc3Qgb2YgdGhlIG5vZGUuanMvY3J5cHRvIGFwaS5cbjtbXG4gICdjcmVhdGVDcmVkZW50aWFscydcbl0uZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICBleHBvcnRzW25hbWVdID0gZnVuY3Rpb24gKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihbXG4gICAgICAnc29ycnksICcgKyBuYW1lICsgJyBpcyBub3QgaW1wbGVtZW50ZWQgeWV0JyxcbiAgICAgICd3ZSBhY2NlcHQgcHVsbCByZXF1ZXN0cycsXG4gICAgICAnaHR0cHM6Ly9naXRodWIuY29tL2NyeXB0by1icm93c2VyaWZ5L2NyeXB0by1icm93c2VyaWZ5J1xuICAgIF0uam9pbignXFxuJykpXG4gIH1cbn0pXG4iLCJ2YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcbnZhciBhZXMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWFlcy9icm93c2VyJylcbnZhciBERVMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWRlcycpXG52YXIgZGVzTW9kZXMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWRlcy9tb2RlcycpXG52YXIgYWVzTW9kZXMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWFlcy9tb2RlcycpXG5mdW5jdGlvbiBjcmVhdGVDaXBoZXIgKHN1aXRlLCBwYXNzd29yZCkge1xuICB2YXIga2V5TGVuLCBpdkxlblxuICBzdWl0ZSA9IHN1aXRlLnRvTG93ZXJDYXNlKClcbiAgaWYgKGFlc01vZGVzW3N1aXRlXSkge1xuICAgIGtleUxlbiA9IGFlc01vZGVzW3N1aXRlXS5rZXlcbiAgICBpdkxlbiA9IGFlc01vZGVzW3N1aXRlXS5pdlxuICB9IGVsc2UgaWYgKGRlc01vZGVzW3N1aXRlXSkge1xuICAgIGtleUxlbiA9IGRlc01vZGVzW3N1aXRlXS5rZXkgKiA4XG4gICAgaXZMZW4gPSBkZXNNb2Rlc1tzdWl0ZV0uaXZcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIHZhciBrZXlzID0gZWJ0ayhwYXNzd29yZCwgZmFsc2UsIGtleUxlbiwgaXZMZW4pXG4gIHJldHVybiBjcmVhdGVDaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlciAoc3VpdGUsIHBhc3N3b3JkKSB7XG4gIHZhciBrZXlMZW4sIGl2TGVuXG4gIHN1aXRlID0gc3VpdGUudG9Mb3dlckNhc2UoKVxuICBpZiAoYWVzTW9kZXNbc3VpdGVdKSB7XG4gICAga2V5TGVuID0gYWVzTW9kZXNbc3VpdGVdLmtleVxuICAgIGl2TGVuID0gYWVzTW9kZXNbc3VpdGVdLml2XG4gIH0gZWxzZSBpZiAoZGVzTW9kZXNbc3VpdGVdKSB7XG4gICAga2V5TGVuID0gZGVzTW9kZXNbc3VpdGVdLmtleSAqIDhcbiAgICBpdkxlbiA9IGRlc01vZGVzW3N1aXRlXS5pdlxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwga2V5TGVuLCBpdkxlbilcbiAgcmV0dXJuIGNyZWF0ZURlY2lwaGVyaXYoc3VpdGUsIGtleXMua2V5LCBrZXlzLml2KVxufVxuXG5mdW5jdGlvbiBjcmVhdGVDaXBoZXJpdiAoc3VpdGUsIGtleSwgaXYpIHtcbiAgc3VpdGUgPSBzdWl0ZS50b0xvd2VyQ2FzZSgpXG4gIGlmIChhZXNNb2Rlc1tzdWl0ZV0pIHtcbiAgICByZXR1cm4gYWVzLmNyZWF0ZUNpcGhlcml2KHN1aXRlLCBrZXksIGl2KVxuICB9IGVsc2UgaWYgKGRlc01vZGVzW3N1aXRlXSkge1xuICAgIHJldHVybiBuZXcgREVTKHtcbiAgICAgIGtleToga2V5LFxuICAgICAgaXY6IGl2LFxuICAgICAgbW9kZTogc3VpdGVcbiAgICB9KVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZURlY2lwaGVyaXYgKHN1aXRlLCBrZXksIGl2KSB7XG4gIHN1aXRlID0gc3VpdGUudG9Mb3dlckNhc2UoKVxuICBpZiAoYWVzTW9kZXNbc3VpdGVdKSB7XG4gICAgcmV0dXJuIGFlcy5jcmVhdGVEZWNpcGhlcml2KHN1aXRlLCBrZXksIGl2KVxuICB9IGVsc2UgaWYgKGRlc01vZGVzW3N1aXRlXSkge1xuICAgIHJldHVybiBuZXcgREVTKHtcbiAgICAgIGtleToga2V5LFxuICAgICAgaXY6IGl2LFxuICAgICAgbW9kZTogc3VpdGUsXG4gICAgICBkZWNyeXB0OiB0cnVlXG4gICAgfSlcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG59XG5leHBvcnRzLmNyZWF0ZUNpcGhlciA9IGV4cG9ydHMuQ2lwaGVyID0gY3JlYXRlQ2lwaGVyXG5leHBvcnRzLmNyZWF0ZUNpcGhlcml2ID0gZXhwb3J0cy5DaXBoZXJpdiA9IGNyZWF0ZUNpcGhlcml2XG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyID0gZXhwb3J0cy5EZWNpcGhlciA9IGNyZWF0ZURlY2lwaGVyXG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyaXYgPSBleHBvcnRzLkRlY2lwaGVyaXYgPSBjcmVhdGVEZWNpcGhlcml2XG5mdW5jdGlvbiBnZXRDaXBoZXJzICgpIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKGRlc01vZGVzKS5jb25jYXQoYWVzLmdldENpcGhlcnMoKSlcbn1cbmV4cG9ydHMubGlzdENpcGhlcnMgPSBleHBvcnRzLmdldENpcGhlcnMgPSBnZXRDaXBoZXJzXG4iLCIvLyBiYXNlZCBvbiB0aGUgYWVzIGltcGxpbWVudGF0aW9uIGluIHRyaXBsZSBzZWNcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9rZXliYXNlL3RyaXBsZXNlY1xuXG4vLyB3aGljaCBpcyBpbiB0dXJuIGJhc2VkIG9uIHRoZSBvbmUgZnJvbSBjcnlwdG8tanNcbi8vIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL1xuXG52YXIgdWludF9tYXggPSBNYXRoLnBvdygyLCAzMilcbmZ1bmN0aW9uIGZpeHVwX3VpbnQzMiAoeCkge1xuICB2YXIgcmV0LCB4X3Bvc1xuICByZXQgPSB4ID4gdWludF9tYXggfHwgeCA8IDAgPyAoeF9wb3MgPSBNYXRoLmFicyh4KSAlIHVpbnRfbWF4LCB4IDwgMCA/IHVpbnRfbWF4IC0geF9wb3MgOiB4X3BvcykgOiB4XG4gIHJldHVybiByZXRcbn1cbmZ1bmN0aW9uIHNjcnViX3ZlYyAodikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHYubGVuZ3RoOyB2KyspIHtcbiAgICB2W2ldID0gMFxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG5mdW5jdGlvbiBHbG9iYWwgKCkge1xuICB0aGlzLlNCT1ggPSBbXVxuICB0aGlzLklOVl9TQk9YID0gW11cbiAgdGhpcy5TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLklOVl9TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLmluaXQoKVxuICB0aGlzLlJDT04gPSBbMHgwMCwgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxYiwgMHgzNl1cbn1cblxuR2xvYmFsLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZCwgaSwgc3gsIHQsIHgsIHgyLCB4NCwgeDgsIHhpLCBfaVxuICBkID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgX2ksIF9yZXN1bHRzXG4gICAgX3Jlc3VsdHMgPSBbXVxuICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgICBpZiAoaSA8IDEyOCkge1xuICAgICAgICBfcmVzdWx0cy5wdXNoKGkgPDwgMSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9yZXN1bHRzLnB1c2goKGkgPDwgMSkgXiAweDExYilcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIF9yZXN1bHRzXG4gIH0pKClcbiAgeCA9IDBcbiAgeGkgPSAwXG4gIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgc3ggPSB4aSBeICh4aSA8PCAxKSBeICh4aSA8PCAyKSBeICh4aSA8PCAzKSBeICh4aSA8PCA0KVxuICAgIHN4ID0gKHN4ID4+PiA4KSBeIChzeCAmIDB4ZmYpIF4gMHg2M1xuICAgIHRoaXMuU0JPWFt4XSA9IHN4XG4gICAgdGhpcy5JTlZfU0JPWFtzeF0gPSB4XG4gICAgeDIgPSBkW3hdXG4gICAgeDQgPSBkW3gyXVxuICAgIHg4ID0gZFt4NF1cbiAgICB0ID0gKGRbc3hdICogMHgxMDEpIF4gKHN4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuU1VCX01JWFswXVt4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KVxuICAgIHRoaXMuU1VCX01JWFsxXVt4XSA9ICh0IDw8IDE2KSB8ICh0ID4+PiAxNilcbiAgICB0aGlzLlNVQl9NSVhbMl1beF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLlNVQl9NSVhbM11beF0gPSB0XG4gICAgdCA9ICh4OCAqIDB4MTAxMDEwMSkgXiAoeDQgKiAweDEwMDAxKSBeICh4MiAqIDB4MTAxKSBeICh4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMF1bc3hdID0gKHQgPDwgMjQpIHwgKHQgPj4+IDgpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsxXVtzeF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsyXVtzeF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLklOVl9TVUJfTUlYWzNdW3N4XSA9IHRcbiAgICBpZiAoeCA9PT0gMCkge1xuICAgICAgeCA9IHhpID0gMVxuICAgIH0gZWxzZSB7XG4gICAgICB4ID0geDIgXiBkW2RbZFt4OCBeIHgyXV1dXG4gICAgICB4aSBePSBkW2RbeGldXVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG52YXIgRyA9IG5ldyBHbG9iYWwoKVxuXG5BRVMuYmxvY2tTaXplID0gNCAqIDRcblxuQUVTLnByb3RvdHlwZS5ibG9ja1NpemUgPSBBRVMuYmxvY2tTaXplXG5cbkFFUy5rZXlTaXplID0gMjU2IC8gOFxuXG5BRVMucHJvdG90eXBlLmtleVNpemUgPSBBRVMua2V5U2l6ZVxuXG5mdW5jdGlvbiBidWZmZXJUb0FycmF5IChidWYpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGggLyA0XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkobGVuKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWYucmVhZFVJbnQzMkJFKGkgKiA0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIEFFUyAoa2V5KSB7XG4gIHRoaXMuX2tleSA9IGJ1ZmZlclRvQXJyYXkoa2V5KVxuICB0aGlzLl9kb1Jlc2V0KClcbn1cblxuQUVTLnByb3RvdHlwZS5fZG9SZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGludktzUm93LCBrZXlTaXplLCBrZXlXb3Jkcywga3NSb3csIGtzUm93cywgdFxuICBrZXlXb3JkcyA9IHRoaXMuX2tleVxuICBrZXlTaXplID0ga2V5V29yZHMubGVuZ3RoXG4gIHRoaXMuX25Sb3VuZHMgPSBrZXlTaXplICsgNlxuICBrc1Jvd3MgPSAodGhpcy5fblJvdW5kcyArIDEpICogNFxuICB0aGlzLl9rZXlTY2hlZHVsZSA9IFtdXG4gIGZvciAoa3NSb3cgPSAwOyBrc1JvdyA8IGtzUm93czsga3NSb3crKykge1xuICAgIHRoaXMuX2tleVNjaGVkdWxlW2tzUm93XSA9IGtzUm93IDwga2V5U2l6ZSA/IGtleVdvcmRzW2tzUm93XSA6ICh0ID0gdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSAxXSwgKGtzUm93ICUga2V5U2l6ZSkgPT09IDAgPyAodCA9ICh0IDw8IDgpIHwgKHQgPj4+IDI0KSwgdCA9IChHLlNCT1hbdCA+Pj4gMjRdIDw8IDI0KSB8IChHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChHLlNCT1hbKHQgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBHLlNCT1hbdCAmIDB4ZmZdLCB0IF49IEcuUkNPTlsoa3NSb3cgLyBrZXlTaXplKSB8IDBdIDw8IDI0KSA6IGtleVNpemUgPiA2ICYmIGtzUm93ICUga2V5U2l6ZSA9PT0gNCA/IHQgPSAoRy5TQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgRy5TQk9YW3QgJiAweGZmXSA6IHZvaWQgMCwgdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSBrZXlTaXplXSBeIHQpXG4gIH1cbiAgdGhpcy5faW52S2V5U2NoZWR1bGUgPSBbXVxuICBmb3IgKGludktzUm93ID0gMDsgaW52S3NSb3cgPCBrc1Jvd3M7IGludktzUm93KyspIHtcbiAgICBrc1JvdyA9IGtzUm93cyAtIGludktzUm93XG4gICAgdCA9IHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0gKGludktzUm93ICUgNCA/IDAgOiA0KV1cbiAgICB0aGlzLl9pbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSBpbnZLc1JvdyA8IDQgfHwga3NSb3cgPD0gNCA/IHQgOiBHLklOVl9TVUJfTUlYWzBdW0cuU0JPWFt0ID4+PiAyNF1dIF4gRy5JTlZfU1VCX01JWFsxXVtHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbMl1bRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbM11bRy5TQk9YW3QgJiAweGZmXV1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5BRVMucHJvdG90eXBlLmVuY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5fa2V5U2NoZWR1bGUsIEcuU1VCX01JWCwgRy5TQk9YKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxuXG5BRVMucHJvdG90eXBlLmRlY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciB0ZW1wID0gW01bM10sIE1bMV1dXG4gIE1bMV0gPSB0ZW1wWzBdXG4gIE1bM10gPSB0ZW1wWzFdXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5faW52S2V5U2NoZWR1bGUsIEcuSU5WX1NVQl9NSVgsIEcuSU5WX1NCT1gpXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKDE2KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMF0sIDApXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgNClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzJdLCA4KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDEyKVxuICByZXR1cm4gYnVmXG59XG5cbkFFUy5wcm90b3R5cGUuc2NydWIgPSBmdW5jdGlvbiAoKSB7XG4gIHNjcnViX3ZlYyh0aGlzLl9rZXlTY2hlZHVsZSlcbiAgc2NydWJfdmVjKHRoaXMuX2ludktleVNjaGVkdWxlKVxuICBzY3J1Yl92ZWModGhpcy5fa2V5KVxufVxuXG5BRVMucHJvdG90eXBlLl9kb0NyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSwga2V5U2NoZWR1bGUsIFNVQl9NSVgsIFNCT1gpIHtcbiAgdmFyIGtzUm93LCBzMCwgczEsIHMyLCBzMywgdDAsIHQxLCB0MiwgdDNcblxuICBzMCA9IE1bMF0gXiBrZXlTY2hlZHVsZVswXVxuICBzMSA9IE1bMV0gXiBrZXlTY2hlZHVsZVsxXVxuICBzMiA9IE1bMl0gXiBrZXlTY2hlZHVsZVsyXVxuICBzMyA9IE1bM10gXiBrZXlTY2hlZHVsZVszXVxuICBrc1JvdyA9IDRcbiAgZm9yICh2YXIgcm91bmQgPSAxOyByb3VuZCA8IHRoaXMuX25Sb3VuZHM7IHJvdW5kKyspIHtcbiAgICB0MCA9IFNVQl9NSVhbMF1bczAgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMxID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMyID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMyAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MSA9IFNVQl9NSVhbMF1bczEgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMyID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMzID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMCAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MiA9IFNVQl9NSVhbMF1bczIgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMzID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMwID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMSAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MyA9IFNVQl9NSVhbMF1bczMgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMwID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMxID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMiAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICBzMCA9IHQwXG4gICAgczEgPSB0MVxuICAgIHMyID0gdDJcbiAgICBzMyA9IHQzXG4gIH1cbiAgdDAgPSAoKFNCT1hbczAgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczEgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMiA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczMgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MSA9ICgoU0JPWFtzMSA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMiA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMzID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMCAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gIHQyID0gKChTQk9YW3MyID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMzID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczAgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDMgPSAoKFNCT1hbczMgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczAgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMSA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczIgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICByZXR1cm4gW1xuICAgIGZpeHVwX3VpbnQzMih0MCksXG4gICAgZml4dXBfdWludDMyKHQxKSxcbiAgICBmaXh1cF91aW50MzIodDIpLFxuICAgIGZpeHVwX3VpbnQzMih0MylcbiAgXVxufVxuXG5leHBvcnRzLkFFUyA9IEFFU1xuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgR0hBU0ggPSByZXF1aXJlKCcuL2doYXNoJylcbnZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcblxuZnVuY3Rpb24gU3RyZWFtQ2lwaGVyIChtb2RlLCBrZXksIGl2LCBkZWNyeXB0KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTdHJlYW1DaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZSwga2V5LCBpdilcbiAgfVxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLl9maW5JRCA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAxXSldKVxuICBpdiA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAyXSldKVxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgdGhpcy5fY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9zZWNDYWNoZSA9IG5ldyBCdWZmZXIoJycpXG4gIHRoaXMuX2RlY3J5cHQgPSBkZWNyeXB0XG4gIHRoaXMuX2FsZW4gPSAwXG4gIHRoaXMuX2xlbiA9IDBcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB2YXIgaCA9IG5ldyBCdWZmZXIoNClcbiAgaC5maWxsKDApXG4gIHRoaXMuX2doYXNoID0gbmV3IEdIQVNIKHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2soaCkpXG4gIHRoaXMuX2F1dGhUYWcgPSBudWxsXG4gIHRoaXMuX2NhbGxlZCA9IGZhbHNlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgaWYgKCF0aGlzLl9jYWxsZWQgJiYgdGhpcy5fYWxlbikge1xuICAgIHZhciBydW1wID0gMTYgLSAodGhpcy5fYWxlbiAlIDE2KVxuICAgIGlmIChydW1wIDwgMTYpIHtcbiAgICAgIHJ1bXAgPSBuZXcgQnVmZmVyKHJ1bXApXG4gICAgICBydW1wLmZpbGwoMClcbiAgICAgIHRoaXMuX2doYXNoLnVwZGF0ZShydW1wKVxuICAgIH1cbiAgfVxuICB0aGlzLl9jYWxsZWQgPSB0cnVlXG4gIHZhciBvdXQgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gIGlmICh0aGlzLl9kZWNyeXB0KSB7XG4gICAgdGhpcy5fZ2hhc2gudXBkYXRlKGNodW5rKVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShvdXQpXG4gIH1cbiAgdGhpcy5fbGVuICs9IGNodW5rLmxlbmd0aFxuICByZXR1cm4gb3V0XG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuX2RlY3J5cHQgJiYgIXRoaXMuX2F1dGhUYWcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YScpXG4gIH1cbiAgdmFyIHRhZyA9IHhvcih0aGlzLl9naGFzaC5maW5hbCh0aGlzLl9hbGVuICogOCwgdGhpcy5fbGVuICogOCksIHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2sodGhpcy5fZmluSUQpKVxuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIGlmICh4b3JUZXN0KHRhZywgdGhpcy5fYXV0aFRhZykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgc3RhdGUgb3IgdW5hYmxlIHRvIGF1dGhlbnRpY2F0ZSBkYXRhJylcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fYXV0aFRhZyA9IHRhZ1xuICB9XG4gIHRoaXMuX2NpcGhlci5zY3J1YigpXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiBnZXRBdXRoVGFnICgpIHtcbiAgaWYgKCF0aGlzLl9kZWNyeXB0ICYmIEJ1ZmZlci5pc0J1ZmZlcih0aGlzLl9hdXRoVGFnKSkge1xuICAgIHJldHVybiB0aGlzLl9hdXRoVGFnXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG4gIH1cbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuc2V0QXV0aFRhZyA9IGZ1bmN0aW9uIHNldEF1dGhUYWcgKHRhZykge1xuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIHRoaXMuX2F1dGhUYWcgPSB0YWdcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0F0dGVtcHRpbmcgdG8gc2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbiAgfVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiBzZXRBQUQgKGJ1Zikge1xuICBpZiAoIXRoaXMuX2NhbGxlZCkge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShidWYpXG4gICAgdGhpcy5fYWxlbiArPSBidWYubGVuZ3RoXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIHNldCBBQUQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxuICB9XG59XG5mdW5jdGlvbiB4b3JUZXN0IChhLCBiKSB7XG4gIHZhciBvdXQgPSAwXG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICBvdXQrK1xuICB9XG4gIHZhciBsZW4gPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dCArPSAoYVtpXSBeIGJbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGNpcGhlcnMgPSByZXF1aXJlKCcuL2VuY3J5cHRlcicpXG5leHBvcnRzLmNyZWF0ZUNpcGhlciA9IGV4cG9ydHMuQ2lwaGVyID0gY2lwaGVycy5jcmVhdGVDaXBoZXJcbmV4cG9ydHMuY3JlYXRlQ2lwaGVyaXYgPSBleHBvcnRzLkNpcGhlcml2ID0gY2lwaGVycy5jcmVhdGVDaXBoZXJpdlxudmFyIGRlY2lwaGVycyA9IHJlcXVpcmUoJy4vZGVjcnlwdGVyJylcbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXIgPSBleHBvcnRzLkRlY2lwaGVyID0gZGVjaXBoZXJzLmNyZWF0ZURlY2lwaGVyXG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyaXYgPSBleHBvcnRzLkRlY2lwaGVyaXYgPSBkZWNpcGhlcnMuY3JlYXRlRGVjaXBoZXJpdlxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9tb2RlcycpXG5mdW5jdGlvbiBnZXRDaXBoZXJzICgpIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKG1vZGVzKVxufVxuZXhwb3J0cy5saXN0Q2lwaGVycyA9IGV4cG9ydHMuZ2V0Q2lwaGVycyA9IGdldENpcGhlcnNcbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9tb2RlcycpXG52YXIgU3RyZWFtQ2lwaGVyID0gcmVxdWlyZSgnLi9zdHJlYW1DaXBoZXInKVxudmFyIEF1dGhDaXBoZXIgPSByZXF1aXJlKCcuL2F1dGhDaXBoZXInKVxudmFyIGVidGsgPSByZXF1aXJlKCdldnBfYnl0ZXN0b2tleScpXG5cbmluaGVyaXRzKERlY2lwaGVyLCBUcmFuc2Zvcm0pXG5mdW5jdGlvbiBEZWNpcGhlciAobW9kZSwga2V5LCBpdikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgRGVjaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBEZWNpcGhlcihtb2RlLCBrZXksIGl2KVxuICB9XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuX2NhY2hlID0gbmV3IFNwbGl0dGVyKClcbiAgdGhpcy5fbGFzdCA9IHZvaWQgMFxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB0aGlzLl9hdXRvcGFkZGluZyA9IHRydWVcbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5fY2FjaGUuYWRkKGRhdGEpXG4gIHZhciBjaHVua1xuICB2YXIgdGhpbmdcbiAgdmFyIG91dCA9IFtdXG4gIHdoaWxlICgoY2h1bmsgPSB0aGlzLl9jYWNoZS5nZXQodGhpcy5fYXV0b3BhZGRpbmcpKSkge1xuICAgIHRoaW5nID0gdGhpcy5fbW9kZS5kZWNyeXB0KHRoaXMsIGNodW5rKVxuICAgIG91dC5wdXNoKHRoaW5nKVxuICB9XG4gIHJldHVybiBCdWZmZXIuY29uY2F0KG91dClcbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBjaHVuayA9IHRoaXMuX2NhY2hlLmZsdXNoKClcbiAgaWYgKHRoaXMuX2F1dG9wYWRkaW5nKSB7XG4gICAgcmV0dXJuIHVucGFkKHRoaXMuX21vZGUuZGVjcnlwdCh0aGlzLCBjaHVuaykpXG4gIH0gZWxzZSBpZiAoY2h1bmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGEgbm90IG11bHRpcGxlIG9mIGJsb2NrIGxlbmd0aCcpXG4gIH1cbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uIChzZXRUbykge1xuICB0aGlzLl9hdXRvcGFkZGluZyA9ICEhc2V0VG9cbiAgcmV0dXJuIHRoaXNcbn1cbmZ1bmN0aW9uIFNwbGl0dGVyICgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNwbGl0dGVyKSkge1xuICAgIHJldHVybiBuZXcgU3BsaXR0ZXIoKVxuICB9XG4gIHRoaXMuY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuY2FjaGUgPSBCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCBkYXRhXSlcbn1cblxuU3BsaXR0ZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChhdXRvUGFkZGluZykge1xuICB2YXIgb3V0XG4gIGlmIChhdXRvUGFkZGluZykge1xuICAgIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+IDE2KSB7XG4gICAgICBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgICByZXR1cm4gb3V0XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+PSAxNikge1xuICAgICAgb3V0ID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgICAgcmV0dXJuIG91dFxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbFxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZVxuICB9XG59XG5mdW5jdGlvbiB1bnBhZCAobGFzdCkge1xuICB2YXIgcGFkZGVkID0gbGFzdFsxNV1cbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgcGFkZGVkKSB7XG4gICAgaWYgKGxhc3RbKGkgKyAoMTYgLSBwYWRkZWQpKV0gIT09IHBhZGRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmFibGUgdG8gZGVjcnlwdCBkYXRhJylcbiAgICB9XG4gIH1cbiAgaWYgKHBhZGRlZCA9PT0gMTYpIHtcbiAgICByZXR1cm5cbiAgfVxuICByZXR1cm4gbGFzdC5zbGljZSgwLCAxNiAtIHBhZGRlZClcbn1cblxudmFyIG1vZGVsaXN0ID0ge1xuICBFQ0I6IHJlcXVpcmUoJy4vbW9kZXMvZWNiJyksXG4gIENCQzogcmVxdWlyZSgnLi9tb2Rlcy9jYmMnKSxcbiAgQ0ZCOiByZXF1aXJlKCcuL21vZGVzL2NmYicpLFxuICBDRkI4OiByZXF1aXJlKCcuL21vZGVzL2NmYjgnKSxcbiAgQ0ZCMTogcmVxdWlyZSgnLi9tb2Rlcy9jZmIxJyksXG4gIE9GQjogcmVxdWlyZSgnLi9tb2Rlcy9vZmInKSxcbiAgQ1RSOiByZXF1aXJlKCcuL21vZGVzL2N0cicpLFxuICBHQ006IHJlcXVpcmUoJy4vbW9kZXMvY3RyJylcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVjaXBoZXJpdiAoc3VpdGUsIHBhc3N3b3JkLCBpdikge1xuICB2YXIgY29uZmlnID0gbW9kZXNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIGlmICh0eXBlb2YgaXYgPT09ICdzdHJpbmcnKSB7XG4gICAgaXYgPSBuZXcgQnVmZmVyKGl2KVxuICB9XG4gIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICdzdHJpbmcnKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkKVxuICB9XG4gIGlmIChwYXNzd29yZC5sZW5ndGggIT09IGNvbmZpZy5rZXkgLyA4KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBrZXkgbGVuZ3RoICcgKyBwYXNzd29yZC5sZW5ndGgpXG4gIH1cbiAgaWYgKGl2Lmxlbmd0aCAhPT0gY29uZmlnLml2KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBpdiBsZW5ndGggJyArIGl2Lmxlbmd0aClcbiAgfVxuICBpZiAoY29uZmlnLnR5cGUgPT09ICdzdHJlYW0nKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYsIHRydWUpXG4gIH0gZWxzZSBpZiAoY29uZmlnLnR5cGUgPT09ICdhdXRoJykge1xuICAgIHJldHVybiBuZXcgQXV0aENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdiwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gbmV3IERlY2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlciAoc3VpdGUsIHBhc3N3b3JkKSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwgY29uZmlnLmtleSwgY29uZmlnLml2KVxuICByZXR1cm4gY3JlYXRlRGVjaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyID0gY3JlYXRlRGVjaXBoZXJcbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXJpdiA9IGNyZWF0ZURlY2lwaGVyaXZcbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9tb2RlcycpXG52YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcbnZhciBTdHJlYW1DaXBoZXIgPSByZXF1aXJlKCcuL3N0cmVhbUNpcGhlcicpXG52YXIgQXV0aENpcGhlciA9IHJlcXVpcmUoJy4vYXV0aENpcGhlcicpXG5pbmhlcml0cyhDaXBoZXIsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIENpcGhlciAobW9kZSwga2V5LCBpdikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2FjaGUgPSBuZXcgU3BsaXR0ZXIoKVxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB0aGlzLl9hdXRvcGFkZGluZyA9IHRydWVcbn1cbkNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2NhY2hlLmFkZChkYXRhKVxuICB2YXIgY2h1bmtcbiAgdmFyIHRoaW5nXG4gIHZhciBvdXQgPSBbXVxuICB3aGlsZSAoKGNodW5rID0gdGhpcy5fY2FjaGUuZ2V0KCkpKSB7XG4gICAgdGhpbmcgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gICAgb3V0LnB1c2godGhpbmcpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQob3V0KVxufVxuQ2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBjaHVuayA9IHRoaXMuX2NhY2hlLmZsdXNoKClcbiAgaWYgKHRoaXMuX2F1dG9wYWRkaW5nKSB7XG4gICAgY2h1bmsgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gICAgdGhpcy5fY2lwaGVyLnNjcnViKClcbiAgICByZXR1cm4gY2h1bmtcbiAgfSBlbHNlIGlmIChjaHVuay50b1N0cmluZygnaGV4JykgIT09ICcxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMCcpIHtcbiAgICB0aGlzLl9jaXBoZXIuc2NydWIoKVxuICAgIHRocm93IG5ldyBFcnJvcignZGF0YSBub3QgbXVsdGlwbGUgb2YgYmxvY2sgbGVuZ3RoJylcbiAgfVxufVxuQ2lwaGVyLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uIChzZXRUbykge1xuICB0aGlzLl9hdXRvcGFkZGluZyA9ICEhc2V0VG9cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gU3BsaXR0ZXIgKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3BsaXR0ZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTcGxpdHRlcigpXG4gIH1cbiAgdGhpcy5jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG59XG5TcGxpdHRlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGRhdGFdKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGggPiAxNSkge1xuICAgIHZhciBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgIHJldHVybiBvdXRcbiAgfVxuICByZXR1cm4gbnVsbFxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbGVuID0gMTYgLSB0aGlzLmNhY2hlLmxlbmd0aFxuICB2YXIgcGFkQnVmZiA9IG5ldyBCdWZmZXIobGVuKVxuXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIHBhZEJ1ZmYud3JpdGVVSW50OChsZW4sIGkpXG4gIH1cbiAgdmFyIG91dCA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIHBhZEJ1ZmZdKVxuICByZXR1cm4gb3V0XG59XG52YXIgbW9kZWxpc3QgPSB7XG4gIEVDQjogcmVxdWlyZSgnLi9tb2Rlcy9lY2InKSxcbiAgQ0JDOiByZXF1aXJlKCcuL21vZGVzL2NiYycpLFxuICBDRkI6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiJyksXG4gIENGQjg6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiOCcpLFxuICBDRkIxOiByZXF1aXJlKCcuL21vZGVzL2NmYjEnKSxcbiAgT0ZCOiByZXF1aXJlKCcuL21vZGVzL29mYicpLFxuICBDVFI6IHJlcXVpcmUoJy4vbW9kZXMvY3RyJyksXG4gIEdDTTogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVDaXBoZXJpdiAoc3VpdGUsIHBhc3N3b3JkLCBpdikge1xuICB2YXIgY29uZmlnID0gbW9kZXNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIGlmICh0eXBlb2YgaXYgPT09ICdzdHJpbmcnKSB7XG4gICAgaXYgPSBuZXcgQnVmZmVyKGl2KVxuICB9XG4gIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICdzdHJpbmcnKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkKVxuICB9XG4gIGlmIChwYXNzd29yZC5sZW5ndGggIT09IGNvbmZpZy5rZXkgLyA4KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBrZXkgbGVuZ3RoICcgKyBwYXNzd29yZC5sZW5ndGgpXG4gIH1cbiAgaWYgKGl2Lmxlbmd0aCAhPT0gY29uZmlnLml2KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBpdiBsZW5ndGggJyArIGl2Lmxlbmd0aClcbiAgfVxuICBpZiAoY29uZmlnLnR5cGUgPT09ICdzdHJlYW0nKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYpXG4gIH0gZWxzZSBpZiAoY29uZmlnLnR5cGUgPT09ICdhdXRoJykge1xuICAgIHJldHVybiBuZXcgQXV0aENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbiAgfVxuICByZXR1cm4gbmV3IENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbn1cbmZ1bmN0aW9uIGNyZWF0ZUNpcGhlciAoc3VpdGUsIHBhc3N3b3JkKSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwgY29uZmlnLmtleSwgY29uZmlnLml2KVxuICByZXR1cm4gY3JlYXRlQ2lwaGVyaXYoc3VpdGUsIGtleXMua2V5LCBrZXlzLml2KVxufVxuXG5leHBvcnRzLmNyZWF0ZUNpcGhlcml2ID0gY3JlYXRlQ2lwaGVyaXZcbmV4cG9ydHMuY3JlYXRlQ2lwaGVyID0gY3JlYXRlQ2lwaGVyXG4iLCJ2YXIgemVyb3MgPSBuZXcgQnVmZmVyKDE2KVxuemVyb3MuZmlsbCgwKVxubW9kdWxlLmV4cG9ydHMgPSBHSEFTSFxuZnVuY3Rpb24gR0hBU0ggKGtleSkge1xuICB0aGlzLmggPSBrZXlcbiAgdGhpcy5zdGF0ZSA9IG5ldyBCdWZmZXIoMTYpXG4gIHRoaXMuc3RhdGUuZmlsbCgwKVxuICB0aGlzLmNhY2hlID0gbmV3IEJ1ZmZlcignJylcbn1cbi8vIGZyb20gaHR0cDovL2JpdHdpc2VzaGlmdGxlZnQuZ2l0aHViLmlvL3NqY2wvZG9jL3N5bWJvbHMvc3JjL2NvcmVfZ2NtLmpzLmh0bWxcbi8vIGJ5IEp1aG8gVsOkaMOkLUhlcnR0dWFcbkdIQVNILnByb3RvdHlwZS5naGFzaCA9IGZ1bmN0aW9uIChibG9jaykge1xuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBibG9jay5sZW5ndGgpIHtcbiAgICB0aGlzLnN0YXRlW2ldIF49IGJsb2NrW2ldXG4gIH1cbiAgdGhpcy5fbXVsdGlwbHkoKVxufVxuXG5HSEFTSC5wcm90b3R5cGUuX211bHRpcGx5ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgVmkgPSB0b0FycmF5KHRoaXMuaClcbiAgdmFyIFppID0gWzAsIDAsIDAsIDBdXG4gIHZhciBqLCB4aSwgbHNiX1ZpXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IDEyOCkge1xuICAgIHhpID0gKHRoaXMuc3RhdGVbfn4oaSAvIDgpXSAmICgxIDw8ICg3IC0gaSAlIDgpKSkgIT09IDBcbiAgICBpZiAoeGkpIHtcbiAgICAgIC8vIFpfaSsxID0gWl9pIF4gVl9pXG4gICAgICBaaSA9IHhvcihaaSwgVmkpXG4gICAgfVxuXG4gICAgLy8gU3RvcmUgdGhlIHZhbHVlIG9mIExTQihWX2kpXG4gICAgbHNiX1ZpID0gKFZpWzNdICYgMSkgIT09IDBcblxuICAgIC8vIFZfaSsxID0gVl9pID4+IDFcbiAgICBmb3IgKGogPSAzOyBqID4gMDsgai0tKSB7XG4gICAgICBWaVtqXSA9IChWaVtqXSA+Pj4gMSkgfCAoKFZpW2ogLSAxXSAmIDEpIDw8IDMxKVxuICAgIH1cbiAgICBWaVswXSA9IFZpWzBdID4+PiAxXG5cbiAgICAvLyBJZiBMU0IoVl9pKSBpcyAxLCBWX2krMSA9IChWX2kgPj4gMSkgXiBSXG4gICAgaWYgKGxzYl9WaSkge1xuICAgICAgVmlbMF0gPSBWaVswXSBeICgweGUxIDw8IDI0KVxuICAgIH1cbiAgfVxuICB0aGlzLnN0YXRlID0gZnJvbUFycmF5KFppKVxufVxuR0hBU0gucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChidWYpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGJ1Zl0pXG4gIHZhciBjaHVua1xuICB3aGlsZSAodGhpcy5jYWNoZS5sZW5ndGggPj0gMTYpIHtcbiAgICBjaHVuayA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgdGhpcy5naGFzaChjaHVuaylcbiAgfVxufVxuR0hBU0gucHJvdG90eXBlLmZpbmFsID0gZnVuY3Rpb24gKGFibCwgYmwpIHtcbiAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoKSB7XG4gICAgdGhpcy5naGFzaChCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCB6ZXJvc10sIDE2KSlcbiAgfVxuICB0aGlzLmdoYXNoKGZyb21BcnJheShbXG4gICAgMCwgYWJsLFxuICAgIDAsIGJsXG4gIF0pKVxuICByZXR1cm4gdGhpcy5zdGF0ZVxufVxuXG5mdW5jdGlvbiB0b0FycmF5IChidWYpIHtcbiAgcmV0dXJuIFtcbiAgICBidWYucmVhZFVJbnQzMkJFKDApLFxuICAgIGJ1Zi5yZWFkVUludDMyQkUoNCksXG4gICAgYnVmLnJlYWRVSW50MzJCRSg4KSxcbiAgICBidWYucmVhZFVJbnQzMkJFKDEyKVxuICBdXG59XG5mdW5jdGlvbiBmcm9tQXJyYXkgKG91dCkge1xuICBvdXQgPSBvdXQubWFwKGZpeHVwX3VpbnQzMilcbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoMTYpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFswXSwgMClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCA0KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMl0sIDgpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgMTIpXG4gIHJldHVybiBidWZcbn1cbnZhciB1aW50X21heCA9IE1hdGgucG93KDIsIDMyKVxuZnVuY3Rpb24gZml4dXBfdWludDMyICh4KSB7XG4gIHZhciByZXQsIHhfcG9zXG4gIHJldCA9IHggPiB1aW50X21heCB8fCB4IDwgMCA/ICh4X3BvcyA9IE1hdGguYWJzKHgpICUgdWludF9tYXgsIHggPCAwID8gdWludF9tYXggLSB4X3BvcyA6IHhfcG9zKSA6IHhcbiAgcmV0dXJuIHJldFxufVxuZnVuY3Rpb24geG9yIChhLCBiKSB7XG4gIHJldHVybiBbXG4gICAgYVswXSBeIGJbMF0sXG4gICAgYVsxXSBeIGJbMV0sXG4gICAgYVsyXSBeIGJbMl0sXG4gICAgYVszXSBeIGJbM11cbiAgXVxufVxuIiwiZXhwb3J0c1snYWVzLTEyOC1lY2InXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAwLFxuICBtb2RlOiAnRUNCJyxcbiAgdHlwZTogJ2Jsb2NrJ1xufVxuZXhwb3J0c1snYWVzLTE5Mi1lY2InXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxOTIsXG4gIGl2OiAwLFxuICBtb2RlOiAnRUNCJyxcbiAgdHlwZTogJ2Jsb2NrJ1xufVxuZXhwb3J0c1snYWVzLTI1Ni1lY2InXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAyNTYsXG4gIGl2OiAwLFxuICBtb2RlOiAnRUNCJyxcbiAgdHlwZTogJ2Jsb2NrJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1jYmMnXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NCQycsXG4gIHR5cGU6ICdibG9jaydcbn1cbmV4cG9ydHNbJ2Flcy0xOTItY2JjJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTkyLFxuICBpdjogMTYsXG4gIG1vZGU6ICdDQkMnLFxuICB0eXBlOiAnYmxvY2snXG59XG5leHBvcnRzWydhZXMtMjU2LWNiYyddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDI1NixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0JDJyxcbiAgdHlwZTogJ2Jsb2NrJ1xufVxuZXhwb3J0c1snYWVzMTI4J10gPSBleHBvcnRzWydhZXMtMTI4LWNiYyddXG5leHBvcnRzWydhZXMxOTInXSA9IGV4cG9ydHNbJ2Flcy0xOTItY2JjJ11cbmV4cG9ydHNbJ2FlczI1NiddID0gZXhwb3J0c1snYWVzLTI1Ni1jYmMnXVxuZXhwb3J0c1snYWVzLTEyOC1jZmInXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NGQicsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMTkyLWNmYiddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDE5MixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0ZCJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0yNTYtY2ZiJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMjU2LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDRkInLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1jZmI4J10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTI4LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDRkI4JyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0xOTItY2ZiOCddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDE5MixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0ZCOCcsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMjU2LWNmYjgnXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAyNTYsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NGQjgnLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1jZmIxJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTI4LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDRkIxJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0xOTItY2ZiMSddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDE5MixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0ZCMScsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMjU2LWNmYjEnXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAyNTYsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NGQjEnLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1vZmInXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAxNixcbiAgbW9kZTogJ09GQicsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMTkyLW9mYiddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDE5MixcbiAgaXY6IDE2LFxuICBtb2RlOiAnT0ZCJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0yNTYtb2ZiJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMjU2LFxuICBpdjogMTYsXG4gIG1vZGU6ICdPRkInLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1jdHInXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NUUicsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMTkyLWN0ciddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDE5MixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ1RSJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0yNTYtY3RyJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMjU2LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDVFInLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1nY20nXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAxMixcbiAgbW9kZTogJ0dDTScsXG4gIHR5cGU6ICdhdXRoJ1xufVxuZXhwb3J0c1snYWVzLTE5Mi1nY20nXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxOTIsXG4gIGl2OiAxMixcbiAgbW9kZTogJ0dDTScsXG4gIHR5cGU6ICdhdXRoJ1xufVxuZXhwb3J0c1snYWVzLTI1Ni1nY20nXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAyNTYsXG4gIGl2OiAxMixcbiAgbW9kZTogJ0dDTScsXG4gIHR5cGU6ICdhdXRoJ1xufVxuIiwidmFyIHhvciA9IHJlcXVpcmUoJ2J1ZmZlci14b3InKVxuXG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgYmxvY2spIHtcbiAgdmFyIGRhdGEgPSB4b3IoYmxvY2ssIHNlbGYuX3ByZXYpXG5cbiAgc2VsZi5fcHJldiA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soZGF0YSlcbiAgcmV0dXJuIHNlbGYuX3ByZXZcbn1cblxuZXhwb3J0cy5kZWNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGJsb2NrKSB7XG4gIHZhciBwYWQgPSBzZWxmLl9wcmV2XG5cbiAgc2VsZi5fcHJldiA9IGJsb2NrXG4gIHZhciBvdXQgPSBzZWxmLl9jaXBoZXIuZGVjcnlwdEJsb2NrKGJsb2NrKVxuXG4gIHJldHVybiB4b3Iob3V0LCBwYWQpXG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBkYXRhLCBkZWNyeXB0KSB7XG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKCcnKVxuICB2YXIgbGVuXG5cbiAgd2hpbGUgKGRhdGEubGVuZ3RoKSB7XG4gICAgaWYgKHNlbGYuX2NhY2hlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgICBzZWxmLl9wcmV2ID0gbmV3IEJ1ZmZlcignJylcbiAgICB9XG5cbiAgICBpZiAoc2VsZi5fY2FjaGUubGVuZ3RoIDw9IGRhdGEubGVuZ3RoKSB7XG4gICAgICBsZW4gPSBzZWxmLl9jYWNoZS5sZW5ndGhcbiAgICAgIG91dCA9IEJ1ZmZlci5jb25jYXQoW291dCwgZW5jcnlwdFN0YXJ0KHNlbGYsIGRhdGEuc2xpY2UoMCwgbGVuKSwgZGVjcnlwdCldKVxuICAgICAgZGF0YSA9IGRhdGEuc2xpY2UobGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFtvdXQsIGVuY3J5cHRTdGFydChzZWxmLCBkYXRhLCBkZWNyeXB0KV0pXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIGVuY3J5cHRTdGFydCAoc2VsZiwgZGF0YSwgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gZGF0YS5sZW5ndGhcbiAgdmFyIG91dCA9IHhvcihkYXRhLCBzZWxmLl9jYWNoZSlcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShsZW4pXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LCBkZWNyeXB0ID8gZGF0YSA6IG91dF0pXG4gIHJldHVybiBvdXRcbn1cbiIsImZ1bmN0aW9uIGVuY3J5cHRCeXRlIChzZWxmLCBieXRlUGFyYW0sIGRlY3J5cHQpIHtcbiAgdmFyIHBhZFxuICB2YXIgaSA9IC0xXG4gIHZhciBsZW4gPSA4XG4gIHZhciBvdXQgPSAwXG4gIHZhciBiaXQsIHZhbHVlXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBwYWQgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgYml0ID0gKGJ5dGVQYXJhbSAmICgxIDw8ICg3IC0gaSkpKSA/IDB4ODAgOiAwXG4gICAgdmFsdWUgPSBwYWRbMF0gXiBiaXRcbiAgICBvdXQgKz0gKCh2YWx1ZSAmIDB4ODApID4+IChpICUgOCkpXG4gICAgc2VsZi5fcHJldiA9IHNoaWZ0SW4oc2VsZi5fcHJldiwgZGVjcnlwdCA/IGJpdCA6IHZhbHVlKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaywgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gY2h1bmsubGVuZ3RoXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGxlbilcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gZW5jcnlwdEJ5dGUoc2VsZiwgY2h1bmtbaV0sIGRlY3J5cHQpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuZnVuY3Rpb24gc2hpZnRJbiAoYnVmZmVyLCB2YWx1ZSkge1xuICB2YXIgbGVuID0gYnVmZmVyLmxlbmd0aFxuICB2YXIgaSA9IC0xXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGJ1ZmZlci5sZW5ndGgpXG4gIGJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW2J1ZmZlciwgbmV3IEJ1ZmZlcihbdmFsdWVdKV0pXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWZmZXJbaV0gPDwgMSB8IGJ1ZmZlcltpICsgMV0gPj4gKDcpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwiZnVuY3Rpb24gZW5jcnlwdEJ5dGUgKHNlbGYsIGJ5dGVQYXJhbSwgZGVjcnlwdCkge1xuICB2YXIgcGFkID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICB2YXIgb3V0ID0gcGFkWzBdIF4gYnl0ZVBhcmFtXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LnNsaWNlKDEpLCBuZXcgQnVmZmVyKFtkZWNyeXB0ID8gYnl0ZVBhcmFtIDogb3V0XSldKVxuICByZXR1cm4gb3V0XG59XG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgY2h1bmssIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGNodW5rLmxlbmd0aFxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihsZW4pXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGVuY3J5cHRCeXRlKHNlbGYsIGNodW5rW2ldLCBkZWNyeXB0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gaW5jcjMyIChpdikge1xuICB2YXIgbGVuID0gaXYubGVuZ3RoXG4gIHZhciBpdGVtXG4gIHdoaWxlIChsZW4tLSkge1xuICAgIGl0ZW0gPSBpdi5yZWFkVUludDgobGVuKVxuICAgIGlmIChpdGVtID09PSAyNTUpIHtcbiAgICAgIGl2LndyaXRlVUludDgoMCwgbGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBpdGVtKytcbiAgICAgIGl2LndyaXRlVUludDgoaXRlbSwgbGVuKVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgdmFyIG91dCA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgaW5jcjMyKHNlbGYuX3ByZXYpXG4gIHJldHVybiBvdXRcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cbiAgdmFyIHBhZCA9IHNlbGYuX2NhY2hlLnNsaWNlKDAsIGNodW5rLmxlbmd0aClcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShjaHVuay5sZW5ndGgpXG4gIHJldHVybiB4b3IoY2h1bmssIHBhZClcbn1cbiIsImV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBibG9jaykge1xuICByZXR1cm4gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhibG9jaylcbn1cbmV4cG9ydHMuZGVjcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBibG9jaykge1xuICByZXR1cm4gc2VsZi5fY2lwaGVyLmRlY3J5cHRCbG9jayhibG9jaylcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgc2VsZi5fcHJldiA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgcmV0dXJuIHNlbGYuX3ByZXZcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cblxuICB2YXIgcGFkID0gc2VsZi5fY2FjaGUuc2xpY2UoMCwgY2h1bmsubGVuZ3RoKVxuICBzZWxmLl9jYWNoZSA9IHNlbGYuX2NhY2hlLnNsaWNlKGNodW5rLmxlbmd0aClcbiAgcmV0dXJuIHhvcihjaHVuaywgcGFkKVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB4b3IgKGEsIGIpIHtcbiAgdmFyIGxlbmd0aCA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aClcbiAgdmFyIGJ1ZmZlciA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBidWZmZXJbaV0gPSBhW2ldIF4gYltpXVxuICB9XG5cbiAgcmV0dXJuIGJ1ZmZlclxufVxuIiwidmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyQmFzZVxuaW5oZXJpdHMoQ2lwaGVyQmFzZSwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyQmFzZSAoaGFzaE1vZGUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5oYXNoTW9kZSA9IHR5cGVvZiBoYXNoTW9kZSA9PT0gJ3N0cmluZydcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICB0aGlzW2hhc2hNb2RlXSA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZpbmFsID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9XG4gIHRoaXMuX2RlY29kZXIgPSBudWxsXG4gIHRoaXMuX2VuY29kaW5nID0gbnVsbFxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGlucHV0RW5jKVxuICB9XG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYylcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uICgpIHt9XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGFhZCBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1c2godGhpcy5fdXBkYXRlKGRhdGEpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBuZXh0KGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGRvbmUpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIGRvbmUoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9maW5hbCgpIHx8IG5ldyBCdWZmZXIoJycpXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jLCB0cnVlKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90b1N0cmluZyA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jLCBmaW5hbCkge1xuICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKVxuICAgIHRoaXMuX2VuY29kaW5nID0gZW5jXG4gIH1cbiAgaWYgKHRoaXMuX2VuY29kaW5nICE9PSBlbmMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhblxcJ3Qgc3dpdGNoIGVuY29kaW5ncycpXG4gIH1cbiAgdmFyIG91dCA9IHRoaXMuX2RlY29kZXIud3JpdGUodmFsdWUpXG4gIGlmIChmaW5hbCkge1xuICAgIG91dCArPSB0aGlzLl9kZWNvZGVyLmVuZCgpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcbmZ1bmN0aW9uIFN0cmVhbUNpcGhlciAobW9kZSwga2V5LCBpdiwgZGVjcnlwdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3RyZWFtQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gbmV3IEJ1ZmZlcihpdi5sZW5ndGgpXG4gIHRoaXMuX2NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fc2VjQ2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9kZWNyeXB0ID0gZGVjcnlwdFxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgcmV0dXJuIHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaywgdGhpcy5fZGVjcnlwdClcbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9jaXBoZXIuc2NydWIoKVxufVxuIiwidmFyIENpcGhlckJhc2UgPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgZGVzID0gcmVxdWlyZSgnZGVzLmpzJylcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcblxudmFyIG1vZGVzID0ge1xuICAnZGVzLWVkZTMtY2JjJzogZGVzLkNCQy5pbnN0YW50aWF0ZShkZXMuRURFKSxcbiAgJ2Rlcy1lZGUzJzogZGVzLkVERSxcbiAgJ2Rlcy1lZGUtY2JjJzogZGVzLkNCQy5pbnN0YW50aWF0ZShkZXMuRURFKSxcbiAgJ2Rlcy1lZGUnOiBkZXMuRURFLFxuICAnZGVzLWNiYyc6IGRlcy5DQkMuaW5zdGFudGlhdGUoZGVzLkRFUyksXG4gICdkZXMtZWNiJzogZGVzLkRFU1xufVxubW9kZXMuZGVzID0gbW9kZXNbJ2Rlcy1jYmMnXVxubW9kZXMuZGVzMyA9IG1vZGVzWydkZXMtZWRlMy1jYmMnXVxubW9kdWxlLmV4cG9ydHMgPSBERVNcbmluaGVyaXRzKERFUywgQ2lwaGVyQmFzZSlcbmZ1bmN0aW9uIERFUyAob3B0cykge1xuICBDaXBoZXJCYXNlLmNhbGwodGhpcylcbiAgdmFyIG1vZGVOYW1lID0gb3B0cy5tb2RlLnRvTG93ZXJDYXNlKClcbiAgdmFyIG1vZGUgPSBtb2Rlc1ttb2RlTmFtZV1cbiAgdmFyIHR5cGVcbiAgaWYgKG9wdHMuZGVjcnlwdCkge1xuICAgIHR5cGUgPSAnZGVjcnlwdCdcbiAgfSBlbHNlIHtcbiAgICB0eXBlID0gJ2VuY3J5cHQnXG4gIH1cbiAgdmFyIGtleSA9IG9wdHMua2V5XG4gIGlmIChtb2RlTmFtZSA9PT0gJ2Rlcy1lZGUnIHx8IG1vZGVOYW1lID09PSAnZGVzLWVkZS1jYmMnKSB7XG4gICAga2V5ID0gQnVmZmVyLmNvbmNhdChba2V5LCBrZXkuc2xpY2UoMCwgOCldKVxuICB9XG4gIHZhciBpdiA9IG9wdHMuaXZcbiAgdGhpcy5fZGVzID0gbW9kZS5jcmVhdGUoe1xuICAgIGtleToga2V5LFxuICAgIGl2OiBpdixcbiAgICB0eXBlOiB0eXBlXG4gIH0pXG59XG5ERVMucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICByZXR1cm4gbmV3IEJ1ZmZlcih0aGlzLl9kZXMudXBkYXRlKGRhdGEpKVxufVxuREVTLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBuZXcgQnVmZmVyKHRoaXMuX2Rlcy5maW5hbCgpKVxufVxuIiwiZXhwb3J0c1snZGVzLWVjYiddID0ge1xuICBrZXk6IDgsXG4gIGl2OiAwXG59XG5leHBvcnRzWydkZXMtY2JjJ10gPSBleHBvcnRzLmRlcyA9IHtcbiAga2V5OiA4LFxuICBpdjogOFxufVxuZXhwb3J0c1snZGVzLWVkZTMtY2JjJ10gPSBleHBvcnRzLmRlczMgPSB7XG4gIGtleTogMjQsXG4gIGl2OiA4XG59XG5leHBvcnRzWydkZXMtZWRlMyddID0ge1xuICBrZXk6IDI0LFxuICBpdjogMFxufVxuZXhwb3J0c1snZGVzLWVkZS1jYmMnXSA9IHtcbiAga2V5OiAxNixcbiAgaXY6IDhcbn1cbmV4cG9ydHNbJ2Rlcy1lZGUnXSA9IHtcbiAga2V5OiAxNixcbiAgaXY6IDBcbn1cbiIsInZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdzdHJlYW0nKS5UcmFuc2Zvcm1cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyXG5tb2R1bGUuZXhwb3J0cyA9IENpcGhlckJhc2VcbmluaGVyaXRzKENpcGhlckJhc2UsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIENpcGhlckJhc2UgKGhhc2hNb2RlKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuaGFzaE1vZGUgPSB0eXBlb2YgaGFzaE1vZGUgPT09ICdzdHJpbmcnXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgdGhpc1toYXNoTW9kZV0gPSB0aGlzLl9maW5hbE9yRGlnZXN0XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5maW5hbCA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfVxuICB0aGlzLl9kZWNvZGVyID0gbnVsbFxuICB0aGlzLl9lbmNvZGluZyA9IG51bGxcbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBpbnB1dEVuYywgb3V0cHV0RW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCBpbnB1dEVuYylcbiAgfVxuICB2YXIgb3V0RGF0YSA9IHRoaXMuX3VwZGF0ZShkYXRhKVxuICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cbiAgaWYgKG91dHB1dEVuYykge1xuICAgIG91dERhdGEgPSB0aGlzLl90b1N0cmluZyhvdXREYXRhLCBvdXRwdXRFbmMpXG4gIH1cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoKSB7fVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5nZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBnZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBzZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhYWQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGRhdGEsIF8sIG5leHQpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgICB0aGlzLl91cGRhdGUoZGF0YSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wdXNoKHRoaXMuX3VwZGF0ZShkYXRhKSlcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlcnIgPSBlXG4gIH0gZmluYWxseSB7XG4gICAgbmV4dChlcnIpXG4gIH1cbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLl9mbHVzaCA9IGZ1bmN0aW9uIChkb25lKSB7XG4gIHZhciBlcnJcbiAgdHJ5IHtcbiAgICB0aGlzLnB1c2godGhpcy5fZmluYWwoKSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBkb25lKGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZpbmFsT3JEaWdlc3QgPSBmdW5jdGlvbiAob3V0cHV0RW5jKSB7XG4gIHZhciBvdXREYXRhID0gdGhpcy5fZmluYWwoKSB8fCBuZXcgQnVmZmVyKCcnKVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYywgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdG9TdHJpbmcgPSBmdW5jdGlvbiAodmFsdWUsIGVuYywgZmluYWwpIHtcbiAgaWYgKCF0aGlzLl9kZWNvZGVyKSB7XG4gICAgdGhpcy5fZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYylcbiAgICB0aGlzLl9lbmNvZGluZyA9IGVuY1xuICB9XG4gIGlmICh0aGlzLl9lbmNvZGluZyAhPT0gZW5jKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYW5cXCd0IHN3aXRjaCBlbmNvZGluZ3MnKVxuICB9XG4gIHZhciBvdXQgPSB0aGlzLl9kZWNvZGVyLndyaXRlKHZhbHVlKVxuICBpZiAoZmluYWwpIHtcbiAgICBvdXQgKz0gdGhpcy5fZGVjb2Rlci5lbmQoKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy51dGlscyA9IHJlcXVpcmUoJy4vZGVzL3V0aWxzJyk7XG5leHBvcnRzLkNpcGhlciA9IHJlcXVpcmUoJy4vZGVzL2NpcGhlcicpO1xuZXhwb3J0cy5ERVMgPSByZXF1aXJlKCcuL2Rlcy9kZXMnKTtcbmV4cG9ydHMuQ0JDID0gcmVxdWlyZSgnLi9kZXMvY2JjJyk7XG5leHBvcnRzLkVERSA9IHJlcXVpcmUoJy4vZGVzL2VkZScpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIHByb3RvID0ge307XG5cbmZ1bmN0aW9uIENCQ1N0YXRlKGl2KSB7XG4gIGFzc2VydC5lcXVhbChpdi5sZW5ndGgsIDgsICdJbnZhbGlkIElWIGxlbmd0aCcpO1xuXG4gIHRoaXMuaXYgPSBuZXcgQXJyYXkoOCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5pdi5sZW5ndGg7IGkrKylcbiAgICB0aGlzLml2W2ldID0gaXZbaV07XG59XG5cbmZ1bmN0aW9uIGluc3RhbnRpYXRlKEJhc2UpIHtcbiAgZnVuY3Rpb24gQ0JDKG9wdGlvbnMpIHtcbiAgICBCYXNlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gICAgdGhpcy5fY2JjSW5pdCgpO1xuICB9XG4gIGluaGVyaXRzKENCQywgQmFzZSk7XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm90byk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgIENCQy5wcm90b3R5cGVba2V5XSA9IHByb3RvW2tleV07XG4gIH1cblxuICBDQkMuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IENCQyhvcHRpb25zKTtcbiAgfTtcblxuICByZXR1cm4gQ0JDO1xufVxuXG5leHBvcnRzLmluc3RhbnRpYXRlID0gaW5zdGFudGlhdGU7XG5cbnByb3RvLl9jYmNJbml0ID0gZnVuY3Rpb24gX2NiY0luaXQoKSB7XG4gIHZhciBzdGF0ZSA9IG5ldyBDQkNTdGF0ZSh0aGlzLm9wdGlvbnMuaXYpO1xuICB0aGlzLl9jYmNTdGF0ZSA9IHN0YXRlO1xufTtcblxucHJvdG8uX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUoaW5wLCBpbk9mZiwgb3V0LCBvdXRPZmYpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fY2JjU3RhdGU7XG4gIHZhciBzdXBlclByb3RvID0gdGhpcy5jb25zdHJ1Y3Rvci5zdXBlcl8ucHJvdG90eXBlO1xuXG4gIHZhciBpdiA9IHN0YXRlLml2O1xuICBpZiAodGhpcy50eXBlID09PSAnZW5jcnlwdCcpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBpdltpXSBePSBpbnBbaW5PZmYgKyBpXTtcblxuICAgIHN1cGVyUHJvdG8uX3VwZGF0ZS5jYWxsKHRoaXMsIGl2LCAwLCBvdXQsIG91dE9mZik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBpdltpXSA9IG91dFtvdXRPZmYgKyBpXTtcbiAgfSBlbHNlIHtcbiAgICBzdXBlclByb3RvLl91cGRhdGUuY2FsbCh0aGlzLCBpbnAsIGluT2ZmLCBvdXQsIG91dE9mZik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBvdXRbb3V0T2ZmICsgaV0gXj0gaXZbaV07XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBpdltpXSA9IGlucFtpbk9mZiArIGldO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG5mdW5jdGlvbiBDaXBoZXIob3B0aW9ucykge1xuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gIHRoaXMudHlwZSA9IHRoaXMub3B0aW9ucy50eXBlO1xuICB0aGlzLmJsb2NrU2l6ZSA9IDg7XG4gIHRoaXMuX2luaXQoKTtcblxuICB0aGlzLmJ1ZmZlciA9IG5ldyBBcnJheSh0aGlzLmJsb2NrU2l6ZSk7XG4gIHRoaXMuYnVmZmVyT2ZmID0gMDtcbn1cbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyO1xuXG5DaXBoZXIucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gX2luaXQoKSB7XG4gIC8vIE1pZ2h0IGJlIG92ZXJyaWRlZFxufTtcblxuQ2lwaGVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUoZGF0YSkge1xuICBpZiAoZGF0YS5sZW5ndGggPT09IDApXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0aGlzLnR5cGUgPT09ICdkZWNyeXB0JylcbiAgICByZXR1cm4gdGhpcy5fdXBkYXRlRGVjcnlwdChkYXRhKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLl91cGRhdGVFbmNyeXB0KGRhdGEpO1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fYnVmZmVyID0gZnVuY3Rpb24gX2J1ZmZlcihkYXRhLCBvZmYpIHtcbiAgLy8gQXBwZW5kIGRhdGEgdG8gYnVmZmVyXG4gIHZhciBtaW4gPSBNYXRoLm1pbih0aGlzLmJ1ZmZlci5sZW5ndGggLSB0aGlzLmJ1ZmZlck9mZiwgZGF0YS5sZW5ndGggLSBvZmYpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1pbjsgaSsrKVxuICAgIHRoaXMuYnVmZmVyW3RoaXMuYnVmZmVyT2ZmICsgaV0gPSBkYXRhW29mZiArIGldO1xuICB0aGlzLmJ1ZmZlck9mZiArPSBtaW47XG5cbiAgLy8gU2hpZnQgbmV4dFxuICByZXR1cm4gbWluO1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fZmx1c2hCdWZmZXIgPSBmdW5jdGlvbiBfZmx1c2hCdWZmZXIob3V0LCBvZmYpIHtcbiAgdGhpcy5fdXBkYXRlKHRoaXMuYnVmZmVyLCAwLCBvdXQsIG9mZik7XG4gIHRoaXMuYnVmZmVyT2ZmID0gMDtcbiAgcmV0dXJuIHRoaXMuYmxvY2tTaXplO1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlRW5jcnlwdCA9IGZ1bmN0aW9uIF91cGRhdGVFbmNyeXB0KGRhdGEpIHtcbiAgdmFyIGlucHV0T2ZmID0gMDtcbiAgdmFyIG91dHB1dE9mZiA9IDA7XG5cbiAgdmFyIGNvdW50ID0gKCh0aGlzLmJ1ZmZlck9mZiArIGRhdGEubGVuZ3RoKSAvIHRoaXMuYmxvY2tTaXplKSB8IDA7XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkoY291bnQgKiB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgaWYgKHRoaXMuYnVmZmVyT2ZmICE9PSAwKSB7XG4gICAgaW5wdXRPZmYgKz0gdGhpcy5fYnVmZmVyKGRhdGEsIGlucHV0T2ZmKTtcblxuICAgIGlmICh0aGlzLmJ1ZmZlck9mZiA9PT0gdGhpcy5idWZmZXIubGVuZ3RoKVxuICAgICAgb3V0cHV0T2ZmICs9IHRoaXMuX2ZsdXNoQnVmZmVyKG91dCwgb3V0cHV0T2ZmKTtcbiAgfVxuXG4gIC8vIFdyaXRlIGJsb2Nrc1xuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGggLSAoKGRhdGEubGVuZ3RoIC0gaW5wdXRPZmYpICUgdGhpcy5ibG9ja1NpemUpO1xuICBmb3IgKDsgaW5wdXRPZmYgPCBtYXg7IGlucHV0T2ZmICs9IHRoaXMuYmxvY2tTaXplKSB7XG4gICAgdGhpcy5fdXBkYXRlKGRhdGEsIGlucHV0T2ZmLCBvdXQsIG91dHB1dE9mZik7XG4gICAgb3V0cHV0T2ZmICs9IHRoaXMuYmxvY2tTaXplO1xuICB9XG5cbiAgLy8gUXVldWUgcmVzdFxuICBmb3IgKDsgaW5wdXRPZmYgPCBkYXRhLmxlbmd0aDsgaW5wdXRPZmYrKywgdGhpcy5idWZmZXJPZmYrKylcbiAgICB0aGlzLmJ1ZmZlclt0aGlzLmJ1ZmZlck9mZl0gPSBkYXRhW2lucHV0T2ZmXTtcblxuICByZXR1cm4gb3V0O1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlRGVjcnlwdCA9IGZ1bmN0aW9uIF91cGRhdGVEZWNyeXB0KGRhdGEpIHtcbiAgdmFyIGlucHV0T2ZmID0gMDtcbiAgdmFyIG91dHB1dE9mZiA9IDA7XG5cbiAgdmFyIGNvdW50ID0gTWF0aC5jZWlsKCh0aGlzLmJ1ZmZlck9mZiArIGRhdGEubGVuZ3RoKSAvIHRoaXMuYmxvY2tTaXplKSAtIDE7XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkoY291bnQgKiB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgLy8gVE9ETyhpbmR1dG55KTogb3B0aW1pemUgaXQsIHRoaXMgaXMgZmFyIGZyb20gb3B0aW1hbFxuICBmb3IgKDsgY291bnQgPiAwOyBjb3VudC0tKSB7XG4gICAgaW5wdXRPZmYgKz0gdGhpcy5fYnVmZmVyKGRhdGEsIGlucHV0T2ZmKTtcbiAgICBvdXRwdXRPZmYgKz0gdGhpcy5fZmx1c2hCdWZmZXIob3V0LCBvdXRwdXRPZmYpO1xuICB9XG5cbiAgLy8gQnVmZmVyIHJlc3Qgb2YgdGhlIGlucHV0XG4gIGlucHV0T2ZmICs9IHRoaXMuX2J1ZmZlcihkYXRhLCBpbnB1dE9mZik7XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuZmluYWwgPSBmdW5jdGlvbiBmaW5hbChidWZmZXIpIHtcbiAgdmFyIGZpcnN0O1xuICBpZiAoYnVmZmVyKVxuICAgIGZpcnN0ID0gdGhpcy51cGRhdGUoYnVmZmVyKTtcblxuICB2YXIgbGFzdDtcbiAgaWYgKHRoaXMudHlwZSA9PT0gJ2VuY3J5cHQnKVxuICAgIGxhc3QgPSB0aGlzLl9maW5hbEVuY3J5cHQoKTtcbiAgZWxzZVxuICAgIGxhc3QgPSB0aGlzLl9maW5hbERlY3J5cHQoKTtcblxuICBpZiAoZmlyc3QpXG4gICAgcmV0dXJuIGZpcnN0LmNvbmNhdChsYXN0KTtcbiAgZWxzZVxuICAgIHJldHVybiBsYXN0O1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gX3BhZChidWZmZXIsIG9mZikge1xuICBpZiAob2ZmID09PSAwKVxuICAgIHJldHVybiBmYWxzZTtcblxuICB3aGlsZSAob2ZmIDwgYnVmZmVyLmxlbmd0aClcbiAgICBidWZmZXJbb2ZmKytdID0gMDtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX2ZpbmFsRW5jcnlwdCA9IGZ1bmN0aW9uIF9maW5hbEVuY3J5cHQoKSB7XG4gIGlmICghdGhpcy5fcGFkKHRoaXMuYnVmZmVyLCB0aGlzLmJ1ZmZlck9mZikpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBvdXQgPSBuZXcgQXJyYXkodGhpcy5ibG9ja1NpemUpO1xuICB0aGlzLl91cGRhdGUodGhpcy5idWZmZXIsIDAsIG91dCwgMCk7XG4gIHJldHVybiBvdXQ7XG59O1xuXG5DaXBoZXIucHJvdG90eXBlLl91bnBhZCA9IGZ1bmN0aW9uIF91bnBhZChidWZmZXIpIHtcbiAgcmV0dXJuIGJ1ZmZlcjtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX2ZpbmFsRGVjcnlwdCA9IGZ1bmN0aW9uIF9maW5hbERlY3J5cHQoKSB7XG4gIGFzc2VydC5lcXVhbCh0aGlzLmJ1ZmZlck9mZiwgdGhpcy5ibG9ja1NpemUsICdOb3QgZW5vdWdoIGRhdGEgdG8gZGVjcnlwdCcpO1xuICB2YXIgb3V0ID0gbmV3IEFycmF5KHRoaXMuYmxvY2tTaXplKTtcbiAgdGhpcy5fZmx1c2hCdWZmZXIob3V0LCAwKTtcblxuICByZXR1cm4gdGhpcy5fdW5wYWQob3V0KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgZGVzID0gcmVxdWlyZSgnLi4vZGVzJyk7XG52YXIgdXRpbHMgPSBkZXMudXRpbHM7XG52YXIgQ2lwaGVyID0gZGVzLkNpcGhlcjtcblxuZnVuY3Rpb24gREVTU3RhdGUoKSB7XG4gIHRoaXMudG1wID0gbmV3IEFycmF5KDIpO1xuICB0aGlzLmtleXMgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBERVMob3B0aW9ucykge1xuICBDaXBoZXIuY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICB2YXIgc3RhdGUgPSBuZXcgREVTU3RhdGUoKTtcbiAgdGhpcy5fZGVzU3RhdGUgPSBzdGF0ZTtcblxuICB0aGlzLmRlcml2ZUtleXMoc3RhdGUsIG9wdGlvbnMua2V5KTtcbn1cbmluaGVyaXRzKERFUywgQ2lwaGVyKTtcbm1vZHVsZS5leHBvcnRzID0gREVTO1xuXG5ERVMuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBERVMob3B0aW9ucyk7XG59O1xuXG52YXIgc2hpZnRUYWJsZSA9IFtcbiAgMSwgMSwgMiwgMiwgMiwgMiwgMiwgMixcbiAgMSwgMiwgMiwgMiwgMiwgMiwgMiwgMVxuXTtcblxuREVTLnByb3RvdHlwZS5kZXJpdmVLZXlzID0gZnVuY3Rpb24gZGVyaXZlS2V5cyhzdGF0ZSwga2V5KSB7XG4gIHN0YXRlLmtleXMgPSBuZXcgQXJyYXkoMTYgKiAyKTtcblxuICBhc3NlcnQuZXF1YWwoa2V5Lmxlbmd0aCwgdGhpcy5ibG9ja1NpemUsICdJbnZhbGlkIGtleSBsZW5ndGgnKTtcblxuICB2YXIga0wgPSB1dGlscy5yZWFkVUludDMyQkUoa2V5LCAwKTtcbiAgdmFyIGtSID0gdXRpbHMucmVhZFVJbnQzMkJFKGtleSwgNCk7XG5cbiAgdXRpbHMucGMxKGtMLCBrUiwgc3RhdGUudG1wLCAwKTtcbiAga0wgPSBzdGF0ZS50bXBbMF07XG4gIGtSID0gc3RhdGUudG1wWzFdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YXRlLmtleXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIgc2hpZnQgPSBzaGlmdFRhYmxlW2kgPj4+IDFdO1xuICAgIGtMID0gdXRpbHMucjI4c2hsKGtMLCBzaGlmdCk7XG4gICAga1IgPSB1dGlscy5yMjhzaGwoa1IsIHNoaWZ0KTtcbiAgICB1dGlscy5wYzIoa0wsIGtSLCBzdGF0ZS5rZXlzLCBpKTtcbiAgfVxufTtcblxuREVTLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShpbnAsIGluT2ZmLCBvdXQsIG91dE9mZikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9kZXNTdGF0ZTtcblxuICB2YXIgbCA9IHV0aWxzLnJlYWRVSW50MzJCRShpbnAsIGluT2ZmKTtcbiAgdmFyIHIgPSB1dGlscy5yZWFkVUludDMyQkUoaW5wLCBpbk9mZiArIDQpO1xuXG4gIC8vIEluaXRpYWwgUGVybXV0YXRpb25cbiAgdXRpbHMuaXAobCwgciwgc3RhdGUudG1wLCAwKTtcbiAgbCA9IHN0YXRlLnRtcFswXTtcbiAgciA9IHN0YXRlLnRtcFsxXTtcblxuICBpZiAodGhpcy50eXBlID09PSAnZW5jcnlwdCcpXG4gICAgdGhpcy5fZW5jcnlwdChzdGF0ZSwgbCwgciwgc3RhdGUudG1wLCAwKTtcbiAgZWxzZVxuICAgIHRoaXMuX2RlY3J5cHQoc3RhdGUsIGwsIHIsIHN0YXRlLnRtcCwgMCk7XG5cbiAgbCA9IHN0YXRlLnRtcFswXTtcbiAgciA9IHN0YXRlLnRtcFsxXTtcblxuICB1dGlscy53cml0ZVVJbnQzMkJFKG91dCwgbCwgb3V0T2ZmKTtcbiAgdXRpbHMud3JpdGVVSW50MzJCRShvdXQsIHIsIG91dE9mZiArIDQpO1xufTtcblxuREVTLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gX3BhZChidWZmZXIsIG9mZikge1xuICB2YXIgdmFsdWUgPSBidWZmZXIubGVuZ3RoIC0gb2ZmO1xuICBmb3IgKHZhciBpID0gb2ZmOyBpIDwgYnVmZmVyLmxlbmd0aDsgaSsrKVxuICAgIGJ1ZmZlcltpXSA9IHZhbHVlO1xuXG4gIHJldHVybiB0cnVlO1xufTtcblxuREVTLnByb3RvdHlwZS5fdW5wYWQgPSBmdW5jdGlvbiBfdW5wYWQoYnVmZmVyKSB7XG4gIHZhciBwYWQgPSBidWZmZXJbYnVmZmVyLmxlbmd0aCAtIDFdO1xuICBmb3IgKHZhciBpID0gYnVmZmVyLmxlbmd0aCAtIHBhZDsgaSA8IGJ1ZmZlci5sZW5ndGg7IGkrKylcbiAgICBhc3NlcnQuZXF1YWwoYnVmZmVyW2ldLCBwYWQpO1xuXG4gIHJldHVybiBidWZmZXIuc2xpY2UoMCwgYnVmZmVyLmxlbmd0aCAtIHBhZCk7XG59O1xuXG5ERVMucHJvdG90eXBlLl9lbmNyeXB0ID0gZnVuY3Rpb24gX2VuY3J5cHQoc3RhdGUsIGxTdGFydCwgclN0YXJ0LCBvdXQsIG9mZikge1xuICB2YXIgbCA9IGxTdGFydDtcbiAgdmFyIHIgPSByU3RhcnQ7XG5cbiAgLy8gQXBwbHkgZigpIHgxNiB0aW1lc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YXRlLmtleXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIga2V5TCA9IHN0YXRlLmtleXNbaV07XG4gICAgdmFyIGtleVIgPSBzdGF0ZS5rZXlzW2kgKyAxXTtcblxuICAgIC8vIGYociwgaylcbiAgICB1dGlscy5leHBhbmQociwgc3RhdGUudG1wLCAwKTtcblxuICAgIGtleUwgXj0gc3RhdGUudG1wWzBdO1xuICAgIGtleVIgXj0gc3RhdGUudG1wWzFdO1xuICAgIHZhciBzID0gdXRpbHMuc3Vic3RpdHV0ZShrZXlMLCBrZXlSKTtcbiAgICB2YXIgZiA9IHV0aWxzLnBlcm11dGUocyk7XG5cbiAgICB2YXIgdCA9IHI7XG4gICAgciA9IChsIF4gZikgPj4+IDA7XG4gICAgbCA9IHQ7XG4gIH1cblxuICAvLyBSZXZlcnNlIEluaXRpYWwgUGVybXV0YXRpb25cbiAgdXRpbHMucmlwKHIsIGwsIG91dCwgb2ZmKTtcbn07XG5cbkRFUy5wcm90b3R5cGUuX2RlY3J5cHQgPSBmdW5jdGlvbiBfZGVjcnlwdChzdGF0ZSwgbFN0YXJ0LCByU3RhcnQsIG91dCwgb2ZmKSB7XG4gIHZhciBsID0gclN0YXJ0O1xuICB2YXIgciA9IGxTdGFydDtcblxuICAvLyBBcHBseSBmKCkgeDE2IHRpbWVzXG4gIGZvciAodmFyIGkgPSBzdGF0ZS5rZXlzLmxlbmd0aCAtIDI7IGkgPj0gMDsgaSAtPSAyKSB7XG4gICAgdmFyIGtleUwgPSBzdGF0ZS5rZXlzW2ldO1xuICAgIHZhciBrZXlSID0gc3RhdGUua2V5c1tpICsgMV07XG5cbiAgICAvLyBmKHIsIGspXG4gICAgdXRpbHMuZXhwYW5kKGwsIHN0YXRlLnRtcCwgMCk7XG5cbiAgICBrZXlMIF49IHN0YXRlLnRtcFswXTtcbiAgICBrZXlSIF49IHN0YXRlLnRtcFsxXTtcbiAgICB2YXIgcyA9IHV0aWxzLnN1YnN0aXR1dGUoa2V5TCwga2V5Uik7XG4gICAgdmFyIGYgPSB1dGlscy5wZXJtdXRlKHMpO1xuXG4gICAgdmFyIHQgPSBsO1xuICAgIGwgPSAociBeIGYpID4+PiAwO1xuICAgIHIgPSB0O1xuICB9XG5cbiAgLy8gUmV2ZXJzZSBJbml0aWFsIFBlcm11dGF0aW9uXG4gIHV0aWxzLnJpcChsLCByLCBvdXQsIG9mZik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIGRlcyA9IHJlcXVpcmUoJy4uL2RlcycpO1xudmFyIENpcGhlciA9IGRlcy5DaXBoZXI7XG52YXIgREVTID0gZGVzLkRFUztcblxuZnVuY3Rpb24gRURFU3RhdGUodHlwZSwga2V5KSB7XG4gIGFzc2VydC5lcXVhbChrZXkubGVuZ3RoLCAyNCwgJ0ludmFsaWQga2V5IGxlbmd0aCcpO1xuXG4gIHZhciBrMSA9IGtleS5zbGljZSgwLCA4KTtcbiAgdmFyIGsyID0ga2V5LnNsaWNlKDgsIDE2KTtcbiAgdmFyIGszID0ga2V5LnNsaWNlKDE2LCAyNCk7XG5cbiAgaWYgKHR5cGUgPT09ICdlbmNyeXB0Jykge1xuICAgIHRoaXMuY2lwaGVycyA9IFtcbiAgICAgIERFUy5jcmVhdGUoeyB0eXBlOiAnZW5jcnlwdCcsIGtleTogazEgfSksXG4gICAgICBERVMuY3JlYXRlKHsgdHlwZTogJ2RlY3J5cHQnLCBrZXk6IGsyIH0pLFxuICAgICAgREVTLmNyZWF0ZSh7IHR5cGU6ICdlbmNyeXB0Jywga2V5OiBrMyB9KVxuICAgIF07XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5jaXBoZXJzID0gW1xuICAgICAgREVTLmNyZWF0ZSh7IHR5cGU6ICdkZWNyeXB0Jywga2V5OiBrMyB9KSxcbiAgICAgIERFUy5jcmVhdGUoeyB0eXBlOiAnZW5jcnlwdCcsIGtleTogazIgfSksXG4gICAgICBERVMuY3JlYXRlKHsgdHlwZTogJ2RlY3J5cHQnLCBrZXk6IGsxIH0pXG4gICAgXTtcbiAgfVxufVxuXG5mdW5jdGlvbiBFREUob3B0aW9ucykge1xuICBDaXBoZXIuY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICB2YXIgc3RhdGUgPSBuZXcgRURFU3RhdGUodGhpcy50eXBlLCB0aGlzLm9wdGlvbnMua2V5KTtcbiAgdGhpcy5fZWRlU3RhdGUgPSBzdGF0ZTtcbn1cbmluaGVyaXRzKEVERSwgQ2lwaGVyKTtcblxubW9kdWxlLmV4cG9ydHMgPSBFREU7XG5cbkVERS5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUob3B0aW9ucykge1xuICByZXR1cm4gbmV3IEVERShvcHRpb25zKTtcbn07XG5cbkVERS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUoaW5wLCBpbk9mZiwgb3V0LCBvdXRPZmYpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fZWRlU3RhdGU7XG5cbiAgc3RhdGUuY2lwaGVyc1swXS5fdXBkYXRlKGlucCwgaW5PZmYsIG91dCwgb3V0T2ZmKTtcbiAgc3RhdGUuY2lwaGVyc1sxXS5fdXBkYXRlKG91dCwgb3V0T2ZmLCBvdXQsIG91dE9mZik7XG4gIHN0YXRlLmNpcGhlcnNbMl0uX3VwZGF0ZShvdXQsIG91dE9mZiwgb3V0LCBvdXRPZmYpO1xufTtcblxuRURFLnByb3RvdHlwZS5fcGFkID0gREVTLnByb3RvdHlwZS5fcGFkO1xuRURFLnByb3RvdHlwZS5fdW5wYWQgPSBERVMucHJvdG90eXBlLl91bnBhZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUoYnl0ZXMsIG9mZikge1xuICB2YXIgcmVzID0gIChieXRlc1swICsgb2ZmXSA8PCAyNCkgfFxuICAgICAgICAgICAgIChieXRlc1sxICsgb2ZmXSA8PCAxNikgfFxuICAgICAgICAgICAgIChieXRlc1syICsgb2ZmXSA8PCA4KSB8XG4gICAgICAgICAgICAgYnl0ZXNbMyArIG9mZl07XG4gIHJldHVybiByZXMgPj4+IDA7XG59O1xuXG5leHBvcnRzLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFKGJ5dGVzLCB2YWx1ZSwgb2ZmKSB7XG4gIGJ5dGVzWzAgKyBvZmZdID0gdmFsdWUgPj4+IDI0O1xuICBieXRlc1sxICsgb2ZmXSA9ICh2YWx1ZSA+Pj4gMTYpICYgMHhmZjtcbiAgYnl0ZXNbMiArIG9mZl0gPSAodmFsdWUgPj4+IDgpICYgMHhmZjtcbiAgYnl0ZXNbMyArIG9mZl0gPSB2YWx1ZSAmIDB4ZmY7XG59O1xuXG5leHBvcnRzLmlwID0gZnVuY3Rpb24gaXAoaW5MLCBpblIsIG91dCwgb2ZmKSB7XG4gIHZhciBvdXRMID0gMDtcbiAgdmFyIG91dFIgPSAwO1xuXG4gIGZvciAodmFyIGkgPSA2OyBpID49IDA7IGkgLT0gMikge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICAgIG91dEwgPDw9IDE7XG4gICAgICBvdXRMIHw9IChpblIgPj4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPD0gMjQ7IGogKz0gOCkge1xuICAgICAgb3V0TCA8PD0gMTtcbiAgICAgIG91dEwgfD0gKGluTCA+Pj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSA2OyBpID49IDA7IGkgLT0gMikge1xuICAgIGZvciAodmFyIGogPSAxOyBqIDw9IDI1OyBqICs9IDgpIHtcbiAgICAgIG91dFIgPDw9IDE7XG4gICAgICBvdXRSIHw9IChpblIgPj4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDE7IGogPD0gMjU7IGogKz0gOCkge1xuICAgICAgb3V0UiA8PD0gMTtcbiAgICAgIG91dFIgfD0gKGluTCA+Pj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgfVxuXG4gIG91dFtvZmYgKyAwXSA9IG91dEwgPj4+IDA7XG4gIG91dFtvZmYgKyAxXSA9IG91dFIgPj4+IDA7XG59O1xuXG5leHBvcnRzLnJpcCA9IGZ1bmN0aW9uIHJpcChpbkwsIGluUiwgb3V0LCBvZmYpIHtcbiAgdmFyIG91dEwgPSAwO1xuICB2YXIgb3V0UiA9IDA7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICBmb3IgKHZhciBqID0gMjQ7IGogPj0gMDsgaiAtPSA4KSB7XG4gICAgICBvdXRMIDw8PSAxO1xuICAgICAgb3V0TCB8PSAoaW5SID4+PiAoaiArIGkpKSAmIDE7XG4gICAgICBvdXRMIDw8PSAxO1xuICAgICAgb3V0TCB8PSAoaW5MID4+PiAoaiArIGkpKSAmIDE7XG4gICAgfVxuICB9XG4gIGZvciAodmFyIGkgPSA0OyBpIDwgODsgaSsrKSB7XG4gICAgZm9yICh2YXIgaiA9IDI0OyBqID49IDA7IGogLT0gOCkge1xuICAgICAgb3V0UiA8PD0gMTtcbiAgICAgIG91dFIgfD0gKGluUiA+Pj4gKGogKyBpKSkgJiAxO1xuICAgICAgb3V0UiA8PD0gMTtcbiAgICAgIG91dFIgfD0gKGluTCA+Pj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgfVxuXG4gIG91dFtvZmYgKyAwXSA9IG91dEwgPj4+IDA7XG4gIG91dFtvZmYgKyAxXSA9IG91dFIgPj4+IDA7XG59O1xuXG5leHBvcnRzLnBjMSA9IGZ1bmN0aW9uIHBjMShpbkwsIGluUiwgb3V0LCBvZmYpIHtcbiAgdmFyIG91dEwgPSAwO1xuICB2YXIgb3V0UiA9IDA7XG5cbiAgLy8gNywgMTUsIDIzLCAzMSwgMzksIDQ3LCA1NSwgNjNcbiAgLy8gNiwgMTQsIDIyLCAzMCwgMzksIDQ3LCA1NSwgNjNcbiAgLy8gNSwgMTMsIDIxLCAyOSwgMzksIDQ3LCA1NSwgNjNcbiAgLy8gNCwgMTIsIDIwLCAyOFxuICBmb3IgKHZhciBpID0gNzsgaSA+PSA1OyBpLS0pIHtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8PSAyNDsgaiArPSA4KSB7XG4gICAgICBvdXRMIDw8PSAxO1xuICAgICAgb3V0TCB8PSAoaW5SID4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPD0gMjQ7IGogKz0gOCkge1xuICAgICAgb3V0TCA8PD0gMTtcbiAgICAgIG91dEwgfD0gKGluTCA+PiAoaiArIGkpKSAmIDE7XG4gICAgfVxuICB9XG4gIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICBvdXRMIDw8PSAxO1xuICAgIG91dEwgfD0gKGluUiA+PiAoaiArIGkpKSAmIDE7XG4gIH1cblxuICAvLyAxLCA5LCAxNywgMjUsIDMzLCA0MSwgNDksIDU3XG4gIC8vIDIsIDEwLCAxOCwgMjYsIDM0LCA0MiwgNTAsIDU4XG4gIC8vIDMsIDExLCAxOSwgMjcsIDM1LCA0MywgNTEsIDU5XG4gIC8vIDM2LCA0NCwgNTIsIDYwXG4gIGZvciAodmFyIGkgPSAxOyBpIDw9IDM7IGkrKykge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICAgIG91dFIgPDw9IDE7XG4gICAgICBvdXRSIHw9IChpblIgPj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8PSAyNDsgaiArPSA4KSB7XG4gICAgICBvdXRSIDw8PSAxO1xuICAgICAgb3V0UiB8PSAoaW5MID4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gIH1cbiAgZm9yICh2YXIgaiA9IDA7IGogPD0gMjQ7IGogKz0gOCkge1xuICAgIG91dFIgPDw9IDE7XG4gICAgb3V0UiB8PSAoaW5MID4+IChqICsgaSkpICYgMTtcbiAgfVxuXG4gIG91dFtvZmYgKyAwXSA9IG91dEwgPj4+IDA7XG4gIG91dFtvZmYgKyAxXSA9IG91dFIgPj4+IDA7XG59O1xuXG5leHBvcnRzLnIyOHNobCA9IGZ1bmN0aW9uIHIyOHNobChudW0sIHNoaWZ0KSB7XG4gIHJldHVybiAoKG51bSA8PCBzaGlmdCkgJiAweGZmZmZmZmYpIHwgKG51bSA+Pj4gKDI4IC0gc2hpZnQpKTtcbn07XG5cbnZhciBwYzJ0YWJsZSA9IFtcbiAgLy8gaW5MID0+IG91dExcbiAgMTQsIDExLCAxNywgNCwgMjcsIDIzLCAyNSwgMCxcbiAgMTMsIDIyLCA3LCAxOCwgNSwgOSwgMTYsIDI0LFxuICAyLCAyMCwgMTIsIDIxLCAxLCA4LCAxNSwgMjYsXG5cbiAgLy8gaW5SID0+IG91dFJcbiAgMTUsIDQsIDI1LCAxOSwgOSwgMSwgMjYsIDE2LFxuICA1LCAxMSwgMjMsIDgsIDEyLCA3LCAxNywgMCxcbiAgMjIsIDMsIDEwLCAxNCwgNiwgMjAsIDI3LCAyNFxuXTtcblxuZXhwb3J0cy5wYzIgPSBmdW5jdGlvbiBwYzIoaW5MLCBpblIsIG91dCwgb2ZmKSB7XG4gIHZhciBvdXRMID0gMDtcbiAgdmFyIG91dFIgPSAwO1xuXG4gIHZhciBsZW4gPSBwYzJ0YWJsZS5sZW5ndGggPj4+IDE7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBvdXRMIDw8PSAxO1xuICAgIG91dEwgfD0gKGluTCA+Pj4gcGMydGFibGVbaV0pICYgMHgxO1xuICB9XG4gIGZvciAodmFyIGkgPSBsZW47IGkgPCBwYzJ0YWJsZS5sZW5ndGg7IGkrKykge1xuICAgIG91dFIgPDw9IDE7XG4gICAgb3V0UiB8PSAoaW5SID4+PiBwYzJ0YWJsZVtpXSkgJiAweDE7XG4gIH1cblxuICBvdXRbb2ZmICsgMF0gPSBvdXRMID4+PiAwO1xuICBvdXRbb2ZmICsgMV0gPSBvdXRSID4+PiAwO1xufTtcblxuZXhwb3J0cy5leHBhbmQgPSBmdW5jdGlvbiBleHBhbmQociwgb3V0LCBvZmYpIHtcbiAgdmFyIG91dEwgPSAwO1xuICB2YXIgb3V0UiA9IDA7XG5cbiAgb3V0TCA9ICgociAmIDEpIDw8IDUpIHwgKHIgPj4+IDI3KTtcbiAgZm9yICh2YXIgaSA9IDIzOyBpID49IDE1OyBpIC09IDQpIHtcbiAgICBvdXRMIDw8PSA2O1xuICAgIG91dEwgfD0gKHIgPj4+IGkpICYgMHgzZjtcbiAgfVxuICBmb3IgKHZhciBpID0gMTE7IGkgPj0gMzsgaSAtPSA0KSB7XG4gICAgb3V0UiB8PSAociA+Pj4gaSkgJiAweDNmO1xuICAgIG91dFIgPDw9IDY7XG4gIH1cbiAgb3V0UiB8PSAoKHIgJiAweDFmKSA8PCAxKSB8IChyID4+PiAzMSk7XG5cbiAgb3V0W29mZiArIDBdID0gb3V0TCA+Pj4gMDtcbiAgb3V0W29mZiArIDFdID0gb3V0UiA+Pj4gMDtcbn07XG5cbnZhciBzVGFibGUgPSBbXG4gIDE0LCAwLCA0LCAxNSwgMTMsIDcsIDEsIDQsIDIsIDE0LCAxNSwgMiwgMTEsIDEzLCA4LCAxLFxuICAzLCAxMCwgMTAsIDYsIDYsIDEyLCAxMiwgMTEsIDUsIDksIDksIDUsIDAsIDMsIDcsIDgsXG4gIDQsIDE1LCAxLCAxMiwgMTQsIDgsIDgsIDIsIDEzLCA0LCA2LCA5LCAyLCAxLCAxMSwgNyxcbiAgMTUsIDUsIDEyLCAxMSwgOSwgMywgNywgMTQsIDMsIDEwLCAxMCwgMCwgNSwgNiwgMCwgMTMsXG5cbiAgMTUsIDMsIDEsIDEzLCA4LCA0LCAxNCwgNywgNiwgMTUsIDExLCAyLCAzLCA4LCA0LCAxNCxcbiAgOSwgMTIsIDcsIDAsIDIsIDEsIDEzLCAxMCwgMTIsIDYsIDAsIDksIDUsIDExLCAxMCwgNSxcbiAgMCwgMTMsIDE0LCA4LCA3LCAxMCwgMTEsIDEsIDEwLCAzLCA0LCAxNSwgMTMsIDQsIDEsIDIsXG4gIDUsIDExLCA4LCA2LCAxMiwgNywgNiwgMTIsIDksIDAsIDMsIDUsIDIsIDE0LCAxNSwgOSxcblxuICAxMCwgMTMsIDAsIDcsIDksIDAsIDE0LCA5LCA2LCAzLCAzLCA0LCAxNSwgNiwgNSwgMTAsXG4gIDEsIDIsIDEzLCA4LCAxMiwgNSwgNywgMTQsIDExLCAxMiwgNCwgMTEsIDIsIDE1LCA4LCAxLFxuICAxMywgMSwgNiwgMTAsIDQsIDEzLCA5LCAwLCA4LCA2LCAxNSwgOSwgMywgOCwgMCwgNyxcbiAgMTEsIDQsIDEsIDE1LCAyLCAxNCwgMTIsIDMsIDUsIDExLCAxMCwgNSwgMTQsIDIsIDcsIDEyLFxuXG4gIDcsIDEzLCAxMywgOCwgMTQsIDExLCAzLCA1LCAwLCA2LCA2LCAxNSwgOSwgMCwgMTAsIDMsXG4gIDEsIDQsIDIsIDcsIDgsIDIsIDUsIDEyLCAxMSwgMSwgMTIsIDEwLCA0LCAxNCwgMTUsIDksXG4gIDEwLCAzLCA2LCAxNSwgOSwgMCwgMCwgNiwgMTIsIDEwLCAxMSwgMSwgNywgMTMsIDEzLCA4LFxuICAxNSwgOSwgMSwgNCwgMywgNSwgMTQsIDExLCA1LCAxMiwgMiwgNywgOCwgMiwgNCwgMTQsXG5cbiAgMiwgMTQsIDEyLCAxMSwgNCwgMiwgMSwgMTIsIDcsIDQsIDEwLCA3LCAxMSwgMTMsIDYsIDEsXG4gIDgsIDUsIDUsIDAsIDMsIDE1LCAxNSwgMTAsIDEzLCAzLCAwLCA5LCAxNCwgOCwgOSwgNixcbiAgNCwgMTEsIDIsIDgsIDEsIDEyLCAxMSwgNywgMTAsIDEsIDEzLCAxNCwgNywgMiwgOCwgMTMsXG4gIDE1LCA2LCA5LCAxNSwgMTIsIDAsIDUsIDksIDYsIDEwLCAzLCA0LCAwLCA1LCAxNCwgMyxcblxuICAxMiwgMTAsIDEsIDE1LCAxMCwgNCwgMTUsIDIsIDksIDcsIDIsIDEyLCA2LCA5LCA4LCA1LFxuICAwLCA2LCAxMywgMSwgMywgMTMsIDQsIDE0LCAxNCwgMCwgNywgMTEsIDUsIDMsIDExLCA4LFxuICA5LCA0LCAxNCwgMywgMTUsIDIsIDUsIDEyLCAyLCA5LCA4LCA1LCAxMiwgMTUsIDMsIDEwLFxuICA3LCAxMSwgMCwgMTQsIDQsIDEsIDEwLCA3LCAxLCA2LCAxMywgMCwgMTEsIDgsIDYsIDEzLFxuXG4gIDQsIDEzLCAxMSwgMCwgMiwgMTEsIDE0LCA3LCAxNSwgNCwgMCwgOSwgOCwgMSwgMTMsIDEwLFxuICAzLCAxNCwgMTIsIDMsIDksIDUsIDcsIDEyLCA1LCAyLCAxMCwgMTUsIDYsIDgsIDEsIDYsXG4gIDEsIDYsIDQsIDExLCAxMSwgMTMsIDEzLCA4LCAxMiwgMSwgMywgNCwgNywgMTAsIDE0LCA3LFxuICAxMCwgOSwgMTUsIDUsIDYsIDAsIDgsIDE1LCAwLCAxNCwgNSwgMiwgOSwgMywgMiwgMTIsXG5cbiAgMTMsIDEsIDIsIDE1LCA4LCAxMywgNCwgOCwgNiwgMTAsIDE1LCAzLCAxMSwgNywgMSwgNCxcbiAgMTAsIDEyLCA5LCA1LCAzLCA2LCAxNCwgMTEsIDUsIDAsIDAsIDE0LCAxMiwgOSwgNywgMixcbiAgNywgMiwgMTEsIDEsIDQsIDE0LCAxLCA3LCA5LCA0LCAxMiwgMTAsIDE0LCA4LCAyLCAxMyxcbiAgMCwgMTUsIDYsIDEyLCAxMCwgOSwgMTMsIDAsIDE1LCAzLCAzLCA1LCA1LCA2LCA4LCAxMVxuXTtcblxuZXhwb3J0cy5zdWJzdGl0dXRlID0gZnVuY3Rpb24gc3Vic3RpdHV0ZShpbkwsIGluUikge1xuICB2YXIgb3V0ID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICB2YXIgYiA9IChpbkwgPj4+ICgxOCAtIGkgKiA2KSkgJiAweDNmO1xuICAgIHZhciBzYiA9IHNUYWJsZVtpICogMHg0MCArIGJdO1xuXG4gICAgb3V0IDw8PSA0O1xuICAgIG91dCB8PSBzYjtcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIHZhciBiID0gKGluUiA+Pj4gKDE4IC0gaSAqIDYpKSAmIDB4M2Y7XG4gICAgdmFyIHNiID0gc1RhYmxlWzQgKiAweDQwICsgaSAqIDB4NDAgKyBiXTtcblxuICAgIG91dCA8PD0gNDtcbiAgICBvdXQgfD0gc2I7XG4gIH1cbiAgcmV0dXJuIG91dCA+Pj4gMDtcbn07XG5cbnZhciBwZXJtdXRlVGFibGUgPSBbXG4gIDE2LCAyNSwgMTIsIDExLCAzLCAyMCwgNCwgMTUsIDMxLCAxNywgOSwgNiwgMjcsIDE0LCAxLCAyMixcbiAgMzAsIDI0LCA4LCAxOCwgMCwgNSwgMjksIDIzLCAxMywgMTksIDIsIDI2LCAxMCwgMjEsIDI4LCA3XG5dO1xuXG5leHBvcnRzLnBlcm11dGUgPSBmdW5jdGlvbiBwZXJtdXRlKG51bSkge1xuICB2YXIgb3V0ID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwZXJtdXRlVGFibGUubGVuZ3RoOyBpKyspIHtcbiAgICBvdXQgPDw9IDE7XG4gICAgb3V0IHw9IChudW0gPj4+IHBlcm11dGVUYWJsZVtpXSkgJiAweDE7XG4gIH1cbiAgcmV0dXJuIG91dCA+Pj4gMDtcbn07XG5cbmV4cG9ydHMucGFkU3BsaXQgPSBmdW5jdGlvbiBwYWRTcGxpdChudW0sIHNpemUsIGdyb3VwKSB7XG4gIHZhciBzdHIgPSBudW0udG9TdHJpbmcoMik7XG4gIHdoaWxlIChzdHIubGVuZ3RoIDwgc2l6ZSlcbiAgICBzdHIgPSAnMCcgKyBzdHI7XG5cbiAgdmFyIG91dCA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7IGkgKz0gZ3JvdXApXG4gICAgb3V0LnB1c2goc3RyLnNsaWNlKGksIGkgKyBncm91cCkpO1xuICByZXR1cm4gb3V0LmpvaW4oJyAnKTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGFzc2VydDtcblxuZnVuY3Rpb24gYXNzZXJ0KHZhbCwgbXNnKSB7XG4gIGlmICghdmFsKVxuICAgIHRocm93IG5ldyBFcnJvcihtc2cgfHwgJ0Fzc2VydGlvbiBmYWlsZWQnKTtcbn1cblxuYXNzZXJ0LmVxdWFsID0gZnVuY3Rpb24gYXNzZXJ0RXF1YWwobCwgciwgbXNnKSB7XG4gIGlmIChsICE9IHIpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAoJ0Fzc2VydGlvbiBmYWlsZWQ6ICcgKyBsICsgJyAhPSAnICsgcikpO1xufTtcbiIsInZhciBtZDUgPSByZXF1aXJlKCdjcmVhdGUtaGFzaC9tZDUnKVxubW9kdWxlLmV4cG9ydHMgPSBFVlBfQnl0ZXNUb0tleVxuZnVuY3Rpb24gRVZQX0J5dGVzVG9LZXkgKHBhc3N3b3JkLCBzYWx0LCBrZXlMZW4sIGl2TGVuKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHBhc3N3b3JkKSkge1xuICAgIHBhc3N3b3JkID0gbmV3IEJ1ZmZlcihwYXNzd29yZCwgJ2JpbmFyeScpXG4gIH1cbiAgaWYgKHNhbHQgJiYgIUJ1ZmZlci5pc0J1ZmZlcihzYWx0KSkge1xuICAgIHNhbHQgPSBuZXcgQnVmZmVyKHNhbHQsICdiaW5hcnknKVxuICB9XG4gIGtleUxlbiA9IGtleUxlbiAvIDhcbiAgaXZMZW4gPSBpdkxlbiB8fCAwXG4gIHZhciBraSA9IDBcbiAgdmFyIGlpID0gMFxuICB2YXIga2V5ID0gbmV3IEJ1ZmZlcihrZXlMZW4pXG4gIHZhciBpdiA9IG5ldyBCdWZmZXIoaXZMZW4pXG4gIHZhciBhZGRtZCA9IDBcbiAgdmFyIG1kX2J1ZlxuICB2YXIgaVxuICB2YXIgYnVmcyA9IFtdXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgaWYgKGFkZG1kKysgPiAwKSB7XG4gICAgICBidWZzLnB1c2gobWRfYnVmKVxuICAgIH1cbiAgICBidWZzLnB1c2gocGFzc3dvcmQpXG4gICAgaWYgKHNhbHQpIHtcbiAgICAgIGJ1ZnMucHVzaChzYWx0KVxuICAgIH1cbiAgICBtZF9idWYgPSBtZDUoQnVmZmVyLmNvbmNhdChidWZzKSlcbiAgICBidWZzID0gW11cbiAgICBpID0gMFxuICAgIGlmIChrZXlMZW4gPiAwKSB7XG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBpZiAoa2V5TGVuID09PSAwKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAga2V5W2tpKytdID0gbWRfYnVmW2ldXG4gICAgICAgIGtleUxlbi0tXG4gICAgICAgIGkrK1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXZMZW4gPiAwICYmIGkgIT09IG1kX2J1Zi5sZW5ndGgpIHtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGlmIChpdkxlbiA9PT0gMCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGkgPT09IG1kX2J1Zi5sZW5ndGgpIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGl2W2lpKytdID0gbWRfYnVmW2ldXG4gICAgICAgIGl2TGVuLS1cbiAgICAgICAgaSsrXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChrZXlMZW4gPT09IDAgJiYgaXZMZW4gPT09IDApIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG4gIGZvciAoaSA9IDA7IGkgPCBtZF9idWYubGVuZ3RoOyBpKyspIHtcbiAgICBtZF9idWZbaV0gPSAwXG4gIH1cbiAgcmV0dXJuIHtcbiAgICBrZXk6IGtleSxcbiAgICBpdjogaXZcbiAgfVxufVxuIiwiJ3VzZSBzdHJpY3QnXG5leHBvcnRzWydSU0EtU0hBMjI0J10gPSBleHBvcnRzLnNoYTIyNFdpdGhSU0FFbmNyeXB0aW9uID0ge1xuICBzaWduOiAncnNhJyxcbiAgaGFzaDogJ3NoYTIyNCcsXG4gIGlkOiBuZXcgQnVmZmVyKCczMDJkMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDQwNTAwMDQxYycsICdoZXgnKVxufVxuZXhwb3J0c1snUlNBLVNIQTI1NiddID0gZXhwb3J0cy5zaGEyNTZXaXRoUlNBRW5jcnlwdGlvbiA9IHtcbiAgc2lnbjogJ3JzYScsXG4gIGhhc2g6ICdzaGEyNTYnLFxuICBpZDogbmV3IEJ1ZmZlcignMzAzMTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAxMDUwMDA0MjAnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ1JTQS1TSEEzODQnXSA9IGV4cG9ydHMuc2hhMzg0V2l0aFJTQUVuY3J5cHRpb24gPSB7XG4gIHNpZ246ICdyc2EnLFxuICBoYXNoOiAnc2hhMzg0JyxcbiAgaWQ6IG5ldyBCdWZmZXIoJzMwNDEzMDBkMDYwOTYwODY0ODAxNjUwMzA0MDIwMjA1MDAwNDMwJywgJ2hleCcpXG59XG5leHBvcnRzWydSU0EtU0hBNTEyJ10gPSBleHBvcnRzLnNoYTUxMldpdGhSU0FFbmNyeXB0aW9uID0ge1xuICBzaWduOiAncnNhJyxcbiAgaGFzaDogJ3NoYTUxMicsXG4gIGlkOiBuZXcgQnVmZmVyKCczMDUxMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDMwNTAwMDQ0MCcsICdoZXgnKVxufVxuZXhwb3J0c1snUlNBLVNIQTEnXSA9IHtcbiAgc2lnbjogJ3JzYScsXG4gIGhhc2g6ICdzaGExJyxcbiAgaWQ6IG5ldyBCdWZmZXIoJzMwMjEzMDA5MDYwNTJiMGUwMzAyMWEwNTAwMDQxNCcsICdoZXgnKVxufVxuZXhwb3J0c1snZWNkc2Etd2l0aC1TSEExJ10gPSB7XG4gIHNpZ246ICdlY2RzYScsXG4gIGhhc2g6ICdzaGExJyxcbiAgaWQ6IG5ldyBCdWZmZXIoJycsICdoZXgnKVxufVxuXG5leHBvcnRzLkRTQSA9IGV4cG9ydHNbJ0RTQS1TSEExJ10gPSBleHBvcnRzWydEU0EtU0hBJ10gPSB7XG4gIHNpZ246ICdkc2EnLFxuICBoYXNoOiAnc2hhMScsXG4gIGlkOiBuZXcgQnVmZmVyKCcnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ0RTQS1TSEEyMjQnXSA9IGV4cG9ydHNbJ0RTQS1XSVRILVNIQTIyNCddID0ge1xuICBzaWduOiAnZHNhJyxcbiAgaGFzaDogJ3NoYTIyNCcsXG4gIGlkOiBuZXcgQnVmZmVyKCcnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ0RTQS1TSEEyNTYnXSA9IGV4cG9ydHNbJ0RTQS1XSVRILVNIQTI1NiddID0ge1xuICBzaWduOiAnZHNhJyxcbiAgaGFzaDogJ3NoYTI1NicsXG4gIGlkOiBuZXcgQnVmZmVyKCcnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ0RTQS1TSEEzODQnXSA9IGV4cG9ydHNbJ0RTQS1XSVRILVNIQTM4NCddID0ge1xuICBzaWduOiAnZHNhJyxcbiAgaGFzaDogJ3NoYTM4NCcsXG4gIGlkOiBuZXcgQnVmZmVyKCcnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ0RTQS1TSEE1MTInXSA9IGV4cG9ydHNbJ0RTQS1XSVRILVNIQTUxMiddID0ge1xuICBzaWduOiAnZHNhJyxcbiAgaGFzaDogJ3NoYTUxMicsXG4gIGlkOiBuZXcgQnVmZmVyKCcnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ0RTQS1SSVBFTUQxNjAnXSA9IHtcbiAgc2lnbjogJ2RzYScsXG4gIGhhc2g6ICdybWQxNjAnLFxuICBpZDogbmV3IEJ1ZmZlcignJywgJ2hleCcpXG59XG5leHBvcnRzWydSU0EtUklQRU1EMTYwJ10gPSBleHBvcnRzLnJpcGVtZDE2MFdpdGhSU0EgPSB7XG4gIHNpZ246ICdyc2EnLFxuICBoYXNoOiAncm1kMTYwJyxcbiAgaWQ6IG5ldyBCdWZmZXIoJzMwMjEzMDA5MDYwNTJiMjQwMzAyMDEwNTAwMDQxNCcsICdoZXgnKVxufVxuZXhwb3J0c1snUlNBLU1ENSddID0gZXhwb3J0cy5tZDVXaXRoUlNBRW5jcnlwdGlvbiA9IHtcbiAgc2lnbjogJ3JzYScsXG4gIGhhc2g6ICdtZDUnLFxuICBpZDogbmV3IEJ1ZmZlcignMzAyMDMwMGMwNjA4MmE4NjQ4ODZmNzBkMDIwNTA1MDAwNDEwJywgJ2hleCcpXG59XG4iLCJ2YXIgX2FsZ29zID0gcmVxdWlyZSgnLi9hbGdvcycpXG52YXIgY3JlYXRlSGFzaCA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoJylcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBzaWduID0gcmVxdWlyZSgnLi9zaWduJylcbnZhciBzdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKVxudmFyIHZlcmlmeSA9IHJlcXVpcmUoJy4vdmVyaWZ5JylcblxudmFyIGFsZ29zID0ge31cbk9iamVjdC5rZXlzKF9hbGdvcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gIGFsZ29zW2tleV0gPSBhbGdvc1trZXkudG9Mb3dlckNhc2UoKV0gPSBfYWxnb3Nba2V5XVxufSlcblxuZnVuY3Rpb24gU2lnbiAoYWxnb3JpdGhtKSB7XG4gIHN0cmVhbS5Xcml0YWJsZS5jYWxsKHRoaXMpXG5cbiAgdmFyIGRhdGEgPSBhbGdvc1thbGdvcml0aG1dXG4gIGlmICghZGF0YSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBtZXNzYWdlIGRpZ2VzdCcpXG4gIH1cblxuICB0aGlzLl9oYXNoVHlwZSA9IGRhdGEuaGFzaFxuICB0aGlzLl9oYXNoID0gY3JlYXRlSGFzaChkYXRhLmhhc2gpXG4gIHRoaXMuX3RhZyA9IGRhdGEuaWRcbiAgdGhpcy5fc2lnblR5cGUgPSBkYXRhLnNpZ25cbn1cbmluaGVyaXRzKFNpZ24sIHN0cmVhbS5Xcml0YWJsZSlcblxuU2lnbi5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gX3dyaXRlIChkYXRhLCBfLCBkb25lKSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG4gIGRvbmUoKVxufVxuXG5TaWduLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUgKGRhdGEsIGVuYykge1xuICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSwgZW5jKVxuICB9XG5cbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbiAgcmV0dXJuIHRoaXNcbn1cblxuU2lnbi5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ25NZXRob2QgKGtleSwgZW5jKSB7XG4gIHRoaXMuZW5kKClcbiAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoLmRpZ2VzdCgpXG4gIHZhciBzaWcgPSBzaWduKEJ1ZmZlci5jb25jYXQoW3RoaXMuX3RhZywgaGFzaF0pLCBrZXksIHRoaXMuX2hhc2hUeXBlLCB0aGlzLl9zaWduVHlwZSlcblxuICByZXR1cm4gZW5jID8gc2lnLnRvU3RyaW5nKGVuYykgOiBzaWdcbn1cblxuZnVuY3Rpb24gVmVyaWZ5IChhbGdvcml0aG0pIHtcbiAgc3RyZWFtLldyaXRhYmxlLmNhbGwodGhpcylcblxuICB2YXIgZGF0YSA9IGFsZ29zW2FsZ29yaXRobV1cbiAgaWYgKCFkYXRhKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIG1lc3NhZ2UgZGlnZXN0JylcbiAgfVxuXG4gIHRoaXMuX2hhc2ggPSBjcmVhdGVIYXNoKGRhdGEuaGFzaClcbiAgdGhpcy5fdGFnID0gZGF0YS5pZFxuICB0aGlzLl9zaWduVHlwZSA9IGRhdGEuc2lnblxufVxuaW5oZXJpdHMoVmVyaWZ5LCBzdHJlYW0uV3JpdGFibGUpXG5cblZlcmlmeS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gX3dyaXRlIChkYXRhLCBfLCBkb25lKSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG5cbiAgZG9uZSgpXG59XG5cblZlcmlmeS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlIChkYXRhLCBlbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGVuYylcbiAgfVxuXG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG4gIHJldHVybiB0aGlzXG59XG5cblZlcmlmeS5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5TWV0aG9kIChrZXksIHNpZywgZW5jKSB7XG4gIGlmICh0eXBlb2Ygc2lnID09PSAnc3RyaW5nJykge1xuICAgIHNpZyA9IG5ldyBCdWZmZXIoc2lnLCBlbmMpXG4gIH1cblxuICB0aGlzLmVuZCgpXG4gIHZhciBoYXNoID0gdGhpcy5faGFzaC5kaWdlc3QoKVxuXG4gIHJldHVybiB2ZXJpZnkoc2lnLCBCdWZmZXIuY29uY2F0KFt0aGlzLl90YWcsIGhhc2hdKSwga2V5LCB0aGlzLl9zaWduVHlwZSlcbn1cblxuZnVuY3Rpb24gY3JlYXRlU2lnbiAoYWxnb3JpdGhtKSB7XG4gIHJldHVybiBuZXcgU2lnbihhbGdvcml0aG0pXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZlcmlmeSAoYWxnb3JpdGhtKSB7XG4gIHJldHVybiBuZXcgVmVyaWZ5KGFsZ29yaXRobSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIFNpZ246IGNyZWF0ZVNpZ24sXG4gIFZlcmlmeTogY3JlYXRlVmVyaWZ5LFxuICBjcmVhdGVTaWduOiBjcmVhdGVTaWduLFxuICBjcmVhdGVWZXJpZnk6IGNyZWF0ZVZlcmlmeVxufVxuIiwiJ3VzZSBzdHJpY3QnXG5leHBvcnRzWycxLjMuMTMyLjAuMTAnXSA9ICdzZWNwMjU2azEnXG5cbmV4cG9ydHNbJzEuMy4xMzIuMC4zMyddID0gJ3AyMjQnXG5cbmV4cG9ydHNbJzEuMi44NDAuMTAwNDUuMy4xLjEnXSA9ICdwMTkyJ1xuXG5leHBvcnRzWycxLjIuODQwLjEwMDQ1LjMuMS43J10gPSAncDI1NidcblxuZXhwb3J0c1snMS4zLjEzMi4wLjM0J10gPSAncDM4NCdcblxuZXhwb3J0c1snMS4zLjEzMi4wLjM1J10gPSAncDUyMSdcbiIsIihmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvLyBVdGlsc1xuICBmdW5jdGlvbiBhc3NlcnQgKHZhbCwgbXNnKSB7XG4gICAgaWYgKCF2YWwpIHRocm93IG5ldyBFcnJvcihtc2cgfHwgJ0Fzc2VydGlvbiBmYWlsZWQnKTtcbiAgfVxuXG4gIC8vIENvdWxkIHVzZSBgaW5oZXJpdHNgIG1vZHVsZSwgYnV0IGRvbid0IHdhbnQgdG8gbW92ZSBmcm9tIHNpbmdsZSBmaWxlXG4gIC8vIGFyY2hpdGVjdHVyZSB5ZXQuXG4gIGZ1bmN0aW9uIGluaGVyaXRzIChjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvcjtcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlO1xuICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKCk7XG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yO1xuICB9XG5cbiAgLy8gQk5cblxuICBmdW5jdGlvbiBCTiAobnVtYmVyLCBiYXNlLCBlbmRpYW4pIHtcbiAgICBpZiAoQk4uaXNCTihudW1iZXIpKSB7XG4gICAgICByZXR1cm4gbnVtYmVyO1xuICAgIH1cblxuICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgIHRoaXMud29yZHMgPSBudWxsO1xuICAgIHRoaXMubGVuZ3RoID0gMDtcblxuICAgIC8vIFJlZHVjdGlvbiBjb250ZXh0XG4gICAgdGhpcy5yZWQgPSBudWxsO1xuXG4gICAgaWYgKG51bWJlciAhPT0gbnVsbCkge1xuICAgICAgaWYgKGJhc2UgPT09ICdsZScgfHwgYmFzZSA9PT0gJ2JlJykge1xuICAgICAgICBlbmRpYW4gPSBiYXNlO1xuICAgICAgICBiYXNlID0gMTA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2luaXQobnVtYmVyIHx8IDAsIGJhc2UgfHwgMTAsIGVuZGlhbiB8fCAnYmUnKTtcbiAgICB9XG4gIH1cbiAgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBCTjtcbiAgfSBlbHNlIHtcbiAgICBleHBvcnRzLkJOID0gQk47XG4gIH1cblxuICBCTi5CTiA9IEJOO1xuICBCTi53b3JkU2l6ZSA9IDI2O1xuXG4gIHZhciBCdWZmZXI7XG4gIHRyeSB7XG4gICAgQnVmZmVyID0gcmVxdWlyZSgnYnVmJyArICdmZXInKS5CdWZmZXI7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgfVxuXG4gIEJOLmlzQk4gPSBmdW5jdGlvbiBpc0JOIChudW0pIHtcbiAgICByZXR1cm4gbnVtICE9PSBudWxsICYmIHR5cGVvZiBudW0gPT09ICdvYmplY3QnICYmXG4gICAgICBudW0uY29uc3RydWN0b3IubmFtZSA9PT0gJ0JOJyAmJiBBcnJheS5pc0FycmF5KG51bS53b3Jkcyk7XG4gIH07XG5cbiAgQk4ubWF4ID0gZnVuY3Rpb24gbWF4IChsZWZ0LCByaWdodCkge1xuICAgIGlmIChsZWZ0LmNtcChyaWdodCkgPiAwKSByZXR1cm4gbGVmdDtcbiAgICByZXR1cm4gcmlnaHQ7XG4gIH07XG5cbiAgQk4ubWluID0gZnVuY3Rpb24gbWluIChsZWZ0LCByaWdodCkge1xuICAgIGlmIChsZWZ0LmNtcChyaWdodCkgPCAwKSByZXR1cm4gbGVmdDtcbiAgICByZXR1cm4gcmlnaHQ7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gaW5pdCAobnVtYmVyLCBiYXNlLCBlbmRpYW4pIHtcbiAgICBpZiAodHlwZW9mIG51bWJlciA9PT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pbml0TnVtYmVyKG51bWJlciwgYmFzZSwgZW5kaWFuKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG51bWJlciA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pbml0QXJyYXkobnVtYmVyLCBiYXNlLCBlbmRpYW4pO1xuICAgIH1cblxuICAgIGlmIChiYXNlID09PSAnaGV4Jykge1xuICAgICAgYmFzZSA9IDE2O1xuICAgIH1cbiAgICBhc3NlcnQoYmFzZSA9PT0gKGJhc2UgfCAwKSAmJiBiYXNlID49IDIgJiYgYmFzZSA8PSAzNik7XG5cbiAgICBudW1iZXIgPSBudW1iZXIudG9TdHJpbmcoKS5yZXBsYWNlKC9cXHMrL2csICcnKTtcbiAgICB2YXIgc3RhcnQgPSAwO1xuICAgIGlmIChudW1iZXJbMF0gPT09ICctJykge1xuICAgICAgc3RhcnQrKztcbiAgICB9XG5cbiAgICBpZiAoYmFzZSA9PT0gMTYpIHtcbiAgICAgIHRoaXMuX3BhcnNlSGV4KG51bWJlciwgc3RhcnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9wYXJzZUJhc2UobnVtYmVyLCBiYXNlLCBzdGFydCk7XG4gICAgfVxuXG4gICAgaWYgKG51bWJlclswXSA9PT0gJy0nKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICB9XG5cbiAgICB0aGlzLnN0cmlwKCk7XG5cbiAgICBpZiAoZW5kaWFuICE9PSAnbGUnKSByZXR1cm47XG5cbiAgICB0aGlzLl9pbml0QXJyYXkodGhpcy50b0FycmF5KCksIGJhc2UsIGVuZGlhbik7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9pbml0TnVtYmVyID0gZnVuY3Rpb24gX2luaXROdW1iZXIgKG51bWJlciwgYmFzZSwgZW5kaWFuKSB7XG4gICAgaWYgKG51bWJlciA8IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgICAgbnVtYmVyID0gLW51bWJlcjtcbiAgICB9XG4gICAgaWYgKG51bWJlciA8IDB4NDAwMDAwMCkge1xuICAgICAgdGhpcy53b3JkcyA9IFsgbnVtYmVyICYgMHgzZmZmZmZmIF07XG4gICAgICB0aGlzLmxlbmd0aCA9IDE7XG4gICAgfSBlbHNlIGlmIChudW1iZXIgPCAweDEwMDAwMDAwMDAwMDAwKSB7XG4gICAgICB0aGlzLndvcmRzID0gW1xuICAgICAgICBudW1iZXIgJiAweDNmZmZmZmYsXG4gICAgICAgIChudW1iZXIgLyAweDQwMDAwMDApICYgMHgzZmZmZmZmXG4gICAgICBdO1xuICAgICAgdGhpcy5sZW5ndGggPSAyO1xuICAgIH0gZWxzZSB7XG4gICAgICBhc3NlcnQobnVtYmVyIDwgMHgyMDAwMDAwMDAwMDAwMCk7IC8vIDIgXiA1MyAodW5zYWZlKVxuICAgICAgdGhpcy53b3JkcyA9IFtcbiAgICAgICAgbnVtYmVyICYgMHgzZmZmZmZmLFxuICAgICAgICAobnVtYmVyIC8gMHg0MDAwMDAwKSAmIDB4M2ZmZmZmZixcbiAgICAgICAgMVxuICAgICAgXTtcbiAgICAgIHRoaXMubGVuZ3RoID0gMztcbiAgICB9XG5cbiAgICBpZiAoZW5kaWFuICE9PSAnbGUnKSByZXR1cm47XG5cbiAgICAvLyBSZXZlcnNlIHRoZSBieXRlc1xuICAgIHRoaXMuX2luaXRBcnJheSh0aGlzLnRvQXJyYXkoKSwgYmFzZSwgZW5kaWFuKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX2luaXRBcnJheSA9IGZ1bmN0aW9uIF9pbml0QXJyYXkgKG51bWJlciwgYmFzZSwgZW5kaWFuKSB7XG4gICAgLy8gUGVyaGFwcyBhIFVpbnQ4QXJyYXlcbiAgICBhc3NlcnQodHlwZW9mIG51bWJlci5sZW5ndGggPT09ICdudW1iZXInKTtcbiAgICBpZiAobnVtYmVyLmxlbmd0aCA8PSAwKSB7XG4gICAgICB0aGlzLndvcmRzID0gWyAwIF07XG4gICAgICB0aGlzLmxlbmd0aCA9IDE7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB0aGlzLmxlbmd0aCA9IE1hdGguY2VpbChudW1iZXIubGVuZ3RoIC8gMyk7XG4gICAgdGhpcy53b3JkcyA9IG5ldyBBcnJheSh0aGlzLmxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gMDtcbiAgICB9XG5cbiAgICB2YXIgaiwgdztcbiAgICB2YXIgb2ZmID0gMDtcbiAgICBpZiAoZW5kaWFuID09PSAnYmUnKSB7XG4gICAgICBmb3IgKGkgPSBudW1iZXIubGVuZ3RoIC0gMSwgaiA9IDA7IGkgPj0gMDsgaSAtPSAzKSB7XG4gICAgICAgIHcgPSBudW1iZXJbaV0gfCAobnVtYmVyW2kgLSAxXSA8PCA4KSB8IChudW1iZXJbaSAtIDJdIDw8IDE2KTtcbiAgICAgICAgdGhpcy53b3Jkc1tqXSB8PSAodyA8PCBvZmYpICYgMHgzZmZmZmZmO1xuICAgICAgICB0aGlzLndvcmRzW2ogKyAxXSA9ICh3ID4+PiAoMjYgLSBvZmYpKSAmIDB4M2ZmZmZmZjtcbiAgICAgICAgb2ZmICs9IDI0O1xuICAgICAgICBpZiAob2ZmID49IDI2KSB7XG4gICAgICAgICAgb2ZmIC09IDI2O1xuICAgICAgICAgIGorKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZW5kaWFuID09PSAnbGUnKSB7XG4gICAgICBmb3IgKGkgPSAwLCBqID0gMDsgaSA8IG51bWJlci5sZW5ndGg7IGkgKz0gMykge1xuICAgICAgICB3ID0gbnVtYmVyW2ldIHwgKG51bWJlcltpICsgMV0gPDwgOCkgfCAobnVtYmVyW2kgKyAyXSA8PCAxNik7XG4gICAgICAgIHRoaXMud29yZHNbal0gfD0gKHcgPDwgb2ZmKSAmIDB4M2ZmZmZmZjtcbiAgICAgICAgdGhpcy53b3Jkc1tqICsgMV0gPSAodyA+Pj4gKDI2IC0gb2ZmKSkgJiAweDNmZmZmZmY7XG4gICAgICAgIG9mZiArPSAyNDtcbiAgICAgICAgaWYgKG9mZiA+PSAyNikge1xuICAgICAgICAgIG9mZiAtPSAyNjtcbiAgICAgICAgICBqKys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBmdW5jdGlvbiBwYXJzZUhleCAoc3RyLCBzdGFydCwgZW5kKSB7XG4gICAgdmFyIHIgPSAwO1xuICAgIHZhciBsZW4gPSBNYXRoLm1pbihzdHIubGVuZ3RoLCBlbmQpO1xuICAgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB2YXIgYyA9IHN0ci5jaGFyQ29kZUF0KGkpIC0gNDg7XG5cbiAgICAgIHIgPDw9IDQ7XG5cbiAgICAgIC8vICdhJyAtICdmJ1xuICAgICAgaWYgKGMgPj0gNDkgJiYgYyA8PSA1NCkge1xuICAgICAgICByIHw9IGMgLSA0OSArIDB4YTtcblxuICAgICAgLy8gJ0EnIC0gJ0YnXG4gICAgICB9IGVsc2UgaWYgKGMgPj0gMTcgJiYgYyA8PSAyMikge1xuICAgICAgICByIHw9IGMgLSAxNyArIDB4YTtcblxuICAgICAgLy8gJzAnIC0gJzknXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByIHw9IGMgJiAweGY7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9XG5cbiAgQk4ucHJvdG90eXBlLl9wYXJzZUhleCA9IGZ1bmN0aW9uIF9wYXJzZUhleCAobnVtYmVyLCBzdGFydCkge1xuICAgIC8vIENyZWF0ZSBwb3NzaWJseSBiaWdnZXIgYXJyYXkgdG8gZW5zdXJlIHRoYXQgaXQgZml0cyB0aGUgbnVtYmVyXG4gICAgdGhpcy5sZW5ndGggPSBNYXRoLmNlaWwoKG51bWJlci5sZW5ndGggLSBzdGFydCkgLyA2KTtcbiAgICB0aGlzLndvcmRzID0gbmV3IEFycmF5KHRoaXMubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSAwO1xuICAgIH1cblxuICAgIHZhciBqLCB3O1xuICAgIC8vIFNjYW4gMjQtYml0IGNodW5rcyBhbmQgYWRkIHRoZW0gdG8gdGhlIG51bWJlclxuICAgIHZhciBvZmYgPSAwO1xuICAgIGZvciAoaSA9IG51bWJlci5sZW5ndGggLSA2LCBqID0gMDsgaSA+PSBzdGFydDsgaSAtPSA2KSB7XG4gICAgICB3ID0gcGFyc2VIZXgobnVtYmVyLCBpLCBpICsgNik7XG4gICAgICB0aGlzLndvcmRzW2pdIHw9ICh3IDw8IG9mZikgJiAweDNmZmZmZmY7XG4gICAgICAvLyBOT1RFOiBgMHgzZmZmZmZgIGlzIGludGVudGlvbmFsIGhlcmUsIDI2Yml0cyBtYXggc2hpZnQgKyAyNGJpdCBoZXggbGltYlxuICAgICAgdGhpcy53b3Jkc1tqICsgMV0gfD0gdyA+Pj4gKDI2IC0gb2ZmKSAmIDB4M2ZmZmZmO1xuICAgICAgb2ZmICs9IDI0O1xuICAgICAgaWYgKG9mZiA+PSAyNikge1xuICAgICAgICBvZmYgLT0gMjY7XG4gICAgICAgIGorKztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGkgKyA2ICE9PSBzdGFydCkge1xuICAgICAgdyA9IHBhcnNlSGV4KG51bWJlciwgc3RhcnQsIGkgKyA2KTtcbiAgICAgIHRoaXMud29yZHNbal0gfD0gKHcgPDwgb2ZmKSAmIDB4M2ZmZmZmZjtcbiAgICAgIHRoaXMud29yZHNbaiArIDFdIHw9IHcgPj4+ICgyNiAtIG9mZikgJiAweDNmZmZmZjtcbiAgICB9XG4gICAgdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHBhcnNlQmFzZSAoc3RyLCBzdGFydCwgZW5kLCBtdWwpIHtcbiAgICB2YXIgciA9IDA7XG4gICAgdmFyIGxlbiA9IE1hdGgubWluKHN0ci5sZW5ndGgsIGVuZCk7XG4gICAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHZhciBjID0gc3RyLmNoYXJDb2RlQXQoaSkgLSA0ODtcblxuICAgICAgciAqPSBtdWw7XG5cbiAgICAgIC8vICdhJ1xuICAgICAgaWYgKGMgPj0gNDkpIHtcbiAgICAgICAgciArPSBjIC0gNDkgKyAweGE7XG5cbiAgICAgIC8vICdBJ1xuICAgICAgfSBlbHNlIGlmIChjID49IDE3KSB7XG4gICAgICAgIHIgKz0gYyAtIDE3ICsgMHhhO1xuXG4gICAgICAvLyAnMCcgLSAnOSdcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHIgKz0gYztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHI7XG4gIH1cblxuICBCTi5wcm90b3R5cGUuX3BhcnNlQmFzZSA9IGZ1bmN0aW9uIF9wYXJzZUJhc2UgKG51bWJlciwgYmFzZSwgc3RhcnQpIHtcbiAgICAvLyBJbml0aWFsaXplIGFzIHplcm9cbiAgICB0aGlzLndvcmRzID0gWyAwIF07XG4gICAgdGhpcy5sZW5ndGggPSAxO1xuXG4gICAgLy8gRmluZCBsZW5ndGggb2YgbGltYiBpbiBiYXNlXG4gICAgZm9yICh2YXIgbGltYkxlbiA9IDAsIGxpbWJQb3cgPSAxOyBsaW1iUG93IDw9IDB4M2ZmZmZmZjsgbGltYlBvdyAqPSBiYXNlKSB7XG4gICAgICBsaW1iTGVuKys7XG4gICAgfVxuICAgIGxpbWJMZW4tLTtcbiAgICBsaW1iUG93ID0gKGxpbWJQb3cgLyBiYXNlKSB8IDA7XG5cbiAgICB2YXIgdG90YWwgPSBudW1iZXIubGVuZ3RoIC0gc3RhcnQ7XG4gICAgdmFyIG1vZCA9IHRvdGFsICUgbGltYkxlbjtcbiAgICB2YXIgZW5kID0gTWF0aC5taW4odG90YWwsIHRvdGFsIC0gbW9kKSArIHN0YXJ0O1xuXG4gICAgdmFyIHdvcmQgPSAwO1xuICAgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSArPSBsaW1iTGVuKSB7XG4gICAgICB3b3JkID0gcGFyc2VCYXNlKG51bWJlciwgaSwgaSArIGxpbWJMZW4sIGJhc2UpO1xuXG4gICAgICB0aGlzLmltdWxuKGxpbWJQb3cpO1xuICAgICAgaWYgKHRoaXMud29yZHNbMF0gKyB3b3JkIDwgMHg0MDAwMDAwKSB7XG4gICAgICAgIHRoaXMud29yZHNbMF0gKz0gd29yZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2lhZGRuKHdvcmQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtb2QgIT09IDApIHtcbiAgICAgIHZhciBwb3cgPSAxO1xuICAgICAgd29yZCA9IHBhcnNlQmFzZShudW1iZXIsIGksIG51bWJlci5sZW5ndGgsIGJhc2UpO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbW9kOyBpKyspIHtcbiAgICAgICAgcG93ICo9IGJhc2U7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuaW11bG4ocG93KTtcbiAgICAgIGlmICh0aGlzLndvcmRzWzBdICsgd29yZCA8IDB4NDAwMDAwMCkge1xuICAgICAgICB0aGlzLndvcmRzWzBdICs9IHdvcmQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9pYWRkbih3b3JkKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5IChkZXN0KSB7XG4gICAgZGVzdC53b3JkcyA9IG5ldyBBcnJheSh0aGlzLmxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBkZXN0LndvcmRzW2ldID0gdGhpcy53b3Jkc1tpXTtcbiAgICB9XG4gICAgZGVzdC5sZW5ndGggPSB0aGlzLmxlbmd0aDtcbiAgICBkZXN0Lm5lZ2F0aXZlID0gdGhpcy5uZWdhdGl2ZTtcbiAgICBkZXN0LnJlZCA9IHRoaXMucmVkO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uIGNsb25lICgpIHtcbiAgICB2YXIgciA9IG5ldyBCTihudWxsKTtcbiAgICB0aGlzLmNvcHkocik7XG4gICAgcmV0dXJuIHI7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9leHBhbmQgPSBmdW5jdGlvbiBfZXhwYW5kIChzaXplKSB7XG4gICAgd2hpbGUgKHRoaXMubGVuZ3RoIDwgc2l6ZSkge1xuICAgICAgdGhpcy53b3Jkc1t0aGlzLmxlbmd0aCsrXSA9IDA7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8vIFJlbW92ZSBsZWFkaW5nIGAwYCBmcm9tIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuc3RyaXAgPSBmdW5jdGlvbiBzdHJpcCAoKSB7XG4gICAgd2hpbGUgKHRoaXMubGVuZ3RoID4gMSAmJiB0aGlzLndvcmRzW3RoaXMubGVuZ3RoIC0gMV0gPT09IDApIHtcbiAgICAgIHRoaXMubGVuZ3RoLS07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9ub3JtU2lnbigpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5fbm9ybVNpZ24gPSBmdW5jdGlvbiBfbm9ybVNpZ24gKCkge1xuICAgIC8vIC0wID0gMFxuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSAmJiB0aGlzLndvcmRzWzBdID09PSAwKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgICByZXR1cm4gKHRoaXMucmVkID8gJzxCTi1SOiAnIDogJzxCTjogJykgKyB0aGlzLnRvU3RyaW5nKDE2KSArICc+JztcbiAgfTtcblxuICAvKlxuXG4gIHZhciB6ZXJvcyA9IFtdO1xuICB2YXIgZ3JvdXBTaXplcyA9IFtdO1xuICB2YXIgZ3JvdXBCYXNlcyA9IFtdO1xuXG4gIHZhciBzID0gJyc7XG4gIHZhciBpID0gLTE7XG4gIHdoaWxlICgrK2kgPCBCTi53b3JkU2l6ZSkge1xuICAgIHplcm9zW2ldID0gcztcbiAgICBzICs9ICcwJztcbiAgfVxuICBncm91cFNpemVzWzBdID0gMDtcbiAgZ3JvdXBTaXplc1sxXSA9IDA7XG4gIGdyb3VwQmFzZXNbMF0gPSAwO1xuICBncm91cEJhc2VzWzFdID0gMDtcbiAgdmFyIGJhc2UgPSAyIC0gMTtcbiAgd2hpbGUgKCsrYmFzZSA8IDM2ICsgMSkge1xuICAgIHZhciBncm91cFNpemUgPSAwO1xuICAgIHZhciBncm91cEJhc2UgPSAxO1xuICAgIHdoaWxlIChncm91cEJhc2UgPCAoMSA8PCBCTi53b3JkU2l6ZSkgLyBiYXNlKSB7XG4gICAgICBncm91cEJhc2UgKj0gYmFzZTtcbiAgICAgIGdyb3VwU2l6ZSArPSAxO1xuICAgIH1cbiAgICBncm91cFNpemVzW2Jhc2VdID0gZ3JvdXBTaXplO1xuICAgIGdyb3VwQmFzZXNbYmFzZV0gPSBncm91cEJhc2U7XG4gIH1cblxuICAqL1xuXG4gIHZhciB6ZXJvcyA9IFtcbiAgICAnJyxcbiAgICAnMCcsXG4gICAgJzAwJyxcbiAgICAnMDAwJyxcbiAgICAnMDAwMCcsXG4gICAgJzAwMDAwJyxcbiAgICAnMDAwMDAwJyxcbiAgICAnMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCdcbiAgXTtcblxuICB2YXIgZ3JvdXBTaXplcyA9IFtcbiAgICAwLCAwLFxuICAgIDI1LCAxNiwgMTIsIDExLCAxMCwgOSwgOCxcbiAgICA4LCA3LCA3LCA3LCA3LCA2LCA2LFxuICAgIDYsIDYsIDYsIDYsIDYsIDUsIDUsXG4gICAgNSwgNSwgNSwgNSwgNSwgNSwgNSxcbiAgICA1LCA1LCA1LCA1LCA1LCA1LCA1XG4gIF07XG5cbiAgdmFyIGdyb3VwQmFzZXMgPSBbXG4gICAgMCwgMCxcbiAgICAzMzU1NDQzMiwgNDMwNDY3MjEsIDE2Nzc3MjE2LCA0ODgyODEyNSwgNjA0NjYxNzYsIDQwMzUzNjA3LCAxNjc3NzIxNixcbiAgICA0MzA0NjcyMSwgMTAwMDAwMDAsIDE5NDg3MTcxLCAzNTgzMTgwOCwgNjI3NDg1MTcsIDc1Mjk1MzYsIDExMzkwNjI1LFxuICAgIDE2Nzc3MjE2LCAyNDEzNzU2OSwgMzQwMTIyMjQsIDQ3MDQ1ODgxLCA2NDAwMDAwMCwgNDA4NDEwMSwgNTE1MzYzMixcbiAgICA2NDM2MzQzLCA3OTYyNjI0LCA5NzY1NjI1LCAxMTg4MTM3NiwgMTQzNDg5MDcsIDE3MjEwMzY4LCAyMDUxMTE0OSxcbiAgICAyNDMwMDAwMCwgMjg2MjkxNTEsIDMzNTU0NDMyLCAzOTEzNTM5MywgNDU0MzU0MjQsIDUyNTIxODc1LCA2MDQ2NjE3NlxuICBdO1xuXG4gIEJOLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nIChiYXNlLCBwYWRkaW5nKSB7XG4gICAgYmFzZSA9IGJhc2UgfHwgMTA7XG4gICAgcGFkZGluZyA9IHBhZGRpbmcgfCAwIHx8IDE7XG5cbiAgICB2YXIgb3V0O1xuICAgIGlmIChiYXNlID09PSAxNiB8fCBiYXNlID09PSAnaGV4Jykge1xuICAgICAgb3V0ID0gJyc7XG4gICAgICB2YXIgb2ZmID0gMDtcbiAgICAgIHZhciBjYXJyeSA9IDA7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHcgPSB0aGlzLndvcmRzW2ldO1xuICAgICAgICB2YXIgd29yZCA9ICgoKHcgPDwgb2ZmKSB8IGNhcnJ5KSAmIDB4ZmZmZmZmKS50b1N0cmluZygxNik7XG4gICAgICAgIGNhcnJ5ID0gKHcgPj4+ICgyNCAtIG9mZikpICYgMHhmZmZmZmY7XG4gICAgICAgIGlmIChjYXJyeSAhPT0gMCB8fCBpICE9PSB0aGlzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICBvdXQgPSB6ZXJvc1s2IC0gd29yZC5sZW5ndGhdICsgd29yZCArIG91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvdXQgPSB3b3JkICsgb3V0O1xuICAgICAgICB9XG4gICAgICAgIG9mZiArPSAyO1xuICAgICAgICBpZiAob2ZmID49IDI2KSB7XG4gICAgICAgICAgb2ZmIC09IDI2O1xuICAgICAgICAgIGktLTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICAgIG91dCA9IGNhcnJ5LnRvU3RyaW5nKDE2KSArIG91dDtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChvdXQubGVuZ3RoICUgcGFkZGluZyAhPT0gMCkge1xuICAgICAgICBvdXQgPSAnMCcgKyBvdXQ7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgICBvdXQgPSAnLScgKyBvdXQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0O1xuICAgIH1cblxuICAgIGlmIChiYXNlID09PSAoYmFzZSB8IDApICYmIGJhc2UgPj0gMiAmJiBiYXNlIDw9IDM2KSB7XG4gICAgICAvLyB2YXIgZ3JvdXBTaXplID0gTWF0aC5mbG9vcihCTi53b3JkU2l6ZSAqIE1hdGguTE4yIC8gTWF0aC5sb2coYmFzZSkpO1xuICAgICAgdmFyIGdyb3VwU2l6ZSA9IGdyb3VwU2l6ZXNbYmFzZV07XG4gICAgICAvLyB2YXIgZ3JvdXBCYXNlID0gTWF0aC5wb3coYmFzZSwgZ3JvdXBTaXplKTtcbiAgICAgIHZhciBncm91cEJhc2UgPSBncm91cEJhc2VzW2Jhc2VdO1xuICAgICAgb3V0ID0gJyc7XG4gICAgICB2YXIgYyA9IHRoaXMuY2xvbmUoKTtcbiAgICAgIGMubmVnYXRpdmUgPSAwO1xuICAgICAgd2hpbGUgKCFjLmlzWmVybygpKSB7XG4gICAgICAgIHZhciByID0gYy5tb2RuKGdyb3VwQmFzZSkudG9TdHJpbmcoYmFzZSk7XG4gICAgICAgIGMgPSBjLmlkaXZuKGdyb3VwQmFzZSk7XG5cbiAgICAgICAgaWYgKCFjLmlzWmVybygpKSB7XG4gICAgICAgICAgb3V0ID0gemVyb3NbZ3JvdXBTaXplIC0gci5sZW5ndGhdICsgciArIG91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvdXQgPSByICsgb3V0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5pc1plcm8oKSkge1xuICAgICAgICBvdXQgPSAnMCcgKyBvdXQ7XG4gICAgICB9XG4gICAgICB3aGlsZSAob3V0Lmxlbmd0aCAlIHBhZGRpbmcgIT09IDApIHtcbiAgICAgICAgb3V0ID0gJzAnICsgb3V0O1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgICAgb3V0ID0gJy0nICsgb3V0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG91dDtcbiAgICB9XG5cbiAgICBhc3NlcnQoZmFsc2UsICdCYXNlIHNob3VsZCBiZSBiZXR3ZWVuIDIgYW5kIDM2Jyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIgKCkge1xuICAgIHZhciByZXQgPSB0aGlzLndvcmRzWzBdO1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMikge1xuICAgICAgcmV0ICs9IHRoaXMud29yZHNbMV0gKiAweDQwMDAwMDA7XG4gICAgfSBlbHNlIGlmICh0aGlzLmxlbmd0aCA9PT0gMyAmJiB0aGlzLndvcmRzWzJdID09PSAweDAxKSB7XG4gICAgICAvLyBOT1RFOiBhdCB0aGlzIHN0YWdlIGl0IGlzIGtub3duIHRoYXQgdGhlIHRvcCBiaXQgaXMgc2V0XG4gICAgICByZXQgKz0gMHgxMDAwMDAwMDAwMDAwMCArICh0aGlzLndvcmRzWzFdICogMHg0MDAwMDAwKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubGVuZ3RoID4gMikge1xuICAgICAgYXNzZXJ0KGZhbHNlLCAnTnVtYmVyIGNhbiBvbmx5IHNhZmVseSBzdG9yZSB1cCB0byA1MyBiaXRzJyk7XG4gICAgfVxuICAgIHJldHVybiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkgPyAtcmV0IDogcmV0O1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICAgIHJldHVybiB0aGlzLnRvU3RyaW5nKDE2KTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiB0b0J1ZmZlciAoZW5kaWFuLCBsZW5ndGgpIHtcbiAgICBhc3NlcnQodHlwZW9mIEJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcpO1xuICAgIHJldHVybiB0aGlzLnRvQXJyYXlMaWtlKEJ1ZmZlciwgZW5kaWFuLCBsZW5ndGgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b0FycmF5ID0gZnVuY3Rpb24gdG9BcnJheSAoZW5kaWFuLCBsZW5ndGgpIHtcbiAgICByZXR1cm4gdGhpcy50b0FycmF5TGlrZShBcnJheSwgZW5kaWFuLCBsZW5ndGgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b0FycmF5TGlrZSA9IGZ1bmN0aW9uIHRvQXJyYXlMaWtlIChBcnJheVR5cGUsIGVuZGlhbiwgbGVuZ3RoKSB7XG4gICAgdmFyIGJ5dGVMZW5ndGggPSB0aGlzLmJ5dGVMZW5ndGgoKTtcbiAgICB2YXIgcmVxTGVuZ3RoID0gbGVuZ3RoIHx8IE1hdGgubWF4KDEsIGJ5dGVMZW5ndGgpO1xuICAgIGFzc2VydChieXRlTGVuZ3RoIDw9IHJlcUxlbmd0aCwgJ2J5dGUgYXJyYXkgbG9uZ2VyIHRoYW4gZGVzaXJlZCBsZW5ndGgnKTtcbiAgICBhc3NlcnQocmVxTGVuZ3RoID4gMCwgJ1JlcXVlc3RlZCBhcnJheSBsZW5ndGggPD0gMCcpO1xuXG4gICAgdGhpcy5zdHJpcCgpO1xuICAgIHZhciBsaXR0bGVFbmRpYW4gPSBlbmRpYW4gPT09ICdsZSc7XG4gICAgdmFyIHJlcyA9IG5ldyBBcnJheVR5cGUocmVxTGVuZ3RoKTtcblxuICAgIHZhciBiLCBpO1xuICAgIHZhciBxID0gdGhpcy5jbG9uZSgpO1xuICAgIGlmICghbGl0dGxlRW5kaWFuKSB7XG4gICAgICAvLyBBc3N1bWUgYmlnLWVuZGlhblxuICAgICAgZm9yIChpID0gMDsgaSA8IHJlcUxlbmd0aCAtIGJ5dGVMZW5ndGg7IGkrKykge1xuICAgICAgICByZXNbaV0gPSAwO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGkgPSAwOyAhcS5pc1plcm8oKTsgaSsrKSB7XG4gICAgICAgIGIgPSBxLmFuZGxuKDB4ZmYpO1xuICAgICAgICBxLml1c2hybig4KTtcblxuICAgICAgICByZXNbcmVxTGVuZ3RoIC0gaSAtIDFdID0gYjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChpID0gMDsgIXEuaXNaZXJvKCk7IGkrKykge1xuICAgICAgICBiID0gcS5hbmRsbigweGZmKTtcbiAgICAgICAgcS5pdXNocm4oOCk7XG5cbiAgICAgICAgcmVzW2ldID0gYjtcbiAgICAgIH1cblxuICAgICAgZm9yICg7IGkgPCByZXFMZW5ndGg7IGkrKykge1xuICAgICAgICByZXNbaV0gPSAwO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgaWYgKE1hdGguY2x6MzIpIHtcbiAgICBCTi5wcm90b3R5cGUuX2NvdW50Qml0cyA9IGZ1bmN0aW9uIF9jb3VudEJpdHMgKHcpIHtcbiAgICAgIHJldHVybiAzMiAtIE1hdGguY2x6MzIodyk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBCTi5wcm90b3R5cGUuX2NvdW50Qml0cyA9IGZ1bmN0aW9uIF9jb3VudEJpdHMgKHcpIHtcbiAgICAgIHZhciB0ID0gdztcbiAgICAgIHZhciByID0gMDtcbiAgICAgIGlmICh0ID49IDB4MTAwMCkge1xuICAgICAgICByICs9IDEzO1xuICAgICAgICB0ID4+Pj0gMTM7XG4gICAgICB9XG4gICAgICBpZiAodCA+PSAweDQwKSB7XG4gICAgICAgIHIgKz0gNztcbiAgICAgICAgdCA+Pj49IDc7XG4gICAgICB9XG4gICAgICBpZiAodCA+PSAweDgpIHtcbiAgICAgICAgciArPSA0O1xuICAgICAgICB0ID4+Pj0gNDtcbiAgICAgIH1cbiAgICAgIGlmICh0ID49IDB4MDIpIHtcbiAgICAgICAgciArPSAyO1xuICAgICAgICB0ID4+Pj0gMjtcbiAgICAgIH1cbiAgICAgIHJldHVybiByICsgdDtcbiAgICB9O1xuICB9XG5cbiAgQk4ucHJvdG90eXBlLl96ZXJvQml0cyA9IGZ1bmN0aW9uIF96ZXJvQml0cyAodykge1xuICAgIC8vIFNob3J0LWN1dFxuICAgIGlmICh3ID09PSAwKSByZXR1cm4gMjY7XG5cbiAgICB2YXIgdCA9IHc7XG4gICAgdmFyIHIgPSAwO1xuICAgIGlmICgodCAmIDB4MWZmZikgPT09IDApIHtcbiAgICAgIHIgKz0gMTM7XG4gICAgICB0ID4+Pj0gMTM7XG4gICAgfVxuICAgIGlmICgodCAmIDB4N2YpID09PSAwKSB7XG4gICAgICByICs9IDc7XG4gICAgICB0ID4+Pj0gNztcbiAgICB9XG4gICAgaWYgKCh0ICYgMHhmKSA9PT0gMCkge1xuICAgICAgciArPSA0O1xuICAgICAgdCA+Pj49IDQ7XG4gICAgfVxuICAgIGlmICgodCAmIDB4MykgPT09IDApIHtcbiAgICAgIHIgKz0gMjtcbiAgICAgIHQgPj4+PSAyO1xuICAgIH1cbiAgICBpZiAoKHQgJiAweDEpID09PSAwKSB7XG4gICAgICByKys7XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9O1xuXG4gIC8vIFJldHVybiBudW1iZXIgb2YgdXNlZCBiaXRzIGluIGEgQk5cbiAgQk4ucHJvdG90eXBlLmJpdExlbmd0aCA9IGZ1bmN0aW9uIGJpdExlbmd0aCAoKSB7XG4gICAgdmFyIHcgPSB0aGlzLndvcmRzW3RoaXMubGVuZ3RoIC0gMV07XG4gICAgdmFyIGhpID0gdGhpcy5fY291bnRCaXRzKHcpO1xuICAgIHJldHVybiAodGhpcy5sZW5ndGggLSAxKSAqIDI2ICsgaGk7XG4gIH07XG5cbiAgZnVuY3Rpb24gdG9CaXRBcnJheSAobnVtKSB7XG4gICAgdmFyIHcgPSBuZXcgQXJyYXkobnVtLmJpdExlbmd0aCgpKTtcblxuICAgIGZvciAodmFyIGJpdCA9IDA7IGJpdCA8IHcubGVuZ3RoOyBiaXQrKykge1xuICAgICAgdmFyIG9mZiA9IChiaXQgLyAyNikgfCAwO1xuICAgICAgdmFyIHdiaXQgPSBiaXQgJSAyNjtcblxuICAgICAgd1tiaXRdID0gKG51bS53b3Jkc1tvZmZdICYgKDEgPDwgd2JpdCkpID4+PiB3Yml0O1xuICAgIH1cblxuICAgIHJldHVybiB3O1xuICB9XG5cbiAgLy8gTnVtYmVyIG9mIHRyYWlsaW5nIHplcm8gYml0c1xuICBCTi5wcm90b3R5cGUuemVyb0JpdHMgPSBmdW5jdGlvbiB6ZXJvQml0cyAoKSB7XG4gICAgaWYgKHRoaXMuaXNaZXJvKCkpIHJldHVybiAwO1xuXG4gICAgdmFyIHIgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGIgPSB0aGlzLl96ZXJvQml0cyh0aGlzLndvcmRzW2ldKTtcbiAgICAgIHIgKz0gYjtcbiAgICAgIGlmIChiICE9PSAyNikgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5ieXRlTGVuZ3RoID0gZnVuY3Rpb24gYnl0ZUxlbmd0aCAoKSB7XG4gICAgcmV0dXJuIE1hdGguY2VpbCh0aGlzLmJpdExlbmd0aCgpIC8gOCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnRvVHdvcyA9IGZ1bmN0aW9uIHRvVHdvcyAod2lkdGgpIHtcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuYWJzKCkuaW5vdG4od2lkdGgpLmlhZGRuKDEpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5mcm9tVHdvcyA9IGZ1bmN0aW9uIGZyb21Ud29zICh3aWR0aCkge1xuICAgIGlmICh0aGlzLnRlc3RuKHdpZHRoIC0gMSkpIHtcbiAgICAgIHJldHVybiB0aGlzLm5vdG4od2lkdGgpLmlhZGRuKDEpLmluZWcoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNOZWcgPSBmdW5jdGlvbiBpc05lZyAoKSB7XG4gICAgcmV0dXJuIHRoaXMubmVnYXRpdmUgIT09IDA7XG4gIH07XG5cbiAgLy8gUmV0dXJuIG5lZ2F0aXZlIGNsb25lIG9mIGB0aGlzYFxuICBCTi5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnICgpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmluZWcoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaW5lZyA9IGZ1bmN0aW9uIGluZWcgKCkge1xuICAgIGlmICghdGhpcy5pc1plcm8oKSkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSBePSAxO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8vIE9yIGBudW1gIHdpdGggYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pdW9yID0gZnVuY3Rpb24gaXVvciAobnVtKSB7XG4gICAgd2hpbGUgKHRoaXMubGVuZ3RoIDwgbnVtLmxlbmd0aCkge1xuICAgICAgdGhpcy53b3Jkc1t0aGlzLmxlbmd0aCsrXSA9IDA7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW0ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSB0aGlzLndvcmRzW2ldIHwgbnVtLndvcmRzW2ldO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlvciA9IGZ1bmN0aW9uIGlvciAobnVtKSB7XG4gICAgYXNzZXJ0KCh0aGlzLm5lZ2F0aXZlIHwgbnVtLm5lZ2F0aXZlKSA9PT0gMCk7XG4gICAgcmV0dXJuIHRoaXMuaXVvcihudW0pO1xuICB9O1xuXG4gIC8vIE9yIGBudW1gIHdpdGggYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5vciA9IGZ1bmN0aW9uIG9yIChudW0pIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gdGhpcy5jbG9uZSgpLmlvcihudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5pb3IodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnVvciA9IGZ1bmN0aW9uIHVvciAobnVtKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5pdW9yKG51bSk7XG4gICAgcmV0dXJuIG51bS5jbG9uZSgpLml1b3IodGhpcyk7XG4gIH07XG5cbiAgLy8gQW5kIGBudW1gIHdpdGggYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pdWFuZCA9IGZ1bmN0aW9uIGl1YW5kIChudW0pIHtcbiAgICAvLyBiID0gbWluLWxlbmd0aChudW0sIHRoaXMpXG4gICAgdmFyIGI7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkge1xuICAgICAgYiA9IG51bTtcbiAgICB9IGVsc2Uge1xuICAgICAgYiA9IHRoaXM7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gdGhpcy53b3Jkc1tpXSAmIG51bS53b3Jkc1tpXTtcbiAgICB9XG5cbiAgICB0aGlzLmxlbmd0aCA9IGIubGVuZ3RoO1xuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaWFuZCA9IGZ1bmN0aW9uIGlhbmQgKG51bSkge1xuICAgIGFzc2VydCgodGhpcy5uZWdhdGl2ZSB8IG51bS5uZWdhdGl2ZSkgPT09IDApO1xuICAgIHJldHVybiB0aGlzLml1YW5kKG51bSk7XG4gIH07XG5cbiAgLy8gQW5kIGBudW1gIHdpdGggYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5hbmQgPSBmdW5jdGlvbiBhbmQgKG51bSkge1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiB0aGlzLmNsb25lKCkuaWFuZChudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5pYW5kKHRoaXMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51YW5kID0gZnVuY3Rpb24gdWFuZCAobnVtKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5pdWFuZChudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5pdWFuZCh0aGlzKTtcbiAgfTtcblxuICAvLyBYb3IgYG51bWAgd2l0aCBgdGhpc2AgaW4tcGxhY2VcbiAgQk4ucHJvdG90eXBlLml1eG9yID0gZnVuY3Rpb24gaXV4b3IgKG51bSkge1xuICAgIC8vIGEubGVuZ3RoID4gYi5sZW5ndGhcbiAgICB2YXIgYTtcbiAgICB2YXIgYjtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSB7XG4gICAgICBhID0gdGhpcztcbiAgICAgIGIgPSBudW07XG4gICAgfSBlbHNlIHtcbiAgICAgIGEgPSBudW07XG4gICAgICBiID0gdGhpcztcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGIubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSBhLndvcmRzW2ldIF4gYi53b3Jkc1tpXTtcbiAgICB9XG5cbiAgICBpZiAodGhpcyAhPT0gYSkge1xuICAgICAgZm9yICg7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSBhLndvcmRzW2ldO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMubGVuZ3RoID0gYS5sZW5ndGg7XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5peG9yID0gZnVuY3Rpb24gaXhvciAobnVtKSB7XG4gICAgYXNzZXJ0KCh0aGlzLm5lZ2F0aXZlIHwgbnVtLm5lZ2F0aXZlKSA9PT0gMCk7XG4gICAgcmV0dXJuIHRoaXMuaXV4b3IobnVtKTtcbiAgfTtcblxuICAvLyBYb3IgYG51bWAgd2l0aCBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLnhvciA9IGZ1bmN0aW9uIHhvciAobnVtKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5peG9yKG51bSk7XG4gICAgcmV0dXJuIG51bS5jbG9uZSgpLml4b3IodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnV4b3IgPSBmdW5jdGlvbiB1eG9yIChudW0pIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gdGhpcy5jbG9uZSgpLml1eG9yKG51bSk7XG4gICAgcmV0dXJuIG51bS5jbG9uZSgpLml1eG9yKHRoaXMpO1xuICB9O1xuXG4gIC8vIE5vdCBgYHRoaXNgYCB3aXRoIGBgd2lkdGhgYCBiaXR3aWR0aFxuICBCTi5wcm90b3R5cGUuaW5vdG4gPSBmdW5jdGlvbiBpbm90biAod2lkdGgpIHtcbiAgICBhc3NlcnQodHlwZW9mIHdpZHRoID09PSAnbnVtYmVyJyAmJiB3aWR0aCA+PSAwKTtcblxuICAgIHZhciBieXRlc05lZWRlZCA9IE1hdGguY2VpbCh3aWR0aCAvIDI2KSB8IDA7XG4gICAgdmFyIGJpdHNMZWZ0ID0gd2lkdGggJSAyNjtcblxuICAgIC8vIEV4dGVuZCB0aGUgYnVmZmVyIHdpdGggbGVhZGluZyB6ZXJvZXNcbiAgICB0aGlzLl9leHBhbmQoYnl0ZXNOZWVkZWQpO1xuXG4gICAgaWYgKGJpdHNMZWZ0ID4gMCkge1xuICAgICAgYnl0ZXNOZWVkZWQtLTtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgY29tcGxldGUgd29yZHNcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzTmVlZGVkOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSB+dGhpcy53b3Jkc1tpXSAmIDB4M2ZmZmZmZjtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgdGhlIHJlc2lkdWVcbiAgICBpZiAoYml0c0xlZnQgPiAwKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gfnRoaXMud29yZHNbaV0gJiAoMHgzZmZmZmZmID4+ICgyNiAtIGJpdHNMZWZ0KSk7XG4gICAgfVxuXG4gICAgLy8gQW5kIHJlbW92ZSBsZWFkaW5nIHplcm9lc1xuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLm5vdG4gPSBmdW5jdGlvbiBub3RuICh3aWR0aCkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaW5vdG4od2lkdGgpO1xuICB9O1xuXG4gIC8vIFNldCBgYml0YCBvZiBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLnNldG4gPSBmdW5jdGlvbiBzZXRuIChiaXQsIHZhbCkge1xuICAgIGFzc2VydCh0eXBlb2YgYml0ID09PSAnbnVtYmVyJyAmJiBiaXQgPj0gMCk7XG5cbiAgICB2YXIgb2ZmID0gKGJpdCAvIDI2KSB8IDA7XG4gICAgdmFyIHdiaXQgPSBiaXQgJSAyNjtcblxuICAgIHRoaXMuX2V4cGFuZChvZmYgKyAxKTtcblxuICAgIGlmICh2YWwpIHtcbiAgICAgIHRoaXMud29yZHNbb2ZmXSA9IHRoaXMud29yZHNbb2ZmXSB8ICgxIDw8IHdiaXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLndvcmRzW29mZl0gPSB0aGlzLndvcmRzW29mZl0gJiB+KDEgPDwgd2JpdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICAvLyBBZGQgYG51bWAgdG8gYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pYWRkID0gZnVuY3Rpb24gaWFkZCAobnVtKSB7XG4gICAgdmFyIHI7XG5cbiAgICAvLyBuZWdhdGl2ZSArIHBvc2l0aXZlXG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDAgJiYgbnVtLm5lZ2F0aXZlID09PSAwKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICAgIHIgPSB0aGlzLmlzdWIobnVtKTtcbiAgICAgIHRoaXMubmVnYXRpdmUgXj0gMTtcbiAgICAgIHJldHVybiB0aGlzLl9ub3JtU2lnbigpO1xuXG4gICAgLy8gcG9zaXRpdmUgKyBuZWdhdGl2ZVxuICAgIH0gZWxzZSBpZiAodGhpcy5uZWdhdGl2ZSA9PT0gMCAmJiBudW0ubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIG51bS5uZWdhdGl2ZSA9IDA7XG4gICAgICByID0gdGhpcy5pc3ViKG51bSk7XG4gICAgICBudW0ubmVnYXRpdmUgPSAxO1xuICAgICAgcmV0dXJuIHIuX25vcm1TaWduKCk7XG4gICAgfVxuXG4gICAgLy8gYS5sZW5ndGggPiBiLmxlbmd0aFxuICAgIHZhciBhLCBiO1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHtcbiAgICAgIGEgPSB0aGlzO1xuICAgICAgYiA9IG51bTtcbiAgICB9IGVsc2Uge1xuICAgICAgYSA9IG51bTtcbiAgICAgIGIgPSB0aGlzO1xuICAgIH1cblxuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKSB7XG4gICAgICByID0gKGEud29yZHNbaV0gfCAwKSArIChiLndvcmRzW2ldIHwgMCkgKyBjYXJyeTtcbiAgICAgIHRoaXMud29yZHNbaV0gPSByICYgMHgzZmZmZmZmO1xuICAgICAgY2FycnkgPSByID4+PiAyNjtcbiAgICB9XG4gICAgZm9yICg7IGNhcnJ5ICE9PSAwICYmIGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICByID0gKGEud29yZHNbaV0gfCAwKSArIGNhcnJ5O1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHIgJiAweDNmZmZmZmY7XG4gICAgICBjYXJyeSA9IHIgPj4+IDI2O1xuICAgIH1cblxuICAgIHRoaXMubGVuZ3RoID0gYS5sZW5ndGg7XG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICB0aGlzLndvcmRzW3RoaXMubGVuZ3RoXSA9IGNhcnJ5O1xuICAgICAgdGhpcy5sZW5ndGgrKztcbiAgICAvLyBDb3B5IHRoZSByZXN0IG9mIHRoZSB3b3Jkc1xuICAgIH0gZWxzZSBpZiAoYSAhPT0gdGhpcykge1xuICAgICAgZm9yICg7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSBhLndvcmRzW2ldO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8vIEFkZCBgbnVtYCB0byBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZCAobnVtKSB7XG4gICAgdmFyIHJlcztcbiAgICBpZiAobnVtLm5lZ2F0aXZlICE9PSAwICYmIHRoaXMubmVnYXRpdmUgPT09IDApIHtcbiAgICAgIG51bS5uZWdhdGl2ZSA9IDA7XG4gICAgICByZXMgPSB0aGlzLnN1YihudW0pO1xuICAgICAgbnVtLm5lZ2F0aXZlIF49IDE7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH0gZWxzZSBpZiAobnVtLm5lZ2F0aXZlID09PSAwICYmIHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgcmVzID0gbnVtLnN1Yih0aGlzKTtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gdGhpcy5jbG9uZSgpLmlhZGQobnVtKTtcblxuICAgIHJldHVybiBudW0uY2xvbmUoKS5pYWRkKHRoaXMpO1xuICB9O1xuXG4gIC8vIFN1YnRyYWN0IGBudW1gIGZyb20gYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pc3ViID0gZnVuY3Rpb24gaXN1YiAobnVtKSB7XG4gICAgLy8gdGhpcyAtICgtbnVtKSA9IHRoaXMgKyBudW1cbiAgICBpZiAobnVtLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICBudW0ubmVnYXRpdmUgPSAwO1xuICAgICAgdmFyIHIgPSB0aGlzLmlhZGQobnVtKTtcbiAgICAgIG51bS5uZWdhdGl2ZSA9IDE7XG4gICAgICByZXR1cm4gci5fbm9ybVNpZ24oKTtcblxuICAgIC8vIC10aGlzIC0gbnVtID0gLSh0aGlzICsgbnVtKVxuICAgIH0gZWxzZSBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICB0aGlzLmlhZGQobnVtKTtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgICAgcmV0dXJuIHRoaXMuX25vcm1TaWduKCk7XG4gICAgfVxuXG4gICAgLy8gQXQgdGhpcyBwb2ludCBib3RoIG51bWJlcnMgYXJlIHBvc2l0aXZlXG4gICAgdmFyIGNtcCA9IHRoaXMuY21wKG51bSk7XG5cbiAgICAvLyBPcHRpbWl6YXRpb24gLSB6ZXJvaWZ5XG4gICAgaWYgKGNtcCA9PT0gMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICB0aGlzLmxlbmd0aCA9IDE7XG4gICAgICB0aGlzLndvcmRzWzBdID0gMDtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIGEgPiBiXG4gICAgdmFyIGEsIGI7XG4gICAgaWYgKGNtcCA+IDApIHtcbiAgICAgIGEgPSB0aGlzO1xuICAgICAgYiA9IG51bTtcbiAgICB9IGVsc2Uge1xuICAgICAgYSA9IG51bTtcbiAgICAgIGIgPSB0aGlzO1xuICAgIH1cblxuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKSB7XG4gICAgICByID0gKGEud29yZHNbaV0gfCAwKSAtIChiLndvcmRzW2ldIHwgMCkgKyBjYXJyeTtcbiAgICAgIGNhcnJ5ID0gciA+PiAyNjtcbiAgICAgIHRoaXMud29yZHNbaV0gPSByICYgMHgzZmZmZmZmO1xuICAgIH1cbiAgICBmb3IgKDsgY2FycnkgIT09IDAgJiYgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIHIgPSAoYS53b3Jkc1tpXSB8IDApICsgY2Fycnk7XG4gICAgICBjYXJyeSA9IHIgPj4gMjY7XG4gICAgICB0aGlzLndvcmRzW2ldID0gciAmIDB4M2ZmZmZmZjtcbiAgICB9XG5cbiAgICAvLyBDb3B5IHJlc3Qgb2YgdGhlIHdvcmRzXG4gICAgaWYgKGNhcnJ5ID09PSAwICYmIGkgPCBhLmxlbmd0aCAmJiBhICE9PSB0aGlzKSB7XG4gICAgICBmb3IgKDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSA9IGEud29yZHNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5sZW5ndGggPSBNYXRoLm1heCh0aGlzLmxlbmd0aCwgaSk7XG5cbiAgICBpZiAoYSAhPT0gdGhpcykge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICAvLyBTdWJ0cmFjdCBgbnVtYCBmcm9tIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuc3ViID0gZnVuY3Rpb24gc3ViIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlzdWIobnVtKTtcbiAgfTtcblxuICBmdW5jdGlvbiBzbWFsbE11bFRvIChzZWxmLCBudW0sIG91dCkge1xuICAgIG91dC5uZWdhdGl2ZSA9IG51bS5uZWdhdGl2ZSBeIHNlbGYubmVnYXRpdmU7XG4gICAgdmFyIGxlbiA9IChzZWxmLmxlbmd0aCArIG51bS5sZW5ndGgpIHwgMDtcbiAgICBvdXQubGVuZ3RoID0gbGVuO1xuICAgIGxlbiA9IChsZW4gLSAxKSB8IDA7XG5cbiAgICAvLyBQZWVsIG9uZSBpdGVyYXRpb24gKGNvbXBpbGVyIGNhbid0IGRvIGl0LCBiZWNhdXNlIG9mIGNvZGUgY29tcGxleGl0eSlcbiAgICB2YXIgYSA9IHNlbGYud29yZHNbMF0gfCAwO1xuICAgIHZhciBiID0gbnVtLndvcmRzWzBdIHwgMDtcbiAgICB2YXIgciA9IGEgKiBiO1xuXG4gICAgdmFyIGxvID0gciAmIDB4M2ZmZmZmZjtcbiAgICB2YXIgY2FycnkgPSAociAvIDB4NDAwMDAwMCkgfCAwO1xuICAgIG91dC53b3Jkc1swXSA9IGxvO1xuXG4gICAgZm9yICh2YXIgayA9IDE7IGsgPCBsZW47IGsrKykge1xuICAgICAgLy8gU3VtIGFsbCB3b3JkcyB3aXRoIHRoZSBzYW1lIGBpICsgaiA9IGtgIGFuZCBhY2N1bXVsYXRlIGBuY2FycnlgLFxuICAgICAgLy8gbm90ZSB0aGF0IG5jYXJyeSBjb3VsZCBiZSA+PSAweDNmZmZmZmZcbiAgICAgIHZhciBuY2FycnkgPSBjYXJyeSA+Pj4gMjY7XG4gICAgICB2YXIgcndvcmQgPSBjYXJyeSAmIDB4M2ZmZmZmZjtcbiAgICAgIHZhciBtYXhKID0gTWF0aC5taW4oaywgbnVtLmxlbmd0aCAtIDEpO1xuICAgICAgZm9yICh2YXIgaiA9IE1hdGgubWF4KDAsIGsgLSBzZWxmLmxlbmd0aCArIDEpOyBqIDw9IG1heEo7IGorKykge1xuICAgICAgICB2YXIgaSA9IChrIC0gaikgfCAwO1xuICAgICAgICBhID0gc2VsZi53b3Jkc1tpXSB8IDA7XG4gICAgICAgIGIgPSBudW0ud29yZHNbal0gfCAwO1xuICAgICAgICByID0gYSAqIGIgKyByd29yZDtcbiAgICAgICAgbmNhcnJ5ICs9IChyIC8gMHg0MDAwMDAwKSB8IDA7XG4gICAgICAgIHJ3b3JkID0gciAmIDB4M2ZmZmZmZjtcbiAgICAgIH1cbiAgICAgIG91dC53b3Jkc1trXSA9IHJ3b3JkIHwgMDtcbiAgICAgIGNhcnJ5ID0gbmNhcnJ5IHwgMDtcbiAgICB9XG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICBvdXQud29yZHNba10gPSBjYXJyeSB8IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dC5sZW5ndGgtLTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0LnN0cmlwKCk7XG4gIH1cblxuICAvLyBUT0RPKGluZHV0bnkpOiBpdCBtYXkgYmUgcmVhc29uYWJsZSB0byBvbWl0IGl0IGZvciB1c2VycyB3aG8gZG9uJ3QgbmVlZFxuICAvLyB0byB3b3JrIHdpdGggMjU2LWJpdCBudW1iZXJzLCBvdGhlcndpc2UgaXQgZ2l2ZXMgMjAlIGltcHJvdmVtZW50IGZvciAyNTYtYml0XG4gIC8vIG11bHRpcGxpY2F0aW9uIChsaWtlIGVsbGlwdGljIHNlY3AyNTZrMSkuXG4gIHZhciBjb21iMTBNdWxUbyA9IGZ1bmN0aW9uIGNvbWIxME11bFRvIChzZWxmLCBudW0sIG91dCkge1xuICAgIHZhciBhID0gc2VsZi53b3JkcztcbiAgICB2YXIgYiA9IG51bS53b3JkcztcbiAgICB2YXIgbyA9IG91dC53b3JkcztcbiAgICB2YXIgYyA9IDA7XG4gICAgdmFyIGxvO1xuICAgIHZhciBtaWQ7XG4gICAgdmFyIGhpO1xuICAgIHZhciBhMCA9IGFbMF0gfCAwO1xuICAgIHZhciBhbDAgPSBhMCAmIDB4MWZmZjtcbiAgICB2YXIgYWgwID0gYTAgPj4+IDEzO1xuICAgIHZhciBhMSA9IGFbMV0gfCAwO1xuICAgIHZhciBhbDEgPSBhMSAmIDB4MWZmZjtcbiAgICB2YXIgYWgxID0gYTEgPj4+IDEzO1xuICAgIHZhciBhMiA9IGFbMl0gfCAwO1xuICAgIHZhciBhbDIgPSBhMiAmIDB4MWZmZjtcbiAgICB2YXIgYWgyID0gYTIgPj4+IDEzO1xuICAgIHZhciBhMyA9IGFbM10gfCAwO1xuICAgIHZhciBhbDMgPSBhMyAmIDB4MWZmZjtcbiAgICB2YXIgYWgzID0gYTMgPj4+IDEzO1xuICAgIHZhciBhNCA9IGFbNF0gfCAwO1xuICAgIHZhciBhbDQgPSBhNCAmIDB4MWZmZjtcbiAgICB2YXIgYWg0ID0gYTQgPj4+IDEzO1xuICAgIHZhciBhNSA9IGFbNV0gfCAwO1xuICAgIHZhciBhbDUgPSBhNSAmIDB4MWZmZjtcbiAgICB2YXIgYWg1ID0gYTUgPj4+IDEzO1xuICAgIHZhciBhNiA9IGFbNl0gfCAwO1xuICAgIHZhciBhbDYgPSBhNiAmIDB4MWZmZjtcbiAgICB2YXIgYWg2ID0gYTYgPj4+IDEzO1xuICAgIHZhciBhNyA9IGFbN10gfCAwO1xuICAgIHZhciBhbDcgPSBhNyAmIDB4MWZmZjtcbiAgICB2YXIgYWg3ID0gYTcgPj4+IDEzO1xuICAgIHZhciBhOCA9IGFbOF0gfCAwO1xuICAgIHZhciBhbDggPSBhOCAmIDB4MWZmZjtcbiAgICB2YXIgYWg4ID0gYTggPj4+IDEzO1xuICAgIHZhciBhOSA9IGFbOV0gfCAwO1xuICAgIHZhciBhbDkgPSBhOSAmIDB4MWZmZjtcbiAgICB2YXIgYWg5ID0gYTkgPj4+IDEzO1xuICAgIHZhciBiMCA9IGJbMF0gfCAwO1xuICAgIHZhciBibDAgPSBiMCAmIDB4MWZmZjtcbiAgICB2YXIgYmgwID0gYjAgPj4+IDEzO1xuICAgIHZhciBiMSA9IGJbMV0gfCAwO1xuICAgIHZhciBibDEgPSBiMSAmIDB4MWZmZjtcbiAgICB2YXIgYmgxID0gYjEgPj4+IDEzO1xuICAgIHZhciBiMiA9IGJbMl0gfCAwO1xuICAgIHZhciBibDIgPSBiMiAmIDB4MWZmZjtcbiAgICB2YXIgYmgyID0gYjIgPj4+IDEzO1xuICAgIHZhciBiMyA9IGJbM10gfCAwO1xuICAgIHZhciBibDMgPSBiMyAmIDB4MWZmZjtcbiAgICB2YXIgYmgzID0gYjMgPj4+IDEzO1xuICAgIHZhciBiNCA9IGJbNF0gfCAwO1xuICAgIHZhciBibDQgPSBiNCAmIDB4MWZmZjtcbiAgICB2YXIgYmg0ID0gYjQgPj4+IDEzO1xuICAgIHZhciBiNSA9IGJbNV0gfCAwO1xuICAgIHZhciBibDUgPSBiNSAmIDB4MWZmZjtcbiAgICB2YXIgYmg1ID0gYjUgPj4+IDEzO1xuICAgIHZhciBiNiA9IGJbNl0gfCAwO1xuICAgIHZhciBibDYgPSBiNiAmIDB4MWZmZjtcbiAgICB2YXIgYmg2ID0gYjYgPj4+IDEzO1xuICAgIHZhciBiNyA9IGJbN10gfCAwO1xuICAgIHZhciBibDcgPSBiNyAmIDB4MWZmZjtcbiAgICB2YXIgYmg3ID0gYjcgPj4+IDEzO1xuICAgIHZhciBiOCA9IGJbOF0gfCAwO1xuICAgIHZhciBibDggPSBiOCAmIDB4MWZmZjtcbiAgICB2YXIgYmg4ID0gYjggPj4+IDEzO1xuICAgIHZhciBiOSA9IGJbOV0gfCAwO1xuICAgIHZhciBibDkgPSBiOSAmIDB4MWZmZjtcbiAgICB2YXIgYmg5ID0gYjkgPj4+IDEzO1xuXG4gICAgb3V0Lm5lZ2F0aXZlID0gc2VsZi5uZWdhdGl2ZSBeIG51bS5uZWdhdGl2ZTtcbiAgICBvdXQubGVuZ3RoID0gMTk7XG4gICAgLyogayA9IDAgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDAsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsMCwgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDAsIGJoMCk7XG4gICAgdmFyIHcwID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzAgPj4+IDI2KTtcbiAgICB3MCAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDEgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDEsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsMSwgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMSwgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDEsIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDEpO1xuICAgIHZhciB3MSA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxID4+PiAyNik7XG4gICAgdzEgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAyICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWwyLCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDIsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWgyLCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoMik7XG4gICAgdmFyIHcyID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzIgPj4+IDI2KTtcbiAgICB3MiAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDMgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDMsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsMywgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDMsIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMiwgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMiwgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMiwgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgyLCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoMyk7XG4gICAgdmFyIHczID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzMgPj4+IDI2KTtcbiAgICB3MyAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDQgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDQsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsNCwgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNCwgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDQsIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDQpO1xuICAgIHZhciB3NCA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHc0ID4+PiAyNik7XG4gICAgdzQgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA1ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw1LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDUsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg1LCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDQsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDQsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDQsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNCwgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwzLCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwzLCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgzLCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDMsIGJoMik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMiwgYmwzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMiwgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMiwgYmwzKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgyLCBiaDMpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsNCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmg0KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDUpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoNSk7XG4gICAgdmFyIHc1ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzUgPj4+IDI2KTtcbiAgICB3NSAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDYgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDYsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsNiwgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDYsIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNSwgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNSwgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNSwgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg1LCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDQsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDQsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDQsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNCwgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwzLCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwzLCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgzLCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDMsIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMiwgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMiwgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMiwgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgyLCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoNik7XG4gICAgdmFyIHc2ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzYgPj4+IDI2KTtcbiAgICB3NiAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDcgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDcsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsNywgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNywgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDcsIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDcpO1xuICAgIHZhciB3NyA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHc3ID4+PiAyNik7XG4gICAgdzcgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA4ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw4LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDgsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg4LCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDcsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDcsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDcsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNywgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw2LCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw2LCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg2LCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDYsIGJoMik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNSwgYmwzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNSwgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNSwgYmwzKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg1LCBiaDMpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDQsIGJsNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDQsIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDQsIGJsNCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNCwgYmg0KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwzLCBibDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwzLCBiaDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgzLCBibDUpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDMsIGJoNSk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMiwgYmw2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMiwgYmg2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMiwgYmw2KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgyLCBiaDYpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsNyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmg3KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDgpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoOCk7XG4gICAgdmFyIHc4ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzggPj4+IDI2KTtcbiAgICB3OCAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDkgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOSwgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsOCwgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsOCwgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOCwgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg4LCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDcsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDcsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDcsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNywgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw2LCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw2LCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg2LCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDYsIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNSwgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNSwgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNSwgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg1LCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDQsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDQsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDQsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNCwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwzLCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwzLCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgzLCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDMsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMiwgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMiwgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMiwgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgyLCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoOSk7XG4gICAgdmFyIHc5ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzkgPj4+IDI2KTtcbiAgICB3OSAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDEwICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDEpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsMSk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoOSk7XG4gICAgdmFyIHcxMCA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxMCA+Pj4gMjYpO1xuICAgIHcxMCAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDExICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDIpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsMik7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDIpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsMyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoMyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsMyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmgzKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDQpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDQpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDQpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoNCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmw1KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmg1KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmw1KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDUpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsNik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoNik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsNik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmg2KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDcpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDcpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDcpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoNyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmw4KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmg4KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmw4KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDgpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsOSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmg5KTtcbiAgICB2YXIgdzExID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzExID4+PiAyNik7XG4gICAgdzExICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTIgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsMyk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOSwgYmwzKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsOCwgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsOCwgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOCwgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg4LCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDcsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDcsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDcsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNywgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw2LCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw2LCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg2LCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDYsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNSwgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNSwgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNSwgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg1LCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDQsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDQsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDQsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNCwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwzLCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwzLCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgzLCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDMsIGJoOSk7XG4gICAgdmFyIHcxMiA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxMiA+Pj4gMjYpO1xuICAgIHcxMiAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDEzICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDQpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsNCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoOSk7XG4gICAgdmFyIHcxMyA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxMyA+Pj4gMjYpO1xuICAgIHcxMyAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDE0ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDUpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsNSk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDUpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsNik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoNik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsNik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmg2KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDcpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDcpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDcpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoNyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmw4KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmg4KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmw4KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDgpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsOSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmg5KTtcbiAgICB2YXIgdzE0ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzE0ID4+PiAyNik7XG4gICAgdzE0ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTUgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsNik7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmg2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOSwgYmw2KTtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsOCwgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsOCwgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOCwgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg4LCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDcsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDcsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDcsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNywgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw2LCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw2LCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg2LCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDYsIGJoOSk7XG4gICAgdmFyIHcxNSA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxNSA+Pj4gMjYpO1xuICAgIHcxNSAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDE2ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDcpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsNyk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoOSk7XG4gICAgdmFyIHcxNiA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxNiA+Pj4gMjYpO1xuICAgIHcxNiAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDE3ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDgpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsOCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDgpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsOSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmg5KTtcbiAgICB2YXIgdzE3ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzE3ID4+PiAyNik7XG4gICAgdzE3ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTggKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsOSk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmg5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOSwgYmw5KTtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoOSk7XG4gICAgdmFyIHcxOCA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxOCA+Pj4gMjYpO1xuICAgIHcxOCAmPSAweDNmZmZmZmY7XG4gICAgb1swXSA9IHcwO1xuICAgIG9bMV0gPSB3MTtcbiAgICBvWzJdID0gdzI7XG4gICAgb1szXSA9IHczO1xuICAgIG9bNF0gPSB3NDtcbiAgICBvWzVdID0gdzU7XG4gICAgb1s2XSA9IHc2O1xuICAgIG9bN10gPSB3NztcbiAgICBvWzhdID0gdzg7XG4gICAgb1s5XSA9IHc5O1xuICAgIG9bMTBdID0gdzEwO1xuICAgIG9bMTFdID0gdzExO1xuICAgIG9bMTJdID0gdzEyO1xuICAgIG9bMTNdID0gdzEzO1xuICAgIG9bMTRdID0gdzE0O1xuICAgIG9bMTVdID0gdzE1O1xuICAgIG9bMTZdID0gdzE2O1xuICAgIG9bMTddID0gdzE3O1xuICAgIG9bMThdID0gdzE4O1xuICAgIGlmIChjICE9PSAwKSB7XG4gICAgICBvWzE5XSA9IGM7XG4gICAgICBvdXQubGVuZ3RoKys7XG4gICAgfVxuICAgIHJldHVybiBvdXQ7XG4gIH07XG5cbiAgLy8gUG9seWZpbGwgY29tYlxuICBpZiAoIU1hdGguaW11bCkge1xuICAgIGNvbWIxME11bFRvID0gc21hbGxNdWxUbztcbiAgfVxuXG4gIGZ1bmN0aW9uIGJpZ011bFRvIChzZWxmLCBudW0sIG91dCkge1xuICAgIG91dC5uZWdhdGl2ZSA9IG51bS5uZWdhdGl2ZSBeIHNlbGYubmVnYXRpdmU7XG4gICAgb3V0Lmxlbmd0aCA9IHNlbGYubGVuZ3RoICsgbnVtLmxlbmd0aDtcblxuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgdmFyIGhuY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGsgPSAwOyBrIDwgb3V0Lmxlbmd0aCAtIDE7IGsrKykge1xuICAgICAgLy8gU3VtIGFsbCB3b3JkcyB3aXRoIHRoZSBzYW1lIGBpICsgaiA9IGtgIGFuZCBhY2N1bXVsYXRlIGBuY2FycnlgLFxuICAgICAgLy8gbm90ZSB0aGF0IG5jYXJyeSBjb3VsZCBiZSA+PSAweDNmZmZmZmZcbiAgICAgIHZhciBuY2FycnkgPSBobmNhcnJ5O1xuICAgICAgaG5jYXJyeSA9IDA7XG4gICAgICB2YXIgcndvcmQgPSBjYXJyeSAmIDB4M2ZmZmZmZjtcbiAgICAgIHZhciBtYXhKID0gTWF0aC5taW4oaywgbnVtLmxlbmd0aCAtIDEpO1xuICAgICAgZm9yICh2YXIgaiA9IE1hdGgubWF4KDAsIGsgLSBzZWxmLmxlbmd0aCArIDEpOyBqIDw9IG1heEo7IGorKykge1xuICAgICAgICB2YXIgaSA9IGsgLSBqO1xuICAgICAgICB2YXIgYSA9IHNlbGYud29yZHNbaV0gfCAwO1xuICAgICAgICB2YXIgYiA9IG51bS53b3Jkc1tqXSB8IDA7XG4gICAgICAgIHZhciByID0gYSAqIGI7XG5cbiAgICAgICAgdmFyIGxvID0gciAmIDB4M2ZmZmZmZjtcbiAgICAgICAgbmNhcnJ5ID0gKG5jYXJyeSArICgociAvIDB4NDAwMDAwMCkgfCAwKSkgfCAwO1xuICAgICAgICBsbyA9IChsbyArIHJ3b3JkKSB8IDA7XG4gICAgICAgIHJ3b3JkID0gbG8gJiAweDNmZmZmZmY7XG4gICAgICAgIG5jYXJyeSA9IChuY2FycnkgKyAobG8gPj4+IDI2KSkgfCAwO1xuXG4gICAgICAgIGhuY2FycnkgKz0gbmNhcnJ5ID4+PiAyNjtcbiAgICAgICAgbmNhcnJ5ICY9IDB4M2ZmZmZmZjtcbiAgICAgIH1cbiAgICAgIG91dC53b3Jkc1trXSA9IHJ3b3JkO1xuICAgICAgY2FycnkgPSBuY2Fycnk7XG4gICAgICBuY2FycnkgPSBobmNhcnJ5O1xuICAgIH1cbiAgICBpZiAoY2FycnkgIT09IDApIHtcbiAgICAgIG91dC53b3Jkc1trXSA9IGNhcnJ5O1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXQubGVuZ3RoLS07XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5zdHJpcCgpO1xuICB9XG5cbiAgZnVuY3Rpb24ganVtYm9NdWxUbyAoc2VsZiwgbnVtLCBvdXQpIHtcbiAgICB2YXIgZmZ0bSA9IG5ldyBGRlRNKCk7XG4gICAgcmV0dXJuIGZmdG0ubXVscChzZWxmLCBudW0sIG91dCk7XG4gIH1cblxuICBCTi5wcm90b3R5cGUubXVsVG8gPSBmdW5jdGlvbiBtdWxUbyAobnVtLCBvdXQpIHtcbiAgICB2YXIgcmVzO1xuICAgIHZhciBsZW4gPSB0aGlzLmxlbmd0aCArIG51bS5sZW5ndGg7XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAxMCAmJiBudW0ubGVuZ3RoID09PSAxMCkge1xuICAgICAgcmVzID0gY29tYjEwTXVsVG8odGhpcywgbnVtLCBvdXQpO1xuICAgIH0gZWxzZSBpZiAobGVuIDwgNjMpIHtcbiAgICAgIHJlcyA9IHNtYWxsTXVsVG8odGhpcywgbnVtLCBvdXQpO1xuICAgIH0gZWxzZSBpZiAobGVuIDwgMTAyNCkge1xuICAgICAgcmVzID0gYmlnTXVsVG8odGhpcywgbnVtLCBvdXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMgPSBqdW1ib011bFRvKHRoaXMsIG51bSwgb3V0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIC8vIENvb2xleS1UdWtleSBhbGdvcml0aG0gZm9yIEZGVFxuICAvLyBzbGlnaHRseSByZXZpc2l0ZWQgdG8gcmVseSBvbiBsb29waW5nIGluc3RlYWQgb2YgcmVjdXJzaW9uXG5cbiAgZnVuY3Rpb24gRkZUTSAoeCwgeSkge1xuICAgIHRoaXMueCA9IHg7XG4gICAgdGhpcy55ID0geTtcbiAgfVxuXG4gIEZGVE0ucHJvdG90eXBlLm1ha2VSQlQgPSBmdW5jdGlvbiBtYWtlUkJUIChOKSB7XG4gICAgdmFyIHQgPSBuZXcgQXJyYXkoTik7XG4gICAgdmFyIGwgPSBCTi5wcm90b3R5cGUuX2NvdW50Qml0cyhOKSAtIDE7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIHtcbiAgICAgIHRbaV0gPSB0aGlzLnJldkJpbihpLCBsLCBOKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdDtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGJpbmFyeS1yZXZlcnNlZCByZXByZXNlbnRhdGlvbiBvZiBgeGBcbiAgRkZUTS5wcm90b3R5cGUucmV2QmluID0gZnVuY3Rpb24gcmV2QmluICh4LCBsLCBOKSB7XG4gICAgaWYgKHggPT09IDAgfHwgeCA9PT0gTiAtIDEpIHJldHVybiB4O1xuXG4gICAgdmFyIHJiID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgcmIgfD0gKHggJiAxKSA8PCAobCAtIGkgLSAxKTtcbiAgICAgIHggPj49IDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJiO1xuICB9O1xuXG4gIC8vIFBlcmZvcm1zIFwidHdlZWRsaW5nXCIgcGhhc2UsIHRoZXJlZm9yZSAnZW11bGF0aW5nJ1xuICAvLyBiZWhhdmlvdXIgb2YgdGhlIHJlY3Vyc2l2ZSBhbGdvcml0aG1cbiAgRkZUTS5wcm90b3R5cGUucGVybXV0ZSA9IGZ1bmN0aW9uIHBlcm11dGUgKHJidCwgcndzLCBpd3MsIHJ0d3MsIGl0d3MsIE4pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgcnR3c1tpXSA9IHJ3c1tyYnRbaV1dO1xuICAgICAgaXR3c1tpXSA9IGl3c1tyYnRbaV1dO1xuICAgIH1cbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS50cmFuc2Zvcm0gPSBmdW5jdGlvbiB0cmFuc2Zvcm0gKHJ3cywgaXdzLCBydHdzLCBpdHdzLCBOLCByYnQpIHtcbiAgICB0aGlzLnBlcm11dGUocmJ0LCByd3MsIGl3cywgcnR3cywgaXR3cywgTik7XG5cbiAgICBmb3IgKHZhciBzID0gMTsgcyA8IE47IHMgPDw9IDEpIHtcbiAgICAgIHZhciBsID0gcyA8PCAxO1xuXG4gICAgICB2YXIgcnR3ZGYgPSBNYXRoLmNvcygyICogTWF0aC5QSSAvIGwpO1xuICAgICAgdmFyIGl0d2RmID0gTWF0aC5zaW4oMiAqIE1hdGguUEkgLyBsKTtcblxuICAgICAgZm9yICh2YXIgcCA9IDA7IHAgPCBOOyBwICs9IGwpIHtcbiAgICAgICAgdmFyIHJ0d2RmXyA9IHJ0d2RmO1xuICAgICAgICB2YXIgaXR3ZGZfID0gaXR3ZGY7XG5cbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBzOyBqKyspIHtcbiAgICAgICAgICB2YXIgcmUgPSBydHdzW3AgKyBqXTtcbiAgICAgICAgICB2YXIgaWUgPSBpdHdzW3AgKyBqXTtcblxuICAgICAgICAgIHZhciBybyA9IHJ0d3NbcCArIGogKyBzXTtcbiAgICAgICAgICB2YXIgaW8gPSBpdHdzW3AgKyBqICsgc107XG5cbiAgICAgICAgICB2YXIgcnggPSBydHdkZl8gKiBybyAtIGl0d2RmXyAqIGlvO1xuXG4gICAgICAgICAgaW8gPSBydHdkZl8gKiBpbyArIGl0d2RmXyAqIHJvO1xuICAgICAgICAgIHJvID0gcng7XG5cbiAgICAgICAgICBydHdzW3AgKyBqXSA9IHJlICsgcm87XG4gICAgICAgICAgaXR3c1twICsgal0gPSBpZSArIGlvO1xuXG4gICAgICAgICAgcnR3c1twICsgaiArIHNdID0gcmUgLSBybztcbiAgICAgICAgICBpdHdzW3AgKyBqICsgc10gPSBpZSAtIGlvO1xuXG4gICAgICAgICAgLyoganNoaW50IG1heGRlcHRoIDogZmFsc2UgKi9cbiAgICAgICAgICBpZiAoaiAhPT0gbCkge1xuICAgICAgICAgICAgcnggPSBydHdkZiAqIHJ0d2RmXyAtIGl0d2RmICogaXR3ZGZfO1xuXG4gICAgICAgICAgICBpdHdkZl8gPSBydHdkZiAqIGl0d2RmXyArIGl0d2RmICogcnR3ZGZfO1xuICAgICAgICAgICAgcnR3ZGZfID0gcng7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIEZGVE0ucHJvdG90eXBlLmd1ZXNzTGVuMTNiID0gZnVuY3Rpb24gZ3Vlc3NMZW4xM2IgKG4sIG0pIHtcbiAgICB2YXIgTiA9IE1hdGgubWF4KG0sIG4pIHwgMTtcbiAgICB2YXIgb2RkID0gTiAmIDE7XG4gICAgdmFyIGkgPSAwO1xuICAgIGZvciAoTiA9IE4gLyAyIHwgMDsgTjsgTiA9IE4gPj4+IDEpIHtcbiAgICAgIGkrKztcbiAgICB9XG5cbiAgICByZXR1cm4gMSA8PCBpICsgMSArIG9kZDtcbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5jb25qdWdhdGUgPSBmdW5jdGlvbiBjb25qdWdhdGUgKHJ3cywgaXdzLCBOKSB7XG4gICAgaWYgKE4gPD0gMSkgcmV0dXJuO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBOIC8gMjsgaSsrKSB7XG4gICAgICB2YXIgdCA9IHJ3c1tpXTtcblxuICAgICAgcndzW2ldID0gcndzW04gLSBpIC0gMV07XG4gICAgICByd3NbTiAtIGkgLSAxXSA9IHQ7XG5cbiAgICAgIHQgPSBpd3NbaV07XG5cbiAgICAgIGl3c1tpXSA9IC1pd3NbTiAtIGkgLSAxXTtcbiAgICAgIGl3c1tOIC0gaSAtIDFdID0gLXQ7XG4gICAgfVxuICB9O1xuXG4gIEZGVE0ucHJvdG90eXBlLm5vcm1hbGl6ZTEzYiA9IGZ1bmN0aW9uIG5vcm1hbGl6ZTEzYiAod3MsIE4pIHtcbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTiAvIDI7IGkrKykge1xuICAgICAgdmFyIHcgPSBNYXRoLnJvdW5kKHdzWzIgKiBpICsgMV0gLyBOKSAqIDB4MjAwMCArXG4gICAgICAgIE1hdGgucm91bmQod3NbMiAqIGldIC8gTikgK1xuICAgICAgICBjYXJyeTtcblxuICAgICAgd3NbaV0gPSB3ICYgMHgzZmZmZmZmO1xuXG4gICAgICBpZiAodyA8IDB4NDAwMDAwMCkge1xuICAgICAgICBjYXJyeSA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYXJyeSA9IHcgLyAweDQwMDAwMDAgfCAwO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB3cztcbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5jb252ZXJ0MTNiID0gZnVuY3Rpb24gY29udmVydDEzYiAod3MsIGxlbiwgcndzLCBOKSB7XG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBjYXJyeSA9IGNhcnJ5ICsgKHdzW2ldIHwgMCk7XG5cbiAgICAgIHJ3c1syICogaV0gPSBjYXJyeSAmIDB4MWZmZjsgY2FycnkgPSBjYXJyeSA+Pj4gMTM7XG4gICAgICByd3NbMiAqIGkgKyAxXSA9IGNhcnJ5ICYgMHgxZmZmOyBjYXJyeSA9IGNhcnJ5ID4+PiAxMztcbiAgICB9XG5cbiAgICAvLyBQYWQgd2l0aCB6ZXJvZXNcbiAgICBmb3IgKGkgPSAyICogbGVuOyBpIDwgTjsgKytpKSB7XG4gICAgICByd3NbaV0gPSAwO1xuICAgIH1cblxuICAgIGFzc2VydChjYXJyeSA9PT0gMCk7XG4gICAgYXNzZXJ0KChjYXJyeSAmIH4weDFmZmYpID09PSAwKTtcbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5zdHViID0gZnVuY3Rpb24gc3R1YiAoTikge1xuICAgIHZhciBwaCA9IG5ldyBBcnJheShOKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgcGhbaV0gPSAwO1xuICAgIH1cblxuICAgIHJldHVybiBwaDtcbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5tdWxwID0gZnVuY3Rpb24gbXVscCAoeCwgeSwgb3V0KSB7XG4gICAgdmFyIE4gPSAyICogdGhpcy5ndWVzc0xlbjEzYih4Lmxlbmd0aCwgeS5sZW5ndGgpO1xuXG4gICAgdmFyIHJidCA9IHRoaXMubWFrZVJCVChOKTtcblxuICAgIHZhciBfID0gdGhpcy5zdHViKE4pO1xuXG4gICAgdmFyIHJ3cyA9IG5ldyBBcnJheShOKTtcbiAgICB2YXIgcndzdCA9IG5ldyBBcnJheShOKTtcbiAgICB2YXIgaXdzdCA9IG5ldyBBcnJheShOKTtcblxuICAgIHZhciBucndzID0gbmV3IEFycmF5KE4pO1xuICAgIHZhciBucndzdCA9IG5ldyBBcnJheShOKTtcbiAgICB2YXIgbml3c3QgPSBuZXcgQXJyYXkoTik7XG5cbiAgICB2YXIgcm13cyA9IG91dC53b3JkcztcbiAgICBybXdzLmxlbmd0aCA9IE47XG5cbiAgICB0aGlzLmNvbnZlcnQxM2IoeC53b3JkcywgeC5sZW5ndGgsIHJ3cywgTik7XG4gICAgdGhpcy5jb252ZXJ0MTNiKHkud29yZHMsIHkubGVuZ3RoLCBucndzLCBOKTtcblxuICAgIHRoaXMudHJhbnNmb3JtKHJ3cywgXywgcndzdCwgaXdzdCwgTiwgcmJ0KTtcbiAgICB0aGlzLnRyYW5zZm9ybShucndzLCBfLCBucndzdCwgbml3c3QsIE4sIHJidCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgdmFyIHJ4ID0gcndzdFtpXSAqIG5yd3N0W2ldIC0gaXdzdFtpXSAqIG5pd3N0W2ldO1xuICAgICAgaXdzdFtpXSA9IHJ3c3RbaV0gKiBuaXdzdFtpXSArIGl3c3RbaV0gKiBucndzdFtpXTtcbiAgICAgIHJ3c3RbaV0gPSByeDtcbiAgICB9XG5cbiAgICB0aGlzLmNvbmp1Z2F0ZShyd3N0LCBpd3N0LCBOKTtcbiAgICB0aGlzLnRyYW5zZm9ybShyd3N0LCBpd3N0LCBybXdzLCBfLCBOLCByYnQpO1xuICAgIHRoaXMuY29uanVnYXRlKHJtd3MsIF8sIE4pO1xuICAgIHRoaXMubm9ybWFsaXplMTNiKHJtd3MsIE4pO1xuXG4gICAgb3V0Lm5lZ2F0aXZlID0geC5uZWdhdGl2ZSBeIHkubmVnYXRpdmU7XG4gICAgb3V0Lmxlbmd0aCA9IHgubGVuZ3RoICsgeS5sZW5ndGg7XG4gICAgcmV0dXJuIG91dC5zdHJpcCgpO1xuICB9O1xuXG4gIC8vIE11bHRpcGx5IGB0aGlzYCBieSBgbnVtYFxuICBCTi5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsIChudW0pIHtcbiAgICB2YXIgb3V0ID0gbmV3IEJOKG51bGwpO1xuICAgIG91dC53b3JkcyA9IG5ldyBBcnJheSh0aGlzLmxlbmd0aCArIG51bS5sZW5ndGgpO1xuICAgIHJldHVybiB0aGlzLm11bFRvKG51bSwgb3V0KTtcbiAgfTtcblxuICAvLyBNdWx0aXBseSBlbXBsb3lpbmcgRkZUXG4gIEJOLnByb3RvdHlwZS5tdWxmID0gZnVuY3Rpb24gbXVsZiAobnVtKSB7XG4gICAgdmFyIG91dCA9IG5ldyBCTihudWxsKTtcbiAgICBvdXQud29yZHMgPSBuZXcgQXJyYXkodGhpcy5sZW5ndGggKyBudW0ubGVuZ3RoKTtcbiAgICByZXR1cm4ganVtYm9NdWxUbyh0aGlzLCBudW0sIG91dCk7XG4gIH07XG5cbiAgLy8gSW4tcGxhY2UgTXVsdGlwbGljYXRpb25cbiAgQk4ucHJvdG90eXBlLmltdWwgPSBmdW5jdGlvbiBpbXVsIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLm11bFRvKG51bSwgdGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmltdWxuID0gZnVuY3Rpb24gaW11bG4gKG51bSkge1xuICAgIGFzc2VydCh0eXBlb2YgbnVtID09PSAnbnVtYmVyJyk7XG4gICAgYXNzZXJ0KG51bSA8IDB4NDAwMDAwMCk7XG5cbiAgICAvLyBDYXJyeVxuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdyA9ICh0aGlzLndvcmRzW2ldIHwgMCkgKiBudW07XG4gICAgICB2YXIgbG8gPSAodyAmIDB4M2ZmZmZmZikgKyAoY2FycnkgJiAweDNmZmZmZmYpO1xuICAgICAgY2FycnkgPj49IDI2O1xuICAgICAgY2FycnkgKz0gKHcgLyAweDQwMDAwMDApIHwgMDtcbiAgICAgIC8vIE5PVEU6IGxvIGlzIDI3Yml0IG1heGltdW1cbiAgICAgIGNhcnJ5ICs9IGxvID4+PiAyNjtcbiAgICAgIHRoaXMud29yZHNbaV0gPSBsbyAmIDB4M2ZmZmZmZjtcbiAgICB9XG5cbiAgICBpZiAoY2FycnkgIT09IDApIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSBjYXJyeTtcbiAgICAgIHRoaXMubGVuZ3RoKys7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLm11bG4gPSBmdW5jdGlvbiBtdWxuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmltdWxuKG51bSk7XG4gIH07XG5cbiAgLy8gYHRoaXNgICogYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5zcXIgPSBmdW5jdGlvbiBzcXIgKCkge1xuICAgIHJldHVybiB0aGlzLm11bCh0aGlzKTtcbiAgfTtcblxuICAvLyBgdGhpc2AgKiBgdGhpc2AgaW4tcGxhY2VcbiAgQk4ucHJvdG90eXBlLmlzcXIgPSBmdW5jdGlvbiBpc3FyICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbXVsKHRoaXMuY2xvbmUoKSk7XG4gIH07XG5cbiAgLy8gTWF0aC5wb3coYHRoaXNgLCBgbnVtYClcbiAgQk4ucHJvdG90eXBlLnBvdyA9IGZ1bmN0aW9uIHBvdyAobnVtKSB7XG4gICAgdmFyIHcgPSB0b0JpdEFycmF5KG51bSk7XG4gICAgaWYgKHcubGVuZ3RoID09PSAwKSByZXR1cm4gbmV3IEJOKDEpO1xuXG4gICAgLy8gU2tpcCBsZWFkaW5nIHplcm9lc1xuICAgIHZhciByZXMgPSB0aGlzO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdy5sZW5ndGg7IGkrKywgcmVzID0gcmVzLnNxcigpKSB7XG4gICAgICBpZiAod1tpXSAhPT0gMCkgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKCsraSA8IHcubGVuZ3RoKSB7XG4gICAgICBmb3IgKHZhciBxID0gcmVzLnNxcigpOyBpIDwgdy5sZW5ndGg7IGkrKywgcSA9IHEuc3FyKCkpIHtcbiAgICAgICAgaWYgKHdbaV0gPT09IDApIGNvbnRpbnVlO1xuXG4gICAgICAgIHJlcyA9IHJlcy5tdWwocSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICAvLyBTaGlmdC1sZWZ0IGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pdXNobG4gPSBmdW5jdGlvbiBpdXNobG4gKGJpdHMpIHtcbiAgICBhc3NlcnQodHlwZW9mIGJpdHMgPT09ICdudW1iZXInICYmIGJpdHMgPj0gMCk7XG4gICAgdmFyIHIgPSBiaXRzICUgMjY7XG4gICAgdmFyIHMgPSAoYml0cyAtIHIpIC8gMjY7XG4gICAgdmFyIGNhcnJ5TWFzayA9ICgweDNmZmZmZmYgPj4+ICgyNiAtIHIpKSA8PCAoMjYgLSByKTtcbiAgICB2YXIgaTtcblxuICAgIGlmIChyICE9PSAwKSB7XG4gICAgICB2YXIgY2FycnkgPSAwO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgbmV3Q2FycnkgPSB0aGlzLndvcmRzW2ldICYgY2FycnlNYXNrO1xuICAgICAgICB2YXIgYyA9ICgodGhpcy53b3Jkc1tpXSB8IDApIC0gbmV3Q2FycnkpIDw8IHI7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSBjIHwgY2Fycnk7XG4gICAgICAgIGNhcnJ5ID0gbmV3Q2FycnkgPj4+ICgyNiAtIHIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2FycnkpIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSA9IGNhcnJ5O1xuICAgICAgICB0aGlzLmxlbmd0aCsrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzICE9PSAwKSB7XG4gICAgICBmb3IgKGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHRoaXMud29yZHNbaSArIHNdID0gdGhpcy53b3Jkc1tpXTtcbiAgICAgIH1cblxuICAgICAgZm9yIChpID0gMDsgaSA8IHM7IGkrKykge1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gMDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5sZW5ndGggKz0gcztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pc2hsbiA9IGZ1bmN0aW9uIGlzaGxuIChiaXRzKSB7XG4gICAgLy8gVE9ETyhpbmR1dG55KTogaW1wbGVtZW50IG1lXG4gICAgYXNzZXJ0KHRoaXMubmVnYXRpdmUgPT09IDApO1xuICAgIHJldHVybiB0aGlzLml1c2hsbihiaXRzKTtcbiAgfTtcblxuICAvLyBTaGlmdC1yaWdodCBpbi1wbGFjZVxuICAvLyBOT1RFOiBgaGludGAgaXMgYSBsb3dlc3QgYml0IGJlZm9yZSB0cmFpbGluZyB6ZXJvZXNcbiAgLy8gTk9URTogaWYgYGV4dGVuZGVkYCBpcyBwcmVzZW50IC0gaXQgd2lsbCBiZSBmaWxsZWQgd2l0aCBkZXN0cm95ZWQgYml0c1xuICBCTi5wcm90b3R5cGUuaXVzaHJuID0gZnVuY3Rpb24gaXVzaHJuIChiaXRzLCBoaW50LCBleHRlbmRlZCkge1xuICAgIGFzc2VydCh0eXBlb2YgYml0cyA9PT0gJ251bWJlcicgJiYgYml0cyA+PSAwKTtcbiAgICB2YXIgaDtcbiAgICBpZiAoaGludCkge1xuICAgICAgaCA9IChoaW50IC0gKGhpbnQgJSAyNikpIC8gMjY7XG4gICAgfSBlbHNlIHtcbiAgICAgIGggPSAwO1xuICAgIH1cblxuICAgIHZhciByID0gYml0cyAlIDI2O1xuICAgIHZhciBzID0gTWF0aC5taW4oKGJpdHMgLSByKSAvIDI2LCB0aGlzLmxlbmd0aCk7XG4gICAgdmFyIG1hc2sgPSAweDNmZmZmZmYgXiAoKDB4M2ZmZmZmZiA+Pj4gcikgPDwgcik7XG4gICAgdmFyIG1hc2tlZFdvcmRzID0gZXh0ZW5kZWQ7XG5cbiAgICBoIC09IHM7XG4gICAgaCA9IE1hdGgubWF4KDAsIGgpO1xuXG4gICAgLy8gRXh0ZW5kZWQgbW9kZSwgY29weSBtYXNrZWQgcGFydFxuICAgIGlmIChtYXNrZWRXb3Jkcykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzOyBpKyspIHtcbiAgICAgICAgbWFza2VkV29yZHMud29yZHNbaV0gPSB0aGlzLndvcmRzW2ldO1xuICAgICAgfVxuICAgICAgbWFza2VkV29yZHMubGVuZ3RoID0gcztcbiAgICB9XG5cbiAgICBpZiAocyA9PT0gMCkge1xuICAgICAgLy8gTm8tb3AsIHdlIHNob3VsZCBub3QgbW92ZSBhbnl0aGluZyBhdCBhbGxcbiAgICB9IGVsc2UgaWYgKHRoaXMubGVuZ3RoID4gcykge1xuICAgICAgdGhpcy5sZW5ndGggLT0gcztcbiAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSB0aGlzLndvcmRzW2kgKyBzXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy53b3Jkc1swXSA9IDA7XG4gICAgICB0aGlzLmxlbmd0aCA9IDE7XG4gICAgfVxuXG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMCAmJiAoY2FycnkgIT09IDAgfHwgaSA+PSBoKTsgaS0tKSB7XG4gICAgICB2YXIgd29yZCA9IHRoaXMud29yZHNbaV0gfCAwO1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IChjYXJyeSA8PCAoMjYgLSByKSkgfCAod29yZCA+Pj4gcik7XG4gICAgICBjYXJyeSA9IHdvcmQgJiBtYXNrO1xuICAgIH1cblxuICAgIC8vIFB1c2ggY2FycmllZCBiaXRzIGFzIGEgbWFza1xuICAgIGlmIChtYXNrZWRXb3JkcyAmJiBjYXJyeSAhPT0gMCkge1xuICAgICAgbWFza2VkV29yZHMud29yZHNbbWFza2VkV29yZHMubGVuZ3RoKytdID0gY2Fycnk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLndvcmRzWzBdID0gMDtcbiAgICAgIHRoaXMubGVuZ3RoID0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pc2hybiA9IGZ1bmN0aW9uIGlzaHJuIChiaXRzLCBoaW50LCBleHRlbmRlZCkge1xuICAgIC8vIFRPRE8oaW5kdXRueSk6IGltcGxlbWVudCBtZVxuICAgIGFzc2VydCh0aGlzLm5lZ2F0aXZlID09PSAwKTtcbiAgICByZXR1cm4gdGhpcy5pdXNocm4oYml0cywgaGludCwgZXh0ZW5kZWQpO1xuICB9O1xuXG4gIC8vIFNoaWZ0LWxlZnRcbiAgQk4ucHJvdG90eXBlLnNobG4gPSBmdW5jdGlvbiBzaGxuIChiaXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pc2hsbihiaXRzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudXNobG4gPSBmdW5jdGlvbiB1c2hsbiAoYml0cykge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaXVzaGxuKGJpdHMpO1xuICB9O1xuXG4gIC8vIFNoaWZ0LXJpZ2h0XG4gIEJOLnByb3RvdHlwZS5zaHJuID0gZnVuY3Rpb24gc2hybiAoYml0cykge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaXNocm4oYml0cyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnVzaHJuID0gZnVuY3Rpb24gdXNocm4gKGJpdHMpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLml1c2hybihiaXRzKTtcbiAgfTtcblxuICAvLyBUZXN0IGlmIG4gYml0IGlzIHNldFxuICBCTi5wcm90b3R5cGUudGVzdG4gPSBmdW5jdGlvbiB0ZXN0biAoYml0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBiaXQgPT09ICdudW1iZXInICYmIGJpdCA+PSAwKTtcbiAgICB2YXIgciA9IGJpdCAlIDI2O1xuICAgIHZhciBzID0gKGJpdCAtIHIpIC8gMjY7XG4gICAgdmFyIHEgPSAxIDw8IHI7XG5cbiAgICAvLyBGYXN0IGNhc2U6IGJpdCBpcyBtdWNoIGhpZ2hlciB0aGFuIGFsbCBleGlzdGluZyB3b3Jkc1xuICAgIGlmICh0aGlzLmxlbmd0aCA8PSBzKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBDaGVjayBiaXQgYW5kIHJldHVyblxuICAgIHZhciB3ID0gdGhpcy53b3Jkc1tzXTtcblxuICAgIHJldHVybiAhISh3ICYgcSk7XG4gIH07XG5cbiAgLy8gUmV0dXJuIG9ubHkgbG93ZXJzIGJpdHMgb2YgbnVtYmVyIChpbi1wbGFjZSlcbiAgQk4ucHJvdG90eXBlLmltYXNrbiA9IGZ1bmN0aW9uIGltYXNrbiAoYml0cykge1xuICAgIGFzc2VydCh0eXBlb2YgYml0cyA9PT0gJ251bWJlcicgJiYgYml0cyA+PSAwKTtcbiAgICB2YXIgciA9IGJpdHMgJSAyNjtcbiAgICB2YXIgcyA9IChiaXRzIC0gcikgLyAyNjtcblxuICAgIGFzc2VydCh0aGlzLm5lZ2F0aXZlID09PSAwLCAnaW1hc2tuIHdvcmtzIG9ubHkgd2l0aCBwb3NpdGl2ZSBudW1iZXJzJyk7XG5cbiAgICBpZiAociAhPT0gMCkge1xuICAgICAgcysrO1xuICAgIH1cbiAgICB0aGlzLmxlbmd0aCA9IE1hdGgubWluKHMsIHRoaXMubGVuZ3RoKTtcblxuICAgIGlmIChyICE9PSAwKSB7XG4gICAgICB2YXIgbWFzayA9IDB4M2ZmZmZmZiBeICgoMHgzZmZmZmZmID4+PiByKSA8PCByKTtcbiAgICAgIHRoaXMud29yZHNbdGhpcy5sZW5ndGggLSAxXSAmPSBtYXNrO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgLy8gUmV0dXJuIG9ubHkgbG93ZXJzIGJpdHMgb2YgbnVtYmVyXG4gIEJOLnByb3RvdHlwZS5tYXNrbiA9IGZ1bmN0aW9uIG1hc2tuIChiaXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pbWFza24oYml0cyk7XG4gIH07XG5cbiAgLy8gQWRkIHBsYWluIG51bWJlciBgbnVtYCB0byBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLmlhZGRuID0gZnVuY3Rpb24gaWFkZG4gKG51bSkge1xuICAgIGFzc2VydCh0eXBlb2YgbnVtID09PSAnbnVtYmVyJyk7XG4gICAgYXNzZXJ0KG51bSA8IDB4NDAwMDAwMCk7XG4gICAgaWYgKG51bSA8IDApIHJldHVybiB0aGlzLmlzdWJuKC1udW0pO1xuXG4gICAgLy8gUG9zc2libGUgc2lnbiBjaGFuZ2VcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAxICYmICh0aGlzLndvcmRzWzBdIHwgMCkgPCBudW0pIHtcbiAgICAgICAgdGhpcy53b3Jkc1swXSA9IG51bSAtICh0aGlzLndvcmRzWzBdIHwgMCk7XG4gICAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICB0aGlzLmlzdWJuKG51bSk7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCB3aXRob3V0IGNoZWNrc1xuICAgIHJldHVybiB0aGlzLl9pYWRkbihudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5faWFkZG4gPSBmdW5jdGlvbiBfaWFkZG4gKG51bSkge1xuICAgIHRoaXMud29yZHNbMF0gKz0gbnVtO1xuXG4gICAgLy8gQ2FycnlcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoICYmIHRoaXMud29yZHNbaV0gPj0gMHg0MDAwMDAwOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gLT0gMHg0MDAwMDAwO1xuICAgICAgaWYgKGkgPT09IHRoaXMubGVuZ3RoIC0gMSkge1xuICAgICAgICB0aGlzLndvcmRzW2kgKyAxXSA9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLndvcmRzW2kgKyAxXSsrO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmxlbmd0aCA9IE1hdGgubWF4KHRoaXMubGVuZ3RoLCBpICsgMSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvLyBTdWJ0cmFjdCBwbGFpbiBudW1iZXIgYG51bWAgZnJvbSBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLmlzdWJuID0gZnVuY3Rpb24gaXN1Ym4gKG51bSkge1xuICAgIGFzc2VydCh0eXBlb2YgbnVtID09PSAnbnVtYmVyJyk7XG4gICAgYXNzZXJ0KG51bSA8IDB4NDAwMDAwMCk7XG4gICAgaWYgKG51bSA8IDApIHJldHVybiB0aGlzLmlhZGRuKC1udW0pO1xuXG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgdGhpcy5pYWRkbihudW0pO1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB0aGlzLndvcmRzWzBdIC09IG51bTtcblxuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSAmJiB0aGlzLndvcmRzWzBdIDwgMCkge1xuICAgICAgdGhpcy53b3Jkc1swXSA9IC10aGlzLndvcmRzWzBdO1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENhcnJ5XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoICYmIHRoaXMud29yZHNbaV0gPCAwOyBpKyspIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSArPSAweDQwMDAwMDA7XG4gICAgICAgIHRoaXMud29yZHNbaSArIDFdIC09IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuYWRkbiA9IGZ1bmN0aW9uIGFkZG4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaWFkZG4obnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuc3VibiA9IGZ1bmN0aW9uIHN1Ym4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaXN1Ym4obnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaWFicyA9IGZ1bmN0aW9uIGlhYnMgKCkge1xuICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmFicyA9IGZ1bmN0aW9uIGFicyAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pYWJzKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9pc2hsbnN1Ym11bCA9IGZ1bmN0aW9uIF9pc2hsbnN1Ym11bCAobnVtLCBtdWwsIHNoaWZ0KSB7XG4gICAgdmFyIGxlbiA9IG51bS5sZW5ndGggKyBzaGlmdDtcbiAgICB2YXIgaTtcblxuICAgIHRoaXMuX2V4cGFuZChsZW4pO1xuXG4gICAgdmFyIHc7XG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtLmxlbmd0aDsgaSsrKSB7XG4gICAgICB3ID0gKHRoaXMud29yZHNbaSArIHNoaWZ0XSB8IDApICsgY2Fycnk7XG4gICAgICB2YXIgcmlnaHQgPSAobnVtLndvcmRzW2ldIHwgMCkgKiBtdWw7XG4gICAgICB3IC09IHJpZ2h0ICYgMHgzZmZmZmZmO1xuICAgICAgY2FycnkgPSAodyA+PiAyNikgLSAoKHJpZ2h0IC8gMHg0MDAwMDAwKSB8IDApO1xuICAgICAgdGhpcy53b3Jkc1tpICsgc2hpZnRdID0gdyAmIDB4M2ZmZmZmZjtcbiAgICB9XG4gICAgZm9yICg7IGkgPCB0aGlzLmxlbmd0aCAtIHNoaWZ0OyBpKyspIHtcbiAgICAgIHcgPSAodGhpcy53b3Jkc1tpICsgc2hpZnRdIHwgMCkgKyBjYXJyeTtcbiAgICAgIGNhcnJ5ID0gdyA+PiAyNjtcbiAgICAgIHRoaXMud29yZHNbaSArIHNoaWZ0XSA9IHcgJiAweDNmZmZmZmY7XG4gICAgfVxuXG4gICAgaWYgKGNhcnJ5ID09PSAwKSByZXR1cm4gdGhpcy5zdHJpcCgpO1xuXG4gICAgLy8gU3VidHJhY3Rpb24gb3ZlcmZsb3dcbiAgICBhc3NlcnQoY2FycnkgPT09IC0xKTtcbiAgICBjYXJyeSA9IDA7XG4gICAgZm9yIChpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHcgPSAtKHRoaXMud29yZHNbaV0gfCAwKSArIGNhcnJ5O1xuICAgICAgY2FycnkgPSB3ID4+IDI2O1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHcgJiAweDNmZmZmZmY7XG4gICAgfVxuICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX3dvcmREaXYgPSBmdW5jdGlvbiBfd29yZERpdiAobnVtLCBtb2RlKSB7XG4gICAgdmFyIHNoaWZ0ID0gdGhpcy5sZW5ndGggLSBudW0ubGVuZ3RoO1xuXG4gICAgdmFyIGEgPSB0aGlzLmNsb25lKCk7XG4gICAgdmFyIGIgPSBudW07XG5cbiAgICAvLyBOb3JtYWxpemVcbiAgICB2YXIgYmhpID0gYi53b3Jkc1tiLmxlbmd0aCAtIDFdIHwgMDtcbiAgICB2YXIgYmhpQml0cyA9IHRoaXMuX2NvdW50Qml0cyhiaGkpO1xuICAgIHNoaWZ0ID0gMjYgLSBiaGlCaXRzO1xuICAgIGlmIChzaGlmdCAhPT0gMCkge1xuICAgICAgYiA9IGIudXNobG4oc2hpZnQpO1xuICAgICAgYS5pdXNobG4oc2hpZnQpO1xuICAgICAgYmhpID0gYi53b3Jkc1tiLmxlbmd0aCAtIDFdIHwgMDtcbiAgICB9XG5cbiAgICAvLyBJbml0aWFsaXplIHF1b3RpZW50XG4gICAgdmFyIG0gPSBhLmxlbmd0aCAtIGIubGVuZ3RoO1xuICAgIHZhciBxO1xuXG4gICAgaWYgKG1vZGUgIT09ICdtb2QnKSB7XG4gICAgICBxID0gbmV3IEJOKG51bGwpO1xuICAgICAgcS5sZW5ndGggPSBtICsgMTtcbiAgICAgIHEud29yZHMgPSBuZXcgQXJyYXkocS5sZW5ndGgpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBxLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHEud29yZHNbaV0gPSAwO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkaWZmID0gYS5jbG9uZSgpLl9pc2hsbnN1Ym11bChiLCAxLCBtKTtcbiAgICBpZiAoZGlmZi5uZWdhdGl2ZSA9PT0gMCkge1xuICAgICAgYSA9IGRpZmY7XG4gICAgICBpZiAocSkge1xuICAgICAgICBxLndvcmRzW21dID0gMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKHZhciBqID0gbSAtIDE7IGogPj0gMDsgai0tKSB7XG4gICAgICB2YXIgcWogPSAoYS53b3Jkc1tiLmxlbmd0aCArIGpdIHwgMCkgKiAweDQwMDAwMDAgK1xuICAgICAgICAoYS53b3Jkc1tiLmxlbmd0aCArIGogLSAxXSB8IDApO1xuXG4gICAgICAvLyBOT1RFOiAocWogLyBiaGkpIGlzICgweDNmZmZmZmYgKiAweDQwMDAwMDAgKyAweDNmZmZmZmYpIC8gMHgyMDAwMDAwIG1heFxuICAgICAgLy8gKDB4N2ZmZmZmZilcbiAgICAgIHFqID0gTWF0aC5taW4oKHFqIC8gYmhpKSB8IDAsIDB4M2ZmZmZmZik7XG5cbiAgICAgIGEuX2lzaGxuc3VibXVsKGIsIHFqLCBqKTtcbiAgICAgIHdoaWxlIChhLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICAgIHFqLS07XG4gICAgICAgIGEubmVnYXRpdmUgPSAwO1xuICAgICAgICBhLl9pc2hsbnN1Ym11bChiLCAxLCBqKTtcbiAgICAgICAgaWYgKCFhLmlzWmVybygpKSB7XG4gICAgICAgICAgYS5uZWdhdGl2ZSBePSAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAocSkge1xuICAgICAgICBxLndvcmRzW2pdID0gcWo7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChxKSB7XG4gICAgICBxLnN0cmlwKCk7XG4gICAgfVxuICAgIGEuc3RyaXAoKTtcblxuICAgIC8vIERlbm9ybWFsaXplXG4gICAgaWYgKG1vZGUgIT09ICdkaXYnICYmIHNoaWZ0ICE9PSAwKSB7XG4gICAgICBhLml1c2hybihzaGlmdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRpdjogcSB8fCBudWxsLFxuICAgICAgbW9kOiBhXG4gICAgfTtcbiAgfTtcblxuICAvLyBOT1RFOiAxKSBgbW9kZWAgY2FuIGJlIHNldCB0byBgbW9kYCB0byByZXF1ZXN0IG1vZCBvbmx5LFxuICAvLyAgICAgICB0byBgZGl2YCB0byByZXF1ZXN0IGRpdiBvbmx5LCBvciBiZSBhYnNlbnQgdG9cbiAgLy8gICAgICAgcmVxdWVzdCBib3RoIGRpdiAmIG1vZFxuICAvLyAgICAgICAyKSBgcG9zaXRpdmVgIGlzIHRydWUgaWYgdW5zaWduZWQgbW9kIGlzIHJlcXVlc3RlZFxuICBCTi5wcm90b3R5cGUuZGl2bW9kID0gZnVuY3Rpb24gZGl2bW9kIChudW0sIG1vZGUsIHBvc2l0aXZlKSB7XG4gICAgYXNzZXJ0KCFudW0uaXNaZXJvKCkpO1xuXG4gICAgaWYgKHRoaXMuaXNaZXJvKCkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRpdjogbmV3IEJOKDApLFxuICAgICAgICBtb2Q6IG5ldyBCTigwKVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgZGl2LCBtb2QsIHJlcztcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCAmJiBudW0ubmVnYXRpdmUgPT09IDApIHtcbiAgICAgIHJlcyA9IHRoaXMubmVnKCkuZGl2bW9kKG51bSwgbW9kZSk7XG5cbiAgICAgIGlmIChtb2RlICE9PSAnbW9kJykge1xuICAgICAgICBkaXYgPSByZXMuZGl2Lm5lZygpO1xuICAgICAgfVxuXG4gICAgICBpZiAobW9kZSAhPT0gJ2RpdicpIHtcbiAgICAgICAgbW9kID0gcmVzLm1vZC5uZWcoKTtcbiAgICAgICAgaWYgKHBvc2l0aXZlICYmIG1vZC5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgICAgIG1vZC5pYWRkKG51bSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGl2OiBkaXYsXG4gICAgICAgIG1vZDogbW9kXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLm5lZ2F0aXZlID09PSAwICYmIG51bS5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgcmVzID0gdGhpcy5kaXZtb2QobnVtLm5lZygpLCBtb2RlKTtcblxuICAgICAgaWYgKG1vZGUgIT09ICdtb2QnKSB7XG4gICAgICAgIGRpdiA9IHJlcy5kaXYubmVnKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRpdjogZGl2LFxuICAgICAgICBtb2Q6IHJlcy5tb2RcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKCh0aGlzLm5lZ2F0aXZlICYgbnVtLm5lZ2F0aXZlKSAhPT0gMCkge1xuICAgICAgcmVzID0gdGhpcy5uZWcoKS5kaXZtb2QobnVtLm5lZygpLCBtb2RlKTtcblxuICAgICAgaWYgKG1vZGUgIT09ICdkaXYnKSB7XG4gICAgICAgIG1vZCA9IHJlcy5tb2QubmVnKCk7XG4gICAgICAgIGlmIChwb3NpdGl2ZSAmJiBtb2QubmVnYXRpdmUgIT09IDApIHtcbiAgICAgICAgICBtb2QuaXN1YihudW0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRpdjogcmVzLmRpdixcbiAgICAgICAgbW9kOiBtb2RcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gQm90aCBudW1iZXJzIGFyZSBwb3NpdGl2ZSBhdCB0aGlzIHBvaW50XG5cbiAgICAvLyBTdHJpcCBib3RoIG51bWJlcnMgdG8gYXBwcm94aW1hdGUgc2hpZnQgdmFsdWVcbiAgICBpZiAobnVtLmxlbmd0aCA+IHRoaXMubGVuZ3RoIHx8IHRoaXMuY21wKG51bSkgPCAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBkaXY6IG5ldyBCTigwKSxcbiAgICAgICAgbW9kOiB0aGlzXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFZlcnkgc2hvcnQgcmVkdWN0aW9uXG4gICAgaWYgKG51bS5sZW5ndGggPT09IDEpIHtcbiAgICAgIGlmIChtb2RlID09PSAnZGl2Jykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGRpdjogdGhpcy5kaXZuKG51bS53b3Jkc1swXSksXG4gICAgICAgICAgbW9kOiBudWxsXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGlmIChtb2RlID09PSAnbW9kJykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGRpdjogbnVsbCxcbiAgICAgICAgICBtb2Q6IG5ldyBCTih0aGlzLm1vZG4obnVtLndvcmRzWzBdKSlcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGl2OiB0aGlzLmRpdm4obnVtLndvcmRzWzBdKSxcbiAgICAgICAgbW9kOiBuZXcgQk4odGhpcy5tb2RuKG51bS53b3Jkc1swXSkpXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl93b3JkRGl2KG51bSwgbW9kZSk7XG4gIH07XG5cbiAgLy8gRmluZCBgdGhpc2AgLyBgbnVtYFxuICBCTi5wcm90b3R5cGUuZGl2ID0gZnVuY3Rpb24gZGl2IChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5kaXZtb2QobnVtLCAnZGl2JywgZmFsc2UpLmRpdjtcbiAgfTtcblxuICAvLyBGaW5kIGB0aGlzYCAlIGBudW1gXG4gIEJOLnByb3RvdHlwZS5tb2QgPSBmdW5jdGlvbiBtb2QgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmRpdm1vZChudW0sICdtb2QnLCBmYWxzZSkubW9kO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51bW9kID0gZnVuY3Rpb24gdW1vZCAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuZGl2bW9kKG51bSwgJ21vZCcsIHRydWUpLm1vZDtcbiAgfTtcblxuICAvLyBGaW5kIFJvdW5kKGB0aGlzYCAvIGBudW1gKVxuICBCTi5wcm90b3R5cGUuZGl2Um91bmQgPSBmdW5jdGlvbiBkaXZSb3VuZCAobnVtKSB7XG4gICAgdmFyIGRtID0gdGhpcy5kaXZtb2QobnVtKTtcblxuICAgIC8vIEZhc3QgY2FzZSAtIGV4YWN0IGRpdmlzaW9uXG4gICAgaWYgKGRtLm1vZC5pc1plcm8oKSkgcmV0dXJuIGRtLmRpdjtcblxuICAgIHZhciBtb2QgPSBkbS5kaXYubmVnYXRpdmUgIT09IDAgPyBkbS5tb2QuaXN1YihudW0pIDogZG0ubW9kO1xuXG4gICAgdmFyIGhhbGYgPSBudW0udXNocm4oMSk7XG4gICAgdmFyIHIyID0gbnVtLmFuZGxuKDEpO1xuICAgIHZhciBjbXAgPSBtb2QuY21wKGhhbGYpO1xuXG4gICAgLy8gUm91bmQgZG93blxuICAgIGlmIChjbXAgPCAwIHx8IHIyID09PSAxICYmIGNtcCA9PT0gMCkgcmV0dXJuIGRtLmRpdjtcblxuICAgIC8vIFJvdW5kIHVwXG4gICAgcmV0dXJuIGRtLmRpdi5uZWdhdGl2ZSAhPT0gMCA/IGRtLmRpdi5pc3VibigxKSA6IGRtLmRpdi5pYWRkbigxKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubW9kbiA9IGZ1bmN0aW9uIG1vZG4gKG51bSkge1xuICAgIGFzc2VydChudW0gPD0gMHgzZmZmZmZmKTtcbiAgICB2YXIgcCA9ICgxIDw8IDI2KSAlIG51bTtcblxuICAgIHZhciBhY2MgPSAwO1xuICAgIGZvciAodmFyIGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBhY2MgPSAocCAqIGFjYyArICh0aGlzLndvcmRzW2ldIHwgMCkpICUgbnVtO1xuICAgIH1cblxuICAgIHJldHVybiBhY2M7XG4gIH07XG5cbiAgLy8gSW4tcGxhY2UgZGl2aXNpb24gYnkgbnVtYmVyXG4gIEJOLnByb3RvdHlwZS5pZGl2biA9IGZ1bmN0aW9uIGlkaXZuIChudW0pIHtcbiAgICBhc3NlcnQobnVtIDw9IDB4M2ZmZmZmZik7XG5cbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgdyA9ICh0aGlzLndvcmRzW2ldIHwgMCkgKyBjYXJyeSAqIDB4NDAwMDAwMDtcbiAgICAgIHRoaXMud29yZHNbaV0gPSAodyAvIG51bSkgfCAwO1xuICAgICAgY2FycnkgPSB3ICUgbnVtO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmRpdm4gPSBmdW5jdGlvbiBkaXZuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlkaXZuKG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmVnY2QgPSBmdW5jdGlvbiBlZ2NkIChwKSB7XG4gICAgYXNzZXJ0KHAubmVnYXRpdmUgPT09IDApO1xuICAgIGFzc2VydCghcC5pc1plcm8oKSk7XG5cbiAgICB2YXIgeCA9IHRoaXM7XG4gICAgdmFyIHkgPSBwLmNsb25lKCk7XG5cbiAgICBpZiAoeC5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgeCA9IHgudW1vZChwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgeCA9IHguY2xvbmUoKTtcbiAgICB9XG5cbiAgICAvLyBBICogeCArIEIgKiB5ID0geFxuICAgIHZhciBBID0gbmV3IEJOKDEpO1xuICAgIHZhciBCID0gbmV3IEJOKDApO1xuXG4gICAgLy8gQyAqIHggKyBEICogeSA9IHlcbiAgICB2YXIgQyA9IG5ldyBCTigwKTtcbiAgICB2YXIgRCA9IG5ldyBCTigxKTtcblxuICAgIHZhciBnID0gMDtcblxuICAgIHdoaWxlICh4LmlzRXZlbigpICYmIHkuaXNFdmVuKCkpIHtcbiAgICAgIHguaXVzaHJuKDEpO1xuICAgICAgeS5pdXNocm4oMSk7XG4gICAgICArK2c7XG4gICAgfVxuXG4gICAgdmFyIHlwID0geS5jbG9uZSgpO1xuICAgIHZhciB4cCA9IHguY2xvbmUoKTtcblxuICAgIHdoaWxlICgheC5pc1plcm8oKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGltID0gMTsgKHgud29yZHNbMF0gJiBpbSkgPT09IDAgJiYgaSA8IDI2OyArK2ksIGltIDw8PSAxKTtcbiAgICAgIGlmIChpID4gMCkge1xuICAgICAgICB4Lml1c2hybihpKTtcbiAgICAgICAgd2hpbGUgKGktLSA+IDApIHtcbiAgICAgICAgICBpZiAoQS5pc09kZCgpIHx8IEIuaXNPZGQoKSkge1xuICAgICAgICAgICAgQS5pYWRkKHlwKTtcbiAgICAgICAgICAgIEIuaXN1Yih4cCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgQS5pdXNocm4oMSk7XG4gICAgICAgICAgQi5pdXNocm4oMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaiA9IDAsIGptID0gMTsgKHkud29yZHNbMF0gJiBqbSkgPT09IDAgJiYgaiA8IDI2OyArK2osIGptIDw8PSAxKTtcbiAgICAgIGlmIChqID4gMCkge1xuICAgICAgICB5Lml1c2hybihqKTtcbiAgICAgICAgd2hpbGUgKGotLSA+IDApIHtcbiAgICAgICAgICBpZiAoQy5pc09kZCgpIHx8IEQuaXNPZGQoKSkge1xuICAgICAgICAgICAgQy5pYWRkKHlwKTtcbiAgICAgICAgICAgIEQuaXN1Yih4cCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgQy5pdXNocm4oMSk7XG4gICAgICAgICAgRC5pdXNocm4oMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHguY21wKHkpID49IDApIHtcbiAgICAgICAgeC5pc3ViKHkpO1xuICAgICAgICBBLmlzdWIoQyk7XG4gICAgICAgIEIuaXN1YihEKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHkuaXN1Yih4KTtcbiAgICAgICAgQy5pc3ViKEEpO1xuICAgICAgICBELmlzdWIoQik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGE6IEMsXG4gICAgICBiOiBELFxuICAgICAgZ2NkOiB5Lml1c2hsbihnKVxuICAgIH07XG4gIH07XG5cbiAgLy8gVGhpcyBpcyByZWR1Y2VkIGluY2FybmF0aW9uIG9mIHRoZSBiaW5hcnkgRUVBXG4gIC8vIGFib3ZlLCBkZXNpZ25hdGVkIHRvIGludmVydCBtZW1iZXJzIG9mIHRoZVxuICAvLyBfcHJpbWVfIGZpZWxkcyBGKHApIGF0IGEgbWF4aW1hbCBzcGVlZFxuICBCTi5wcm90b3R5cGUuX2ludm1wID0gZnVuY3Rpb24gX2ludm1wIChwKSB7XG4gICAgYXNzZXJ0KHAubmVnYXRpdmUgPT09IDApO1xuICAgIGFzc2VydCghcC5pc1plcm8oKSk7XG5cbiAgICB2YXIgYSA9IHRoaXM7XG4gICAgdmFyIGIgPSBwLmNsb25lKCk7XG5cbiAgICBpZiAoYS5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgYSA9IGEudW1vZChwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYSA9IGEuY2xvbmUoKTtcbiAgICB9XG5cbiAgICB2YXIgeDEgPSBuZXcgQk4oMSk7XG4gICAgdmFyIHgyID0gbmV3IEJOKDApO1xuXG4gICAgdmFyIGRlbHRhID0gYi5jbG9uZSgpO1xuXG4gICAgd2hpbGUgKGEuY21wbigxKSA+IDAgJiYgYi5jbXBuKDEpID4gMCkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGltID0gMTsgKGEud29yZHNbMF0gJiBpbSkgPT09IDAgJiYgaSA8IDI2OyArK2ksIGltIDw8PSAxKTtcbiAgICAgIGlmIChpID4gMCkge1xuICAgICAgICBhLml1c2hybihpKTtcbiAgICAgICAgd2hpbGUgKGktLSA+IDApIHtcbiAgICAgICAgICBpZiAoeDEuaXNPZGQoKSkge1xuICAgICAgICAgICAgeDEuaWFkZChkZWx0YSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgeDEuaXVzaHJuKDEpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGogPSAwLCBqbSA9IDE7IChiLndvcmRzWzBdICYgam0pID09PSAwICYmIGogPCAyNjsgKytqLCBqbSA8PD0gMSk7XG4gICAgICBpZiAoaiA+IDApIHtcbiAgICAgICAgYi5pdXNocm4oaik7XG4gICAgICAgIHdoaWxlIChqLS0gPiAwKSB7XG4gICAgICAgICAgaWYgKHgyLmlzT2RkKCkpIHtcbiAgICAgICAgICAgIHgyLmlhZGQoZGVsdGEpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHgyLml1c2hybigxKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoYS5jbXAoYikgPj0gMCkge1xuICAgICAgICBhLmlzdWIoYik7XG4gICAgICAgIHgxLmlzdWIoeDIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYi5pc3ViKGEpO1xuICAgICAgICB4Mi5pc3ViKHgxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVzO1xuICAgIGlmIChhLmNtcG4oMSkgPT09IDApIHtcbiAgICAgIHJlcyA9IHgxO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMgPSB4MjtcbiAgICB9XG5cbiAgICBpZiAocmVzLmNtcG4oMCkgPCAwKSB7XG4gICAgICByZXMuaWFkZChwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5nY2QgPSBmdW5jdGlvbiBnY2QgKG51bSkge1xuICAgIGlmICh0aGlzLmlzWmVybygpKSByZXR1cm4gbnVtLmFicygpO1xuICAgIGlmIChudW0uaXNaZXJvKCkpIHJldHVybiB0aGlzLmFicygpO1xuXG4gICAgdmFyIGEgPSB0aGlzLmNsb25lKCk7XG4gICAgdmFyIGIgPSBudW0uY2xvbmUoKTtcbiAgICBhLm5lZ2F0aXZlID0gMDtcbiAgICBiLm5lZ2F0aXZlID0gMDtcblxuICAgIC8vIFJlbW92ZSBjb21tb24gZmFjdG9yIG9mIHR3b1xuICAgIGZvciAodmFyIHNoaWZ0ID0gMDsgYS5pc0V2ZW4oKSAmJiBiLmlzRXZlbigpOyBzaGlmdCsrKSB7XG4gICAgICBhLml1c2hybigxKTtcbiAgICAgIGIuaXVzaHJuKDEpO1xuICAgIH1cblxuICAgIGRvIHtcbiAgICAgIHdoaWxlIChhLmlzRXZlbigpKSB7XG4gICAgICAgIGEuaXVzaHJuKDEpO1xuICAgICAgfVxuICAgICAgd2hpbGUgKGIuaXNFdmVuKCkpIHtcbiAgICAgICAgYi5pdXNocm4oMSk7XG4gICAgICB9XG5cbiAgICAgIHZhciByID0gYS5jbXAoYik7XG4gICAgICBpZiAociA8IDApIHtcbiAgICAgICAgLy8gU3dhcCBgYWAgYW5kIGBiYCB0byBtYWtlIGBhYCBhbHdheXMgYmlnZ2VyIHRoYW4gYGJgXG4gICAgICAgIHZhciB0ID0gYTtcbiAgICAgICAgYSA9IGI7XG4gICAgICAgIGIgPSB0O1xuICAgICAgfSBlbHNlIGlmIChyID09PSAwIHx8IGIuY21wbigxKSA9PT0gMCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgYS5pc3ViKGIpO1xuICAgIH0gd2hpbGUgKHRydWUpO1xuXG4gICAgcmV0dXJuIGIuaXVzaGxuKHNoaWZ0KTtcbiAgfTtcblxuICAvLyBJbnZlcnQgbnVtYmVyIGluIHRoZSBmaWVsZCBGKG51bSlcbiAgQk4ucHJvdG90eXBlLmludm0gPSBmdW5jdGlvbiBpbnZtIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5lZ2NkKG51bSkuYS51bW9kKG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlzRXZlbiA9IGZ1bmN0aW9uIGlzRXZlbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLndvcmRzWzBdICYgMSkgPT09IDA7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlzT2RkID0gZnVuY3Rpb24gaXNPZGQgKCkge1xuICAgIHJldHVybiAodGhpcy53b3Jkc1swXSAmIDEpID09PSAxO1xuICB9O1xuXG4gIC8vIEFuZCBmaXJzdCB3b3JkIGFuZCBudW1cbiAgQk4ucHJvdG90eXBlLmFuZGxuID0gZnVuY3Rpb24gYW5kbG4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLndvcmRzWzBdICYgbnVtO1xuICB9O1xuXG4gIC8vIEluY3JlbWVudCBhdCB0aGUgYml0IHBvc2l0aW9uIGluLWxpbmVcbiAgQk4ucHJvdG90eXBlLmJpbmNuID0gZnVuY3Rpb24gYmluY24gKGJpdCkge1xuICAgIGFzc2VydCh0eXBlb2YgYml0ID09PSAnbnVtYmVyJyk7XG4gICAgdmFyIHIgPSBiaXQgJSAyNjtcbiAgICB2YXIgcyA9IChiaXQgLSByKSAvIDI2O1xuICAgIHZhciBxID0gMSA8PCByO1xuXG4gICAgLy8gRmFzdCBjYXNlOiBiaXQgaXMgbXVjaCBoaWdoZXIgdGhhbiBhbGwgZXhpc3Rpbmcgd29yZHNcbiAgICBpZiAodGhpcy5sZW5ndGggPD0gcykge1xuICAgICAgdGhpcy5fZXhwYW5kKHMgKyAxKTtcbiAgICAgIHRoaXMud29yZHNbc10gfD0gcTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBiaXQgYW5kIHByb3BhZ2F0ZSwgaWYgbmVlZGVkXG4gICAgdmFyIGNhcnJ5ID0gcTtcbiAgICBmb3IgKHZhciBpID0gczsgY2FycnkgIT09IDAgJiYgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciB3ID0gdGhpcy53b3Jkc1tpXSB8IDA7XG4gICAgICB3ICs9IGNhcnJ5O1xuICAgICAgY2FycnkgPSB3ID4+PiAyNjtcbiAgICAgIHcgJj0gMHgzZmZmZmZmO1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHc7XG4gICAgfVxuICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IGNhcnJ5O1xuICAgICAgdGhpcy5sZW5ndGgrKztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlzWmVybyA9IGZ1bmN0aW9uIGlzWmVybyAoKSB7XG4gICAgcmV0dXJuIHRoaXMubGVuZ3RoID09PSAxICYmIHRoaXMud29yZHNbMF0gPT09IDA7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmNtcG4gPSBmdW5jdGlvbiBjbXBuIChudW0pIHtcbiAgICB2YXIgbmVnYXRpdmUgPSBudW0gPCAwO1xuXG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDAgJiYgIW5lZ2F0aXZlKSByZXR1cm4gLTE7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgPT09IDAgJiYgbmVnYXRpdmUpIHJldHVybiAxO1xuXG4gICAgdGhpcy5zdHJpcCgpO1xuXG4gICAgdmFyIHJlcztcbiAgICBpZiAodGhpcy5sZW5ndGggPiAxKSB7XG4gICAgICByZXMgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobmVnYXRpdmUpIHtcbiAgICAgICAgbnVtID0gLW51bTtcbiAgICAgIH1cblxuICAgICAgYXNzZXJ0KG51bSA8PSAweDNmZmZmZmYsICdOdW1iZXIgaXMgdG9vIGJpZycpO1xuXG4gICAgICB2YXIgdyA9IHRoaXMud29yZHNbMF0gfCAwO1xuICAgICAgcmVzID0gdyA9PT0gbnVtID8gMCA6IHcgPCBudW0gPyAtMSA6IDE7XG4gICAgfVxuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwKSByZXR1cm4gLXJlcyB8IDA7XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICAvLyBDb21wYXJlIHR3byBudW1iZXJzIGFuZCByZXR1cm46XG4gIC8vIDEgLSBpZiBgdGhpc2AgPiBgbnVtYFxuICAvLyAwIC0gaWYgYHRoaXNgID09IGBudW1gXG4gIC8vIC0xIC0gaWYgYHRoaXNgIDwgYG51bWBcbiAgQk4ucHJvdG90eXBlLmNtcCA9IGZ1bmN0aW9uIGNtcCAobnVtKSB7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDAgJiYgbnVtLm5lZ2F0aXZlID09PSAwKSByZXR1cm4gLTE7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgPT09IDAgJiYgbnVtLm5lZ2F0aXZlICE9PSAwKSByZXR1cm4gMTtcblxuICAgIHZhciByZXMgPSB0aGlzLnVjbXAobnVtKTtcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkgcmV0dXJuIC1yZXMgfCAwO1xuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgLy8gVW5zaWduZWQgY29tcGFyaXNvblxuICBCTi5wcm90b3R5cGUudWNtcCA9IGZ1bmN0aW9uIHVjbXAgKG51bSkge1xuICAgIC8vIEF0IHRoaXMgcG9pbnQgYm90aCBudW1iZXJzIGhhdmUgdGhlIHNhbWUgc2lnblxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiAxO1xuICAgIGlmICh0aGlzLmxlbmd0aCA8IG51bS5sZW5ndGgpIHJldHVybiAtMTtcblxuICAgIHZhciByZXMgPSAwO1xuICAgIGZvciAodmFyIGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgYSA9IHRoaXMud29yZHNbaV0gfCAwO1xuICAgICAgdmFyIGIgPSBudW0ud29yZHNbaV0gfCAwO1xuXG4gICAgICBpZiAoYSA9PT0gYikgY29udGludWU7XG4gICAgICBpZiAoYSA8IGIpIHtcbiAgICAgICAgcmVzID0gLTE7XG4gICAgICB9IGVsc2UgaWYgKGEgPiBiKSB7XG4gICAgICAgIHJlcyA9IDE7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZ3RuID0gZnVuY3Rpb24gZ3RuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXBuKG51bSkgPT09IDE7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmd0ID0gZnVuY3Rpb24gZ3QgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcChudW0pID09PSAxO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5ndGVuID0gZnVuY3Rpb24gZ3RlbiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wbihudW0pID49IDA7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmd0ZSA9IGZ1bmN0aW9uIGd0ZSAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wKG51bSkgPj0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubHRuID0gZnVuY3Rpb24gbHRuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXBuKG51bSkgPT09IC0xO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5sdCA9IGZ1bmN0aW9uIGx0IChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXAobnVtKSA9PT0gLTE7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmx0ZW4gPSBmdW5jdGlvbiBsdGVuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXBuKG51bSkgPD0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubHRlID0gZnVuY3Rpb24gbHRlIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXAobnVtKSA8PSAwO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5lcW4gPSBmdW5jdGlvbiBlcW4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcG4obnVtKSA9PT0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZXEgPSBmdW5jdGlvbiBlcSAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wKG51bSkgPT09IDA7XG4gIH07XG5cbiAgLy9cbiAgLy8gQSByZWR1Y2UgY29udGV4dCwgY291bGQgYmUgdXNpbmcgbW9udGdvbWVyeSBvciBzb21ldGhpbmcgYmV0dGVyLCBkZXBlbmRpbmdcbiAgLy8gb24gdGhlIGBtYCBpdHNlbGYuXG4gIC8vXG4gIEJOLnJlZCA9IGZ1bmN0aW9uIHJlZCAobnVtKSB7XG4gICAgcmV0dXJuIG5ldyBSZWQobnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudG9SZWQgPSBmdW5jdGlvbiB0b1JlZCAoY3R4KSB7XG4gICAgYXNzZXJ0KCF0aGlzLnJlZCwgJ0FscmVhZHkgYSBudW1iZXIgaW4gcmVkdWN0aW9uIGNvbnRleHQnKTtcbiAgICBhc3NlcnQodGhpcy5uZWdhdGl2ZSA9PT0gMCwgJ3JlZCB3b3JrcyBvbmx5IHdpdGggcG9zaXRpdmVzJyk7XG4gICAgcmV0dXJuIGN0eC5jb252ZXJ0VG8odGhpcykuX2ZvcmNlUmVkKGN0eCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmZyb21SZWQgPSBmdW5jdGlvbiBmcm9tUmVkICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdmcm9tUmVkIHdvcmtzIG9ubHkgd2l0aCBudW1iZXJzIGluIHJlZHVjdGlvbiBjb250ZXh0Jyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmNvbnZlcnRGcm9tKHRoaXMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5fZm9yY2VSZWQgPSBmdW5jdGlvbiBfZm9yY2VSZWQgKGN0eCkge1xuICAgIHRoaXMucmVkID0gY3R4O1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5mb3JjZVJlZCA9IGZ1bmN0aW9uIGZvcmNlUmVkIChjdHgpIHtcbiAgICBhc3NlcnQoIXRoaXMucmVkLCAnQWxyZWFkeSBhIG51bWJlciBpbiByZWR1Y3Rpb24gY29udGV4dCcpO1xuICAgIHJldHVybiB0aGlzLl9mb3JjZVJlZChjdHgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRBZGQgPSBmdW5jdGlvbiByZWRBZGQgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZEFkZCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICByZXR1cm4gdGhpcy5yZWQuYWRkKHRoaXMsIG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZElBZGQgPSBmdW5jdGlvbiByZWRJQWRkIChudW0pIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRJQWRkIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHJldHVybiB0aGlzLnJlZC5pYWRkKHRoaXMsIG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZFN1YiA9IGZ1bmN0aW9uIHJlZFN1YiAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkU3ViIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHJldHVybiB0aGlzLnJlZC5zdWIodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkSVN1YiA9IGZ1bmN0aW9uIHJlZElTdWIgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZElTdWIgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmlzdWIodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkU2hsID0gZnVuY3Rpb24gcmVkU2hsIChudW0pIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRTaGwgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLnNobCh0aGlzLCBudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRNdWwgPSBmdW5jdGlvbiByZWRNdWwgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZE11bCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICB0aGlzLnJlZC5fdmVyaWZ5Mih0aGlzLCBudW0pO1xuICAgIHJldHVybiB0aGlzLnJlZC5tdWwodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkSU11bCA9IGZ1bmN0aW9uIHJlZElNdWwgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZE11bCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICB0aGlzLnJlZC5fdmVyaWZ5Mih0aGlzLCBudW0pO1xuICAgIHJldHVybiB0aGlzLnJlZC5pbXVsKHRoaXMsIG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZFNxciA9IGZ1bmN0aW9uIHJlZFNxciAoKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkU3FyIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5zcXIodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZElTcXIgPSBmdW5jdGlvbiByZWRJU3FyICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRJU3FyIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5pc3FyKHRoaXMpO1xuICB9O1xuXG4gIC8vIFNxdWFyZSByb290IG92ZXIgcFxuICBCTi5wcm90b3R5cGUucmVkU3FydCA9IGZ1bmN0aW9uIHJlZFNxcnQgKCkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZFNxcnQgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgdGhpcy5yZWQuX3ZlcmlmeTEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLnNxcnQodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZEludm0gPSBmdW5jdGlvbiByZWRJbnZtICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRJbnZtIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5pbnZtKHRoaXMpO1xuICB9O1xuXG4gIC8vIFJldHVybiBuZWdhdGl2ZSBjbG9uZSBvZiBgdGhpc2AgJSBgcmVkIG1vZHVsb2BcbiAgQk4ucHJvdG90eXBlLnJlZE5lZyA9IGZ1bmN0aW9uIHJlZE5lZyAoKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkTmVnIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5uZWcodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZFBvdyA9IGZ1bmN0aW9uIHJlZFBvdyAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkICYmICFudW0ucmVkLCAncmVkUG93KG5vcm1hbE51bSknKTtcbiAgICB0aGlzLnJlZC5fdmVyaWZ5MSh0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5yZWQucG93KHRoaXMsIG51bSk7XG4gIH07XG5cbiAgLy8gUHJpbWUgbnVtYmVycyB3aXRoIGVmZmljaWVudCByZWR1Y3Rpb25cbiAgdmFyIHByaW1lcyA9IHtcbiAgICBrMjU2OiBudWxsLFxuICAgIHAyMjQ6IG51bGwsXG4gICAgcDE5MjogbnVsbCxcbiAgICBwMjU1MTk6IG51bGxcbiAgfTtcblxuICAvLyBQc2V1ZG8tTWVyc2VubmUgcHJpbWVcbiAgZnVuY3Rpb24gTVByaW1lIChuYW1lLCBwKSB7XG4gICAgLy8gUCA9IDIgXiBOIC0gS1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5wID0gbmV3IEJOKHAsIDE2KTtcbiAgICB0aGlzLm4gPSB0aGlzLnAuYml0TGVuZ3RoKCk7XG4gICAgdGhpcy5rID0gbmV3IEJOKDEpLml1c2hsbih0aGlzLm4pLmlzdWIodGhpcy5wKTtcblxuICAgIHRoaXMudG1wID0gdGhpcy5fdG1wKCk7XG4gIH1cblxuICBNUHJpbWUucHJvdG90eXBlLl90bXAgPSBmdW5jdGlvbiBfdG1wICgpIHtcbiAgICB2YXIgdG1wID0gbmV3IEJOKG51bGwpO1xuICAgIHRtcC53b3JkcyA9IG5ldyBBcnJheShNYXRoLmNlaWwodGhpcy5uIC8gMTMpKTtcbiAgICByZXR1cm4gdG1wO1xuICB9O1xuXG4gIE1QcmltZS5wcm90b3R5cGUuaXJlZHVjZSA9IGZ1bmN0aW9uIGlyZWR1Y2UgKG51bSkge1xuICAgIC8vIEFzc3VtZXMgdGhhdCBgbnVtYCBpcyBsZXNzIHRoYW4gYFBeMmBcbiAgICAvLyBudW0gPSBISSAqICgyIF4gTiAtIEspICsgSEkgKiBLICsgTE8gPSBISSAqIEsgKyBMTyAobW9kIFApXG4gICAgdmFyIHIgPSBudW07XG4gICAgdmFyIHJsZW47XG5cbiAgICBkbyB7XG4gICAgICB0aGlzLnNwbGl0KHIsIHRoaXMudG1wKTtcbiAgICAgIHIgPSB0aGlzLmltdWxLKHIpO1xuICAgICAgciA9IHIuaWFkZCh0aGlzLnRtcCk7XG4gICAgICBybGVuID0gci5iaXRMZW5ndGgoKTtcbiAgICB9IHdoaWxlIChybGVuID4gdGhpcy5uKTtcblxuICAgIHZhciBjbXAgPSBybGVuIDwgdGhpcy5uID8gLTEgOiByLnVjbXAodGhpcy5wKTtcbiAgICBpZiAoY21wID09PSAwKSB7XG4gICAgICByLndvcmRzWzBdID0gMDtcbiAgICAgIHIubGVuZ3RoID0gMTtcbiAgICB9IGVsc2UgaWYgKGNtcCA+IDApIHtcbiAgICAgIHIuaXN1Yih0aGlzLnApO1xuICAgIH0gZWxzZSB7XG4gICAgICByLnN0cmlwKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHI7XG4gIH07XG5cbiAgTVByaW1lLnByb3RvdHlwZS5zcGxpdCA9IGZ1bmN0aW9uIHNwbGl0IChpbnB1dCwgb3V0KSB7XG4gICAgaW5wdXQuaXVzaHJuKHRoaXMubiwgMCwgb3V0KTtcbiAgfTtcblxuICBNUHJpbWUucHJvdG90eXBlLmltdWxLID0gZnVuY3Rpb24gaW11bEsgKG51bSkge1xuICAgIHJldHVybiBudW0uaW11bCh0aGlzLmspO1xuICB9O1xuXG4gIGZ1bmN0aW9uIEsyNTYgKCkge1xuICAgIE1QcmltZS5jYWxsKFxuICAgICAgdGhpcyxcbiAgICAgICdrMjU2JyxcbiAgICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBmZmZmZmMyZicpO1xuICB9XG4gIGluaGVyaXRzKEsyNTYsIE1QcmltZSk7XG5cbiAgSzI1Ni5wcm90b3R5cGUuc3BsaXQgPSBmdW5jdGlvbiBzcGxpdCAoaW5wdXQsIG91dHB1dCkge1xuICAgIC8vIDI1NiA9IDkgKiAyNiArIDIyXG4gICAgdmFyIG1hc2sgPSAweDNmZmZmZjtcblxuICAgIHZhciBvdXRMZW4gPSBNYXRoLm1pbihpbnB1dC5sZW5ndGgsIDkpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3V0TGVuOyBpKyspIHtcbiAgICAgIG91dHB1dC53b3Jkc1tpXSA9IGlucHV0LndvcmRzW2ldO1xuICAgIH1cbiAgICBvdXRwdXQubGVuZ3RoID0gb3V0TGVuO1xuXG4gICAgaWYgKGlucHV0Lmxlbmd0aCA8PSA5KSB7XG4gICAgICBpbnB1dC53b3Jkc1swXSA9IDA7XG4gICAgICBpbnB1dC5sZW5ndGggPSAxO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNoaWZ0IGJ5IDkgbGltYnNcbiAgICB2YXIgcHJldiA9IGlucHV0LndvcmRzWzldO1xuICAgIG91dHB1dC53b3Jkc1tvdXRwdXQubGVuZ3RoKytdID0gcHJldiAmIG1hc2s7XG5cbiAgICBmb3IgKGkgPSAxMDsgaSA8IGlucHV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbmV4dCA9IGlucHV0LndvcmRzW2ldIHwgMDtcbiAgICAgIGlucHV0LndvcmRzW2kgLSAxMF0gPSAoKG5leHQgJiBtYXNrKSA8PCA0KSB8IChwcmV2ID4+PiAyMik7XG4gICAgICBwcmV2ID0gbmV4dDtcbiAgICB9XG4gICAgcHJldiA+Pj49IDIyO1xuICAgIGlucHV0LndvcmRzW2kgLSAxMF0gPSBwcmV2O1xuICAgIGlmIChwcmV2ID09PSAwICYmIGlucHV0Lmxlbmd0aCA+IDEwKSB7XG4gICAgICBpbnB1dC5sZW5ndGggLT0gMTA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlucHV0Lmxlbmd0aCAtPSA5O1xuICAgIH1cbiAgfTtcblxuICBLMjU2LnByb3RvdHlwZS5pbXVsSyA9IGZ1bmN0aW9uIGltdWxLIChudW0pIHtcbiAgICAvLyBLID0gMHgxMDAwMDAzZDEgPSBbIDB4NDAsIDB4M2QxIF1cbiAgICBudW0ud29yZHNbbnVtLmxlbmd0aF0gPSAwO1xuICAgIG51bS53b3Jkc1tudW0ubGVuZ3RoICsgMV0gPSAwO1xuICAgIG51bS5sZW5ndGggKz0gMjtcblxuICAgIC8vIGJvdW5kZWQgYXQ6IDB4NDAgKiAweDNmZmZmZmYgKyAweDNkMCA9IDB4MTAwMDAwMzkwXG4gICAgdmFyIGxvID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG51bS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHcgPSBudW0ud29yZHNbaV0gfCAwO1xuICAgICAgbG8gKz0gdyAqIDB4M2QxO1xuICAgICAgbnVtLndvcmRzW2ldID0gbG8gJiAweDNmZmZmZmY7XG4gICAgICBsbyA9IHcgKiAweDQwICsgKChsbyAvIDB4NDAwMDAwMCkgfCAwKTtcbiAgICB9XG5cbiAgICAvLyBGYXN0IGxlbmd0aCByZWR1Y3Rpb25cbiAgICBpZiAobnVtLndvcmRzW251bS5sZW5ndGggLSAxXSA9PT0gMCkge1xuICAgICAgbnVtLmxlbmd0aC0tO1xuICAgICAgaWYgKG51bS53b3Jkc1tudW0ubGVuZ3RoIC0gMV0gPT09IDApIHtcbiAgICAgICAgbnVtLmxlbmd0aC0tO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVtO1xuICB9O1xuXG4gIGZ1bmN0aW9uIFAyMjQgKCkge1xuICAgIE1QcmltZS5jYWxsKFxuICAgICAgdGhpcyxcbiAgICAgICdwMjI0JyxcbiAgICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAwMDAwMDAwMCAwMDAwMDAwMCAwMDAwMDAwMScpO1xuICB9XG4gIGluaGVyaXRzKFAyMjQsIE1QcmltZSk7XG5cbiAgZnVuY3Rpb24gUDE5MiAoKSB7XG4gICAgTVByaW1lLmNhbGwoXG4gICAgICB0aGlzLFxuICAgICAgJ3AxOTInLFxuICAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmZmZmIGZmZmZmZmZmJyk7XG4gIH1cbiAgaW5oZXJpdHMoUDE5MiwgTVByaW1lKTtcblxuICBmdW5jdGlvbiBQMjU1MTkgKCkge1xuICAgIC8vIDIgXiAyNTUgLSAxOVxuICAgIE1QcmltZS5jYWxsKFxuICAgICAgdGhpcyxcbiAgICAgICcyNTUxOScsXG4gICAgICAnN2ZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZlZCcpO1xuICB9XG4gIGluaGVyaXRzKFAyNTUxOSwgTVByaW1lKTtcblxuICBQMjU1MTkucHJvdG90eXBlLmltdWxLID0gZnVuY3Rpb24gaW11bEsgKG51bSkge1xuICAgIC8vIEsgPSAweDEzXG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG51bS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGhpID0gKG51bS53b3Jkc1tpXSB8IDApICogMHgxMyArIGNhcnJ5O1xuICAgICAgdmFyIGxvID0gaGkgJiAweDNmZmZmZmY7XG4gICAgICBoaSA+Pj49IDI2O1xuXG4gICAgICBudW0ud29yZHNbaV0gPSBsbztcbiAgICAgIGNhcnJ5ID0gaGk7XG4gICAgfVxuICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgbnVtLndvcmRzW251bS5sZW5ndGgrK10gPSBjYXJyeTtcbiAgICB9XG4gICAgcmV0dXJuIG51bTtcbiAgfTtcblxuICAvLyBFeHBvcnRlZCBtb3N0bHkgZm9yIHRlc3RpbmcgcHVycG9zZXMsIHVzZSBwbGFpbiBuYW1lIGluc3RlYWRcbiAgQk4uX3ByaW1lID0gZnVuY3Rpb24gcHJpbWUgKG5hbWUpIHtcbiAgICAvLyBDYWNoZWQgdmVyc2lvbiBvZiBwcmltZVxuICAgIGlmIChwcmltZXNbbmFtZV0pIHJldHVybiBwcmltZXNbbmFtZV07XG5cbiAgICB2YXIgcHJpbWU7XG4gICAgaWYgKG5hbWUgPT09ICdrMjU2Jykge1xuICAgICAgcHJpbWUgPSBuZXcgSzI1NigpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3AyMjQnKSB7XG4gICAgICBwcmltZSA9IG5ldyBQMjI0KCk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSAncDE5MicpIHtcbiAgICAgIHByaW1lID0gbmV3IFAxOTIoKTtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdwMjU1MTknKSB7XG4gICAgICBwcmltZSA9IG5ldyBQMjU1MTkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHByaW1lICcgKyBuYW1lKTtcbiAgICB9XG4gICAgcHJpbWVzW25hbWVdID0gcHJpbWU7XG5cbiAgICByZXR1cm4gcHJpbWU7XG4gIH07XG5cbiAgLy9cbiAgLy8gQmFzZSByZWR1Y3Rpb24gZW5naW5lXG4gIC8vXG4gIGZ1bmN0aW9uIFJlZCAobSkge1xuICAgIGlmICh0eXBlb2YgbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHZhciBwcmltZSA9IEJOLl9wcmltZShtKTtcbiAgICAgIHRoaXMubSA9IHByaW1lLnA7XG4gICAgICB0aGlzLnByaW1lID0gcHJpbWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFzc2VydChtLmd0bigxKSwgJ21vZHVsdXMgbXVzdCBiZSBncmVhdGVyIHRoYW4gMScpO1xuICAgICAgdGhpcy5tID0gbTtcbiAgICAgIHRoaXMucHJpbWUgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIFJlZC5wcm90b3R5cGUuX3ZlcmlmeTEgPSBmdW5jdGlvbiBfdmVyaWZ5MSAoYSkge1xuICAgIGFzc2VydChhLm5lZ2F0aXZlID09PSAwLCAncmVkIHdvcmtzIG9ubHkgd2l0aCBwb3NpdGl2ZXMnKTtcbiAgICBhc3NlcnQoYS5yZWQsICdyZWQgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5fdmVyaWZ5MiA9IGZ1bmN0aW9uIF92ZXJpZnkyIChhLCBiKSB7XG4gICAgYXNzZXJ0KChhLm5lZ2F0aXZlIHwgYi5uZWdhdGl2ZSkgPT09IDAsICdyZWQgd29ya3Mgb25seSB3aXRoIHBvc2l0aXZlcycpO1xuICAgIGFzc2VydChhLnJlZCAmJiBhLnJlZCA9PT0gYi5yZWQsXG4gICAgICAncmVkIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuaW1vZCA9IGZ1bmN0aW9uIGltb2QgKGEpIHtcbiAgICBpZiAodGhpcy5wcmltZSkgcmV0dXJuIHRoaXMucHJpbWUuaXJlZHVjZShhKS5fZm9yY2VSZWQodGhpcyk7XG4gICAgcmV0dXJuIGEudW1vZCh0aGlzLm0pLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLm5lZyA9IGZ1bmN0aW9uIG5lZyAoYSkge1xuICAgIGlmIChhLmlzWmVybygpKSB7XG4gICAgICByZXR1cm4gYS5jbG9uZSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm0uc3ViKGEpLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZCAoYSwgYikge1xuICAgIHRoaXMuX3ZlcmlmeTIoYSwgYik7XG5cbiAgICB2YXIgcmVzID0gYS5hZGQoYik7XG4gICAgaWYgKHJlcy5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMuaXN1Yih0aGlzLm0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmlhZGQgPSBmdW5jdGlvbiBpYWRkIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcblxuICAgIHZhciByZXMgPSBhLmlhZGQoYik7XG4gICAgaWYgKHJlcy5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMuaXN1Yih0aGlzLm0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuc3ViID0gZnVuY3Rpb24gc3ViIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcblxuICAgIHZhciByZXMgPSBhLnN1YihiKTtcbiAgICBpZiAocmVzLmNtcG4oMCkgPCAwKSB7XG4gICAgICByZXMuaWFkZCh0aGlzLm0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmlzdWIgPSBmdW5jdGlvbiBpc3ViIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcblxuICAgIHZhciByZXMgPSBhLmlzdWIoYik7XG4gICAgaWYgKHJlcy5jbXBuKDApIDwgMCkge1xuICAgICAgcmVzLmlhZGQodGhpcy5tKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLnNobCA9IGZ1bmN0aW9uIHNobCAoYSwgbnVtKSB7XG4gICAgdGhpcy5fdmVyaWZ5MShhKTtcbiAgICByZXR1cm4gdGhpcy5pbW9kKGEudXNobG4obnVtKSk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5pbXVsID0gZnVuY3Rpb24gaW11bCAoYSwgYikge1xuICAgIHRoaXMuX3ZlcmlmeTIoYSwgYik7XG4gICAgcmV0dXJuIHRoaXMuaW1vZChhLmltdWwoYikpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcbiAgICByZXR1cm4gdGhpcy5pbW9kKGEubXVsKGIpKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmlzcXIgPSBmdW5jdGlvbiBpc3FyIChhKSB7XG4gICAgcmV0dXJuIHRoaXMuaW11bChhLCBhLmNsb25lKCkpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuc3FyID0gZnVuY3Rpb24gc3FyIChhKSB7XG4gICAgcmV0dXJuIHRoaXMubXVsKGEsIGEpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuc3FydCA9IGZ1bmN0aW9uIHNxcnQgKGEpIHtcbiAgICBpZiAoYS5pc1plcm8oKSkgcmV0dXJuIGEuY2xvbmUoKTtcblxuICAgIHZhciBtb2QzID0gdGhpcy5tLmFuZGxuKDMpO1xuICAgIGFzc2VydChtb2QzICUgMiA9PT0gMSk7XG5cbiAgICAvLyBGYXN0IGNhc2VcbiAgICBpZiAobW9kMyA9PT0gMykge1xuICAgICAgdmFyIHBvdyA9IHRoaXMubS5hZGQobmV3IEJOKDEpKS5pdXNocm4oMik7XG4gICAgICByZXR1cm4gdGhpcy5wb3coYSwgcG93KTtcbiAgICB9XG5cbiAgICAvLyBUb25lbGxpLVNoYW5rcyBhbGdvcml0aG0gKFRvdGFsbHkgdW5vcHRpbWl6ZWQgYW5kIHNsb3cpXG4gICAgLy9cbiAgICAvLyBGaW5kIFEgYW5kIFMsIHRoYXQgUSAqIDIgXiBTID0gKFAgLSAxKVxuICAgIHZhciBxID0gdGhpcy5tLnN1Ym4oMSk7XG4gICAgdmFyIHMgPSAwO1xuICAgIHdoaWxlICghcS5pc1plcm8oKSAmJiBxLmFuZGxuKDEpID09PSAwKSB7XG4gICAgICBzKys7XG4gICAgICBxLml1c2hybigxKTtcbiAgICB9XG4gICAgYXNzZXJ0KCFxLmlzWmVybygpKTtcblxuICAgIHZhciBvbmUgPSBuZXcgQk4oMSkudG9SZWQodGhpcyk7XG4gICAgdmFyIG5PbmUgPSBvbmUucmVkTmVnKCk7XG5cbiAgICAvLyBGaW5kIHF1YWRyYXRpYyBub24tcmVzaWR1ZVxuICAgIC8vIE5PVEU6IE1heCBpcyBzdWNoIGJlY2F1c2Ugb2YgZ2VuZXJhbGl6ZWQgUmllbWFubiBoeXBvdGhlc2lzLlxuICAgIHZhciBscG93ID0gdGhpcy5tLnN1Ym4oMSkuaXVzaHJuKDEpO1xuICAgIHZhciB6ID0gdGhpcy5tLmJpdExlbmd0aCgpO1xuICAgIHogPSBuZXcgQk4oMiAqIHogKiB6KS50b1JlZCh0aGlzKTtcblxuICAgIHdoaWxlICh0aGlzLnBvdyh6LCBscG93KS5jbXAobk9uZSkgIT09IDApIHtcbiAgICAgIHoucmVkSUFkZChuT25lKTtcbiAgICB9XG5cbiAgICB2YXIgYyA9IHRoaXMucG93KHosIHEpO1xuICAgIHZhciByID0gdGhpcy5wb3coYSwgcS5hZGRuKDEpLml1c2hybigxKSk7XG4gICAgdmFyIHQgPSB0aGlzLnBvdyhhLCBxKTtcbiAgICB2YXIgbSA9IHM7XG4gICAgd2hpbGUgKHQuY21wKG9uZSkgIT09IDApIHtcbiAgICAgIHZhciB0bXAgPSB0O1xuICAgICAgZm9yICh2YXIgaSA9IDA7IHRtcC5jbXAob25lKSAhPT0gMDsgaSsrKSB7XG4gICAgICAgIHRtcCA9IHRtcC5yZWRTcXIoKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydChpIDwgbSk7XG4gICAgICB2YXIgYiA9IHRoaXMucG93KGMsIG5ldyBCTigxKS5pdXNobG4obSAtIGkgLSAxKSk7XG5cbiAgICAgIHIgPSByLnJlZE11bChiKTtcbiAgICAgIGMgPSBiLnJlZFNxcigpO1xuICAgICAgdCA9IHQucmVkTXVsKGMpO1xuICAgICAgbSA9IGk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHI7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5pbnZtID0gZnVuY3Rpb24gaW52bSAoYSkge1xuICAgIHZhciBpbnYgPSBhLl9pbnZtcCh0aGlzLm0pO1xuICAgIGlmIChpbnYubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIGludi5uZWdhdGl2ZSA9IDA7XG4gICAgICByZXR1cm4gdGhpcy5pbW9kKGludikucmVkTmVnKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmltb2QoaW52KTtcbiAgICB9XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5wb3cgPSBmdW5jdGlvbiBwb3cgKGEsIG51bSkge1xuICAgIGlmIChudW0uaXNaZXJvKCkpIHJldHVybiBuZXcgQk4oMSk7XG4gICAgaWYgKG51bS5jbXBuKDEpID09PSAwKSByZXR1cm4gYS5jbG9uZSgpO1xuXG4gICAgdmFyIHdpbmRvd1NpemUgPSA0O1xuICAgIHZhciB3bmQgPSBuZXcgQXJyYXkoMSA8PCB3aW5kb3dTaXplKTtcbiAgICB3bmRbMF0gPSBuZXcgQk4oMSkudG9SZWQodGhpcyk7XG4gICAgd25kWzFdID0gYTtcbiAgICBmb3IgKHZhciBpID0gMjsgaSA8IHduZC5sZW5ndGg7IGkrKykge1xuICAgICAgd25kW2ldID0gdGhpcy5tdWwod25kW2kgLSAxXSwgYSk7XG4gICAgfVxuXG4gICAgdmFyIHJlcyA9IHduZFswXTtcbiAgICB2YXIgY3VycmVudCA9IDA7XG4gICAgdmFyIGN1cnJlbnRMZW4gPSAwO1xuICAgIHZhciBzdGFydCA9IG51bS5iaXRMZW5ndGgoKSAlIDI2O1xuICAgIGlmIChzdGFydCA9PT0gMCkge1xuICAgICAgc3RhcnQgPSAyNjtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSBudW0ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciB3b3JkID0gbnVtLndvcmRzW2ldO1xuICAgICAgZm9yICh2YXIgaiA9IHN0YXJ0IC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgICAgdmFyIGJpdCA9ICh3b3JkID4+IGopICYgMTtcbiAgICAgICAgaWYgKHJlcyAhPT0gd25kWzBdKSB7XG4gICAgICAgICAgcmVzID0gdGhpcy5zcXIocmVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChiaXQgPT09IDAgJiYgY3VycmVudCA9PT0gMCkge1xuICAgICAgICAgIGN1cnJlbnRMZW4gPSAwO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY3VycmVudCA8PD0gMTtcbiAgICAgICAgY3VycmVudCB8PSBiaXQ7XG4gICAgICAgIGN1cnJlbnRMZW4rKztcbiAgICAgICAgaWYgKGN1cnJlbnRMZW4gIT09IHdpbmRvd1NpemUgJiYgKGkgIT09IDAgfHwgaiAhPT0gMCkpIGNvbnRpbnVlO1xuXG4gICAgICAgIHJlcyA9IHRoaXMubXVsKHJlcywgd25kW2N1cnJlbnRdKTtcbiAgICAgICAgY3VycmVudExlbiA9IDA7XG4gICAgICAgIGN1cnJlbnQgPSAwO1xuICAgICAgfVxuICAgICAgc3RhcnQgPSAyNjtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuY29udmVydFRvID0gZnVuY3Rpb24gY29udmVydFRvIChudW0pIHtcbiAgICB2YXIgciA9IG51bS51bW9kKHRoaXMubSk7XG5cbiAgICByZXR1cm4gciA9PT0gbnVtID8gci5jbG9uZSgpIDogcjtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmNvbnZlcnRGcm9tID0gZnVuY3Rpb24gY29udmVydEZyb20gKG51bSkge1xuICAgIHZhciByZXMgPSBudW0uY2xvbmUoKTtcbiAgICByZXMucmVkID0gbnVsbDtcbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIC8vXG4gIC8vIE1vbnRnb21lcnkgbWV0aG9kIGVuZ2luZVxuICAvL1xuXG4gIEJOLm1vbnQgPSBmdW5jdGlvbiBtb250IChudW0pIHtcbiAgICByZXR1cm4gbmV3IE1vbnQobnVtKTtcbiAgfTtcblxuICBmdW5jdGlvbiBNb250IChtKSB7XG4gICAgUmVkLmNhbGwodGhpcywgbSk7XG5cbiAgICB0aGlzLnNoaWZ0ID0gdGhpcy5tLmJpdExlbmd0aCgpO1xuICAgIGlmICh0aGlzLnNoaWZ0ICUgMjYgIT09IDApIHtcbiAgICAgIHRoaXMuc2hpZnQgKz0gMjYgLSAodGhpcy5zaGlmdCAlIDI2KTtcbiAgICB9XG5cbiAgICB0aGlzLnIgPSBuZXcgQk4oMSkuaXVzaGxuKHRoaXMuc2hpZnQpO1xuICAgIHRoaXMucjIgPSB0aGlzLmltb2QodGhpcy5yLnNxcigpKTtcbiAgICB0aGlzLnJpbnYgPSB0aGlzLnIuX2ludm1wKHRoaXMubSk7XG5cbiAgICB0aGlzLm1pbnYgPSB0aGlzLnJpbnYubXVsKHRoaXMucikuaXN1Ym4oMSkuZGl2KHRoaXMubSk7XG4gICAgdGhpcy5taW52ID0gdGhpcy5taW52LnVtb2QodGhpcy5yKTtcbiAgICB0aGlzLm1pbnYgPSB0aGlzLnIuc3ViKHRoaXMubWludik7XG4gIH1cbiAgaW5oZXJpdHMoTW9udCwgUmVkKTtcblxuICBNb250LnByb3RvdHlwZS5jb252ZXJ0VG8gPSBmdW5jdGlvbiBjb252ZXJ0VG8gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmltb2QobnVtLnVzaGxuKHRoaXMuc2hpZnQpKTtcbiAgfTtcblxuICBNb250LnByb3RvdHlwZS5jb252ZXJ0RnJvbSA9IGZ1bmN0aW9uIGNvbnZlcnRGcm9tIChudW0pIHtcbiAgICB2YXIgciA9IHRoaXMuaW1vZChudW0ubXVsKHRoaXMucmludikpO1xuICAgIHIucmVkID0gbnVsbDtcbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICBNb250LnByb3RvdHlwZS5pbXVsID0gZnVuY3Rpb24gaW11bCAoYSwgYikge1xuICAgIGlmIChhLmlzWmVybygpIHx8IGIuaXNaZXJvKCkpIHtcbiAgICAgIGEud29yZHNbMF0gPSAwO1xuICAgICAgYS5sZW5ndGggPSAxO1xuICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgdmFyIHQgPSBhLmltdWwoYik7XG4gICAgdmFyIGMgPSB0Lm1hc2tuKHRoaXMuc2hpZnQpLm11bCh0aGlzLm1pbnYpLmltYXNrbih0aGlzLnNoaWZ0KS5tdWwodGhpcy5tKTtcbiAgICB2YXIgdSA9IHQuaXN1YihjKS5pdXNocm4odGhpcy5zaGlmdCk7XG4gICAgdmFyIHJlcyA9IHU7XG5cbiAgICBpZiAodS5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMgPSB1LmlzdWIodGhpcy5tKTtcbiAgICB9IGVsc2UgaWYgKHUuY21wbigwKSA8IDApIHtcbiAgICAgIHJlcyA9IHUuaWFkZCh0aGlzLm0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIE1vbnQucHJvdG90eXBlLm11bCA9IGZ1bmN0aW9uIG11bCAoYSwgYikge1xuICAgIGlmIChhLmlzWmVybygpIHx8IGIuaXNaZXJvKCkpIHJldHVybiBuZXcgQk4oMCkuX2ZvcmNlUmVkKHRoaXMpO1xuXG4gICAgdmFyIHQgPSBhLm11bChiKTtcbiAgICB2YXIgYyA9IHQubWFza24odGhpcy5zaGlmdCkubXVsKHRoaXMubWludikuaW1hc2tuKHRoaXMuc2hpZnQpLm11bCh0aGlzLm0pO1xuICAgIHZhciB1ID0gdC5pc3ViKGMpLml1c2hybih0aGlzLnNoaWZ0KTtcbiAgICB2YXIgcmVzID0gdTtcbiAgICBpZiAodS5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMgPSB1LmlzdWIodGhpcy5tKTtcbiAgICB9IGVsc2UgaWYgKHUuY21wbigwKSA8IDApIHtcbiAgICAgIHJlcyA9IHUuaWFkZCh0aGlzLm0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIE1vbnQucHJvdG90eXBlLmludm0gPSBmdW5jdGlvbiBpbnZtIChhKSB7XG4gICAgLy8gKEFSKV4tMSAqIFJeMiA9IChBXi0xICogUl4tMSkgKiBSXjIgPSBBXi0xICogUlxuICAgIHZhciByZXMgPSB0aGlzLmltb2QoYS5faW52bXAodGhpcy5tKS5tdWwodGhpcy5yMikpO1xuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xufSkodHlwZW9mIG1vZHVsZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbW9kdWxlLCB0aGlzKTtcbiIsInZhciBibiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgcmFuZG9tQnl0ZXMgPSByZXF1aXJlKCdyYW5kb21ieXRlcycpO1xubW9kdWxlLmV4cG9ydHMgPSBjcnQ7XG5mdW5jdGlvbiBibGluZChwcml2KSB7XG4gIHZhciByID0gZ2V0cihwcml2KTtcbiAgdmFyIGJsaW5kZXIgPSByLnRvUmVkKGJuLm1vbnQocHJpdi5tb2R1bHVzKSlcbiAgLnJlZFBvdyhuZXcgYm4ocHJpdi5wdWJsaWNFeHBvbmVudCkpLmZyb21SZWQoKTtcbiAgcmV0dXJuIHtcbiAgICBibGluZGVyOiBibGluZGVyLFxuICAgIHVuYmxpbmRlcjpyLmludm0ocHJpdi5tb2R1bHVzKVxuICB9O1xufVxuZnVuY3Rpb24gY3J0KG1zZywgcHJpdikge1xuICB2YXIgYmxpbmRzID0gYmxpbmQocHJpdik7XG4gIHZhciBsZW4gPSBwcml2Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpO1xuICB2YXIgbW9kID0gYm4ubW9udChwcml2Lm1vZHVsdXMpO1xuICB2YXIgYmxpbmRlZCA9IG5ldyBibihtc2cpLm11bChibGluZHMuYmxpbmRlcikudW1vZChwcml2Lm1vZHVsdXMpO1xuICB2YXIgYzEgPSBibGluZGVkLnRvUmVkKGJuLm1vbnQocHJpdi5wcmltZTEpKTtcbiAgdmFyIGMyID0gYmxpbmRlZC50b1JlZChibi5tb250KHByaXYucHJpbWUyKSk7XG4gIHZhciBxaW52ID0gcHJpdi5jb2VmZmljaWVudDtcbiAgdmFyIHAgPSBwcml2LnByaW1lMTtcbiAgdmFyIHEgPSBwcml2LnByaW1lMjtcbiAgdmFyIG0xID0gYzEucmVkUG93KHByaXYuZXhwb25lbnQxKTtcbiAgdmFyIG0yID0gYzIucmVkUG93KHByaXYuZXhwb25lbnQyKTtcbiAgbTEgPSBtMS5mcm9tUmVkKCk7XG4gIG0yID0gbTIuZnJvbVJlZCgpO1xuICB2YXIgaCA9IG0xLmlzdWIobTIpLmltdWwocWludikudW1vZChwKTtcbiAgaC5pbXVsKHEpO1xuICBtMi5pYWRkKGgpO1xuICByZXR1cm4gbmV3IEJ1ZmZlcihtMi5pbXVsKGJsaW5kcy51bmJsaW5kZXIpLnVtb2QocHJpdi5tb2R1bHVzKS50b0FycmF5KGZhbHNlLCBsZW4pKTtcbn1cbmNydC5nZXRyID0gZ2V0cjtcbmZ1bmN0aW9uIGdldHIocHJpdikge1xuICB2YXIgbGVuID0gcHJpdi5tb2R1bHVzLmJ5dGVMZW5ndGgoKTtcbiAgdmFyIHIgPSBuZXcgYm4ocmFuZG9tQnl0ZXMobGVuKSk7XG4gIHdoaWxlIChyLmNtcChwcml2Lm1vZHVsdXMpID49ICAwIHx8ICFyLnVtb2QocHJpdi5wcmltZTEpIHx8ICFyLnVtb2QocHJpdi5wcmltZTIpKSB7XG4gICAgciA9IG5ldyBibihyYW5kb21CeXRlcyhsZW4pKTtcbiAgfVxuICByZXR1cm4gcjtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGVsbGlwdGljID0gZXhwb3J0cztcblxuZWxsaXB0aWMudmVyc2lvbiA9IHJlcXVpcmUoJy4uL3BhY2thZ2UuanNvbicpLnZlcnNpb247XG5lbGxpcHRpYy51dGlscyA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvdXRpbHMnKTtcbmVsbGlwdGljLnJhbmQgPSByZXF1aXJlKCdicm9yYW5kJyk7XG5lbGxpcHRpYy5obWFjRFJCRyA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvaG1hYy1kcmJnJyk7XG5lbGxpcHRpYy5jdXJ2ZSA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvY3VydmUnKTtcbmVsbGlwdGljLmN1cnZlcyA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvY3VydmVzJyk7XG5cbi8vIFByb3RvY29sc1xuZWxsaXB0aWMuZWMgPSByZXF1aXJlKCcuL2VsbGlwdGljL2VjJyk7XG5lbGxpcHRpYy5lZGRzYSA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvZWRkc2EnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgdXRpbHMgPSBlbGxpcHRpYy51dGlscztcbnZhciBnZXROQUYgPSB1dGlscy5nZXROQUY7XG52YXIgZ2V0SlNGID0gdXRpbHMuZ2V0SlNGO1xudmFyIGFzc2VydCA9IHV0aWxzLmFzc2VydDtcblxuZnVuY3Rpb24gQmFzZUN1cnZlKHR5cGUsIGNvbmYpIHtcbiAgdGhpcy50eXBlID0gdHlwZTtcbiAgdGhpcy5wID0gbmV3IEJOKGNvbmYucCwgMTYpO1xuXG4gIC8vIFVzZSBNb250Z29tZXJ5LCB3aGVuIHRoZXJlIGlzIG5vIGZhc3QgcmVkdWN0aW9uIGZvciB0aGUgcHJpbWVcbiAgdGhpcy5yZWQgPSBjb25mLnByaW1lID8gQk4ucmVkKGNvbmYucHJpbWUpIDogQk4ubW9udCh0aGlzLnApO1xuXG4gIC8vIFVzZWZ1bCBmb3IgbWFueSBjdXJ2ZXNcbiAgdGhpcy56ZXJvID0gbmV3IEJOKDApLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5vbmUgPSBuZXcgQk4oMSkudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLnR3byA9IG5ldyBCTigyKS50b1JlZCh0aGlzLnJlZCk7XG5cbiAgLy8gQ3VydmUgY29uZmlndXJhdGlvbiwgb3B0aW9uYWxcbiAgdGhpcy5uID0gY29uZi5uICYmIG5ldyBCTihjb25mLm4sIDE2KTtcbiAgdGhpcy5nID0gY29uZi5nICYmIHRoaXMucG9pbnRGcm9tSlNPTihjb25mLmcsIGNvbmYuZ1JlZCk7XG5cbiAgLy8gVGVtcG9yYXJ5IGFycmF5c1xuICB0aGlzLl93bmFmVDEgPSBuZXcgQXJyYXkoNCk7XG4gIHRoaXMuX3duYWZUMiA9IG5ldyBBcnJheSg0KTtcbiAgdGhpcy5fd25hZlQzID0gbmV3IEFycmF5KDQpO1xuICB0aGlzLl93bmFmVDQgPSBuZXcgQXJyYXkoNCk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VDdXJ2ZTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS5wb2ludCA9IGZ1bmN0aW9uIHBvaW50KCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS5fZml4ZWROYWZNdWwgPSBmdW5jdGlvbiBfZml4ZWROYWZNdWwocCwgaykge1xuICBhc3NlcnQocC5wcmVjb21wdXRlZCk7XG4gIHZhciBkb3VibGVzID0gcC5fZ2V0RG91YmxlcygpO1xuXG4gIHZhciBuYWYgPSBnZXROQUYoaywgMSk7XG4gIHZhciBJID0gKDEgPDwgKGRvdWJsZXMuc3RlcCArIDEpKSAtIChkb3VibGVzLnN0ZXAgJSAyID09PSAwID8gMiA6IDEpO1xuICBJIC89IDM7XG5cbiAgLy8gVHJhbnNsYXRlIGludG8gbW9yZSB3aW5kb3dlZCBmb3JtXG4gIHZhciByZXByID0gW107XG4gIGZvciAodmFyIGogPSAwOyBqIDwgbmFmLmxlbmd0aDsgaiArPSBkb3VibGVzLnN0ZXApIHtcbiAgICB2YXIgbmFmVyA9IDA7XG4gICAgZm9yICh2YXIgayA9IGogKyBkb3VibGVzLnN0ZXAgLSAxOyBrID49IGo7IGstLSlcbiAgICAgIG5hZlcgPSAobmFmVyA8PCAxKSArIG5hZltrXTtcbiAgICByZXByLnB1c2gobmFmVyk7XG4gIH1cblxuICB2YXIgYSA9IHRoaXMuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuICB2YXIgYiA9IHRoaXMuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuICBmb3IgKHZhciBpID0gSTsgaSA+IDA7IGktLSkge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgcmVwci5sZW5ndGg7IGorKykge1xuICAgICAgdmFyIG5hZlcgPSByZXByW2pdO1xuICAgICAgaWYgKG5hZlcgPT09IGkpXG4gICAgICAgIGIgPSBiLm1peGVkQWRkKGRvdWJsZXMucG9pbnRzW2pdKTtcbiAgICAgIGVsc2UgaWYgKG5hZlcgPT09IC1pKVxuICAgICAgICBiID0gYi5taXhlZEFkZChkb3VibGVzLnBvaW50c1tqXS5uZWcoKSk7XG4gICAgfVxuICAgIGEgPSBhLmFkZChiKTtcbiAgfVxuICByZXR1cm4gYS50b1AoKTtcbn07XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUuX3duYWZNdWwgPSBmdW5jdGlvbiBfd25hZk11bChwLCBrKSB7XG4gIHZhciB3ID0gNDtcblxuICAvLyBQcmVjb21wdXRlIHdpbmRvd1xuICB2YXIgbmFmUG9pbnRzID0gcC5fZ2V0TkFGUG9pbnRzKHcpO1xuICB3ID0gbmFmUG9pbnRzLnduZDtcbiAgdmFyIHduZCA9IG5hZlBvaW50cy5wb2ludHM7XG5cbiAgLy8gR2V0IE5BRiBmb3JtXG4gIHZhciBuYWYgPSBnZXROQUYoaywgdyk7XG5cbiAgLy8gQWRkIGB0aGlzYCooTisxKSBmb3IgZXZlcnkgdy1OQUYgaW5kZXhcbiAgdmFyIGFjYyA9IHRoaXMuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuICBmb3IgKHZhciBpID0gbmFmLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgLy8gQ291bnQgemVyb2VzXG4gICAgZm9yICh2YXIgayA9IDA7IGkgPj0gMCAmJiBuYWZbaV0gPT09IDA7IGktLSlcbiAgICAgIGsrKztcbiAgICBpZiAoaSA+PSAwKVxuICAgICAgaysrO1xuICAgIGFjYyA9IGFjYy5kYmxwKGspO1xuXG4gICAgaWYgKGkgPCAwKVxuICAgICAgYnJlYWs7XG4gICAgdmFyIHogPSBuYWZbaV07XG4gICAgYXNzZXJ0KHogIT09IDApO1xuICAgIGlmIChwLnR5cGUgPT09ICdhZmZpbmUnKSB7XG4gICAgICAvLyBKICstIFBcbiAgICAgIGlmICh6ID4gMClcbiAgICAgICAgYWNjID0gYWNjLm1peGVkQWRkKHduZFsoeiAtIDEpID4+IDFdKTtcbiAgICAgIGVsc2VcbiAgICAgICAgYWNjID0gYWNjLm1peGVkQWRkKHduZFsoLXogLSAxKSA+PiAxXS5uZWcoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEogKy0gSlxuICAgICAgaWYgKHogPiAwKVxuICAgICAgICBhY2MgPSBhY2MuYWRkKHduZFsoeiAtIDEpID4+IDFdKTtcbiAgICAgIGVsc2VcbiAgICAgICAgYWNjID0gYWNjLmFkZCh3bmRbKC16IC0gMSkgPj4gMV0ubmVnKCkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcC50eXBlID09PSAnYWZmaW5lJyA/IGFjYy50b1AoKSA6IGFjYztcbn07XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUuX3duYWZNdWxBZGQgPSBmdW5jdGlvbiBfd25hZk11bEFkZChkZWZXLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50cyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2VmZnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuKSB7XG4gIHZhciB3bmRXaWR0aCA9IHRoaXMuX3duYWZUMTtcbiAgdmFyIHduZCA9IHRoaXMuX3duYWZUMjtcbiAgdmFyIG5hZiA9IHRoaXMuX3duYWZUMztcblxuICAvLyBGaWxsIGFsbCBhcnJheXNcbiAgdmFyIG1heCA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIgcCA9IHBvaW50c1tpXTtcbiAgICB2YXIgbmFmUG9pbnRzID0gcC5fZ2V0TkFGUG9pbnRzKGRlZlcpO1xuICAgIHduZFdpZHRoW2ldID0gbmFmUG9pbnRzLnduZDtcbiAgICB3bmRbaV0gPSBuYWZQb2ludHMucG9pbnRzO1xuICB9XG5cbiAgLy8gQ29tYiBzbWFsbCB3aW5kb3cgTkFGc1xuICBmb3IgKHZhciBpID0gbGVuIC0gMTsgaSA+PSAxOyBpIC09IDIpIHtcbiAgICB2YXIgYSA9IGkgLSAxO1xuICAgIHZhciBiID0gaTtcbiAgICBpZiAod25kV2lkdGhbYV0gIT09IDEgfHwgd25kV2lkdGhbYl0gIT09IDEpIHtcbiAgICAgIG5hZlthXSA9IGdldE5BRihjb2VmZnNbYV0sIHduZFdpZHRoW2FdKTtcbiAgICAgIG5hZltiXSA9IGdldE5BRihjb2VmZnNbYl0sIHduZFdpZHRoW2JdKTtcbiAgICAgIG1heCA9IE1hdGgubWF4KG5hZlthXS5sZW5ndGgsIG1heCk7XG4gICAgICBtYXggPSBNYXRoLm1heChuYWZbYl0ubGVuZ3RoLCBtYXgpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIGNvbWIgPSBbXG4gICAgICBwb2ludHNbYV0sIC8qIDEgKi9cbiAgICAgIG51bGwsIC8qIDMgKi9cbiAgICAgIG51bGwsIC8qIDUgKi9cbiAgICAgIHBvaW50c1tiXSAvKiA3ICovXG4gICAgXTtcblxuICAgIC8vIFRyeSB0byBhdm9pZCBQcm9qZWN0aXZlIHBvaW50cywgaWYgcG9zc2libGVcbiAgICBpZiAocG9pbnRzW2FdLnkuY21wKHBvaW50c1tiXS55KSA9PT0gMCkge1xuICAgICAgY29tYlsxXSA9IHBvaW50c1thXS5hZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdLm5lZygpKTtcbiAgICB9IGVsc2UgaWYgKHBvaW50c1thXS55LmNtcChwb2ludHNbYl0ueS5yZWROZWcoKSkgPT09IDApIHtcbiAgICAgIGNvbWJbMV0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0uYWRkKHBvaW50c1tiXS5uZWcoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbWJbMV0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdLm5lZygpKTtcbiAgICB9XG5cbiAgICB2YXIgaW5kZXggPSBbXG4gICAgICAtMywgLyogLTEgLTEgKi9cbiAgICAgIC0xLCAvKiAtMSAwICovXG4gICAgICAtNSwgLyogLTEgMSAqL1xuICAgICAgLTcsIC8qIDAgLTEgKi9cbiAgICAgIDAsIC8qIDAgMCAqL1xuICAgICAgNywgLyogMCAxICovXG4gICAgICA1LCAvKiAxIC0xICovXG4gICAgICAxLCAvKiAxIDAgKi9cbiAgICAgIDMgIC8qIDEgMSAqL1xuICAgIF07XG5cbiAgICB2YXIganNmID0gZ2V0SlNGKGNvZWZmc1thXSwgY29lZmZzW2JdKTtcbiAgICBtYXggPSBNYXRoLm1heChqc2ZbMF0ubGVuZ3RoLCBtYXgpO1xuICAgIG5hZlthXSA9IG5ldyBBcnJheShtYXgpO1xuICAgIG5hZltiXSA9IG5ldyBBcnJheShtYXgpO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWF4OyBqKyspIHtcbiAgICAgIHZhciBqYSA9IGpzZlswXVtqXSB8IDA7XG4gICAgICB2YXIgamIgPSBqc2ZbMV1bal0gfCAwO1xuXG4gICAgICBuYWZbYV1bal0gPSBpbmRleFsoamEgKyAxKSAqIDMgKyAoamIgKyAxKV07XG4gICAgICBuYWZbYl1bal0gPSAwO1xuICAgICAgd25kW2FdID0gY29tYjtcbiAgICB9XG4gIH1cblxuICB2YXIgYWNjID0gdGhpcy5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gIHZhciB0bXAgPSB0aGlzLl93bmFmVDQ7XG4gIGZvciAodmFyIGkgPSBtYXg7IGkgPj0gMDsgaS0tKSB7XG4gICAgdmFyIGsgPSAwO1xuXG4gICAgd2hpbGUgKGkgPj0gMCkge1xuICAgICAgdmFyIHplcm8gPSB0cnVlO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBsZW47IGorKykge1xuICAgICAgICB0bXBbal0gPSBuYWZbal1baV0gfCAwO1xuICAgICAgICBpZiAodG1wW2pdICE9PSAwKVxuICAgICAgICAgIHplcm8gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICghemVybylcbiAgICAgICAgYnJlYWs7XG4gICAgICBrKys7XG4gICAgICBpLS07XG4gICAgfVxuICAgIGlmIChpID49IDApXG4gICAgICBrKys7XG4gICAgYWNjID0gYWNjLmRibHAoayk7XG4gICAgaWYgKGkgPCAwKVxuICAgICAgYnJlYWs7XG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICB2YXIgeiA9IHRtcFtqXTtcbiAgICAgIHZhciBwO1xuICAgICAgaWYgKHogPT09IDApXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgZWxzZSBpZiAoeiA+IDApXG4gICAgICAgIHAgPSB3bmRbal1bKHogLSAxKSA+PiAxXTtcbiAgICAgIGVsc2UgaWYgKHogPCAwKVxuICAgICAgICBwID0gd25kW2pdWygteiAtIDEpID4+IDFdLm5lZygpO1xuXG4gICAgICBpZiAocC50eXBlID09PSAnYWZmaW5lJylcbiAgICAgICAgYWNjID0gYWNjLm1peGVkQWRkKHApO1xuICAgICAgZWxzZVxuICAgICAgICBhY2MgPSBhY2MuYWRkKHApO1xuICAgIH1cbiAgfVxuICAvLyBaZXJvaWZ5IHJlZmVyZW5jZXNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICB3bmRbaV0gPSBudWxsO1xuICByZXR1cm4gYWNjLnRvUCgpO1xufTtcblxuZnVuY3Rpb24gQmFzZVBvaW50KGN1cnZlLCB0eXBlKSB7XG4gIHRoaXMuY3VydmUgPSBjdXJ2ZTtcbiAgdGhpcy50eXBlID0gdHlwZTtcbiAgdGhpcy5wcmVjb21wdXRlZCA9IG51bGw7XG59XG5CYXNlQ3VydmUuQmFzZVBvaW50ID0gQmFzZVBvaW50O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLmVxID0gZnVuY3Rpb24gZXEoLypvdGhlciovKSB7XG4gIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gdmFsaWRhdGUoKSB7XG4gIHJldHVybiB0aGlzLmN1cnZlLnZhbGlkYXRlKHRoaXMpO1xufTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS5kZWNvZGVQb2ludCA9IGZ1bmN0aW9uIGRlY29kZVBvaW50KGJ5dGVzLCBlbmMpIHtcbiAgYnl0ZXMgPSB1dGlscy50b0FycmF5KGJ5dGVzLCBlbmMpO1xuXG4gIHZhciBsZW4gPSB0aGlzLnAuYnl0ZUxlbmd0aCgpO1xuICBpZiAoYnl0ZXNbMF0gPT09IDB4MDQgJiYgYnl0ZXMubGVuZ3RoIC0gMSA9PT0gMiAqIGxlbikge1xuICAgIHJldHVybiB0aGlzLnBvaW50KGJ5dGVzLnNsaWNlKDEsIDEgKyBsZW4pLFxuICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzLnNsaWNlKDEgKyBsZW4sIDEgKyAyICogbGVuKSk7XG4gIH0gZWxzZSBpZiAoKGJ5dGVzWzBdID09PSAweDAyIHx8IGJ5dGVzWzBdID09PSAweDAzKSAmJlxuICAgICAgICAgICAgICBieXRlcy5sZW5ndGggLSAxID09PSBsZW4pIHtcbiAgICByZXR1cm4gdGhpcy5wb2ludEZyb21YKGJ5dGVzLnNsaWNlKDEsIDEgKyBsZW4pLCBieXRlc1swXSA9PT0gMHgwMyk7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHBvaW50IGZvcm1hdCcpO1xufTtcblxuQmFzZVBvaW50LnByb3RvdHlwZS5lbmNvZGVDb21wcmVzc2VkID0gZnVuY3Rpb24gZW5jb2RlQ29tcHJlc3NlZChlbmMpIHtcbiAgcmV0dXJuIHRoaXMuZW5jb2RlKGVuYywgdHJ1ZSk7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLl9lbmNvZGUgPSBmdW5jdGlvbiBfZW5jb2RlKGNvbXBhY3QpIHtcbiAgdmFyIGxlbiA9IHRoaXMuY3VydmUucC5ieXRlTGVuZ3RoKCk7XG4gIHZhciB4ID0gdGhpcy5nZXRYKCkudG9BcnJheSgnYmUnLCBsZW4pO1xuXG4gIGlmIChjb21wYWN0KVxuICAgIHJldHVybiBbIHRoaXMuZ2V0WSgpLmlzRXZlbigpID8gMHgwMiA6IDB4MDMgXS5jb25jYXQoeCk7XG5cbiAgcmV0dXJuIFsgMHgwNCBdLmNvbmNhdCh4LCB0aGlzLmdldFkoKS50b0FycmF5KCdiZScsIGxlbikpIDtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGVuYywgY29tcGFjdCkge1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHRoaXMuX2VuY29kZShjb21wYWN0KSwgZW5jKTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUucHJlY29tcHV0ZSA9IGZ1bmN0aW9uIHByZWNvbXB1dGUocG93ZXIpIHtcbiAgaWYgKHRoaXMucHJlY29tcHV0ZWQpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgdmFyIHByZWNvbXB1dGVkID0ge1xuICAgIGRvdWJsZXM6IG51bGwsXG4gICAgbmFmOiBudWxsLFxuICAgIGJldGE6IG51bGxcbiAgfTtcbiAgcHJlY29tcHV0ZWQubmFmID0gdGhpcy5fZ2V0TkFGUG9pbnRzKDgpO1xuICBwcmVjb21wdXRlZC5kb3VibGVzID0gdGhpcy5fZ2V0RG91Ymxlcyg0LCBwb3dlcik7XG4gIHByZWNvbXB1dGVkLmJldGEgPSB0aGlzLl9nZXRCZXRhKCk7XG4gIHRoaXMucHJlY29tcHV0ZWQgPSBwcmVjb21wdXRlZDtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2hhc0RvdWJsZXMgPSBmdW5jdGlvbiBfaGFzRG91YmxlcyhrKSB7XG4gIGlmICghdGhpcy5wcmVjb21wdXRlZClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGRvdWJsZXMgPSB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXM7XG4gIGlmICghZG91YmxlcylcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIGRvdWJsZXMucG9pbnRzLmxlbmd0aCA+PSBNYXRoLmNlaWwoKGsuYml0TGVuZ3RoKCkgKyAxKSAvIGRvdWJsZXMuc3RlcCk7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLl9nZXREb3VibGVzID0gZnVuY3Rpb24gX2dldERvdWJsZXMoc3RlcCwgcG93ZXIpIHtcbiAgaWYgKHRoaXMucHJlY29tcHV0ZWQgJiYgdGhpcy5wcmVjb21wdXRlZC5kb3VibGVzKVxuICAgIHJldHVybiB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXM7XG5cbiAgdmFyIGRvdWJsZXMgPSBbIHRoaXMgXTtcbiAgdmFyIGFjYyA9IHRoaXM7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcG93ZXI7IGkgKz0gc3RlcCkge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3RlcDsgaisrKVxuICAgICAgYWNjID0gYWNjLmRibCgpO1xuICAgIGRvdWJsZXMucHVzaChhY2MpO1xuICB9XG4gIHJldHVybiB7XG4gICAgc3RlcDogc3RlcCxcbiAgICBwb2ludHM6IGRvdWJsZXNcbiAgfTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2dldE5BRlBvaW50cyA9IGZ1bmN0aW9uIF9nZXROQUZQb2ludHMod25kKSB7XG4gIGlmICh0aGlzLnByZWNvbXB1dGVkICYmIHRoaXMucHJlY29tcHV0ZWQubmFmKVxuICAgIHJldHVybiB0aGlzLnByZWNvbXB1dGVkLm5hZjtcblxuICB2YXIgcmVzID0gWyB0aGlzIF07XG4gIHZhciBtYXggPSAoMSA8PCB3bmQpIC0gMTtcbiAgdmFyIGRibCA9IG1heCA9PT0gMSA/IG51bGwgOiB0aGlzLmRibCgpO1xuICBmb3IgKHZhciBpID0gMTsgaSA8IG1heDsgaSsrKVxuICAgIHJlc1tpXSA9IHJlc1tpIC0gMV0uYWRkKGRibCk7XG4gIHJldHVybiB7XG4gICAgd25kOiB3bmQsXG4gICAgcG9pbnRzOiByZXNcbiAgfTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2dldEJldGEgPSBmdW5jdGlvbiBfZ2V0QmV0YSgpIHtcbiAgcmV0dXJuIG51bGw7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLmRibHAgPSBmdW5jdGlvbiBkYmxwKGspIHtcbiAgdmFyIHIgPSB0aGlzO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGs7IGkrKylcbiAgICByID0gci5kYmwoKTtcbiAgcmV0dXJuIHI7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmUgPSByZXF1aXJlKCcuLi9jdXJ2ZScpO1xudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vLi4vZWxsaXB0aWMnKTtcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJhc2UgPSBjdXJ2ZS5iYXNlO1xuXG52YXIgYXNzZXJ0ID0gZWxsaXB0aWMudXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBFZHdhcmRzQ3VydmUoY29uZikge1xuICAvLyBOT1RFOiBJbXBvcnRhbnQgYXMgd2UgYXJlIGNyZWF0aW5nIHBvaW50IGluIEJhc2UuY2FsbCgpXG4gIHRoaXMudHdpc3RlZCA9IChjb25mLmEgfCAwKSAhPT0gMTtcbiAgdGhpcy5tT25lQSA9IHRoaXMudHdpc3RlZCAmJiAoY29uZi5hIHwgMCkgPT09IC0xO1xuICB0aGlzLmV4dGVuZGVkID0gdGhpcy5tT25lQTtcblxuICBCYXNlLmNhbGwodGhpcywgJ2Vkd2FyZHMnLCBjb25mKTtcblxuICB0aGlzLmEgPSBuZXcgQk4oY29uZi5hLCAxNikudW1vZCh0aGlzLnJlZC5tKTtcbiAgdGhpcy5hID0gdGhpcy5hLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5jID0gbmV3IEJOKGNvbmYuYywgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5jMiA9IHRoaXMuYy5yZWRTcXIoKTtcbiAgdGhpcy5kID0gbmV3IEJOKGNvbmYuZCwgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5kZCA9IHRoaXMuZC5yZWRBZGQodGhpcy5kKTtcblxuICBhc3NlcnQoIXRoaXMudHdpc3RlZCB8fCB0aGlzLmMuZnJvbVJlZCgpLmNtcG4oMSkgPT09IDApO1xuICB0aGlzLm9uZUMgPSAoY29uZi5jIHwgMCkgPT09IDE7XG59XG5pbmhlcml0cyhFZHdhcmRzQ3VydmUsIEJhc2UpO1xubW9kdWxlLmV4cG9ydHMgPSBFZHdhcmRzQ3VydmU7XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUuX211bEEgPSBmdW5jdGlvbiBfbXVsQShudW0pIHtcbiAgaWYgKHRoaXMubU9uZUEpXG4gICAgcmV0dXJuIG51bS5yZWROZWcoKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmEucmVkTXVsKG51bSk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLl9tdWxDID0gZnVuY3Rpb24gX211bEMobnVtKSB7XG4gIGlmICh0aGlzLm9uZUMpXG4gICAgcmV0dXJuIG51bTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmMucmVkTXVsKG51bSk7XG59O1xuXG4vLyBKdXN0IGZvciBjb21wYXRpYmlsaXR5IHdpdGggU2hvcnQgY3VydmVcbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUuanBvaW50ID0gZnVuY3Rpb24ganBvaW50KHgsIHksIHosIHQpIHtcbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSwgeiwgdCk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbVggPSBmdW5jdGlvbiBwb2ludEZyb21YKHgsIG9kZCkge1xuICB4ID0gbmV3IEJOKHgsIDE2KTtcbiAgaWYgKCF4LnJlZClcbiAgICB4ID0geC50b1JlZCh0aGlzLnJlZCk7XG5cbiAgdmFyIHgyID0geC5yZWRTcXIoKTtcbiAgdmFyIHJocyA9IHRoaXMuYzIucmVkU3ViKHRoaXMuYS5yZWRNdWwoeDIpKTtcbiAgdmFyIGxocyA9IHRoaXMub25lLnJlZFN1Yih0aGlzLmMyLnJlZE11bCh0aGlzLmQpLnJlZE11bCh4MikpO1xuXG4gIHZhciB5MiA9IHJocy5yZWRNdWwobGhzLnJlZEludm0oKSk7XG4gIHZhciB5ID0geTIucmVkU3FydCgpO1xuICBpZiAoeS5yZWRTcXIoKS5yZWRTdWIoeTIpLmNtcCh0aGlzLnplcm8pICE9PSAwKVxuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBwb2ludCcpO1xuXG4gIHZhciBpc09kZCA9IHkuZnJvbVJlZCgpLmlzT2RkKCk7XG4gIGlmIChvZGQgJiYgIWlzT2RkIHx8ICFvZGQgJiYgaXNPZGQpXG4gICAgeSA9IHkucmVkTmVnKCk7XG5cbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbVkgPSBmdW5jdGlvbiBwb2ludEZyb21ZKHksIG9kZCkge1xuICB5ID0gbmV3IEJOKHksIDE2KTtcbiAgaWYgKCF5LnJlZClcbiAgICB5ID0geS50b1JlZCh0aGlzLnJlZCk7XG5cbiAgLy8geF4yID0gKHleMiAtIDEpIC8gKGQgeV4yICsgMSlcbiAgdmFyIHkyID0geS5yZWRTcXIoKTtcbiAgdmFyIGxocyA9IHkyLnJlZFN1Yih0aGlzLm9uZSk7XG4gIHZhciByaHMgPSB5Mi5yZWRNdWwodGhpcy5kKS5yZWRBZGQodGhpcy5vbmUpO1xuICB2YXIgeDIgPSBsaHMucmVkTXVsKHJocy5yZWRJbnZtKCkpO1xuXG4gIGlmICh4Mi5jbXAodGhpcy56ZXJvKSA9PT0gMCkge1xuICAgIGlmIChvZGQpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcG9pbnQnKTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gdGhpcy5wb2ludCh0aGlzLnplcm8sIHkpO1xuICB9XG5cbiAgdmFyIHggPSB4Mi5yZWRTcXJ0KCk7XG4gIGlmICh4LnJlZFNxcigpLnJlZFN1Yih4MikuY21wKHRoaXMuemVybykgIT09IDApXG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHBvaW50Jyk7XG5cbiAgaWYgKHguaXNPZGQoKSAhPT0gb2RkKVxuICAgIHggPSB4LnJlZE5lZygpO1xuXG4gIHJldHVybiB0aGlzLnBvaW50KHgsIHkpO1xufTtcblxuRWR3YXJkc0N1cnZlLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKHBvaW50KSB7XG4gIGlmIChwb2ludC5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgLy8gQ3VydmU6IEEgKiBYXjIgKyBZXjIgPSBDXjIgKiAoMSArIEQgKiBYXjIgKiBZXjIpXG4gIHBvaW50Lm5vcm1hbGl6ZSgpO1xuXG4gIHZhciB4MiA9IHBvaW50LngucmVkU3FyKCk7XG4gIHZhciB5MiA9IHBvaW50LnkucmVkU3FyKCk7XG4gIHZhciBsaHMgPSB4Mi5yZWRNdWwodGhpcy5hKS5yZWRBZGQoeTIpO1xuICB2YXIgcmhzID0gdGhpcy5jMi5yZWRNdWwodGhpcy5vbmUucmVkQWRkKHRoaXMuZC5yZWRNdWwoeDIpLnJlZE11bCh5MikpKTtcblxuICByZXR1cm4gbGhzLmNtcChyaHMpID09PSAwO1xufTtcblxuZnVuY3Rpb24gUG9pbnQoY3VydmUsIHgsIHksIHosIHQpIHtcbiAgQmFzZS5CYXNlUG9pbnQuY2FsbCh0aGlzLCBjdXJ2ZSwgJ3Byb2plY3RpdmUnKTtcbiAgaWYgKHggPT09IG51bGwgJiYgeSA9PT0gbnVsbCAmJiB6ID09PSBudWxsKSB7XG4gICAgdGhpcy54ID0gdGhpcy5jdXJ2ZS56ZXJvO1xuICAgIHRoaXMueSA9IHRoaXMuY3VydmUub25lO1xuICAgIHRoaXMueiA9IHRoaXMuY3VydmUub25lO1xuICAgIHRoaXMudCA9IHRoaXMuY3VydmUuemVybztcbiAgICB0aGlzLnpPbmUgPSB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHRoaXMueCA9IG5ldyBCTih4LCAxNik7XG4gICAgdGhpcy55ID0gbmV3IEJOKHksIDE2KTtcbiAgICB0aGlzLnogPSB6ID8gbmV3IEJOKHosIDE2KSA6IHRoaXMuY3VydmUub25lO1xuICAgIHRoaXMudCA9IHQgJiYgbmV3IEJOKHQsIDE2KTtcbiAgICBpZiAoIXRoaXMueC5yZWQpXG4gICAgICB0aGlzLnggPSB0aGlzLngudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIGlmICghdGhpcy55LnJlZClcbiAgICAgIHRoaXMueSA9IHRoaXMueS50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgaWYgKCF0aGlzLnoucmVkKVxuICAgICAgdGhpcy56ID0gdGhpcy56LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICBpZiAodGhpcy50ICYmICF0aGlzLnQucmVkKVxuICAgICAgdGhpcy50ID0gdGhpcy50LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICB0aGlzLnpPbmUgPSB0aGlzLnogPT09IHRoaXMuY3VydmUub25lO1xuXG4gICAgLy8gVXNlIGV4dGVuZGVkIGNvb3JkaW5hdGVzXG4gICAgaWYgKHRoaXMuY3VydmUuZXh0ZW5kZWQgJiYgIXRoaXMudCkge1xuICAgICAgdGhpcy50ID0gdGhpcy54LnJlZE11bCh0aGlzLnkpO1xuICAgICAgaWYgKCF0aGlzLnpPbmUpXG4gICAgICAgIHRoaXMudCA9IHRoaXMudC5yZWRNdWwodGhpcy56LnJlZEludm0oKSk7XG4gICAgfVxuICB9XG59XG5pbmhlcml0cyhQb2ludCwgQmFzZS5CYXNlUG9pbnQpO1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbUpTT04gPSBmdW5jdGlvbiBwb2ludEZyb21KU09OKG9iaikge1xuICByZXR1cm4gUG9pbnQuZnJvbUpTT04odGhpcywgb2JqKTtcbn07XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUucG9pbnQgPSBmdW5jdGlvbiBwb2ludCh4LCB5LCB6LCB0KSB7XG4gIHJldHVybiBuZXcgUG9pbnQodGhpcywgeCwgeSwgeiwgdCk7XG59O1xuXG5Qb2ludC5mcm9tSlNPTiA9IGZ1bmN0aW9uIGZyb21KU09OKGN1cnZlLCBvYmopIHtcbiAgcmV0dXJuIG5ldyBQb2ludChjdXJ2ZSwgb2JqWzBdLCBvYmpbMV0sIG9ialsyXSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gJzxFQyBQb2ludCBJbmZpbml0eT4nO1xuICByZXR1cm4gJzxFQyBQb2ludCB4OiAnICsgdGhpcy54LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgK1xuICAgICAgJyB5OiAnICsgdGhpcy55LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgK1xuICAgICAgJyB6OiAnICsgdGhpcy56LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgKyAnPic7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaXNJbmZpbml0eSA9IGZ1bmN0aW9uIGlzSW5maW5pdHkoKSB7XG4gIC8vIFhYWCBUaGlzIGNvZGUgYXNzdW1lcyB0aGF0IHplcm8gaXMgYWx3YXlzIHplcm8gaW4gcmVkXG4gIHJldHVybiB0aGlzLnguY21wbigwKSA9PT0gMCAmJlxuICAgICAgICAgdGhpcy55LmNtcCh0aGlzLnopID09PSAwO1xufTtcblxuUG9pbnQucHJvdG90eXBlLl9leHREYmwgPSBmdW5jdGlvbiBfZXh0RGJsKCkge1xuICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tdHdpc3RlZC1leHRlbmRlZC0xLmh0bWxcbiAgLy8gICAgICNkb3VibGluZy1kYmwtMjAwOC1od2NkXG4gIC8vIDRNICsgNFNcblxuICAvLyBBID0gWDFeMlxuICB2YXIgYSA9IHRoaXMueC5yZWRTcXIoKTtcbiAgLy8gQiA9IFkxXjJcbiAgdmFyIGIgPSB0aGlzLnkucmVkU3FyKCk7XG4gIC8vIEMgPSAyICogWjFeMlxuICB2YXIgYyA9IHRoaXMuei5yZWRTcXIoKTtcbiAgYyA9IGMucmVkSUFkZChjKTtcbiAgLy8gRCA9IGEgKiBBXG4gIHZhciBkID0gdGhpcy5jdXJ2ZS5fbXVsQShhKTtcbiAgLy8gRSA9IChYMSArIFkxKV4yIC0gQSAtIEJcbiAgdmFyIGUgPSB0aGlzLngucmVkQWRkKHRoaXMueSkucmVkU3FyKCkucmVkSVN1YihhKS5yZWRJU3ViKGIpO1xuICAvLyBHID0gRCArIEJcbiAgdmFyIGcgPSBkLnJlZEFkZChiKTtcbiAgLy8gRiA9IEcgLSBDXG4gIHZhciBmID0gZy5yZWRTdWIoYyk7XG4gIC8vIEggPSBEIC0gQlxuICB2YXIgaCA9IGQucmVkU3ViKGIpO1xuICAvLyBYMyA9IEUgKiBGXG4gIHZhciBueCA9IGUucmVkTXVsKGYpO1xuICAvLyBZMyA9IEcgKiBIXG4gIHZhciBueSA9IGcucmVkTXVsKGgpO1xuICAvLyBUMyA9IEUgKiBIXG4gIHZhciBudCA9IGUucmVkTXVsKGgpO1xuICAvLyBaMyA9IEYgKiBHXG4gIHZhciBueiA9IGYucmVkTXVsKGcpO1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChueCwgbnksIG56LCBudCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX3Byb2pEYmwgPSBmdW5jdGlvbiBfcHJvakRibCgpIHtcbiAgLy8gaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLXR3aXN0ZWQtcHJvamVjdGl2ZS5odG1sXG4gIC8vICAgICAjZG91YmxpbmctZGJsLTIwMDgtYmJqbHBcbiAgLy8gICAgICNkb3VibGluZy1kYmwtMjAwNy1ibFxuICAvLyBhbmQgb3RoZXJzXG4gIC8vIEdlbmVyYWxseSAzTSArIDRTIG9yIDJNICsgNFNcblxuICAvLyBCID0gKFgxICsgWTEpXjJcbiAgdmFyIGIgPSB0aGlzLngucmVkQWRkKHRoaXMueSkucmVkU3FyKCk7XG4gIC8vIEMgPSBYMV4yXG4gIHZhciBjID0gdGhpcy54LnJlZFNxcigpO1xuICAvLyBEID0gWTFeMlxuICB2YXIgZCA9IHRoaXMueS5yZWRTcXIoKTtcblxuICB2YXIgbng7XG4gIHZhciBueTtcbiAgdmFyIG56O1xuICBpZiAodGhpcy5jdXJ2ZS50d2lzdGVkKSB7XG4gICAgLy8gRSA9IGEgKiBDXG4gICAgdmFyIGUgPSB0aGlzLmN1cnZlLl9tdWxBKGMpO1xuICAgIC8vIEYgPSBFICsgRFxuICAgIHZhciBmID0gZS5yZWRBZGQoZCk7XG4gICAgaWYgKHRoaXMuek9uZSkge1xuICAgICAgLy8gWDMgPSAoQiAtIEMgLSBEKSAqIChGIC0gMilcbiAgICAgIG54ID0gYi5yZWRTdWIoYykucmVkU3ViKGQpLnJlZE11bChmLnJlZFN1Yih0aGlzLmN1cnZlLnR3bykpO1xuICAgICAgLy8gWTMgPSBGICogKEUgLSBEKVxuICAgICAgbnkgPSBmLnJlZE11bChlLnJlZFN1YihkKSk7XG4gICAgICAvLyBaMyA9IEZeMiAtIDIgKiBGXG4gICAgICBueiA9IGYucmVkU3FyKCkucmVkU3ViKGYpLnJlZFN1YihmKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSCA9IFoxXjJcbiAgICAgIHZhciBoID0gdGhpcy56LnJlZFNxcigpO1xuICAgICAgLy8gSiA9IEYgLSAyICogSFxuICAgICAgdmFyIGogPSBmLnJlZFN1YihoKS5yZWRJU3ViKGgpO1xuICAgICAgLy8gWDMgPSAoQi1DLUQpKkpcbiAgICAgIG54ID0gYi5yZWRTdWIoYykucmVkSVN1YihkKS5yZWRNdWwoaik7XG4gICAgICAvLyBZMyA9IEYgKiAoRSAtIEQpXG4gICAgICBueSA9IGYucmVkTXVsKGUucmVkU3ViKGQpKTtcbiAgICAgIC8vIFozID0gRiAqIEpcbiAgICAgIG56ID0gZi5yZWRNdWwoaik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIEUgPSBDICsgRFxuICAgIHZhciBlID0gYy5yZWRBZGQoZCk7XG4gICAgLy8gSCA9IChjICogWjEpXjJcbiAgICB2YXIgaCA9IHRoaXMuY3VydmUuX211bEModGhpcy5jLnJlZE11bCh0aGlzLnopKS5yZWRTcXIoKTtcbiAgICAvLyBKID0gRSAtIDIgKiBIXG4gICAgdmFyIGogPSBlLnJlZFN1YihoKS5yZWRTdWIoaCk7XG4gICAgLy8gWDMgPSBjICogKEIgLSBFKSAqIEpcbiAgICBueCA9IHRoaXMuY3VydmUuX211bEMoYi5yZWRJU3ViKGUpKS5yZWRNdWwoaik7XG4gICAgLy8gWTMgPSBjICogRSAqIChDIC0gRClcbiAgICBueSA9IHRoaXMuY3VydmUuX211bEMoZSkucmVkTXVsKGMucmVkSVN1YihkKSk7XG4gICAgLy8gWjMgPSBFICogSlxuICAgIG56ID0gZS5yZWRNdWwoaik7XG4gIH1cbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG55LCBueik7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZGJsID0gZnVuY3Rpb24gZGJsKCkge1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gRG91YmxlIGluIGV4dGVuZGVkIGNvb3JkaW5hdGVzXG4gIGlmICh0aGlzLmN1cnZlLmV4dGVuZGVkKVxuICAgIHJldHVybiB0aGlzLl9leHREYmwoKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLl9wcm9qRGJsKCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX2V4dEFkZCA9IGZ1bmN0aW9uIF9leHRBZGQocCkge1xuICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tdHdpc3RlZC1leHRlbmRlZC0xLmh0bWxcbiAgLy8gICAgICNhZGRpdGlvbi1hZGQtMjAwOC1od2NkLTNcbiAgLy8gOE1cblxuICAvLyBBID0gKFkxIC0gWDEpICogKFkyIC0gWDIpXG4gIHZhciBhID0gdGhpcy55LnJlZFN1Yih0aGlzLngpLnJlZE11bChwLnkucmVkU3ViKHAueCkpO1xuICAvLyBCID0gKFkxICsgWDEpICogKFkyICsgWDIpXG4gIHZhciBiID0gdGhpcy55LnJlZEFkZCh0aGlzLngpLnJlZE11bChwLnkucmVkQWRkKHAueCkpO1xuICAvLyBDID0gVDEgKiBrICogVDJcbiAgdmFyIGMgPSB0aGlzLnQucmVkTXVsKHRoaXMuY3VydmUuZGQpLnJlZE11bChwLnQpO1xuICAvLyBEID0gWjEgKiAyICogWjJcbiAgdmFyIGQgPSB0aGlzLnoucmVkTXVsKHAuei5yZWRBZGQocC56KSk7XG4gIC8vIEUgPSBCIC0gQVxuICB2YXIgZSA9IGIucmVkU3ViKGEpO1xuICAvLyBGID0gRCAtIENcbiAgdmFyIGYgPSBkLnJlZFN1YihjKTtcbiAgLy8gRyA9IEQgKyBDXG4gIHZhciBnID0gZC5yZWRBZGQoYyk7XG4gIC8vIEggPSBCICsgQVxuICB2YXIgaCA9IGIucmVkQWRkKGEpO1xuICAvLyBYMyA9IEUgKiBGXG4gIHZhciBueCA9IGUucmVkTXVsKGYpO1xuICAvLyBZMyA9IEcgKiBIXG4gIHZhciBueSA9IGcucmVkTXVsKGgpO1xuICAvLyBUMyA9IEUgKiBIXG4gIHZhciBudCA9IGUucmVkTXVsKGgpO1xuICAvLyBaMyA9IEYgKiBHXG4gIHZhciBueiA9IGYucmVkTXVsKGcpO1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChueCwgbnksIG56LCBudCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX3Byb2pBZGQgPSBmdW5jdGlvbiBfcHJvakFkZChwKSB7XG4gIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by10d2lzdGVkLXByb2plY3RpdmUuaHRtbFxuICAvLyAgICAgI2FkZGl0aW9uLWFkZC0yMDA4LWJiamxwXG4gIC8vICAgICAjYWRkaXRpb24tYWRkLTIwMDctYmxcbiAgLy8gMTBNICsgMVNcblxuICAvLyBBID0gWjEgKiBaMlxuICB2YXIgYSA9IHRoaXMuei5yZWRNdWwocC56KTtcbiAgLy8gQiA9IEFeMlxuICB2YXIgYiA9IGEucmVkU3FyKCk7XG4gIC8vIEMgPSBYMSAqIFgyXG4gIHZhciBjID0gdGhpcy54LnJlZE11bChwLngpO1xuICAvLyBEID0gWTEgKiBZMlxuICB2YXIgZCA9IHRoaXMueS5yZWRNdWwocC55KTtcbiAgLy8gRSA9IGQgKiBDICogRFxuICB2YXIgZSA9IHRoaXMuY3VydmUuZC5yZWRNdWwoYykucmVkTXVsKGQpO1xuICAvLyBGID0gQiAtIEVcbiAgdmFyIGYgPSBiLnJlZFN1YihlKTtcbiAgLy8gRyA9IEIgKyBFXG4gIHZhciBnID0gYi5yZWRBZGQoZSk7XG4gIC8vIFgzID0gQSAqIEYgKiAoKFgxICsgWTEpICogKFgyICsgWTIpIC0gQyAtIEQpXG4gIHZhciB0bXAgPSB0aGlzLngucmVkQWRkKHRoaXMueSkucmVkTXVsKHAueC5yZWRBZGQocC55KSkucmVkSVN1YihjKS5yZWRJU3ViKGQpO1xuICB2YXIgbnggPSBhLnJlZE11bChmKS5yZWRNdWwodG1wKTtcbiAgdmFyIG55O1xuICB2YXIgbno7XG4gIGlmICh0aGlzLmN1cnZlLnR3aXN0ZWQpIHtcbiAgICAvLyBZMyA9IEEgKiBHICogKEQgLSBhICogQylcbiAgICBueSA9IGEucmVkTXVsKGcpLnJlZE11bChkLnJlZFN1Yih0aGlzLmN1cnZlLl9tdWxBKGMpKSk7XG4gICAgLy8gWjMgPSBGICogR1xuICAgIG56ID0gZi5yZWRNdWwoZyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gWTMgPSBBICogRyAqIChEIC0gQylcbiAgICBueSA9IGEucmVkTXVsKGcpLnJlZE11bChkLnJlZFN1YihjKSk7XG4gICAgLy8gWjMgPSBjICogRiAqIEdcbiAgICBueiA9IHRoaXMuY3VydmUuX211bEMoZikucmVkTXVsKGcpO1xuICB9XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSwgbnopO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZChwKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gcDtcbiAgaWYgKHAuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIGlmICh0aGlzLmN1cnZlLmV4dGVuZGVkKVxuICAgIHJldHVybiB0aGlzLl9leHRBZGQocCk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5fcHJvakFkZChwKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwoaykge1xuICBpZiAodGhpcy5faGFzRG91YmxlcyhrKSlcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fZml4ZWROYWZNdWwodGhpcywgayk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fd25hZk11bCh0aGlzLCBrKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWxBZGQgPSBmdW5jdGlvbiBtdWxBZGQoazEsIHAsIGsyKSB7XG4gIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsQWRkKDEsIFsgdGhpcywgcCBdLCBbIGsxLCBrMiBdLCAyKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5ub3JtYWxpemUgPSBmdW5jdGlvbiBub3JtYWxpemUoKSB7XG4gIGlmICh0aGlzLnpPbmUpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gTm9ybWFsaXplIGNvb3JkaW5hdGVzXG4gIHZhciB6aSA9IHRoaXMuei5yZWRJbnZtKCk7XG4gIHRoaXMueCA9IHRoaXMueC5yZWRNdWwoemkpO1xuICB0aGlzLnkgPSB0aGlzLnkucmVkTXVsKHppKTtcbiAgaWYgKHRoaXMudClcbiAgICB0aGlzLnQgPSB0aGlzLnQucmVkTXVsKHppKTtcbiAgdGhpcy56ID0gdGhpcy5jdXJ2ZS5vbmU7XG4gIHRoaXMuek9uZSA9IHRydWU7XG4gIHJldHVybiB0aGlzO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm5lZyA9IGZ1bmN0aW9uIG5lZygpIHtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQodGhpcy54LnJlZE5lZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMueixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50ICYmIHRoaXMudC5yZWROZWcoKSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WCA9IGZ1bmN0aW9uIGdldFgoKSB7XG4gIHRoaXMubm9ybWFsaXplKCk7XG4gIHJldHVybiB0aGlzLnguZnJvbVJlZCgpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmdldFkgPSBmdW5jdGlvbiBnZXRZKCkge1xuICB0aGlzLm5vcm1hbGl6ZSgpO1xuICByZXR1cm4gdGhpcy55LmZyb21SZWQoKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxKG90aGVyKSB7XG4gIHJldHVybiB0aGlzID09PSBvdGhlciB8fFxuICAgICAgICAgdGhpcy5nZXRYKCkuY21wKG90aGVyLmdldFgoKSkgPT09IDAgJiZcbiAgICAgICAgIHRoaXMuZ2V0WSgpLmNtcChvdGhlci5nZXRZKCkpID09PSAwO1xufTtcblxuLy8gQ29tcGF0aWJpbGl0eSB3aXRoIEJhc2VDdXJ2ZVxuUG9pbnQucHJvdG90eXBlLnRvUCA9IFBvaW50LnByb3RvdHlwZS5ub3JtYWxpemU7XG5Qb2ludC5wcm90b3R5cGUubWl4ZWRBZGQgPSBQb2ludC5wcm90b3R5cGUuYWRkO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmUgPSBleHBvcnRzO1xuXG5jdXJ2ZS5iYXNlID0gcmVxdWlyZSgnLi9iYXNlJyk7XG5jdXJ2ZS5zaG9ydCA9IHJlcXVpcmUoJy4vc2hvcnQnKTtcbmN1cnZlLm1vbnQgPSByZXF1aXJlKCcuL21vbnQnKTtcbmN1cnZlLmVkd2FyZHMgPSByZXF1aXJlKCcuL2Vkd2FyZHMnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1cnZlID0gcmVxdWlyZSgnLi4vY3VydmUnKTtcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJhc2UgPSBjdXJ2ZS5iYXNlO1xuXG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG5cbmZ1bmN0aW9uIE1vbnRDdXJ2ZShjb25mKSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnbW9udCcsIGNvbmYpO1xuXG4gIHRoaXMuYSA9IG5ldyBCTihjb25mLmEsIDE2KS50b1JlZCh0aGlzLnJlZCk7XG4gIHRoaXMuYiA9IG5ldyBCTihjb25mLmIsIDE2KS50b1JlZCh0aGlzLnJlZCk7XG4gIHRoaXMuaTQgPSBuZXcgQk4oNCkudG9SZWQodGhpcy5yZWQpLnJlZEludm0oKTtcbiAgdGhpcy50d28gPSBuZXcgQk4oMikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLmEyNCA9IHRoaXMuaTQucmVkTXVsKHRoaXMuYS5yZWRBZGQodGhpcy50d28pKTtcbn1cbmluaGVyaXRzKE1vbnRDdXJ2ZSwgQmFzZSk7XG5tb2R1bGUuZXhwb3J0cyA9IE1vbnRDdXJ2ZTtcblxuTW9udEN1cnZlLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKHBvaW50KSB7XG4gIHZhciB4ID0gcG9pbnQubm9ybWFsaXplKCkueDtcbiAgdmFyIHgyID0geC5yZWRTcXIoKTtcbiAgdmFyIHJocyA9IHgyLnJlZE11bCh4KS5yZWRBZGQoeDIucmVkTXVsKHRoaXMuYSkpLnJlZEFkZCh4KTtcbiAgdmFyIHkgPSByaHMucmVkU3FydCgpO1xuXG4gIHJldHVybiB5LnJlZFNxcigpLmNtcChyaHMpID09PSAwO1xufTtcblxuZnVuY3Rpb24gUG9pbnQoY3VydmUsIHgsIHopIHtcbiAgQmFzZS5CYXNlUG9pbnQuY2FsbCh0aGlzLCBjdXJ2ZSwgJ3Byb2plY3RpdmUnKTtcbiAgaWYgKHggPT09IG51bGwgJiYgeiA9PT0gbnVsbCkge1xuICAgIHRoaXMueCA9IHRoaXMuY3VydmUub25lO1xuICAgIHRoaXMueiA9IHRoaXMuY3VydmUuemVybztcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnggPSBuZXcgQk4oeCwgMTYpO1xuICAgIHRoaXMueiA9IG5ldyBCTih6LCAxNik7XG4gICAgaWYgKCF0aGlzLngucmVkKVxuICAgICAgdGhpcy54ID0gdGhpcy54LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICBpZiAoIXRoaXMuei5yZWQpXG4gICAgICB0aGlzLnogPSB0aGlzLnoudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICB9XG59XG5pbmhlcml0cyhQb2ludCwgQmFzZS5CYXNlUG9pbnQpO1xuXG5Nb250Q3VydmUucHJvdG90eXBlLmRlY29kZVBvaW50ID0gZnVuY3Rpb24gZGVjb2RlUG9pbnQoYnl0ZXMsIGVuYykge1xuICByZXR1cm4gdGhpcy5wb2ludCh1dGlscy50b0FycmF5KGJ5dGVzLCBlbmMpLCAxKTtcbn07XG5cbk1vbnRDdXJ2ZS5wcm90b3R5cGUucG9pbnQgPSBmdW5jdGlvbiBwb2ludCh4LCB6KSB7XG4gIHJldHVybiBuZXcgUG9pbnQodGhpcywgeCwgeik7XG59O1xuXG5Nb250Q3VydmUucHJvdG90eXBlLnBvaW50RnJvbUpTT04gPSBmdW5jdGlvbiBwb2ludEZyb21KU09OKG9iaikge1xuICByZXR1cm4gUG9pbnQuZnJvbUpTT04odGhpcywgb2JqKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5wcmVjb21wdXRlID0gZnVuY3Rpb24gcHJlY29tcHV0ZSgpIHtcbiAgLy8gTm8tb3Bcbn07XG5cblBvaW50LnByb3RvdHlwZS5fZW5jb2RlID0gZnVuY3Rpb24gX2VuY29kZSgpIHtcbiAgcmV0dXJuIHRoaXMuZ2V0WCgpLnRvQXJyYXkoJ2JlJywgdGhpcy5jdXJ2ZS5wLmJ5dGVMZW5ndGgoKSk7XG59O1xuXG5Qb2ludC5mcm9tSlNPTiA9IGZ1bmN0aW9uIGZyb21KU09OKGN1cnZlLCBvYmopIHtcbiAgcmV0dXJuIG5ldyBQb2ludChjdXJ2ZSwgb2JqWzBdLCBvYmpbMV0gfHwgY3VydmUub25lKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiAnPEVDIFBvaW50IEluZmluaXR5Pic7XG4gIHJldHVybiAnPEVDIFBvaW50IHg6ICcgKyB0aGlzLnguZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHo6ICcgKyB0aGlzLnouZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArICc+Jztcbn07XG5cblBvaW50LnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gaXNJbmZpbml0eSgpIHtcbiAgLy8gWFhYIFRoaXMgY29kZSBhc3N1bWVzIHRoYXQgemVybyBpcyBhbHdheXMgemVybyBpbiByZWRcbiAgcmV0dXJuIHRoaXMuei5jbXBuKDApID09PSAwO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmRibCA9IGZ1bmN0aW9uIGRibCgpIHtcbiAgLy8gaHR0cDovL2h5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1tb250Z29tLXh6Lmh0bWwjZG91YmxpbmctZGJsLTE5ODctbS0zXG4gIC8vIDJNICsgMlMgKyA0QVxuXG4gIC8vIEEgPSBYMSArIFoxXG4gIHZhciBhID0gdGhpcy54LnJlZEFkZCh0aGlzLnopO1xuICAvLyBBQSA9IEFeMlxuICB2YXIgYWEgPSBhLnJlZFNxcigpO1xuICAvLyBCID0gWDEgLSBaMVxuICB2YXIgYiA9IHRoaXMueC5yZWRTdWIodGhpcy56KTtcbiAgLy8gQkIgPSBCXjJcbiAgdmFyIGJiID0gYi5yZWRTcXIoKTtcbiAgLy8gQyA9IEFBIC0gQkJcbiAgdmFyIGMgPSBhYS5yZWRTdWIoYmIpO1xuICAvLyBYMyA9IEFBICogQkJcbiAgdmFyIG54ID0gYWEucmVkTXVsKGJiKTtcbiAgLy8gWjMgPSBDICogKEJCICsgQTI0ICogQylcbiAgdmFyIG56ID0gYy5yZWRNdWwoYmIucmVkQWRkKHRoaXMuY3VydmUuYTI0LnJlZE11bChjKSkpO1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChueCwgbnopO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZCgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdOb3Qgc3VwcG9ydGVkIG9uIE1vbnRnb21lcnkgY3VydmUnKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5kaWZmQWRkID0gZnVuY3Rpb24gZGlmZkFkZChwLCBkaWZmKSB7XG4gIC8vIGh0dHA6Ly9oeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tbW9udGdvbS14ei5odG1sI2RpZmZhZGQtZGFkZC0xOTg3LW0tM1xuICAvLyA0TSArIDJTICsgNkFcblxuICAvLyBBID0gWDIgKyBaMlxuICB2YXIgYSA9IHRoaXMueC5yZWRBZGQodGhpcy56KTtcbiAgLy8gQiA9IFgyIC0gWjJcbiAgdmFyIGIgPSB0aGlzLngucmVkU3ViKHRoaXMueik7XG4gIC8vIEMgPSBYMyArIFozXG4gIHZhciBjID0gcC54LnJlZEFkZChwLnopO1xuICAvLyBEID0gWDMgLSBaM1xuICB2YXIgZCA9IHAueC5yZWRTdWIocC56KTtcbiAgLy8gREEgPSBEICogQVxuICB2YXIgZGEgPSBkLnJlZE11bChhKTtcbiAgLy8gQ0IgPSBDICogQlxuICB2YXIgY2IgPSBjLnJlZE11bChiKTtcbiAgLy8gWDUgPSBaMSAqIChEQSArIENCKV4yXG4gIHZhciBueCA9IGRpZmYuei5yZWRNdWwoZGEucmVkQWRkKGNiKS5yZWRTcXIoKSk7XG4gIC8vIFo1ID0gWDEgKiAoREEgLSBDQileMlxuICB2YXIgbnogPSBkaWZmLngucmVkTXVsKGRhLnJlZElTdWIoY2IpLnJlZFNxcigpKTtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG56KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwoaykge1xuICB2YXIgdCA9IGsuY2xvbmUoKTtcbiAgdmFyIGEgPSB0aGlzOyAvLyAoTiAvIDIpICogUSArIFFcbiAgdmFyIGIgPSB0aGlzLmN1cnZlLnBvaW50KG51bGwsIG51bGwpOyAvLyAoTiAvIDIpICogUVxuICB2YXIgYyA9IHRoaXM7IC8vIFFcblxuICBmb3IgKHZhciBiaXRzID0gW107IHQuY21wbigwKSAhPT0gMDsgdC5pdXNocm4oMSkpXG4gICAgYml0cy5wdXNoKHQuYW5kbG4oMSkpO1xuXG4gIGZvciAodmFyIGkgPSBiaXRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKGJpdHNbaV0gPT09IDApIHtcbiAgICAgIC8vIE4gKiBRICsgUSA9ICgoTiAvIDIpICogUSArIFEpKSArIChOIC8gMikgKiBRXG4gICAgICBhID0gYS5kaWZmQWRkKGIsIGMpO1xuICAgICAgLy8gTiAqIFEgPSAyICogKChOIC8gMikgKiBRICsgUSkpXG4gICAgICBiID0gYi5kYmwoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTiAqIFEgPSAoKE4gLyAyKSAqIFEgKyBRKSArICgoTiAvIDIpICogUSlcbiAgICAgIGIgPSBhLmRpZmZBZGQoYiwgYyk7XG4gICAgICAvLyBOICogUSArIFEgPSAyICogKChOIC8gMikgKiBRICsgUSlcbiAgICAgIGEgPSBhLmRibCgpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYjtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWxBZGQgPSBmdW5jdGlvbiBtdWxBZGQoKSB7XG4gIHRocm93IG5ldyBFcnJvcignTm90IHN1cHBvcnRlZCBvbiBNb250Z29tZXJ5IGN1cnZlJyk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZXEgPSBmdW5jdGlvbiBlcShvdGhlcikge1xuICByZXR1cm4gdGhpcy5nZXRYKCkuY21wKG90aGVyLmdldFgoKSkgPT09IDA7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubm9ybWFsaXplID0gZnVuY3Rpb24gbm9ybWFsaXplKCkge1xuICB0aGlzLnggPSB0aGlzLngucmVkTXVsKHRoaXMuei5yZWRJbnZtKCkpO1xuICB0aGlzLnogPSB0aGlzLmN1cnZlLm9uZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WCA9IGZ1bmN0aW9uIGdldFgoKSB7XG4gIC8vIE5vcm1hbGl6ZSBjb29yZGluYXRlc1xuICB0aGlzLm5vcm1hbGl6ZSgpO1xuXG4gIHJldHVybiB0aGlzLnguZnJvbVJlZCgpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1cnZlID0gcmVxdWlyZSgnLi4vY3VydmUnKTtcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBCYXNlID0gY3VydmUuYmFzZTtcblxudmFyIGFzc2VydCA9IGVsbGlwdGljLnV0aWxzLmFzc2VydDtcblxuZnVuY3Rpb24gU2hvcnRDdXJ2ZShjb25mKSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnc2hvcnQnLCBjb25mKTtcblxuICB0aGlzLmEgPSBuZXcgQk4oY29uZi5hLCAxNikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLmIgPSBuZXcgQk4oY29uZi5iLCAxNikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLnRpbnYgPSB0aGlzLnR3by5yZWRJbnZtKCk7XG5cbiAgdGhpcy56ZXJvQSA9IHRoaXMuYS5mcm9tUmVkKCkuY21wbigwKSA9PT0gMDtcbiAgdGhpcy50aHJlZUEgPSB0aGlzLmEuZnJvbVJlZCgpLnN1Yih0aGlzLnApLmNtcG4oLTMpID09PSAwO1xuXG4gIC8vIElmIHRoZSBjdXJ2ZSBpcyBlbmRvbW9ycGhpYywgcHJlY2FsY3VsYXRlIGJldGEgYW5kIGxhbWJkYVxuICB0aGlzLmVuZG8gPSB0aGlzLl9nZXRFbmRvbW9ycGhpc20oY29uZik7XG4gIHRoaXMuX2VuZG9XbmFmVDEgPSBuZXcgQXJyYXkoNCk7XG4gIHRoaXMuX2VuZG9XbmFmVDIgPSBuZXcgQXJyYXkoNCk7XG59XG5pbmhlcml0cyhTaG9ydEN1cnZlLCBCYXNlKTtcbm1vZHVsZS5leHBvcnRzID0gU2hvcnRDdXJ2ZTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUuX2dldEVuZG9tb3JwaGlzbSA9IGZ1bmN0aW9uIF9nZXRFbmRvbW9ycGhpc20oY29uZikge1xuICAvLyBObyBlZmZpY2llbnQgZW5kb21vcnBoaXNtXG4gIGlmICghdGhpcy56ZXJvQSB8fCAhdGhpcy5nIHx8ICF0aGlzLm4gfHwgdGhpcy5wLm1vZG4oMykgIT09IDEpXG4gICAgcmV0dXJuO1xuXG4gIC8vIENvbXB1dGUgYmV0YSBhbmQgbGFtYmRhLCB0aGF0IGxhbWJkYSAqIFAgPSAoYmV0YSAqIFB4OyBQeSlcbiAgdmFyIGJldGE7XG4gIHZhciBsYW1iZGE7XG4gIGlmIChjb25mLmJldGEpIHtcbiAgICBiZXRhID0gbmV3IEJOKGNvbmYuYmV0YSwgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgYmV0YXMgPSB0aGlzLl9nZXRFbmRvUm9vdHModGhpcy5wKTtcbiAgICAvLyBDaG9vc2UgdGhlIHNtYWxsZXN0IGJldGFcbiAgICBiZXRhID0gYmV0YXNbMF0uY21wKGJldGFzWzFdKSA8IDAgPyBiZXRhc1swXSA6IGJldGFzWzFdO1xuICAgIGJldGEgPSBiZXRhLnRvUmVkKHRoaXMucmVkKTtcbiAgfVxuICBpZiAoY29uZi5sYW1iZGEpIHtcbiAgICBsYW1iZGEgPSBuZXcgQk4oY29uZi5sYW1iZGEsIDE2KTtcbiAgfSBlbHNlIHtcbiAgICAvLyBDaG9vc2UgdGhlIGxhbWJkYSB0aGF0IGlzIG1hdGNoaW5nIHNlbGVjdGVkIGJldGFcbiAgICB2YXIgbGFtYmRhcyA9IHRoaXMuX2dldEVuZG9Sb290cyh0aGlzLm4pO1xuICAgIGlmICh0aGlzLmcubXVsKGxhbWJkYXNbMF0pLnguY21wKHRoaXMuZy54LnJlZE11bChiZXRhKSkgPT09IDApIHtcbiAgICAgIGxhbWJkYSA9IGxhbWJkYXNbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxhbWJkYSA9IGxhbWJkYXNbMV07XG4gICAgICBhc3NlcnQodGhpcy5nLm11bChsYW1iZGEpLnguY21wKHRoaXMuZy54LnJlZE11bChiZXRhKSkgPT09IDApO1xuICAgIH1cbiAgfVxuXG4gIC8vIEdldCBiYXNpcyB2ZWN0b3JzLCB1c2VkIGZvciBiYWxhbmNlZCBsZW5ndGgtdHdvIHJlcHJlc2VudGF0aW9uXG4gIHZhciBiYXNpcztcbiAgaWYgKGNvbmYuYmFzaXMpIHtcbiAgICBiYXNpcyA9IGNvbmYuYmFzaXMubWFwKGZ1bmN0aW9uKHZlYykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYTogbmV3IEJOKHZlYy5hLCAxNiksXG4gICAgICAgIGI6IG5ldyBCTih2ZWMuYiwgMTYpXG4gICAgICB9O1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGJhc2lzID0gdGhpcy5fZ2V0RW5kb0Jhc2lzKGxhbWJkYSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJldGE6IGJldGEsXG4gICAgbGFtYmRhOiBsYW1iZGEsXG4gICAgYmFzaXM6IGJhc2lzXG4gIH07XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5fZ2V0RW5kb1Jvb3RzID0gZnVuY3Rpb24gX2dldEVuZG9Sb290cyhudW0pIHtcbiAgLy8gRmluZCByb290cyBvZiBmb3IgeF4yICsgeCArIDEgaW4gRlxuICAvLyBSb290ID0gKC0xICstIFNxcnQoLTMpKSAvIDJcbiAgLy9cbiAgdmFyIHJlZCA9IG51bSA9PT0gdGhpcy5wID8gdGhpcy5yZWQgOiBCTi5tb250KG51bSk7XG4gIHZhciB0aW52ID0gbmV3IEJOKDIpLnRvUmVkKHJlZCkucmVkSW52bSgpO1xuICB2YXIgbnRpbnYgPSB0aW52LnJlZE5lZygpO1xuXG4gIHZhciBzID0gbmV3IEJOKDMpLnRvUmVkKHJlZCkucmVkTmVnKCkucmVkU3FydCgpLnJlZE11bCh0aW52KTtcblxuICB2YXIgbDEgPSBudGludi5yZWRBZGQocykuZnJvbVJlZCgpO1xuICB2YXIgbDIgPSBudGludi5yZWRTdWIocykuZnJvbVJlZCgpO1xuICByZXR1cm4gWyBsMSwgbDIgXTtcbn07XG5cblNob3J0Q3VydmUucHJvdG90eXBlLl9nZXRFbmRvQmFzaXMgPSBmdW5jdGlvbiBfZ2V0RW5kb0Jhc2lzKGxhbWJkYSkge1xuICAvLyBhcHJ4U3FydCA+PSBzcXJ0KHRoaXMubilcbiAgdmFyIGFwcnhTcXJ0ID0gdGhpcy5uLnVzaHJuKE1hdGguZmxvb3IodGhpcy5uLmJpdExlbmd0aCgpIC8gMikpO1xuXG4gIC8vIDMuNzRcbiAgLy8gUnVuIEVHQ0QsIHVudGlsIHIoTCArIDEpIDwgYXByeFNxcnRcbiAgdmFyIHUgPSBsYW1iZGE7XG4gIHZhciB2ID0gdGhpcy5uLmNsb25lKCk7XG4gIHZhciB4MSA9IG5ldyBCTigxKTtcbiAgdmFyIHkxID0gbmV3IEJOKDApO1xuICB2YXIgeDIgPSBuZXcgQk4oMCk7XG4gIHZhciB5MiA9IG5ldyBCTigxKTtcblxuICAvLyBOT1RFOiBhbGwgdmVjdG9ycyBhcmUgcm9vdHMgb2Y6IGEgKyBiICogbGFtYmRhID0gMCAobW9kIG4pXG4gIHZhciBhMDtcbiAgdmFyIGIwO1xuICAvLyBGaXJzdCB2ZWN0b3JcbiAgdmFyIGExO1xuICB2YXIgYjE7XG4gIC8vIFNlY29uZCB2ZWN0b3JcbiAgdmFyIGEyO1xuICB2YXIgYjI7XG5cbiAgdmFyIHByZXZSO1xuICB2YXIgaSA9IDA7XG4gIHZhciByO1xuICB2YXIgeDtcbiAgd2hpbGUgKHUuY21wbigwKSAhPT0gMCkge1xuICAgIHZhciBxID0gdi5kaXYodSk7XG4gICAgciA9IHYuc3ViKHEubXVsKHUpKTtcbiAgICB4ID0geDIuc3ViKHEubXVsKHgxKSk7XG4gICAgdmFyIHkgPSB5Mi5zdWIocS5tdWwoeTEpKTtcblxuICAgIGlmICghYTEgJiYgci5jbXAoYXByeFNxcnQpIDwgMCkge1xuICAgICAgYTAgPSBwcmV2Ui5uZWcoKTtcbiAgICAgIGIwID0geDE7XG4gICAgICBhMSA9IHIubmVnKCk7XG4gICAgICBiMSA9IHg7XG4gICAgfSBlbHNlIGlmIChhMSAmJiArK2kgPT09IDIpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBwcmV2UiA9IHI7XG5cbiAgICB2ID0gdTtcbiAgICB1ID0gcjtcbiAgICB4MiA9IHgxO1xuICAgIHgxID0geDtcbiAgICB5MiA9IHkxO1xuICAgIHkxID0geTtcbiAgfVxuICBhMiA9IHIubmVnKCk7XG4gIGIyID0geDtcblxuICB2YXIgbGVuMSA9IGExLnNxcigpLmFkZChiMS5zcXIoKSk7XG4gIHZhciBsZW4yID0gYTIuc3FyKCkuYWRkKGIyLnNxcigpKTtcbiAgaWYgKGxlbjIuY21wKGxlbjEpID49IDApIHtcbiAgICBhMiA9IGEwO1xuICAgIGIyID0gYjA7XG4gIH1cblxuICAvLyBOb3JtYWxpemUgc2lnbnNcbiAgaWYgKGExLm5lZ2F0aXZlKSB7XG4gICAgYTEgPSBhMS5uZWcoKTtcbiAgICBiMSA9IGIxLm5lZygpO1xuICB9XG4gIGlmIChhMi5uZWdhdGl2ZSkge1xuICAgIGEyID0gYTIubmVnKCk7XG4gICAgYjIgPSBiMi5uZWcoKTtcbiAgfVxuXG4gIHJldHVybiBbXG4gICAgeyBhOiBhMSwgYjogYjEgfSxcbiAgICB7IGE6IGEyLCBiOiBiMiB9XG4gIF07XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5fZW5kb1NwbGl0ID0gZnVuY3Rpb24gX2VuZG9TcGxpdChrKSB7XG4gIHZhciBiYXNpcyA9IHRoaXMuZW5kby5iYXNpcztcbiAgdmFyIHYxID0gYmFzaXNbMF07XG4gIHZhciB2MiA9IGJhc2lzWzFdO1xuXG4gIHZhciBjMSA9IHYyLmIubXVsKGspLmRpdlJvdW5kKHRoaXMubik7XG4gIHZhciBjMiA9IHYxLmIubmVnKCkubXVsKGspLmRpdlJvdW5kKHRoaXMubik7XG5cbiAgdmFyIHAxID0gYzEubXVsKHYxLmEpO1xuICB2YXIgcDIgPSBjMi5tdWwodjIuYSk7XG4gIHZhciBxMSA9IGMxLm11bCh2MS5iKTtcbiAgdmFyIHEyID0gYzIubXVsKHYyLmIpO1xuXG4gIC8vIENhbGN1bGF0ZSBhbnN3ZXJcbiAgdmFyIGsxID0gay5zdWIocDEpLnN1YihwMik7XG4gIHZhciBrMiA9IHExLmFkZChxMikubmVnKCk7XG4gIHJldHVybiB7IGsxOiBrMSwgazI6IGsyIH07XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5wb2ludEZyb21YID0gZnVuY3Rpb24gcG9pbnRGcm9tWCh4LCBvZGQpIHtcbiAgeCA9IG5ldyBCTih4LCAxNik7XG4gIGlmICgheC5yZWQpXG4gICAgeCA9IHgudG9SZWQodGhpcy5yZWQpO1xuXG4gIHZhciB5MiA9IHgucmVkU3FyKCkucmVkTXVsKHgpLnJlZElBZGQoeC5yZWRNdWwodGhpcy5hKSkucmVkSUFkZCh0aGlzLmIpO1xuICB2YXIgeSA9IHkyLnJlZFNxcnQoKTtcbiAgaWYgKHkucmVkU3FyKCkucmVkU3ViKHkyKS5jbXAodGhpcy56ZXJvKSAhPT0gMClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcG9pbnQnKTtcblxuICAvLyBYWFggSXMgdGhlcmUgYW55IHdheSB0byB0ZWxsIGlmIHRoZSBudW1iZXIgaXMgb2RkIHdpdGhvdXQgY29udmVydGluZyBpdFxuICAvLyB0byBub24tcmVkIGZvcm0/XG4gIHZhciBpc09kZCA9IHkuZnJvbVJlZCgpLmlzT2RkKCk7XG4gIGlmIChvZGQgJiYgIWlzT2RkIHx8ICFvZGQgJiYgaXNPZGQpXG4gICAgeSA9IHkucmVkTmVnKCk7XG5cbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSk7XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKHBvaW50KSB7XG4gIGlmIChwb2ludC5pbmYpXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgdmFyIHggPSBwb2ludC54O1xuICB2YXIgeSA9IHBvaW50Lnk7XG5cbiAgdmFyIGF4ID0gdGhpcy5hLnJlZE11bCh4KTtcbiAgdmFyIHJocyA9IHgucmVkU3FyKCkucmVkTXVsKHgpLnJlZElBZGQoYXgpLnJlZElBZGQodGhpcy5iKTtcbiAgcmV0dXJuIHkucmVkU3FyKCkucmVkSVN1YihyaHMpLmNtcG4oMCkgPT09IDA7XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5fZW5kb1duYWZNdWxBZGQgPVxuICAgIGZ1bmN0aW9uIF9lbmRvV25hZk11bEFkZChwb2ludHMsIGNvZWZmcykge1xuICB2YXIgbnBvaW50cyA9IHRoaXMuX2VuZG9XbmFmVDE7XG4gIHZhciBuY29lZmZzID0gdGhpcy5fZW5kb1duYWZUMjtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc3BsaXQgPSB0aGlzLl9lbmRvU3BsaXQoY29lZmZzW2ldKTtcbiAgICB2YXIgcCA9IHBvaW50c1tpXTtcbiAgICB2YXIgYmV0YSA9IHAuX2dldEJldGEoKTtcblxuICAgIGlmIChzcGxpdC5rMS5uZWdhdGl2ZSkge1xuICAgICAgc3BsaXQuazEuaW5lZygpO1xuICAgICAgcCA9IHAubmVnKHRydWUpO1xuICAgIH1cbiAgICBpZiAoc3BsaXQuazIubmVnYXRpdmUpIHtcbiAgICAgIHNwbGl0LmsyLmluZWcoKTtcbiAgICAgIGJldGEgPSBiZXRhLm5lZyh0cnVlKTtcbiAgICB9XG5cbiAgICBucG9pbnRzW2kgKiAyXSA9IHA7XG4gICAgbnBvaW50c1tpICogMiArIDFdID0gYmV0YTtcbiAgICBuY29lZmZzW2kgKiAyXSA9IHNwbGl0LmsxO1xuICAgIG5jb2VmZnNbaSAqIDIgKyAxXSA9IHNwbGl0LmsyO1xuICB9XG4gIHZhciByZXMgPSB0aGlzLl93bmFmTXVsQWRkKDEsIG5wb2ludHMsIG5jb2VmZnMsIGkgKiAyKTtcblxuICAvLyBDbGVhbi11cCByZWZlcmVuY2VzIHRvIHBvaW50cyBhbmQgY29lZmZpY2llbnRzXG4gIGZvciAodmFyIGogPSAwOyBqIDwgaSAqIDI7IGorKykge1xuICAgIG5wb2ludHNbal0gPSBudWxsO1xuICAgIG5jb2VmZnNbal0gPSBudWxsO1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBQb2ludChjdXJ2ZSwgeCwgeSwgaXNSZWQpIHtcbiAgQmFzZS5CYXNlUG9pbnQuY2FsbCh0aGlzLCBjdXJ2ZSwgJ2FmZmluZScpO1xuICBpZiAoeCA9PT0gbnVsbCAmJiB5ID09PSBudWxsKSB7XG4gICAgdGhpcy54ID0gbnVsbDtcbiAgICB0aGlzLnkgPSBudWxsO1xuICAgIHRoaXMuaW5mID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnggPSBuZXcgQk4oeCwgMTYpO1xuICAgIHRoaXMueSA9IG5ldyBCTih5LCAxNik7XG4gICAgLy8gRm9yY2UgcmVkZ29tZXJ5IHJlcHJlc2VudGF0aW9uIHdoZW4gbG9hZGluZyBmcm9tIEpTT05cbiAgICBpZiAoaXNSZWQpIHtcbiAgICAgIHRoaXMueC5mb3JjZVJlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgICB0aGlzLnkuZm9yY2VSZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMueC5yZWQpXG4gICAgICB0aGlzLnggPSB0aGlzLngudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIGlmICghdGhpcy55LnJlZClcbiAgICAgIHRoaXMueSA9IHRoaXMueS50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgdGhpcy5pbmYgPSBmYWxzZTtcbiAgfVxufVxuaW5oZXJpdHMoUG9pbnQsIEJhc2UuQmFzZVBvaW50KTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUucG9pbnQgPSBmdW5jdGlvbiBwb2ludCh4LCB5LCBpc1JlZCkge1xuICByZXR1cm4gbmV3IFBvaW50KHRoaXMsIHgsIHksIGlzUmVkKTtcbn07XG5cblNob3J0Q3VydmUucHJvdG90eXBlLnBvaW50RnJvbUpTT04gPSBmdW5jdGlvbiBwb2ludEZyb21KU09OKG9iaiwgcmVkKSB7XG4gIHJldHVybiBQb2ludC5mcm9tSlNPTih0aGlzLCBvYmosIHJlZCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX2dldEJldGEgPSBmdW5jdGlvbiBfZ2V0QmV0YSgpIHtcbiAgaWYgKCF0aGlzLmN1cnZlLmVuZG8pXG4gICAgcmV0dXJuO1xuXG4gIHZhciBwcmUgPSB0aGlzLnByZWNvbXB1dGVkO1xuICBpZiAocHJlICYmIHByZS5iZXRhKVxuICAgIHJldHVybiBwcmUuYmV0YTtcblxuICB2YXIgYmV0YSA9IHRoaXMuY3VydmUucG9pbnQodGhpcy54LnJlZE11bCh0aGlzLmN1cnZlLmVuZG8uYmV0YSksIHRoaXMueSk7XG4gIGlmIChwcmUpIHtcbiAgICB2YXIgY3VydmUgPSB0aGlzLmN1cnZlO1xuICAgIHZhciBlbmRvTXVsID0gZnVuY3Rpb24ocCkge1xuICAgICAgcmV0dXJuIGN1cnZlLnBvaW50KHAueC5yZWRNdWwoY3VydmUuZW5kby5iZXRhKSwgcC55KTtcbiAgICB9O1xuICAgIHByZS5iZXRhID0gYmV0YTtcbiAgICBiZXRhLnByZWNvbXB1dGVkID0ge1xuICAgICAgYmV0YTogbnVsbCxcbiAgICAgIG5hZjogcHJlLm5hZiAmJiB7XG4gICAgICAgIHduZDogcHJlLm5hZi53bmQsXG4gICAgICAgIHBvaW50czogcHJlLm5hZi5wb2ludHMubWFwKGVuZG9NdWwpXG4gICAgICB9LFxuICAgICAgZG91YmxlczogcHJlLmRvdWJsZXMgJiYge1xuICAgICAgICBzdGVwOiBwcmUuZG91Ymxlcy5zdGVwLFxuICAgICAgICBwb2ludHM6IHByZS5kb3VibGVzLnBvaW50cy5tYXAoZW5kb011bClcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIHJldHVybiBiZXRhO1xufTtcblxuUG9pbnQucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgaWYgKCF0aGlzLnByZWNvbXB1dGVkKVxuICAgIHJldHVybiBbIHRoaXMueCwgdGhpcy55IF07XG5cbiAgcmV0dXJuIFsgdGhpcy54LCB0aGlzLnksIHRoaXMucHJlY29tcHV0ZWQgJiYge1xuICAgIGRvdWJsZXM6IHRoaXMucHJlY29tcHV0ZWQuZG91YmxlcyAmJiB7XG4gICAgICBzdGVwOiB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXMuc3RlcCxcbiAgICAgIHBvaW50czogdGhpcy5wcmVjb21wdXRlZC5kb3VibGVzLnBvaW50cy5zbGljZSgxKVxuICAgIH0sXG4gICAgbmFmOiB0aGlzLnByZWNvbXB1dGVkLm5hZiAmJiB7XG4gICAgICB3bmQ6IHRoaXMucHJlY29tcHV0ZWQubmFmLnduZCxcbiAgICAgIHBvaW50czogdGhpcy5wcmVjb21wdXRlZC5uYWYucG9pbnRzLnNsaWNlKDEpXG4gICAgfVxuICB9IF07XG59O1xuXG5Qb2ludC5mcm9tSlNPTiA9IGZ1bmN0aW9uIGZyb21KU09OKGN1cnZlLCBvYmosIHJlZCkge1xuICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycpXG4gICAgb2JqID0gSlNPTi5wYXJzZShvYmopO1xuICB2YXIgcmVzID0gY3VydmUucG9pbnQob2JqWzBdLCBvYmpbMV0sIHJlZCk7XG4gIGlmICghb2JqWzJdKVxuICAgIHJldHVybiByZXM7XG5cbiAgZnVuY3Rpb24gb2JqMnBvaW50KG9iaikge1xuICAgIHJldHVybiBjdXJ2ZS5wb2ludChvYmpbMF0sIG9ialsxXSwgcmVkKTtcbiAgfVxuXG4gIHZhciBwcmUgPSBvYmpbMl07XG4gIHJlcy5wcmVjb21wdXRlZCA9IHtcbiAgICBiZXRhOiBudWxsLFxuICAgIGRvdWJsZXM6IHByZS5kb3VibGVzICYmIHtcbiAgICAgIHN0ZXA6IHByZS5kb3VibGVzLnN0ZXAsXG4gICAgICBwb2ludHM6IFsgcmVzIF0uY29uY2F0KHByZS5kb3VibGVzLnBvaW50cy5tYXAob2JqMnBvaW50KSlcbiAgICB9LFxuICAgIG5hZjogcHJlLm5hZiAmJiB7XG4gICAgICB3bmQ6IHByZS5uYWYud25kLFxuICAgICAgcG9pbnRzOiBbIHJlcyBdLmNvbmNhdChwcmUubmFmLnBvaW50cy5tYXAob2JqMnBvaW50KSlcbiAgICB9XG4gIH07XG4gIHJldHVybiByZXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gJzxFQyBQb2ludCBJbmZpbml0eT4nO1xuICByZXR1cm4gJzxFQyBQb2ludCB4OiAnICsgdGhpcy54LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgK1xuICAgICAgJyB5OiAnICsgdGhpcy55LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgKyAnPic7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaXNJbmZpbml0eSA9IGZ1bmN0aW9uIGlzSW5maW5pdHkoKSB7XG4gIHJldHVybiB0aGlzLmluZjtcbn07XG5cblBvaW50LnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQocCkge1xuICAvLyBPICsgUCA9IFBcbiAgaWYgKHRoaXMuaW5mKVxuICAgIHJldHVybiBwO1xuXG4gIC8vIFAgKyBPID0gUFxuICBpZiAocC5pbmYpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gUCArIFAgPSAyUFxuICBpZiAodGhpcy5lcShwKSlcbiAgICByZXR1cm4gdGhpcy5kYmwoKTtcblxuICAvLyBQICsgKC1QKSA9IE9cbiAgaWYgKHRoaXMubmVnKCkuZXEocCkpXG4gICAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobnVsbCwgbnVsbCk7XG5cbiAgLy8gUCArIFEgPSBPXG4gIGlmICh0aGlzLnguY21wKHAueCkgPT09IDApXG4gICAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobnVsbCwgbnVsbCk7XG5cbiAgdmFyIGMgPSB0aGlzLnkucmVkU3ViKHAueSk7XG4gIGlmIChjLmNtcG4oMCkgIT09IDApXG4gICAgYyA9IGMucmVkTXVsKHRoaXMueC5yZWRTdWIocC54KS5yZWRJbnZtKCkpO1xuICB2YXIgbnggPSBjLnJlZFNxcigpLnJlZElTdWIodGhpcy54KS5yZWRJU3ViKHAueCk7XG4gIHZhciBueSA9IGMucmVkTXVsKHRoaXMueC5yZWRTdWIobngpKS5yZWRJU3ViKHRoaXMueSk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZGJsID0gZnVuY3Rpb24gZGJsKCkge1xuICBpZiAodGhpcy5pbmYpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gMlAgPSBPXG4gIHZhciB5czEgPSB0aGlzLnkucmVkQWRkKHRoaXMueSk7XG4gIGlmICh5czEuY21wbigwKSA9PT0gMClcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTtcblxuICB2YXIgYSA9IHRoaXMuY3VydmUuYTtcblxuICB2YXIgeDIgPSB0aGlzLngucmVkU3FyKCk7XG4gIHZhciBkeWludiA9IHlzMS5yZWRJbnZtKCk7XG4gIHZhciBjID0geDIucmVkQWRkKHgyKS5yZWRJQWRkKHgyKS5yZWRJQWRkKGEpLnJlZE11bChkeWludik7XG5cbiAgdmFyIG54ID0gYy5yZWRTcXIoKS5yZWRJU3ViKHRoaXMueC5yZWRBZGQodGhpcy54KSk7XG4gIHZhciBueSA9IGMucmVkTXVsKHRoaXMueC5yZWRTdWIobngpKS5yZWRJU3ViKHRoaXMueSk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WCA9IGZ1bmN0aW9uIGdldFgoKSB7XG4gIHJldHVybiB0aGlzLnguZnJvbVJlZCgpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmdldFkgPSBmdW5jdGlvbiBnZXRZKCkge1xuICByZXR1cm4gdGhpcy55LmZyb21SZWQoKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwoaykge1xuICBrID0gbmV3IEJOKGssIDE2KTtcblxuICBpZiAodGhpcy5faGFzRG91YmxlcyhrKSlcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fZml4ZWROYWZNdWwodGhpcywgayk7XG4gIGVsc2UgaWYgKHRoaXMuY3VydmUuZW5kbylcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fZW5kb1duYWZNdWxBZGQoWyB0aGlzIF0sIFsgayBdKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsKHRoaXMsIGspO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bEFkZCA9IGZ1bmN0aW9uIG11bEFkZChrMSwgcDIsIGsyKSB7XG4gIHZhciBwb2ludHMgPSBbIHRoaXMsIHAyIF07XG4gIHZhciBjb2VmZnMgPSBbIGsxLCBrMiBdO1xuICBpZiAodGhpcy5jdXJ2ZS5lbmRvKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9lbmRvV25hZk11bEFkZChwb2ludHMsIGNvZWZmcyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fd25hZk11bEFkZCgxLCBwb2ludHMsIGNvZWZmcywgMik7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZXEgPSBmdW5jdGlvbiBlcShwKSB7XG4gIHJldHVybiB0aGlzID09PSBwIHx8XG4gICAgICAgICB0aGlzLmluZiA9PT0gcC5pbmYgJiZcbiAgICAgICAgICAgICAodGhpcy5pbmYgfHwgdGhpcy54LmNtcChwLngpID09PSAwICYmIHRoaXMueS5jbXAocC55KSA9PT0gMCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnKF9wcmVjb21wdXRlKSB7XG4gIGlmICh0aGlzLmluZilcbiAgICByZXR1cm4gdGhpcztcblxuICB2YXIgcmVzID0gdGhpcy5jdXJ2ZS5wb2ludCh0aGlzLngsIHRoaXMueS5yZWROZWcoKSk7XG4gIGlmIChfcHJlY29tcHV0ZSAmJiB0aGlzLnByZWNvbXB1dGVkKSB7XG4gICAgdmFyIHByZSA9IHRoaXMucHJlY29tcHV0ZWQ7XG4gICAgdmFyIG5lZ2F0ZSA9IGZ1bmN0aW9uKHApIHtcbiAgICAgIHJldHVybiBwLm5lZygpO1xuICAgIH07XG4gICAgcmVzLnByZWNvbXB1dGVkID0ge1xuICAgICAgbmFmOiBwcmUubmFmICYmIHtcbiAgICAgICAgd25kOiBwcmUubmFmLnduZCxcbiAgICAgICAgcG9pbnRzOiBwcmUubmFmLnBvaW50cy5tYXAobmVnYXRlKVxuICAgICAgfSxcbiAgICAgIGRvdWJsZXM6IHByZS5kb3VibGVzICYmIHtcbiAgICAgICAgc3RlcDogcHJlLmRvdWJsZXMuc3RlcCxcbiAgICAgICAgcG9pbnRzOiBwcmUuZG91Ymxlcy5wb2ludHMubWFwKG5lZ2F0ZSlcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUudG9KID0gZnVuY3Rpb24gdG9KKCkge1xuICBpZiAodGhpcy5pbmYpXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuXG4gIHZhciByZXMgPSB0aGlzLmN1cnZlLmpwb2ludCh0aGlzLngsIHRoaXMueSwgdGhpcy5jdXJ2ZS5vbmUpO1xuICByZXR1cm4gcmVzO1xufTtcblxuZnVuY3Rpb24gSlBvaW50KGN1cnZlLCB4LCB5LCB6KSB7XG4gIEJhc2UuQmFzZVBvaW50LmNhbGwodGhpcywgY3VydmUsICdqYWNvYmlhbicpO1xuICBpZiAoeCA9PT0gbnVsbCAmJiB5ID09PSBudWxsICYmIHogPT09IG51bGwpIHtcbiAgICB0aGlzLnggPSB0aGlzLmN1cnZlLm9uZTtcbiAgICB0aGlzLnkgPSB0aGlzLmN1cnZlLm9uZTtcbiAgICB0aGlzLnogPSBuZXcgQk4oMCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54ID0gbmV3IEJOKHgsIDE2KTtcbiAgICB0aGlzLnkgPSBuZXcgQk4oeSwgMTYpO1xuICAgIHRoaXMueiA9IG5ldyBCTih6LCAxNik7XG4gIH1cbiAgaWYgKCF0aGlzLngucmVkKVxuICAgIHRoaXMueCA9IHRoaXMueC50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gIGlmICghdGhpcy55LnJlZClcbiAgICB0aGlzLnkgPSB0aGlzLnkudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICBpZiAoIXRoaXMuei5yZWQpXG4gICAgdGhpcy56ID0gdGhpcy56LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcblxuICB0aGlzLnpPbmUgPSB0aGlzLnogPT09IHRoaXMuY3VydmUub25lO1xufVxuaW5oZXJpdHMoSlBvaW50LCBCYXNlLkJhc2VQb2ludCk7XG5cblNob3J0Q3VydmUucHJvdG90eXBlLmpwb2ludCA9IGZ1bmN0aW9uIGpwb2ludCh4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgSlBvaW50KHRoaXMsIHgsIHksIHopO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS50b1AgPSBmdW5jdGlvbiB0b1AoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTtcblxuICB2YXIgemludiA9IHRoaXMuei5yZWRJbnZtKCk7XG4gIHZhciB6aW52MiA9IHppbnYucmVkU3FyKCk7XG4gIHZhciBheCA9IHRoaXMueC5yZWRNdWwoemludjIpO1xuICB2YXIgYXkgPSB0aGlzLnkucmVkTXVsKHppbnYyKS5yZWRNdWwoemludik7XG5cbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQoYXgsIGF5KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnKCkge1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQodGhpcy54LCB0aGlzLnkucmVkTmVnKCksIHRoaXMueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZChwKSB7XG4gIC8vIE8gKyBQID0gUFxuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHA7XG5cbiAgLy8gUCArIE8gPSBQXG4gIGlmIChwLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyAxMk0gKyA0UyArIDdBXG4gIHZhciBwejIgPSBwLnoucmVkU3FyKCk7XG4gIHZhciB6MiA9IHRoaXMuei5yZWRTcXIoKTtcbiAgdmFyIHUxID0gdGhpcy54LnJlZE11bChwejIpO1xuICB2YXIgdTIgPSBwLngucmVkTXVsKHoyKTtcbiAgdmFyIHMxID0gdGhpcy55LnJlZE11bChwejIucmVkTXVsKHAueikpO1xuICB2YXIgczIgPSBwLnkucmVkTXVsKHoyLnJlZE11bCh0aGlzLnopKTtcblxuICB2YXIgaCA9IHUxLnJlZFN1Yih1Mik7XG4gIHZhciByID0gczEucmVkU3ViKHMyKTtcbiAgaWYgKGguY21wbigwKSA9PT0gMCkge1xuICAgIGlmIChyLmNtcG4oMCkgIT09IDApXG4gICAgICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMuZGJsKCk7XG4gIH1cblxuICB2YXIgaDIgPSBoLnJlZFNxcigpO1xuICB2YXIgaDMgPSBoMi5yZWRNdWwoaCk7XG4gIHZhciB2ID0gdTEucmVkTXVsKGgyKTtcblxuICB2YXIgbnggPSByLnJlZFNxcigpLnJlZElBZGQoaDMpLnJlZElTdWIodikucmVkSVN1Yih2KTtcbiAgdmFyIG55ID0gci5yZWRNdWwodi5yZWRJU3ViKG54KSkucmVkSVN1YihzMS5yZWRNdWwoaDMpKTtcbiAgdmFyIG56ID0gdGhpcy56LnJlZE11bChwLnopLnJlZE11bChoKTtcblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLm1peGVkQWRkID0gZnVuY3Rpb24gbWl4ZWRBZGQocCkge1xuICAvLyBPICsgUCA9IFBcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiBwLnRvSigpO1xuXG4gIC8vIFAgKyBPID0gUFxuICBpZiAocC5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gOE0gKyAzUyArIDdBXG4gIHZhciB6MiA9IHRoaXMuei5yZWRTcXIoKTtcbiAgdmFyIHUxID0gdGhpcy54O1xuICB2YXIgdTIgPSBwLngucmVkTXVsKHoyKTtcbiAgdmFyIHMxID0gdGhpcy55O1xuICB2YXIgczIgPSBwLnkucmVkTXVsKHoyKS5yZWRNdWwodGhpcy56KTtcblxuICB2YXIgaCA9IHUxLnJlZFN1Yih1Mik7XG4gIHZhciByID0gczEucmVkU3ViKHMyKTtcbiAgaWYgKGguY21wbigwKSA9PT0gMCkge1xuICAgIGlmIChyLmNtcG4oMCkgIT09IDApXG4gICAgICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMuZGJsKCk7XG4gIH1cblxuICB2YXIgaDIgPSBoLnJlZFNxcigpO1xuICB2YXIgaDMgPSBoMi5yZWRNdWwoaCk7XG4gIHZhciB2ID0gdTEucmVkTXVsKGgyKTtcblxuICB2YXIgbnggPSByLnJlZFNxcigpLnJlZElBZGQoaDMpLnJlZElTdWIodikucmVkSVN1Yih2KTtcbiAgdmFyIG55ID0gci5yZWRNdWwodi5yZWRJU3ViKG54KSkucmVkSVN1YihzMS5yZWRNdWwoaDMpKTtcbiAgdmFyIG56ID0gdGhpcy56LnJlZE11bChoKTtcblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmRibHAgPSBmdW5jdGlvbiBkYmxwKHBvdykge1xuICBpZiAocG93ID09PSAwKVxuICAgIHJldHVybiB0aGlzO1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG4gIGlmICghcG93KVxuICAgIHJldHVybiB0aGlzLmRibCgpO1xuXG4gIGlmICh0aGlzLmN1cnZlLnplcm9BIHx8IHRoaXMuY3VydmUudGhyZWVBKSB7XG4gICAgdmFyIHIgPSB0aGlzO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG93OyBpKyspXG4gICAgICByID0gci5kYmwoKTtcbiAgICByZXR1cm4gcjtcbiAgfVxuXG4gIC8vIDFNICsgMlMgKyAxQSArIE4gKiAoNFMgKyA1TSArIDhBKVxuICAvLyBOID0gMSA9PiA2TSArIDZTICsgOUFcbiAgdmFyIGEgPSB0aGlzLmN1cnZlLmE7XG4gIHZhciB0aW52ID0gdGhpcy5jdXJ2ZS50aW52O1xuXG4gIHZhciBqeCA9IHRoaXMueDtcbiAgdmFyIGp5ID0gdGhpcy55O1xuICB2YXIganogPSB0aGlzLno7XG4gIHZhciBqejQgPSBqei5yZWRTcXIoKS5yZWRTcXIoKTtcblxuICAvLyBSZXVzZSByZXN1bHRzXG4gIHZhciBqeWQgPSBqeS5yZWRBZGQoankpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBvdzsgaSsrKSB7XG4gICAgdmFyIGp4MiA9IGp4LnJlZFNxcigpO1xuICAgIHZhciBqeWQyID0ganlkLnJlZFNxcigpO1xuICAgIHZhciBqeWQ0ID0ganlkMi5yZWRTcXIoKTtcbiAgICB2YXIgYyA9IGp4Mi5yZWRBZGQoangyKS5yZWRJQWRkKGp4MikucmVkSUFkZChhLnJlZE11bChqejQpKTtcblxuICAgIHZhciB0MSA9IGp4LnJlZE11bChqeWQyKTtcbiAgICB2YXIgbnggPSBjLnJlZFNxcigpLnJlZElTdWIodDEucmVkQWRkKHQxKSk7XG4gICAgdmFyIHQyID0gdDEucmVkSVN1YihueCk7XG4gICAgdmFyIGRueSA9IGMucmVkTXVsKHQyKTtcbiAgICBkbnkgPSBkbnkucmVkSUFkZChkbnkpLnJlZElTdWIoanlkNCk7XG4gICAgdmFyIG56ID0ganlkLnJlZE11bChqeik7XG4gICAgaWYgKGkgKyAxIDwgcG93KVxuICAgICAgano0ID0gano0LnJlZE11bChqeWQ0KTtcblxuICAgIGp4ID0gbng7XG4gICAganogPSBuejtcbiAgICBqeWQgPSBkbnk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQoangsIGp5ZC5yZWRNdWwodGludiksIGp6KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuZGJsID0gZnVuY3Rpb24gZGJsKCkge1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgaWYgKHRoaXMuY3VydmUuemVyb0EpXG4gICAgcmV0dXJuIHRoaXMuX3plcm9EYmwoKTtcbiAgZWxzZSBpZiAodGhpcy5jdXJ2ZS50aHJlZUEpXG4gICAgcmV0dXJuIHRoaXMuX3RocmVlRGJsKCk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5fZGJsKCk7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLl96ZXJvRGJsID0gZnVuY3Rpb24gX3plcm9EYmwoKSB7XG4gIHZhciBueDtcbiAgdmFyIG55O1xuICB2YXIgbno7XG4gIC8vIFogPSAxXG4gIGlmICh0aGlzLnpPbmUpIHtcbiAgICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tc2hvcnR3LWphY29iaWFuLTAuaHRtbFxuICAgIC8vICAgICAjZG91YmxpbmctbWRibC0yMDA3LWJsXG4gICAgLy8gMU0gKyA1UyArIDE0QVxuXG4gICAgLy8gWFggPSBYMV4yXG4gICAgdmFyIHh4ID0gdGhpcy54LnJlZFNxcigpO1xuICAgIC8vIFlZID0gWTFeMlxuICAgIHZhciB5eSA9IHRoaXMueS5yZWRTcXIoKTtcbiAgICAvLyBZWVlZID0gWVleMlxuICAgIHZhciB5eXl5ID0geXkucmVkU3FyKCk7XG4gICAgLy8gUyA9IDIgKiAoKFgxICsgWVkpXjIgLSBYWCAtIFlZWVkpXG4gICAgdmFyIHMgPSB0aGlzLngucmVkQWRkKHl5KS5yZWRTcXIoKS5yZWRJU3ViKHh4KS5yZWRJU3ViKHl5eXkpO1xuICAgIHMgPSBzLnJlZElBZGQocyk7XG4gICAgLy8gTSA9IDMgKiBYWCArIGE7IGEgPSAwXG4gICAgdmFyIG0gPSB4eC5yZWRBZGQoeHgpLnJlZElBZGQoeHgpO1xuICAgIC8vIFQgPSBNIF4gMiAtIDIqU1xuICAgIHZhciB0ID0gbS5yZWRTcXIoKS5yZWRJU3ViKHMpLnJlZElTdWIocyk7XG5cbiAgICAvLyA4ICogWVlZWVxuICAgIHZhciB5eXl5OCA9IHl5eXkucmVkSUFkZCh5eXl5KTtcbiAgICB5eXl5OCA9IHl5eXk4LnJlZElBZGQoeXl5eTgpO1xuICAgIHl5eXk4ID0geXl5eTgucmVkSUFkZCh5eXl5OCk7XG5cbiAgICAvLyBYMyA9IFRcbiAgICBueCA9IHQ7XG4gICAgLy8gWTMgPSBNICogKFMgLSBUKSAtIDggKiBZWVlZXG4gICAgbnkgPSBtLnJlZE11bChzLnJlZElTdWIodCkpLnJlZElTdWIoeXl5eTgpO1xuICAgIC8vIFozID0gMipZMVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnkpO1xuICB9IGVsc2Uge1xuICAgIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1zaG9ydHctamFjb2JpYW4tMC5odG1sXG4gICAgLy8gICAgICNkb3VibGluZy1kYmwtMjAwOS1sXG4gICAgLy8gMk0gKyA1UyArIDEzQVxuXG4gICAgLy8gQSA9IFgxXjJcbiAgICB2YXIgYSA9IHRoaXMueC5yZWRTcXIoKTtcbiAgICAvLyBCID0gWTFeMlxuICAgIHZhciBiID0gdGhpcy55LnJlZFNxcigpO1xuICAgIC8vIEMgPSBCXjJcbiAgICB2YXIgYyA9IGIucmVkU3FyKCk7XG4gICAgLy8gRCA9IDIgKiAoKFgxICsgQileMiAtIEEgLSBDKVxuICAgIHZhciBkID0gdGhpcy54LnJlZEFkZChiKS5yZWRTcXIoKS5yZWRJU3ViKGEpLnJlZElTdWIoYyk7XG4gICAgZCA9IGQucmVkSUFkZChkKTtcbiAgICAvLyBFID0gMyAqIEFcbiAgICB2YXIgZSA9IGEucmVkQWRkKGEpLnJlZElBZGQoYSk7XG4gICAgLy8gRiA9IEVeMlxuICAgIHZhciBmID0gZS5yZWRTcXIoKTtcblxuICAgIC8vIDggKiBDXG4gICAgdmFyIGM4ID0gYy5yZWRJQWRkKGMpO1xuICAgIGM4ID0gYzgucmVkSUFkZChjOCk7XG4gICAgYzggPSBjOC5yZWRJQWRkKGM4KTtcblxuICAgIC8vIFgzID0gRiAtIDIgKiBEXG4gICAgbnggPSBmLnJlZElTdWIoZCkucmVkSVN1YihkKTtcbiAgICAvLyBZMyA9IEUgKiAoRCAtIFgzKSAtIDggKiBDXG4gICAgbnkgPSBlLnJlZE11bChkLnJlZElTdWIobngpKS5yZWRJU3ViKGM4KTtcbiAgICAvLyBaMyA9IDIgKiBZMSAqIFoxXG4gICAgbnogPSB0aGlzLnkucmVkTXVsKHRoaXMueik7XG4gICAgbnogPSBuei5yZWRJQWRkKG56KTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChueCwgbnksIG56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuX3RocmVlRGJsID0gZnVuY3Rpb24gX3RocmVlRGJsKCkge1xuICB2YXIgbng7XG4gIHZhciBueTtcbiAgdmFyIG56O1xuICAvLyBaID0gMVxuICBpZiAodGhpcy56T25lKSB7XG4gICAgLy8gaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLXNob3J0dy1qYWNvYmlhbi0zLmh0bWxcbiAgICAvLyAgICAgI2RvdWJsaW5nLW1kYmwtMjAwNy1ibFxuICAgIC8vIDFNICsgNVMgKyAxNUFcblxuICAgIC8vIFhYID0gWDFeMlxuICAgIHZhciB4eCA9IHRoaXMueC5yZWRTcXIoKTtcbiAgICAvLyBZWSA9IFkxXjJcbiAgICB2YXIgeXkgPSB0aGlzLnkucmVkU3FyKCk7XG4gICAgLy8gWVlZWSA9IFlZXjJcbiAgICB2YXIgeXl5eSA9IHl5LnJlZFNxcigpO1xuICAgIC8vIFMgPSAyICogKChYMSArIFlZKV4yIC0gWFggLSBZWVlZKVxuICAgIHZhciBzID0gdGhpcy54LnJlZEFkZCh5eSkucmVkU3FyKCkucmVkSVN1Yih4eCkucmVkSVN1Yih5eXl5KTtcbiAgICBzID0gcy5yZWRJQWRkKHMpO1xuICAgIC8vIE0gPSAzICogWFggKyBhXG4gICAgdmFyIG0gPSB4eC5yZWRBZGQoeHgpLnJlZElBZGQoeHgpLnJlZElBZGQodGhpcy5jdXJ2ZS5hKTtcbiAgICAvLyBUID0gTV4yIC0gMiAqIFNcbiAgICB2YXIgdCA9IG0ucmVkU3FyKCkucmVkSVN1YihzKS5yZWRJU3ViKHMpO1xuICAgIC8vIFgzID0gVFxuICAgIG54ID0gdDtcbiAgICAvLyBZMyA9IE0gKiAoUyAtIFQpIC0gOCAqIFlZWVlcbiAgICB2YXIgeXl5eTggPSB5eXl5LnJlZElBZGQoeXl5eSk7XG4gICAgeXl5eTggPSB5eXl5OC5yZWRJQWRkKHl5eXk4KTtcbiAgICB5eXl5OCA9IHl5eXk4LnJlZElBZGQoeXl5eTgpO1xuICAgIG55ID0gbS5yZWRNdWwocy5yZWRJU3ViKHQpKS5yZWRJU3ViKHl5eXk4KTtcbiAgICAvLyBaMyA9IDIgKiBZMVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnkpO1xuICB9IGVsc2Uge1xuICAgIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1zaG9ydHctamFjb2JpYW4tMy5odG1sI2RvdWJsaW5nLWRibC0yMDAxLWJcbiAgICAvLyAzTSArIDVTXG5cbiAgICAvLyBkZWx0YSA9IFoxXjJcbiAgICB2YXIgZGVsdGEgPSB0aGlzLnoucmVkU3FyKCk7XG4gICAgLy8gZ2FtbWEgPSBZMV4yXG4gICAgdmFyIGdhbW1hID0gdGhpcy55LnJlZFNxcigpO1xuICAgIC8vIGJldGEgPSBYMSAqIGdhbW1hXG4gICAgdmFyIGJldGEgPSB0aGlzLngucmVkTXVsKGdhbW1hKTtcbiAgICAvLyBhbHBoYSA9IDMgKiAoWDEgLSBkZWx0YSkgKiAoWDEgKyBkZWx0YSlcbiAgICB2YXIgYWxwaGEgPSB0aGlzLngucmVkU3ViKGRlbHRhKS5yZWRNdWwodGhpcy54LnJlZEFkZChkZWx0YSkpO1xuICAgIGFscGhhID0gYWxwaGEucmVkQWRkKGFscGhhKS5yZWRJQWRkKGFscGhhKTtcbiAgICAvLyBYMyA9IGFscGhhXjIgLSA4ICogYmV0YVxuICAgIHZhciBiZXRhNCA9IGJldGEucmVkSUFkZChiZXRhKTtcbiAgICBiZXRhNCA9IGJldGE0LnJlZElBZGQoYmV0YTQpO1xuICAgIHZhciBiZXRhOCA9IGJldGE0LnJlZEFkZChiZXRhNCk7XG4gICAgbnggPSBhbHBoYS5yZWRTcXIoKS5yZWRJU3ViKGJldGE4KTtcbiAgICAvLyBaMyA9IChZMSArIFoxKV4yIC0gZ2FtbWEgLSBkZWx0YVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnopLnJlZFNxcigpLnJlZElTdWIoZ2FtbWEpLnJlZElTdWIoZGVsdGEpO1xuICAgIC8vIFkzID0gYWxwaGEgKiAoNCAqIGJldGEgLSBYMykgLSA4ICogZ2FtbWFeMlxuICAgIHZhciBnZ2FtbWE4ID0gZ2FtbWEucmVkU3FyKCk7XG4gICAgZ2dhbW1hOCA9IGdnYW1tYTgucmVkSUFkZChnZ2FtbWE4KTtcbiAgICBnZ2FtbWE4ID0gZ2dhbW1hOC5yZWRJQWRkKGdnYW1tYTgpO1xuICAgIGdnYW1tYTggPSBnZ2FtbWE4LnJlZElBZGQoZ2dhbW1hOCk7XG4gICAgbnkgPSBhbHBoYS5yZWRNdWwoYmV0YTQucmVkSVN1YihueCkpLnJlZElTdWIoZ2dhbW1hOCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLl9kYmwgPSBmdW5jdGlvbiBfZGJsKCkge1xuICB2YXIgYSA9IHRoaXMuY3VydmUuYTtcblxuICAvLyA0TSArIDZTICsgMTBBXG4gIHZhciBqeCA9IHRoaXMueDtcbiAgdmFyIGp5ID0gdGhpcy55O1xuICB2YXIganogPSB0aGlzLno7XG4gIHZhciBqejQgPSBqei5yZWRTcXIoKS5yZWRTcXIoKTtcblxuICB2YXIgangyID0gangucmVkU3FyKCk7XG4gIHZhciBqeTIgPSBqeS5yZWRTcXIoKTtcblxuICB2YXIgYyA9IGp4Mi5yZWRBZGQoangyKS5yZWRJQWRkKGp4MikucmVkSUFkZChhLnJlZE11bChqejQpKTtcblxuICB2YXIganhkNCA9IGp4LnJlZEFkZChqeCk7XG4gIGp4ZDQgPSBqeGQ0LnJlZElBZGQoanhkNCk7XG4gIHZhciB0MSA9IGp4ZDQucmVkTXVsKGp5Mik7XG4gIHZhciBueCA9IGMucmVkU3FyKCkucmVkSVN1Yih0MS5yZWRBZGQodDEpKTtcbiAgdmFyIHQyID0gdDEucmVkSVN1YihueCk7XG5cbiAgdmFyIGp5ZDggPSBqeTIucmVkU3FyKCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIHZhciBueSA9IGMucmVkTXVsKHQyKS5yZWRJU3ViKGp5ZDgpO1xuICB2YXIgbnogPSBqeS5yZWRBZGQoankpLnJlZE11bChqeik7XG5cbiAgcmV0dXJuIHRoaXMuY3VydmUuanBvaW50KG54LCBueSwgbnopO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS50cnBsID0gZnVuY3Rpb24gdHJwbCgpIHtcbiAgaWYgKCF0aGlzLmN1cnZlLnplcm9BKVxuICAgIHJldHVybiB0aGlzLmRibCgpLmFkZCh0aGlzKTtcblxuICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tc2hvcnR3LWphY29iaWFuLTAuaHRtbCN0cmlwbGluZy10cGwtMjAwNy1ibFxuICAvLyA1TSArIDEwUyArIC4uLlxuXG4gIC8vIFhYID0gWDFeMlxuICB2YXIgeHggPSB0aGlzLngucmVkU3FyKCk7XG4gIC8vIFlZID0gWTFeMlxuICB2YXIgeXkgPSB0aGlzLnkucmVkU3FyKCk7XG4gIC8vIFpaID0gWjFeMlxuICB2YXIgenogPSB0aGlzLnoucmVkU3FyKCk7XG4gIC8vIFlZWVkgPSBZWV4yXG4gIHZhciB5eXl5ID0geXkucmVkU3FyKCk7XG4gIC8vIE0gPSAzICogWFggKyBhICogWloyOyBhID0gMFxuICB2YXIgbSA9IHh4LnJlZEFkZCh4eCkucmVkSUFkZCh4eCk7XG4gIC8vIE1NID0gTV4yXG4gIHZhciBtbSA9IG0ucmVkU3FyKCk7XG4gIC8vIEUgPSA2ICogKChYMSArIFlZKV4yIC0gWFggLSBZWVlZKSAtIE1NXG4gIHZhciBlID0gdGhpcy54LnJlZEFkZCh5eSkucmVkU3FyKCkucmVkSVN1Yih4eCkucmVkSVN1Yih5eXl5KTtcbiAgZSA9IGUucmVkSUFkZChlKTtcbiAgZSA9IGUucmVkQWRkKGUpLnJlZElBZGQoZSk7XG4gIGUgPSBlLnJlZElTdWIobW0pO1xuICAvLyBFRSA9IEVeMlxuICB2YXIgZWUgPSBlLnJlZFNxcigpO1xuICAvLyBUID0gMTYqWVlZWVxuICB2YXIgdCA9IHl5eXkucmVkSUFkZCh5eXl5KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgLy8gVSA9IChNICsgRSleMiAtIE1NIC0gRUUgLSBUXG4gIHZhciB1ID0gbS5yZWRJQWRkKGUpLnJlZFNxcigpLnJlZElTdWIobW0pLnJlZElTdWIoZWUpLnJlZElTdWIodCk7XG4gIC8vIFgzID0gNCAqIChYMSAqIEVFIC0gNCAqIFlZICogVSlcbiAgdmFyIHl5dTQgPSB5eS5yZWRNdWwodSk7XG4gIHl5dTQgPSB5eXU0LnJlZElBZGQoeXl1NCk7XG4gIHl5dTQgPSB5eXU0LnJlZElBZGQoeXl1NCk7XG4gIHZhciBueCA9IHRoaXMueC5yZWRNdWwoZWUpLnJlZElTdWIoeXl1NCk7XG4gIG54ID0gbngucmVkSUFkZChueCk7XG4gIG54ID0gbngucmVkSUFkZChueCk7XG4gIC8vIFkzID0gOCAqIFkxICogKFUgKiAoVCAtIFUpIC0gRSAqIEVFKVxuICB2YXIgbnkgPSB0aGlzLnkucmVkTXVsKHUucmVkTXVsKHQucmVkSVN1Yih1KSkucmVkSVN1YihlLnJlZE11bChlZSkpKTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgLy8gWjMgPSAoWjEgKyBFKV4yIC0gWlogLSBFRVxuICB2YXIgbnogPSB0aGlzLnoucmVkQWRkKGUpLnJlZFNxcigpLnJlZElTdWIoenopLnJlZElTdWIoZWUpO1xuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChueCwgbnksIG56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsKGssIGtiYXNlKSB7XG4gIGsgPSBuZXcgQk4oaywga2Jhc2UpO1xuXG4gIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsKHRoaXMsIGspO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxKHApIHtcbiAgaWYgKHAudHlwZSA9PT0gJ2FmZmluZScpXG4gICAgcmV0dXJuIHRoaXMuZXEocC50b0ooKSk7XG5cbiAgaWYgKHRoaXMgPT09IHApXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgLy8geDEgKiB6Ml4yID09IHgyICogejFeMlxuICB2YXIgejIgPSB0aGlzLnoucmVkU3FyKCk7XG4gIHZhciBwejIgPSBwLnoucmVkU3FyKCk7XG4gIGlmICh0aGlzLngucmVkTXVsKHB6MikucmVkSVN1YihwLngucmVkTXVsKHoyKSkuY21wbigwKSAhPT0gMClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8geTEgKiB6Ml4zID09IHkyICogejFeM1xuICB2YXIgejMgPSB6Mi5yZWRNdWwodGhpcy56KTtcbiAgdmFyIHB6MyA9IHB6Mi5yZWRNdWwocC56KTtcbiAgcmV0dXJuIHRoaXMueS5yZWRNdWwocHozKS5yZWRJU3ViKHAueS5yZWRNdWwoejMpKS5jbXBuKDApID09PSAwO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiAnPEVDIEpQb2ludCBJbmZpbml0eT4nO1xuICByZXR1cm4gJzxFQyBKUG9pbnQgeDogJyArIHRoaXMueC50b1N0cmluZygxNiwgMikgK1xuICAgICAgJyB5OiAnICsgdGhpcy55LnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHo6ICcgKyB0aGlzLnoudG9TdHJpbmcoMTYsIDIpICsgJz4nO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gaXNJbmZpbml0eSgpIHtcbiAgLy8gWFhYIFRoaXMgY29kZSBhc3N1bWVzIHRoYXQgemVybyBpcyBhbHdheXMgemVybyBpbiByZWRcbiAgcmV0dXJuIHRoaXMuei5jbXBuKDApID09PSAwO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1cnZlcyA9IGV4cG9ydHM7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnaGFzaC5qcycpO1xudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vZWxsaXB0aWMnKTtcblxudmFyIGFzc2VydCA9IGVsbGlwdGljLnV0aWxzLmFzc2VydDtcblxuZnVuY3Rpb24gUHJlc2V0Q3VydmUob3B0aW9ucykge1xuICBpZiAob3B0aW9ucy50eXBlID09PSAnc2hvcnQnKVxuICAgIHRoaXMuY3VydmUgPSBuZXcgZWxsaXB0aWMuY3VydmUuc2hvcnQob3B0aW9ucyk7XG4gIGVsc2UgaWYgKG9wdGlvbnMudHlwZSA9PT0gJ2Vkd2FyZHMnKVxuICAgIHRoaXMuY3VydmUgPSBuZXcgZWxsaXB0aWMuY3VydmUuZWR3YXJkcyhvcHRpb25zKTtcbiAgZWxzZVxuICAgIHRoaXMuY3VydmUgPSBuZXcgZWxsaXB0aWMuY3VydmUubW9udChvcHRpb25zKTtcbiAgdGhpcy5nID0gdGhpcy5jdXJ2ZS5nO1xuICB0aGlzLm4gPSB0aGlzLmN1cnZlLm47XG4gIHRoaXMuaGFzaCA9IG9wdGlvbnMuaGFzaDtcblxuICBhc3NlcnQodGhpcy5nLnZhbGlkYXRlKCksICdJbnZhbGlkIGN1cnZlJyk7XG4gIGFzc2VydCh0aGlzLmcubXVsKHRoaXMubikuaXNJbmZpbml0eSgpLCAnSW52YWxpZCBjdXJ2ZSwgRypOICE9IE8nKTtcbn1cbmN1cnZlcy5QcmVzZXRDdXJ2ZSA9IFByZXNldEN1cnZlO1xuXG5mdW5jdGlvbiBkZWZpbmVDdXJ2ZShuYW1lLCBvcHRpb25zKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdXJ2ZXMsIG5hbWUsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGN1cnZlID0gbmV3IFByZXNldEN1cnZlKG9wdGlvbnMpO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN1cnZlcywgbmFtZSwge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIHZhbHVlOiBjdXJ2ZVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gY3VydmU7XG4gICAgfVxuICB9KTtcbn1cblxuZGVmaW5lQ3VydmUoJ3AxOTInLCB7XG4gIHR5cGU6ICdzaG9ydCcsXG4gIHByaW1lOiAncDE5MicsXG4gIHA6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBmZmZmZmZmZiBmZmZmZmZmZicsXG4gIGE6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBmZmZmZmZmZiBmZmZmZmZmYycsXG4gIGI6ICc2NDIxMDUxOSBlNTljODBlNyAwZmE3ZTlhYiA3MjI0MzA0OSBmZWI4ZGVlYyBjMTQ2YjliMScsXG4gIG46ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiA5OWRlZjgzNiAxNDZiYzliMSBiNGQyMjgzMScsXG4gIGhhc2g6IGhhc2guc2hhMjU2LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICcxODhkYTgwZSBiMDMwOTBmNiA3Y2JmMjBlYiA0M2ExODgwMCBmNGZmMGFmZCA4MmZmMTAxMicsXG4gICAgJzA3MTkyYjk1IGZmYzhkYTc4IDYzMTAxMWVkIDZiMjRjZGQ1IDczZjk3N2ExIDFlNzk0ODExJ1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ3AyMjQnLCB7XG4gIHR5cGU6ICdzaG9ydCcsXG4gIHByaW1lOiAncDIyNCcsXG4gIHA6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAwMDAwMDAwMCAwMDAwMDAwMCAwMDAwMDAwMScsXG4gIGE6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZScsXG4gIGI6ICdiNDA1MGE4NSAwYzA0YjNhYiBmNTQxMzI1NiA1MDQ0YjBiNyBkN2JmZDhiYSAyNzBiMzk0MyAyMzU1ZmZiNCcsXG4gIG46ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmMTZhMiBlMGI4ZjAzZSAxM2RkMjk0NSA1YzVjMmEzZCcsXG4gIGhhc2g6IGhhc2guc2hhMjU2LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICdiNzBlMGNiZCA2YmI0YmY3ZiAzMjEzOTBiOSA0YTAzYzFkMyA1NmMyMTEyMiAzNDMyODBkNiAxMTVjMWQyMScsXG4gICAgJ2JkMzc2Mzg4IGI1ZjcyM2ZiIDRjMjJkZmU2IGNkNDM3NWEwIDVhMDc0NzY0IDQ0ZDU4MTk5IDg1MDA3ZTM0J1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ3AyNTYnLCB7XG4gIHR5cGU6ICdzaG9ydCcsXG4gIHByaW1lOiBudWxsLFxuICBwOiAnZmZmZmZmZmYgMDAwMDAwMDEgMDAwMDAwMDAgMDAwMDAwMDAgMDAwMDAwMDAgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYnLFxuICBhOiAnZmZmZmZmZmYgMDAwMDAwMDEgMDAwMDAwMDAgMDAwMDAwMDAgMDAwMDAwMDAgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmMnLFxuICBiOiAnNWFjNjM1ZDggYWEzYTkzZTcgYjNlYmJkNTUgNzY5ODg2YmMgNjUxZDA2YjAgY2M1M2IwZjYgM2JjZTNjM2UgMjdkMjYwNGInLFxuICBuOiAnZmZmZmZmZmYgMDAwMDAwMDAgZmZmZmZmZmYgZmZmZmZmZmYgYmNlNmZhYWQgYTcxNzllODQgZjNiOWNhYzIgZmM2MzI1NTEnLFxuICBoYXNoOiBoYXNoLnNoYTI1NixcbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnNmIxN2QxZjIgZTEyYzQyNDcgZjhiY2U2ZTUgNjNhNDQwZjIgNzcwMzdkODEgMmRlYjMzYTAgZjRhMTM5NDUgZDg5OGMyOTYnLFxuICAgICc0ZmUzNDJlMiBmZTFhN2Y5YiA4ZWU3ZWI0YSA3YzBmOWUxNiAyYmNlMzM1NyA2YjMxNWVjZSBjYmI2NDA2OCAzN2JmNTFmNSdcbiAgXVxufSk7XG5cbmRlZmluZUN1cnZlKCdwMzg0Jywge1xuICB0eXBlOiAnc2hvcnQnLFxuICBwcmltZTogbnVsbCxcbiAgcDogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmICcgK1xuICAgICAnZmZmZmZmZmUgZmZmZmZmZmYgMDAwMDAwMDAgMDAwMDAwMDAgZmZmZmZmZmYnLFxuICBhOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZSBmZmZmZmZmZiAwMDAwMDAwMCAwMDAwMDAwMCBmZmZmZmZmYycsXG4gIGI6ICdiMzMxMmZhNyBlMjNlZTdlNCA5ODhlMDU2YiBlM2Y4MmQxOSAxODFkOWM2ZSBmZTgxNDExMiAwMzE0MDg4ZiAnICtcbiAgICAgJzUwMTM4NzVhIGM2NTYzOThkIDhhMmVkMTlkIDJhODVjOGVkIGQzZWMyYWVmJyxcbiAgbjogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGM3NjM0ZDgxICcgK1xuICAgICAnZjQzNzJkZGYgNTgxYTBkYjIgNDhiMGE3N2EgZWNlYzE5NmEgY2NjNTI5NzMnLFxuICBoYXNoOiBoYXNoLnNoYTM4NCxcbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnYWE4N2NhMjIgYmU4YjA1MzcgOGViMWM3MWUgZjMyMGFkNzQgNmUxZDNiNjIgOGJhNzliOTggNTlmNzQxZTAgODI1NDJhMzggJyArXG4gICAgJzU1MDJmMjVkIGJmNTUyOTZjIDNhNTQ1ZTM4IDcyNzYwYWI3JyxcbiAgICAnMzYxN2RlNGEgOTYyNjJjNmYgNWQ5ZTk4YmYgOTI5MmRjMjkgZjhmNDFkYmQgMjg5YTE0N2MgZTlkYTMxMTMgYjVmMGI4YzAgJyArXG4gICAgJzBhNjBiMWNlIDFkN2U4MTlkIDdhNDMxZDdjIDkwZWEwZTVmJ1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ3A1MjEnLCB7XG4gIHR5cGU6ICdzaG9ydCcsXG4gIHByaW1lOiBudWxsLFxuICBwOiAnMDAwMDAxZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmJyxcbiAgYTogJzAwMDAwMWZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmICcgK1xuICAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmYycsXG4gIGI6ICcwMDAwMDA1MSA5NTNlYjk2MSA4ZTFjOWExZiA5MjlhMjFhMCBiNjg1NDBlZSBhMmRhNzI1YiAnICtcbiAgICAgJzk5YjMxNWYzIGI4YjQ4OTkxIDhlZjEwOWUxIDU2MTkzOTUxIGVjN2U5MzdiIDE2NTJjMGJkICcgK1xuICAgICAnM2JiMWJmMDcgMzU3M2RmODggM2QyYzM0ZjEgZWY0NTFmZDQgNmI1MDNmMDAnLFxuICBuOiAnMDAwMDAxZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmYSA1MTg2ODc4MyBiZjJmOTY2YiA3ZmNjMDE0OCAnICtcbiAgICAgJ2Y3MDlhNWQwIDNiYjVjOWI4IDg5OWM0N2FlIGJiNmZiNzFlIDkxMzg2NDA5JyxcbiAgaGFzaDogaGFzaC5zaGE1MTIsXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJzAwMDAwMGM2IDg1OGUwNmI3IDA0MDRlOWNkIDllM2VjYjY2IDIzOTViNDQyIDljNjQ4MTM5ICcgK1xuICAgICcwNTNmYjUyMSBmODI4YWY2MCA2YjRkM2RiYSBhMTRiNWU3NyBlZmU3NTkyOCBmZTFkYzEyNyAnICtcbiAgICAnYTJmZmE4ZGUgMzM0OGIzYzEgODU2YTQyOWIgZjk3ZTdlMzEgYzJlNWJkNjYnLFxuICAgICcwMDAwMDExOCAzOTI5NmE3OCA5YTNiYzAwNCA1YzhhNWZiNCAyYzdkMWJkOSA5OGY1NDQ0OSAnICtcbiAgICAnNTc5YjQ0NjggMTdhZmJkMTcgMjczZTY2MmMgOTdlZTcyOTkgNWVmNDI2NDAgYzU1MGI5MDEgJyArXG4gICAgJzNmYWQwNzYxIDM1M2M3MDg2IGEyNzJjMjQwIDg4YmU5NDc2IDlmZDE2NjUwJ1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ2N1cnZlMjU1MTknLCB7XG4gIHR5cGU6ICdtb250JyxcbiAgcHJpbWU6ICdwMjU1MTknLFxuICBwOiAnN2ZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZlZCcsXG4gIGE6ICc3NmQwNicsXG4gIGI6ICcwJyxcbiAgbjogJzEwMDAwMDAwMDAwMDAwMDAgMDAwMDAwMDAwMDAwMDAwMCAxNGRlZjlkZWEyZjc5Y2Q2IDU4MTI2MzFhNWNmNWQzZWQnLFxuICBoYXNoOiBoYXNoLnNoYTI1NixcbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnOSdcbiAgXVxufSk7XG5cbmRlZmluZUN1cnZlKCdlZDI1NTE5Jywge1xuICB0eXBlOiAnZWR3YXJkcycsXG4gIHByaW1lOiAncDI1NTE5JyxcbiAgcDogJzdmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZWQnLFxuICBhOiAnLTEnLFxuICBjOiAnMScsXG4gIC8vIC0xMjE2NjUgKiAoMTIxNjY2XigtMSkpIChtb2QgUClcbiAgZDogJzUyMDM2Y2VlMmI2ZmZlNzMgOGNjNzQwNzk3Nzc5ZTg5OCAwMDcwMGE0ZDQxNDFkOGFiIDc1ZWI0ZGNhMTM1OTc4YTMnLFxuICBuOiAnMTAwMDAwMDAwMDAwMDAwMCAwMDAwMDAwMDAwMDAwMDAwIDE0ZGVmOWRlYTJmNzljZDYgNTgxMjYzMWE1Y2Y1ZDNlZCcsXG4gIGhhc2g6IGhhc2guc2hhMjU2LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICcyMTY5MzZkM2NkNmU1M2ZlYzBhNGUyMzFmZGQ2ZGM1YzY5MmNjNzYwOTUyNWE3YjJjOTU2MmQ2MDhmMjVkNTFhJyxcblxuICAgIC8vIDQvNVxuICAgICc2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjU4J1xuICBdXG59KTtcblxudmFyIHByZTtcbnRyeSB7XG4gIHByZSA9IHJlcXVpcmUoJy4vcHJlY29tcHV0ZWQvc2VjcDI1NmsxJyk7XG59IGNhdGNoIChlKSB7XG4gIHByZSA9IHVuZGVmaW5lZDtcbn1cblxuZGVmaW5lQ3VydmUoJ3NlY3AyNTZrMScsIHtcbiAgdHlwZTogJ3Nob3J0JyxcbiAgcHJpbWU6ICdrMjU2JyxcbiAgcDogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmYzJmJyxcbiAgYTogJzAnLFxuICBiOiAnNycsXG4gIG46ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBiYWFlZGNlNiBhZjQ4YTAzYiBiZmQyNWU4YyBkMDM2NDE0MScsXG4gIGg6ICcxJyxcbiAgaGFzaDogaGFzaC5zaGEyNTYsXG5cbiAgLy8gUHJlY29tcHV0ZWQgZW5kb21vcnBoaXNtXG4gIGJldGE6ICc3YWU5NmEyYjY1N2MwNzEwNmU2NDQ3OWVhYzM0MzRlOTljZjA0OTc1MTJmNTg5OTVjMTM5NmMyODcxOTUwMWVlJyxcbiAgbGFtYmRhOiAnNTM2M2FkNGNjMDVjMzBlMGE1MjYxYzAyODgxMjY0NWExMjJlMjJlYTIwODE2Njc4ZGYwMjk2N2MxYjIzYmQ3MicsXG4gIGJhc2lzOiBbXG4gICAge1xuICAgICAgYTogJzMwODZkMjIxYTdkNDZiY2RlODZjOTBlNDkyODRlYjE1JyxcbiAgICAgIGI6ICctZTQ0MzdlZDYwMTBlODgyODZmNTQ3ZmE5MGFiZmU0YzMnXG4gICAgfSxcbiAgICB7XG4gICAgICBhOiAnMTE0Y2E1MGY3YThlMmYzZjY1N2MxMTA4ZDlkNDRjZmQ4JyxcbiAgICAgIGI6ICczMDg2ZDIyMWE3ZDQ2YmNkZTg2YzkwZTQ5Mjg0ZWIxNSdcbiAgICB9XG4gIF0sXG5cbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnNzliZTY2N2VmOWRjYmJhYzU1YTA2Mjk1Y2U4NzBiMDcwMjliZmNkYjJkY2UyOGQ5NTlmMjgxNWIxNmY4MTc5OCcsXG4gICAgJzQ4M2FkYTc3MjZhM2M0NjU1ZGE0ZmJmYzBlMTEwOGE4ZmQxN2I0NDhhNjg1NTQxOTljNDdkMDhmZmIxMGQ0YjgnLFxuICAgIHByZVxuICBdXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgdXRpbHMgPSBlbGxpcHRpYy51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbnZhciBLZXlQYWlyID0gcmVxdWlyZSgnLi9rZXknKTtcbnZhciBTaWduYXR1cmUgPSByZXF1aXJlKCcuL3NpZ25hdHVyZScpO1xuXG5mdW5jdGlvbiBFQyhvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBFQykpXG4gICAgcmV0dXJuIG5ldyBFQyhvcHRpb25zKTtcblxuICAvLyBTaG9ydGN1dCBgZWxsaXB0aWMuZWMoY3VydmUtbmFtZSlgXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHtcbiAgICBhc3NlcnQoZWxsaXB0aWMuY3VydmVzLmhhc093blByb3BlcnR5KG9wdGlvbnMpLCAnVW5rbm93biBjdXJ2ZSAnICsgb3B0aW9ucyk7XG5cbiAgICBvcHRpb25zID0gZWxsaXB0aWMuY3VydmVzW29wdGlvbnNdO1xuICB9XG5cbiAgLy8gU2hvcnRjdXQgZm9yIGBlbGxpcHRpYy5lYyhlbGxpcHRpYy5jdXJ2ZXMuY3VydmVOYW1lKWBcbiAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBlbGxpcHRpYy5jdXJ2ZXMuUHJlc2V0Q3VydmUpXG4gICAgb3B0aW9ucyA9IHsgY3VydmU6IG9wdGlvbnMgfTtcblxuICB0aGlzLmN1cnZlID0gb3B0aW9ucy5jdXJ2ZS5jdXJ2ZTtcbiAgdGhpcy5uID0gdGhpcy5jdXJ2ZS5uO1xuICB0aGlzLm5oID0gdGhpcy5uLnVzaHJuKDEpO1xuICB0aGlzLmcgPSB0aGlzLmN1cnZlLmc7XG5cbiAgLy8gUG9pbnQgb24gY3VydmVcbiAgdGhpcy5nID0gb3B0aW9ucy5jdXJ2ZS5nO1xuICB0aGlzLmcucHJlY29tcHV0ZShvcHRpb25zLmN1cnZlLm4uYml0TGVuZ3RoKCkgKyAxKTtcblxuICAvLyBIYXNoIGZvciBmdW5jdGlvbiBmb3IgRFJCR1xuICB0aGlzLmhhc2ggPSBvcHRpb25zLmhhc2ggfHwgb3B0aW9ucy5jdXJ2ZS5oYXNoO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFQztcblxuRUMucHJvdG90eXBlLmtleVBhaXIgPSBmdW5jdGlvbiBrZXlQYWlyKG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBLZXlQYWlyKHRoaXMsIG9wdGlvbnMpO1xufTtcblxuRUMucHJvdG90eXBlLmtleUZyb21Qcml2YXRlID0gZnVuY3Rpb24ga2V5RnJvbVByaXZhdGUocHJpdiwgZW5jKSB7XG4gIHJldHVybiBLZXlQYWlyLmZyb21Qcml2YXRlKHRoaXMsIHByaXYsIGVuYyk7XG59O1xuXG5FQy5wcm90b3R5cGUua2V5RnJvbVB1YmxpYyA9IGZ1bmN0aW9uIGtleUZyb21QdWJsaWMocHViLCBlbmMpIHtcbiAgcmV0dXJuIEtleVBhaXIuZnJvbVB1YmxpYyh0aGlzLCBwdWIsIGVuYyk7XG59O1xuXG5FQy5wcm90b3R5cGUuZ2VuS2V5UGFpciA9IGZ1bmN0aW9uIGdlbktleVBhaXIob3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpXG4gICAgb3B0aW9ucyA9IHt9O1xuXG4gIC8vIEluc3RhbnRpYXRlIEhtYWNfRFJCR1xuICB2YXIgZHJiZyA9IG5ldyBlbGxpcHRpYy5obWFjRFJCRyh7XG4gICAgaGFzaDogdGhpcy5oYXNoLFxuICAgIHBlcnM6IG9wdGlvbnMucGVycyxcbiAgICBlbnRyb3B5OiBvcHRpb25zLmVudHJvcHkgfHwgZWxsaXB0aWMucmFuZCh0aGlzLmhhc2guaG1hY1N0cmVuZ3RoKSxcbiAgICBub25jZTogdGhpcy5uLnRvQXJyYXkoKVxuICB9KTtcblxuICB2YXIgYnl0ZXMgPSB0aGlzLm4uYnl0ZUxlbmd0aCgpO1xuICB2YXIgbnMyID0gdGhpcy5uLnN1YihuZXcgQk4oMikpO1xuICBkbyB7XG4gICAgdmFyIHByaXYgPSBuZXcgQk4oZHJiZy5nZW5lcmF0ZShieXRlcykpO1xuICAgIGlmIChwcml2LmNtcChuczIpID4gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgcHJpdi5pYWRkbigxKTtcbiAgICByZXR1cm4gdGhpcy5rZXlGcm9tUHJpdmF0ZShwcml2KTtcbiAgfSB3aGlsZSAodHJ1ZSk7XG59O1xuXG5FQy5wcm90b3R5cGUuX3RydW5jYXRlVG9OID0gZnVuY3Rpb24gdHJ1bmNhdGVUb04obXNnLCB0cnVuY09ubHkpIHtcbiAgdmFyIGRlbHRhID0gbXNnLmJ5dGVMZW5ndGgoKSAqIDggLSB0aGlzLm4uYml0TGVuZ3RoKCk7XG4gIGlmIChkZWx0YSA+IDApXG4gICAgbXNnID0gbXNnLnVzaHJuKGRlbHRhKTtcbiAgaWYgKCF0cnVuY09ubHkgJiYgbXNnLmNtcCh0aGlzLm4pID49IDApXG4gICAgcmV0dXJuIG1zZy5zdWIodGhpcy5uKTtcbiAgZWxzZVxuICAgIHJldHVybiBtc2c7XG59O1xuXG5FQy5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24obXNnLCBrZXksIGVuYywgb3B0aW9ucykge1xuICBpZiAodHlwZW9mIGVuYyA9PT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0gZW5jO1xuICAgIGVuYyA9IG51bGw7XG4gIH1cbiAgaWYgKCFvcHRpb25zKVxuICAgIG9wdGlvbnMgPSB7fTtcblxuICBrZXkgPSB0aGlzLmtleUZyb21Qcml2YXRlKGtleSwgZW5jKTtcbiAgbXNnID0gdGhpcy5fdHJ1bmNhdGVUb04obmV3IEJOKG1zZywgMTYpKTtcblxuICAvLyBaZXJvLWV4dGVuZCBrZXkgdG8gcHJvdmlkZSBlbm91Z2ggZW50cm9weVxuICB2YXIgYnl0ZXMgPSB0aGlzLm4uYnl0ZUxlbmd0aCgpO1xuICB2YXIgYmtleSA9IGtleS5nZXRQcml2YXRlKCkudG9BcnJheSgnYmUnLCBieXRlcyk7XG5cbiAgLy8gWmVyby1leHRlbmQgbm9uY2UgdG8gaGF2ZSB0aGUgc2FtZSBieXRlIHNpemUgYXMgTlxuICB2YXIgbm9uY2UgPSBtc2cudG9BcnJheSgnYmUnLCBieXRlcyk7XG5cbiAgLy8gSW5zdGFudGlhdGUgSG1hY19EUkJHXG4gIHZhciBkcmJnID0gbmV3IGVsbGlwdGljLmhtYWNEUkJHKHtcbiAgICBoYXNoOiB0aGlzLmhhc2gsXG4gICAgZW50cm9weTogYmtleSxcbiAgICBub25jZTogbm9uY2UsXG4gICAgcGVyczogb3B0aW9ucy5wZXJzLFxuICAgIHBlcnNFbmM6IG9wdGlvbnMucGVyc0VuY1xuICB9KTtcblxuICAvLyBOdW1iZXIgb2YgYnl0ZXMgdG8gZ2VuZXJhdGVcbiAgdmFyIG5zMSA9IHRoaXMubi5zdWIobmV3IEJOKDEpKTtcblxuICBmb3IgKHZhciBpdGVyID0gMDsgdHJ1ZTsgaXRlcisrKSB7XG4gICAgdmFyIGsgPSBvcHRpb25zLmsgP1xuICAgICAgICBvcHRpb25zLmsoaXRlcikgOlxuICAgICAgICBuZXcgQk4oZHJiZy5nZW5lcmF0ZSh0aGlzLm4uYnl0ZUxlbmd0aCgpKSk7XG4gICAgayA9IHRoaXMuX3RydW5jYXRlVG9OKGssIHRydWUpO1xuICAgIGlmIChrLmNtcG4oMSkgPD0gMCB8fCBrLmNtcChuczEpID49IDApXG4gICAgICBjb250aW51ZTtcblxuICAgIHZhciBrcCA9IHRoaXMuZy5tdWwoayk7XG4gICAgaWYgKGtwLmlzSW5maW5pdHkoKSlcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgdmFyIGtwWCA9IGtwLmdldFgoKTtcbiAgICB2YXIgciA9IGtwWC51bW9kKHRoaXMubik7XG4gICAgaWYgKHIuY21wbigwKSA9PT0gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgdmFyIHMgPSBrLmludm0odGhpcy5uKS5tdWwoci5tdWwoa2V5LmdldFByaXZhdGUoKSkuaWFkZChtc2cpKTtcbiAgICBzID0gcy51bW9kKHRoaXMubik7XG4gICAgaWYgKHMuY21wbigwKSA9PT0gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgdmFyIHJlY292ZXJ5UGFyYW0gPSAoa3AuZ2V0WSgpLmlzT2RkKCkgPyAxIDogMCkgfFxuICAgICAgICAgICAgICAgICAgICAgICAgKGtwWC5jbXAocikgIT09IDAgPyAyIDogMCk7XG5cbiAgICAvLyBVc2UgY29tcGxlbWVudCBvZiBgc2AsIGlmIGl0IGlzID4gYG4gLyAyYFxuICAgIGlmIChvcHRpb25zLmNhbm9uaWNhbCAmJiBzLmNtcCh0aGlzLm5oKSA+IDApIHtcbiAgICAgIHMgPSB0aGlzLm4uc3ViKHMpO1xuICAgICAgcmVjb3ZlcnlQYXJhbSBePSAxO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgU2lnbmF0dXJlKHsgcjogciwgczogcywgcmVjb3ZlcnlQYXJhbTogcmVjb3ZlcnlQYXJhbSB9KTtcbiAgfVxufTtcblxuRUMucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtc2csIHNpZ25hdHVyZSwga2V5LCBlbmMpIHtcbiAgbXNnID0gdGhpcy5fdHJ1bmNhdGVUb04obmV3IEJOKG1zZywgMTYpKTtcbiAga2V5ID0gdGhpcy5rZXlGcm9tUHVibGljKGtleSwgZW5jKTtcbiAgc2lnbmF0dXJlID0gbmV3IFNpZ25hdHVyZShzaWduYXR1cmUsICdoZXgnKTtcblxuICAvLyBQZXJmb3JtIHByaW1pdGl2ZSB2YWx1ZXMgdmFsaWRhdGlvblxuICB2YXIgciA9IHNpZ25hdHVyZS5yO1xuICB2YXIgcyA9IHNpZ25hdHVyZS5zO1xuICBpZiAoci5jbXBuKDEpIDwgMCB8fCByLmNtcCh0aGlzLm4pID49IDApXG4gICAgcmV0dXJuIGZhbHNlO1xuICBpZiAocy5jbXBuKDEpIDwgMCB8fCBzLmNtcCh0aGlzLm4pID49IDApXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIFZhbGlkYXRlIHNpZ25hdHVyZVxuICB2YXIgc2ludiA9IHMuaW52bSh0aGlzLm4pO1xuICB2YXIgdTEgPSBzaW52Lm11bChtc2cpLnVtb2QodGhpcy5uKTtcbiAgdmFyIHUyID0gc2ludi5tdWwocikudW1vZCh0aGlzLm4pO1xuXG4gIHZhciBwID0gdGhpcy5nLm11bEFkZCh1MSwga2V5LmdldFB1YmxpYygpLCB1Mik7XG4gIGlmIChwLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIHAuZ2V0WCgpLnVtb2QodGhpcy5uKS5jbXAocikgPT09IDA7XG59O1xuXG5FQy5wcm90b3R5cGUucmVjb3ZlclB1YktleSA9IGZ1bmN0aW9uKG1zZywgc2lnbmF0dXJlLCBqLCBlbmMpIHtcbiAgYXNzZXJ0KCgzICYgaikgPT09IGosICdUaGUgcmVjb3ZlcnkgcGFyYW0gaXMgbW9yZSB0aGFuIHR3byBiaXRzJyk7XG4gIHNpZ25hdHVyZSA9IG5ldyBTaWduYXR1cmUoc2lnbmF0dXJlLCBlbmMpO1xuXG4gIHZhciBuID0gdGhpcy5uO1xuICB2YXIgZSA9IG5ldyBCTihtc2cpO1xuICB2YXIgciA9IHNpZ25hdHVyZS5yO1xuICB2YXIgcyA9IHNpZ25hdHVyZS5zO1xuXG4gIC8vIEEgc2V0IExTQiBzaWduaWZpZXMgdGhhdCB0aGUgeS1jb29yZGluYXRlIGlzIG9kZFxuICB2YXIgaXNZT2RkID0gaiAmIDE7XG4gIHZhciBpc1NlY29uZEtleSA9IGogPj4gMTtcbiAgaWYgKHIuY21wKHRoaXMuY3VydmUucC51bW9kKHRoaXMuY3VydmUubikpID49IDAgJiYgaXNTZWNvbmRLZXkpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBzZW5jb25kIGtleSBjYW5kaW5hdGUnKTtcblxuICAvLyAxLjEuIExldCB4ID0gciArIGpuLlxuICBpZiAoaXNTZWNvbmRLZXkpXG4gICAgciA9IHRoaXMuY3VydmUucG9pbnRGcm9tWChyLmFkZCh0aGlzLmN1cnZlLm4pLCBpc1lPZGQpO1xuICBlbHNlXG4gICAgciA9IHRoaXMuY3VydmUucG9pbnRGcm9tWChyLCBpc1lPZGQpO1xuXG4gIHZhciBlTmVnID0gbi5zdWIoZSk7XG5cbiAgLy8gMS42LjEgQ29tcHV0ZSBRID0gcl4tMSAoc1IgLSAgZUcpXG4gIC8vICAgICAgICAgICAgICAgUSA9IHJeLTEgKHNSICsgLWVHKVxuICB2YXIgckludiA9IHNpZ25hdHVyZS5yLmludm0obik7XG4gIHJldHVybiB0aGlzLmcubXVsQWRkKGVOZWcsIHIsIHMpLm11bChySW52KTtcbn07XG5cbkVDLnByb3RvdHlwZS5nZXRLZXlSZWNvdmVyeVBhcmFtID0gZnVuY3Rpb24oZSwgc2lnbmF0dXJlLCBRLCBlbmMpIHtcbiAgc2lnbmF0dXJlID0gbmV3IFNpZ25hdHVyZShzaWduYXR1cmUsIGVuYyk7XG4gIGlmIChzaWduYXR1cmUucmVjb3ZlcnlQYXJhbSAhPT0gbnVsbClcbiAgICByZXR1cm4gc2lnbmF0dXJlLnJlY292ZXJ5UGFyYW07XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICB2YXIgUXByaW1lO1xuICAgIHRyeSB7XG4gICAgICBRcHJpbWUgPSB0aGlzLnJlY292ZXJQdWJLZXkoZSwgc2lnbmF0dXJlLCBpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoUXByaW1lLmVxKFEpKVxuICAgICAgcmV0dXJuIGk7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCB2YWxpZCByZWNvdmVyeSBmYWN0b3InKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG5cbmZ1bmN0aW9uIEtleVBhaXIoZWMsIG9wdGlvbnMpIHtcbiAgdGhpcy5lYyA9IGVjO1xuICB0aGlzLnByaXYgPSBudWxsO1xuICB0aGlzLnB1YiA9IG51bGw7XG5cbiAgLy8gS2V5UGFpcihlYywgeyBwcml2OiAuLi4sIHB1YjogLi4uIH0pXG4gIGlmIChvcHRpb25zLnByaXYpXG4gICAgdGhpcy5faW1wb3J0UHJpdmF0ZShvcHRpb25zLnByaXYsIG9wdGlvbnMucHJpdkVuYyk7XG4gIGlmIChvcHRpb25zLnB1YilcbiAgICB0aGlzLl9pbXBvcnRQdWJsaWMob3B0aW9ucy5wdWIsIG9wdGlvbnMucHViRW5jKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gS2V5UGFpcjtcblxuS2V5UGFpci5mcm9tUHVibGljID0gZnVuY3Rpb24gZnJvbVB1YmxpYyhlYywgcHViLCBlbmMpIHtcbiAgaWYgKHB1YiBpbnN0YW5jZW9mIEtleVBhaXIpXG4gICAgcmV0dXJuIHB1YjtcblxuICByZXR1cm4gbmV3IEtleVBhaXIoZWMsIHtcbiAgICBwdWI6IHB1YixcbiAgICBwdWJFbmM6IGVuY1xuICB9KTtcbn07XG5cbktleVBhaXIuZnJvbVByaXZhdGUgPSBmdW5jdGlvbiBmcm9tUHJpdmF0ZShlYywgcHJpdiwgZW5jKSB7XG4gIGlmIChwcml2IGluc3RhbmNlb2YgS2V5UGFpcilcbiAgICByZXR1cm4gcHJpdjtcblxuICByZXR1cm4gbmV3IEtleVBhaXIoZWMsIHtcbiAgICBwcml2OiBwcml2LFxuICAgIHByaXZFbmM6IGVuY1xuICB9KTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gdmFsaWRhdGUoKSB7XG4gIHZhciBwdWIgPSB0aGlzLmdldFB1YmxpYygpO1xuXG4gIGlmIChwdWIuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIHJlYXNvbjogJ0ludmFsaWQgcHVibGljIGtleScgfTtcbiAgaWYgKCFwdWIudmFsaWRhdGUoKSlcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCByZWFzb246ICdQdWJsaWMga2V5IGlzIG5vdCBhIHBvaW50JyB9O1xuICBpZiAoIXB1Yi5tdWwodGhpcy5lYy5jdXJ2ZS5uKS5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgcmVhc29uOiAnUHVibGljIGtleSAqIE4gIT0gTycgfTtcblxuICByZXR1cm4geyByZXN1bHQ6IHRydWUsIHJlYXNvbjogbnVsbCB9O1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUuZ2V0UHVibGljID0gZnVuY3Rpb24gZ2V0UHVibGljKGNvbXBhY3QsIGVuYykge1xuICAvLyBjb21wYWN0IGlzIG9wdGlvbmFsIGFyZ3VtZW50XG4gIGlmICh0eXBlb2YgY29tcGFjdCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmMgPSBjb21wYWN0O1xuICAgIGNvbXBhY3QgPSBudWxsO1xuICB9XG5cbiAgaWYgKCF0aGlzLnB1YilcbiAgICB0aGlzLnB1YiA9IHRoaXMuZWMuZy5tdWwodGhpcy5wcml2KTtcblxuICBpZiAoIWVuYylcbiAgICByZXR1cm4gdGhpcy5wdWI7XG5cbiAgcmV0dXJuIHRoaXMucHViLmVuY29kZShlbmMsIGNvbXBhY3QpO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUuZ2V0UHJpdmF0ZSA9IGZ1bmN0aW9uIGdldFByaXZhdGUoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB0aGlzLnByaXYudG9TdHJpbmcoMTYsIDIpO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMucHJpdjtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLl9pbXBvcnRQcml2YXRlID0gZnVuY3Rpb24gX2ltcG9ydFByaXZhdGUoa2V5LCBlbmMpIHtcbiAgdGhpcy5wcml2ID0gbmV3IEJOKGtleSwgZW5jIHx8IDE2KTtcblxuICAvLyBFbnN1cmUgdGhhdCB0aGUgcHJpdiB3b24ndCBiZSBiaWdnZXIgdGhhbiBuLCBvdGhlcndpc2Ugd2UgbWF5IGZhaWxcbiAgLy8gaW4gZml4ZWQgbXVsdGlwbGljYXRpb24gbWV0aG9kXG4gIHRoaXMucHJpdiA9IHRoaXMucHJpdi51bW9kKHRoaXMuZWMuY3VydmUubik7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5faW1wb3J0UHVibGljID0gZnVuY3Rpb24gX2ltcG9ydFB1YmxpYyhrZXksIGVuYykge1xuICBpZiAoa2V5LnggfHwga2V5LnkpIHtcbiAgICB0aGlzLnB1YiA9IHRoaXMuZWMuY3VydmUucG9pbnQoa2V5LngsIGtleS55KTtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5wdWIgPSB0aGlzLmVjLmN1cnZlLmRlY29kZVBvaW50KGtleSwgZW5jKTtcbn07XG5cbi8vIEVDREhcbktleVBhaXIucHJvdG90eXBlLmRlcml2ZSA9IGZ1bmN0aW9uIGRlcml2ZShwdWIpIHtcbiAgcmV0dXJuIHB1Yi5tdWwodGhpcy5wcml2KS5nZXRYKCk7XG59O1xuXG4vLyBFQ0RTQVxuS2V5UGFpci5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24obXNnLCBlbmMsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHRoaXMuZWMuc2lnbihtc2csIHRoaXMsIGVuYywgb3B0aW9ucyk7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobXNnLCBzaWduYXR1cmUpIHtcbiAgcmV0dXJuIHRoaXMuZWMudmVyaWZ5KG1zZywgc2lnbmF0dXJlLCB0aGlzKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICByZXR1cm4gJzxLZXkgcHJpdjogJyArICh0aGlzLnByaXYgJiYgdGhpcy5wcml2LnRvU3RyaW5nKDE2LCAyKSkgK1xuICAgICAgICAgJyBwdWI6ICcgKyAodGhpcy5wdWIgJiYgdGhpcy5wdWIuaW5zcGVjdCgpKSArICcgPic7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xuXG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBTaWduYXR1cmUob3B0aW9ucywgZW5jKSB7XG4gIGlmIChvcHRpb25zIGluc3RhbmNlb2YgU2lnbmF0dXJlKVxuICAgIHJldHVybiBvcHRpb25zO1xuXG4gIGlmICh0aGlzLl9pbXBvcnRERVIob3B0aW9ucywgZW5jKSlcbiAgICByZXR1cm47XG5cbiAgYXNzZXJ0KG9wdGlvbnMuciAmJiBvcHRpb25zLnMsICdTaWduYXR1cmUgd2l0aG91dCByIG9yIHMnKTtcbiAgdGhpcy5yID0gbmV3IEJOKG9wdGlvbnMuciwgMTYpO1xuICB0aGlzLnMgPSBuZXcgQk4ob3B0aW9ucy5zLCAxNik7XG4gIGlmIChvcHRpb25zLnJlY292ZXJ5UGFyYW0gPT09IHVuZGVmaW5lZClcbiAgICB0aGlzLnJlY292ZXJ5UGFyYW0gPSBudWxsO1xuICBlbHNlXG4gICAgdGhpcy5yZWNvdmVyeVBhcmFtID0gb3B0aW9ucy5yZWNvdmVyeVBhcmFtO1xufVxubW9kdWxlLmV4cG9ydHMgPSBTaWduYXR1cmU7XG5cbmZ1bmN0aW9uIFBvc2l0aW9uKCkge1xuICB0aGlzLnBsYWNlID0gMDtcbn1cblxuZnVuY3Rpb24gZ2V0TGVuZ3RoKGJ1ZiwgcCkge1xuICB2YXIgaW5pdGlhbCA9IGJ1ZltwLnBsYWNlKytdO1xuICBpZiAoIShpbml0aWFsICYgMHg4MCkpIHtcbiAgICByZXR1cm4gaW5pdGlhbDtcbiAgfVxuICB2YXIgb2N0ZXRMZW4gPSBpbml0aWFsICYgMHhmO1xuICB2YXIgdmFsID0gMDtcbiAgZm9yICh2YXIgaSA9IDAsIG9mZiA9IHAucGxhY2U7IGkgPCBvY3RldExlbjsgaSsrLCBvZmYrKykge1xuICAgIHZhbCA8PD0gODtcbiAgICB2YWwgfD0gYnVmW29mZl07XG4gIH1cbiAgcC5wbGFjZSA9IG9mZjtcbiAgcmV0dXJuIHZhbDtcbn1cblxuZnVuY3Rpb24gcm1QYWRkaW5nKGJ1Zikge1xuICB2YXIgaSA9IDA7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoIC0gMTtcbiAgd2hpbGUgKCFidWZbaV0gJiYgIShidWZbaSArIDFdICYgMHg4MCkgJiYgaSA8IGxlbikge1xuICAgIGkrKztcbiAgfVxuICBpZiAoaSA9PT0gMCkge1xuICAgIHJldHVybiBidWY7XG4gIH1cbiAgcmV0dXJuIGJ1Zi5zbGljZShpKTtcbn1cblxuU2lnbmF0dXJlLnByb3RvdHlwZS5faW1wb3J0REVSID0gZnVuY3Rpb24gX2ltcG9ydERFUihkYXRhLCBlbmMpIHtcbiAgZGF0YSA9IHV0aWxzLnRvQXJyYXkoZGF0YSwgZW5jKTtcbiAgdmFyIHAgPSBuZXcgUG9zaXRpb24oKTtcbiAgaWYgKGRhdGFbcC5wbGFjZSsrXSAhPT0gMHgzMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgbGVuID0gZ2V0TGVuZ3RoKGRhdGEsIHApO1xuICBpZiAoKGxlbiArIHAucGxhY2UpICE9PSBkYXRhLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZGF0YVtwLnBsYWNlKytdICE9PSAweDAyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBybGVuID0gZ2V0TGVuZ3RoKGRhdGEsIHApO1xuICB2YXIgciA9IGRhdGEuc2xpY2UocC5wbGFjZSwgcmxlbiArIHAucGxhY2UpO1xuICBwLnBsYWNlICs9IHJsZW47XG4gIGlmIChkYXRhW3AucGxhY2UrK10gIT09IDB4MDIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHNsZW4gPSBnZXRMZW5ndGgoZGF0YSwgcCk7XG4gIGlmIChkYXRhLmxlbmd0aCAhPT0gc2xlbiArIHAucGxhY2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHMgPSBkYXRhLnNsaWNlKHAucGxhY2UsIHNsZW4gKyBwLnBsYWNlKTtcbiAgaWYgKHJbMF0gPT09IDAgJiYgKHJbMV0gJiAweDgwKSkge1xuICAgIHIgPSByLnNsaWNlKDEpO1xuICB9XG4gIGlmIChzWzBdID09PSAwICYmIChzWzFdICYgMHg4MCkpIHtcbiAgICBzID0gcy5zbGljZSgxKTtcbiAgfVxuXG4gIHRoaXMuciA9IG5ldyBCTihyKTtcbiAgdGhpcy5zID0gbmV3IEJOKHMpO1xuICB0aGlzLnJlY292ZXJ5UGFyYW0gPSBudWxsO1xuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gY29uc3RydWN0TGVuZ3RoKGFyciwgbGVuKSB7XG4gIGlmIChsZW4gPCAweDgwKSB7XG4gICAgYXJyLnB1c2gobGVuKTtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIG9jdGV0cyA9IDEgKyAoTWF0aC5sb2cobGVuKSAvIE1hdGguTE4yID4+PiAzKTtcbiAgYXJyLnB1c2gob2N0ZXRzIHwgMHg4MCk7XG4gIHdoaWxlICgtLW9jdGV0cykge1xuICAgIGFyci5wdXNoKChsZW4gPj4+IChvY3RldHMgPDwgMykpICYgMHhmZik7XG4gIH1cbiAgYXJyLnB1c2gobGVuKTtcbn1cblxuU2lnbmF0dXJlLnByb3RvdHlwZS50b0RFUiA9IGZ1bmN0aW9uIHRvREVSKGVuYykge1xuICB2YXIgciA9IHRoaXMuci50b0FycmF5KCk7XG4gIHZhciBzID0gdGhpcy5zLnRvQXJyYXkoKTtcblxuICAvLyBQYWQgdmFsdWVzXG4gIGlmIChyWzBdICYgMHg4MClcbiAgICByID0gWyAwIF0uY29uY2F0KHIpO1xuICAvLyBQYWQgdmFsdWVzXG4gIGlmIChzWzBdICYgMHg4MClcbiAgICBzID0gWyAwIF0uY29uY2F0KHMpO1xuXG4gIHIgPSBybVBhZGRpbmcocik7XG4gIHMgPSBybVBhZGRpbmcocyk7XG5cbiAgd2hpbGUgKCFzWzBdICYmICEoc1sxXSAmIDB4ODApKSB7XG4gICAgcyA9IHMuc2xpY2UoMSk7XG4gIH1cbiAgdmFyIGFyciA9IFsgMHgwMiBdO1xuICBjb25zdHJ1Y3RMZW5ndGgoYXJyLCByLmxlbmd0aCk7XG4gIGFyciA9IGFyci5jb25jYXQocik7XG4gIGFyci5wdXNoKDB4MDIpO1xuICBjb25zdHJ1Y3RMZW5ndGgoYXJyLCBzLmxlbmd0aCk7XG4gIHZhciBiYWNrSGFsZiA9IGFyci5jb25jYXQocyk7XG4gIHZhciByZXMgPSBbIDB4MzAgXTtcbiAgY29uc3RydWN0TGVuZ3RoKHJlcywgYmFja0hhbGYubGVuZ3RoKTtcbiAgcmVzID0gcmVzLmNvbmNhdChiYWNrSGFsZik7XG4gIHJldHVybiB1dGlscy5lbmNvZGUocmVzLCBlbmMpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGhhc2ggPSByZXF1aXJlKCdoYXNoLmpzJyk7XG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xudmFyIHBhcnNlQnl0ZXMgPSB1dGlscy5wYXJzZUJ5dGVzO1xudmFyIEtleVBhaXIgPSByZXF1aXJlKCcuL2tleScpO1xudmFyIFNpZ25hdHVyZSA9IHJlcXVpcmUoJy4vc2lnbmF0dXJlJyk7XG5cbmZ1bmN0aW9uIEVERFNBKGN1cnZlKSB7XG4gIGFzc2VydChjdXJ2ZSA9PT0gJ2VkMjU1MTknLCAnb25seSB0ZXN0ZWQgd2l0aCBlZDI1NTE5IHNvIGZhcicpO1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBFRERTQSkpXG4gICAgcmV0dXJuIG5ldyBFRERTQShjdXJ2ZSk7XG5cbiAgdmFyIGN1cnZlID0gZWxsaXB0aWMuY3VydmVzW2N1cnZlXS5jdXJ2ZTtcbiAgdGhpcy5jdXJ2ZSA9IGN1cnZlO1xuICB0aGlzLmcgPSBjdXJ2ZS5nO1xuICB0aGlzLmcucHJlY29tcHV0ZShjdXJ2ZS5uLmJpdExlbmd0aCgpICsgMSk7XG5cbiAgdGhpcy5wb2ludENsYXNzID0gY3VydmUucG9pbnQoKS5jb25zdHJ1Y3RvcjtcbiAgdGhpcy5lbmNvZGluZ0xlbmd0aCA9IE1hdGguY2VpbChjdXJ2ZS5uLmJpdExlbmd0aCgpIC8gOCk7XG4gIHRoaXMuaGFzaCA9IGhhc2guc2hhNTEyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEVERFNBO1xuXG4vKipcbiogQHBhcmFtIHtBcnJheXxTdHJpbmd9IG1lc3NhZ2UgLSBtZXNzYWdlIGJ5dGVzXG4qIEBwYXJhbSB7QXJyYXl8U3RyaW5nfEtleVBhaXJ9IHNlY3JldCAtIHNlY3JldCBieXRlcyBvciBhIGtleXBhaXJcbiogQHJldHVybnMge1NpZ25hdHVyZX0gLSBzaWduYXR1cmVcbiovXG5FRERTQS5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24obWVzc2FnZSwgc2VjcmV0KSB7XG4gIG1lc3NhZ2UgPSBwYXJzZUJ5dGVzKG1lc3NhZ2UpO1xuICB2YXIga2V5ID0gdGhpcy5rZXlGcm9tU2VjcmV0KHNlY3JldCk7XG4gIHZhciByID0gdGhpcy5oYXNoSW50KGtleS5tZXNzYWdlUHJlZml4KCksIG1lc3NhZ2UpO1xuICB2YXIgUiA9IHRoaXMuZy5tdWwocik7XG4gIHZhciBSZW5jb2RlZCA9IHRoaXMuZW5jb2RlUG9pbnQoUik7XG4gIHZhciBzXyA9IHRoaXMuaGFzaEludChSZW5jb2RlZCwga2V5LnB1YkJ5dGVzKCksIG1lc3NhZ2UpXG4gICAgICAgICAgICAgICAubXVsKGtleS5wcml2KCkpO1xuICB2YXIgUyA9IHIuYWRkKHNfKS51bW9kKHRoaXMuY3VydmUubik7XG4gIHJldHVybiB0aGlzLm1ha2VTaWduYXR1cmUoeyBSOiBSLCBTOiBTLCBSZW5jb2RlZDogUmVuY29kZWQgfSk7XG59O1xuXG4vKipcbiogQHBhcmFtIHtBcnJheX0gbWVzc2FnZSAtIG1lc3NhZ2UgYnl0ZXNcbiogQHBhcmFtIHtBcnJheXxTdHJpbmd8U2lnbmF0dXJlfSBzaWcgLSBzaWcgYnl0ZXNcbiogQHBhcmFtIHtBcnJheXxTdHJpbmd8UG9pbnR8S2V5UGFpcn0gcHViIC0gcHVibGljIGtleVxuKiBAcmV0dXJucyB7Qm9vbGVhbn0gLSB0cnVlIGlmIHB1YmxpYyBrZXkgbWF0Y2hlcyBzaWcgb2YgbWVzc2FnZVxuKi9cbkVERFNBLnByb3RvdHlwZS52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSwgc2lnLCBwdWIpIHtcbiAgbWVzc2FnZSA9IHBhcnNlQnl0ZXMobWVzc2FnZSk7XG4gIHNpZyA9IHRoaXMubWFrZVNpZ25hdHVyZShzaWcpO1xuICB2YXIga2V5ID0gdGhpcy5rZXlGcm9tUHVibGljKHB1Yik7XG4gIHZhciBoID0gdGhpcy5oYXNoSW50KHNpZy5SZW5jb2RlZCgpLCBrZXkucHViQnl0ZXMoKSwgbWVzc2FnZSk7XG4gIHZhciBTRyA9IHRoaXMuZy5tdWwoc2lnLlMoKSk7XG4gIHZhciBScGx1c0FoID0gc2lnLlIoKS5hZGQoa2V5LnB1YigpLm11bChoKSk7XG4gIHJldHVybiBScGx1c0FoLmVxKFNHKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5oYXNoSW50ID0gZnVuY3Rpb24gaGFzaEludCgpIHtcbiAgdmFyIGhhc2ggPSB0aGlzLmhhc2goKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXG4gICAgaGFzaC51cGRhdGUoYXJndW1lbnRzW2ldKTtcbiAgcmV0dXJuIHV0aWxzLmludEZyb21MRShoYXNoLmRpZ2VzdCgpKS51bW9kKHRoaXMuY3VydmUubik7XG59O1xuXG5FRERTQS5wcm90b3R5cGUua2V5RnJvbVB1YmxpYyA9IGZ1bmN0aW9uIGtleUZyb21QdWJsaWMocHViKSB7XG4gIHJldHVybiBLZXlQYWlyLmZyb21QdWJsaWModGhpcywgcHViKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5rZXlGcm9tU2VjcmV0ID0gZnVuY3Rpb24ga2V5RnJvbVNlY3JldChzZWNyZXQpIHtcbiAgcmV0dXJuIEtleVBhaXIuZnJvbVNlY3JldCh0aGlzLCBzZWNyZXQpO1xufTtcblxuRUREU0EucHJvdG90eXBlLm1ha2VTaWduYXR1cmUgPSBmdW5jdGlvbiBtYWtlU2lnbmF0dXJlKHNpZykge1xuICBpZiAoc2lnIGluc3RhbmNlb2YgU2lnbmF0dXJlKVxuICAgIHJldHVybiBzaWc7XG4gIHJldHVybiBuZXcgU2lnbmF0dXJlKHRoaXMsIHNpZyk7XG59O1xuXG4vKipcbiogKiBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvZHJhZnQtam9zZWZzc29uLWVkZHNhLWVkMjU1MTktMDMjc2VjdGlvbi01LjJcbipcbiogRUREU0EgZGVmaW5lcyBtZXRob2RzIGZvciBlbmNvZGluZyBhbmQgZGVjb2RpbmcgcG9pbnRzIGFuZCBpbnRlZ2Vycy4gVGhlc2UgYXJlXG4qIGhlbHBlciBjb252ZW5pZW5jZSBtZXRob2RzLCB0aGF0IHBhc3MgYWxvbmcgdG8gdXRpbGl0eSBmdW5jdGlvbnMgaW1wbGllZFxuKiBwYXJhbWV0ZXJzLlxuKlxuKi9cbkVERFNBLnByb3RvdHlwZS5lbmNvZGVQb2ludCA9IGZ1bmN0aW9uIGVuY29kZVBvaW50KHBvaW50KSB7XG4gIHZhciBlbmMgPSBwb2ludC5nZXRZKCkudG9BcnJheSgnbGUnLCB0aGlzLmVuY29kaW5nTGVuZ3RoKTtcbiAgZW5jW3RoaXMuZW5jb2RpbmdMZW5ndGggLSAxXSB8PSBwb2ludC5nZXRYKCkuaXNPZGQoKSA/IDB4ODAgOiAwO1xuICByZXR1cm4gZW5jO1xufTtcblxuRUREU0EucHJvdG90eXBlLmRlY29kZVBvaW50ID0gZnVuY3Rpb24gZGVjb2RlUG9pbnQoYnl0ZXMpIHtcbiAgYnl0ZXMgPSB1dGlscy5wYXJzZUJ5dGVzKGJ5dGVzKTtcblxuICB2YXIgbGFzdEl4ID0gYnl0ZXMubGVuZ3RoIC0gMTtcbiAgdmFyIG5vcm1lZCA9IGJ5dGVzLnNsaWNlKDAsIGxhc3RJeCkuY29uY2F0KGJ5dGVzW2xhc3RJeF0gJiB+MHg4MCk7XG4gIHZhciB4SXNPZGQgPSAoYnl0ZXNbbGFzdEl4XSAmIDB4ODApICE9PSAwO1xuXG4gIHZhciB5ID0gdXRpbHMuaW50RnJvbUxFKG5vcm1lZCk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50RnJvbVkoeSwgeElzT2RkKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5lbmNvZGVJbnQgPSBmdW5jdGlvbiBlbmNvZGVJbnQobnVtKSB7XG4gIHJldHVybiBudW0udG9BcnJheSgnbGUnLCB0aGlzLmVuY29kaW5nTGVuZ3RoKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5kZWNvZGVJbnQgPSBmdW5jdGlvbiBkZWNvZGVJbnQoYnl0ZXMpIHtcbiAgcmV0dXJuIHV0aWxzLmludEZyb21MRShieXRlcyk7XG59O1xuXG5FRERTQS5wcm90b3R5cGUuaXNQb2ludCA9IGZ1bmN0aW9uIGlzUG9pbnQodmFsKSB7XG4gIHJldHVybiB2YWwgaW5zdGFuY2VvZiB0aGlzLnBvaW50Q2xhc3M7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xudmFyIHBhcnNlQnl0ZXMgPSB1dGlscy5wYXJzZUJ5dGVzO1xudmFyIGNhY2hlZFByb3BlcnR5ID0gdXRpbHMuY2FjaGVkUHJvcGVydHk7XG5cbi8qKlxuKiBAcGFyYW0ge0VERFNBfSBlZGRzYSAtIGluc3RhbmNlXG4qIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBwdWJsaWMvcHJpdmF0ZSBrZXkgcGFyYW1ldGVyc1xuKlxuKiBAcGFyYW0ge0FycmF5PEJ5dGU+fSBbcGFyYW1zLnNlY3JldF0gLSBzZWNyZXQgc2VlZCBieXRlc1xuKiBAcGFyYW0ge1BvaW50fSBbcGFyYW1zLnB1Yl0gLSBwdWJsaWMga2V5IHBvaW50IChha2EgYEFgIGluIGVkZHNhIHRlcm1zKVxuKiBAcGFyYW0ge0FycmF5PEJ5dGU+fSBbcGFyYW1zLnB1Yl0gLSBwdWJsaWMga2V5IHBvaW50IGVuY29kZWQgYXMgYnl0ZXNcbipcbiovXG5mdW5jdGlvbiBLZXlQYWlyKGVkZHNhLCBwYXJhbXMpIHtcbiAgdGhpcy5lZGRzYSA9IGVkZHNhO1xuICB0aGlzLl9zZWNyZXQgPSBwYXJzZUJ5dGVzKHBhcmFtcy5zZWNyZXQpO1xuICBpZiAoZWRkc2EuaXNQb2ludChwYXJhbXMucHViKSlcbiAgICB0aGlzLl9wdWIgPSBwYXJhbXMucHViO1xuICBlbHNlXG4gICAgdGhpcy5fcHViQnl0ZXMgPSBwYXJzZUJ5dGVzKHBhcmFtcy5wdWIpO1xufVxuXG5LZXlQYWlyLmZyb21QdWJsaWMgPSBmdW5jdGlvbiBmcm9tUHVibGljKGVkZHNhLCBwdWIpIHtcbiAgaWYgKHB1YiBpbnN0YW5jZW9mIEtleVBhaXIpXG4gICAgcmV0dXJuIHB1YjtcbiAgcmV0dXJuIG5ldyBLZXlQYWlyKGVkZHNhLCB7IHB1YjogcHViIH0pO1xufTtcblxuS2V5UGFpci5mcm9tU2VjcmV0ID0gZnVuY3Rpb24gZnJvbVNlY3JldChlZGRzYSwgc2VjcmV0KSB7XG4gIGlmIChzZWNyZXQgaW5zdGFuY2VvZiBLZXlQYWlyKVxuICAgIHJldHVybiBzZWNyZXQ7XG4gIHJldHVybiBuZXcgS2V5UGFpcihlZGRzYSwgeyBzZWNyZXQ6IHNlY3JldCB9KTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLnNlY3JldCA9IGZ1bmN0aW9uIHNlY3JldCgpIHtcbiAgcmV0dXJuIHRoaXMuX3NlY3JldDtcbn07XG5cbmNhY2hlZFByb3BlcnR5KEtleVBhaXIsIGZ1bmN0aW9uIHB1YkJ5dGVzKCkge1xuICByZXR1cm4gdGhpcy5lZGRzYS5lbmNvZGVQb2ludCh0aGlzLnB1YigpKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCBmdW5jdGlvbiBwdWIoKSB7XG4gIGlmICh0aGlzLl9wdWJCeXRlcylcbiAgICByZXR1cm4gdGhpcy5lZGRzYS5kZWNvZGVQb2ludCh0aGlzLl9wdWJCeXRlcyk7XG4gIHJldHVybiB0aGlzLmVkZHNhLmcubXVsKHRoaXMucHJpdigpKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCBmdW5jdGlvbiBwcml2Qnl0ZXMoKSB7XG4gIHZhciBlZGRzYSA9IHRoaXMuZWRkc2E7XG4gIHZhciBoYXNoID0gdGhpcy5oYXNoKCk7XG4gIHZhciBsYXN0SXggPSBlZGRzYS5lbmNvZGluZ0xlbmd0aCAtIDE7XG5cbiAgdmFyIGEgPSBoYXNoLnNsaWNlKDAsIGVkZHNhLmVuY29kaW5nTGVuZ3RoKTtcbiAgYVswXSAmPSAyNDg7XG4gIGFbbGFzdEl4XSAmPSAxMjc7XG4gIGFbbGFzdEl4XSB8PSA2NDtcblxuICByZXR1cm4gYTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCBmdW5jdGlvbiBwcml2KCkge1xuICByZXR1cm4gdGhpcy5lZGRzYS5kZWNvZGVJbnQodGhpcy5wcml2Qnl0ZXMoKSk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoS2V5UGFpciwgZnVuY3Rpb24gaGFzaCgpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuaGFzaCgpLnVwZGF0ZSh0aGlzLnNlY3JldCgpKS5kaWdlc3QoKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCBmdW5jdGlvbiBtZXNzYWdlUHJlZml4KCkge1xuICByZXR1cm4gdGhpcy5oYXNoKCkuc2xpY2UodGhpcy5lZGRzYS5lbmNvZGluZ0xlbmd0aCk7XG59KTtcblxuS2V5UGFpci5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24obWVzc2FnZSkge1xuICBhc3NlcnQodGhpcy5fc2VjcmV0LCAnS2V5UGFpciBjYW4gb25seSB2ZXJpZnknKTtcbiAgcmV0dXJuIHRoaXMuZWRkc2Euc2lnbihtZXNzYWdlLCB0aGlzKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlLCBzaWcpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EudmVyaWZ5KG1lc3NhZ2UsIHNpZywgdGhpcyk7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5nZXRTZWNyZXQgPSBmdW5jdGlvbiBnZXRTZWNyZXQoZW5jKSB7XG4gIGFzc2VydCh0aGlzLl9zZWNyZXQsICdLZXlQYWlyIGlzIHB1YmxpYyBvbmx5Jyk7XG4gIHJldHVybiB1dGlscy5lbmNvZGUodGhpcy5zZWNyZXQoKSwgZW5jKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLmdldFB1YmxpYyA9IGZ1bmN0aW9uIGdldFB1YmxpYyhlbmMpIHtcbiAgcmV0dXJuIHV0aWxzLmVuY29kZSh0aGlzLnB1YkJ5dGVzKCksIGVuYyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEtleVBhaXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xudmFyIGNhY2hlZFByb3BlcnR5ID0gdXRpbHMuY2FjaGVkUHJvcGVydHk7XG52YXIgcGFyc2VCeXRlcyA9IHV0aWxzLnBhcnNlQnl0ZXM7XG5cbi8qKlxuKiBAcGFyYW0ge0VERFNBfSBlZGRzYSAtIGVkZHNhIGluc3RhbmNlXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fE9iamVjdH0gc2lnIC1cbiogQHBhcmFtIHtBcnJheTxCeXRlcz58UG9pbnR9IFtzaWcuUl0gLSBSIHBvaW50IGFzIFBvaW50IG9yIGJ5dGVzXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fGJufSBbc2lnLlNdIC0gUyBzY2FsYXIgYXMgYm4gb3IgYnl0ZXNcbiogQHBhcmFtIHtBcnJheTxCeXRlcz59IFtzaWcuUmVuY29kZWRdIC0gUiBwb2ludCBlbmNvZGVkXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fSBbc2lnLlNlbmNvZGVkXSAtIFMgc2NhbGFyIGVuY29kZWRcbiovXG5mdW5jdGlvbiBTaWduYXR1cmUoZWRkc2EsIHNpZykge1xuICB0aGlzLmVkZHNhID0gZWRkc2E7XG5cbiAgaWYgKHR5cGVvZiBzaWcgIT09ICdvYmplY3QnKVxuICAgIHNpZyA9IHBhcnNlQnl0ZXMoc2lnKTtcblxuICBpZiAoQXJyYXkuaXNBcnJheShzaWcpKSB7XG4gICAgc2lnID0ge1xuICAgICAgUjogc2lnLnNsaWNlKDAsIGVkZHNhLmVuY29kaW5nTGVuZ3RoKSxcbiAgICAgIFM6IHNpZy5zbGljZShlZGRzYS5lbmNvZGluZ0xlbmd0aClcbiAgICB9O1xuICB9XG5cbiAgYXNzZXJ0KHNpZy5SICYmIHNpZy5TLCAnU2lnbmF0dXJlIHdpdGhvdXQgUiBvciBTJyk7XG5cbiAgaWYgKGVkZHNhLmlzUG9pbnQoc2lnLlIpKVxuICAgIHRoaXMuX1IgPSBzaWcuUjtcbiAgaWYgKHNpZy5TIGluc3RhbmNlb2YgQk4pXG4gICAgdGhpcy5fUyA9IHNpZy5TO1xuXG4gIHRoaXMuX1JlbmNvZGVkID0gQXJyYXkuaXNBcnJheShzaWcuUikgPyBzaWcuUiA6IHNpZy5SZW5jb2RlZDtcbiAgdGhpcy5fU2VuY29kZWQgPSBBcnJheS5pc0FycmF5KHNpZy5TKSA/IHNpZy5TIDogc2lnLlNlbmNvZGVkO1xufVxuXG5jYWNoZWRQcm9wZXJ0eShTaWduYXR1cmUsIGZ1bmN0aW9uIFMoKSB7XG4gIHJldHVybiB0aGlzLmVkZHNhLmRlY29kZUludCh0aGlzLlNlbmNvZGVkKCkpO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KFNpZ25hdHVyZSwgZnVuY3Rpb24gUigpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZGVjb2RlUG9pbnQodGhpcy5SZW5jb2RlZCgpKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShTaWduYXR1cmUsIGZ1bmN0aW9uIFJlbmNvZGVkKCkge1xuICByZXR1cm4gdGhpcy5lZGRzYS5lbmNvZGVQb2ludCh0aGlzLlIoKSk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoU2lnbmF0dXJlLCBmdW5jdGlvbiBTZW5jb2RlZCgpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZW5jb2RlSW50KHRoaXMuUygpKTtcbn0pO1xuXG5TaWduYXR1cmUucHJvdG90eXBlLnRvQnl0ZXMgPSBmdW5jdGlvbiB0b0J5dGVzKCkge1xuICByZXR1cm4gdGhpcy5SZW5jb2RlZCgpLmNvbmNhdCh0aGlzLlNlbmNvZGVkKCkpO1xufTtcblxuU2lnbmF0dXJlLnByb3RvdHlwZS50b0hleCA9IGZ1bmN0aW9uIHRvSGV4KCkge1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHRoaXMudG9CeXRlcygpLCAnaGV4JykudG9VcHBlckNhc2UoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gU2lnbmF0dXJlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzaCA9IHJlcXVpcmUoJ2hhc2guanMnKTtcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uL2VsbGlwdGljJyk7XG52YXIgdXRpbHMgPSBlbGxpcHRpYy51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbmZ1bmN0aW9uIEhtYWNEUkJHKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEhtYWNEUkJHKSlcbiAgICByZXR1cm4gbmV3IEhtYWNEUkJHKG9wdGlvbnMpO1xuICB0aGlzLmhhc2ggPSBvcHRpb25zLmhhc2g7XG4gIHRoaXMucHJlZFJlc2lzdCA9ICEhb3B0aW9ucy5wcmVkUmVzaXN0O1xuXG4gIHRoaXMub3V0TGVuID0gdGhpcy5oYXNoLm91dFNpemU7XG4gIHRoaXMubWluRW50cm9weSA9IG9wdGlvbnMubWluRW50cm9weSB8fCB0aGlzLmhhc2guaG1hY1N0cmVuZ3RoO1xuXG4gIHRoaXMucmVzZWVkID0gbnVsbDtcbiAgdGhpcy5yZXNlZWRJbnRlcnZhbCA9IG51bGw7XG4gIHRoaXMuSyA9IG51bGw7XG4gIHRoaXMuViA9IG51bGw7XG5cbiAgdmFyIGVudHJvcHkgPSB1dGlscy50b0FycmF5KG9wdGlvbnMuZW50cm9weSwgb3B0aW9ucy5lbnRyb3B5RW5jKTtcbiAgdmFyIG5vbmNlID0gdXRpbHMudG9BcnJheShvcHRpb25zLm5vbmNlLCBvcHRpb25zLm5vbmNlRW5jKTtcbiAgdmFyIHBlcnMgPSB1dGlscy50b0FycmF5KG9wdGlvbnMucGVycywgb3B0aW9ucy5wZXJzRW5jKTtcbiAgYXNzZXJ0KGVudHJvcHkubGVuZ3RoID49ICh0aGlzLm1pbkVudHJvcHkgLyA4KSxcbiAgICAgICAgICdOb3QgZW5vdWdoIGVudHJvcHkuIE1pbmltdW0gaXM6ICcgKyB0aGlzLm1pbkVudHJvcHkgKyAnIGJpdHMnKTtcbiAgdGhpcy5faW5pdChlbnRyb3B5LCBub25jZSwgcGVycyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEhtYWNEUkJHO1xuXG5IbWFjRFJCRy5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGVudHJvcHksIG5vbmNlLCBwZXJzKSB7XG4gIHZhciBzZWVkID0gZW50cm9weS5jb25jYXQobm9uY2UpLmNvbmNhdChwZXJzKTtcblxuICB0aGlzLksgPSBuZXcgQXJyYXkodGhpcy5vdXRMZW4gLyA4KTtcbiAgdGhpcy5WID0gbmV3IEFycmF5KHRoaXMub3V0TGVuIC8gOCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5WLmxlbmd0aDsgaSsrKSB7XG4gICAgdGhpcy5LW2ldID0gMHgwMDtcbiAgICB0aGlzLlZbaV0gPSAweDAxO1xuICB9XG5cbiAgdGhpcy5fdXBkYXRlKHNlZWQpO1xuICB0aGlzLnJlc2VlZCA9IDE7XG4gIHRoaXMucmVzZWVkSW50ZXJ2YWwgPSAweDEwMDAwMDAwMDAwMDA7ICAvLyAyXjQ4XG59O1xuXG5IbWFjRFJCRy5wcm90b3R5cGUuX2htYWMgPSBmdW5jdGlvbiBobWFjKCkge1xuICByZXR1cm4gbmV3IGhhc2guaG1hYyh0aGlzLmhhc2gsIHRoaXMuSyk7XG59O1xuXG5IbWFjRFJCRy5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIHVwZGF0ZShzZWVkKSB7XG4gIHZhciBrbWFjID0gdGhpcy5faG1hYygpXG4gICAgICAgICAgICAgICAgIC51cGRhdGUodGhpcy5WKVxuICAgICAgICAgICAgICAgICAudXBkYXRlKFsgMHgwMCBdKTtcbiAgaWYgKHNlZWQpXG4gICAga21hYyA9IGttYWMudXBkYXRlKHNlZWQpO1xuICB0aGlzLksgPSBrbWFjLmRpZ2VzdCgpO1xuICB0aGlzLlYgPSB0aGlzLl9obWFjKCkudXBkYXRlKHRoaXMuVikuZGlnZXN0KCk7XG4gIGlmICghc2VlZClcbiAgICByZXR1cm47XG5cbiAgdGhpcy5LID0gdGhpcy5faG1hYygpXG4gICAgICAgICAgICAgICAudXBkYXRlKHRoaXMuVilcbiAgICAgICAgICAgICAgIC51cGRhdGUoWyAweDAxIF0pXG4gICAgICAgICAgICAgICAudXBkYXRlKHNlZWQpXG4gICAgICAgICAgICAgICAuZGlnZXN0KCk7XG4gIHRoaXMuViA9IHRoaXMuX2htYWMoKS51cGRhdGUodGhpcy5WKS5kaWdlc3QoKTtcbn07XG5cbkhtYWNEUkJHLnByb3RvdHlwZS5yZXNlZWQgPSBmdW5jdGlvbiByZXNlZWQoZW50cm9weSwgZW50cm9weUVuYywgYWRkLCBhZGRFbmMpIHtcbiAgLy8gT3B0aW9uYWwgZW50cm9weSBlbmNcbiAgaWYgKHR5cGVvZiBlbnRyb3B5RW5jICE9PSAnc3RyaW5nJykge1xuICAgIGFkZEVuYyA9IGFkZDtcbiAgICBhZGQgPSBlbnRyb3B5RW5jO1xuICAgIGVudHJvcHlFbmMgPSBudWxsO1xuICB9XG5cbiAgZW50cm9weSA9IHV0aWxzLnRvQnVmZmVyKGVudHJvcHksIGVudHJvcHlFbmMpO1xuICBhZGQgPSB1dGlscy50b0J1ZmZlcihhZGQsIGFkZEVuYyk7XG5cbiAgYXNzZXJ0KGVudHJvcHkubGVuZ3RoID49ICh0aGlzLm1pbkVudHJvcHkgLyA4KSxcbiAgICAgICAgICdOb3QgZW5vdWdoIGVudHJvcHkuIE1pbmltdW0gaXM6ICcgKyB0aGlzLm1pbkVudHJvcHkgKyAnIGJpdHMnKTtcblxuICB0aGlzLl91cGRhdGUoZW50cm9weS5jb25jYXQoYWRkIHx8IFtdKSk7XG4gIHRoaXMucmVzZWVkID0gMTtcbn07XG5cbkhtYWNEUkJHLnByb3RvdHlwZS5nZW5lcmF0ZSA9IGZ1bmN0aW9uIGdlbmVyYXRlKGxlbiwgZW5jLCBhZGQsIGFkZEVuYykge1xuICBpZiAodGhpcy5yZXNlZWQgPiB0aGlzLnJlc2VlZEludGVydmFsKVxuICAgIHRocm93IG5ldyBFcnJvcignUmVzZWVkIGlzIHJlcXVpcmVkJyk7XG5cbiAgLy8gT3B0aW9uYWwgZW5jb2RpbmdcbiAgaWYgKHR5cGVvZiBlbmMgIT09ICdzdHJpbmcnKSB7XG4gICAgYWRkRW5jID0gYWRkO1xuICAgIGFkZCA9IGVuYztcbiAgICBlbmMgPSBudWxsO1xuICB9XG5cbiAgLy8gT3B0aW9uYWwgYWRkaXRpb25hbCBkYXRhXG4gIGlmIChhZGQpIHtcbiAgICBhZGQgPSB1dGlscy50b0FycmF5KGFkZCwgYWRkRW5jKTtcbiAgICB0aGlzLl91cGRhdGUoYWRkKTtcbiAgfVxuXG4gIHZhciB0ZW1wID0gW107XG4gIHdoaWxlICh0ZW1wLmxlbmd0aCA8IGxlbikge1xuICAgIHRoaXMuViA9IHRoaXMuX2htYWMoKS51cGRhdGUodGhpcy5WKS5kaWdlc3QoKTtcbiAgICB0ZW1wID0gdGVtcC5jb25jYXQodGhpcy5WKTtcbiAgfVxuXG4gIHZhciByZXMgPSB0ZW1wLnNsaWNlKDAsIGxlbik7XG4gIHRoaXMuX3VwZGF0ZShhZGQpO1xuICB0aGlzLnJlc2VlZCsrO1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHJlcywgZW5jKTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgZG91Ymxlczoge1xuICAgIHN0ZXA6IDQsXG4gICAgcG9pbnRzOiBbXG4gICAgICBbXG4gICAgICAgICdlNjBmY2U5M2I1OWU5ZWM1MzAxMWFhYmMyMWMyM2U5N2IyYTMxMzY5Yjg3YTVhZTljNDRlZTg5ZTJhNmRlYzBhJyxcbiAgICAgICAgJ2Y3ZTM1MDczOTllNTk1OTI5ZGI5OWYzNGY1NzkzNzEwMTI5Njg5MWU0NGQyM2YwYmUxZjMyY2NlNjk2MTY4MjEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODI4MjI2MzIxMmM2MDlkOWVhMmE2ZTNlMTcyZGUyMzhkOGMzOWNhYmQ1YWMxY2ExMDY0NmUyM2ZkNWY1MTUwOCcsXG4gICAgICAgICcxMWY4YTgwOTg1NTdkZmU0NWU4MjU2ZTgzMGI2MGFjZTYyZDYxM2FjMmY3YjE3YmVkMzFiNmVhZmY2ZTI2Y2FmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE3NWUxNTlmNzI4Yjg2NWE3MmY5OWNjNmM2ZmM4NDZkZTBiOTM4MzNmZDIyMjJlZDczZmNlNWI1NTFlNWI3MzknLFxuICAgICAgICAnZDM1MDZlMGQ5ZTNjNzllYmE0ZWY5N2E1MWZmNzFmNWVhY2I1OTU1YWRkMjQzNDVjNmVmYTZmZmVlOWZlZDY5NSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNjNkOTBkNDQ3YjAwYzljOTljZWFjMDViNjI2MmVlMDUzNDQxYzdlNTU1NTJmZmU1MjZiYWQ4ZjgzZmY0NjQwJyxcbiAgICAgICAgJzRlMjczYWRmYzczMjIyMTk1M2I0NDUzOTdmMzM2MzE0NWI5YTg5MDA4MTk5ZWNiNjIwMDNjN2YzYmVlOWRlOSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4YjRiNWYxNjVkZjNjMmJlOGM2MjQ0YjViNzQ1NjM4ODQzZTRhNzgxYTE1YmNkMWI2OWY3OWE1NWRmZmRmODBjJyxcbiAgICAgICAgJzRhYWQwYTZmNjhkMzA4YjRiM2ZiZDc4MTNhYjBkYTA0ZjllMzM2NTQ2MTYyZWU1NmIzZWZmMGM2NWZkNGZkMzYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzIzY2JhYTZlNWRiOTk2ZDZiZjc3MWMwMGJkNTQ4YzdiNzAwZGJmZmE2YzBlNzdiY2I2MTE1OTI1MjMyZmNkYScsXG4gICAgICAgICc5NmU4NjdiNTU5NWNjNDk4YTkyMTEzNzQ4ODgyNGQ2ZTI2NjBhMDY1Mzc3OTQ5NDgwMWRjMDY5ZDllYjM5ZjVmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VlYmZhNGQ0OTNiZWJmOThiYTVmZWVjODEyYzJkM2I1MDk0Nzk2MTIzN2E5MTk4MzlhNTMzZWNhMGU3ZGQ3ZmEnLFxuICAgICAgICAnNWQ5YThjYTM5NzBlZjBmMjY5ZWU3ZWRhZjE3ODA4OWQ5YWU0Y2RjM2E3MTFmNzEyZGRmZDRmZGFlMWRlODk5OSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxMDBmNDRkYTY5NmU3MTY3Mjc5MWQwYTA5YjdiZGU0NTlmMTIxNWEyOWIzYzAzYmZlZmQ3ODM1YjM5YTQ4ZGIwJyxcbiAgICAgICAgJ2NkZDllMTMxOTJhMDBiNzcyZWM4ZjMzMDBjMDkwNjY2YjdmZjRhMThmZjUxOTVhYzBmYmQ1Y2Q2MmJjNjVhMDknXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTEwMzFiZTI2MmM3ZWQxYjFkYzkyMjdhNGEwNGMwMTdhNzdmOGQ0NDY0ZjNiMzg1MmM4YWNkZTZlNTM0ZmQyZCcsXG4gICAgICAgICc5ZDcwNjE5Mjg5NDA0MDVlNmJiNmE0MTc2NTk3NTM1YWYyOTJkZDQxOWUxY2VkNzlhNDRmMThmMjk0NTZhMDBkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2ZlZWE2Y2FlNDZkNTViNTMwYWMyODM5ZjE0M2JkN2VjNWNmOGIyNjZhNDFkNmFmNTJkNWU2ODhkOTA5NDY5NmQnLFxuICAgICAgICAnZTU3YzZiNmM5N2RjZTFiYWIwNmU0ZTEyYmYzZWNkNWM5ODFjODk1N2NjNDE0NDJkMzE1NWRlYmYxODA5MDA4OCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkYTY3YTkxZDkxMDQ5Y2RjYjM2N2JlNGJlNmZmY2EzY2ZlZWQ2NTdkODA4NTgzZGUzM2ZhOTc4YmMxZWM2Y2IxJyxcbiAgICAgICAgJzliYWNhYTM1NDgxNjQyYmM0MWY0NjNmN2VjOTc4MGU1ZGVjN2FkYzUwOGY3NDBhMTdlOWVhOGUyN2E2OGJlMWQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNTM5MDRmYWEwYjMzNGNkZGE2ZTAwMDkzNWVmMjIxNTFlYzA4ZDBmN2JiMTEwNjlmNTc1NDVjY2MxYTM3YjdjMCcsXG4gICAgICAgICc1YmMwODdkMGJjODAxMDZkODhjOWVjY2FjMjBkM2MxYzEzOTk5OTgxZTE0NDM0Njk5ZGNiMDk2YjAyMjc3MWM4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhlN2JjZDBiZDM1OTgzYTc3MTljY2E3NzY0Y2E5MDY3NzliNTNhMDQzYTliOGJjYWVmZjk1OWY0M2FkODYwNDcnLFxuICAgICAgICAnMTBiNzc3MGIyYTNkYTRiMzk0MDMxMDQyMGNhOTUxNDU3OWU4OGUyZTQ3ZmQ2OGIzZWExMDA0N2U4NDYwMzcyYSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczODVlZWQzNGMxY2RmZjIxZTZkMDgxODY4OWI4MWJkZTcxYTdmNGYxODM5N2U2NjkwYTg0MWUxNTk5YzQzODYyJyxcbiAgICAgICAgJzI4M2JlYmMzZThlYTIzZjU2NzAxZGUxOWU5ZWJmNDU3NmIzMDRlZWMyMDg2ZGM4Y2MwNDU4ZmU1NTQyZTU0NTMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNmY5ZDliODAzZWNmMTkxNjM3YzczYTQ0MTNkZmExODBmZGRmODRhNTk0N2ZiYzljNjA2ZWQ4NmMzZmFjM2E3JyxcbiAgICAgICAgJzdjODBjNjhlNjAzMDU5YmE2OWI4ZTJhMzBlNDVjNGQ0N2VhNGRkMmY1YzI4MTAwMmQ4Njg5MDYwM2E4NDIxNjAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzMyMmQ0MDEyNDNjNGUyNTgyYTIxNDdjMTA0ZDZlY2JmNzc0ZDE2M2RiMGY1ZTUzMTNiN2UwZTc0MmQwZTZiZCcsXG4gICAgICAgICc1NmU3MDc5N2U5NjY0ZWY1YmZiMDE5YmM0ZGRhZjliNzI4MDVmNjNlYTI4NzNhZjYyNGYzYTJlOTZjMjhiMmEwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg1NjcyYzdkMmRlMGI3ZGEyYmQxNzcwZDg5NjY1ODY4NzQxYjNmOWFmNzY0MzM5NzcyMWQ3NGQyODEzNGFiODMnLFxuICAgICAgICAnN2M0ODFiOWI1YjQzYjJlYjYzNzQwNDliZmE2MmMyZTVlNzdmMTdmY2M1Mjk4ZjQ0YzhlMzA5NGY3OTAzMTNhNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5NDhiZjgwOWIxOTg4YTQ2YjA2YzlmMTkxOTQxM2IxMGY5MjI2YzYwZjY2ODgzMmZmZDk1OWFmNjBjODJhMGEnLFxuICAgICAgICAnNTNhNTYyODU2ZGNiNjY0NmRjNmI3NGM1ZDFjMzQxOGM2ZDRkZmYwOGM5N2NkMmJlZDRjYjdmODhkOGM4ZTU4OSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2MjYwY2U3ZjQ2MTgwMWMzNGYwNjdjZTBmMDI4NzNhOGYxYjBlNDRkZmM2OTc1MmFjY2VjZDgxOWYzOGZkOGU4JyxcbiAgICAgICAgJ2JjMmRhODJiNmZhNWI1NzFhN2YwOTA0OTc3NmExZWY3ZWNkMjkyMjM4MDUxYzE5OGMxYTg0ZTk1YjJiNGFlMTcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTUwMzdkZTBhZmMxZDhkNDNkODM0ODQxNGJiZjQxMDMwNDNlYzhmNTc1YmZkYzQzMjk1M2NjOGQyMDM3ZmEyZCcsXG4gICAgICAgICc0NTcxNTM0YmFhOTRkM2I1ZjlmOThkMDlmYjk5MGJkZGJkNWY1YjAzZWM0ODFmMTBlMGU1ZGM4NDFkNzU1YmRhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2UwNjM3MmIwZjRhMjA3YWRmNWVhOTA1ZThmMTc3MWI0ZTdlOGRiZDFjNmE2YzViNzI1ODY2YTBhZTRmY2U3MjUnLFxuICAgICAgICAnN2E5MDg5NzRiY2UxOGNmZTEyYTI3YmIyYWQ1YTQ4OGNkNzQ4NGE3Nzg3MTA0ODcwYjI3MDM0Zjk0ZWVlMzFkZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyMTNjN2E3MTVjZDVkNDUzNThkMGJiZjlkYzBjZTAyMjA0YjEwYmRkZTJhM2Y1ODU0MGFkNjkwOGQwNTU5NzU0JyxcbiAgICAgICAgJzRiNmRhZDBiNWFlNDYyNTA3MDEzYWQwNjI0NWJhMTkwYmI0ODUwZjVmMzZhN2VlZGRmZjJjMjc1MzRiNDU4ZjInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNGU3YzI3MmE3YWY0YjM0ZThkYmI5MzUyYTU0MTlhODdlMjgzOGM3MGFkYzYyY2RkZjBjYzNhM2IwOGZiZDUzYycsXG4gICAgICAgICcxNzc0OWM3NjZjOWQwYjE4ZTE2ZmQwOWY2ZGVmNjgxYjUzMGI5NjE0YmZmN2RkMzNlMGIzOTQxODE3ZGNhYWU2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2ZlYTc0ZTNkYmU3NzhiMWIxMGYyMzhhZDYxNjg2YWE1Yzc2ZTNkYjJiZTQzMDU3NjMyNDI3ZTI4NDBmYjI3YjYnLFxuICAgICAgICAnNmUwNTY4ZGI5YjBiMTMyOTdjZjY3NGRlY2NiNmFmOTMxMjZiNTk2Yjk3M2Y3Yjc3NzAxZDNkYjdmMjNjYjk2ZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NmU2NDExM2Y2NzdjZjBlMTBhMjU3MGQ1OTk5NjhkMzE1NDRlMTc5Yjc2MDQzMjk1MmMwMmE0NDE3YmRkZTM5JyxcbiAgICAgICAgJ2M5MGRkZjhkZWU0ZTk1Y2Y1NzcwNjZkNzA2ODFmMGQzNWUyYTMzZDJiNTZkMjAzMmI0YjE3NTJkMTkwMWFjMDEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYzczOGM1NmIwM2IyYWJlMWU4MjgxYmFhNzQzZjhmOWE4ZjdjYzY0M2RmMjZjYmVlM2FiMTUwMjQyYmNiYjg5MScsXG4gICAgICAgICc4OTNmYjU3ODk1MWFkMjUzN2Y3MThmMmVhY2JmYmJiYjgyMzE0ZWVmNzg4MGNmZTkxN2U3MzVkOTY5OWE4NGMzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2Q4OTU2MjY1NDhiNjViODFlMjY0Yzc2MzdjOTcyODc3ZDFkNzJlNWYzYTkyNTAxNDM3MmU5ZjY1ODhmNmMxNGInLFxuICAgICAgICAnZmViZmFhMzhmMmJjN2VhZTcyOGVjNjA4MThjMzQwZWIwMzQyOGQ2MzJiYjA2N2UxNzkzNjNlZDc1ZDdkOTkxZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiOGRhOTQwMzJhOTU3NTE4ZWIwZjY0MzM1NzFlODc2MWNlZmZjNzM2OTNlODRlZGQ0OTE1MGE1NjRmNjc2ZTAzJyxcbiAgICAgICAgJzI4MDRkZmE0NDgwNWExZTRkN2M5OWNjOTc2MjgwOGIwOTJjYzU4NGQ5NWZmM2I1MTE0ODhlNGU3NGVmZGY2ZTcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTgwZmVhMTQ0NDFmYjMzYTdkOGFkYWI5NDc1ZDdmYWIyMDE5ZWZmYjUxNTZhNzkyZjFhMTE3NzhlM2MwZGY1ZCcsXG4gICAgICAgICdlZWQxZGU3ZjYzOGUwMDc3MWU4OTc2OGNhM2NhOTQ0NzJkMTU1ZTgwYWYzMjJlYTlmY2I0MjkxYjZhYzllYzc4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2EzMDE2OTdiZGZjZDcwNDMxM2JhNDhlNTFkNTY3NTQzZjJhMTgyMDMxZWZkNjkxNWRkYzA3YmJjYzRlMTYwNzAnLFxuICAgICAgICAnNzM3MGY5MWNmYjY3ZTRmNTA4MTgwOWZhMjVkNDBmOWIxNzM1ZGJmN2MwYTExYTEzMGMwZDFhMDQxZTE3N2VhMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5MGFkODViMzg5ZDZiOTM2NDYzZjlkMDUxMjY3OGRlMjA4Y2MzMzBiMTEzMDdmZmZhYjdhYzYzZTNmYjA0ZWQ0JyxcbiAgICAgICAgJ2U1MDdhMzYyMGEzODI2MWFmZmRjYmQ5NDI3MjIyYjgzOWFlZmFiZTE1ODI4OTRkOTkxZDRkNDhjYjZlZjE1MCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4ZjY4YjlkMmY2M2I1ZjMzOTIzOWMxYWQ5ODFmMTYyZWU4OGM1Njc4NzIzZWEzMzUxYjdiNDQ0YzllYzRjMGRhJyxcbiAgICAgICAgJzY2MmE5ZjJkYmEwNjM5ODZkZTFkOTBjMmI2YmUyMTVkYmJlYTJjZmU5NTUxMGJmZGYyM2NiZjc5NTAxZmZmODInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTRmM2ZiMDE3NmFmODVkNjVmZjk5ZmY5MTk4YzM2MDkxZjQ4ZTg2NTAzNjgxZTNlNjY4NmZkNTA1MzIzMWUxMScsXG4gICAgICAgICcxZTYzNjMzYWQwZWY0ZjFjMTY2MWE2ZDBlYTAyYjcyODZjYzdlNzRlYzk1MWQxYzk4MjJjMzg1NzZmZWI3M2JjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhjMDBmYTliMThlYmYzMzFlYjk2MTUzN2E0NWE0MjY2YzcwMzRmMmYwZDRlMWQwNzE2ZmI2ZWFlMjBlYWUyOWUnLFxuICAgICAgICAnZWZhNDcyNjdmZWE1MjFhMWE5ZGMzNDNhMzczNmM5NzRjMmZhZGFmYTgxZTM2YzU0ZTdkMmE0YzY2NzAyNDE0YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlN2EyNmNlNjlkZDQ4MjlmM2UxMGNlYzBhOWU5OGVkMzE0M2QwODRmMzA4YjkyYzA5OTdmZGRmYzYwY2IzZTQxJyxcbiAgICAgICAgJzJhNzU4ZTMwMGZhNzk4NGI0NzFiMDA2YTFhYWZiYjE4ZDBhNmIyYzA0MjBlODNlMjBlOGE5NDIxY2YyY2ZkNTEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYjY0NTllMGVlMzY2MmVjOGQyMzU0MGMyMjNiY2JkYzU3MWNiY2I5NjdkNzk0MjRmM2NmMjllYjNkZTZiODBlZicsXG4gICAgICAgICc2N2M4NzZkMDZmM2UwNmRlMWRhZGYxNmU1NjYxZGIzYzRiM2FlNmQ0OGUzNWIyZmYzMGJmMGI2MWE3MWJhNDUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDY4YTgwYzgyODBiYjg0MDc5MzIzNGFhMTE4ZjA2MjMxZDZmMWZjNjdlNzNjNWE1ZGVkYTBmNWI0OTY5NDNlOCcsXG4gICAgICAgICdkYjhiYTlmZmY0YjU4NmQwMGM0YjFmOTE3N2IwZTI4YjViMGU3YjhmNzg0NTI5NWEyOTRjODQyNjZiMTMzMTIwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMyNGFlZDdkZjY1YzgwNDI1MmRjMDI3MDkwN2EzMGIwOTYxMmFlYjk3MzQ0OWNlYTQwOTU5ODBmYzI4ZDNkNWQnLFxuICAgICAgICAnNjQ4YTM2NTc3NGI2MWYyZmYxMzBjMGMzNWFlYzFmNGYxOTIxM2IwYzdlMzMyODQzOTY3MjI0YWY5NmFiN2M4NCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0ZGY5YzE0OTE5Y2RlNjFmNmQ1MWRmZGJlNWZlZTVkY2VlYzQxNDNiYThkMWNhODg4ZThiZDM3M2ZkMDU0Yzk2JyxcbiAgICAgICAgJzM1ZWM1MTA5MmQ4NzI4MDUwOTc0YzIzYTFkODVkNGI1ZDUwNmNkYzI4ODQ5MDE5MmViYWMwNmNhZDEwZDVkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzljMzkxOWE4NGE0NzQ4NzBmYWVkOGE5YzFjYzY2MDIxNTIzNDg5MDU0ZDdmMDMwOGNiZmM5OWM4YWMxZjk4Y2QnLFxuICAgICAgICAnZGRiODRmMGY0YTRkZGQ1NzU4NGYwNDRiZjI2MGU2NDE5MDUzMjZmNzZjNjRjOGU2YmU3ZTVlMDNkNGZjNTk5ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2MDU3MTcwYjFkZDEyZmRmOGRlMDVmMjgxZDhlMDZiYjkxZTE0OTNhOGI5MWQ0Y2M1YTIxMzgyMTIwYTk1OWU1JyxcbiAgICAgICAgJzlhMWFmMGIyNmE2YTQ4MDdhZGQ5YTJkYWY3MWRmMjYyNDY1MTUyYmMzZWUyNGM2NWU4OTliZTkzMjM4NWEyYTgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTU3NmRmOGUyM2EwODQxMTQyMTQzOWE0NTE4ZGEzMTg4MGNlZjBmYmE3ZDRkZjEyYjFhNjk3M2VlY2I5NDI2NicsXG4gICAgICAgICc0MGE2YmYyMGU3NjY0MGIyYzkyYjk3YWZlNThjZDgyYzQzMmUxMGE3ZjUxNGQ5ZjNlZThiZTExYWUxYjI4ZWM4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc3NzhhNzhjMjhkZWMzZTMwYTA1ZmU5NjI5ZGU4YzM4YmIzMGQxZjVjZjlhM2EyMDhmNzYzODg5YmU1OGFkNzEnLFxuICAgICAgICAnMzQ2MjZkOWFiNWE1YjIyZmY3MDk4ZTEyZjJmZjU4MDA4N2IzODQxMWZmMjRhYzU2M2I1MTNmYzFmZDlmNDNhYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5Mjg5NTVlZTYzN2E4NDQ2MzcyOWZkMzBlN2FmZDJlZDVmOTYyNzRlNWFkN2U1Y2IwOWVkYTljMDZkOTAzYWMnLFxuICAgICAgICAnYzI1NjIxMDAzZDNmNDJhODI3Yjc4YTEzMDkzYTk1ZWVhYzNkMjZlZmE4YThkODNmYzUxODBlOTM1YmNkMDkxZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4NWQwZmVmM2VjNmRiMTA5Mzk5MDY0ZjNhMGUzYjI4NTU2NDViNGE5MDdhZDM1NDUyN2FhZTc1MTYzZDgyNzUxJyxcbiAgICAgICAgJzFmMDM2NDg0MTNhMzhjMGJlMjlkNDk2ZTU4MmNmNTY2M2U4NzUxZTk2ODc3MzMxNTgyYzIzN2EyNGViMWY5NjInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmYyYjBkY2U5N2VlY2U5N2MxYzliNjA0MTc5OGI4NWRmZGZiNmQ4ODgyZGEyMDMwOGY1NDA0ODI0NTI2MDg3ZScsXG4gICAgICAgICc0OTNkMTNmZWY1MjRiYTE4OGFmNGM0ZGM1NGQwNzkzNmM3YjdlZDZmYjkwZTJjZWIyYzk1MWUwMWYwYzI5OTA3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzgyN2ZiYmU0YjFlODgwZWE5ZWQyYjJlNjMwMWIyMTJiNTdmMWVlMTQ4Y2Q2ZGQyODc4MGU1ZTJjZjg1NmUyNDEnLFxuICAgICAgICAnYzYwZjljOTIzYzcyN2IwYjcxYmVmMmM2N2QxZDEyNjg3ZmY3YTYzMTg2OTAzMTY2ZDYwNWI2OGJhZWMyOTNlYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlYWE2NDlmMjFmNTFiZGJhZTdiZTRhZTM0Y2U2ZTUyMTdhNThmZGNlN2Y0N2Y5YWE3ZjNiNThmYTIxMjBlMmIzJyxcbiAgICAgICAgJ2JlMzI3OWVkNWJiYmIwM2FjNjlhODBmODk4NzlhYTVhMDFhNmI5NjVmMTNmN2U1OWQ0N2E1MzA1YmE1YWQ5M2QnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTRhNDJkNDNjNWNmMTY5ZDkzOTFkZjZkZWNmNDJlZTU0MWI2ZDhmMGM5YTEzNzQwMWUyMzYzMmRkYTM0ZDI0ZicsXG4gICAgICAgICc0ZDlmOTJlNzE2ZDFjNzM1MjZmYzk5Y2NmYjhhZDM0Y2U4ODZlZWRmYThkOGU0ZjEzYTdmNzEzMWRlYmE5NDE0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzFlYzgwZmVmMzYwY2JkZDk1NDE2MGZhZGFiMzUyYjZiOTJiNTM1NzZhODhmZWE0OTQ3MTczYjlkNDMwMGJmMTknLFxuICAgICAgICAnYWVlZmU5Mzc1NmI1MzQwZDJmM2E0OTU4YTdhYmJmNWUwMTQ2ZTc3ZjYyOTVhMDdiNjcxY2RjMWNjMTA3Y2VmZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNDZhNzc4YzA0NjcwYzJmOTFiMDBhZjQ2ODBkZmE4YmNlMzQ5MDcxN2Q1OGJhODg5ZGRiNTkyODM2NjY0MmJlJyxcbiAgICAgICAgJ2IzMThlMGVjMzM1NDAyOGFkZDY2OTgyN2Y5ZDRiMjg3MGFhYTk3MWQyZjdlNWVkMWQwYjI5NzQ4M2Q4M2VmZDAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmE1MGMwZjYxZDIyZTVmMDdlM2FjZWJiMWFhMDdiMTI4ZDAwMTIyMDlhMjhiOTc3NmQ3NmE4NzkzMTgwZWVmOScsXG4gICAgICAgICc2Yjg0YzY5MjIzOTdlYmE5YjcyY2QyODcyMjgxYTY4YTVlNjgzMjkzYTU3YTIxM2IzOGNkOGQ3ZDNmNGYyODExJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RhMWQ2MWQwY2E3MjFhMTFiMWE1YmY2YjdkODhlODQyMWEyODhhYjVkNWJiYTUyMjBlNTNkMzJiNWYwNjdlYzInLFxuICAgICAgICAnODE1N2Y1NWE3Yzk5MzA2Yzc5YzA3NjYxNjFjOTFlMjk2NmE3Mzg5OWQyNzliNDhhNjU1ZmJhMGYxYWQ4MzZmMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhOGUyODJmZjBjOTcwNjkwNzIxNWZmOThlOGZkNDE2NjE1MzExZGUwNDQ2ZjFlMDYyYTczYjA2MTBkMDY0ZTEzJyxcbiAgICAgICAgJzdmOTczNTViOGRiODFjMDlhYmZiN2YzYzViMjUxNTg4OGI2NzlhM2U1MGRkNmJkNmNlZjdjNzMxMTFmNGNjMGMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTc0YTUzYjljOWEyODU4NzJkMzllNTZlNjkxM2NhYjE1ZDU5YjFmYTUxMjUwOGMwMjJmMzgyZGU4MzE5NDk3YycsXG4gICAgICAgICdjY2M5ZGMzN2FiZmM5YzE2NTdiNDE1NWYyYzQ3ZjllNjY0NmIzYTFkOGNiOTg1NDM4M2RhMTNhYzA3OWFmYTczJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzk1OTM5Njk4MTk0Mzc4NWMzZDNlNTdlZGY1MDE4Y2RiZTAzOWU3MzBlNDkxOGIzZDg4NGZkZmYwOTQ3NWI3YmEnLFxuICAgICAgICAnMmU3ZTU1Mjg4OGMzMzFkZDhiYTAzODZhNGI5Y2Q2ODQ5YzY1M2Y2NGM4NzA5Mzg1ZTliOGFiZjg3NTI0ZjJmZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkMmE2M2E1MGFlNDAxZTU2ZDY0NWExMTUzYjEwOWE4ZmNjYTBhNDNkNTYxZmJhMmRiYjUxMzQwYzlkODJiMTUxJyxcbiAgICAgICAgJ2U4MmQ4NmZiNjQ0M2ZjYjc1NjVhZWU1OGIyOTQ4MjIwYTcwZjc1MGFmNDg0Y2E1MmQ0MTQyMTc0ZGNmODk0MDUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNjQ1ODdlMjMzNTQ3MWViODkwZWU3ODk2ZDdjZmRjODY2YmFjYmRiZDM4MzkzMTdiMzQzNmY5YjQ1NjE3ZTA3MycsXG4gICAgICAgICdkOTlmY2RkNWJmNjkwMmUyYWU5NmRkNjQ0N2MyOTlhMTg1YjkwYTM5MTMzYWVhYjM1ODI5OWU1ZTlmYWY2NTg5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg0ODFiZGUwZTRlNGQ4ODViM2E1NDZkM2U1NDlkZTA0MmYwYWE2Y2VhMjUwZTdmZDM1OGQ2Yzg2ZGQ0NWU0NTgnLFxuICAgICAgICAnMzhlZTdiOGNiYTU0MDRkZDg0YTI1YmYzOWNlY2IyY2E5MDBhNzljNDJiMjYyZTU1NmQ2NGIxYjU5Nzc5MDU3ZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxMzQ2NGE1N2E3ODEwMmFhNjJiNjk3OWFlODE3ZjQ2MzdmZmNmZWQzYzRiMWNlMzBiY2Q2MzAzZjZjYWY2NjZiJyxcbiAgICAgICAgJzY5YmUxNTkwMDQ2MTQ1ODBlZjdlNDMzNDUzY2NiMGNhNDhmMzAwYTgxZDA5NDJlMTNmNDk1YTkwN2Y2ZWNjMjcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYmM0YTlkZjViNzEzZmUyZTlhZWY0MzBiY2MxZGM5N2EwY2Q5Y2NlZGUyZjI4NTg4Y2FkYTNhMGQyZDgzZjM2NicsXG4gICAgICAgICdkM2E4MWNhNmU3ODVjMDYzODM5MzdhZGY0Yjc5OGNhYTZlOGE5ZmJmYTU0N2IxNmQ3NThkNjY2NTgxZjMzYzEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGMyOGE5N2JmODI5OGJjMGQyM2Q4Yzc0OTQ1MmEzMmU2OTRiNjVlMzBhOTQ3MmEzOTU0YWIzMGZlNTMyNGNhYScsXG4gICAgICAgICc0MGEzMDQ2M2EzMzA1MTkzMzc4ZmVkZjMxZjdjYzBlYjdhZTc4NGYwNDUxY2I5NDU5ZTcxZGM3M2NiZWY5NDgyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhlYTk2NjYxMzk1MjdhOGMxZGQ5NGNlNGYwNzFmZDIzYzhiMzUwYzVhNGJiMzM3NDhjNGJhMTExZmFjY2FlMCcsXG4gICAgICAgICc2MjBlZmFiYmM4ZWUyNzgyZTI0ZTdjMGNmYjk1YzVkNzM1Yjc4M2JlOWNmMGY4ZTk1NWFmMzRhMzBlNjJiOTQ1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RkMzYyNWZhZWY1YmEwNjA3NDY2OTcxNmJiZDM3ODhkODliZGRlODE1OTU5OTY4MDkyZjc2Y2M0ZWI5YTk3ODcnLFxuICAgICAgICAnN2ExODhmYTM1MjBlMzBkNDYxZGEyNTAxMDQ1NzMxY2E5NDE0NjE5ODI4ODMzOTU5MzdmNjhkMDBjNjQ0YTU3MydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmNzEwZDc5ZDllYjk2MjI5N2U0ZjYyMzJiNDBlOGY3ZmViMmJjNjM4MTQ2MTRkNjkyYzEyZGU3NTI0MDgyMjFlJyxcbiAgICAgICAgJ2VhOThlNjcyMzJkM2IzMjk1ZDNiNTM1NTMyMTE1Y2NhYzg2MTJjNzIxODUxNjE3NTI2YWU0N2E5Yzc3YmZjODInXG4gICAgICBdXG4gICAgXVxuICB9LFxuICBuYWY6IHtcbiAgICB3bmQ6IDcsXG4gICAgcG9pbnRzOiBbXG4gICAgICBbXG4gICAgICAgICdmOTMwOGEwMTkyNThjMzEwNDkzNDRmODVmODlkNTIyOWI1MzFjODQ1ODM2Zjk5YjA4NjAxZjExM2JjZTAzNmY5JyxcbiAgICAgICAgJzM4OGY3YjBmNjMyZGU4MTQwZmUzMzdlNjJhMzdmMzU2NjUwMGE5OTkzNGMyMjMxYjZjYjlmZDc1ODRiOGU2NzInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMmY4YmRlNGQxYTA3MjA5MzU1YjRhNzI1MGE1YzUxMjhlODhiODRiZGRjNjE5YWI3Y2JhOGQ1NjliMjQwZWZlNCcsXG4gICAgICAgICdkOGFjMjIyNjM2ZTVlM2Q2ZDRkYmE5ZGRhNmM5YzQyNmY3ODgyNzFiYWIwZDY4NDBkY2E4N2QzYWE2YWM2MmQ2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzVjYmRmMDY0NmU1ZGI0ZWFhMzk4ZjM2NWYyZWE3YTBlM2Q0MTliN2UwMzMwZTM5Y2U5MmJkZGVkY2FjNGY5YmMnLFxuICAgICAgICAnNmFlYmNhNDBiYTI1NTk2MGEzMTc4ZDZkODYxYTU0ZGJhODEzZDBiODEzZmRlN2I1YTUwODI2MjgwODcyNjRkYSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhY2Q0ODRlMmYwYzdmNjUzMDlhZDE3OGE5ZjU1OWFiZGUwOTc5Njk3NGM1N2U3MTRjMzVmMTEwZGZjMjdjY2JlJyxcbiAgICAgICAgJ2NjMzM4OTIxYjBhN2Q5ZmQ2NDM4MDk3MTc2M2I2MWU5YWRkODg4YTQzNzVmOGUwZjA1Y2MyNjJhYzY0ZjljMzcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzc0YWU3Zjg1OGE5NDExZTVlZjQyNDZiNzBjNjVhYWM1NjQ5OTgwYmU1YzE3ODkxYmJlYzE3ODk1ZGEwMDhjYicsXG4gICAgICAgICdkOTg0YTAzMmViNmI1ZTE5MDI0M2RkNTZkN2I3YjM2NTM3MmRiMWUyZGZmOWQ2YTgzMDFkNzRjOWM5NTNjNjFiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2YyODc3M2MyZDk3NTI4OGJjN2QxZDIwNWMzNzQ4NjUxYjA3NWZiYzY2MTBlNThjZGRlZWRkZjhmMTk0MDVhYTgnLFxuICAgICAgICAnYWIwOTAyZThkODgwYTg5NzU4MjEyZWI2NWNkYWY0NzNhMWEwNmRhNTIxZmE5MWYyOWI1Y2I1MmRiMDNlZDgxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2Q3OTI0ZDRmN2Q0M2VhOTY1YTQ2NWFlMzA5NWZmNDExMzFlNTk0NmYzYzg1Zjc5ZTQ0YWRiY2Y4ZTI3ZTA4MGUnLFxuICAgICAgICAnNTgxZTI4NzJhODZjNzJhNjgzODQyZWMyMjhjYzZkZWZlYTQwYWYyYmQ4OTZkM2E1YzUwNGRjOWZmNmEyNmI1OCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkZWZkZWE0Y2RiNjc3NzUwYTQyMGZlZTgwN2VhY2YyMWViOTg5OGFlNzliOTc2ODc2NmU0ZmFhMDRhMmQ0YTM0JyxcbiAgICAgICAgJzQyMTFhYjA2OTQ2MzUxNjhlOTk3YjBlYWQyYTkzZGFlY2VkMWY0YTA0YTk1YzBmNmNmYjE5OWY2OWU1NmViNzcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMmI0ZWEwYTc5N2E0NDNkMjkzZWY1Y2ZmNDQ0ZjQ5NzlmMDZhY2ZlYmQ3ZTg2ZDI3NzQ3NTY1NjEzODM4NWI2YycsXG4gICAgICAgICc4NWU4OWJjMDM3OTQ1ZDkzYjM0MzA4M2I1YTFjODYxMzFhMDFmNjBjNTAyNjk3NjNiNTcwYzg1NGU1YzA5YjdhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM1MmJiZjRhNGNkZDEyNTY0ZjkzZmEzMzJjZTMzMzMwMWQ5YWQ0MDI3MWY4MTA3MTgxMzQwYWVmMjViZTU5ZDUnLFxuICAgICAgICAnMzIxZWI0MDc1MzQ4ZjUzNGQ1OWMxODI1OWRkYTNlMWY0YTFiM2IyZTcxYjEwMzljNjdiZDNkOGJjZjgxOTk4YydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyZmEyMTA0ZDZiMzhkMTFiMDIzMDAxMDU1OTg3OTEyNGU0MmFiOGRmZWZmNWZmMjlkYzljZGFkZDRlY2FjYzNmJyxcbiAgICAgICAgJzJkZTEwNjgyOTVkZDg2NWI2NDU2OTMzNWJkNWRkODAxODFkNzBlY2ZjODgyNjQ4NDIzYmE3NmI1MzJiN2Q2NydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5MjQ4Mjc5YjA5YjRkNjhkYWIyMWE5YjA2NmVkZGE4MzI2M2MzZDg0ZTA5NTcyZTI2OWNhMGNkN2Y1NDUzNzE0JyxcbiAgICAgICAgJzczMDE2ZjdiZjIzNGFhZGU1ZDFhYTcxYmRlYTJiMWZmM2ZjMGRlMmE4ODc5MTJmZmU1NGEzMmNlOTdjYjM0MDInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGFlZDRmMmJlM2E4YmYyNzhlNzAxMzJmYjBiZWI3NTIyZjU3MGUxNDRiZjYxNWMwN2U5OTZkNDQzZGVlODcyOScsXG4gICAgICAgICdhNjlkY2U0YTdkNmM5OGU4ZDRhMWFjYTg3ZWY4ZDcwMDNmODNjMjMwZjNhZmE3MjZhYjQwZTUyMjkwYmUxYzU1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2M0NGQxMmM3MDY1ZDgxMmU4YWNmMjhkN2NiYjE5ZjkwMTFlY2Q5ZTlmZGYyODFiMGU2YTNiNWU4N2QyMmU3ZGInLFxuICAgICAgICAnMjExOWE0NjBjZTMyNmNkYzc2YzQ1OTI2Yzk4MmZkYWMwZTEwNmU4NjFlZGY2MWM1YTAzOTA2M2YwZTBlNjQ4MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2YTI0NWJmNmRjNjk4NTA0Yzg5YTIwY2ZkZWQ2MDg1MzE1MmI2OTUzMzZjMjgwNjNiNjFjNjVjYmQyNjllNmI0JyxcbiAgICAgICAgJ2UwMjJjZjQyYzJiZDRhNzA4YjNmNTEyNmYxNmEyNGFkOGIzM2JhNDhkMDQyM2I2ZWZkNWU2MzQ4MTAwZDhhODInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTY5N2ZmYTZmZDlkZTYyN2MwNzdlM2QyZmU1NDEwODRjZTEzMzAwYjBiZWMxMTQ2Zjk1YWU1N2YwZDBiZDZhNScsXG4gICAgICAgICdiOWMzOThmMTg2ODA2ZjVkMjc1NjE1MDZlNDU1NzQzM2EyY2YxNTAwOWU0OThhZTdhZGVlOWQ2M2QwMWIyMzk2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzYwNWJkYjAxOTk4MTcxOGI5ODZkMGYwN2U4MzRjYjBkOWRlYjgzNjBmZmI3ZjYxZGY5ODIzNDVlZjI3YTc0NzknLFxuICAgICAgICAnMjk3MmQyZGU0ZjhkMjA2ODFhNzhkOTNlYzk2ZmUyM2MyNmJmYWU4NGZiMTRkYjQzYjAxZTFlOTA1NmI4YzQ5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzYyZDE0ZGFiNDE1MGJmNDk3NDAyZmRjNDVhMjE1ZTEwZGNiMDFjMzU0OTU5YjEwY2ZlMzFjN2U5ZDg3ZmYzM2QnLFxuICAgICAgICAnODBmYzA2YmQ4Y2M1YjAxMDk4MDg4YTE5NTBlZWQwZGIwMWFhMTMyOTY3YWI0NzIyMzVmNTY0MjQ4M2IyNWVhZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4MGM2MGFkMDA0MGYyN2RhZGU1YjRiMDZjNDA4ZTU2YjJjNTBlOWY1NmI5YjhiNDI1ZTU1NWMyZjg2MzA4YjZmJyxcbiAgICAgICAgJzFjMzgzMDNmMWNjNWMzMGYyNmU2NmJhZDdmZTcyZjcwYTY1ZWVkNGNiZTcwMjRlYjFhYTAxZjU2NDMwYmQ1N2EnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnN2E5Mzc1YWQ2MTY3YWQ1NGFhNzRjNjM0OGNjNTRkMzQ0Y2M1ZGM5NDg3ZDg0NzA0OWQ1ZWFiYjBmYTAzYzhmYicsXG4gICAgICAgICdkMGUzZmE5ZWNhODcyNjkwOTU1OWUwZDc5MjY5MDQ2YmRjNTllYTEwYzcwY2UyYjAyZDQ5OWVjMjI0ZGM3ZjcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDUyOGVjZDliNjk2YjU0YzkwN2E5ZWQwNDU0NDdhNzliYjQwOGVjMzliNjhkZjUwNGJiNTFmNDU5YmMzZmZjOScsXG4gICAgICAgICdlZWNmNDEyNTMxMzZlNWY5OTk2NmYyMTg4MWZkNjU2ZWJjNDM0NTQwNWM1MjBkYmMwNjM0NjViNTIxNDA5OTMzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzQ5MzcwYTRiNWY0MzQxMmVhMjVmNTE0ZThlY2RhZDA1MjY2MTE1ZTRhN2VjYjEzODcyMzE4MDhmOGI0NTk2MycsXG4gICAgICAgICc3NThmM2Y0MWFmZDZlZDQyOGIzMDgxYjA1MTJmZDYyYTU0YzNmM2FmYmI1YjY3NjRiNjUzMDUyYTEyOTQ5YzlhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc3ZjIzMDkzNmVlODhjYmJkNzNkZjkzMGQ2NDcwMmVmODgxZDgxMWUwZTE0OThlMmYxYzEzZWIxZmMzNDVkNzQnLFxuICAgICAgICAnOTU4ZWY0MmE3ODg2YjY0MDBhMDgyNjZlOWJhMWIzNzg5NmM5NTMzMGQ5NzA3N2NiYmU4ZWIzYzc2NzFjNjBkNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmMmRhYzk5MWNjNGNlNGI5ZWE0NDg4N2U1YzdjMGJjZTU4YzgwMDc0YWI5ZDRkYmFlYjI4NTMxYjc3MzlmNTMwJyxcbiAgICAgICAgJ2UwZGVkYzliM2IyZjhkYWQ0ZGExZjMyZGVjMjUzMWRmOWViNWZiZWIwNTk4ZTRmZDFhMTE3ZGJhNzAzYTNjMzcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDYzYjNkOWY2NjI2MjFmYjFiNGJlOGZiYmUyNTIwMTI1YTIxNmNkZmM5ZGFlM2RlYmNiYTQ4NTBjNjkwZDQ1YicsXG4gICAgICAgICc1ZWQ0MzBkNzhjMjk2YzM1NDMxMTQzMDZkZDg2MjJkN2M2MjJlMjdjOTcwYTFkZTMxY2IzNzdiMDFhZjczMDdlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2YxNmY4MDQyNDRlNDZlMmEwOTIzMmQ0YWZmM2I1OTk3NmI5OGZhYzE0MzI4YTJkMWEzMjQ5NmI0OTk5OGYyNDcnLFxuICAgICAgICAnY2VkYWJkOWI4MjIwM2Y3ZTEzZDIwNmZjZGY0ZTMzZDkyYTZjNTNjMjZlNWNjZTI2ZDY1Nzk5NjJjNGUzMWRmNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjYWY3NTQyNzJkYzg0NTYzYjAzNTJiN2ExNDMxMWFmNTVkMjQ1MzE1YWNlMjdjNjUzNjllMTVmNzE1MWQ0MWQxJyxcbiAgICAgICAgJ2NiNDc0NjYwZWYzNWY1ZjJhNDFiNjQzZmE1ZTQ2MDU3NWY0ZmE5Yjc5NjIyMzJhNWMzMmY5MDgzMThhMDQ0NzYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMjYwMGNhNGIyODJjYjk4NmY4NWQwZjE3MDk5NzlkOGI0NGEwOWMwN2NiODZkN2MxMjQ0OTdiYzg2ZjA4MjEyMCcsXG4gICAgICAgICc0MTE5Yjg4NzUzYzE1YmQ2YTY5M2IwM2ZjZGRiYjQ1ZDVhYzZiZTc0YWI1ZjBlZjQ0YjBiZTk0NzVhN2U0YjQwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc2MzVjYTcyZDdlODQzMmMzMzhlYzUzY2QxMjIyMGJjMDFjNDg2ODVlMjRmN2RjOGM2MDJhNzc0Njk5OGU0MzUnLFxuICAgICAgICAnOTFiNjQ5NjA5NDg5ZDYxM2QxZDVlNTkwZjc4ZTZkNzRlY2ZjMDYxZDU3MDQ4YmFkOWU3NmYzMDJjNWI5YzYxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc1NGUzMjM5ZjMyNTU3MGNkYmJmNGE4N2RlZWU4YTY2YjdmMmIzMzQ3OWQ0NjhmYmMxYTUwNzQzYmY1NmNjMTgnLFxuICAgICAgICAnNjczZmI4NmU1YmRhMzBmYjNjZDBlZDMwNGVhNDlhMDIzZWUzM2QwMTk3YTY5NWQwYzVkOTgwOTNjNTM2NjgzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2UzZTZiZDEwNzFhMWU5NmFmZjU3ODU5YzgyZDU3MGYwMzMwODAwNjYxZDFjOTUyZjlmZTI2OTQ2OTFkOWI5ZTgnLFxuICAgICAgICAnNTljOWUwYmJhMzk0ZTc2ZjQwYzBhYTU4Mzc5YTNjYjZhNWEyMjgzOTkzZTkwYzQxNjcwMDJhZjQ5MjBlMzdmNSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxODZiNDgzZDA1NmEwMzM4MjZhZTczZDg4ZjczMjk4NWM0Y2NiMWYzMmJhMzVmNGI0Y2M0N2ZkY2YwNGFhNmViJyxcbiAgICAgICAgJzNiOTUyZDMyYzY3Y2Y3N2UyZTE3NDQ2ZTIwNDE4MGFiMjFmYjgwOTA4OTUxMzhiNGE0YTc5N2Y4NmU4MDg4OGInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGY5ZDcwYTZiOTg3NmNlNTQ0Yzk4NTYxZjRiZTRmNzI1NDQyZTZkMmI3MzdkOWM5MWE4MzIxNzI0Y2UwOTYzZicsXG4gICAgICAgICc1NWViMmRhZmQ4NGQ2Y2NkNWY4NjJiNzg1ZGMzOWQ0YWIxNTcyMjI3MjBlZjlkYTIxN2I4YzQ1Y2YyYmEyNDE3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzVlZGQ1Y2MyM2M1MWU4N2E0OTdjYTgxNWQ1ZGNlMGY4YWI1MjU1NGY4NDllZDg5OTVkZTY0YzVmMzRjZTcxNDMnLFxuICAgICAgICAnZWZhZTljOGRiYzE0MTMwNjYxZThjZWMwMzBjODlhZDBjMTNjNjZjMGQxN2EyOTA1Y2RjNzA2YWI3Mzk5YTg2OCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyOTA3OThjMmI2NDc2ODMwZGExMmZlMDIyODdlOWU3NzdhYTNmYmExYzM1NWIxN2E3MjJkMzYyZjg0NjE0ZmJhJyxcbiAgICAgICAgJ2UzOGRhNzZkY2Q0NDA2MjE5ODhkMDBiY2Y3OWFmMjVkNWIyOWMwOTRkYjJhMjMxNDZkMDAzYWZkNDE5NDNlN2EnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYWYzYzQyM2E5NWQ5ZjViMzA1NDc1NGVmYTE1MGFjMzljZDI5NTUyZmUzNjAyNTczNjJkZmRlY2VmNDA1M2I0NScsXG4gICAgICAgICdmOThhM2ZkODMxZWIyYjc0OWE5M2IwZTZmMzVjZmI0MGM4Y2Q1YWE2NjdhMTU1ODFiYzJmZWRlZDQ5OGZkOWM2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc2NmRiYjI0ZDEzNGU3NDVjY2NhYTI4Yzk5YmYyNzQ5MDZiYjY2YjI2ZGNmOThkZjhkMmZlZDUwZDg4NDI0OWEnLFxuICAgICAgICAnNzQ0YjExNTJlYWNiZTVlMzhkY2M4ODc5ODBkYTM4Yjg5NzU4NGE2NWZhMDZjZWRkMmM5MjRmOTdjYmFjNTk5NidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1OWRiZjQ2ZjhjOTQ3NTliYTIxMjc3YzMzNzg0ZjQxNjQ1ZjdiNDRmNmM1OTZhNThjZTkyZTY2NjE5MWFiZTNlJyxcbiAgICAgICAgJ2M1MzRhZDQ0MTc1ZmJjMzAwZjRlYTZjZTY0ODMwOWEwNDJjZTczOWE3OTE5Nzk4Y2Q4NWUyMTZjNGEzMDdmNmUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZjEzYWRhOTUxMDNjNDUzNzMwNWU2OTFlNzRlOWE0YThkZDY0N2U3MTFhOTVlNzNjYjYyZGM2MDE4Y2ZkODdiOCcsXG4gICAgICAgICdlMTM4MTdiNDRlZTE0ZGU2NjNiZjRiYzgwODM0MWYzMjY5NDllMjFhNmE3NWMyNTcwNzc4NDE5YmRhZjU3MzNkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc3NTRiNGZhMGU4YWNlZDA2ZDQxNjdhMmM1OWNjYTRjZGExODY5YzA2ZWJhZGZiNjQ4ODU1MDAxNWE4ODUyMmMnLFxuICAgICAgICAnMzBlOTNlODY0ZTY2OWQ4MjIyNGI5NjdjMzAyMGI4ZmE4ZDFlNGUzNTBiNmNiY2M1MzdhNDhiNTc4NDExNjNhMidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5NDhkY2FkZjU5OTBlMDQ4YWEzODc0ZDQ2YWJlZjlkNzAxODU4Zjk1ZGU4MDQxZDJhNjgyOGM5OWUyMjYyNTE5JyxcbiAgICAgICAgJ2U0OTFhNDI1MzdmNmU1OTdkNWQyOGEzMjI0YjFiYzI1ZGY5MTU0ZWZiZDJlZjFkMmNiYmEyY2FlNTM0N2Q1N2UnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzk2MjQxNDQ1MGM3NmMxNjg5YzdiNDhmODIwMmVjMzdmYjIyNGNmNWFjMGJmYTE1NzAzMjhhOGEzZDdjNzdhYicsXG4gICAgICAgICcxMDBiNjEwZWM0ZmZiNDc2MGQ1YzFmYzEzM2VmNmY2YjEyNTA3YTA1MWYwNGFjNTc2MGFmYTViMjlkYjgzNDM3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM1MTQwODc4MzQ5NjRiNTRiMTViMTYwNjQ0ZDkxNTQ4NWExNjk3NzIyNWI4ODQ3YmIwZGQwODUxMzdlYzQ3Y2EnLFxuICAgICAgICAnZWYwYWZiYjIwNTYyMDU0NDhlMTY1MmM0OGU4MTI3ZmM2MDM5ZTc3YzE1YzIzNzhiN2U3ZDE1YTBkZTI5MzMxMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkM2NjMzBhZDZiNDgzZTRiYzc5Y2UyYzlkZDhiYzU0OTkzZTk0N2ViOGRmNzg3YjQ0Mjk0M2QzZjdiNTI3ZWFmJyxcbiAgICAgICAgJzhiMzc4YTIyZDgyNzI3OGQ4OWM1ZTliZThmOTUwOGFlM2MyYWQ0NjI5MDM1ODYzMGFmYjM0ZGIwNGVlZGUwYTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTYyNGQ4NDc4MDczMjg2MGNlMWM3OGZjYmZlZmUwOGIyYjI5ODIzZGI5MTNmNjQ5Mzk3NWJhMGZmNDg0NzYxMCcsXG4gICAgICAgICc2ODY1MWNmOWI2ZGE5MDNlMDkxNDQ0OGM2Y2Q5ZDRjYTg5Njg3OGY1MjgyYmU0YzhjYzA2ZTJhNDA0MDc4NTc1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzczM2NlODBkYTk1NWE4YTI2OTAyYzk1NjMzZTYyYTk4NTE5MjQ3NGI1YWYyMDdkYTZkZjdiNGZkNWZjNjFjZDQnLFxuICAgICAgICAnZjU0MzVhMmJkMmJhZGY3ZDQ4NWE0ZDhiOGRiOWZjY2UzZTFlZjhlMDIwMWU0NTc4YzU0NjczYmMxZGM1ZWExZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNWQ5NDQxMjU0OTQ1MDY0Y2YxYTFjMzNiYmQzYjQ5Zjg5NjZjNTA5MjE3MWU2OTllZjI1OGRmYWI4MWMwNDVjJyxcbiAgICAgICAgJ2Q1NmViMzBiNjk0NjNlNzIzNGY1MTM3YjczYjg0MTc3NDM0ODAwYmFjZWJmYzY4NWZjMzdiYmU5ZWZlNDA3MGQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTFkMGZjZjJlYzlkZTY3NWI2MTIxMzZlNWNlNzBkMjcxYzIxNDE3YzlkMmI4YWFhYWMxMzg1OTlkMDcxNzk0MCcsXG4gICAgICAgICdlZGQ3N2Y1MGJjYjVhM2NhYjJlOTA3MzczMDk2NjdmMjY0MTQ2MmE1NDA3MGYzZDUxOTIxMmQzOWMxOTdhNjI5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2UyMmZiZTE1YzBhZjhjY2M1NzgwYzA3MzVmODRkYmU5YTc5MGJhZGVlODI0NWMwNmM3Y2EzNzMzMWNiMzY5ODAnLFxuICAgICAgICAnYTg1NWJhYmFkNWNkNjBjODhiNDMwYTY5ZjUzYTFhN2EzODI4OTE1NDk2NDc5OWJlNDNkMDZkNzdkMzFkYTA2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMxMTA5MWRkOTg2MGU4ZTIwZWUxMzQ3M2MxMTU1ZjVmNjk2MzVlMzk0NzA0ZWFhNzQwMDk0NTIyNDZjZmE5YjMnLFxuICAgICAgICAnNjZkYjY1NmY4N2QxZjA0ZmZmZDFmMDQ3ODhjMDY4MzA4NzFlYzVhNjRmZWVlNjg1YmQ4MGYwYjEyODZkODM3NCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNGMxZmQwNGQzMDFiZTg5YjMxYzA0NDJkM2U2YWMyNDg4MzkyOGI0NWE5MzQwNzgxODY3ZDQyMzJlYzJkYmRmJyxcbiAgICAgICAgJzk0MTQ2ODVlOTdiMWI1OTU0YmQ0NmY3MzAxNzQxMzZkNTdmMWNlZWI0ODc0NDNkYzUzMjE4NTdiYTczYWJlZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmMjE5ZWE1ZDZiNTQ3MDFjMWMxNGRlNWI1NTdlYjQyYThkMTNmM2FiYmNkMDhhZmZjYzJhNWU2YjA0OWI4ZDYzJyxcbiAgICAgICAgJzRjYjk1OTU3ZTgzZDQwYjBmNzNhZjQ1NDRjY2NmNmIxZjRiMDhkM2MwN2IyN2ZiOGQ4YzI5NjJhNDAwNzY2ZDEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDdiODc0MGY3NGE4ZmJhYWIxZjY4M2RiOGY0NWRlMjY1NDNhNTQ5MGJjYTYyNzA4NzIzNjkxMjQ2OWEwYjQ0OCcsXG4gICAgICAgICdmYTc3OTY4MTI4ZDljOTJlZTEwMTBmMzM3YWQ0NzE3ZWZmMTVkYjVlZDNjMDQ5YjM0MTFlMDMxNWVhYTQ1OTNiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMyZDMxYzIyMmY4ZjZmMGVmODZmN2M5OGQzYTMzMzVlYWQ1YmNkMzJhYmRkOTQyODlmZTRkMzA5MWFhODI0YmYnLFxuICAgICAgICAnNWYzMDMyZjU4OTIxNTZlMzljY2QzZDc5MTViOWUxZGEyZTZkYWM5ZTZmMjZlOTYxMTE4ZDE0Yjg0NjJlMTY2MSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NDYxZjM3MTkxNGFiMzI2NzEwNDVhMTU1ZDk4MzFlYTg3OTNkNzdjZDU5NTkyYzQzNDBmODZjYmMxODM0N2I1JyxcbiAgICAgICAgJzhlYzBiYTIzOGI5NmJlYzBjYmRkZGNhZTBhYTQ0MjU0MmVlZTFmZjUwYzk4NmVhNmIzOTg0N2IzY2MwOTJmZjYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZWUwNzlhZGIxZGYxODYwMDc0MzU2YTI1YWEzODIwNmE2ZDcxNmIyYzNlNjc0NTNkMjg3Njk4YmFkN2IyYjJkNicsXG4gICAgICAgICc4ZGMyNDEyYWFmZTNiZTVjNGM1ZjM3ZTBlY2M1ZjlmNmE0NDY5ODlhZjA0YzRlMjVlYmFhYzQ3OWVjMWM4YzFlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE2ZWM5M2U0NDdlYzgzZjA0NjdiMTgzMDJlZTYyMGY3ZTY1ZGUzMzE4NzRjOWRjNzJiZmQ4NjE2YmE5ZGE2YjUnLFxuICAgICAgICAnNWU0NjMxMTUwZTYyZmI0MGQwZThjMmE3Y2E1ODA0YTM5ZDU4MTg2YTUwZTQ5NzEzOTYyNjc3OGUyNWIwNjc0ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlYWE1Zjk4MGMyNDVmNmYwMzg5NzgyOTBhZmE3MGI2YmQ4ODU1ODk3Zjk4YjZhYTQ4NWI5NjA2NWQ1MzdiZDk5JyxcbiAgICAgICAgJ2Y2NWY1ZDNlMjkyYzJlMDgxOWE1MjgzOTFjOTk0NjI0ZDc4NDg2OWQ3ZTZlYTY3ZmIxODA0MTAyNGVkYzA3ZGMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzhjOTQwNzU0NGFjMTMyNjkyZWUxOTEwYTAyNDM5OTU4YWUwNDg3NzE1MTM0MmVhOTZjNGI2YjM1YTQ5ZjUxJyxcbiAgICAgICAgJ2YzZTAzMTkxNjllYjliODVkNTQwNDc5NTUzOWE1ZTY4ZmExZmJkNTgzYzA2NGQyNDYyYjY3NWYxOTRhM2RkYjQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDk0ZjRiZTIxOWExYTc3MDE2ZGNkODM4NDMxYWVhMDAwMWNkYzhhZTdhNmZjNjg4NzI2NTc4ZDk3MDI4NTdhNScsXG4gICAgICAgICc0MjI0MmE5NjkyODNhNWYzMzliYTdmMDc1ZTM2YmEyYWY5MjVjZTMwZDc2N2VkNmU1NWY0YjAzMTg4MGQ1NjJjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2E1OThhODAzMGRhNmQ4NmM2YmM3ZjJmNTE0NGVhNTQ5ZDI4MjExZWE1OGZhYTcwZWJmNGMxZTY2NWMxZmU5YjUnLFxuICAgICAgICAnMjA0YjVkNmY4NDgyMmMzMDdlNGI0YTcxNDA3MzdhZWMyM2ZjNjNiNjViMzVmODZhMTAwMjZkYmQyZDg2NGU2YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjNDE5MTYzNjVhYmIyYjVkMDkxOTJmNWYyZGJlYWZlYzIwOGYwMjBmMTI1NzBhMTg0ZGJhZGMzZTU4NTk1OTk3JyxcbiAgICAgICAgJzRmMTQzNTFkMDA4N2VmYTQ5ZDI0NWIzMjg5ODQ5ODlkNWNhZjk0NTBmMzRiZmMwZWQxNmU5NmI1OGZhOTkxMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4NDFkNjA2M2E1ODZmYTQ3NWE3MjQ2MDRkYTAzYmM1YjkyYTJlMGQyZTBhMzZhY2ZlNGM3M2E1NTE0NzQyODgxJyxcbiAgICAgICAgJzczODY3ZjU5YzA2NTllODE5MDRmOWExYzc1NDM2OThlNjI1NjJkNjc0NGMxNjljZTdhMzZkZTAxYThkNjE1NCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1ZTk1YmIzOTlhNjk3MWQzNzYwMjY5NDdmODliZGUyZjI4MmIzMzgxMDkyOGJlNGRlZDExMmFjNGQ3MGUyMGQ1JyxcbiAgICAgICAgJzM5ZjIzZjM2NjgwOTA4NWJlZWJmYzcxMTgxMzEzNzc1YTk5YzlhZWQ3ZDhiYTM4YjE2MTM4NGM3NDYwMTI4NjUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzZlNDY0MWE1Mzk0OGZkNDc2YzM5ZjhhOTlmZDk3NGU1ZWMwNzU2NGI1MzE1ZDhiZjk5NDcxYmNhMGVmMmY2NicsXG4gICAgICAgICdkMjQyNGIxYjFhYmU0ZWI4MTY0MjI3YjA4NWM5YWE5NDU2ZWExMzQ5M2ZkNTYzZTA2ZmQ1MWNmNTY5NGM3OGZjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMzNjU4MWVhN2JmYmJiMjkwYzE5MWEyZjUwN2E0MWNmNTY0Mzg0MjE3MGU5MTRmYWVhYjI3YzJjNTc5ZjcyNicsXG4gICAgICAgICdlYWQxMjE2ODU5NWZlMWJlOTkyNTIxMjliNmU1NmIzMzkxZjdhYjE0MTBjZDFlMGVmM2RjZGNhYmQyZmRhMjI0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhhYjg5ODE2ZGFkZmQ2YjZhMWYyNjM0ZmNmMDBlYzg0MDM3ODEwMjVlZDY4OTBjNDg0OTc0MjcwNmJkNDNlZGUnLFxuICAgICAgICAnNmZkY2VmMDlmMmY2ZDBhMDQ0ZTY1NGFlZjYyNDEzNmY1MDNkNDU5YzNlODk4NDU4NThhNDdhOTEyOWNkZDI0ZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxZTMzZjFhNzQ2YzljNTc3ODEzMzM0NGQ5Mjk5ZmNhYTIwYjA5MzhlOGFjZmYyNTQ0YmI0MDI4NGI4YzVmYjk0JyxcbiAgICAgICAgJzYwNjYwMjU3ZGQxMWIzYWE5YzhlZDYxOGQyNGVkZmYyMzA2ZDMyMGYxZDAzMDEwZTMzYTdkMjA1N2YzYjNiNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4NWI3YzFkY2IzY2VjMWI3ZWU3ZjMwZGVkNzlkZDIwYTBlZDFmNGNjMThjYmNmY2ZhNDEwMzYxZmQ4ZjA4ZjMxJyxcbiAgICAgICAgJzNkOThhOWNkZDAyNmRkNDNmMzkwNDhmMjVhODg0N2Y0ZmNhZmFkMTg5NWQ3YTYzM2M2ZmVkM2MzNWU5OTk1MTEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMjlkZjlmYmQ4ZDllNDY1MDkyNzVmNGIxMjVkNmQ0NWQ3ZmJlOWEzYjg3OGE3YWY4NzJhMjgwMDY2MWFjNWY1MScsXG4gICAgICAgICdiNGM0ZmU5OWM3NzVhNjA2ZTJkODg2MjE3OTEzOWZmZGE2MWRjODYxYzAxOWU1NWNkMjg3NmViMmEyN2Q4NGInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTBiMWNhZTA2YjBhODQ3YTNmZWE2ZTY3MWFhZjhhZGZkZmU1OGNhMmY3NjgxMDVjODA4MmIyZTQ0OWZjZTI1MicsXG4gICAgICAgICdhZTQzNDEwMmVkZGUwOTU4ZWM0YjE5ZDkxN2E2YTI4ZTZiNzJkYTE4MzRhZmYwZTY1MGYwNDk1MDNhMjk2Y2YyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzRlOGNlYWZiOWIzZTlhMTM2ZGM3ZmY2N2U4NDAyOTViNDk5ZGZiM2IyMTMzZTRiYTExM2YyZTRjMGUxMjFlNScsXG4gICAgICAgICdjZjIxNzQxMThjOGI2ZDdhNGI0OGY2ZDUzNGNlNWM3OTQyMmMwODZhNjM0NjA1MDJiODI3Y2U2MmEzMjY2ODNjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2QyNGE0NGUwNDdlMTliNmY1YWZiODFjN2NhMmY2OTA4MGE1MDc2Njg5YTAxMDkxOWY0MjcyNWMyYjc4OWEzM2InLFxuICAgICAgICAnNmZiOGQ1NTkxYjQ2NmY4ZmM2M2RiNTBmMWMwZjFjNjkwMTNmOTk2ODg3YjgyNDRkMmNkZWM0MTdhZmVhOGZhMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlYTAxNjA2YTdhNmM5Y2RkMjQ5ZmRmY2ZhY2I5OTU4NDAwMWVkZDI4YWJiYWI3N2I1MTA0ZTk4ZThlM2IzNWQ0JyxcbiAgICAgICAgJzMyMmFmNDkwOGM3MzEyYjBjZmJmZTM2OWY3YTdiM2NkYjdkNDQ5NGJjMjgyMzcwMGNmZDY1MjE4OGEzZWE5OGQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYWY4YWRkYmYyYjY2MWM4YTZjNjMyODY1NWViOTY2NTEyNTIwMDdkOGM1ZWEzMWJlNGFkMTk2ZGU4Y2UyMTMxZicsXG4gICAgICAgICc2NzQ5ZTY3YzAyOWI4NWY1MmEwMzRlYWZkMDk2ODM2YjI1MjA4MTg2ODBlMjZhYzhmM2RmYmNkYjcxNzQ5NzAwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2UzYWUxOTc0NTY2Y2EwNmNjNTE2ZDQ3ZTBmYjE2NWE2NzRhM2RhYmNmY2ExNWU3MjJmMGUzNDUwZjQ1ODg5JyxcbiAgICAgICAgJzJhZWFiZTdlNDUzMTUxMDExNjIxN2YwN2JmNGQwNzMwMGRlOTdlNDg3NGY4MWY1MzM0MjBhNzJlZWIwYmQ2YTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNTkxZWUzNTUzMTNkOTk3MjFjZjY5OTNmZmVkMWUzZTMwMTk5M2ZmM2VkMjU4ODAyMDc1ZWE4Y2VkMzk3ZTI0NicsXG4gICAgICAgICdiMGVhNTU4YTExM2MzMGJlYTYwZmM0Nzc1NDYwYzc5MDFmZjBiMDUzZDI1Y2EyYmRlZWU5OGYxYTRiZTVkMTk2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzExMzk2ZDU1ZmRhNTRjNDlmMTlhYTk3MzE4ZDhkYTYxZmE4NTg0ZTQ3YjA4NDk0NTA3N2NmMDMyNTViNTI5ODQnLFxuICAgICAgICAnOTk4Yzc0YThjZDQ1YWMwMTI4OWQ1ODMzYTdiZWI0NzQ0ZmY1MzZiMDFiMjU3YmU0YzU3NjdiZWE5M2VhNTdhNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczYzVkMmExYmEzOWM1YTE3OTAwMDA3MzhjOWUwYzQwYjhkY2RmZDU0Njg3NTRiNjQwNTU0MDE1N2UwMTdhYTdhJyxcbiAgICAgICAgJ2IyMjg0Mjc5OTk1YTM0ZTJmOWQ0ZGU3Mzk2ZmMxOGI4MGY5YjhiOWZkZDI3MGY2NjYxZjc5Y2E0YzgxYmQyNTcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnY2M4NzA0YjhhNjBhMGRlZmEzYTk5YTcyOTlmMmU5YzNmYmMzOTVhZmIwNGFjMDc4NDI1ZWY4YTE3OTNjYzAzMCcsXG4gICAgICAgICdiZGQ0NjAzOWZlZWQxNzg4MWQxZTA4NjJkYjM0N2Y4Y2YzOTViNzRmYzRiY2RjNGU5NDBiNzRlM2FjMWYxYjEzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2M1MzNlNGY3ZWE4NTU1YWFjZDk3NzdhYzVjYWQyOWI5N2RkNGRlZmNjYzUzZWU3ZWEyMDQxMTliMjg4OWIxOTcnLFxuICAgICAgICAnNmYwYTI1NmJjNWVmZGY0MjlhMmZiNjI0MmYxYTQzYTJkOWI5MjViYjRhNGIzYTI2YmI4ZTBmNDVlYjU5NjA5NidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjMTRmOGYyY2NiMjdkNmYxMDlmNmQwOGQwM2NjOTZhNjliYThjMzRlZWMwN2JiY2Y1NjZkNDhlMzNkYTY1OTMnLFxuICAgICAgICAnYzM1OWQ2OTIzYmIzOThmN2ZkNDQ3M2UxNmZlMWMyODQ3NWI3NDBkZDA5ODA3NWU2YzBlODY0OTExM2RjM2EzOCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhNmNiYzMwNDZiYzZhNDUwYmFjMjQ3ODlmYTE3MTE1YTRjOTczOWVkNzVmOGYyMWNlNDQxZjcyZTBiOTBlNmVmJyxcbiAgICAgICAgJzIxYWU3ZjQ2ODBlODg5YmIxMzA2MTllMmMwZjk1YTM2MGNlYjU3M2M3MDYwMzEzOTg2MmFmZDYxN2ZhOWI5ZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNDdkNmQ5YTAyYzQ4OTI3ZWJmYjg2YzEzNTliMWNhZjEzMGEzYzAyNjdkMTFjZTYzNDRiMzlmOTlkNDNjYzM4JyxcbiAgICAgICAgJzYwZWE3ZjYxYTM1MzUyNGQxYzk4N2Y2ZWNlYzkyZjA4NmQ1NjVhYjY4Nzg3MGNiMTI2ODlmZjFlMzFjNzQ0NDgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGE2NTQ1ZDIxODFkYjhkOTgzZjdkY2IzNzVlZjU4NjZkNDdjNjdiMWJmMzFjOGNmODU1ZWY3NDM3YjcyNjU2YScsXG4gICAgICAgICc0OWI5NjcxNWFiNjg3OGE3OWU3OGYwN2NlNTY4MGM1ZDY2NzMwNTFiNDkzNWJkODk3ZmVhODI0Yjc3ZGMyMDhhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2M0MDc0N2NjOWQwMTJjYjFhMTNiODE0ODMwOWM2ZGU3ZWMyNWQ2OTQ1ZDY1NzE0NmI5ZDU5OTRiOGZlYjExMTEnLFxuICAgICAgICAnNWNhNTYwNzUzYmUyYTEyZmM2ZGU2Y2FmMmNiNDg5NTY1ZGI5MzYxNTZiOTUxNGUxYmI1ZTgzMDM3ZTBmYTJkNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0ZTQyYzhlYzgyYzk5Nzk4Y2NmM2E2MTBiZTg3MGU3ODMzOGM3ZjcxMzM0OGJkMzRjODIwM2VmNDAzN2YzNTAyJyxcbiAgICAgICAgJzc1NzFkNzRlZTVlMGZiOTJhN2E4YjMzYTA3NzgzMzQxYTU0OTIxNDRjYzU0YmNjNDBhOTQ0NzM2OTM2MDY0MzcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzc3NWFiNzA4OWJjNmFmODIzYWJhMmUxYWY3MGIyMzZkMjUxY2FkYjBjODY3NDMyODc1MjJhMWIzYjBkZWRlYScsXG4gICAgICAgICdiZTUyZDEwN2JjZmEwOWQ4YmNiOTczNmE4MjhjZmE3ZmFjOGRiMTdiZjdhNzZhMmM0MmFkOTYxNDA5MDE4Y2Y3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2NlZTMxY2JmN2UzNGVjMzc5ZDk0ZmI4MTRkM2Q3NzVhZDk1NDU5NWQxMzE0YmE4ODQ2OTU5ZTNlODJmNzRlMjYnLFxuICAgICAgICAnOGZkNjRhMTRjMDZiNTg5YzI2Yjk0N2FlMmJjZjZiZmEwMTQ5ZWYwYmUxNGVkNGQ4MGY0NDhhMDFjNDNiMWM2ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiNGY5ZWFlYTA5YjY5MTc2MTlmNmVhNmE0ZWI1NDY0ZWZkZGI1OGZkNDViMWViZWZjZGMxYTAxZDA4YjQ3OTg2JyxcbiAgICAgICAgJzM5ZTVjOTkyNWI1YTU0YjA3NDMzYTRmMThjNjE3MjZmOGJiMTMxYzAxMmNhNTQyZWIyNGE4YWMwNzIwMDY4MmEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDQyNjNkZmMzZDJkZjkyM2EwMTc5YTQ4OTY2ZDMwY2U4NGUyNTE1YWZjM2RjY2MxYjc3OTA3NzkyZWJjYzYwZScsXG4gICAgICAgICc2MmRmYWYwN2EwZjc4ZmViMzBlMzBkNjI5NTg1M2NlMTg5ZTEyNzc2MGFkNmNmN2ZhZTE2NGUxMjJhMjA4ZDU0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzQ4NDU3NTI0ODIwZmE2NWE0ZjhkMzVlYjY5MzA4NTdjMDAzMmFjYzBhNGEyZGU0MjIyMzNlZWRhODk3NjEyYzQnLFxuICAgICAgICAnMjVhNzQ4YWIzNjc5NzlkOTg3MzNjMzhhMWZhMWMyZTdkYzZjYzA3ZGIyZDYwYTlhZTdhNzZhYWE0OWJkMGY3NydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkZmVlZWYxODgxMTAxZjJjYjExNjQ0ZjNhMmFmZGZjMjA0NWUxOTkxOTE1MjkyM2YzNjdhMTc2N2MxMWNjZWRhJyxcbiAgICAgICAgJ2VjZmI3MDU2Y2YxZGUwNDJmOTQyMGJhYjM5Njc5M2MwYzM5MGJkZTc0YjRiYmRmZjE2YTgzYWUwOWE5YTc1MTcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNmQ3ZWY2YjE3NTQzZjgzNzNjNTczZjQ0ZTFmMzg5ODM1ZDg5YmNiYzYwNjJjZWQzNmM4MmRmODNiOGZhZTg1OScsXG4gICAgICAgICdjZDQ1MGVjMzM1NDM4OTg2ZGZlZmExMGM1N2ZlYTliY2M1MjFhMDk1OWIyZDgwYmJmNzRiMTkwZGNhNzEyZDEwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2U3NTYwNWQ1OTEwMmE1YTI2ODQ1MDBkM2I5OTFmMmUzZjNjODhiOTMyMjU1NDcwMzVhZjI1YWY2NmUwNDU0MWYnLFxuICAgICAgICAnZjVjNTQ3NTRhOGY3MWVlNTQwYjliNDg3Mjg0NzNlMzE0ZjcyOWFjNTMwOGIwNjkzODM2MDk5MGUyYmZhZDEyNSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlYjk4NjYwZjRjNGRmYWEwNmEyYmU0NTNkNTAyMGJjOTlhMGMyZTYwYWJlMzg4NDU3ZGQ0M2ZlZmIxZWQ2MjBjJyxcbiAgICAgICAgJzZjYjlhODg3NmQ5Y2I4NTIwNjA5YWYzYWRkMjZjZDIwYTBhN2NkOGE5NDExMTMxY2U4NWY0NDEwMDA5OTIyM2UnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTNlODdiMDI3ZDg1MTRkMzU5MzlmMmU2ODkyYjE5OTIyMTU0NTk2OTQxODg4MzM2ZGMzNTYzZTNiOGRiYTk0MicsXG4gICAgICAgICdmZWY1YTNjNjgwNTlhNmRlYzVkNjI0MTE0YmYxZTkxYWFjMmI5ZGE1NjhkNmFiZWIyNTcwZDU1NjQ2YjhhZGYxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VlMTYzMDI2ZTlmZDZmZTAxN2MzOGYwNmE1YmU2ZmMxMjU0MjRiMzcxY2UyNzA4ZTdiZjQ0OTE2OTFlNTc2NGEnLFxuICAgICAgICAnMWFjYjI1MGYyNTVkZDYxYzQzZDk0Y2NjNjcwZDBmNThmNDlhZTNmYTE1Yjk2NjIzZTU0MzBkYTBhZDZjNjJiMidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiMjY4ZjVlZjlhZDUxZTRkNzhkZTNhNzUwYzJkYzg5YjFlNjI2ZDQzNTA1ODY3OTk5OTMyZTVkYjMzYWYzZDgwJyxcbiAgICAgICAgJzVmMzEwZDRiM2M5OWI5ZWJiMTlmNzdkNDFjMWRlZTAxOGNmMGQzNGZkNDE5MTYxNDAwM2U5NDVhMTIxNmU0MjMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmYwN2YzMTE4YTlkZjAzNWU5ZmFkODVlYjZjN2JmZTQyYjAyZjAxY2E5OWNlZWEzYmY3ZmZkYmE5M2M0NzUwZCcsXG4gICAgICAgICc0MzgxMzZkNjAzZTg1OGEzYTVjNDQwYzM4ZWNjYmFkZGMxZDI5NDIxMTRlMmVkZGQ0NzQwZDA5OGNlZDFmMGQ4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhkOGI5ODU1YzdjMDUyYTM0MTQ2ZmQyMGZmYjY1OGJlYTRiOWY2OWUwZDgyNWViZWMxNmU4YzNjZTJiNTI2YTEnLFxuICAgICAgICAnY2RiNTU5ZWVkYzJkNzlmOTI2YmFmNDRmYjg0ZWE0ZDQ0YmNmNTBmZWU1MWQ3Y2ViMzBlMmU3ZjQ2MzAzNjc1OCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1MmRiMGI1Mzg0ZGZiZjA1YmZhOWQ0NzJkN2FlMjZkZmU0Yjg1MWNlY2E5MWIxZWJhNTQyNjMxODBkYTMyYjYzJyxcbiAgICAgICAgJ2MzYjk5N2QwNTBlZTVkNDIzZWJhZjY2YTZkYjlmNTdiMzE4MGM5MDI4NzU2NzlkZTkyNGI2OWQ4NGE3YjM3NSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlNjJmOTQ5MGQzZDUxZGE2Mzk1ZWZkMjRlODA5MTljYzdkMGYyOWMzZjNmYTQ4YzZmZmY1NDNiZWNiZDQzMzUyJyxcbiAgICAgICAgJzZkODlhZDdiYTQ4NzZiMGIyMmMyY2EyODBjNjgyODYyZjM0MmM4NTkxZjFkYWY1MTcwZTA3YmZkOWNjYWZhN2QnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnN2YzMGVhMjQ3NmIzOTliNDk1NzUwOWM4OGY3N2QwMTkxYWZhMmZmNWNiN2IxNGZkNmQ4ZTdkNjVhYWFiMTE5MycsXG4gICAgICAgICdjYTVlZjdkNGIyMzFjOTRjM2IxNTM4OWE1ZjYzMTFlOWRhZmY3YmI2N2IxMDNlOTg4MGVmNGJmZjYzN2FjYWVjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzUwOThmZjFlMWQ5ZjE0ZmI0NmEyMTBmYWRhNmM5MDNmZWYwZmI3YjRhMWRkMWQ5YWM2MGEwMzYxODAwYjdhMDAnLFxuICAgICAgICAnOTczMTE0MWQ4MWZjOGY4MDg0ZDM3YzZlNzU0MjAwNmIzZWUxYjQwZDYwZGZlNTM2MmE1YjEzMmZkMTdkZGMwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMyYjc4YzdkZTllZTUxMmE3Mjg5NWJlNmI5Y2JlZmE2ZTJmM2M0Y2NjZTQ0NWM5NmI5ZjJjODFlMjc3OGFkNTgnLFxuICAgICAgICAnZWUxODQ5ZjUxM2RmNzFlMzJlZmMzODk2ZWUyODI2MGM3M2JiODA1NDdhZTIyNzViYTQ5NzIzNzc5NGM4NzUzYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlMmNiNzRmZGRjOGU5ZmJjZDA3NmVlZjJhN2M3MmIwY2UzN2Q1MGYwODI2OWRmYzA3NGI1ODE1NTA1NDdhNGY3JyxcbiAgICAgICAgJ2QzYWEyZWQ3MWM5ZGQyMjQ3YTYyZGYwNjI3MzZlYjBiYWRkZWE5ZTM2MTIyZDJiZTg2NDFhYmNiMDA1Y2M0YTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODQzODQ0NzU2NmQ0ZDdiZWRhZGMyOTk0OTZhYjM1NzQyNjAwOWEzNWYyMzVjYjE0MWJlMGQ5OWNkMTBhZTNhOCcsXG4gICAgICAgICdjNGUxMDIwOTE2OTgwYTRkYTVkMDFhYzVlNmFkMzMwNzM0ZWYwZDc5MDY2MzFjNGYyMzkwNDI2YjJlZGQ3OTFmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzQxNjJkNDg4Yjg5NDAyMDM5YjU4NGM2ZmM2YzMwODg3MDU4N2Q5YzQ2ZjY2MGI4NzhhYjY1YzgyYzcxMWQ2N2UnLFxuICAgICAgICAnNjcxNjNlOTAzMjM2Mjg5Zjc3NmYyMmMyNWZiOGEzYWZjMTczMmYyYjg0YjRlOTVkYmRhNDdhZTVhMDg1MjY0OSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczZmFkM2ZhODRjYWYwZjM0ZjBmODliZmQyZGNmNTRmYzE3NWQ3NjdhZWMzZTUwNjg0ZjNiYTRhNGJmNWY2ODNkJyxcbiAgICAgICAgJ2NkMWJjN2NiNmNjNDA3YmIyZjBjYTY0N2M3MThhNzMwY2Y3MTg3MmU3ZDBkMmE1M2ZhMjBlZmNkZmU2MTgyNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2NzRmMjYwMGEzMDA3YTAwNTY4YzFhN2NlMDVkMDgxNmMxZmI4NGJmMTM3MDc5OGYxYzY5NTMyZmFlYjFhODZiJyxcbiAgICAgICAgJzI5OWQyMWY5NDEzZjMzYjNlZGY0M2IyNTcwMDQ1ODBiNzBkYjU3ZGEwYjE4MjI1OWUwOWVlY2M2OWUwZDM4YTUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDMyZjRkYTU0YWRlNzRhYmI4MWI4MTVhZDFmYjNiMjYzZDgyZDZjNjkyNzE0YmNmZjg3ZDI5YmQ1ZWU5ZjA4ZicsXG4gICAgICAgICdmOTQyOWU3MzhiOGU1M2I5NjhlOTkwMTZjMDU5NzA3NzgyZTE0ZjQ1MzUzNTlkNTgyZmM0MTY5MTBiM2VlYTg3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMwZTRlNjcwNDM1Mzg1NTU2ZTU5MzY1NzEzNTg0NWQzNmZiYjY5MzFmNzJiMDhjYjFlZDk1NGYxZTNjZTNmZjYnLFxuICAgICAgICAnNDYyZjliY2U2MTk4OTg2Mzg0OTkzNTAxMTNiYmM5YjEwYTg3OGQzNWRhNzA3NDBkYzY5NWE1NTllYjg4ZGI3YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiZTIwNjIwMDNjNTFjYzMwMDQ2ODI5MDQzMzBlNGRlZTdmM2RjZDEwYjAxZTU4MGJmMTk3MWIwNGQ0Y2FkMjk3JyxcbiAgICAgICAgJzYyMTg4YmM0OWQ2MWU1NDI4NTczZDQ4YTc0ZTFjNjU1YjFjNjEwOTA5MDU2ODJhMGQ1NTU4ZWQ3MmRjY2I5YmMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOTMxNDQ0MjNhY2UzNDUxZWQyOWUwZmI5YWMyYWYyMTFjYjZlODRhNjAxZGY1OTkzYzQxOTg1OWZmZjVkZjA0YScsXG4gICAgICAgICc3YzEwZGZiMTY0YzM0MjVmNWM3MWEzZjlkNzk5MjAzOGYxMDY1MjI0ZjcyYmI5ZDFkOTAyYTZkMTMwMzdiNDdjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2IwMTVmODA0NGY1ZmNiZGNmMjFjYTI2ZDZjMzRmYjgxOTc4MjkyMDVjN2I3ZDJhN2NiNjY0MThjMTU3YjExMmMnLFxuICAgICAgICAnYWI4YzFlMDg2ZDA0ZTgxMzc0NGE2NTViMmRmOGQ1ZjgzYjNjZGM2ZmFhMzA4OGMxZDNhZWExNDU0ZTNhMWQ1ZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkNWU5ZTFkYTY0OWQ5N2Q4OWU0ODY4MTE3YTQ2NWEzYTRmOGExOGRlNTdhMTQwZDM2YjNmMmFmMzQxYTIxYjUyJyxcbiAgICAgICAgJzRjYjA0NDM3ZjM5MWVkNzMxMTFhMTNjYzFkNGRkMGRiMTY5MzQ2NWMyMjQwNDgwZDg5NTVlODU5MmYyNzQ0N2EnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDNhZTQxMDQ3ZGQ3Y2EwNjVkYmY4ZWQ3N2I5OTI0Mzk5ODMwMDVjZDcyZTE2ZDZmOTk2YTUzMTZkMzY5NjZiYicsXG4gICAgICAgICdiZDFhZWIyMWFkMjJlYmIyMmExMGYwMzAzNDE3YzZkOTY0ZjhjZGQ3ZGYwYWNhNjE0YjEwZGMxNGQxMjVhYzQ2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzQ2M2UyNzYzZDg4NWY5NThmYzY2Y2RkMjI4MDBmMGE0ODcxOTdkMGE4MmUzNzdiNDlmODBhZjg3Yzg5N2IwNjUnLFxuICAgICAgICAnYmZlZmFjZGIwZTVkMGZkN2RmM2EzMTFhOTRkZTA2MmIyNmI4MGM2MWZiYzk3NTA4Yjc5OTkyNjcxZWY3Y2E3ZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3OTg1ZmRmZDEyN2MwNTY3YzZmNTNlYzFiYjYzZWMzMTU4ZTU5N2M0MGJmZTc0N2M4M2NkZGZjOTEwNjQxOTE3JyxcbiAgICAgICAgJzYwM2MxMmRhZjNkOTg2MmVmMmIyNWZlMWRlMjg5YWVkMjRlZDI5MWUwZWM2NzA4NzAzYTViZDU2N2YzMmVkMDMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzRhMWFkNmI1Zjc2ZTM5ZGIyZGQyNDk0MTBlYWM3Zjk5ZTc0YzU5Y2I4M2QyZDBlZDVmZjE1NDNkYTc3MDNlOScsXG4gICAgICAgICdjYzYxNTdlZjE4YzljNjNjZDYxOTNkODM2MzFiYmVhMDA5M2UwOTY4OTQyZThjMzNkNTczN2ZkNzkwZTBkYjA4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMwNjgyYTUwNzAzMzc1ZjYwMmQ0MTY2NjRiYTE5YjdmYzliYWI0MmM3Mjc0NzQ2M2E3MWQwODk2YjIyZjZkYTMnLFxuICAgICAgICAnNTUzZTA0ZjZiMDE4YjRmYTZjOGYzOWU3ZjMxMWQzMTc2MjkwZDBlMGYxOWNhNzNmMTc3MTRkOTk3N2EyMmZmOCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5ZTIxNThmMGQ3YzBkNWYyNmMzNzkxZWZlZmE3OTU5NzY1NGU3YTJiMjQ2NGY1MmIxZWU2YzEzNDc3NjllZjU3JyxcbiAgICAgICAgJzcxMmZjZGQxYjkwNTNmMDkwMDNhMzQ4MWZhNzc2MmU5ZmZkN2M4ZWYzNWEzODUwOWUyZmJmMjYyOTAwODM3MydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNzZlMjY5ODlhNDNjOWNmZWJhNDAyOWMyMDI1MzhjMjgxNzJlNTY2ZTNjNGZjZTczMjI4NTdmM2JlMzI3ZDY2JyxcbiAgICAgICAgJ2VkOGNjOWQwNGIyOWViODc3ZDI3MGI0ODc4ZGM0M2MxOWFlZmQzMWY0ZWVlMDllZTdiNDc4MzRjMWZhNGIxYzMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzVkNDZlZmVhMzc3MWU2ZTY4YWJiODlhMTNhZDc0N2VjZjE4OTIzOTNkZmM0ZjFiNzAwNDc4OGM1MDM3NGRhOCcsXG4gICAgICAgICc5ODUyMzkwYTk5NTA3Njc5ZmQwYjg2ZmQyYjM5YTg2OGQ3ZWZjMjIxNTEzNDZlMWEzY2E0NzI2NTg2YTZiZWQ4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzgwOWEyMGM2N2Q2NDkwMGZmYjY5OGM0YzgyNWY2ZDVmMjMxMGZiMDQ1MWM4NjkzNDViNzMxOWY2NDU2MDU3MjEnLFxuICAgICAgICAnOWU5OTQ5ODBkOTkxN2UyMmI3NmIwNjE5MjdmYTA0MTQzZDA5NmNjYzU0OTYzZTZhNWViZmE1ZjNmOGUyODZjMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxYjM4OTAzYTQzZjdmMTE0ZWQ0NTAwYjRlYWM3MDgzZmRlZmVjZTFjZjI5YzYzNTI4ZDU2MzQ0NmY5NzJjMTgwJyxcbiAgICAgICAgJzQwMzZlZGM5MzFhNjBhZTg4OTM1M2Y3N2ZkNTNkZTRhMjcwOGIyNmI2ZjVkYTcyYWQzMzk0MTE5ZGFmNDA4ZjknXG4gICAgICBdXG4gICAgXVxuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSBleHBvcnRzO1xudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcblxudXRpbHMuYXNzZXJ0ID0gZnVuY3Rpb24gYXNzZXJ0KHZhbCwgbXNnKSB7XG4gIGlmICghdmFsKVxuICAgIHRocm93IG5ldyBFcnJvcihtc2cgfHwgJ0Fzc2VydGlvbiBmYWlsZWQnKTtcbn07XG5cbmZ1bmN0aW9uIHRvQXJyYXkobXNnLCBlbmMpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkobXNnKSlcbiAgICByZXR1cm4gbXNnLnNsaWNlKCk7XG4gIGlmICghbXNnKVxuICAgIHJldHVybiBbXTtcbiAgdmFyIHJlcyA9IFtdO1xuICBpZiAodHlwZW9mIG1zZyAhPT0gJ3N0cmluZycpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKylcbiAgICAgIHJlc1tpXSA9IG1zZ1tpXSB8IDA7XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuICBpZiAoIWVuYykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgYyA9IG1zZy5jaGFyQ29kZUF0KGkpO1xuICAgICAgdmFyIGhpID0gYyA+PiA4O1xuICAgICAgdmFyIGxvID0gYyAmIDB4ZmY7XG4gICAgICBpZiAoaGkpXG4gICAgICAgIHJlcy5wdXNoKGhpLCBsbyk7XG4gICAgICBlbHNlXG4gICAgICAgIHJlcy5wdXNoKGxvKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoZW5jID09PSAnaGV4Jykge1xuICAgIG1zZyA9IG1zZy5yZXBsYWNlKC9bXmEtejAtOV0rL2lnLCAnJyk7XG4gICAgaWYgKG1zZy5sZW5ndGggJSAyICE9PSAwKVxuICAgICAgbXNnID0gJzAnICsgbXNnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSArPSAyKVxuICAgICAgcmVzLnB1c2gocGFyc2VJbnQobXNnW2ldICsgbXNnW2kgKyAxXSwgMTYpKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxudXRpbHMudG9BcnJheSA9IHRvQXJyYXk7XG5cbmZ1bmN0aW9uIHplcm8yKHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG51dGlscy56ZXJvMiA9IHplcm8yO1xuXG5mdW5jdGlvbiB0b0hleChtc2cpIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKylcbiAgICByZXMgKz0gemVybzIobXNnW2ldLnRvU3RyaW5nKDE2KSk7XG4gIHJldHVybiByZXM7XG59XG51dGlscy50b0hleCA9IHRvSGV4O1xuXG51dGlscy5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoYXJyLCBlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHRvSGV4KGFycik7XG4gIGVsc2VcbiAgICByZXR1cm4gYXJyO1xufTtcblxuLy8gUmVwcmVzZW50IG51bSBpbiBhIHctTkFGIGZvcm1cbmZ1bmN0aW9uIGdldE5BRihudW0sIHcpIHtcbiAgdmFyIG5hZiA9IFtdO1xuICB2YXIgd3MgPSAxIDw8ICh3ICsgMSk7XG4gIHZhciBrID0gbnVtLmNsb25lKCk7XG4gIHdoaWxlIChrLmNtcG4oMSkgPj0gMCkge1xuICAgIHZhciB6O1xuICAgIGlmIChrLmlzT2RkKCkpIHtcbiAgICAgIHZhciBtb2QgPSBrLmFuZGxuKHdzIC0gMSk7XG4gICAgICBpZiAobW9kID4gKHdzID4+IDEpIC0gMSlcbiAgICAgICAgeiA9ICh3cyA+PiAxKSAtIG1vZDtcbiAgICAgIGVsc2VcbiAgICAgICAgeiA9IG1vZDtcbiAgICAgIGsuaXN1Ym4oeik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHogPSAwO1xuICAgIH1cbiAgICBuYWYucHVzaCh6KTtcblxuICAgIC8vIE9wdGltaXphdGlvbiwgc2hpZnQgYnkgd29yZCBpZiBwb3NzaWJsZVxuICAgIHZhciBzaGlmdCA9IChrLmNtcG4oMCkgIT09IDAgJiYgay5hbmRsbih3cyAtIDEpID09PSAwKSA/ICh3ICsgMSkgOiAxO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgc2hpZnQ7IGkrKylcbiAgICAgIG5hZi5wdXNoKDApO1xuICAgIGsuaXVzaHJuKHNoaWZ0KTtcbiAgfVxuXG4gIHJldHVybiBuYWY7XG59XG51dGlscy5nZXROQUYgPSBnZXROQUY7XG5cbi8vIFJlcHJlc2VudCBrMSwgazIgaW4gYSBKb2ludCBTcGFyc2UgRm9ybVxuZnVuY3Rpb24gZ2V0SlNGKGsxLCBrMikge1xuICB2YXIganNmID0gW1xuICAgIFtdLFxuICAgIFtdXG4gIF07XG5cbiAgazEgPSBrMS5jbG9uZSgpO1xuICBrMiA9IGsyLmNsb25lKCk7XG4gIHZhciBkMSA9IDA7XG4gIHZhciBkMiA9IDA7XG4gIHdoaWxlIChrMS5jbXBuKC1kMSkgPiAwIHx8IGsyLmNtcG4oLWQyKSA+IDApIHtcblxuICAgIC8vIEZpcnN0IHBoYXNlXG4gICAgdmFyIG0xNCA9IChrMS5hbmRsbigzKSArIGQxKSAmIDM7XG4gICAgdmFyIG0yNCA9IChrMi5hbmRsbigzKSArIGQyKSAmIDM7XG4gICAgaWYgKG0xNCA9PT0gMylcbiAgICAgIG0xNCA9IC0xO1xuICAgIGlmIChtMjQgPT09IDMpXG4gICAgICBtMjQgPSAtMTtcbiAgICB2YXIgdTE7XG4gICAgaWYgKChtMTQgJiAxKSA9PT0gMCkge1xuICAgICAgdTEgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbTggPSAoazEuYW5kbG4oNykgKyBkMSkgJiA3O1xuICAgICAgaWYgKChtOCA9PT0gMyB8fCBtOCA9PT0gNSkgJiYgbTI0ID09PSAyKVxuICAgICAgICB1MSA9IC1tMTQ7XG4gICAgICBlbHNlXG4gICAgICAgIHUxID0gbTE0O1xuICAgIH1cbiAgICBqc2ZbMF0ucHVzaCh1MSk7XG5cbiAgICB2YXIgdTI7XG4gICAgaWYgKChtMjQgJiAxKSA9PT0gMCkge1xuICAgICAgdTIgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbTggPSAoazIuYW5kbG4oNykgKyBkMikgJiA3O1xuICAgICAgaWYgKChtOCA9PT0gMyB8fCBtOCA9PT0gNSkgJiYgbTE0ID09PSAyKVxuICAgICAgICB1MiA9IC1tMjQ7XG4gICAgICBlbHNlXG4gICAgICAgIHUyID0gbTI0O1xuICAgIH1cbiAgICBqc2ZbMV0ucHVzaCh1Mik7XG5cbiAgICAvLyBTZWNvbmQgcGhhc2VcbiAgICBpZiAoMiAqIGQxID09PSB1MSArIDEpXG4gICAgICBkMSA9IDEgLSBkMTtcbiAgICBpZiAoMiAqIGQyID09PSB1MiArIDEpXG4gICAgICBkMiA9IDEgLSBkMjtcbiAgICBrMS5pdXNocm4oMSk7XG4gICAgazIuaXVzaHJuKDEpO1xuICB9XG5cbiAgcmV0dXJuIGpzZjtcbn1cbnV0aWxzLmdldEpTRiA9IGdldEpTRjtcblxuZnVuY3Rpb24gY2FjaGVkUHJvcGVydHkob2JqLCBjb21wdXRlcikge1xuICB2YXIgbmFtZSA9IGNvbXB1dGVyLm5hbWU7XG4gIHZhciBrZXkgPSAnXycgKyBuYW1lO1xuICBvYmoucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24gY2FjaGVkUHJvcGVydHkoKSB7XG4gICAgcmV0dXJuIHRoaXNba2V5XSAhPT0gdW5kZWZpbmVkID8gdGhpc1trZXldIDpcbiAgICAgICAgICAgdGhpc1trZXldID0gY29tcHV0ZXIuY2FsbCh0aGlzKTtcbiAgfTtcbn1cbnV0aWxzLmNhY2hlZFByb3BlcnR5ID0gY2FjaGVkUHJvcGVydHk7XG5cbmZ1bmN0aW9uIHBhcnNlQnl0ZXMoYnl0ZXMpIHtcbiAgcmV0dXJuIHR5cGVvZiBieXRlcyA9PT0gJ3N0cmluZycgPyB1dGlscy50b0FycmF5KGJ5dGVzLCAnaGV4JykgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzO1xufVxudXRpbHMucGFyc2VCeXRlcyA9IHBhcnNlQnl0ZXM7XG5cbmZ1bmN0aW9uIGludEZyb21MRShieXRlcykge1xuICByZXR1cm4gbmV3IEJOKGJ5dGVzLCAnaGV4JywgJ2xlJyk7XG59XG51dGlscy5pbnRGcm9tTEUgPSBpbnRGcm9tTEU7XG5cbiIsInZhciByO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJhbmQobGVuKSB7XG4gIGlmICghcilcbiAgICByID0gbmV3IFJhbmQobnVsbCk7XG5cbiAgcmV0dXJuIHIuZ2VuZXJhdGUobGVuKTtcbn07XG5cbmZ1bmN0aW9uIFJhbmQocmFuZCkge1xuICB0aGlzLnJhbmQgPSByYW5kO1xufVxubW9kdWxlLmV4cG9ydHMuUmFuZCA9IFJhbmQ7XG5cblJhbmQucHJvdG90eXBlLmdlbmVyYXRlID0gZnVuY3Rpb24gZ2VuZXJhdGUobGVuKSB7XG4gIHJldHVybiB0aGlzLl9yYW5kKGxlbik7XG59O1xuXG5pZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHtcbiAgaWYgKHdpbmRvdy5jcnlwdG8gJiYgd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAvLyBNb2Rlcm4gYnJvd3NlcnNcbiAgICBSYW5kLnByb3RvdHlwZS5fcmFuZCA9IGZ1bmN0aW9uIF9yYW5kKG4pIHtcbiAgICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheShuKTtcbiAgICAgIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycik7XG4gICAgICByZXR1cm4gYXJyO1xuICAgIH07XG4gIH0gZWxzZSBpZiAod2luZG93Lm1zQ3J5cHRvICYmIHdpbmRvdy5tc0NyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAvLyBJRVxuICAgIFJhbmQucHJvdG90eXBlLl9yYW5kID0gZnVuY3Rpb24gX3JhbmQobikge1xuICAgICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KG4pO1xuICAgICAgd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyhhcnIpO1xuICAgICAgcmV0dXJuIGFycjtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIC8vIE9sZCBqdW5rXG4gICAgUmFuZC5wcm90b3R5cGUuX3JhbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkIHlldCcpO1xuICAgIH07XG4gIH1cbn0gZWxzZSB7XG4gIC8vIE5vZGUuanMgb3IgV2ViIHdvcmtlclxuICB0cnkge1xuICAgIHZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnknICsgJ3B0bycpO1xuXG4gICAgUmFuZC5wcm90b3R5cGUuX3JhbmQgPSBmdW5jdGlvbiBfcmFuZChuKSB7XG4gICAgICByZXR1cm4gY3J5cHRvLnJhbmRvbUJ5dGVzKG4pO1xuICAgIH07XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBFbXVsYXRlIGNyeXB0byBBUEkgdXNpbmcgcmFuZHlcbiAgICBSYW5kLnByb3RvdHlwZS5fcmFuZCA9IGZ1bmN0aW9uIF9yYW5kKG4pIHtcbiAgICAgIHZhciByZXMgPSBuZXcgVWludDhBcnJheShuKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKVxuICAgICAgICByZXNbaV0gPSB0aGlzLnJhbmQuZ2V0Qnl0ZSgpO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9O1xuICB9XG59XG4iLCJ2YXIgaGFzaCA9IGV4cG9ydHM7XG5cbmhhc2gudXRpbHMgPSByZXF1aXJlKCcuL2hhc2gvdXRpbHMnKTtcbmhhc2guY29tbW9uID0gcmVxdWlyZSgnLi9oYXNoL2NvbW1vbicpO1xuaGFzaC5zaGEgPSByZXF1aXJlKCcuL2hhc2gvc2hhJyk7XG5oYXNoLnJpcGVtZCA9IHJlcXVpcmUoJy4vaGFzaC9yaXBlbWQnKTtcbmhhc2guaG1hYyA9IHJlcXVpcmUoJy4vaGFzaC9obWFjJyk7XG5cbi8vIFByb3h5IGhhc2ggZnVuY3Rpb25zIHRvIHRoZSBtYWluIG9iamVjdFxuaGFzaC5zaGExID0gaGFzaC5zaGEuc2hhMTtcbmhhc2guc2hhMjU2ID0gaGFzaC5zaGEuc2hhMjU2O1xuaGFzaC5zaGEyMjQgPSBoYXNoLnNoYS5zaGEyMjQ7XG5oYXNoLnNoYTM4NCA9IGhhc2guc2hhLnNoYTM4NDtcbmhhc2guc2hhNTEyID0gaGFzaC5zaGEuc2hhNTEyO1xuaGFzaC5yaXBlbWQxNjAgPSBoYXNoLnJpcGVtZC5yaXBlbWQxNjA7XG4iLCJ2YXIgaGFzaCA9IHJlcXVpcmUoJy4uL2hhc2gnKTtcbnZhciB1dGlscyA9IGhhc2gudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBCbG9ja0hhc2goKSB7XG4gIHRoaXMucGVuZGluZyA9IG51bGw7XG4gIHRoaXMucGVuZGluZ1RvdGFsID0gMDtcbiAgdGhpcy5ibG9ja1NpemUgPSB0aGlzLmNvbnN0cnVjdG9yLmJsb2NrU2l6ZTtcbiAgdGhpcy5vdXRTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5vdXRTaXplO1xuICB0aGlzLmhtYWNTdHJlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IuaG1hY1N0cmVuZ3RoO1xuICB0aGlzLnBhZExlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IucGFkTGVuZ3RoIC8gODtcbiAgdGhpcy5lbmRpYW4gPSAnYmlnJztcblxuICB0aGlzLl9kZWx0YTggPSB0aGlzLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMuX2RlbHRhMzIgPSB0aGlzLmJsb2NrU2l6ZSAvIDMyO1xufVxuZXhwb3J0cy5CbG9ja0hhc2ggPSBCbG9ja0hhc2g7XG5cbkJsb2NrSGFzaC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIC8vIENvbnZlcnQgbWVzc2FnZSB0byBhcnJheSwgcGFkIGl0LCBhbmQgam9pbiBpbnRvIDMyYml0IGJsb2Nrc1xuICBtc2cgPSB1dGlscy50b0FycmF5KG1zZywgZW5jKTtcbiAgaWYgKCF0aGlzLnBlbmRpbmcpXG4gICAgdGhpcy5wZW5kaW5nID0gbXNnO1xuICBlbHNlXG4gICAgdGhpcy5wZW5kaW5nID0gdGhpcy5wZW5kaW5nLmNvbmNhdChtc2cpO1xuICB0aGlzLnBlbmRpbmdUb3RhbCArPSBtc2cubGVuZ3RoO1xuXG4gIC8vIEVub3VnaCBkYXRhLCB0cnkgdXBkYXRpbmdcbiAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPj0gdGhpcy5fZGVsdGE4KSB7XG4gICAgbXNnID0gdGhpcy5wZW5kaW5nO1xuXG4gICAgLy8gUHJvY2VzcyBwZW5kaW5nIGRhdGEgaW4gYmxvY2tzXG4gICAgdmFyIHIgPSBtc2cubGVuZ3RoICUgdGhpcy5fZGVsdGE4O1xuICAgIHRoaXMucGVuZGluZyA9IG1zZy5zbGljZShtc2cubGVuZ3RoIC0gciwgbXNnLmxlbmd0aCk7XG4gICAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLnBlbmRpbmcgPSBudWxsO1xuXG4gICAgbXNnID0gdXRpbHMuam9pbjMyKG1zZywgMCwgbXNnLmxlbmd0aCAtIHIsIHRoaXMuZW5kaWFuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkgKz0gdGhpcy5fZGVsdGEzMilcbiAgICAgIHRoaXMuX3VwZGF0ZShtc2csIGksIGkgKyB0aGlzLl9kZWx0YTMyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMudXBkYXRlKHRoaXMuX3BhZCgpKTtcbiAgYXNzZXJ0KHRoaXMucGVuZGluZyA9PT0gbnVsbCk7XG5cbiAgcmV0dXJuIHRoaXMuX2RpZ2VzdChlbmMpO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gcGFkKCkge1xuICB2YXIgbGVuID0gdGhpcy5wZW5kaW5nVG90YWw7XG4gIHZhciBieXRlcyA9IHRoaXMuX2RlbHRhODtcbiAgdmFyIGsgPSBieXRlcyAtICgobGVuICsgdGhpcy5wYWRMZW5ndGgpICUgYnl0ZXMpO1xuICB2YXIgcmVzID0gbmV3IEFycmF5KGsgKyB0aGlzLnBhZExlbmd0aCk7XG4gIHJlc1swXSA9IDB4ODA7XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgazsgaSsrKVxuICAgIHJlc1tpXSA9IDA7XG5cbiAgLy8gQXBwZW5kIGxlbmd0aFxuICBsZW4gPDw9IDM7XG4gIGlmICh0aGlzLmVuZGlhbiA9PT0gJ2JpZycpIHtcbiAgICBmb3IgKHZhciB0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG5cbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAyNCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDgpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IGxlbiAmIDB4ZmY7XG4gIH0gZWxzZSB7XG4gICAgcmVzW2krK10gPSBsZW4gJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gOCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDI0KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuXG4gICAgZm9yICh2YXIgdCA9IDg7IHQgPCB0aGlzLnBhZExlbmd0aDsgdCsrKVxuICAgICAgcmVzW2krK10gPSAwO1xuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG4iLCJ2YXIgaG1hYyA9IGV4cG9ydHM7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnLi4vaGFzaCcpO1xudmFyIHV0aWxzID0gaGFzaC51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbmZ1bmN0aW9uIEhtYWMoaGFzaCwga2V5LCBlbmMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEhtYWMpKVxuICAgIHJldHVybiBuZXcgSG1hYyhoYXNoLCBrZXksIGVuYyk7XG4gIHRoaXMuSGFzaCA9IGhhc2g7XG4gIHRoaXMuYmxvY2tTaXplID0gaGFzaC5ibG9ja1NpemUgLyA4O1xuICB0aGlzLm91dFNpemUgPSBoYXNoLm91dFNpemUgLyA4O1xuICB0aGlzLmlubmVyID0gbnVsbDtcbiAgdGhpcy5vdXRlciA9IG51bGw7XG5cbiAgdGhpcy5faW5pdCh1dGlscy50b0FycmF5KGtleSwgZW5jKSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEhtYWM7XG5cbkhtYWMucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gaW5pdChrZXkpIHtcbiAgLy8gU2hvcnRlbiBrZXksIGlmIG5lZWRlZFxuICBpZiAoa2V5Lmxlbmd0aCA+IHRoaXMuYmxvY2tTaXplKVxuICAgIGtleSA9IG5ldyB0aGlzLkhhc2goKS51cGRhdGUoa2V5KS5kaWdlc3QoKTtcbiAgYXNzZXJ0KGtleS5sZW5ndGggPD0gdGhpcy5ibG9ja1NpemUpO1xuXG4gIC8vIEFkZCBwYWRkaW5nIHRvIGtleVxuICBmb3IgKHZhciBpID0ga2V5Lmxlbmd0aDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAga2V5LnB1c2goMCk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXkubGVuZ3RoOyBpKyspXG4gICAga2V5W2ldIF49IDB4MzY7XG4gIHRoaXMuaW5uZXIgPSBuZXcgdGhpcy5IYXNoKCkudXBkYXRlKGtleSk7XG5cbiAgLy8gMHgzNiBeIDB4NWMgPSAweDZhXG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDZhO1xuICB0aGlzLm91dGVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xufTtcblxuSG1hYy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIHRoaXMuaW5uZXIudXBkYXRlKG1zZywgZW5jKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5IbWFjLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMub3V0ZXIudXBkYXRlKHRoaXMuaW5uZXIuZGlnZXN0KCkpO1xuICByZXR1cm4gdGhpcy5vdXRlci5kaWdlc3QoZW5jKTtcbn07XG4iLCJ2YXIgaGFzaCA9IHJlcXVpcmUoJy4uL2hhc2gnKTtcbnZhciB1dGlscyA9IGhhc2gudXRpbHM7XG5cbnZhciByb3RsMzIgPSB1dGlscy5yb3RsMzI7XG52YXIgc3VtMzIgPSB1dGlscy5zdW0zMjtcbnZhciBzdW0zMl8zID0gdXRpbHMuc3VtMzJfMztcbnZhciBzdW0zMl80ID0gdXRpbHMuc3VtMzJfNDtcbnZhciBCbG9ja0hhc2ggPSBoYXNoLmNvbW1vbi5CbG9ja0hhc2g7XG5cbmZ1bmN0aW9uIFJJUEVNRDE2MCgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJJUEVNRDE2MCkpXG4gICAgcmV0dXJuIG5ldyBSSVBFTUQxNjAoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcblxuICB0aGlzLmggPSBbIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5lbmRpYW4gPSAnbGl0dGxlJztcbn1cbnV0aWxzLmluaGVyaXRzKFJJUEVNRDE2MCwgQmxvY2tIYXNoKTtcbmV4cG9ydHMucmlwZW1kMTYwID0gUklQRU1EMTYwO1xuXG5SSVBFTUQxNjAuYmxvY2tTaXplID0gNTEyO1xuUklQRU1EMTYwLm91dFNpemUgPSAxNjA7XG5SSVBFTUQxNjAuaG1hY1N0cmVuZ3RoID0gMTkyO1xuUklQRU1EMTYwLnBhZExlbmd0aCA9IDY0O1xuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgQSA9IHRoaXMuaFswXTtcbiAgdmFyIEIgPSB0aGlzLmhbMV07XG4gIHZhciBDID0gdGhpcy5oWzJdO1xuICB2YXIgRCA9IHRoaXMuaFszXTtcbiAgdmFyIEUgPSB0aGlzLmhbNF07XG4gIHZhciBBaCA9IEE7XG4gIHZhciBCaCA9IEI7XG4gIHZhciBDaCA9IEM7XG4gIHZhciBEaCA9IEQ7XG4gIHZhciBFaCA9IEU7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7IGorKykge1xuICAgIHZhciBUID0gc3VtMzIoXG4gICAgICByb3RsMzIoXG4gICAgICAgIHN1bTMyXzQoQSwgZihqLCBCLCBDLCBEKSwgbXNnW3Jbal0gKyBzdGFydF0sIEsoaikpLFxuICAgICAgICBzW2pdKSxcbiAgICAgIEUpO1xuICAgIEEgPSBFO1xuICAgIEUgPSBEO1xuICAgIEQgPSByb3RsMzIoQywgMTApO1xuICAgIEMgPSBCO1xuICAgIEIgPSBUO1xuICAgIFQgPSBzdW0zMihcbiAgICAgIHJvdGwzMihcbiAgICAgICAgc3VtMzJfNChBaCwgZig3OSAtIGosIEJoLCBDaCwgRGgpLCBtc2dbcmhbal0gKyBzdGFydF0sIEtoKGopKSxcbiAgICAgICAgc2hbal0pLFxuICAgICAgRWgpO1xuICAgIEFoID0gRWg7XG4gICAgRWggPSBEaDtcbiAgICBEaCA9IHJvdGwzMihDaCwgMTApO1xuICAgIENoID0gQmg7XG4gICAgQmggPSBUO1xuICB9XG4gIFQgPSBzdW0zMl8zKHRoaXMuaFsxXSwgQywgRGgpO1xuICB0aGlzLmhbMV0gPSBzdW0zMl8zKHRoaXMuaFsyXSwgRCwgRWgpO1xuICB0aGlzLmhbMl0gPSBzdW0zMl8zKHRoaXMuaFszXSwgRSwgQWgpO1xuICB0aGlzLmhbM10gPSBzdW0zMl8zKHRoaXMuaFs0XSwgQSwgQmgpO1xuICB0aGlzLmhbNF0gPSBzdW0zMl8zKHRoaXMuaFswXSwgQiwgQ2gpO1xuICB0aGlzLmhbMF0gPSBUO1xufTtcblxuUklQRU1EMTYwLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdsaXR0bGUnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2xpdHRsZScpO1xufTtcblxuZnVuY3Rpb24gZihqLCB4LCB5LCB6KSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiB4IF4geSBeIHo7XG4gIGVsc2UgaWYgKGogPD0gMzEpXG4gICAgcmV0dXJuICh4ICYgeSkgfCAoKH54KSAmIHopO1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAoeCB8ICh+eSkpIF4gejtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gKHggJiB6KSB8ICh5ICYgKH56KSk7XG4gIGVsc2VcbiAgICByZXR1cm4geCBeICh5IHwgKH56KSk7XG59XG5cbmZ1bmN0aW9uIEsoaikge1xuICBpZiAoaiA8PSAxNSlcbiAgICByZXR1cm4gMHgwMDAwMDAwMDtcbiAgZWxzZSBpZiAoaiA8PSAzMSlcbiAgICByZXR1cm4gMHg1YTgyNzk5OTtcbiAgZWxzZSBpZiAoaiA8PSA0NylcbiAgICByZXR1cm4gMHg2ZWQ5ZWJhMTtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gMHg4ZjFiYmNkYztcbiAgZWxzZVxuICAgIHJldHVybiAweGE5NTNmZDRlO1xufVxuXG5mdW5jdGlvbiBLaChqKSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiAweDUwYTI4YmU2O1xuICBlbHNlIGlmIChqIDw9IDMxKVxuICAgIHJldHVybiAweDVjNGRkMTI0O1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAweDZkNzAzZWYzO1xuICBlbHNlIGlmIChqIDw9IDYzKVxuICAgIHJldHVybiAweDdhNmQ3NmU5O1xuICBlbHNlXG4gICAgcmV0dXJuIDB4MDAwMDAwMDA7XG59XG5cbnZhciByID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dO1xuXG52YXIgcmggPSBbXG4gIDUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsXG4gIDYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDIsXG4gIDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTMsXG4gIDgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTQsXG4gIDEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFcbl07XG5cbnZhciBzID0gW1xuICAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDgsXG4gIDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMixcbiAgMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1LFxuICAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTIsXG4gIDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuXTtcblxudmFyIHNoID0gW1xuICA4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDYsXG4gIDksIDEzLCAxNSwgNywgMTIsIDgsIDksIDExLCA3LCA3LCAxMiwgNywgNiwgMTUsIDEzLCAxMSxcbiAgOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1LFxuICAxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDgsXG4gIDgsIDUsIDEyLCA5LCAxMiwgNSwgMTQsIDYsIDgsIDEzLCA2LCA1LCAxNSwgMTMsIDExLCAxMVxuXTtcbiIsInZhciBoYXNoID0gcmVxdWlyZSgnLi4vaGFzaCcpO1xudmFyIHV0aWxzID0gaGFzaC51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbnZhciByb3RyMzIgPSB1dGlscy5yb3RyMzI7XG52YXIgcm90bDMyID0gdXRpbHMucm90bDMyO1xudmFyIHN1bTMyID0gdXRpbHMuc3VtMzI7XG52YXIgc3VtMzJfNCA9IHV0aWxzLnN1bTMyXzQ7XG52YXIgc3VtMzJfNSA9IHV0aWxzLnN1bTMyXzU7XG52YXIgcm90cjY0X2hpID0gdXRpbHMucm90cjY0X2hpO1xudmFyIHJvdHI2NF9sbyA9IHV0aWxzLnJvdHI2NF9sbztcbnZhciBzaHI2NF9oaSA9IHV0aWxzLnNocjY0X2hpO1xudmFyIHNocjY0X2xvID0gdXRpbHMuc2hyNjRfbG87XG52YXIgc3VtNjQgPSB1dGlscy5zdW02NDtcbnZhciBzdW02NF9oaSA9IHV0aWxzLnN1bTY0X2hpO1xudmFyIHN1bTY0X2xvID0gdXRpbHMuc3VtNjRfbG87XG52YXIgc3VtNjRfNF9oaSA9IHV0aWxzLnN1bTY0XzRfaGk7XG52YXIgc3VtNjRfNF9sbyA9IHV0aWxzLnN1bTY0XzRfbG87XG52YXIgc3VtNjRfNV9oaSA9IHV0aWxzLnN1bTY0XzVfaGk7XG52YXIgc3VtNjRfNV9sbyA9IHV0aWxzLnN1bTY0XzVfbG87XG52YXIgQmxvY2tIYXNoID0gaGFzaC5jb21tb24uQmxvY2tIYXNoO1xuXG52YXIgc2hhMjU2X0sgPSBbXG4gIDB4NDI4YTJmOTgsIDB4NzEzNzQ0OTEsIDB4YjVjMGZiY2YsIDB4ZTliNWRiYTUsXG4gIDB4Mzk1NmMyNWIsIDB4NTlmMTExZjEsIDB4OTIzZjgyYTQsIDB4YWIxYzVlZDUsXG4gIDB4ZDgwN2FhOTgsIDB4MTI4MzViMDEsIDB4MjQzMTg1YmUsIDB4NTUwYzdkYzMsXG4gIDB4NzJiZTVkNzQsIDB4ODBkZWIxZmUsIDB4OWJkYzA2YTcsIDB4YzE5YmYxNzQsXG4gIDB4ZTQ5YjY5YzEsIDB4ZWZiZTQ3ODYsIDB4MGZjMTlkYzYsIDB4MjQwY2ExY2MsXG4gIDB4MmRlOTJjNmYsIDB4NGE3NDg0YWEsIDB4NWNiMGE5ZGMsIDB4NzZmOTg4ZGEsXG4gIDB4OTgzZTUxNTIsIDB4YTgzMWM2NmQsIDB4YjAwMzI3YzgsIDB4YmY1OTdmYzcsXG4gIDB4YzZlMDBiZjMsIDB4ZDVhNzkxNDcsIDB4MDZjYTYzNTEsIDB4MTQyOTI5NjcsXG4gIDB4MjdiNzBhODUsIDB4MmUxYjIxMzgsIDB4NGQyYzZkZmMsIDB4NTMzODBkMTMsXG4gIDB4NjUwYTczNTQsIDB4NzY2YTBhYmIsIDB4ODFjMmM5MmUsIDB4OTI3MjJjODUsXG4gIDB4YTJiZmU4YTEsIDB4YTgxYTY2NGIsIDB4YzI0YjhiNzAsIDB4Yzc2YzUxYTMsXG4gIDB4ZDE5MmU4MTksIDB4ZDY5OTA2MjQsIDB4ZjQwZTM1ODUsIDB4MTA2YWEwNzAsXG4gIDB4MTlhNGMxMTYsIDB4MWUzNzZjMDgsIDB4Mjc0ODc3NGMsIDB4MzRiMGJjYjUsXG4gIDB4MzkxYzBjYjMsIDB4NGVkOGFhNGEsIDB4NWI5Y2NhNGYsIDB4NjgyZTZmZjMsXG4gIDB4NzQ4ZjgyZWUsIDB4NzhhNTYzNmYsIDB4ODRjODc4MTQsIDB4OGNjNzAyMDgsXG4gIDB4OTBiZWZmZmEsIDB4YTQ1MDZjZWIsIDB4YmVmOWEzZjcsIDB4YzY3MTc4ZjJcbl07XG5cbnZhciBzaGE1MTJfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXTtcblxudmFyIHNoYTFfSyA9IFtcbiAgMHg1QTgyNzk5OSwgMHg2RUQ5RUJBMSxcbiAgMHg4RjFCQkNEQywgMHhDQTYyQzFENlxuXTtcblxuZnVuY3Rpb24gU0hBMjU2KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMjU2KSlcbiAgICByZXR1cm4gbmV3IFNIQTI1NigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbIDB4NmEwOWU2NjcsIDB4YmI2N2FlODUsIDB4M2M2ZWYzNzIsIDB4YTU0ZmY1M2EsXG4gICAgICAgICAgICAgMHg1MTBlNTI3ZiwgMHg5YjA1Njg4YywgMHgxZjgzZDlhYiwgMHg1YmUwY2QxOSBdO1xuICB0aGlzLmsgPSBzaGEyNTZfSztcbiAgdGhpcy5XID0gbmV3IEFycmF5KDY0KTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTI1NiwgQmxvY2tIYXNoKTtcbmV4cG9ydHMuc2hhMjU2ID0gU0hBMjU2O1xuXG5TSEEyNTYuYmxvY2tTaXplID0gNTEyO1xuU0hBMjU2Lm91dFNpemUgPSAyNTY7XG5TSEEyNTYuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMjU2LnBhZExlbmd0aCA9IDY0O1xuXG5TSEEyNTYucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiBfdXBkYXRlKG1zZywgc3RhcnQpIHtcbiAgdmFyIFcgPSB0aGlzLlc7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKVxuICAgIFdbaV0gPSBtc2dbc3RhcnQgKyBpXTtcbiAgZm9yICg7IGkgPCBXLmxlbmd0aDsgaSsrKVxuICAgIFdbaV0gPSBzdW0zMl80KGcxXzI1NihXW2kgLSAyXSksIFdbaSAtIDddLCBnMF8yNTYoV1tpIC0gMTVdKSwgV1tpIC0gMTZdKTtcblxuICB2YXIgYSA9IHRoaXMuaFswXTtcbiAgdmFyIGIgPSB0aGlzLmhbMV07XG4gIHZhciBjID0gdGhpcy5oWzJdO1xuICB2YXIgZCA9IHRoaXMuaFszXTtcbiAgdmFyIGUgPSB0aGlzLmhbNF07XG4gIHZhciBmID0gdGhpcy5oWzVdO1xuICB2YXIgZyA9IHRoaXMuaFs2XTtcbiAgdmFyIGggPSB0aGlzLmhbN107XG5cbiAgYXNzZXJ0KHRoaXMuay5sZW5ndGggPT09IFcubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIFQxID0gc3VtMzJfNShoLCBzMV8yNTYoZSksIGNoMzIoZSwgZiwgZyksIHRoaXMua1tpXSwgV1tpXSk7XG4gICAgdmFyIFQyID0gc3VtMzIoczBfMjU2KGEpLCBtYWozMihhLCBiLCBjKSk7XG4gICAgaCA9IGc7XG4gICAgZyA9IGY7XG4gICAgZiA9IGU7XG4gICAgZSA9IHN1bTMyKGQsIFQxKTtcbiAgICBkID0gYztcbiAgICBjID0gYjtcbiAgICBiID0gYTtcbiAgICBhID0gc3VtMzIoVDEsIFQyKTtcbiAgfVxuXG4gIHRoaXMuaFswXSA9IHN1bTMyKHRoaXMuaFswXSwgYSk7XG4gIHRoaXMuaFsxXSA9IHN1bTMyKHRoaXMuaFsxXSwgYik7XG4gIHRoaXMuaFsyXSA9IHN1bTMyKHRoaXMuaFsyXSwgYyk7XG4gIHRoaXMuaFszXSA9IHN1bTMyKHRoaXMuaFszXSwgZCk7XG4gIHRoaXMuaFs0XSA9IHN1bTMyKHRoaXMuaFs0XSwgZSk7XG4gIHRoaXMuaFs1XSA9IHN1bTMyKHRoaXMuaFs1XSwgZik7XG4gIHRoaXMuaFs2XSA9IHN1bTMyKHRoaXMuaFs2XSwgZyk7XG4gIHRoaXMuaFs3XSA9IHN1bTMyKHRoaXMuaFs3XSwgaCk7XG59O1xuXG5TSEEyNTYucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaCwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLCAnYmlnJyk7XG59O1xuXG5mdW5jdGlvbiBTSEEyMjQoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEyMjQpKVxuICAgIHJldHVybiBuZXcgU0hBMjI0KCk7XG5cbiAgU0hBMjU2LmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFsgMHhjMTA1OWVkOCwgMHgzNjdjZDUwNywgMHgzMDcwZGQxNywgMHhmNzBlNTkzOSxcbiAgICAgICAgICAgICAweGZmYzAwYjMxLCAweDY4NTgxNTExLCAweDY0Zjk4ZmE3LCAweGJlZmE0ZmE0IF07XG59XG51dGlscy5pbmhlcml0cyhTSEEyMjQsIFNIQTI1Nik7XG5leHBvcnRzLnNoYTIyNCA9IFNIQTIyNDtcblxuU0hBMjI0LmJsb2NrU2l6ZSA9IDUxMjtcblNIQTIyNC5vdXRTaXplID0gMjI0O1xuU0hBMjI0LmhtYWNTdHJlbmd0aCA9IDE5MjtcblNIQTIyNC5wYWRMZW5ndGggPSA2NDtcblxuU0hBMjI0LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICAvLyBKdXN0IHRydW5jYXRlIG91dHB1dFxuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmguc2xpY2UoMCwgNyksICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaC5zbGljZSgwLCA3KSwgJ2JpZycpO1xufTtcblxuZnVuY3Rpb24gU0hBNTEyKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBNTEyKSlcbiAgICByZXR1cm4gbmV3IFNIQTUxMigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbIDB4NmEwOWU2NjcsIDB4ZjNiY2M5MDgsXG4gICAgICAgICAgICAgMHhiYjY3YWU4NSwgMHg4NGNhYTczYixcbiAgICAgICAgICAgICAweDNjNmVmMzcyLCAweGZlOTRmODJiLFxuICAgICAgICAgICAgIDB4YTU0ZmY1M2EsIDB4NWYxZDM2ZjEsXG4gICAgICAgICAgICAgMHg1MTBlNTI3ZiwgMHhhZGU2ODJkMSxcbiAgICAgICAgICAgICAweDliMDU2ODhjLCAweDJiM2U2YzFmLFxuICAgICAgICAgICAgIDB4MWY4M2Q5YWIsIDB4ZmI0MWJkNmIsXG4gICAgICAgICAgICAgMHg1YmUwY2QxOSwgMHgxMzdlMjE3OSBdO1xuICB0aGlzLmsgPSBzaGE1MTJfSztcbiAgdGhpcy5XID0gbmV3IEFycmF5KDE2MCk7XG59XG51dGlscy5pbmhlcml0cyhTSEE1MTIsIEJsb2NrSGFzaCk7XG5leHBvcnRzLnNoYTUxMiA9IFNIQTUxMjtcblxuU0hBNTEyLmJsb2NrU2l6ZSA9IDEwMjQ7XG5TSEE1MTIub3V0U2l6ZSA9IDUxMjtcblNIQTUxMi5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEE1MTIucGFkTGVuZ3RoID0gMTI4O1xuXG5TSEE1MTIucHJvdG90eXBlLl9wcmVwYXJlQmxvY2sgPSBmdW5jdGlvbiBfcHJlcGFyZUJsb2NrKG1zZywgc3RhcnQpIHtcbiAgdmFyIFcgPSB0aGlzLlc7XG5cbiAgLy8gMzIgeCAzMmJpdCB3b3Jkc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuICBmb3IgKDsgaSA8IFcubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIgYzBfaGkgPSBnMV81MTJfaGkoV1tpIC0gNF0sIFdbaSAtIDNdKTsgIC8vIGkgLSAyXG4gICAgdmFyIGMwX2xvID0gZzFfNTEyX2xvKFdbaSAtIDRdLCBXW2kgLSAzXSk7XG4gICAgdmFyIGMxX2hpID0gV1tpIC0gMTRdOyAgLy8gaSAtIDdcbiAgICB2YXIgYzFfbG8gPSBXW2kgLSAxM107XG4gICAgdmFyIGMyX2hpID0gZzBfNTEyX2hpKFdbaSAtIDMwXSwgV1tpIC0gMjldKTsgIC8vIGkgLSAxNVxuICAgIHZhciBjMl9sbyA9IGcwXzUxMl9sbyhXW2kgLSAzMF0sIFdbaSAtIDI5XSk7XG4gICAgdmFyIGMzX2hpID0gV1tpIC0gMzJdOyAgLy8gaSAtIDE2XG4gICAgdmFyIGMzX2xvID0gV1tpIC0gMzFdO1xuXG4gICAgV1tpXSA9IHN1bTY0XzRfaGkoYzBfaGksIGMwX2xvLFxuICAgICAgICAgICAgICAgICAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgICAgICAgICAgICAgICAgICBjMl9oaSwgYzJfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgYzNfaGksIGMzX2xvKTtcbiAgICBXW2kgKyAxXSA9IHN1bTY0XzRfbG8oYzBfaGksIGMwX2xvLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBjMV9oaSwgYzFfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYzNfaGksIGMzX2xvKTtcbiAgfVxufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHRoaXMuX3ByZXBhcmVCbG9jayhtc2csIHN0YXJ0KTtcblxuICB2YXIgVyA9IHRoaXMuVztcblxuICB2YXIgYWggPSB0aGlzLmhbMF07XG4gIHZhciBhbCA9IHRoaXMuaFsxXTtcbiAgdmFyIGJoID0gdGhpcy5oWzJdO1xuICB2YXIgYmwgPSB0aGlzLmhbM107XG4gIHZhciBjaCA9IHRoaXMuaFs0XTtcbiAgdmFyIGNsID0gdGhpcy5oWzVdO1xuICB2YXIgZGggPSB0aGlzLmhbNl07XG4gIHZhciBkbCA9IHRoaXMuaFs3XTtcbiAgdmFyIGVoID0gdGhpcy5oWzhdO1xuICB2YXIgZWwgPSB0aGlzLmhbOV07XG4gIHZhciBmaCA9IHRoaXMuaFsxMF07XG4gIHZhciBmbCA9IHRoaXMuaFsxMV07XG4gIHZhciBnaCA9IHRoaXMuaFsxMl07XG4gIHZhciBnbCA9IHRoaXMuaFsxM107XG4gIHZhciBoaCA9IHRoaXMuaFsxNF07XG4gIHZhciBobCA9IHRoaXMuaFsxNV07XG5cbiAgYXNzZXJ0KHRoaXMuay5sZW5ndGggPT09IFcubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIGMwX2hpID0gaGg7XG4gICAgdmFyIGMwX2xvID0gaGw7XG4gICAgdmFyIGMxX2hpID0gczFfNTEyX2hpKGVoLCBlbCk7XG4gICAgdmFyIGMxX2xvID0gczFfNTEyX2xvKGVoLCBlbCk7XG4gICAgdmFyIGMyX2hpID0gY2g2NF9oaShlaCwgZWwsIGZoLCBmbCwgZ2gsIGdsKTtcbiAgICB2YXIgYzJfbG8gPSBjaDY0X2xvKGVoLCBlbCwgZmgsIGZsLCBnaCwgZ2wpO1xuICAgIHZhciBjM19oaSA9IHRoaXMua1tpXTtcbiAgICB2YXIgYzNfbG8gPSB0aGlzLmtbaSArIDFdO1xuICAgIHZhciBjNF9oaSA9IFdbaV07XG4gICAgdmFyIGM0X2xvID0gV1tpICsgMV07XG5cbiAgICB2YXIgVDFfaGkgPSBzdW02NF81X2hpKGMwX2hpLCBjMF9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMzX2hpLCBjM19sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGM0X2hpLCBjNF9sbyk7XG4gICAgdmFyIFQxX2xvID0gc3VtNjRfNV9sbyhjMF9oaSwgYzBfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjMV9oaSwgYzFfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjMl9oaSwgYzJfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjM19oaSwgYzNfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjNF9oaSwgYzRfbG8pO1xuXG4gICAgdmFyIGMwX2hpID0gczBfNTEyX2hpKGFoLCBhbCk7XG4gICAgdmFyIGMwX2xvID0gczBfNTEyX2xvKGFoLCBhbCk7XG4gICAgdmFyIGMxX2hpID0gbWFqNjRfaGkoYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCk7XG4gICAgdmFyIGMxX2xvID0gbWFqNjRfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCk7XG5cbiAgICB2YXIgVDJfaGkgPSBzdW02NF9oaShjMF9oaSwgYzBfbG8sIGMxX2hpLCBjMV9sbyk7XG4gICAgdmFyIFQyX2xvID0gc3VtNjRfbG8oYzBfaGksIGMwX2xvLCBjMV9oaSwgYzFfbG8pO1xuXG4gICAgaGggPSBnaDtcbiAgICBobCA9IGdsO1xuXG4gICAgZ2ggPSBmaDtcbiAgICBnbCA9IGZsO1xuXG4gICAgZmggPSBlaDtcbiAgICBmbCA9IGVsO1xuXG4gICAgZWggPSBzdW02NF9oaShkaCwgZGwsIFQxX2hpLCBUMV9sbyk7XG4gICAgZWwgPSBzdW02NF9sbyhkbCwgZGwsIFQxX2hpLCBUMV9sbyk7XG5cbiAgICBkaCA9IGNoO1xuICAgIGRsID0gY2w7XG5cbiAgICBjaCA9IGJoO1xuICAgIGNsID0gYmw7XG5cbiAgICBiaCA9IGFoO1xuICAgIGJsID0gYWw7XG5cbiAgICBhaCA9IHN1bTY0X2hpKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgICBhbCA9IHN1bTY0X2xvKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgfVxuXG4gIHN1bTY0KHRoaXMuaCwgMCwgYWgsIGFsKTtcbiAgc3VtNjQodGhpcy5oLCAyLCBiaCwgYmwpO1xuICBzdW02NCh0aGlzLmgsIDQsIGNoLCBjbCk7XG4gIHN1bTY0KHRoaXMuaCwgNiwgZGgsIGRsKTtcbiAgc3VtNjQodGhpcy5oLCA4LCBlaCwgZWwpO1xuICBzdW02NCh0aGlzLmgsIDEwLCBmaCwgZmwpO1xuICBzdW02NCh0aGlzLmgsIDEyLCBnaCwgZ2wpO1xuICBzdW02NCh0aGlzLmgsIDE0LCBoaCwgaGwpO1xufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcblxuZnVuY3Rpb24gU0hBMzg0KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMzg0KSlcbiAgICByZXR1cm4gbmV3IFNIQTM4NCgpO1xuXG4gIFNIQTUxMi5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbIDB4Y2JiYjlkNWQsIDB4YzEwNTllZDgsXG4gICAgICAgICAgICAgMHg2MjlhMjkyYSwgMHgzNjdjZDUwNyxcbiAgICAgICAgICAgICAweDkxNTkwMTVhLCAweDMwNzBkZDE3LFxuICAgICAgICAgICAgIDB4MTUyZmVjZDgsIDB4ZjcwZTU5MzksXG4gICAgICAgICAgICAgMHg2NzMzMjY2NywgMHhmZmMwMGIzMSxcbiAgICAgICAgICAgICAweDhlYjQ0YTg3LCAweDY4NTgxNTExLFxuICAgICAgICAgICAgIDB4ZGIwYzJlMGQsIDB4NjRmOThmYTcsXG4gICAgICAgICAgICAgMHg0N2I1NDgxZCwgMHhiZWZhNGZhNCBdO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBMzg0LCBTSEE1MTIpO1xuZXhwb3J0cy5zaGEzODQgPSBTSEEzODQ7XG5cblNIQTM4NC5ibG9ja1NpemUgPSAxMDI0O1xuU0hBMzg0Lm91dFNpemUgPSAzODQ7XG5TSEEzODQuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMzg0LnBhZExlbmd0aCA9IDEyODtcblxuU0hBMzg0LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmguc2xpY2UoMCwgMTIpLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmguc2xpY2UoMCwgMTIpLCAnYmlnJyk7XG59O1xuXG5mdW5jdGlvbiBTSEExKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMSkpXG4gICAgcmV0dXJuIG5ldyBTSEExKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFsgMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSwgMHg5OGJhZGNmZSxcbiAgICAgICAgICAgICAweDEwMzI1NDc2LCAweGMzZDJlMWYwIF07XG4gIHRoaXMuVyA9IG5ldyBBcnJheSg4MCk7XG59XG5cbnV0aWxzLmluaGVyaXRzKFNIQTEsIEJsb2NrSGFzaCk7XG5leHBvcnRzLnNoYTEgPSBTSEExO1xuXG5TSEExLmJsb2NrU2l6ZSA9IDUxMjtcblNIQTEub3V0U2l6ZSA9IDE2MDtcblNIQTEuaG1hY1N0cmVuZ3RoID0gODA7XG5TSEExLnBhZExlbmd0aCA9IDY0O1xuXG5TSEExLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHZhciBXID0gdGhpcy5XO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKylcbiAgICBXW2ldID0gbXNnW3N0YXJ0ICsgaV07XG5cbiAgZm9yKDsgaSA8IFcubGVuZ3RoOyBpKyspXG4gICAgV1tpXSA9IHJvdGwzMihXW2kgLSAzXSBeIFdbaSAtIDhdIF4gV1tpIC0gMTRdIF4gV1tpIC0gMTZdLCAxKTtcblxuICB2YXIgYSA9IHRoaXMuaFswXTtcbiAgdmFyIGIgPSB0aGlzLmhbMV07XG4gIHZhciBjID0gdGhpcy5oWzJdO1xuICB2YXIgZCA9IHRoaXMuaFszXTtcbiAgdmFyIGUgPSB0aGlzLmhbNF07XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHMgPSB+fihpIC8gMjApO1xuICAgIHZhciB0ID0gc3VtMzJfNShyb3RsMzIoYSwgNSksIGZ0XzEocywgYiwgYywgZCksIGUsIFdbaV0sIHNoYTFfS1tzXSk7XG4gICAgZSA9IGQ7XG4gICAgZCA9IGM7XG4gICAgYyA9IHJvdGwzMihiLCAzMCk7XG4gICAgYiA9IGE7XG4gICAgYSA9IHQ7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xufTtcblxuU0hBMS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdiaWcnKTtcbn07XG5cbmZ1bmN0aW9uIGNoMzIoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSBeICgofngpICYgeik7XG59XG5cbmZ1bmN0aW9uIG1hajMyKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbn1cblxuZnVuY3Rpb24gcDMyKHgsIHksIHopIHtcbiAgcmV0dXJuIHggXiB5IF4gejtcbn1cblxuZnVuY3Rpb24gczBfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCAyKSBeIHJvdHIzMih4LCAxMykgXiByb3RyMzIoeCwgMjIpO1xufVxuXG5mdW5jdGlvbiBzMV8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDYpIF4gcm90cjMyKHgsIDExKSBeIHJvdHIzMih4LCAyNSk7XG59XG5cbmZ1bmN0aW9uIGcwXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgNykgXiByb3RyMzIoeCwgMTgpIF4gKHggPj4+IDMpO1xufVxuXG5mdW5jdGlvbiBnMV8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDE3KSBeIHJvdHIzMih4LCAxOSkgXiAoeCA+Pj4gMTApO1xufVxuXG5mdW5jdGlvbiBmdF8xKHMsIHgsIHksIHopIHtcbiAgaWYgKHMgPT09IDApXG4gICAgcmV0dXJuIGNoMzIoeCwgeSwgeik7XG4gIGlmIChzID09PSAxIHx8IHMgPT09IDMpXG4gICAgcmV0dXJuIHAzMih4LCB5LCB6KTtcbiAgaWYgKHMgPT09IDIpXG4gICAgcmV0dXJuIG1hajMyKHgsIHksIHopO1xufVxuXG5mdW5jdGlvbiBjaDY0X2hpKHhoLCB4bCwgeWgsIHlsLCB6aCwgemwpIHtcbiAgdmFyIHIgPSAoeGggJiB5aCkgXiAoKH54aCkgJiB6aCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gY2g2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKCh+eGwpICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIG1hajY0X2hpKHhoLCB4bCwgeWgsIHlsLCB6aCwgemwpIHtcbiAgdmFyIHIgPSAoeGggJiB5aCkgXiAoeGggJiB6aCkgXiAoeWggJiB6aCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gbWFqNjRfbG8oeGgsIHhsLCB5aCwgeWwsIHpoLCB6bCkge1xuICB2YXIgciA9ICh4bCAmIHlsKSBeICh4bCAmIHpsKSBeICh5bCAmIHpsKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMF81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDI4KTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgMik7ICAvLyAzNFxuICB2YXIgYzJfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCA3KTsgIC8vIDM5XG5cbiAgdmFyIHIgPSBjMF9oaSBeIGMxX2hpIF4gYzJfaGk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczBfNTEyX2xvKHhoLCB4bCkge1xuICB2YXIgYzBfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAyOCk7XG4gIHZhciBjMV9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDIpOyAgLy8gMzRcbiAgdmFyIGMyX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgNyk7ICAvLyAzOVxuXG4gIHZhciByID0gYzBfbG8gXiBjMV9sbyBeIGMyX2xvO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMxXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMTQpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxOCk7XG4gIHZhciBjMl9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDkpOyAgLy8gNDFcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMV81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDE0KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMTgpO1xuICB2YXIgYzJfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCA5KTsgIC8vIDQxXG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzBfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxKTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgOCk7XG4gIHZhciBjMl9oaSA9IHNocjY0X2hpKHhoLCB4bCwgNyk7XG5cbiAgdmFyIHIgPSBjMF9oaSBeIGMxX2hpIF4gYzJfaGk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzBfNTEyX2xvKHhoLCB4bCkge1xuICB2YXIgYzBfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxKTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgOCk7XG4gIHZhciBjMl9sbyA9IHNocjY0X2xvKHhoLCB4bCwgNyk7XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzFfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxOSk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDI5KTsgIC8vIDYxXG4gIHZhciBjMl9oaSA9IHNocjY0X2hpKHhoLCB4bCwgNik7XG5cbiAgdmFyIHIgPSBjMF9oaSBeIGMxX2hpIF4gYzJfaGk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzFfNTEyX2xvKHhoLCB4bCkge1xuICB2YXIgYzBfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxOSk7XG4gIHZhciBjMV9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDI5KTsgIC8vIDYxXG4gIHZhciBjMl9sbyA9IHNocjY0X2xvKHhoLCB4bCwgNik7XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cbiIsInZhciB1dGlscyA9IGV4cG9ydHM7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG5mdW5jdGlvbiB0b0FycmF5KG1zZywgZW5jKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG1zZykpXG4gICAgcmV0dXJuIG1zZy5zbGljZSgpO1xuICBpZiAoIW1zZylcbiAgICByZXR1cm4gW107XG4gIHZhciByZXMgPSBbXTtcbiAgaWYgKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCFlbmMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIHZhciBoaSA9IGMgPj4gODtcbiAgICAgICAgdmFyIGxvID0gYyAmIDB4ZmY7XG4gICAgICAgIGlmIChoaSlcbiAgICAgICAgICByZXMucHVzaChoaSwgbG8pO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgcmVzLnB1c2gobG8pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZW5jID09PSAnaGV4Jykge1xuICAgICAgbXNnID0gbXNnLnJlcGxhY2UoL1teYS16MC05XSsvaWcsICcnKTtcbiAgICAgIGlmIChtc2cubGVuZ3RoICUgMiAhPT0gMClcbiAgICAgICAgbXNnID0gJzAnICsgbXNnO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpICs9IDIpXG4gICAgICAgIHJlcy5wdXNoKHBhcnNlSW50KG1zZ1tpXSArIG1zZ1tpICsgMV0sIDE2KSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxudXRpbHMudG9BcnJheSA9IHRvQXJyYXk7XG5cbmZ1bmN0aW9uIHRvSGV4KG1zZykge1xuICB2YXIgcmVzID0gJyc7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgIHJlcyArPSB6ZXJvMihtc2dbaV0udG9TdHJpbmcoMTYpKTtcbiAgcmV0dXJuIHJlcztcbn1cbnV0aWxzLnRvSGV4ID0gdG9IZXg7XG5cbmZ1bmN0aW9uIGh0b25sKHcpIHtcbiAgdmFyIHJlcyA9ICh3ID4+PiAyNCkgfFxuICAgICAgICAgICAgKCh3ID4+PiA4KSAmIDB4ZmYwMCkgfFxuICAgICAgICAgICAgKCh3IDw8IDgpICYgMHhmZjAwMDApIHxcbiAgICAgICAgICAgICgodyAmIDB4ZmYpIDw8IDI0KTtcbiAgcmV0dXJuIHJlcyA+Pj4gMDtcbn1cbnV0aWxzLmh0b25sID0gaHRvbmw7XG5cbmZ1bmN0aW9uIHRvSGV4MzIobXNnLCBlbmRpYW4pIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB3ID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdsaXR0bGUnKVxuICAgICAgdyA9IGh0b25sKHcpO1xuICAgIHJlcyArPSB6ZXJvOCh3LnRvU3RyaW5nKDE2KSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbnV0aWxzLnRvSGV4MzIgPSB0b0hleDMyO1xuXG5mdW5jdGlvbiB6ZXJvMih3b3JkKSB7XG4gIGlmICh3b3JkLmxlbmd0aCA9PT0gMSlcbiAgICByZXR1cm4gJzAnICsgd29yZDtcbiAgZWxzZVxuICAgIHJldHVybiB3b3JkO1xufVxudXRpbHMuemVybzIgPSB6ZXJvMjtcblxuZnVuY3Rpb24gemVybzgod29yZCkge1xuICBpZiAod29yZC5sZW5ndGggPT09IDcpXG4gICAgcmV0dXJuICcwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA2KVxuICAgIHJldHVybiAnMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDUpXG4gICAgcmV0dXJuICcwMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDQpXG4gICAgcmV0dXJuICcwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAzKVxuICAgIHJldHVybiAnMDAwMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDIpXG4gICAgcmV0dXJuICcwMDAwMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDEpXG4gICAgcmV0dXJuICcwMDAwMDAwJyArIHdvcmQ7XG4gIGVsc2VcbiAgICByZXR1cm4gd29yZDtcbn1cbnV0aWxzLnplcm84ID0gemVybzg7XG5cbmZ1bmN0aW9uIGpvaW4zMihtc2csIHN0YXJ0LCBlbmQsIGVuZGlhbikge1xuICB2YXIgbGVuID0gZW5kIC0gc3RhcnQ7XG4gIGFzc2VydChsZW4gJSA0ID09PSAwKTtcbiAgdmFyIHJlcyA9IG5ldyBBcnJheShsZW4gLyA0KTtcbiAgZm9yICh2YXIgaSA9IDAsIGsgPSBzdGFydDsgaSA8IHJlcy5sZW5ndGg7IGkrKywgayArPSA0KSB7XG4gICAgdmFyIHc7XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2JpZycpXG4gICAgICB3ID0gKG1zZ1trXSA8PCAyNCkgfCAobXNnW2sgKyAxXSA8PCAxNikgfCAobXNnW2sgKyAyXSA8PCA4KSB8IG1zZ1trICsgM107XG4gICAgZWxzZVxuICAgICAgdyA9IChtc2dbayArIDNdIDw8IDI0KSB8IChtc2dbayArIDJdIDw8IDE2KSB8IChtc2dbayArIDFdIDw8IDgpIHwgbXNnW2tdO1xuICAgIHJlc1tpXSA9IHcgPj4+IDA7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbnV0aWxzLmpvaW4zMiA9IGpvaW4zMjtcblxuZnVuY3Rpb24gc3BsaXQzMihtc2csIGVuZGlhbikge1xuICB2YXIgcmVzID0gbmV3IEFycmF5KG1zZy5sZW5ndGggKiA0KTtcbiAgZm9yICh2YXIgaSA9IDAsIGsgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrLCBrICs9IDQpIHtcbiAgICB2YXIgbSA9IG1zZ1tpXTtcbiAgICBpZiAoZW5kaWFuID09PSAnYmlnJykge1xuICAgICAgcmVzW2tdID0gbSA+Pj4gMjQ7XG4gICAgICByZXNbayArIDFdID0gKG0gPj4+IDE2KSAmIDB4ZmY7XG4gICAgICByZXNbayArIDJdID0gKG0gPj4+IDgpICYgMHhmZjtcbiAgICAgIHJlc1trICsgM10gPSBtICYgMHhmZjtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzW2sgKyAzXSA9IG0gPj4+IDI0O1xuICAgICAgcmVzW2sgKyAyXSA9IChtID4+PiAxNikgJiAweGZmO1xuICAgICAgcmVzW2sgKyAxXSA9IChtID4+PiA4KSAmIDB4ZmY7XG4gICAgICByZXNba10gPSBtICYgMHhmZjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbnV0aWxzLnNwbGl0MzIgPSBzcGxpdDMyO1xuXG5mdW5jdGlvbiByb3RyMzIodywgYikge1xuICByZXR1cm4gKHcgPj4+IGIpIHwgKHcgPDwgKDMyIC0gYikpO1xufVxudXRpbHMucm90cjMyID0gcm90cjMyO1xuXG5mdW5jdGlvbiByb3RsMzIodywgYikge1xuICByZXR1cm4gKHcgPDwgYikgfCAodyA+Pj4gKDMyIC0gYikpO1xufVxudXRpbHMucm90bDMyID0gcm90bDMyO1xuXG5mdW5jdGlvbiBzdW0zMihhLCBiKSB7XG4gIHJldHVybiAoYSArIGIpID4+PiAwO1xufVxudXRpbHMuc3VtMzIgPSBzdW0zMjtcblxuZnVuY3Rpb24gc3VtMzJfMyhhLCBiLCBjKSB7XG4gIHJldHVybiAoYSArIGIgKyBjKSA+Pj4gMDtcbn1cbnV0aWxzLnN1bTMyXzMgPSBzdW0zMl8zO1xuXG5mdW5jdGlvbiBzdW0zMl80KGEsIGIsIGMsIGQpIHtcbiAgcmV0dXJuIChhICsgYiArIGMgKyBkKSA+Pj4gMDtcbn1cbnV0aWxzLnN1bTMyXzQgPSBzdW0zMl80O1xuXG5mdW5jdGlvbiBzdW0zMl81KGEsIGIsIGMsIGQsIGUpIHtcbiAgcmV0dXJuIChhICsgYiArIGMgKyBkICsgZSkgPj4+IDA7XG59XG51dGlscy5zdW0zMl81ID0gc3VtMzJfNTtcblxuZnVuY3Rpb24gYXNzZXJ0KGNvbmQsIG1zZykge1xuICBpZiAoIWNvbmQpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAnQXNzZXJ0aW9uIGZhaWxlZCcpO1xufVxudXRpbHMuYXNzZXJ0ID0gYXNzZXJ0O1xuXG51dGlscy5pbmhlcml0cyA9IGluaGVyaXRzO1xuXG5mdW5jdGlvbiBzdW02NChidWYsIHBvcywgYWgsIGFsKSB7XG4gIHZhciBiaCA9IGJ1Zltwb3NdO1xuICB2YXIgYmwgPSBidWZbcG9zICsgMV07XG5cbiAgdmFyIGxvID0gKGFsICsgYmwpID4+PiAwO1xuICB2YXIgaGkgPSAobG8gPCBhbCA/IDEgOiAwKSArIGFoICsgYmg7XG4gIGJ1Zltwb3NdID0gaGkgPj4+IDA7XG4gIGJ1Zltwb3MgKyAxXSA9IGxvO1xufVxuZXhwb3J0cy5zdW02NCA9IHN1bTY0O1xuXG5mdW5jdGlvbiBzdW02NF9oaShhaCwgYWwsIGJoLCBibCkge1xuICB2YXIgbG8gPSAoYWwgKyBibCkgPj4+IDA7XG4gIHZhciBoaSA9IChsbyA8IGFsID8gMSA6IDApICsgYWggKyBiaDtcbiAgcmV0dXJuIGhpID4+PiAwO1xufTtcbmV4cG9ydHMuc3VtNjRfaGkgPSBzdW02NF9oaTtcblxuZnVuY3Rpb24gc3VtNjRfbG8oYWgsIGFsLCBiaCwgYmwpIHtcbiAgdmFyIGxvID0gYWwgKyBibDtcbiAgcmV0dXJuIGxvID4+PiAwO1xufTtcbmV4cG9ydHMuc3VtNjRfbG8gPSBzdW02NF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNF9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBjYXJyeTtcbiAgcmV0dXJuIGhpID4+PiAwO1xufTtcbmV4cG9ydHMuc3VtNjRfNF9oaSA9IHN1bTY0XzRfaGk7XG5cbmZ1bmN0aW9uIHN1bTY0XzRfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCwgZGgsIGRsKSB7XG4gIHZhciBsbyA9IGFsICsgYmwgKyBjbCArIGRsO1xuICByZXR1cm4gbG8gPj4+IDA7XG59O1xuZXhwb3J0cy5zdW02NF80X2xvID0gc3VtNjRfNF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNV9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwsIGVoLCBlbCkge1xuICB2YXIgY2FycnkgPSAwO1xuICB2YXIgbG8gPSBhbDtcbiAgbG8gPSAobG8gKyBibCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgYWwgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBjbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgY2wgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBkbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgZGwgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBlbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgZWwgPyAxIDogMDtcblxuICB2YXIgaGkgPSBhaCArIGJoICsgY2ggKyBkaCArIGVoICsgY2Fycnk7XG4gIHJldHVybiBoaSA+Pj4gMDtcbn07XG5leHBvcnRzLnN1bTY0XzVfaGkgPSBzdW02NF81X2hpO1xuXG5mdW5jdGlvbiBzdW02NF81X2xvKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCwgZWgsIGVsKSB7XG4gIHZhciBsbyA9IGFsICsgYmwgKyBjbCArIGRsICsgZWw7XG5cbiAgcmV0dXJuIGxvID4+PiAwO1xufTtcbmV4cG9ydHMuc3VtNjRfNV9sbyA9IHN1bTY0XzVfbG87XG5cbmZ1bmN0aW9uIHJvdHI2NF9oaShhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhbCA8PCAoMzIgLSBudW0pKSB8IChhaCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59O1xuZXhwb3J0cy5yb3RyNjRfaGkgPSByb3RyNjRfaGk7XG5cbmZ1bmN0aW9uIHJvdHI2NF9sbyhhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhaCA8PCAoMzIgLSBudW0pKSB8IChhbCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59O1xuZXhwb3J0cy5yb3RyNjRfbG8gPSByb3RyNjRfbG87XG5cbmZ1bmN0aW9uIHNocjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHJldHVybiBhaCA+Pj4gbnVtO1xufTtcbmV4cG9ydHMuc2hyNjRfaGkgPSBzaHI2NF9oaTtcblxuZnVuY3Rpb24gc2hyNjRfbG8oYWgsIGFsLCBudW0pIHtcbiAgdmFyIHIgPSAoYWggPDwgKDMyIC0gbnVtKSkgfCAoYWwgPj4+IG51bSk7XG4gIHJldHVybiByID4+PiAwO1xufTtcbmV4cG9ydHMuc2hyNjRfbG8gPSBzaHI2NF9sbztcbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJuYW1lXCI6IFwiZWxsaXB0aWNcIixcbiAgXCJ2ZXJzaW9uXCI6IFwiNi4yLjNcIixcbiAgXCJkZXNjcmlwdGlvblwiOiBcIkVDIGNyeXB0b2dyYXBoeVwiLFxuICBcIm1haW5cIjogXCJsaWIvZWxsaXB0aWMuanNcIixcbiAgXCJmaWxlc1wiOiBbXG4gICAgXCJsaWJcIlxuICBdLFxuICBcInNjcmlwdHNcIjoge1xuICAgIFwiY292ZXJhZ2VcIjogXCJucG0gcnVuIHVuaXQgLS1jb3ZlcmFnZVwiLFxuICAgIFwiY292ZXJhbGxzXCI6IFwibnBtIHJ1biBjb3ZlcmFnZSAmJiBjYXQgLi9jb3ZlcmFnZS9sY292LmluZm8gfCBjb3ZlcmFsbHNcIixcbiAgICBcImpzY3NcIjogXCJqc2NzIGJlbmNobWFya3MvKi5qcyBsaWIvKi5qcyBsaWIvKiovKi5qcyBsaWIvKiovKiovKi5qcyB0ZXN0LyouanNcIixcbiAgICBcImpzaGludFwiOiBcImpzY3MgYmVuY2htYXJrcy8qLmpzIGxpYi8qLmpzIGxpYi8qKi8qLmpzIGxpYi8qKi8qKi8qLmpzIHRlc3QvKi5qc1wiLFxuICAgIFwibGludFwiOiBcIm5wbSBydW4ganNjcyAmJiBucG0gcnVuIGpzaGludFwiLFxuICAgIFwidGVzdFwiOiBcIm5wbSBydW4gbGludCAmJiBucG0gcnVuIHVuaXRcIixcbiAgICBcInVuaXRcIjogXCJpc3RhbmJ1bCB0ZXN0IF9tb2NoYSAtLXJlcG9ydGVyPXNwZWMgdGVzdC8qLXRlc3QuanNcIlxuICB9LFxuICBcInJlcG9zaXRvcnlcIjoge1xuICAgIFwidHlwZVwiOiBcImdpdFwiLFxuICAgIFwidXJsXCI6IFwiZ2l0K3NzaDovL2dpdEBnaXRodWIuY29tL2luZHV0bnkvZWxsaXB0aWMuZ2l0XCJcbiAgfSxcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJFQ1wiLFxuICAgIFwiRWxsaXB0aWNcIixcbiAgICBcImN1cnZlXCIsXG4gICAgXCJDcnlwdG9ncmFwaHlcIlxuICBdLFxuICBcImF1dGhvclwiOiB7XG4gICAgXCJuYW1lXCI6IFwiRmVkb3IgSW5kdXRueVwiLFxuICAgIFwiZW1haWxcIjogXCJmZWRvckBpbmR1dG55LmNvbVwiXG4gIH0sXG4gIFwibGljZW5zZVwiOiBcIk1JVFwiLFxuICBcImJ1Z3NcIjoge1xuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2luZHV0bnkvZWxsaXB0aWMvaXNzdWVzXCJcbiAgfSxcbiAgXCJob21lcGFnZVwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9pbmR1dG55L2VsbGlwdGljXCIsXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcImNvdmVyYWxsc1wiOiBcIl4yLjExLjNcIixcbiAgICBcImlzdGFuYnVsXCI6IFwiXjAuNC4yXCIsXG4gICAgXCJqc2NzXCI6IFwiXjIuOS4wXCIsXG4gICAgXCJqc2hpbnRcIjogXCJeMi42LjBcIixcbiAgICBcIm1vY2hhXCI6IFwiXjIuMS4wXCJcbiAgfSxcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiYm4uanNcIjogXCJeNC4wLjBcIixcbiAgICBcImJyb3JhbmRcIjogXCJeMS4wLjFcIixcbiAgICBcImhhc2guanNcIjogXCJeMS4wLjBcIixcbiAgICBcImluaGVyaXRzXCI6IFwiXjIuMC4xXCJcbiAgfSxcbiAgXCJnaXRIZWFkXCI6IFwiYzMyZjIwYjIyYjQyMGViNmFmM2M2ZGRhMjg5NjNkZWI3ZmFjZjgyM1wiLFxuICBcIl9pZFwiOiBcImVsbGlwdGljQDYuMi4zXCIsXG4gIFwiX3NoYXN1bVwiOiBcIjE4ZTQ2ZDczMDZiMDk1MTI3NWEyZDQyMDYzMjcwYTE0Yjc0ZWJlOTlcIixcbiAgXCJfZnJvbVwiOiBcImVsbGlwdGljQF42LjAuMFwiLFxuICBcIl9ucG1WZXJzaW9uXCI6IFwiMy4zLjEyXCIsXG4gIFwiX25vZGVWZXJzaW9uXCI6IFwiNS40LjFcIixcbiAgXCJfbnBtVXNlclwiOiB7XG4gICAgXCJuYW1lXCI6IFwiaW5kdXRueVwiLFxuICAgIFwiZW1haWxcIjogXCJmZWRvckBpbmR1dG55LmNvbVwiXG4gIH0sXG4gIFwiZGlzdFwiOiB7XG4gICAgXCJzaGFzdW1cIjogXCIxOGU0NmQ3MzA2YjA5NTEyNzVhMmQ0MjA2MzI3MGExNGI3NGViZTk5XCIsXG4gICAgXCJ0YXJiYWxsXCI6IFwiaHR0cDovL3JlZ2lzdHJ5Lm5wbWpzLm9yZy9lbGxpcHRpYy8tL2VsbGlwdGljLTYuMi4zLnRnelwiXG4gIH0sXG4gIFwibWFpbnRhaW5lcnNcIjogW1xuICAgIHtcbiAgICAgIFwibmFtZVwiOiBcImluZHV0bnlcIixcbiAgICAgIFwiZW1haWxcIjogXCJmZWRvckBpbmR1dG55LmNvbVwiXG4gICAgfVxuICBdLFxuICBcImRpcmVjdG9yaWVzXCI6IHt9LFxuICBcIl9yZXNvbHZlZFwiOiBcImh0dHBzOi8vcmVnaXN0cnkubnBtanMub3JnL2VsbGlwdGljLy0vZWxsaXB0aWMtNi4yLjMudGd6XCIsXG4gIFwicmVhZG1lXCI6IFwiRVJST1I6IE5vIFJFQURNRSBkYXRhIGZvdW5kIVwiXG59XG4iLCJtb2R1bGUuZXhwb3J0cz17XCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4xXCI6IFwiYWVzLTEyOC1lY2JcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuMlwiOiBcImFlcy0xMjgtY2JjXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjNcIjogXCJhZXMtMTI4LW9mYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS40XCI6IFwiYWVzLTEyOC1jZmJcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuMjFcIjogXCJhZXMtMTkyLWVjYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yMlwiOiBcImFlcy0xOTItY2JjXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjIzXCI6IFwiYWVzLTE5Mi1vZmJcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuMjRcIjogXCJhZXMtMTkyLWNmYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS40MVwiOiBcImFlcy0yNTYtZWNiXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjQyXCI6IFwiYWVzLTI1Ni1jYmNcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuNDNcIjogXCJhZXMtMjU2LW9mYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS40NFwiOiBcImFlcy0yNTYtY2ZiXCJcbn0iLCIvLyBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9pbmR1dG55L3NlbGYtc2lnbmVkL2Jsb2IvZ2gtcGFnZXMvbGliL2FzbjEuanNcbi8vIEZlZG9yLCB5b3UgYXJlIGFtYXppbmcuXG5cbnZhciBhc24xID0gcmVxdWlyZSgnYXNuMS5qcycpXG5cbnZhciBSU0FQcml2YXRlS2V5ID0gYXNuMS5kZWZpbmUoJ1JTQVByaXZhdGVLZXknLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCd2ZXJzaW9uJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ21vZHVsdXMnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHVibGljRXhwb25lbnQnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHJpdmF0ZUV4cG9uZW50JykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3ByaW1lMScpLmludCgpLFxuICAgIHRoaXMua2V5KCdwcmltZTInKS5pbnQoKSxcbiAgICB0aGlzLmtleSgnZXhwb25lbnQxJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ2V4cG9uZW50MicpLmludCgpLFxuICAgIHRoaXMua2V5KCdjb2VmZmljaWVudCcpLmludCgpXG4gIClcbn0pXG5leHBvcnRzLlJTQVByaXZhdGVLZXkgPSBSU0FQcml2YXRlS2V5XG5cbnZhciBSU0FQdWJsaWNLZXkgPSBhc24xLmRlZmluZSgnUlNBUHVibGljS2V5JywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgnbW9kdWx1cycpLmludCgpLFxuICAgIHRoaXMua2V5KCdwdWJsaWNFeHBvbmVudCcpLmludCgpXG4gIClcbn0pXG5leHBvcnRzLlJTQVB1YmxpY0tleSA9IFJTQVB1YmxpY0tleVxuXG52YXIgUHVibGljS2V5ID0gYXNuMS5kZWZpbmUoJ1N1YmplY3RQdWJsaWNLZXlJbmZvJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgnYWxnb3JpdGhtJykudXNlKEFsZ29yaXRobUlkZW50aWZpZXIpLFxuICAgIHRoaXMua2V5KCdzdWJqZWN0UHVibGljS2V5JykuYml0c3RyKClcbiAgKVxufSlcbmV4cG9ydHMuUHVibGljS2V5ID0gUHVibGljS2V5XG5cbnZhciBBbGdvcml0aG1JZGVudGlmaWVyID0gYXNuMS5kZWZpbmUoJ0FsZ29yaXRobUlkZW50aWZpZXInLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdhbGdvcml0aG0nKS5vYmppZCgpLFxuICAgIHRoaXMua2V5KCdub25lJykubnVsbF8oKS5vcHRpb25hbCgpLFxuICAgIHRoaXMua2V5KCdjdXJ2ZScpLm9iamlkKCkub3B0aW9uYWwoKSxcbiAgICB0aGlzLmtleSgncGFyYW1zJykuc2VxKCkub2JqKFxuICAgICAgdGhpcy5rZXkoJ3AnKS5pbnQoKSxcbiAgICAgIHRoaXMua2V5KCdxJykuaW50KCksXG4gICAgICB0aGlzLmtleSgnZycpLmludCgpXG4gICAgKS5vcHRpb25hbCgpXG4gIClcbn0pXG5cbnZhciBQcml2YXRlS2V5SW5mbyA9IGFzbjEuZGVmaW5lKCdQcml2YXRlS2V5SW5mbycsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ3ZlcnNpb24nKS5pbnQoKSxcbiAgICB0aGlzLmtleSgnYWxnb3JpdGhtJykudXNlKEFsZ29yaXRobUlkZW50aWZpZXIpLFxuICAgIHRoaXMua2V5KCdzdWJqZWN0UHJpdmF0ZUtleScpLm9jdHN0cigpXG4gIClcbn0pXG5leHBvcnRzLlByaXZhdGVLZXkgPSBQcml2YXRlS2V5SW5mb1xudmFyIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvID0gYXNuMS5kZWZpbmUoJ0VuY3J5cHRlZFByaXZhdGVLZXlJbmZvJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgnYWxnb3JpdGhtJykuc2VxKCkub2JqKFxuICAgICAgdGhpcy5rZXkoJ2lkJykub2JqaWQoKSxcbiAgICAgIHRoaXMua2V5KCdkZWNyeXB0Jykuc2VxKCkub2JqKFxuICAgICAgICB0aGlzLmtleSgna2RlJykuc2VxKCkub2JqKFxuICAgICAgICAgIHRoaXMua2V5KCdpZCcpLm9iamlkKCksXG4gICAgICAgICAgdGhpcy5rZXkoJ2tkZXBhcmFtcycpLnNlcSgpLm9iaihcbiAgICAgICAgICAgIHRoaXMua2V5KCdzYWx0Jykub2N0c3RyKCksXG4gICAgICAgICAgICB0aGlzLmtleSgnaXRlcnMnKS5pbnQoKVxuICAgICAgICAgIClcbiAgICAgICAgKSxcbiAgICAgICAgdGhpcy5rZXkoJ2NpcGhlcicpLnNlcSgpLm9iaihcbiAgICAgICAgICB0aGlzLmtleSgnYWxnbycpLm9iamlkKCksXG4gICAgICAgICAgdGhpcy5rZXkoJ2l2Jykub2N0c3RyKClcbiAgICAgICAgKVxuICAgICAgKVxuICAgICksXG4gICAgdGhpcy5rZXkoJ3N1YmplY3RQcml2YXRlS2V5Jykub2N0c3RyKClcbiAgKVxufSlcblxuZXhwb3J0cy5FbmNyeXB0ZWRQcml2YXRlS2V5ID0gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm9cblxudmFyIERTQVByaXZhdGVLZXkgPSBhc24xLmRlZmluZSgnRFNBUHJpdmF0ZUtleScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ3ZlcnNpb24nKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncCcpLmludCgpLFxuICAgIHRoaXMua2V5KCdxJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ2cnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHViX2tleScpLmludCgpLFxuICAgIHRoaXMua2V5KCdwcml2X2tleScpLmludCgpXG4gIClcbn0pXG5leHBvcnRzLkRTQVByaXZhdGVLZXkgPSBEU0FQcml2YXRlS2V5XG5cbmV4cG9ydHMuRFNBcGFyYW0gPSBhc24xLmRlZmluZSgnRFNBcGFyYW0nLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuaW50KClcbn0pXG52YXIgRUNQcml2YXRlS2V5ID0gYXNuMS5kZWZpbmUoJ0VDUHJpdmF0ZUtleScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ3ZlcnNpb24nKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHJpdmF0ZUtleScpLm9jdHN0cigpLFxuICAgIHRoaXMua2V5KCdwYXJhbWV0ZXJzJykub3B0aW9uYWwoKS5leHBsaWNpdCgwKS51c2UoRUNQYXJhbWV0ZXJzKSxcbiAgICB0aGlzLmtleSgncHVibGljS2V5Jykub3B0aW9uYWwoKS5leHBsaWNpdCgxKS5iaXRzdHIoKVxuICApXG59KVxuZXhwb3J0cy5FQ1ByaXZhdGVLZXkgPSBFQ1ByaXZhdGVLZXlcbnZhciBFQ1BhcmFtZXRlcnMgPSBhc24xLmRlZmluZSgnRUNQYXJhbWV0ZXJzJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLmNob2ljZSh7XG4gICAgbmFtZWRDdXJ2ZTogdGhpcy5vYmppZCgpXG4gIH0pXG59KVxuXG5leHBvcnRzLnNpZ25hdHVyZSA9IGFzbjEuZGVmaW5lKCdzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdyJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3MnKS5pbnQoKVxuICApXG59KVxuIiwiLy8gYWRhcHRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9hcGF0aWwvcGVtc3RyaXBcbnZhciBmaW5kUHJvYyA9IC9Qcm9jLVR5cGU6IDQsRU5DUllQVEVEXFxyP1xcbkRFSy1JbmZvOiBBRVMtKCg/OjEyOCl8KD86MTkyKXwoPzoyNTYpKS1DQkMsKFswLTlBLUhdKylcXHI/XFxuXFxyP1xcbihbMC05QS16XFxuXFxyXFwrXFwvXFw9XSspXFxyP1xcbi9tXG52YXIgc3RhcnRSZWdleCA9IC9eLS0tLS1CRUdJTiAoLiopIEtFWS0tLS0tXFxyP1xcbi9tXG52YXIgZnVsbFJlZ2V4ID0gL14tLS0tLUJFR0lOICguKikgS0VZLS0tLS1cXHI/XFxuKFswLTlBLXpcXG5cXHJcXCtcXC9cXD1dKylcXHI/XFxuLS0tLS1FTkQgXFwxIEtFWS0tLS0tJC9tXG52YXIgZXZwID0gcmVxdWlyZSgnZXZwX2J5dGVzdG9rZXknKVxudmFyIGNpcGhlcnMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWFlcycpXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChva2V5LCBwYXNzd29yZCkge1xuICB2YXIga2V5ID0gb2tleS50b1N0cmluZygpXG4gIHZhciBtYXRjaCA9IGtleS5tYXRjaChmaW5kUHJvYylcbiAgdmFyIGRlY3J5cHRlZFxuICBpZiAoIW1hdGNoKSB7XG4gICAgdmFyIG1hdGNoMiA9IGtleS5tYXRjaChmdWxsUmVnZXgpXG4gICAgZGVjcnlwdGVkID0gbmV3IEJ1ZmZlcihtYXRjaDJbMl0ucmVwbGFjZSgvXFxyP1xcbi9nLCAnJyksICdiYXNlNjQnKVxuICB9IGVsc2Uge1xuICAgIHZhciBzdWl0ZSA9ICdhZXMnICsgbWF0Y2hbMV1cbiAgICB2YXIgaXYgPSBuZXcgQnVmZmVyKG1hdGNoWzJdLCAnaGV4JylcbiAgICB2YXIgY2lwaGVyVGV4dCA9IG5ldyBCdWZmZXIobWF0Y2hbM10ucmVwbGFjZSgvXFxyP1xcbi9nLCAnJyksICdiYXNlNjQnKVxuICAgIHZhciBjaXBoZXJLZXkgPSBldnAocGFzc3dvcmQsIGl2LnNsaWNlKDAsIDgpLCBwYXJzZUludChtYXRjaFsxXSwgMTApKS5rZXlcbiAgICB2YXIgb3V0ID0gW11cbiAgICB2YXIgY2lwaGVyID0gY2lwaGVycy5jcmVhdGVEZWNpcGhlcml2KHN1aXRlLCBjaXBoZXJLZXksIGl2KVxuICAgIG91dC5wdXNoKGNpcGhlci51cGRhdGUoY2lwaGVyVGV4dCkpXG4gICAgb3V0LnB1c2goY2lwaGVyLmZpbmFsKCkpXG4gICAgZGVjcnlwdGVkID0gQnVmZmVyLmNvbmNhdChvdXQpXG4gIH1cbiAgdmFyIHRhZyA9IGtleS5tYXRjaChzdGFydFJlZ2V4KVsxXSArICcgS0VZJ1xuICByZXR1cm4ge1xuICAgIHRhZzogdGFnLFxuICAgIGRhdGE6IGRlY3J5cHRlZFxuICB9XG59XG4iLCJ2YXIgYXNuMSA9IHJlcXVpcmUoJy4vYXNuMScpXG52YXIgYWVzaWQgPSByZXF1aXJlKCcuL2Flc2lkLmpzb24nKVxudmFyIGZpeFByb2MgPSByZXF1aXJlKCcuL2ZpeFByb2MnKVxudmFyIGNpcGhlcnMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWFlcycpXG52YXIgY29tcGF0ID0gcmVxdWlyZSgncGJrZGYyJylcbm1vZHVsZS5leHBvcnRzID0gcGFyc2VLZXlzXG5cbmZ1bmN0aW9uIHBhcnNlS2V5cyAoYnVmZmVyKSB7XG4gIHZhciBwYXNzd29yZFxuICBpZiAodHlwZW9mIGJ1ZmZlciA9PT0gJ29iamVjdCcgJiYgIUJ1ZmZlci5pc0J1ZmZlcihidWZmZXIpKSB7XG4gICAgcGFzc3dvcmQgPSBidWZmZXIucGFzc3BocmFzZVxuICAgIGJ1ZmZlciA9IGJ1ZmZlci5rZXlcbiAgfVxuICBpZiAodHlwZW9mIGJ1ZmZlciA9PT0gJ3N0cmluZycpIHtcbiAgICBidWZmZXIgPSBuZXcgQnVmZmVyKGJ1ZmZlcilcbiAgfVxuXG4gIHZhciBzdHJpcHBlZCA9IGZpeFByb2MoYnVmZmVyLCBwYXNzd29yZClcblxuICB2YXIgdHlwZSA9IHN0cmlwcGVkLnRhZ1xuICB2YXIgZGF0YSA9IHN0cmlwcGVkLmRhdGFcbiAgdmFyIHN1YnR5cGUsIG5kYXRhXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ1BVQkxJQyBLRVknOlxuICAgICAgbmRhdGEgPSBhc24xLlB1YmxpY0tleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICBzdWJ0eXBlID0gbmRhdGEuYWxnb3JpdGhtLmFsZ29yaXRobS5qb2luKCcuJylcbiAgICAgIHN3aXRjaCAoc3VidHlwZSkge1xuICAgICAgICBjYXNlICcxLjIuODQwLjExMzU0OS4xLjEuMSc6XG4gICAgICAgICAgcmV0dXJuIGFzbjEuUlNBUHVibGljS2V5LmRlY29kZShuZGF0YS5zdWJqZWN0UHVibGljS2V5LmRhdGEsICdkZXInKVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQ1LjIuMSc6XG4gICAgICAgICAgbmRhdGEuc3ViamVjdFByaXZhdGVLZXkgPSBuZGF0YS5zdWJqZWN0UHVibGljS2V5XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdlYycsXG4gICAgICAgICAgICBkYXRhOiBuZGF0YVxuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnMS4yLjg0MC4xMDA0MC40LjEnOlxuICAgICAgICAgIG5kYXRhLmFsZ29yaXRobS5wYXJhbXMucHViX2tleSA9IGFzbjEuRFNBcGFyYW0uZGVjb2RlKG5kYXRhLnN1YmplY3RQdWJsaWNLZXkuZGF0YSwgJ2RlcicpXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdkc2EnLFxuICAgICAgICAgICAgZGF0YTogbmRhdGEuYWxnb3JpdGhtLnBhcmFtc1xuICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSBpZCAnICsgc3VidHlwZSlcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgdHlwZSAnICsgdHlwZSlcbiAgICBjYXNlICdFTkNSWVBURUQgUFJJVkFURSBLRVknOlxuICAgICAgZGF0YSA9IGFzbjEuRW5jcnlwdGVkUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICBkYXRhID0gZGVjcnlwdChkYXRhLCBwYXNzd29yZClcbiAgICAgIC8vIGZhbGxzIHRocm91Z2hcbiAgICBjYXNlICdQUklWQVRFIEtFWSc6XG4gICAgICBuZGF0YSA9IGFzbjEuUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICBzdWJ0eXBlID0gbmRhdGEuYWxnb3JpdGhtLmFsZ29yaXRobS5qb2luKCcuJylcbiAgICAgIHN3aXRjaCAoc3VidHlwZSkge1xuICAgICAgICBjYXNlICcxLjIuODQwLjExMzU0OS4xLjEuMSc6XG4gICAgICAgICAgcmV0dXJuIGFzbjEuUlNBUHJpdmF0ZUtleS5kZWNvZGUobmRhdGEuc3ViamVjdFByaXZhdGVLZXksICdkZXInKVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQ1LjIuMSc6XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGN1cnZlOiBuZGF0YS5hbGdvcml0aG0uY3VydmUsXG4gICAgICAgICAgICBwcml2YXRlS2V5OiBhc24xLkVDUHJpdmF0ZUtleS5kZWNvZGUobmRhdGEuc3ViamVjdFByaXZhdGVLZXksICdkZXInKS5wcml2YXRlS2V5XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQwLjQuMSc6XG4gICAgICAgICAgbmRhdGEuYWxnb3JpdGhtLnBhcmFtcy5wcml2X2tleSA9IGFzbjEuRFNBcGFyYW0uZGVjb2RlKG5kYXRhLnN1YmplY3RQcml2YXRlS2V5LCAnZGVyJylcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2RzYScsXG4gICAgICAgICAgICBwYXJhbXM6IG5kYXRhLmFsZ29yaXRobS5wYXJhbXNcbiAgICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgaWQgJyArIHN1YnR5cGUpXG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24ga2V5IHR5cGUgJyArIHR5cGUpXG4gICAgY2FzZSAnUlNBIFBVQkxJQyBLRVknOlxuICAgICAgcmV0dXJuIGFzbjEuUlNBUHVibGljS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICBjYXNlICdSU0EgUFJJVkFURSBLRVknOlxuICAgICAgcmV0dXJuIGFzbjEuUlNBUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgY2FzZSAnRFNBIFBSSVZBVEUgS0VZJzpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdkc2EnLFxuICAgICAgICBwYXJhbXM6IGFzbjEuRFNBUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICB9XG4gICAgY2FzZSAnRUMgUFJJVkFURSBLRVknOlxuICAgICAgZGF0YSA9IGFzbjEuRUNQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGN1cnZlOiBkYXRhLnBhcmFtZXRlcnMudmFsdWUsXG4gICAgICAgIHByaXZhdGVLZXk6IGRhdGEucHJpdmF0ZUtleVxuICAgICAgfVxuICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgdHlwZSAnICsgdHlwZSlcbiAgfVxufVxucGFyc2VLZXlzLnNpZ25hdHVyZSA9IGFzbjEuc2lnbmF0dXJlXG5mdW5jdGlvbiBkZWNyeXB0IChkYXRhLCBwYXNzd29yZCkge1xuICB2YXIgc2FsdCA9IGRhdGEuYWxnb3JpdGhtLmRlY3J5cHQua2RlLmtkZXBhcmFtcy5zYWx0XG4gIHZhciBpdGVycyA9IHBhcnNlSW50KGRhdGEuYWxnb3JpdGhtLmRlY3J5cHQua2RlLmtkZXBhcmFtcy5pdGVycy50b1N0cmluZygpLCAxMClcbiAgdmFyIGFsZ28gPSBhZXNpZFtkYXRhLmFsZ29yaXRobS5kZWNyeXB0LmNpcGhlci5hbGdvLmpvaW4oJy4nKV1cbiAgdmFyIGl2ID0gZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5jaXBoZXIuaXZcbiAgdmFyIGNpcGhlclRleHQgPSBkYXRhLnN1YmplY3RQcml2YXRlS2V5XG4gIHZhciBrZXlsZW4gPSBwYXJzZUludChhbGdvLnNwbGl0KCctJylbMV0sIDEwKSAvIDhcbiAgdmFyIGtleSA9IGNvbXBhdC5wYmtkZjJTeW5jKHBhc3N3b3JkLCBzYWx0LCBpdGVycywga2V5bGVuKVxuICB2YXIgY2lwaGVyID0gY2lwaGVycy5jcmVhdGVEZWNpcGhlcml2KGFsZ28sIGtleSwgaXYpXG4gIHZhciBvdXQgPSBbXVxuICBvdXQucHVzaChjaXBoZXIudXBkYXRlKGNpcGhlclRleHQpKVxuICBvdXQucHVzaChjaXBoZXIuZmluYWwoKSlcbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQob3V0KVxufVxuIiwidmFyIGFzbjEgPSBleHBvcnRzO1xuXG5hc24xLmJpZ251bSA9IHJlcXVpcmUoJ2JuLmpzJyk7XG5cbmFzbjEuZGVmaW5lID0gcmVxdWlyZSgnLi9hc24xL2FwaScpLmRlZmluZTtcbmFzbjEuYmFzZSA9IHJlcXVpcmUoJy4vYXNuMS9iYXNlJyk7XG5hc24xLmNvbnN0YW50cyA9IHJlcXVpcmUoJy4vYXNuMS9jb25zdGFudHMnKTtcbmFzbjEuZGVjb2RlcnMgPSByZXF1aXJlKCcuL2FzbjEvZGVjb2RlcnMnKTtcbmFzbjEuZW5jb2RlcnMgPSByZXF1aXJlKCcuL2FzbjEvZW5jb2RlcnMnKTtcbiIsInZhciBhc24xID0gcmVxdWlyZSgnLi4vYXNuMScpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIGFwaSA9IGV4cG9ydHM7XG5cbmFwaS5kZWZpbmUgPSBmdW5jdGlvbiBkZWZpbmUobmFtZSwgYm9keSkge1xuICByZXR1cm4gbmV3IEVudGl0eShuYW1lLCBib2R5KTtcbn07XG5cbmZ1bmN0aW9uIEVudGl0eShuYW1lLCBib2R5KSB7XG4gIHRoaXMubmFtZSA9IG5hbWU7XG4gIHRoaXMuYm9keSA9IGJvZHk7XG5cbiAgdGhpcy5kZWNvZGVycyA9IHt9O1xuICB0aGlzLmVuY29kZXJzID0ge307XG59O1xuXG5FbnRpdHkucHJvdG90eXBlLl9jcmVhdGVOYW1lZCA9IGZ1bmN0aW9uIGNyZWF0ZU5hbWVkKGJhc2UpIHtcbiAgdmFyIG5hbWVkO1xuICB0cnkge1xuICAgIG5hbWVkID0gcmVxdWlyZSgndm0nKS5ydW5JblRoaXNDb250ZXh0KFxuICAgICAgJyhmdW5jdGlvbiAnICsgdGhpcy5uYW1lICsgJyhlbnRpdHkpIHtcXG4nICtcbiAgICAgICcgIHRoaXMuX2luaXROYW1lZChlbnRpdHkpO1xcbicgK1xuICAgICAgJ30pJ1xuICAgICk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBuYW1lZCA9IGZ1bmN0aW9uIChlbnRpdHkpIHtcbiAgICAgIHRoaXMuX2luaXROYW1lZChlbnRpdHkpO1xuICAgIH07XG4gIH1cbiAgaW5oZXJpdHMobmFtZWQsIGJhc2UpO1xuICBuYW1lZC5wcm90b3R5cGUuX2luaXROYW1lZCA9IGZ1bmN0aW9uIGluaXRuYW1lZChlbnRpdHkpIHtcbiAgICBiYXNlLmNhbGwodGhpcywgZW50aXR5KTtcbiAgfTtcblxuICByZXR1cm4gbmV3IG5hbWVkKHRoaXMpO1xufTtcblxuRW50aXR5LnByb3RvdHlwZS5fZ2V0RGVjb2RlciA9IGZ1bmN0aW9uIF9nZXREZWNvZGVyKGVuYykge1xuICBlbmMgPSBlbmMgfHwgJ2Rlcic7XG4gIC8vIExhemlseSBjcmVhdGUgZGVjb2RlclxuICBpZiAoIXRoaXMuZGVjb2RlcnMuaGFzT3duUHJvcGVydHkoZW5jKSlcbiAgICB0aGlzLmRlY29kZXJzW2VuY10gPSB0aGlzLl9jcmVhdGVOYW1lZChhc24xLmRlY29kZXJzW2VuY10pO1xuICByZXR1cm4gdGhpcy5kZWNvZGVyc1tlbmNdO1xufTtcblxuRW50aXR5LnByb3RvdHlwZS5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUoZGF0YSwgZW5jLCBvcHRpb25zKSB7XG4gIHJldHVybiB0aGlzLl9nZXREZWNvZGVyKGVuYykuZGVjb2RlKGRhdGEsIG9wdGlvbnMpO1xufTtcblxuRW50aXR5LnByb3RvdHlwZS5fZ2V0RW5jb2RlciA9IGZ1bmN0aW9uIF9nZXRFbmNvZGVyKGVuYykge1xuICBlbmMgPSBlbmMgfHwgJ2Rlcic7XG4gIC8vIExhemlseSBjcmVhdGUgZW5jb2RlclxuICBpZiAoIXRoaXMuZW5jb2RlcnMuaGFzT3duUHJvcGVydHkoZW5jKSlcbiAgICB0aGlzLmVuY29kZXJzW2VuY10gPSB0aGlzLl9jcmVhdGVOYW1lZChhc24xLmVuY29kZXJzW2VuY10pO1xuICByZXR1cm4gdGhpcy5lbmNvZGVyc1tlbmNdO1xufTtcblxuRW50aXR5LnByb3RvdHlwZS5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoZGF0YSwgZW5jLCAvKiBpbnRlcm5hbCAqLyByZXBvcnRlcikge1xuICByZXR1cm4gdGhpcy5fZ2V0RW5jb2RlcihlbmMpLmVuY29kZShkYXRhLCByZXBvcnRlcik7XG59O1xuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBSZXBvcnRlciA9IHJlcXVpcmUoJy4uL2Jhc2UnKS5SZXBvcnRlcjtcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbmZ1bmN0aW9uIERlY29kZXJCdWZmZXIoYmFzZSwgb3B0aW9ucykge1xuICBSZXBvcnRlci5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihiYXNlKSkge1xuICAgIHRoaXMuZXJyb3IoJ0lucHV0IG5vdCBCdWZmZXInKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLmJhc2UgPSBiYXNlO1xuICB0aGlzLm9mZnNldCA9IDA7XG4gIHRoaXMubGVuZ3RoID0gYmFzZS5sZW5ndGg7XG59XG5pbmhlcml0cyhEZWNvZGVyQnVmZmVyLCBSZXBvcnRlcik7XG5leHBvcnRzLkRlY29kZXJCdWZmZXIgPSBEZWNvZGVyQnVmZmVyO1xuXG5EZWNvZGVyQnVmZmVyLnByb3RvdHlwZS5zYXZlID0gZnVuY3Rpb24gc2F2ZSgpIHtcbiAgcmV0dXJuIHsgb2Zmc2V0OiB0aGlzLm9mZnNldCwgcmVwb3J0ZXI6IFJlcG9ydGVyLnByb3RvdHlwZS5zYXZlLmNhbGwodGhpcykgfTtcbn07XG5cbkRlY29kZXJCdWZmZXIucHJvdG90eXBlLnJlc3RvcmUgPSBmdW5jdGlvbiByZXN0b3JlKHNhdmUpIHtcbiAgLy8gUmV0dXJuIHNraXBwZWQgZGF0YVxuICB2YXIgcmVzID0gbmV3IERlY29kZXJCdWZmZXIodGhpcy5iYXNlKTtcbiAgcmVzLm9mZnNldCA9IHNhdmUub2Zmc2V0O1xuICByZXMubGVuZ3RoID0gdGhpcy5vZmZzZXQ7XG5cbiAgdGhpcy5vZmZzZXQgPSBzYXZlLm9mZnNldDtcbiAgUmVwb3J0ZXIucHJvdG90eXBlLnJlc3RvcmUuY2FsbCh0aGlzLCBzYXZlLnJlcG9ydGVyKTtcblxuICByZXR1cm4gcmVzO1xufTtcblxuRGVjb2RlckJ1ZmZlci5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uIGlzRW1wdHkoKSB7XG4gIHJldHVybiB0aGlzLm9mZnNldCA9PT0gdGhpcy5sZW5ndGg7XG59O1xuXG5EZWNvZGVyQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDgoZmFpbCkge1xuICBpZiAodGhpcy5vZmZzZXQgKyAxIDw9IHRoaXMubGVuZ3RoKVxuICAgIHJldHVybiB0aGlzLmJhc2UucmVhZFVJbnQ4KHRoaXMub2Zmc2V0KyssIHRydWUpO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMuZXJyb3IoZmFpbCB8fCAnRGVjb2RlckJ1ZmZlciBvdmVycnVuJyk7XG59XG5cbkRlY29kZXJCdWZmZXIucHJvdG90eXBlLnNraXAgPSBmdW5jdGlvbiBza2lwKGJ5dGVzLCBmYWlsKSB7XG4gIGlmICghKHRoaXMub2Zmc2V0ICsgYnl0ZXMgPD0gdGhpcy5sZW5ndGgpKVxuICAgIHJldHVybiB0aGlzLmVycm9yKGZhaWwgfHwgJ0RlY29kZXJCdWZmZXIgb3ZlcnJ1bicpO1xuXG4gIHZhciByZXMgPSBuZXcgRGVjb2RlckJ1ZmZlcih0aGlzLmJhc2UpO1xuXG4gIC8vIFNoYXJlIHJlcG9ydGVyIHN0YXRlXG4gIHJlcy5fcmVwb3J0ZXJTdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgcmVzLm9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICByZXMubGVuZ3RoID0gdGhpcy5vZmZzZXQgKyBieXRlcztcbiAgdGhpcy5vZmZzZXQgKz0gYnl0ZXM7XG4gIHJldHVybiByZXM7XG59XG5cbkRlY29kZXJCdWZmZXIucHJvdG90eXBlLnJhdyA9IGZ1bmN0aW9uIHJhdyhzYXZlKSB7XG4gIHJldHVybiB0aGlzLmJhc2Uuc2xpY2Uoc2F2ZSA/IHNhdmUub2Zmc2V0IDogdGhpcy5vZmZzZXQsIHRoaXMubGVuZ3RoKTtcbn1cblxuZnVuY3Rpb24gRW5jb2RlckJ1ZmZlcih2YWx1ZSwgcmVwb3J0ZXIpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZS5tYXAoZnVuY3Rpb24oaXRlbSkge1xuICAgICAgaWYgKCEoaXRlbSBpbnN0YW5jZW9mIEVuY29kZXJCdWZmZXIpKVxuICAgICAgICBpdGVtID0gbmV3IEVuY29kZXJCdWZmZXIoaXRlbSwgcmVwb3J0ZXIpO1xuICAgICAgdGhpcy5sZW5ndGggKz0gaXRlbS5sZW5ndGg7XG4gICAgICByZXR1cm4gaXRlbTtcbiAgICB9LCB0aGlzKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKCEoMCA8PSB2YWx1ZSAmJiB2YWx1ZSA8PSAweGZmKSlcbiAgICAgIHJldHVybiByZXBvcnRlci5lcnJvcignbm9uLWJ5dGUgRW5jb2RlckJ1ZmZlciB2YWx1ZScpO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmxlbmd0aCA9IDE7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmxlbmd0aCA9IEJ1ZmZlci5ieXRlTGVuZ3RoKHZhbHVlKTtcbiAgfSBlbHNlIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMubGVuZ3RoID0gdmFsdWUubGVuZ3RoO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiByZXBvcnRlci5lcnJvcignVW5zdXBwb3J0ZWQgdHlwZTogJyArIHR5cGVvZiB2YWx1ZSk7XG4gIH1cbn1cbmV4cG9ydHMuRW5jb2RlckJ1ZmZlciA9IEVuY29kZXJCdWZmZXI7XG5cbkVuY29kZXJCdWZmZXIucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiBqb2luKG91dCwgb2Zmc2V0KSB7XG4gIGlmICghb3V0KVxuICAgIG91dCA9IG5ldyBCdWZmZXIodGhpcy5sZW5ndGgpO1xuICBpZiAoIW9mZnNldClcbiAgICBvZmZzZXQgPSAwO1xuXG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMClcbiAgICByZXR1cm4gb3V0O1xuXG4gIGlmIChBcnJheS5pc0FycmF5KHRoaXMudmFsdWUpKSB7XG4gICAgdGhpcy52YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICAgIGl0ZW0uam9pbihvdXQsIG9mZnNldCk7XG4gICAgICBvZmZzZXQgKz0gaXRlbS5sZW5ndGg7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgIG91dFtvZmZzZXRdID0gdGhpcy52YWx1ZTtcbiAgICBlbHNlIGlmICh0eXBlb2YgdGhpcy52YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICBvdXQud3JpdGUodGhpcy52YWx1ZSwgb2Zmc2V0KTtcbiAgICBlbHNlIGlmIChCdWZmZXIuaXNCdWZmZXIodGhpcy52YWx1ZSkpXG4gICAgICB0aGlzLnZhbHVlLmNvcHkob3V0LCBvZmZzZXQpO1xuICAgIG9mZnNldCArPSB0aGlzLmxlbmd0aDtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuIiwidmFyIGJhc2UgPSBleHBvcnRzO1xuXG5iYXNlLlJlcG9ydGVyID0gcmVxdWlyZSgnLi9yZXBvcnRlcicpLlJlcG9ydGVyO1xuYmFzZS5EZWNvZGVyQnVmZmVyID0gcmVxdWlyZSgnLi9idWZmZXInKS5EZWNvZGVyQnVmZmVyO1xuYmFzZS5FbmNvZGVyQnVmZmVyID0gcmVxdWlyZSgnLi9idWZmZXInKS5FbmNvZGVyQnVmZmVyO1xuYmFzZS5Ob2RlID0gcmVxdWlyZSgnLi9ub2RlJyk7XG4iLCJ2YXIgUmVwb3J0ZXIgPSByZXF1aXJlKCcuLi9iYXNlJykuUmVwb3J0ZXI7XG52YXIgRW5jb2RlckJ1ZmZlciA9IHJlcXVpcmUoJy4uL2Jhc2UnKS5FbmNvZGVyQnVmZmVyO1xudmFyIERlY29kZXJCdWZmZXIgPSByZXF1aXJlKCcuLi9iYXNlJykuRGVjb2RlckJ1ZmZlcjtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG5cbi8vIFN1cHBvcnRlZCB0YWdzXG52YXIgdGFncyA9IFtcbiAgJ3NlcScsICdzZXFvZicsICdzZXQnLCAnc2V0b2YnLCAnb2JqaWQnLCAnYm9vbCcsXG4gICdnZW50aW1lJywgJ3V0Y3RpbWUnLCAnbnVsbF8nLCAnZW51bScsICdpbnQnLFxuICAnYml0c3RyJywgJ2JtcHN0cicsICdjaGFyc3RyJywgJ2dlbnN0cicsICdncmFwaHN0cicsICdpYTVzdHInLCAnaXNvNjQ2c3RyJyxcbiAgJ251bXN0cicsICdvY3RzdHInLCAncHJpbnRzdHInLCAndDYxc3RyJywgJ3VuaXN0cicsICd1dGY4c3RyJywgJ3ZpZGVvc3RyJ1xuXTtcblxuLy8gUHVibGljIG1ldGhvZHMgbGlzdFxudmFyIG1ldGhvZHMgPSBbXG4gICdrZXknLCAnb2JqJywgJ3VzZScsICdvcHRpb25hbCcsICdleHBsaWNpdCcsICdpbXBsaWNpdCcsICdkZWYnLCAnY2hvaWNlJyxcbiAgJ2FueScsICdjb250YWlucydcbl0uY29uY2F0KHRhZ3MpO1xuXG4vLyBPdmVycmlkZWQgbWV0aG9kcyBsaXN0XG52YXIgb3ZlcnJpZGVkID0gW1xuICAnX3BlZWtUYWcnLCAnX2RlY29kZVRhZycsICdfdXNlJyxcbiAgJ19kZWNvZGVTdHInLCAnX2RlY29kZU9iamlkJywgJ19kZWNvZGVUaW1lJyxcbiAgJ19kZWNvZGVOdWxsJywgJ19kZWNvZGVJbnQnLCAnX2RlY29kZUJvb2wnLCAnX2RlY29kZUxpc3QnLFxuXG4gICdfZW5jb2RlQ29tcG9zaXRlJywgJ19lbmNvZGVTdHInLCAnX2VuY29kZU9iamlkJywgJ19lbmNvZGVUaW1lJyxcbiAgJ19lbmNvZGVOdWxsJywgJ19lbmNvZGVJbnQnLCAnX2VuY29kZUJvb2wnXG5dO1xuXG5mdW5jdGlvbiBOb2RlKGVuYywgcGFyZW50KSB7XG4gIHZhciBzdGF0ZSA9IHt9O1xuICB0aGlzLl9iYXNlU3RhdGUgPSBzdGF0ZTtcblxuICBzdGF0ZS5lbmMgPSBlbmM7XG5cbiAgc3RhdGUucGFyZW50ID0gcGFyZW50IHx8IG51bGw7XG4gIHN0YXRlLmNoaWxkcmVuID0gbnVsbDtcblxuICAvLyBTdGF0ZVxuICBzdGF0ZS50YWcgPSBudWxsO1xuICBzdGF0ZS5hcmdzID0gbnVsbDtcbiAgc3RhdGUucmV2ZXJzZUFyZ3MgPSBudWxsO1xuICBzdGF0ZS5jaG9pY2UgPSBudWxsO1xuICBzdGF0ZS5vcHRpb25hbCA9IGZhbHNlO1xuICBzdGF0ZS5hbnkgPSBmYWxzZTtcbiAgc3RhdGUub2JqID0gZmFsc2U7XG4gIHN0YXRlLnVzZSA9IG51bGw7XG4gIHN0YXRlLnVzZURlY29kZXIgPSBudWxsO1xuICBzdGF0ZS5rZXkgPSBudWxsO1xuICBzdGF0ZVsnZGVmYXVsdCddID0gbnVsbDtcbiAgc3RhdGUuZXhwbGljaXQgPSBudWxsO1xuICBzdGF0ZS5pbXBsaWNpdCA9IG51bGw7XG4gIHN0YXRlLmNvbnRhaW5zID0gbnVsbDtcblxuICAvLyBTaG91bGQgY3JlYXRlIG5ldyBpbnN0YW5jZSBvbiBlYWNoIG1ldGhvZFxuICBpZiAoIXN0YXRlLnBhcmVudCkge1xuICAgIHN0YXRlLmNoaWxkcmVuID0gW107XG4gICAgdGhpcy5fd3JhcCgpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IE5vZGU7XG5cbnZhciBzdGF0ZVByb3BzID0gW1xuICAnZW5jJywgJ3BhcmVudCcsICdjaGlsZHJlbicsICd0YWcnLCAnYXJncycsICdyZXZlcnNlQXJncycsICdjaG9pY2UnLFxuICAnb3B0aW9uYWwnLCAnYW55JywgJ29iaicsICd1c2UnLCAnYWx0ZXJlZFVzZScsICdrZXknLCAnZGVmYXVsdCcsICdleHBsaWNpdCcsXG4gICdpbXBsaWNpdCdcbl07XG5cbk5vZGUucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gY2xvbmUoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgdmFyIGNzdGF0ZSA9IHt9O1xuICBzdGF0ZVByb3BzLmZvckVhY2goZnVuY3Rpb24ocHJvcCkge1xuICAgIGNzdGF0ZVtwcm9wXSA9IHN0YXRlW3Byb3BdO1xuICB9KTtcbiAgdmFyIHJlcyA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKGNzdGF0ZS5wYXJlbnQpO1xuICByZXMuX2Jhc2VTdGF0ZSA9IGNzdGF0ZTtcbiAgcmV0dXJuIHJlcztcbn07XG5cbk5vZGUucHJvdG90eXBlLl93cmFwID0gZnVuY3Rpb24gd3JhcCgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICBtZXRob2RzLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgdGhpc1ttZXRob2RdID0gZnVuY3Rpb24gX3dyYXBwZWRNZXRob2QoKSB7XG4gICAgICB2YXIgY2xvbmUgPSBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgIHN0YXRlLmNoaWxkcmVuLnB1c2goY2xvbmUpO1xuICAgICAgcmV0dXJuIGNsb25lW21ldGhvZF0uYXBwbHkoY2xvbmUsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfSwgdGhpcyk7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uIGluaXQoYm9keSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLnBhcmVudCA9PT0gbnVsbCk7XG4gIGJvZHkuY2FsbCh0aGlzKTtcblxuICAvLyBGaWx0ZXIgY2hpbGRyZW5cbiAgc3RhdGUuY2hpbGRyZW4gPSBzdGF0ZS5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24oY2hpbGQpIHtcbiAgICByZXR1cm4gY2hpbGQuX2Jhc2VTdGF0ZS5wYXJlbnQgPT09IHRoaXM7XG4gIH0sIHRoaXMpO1xuICBhc3NlcnQuZXF1YWwoc3RhdGUuY2hpbGRyZW4ubGVuZ3RoLCAxLCAnUm9vdCBub2RlIGNhbiBoYXZlIG9ubHkgb25lIGNoaWxkJyk7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fdXNlQXJncyA9IGZ1bmN0aW9uIHVzZUFyZ3MoYXJncykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgLy8gRmlsdGVyIGNoaWxkcmVuIGFuZCBhcmdzXG4gIHZhciBjaGlsZHJlbiA9IGFyZ3MuZmlsdGVyKGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiBhcmcgaW5zdGFuY2VvZiB0aGlzLmNvbnN0cnVjdG9yO1xuICB9LCB0aGlzKTtcbiAgYXJncyA9IGFyZ3MuZmlsdGVyKGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiAhKGFyZyBpbnN0YW5jZW9mIHRoaXMuY29uc3RydWN0b3IpO1xuICB9LCB0aGlzKTtcblxuICBpZiAoY2hpbGRyZW4ubGVuZ3RoICE9PSAwKSB7XG4gICAgYXNzZXJ0KHN0YXRlLmNoaWxkcmVuID09PSBudWxsKTtcbiAgICBzdGF0ZS5jaGlsZHJlbiA9IGNoaWxkcmVuO1xuXG4gICAgLy8gUmVwbGFjZSBwYXJlbnQgdG8gbWFpbnRhaW4gYmFja3dhcmQgbGlua1xuICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgIGNoaWxkLl9iYXNlU3RhdGUucGFyZW50ID0gdGhpcztcbiAgICB9LCB0aGlzKTtcbiAgfVxuICBpZiAoYXJncy5sZW5ndGggIT09IDApIHtcbiAgICBhc3NlcnQoc3RhdGUuYXJncyA9PT0gbnVsbCk7XG4gICAgc3RhdGUuYXJncyA9IGFyZ3M7XG4gICAgc3RhdGUucmV2ZXJzZUFyZ3MgPSBhcmdzLm1hcChmdW5jdGlvbihhcmcpIHtcbiAgICAgIGlmICh0eXBlb2YgYXJnICE9PSAnb2JqZWN0JyB8fCBhcmcuY29uc3RydWN0b3IgIT09IE9iamVjdClcbiAgICAgICAgcmV0dXJuIGFyZztcblxuICAgICAgdmFyIHJlcyA9IHt9O1xuICAgICAgT2JqZWN0LmtleXMoYXJnKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAoa2V5ID09IChrZXkgfCAwKSlcbiAgICAgICAgICBrZXkgfD0gMDtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJnW2tleV07XG4gICAgICAgIHJlc1t2YWx1ZV0gPSBrZXk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXM7XG4gICAgfSk7XG4gIH1cbn07XG5cbi8vXG4vLyBPdmVycmlkZWQgbWV0aG9kc1xuLy9cblxub3ZlcnJpZGVkLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gIE5vZGUucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbiBfb3ZlcnJpZGVkKCkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgICB0aHJvdyBuZXcgRXJyb3IobWV0aG9kICsgJyBub3QgaW1wbGVtZW50ZWQgZm9yIGVuY29kaW5nOiAnICsgc3RhdGUuZW5jKTtcbiAgfTtcbn0pO1xuXG4vL1xuLy8gUHVibGljIG1ldGhvZHNcbi8vXG5cbnRhZ3MuZm9yRWFjaChmdW5jdGlvbih0YWcpIHtcbiAgTm9kZS5wcm90b3R5cGVbdGFnXSA9IGZ1bmN0aW9uIF90YWdNZXRob2QoKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgIGFzc2VydChzdGF0ZS50YWcgPT09IG51bGwpO1xuICAgIHN0YXRlLnRhZyA9IHRhZztcblxuICAgIHRoaXMuX3VzZUFyZ3MoYXJncyk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbn0pO1xuXG5Ob2RlLnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbiB1c2UoaXRlbSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLnVzZSA9PT0gbnVsbCk7XG4gIHN0YXRlLnVzZSA9IGl0ZW07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5vcHRpb25hbCA9IGZ1bmN0aW9uIG9wdGlvbmFsKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgc3RhdGUub3B0aW9uYWwgPSB0cnVlO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUuZGVmID0gZnVuY3Rpb24gZGVmKHZhbCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlWydkZWZhdWx0J10gPT09IG51bGwpO1xuICBzdGF0ZVsnZGVmYXVsdCddID0gdmFsO1xuICBzdGF0ZS5vcHRpb25hbCA9IHRydWU7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5leHBsaWNpdCA9IGZ1bmN0aW9uIGV4cGxpY2l0KG51bSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLmV4cGxpY2l0ID09PSBudWxsICYmIHN0YXRlLmltcGxpY2l0ID09PSBudWxsKTtcbiAgc3RhdGUuZXhwbGljaXQgPSBudW07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5pbXBsaWNpdCA9IGZ1bmN0aW9uIGltcGxpY2l0KG51bSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLmV4cGxpY2l0ID09PSBudWxsICYmIHN0YXRlLmltcGxpY2l0ID09PSBudWxsKTtcbiAgc3RhdGUuaW1wbGljaXQgPSBudW07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5vYmogPSBmdW5jdGlvbiBvYmooKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXG4gIHN0YXRlLm9iaiA9IHRydWU7XG5cbiAgaWYgKGFyZ3MubGVuZ3RoICE9PSAwKVxuICAgIHRoaXMuX3VzZUFyZ3MoYXJncyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5rZXkgPSBmdW5jdGlvbiBrZXkobmV3S2V5KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBhc3NlcnQoc3RhdGUua2V5ID09PSBudWxsKTtcbiAgc3RhdGUua2V5ID0gbmV3S2V5O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUuYW55ID0gZnVuY3Rpb24gYW55KCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgc3RhdGUuYW55ID0gdHJ1ZTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk5vZGUucHJvdG90eXBlLmNob2ljZSA9IGZ1bmN0aW9uIGNob2ljZShvYmopIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZS5jaG9pY2UgPT09IG51bGwpO1xuICBzdGF0ZS5jaG9pY2UgPSBvYmo7XG4gIHRoaXMuX3VzZUFyZ3MoT2JqZWN0LmtleXMob2JqKS5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgcmV0dXJuIG9ialtrZXldO1xuICB9KSk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uIGNvbnRhaW5zKGl0ZW0pIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZS51c2UgPT09IG51bGwpO1xuICBzdGF0ZS5jb250YWlucyA9IGl0ZW07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vL1xuLy8gRGVjb2Rpbmdcbi8vXG5cbk5vZGUucHJvdG90eXBlLl9kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUoaW5wdXQpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIC8vIERlY29kZSByb290IG5vZGVcbiAgaWYgKHN0YXRlLnBhcmVudCA9PT0gbnVsbClcbiAgICByZXR1cm4gaW5wdXQud3JhcFJlc3VsdChzdGF0ZS5jaGlsZHJlblswXS5fZGVjb2RlKGlucHV0KSk7XG5cbiAgdmFyIHJlc3VsdCA9IHN0YXRlWydkZWZhdWx0J107XG4gIHZhciBwcmVzZW50ID0gdHJ1ZTtcblxuICB2YXIgcHJldktleTtcbiAgaWYgKHN0YXRlLmtleSAhPT0gbnVsbClcbiAgICBwcmV2S2V5ID0gaW5wdXQuZW50ZXJLZXkoc3RhdGUua2V5KTtcblxuICAvLyBDaGVjayBpZiB0YWcgaXMgdGhlcmVcbiAgaWYgKHN0YXRlLm9wdGlvbmFsKSB7XG4gICAgdmFyIHRhZyA9IG51bGw7XG4gICAgaWYgKHN0YXRlLmV4cGxpY2l0ICE9PSBudWxsKVxuICAgICAgdGFnID0gc3RhdGUuZXhwbGljaXQ7XG4gICAgZWxzZSBpZiAoc3RhdGUuaW1wbGljaXQgIT09IG51bGwpXG4gICAgICB0YWcgPSBzdGF0ZS5pbXBsaWNpdDtcbiAgICBlbHNlIGlmIChzdGF0ZS50YWcgIT09IG51bGwpXG4gICAgICB0YWcgPSBzdGF0ZS50YWc7XG5cbiAgICBpZiAodGFnID09PSBudWxsICYmICFzdGF0ZS5hbnkpIHtcbiAgICAgIC8vIFRyaWFsIGFuZCBFcnJvclxuICAgICAgdmFyIHNhdmUgPSBpbnB1dC5zYXZlKCk7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoc3RhdGUuY2hvaWNlID09PSBudWxsKVxuICAgICAgICAgIHRoaXMuX2RlY29kZUdlbmVyaWMoc3RhdGUudGFnLCBpbnB1dCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICB0aGlzLl9kZWNvZGVDaG9pY2UoaW5wdXQpO1xuICAgICAgICBwcmVzZW50ID0gdHJ1ZTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcHJlc2VudCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaW5wdXQucmVzdG9yZShzYXZlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJlc2VudCA9IHRoaXMuX3BlZWtUYWcoaW5wdXQsIHRhZywgc3RhdGUuYW55KTtcblxuICAgICAgaWYgKGlucHV0LmlzRXJyb3IocHJlc2VudCkpXG4gICAgICAgIHJldHVybiBwcmVzZW50O1xuICAgIH1cbiAgfVxuXG4gIC8vIFB1c2ggb2JqZWN0IG9uIHN0YWNrXG4gIHZhciBwcmV2T2JqO1xuICBpZiAoc3RhdGUub2JqICYmIHByZXNlbnQpXG4gICAgcHJldk9iaiA9IGlucHV0LmVudGVyT2JqZWN0KCk7XG5cbiAgaWYgKHByZXNlbnQpIHtcbiAgICAvLyBVbndyYXAgZXhwbGljaXQgdmFsdWVzXG4gICAgaWYgKHN0YXRlLmV4cGxpY2l0ICE9PSBudWxsKSB7XG4gICAgICB2YXIgZXhwbGljaXQgPSB0aGlzLl9kZWNvZGVUYWcoaW5wdXQsIHN0YXRlLmV4cGxpY2l0KTtcbiAgICAgIGlmIChpbnB1dC5pc0Vycm9yKGV4cGxpY2l0KSlcbiAgICAgICAgcmV0dXJuIGV4cGxpY2l0O1xuICAgICAgaW5wdXQgPSBleHBsaWNpdDtcbiAgICB9XG5cbiAgICAvLyBVbndyYXAgaW1wbGljaXQgYW5kIG5vcm1hbCB2YWx1ZXNcbiAgICBpZiAoc3RhdGUudXNlID09PSBudWxsICYmIHN0YXRlLmNob2ljZSA9PT0gbnVsbCkge1xuICAgICAgaWYgKHN0YXRlLmFueSlcbiAgICAgICAgdmFyIHNhdmUgPSBpbnB1dC5zYXZlKCk7XG4gICAgICB2YXIgYm9keSA9IHRoaXMuX2RlY29kZVRhZyhcbiAgICAgICAgaW5wdXQsXG4gICAgICAgIHN0YXRlLmltcGxpY2l0ICE9PSBudWxsID8gc3RhdGUuaW1wbGljaXQgOiBzdGF0ZS50YWcsXG4gICAgICAgIHN0YXRlLmFueVxuICAgICAgKTtcbiAgICAgIGlmIChpbnB1dC5pc0Vycm9yKGJvZHkpKVxuICAgICAgICByZXR1cm4gYm9keTtcblxuICAgICAgaWYgKHN0YXRlLmFueSlcbiAgICAgICAgcmVzdWx0ID0gaW5wdXQucmF3KHNhdmUpO1xuICAgICAgZWxzZVxuICAgICAgICBpbnB1dCA9IGJvZHk7XG4gICAgfVxuXG4gICAgLy8gU2VsZWN0IHByb3BlciBtZXRob2QgZm9yIHRhZ1xuICAgIGlmIChzdGF0ZS5hbnkpXG4gICAgICByZXN1bHQgPSByZXN1bHQ7XG4gICAgZWxzZSBpZiAoc3RhdGUuY2hvaWNlID09PSBudWxsKVxuICAgICAgcmVzdWx0ID0gdGhpcy5fZGVjb2RlR2VuZXJpYyhzdGF0ZS50YWcsIGlucHV0KTtcbiAgICBlbHNlXG4gICAgICByZXN1bHQgPSB0aGlzLl9kZWNvZGVDaG9pY2UoaW5wdXQpO1xuXG4gICAgaWYgKGlucHV0LmlzRXJyb3IocmVzdWx0KSlcbiAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICAvLyBEZWNvZGUgY2hpbGRyZW5cbiAgICBpZiAoIXN0YXRlLmFueSAmJiBzdGF0ZS5jaG9pY2UgPT09IG51bGwgJiYgc3RhdGUuY2hpbGRyZW4gIT09IG51bGwpIHtcbiAgICAgIHN0YXRlLmNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gZGVjb2RlQ2hpbGRyZW4oY2hpbGQpIHtcbiAgICAgICAgLy8gTk9URTogV2UgYXJlIGlnbm9yaW5nIGVycm9ycyBoZXJlLCB0byBsZXQgcGFyc2VyIGNvbnRpbnVlIHdpdGggb3RoZXJcbiAgICAgICAgLy8gcGFydHMgb2YgZW5jb2RlZCBkYXRhXG4gICAgICAgIGNoaWxkLl9kZWNvZGUoaW5wdXQpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gRGVjb2RlIGNvbnRhaW5lZC9lbmNvZGVkIGJ5IHNjaGVtYSwgb25seSBpbiBiaXQgb3Igb2N0ZXQgc3RyaW5nc1xuICAgIGlmIChzdGF0ZS5jb250YWlucyAmJiAoc3RhdGUudGFnID09PSAnb2N0c3RyJyB8fCBzdGF0ZS50YWcgPT09ICdiaXRzdHInKSkge1xuICAgICAgdmFyIGRhdGEgPSBuZXcgRGVjb2RlckJ1ZmZlcihyZXN1bHQpO1xuICAgICAgcmVzdWx0ID0gdGhpcy5fZ2V0VXNlKHN0YXRlLmNvbnRhaW5zLCBpbnB1dC5fcmVwb3J0ZXJTdGF0ZS5vYmopLl9kZWNvZGUoZGF0YSk7XG4gICAgfVxuICB9XG5cbiAgLy8gUG9wIG9iamVjdFxuICBpZiAoc3RhdGUub2JqICYmIHByZXNlbnQpXG4gICAgcmVzdWx0ID0gaW5wdXQubGVhdmVPYmplY3QocHJldk9iaik7XG5cbiAgLy8gU2V0IGtleVxuICBpZiAoc3RhdGUua2V5ICE9PSBudWxsICYmIChyZXN1bHQgIT09IG51bGwgfHwgcHJlc2VudCA9PT0gdHJ1ZSkpXG4gICAgaW5wdXQubGVhdmVLZXkocHJldktleSwgc3RhdGUua2V5LCByZXN1bHQpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZGVjb2RlR2VuZXJpYyA9IGZ1bmN0aW9uIGRlY29kZUdlbmVyaWModGFnLCBpbnB1dCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgaWYgKHRhZyA9PT0gJ3NlcScgfHwgdGFnID09PSAnc2V0JylcbiAgICByZXR1cm4gbnVsbDtcbiAgaWYgKHRhZyA9PT0gJ3NlcW9mJyB8fCB0YWcgPT09ICdzZXRvZicpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZUxpc3QoaW5wdXQsIHRhZywgc3RhdGUuYXJnc1swXSk7XG4gIGVsc2UgaWYgKC9zdHIkLy50ZXN0KHRhZykpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZVN0cihpbnB1dCwgdGFnKTtcbiAgZWxzZSBpZiAodGFnID09PSAnb2JqaWQnICYmIHN0YXRlLmFyZ3MpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZU9iamlkKGlucHV0LCBzdGF0ZS5hcmdzWzBdLCBzdGF0ZS5hcmdzWzFdKTtcbiAgZWxzZSBpZiAodGFnID09PSAnb2JqaWQnKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVPYmppZChpbnB1dCwgbnVsbCwgbnVsbCk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ2dlbnRpbWUnIHx8IHRhZyA9PT0gJ3V0Y3RpbWUnKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVUaW1lKGlucHV0LCB0YWcpO1xuICBlbHNlIGlmICh0YWcgPT09ICdudWxsXycpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZU51bGwoaW5wdXQpO1xuICBlbHNlIGlmICh0YWcgPT09ICdib29sJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlQm9vbChpbnB1dCk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ2ludCcgfHwgdGFnID09PSAnZW51bScpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZUludChpbnB1dCwgc3RhdGUuYXJncyAmJiBzdGF0ZS5hcmdzWzBdKTtcbiAgZWxzZSBpZiAoc3RhdGUudXNlICE9PSBudWxsKVxuICAgIHJldHVybiB0aGlzLl9nZXRVc2Uoc3RhdGUudXNlLCBpbnB1dC5fcmVwb3J0ZXJTdGF0ZS5vYmopLl9kZWNvZGUoaW5wdXQpO1xuICBlbHNlXG4gICAgcmV0dXJuIGlucHV0LmVycm9yKCd1bmtub3duIHRhZzogJyArIHRhZyk7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZ2V0VXNlID0gZnVuY3Rpb24gX2dldFVzZShlbnRpdHksIG9iaikge1xuXG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgLy8gQ3JlYXRlIGFsdGVyZWQgdXNlIGRlY29kZXIgaWYgaW1wbGljaXQgaXMgc2V0XG4gIHN0YXRlLnVzZURlY29kZXIgPSB0aGlzLl91c2UoZW50aXR5LCBvYmopO1xuICBhc3NlcnQoc3RhdGUudXNlRGVjb2Rlci5fYmFzZVN0YXRlLnBhcmVudCA9PT0gbnVsbCk7XG4gIHN0YXRlLnVzZURlY29kZXIgPSBzdGF0ZS51c2VEZWNvZGVyLl9iYXNlU3RhdGUuY2hpbGRyZW5bMF07XG4gIGlmIChzdGF0ZS5pbXBsaWNpdCAhPT0gc3RhdGUudXNlRGVjb2Rlci5fYmFzZVN0YXRlLmltcGxpY2l0KSB7XG4gICAgc3RhdGUudXNlRGVjb2RlciA9IHN0YXRlLnVzZURlY29kZXIuY2xvbmUoKTtcbiAgICBzdGF0ZS51c2VEZWNvZGVyLl9iYXNlU3RhdGUuaW1wbGljaXQgPSBzdGF0ZS5pbXBsaWNpdDtcbiAgfVxuICByZXR1cm4gc3RhdGUudXNlRGVjb2Rlcjtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9kZWNvZGVDaG9pY2UgPSBmdW5jdGlvbiBkZWNvZGVDaG9pY2UoaW5wdXQpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgdmFyIG1hdGNoID0gZmFsc2U7XG5cbiAgT2JqZWN0LmtleXMoc3RhdGUuY2hvaWNlKS5zb21lKGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciBzYXZlID0gaW5wdXQuc2F2ZSgpO1xuICAgIHZhciBub2RlID0gc3RhdGUuY2hvaWNlW2tleV07XG4gICAgdHJ5IHtcbiAgICAgIHZhciB2YWx1ZSA9IG5vZGUuX2RlY29kZShpbnB1dCk7XG4gICAgICBpZiAoaW5wdXQuaXNFcnJvcih2YWx1ZSkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgcmVzdWx0ID0geyB0eXBlOiBrZXksIHZhbHVlOiB2YWx1ZSB9O1xuICAgICAgbWF0Y2ggPSB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlucHV0LnJlc3RvcmUoc2F2ZSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9LCB0aGlzKTtcblxuICBpZiAoIW1hdGNoKVxuICAgIHJldHVybiBpbnB1dC5lcnJvcignQ2hvaWNlIG5vdCBtYXRjaGVkJyk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8vXG4vLyBFbmNvZGluZ1xuLy9cblxuTm9kZS5wcm90b3R5cGUuX2NyZWF0ZUVuY29kZXJCdWZmZXIgPSBmdW5jdGlvbiBjcmVhdGVFbmNvZGVyQnVmZmVyKGRhdGEpIHtcbiAgcmV0dXJuIG5ldyBFbmNvZGVyQnVmZmVyKGRhdGEsIHRoaXMucmVwb3J0ZXIpO1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2VuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShkYXRhLCByZXBvcnRlciwgcGFyZW50KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgaWYgKHN0YXRlWydkZWZhdWx0J10gIT09IG51bGwgJiYgc3RhdGVbJ2RlZmF1bHQnXSA9PT0gZGF0YSlcbiAgICByZXR1cm47XG5cbiAgdmFyIHJlc3VsdCA9IHRoaXMuX2VuY29kZVZhbHVlKGRhdGEsIHJlcG9ydGVyLCBwYXJlbnQpO1xuICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuO1xuXG4gIGlmICh0aGlzLl9za2lwRGVmYXVsdChyZXN1bHQsIHJlcG9ydGVyLCBwYXJlbnQpKVxuICAgIHJldHVybjtcblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2VuY29kZVZhbHVlID0gZnVuY3Rpb24gZW5jb2RlKGRhdGEsIHJlcG9ydGVyLCBwYXJlbnQpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIC8vIERlY29kZSByb290IG5vZGVcbiAgaWYgKHN0YXRlLnBhcmVudCA9PT0gbnVsbClcbiAgICByZXR1cm4gc3RhdGUuY2hpbGRyZW5bMF0uX2VuY29kZShkYXRhLCByZXBvcnRlciB8fCBuZXcgUmVwb3J0ZXIoKSk7XG5cbiAgdmFyIHJlc3VsdCA9IG51bGw7XG5cbiAgLy8gU2V0IHJlcG9ydGVyIHRvIHNoYXJlIGl0IHdpdGggYSBjaGlsZCBjbGFzc1xuICB0aGlzLnJlcG9ydGVyID0gcmVwb3J0ZXI7XG5cbiAgLy8gQ2hlY2sgaWYgZGF0YSBpcyB0aGVyZVxuICBpZiAoc3RhdGUub3B0aW9uYWwgJiYgZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHN0YXRlWydkZWZhdWx0J10gIT09IG51bGwpXG4gICAgICBkYXRhID0gc3RhdGVbJ2RlZmF1bHQnXVxuICAgIGVsc2VcbiAgICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEVuY29kZSBjaGlsZHJlbiBmaXJzdFxuICB2YXIgY29udGVudCA9IG51bGw7XG4gIHZhciBwcmltaXRpdmUgPSBmYWxzZTtcbiAgaWYgKHN0YXRlLmFueSkge1xuICAgIC8vIEFueXRoaW5nIHRoYXQgd2FzIGdpdmVuIGlzIHRyYW5zbGF0ZWQgdG8gYnVmZmVyXG4gICAgcmVzdWx0ID0gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihkYXRhKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5jaG9pY2UpIHtcbiAgICByZXN1bHQgPSB0aGlzLl9lbmNvZGVDaG9pY2UoZGF0YSwgcmVwb3J0ZXIpO1xuICB9IGVsc2UgaWYgKHN0YXRlLmNvbnRhaW5zKSB7XG4gICAgY29udGVudCA9IHRoaXMuX2dldFVzZShzdGF0ZS5jb250YWlucywgcGFyZW50KS5fZW5jb2RlKGRhdGEsIHJlcG9ydGVyKTtcbiAgICBwcmltaXRpdmUgPSB0cnVlO1xuICB9IGVsc2UgaWYgKHN0YXRlLmNoaWxkcmVuKSB7XG4gICAgY29udGVudCA9IHN0YXRlLmNoaWxkcmVuLm1hcChmdW5jdGlvbihjaGlsZCkge1xuICAgICAgaWYgKGNoaWxkLl9iYXNlU3RhdGUudGFnID09PSAnbnVsbF8nKVxuICAgICAgICByZXR1cm4gY2hpbGQuX2VuY29kZShudWxsLCByZXBvcnRlciwgZGF0YSk7XG5cbiAgICAgIGlmIChjaGlsZC5fYmFzZVN0YXRlLmtleSA9PT0gbnVsbClcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdDaGlsZCBzaG91bGQgaGF2ZSBhIGtleScpO1xuICAgICAgdmFyIHByZXZLZXkgPSByZXBvcnRlci5lbnRlcktleShjaGlsZC5fYmFzZVN0YXRlLmtleSk7XG5cbiAgICAgIGlmICh0eXBlb2YgZGF0YSAhPT0gJ29iamVjdCcpXG4gICAgICAgIHJldHVybiByZXBvcnRlci5lcnJvcignQ2hpbGQgZXhwZWN0ZWQsIGJ1dCBpbnB1dCBpcyBub3Qgb2JqZWN0Jyk7XG5cbiAgICAgIHZhciByZXMgPSBjaGlsZC5fZW5jb2RlKGRhdGFbY2hpbGQuX2Jhc2VTdGF0ZS5rZXldLCByZXBvcnRlciwgZGF0YSk7XG4gICAgICByZXBvcnRlci5sZWF2ZUtleShwcmV2S2V5KTtcblxuICAgICAgcmV0dXJuIHJlcztcbiAgICB9LCB0aGlzKS5maWx0ZXIoZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgIHJldHVybiBjaGlsZDtcbiAgICB9KTtcbiAgICBjb250ZW50ID0gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihjb250ZW50KTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoc3RhdGUudGFnID09PSAnc2Vxb2YnIHx8IHN0YXRlLnRhZyA9PT0gJ3NldG9mJykge1xuICAgICAgLy8gVE9ETyhpbmR1dG55KTogdGhpcyBzaG91bGQgYmUgdGhyb3duIG9uIERTTCBsZXZlbFxuICAgICAgaWYgKCEoc3RhdGUuYXJncyAmJiBzdGF0ZS5hcmdzLmxlbmd0aCA9PT0gMSkpXG4gICAgICAgIHJldHVybiByZXBvcnRlci5lcnJvcignVG9vIG1hbnkgYXJncyBmb3IgOiAnICsgc3RhdGUudGFnKTtcblxuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGRhdGEpKVxuICAgICAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ3NlcW9mL3NldG9mLCBidXQgZGF0YSBpcyBub3QgQXJyYXknKTtcblxuICAgICAgdmFyIGNoaWxkID0gdGhpcy5jbG9uZSgpO1xuICAgICAgY2hpbGQuX2Jhc2VTdGF0ZS5pbXBsaWNpdCA9IG51bGw7XG4gICAgICBjb250ZW50ID0gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihkYXRhLm1hcChmdW5jdGlvbihpdGVtKSB7XG4gICAgICAgIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0VXNlKHN0YXRlLmFyZ3NbMF0sIGRhdGEpLl9lbmNvZGUoaXRlbSwgcmVwb3J0ZXIpO1xuICAgICAgfSwgY2hpbGQpKTtcbiAgICB9IGVsc2UgaWYgKHN0YXRlLnVzZSAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ID0gdGhpcy5fZ2V0VXNlKHN0YXRlLnVzZSwgcGFyZW50KS5fZW5jb2RlKGRhdGEsIHJlcG9ydGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGVudCA9IHRoaXMuX2VuY29kZVByaW1pdGl2ZShzdGF0ZS50YWcsIGRhdGEpO1xuICAgICAgcHJpbWl0aXZlID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvLyBFbmNvZGUgZGF0YSBpdHNlbGZcbiAgdmFyIHJlc3VsdDtcbiAgaWYgKCFzdGF0ZS5hbnkgJiYgc3RhdGUuY2hvaWNlID09PSBudWxsKSB7XG4gICAgdmFyIHRhZyA9IHN0YXRlLmltcGxpY2l0ICE9PSBudWxsID8gc3RhdGUuaW1wbGljaXQgOiBzdGF0ZS50YWc7XG4gICAgdmFyIGNscyA9IHN0YXRlLmltcGxpY2l0ID09PSBudWxsID8gJ3VuaXZlcnNhbCcgOiAnY29udGV4dCc7XG5cbiAgICBpZiAodGFnID09PSBudWxsKSB7XG4gICAgICBpZiAoc3RhdGUudXNlID09PSBudWxsKVxuICAgICAgICByZXBvcnRlci5lcnJvcignVGFnIGNvdWxkIGJlIG9tbWl0ZWQgb25seSBmb3IgLnVzZSgpJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzdGF0ZS51c2UgPT09IG51bGwpXG4gICAgICAgIHJlc3VsdCA9IHRoaXMuX2VuY29kZUNvbXBvc2l0ZSh0YWcsIHByaW1pdGl2ZSwgY2xzLCBjb250ZW50KTtcbiAgICB9XG4gIH1cblxuICAvLyBXcmFwIGluIGV4cGxpY2l0XG4gIGlmIChzdGF0ZS5leHBsaWNpdCAhPT0gbnVsbClcbiAgICByZXN1bHQgPSB0aGlzLl9lbmNvZGVDb21wb3NpdGUoc3RhdGUuZXhwbGljaXQsIGZhbHNlLCAnY29udGV4dCcsIHJlc3VsdCk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9lbmNvZGVDaG9pY2UgPSBmdW5jdGlvbiBlbmNvZGVDaG9pY2UoZGF0YSwgcmVwb3J0ZXIpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIHZhciBub2RlID0gc3RhdGUuY2hvaWNlW2RhdGEudHlwZV07XG4gIGlmICghbm9kZSkge1xuICAgIGFzc2VydChcbiAgICAgICAgZmFsc2UsXG4gICAgICAgIGRhdGEudHlwZSArICcgbm90IGZvdW5kIGluICcgK1xuICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXMoc3RhdGUuY2hvaWNlKSkpO1xuICB9XG4gIHJldHVybiBub2RlLl9lbmNvZGUoZGF0YS52YWx1ZSwgcmVwb3J0ZXIpO1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2VuY29kZVByaW1pdGl2ZSA9IGZ1bmN0aW9uIGVuY29kZVByaW1pdGl2ZSh0YWcsIGRhdGEpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGlmICgvc3RyJC8udGVzdCh0YWcpKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVTdHIoZGF0YSwgdGFnKTtcbiAgZWxzZSBpZiAodGFnID09PSAnb2JqaWQnICYmIHN0YXRlLmFyZ3MpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZU9iamlkKGRhdGEsIHN0YXRlLnJldmVyc2VBcmdzWzBdLCBzdGF0ZS5hcmdzWzFdKTtcbiAgZWxzZSBpZiAodGFnID09PSAnb2JqaWQnKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVPYmppZChkYXRhLCBudWxsLCBudWxsKTtcbiAgZWxzZSBpZiAodGFnID09PSAnZ2VudGltZScgfHwgdGFnID09PSAndXRjdGltZScpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZVRpbWUoZGF0YSwgdGFnKTtcbiAgZWxzZSBpZiAodGFnID09PSAnbnVsbF8nKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVOdWxsKCk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ2ludCcgfHwgdGFnID09PSAnZW51bScpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZUludChkYXRhLCBzdGF0ZS5hcmdzICYmIHN0YXRlLnJldmVyc2VBcmdzWzBdKTtcbiAgZWxzZSBpZiAodGFnID09PSAnYm9vbCcpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZUJvb2woZGF0YSk7XG4gIGVsc2VcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHRhZzogJyArIHRhZyk7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5faXNOdW1zdHIgPSBmdW5jdGlvbiBpc051bXN0cihzdHIpIHtcbiAgcmV0dXJuIC9eWzAtOSBdKiQvLnRlc3Qoc3RyKTtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9pc1ByaW50c3RyID0gZnVuY3Rpb24gaXNQcmludHN0cihzdHIpIHtcbiAgcmV0dXJuIC9eW0EtWmEtejAtOSAnXFwoXFwpXFwrLFxcLVxcLlxcLzo9XFw/XSokLy50ZXN0KHN0cik7XG59O1xuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZnVuY3Rpb24gUmVwb3J0ZXIob3B0aW9ucykge1xuICB0aGlzLl9yZXBvcnRlclN0YXRlID0ge1xuICAgIG9iajogbnVsbCxcbiAgICBwYXRoOiBbXSxcbiAgICBvcHRpb25zOiBvcHRpb25zIHx8IHt9LFxuICAgIGVycm9yczogW11cbiAgfTtcbn1cbmV4cG9ydHMuUmVwb3J0ZXIgPSBSZXBvcnRlcjtcblxuUmVwb3J0ZXIucHJvdG90eXBlLmlzRXJyb3IgPSBmdW5jdGlvbiBpc0Vycm9yKG9iaikge1xuICByZXR1cm4gb2JqIGluc3RhbmNlb2YgUmVwb3J0ZXJFcnJvcjtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5zYXZlID0gZnVuY3Rpb24gc2F2ZSgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcblxuICByZXR1cm4geyBvYmo6IHN0YXRlLm9iaiwgcGF0aExlbjogc3RhdGUucGF0aC5sZW5ndGggfTtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5yZXN0b3JlID0gZnVuY3Rpb24gcmVzdG9yZShkYXRhKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgc3RhdGUub2JqID0gZGF0YS5vYmo7XG4gIHN0YXRlLnBhdGggPSBzdGF0ZS5wYXRoLnNsaWNlKDAsIGRhdGEucGF0aExlbik7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUuZW50ZXJLZXkgPSBmdW5jdGlvbiBlbnRlcktleShrZXkpIHtcbiAgcmV0dXJuIHRoaXMuX3JlcG9ydGVyU3RhdGUucGF0aC5wdXNoKGtleSk7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUubGVhdmVLZXkgPSBmdW5jdGlvbiBsZWF2ZUtleShpbmRleCwga2V5LCB2YWx1ZSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHN0YXRlLnBhdGggPSBzdGF0ZS5wYXRoLnNsaWNlKDAsIGluZGV4IC0gMSk7XG4gIGlmIChzdGF0ZS5vYmogIT09IG51bGwpXG4gICAgc3RhdGUub2JqW2tleV0gPSB2YWx1ZTtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5lbnRlck9iamVjdCA9IGZ1bmN0aW9uIGVudGVyT2JqZWN0KCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHZhciBwcmV2ID0gc3RhdGUub2JqO1xuICBzdGF0ZS5vYmogPSB7fTtcbiAgcmV0dXJuIHByZXY7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUubGVhdmVPYmplY3QgPSBmdW5jdGlvbiBsZWF2ZU9iamVjdChwcmV2KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgdmFyIG5vdyA9IHN0YXRlLm9iajtcbiAgc3RhdGUub2JqID0gcHJldjtcbiAgcmV0dXJuIG5vdztcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5lcnJvciA9IGZ1bmN0aW9uIGVycm9yKG1zZykge1xuICB2YXIgZXJyO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHZhciBpbmhlcml0ZWQgPSBtc2cgaW5zdGFuY2VvZiBSZXBvcnRlckVycm9yO1xuICBpZiAoaW5oZXJpdGVkKSB7XG4gICAgZXJyID0gbXNnO1xuICB9IGVsc2Uge1xuICAgIGVyciA9IG5ldyBSZXBvcnRlckVycm9yKHN0YXRlLnBhdGgubWFwKGZ1bmN0aW9uKGVsZW0pIHtcbiAgICAgIHJldHVybiAnWycgKyBKU09OLnN0cmluZ2lmeShlbGVtKSArICddJztcbiAgICB9KS5qb2luKCcnKSwgbXNnLm1lc3NhZ2UgfHwgbXNnLCBtc2cuc3RhY2spO1xuICB9XG5cbiAgaWYgKCFzdGF0ZS5vcHRpb25zLnBhcnRpYWwpXG4gICAgdGhyb3cgZXJyO1xuXG4gIGlmICghaW5oZXJpdGVkKVxuICAgIHN0YXRlLmVycm9ycy5wdXNoKGVycik7XG5cbiAgcmV0dXJuIGVycjtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS53cmFwUmVzdWx0ID0gZnVuY3Rpb24gd3JhcFJlc3VsdChyZXN1bHQpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcbiAgaWYgKCFzdGF0ZS5vcHRpb25zLnBhcnRpYWwpXG4gICAgcmV0dXJuIHJlc3VsdDtcblxuICByZXR1cm4ge1xuICAgIHJlc3VsdDogdGhpcy5pc0Vycm9yKHJlc3VsdCkgPyBudWxsIDogcmVzdWx0LFxuICAgIGVycm9yczogc3RhdGUuZXJyb3JzXG4gIH07XG59O1xuXG5mdW5jdGlvbiBSZXBvcnRlckVycm9yKHBhdGgsIG1zZykge1xuICB0aGlzLnBhdGggPSBwYXRoO1xuICB0aGlzLnJldGhyb3cobXNnKTtcbn07XG5pbmhlcml0cyhSZXBvcnRlckVycm9yLCBFcnJvcik7XG5cblJlcG9ydGVyRXJyb3IucHJvdG90eXBlLnJldGhyb3cgPSBmdW5jdGlvbiByZXRocm93KG1zZykge1xuICB0aGlzLm1lc3NhZ2UgPSBtc2cgKyAnIGF0OiAnICsgKHRoaXMucGF0aCB8fCAnKHNoYWxsb3cpJyk7XG4gIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIFJlcG9ydGVyRXJyb3IpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcbiIsInZhciBjb25zdGFudHMgPSByZXF1aXJlKCcuLi9jb25zdGFudHMnKTtcblxuZXhwb3J0cy50YWdDbGFzcyA9IHtcbiAgMDogJ3VuaXZlcnNhbCcsXG4gIDE6ICdhcHBsaWNhdGlvbicsXG4gIDI6ICdjb250ZXh0JyxcbiAgMzogJ3ByaXZhdGUnXG59O1xuZXhwb3J0cy50YWdDbGFzc0J5TmFtZSA9IGNvbnN0YW50cy5fcmV2ZXJzZShleHBvcnRzLnRhZ0NsYXNzKTtcblxuZXhwb3J0cy50YWcgPSB7XG4gIDB4MDA6ICdlbmQnLFxuICAweDAxOiAnYm9vbCcsXG4gIDB4MDI6ICdpbnQnLFxuICAweDAzOiAnYml0c3RyJyxcbiAgMHgwNDogJ29jdHN0cicsXG4gIDB4MDU6ICdudWxsXycsXG4gIDB4MDY6ICdvYmppZCcsXG4gIDB4MDc6ICdvYmpEZXNjJyxcbiAgMHgwODogJ2V4dGVybmFsJyxcbiAgMHgwOTogJ3JlYWwnLFxuICAweDBhOiAnZW51bScsXG4gIDB4MGI6ICdlbWJlZCcsXG4gIDB4MGM6ICd1dGY4c3RyJyxcbiAgMHgwZDogJ3JlbGF0aXZlT2lkJyxcbiAgMHgxMDogJ3NlcScsXG4gIDB4MTE6ICdzZXQnLFxuICAweDEyOiAnbnVtc3RyJyxcbiAgMHgxMzogJ3ByaW50c3RyJyxcbiAgMHgxNDogJ3Q2MXN0cicsXG4gIDB4MTU6ICd2aWRlb3N0cicsXG4gIDB4MTY6ICdpYTVzdHInLFxuICAweDE3OiAndXRjdGltZScsXG4gIDB4MTg6ICdnZW50aW1lJyxcbiAgMHgxOTogJ2dyYXBoc3RyJyxcbiAgMHgxYTogJ2lzbzY0NnN0cicsXG4gIDB4MWI6ICdnZW5zdHInLFxuICAweDFjOiAndW5pc3RyJyxcbiAgMHgxZDogJ2NoYXJzdHInLFxuICAweDFlOiAnYm1wc3RyJ1xufTtcbmV4cG9ydHMudGFnQnlOYW1lID0gY29uc3RhbnRzLl9yZXZlcnNlKGV4cG9ydHMudGFnKTtcbiIsInZhciBjb25zdGFudHMgPSBleHBvcnRzO1xuXG4vLyBIZWxwZXJcbmNvbnN0YW50cy5fcmV2ZXJzZSA9IGZ1bmN0aW9uIHJldmVyc2UobWFwKSB7XG4gIHZhciByZXMgPSB7fTtcblxuICBPYmplY3Qua2V5cyhtYXApLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgLy8gQ29udmVydCBrZXkgdG8gaW50ZWdlciBpZiBpdCBpcyBzdHJpbmdpZmllZFxuICAgIGlmICgoa2V5IHwgMCkgPT0ga2V5KVxuICAgICAga2V5ID0ga2V5IHwgMDtcblxuICAgIHZhciB2YWx1ZSA9IG1hcFtrZXldO1xuICAgIHJlc1t2YWx1ZV0gPSBrZXk7XG4gIH0pO1xuXG4gIHJldHVybiByZXM7XG59O1xuXG5jb25zdGFudHMuZGVyID0gcmVxdWlyZSgnLi9kZXInKTtcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBhc24xID0gcmVxdWlyZSgnLi4vLi4vYXNuMScpO1xudmFyIGJhc2UgPSBhc24xLmJhc2U7XG52YXIgYmlnbnVtID0gYXNuMS5iaWdudW07XG5cbi8vIEltcG9ydCBERVIgY29uc3RhbnRzXG52YXIgZGVyID0gYXNuMS5jb25zdGFudHMuZGVyO1xuXG5mdW5jdGlvbiBERVJEZWNvZGVyKGVudGl0eSkge1xuICB0aGlzLmVuYyA9ICdkZXInO1xuICB0aGlzLm5hbWUgPSBlbnRpdHkubmFtZTtcbiAgdGhpcy5lbnRpdHkgPSBlbnRpdHk7XG5cbiAgLy8gQ29uc3RydWN0IGJhc2UgdHJlZVxuICB0aGlzLnRyZWUgPSBuZXcgREVSTm9kZSgpO1xuICB0aGlzLnRyZWUuX2luaXQoZW50aXR5LmJvZHkpO1xufTtcbm1vZHVsZS5leHBvcnRzID0gREVSRGVjb2RlcjtcblxuREVSRGVjb2Rlci5wcm90b3R5cGUuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKGRhdGEsIG9wdGlvbnMpIHtcbiAgaWYgKCEoZGF0YSBpbnN0YW5jZW9mIGJhc2UuRGVjb2RlckJ1ZmZlcikpXG4gICAgZGF0YSA9IG5ldyBiYXNlLkRlY29kZXJCdWZmZXIoZGF0YSwgb3B0aW9ucyk7XG5cbiAgcmV0dXJuIHRoaXMudHJlZS5fZGVjb2RlKGRhdGEsIG9wdGlvbnMpO1xufTtcblxuLy8gVHJlZSBtZXRob2RzXG5cbmZ1bmN0aW9uIERFUk5vZGUocGFyZW50KSB7XG4gIGJhc2UuTm9kZS5jYWxsKHRoaXMsICdkZXInLCBwYXJlbnQpO1xufVxuaW5oZXJpdHMoREVSTm9kZSwgYmFzZS5Ob2RlKTtcblxuREVSTm9kZS5wcm90b3R5cGUuX3BlZWtUYWcgPSBmdW5jdGlvbiBwZWVrVGFnKGJ1ZmZlciwgdGFnLCBhbnkpIHtcbiAgaWYgKGJ1ZmZlci5pc0VtcHR5KCkpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBzdGF0ZSA9IGJ1ZmZlci5zYXZlKCk7XG4gIHZhciBkZWNvZGVkVGFnID0gZGVyRGVjb2RlVGFnKGJ1ZmZlciwgJ0ZhaWxlZCB0byBwZWVrIHRhZzogXCInICsgdGFnICsgJ1wiJyk7XG4gIGlmIChidWZmZXIuaXNFcnJvcihkZWNvZGVkVGFnKSlcbiAgICByZXR1cm4gZGVjb2RlZFRhZztcblxuICBidWZmZXIucmVzdG9yZShzdGF0ZSk7XG5cbiAgcmV0dXJuIGRlY29kZWRUYWcudGFnID09PSB0YWcgfHwgZGVjb2RlZFRhZy50YWdTdHIgPT09IHRhZyB8fFxuICAgIChkZWNvZGVkVGFnLnRhZ1N0ciArICdvZicpID09PSB0YWcgfHwgYW55O1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZVRhZyA9IGZ1bmN0aW9uIGRlY29kZVRhZyhidWZmZXIsIHRhZywgYW55KSB7XG4gIHZhciBkZWNvZGVkVGFnID0gZGVyRGVjb2RlVGFnKGJ1ZmZlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0ZhaWxlZCB0byBkZWNvZGUgdGFnIG9mIFwiJyArIHRhZyArICdcIicpO1xuICBpZiAoYnVmZmVyLmlzRXJyb3IoZGVjb2RlZFRhZykpXG4gICAgcmV0dXJuIGRlY29kZWRUYWc7XG5cbiAgdmFyIGxlbiA9IGRlckRlY29kZUxlbihidWZmZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgZGVjb2RlZFRhZy5wcmltaXRpdmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ0ZhaWxlZCB0byBnZXQgbGVuZ3RoIG9mIFwiJyArIHRhZyArICdcIicpO1xuXG4gIC8vIEZhaWx1cmVcbiAgaWYgKGJ1ZmZlci5pc0Vycm9yKGxlbikpXG4gICAgcmV0dXJuIGxlbjtcblxuICBpZiAoIWFueSAmJlxuICAgICAgZGVjb2RlZFRhZy50YWcgIT09IHRhZyAmJlxuICAgICAgZGVjb2RlZFRhZy50YWdTdHIgIT09IHRhZyAmJlxuICAgICAgZGVjb2RlZFRhZy50YWdTdHIgKyAnb2YnICE9PSB0YWcpIHtcbiAgICByZXR1cm4gYnVmZmVyLmVycm9yKCdGYWlsZWQgdG8gbWF0Y2ggdGFnOiBcIicgKyB0YWcgKyAnXCInKTtcbiAgfVxuXG4gIGlmIChkZWNvZGVkVGFnLnByaW1pdGl2ZSB8fCBsZW4gIT09IG51bGwpXG4gICAgcmV0dXJuIGJ1ZmZlci5za2lwKGxlbiwgJ0ZhaWxlZCB0byBtYXRjaCBib2R5IG9mOiBcIicgKyB0YWcgKyAnXCInKTtcblxuICAvLyBJbmRlZmluaXRlIGxlbmd0aC4uLiBmaW5kIEVORCB0YWdcbiAgdmFyIHN0YXRlID0gYnVmZmVyLnNhdmUoKTtcbiAgdmFyIHJlcyA9IHRoaXMuX3NraXBVbnRpbEVuZChcbiAgICAgIGJ1ZmZlcixcbiAgICAgICdGYWlsZWQgdG8gc2tpcCBpbmRlZmluaXRlIGxlbmd0aCBib2R5OiBcIicgKyB0aGlzLnRhZyArICdcIicpO1xuICBpZiAoYnVmZmVyLmlzRXJyb3IocmVzKSlcbiAgICByZXR1cm4gcmVzO1xuXG4gIGxlbiA9IGJ1ZmZlci5vZmZzZXQgLSBzdGF0ZS5vZmZzZXQ7XG4gIGJ1ZmZlci5yZXN0b3JlKHN0YXRlKTtcbiAgcmV0dXJuIGJ1ZmZlci5za2lwKGxlbiwgJ0ZhaWxlZCB0byBtYXRjaCBib2R5IG9mOiBcIicgKyB0YWcgKyAnXCInKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9za2lwVW50aWxFbmQgPSBmdW5jdGlvbiBza2lwVW50aWxFbmQoYnVmZmVyLCBmYWlsKSB7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgdmFyIHRhZyA9IGRlckRlY29kZVRhZyhidWZmZXIsIGZhaWwpO1xuICAgIGlmIChidWZmZXIuaXNFcnJvcih0YWcpKVxuICAgICAgcmV0dXJuIHRhZztcbiAgICB2YXIgbGVuID0gZGVyRGVjb2RlTGVuKGJ1ZmZlciwgdGFnLnByaW1pdGl2ZSwgZmFpbCk7XG4gICAgaWYgKGJ1ZmZlci5pc0Vycm9yKGxlbikpXG4gICAgICByZXR1cm4gbGVuO1xuXG4gICAgdmFyIHJlcztcbiAgICBpZiAodGFnLnByaW1pdGl2ZSB8fCBsZW4gIT09IG51bGwpXG4gICAgICByZXMgPSBidWZmZXIuc2tpcChsZW4pXG4gICAgZWxzZVxuICAgICAgcmVzID0gdGhpcy5fc2tpcFVudGlsRW5kKGJ1ZmZlciwgZmFpbCk7XG5cbiAgICAvLyBGYWlsdXJlXG4gICAgaWYgKGJ1ZmZlci5pc0Vycm9yKHJlcykpXG4gICAgICByZXR1cm4gcmVzO1xuXG4gICAgaWYgKHRhZy50YWdTdHIgPT09ICdlbmQnKVxuICAgICAgYnJlYWs7XG4gIH1cbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVMaXN0ID0gZnVuY3Rpb24gZGVjb2RlTGlzdChidWZmZXIsIHRhZywgZGVjb2Rlcikge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHdoaWxlICghYnVmZmVyLmlzRW1wdHkoKSkge1xuICAgIHZhciBwb3NzaWJsZUVuZCA9IHRoaXMuX3BlZWtUYWcoYnVmZmVyLCAnZW5kJyk7XG4gICAgaWYgKGJ1ZmZlci5pc0Vycm9yKHBvc3NpYmxlRW5kKSlcbiAgICAgIHJldHVybiBwb3NzaWJsZUVuZDtcblxuICAgIHZhciByZXMgPSBkZWNvZGVyLmRlY29kZShidWZmZXIsICdkZXInKTtcbiAgICBpZiAoYnVmZmVyLmlzRXJyb3IocmVzKSAmJiBwb3NzaWJsZUVuZClcbiAgICAgIGJyZWFrO1xuICAgIHJlc3VsdC5wdXNoKHJlcyk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVTdHIgPSBmdW5jdGlvbiBkZWNvZGVTdHIoYnVmZmVyLCB0YWcpIHtcbiAgaWYgKHRhZyA9PT0gJ2JpdHN0cicpIHtcbiAgICB2YXIgdW51c2VkID0gYnVmZmVyLnJlYWRVSW50OCgpO1xuICAgIGlmIChidWZmZXIuaXNFcnJvcih1bnVzZWQpKVxuICAgICAgcmV0dXJuIHVudXNlZDtcbiAgICByZXR1cm4geyB1bnVzZWQ6IHVudXNlZCwgZGF0YTogYnVmZmVyLnJhdygpIH07XG4gIH0gZWxzZSBpZiAodGFnID09PSAnYm1wc3RyJykge1xuICAgIHZhciByYXcgPSBidWZmZXIucmF3KCk7XG4gICAgaWYgKHJhdy5sZW5ndGggJSAyID09PSAxKVxuICAgICAgcmV0dXJuIGJ1ZmZlci5lcnJvcignRGVjb2Rpbmcgb2Ygc3RyaW5nIHR5cGU6IGJtcHN0ciBsZW5ndGggbWlzbWF0Y2gnKTtcblxuICAgIHZhciBzdHIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhdy5sZW5ndGggLyAyOyBpKyspIHtcbiAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHJhdy5yZWFkVUludDE2QkUoaSAqIDIpKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0cjtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdudW1zdHInKSB7XG4gICAgdmFyIG51bXN0ciA9IGJ1ZmZlci5yYXcoKS50b1N0cmluZygnYXNjaWknKTtcbiAgICBpZiAoIXRoaXMuX2lzTnVtc3RyKG51bXN0cikpIHtcbiAgICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0RlY29kaW5nIG9mIHN0cmluZyB0eXBlOiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ251bXN0ciB1bnN1cHBvcnRlZCBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuICAgIHJldHVybiBudW1zdHI7XG4gIH0gZWxzZSBpZiAodGFnID09PSAnb2N0c3RyJykge1xuICAgIHJldHVybiBidWZmZXIucmF3KCk7XG4gIH0gZWxzZSBpZiAodGFnID09PSAncHJpbnRzdHInKSB7XG4gICAgdmFyIHByaW50c3RyID0gYnVmZmVyLnJhdygpLnRvU3RyaW5nKCdhc2NpaScpO1xuICAgIGlmICghdGhpcy5faXNQcmludHN0cihwcmludHN0cikpIHtcbiAgICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0RlY29kaW5nIG9mIHN0cmluZyB0eXBlOiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ3ByaW50c3RyIHVuc3VwcG9ydGVkIGNoYXJhY3RlcnMnKTtcbiAgICB9XG4gICAgcmV0dXJuIHByaW50c3RyO1xuICB9IGVsc2UgaWYgKC9zdHIkLy50ZXN0KHRhZykpIHtcbiAgICByZXR1cm4gYnVmZmVyLnJhdygpLnRvU3RyaW5nKCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJ1ZmZlci5lcnJvcignRGVjb2Rpbmcgb2Ygc3RyaW5nIHR5cGU6ICcgKyB0YWcgKyAnIHVuc3VwcG9ydGVkJyk7XG4gIH1cbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVPYmppZCA9IGZ1bmN0aW9uIGRlY29kZU9iamlkKGJ1ZmZlciwgdmFsdWVzLCByZWxhdGl2ZSkge1xuICB2YXIgcmVzdWx0O1xuICB2YXIgaWRlbnRpZmllcnMgPSBbXTtcbiAgdmFyIGlkZW50ID0gMDtcbiAgd2hpbGUgKCFidWZmZXIuaXNFbXB0eSgpKSB7XG4gICAgdmFyIHN1YmlkZW50ID0gYnVmZmVyLnJlYWRVSW50OCgpO1xuICAgIGlkZW50IDw8PSA3O1xuICAgIGlkZW50IHw9IHN1YmlkZW50ICYgMHg3ZjtcbiAgICBpZiAoKHN1YmlkZW50ICYgMHg4MCkgPT09IDApIHtcbiAgICAgIGlkZW50aWZpZXJzLnB1c2goaWRlbnQpO1xuICAgICAgaWRlbnQgPSAwO1xuICAgIH1cbiAgfVxuICBpZiAoc3ViaWRlbnQgJiAweDgwKVxuICAgIGlkZW50aWZpZXJzLnB1c2goaWRlbnQpO1xuXG4gIHZhciBmaXJzdCA9IChpZGVudGlmaWVyc1swXSAvIDQwKSB8IDA7XG4gIHZhciBzZWNvbmQgPSBpZGVudGlmaWVyc1swXSAlIDQwO1xuXG4gIGlmIChyZWxhdGl2ZSlcbiAgICByZXN1bHQgPSBpZGVudGlmaWVycztcbiAgZWxzZVxuICAgIHJlc3VsdCA9IFtmaXJzdCwgc2Vjb25kXS5jb25jYXQoaWRlbnRpZmllcnMuc2xpY2UoMSkpO1xuXG4gIGlmICh2YWx1ZXMpIHtcbiAgICB2YXIgdG1wID0gdmFsdWVzW3Jlc3VsdC5qb2luKCcgJyldO1xuICAgIGlmICh0bXAgPT09IHVuZGVmaW5lZClcbiAgICAgIHRtcCA9IHZhbHVlc1tyZXN1bHQuam9pbignLicpXTtcbiAgICBpZiAodG1wICE9PSB1bmRlZmluZWQpXG4gICAgICByZXN1bHQgPSB0bXA7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZVRpbWUgPSBmdW5jdGlvbiBkZWNvZGVUaW1lKGJ1ZmZlciwgdGFnKSB7XG4gIHZhciBzdHIgPSBidWZmZXIucmF3KCkudG9TdHJpbmcoKTtcbiAgaWYgKHRhZyA9PT0gJ2dlbnRpbWUnKSB7XG4gICAgdmFyIHllYXIgPSBzdHIuc2xpY2UoMCwgNCkgfCAwO1xuICAgIHZhciBtb24gPSBzdHIuc2xpY2UoNCwgNikgfCAwO1xuICAgIHZhciBkYXkgPSBzdHIuc2xpY2UoNiwgOCkgfCAwO1xuICAgIHZhciBob3VyID0gc3RyLnNsaWNlKDgsIDEwKSB8IDA7XG4gICAgdmFyIG1pbiA9IHN0ci5zbGljZSgxMCwgMTIpIHwgMDtcbiAgICB2YXIgc2VjID0gc3RyLnNsaWNlKDEyLCAxNCkgfCAwO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ3V0Y3RpbWUnKSB7XG4gICAgdmFyIHllYXIgPSBzdHIuc2xpY2UoMCwgMikgfCAwO1xuICAgIHZhciBtb24gPSBzdHIuc2xpY2UoMiwgNCkgfCAwO1xuICAgIHZhciBkYXkgPSBzdHIuc2xpY2UoNCwgNikgfCAwO1xuICAgIHZhciBob3VyID0gc3RyLnNsaWNlKDYsIDgpIHwgMDtcbiAgICB2YXIgbWluID0gc3RyLnNsaWNlKDgsIDEwKSB8IDA7XG4gICAgdmFyIHNlYyA9IHN0ci5zbGljZSgxMCwgMTIpIHwgMDtcbiAgICBpZiAoeWVhciA8IDcwKVxuICAgICAgeWVhciA9IDIwMDAgKyB5ZWFyO1xuICAgIGVsc2VcbiAgICAgIHllYXIgPSAxOTAwICsgeWVhcjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYnVmZmVyLmVycm9yKCdEZWNvZGluZyAnICsgdGFnICsgJyB0aW1lIGlzIG5vdCBzdXBwb3J0ZWQgeWV0Jyk7XG4gIH1cblxuICByZXR1cm4gRGF0ZS5VVEMoeWVhciwgbW9uIC0gMSwgZGF5LCBob3VyLCBtaW4sIHNlYywgMCk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlTnVsbCA9IGZ1bmN0aW9uIGRlY29kZU51bGwoYnVmZmVyKSB7XG4gIHJldHVybiBudWxsO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZUJvb2wgPSBmdW5jdGlvbiBkZWNvZGVCb29sKGJ1ZmZlcikge1xuICB2YXIgcmVzID0gYnVmZmVyLnJlYWRVSW50OCgpO1xuICBpZiAoYnVmZmVyLmlzRXJyb3IocmVzKSlcbiAgICByZXR1cm4gcmVzO1xuICBlbHNlXG4gICAgcmV0dXJuIHJlcyAhPT0gMDtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVJbnQgPSBmdW5jdGlvbiBkZWNvZGVJbnQoYnVmZmVyLCB2YWx1ZXMpIHtcbiAgLy8gQmlnaW50LCByZXR1cm4gYXMgaXQgaXMgKGFzc3VtZSBiaWcgZW5kaWFuKVxuICB2YXIgcmF3ID0gYnVmZmVyLnJhdygpO1xuICB2YXIgcmVzID0gbmV3IGJpZ251bShyYXcpO1xuXG4gIGlmICh2YWx1ZXMpXG4gICAgcmVzID0gdmFsdWVzW3Jlcy50b1N0cmluZygxMCldIHx8IHJlcztcblxuICByZXR1cm4gcmVzO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX3VzZSA9IGZ1bmN0aW9uIHVzZShlbnRpdHksIG9iaikge1xuICBpZiAodHlwZW9mIGVudGl0eSA9PT0gJ2Z1bmN0aW9uJylcbiAgICBlbnRpdHkgPSBlbnRpdHkob2JqKTtcbiAgcmV0dXJuIGVudGl0eS5fZ2V0RGVjb2RlcignZGVyJykudHJlZTtcbn07XG5cbi8vIFV0aWxpdHkgbWV0aG9kc1xuXG5mdW5jdGlvbiBkZXJEZWNvZGVUYWcoYnVmLCBmYWlsKSB7XG4gIHZhciB0YWcgPSBidWYucmVhZFVJbnQ4KGZhaWwpO1xuICBpZiAoYnVmLmlzRXJyb3IodGFnKSlcbiAgICByZXR1cm4gdGFnO1xuXG4gIHZhciBjbHMgPSBkZXIudGFnQ2xhc3NbdGFnID4+IDZdO1xuICB2YXIgcHJpbWl0aXZlID0gKHRhZyAmIDB4MjApID09PSAwO1xuXG4gIC8vIE11bHRpLW9jdGV0IHRhZyAtIGxvYWRcbiAgaWYgKCh0YWcgJiAweDFmKSA9PT0gMHgxZikge1xuICAgIHZhciBvY3QgPSB0YWc7XG4gICAgdGFnID0gMDtcbiAgICB3aGlsZSAoKG9jdCAmIDB4ODApID09PSAweDgwKSB7XG4gICAgICBvY3QgPSBidWYucmVhZFVJbnQ4KGZhaWwpO1xuICAgICAgaWYgKGJ1Zi5pc0Vycm9yKG9jdCkpXG4gICAgICAgIHJldHVybiBvY3Q7XG5cbiAgICAgIHRhZyA8PD0gNztcbiAgICAgIHRhZyB8PSBvY3QgJiAweDdmO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0YWcgJj0gMHgxZjtcbiAgfVxuICB2YXIgdGFnU3RyID0gZGVyLnRhZ1t0YWddO1xuXG4gIHJldHVybiB7XG4gICAgY2xzOiBjbHMsXG4gICAgcHJpbWl0aXZlOiBwcmltaXRpdmUsXG4gICAgdGFnOiB0YWcsXG4gICAgdGFnU3RyOiB0YWdTdHJcbiAgfTtcbn1cblxuZnVuY3Rpb24gZGVyRGVjb2RlTGVuKGJ1ZiwgcHJpbWl0aXZlLCBmYWlsKSB7XG4gIHZhciBsZW4gPSBidWYucmVhZFVJbnQ4KGZhaWwpO1xuICBpZiAoYnVmLmlzRXJyb3IobGVuKSlcbiAgICByZXR1cm4gbGVuO1xuXG4gIC8vIEluZGVmaW5pdGUgZm9ybVxuICBpZiAoIXByaW1pdGl2ZSAmJiBsZW4gPT09IDB4ODApXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgLy8gRGVmaW5pdGUgZm9ybVxuICBpZiAoKGxlbiAmIDB4ODApID09PSAwKSB7XG4gICAgLy8gU2hvcnQgZm9ybVxuICAgIHJldHVybiBsZW47XG4gIH1cblxuICAvLyBMb25nIGZvcm1cbiAgdmFyIG51bSA9IGxlbiAmIDB4N2Y7XG4gIGlmIChudW0gPj0gNClcbiAgICByZXR1cm4gYnVmLmVycm9yKCdsZW5ndGggb2N0ZWN0IGlzIHRvbyBsb25nJyk7XG5cbiAgbGVuID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW07IGkrKykge1xuICAgIGxlbiA8PD0gODtcbiAgICB2YXIgaiA9IGJ1Zi5yZWFkVUludDgoZmFpbCk7XG4gICAgaWYgKGJ1Zi5pc0Vycm9yKGopKVxuICAgICAgcmV0dXJuIGo7XG4gICAgbGVuIHw9IGo7XG4gIH1cblxuICByZXR1cm4gbGVuO1xufVxuIiwidmFyIGRlY29kZXJzID0gZXhwb3J0cztcblxuZGVjb2RlcnMuZGVyID0gcmVxdWlyZSgnLi9kZXInKTtcbmRlY29kZXJzLnBlbSA9IHJlcXVpcmUoJy4vcGVtJyk7XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxudmFyIERFUkRlY29kZXIgPSByZXF1aXJlKCcuL2RlcicpO1xuXG5mdW5jdGlvbiBQRU1EZWNvZGVyKGVudGl0eSkge1xuICBERVJEZWNvZGVyLmNhbGwodGhpcywgZW50aXR5KTtcbiAgdGhpcy5lbmMgPSAncGVtJztcbn07XG5pbmhlcml0cyhQRU1EZWNvZGVyLCBERVJEZWNvZGVyKTtcbm1vZHVsZS5leHBvcnRzID0gUEVNRGVjb2RlcjtcblxuUEVNRGVjb2Rlci5wcm90b3R5cGUuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKGRhdGEsIG9wdGlvbnMpIHtcbiAgdmFyIGxpbmVzID0gZGF0YS50b1N0cmluZygpLnNwbGl0KC9bXFxyXFxuXSsvZyk7XG5cbiAgdmFyIGxhYmVsID0gb3B0aW9ucy5sYWJlbC50b1VwcGVyQ2FzZSgpO1xuXG4gIHZhciByZSA9IC9eLS0tLS0oQkVHSU58RU5EKSAoW14tXSspLS0tLS0kLztcbiAgdmFyIHN0YXJ0ID0gLTE7XG4gIHZhciBlbmQgPSAtMTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBtYXRjaCA9IGxpbmVzW2ldLm1hdGNoKHJlKTtcbiAgICBpZiAobWF0Y2ggPT09IG51bGwpXG4gICAgICBjb250aW51ZTtcblxuICAgIGlmIChtYXRjaFsyXSAhPT0gbGFiZWwpXG4gICAgICBjb250aW51ZTtcblxuICAgIGlmIChzdGFydCA9PT0gLTEpIHtcbiAgICAgIGlmIChtYXRjaFsxXSAhPT0gJ0JFR0lOJylcbiAgICAgICAgYnJlYWs7XG4gICAgICBzdGFydCA9IGk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChtYXRjaFsxXSAhPT0gJ0VORCcpXG4gICAgICAgIGJyZWFrO1xuICAgICAgZW5kID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoc3RhcnQgPT09IC0xIHx8IGVuZCA9PT0gLTEpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdQRU0gc2VjdGlvbiBub3QgZm91bmQgZm9yOiAnICsgbGFiZWwpO1xuXG4gIHZhciBiYXNlNjQgPSBsaW5lcy5zbGljZShzdGFydCArIDEsIGVuZCkuam9pbignJyk7XG4gIC8vIFJlbW92ZSBleGNlc3NpdmUgc3ltYm9sc1xuICBiYXNlNjQucmVwbGFjZSgvW15hLXowLTlcXCtcXC89XSsvZ2ksICcnKTtcblxuICB2YXIgaW5wdXQgPSBuZXcgQnVmZmVyKGJhc2U2NCwgJ2Jhc2U2NCcpO1xuICByZXR1cm4gREVSRGVjb2Rlci5wcm90b3R5cGUuZGVjb2RlLmNhbGwodGhpcywgaW5wdXQsIG9wdGlvbnMpO1xufTtcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG52YXIgYXNuMSA9IHJlcXVpcmUoJy4uLy4uL2FzbjEnKTtcbnZhciBiYXNlID0gYXNuMS5iYXNlO1xuXG4vLyBJbXBvcnQgREVSIGNvbnN0YW50c1xudmFyIGRlciA9IGFzbjEuY29uc3RhbnRzLmRlcjtcblxuZnVuY3Rpb24gREVSRW5jb2RlcihlbnRpdHkpIHtcbiAgdGhpcy5lbmMgPSAnZGVyJztcbiAgdGhpcy5uYW1lID0gZW50aXR5Lm5hbWU7XG4gIHRoaXMuZW50aXR5ID0gZW50aXR5O1xuXG4gIC8vIENvbnN0cnVjdCBiYXNlIHRyZWVcbiAgdGhpcy50cmVlID0gbmV3IERFUk5vZGUoKTtcbiAgdGhpcy50cmVlLl9pbml0KGVudGl0eS5ib2R5KTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IERFUkVuY29kZXI7XG5cbkRFUkVuY29kZXIucHJvdG90eXBlLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShkYXRhLCByZXBvcnRlcikge1xuICByZXR1cm4gdGhpcy50cmVlLl9lbmNvZGUoZGF0YSwgcmVwb3J0ZXIpLmpvaW4oKTtcbn07XG5cbi8vIFRyZWUgbWV0aG9kc1xuXG5mdW5jdGlvbiBERVJOb2RlKHBhcmVudCkge1xuICBiYXNlLk5vZGUuY2FsbCh0aGlzLCAnZGVyJywgcGFyZW50KTtcbn1cbmluaGVyaXRzKERFUk5vZGUsIGJhc2UuTm9kZSk7XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVDb21wb3NpdGUgPSBmdW5jdGlvbiBlbmNvZGVDb21wb3NpdGUodGFnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmltaXRpdmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNscyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCkge1xuICB2YXIgZW5jb2RlZFRhZyA9IGVuY29kZVRhZyh0YWcsIHByaW1pdGl2ZSwgY2xzLCB0aGlzLnJlcG9ydGVyKTtcblxuICAvLyBTaG9ydCBmb3JtXG4gIGlmIChjb250ZW50Lmxlbmd0aCA8IDB4ODApIHtcbiAgICB2YXIgaGVhZGVyID0gbmV3IEJ1ZmZlcigyKTtcbiAgICBoZWFkZXJbMF0gPSBlbmNvZGVkVGFnO1xuICAgIGhlYWRlclsxXSA9IGNvbnRlbnQubGVuZ3RoO1xuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKFsgaGVhZGVyLCBjb250ZW50IF0pO1xuICB9XG5cbiAgLy8gTG9uZyBmb3JtXG4gIC8vIENvdW50IG9jdGV0cyByZXF1aXJlZCB0byBzdG9yZSBsZW5ndGhcbiAgdmFyIGxlbk9jdGV0cyA9IDE7XG4gIGZvciAodmFyIGkgPSBjb250ZW50Lmxlbmd0aDsgaSA+PSAweDEwMDsgaSA+Pj0gOClcbiAgICBsZW5PY3RldHMrKztcblxuICB2YXIgaGVhZGVyID0gbmV3IEJ1ZmZlcigxICsgMSArIGxlbk9jdGV0cyk7XG4gIGhlYWRlclswXSA9IGVuY29kZWRUYWc7XG4gIGhlYWRlclsxXSA9IDB4ODAgfCBsZW5PY3RldHM7XG5cbiAgZm9yICh2YXIgaSA9IDEgKyBsZW5PY3RldHMsIGogPSBjb250ZW50Lmxlbmd0aDsgaiA+IDA7IGktLSwgaiA+Pj0gOClcbiAgICBoZWFkZXJbaV0gPSBqICYgMHhmZjtcblxuICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihbIGhlYWRlciwgY29udGVudCBdKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVTdHIgPSBmdW5jdGlvbiBlbmNvZGVTdHIoc3RyLCB0YWcpIHtcbiAgaWYgKHRhZyA9PT0gJ2JpdHN0cicpIHtcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihbIHN0ci51bnVzZWQgfCAwLCBzdHIuZGF0YSBdKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdibXBzdHInKSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc3RyLmxlbmd0aCAqIDIpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBidWYud3JpdGVVSW50MTZCRShzdHIuY2hhckNvZGVBdChpKSwgaSAqIDIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihidWYpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ251bXN0cicpIHtcbiAgICBpZiAoIXRoaXMuX2lzTnVtc3RyKHN0cikpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdFbmNvZGluZyBvZiBzdHJpbmcgdHlwZTogbnVtc3RyIHN1cHBvcnRzICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ29ubHkgZGlnaXRzIGFuZCBzcGFjZScpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihzdHIpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ3ByaW50c3RyJykge1xuICAgIGlmICghdGhpcy5faXNQcmludHN0cihzdHIpKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignRW5jb2Rpbmcgb2Ygc3RyaW5nIHR5cGU6IHByaW50c3RyIHN1cHBvcnRzICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ29ubHkgbGF0aW4gdXBwZXIgYW5kIGxvd2VyIGNhc2UgbGV0dGVycywgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGlnaXRzLCBzcGFjZSwgYXBvc3Ryb3BoZSwgbGVmdCBhbmQgcmlndGggJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGFyZW50aGVzaXMsIHBsdXMgc2lnbiwgY29tbWEsIGh5cGhlbiwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZG90LCBzbGFzaCwgY29sb24sIGVxdWFsIHNpZ24sICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3F1ZXN0aW9uIG1hcmsnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoc3RyKTtcbiAgfSBlbHNlIGlmICgvc3RyJC8udGVzdCh0YWcpKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoc3RyKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignRW5jb2Rpbmcgb2Ygc3RyaW5nIHR5cGU6ICcgKyB0YWcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgdW5zdXBwb3J0ZWQnKTtcbiAgfVxufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2VuY29kZU9iamlkID0gZnVuY3Rpb24gZW5jb2RlT2JqaWQoaWQsIHZhbHVlcywgcmVsYXRpdmUpIHtcbiAgaWYgKHR5cGVvZiBpZCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoIXZhbHVlcylcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdzdHJpbmcgb2JqaWQgZ2l2ZW4sIGJ1dCBubyB2YWx1ZXMgbWFwIGZvdW5kJyk7XG4gICAgaWYgKCF2YWx1ZXMuaGFzT3duUHJvcGVydHkoaWQpKVxuICAgICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ29iamlkIG5vdCBmb3VuZCBpbiB2YWx1ZXMgbWFwJyk7XG4gICAgaWQgPSB2YWx1ZXNbaWRdLnNwbGl0KC9bXFxzXFwuXSsvZyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpZC5sZW5ndGg7IGkrKylcbiAgICAgIGlkW2ldIHw9IDA7XG4gIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShpZCkpIHtcbiAgICBpZCA9IGlkLnNsaWNlKCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpZC5sZW5ndGg7IGkrKylcbiAgICAgIGlkW2ldIHw9IDA7XG4gIH1cblxuICBpZiAoIUFycmF5LmlzQXJyYXkoaWQpKSB7XG4gICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ29iamlkKCkgc2hvdWxkIGJlIGVpdGhlciBhcnJheSBvciBzdHJpbmcsICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdnb3Q6ICcgKyBKU09OLnN0cmluZ2lmeShpZCkpO1xuICB9XG5cbiAgaWYgKCFyZWxhdGl2ZSkge1xuICAgIGlmIChpZFsxXSA+PSA0MClcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdTZWNvbmQgb2JqaWQgaWRlbnRpZmllciBPT0InKTtcbiAgICBpZC5zcGxpY2UoMCwgMiwgaWRbMF0gKiA0MCArIGlkWzFdKTtcbiAgfVxuXG4gIC8vIENvdW50IG51bWJlciBvZiBvY3RldHNcbiAgdmFyIHNpemUgPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGlkLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGlkZW50ID0gaWRbaV07XG4gICAgZm9yIChzaXplKys7IGlkZW50ID49IDB4ODA7IGlkZW50ID4+PSA3KVxuICAgICAgc2l6ZSsrO1xuICB9XG5cbiAgdmFyIG9iamlkID0gbmV3IEJ1ZmZlcihzaXplKTtcbiAgdmFyIG9mZnNldCA9IG9iamlkLmxlbmd0aCAtIDE7XG4gIGZvciAodmFyIGkgPSBpZC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIHZhciBpZGVudCA9IGlkW2ldO1xuICAgIG9iamlkW29mZnNldC0tXSA9IGlkZW50ICYgMHg3ZjtcbiAgICB3aGlsZSAoKGlkZW50ID4+PSA3KSA+IDApXG4gICAgICBvYmppZFtvZmZzZXQtLV0gPSAweDgwIHwgKGlkZW50ICYgMHg3Zik7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihvYmppZCk7XG59O1xuXG5mdW5jdGlvbiB0d28obnVtKSB7XG4gIGlmIChudW0gPCAxMClcbiAgICByZXR1cm4gJzAnICsgbnVtO1xuICBlbHNlXG4gICAgcmV0dXJuIG51bTtcbn1cblxuREVSTm9kZS5wcm90b3R5cGUuX2VuY29kZVRpbWUgPSBmdW5jdGlvbiBlbmNvZGVUaW1lKHRpbWUsIHRhZykge1xuICB2YXIgc3RyO1xuICB2YXIgZGF0ZSA9IG5ldyBEYXRlKHRpbWUpO1xuXG4gIGlmICh0YWcgPT09ICdnZW50aW1lJykge1xuICAgIHN0ciA9IFtcbiAgICAgIHR3byhkYXRlLmdldEZ1bGxZZWFyKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDTW9udGgoKSArIDEpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDRGF0ZSgpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ0hvdXJzKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDTWludXRlcygpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ1NlY29uZHMoKSksXG4gICAgICAnWidcbiAgICBdLmpvaW4oJycpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ3V0Y3RpbWUnKSB7XG4gICAgc3RyID0gW1xuICAgICAgdHdvKGRhdGUuZ2V0RnVsbFllYXIoKSAlIDEwMCksXG4gICAgICB0d28oZGF0ZS5nZXRVVENNb250aCgpICsgMSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENEYXRlKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDSG91cnMoKSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENNaW51dGVzKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDU2Vjb25kcygpKSxcbiAgICAgICdaJ1xuICAgIF0uam9pbignJyk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yZXBvcnRlci5lcnJvcignRW5jb2RpbmcgJyArIHRhZyArICcgdGltZSBpcyBub3Qgc3VwcG9ydGVkIHlldCcpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX2VuY29kZVN0cihzdHIsICdvY3RzdHInKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVOdWxsID0gZnVuY3Rpb24gZW5jb2RlTnVsbCgpIHtcbiAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoJycpO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2VuY29kZUludCA9IGZ1bmN0aW9uIGVuY29kZUludChudW0sIHZhbHVlcykge1xuICBpZiAodHlwZW9mIG51bSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoIXZhbHVlcylcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdTdHJpbmcgaW50IG9yIGVudW0gZ2l2ZW4sIGJ1dCBubyB2YWx1ZXMgbWFwJyk7XG4gICAgaWYgKCF2YWx1ZXMuaGFzT3duUHJvcGVydHkobnVtKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ1ZhbHVlcyBtYXAgZG9lc25cXCd0IGNvbnRhaW46ICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkobnVtKSk7XG4gICAgfVxuICAgIG51bSA9IHZhbHVlc1tudW1dO1xuICB9XG5cbiAgLy8gQmlnbnVtLCBhc3N1bWUgYmlnIGVuZGlhblxuICBpZiAodHlwZW9mIG51bSAhPT0gJ251bWJlcicgJiYgIUJ1ZmZlci5pc0J1ZmZlcihudW0pKSB7XG4gICAgdmFyIG51bUFycmF5ID0gbnVtLnRvQXJyYXkoKTtcbiAgICBpZiAoIW51bS5zaWduICYmIG51bUFycmF5WzBdICYgMHg4MCkge1xuICAgICAgbnVtQXJyYXkudW5zaGlmdCgwKTtcbiAgICB9XG4gICAgbnVtID0gbmV3IEJ1ZmZlcihudW1BcnJheSk7XG4gIH1cblxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG51bSkpIHtcbiAgICB2YXIgc2l6ZSA9IG51bS5sZW5ndGg7XG4gICAgaWYgKG51bS5sZW5ndGggPT09IDApXG4gICAgICBzaXplKys7XG5cbiAgICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihzaXplKTtcbiAgICBudW0uY29weShvdXQpO1xuICAgIGlmIChudW0ubGVuZ3RoID09PSAwKVxuICAgICAgb3V0WzBdID0gMFxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKG91dCk7XG4gIH1cblxuICBpZiAobnVtIDwgMHg4MClcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihudW0pO1xuXG4gIGlmIChudW0gPCAweDEwMClcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihbMCwgbnVtXSk7XG5cbiAgdmFyIHNpemUgPSAxO1xuICBmb3IgKHZhciBpID0gbnVtOyBpID49IDB4MTAwOyBpID4+PSA4KVxuICAgIHNpemUrKztcblxuICB2YXIgb3V0ID0gbmV3IEFycmF5KHNpemUpO1xuICBmb3IgKHZhciBpID0gb3V0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgb3V0W2ldID0gbnVtICYgMHhmZjtcbiAgICBudW0gPj49IDg7XG4gIH1cbiAgaWYob3V0WzBdICYgMHg4MCkge1xuICAgIG91dC51bnNoaWZ0KDApO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIobmV3IEJ1ZmZlcihvdXQpKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVCb29sID0gZnVuY3Rpb24gZW5jb2RlQm9vbCh2YWx1ZSkge1xuICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcih2YWx1ZSA/IDB4ZmYgOiAwKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl91c2UgPSBmdW5jdGlvbiB1c2UoZW50aXR5LCBvYmopIHtcbiAgaWYgKHR5cGVvZiBlbnRpdHkgPT09ICdmdW5jdGlvbicpXG4gICAgZW50aXR5ID0gZW50aXR5KG9iaik7XG4gIHJldHVybiBlbnRpdHkuX2dldEVuY29kZXIoJ2RlcicpLnRyZWU7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fc2tpcERlZmF1bHQgPSBmdW5jdGlvbiBza2lwRGVmYXVsdChkYXRhQnVmZmVyLCByZXBvcnRlciwgcGFyZW50KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgdmFyIGk7XG4gIGlmIChzdGF0ZVsnZGVmYXVsdCddID09PSBudWxsKVxuICAgIHJldHVybiBmYWxzZTtcblxuICB2YXIgZGF0YSA9IGRhdGFCdWZmZXIuam9pbigpO1xuICBpZiAoc3RhdGUuZGVmYXVsdEJ1ZmZlciA9PT0gdW5kZWZpbmVkKVxuICAgIHN0YXRlLmRlZmF1bHRCdWZmZXIgPSB0aGlzLl9lbmNvZGVWYWx1ZShzdGF0ZVsnZGVmYXVsdCddLCByZXBvcnRlciwgcGFyZW50KS5qb2luKCk7XG5cbiAgaWYgKGRhdGEubGVuZ3RoICE9PSBzdGF0ZS5kZWZhdWx0QnVmZmVyLmxlbmd0aClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgZm9yIChpPTA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKVxuICAgIGlmIChkYXRhW2ldICE9PSBzdGF0ZS5kZWZhdWx0QnVmZmVyW2ldKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gIHJldHVybiB0cnVlO1xufTtcblxuLy8gVXRpbGl0eSBtZXRob2RzXG5cbmZ1bmN0aW9uIGVuY29kZVRhZyh0YWcsIHByaW1pdGl2ZSwgY2xzLCByZXBvcnRlcikge1xuICB2YXIgcmVzO1xuXG4gIGlmICh0YWcgPT09ICdzZXFvZicpXG4gICAgdGFnID0gJ3NlcSc7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ3NldG9mJylcbiAgICB0YWcgPSAnc2V0JztcblxuICBpZiAoZGVyLnRhZ0J5TmFtZS5oYXNPd25Qcm9wZXJ0eSh0YWcpKVxuICAgIHJlcyA9IGRlci50YWdCeU5hbWVbdGFnXTtcbiAgZWxzZSBpZiAodHlwZW9mIHRhZyA9PT0gJ251bWJlcicgJiYgKHRhZyB8IDApID09PSB0YWcpXG4gICAgcmVzID0gdGFnO1xuICBlbHNlXG4gICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdVbmtub3duIHRhZzogJyArIHRhZyk7XG5cbiAgaWYgKHJlcyA+PSAweDFmKVxuICAgIHJldHVybiByZXBvcnRlci5lcnJvcignTXVsdGktb2N0ZXQgdGFnIGVuY29kaW5nIHVuc3VwcG9ydGVkJyk7XG5cbiAgaWYgKCFwcmltaXRpdmUpXG4gICAgcmVzIHw9IDB4MjA7XG5cbiAgcmVzIHw9IChkZXIudGFnQ2xhc3NCeU5hbWVbY2xzIHx8ICd1bml2ZXJzYWwnXSA8PCA2KTtcblxuICByZXR1cm4gcmVzO1xufVxuIiwidmFyIGVuY29kZXJzID0gZXhwb3J0cztcblxuZW5jb2RlcnMuZGVyID0gcmVxdWlyZSgnLi9kZXInKTtcbmVuY29kZXJzLnBlbSA9IHJlcXVpcmUoJy4vcGVtJyk7XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgREVSRW5jb2RlciA9IHJlcXVpcmUoJy4vZGVyJyk7XG5cbmZ1bmN0aW9uIFBFTUVuY29kZXIoZW50aXR5KSB7XG4gIERFUkVuY29kZXIuY2FsbCh0aGlzLCBlbnRpdHkpO1xuICB0aGlzLmVuYyA9ICdwZW0nO1xufTtcbmluaGVyaXRzKFBFTUVuY29kZXIsIERFUkVuY29kZXIpO1xubW9kdWxlLmV4cG9ydHMgPSBQRU1FbmNvZGVyO1xuXG5QRU1FbmNvZGVyLnByb3RvdHlwZS5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoZGF0YSwgb3B0aW9ucykge1xuICB2YXIgYnVmID0gREVSRW5jb2Rlci5wcm90b3R5cGUuZW5jb2RlLmNhbGwodGhpcywgZGF0YSk7XG5cbiAgdmFyIHAgPSBidWYudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICB2YXIgb3V0ID0gWyAnLS0tLS1CRUdJTiAnICsgb3B0aW9ucy5sYWJlbCArICctLS0tLScgXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwLmxlbmd0aDsgaSArPSA2NClcbiAgICBvdXQucHVzaChwLnNsaWNlKGksIGkgKyA2NCkpO1xuICBvdXQucHVzaCgnLS0tLS1FTkQgJyArIG9wdGlvbnMubGFiZWwgKyAnLS0tLS0nKTtcbiAgcmV0dXJuIG91dC5qb2luKCdcXG4nKTtcbn07XG4iLCIvLyBiYXNlZCBvbiB0aGUgYWVzIGltcGxpbWVudGF0aW9uIGluIHRyaXBsZSBzZWNcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9rZXliYXNlL3RyaXBsZXNlY1xuXG4vLyB3aGljaCBpcyBpbiB0dXJuIGJhc2VkIG9uIHRoZSBvbmUgZnJvbSBjcnlwdG8tanNcbi8vIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL1xuXG52YXIgdWludF9tYXggPSBNYXRoLnBvdygyLCAzMilcbmZ1bmN0aW9uIGZpeHVwX3VpbnQzMiAoeCkge1xuICB2YXIgcmV0LCB4X3Bvc1xuICByZXQgPSB4ID4gdWludF9tYXggfHwgeCA8IDAgPyAoeF9wb3MgPSBNYXRoLmFicyh4KSAlIHVpbnRfbWF4LCB4IDwgMCA/IHVpbnRfbWF4IC0geF9wb3MgOiB4X3BvcykgOiB4XG4gIHJldHVybiByZXRcbn1cbmZ1bmN0aW9uIHNjcnViX3ZlYyAodikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHYubGVuZ3RoOyB2KyspIHtcbiAgICB2W2ldID0gMFxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG5mdW5jdGlvbiBHbG9iYWwgKCkge1xuICB0aGlzLlNCT1ggPSBbXVxuICB0aGlzLklOVl9TQk9YID0gW11cbiAgdGhpcy5TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLklOVl9TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLmluaXQoKVxuICB0aGlzLlJDT04gPSBbMHgwMCwgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxYiwgMHgzNl1cbn1cblxuR2xvYmFsLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZCwgaSwgc3gsIHQsIHgsIHgyLCB4NCwgeDgsIHhpLCBfaVxuICBkID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgX2ksIF9yZXN1bHRzXG4gICAgX3Jlc3VsdHMgPSBbXVxuICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgICBpZiAoaSA8IDEyOCkge1xuICAgICAgICBfcmVzdWx0cy5wdXNoKGkgPDwgMSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9yZXN1bHRzLnB1c2goKGkgPDwgMSkgXiAweDExYilcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIF9yZXN1bHRzXG4gIH0pKClcbiAgeCA9IDBcbiAgeGkgPSAwXG4gIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgc3ggPSB4aSBeICh4aSA8PCAxKSBeICh4aSA8PCAyKSBeICh4aSA8PCAzKSBeICh4aSA8PCA0KVxuICAgIHN4ID0gKHN4ID4+PiA4KSBeIChzeCAmIDB4ZmYpIF4gMHg2M1xuICAgIHRoaXMuU0JPWFt4XSA9IHN4XG4gICAgdGhpcy5JTlZfU0JPWFtzeF0gPSB4XG4gICAgeDIgPSBkW3hdXG4gICAgeDQgPSBkW3gyXVxuICAgIHg4ID0gZFt4NF1cbiAgICB0ID0gKGRbc3hdICogMHgxMDEpIF4gKHN4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuU1VCX01JWFswXVt4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KVxuICAgIHRoaXMuU1VCX01JWFsxXVt4XSA9ICh0IDw8IDE2KSB8ICh0ID4+PiAxNilcbiAgICB0aGlzLlNVQl9NSVhbMl1beF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLlNVQl9NSVhbM11beF0gPSB0XG4gICAgdCA9ICh4OCAqIDB4MTAxMDEwMSkgXiAoeDQgKiAweDEwMDAxKSBeICh4MiAqIDB4MTAxKSBeICh4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMF1bc3hdID0gKHQgPDwgMjQpIHwgKHQgPj4+IDgpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsxXVtzeF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsyXVtzeF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLklOVl9TVUJfTUlYWzNdW3N4XSA9IHRcbiAgICBpZiAoeCA9PT0gMCkge1xuICAgICAgeCA9IHhpID0gMVxuICAgIH0gZWxzZSB7XG4gICAgICB4ID0geDIgXiBkW2RbZFt4OCBeIHgyXV1dXG4gICAgICB4aSBePSBkW2RbeGldXVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG52YXIgRyA9IG5ldyBHbG9iYWwoKVxuXG5BRVMuYmxvY2tTaXplID0gNCAqIDRcblxuQUVTLnByb3RvdHlwZS5ibG9ja1NpemUgPSBBRVMuYmxvY2tTaXplXG5cbkFFUy5rZXlTaXplID0gMjU2IC8gOFxuXG5BRVMucHJvdG90eXBlLmtleVNpemUgPSBBRVMua2V5U2l6ZVxuXG5mdW5jdGlvbiBidWZmZXJUb0FycmF5IChidWYpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGggLyA0XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkobGVuKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWYucmVhZFVJbnQzMkJFKGkgKiA0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIEFFUyAoa2V5KSB7XG4gIHRoaXMuX2tleSA9IGJ1ZmZlclRvQXJyYXkoa2V5KVxuICB0aGlzLl9kb1Jlc2V0KClcbn1cblxuQUVTLnByb3RvdHlwZS5fZG9SZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGludktzUm93LCBrZXlTaXplLCBrZXlXb3Jkcywga3NSb3csIGtzUm93cywgdFxuICBrZXlXb3JkcyA9IHRoaXMuX2tleVxuICBrZXlTaXplID0ga2V5V29yZHMubGVuZ3RoXG4gIHRoaXMuX25Sb3VuZHMgPSBrZXlTaXplICsgNlxuICBrc1Jvd3MgPSAodGhpcy5fblJvdW5kcyArIDEpICogNFxuICB0aGlzLl9rZXlTY2hlZHVsZSA9IFtdXG4gIGZvciAoa3NSb3cgPSAwOyBrc1JvdyA8IGtzUm93czsga3NSb3crKykge1xuICAgIHRoaXMuX2tleVNjaGVkdWxlW2tzUm93XSA9IGtzUm93IDwga2V5U2l6ZSA/IGtleVdvcmRzW2tzUm93XSA6ICh0ID0gdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSAxXSwgKGtzUm93ICUga2V5U2l6ZSkgPT09IDAgPyAodCA9ICh0IDw8IDgpIHwgKHQgPj4+IDI0KSwgdCA9IChHLlNCT1hbdCA+Pj4gMjRdIDw8IDI0KSB8IChHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChHLlNCT1hbKHQgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBHLlNCT1hbdCAmIDB4ZmZdLCB0IF49IEcuUkNPTlsoa3NSb3cgLyBrZXlTaXplKSB8IDBdIDw8IDI0KSA6IGtleVNpemUgPiA2ICYmIGtzUm93ICUga2V5U2l6ZSA9PT0gNCA/IHQgPSAoRy5TQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgRy5TQk9YW3QgJiAweGZmXSA6IHZvaWQgMCwgdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSBrZXlTaXplXSBeIHQpXG4gIH1cbiAgdGhpcy5faW52S2V5U2NoZWR1bGUgPSBbXVxuICBmb3IgKGludktzUm93ID0gMDsgaW52S3NSb3cgPCBrc1Jvd3M7IGludktzUm93KyspIHtcbiAgICBrc1JvdyA9IGtzUm93cyAtIGludktzUm93XG4gICAgdCA9IHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0gKGludktzUm93ICUgNCA/IDAgOiA0KV1cbiAgICB0aGlzLl9pbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSBpbnZLc1JvdyA8IDQgfHwga3NSb3cgPD0gNCA/IHQgOiBHLklOVl9TVUJfTUlYWzBdW0cuU0JPWFt0ID4+PiAyNF1dIF4gRy5JTlZfU1VCX01JWFsxXVtHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbMl1bRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbM11bRy5TQk9YW3QgJiAweGZmXV1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5BRVMucHJvdG90eXBlLmVuY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5fa2V5U2NoZWR1bGUsIEcuU1VCX01JWCwgRy5TQk9YKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxuXG5BRVMucHJvdG90eXBlLmRlY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciB0ZW1wID0gW01bM10sIE1bMV1dXG4gIE1bMV0gPSB0ZW1wWzBdXG4gIE1bM10gPSB0ZW1wWzFdXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5faW52S2V5U2NoZWR1bGUsIEcuSU5WX1NVQl9NSVgsIEcuSU5WX1NCT1gpXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKDE2KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMF0sIDApXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgNClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzJdLCA4KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDEyKVxuICByZXR1cm4gYnVmXG59XG5cbkFFUy5wcm90b3R5cGUuc2NydWIgPSBmdW5jdGlvbiAoKSB7XG4gIHNjcnViX3ZlYyh0aGlzLl9rZXlTY2hlZHVsZSlcbiAgc2NydWJfdmVjKHRoaXMuX2ludktleVNjaGVkdWxlKVxuICBzY3J1Yl92ZWModGhpcy5fa2V5KVxufVxuXG5BRVMucHJvdG90eXBlLl9kb0NyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSwga2V5U2NoZWR1bGUsIFNVQl9NSVgsIFNCT1gpIHtcbiAgdmFyIGtzUm93LCBzMCwgczEsIHMyLCBzMywgdDAsIHQxLCB0MiwgdDNcblxuICBzMCA9IE1bMF0gXiBrZXlTY2hlZHVsZVswXVxuICBzMSA9IE1bMV0gXiBrZXlTY2hlZHVsZVsxXVxuICBzMiA9IE1bMl0gXiBrZXlTY2hlZHVsZVsyXVxuICBzMyA9IE1bM10gXiBrZXlTY2hlZHVsZVszXVxuICBrc1JvdyA9IDRcbiAgZm9yICh2YXIgcm91bmQgPSAxOyByb3VuZCA8IHRoaXMuX25Sb3VuZHM7IHJvdW5kKyspIHtcbiAgICB0MCA9IFNVQl9NSVhbMF1bczAgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMxID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMyID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMyAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MSA9IFNVQl9NSVhbMF1bczEgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMyID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMzID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMCAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MiA9IFNVQl9NSVhbMF1bczIgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMzID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMwID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMSAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MyA9IFNVQl9NSVhbMF1bczMgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMwID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMxID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMiAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICBzMCA9IHQwXG4gICAgczEgPSB0MVxuICAgIHMyID0gdDJcbiAgICBzMyA9IHQzXG4gIH1cbiAgdDAgPSAoKFNCT1hbczAgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczEgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMiA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczMgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MSA9ICgoU0JPWFtzMSA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMiA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMzID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMCAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gIHQyID0gKChTQk9YW3MyID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMzID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczAgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDMgPSAoKFNCT1hbczMgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczAgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMSA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczIgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICByZXR1cm4gW1xuICAgIGZpeHVwX3VpbnQzMih0MCksXG4gICAgZml4dXBfdWludDMyKHQxKSxcbiAgICBmaXh1cF91aW50MzIodDIpLFxuICAgIGZpeHVwX3VpbnQzMih0MylcbiAgXVxufVxuXG5leHBvcnRzLkFFUyA9IEFFU1xuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgR0hBU0ggPSByZXF1aXJlKCcuL2doYXNoJylcbnZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcblxuZnVuY3Rpb24gU3RyZWFtQ2lwaGVyIChtb2RlLCBrZXksIGl2LCBkZWNyeXB0KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTdHJlYW1DaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZSwga2V5LCBpdilcbiAgfVxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLl9maW5JRCA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAxXSldKVxuICBpdiA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAyXSldKVxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgdGhpcy5fY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9zZWNDYWNoZSA9IG5ldyBCdWZmZXIoJycpXG4gIHRoaXMuX2RlY3J5cHQgPSBkZWNyeXB0XG4gIHRoaXMuX2FsZW4gPSAwXG4gIHRoaXMuX2xlbiA9IDBcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB2YXIgaCA9IG5ldyBCdWZmZXIoNClcbiAgaC5maWxsKDApXG4gIHRoaXMuX2doYXNoID0gbmV3IEdIQVNIKHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2soaCkpXG4gIHRoaXMuX2F1dGhUYWcgPSBudWxsXG4gIHRoaXMuX2NhbGxlZCA9IGZhbHNlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgaWYgKCF0aGlzLl9jYWxsZWQgJiYgdGhpcy5fYWxlbikge1xuICAgIHZhciBydW1wID0gMTYgLSAodGhpcy5fYWxlbiAlIDE2KVxuICAgIGlmIChydW1wIDwgMTYpIHtcbiAgICAgIHJ1bXAgPSBuZXcgQnVmZmVyKHJ1bXApXG4gICAgICBydW1wLmZpbGwoMClcbiAgICAgIHRoaXMuX2doYXNoLnVwZGF0ZShydW1wKVxuICAgIH1cbiAgfVxuICB0aGlzLl9jYWxsZWQgPSB0cnVlXG4gIHZhciBvdXQgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gIGlmICh0aGlzLl9kZWNyeXB0KSB7XG4gICAgdGhpcy5fZ2hhc2gudXBkYXRlKGNodW5rKVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShvdXQpXG4gIH1cbiAgdGhpcy5fbGVuICs9IGNodW5rLmxlbmd0aFxuICByZXR1cm4gb3V0XG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuX2RlY3J5cHQgJiYgIXRoaXMuX2F1dGhUYWcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YScpXG4gIH1cbiAgdmFyIHRhZyA9IHhvcih0aGlzLl9naGFzaC5maW5hbCh0aGlzLl9hbGVuICogOCwgdGhpcy5fbGVuICogOCksIHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2sodGhpcy5fZmluSUQpKVxuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIGlmICh4b3JUZXN0KHRhZywgdGhpcy5fYXV0aFRhZykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgc3RhdGUgb3IgdW5hYmxlIHRvIGF1dGhlbnRpY2F0ZSBkYXRhJylcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fYXV0aFRhZyA9IHRhZ1xuICB9XG4gIHRoaXMuX2NpcGhlci5zY3J1YigpXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiBnZXRBdXRoVGFnICgpIHtcbiAgaWYgKCF0aGlzLl9kZWNyeXB0ICYmIEJ1ZmZlci5pc0J1ZmZlcih0aGlzLl9hdXRoVGFnKSkge1xuICAgIHJldHVybiB0aGlzLl9hdXRoVGFnXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG4gIH1cbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuc2V0QXV0aFRhZyA9IGZ1bmN0aW9uIHNldEF1dGhUYWcgKHRhZykge1xuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIHRoaXMuX2F1dGhUYWcgPSB0YWdcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0F0dGVtcHRpbmcgdG8gc2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbiAgfVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiBzZXRBQUQgKGJ1Zikge1xuICBpZiAoIXRoaXMuX2NhbGxlZCkge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShidWYpXG4gICAgdGhpcy5fYWxlbiArPSBidWYubGVuZ3RoXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIHNldCBBQUQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxuICB9XG59XG5mdW5jdGlvbiB4b3JUZXN0IChhLCBiKSB7XG4gIHZhciBvdXQgPSAwXG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICBvdXQrK1xuICB9XG4gIHZhciBsZW4gPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dCArPSAoYVtpXSBeIGJbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgbW9kZXMgPSByZXF1aXJlKCcuL21vZGVzJylcbnZhciBTdHJlYW1DaXBoZXIgPSByZXF1aXJlKCcuL3N0cmVhbUNpcGhlcicpXG52YXIgQXV0aENpcGhlciA9IHJlcXVpcmUoJy4vYXV0aENpcGhlcicpXG52YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcblxuaW5oZXJpdHMoRGVjaXBoZXIsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIERlY2lwaGVyIChtb2RlLCBrZXksIGl2KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEZWNpcGhlcikpIHtcbiAgICByZXR1cm4gbmV3IERlY2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2FjaGUgPSBuZXcgU3BsaXR0ZXIoKVxuICB0aGlzLl9sYXN0ID0gdm9pZCAwXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IG5ldyBCdWZmZXIoaXYubGVuZ3RoKVxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gdHJ1ZVxufVxuRGVjaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLl9jYWNoZS5hZGQoZGF0YSlcbiAgdmFyIGNodW5rXG4gIHZhciB0aGluZ1xuICB2YXIgb3V0ID0gW11cbiAgd2hpbGUgKChjaHVuayA9IHRoaXMuX2NhY2hlLmdldCh0aGlzLl9hdXRvcGFkZGluZykpKSB7XG4gICAgdGhpbmcgPSB0aGlzLl9tb2RlLmRlY3J5cHQodGhpcywgY2h1bmspXG4gICAgb3V0LnB1c2godGhpbmcpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQob3V0KVxufVxuRGVjaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNodW5rID0gdGhpcy5fY2FjaGUuZmx1c2goKVxuICBpZiAodGhpcy5fYXV0b3BhZGRpbmcpIHtcbiAgICByZXR1cm4gdW5wYWQodGhpcy5fbW9kZS5kZWNyeXB0KHRoaXMsIGNodW5rKSlcbiAgfSBlbHNlIGlmIChjaHVuaykge1xuICAgIHRocm93IG5ldyBFcnJvcignZGF0YSBub3QgbXVsdGlwbGUgb2YgYmxvY2sgbGVuZ3RoJylcbiAgfVxufVxuRGVjaXBoZXIucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKHNldFRvKSB7XG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gISFzZXRUb1xuICByZXR1cm4gdGhpc1xufVxuZnVuY3Rpb24gU3BsaXR0ZXIgKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3BsaXR0ZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTcGxpdHRlcigpXG4gIH1cbiAgdGhpcy5jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG59XG5TcGxpdHRlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGRhdGFdKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGF1dG9QYWRkaW5nKSB7XG4gIHZhciBvdXRcbiAgaWYgKGF1dG9QYWRkaW5nKSB7XG4gICAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID4gMTYpIHtcbiAgICAgIG91dCA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICAgIHJldHVybiBvdXRcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID49IDE2KSB7XG4gICAgICBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgICByZXR1cm4gb3V0XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsXG59XG5TcGxpdHRlci5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNhY2hlLmxlbmd0aCkge1xuICAgIHJldHVybiB0aGlzLmNhY2hlXG4gIH1cbn1cbmZ1bmN0aW9uIHVucGFkIChsYXN0KSB7XG4gIHZhciBwYWRkZWQgPSBsYXN0WzE1XVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBwYWRkZWQpIHtcbiAgICBpZiAobGFzdFsoaSArICgxNiAtIHBhZGRlZCkpXSAhPT0gcGFkZGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VuYWJsZSB0byBkZWNyeXB0IGRhdGEnKVxuICAgIH1cbiAgfVxuICBpZiAocGFkZGVkID09PSAxNikge1xuICAgIHJldHVyblxuICB9XG4gIHJldHVybiBsYXN0LnNsaWNlKDAsIDE2IC0gcGFkZGVkKVxufVxuXG52YXIgbW9kZWxpc3QgPSB7XG4gIEVDQjogcmVxdWlyZSgnLi9tb2Rlcy9lY2InKSxcbiAgQ0JDOiByZXF1aXJlKCcuL21vZGVzL2NiYycpLFxuICBDRkI6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiJyksXG4gIENGQjg6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiOCcpLFxuICBDRkIxOiByZXF1aXJlKCcuL21vZGVzL2NmYjEnKSxcbiAgT0ZCOiByZXF1aXJlKCcuL21vZGVzL29mYicpLFxuICBDVFI6IHJlcXVpcmUoJy4vbW9kZXMvY3RyJyksXG4gIEdDTTogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlcml2IChzdWl0ZSwgcGFzc3dvcmQsIGl2KSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgaWYgKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHtcbiAgICBpdiA9IG5ldyBCdWZmZXIoaXYpXG4gIH1cbiAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXNzd29yZCA9IG5ldyBCdWZmZXIocGFzc3dvcmQpXG4gIH1cbiAgaWYgKHBhc3N3b3JkLmxlbmd0aCAhPT0gY29uZmlnLmtleSAvIDgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGtleSBsZW5ndGggJyArIHBhc3N3b3JkLmxlbmd0aClcbiAgfVxuICBpZiAoaXYubGVuZ3RoICE9PSBjb25maWcuaXYpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGl2IGxlbmd0aCAnICsgaXYubGVuZ3RoKVxuICB9XG4gIGlmIChjb25maWcudHlwZSA9PT0gJ3N0cmVhbScpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdiwgdHJ1ZSlcbiAgfSBlbHNlIGlmIChjb25maWcudHlwZSA9PT0gJ2F1dGgnKSB7XG4gICAgcmV0dXJuIG5ldyBBdXRoQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2LCB0cnVlKVxuICB9XG4gIHJldHVybiBuZXcgRGVjaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZURlY2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgdmFyIGNvbmZpZyA9IG1vZGVzW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuICB2YXIga2V5cyA9IGVidGsocGFzc3dvcmQsIGZhbHNlLCBjb25maWcua2V5LCBjb25maWcuaXYpXG4gIHJldHVybiBjcmVhdGVEZWNpcGhlcml2KHN1aXRlLCBrZXlzLmtleSwga2V5cy5pdilcbn1cbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXIgPSBjcmVhdGVEZWNpcGhlclxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlcml2ID0gY3JlYXRlRGVjaXBoZXJpdlxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgbW9kZXMgPSByZXF1aXJlKCcuL21vZGVzJylcbnZhciBlYnRrID0gcmVxdWlyZSgnZXZwX2J5dGVzdG9rZXknKVxudmFyIFN0cmVhbUNpcGhlciA9IHJlcXVpcmUoJy4vc3RyZWFtQ2lwaGVyJylcbnZhciBBdXRoQ2lwaGVyID0gcmVxdWlyZSgnLi9hdXRoQ2lwaGVyJylcbmluaGVyaXRzKENpcGhlciwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyIChtb2RlLCBrZXksIGl2KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBDaXBoZXIobW9kZSwga2V5LCBpdilcbiAgfVxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLl9jYWNoZSA9IG5ldyBTcGxpdHRlcigpXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IG5ldyBCdWZmZXIoaXYubGVuZ3RoKVxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gdHJ1ZVxufVxuQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5fY2FjaGUuYWRkKGRhdGEpXG4gIHZhciBjaHVua1xuICB2YXIgdGhpbmdcbiAgdmFyIG91dCA9IFtdXG4gIHdoaWxlICgoY2h1bmsgPSB0aGlzLl9jYWNoZS5nZXQoKSkpIHtcbiAgICB0aGluZyA9IHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaylcbiAgICBvdXQucHVzaCh0aGluZylcbiAgfVxuICByZXR1cm4gQnVmZmVyLmNvbmNhdChvdXQpXG59XG5DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNodW5rID0gdGhpcy5fY2FjaGUuZmx1c2goKVxuICBpZiAodGhpcy5fYXV0b3BhZGRpbmcpIHtcbiAgICBjaHVuayA9IHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaylcbiAgICB0aGlzLl9jaXBoZXIuc2NydWIoKVxuICAgIHJldHVybiBjaHVua1xuICB9IGVsc2UgaWYgKGNodW5rLnRvU3RyaW5nKCdoZXgnKSAhPT0gJzEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwJykge1xuICAgIHRoaXMuX2NpcGhlci5zY3J1YigpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhIG5vdCBtdWx0aXBsZSBvZiBibG9jayBsZW5ndGgnKVxuICB9XG59XG5DaXBoZXIucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKHNldFRvKSB7XG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gISFzZXRUb1xuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBTcGxpdHRlciAoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTcGxpdHRlcikpIHtcbiAgICByZXR1cm4gbmV3IFNwbGl0dGVyKClcbiAgfVxuICB0aGlzLmNhY2hlID0gbmV3IEJ1ZmZlcignJylcbn1cblNwbGl0dGVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLmNhY2hlID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgZGF0YV0pXG59XG5cblNwbGl0dGVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+IDE1KSB7XG4gICAgdmFyIG91dCA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgcmV0dXJuIG91dFxuICB9XG4gIHJldHVybiBudWxsXG59XG5TcGxpdHRlci5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBsZW4gPSAxNiAtIHRoaXMuY2FjaGUubGVuZ3RoXG4gIHZhciBwYWRCdWZmID0gbmV3IEJ1ZmZlcihsZW4pXG5cbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgcGFkQnVmZi53cml0ZVVJbnQ4KGxlbiwgaSlcbiAgfVxuICB2YXIgb3V0ID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgcGFkQnVmZl0pXG4gIHJldHVybiBvdXRcbn1cbnZhciBtb2RlbGlzdCA9IHtcbiAgRUNCOiByZXF1aXJlKCcuL21vZGVzL2VjYicpLFxuICBDQkM6IHJlcXVpcmUoJy4vbW9kZXMvY2JjJyksXG4gIENGQjogcmVxdWlyZSgnLi9tb2Rlcy9jZmInKSxcbiAgQ0ZCODogcmVxdWlyZSgnLi9tb2Rlcy9jZmI4JyksXG4gIENGQjE6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiMScpLFxuICBPRkI6IHJlcXVpcmUoJy4vbW9kZXMvb2ZiJyksXG4gIENUUjogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKSxcbiAgR0NNOiByZXF1aXJlKCcuL21vZGVzL2N0cicpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNpcGhlcml2IChzdWl0ZSwgcGFzc3dvcmQsIGl2KSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgaWYgKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHtcbiAgICBpdiA9IG5ldyBCdWZmZXIoaXYpXG4gIH1cbiAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXNzd29yZCA9IG5ldyBCdWZmZXIocGFzc3dvcmQpXG4gIH1cbiAgaWYgKHBhc3N3b3JkLmxlbmd0aCAhPT0gY29uZmlnLmtleSAvIDgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGtleSBsZW5ndGggJyArIHBhc3N3b3JkLmxlbmd0aClcbiAgfVxuICBpZiAoaXYubGVuZ3RoICE9PSBjb25maWcuaXYpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGl2IGxlbmd0aCAnICsgaXYubGVuZ3RoKVxuICB9XG4gIGlmIChjb25maWcudHlwZSA9PT0gJ3N0cmVhbScpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbiAgfSBlbHNlIGlmIChjb25maWcudHlwZSA9PT0gJ2F1dGgnKSB7XG4gICAgcmV0dXJuIG5ldyBBdXRoQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxuICB9XG4gIHJldHVybiBuZXcgQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxufVxuZnVuY3Rpb24gY3JlYXRlQ2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgdmFyIGNvbmZpZyA9IG1vZGVzW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuICB2YXIga2V5cyA9IGVidGsocGFzc3dvcmQsIGZhbHNlLCBjb25maWcua2V5LCBjb25maWcuaXYpXG4gIHJldHVybiBjcmVhdGVDaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5cbmV4cG9ydHMuY3JlYXRlQ2lwaGVyaXYgPSBjcmVhdGVDaXBoZXJpdlxuZXhwb3J0cy5jcmVhdGVDaXBoZXIgPSBjcmVhdGVDaXBoZXJcbiIsInZhciB6ZXJvcyA9IG5ldyBCdWZmZXIoMTYpXG56ZXJvcy5maWxsKDApXG5tb2R1bGUuZXhwb3J0cyA9IEdIQVNIXG5mdW5jdGlvbiBHSEFTSCAoa2V5KSB7XG4gIHRoaXMuaCA9IGtleVxuICB0aGlzLnN0YXRlID0gbmV3IEJ1ZmZlcigxNilcbiAgdGhpcy5zdGF0ZS5maWxsKDApXG4gIHRoaXMuY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxufVxuLy8gZnJvbSBodHRwOi8vYml0d2lzZXNoaWZ0bGVmdC5naXRodWIuaW8vc2pjbC9kb2Mvc3ltYm9scy9zcmMvY29yZV9nY20uanMuaHRtbFxuLy8gYnkgSnVobyBWw6Row6QtSGVydHR1YVxuR0hBU0gucHJvdG90eXBlLmdoYXNoID0gZnVuY3Rpb24gKGJsb2NrKSB7XG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGJsb2NrLmxlbmd0aCkge1xuICAgIHRoaXMuc3RhdGVbaV0gXj0gYmxvY2tbaV1cbiAgfVxuICB0aGlzLl9tdWx0aXBseSgpXG59XG5cbkdIQVNILnByb3RvdHlwZS5fbXVsdGlwbHkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBWaSA9IHRvQXJyYXkodGhpcy5oKVxuICB2YXIgWmkgPSBbMCwgMCwgMCwgMF1cbiAgdmFyIGosIHhpLCBsc2JfVmlcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgMTI4KSB7XG4gICAgeGkgPSAodGhpcy5zdGF0ZVt+fihpIC8gOCldICYgKDEgPDwgKDcgLSBpICUgOCkpKSAhPT0gMFxuICAgIGlmICh4aSkge1xuICAgICAgLy8gWl9pKzEgPSBaX2kgXiBWX2lcbiAgICAgIFppID0geG9yKFppLCBWaSlcbiAgICB9XG5cbiAgICAvLyBTdG9yZSB0aGUgdmFsdWUgb2YgTFNCKFZfaSlcbiAgICBsc2JfVmkgPSAoVmlbM10gJiAxKSAhPT0gMFxuXG4gICAgLy8gVl9pKzEgPSBWX2kgPj4gMVxuICAgIGZvciAoaiA9IDM7IGogPiAwOyBqLS0pIHtcbiAgICAgIFZpW2pdID0gKFZpW2pdID4+PiAxKSB8ICgoVmlbaiAtIDFdICYgMSkgPDwgMzEpXG4gICAgfVxuICAgIFZpWzBdID0gVmlbMF0gPj4+IDFcblxuICAgIC8vIElmIExTQihWX2kpIGlzIDEsIFZfaSsxID0gKFZfaSA+PiAxKSBeIFJcbiAgICBpZiAobHNiX1ZpKSB7XG4gICAgICBWaVswXSA9IFZpWzBdIF4gKDB4ZTEgPDwgMjQpXG4gICAgfVxuICB9XG4gIHRoaXMuc3RhdGUgPSBmcm9tQXJyYXkoWmkpXG59XG5HSEFTSC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGJ1Zikge1xuICB0aGlzLmNhY2hlID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgYnVmXSlcbiAgdmFyIGNodW5rXG4gIHdoaWxlICh0aGlzLmNhY2hlLmxlbmd0aCA+PSAxNikge1xuICAgIGNodW5rID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICB0aGlzLmdoYXNoKGNodW5rKVxuICB9XG59XG5HSEFTSC5wcm90b3R5cGUuZmluYWwgPSBmdW5jdGlvbiAoYWJsLCBibCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGgpIHtcbiAgICB0aGlzLmdoYXNoKEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIHplcm9zXSwgMTYpKVxuICB9XG4gIHRoaXMuZ2hhc2goZnJvbUFycmF5KFtcbiAgICAwLCBhYmwsXG4gICAgMCwgYmxcbiAgXSkpXG4gIHJldHVybiB0aGlzLnN0YXRlXG59XG5cbmZ1bmN0aW9uIHRvQXJyYXkgKGJ1Zikge1xuICByZXR1cm4gW1xuICAgIGJ1Zi5yZWFkVUludDMyQkUoMCksXG4gICAgYnVmLnJlYWRVSW50MzJCRSg0KSxcbiAgICBidWYucmVhZFVJbnQzMkJFKDgpLFxuICAgIGJ1Zi5yZWFkVUludDMyQkUoMTIpXG4gIF1cbn1cbmZ1bmN0aW9uIGZyb21BcnJheSAob3V0KSB7XG4gIG91dCA9IG91dC5tYXAoZml4dXBfdWludDMyKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxudmFyIHVpbnRfbWF4ID0gTWF0aC5wb3coMiwgMzIpXG5mdW5jdGlvbiBmaXh1cF91aW50MzIgKHgpIHtcbiAgdmFyIHJldCwgeF9wb3NcbiAgcmV0ID0geCA+IHVpbnRfbWF4IHx8IHggPCAwID8gKHhfcG9zID0gTWF0aC5hYnMoeCkgJSB1aW50X21heCwgeCA8IDAgPyB1aW50X21heCAtIHhfcG9zIDogeF9wb3MpIDogeFxuICByZXR1cm4gcmV0XG59XG5mdW5jdGlvbiB4b3IgKGEsIGIpIHtcbiAgcmV0dXJuIFtcbiAgICBhWzBdIF4gYlswXSxcbiAgICBhWzFdIF4gYlsxXSxcbiAgICBhWzJdIF4gYlsyXSxcbiAgICBhWzNdIF4gYlszXVxuICBdXG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBkYXRhLCBkZWNyeXB0KSB7XG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKCcnKVxuICB2YXIgbGVuXG5cbiAgd2hpbGUgKGRhdGEubGVuZ3RoKSB7XG4gICAgaWYgKHNlbGYuX2NhY2hlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgICBzZWxmLl9wcmV2ID0gbmV3IEJ1ZmZlcignJylcbiAgICB9XG5cbiAgICBpZiAoc2VsZi5fY2FjaGUubGVuZ3RoIDw9IGRhdGEubGVuZ3RoKSB7XG4gICAgICBsZW4gPSBzZWxmLl9jYWNoZS5sZW5ndGhcbiAgICAgIG91dCA9IEJ1ZmZlci5jb25jYXQoW291dCwgZW5jcnlwdFN0YXJ0KHNlbGYsIGRhdGEuc2xpY2UoMCwgbGVuKSwgZGVjcnlwdCldKVxuICAgICAgZGF0YSA9IGRhdGEuc2xpY2UobGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFtvdXQsIGVuY3J5cHRTdGFydChzZWxmLCBkYXRhLCBkZWNyeXB0KV0pXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIGVuY3J5cHRTdGFydCAoc2VsZiwgZGF0YSwgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gZGF0YS5sZW5ndGhcbiAgdmFyIG91dCA9IHhvcihkYXRhLCBzZWxmLl9jYWNoZSlcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShsZW4pXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LCBkZWNyeXB0ID8gZGF0YSA6IG91dF0pXG4gIHJldHVybiBvdXRcbn1cbiIsImZ1bmN0aW9uIGVuY3J5cHRCeXRlIChzZWxmLCBieXRlUGFyYW0sIGRlY3J5cHQpIHtcbiAgdmFyIHBhZFxuICB2YXIgaSA9IC0xXG4gIHZhciBsZW4gPSA4XG4gIHZhciBvdXQgPSAwXG4gIHZhciBiaXQsIHZhbHVlXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBwYWQgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgYml0ID0gKGJ5dGVQYXJhbSAmICgxIDw8ICg3IC0gaSkpKSA/IDB4ODAgOiAwXG4gICAgdmFsdWUgPSBwYWRbMF0gXiBiaXRcbiAgICBvdXQgKz0gKCh2YWx1ZSAmIDB4ODApID4+IChpICUgOCkpXG4gICAgc2VsZi5fcHJldiA9IHNoaWZ0SW4oc2VsZi5fcHJldiwgZGVjcnlwdCA/IGJpdCA6IHZhbHVlKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaywgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gY2h1bmsubGVuZ3RoXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGxlbilcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gZW5jcnlwdEJ5dGUoc2VsZiwgY2h1bmtbaV0sIGRlY3J5cHQpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuZnVuY3Rpb24gc2hpZnRJbiAoYnVmZmVyLCB2YWx1ZSkge1xuICB2YXIgbGVuID0gYnVmZmVyLmxlbmd0aFxuICB2YXIgaSA9IC0xXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGJ1ZmZlci5sZW5ndGgpXG4gIGJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW2J1ZmZlciwgbmV3IEJ1ZmZlcihbdmFsdWVdKV0pXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWZmZXJbaV0gPDwgMSB8IGJ1ZmZlcltpICsgMV0gPj4gKDcpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwiZnVuY3Rpb24gZW5jcnlwdEJ5dGUgKHNlbGYsIGJ5dGVQYXJhbSwgZGVjcnlwdCkge1xuICB2YXIgcGFkID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICB2YXIgb3V0ID0gcGFkWzBdIF4gYnl0ZVBhcmFtXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LnNsaWNlKDEpLCBuZXcgQnVmZmVyKFtkZWNyeXB0ID8gYnl0ZVBhcmFtIDogb3V0XSldKVxuICByZXR1cm4gb3V0XG59XG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgY2h1bmssIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGNodW5rLmxlbmd0aFxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihsZW4pXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGVuY3J5cHRCeXRlKHNlbGYsIGNodW5rW2ldLCBkZWNyeXB0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gaW5jcjMyIChpdikge1xuICB2YXIgbGVuID0gaXYubGVuZ3RoXG4gIHZhciBpdGVtXG4gIHdoaWxlIChsZW4tLSkge1xuICAgIGl0ZW0gPSBpdi5yZWFkVUludDgobGVuKVxuICAgIGlmIChpdGVtID09PSAyNTUpIHtcbiAgICAgIGl2LndyaXRlVUludDgoMCwgbGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBpdGVtKytcbiAgICAgIGl2LndyaXRlVUludDgoaXRlbSwgbGVuKVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgdmFyIG91dCA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgaW5jcjMyKHNlbGYuX3ByZXYpXG4gIHJldHVybiBvdXRcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cbiAgdmFyIHBhZCA9IHNlbGYuX2NhY2hlLnNsaWNlKDAsIGNodW5rLmxlbmd0aClcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShjaHVuay5sZW5ndGgpXG4gIHJldHVybiB4b3IoY2h1bmssIHBhZClcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgc2VsZi5fcHJldiA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgcmV0dXJuIHNlbGYuX3ByZXZcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cblxuICB2YXIgcGFkID0gc2VsZi5fY2FjaGUuc2xpY2UoMCwgY2h1bmsubGVuZ3RoKVxuICBzZWxmLl9jYWNoZSA9IHNlbGYuX2NhY2hlLnNsaWNlKGNodW5rLmxlbmd0aClcbiAgcmV0dXJuIHhvcihjaHVuaywgcGFkKVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB4b3IgKGEsIGIpIHtcbiAgdmFyIGxlbmd0aCA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aClcbiAgdmFyIGJ1ZmZlciA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBidWZmZXJbaV0gPSBhW2ldIF4gYltpXVxuICB9XG5cbiAgcmV0dXJuIGJ1ZmZlclxufVxuIiwidmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyQmFzZVxuaW5oZXJpdHMoQ2lwaGVyQmFzZSwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyQmFzZSAoaGFzaE1vZGUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5oYXNoTW9kZSA9IHR5cGVvZiBoYXNoTW9kZSA9PT0gJ3N0cmluZydcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICB0aGlzW2hhc2hNb2RlXSA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZpbmFsID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9XG4gIHRoaXMuX2RlY29kZXIgPSBudWxsXG4gIHRoaXMuX2VuY29kaW5nID0gbnVsbFxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGlucHV0RW5jKVxuICB9XG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYylcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uICgpIHt9XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGFhZCBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1c2godGhpcy5fdXBkYXRlKGRhdGEpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBuZXh0KGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGRvbmUpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIGRvbmUoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9maW5hbCgpIHx8IG5ldyBCdWZmZXIoJycpXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jLCB0cnVlKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90b1N0cmluZyA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jLCBmaW5hbCkge1xuICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKVxuICAgIHRoaXMuX2VuY29kaW5nID0gZW5jXG4gIH1cbiAgaWYgKHRoaXMuX2VuY29kaW5nICE9PSBlbmMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhblxcJ3Qgc3dpdGNoIGVuY29kaW5ncycpXG4gIH1cbiAgdmFyIG91dCA9IHRoaXMuX2RlY29kZXIud3JpdGUodmFsdWUpXG4gIGlmIChmaW5hbCkge1xuICAgIG91dCArPSB0aGlzLl9kZWNvZGVyLmVuZCgpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcbmZ1bmN0aW9uIFN0cmVhbUNpcGhlciAobW9kZSwga2V5LCBpdiwgZGVjcnlwdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3RyZWFtQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gbmV3IEJ1ZmZlcihpdi5sZW5ndGgpXG4gIHRoaXMuX2NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fc2VjQ2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9kZWNyeXB0ID0gZGVjcnlwdFxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgcmV0dXJuIHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaywgdGhpcy5fZGVjcnlwdClcbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9jaXBoZXIuc2NydWIoKVxufVxuIiwidmFyIG1kNSA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoL21kNScpXG5tb2R1bGUuZXhwb3J0cyA9IEVWUF9CeXRlc1RvS2V5XG5mdW5jdGlvbiBFVlBfQnl0ZXNUb0tleSAocGFzc3dvcmQsIHNhbHQsIGtleUxlbiwgaXZMZW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocGFzc3dvcmQpKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkLCAnYmluYXJ5JylcbiAgfVxuICBpZiAoc2FsdCAmJiAhQnVmZmVyLmlzQnVmZmVyKHNhbHQpKSB7XG4gICAgc2FsdCA9IG5ldyBCdWZmZXIoc2FsdCwgJ2JpbmFyeScpXG4gIH1cbiAga2V5TGVuID0ga2V5TGVuIC8gOFxuICBpdkxlbiA9IGl2TGVuIHx8IDBcbiAgdmFyIGtpID0gMFxuICB2YXIgaWkgPSAwXG4gIHZhciBrZXkgPSBuZXcgQnVmZmVyKGtleUxlbilcbiAgdmFyIGl2ID0gbmV3IEJ1ZmZlcihpdkxlbilcbiAgdmFyIGFkZG1kID0gMFxuICB2YXIgbWRfYnVmXG4gIHZhciBpXG4gIHZhciBidWZzID0gW11cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoYWRkbWQrKyA+IDApIHtcbiAgICAgIGJ1ZnMucHVzaChtZF9idWYpXG4gICAgfVxuICAgIGJ1ZnMucHVzaChwYXNzd29yZClcbiAgICBpZiAoc2FsdCkge1xuICAgICAgYnVmcy5wdXNoKHNhbHQpXG4gICAgfVxuICAgIG1kX2J1ZiA9IG1kNShCdWZmZXIuY29uY2F0KGJ1ZnMpKVxuICAgIGJ1ZnMgPSBbXVxuICAgIGkgPSAwXG4gICAgaWYgKGtleUxlbiA+IDApIHtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGlmIChrZXlMZW4gPT09IDApIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGlmIChpID09PSBtZF9idWYubGVuZ3RoKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBrZXlba2krK10gPSBtZF9idWZbaV1cbiAgICAgICAga2V5TGVuLS1cbiAgICAgICAgaSsrXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpdkxlbiA+IDAgJiYgaSAhPT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaWYgKGl2TGVuID09PSAwKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaXZbaWkrK10gPSBtZF9idWZbaV1cbiAgICAgICAgaXZMZW4tLVxuICAgICAgICBpKytcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGtleUxlbiA9PT0gMCAmJiBpdkxlbiA9PT0gMCkge1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMDsgaSA8IG1kX2J1Zi5sZW5ndGg7IGkrKykge1xuICAgIG1kX2J1ZltpXSA9IDBcbiAgfVxuICByZXR1cm4ge1xuICAgIGtleToga2V5LFxuICAgIGl2OiBpdlxuICB9XG59XG4iLCIvLyBtdWNoIG9mIHRoaXMgYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2luZHV0bnkvc2VsZi1zaWduZWQvYmxvYi9naC1wYWdlcy9saWIvcnNhLmpzXG52YXIgY3JlYXRlSG1hYyA9IHJlcXVpcmUoJ2NyZWF0ZS1obWFjJylcbnZhciBjcnQgPSByZXF1aXJlKCdicm93c2VyaWZ5LXJzYScpXG52YXIgY3VydmVzID0gcmVxdWlyZSgnLi9jdXJ2ZXMnKVxudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnZWxsaXB0aWMnKVxudmFyIHBhcnNlS2V5cyA9IHJlcXVpcmUoJ3BhcnNlLWFzbjEnKVxuXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpXG52YXIgRUMgPSBlbGxpcHRpYy5lY1xuXG5mdW5jdGlvbiBzaWduIChoYXNoLCBrZXksIGhhc2hUeXBlLCBzaWduVHlwZSkge1xuICB2YXIgcHJpdiA9IHBhcnNlS2V5cyhrZXkpXG4gIGlmIChwcml2LmN1cnZlKSB7XG4gICAgaWYgKHNpZ25UeXBlICE9PSAnZWNkc2EnKSB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHByaXZhdGUga2V5IHR5cGUnKVxuXG4gICAgcmV0dXJuIGVjU2lnbihoYXNoLCBwcml2KVxuICB9IGVsc2UgaWYgKHByaXYudHlwZSA9PT0gJ2RzYScpIHtcbiAgICBpZiAoc2lnblR5cGUgIT09ICdkc2EnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHByaXZhdGUga2V5IHR5cGUnKVxuICAgIH1cbiAgICByZXR1cm4gZHNhU2lnbihoYXNoLCBwcml2LCBoYXNoVHlwZSlcbiAgfSBlbHNlIHtcbiAgICBpZiAoc2lnblR5cGUgIT09ICdyc2EnKSB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHByaXZhdGUga2V5IHR5cGUnKVxuICB9XG5cbiAgdmFyIGxlbiA9IHByaXYubW9kdWx1cy5ieXRlTGVuZ3RoKClcbiAgdmFyIHBhZCA9IFsgMCwgMSBdXG4gIHdoaWxlIChoYXNoLmxlbmd0aCArIHBhZC5sZW5ndGggKyAxIDwgbGVuKSB7XG4gICAgcGFkLnB1c2goMHhmZilcbiAgfVxuICBwYWQucHVzaCgweDAwKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBoYXNoLmxlbmd0aCkge1xuICAgIHBhZC5wdXNoKGhhc2hbaV0pXG4gIH1cblxuICB2YXIgb3V0ID0gY3J0KHBhZCwgcHJpdilcbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiBlY1NpZ24gKGhhc2gsIHByaXYpIHtcbiAgdmFyIGN1cnZlSWQgPSBjdXJ2ZXNbcHJpdi5jdXJ2ZS5qb2luKCcuJyldXG4gIGlmICghY3VydmVJZCkgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGN1cnZlICcgKyBwcml2LmN1cnZlLmpvaW4oJy4nKSlcblxuICB2YXIgY3VydmUgPSBuZXcgRUMoY3VydmVJZClcbiAgdmFyIGtleSA9IGN1cnZlLmdlbktleVBhaXIoKVxuXG4gIGtleS5faW1wb3J0UHJpdmF0ZShwcml2LnByaXZhdGVLZXkpXG4gIHZhciBvdXQgPSBrZXkuc2lnbihoYXNoKVxuXG4gIHJldHVybiBuZXcgQnVmZmVyKG91dC50b0RFUigpKVxufVxuXG5mdW5jdGlvbiBkc2FTaWduIChoYXNoLCBwcml2LCBhbGdvKSB7XG4gIHZhciB4ID0gcHJpdi5wYXJhbXMucHJpdl9rZXlcbiAgdmFyIHAgPSBwcml2LnBhcmFtcy5wXG4gIHZhciBxID0gcHJpdi5wYXJhbXMucVxuICB2YXIgZyA9IHByaXYucGFyYW1zLmdcbiAgdmFyIHIgPSBuZXcgQk4oMClcbiAgdmFyIGtcbiAgdmFyIEggPSBiaXRzMmludChoYXNoLCBxKS5tb2QocSlcbiAgdmFyIHMgPSBmYWxzZVxuICB2YXIga3YgPSBnZXRLZXkoeCwgcSwgaGFzaCwgYWxnbylcbiAgd2hpbGUgKHMgPT09IGZhbHNlKSB7XG4gICAgayA9IG1ha2VLZXkocSwga3YsIGFsZ28pXG4gICAgciA9IG1ha2VSKGcsIGssIHAsIHEpXG4gICAgcyA9IGsuaW52bShxKS5pbXVsKEguYWRkKHgubXVsKHIpKSkubW9kKHEpXG4gICAgaWYgKCFzLmNtcG4oMCkpIHtcbiAgICAgIHMgPSBmYWxzZVxuICAgICAgciA9IG5ldyBCTigwKVxuICAgIH1cbiAgfVxuICByZXR1cm4gdG9ERVIociwgcylcbn1cblxuZnVuY3Rpb24gdG9ERVIgKHIsIHMpIHtcbiAgciA9IHIudG9BcnJheSgpXG4gIHMgPSBzLnRvQXJyYXkoKVxuXG4gIC8vIFBhZCB2YWx1ZXNcbiAgaWYgKHJbMF0gJiAweDgwKSB7XG4gICAgciA9IFsgMCBdLmNvbmNhdChyKVxuICB9XG4gIC8vIFBhZCB2YWx1ZXNcbiAgaWYgKHNbMF0gJiAweDgwKSB7XG4gICAgcyA9IFswXS5jb25jYXQocylcbiAgfVxuXG4gIHZhciB0b3RhbCA9IHIubGVuZ3RoICsgcy5sZW5ndGggKyA0XG4gIHZhciByZXMgPSBbIDB4MzAsIHRvdGFsLCAweDAyLCByLmxlbmd0aCBdXG4gIHJlcyA9IHJlcy5jb25jYXQociwgWyAweDAyLCBzLmxlbmd0aCBdLCBzKVxuICByZXR1cm4gbmV3IEJ1ZmZlcihyZXMpXG59XG5cbmZ1bmN0aW9uIGdldEtleSAoeCwgcSwgaGFzaCwgYWxnbykge1xuICB4ID0gbmV3IEJ1ZmZlcih4LnRvQXJyYXkoKSlcbiAgaWYgKHgubGVuZ3RoIDwgcS5ieXRlTGVuZ3RoKCkpIHtcbiAgICB2YXIgemVyb3MgPSBuZXcgQnVmZmVyKHEuYnl0ZUxlbmd0aCgpIC0geC5sZW5ndGgpXG4gICAgemVyb3MuZmlsbCgwKVxuICAgIHggPSBCdWZmZXIuY29uY2F0KFt6ZXJvcywgeF0pXG4gIH1cbiAgdmFyIGhsZW4gPSBoYXNoLmxlbmd0aFxuICB2YXIgaGJpdHMgPSBiaXRzMm9jdGV0cyhoYXNoLCBxKVxuICB2YXIgdiA9IG5ldyBCdWZmZXIoaGxlbilcbiAgdi5maWxsKDEpXG4gIHZhciBrID0gbmV3IEJ1ZmZlcihobGVuKVxuICBrLmZpbGwoMClcbiAgayA9IGNyZWF0ZUhtYWMoYWxnbywgaylcbiAgICAudXBkYXRlKHYpXG4gICAgLnVwZGF0ZShuZXcgQnVmZmVyKFswXSkpXG4gICAgLnVwZGF0ZSh4KVxuICAgIC51cGRhdGUoaGJpdHMpXG4gICAgLmRpZ2VzdCgpXG4gIHYgPSBjcmVhdGVIbWFjKGFsZ28sIGspXG4gICAgLnVwZGF0ZSh2KVxuICAgIC5kaWdlc3QoKVxuICBrID0gY3JlYXRlSG1hYyhhbGdvLCBrKVxuICAgIC51cGRhdGUodilcbiAgICAudXBkYXRlKG5ldyBCdWZmZXIoWzFdKSlcbiAgICAudXBkYXRlKHgpXG4gICAgLnVwZGF0ZShoYml0cylcbiAgICAuZGlnZXN0KClcbiAgdiA9IGNyZWF0ZUhtYWMoYWxnbywgaylcbiAgICAudXBkYXRlKHYpXG4gICAgLmRpZ2VzdCgpXG4gIHJldHVybiB7XG4gICAgazogayxcbiAgICB2OiB2XG4gIH1cbn1cblxuZnVuY3Rpb24gYml0czJpbnQgKG9iaXRzLCBxKSB7XG4gIHZhciBiaXRzID0gbmV3IEJOKG9iaXRzKVxuICB2YXIgc2hpZnQgPSAob2JpdHMubGVuZ3RoIDw8IDMpIC0gcS5iaXRMZW5ndGgoKVxuICBpZiAoc2hpZnQgPiAwKSB7XG4gICAgYml0cy5pc2hybihzaGlmdClcbiAgfVxuICByZXR1cm4gYml0c1xufVxuXG5mdW5jdGlvbiBiaXRzMm9jdGV0cyAoYml0cywgcSkge1xuICBiaXRzID0gYml0czJpbnQoYml0cywgcSlcbiAgYml0cyA9IGJpdHMubW9kKHEpXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGJpdHMudG9BcnJheSgpKVxuICBpZiAob3V0Lmxlbmd0aCA8IHEuYnl0ZUxlbmd0aCgpKSB7XG4gICAgdmFyIHplcm9zID0gbmV3IEJ1ZmZlcihxLmJ5dGVMZW5ndGgoKSAtIG91dC5sZW5ndGgpXG4gICAgemVyb3MuZmlsbCgwKVxuICAgIG91dCA9IEJ1ZmZlci5jb25jYXQoW3plcm9zLCBvdXRdKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gbWFrZUtleSAocSwga3YsIGFsZ28pIHtcbiAgdmFyIHQsIGtcblxuICBkbyB7XG4gICAgdCA9IG5ldyBCdWZmZXIoJycpXG5cbiAgICB3aGlsZSAodC5sZW5ndGggKiA4IDwgcS5iaXRMZW5ndGgoKSkge1xuICAgICAga3YudiA9IGNyZWF0ZUhtYWMoYWxnbywga3YuaylcbiAgICAgICAgLnVwZGF0ZShrdi52KVxuICAgICAgICAuZGlnZXN0KClcbiAgICAgIHQgPSBCdWZmZXIuY29uY2F0KFt0LCBrdi52XSlcbiAgICB9XG5cbiAgICBrID0gYml0czJpbnQodCwgcSlcbiAgICBrdi5rID0gY3JlYXRlSG1hYyhhbGdvLCBrdi5rKVxuICAgICAgLnVwZGF0ZShrdi52KVxuICAgICAgLnVwZGF0ZShuZXcgQnVmZmVyKFswXSkpXG4gICAgICAuZGlnZXN0KClcbiAgICBrdi52ID0gY3JlYXRlSG1hYyhhbGdvLCBrdi5rKVxuICAgICAgLnVwZGF0ZShrdi52KVxuICAgICAgLmRpZ2VzdCgpXG4gIH0gd2hpbGUgKGsuY21wKHEpICE9PSAtMSlcblxuICByZXR1cm4ga1xufVxuXG5mdW5jdGlvbiBtYWtlUiAoZywgaywgcCwgcSkge1xuICByZXR1cm4gZy50b1JlZChCTi5tb250KHApKS5yZWRQb3coaykuZnJvbVJlZCgpLm1vZChxKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNpZ25cbm1vZHVsZS5leHBvcnRzLmdldEtleSA9IGdldEtleVxubW9kdWxlLmV4cG9ydHMubWFrZUtleSA9IG1ha2VLZXlcbiIsIi8vIG11Y2ggb2YgdGhpcyBiYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9zZWxmLXNpZ25lZC9ibG9iL2doLXBhZ2VzL2xpYi9yc2EuanNcbnZhciBjdXJ2ZXMgPSByZXF1aXJlKCcuL2N1cnZlcycpXG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCdlbGxpcHRpYycpXG52YXIgcGFyc2VLZXlzID0gcmVxdWlyZSgncGFyc2UtYXNuMScpXG5cbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJylcbnZhciBFQyA9IGVsbGlwdGljLmVjXG5cbmZ1bmN0aW9uIHZlcmlmeSAoc2lnLCBoYXNoLCBrZXksIHNpZ25UeXBlKSB7XG4gIHZhciBwdWIgPSBwYXJzZUtleXMoa2V5KVxuICBpZiAocHViLnR5cGUgPT09ICdlYycpIHtcbiAgICBpZiAoc2lnblR5cGUgIT09ICdlY2RzYScpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignd3JvbmcgcHVibGljIGtleSB0eXBlJylcbiAgICB9XG4gICAgcmV0dXJuIGVjVmVyaWZ5KHNpZywgaGFzaCwgcHViKVxuICB9IGVsc2UgaWYgKHB1Yi50eXBlID09PSAnZHNhJykge1xuICAgIGlmIChzaWduVHlwZSAhPT0gJ2RzYScpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignd3JvbmcgcHVibGljIGtleSB0eXBlJylcbiAgICB9XG4gICAgcmV0dXJuIGRzYVZlcmlmeShzaWcsIGhhc2gsIHB1YilcbiAgfSBlbHNlIHtcbiAgICBpZiAoc2lnblR5cGUgIT09ICdyc2EnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHB1YmxpYyBrZXkgdHlwZScpXG4gICAgfVxuICB9XG4gIHZhciBsZW4gPSBwdWIubW9kdWx1cy5ieXRlTGVuZ3RoKClcbiAgdmFyIHBhZCA9IFsgMSBdXG4gIHZhciBwYWROdW0gPSAwXG4gIHdoaWxlIChoYXNoLmxlbmd0aCArIHBhZC5sZW5ndGggKyAyIDwgbGVuKSB7XG4gICAgcGFkLnB1c2goMHhmZilcbiAgICBwYWROdW0rK1xuICB9XG4gIHBhZC5wdXNoKDB4MDApXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGhhc2gubGVuZ3RoKSB7XG4gICAgcGFkLnB1c2goaGFzaFtpXSlcbiAgfVxuICBwYWQgPSBuZXcgQnVmZmVyKHBhZClcbiAgdmFyIHJlZCA9IEJOLm1vbnQocHViLm1vZHVsdXMpXG4gIHNpZyA9IG5ldyBCTihzaWcpLnRvUmVkKHJlZClcblxuICBzaWcgPSBzaWcucmVkUG93KG5ldyBCTihwdWIucHVibGljRXhwb25lbnQpKVxuXG4gIHNpZyA9IG5ldyBCdWZmZXIoc2lnLmZyb21SZWQoKS50b0FycmF5KCkpXG4gIHZhciBvdXQgPSAwXG4gIGlmIChwYWROdW0gPCA4KSB7XG4gICAgb3V0ID0gMVxuICB9XG4gIGxlbiA9IE1hdGgubWluKHNpZy5sZW5ndGgsIHBhZC5sZW5ndGgpXG4gIGlmIChzaWcubGVuZ3RoICE9PSBwYWQubGVuZ3RoKSB7XG4gICAgb3V0ID0gMVxuICB9XG5cbiAgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXQgfD0gKHNpZ1tpXSBeIHBhZFtpXSlcbiAgfVxuICByZXR1cm4gb3V0ID09PSAwXG59XG5cbmZ1bmN0aW9uIGVjVmVyaWZ5IChzaWcsIGhhc2gsIHB1Yikge1xuICB2YXIgY3VydmVJZCA9IGN1cnZlc1twdWIuZGF0YS5hbGdvcml0aG0uY3VydmUuam9pbignLicpXVxuICBpZiAoIWN1cnZlSWQpIHRocm93IG5ldyBFcnJvcigndW5rbm93biBjdXJ2ZSAnICsgcHViLmRhdGEuYWxnb3JpdGhtLmN1cnZlLmpvaW4oJy4nKSlcblxuICB2YXIgY3VydmUgPSBuZXcgRUMoY3VydmVJZClcbiAgdmFyIHB1YmtleSA9IHB1Yi5kYXRhLnN1YmplY3RQcml2YXRlS2V5LmRhdGFcblxuICByZXR1cm4gY3VydmUudmVyaWZ5KGhhc2gsIHNpZywgcHVia2V5KVxufVxuXG5mdW5jdGlvbiBkc2FWZXJpZnkgKHNpZywgaGFzaCwgcHViKSB7XG4gIHZhciBwID0gcHViLmRhdGEucFxuICB2YXIgcSA9IHB1Yi5kYXRhLnFcbiAgdmFyIGcgPSBwdWIuZGF0YS5nXG4gIHZhciB5ID0gcHViLmRhdGEucHViX2tleVxuICB2YXIgdW5wYWNrZWQgPSBwYXJzZUtleXMuc2lnbmF0dXJlLmRlY29kZShzaWcsICdkZXInKVxuICB2YXIgcyA9IHVucGFja2VkLnNcbiAgdmFyIHIgPSB1bnBhY2tlZC5yXG4gIGNoZWNrVmFsdWUocywgcSlcbiAgY2hlY2tWYWx1ZShyLCBxKVxuICB2YXIgbW9udHAgPSBCTi5tb250KHApXG4gIHZhciB3ID0gcy5pbnZtKHEpXG4gIHZhciB2ID0gZy50b1JlZChtb250cClcbiAgICAucmVkUG93KG5ldyBCTihoYXNoKS5tdWwodykubW9kKHEpKVxuICAgIC5mcm9tUmVkKClcbiAgICAubXVsKFxuICAgICAgeS50b1JlZChtb250cClcbiAgICAgICAgLnJlZFBvdyhyLm11bCh3KS5tb2QocSkpXG4gICAgICAgIC5mcm9tUmVkKClcbiAgKS5tb2QocCkubW9kKHEpXG4gIHJldHVybiAhdi5jbXAocilcbn1cblxuZnVuY3Rpb24gY2hlY2tWYWx1ZSAoYiwgcSkge1xuICBpZiAoYi5jbXBuKDApIDw9IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgc2lnJylcbiAgfVxuICBpZiAoYi5jbXAocSkgPj0gcSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzaWcnKVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdmVyaWZ5XG4iLCJ2YXIgZWxsaXB0aWMgPSByZXF1aXJlKCdlbGxpcHRpYycpO1xudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmVhdGVFQ0RIKGN1cnZlKSB7XG5cdHJldHVybiBuZXcgRUNESChjdXJ2ZSk7XG59O1xuXG52YXIgYWxpYXNlcyA9IHtcblx0c2VjcDI1NmsxOiB7XG5cdFx0bmFtZTogJ3NlY3AyNTZrMScsXG5cdFx0Ynl0ZUxlbmd0aDogMzJcblx0fSxcblx0c2VjcDIyNHIxOiB7XG5cdFx0bmFtZTogJ3AyMjQnLFxuXHRcdGJ5dGVMZW5ndGg6IDI4XG5cdH0sXG5cdHByaW1lMjU2djE6IHtcblx0XHRuYW1lOiAncDI1NicsXG5cdFx0Ynl0ZUxlbmd0aDogMzJcblx0fSxcblx0cHJpbWUxOTJ2MToge1xuXHRcdG5hbWU6ICdwMTkyJyxcblx0XHRieXRlTGVuZ3RoOiAyNFxuXHR9LFxuXHRlZDI1NTE5OiB7XG5cdFx0bmFtZTogJ2VkMjU1MTknLFxuXHRcdGJ5dGVMZW5ndGg6IDMyXG5cdH0sXG5cdHNlY3AzODRyMToge1xuXHRcdG5hbWU6ICdwMzg0Jyxcblx0XHRieXRlTGVuZ3RoOiA0OFxuXHR9LFxuXHRzZWNwNTIxcjE6IHtcblx0XHRuYW1lOiAncDUyMScsXG5cdFx0Ynl0ZUxlbmd0aDogNjZcblx0fVxufTtcblxuYWxpYXNlcy5wMjI0ID0gYWxpYXNlcy5zZWNwMjI0cjE7XG5hbGlhc2VzLnAyNTYgPSBhbGlhc2VzLnNlY3AyNTZyMSA9IGFsaWFzZXMucHJpbWUyNTZ2MTtcbmFsaWFzZXMucDE5MiA9IGFsaWFzZXMuc2VjcDE5MnIxID0gYWxpYXNlcy5wcmltZTE5MnYxO1xuYWxpYXNlcy5wMzg0ID0gYWxpYXNlcy5zZWNwMzg0cjE7XG5hbGlhc2VzLnA1MjEgPSBhbGlhc2VzLnNlY3A1MjFyMTtcblxuZnVuY3Rpb24gRUNESChjdXJ2ZSkge1xuXHR0aGlzLmN1cnZlVHlwZSA9IGFsaWFzZXNbY3VydmVdO1xuXHRpZiAoIXRoaXMuY3VydmVUeXBlICkge1xuXHRcdHRoaXMuY3VydmVUeXBlID0ge1xuXHRcdFx0bmFtZTogY3VydmVcblx0XHR9O1xuXHR9XG5cdHRoaXMuY3VydmUgPSBuZXcgZWxsaXB0aWMuZWModGhpcy5jdXJ2ZVR5cGUubmFtZSk7XG5cdHRoaXMua2V5cyA9IHZvaWQgMDtcbn1cblxuRUNESC5wcm90b3R5cGUuZ2VuZXJhdGVLZXlzID0gZnVuY3Rpb24gKGVuYywgZm9ybWF0KSB7XG5cdHRoaXMua2V5cyA9IHRoaXMuY3VydmUuZ2VuS2V5UGFpcigpO1xuXHRyZXR1cm4gdGhpcy5nZXRQdWJsaWNLZXkoZW5jLCBmb3JtYXQpO1xufTtcblxuRUNESC5wcm90b3R5cGUuY29tcHV0ZVNlY3JldCA9IGZ1bmN0aW9uIChvdGhlciwgaW5lbmMsIGVuYykge1xuXHRpbmVuYyA9IGluZW5jIHx8ICd1dGY4Jztcblx0aWYgKCFCdWZmZXIuaXNCdWZmZXIob3RoZXIpKSB7XG5cdFx0b3RoZXIgPSBuZXcgQnVmZmVyKG90aGVyLCBpbmVuYyk7XG5cdH1cblx0dmFyIG90aGVyUHViID0gdGhpcy5jdXJ2ZS5rZXlGcm9tUHVibGljKG90aGVyKS5nZXRQdWJsaWMoKTtcblx0dmFyIG91dCA9IG90aGVyUHViLm11bCh0aGlzLmtleXMuZ2V0UHJpdmF0ZSgpKS5nZXRYKCk7XG5cdHJldHVybiBmb3JtYXRSZXR1cm5WYWx1ZShvdXQsIGVuYywgdGhpcy5jdXJ2ZVR5cGUuYnl0ZUxlbmd0aCk7XG59O1xuXG5FQ0RILnByb3RvdHlwZS5nZXRQdWJsaWNLZXkgPSBmdW5jdGlvbiAoZW5jLCBmb3JtYXQpIHtcblx0dmFyIGtleSA9IHRoaXMua2V5cy5nZXRQdWJsaWMoZm9ybWF0ID09PSAnY29tcHJlc3NlZCcsIHRydWUpO1xuXHRpZiAoZm9ybWF0ID09PSAnaHlicmlkJykge1xuXHRcdGlmIChrZXlba2V5Lmxlbmd0aCAtIDFdICUgMikge1xuXHRcdFx0a2V5WzBdID0gNztcblx0XHR9IGVsc2Uge1xuXHRcdFx0a2V5IFswXSA9IDY7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBmb3JtYXRSZXR1cm5WYWx1ZShrZXksIGVuYyk7XG59O1xuXG5FQ0RILnByb3RvdHlwZS5nZXRQcml2YXRlS2V5ID0gZnVuY3Rpb24gKGVuYykge1xuXHRyZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5rZXlzLmdldFByaXZhdGUoKSwgZW5jKTtcbn07XG5cbkVDREgucHJvdG90eXBlLnNldFB1YmxpY0tleSA9IGZ1bmN0aW9uIChwdWIsIGVuYykge1xuXHRlbmMgPSBlbmMgfHwgJ3V0ZjgnO1xuXHRpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwdWIpKSB7XG5cdFx0cHViID0gbmV3IEJ1ZmZlcihwdWIsIGVuYyk7XG5cdH1cblx0dGhpcy5rZXlzLl9pbXBvcnRQdWJsaWMocHViKTtcblx0cmV0dXJuIHRoaXM7XG59O1xuXG5FQ0RILnByb3RvdHlwZS5zZXRQcml2YXRlS2V5ID0gZnVuY3Rpb24gKHByaXYsIGVuYykge1xuXHRlbmMgPSBlbmMgfHwgJ3V0ZjgnO1xuXHRpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwcml2KSkge1xuXHRcdHByaXYgPSBuZXcgQnVmZmVyKHByaXYsIGVuYyk7XG5cdH1cblx0dmFyIF9wcml2ID0gbmV3IEJOKHByaXYpO1xuXHRfcHJpdiA9IF9wcml2LnRvU3RyaW5nKDE2KTtcblx0dGhpcy5rZXlzLl9pbXBvcnRQcml2YXRlKF9wcml2KTtcblx0cmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmb3JtYXRSZXR1cm5WYWx1ZShibiwgZW5jLCBsZW4pIHtcblx0aWYgKCFBcnJheS5pc0FycmF5KGJuKSkge1xuXHRcdGJuID0gYm4udG9BcnJheSgpO1xuXHR9XG5cdHZhciBidWYgPSBuZXcgQnVmZmVyKGJuKTtcblx0aWYgKGxlbiAmJiBidWYubGVuZ3RoIDwgbGVuKSB7XG5cdFx0dmFyIHplcm9zID0gbmV3IEJ1ZmZlcihsZW4gLSBidWYubGVuZ3RoKTtcblx0XHR6ZXJvcy5maWxsKDApO1xuXHRcdGJ1ZiA9IEJ1ZmZlci5jb25jYXQoW3plcm9zLCBidWZdKTtcblx0fVxuXHRpZiAoIWVuYykge1xuXHRcdHJldHVybiBidWY7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGJ1Zi50b1N0cmluZyhlbmMpO1xuXHR9XG59XG4iLCIndXNlIHN0cmljdCc7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgbWQ1ID0gcmVxdWlyZSgnLi9tZDUnKVxudmFyIHJtZDE2MCA9IHJlcXVpcmUoJ3JpcGVtZDE2MCcpXG52YXIgc2hhID0gcmVxdWlyZSgnc2hhLmpzJylcblxudmFyIEJhc2UgPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG5cbmZ1bmN0aW9uIEhhc2hOb0NvbnN0cnVjdG9yKGhhc2gpIHtcbiAgQmFzZS5jYWxsKHRoaXMsICdkaWdlc3QnKVxuXG4gIHRoaXMuX2hhc2ggPSBoYXNoXG4gIHRoaXMuYnVmZmVycyA9IFtdXG59XG5cbmluaGVyaXRzKEhhc2hOb0NvbnN0cnVjdG9yLCBCYXNlKVxuXG5IYXNoTm9Db25zdHJ1Y3Rvci5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuYnVmZmVycy5wdXNoKGRhdGEpXG59XG5cbkhhc2hOb0NvbnN0cnVjdG9yLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBidWYgPSBCdWZmZXIuY29uY2F0KHRoaXMuYnVmZmVycylcbiAgdmFyIHIgPSB0aGlzLl9oYXNoKGJ1ZilcbiAgdGhpcy5idWZmZXJzID0gbnVsbFxuXG4gIHJldHVybiByXG59XG5cbmZ1bmN0aW9uIEhhc2goaGFzaCkge1xuICBCYXNlLmNhbGwodGhpcywgJ2RpZ2VzdCcpXG5cbiAgdGhpcy5faGFzaCA9IGhhc2hcbn1cblxuaW5oZXJpdHMoSGFzaCwgQmFzZSlcblxuSGFzaC5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG59XG5cbkhhc2gucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuX2hhc2guZGlnZXN0KClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmVhdGVIYXNoIChhbGcpIHtcbiAgYWxnID0gYWxnLnRvTG93ZXJDYXNlKClcbiAgaWYgKCdtZDUnID09PSBhbGcpIHJldHVybiBuZXcgSGFzaE5vQ29uc3RydWN0b3IobWQ1KVxuICBpZiAoJ3JtZDE2MCcgPT09IGFsZyB8fCAncmlwZW1kMTYwJyA9PT0gYWxnKSByZXR1cm4gbmV3IEhhc2hOb0NvbnN0cnVjdG9yKHJtZDE2MClcblxuICByZXR1cm4gbmV3IEhhc2goc2hhKGFsZykpXG59XG4iLCIndXNlIHN0cmljdCc7XG52YXIgaW50U2l6ZSA9IDQ7XG52YXIgemVyb0J1ZmZlciA9IG5ldyBCdWZmZXIoaW50U2l6ZSk7IHplcm9CdWZmZXIuZmlsbCgwKTtcbnZhciBjaHJzeiA9IDg7XG5cbmZ1bmN0aW9uIHRvQXJyYXkoYnVmLCBiaWdFbmRpYW4pIHtcbiAgaWYgKChidWYubGVuZ3RoICUgaW50U2l6ZSkgIT09IDApIHtcbiAgICB2YXIgbGVuID0gYnVmLmxlbmd0aCArIChpbnRTaXplIC0gKGJ1Zi5sZW5ndGggJSBpbnRTaXplKSk7XG4gICAgYnVmID0gQnVmZmVyLmNvbmNhdChbYnVmLCB6ZXJvQnVmZmVyXSwgbGVuKTtcbiAgfVxuXG4gIHZhciBhcnIgPSBbXTtcbiAgdmFyIGZuID0gYmlnRW5kaWFuID8gYnVmLnJlYWRJbnQzMkJFIDogYnVmLnJlYWRJbnQzMkxFO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ1Zi5sZW5ndGg7IGkgKz0gaW50U2l6ZSkge1xuICAgIGFyci5wdXNoKGZuLmNhbGwoYnVmLCBpKSk7XG4gIH1cbiAgcmV0dXJuIGFycjtcbn1cblxuZnVuY3Rpb24gdG9CdWZmZXIoYXJyLCBzaXplLCBiaWdFbmRpYW4pIHtcbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc2l6ZSk7XG4gIHZhciBmbiA9IGJpZ0VuZGlhbiA/IGJ1Zi53cml0ZUludDMyQkUgOiBidWYud3JpdGVJbnQzMkxFO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGZuLmNhbGwoYnVmLCBhcnJbaV0sIGkgKiA0LCB0cnVlKTtcbiAgfVxuICByZXR1cm4gYnVmO1xufVxuXG5mdW5jdGlvbiBoYXNoKGJ1ZiwgZm4sIGhhc2hTaXplLCBiaWdFbmRpYW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgYnVmID0gbmV3IEJ1ZmZlcihidWYpO1xuICB2YXIgYXJyID0gZm4odG9BcnJheShidWYsIGJpZ0VuZGlhbiksIGJ1Zi5sZW5ndGggKiBjaHJzeik7XG4gIHJldHVybiB0b0J1ZmZlcihhcnIsIGhhc2hTaXplLCBiaWdFbmRpYW4pO1xufVxuZXhwb3J0cy5oYXNoID0gaGFzaDsiLCIndXNlIHN0cmljdCc7XG4vKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBSU0EgRGF0YSBTZWN1cml0eSwgSW5jLiBNRDUgTWVzc2FnZVxuICogRGlnZXN0IEFsZ29yaXRobSwgYXMgZGVmaW5lZCBpbiBSRkMgMTMyMS5cbiAqIFZlcnNpb24gMi4xIENvcHlyaWdodCAoQykgUGF1bCBKb2huc3RvbiAxOTk5IC0gMjAwMi5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIG1vcmUgaW5mby5cbiAqL1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xuXG4vKlxuICogQ2FsY3VsYXRlIHRoZSBNRDUgb2YgYW4gYXJyYXkgb2YgbGl0dGxlLWVuZGlhbiB3b3JkcywgYW5kIGEgYml0IGxlbmd0aFxuICovXG5mdW5jdGlvbiBjb3JlX21kNSh4LCBsZW4pXG57XG4gIC8qIGFwcGVuZCBwYWRkaW5nICovXG4gIHhbbGVuID4+IDVdIHw9IDB4ODAgPDwgKChsZW4pICUgMzIpO1xuICB4WygoKGxlbiArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNF0gPSBsZW47XG5cbiAgdmFyIGEgPSAgMTczMjU4NDE5MztcbiAgdmFyIGIgPSAtMjcxNzMzODc5O1xuICB2YXIgYyA9IC0xNzMyNTg0MTk0O1xuICB2YXIgZCA9ICAyNzE3MzM4Nzg7XG5cbiAgZm9yKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KVxuICB7XG4gICAgdmFyIG9sZGEgPSBhO1xuICAgIHZhciBvbGRiID0gYjtcbiAgICB2YXIgb2xkYyA9IGM7XG4gICAgdmFyIG9sZGQgPSBkO1xuXG4gICAgYSA9IG1kNV9mZihhLCBiLCBjLCBkLCB4W2krIDBdLCA3ICwgLTY4MDg3NjkzNik7XG4gICAgZCA9IG1kNV9mZihkLCBhLCBiLCBjLCB4W2krIDFdLCAxMiwgLTM4OTU2NDU4Nik7XG4gICAgYyA9IG1kNV9mZihjLCBkLCBhLCBiLCB4W2krIDJdLCAxNywgIDYwNjEwNTgxOSk7XG4gICAgYiA9IG1kNV9mZihiLCBjLCBkLCBhLCB4W2krIDNdLCAyMiwgLTEwNDQ1MjUzMzApO1xuICAgIGEgPSBtZDVfZmYoYSwgYiwgYywgZCwgeFtpKyA0XSwgNyAsIC0xNzY0MTg4OTcpO1xuICAgIGQgPSBtZDVfZmYoZCwgYSwgYiwgYywgeFtpKyA1XSwgMTIsICAxMjAwMDgwNDI2KTtcbiAgICBjID0gbWQ1X2ZmKGMsIGQsIGEsIGIsIHhbaSsgNl0sIDE3LCAtMTQ3MzIzMTM0MSk7XG4gICAgYiA9IG1kNV9mZihiLCBjLCBkLCBhLCB4W2krIDddLCAyMiwgLTQ1NzA1OTgzKTtcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgOF0sIDcgLCAgMTc3MDAzNTQxNik7XG4gICAgZCA9IG1kNV9mZihkLCBhLCBiLCBjLCB4W2krIDldLCAxMiwgLTE5NTg0MTQ0MTcpO1xuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKzEwXSwgMTcsIC00MjA2Myk7XG4gICAgYiA9IG1kNV9mZihiLCBjLCBkLCBhLCB4W2krMTFdLCAyMiwgLTE5OTA0MDQxNjIpO1xuICAgIGEgPSBtZDVfZmYoYSwgYiwgYywgZCwgeFtpKzEyXSwgNyAsICAxODA0NjAzNjgyKTtcbiAgICBkID0gbWQ1X2ZmKGQsIGEsIGIsIGMsIHhbaSsxM10sIDEyLCAtNDAzNDExMDEpO1xuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKzE0XSwgMTcsIC0xNTAyMDAyMjkwKTtcbiAgICBiID0gbWQ1X2ZmKGIsIGMsIGQsIGEsIHhbaSsxNV0sIDIyLCAgMTIzNjUzNTMyOSk7XG5cbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsgMV0sIDUgLCAtMTY1Nzk2NTEwKTtcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsgNl0sIDkgLCAtMTA2OTUwMTYzMik7XG4gICAgYyA9IG1kNV9nZyhjLCBkLCBhLCBiLCB4W2krMTFdLCAxNCwgIDY0MzcxNzcxMyk7XG4gICAgYiA9IG1kNV9nZyhiLCBjLCBkLCBhLCB4W2krIDBdLCAyMCwgLTM3Mzg5NzMwMik7XG4gICAgYSA9IG1kNV9nZyhhLCBiLCBjLCBkLCB4W2krIDVdLCA1ICwgLTcwMTU1ODY5MSk7XG4gICAgZCA9IG1kNV9nZyhkLCBhLCBiLCBjLCB4W2krMTBdLCA5ICwgIDM4MDE2MDgzKTtcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsxNV0sIDE0LCAtNjYwNDc4MzM1KTtcbiAgICBiID0gbWQ1X2dnKGIsIGMsIGQsIGEsIHhbaSsgNF0sIDIwLCAtNDA1NTM3ODQ4KTtcbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsgOV0sIDUgLCAgNTY4NDQ2NDM4KTtcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsxNF0sIDkgLCAtMTAxOTgwMzY5MCk7XG4gICAgYyA9IG1kNV9nZyhjLCBkLCBhLCBiLCB4W2krIDNdLCAxNCwgLTE4NzM2Mzk2MSk7XG4gICAgYiA9IG1kNV9nZyhiLCBjLCBkLCBhLCB4W2krIDhdLCAyMCwgIDExNjM1MzE1MDEpO1xuICAgIGEgPSBtZDVfZ2coYSwgYiwgYywgZCwgeFtpKzEzXSwgNSAsIC0xNDQ0NjgxNDY3KTtcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsgMl0sIDkgLCAtNTE0MDM3ODQpO1xuICAgIGMgPSBtZDVfZ2coYywgZCwgYSwgYiwgeFtpKyA3XSwgMTQsICAxNzM1MzI4NDczKTtcbiAgICBiID0gbWQ1X2dnKGIsIGMsIGQsIGEsIHhbaSsxMl0sIDIwLCAtMTkyNjYwNzczNCk7XG5cbiAgICBhID0gbWQ1X2hoKGEsIGIsIGMsIGQsIHhbaSsgNV0sIDQgLCAtMzc4NTU4KTtcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsgOF0sIDExLCAtMjAyMjU3NDQ2Myk7XG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krMTFdLCAxNiwgIDE4MzkwMzA1NjIpO1xuICAgIGIgPSBtZDVfaGgoYiwgYywgZCwgYSwgeFtpKzE0XSwgMjMsIC0zNTMwOTU1Nik7XG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDFdLCA0ICwgLTE1MzA5OTIwNjApO1xuICAgIGQgPSBtZDVfaGgoZCwgYSwgYiwgYywgeFtpKyA0XSwgMTEsICAxMjcyODkzMzUzKTtcbiAgICBjID0gbWQ1X2hoKGMsIGQsIGEsIGIsIHhbaSsgN10sIDE2LCAtMTU1NDk3NjMyKTtcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsxMF0sIDIzLCAtMTA5NDczMDY0MCk7XG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krMTNdLCA0ICwgIDY4MTI3OTE3NCk7XG4gICAgZCA9IG1kNV9oaChkLCBhLCBiLCBjLCB4W2krIDBdLCAxMSwgLTM1ODUzNzIyMik7XG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krIDNdLCAxNiwgLTcyMjUyMTk3OSk7XG4gICAgYiA9IG1kNV9oaChiLCBjLCBkLCBhLCB4W2krIDZdLCAyMywgIDc2MDI5MTg5KTtcbiAgICBhID0gbWQ1X2hoKGEsIGIsIGMsIGQsIHhbaSsgOV0sIDQgLCAtNjQwMzY0NDg3KTtcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsxMl0sIDExLCAtNDIxODE1ODM1KTtcbiAgICBjID0gbWQ1X2hoKGMsIGQsIGEsIGIsIHhbaSsxNV0sIDE2LCAgNTMwNzQyNTIwKTtcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsgMl0sIDIzLCAtOTk1MzM4NjUxKTtcblxuICAgIGEgPSBtZDVfaWkoYSwgYiwgYywgZCwgeFtpKyAwXSwgNiAsIC0xOTg2MzA4NDQpO1xuICAgIGQgPSBtZDVfaWkoZCwgYSwgYiwgYywgeFtpKyA3XSwgMTAsICAxMTI2ODkxNDE1KTtcbiAgICBjID0gbWQ1X2lpKGMsIGQsIGEsIGIsIHhbaSsxNF0sIDE1LCAtMTQxNjM1NDkwNSk7XG4gICAgYiA9IG1kNV9paShiLCBjLCBkLCBhLCB4W2krIDVdLCAyMSwgLTU3NDM0MDU1KTtcbiAgICBhID0gbWQ1X2lpKGEsIGIsIGMsIGQsIHhbaSsxMl0sIDYgLCAgMTcwMDQ4NTU3MSk7XG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krIDNdLCAxMCwgLTE4OTQ5ODY2MDYpO1xuICAgIGMgPSBtZDVfaWkoYywgZCwgYSwgYiwgeFtpKzEwXSwgMTUsIC0xMDUxNTIzKTtcbiAgICBiID0gbWQ1X2lpKGIsIGMsIGQsIGEsIHhbaSsgMV0sIDIxLCAtMjA1NDkyMjc5OSk7XG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krIDhdLCA2ICwgIDE4NzMzMTMzNTkpO1xuICAgIGQgPSBtZDVfaWkoZCwgYSwgYiwgYywgeFtpKzE1XSwgMTAsIC0zMDYxMTc0NCk7XG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krIDZdLCAxNSwgLTE1NjAxOTgzODApO1xuICAgIGIgPSBtZDVfaWkoYiwgYywgZCwgYSwgeFtpKzEzXSwgMjEsICAxMzA5MTUxNjQ5KTtcbiAgICBhID0gbWQ1X2lpKGEsIGIsIGMsIGQsIHhbaSsgNF0sIDYgLCAtMTQ1NTIzMDcwKTtcbiAgICBkID0gbWQ1X2lpKGQsIGEsIGIsIGMsIHhbaSsxMV0sIDEwLCAtMTEyMDIxMDM3OSk7XG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krIDJdLCAxNSwgIDcxODc4NzI1OSk7XG4gICAgYiA9IG1kNV9paShiLCBjLCBkLCBhLCB4W2krIDldLCAyMSwgLTM0MzQ4NTU1MSk7XG5cbiAgICBhID0gc2FmZV9hZGQoYSwgb2xkYSk7XG4gICAgYiA9IHNhZmVfYWRkKGIsIG9sZGIpO1xuICAgIGMgPSBzYWZlX2FkZChjLCBvbGRjKTtcbiAgICBkID0gc2FmZV9hZGQoZCwgb2xkZCk7XG4gIH1cbiAgcmV0dXJuIEFycmF5KGEsIGIsIGMsIGQpO1xuXG59XG5cbi8qXG4gKiBUaGVzZSBmdW5jdGlvbnMgaW1wbGVtZW50IHRoZSBmb3VyIGJhc2ljIG9wZXJhdGlvbnMgdGhlIGFsZ29yaXRobSB1c2VzLlxuICovXG5mdW5jdGlvbiBtZDVfY21uKHEsIGEsIGIsIHgsIHMsIHQpXG57XG4gIHJldHVybiBzYWZlX2FkZChiaXRfcm9sKHNhZmVfYWRkKHNhZmVfYWRkKGEsIHEpLCBzYWZlX2FkZCh4LCB0KSksIHMpLGIpO1xufVxuZnVuY3Rpb24gbWQ1X2ZmKGEsIGIsIGMsIGQsIHgsIHMsIHQpXG57XG4gIHJldHVybiBtZDVfY21uKChiICYgYykgfCAoKH5iKSAmIGQpLCBhLCBiLCB4LCBzLCB0KTtcbn1cbmZ1bmN0aW9uIG1kNV9nZyhhLCBiLCBjLCBkLCB4LCBzLCB0KVxue1xuICByZXR1cm4gbWQ1X2NtbigoYiAmIGQpIHwgKGMgJiAofmQpKSwgYSwgYiwgeCwgcywgdCk7XG59XG5mdW5jdGlvbiBtZDVfaGgoYSwgYiwgYywgZCwgeCwgcywgdClcbntcbiAgcmV0dXJuIG1kNV9jbW4oYiBeIGMgXiBkLCBhLCBiLCB4LCBzLCB0KTtcbn1cbmZ1bmN0aW9uIG1kNV9paShhLCBiLCBjLCBkLCB4LCBzLCB0KVxue1xuICByZXR1cm4gbWQ1X2NtbihjIF4gKGIgfCAofmQpKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbi8qXG4gKiBBZGQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9ucyBpbnRlcm5hbGx5XG4gKiB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICovXG5mdW5jdGlvbiBzYWZlX2FkZCh4LCB5KVxue1xuICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpO1xuICB2YXIgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG4gIHJldHVybiAobXN3IDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xufVxuXG4vKlxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxuICovXG5mdW5jdGlvbiBiaXRfcm9sKG51bSwgY250KVxue1xuICByZXR1cm4gKG51bSA8PCBjbnQpIHwgKG51bSA+Pj4gKDMyIC0gY250KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbWQ1KGJ1Zikge1xuICByZXR1cm4gaGVscGVycy5oYXNoKGJ1ZiwgY29yZV9tZDUsIDE2KTtcbn07IiwidmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyQmFzZVxuaW5oZXJpdHMoQ2lwaGVyQmFzZSwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyQmFzZSAoaGFzaE1vZGUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5oYXNoTW9kZSA9IHR5cGVvZiBoYXNoTW9kZSA9PT0gJ3N0cmluZydcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICB0aGlzW2hhc2hNb2RlXSA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZpbmFsID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9XG4gIHRoaXMuX2RlY29kZXIgPSBudWxsXG4gIHRoaXMuX2VuY29kaW5nID0gbnVsbFxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGlucHV0RW5jKVxuICB9XG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYylcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uICgpIHt9XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGFhZCBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1c2godGhpcy5fdXBkYXRlKGRhdGEpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBuZXh0KGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGRvbmUpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIGRvbmUoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9maW5hbCgpIHx8IG5ldyBCdWZmZXIoJycpXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jLCB0cnVlKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90b1N0cmluZyA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jLCBmaW5hbCkge1xuICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKVxuICAgIHRoaXMuX2VuY29kaW5nID0gZW5jXG4gIH1cbiAgaWYgKHRoaXMuX2VuY29kaW5nICE9PSBlbmMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhblxcJ3Qgc3dpdGNoIGVuY29kaW5ncycpXG4gIH1cbiAgdmFyIG91dCA9IHRoaXMuX2RlY29kZXIud3JpdGUodmFsdWUpXG4gIGlmIChmaW5hbCkge1xuICAgIG91dCArPSB0aGlzLl9kZWNvZGVyLmVuZCgpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwiLypcbkNyeXB0b0pTIHYzLjEuMlxuY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXG4oYykgMjAwOS0yMDEzIGJ5IEplZmYgTW90dC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbmNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy93aWtpL0xpY2Vuc2VcbiovXG4vKiogQHByZXNlcnZlXG4oYykgMjAxMiBieSBDw6lkcmljIE1lc25pbC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxuUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuXG4gICAgLSBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gICAgLSBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG5cblRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbi8vIGNvbnN0YW50cyB0YWJsZVxudmFyIHpsID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dXG5cbnZhciB6ciA9IFtcbiAgNSwgMTQsIDcsIDAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMixcbiAgNiwgMTEsIDMsIDcsIDAsIDEzLCA1LCAxMCwgMTQsIDE1LCA4LCAxMiwgNCwgOSwgMSwgMixcbiAgMTUsIDUsIDEsIDMsIDcsIDE0LCA2LCA5LCAxMSwgOCwgMTIsIDIsIDEwLCAwLCA0LCAxMyxcbiAgOCwgNiwgNCwgMSwgMywgMTEsIDE1LCAwLCA1LCAxMiwgMiwgMTMsIDksIDcsIDEwLCAxNCxcbiAgMTIsIDE1LCAxMCwgNCwgMSwgNSwgOCwgNywgNiwgMiwgMTMsIDE0LCAwLCAzLCA5LCAxMVxuXVxuXG52YXIgc2wgPSBbXG4gIDExLCAxNCwgMTUsIDEyLCA1LCA4LCA3LCA5LCAxMSwgMTMsIDE0LCAxNSwgNiwgNywgOSwgOCxcbiAgNywgNiwgOCwgMTMsIDExLCA5LCA3LCAxNSwgNywgMTIsIDE1LCA5LCAxMSwgNywgMTMsIDEyLFxuICAxMSwgMTMsIDYsIDcsIDE0LCA5LCAxMywgMTUsIDE0LCA4LCAxMywgNiwgNSwgMTIsIDcsIDUsXG4gIDExLCAxMiwgMTQsIDE1LCAxNCwgMTUsIDksIDgsIDksIDE0LCA1LCA2LCA4LCA2LCA1LCAxMixcbiAgOSwgMTUsIDUsIDExLCA2LCA4LCAxMywgMTIsIDUsIDEyLCAxMywgMTQsIDExLCA4LCA1LCA2XG5dXG5cbnZhciBzciA9IFtcbiAgOCwgOSwgOSwgMTEsIDEzLCAxNSwgMTUsIDUsIDcsIDcsIDgsIDExLCAxNCwgMTQsIDEyLCA2LFxuICA5LCAxMywgMTUsIDcsIDEyLCA4LCA5LCAxMSwgNywgNywgMTIsIDcsIDYsIDE1LCAxMywgMTEsXG4gIDksIDcsIDE1LCAxMSwgOCwgNiwgNiwgMTQsIDEyLCAxMywgNSwgMTQsIDEzLCAxMywgNywgNSxcbiAgMTUsIDUsIDgsIDExLCAxNCwgMTQsIDYsIDE0LCA2LCA5LCAxMiwgOSwgMTIsIDUsIDE1LCA4LFxuICA4LCA1LCAxMiwgOSwgMTIsIDUsIDE0LCA2LCA4LCAxMywgNiwgNSwgMTUsIDEzLCAxMSwgMTFcbl1cblxudmFyIGhsID0gWzB4MDAwMDAwMDAsIDB4NUE4Mjc5OTksIDB4NkVEOUVCQTEsIDB4OEYxQkJDREMsIDB4QTk1M0ZENEVdXG52YXIgaHIgPSBbMHg1MEEyOEJFNiwgMHg1QzRERDEyNCwgMHg2RDcwM0VGMywgMHg3QTZENzZFOSwgMHgwMDAwMDAwMF1cblxuZnVuY3Rpb24gYnl0ZXNUb1dvcmRzIChieXRlcykge1xuICB2YXIgd29yZHMgPSBbXVxuICBmb3IgKHZhciBpID0gMCwgYiA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKywgYiArPSA4KSB7XG4gICAgd29yZHNbYiA+Pj4gNV0gfD0gYnl0ZXNbaV0gPDwgKDI0IC0gYiAlIDMyKVxuICB9XG4gIHJldHVybiB3b3Jkc1xufVxuXG5mdW5jdGlvbiB3b3Jkc1RvQnl0ZXMgKHdvcmRzKSB7XG4gIHZhciBieXRlcyA9IFtdXG4gIGZvciAodmFyIGIgPSAwOyBiIDwgd29yZHMubGVuZ3RoICogMzI7IGIgKz0gOCkge1xuICAgIGJ5dGVzLnB1c2goKHdvcmRzW2IgPj4+IDVdID4+PiAoMjQgLSBiICUgMzIpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NCbG9jayAoSCwgTSwgb2Zmc2V0KSB7XG4gIC8vIHN3YXAgZW5kaWFuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIHZhciBvZmZzZXRfaSA9IG9mZnNldCArIGlcbiAgICB2YXIgTV9vZmZzZXRfaSA9IE1bb2Zmc2V0X2ldXG5cbiAgICAvLyBTd2FwXG4gICAgTVtvZmZzZXRfaV0gPSAoXG4gICAgICAoKChNX29mZnNldF9pIDw8IDgpIHwgKE1fb2Zmc2V0X2kgPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG4gICAgICAoKChNX29mZnNldF9pIDw8IDI0KSB8IChNX29mZnNldF9pID4+PiA4KSkgJiAweGZmMDBmZjAwKVxuICAgIClcbiAgfVxuXG4gIC8vIFdvcmtpbmcgdmFyaWFibGVzXG4gIHZhciBhbCwgYmwsIGNsLCBkbCwgZWxcbiAgdmFyIGFyLCBiciwgY3IsIGRyLCBlclxuXG4gIGFyID0gYWwgPSBIWzBdXG4gIGJyID0gYmwgPSBIWzFdXG4gIGNyID0gY2wgPSBIWzJdXG4gIGRyID0gZGwgPSBIWzNdXG4gIGVyID0gZWwgPSBIWzRdXG5cbiAgLy8gY29tcHV0YXRpb25cbiAgdmFyIHRcbiAgZm9yIChpID0gMDsgaSA8IDgwOyBpICs9IDEpIHtcbiAgICB0ID0gKGFsICsgTVtvZmZzZXQgKyB6bFtpXV0pIHwgMFxuICAgIGlmIChpIDwgMTYpIHtcbiAgICAgIHQgKz0gZjEoYmwsIGNsLCBkbCkgKyBobFswXVxuICAgIH0gZWxzZSBpZiAoaSA8IDMyKSB7XG4gICAgICB0ICs9IGYyKGJsLCBjbCwgZGwpICsgaGxbMV1cbiAgICB9IGVsc2UgaWYgKGkgPCA0OCkge1xuICAgICAgdCArPSBmMyhibCwgY2wsIGRsKSArIGhsWzJdXG4gICAgfSBlbHNlIGlmIChpIDwgNjQpIHtcbiAgICAgIHQgKz0gZjQoYmwsIGNsLCBkbCkgKyBobFszXVxuICAgIH0gZWxzZSB7Ly8gaWYgKGk8ODApIHtcbiAgICAgIHQgKz0gZjUoYmwsIGNsLCBkbCkgKyBobFs0XVxuICAgIH1cbiAgICB0ID0gdCB8IDBcbiAgICB0ID0gcm90bCh0LCBzbFtpXSlcbiAgICB0ID0gKHQgKyBlbCkgfCAwXG4gICAgYWwgPSBlbFxuICAgIGVsID0gZGxcbiAgICBkbCA9IHJvdGwoY2wsIDEwKVxuICAgIGNsID0gYmxcbiAgICBibCA9IHRcblxuICAgIHQgPSAoYXIgKyBNW29mZnNldCArIHpyW2ldXSkgfCAwXG4gICAgaWYgKGkgPCAxNikge1xuICAgICAgdCArPSBmNShiciwgY3IsIGRyKSArIGhyWzBdXG4gICAgfSBlbHNlIGlmIChpIDwgMzIpIHtcbiAgICAgIHQgKz0gZjQoYnIsIGNyLCBkcikgKyBoclsxXVxuICAgIH0gZWxzZSBpZiAoaSA8IDQ4KSB7XG4gICAgICB0ICs9IGYzKGJyLCBjciwgZHIpICsgaHJbMl1cbiAgICB9IGVsc2UgaWYgKGkgPCA2NCkge1xuICAgICAgdCArPSBmMihiciwgY3IsIGRyKSArIGhyWzNdXG4gICAgfSBlbHNlIHsvLyBpZiAoaTw4MCkge1xuICAgICAgdCArPSBmMShiciwgY3IsIGRyKSArIGhyWzRdXG4gICAgfVxuXG4gICAgdCA9IHQgfCAwXG4gICAgdCA9IHJvdGwodCwgc3JbaV0pXG4gICAgdCA9ICh0ICsgZXIpIHwgMFxuICAgIGFyID0gZXJcbiAgICBlciA9IGRyXG4gICAgZHIgPSByb3RsKGNyLCAxMClcbiAgICBjciA9IGJyXG4gICAgYnIgPSB0XG4gIH1cblxuICAvLyBpbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZVxuICB0ID0gKEhbMV0gKyBjbCArIGRyKSB8IDBcbiAgSFsxXSA9IChIWzJdICsgZGwgKyBlcikgfCAwXG4gIEhbMl0gPSAoSFszXSArIGVsICsgYXIpIHwgMFxuICBIWzNdID0gKEhbNF0gKyBhbCArIGJyKSB8IDBcbiAgSFs0XSA9IChIWzBdICsgYmwgKyBjcikgfCAwXG4gIEhbMF0gPSB0XG59XG5cbmZ1bmN0aW9uIGYxICh4LCB5LCB6KSB7XG4gIHJldHVybiAoKHgpIF4gKHkpIF4gKHopKVxufVxuXG5mdW5jdGlvbiBmMiAoeCwgeSwgeikge1xuICByZXR1cm4gKCgoeCkgJiAoeSkpIHwgKCh+eCkgJiAoeikpKVxufVxuXG5mdW5jdGlvbiBmMyAoeCwgeSwgeikge1xuICByZXR1cm4gKCgoeCkgfCAofih5KSkpIF4gKHopKVxufVxuXG5mdW5jdGlvbiBmNCAoeCwgeSwgeikge1xuICByZXR1cm4gKCgoeCkgJiAoeikpIHwgKCh5KSAmICh+KHopKSkpXG59XG5cbmZ1bmN0aW9uIGY1ICh4LCB5LCB6KSB7XG4gIHJldHVybiAoKHgpIF4gKCh5KSB8ICh+KHopKSkpXG59XG5cbmZ1bmN0aW9uIHJvdGwgKHgsIG4pIHtcbiAgcmV0dXJuICh4IDw8IG4pIHwgKHggPj4+ICgzMiAtIG4pKVxufVxuXG5mdW5jdGlvbiByaXBlbWQxNjAgKG1lc3NhZ2UpIHtcbiAgdmFyIEggPSBbMHg2NzQ1MjMwMSwgMHhFRkNEQUI4OSwgMHg5OEJBRENGRSwgMHgxMDMyNTQ3NiwgMHhDM0QyRTFGMF1cblxuICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgbWVzc2FnZSA9IG5ldyBCdWZmZXIobWVzc2FnZSwgJ3V0ZjgnKVxuICB9XG5cbiAgdmFyIG0gPSBieXRlc1RvV29yZHMobWVzc2FnZSlcblxuICB2YXIgbkJpdHNMZWZ0ID0gbWVzc2FnZS5sZW5ndGggKiA4XG4gIHZhciBuQml0c1RvdGFsID0gbWVzc2FnZS5sZW5ndGggKiA4XG5cbiAgLy8gQWRkIHBhZGRpbmdcbiAgbVtuQml0c0xlZnQgPj4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gbkJpdHNMZWZ0ICUgMzIpXG4gIG1bKCgobkJpdHNMZWZ0ICsgNjQpID4+PiA5KSA8PCA0KSArIDE0XSA9IChcbiAgICAoKChuQml0c1RvdGFsIDw8IDgpIHwgKG5CaXRzVG90YWwgPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG4gICAgKCgobkJpdHNUb3RhbCA8PCAyNCkgfCAobkJpdHNUb3RhbCA+Pj4gOCkpICYgMHhmZjAwZmYwMClcbiAgKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbS5sZW5ndGg7IGkgKz0gMTYpIHtcbiAgICBwcm9jZXNzQmxvY2soSCwgbSwgaSlcbiAgfVxuXG4gIC8vIHN3YXAgZW5kaWFuXG4gIGZvciAoaSA9IDA7IGkgPCA1OyBpKyspIHtcbiAgICAvLyBzaG9ydGN1dFxuICAgIHZhciBIX2kgPSBIW2ldXG5cbiAgICAvLyBTd2FwXG4gICAgSFtpXSA9ICgoKEhfaSA8PCA4KSB8IChIX2kgPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG4gICAgICAoKChIX2kgPDwgMjQpIHwgKEhfaSA+Pj4gOCkpICYgMHhmZjAwZmYwMClcbiAgfVxuXG4gIHZhciBkaWdlc3RieXRlcyA9IHdvcmRzVG9CeXRlcyhIKVxuICByZXR1cm4gbmV3IEJ1ZmZlcihkaWdlc3RieXRlcylcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByaXBlbWQxNjBcbiIsIi8vIHByb3RvdHlwZSBjbGFzcyBmb3IgaGFzaCBmdW5jdGlvbnNcbmZ1bmN0aW9uIEhhc2ggKGJsb2NrU2l6ZSwgZmluYWxTaXplKSB7XG4gIHRoaXMuX2Jsb2NrID0gbmV3IEJ1ZmZlcihibG9ja1NpemUpXG4gIHRoaXMuX2ZpbmFsU2l6ZSA9IGZpbmFsU2l6ZVxuICB0aGlzLl9ibG9ja1NpemUgPSBibG9ja1NpemVcbiAgdGhpcy5fbGVuID0gMFxuICB0aGlzLl9zID0gMFxufVxuXG5IYXNoLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgZW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmMgPSBlbmMgfHwgJ3V0ZjgnXG4gICAgZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSwgZW5jKVxuICB9XG5cbiAgdmFyIGwgPSB0aGlzLl9sZW4gKz0gZGF0YS5sZW5ndGhcbiAgdmFyIHMgPSB0aGlzLl9zIHx8IDBcbiAgdmFyIGYgPSAwXG4gIHZhciBidWZmZXIgPSB0aGlzLl9ibG9ja1xuXG4gIHdoaWxlIChzIDwgbCkge1xuICAgIHZhciB0ID0gTWF0aC5taW4oZGF0YS5sZW5ndGgsIGYgKyB0aGlzLl9ibG9ja1NpemUgLSAocyAlIHRoaXMuX2Jsb2NrU2l6ZSkpXG4gICAgdmFyIGNoID0gKHQgLSBmKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaDsgaSsrKSB7XG4gICAgICBidWZmZXJbKHMgJSB0aGlzLl9ibG9ja1NpemUpICsgaV0gPSBkYXRhW2kgKyBmXVxuICAgIH1cblxuICAgIHMgKz0gY2hcbiAgICBmICs9IGNoXG5cbiAgICBpZiAoKHMgJSB0aGlzLl9ibG9ja1NpemUpID09PSAwKSB7XG4gICAgICB0aGlzLl91cGRhdGUoYnVmZmVyKVxuICAgIH1cbiAgfVxuICB0aGlzLl9zID0gc1xuXG4gIHJldHVybiB0aGlzXG59XG5cbkhhc2gucHJvdG90eXBlLmRpZ2VzdCA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgLy8gU3VwcG9zZSB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlIE0sIGluIGJpdHMsIGlzIGxcbiAgdmFyIGwgPSB0aGlzLl9sZW4gKiA4XG5cbiAgLy8gQXBwZW5kIHRoZSBiaXQgMSB0byB0aGUgZW5kIG9mIHRoZSBtZXNzYWdlXG4gIHRoaXMuX2Jsb2NrW3RoaXMuX2xlbiAlIHRoaXMuX2Jsb2NrU2l6ZV0gPSAweDgwXG5cbiAgLy8gYW5kIHRoZW4gayB6ZXJvIGJpdHMsIHdoZXJlIGsgaXMgdGhlIHNtYWxsZXN0IG5vbi1uZWdhdGl2ZSBzb2x1dGlvbiB0byB0aGUgZXF1YXRpb24gKGwgKyAxICsgaykgPT09IGZpbmFsU2l6ZSBtb2QgYmxvY2tTaXplXG4gIHRoaXMuX2Jsb2NrLmZpbGwoMCwgdGhpcy5fbGVuICUgdGhpcy5fYmxvY2tTaXplICsgMSlcblxuICBpZiAobCAlICh0aGlzLl9ibG9ja1NpemUgKiA4KSA+PSB0aGlzLl9maW5hbFNpemUgKiA4KSB7XG4gICAgdGhpcy5fdXBkYXRlKHRoaXMuX2Jsb2NrKVxuICAgIHRoaXMuX2Jsb2NrLmZpbGwoMClcbiAgfVxuXG4gIC8vIHRvIHRoaXMgYXBwZW5kIHRoZSBibG9jayB3aGljaCBpcyBlcXVhbCB0byB0aGUgbnVtYmVyIGwgd3JpdHRlbiBpbiBiaW5hcnlcbiAgLy8gVE9ETzogaGFuZGxlIGNhc2Ugd2hlcmUgbCBpcyA+IE1hdGgucG93KDIsIDI5KVxuICB0aGlzLl9ibG9jay53cml0ZUludDMyQkUobCwgdGhpcy5fYmxvY2tTaXplIC0gNClcblxuICB2YXIgaGFzaCA9IHRoaXMuX3VwZGF0ZSh0aGlzLl9ibG9jaykgfHwgdGhpcy5faGFzaCgpXG5cbiAgcmV0dXJuIGVuYyA/IGhhc2gudG9TdHJpbmcoZW5jKSA6IGhhc2hcbn1cblxuSGFzaC5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdXBkYXRlIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MnKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEhhc2hcbiIsInZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTSEEgKGFsZ29yaXRobSkge1xuICBhbGdvcml0aG0gPSBhbGdvcml0aG0udG9Mb3dlckNhc2UoKVxuXG4gIHZhciBBbGdvcml0aG0gPSBleHBvcnRzW2FsZ29yaXRobV1cbiAgaWYgKCFBbGdvcml0aG0pIHRocm93IG5ldyBFcnJvcihhbGdvcml0aG0gKyAnIGlzIG5vdCBzdXBwb3J0ZWQgKHdlIGFjY2VwdCBwdWxsIHJlcXVlc3RzKScpXG5cbiAgcmV0dXJuIG5ldyBBbGdvcml0aG0oKVxufVxuXG5leHBvcnRzLnNoYSA9IHJlcXVpcmUoJy4vc2hhJylcbmV4cG9ydHMuc2hhMSA9IHJlcXVpcmUoJy4vc2hhMScpXG5leHBvcnRzLnNoYTIyNCA9IHJlcXVpcmUoJy4vc2hhMjI0JylcbmV4cG9ydHMuc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEyNTYnKVxuZXhwb3J0cy5zaGEzODQgPSByZXF1aXJlKCcuL3NoYTM4NCcpXG5leHBvcnRzLnNoYTUxMiA9IHJlcXVpcmUoJy4vc2hhNTEyJylcbiIsIi8qXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTAsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgUFVCIDE4MC0xXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGRlcml2ZWQgZnJvbSBzaGExLmpzIG9mIHRoZSBzYW1lIHJlcG9zaXRvcnkuXG4gKiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIFNIQS0wIGFuZCBTSEEtMSBpcyBqdXN0IGEgYml0d2lzZSByb3RhdGUgbGVmdFxuICogb3BlcmF0aW9uIHdhcyBhZGRlZC5cbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG5cbnZhciBLID0gW1xuICAweDVhODI3OTk5LCAweDZlZDllYmExLCAweDhmMWJiY2RjIHwgMCwgMHhjYTYyYzFkNiB8IDBcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoODApXG5cbmZ1bmN0aW9uIFNoYSAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhLCBIYXNoKVxuXG5TaGEucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweDY3NDUyMzAxXG4gIHRoaXMuX2IgPSAweGVmY2RhYjg5XG4gIHRoaXMuX2MgPSAweDk4YmFkY2ZlXG4gIHRoaXMuX2QgPSAweDEwMzI1NDc2XG4gIHRoaXMuX2UgPSAweGMzZDJlMWYwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gcm90bDUgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCA1KSB8IChudW0gPj4+IDI3KVxufVxuXG5mdW5jdGlvbiByb3RsMzAgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCAzMCkgfCAobnVtID4+PiAyKVxufVxuXG5mdW5jdGlvbiBmdCAocywgYiwgYywgZCkge1xuICBpZiAocyA9PT0gMCkgcmV0dXJuIChiICYgYykgfCAoKH5iKSAmIGQpXG4gIGlmIChzID09PSAyKSByZXR1cm4gKGIgJiBjKSB8IChiICYgZCkgfCAoYyAmIGQpXG4gIHJldHVybiBiIF4gYyBeIGRcbn1cblxuU2hhLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGEgPSB0aGlzLl9hIHwgMFxuICB2YXIgYiA9IHRoaXMuX2IgfCAwXG4gIHZhciBjID0gdGhpcy5fYyB8IDBcbiAgdmFyIGQgPSB0aGlzLl9kIHwgMFxuICB2YXIgZSA9IHRoaXMuX2UgfCAwXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgKytpKSBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgZm9yICg7IGkgPCA4MDsgKytpKSBXW2ldID0gV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XVxuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7ICsraikge1xuICAgIHZhciBzID0gfn4oaiAvIDIwKVxuICAgIHZhciB0ID0gKHJvdGw1KGEpICsgZnQocywgYiwgYywgZCkgKyBlICsgV1tqXSArIEtbc10pIHwgMFxuXG4gICAgZSA9IGRcbiAgICBkID0gY1xuICAgIGMgPSByb3RsMzAoYilcbiAgICBiID0gYVxuICAgIGEgPSB0XG4gIH1cblxuICB0aGlzLl9hID0gKGEgKyB0aGlzLl9hKSB8IDBcbiAgdGhpcy5fYiA9IChiICsgdGhpcy5fYikgfCAwXG4gIHRoaXMuX2MgPSAoYyArIHRoaXMuX2MpIHwgMFxuICB0aGlzLl9kID0gKGQgKyB0aGlzLl9kKSB8IDBcbiAgdGhpcy5fZSA9IChlICsgdGhpcy5fZSkgfCAwXG59XG5cblNoYS5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcigyMClcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hIHwgMCwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiB8IDAsIDQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2MgfCAwLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kIHwgMCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UgfCAwLCAxNilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYVxuIiwiLypcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMSwgYXMgZGVmaW5lZFxuICogaW4gRklQUyBQVUIgMTgwLTFcbiAqIFZlcnNpb24gMi4xYSBDb3B5cmlnaHQgUGF1bCBKb2huc3RvbiAyMDAwIC0gMjAwMi5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIGRldGFpbHMuXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxuXG52YXIgSyA9IFtcbiAgMHg1YTgyNzk5OSwgMHg2ZWQ5ZWJhMSwgMHg4ZjFiYmNkYyB8IDAsIDB4Y2E2MmMxZDYgfCAwXG5dXG5cbnZhciBXID0gbmV3IEFycmF5KDgwKVxuXG5mdW5jdGlvbiBTaGExICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGExLCBIYXNoKVxuXG5TaGExLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxuICB0aGlzLl9lID0gMHhjM2QyZTFmMFxuXG4gIHJldHVybiB0aGlzXG59XG5cbmZ1bmN0aW9uIHJvdGwxIChudW0pIHtcbiAgcmV0dXJuIChudW0gPDwgMSkgfCAobnVtID4+PiAzMSlcbn1cblxuZnVuY3Rpb24gcm90bDUgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCA1KSB8IChudW0gPj4+IDI3KVxufVxuXG5mdW5jdGlvbiByb3RsMzAgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCAzMCkgfCAobnVtID4+PiAyKVxufVxuXG5mdW5jdGlvbiBmdCAocywgYiwgYywgZCkge1xuICBpZiAocyA9PT0gMCkgcmV0dXJuIChiICYgYykgfCAoKH5iKSAmIGQpXG4gIGlmIChzID09PSAyKSByZXR1cm4gKGIgJiBjKSB8IChiICYgZCkgfCAoYyAmIGQpXG4gIHJldHVybiBiIF4gYyBeIGRcbn1cblxuU2hhMS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBXID0gdGhpcy5fd1xuXG4gIHZhciBhID0gdGhpcy5fYSB8IDBcbiAgdmFyIGIgPSB0aGlzLl9iIHwgMFxuICB2YXIgYyA9IHRoaXMuX2MgfCAwXG4gIHZhciBkID0gdGhpcy5fZCB8IDBcbiAgdmFyIGUgPSB0aGlzLl9lIHwgMFxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7ICsraSkgV1tpXSA9IE0ucmVhZEludDMyQkUoaSAqIDQpXG4gIGZvciAoOyBpIDwgODA7ICsraSkgV1tpXSA9IHJvdGwxKFdbaSAtIDNdIF4gV1tpIC0gOF0gXiBXW2kgLSAxNF0gXiBXW2kgLSAxNl0pXG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCA4MDsgKytqKSB7XG4gICAgdmFyIHMgPSB+fihqIC8gMjApXG4gICAgdmFyIHQgPSAocm90bDUoYSkgKyBmdChzLCBiLCBjLCBkKSArIGUgKyBXW2pdICsgS1tzXSkgfCAwXG5cbiAgICBlID0gZFxuICAgIGQgPSBjXG4gICAgYyA9IHJvdGwzMChiKVxuICAgIGIgPSBhXG4gICAgYSA9IHRcbiAgfVxuXG4gIHRoaXMuX2EgPSAoYSArIHRoaXMuX2EpIHwgMFxuICB0aGlzLl9iID0gKGIgKyB0aGlzLl9iKSB8IDBcbiAgdGhpcy5fYyA9IChjICsgdGhpcy5fYykgfCAwXG4gIHRoaXMuX2QgPSAoZCArIHRoaXMuX2QpIHwgMFxuICB0aGlzLl9lID0gKGUgKyB0aGlzLl9lKSB8IDBcbn1cblxuU2hhMS5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcigyMClcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hIHwgMCwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiB8IDAsIDQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2MgfCAwLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kIHwgMCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UgfCAwLCAxNilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTFcbiIsIi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgU2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEyNTYnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxuXG52YXIgVyA9IG5ldyBBcnJheSg2NClcblxuZnVuY3Rpb24gU2hhMjI0ICgpIHtcbiAgdGhpcy5pbml0KClcblxuICB0aGlzLl93ID0gVyAvLyBuZXcgQXJyYXkoNjQpXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhMjI0LCBTaGEyNTYpXG5cblNoYTIyNC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4YzEwNTllZDhcbiAgdGhpcy5fYiA9IDB4MzY3Y2Q1MDdcbiAgdGhpcy5fYyA9IDB4MzA3MGRkMTdcbiAgdGhpcy5fZCA9IDB4ZjcwZTU5MzlcbiAgdGhpcy5fZSA9IDB4ZmZjMDBiMzFcbiAgdGhpcy5fZiA9IDB4Njg1ODE1MTFcbiAgdGhpcy5fZyA9IDB4NjRmOThmYTdcbiAgdGhpcy5faCA9IDB4YmVmYTRmYTRcblxuICByZXR1cm4gdGhpc1xufVxuXG5TaGEyMjQucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IG5ldyBCdWZmZXIoMjgpXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYywgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UsIDE2KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9mLCAyMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZywgMjQpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGEyMjRcbiIsIi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG5cbnZhciBLID0gW1xuICAweDQyOEEyRjk4LCAweDcxMzc0NDkxLCAweEI1QzBGQkNGLCAweEU5QjVEQkE1LFxuICAweDM5NTZDMjVCLCAweDU5RjExMUYxLCAweDkyM0Y4MkE0LCAweEFCMUM1RUQ1LFxuICAweEQ4MDdBQTk4LCAweDEyODM1QjAxLCAweDI0MzE4NUJFLCAweDU1MEM3REMzLFxuICAweDcyQkU1RDc0LCAweDgwREVCMUZFLCAweDlCREMwNkE3LCAweEMxOUJGMTc0LFxuICAweEU0OUI2OUMxLCAweEVGQkU0Nzg2LCAweDBGQzE5REM2LCAweDI0MENBMUNDLFxuICAweDJERTkyQzZGLCAweDRBNzQ4NEFBLCAweDVDQjBBOURDLCAweDc2Rjk4OERBLFxuICAweDk4M0U1MTUyLCAweEE4MzFDNjZELCAweEIwMDMyN0M4LCAweEJGNTk3RkM3LFxuICAweEM2RTAwQkYzLCAweEQ1QTc5MTQ3LCAweDA2Q0E2MzUxLCAweDE0MjkyOTY3LFxuICAweDI3QjcwQTg1LCAweDJFMUIyMTM4LCAweDREMkM2REZDLCAweDUzMzgwRDEzLFxuICAweDY1MEE3MzU0LCAweDc2NkEwQUJCLCAweDgxQzJDOTJFLCAweDkyNzIyQzg1LFxuICAweEEyQkZFOEExLCAweEE4MUE2NjRCLCAweEMyNEI4QjcwLCAweEM3NkM1MUEzLFxuICAweEQxOTJFODE5LCAweEQ2OTkwNjI0LCAweEY0MEUzNTg1LCAweDEwNkFBMDcwLFxuICAweDE5QTRDMTE2LCAweDFFMzc2QzA4LCAweDI3NDg3NzRDLCAweDM0QjBCQ0I1LFxuICAweDM5MUMwQ0IzLCAweDRFRDhBQTRBLCAweDVCOUNDQTRGLCAweDY4MkU2RkYzLFxuICAweDc0OEY4MkVFLCAweDc4QTU2MzZGLCAweDg0Qzg3ODE0LCAweDhDQzcwMjA4LFxuICAweDkwQkVGRkZBLCAweEE0NTA2Q0VCLCAweEJFRjlBM0Y3LCAweEM2NzE3OEYyXG5dXG5cbnZhciBXID0gbmV3IEFycmF5KDY0KVxuXG5mdW5jdGlvbiBTaGEyNTYgKCkge1xuICB0aGlzLmluaXQoKVxuXG4gIHRoaXMuX3cgPSBXIC8vIG5ldyBBcnJheSg2NClcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGEyNTYsIEhhc2gpXG5cblNoYTI1Ni5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4NmEwOWU2NjdcbiAgdGhpcy5fYiA9IDB4YmI2N2FlODVcbiAgdGhpcy5fYyA9IDB4M2M2ZWYzNzJcbiAgdGhpcy5fZCA9IDB4YTU0ZmY1M2FcbiAgdGhpcy5fZSA9IDB4NTEwZTUyN2ZcbiAgdGhpcy5fZiA9IDB4OWIwNTY4OGNcbiAgdGhpcy5fZyA9IDB4MWY4M2Q5YWJcbiAgdGhpcy5faCA9IDB4NWJlMGNkMTlcblxuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBjaCAoeCwgeSwgeikge1xuICByZXR1cm4geiBeICh4ICYgKHkgXiB6KSlcbn1cblxuZnVuY3Rpb24gbWFqICh4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIHwgKHogJiAoeCB8IHkpKVxufVxuXG5mdW5jdGlvbiBzaWdtYTAgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiAyIHwgeCA8PCAzMCkgXiAoeCA+Pj4gMTMgfCB4IDw8IDE5KSBeICh4ID4+PiAyMiB8IHggPDwgMTApXG59XG5cbmZ1bmN0aW9uIHNpZ21hMSAoeCkge1xuICByZXR1cm4gKHggPj4+IDYgfCB4IDw8IDI2KSBeICh4ID4+PiAxMSB8IHggPDwgMjEpIF4gKHggPj4+IDI1IHwgeCA8PCA3KVxufVxuXG5mdW5jdGlvbiBnYW1tYTAgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiA3IHwgeCA8PCAyNSkgXiAoeCA+Pj4gMTggfCB4IDw8IDE0KSBeICh4ID4+PiAzKVxufVxuXG5mdW5jdGlvbiBnYW1tYTEgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiAxNyB8IHggPDwgMTUpIF4gKHggPj4+IDE5IHwgeCA8PCAxMykgXiAoeCA+Pj4gMTApXG59XG5cblNoYTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBXID0gdGhpcy5fd1xuXG4gIHZhciBhID0gdGhpcy5fYSB8IDBcbiAgdmFyIGIgPSB0aGlzLl9iIHwgMFxuICB2YXIgYyA9IHRoaXMuX2MgfCAwXG4gIHZhciBkID0gdGhpcy5fZCB8IDBcbiAgdmFyIGUgPSB0aGlzLl9lIHwgMFxuICB2YXIgZiA9IHRoaXMuX2YgfCAwXG4gIHZhciBnID0gdGhpcy5fZyB8IDBcbiAgdmFyIGggPSB0aGlzLl9oIHwgMFxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7ICsraSkgV1tpXSA9IE0ucmVhZEludDMyQkUoaSAqIDQpXG4gIGZvciAoOyBpIDwgNjQ7ICsraSkgV1tpXSA9IChnYW1tYTEoV1tpIC0gMl0pICsgV1tpIC0gN10gKyBnYW1tYTAoV1tpIC0gMTVdKSArIFdbaSAtIDE2XSkgfCAwXG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCA2NDsgKytqKSB7XG4gICAgdmFyIFQxID0gKGggKyBzaWdtYTEoZSkgKyBjaChlLCBmLCBnKSArIEtbal0gKyBXW2pdKSB8IDBcbiAgICB2YXIgVDIgPSAoc2lnbWEwKGEpICsgbWFqKGEsIGIsIGMpKSB8IDBcblxuICAgIGggPSBnXG4gICAgZyA9IGZcbiAgICBmID0gZVxuICAgIGUgPSAoZCArIFQxKSB8IDBcbiAgICBkID0gY1xuICAgIGMgPSBiXG4gICAgYiA9IGFcbiAgICBhID0gKFQxICsgVDIpIHwgMFxuICB9XG5cbiAgdGhpcy5fYSA9IChhICsgdGhpcy5fYSkgfCAwXG4gIHRoaXMuX2IgPSAoYiArIHRoaXMuX2IpIHwgMFxuICB0aGlzLl9jID0gKGMgKyB0aGlzLl9jKSB8IDBcbiAgdGhpcy5fZCA9IChkICsgdGhpcy5fZCkgfCAwXG4gIHRoaXMuX2UgPSAoZSArIHRoaXMuX2UpIHwgMFxuICB0aGlzLl9mID0gKGYgKyB0aGlzLl9mKSB8IDBcbiAgdGhpcy5fZyA9IChnICsgdGhpcy5fZykgfCAwXG4gIHRoaXMuX2ggPSAoaCArIHRoaXMuX2gpIHwgMFxufVxuXG5TaGEyNTYucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IG5ldyBCdWZmZXIoMzIpXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYywgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UsIDE2KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9mLCAyMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZywgMjQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2gsIDI4KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMjU2XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgU0hBNTEyID0gcmVxdWlyZSgnLi9zaGE1MTInKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxuXG52YXIgVyA9IG5ldyBBcnJheSgxNjApXG5cbmZ1bmN0aW9uIFNoYTM4NCAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDEyOCwgMTEyKVxufVxuXG5pbmhlcml0cyhTaGEzODQsIFNIQTUxMilcblxuU2hhMzg0LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9haCA9IDB4Y2JiYjlkNWRcbiAgdGhpcy5fYmggPSAweDYyOWEyOTJhXG4gIHRoaXMuX2NoID0gMHg5MTU5MDE1YVxuICB0aGlzLl9kaCA9IDB4MTUyZmVjZDhcbiAgdGhpcy5fZWggPSAweDY3MzMyNjY3XG4gIHRoaXMuX2ZoID0gMHg4ZWI0NGE4N1xuICB0aGlzLl9naCA9IDB4ZGIwYzJlMGRcbiAgdGhpcy5faGggPSAweDQ3YjU0ODFkXG5cbiAgdGhpcy5fYWwgPSAweGMxMDU5ZWQ4XG4gIHRoaXMuX2JsID0gMHgzNjdjZDUwN1xuICB0aGlzLl9jbCA9IDB4MzA3MGRkMTdcbiAgdGhpcy5fZGwgPSAweGY3MGU1OTM5XG4gIHRoaXMuX2VsID0gMHhmZmMwMGIzMVxuICB0aGlzLl9mbCA9IDB4Njg1ODE1MTFcbiAgdGhpcy5fZ2wgPSAweDY0Zjk4ZmE3XG4gIHRoaXMuX2hsID0gMHhiZWZhNGZhNFxuXG4gIHJldHVybiB0aGlzXG59XG5cblNoYTM4NC5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcig0OClcblxuICBmdW5jdGlvbiB3cml0ZUludDY0QkUgKGgsIGwsIG9mZnNldCkge1xuICAgIEgud3JpdGVJbnQzMkJFKGgsIG9mZnNldClcbiAgICBILndyaXRlSW50MzJCRShsLCBvZmZzZXQgKyA0KVxuICB9XG5cbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2FoLCB0aGlzLl9hbCwgMClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2JoLCB0aGlzLl9ibCwgOClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2NoLCB0aGlzLl9jbCwgMTYpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9kaCwgdGhpcy5fZGwsIDI0KVxuICB3cml0ZUludDY0QkUodGhpcy5fZWgsIHRoaXMuX2VsLCAzMilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2ZoLCB0aGlzLl9mbCwgNDApXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGEzODRcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBIYXNoID0gcmVxdWlyZSgnLi9oYXNoJylcblxudmFyIEsgPSBbXG4gIDB4NDI4YTJmOTgsIDB4ZDcyOGFlMjIsIDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QsXG4gIDB4YjVjMGZiY2YsIDB4ZWM0ZDNiMmYsIDB4ZTliNWRiYTUsIDB4ODE4OWRiYmMsXG4gIDB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzgsIDB4NTlmMTExZjEsIDB4YjYwNWQwMTksXG4gIDB4OTIzZjgyYTQsIDB4YWYxOTRmOWIsIDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgsXG4gIDB4ZDgwN2FhOTgsIDB4YTMwMzAyNDIsIDB4MTI4MzViMDEsIDB4NDU3MDZmYmUsXG4gIDB4MjQzMTg1YmUsIDB4NGVlNGIyOGMsIDB4NTUwYzdkYzMsIDB4ZDVmZmI0ZTIsXG4gIDB4NzJiZTVkNzQsIDB4ZjI3Yjg5NmYsIDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEsXG4gIDB4OWJkYzA2YTcsIDB4MjVjNzEyMzUsIDB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTQsXG4gIDB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDIsIDB4ZWZiZTQ3ODYsIDB4Mzg0ZjI1ZTMsXG4gIDB4MGZjMTlkYzYsIDB4OGI4Y2Q1YjUsIDB4MjQwY2ExY2MsIDB4NzdhYzljNjUsXG4gIDB4MmRlOTJjNmYsIDB4NTkyYjAyNzUsIDB4NGE3NDg0YWEsIDB4NmVhNmU0ODMsXG4gIDB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDQsIDB4NzZmOTg4ZGEsIDB4ODMxMTUzYjUsXG4gIDB4OTgzZTUxNTIsIDB4ZWU2NmRmYWIsIDB4YTgzMWM2NmQsIDB4MmRiNDMyMTAsXG4gIDB4YjAwMzI3YzgsIDB4OThmYjIxM2YsIDB4YmY1OTdmYzcsIDB4YmVlZjBlZTQsXG4gIDB4YzZlMDBiZjMsIDB4M2RhODhmYzIsIDB4ZDVhNzkxNDcsIDB4OTMwYWE3MjUsXG4gIDB4MDZjYTYzNTEsIDB4ZTAwMzgyNmYsIDB4MTQyOTI5NjcsIDB4MGEwZTZlNzAsXG4gIDB4MjdiNzBhODUsIDB4NDZkMjJmZmMsIDB4MmUxYjIxMzgsIDB4NWMyNmM5MjYsXG4gIDB4NGQyYzZkZmMsIDB4NWFjNDJhZWQsIDB4NTMzODBkMTMsIDB4OWQ5NWIzZGYsXG4gIDB4NjUwYTczNTQsIDB4OGJhZjYzZGUsIDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgsXG4gIDB4ODFjMmM5MmUsIDB4NDdlZGFlZTYsIDB4OTI3MjJjODUsIDB4MTQ4MjM1M2IsXG4gIDB4YTJiZmU4YTEsIDB4NGNmMTAzNjQsIDB4YTgxYTY2NGIsIDB4YmM0MjMwMDEsXG4gIDB4YzI0YjhiNzAsIDB4ZDBmODk3OTEsIDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzAsXG4gIDB4ZDE5MmU4MTksIDB4ZDZlZjUyMTgsIDB4ZDY5OTA2MjQsIDB4NTU2NWE5MTAsXG4gIDB4ZjQwZTM1ODUsIDB4NTc3MTIwMmEsIDB4MTA2YWEwNzAsIDB4MzJiYmQxYjgsXG4gIDB4MTlhNGMxMTYsIDB4YjhkMmQwYzgsIDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMsXG4gIDB4Mjc0ODc3NGMsIDB4ZGY4ZWViOTksIDB4MzRiMGJjYjUsIDB4ZTE5YjQ4YTgsXG4gIDB4MzkxYzBjYjMsIDB4YzVjOTVhNjMsIDB4NGVkOGFhNGEsIDB4ZTM0MThhY2IsXG4gIDB4NWI5Y2NhNGYsIDB4Nzc2M2UzNzMsIDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMsXG4gIDB4NzQ4ZjgyZWUsIDB4NWRlZmIyZmMsIDB4NzhhNTYzNmYsIDB4NDMxNzJmNjAsXG4gIDB4ODRjODc4MTQsIDB4YTFmMGFiNzIsIDB4OGNjNzAyMDgsIDB4MWE2NDM5ZWMsXG4gIDB4OTBiZWZmZmEsIDB4MjM2MzFlMjgsIDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTksXG4gIDB4YmVmOWEzZjcsIDB4YjJjNjc5MTUsIDB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmIsXG4gIDB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWMsIDB4ZDE4NmI4YzcsIDB4MjFjMGMyMDcsXG4gIDB4ZWFkYTdkZDYsIDB4Y2RlMGViMWUsIDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgsXG4gIDB4MDZmMDY3YWEsIDB4NzIxNzZmYmEsIDB4MGE2MzdkYzUsIDB4YTJjODk4YTYsXG4gIDB4MTEzZjk4MDQsIDB4YmVmOTBkYWUsIDB4MWI3MTBiMzUsIDB4MTMxYzQ3MWIsXG4gIDB4MjhkYjc3ZjUsIDB4MjMwNDdkODQsIDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMsXG4gIDB4M2M5ZWJlMGEsIDB4MTVjOWJlYmMsIDB4NDMxZDY3YzQsIDB4OWMxMDBkNGMsXG4gIDB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjYsIDB4NTk3ZjI5OWMsIDB4ZmM2NTdlMmEsXG4gIDB4NWZjYjZmYWIsIDB4M2FkNmZhZWMsIDB4NmM0NDE5OGMsIDB4NGE0NzU4MTdcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoMTYwKVxuXG5mdW5jdGlvbiBTaGE1MTIgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCAxMjgsIDExMilcbn1cblxuaW5oZXJpdHMoU2hhNTEyLCBIYXNoKVxuXG5TaGE1MTIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2FoID0gMHg2YTA5ZTY2N1xuICB0aGlzLl9iaCA9IDB4YmI2N2FlODVcbiAgdGhpcy5fY2ggPSAweDNjNmVmMzcyXG4gIHRoaXMuX2RoID0gMHhhNTRmZjUzYVxuICB0aGlzLl9laCA9IDB4NTEwZTUyN2ZcbiAgdGhpcy5fZmggPSAweDliMDU2ODhjXG4gIHRoaXMuX2doID0gMHgxZjgzZDlhYlxuICB0aGlzLl9oaCA9IDB4NWJlMGNkMTlcblxuICB0aGlzLl9hbCA9IDB4ZjNiY2M5MDhcbiAgdGhpcy5fYmwgPSAweDg0Y2FhNzNiXG4gIHRoaXMuX2NsID0gMHhmZTk0ZjgyYlxuICB0aGlzLl9kbCA9IDB4NWYxZDM2ZjFcbiAgdGhpcy5fZWwgPSAweGFkZTY4MmQxXG4gIHRoaXMuX2ZsID0gMHgyYjNlNmMxZlxuICB0aGlzLl9nbCA9IDB4ZmI0MWJkNmJcbiAgdGhpcy5faGwgPSAweDEzN2UyMTc5XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gQ2ggKHgsIHksIHopIHtcbiAgcmV0dXJuIHogXiAoeCAmICh5IF4geikpXG59XG5cbmZ1bmN0aW9uIG1haiAoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSB8ICh6ICYgKHggfCB5KSlcbn1cblxuZnVuY3Rpb24gc2lnbWEwICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDI4IHwgeGwgPDwgNCkgXiAoeGwgPj4+IDIgfCB4IDw8IDMwKSBeICh4bCA+Pj4gNyB8IHggPDwgMjUpXG59XG5cbmZ1bmN0aW9uIHNpZ21hMSAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxNCB8IHhsIDw8IDE4KSBeICh4ID4+PiAxOCB8IHhsIDw8IDE0KSBeICh4bCA+Pj4gOSB8IHggPDwgMjMpXG59XG5cbmZ1bmN0aW9uIEdhbW1hMCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNylcbn1cblxuZnVuY3Rpb24gR2FtbWEwbCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNyB8IHhsIDw8IDI1KVxufVxuXG5mdW5jdGlvbiBHYW1tYTEgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMTkgfCB4bCA8PCAxMykgXiAoeGwgPj4+IDI5IHwgeCA8PCAzKSBeICh4ID4+PiA2KVxufVxuXG5mdW5jdGlvbiBHYW1tYTFsICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDE5IHwgeGwgPDwgMTMpIF4gKHhsID4+PiAyOSB8IHggPDwgMykgXiAoeCA+Pj4gNiB8IHhsIDw8IDI2KVxufVxuXG5mdW5jdGlvbiBnZXRDYXJyeSAoYSwgYikge1xuICByZXR1cm4gKGEgPj4+IDApIDwgKGIgPj4+IDApID8gMSA6IDBcbn1cblxuU2hhNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGFoID0gdGhpcy5fYWggfCAwXG4gIHZhciBiaCA9IHRoaXMuX2JoIHwgMFxuICB2YXIgY2ggPSB0aGlzLl9jaCB8IDBcbiAgdmFyIGRoID0gdGhpcy5fZGggfCAwXG4gIHZhciBlaCA9IHRoaXMuX2VoIHwgMFxuICB2YXIgZmggPSB0aGlzLl9maCB8IDBcbiAgdmFyIGdoID0gdGhpcy5fZ2ggfCAwXG4gIHZhciBoaCA9IHRoaXMuX2hoIHwgMFxuXG4gIHZhciBhbCA9IHRoaXMuX2FsIHwgMFxuICB2YXIgYmwgPSB0aGlzLl9ibCB8IDBcbiAgdmFyIGNsID0gdGhpcy5fY2wgfCAwXG4gIHZhciBkbCA9IHRoaXMuX2RsIHwgMFxuICB2YXIgZWwgPSB0aGlzLl9lbCB8IDBcbiAgdmFyIGZsID0gdGhpcy5fZmwgfCAwXG4gIHZhciBnbCA9IHRoaXMuX2dsIHwgMFxuICB2YXIgaGwgPSB0aGlzLl9obCB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpICs9IDIpIHtcbiAgICBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgICBXW2kgKyAxXSA9IE0ucmVhZEludDMyQkUoaSAqIDQgKyA0KVxuICB9XG4gIGZvciAoOyBpIDwgMTYwOyBpICs9IDIpIHtcbiAgICB2YXIgeGggPSBXW2kgLSAxNSAqIDJdXG4gICAgdmFyIHhsID0gV1tpIC0gMTUgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWEwID0gR2FtbWEwKHhoLCB4bClcbiAgICB2YXIgZ2FtbWEwbCA9IEdhbW1hMGwoeGwsIHhoKVxuXG4gICAgeGggPSBXW2kgLSAyICogMl1cbiAgICB4bCA9IFdbaSAtIDIgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWExID0gR2FtbWExKHhoLCB4bClcbiAgICB2YXIgZ2FtbWExbCA9IEdhbW1hMWwoeGwsIHhoKVxuXG4gICAgLy8gV1tpXSA9IGdhbW1hMCArIFdbaSAtIDddICsgZ2FtbWExICsgV1tpIC0gMTZdXG4gICAgdmFyIFdpN2ggPSBXW2kgLSA3ICogMl1cbiAgICB2YXIgV2k3bCA9IFdbaSAtIDcgKiAyICsgMV1cblxuICAgIHZhciBXaTE2aCA9IFdbaSAtIDE2ICogMl1cbiAgICB2YXIgV2kxNmwgPSBXW2kgLSAxNiAqIDIgKyAxXVxuXG4gICAgdmFyIFdpbCA9IChnYW1tYTBsICsgV2k3bCkgfCAwXG4gICAgdmFyIFdpaCA9IChnYW1tYTAgKyBXaTdoICsgZ2V0Q2FycnkoV2lsLCBnYW1tYTBsKSkgfCAwXG4gICAgV2lsID0gKFdpbCArIGdhbW1hMWwpIHwgMFxuICAgIFdpaCA9IChXaWggKyBnYW1tYTEgKyBnZXRDYXJyeShXaWwsIGdhbW1hMWwpKSB8IDBcbiAgICBXaWwgPSAoV2lsICsgV2kxNmwpIHwgMFxuICAgIFdpaCA9IChXaWggKyBXaTE2aCArIGdldENhcnJ5KFdpbCwgV2kxNmwpKSB8IDBcblxuICAgIFdbaV0gPSBXaWhcbiAgICBXW2kgKyAxXSA9IFdpbFxuICB9XG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCAxNjA7IGogKz0gMikge1xuICAgIFdpaCA9IFdbal1cbiAgICBXaWwgPSBXW2ogKyAxXVxuXG4gICAgdmFyIG1hamggPSBtYWooYWgsIGJoLCBjaClcbiAgICB2YXIgbWFqbCA9IG1haihhbCwgYmwsIGNsKVxuXG4gICAgdmFyIHNpZ21hMGggPSBzaWdtYTAoYWgsIGFsKVxuICAgIHZhciBzaWdtYTBsID0gc2lnbWEwKGFsLCBhaClcbiAgICB2YXIgc2lnbWExaCA9IHNpZ21hMShlaCwgZWwpXG4gICAgdmFyIHNpZ21hMWwgPSBzaWdtYTEoZWwsIGVoKVxuXG4gICAgLy8gdDEgPSBoICsgc2lnbWExICsgY2ggKyBLW2pdICsgV1tqXVxuICAgIHZhciBLaWggPSBLW2pdXG4gICAgdmFyIEtpbCA9IEtbaiArIDFdXG5cbiAgICB2YXIgY2hoID0gQ2goZWgsIGZoLCBnaClcbiAgICB2YXIgY2hsID0gQ2goZWwsIGZsLCBnbClcblxuICAgIHZhciB0MWwgPSAoaGwgKyBzaWdtYTFsKSB8IDBcbiAgICB2YXIgdDFoID0gKGhoICsgc2lnbWExaCArIGdldENhcnJ5KHQxbCwgaGwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgY2hsKSB8IDBcbiAgICB0MWggPSAodDFoICsgY2hoICsgZ2V0Q2FycnkodDFsLCBjaGwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgS2lsKSB8IDBcbiAgICB0MWggPSAodDFoICsgS2loICsgZ2V0Q2FycnkodDFsLCBLaWwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgV2lsKSB8IDBcbiAgICB0MWggPSAodDFoICsgV2loICsgZ2V0Q2FycnkodDFsLCBXaWwpKSB8IDBcblxuICAgIC8vIHQyID0gc2lnbWEwICsgbWFqXG4gICAgdmFyIHQybCA9IChzaWdtYTBsICsgbWFqbCkgfCAwXG4gICAgdmFyIHQyaCA9IChzaWdtYTBoICsgbWFqaCArIGdldENhcnJ5KHQybCwgc2lnbWEwbCkpIHwgMFxuXG4gICAgaGggPSBnaFxuICAgIGhsID0gZ2xcbiAgICBnaCA9IGZoXG4gICAgZ2wgPSBmbFxuICAgIGZoID0gZWhcbiAgICBmbCA9IGVsXG4gICAgZWwgPSAoZGwgKyB0MWwpIHwgMFxuICAgIGVoID0gKGRoICsgdDFoICsgZ2V0Q2FycnkoZWwsIGRsKSkgfCAwXG4gICAgZGggPSBjaFxuICAgIGRsID0gY2xcbiAgICBjaCA9IGJoXG4gICAgY2wgPSBibFxuICAgIGJoID0gYWhcbiAgICBibCA9IGFsXG4gICAgYWwgPSAodDFsICsgdDJsKSB8IDBcbiAgICBhaCA9ICh0MWggKyB0MmggKyBnZXRDYXJyeShhbCwgdDFsKSkgfCAwXG4gIH1cblxuICB0aGlzLl9hbCA9ICh0aGlzLl9hbCArIGFsKSB8IDBcbiAgdGhpcy5fYmwgPSAodGhpcy5fYmwgKyBibCkgfCAwXG4gIHRoaXMuX2NsID0gKHRoaXMuX2NsICsgY2wpIHwgMFxuICB0aGlzLl9kbCA9ICh0aGlzLl9kbCArIGRsKSB8IDBcbiAgdGhpcy5fZWwgPSAodGhpcy5fZWwgKyBlbCkgfCAwXG4gIHRoaXMuX2ZsID0gKHRoaXMuX2ZsICsgZmwpIHwgMFxuICB0aGlzLl9nbCA9ICh0aGlzLl9nbCArIGdsKSB8IDBcbiAgdGhpcy5faGwgPSAodGhpcy5faGwgKyBobCkgfCAwXG5cbiAgdGhpcy5fYWggPSAodGhpcy5fYWggKyBhaCArIGdldENhcnJ5KHRoaXMuX2FsLCBhbCkpIHwgMFxuICB0aGlzLl9iaCA9ICh0aGlzLl9iaCArIGJoICsgZ2V0Q2FycnkodGhpcy5fYmwsIGJsKSkgfCAwXG4gIHRoaXMuX2NoID0gKHRoaXMuX2NoICsgY2ggKyBnZXRDYXJyeSh0aGlzLl9jbCwgY2wpKSB8IDBcbiAgdGhpcy5fZGggPSAodGhpcy5fZGggKyBkaCArIGdldENhcnJ5KHRoaXMuX2RsLCBkbCkpIHwgMFxuICB0aGlzLl9laCA9ICh0aGlzLl9laCArIGVoICsgZ2V0Q2FycnkodGhpcy5fZWwsIGVsKSkgfCAwXG4gIHRoaXMuX2ZoID0gKHRoaXMuX2ZoICsgZmggKyBnZXRDYXJyeSh0aGlzLl9mbCwgZmwpKSB8IDBcbiAgdGhpcy5fZ2ggPSAodGhpcy5fZ2ggKyBnaCArIGdldENhcnJ5KHRoaXMuX2dsLCBnbCkpIHwgMFxuICB0aGlzLl9oaCA9ICh0aGlzLl9oaCArIGhoICsgZ2V0Q2FycnkodGhpcy5faGwsIGhsKSkgfCAwXG59XG5cblNoYTUxMi5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcig2NClcblxuICBmdW5jdGlvbiB3cml0ZUludDY0QkUgKGgsIGwsIG9mZnNldCkge1xuICAgIEgud3JpdGVJbnQzMkJFKGgsIG9mZnNldClcbiAgICBILndyaXRlSW50MzJCRShsLCBvZmZzZXQgKyA0KVxuICB9XG5cbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2FoLCB0aGlzLl9hbCwgMClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2JoLCB0aGlzLl9ibCwgOClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2NoLCB0aGlzLl9jbCwgMTYpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9kaCwgdGhpcy5fZGwsIDI0KVxuICB3cml0ZUludDY0QkUodGhpcy5fZWgsIHRoaXMuX2VsLCAzMilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2ZoLCB0aGlzLl9mbCwgNDApXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9naCwgdGhpcy5fZ2wsIDQ4KVxuICB3cml0ZUludDY0QkUodGhpcy5faGgsIHRoaXMuX2hsLCA1NilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTUxMlxuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGNyZWF0ZUhhc2ggPSByZXF1aXJlKCdjcmVhdGUtaGFzaC9icm93c2VyJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdzdHJlYW0nKS5UcmFuc2Zvcm1cblxudmFyIFpFUk9TID0gbmV3IEJ1ZmZlcigxMjgpXG5aRVJPUy5maWxsKDApXG5cbmZ1bmN0aW9uIEhtYWMoYWxnLCBrZXkpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgYWxnID0gYWxnLnRvTG93ZXJDYXNlKClcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gbmV3IEJ1ZmZlcihrZXkpXG4gIH1cblxuICB2YXIgYmxvY2tzaXplID0gKGFsZyA9PT0gJ3NoYTUxMicgfHwgYWxnID09PSAnc2hhMzg0JykgPyAxMjggOiA2NFxuXG4gIHRoaXMuX2FsZyA9IGFsZ1xuICB0aGlzLl9rZXkgPSBrZXlcblxuICBpZiAoa2V5Lmxlbmd0aCA+IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IGNyZWF0ZUhhc2goYWxnKS51cGRhdGUoa2V5KS5kaWdlc3QoKVxuXG4gIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA8IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwgWkVST1NdLCBibG9ja3NpemUpXG4gIH1cblxuICB2YXIgaXBhZCA9IHRoaXMuX2lwYWQgPSBuZXcgQnVmZmVyKGJsb2Nrc2l6ZSlcbiAgdmFyIG9wYWQgPSB0aGlzLl9vcGFkID0gbmV3IEJ1ZmZlcihibG9ja3NpemUpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja3NpemU7IGkrKykge1xuICAgIGlwYWRbaV0gPSBrZXlbaV0gXiAweDM2XG4gICAgb3BhZFtpXSA9IGtleVtpXSBeIDB4NUNcbiAgfVxuXG4gIHRoaXMuX2hhc2ggPSBjcmVhdGVIYXNoKGFsZykudXBkYXRlKGlwYWQpXG59XG5cbmluaGVyaXRzKEhtYWMsIFRyYW5zZm9ybSlcblxuSG1hYy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGVuYykge1xuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhLCBlbmMpXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuSG1hYy5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChkYXRhLCBfLCBuZXh0KSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG5cbiAgbmV4dCgpXG59XG5cbkhtYWMucHJvdG90eXBlLl9mbHVzaCA9IGZ1bmN0aW9uIChuZXh0KSB7XG4gIHRoaXMucHVzaCh0aGlzLmRpZ2VzdCgpKVxuXG4gIG5leHQoKVxufVxuXG5IbWFjLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiAoZW5jKSB7XG4gIHZhciBoID0gdGhpcy5faGFzaC5kaWdlc3QoKVxuXG4gIHJldHVybiBjcmVhdGVIYXNoKHRoaXMuX2FsZykudXBkYXRlKHRoaXMuX29wYWQpLnVwZGF0ZShoKS5kaWdlc3QoZW5jKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZUhtYWMoYWxnLCBrZXkpIHtcbiAgcmV0dXJuIG5ldyBIbWFjKGFsZywga2V5KVxufVxuIiwidmFyIGdlbmVyYXRlUHJpbWUgPSByZXF1aXJlKCcuL2xpYi9nZW5lcmF0ZVByaW1lJylcbnZhciBwcmltZXMgPSByZXF1aXJlKCcuL2xpYi9wcmltZXMuanNvbicpXG5cbnZhciBESCA9IHJlcXVpcmUoJy4vbGliL2RoJylcblxuZnVuY3Rpb24gZ2V0RGlmZmllSGVsbG1hbiAobW9kKSB7XG4gIHZhciBwcmltZSA9IG5ldyBCdWZmZXIocHJpbWVzW21vZF0ucHJpbWUsICdoZXgnKVxuICB2YXIgZ2VuID0gbmV3IEJ1ZmZlcihwcmltZXNbbW9kXS5nZW4sICdoZXgnKVxuXG4gIHJldHVybiBuZXcgREgocHJpbWUsIGdlbilcbn1cblxudmFyIEVOQ09ESU5HUyA9IHtcbiAgJ2JpbmFyeSc6IHRydWUsICdoZXgnOiB0cnVlLCAnYmFzZTY0JzogdHJ1ZVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEaWZmaWVIZWxsbWFuIChwcmltZSwgZW5jLCBnZW5lcmF0b3IsIGdlbmMpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihlbmMpIHx8IEVOQ09ESU5HU1tlbmNdID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gY3JlYXRlRGlmZmllSGVsbG1hbihwcmltZSwgJ2JpbmFyeScsIGVuYywgZ2VuZXJhdG9yKVxuICB9XG5cbiAgZW5jID0gZW5jIHx8ICdiaW5hcnknXG4gIGdlbmMgPSBnZW5jIHx8ICdiaW5hcnknXG4gIGdlbmVyYXRvciA9IGdlbmVyYXRvciB8fCBuZXcgQnVmZmVyKFsyXSlcblxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihnZW5lcmF0b3IpKSB7XG4gICAgZ2VuZXJhdG9yID0gbmV3IEJ1ZmZlcihnZW5lcmF0b3IsIGdlbmMpXG4gIH1cblxuICBpZiAodHlwZW9mIHByaW1lID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBuZXcgREgoZ2VuZXJhdGVQcmltZShwcmltZSwgZ2VuZXJhdG9yKSwgZ2VuZXJhdG9yLCB0cnVlKVxuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocHJpbWUpKSB7XG4gICAgcHJpbWUgPSBuZXcgQnVmZmVyKHByaW1lLCBlbmMpXG4gIH1cblxuICByZXR1cm4gbmV3IERIKHByaW1lLCBnZW5lcmF0b3IsIHRydWUpXG59XG5cbmV4cG9ydHMuRGlmZmllSGVsbG1hbkdyb3VwID0gZXhwb3J0cy5jcmVhdGVEaWZmaWVIZWxsbWFuR3JvdXAgPSBleHBvcnRzLmdldERpZmZpZUhlbGxtYW4gPSBnZXREaWZmaWVIZWxsbWFuXG5leHBvcnRzLmNyZWF0ZURpZmZpZUhlbGxtYW4gPSBleHBvcnRzLkRpZmZpZUhlbGxtYW4gPSBjcmVhdGVEaWZmaWVIZWxsbWFuXG4iLCJ2YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIE1pbGxlclJhYmluID0gcmVxdWlyZSgnbWlsbGVyLXJhYmluJyk7XG52YXIgbWlsbGVyUmFiaW4gPSBuZXcgTWlsbGVyUmFiaW4oKTtcbnZhciBUV0VOVFlGT1VSID0gbmV3IEJOKDI0KTtcbnZhciBFTEVWRU4gPSBuZXcgQk4oMTEpO1xudmFyIFRFTiA9IG5ldyBCTigxMCk7XG52YXIgVEhSRUUgPSBuZXcgQk4oMyk7XG52YXIgU0VWRU4gPSBuZXcgQk4oNyk7XG52YXIgcHJpbWVzID0gcmVxdWlyZSgnLi9nZW5lcmF0ZVByaW1lJyk7XG52YXIgcmFuZG9tQnl0ZXMgPSByZXF1aXJlKCdyYW5kb21ieXRlcycpO1xubW9kdWxlLmV4cG9ydHMgPSBESDtcblxuZnVuY3Rpb24gc2V0UHVibGljS2V5KHB1YiwgZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAndXRmOCc7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHB1YikpIHtcbiAgICBwdWIgPSBuZXcgQnVmZmVyKHB1YiwgZW5jKTtcbiAgfVxuICB0aGlzLl9wdWIgPSBuZXcgQk4ocHViKTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIHNldFByaXZhdGVLZXkocHJpdiwgZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAndXRmOCc7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHByaXYpKSB7XG4gICAgcHJpdiA9IG5ldyBCdWZmZXIocHJpdiwgZW5jKTtcbiAgfVxuICB0aGlzLl9wcml2ID0gbmV3IEJOKHByaXYpO1xuICByZXR1cm4gdGhpcztcbn1cblxudmFyIHByaW1lQ2FjaGUgPSB7fTtcbmZ1bmN0aW9uIGNoZWNrUHJpbWUocHJpbWUsIGdlbmVyYXRvcikge1xuICB2YXIgZ2VuID0gZ2VuZXJhdG9yLnRvU3RyaW5nKCdoZXgnKTtcbiAgdmFyIGhleCA9IFtnZW4sIHByaW1lLnRvU3RyaW5nKDE2KV0uam9pbignXycpO1xuICBpZiAoaGV4IGluIHByaW1lQ2FjaGUpIHtcbiAgICByZXR1cm4gcHJpbWVDYWNoZVtoZXhdO1xuICB9XG4gIHZhciBlcnJvciA9IDA7XG5cbiAgaWYgKHByaW1lLmlzRXZlbigpIHx8XG4gICAgIXByaW1lcy5zaW1wbGVTaWV2ZSB8fFxuICAgICFwcmltZXMuZmVybWF0VGVzdChwcmltZSkgfHxcbiAgICAhbWlsbGVyUmFiaW4udGVzdChwcmltZSkpIHtcbiAgICAvL25vdCBhIHByaW1lIHNvICsxXG4gICAgZXJyb3IgKz0gMTtcblxuICAgIGlmIChnZW4gPT09ICcwMicgfHwgZ2VuID09PSAnMDUnKSB7XG4gICAgICAvLyB3ZSdkIGJlIGFibGUgdG8gY2hlY2sgdGhlIGdlbmVyYXRvclxuICAgICAgLy8gaXQgd291bGQgZmFpbCBzbyArOFxuICAgICAgZXJyb3IgKz0gODtcbiAgICB9IGVsc2Uge1xuICAgICAgLy93ZSB3b3VsZG4ndCBiZSBhYmxlIHRvIHRlc3QgdGhlIGdlbmVyYXRvclxuICAgICAgLy8gc28gKzRcbiAgICAgIGVycm9yICs9IDQ7XG4gICAgfVxuICAgIHByaW1lQ2FjaGVbaGV4XSA9IGVycm9yO1xuICAgIHJldHVybiBlcnJvcjtcbiAgfVxuICBpZiAoIW1pbGxlclJhYmluLnRlc3QocHJpbWUuc2hybigxKSkpIHtcbiAgICAvL25vdCBhIHNhZmUgcHJpbWVcbiAgICBlcnJvciArPSAyO1xuICB9XG4gIHZhciByZW07XG4gIHN3aXRjaCAoZ2VuKSB7XG4gICAgY2FzZSAnMDInOlxuICAgICAgaWYgKHByaW1lLm1vZChUV0VOVFlGT1VSKS5jbXAoRUxFVkVOKSkge1xuICAgICAgICAvLyB1bnN1aWRhYmxlIGdlbmVyYXRvclxuICAgICAgICBlcnJvciArPSA4O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnMDUnOlxuICAgICAgcmVtID0gcHJpbWUubW9kKFRFTik7XG4gICAgICBpZiAocmVtLmNtcChUSFJFRSkgJiYgcmVtLmNtcChTRVZFTikpIHtcbiAgICAgICAgLy8gcHJpbWUgbW9kIDEwIG5lZWRzIHRvIGVxdWFsIDMgb3IgN1xuICAgICAgICBlcnJvciArPSA4O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGVycm9yICs9IDQ7XG4gIH1cbiAgcHJpbWVDYWNoZVtoZXhdID0gZXJyb3I7XG4gIHJldHVybiBlcnJvcjtcbn1cblxuZnVuY3Rpb24gREgocHJpbWUsIGdlbmVyYXRvciwgbWFsbGVhYmxlKSB7XG4gIHRoaXMuc2V0R2VuZXJhdG9yKGdlbmVyYXRvcik7XG4gIHRoaXMuX19wcmltZSA9IG5ldyBCTihwcmltZSk7XG4gIHRoaXMuX3ByaW1lID0gQk4ubW9udCh0aGlzLl9fcHJpbWUpO1xuICB0aGlzLl9wcmltZUxlbiA9IHByaW1lLmxlbmd0aDtcbiAgdGhpcy5fcHViID0gdW5kZWZpbmVkO1xuICB0aGlzLl9wcml2ID0gdW5kZWZpbmVkO1xuICB0aGlzLl9wcmltZUNvZGUgPSB1bmRlZmluZWQ7XG4gIGlmIChtYWxsZWFibGUpIHtcbiAgICB0aGlzLnNldFB1YmxpY0tleSA9IHNldFB1YmxpY0tleTtcbiAgICB0aGlzLnNldFByaXZhdGVLZXkgPSBzZXRQcml2YXRlS2V5O1xuICB9IGVsc2Uge1xuICAgIHRoaXMuX3ByaW1lQ29kZSA9IDg7XG4gIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShESC5wcm90b3R5cGUsICd2ZXJpZnlFcnJvcicsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9wcmltZUNvZGUgIT09ICdudW1iZXInKSB7XG4gICAgICB0aGlzLl9wcmltZUNvZGUgPSBjaGVja1ByaW1lKHRoaXMuX19wcmltZSwgdGhpcy5fX2dlbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9wcmltZUNvZGU7XG4gIH1cbn0pO1xuREgucHJvdG90eXBlLmdlbmVyYXRlS2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLl9wcml2KSB7XG4gICAgdGhpcy5fcHJpdiA9IG5ldyBCTihyYW5kb21CeXRlcyh0aGlzLl9wcmltZUxlbikpO1xuICB9XG4gIHRoaXMuX3B1YiA9IHRoaXMuX2dlbi50b1JlZCh0aGlzLl9wcmltZSkucmVkUG93KHRoaXMuX3ByaXYpLmZyb21SZWQoKTtcbiAgcmV0dXJuIHRoaXMuZ2V0UHVibGljS2V5KCk7XG59O1xuXG5ESC5wcm90b3R5cGUuY29tcHV0ZVNlY3JldCA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBvdGhlciA9IG5ldyBCTihvdGhlcik7XG4gIG90aGVyID0gb3RoZXIudG9SZWQodGhpcy5fcHJpbWUpO1xuICB2YXIgc2VjcmV0ID0gb3RoZXIucmVkUG93KHRoaXMuX3ByaXYpLmZyb21SZWQoKTtcbiAgdmFyIG91dCA9IG5ldyBCdWZmZXIoc2VjcmV0LnRvQXJyYXkoKSk7XG4gIHZhciBwcmltZSA9IHRoaXMuZ2V0UHJpbWUoKTtcbiAgaWYgKG91dC5sZW5ndGggPCBwcmltZS5sZW5ndGgpIHtcbiAgICB2YXIgZnJvbnQgPSBuZXcgQnVmZmVyKHByaW1lLmxlbmd0aCAtIG91dC5sZW5ndGgpO1xuICAgIGZyb250LmZpbGwoMCk7XG4gICAgb3V0ID0gQnVmZmVyLmNvbmNhdChbZnJvbnQsIG91dF0pO1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG5ESC5wcm90b3R5cGUuZ2V0UHVibGljS2V5ID0gZnVuY3Rpb24gZ2V0UHVibGljS2V5KGVuYykge1xuICByZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5fcHViLCBlbmMpO1xufTtcblxuREgucHJvdG90eXBlLmdldFByaXZhdGVLZXkgPSBmdW5jdGlvbiBnZXRQcml2YXRlS2V5KGVuYykge1xuICByZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5fcHJpdiwgZW5jKTtcbn07XG5cbkRILnByb3RvdHlwZS5nZXRQcmltZSA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgcmV0dXJuIGZvcm1hdFJldHVyblZhbHVlKHRoaXMuX19wcmltZSwgZW5jKTtcbn07XG5cbkRILnByb3RvdHlwZS5nZXRHZW5lcmF0b3IgPSBmdW5jdGlvbiAoZW5jKSB7XG4gIHJldHVybiBmb3JtYXRSZXR1cm5WYWx1ZSh0aGlzLl9nZW4sIGVuYyk7XG59O1xuXG5ESC5wcm90b3R5cGUuc2V0R2VuZXJhdG9yID0gZnVuY3Rpb24gKGdlbiwgZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAndXRmOCc7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGdlbikpIHtcbiAgICBnZW4gPSBuZXcgQnVmZmVyKGdlbiwgZW5jKTtcbiAgfVxuICB0aGlzLl9fZ2VuID0gZ2VuO1xuICB0aGlzLl9nZW4gPSBuZXcgQk4oZ2VuKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmb3JtYXRSZXR1cm5WYWx1ZShibiwgZW5jKSB7XG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKGJuLnRvQXJyYXkoKSk7XG4gIGlmICghZW5jKSB7XG4gICAgcmV0dXJuIGJ1ZjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYnVmLnRvU3RyaW5nKGVuYyk7XG4gIH1cbn1cbiIsInZhciByYW5kb21CeXRlcyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZpbmRQcmltZTtcbmZpbmRQcmltZS5zaW1wbGVTaWV2ZSA9IHNpbXBsZVNpZXZlO1xuZmluZFByaW1lLmZlcm1hdFRlc3QgPSBmZXJtYXRUZXN0O1xudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBUV0VOVFlGT1VSID0gbmV3IEJOKDI0KTtcbnZhciBNaWxsZXJSYWJpbiA9IHJlcXVpcmUoJ21pbGxlci1yYWJpbicpO1xudmFyIG1pbGxlclJhYmluID0gbmV3IE1pbGxlclJhYmluKCk7XG52YXIgT05FID0gbmV3IEJOKDEpO1xudmFyIFRXTyA9IG5ldyBCTigyKTtcbnZhciBGSVZFID0gbmV3IEJOKDUpO1xudmFyIFNJWFRFRU4gPSBuZXcgQk4oMTYpO1xudmFyIEVJR0hUID0gbmV3IEJOKDgpO1xudmFyIFRFTiA9IG5ldyBCTigxMCk7XG52YXIgVEhSRUUgPSBuZXcgQk4oMyk7XG52YXIgU0VWRU4gPSBuZXcgQk4oNyk7XG52YXIgRUxFVkVOID0gbmV3IEJOKDExKTtcbnZhciBGT1VSID0gbmV3IEJOKDQpO1xudmFyIFRXRUxWRSA9IG5ldyBCTigxMik7XG52YXIgcHJpbWVzID0gbnVsbDtcblxuZnVuY3Rpb24gX2dldFByaW1lcygpIHtcbiAgaWYgKHByaW1lcyAhPT0gbnVsbClcbiAgICByZXR1cm4gcHJpbWVzO1xuXG4gIHZhciBsaW1pdCA9IDB4MTAwMDAwO1xuICB2YXIgcmVzID0gW107XG4gIHJlc1swXSA9IDI7XG4gIGZvciAodmFyIGkgPSAxLCBrID0gMzsgayA8IGxpbWl0OyBrICs9IDIpIHtcbiAgICB2YXIgc3FydCA9IE1hdGguY2VpbChNYXRoLnNxcnQoaykpO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgaSAmJiByZXNbal0gPD0gc3FydDsgaisrKVxuICAgICAgaWYgKGsgJSByZXNbal0gPT09IDApXG4gICAgICAgIGJyZWFrO1xuXG4gICAgaWYgKGkgIT09IGogJiYgcmVzW2pdIDw9IHNxcnQpXG4gICAgICBjb250aW51ZTtcblxuICAgIHJlc1tpKytdID0gaztcbiAgfVxuICBwcmltZXMgPSByZXM7XG4gIHJldHVybiByZXM7XG59XG5cbmZ1bmN0aW9uIHNpbXBsZVNpZXZlKHApIHtcbiAgdmFyIHByaW1lcyA9IF9nZXRQcmltZXMoKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHByaW1lcy5sZW5ndGg7IGkrKylcbiAgICBpZiAocC5tb2RuKHByaW1lc1tpXSkgPT09IDApIHtcbiAgICAgIGlmIChwLmNtcG4ocHJpbWVzW2ldKSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGZlcm1hdFRlc3QocCkge1xuICB2YXIgcmVkID0gQk4ubW9udChwKTtcbiAgcmV0dXJuIFRXTy50b1JlZChyZWQpLnJlZFBvdyhwLnN1Ym4oMSkpLmZyb21SZWQoKS5jbXBuKDEpID09PSAwO1xufVxuXG5mdW5jdGlvbiBmaW5kUHJpbWUoYml0cywgZ2VuKSB7XG4gIGlmIChiaXRzIDwgMTYpIHtcbiAgICAvLyB0aGlzIGlzIHdoYXQgb3BlbnNzbCBkb2VzXG4gICAgaWYgKGdlbiA9PT0gMiB8fCBnZW4gPT09IDUpIHtcbiAgICAgIHJldHVybiBuZXcgQk4oWzB4OGMsIDB4N2JdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5ldyBCTihbMHg4YywgMHgyN10pO1xuICAgIH1cbiAgfVxuICBnZW4gPSBuZXcgQk4oZ2VuKTtcblxuICB2YXIgbnVtLCBuMjtcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIG51bSA9IG5ldyBCTihyYW5kb21CeXRlcyhNYXRoLmNlaWwoYml0cyAvIDgpKSk7XG4gICAgd2hpbGUgKG51bS5iaXRMZW5ndGgoKSA+IGJpdHMpIHtcbiAgICAgIG51bS5pc2hybigxKTtcbiAgICB9XG4gICAgaWYgKG51bS5pc0V2ZW4oKSkge1xuICAgICAgbnVtLmlhZGQoT05FKTtcbiAgICB9XG4gICAgaWYgKCFudW0udGVzdG4oMSkpIHtcbiAgICAgIG51bS5pYWRkKFRXTyk7XG4gICAgfVxuICAgIGlmICghZ2VuLmNtcChUV08pKSB7XG4gICAgICB3aGlsZSAobnVtLm1vZChUV0VOVFlGT1VSKS5jbXAoRUxFVkVOKSkge1xuICAgICAgICBudW0uaWFkZChGT1VSKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFnZW4uY21wKEZJVkUpKSB7XG4gICAgICB3aGlsZSAobnVtLm1vZChURU4pLmNtcChUSFJFRSkpIHtcbiAgICAgICAgbnVtLmlhZGQoRk9VUik7XG4gICAgICB9XG4gICAgfVxuICAgIG4yID0gbnVtLnNocm4oMSk7XG4gICAgaWYgKHNpbXBsZVNpZXZlKG4yKSAmJiBzaW1wbGVTaWV2ZShudW0pICYmXG4gICAgICBmZXJtYXRUZXN0KG4yKSAmJiBmZXJtYXRUZXN0KG51bSkgJiZcbiAgICAgIG1pbGxlclJhYmluLnRlc3QobjIpICYmIG1pbGxlclJhYmluLnRlc3QobnVtKSkge1xuICAgICAgcmV0dXJuIG51bTtcbiAgICB9XG4gIH1cblxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICAgIFwibW9kcDFcIjoge1xuICAgICAgICBcImdlblwiOiBcIjAyXCIsXG4gICAgICAgIFwicHJpbWVcIjogXCJmZmZmZmZmZmZmZmZmZmZmYzkwZmRhYTIyMTY4YzIzNGM0YzY2MjhiODBkYzFjZDEyOTAyNGUwODhhNjdjYzc0MDIwYmJlYTYzYjEzOWIyMjUxNGEwODc5OGUzNDA0ZGRlZjk1MTliM2NkM2E0MzFiMzAyYjBhNmRmMjVmMTQzNzRmZTEzNTZkNmQ1MWMyNDVlNDg1YjU3NjYyNWU3ZWM2ZjQ0YzQyZTlhNjNhMzYyMGZmZmZmZmZmZmZmZmZmZmZcIlxuICAgIH0sXG4gICAgXCJtb2RwMlwiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U2NTM4MWZmZmZmZmZmZmZmZmZmZmZcIlxuICAgIH0sXG4gICAgXCJtb2RwNVwiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U0NWIzZGMyMDA3Y2I4YTE2M2JmMDU5OGRhNDgzNjFjNTVkMzlhNjkxNjNmYThmZDI0Y2Y1ZjgzNjU1ZDIzZGNhM2FkOTYxYzYyZjM1NjIwODU1MmJiOWVkNTI5MDc3MDk2OTY2ZDY3MGMzNTRlNGFiYzk4MDRmMTc0NmMwOGNhMjM3MzI3ZmZmZmZmZmZmZmZmZmZmZlwiXG4gICAgfSxcbiAgICBcIm1vZHAxNFwiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U0NWIzZGMyMDA3Y2I4YTE2M2JmMDU5OGRhNDgzNjFjNTVkMzlhNjkxNjNmYThmZDI0Y2Y1ZjgzNjU1ZDIzZGNhM2FkOTYxYzYyZjM1NjIwODU1MmJiOWVkNTI5MDc3MDk2OTY2ZDY3MGMzNTRlNGFiYzk4MDRmMTc0NmMwOGNhMTgyMTdjMzI5MDVlNDYyZTM2Y2UzYmUzOWU3NzJjMTgwZTg2MDM5YjI3ODNhMmVjMDdhMjhmYjVjNTVkZjA2ZjRjNTJjOWRlMmJjYmY2OTU1ODE3MTgzOTk1NDk3Y2VhOTU2YWU1MTVkMjI2MTg5OGZhMDUxMDE1NzI4ZTVhOGFhY2FhNjhmZmZmZmZmZmZmZmZmZmZmXCJcbiAgICB9LFxuICAgIFwibW9kcDE1XCI6IHtcbiAgICAgICAgXCJnZW5cIjogXCIwMlwiLFxuICAgICAgICBcInByaW1lXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmM5MGZkYWEyMjE2OGMyMzRjNGM2NjI4YjgwZGMxY2QxMjkwMjRlMDg4YTY3Y2M3NDAyMGJiZWE2M2IxMzliMjI1MTRhMDg3OThlMzQwNGRkZWY5NTE5YjNjZDNhNDMxYjMwMmIwYTZkZjI1ZjE0Mzc0ZmUxMzU2ZDZkNTFjMjQ1ZTQ4NWI1NzY2MjVlN2VjNmY0NGM0MmU5YTYzN2VkNmIwYmZmNWNiNmY0MDZiN2VkZWUzODZiZmI1YTg5OWZhNWFlOWYyNDExN2M0YjFmZTY0OTI4NjY1MWVjZTQ1YjNkYzIwMDdjYjhhMTYzYmYwNTk4ZGE0ODM2MWM1NWQzOWE2OTE2M2ZhOGZkMjRjZjVmODM2NTVkMjNkY2EzYWQ5NjFjNjJmMzU2MjA4NTUyYmI5ZWQ1MjkwNzcwOTY5NjZkNjcwYzM1NGU0YWJjOTgwNGYxNzQ2YzA4Y2ExODIxN2MzMjkwNWU0NjJlMzZjZTNiZTM5ZTc3MmMxODBlODYwMzliMjc4M2EyZWMwN2EyOGZiNWM1NWRmMDZmNGM1MmM5ZGUyYmNiZjY5NTU4MTcxODM5OTU0OTdjZWE5NTZhZTUxNWQyMjYxODk4ZmEwNTEwMTU3MjhlNWE4YWFhYzQyZGFkMzMxNzBkMDQ1MDdhMzNhODU1MjFhYmRmMWNiYTY0ZWNmYjg1MDQ1OGRiZWYwYThhZWE3MTU3NWQwNjBjN2RiMzk3MGY4NWE2ZTFlNGM3YWJmNWFlOGNkYjA5MzNkNzFlOGM5NGUwNGEyNTYxOWRjZWUzZDIyNjFhZDJlZTZiZjEyZmZhMDZkOThhMDg2NGQ4NzYwMjczM2VjODZhNjQ1MjFmMmIxODE3N2IyMDBjYmJlMTE3NTc3YTYxNWQ2Yzc3MDk4OGMwYmFkOTQ2ZTIwOGUyNGZhMDc0ZTVhYjMxNDNkYjViZmNlMGZkMTA4ZTRiODJkMTIwYTkzYWQyY2FmZmZmZmZmZmZmZmZmZmZmXCJcbiAgICB9LFxuICAgIFwibW9kcDE2XCI6IHtcbiAgICAgICAgXCJnZW5cIjogXCIwMlwiLFxuICAgICAgICBcInByaW1lXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmM5MGZkYWEyMjE2OGMyMzRjNGM2NjI4YjgwZGMxY2QxMjkwMjRlMDg4YTY3Y2M3NDAyMGJiZWE2M2IxMzliMjI1MTRhMDg3OThlMzQwNGRkZWY5NTE5YjNjZDNhNDMxYjMwMmIwYTZkZjI1ZjE0Mzc0ZmUxMzU2ZDZkNTFjMjQ1ZTQ4NWI1NzY2MjVlN2VjNmY0NGM0MmU5YTYzN2VkNmIwYmZmNWNiNmY0MDZiN2VkZWUzODZiZmI1YTg5OWZhNWFlOWYyNDExN2M0YjFmZTY0OTI4NjY1MWVjZTQ1YjNkYzIwMDdjYjhhMTYzYmYwNTk4ZGE0ODM2MWM1NWQzOWE2OTE2M2ZhOGZkMjRjZjVmODM2NTVkMjNkY2EzYWQ5NjFjNjJmMzU2MjA4NTUyYmI5ZWQ1MjkwNzcwOTY5NjZkNjcwYzM1NGU0YWJjOTgwNGYxNzQ2YzA4Y2ExODIxN2MzMjkwNWU0NjJlMzZjZTNiZTM5ZTc3MmMxODBlODYwMzliMjc4M2EyZWMwN2EyOGZiNWM1NWRmMDZmNGM1MmM5ZGUyYmNiZjY5NTU4MTcxODM5OTU0OTdjZWE5NTZhZTUxNWQyMjYxODk4ZmEwNTEwMTU3MjhlNWE4YWFhYzQyZGFkMzMxNzBkMDQ1MDdhMzNhODU1MjFhYmRmMWNiYTY0ZWNmYjg1MDQ1OGRiZWYwYThhZWE3MTU3NWQwNjBjN2RiMzk3MGY4NWE2ZTFlNGM3YWJmNWFlOGNkYjA5MzNkNzFlOGM5NGUwNGEyNTYxOWRjZWUzZDIyNjFhZDJlZTZiZjEyZmZhMDZkOThhMDg2NGQ4NzYwMjczM2VjODZhNjQ1MjFmMmIxODE3N2IyMDBjYmJlMTE3NTc3YTYxNWQ2Yzc3MDk4OGMwYmFkOTQ2ZTIwOGUyNGZhMDc0ZTVhYjMxNDNkYjViZmNlMGZkMTA4ZTRiODJkMTIwYTkyMTA4MDExYTcyM2MxMmE3ODdlNmQ3ODg3MTlhMTBiZGJhNWIyNjk5YzMyNzE4NmFmNGUyM2MxYTk0NjgzNGI2MTUwYmRhMjU4M2U5Y2EyYWQ0NGNlOGRiYmJjMmRiMDRkZThlZjkyZThlZmMxNDFmYmVjYWE2Mjg3YzU5NDc0ZTZiYzA1ZDk5YjI5NjRmYTA5MGMzYTIyMzNiYTE4NjUxNWJlN2VkMWY2MTI5NzBjZWUyZDdhZmI4MWJkZDc2MjE3MDQ4MWNkMDA2OTEyN2Q1YjA1YWE5OTNiNGVhOTg4ZDhmZGRjMTg2ZmZiN2RjOTBhNmMwOGY0ZGY0MzVjOTM0MDYzMTk5ZmZmZmZmZmZmZmZmZmZmZlwiXG4gICAgfSxcbiAgICBcIm1vZHAxN1wiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U0NWIzZGMyMDA3Y2I4YTE2M2JmMDU5OGRhNDgzNjFjNTVkMzlhNjkxNjNmYThmZDI0Y2Y1ZjgzNjU1ZDIzZGNhM2FkOTYxYzYyZjM1NjIwODU1MmJiOWVkNTI5MDc3MDk2OTY2ZDY3MGMzNTRlNGFiYzk4MDRmMTc0NmMwOGNhMTgyMTdjMzI5MDVlNDYyZTM2Y2UzYmUzOWU3NzJjMTgwZTg2MDM5YjI3ODNhMmVjMDdhMjhmYjVjNTVkZjA2ZjRjNTJjOWRlMmJjYmY2OTU1ODE3MTgzOTk1NDk3Y2VhOTU2YWU1MTVkMjI2MTg5OGZhMDUxMDE1NzI4ZTVhOGFhYWM0MmRhZDMzMTcwZDA0NTA3YTMzYTg1NTIxYWJkZjFjYmE2NGVjZmI4NTA0NThkYmVmMGE4YWVhNzE1NzVkMDYwYzdkYjM5NzBmODVhNmUxZTRjN2FiZjVhZThjZGIwOTMzZDcxZThjOTRlMDRhMjU2MTlkY2VlM2QyMjYxYWQyZWU2YmYxMmZmYTA2ZDk4YTA4NjRkODc2MDI3MzNlYzg2YTY0NTIxZjJiMTgxNzdiMjAwY2JiZTExNzU3N2E2MTVkNmM3NzA5ODhjMGJhZDk0NmUyMDhlMjRmYTA3NGU1YWIzMTQzZGI1YmZjZTBmZDEwOGU0YjgyZDEyMGE5MjEwODAxMWE3MjNjMTJhNzg3ZTZkNzg4NzE5YTEwYmRiYTViMjY5OWMzMjcxODZhZjRlMjNjMWE5NDY4MzRiNjE1MGJkYTI1ODNlOWNhMmFkNDRjZThkYmJiYzJkYjA0ZGU4ZWY5MmU4ZWZjMTQxZmJlY2FhNjI4N2M1OTQ3NGU2YmMwNWQ5OWIyOTY0ZmEwOTBjM2EyMjMzYmExODY1MTViZTdlZDFmNjEyOTcwY2VlMmQ3YWZiODFiZGQ3NjIxNzA0ODFjZDAwNjkxMjdkNWIwNWFhOTkzYjRlYTk4OGQ4ZmRkYzE4NmZmYjdkYzkwYTZjMDhmNGRmNDM1YzkzNDAyODQ5MjM2YzNmYWI0ZDI3YzcwMjZjMWQ0ZGNiMjYwMjY0NmRlYzk3NTFlNzYzZGJhMzdiZGY4ZmY5NDA2YWQ5ZTUzMGVlNWRiMzgyZjQxMzAwMWFlYjA2YTUzZWQ5MDI3ZDgzMTE3OTcyN2IwODY1YTg5MThkYTNlZGJlYmNmOWIxNGVkNDRjZTZjYmFjZWQ0YmIxYmRiN2YxNDQ3ZTZjYzI1NGIzMzIwNTE1MTJiZDdhZjQyNmZiOGY0MDEzNzhjZDJiZjU5ODNjYTAxYzY0YjkyZWNmMDMyZWExNWQxNzIxZDAzZjQ4MmQ3Y2U2ZTc0ZmVmNmQ1NWU3MDJmNDY5ODBjODJiNWE4NDAzMTkwMGIxYzllNTllN2M5N2ZiZWM3ZThmMzIzYTk3YTdlMzZjYzg4YmUwZjFkNDViN2ZmNTg1YWM1NGJkNDA3YjIyYjQxNTRhYWNjOGY2ZDdlYmY0OGUxZDgxNGNjNWVkMjBmODAzN2UwYTc5NzE1ZWVmMjliZTMyODA2YTFkNThiYjdjNWRhNzZmNTUwYWEzZDhhMWZiZmYwZWIxOWNjYjFhMzEzZDU1Y2RhNTZjOWVjMmVmMjk2MzIzODdmZThkNzZlM2MwNDY4MDQzZThmNjYzZjQ4NjBlZTEyYmYyZDViMGI3NDc0ZDZlNjk0ZjkxZTZkY2M0MDI0ZmZmZmZmZmZmZmZmZmZmZlwiXG4gICAgfSxcbiAgICBcIm1vZHAxOFwiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U0NWIzZGMyMDA3Y2I4YTE2M2JmMDU5OGRhNDgzNjFjNTVkMzlhNjkxNjNmYThmZDI0Y2Y1ZjgzNjU1ZDIzZGNhM2FkOTYxYzYyZjM1NjIwODU1MmJiOWVkNTI5MDc3MDk2OTY2ZDY3MGMzNTRlNGFiYzk4MDRmMTc0NmMwOGNhMTgyMTdjMzI5MDVlNDYyZTM2Y2UzYmUzOWU3NzJjMTgwZTg2MDM5YjI3ODNhMmVjMDdhMjhmYjVjNTVkZjA2ZjRjNTJjOWRlMmJjYmY2OTU1ODE3MTgzOTk1NDk3Y2VhOTU2YWU1MTVkMjI2MTg5OGZhMDUxMDE1NzI4ZTVhOGFhYWM0MmRhZDMzMTcwZDA0NTA3YTMzYTg1NTIxYWJkZjFjYmE2NGVjZmI4NTA0NThkYmVmMGE4YWVhNzE1NzVkMDYwYzdkYjM5NzBmODVhNmUxZTRjN2FiZjVhZThjZGIwOTMzZDcxZThjOTRlMDRhMjU2MTlkY2VlM2QyMjYxYWQyZWU2YmYxMmZmYTA2ZDk4YTA4NjRkODc2MDI3MzNlYzg2YTY0NTIxZjJiMTgxNzdiMjAwY2JiZTExNzU3N2E2MTVkNmM3NzA5ODhjMGJhZDk0NmUyMDhlMjRmYTA3NGU1YWIzMTQzZGI1YmZjZTBmZDEwOGU0YjgyZDEyMGE5MjEwODAxMWE3MjNjMTJhNzg3ZTZkNzg4NzE5YTEwYmRiYTViMjY5OWMzMjcxODZhZjRlMjNjMWE5NDY4MzRiNjE1MGJkYTI1ODNlOWNhMmFkNDRjZThkYmJiYzJkYjA0ZGU4ZWY5MmU4ZWZjMTQxZmJlY2FhNjI4N2M1OTQ3NGU2YmMwNWQ5OWIyOTY0ZmEwOTBjM2EyMjMzYmExODY1MTViZTdlZDFmNjEyOTcwY2VlMmQ3YWZiODFiZGQ3NjIxNzA0ODFjZDAwNjkxMjdkNWIwNWFhOTkzYjRlYTk4OGQ4ZmRkYzE4NmZmYjdkYzkwYTZjMDhmNGRmNDM1YzkzNDAyODQ5MjM2YzNmYWI0ZDI3YzcwMjZjMWQ0ZGNiMjYwMjY0NmRlYzk3NTFlNzYzZGJhMzdiZGY4ZmY5NDA2YWQ5ZTUzMGVlNWRiMzgyZjQxMzAwMWFlYjA2YTUzZWQ5MDI3ZDgzMTE3OTcyN2IwODY1YTg5MThkYTNlZGJlYmNmOWIxNGVkNDRjZTZjYmFjZWQ0YmIxYmRiN2YxNDQ3ZTZjYzI1NGIzMzIwNTE1MTJiZDdhZjQyNmZiOGY0MDEzNzhjZDJiZjU5ODNjYTAxYzY0YjkyZWNmMDMyZWExNWQxNzIxZDAzZjQ4MmQ3Y2U2ZTc0ZmVmNmQ1NWU3MDJmNDY5ODBjODJiNWE4NDAzMTkwMGIxYzllNTllN2M5N2ZiZWM3ZThmMzIzYTk3YTdlMzZjYzg4YmUwZjFkNDViN2ZmNTg1YWM1NGJkNDA3YjIyYjQxNTRhYWNjOGY2ZDdlYmY0OGUxZDgxNGNjNWVkMjBmODAzN2UwYTc5NzE1ZWVmMjliZTMyODA2YTFkNThiYjdjNWRhNzZmNTUwYWEzZDhhMWZiZmYwZWIxOWNjYjFhMzEzZDU1Y2RhNTZjOWVjMmVmMjk2MzIzODdmZThkNzZlM2MwNDY4MDQzZThmNjYzZjQ4NjBlZTEyYmYyZDViMGI3NDc0ZDZlNjk0ZjkxZTZkYmUxMTU5NzRhMzkyNmYxMmZlZTVlNDM4Nzc3Y2I2YTkzMmRmOGNkOGJlYzRkMDczYjkzMWJhM2JjODMyYjY4ZDlkZDMwMDc0MWZhN2JmOGFmYzQ3ZWQyNTc2ZjY5MzZiYTQyNDY2M2FhYjYzOWM1YWU0ZjU2ODM0MjNiNDc0MmJmMWM5NzgyMzhmMTZjYmUzOWQ2NTJkZTNmZGI4YmVmYzg0OGFkOTIyMjIyZTA0YTQwMzdjMDcxM2ViNTdhODFhMjNmMGM3MzQ3M2ZjNjQ2Y2VhMzA2YjRiY2JjODg2MmY4Mzg1ZGRmYTlkNGI3ZmEyYzA4N2U4Nzk2ODMzMDNlZDViZGQzYTA2MmIzY2Y1YjNhMjc4YTY2ZDJhMTNmODNmNDRmODJkZGYzMTBlZTA3NGFiNmEzNjQ1OTdlODk5YTAyNTVkYzE2NGYzMWNjNTA4NDY4NTFkZjlhYjQ4MTk1ZGVkN2VhMWIxZDUxMGJkN2VlNzRkNzNmYWYzNmJjMzFlY2ZhMjY4MzU5MDQ2ZjRlYjg3OWY5MjQwMDk0MzhiNDgxYzZjZDc4ODlhMDAyZWQ1ZWUzODJiYzkxOTBkYTZmYzAyNmU0Nzk1NThlNDQ3NTY3N2U5YWE5ZTMwNTBlMjc2NTY5NGRmYzgxZjU2ZTg4MGI5NmU3MTYwYzk4MGRkOThlZGQzZGZmZmZmZmZmZmZmZmZmZmZmXCJcbiAgICB9XG59IiwidmFyIGJuID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBicm9yYW5kID0gcmVxdWlyZSgnYnJvcmFuZCcpO1xuXG5mdW5jdGlvbiBNaWxsZXJSYWJpbihyYW5kKSB7XG4gIHRoaXMucmFuZCA9IHJhbmQgfHwgbmV3IGJyb3JhbmQuUmFuZCgpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBNaWxsZXJSYWJpbjtcblxuTWlsbGVyUmFiaW4uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHJhbmQpIHtcbiAgcmV0dXJuIG5ldyBNaWxsZXJSYWJpbihyYW5kKTtcbn07XG5cbk1pbGxlclJhYmluLnByb3RvdHlwZS5fcmFuZCA9IGZ1bmN0aW9uIF9yYW5kKG4pIHtcbiAgdmFyIGxlbiA9IG4uYml0TGVuZ3RoKCk7XG4gIHZhciBidWYgPSB0aGlzLnJhbmQuZ2VuZXJhdGUoTWF0aC5jZWlsKGxlbiAvIDgpKTtcblxuICAvLyBTZXQgbG93IGJpdHNcbiAgYnVmWzBdIHw9IDM7XG5cbiAgLy8gTWFzayBoaWdoIGJpdHNcbiAgdmFyIG1hc2sgPSBsZW4gJiAweDc7XG4gIGlmIChtYXNrICE9PSAwKVxuICAgIGJ1ZltidWYubGVuZ3RoIC0gMV0gPj49IDcgLSBtYXNrO1xuXG4gIHJldHVybiBuZXcgYm4oYnVmKTtcbn1cblxuTWlsbGVyUmFiaW4ucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbiB0ZXN0KG4sIGssIGNiKSB7XG4gIHZhciBsZW4gPSBuLmJpdExlbmd0aCgpO1xuICB2YXIgcmVkID0gYm4ubW9udChuKTtcbiAgdmFyIHJvbmUgPSBuZXcgYm4oMSkudG9SZWQocmVkKTtcblxuICBpZiAoIWspXG4gICAgayA9IE1hdGgubWF4KDEsIChsZW4gLyA0OCkgfCAwKTtcblxuICAvLyBGaW5kIGQgYW5kIHMsIChuIC0gMSkgPSAoMiBeIHMpICogZDtcbiAgdmFyIG4xID0gbi5zdWJuKDEpO1xuICB2YXIgbjIgPSBuMS5zdWJuKDEpO1xuICBmb3IgKHZhciBzID0gMDsgIW4xLnRlc3RuKHMpOyBzKyspIHt9XG4gIHZhciBkID0gbi5zaHJuKHMpO1xuXG4gIHZhciBybjEgPSBuMS50b1JlZChyZWQpO1xuXG4gIHZhciBwcmltZSA9IHRydWU7XG4gIGZvciAoOyBrID4gMDsgay0tKSB7XG4gICAgdmFyIGEgPSB0aGlzLl9yYW5kKG4yKTtcbiAgICBpZiAoY2IpXG4gICAgICBjYihhKTtcblxuICAgIHZhciB4ID0gYS50b1JlZChyZWQpLnJlZFBvdyhkKTtcbiAgICBpZiAoeC5jbXAocm9uZSkgPT09IDAgfHwgeC5jbXAocm4xKSA9PT0gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBzOyBpKyspIHtcbiAgICAgIHggPSB4LnJlZFNxcigpO1xuXG4gICAgICBpZiAoeC5jbXAocm9uZSkgPT09IDApXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIGlmICh4LmNtcChybjEpID09PSAwKVxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoaSA9PT0gcylcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBwcmltZTtcbn07XG5cbk1pbGxlclJhYmluLnByb3RvdHlwZS5nZXREaXZpc29yID0gZnVuY3Rpb24gZ2V0RGl2aXNvcihuLCBrKSB7XG4gIHZhciBsZW4gPSBuLmJpdExlbmd0aCgpO1xuICB2YXIgcmVkID0gYm4ubW9udChuKTtcbiAgdmFyIHJvbmUgPSBuZXcgYm4oMSkudG9SZWQocmVkKTtcblxuICBpZiAoIWspXG4gICAgayA9IE1hdGgubWF4KDEsIChsZW4gLyA0OCkgfCAwKTtcblxuICAvLyBGaW5kIGQgYW5kIHMsIChuIC0gMSkgPSAoMiBeIHMpICogZDtcbiAgdmFyIG4xID0gbi5zdWJuKDEpO1xuICB2YXIgbjIgPSBuMS5zdWJuKDEpO1xuICBmb3IgKHZhciBzID0gMDsgIW4xLnRlc3RuKHMpOyBzKyspIHt9XG4gIHZhciBkID0gbi5zaHJuKHMpO1xuXG4gIHZhciBybjEgPSBuMS50b1JlZChyZWQpO1xuXG4gIGZvciAoOyBrID4gMDsgay0tKSB7XG4gICAgdmFyIGEgPSB0aGlzLl9yYW5kKG4yKTtcblxuICAgIHZhciBnID0gbi5nY2QoYSk7XG4gICAgaWYgKGcuY21wbigxKSAhPT0gMClcbiAgICAgIHJldHVybiBnO1xuXG4gICAgdmFyIHggPSBhLnRvUmVkKHJlZCkucmVkUG93KGQpO1xuICAgIGlmICh4LmNtcChyb25lKSA9PT0gMCB8fCB4LmNtcChybjEpID09PSAwKVxuICAgICAgY29udGludWU7XG5cbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IHM7IGkrKykge1xuICAgICAgeCA9IHgucmVkU3FyKCk7XG5cbiAgICAgIGlmICh4LmNtcChyb25lKSA9PT0gMClcbiAgICAgICAgcmV0dXJuIHguZnJvbVJlZCgpLnN1Ym4oMSkuZ2NkKG4pO1xuICAgICAgaWYgKHguY21wKHJuMSkgPT09IDApXG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmIChpID09PSBzKSB7XG4gICAgICB4ID0geC5yZWRTcXIoKTtcbiAgICAgIHJldHVybiB4LmZyb21SZWQoKS5zdWJuKDEpLmdjZChuKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59O1xuIiwidmFyIGNyZWF0ZUhtYWMgPSByZXF1aXJlKCdjcmVhdGUtaG1hYycpXG52YXIgTUFYX0FMTE9DID0gTWF0aC5wb3coMiwgMzApIC0gMSAvLyBkZWZhdWx0IGluIGlvanNcblxuZXhwb3J0cy5wYmtkZjIgPSBwYmtkZjJcbmZ1bmN0aW9uIHBia2RmMiAocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbnMsIGtleWxlbiwgZGlnZXN0LCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIGRpZ2VzdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gZGlnZXN0XG4gICAgZGlnZXN0ID0gdW5kZWZpbmVkXG4gIH1cblxuICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyBjYWxsYmFjayBwcm92aWRlZCB0byBwYmtkZjInKVxuICB9XG5cbiAgdmFyIHJlc3VsdCA9IHBia2RmMlN5bmMocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbnMsIGtleWxlbiwgZGlnZXN0KVxuICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBjYWxsYmFjayh1bmRlZmluZWQsIHJlc3VsdClcbiAgfSlcbn1cblxuZXhwb3J0cy5wYmtkZjJTeW5jID0gcGJrZGYyU3luY1xuZnVuY3Rpb24gcGJrZGYyU3luYyAocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbnMsIGtleWxlbiwgZGlnZXN0KSB7XG4gIGlmICh0eXBlb2YgaXRlcmF0aW9ucyAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJdGVyYXRpb25zIG5vdCBhIG51bWJlcicpXG4gIH1cblxuICBpZiAoaXRlcmF0aW9ucyA8IDApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCYWQgaXRlcmF0aW9ucycpXG4gIH1cblxuICBpZiAodHlwZW9mIGtleWxlbiAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdLZXkgbGVuZ3RoIG5vdCBhIG51bWJlcicpXG4gIH1cblxuICBpZiAoa2V5bGVuIDwgMCB8fCBrZXlsZW4gPiBNQVhfQUxMT0MpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCYWQga2V5IGxlbmd0aCcpXG4gIH1cblxuICBkaWdlc3QgPSBkaWdlc3QgfHwgJ3NoYTEnXG5cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocGFzc3dvcmQpKSBwYXNzd29yZCA9IG5ldyBCdWZmZXIocGFzc3dvcmQsICdiaW5hcnknKVxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihzYWx0KSkgc2FsdCA9IG5ldyBCdWZmZXIoc2FsdCwgJ2JpbmFyeScpXG5cbiAgdmFyIGhMZW5cbiAgdmFyIGwgPSAxXG4gIHZhciBESyA9IG5ldyBCdWZmZXIoa2V5bGVuKVxuICB2YXIgYmxvY2sxID0gbmV3IEJ1ZmZlcihzYWx0Lmxlbmd0aCArIDQpXG4gIHNhbHQuY29weShibG9jazEsIDAsIDAsIHNhbHQubGVuZ3RoKVxuXG4gIHZhciByXG4gIHZhciBUXG5cbiAgZm9yICh2YXIgaSA9IDE7IGkgPD0gbDsgaSsrKSB7XG4gICAgYmxvY2sxLndyaXRlVUludDMyQkUoaSwgc2FsdC5sZW5ndGgpXG4gICAgdmFyIFUgPSBjcmVhdGVIbWFjKGRpZ2VzdCwgcGFzc3dvcmQpLnVwZGF0ZShibG9jazEpLmRpZ2VzdCgpXG5cbiAgICBpZiAoIWhMZW4pIHtcbiAgICAgIGhMZW4gPSBVLmxlbmd0aFxuICAgICAgVCA9IG5ldyBCdWZmZXIoaExlbilcbiAgICAgIGwgPSBNYXRoLmNlaWwoa2V5bGVuIC8gaExlbilcbiAgICAgIHIgPSBrZXlsZW4gLSAobCAtIDEpICogaExlblxuICAgIH1cblxuICAgIFUuY29weShULCAwLCAwLCBoTGVuKVxuXG4gICAgZm9yICh2YXIgaiA9IDE7IGogPCBpdGVyYXRpb25zOyBqKyspIHtcbiAgICAgIFUgPSBjcmVhdGVIbWFjKGRpZ2VzdCwgcGFzc3dvcmQpLnVwZGF0ZShVKS5kaWdlc3QoKVxuXG4gICAgICBmb3IgKHZhciBrID0gMDsgayA8IGhMZW47IGsrKykge1xuICAgICAgICBUW2tdIF49IFVba11cbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZGVzdFBvcyA9IChpIC0gMSkgKiBoTGVuXG4gICAgdmFyIGxlbiA9IChpID09PSBsID8gciA6IGhMZW4pXG4gICAgVC5jb3B5KERLLCBkZXN0UG9zLCAwLCBsZW4pXG4gIH1cblxuICByZXR1cm4gREtcbn1cbiIsImV4cG9ydHMucHVibGljRW5jcnlwdCA9IHJlcXVpcmUoJy4vcHVibGljRW5jcnlwdCcpO1xuZXhwb3J0cy5wcml2YXRlRGVjcnlwdCA9IHJlcXVpcmUoJy4vcHJpdmF0ZURlY3J5cHQnKTtcblxuZXhwb3J0cy5wcml2YXRlRW5jcnlwdCA9IGZ1bmN0aW9uIHByaXZhdGVFbmNyeXB0KGtleSwgYnVmKSB7XG4gIHJldHVybiBleHBvcnRzLnB1YmxpY0VuY3J5cHQoa2V5LCBidWYsIHRydWUpO1xufTtcblxuZXhwb3J0cy5wdWJsaWNEZWNyeXB0ID0gZnVuY3Rpb24gcHVibGljRGVjcnlwdChrZXksIGJ1Zikge1xuICByZXR1cm4gZXhwb3J0cy5wcml2YXRlRGVjcnlwdChrZXksIGJ1ZiwgdHJ1ZSk7XG59OyIsInZhciBjcmVhdGVIYXNoID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHNlZWQsIGxlbikge1xuICB2YXIgdCA9IG5ldyBCdWZmZXIoJycpO1xuICB2YXIgIGkgPSAwLCBjO1xuICB3aGlsZSAodC5sZW5ndGggPCBsZW4pIHtcbiAgICBjID0gaTJvcHMoaSsrKTtcbiAgICB0ID0gQnVmZmVyLmNvbmNhdChbdCwgY3JlYXRlSGFzaCgnc2hhMScpLnVwZGF0ZShzZWVkKS51cGRhdGUoYykuZGlnZXN0KCldKTtcbiAgfVxuICByZXR1cm4gdC5zbGljZSgwLCBsZW4pO1xufTtcblxuZnVuY3Rpb24gaTJvcHMoYykge1xuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcig0KTtcbiAgb3V0LndyaXRlVUludDMyQkUoYywwKTtcbiAgcmV0dXJuIG91dDtcbn0iLCJ2YXIgYm4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIHJhbmRvbUJ5dGVzID0gcmVxdWlyZSgncmFuZG9tYnl0ZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gY3J0O1xuZnVuY3Rpb24gYmxpbmQocHJpdikge1xuICB2YXIgciA9IGdldHIocHJpdik7XG4gIHZhciBibGluZGVyID0gci50b1JlZChibi5tb250KHByaXYubW9kdWx1cykpXG4gIC5yZWRQb3cobmV3IGJuKHByaXYucHVibGljRXhwb25lbnQpKS5mcm9tUmVkKCk7XG4gIHJldHVybiB7XG4gICAgYmxpbmRlcjogYmxpbmRlcixcbiAgICB1bmJsaW5kZXI6ci5pbnZtKHByaXYubW9kdWx1cylcbiAgfTtcbn1cbmZ1bmN0aW9uIGNydChtc2csIHByaXYpIHtcbiAgdmFyIGJsaW5kcyA9IGJsaW5kKHByaXYpO1xuICB2YXIgbGVuID0gcHJpdi5tb2R1bHVzLmJ5dGVMZW5ndGgoKTtcbiAgdmFyIG1vZCA9IGJuLm1vbnQocHJpdi5tb2R1bHVzKTtcbiAgdmFyIGJsaW5kZWQgPSBuZXcgYm4obXNnKS5tdWwoYmxpbmRzLmJsaW5kZXIpLnVtb2QocHJpdi5tb2R1bHVzKTtcbiAgdmFyIGMxID0gYmxpbmRlZC50b1JlZChibi5tb250KHByaXYucHJpbWUxKSk7XG4gIHZhciBjMiA9IGJsaW5kZWQudG9SZWQoYm4ubW9udChwcml2LnByaW1lMikpO1xuICB2YXIgcWludiA9IHByaXYuY29lZmZpY2llbnQ7XG4gIHZhciBwID0gcHJpdi5wcmltZTE7XG4gIHZhciBxID0gcHJpdi5wcmltZTI7XG4gIHZhciBtMSA9IGMxLnJlZFBvdyhwcml2LmV4cG9uZW50MSk7XG4gIHZhciBtMiA9IGMyLnJlZFBvdyhwcml2LmV4cG9uZW50Mik7XG4gIG0xID0gbTEuZnJvbVJlZCgpO1xuICBtMiA9IG0yLmZyb21SZWQoKTtcbiAgdmFyIGggPSBtMS5pc3ViKG0yKS5pbXVsKHFpbnYpLnVtb2QocCk7XG4gIGguaW11bChxKTtcbiAgbTIuaWFkZChoKTtcbiAgcmV0dXJuIG5ldyBCdWZmZXIobTIuaW11bChibGluZHMudW5ibGluZGVyKS51bW9kKHByaXYubW9kdWx1cykudG9BcnJheShmYWxzZSwgbGVuKSk7XG59XG5jcnQuZ2V0ciA9IGdldHI7XG5mdW5jdGlvbiBnZXRyKHByaXYpIHtcbiAgdmFyIGxlbiA9IHByaXYubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIHZhciByID0gbmV3IGJuKHJhbmRvbUJ5dGVzKGxlbikpO1xuICB3aGlsZSAoci5jbXAocHJpdi5tb2R1bHVzKSA+PSAgMCB8fCAhci51bW9kKHByaXYucHJpbWUxKSB8fCAhci51bW9kKHByaXYucHJpbWUyKSkge1xuICAgIHIgPSBuZXcgYm4ocmFuZG9tQnl0ZXMobGVuKSk7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG4iLCIvLyBhZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2FwYXRpbC9wZW1zdHJpcFxudmFyIGZpbmRQcm9jID0gL1Byb2MtVHlwZTogNCxFTkNSWVBURURcXHI/XFxuREVLLUluZm86IEFFUy0oKD86MTI4KXwoPzoxOTIpfCg/OjI1NikpLUNCQywoWzAtOUEtSF0rKVxccj9cXG5cXHI/XFxuKFswLTlBLXpcXG5cXHJcXCtcXC9cXD1dKylcXHI/XFxuL21cbnZhciBzdGFydFJlZ2V4ID0gL14tLS0tLUJFR0lOICguKikgS0VZLS0tLS1cXHI/XFxuL21cbnZhciBmdWxsUmVnZXggPSAvXi0tLS0tQkVHSU4gKC4qKSBLRVktLS0tLVxccj9cXG4oWzAtOUEtelxcblxcclxcK1xcL1xcPV0rKVxccj9cXG4tLS0tLUVORCBcXDEgS0VZLS0tLS0kL21cbnZhciBldnAgPSByZXF1aXJlKCdldnBfYnl0ZXN0b2tleScpXG52YXIgY2lwaGVycyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktYWVzJylcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9rZXksIHBhc3N3b3JkKSB7XG4gIHZhciBrZXkgPSBva2V5LnRvU3RyaW5nKClcbiAgdmFyIG1hdGNoID0ga2V5Lm1hdGNoKGZpbmRQcm9jKVxuICB2YXIgZGVjcnlwdGVkXG4gIGlmICghbWF0Y2gpIHtcbiAgICB2YXIgbWF0Y2gyID0ga2V5Lm1hdGNoKGZ1bGxSZWdleClcbiAgICBkZWNyeXB0ZWQgPSBuZXcgQnVmZmVyKG1hdGNoMlsyXS5yZXBsYWNlKC9cXHI/XFxuL2csICcnKSwgJ2Jhc2U2NCcpXG4gIH0gZWxzZSB7XG4gICAgdmFyIHN1aXRlID0gJ2FlcycgKyBtYXRjaFsxXVxuICAgIHZhciBpdiA9IG5ldyBCdWZmZXIobWF0Y2hbMl0sICdoZXgnKVxuICAgIHZhciBjaXBoZXJUZXh0ID0gbmV3IEJ1ZmZlcihtYXRjaFszXS5yZXBsYWNlKC9cXHI/XFxuL2csICcnKSwgJ2Jhc2U2NCcpXG4gICAgdmFyIGNpcGhlcktleSA9IGV2cChwYXNzd29yZCwgaXYuc2xpY2UoMCwgOCksIHBhcnNlSW50KG1hdGNoWzFdLCAxMCkpLmtleVxuICAgIHZhciBvdXQgPSBbXVxuICAgIHZhciBjaXBoZXIgPSBjaXBoZXJzLmNyZWF0ZURlY2lwaGVyaXYoc3VpdGUsIGNpcGhlcktleSwgaXYpXG4gICAgb3V0LnB1c2goY2lwaGVyLnVwZGF0ZShjaXBoZXJUZXh0KSlcbiAgICBvdXQucHVzaChjaXBoZXIuZmluYWwoKSlcbiAgICBkZWNyeXB0ZWQgPSBCdWZmZXIuY29uY2F0KG91dClcbiAgfVxuICB2YXIgdGFnID0ga2V5Lm1hdGNoKHN0YXJ0UmVnZXgpWzFdICsgJyBLRVknXG4gIHJldHVybiB7XG4gICAgdGFnOiB0YWcsXG4gICAgZGF0YTogZGVjcnlwdGVkXG4gIH1cbn1cbiIsInZhciBhc24xID0gcmVxdWlyZSgnLi9hc24xJylcbnZhciBhZXNpZCA9IHJlcXVpcmUoJy4vYWVzaWQuanNvbicpXG52YXIgZml4UHJvYyA9IHJlcXVpcmUoJy4vZml4UHJvYycpXG52YXIgY2lwaGVycyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktYWVzJylcbnZhciBjb21wYXQgPSByZXF1aXJlKCdwYmtkZjInKVxubW9kdWxlLmV4cG9ydHMgPSBwYXJzZUtleXNcblxuZnVuY3Rpb24gcGFyc2VLZXlzIChidWZmZXIpIHtcbiAgdmFyIHBhc3N3b3JkXG4gIGlmICh0eXBlb2YgYnVmZmVyID09PSAnb2JqZWN0JyAmJiAhQnVmZmVyLmlzQnVmZmVyKGJ1ZmZlcikpIHtcbiAgICBwYXNzd29yZCA9IGJ1ZmZlci5wYXNzcGhyYXNlXG4gICAgYnVmZmVyID0gYnVmZmVyLmtleVxuICB9XG4gIGlmICh0eXBlb2YgYnVmZmVyID09PSAnc3RyaW5nJykge1xuICAgIGJ1ZmZlciA9IG5ldyBCdWZmZXIoYnVmZmVyKVxuICB9XG5cbiAgdmFyIHN0cmlwcGVkID0gZml4UHJvYyhidWZmZXIsIHBhc3N3b3JkKVxuXG4gIHZhciB0eXBlID0gc3RyaXBwZWQudGFnXG4gIHZhciBkYXRhID0gc3RyaXBwZWQuZGF0YVxuICB2YXIgc3VidHlwZSwgbmRhdGFcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnUFVCTElDIEtFWSc6XG4gICAgICBuZGF0YSA9IGFzbjEuUHVibGljS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIHN1YnR5cGUgPSBuZGF0YS5hbGdvcml0aG0uYWxnb3JpdGhtLmpvaW4oJy4nKVxuICAgICAgc3dpdGNoIChzdWJ0eXBlKSB7XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTEzNTQ5LjEuMS4xJzpcbiAgICAgICAgICByZXR1cm4gYXNuMS5SU0FQdWJsaWNLZXkuZGVjb2RlKG5kYXRhLnN1YmplY3RQdWJsaWNLZXkuZGF0YSwgJ2RlcicpXG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDUuMi4xJzpcbiAgICAgICAgICBuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSA9IG5kYXRhLnN1YmplY3RQdWJsaWNLZXlcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2VjJyxcbiAgICAgICAgICAgIGRhdGE6IG5kYXRhXG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQwLjQuMSc6XG4gICAgICAgICAgbmRhdGEuYWxnb3JpdGhtLnBhcmFtcy5wdWJfa2V5ID0gYXNuMS5EU0FwYXJhbS5kZWNvZGUobmRhdGEuc3ViamVjdFB1YmxpY0tleS5kYXRhLCAnZGVyJylcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2RzYScsXG4gICAgICAgICAgICBkYXRhOiBuZGF0YS5hbGdvcml0aG0ucGFyYW1zXG4gICAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24ga2V5IGlkICcgKyBzdWJ0eXBlKVxuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSB0eXBlICcgKyB0eXBlKVxuICAgIGNhc2UgJ0VOQ1JZUFRFRCBQUklWQVRFIEtFWSc6XG4gICAgICBkYXRhID0gYXNuMS5FbmNyeXB0ZWRQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIGRhdGEgPSBkZWNyeXB0KGRhdGEsIHBhc3N3b3JkKVxuICAgICAgLy8gZmFsbHMgdGhyb3VnaFxuICAgIGNhc2UgJ1BSSVZBVEUgS0VZJzpcbiAgICAgIG5kYXRhID0gYXNuMS5Qcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIHN1YnR5cGUgPSBuZGF0YS5hbGdvcml0aG0uYWxnb3JpdGhtLmpvaW4oJy4nKVxuICAgICAgc3dpdGNoIChzdWJ0eXBlKSB7XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTEzNTQ5LjEuMS4xJzpcbiAgICAgICAgICByZXR1cm4gYXNuMS5SU0FQcml2YXRlS2V5LmRlY29kZShuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSwgJ2RlcicpXG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDUuMi4xJzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3VydmU6IG5kYXRhLmFsZ29yaXRobS5jdXJ2ZSxcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IGFzbjEuRUNQcml2YXRlS2V5LmRlY29kZShuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSwgJ2RlcicpLnByaXZhdGVLZXlcbiAgICAgICAgICB9XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDAuNC4xJzpcbiAgICAgICAgICBuZGF0YS5hbGdvcml0aG0ucGFyYW1zLnByaXZfa2V5ID0gYXNuMS5EU0FwYXJhbS5kZWNvZGUobmRhdGEuc3ViamVjdFByaXZhdGVLZXksICdkZXInKVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAnZHNhJyxcbiAgICAgICAgICAgIHBhcmFtczogbmRhdGEuYWxnb3JpdGhtLnBhcmFtc1xuICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSBpZCAnICsgc3VidHlwZSlcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgdHlwZSAnICsgdHlwZSlcbiAgICBjYXNlICdSU0EgUFVCTElDIEtFWSc6XG4gICAgICByZXR1cm4gYXNuMS5SU0FQdWJsaWNLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgIGNhc2UgJ1JTQSBQUklWQVRFIEtFWSc6XG4gICAgICByZXR1cm4gYXNuMS5SU0FQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICBjYXNlICdEU0EgUFJJVkFURSBLRVknOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2RzYScsXG4gICAgICAgIHBhcmFtczogYXNuMS5EU0FQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIH1cbiAgICBjYXNlICdFQyBQUklWQVRFIEtFWSc6XG4gICAgICBkYXRhID0gYXNuMS5FQ1ByaXZhdGVLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY3VydmU6IGRhdGEucGFyYW1ldGVycy52YWx1ZSxcbiAgICAgICAgcHJpdmF0ZUtleTogZGF0YS5wcml2YXRlS2V5XG4gICAgICB9XG4gICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSB0eXBlICcgKyB0eXBlKVxuICB9XG59XG5wYXJzZUtleXMuc2lnbmF0dXJlID0gYXNuMS5zaWduYXR1cmVcbmZ1bmN0aW9uIGRlY3J5cHQgKGRhdGEsIHBhc3N3b3JkKSB7XG4gIHZhciBzYWx0ID0gZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5rZGUua2RlcGFyYW1zLnNhbHRcbiAgdmFyIGl0ZXJzID0gcGFyc2VJbnQoZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5rZGUua2RlcGFyYW1zLml0ZXJzLnRvU3RyaW5nKCksIDEwKVxuICB2YXIgYWxnbyA9IGFlc2lkW2RhdGEuYWxnb3JpdGhtLmRlY3J5cHQuY2lwaGVyLmFsZ28uam9pbignLicpXVxuICB2YXIgaXYgPSBkYXRhLmFsZ29yaXRobS5kZWNyeXB0LmNpcGhlci5pdlxuICB2YXIgY2lwaGVyVGV4dCA9IGRhdGEuc3ViamVjdFByaXZhdGVLZXlcbiAgdmFyIGtleWxlbiA9IHBhcnNlSW50KGFsZ28uc3BsaXQoJy0nKVsxXSwgMTApIC8gOFxuICB2YXIga2V5ID0gY29tcGF0LnBia2RmMlN5bmMocGFzc3dvcmQsIHNhbHQsIGl0ZXJzLCBrZXlsZW4pXG4gIHZhciBjaXBoZXIgPSBjaXBoZXJzLmNyZWF0ZURlY2lwaGVyaXYoYWxnbywga2V5LCBpdilcbiAgdmFyIG91dCA9IFtdXG4gIG91dC5wdXNoKGNpcGhlci51cGRhdGUoY2lwaGVyVGV4dCkpXG4gIG91dC5wdXNoKGNpcGhlci5maW5hbCgpKVxuICByZXR1cm4gQnVmZmVyLmNvbmNhdChvdXQpXG59XG4iLCIvLyBiYXNlZCBvbiB0aGUgYWVzIGltcGxpbWVudGF0aW9uIGluIHRyaXBsZSBzZWNcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9rZXliYXNlL3RyaXBsZXNlY1xuXG4vLyB3aGljaCBpcyBpbiB0dXJuIGJhc2VkIG9uIHRoZSBvbmUgZnJvbSBjcnlwdG8tanNcbi8vIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL1xuXG52YXIgdWludF9tYXggPSBNYXRoLnBvdygyLCAzMilcbmZ1bmN0aW9uIGZpeHVwX3VpbnQzMiAoeCkge1xuICB2YXIgcmV0LCB4X3Bvc1xuICByZXQgPSB4ID4gdWludF9tYXggfHwgeCA8IDAgPyAoeF9wb3MgPSBNYXRoLmFicyh4KSAlIHVpbnRfbWF4LCB4IDwgMCA/IHVpbnRfbWF4IC0geF9wb3MgOiB4X3BvcykgOiB4XG4gIHJldHVybiByZXRcbn1cbmZ1bmN0aW9uIHNjcnViX3ZlYyAodikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHYubGVuZ3RoOyB2KyspIHtcbiAgICB2W2ldID0gMFxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG5mdW5jdGlvbiBHbG9iYWwgKCkge1xuICB0aGlzLlNCT1ggPSBbXVxuICB0aGlzLklOVl9TQk9YID0gW11cbiAgdGhpcy5TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLklOVl9TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLmluaXQoKVxuICB0aGlzLlJDT04gPSBbMHgwMCwgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxYiwgMHgzNl1cbn1cblxuR2xvYmFsLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZCwgaSwgc3gsIHQsIHgsIHgyLCB4NCwgeDgsIHhpLCBfaVxuICBkID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgX2ksIF9yZXN1bHRzXG4gICAgX3Jlc3VsdHMgPSBbXVxuICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgICBpZiAoaSA8IDEyOCkge1xuICAgICAgICBfcmVzdWx0cy5wdXNoKGkgPDwgMSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9yZXN1bHRzLnB1c2goKGkgPDwgMSkgXiAweDExYilcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIF9yZXN1bHRzXG4gIH0pKClcbiAgeCA9IDBcbiAgeGkgPSAwXG4gIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgc3ggPSB4aSBeICh4aSA8PCAxKSBeICh4aSA8PCAyKSBeICh4aSA8PCAzKSBeICh4aSA8PCA0KVxuICAgIHN4ID0gKHN4ID4+PiA4KSBeIChzeCAmIDB4ZmYpIF4gMHg2M1xuICAgIHRoaXMuU0JPWFt4XSA9IHN4XG4gICAgdGhpcy5JTlZfU0JPWFtzeF0gPSB4XG4gICAgeDIgPSBkW3hdXG4gICAgeDQgPSBkW3gyXVxuICAgIHg4ID0gZFt4NF1cbiAgICB0ID0gKGRbc3hdICogMHgxMDEpIF4gKHN4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuU1VCX01JWFswXVt4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KVxuICAgIHRoaXMuU1VCX01JWFsxXVt4XSA9ICh0IDw8IDE2KSB8ICh0ID4+PiAxNilcbiAgICB0aGlzLlNVQl9NSVhbMl1beF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLlNVQl9NSVhbM11beF0gPSB0XG4gICAgdCA9ICh4OCAqIDB4MTAxMDEwMSkgXiAoeDQgKiAweDEwMDAxKSBeICh4MiAqIDB4MTAxKSBeICh4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMF1bc3hdID0gKHQgPDwgMjQpIHwgKHQgPj4+IDgpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsxXVtzeF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsyXVtzeF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLklOVl9TVUJfTUlYWzNdW3N4XSA9IHRcbiAgICBpZiAoeCA9PT0gMCkge1xuICAgICAgeCA9IHhpID0gMVxuICAgIH0gZWxzZSB7XG4gICAgICB4ID0geDIgXiBkW2RbZFt4OCBeIHgyXV1dXG4gICAgICB4aSBePSBkW2RbeGldXVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG52YXIgRyA9IG5ldyBHbG9iYWwoKVxuXG5BRVMuYmxvY2tTaXplID0gNCAqIDRcblxuQUVTLnByb3RvdHlwZS5ibG9ja1NpemUgPSBBRVMuYmxvY2tTaXplXG5cbkFFUy5rZXlTaXplID0gMjU2IC8gOFxuXG5BRVMucHJvdG90eXBlLmtleVNpemUgPSBBRVMua2V5U2l6ZVxuXG5mdW5jdGlvbiBidWZmZXJUb0FycmF5IChidWYpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGggLyA0XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkobGVuKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWYucmVhZFVJbnQzMkJFKGkgKiA0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIEFFUyAoa2V5KSB7XG4gIHRoaXMuX2tleSA9IGJ1ZmZlclRvQXJyYXkoa2V5KVxuICB0aGlzLl9kb1Jlc2V0KClcbn1cblxuQUVTLnByb3RvdHlwZS5fZG9SZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGludktzUm93LCBrZXlTaXplLCBrZXlXb3Jkcywga3NSb3csIGtzUm93cywgdFxuICBrZXlXb3JkcyA9IHRoaXMuX2tleVxuICBrZXlTaXplID0ga2V5V29yZHMubGVuZ3RoXG4gIHRoaXMuX25Sb3VuZHMgPSBrZXlTaXplICsgNlxuICBrc1Jvd3MgPSAodGhpcy5fblJvdW5kcyArIDEpICogNFxuICB0aGlzLl9rZXlTY2hlZHVsZSA9IFtdXG4gIGZvciAoa3NSb3cgPSAwOyBrc1JvdyA8IGtzUm93czsga3NSb3crKykge1xuICAgIHRoaXMuX2tleVNjaGVkdWxlW2tzUm93XSA9IGtzUm93IDwga2V5U2l6ZSA/IGtleVdvcmRzW2tzUm93XSA6ICh0ID0gdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSAxXSwgKGtzUm93ICUga2V5U2l6ZSkgPT09IDAgPyAodCA9ICh0IDw8IDgpIHwgKHQgPj4+IDI0KSwgdCA9IChHLlNCT1hbdCA+Pj4gMjRdIDw8IDI0KSB8IChHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChHLlNCT1hbKHQgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBHLlNCT1hbdCAmIDB4ZmZdLCB0IF49IEcuUkNPTlsoa3NSb3cgLyBrZXlTaXplKSB8IDBdIDw8IDI0KSA6IGtleVNpemUgPiA2ICYmIGtzUm93ICUga2V5U2l6ZSA9PT0gNCA/IHQgPSAoRy5TQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgRy5TQk9YW3QgJiAweGZmXSA6IHZvaWQgMCwgdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSBrZXlTaXplXSBeIHQpXG4gIH1cbiAgdGhpcy5faW52S2V5U2NoZWR1bGUgPSBbXVxuICBmb3IgKGludktzUm93ID0gMDsgaW52S3NSb3cgPCBrc1Jvd3M7IGludktzUm93KyspIHtcbiAgICBrc1JvdyA9IGtzUm93cyAtIGludktzUm93XG4gICAgdCA9IHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0gKGludktzUm93ICUgNCA/IDAgOiA0KV1cbiAgICB0aGlzLl9pbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSBpbnZLc1JvdyA8IDQgfHwga3NSb3cgPD0gNCA/IHQgOiBHLklOVl9TVUJfTUlYWzBdW0cuU0JPWFt0ID4+PiAyNF1dIF4gRy5JTlZfU1VCX01JWFsxXVtHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbMl1bRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbM11bRy5TQk9YW3QgJiAweGZmXV1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5BRVMucHJvdG90eXBlLmVuY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5fa2V5U2NoZWR1bGUsIEcuU1VCX01JWCwgRy5TQk9YKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxuXG5BRVMucHJvdG90eXBlLmRlY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciB0ZW1wID0gW01bM10sIE1bMV1dXG4gIE1bMV0gPSB0ZW1wWzBdXG4gIE1bM10gPSB0ZW1wWzFdXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5faW52S2V5U2NoZWR1bGUsIEcuSU5WX1NVQl9NSVgsIEcuSU5WX1NCT1gpXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKDE2KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMF0sIDApXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgNClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzJdLCA4KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDEyKVxuICByZXR1cm4gYnVmXG59XG5cbkFFUy5wcm90b3R5cGUuc2NydWIgPSBmdW5jdGlvbiAoKSB7XG4gIHNjcnViX3ZlYyh0aGlzLl9rZXlTY2hlZHVsZSlcbiAgc2NydWJfdmVjKHRoaXMuX2ludktleVNjaGVkdWxlKVxuICBzY3J1Yl92ZWModGhpcy5fa2V5KVxufVxuXG5BRVMucHJvdG90eXBlLl9kb0NyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSwga2V5U2NoZWR1bGUsIFNVQl9NSVgsIFNCT1gpIHtcbiAgdmFyIGtzUm93LCBzMCwgczEsIHMyLCBzMywgdDAsIHQxLCB0MiwgdDNcblxuICBzMCA9IE1bMF0gXiBrZXlTY2hlZHVsZVswXVxuICBzMSA9IE1bMV0gXiBrZXlTY2hlZHVsZVsxXVxuICBzMiA9IE1bMl0gXiBrZXlTY2hlZHVsZVsyXVxuICBzMyA9IE1bM10gXiBrZXlTY2hlZHVsZVszXVxuICBrc1JvdyA9IDRcbiAgZm9yICh2YXIgcm91bmQgPSAxOyByb3VuZCA8IHRoaXMuX25Sb3VuZHM7IHJvdW5kKyspIHtcbiAgICB0MCA9IFNVQl9NSVhbMF1bczAgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMxID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMyID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMyAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MSA9IFNVQl9NSVhbMF1bczEgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMyID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMzID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMCAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MiA9IFNVQl9NSVhbMF1bczIgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMzID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMwID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMSAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MyA9IFNVQl9NSVhbMF1bczMgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMwID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMxID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMiAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICBzMCA9IHQwXG4gICAgczEgPSB0MVxuICAgIHMyID0gdDJcbiAgICBzMyA9IHQzXG4gIH1cbiAgdDAgPSAoKFNCT1hbczAgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczEgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMiA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczMgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MSA9ICgoU0JPWFtzMSA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMiA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMzID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMCAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gIHQyID0gKChTQk9YW3MyID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMzID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczAgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDMgPSAoKFNCT1hbczMgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczAgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMSA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczIgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICByZXR1cm4gW1xuICAgIGZpeHVwX3VpbnQzMih0MCksXG4gICAgZml4dXBfdWludDMyKHQxKSxcbiAgICBmaXh1cF91aW50MzIodDIpLFxuICAgIGZpeHVwX3VpbnQzMih0MylcbiAgXVxufVxuXG5leHBvcnRzLkFFUyA9IEFFU1xuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgR0hBU0ggPSByZXF1aXJlKCcuL2doYXNoJylcbnZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcblxuZnVuY3Rpb24gU3RyZWFtQ2lwaGVyIChtb2RlLCBrZXksIGl2LCBkZWNyeXB0KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTdHJlYW1DaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZSwga2V5LCBpdilcbiAgfVxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLl9maW5JRCA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAxXSldKVxuICBpdiA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAyXSldKVxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgdGhpcy5fY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9zZWNDYWNoZSA9IG5ldyBCdWZmZXIoJycpXG4gIHRoaXMuX2RlY3J5cHQgPSBkZWNyeXB0XG4gIHRoaXMuX2FsZW4gPSAwXG4gIHRoaXMuX2xlbiA9IDBcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB2YXIgaCA9IG5ldyBCdWZmZXIoNClcbiAgaC5maWxsKDApXG4gIHRoaXMuX2doYXNoID0gbmV3IEdIQVNIKHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2soaCkpXG4gIHRoaXMuX2F1dGhUYWcgPSBudWxsXG4gIHRoaXMuX2NhbGxlZCA9IGZhbHNlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgaWYgKCF0aGlzLl9jYWxsZWQgJiYgdGhpcy5fYWxlbikge1xuICAgIHZhciBydW1wID0gMTYgLSAodGhpcy5fYWxlbiAlIDE2KVxuICAgIGlmIChydW1wIDwgMTYpIHtcbiAgICAgIHJ1bXAgPSBuZXcgQnVmZmVyKHJ1bXApXG4gICAgICBydW1wLmZpbGwoMClcbiAgICAgIHRoaXMuX2doYXNoLnVwZGF0ZShydW1wKVxuICAgIH1cbiAgfVxuICB0aGlzLl9jYWxsZWQgPSB0cnVlXG4gIHZhciBvdXQgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gIGlmICh0aGlzLl9kZWNyeXB0KSB7XG4gICAgdGhpcy5fZ2hhc2gudXBkYXRlKGNodW5rKVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShvdXQpXG4gIH1cbiAgdGhpcy5fbGVuICs9IGNodW5rLmxlbmd0aFxuICByZXR1cm4gb3V0XG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuX2RlY3J5cHQgJiYgIXRoaXMuX2F1dGhUYWcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YScpXG4gIH1cbiAgdmFyIHRhZyA9IHhvcih0aGlzLl9naGFzaC5maW5hbCh0aGlzLl9hbGVuICogOCwgdGhpcy5fbGVuICogOCksIHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2sodGhpcy5fZmluSUQpKVxuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIGlmICh4b3JUZXN0KHRhZywgdGhpcy5fYXV0aFRhZykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgc3RhdGUgb3IgdW5hYmxlIHRvIGF1dGhlbnRpY2F0ZSBkYXRhJylcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fYXV0aFRhZyA9IHRhZ1xuICB9XG4gIHRoaXMuX2NpcGhlci5zY3J1YigpXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiBnZXRBdXRoVGFnICgpIHtcbiAgaWYgKCF0aGlzLl9kZWNyeXB0ICYmIEJ1ZmZlci5pc0J1ZmZlcih0aGlzLl9hdXRoVGFnKSkge1xuICAgIHJldHVybiB0aGlzLl9hdXRoVGFnXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG4gIH1cbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuc2V0QXV0aFRhZyA9IGZ1bmN0aW9uIHNldEF1dGhUYWcgKHRhZykge1xuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIHRoaXMuX2F1dGhUYWcgPSB0YWdcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0F0dGVtcHRpbmcgdG8gc2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbiAgfVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiBzZXRBQUQgKGJ1Zikge1xuICBpZiAoIXRoaXMuX2NhbGxlZCkge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShidWYpXG4gICAgdGhpcy5fYWxlbiArPSBidWYubGVuZ3RoXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIHNldCBBQUQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxuICB9XG59XG5mdW5jdGlvbiB4b3JUZXN0IChhLCBiKSB7XG4gIHZhciBvdXQgPSAwXG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICBvdXQrK1xuICB9XG4gIHZhciBsZW4gPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dCArPSAoYVtpXSBeIGJbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgbW9kZXMgPSByZXF1aXJlKCcuL21vZGVzJylcbnZhciBTdHJlYW1DaXBoZXIgPSByZXF1aXJlKCcuL3N0cmVhbUNpcGhlcicpXG52YXIgQXV0aENpcGhlciA9IHJlcXVpcmUoJy4vYXV0aENpcGhlcicpXG52YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcblxuaW5oZXJpdHMoRGVjaXBoZXIsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIERlY2lwaGVyIChtb2RlLCBrZXksIGl2KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEZWNpcGhlcikpIHtcbiAgICByZXR1cm4gbmV3IERlY2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2FjaGUgPSBuZXcgU3BsaXR0ZXIoKVxuICB0aGlzLl9sYXN0ID0gdm9pZCAwXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IG5ldyBCdWZmZXIoaXYubGVuZ3RoKVxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gdHJ1ZVxufVxuRGVjaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLl9jYWNoZS5hZGQoZGF0YSlcbiAgdmFyIGNodW5rXG4gIHZhciB0aGluZ1xuICB2YXIgb3V0ID0gW11cbiAgd2hpbGUgKChjaHVuayA9IHRoaXMuX2NhY2hlLmdldCh0aGlzLl9hdXRvcGFkZGluZykpKSB7XG4gICAgdGhpbmcgPSB0aGlzLl9tb2RlLmRlY3J5cHQodGhpcywgY2h1bmspXG4gICAgb3V0LnB1c2godGhpbmcpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQob3V0KVxufVxuRGVjaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNodW5rID0gdGhpcy5fY2FjaGUuZmx1c2goKVxuICBpZiAodGhpcy5fYXV0b3BhZGRpbmcpIHtcbiAgICByZXR1cm4gdW5wYWQodGhpcy5fbW9kZS5kZWNyeXB0KHRoaXMsIGNodW5rKSlcbiAgfSBlbHNlIGlmIChjaHVuaykge1xuICAgIHRocm93IG5ldyBFcnJvcignZGF0YSBub3QgbXVsdGlwbGUgb2YgYmxvY2sgbGVuZ3RoJylcbiAgfVxufVxuRGVjaXBoZXIucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKHNldFRvKSB7XG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gISFzZXRUb1xuICByZXR1cm4gdGhpc1xufVxuZnVuY3Rpb24gU3BsaXR0ZXIgKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3BsaXR0ZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTcGxpdHRlcigpXG4gIH1cbiAgdGhpcy5jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG59XG5TcGxpdHRlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGRhdGFdKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGF1dG9QYWRkaW5nKSB7XG4gIHZhciBvdXRcbiAgaWYgKGF1dG9QYWRkaW5nKSB7XG4gICAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID4gMTYpIHtcbiAgICAgIG91dCA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICAgIHJldHVybiBvdXRcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID49IDE2KSB7XG4gICAgICBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgICByZXR1cm4gb3V0XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsXG59XG5TcGxpdHRlci5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNhY2hlLmxlbmd0aCkge1xuICAgIHJldHVybiB0aGlzLmNhY2hlXG4gIH1cbn1cbmZ1bmN0aW9uIHVucGFkIChsYXN0KSB7XG4gIHZhciBwYWRkZWQgPSBsYXN0WzE1XVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBwYWRkZWQpIHtcbiAgICBpZiAobGFzdFsoaSArICgxNiAtIHBhZGRlZCkpXSAhPT0gcGFkZGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VuYWJsZSB0byBkZWNyeXB0IGRhdGEnKVxuICAgIH1cbiAgfVxuICBpZiAocGFkZGVkID09PSAxNikge1xuICAgIHJldHVyblxuICB9XG4gIHJldHVybiBsYXN0LnNsaWNlKDAsIDE2IC0gcGFkZGVkKVxufVxuXG52YXIgbW9kZWxpc3QgPSB7XG4gIEVDQjogcmVxdWlyZSgnLi9tb2Rlcy9lY2InKSxcbiAgQ0JDOiByZXF1aXJlKCcuL21vZGVzL2NiYycpLFxuICBDRkI6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiJyksXG4gIENGQjg6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiOCcpLFxuICBDRkIxOiByZXF1aXJlKCcuL21vZGVzL2NmYjEnKSxcbiAgT0ZCOiByZXF1aXJlKCcuL21vZGVzL29mYicpLFxuICBDVFI6IHJlcXVpcmUoJy4vbW9kZXMvY3RyJyksXG4gIEdDTTogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlcml2IChzdWl0ZSwgcGFzc3dvcmQsIGl2KSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgaWYgKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHtcbiAgICBpdiA9IG5ldyBCdWZmZXIoaXYpXG4gIH1cbiAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXNzd29yZCA9IG5ldyBCdWZmZXIocGFzc3dvcmQpXG4gIH1cbiAgaWYgKHBhc3N3b3JkLmxlbmd0aCAhPT0gY29uZmlnLmtleSAvIDgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGtleSBsZW5ndGggJyArIHBhc3N3b3JkLmxlbmd0aClcbiAgfVxuICBpZiAoaXYubGVuZ3RoICE9PSBjb25maWcuaXYpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGl2IGxlbmd0aCAnICsgaXYubGVuZ3RoKVxuICB9XG4gIGlmIChjb25maWcudHlwZSA9PT0gJ3N0cmVhbScpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdiwgdHJ1ZSlcbiAgfSBlbHNlIGlmIChjb25maWcudHlwZSA9PT0gJ2F1dGgnKSB7XG4gICAgcmV0dXJuIG5ldyBBdXRoQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2LCB0cnVlKVxuICB9XG4gIHJldHVybiBuZXcgRGVjaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZURlY2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgdmFyIGNvbmZpZyA9IG1vZGVzW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuICB2YXIga2V5cyA9IGVidGsocGFzc3dvcmQsIGZhbHNlLCBjb25maWcua2V5LCBjb25maWcuaXYpXG4gIHJldHVybiBjcmVhdGVEZWNpcGhlcml2KHN1aXRlLCBrZXlzLmtleSwga2V5cy5pdilcbn1cbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXIgPSBjcmVhdGVEZWNpcGhlclxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlcml2ID0gY3JlYXRlRGVjaXBoZXJpdlxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgbW9kZXMgPSByZXF1aXJlKCcuL21vZGVzJylcbnZhciBlYnRrID0gcmVxdWlyZSgnZXZwX2J5dGVzdG9rZXknKVxudmFyIFN0cmVhbUNpcGhlciA9IHJlcXVpcmUoJy4vc3RyZWFtQ2lwaGVyJylcbnZhciBBdXRoQ2lwaGVyID0gcmVxdWlyZSgnLi9hdXRoQ2lwaGVyJylcbmluaGVyaXRzKENpcGhlciwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyIChtb2RlLCBrZXksIGl2KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBDaXBoZXIobW9kZSwga2V5LCBpdilcbiAgfVxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLl9jYWNoZSA9IG5ldyBTcGxpdHRlcigpXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IG5ldyBCdWZmZXIoaXYubGVuZ3RoKVxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gdHJ1ZVxufVxuQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5fY2FjaGUuYWRkKGRhdGEpXG4gIHZhciBjaHVua1xuICB2YXIgdGhpbmdcbiAgdmFyIG91dCA9IFtdXG4gIHdoaWxlICgoY2h1bmsgPSB0aGlzLl9jYWNoZS5nZXQoKSkpIHtcbiAgICB0aGluZyA9IHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaylcbiAgICBvdXQucHVzaCh0aGluZylcbiAgfVxuICByZXR1cm4gQnVmZmVyLmNvbmNhdChvdXQpXG59XG5DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNodW5rID0gdGhpcy5fY2FjaGUuZmx1c2goKVxuICBpZiAodGhpcy5fYXV0b3BhZGRpbmcpIHtcbiAgICBjaHVuayA9IHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaylcbiAgICB0aGlzLl9jaXBoZXIuc2NydWIoKVxuICAgIHJldHVybiBjaHVua1xuICB9IGVsc2UgaWYgKGNodW5rLnRvU3RyaW5nKCdoZXgnKSAhPT0gJzEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwJykge1xuICAgIHRoaXMuX2NpcGhlci5zY3J1YigpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhIG5vdCBtdWx0aXBsZSBvZiBibG9jayBsZW5ndGgnKVxuICB9XG59XG5DaXBoZXIucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKHNldFRvKSB7XG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gISFzZXRUb1xuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBTcGxpdHRlciAoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTcGxpdHRlcikpIHtcbiAgICByZXR1cm4gbmV3IFNwbGl0dGVyKClcbiAgfVxuICB0aGlzLmNhY2hlID0gbmV3IEJ1ZmZlcignJylcbn1cblNwbGl0dGVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLmNhY2hlID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgZGF0YV0pXG59XG5cblNwbGl0dGVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+IDE1KSB7XG4gICAgdmFyIG91dCA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgcmV0dXJuIG91dFxuICB9XG4gIHJldHVybiBudWxsXG59XG5TcGxpdHRlci5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBsZW4gPSAxNiAtIHRoaXMuY2FjaGUubGVuZ3RoXG4gIHZhciBwYWRCdWZmID0gbmV3IEJ1ZmZlcihsZW4pXG5cbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgcGFkQnVmZi53cml0ZVVJbnQ4KGxlbiwgaSlcbiAgfVxuICB2YXIgb3V0ID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgcGFkQnVmZl0pXG4gIHJldHVybiBvdXRcbn1cbnZhciBtb2RlbGlzdCA9IHtcbiAgRUNCOiByZXF1aXJlKCcuL21vZGVzL2VjYicpLFxuICBDQkM6IHJlcXVpcmUoJy4vbW9kZXMvY2JjJyksXG4gIENGQjogcmVxdWlyZSgnLi9tb2Rlcy9jZmInKSxcbiAgQ0ZCODogcmVxdWlyZSgnLi9tb2Rlcy9jZmI4JyksXG4gIENGQjE6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiMScpLFxuICBPRkI6IHJlcXVpcmUoJy4vbW9kZXMvb2ZiJyksXG4gIENUUjogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKSxcbiAgR0NNOiByZXF1aXJlKCcuL21vZGVzL2N0cicpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNpcGhlcml2IChzdWl0ZSwgcGFzc3dvcmQsIGl2KSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgaWYgKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHtcbiAgICBpdiA9IG5ldyBCdWZmZXIoaXYpXG4gIH1cbiAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXNzd29yZCA9IG5ldyBCdWZmZXIocGFzc3dvcmQpXG4gIH1cbiAgaWYgKHBhc3N3b3JkLmxlbmd0aCAhPT0gY29uZmlnLmtleSAvIDgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGtleSBsZW5ndGggJyArIHBhc3N3b3JkLmxlbmd0aClcbiAgfVxuICBpZiAoaXYubGVuZ3RoICE9PSBjb25maWcuaXYpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGl2IGxlbmd0aCAnICsgaXYubGVuZ3RoKVxuICB9XG4gIGlmIChjb25maWcudHlwZSA9PT0gJ3N0cmVhbScpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbiAgfSBlbHNlIGlmIChjb25maWcudHlwZSA9PT0gJ2F1dGgnKSB7XG4gICAgcmV0dXJuIG5ldyBBdXRoQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxuICB9XG4gIHJldHVybiBuZXcgQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxufVxuZnVuY3Rpb24gY3JlYXRlQ2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgdmFyIGNvbmZpZyA9IG1vZGVzW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuICB2YXIga2V5cyA9IGVidGsocGFzc3dvcmQsIGZhbHNlLCBjb25maWcua2V5LCBjb25maWcuaXYpXG4gIHJldHVybiBjcmVhdGVDaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5cbmV4cG9ydHMuY3JlYXRlQ2lwaGVyaXYgPSBjcmVhdGVDaXBoZXJpdlxuZXhwb3J0cy5jcmVhdGVDaXBoZXIgPSBjcmVhdGVDaXBoZXJcbiIsInZhciB6ZXJvcyA9IG5ldyBCdWZmZXIoMTYpXG56ZXJvcy5maWxsKDApXG5tb2R1bGUuZXhwb3J0cyA9IEdIQVNIXG5mdW5jdGlvbiBHSEFTSCAoa2V5KSB7XG4gIHRoaXMuaCA9IGtleVxuICB0aGlzLnN0YXRlID0gbmV3IEJ1ZmZlcigxNilcbiAgdGhpcy5zdGF0ZS5maWxsKDApXG4gIHRoaXMuY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxufVxuLy8gZnJvbSBodHRwOi8vYml0d2lzZXNoaWZ0bGVmdC5naXRodWIuaW8vc2pjbC9kb2Mvc3ltYm9scy9zcmMvY29yZV9nY20uanMuaHRtbFxuLy8gYnkgSnVobyBWw6Row6QtSGVydHR1YVxuR0hBU0gucHJvdG90eXBlLmdoYXNoID0gZnVuY3Rpb24gKGJsb2NrKSB7XG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGJsb2NrLmxlbmd0aCkge1xuICAgIHRoaXMuc3RhdGVbaV0gXj0gYmxvY2tbaV1cbiAgfVxuICB0aGlzLl9tdWx0aXBseSgpXG59XG5cbkdIQVNILnByb3RvdHlwZS5fbXVsdGlwbHkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBWaSA9IHRvQXJyYXkodGhpcy5oKVxuICB2YXIgWmkgPSBbMCwgMCwgMCwgMF1cbiAgdmFyIGosIHhpLCBsc2JfVmlcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgMTI4KSB7XG4gICAgeGkgPSAodGhpcy5zdGF0ZVt+fihpIC8gOCldICYgKDEgPDwgKDcgLSBpICUgOCkpKSAhPT0gMFxuICAgIGlmICh4aSkge1xuICAgICAgLy8gWl9pKzEgPSBaX2kgXiBWX2lcbiAgICAgIFppID0geG9yKFppLCBWaSlcbiAgICB9XG5cbiAgICAvLyBTdG9yZSB0aGUgdmFsdWUgb2YgTFNCKFZfaSlcbiAgICBsc2JfVmkgPSAoVmlbM10gJiAxKSAhPT0gMFxuXG4gICAgLy8gVl9pKzEgPSBWX2kgPj4gMVxuICAgIGZvciAoaiA9IDM7IGogPiAwOyBqLS0pIHtcbiAgICAgIFZpW2pdID0gKFZpW2pdID4+PiAxKSB8ICgoVmlbaiAtIDFdICYgMSkgPDwgMzEpXG4gICAgfVxuICAgIFZpWzBdID0gVmlbMF0gPj4+IDFcblxuICAgIC8vIElmIExTQihWX2kpIGlzIDEsIFZfaSsxID0gKFZfaSA+PiAxKSBeIFJcbiAgICBpZiAobHNiX1ZpKSB7XG4gICAgICBWaVswXSA9IFZpWzBdIF4gKDB4ZTEgPDwgMjQpXG4gICAgfVxuICB9XG4gIHRoaXMuc3RhdGUgPSBmcm9tQXJyYXkoWmkpXG59XG5HSEFTSC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGJ1Zikge1xuICB0aGlzLmNhY2hlID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgYnVmXSlcbiAgdmFyIGNodW5rXG4gIHdoaWxlICh0aGlzLmNhY2hlLmxlbmd0aCA+PSAxNikge1xuICAgIGNodW5rID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICB0aGlzLmdoYXNoKGNodW5rKVxuICB9XG59XG5HSEFTSC5wcm90b3R5cGUuZmluYWwgPSBmdW5jdGlvbiAoYWJsLCBibCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGgpIHtcbiAgICB0aGlzLmdoYXNoKEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIHplcm9zXSwgMTYpKVxuICB9XG4gIHRoaXMuZ2hhc2goZnJvbUFycmF5KFtcbiAgICAwLCBhYmwsXG4gICAgMCwgYmxcbiAgXSkpXG4gIHJldHVybiB0aGlzLnN0YXRlXG59XG5cbmZ1bmN0aW9uIHRvQXJyYXkgKGJ1Zikge1xuICByZXR1cm4gW1xuICAgIGJ1Zi5yZWFkVUludDMyQkUoMCksXG4gICAgYnVmLnJlYWRVSW50MzJCRSg0KSxcbiAgICBidWYucmVhZFVJbnQzMkJFKDgpLFxuICAgIGJ1Zi5yZWFkVUludDMyQkUoMTIpXG4gIF1cbn1cbmZ1bmN0aW9uIGZyb21BcnJheSAob3V0KSB7XG4gIG91dCA9IG91dC5tYXAoZml4dXBfdWludDMyKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxudmFyIHVpbnRfbWF4ID0gTWF0aC5wb3coMiwgMzIpXG5mdW5jdGlvbiBmaXh1cF91aW50MzIgKHgpIHtcbiAgdmFyIHJldCwgeF9wb3NcbiAgcmV0ID0geCA+IHVpbnRfbWF4IHx8IHggPCAwID8gKHhfcG9zID0gTWF0aC5hYnMoeCkgJSB1aW50X21heCwgeCA8IDAgPyB1aW50X21heCAtIHhfcG9zIDogeF9wb3MpIDogeFxuICByZXR1cm4gcmV0XG59XG5mdW5jdGlvbiB4b3IgKGEsIGIpIHtcbiAgcmV0dXJuIFtcbiAgICBhWzBdIF4gYlswXSxcbiAgICBhWzFdIF4gYlsxXSxcbiAgICBhWzJdIF4gYlsyXSxcbiAgICBhWzNdIF4gYlszXVxuICBdXG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBkYXRhLCBkZWNyeXB0KSB7XG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKCcnKVxuICB2YXIgbGVuXG5cbiAgd2hpbGUgKGRhdGEubGVuZ3RoKSB7XG4gICAgaWYgKHNlbGYuX2NhY2hlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgICBzZWxmLl9wcmV2ID0gbmV3IEJ1ZmZlcignJylcbiAgICB9XG5cbiAgICBpZiAoc2VsZi5fY2FjaGUubGVuZ3RoIDw9IGRhdGEubGVuZ3RoKSB7XG4gICAgICBsZW4gPSBzZWxmLl9jYWNoZS5sZW5ndGhcbiAgICAgIG91dCA9IEJ1ZmZlci5jb25jYXQoW291dCwgZW5jcnlwdFN0YXJ0KHNlbGYsIGRhdGEuc2xpY2UoMCwgbGVuKSwgZGVjcnlwdCldKVxuICAgICAgZGF0YSA9IGRhdGEuc2xpY2UobGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFtvdXQsIGVuY3J5cHRTdGFydChzZWxmLCBkYXRhLCBkZWNyeXB0KV0pXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIGVuY3J5cHRTdGFydCAoc2VsZiwgZGF0YSwgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gZGF0YS5sZW5ndGhcbiAgdmFyIG91dCA9IHhvcihkYXRhLCBzZWxmLl9jYWNoZSlcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShsZW4pXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LCBkZWNyeXB0ID8gZGF0YSA6IG91dF0pXG4gIHJldHVybiBvdXRcbn1cbiIsImZ1bmN0aW9uIGVuY3J5cHRCeXRlIChzZWxmLCBieXRlUGFyYW0sIGRlY3J5cHQpIHtcbiAgdmFyIHBhZFxuICB2YXIgaSA9IC0xXG4gIHZhciBsZW4gPSA4XG4gIHZhciBvdXQgPSAwXG4gIHZhciBiaXQsIHZhbHVlXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBwYWQgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgYml0ID0gKGJ5dGVQYXJhbSAmICgxIDw8ICg3IC0gaSkpKSA/IDB4ODAgOiAwXG4gICAgdmFsdWUgPSBwYWRbMF0gXiBiaXRcbiAgICBvdXQgKz0gKCh2YWx1ZSAmIDB4ODApID4+IChpICUgOCkpXG4gICAgc2VsZi5fcHJldiA9IHNoaWZ0SW4oc2VsZi5fcHJldiwgZGVjcnlwdCA/IGJpdCA6IHZhbHVlKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaywgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gY2h1bmsubGVuZ3RoXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGxlbilcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gZW5jcnlwdEJ5dGUoc2VsZiwgY2h1bmtbaV0sIGRlY3J5cHQpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuZnVuY3Rpb24gc2hpZnRJbiAoYnVmZmVyLCB2YWx1ZSkge1xuICB2YXIgbGVuID0gYnVmZmVyLmxlbmd0aFxuICB2YXIgaSA9IC0xXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGJ1ZmZlci5sZW5ndGgpXG4gIGJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW2J1ZmZlciwgbmV3IEJ1ZmZlcihbdmFsdWVdKV0pXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWZmZXJbaV0gPDwgMSB8IGJ1ZmZlcltpICsgMV0gPj4gKDcpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwiZnVuY3Rpb24gZW5jcnlwdEJ5dGUgKHNlbGYsIGJ5dGVQYXJhbSwgZGVjcnlwdCkge1xuICB2YXIgcGFkID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICB2YXIgb3V0ID0gcGFkWzBdIF4gYnl0ZVBhcmFtXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LnNsaWNlKDEpLCBuZXcgQnVmZmVyKFtkZWNyeXB0ID8gYnl0ZVBhcmFtIDogb3V0XSldKVxuICByZXR1cm4gb3V0XG59XG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgY2h1bmssIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGNodW5rLmxlbmd0aFxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihsZW4pXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGVuY3J5cHRCeXRlKHNlbGYsIGNodW5rW2ldLCBkZWNyeXB0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gaW5jcjMyIChpdikge1xuICB2YXIgbGVuID0gaXYubGVuZ3RoXG4gIHZhciBpdGVtXG4gIHdoaWxlIChsZW4tLSkge1xuICAgIGl0ZW0gPSBpdi5yZWFkVUludDgobGVuKVxuICAgIGlmIChpdGVtID09PSAyNTUpIHtcbiAgICAgIGl2LndyaXRlVUludDgoMCwgbGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBpdGVtKytcbiAgICAgIGl2LndyaXRlVUludDgoaXRlbSwgbGVuKVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgdmFyIG91dCA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgaW5jcjMyKHNlbGYuX3ByZXYpXG4gIHJldHVybiBvdXRcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cbiAgdmFyIHBhZCA9IHNlbGYuX2NhY2hlLnNsaWNlKDAsIGNodW5rLmxlbmd0aClcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShjaHVuay5sZW5ndGgpXG4gIHJldHVybiB4b3IoY2h1bmssIHBhZClcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgc2VsZi5fcHJldiA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgcmV0dXJuIHNlbGYuX3ByZXZcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cblxuICB2YXIgcGFkID0gc2VsZi5fY2FjaGUuc2xpY2UoMCwgY2h1bmsubGVuZ3RoKVxuICBzZWxmLl9jYWNoZSA9IHNlbGYuX2NhY2hlLnNsaWNlKGNodW5rLmxlbmd0aClcbiAgcmV0dXJuIHhvcihjaHVuaywgcGFkKVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB4b3IgKGEsIGIpIHtcbiAgdmFyIGxlbmd0aCA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aClcbiAgdmFyIGJ1ZmZlciA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBidWZmZXJbaV0gPSBhW2ldIF4gYltpXVxuICB9XG5cbiAgcmV0dXJuIGJ1ZmZlclxufVxuIiwidmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyQmFzZVxuaW5oZXJpdHMoQ2lwaGVyQmFzZSwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyQmFzZSAoaGFzaE1vZGUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5oYXNoTW9kZSA9IHR5cGVvZiBoYXNoTW9kZSA9PT0gJ3N0cmluZydcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICB0aGlzW2hhc2hNb2RlXSA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZpbmFsID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9XG4gIHRoaXMuX2RlY29kZXIgPSBudWxsXG4gIHRoaXMuX2VuY29kaW5nID0gbnVsbFxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGlucHV0RW5jKVxuICB9XG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYylcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uICgpIHt9XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGFhZCBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1c2godGhpcy5fdXBkYXRlKGRhdGEpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBuZXh0KGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGRvbmUpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIGRvbmUoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9maW5hbCgpIHx8IG5ldyBCdWZmZXIoJycpXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jLCB0cnVlKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90b1N0cmluZyA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jLCBmaW5hbCkge1xuICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKVxuICAgIHRoaXMuX2VuY29kaW5nID0gZW5jXG4gIH1cbiAgaWYgKHRoaXMuX2VuY29kaW5nICE9PSBlbmMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhblxcJ3Qgc3dpdGNoIGVuY29kaW5ncycpXG4gIH1cbiAgdmFyIG91dCA9IHRoaXMuX2RlY29kZXIud3JpdGUodmFsdWUpXG4gIGlmIChmaW5hbCkge1xuICAgIG91dCArPSB0aGlzLl9kZWNvZGVyLmVuZCgpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcbmZ1bmN0aW9uIFN0cmVhbUNpcGhlciAobW9kZSwga2V5LCBpdiwgZGVjcnlwdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3RyZWFtQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gbmV3IEJ1ZmZlcihpdi5sZW5ndGgpXG4gIHRoaXMuX2NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fc2VjQ2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9kZWNyeXB0ID0gZGVjcnlwdFxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgcmV0dXJuIHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaywgdGhpcy5fZGVjcnlwdClcbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9jaXBoZXIuc2NydWIoKVxufVxuIiwidmFyIG1kNSA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoL21kNScpXG5tb2R1bGUuZXhwb3J0cyA9IEVWUF9CeXRlc1RvS2V5XG5mdW5jdGlvbiBFVlBfQnl0ZXNUb0tleSAocGFzc3dvcmQsIHNhbHQsIGtleUxlbiwgaXZMZW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocGFzc3dvcmQpKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkLCAnYmluYXJ5JylcbiAgfVxuICBpZiAoc2FsdCAmJiAhQnVmZmVyLmlzQnVmZmVyKHNhbHQpKSB7XG4gICAgc2FsdCA9IG5ldyBCdWZmZXIoc2FsdCwgJ2JpbmFyeScpXG4gIH1cbiAga2V5TGVuID0ga2V5TGVuIC8gOFxuICBpdkxlbiA9IGl2TGVuIHx8IDBcbiAgdmFyIGtpID0gMFxuICB2YXIgaWkgPSAwXG4gIHZhciBrZXkgPSBuZXcgQnVmZmVyKGtleUxlbilcbiAgdmFyIGl2ID0gbmV3IEJ1ZmZlcihpdkxlbilcbiAgdmFyIGFkZG1kID0gMFxuICB2YXIgbWRfYnVmXG4gIHZhciBpXG4gIHZhciBidWZzID0gW11cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoYWRkbWQrKyA+IDApIHtcbiAgICAgIGJ1ZnMucHVzaChtZF9idWYpXG4gICAgfVxuICAgIGJ1ZnMucHVzaChwYXNzd29yZClcbiAgICBpZiAoc2FsdCkge1xuICAgICAgYnVmcy5wdXNoKHNhbHQpXG4gICAgfVxuICAgIG1kX2J1ZiA9IG1kNShCdWZmZXIuY29uY2F0KGJ1ZnMpKVxuICAgIGJ1ZnMgPSBbXVxuICAgIGkgPSAwXG4gICAgaWYgKGtleUxlbiA+IDApIHtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGlmIChrZXlMZW4gPT09IDApIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGlmIChpID09PSBtZF9idWYubGVuZ3RoKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBrZXlba2krK10gPSBtZF9idWZbaV1cbiAgICAgICAga2V5TGVuLS1cbiAgICAgICAgaSsrXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpdkxlbiA+IDAgJiYgaSAhPT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaWYgKGl2TGVuID09PSAwKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaXZbaWkrK10gPSBtZF9idWZbaV1cbiAgICAgICAgaXZMZW4tLVxuICAgICAgICBpKytcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGtleUxlbiA9PT0gMCAmJiBpdkxlbiA9PT0gMCkge1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMDsgaSA8IG1kX2J1Zi5sZW5ndGg7IGkrKykge1xuICAgIG1kX2J1ZltpXSA9IDBcbiAgfVxuICByZXR1cm4ge1xuICAgIGtleToga2V5LFxuICAgIGl2OiBpdlxuICB9XG59XG4iLCJ2YXIgcGFyc2VLZXlzID0gcmVxdWlyZSgncGFyc2UtYXNuMScpO1xudmFyIG1nZiA9IHJlcXVpcmUoJy4vbWdmJyk7XG52YXIgeG9yID0gcmVxdWlyZSgnLi94b3InKTtcbnZhciBibiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgY3J0ID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1yc2EnKTtcbnZhciBjcmVhdGVIYXNoID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gnKTtcbnZhciB3aXRoUHVibGljID0gcmVxdWlyZSgnLi93aXRoUHVibGljJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHByaXZhdGVEZWNyeXB0KHByaXZhdGVfa2V5LCBlbmMsIHJldmVyc2UpIHtcbiAgdmFyIHBhZGRpbmc7XG4gIGlmIChwcml2YXRlX2tleS5wYWRkaW5nKSB7XG4gICAgcGFkZGluZyA9IHByaXZhdGVfa2V5LnBhZGRpbmc7XG4gIH0gZWxzZSBpZiAocmV2ZXJzZSkge1xuICAgIHBhZGRpbmcgPSAxO1xuICB9IGVsc2Uge1xuICAgIHBhZGRpbmcgPSA0O1xuICB9XG4gIFxuICB2YXIga2V5ID0gcGFyc2VLZXlzKHByaXZhdGVfa2V5KTtcbiAgdmFyIGsgPSBrZXkubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIGlmIChlbmMubGVuZ3RoID4gayB8fCBuZXcgYm4oZW5jKS5jbXAoa2V5Lm1vZHVsdXMpID49IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlY3J5cHRpb24gZXJyb3InKTtcbiAgfVxuICB2YXIgbXNnO1xuICBpZiAocmV2ZXJzZSkge1xuICAgIG1zZyA9IHdpdGhQdWJsaWMobmV3IGJuKGVuYyksIGtleSk7XG4gIH0gZWxzZSB7XG4gICAgbXNnID0gY3J0KGVuYywga2V5KTtcbiAgfVxuICB2YXIgekJ1ZmZlciA9IG5ldyBCdWZmZXIoayAtIG1zZy5sZW5ndGgpO1xuICB6QnVmZmVyLmZpbGwoMCk7XG4gIG1zZyA9IEJ1ZmZlci5jb25jYXQoW3pCdWZmZXIsIG1zZ10sIGspO1xuICBpZiAocGFkZGluZyA9PT0gNCkge1xuICAgIHJldHVybiBvYWVwKGtleSwgbXNnKTtcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09PSAxKSB7XG4gICAgcmV0dXJuIHBrY3MxKGtleSwgbXNnLCByZXZlcnNlKTtcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09PSAzKSB7XG4gICAgcmV0dXJuIG1zZztcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gcGFkZGluZycpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBvYWVwKGtleSwgbXNnKXtcbiAgdmFyIG4gPSBrZXkubW9kdWx1cztcbiAgdmFyIGsgPSBrZXkubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIHZhciBtTGVuID0gbXNnLmxlbmd0aDtcbiAgdmFyIGlIYXNoID0gY3JlYXRlSGFzaCgnc2hhMScpLnVwZGF0ZShuZXcgQnVmZmVyKCcnKSkuZGlnZXN0KCk7XG4gIHZhciBoTGVuID0gaUhhc2gubGVuZ3RoO1xuICB2YXIgaExlbjIgPSAyICogaExlbjtcbiAgaWYgKG1zZ1swXSAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGVjcnlwdGlvbiBlcnJvcicpO1xuICB9XG4gIHZhciBtYXNrZWRTZWVkID0gbXNnLnNsaWNlKDEsIGhMZW4gKyAxKTtcbiAgdmFyIG1hc2tlZERiID0gIG1zZy5zbGljZShoTGVuICsgMSk7XG4gIHZhciBzZWVkID0geG9yKG1hc2tlZFNlZWQsIG1nZihtYXNrZWREYiwgaExlbikpO1xuICB2YXIgZGIgPSB4b3IobWFza2VkRGIsIG1nZihzZWVkLCBrIC0gaExlbiAtIDEpKTtcbiAgaWYgKGNvbXBhcmUoaUhhc2gsIGRiLnNsaWNlKDAsIGhMZW4pKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGVjcnlwdGlvbiBlcnJvcicpO1xuICB9XG4gIHZhciBpID0gaExlbjtcbiAgd2hpbGUgKGRiW2ldID09PSAwKSB7XG4gICAgaSsrO1xuICB9XG4gIGlmIChkYltpKytdICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkZWNyeXB0aW9uIGVycm9yJyk7XG4gIH1cbiAgcmV0dXJuIGRiLnNsaWNlKGkpO1xufVxuXG5mdW5jdGlvbiBwa2NzMShrZXksIG1zZywgcmV2ZXJzZSl7XG4gIHZhciBwMSA9IG1zZy5zbGljZSgwLCAyKTtcbiAgdmFyIGkgPSAyO1xuICB2YXIgc3RhdHVzID0gMDtcbiAgd2hpbGUgKG1zZ1tpKytdICE9PSAwKSB7XG4gICAgaWYgKGkgPj0gbXNnLmxlbmd0aCkge1xuICAgICAgc3RhdHVzKys7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgdmFyIHBzID0gbXNnLnNsaWNlKDIsIGkgLSAxKTtcbiAgdmFyIHAyID0gbXNnLnNsaWNlKGkgLSAxLCBpKTtcblxuICBpZiAoKHAxLnRvU3RyaW5nKCdoZXgnKSAhPT0gJzAwMDInICYmICFyZXZlcnNlKSB8fCAocDEudG9TdHJpbmcoJ2hleCcpICE9PSAnMDAwMScgJiYgcmV2ZXJzZSkpe1xuICAgIHN0YXR1cysrO1xuICB9XG4gIGlmIChwcy5sZW5ndGggPCA4KSB7XG4gICAgc3RhdHVzKys7XG4gIH1cbiAgaWYgKHN0YXR1cykge1xuICAgIHRocm93IG5ldyBFcnJvcignZGVjcnlwdGlvbiBlcnJvcicpO1xuICB9XG4gIHJldHVybiAgbXNnLnNsaWNlKGkpO1xufVxuZnVuY3Rpb24gY29tcGFyZShhLCBiKXtcbiAgYSA9IG5ldyBCdWZmZXIoYSk7XG4gIGIgPSBuZXcgQnVmZmVyKGIpO1xuICB2YXIgZGlmID0gMDtcbiAgdmFyIGxlbiA9IGEubGVuZ3RoO1xuICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgZGlmKys7XG4gICAgbGVuID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKTtcbiAgfVxuICB2YXIgaSA9IC0xO1xuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgZGlmICs9IChhW2ldIF4gYltpXSk7XG4gIH1cbiAgcmV0dXJuIGRpZjtcbn0iLCJ2YXIgcGFyc2VLZXlzID0gcmVxdWlyZSgncGFyc2UtYXNuMScpO1xudmFyIHJhbmRvbUJ5dGVzID0gcmVxdWlyZSgncmFuZG9tYnl0ZXMnKTtcbnZhciBjcmVhdGVIYXNoID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gnKTtcbnZhciBtZ2YgPSByZXF1aXJlKCcuL21nZicpO1xudmFyIHhvciA9IHJlcXVpcmUoJy4veG9yJyk7XG52YXIgYm4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIHdpdGhQdWJsaWMgPSByZXF1aXJlKCcuL3dpdGhQdWJsaWMnKTtcbnZhciBjcnQgPSByZXF1aXJlKCdicm93c2VyaWZ5LXJzYScpO1xuXG52YXIgY29uc3RhbnRzID0ge1xuICBSU0FfUEtDUzFfT0FFUF9QQURESU5HOiA0LFxuICBSU0FfUEtDUzFfUEFERElOOiAxLFxuICBSU0FfTk9fUEFERElORzogM1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwdWJsaWNFbmNyeXB0KHB1YmxpY19rZXksIG1zZywgcmV2ZXJzZSkge1xuICB2YXIgcGFkZGluZztcbiAgaWYgKHB1YmxpY19rZXkucGFkZGluZykge1xuICAgIHBhZGRpbmcgPSBwdWJsaWNfa2V5LnBhZGRpbmc7XG4gIH0gZWxzZSBpZiAocmV2ZXJzZSkge1xuICAgIHBhZGRpbmcgPSAxO1xuICB9IGVsc2Uge1xuICAgIHBhZGRpbmcgPSA0O1xuICB9XG4gIHZhciBrZXkgPSBwYXJzZUtleXMocHVibGljX2tleSk7XG4gIHZhciBwYWRkZWRNc2c7XG4gIGlmIChwYWRkaW5nID09PSA0KSB7XG4gICAgcGFkZGVkTXNnID0gb2FlcChrZXksIG1zZyk7XG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PT0gMSkge1xuICAgIHBhZGRlZE1zZyA9IHBrY3MxKGtleSwgbXNnLCByZXZlcnNlKTtcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09PSAzKSB7XG4gICAgcGFkZGVkTXNnID0gbmV3IGJuKG1zZyk7XG4gICAgaWYgKHBhZGRlZE1zZy5jbXAoa2V5Lm1vZHVsdXMpID49IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZGF0YSB0b28gbG9uZyBmb3IgbW9kdWx1cycpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gcGFkZGluZycpO1xuICB9XG4gIGlmIChyZXZlcnNlKSB7XG4gICAgcmV0dXJuIGNydChwYWRkZWRNc2csIGtleSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHdpdGhQdWJsaWMocGFkZGVkTXNnLCBrZXkpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBvYWVwKGtleSwgbXNnKXtcbiAgdmFyIGsgPSBrZXkubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIHZhciBtTGVuID0gbXNnLmxlbmd0aDtcbiAgdmFyIGlIYXNoID0gY3JlYXRlSGFzaCgnc2hhMScpLnVwZGF0ZShuZXcgQnVmZmVyKCcnKSkuZGlnZXN0KCk7XG4gIHZhciBoTGVuID0gaUhhc2gubGVuZ3RoO1xuICB2YXIgaExlbjIgPSAyICogaExlbjtcbiAgaWYgKG1MZW4gPiBrIC0gaExlbjIgLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtZXNzYWdlIHRvbyBsb25nJyk7XG4gIH1cbiAgdmFyIHBzID0gbmV3IEJ1ZmZlcihrIC0gbUxlbiAtIGhMZW4yIC0gMik7XG4gIHBzLmZpbGwoMCk7XG4gIHZhciBkYmxlbiA9IGsgLSBoTGVuIC0gMTtcbiAgdmFyIHNlZWQgPSByYW5kb21CeXRlcyhoTGVuKTtcbiAgdmFyIG1hc2tlZERiID0geG9yKEJ1ZmZlci5jb25jYXQoW2lIYXNoLCBwcywgbmV3IEJ1ZmZlcihbMV0pLCBtc2ddLCBkYmxlbiksIG1nZihzZWVkLCBkYmxlbikpO1xuICB2YXIgbWFza2VkU2VlZCA9IHhvcihzZWVkLCBtZ2YobWFza2VkRGIsIGhMZW4pKTtcbiAgcmV0dXJuIG5ldyBibihCdWZmZXIuY29uY2F0KFtuZXcgQnVmZmVyKFswXSksIG1hc2tlZFNlZWQsIG1hc2tlZERiXSwgaykpO1xufVxuZnVuY3Rpb24gcGtjczEoa2V5LCBtc2csIHJldmVyc2Upe1xuICB2YXIgbUxlbiA9IG1zZy5sZW5ndGg7XG4gIHZhciBrID0ga2V5Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpO1xuICBpZiAobUxlbiA+IGsgLSAxMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWVzc2FnZSB0b28gbG9uZycpO1xuICB9XG4gIHZhciBwcztcbiAgaWYgKHJldmVyc2UpIHtcbiAgICBwcyA9IG5ldyBCdWZmZXIoayAtIG1MZW4gLSAzKTtcbiAgICBwcy5maWxsKDB4ZmYpO1xuICB9IGVsc2Uge1xuICAgIHBzID0gbm9uWmVybyhrIC0gbUxlbiAtIDMpO1xuICB9XG4gIHJldHVybiBuZXcgYm4oQnVmZmVyLmNvbmNhdChbbmV3IEJ1ZmZlcihbMCwgcmV2ZXJzZT8xOjJdKSwgcHMsIG5ldyBCdWZmZXIoWzBdKSwgbXNnXSwgaykpO1xufVxuZnVuY3Rpb24gbm9uWmVybyhsZW4sIGNyeXB0bykge1xuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihsZW4pO1xuICB2YXIgaSA9IDA7XG4gIHZhciBjYWNoZSA9IHJhbmRvbUJ5dGVzKGxlbioyKTtcbiAgdmFyIGN1ciA9IDA7XG4gIHZhciBudW07XG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgaWYgKGN1ciA9PT0gY2FjaGUubGVuZ3RoKSB7XG4gICAgICBjYWNoZSA9IHJhbmRvbUJ5dGVzKGxlbioyKTtcbiAgICAgIGN1ciA9IDA7XG4gICAgfVxuICAgIG51bSA9IGNhY2hlW2N1cisrXTtcbiAgICBpZiAobnVtKSB7XG4gICAgICBvdXRbaSsrXSA9IG51bTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dDtcbn0iLCJ2YXIgYm4gPSByZXF1aXJlKCdibi5qcycpO1xuZnVuY3Rpb24gd2l0aFB1YmxpYyhwYWRkZWRNc2csIGtleSkge1xuICByZXR1cm4gbmV3IEJ1ZmZlcihwYWRkZWRNc2dcbiAgICAudG9SZWQoYm4ubW9udChrZXkubW9kdWx1cykpXG4gICAgLnJlZFBvdyhuZXcgYm4oa2V5LnB1YmxpY0V4cG9uZW50KSlcbiAgICAuZnJvbVJlZCgpXG4gICAgLnRvQXJyYXkoKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gd2l0aFB1YmxpYzsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHhvcihhLCBiKSB7XG4gIHZhciBsZW4gPSBhLmxlbmd0aDtcbiAgdmFyIGkgPSAtMTtcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIGFbaV0gXj0gYltpXTtcbiAgfVxuICByZXR1cm4gYVxufTsiLCIndXNlIHN0cmljdCdcblxuZnVuY3Rpb24gb2xkQnJvd3NlciAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignc2VjdXJlIHJhbmRvbSBudW1iZXIgZ2VuZXJhdGlvbiBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgYnJvd3NlclxcbnVzZSBjaHJvbWUsIEZpcmVGb3ggb3IgSW50ZXJuZXQgRXhwbG9yZXIgMTEnKVxufVxuXG52YXIgY3J5cHRvID0gZ2xvYmFsLmNyeXB0byB8fCBnbG9iYWwubXNDcnlwdG9cblxuaWYgKGNyeXB0byAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmFuZG9tQnl0ZXNcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gb2xkQnJvd3NlclxufVxuXG5mdW5jdGlvbiByYW5kb21CeXRlcyAoc2l6ZSwgY2IpIHtcbiAgLy8gcGhhbnRvbWpzIG5lZWRzIHRvIHRocm93XG4gIGlmIChzaXplID4gNjU1MzYpIHRocm93IG5ldyBFcnJvcigncmVxdWVzdGVkIHRvbyBtYW55IHJhbmRvbSBieXRlcycpXG4gIC8vIGluIGNhc2UgYnJvd3NlcmlmeSAgaXNuJ3QgdXNpbmcgdGhlIFVpbnQ4QXJyYXkgdmVyc2lvblxuICB2YXIgcmF3Qnl0ZXMgPSBuZXcgZ2xvYmFsLlVpbnQ4QXJyYXkoc2l6ZSlcblxuICAvLyBUaGlzIHdpbGwgbm90IHdvcmsgaW4gb2xkZXIgYnJvd3NlcnMuXG4gIC8vIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXNcbiAgaWYgKHNpemUgPiAwKSB7ICAvLyBnZXRSYW5kb21WYWx1ZXMgZmFpbHMgb24gSUUgaWYgc2l6ZSA9PSAwXG4gICAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhyYXdCeXRlcylcbiAgfVxuICAvLyBwaGFudG9tanMgZG9lc24ndCBsaWtlIGEgYnVmZmVyIGJlaW5nIHBhc3NlZCBoZXJlXG4gIHZhciBieXRlcyA9IG5ldyBCdWZmZXIocmF3Qnl0ZXMuYnVmZmVyKVxuXG4gIGlmICh0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICBjYihudWxsLCBieXRlcylcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICB0aGlzLl9ldmVudHMgPSB0aGlzLl9ldmVudHMgfHwge307XG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbkV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbi8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uKG4pIHtcbiAgaWYgKCFpc051bWJlcihuKSB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ24gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSBuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGVyLCBoYW5kbGVyLCBsZW4sIGFyZ3MsIGksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmICh0eXBlID09PSAnZXJyb3InKSB7XG4gICAgaWYgKCF0aGlzLl9ldmVudHMuZXJyb3IgfHxcbiAgICAgICAgKGlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikgJiYgIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpKSB7XG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgICAgfVxuICAgICAgdGhyb3cgVHlwZUVycm9yKCdVbmNhdWdodCwgdW5zcGVjaWZpZWQgXCJlcnJvclwiIGV2ZW50LicpO1xuICAgIH1cbiAgfVxuXG4gIGhhbmRsZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzVW5kZWZpbmVkKGhhbmRsZXIpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgLy8gZmFzdCBjYXNlc1xuICAgICAgY2FzZSAxOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoaGFuZGxlcikpIHtcbiAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICBsaXN0ZW5lcnMgPSBoYW5kbGVyLnNsaWNlKCk7XG4gICAgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lclwiLlxuICBpZiAodGhpcy5fZXZlbnRzLm5ld0xpc3RlbmVyKVxuICAgIHRoaXMuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICBpc0Z1bmN0aW9uKGxpc3RlbmVyLmxpc3RlbmVyKSA/XG4gICAgICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICBlbHNlIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gIGVsc2VcbiAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBbdGhpcy5fZXZlbnRzW3R5cGVdLCBsaXN0ZW5lcl07XG5cbiAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkgJiYgIXRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQpIHtcbiAgICBpZiAoIWlzVW5kZWZpbmVkKHRoaXMuX21heExpc3RlbmVycykpIHtcbiAgICAgIG0gPSB0aGlzLl9tYXhMaXN0ZW5lcnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgICB9XG5cbiAgICBpZiAobSAmJiBtID4gMCAmJiB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoID4gbSkge1xuICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCA9IHRydWU7XG4gICAgICBjb25zb2xlLmVycm9yKCcobm9kZSkgd2FybmluZzogcG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSAnICtcbiAgICAgICAgICAgICAgICAgICAgJ2xlYWsgZGV0ZWN0ZWQuICVkIGxpc3RlbmVycyBhZGRlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICdVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byBpbmNyZWFzZSBsaW1pdC4nLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoKTtcbiAgICAgIGlmICh0eXBlb2YgY29uc29sZS50cmFjZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBub3Qgc3VwcG9ydGVkIGluIElFIDEwXG4gICAgICAgIGNvbnNvbGUudHJhY2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgdmFyIGZpcmVkID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gZygpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGcpO1xuXG4gICAgaWYgKCFmaXJlZCkge1xuICAgICAgZmlyZWQgPSB0cnVlO1xuICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cblxuICBnLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHRoaXMub24odHlwZSwgZyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBlbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWZmIHRoZSBsaXN0ZW5lciB3YXMgcmVtb3ZlZFxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBsaXN0LCBwb3NpdGlvbiwgbGVuZ3RoLCBpO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIGxpc3QgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gIGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICBwb3NpdGlvbiA9IC0xO1xuXG4gIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fFxuICAgICAgKGlzRnVuY3Rpb24obGlzdC5saXN0ZW5lcikgJiYgbGlzdC5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcblxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGxpc3QpKSB7XG4gICAgZm9yIChpID0gbGVuZ3RoOyBpLS0gPiAwOykge1xuICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8XG4gICAgICAgICAgKGxpc3RbaV0ubGlzdGVuZXIgJiYgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgICBsaXN0Lmxlbmd0aCA9IDA7XG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaXN0LnNwbGljZShwb3NpdGlvbiwgMSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIga2V5LCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICBpZiAoIXRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxuICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgZWxzZSBpZiAodGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAoa2V5IGluIHRoaXMuX2V2ZW50cykge1xuICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgIH1cbiAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNGdW5jdGlvbihsaXN0ZW5lcnMpKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgIC8vIExJRk8gb3JkZXJcbiAgICB3aGlsZSAobGlzdGVuZXJzLmxlbmd0aClcbiAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXSk7XG4gIH1cbiAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgcmV0O1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldCA9IFtdO1xuICBlbHNlIGlmIChpc0Z1bmN0aW9uKHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgcmV0ID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG4gIGVsc2VcbiAgICByZXQgPSB0aGlzLl9ldmVudHNbdHlwZV0uc2xpY2UoKTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgaWYgKHRoaXMuX2V2ZW50cykge1xuICAgIHZhciBldmxpc3RlbmVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKGlzRnVuY3Rpb24oZXZsaXN0ZW5lcikpXG4gICAgICByZXR1cm4gMTtcbiAgICBlbHNlIGlmIChldmxpc3RlbmVyKVxuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICB9XG4gIHJldHVybiAwO1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG59O1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIi8qKlxuICogRGV0ZXJtaW5lIGlmIGFuIG9iamVjdCBpcyBCdWZmZXJcbiAqXG4gKiBBdXRob3I6ICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIExpY2Vuc2U6ICBNSVRcbiAqXG4gKiBgbnBtIGluc3RhbGwgaXMtYnVmZmVyYFxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaikge1xuICByZXR1cm4gISEob2JqICE9IG51bGwgJiZcbiAgICAob2JqLl9pc0J1ZmZlciB8fCAvLyBGb3IgU2FmYXJpIDUtNyAobWlzc2luZyBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yKVxuICAgICAgKG9iai5jb25zdHJ1Y3RvciAmJlxuICAgICAgdHlwZW9mIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyKG9iaikpXG4gICAgKSlcbn1cbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBzZXRUaW1lb3V0KGRyYWluUXVldWUsIDApO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIilcbiIsIi8vIGEgZHVwbGV4IHN0cmVhbSBpcyBqdXN0IGEgc3RyZWFtIHRoYXQgaXMgYm90aCByZWFkYWJsZSBhbmQgd3JpdGFibGUuXG4vLyBTaW5jZSBKUyBkb2Vzbid0IGhhdmUgbXVsdGlwbGUgcHJvdG90eXBhbCBpbmhlcml0YW5jZSwgdGhpcyBjbGFzc1xuLy8gcHJvdG90eXBhbGx5IGluaGVyaXRzIGZyb20gUmVhZGFibGUsIGFuZCB0aGVuIHBhcmFzaXRpY2FsbHkgZnJvbVxuLy8gV3JpdGFibGUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBrZXlzLnB1c2goa2V5KTtcbiAgfXJldHVybiBrZXlzO1xufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IER1cGxleDtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBwcm9jZXNzTmV4dFRpY2sgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIFJlYWRhYmxlID0gcmVxdWlyZSgnLi9fc3RyZWFtX3JlYWRhYmxlJyk7XG52YXIgV3JpdGFibGUgPSByZXF1aXJlKCcuL19zdHJlYW1fd3JpdGFibGUnKTtcblxudXRpbC5pbmhlcml0cyhEdXBsZXgsIFJlYWRhYmxlKTtcblxudmFyIGtleXMgPSBvYmplY3RLZXlzKFdyaXRhYmxlLnByb3RvdHlwZSk7XG5mb3IgKHZhciB2ID0gMDsgdiA8IGtleXMubGVuZ3RoOyB2KyspIHtcbiAgdmFyIG1ldGhvZCA9IGtleXNbdl07XG4gIGlmICghRHVwbGV4LnByb3RvdHlwZVttZXRob2RdKSBEdXBsZXgucHJvdG90eXBlW21ldGhvZF0gPSBXcml0YWJsZS5wcm90b3R5cGVbbWV0aG9kXTtcbn1cblxuZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuXG4gIFJlYWRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIFdyaXRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWFkYWJsZSA9PT0gZmFsc2UpIHRoaXMucmVhZGFibGUgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSkgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuXG4gIHRoaXMuYWxsb3dIYWxmT3BlbiA9IHRydWU7XG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYWxsb3dIYWxmT3BlbiA9PT0gZmFsc2UpIHRoaXMuYWxsb3dIYWxmT3BlbiA9IGZhbHNlO1xuXG4gIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xufVxuXG4vLyB0aGUgbm8taGFsZi1vcGVuIGVuZm9yY2VyXG5mdW5jdGlvbiBvbmVuZCgpIHtcbiAgLy8gaWYgd2UgYWxsb3cgaGFsZi1vcGVuIHN0YXRlLCBvciBpZiB0aGUgd3JpdGFibGUgc2lkZSBlbmRlZCxcbiAgLy8gdGhlbiB3ZSdyZSBvay5cbiAgaWYgKHRoaXMuYWxsb3dIYWxmT3BlbiB8fCB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKSByZXR1cm47XG5cbiAgLy8gbm8gbW9yZSBkYXRhIGNhbiBiZSB3cml0dGVuLlxuICAvLyBCdXQgYWxsb3cgbW9yZSB3cml0ZXMgdG8gaGFwcGVuIGluIHRoaXMgdGljay5cbiAgcHJvY2Vzc05leHRUaWNrKG9uRW5kTlQsIHRoaXMpO1xufVxuXG5mdW5jdGlvbiBvbkVuZE5UKHNlbGYpIHtcbiAgc2VsZi5lbmQoKTtcbn1cblxuZnVuY3Rpb24gZm9yRWFjaCh4cywgZikge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGYoeHNbaV0sIGkpO1xuICB9XG59IiwiLy8gYSBwYXNzdGhyb3VnaCBzdHJlYW0uXG4vLyBiYXNpY2FsbHkganVzdCB0aGUgbW9zdCBtaW5pbWFsIHNvcnQgb2YgVHJhbnNmb3JtIHN0cmVhbS5cbi8vIEV2ZXJ5IHdyaXR0ZW4gY2h1bmsgZ2V0cyBvdXRwdXQgYXMtaXMuXG5cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBQYXNzVGhyb3VnaDtcblxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vX3N0cmVhbV90cmFuc2Zvcm0nKTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG51dGlsLmluaGVyaXRzKFBhc3NUaHJvdWdoLCBUcmFuc2Zvcm0pO1xuXG5mdW5jdGlvbiBQYXNzVGhyb3VnaChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBQYXNzVGhyb3VnaCkpIHJldHVybiBuZXcgUGFzc1Rocm91Z2gob3B0aW9ucyk7XG5cbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgb3B0aW9ucyk7XG59XG5cblBhc3NUaHJvdWdoLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobnVsbCwgY2h1bmspO1xufTsiLCIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhZGFibGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgcHJvY2Vzc05leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy1uZXh0aWNrLWFyZ3MnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5Jyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuUmVhZGFibGUuUmVhZGFibGVTdGF0ZSA9IFJlYWRhYmxlU3RhdGU7XG5cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEVFbGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uIChlbWl0dGVyLCB0eXBlKSB7XG4gIHJldHVybiBlbWl0dGVyLmxpc3RlbmVycyh0eXBlKS5sZW5ndGg7XG59O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgU3RyZWFtO1xuKGZ1bmN0aW9uICgpIHtcbiAgdHJ5IHtcbiAgICBTdHJlYW0gPSByZXF1aXJlKCdzdCcgKyAncmVhbScpO1xuICB9IGNhdGNoIChfKSB7fSBmaW5hbGx5IHtcbiAgICBpZiAoIVN0cmVhbSkgU3RyZWFtID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuICB9XG59KSgpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBkZWJ1Z1V0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgZGVidWcgPSB1bmRlZmluZWQ7XG5pZiAoZGVidWdVdGlsICYmIGRlYnVnVXRpbC5kZWJ1Z2xvZykge1xuICBkZWJ1ZyA9IGRlYnVnVXRpbC5kZWJ1Z2xvZygnc3RyZWFtJyk7XG59IGVsc2Uge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uICgpIHt9O1xufVxuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBTdHJpbmdEZWNvZGVyO1xuXG51dGlsLmluaGVyaXRzKFJlYWRhYmxlLCBTdHJlYW0pO1xuXG52YXIgRHVwbGV4O1xuZnVuY3Rpb24gUmVhZGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0pIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBvYmplY3Qgc3RyZWFtIGZsYWcuIFVzZWQgdG8gbWFrZSByZWFkKG4pIGlnbm9yZSBuIGFuZCB0b1xuICAvLyBtYWtlIGFsbCB0aGUgYnVmZmVyIG1lcmdpbmcgYW5kIGxlbmd0aCBjaGVja3MgZ28gYXdheVxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcblxuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4KSB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLnJlYWRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggaXQgc3RvcHMgY2FsbGluZyBfcmVhZCgpIHRvIGZpbGwgdGhlIGJ1ZmZlclxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIFwiZG9uJ3QgY2FsbCBfcmVhZCBwcmVlbXB0aXZlbHkgZXZlclwiXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciBkZWZhdWx0SHdtID0gdGhpcy5vYmplY3RNb2RlID8gMTYgOiAxNiAqIDEwMjQ7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IGh3bSB8fCBod20gPT09IDAgPyBod20gOiBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfiB+dGhpcy5oaWdoV2F0ZXJNYXJrO1xuXG4gIHRoaXMuYnVmZmVyID0gW107XG4gIHRoaXMubGVuZ3RoID0gMDtcbiAgdGhpcy5waXBlcyA9IG51bGw7XG4gIHRoaXMucGlwZXNDb3VudCA9IDA7XG4gIHRoaXMuZmxvd2luZyA9IG51bGw7XG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgdGhpcy5lbmRFbWl0dGVkID0gZmFsc2U7XG4gIHRoaXMucmVhZGluZyA9IGZhbHNlO1xuXG4gIC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIG9ud3JpdGUgY2IgaXMgY2FsbGVkIGltbWVkaWF0ZWx5LFxuICAvLyBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWNhdXNlIGFueVxuICAvLyBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBjYWxsLlxuICB0aGlzLnN5bmMgPSB0cnVlO1xuXG4gIC8vIHdoZW5ldmVyIHdlIHJldHVybiBudWxsLCB0aGVuIHdlIHNldCBhIGZsYWcgdG8gc2F5XG4gIC8vIHRoYXQgd2UncmUgYXdhaXRpbmcgYSAncmVhZGFibGUnIGV2ZW50IGVtaXNzaW9uLlxuICB0aGlzLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLnJlYWRhYmxlTGlzdGVuaW5nID0gZmFsc2U7XG4gIHRoaXMucmVzdW1lU2NoZWR1bGVkID0gZmFsc2U7XG5cbiAgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cbiAgdGhpcy5kZWZhdWx0RW5jb2RpbmcgPSBvcHRpb25zLmRlZmF1bHRFbmNvZGluZyB8fCAndXRmOCc7XG5cbiAgLy8gd2hlbiBwaXBpbmcsIHdlIG9ubHkgY2FyZSBhYm91dCAncmVhZGFibGUnIGV2ZW50cyB0aGF0IGhhcHBlblxuICAvLyBhZnRlciByZWFkKClpbmcgYWxsIHRoZSBieXRlcyBhbmQgbm90IGdldHRpbmcgYW55IHB1c2hiYWNrLlxuICB0aGlzLnJhbk91dCA9IGZhbHNlO1xuXG4gIC8vIHRoZSBudW1iZXIgb2Ygd3JpdGVycyB0aGF0IGFyZSBhd2FpdGluZyBhIGRyYWluIGV2ZW50IGluIC5waXBlKClzXG4gIHRoaXMuYXdhaXREcmFpbiA9IDA7XG5cbiAgLy8gaWYgdHJ1ZSwgYSBtYXliZVJlYWRNb3JlIGhhcyBiZWVuIHNjaGVkdWxlZFxuICB0aGlzLnJlYWRpbmdNb3JlID0gZmFsc2U7XG5cbiAgdGhpcy5kZWNvZGVyID0gbnVsbDtcbiAgdGhpcy5lbmNvZGluZyA9IG51bGw7XG4gIGlmIChvcHRpb25zLmVuY29kaW5nKSB7XG4gICAgaWYgKCFTdHJpbmdEZWNvZGVyKSBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgICB0aGlzLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihvcHRpb25zLmVuY29kaW5nKTtcbiAgICB0aGlzLmVuY29kaW5nID0gb3B0aW9ucy5lbmNvZGluZztcbiAgfVxufVxuXG52YXIgRHVwbGV4O1xuZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSZWFkYWJsZSkpIHJldHVybiBuZXcgUmVhZGFibGUob3B0aW9ucyk7XG5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZSA9IG5ldyBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeVxuICB0aGlzLnJlYWRhYmxlID0gdHJ1ZTtcblxuICBpZiAob3B0aW9ucyAmJiB0eXBlb2Ygb3B0aW9ucy5yZWFkID09PSAnZnVuY3Rpb24nKSB0aGlzLl9yZWFkID0gb3B0aW9ucy5yZWFkO1xuXG4gIFN0cmVhbS5jYWxsKHRoaXMpO1xufVxuXG4vLyBNYW51YWxseSBzaG92ZSBzb21ldGhpbmcgaW50byB0aGUgcmVhZCgpIGJ1ZmZlci5cbi8vIFRoaXMgcmV0dXJucyB0cnVlIGlmIHRoZSBoaWdoV2F0ZXJNYXJrIGhhcyBub3QgYmVlbiBoaXQgeWV0LFxuLy8gc2ltaWxhciB0byBob3cgV3JpdGFibGUud3JpdGUoKSByZXR1cm5zIHRydWUgaWYgeW91IHNob3VsZFxuLy8gd3JpdGUoKSBzb21lIG1vcmUuXG5SZWFkYWJsZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgdHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuICAgIGlmIChlbmNvZGluZyAhPT0gc3RhdGUuZW5jb2RpbmcpIHtcbiAgICAgIGNodW5rID0gbmV3IEJ1ZmZlcihjaHVuaywgZW5jb2RpbmcpO1xuICAgICAgZW5jb2RpbmcgPSAnJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBmYWxzZSk7XG59O1xuXG4vLyBVbnNoaWZ0IHNob3VsZCAqYWx3YXlzKiBiZSBzb21ldGhpbmcgZGlyZWN0bHkgb3V0IG9mIHJlYWQoKVxuUmVhZGFibGUucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCAnJywgdHJ1ZSk7XG59O1xuXG5SZWFkYWJsZS5wcm90b3R5cGUuaXNQYXVzZWQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPT09IGZhbHNlO1xufTtcblxuZnVuY3Rpb24gcmVhZGFibGVBZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGFkZFRvRnJvbnQpIHtcbiAgdmFyIGVyID0gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuayk7XG4gIGlmIChlcikge1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfSBlbHNlIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpO1xuICB9IGVsc2UgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsgJiYgY2h1bmsubGVuZ3RoID4gMCkge1xuICAgIGlmIChzdGF0ZS5lbmRlZCAmJiAhYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ3N0cmVhbS5wdXNoKCkgYWZ0ZXIgRU9GJyk7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlKTtcbiAgICB9IGVsc2UgaWYgKHN0YXRlLmVuZEVtaXR0ZWQgJiYgYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ3N0cmVhbS51bnNoaWZ0KCkgYWZ0ZXIgZW5kIGV2ZW50Jyk7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHNraXBBZGQ7XG4gICAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhYWRkVG9Gcm9udCAmJiAhZW5jb2RpbmcpIHtcbiAgICAgICAgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcbiAgICAgICAgc2tpcEFkZCA9ICFzdGF0ZS5vYmplY3RNb2RlICYmIGNodW5rLmxlbmd0aCA9PT0gMDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFhZGRUb0Zyb250KSBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG5cbiAgICAgIC8vIERvbid0IGFkZCB0byB0aGUgYnVmZmVyIGlmIHdlJ3ZlIGRlY29kZWQgdG8gYW4gZW1wdHkgc3RyaW5nIGNodW5rIGFuZFxuICAgICAgLy8gd2UncmUgbm90IGluIG9iamVjdCBtb2RlXG4gICAgICBpZiAoIXNraXBBZGQpIHtcbiAgICAgICAgLy8gaWYgd2Ugd2FudCB0aGUgZGF0YSBub3csIGp1c3QgZW1pdCBpdC5cbiAgICAgICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwICYmICFzdGF0ZS5zeW5jKSB7XG4gICAgICAgICAgc3RyZWFtLmVtaXQoJ2RhdGEnLCBjaHVuayk7XG4gICAgICAgICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gdXBkYXRlIHRoZSBidWZmZXIgaW5mby5cbiAgICAgICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgICAgICAgaWYgKGFkZFRvRnJvbnQpIHN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtlbHNlIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcblxuICAgICAgICAgIGlmIChzdGF0ZS5uZWVkUmVhZGFibGUpIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCFhZGRUb0Zyb250KSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIG5lZWRNb3JlRGF0YShzdGF0ZSk7XG59XG5cbi8vIGlmIGl0J3MgcGFzdCB0aGUgaGlnaCB3YXRlciBtYXJrLCB3ZSBjYW4gcHVzaCBpbiBzb21lIG1vcmUuXG4vLyBBbHNvLCBpZiB3ZSBoYXZlIG5vIGRhdGEgeWV0LCB3ZSBjYW4gc3RhbmQgc29tZVxuLy8gbW9yZSBieXRlcy4gIFRoaXMgaXMgdG8gd29yayBhcm91bmQgY2FzZXMgd2hlcmUgaHdtPTAsXG4vLyBzdWNoIGFzIHRoZSByZXBsLiAgQWxzbywgaWYgdGhlIHB1c2goKSB0cmlnZ2VyZWQgYVxuLy8gcmVhZGFibGUgZXZlbnQsIGFuZCB0aGUgdXNlciBjYWxsZWQgcmVhZChsYXJnZU51bWJlcikgc3VjaCB0aGF0XG4vLyBuZWVkUmVhZGFibGUgd2FzIHNldCwgdGhlbiB3ZSBvdWdodCB0byBwdXNoIG1vcmUsIHNvIHRoYXQgYW5vdGhlclxuLy8gJ3JlYWRhYmxlJyBldmVudCB3aWxsIGJlIHRyaWdnZXJlZC5cbmZ1bmN0aW9uIG5lZWRNb3JlRGF0YShzdGF0ZSkge1xuICByZXR1cm4gIXN0YXRlLmVuZGVkICYmIChzdGF0ZS5uZWVkUmVhZGFibGUgfHwgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyayB8fCBzdGF0ZS5sZW5ndGggPT09IDApO1xufVxuXG4vLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cblJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZyA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgaWYgKCFTdHJpbmdEZWNvZGVyKSBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKTtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmNvZGluZyA9IGVuYztcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBEb24ndCByYWlzZSB0aGUgaHdtID4gOE1CXG52YXIgTUFYX0hXTSA9IDB4ODAwMDAwO1xuZnVuY3Rpb24gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobikge1xuICBpZiAobiA+PSBNQVhfSFdNKSB7XG4gICAgbiA9IE1BWF9IV007XG4gIH0gZWxzZSB7XG4gICAgLy8gR2V0IHRoZSBuZXh0IGhpZ2hlc3QgcG93ZXIgb2YgMlxuICAgIG4tLTtcbiAgICBuIHw9IG4gPj4+IDE7XG4gICAgbiB8PSBuID4+PiAyO1xuICAgIG4gfD0gbiA+Pj4gNDtcbiAgICBuIHw9IG4gPj4+IDg7XG4gICAgbiB8PSBuID4+PiAxNjtcbiAgICBuKys7XG4gIH1cbiAgcmV0dXJuIG47XG59XG5cbmZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobiwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkgcmV0dXJuIDA7XG5cbiAgaWYgKHN0YXRlLm9iamVjdE1vZGUpIHJldHVybiBuID09PSAwID8gMCA6IDE7XG5cbiAgaWYgKG4gPT09IG51bGwgfHwgaXNOYU4obikpIHtcbiAgICAvLyBvbmx5IGZsb3cgb25lIGJ1ZmZlciBhdCBhIHRpbWVcbiAgICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5idWZmZXIubGVuZ3RoKSByZXR1cm4gc3RhdGUuYnVmZmVyWzBdLmxlbmd0aDtlbHNlIHJldHVybiBzdGF0ZS5sZW5ndGg7XG4gIH1cblxuICBpZiAobiA8PSAwKSByZXR1cm4gMDtcblxuICAvLyBJZiB3ZSdyZSBhc2tpbmcgZm9yIG1vcmUgdGhhbiB0aGUgdGFyZ2V0IGJ1ZmZlciBsZXZlbCxcbiAgLy8gdGhlbiByYWlzZSB0aGUgd2F0ZXIgbWFyay4gIEJ1bXAgdXAgdG8gdGhlIG5leHQgaGlnaGVzdFxuICAvLyBwb3dlciBvZiAyLCB0byBwcmV2ZW50IGluY3JlYXNpbmcgaXQgZXhjZXNzaXZlbHkgaW4gdGlueVxuICAvLyBhbW91bnRzLlxuICBpZiAobiA+IHN0YXRlLmhpZ2hXYXRlck1hcmspIHN0YXRlLmhpZ2hXYXRlck1hcmsgPSBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKTtcblxuICAvLyBkb24ndCBoYXZlIHRoYXQgbXVjaC4gIHJldHVybiBudWxsLCB1bmxlc3Mgd2UndmUgZW5kZWQuXG4gIGlmIChuID4gc3RhdGUubGVuZ3RoKSB7XG4gICAgaWYgKCFzdGF0ZS5lbmRlZCkge1xuICAgICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuO1xufVxuXG4vLyB5b3UgY2FuIG92ZXJyaWRlIGVpdGhlciB0aGlzIG1ldGhvZCwgb3IgdGhlIGFzeW5jIF9yZWFkKG4pIGJlbG93LlxuUmVhZGFibGUucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbiAobikge1xuICBkZWJ1ZygncmVhZCcsIG4pO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgbk9yaWcgPSBuO1xuXG4gIGlmICh0eXBlb2YgbiAhPT0gJ251bWJlcicgfHwgbiA+IDApIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuXG4gIC8vIGlmIHdlJ3JlIGRvaW5nIHJlYWQoMCkgdG8gdHJpZ2dlciBhIHJlYWRhYmxlIGV2ZW50LCBidXQgd2VcbiAgLy8gYWxyZWFkeSBoYXZlIGEgYnVuY2ggb2YgZGF0YSBpbiB0aGUgYnVmZmVyLCB0aGVuIGp1c3QgdHJpZ2dlclxuICAvLyB0aGUgJ3JlYWRhYmxlJyBldmVudCBhbmQgbW92ZSBvbi5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUubmVlZFJlYWRhYmxlICYmIChzdGF0ZS5sZW5ndGggPj0gc3RhdGUuaGlnaFdhdGVyTWFyayB8fCBzdGF0ZS5lbmRlZCkpIHtcbiAgICBkZWJ1ZygncmVhZDogZW1pdFJlYWRhYmxlJywgc3RhdGUubGVuZ3RoLCBzdGF0ZS5lbmRlZCk7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkgZW5kUmVhZGFibGUodGhpcyk7ZWxzZSBlbWl0UmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBuID0gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSk7XG5cbiAgLy8gaWYgd2UndmUgZW5kZWQsIGFuZCB3ZSdyZSBub3cgY2xlYXIsIHRoZW4gZmluaXNoIGl0IHVwLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkge1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIGVuZFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQWxsIHRoZSBhY3R1YWwgY2h1bmsgZ2VuZXJhdGlvbiBsb2dpYyBuZWVkcyB0byBiZVxuICAvLyAqYmVsb3cqIHRoZSBjYWxsIHRvIF9yZWFkLiAgVGhlIHJlYXNvbiBpcyB0aGF0IGluIGNlcnRhaW5cbiAgLy8gc3ludGhldGljIHN0cmVhbSBjYXNlcywgc3VjaCBhcyBwYXNzdGhyb3VnaCBzdHJlYW1zLCBfcmVhZFxuICAvLyBtYXkgYmUgYSBjb21wbGV0ZWx5IHN5bmNocm9ub3VzIG9wZXJhdGlvbiB3aGljaCBtYXkgY2hhbmdlXG4gIC8vIHRoZSBzdGF0ZSBvZiB0aGUgcmVhZCBidWZmZXIsIHByb3ZpZGluZyBlbm91Z2ggZGF0YSB3aGVuXG4gIC8vIGJlZm9yZSB0aGVyZSB3YXMgKm5vdCogZW5vdWdoLlxuICAvL1xuICAvLyBTbywgdGhlIHN0ZXBzIGFyZTpcbiAgLy8gMS4gRmlndXJlIG91dCB3aGF0IHRoZSBzdGF0ZSBvZiB0aGluZ3Mgd2lsbCBiZSBhZnRlciB3ZSBkb1xuICAvLyBhIHJlYWQgZnJvbSB0aGUgYnVmZmVyLlxuICAvL1xuICAvLyAyLiBJZiB0aGF0IHJlc3VsdGluZyBzdGF0ZSB3aWxsIHRyaWdnZXIgYSBfcmVhZCwgdGhlbiBjYWxsIF9yZWFkLlxuICAvLyBOb3RlIHRoYXQgdGhpcyBtYXkgYmUgYXN5bmNocm9ub3VzLCBvciBzeW5jaHJvbm91cy4gIFllcywgaXQgaXNcbiAgLy8gZGVlcGx5IHVnbHkgdG8gd3JpdGUgQVBJcyB0aGlzIHdheSwgYnV0IHRoYXQgc3RpbGwgZG9lc24ndCBtZWFuXG4gIC8vIHRoYXQgdGhlIFJlYWRhYmxlIGNsYXNzIHNob3VsZCBiZWhhdmUgaW1wcm9wZXJseSwgYXMgc3RyZWFtcyBhcmVcbiAgLy8gZGVzaWduZWQgdG8gYmUgc3luYy9hc3luYyBhZ25vc3RpYy5cbiAgLy8gVGFrZSBub3RlIGlmIHRoZSBfcmVhZCBjYWxsIGlzIHN5bmMgb3IgYXN5bmMgKGllLCBpZiB0aGUgcmVhZCBjYWxsXG4gIC8vIGhhcyByZXR1cm5lZCB5ZXQpLCBzbyB0aGF0IHdlIGtub3cgd2hldGhlciBvciBub3QgaXQncyBzYWZlIHRvIGVtaXRcbiAgLy8gJ3JlYWRhYmxlJyBldGMuXG4gIC8vXG4gIC8vIDMuIEFjdHVhbGx5IHB1bGwgdGhlIHJlcXVlc3RlZCBjaHVua3Mgb3V0IG9mIHRoZSBidWZmZXIgYW5kIHJldHVybi5cblxuICAvLyBpZiB3ZSBuZWVkIGEgcmVhZGFibGUgZXZlbnQsIHRoZW4gd2UgbmVlZCB0byBkbyBzb21lIHJlYWRpbmcuXG4gIHZhciBkb1JlYWQgPSBzdGF0ZS5uZWVkUmVhZGFibGU7XG4gIGRlYnVnKCduZWVkIHJlYWRhYmxlJywgZG9SZWFkKTtcblxuICAvLyBpZiB3ZSBjdXJyZW50bHkgaGF2ZSBsZXNzIHRoYW4gdGhlIGhpZ2hXYXRlck1hcmssIHRoZW4gYWxzbyByZWFkIHNvbWVcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCB8fCBzdGF0ZS5sZW5ndGggLSBuIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRvUmVhZCA9IHRydWU7XG4gICAgZGVidWcoJ2xlbmd0aCBsZXNzIHRoYW4gd2F0ZXJtYXJrJywgZG9SZWFkKTtcbiAgfVxuXG4gIC8vIGhvd2V2ZXIsIGlmIHdlJ3ZlIGVuZGVkLCB0aGVuIHRoZXJlJ3Mgbm8gcG9pbnQsIGFuZCBpZiB3ZSdyZSBhbHJlYWR5XG4gIC8vIHJlYWRpbmcsIHRoZW4gaXQncyB1bm5lY2Vzc2FyeS5cbiAgaWYgKHN0YXRlLmVuZGVkIHx8IHN0YXRlLnJlYWRpbmcpIHtcbiAgICBkb1JlYWQgPSBmYWxzZTtcbiAgICBkZWJ1ZygncmVhZGluZyBvciBlbmRlZCcsIGRvUmVhZCk7XG4gIH1cblxuICBpZiAoZG9SZWFkKSB7XG4gICAgZGVidWcoJ2RvIHJlYWQnKTtcbiAgICBzdGF0ZS5yZWFkaW5nID0gdHJ1ZTtcbiAgICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgICAvLyBpZiB0aGUgbGVuZ3RoIGlzIGN1cnJlbnRseSB6ZXJvLCB0aGVuIHdlICpuZWVkKiBhIHJlYWRhYmxlIGV2ZW50LlxuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgLy8gY2FsbCBpbnRlcm5hbCByZWFkIG1ldGhvZFxuICAgIHRoaXMuX3JlYWQoc3RhdGUuaGlnaFdhdGVyTWFyayk7XG4gICAgc3RhdGUuc3luYyA9IGZhbHNlO1xuICB9XG5cbiAgLy8gSWYgX3JlYWQgcHVzaGVkIGRhdGEgc3luY2hyb25vdXNseSwgdGhlbiBgcmVhZGluZ2Agd2lsbCBiZSBmYWxzZSxcbiAgLy8gYW5kIHdlIG5lZWQgdG8gcmUtZXZhbHVhdGUgaG93IG11Y2ggZGF0YSB3ZSBjYW4gcmV0dXJuIHRvIHRoZSB1c2VyLlxuICBpZiAoZG9SZWFkICYmICFzdGF0ZS5yZWFkaW5nKSBuID0gaG93TXVjaFRvUmVhZChuT3JpZywgc3RhdGUpO1xuXG4gIHZhciByZXQ7XG4gIGlmIChuID4gMCkgcmV0ID0gZnJvbUxpc3Qobiwgc3RhdGUpO2Vsc2UgcmV0ID0gbnVsbDtcblxuICBpZiAocmV0ID09PSBudWxsKSB7XG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBuID0gMDtcbiAgfVxuXG4gIHN0YXRlLmxlbmd0aCAtPSBuO1xuXG4gIC8vIElmIHdlIGhhdmUgbm90aGluZyBpbiB0aGUgYnVmZmVyLCB0aGVuIHdlIHdhbnQgdG8ga25vd1xuICAvLyBhcyBzb29uIGFzIHdlICpkbyogZ2V0IHNvbWV0aGluZyBpbnRvIHRoZSBidWZmZXIuXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLmVuZGVkKSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gIC8vIElmIHdlIHRyaWVkIHRvIHJlYWQoKSBwYXN0IHRoZSBFT0YsIHRoZW4gZW1pdCBlbmQgb24gdGhlIG5leHQgdGljay5cbiAgaWYgKG5PcmlnICE9PSBuICYmIHN0YXRlLmVuZGVkICYmIHN0YXRlLmxlbmd0aCA9PT0gMCkgZW5kUmVhZGFibGUodGhpcyk7XG5cbiAgaWYgKHJldCAhPT0gbnVsbCkgdGhpcy5lbWl0KCdkYXRhJywgcmV0KTtcblxuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuaykge1xuICB2YXIgZXIgPSBudWxsO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykgJiYgdHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gbnVsbCAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgcmV0dXJuIGVyO1xufVxuXG5mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmVuZGVkKSByZXR1cm47XG4gIGlmIChzdGF0ZS5kZWNvZGVyKSB7XG4gICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSB7XG4gICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcblxuICAvLyBlbWl0ICdyZWFkYWJsZScgbm93IHRvIG1ha2Ugc3VyZSBpdCBnZXRzIHBpY2tlZCB1cC5cbiAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG59XG5cbi8vIERvbid0IGVtaXQgcmVhZGFibGUgcmlnaHQgYXdheSBpbiBzeW5jIG1vZGUsIGJlY2F1c2UgdGhpcyBjYW4gdHJpZ2dlclxuLy8gYW5vdGhlciByZWFkKCkgY2FsbCA9PiBzdGFjayBvdmVyZmxvdy4gIFRoaXMgd2F5LCBpdCBtaWdodCB0cmlnZ2VyXG4vLyBhIG5leHRUaWNrIHJlY3Vyc2lvbiB3YXJuaW5nLCBidXQgdGhhdCdzIG5vdCBzbyBiYWQuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIGlmICghc3RhdGUuZW1pdHRlZFJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ2VtaXRSZWFkYWJsZScsIHN0YXRlLmZsb3dpbmcpO1xuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgaWYgKHN0YXRlLnN5bmMpIHByb2Nlc3NOZXh0VGljayhlbWl0UmVhZGFibGVfLCBzdHJlYW0pO2Vsc2UgZW1pdFJlYWRhYmxlXyhzdHJlYW0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZV8oc3RyZWFtKSB7XG4gIGRlYnVnKCdlbWl0IHJlYWRhYmxlJyk7XG4gIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xuICBmbG93KHN0cmVhbSk7XG59XG5cbi8vIGF0IHRoaXMgcG9pbnQsIHRoZSB1c2VyIGhhcyBwcmVzdW1hYmx5IHNlZW4gdGhlICdyZWFkYWJsZScgZXZlbnQsXG4vLyBhbmQgY2FsbGVkIHJlYWQoKSB0byBjb25zdW1lIHNvbWUgZGF0YS4gIHRoYXQgbWF5IGhhdmUgdHJpZ2dlcmVkXG4vLyBpbiB0dXJuIGFub3RoZXIgX3JlYWQobikgY2FsbCwgaW4gd2hpY2ggY2FzZSByZWFkaW5nID0gdHJ1ZSBpZlxuLy8gaXQncyBpbiBwcm9ncmVzcy5cbi8vIEhvd2V2ZXIsIGlmIHdlJ3JlIG5vdCBlbmRlZCwgb3IgcmVhZGluZywgYW5kIHRoZSBsZW5ndGggPCBod20sXG4vLyB0aGVuIGdvIGFoZWFkIGFuZCB0cnkgdG8gcmVhZCBzb21lIG1vcmUgcHJlZW1wdGl2ZWx5LlxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZ01vcmUpIHtcbiAgICBzdGF0ZS5yZWFkaW5nTW9yZSA9IHRydWU7XG4gICAgcHJvY2Vzc05leHRUaWNrKG1heWJlUmVhZE1vcmVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlXyhzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIHdoaWxlICghc3RhdGUucmVhZGluZyAmJiAhc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUuZW5kZWQgJiYgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRlYnVnKCdtYXliZVJlYWRNb3JlIHJlYWQgMCcpO1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICAgIGlmIChsZW4gPT09IHN0YXRlLmxlbmd0aClcbiAgICAgIC8vIGRpZG4ndCBnZXQgYW55IGRhdGEsIHN0b3Agc3Bpbm5pbmcuXG4gICAgICBicmVhaztlbHNlIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgfVxuICBzdGF0ZS5yZWFkaW5nTW9yZSA9IGZhbHNlO1xufVxuXG4vLyBhYnN0cmFjdCBtZXRob2QuICB0byBiZSBvdmVycmlkZGVuIGluIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyBjYWxsIGNiKGVyLCBkYXRhKSB3aGVyZSBkYXRhIGlzIDw9IG4gaW4gbGVuZ3RoLlxuLy8gZm9yIHZpcnR1YWwgKG5vbi1zdHJpbmcsIG5vbi1idWZmZXIpIHN0cmVhbXMsIFwibGVuZ3RoXCIgaXMgc29tZXdoYXRcbi8vIGFyYml0cmFyeSwgYW5kIHBlcmhhcHMgbm90IHZlcnkgbWVhbmluZ2Z1bC5cblJlYWRhYmxlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cblJlYWRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKGRlc3QsIHBpcGVPcHRzKSB7XG4gIHZhciBzcmMgPSB0aGlzO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIHN3aXRjaCAoc3RhdGUucGlwZXNDb3VudCkge1xuICAgIGNhc2UgMDpcbiAgICAgIHN0YXRlLnBpcGVzID0gZGVzdDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMTpcbiAgICAgIHN0YXRlLnBpcGVzID0gW3N0YXRlLnBpcGVzLCBkZXN0XTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBzdGF0ZS5waXBlcy5wdXNoKGRlc3QpO1xuICAgICAgYnJlYWs7XG4gIH1cbiAgc3RhdGUucGlwZXNDb3VudCArPSAxO1xuICBkZWJ1ZygncGlwZSBjb3VudD0lZCBvcHRzPSVqJywgc3RhdGUucGlwZXNDb3VudCwgcGlwZU9wdHMpO1xuXG4gIHZhciBkb0VuZCA9ICghcGlwZU9wdHMgfHwgcGlwZU9wdHMuZW5kICE9PSBmYWxzZSkgJiYgZGVzdCAhPT0gcHJvY2Vzcy5zdGRvdXQgJiYgZGVzdCAhPT0gcHJvY2Vzcy5zdGRlcnI7XG5cbiAgdmFyIGVuZEZuID0gZG9FbmQgPyBvbmVuZCA6IGNsZWFudXA7XG4gIGlmIChzdGF0ZS5lbmRFbWl0dGVkKSBwcm9jZXNzTmV4dFRpY2soZW5kRm4pO2Vsc2Ugc3JjLm9uY2UoJ2VuZCcsIGVuZEZuKTtcblxuICBkZXN0Lm9uKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gIGZ1bmN0aW9uIG9udW5waXBlKHJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ29udW5waXBlJyk7XG4gICAgaWYgKHJlYWRhYmxlID09PSBzcmMpIHtcbiAgICAgIGNsZWFudXAoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBkZWJ1Zygnb25lbmQnKTtcbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cbiAgLy8gd2hlbiB0aGUgZGVzdCBkcmFpbnMsIGl0IHJlZHVjZXMgdGhlIGF3YWl0RHJhaW4gY291bnRlclxuICAvLyBvbiB0aGUgc291cmNlLiAgVGhpcyB3b3VsZCBiZSBtb3JlIGVsZWdhbnQgd2l0aCBhIC5vbmNlKClcbiAgLy8gaGFuZGxlciBpbiBmbG93KCksIGJ1dCBhZGRpbmcgYW5kIHJlbW92aW5nIHJlcGVhdGVkbHkgaXNcbiAgLy8gdG9vIHNsb3cuXG4gIHZhciBvbmRyYWluID0gcGlwZU9uRHJhaW4oc3JjKTtcbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICB2YXIgY2xlYW5lZFVwID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgZGVidWcoJ2NsZWFudXAnKTtcbiAgICAvLyBjbGVhbnVwIGV2ZW50IGhhbmRsZXJzIG9uY2UgdGhlIHBpcGUgaXMgYnJva2VuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ3VucGlwZScsIG9udW5waXBlKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIGNsZWFudXApO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG5cbiAgICBjbGVhbmVkVXAgPSB0cnVlO1xuXG4gICAgLy8gaWYgdGhlIHJlYWRlciBpcyB3YWl0aW5nIGZvciBhIGRyYWluIGV2ZW50IGZyb20gdGhpc1xuICAgIC8vIHNwZWNpZmljIHdyaXRlciwgdGhlbiBpdCB3b3VsZCBjYXVzZSBpdCB0byBuZXZlciBzdGFydFxuICAgIC8vIGZsb3dpbmcgYWdhaW4uXG4gICAgLy8gU28sIGlmIHRoaXMgaXMgYXdhaXRpbmcgYSBkcmFpbiwgdGhlbiB3ZSBqdXN0IGNhbGwgaXQgbm93LlxuICAgIC8vIElmIHdlIGRvbid0IGtub3csIHRoZW4gYXNzdW1lIHRoYXQgd2UgYXJlIHdhaXRpbmcgZm9yIG9uZS5cbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiAmJiAoIWRlc3QuX3dyaXRhYmxlU3RhdGUgfHwgZGVzdC5fd3JpdGFibGVTdGF0ZS5uZWVkRHJhaW4pKSBvbmRyYWluKCk7XG4gIH1cblxuICBzcmMub24oJ2RhdGEnLCBvbmRhdGEpO1xuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBkZWJ1Zygnb25kYXRhJyk7XG4gICAgdmFyIHJldCA9IGRlc3Qud3JpdGUoY2h1bmspO1xuICAgIGlmIChmYWxzZSA9PT0gcmV0KSB7XG4gICAgICAvLyBJZiB0aGUgdXNlciB1bnBpcGVkIGR1cmluZyBgZGVzdC53cml0ZSgpYCwgaXQgaXMgcG9zc2libGVcbiAgICAgIC8vIHRvIGdldCBzdHVjayBpbiBhIHBlcm1hbmVudGx5IHBhdXNlZCBzdGF0ZSBpZiB0aGF0IHdyaXRlXG4gICAgICAvLyBhbHNvIHJldHVybmVkIGZhbHNlLlxuICAgICAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEgJiYgc3RhdGUucGlwZXNbMF0gPT09IGRlc3QgJiYgc3JjLmxpc3RlbmVyQ291bnQoJ2RhdGEnKSA9PT0gMSAmJiAhY2xlYW5lZFVwKSB7XG4gICAgICAgIGRlYnVnKCdmYWxzZSB3cml0ZSByZXNwb25zZSwgcGF1c2UnLCBzcmMuX3JlYWRhYmxlU3RhdGUuYXdhaXREcmFpbik7XG4gICAgICAgIHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKys7XG4gICAgICB9XG4gICAgICBzcmMucGF1c2UoKTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgZGVzdCBoYXMgYW4gZXJyb3IsIHRoZW4gc3RvcCBwaXBpbmcgaW50byBpdC5cbiAgLy8gaG93ZXZlciwgZG9uJ3Qgc3VwcHJlc3MgdGhlIHRocm93aW5nIGJlaGF2aW9yIGZvciB0aGlzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgZGVidWcoJ29uZXJyb3InLCBlcik7XG4gICAgdW5waXBlKCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBpZiAoRUVsaXN0ZW5lckNvdW50KGRlc3QsICdlcnJvcicpID09PSAwKSBkZXN0LmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9XG4gIC8vIFRoaXMgaXMgYSBicnV0YWxseSB1Z2x5IGhhY2sgdG8gbWFrZSBzdXJlIHRoYXQgb3VyIGVycm9yIGhhbmRsZXJcbiAgLy8gaXMgYXR0YWNoZWQgYmVmb3JlIGFueSB1c2VybGFuZCBvbmVzLiAgTkVWRVIgRE8gVEhJUy5cbiAgaWYgKCFkZXN0Ll9ldmVudHMgfHwgIWRlc3QuX2V2ZW50cy5lcnJvcikgZGVzdC5vbignZXJyb3InLCBvbmVycm9yKTtlbHNlIGlmIChpc0FycmF5KGRlc3QuX2V2ZW50cy5lcnJvcikpIGRlc3QuX2V2ZW50cy5lcnJvci51bnNoaWZ0KG9uZXJyb3IpO2Vsc2UgZGVzdC5fZXZlbnRzLmVycm9yID0gW29uZXJyb3IsIGRlc3QuX2V2ZW50cy5lcnJvcl07XG5cbiAgLy8gQm90aCBjbG9zZSBhbmQgZmluaXNoIHNob3VsZCB0cmlnZ2VyIHVucGlwZSwgYnV0IG9ubHkgb25jZS5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICBmdW5jdGlvbiBvbmZpbmlzaCgpIHtcbiAgICBkZWJ1Zygnb25maW5pc2gnKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnZmluaXNoJywgb25maW5pc2gpO1xuXG4gIGZ1bmN0aW9uIHVucGlwZSgpIHtcbiAgICBkZWJ1ZygndW5waXBlJyk7XG4gICAgc3JjLnVucGlwZShkZXN0KTtcbiAgfVxuXG4gIC8vIHRlbGwgdGhlIGRlc3QgdGhhdCBpdCdzIGJlaW5nIHBpcGVkIHRvXG4gIGRlc3QuZW1pdCgncGlwZScsIHNyYyk7XG5cbiAgLy8gc3RhcnQgdGhlIGZsb3cgaWYgaXQgaGFzbid0IGJlZW4gc3RhcnRlZCBhbHJlYWR5LlxuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGlwZSByZXN1bWUnKTtcbiAgICBzcmMucmVzdW1lKCk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn07XG5cbmZ1bmN0aW9uIHBpcGVPbkRyYWluKHNyYykge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgICBkZWJ1ZygncGlwZU9uRHJhaW4nLCBzdGF0ZS5hd2FpdERyYWluKTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbikgc3RhdGUuYXdhaXREcmFpbi0tO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluID09PSAwICYmIEVFbGlzdGVuZXJDb3VudChzcmMsICdkYXRhJykpIHtcbiAgICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgICAgZmxvdyhzcmMpO1xuICAgIH1cbiAgfTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnVucGlwZSA9IGZ1bmN0aW9uIChkZXN0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gaWYgd2UncmUgbm90IHBpcGluZyBhbnl3aGVyZSwgdGhlbiBkbyBub3RoaW5nLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMCkgcmV0dXJuIHRoaXM7XG5cbiAgLy8ganVzdCBvbmUgZGVzdGluYXRpb24uICBtb3N0IGNvbW1vbiBjYXNlLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSkge1xuICAgIC8vIHBhc3NlZCBpbiBvbmUsIGJ1dCBpdCdzIG5vdCB0aGUgcmlnaHQgb25lLlxuICAgIGlmIChkZXN0ICYmIGRlc3QgIT09IHN0YXRlLnBpcGVzKSByZXR1cm4gdGhpcztcblxuICAgIGlmICghZGVzdCkgZGVzdCA9IHN0YXRlLnBpcGVzO1xuXG4gICAgLy8gZ290IGEgbWF0Y2guXG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICBpZiAoZGVzdCkgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHNsb3cgY2FzZS4gbXVsdGlwbGUgcGlwZSBkZXN0aW5hdGlvbnMuXG5cbiAgaWYgKCFkZXN0KSB7XG4gICAgLy8gcmVtb3ZlIGFsbC5cbiAgICB2YXIgZGVzdHMgPSBzdGF0ZS5waXBlcztcbiAgICB2YXIgbGVuID0gc3RhdGUucGlwZXNDb3VudDtcbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuXG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGxlbjsgX2krKykge1xuICAgICAgZGVzdHNbX2ldLmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuICAgIH1yZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHRyeSB0byBmaW5kIHRoZSByaWdodCBvbmUuXG4gIHZhciBpID0gaW5kZXhPZihzdGF0ZS5waXBlcywgZGVzdCk7XG4gIGlmIChpID09PSAtMSkgcmV0dXJuIHRoaXM7XG5cbiAgc3RhdGUucGlwZXMuc3BsaWNlKGksIDEpO1xuICBzdGF0ZS5waXBlc0NvdW50IC09IDE7XG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSBzdGF0ZS5waXBlcyA9IHN0YXRlLnBpcGVzWzBdO1xuXG4gIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBzZXQgdXAgZGF0YSBldmVudHMgaWYgdGhleSBhcmUgYXNrZWQgZm9yXG4vLyBFbnN1cmUgcmVhZGFibGUgbGlzdGVuZXJzIGV2ZW50dWFsbHkgZ2V0IHNvbWV0aGluZ1xuUmVhZGFibGUucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKGV2LCBmbikge1xuICB2YXIgcmVzID0gU3RyZWFtLnByb3RvdHlwZS5vbi5jYWxsKHRoaXMsIGV2LCBmbik7XG5cbiAgLy8gSWYgbGlzdGVuaW5nIHRvIGRhdGEsIGFuZCBpdCBoYXMgbm90IGV4cGxpY2l0bHkgYmVlbiBwYXVzZWQsXG4gIC8vIHRoZW4gY2FsbCByZXN1bWUgdG8gc3RhcnQgdGhlIGZsb3cgb2YgZGF0YSBvbiB0aGUgbmV4dCB0aWNrLlxuICBpZiAoZXYgPT09ICdkYXRhJyAmJiBmYWxzZSAhPT0gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKSB7XG4gICAgdGhpcy5yZXN1bWUoKTtcbiAgfVxuXG4gIGlmIChldiA9PT0gJ3JlYWRhYmxlJyAmJiAhdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmRFbWl0dGVkKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgICBpZiAoIXN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nKSB7XG4gICAgICBzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZyA9IHRydWU7XG4gICAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICAgICAgcHJvY2Vzc05leHRUaWNrKG5SZWFkaW5nTmV4dFRpY2ssIHRoaXMpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5sZW5ndGgpIHtcbiAgICAgICAgZW1pdFJlYWRhYmxlKHRoaXMsIHN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblJlYWRhYmxlLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IFJlYWRhYmxlLnByb3RvdHlwZS5vbjtcblxuZnVuY3Rpb24gblJlYWRpbmdOZXh0VGljayhzZWxmKSB7XG4gIGRlYnVnKCdyZWFkYWJsZSBuZXh0dGljayByZWFkIDAnKTtcbiAgc2VsZi5yZWFkKDApO1xufVxuXG4vLyBwYXVzZSgpIGFuZCByZXN1bWUoKSBhcmUgcmVtbmFudHMgb2YgdGhlIGxlZ2FjeSByZWFkYWJsZSBzdHJlYW0gQVBJXG4vLyBJZiB0aGUgdXNlciB1c2VzIHRoZW0sIHRoZW4gc3dpdGNoIGludG8gb2xkIG1vZGUuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncmVzdW1lJyk7XG4gICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG4gICAgcmVzdW1lKHRoaXMsIHN0YXRlKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHJlc3VtZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVzdW1lU2NoZWR1bGVkKSB7XG4gICAgc3RhdGUucmVzdW1lU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICBwcm9jZXNzTmV4dFRpY2socmVzdW1lXywgc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzdW1lXyhzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZykge1xuICAgIGRlYnVnKCdyZXN1bWUgcmVhZCAwJyk7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gIH1cblxuICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgc3RyZWFtLmVtaXQoJ3Jlc3VtZScpO1xuICBmbG93KHN0cmVhbSk7XG4gIGlmIChzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5yZWFkaW5nKSBzdHJlYW0ucmVhZCgwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2FsbCBwYXVzZSBmbG93aW5nPSVqJywgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKTtcbiAgaWYgKGZhbHNlICE9PSB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGF1c2UnKTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmbG93KHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGRlYnVnKCdmbG93Jywgc3RhdGUuZmxvd2luZyk7XG4gIGlmIChzdGF0ZS5mbG93aW5nKSB7XG4gICAgZG8ge1xuICAgICAgdmFyIGNodW5rID0gc3RyZWFtLnJlYWQoKTtcbiAgICB9IHdoaWxlIChudWxsICE9PSBjaHVuayAmJiBzdGF0ZS5mbG93aW5nKTtcbiAgfVxufVxuXG4vLyB3cmFwIGFuIG9sZC1zdHlsZSBzdHJlYW0gYXMgdGhlIGFzeW5jIGRhdGEgc291cmNlLlxuLy8gVGhpcyBpcyAqbm90KiBwYXJ0IG9mIHRoZSByZWFkYWJsZSBzdHJlYW0gaW50ZXJmYWNlLlxuLy8gSXQgaXMgYW4gdWdseSB1bmZvcnR1bmF0ZSBtZXNzIG9mIGhpc3RvcnkuXG5SZWFkYWJsZS5wcm90b3R5cGUud3JhcCA9IGZ1bmN0aW9uIChzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHBhdXNlZCA9IGZhbHNlO1xuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgc3RyZWFtLm9uKCdlbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgZW5kJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIXN0YXRlLmVuZGVkKSB7XG4gICAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkgc2VsZi5wdXNoKGNodW5rKTtcbiAgICB9XG5cbiAgICBzZWxmLnB1c2gobnVsbCk7XG4gIH0pO1xuXG4gIHN0cmVhbS5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykge1xuICAgIGRlYnVnKCd3cmFwcGVkIGRhdGEnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlcikgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcblxuICAgIC8vIGRvbid0IHNraXAgb3ZlciBmYWxzeSB2YWx1ZXMgaW4gb2JqZWN0TW9kZVxuICAgIGlmIChzdGF0ZS5vYmplY3RNb2RlICYmIChjaHVuayA9PT0gbnVsbCB8fCBjaHVuayA9PT0gdW5kZWZpbmVkKSkgcmV0dXJuO2Vsc2UgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmICghY2h1bmsgfHwgIWNodW5rLmxlbmd0aCkpIHJldHVybjtcblxuICAgIHZhciByZXQgPSBzZWxmLnB1c2goY2h1bmspO1xuICAgIGlmICghcmV0KSB7XG4gICAgICBwYXVzZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLnBhdXNlKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBwcm94eSBhbGwgdGhlIG90aGVyIG1ldGhvZHMuXG4gIC8vIGltcG9ydGFudCB3aGVuIHdyYXBwaW5nIGZpbHRlcnMgYW5kIGR1cGxleGVzLlxuICBmb3IgKHZhciBpIGluIHN0cmVhbSkge1xuICAgIGlmICh0aGlzW2ldID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIHN0cmVhbVtpXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpc1tpXSA9IGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gc3RyZWFtW21ldGhvZF0uYXBwbHkoc3RyZWFtLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgICAgfShpKTtcbiAgICB9XG4gIH1cblxuICAvLyBwcm94eSBjZXJ0YWluIGltcG9ydGFudCBldmVudHMuXG4gIHZhciBldmVudHMgPSBbJ2Vycm9yJywgJ2Nsb3NlJywgJ2Rlc3Ryb3knLCAncGF1c2UnLCAncmVzdW1lJ107XG4gIGZvckVhY2goZXZlbnRzLCBmdW5jdGlvbiAoZXYpIHtcbiAgICBzdHJlYW0ub24oZXYsIHNlbGYuZW1pdC5iaW5kKHNlbGYsIGV2KSk7XG4gIH0pO1xuXG4gIC8vIHdoZW4gd2UgdHJ5IHRvIGNvbnN1bWUgc29tZSBtb3JlIGJ5dGVzLCBzaW1wbHkgdW5wYXVzZSB0aGVcbiAgLy8gdW5kZXJseWluZyBzdHJlYW0uXG4gIHNlbGYuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICAgIGRlYnVnKCd3cmFwcGVkIF9yZWFkJywgbik7XG4gICAgaWYgKHBhdXNlZCkge1xuICAgICAgcGF1c2VkID0gZmFsc2U7XG4gICAgICBzdHJlYW0ucmVzdW1lKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBzZWxmO1xufTtcblxuLy8gZXhwb3NlZCBmb3IgdGVzdGluZyBwdXJwb3NlcyBvbmx5LlxuUmVhZGFibGUuX2Zyb21MaXN0ID0gZnJvbUxpc3Q7XG5cbi8vIFBsdWNrIG9mZiBuIGJ5dGVzIGZyb20gYW4gYXJyYXkgb2YgYnVmZmVycy5cbi8vIExlbmd0aCBpcyB0aGUgY29tYmluZWQgbGVuZ3RocyBvZiBhbGwgdGhlIGJ1ZmZlcnMgaW4gdGhlIGxpc3QuXG5mdW5jdGlvbiBmcm9tTGlzdChuLCBzdGF0ZSkge1xuICB2YXIgbGlzdCA9IHN0YXRlLmJ1ZmZlcjtcbiAgdmFyIGxlbmd0aCA9IHN0YXRlLmxlbmd0aDtcbiAgdmFyIHN0cmluZ01vZGUgPSAhIXN0YXRlLmRlY29kZXI7XG4gIHZhciBvYmplY3RNb2RlID0gISFzdGF0ZS5vYmplY3RNb2RlO1xuICB2YXIgcmV0O1xuXG4gIC8vIG5vdGhpbmcgaW4gdGhlIGxpc3QsIGRlZmluaXRlbHkgZW1wdHkuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG5cbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0ID0gbnVsbDtlbHNlIGlmIChvYmplY3RNb2RlKSByZXQgPSBsaXN0LnNoaWZ0KCk7ZWxzZSBpZiAoIW4gfHwgbiA+PSBsZW5ndGgpIHtcbiAgICAvLyByZWFkIGl0IGFsbCwgdHJ1bmNhdGUgdGhlIGFycmF5LlxuICAgIGlmIChzdHJpbmdNb2RlKSByZXQgPSBsaXN0LmpvaW4oJycpO2Vsc2UgaWYgKGxpc3QubGVuZ3RoID09PSAxKSByZXQgPSBsaXN0WzBdO2Vsc2UgcmV0ID0gQnVmZmVyLmNvbmNhdChsaXN0LCBsZW5ndGgpO1xuICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyByZWFkIGp1c3Qgc29tZSBvZiBpdC5cbiAgICBpZiAobiA8IGxpc3RbMF0ubGVuZ3RoKSB7XG4gICAgICAvLyBqdXN0IHRha2UgYSBwYXJ0IG9mIHRoZSBmaXJzdCBsaXN0IGl0ZW0uXG4gICAgICAvLyBzbGljZSBpcyB0aGUgc2FtZSBmb3IgYnVmZmVycyBhbmQgc3RyaW5ncy5cbiAgICAgIHZhciBidWYgPSBsaXN0WzBdO1xuICAgICAgcmV0ID0gYnVmLnNsaWNlKDAsIG4pO1xuICAgICAgbGlzdFswXSA9IGJ1Zi5zbGljZShuKTtcbiAgICB9IGVsc2UgaWYgKG4gPT09IGxpc3RbMF0ubGVuZ3RoKSB7XG4gICAgICAvLyBmaXJzdCBsaXN0IGlzIGEgcGVyZmVjdCBtYXRjaFxuICAgICAgcmV0ID0gbGlzdC5zaGlmdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBjb21wbGV4IGNhc2UuXG4gICAgICAvLyB3ZSBoYXZlIGVub3VnaCB0byBjb3ZlciBpdCwgYnV0IGl0IHNwYW5zIHBhc3QgdGhlIGZpcnN0IGJ1ZmZlci5cbiAgICAgIGlmIChzdHJpbmdNb2RlKSByZXQgPSAnJztlbHNlIHJldCA9IG5ldyBCdWZmZXIobik7XG5cbiAgICAgIHZhciBjID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gbGlzdC5sZW5ndGg7IGkgPCBsICYmIGMgPCBuOyBpKyspIHtcbiAgICAgICAgdmFyIGJ1ZiA9IGxpc3RbMF07XG4gICAgICAgIHZhciBjcHkgPSBNYXRoLm1pbihuIC0gYywgYnVmLmxlbmd0aCk7XG5cbiAgICAgICAgaWYgKHN0cmluZ01vZGUpIHJldCArPSBidWYuc2xpY2UoMCwgY3B5KTtlbHNlIGJ1Zi5jb3B5KHJldCwgYywgMCwgY3B5KTtcblxuICAgICAgICBpZiAoY3B5IDwgYnVmLmxlbmd0aCkgbGlzdFswXSA9IGJ1Zi5zbGljZShjcHkpO2Vsc2UgbGlzdC5zaGlmdCgpO1xuXG4gICAgICAgIGMgKz0gY3B5O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gSWYgd2UgZ2V0IGhlcmUgYmVmb3JlIGNvbnN1bWluZyBhbGwgdGhlIGJ5dGVzLCB0aGVuIHRoYXQgaXMgYVxuICAvLyBidWcgaW4gbm9kZS4gIFNob3VsZCBuZXZlciBoYXBwZW4uXG4gIGlmIChzdGF0ZS5sZW5ndGggPiAwKSB0aHJvdyBuZXcgRXJyb3IoJ2VuZFJlYWRhYmxlIGNhbGxlZCBvbiBub24tZW1wdHkgc3RyZWFtJyk7XG5cbiAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkKSB7XG4gICAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuICAgIHByb2Nlc3NOZXh0VGljayhlbmRSZWFkYWJsZU5ULCBzdGF0ZSwgc3RyZWFtKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbmRSZWFkYWJsZU5UKHN0YXRlLCBzdHJlYW0pIHtcbiAgLy8gQ2hlY2sgdGhhdCB3ZSBkaWRuJ3QgZ2V0IG9uZSBsYXN0IHVuc2hpZnQuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCAmJiBzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICBzdGF0ZS5lbmRFbWl0dGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0ucmVhZGFibGUgPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZW5kJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZm9yRWFjaCh4cywgZikge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGYoeHNbaV0sIGkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBpZiAoeHNbaV0gPT09IHgpIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn0iLCIvLyBhIHRyYW5zZm9ybSBzdHJlYW0gaXMgYSByZWFkYWJsZS93cml0YWJsZSBzdHJlYW0gd2hlcmUgeW91IGRvXG4vLyBzb21ldGhpbmcgd2l0aCB0aGUgZGF0YS4gIFNvbWV0aW1lcyBpdCdzIGNhbGxlZCBhIFwiZmlsdGVyXCIsXG4vLyBidXQgdGhhdCdzIG5vdCBhIGdyZWF0IG5hbWUgZm9yIGl0LCBzaW5jZSB0aGF0IGltcGxpZXMgYSB0aGluZyB3aGVyZVxuLy8gc29tZSBiaXRzIHBhc3MgdGhyb3VnaCwgYW5kIG90aGVycyBhcmUgc2ltcGx5IGlnbm9yZWQuICAoVGhhdCB3b3VsZFxuLy8gYmUgYSB2YWxpZCBleGFtcGxlIG9mIGEgdHJhbnNmb3JtLCBvZiBjb3Vyc2UuKVxuLy9cbi8vIFdoaWxlIHRoZSBvdXRwdXQgaXMgY2F1c2FsbHkgcmVsYXRlZCB0byB0aGUgaW5wdXQsIGl0J3Mgbm90IGFcbi8vIG5lY2Vzc2FyaWx5IHN5bW1ldHJpYyBvciBzeW5jaHJvbm91cyB0cmFuc2Zvcm1hdGlvbi4gIEZvciBleGFtcGxlLFxuLy8gYSB6bGliIHN0cmVhbSBtaWdodCB0YWtlIG11bHRpcGxlIHBsYWluLXRleHQgd3JpdGVzKCksIGFuZCB0aGVuXG4vLyBlbWl0IGEgc2luZ2xlIGNvbXByZXNzZWQgY2h1bmsgc29tZSB0aW1lIGluIHRoZSBmdXR1cmUuXG4vL1xuLy8gSGVyZSdzIGhvdyB0aGlzIHdvcmtzOlxuLy9cbi8vIFRoZSBUcmFuc2Zvcm0gc3RyZWFtIGhhcyBhbGwgdGhlIGFzcGVjdHMgb2YgdGhlIHJlYWRhYmxlIGFuZCB3cml0YWJsZVxuLy8gc3RyZWFtIGNsYXNzZXMuICBXaGVuIHlvdSB3cml0ZShjaHVuayksIHRoYXQgY2FsbHMgX3dyaXRlKGNodW5rLGNiKVxuLy8gaW50ZXJuYWxseSwgYW5kIHJldHVybnMgZmFsc2UgaWYgdGhlcmUncyBhIGxvdCBvZiBwZW5kaW5nIHdyaXRlc1xuLy8gYnVmZmVyZWQgdXAuICBXaGVuIHlvdSBjYWxsIHJlYWQoKSwgdGhhdCBjYWxscyBfcmVhZChuKSB1bnRpbFxuLy8gdGhlcmUncyBlbm91Z2ggcGVuZGluZyByZWFkYWJsZSBkYXRhIGJ1ZmZlcmVkIHVwLlxuLy9cbi8vIEluIGEgdHJhbnNmb3JtIHN0cmVhbSwgdGhlIHdyaXR0ZW4gZGF0YSBpcyBwbGFjZWQgaW4gYSBidWZmZXIuICBXaGVuXG4vLyBfcmVhZChuKSBpcyBjYWxsZWQsIGl0IHRyYW5zZm9ybXMgdGhlIHF1ZXVlZCB1cCBkYXRhLCBjYWxsaW5nIHRoZVxuLy8gYnVmZmVyZWQgX3dyaXRlIGNiJ3MgYXMgaXQgY29uc3VtZXMgY2h1bmtzLiAgSWYgY29uc3VtaW5nIGEgc2luZ2xlXG4vLyB3cml0dGVuIGNodW5rIHdvdWxkIHJlc3VsdCBpbiBtdWx0aXBsZSBvdXRwdXQgY2h1bmtzLCB0aGVuIHRoZSBmaXJzdFxuLy8gb3V0cHV0dGVkIGJpdCBjYWxscyB0aGUgcmVhZGNiLCBhbmQgc3Vic2VxdWVudCBjaHVua3MganVzdCBnbyBpbnRvXG4vLyB0aGUgcmVhZCBidWZmZXIsIGFuZCB3aWxsIGNhdXNlIGl0IHRvIGVtaXQgJ3JlYWRhYmxlJyBpZiBuZWNlc3NhcnkuXG4vL1xuLy8gVGhpcyB3YXksIGJhY2stcHJlc3N1cmUgaXMgYWN0dWFsbHkgZGV0ZXJtaW5lZCBieSB0aGUgcmVhZGluZyBzaWRlLFxuLy8gc2luY2UgX3JlYWQgaGFzIHRvIGJlIGNhbGxlZCB0byBzdGFydCBwcm9jZXNzaW5nIGEgbmV3IGNodW5rLiAgSG93ZXZlcixcbi8vIGEgcGF0aG9sb2dpY2FsIGluZmxhdGUgdHlwZSBvZiB0cmFuc2Zvcm0gY2FuIGNhdXNlIGV4Y2Vzc2l2ZSBidWZmZXJpbmdcbi8vIGhlcmUuICBGb3IgZXhhbXBsZSwgaW1hZ2luZSBhIHN0cmVhbSB3aGVyZSBldmVyeSBieXRlIG9mIGlucHV0IGlzXG4vLyBpbnRlcnByZXRlZCBhcyBhbiBpbnRlZ2VyIGZyb20gMC0yNTUsIGFuZCB0aGVuIHJlc3VsdHMgaW4gdGhhdCBtYW55XG4vLyBieXRlcyBvZiBvdXRwdXQuICBXcml0aW5nIHRoZSA0IGJ5dGVzIHtmZixmZixmZixmZn0gd291bGQgcmVzdWx0IGluXG4vLyAxa2Igb2YgZGF0YSBiZWluZyBvdXRwdXQuICBJbiB0aGlzIGNhc2UsIHlvdSBjb3VsZCB3cml0ZSBhIHZlcnkgc21hbGxcbi8vIGFtb3VudCBvZiBpbnB1dCwgYW5kIGVuZCB1cCB3aXRoIGEgdmVyeSBsYXJnZSBhbW91bnQgb2Ygb3V0cHV0LiAgSW5cbi8vIHN1Y2ggYSBwYXRob2xvZ2ljYWwgaW5mbGF0aW5nIG1lY2hhbmlzbSwgdGhlcmUnZCBiZSBubyB3YXkgdG8gdGVsbFxuLy8gdGhlIHN5c3RlbSB0byBzdG9wIGRvaW5nIHRoZSB0cmFuc2Zvcm0uICBBIHNpbmdsZSA0TUIgd3JpdGUgY291bGRcbi8vIGNhdXNlIHRoZSBzeXN0ZW0gdG8gcnVuIG91dCBvZiBtZW1vcnkuXG4vL1xuLy8gSG93ZXZlciwgZXZlbiBpbiBzdWNoIGEgcGF0aG9sb2dpY2FsIGNhc2UsIG9ubHkgYSBzaW5nbGUgd3JpdHRlbiBjaHVua1xuLy8gd291bGQgYmUgY29uc3VtZWQsIGFuZCB0aGVuIHRoZSByZXN0IHdvdWxkIHdhaXQgKHVuLXRyYW5zZm9ybWVkKSB1bnRpbFxuLy8gdGhlIHJlc3VsdHMgb2YgdGhlIHByZXZpb3VzIHRyYW5zZm9ybWVkIGNodW5rIHdlcmUgY29uc3VtZWQuXG5cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc2Zvcm07XG5cbnZhciBEdXBsZXggPSByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhUcmFuc2Zvcm0sIER1cGxleCk7XG5cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0YXRlKHN0cmVhbSkge1xuICB0aGlzLmFmdGVyVHJhbnNmb3JtID0gZnVuY3Rpb24gKGVyLCBkYXRhKSB7XG4gICAgcmV0dXJuIGFmdGVyVHJhbnNmb3JtKHN0cmVhbSwgZXIsIGRhdGEpO1xuICB9O1xuXG4gIHRoaXMubmVlZFRyYW5zZm9ybSA9IGZhbHNlO1xuICB0aGlzLnRyYW5zZm9ybWluZyA9IGZhbHNlO1xuICB0aGlzLndyaXRlY2IgPSBudWxsO1xuICB0aGlzLndyaXRlY2h1bmsgPSBudWxsO1xuICB0aGlzLndyaXRlZW5jb2RpbmcgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBhZnRlclRyYW5zZm9ybShzdHJlYW0sIGVyLCBkYXRhKSB7XG4gIHZhciB0cyA9IHN0cmVhbS5fdHJhbnNmb3JtU3RhdGU7XG4gIHRzLnRyYW5zZm9ybWluZyA9IGZhbHNlO1xuXG4gIHZhciBjYiA9IHRzLndyaXRlY2I7XG5cbiAgaWYgKCFjYikgcmV0dXJuIHN0cmVhbS5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignbm8gd3JpdGVjYiBpbiBUcmFuc2Zvcm0gY2xhc3MnKSk7XG5cbiAgdHMud3JpdGVjaHVuayA9IG51bGw7XG4gIHRzLndyaXRlY2IgPSBudWxsO1xuXG4gIGlmIChkYXRhICE9PSBudWxsICYmIGRhdGEgIT09IHVuZGVmaW5lZCkgc3RyZWFtLnB1c2goZGF0YSk7XG5cbiAgY2IoZXIpO1xuXG4gIHZhciBycyA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgcnMucmVhZGluZyA9IGZhbHNlO1xuICBpZiAocnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHtcbiAgICBzdHJlYW0uX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn1cblxuZnVuY3Rpb24gVHJhbnNmb3JtKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFRyYW5zZm9ybSkpIHJldHVybiBuZXcgVHJhbnNmb3JtKG9wdGlvbnMpO1xuXG4gIER1cGxleC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlID0gbmV3IFRyYW5zZm9ybVN0YXRlKHRoaXMpO1xuXG4gIC8vIHdoZW4gdGhlIHdyaXRhYmxlIHNpZGUgZmluaXNoZXMsIHRoZW4gZmx1c2ggb3V0IGFueXRoaW5nIHJlbWFpbmluZy5cbiAgdmFyIHN0cmVhbSA9IHRoaXM7XG5cbiAgLy8gc3RhcnQgb3V0IGFza2luZyBmb3IgYSByZWFkYWJsZSBldmVudCBvbmNlIGRhdGEgaXMgdHJhbnNmb3JtZWQuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcblxuICAvLyB3ZSBoYXZlIGltcGxlbWVudGVkIHRoZSBfcmVhZCBtZXRob2QsIGFuZCBkb25lIHRoZSBvdGhlciB0aGluZ3NcbiAgLy8gdGhhdCBSZWFkYWJsZSB3YW50cyBiZWZvcmUgdGhlIGZpcnN0IF9yZWFkIGNhbGwsIHNvIHVuc2V0IHRoZVxuICAvLyBzeW5jIGd1YXJkIGZsYWcuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuc3luYyA9IGZhbHNlO1xuXG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnRyYW5zZm9ybSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fdHJhbnNmb3JtID0gb3B0aW9ucy50cmFuc2Zvcm07XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZmx1c2ggPT09ICdmdW5jdGlvbicpIHRoaXMuX2ZsdXNoID0gb3B0aW9ucy5mbHVzaDtcbiAgfVxuXG4gIHRoaXMub25jZSgncHJlZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fZmx1c2ggPT09ICdmdW5jdGlvbicpIHRoaXMuX2ZsdXNoKGZ1bmN0aW9uIChlcikge1xuICAgICAgZG9uZShzdHJlYW0sIGVyKTtcbiAgICB9KTtlbHNlIGRvbmUoc3RyZWFtKTtcbiAgfSk7XG59XG5cblRyYW5zZm9ybS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcpIHtcbiAgdGhpcy5fdHJhbnNmb3JtU3RhdGUubmVlZFRyYW5zZm9ybSA9IGZhbHNlO1xuICByZXR1cm4gRHVwbGV4LnByb3RvdHlwZS5wdXNoLmNhbGwodGhpcywgY2h1bmssIGVuY29kaW5nKTtcbn07XG5cbi8vIFRoaXMgaXMgdGhlIHBhcnQgd2hlcmUgeW91IGRvIHN0dWZmIVxuLy8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBpbiBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLlxuLy8gJ2NodW5rJyBpcyBhbiBpbnB1dCBjaHVuay5cbi8vXG4vLyBDYWxsIGBwdXNoKG5ld0NodW5rKWAgdG8gcGFzcyBhbG9uZyB0cmFuc2Zvcm1lZCBvdXRwdXRcbi8vIHRvIHRoZSByZWFkYWJsZSBzaWRlLiAgWW91IG1heSBjYWxsICdwdXNoJyB6ZXJvIG9yIG1vcmUgdGltZXMuXG4vL1xuLy8gQ2FsbCBgY2IoZXJyKWAgd2hlbiB5b3UgYXJlIGRvbmUgd2l0aCB0aGlzIGNodW5rLiAgSWYgeW91IHBhc3Ncbi8vIGFuIGVycm9yLCB0aGVuIHRoYXQnbGwgcHV0IHRoZSBodXJ0IG9uIHRoZSB3aG9sZSBvcGVyYXRpb24uICBJZiB5b3Vcbi8vIG5ldmVyIGNhbGwgY2IoKSwgdGhlbiB5b3UnbGwgbmV2ZXIgZ2V0IGFub3RoZXIgY2h1bmsuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aHJvdyBuZXcgRXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuVHJhbnNmb3JtLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcbiAgdHMud3JpdGVjYiA9IGNiO1xuICB0cy53cml0ZWNodW5rID0gY2h1bms7XG4gIHRzLndyaXRlZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgaWYgKCF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB2YXIgcnMgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICAgIGlmICh0cy5uZWVkVHJhbnNmb3JtIHx8IHJzLm5lZWRSZWFkYWJsZSB8fCBycy5sZW5ndGggPCBycy5oaWdoV2F0ZXJNYXJrKSB0aGlzLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspO1xuICB9XG59O1xuXG4vLyBEb2Vzbid0IG1hdHRlciB3aGF0IHRoZSBhcmdzIGFyZSBoZXJlLlxuLy8gX3RyYW5zZm9ybSBkb2VzIGFsbCB0aGUgd29yay5cbi8vIFRoYXQgd2UgZ290IGhlcmUgbWVhbnMgdGhhdCB0aGUgcmVhZGFibGUgc2lkZSB3YW50cyBtb3JlIGRhdGEuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG5cbiAgaWYgKHRzLndyaXRlY2h1bmsgIT09IG51bGwgJiYgdHMud3JpdGVjYiAmJiAhdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdHMudHJhbnNmb3JtaW5nID0gdHJ1ZTtcbiAgICB0aGlzLl90cmFuc2Zvcm0odHMud3JpdGVjaHVuaywgdHMud3JpdGVlbmNvZGluZywgdHMuYWZ0ZXJUcmFuc2Zvcm0pO1xuICB9IGVsc2Uge1xuICAgIC8vIG1hcmsgdGhhdCB3ZSBuZWVkIGEgdHJhbnNmb3JtLCBzbyB0aGF0IGFueSBkYXRhIHRoYXQgY29tZXMgaW5cbiAgICAvLyB3aWxsIGdldCBwcm9jZXNzZWQsIG5vdyB0aGF0IHdlJ3ZlIGFza2VkIGZvciBpdC5cbiAgICB0cy5uZWVkVHJhbnNmb3JtID0gdHJ1ZTtcbiAgfVxufTtcblxuZnVuY3Rpb24gZG9uZShzdHJlYW0sIGVyKSB7XG4gIGlmIChlcikgcmV0dXJuIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcblxuICAvLyBpZiB0aGVyZSdzIG5vdGhpbmcgaW4gdGhlIHdyaXRlIGJ1ZmZlciwgdGhlbiB0aGF0IG1lYW5zXG4gIC8vIHRoYXQgbm90aGluZyBtb3JlIHdpbGwgZXZlciBiZSBwcm92aWRlZFxuICB2YXIgd3MgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciB0cyA9IHN0cmVhbS5fdHJhbnNmb3JtU3RhdGU7XG5cbiAgaWYgKHdzLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdjYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gd3MubGVuZ3RoICE9IDAnKTtcblxuICBpZiAodHMudHJhbnNmb3JtaW5nKSB0aHJvdyBuZXcgRXJyb3IoJ2NhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiBzdGlsbCB0cmFuc2Zvcm1pbmcnKTtcblxuICByZXR1cm4gc3RyZWFtLnB1c2gobnVsbCk7XG59IiwiLy8gQSBiaXQgc2ltcGxlciB0aGFuIHJlYWRhYmxlIHN0cmVhbXMuXG4vLyBJbXBsZW1lbnQgYW4gYXN5bmMgLl93cml0ZShjaHVuaywgZW5jb2RpbmcsIGNiKSwgYW5kIGl0J2xsIGhhbmRsZSBhbGxcbi8vIHRoZSBkcmFpbiBldmVudCBlbWlzc2lvbiBhbmQgYnVmZmVyaW5nLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gV3JpdGFibGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgcHJvY2Vzc05leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy1uZXh0aWNrLWFyZ3MnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGFzeW5jV3JpdGUgPSAhcHJvY2Vzcy5icm93c2VyICYmIFsndjAuMTAnLCAndjAuOS4nXS5pbmRleE9mKHByb2Nlc3MudmVyc2lvbi5zbGljZSgwLCA1KSkgPiAtMSA/IHNldEltbWVkaWF0ZSA6IHByb2Nlc3NOZXh0VGljaztcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5Xcml0YWJsZS5Xcml0YWJsZVN0YXRlID0gV3JpdGFibGVTdGF0ZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGludGVybmFsVXRpbCA9IHtcbiAgZGVwcmVjYXRlOiByZXF1aXJlKCd1dGlsLWRlcHJlY2F0ZScpXG59O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgU3RyZWFtO1xuKGZ1bmN0aW9uICgpIHtcbiAgdHJ5IHtcbiAgICBTdHJlYW0gPSByZXF1aXJlKCdzdCcgKyAncmVhbScpO1xuICB9IGNhdGNoIChfKSB7fSBmaW5hbGx5IHtcbiAgICBpZiAoIVN0cmVhbSkgU3RyZWFtID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuICB9XG59KSgpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbnV0aWwuaW5oZXJpdHMoV3JpdGFibGUsIFN0cmVhbSk7XG5cbmZ1bmN0aW9uIG5vcCgpIHt9XG5cbmZ1bmN0aW9uIFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhpcy5jaHVuayA9IGNodW5rO1xuICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHRoaXMuY2FsbGJhY2sgPSBjYjtcbiAgdGhpcy5uZXh0ID0gbnVsbDtcbn1cblxudmFyIER1cGxleDtcbmZ1bmN0aW9uIFdyaXRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnIHRvIGluZGljYXRlIHdoZXRoZXIgb3Igbm90IHRoaXMgc3RyZWFtXG4gIC8vIGNvbnRhaW5zIGJ1ZmZlcnMgb3Igb2JqZWN0cy5cbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG5cbiAgaWYgKHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleCkgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy53cml0YWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIHdyaXRlKCkgc3RhcnRzIHJldHVybmluZyBmYWxzZVxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIHRoYXQgd2UgYWx3YXlzIHJldHVybiBmYWxzZSBpZlxuICAvLyB0aGUgZW50aXJlIGJ1ZmZlciBpcyBub3QgZmx1c2hlZCBpbW1lZGlhdGVseSBvbiB3cml0ZSgpXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciBkZWZhdWx0SHdtID0gdGhpcy5vYmplY3RNb2RlID8gMTYgOiAxNiAqIDEwMjQ7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IGh3bSB8fCBod20gPT09IDAgPyBod20gOiBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfiB+dGhpcy5oaWdoV2F0ZXJNYXJrO1xuXG4gIHRoaXMubmVlZERyYWluID0gZmFsc2U7XG4gIC8vIGF0IHRoZSBzdGFydCBvZiBjYWxsaW5nIGVuZCgpXG4gIHRoaXMuZW5kaW5nID0gZmFsc2U7XG4gIC8vIHdoZW4gZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgcmV0dXJuZWRcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAvLyB3aGVuICdmaW5pc2gnIGlzIGVtaXR0ZWRcbiAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIHNob3VsZCB3ZSBkZWNvZGUgc3RyaW5ncyBpbnRvIGJ1ZmZlcnMgYmVmb3JlIHBhc3NpbmcgdG8gX3dyaXRlP1xuICAvLyB0aGlzIGlzIGhlcmUgc28gdGhhdCBzb21lIG5vZGUtY29yZSBzdHJlYW1zIGNhbiBvcHRpbWl6ZSBzdHJpbmdcbiAgLy8gaGFuZGxpbmcgYXQgYSBsb3dlciBsZXZlbC5cbiAgdmFyIG5vRGVjb2RlID0gb3B0aW9ucy5kZWNvZGVTdHJpbmdzID09PSBmYWxzZTtcbiAgdGhpcy5kZWNvZGVTdHJpbmdzID0gIW5vRGVjb2RlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIG5vdCBhbiBhY3R1YWwgYnVmZmVyIHdlIGtlZXAgdHJhY2sgb2YsIGJ1dCBhIG1lYXN1cmVtZW50XG4gIC8vIG9mIGhvdyBtdWNoIHdlJ3JlIHdhaXRpbmcgdG8gZ2V0IHB1c2hlZCB0byBzb21lIHVuZGVybHlpbmdcbiAgLy8gc29ja2V0IG9yIGZpbGUuXG4gIHRoaXMubGVuZ3RoID0gMDtcblxuICAvLyBhIGZsYWcgdG8gc2VlIHdoZW4gd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIHdyaXRlLlxuICB0aGlzLndyaXRpbmcgPSBmYWxzZTtcblxuICAvLyB3aGVuIHRydWUgYWxsIHdyaXRlcyB3aWxsIGJlIGJ1ZmZlcmVkIHVudGlsIC51bmNvcmsoKSBjYWxsXG4gIHRoaXMuY29ya2VkID0gMDtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyBhIGZsYWcgdG8ga25vdyBpZiB3ZSdyZSBwcm9jZXNzaW5nIHByZXZpb3VzbHkgYnVmZmVyZWQgaXRlbXMsIHdoaWNoXG4gIC8vIG1heSBjYWxsIHRoZSBfd3JpdGUoKSBjYWxsYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyB0aGF0IHdlIGRvbid0XG4gIC8vIGVuZCB1cCBpbiBhbiBvdmVybGFwcGVkIG9ud3JpdGUgc2l0dWF0aW9uLlxuICB0aGlzLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCdzIHBhc3NlZCB0byBfd3JpdGUoY2h1bmssY2IpXG4gIHRoaXMub253cml0ZSA9IGZ1bmN0aW9uIChlcikge1xuICAgIG9ud3JpdGUoc3RyZWFtLCBlcik7XG4gIH07XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQgdGhlIHVzZXIgc3VwcGxpZXMgdG8gd3JpdGUoY2h1bmssZW5jb2RpbmcsY2IpXG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG5cbiAgLy8gdGhlIGFtb3VudCB0aGF0IGlzIGJlaW5nIHdyaXR0ZW4gd2hlbiBfd3JpdGUgaXMgY2FsbGVkLlxuICB0aGlzLndyaXRlbGVuID0gMDtcblxuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIHRoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cbiAgLy8gbnVtYmVyIG9mIHBlbmRpbmcgdXNlci1zdXBwbGllZCB3cml0ZSBjYWxsYmFja3NcbiAgLy8gdGhpcyBtdXN0IGJlIDAgYmVmb3JlICdmaW5pc2gnIGNhbiBiZSBlbWl0dGVkXG4gIHRoaXMucGVuZGluZ2NiID0gMDtcblxuICAvLyBlbWl0IHByZWZpbmlzaCBpZiB0aGUgb25seSB0aGluZyB3ZSdyZSB3YWl0aW5nIGZvciBpcyBfd3JpdGUgY2JzXG4gIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHN5bmNocm9ub3VzIFRyYW5zZm9ybSBzdHJlYW1zXG4gIHRoaXMucHJlZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBUcnVlIGlmIHRoZSBlcnJvciB3YXMgYWxyZWFkeSBlbWl0dGVkIGFuZCBzaG91bGQgbm90IGJlIHRocm93biBhZ2FpblxuICB0aGlzLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuXG4gIC8vIGNvdW50IGJ1ZmZlcmVkIHJlcXVlc3RzXG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuXG4gIC8vIGNyZWF0ZSB0aGUgdHdvIG9iamVjdHMgbmVlZGVkIHRvIHN0b3JlIHRoZSBjb3JrZWQgcmVxdWVzdHNcbiAgLy8gdGhleSBhcmUgbm90IGEgbGlua2VkIGxpc3QsIGFzIG5vIG5ldyBlbGVtZW50cyBhcmUgaW5zZXJ0ZWQgaW4gdGhlcmVcbiAgdGhpcy5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBuZXcgQ29ya2VkUmVxdWVzdCh0aGlzKTtcbiAgdGhpcy5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dCA9IG5ldyBDb3JrZWRSZXF1ZXN0KHRoaXMpO1xufVxuXG5Xcml0YWJsZVN0YXRlLnByb3RvdHlwZS5nZXRCdWZmZXIgPSBmdW5jdGlvbiB3cml0YWJsZVN0YXRlR2V0QnVmZmVyKCkge1xuICB2YXIgY3VycmVudCA9IHRoaXMuYnVmZmVyZWRSZXF1ZXN0O1xuICB2YXIgb3V0ID0gW107XG4gIHdoaWxlIChjdXJyZW50KSB7XG4gICAgb3V0LnB1c2goY3VycmVudCk7XG4gICAgY3VycmVudCA9IGN1cnJlbnQubmV4dDtcbiAgfVxuICByZXR1cm4gb3V0O1xufTtcblxuKGZ1bmN0aW9uICgpIHtcbiAgdHJ5IHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUsICdidWZmZXInLCB7XG4gICAgICBnZXQ6IGludGVybmFsVXRpbC5kZXByZWNhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRCdWZmZXIoKTtcbiAgICAgIH0sICdfd3JpdGFibGVTdGF0ZS5idWZmZXIgaXMgZGVwcmVjYXRlZC4gVXNlIF93cml0YWJsZVN0YXRlLmdldEJ1ZmZlciAnICsgJ2luc3RlYWQuJylcbiAgICB9KTtcbiAgfSBjYXRjaCAoXykge31cbn0pKCk7XG5cbnZhciBEdXBsZXg7XG5mdW5jdGlvbiBXcml0YWJsZShvcHRpb25zKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgLy8gV3JpdGFibGUgY3RvciBpcyBhcHBsaWVkIHRvIER1cGxleGVzLCB0aG91Z2ggdGhleSdyZSBub3RcbiAgLy8gaW5zdGFuY2VvZiBXcml0YWJsZSwgdGhleSdyZSBpbnN0YW5jZW9mIFJlYWRhYmxlLlxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgV3JpdGFibGUpICYmICEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHJldHVybiBuZXcgV3JpdGFibGUob3B0aW9ucyk7XG5cbiAgdGhpcy5fd3JpdGFibGVTdGF0ZSA9IG5ldyBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeS5cbiAgdGhpcy53cml0YWJsZSA9IHRydWU7XG5cbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMud3JpdGUgPT09ICdmdW5jdGlvbicpIHRoaXMuX3dyaXRlID0gb3B0aW9ucy53cml0ZTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy53cml0ZXYgPT09ICdmdW5jdGlvbicpIHRoaXMuX3dyaXRldiA9IG9wdGlvbnMud3JpdGV2O1xuICB9XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE90aGVyd2lzZSBwZW9wbGUgY2FuIHBpcGUgV3JpdGFibGUgc3RyZWFtcywgd2hpY2ggaXMganVzdCB3cm9uZy5cbldyaXRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdDYW5ub3QgcGlwZS4gTm90IHJlYWRhYmxlLicpKTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLCBjYikge1xuICB2YXIgZXIgPSBuZXcgRXJyb3IoJ3dyaXRlIGFmdGVyIGVuZCcpO1xuICAvLyBUT0RPOiBkZWZlciBlcnJvciBldmVudHMgY29uc2lzdGVudGx5IGV2ZXJ5d2hlcmUsIG5vdCBqdXN0IHRoZSBjYlxuICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIHByb2Nlc3NOZXh0VGljayhjYiwgZXIpO1xufVxuXG4vLyBJZiB3ZSBnZXQgc29tZXRoaW5nIHRoYXQgaXMgbm90IGEgYnVmZmVyLCBzdHJpbmcsIG51bGwsIG9yIHVuZGVmaW5lZCxcbi8vIGFuZCB3ZSdyZSBub3QgaW4gb2JqZWN0TW9kZSwgdGhlbiB0aGF0J3MgYW4gZXJyb3IuXG4vLyBPdGhlcndpc2Ugc3RyZWFtIGNodW5rcyBhcmUgYWxsIGNvbnNpZGVyZWQgdG8gYmUgb2YgbGVuZ3RoPTEsIGFuZCB0aGVcbi8vIHdhdGVybWFya3MgZGV0ZXJtaW5lIGhvdyBtYW55IG9iamVjdHMgdG8ga2VlcCBpbiB0aGUgYnVmZmVyLCByYXRoZXIgdGhhblxuLy8gaG93IG1hbnkgYnl0ZXMgb3IgY2hhcmFjdGVycy5cbmZ1bmN0aW9uIHZhbGlkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGNiKSB7XG4gIHZhciB2YWxpZCA9IHRydWU7XG5cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoY2h1bmspICYmIHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycgJiYgY2h1bmsgIT09IG51bGwgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCAmJiAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIHZhciBlciA9IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmsnKTtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgcHJvY2Vzc05leHRUaWNrKGNiLCBlcik7XG4gICAgdmFsaWQgPSBmYWxzZTtcbiAgfVxuICByZXR1cm4gdmFsaWQ7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG4gIHZhciByZXQgPSBmYWxzZTtcblxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSkgZW5jb2RpbmcgPSAnYnVmZmVyJztlbHNlIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuXG4gIGlmICh0eXBlb2YgY2IgIT09ICdmdW5jdGlvbicpIGNiID0gbm9wO1xuXG4gIGlmIChzdGF0ZS5lbmRlZCkgd3JpdGVBZnRlckVuZCh0aGlzLCBjYik7ZWxzZSBpZiAodmFsaWRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGNiKSkge1xuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHJldCA9IHdyaXRlT3JCdWZmZXIodGhpcywgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5jb3JrID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIHN0YXRlLmNvcmtlZCsrO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLnVuY29yayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAoc3RhdGUuY29ya2VkKSB7XG4gICAgc3RhdGUuY29ya2VkLS07XG5cbiAgICBpZiAoIXN0YXRlLndyaXRpbmcgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuZmluaXNoZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSBjbGVhckJ1ZmZlcih0aGlzLCBzdGF0ZSk7XG4gIH1cbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5zZXREZWZhdWx0RW5jb2RpbmcgPSBmdW5jdGlvbiBzZXREZWZhdWx0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgLy8gbm9kZTo6UGFyc2VFbmNvZGluZygpIHJlcXVpcmVzIGxvd2VyIGNhc2UuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnKSBlbmNvZGluZyA9IGVuY29kaW5nLnRvTG93ZXJDYXNlKCk7XG4gIGlmICghKFsnaGV4JywgJ3V0ZjgnLCAndXRmLTgnLCAnYXNjaWknLCAnYmluYXJ5JywgJ2Jhc2U2NCcsICd1Y3MyJywgJ3Vjcy0yJywgJ3V0ZjE2bGUnLCAndXRmLTE2bGUnLCAncmF3J10uaW5kZXhPZigoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKSkgPiAtMSkpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVmYXVsdEVuY29kaW5nID0gZW5jb2Rpbmc7XG59O1xuXG5mdW5jdGlvbiBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKSB7XG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiBzdGF0ZS5kZWNvZGVTdHJpbmdzICE9PSBmYWxzZSAmJiB0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgY2h1bmsgPSBuZXcgQnVmZmVyKGNodW5rLCBlbmNvZGluZyk7XG4gIH1cbiAgcmV0dXJuIGNodW5rO1xufVxuXG4vLyBpZiB3ZSdyZSBhbHJlYWR5IHdyaXRpbmcgc29tZXRoaW5nLCB0aGVuIGp1c3QgcHV0IHRoaXNcbi8vIGluIHRoZSBxdWV1ZSwgYW5kIHdhaXQgb3VyIHR1cm4uICBPdGhlcndpc2UsIGNhbGwgX3dyaXRlXG4vLyBJZiB3ZSByZXR1cm4gZmFsc2UsIHRoZW4gd2UgbmVlZCBhIGRyYWluIGV2ZW50LCBzbyBzZXQgdGhhdCBmbGFnLlxuZnVuY3Rpb24gd3JpdGVPckJ1ZmZlcihzdHJlYW0sIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNodW5rID0gZGVjb2RlQ2h1bmsoc3RhdGUsIGNodW5rLCBlbmNvZGluZyk7XG5cbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpIGVuY29kaW5nID0gJ2J1ZmZlcic7XG4gIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcblxuICBzdGF0ZS5sZW5ndGggKz0gbGVuO1xuXG4gIHZhciByZXQgPSBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrO1xuICAvLyB3ZSBtdXN0IGVuc3VyZSB0aGF0IHByZXZpb3VzIG5lZWREcmFpbiB3aWxsIG5vdCBiZSByZXNldCB0byBmYWxzZS5cbiAgaWYgKCFyZXQpIHN0YXRlLm5lZWREcmFpbiA9IHRydWU7XG5cbiAgaWYgKHN0YXRlLndyaXRpbmcgfHwgc3RhdGUuY29ya2VkKSB7XG4gICAgdmFyIGxhc3QgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBuZXcgV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYik7XG4gICAgaWYgKGxhc3QpIHtcbiAgICAgIGxhc3QubmV4dCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfVxuICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ICs9IDE7XG4gIH0gZWxzZSB7XG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgd3JpdGV2LCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgc3RhdGUud3JpdGVsZW4gPSBsZW47XG4gIHN0YXRlLndyaXRlY2IgPSBjYjtcbiAgc3RhdGUud3JpdGluZyA9IHRydWU7XG4gIHN0YXRlLnN5bmMgPSB0cnVlO1xuICBpZiAod3JpdGV2KSBzdHJlYW0uX3dyaXRldihjaHVuaywgc3RhdGUub253cml0ZSk7ZWxzZSBzdHJlYW0uX3dyaXRlKGNodW5rLCBlbmNvZGluZywgc3RhdGUub253cml0ZSk7XG4gIHN0YXRlLnN5bmMgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYikge1xuICAtLXN0YXRlLnBlbmRpbmdjYjtcbiAgaWYgKHN5bmMpIHByb2Nlc3NOZXh0VGljayhjYiwgZXIpO2Vsc2UgY2IoZXIpO1xuXG4gIHN0cmVhbS5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSB0cnVlO1xuICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSkge1xuICBzdGF0ZS53cml0aW5nID0gZmFsc2U7XG4gIHN0YXRlLndyaXRlY2IgPSBudWxsO1xuICBzdGF0ZS5sZW5ndGggLT0gc3RhdGUud3JpdGVsZW47XG4gIHN0YXRlLndyaXRlbGVuID0gMDtcbn1cblxuZnVuY3Rpb24gb253cml0ZShzdHJlYW0sIGVyKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHN5bmMgPSBzdGF0ZS5zeW5jO1xuICB2YXIgY2IgPSBzdGF0ZS53cml0ZWNiO1xuXG4gIG9ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSk7XG5cbiAgaWYgKGVyKSBvbndyaXRlRXJyb3Ioc3RyZWFtLCBzdGF0ZSwgc3luYywgZXIsIGNiKTtlbHNlIHtcbiAgICAvLyBDaGVjayBpZiB3ZSdyZSBhY3R1YWxseSByZWFkeSB0byBmaW5pc2gsIGJ1dCBkb24ndCBlbWl0IHlldFxuICAgIHZhciBmaW5pc2hlZCA9IG5lZWRGaW5pc2goc3RhdGUpO1xuXG4gICAgaWYgKCFmaW5pc2hlZCAmJiAhc3RhdGUuY29ya2VkICYmICFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nICYmIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCkge1xuICAgICAgY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuXG4gICAgaWYgKHN5bmMpIHtcbiAgICAgIC8qPHJlcGxhY2VtZW50PiovXG4gICAgICBhc3luY1dyaXRlKGFmdGVyV3JpdGUsIHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYik7XG4gICAgICAvKjwvcmVwbGFjZW1lbnQ+Ki9cbiAgICB9IGVsc2Uge1xuICAgICAgICBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYik7XG4gICAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZCkgb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpO1xuICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgY2IoKTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5cbi8vIE11c3QgZm9yY2UgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIG9uIG5leHRUaWNrLCBzbyB0aGF0IHdlIGRvbid0XG4vLyBlbWl0ICdkcmFpbicgYmVmb3JlIHRoZSB3cml0ZSgpIGNvbnN1bWVyIGdldHMgdGhlICdmYWxzZScgcmV0dXJuXG4vLyB2YWx1ZSwgYW5kIGhhcyBhIGNoYW5jZSB0byBhdHRhY2ggYSAnZHJhaW4nIGxpc3RlbmVyLlxuZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5uZWVkRHJhaW4pIHtcbiAgICBzdGF0ZS5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZHJhaW4nKTtcbiAgfVxufVxuXG4vLyBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiB0aGUgYnVmZmVyIHdhaXRpbmcsIHRoZW4gcHJvY2VzcyBpdFxuZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSkge1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgdmFyIGVudHJ5ID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0O1xuXG4gIGlmIChzdHJlYW0uX3dyaXRldiAmJiBlbnRyeSAmJiBlbnRyeS5uZXh0KSB7XG4gICAgLy8gRmFzdCBjYXNlLCB3cml0ZSBldmVyeXRoaW5nIHVzaW5nIF93cml0ZXYoKVxuICAgIHZhciBsID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQ7XG4gICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheShsKTtcbiAgICB2YXIgaG9sZGVyID0gc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlO1xuICAgIGhvbGRlci5lbnRyeSA9IGVudHJ5O1xuXG4gICAgdmFyIGNvdW50ID0gMDtcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIGJ1ZmZlcltjb3VudF0gPSBlbnRyeTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIGNvdW50ICs9IDE7XG4gICAgfVxuXG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCB0cnVlLCBzdGF0ZS5sZW5ndGgsIGJ1ZmZlciwgJycsIGhvbGRlci5maW5pc2gpO1xuXG4gICAgLy8gZG9Xcml0ZSBpcyBhbHdheXMgYXN5bmMsIGRlZmVyIHRoZXNlIHRvIHNhdmUgYSBiaXQgb2YgdGltZVxuICAgIC8vIGFzIHRoZSBob3QgcGF0aCBlbmRzIHdpdGggZG9Xcml0ZVxuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IGhvbGRlci5uZXh0O1xuICAgIGhvbGRlci5uZXh0ID0gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICAvLyBTbG93IGNhc2UsIHdyaXRlIGNodW5rcyBvbmUtYnktb25lXG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICB2YXIgY2h1bmsgPSBlbnRyeS5jaHVuaztcbiAgICAgIHZhciBlbmNvZGluZyA9IGVudHJ5LmVuY29kaW5nO1xuICAgICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmFsc2UsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgICAvLyBpZiB3ZSBkaWRuJ3QgY2FsbCB0aGUgb253cml0ZSBpbW1lZGlhdGVseSwgdGhlblxuICAgICAgLy8gaXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIHdhaXQgdW50aWwgaXQgZG9lcy5cbiAgICAgIC8vIGFsc28sIHRoYXQgbWVhbnMgdGhhdCB0aGUgY2h1bmsgYW5kIGNiIGFyZSBjdXJyZW50bHlcbiAgICAgIC8vIGJlaW5nIHByb2Nlc3NlZCwgc28gbW92ZSB0aGUgYnVmZmVyIGNvdW50ZXIgcGFzdCB0aGVtLlxuICAgICAgaWYgKHN0YXRlLndyaXRpbmcpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVudHJ5ID09PSBudWxsKSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgfVxuXG4gIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ID0gMDtcbiAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID0gZW50cnk7XG4gIHN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcbn1cblxuV3JpdGFibGUucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLl93cml0ZXYgPSBudWxsO1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAodHlwZW9mIGNodW5rID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBjaHVuaztcbiAgICBjaHVuayA9IG51bGw7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKGNodW5rICE9PSBudWxsICYmIGNodW5rICE9PSB1bmRlZmluZWQpIHRoaXMud3JpdGUoY2h1bmssIGVuY29kaW5nKTtcblxuICAvLyAuZW5kKCkgZnVsbHkgdW5jb3Jrc1xuICBpZiAoc3RhdGUuY29ya2VkKSB7XG4gICAgc3RhdGUuY29ya2VkID0gMTtcbiAgICB0aGlzLnVuY29yaygpO1xuICB9XG5cbiAgLy8gaWdub3JlIHVubmVjZXNzYXJ5IGVuZCgpIGNhbGxzLlxuICBpZiAoIXN0YXRlLmVuZGluZyAmJiAhc3RhdGUuZmluaXNoZWQpIGVuZFdyaXRhYmxlKHRoaXMsIHN0YXRlLCBjYik7XG59O1xuXG5mdW5jdGlvbiBuZWVkRmluaXNoKHN0YXRlKSB7XG4gIHJldHVybiBzdGF0ZS5lbmRpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9PT0gbnVsbCAmJiAhc3RhdGUuZmluaXNoZWQgJiYgIXN0YXRlLndyaXRpbmc7XG59XG5cbmZ1bmN0aW9uIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucHJlZmluaXNoZWQpIHtcbiAgICBzdGF0ZS5wcmVmaW5pc2hlZCA9IHRydWU7XG4gICAgc3RyZWFtLmVtaXQoJ3ByZWZpbmlzaCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpIHtcbiAgdmFyIG5lZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcbiAgaWYgKG5lZWQpIHtcbiAgICBpZiAoc3RhdGUucGVuZGluZ2NiID09PSAwKSB7XG4gICAgICBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG4gICAgICBzdGF0ZS5maW5pc2hlZCA9IHRydWU7XG4gICAgICBzdHJlYW0uZW1pdCgnZmluaXNoJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5lZWQ7XG59XG5cbmZ1bmN0aW9uIGVuZFdyaXRhYmxlKHN0cmVhbSwgc3RhdGUsIGNiKSB7XG4gIHN0YXRlLmVuZGluZyA9IHRydWU7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xuICBpZiAoY2IpIHtcbiAgICBpZiAoc3RhdGUuZmluaXNoZWQpIHByb2Nlc3NOZXh0VGljayhjYik7ZWxzZSBzdHJlYW0ub25jZSgnZmluaXNoJywgY2IpO1xuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgc3RyZWFtLndyaXRhYmxlID0gZmFsc2U7XG59XG5cbi8vIEl0IHNlZW1zIGEgbGlua2VkIGxpc3QgYnV0IGl0IGlzIG5vdFxuLy8gdGhlcmUgd2lsbCBiZSBvbmx5IDIgb2YgdGhlc2UgZm9yIGVhY2ggc3RyZWFtXG5mdW5jdGlvbiBDb3JrZWRSZXF1ZXN0KHN0YXRlKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgdGhpcy5uZXh0ID0gbnVsbDtcbiAgdGhpcy5lbnRyeSA9IG51bGw7XG5cbiAgdGhpcy5maW5pc2ggPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgdmFyIGVudHJ5ID0gX3RoaXMuZW50cnk7XG4gICAgX3RoaXMuZW50cnkgPSBudWxsO1xuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgICAgIGNiKGVycik7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgfVxuICAgIGlmIChzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUpIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZS5uZXh0ID0gX3RoaXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IF90aGlzO1xuICAgIH1cbiAgfTtcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cblxuZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShhcmcpO1xuICB9XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gQnVmZmVyLmlzQnVmZmVyO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbmlmICghcHJvY2Vzcy52ZXJzaW9uIHx8XG4gICAgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YwLicpID09PSAwIHx8XG4gICAgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YxLicpID09PSAwICYmIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MS44LicpICE9PSAwKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gbmV4dFRpY2s7XG59IGVsc2Uge1xuICBtb2R1bGUuZXhwb3J0cyA9IHByb2Nlc3MubmV4dFRpY2s7XG59XG5cbmZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgdmFyIGkgPSAwO1xuICB3aGlsZSAoaSA8IGFyZ3MubGVuZ3RoKSB7XG4gICAgYXJnc1tpKytdID0gYXJndW1lbnRzW2ldO1xuICB9XG4gIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrKCkge1xuICAgIGZuLmFwcGx5KG51bGwsIGFyZ3MpO1xuICB9KTtcbn1cbiIsIlxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlcHJlY2F0ZTtcblxuLyoqXG4gKiBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuICogUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLm5vRGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLnRocm93RGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gZGVwcmVjYXRlZCBmdW5jdGlvbnNcbiAqIHdpbGwgdGhyb3cgYW4gRXJyb3Igd2hlbiBpbnZva2VkLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudHJhY2VEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCBpbnZva2UgYGNvbnNvbGUudHJhY2UoKWAgaW5zdGVhZCBvZiBgY29uc29sZS5lcnJvcigpYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBkZXByZWNhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgLSB0aGUgc3RyaW5nIHRvIHByaW50IHRvIHRoZSBjb25zb2xlIHdoZW4gYGZuYCBpcyBpbnZva2VkXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IGEgbmV3IFwiZGVwcmVjYXRlZFwiIHZlcnNpb24gb2YgYGZuYFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZXByZWNhdGUgKGZuLCBtc2cpIHtcbiAgaWYgKGNvbmZpZygnbm9EZXByZWNhdGlvbicpKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAoY29uZmlnKCd0aHJvd0RlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKGNvbmZpZygndHJhY2VEZXByZWNhdGlvbicpKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2Fybihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgYGxvY2FsU3RvcmFnZWAgZm9yIGJvb2xlYW4gdmFsdWVzIGZvciB0aGUgZ2l2ZW4gYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGNvbmZpZyAobmFtZSkge1xuICAvLyBhY2Nlc3NpbmcgZ2xvYmFsLmxvY2FsU3RvcmFnZSBjYW4gdHJpZ2dlciBhIERPTUV4Y2VwdGlvbiBpbiBzYW5kYm94ZWQgaWZyYW1lc1xuICB0cnkge1xuICAgIGlmICghZ2xvYmFsLmxvY2FsU3RvcmFnZSkgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB2YWwgPSBnbG9iYWwubG9jYWxTdG9yYWdlW25hbWVdO1xuICBpZiAobnVsbCA9PSB2YWwpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJztcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIilcbiIsInZhciBTdHJlYW0gPSAoZnVuY3Rpb24gKCl7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHJlcXVpcmUoJ3N0JyArICdyZWFtJyk7IC8vIGhhY2sgdG8gZml4IGEgY2lyY3VsYXIgZGVwZW5kZW5jeSBpc3N1ZSB3aGVuIHVzZWQgd2l0aCBicm93c2VyaWZ5XG4gIH0gY2F0Y2goXyl7fVxufSgpKTtcbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fcmVhZGFibGUuanMnKTtcbmV4cG9ydHMuU3RyZWFtID0gU3RyZWFtIHx8IGV4cG9ydHM7XG5leHBvcnRzLlJlYWRhYmxlID0gZXhwb3J0cztcbmV4cG9ydHMuV3JpdGFibGUgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzJyk7XG5leHBvcnRzLkR1cGxleCA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fZHVwbGV4LmpzJyk7XG5leHBvcnRzLlRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzJyk7XG5leHBvcnRzLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcycpO1xuXG5pZiAoIXByb2Nlc3MuYnJvd3NlciAmJiBwcm9jZXNzLmVudi5SRUFEQUJMRV9TVFJFQU0gPT09ICdkaXNhYmxlJyAmJiBTdHJlYW0pIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiKVxuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9saWIvX3N0cmVhbV93cml0YWJsZS5qc1wiKVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtO1xuXG52YXIgRUUgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG5pbmhlcml0cyhTdHJlYW0sIEVFKTtcblN0cmVhbS5SZWFkYWJsZSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS5qcycpO1xuU3RyZWFtLldyaXRhYmxlID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3dyaXRhYmxlLmpzJyk7XG5TdHJlYW0uRHVwbGV4ID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL2R1cGxleC5qcycpO1xuU3RyZWFtLlRyYW5zZm9ybSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanMnKTtcblN0cmVhbS5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qcycpO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjQueFxuU3RyZWFtLlN0cmVhbSA9IFN0cmVhbTtcblxuXG5cbi8vIG9sZC1zdHlsZSBzdHJlYW1zLiAgTm90ZSB0aGF0IHRoZSBwaXBlIG1ldGhvZCAodGhlIG9ubHkgcmVsZXZhbnRcbi8vIHBhcnQgb2YgdGhpcyBjbGFzcykgaXMgb3ZlcnJpZGRlbiBpbiB0aGUgUmVhZGFibGUgY2xhc3MuXG5cbmZ1bmN0aW9uIFN0cmVhbSgpIHtcbiAgRUUuY2FsbCh0aGlzKTtcbn1cblxuU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oZGVzdCwgb3B0aW9ucykge1xuICB2YXIgc291cmNlID0gdGhpcztcblxuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBpZiAoZGVzdC53cml0YWJsZSkge1xuICAgICAgaWYgKGZhbHNlID09PSBkZXN0LndyaXRlKGNodW5rKSAmJiBzb3VyY2UucGF1c2UpIHtcbiAgICAgICAgc291cmNlLnBhdXNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc291cmNlLm9uKCdkYXRhJywgb25kYXRhKTtcblxuICBmdW5jdGlvbiBvbmRyYWluKCkge1xuICAgIGlmIChzb3VyY2UucmVhZGFibGUgJiYgc291cmNlLnJlc3VtZSkge1xuICAgICAgc291cmNlLnJlc3VtZSgpO1xuICAgIH1cbiAgfVxuXG4gIGRlc3Qub24oJ2RyYWluJywgb25kcmFpbik7XG5cbiAgLy8gSWYgdGhlICdlbmQnIG9wdGlvbiBpcyBub3Qgc3VwcGxpZWQsIGRlc3QuZW5kKCkgd2lsbCBiZSBjYWxsZWQgd2hlblxuICAvLyBzb3VyY2UgZ2V0cyB0aGUgJ2VuZCcgb3IgJ2Nsb3NlJyBldmVudHMuICBPbmx5IGRlc3QuZW5kKCkgb25jZS5cbiAgaWYgKCFkZXN0Ll9pc1N0ZGlvICYmICghb3B0aW9ucyB8fCBvcHRpb25zLmVuZCAhPT0gZmFsc2UpKSB7XG4gICAgc291cmNlLm9uKCdlbmQnLCBvbmVuZCk7XG4gICAgc291cmNlLm9uKCdjbG9zZScsIG9uY2xvc2UpO1xuICB9XG5cbiAgdmFyIGRpZE9uRW5kID0gZmFsc2U7XG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgaWYgKGRpZE9uRW5kKSByZXR1cm47XG4gICAgZGlkT25FbmQgPSB0cnVlO1xuXG4gICAgaWYgKHR5cGVvZiBkZXN0LmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIGRlc3QuZGVzdHJveSgpO1xuICB9XG5cbiAgLy8gZG9uJ3QgbGVhdmUgZGFuZ2xpbmcgcGlwZXMgd2hlbiB0aGVyZSBhcmUgZXJyb3JzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgY2xlYW51cCgpO1xuICAgIGlmIChFRS5saXN0ZW5lckNvdW50KHRoaXMsICdlcnJvcicpID09PSAwKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkIHN0cmVhbSBlcnJvciBpbiBwaXBlLlxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZXJyb3InLCBvbmVycm9yKTtcbiAgZGVzdC5vbignZXJyb3InLCBvbmVycm9yKTtcblxuICAvLyByZW1vdmUgYWxsIHRoZSBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZXJlIGFkZGVkLlxuICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBjbGVhbnVwKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuICB9XG5cbiAgc291cmNlLm9uKCdlbmQnLCBjbGVhbnVwKTtcbiAgc291cmNlLm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3Qub24oJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgZGVzdC5lbWl0KCdwaXBlJywgc291cmNlKTtcblxuICAvLyBBbGxvdyBmb3IgdW5peC1saWtlIHVzYWdlOiBBLnBpcGUoQikucGlwZShDKVxuICByZXR1cm4gZGVzdDtcbn07XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxudmFyIGlzQnVmZmVyRW5jb2RpbmcgPSBCdWZmZXIuaXNFbmNvZGluZ1xuICB8fCBmdW5jdGlvbihlbmNvZGluZykge1xuICAgICAgIHN3aXRjaCAoZW5jb2RpbmcgJiYgZW5jb2RpbmcudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgY2FzZSAnaGV4JzogY2FzZSAndXRmOCc6IGNhc2UgJ3V0Zi04JzogY2FzZSAnYXNjaWknOiBjYXNlICdiaW5hcnknOiBjYXNlICdiYXNlNjQnOiBjYXNlICd1Y3MyJzogY2FzZSAndWNzLTInOiBjYXNlICd1dGYxNmxlJzogY2FzZSAndXRmLTE2bGUnOiBjYXNlICdyYXcnOiByZXR1cm4gdHJ1ZTtcbiAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBmYWxzZTtcbiAgICAgICB9XG4gICAgIH1cblxuXG5mdW5jdGlvbiBhc3NlcnRFbmNvZGluZyhlbmNvZGluZykge1xuICBpZiAoZW5jb2RpbmcgJiYgIWlzQnVmZmVyRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpO1xuICB9XG59XG5cbi8vIFN0cmluZ0RlY29kZXIgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIGZvciBlZmZpY2llbnRseSBzcGxpdHRpbmcgYSBzZXJpZXMgb2Zcbi8vIGJ1ZmZlcnMgaW50byBhIHNlcmllcyBvZiBKUyBzdHJpbmdzIHdpdGhvdXQgYnJlYWtpbmcgYXBhcnQgbXVsdGktYnl0ZVxuLy8gY2hhcmFjdGVycy4gQ0VTVS04IGlzIGhhbmRsZWQgYXMgcGFydCBvZiB0aGUgVVRGLTggZW5jb2RpbmcuXG4vL1xuLy8gQFRPRE8gSGFuZGxpbmcgYWxsIGVuY29kaW5ncyBpbnNpZGUgYSBzaW5nbGUgb2JqZWN0IG1ha2VzIGl0IHZlcnkgZGlmZmljdWx0XG4vLyB0byByZWFzb24gYWJvdXQgdGhpcyBjb2RlLCBzbyBpdCBzaG91bGQgYmUgc3BsaXQgdXAgaW4gdGhlIGZ1dHVyZS5cbi8vIEBUT0RPIFRoZXJlIHNob3VsZCBiZSBhIHV0Zjgtc3RyaWN0IGVuY29kaW5nIHRoYXQgcmVqZWN0cyBpbnZhbGlkIFVURi04IGNvZGVcbi8vIHBvaW50cyBhcyB1c2VkIGJ5IENFU1UtOC5cbnZhciBTdHJpbmdEZWNvZGVyID0gZXhwb3J0cy5TdHJpbmdEZWNvZGVyID0gZnVuY3Rpb24oZW5jb2RpbmcpIHtcbiAgdGhpcy5lbmNvZGluZyA9IChlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWy1fXS8sICcnKTtcbiAgYXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpO1xuICBzd2l0Y2ggKHRoaXMuZW5jb2RpbmcpIHtcbiAgICBjYXNlICd1dGY4JzpcbiAgICAgIC8vIENFU1UtOCByZXByZXNlbnRzIGVhY2ggb2YgU3Vycm9nYXRlIFBhaXIgYnkgMy1ieXRlc1xuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgLy8gVVRGLTE2IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAyLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAyO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IHV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXI7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgLy8gQmFzZS02NCBzdG9yZXMgMyBieXRlcyBpbiA0IGNoYXJzLCBhbmQgcGFkcyB0aGUgcmVtYWluZGVyLlxuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMztcbiAgICAgIHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSBiYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aGlzLndyaXRlID0gcGFzc1Rocm91Z2hXcml0ZTtcbiAgICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEVub3VnaCBzcGFjZSB0byBzdG9yZSBhbGwgYnl0ZXMgb2YgYSBzaW5nbGUgY2hhcmFjdGVyLiBVVEYtOCBuZWVkcyA0XG4gIC8vIGJ5dGVzLCBidXQgQ0VTVS04IG1heSByZXF1aXJlIHVwIHRvIDYgKDMgYnl0ZXMgcGVyIHN1cnJvZ2F0ZSkuXG4gIHRoaXMuY2hhckJ1ZmZlciA9IG5ldyBCdWZmZXIoNik7XG4gIC8vIE51bWJlciBvZiBieXRlcyByZWNlaXZlZCBmb3IgdGhlIGN1cnJlbnQgaW5jb21wbGV0ZSBtdWx0aS1ieXRlIGNoYXJhY3Rlci5cbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSAwO1xuICAvLyBOdW1iZXIgb2YgYnl0ZXMgZXhwZWN0ZWQgZm9yIHRoZSBjdXJyZW50IGluY29tcGxldGUgbXVsdGktYnl0ZSBjaGFyYWN0ZXIuXG4gIHRoaXMuY2hhckxlbmd0aCA9IDA7XG59O1xuXG5cbi8vIHdyaXRlIGRlY29kZXMgdGhlIGdpdmVuIGJ1ZmZlciBhbmQgcmV0dXJucyBpdCBhcyBKUyBzdHJpbmcgdGhhdCBpc1xuLy8gZ3VhcmFudGVlZCB0byBub3QgY29udGFpbiBhbnkgcGFydGlhbCBtdWx0aS1ieXRlIGNoYXJhY3RlcnMuIEFueSBwYXJ0aWFsXG4vLyBjaGFyYWN0ZXIgZm91bmQgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyIGlzIGJ1ZmZlcmVkIHVwLCBhbmQgd2lsbCBiZVxuLy8gcmV0dXJuZWQgd2hlbiBjYWxsaW5nIHdyaXRlIGFnYWluIHdpdGggdGhlIHJlbWFpbmluZyBieXRlcy5cbi8vXG4vLyBOb3RlOiBDb252ZXJ0aW5nIGEgQnVmZmVyIGNvbnRhaW5pbmcgYW4gb3JwaGFuIHN1cnJvZ2F0ZSB0byBhIFN0cmluZ1xuLy8gY3VycmVudGx5IHdvcmtzLCBidXQgY29udmVydGluZyBhIFN0cmluZyB0byBhIEJ1ZmZlciAodmlhIGBuZXcgQnVmZmVyYCwgb3Jcbi8vIEJ1ZmZlciN3cml0ZSkgd2lsbCByZXBsYWNlIGluY29tcGxldGUgc3Vycm9nYXRlcyB3aXRoIHRoZSB1bmljb2RlXG4vLyByZXBsYWNlbWVudCBjaGFyYWN0ZXIuIFNlZSBodHRwczovL2NvZGVyZXZpZXcuY2hyb21pdW0ub3JnLzEyMTE3MzAwOS8gLlxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIGNoYXJTdHIgPSAnJztcbiAgLy8gaWYgb3VyIGxhc3Qgd3JpdGUgZW5kZWQgd2l0aCBhbiBpbmNvbXBsZXRlIG11bHRpYnl0ZSBjaGFyYWN0ZXJcbiAgd2hpbGUgKHRoaXMuY2hhckxlbmd0aCkge1xuICAgIC8vIGRldGVybWluZSBob3cgbWFueSByZW1haW5pbmcgYnl0ZXMgdGhpcyBidWZmZXIgaGFzIHRvIG9mZmVyIGZvciB0aGlzIGNoYXJcbiAgICB2YXIgYXZhaWxhYmxlID0gKGJ1ZmZlci5sZW5ndGggPj0gdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQpID9cbiAgICAgICAgdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQgOlxuICAgICAgICBidWZmZXIubGVuZ3RoO1xuXG4gICAgLy8gYWRkIHRoZSBuZXcgYnl0ZXMgdG8gdGhlIGNoYXIgYnVmZmVyXG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCB0aGlzLmNoYXJSZWNlaXZlZCwgMCwgYXZhaWxhYmxlKTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCArPSBhdmFpbGFibGU7XG5cbiAgICBpZiAodGhpcy5jaGFyUmVjZWl2ZWQgPCB0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAgIC8vIHN0aWxsIG5vdCBlbm91Z2ggY2hhcnMgaW4gdGhpcyBidWZmZXI/IHdhaXQgZm9yIG1vcmUgLi4uXG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGJ5dGVzIGJlbG9uZ2luZyB0byB0aGUgY3VycmVudCBjaGFyYWN0ZXIgZnJvbSB0aGUgYnVmZmVyXG4gICAgYnVmZmVyID0gYnVmZmVyLnNsaWNlKGF2YWlsYWJsZSwgYnVmZmVyLmxlbmd0aCk7XG5cbiAgICAvLyBnZXQgdGhlIGNoYXJhY3RlciB0aGF0IHdhcyBzcGxpdFxuICAgIGNoYXJTdHIgPSB0aGlzLmNoYXJCdWZmZXIuc2xpY2UoMCwgdGhpcy5jaGFyTGVuZ3RoKS50b1N0cmluZyh0aGlzLmVuY29kaW5nKTtcblxuICAgIC8vIENFU1UtODogbGVhZCBzdXJyb2dhdGUgKEQ4MDAtREJGRikgaXMgYWxzbyB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXJcbiAgICB2YXIgY2hhckNvZGUgPSBjaGFyU3RyLmNoYXJDb2RlQXQoY2hhclN0ci5sZW5ndGggLSAxKTtcbiAgICBpZiAoY2hhckNvZGUgPj0gMHhEODAwICYmIGNoYXJDb2RlIDw9IDB4REJGRikge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoICs9IHRoaXMuc3Vycm9nYXRlU2l6ZTtcbiAgICAgIGNoYXJTdHIgPSAnJztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB0aGlzLmNoYXJSZWNlaXZlZCA9IHRoaXMuY2hhckxlbmd0aCA9IDA7XG5cbiAgICAvLyBpZiB0aGVyZSBhcmUgbm8gbW9yZSBieXRlcyBpbiB0aGlzIGJ1ZmZlciwganVzdCBlbWl0IG91ciBjaGFyXG4gICAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBjaGFyU3RyO1xuICAgIH1cbiAgICBicmVhaztcbiAgfVxuXG4gIC8vIGRldGVybWluZSBhbmQgc2V0IGNoYXJMZW5ndGggLyBjaGFyUmVjZWl2ZWRcbiAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpO1xuXG4gIHZhciBlbmQgPSBidWZmZXIubGVuZ3RoO1xuICBpZiAodGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgLy8gYnVmZmVyIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlciBieXRlcyB3ZSBnb3RcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCwgZW5kKTtcbiAgICBlbmQgLT0gdGhpcy5jaGFyUmVjZWl2ZWQ7XG4gIH1cblxuICBjaGFyU3RyICs9IGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCBlbmQpO1xuXG4gIHZhciBlbmQgPSBjaGFyU3RyLmxlbmd0aCAtIDE7XG4gIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChlbmQpO1xuICAvLyBDRVNVLTg6IGxlYWQgc3Vycm9nYXRlIChEODAwLURCRkYpIGlzIGFsc28gdGhlIGluY29tcGxldGUgY2hhcmFjdGVyXG4gIGlmIChjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGKSB7XG4gICAgdmFyIHNpemUgPSB0aGlzLnN1cnJvZ2F0ZVNpemU7XG4gICAgdGhpcy5jaGFyTGVuZ3RoICs9IHNpemU7XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgKz0gc2l6ZTtcbiAgICB0aGlzLmNoYXJCdWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIHNpemUsIDAsIHNpemUpO1xuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgMCwgMCwgc2l6ZSk7XG4gICAgcmV0dXJuIGNoYXJTdHIuc3Vic3RyaW5nKDAsIGVuZCk7XG4gIH1cblxuICAvLyBvciBqdXN0IGVtaXQgdGhlIGNoYXJTdHJcbiAgcmV0dXJuIGNoYXJTdHI7XG59O1xuXG4vLyBkZXRlY3RJbmNvbXBsZXRlQ2hhciBkZXRlcm1pbmVzIGlmIHRoZXJlIGlzIGFuIGluY29tcGxldGUgVVRGLTggY2hhcmFjdGVyIGF0XG4vLyB0aGUgZW5kIG9mIHRoZSBnaXZlbiBidWZmZXIuIElmIHNvLCBpdCBzZXRzIHRoaXMuY2hhckxlbmd0aCB0byB0aGUgYnl0ZVxuLy8gbGVuZ3RoIHRoYXQgY2hhcmFjdGVyLCBhbmQgc2V0cyB0aGlzLmNoYXJSZWNlaXZlZCB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzXG4vLyB0aGF0IGFyZSBhdmFpbGFibGUgZm9yIHRoaXMgY2hhcmFjdGVyLlxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IGJ5dGVzIHdlIGhhdmUgdG8gY2hlY2sgYXQgdGhlIGVuZCBvZiB0aGlzIGJ1ZmZlclxuICB2YXIgaSA9IChidWZmZXIubGVuZ3RoID49IDMpID8gMyA6IGJ1ZmZlci5sZW5ndGg7XG5cbiAgLy8gRmlndXJlIG91dCBpZiBvbmUgb2YgdGhlIGxhc3QgaSBieXRlcyBvZiBvdXIgYnVmZmVyIGFubm91bmNlcyBhblxuICAvLyBpbmNvbXBsZXRlIGNoYXIuXG4gIGZvciAoOyBpID4gMDsgaS0tKSB7XG4gICAgdmFyIGMgPSBidWZmZXJbYnVmZmVyLmxlbmd0aCAtIGldO1xuXG4gICAgLy8gU2VlIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVVRGLTgjRGVzY3JpcHRpb25cblxuICAgIC8vIDExMFhYWFhYXG4gICAgaWYgKGkgPT0gMSAmJiBjID4+IDUgPT0gMHgwNikge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gMjtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIDExMTBYWFhYXG4gICAgaWYgKGkgPD0gMiAmJiBjID4+IDQgPT0gMHgwRSkge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gMztcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIDExMTEwWFhYXG4gICAgaWYgKGkgPD0gMyAmJiBjID4+IDMgPT0gMHgxRSkge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGk7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBpZiAoYnVmZmVyICYmIGJ1ZmZlci5sZW5ndGgpXG4gICAgcmVzID0gdGhpcy53cml0ZShidWZmZXIpO1xuXG4gIGlmICh0aGlzLmNoYXJSZWNlaXZlZCkge1xuICAgIHZhciBjciA9IHRoaXMuY2hhclJlY2VpdmVkO1xuICAgIHZhciBidWYgPSB0aGlzLmNoYXJCdWZmZXI7XG4gICAgdmFyIGVuYyA9IHRoaXMuZW5jb2Rpbmc7XG4gICAgcmVzICs9IGJ1Zi5zbGljZSgwLCBjcikudG9TdHJpbmcoZW5jKTtcbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBwYXNzVGhyb3VnaFdyaXRlKGJ1ZmZlcikge1xuICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xufVxuXG5mdW5jdGlvbiB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGJ1ZmZlci5sZW5ndGggJSAyO1xuICB0aGlzLmNoYXJMZW5ndGggPSB0aGlzLmNoYXJSZWNlaXZlZCA/IDIgOiAwO1xufVxuXG5mdW5jdGlvbiBiYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpIHtcbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSBidWZmZXIubGVuZ3RoICUgMztcbiAgdGhpcy5jaGFyTGVuZ3RoID0gdGhpcy5jaGFyUmVjZWl2ZWQgPyAzIDogMDtcbn1cbiIsInZhciBpbmRleE9mID0gcmVxdWlyZSgnaW5kZXhvZicpO1xuXG52YXIgT2JqZWN0X2tleXMgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgaWYgKE9iamVjdC5rZXlzKSByZXR1cm4gT2JqZWN0LmtleXMob2JqKVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgcmVzID0gW107XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHJlcy5wdXNoKGtleSlcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG59O1xuXG52YXIgZm9yRWFjaCA9IGZ1bmN0aW9uICh4cywgZm4pIHtcbiAgICBpZiAoeHMuZm9yRWFjaCkgcmV0dXJuIHhzLmZvckVhY2goZm4pXG4gICAgZWxzZSBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZuKHhzW2ldLCBpLCB4cyk7XG4gICAgfVxufTtcblxudmFyIGRlZmluZVByb3AgPSAoZnVuY3Rpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnXycsIHt9KTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iaiwgbmFtZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIG5hbWUsIHtcbiAgICAgICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICAgICAgICB9KVxuICAgICAgICB9O1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24ob2JqLCBuYW1lLCB2YWx1ZSkge1xuICAgICAgICAgICAgb2JqW25hbWVdID0gdmFsdWU7XG4gICAgICAgIH07XG4gICAgfVxufSgpKTtcblxudmFyIGdsb2JhbHMgPSBbJ0FycmF5JywgJ0Jvb2xlYW4nLCAnRGF0ZScsICdFcnJvcicsICdFdmFsRXJyb3InLCAnRnVuY3Rpb24nLFxuJ0luZmluaXR5JywgJ0pTT04nLCAnTWF0aCcsICdOYU4nLCAnTnVtYmVyJywgJ09iamVjdCcsICdSYW5nZUVycm9yJyxcbidSZWZlcmVuY2VFcnJvcicsICdSZWdFeHAnLCAnU3RyaW5nJywgJ1N5bnRheEVycm9yJywgJ1R5cGVFcnJvcicsICdVUklFcnJvcicsXG4nZGVjb2RlVVJJJywgJ2RlY29kZVVSSUNvbXBvbmVudCcsICdlbmNvZGVVUkknLCAnZW5jb2RlVVJJQ29tcG9uZW50JywgJ2VzY2FwZScsXG4nZXZhbCcsICdpc0Zpbml0ZScsICdpc05hTicsICdwYXJzZUZsb2F0JywgJ3BhcnNlSW50JywgJ3VuZGVmaW5lZCcsICd1bmVzY2FwZSddO1xuXG5mdW5jdGlvbiBDb250ZXh0KCkge31cbkNvbnRleHQucHJvdG90eXBlID0ge307XG5cbnZhciBTY3JpcHQgPSBleHBvcnRzLlNjcmlwdCA9IGZ1bmN0aW9uIE5vZGVTY3JpcHQgKGNvZGUpIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU2NyaXB0KSkgcmV0dXJuIG5ldyBTY3JpcHQoY29kZSk7XG4gICAgdGhpcy5jb2RlID0gY29kZTtcbn07XG5cblNjcmlwdC5wcm90b3R5cGUucnVuSW5Db250ZXh0ID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICBpZiAoIShjb250ZXh0IGluc3RhbmNlb2YgQ29udGV4dCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIm5lZWRzIGEgJ2NvbnRleHQnIGFyZ3VtZW50LlwiKTtcbiAgICB9XG4gICAgXG4gICAgdmFyIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuICAgIGlmICghaWZyYW1lLnN0eWxlKSBpZnJhbWUuc3R5bGUgPSB7fTtcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGlmcmFtZSk7XG4gICAgXG4gICAgdmFyIHdpbiA9IGlmcmFtZS5jb250ZW50V2luZG93O1xuICAgIHZhciB3RXZhbCA9IHdpbi5ldmFsLCB3RXhlY1NjcmlwdCA9IHdpbi5leGVjU2NyaXB0O1xuXG4gICAgaWYgKCF3RXZhbCAmJiB3RXhlY1NjcmlwdCkge1xuICAgICAgICAvLyB3aW4uZXZhbCgpIG1hZ2ljYWxseSBhcHBlYXJzIHdoZW4gdGhpcyBpcyBjYWxsZWQgaW4gSUU6XG4gICAgICAgIHdFeGVjU2NyaXB0LmNhbGwod2luLCAnbnVsbCcpO1xuICAgICAgICB3RXZhbCA9IHdpbi5ldmFsO1xuICAgIH1cbiAgICBcbiAgICBmb3JFYWNoKE9iamVjdF9rZXlzKGNvbnRleHQpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHdpbltrZXldID0gY29udGV4dFtrZXldO1xuICAgIH0pO1xuICAgIGZvckVhY2goZ2xvYmFscywgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoY29udGV4dFtrZXldKSB7XG4gICAgICAgICAgICB3aW5ba2V5XSA9IGNvbnRleHRba2V5XTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIFxuICAgIHZhciB3aW5LZXlzID0gT2JqZWN0X2tleXMod2luKTtcblxuICAgIHZhciByZXMgPSB3RXZhbC5jYWxsKHdpbiwgdGhpcy5jb2RlKTtcbiAgICBcbiAgICBmb3JFYWNoKE9iamVjdF9rZXlzKHdpbiksIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgLy8gQXZvaWQgY29weWluZyBjaXJjdWxhciBvYmplY3RzIGxpa2UgYHRvcGAgYW5kIGB3aW5kb3dgIGJ5IG9ubHlcbiAgICAgICAgLy8gdXBkYXRpbmcgZXhpc3RpbmcgY29udGV4dCBwcm9wZXJ0aWVzIG9yIG5ldyBwcm9wZXJ0aWVzIGluIHRoZSBgd2luYFxuICAgICAgICAvLyB0aGF0IHdhcyBvbmx5IGludHJvZHVjZWQgYWZ0ZXIgdGhlIGV2YWwuXG4gICAgICAgIGlmIChrZXkgaW4gY29udGV4dCB8fCBpbmRleE9mKHdpbktleXMsIGtleSkgPT09IC0xKSB7XG4gICAgICAgICAgICBjb250ZXh0W2tleV0gPSB3aW5ba2V5XTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgZm9yRWFjaChnbG9iYWxzLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIGlmICghKGtleSBpbiBjb250ZXh0KSkge1xuICAgICAgICAgICAgZGVmaW5lUHJvcChjb250ZXh0LCBrZXksIHdpbltrZXldKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIFxuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgICBcbiAgICByZXR1cm4gcmVzO1xufTtcblxuU2NyaXB0LnByb3RvdHlwZS5ydW5JblRoaXNDb250ZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBldmFsKHRoaXMuY29kZSk7IC8vIG1heWJlLi4uXG59O1xuXG5TY3JpcHQucHJvdG90eXBlLnJ1bkluTmV3Q29udGV4dCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgdmFyIGN0eCA9IFNjcmlwdC5jcmVhdGVDb250ZXh0KGNvbnRleHQpO1xuICAgIHZhciByZXMgPSB0aGlzLnJ1bkluQ29udGV4dChjdHgpO1xuXG4gICAgZm9yRWFjaChPYmplY3Rfa2V5cyhjdHgpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIGNvbnRleHRba2V5XSA9IGN0eFtrZXldO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlcztcbn07XG5cbmZvckVhY2goT2JqZWN0X2tleXMoU2NyaXB0LnByb3RvdHlwZSksIGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgZXhwb3J0c1tuYW1lXSA9IFNjcmlwdFtuYW1lXSA9IGZ1bmN0aW9uIChjb2RlKSB7XG4gICAgICAgIHZhciBzID0gU2NyaXB0KGNvZGUpO1xuICAgICAgICByZXR1cm4gc1tuYW1lXS5hcHBseShzLCBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIH07XG59KTtcblxuZXhwb3J0cy5jcmVhdGVTY3JpcHQgPSBmdW5jdGlvbiAoY29kZSkge1xuICAgIHJldHVybiBleHBvcnRzLlNjcmlwdChjb2RlKTtcbn07XG5cbmV4cG9ydHMuY3JlYXRlQ29udGV4dCA9IFNjcmlwdC5jcmVhdGVDb250ZXh0ID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgY29weSA9IG5ldyBDb250ZXh0KCk7XG4gICAgaWYodHlwZW9mIGNvbnRleHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGZvckVhY2goT2JqZWN0X2tleXMoY29udGV4dCksIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgIGNvcHlba2V5XSA9IGNvbnRleHRba2V5XTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBjb3B5O1xufTtcbiIsIlxudmFyIGluZGV4T2YgPSBbXS5pbmRleE9mO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGFyciwgb2JqKXtcbiAgaWYgKGluZGV4T2YpIHJldHVybiBhcnIuaW5kZXhPZihvYmopO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7ICsraSkge1xuICAgIGlmIChhcnJbaV0gPT09IG9iaikgcmV0dXJuIGk7XG4gIH1cbiAgcmV0dXJuIC0xO1xufTsiLCIvKipcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTQtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqICBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqICBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqICBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqICBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqL1xuXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG4gIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShmYWN0b3J5KSA6XG4gIChnbG9iYWwuSW1tdXRhYmxlID0gZmFjdG9yeSgpKTtcbn0odGhpcywgZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7dmFyIFNMSUNFJDAgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbiAgZnVuY3Rpb24gY3JlYXRlQ2xhc3MoY3Rvciwgc3VwZXJDbGFzcykge1xuICAgIGlmIChzdXBlckNsYXNzKSB7XG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcy5wcm90b3R5cGUpO1xuICAgIH1cbiAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3I7XG4gIH1cblxuICBmdW5jdGlvbiBJdGVyYWJsZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzSXRlcmFibGUodmFsdWUpID8gdmFsdWUgOiBTZXEodmFsdWUpO1xuICAgIH1cblxuXG4gIGNyZWF0ZUNsYXNzKEtleWVkSXRlcmFibGUsIEl0ZXJhYmxlKTtcbiAgICBmdW5jdGlvbiBLZXllZEl0ZXJhYmxlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNLZXllZCh2YWx1ZSkgPyB2YWx1ZSA6IEtleWVkU2VxKHZhbHVlKTtcbiAgICB9XG5cblxuICBjcmVhdGVDbGFzcyhJbmRleGVkSXRlcmFibGUsIEl0ZXJhYmxlKTtcbiAgICBmdW5jdGlvbiBJbmRleGVkSXRlcmFibGUodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc0luZGV4ZWQodmFsdWUpID8gdmFsdWUgOiBJbmRleGVkU2VxKHZhbHVlKTtcbiAgICB9XG5cblxuICBjcmVhdGVDbGFzcyhTZXRJdGVyYWJsZSwgSXRlcmFibGUpO1xuICAgIGZ1bmN0aW9uIFNldEl0ZXJhYmxlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNJdGVyYWJsZSh2YWx1ZSkgJiYgIWlzQXNzb2NpYXRpdmUodmFsdWUpID8gdmFsdWUgOiBTZXRTZXEodmFsdWUpO1xuICAgIH1cblxuXG5cbiAgZnVuY3Rpb24gaXNJdGVyYWJsZShtYXliZUl0ZXJhYmxlKSB7XG4gICAgcmV0dXJuICEhKG1heWJlSXRlcmFibGUgJiYgbWF5YmVJdGVyYWJsZVtJU19JVEVSQUJMRV9TRU5USU5FTF0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNLZXllZChtYXliZUtleWVkKSB7XG4gICAgcmV0dXJuICEhKG1heWJlS2V5ZWQgJiYgbWF5YmVLZXllZFtJU19LRVlFRF9TRU5USU5FTF0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNJbmRleGVkKG1heWJlSW5kZXhlZCkge1xuICAgIHJldHVybiAhIShtYXliZUluZGV4ZWQgJiYgbWF5YmVJbmRleGVkW0lTX0lOREVYRURfU0VOVElORUxdKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzQXNzb2NpYXRpdmUobWF5YmVBc3NvY2lhdGl2ZSkge1xuICAgIHJldHVybiBpc0tleWVkKG1heWJlQXNzb2NpYXRpdmUpIHx8IGlzSW5kZXhlZChtYXliZUFzc29jaWF0aXZlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzT3JkZXJlZChtYXliZU9yZGVyZWQpIHtcbiAgICByZXR1cm4gISEobWF5YmVPcmRlcmVkICYmIG1heWJlT3JkZXJlZFtJU19PUkRFUkVEX1NFTlRJTkVMXSk7XG4gIH1cblxuICBJdGVyYWJsZS5pc0l0ZXJhYmxlID0gaXNJdGVyYWJsZTtcbiAgSXRlcmFibGUuaXNLZXllZCA9IGlzS2V5ZWQ7XG4gIEl0ZXJhYmxlLmlzSW5kZXhlZCA9IGlzSW5kZXhlZDtcbiAgSXRlcmFibGUuaXNBc3NvY2lhdGl2ZSA9IGlzQXNzb2NpYXRpdmU7XG4gIEl0ZXJhYmxlLmlzT3JkZXJlZCA9IGlzT3JkZXJlZDtcblxuICBJdGVyYWJsZS5LZXllZCA9IEtleWVkSXRlcmFibGU7XG4gIEl0ZXJhYmxlLkluZGV4ZWQgPSBJbmRleGVkSXRlcmFibGU7XG4gIEl0ZXJhYmxlLlNldCA9IFNldEl0ZXJhYmxlO1xuXG5cbiAgdmFyIElTX0lURVJBQkxFX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfSVRFUkFCTEVfX0BAJztcbiAgdmFyIElTX0tFWUVEX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfS0VZRURfX0BAJztcbiAgdmFyIElTX0lOREVYRURfU0VOVElORUwgPSAnQEBfX0lNTVVUQUJMRV9JTkRFWEVEX19AQCc7XG4gIHZhciBJU19PUkRFUkVEX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfT1JERVJFRF9fQEAnO1xuXG4gIC8vIFVzZWQgZm9yIHNldHRpbmcgcHJvdG90eXBlIG1ldGhvZHMgdGhhdCBJRTggY2hva2VzIG9uLlxuICB2YXIgREVMRVRFID0gJ2RlbGV0ZSc7XG5cbiAgLy8gQ29uc3RhbnRzIGRlc2NyaWJpbmcgdGhlIHNpemUgb2YgdHJpZSBub2Rlcy5cbiAgdmFyIFNISUZUID0gNTsgLy8gUmVzdWx0ZWQgaW4gYmVzdCBwZXJmb3JtYW5jZSBhZnRlciBfX19fX18/XG4gIHZhciBTSVpFID0gMSA8PCBTSElGVDtcbiAgdmFyIE1BU0sgPSBTSVpFIC0gMTtcblxuICAvLyBBIGNvbnNpc3RlbnQgc2hhcmVkIHZhbHVlIHJlcHJlc2VudGluZyBcIm5vdCBzZXRcIiB3aGljaCBlcXVhbHMgbm90aGluZyBvdGhlclxuICAvLyB0aGFuIGl0c2VsZiwgYW5kIG5vdGhpbmcgdGhhdCBjb3VsZCBiZSBwcm92aWRlZCBleHRlcm5hbGx5LlxuICB2YXIgTk9UX1NFVCA9IHt9O1xuXG4gIC8vIEJvb2xlYW4gcmVmZXJlbmNlcywgUm91Z2ggZXF1aXZhbGVudCBvZiBgYm9vbCAmYC5cbiAgdmFyIENIQU5HRV9MRU5HVEggPSB7IHZhbHVlOiBmYWxzZSB9O1xuICB2YXIgRElEX0FMVEVSID0geyB2YWx1ZTogZmFsc2UgfTtcblxuICBmdW5jdGlvbiBNYWtlUmVmKHJlZikge1xuICAgIHJlZi52YWx1ZSA9IGZhbHNlO1xuICAgIHJldHVybiByZWY7XG4gIH1cblxuICBmdW5jdGlvbiBTZXRSZWYocmVmKSB7XG4gICAgcmVmICYmIChyZWYudmFsdWUgPSB0cnVlKTtcbiAgfVxuXG4gIC8vIEEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhIHZhbHVlIHJlcHJlc2VudGluZyBhbiBcIm93bmVyXCIgZm9yIHRyYW5zaWVudCB3cml0ZXNcbiAgLy8gdG8gdHJpZXMuIFRoZSByZXR1cm4gdmFsdWUgd2lsbCBvbmx5IGV2ZXIgZXF1YWwgaXRzZWxmLCBhbmQgd2lsbCBub3QgZXF1YWxcbiAgLy8gdGhlIHJldHVybiBvZiBhbnkgc3Vic2VxdWVudCBjYWxsIG9mIHRoaXMgZnVuY3Rpb24uXG4gIGZ1bmN0aW9uIE93bmVySUQoKSB7fVxuXG4gIC8vIGh0dHA6Ly9qc3BlcmYuY29tL2NvcHktYXJyYXktaW5saW5lXG4gIGZ1bmN0aW9uIGFyckNvcHkoYXJyLCBvZmZzZXQpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfHwgMDtcbiAgICB2YXIgbGVuID0gTWF0aC5tYXgoMCwgYXJyLmxlbmd0aCAtIG9mZnNldCk7XG4gICAgdmFyIG5ld0FyciA9IG5ldyBBcnJheShsZW4pO1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCBsZW47IGlpKyspIHtcbiAgICAgIG5ld0FycltpaV0gPSBhcnJbaWkgKyBvZmZzZXRdO1xuICAgIH1cbiAgICByZXR1cm4gbmV3QXJyO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5zdXJlU2l6ZShpdGVyKSB7XG4gICAgaWYgKGl0ZXIuc2l6ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpdGVyLnNpemUgPSBpdGVyLl9faXRlcmF0ZShyZXR1cm5UcnVlKTtcbiAgICB9XG4gICAgcmV0dXJuIGl0ZXIuc2l6ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdyYXBJbmRleChpdGVyLCBpbmRleCkge1xuICAgIC8vIFRoaXMgaW1wbGVtZW50cyBcImlzIGFycmF5IGluZGV4XCIgd2hpY2ggdGhlIEVDTUFTdHJpbmcgc3BlYyBkZWZpbmVzIGFzOlxuICAgIC8vXG4gICAgLy8gICAgIEEgU3RyaW5nIHByb3BlcnR5IG5hbWUgUCBpcyBhbiBhcnJheSBpbmRleCBpZiBhbmQgb25seSBpZlxuICAgIC8vICAgICBUb1N0cmluZyhUb1VpbnQzMihQKSkgaXMgZXF1YWwgdG8gUCBhbmQgVG9VaW50MzIoUCkgaXMgbm90IGVxdWFsXG4gICAgLy8gICAgIHRvIDJeMzLiiJIxLlxuICAgIC8vXG4gICAgLy8gaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWFycmF5LWV4b3RpYy1vYmplY3RzXG4gICAgaWYgKHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicpIHtcbiAgICAgIHZhciB1aW50MzJJbmRleCA9IGluZGV4ID4+PiAwOyAvLyBOID4+PiAwIGlzIHNob3J0aGFuZCBmb3IgVG9VaW50MzJcbiAgICAgIGlmICgnJyArIHVpbnQzMkluZGV4ICE9PSBpbmRleCB8fCB1aW50MzJJbmRleCA9PT0gNDI5NDk2NzI5NSkge1xuICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgfVxuICAgICAgaW5kZXggPSB1aW50MzJJbmRleDtcbiAgICB9XG4gICAgcmV0dXJuIGluZGV4IDwgMCA/IGVuc3VyZVNpemUoaXRlcikgKyBpbmRleCA6IGluZGV4O1xuICB9XG5cbiAgZnVuY3Rpb24gcmV0dXJuVHJ1ZSgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdob2xlU2xpY2UoYmVnaW4sIGVuZCwgc2l6ZSkge1xuICAgIHJldHVybiAoYmVnaW4gPT09IDAgfHwgKHNpemUgIT09IHVuZGVmaW5lZCAmJiBiZWdpbiA8PSAtc2l6ZSkpICYmXG4gICAgICAoZW5kID09PSB1bmRlZmluZWQgfHwgKHNpemUgIT09IHVuZGVmaW5lZCAmJiBlbmQgPj0gc2l6ZSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzb2x2ZUJlZ2luKGJlZ2luLCBzaXplKSB7XG4gICAgcmV0dXJuIHJlc29sdmVJbmRleChiZWdpbiwgc2l6ZSwgMCk7XG4gIH1cblxuICBmdW5jdGlvbiByZXNvbHZlRW5kKGVuZCwgc2l6ZSkge1xuICAgIHJldHVybiByZXNvbHZlSW5kZXgoZW5kLCBzaXplLCBzaXplKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc29sdmVJbmRleChpbmRleCwgc2l6ZSwgZGVmYXVsdEluZGV4KSB7XG4gICAgcmV0dXJuIGluZGV4ID09PSB1bmRlZmluZWQgP1xuICAgICAgZGVmYXVsdEluZGV4IDpcbiAgICAgIGluZGV4IDwgMCA/XG4gICAgICAgIE1hdGgubWF4KDAsIHNpemUgKyBpbmRleCkgOlxuICAgICAgICBzaXplID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgIGluZGV4IDpcbiAgICAgICAgICBNYXRoLm1pbihzaXplLCBpbmRleCk7XG4gIH1cblxuICAvKiBnbG9iYWwgU3ltYm9sICovXG5cbiAgdmFyIElURVJBVEVfS0VZUyA9IDA7XG4gIHZhciBJVEVSQVRFX1ZBTFVFUyA9IDE7XG4gIHZhciBJVEVSQVRFX0VOVFJJRVMgPSAyO1xuXG4gIHZhciBSRUFMX0lURVJBVE9SX1NZTUJPTCA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLml0ZXJhdG9yO1xuICB2YXIgRkFVWF9JVEVSQVRPUl9TWU1CT0wgPSAnQEBpdGVyYXRvcic7XG5cbiAgdmFyIElURVJBVE9SX1NZTUJPTCA9IFJFQUxfSVRFUkFUT1JfU1lNQk9MIHx8IEZBVVhfSVRFUkFUT1JfU1lNQk9MO1xuXG5cbiAgZnVuY3Rpb24gSXRlcmF0b3IobmV4dCkge1xuICAgICAgdGhpcy5uZXh0ID0gbmV4dDtcbiAgICB9XG5cbiAgICBJdGVyYXRvci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAnW0l0ZXJhdG9yXSc7XG4gICAgfTtcblxuXG4gIEl0ZXJhdG9yLktFWVMgPSBJVEVSQVRFX0tFWVM7XG4gIEl0ZXJhdG9yLlZBTFVFUyA9IElURVJBVEVfVkFMVUVTO1xuICBJdGVyYXRvci5FTlRSSUVTID0gSVRFUkFURV9FTlRSSUVTO1xuXG4gIEl0ZXJhdG9yLnByb3RvdHlwZS5pbnNwZWN0ID1cbiAgSXRlcmF0b3IucHJvdG90eXBlLnRvU291cmNlID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy50b1N0cmluZygpOyB9XG4gIEl0ZXJhdG9yLnByb3RvdHlwZVtJVEVSQVRPUl9TWU1CT0xdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG5cbiAgZnVuY3Rpb24gaXRlcmF0b3JWYWx1ZSh0eXBlLCBrLCB2LCBpdGVyYXRvclJlc3VsdCkge1xuICAgIHZhciB2YWx1ZSA9IHR5cGUgPT09IDAgPyBrIDogdHlwZSA9PT0gMSA/IHYgOiBbaywgdl07XG4gICAgaXRlcmF0b3JSZXN1bHQgPyAoaXRlcmF0b3JSZXN1bHQudmFsdWUgPSB2YWx1ZSkgOiAoaXRlcmF0b3JSZXN1bHQgPSB7XG4gICAgICB2YWx1ZTogdmFsdWUsIGRvbmU6IGZhbHNlXG4gICAgfSk7XG4gICAgcmV0dXJuIGl0ZXJhdG9yUmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gaXRlcmF0b3JEb25lKCkge1xuICAgIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhc0l0ZXJhdG9yKG1heWJlSXRlcmFibGUpIHtcbiAgICByZXR1cm4gISFnZXRJdGVyYXRvckZuKG1heWJlSXRlcmFibGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNJdGVyYXRvcihtYXliZUl0ZXJhdG9yKSB7XG4gICAgcmV0dXJuIG1heWJlSXRlcmF0b3IgJiYgdHlwZW9mIG1heWJlSXRlcmF0b3IubmV4dCA9PT0gJ2Z1bmN0aW9uJztcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEl0ZXJhdG9yKGl0ZXJhYmxlKSB7XG4gICAgdmFyIGl0ZXJhdG9yRm4gPSBnZXRJdGVyYXRvckZuKGl0ZXJhYmxlKTtcbiAgICByZXR1cm4gaXRlcmF0b3JGbiAmJiBpdGVyYXRvckZuLmNhbGwoaXRlcmFibGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0SXRlcmF0b3JGbihpdGVyYWJsZSkge1xuICAgIHZhciBpdGVyYXRvckZuID0gaXRlcmFibGUgJiYgKFxuICAgICAgKFJFQUxfSVRFUkFUT1JfU1lNQk9MICYmIGl0ZXJhYmxlW1JFQUxfSVRFUkFUT1JfU1lNQk9MXSkgfHxcbiAgICAgIGl0ZXJhYmxlW0ZBVVhfSVRFUkFUT1JfU1lNQk9MXVxuICAgICk7XG4gICAgaWYgKHR5cGVvZiBpdGVyYXRvckZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gaXRlcmF0b3JGbjtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpc0FycmF5TGlrZSh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJztcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKFNlcSwgSXRlcmFibGUpO1xuICAgIGZ1bmN0aW9uIFNlcSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgPyBlbXB0eVNlcXVlbmNlKCkgOlxuICAgICAgICBpc0l0ZXJhYmxlKHZhbHVlKSA/IHZhbHVlLnRvU2VxKCkgOiBzZXFGcm9tVmFsdWUodmFsdWUpO1xuICAgIH1cblxuICAgIFNlcS5vZiA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHJldHVybiBTZXEoYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgU2VxLnByb3RvdHlwZS50b1NlcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFNlcS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fdG9TdHJpbmcoJ1NlcSB7JywgJ30nKTtcbiAgICB9O1xuXG4gICAgU2VxLnByb3RvdHlwZS5jYWNoZVJlc3VsdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLl9jYWNoZSAmJiB0aGlzLl9faXRlcmF0ZVVuY2FjaGVkKSB7XG4gICAgICAgIHRoaXMuX2NhY2hlID0gdGhpcy5lbnRyeVNlcSgpLnRvQXJyYXkoKTtcbiAgICAgICAgdGhpcy5zaXplID0gdGhpcy5fY2FjaGUubGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIGFic3RyYWN0IF9faXRlcmF0ZVVuY2FjaGVkKGZuLCByZXZlcnNlKVxuXG4gICAgU2VxLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge1xuICAgICAgcmV0dXJuIHNlcUl0ZXJhdGUodGhpcywgZm4sIHJldmVyc2UsIHRydWUpO1xuICAgIH07XG5cbiAgICAvLyBhYnN0cmFjdCBfX2l0ZXJhdG9yVW5jYWNoZWQodHlwZSwgcmV2ZXJzZSlcblxuICAgIFNlcS5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHJldHVybiBzZXFJdGVyYXRvcih0aGlzLCB0eXBlLCByZXZlcnNlLCB0cnVlKTtcbiAgICB9O1xuXG5cblxuICBjcmVhdGVDbGFzcyhLZXllZFNlcSwgU2VxKTtcbiAgICBmdW5jdGlvbiBLZXllZFNlcSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgP1xuICAgICAgICBlbXB0eVNlcXVlbmNlKCkudG9LZXllZFNlcSgpIDpcbiAgICAgICAgaXNJdGVyYWJsZSh2YWx1ZSkgP1xuICAgICAgICAgIChpc0tleWVkKHZhbHVlKSA/IHZhbHVlLnRvU2VxKCkgOiB2YWx1ZS5mcm9tRW50cnlTZXEoKSkgOlxuICAgICAgICAgIGtleWVkU2VxRnJvbVZhbHVlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBLZXllZFNlcS5wcm90b3R5cGUudG9LZXllZFNlcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuXG5cbiAgY3JlYXRlQ2xhc3MoSW5kZXhlZFNlcSwgU2VxKTtcbiAgICBmdW5jdGlvbiBJbmRleGVkU2VxKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCA/IGVtcHR5U2VxdWVuY2UoKSA6XG4gICAgICAgICFpc0l0ZXJhYmxlKHZhbHVlKSA/IGluZGV4ZWRTZXFGcm9tVmFsdWUodmFsdWUpIDpcbiAgICAgICAgaXNLZXllZCh2YWx1ZSkgPyB2YWx1ZS5lbnRyeVNlcSgpIDogdmFsdWUudG9JbmRleGVkU2VxKCk7XG4gICAgfVxuXG4gICAgSW5kZXhlZFNlcS5vZiA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHJldHVybiBJbmRleGVkU2VxKGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIEluZGV4ZWRTZXEucHJvdG90eXBlLnRvSW5kZXhlZFNlcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIEluZGV4ZWRTZXEucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX3RvU3RyaW5nKCdTZXEgWycsICddJyk7XG4gICAgfTtcblxuICAgIEluZGV4ZWRTZXEucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICByZXR1cm4gc2VxSXRlcmF0ZSh0aGlzLCBmbiwgcmV2ZXJzZSwgZmFsc2UpO1xuICAgIH07XG5cbiAgICBJbmRleGVkU2VxLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgcmV0dXJuIHNlcUl0ZXJhdG9yKHRoaXMsIHR5cGUsIHJldmVyc2UsIGZhbHNlKTtcbiAgICB9O1xuXG5cblxuICBjcmVhdGVDbGFzcyhTZXRTZXEsIFNlcSk7XG4gICAgZnVuY3Rpb24gU2V0U2VxKHZhbHVlKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gZW1wdHlTZXF1ZW5jZSgpIDpcbiAgICAgICAgIWlzSXRlcmFibGUodmFsdWUpID8gaW5kZXhlZFNlcUZyb21WYWx1ZSh2YWx1ZSkgOlxuICAgICAgICBpc0tleWVkKHZhbHVlKSA/IHZhbHVlLmVudHJ5U2VxKCkgOiB2YWx1ZVxuICAgICAgKS50b1NldFNlcSgpO1xuICAgIH1cblxuICAgIFNldFNlcS5vZiA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHJldHVybiBTZXRTZXEoYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgU2V0U2VxLnByb3RvdHlwZS50b1NldFNlcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuXG5cbiAgU2VxLmlzU2VxID0gaXNTZXE7XG4gIFNlcS5LZXllZCA9IEtleWVkU2VxO1xuICBTZXEuU2V0ID0gU2V0U2VxO1xuICBTZXEuSW5kZXhlZCA9IEluZGV4ZWRTZXE7XG5cbiAgdmFyIElTX1NFUV9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX1NFUV9fQEAnO1xuXG4gIFNlcS5wcm90b3R5cGVbSVNfU0VRX1NFTlRJTkVMXSA9IHRydWU7XG5cblxuXG4gIGNyZWF0ZUNsYXNzKEFycmF5U2VxLCBJbmRleGVkU2VxKTtcbiAgICBmdW5jdGlvbiBBcnJheVNlcShhcnJheSkge1xuICAgICAgdGhpcy5fYXJyYXkgPSBhcnJheTtcbiAgICAgIHRoaXMuc2l6ZSA9IGFycmF5Lmxlbmd0aDtcbiAgICB9XG5cbiAgICBBcnJheVNlcS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oaW5kZXgsIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5oYXMoaW5kZXgpID8gdGhpcy5fYXJyYXlbd3JhcEluZGV4KHRoaXMsIGluZGV4KV0gOiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgQXJyYXlTZXEucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICB2YXIgYXJyYXkgPSB0aGlzLl9hcnJheTtcbiAgICAgIHZhciBtYXhJbmRleCA9IGFycmF5Lmxlbmd0aCAtIDE7XG4gICAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDw9IG1heEluZGV4OyBpaSsrKSB7XG4gICAgICAgIGlmIChmbihhcnJheVtyZXZlcnNlID8gbWF4SW5kZXggLSBpaSA6IGlpXSwgaWksIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybiBpaSArIDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpaTtcbiAgICB9O1xuXG4gICAgQXJyYXlTZXEucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgYXJyYXkgPSB0aGlzLl9hcnJheTtcbiAgICAgIHZhciBtYXhJbmRleCA9IGFycmF5Lmxlbmd0aCAtIDE7XG4gICAgICB2YXIgaWkgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpIFxuICAgICAgICB7cmV0dXJuIGlpID4gbWF4SW5kZXggP1xuICAgICAgICAgIGl0ZXJhdG9yRG9uZSgpIDpcbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIGlpLCBhcnJheVtyZXZlcnNlID8gbWF4SW5kZXggLSBpaSsrIDogaWkrK10pfVxuICAgICAgKTtcbiAgICB9O1xuXG5cblxuICBjcmVhdGVDbGFzcyhPYmplY3RTZXEsIEtleWVkU2VxKTtcbiAgICBmdW5jdGlvbiBPYmplY3RTZXEob2JqZWN0KSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdCk7XG4gICAgICB0aGlzLl9vYmplY3QgPSBvYmplY3Q7XG4gICAgICB0aGlzLl9rZXlzID0ga2V5cztcbiAgICAgIHRoaXMuc2l6ZSA9IGtleXMubGVuZ3RoO1xuICAgIH1cblxuICAgIE9iamVjdFNlcS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oa2V5LCBub3RTZXRWYWx1ZSkge1xuICAgICAgaWYgKG5vdFNldFZhbHVlICE9PSB1bmRlZmluZWQgJiYgIXRoaXMuaGFzKGtleSkpIHtcbiAgICAgICAgcmV0dXJuIG5vdFNldFZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuX29iamVjdFtrZXldO1xuICAgIH07XG5cbiAgICBPYmplY3RTZXEucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIHRoaXMuX29iamVjdC5oYXNPd25Qcm9wZXJ0eShrZXkpO1xuICAgIH07XG5cbiAgICBPYmplY3RTZXEucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICB2YXIgb2JqZWN0ID0gdGhpcy5fb2JqZWN0O1xuICAgICAgdmFyIGtleXMgPSB0aGlzLl9rZXlzO1xuICAgICAgdmFyIG1heEluZGV4ID0ga2V5cy5sZW5ndGggLSAxO1xuICAgICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8PSBtYXhJbmRleDsgaWkrKykge1xuICAgICAgICB2YXIga2V5ID0ga2V5c1tyZXZlcnNlID8gbWF4SW5kZXggLSBpaSA6IGlpXTtcbiAgICAgICAgaWYgKGZuKG9iamVjdFtrZXldLCBrZXksIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybiBpaSArIDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpaTtcbiAgICB9O1xuXG4gICAgT2JqZWN0U2VxLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIG9iamVjdCA9IHRoaXMuX29iamVjdDtcbiAgICAgIHZhciBrZXlzID0gdGhpcy5fa2V5cztcbiAgICAgIHZhciBtYXhJbmRleCA9IGtleXMubGVuZ3RoIC0gMTtcbiAgICAgIHZhciBpaSA9IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbcmV2ZXJzZSA/IG1heEluZGV4IC0gaWkgOiBpaV07XG4gICAgICAgIHJldHVybiBpaSsrID4gbWF4SW5kZXggP1xuICAgICAgICAgIGl0ZXJhdG9yRG9uZSgpIDpcbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIGtleSwgb2JqZWN0W2tleV0pO1xuICAgICAgfSk7XG4gICAgfTtcblxuICBPYmplY3RTZXEucHJvdG90eXBlW0lTX09SREVSRURfU0VOVElORUxdID0gdHJ1ZTtcblxuXG4gIGNyZWF0ZUNsYXNzKEl0ZXJhYmxlU2VxLCBJbmRleGVkU2VxKTtcbiAgICBmdW5jdGlvbiBJdGVyYWJsZVNlcShpdGVyYWJsZSkge1xuICAgICAgdGhpcy5faXRlcmFibGUgPSBpdGVyYWJsZTtcbiAgICAgIHRoaXMuc2l6ZSA9IGl0ZXJhYmxlLmxlbmd0aCB8fCBpdGVyYWJsZS5zaXplO1xuICAgIH1cblxuICAgIEl0ZXJhYmxlU2VxLnByb3RvdHlwZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0ZShmbiwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmFibGUgPSB0aGlzLl9pdGVyYWJsZTtcbiAgICAgIHZhciBpdGVyYXRvciA9IGdldEl0ZXJhdG9yKGl0ZXJhYmxlKTtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIGlmIChpc0l0ZXJhdG9yKGl0ZXJhdG9yKSkge1xuICAgICAgICB2YXIgc3RlcDtcbiAgICAgICAgd2hpbGUgKCEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgICAgIGlmIChmbihzdGVwLnZhbHVlLCBpdGVyYXRpb25zKyssIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaXRlcmF0aW9ucztcbiAgICB9O1xuXG4gICAgSXRlcmFibGVTZXEucHJvdG90eXBlLl9faXRlcmF0b3JVbmNhY2hlZCA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlUmVzdWx0KCkuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyYWJsZSA9IHRoaXMuX2l0ZXJhYmxlO1xuICAgICAgdmFyIGl0ZXJhdG9yID0gZ2V0SXRlcmF0b3IoaXRlcmFibGUpO1xuICAgICAgaWYgKCFpc0l0ZXJhdG9yKGl0ZXJhdG9yKSkge1xuICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGl0ZXJhdG9yRG9uZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgdmFyIHN0ZXAgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIHJldHVybiBzdGVwLmRvbmUgPyBzdGVwIDogaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHN0ZXAudmFsdWUpO1xuICAgICAgfSk7XG4gICAgfTtcblxuXG5cbiAgY3JlYXRlQ2xhc3MoSXRlcmF0b3JTZXEsIEluZGV4ZWRTZXEpO1xuICAgIGZ1bmN0aW9uIEl0ZXJhdG9yU2VxKGl0ZXJhdG9yKSB7XG4gICAgICB0aGlzLl9pdGVyYXRvciA9IGl0ZXJhdG9yO1xuICAgICAgdGhpcy5faXRlcmF0b3JDYWNoZSA9IFtdO1xuICAgIH1cblxuICAgIEl0ZXJhdG9yU2VxLnByb3RvdHlwZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0ZShmbiwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmF0b3IgPSB0aGlzLl9pdGVyYXRvcjtcbiAgICAgIHZhciBjYWNoZSA9IHRoaXMuX2l0ZXJhdG9yQ2FjaGU7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICB3aGlsZSAoaXRlcmF0aW9ucyA8IGNhY2hlLmxlbmd0aCkge1xuICAgICAgICBpZiAoZm4oY2FjaGVbaXRlcmF0aW9uc10sIGl0ZXJhdGlvbnMrKywgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciBzdGVwO1xuICAgICAgd2hpbGUgKCEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgICB2YXIgdmFsID0gc3RlcC52YWx1ZTtcbiAgICAgICAgY2FjaGVbaXRlcmF0aW9uc10gPSB2YWw7XG4gICAgICAgIGlmIChmbih2YWwsIGl0ZXJhdGlvbnMrKywgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH07XG5cbiAgICBJdGVyYXRvclNlcS5wcm90b3R5cGUuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGVSZXN1bHQoKS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXJhdG9yID0gdGhpcy5faXRlcmF0b3I7XG4gICAgICB2YXIgY2FjaGUgPSB0aGlzLl9pdGVyYXRvckNhY2hlO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIGlmIChpdGVyYXRpb25zID49IGNhY2hlLmxlbmd0aCkge1xuICAgICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgIGlmIChzdGVwLmRvbmUpIHtcbiAgICAgICAgICAgIHJldHVybiBzdGVwO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYWNoZVtpdGVyYXRpb25zXSA9IHN0ZXAudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVmFsdWUodHlwZSwgaXRlcmF0aW9ucywgY2FjaGVbaXRlcmF0aW9ucysrXSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG5cblxuXG4gIC8vICMgcHJhZ21hIEhlbHBlciBmdW5jdGlvbnNcblxuICBmdW5jdGlvbiBpc1NlcShtYXliZVNlcSkge1xuICAgIHJldHVybiAhIShtYXliZVNlcSAmJiBtYXliZVNlcVtJU19TRVFfU0VOVElORUxdKTtcbiAgfVxuXG4gIHZhciBFTVBUWV9TRVE7XG5cbiAgZnVuY3Rpb24gZW1wdHlTZXF1ZW5jZSgpIHtcbiAgICByZXR1cm4gRU1QVFlfU0VRIHx8IChFTVBUWV9TRVEgPSBuZXcgQXJyYXlTZXEoW10pKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGtleWVkU2VxRnJvbVZhbHVlKHZhbHVlKSB7XG4gICAgdmFyIHNlcSA9XG4gICAgICBBcnJheS5pc0FycmF5KHZhbHVlKSA/IG5ldyBBcnJheVNlcSh2YWx1ZSkuZnJvbUVudHJ5U2VxKCkgOlxuICAgICAgaXNJdGVyYXRvcih2YWx1ZSkgPyBuZXcgSXRlcmF0b3JTZXEodmFsdWUpLmZyb21FbnRyeVNlcSgpIDpcbiAgICAgIGhhc0l0ZXJhdG9yKHZhbHVlKSA/IG5ldyBJdGVyYWJsZVNlcSh2YWx1ZSkuZnJvbUVudHJ5U2VxKCkgOlxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyA/IG5ldyBPYmplY3RTZXEodmFsdWUpIDpcbiAgICAgIHVuZGVmaW5lZDtcbiAgICBpZiAoIXNlcSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgJ0V4cGVjdGVkIEFycmF5IG9yIGl0ZXJhYmxlIG9iamVjdCBvZiBbaywgdl0gZW50cmllcywgJytcbiAgICAgICAgJ29yIGtleWVkIG9iamVjdDogJyArIHZhbHVlXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gc2VxO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5kZXhlZFNlcUZyb21WYWx1ZSh2YWx1ZSkge1xuICAgIHZhciBzZXEgPSBtYXliZUluZGV4ZWRTZXFGcm9tVmFsdWUodmFsdWUpO1xuICAgIGlmICghc2VxKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAnRXhwZWN0ZWQgQXJyYXkgb3IgaXRlcmFibGUgb2JqZWN0IG9mIHZhbHVlczogJyArIHZhbHVlXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gc2VxO1xuICB9XG5cbiAgZnVuY3Rpb24gc2VxRnJvbVZhbHVlKHZhbHVlKSB7XG4gICAgdmFyIHNlcSA9IG1heWJlSW5kZXhlZFNlcUZyb21WYWx1ZSh2YWx1ZSkgfHxcbiAgICAgICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIG5ldyBPYmplY3RTZXEodmFsdWUpKTtcbiAgICBpZiAoIXNlcSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgJ0V4cGVjdGVkIEFycmF5IG9yIGl0ZXJhYmxlIG9iamVjdCBvZiB2YWx1ZXMsIG9yIGtleWVkIG9iamVjdDogJyArIHZhbHVlXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gc2VxO1xuICB9XG5cbiAgZnVuY3Rpb24gbWF5YmVJbmRleGVkU2VxRnJvbVZhbHVlKHZhbHVlKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGlzQXJyYXlMaWtlKHZhbHVlKSA/IG5ldyBBcnJheVNlcSh2YWx1ZSkgOlxuICAgICAgaXNJdGVyYXRvcih2YWx1ZSkgPyBuZXcgSXRlcmF0b3JTZXEodmFsdWUpIDpcbiAgICAgIGhhc0l0ZXJhdG9yKHZhbHVlKSA/IG5ldyBJdGVyYWJsZVNlcSh2YWx1ZSkgOlxuICAgICAgdW5kZWZpbmVkXG4gICAgKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNlcUl0ZXJhdGUoc2VxLCBmbiwgcmV2ZXJzZSwgdXNlS2V5cykge1xuICAgIHZhciBjYWNoZSA9IHNlcS5fY2FjaGU7XG4gICAgaWYgKGNhY2hlKSB7XG4gICAgICB2YXIgbWF4SW5kZXggPSBjYWNoZS5sZW5ndGggLSAxO1xuICAgICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8PSBtYXhJbmRleDsgaWkrKykge1xuICAgICAgICB2YXIgZW50cnkgPSBjYWNoZVtyZXZlcnNlID8gbWF4SW5kZXggLSBpaSA6IGlpXTtcbiAgICAgICAgaWYgKGZuKGVudHJ5WzFdLCB1c2VLZXlzID8gZW50cnlbMF0gOiBpaSwgc2VxKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICByZXR1cm4gaWkgKyAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaWk7XG4gICAgfVxuICAgIHJldHVybiBzZXEuX19pdGVyYXRlVW5jYWNoZWQoZm4sIHJldmVyc2UpO1xuICB9XG5cbiAgZnVuY3Rpb24gc2VxSXRlcmF0b3Ioc2VxLCB0eXBlLCByZXZlcnNlLCB1c2VLZXlzKSB7XG4gICAgdmFyIGNhY2hlID0gc2VxLl9jYWNoZTtcbiAgICBpZiAoY2FjaGUpIHtcbiAgICAgIHZhciBtYXhJbmRleCA9IGNhY2hlLmxlbmd0aCAtIDE7XG4gICAgICB2YXIgaWkgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBlbnRyeSA9IGNhY2hlW3JldmVyc2UgPyBtYXhJbmRleCAtIGlpIDogaWldO1xuICAgICAgICByZXR1cm4gaWkrKyA+IG1heEluZGV4ID9cbiAgICAgICAgICBpdGVyYXRvckRvbmUoKSA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCB1c2VLZXlzID8gZW50cnlbMF0gOiBpaSAtIDEsIGVudHJ5WzFdKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gc2VxLl9faXRlcmF0b3JVbmNhY2hlZCh0eXBlLCByZXZlcnNlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZyb21KUyhqc29uLCBjb252ZXJ0ZXIpIHtcbiAgICByZXR1cm4gY29udmVydGVyID9cbiAgICAgIGZyb21KU1dpdGgoY29udmVydGVyLCBqc29uLCAnJywgeycnOiBqc29ufSkgOlxuICAgICAgZnJvbUpTRGVmYXVsdChqc29uKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZyb21KU1dpdGgoY29udmVydGVyLCBqc29uLCBrZXksIHBhcmVudEpTT04pIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShqc29uKSkge1xuICAgICAgcmV0dXJuIGNvbnZlcnRlci5jYWxsKHBhcmVudEpTT04sIGtleSwgSW5kZXhlZFNlcShqc29uKS5tYXAoZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gZnJvbUpTV2l0aChjb252ZXJ0ZXIsIHYsIGssIGpzb24pfSkpO1xuICAgIH1cbiAgICBpZiAoaXNQbGFpbk9iaihqc29uKSkge1xuICAgICAgcmV0dXJuIGNvbnZlcnRlci5jYWxsKHBhcmVudEpTT04sIGtleSwgS2V5ZWRTZXEoanNvbikubWFwKGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIGZyb21KU1dpdGgoY29udmVydGVyLCB2LCBrLCBqc29uKX0pKTtcbiAgICB9XG4gICAgcmV0dXJuIGpzb247XG4gIH1cblxuICBmdW5jdGlvbiBmcm9tSlNEZWZhdWx0KGpzb24pIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShqc29uKSkge1xuICAgICAgcmV0dXJuIEluZGV4ZWRTZXEoanNvbikubWFwKGZyb21KU0RlZmF1bHQpLnRvTGlzdCgpO1xuICAgIH1cbiAgICBpZiAoaXNQbGFpbk9iaihqc29uKSkge1xuICAgICAgcmV0dXJuIEtleWVkU2VxKGpzb24pLm1hcChmcm9tSlNEZWZhdWx0KS50b01hcCgpO1xuICAgIH1cbiAgICByZXR1cm4ganNvbjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzUGxhaW5PYmoodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgJiYgKHZhbHVlLmNvbnN0cnVjdG9yID09PSBPYmplY3QgfHwgdmFsdWUuY29uc3RydWN0b3IgPT09IHVuZGVmaW5lZCk7XG4gIH1cblxuICAvKipcbiAgICogQW4gZXh0ZW5zaW9uIG9mIHRoZSBcInNhbWUtdmFsdWVcIiBhbGdvcml0aG0gYXMgW2Rlc2NyaWJlZCBmb3IgdXNlIGJ5IEVTNiBNYXBcbiAgICogYW5kIFNldF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvTWFwI0tleV9lcXVhbGl0eSlcbiAgICpcbiAgICogTmFOIGlzIGNvbnNpZGVyZWQgdGhlIHNhbWUgYXMgTmFOLCBob3dldmVyIC0wIGFuZCAwIGFyZSBjb25zaWRlcmVkIHRoZSBzYW1lXG4gICAqIHZhbHVlLCB3aGljaCBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgYWxnb3JpdGhtIGRlc2NyaWJlZCBieVxuICAgKiBbYE9iamVjdC5pc2BdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL09iamVjdC9pcykuXG4gICAqXG4gICAqIFRoaXMgaXMgZXh0ZW5kZWQgZnVydGhlciB0byBhbGxvdyBPYmplY3RzIHRvIGRlc2NyaWJlIHRoZSB2YWx1ZXMgdGhleVxuICAgKiByZXByZXNlbnQsIGJ5IHdheSBvZiBgdmFsdWVPZmAgb3IgYGVxdWFsc2AgKGFuZCBgaGFzaENvZGVgKS5cbiAgICpcbiAgICogTm90ZTogYmVjYXVzZSBvZiB0aGlzIGV4dGVuc2lvbiwgdGhlIGtleSBlcXVhbGl0eSBvZiBJbW11dGFibGUuTWFwIGFuZCB0aGVcbiAgICogdmFsdWUgZXF1YWxpdHkgb2YgSW1tdXRhYmxlLlNldCB3aWxsIGRpZmZlciBmcm9tIEVTNiBNYXAgYW5kIFNldC5cbiAgICpcbiAgICogIyMjIERlZmluaW5nIGN1c3RvbSB2YWx1ZXNcbiAgICpcbiAgICogVGhlIGVhc2llc3Qgd2F5IHRvIGRlc2NyaWJlIHRoZSB2YWx1ZSBhbiBvYmplY3QgcmVwcmVzZW50cyBpcyBieSBpbXBsZW1lbnRpbmdcbiAgICogYHZhbHVlT2ZgLiBGb3IgZXhhbXBsZSwgYERhdGVgIHJlcHJlc2VudHMgYSB2YWx1ZSBieSByZXR1cm5pbmcgYSB1bml4XG4gICAqIHRpbWVzdGFtcCBmb3IgYHZhbHVlT2ZgOlxuICAgKlxuICAgKiAgICAgdmFyIGRhdGUxID0gbmV3IERhdGUoMTIzNDU2Nzg5MDAwMCk7IC8vIEZyaSBGZWIgMTMgMjAwOSAuLi5cbiAgICogICAgIHZhciBkYXRlMiA9IG5ldyBEYXRlKDEyMzQ1Njc4OTAwMDApO1xuICAgKiAgICAgZGF0ZTEudmFsdWVPZigpOyAvLyAxMjM0NTY3ODkwMDAwXG4gICAqICAgICBhc3NlcnQoIGRhdGUxICE9PSBkYXRlMiApO1xuICAgKiAgICAgYXNzZXJ0KCBJbW11dGFibGUuaXMoIGRhdGUxLCBkYXRlMiApICk7XG4gICAqXG4gICAqIE5vdGU6IG92ZXJyaWRpbmcgYHZhbHVlT2ZgIG1heSBoYXZlIG90aGVyIGltcGxpY2F0aW9ucyBpZiB5b3UgdXNlIHRoaXMgb2JqZWN0XG4gICAqIHdoZXJlIEphdmFTY3JpcHQgZXhwZWN0cyBhIHByaW1pdGl2ZSwgc3VjaCBhcyBpbXBsaWNpdCBzdHJpbmcgY29lcmNpb24uXG4gICAqXG4gICAqIEZvciBtb3JlIGNvbXBsZXggdHlwZXMsIGVzcGVjaWFsbHkgY29sbGVjdGlvbnMsIGltcGxlbWVudGluZyBgdmFsdWVPZmAgbWF5XG4gICAqIG5vdCBiZSBwZXJmb3JtYW50LiBBbiBhbHRlcm5hdGl2ZSBpcyB0byBpbXBsZW1lbnQgYGVxdWFsc2AgYW5kIGBoYXNoQ29kZWAuXG4gICAqXG4gICAqIGBlcXVhbHNgIHRha2VzIGFub3RoZXIgb2JqZWN0LCBwcmVzdW1hYmx5IG9mIHNpbWlsYXIgdHlwZSwgYW5kIHJldHVybnMgdHJ1ZVxuICAgKiBpZiB0aGUgaXQgaXMgZXF1YWwuIEVxdWFsaXR5IGlzIHN5bW1ldHJpY2FsLCBzbyB0aGUgc2FtZSByZXN1bHQgc2hvdWxkIGJlXG4gICAqIHJldHVybmVkIGlmIHRoaXMgYW5kIHRoZSBhcmd1bWVudCBhcmUgZmxpcHBlZC5cbiAgICpcbiAgICogICAgIGFzc2VydCggYS5lcXVhbHMoYikgPT09IGIuZXF1YWxzKGEpICk7XG4gICAqXG4gICAqIGBoYXNoQ29kZWAgcmV0dXJucyBhIDMyYml0IGludGVnZXIgbnVtYmVyIHJlcHJlc2VudGluZyB0aGUgb2JqZWN0IHdoaWNoIHdpbGxcbiAgICogYmUgdXNlZCB0byBkZXRlcm1pbmUgaG93IHRvIHN0b3JlIHRoZSB2YWx1ZSBvYmplY3QgaW4gYSBNYXAgb3IgU2V0LiBZb3UgbXVzdFxuICAgKiBwcm92aWRlIGJvdGggb3IgbmVpdGhlciBtZXRob2RzLCBvbmUgbXVzdCBub3QgZXhpc3Qgd2l0aG91dCB0aGUgb3RoZXIuXG4gICAqXG4gICAqIEFsc28sIGFuIGltcG9ydGFudCByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGVzZSBtZXRob2RzIG11c3QgYmUgdXBoZWxkOiBpZiB0d29cbiAgICogdmFsdWVzIGFyZSBlcXVhbCwgdGhleSAqbXVzdCogcmV0dXJuIHRoZSBzYW1lIGhhc2hDb2RlLiBJZiB0aGUgdmFsdWVzIGFyZSBub3RcbiAgICogZXF1YWwsIHRoZXkgbWlnaHQgaGF2ZSB0aGUgc2FtZSBoYXNoQ29kZTsgdGhpcyBpcyBjYWxsZWQgYSBoYXNoIGNvbGxpc2lvbixcbiAgICogYW5kIHdoaWxlIHVuZGVzaXJhYmxlIGZvciBwZXJmb3JtYW5jZSByZWFzb25zLCBpdCBpcyBhY2NlcHRhYmxlLlxuICAgKlxuICAgKiAgICAgaWYgKGEuZXF1YWxzKGIpKSB7XG4gICAqICAgICAgIGFzc2VydCggYS5oYXNoQ29kZSgpID09PSBiLmhhc2hDb2RlKCkgKTtcbiAgICogICAgIH1cbiAgICpcbiAgICogQWxsIEltbXV0YWJsZSBjb2xsZWN0aW9ucyBpbXBsZW1lbnQgYGVxdWFsc2AgYW5kIGBoYXNoQ29kZWAuXG4gICAqXG4gICAqL1xuICBmdW5jdGlvbiBpcyh2YWx1ZUEsIHZhbHVlQikge1xuICAgIGlmICh2YWx1ZUEgPT09IHZhbHVlQiB8fCAodmFsdWVBICE9PSB2YWx1ZUEgJiYgdmFsdWVCICE9PSB2YWx1ZUIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCF2YWx1ZUEgfHwgIXZhbHVlQikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlQS52YWx1ZU9mID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIHR5cGVvZiB2YWx1ZUIudmFsdWVPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFsdWVBID0gdmFsdWVBLnZhbHVlT2YoKTtcbiAgICAgIHZhbHVlQiA9IHZhbHVlQi52YWx1ZU9mKCk7XG4gICAgICBpZiAodmFsdWVBID09PSB2YWx1ZUIgfHwgKHZhbHVlQSAhPT0gdmFsdWVBICYmIHZhbHVlQiAhPT0gdmFsdWVCKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmICghdmFsdWVBIHx8ICF2YWx1ZUIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlQS5lcXVhbHMgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgdHlwZW9mIHZhbHVlQi5lcXVhbHMgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgdmFsdWVBLmVxdWFscyh2YWx1ZUIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gZGVlcEVxdWFsKGEsIGIpIHtcbiAgICBpZiAoYSA9PT0gYikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgIWlzSXRlcmFibGUoYikgfHxcbiAgICAgIGEuc2l6ZSAhPT0gdW5kZWZpbmVkICYmIGIuc2l6ZSAhPT0gdW5kZWZpbmVkICYmIGEuc2l6ZSAhPT0gYi5zaXplIHx8XG4gICAgICBhLl9faGFzaCAhPT0gdW5kZWZpbmVkICYmIGIuX19oYXNoICE9PSB1bmRlZmluZWQgJiYgYS5fX2hhc2ggIT09IGIuX19oYXNoIHx8XG4gICAgICBpc0tleWVkKGEpICE9PSBpc0tleWVkKGIpIHx8XG4gICAgICBpc0luZGV4ZWQoYSkgIT09IGlzSW5kZXhlZChiKSB8fFxuICAgICAgaXNPcmRlcmVkKGEpICE9PSBpc09yZGVyZWQoYilcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoYS5zaXplID09PSAwICYmIGIuc2l6ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdmFyIG5vdEFzc29jaWF0aXZlID0gIWlzQXNzb2NpYXRpdmUoYSk7XG5cbiAgICBpZiAoaXNPcmRlcmVkKGEpKSB7XG4gICAgICB2YXIgZW50cmllcyA9IGEuZW50cmllcygpO1xuICAgICAgcmV0dXJuIGIuZXZlcnkoZnVuY3Rpb24odiwgaykgIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gZW50cmllcy5uZXh0KCkudmFsdWU7XG4gICAgICAgIHJldHVybiBlbnRyeSAmJiBpcyhlbnRyeVsxXSwgdikgJiYgKG5vdEFzc29jaWF0aXZlIHx8IGlzKGVudHJ5WzBdLCBrKSk7XG4gICAgICB9KSAmJiBlbnRyaWVzLm5leHQoKS5kb25lO1xuICAgIH1cblxuICAgIHZhciBmbGlwcGVkID0gZmFsc2U7XG5cbiAgICBpZiAoYS5zaXplID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChiLnNpemUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGEuY2FjaGVSZXN1bHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBhLmNhY2hlUmVzdWx0KCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZsaXBwZWQgPSB0cnVlO1xuICAgICAgICB2YXIgXyA9IGE7XG4gICAgICAgIGEgPSBiO1xuICAgICAgICBiID0gXztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgYWxsRXF1YWwgPSB0cnVlO1xuICAgIHZhciBiU2l6ZSA9IGIuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGspICB7XG4gICAgICBpZiAobm90QXNzb2NpYXRpdmUgPyAhYS5oYXModikgOlxuICAgICAgICAgIGZsaXBwZWQgPyAhaXModiwgYS5nZXQoaywgTk9UX1NFVCkpIDogIWlzKGEuZ2V0KGssIE5PVF9TRVQpLCB2KSkge1xuICAgICAgICBhbGxFcXVhbCA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gYWxsRXF1YWwgJiYgYS5zaXplID09PSBiU2l6ZTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKFJlcGVhdCwgSW5kZXhlZFNlcSk7XG5cbiAgICBmdW5jdGlvbiBSZXBlYXQodmFsdWUsIHRpbWVzKSB7XG4gICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVwZWF0KSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcGVhdCh2YWx1ZSwgdGltZXMpO1xuICAgICAgfVxuICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcbiAgICAgIHRoaXMuc2l6ZSA9IHRpbWVzID09PSB1bmRlZmluZWQgPyBJbmZpbml0eSA6IE1hdGgubWF4KDAsIHRpbWVzKTtcbiAgICAgIGlmICh0aGlzLnNpemUgPT09IDApIHtcbiAgICAgICAgaWYgKEVNUFRZX1JFUEVBVCkge1xuICAgICAgICAgIHJldHVybiBFTVBUWV9SRVBFQVQ7XG4gICAgICAgIH1cbiAgICAgICAgRU1QVFlfUkVQRUFUID0gdGhpcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiAnUmVwZWF0IFtdJztcbiAgICAgIH1cbiAgICAgIHJldHVybiAnUmVwZWF0IFsgJyArIHRoaXMuX3ZhbHVlICsgJyAnICsgdGhpcy5zaXplICsgJyB0aW1lcyBdJztcbiAgICB9O1xuXG4gICAgUmVwZWF0LnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihpbmRleCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhcyhpbmRleCkgPyB0aGlzLl92YWx1ZSA6IG5vdFNldFZhbHVlO1xuICAgIH07XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIHJldHVybiBpcyh0aGlzLl92YWx1ZSwgc2VhcmNoVmFsdWUpO1xuICAgIH07XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xuICAgICAgdmFyIHNpemUgPSB0aGlzLnNpemU7XG4gICAgICByZXR1cm4gd2hvbGVTbGljZShiZWdpbiwgZW5kLCBzaXplKSA/IHRoaXMgOlxuICAgICAgICBuZXcgUmVwZWF0KHRoaXMuX3ZhbHVlLCByZXNvbHZlRW5kKGVuZCwgc2l6ZSkgLSByZXNvbHZlQmVnaW4oYmVnaW4sIHNpemUpKTtcbiAgICB9O1xuXG4gICAgUmVwZWF0LnByb3RvdHlwZS5yZXZlcnNlID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgUmVwZWF0LnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIGlmIChpcyh0aGlzLl92YWx1ZSwgc2VhcmNoVmFsdWUpKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH07XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLmxhc3RJbmRleE9mID0gZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIGlmIChpcyh0aGlzLl92YWx1ZSwgc2VhcmNoVmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNpemU7XG4gICAgICB9XG4gICAgICByZXR1cm4gLTE7XG4gICAgfTtcblxuICAgIFJlcGVhdC5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHtcbiAgICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCB0aGlzLnNpemU7IGlpKyspIHtcbiAgICAgICAgaWYgKGZuKHRoaXMuX3ZhbHVlLCBpaSwgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuIGlpICsgMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGlpO1xuICAgIH07XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICB2YXIgaWkgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpIFxuICAgICAgICB7cmV0dXJuIGlpIDwgdGhpcyQwLnNpemUgPyBpdGVyYXRvclZhbHVlKHR5cGUsIGlpKyssIHRoaXMkMC5fdmFsdWUpIDogaXRlcmF0b3JEb25lKCl9XG4gICAgICApO1xuICAgIH07XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICByZXR1cm4gb3RoZXIgaW5zdGFuY2VvZiBSZXBlYXQgP1xuICAgICAgICBpcyh0aGlzLl92YWx1ZSwgb3RoZXIuX3ZhbHVlKSA6XG4gICAgICAgIGRlZXBFcXVhbChvdGhlcik7XG4gICAgfTtcblxuXG4gIHZhciBFTVBUWV9SRVBFQVQ7XG5cbiAgZnVuY3Rpb24gaW52YXJpYW50KGNvbmRpdGlvbiwgZXJyb3IpIHtcbiAgICBpZiAoIWNvbmRpdGlvbikgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKFJhbmdlLCBJbmRleGVkU2VxKTtcblxuICAgIGZ1bmN0aW9uIFJhbmdlKHN0YXJ0LCBlbmQsIHN0ZXApIHtcbiAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSYW5nZSkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSYW5nZShzdGFydCwgZW5kLCBzdGVwKTtcbiAgICAgIH1cbiAgICAgIGludmFyaWFudChzdGVwICE9PSAwLCAnQ2Fubm90IHN0ZXAgYSBSYW5nZSBieSAwJyk7XG4gICAgICBzdGFydCA9IHN0YXJ0IHx8IDA7XG4gICAgICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZW5kID0gSW5maW5pdHk7XG4gICAgICB9XG4gICAgICBzdGVwID0gc3RlcCA9PT0gdW5kZWZpbmVkID8gMSA6IE1hdGguYWJzKHN0ZXApO1xuICAgICAgaWYgKGVuZCA8IHN0YXJ0KSB7XG4gICAgICAgIHN0ZXAgPSAtc3RlcDtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3N0YXJ0ID0gc3RhcnQ7XG4gICAgICB0aGlzLl9lbmQgPSBlbmQ7XG4gICAgICB0aGlzLl9zdGVwID0gc3RlcDtcbiAgICAgIHRoaXMuc2l6ZSA9IE1hdGgubWF4KDAsIE1hdGguY2VpbCgoZW5kIC0gc3RhcnQpIC8gc3RlcCAtIDEpICsgMSk7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIGlmIChFTVBUWV9SQU5HRSkge1xuICAgICAgICAgIHJldHVybiBFTVBUWV9SQU5HRTtcbiAgICAgICAgfVxuICAgICAgICBFTVBUWV9SQU5HRSA9IHRoaXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgUmFuZ2UucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiAnUmFuZ2UgW10nO1xuICAgICAgfVxuICAgICAgcmV0dXJuICdSYW5nZSBbICcgK1xuICAgICAgICB0aGlzLl9zdGFydCArICcuLi4nICsgdGhpcy5fZW5kICtcbiAgICAgICAgKHRoaXMuX3N0ZXAgIT09IDEgPyAnIGJ5ICcgKyB0aGlzLl9zdGVwIDogJycpICtcbiAgICAgICcgXSc7XG4gICAgfTtcblxuICAgIFJhbmdlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihpbmRleCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhcyhpbmRleCkgP1xuICAgICAgICB0aGlzLl9zdGFydCArIHdyYXBJbmRleCh0aGlzLCBpbmRleCkgKiB0aGlzLl9zdGVwIDpcbiAgICAgICAgbm90U2V0VmFsdWU7XG4gICAgfTtcblxuICAgIFJhbmdlLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICB2YXIgcG9zc2libGVJbmRleCA9IChzZWFyY2hWYWx1ZSAtIHRoaXMuX3N0YXJ0KSAvIHRoaXMuX3N0ZXA7XG4gICAgICByZXR1cm4gcG9zc2libGVJbmRleCA+PSAwICYmXG4gICAgICAgIHBvc3NpYmxlSW5kZXggPCB0aGlzLnNpemUgJiZcbiAgICAgICAgcG9zc2libGVJbmRleCA9PT0gTWF0aC5mbG9vcihwb3NzaWJsZUluZGV4KTtcbiAgICB9O1xuXG4gICAgUmFuZ2UucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xuICAgICAgaWYgKHdob2xlU2xpY2UoYmVnaW4sIGVuZCwgdGhpcy5zaXplKSkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGJlZ2luID0gcmVzb2x2ZUJlZ2luKGJlZ2luLCB0aGlzLnNpemUpO1xuICAgICAgZW5kID0gcmVzb2x2ZUVuZChlbmQsIHRoaXMuc2l6ZSk7XG4gICAgICBpZiAoZW5kIDw9IGJlZ2luKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmFuZ2UoMCwgMCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFJhbmdlKHRoaXMuZ2V0KGJlZ2luLCB0aGlzLl9lbmQpLCB0aGlzLmdldChlbmQsIHRoaXMuX2VuZCksIHRoaXMuX3N0ZXApO1xuICAgIH07XG5cbiAgICBSYW5nZS5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICB2YXIgb2Zmc2V0VmFsdWUgPSBzZWFyY2hWYWx1ZSAtIHRoaXMuX3N0YXJ0O1xuICAgICAgaWYgKG9mZnNldFZhbHVlICUgdGhpcy5fc3RlcCA9PT0gMCkge1xuICAgICAgICB2YXIgaW5kZXggPSBvZmZzZXRWYWx1ZSAvIHRoaXMuX3N0ZXA7XG4gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgdGhpcy5zaXplKSB7XG4gICAgICAgICAgcmV0dXJuIGluZGV4XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAtMTtcbiAgICB9O1xuXG4gICAgUmFuZ2UucHJvdG90eXBlLmxhc3RJbmRleE9mID0gZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmluZGV4T2Yoc2VhcmNoVmFsdWUpO1xuICAgIH07XG5cbiAgICBSYW5nZS5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHtcbiAgICAgIHZhciBtYXhJbmRleCA9IHRoaXMuc2l6ZSAtIDE7XG4gICAgICB2YXIgc3RlcCA9IHRoaXMuX3N0ZXA7XG4gICAgICB2YXIgdmFsdWUgPSByZXZlcnNlID8gdGhpcy5fc3RhcnQgKyBtYXhJbmRleCAqIHN0ZXAgOiB0aGlzLl9zdGFydDtcbiAgICAgIGZvciAodmFyIGlpID0gMDsgaWkgPD0gbWF4SW5kZXg7IGlpKyspIHtcbiAgICAgICAgaWYgKGZuKHZhbHVlLCBpaSwgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuIGlpICsgMTtcbiAgICAgICAgfVxuICAgICAgICB2YWx1ZSArPSByZXZlcnNlID8gLXN0ZXAgOiBzdGVwO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlpO1xuICAgIH07XG5cbiAgICBSYW5nZS5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHZhciBtYXhJbmRleCA9IHRoaXMuc2l6ZSAtIDE7XG4gICAgICB2YXIgc3RlcCA9IHRoaXMuX3N0ZXA7XG4gICAgICB2YXIgdmFsdWUgPSByZXZlcnNlID8gdGhpcy5fc3RhcnQgKyBtYXhJbmRleCAqIHN0ZXAgOiB0aGlzLl9zdGFydDtcbiAgICAgIHZhciBpaSA9IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgdmFyIHYgPSB2YWx1ZTtcbiAgICAgICAgdmFsdWUgKz0gcmV2ZXJzZSA/IC1zdGVwIDogc3RlcDtcbiAgICAgICAgcmV0dXJuIGlpID4gbWF4SW5kZXggPyBpdGVyYXRvckRvbmUoKSA6IGl0ZXJhdG9yVmFsdWUodHlwZSwgaWkrKywgdik7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgUmFuZ2UucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICByZXR1cm4gb3RoZXIgaW5zdGFuY2VvZiBSYW5nZSA/XG4gICAgICAgIHRoaXMuX3N0YXJ0ID09PSBvdGhlci5fc3RhcnQgJiZcbiAgICAgICAgdGhpcy5fZW5kID09PSBvdGhlci5fZW5kICYmXG4gICAgICAgIHRoaXMuX3N0ZXAgPT09IG90aGVyLl9zdGVwIDpcbiAgICAgICAgZGVlcEVxdWFsKHRoaXMsIG90aGVyKTtcbiAgICB9O1xuXG5cbiAgdmFyIEVNUFRZX1JBTkdFO1xuXG4gIGNyZWF0ZUNsYXNzKENvbGxlY3Rpb24sIEl0ZXJhYmxlKTtcbiAgICBmdW5jdGlvbiBDb2xsZWN0aW9uKCkge1xuICAgICAgdGhyb3cgVHlwZUVycm9yKCdBYnN0cmFjdCcpO1xuICAgIH1cblxuXG4gIGNyZWF0ZUNsYXNzKEtleWVkQ29sbGVjdGlvbiwgQ29sbGVjdGlvbik7ZnVuY3Rpb24gS2V5ZWRDb2xsZWN0aW9uKCkge31cblxuICBjcmVhdGVDbGFzcyhJbmRleGVkQ29sbGVjdGlvbiwgQ29sbGVjdGlvbik7ZnVuY3Rpb24gSW5kZXhlZENvbGxlY3Rpb24oKSB7fVxuXG4gIGNyZWF0ZUNsYXNzKFNldENvbGxlY3Rpb24sIENvbGxlY3Rpb24pO2Z1bmN0aW9uIFNldENvbGxlY3Rpb24oKSB7fVxuXG5cbiAgQ29sbGVjdGlvbi5LZXllZCA9IEtleWVkQ29sbGVjdGlvbjtcbiAgQ29sbGVjdGlvbi5JbmRleGVkID0gSW5kZXhlZENvbGxlY3Rpb247XG4gIENvbGxlY3Rpb24uU2V0ID0gU2V0Q29sbGVjdGlvbjtcblxuICB2YXIgaW11bCA9XG4gICAgdHlwZW9mIE1hdGguaW11bCA9PT0gJ2Z1bmN0aW9uJyAmJiBNYXRoLmltdWwoMHhmZmZmZmZmZiwgMikgPT09IC0yID9cbiAgICBNYXRoLmltdWwgOlxuICAgIGZ1bmN0aW9uIGltdWwoYSwgYikge1xuICAgICAgYSA9IGEgfCAwOyAvLyBpbnRcbiAgICAgIGIgPSBiIHwgMDsgLy8gaW50XG4gICAgICB2YXIgYyA9IGEgJiAweGZmZmY7XG4gICAgICB2YXIgZCA9IGIgJiAweGZmZmY7XG4gICAgICAvLyBTaGlmdCBieSAwIGZpeGVzIHRoZSBzaWduIG9uIHRoZSBoaWdoIHBhcnQuXG4gICAgICByZXR1cm4gKGMgKiBkKSArICgoKChhID4+PiAxNikgKiBkICsgYyAqIChiID4+PiAxNikpIDw8IDE2KSA+Pj4gMCkgfCAwOyAvLyBpbnRcbiAgICB9O1xuXG4gIC8vIHY4IGhhcyBhbiBvcHRpbWl6YXRpb24gZm9yIHN0b3JpbmcgMzEtYml0IHNpZ25lZCBudW1iZXJzLlxuICAvLyBWYWx1ZXMgd2hpY2ggaGF2ZSBlaXRoZXIgMDAgb3IgMTEgYXMgdGhlIGhpZ2ggb3JkZXIgYml0cyBxdWFsaWZ5LlxuICAvLyBUaGlzIGZ1bmN0aW9uIGRyb3BzIHRoZSBoaWdoZXN0IG9yZGVyIGJpdCBpbiBhIHNpZ25lZCBudW1iZXIsIG1haW50YWluaW5nXG4gIC8vIHRoZSBzaWduIGJpdC5cbiAgZnVuY3Rpb24gc21pKGkzMikge1xuICAgIHJldHVybiAoKGkzMiA+Pj4gMSkgJiAweDQwMDAwMDAwKSB8IChpMzIgJiAweEJGRkZGRkZGKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhc2gobykge1xuICAgIGlmIChvID09PSBmYWxzZSB8fCBvID09PSBudWxsIHx8IG8gPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygby52YWx1ZU9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBvID0gby52YWx1ZU9mKCk7XG4gICAgICBpZiAobyA9PT0gZmFsc2UgfHwgbyA9PT0gbnVsbCB8fCBvID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChvID09PSB0cnVlKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gICAgdmFyIHR5cGUgPSB0eXBlb2YgbztcbiAgICBpZiAodHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGlmIChvICE9PSBvIHx8IG8gPT09IEluZmluaXR5KSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgICAgdmFyIGggPSBvIHwgMDtcbiAgICAgIGlmIChoICE9PSBvKSB7XG4gICAgICAgIGggXj0gbyAqIDB4RkZGRkZGRkY7XG4gICAgICB9XG4gICAgICB3aGlsZSAobyA+IDB4RkZGRkZGRkYpIHtcbiAgICAgICAgbyAvPSAweEZGRkZGRkZGO1xuICAgICAgICBoIF49IG87XG4gICAgICB9XG4gICAgICByZXR1cm4gc21pKGgpO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBvLmxlbmd0aCA+IFNUUklOR19IQVNIX0NBQ0hFX01JTl9TVFJMRU4gPyBjYWNoZWRIYXNoU3RyaW5nKG8pIDogaGFzaFN0cmluZyhvKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvLmhhc2hDb2RlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gby5oYXNoQ29kZSgpO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiBoYXNoSlNPYmoobyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygby50b1N0cmluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIGhhc2hTdHJpbmcoby50b1N0cmluZygpKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKCdWYWx1ZSB0eXBlICcgKyB0eXBlICsgJyBjYW5ub3QgYmUgaGFzaGVkLicpO1xuICB9XG5cbiAgZnVuY3Rpb24gY2FjaGVkSGFzaFN0cmluZyhzdHJpbmcpIHtcbiAgICB2YXIgaGFzaCA9IHN0cmluZ0hhc2hDYWNoZVtzdHJpbmddO1xuICAgIGlmIChoYXNoID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGhhc2ggPSBoYXNoU3RyaW5nKHN0cmluZyk7XG4gICAgICBpZiAoU1RSSU5HX0hBU0hfQ0FDSEVfU0laRSA9PT0gU1RSSU5HX0hBU0hfQ0FDSEVfTUFYX1NJWkUpIHtcbiAgICAgICAgU1RSSU5HX0hBU0hfQ0FDSEVfU0laRSA9IDA7XG4gICAgICAgIHN0cmluZ0hhc2hDYWNoZSA9IHt9O1xuICAgICAgfVxuICAgICAgU1RSSU5HX0hBU0hfQ0FDSEVfU0laRSsrO1xuICAgICAgc3RyaW5nSGFzaENhY2hlW3N0cmluZ10gPSBoYXNoO1xuICAgIH1cbiAgICByZXR1cm4gaGFzaDtcbiAgfVxuXG4gIC8vIGh0dHA6Ly9qc3BlcmYuY29tL2hhc2hpbmctc3RyaW5nc1xuICBmdW5jdGlvbiBoYXNoU3RyaW5nKHN0cmluZykge1xuICAgIC8vIFRoaXMgaXMgdGhlIGhhc2ggZnJvbSBKVk1cbiAgICAvLyBUaGUgaGFzaCBjb2RlIGZvciBhIHN0cmluZyBpcyBjb21wdXRlZCBhc1xuICAgIC8vIHNbMF0gKiAzMSBeIChuIC0gMSkgKyBzWzFdICogMzEgXiAobiAtIDIpICsgLi4uICsgc1tuIC0gMV0sXG4gICAgLy8gd2hlcmUgc1tpXSBpcyB0aGUgaXRoIGNoYXJhY3RlciBvZiB0aGUgc3RyaW5nIGFuZCBuIGlzIHRoZSBsZW5ndGggb2ZcbiAgICAvLyB0aGUgc3RyaW5nLiBXZSBcIm1vZFwiIHRoZSByZXN1bHQgdG8gbWFrZSBpdCBiZXR3ZWVuIDAgKGluY2x1c2l2ZSkgYW5kIDJeMzFcbiAgICAvLyAoZXhjbHVzaXZlKSBieSBkcm9wcGluZyBoaWdoIGJpdHMuXG4gICAgdmFyIGhhc2ggPSAwO1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCBzdHJpbmcubGVuZ3RoOyBpaSsrKSB7XG4gICAgICBoYXNoID0gMzEgKiBoYXNoICsgc3RyaW5nLmNoYXJDb2RlQXQoaWkpIHwgMDtcbiAgICB9XG4gICAgcmV0dXJuIHNtaShoYXNoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhc2hKU09iaihvYmopIHtcbiAgICB2YXIgaGFzaDtcbiAgICBpZiAodXNpbmdXZWFrTWFwKSB7XG4gICAgICBoYXNoID0gd2Vha01hcC5nZXQob2JqKTtcbiAgICAgIGlmIChoYXNoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGhhc2g7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaGFzaCA9IG9ialtVSURfSEFTSF9LRVldO1xuICAgIGlmIChoYXNoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBoYXNoO1xuICAgIH1cblxuICAgIGlmICghY2FuRGVmaW5lUHJvcGVydHkpIHtcbiAgICAgIGhhc2ggPSBvYmoucHJvcGVydHlJc0VudW1lcmFibGUgJiYgb2JqLnByb3BlcnR5SXNFbnVtZXJhYmxlW1VJRF9IQVNIX0tFWV07XG4gICAgICBpZiAoaGFzaCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBoYXNoO1xuICAgICAgfVxuXG4gICAgICBoYXNoID0gZ2V0SUVOb2RlSGFzaChvYmopO1xuICAgICAgaWYgKGhhc2ggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gaGFzaDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBoYXNoID0gKytvYmpIYXNoVUlEO1xuICAgIGlmIChvYmpIYXNoVUlEICYgMHg0MDAwMDAwMCkge1xuICAgICAgb2JqSGFzaFVJRCA9IDA7XG4gICAgfVxuXG4gICAgaWYgKHVzaW5nV2Vha01hcCkge1xuICAgICAgd2Vha01hcC5zZXQob2JqLCBoYXNoKTtcbiAgICB9IGVsc2UgaWYgKGlzRXh0ZW5zaWJsZSAhPT0gdW5kZWZpbmVkICYmIGlzRXh0ZW5zaWJsZShvYmopID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb24tZXh0ZW5zaWJsZSBvYmplY3RzIGFyZSBub3QgYWxsb3dlZCBhcyBrZXlzLicpO1xuICAgIH0gZWxzZSBpZiAoY2FuRGVmaW5lUHJvcGVydHkpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIFVJRF9IQVNIX0tFWSwge1xuICAgICAgICAnZW51bWVyYWJsZSc6IGZhbHNlLFxuICAgICAgICAnY29uZmlndXJhYmxlJzogZmFsc2UsXG4gICAgICAgICd3cml0YWJsZSc6IGZhbHNlLFxuICAgICAgICAndmFsdWUnOiBoYXNoXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKG9iai5wcm9wZXJ0eUlzRW51bWVyYWJsZSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICBvYmoucHJvcGVydHlJc0VudW1lcmFibGUgPT09IG9iai5jb25zdHJ1Y3Rvci5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUpIHtcbiAgICAgIC8vIFNpbmNlIHdlIGNhbid0IGRlZmluZSBhIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5IG9uIHRoZSBvYmplY3RcbiAgICAgIC8vIHdlJ2xsIGhpamFjayBvbmUgb2YgdGhlIGxlc3MtdXNlZCBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzIHRvXG4gICAgICAvLyBzYXZlIG91ciBoYXNoIG9uIGl0LiBTaW5jZSB0aGlzIGlzIGEgZnVuY3Rpb24gaXQgd2lsbCBub3Qgc2hvdyB1cCBpblxuICAgICAgLy8gYEpTT04uc3RyaW5naWZ5YCB3aGljaCBpcyB3aGF0IHdlIHdhbnQuXG4gICAgICBvYmoucHJvcGVydHlJc0VudW1lcmFibGUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgICAgb2JqLnByb3BlcnR5SXNFbnVtZXJhYmxlW1VJRF9IQVNIX0tFWV0gPSBoYXNoO1xuICAgIH0gZWxzZSBpZiAob2JqLm5vZGVUeXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIEF0IHRoaXMgcG9pbnQgd2UgY291bGRuJ3QgZ2V0IHRoZSBJRSBgdW5pcXVlSURgIHRvIHVzZSBhcyBhIGhhc2hcbiAgICAgIC8vIGFuZCB3ZSBjb3VsZG4ndCB1c2UgYSBub24tZW51bWVyYWJsZSBwcm9wZXJ0eSB0byBleHBsb2l0IHRoZVxuICAgICAgLy8gZG9udEVudW0gYnVnIHNvIHdlIHNpbXBseSBhZGQgdGhlIGBVSURfSEFTSF9LRVlgIG9uIHRoZSBub2RlXG4gICAgICAvLyBpdHNlbGYuXG4gICAgICBvYmpbVUlEX0hBU0hfS0VZXSA9IGhhc2g7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIHNldCBhIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5IG9uIG9iamVjdC4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaGFzaDtcbiAgfVxuXG4gIC8vIEdldCByZWZlcmVuY2VzIHRvIEVTNSBvYmplY3QgbWV0aG9kcy5cbiAgdmFyIGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGU7XG5cbiAgLy8gVHJ1ZSBpZiBPYmplY3QuZGVmaW5lUHJvcGVydHkgd29ya3MgYXMgZXhwZWN0ZWQuIElFOCBmYWlscyB0aGlzIHRlc3QuXG4gIHZhciBjYW5EZWZpbmVQcm9wZXJ0eSA9IChmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnQCcsIHt9KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0oKSk7XG5cbiAgLy8gSUUgaGFzIGEgYHVuaXF1ZUlEYCBwcm9wZXJ0eSBvbiBET00gbm9kZXMuIFdlIGNhbiBjb25zdHJ1Y3QgdGhlIGhhc2ggZnJvbSBpdFxuICAvLyBhbmQgYXZvaWQgbWVtb3J5IGxlYWtzIGZyb20gdGhlIElFIGNsb25lTm9kZSBidWcuXG4gIGZ1bmN0aW9uIGdldElFTm9kZUhhc2gobm9kZSkge1xuICAgIGlmIChub2RlICYmIG5vZGUubm9kZVR5cGUgPiAwKSB7XG4gICAgICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICAgICAgY2FzZSAxOiAvLyBFbGVtZW50XG4gICAgICAgICAgcmV0dXJuIG5vZGUudW5pcXVlSUQ7XG4gICAgICAgIGNhc2UgOTogLy8gRG9jdW1lbnRcbiAgICAgICAgICByZXR1cm4gbm9kZS5kb2N1bWVudEVsZW1lbnQgJiYgbm9kZS5kb2N1bWVudEVsZW1lbnQudW5pcXVlSUQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gSWYgcG9zc2libGUsIHVzZSBhIFdlYWtNYXAuXG4gIHZhciB1c2luZ1dlYWtNYXAgPSB0eXBlb2YgV2Vha01hcCA9PT0gJ2Z1bmN0aW9uJztcbiAgdmFyIHdlYWtNYXA7XG4gIGlmICh1c2luZ1dlYWtNYXApIHtcbiAgICB3ZWFrTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgfVxuXG4gIHZhciBvYmpIYXNoVUlEID0gMDtcblxuICB2YXIgVUlEX0hBU0hfS0VZID0gJ19faW1tdXRhYmxlaGFzaF9fJztcbiAgaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicpIHtcbiAgICBVSURfSEFTSF9LRVkgPSBTeW1ib2woVUlEX0hBU0hfS0VZKTtcbiAgfVxuXG4gIHZhciBTVFJJTkdfSEFTSF9DQUNIRV9NSU5fU1RSTEVOID0gMTY7XG4gIHZhciBTVFJJTkdfSEFTSF9DQUNIRV9NQVhfU0laRSA9IDI1NTtcbiAgdmFyIFNUUklOR19IQVNIX0NBQ0hFX1NJWkUgPSAwO1xuICB2YXIgc3RyaW5nSGFzaENhY2hlID0ge307XG5cbiAgZnVuY3Rpb24gYXNzZXJ0Tm90SW5maW5pdGUoc2l6ZSkge1xuICAgIGludmFyaWFudChcbiAgICAgIHNpemUgIT09IEluZmluaXR5LFxuICAgICAgJ0Nhbm5vdCBwZXJmb3JtIHRoaXMgYWN0aW9uIHdpdGggYW4gaW5maW5pdGUgc2l6ZS4nXG4gICAgKTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKE1hcCwgS2V5ZWRDb2xsZWN0aW9uKTtcblxuICAgIC8vIEBwcmFnbWEgQ29uc3RydWN0aW9uXG5cbiAgICBmdW5jdGlvbiBNYXAodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gZW1wdHlNYXAoKSA6XG4gICAgICAgIGlzTWFwKHZhbHVlKSAmJiAhaXNPcmRlcmVkKHZhbHVlKSA/IHZhbHVlIDpcbiAgICAgICAgZW1wdHlNYXAoKS53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKG1hcCApIHtcbiAgICAgICAgICB2YXIgaXRlciA9IEtleWVkSXRlcmFibGUodmFsdWUpO1xuICAgICAgICAgIGFzc2VydE5vdEluZmluaXRlKGl0ZXIuc2l6ZSk7XG4gICAgICAgICAgaXRlci5mb3JFYWNoKGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIG1hcC5zZXQoaywgdil9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgTWFwLm9mID0gZnVuY3Rpb24oKSB7dmFyIGtleVZhbHVlcyA9IFNMSUNFJDAuY2FsbChhcmd1bWVudHMsIDApO1xuICAgICAgcmV0dXJuIGVtcHR5TWFwKCkud2l0aE11dGF0aW9ucyhmdW5jdGlvbihtYXAgKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5VmFsdWVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgICAgaWYgKGkgKyAxID49IGtleVZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB2YWx1ZSBmb3Iga2V5OiAnICsga2V5VmFsdWVzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbWFwLnNldChrZXlWYWx1ZXNbaV0sIGtleVZhbHVlc1tpICsgMV0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX190b1N0cmluZygnTWFwIHsnLCAnfScpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIEFjY2Vzc1xuXG4gICAgTWFwLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihrLCBub3RTZXRWYWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3Jvb3QgP1xuICAgICAgICB0aGlzLl9yb290LmdldCgwLCB1bmRlZmluZWQsIGssIG5vdFNldFZhbHVlKSA6XG4gICAgICAgIG5vdFNldFZhbHVlO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIE1vZGlmaWNhdGlvblxuXG4gICAgTWFwLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbihrLCB2KSB7XG4gICAgICByZXR1cm4gdXBkYXRlTWFwKHRoaXMsIGssIHYpO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLnNldEluID0gZnVuY3Rpb24oa2V5UGF0aCwgdikge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlSW4oa2V5UGF0aCwgTk9UX1NFVCwgZnVuY3Rpb24oKSAge3JldHVybiB2fSk7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oaykge1xuICAgICAgcmV0dXJuIHVwZGF0ZU1hcCh0aGlzLCBrLCBOT1RfU0VUKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5kZWxldGVJbiA9IGZ1bmN0aW9uKGtleVBhdGgpIHtcbiAgICAgIHJldHVybiB0aGlzLnVwZGF0ZUluKGtleVBhdGgsIGZ1bmN0aW9uKCkgIHtyZXR1cm4gTk9UX1NFVH0pO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKGssIG5vdFNldFZhbHVlLCB1cGRhdGVyKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/XG4gICAgICAgIGsodGhpcykgOlxuICAgICAgICB0aGlzLnVwZGF0ZUluKFtrXSwgbm90U2V0VmFsdWUsIHVwZGF0ZXIpO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLnVwZGF0ZUluID0gZnVuY3Rpb24oa2V5UGF0aCwgbm90U2V0VmFsdWUsIHVwZGF0ZXIpIHtcbiAgICAgIGlmICghdXBkYXRlcikge1xuICAgICAgICB1cGRhdGVyID0gbm90U2V0VmFsdWU7XG4gICAgICAgIG5vdFNldFZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgdmFyIHVwZGF0ZWRWYWx1ZSA9IHVwZGF0ZUluRGVlcE1hcChcbiAgICAgICAgdGhpcyxcbiAgICAgICAgZm9yY2VJdGVyYXRvcihrZXlQYXRoKSxcbiAgICAgICAgbm90U2V0VmFsdWUsXG4gICAgICAgIHVwZGF0ZXJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdXBkYXRlZFZhbHVlID09PSBOT1RfU0VUID8gdW5kZWZpbmVkIDogdXBkYXRlZFZhbHVlO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHRoaXMuc2l6ZSA9IDA7XG4gICAgICAgIHRoaXMuX3Jvb3QgPSBudWxsO1xuICAgICAgICB0aGlzLl9faGFzaCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fX2FsdGVyZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbXB0eU1hcCgpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIENvbXBvc2l0aW9uXG5cbiAgICBNYXAucHJvdG90eXBlLm1lcmdlID0gZnVuY3Rpb24oLyouLi5pdGVycyovKSB7XG4gICAgICByZXR1cm4gbWVyZ2VJbnRvTWFwV2l0aCh0aGlzLCB1bmRlZmluZWQsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUubWVyZ2VXaXRoID0gZnVuY3Rpb24obWVyZ2VyKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICByZXR1cm4gbWVyZ2VJbnRvTWFwV2l0aCh0aGlzLCBtZXJnZXIsIGl0ZXJzKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5tZXJnZUluID0gZnVuY3Rpb24oa2V5UGF0aCkge3ZhciBpdGVycyA9IFNMSUNFJDAuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlSW4oXG4gICAgICAgIGtleVBhdGgsXG4gICAgICAgIGVtcHR5TWFwKCksXG4gICAgICAgIGZ1bmN0aW9uKG0gKSB7cmV0dXJuIHR5cGVvZiBtLm1lcmdlID09PSAnZnVuY3Rpb24nID9cbiAgICAgICAgICBtLm1lcmdlLmFwcGx5KG0sIGl0ZXJzKSA6XG4gICAgICAgICAgaXRlcnNbaXRlcnMubGVuZ3RoIC0gMV19XG4gICAgICApO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLm1lcmdlRGVlcCA9IGZ1bmN0aW9uKC8qLi4uaXRlcnMqLykge1xuICAgICAgcmV0dXJuIG1lcmdlSW50b01hcFdpdGgodGhpcywgZGVlcE1lcmdlciwgYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5tZXJnZURlZXBXaXRoID0gZnVuY3Rpb24obWVyZ2VyKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICByZXR1cm4gbWVyZ2VJbnRvTWFwV2l0aCh0aGlzLCBkZWVwTWVyZ2VyV2l0aChtZXJnZXIpLCBpdGVycyk7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUubWVyZ2VEZWVwSW4gPSBmdW5jdGlvbihrZXlQYXRoKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICByZXR1cm4gdGhpcy51cGRhdGVJbihcbiAgICAgICAga2V5UGF0aCxcbiAgICAgICAgZW1wdHlNYXAoKSxcbiAgICAgICAgZnVuY3Rpb24obSApIHtyZXR1cm4gdHlwZW9mIG0ubWVyZ2VEZWVwID09PSAnZnVuY3Rpb24nID9cbiAgICAgICAgICBtLm1lcmdlRGVlcC5hcHBseShtLCBpdGVycykgOlxuICAgICAgICAgIGl0ZXJzW2l0ZXJzLmxlbmd0aCAtIDFdfVxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5zb3J0ID0gZnVuY3Rpb24oY29tcGFyYXRvcikge1xuICAgICAgLy8gTGF0ZSBiaW5kaW5nXG4gICAgICByZXR1cm4gT3JkZXJlZE1hcChzb3J0RmFjdG9yeSh0aGlzLCBjb21wYXJhdG9yKSk7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUuc29ydEJ5ID0gZnVuY3Rpb24obWFwcGVyLCBjb21wYXJhdG9yKSB7XG4gICAgICAvLyBMYXRlIGJpbmRpbmdcbiAgICAgIHJldHVybiBPcmRlcmVkTWFwKHNvcnRGYWN0b3J5KHRoaXMsIGNvbXBhcmF0b3IsIG1hcHBlcikpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIE11dGFiaWxpdHlcblxuICAgIE1hcC5wcm90b3R5cGUud2l0aE11dGF0aW9ucyA9IGZ1bmN0aW9uKGZuKSB7XG4gICAgICB2YXIgbXV0YWJsZSA9IHRoaXMuYXNNdXRhYmxlKCk7XG4gICAgICBmbihtdXRhYmxlKTtcbiAgICAgIHJldHVybiBtdXRhYmxlLndhc0FsdGVyZWQoKSA/IG11dGFibGUuX19lbnN1cmVPd25lcih0aGlzLl9fb3duZXJJRCkgOiB0aGlzO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLmFzTXV0YWJsZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX19vd25lcklEID8gdGhpcyA6IHRoaXMuX19lbnN1cmVPd25lcihuZXcgT3duZXJJRCgpKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5hc0ltbXV0YWJsZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX19lbnN1cmVPd25lcigpO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLndhc0FsdGVyZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fYWx0ZXJlZDtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgcmV0dXJuIG5ldyBNYXBJdGVyYXRvcih0aGlzLCB0eXBlLCByZXZlcnNlKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgdGhpcy5fcm9vdCAmJiB0aGlzLl9yb290Lml0ZXJhdGUoZnVuY3Rpb24oZW50cnkgKSB7XG4gICAgICAgIGl0ZXJhdGlvbnMrKztcbiAgICAgICAgcmV0dXJuIGZuKGVudHJ5WzFdLCBlbnRyeVswXSwgdGhpcyQwKTtcbiAgICAgIH0sIHJldmVyc2UpO1xuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUuX19lbnN1cmVPd25lciA9IGZ1bmN0aW9uKG93bmVySUQpIHtcbiAgICAgIGlmIChvd25lcklEID09PSB0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICghb3duZXJJRCkge1xuICAgICAgICB0aGlzLl9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgICAgIHRoaXMuX19hbHRlcmVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VNYXAodGhpcy5zaXplLCB0aGlzLl9yb290LCBvd25lcklELCB0aGlzLl9faGFzaCk7XG4gICAgfTtcblxuXG4gIGZ1bmN0aW9uIGlzTWFwKG1heWJlTWFwKSB7XG4gICAgcmV0dXJuICEhKG1heWJlTWFwICYmIG1heWJlTWFwW0lTX01BUF9TRU5USU5FTF0pO1xuICB9XG5cbiAgTWFwLmlzTWFwID0gaXNNYXA7XG5cbiAgdmFyIElTX01BUF9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX01BUF9fQEAnO1xuXG4gIHZhciBNYXBQcm90b3R5cGUgPSBNYXAucHJvdG90eXBlO1xuICBNYXBQcm90b3R5cGVbSVNfTUFQX1NFTlRJTkVMXSA9IHRydWU7XG4gIE1hcFByb3RvdHlwZVtERUxFVEVdID0gTWFwUHJvdG90eXBlLnJlbW92ZTtcbiAgTWFwUHJvdG90eXBlLnJlbW92ZUluID0gTWFwUHJvdG90eXBlLmRlbGV0ZUluO1xuXG5cbiAgLy8gI3ByYWdtYSBUcmllIE5vZGVzXG5cblxuXG4gICAgZnVuY3Rpb24gQXJyYXlNYXBOb2RlKG93bmVySUQsIGVudHJpZXMpIHtcbiAgICAgIHRoaXMub3duZXJJRCA9IG93bmVySUQ7XG4gICAgICB0aGlzLmVudHJpZXMgPSBlbnRyaWVzO1xuICAgIH1cblxuICAgIEFycmF5TWFwTm9kZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oc2hpZnQsIGtleUhhc2gsIGtleSwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHZhciBlbnRyaWVzID0gdGhpcy5lbnRyaWVzO1xuICAgICAgZm9yICh2YXIgaWkgPSAwLCBsZW4gPSBlbnRyaWVzLmxlbmd0aDsgaWkgPCBsZW47IGlpKyspIHtcbiAgICAgICAgaWYgKGlzKGtleSwgZW50cmllc1tpaV1bMF0pKSB7XG4gICAgICAgICAgcmV0dXJuIGVudHJpZXNbaWldWzFdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbm90U2V0VmFsdWU7XG4gICAgfTtcblxuICAgIEFycmF5TWFwTm9kZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24ob3duZXJJRCwgc2hpZnQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKSB7XG4gICAgICB2YXIgcmVtb3ZlZCA9IHZhbHVlID09PSBOT1RfU0VUO1xuXG4gICAgICB2YXIgZW50cmllcyA9IHRoaXMuZW50cmllcztcbiAgICAgIHZhciBpZHggPSAwO1xuICAgICAgZm9yICh2YXIgbGVuID0gZW50cmllcy5sZW5ndGg7IGlkeCA8IGxlbjsgaWR4KyspIHtcbiAgICAgICAgaWYgKGlzKGtleSwgZW50cmllc1tpZHhdWzBdKSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB2YXIgZXhpc3RzID0gaWR4IDwgbGVuO1xuXG4gICAgICBpZiAoZXhpc3RzID8gZW50cmllc1tpZHhdWzFdID09PSB2YWx1ZSA6IHJlbW92ZWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIFNldFJlZihkaWRBbHRlcik7XG4gICAgICAocmVtb3ZlZCB8fCAhZXhpc3RzKSAmJiBTZXRSZWYoZGlkQ2hhbmdlU2l6ZSk7XG5cbiAgICAgIGlmIChyZW1vdmVkICYmIGVudHJpZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHJldHVybjsgLy8gdW5kZWZpbmVkXG4gICAgICB9XG5cbiAgICAgIGlmICghZXhpc3RzICYmICFyZW1vdmVkICYmIGVudHJpZXMubGVuZ3RoID49IE1BWF9BUlJBWV9NQVBfU0laRSkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTm9kZXMob3duZXJJRCwgZW50cmllcywga2V5LCB2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBpc0VkaXRhYmxlID0gb3duZXJJRCAmJiBvd25lcklEID09PSB0aGlzLm93bmVySUQ7XG4gICAgICB2YXIgbmV3RW50cmllcyA9IGlzRWRpdGFibGUgPyBlbnRyaWVzIDogYXJyQ29weShlbnRyaWVzKTtcblxuICAgICAgaWYgKGV4aXN0cykge1xuICAgICAgICBpZiAocmVtb3ZlZCkge1xuICAgICAgICAgIGlkeCA9PT0gbGVuIC0gMSA/IG5ld0VudHJpZXMucG9wKCkgOiAobmV3RW50cmllc1tpZHhdID0gbmV3RW50cmllcy5wb3AoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3RW50cmllc1tpZHhdID0gW2tleSwgdmFsdWVdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdFbnRyaWVzLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzRWRpdGFibGUpIHtcbiAgICAgICAgdGhpcy5lbnRyaWVzID0gbmV3RW50cmllcztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgQXJyYXlNYXBOb2RlKG93bmVySUQsIG5ld0VudHJpZXMpO1xuICAgIH07XG5cblxuXG5cbiAgICBmdW5jdGlvbiBCaXRtYXBJbmRleGVkTm9kZShvd25lcklELCBiaXRtYXAsIG5vZGVzKSB7XG4gICAgICB0aGlzLm93bmVySUQgPSBvd25lcklEO1xuICAgICAgdGhpcy5iaXRtYXAgPSBiaXRtYXA7XG4gICAgICB0aGlzLm5vZGVzID0gbm9kZXM7XG4gICAgfVxuXG4gICAgQml0bWFwSW5kZXhlZE5vZGUucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHNoaWZ0LCBrZXlIYXNoLCBrZXksIG5vdFNldFZhbHVlKSB7XG4gICAgICBpZiAoa2V5SGFzaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGtleUhhc2ggPSBoYXNoKGtleSk7XG4gICAgICB9XG4gICAgICB2YXIgYml0ID0gKDEgPDwgKChzaGlmdCA9PT0gMCA/IGtleUhhc2ggOiBrZXlIYXNoID4+PiBzaGlmdCkgJiBNQVNLKSk7XG4gICAgICB2YXIgYml0bWFwID0gdGhpcy5iaXRtYXA7XG4gICAgICByZXR1cm4gKGJpdG1hcCAmIGJpdCkgPT09IDAgPyBub3RTZXRWYWx1ZSA6XG4gICAgICAgIHRoaXMubm9kZXNbcG9wQ291bnQoYml0bWFwICYgKGJpdCAtIDEpKV0uZ2V0KHNoaWZ0ICsgU0hJRlQsIGtleUhhc2gsIGtleSwgbm90U2V0VmFsdWUpO1xuICAgIH07XG5cbiAgICBCaXRtYXBJbmRleGVkTm9kZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24ob3duZXJJRCwgc2hpZnQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKSB7XG4gICAgICBpZiAoa2V5SGFzaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGtleUhhc2ggPSBoYXNoKGtleSk7XG4gICAgICB9XG4gICAgICB2YXIga2V5SGFzaEZyYWcgPSAoc2hpZnQgPT09IDAgPyBrZXlIYXNoIDoga2V5SGFzaCA+Pj4gc2hpZnQpICYgTUFTSztcbiAgICAgIHZhciBiaXQgPSAxIDw8IGtleUhhc2hGcmFnO1xuICAgICAgdmFyIGJpdG1hcCA9IHRoaXMuYml0bWFwO1xuICAgICAgdmFyIGV4aXN0cyA9IChiaXRtYXAgJiBiaXQpICE9PSAwO1xuXG4gICAgICBpZiAoIWV4aXN0cyAmJiB2YWx1ZSA9PT0gTk9UX1NFVCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgdmFyIGlkeCA9IHBvcENvdW50KGJpdG1hcCAmIChiaXQgLSAxKSk7XG4gICAgICB2YXIgbm9kZXMgPSB0aGlzLm5vZGVzO1xuICAgICAgdmFyIG5vZGUgPSBleGlzdHMgPyBub2Rlc1tpZHhdIDogdW5kZWZpbmVkO1xuICAgICAgdmFyIG5ld05vZGUgPSB1cGRhdGVOb2RlKG5vZGUsIG93bmVySUQsIHNoaWZ0ICsgU0hJRlQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKTtcblxuICAgICAgaWYgKG5ld05vZGUgPT09IG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGlmICghZXhpc3RzICYmIG5ld05vZGUgJiYgbm9kZXMubGVuZ3RoID49IE1BWF9CSVRNQVBfSU5ERVhFRF9TSVpFKSB7XG4gICAgICAgIHJldHVybiBleHBhbmROb2Rlcyhvd25lcklELCBub2RlcywgYml0bWFwLCBrZXlIYXNoRnJhZywgbmV3Tm9kZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChleGlzdHMgJiYgIW5ld05vZGUgJiYgbm9kZXMubGVuZ3RoID09PSAyICYmIGlzTGVhZk5vZGUobm9kZXNbaWR4IF4gMV0pKSB7XG4gICAgICAgIHJldHVybiBub2Rlc1tpZHggXiAxXTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV4aXN0cyAmJiBuZXdOb2RlICYmIG5vZGVzLmxlbmd0aCA9PT0gMSAmJiBpc0xlYWZOb2RlKG5ld05vZGUpKSB7XG4gICAgICAgIHJldHVybiBuZXdOb2RlO1xuICAgICAgfVxuXG4gICAgICB2YXIgaXNFZGl0YWJsZSA9IG93bmVySUQgJiYgb3duZXJJRCA9PT0gdGhpcy5vd25lcklEO1xuICAgICAgdmFyIG5ld0JpdG1hcCA9IGV4aXN0cyA/IG5ld05vZGUgPyBiaXRtYXAgOiBiaXRtYXAgXiBiaXQgOiBiaXRtYXAgfCBiaXQ7XG4gICAgICB2YXIgbmV3Tm9kZXMgPSBleGlzdHMgPyBuZXdOb2RlID9cbiAgICAgICAgc2V0SW4obm9kZXMsIGlkeCwgbmV3Tm9kZSwgaXNFZGl0YWJsZSkgOlxuICAgICAgICBzcGxpY2VPdXQobm9kZXMsIGlkeCwgaXNFZGl0YWJsZSkgOlxuICAgICAgICBzcGxpY2VJbihub2RlcywgaWR4LCBuZXdOb2RlLCBpc0VkaXRhYmxlKTtcblxuICAgICAgaWYgKGlzRWRpdGFibGUpIHtcbiAgICAgICAgdGhpcy5iaXRtYXAgPSBuZXdCaXRtYXA7XG4gICAgICAgIHRoaXMubm9kZXMgPSBuZXdOb2RlcztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgQml0bWFwSW5kZXhlZE5vZGUob3duZXJJRCwgbmV3Qml0bWFwLCBuZXdOb2Rlcyk7XG4gICAgfTtcblxuXG5cblxuICAgIGZ1bmN0aW9uIEhhc2hBcnJheU1hcE5vZGUob3duZXJJRCwgY291bnQsIG5vZGVzKSB7XG4gICAgICB0aGlzLm93bmVySUQgPSBvd25lcklEO1xuICAgICAgdGhpcy5jb3VudCA9IGNvdW50O1xuICAgICAgdGhpcy5ub2RlcyA9IG5vZGVzO1xuICAgIH1cblxuICAgIEhhc2hBcnJheU1hcE5vZGUucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHNoaWZ0LCBrZXlIYXNoLCBrZXksIG5vdFNldFZhbHVlKSB7XG4gICAgICBpZiAoa2V5SGFzaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGtleUhhc2ggPSBoYXNoKGtleSk7XG4gICAgICB9XG4gICAgICB2YXIgaWR4ID0gKHNoaWZ0ID09PSAwID8ga2V5SGFzaCA6IGtleUhhc2ggPj4+IHNoaWZ0KSAmIE1BU0s7XG4gICAgICB2YXIgbm9kZSA9IHRoaXMubm9kZXNbaWR4XTtcbiAgICAgIHJldHVybiBub2RlID8gbm9kZS5nZXQoc2hpZnQgKyBTSElGVCwga2V5SGFzaCwga2V5LCBub3RTZXRWYWx1ZSkgOiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgSGFzaEFycmF5TWFwTm9kZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24ob3duZXJJRCwgc2hpZnQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKSB7XG4gICAgICBpZiAoa2V5SGFzaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGtleUhhc2ggPSBoYXNoKGtleSk7XG4gICAgICB9XG4gICAgICB2YXIgaWR4ID0gKHNoaWZ0ID09PSAwID8ga2V5SGFzaCA6IGtleUhhc2ggPj4+IHNoaWZ0KSAmIE1BU0s7XG4gICAgICB2YXIgcmVtb3ZlZCA9IHZhbHVlID09PSBOT1RfU0VUO1xuICAgICAgdmFyIG5vZGVzID0gdGhpcy5ub2RlcztcbiAgICAgIHZhciBub2RlID0gbm9kZXNbaWR4XTtcblxuICAgICAgaWYgKHJlbW92ZWQgJiYgIW5vZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIHZhciBuZXdOb2RlID0gdXBkYXRlTm9kZShub2RlLCBvd25lcklELCBzaGlmdCArIFNISUZULCBrZXlIYXNoLCBrZXksIHZhbHVlLCBkaWRDaGFuZ2VTaXplLCBkaWRBbHRlcik7XG4gICAgICBpZiAobmV3Tm9kZSA9PT0gbm9kZSkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgdmFyIG5ld0NvdW50ID0gdGhpcy5jb3VudDtcbiAgICAgIGlmICghbm9kZSkge1xuICAgICAgICBuZXdDb3VudCsrO1xuICAgICAgfSBlbHNlIGlmICghbmV3Tm9kZSkge1xuICAgICAgICBuZXdDb3VudC0tO1xuICAgICAgICBpZiAobmV3Q291bnQgPCBNSU5fSEFTSF9BUlJBWV9NQVBfU0laRSkge1xuICAgICAgICAgIHJldHVybiBwYWNrTm9kZXMob3duZXJJRCwgbm9kZXMsIG5ld0NvdW50LCBpZHgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBpc0VkaXRhYmxlID0gb3duZXJJRCAmJiBvd25lcklEID09PSB0aGlzLm93bmVySUQ7XG4gICAgICB2YXIgbmV3Tm9kZXMgPSBzZXRJbihub2RlcywgaWR4LCBuZXdOb2RlLCBpc0VkaXRhYmxlKTtcblxuICAgICAgaWYgKGlzRWRpdGFibGUpIHtcbiAgICAgICAgdGhpcy5jb3VudCA9IG5ld0NvdW50O1xuICAgICAgICB0aGlzLm5vZGVzID0gbmV3Tm9kZXM7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IEhhc2hBcnJheU1hcE5vZGUob3duZXJJRCwgbmV3Q291bnQsIG5ld05vZGVzKTtcbiAgICB9O1xuXG5cblxuXG4gICAgZnVuY3Rpb24gSGFzaENvbGxpc2lvbk5vZGUob3duZXJJRCwga2V5SGFzaCwgZW50cmllcykge1xuICAgICAgdGhpcy5vd25lcklEID0gb3duZXJJRDtcbiAgICAgIHRoaXMua2V5SGFzaCA9IGtleUhhc2g7XG4gICAgICB0aGlzLmVudHJpZXMgPSBlbnRyaWVzO1xuICAgIH1cblxuICAgIEhhc2hDb2xsaXNpb25Ob2RlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihzaGlmdCwga2V5SGFzaCwga2V5LCBub3RTZXRWYWx1ZSkge1xuICAgICAgdmFyIGVudHJpZXMgPSB0aGlzLmVudHJpZXM7XG4gICAgICBmb3IgKHZhciBpaSA9IDAsIGxlbiA9IGVudHJpZXMubGVuZ3RoOyBpaSA8IGxlbjsgaWkrKykge1xuICAgICAgICBpZiAoaXMoa2V5LCBlbnRyaWVzW2lpXVswXSkpIHtcbiAgICAgICAgICByZXR1cm4gZW50cmllc1tpaV1bMV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgSGFzaENvbGxpc2lvbk5vZGUucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKG93bmVySUQsIHNoaWZ0LCBrZXlIYXNoLCBrZXksIHZhbHVlLCBkaWRDaGFuZ2VTaXplLCBkaWRBbHRlcikge1xuICAgICAgaWYgKGtleUhhc2ggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBrZXlIYXNoID0gaGFzaChrZXkpO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVtb3ZlZCA9IHZhbHVlID09PSBOT1RfU0VUO1xuXG4gICAgICBpZiAoa2V5SGFzaCAhPT0gdGhpcy5rZXlIYXNoKSB7XG4gICAgICAgIGlmIChyZW1vdmVkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgU2V0UmVmKGRpZEFsdGVyKTtcbiAgICAgICAgU2V0UmVmKGRpZENoYW5nZVNpemUpO1xuICAgICAgICByZXR1cm4gbWVyZ2VJbnRvTm9kZSh0aGlzLCBvd25lcklELCBzaGlmdCwga2V5SGFzaCwgW2tleSwgdmFsdWVdKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGVudHJpZXMgPSB0aGlzLmVudHJpZXM7XG4gICAgICB2YXIgaWR4ID0gMDtcbiAgICAgIGZvciAodmFyIGxlbiA9IGVudHJpZXMubGVuZ3RoOyBpZHggPCBsZW47IGlkeCsrKSB7XG4gICAgICAgIGlmIChpcyhrZXksIGVudHJpZXNbaWR4XVswXSkpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdmFyIGV4aXN0cyA9IGlkeCA8IGxlbjtcblxuICAgICAgaWYgKGV4aXN0cyA/IGVudHJpZXNbaWR4XVsxXSA9PT0gdmFsdWUgOiByZW1vdmVkKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICBTZXRSZWYoZGlkQWx0ZXIpO1xuICAgICAgKHJlbW92ZWQgfHwgIWV4aXN0cykgJiYgU2V0UmVmKGRpZENoYW5nZVNpemUpO1xuXG4gICAgICBpZiAocmVtb3ZlZCAmJiBsZW4gPT09IDIpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBWYWx1ZU5vZGUob3duZXJJRCwgdGhpcy5rZXlIYXNoLCBlbnRyaWVzW2lkeCBeIDFdKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGlzRWRpdGFibGUgPSBvd25lcklEICYmIG93bmVySUQgPT09IHRoaXMub3duZXJJRDtcbiAgICAgIHZhciBuZXdFbnRyaWVzID0gaXNFZGl0YWJsZSA/IGVudHJpZXMgOiBhcnJDb3B5KGVudHJpZXMpO1xuXG4gICAgICBpZiAoZXhpc3RzKSB7XG4gICAgICAgIGlmIChyZW1vdmVkKSB7XG4gICAgICAgICAgaWR4ID09PSBsZW4gLSAxID8gbmV3RW50cmllcy5wb3AoKSA6IChuZXdFbnRyaWVzW2lkeF0gPSBuZXdFbnRyaWVzLnBvcCgpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdFbnRyaWVzW2lkeF0gPSBba2V5LCB2YWx1ZV07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld0VudHJpZXMucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNFZGl0YWJsZSkge1xuICAgICAgICB0aGlzLmVudHJpZXMgPSBuZXdFbnRyaWVzO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ldyBIYXNoQ29sbGlzaW9uTm9kZShvd25lcklELCB0aGlzLmtleUhhc2gsIG5ld0VudHJpZXMpO1xuICAgIH07XG5cblxuXG5cbiAgICBmdW5jdGlvbiBWYWx1ZU5vZGUob3duZXJJRCwga2V5SGFzaCwgZW50cnkpIHtcbiAgICAgIHRoaXMub3duZXJJRCA9IG93bmVySUQ7XG4gICAgICB0aGlzLmtleUhhc2ggPSBrZXlIYXNoO1xuICAgICAgdGhpcy5lbnRyeSA9IGVudHJ5O1xuICAgIH1cblxuICAgIFZhbHVlTm9kZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oc2hpZnQsIGtleUhhc2gsIGtleSwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHJldHVybiBpcyhrZXksIHRoaXMuZW50cnlbMF0pID8gdGhpcy5lbnRyeVsxXSA6IG5vdFNldFZhbHVlO1xuICAgIH07XG5cbiAgICBWYWx1ZU5vZGUucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKG93bmVySUQsIHNoaWZ0LCBrZXlIYXNoLCBrZXksIHZhbHVlLCBkaWRDaGFuZ2VTaXplLCBkaWRBbHRlcikge1xuICAgICAgdmFyIHJlbW92ZWQgPSB2YWx1ZSA9PT0gTk9UX1NFVDtcbiAgICAgIHZhciBrZXlNYXRjaCA9IGlzKGtleSwgdGhpcy5lbnRyeVswXSk7XG4gICAgICBpZiAoa2V5TWF0Y2ggPyB2YWx1ZSA9PT0gdGhpcy5lbnRyeVsxXSA6IHJlbW92ZWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIFNldFJlZihkaWRBbHRlcik7XG5cbiAgICAgIGlmIChyZW1vdmVkKSB7XG4gICAgICAgIFNldFJlZihkaWRDaGFuZ2VTaXplKTtcbiAgICAgICAgcmV0dXJuOyAvLyB1bmRlZmluZWRcbiAgICAgIH1cblxuICAgICAgaWYgKGtleU1hdGNoKSB7XG4gICAgICAgIGlmIChvd25lcklEICYmIG93bmVySUQgPT09IHRoaXMub3duZXJJRCkge1xuICAgICAgICAgIHRoaXMuZW50cnlbMV0gPSB2YWx1ZTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFZhbHVlTm9kZShvd25lcklELCB0aGlzLmtleUhhc2gsIFtrZXksIHZhbHVlXSk7XG4gICAgICB9XG5cbiAgICAgIFNldFJlZihkaWRDaGFuZ2VTaXplKTtcbiAgICAgIHJldHVybiBtZXJnZUludG9Ob2RlKHRoaXMsIG93bmVySUQsIHNoaWZ0LCBoYXNoKGtleSksIFtrZXksIHZhbHVlXSk7XG4gICAgfTtcblxuXG5cbiAgLy8gI3ByYWdtYSBJdGVyYXRvcnNcblxuICBBcnJheU1hcE5vZGUucHJvdG90eXBlLml0ZXJhdGUgPVxuICBIYXNoQ29sbGlzaW9uTm9kZS5wcm90b3R5cGUuaXRlcmF0ZSA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge1xuICAgIHZhciBlbnRyaWVzID0gdGhpcy5lbnRyaWVzO1xuICAgIGZvciAodmFyIGlpID0gMCwgbWF4SW5kZXggPSBlbnRyaWVzLmxlbmd0aCAtIDE7IGlpIDw9IG1heEluZGV4OyBpaSsrKSB7XG4gICAgICBpZiAoZm4oZW50cmllc1tyZXZlcnNlID8gbWF4SW5kZXggLSBpaSA6IGlpXSkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBCaXRtYXBJbmRleGVkTm9kZS5wcm90b3R5cGUuaXRlcmF0ZSA9XG4gIEhhc2hBcnJheU1hcE5vZGUucHJvdG90eXBlLml0ZXJhdGUgPSBmdW5jdGlvbiAoZm4sIHJldmVyc2UpIHtcbiAgICB2YXIgbm9kZXMgPSB0aGlzLm5vZGVzO1xuICAgIGZvciAodmFyIGlpID0gMCwgbWF4SW5kZXggPSBub2Rlcy5sZW5ndGggLSAxOyBpaSA8PSBtYXhJbmRleDsgaWkrKykge1xuICAgICAgdmFyIG5vZGUgPSBub2Rlc1tyZXZlcnNlID8gbWF4SW5kZXggLSBpaSA6IGlpXTtcbiAgICAgIGlmIChub2RlICYmIG5vZGUuaXRlcmF0ZShmbiwgcmV2ZXJzZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBWYWx1ZU5vZGUucHJvdG90eXBlLml0ZXJhdGUgPSBmdW5jdGlvbiAoZm4sIHJldmVyc2UpIHtcbiAgICByZXR1cm4gZm4odGhpcy5lbnRyeSk7XG4gIH1cblxuICBjcmVhdGVDbGFzcyhNYXBJdGVyYXRvciwgSXRlcmF0b3IpO1xuXG4gICAgZnVuY3Rpb24gTWFwSXRlcmF0b3IobWFwLCB0eXBlLCByZXZlcnNlKSB7XG4gICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgIHRoaXMuX3JldmVyc2UgPSByZXZlcnNlO1xuICAgICAgdGhpcy5fc3RhY2sgPSBtYXAuX3Jvb3QgJiYgbWFwSXRlcmF0b3JGcmFtZShtYXAuX3Jvb3QpO1xuICAgIH1cblxuICAgIE1hcEl0ZXJhdG9yLnByb3RvdHlwZS5uZXh0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgdHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgICB2YXIgc3RhY2sgPSB0aGlzLl9zdGFjaztcbiAgICAgIHdoaWxlIChzdGFjaykge1xuICAgICAgICB2YXIgbm9kZSA9IHN0YWNrLm5vZGU7XG4gICAgICAgIHZhciBpbmRleCA9IHN0YWNrLmluZGV4Kys7XG4gICAgICAgIHZhciBtYXhJbmRleDtcbiAgICAgICAgaWYgKG5vZGUuZW50cnkpIHtcbiAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBtYXBJdGVyYXRvclZhbHVlKHR5cGUsIG5vZGUuZW50cnkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChub2RlLmVudHJpZXMpIHtcbiAgICAgICAgICBtYXhJbmRleCA9IG5vZGUuZW50cmllcy5sZW5ndGggLSAxO1xuICAgICAgICAgIGlmIChpbmRleCA8PSBtYXhJbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuIG1hcEl0ZXJhdG9yVmFsdWUodHlwZSwgbm9kZS5lbnRyaWVzW3RoaXMuX3JldmVyc2UgPyBtYXhJbmRleCAtIGluZGV4IDogaW5kZXhdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWF4SW5kZXggPSBub2RlLm5vZGVzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgaWYgKGluZGV4IDw9IG1heEluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc3ViTm9kZSA9IG5vZGUubm9kZXNbdGhpcy5fcmV2ZXJzZSA/IG1heEluZGV4IC0gaW5kZXggOiBpbmRleF07XG4gICAgICAgICAgICBpZiAoc3ViTm9kZSkge1xuICAgICAgICAgICAgICBpZiAoc3ViTm9kZS5lbnRyeSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXBJdGVyYXRvclZhbHVlKHR5cGUsIHN1Yk5vZGUuZW50cnkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHN0YWNrID0gdGhpcy5fc3RhY2sgPSBtYXBJdGVyYXRvckZyYW1lKHN1Yk5vZGUsIHN0YWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFjayA9IHRoaXMuX3N0YWNrID0gdGhpcy5fc3RhY2suX19wcmV2O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGl0ZXJhdG9yRG9uZSgpO1xuICAgIH07XG5cblxuICBmdW5jdGlvbiBtYXBJdGVyYXRvclZhbHVlKHR5cGUsIGVudHJ5KSB7XG4gICAgcmV0dXJuIGl0ZXJhdG9yVmFsdWUodHlwZSwgZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1hcEl0ZXJhdG9yRnJhbWUobm9kZSwgcHJldikge1xuICAgIHJldHVybiB7XG4gICAgICBub2RlOiBub2RlLFxuICAgICAgaW5kZXg6IDAsXG4gICAgICBfX3ByZXY6IHByZXZcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gbWFrZU1hcChzaXplLCByb290LCBvd25lcklELCBoYXNoKSB7XG4gICAgdmFyIG1hcCA9IE9iamVjdC5jcmVhdGUoTWFwUHJvdG90eXBlKTtcbiAgICBtYXAuc2l6ZSA9IHNpemU7XG4gICAgbWFwLl9yb290ID0gcm9vdDtcbiAgICBtYXAuX19vd25lcklEID0gb3duZXJJRDtcbiAgICBtYXAuX19oYXNoID0gaGFzaDtcbiAgICBtYXAuX19hbHRlcmVkID0gZmFsc2U7XG4gICAgcmV0dXJuIG1hcDtcbiAgfVxuXG4gIHZhciBFTVBUWV9NQVA7XG4gIGZ1bmN0aW9uIGVtcHR5TWFwKCkge1xuICAgIHJldHVybiBFTVBUWV9NQVAgfHwgKEVNUFRZX01BUCA9IG1ha2VNYXAoMCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTWFwKG1hcCwgaywgdikge1xuICAgIHZhciBuZXdSb290O1xuICAgIHZhciBuZXdTaXplO1xuICAgIGlmICghbWFwLl9yb290KSB7XG4gICAgICBpZiAodiA9PT0gTk9UX1NFVCkge1xuICAgICAgICByZXR1cm4gbWFwO1xuICAgICAgfVxuICAgICAgbmV3U2l6ZSA9IDE7XG4gICAgICBuZXdSb290ID0gbmV3IEFycmF5TWFwTm9kZShtYXAuX19vd25lcklELCBbW2ssIHZdXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBkaWRDaGFuZ2VTaXplID0gTWFrZVJlZihDSEFOR0VfTEVOR1RIKTtcbiAgICAgIHZhciBkaWRBbHRlciA9IE1ha2VSZWYoRElEX0FMVEVSKTtcbiAgICAgIG5ld1Jvb3QgPSB1cGRhdGVOb2RlKG1hcC5fcm9vdCwgbWFwLl9fb3duZXJJRCwgMCwgdW5kZWZpbmVkLCBrLCB2LCBkaWRDaGFuZ2VTaXplLCBkaWRBbHRlcik7XG4gICAgICBpZiAoIWRpZEFsdGVyLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiBtYXA7XG4gICAgICB9XG4gICAgICBuZXdTaXplID0gbWFwLnNpemUgKyAoZGlkQ2hhbmdlU2l6ZS52YWx1ZSA/IHYgPT09IE5PVF9TRVQgPyAtMSA6IDEgOiAwKTtcbiAgICB9XG4gICAgaWYgKG1hcC5fX293bmVySUQpIHtcbiAgICAgIG1hcC5zaXplID0gbmV3U2l6ZTtcbiAgICAgIG1hcC5fcm9vdCA9IG5ld1Jvb3Q7XG4gICAgICBtYXAuX19oYXNoID0gdW5kZWZpbmVkO1xuICAgICAgbWFwLl9fYWx0ZXJlZCA9IHRydWU7XG4gICAgICByZXR1cm4gbWFwO1xuICAgIH1cbiAgICByZXR1cm4gbmV3Um9vdCA/IG1ha2VNYXAobmV3U2l6ZSwgbmV3Um9vdCkgOiBlbXB0eU1hcCgpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTm9kZShub2RlLCBvd25lcklELCBzaGlmdCwga2V5SGFzaCwga2V5LCB2YWx1ZSwgZGlkQ2hhbmdlU2l6ZSwgZGlkQWx0ZXIpIHtcbiAgICBpZiAoIW5vZGUpIHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gTk9UX1NFVCkge1xuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgIH1cbiAgICAgIFNldFJlZihkaWRBbHRlcik7XG4gICAgICBTZXRSZWYoZGlkQ2hhbmdlU2l6ZSk7XG4gICAgICByZXR1cm4gbmV3IFZhbHVlTm9kZShvd25lcklELCBrZXlIYXNoLCBba2V5LCB2YWx1ZV0pO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZS51cGRhdGUob3duZXJJRCwgc2hpZnQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzTGVhZk5vZGUobm9kZSkge1xuICAgIHJldHVybiBub2RlLmNvbnN0cnVjdG9yID09PSBWYWx1ZU5vZGUgfHwgbm9kZS5jb25zdHJ1Y3RvciA9PT0gSGFzaENvbGxpc2lvbk5vZGU7XG4gIH1cblxuICBmdW5jdGlvbiBtZXJnZUludG9Ob2RlKG5vZGUsIG93bmVySUQsIHNoaWZ0LCBrZXlIYXNoLCBlbnRyeSkge1xuICAgIGlmIChub2RlLmtleUhhc2ggPT09IGtleUhhc2gpIHtcbiAgICAgIHJldHVybiBuZXcgSGFzaENvbGxpc2lvbk5vZGUob3duZXJJRCwga2V5SGFzaCwgW25vZGUuZW50cnksIGVudHJ5XSk7XG4gICAgfVxuXG4gICAgdmFyIGlkeDEgPSAoc2hpZnQgPT09IDAgPyBub2RlLmtleUhhc2ggOiBub2RlLmtleUhhc2ggPj4+IHNoaWZ0KSAmIE1BU0s7XG4gICAgdmFyIGlkeDIgPSAoc2hpZnQgPT09IDAgPyBrZXlIYXNoIDoga2V5SGFzaCA+Pj4gc2hpZnQpICYgTUFTSztcblxuICAgIHZhciBuZXdOb2RlO1xuICAgIHZhciBub2RlcyA9IGlkeDEgPT09IGlkeDIgP1xuICAgICAgW21lcmdlSW50b05vZGUobm9kZSwgb3duZXJJRCwgc2hpZnQgKyBTSElGVCwga2V5SGFzaCwgZW50cnkpXSA6XG4gICAgICAoKG5ld05vZGUgPSBuZXcgVmFsdWVOb2RlKG93bmVySUQsIGtleUhhc2gsIGVudHJ5KSksIGlkeDEgPCBpZHgyID8gW25vZGUsIG5ld05vZGVdIDogW25ld05vZGUsIG5vZGVdKTtcblxuICAgIHJldHVybiBuZXcgQml0bWFwSW5kZXhlZE5vZGUob3duZXJJRCwgKDEgPDwgaWR4MSkgfCAoMSA8PCBpZHgyKSwgbm9kZXMpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlTm9kZXMob3duZXJJRCwgZW50cmllcywga2V5LCB2YWx1ZSkge1xuICAgIGlmICghb3duZXJJRCkge1xuICAgICAgb3duZXJJRCA9IG5ldyBPd25lcklEKCk7XG4gICAgfVxuICAgIHZhciBub2RlID0gbmV3IFZhbHVlTm9kZShvd25lcklELCBoYXNoKGtleSksIFtrZXksIHZhbHVlXSk7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IGVudHJpZXMubGVuZ3RoOyBpaSsrKSB7XG4gICAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2lpXTtcbiAgICAgIG5vZGUgPSBub2RlLnVwZGF0ZShvd25lcklELCAwLCB1bmRlZmluZWQsIGVudHJ5WzBdLCBlbnRyeVsxXSk7XG4gICAgfVxuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFja05vZGVzKG93bmVySUQsIG5vZGVzLCBjb3VudCwgZXhjbHVkaW5nKSB7XG4gICAgdmFyIGJpdG1hcCA9IDA7XG4gICAgdmFyIHBhY2tlZElJID0gMDtcbiAgICB2YXIgcGFja2VkTm9kZXMgPSBuZXcgQXJyYXkoY291bnQpO1xuICAgIGZvciAodmFyIGlpID0gMCwgYml0ID0gMSwgbGVuID0gbm9kZXMubGVuZ3RoOyBpaSA8IGxlbjsgaWkrKywgYml0IDw8PSAxKSB7XG4gICAgICB2YXIgbm9kZSA9IG5vZGVzW2lpXTtcbiAgICAgIGlmIChub2RlICE9PSB1bmRlZmluZWQgJiYgaWkgIT09IGV4Y2x1ZGluZykge1xuICAgICAgICBiaXRtYXAgfD0gYml0O1xuICAgICAgICBwYWNrZWROb2Rlc1twYWNrZWRJSSsrXSA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgQml0bWFwSW5kZXhlZE5vZGUob3duZXJJRCwgYml0bWFwLCBwYWNrZWROb2Rlcyk7XG4gIH1cblxuICBmdW5jdGlvbiBleHBhbmROb2Rlcyhvd25lcklELCBub2RlcywgYml0bWFwLCBpbmNsdWRpbmcsIG5vZGUpIHtcbiAgICB2YXIgY291bnQgPSAwO1xuICAgIHZhciBleHBhbmRlZE5vZGVzID0gbmV3IEFycmF5KFNJWkUpO1xuICAgIGZvciAodmFyIGlpID0gMDsgYml0bWFwICE9PSAwOyBpaSsrLCBiaXRtYXAgPj4+PSAxKSB7XG4gICAgICBleHBhbmRlZE5vZGVzW2lpXSA9IGJpdG1hcCAmIDEgPyBub2Rlc1tjb3VudCsrXSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZXhwYW5kZWROb2Rlc1tpbmNsdWRpbmddID0gbm9kZTtcbiAgICByZXR1cm4gbmV3IEhhc2hBcnJheU1hcE5vZGUob3duZXJJRCwgY291bnQgKyAxLCBleHBhbmRlZE5vZGVzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1lcmdlSW50b01hcFdpdGgobWFwLCBtZXJnZXIsIGl0ZXJhYmxlcykge1xuICAgIHZhciBpdGVycyA9IFtdO1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCBpdGVyYWJsZXMubGVuZ3RoOyBpaSsrKSB7XG4gICAgICB2YXIgdmFsdWUgPSBpdGVyYWJsZXNbaWldO1xuICAgICAgdmFyIGl0ZXIgPSBLZXllZEl0ZXJhYmxlKHZhbHVlKTtcbiAgICAgIGlmICghaXNJdGVyYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgaXRlciA9IGl0ZXIubWFwKGZ1bmN0aW9uKHYgKSB7cmV0dXJuIGZyb21KUyh2KX0pO1xuICAgICAgfVxuICAgICAgaXRlcnMucHVzaChpdGVyKTtcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlSW50b0NvbGxlY3Rpb25XaXRoKG1hcCwgbWVyZ2VyLCBpdGVycyk7XG4gIH1cblxuICBmdW5jdGlvbiBkZWVwTWVyZ2VyKGV4aXN0aW5nLCB2YWx1ZSwga2V5KSB7XG4gICAgcmV0dXJuIGV4aXN0aW5nICYmIGV4aXN0aW5nLm1lcmdlRGVlcCAmJiBpc0l0ZXJhYmxlKHZhbHVlKSA/XG4gICAgICBleGlzdGluZy5tZXJnZURlZXAodmFsdWUpIDpcbiAgICAgIGlzKGV4aXN0aW5nLCB2YWx1ZSkgPyBleGlzdGluZyA6IHZhbHVlO1xuICB9XG5cbiAgZnVuY3Rpb24gZGVlcE1lcmdlcldpdGgobWVyZ2VyKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV4aXN0aW5nLCB2YWx1ZSwga2V5KSAge1xuICAgICAgaWYgKGV4aXN0aW5nICYmIGV4aXN0aW5nLm1lcmdlRGVlcFdpdGggJiYgaXNJdGVyYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGV4aXN0aW5nLm1lcmdlRGVlcFdpdGgobWVyZ2VyLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgICB2YXIgbmV4dFZhbHVlID0gbWVyZ2VyKGV4aXN0aW5nLCB2YWx1ZSwga2V5KTtcbiAgICAgIHJldHVybiBpcyhleGlzdGluZywgbmV4dFZhbHVlKSA/IGV4aXN0aW5nIDogbmV4dFZhbHVlO1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBtZXJnZUludG9Db2xsZWN0aW9uV2l0aChjb2xsZWN0aW9uLCBtZXJnZXIsIGl0ZXJzKSB7XG4gICAgaXRlcnMgPSBpdGVycy5maWx0ZXIoZnVuY3Rpb24oeCApIHtyZXR1cm4geC5zaXplICE9PSAwfSk7XG4gICAgaWYgKGl0ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb247XG4gICAgfVxuICAgIGlmIChjb2xsZWN0aW9uLnNpemUgPT09IDAgJiYgIWNvbGxlY3Rpb24uX19vd25lcklEICYmIGl0ZXJzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb24uY29uc3RydWN0b3IoaXRlcnNbMF0pO1xuICAgIH1cbiAgICByZXR1cm4gY29sbGVjdGlvbi53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKGNvbGxlY3Rpb24gKSB7XG4gICAgICB2YXIgbWVyZ2VJbnRvTWFwID0gbWVyZ2VyID9cbiAgICAgICAgZnVuY3Rpb24odmFsdWUsIGtleSkgIHtcbiAgICAgICAgICBjb2xsZWN0aW9uLnVwZGF0ZShrZXksIE5PVF9TRVQsIGZ1bmN0aW9uKGV4aXN0aW5nIClcbiAgICAgICAgICAgIHtyZXR1cm4gZXhpc3RpbmcgPT09IE5PVF9TRVQgPyB2YWx1ZSA6IG1lcmdlcihleGlzdGluZywgdmFsdWUsIGtleSl9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSA6XG4gICAgICAgIGZ1bmN0aW9uKHZhbHVlLCBrZXkpICB7XG4gICAgICAgICAgY29sbGVjdGlvbi5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCBpdGVycy5sZW5ndGg7IGlpKyspIHtcbiAgICAgICAgaXRlcnNbaWldLmZvckVhY2gobWVyZ2VJbnRvTWFwKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUluRGVlcE1hcChleGlzdGluZywga2V5UGF0aEl0ZXIsIG5vdFNldFZhbHVlLCB1cGRhdGVyKSB7XG4gICAgdmFyIGlzTm90U2V0ID0gZXhpc3RpbmcgPT09IE5PVF9TRVQ7XG4gICAgdmFyIHN0ZXAgPSBrZXlQYXRoSXRlci5uZXh0KCk7XG4gICAgaWYgKHN0ZXAuZG9uZSkge1xuICAgICAgdmFyIGV4aXN0aW5nVmFsdWUgPSBpc05vdFNldCA/IG5vdFNldFZhbHVlIDogZXhpc3Rpbmc7XG4gICAgICB2YXIgbmV3VmFsdWUgPSB1cGRhdGVyKGV4aXN0aW5nVmFsdWUpO1xuICAgICAgcmV0dXJuIG5ld1ZhbHVlID09PSBleGlzdGluZ1ZhbHVlID8gZXhpc3RpbmcgOiBuZXdWYWx1ZTtcbiAgICB9XG4gICAgaW52YXJpYW50KFxuICAgICAgaXNOb3RTZXQgfHwgKGV4aXN0aW5nICYmIGV4aXN0aW5nLnNldCksXG4gICAgICAnaW52YWxpZCBrZXlQYXRoJ1xuICAgICk7XG4gICAgdmFyIGtleSA9IHN0ZXAudmFsdWU7XG4gICAgdmFyIG5leHRFeGlzdGluZyA9IGlzTm90U2V0ID8gTk9UX1NFVCA6IGV4aXN0aW5nLmdldChrZXksIE5PVF9TRVQpO1xuICAgIHZhciBuZXh0VXBkYXRlZCA9IHVwZGF0ZUluRGVlcE1hcChcbiAgICAgIG5leHRFeGlzdGluZyxcbiAgICAgIGtleVBhdGhJdGVyLFxuICAgICAgbm90U2V0VmFsdWUsXG4gICAgICB1cGRhdGVyXG4gICAgKTtcbiAgICByZXR1cm4gbmV4dFVwZGF0ZWQgPT09IG5leHRFeGlzdGluZyA/IGV4aXN0aW5nIDpcbiAgICAgIG5leHRVcGRhdGVkID09PSBOT1RfU0VUID8gZXhpc3RpbmcucmVtb3ZlKGtleSkgOlxuICAgICAgKGlzTm90U2V0ID8gZW1wdHlNYXAoKSA6IGV4aXN0aW5nKS5zZXQoa2V5LCBuZXh0VXBkYXRlZCk7XG4gIH1cblxuICBmdW5jdGlvbiBwb3BDb3VudCh4KSB7XG4gICAgeCA9IHggLSAoKHggPj4gMSkgJiAweDU1NTU1NTU1KTtcbiAgICB4ID0gKHggJiAweDMzMzMzMzMzKSArICgoeCA+PiAyKSAmIDB4MzMzMzMzMzMpO1xuICAgIHggPSAoeCArICh4ID4+IDQpKSAmIDB4MGYwZjBmMGY7XG4gICAgeCA9IHggKyAoeCA+PiA4KTtcbiAgICB4ID0geCArICh4ID4+IDE2KTtcbiAgICByZXR1cm4geCAmIDB4N2Y7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRJbihhcnJheSwgaWR4LCB2YWwsIGNhbkVkaXQpIHtcbiAgICB2YXIgbmV3QXJyYXkgPSBjYW5FZGl0ID8gYXJyYXkgOiBhcnJDb3B5KGFycmF5KTtcbiAgICBuZXdBcnJheVtpZHhdID0gdmFsO1xuICAgIHJldHVybiBuZXdBcnJheTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNwbGljZUluKGFycmF5LCBpZHgsIHZhbCwgY2FuRWRpdCkge1xuICAgIHZhciBuZXdMZW4gPSBhcnJheS5sZW5ndGggKyAxO1xuICAgIGlmIChjYW5FZGl0ICYmIGlkeCArIDEgPT09IG5ld0xlbikge1xuICAgICAgYXJyYXlbaWR4XSA9IHZhbDtcbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG4gICAgdmFyIG5ld0FycmF5ID0gbmV3IEFycmF5KG5ld0xlbik7XG4gICAgdmFyIGFmdGVyID0gMDtcbiAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgbmV3TGVuOyBpaSsrKSB7XG4gICAgICBpZiAoaWkgPT09IGlkeCkge1xuICAgICAgICBuZXdBcnJheVtpaV0gPSB2YWw7XG4gICAgICAgIGFmdGVyID0gLTE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdBcnJheVtpaV0gPSBhcnJheVtpaSArIGFmdGVyXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ld0FycmF5O1xuICB9XG5cbiAgZnVuY3Rpb24gc3BsaWNlT3V0KGFycmF5LCBpZHgsIGNhbkVkaXQpIHtcbiAgICB2YXIgbmV3TGVuID0gYXJyYXkubGVuZ3RoIC0gMTtcbiAgICBpZiAoY2FuRWRpdCAmJiBpZHggPT09IG5ld0xlbikge1xuICAgICAgYXJyYXkucG9wKCk7XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuICAgIHZhciBuZXdBcnJheSA9IG5ldyBBcnJheShuZXdMZW4pO1xuICAgIHZhciBhZnRlciA9IDA7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IG5ld0xlbjsgaWkrKykge1xuICAgICAgaWYgKGlpID09PSBpZHgpIHtcbiAgICAgICAgYWZ0ZXIgPSAxO1xuICAgICAgfVxuICAgICAgbmV3QXJyYXlbaWldID0gYXJyYXlbaWkgKyBhZnRlcl07XG4gICAgfVxuICAgIHJldHVybiBuZXdBcnJheTtcbiAgfVxuXG4gIHZhciBNQVhfQVJSQVlfTUFQX1NJWkUgPSBTSVpFIC8gNDtcbiAgdmFyIE1BWF9CSVRNQVBfSU5ERVhFRF9TSVpFID0gU0laRSAvIDI7XG4gIHZhciBNSU5fSEFTSF9BUlJBWV9NQVBfU0laRSA9IFNJWkUgLyA0O1xuXG4gIGNyZWF0ZUNsYXNzKExpc3QsIEluZGV4ZWRDb2xsZWN0aW9uKTtcblxuICAgIC8vIEBwcmFnbWEgQ29uc3RydWN0aW9uXG5cbiAgICBmdW5jdGlvbiBMaXN0KHZhbHVlKSB7XG4gICAgICB2YXIgZW1wdHkgPSBlbXB0eUxpc3QoKTtcbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBlbXB0eTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0xpc3QodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyID0gSW5kZXhlZEl0ZXJhYmxlKHZhbHVlKTtcbiAgICAgIHZhciBzaXplID0gaXRlci5zaXplO1xuICAgICAgaWYgKHNpemUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGVtcHR5O1xuICAgICAgfVxuICAgICAgYXNzZXJ0Tm90SW5maW5pdGUoc2l6ZSk7XG4gICAgICBpZiAoc2l6ZSA+IDAgJiYgc2l6ZSA8IFNJWkUpIHtcbiAgICAgICAgcmV0dXJuIG1ha2VMaXN0KDAsIHNpemUsIFNISUZULCBudWxsLCBuZXcgVk5vZGUoaXRlci50b0FycmF5KCkpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbXB0eS53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKGxpc3QgKSB7XG4gICAgICAgIGxpc3Quc2V0U2l6ZShzaXplKTtcbiAgICAgICAgaXRlci5mb3JFYWNoKGZ1bmN0aW9uKHYsIGkpICB7cmV0dXJuIGxpc3Quc2V0KGksIHYpfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBMaXN0Lm9mID0gZnVuY3Rpb24oLyouLi52YWx1ZXMqLykge1xuICAgICAgcmV0dXJuIHRoaXMoYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fdG9TdHJpbmcoJ0xpc3QgWycsICddJyk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgQWNjZXNzXG5cbiAgICBMaXN0LnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihpbmRleCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIGluZGV4ID0gd3JhcEluZGV4KHRoaXMsIGluZGV4KTtcbiAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgdGhpcy5zaXplKSB7XG4gICAgICAgIGluZGV4ICs9IHRoaXMuX29yaWdpbjtcbiAgICAgICAgdmFyIG5vZGUgPSBsaXN0Tm9kZUZvcih0aGlzLCBpbmRleCk7XG4gICAgICAgIHJldHVybiBub2RlICYmIG5vZGUuYXJyYXlbaW5kZXggJiBNQVNLXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBNb2RpZmljYXRpb25cblxuICAgIExpc3QucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKGluZGV4LCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIHVwZGF0ZUxpc3QodGhpcywgaW5kZXgsIHZhbHVlKTtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgIHJldHVybiAhdGhpcy5oYXMoaW5kZXgpID8gdGhpcyA6XG4gICAgICAgIGluZGV4ID09PSAwID8gdGhpcy5zaGlmdCgpIDpcbiAgICAgICAgaW5kZXggPT09IHRoaXMuc2l6ZSAtIDEgPyB0aGlzLnBvcCgpIDpcbiAgICAgICAgdGhpcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5pbnNlcnQgPSBmdW5jdGlvbihpbmRleCwgdmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnNwbGljZShpbmRleCwgMCwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuc2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICB0aGlzLnNpemUgPSB0aGlzLl9vcmlnaW4gPSB0aGlzLl9jYXBhY2l0eSA9IDA7XG4gICAgICAgIHRoaXMuX2xldmVsID0gU0hJRlQ7XG4gICAgICAgIHRoaXMuX3Jvb3QgPSB0aGlzLl90YWlsID0gbnVsbDtcbiAgICAgICAgdGhpcy5fX2hhc2ggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX19hbHRlcmVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gZW1wdHlMaXN0KCk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICB2YXIgdmFsdWVzID0gYXJndW1lbnRzO1xuICAgICAgdmFyIG9sZFNpemUgPSB0aGlzLnNpemU7XG4gICAgICByZXR1cm4gdGhpcy53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKGxpc3QgKSB7XG4gICAgICAgIHNldExpc3RCb3VuZHMobGlzdCwgMCwgb2xkU2l6ZSArIHZhbHVlcy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgdmFsdWVzLmxlbmd0aDsgaWkrKykge1xuICAgICAgICAgIGxpc3Quc2V0KG9sZFNpemUgKyBpaSwgdmFsdWVzW2lpXSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBzZXRMaXN0Qm91bmRzKHRoaXMsIDAsIC0xKTtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHZhciB2YWx1ZXMgPSBhcmd1bWVudHM7XG4gICAgICByZXR1cm4gdGhpcy53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKGxpc3QgKSB7XG4gICAgICAgIHNldExpc3RCb3VuZHMobGlzdCwgLXZhbHVlcy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgdmFsdWVzLmxlbmd0aDsgaWkrKykge1xuICAgICAgICAgIGxpc3Quc2V0KGlpLCB2YWx1ZXNbaWldKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLnNoaWZ0ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gc2V0TGlzdEJvdW5kcyh0aGlzLCAxKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBDb21wb3NpdGlvblxuXG4gICAgTGlzdC5wcm90b3R5cGUubWVyZ2UgPSBmdW5jdGlvbigvKi4uLml0ZXJzKi8pIHtcbiAgICAgIHJldHVybiBtZXJnZUludG9MaXN0V2l0aCh0aGlzLCB1bmRlZmluZWQsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLm1lcmdlV2l0aCA9IGZ1bmN0aW9uKG1lcmdlcikge3ZhciBpdGVycyA9IFNMSUNFJDAuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgcmV0dXJuIG1lcmdlSW50b0xpc3RXaXRoKHRoaXMsIG1lcmdlciwgaXRlcnMpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5tZXJnZURlZXAgPSBmdW5jdGlvbigvKi4uLml0ZXJzKi8pIHtcbiAgICAgIHJldHVybiBtZXJnZUludG9MaXN0V2l0aCh0aGlzLCBkZWVwTWVyZ2VyLCBhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5tZXJnZURlZXBXaXRoID0gZnVuY3Rpb24obWVyZ2VyKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICByZXR1cm4gbWVyZ2VJbnRvTGlzdFdpdGgodGhpcywgZGVlcE1lcmdlcldpdGgobWVyZ2VyKSwgaXRlcnMpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5zZXRTaXplID0gZnVuY3Rpb24oc2l6ZSkge1xuICAgICAgcmV0dXJuIHNldExpc3RCb3VuZHModGhpcywgMCwgc2l6ZSk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgSXRlcmF0aW9uXG5cbiAgICBMaXN0LnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcbiAgICAgIHZhciBzaXplID0gdGhpcy5zaXplO1xuICAgICAgaWYgKHdob2xlU2xpY2UoYmVnaW4sIGVuZCwgc2l6ZSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2V0TGlzdEJvdW5kcyhcbiAgICAgICAgdGhpcyxcbiAgICAgICAgcmVzb2x2ZUJlZ2luKGJlZ2luLCBzaXplKSxcbiAgICAgICAgcmVzb2x2ZUVuZChlbmQsIHNpemUpXG4gICAgICApO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGluZGV4ID0gMDtcbiAgICAgIHZhciB2YWx1ZXMgPSBpdGVyYXRlTGlzdCh0aGlzLCByZXZlcnNlKTtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICB2YXIgdmFsdWUgPSB2YWx1ZXMoKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSBET05FID9cbiAgICAgICAgICBpdGVyYXRvckRvbmUoKSA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCBpbmRleCsrLCB2YWx1ZSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHtcbiAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICB2YXIgdmFsdWVzID0gaXRlcmF0ZUxpc3QodGhpcywgcmV2ZXJzZSk7XG4gICAgICB2YXIgdmFsdWU7XG4gICAgICB3aGlsZSAoKHZhbHVlID0gdmFsdWVzKCkpICE9PSBET05FKSB7XG4gICAgICAgIGlmIChmbih2YWx1ZSwgaW5kZXgrKywgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUuX19lbnN1cmVPd25lciA9IGZ1bmN0aW9uKG93bmVySUQpIHtcbiAgICAgIGlmIChvd25lcklEID09PSB0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICghb3duZXJJRCkge1xuICAgICAgICB0aGlzLl9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VMaXN0KHRoaXMuX29yaWdpbiwgdGhpcy5fY2FwYWNpdHksIHRoaXMuX2xldmVsLCB0aGlzLl9yb290LCB0aGlzLl90YWlsLCBvd25lcklELCB0aGlzLl9faGFzaCk7XG4gICAgfTtcblxuXG4gIGZ1bmN0aW9uIGlzTGlzdChtYXliZUxpc3QpIHtcbiAgICByZXR1cm4gISEobWF5YmVMaXN0ICYmIG1heWJlTGlzdFtJU19MSVNUX1NFTlRJTkVMXSk7XG4gIH1cblxuICBMaXN0LmlzTGlzdCA9IGlzTGlzdDtcblxuICB2YXIgSVNfTElTVF9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX0xJU1RfX0BAJztcblxuICB2YXIgTGlzdFByb3RvdHlwZSA9IExpc3QucHJvdG90eXBlO1xuICBMaXN0UHJvdG90eXBlW0lTX0xJU1RfU0VOVElORUxdID0gdHJ1ZTtcbiAgTGlzdFByb3RvdHlwZVtERUxFVEVdID0gTGlzdFByb3RvdHlwZS5yZW1vdmU7XG4gIExpc3RQcm90b3R5cGUuc2V0SW4gPSBNYXBQcm90b3R5cGUuc2V0SW47XG4gIExpc3RQcm90b3R5cGUuZGVsZXRlSW4gPVxuICBMaXN0UHJvdG90eXBlLnJlbW92ZUluID0gTWFwUHJvdG90eXBlLnJlbW92ZUluO1xuICBMaXN0UHJvdG90eXBlLnVwZGF0ZSA9IE1hcFByb3RvdHlwZS51cGRhdGU7XG4gIExpc3RQcm90b3R5cGUudXBkYXRlSW4gPSBNYXBQcm90b3R5cGUudXBkYXRlSW47XG4gIExpc3RQcm90b3R5cGUubWVyZ2VJbiA9IE1hcFByb3RvdHlwZS5tZXJnZUluO1xuICBMaXN0UHJvdG90eXBlLm1lcmdlRGVlcEluID0gTWFwUHJvdG90eXBlLm1lcmdlRGVlcEluO1xuICBMaXN0UHJvdG90eXBlLndpdGhNdXRhdGlvbnMgPSBNYXBQcm90b3R5cGUud2l0aE11dGF0aW9ucztcbiAgTGlzdFByb3RvdHlwZS5hc011dGFibGUgPSBNYXBQcm90b3R5cGUuYXNNdXRhYmxlO1xuICBMaXN0UHJvdG90eXBlLmFzSW1tdXRhYmxlID0gTWFwUHJvdG90eXBlLmFzSW1tdXRhYmxlO1xuICBMaXN0UHJvdG90eXBlLndhc0FsdGVyZWQgPSBNYXBQcm90b3R5cGUud2FzQWx0ZXJlZDtcblxuXG5cbiAgICBmdW5jdGlvbiBWTm9kZShhcnJheSwgb3duZXJJRCkge1xuICAgICAgdGhpcy5hcnJheSA9IGFycmF5O1xuICAgICAgdGhpcy5vd25lcklEID0gb3duZXJJRDtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBzZWVtcyBsaWtlIHRoZXNlIG1ldGhvZHMgYXJlIHZlcnkgc2ltaWxhclxuXG4gICAgVk5vZGUucHJvdG90eXBlLnJlbW92ZUJlZm9yZSA9IGZ1bmN0aW9uKG93bmVySUQsIGxldmVsLCBpbmRleCkge1xuICAgICAgaWYgKGluZGV4ID09PSBsZXZlbCA/IDEgPDwgbGV2ZWwgOiAwIHx8IHRoaXMuYXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIG9yaWdpbkluZGV4ID0gKGluZGV4ID4+PiBsZXZlbCkgJiBNQVNLO1xuICAgICAgaWYgKG9yaWdpbkluZGV4ID49IHRoaXMuYXJyYXkubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVk5vZGUoW10sIG93bmVySUQpO1xuICAgICAgfVxuICAgICAgdmFyIHJlbW92aW5nRmlyc3QgPSBvcmlnaW5JbmRleCA9PT0gMDtcbiAgICAgIHZhciBuZXdDaGlsZDtcbiAgICAgIGlmIChsZXZlbCA+IDApIHtcbiAgICAgICAgdmFyIG9sZENoaWxkID0gdGhpcy5hcnJheVtvcmlnaW5JbmRleF07XG4gICAgICAgIG5ld0NoaWxkID0gb2xkQ2hpbGQgJiYgb2xkQ2hpbGQucmVtb3ZlQmVmb3JlKG93bmVySUQsIGxldmVsIC0gU0hJRlQsIGluZGV4KTtcbiAgICAgICAgaWYgKG5ld0NoaWxkID09PSBvbGRDaGlsZCAmJiByZW1vdmluZ0ZpcnN0KSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChyZW1vdmluZ0ZpcnN0ICYmICFuZXdDaGlsZCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHZhciBlZGl0YWJsZSA9IGVkaXRhYmxlVk5vZGUodGhpcywgb3duZXJJRCk7XG4gICAgICBpZiAoIXJlbW92aW5nRmlyc3QpIHtcbiAgICAgICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IG9yaWdpbkluZGV4OyBpaSsrKSB7XG4gICAgICAgICAgZWRpdGFibGUuYXJyYXlbaWldID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobmV3Q2hpbGQpIHtcbiAgICAgICAgZWRpdGFibGUuYXJyYXlbb3JpZ2luSW5kZXhdID0gbmV3Q2hpbGQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gZWRpdGFibGU7XG4gICAgfTtcblxuICAgIFZOb2RlLnByb3RvdHlwZS5yZW1vdmVBZnRlciA9IGZ1bmN0aW9uKG93bmVySUQsIGxldmVsLCBpbmRleCkge1xuICAgICAgaWYgKGluZGV4ID09PSAobGV2ZWwgPyAxIDw8IGxldmVsIDogMCkgfHwgdGhpcy5hcnJheS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICB2YXIgc2l6ZUluZGV4ID0gKChpbmRleCAtIDEpID4+PiBsZXZlbCkgJiBNQVNLO1xuICAgICAgaWYgKHNpemVJbmRleCA+PSB0aGlzLmFycmF5Lmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgdmFyIG5ld0NoaWxkO1xuICAgICAgaWYgKGxldmVsID4gMCkge1xuICAgICAgICB2YXIgb2xkQ2hpbGQgPSB0aGlzLmFycmF5W3NpemVJbmRleF07XG4gICAgICAgIG5ld0NoaWxkID0gb2xkQ2hpbGQgJiYgb2xkQ2hpbGQucmVtb3ZlQWZ0ZXIob3duZXJJRCwgbGV2ZWwgLSBTSElGVCwgaW5kZXgpO1xuICAgICAgICBpZiAobmV3Q2hpbGQgPT09IG9sZENoaWxkICYmIHNpemVJbmRleCA9PT0gdGhpcy5hcnJheS5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGVkaXRhYmxlID0gZWRpdGFibGVWTm9kZSh0aGlzLCBvd25lcklEKTtcbiAgICAgIGVkaXRhYmxlLmFycmF5LnNwbGljZShzaXplSW5kZXggKyAxKTtcbiAgICAgIGlmIChuZXdDaGlsZCkge1xuICAgICAgICBlZGl0YWJsZS5hcnJheVtzaXplSW5kZXhdID0gbmV3Q2hpbGQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gZWRpdGFibGU7XG4gICAgfTtcblxuXG5cbiAgdmFyIERPTkUgPSB7fTtcblxuICBmdW5jdGlvbiBpdGVyYXRlTGlzdChsaXN0LCByZXZlcnNlKSB7XG4gICAgdmFyIGxlZnQgPSBsaXN0Ll9vcmlnaW47XG4gICAgdmFyIHJpZ2h0ID0gbGlzdC5fY2FwYWNpdHk7XG4gICAgdmFyIHRhaWxQb3MgPSBnZXRUYWlsT2Zmc2V0KHJpZ2h0KTtcbiAgICB2YXIgdGFpbCA9IGxpc3QuX3RhaWw7XG5cbiAgICByZXR1cm4gaXRlcmF0ZU5vZGVPckxlYWYobGlzdC5fcm9vdCwgbGlzdC5fbGV2ZWwsIDApO1xuXG4gICAgZnVuY3Rpb24gaXRlcmF0ZU5vZGVPckxlYWYobm9kZSwgbGV2ZWwsIG9mZnNldCkge1xuICAgICAgcmV0dXJuIGxldmVsID09PSAwID9cbiAgICAgICAgaXRlcmF0ZUxlYWYobm9kZSwgb2Zmc2V0KSA6XG4gICAgICAgIGl0ZXJhdGVOb2RlKG5vZGUsIGxldmVsLCBvZmZzZXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGl0ZXJhdGVMZWFmKG5vZGUsIG9mZnNldCkge1xuICAgICAgdmFyIGFycmF5ID0gb2Zmc2V0ID09PSB0YWlsUG9zID8gdGFpbCAmJiB0YWlsLmFycmF5IDogbm9kZSAmJiBub2RlLmFycmF5O1xuICAgICAgdmFyIGZyb20gPSBvZmZzZXQgPiBsZWZ0ID8gMCA6IGxlZnQgLSBvZmZzZXQ7XG4gICAgICB2YXIgdG8gPSByaWdodCAtIG9mZnNldDtcbiAgICAgIGlmICh0byA+IFNJWkUpIHtcbiAgICAgICAgdG8gPSBTSVpFO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgaWYgKGZyb20gPT09IHRvKSB7XG4gICAgICAgICAgcmV0dXJuIERPTkU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGlkeCA9IHJldmVyc2UgPyAtLXRvIDogZnJvbSsrO1xuICAgICAgICByZXR1cm4gYXJyYXkgJiYgYXJyYXlbaWR4XTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXRlcmF0ZU5vZGUobm9kZSwgbGV2ZWwsIG9mZnNldCkge1xuICAgICAgdmFyIHZhbHVlcztcbiAgICAgIHZhciBhcnJheSA9IG5vZGUgJiYgbm9kZS5hcnJheTtcbiAgICAgIHZhciBmcm9tID0gb2Zmc2V0ID4gbGVmdCA/IDAgOiAobGVmdCAtIG9mZnNldCkgPj4gbGV2ZWw7XG4gICAgICB2YXIgdG8gPSAoKHJpZ2h0IC0gb2Zmc2V0KSA+PiBsZXZlbCkgKyAxO1xuICAgICAgaWYgKHRvID4gU0laRSkge1xuICAgICAgICB0byA9IFNJWkU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSAge1xuICAgICAgICBkbyB7XG4gICAgICAgICAgaWYgKHZhbHVlcykge1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gdmFsdWVzKCk7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IERPTkUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFsdWVzID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGZyb20gPT09IHRvKSB7XG4gICAgICAgICAgICByZXR1cm4gRE9ORTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGlkeCA9IHJldmVyc2UgPyAtLXRvIDogZnJvbSsrO1xuICAgICAgICAgIHZhbHVlcyA9IGl0ZXJhdGVOb2RlT3JMZWFmKFxuICAgICAgICAgICAgYXJyYXkgJiYgYXJyYXlbaWR4XSwgbGV2ZWwgLSBTSElGVCwgb2Zmc2V0ICsgKGlkeCA8PCBsZXZlbClcbiAgICAgICAgICApO1xuICAgICAgICB9IHdoaWxlICh0cnVlKTtcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbWFrZUxpc3Qob3JpZ2luLCBjYXBhY2l0eSwgbGV2ZWwsIHJvb3QsIHRhaWwsIG93bmVySUQsIGhhc2gpIHtcbiAgICB2YXIgbGlzdCA9IE9iamVjdC5jcmVhdGUoTGlzdFByb3RvdHlwZSk7XG4gICAgbGlzdC5zaXplID0gY2FwYWNpdHkgLSBvcmlnaW47XG4gICAgbGlzdC5fb3JpZ2luID0gb3JpZ2luO1xuICAgIGxpc3QuX2NhcGFjaXR5ID0gY2FwYWNpdHk7XG4gICAgbGlzdC5fbGV2ZWwgPSBsZXZlbDtcbiAgICBsaXN0Ll9yb290ID0gcm9vdDtcbiAgICBsaXN0Ll90YWlsID0gdGFpbDtcbiAgICBsaXN0Ll9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgbGlzdC5fX2hhc2ggPSBoYXNoO1xuICAgIGxpc3QuX19hbHRlcmVkID0gZmFsc2U7XG4gICAgcmV0dXJuIGxpc3Q7XG4gIH1cblxuICB2YXIgRU1QVFlfTElTVDtcbiAgZnVuY3Rpb24gZW1wdHlMaXN0KCkge1xuICAgIHJldHVybiBFTVBUWV9MSVNUIHx8IChFTVBUWV9MSVNUID0gbWFrZUxpc3QoMCwgMCwgU0hJRlQpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUxpc3QobGlzdCwgaW5kZXgsIHZhbHVlKSB7XG4gICAgaW5kZXggPSB3cmFwSW5kZXgobGlzdCwgaW5kZXgpO1xuXG4gICAgaWYgKGluZGV4ICE9PSBpbmRleCkge1xuICAgICAgcmV0dXJuIGxpc3Q7XG4gICAgfVxuXG4gICAgaWYgKGluZGV4ID49IGxpc3Quc2l6ZSB8fCBpbmRleCA8IDApIHtcbiAgICAgIHJldHVybiBsaXN0LndpdGhNdXRhdGlvbnMoZnVuY3Rpb24obGlzdCApIHtcbiAgICAgICAgaW5kZXggPCAwID9cbiAgICAgICAgICBzZXRMaXN0Qm91bmRzKGxpc3QsIGluZGV4KS5zZXQoMCwgdmFsdWUpIDpcbiAgICAgICAgICBzZXRMaXN0Qm91bmRzKGxpc3QsIDAsIGluZGV4ICsgMSkuc2V0KGluZGV4LCB2YWx1ZSlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGluZGV4ICs9IGxpc3QuX29yaWdpbjtcblxuICAgIHZhciBuZXdUYWlsID0gbGlzdC5fdGFpbDtcbiAgICB2YXIgbmV3Um9vdCA9IGxpc3QuX3Jvb3Q7XG4gICAgdmFyIGRpZEFsdGVyID0gTWFrZVJlZihESURfQUxURVIpO1xuICAgIGlmIChpbmRleCA+PSBnZXRUYWlsT2Zmc2V0KGxpc3QuX2NhcGFjaXR5KSkge1xuICAgICAgbmV3VGFpbCA9IHVwZGF0ZVZOb2RlKG5ld1RhaWwsIGxpc3QuX19vd25lcklELCAwLCBpbmRleCwgdmFsdWUsIGRpZEFsdGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3Um9vdCA9IHVwZGF0ZVZOb2RlKG5ld1Jvb3QsIGxpc3QuX19vd25lcklELCBsaXN0Ll9sZXZlbCwgaW5kZXgsIHZhbHVlLCBkaWRBbHRlcik7XG4gICAgfVxuXG4gICAgaWYgKCFkaWRBbHRlci52YWx1ZSkge1xuICAgICAgcmV0dXJuIGxpc3Q7XG4gICAgfVxuXG4gICAgaWYgKGxpc3QuX19vd25lcklEKSB7XG4gICAgICBsaXN0Ll9yb290ID0gbmV3Um9vdDtcbiAgICAgIGxpc3QuX3RhaWwgPSBuZXdUYWlsO1xuICAgICAgbGlzdC5fX2hhc2ggPSB1bmRlZmluZWQ7XG4gICAgICBsaXN0Ll9fYWx0ZXJlZCA9IHRydWU7XG4gICAgICByZXR1cm4gbGlzdDtcbiAgICB9XG4gICAgcmV0dXJuIG1ha2VMaXN0KGxpc3QuX29yaWdpbiwgbGlzdC5fY2FwYWNpdHksIGxpc3QuX2xldmVsLCBuZXdSb290LCBuZXdUYWlsKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVZOb2RlKG5vZGUsIG93bmVySUQsIGxldmVsLCBpbmRleCwgdmFsdWUsIGRpZEFsdGVyKSB7XG4gICAgdmFyIGlkeCA9IChpbmRleCA+Pj4gbGV2ZWwpICYgTUFTSztcbiAgICB2YXIgbm9kZUhhcyA9IG5vZGUgJiYgaWR4IDwgbm9kZS5hcnJheS5sZW5ndGg7XG4gICAgaWYgKCFub2RlSGFzICYmIHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cblxuICAgIHZhciBuZXdOb2RlO1xuXG4gICAgaWYgKGxldmVsID4gMCkge1xuICAgICAgdmFyIGxvd2VyTm9kZSA9IG5vZGUgJiYgbm9kZS5hcnJheVtpZHhdO1xuICAgICAgdmFyIG5ld0xvd2VyTm9kZSA9IHVwZGF0ZVZOb2RlKGxvd2VyTm9kZSwgb3duZXJJRCwgbGV2ZWwgLSBTSElGVCwgaW5kZXgsIHZhbHVlLCBkaWRBbHRlcik7XG4gICAgICBpZiAobmV3TG93ZXJOb2RlID09PSBsb3dlck5vZGUpIHtcbiAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICB9XG4gICAgICBuZXdOb2RlID0gZWRpdGFibGVWTm9kZShub2RlLCBvd25lcklEKTtcbiAgICAgIG5ld05vZGUuYXJyYXlbaWR4XSA9IG5ld0xvd2VyTm9kZTtcbiAgICAgIHJldHVybiBuZXdOb2RlO1xuICAgIH1cblxuICAgIGlmIChub2RlSGFzICYmIG5vZGUuYXJyYXlbaWR4XSA9PT0gdmFsdWUpIHtcbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cblxuICAgIFNldFJlZihkaWRBbHRlcik7XG5cbiAgICBuZXdOb2RlID0gZWRpdGFibGVWTm9kZShub2RlLCBvd25lcklEKTtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiBpZHggPT09IG5ld05vZGUuYXJyYXkubGVuZ3RoIC0gMSkge1xuICAgICAgbmV3Tm9kZS5hcnJheS5wb3AoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3Tm9kZS5hcnJheVtpZHhdID0gdmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBuZXdOb2RlO1xuICB9XG5cbiAgZnVuY3Rpb24gZWRpdGFibGVWTm9kZShub2RlLCBvd25lcklEKSB7XG4gICAgaWYgKG93bmVySUQgJiYgbm9kZSAmJiBvd25lcklEID09PSBub2RlLm93bmVySUQpIHtcbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFZOb2RlKG5vZGUgPyBub2RlLmFycmF5LnNsaWNlKCkgOiBbXSwgb3duZXJJRCk7XG4gIH1cblxuICBmdW5jdGlvbiBsaXN0Tm9kZUZvcihsaXN0LCByYXdJbmRleCkge1xuICAgIGlmIChyYXdJbmRleCA+PSBnZXRUYWlsT2Zmc2V0KGxpc3QuX2NhcGFjaXR5KSkge1xuICAgICAgcmV0dXJuIGxpc3QuX3RhaWw7XG4gICAgfVxuICAgIGlmIChyYXdJbmRleCA8IDEgPDwgKGxpc3QuX2xldmVsICsgU0hJRlQpKSB7XG4gICAgICB2YXIgbm9kZSA9IGxpc3QuX3Jvb3Q7XG4gICAgICB2YXIgbGV2ZWwgPSBsaXN0Ll9sZXZlbDtcbiAgICAgIHdoaWxlIChub2RlICYmIGxldmVsID4gMCkge1xuICAgICAgICBub2RlID0gbm9kZS5hcnJheVsocmF3SW5kZXggPj4+IGxldmVsKSAmIE1BU0tdO1xuICAgICAgICBsZXZlbCAtPSBTSElGVDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldExpc3RCb3VuZHMobGlzdCwgYmVnaW4sIGVuZCkge1xuICAgIC8vIFNhbml0aXplIGJlZ2luICYgZW5kIHVzaW5nIHRoaXMgc2hvcnRoYW5kIGZvciBUb0ludDMyKGFyZ3VtZW50KVxuICAgIC8vIGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b2ludDMyXG4gICAgaWYgKGJlZ2luICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGJlZ2luID0gYmVnaW4gfCAwO1xuICAgIH1cbiAgICBpZiAoZW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGVuZCA9IGVuZCB8IDA7XG4gICAgfVxuICAgIHZhciBvd25lciA9IGxpc3QuX19vd25lcklEIHx8IG5ldyBPd25lcklEKCk7XG4gICAgdmFyIG9sZE9yaWdpbiA9IGxpc3QuX29yaWdpbjtcbiAgICB2YXIgb2xkQ2FwYWNpdHkgPSBsaXN0Ll9jYXBhY2l0eTtcbiAgICB2YXIgbmV3T3JpZ2luID0gb2xkT3JpZ2luICsgYmVnaW47XG4gICAgdmFyIG5ld0NhcGFjaXR5ID0gZW5kID09PSB1bmRlZmluZWQgPyBvbGRDYXBhY2l0eSA6IGVuZCA8IDAgPyBvbGRDYXBhY2l0eSArIGVuZCA6IG9sZE9yaWdpbiArIGVuZDtcbiAgICBpZiAobmV3T3JpZ2luID09PSBvbGRPcmlnaW4gJiYgbmV3Q2FwYWNpdHkgPT09IG9sZENhcGFjaXR5KSB7XG4gICAgICByZXR1cm4gbGlzdDtcbiAgICB9XG5cbiAgICAvLyBJZiBpdCdzIGdvaW5nIHRvIGVuZCBhZnRlciBpdCBzdGFydHMsIGl0J3MgZW1wdHkuXG4gICAgaWYgKG5ld09yaWdpbiA+PSBuZXdDYXBhY2l0eSkge1xuICAgICAgcmV0dXJuIGxpc3QuY2xlYXIoKTtcbiAgICB9XG5cbiAgICB2YXIgbmV3TGV2ZWwgPSBsaXN0Ll9sZXZlbDtcbiAgICB2YXIgbmV3Um9vdCA9IGxpc3QuX3Jvb3Q7XG5cbiAgICAvLyBOZXcgb3JpZ2luIG1pZ2h0IG5lZWQgY3JlYXRpbmcgYSBoaWdoZXIgcm9vdC5cbiAgICB2YXIgb2Zmc2V0U2hpZnQgPSAwO1xuICAgIHdoaWxlIChuZXdPcmlnaW4gKyBvZmZzZXRTaGlmdCA8IDApIHtcbiAgICAgIG5ld1Jvb3QgPSBuZXcgVk5vZGUobmV3Um9vdCAmJiBuZXdSb290LmFycmF5Lmxlbmd0aCA/IFt1bmRlZmluZWQsIG5ld1Jvb3RdIDogW10sIG93bmVyKTtcbiAgICAgIG5ld0xldmVsICs9IFNISUZUO1xuICAgICAgb2Zmc2V0U2hpZnQgKz0gMSA8PCBuZXdMZXZlbDtcbiAgICB9XG4gICAgaWYgKG9mZnNldFNoaWZ0KSB7XG4gICAgICBuZXdPcmlnaW4gKz0gb2Zmc2V0U2hpZnQ7XG4gICAgICBvbGRPcmlnaW4gKz0gb2Zmc2V0U2hpZnQ7XG4gICAgICBuZXdDYXBhY2l0eSArPSBvZmZzZXRTaGlmdDtcbiAgICAgIG9sZENhcGFjaXR5ICs9IG9mZnNldFNoaWZ0O1xuICAgIH1cblxuICAgIHZhciBvbGRUYWlsT2Zmc2V0ID0gZ2V0VGFpbE9mZnNldChvbGRDYXBhY2l0eSk7XG4gICAgdmFyIG5ld1RhaWxPZmZzZXQgPSBnZXRUYWlsT2Zmc2V0KG5ld0NhcGFjaXR5KTtcblxuICAgIC8vIE5ldyBzaXplIG1pZ2h0IG5lZWQgY3JlYXRpbmcgYSBoaWdoZXIgcm9vdC5cbiAgICB3aGlsZSAobmV3VGFpbE9mZnNldCA+PSAxIDw8IChuZXdMZXZlbCArIFNISUZUKSkge1xuICAgICAgbmV3Um9vdCA9IG5ldyBWTm9kZShuZXdSb290ICYmIG5ld1Jvb3QuYXJyYXkubGVuZ3RoID8gW25ld1Jvb3RdIDogW10sIG93bmVyKTtcbiAgICAgIG5ld0xldmVsICs9IFNISUZUO1xuICAgIH1cblxuICAgIC8vIExvY2F0ZSBvciBjcmVhdGUgdGhlIG5ldyB0YWlsLlxuICAgIHZhciBvbGRUYWlsID0gbGlzdC5fdGFpbDtcbiAgICB2YXIgbmV3VGFpbCA9IG5ld1RhaWxPZmZzZXQgPCBvbGRUYWlsT2Zmc2V0ID9cbiAgICAgIGxpc3ROb2RlRm9yKGxpc3QsIG5ld0NhcGFjaXR5IC0gMSkgOlxuICAgICAgbmV3VGFpbE9mZnNldCA+IG9sZFRhaWxPZmZzZXQgPyBuZXcgVk5vZGUoW10sIG93bmVyKSA6IG9sZFRhaWw7XG5cbiAgICAvLyBNZXJnZSBUYWlsIGludG8gdHJlZS5cbiAgICBpZiAob2xkVGFpbCAmJiBuZXdUYWlsT2Zmc2V0ID4gb2xkVGFpbE9mZnNldCAmJiBuZXdPcmlnaW4gPCBvbGRDYXBhY2l0eSAmJiBvbGRUYWlsLmFycmF5Lmxlbmd0aCkge1xuICAgICAgbmV3Um9vdCA9IGVkaXRhYmxlVk5vZGUobmV3Um9vdCwgb3duZXIpO1xuICAgICAgdmFyIG5vZGUgPSBuZXdSb290O1xuICAgICAgZm9yICh2YXIgbGV2ZWwgPSBuZXdMZXZlbDsgbGV2ZWwgPiBTSElGVDsgbGV2ZWwgLT0gU0hJRlQpIHtcbiAgICAgICAgdmFyIGlkeCA9IChvbGRUYWlsT2Zmc2V0ID4+PiBsZXZlbCkgJiBNQVNLO1xuICAgICAgICBub2RlID0gbm9kZS5hcnJheVtpZHhdID0gZWRpdGFibGVWTm9kZShub2RlLmFycmF5W2lkeF0sIG93bmVyKTtcbiAgICAgIH1cbiAgICAgIG5vZGUuYXJyYXlbKG9sZFRhaWxPZmZzZXQgPj4+IFNISUZUKSAmIE1BU0tdID0gb2xkVGFpbDtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgc2l6ZSBoYXMgYmVlbiByZWR1Y2VkLCB0aGVyZSdzIGEgY2hhbmNlIHRoZSB0YWlsIG5lZWRzIHRvIGJlIHRyaW1tZWQuXG4gICAgaWYgKG5ld0NhcGFjaXR5IDwgb2xkQ2FwYWNpdHkpIHtcbiAgICAgIG5ld1RhaWwgPSBuZXdUYWlsICYmIG5ld1RhaWwucmVtb3ZlQWZ0ZXIob3duZXIsIDAsIG5ld0NhcGFjaXR5KTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgbmV3IG9yaWdpbiBpcyB3aXRoaW4gdGhlIHRhaWwsIHRoZW4gd2UgZG8gbm90IG5lZWQgYSByb290LlxuICAgIGlmIChuZXdPcmlnaW4gPj0gbmV3VGFpbE9mZnNldCkge1xuICAgICAgbmV3T3JpZ2luIC09IG5ld1RhaWxPZmZzZXQ7XG4gICAgICBuZXdDYXBhY2l0eSAtPSBuZXdUYWlsT2Zmc2V0O1xuICAgICAgbmV3TGV2ZWwgPSBTSElGVDtcbiAgICAgIG5ld1Jvb3QgPSBudWxsO1xuICAgICAgbmV3VGFpbCA9IG5ld1RhaWwgJiYgbmV3VGFpbC5yZW1vdmVCZWZvcmUob3duZXIsIDAsIG5ld09yaWdpbik7XG5cbiAgICAvLyBPdGhlcndpc2UsIGlmIHRoZSByb290IGhhcyBiZWVuIHRyaW1tZWQsIGdhcmJhZ2UgY29sbGVjdC5cbiAgICB9IGVsc2UgaWYgKG5ld09yaWdpbiA+IG9sZE9yaWdpbiB8fCBuZXdUYWlsT2Zmc2V0IDwgb2xkVGFpbE9mZnNldCkge1xuICAgICAgb2Zmc2V0U2hpZnQgPSAwO1xuXG4gICAgICAvLyBJZGVudGlmeSB0aGUgbmV3IHRvcCByb290IG5vZGUgb2YgdGhlIHN1YnRyZWUgb2YgdGhlIG9sZCByb290LlxuICAgICAgd2hpbGUgKG5ld1Jvb3QpIHtcbiAgICAgICAgdmFyIGJlZ2luSW5kZXggPSAobmV3T3JpZ2luID4+PiBuZXdMZXZlbCkgJiBNQVNLO1xuICAgICAgICBpZiAoYmVnaW5JbmRleCAhPT0gKG5ld1RhaWxPZmZzZXQgPj4+IG5ld0xldmVsKSAmIE1BU0spIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoYmVnaW5JbmRleCkge1xuICAgICAgICAgIG9mZnNldFNoaWZ0ICs9ICgxIDw8IG5ld0xldmVsKSAqIGJlZ2luSW5kZXg7XG4gICAgICAgIH1cbiAgICAgICAgbmV3TGV2ZWwgLT0gU0hJRlQ7XG4gICAgICAgIG5ld1Jvb3QgPSBuZXdSb290LmFycmF5W2JlZ2luSW5kZXhdO1xuICAgICAgfVxuXG4gICAgICAvLyBUcmltIHRoZSBuZXcgc2lkZXMgb2YgdGhlIG5ldyByb290LlxuICAgICAgaWYgKG5ld1Jvb3QgJiYgbmV3T3JpZ2luID4gb2xkT3JpZ2luKSB7XG4gICAgICAgIG5ld1Jvb3QgPSBuZXdSb290LnJlbW92ZUJlZm9yZShvd25lciwgbmV3TGV2ZWwsIG5ld09yaWdpbiAtIG9mZnNldFNoaWZ0KTtcbiAgICAgIH1cbiAgICAgIGlmIChuZXdSb290ICYmIG5ld1RhaWxPZmZzZXQgPCBvbGRUYWlsT2Zmc2V0KSB7XG4gICAgICAgIG5ld1Jvb3QgPSBuZXdSb290LnJlbW92ZUFmdGVyKG93bmVyLCBuZXdMZXZlbCwgbmV3VGFpbE9mZnNldCAtIG9mZnNldFNoaWZ0KTtcbiAgICAgIH1cbiAgICAgIGlmIChvZmZzZXRTaGlmdCkge1xuICAgICAgICBuZXdPcmlnaW4gLT0gb2Zmc2V0U2hpZnQ7XG4gICAgICAgIG5ld0NhcGFjaXR5IC09IG9mZnNldFNoaWZ0O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChsaXN0Ll9fb3duZXJJRCkge1xuICAgICAgbGlzdC5zaXplID0gbmV3Q2FwYWNpdHkgLSBuZXdPcmlnaW47XG4gICAgICBsaXN0Ll9vcmlnaW4gPSBuZXdPcmlnaW47XG4gICAgICBsaXN0Ll9jYXBhY2l0eSA9IG5ld0NhcGFjaXR5O1xuICAgICAgbGlzdC5fbGV2ZWwgPSBuZXdMZXZlbDtcbiAgICAgIGxpc3QuX3Jvb3QgPSBuZXdSb290O1xuICAgICAgbGlzdC5fdGFpbCA9IG5ld1RhaWw7XG4gICAgICBsaXN0Ll9faGFzaCA9IHVuZGVmaW5lZDtcbiAgICAgIGxpc3QuX19hbHRlcmVkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBsaXN0O1xuICAgIH1cbiAgICByZXR1cm4gbWFrZUxpc3QobmV3T3JpZ2luLCBuZXdDYXBhY2l0eSwgbmV3TGV2ZWwsIG5ld1Jvb3QsIG5ld1RhaWwpO1xuICB9XG5cbiAgZnVuY3Rpb24gbWVyZ2VJbnRvTGlzdFdpdGgobGlzdCwgbWVyZ2VyLCBpdGVyYWJsZXMpIHtcbiAgICB2YXIgaXRlcnMgPSBbXTtcbiAgICB2YXIgbWF4U2l6ZSA9IDA7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IGl0ZXJhYmxlcy5sZW5ndGg7IGlpKyspIHtcbiAgICAgIHZhciB2YWx1ZSA9IGl0ZXJhYmxlc1tpaV07XG4gICAgICB2YXIgaXRlciA9IEluZGV4ZWRJdGVyYWJsZSh2YWx1ZSk7XG4gICAgICBpZiAoaXRlci5zaXplID4gbWF4U2l6ZSkge1xuICAgICAgICBtYXhTaXplID0gaXRlci5zaXplO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0l0ZXJhYmxlKHZhbHVlKSkge1xuICAgICAgICBpdGVyID0gaXRlci5tYXAoZnVuY3Rpb24odiApIHtyZXR1cm4gZnJvbUpTKHYpfSk7XG4gICAgICB9XG4gICAgICBpdGVycy5wdXNoKGl0ZXIpO1xuICAgIH1cbiAgICBpZiAobWF4U2l6ZSA+IGxpc3Quc2l6ZSkge1xuICAgICAgbGlzdCA9IGxpc3Quc2V0U2l6ZShtYXhTaXplKTtcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlSW50b0NvbGxlY3Rpb25XaXRoKGxpc3QsIG1lcmdlciwgaXRlcnMpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0VGFpbE9mZnNldChzaXplKSB7XG4gICAgcmV0dXJuIHNpemUgPCBTSVpFID8gMCA6ICgoKHNpemUgLSAxKSA+Pj4gU0hJRlQpIDw8IFNISUZUKTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKE9yZGVyZWRNYXAsIE1hcCk7XG5cbiAgICAvLyBAcHJhZ21hIENvbnN0cnVjdGlvblxuXG4gICAgZnVuY3Rpb24gT3JkZXJlZE1hcCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgPyBlbXB0eU9yZGVyZWRNYXAoKSA6XG4gICAgICAgIGlzT3JkZXJlZE1hcCh2YWx1ZSkgPyB2YWx1ZSA6XG4gICAgICAgIGVtcHR5T3JkZXJlZE1hcCgpLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24obWFwICkge1xuICAgICAgICAgIHZhciBpdGVyID0gS2V5ZWRJdGVyYWJsZSh2YWx1ZSk7XG4gICAgICAgICAgYXNzZXJ0Tm90SW5maW5pdGUoaXRlci5zaXplKTtcbiAgICAgICAgICBpdGVyLmZvckVhY2goZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gbWFwLnNldChrLCB2KX0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBPcmRlcmVkTWFwLm9mID0gZnVuY3Rpb24oLyouLi52YWx1ZXMqLykge1xuICAgICAgcmV0dXJuIHRoaXMoYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgT3JkZXJlZE1hcC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fdG9TdHJpbmcoJ09yZGVyZWRNYXAgeycsICd9Jyk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgQWNjZXNzXG5cbiAgICBPcmRlcmVkTWFwLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihrLCBub3RTZXRWYWx1ZSkge1xuICAgICAgdmFyIGluZGV4ID0gdGhpcy5fbWFwLmdldChrKTtcbiAgICAgIHJldHVybiBpbmRleCAhPT0gdW5kZWZpbmVkID8gdGhpcy5fbGlzdC5nZXQoaW5kZXgpWzFdIDogbm90U2V0VmFsdWU7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgTW9kaWZpY2F0aW9uXG5cbiAgICBPcmRlcmVkTWFwLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuc2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICB0aGlzLnNpemUgPSAwO1xuICAgICAgICB0aGlzLl9tYXAuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fbGlzdC5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbXB0eU9yZGVyZWRNYXAoKTtcbiAgICB9O1xuXG4gICAgT3JkZXJlZE1hcC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24oaywgdikge1xuICAgICAgcmV0dXJuIHVwZGF0ZU9yZGVyZWRNYXAodGhpcywgaywgdik7XG4gICAgfTtcblxuICAgIE9yZGVyZWRNYXAucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKGspIHtcbiAgICAgIHJldHVybiB1cGRhdGVPcmRlcmVkTWFwKHRoaXMsIGssIE5PVF9TRVQpO1xuICAgIH07XG5cbiAgICBPcmRlcmVkTWFwLnByb3RvdHlwZS53YXNBbHRlcmVkID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbWFwLndhc0FsdGVyZWQoKSB8fCB0aGlzLl9saXN0Lndhc0FsdGVyZWQoKTtcbiAgICB9O1xuXG4gICAgT3JkZXJlZE1hcC5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHJldHVybiB0aGlzLl9saXN0Ll9faXRlcmF0ZShcbiAgICAgICAgZnVuY3Rpb24oZW50cnkgKSB7cmV0dXJuIGVudHJ5ICYmIGZuKGVudHJ5WzFdLCBlbnRyeVswXSwgdGhpcyQwKX0sXG4gICAgICAgIHJldmVyc2VcbiAgICAgICk7XG4gICAgfTtcblxuICAgIE9yZGVyZWRNYXAucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbGlzdC5mcm9tRW50cnlTZXEoKS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgIH07XG5cbiAgICBPcmRlcmVkTWFwLnByb3RvdHlwZS5fX2Vuc3VyZU93bmVyID0gZnVuY3Rpb24ob3duZXJJRCkge1xuICAgICAgaWYgKG93bmVySUQgPT09IHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIG5ld01hcCA9IHRoaXMuX21hcC5fX2Vuc3VyZU93bmVyKG93bmVySUQpO1xuICAgICAgdmFyIG5ld0xpc3QgPSB0aGlzLl9saXN0Ll9fZW5zdXJlT3duZXIob3duZXJJRCk7XG4gICAgICBpZiAoIW93bmVySUQpIHtcbiAgICAgICAgdGhpcy5fX293bmVySUQgPSBvd25lcklEO1xuICAgICAgICB0aGlzLl9tYXAgPSBuZXdNYXA7XG4gICAgICAgIHRoaXMuX2xpc3QgPSBuZXdMaXN0O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYWtlT3JkZXJlZE1hcChuZXdNYXAsIG5ld0xpc3QsIG93bmVySUQsIHRoaXMuX19oYXNoKTtcbiAgICB9O1xuXG5cbiAgZnVuY3Rpb24gaXNPcmRlcmVkTWFwKG1heWJlT3JkZXJlZE1hcCkge1xuICAgIHJldHVybiBpc01hcChtYXliZU9yZGVyZWRNYXApICYmIGlzT3JkZXJlZChtYXliZU9yZGVyZWRNYXApO1xuICB9XG5cbiAgT3JkZXJlZE1hcC5pc09yZGVyZWRNYXAgPSBpc09yZGVyZWRNYXA7XG5cbiAgT3JkZXJlZE1hcC5wcm90b3R5cGVbSVNfT1JERVJFRF9TRU5USU5FTF0gPSB0cnVlO1xuICBPcmRlcmVkTWFwLnByb3RvdHlwZVtERUxFVEVdID0gT3JkZXJlZE1hcC5wcm90b3R5cGUucmVtb3ZlO1xuXG5cblxuICBmdW5jdGlvbiBtYWtlT3JkZXJlZE1hcChtYXAsIGxpc3QsIG93bmVySUQsIGhhc2gpIHtcbiAgICB2YXIgb21hcCA9IE9iamVjdC5jcmVhdGUoT3JkZXJlZE1hcC5wcm90b3R5cGUpO1xuICAgIG9tYXAuc2l6ZSA9IG1hcCA/IG1hcC5zaXplIDogMDtcbiAgICBvbWFwLl9tYXAgPSBtYXA7XG4gICAgb21hcC5fbGlzdCA9IGxpc3Q7XG4gICAgb21hcC5fX293bmVySUQgPSBvd25lcklEO1xuICAgIG9tYXAuX19oYXNoID0gaGFzaDtcbiAgICByZXR1cm4gb21hcDtcbiAgfVxuXG4gIHZhciBFTVBUWV9PUkRFUkVEX01BUDtcbiAgZnVuY3Rpb24gZW1wdHlPcmRlcmVkTWFwKCkge1xuICAgIHJldHVybiBFTVBUWV9PUkRFUkVEX01BUCB8fCAoRU1QVFlfT1JERVJFRF9NQVAgPSBtYWtlT3JkZXJlZE1hcChlbXB0eU1hcCgpLCBlbXB0eUxpc3QoKSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlT3JkZXJlZE1hcChvbWFwLCBrLCB2KSB7XG4gICAgdmFyIG1hcCA9IG9tYXAuX21hcDtcbiAgICB2YXIgbGlzdCA9IG9tYXAuX2xpc3Q7XG4gICAgdmFyIGkgPSBtYXAuZ2V0KGspO1xuICAgIHZhciBoYXMgPSBpICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIG5ld01hcDtcbiAgICB2YXIgbmV3TGlzdDtcbiAgICBpZiAodiA9PT0gTk9UX1NFVCkgeyAvLyByZW1vdmVkXG4gICAgICBpZiAoIWhhcykge1xuICAgICAgICByZXR1cm4gb21hcDtcbiAgICAgIH1cbiAgICAgIGlmIChsaXN0LnNpemUgPj0gU0laRSAmJiBsaXN0LnNpemUgPj0gbWFwLnNpemUgKiAyKSB7XG4gICAgICAgIG5ld0xpc3QgPSBsaXN0LmZpbHRlcihmdW5jdGlvbihlbnRyeSwgaWR4KSAge3JldHVybiBlbnRyeSAhPT0gdW5kZWZpbmVkICYmIGkgIT09IGlkeH0pO1xuICAgICAgICBuZXdNYXAgPSBuZXdMaXN0LnRvS2V5ZWRTZXEoKS5tYXAoZnVuY3Rpb24oZW50cnkgKSB7cmV0dXJuIGVudHJ5WzBdfSkuZmxpcCgpLnRvTWFwKCk7XG4gICAgICAgIGlmIChvbWFwLl9fb3duZXJJRCkge1xuICAgICAgICAgIG5ld01hcC5fX293bmVySUQgPSBuZXdMaXN0Ll9fb3duZXJJRCA9IG9tYXAuX19vd25lcklEO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdNYXAgPSBtYXAucmVtb3ZlKGspO1xuICAgICAgICBuZXdMaXN0ID0gaSA9PT0gbGlzdC5zaXplIC0gMSA/IGxpc3QucG9wKCkgOiBsaXN0LnNldChpLCB1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaGFzKSB7XG4gICAgICAgIGlmICh2ID09PSBsaXN0LmdldChpKVsxXSkge1xuICAgICAgICAgIHJldHVybiBvbWFwO1xuICAgICAgICB9XG4gICAgICAgIG5ld01hcCA9IG1hcDtcbiAgICAgICAgbmV3TGlzdCA9IGxpc3Quc2V0KGksIFtrLCB2XSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdNYXAgPSBtYXAuc2V0KGssIGxpc3Quc2l6ZSk7XG4gICAgICAgIG5ld0xpc3QgPSBsaXN0LnNldChsaXN0LnNpemUsIFtrLCB2XSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChvbWFwLl9fb3duZXJJRCkge1xuICAgICAgb21hcC5zaXplID0gbmV3TWFwLnNpemU7XG4gICAgICBvbWFwLl9tYXAgPSBuZXdNYXA7XG4gICAgICBvbWFwLl9saXN0ID0gbmV3TGlzdDtcbiAgICAgIG9tYXAuX19oYXNoID0gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIG9tYXA7XG4gICAgfVxuICAgIHJldHVybiBtYWtlT3JkZXJlZE1hcChuZXdNYXAsIG5ld0xpc3QpO1xuICB9XG5cbiAgY3JlYXRlQ2xhc3MoVG9LZXllZFNlcXVlbmNlLCBLZXllZFNlcSk7XG4gICAgZnVuY3Rpb24gVG9LZXllZFNlcXVlbmNlKGluZGV4ZWQsIHVzZUtleXMpIHtcbiAgICAgIHRoaXMuX2l0ZXIgPSBpbmRleGVkO1xuICAgICAgdGhpcy5fdXNlS2V5cyA9IHVzZUtleXM7XG4gICAgICB0aGlzLnNpemUgPSBpbmRleGVkLnNpemU7XG4gICAgfVxuXG4gICAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihrZXksIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5nZXQoa2V5LCBub3RTZXRWYWx1ZSk7XG4gICAgfTtcblxuICAgIFRvS2V5ZWRTZXF1ZW5jZS5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5oYXMoa2V5KTtcbiAgICB9O1xuXG4gICAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS52YWx1ZVNlcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2l0ZXIudmFsdWVTZXEoKTtcbiAgICB9O1xuXG4gICAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS5yZXZlcnNlID0gZnVuY3Rpb24oKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICB2YXIgcmV2ZXJzZWRTZXF1ZW5jZSA9IHJldmVyc2VGYWN0b3J5KHRoaXMsIHRydWUpO1xuICAgICAgaWYgKCF0aGlzLl91c2VLZXlzKSB7XG4gICAgICAgIHJldmVyc2VkU2VxdWVuY2UudmFsdWVTZXEgPSBmdW5jdGlvbigpICB7cmV0dXJuIHRoaXMkMC5faXRlci50b1NlcSgpLnJldmVyc2UoKX07XG4gICAgICB9XG4gICAgICByZXR1cm4gcmV2ZXJzZWRTZXF1ZW5jZTtcbiAgICB9O1xuXG4gICAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS5tYXAgPSBmdW5jdGlvbihtYXBwZXIsIGNvbnRleHQpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHZhciBtYXBwZWRTZXF1ZW5jZSA9IG1hcEZhY3RvcnkodGhpcywgbWFwcGVyLCBjb250ZXh0KTtcbiAgICAgIGlmICghdGhpcy5fdXNlS2V5cykge1xuICAgICAgICBtYXBwZWRTZXF1ZW5jZS52YWx1ZVNlcSA9IGZ1bmN0aW9uKCkgIHtyZXR1cm4gdGhpcyQwLl9pdGVyLnRvU2VxKCkubWFwKG1hcHBlciwgY29udGV4dCl9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hcHBlZFNlcXVlbmNlO1xuICAgIH07XG5cbiAgICBUb0tleWVkU2VxdWVuY2UucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICB2YXIgaWk7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5fX2l0ZXJhdGUoXG4gICAgICAgIHRoaXMuX3VzZUtleXMgP1xuICAgICAgICAgIGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIGZuKHYsIGssIHRoaXMkMCl9IDpcbiAgICAgICAgICAoKGlpID0gcmV2ZXJzZSA/IHJlc29sdmVTaXplKHRoaXMpIDogMCksXG4gICAgICAgICAgICBmdW5jdGlvbih2ICkge3JldHVybiBmbih2LCByZXZlcnNlID8gLS1paSA6IGlpKyssIHRoaXMkMCl9KSxcbiAgICAgICAgcmV2ZXJzZVxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgaWYgKHRoaXMuX3VzZUtleXMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2l0ZXIuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyYXRvciA9IHRoaXMuX2l0ZXIuX19pdGVyYXRvcihJVEVSQVRFX1ZBTFVFUywgcmV2ZXJzZSk7XG4gICAgICB2YXIgaWkgPSByZXZlcnNlID8gcmVzb2x2ZVNpemUodGhpcykgOiAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICByZXR1cm4gc3RlcC5kb25lID8gc3RlcCA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCByZXZlcnNlID8gLS1paSA6IGlpKyssIHN0ZXAudmFsdWUsIHN0ZXApO1xuICAgICAgfSk7XG4gICAgfTtcblxuICBUb0tleWVkU2VxdWVuY2UucHJvdG90eXBlW0lTX09SREVSRURfU0VOVElORUxdID0gdHJ1ZTtcblxuXG4gIGNyZWF0ZUNsYXNzKFRvSW5kZXhlZFNlcXVlbmNlLCBJbmRleGVkU2VxKTtcbiAgICBmdW5jdGlvbiBUb0luZGV4ZWRTZXF1ZW5jZShpdGVyKSB7XG4gICAgICB0aGlzLl9pdGVyID0gaXRlcjtcbiAgICAgIHRoaXMuc2l6ZSA9IGl0ZXIuc2l6ZTtcbiAgICB9XG5cbiAgICBUb0luZGV4ZWRTZXF1ZW5jZS5wcm90b3R5cGUuaW5jbHVkZXMgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2l0ZXIuaW5jbHVkZXModmFsdWUpO1xuICAgIH07XG5cbiAgICBUb0luZGV4ZWRTZXF1ZW5jZS5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHJldHVybiB0aGlzLl9pdGVyLl9faXRlcmF0ZShmdW5jdGlvbih2ICkge3JldHVybiBmbih2LCBpdGVyYXRpb25zKyssIHRoaXMkMCl9LCByZXZlcnNlKTtcbiAgICB9O1xuXG4gICAgVG9JbmRleGVkU2VxdWVuY2UucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgaXRlcmF0b3IgPSB0aGlzLl9pdGVyLl9faXRlcmF0b3IoSVRFUkFURV9WQUxVRVMsIHJldmVyc2UpO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICByZXR1cm4gc3RlcC5kb25lID8gc3RlcCA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHN0ZXAudmFsdWUsIHN0ZXApXG4gICAgICB9KTtcbiAgICB9O1xuXG5cblxuICBjcmVhdGVDbGFzcyhUb1NldFNlcXVlbmNlLCBTZXRTZXEpO1xuICAgIGZ1bmN0aW9uIFRvU2V0U2VxdWVuY2UoaXRlcikge1xuICAgICAgdGhpcy5faXRlciA9IGl0ZXI7XG4gICAgICB0aGlzLnNpemUgPSBpdGVyLnNpemU7XG4gICAgfVxuXG4gICAgVG9TZXRTZXF1ZW5jZS5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5pbmNsdWRlcyhrZXkpO1xuICAgIH07XG5cbiAgICBUb1NldFNlcXVlbmNlLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIHRoaXMuX2l0ZXIuX19pdGVyYXRlKGZ1bmN0aW9uKHYgKSB7cmV0dXJuIGZuKHYsIHYsIHRoaXMkMCl9LCByZXZlcnNlKTtcbiAgICB9O1xuXG4gICAgVG9TZXRTZXF1ZW5jZS5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHZhciBpdGVyYXRvciA9IHRoaXMuX2l0ZXIuX19pdGVyYXRvcihJVEVSQVRFX1ZBTFVFUywgcmV2ZXJzZSk7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgdmFyIHN0ZXAgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIHJldHVybiBzdGVwLmRvbmUgPyBzdGVwIDpcbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIHN0ZXAudmFsdWUsIHN0ZXAudmFsdWUsIHN0ZXApO1xuICAgICAgfSk7XG4gICAgfTtcblxuXG5cbiAgY3JlYXRlQ2xhc3MoRnJvbUVudHJpZXNTZXF1ZW5jZSwgS2V5ZWRTZXEpO1xuICAgIGZ1bmN0aW9uIEZyb21FbnRyaWVzU2VxdWVuY2UoZW50cmllcykge1xuICAgICAgdGhpcy5faXRlciA9IGVudHJpZXM7XG4gICAgICB0aGlzLnNpemUgPSBlbnRyaWVzLnNpemU7XG4gICAgfVxuXG4gICAgRnJvbUVudHJpZXNTZXF1ZW5jZS5wcm90b3R5cGUuZW50cnlTZXEgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pdGVyLnRvU2VxKCk7XG4gICAgfTtcblxuICAgIEZyb21FbnRyaWVzU2VxdWVuY2UucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5fX2l0ZXJhdGUoZnVuY3Rpb24oZW50cnkgKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIGVudHJ5IGV4aXN0cyBmaXJzdCBzbyBhcnJheSBhY2Nlc3MgZG9lc24ndCB0aHJvdyBmb3IgaG9sZXNcbiAgICAgICAgLy8gaW4gdGhlIHBhcmVudCBpdGVyYXRpb24uXG4gICAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICAgIHZhbGlkYXRlRW50cnkoZW50cnkpO1xuICAgICAgICAgIHZhciBpbmRleGVkSXRlcmFibGUgPSBpc0l0ZXJhYmxlKGVudHJ5KTtcbiAgICAgICAgICByZXR1cm4gZm4oXG4gICAgICAgICAgICBpbmRleGVkSXRlcmFibGUgPyBlbnRyeS5nZXQoMSkgOiBlbnRyeVsxXSxcbiAgICAgICAgICAgIGluZGV4ZWRJdGVyYWJsZSA/IGVudHJ5LmdldCgwKSA6IGVudHJ5WzBdLFxuICAgICAgICAgICAgdGhpcyQwXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSwgcmV2ZXJzZSk7XG4gICAgfTtcblxuICAgIEZyb21FbnRyaWVzU2VxdWVuY2UucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgaXRlcmF0b3IgPSB0aGlzLl9pdGVyLl9faXRlcmF0b3IoSVRFUkFURV9WQUxVRVMsIHJldmVyc2UpO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgdmFyIHN0ZXAgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgICAgaWYgKHN0ZXAuZG9uZSkge1xuICAgICAgICAgICAgcmV0dXJuIHN0ZXA7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciBlbnRyeSA9IHN0ZXAudmFsdWU7XG4gICAgICAgICAgLy8gQ2hlY2sgaWYgZW50cnkgZXhpc3RzIGZpcnN0IHNvIGFycmF5IGFjY2VzcyBkb2Vzbid0IHRocm93IGZvciBob2xlc1xuICAgICAgICAgIC8vIGluIHRoZSBwYXJlbnQgaXRlcmF0aW9uLlxuICAgICAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICAgICAgdmFsaWRhdGVFbnRyeShlbnRyeSk7XG4gICAgICAgICAgICB2YXIgaW5kZXhlZEl0ZXJhYmxlID0gaXNJdGVyYWJsZShlbnRyeSk7XG4gICAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZShcbiAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgaW5kZXhlZEl0ZXJhYmxlID8gZW50cnkuZ2V0KDApIDogZW50cnlbMF0sXG4gICAgICAgICAgICAgIGluZGV4ZWRJdGVyYWJsZSA/IGVudHJ5LmdldCgxKSA6IGVudHJ5WzFdLFxuICAgICAgICAgICAgICBzdGVwXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuXG4gIFRvSW5kZXhlZFNlcXVlbmNlLnByb3RvdHlwZS5jYWNoZVJlc3VsdCA9XG4gIFRvS2V5ZWRTZXF1ZW5jZS5wcm90b3R5cGUuY2FjaGVSZXN1bHQgPVxuICBUb1NldFNlcXVlbmNlLnByb3RvdHlwZS5jYWNoZVJlc3VsdCA9XG4gIEZyb21FbnRyaWVzU2VxdWVuY2UucHJvdG90eXBlLmNhY2hlUmVzdWx0ID1cbiAgICBjYWNoZVJlc3VsdFRocm91Z2g7XG5cblxuICBmdW5jdGlvbiBmbGlwRmFjdG9yeShpdGVyYWJsZSkge1xuICAgIHZhciBmbGlwU2VxdWVuY2UgPSBtYWtlU2VxdWVuY2UoaXRlcmFibGUpO1xuICAgIGZsaXBTZXF1ZW5jZS5faXRlciA9IGl0ZXJhYmxlO1xuICAgIGZsaXBTZXF1ZW5jZS5zaXplID0gaXRlcmFibGUuc2l6ZTtcbiAgICBmbGlwU2VxdWVuY2UuZmxpcCA9IGZ1bmN0aW9uKCkgIHtyZXR1cm4gaXRlcmFibGV9O1xuICAgIGZsaXBTZXF1ZW5jZS5yZXZlcnNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHJldmVyc2VkU2VxdWVuY2UgPSBpdGVyYWJsZS5yZXZlcnNlLmFwcGx5KHRoaXMpOyAvLyBzdXBlci5yZXZlcnNlKClcbiAgICAgIHJldmVyc2VkU2VxdWVuY2UuZmxpcCA9IGZ1bmN0aW9uKCkgIHtyZXR1cm4gaXRlcmFibGUucmV2ZXJzZSgpfTtcbiAgICAgIHJldHVybiByZXZlcnNlZFNlcXVlbmNlO1xuICAgIH07XG4gICAgZmxpcFNlcXVlbmNlLmhhcyA9IGZ1bmN0aW9uKGtleSApIHtyZXR1cm4gaXRlcmFibGUuaW5jbHVkZXMoa2V5KX07XG4gICAgZmxpcFNlcXVlbmNlLmluY2x1ZGVzID0gZnVuY3Rpb24oa2V5ICkge3JldHVybiBpdGVyYWJsZS5oYXMoa2V5KX07XG4gICAgZmxpcFNlcXVlbmNlLmNhY2hlUmVzdWx0ID0gY2FjaGVSZXN1bHRUaHJvdWdoO1xuICAgIGZsaXBTZXF1ZW5jZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIGl0ZXJhYmxlLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrKSAge3JldHVybiBmbihrLCB2LCB0aGlzJDApICE9PSBmYWxzZX0sIHJldmVyc2UpO1xuICAgIH1cbiAgICBmbGlwU2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgaWYgKHR5cGUgPT09IElURVJBVEVfRU5UUklFUykge1xuICAgICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYWJsZS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICBpZiAoIXN0ZXAuZG9uZSkge1xuICAgICAgICAgICAgdmFyIGsgPSBzdGVwLnZhbHVlWzBdO1xuICAgICAgICAgICAgc3RlcC52YWx1ZVswXSA9IHN0ZXAudmFsdWVbMV07XG4gICAgICAgICAgICBzdGVwLnZhbHVlWzFdID0gaztcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHN0ZXA7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGl0ZXJhYmxlLl9faXRlcmF0b3IoXG4gICAgICAgIHR5cGUgPT09IElURVJBVEVfVkFMVUVTID8gSVRFUkFURV9LRVlTIDogSVRFUkFURV9WQUxVRVMsXG4gICAgICAgIHJldmVyc2VcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBmbGlwU2VxdWVuY2U7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIG1hcEZhY3RvcnkoaXRlcmFibGUsIG1hcHBlciwgY29udGV4dCkge1xuICAgIHZhciBtYXBwZWRTZXF1ZW5jZSA9IG1ha2VTZXF1ZW5jZShpdGVyYWJsZSk7XG4gICAgbWFwcGVkU2VxdWVuY2Uuc2l6ZSA9IGl0ZXJhYmxlLnNpemU7XG4gICAgbWFwcGVkU2VxdWVuY2UuaGFzID0gZnVuY3Rpb24oa2V5ICkge3JldHVybiBpdGVyYWJsZS5oYXMoa2V5KX07XG4gICAgbWFwcGVkU2VxdWVuY2UuZ2V0ID0gZnVuY3Rpb24oa2V5LCBub3RTZXRWYWx1ZSkgIHtcbiAgICAgIHZhciB2ID0gaXRlcmFibGUuZ2V0KGtleSwgTk9UX1NFVCk7XG4gICAgICByZXR1cm4gdiA9PT0gTk9UX1NFVCA/XG4gICAgICAgIG5vdFNldFZhbHVlIDpcbiAgICAgICAgbWFwcGVyLmNhbGwoY29udGV4dCwgdiwga2V5LCBpdGVyYWJsZSk7XG4gICAgfTtcbiAgICBtYXBwZWRTZXF1ZW5jZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIGl0ZXJhYmxlLl9faXRlcmF0ZShcbiAgICAgICAgZnVuY3Rpb24odiwgaywgYykgIHtyZXR1cm4gZm4obWFwcGVyLmNhbGwoY29udGV4dCwgdiwgaywgYyksIGssIHRoaXMkMCkgIT09IGZhbHNlfSxcbiAgICAgICAgcmV2ZXJzZVxuICAgICAgKTtcbiAgICB9XG4gICAgbWFwcGVkU2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24gKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHZhciBpdGVyYXRvciA9IGl0ZXJhYmxlLl9faXRlcmF0b3IoSVRFUkFURV9FTlRSSUVTLCByZXZlcnNlKTtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKHN0ZXAuZG9uZSkge1xuICAgICAgICAgIHJldHVybiBzdGVwO1xuICAgICAgICB9XG4gICAgICAgIHZhciBlbnRyeSA9IHN0ZXAudmFsdWU7XG4gICAgICAgIHZhciBrZXkgPSBlbnRyeVswXTtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVmFsdWUoXG4gICAgICAgICAgdHlwZSxcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgbWFwcGVyLmNhbGwoY29udGV4dCwgZW50cnlbMV0sIGtleSwgaXRlcmFibGUpLFxuICAgICAgICAgIHN0ZXBcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gbWFwcGVkU2VxdWVuY2U7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHJldmVyc2VGYWN0b3J5KGl0ZXJhYmxlLCB1c2VLZXlzKSB7XG4gICAgdmFyIHJldmVyc2VkU2VxdWVuY2UgPSBtYWtlU2VxdWVuY2UoaXRlcmFibGUpO1xuICAgIHJldmVyc2VkU2VxdWVuY2UuX2l0ZXIgPSBpdGVyYWJsZTtcbiAgICByZXZlcnNlZFNlcXVlbmNlLnNpemUgPSBpdGVyYWJsZS5zaXplO1xuICAgIHJldmVyc2VkU2VxdWVuY2UucmV2ZXJzZSA9IGZ1bmN0aW9uKCkgIHtyZXR1cm4gaXRlcmFibGV9O1xuICAgIGlmIChpdGVyYWJsZS5mbGlwKSB7XG4gICAgICByZXZlcnNlZFNlcXVlbmNlLmZsaXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmbGlwU2VxdWVuY2UgPSBmbGlwRmFjdG9yeShpdGVyYWJsZSk7XG4gICAgICAgIGZsaXBTZXF1ZW5jZS5yZXZlcnNlID0gZnVuY3Rpb24oKSAge3JldHVybiBpdGVyYWJsZS5mbGlwKCl9O1xuICAgICAgICByZXR1cm4gZmxpcFNlcXVlbmNlO1xuICAgICAgfTtcbiAgICB9XG4gICAgcmV2ZXJzZWRTZXF1ZW5jZS5nZXQgPSBmdW5jdGlvbihrZXksIG5vdFNldFZhbHVlKSBcbiAgICAgIHtyZXR1cm4gaXRlcmFibGUuZ2V0KHVzZUtleXMgPyBrZXkgOiAtMSAtIGtleSwgbm90U2V0VmFsdWUpfTtcbiAgICByZXZlcnNlZFNlcXVlbmNlLmhhcyA9IGZ1bmN0aW9uKGtleSApXG4gICAgICB7cmV0dXJuIGl0ZXJhYmxlLmhhcyh1c2VLZXlzID8ga2V5IDogLTEgLSBrZXkpfTtcbiAgICByZXZlcnNlZFNlcXVlbmNlLmluY2x1ZGVzID0gZnVuY3Rpb24odmFsdWUgKSB7cmV0dXJuIGl0ZXJhYmxlLmluY2x1ZGVzKHZhbHVlKX07XG4gICAgcmV2ZXJzZWRTZXF1ZW5jZS5jYWNoZVJlc3VsdCA9IGNhY2hlUmVzdWx0VGhyb3VnaDtcbiAgICByZXZlcnNlZFNlcXVlbmNlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIGl0ZXJhYmxlLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrKSAge3JldHVybiBmbih2LCBrLCB0aGlzJDApfSwgIXJldmVyc2UpO1xuICAgIH07XG4gICAgcmV2ZXJzZWRTZXF1ZW5jZS5fX2l0ZXJhdG9yID1cbiAgICAgIGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpICB7cmV0dXJuIGl0ZXJhYmxlLl9faXRlcmF0b3IodHlwZSwgIXJldmVyc2UpfTtcbiAgICByZXR1cm4gcmV2ZXJzZWRTZXF1ZW5jZTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gZmlsdGVyRmFjdG9yeShpdGVyYWJsZSwgcHJlZGljYXRlLCBjb250ZXh0LCB1c2VLZXlzKSB7XG4gICAgdmFyIGZpbHRlclNlcXVlbmNlID0gbWFrZVNlcXVlbmNlKGl0ZXJhYmxlKTtcbiAgICBpZiAodXNlS2V5cykge1xuICAgICAgZmlsdGVyU2VxdWVuY2UuaGFzID0gZnVuY3Rpb24oa2V5ICkge1xuICAgICAgICB2YXIgdiA9IGl0ZXJhYmxlLmdldChrZXksIE5PVF9TRVQpO1xuICAgICAgICByZXR1cm4gdiAhPT0gTk9UX1NFVCAmJiAhIXByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHYsIGtleSwgaXRlcmFibGUpO1xuICAgICAgfTtcbiAgICAgIGZpbHRlclNlcXVlbmNlLmdldCA9IGZ1bmN0aW9uKGtleSwgbm90U2V0VmFsdWUpICB7XG4gICAgICAgIHZhciB2ID0gaXRlcmFibGUuZ2V0KGtleSwgTk9UX1NFVCk7XG4gICAgICAgIHJldHVybiB2ICE9PSBOT1RfU0VUICYmIHByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHYsIGtleSwgaXRlcmFibGUpID9cbiAgICAgICAgICB2IDogbm90U2V0VmFsdWU7XG4gICAgICB9O1xuICAgIH1cbiAgICBmaWx0ZXJTZXF1ZW5jZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgaXRlcmFibGUuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGssIGMpICB7XG4gICAgICAgIGlmIChwcmVkaWNhdGUuY2FsbChjb250ZXh0LCB2LCBrLCBjKSkge1xuICAgICAgICAgIGl0ZXJhdGlvbnMrKztcbiAgICAgICAgICByZXR1cm4gZm4odiwgdXNlS2V5cyA/IGsgOiBpdGVyYXRpb25zIC0gMSwgdGhpcyQwKTtcbiAgICAgICAgfVxuICAgICAgfSwgcmV2ZXJzZSk7XG4gICAgICByZXR1cm4gaXRlcmF0aW9ucztcbiAgICB9O1xuICAgIGZpbHRlclNlcXVlbmNlLl9faXRlcmF0b3JVbmNhY2hlZCA9IGZ1bmN0aW9uICh0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYWJsZS5fX2l0ZXJhdG9yKElURVJBVEVfRU5UUklFUywgcmV2ZXJzZSk7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICBpZiAoc3RlcC5kb25lKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RlcDtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGVudHJ5ID0gc3RlcC52YWx1ZTtcbiAgICAgICAgICB2YXIga2V5ID0gZW50cnlbMF07XG4gICAgICAgICAgdmFyIHZhbHVlID0gZW50cnlbMV07XG4gICAgICAgICAgaWYgKHByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHZhbHVlLCBrZXksIGl0ZXJhYmxlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVmFsdWUodHlwZSwgdXNlS2V5cyA/IGtleSA6IGl0ZXJhdGlvbnMrKywgdmFsdWUsIHN0ZXApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBmaWx0ZXJTZXF1ZW5jZTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gY291bnRCeUZhY3RvcnkoaXRlcmFibGUsIGdyb3VwZXIsIGNvbnRleHQpIHtcbiAgICB2YXIgZ3JvdXBzID0gTWFwKCkuYXNNdXRhYmxlKCk7XG4gICAgaXRlcmFibGUuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGspICB7XG4gICAgICBncm91cHMudXBkYXRlKFxuICAgICAgICBncm91cGVyLmNhbGwoY29udGV4dCwgdiwgaywgaXRlcmFibGUpLFxuICAgICAgICAwLFxuICAgICAgICBmdW5jdGlvbihhICkge3JldHVybiBhICsgMX1cbiAgICAgICk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGdyb3Vwcy5hc0ltbXV0YWJsZSgpO1xuICB9XG5cblxuICBmdW5jdGlvbiBncm91cEJ5RmFjdG9yeShpdGVyYWJsZSwgZ3JvdXBlciwgY29udGV4dCkge1xuICAgIHZhciBpc0tleWVkSXRlciA9IGlzS2V5ZWQoaXRlcmFibGUpO1xuICAgIHZhciBncm91cHMgPSAoaXNPcmRlcmVkKGl0ZXJhYmxlKSA/IE9yZGVyZWRNYXAoKSA6IE1hcCgpKS5hc011dGFibGUoKTtcbiAgICBpdGVyYWJsZS5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaykgIHtcbiAgICAgIGdyb3Vwcy51cGRhdGUoXG4gICAgICAgIGdyb3VwZXIuY2FsbChjb250ZXh0LCB2LCBrLCBpdGVyYWJsZSksXG4gICAgICAgIGZ1bmN0aW9uKGEgKSB7cmV0dXJuIChhID0gYSB8fCBbXSwgYS5wdXNoKGlzS2V5ZWRJdGVyID8gW2ssIHZdIDogdiksIGEpfVxuICAgICAgKTtcbiAgICB9KTtcbiAgICB2YXIgY29lcmNlID0gaXRlcmFibGVDbGFzcyhpdGVyYWJsZSk7XG4gICAgcmV0dXJuIGdyb3Vwcy5tYXAoZnVuY3Rpb24oYXJyICkge3JldHVybiByZWlmeShpdGVyYWJsZSwgY29lcmNlKGFycikpfSk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHNsaWNlRmFjdG9yeShpdGVyYWJsZSwgYmVnaW4sIGVuZCwgdXNlS2V5cykge1xuICAgIHZhciBvcmlnaW5hbFNpemUgPSBpdGVyYWJsZS5zaXplO1xuXG4gICAgLy8gU2FuaXRpemUgYmVnaW4gJiBlbmQgdXNpbmcgdGhpcyBzaG9ydGhhbmQgZm9yIFRvSW50MzIoYXJndW1lbnQpXG4gICAgLy8gaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvaW50MzJcbiAgICBpZiAoYmVnaW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgYmVnaW4gPSBiZWdpbiB8IDA7XG4gICAgfVxuICAgIGlmIChlbmQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGVuZCA9PT0gSW5maW5pdHkpIHtcbiAgICAgICAgZW5kID0gb3JpZ2luYWxTaXplO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZW5kID0gZW5kIHwgMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAod2hvbGVTbGljZShiZWdpbiwgZW5kLCBvcmlnaW5hbFNpemUpKSB7XG4gICAgICByZXR1cm4gaXRlcmFibGU7XG4gICAgfVxuXG4gICAgdmFyIHJlc29sdmVkQmVnaW4gPSByZXNvbHZlQmVnaW4oYmVnaW4sIG9yaWdpbmFsU2l6ZSk7XG4gICAgdmFyIHJlc29sdmVkRW5kID0gcmVzb2x2ZUVuZChlbmQsIG9yaWdpbmFsU2l6ZSk7XG5cbiAgICAvLyBiZWdpbiBvciBlbmQgd2lsbCBiZSBOYU4gaWYgdGhleSB3ZXJlIHByb3ZpZGVkIGFzIG5lZ2F0aXZlIG51bWJlcnMgYW5kXG4gICAgLy8gdGhpcyBpdGVyYWJsZSdzIHNpemUgaXMgdW5rbm93bi4gSW4gdGhhdCBjYXNlLCBjYWNoZSBmaXJzdCBzbyB0aGVyZSBpc1xuICAgIC8vIGEga25vd24gc2l6ZSBhbmQgdGhlc2UgZG8gbm90IHJlc29sdmUgdG8gTmFOLlxuICAgIGlmIChyZXNvbHZlZEJlZ2luICE9PSByZXNvbHZlZEJlZ2luIHx8IHJlc29sdmVkRW5kICE9PSByZXNvbHZlZEVuZCkge1xuICAgICAgcmV0dXJuIHNsaWNlRmFjdG9yeShpdGVyYWJsZS50b1NlcSgpLmNhY2hlUmVzdWx0KCksIGJlZ2luLCBlbmQsIHVzZUtleXMpO1xuICAgIH1cblxuICAgIC8vIE5vdGU6IHJlc29sdmVkRW5kIGlzIHVuZGVmaW5lZCB3aGVuIHRoZSBvcmlnaW5hbCBzZXF1ZW5jZSdzIGxlbmd0aCBpc1xuICAgIC8vIHVua25vd24gYW5kIHRoaXMgc2xpY2UgZGlkIG5vdCBzdXBwbHkgYW4gZW5kIGFuZCBzaG91bGQgY29udGFpbiBhbGxcbiAgICAvLyBlbGVtZW50cyBhZnRlciByZXNvbHZlZEJlZ2luLlxuICAgIC8vIEluIHRoYXQgY2FzZSwgcmVzb2x2ZWRTaXplIHdpbGwgYmUgTmFOIGFuZCBzbGljZVNpemUgd2lsbCByZW1haW4gdW5kZWZpbmVkLlxuICAgIHZhciByZXNvbHZlZFNpemUgPSByZXNvbHZlZEVuZCAtIHJlc29sdmVkQmVnaW47XG4gICAgdmFyIHNsaWNlU2l6ZTtcbiAgICBpZiAocmVzb2x2ZWRTaXplID09PSByZXNvbHZlZFNpemUpIHtcbiAgICAgIHNsaWNlU2l6ZSA9IHJlc29sdmVkU2l6ZSA8IDAgPyAwIDogcmVzb2x2ZWRTaXplO1xuICAgIH1cblxuICAgIHZhciBzbGljZVNlcSA9IG1ha2VTZXF1ZW5jZShpdGVyYWJsZSk7XG5cbiAgICAvLyBJZiBpdGVyYWJsZS5zaXplIGlzIHVuZGVmaW5lZCwgdGhlIHNpemUgb2YgdGhlIHJlYWxpemVkIHNsaWNlU2VxIGlzXG4gICAgLy8gdW5rbm93biBhdCB0aGlzIHBvaW50IHVubGVzcyB0aGUgbnVtYmVyIG9mIGl0ZW1zIHRvIHNsaWNlIGlzIDBcbiAgICBzbGljZVNlcS5zaXplID0gc2xpY2VTaXplID09PSAwID8gc2xpY2VTaXplIDogaXRlcmFibGUuc2l6ZSAmJiBzbGljZVNpemUgfHwgdW5kZWZpbmVkO1xuXG4gICAgaWYgKCF1c2VLZXlzICYmIGlzU2VxKGl0ZXJhYmxlKSAmJiBzbGljZVNpemUgPj0gMCkge1xuICAgICAgc2xpY2VTZXEuZ2V0ID0gZnVuY3Rpb24gKGluZGV4LCBub3RTZXRWYWx1ZSkge1xuICAgICAgICBpbmRleCA9IHdyYXBJbmRleCh0aGlzLCBpbmRleCk7XG4gICAgICAgIHJldHVybiBpbmRleCA+PSAwICYmIGluZGV4IDwgc2xpY2VTaXplID9cbiAgICAgICAgICBpdGVyYWJsZS5nZXQoaW5kZXggKyByZXNvbHZlZEJlZ2luLCBub3RTZXRWYWx1ZSkgOlxuICAgICAgICAgIG5vdFNldFZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHNsaWNlU2VxLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIGlmIChzbGljZVNpemUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0ZShmbiwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgc2tpcHBlZCA9IDA7XG4gICAgICB2YXIgaXNTa2lwcGluZyA9IHRydWU7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICBpdGVyYWJsZS5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaykgIHtcbiAgICAgICAgaWYgKCEoaXNTa2lwcGluZyAmJiAoaXNTa2lwcGluZyA9IHNraXBwZWQrKyA8IHJlc29sdmVkQmVnaW4pKSkge1xuICAgICAgICAgIGl0ZXJhdGlvbnMrKztcbiAgICAgICAgICByZXR1cm4gZm4odiwgdXNlS2V5cyA/IGsgOiBpdGVyYXRpb25zIC0gMSwgdGhpcyQwKSAhPT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAgaXRlcmF0aW9ucyAhPT0gc2xpY2VTaXplO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH07XG5cbiAgICBzbGljZVNlcS5fX2l0ZXJhdG9yVW5jYWNoZWQgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICBpZiAoc2xpY2VTaXplICE9PSAwICYmIHJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGVSZXN1bHQoKS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgICAgfVxuICAgICAgLy8gRG9uJ3QgYm90aGVyIGluc3RhbnRpYXRpbmcgcGFyZW50IGl0ZXJhdG9yIGlmIHRha2luZyAwLlxuICAgICAgdmFyIGl0ZXJhdG9yID0gc2xpY2VTaXplICE9PSAwICYmIGl0ZXJhYmxlLl9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgICB2YXIgc2tpcHBlZCA9IDA7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgd2hpbGUgKHNraXBwZWQrKyA8IHJlc29sdmVkQmVnaW4pIHtcbiAgICAgICAgICBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCsraXRlcmF0aW9ucyA+IHNsaWNlU2l6ZSkge1xuICAgICAgICAgIHJldHVybiBpdGVyYXRvckRvbmUoKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKHVzZUtleXMgfHwgdHlwZSA9PT0gSVRFUkFURV9WQUxVRVMpIHtcbiAgICAgICAgICByZXR1cm4gc3RlcDtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBJVEVSQVRFX0tFWVMpIHtcbiAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zIC0gMSwgdW5kZWZpbmVkLCBzdGVwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zIC0gMSwgc3RlcC52YWx1ZVsxXSwgc3RlcCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBzbGljZVNlcTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gdGFrZVdoaWxlRmFjdG9yeShpdGVyYWJsZSwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgdmFyIHRha2VTZXF1ZW5jZSA9IG1ha2VTZXF1ZW5jZShpdGVyYWJsZSk7XG4gICAgdGFrZVNlcXVlbmNlLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlUmVzdWx0KCkuX19pdGVyYXRlKGZuLCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIGl0ZXJhYmxlLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrLCBjKSBcbiAgICAgICAge3JldHVybiBwcmVkaWNhdGUuY2FsbChjb250ZXh0LCB2LCBrLCBjKSAmJiArK2l0ZXJhdGlvbnMgJiYgZm4odiwgaywgdGhpcyQwKX1cbiAgICAgICk7XG4gICAgICByZXR1cm4gaXRlcmF0aW9ucztcbiAgICB9O1xuICAgIHRha2VTZXF1ZW5jZS5fX2l0ZXJhdG9yVW5jYWNoZWQgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYWJsZS5fX2l0ZXJhdG9yKElURVJBVEVfRU5UUklFUywgcmV2ZXJzZSk7XG4gICAgICB2YXIgaXRlcmF0aW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICBpZiAoIWl0ZXJhdGluZykge1xuICAgICAgICAgIHJldHVybiBpdGVyYXRvckRvbmUoKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKHN0ZXAuZG9uZSkge1xuICAgICAgICAgIHJldHVybiBzdGVwO1xuICAgICAgICB9XG4gICAgICAgIHZhciBlbnRyeSA9IHN0ZXAudmFsdWU7XG4gICAgICAgIHZhciBrID0gZW50cnlbMF07XG4gICAgICAgIHZhciB2ID0gZW50cnlbMV07XG4gICAgICAgIGlmICghcHJlZGljYXRlLmNhbGwoY29udGV4dCwgdiwgaywgdGhpcyQwKSkge1xuICAgICAgICAgIGl0ZXJhdGluZyA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiBpdGVyYXRvckRvbmUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZSA9PT0gSVRFUkFURV9FTlRSSUVTID8gc3RlcCA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCBrLCB2LCBzdGVwKTtcbiAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIHRha2VTZXF1ZW5jZTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gc2tpcFdoaWxlRmFjdG9yeShpdGVyYWJsZSwgcHJlZGljYXRlLCBjb250ZXh0LCB1c2VLZXlzKSB7XG4gICAgdmFyIHNraXBTZXF1ZW5jZSA9IG1ha2VTZXF1ZW5jZShpdGVyYWJsZSk7XG4gICAgc2tpcFNlcXVlbmNlLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24gKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0ZShmbiwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXNTa2lwcGluZyA9IHRydWU7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICBpdGVyYWJsZS5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaywgYykgIHtcbiAgICAgICAgaWYgKCEoaXNTa2lwcGluZyAmJiAoaXNTa2lwcGluZyA9IHByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHYsIGssIGMpKSkpIHtcbiAgICAgICAgICBpdGVyYXRpb25zKys7XG4gICAgICAgICAgcmV0dXJuIGZuKHYsIHVzZUtleXMgPyBrIDogaXRlcmF0aW9ucyAtIDEsIHRoaXMkMCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgfTtcbiAgICBza2lwU2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGVSZXN1bHQoKS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmFibGUuX19pdGVyYXRvcihJVEVSQVRFX0VOVFJJRVMsIHJldmVyc2UpO1xuICAgICAgdmFyIHNraXBwaW5nID0gdHJ1ZTtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICB2YXIgc3RlcCwgaywgdjtcbiAgICAgICAgZG8ge1xuICAgICAgICAgIHN0ZXAgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgICAgaWYgKHN0ZXAuZG9uZSkge1xuICAgICAgICAgICAgaWYgKHVzZUtleXMgfHwgdHlwZSA9PT0gSVRFUkFURV9WQUxVRVMpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHN0ZXA7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IElURVJBVEVfS0VZUykge1xuICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHVuZGVmaW5lZCwgc3RlcCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHN0ZXAudmFsdWVbMV0sIHN0ZXApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgZW50cnkgPSBzdGVwLnZhbHVlO1xuICAgICAgICAgIGsgPSBlbnRyeVswXTtcbiAgICAgICAgICB2ID0gZW50cnlbMV07XG4gICAgICAgICAgc2tpcHBpbmcgJiYgKHNraXBwaW5nID0gcHJlZGljYXRlLmNhbGwoY29udGV4dCwgdiwgaywgdGhpcyQwKSk7XG4gICAgICAgIH0gd2hpbGUgKHNraXBwaW5nKTtcbiAgICAgICAgcmV0dXJuIHR5cGUgPT09IElURVJBVEVfRU5UUklFUyA/IHN0ZXAgOlxuICAgICAgICAgIGl0ZXJhdG9yVmFsdWUodHlwZSwgaywgdiwgc3RlcCk7XG4gICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBza2lwU2VxdWVuY2U7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIGNvbmNhdEZhY3RvcnkoaXRlcmFibGUsIHZhbHVlcykge1xuICAgIHZhciBpc0tleWVkSXRlcmFibGUgPSBpc0tleWVkKGl0ZXJhYmxlKTtcbiAgICB2YXIgaXRlcnMgPSBbaXRlcmFibGVdLmNvbmNhdCh2YWx1ZXMpLm1hcChmdW5jdGlvbih2ICkge1xuICAgICAgaWYgKCFpc0l0ZXJhYmxlKHYpKSB7XG4gICAgICAgIHYgPSBpc0tleWVkSXRlcmFibGUgP1xuICAgICAgICAgIGtleWVkU2VxRnJvbVZhbHVlKHYpIDpcbiAgICAgICAgICBpbmRleGVkU2VxRnJvbVZhbHVlKEFycmF5LmlzQXJyYXkodikgPyB2IDogW3ZdKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNLZXllZEl0ZXJhYmxlKSB7XG4gICAgICAgIHYgPSBLZXllZEl0ZXJhYmxlKHYpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHY7XG4gICAgfSkuZmlsdGVyKGZ1bmN0aW9uKHYgKSB7cmV0dXJuIHYuc2l6ZSAhPT0gMH0pO1xuXG4gICAgaWYgKGl0ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGl0ZXJhYmxlO1xuICAgIH1cblxuICAgIGlmIChpdGVycy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBzaW5nbGV0b24gPSBpdGVyc1swXTtcbiAgICAgIGlmIChzaW5nbGV0b24gPT09IGl0ZXJhYmxlIHx8XG4gICAgICAgICAgaXNLZXllZEl0ZXJhYmxlICYmIGlzS2V5ZWQoc2luZ2xldG9uKSB8fFxuICAgICAgICAgIGlzSW5kZXhlZChpdGVyYWJsZSkgJiYgaXNJbmRleGVkKHNpbmdsZXRvbikpIHtcbiAgICAgICAgcmV0dXJuIHNpbmdsZXRvbjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgY29uY2F0U2VxID0gbmV3IEFycmF5U2VxKGl0ZXJzKTtcbiAgICBpZiAoaXNLZXllZEl0ZXJhYmxlKSB7XG4gICAgICBjb25jYXRTZXEgPSBjb25jYXRTZXEudG9LZXllZFNlcSgpO1xuICAgIH0gZWxzZSBpZiAoIWlzSW5kZXhlZChpdGVyYWJsZSkpIHtcbiAgICAgIGNvbmNhdFNlcSA9IGNvbmNhdFNlcS50b1NldFNlcSgpO1xuICAgIH1cbiAgICBjb25jYXRTZXEgPSBjb25jYXRTZXEuZmxhdHRlbih0cnVlKTtcbiAgICBjb25jYXRTZXEuc2l6ZSA9IGl0ZXJzLnJlZHVjZShcbiAgICAgIGZ1bmN0aW9uKHN1bSwgc2VxKSAge1xuICAgICAgICBpZiAoc3VtICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB2YXIgc2l6ZSA9IHNlcS5zaXplO1xuICAgICAgICAgIGlmIChzaXplICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBzdW0gKyBzaXplO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIDBcbiAgICApO1xuICAgIHJldHVybiBjb25jYXRTZXE7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIGZsYXR0ZW5GYWN0b3J5KGl0ZXJhYmxlLCBkZXB0aCwgdXNlS2V5cykge1xuICAgIHZhciBmbGF0U2VxdWVuY2UgPSBtYWtlU2VxdWVuY2UoaXRlcmFibGUpO1xuICAgIGZsYXRTZXF1ZW5jZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICB2YXIgc3RvcHBlZCA9IGZhbHNlO1xuICAgICAgZnVuY3Rpb24gZmxhdERlZXAoaXRlciwgY3VycmVudERlcHRoKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICAgIGl0ZXIuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGspICB7XG4gICAgICAgICAgaWYgKCghZGVwdGggfHwgY3VycmVudERlcHRoIDwgZGVwdGgpICYmIGlzSXRlcmFibGUodikpIHtcbiAgICAgICAgICAgIGZsYXREZWVwKHYsIGN1cnJlbnREZXB0aCArIDEpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZm4odiwgdXNlS2V5cyA/IGsgOiBpdGVyYXRpb25zKyssIHRoaXMkMCkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBzdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuICFzdG9wcGVkO1xuICAgICAgICB9LCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIGZsYXREZWVwKGl0ZXJhYmxlLCAwKTtcbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH1cbiAgICBmbGF0U2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmFibGUuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICAgIHZhciBzdGFjayA9IFtdO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHdoaWxlIChpdGVyYXRvcikge1xuICAgICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgIGlmIChzdGVwLmRvbmUgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICBpdGVyYXRvciA9IHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciB2ID0gc3RlcC52YWx1ZTtcbiAgICAgICAgICBpZiAodHlwZSA9PT0gSVRFUkFURV9FTlRSSUVTKSB7XG4gICAgICAgICAgICB2ID0gdlsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCghZGVwdGggfHwgc3RhY2subGVuZ3RoIDwgZGVwdGgpICYmIGlzSXRlcmFibGUodikpIHtcbiAgICAgICAgICAgIHN0YWNrLnB1c2goaXRlcmF0b3IpO1xuICAgICAgICAgICAgaXRlcmF0b3IgPSB2Ll9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1c2VLZXlzID8gc3RlcCA6IGl0ZXJhdG9yVmFsdWUodHlwZSwgaXRlcmF0aW9ucysrLCB2LCBzdGVwKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yRG9uZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBmbGF0U2VxdWVuY2U7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIGZsYXRNYXBGYWN0b3J5KGl0ZXJhYmxlLCBtYXBwZXIsIGNvbnRleHQpIHtcbiAgICB2YXIgY29lcmNlID0gaXRlcmFibGVDbGFzcyhpdGVyYWJsZSk7XG4gICAgcmV0dXJuIGl0ZXJhYmxlLnRvU2VxKCkubWFwKFxuICAgICAgZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gY29lcmNlKG1hcHBlci5jYWxsKGNvbnRleHQsIHYsIGssIGl0ZXJhYmxlKSl9XG4gICAgKS5mbGF0dGVuKHRydWUpO1xuICB9XG5cblxuICBmdW5jdGlvbiBpbnRlcnBvc2VGYWN0b3J5KGl0ZXJhYmxlLCBzZXBhcmF0b3IpIHtcbiAgICB2YXIgaW50ZXJwb3NlZFNlcXVlbmNlID0gbWFrZVNlcXVlbmNlKGl0ZXJhYmxlKTtcbiAgICBpbnRlcnBvc2VkU2VxdWVuY2Uuc2l6ZSA9IGl0ZXJhYmxlLnNpemUgJiYgaXRlcmFibGUuc2l6ZSAqIDIgLTE7XG4gICAgaW50ZXJwb3NlZFNlcXVlbmNlLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIGl0ZXJhYmxlLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrKSBcbiAgICAgICAge3JldHVybiAoIWl0ZXJhdGlvbnMgfHwgZm4oc2VwYXJhdG9yLCBpdGVyYXRpb25zKyssIHRoaXMkMCkgIT09IGZhbHNlKSAmJlxuICAgICAgICBmbih2LCBpdGVyYXRpb25zKyssIHRoaXMkMCkgIT09IGZhbHNlfSxcbiAgICAgICAgcmV2ZXJzZVxuICAgICAgKTtcbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH07XG4gICAgaW50ZXJwb3NlZFNlcXVlbmNlLl9faXRlcmF0b3JVbmNhY2hlZCA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHZhciBpdGVyYXRvciA9IGl0ZXJhYmxlLl9faXRlcmF0b3IoSVRFUkFURV9WQUxVRVMsIHJldmVyc2UpO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgdmFyIHN0ZXA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgaWYgKCFzdGVwIHx8IGl0ZXJhdGlvbnMgJSAyKSB7XG4gICAgICAgICAgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICBpZiAoc3RlcC5kb25lKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RlcDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZXJhdGlvbnMgJSAyID9cbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIGl0ZXJhdGlvbnMrKywgc2VwYXJhdG9yKSA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHN0ZXAudmFsdWUsIHN0ZXApO1xuICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gaW50ZXJwb3NlZFNlcXVlbmNlO1xuICB9XG5cblxuICBmdW5jdGlvbiBzb3J0RmFjdG9yeShpdGVyYWJsZSwgY29tcGFyYXRvciwgbWFwcGVyKSB7XG4gICAgaWYgKCFjb21wYXJhdG9yKSB7XG4gICAgICBjb21wYXJhdG9yID0gZGVmYXVsdENvbXBhcmF0b3I7XG4gICAgfVxuICAgIHZhciBpc0tleWVkSXRlcmFibGUgPSBpc0tleWVkKGl0ZXJhYmxlKTtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBlbnRyaWVzID0gaXRlcmFibGUudG9TZXEoKS5tYXAoXG4gICAgICBmdW5jdGlvbih2LCBrKSAge3JldHVybiBbaywgdiwgaW5kZXgrKywgbWFwcGVyID8gbWFwcGVyKHYsIGssIGl0ZXJhYmxlKSA6IHZdfVxuICAgICkudG9BcnJheSgpO1xuICAgIGVudHJpZXMuc29ydChmdW5jdGlvbihhLCBiKSAge3JldHVybiBjb21wYXJhdG9yKGFbM10sIGJbM10pIHx8IGFbMl0gLSBiWzJdfSkuZm9yRWFjaChcbiAgICAgIGlzS2V5ZWRJdGVyYWJsZSA/XG4gICAgICBmdW5jdGlvbih2LCBpKSAgeyBlbnRyaWVzW2ldLmxlbmd0aCA9IDI7IH0gOlxuICAgICAgZnVuY3Rpb24odiwgaSkgIHsgZW50cmllc1tpXSA9IHZbMV07IH1cbiAgICApO1xuICAgIHJldHVybiBpc0tleWVkSXRlcmFibGUgPyBLZXllZFNlcShlbnRyaWVzKSA6XG4gICAgICBpc0luZGV4ZWQoaXRlcmFibGUpID8gSW5kZXhlZFNlcShlbnRyaWVzKSA6XG4gICAgICBTZXRTZXEoZW50cmllcyk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIG1heEZhY3RvcnkoaXRlcmFibGUsIGNvbXBhcmF0b3IsIG1hcHBlcikge1xuICAgIGlmICghY29tcGFyYXRvcikge1xuICAgICAgY29tcGFyYXRvciA9IGRlZmF1bHRDb21wYXJhdG9yO1xuICAgIH1cbiAgICBpZiAobWFwcGVyKSB7XG4gICAgICB2YXIgZW50cnkgPSBpdGVyYWJsZS50b1NlcSgpXG4gICAgICAgIC5tYXAoZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gW3YsIG1hcHBlcih2LCBrLCBpdGVyYWJsZSldfSlcbiAgICAgICAgLnJlZHVjZShmdW5jdGlvbihhLCBiKSAge3JldHVybiBtYXhDb21wYXJlKGNvbXBhcmF0b3IsIGFbMV0sIGJbMV0pID8gYiA6IGF9KTtcbiAgICAgIHJldHVybiBlbnRyeSAmJiBlbnRyeVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGl0ZXJhYmxlLnJlZHVjZShmdW5jdGlvbihhLCBiKSAge3JldHVybiBtYXhDb21wYXJlKGNvbXBhcmF0b3IsIGEsIGIpID8gYiA6IGF9KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBtYXhDb21wYXJlKGNvbXBhcmF0b3IsIGEsIGIpIHtcbiAgICB2YXIgY29tcCA9IGNvbXBhcmF0b3IoYiwgYSk7XG4gICAgLy8gYiBpcyBjb25zaWRlcmVkIHRoZSBuZXcgbWF4IGlmIHRoZSBjb21wYXJhdG9yIGRlY2xhcmVzIHRoZW0gZXF1YWwsIGJ1dFxuICAgIC8vIHRoZXkgYXJlIG5vdCBlcXVhbCBhbmQgYiBpcyBpbiBmYWN0IGEgbnVsbGlzaCB2YWx1ZS5cbiAgICByZXR1cm4gKGNvbXAgPT09IDAgJiYgYiAhPT0gYSAmJiAoYiA9PT0gdW5kZWZpbmVkIHx8IGIgPT09IG51bGwgfHwgYiAhPT0gYikpIHx8IGNvbXAgPiAwO1xuICB9XG5cblxuICBmdW5jdGlvbiB6aXBXaXRoRmFjdG9yeShrZXlJdGVyLCB6aXBwZXIsIGl0ZXJzKSB7XG4gICAgdmFyIHppcFNlcXVlbmNlID0gbWFrZVNlcXVlbmNlKGtleUl0ZXIpO1xuICAgIHppcFNlcXVlbmNlLnNpemUgPSBuZXcgQXJyYXlTZXEoaXRlcnMpLm1hcChmdW5jdGlvbihpICkge3JldHVybiBpLnNpemV9KS5taW4oKTtcbiAgICAvLyBOb3RlOiB0aGlzIGEgZ2VuZXJpYyBiYXNlIGltcGxlbWVudGF0aW9uIG9mIF9faXRlcmF0ZSBpbiB0ZXJtcyBvZlxuICAgIC8vIF9faXRlcmF0b3Igd2hpY2ggbWF5IGJlIG1vcmUgZ2VuZXJpY2FsbHkgdXNlZnVsIGluIHRoZSBmdXR1cmUuXG4gICAgemlwU2VxdWVuY2UuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHtcbiAgICAgIC8qIGdlbmVyaWM6XG4gICAgICB2YXIgaXRlcmF0b3IgPSB0aGlzLl9faXRlcmF0b3IoSVRFUkFURV9FTlRSSUVTLCByZXZlcnNlKTtcbiAgICAgIHZhciBzdGVwO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgd2hpbGUgKCEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgICBpdGVyYXRpb25zKys7XG4gICAgICAgIGlmIChmbihzdGVwLnZhbHVlWzFdLCBzdGVwLnZhbHVlWzBdLCB0aGlzKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgICAqL1xuICAgICAgLy8gaW5kZXhlZDpcbiAgICAgIHZhciBpdGVyYXRvciA9IHRoaXMuX19pdGVyYXRvcihJVEVSQVRFX1ZBTFVFUywgcmV2ZXJzZSk7XG4gICAgICB2YXIgc3RlcDtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgaWYgKGZuKHN0ZXAudmFsdWUsIGl0ZXJhdGlvbnMrKywgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH07XG4gICAgemlwU2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGl0ZXJhdG9ycyA9IGl0ZXJzLm1hcChmdW5jdGlvbihpIClcbiAgICAgICAge3JldHVybiAoaSA9IEl0ZXJhYmxlKGkpLCBnZXRJdGVyYXRvcihyZXZlcnNlID8gaS5yZXZlcnNlKCkgOiBpKSl9XG4gICAgICApO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgdmFyIGlzRG9uZSA9IGZhbHNlO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBzdGVwcztcbiAgICAgICAgaWYgKCFpc0RvbmUpIHtcbiAgICAgICAgICBzdGVwcyA9IGl0ZXJhdG9ycy5tYXAoZnVuY3Rpb24oaSApIHtyZXR1cm4gaS5uZXh0KCl9KTtcbiAgICAgICAgICBpc0RvbmUgPSBzdGVwcy5zb21lKGZ1bmN0aW9uKHMgKSB7cmV0dXJuIHMuZG9uZX0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0RvbmUpIHtcbiAgICAgICAgICByZXR1cm4gaXRlcmF0b3JEb25lKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVmFsdWUoXG4gICAgICAgICAgdHlwZSxcbiAgICAgICAgICBpdGVyYXRpb25zKyssXG4gICAgICAgICAgemlwcGVyLmFwcGx5KG51bGwsIHN0ZXBzLm1hcChmdW5jdGlvbihzICkge3JldHVybiBzLnZhbHVlfSkpXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiB6aXBTZXF1ZW5jZVxuICB9XG5cblxuICAvLyAjcHJhZ21hIEhlbHBlciBGdW5jdGlvbnNcblxuICBmdW5jdGlvbiByZWlmeShpdGVyLCBzZXEpIHtcbiAgICByZXR1cm4gaXNTZXEoaXRlcikgPyBzZXEgOiBpdGVyLmNvbnN0cnVjdG9yKHNlcSk7XG4gIH1cblxuICBmdW5jdGlvbiB2YWxpZGF0ZUVudHJ5KGVudHJ5KSB7XG4gICAgaWYgKGVudHJ5ICE9PSBPYmplY3QoZW50cnkpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCBbSywgVl0gdHVwbGU6ICcgKyBlbnRyeSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVzb2x2ZVNpemUoaXRlcikge1xuICAgIGFzc2VydE5vdEluZmluaXRlKGl0ZXIuc2l6ZSk7XG4gICAgcmV0dXJuIGVuc3VyZVNpemUoaXRlcik7XG4gIH1cblxuICBmdW5jdGlvbiBpdGVyYWJsZUNsYXNzKGl0ZXJhYmxlKSB7XG4gICAgcmV0dXJuIGlzS2V5ZWQoaXRlcmFibGUpID8gS2V5ZWRJdGVyYWJsZSA6XG4gICAgICBpc0luZGV4ZWQoaXRlcmFibGUpID8gSW5kZXhlZEl0ZXJhYmxlIDpcbiAgICAgIFNldEl0ZXJhYmxlO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFrZVNlcXVlbmNlKGl0ZXJhYmxlKSB7XG4gICAgcmV0dXJuIE9iamVjdC5jcmVhdGUoXG4gICAgICAoXG4gICAgICAgIGlzS2V5ZWQoaXRlcmFibGUpID8gS2V5ZWRTZXEgOlxuICAgICAgICBpc0luZGV4ZWQoaXRlcmFibGUpID8gSW5kZXhlZFNlcSA6XG4gICAgICAgIFNldFNlcVxuICAgICAgKS5wcm90b3R5cGVcbiAgICApO1xuICB9XG5cbiAgZnVuY3Rpb24gY2FjaGVSZXN1bHRUaHJvdWdoKCkge1xuICAgIGlmICh0aGlzLl9pdGVyLmNhY2hlUmVzdWx0KSB7XG4gICAgICB0aGlzLl9pdGVyLmNhY2hlUmVzdWx0KCk7XG4gICAgICB0aGlzLnNpemUgPSB0aGlzLl9pdGVyLnNpemU7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFNlcS5wcm90b3R5cGUuY2FjaGVSZXN1bHQuY2FsbCh0aGlzKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBkZWZhdWx0Q29tcGFyYXRvcihhLCBiKSB7XG4gICAgcmV0dXJuIGEgPiBiID8gMSA6IGEgPCBiID8gLTEgOiAwO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9yY2VJdGVyYXRvcihrZXlQYXRoKSB7XG4gICAgdmFyIGl0ZXIgPSBnZXRJdGVyYXRvcihrZXlQYXRoKTtcbiAgICBpZiAoIWl0ZXIpIHtcbiAgICAgIC8vIEFycmF5IG1pZ2h0IG5vdCBiZSBpdGVyYWJsZSBpbiB0aGlzIGVudmlyb25tZW50LCBzbyB3ZSBuZWVkIGEgZmFsbGJhY2tcbiAgICAgIC8vIHRvIG91ciB3cmFwcGVkIHR5cGUuXG4gICAgICBpZiAoIWlzQXJyYXlMaWtlKGtleVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0V4cGVjdGVkIGl0ZXJhYmxlIG9yIGFycmF5LWxpa2U6ICcgKyBrZXlQYXRoKTtcbiAgICAgIH1cbiAgICAgIGl0ZXIgPSBnZXRJdGVyYXRvcihJdGVyYWJsZShrZXlQYXRoKSk7XG4gICAgfVxuICAgIHJldHVybiBpdGVyO1xuICB9XG5cbiAgY3JlYXRlQ2xhc3MoUmVjb3JkLCBLZXllZENvbGxlY3Rpb24pO1xuXG4gICAgZnVuY3Rpb24gUmVjb3JkKGRlZmF1bHRWYWx1ZXMsIG5hbWUpIHtcbiAgICAgIHZhciBoYXNJbml0aWFsaXplZDtcblxuICAgICAgdmFyIFJlY29yZFR5cGUgPSBmdW5jdGlvbiBSZWNvcmQodmFsdWVzKSB7XG4gICAgICAgIGlmICh2YWx1ZXMgaW5zdGFuY2VvZiBSZWNvcmRUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICAgICAgfVxuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVjb3JkVHlwZSkpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFJlY29yZFR5cGUodmFsdWVzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWhhc0luaXRpYWxpemVkKSB7XG4gICAgICAgICAgaGFzSW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoZGVmYXVsdFZhbHVlcyk7XG4gICAgICAgICAgc2V0UHJvcHMoUmVjb3JkVHlwZVByb3RvdHlwZSwga2V5cyk7XG4gICAgICAgICAgUmVjb3JkVHlwZVByb3RvdHlwZS5zaXplID0ga2V5cy5sZW5ndGg7XG4gICAgICAgICAgUmVjb3JkVHlwZVByb3RvdHlwZS5fbmFtZSA9IG5hbWU7XG4gICAgICAgICAgUmVjb3JkVHlwZVByb3RvdHlwZS5fa2V5cyA9IGtleXM7XG4gICAgICAgICAgUmVjb3JkVHlwZVByb3RvdHlwZS5fZGVmYXVsdFZhbHVlcyA9IGRlZmF1bHRWYWx1ZXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbWFwID0gTWFwKHZhbHVlcyk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgUmVjb3JkVHlwZVByb3RvdHlwZSA9IFJlY29yZFR5cGUucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShSZWNvcmRQcm90b3R5cGUpO1xuICAgICAgUmVjb3JkVHlwZVByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFJlY29yZFR5cGU7XG5cbiAgICAgIHJldHVybiBSZWNvcmRUeXBlO1xuICAgIH1cblxuICAgIFJlY29yZC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fdG9TdHJpbmcocmVjb3JkTmFtZSh0aGlzKSArICcgeycsICd9Jyk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgQWNjZXNzXG5cbiAgICBSZWNvcmQucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uKGspIHtcbiAgICAgIHJldHVybiB0aGlzLl9kZWZhdWx0VmFsdWVzLmhhc093blByb3BlcnR5KGspO1xuICAgIH07XG5cbiAgICBSZWNvcmQucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGssIG5vdFNldFZhbHVlKSB7XG4gICAgICBpZiAoIXRoaXMuaGFzKGspKSB7XG4gICAgICAgIHJldHVybiBub3RTZXRWYWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBkZWZhdWx0VmFsID0gdGhpcy5fZGVmYXVsdFZhbHVlc1trXTtcbiAgICAgIHJldHVybiB0aGlzLl9tYXAgPyB0aGlzLl9tYXAuZ2V0KGssIGRlZmF1bHRWYWwpIDogZGVmYXVsdFZhbDtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBNb2RpZmljYXRpb25cblxuICAgIFJlY29yZC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICB0aGlzLl9tYXAgJiYgdGhpcy5fbWFwLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIFJlY29yZFR5cGUgPSB0aGlzLmNvbnN0cnVjdG9yO1xuICAgICAgcmV0dXJuIFJlY29yZFR5cGUuX2VtcHR5IHx8IChSZWNvcmRUeXBlLl9lbXB0eSA9IG1ha2VSZWNvcmQodGhpcywgZW1wdHlNYXAoKSkpO1xuICAgIH07XG5cbiAgICBSZWNvcmQucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKGssIHYpIHtcbiAgICAgIGlmICghdGhpcy5oYXMoaykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3Qgc2V0IHVua25vd24ga2V5IFwiJyArIGsgKyAnXCIgb24gJyArIHJlY29yZE5hbWUodGhpcykpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX21hcCAmJiAhdGhpcy5fbWFwLmhhcyhrKSkge1xuICAgICAgICB2YXIgZGVmYXVsdFZhbCA9IHRoaXMuX2RlZmF1bHRWYWx1ZXNba107XG4gICAgICAgIGlmICh2ID09PSBkZWZhdWx0VmFsKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciBuZXdNYXAgPSB0aGlzLl9tYXAgJiYgdGhpcy5fbWFwLnNldChrLCB2KTtcbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCB8fCBuZXdNYXAgPT09IHRoaXMuX21hcCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYWtlUmVjb3JkKHRoaXMsIG5ld01hcCk7XG4gICAgfTtcblxuICAgIFJlY29yZC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oaykge1xuICAgICAgaWYgKCF0aGlzLmhhcyhrKSkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHZhciBuZXdNYXAgPSB0aGlzLl9tYXAgJiYgdGhpcy5fbWFwLnJlbW92ZShrKTtcbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCB8fCBuZXdNYXAgPT09IHRoaXMuX21hcCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYWtlUmVjb3JkKHRoaXMsIG5ld01hcCk7XG4gICAgfTtcblxuICAgIFJlY29yZC5wcm90b3R5cGUud2FzQWx0ZXJlZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX21hcC53YXNBbHRlcmVkKCk7XG4gICAgfTtcblxuICAgIFJlY29yZC5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHJldHVybiBLZXllZEl0ZXJhYmxlKHRoaXMuX2RlZmF1bHRWYWx1ZXMpLm1hcChmdW5jdGlvbihfLCBrKSAge3JldHVybiB0aGlzJDAuZ2V0KGspfSkuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICB9O1xuXG4gICAgUmVjb3JkLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIEtleWVkSXRlcmFibGUodGhpcy5fZGVmYXVsdFZhbHVlcykubWFwKGZ1bmN0aW9uKF8sIGspICB7cmV0dXJuIHRoaXMkMC5nZXQoayl9KS5fX2l0ZXJhdGUoZm4sIHJldmVyc2UpO1xuICAgIH07XG5cbiAgICBSZWNvcmQucHJvdG90eXBlLl9fZW5zdXJlT3duZXIgPSBmdW5jdGlvbihvd25lcklEKSB7XG4gICAgICBpZiAob3duZXJJRCA9PT0gdGhpcy5fX293bmVySUQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICB2YXIgbmV3TWFwID0gdGhpcy5fbWFwICYmIHRoaXMuX21hcC5fX2Vuc3VyZU93bmVyKG93bmVySUQpO1xuICAgICAgaWYgKCFvd25lcklEKSB7XG4gICAgICAgIHRoaXMuX19vd25lcklEID0gb3duZXJJRDtcbiAgICAgICAgdGhpcy5fbWFwID0gbmV3TWFwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYWtlUmVjb3JkKHRoaXMsIG5ld01hcCwgb3duZXJJRCk7XG4gICAgfTtcblxuXG4gIHZhciBSZWNvcmRQcm90b3R5cGUgPSBSZWNvcmQucHJvdG90eXBlO1xuICBSZWNvcmRQcm90b3R5cGVbREVMRVRFXSA9IFJlY29yZFByb3RvdHlwZS5yZW1vdmU7XG4gIFJlY29yZFByb3RvdHlwZS5kZWxldGVJbiA9XG4gIFJlY29yZFByb3RvdHlwZS5yZW1vdmVJbiA9IE1hcFByb3RvdHlwZS5yZW1vdmVJbjtcbiAgUmVjb3JkUHJvdG90eXBlLm1lcmdlID0gTWFwUHJvdG90eXBlLm1lcmdlO1xuICBSZWNvcmRQcm90b3R5cGUubWVyZ2VXaXRoID0gTWFwUHJvdG90eXBlLm1lcmdlV2l0aDtcbiAgUmVjb3JkUHJvdG90eXBlLm1lcmdlSW4gPSBNYXBQcm90b3R5cGUubWVyZ2VJbjtcbiAgUmVjb3JkUHJvdG90eXBlLm1lcmdlRGVlcCA9IE1hcFByb3RvdHlwZS5tZXJnZURlZXA7XG4gIFJlY29yZFByb3RvdHlwZS5tZXJnZURlZXBXaXRoID0gTWFwUHJvdG90eXBlLm1lcmdlRGVlcFdpdGg7XG4gIFJlY29yZFByb3RvdHlwZS5tZXJnZURlZXBJbiA9IE1hcFByb3RvdHlwZS5tZXJnZURlZXBJbjtcbiAgUmVjb3JkUHJvdG90eXBlLnNldEluID0gTWFwUHJvdG90eXBlLnNldEluO1xuICBSZWNvcmRQcm90b3R5cGUudXBkYXRlID0gTWFwUHJvdG90eXBlLnVwZGF0ZTtcbiAgUmVjb3JkUHJvdG90eXBlLnVwZGF0ZUluID0gTWFwUHJvdG90eXBlLnVwZGF0ZUluO1xuICBSZWNvcmRQcm90b3R5cGUud2l0aE11dGF0aW9ucyA9IE1hcFByb3RvdHlwZS53aXRoTXV0YXRpb25zO1xuICBSZWNvcmRQcm90b3R5cGUuYXNNdXRhYmxlID0gTWFwUHJvdG90eXBlLmFzTXV0YWJsZTtcbiAgUmVjb3JkUHJvdG90eXBlLmFzSW1tdXRhYmxlID0gTWFwUHJvdG90eXBlLmFzSW1tdXRhYmxlO1xuXG5cbiAgZnVuY3Rpb24gbWFrZVJlY29yZChsaWtlUmVjb3JkLCBtYXAsIG93bmVySUQpIHtcbiAgICB2YXIgcmVjb3JkID0gT2JqZWN0LmNyZWF0ZShPYmplY3QuZ2V0UHJvdG90eXBlT2YobGlrZVJlY29yZCkpO1xuICAgIHJlY29yZC5fbWFwID0gbWFwO1xuICAgIHJlY29yZC5fX293bmVySUQgPSBvd25lcklEO1xuICAgIHJldHVybiByZWNvcmQ7XG4gIH1cblxuICBmdW5jdGlvbiByZWNvcmROYW1lKHJlY29yZCkge1xuICAgIHJldHVybiByZWNvcmQuX25hbWUgfHwgcmVjb3JkLmNvbnN0cnVjdG9yLm5hbWUgfHwgJ1JlY29yZCc7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRQcm9wcyhwcm90b3R5cGUsIG5hbWVzKSB7XG4gICAgdHJ5IHtcbiAgICAgIG5hbWVzLmZvckVhY2goc2V0UHJvcC5iaW5kKHVuZGVmaW5lZCwgcHJvdG90eXBlKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSBmYWlsZWQuIFByb2JhYmx5IElFOC5cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzZXRQcm9wKHByb3RvdHlwZSwgbmFtZSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm90b3R5cGUsIG5hbWUsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldChuYW1lKTtcbiAgICAgIH0sXG4gICAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIGludmFyaWFudCh0aGlzLl9fb3duZXJJRCwgJ0Nhbm5vdCBzZXQgb24gYW4gaW1tdXRhYmxlIHJlY29yZC4nKTtcbiAgICAgICAgdGhpcy5zZXQobmFtZSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlQ2xhc3MoU2V0LCBTZXRDb2xsZWN0aW9uKTtcblxuICAgIC8vIEBwcmFnbWEgQ29uc3RydWN0aW9uXG5cbiAgICBmdW5jdGlvbiBTZXQodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gZW1wdHlTZXQoKSA6XG4gICAgICAgIGlzU2V0KHZhbHVlKSAmJiAhaXNPcmRlcmVkKHZhbHVlKSA/IHZhbHVlIDpcbiAgICAgICAgZW1wdHlTZXQoKS53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKHNldCApIHtcbiAgICAgICAgICB2YXIgaXRlciA9IFNldEl0ZXJhYmxlKHZhbHVlKTtcbiAgICAgICAgICBhc3NlcnROb3RJbmZpbml0ZShpdGVyLnNpemUpO1xuICAgICAgICAgIGl0ZXIuZm9yRWFjaChmdW5jdGlvbih2ICkge3JldHVybiBzZXQuYWRkKHYpfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIFNldC5vZiA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHJldHVybiB0aGlzKGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIFNldC5mcm9tS2V5cyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcyhLZXllZEl0ZXJhYmxlKHZhbHVlKS5rZXlTZXEoKSk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fdG9TdHJpbmcoJ1NldCB7JywgJ30nKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBBY2Nlc3NcblxuICAgIFNldC5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9tYXAuaGFzKHZhbHVlKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBNb2RpZmljYXRpb25cblxuICAgIFNldC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB1cGRhdGVTZXQodGhpcywgdGhpcy5fbWFwLnNldCh2YWx1ZSwgdHJ1ZSkpO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdXBkYXRlU2V0KHRoaXMsIHRoaXMuX21hcC5yZW1vdmUodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHVwZGF0ZVNldCh0aGlzLCB0aGlzLl9tYXAuY2xlYXIoKSk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgQ29tcG9zaXRpb25cblxuICAgIFNldC5wcm90b3R5cGUudW5pb24gPSBmdW5jdGlvbigpIHt2YXIgaXRlcnMgPSBTTElDRSQwLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgICAgIGl0ZXJzID0gaXRlcnMuZmlsdGVyKGZ1bmN0aW9uKHggKSB7cmV0dXJuIHguc2l6ZSAhPT0gMH0pO1xuICAgICAgaWYgKGl0ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnNpemUgPT09IDAgJiYgIXRoaXMuX19vd25lcklEICYmIGl0ZXJzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3RvcihpdGVyc1swXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKHNldCApIHtcbiAgICAgICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IGl0ZXJzLmxlbmd0aDsgaWkrKykge1xuICAgICAgICAgIFNldEl0ZXJhYmxlKGl0ZXJzW2lpXSkuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSApIHtyZXR1cm4gc2V0LmFkZCh2YWx1ZSl9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUuaW50ZXJzZWN0ID0gZnVuY3Rpb24oKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMCk7XG4gICAgICBpZiAoaXRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgaXRlcnMgPSBpdGVycy5tYXAoZnVuY3Rpb24oaXRlciApIHtyZXR1cm4gU2V0SXRlcmFibGUoaXRlcil9KTtcbiAgICAgIHZhciBvcmlnaW5hbFNldCA9IHRoaXM7XG4gICAgICByZXR1cm4gdGhpcy53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKHNldCApIHtcbiAgICAgICAgb3JpZ2luYWxTZXQuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSApIHtcbiAgICAgICAgICBpZiAoIWl0ZXJzLmV2ZXJ5KGZ1bmN0aW9uKGl0ZXIgKSB7cmV0dXJuIGl0ZXIuaW5jbHVkZXModmFsdWUpfSkpIHtcbiAgICAgICAgICAgIHNldC5yZW1vdmUodmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS5zdWJ0cmFjdCA9IGZ1bmN0aW9uKCkge3ZhciBpdGVycyA9IFNMSUNFJDAuY2FsbChhcmd1bWVudHMsIDApO1xuICAgICAgaWYgKGl0ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGl0ZXJzID0gaXRlcnMubWFwKGZ1bmN0aW9uKGl0ZXIgKSB7cmV0dXJuIFNldEl0ZXJhYmxlKGl0ZXIpfSk7XG4gICAgICB2YXIgb3JpZ2luYWxTZXQgPSB0aGlzO1xuICAgICAgcmV0dXJuIHRoaXMud2l0aE11dGF0aW9ucyhmdW5jdGlvbihzZXQgKSB7XG4gICAgICAgIG9yaWdpbmFsU2V0LmZvckVhY2goZnVuY3Rpb24odmFsdWUgKSB7XG4gICAgICAgICAgaWYgKGl0ZXJzLnNvbWUoZnVuY3Rpb24oaXRlciApIHtyZXR1cm4gaXRlci5pbmNsdWRlcyh2YWx1ZSl9KSkge1xuICAgICAgICAgICAgc2V0LnJlbW92ZSh2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLm1lcmdlID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy51bmlvbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLm1lcmdlV2l0aCA9IGZ1bmN0aW9uKG1lcmdlcikge3ZhciBpdGVycyA9IFNMSUNFJDAuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgcmV0dXJuIHRoaXMudW5pb24uYXBwbHkodGhpcywgaXRlcnMpO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLnNvcnQgPSBmdW5jdGlvbihjb21wYXJhdG9yKSB7XG4gICAgICAvLyBMYXRlIGJpbmRpbmdcbiAgICAgIHJldHVybiBPcmRlcmVkU2V0KHNvcnRGYWN0b3J5KHRoaXMsIGNvbXBhcmF0b3IpKTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS5zb3J0QnkgPSBmdW5jdGlvbihtYXBwZXIsIGNvbXBhcmF0b3IpIHtcbiAgICAgIC8vIExhdGUgYmluZGluZ1xuICAgICAgcmV0dXJuIE9yZGVyZWRTZXQoc29ydEZhY3RvcnkodGhpcywgY29tcGFyYXRvciwgbWFwcGVyKSk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUud2FzQWx0ZXJlZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX21hcC53YXNBbHRlcmVkKCk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHJldHVybiB0aGlzLl9tYXAuX19pdGVyYXRlKGZ1bmN0aW9uKF8sIGspICB7cmV0dXJuIGZuKGssIGssIHRoaXMkMCl9LCByZXZlcnNlKTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX21hcC5tYXAoZnVuY3Rpb24oXywgaykgIHtyZXR1cm4ga30pLl9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUuX19lbnN1cmVPd25lciA9IGZ1bmN0aW9uKG93bmVySUQpIHtcbiAgICAgIGlmIChvd25lcklEID09PSB0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHZhciBuZXdNYXAgPSB0aGlzLl9tYXAuX19lbnN1cmVPd25lcihvd25lcklEKTtcbiAgICAgIGlmICghb3duZXJJRCkge1xuICAgICAgICB0aGlzLl9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgICAgIHRoaXMuX21hcCA9IG5ld01hcDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5fX21ha2UobmV3TWFwLCBvd25lcklEKTtcbiAgICB9O1xuXG5cbiAgZnVuY3Rpb24gaXNTZXQobWF5YmVTZXQpIHtcbiAgICByZXR1cm4gISEobWF5YmVTZXQgJiYgbWF5YmVTZXRbSVNfU0VUX1NFTlRJTkVMXSk7XG4gIH1cblxuICBTZXQuaXNTZXQgPSBpc1NldDtcblxuICB2YXIgSVNfU0VUX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfU0VUX19AQCc7XG5cbiAgdmFyIFNldFByb3RvdHlwZSA9IFNldC5wcm90b3R5cGU7XG4gIFNldFByb3RvdHlwZVtJU19TRVRfU0VOVElORUxdID0gdHJ1ZTtcbiAgU2V0UHJvdG90eXBlW0RFTEVURV0gPSBTZXRQcm90b3R5cGUucmVtb3ZlO1xuICBTZXRQcm90b3R5cGUubWVyZ2VEZWVwID0gU2V0UHJvdG90eXBlLm1lcmdlO1xuICBTZXRQcm90b3R5cGUubWVyZ2VEZWVwV2l0aCA9IFNldFByb3RvdHlwZS5tZXJnZVdpdGg7XG4gIFNldFByb3RvdHlwZS53aXRoTXV0YXRpb25zID0gTWFwUHJvdG90eXBlLndpdGhNdXRhdGlvbnM7XG4gIFNldFByb3RvdHlwZS5hc011dGFibGUgPSBNYXBQcm90b3R5cGUuYXNNdXRhYmxlO1xuICBTZXRQcm90b3R5cGUuYXNJbW11dGFibGUgPSBNYXBQcm90b3R5cGUuYXNJbW11dGFibGU7XG5cbiAgU2V0UHJvdG90eXBlLl9fZW1wdHkgPSBlbXB0eVNldDtcbiAgU2V0UHJvdG90eXBlLl9fbWFrZSA9IG1ha2VTZXQ7XG5cbiAgZnVuY3Rpb24gdXBkYXRlU2V0KHNldCwgbmV3TWFwKSB7XG4gICAgaWYgKHNldC5fX293bmVySUQpIHtcbiAgICAgIHNldC5zaXplID0gbmV3TWFwLnNpemU7XG4gICAgICBzZXQuX21hcCA9IG5ld01hcDtcbiAgICAgIHJldHVybiBzZXQ7XG4gICAgfVxuICAgIHJldHVybiBuZXdNYXAgPT09IHNldC5fbWFwID8gc2V0IDpcbiAgICAgIG5ld01hcC5zaXplID09PSAwID8gc2V0Ll9fZW1wdHkoKSA6XG4gICAgICBzZXQuX19tYWtlKG5ld01hcCk7XG4gIH1cblxuICBmdW5jdGlvbiBtYWtlU2V0KG1hcCwgb3duZXJJRCkge1xuICAgIHZhciBzZXQgPSBPYmplY3QuY3JlYXRlKFNldFByb3RvdHlwZSk7XG4gICAgc2V0LnNpemUgPSBtYXAgPyBtYXAuc2l6ZSA6IDA7XG4gICAgc2V0Ll9tYXAgPSBtYXA7XG4gICAgc2V0Ll9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgcmV0dXJuIHNldDtcbiAgfVxuXG4gIHZhciBFTVBUWV9TRVQ7XG4gIGZ1bmN0aW9uIGVtcHR5U2V0KCkge1xuICAgIHJldHVybiBFTVBUWV9TRVQgfHwgKEVNUFRZX1NFVCA9IG1ha2VTZXQoZW1wdHlNYXAoKSkpO1xuICB9XG5cbiAgY3JlYXRlQ2xhc3MoT3JkZXJlZFNldCwgU2V0KTtcblxuICAgIC8vIEBwcmFnbWEgQ29uc3RydWN0aW9uXG5cbiAgICBmdW5jdGlvbiBPcmRlcmVkU2V0KHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCA/IGVtcHR5T3JkZXJlZFNldCgpIDpcbiAgICAgICAgaXNPcmRlcmVkU2V0KHZhbHVlKSA/IHZhbHVlIDpcbiAgICAgICAgZW1wdHlPcmRlcmVkU2V0KCkud2l0aE11dGF0aW9ucyhmdW5jdGlvbihzZXQgKSB7XG4gICAgICAgICAgdmFyIGl0ZXIgPSBTZXRJdGVyYWJsZSh2YWx1ZSk7XG4gICAgICAgICAgYXNzZXJ0Tm90SW5maW5pdGUoaXRlci5zaXplKTtcbiAgICAgICAgICBpdGVyLmZvckVhY2goZnVuY3Rpb24odiApIHtyZXR1cm4gc2V0LmFkZCh2KX0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBPcmRlcmVkU2V0Lm9mID0gZnVuY3Rpb24oLyouLi52YWx1ZXMqLykge1xuICAgICAgcmV0dXJuIHRoaXMoYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgT3JkZXJlZFNldC5mcm9tS2V5cyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcyhLZXllZEl0ZXJhYmxlKHZhbHVlKS5rZXlTZXEoKSk7XG4gICAgfTtcblxuICAgIE9yZGVyZWRTZXQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX3RvU3RyaW5nKCdPcmRlcmVkU2V0IHsnLCAnfScpO1xuICAgIH07XG5cblxuICBmdW5jdGlvbiBpc09yZGVyZWRTZXQobWF5YmVPcmRlcmVkU2V0KSB7XG4gICAgcmV0dXJuIGlzU2V0KG1heWJlT3JkZXJlZFNldCkgJiYgaXNPcmRlcmVkKG1heWJlT3JkZXJlZFNldCk7XG4gIH1cblxuICBPcmRlcmVkU2V0LmlzT3JkZXJlZFNldCA9IGlzT3JkZXJlZFNldDtcblxuICB2YXIgT3JkZXJlZFNldFByb3RvdHlwZSA9IE9yZGVyZWRTZXQucHJvdG90eXBlO1xuICBPcmRlcmVkU2V0UHJvdG90eXBlW0lTX09SREVSRURfU0VOVElORUxdID0gdHJ1ZTtcblxuICBPcmRlcmVkU2V0UHJvdG90eXBlLl9fZW1wdHkgPSBlbXB0eU9yZGVyZWRTZXQ7XG4gIE9yZGVyZWRTZXRQcm90b3R5cGUuX19tYWtlID0gbWFrZU9yZGVyZWRTZXQ7XG5cbiAgZnVuY3Rpb24gbWFrZU9yZGVyZWRTZXQobWFwLCBvd25lcklEKSB7XG4gICAgdmFyIHNldCA9IE9iamVjdC5jcmVhdGUoT3JkZXJlZFNldFByb3RvdHlwZSk7XG4gICAgc2V0LnNpemUgPSBtYXAgPyBtYXAuc2l6ZSA6IDA7XG4gICAgc2V0Ll9tYXAgPSBtYXA7XG4gICAgc2V0Ll9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgcmV0dXJuIHNldDtcbiAgfVxuXG4gIHZhciBFTVBUWV9PUkRFUkVEX1NFVDtcbiAgZnVuY3Rpb24gZW1wdHlPcmRlcmVkU2V0KCkge1xuICAgIHJldHVybiBFTVBUWV9PUkRFUkVEX1NFVCB8fCAoRU1QVFlfT1JERVJFRF9TRVQgPSBtYWtlT3JkZXJlZFNldChlbXB0eU9yZGVyZWRNYXAoKSkpO1xuICB9XG5cbiAgY3JlYXRlQ2xhc3MoU3RhY2ssIEluZGV4ZWRDb2xsZWN0aW9uKTtcblxuICAgIC8vIEBwcmFnbWEgQ29uc3RydWN0aW9uXG5cbiAgICBmdW5jdGlvbiBTdGFjayh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgPyBlbXB0eVN0YWNrKCkgOlxuICAgICAgICBpc1N0YWNrKHZhbHVlKSA/IHZhbHVlIDpcbiAgICAgICAgZW1wdHlTdGFjaygpLnVuc2hpZnRBbGwodmFsdWUpO1xuICAgIH1cblxuICAgIFN0YWNrLm9mID0gZnVuY3Rpb24oLyouLi52YWx1ZXMqLykge1xuICAgICAgcmV0dXJuIHRoaXMoYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgU3RhY2sucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX3RvU3RyaW5nKCdTdGFjayBbJywgJ10nKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBBY2Nlc3NcblxuICAgIFN0YWNrLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihpbmRleCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHZhciBoZWFkID0gdGhpcy5faGVhZDtcbiAgICAgIGluZGV4ID0gd3JhcEluZGV4KHRoaXMsIGluZGV4KTtcbiAgICAgIHdoaWxlIChoZWFkICYmIGluZGV4LS0pIHtcbiAgICAgICAgaGVhZCA9IGhlYWQubmV4dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBoZWFkID8gaGVhZC52YWx1ZSA6IG5vdFNldFZhbHVlO1xuICAgIH07XG5cbiAgICBTdGFjay5wcm90b3R5cGUucGVlayA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2hlYWQgJiYgdGhpcy5faGVhZC52YWx1ZTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBNb2RpZmljYXRpb25cblxuICAgIFN0YWNrLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24oLyouLi52YWx1ZXMqLykge1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICB2YXIgbmV3U2l6ZSA9IHRoaXMuc2l6ZSArIGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICB2YXIgaGVhZCA9IHRoaXMuX2hlYWQ7XG4gICAgICBmb3IgKHZhciBpaSA9IGFyZ3VtZW50cy5sZW5ndGggLSAxOyBpaSA+PSAwOyBpaS0tKSB7XG4gICAgICAgIGhlYWQgPSB7XG4gICAgICAgICAgdmFsdWU6IGFyZ3VtZW50c1tpaV0sXG4gICAgICAgICAgbmV4dDogaGVhZFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHRoaXMuc2l6ZSA9IG5ld1NpemU7XG4gICAgICAgIHRoaXMuX2hlYWQgPSBoZWFkO1xuICAgICAgICB0aGlzLl9faGFzaCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fX2FsdGVyZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYWtlU3RhY2sobmV3U2l6ZSwgaGVhZCk7XG4gICAgfTtcblxuICAgIFN0YWNrLnByb3RvdHlwZS5wdXNoQWxsID0gZnVuY3Rpb24oaXRlcikge1xuICAgICAgaXRlciA9IEluZGV4ZWRJdGVyYWJsZShpdGVyKTtcbiAgICAgIGlmIChpdGVyLnNpemUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICBhc3NlcnROb3RJbmZpbml0ZShpdGVyLnNpemUpO1xuICAgICAgdmFyIG5ld1NpemUgPSB0aGlzLnNpemU7XG4gICAgICB2YXIgaGVhZCA9IHRoaXMuX2hlYWQ7XG4gICAgICBpdGVyLnJldmVyc2UoKS5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlICkge1xuICAgICAgICBuZXdTaXplKys7XG4gICAgICAgIGhlYWQgPSB7XG4gICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgIG5leHQ6IGhlYWRcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgICAgaWYgKHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHRoaXMuc2l6ZSA9IG5ld1NpemU7XG4gICAgICAgIHRoaXMuX2hlYWQgPSBoZWFkO1xuICAgICAgICB0aGlzLl9faGFzaCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fX2FsdGVyZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYWtlU3RhY2sobmV3U2l6ZSwgaGVhZCk7XG4gICAgfTtcblxuICAgIFN0YWNrLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnNsaWNlKDEpO1xuICAgIH07XG5cbiAgICBTdGFjay5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHJldHVybiB0aGlzLnB1c2guYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgU3RhY2sucHJvdG90eXBlLnVuc2hpZnRBbGwgPSBmdW5jdGlvbihpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5wdXNoQWxsKGl0ZXIpO1xuICAgIH07XG5cbiAgICBTdGFjay5wcm90b3R5cGUuc2hpZnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnBvcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBTdGFjay5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLnNpemUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5fX293bmVySUQpIHtcbiAgICAgICAgdGhpcy5zaXplID0gMDtcbiAgICAgICAgdGhpcy5faGVhZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fX2hhc2ggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX19hbHRlcmVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gZW1wdHlTdGFjaygpO1xuICAgIH07XG5cbiAgICBTdGFjay5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XG4gICAgICBpZiAod2hvbGVTbGljZShiZWdpbiwgZW5kLCB0aGlzLnNpemUpKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIHJlc29sdmVkQmVnaW4gPSByZXNvbHZlQmVnaW4oYmVnaW4sIHRoaXMuc2l6ZSk7XG4gICAgICB2YXIgcmVzb2x2ZWRFbmQgPSByZXNvbHZlRW5kKGVuZCwgdGhpcy5zaXplKTtcbiAgICAgIGlmIChyZXNvbHZlZEVuZCAhPT0gdGhpcy5zaXplKSB7XG4gICAgICAgIC8vIHN1cGVyLnNsaWNlKGJlZ2luLCBlbmQpO1xuICAgICAgICByZXR1cm4gSW5kZXhlZENvbGxlY3Rpb24ucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcywgYmVnaW4sIGVuZCk7XG4gICAgICB9XG4gICAgICB2YXIgbmV3U2l6ZSA9IHRoaXMuc2l6ZSAtIHJlc29sdmVkQmVnaW47XG4gICAgICB2YXIgaGVhZCA9IHRoaXMuX2hlYWQ7XG4gICAgICB3aGlsZSAocmVzb2x2ZWRCZWdpbi0tKSB7XG4gICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5fX293bmVySUQpIHtcbiAgICAgICAgdGhpcy5zaXplID0gbmV3U2l6ZTtcbiAgICAgICAgdGhpcy5faGVhZCA9IGhlYWQ7XG4gICAgICAgIHRoaXMuX19oYXNoID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9fYWx0ZXJlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VTdGFjayhuZXdTaXplLCBoZWFkKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBNdXRhYmlsaXR5XG5cbiAgICBTdGFjay5wcm90b3R5cGUuX19lbnN1cmVPd25lciA9IGZ1bmN0aW9uKG93bmVySUQpIHtcbiAgICAgIGlmIChvd25lcklEID09PSB0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICghb3duZXJJRCkge1xuICAgICAgICB0aGlzLl9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgICAgIHRoaXMuX19hbHRlcmVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VTdGFjayh0aGlzLnNpemUsIHRoaXMuX2hlYWQsIG93bmVySUQsIHRoaXMuX19oYXNoKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBJdGVyYXRpb25cblxuICAgIFN0YWNrLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge1xuICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmV2ZXJzZSgpLl9faXRlcmF0ZShmbik7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICB2YXIgbm9kZSA9IHRoaXMuX2hlYWQ7XG4gICAgICB3aGlsZSAobm9kZSkge1xuICAgICAgICBpZiAoZm4obm9kZS52YWx1ZSwgaXRlcmF0aW9ucysrLCB0aGlzKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBub2RlID0gbm9kZS5uZXh0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgfTtcblxuICAgIFN0YWNrLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmV2ZXJzZSgpLl9faXRlcmF0b3IodHlwZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICB2YXIgbm9kZSA9IHRoaXMuX2hlYWQ7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgaWYgKG5vZGUpIHtcbiAgICAgICAgICB2YXIgdmFsdWUgPSBub2RlLnZhbHVlO1xuICAgICAgICAgIG5vZGUgPSBub2RlLm5leHQ7XG4gICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVmFsdWUodHlwZSwgaXRlcmF0aW9ucysrLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yRG9uZSgpO1xuICAgICAgfSk7XG4gICAgfTtcblxuXG4gIGZ1bmN0aW9uIGlzU3RhY2sobWF5YmVTdGFjaykge1xuICAgIHJldHVybiAhIShtYXliZVN0YWNrICYmIG1heWJlU3RhY2tbSVNfU1RBQ0tfU0VOVElORUxdKTtcbiAgfVxuXG4gIFN0YWNrLmlzU3RhY2sgPSBpc1N0YWNrO1xuXG4gIHZhciBJU19TVEFDS19TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX1NUQUNLX19AQCc7XG5cbiAgdmFyIFN0YWNrUHJvdG90eXBlID0gU3RhY2sucHJvdG90eXBlO1xuICBTdGFja1Byb3RvdHlwZVtJU19TVEFDS19TRU5USU5FTF0gPSB0cnVlO1xuICBTdGFja1Byb3RvdHlwZS53aXRoTXV0YXRpb25zID0gTWFwUHJvdG90eXBlLndpdGhNdXRhdGlvbnM7XG4gIFN0YWNrUHJvdG90eXBlLmFzTXV0YWJsZSA9IE1hcFByb3RvdHlwZS5hc011dGFibGU7XG4gIFN0YWNrUHJvdG90eXBlLmFzSW1tdXRhYmxlID0gTWFwUHJvdG90eXBlLmFzSW1tdXRhYmxlO1xuICBTdGFja1Byb3RvdHlwZS53YXNBbHRlcmVkID0gTWFwUHJvdG90eXBlLndhc0FsdGVyZWQ7XG5cblxuICBmdW5jdGlvbiBtYWtlU3RhY2soc2l6ZSwgaGVhZCwgb3duZXJJRCwgaGFzaCkge1xuICAgIHZhciBtYXAgPSBPYmplY3QuY3JlYXRlKFN0YWNrUHJvdG90eXBlKTtcbiAgICBtYXAuc2l6ZSA9IHNpemU7XG4gICAgbWFwLl9oZWFkID0gaGVhZDtcbiAgICBtYXAuX19vd25lcklEID0gb3duZXJJRDtcbiAgICBtYXAuX19oYXNoID0gaGFzaDtcbiAgICBtYXAuX19hbHRlcmVkID0gZmFsc2U7XG4gICAgcmV0dXJuIG1hcDtcbiAgfVxuXG4gIHZhciBFTVBUWV9TVEFDSztcbiAgZnVuY3Rpb24gZW1wdHlTdGFjaygpIHtcbiAgICByZXR1cm4gRU1QVFlfU1RBQ0sgfHwgKEVNUFRZX1NUQUNLID0gbWFrZVN0YWNrKDApKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb250cmlidXRlcyBhZGRpdGlvbmFsIG1ldGhvZHMgdG8gYSBjb25zdHJ1Y3RvclxuICAgKi9cbiAgZnVuY3Rpb24gbWl4aW4oY3RvciwgbWV0aG9kcykge1xuICAgIHZhciBrZXlDb3BpZXIgPSBmdW5jdGlvbihrZXkgKSB7IGN0b3IucHJvdG90eXBlW2tleV0gPSBtZXRob2RzW2tleV07IH07XG4gICAgT2JqZWN0LmtleXMobWV0aG9kcykuZm9yRWFjaChrZXlDb3BpZXIpO1xuICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgJiZcbiAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMobWV0aG9kcykuZm9yRWFjaChrZXlDb3BpZXIpO1xuICAgIHJldHVybiBjdG9yO1xuICB9XG5cbiAgSXRlcmFibGUuSXRlcmF0b3IgPSBJdGVyYXRvcjtcblxuICBtaXhpbihJdGVyYWJsZSwge1xuXG4gICAgLy8gIyMjIENvbnZlcnNpb24gdG8gb3RoZXIgdHlwZXNcblxuICAgIHRvQXJyYXk6IGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0Tm90SW5maW5pdGUodGhpcy5zaXplKTtcbiAgICAgIHZhciBhcnJheSA9IG5ldyBBcnJheSh0aGlzLnNpemUgfHwgMCk7XG4gICAgICB0aGlzLnZhbHVlU2VxKCkuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGkpICB7IGFycmF5W2ldID0gdjsgfSk7XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfSxcblxuICAgIHRvSW5kZXhlZFNlcTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IFRvSW5kZXhlZFNlcXVlbmNlKHRoaXMpO1xuICAgIH0sXG5cbiAgICB0b0pTOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnRvU2VxKCkubWFwKFxuICAgICAgICBmdW5jdGlvbih2YWx1ZSApIHtyZXR1cm4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlLnRvSlMgPT09ICdmdW5jdGlvbicgPyB2YWx1ZS50b0pTKCkgOiB2YWx1ZX1cbiAgICAgICkuX190b0pTKCk7XG4gICAgfSxcblxuICAgIHRvSlNPTjogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50b1NlcSgpLm1hcChcbiAgICAgICAgZnVuY3Rpb24odmFsdWUgKSB7cmV0dXJuIHZhbHVlICYmIHR5cGVvZiB2YWx1ZS50b0pTT04gPT09ICdmdW5jdGlvbicgPyB2YWx1ZS50b0pTT04oKSA6IHZhbHVlfVxuICAgICAgKS5fX3RvSlMoKTtcbiAgICB9LFxuXG4gICAgdG9LZXllZFNlcTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IFRvS2V5ZWRTZXF1ZW5jZSh0aGlzLCB0cnVlKTtcbiAgICB9LFxuXG4gICAgdG9NYXA6IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gVXNlIExhdGUgQmluZGluZyBoZXJlIHRvIHNvbHZlIHRoZSBjaXJjdWxhciBkZXBlbmRlbmN5LlxuICAgICAgcmV0dXJuIE1hcCh0aGlzLnRvS2V5ZWRTZXEoKSk7XG4gICAgfSxcblxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydE5vdEluZmluaXRlKHRoaXMuc2l6ZSk7XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICB0aGlzLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrKSAgeyBvYmplY3Rba10gPSB2OyB9KTtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfSxcblxuICAgIHRvT3JkZXJlZE1hcDogZnVuY3Rpb24oKSB7XG4gICAgICAvLyBVc2UgTGF0ZSBCaW5kaW5nIGhlcmUgdG8gc29sdmUgdGhlIGNpcmN1bGFyIGRlcGVuZGVuY3kuXG4gICAgICByZXR1cm4gT3JkZXJlZE1hcCh0aGlzLnRvS2V5ZWRTZXEoKSk7XG4gICAgfSxcblxuICAgIHRvT3JkZXJlZFNldDogZnVuY3Rpb24oKSB7XG4gICAgICAvLyBVc2UgTGF0ZSBCaW5kaW5nIGhlcmUgdG8gc29sdmUgdGhlIGNpcmN1bGFyIGRlcGVuZGVuY3kuXG4gICAgICByZXR1cm4gT3JkZXJlZFNldChpc0tleWVkKHRoaXMpID8gdGhpcy52YWx1ZVNlcSgpIDogdGhpcyk7XG4gICAgfSxcblxuICAgIHRvU2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIC8vIFVzZSBMYXRlIEJpbmRpbmcgaGVyZSB0byBzb2x2ZSB0aGUgY2lyY3VsYXIgZGVwZW5kZW5jeS5cbiAgICAgIHJldHVybiBTZXQoaXNLZXllZCh0aGlzKSA/IHRoaXMudmFsdWVTZXEoKSA6IHRoaXMpO1xuICAgIH0sXG5cbiAgICB0b1NldFNlcTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IFRvU2V0U2VxdWVuY2UodGhpcyk7XG4gICAgfSxcblxuICAgIHRvU2VxOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBpc0luZGV4ZWQodGhpcykgPyB0aGlzLnRvSW5kZXhlZFNlcSgpIDpcbiAgICAgICAgaXNLZXllZCh0aGlzKSA/IHRoaXMudG9LZXllZFNlcSgpIDpcbiAgICAgICAgdGhpcy50b1NldFNlcSgpO1xuICAgIH0sXG5cbiAgICB0b1N0YWNrOiBmdW5jdGlvbigpIHtcbiAgICAgIC8vIFVzZSBMYXRlIEJpbmRpbmcgaGVyZSB0byBzb2x2ZSB0aGUgY2lyY3VsYXIgZGVwZW5kZW5jeS5cbiAgICAgIHJldHVybiBTdGFjayhpc0tleWVkKHRoaXMpID8gdGhpcy52YWx1ZVNlcSgpIDogdGhpcyk7XG4gICAgfSxcblxuICAgIHRvTGlzdDogZnVuY3Rpb24oKSB7XG4gICAgICAvLyBVc2UgTGF0ZSBCaW5kaW5nIGhlcmUgdG8gc29sdmUgdGhlIGNpcmN1bGFyIGRlcGVuZGVuY3kuXG4gICAgICByZXR1cm4gTGlzdChpc0tleWVkKHRoaXMpID8gdGhpcy52YWx1ZVNlcSgpIDogdGhpcyk7XG4gICAgfSxcblxuXG4gICAgLy8gIyMjIENvbW1vbiBKYXZhU2NyaXB0IG1ldGhvZHMgYW5kIHByb3BlcnRpZXNcblxuICAgIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAnW0l0ZXJhYmxlXSc7XG4gICAgfSxcblxuICAgIF9fdG9TdHJpbmc6IGZ1bmN0aW9uKGhlYWQsIHRhaWwpIHtcbiAgICAgIGlmICh0aGlzLnNpemUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGhlYWQgKyB0YWlsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhlYWQgKyAnICcgKyB0aGlzLnRvU2VxKCkubWFwKHRoaXMuX190b1N0cmluZ01hcHBlcikuam9pbignLCAnKSArICcgJyArIHRhaWw7XG4gICAgfSxcblxuXG4gICAgLy8gIyMjIEVTNiBDb2xsZWN0aW9uIG1ldGhvZHMgKEVTNiBBcnJheSBhbmQgTWFwKVxuXG4gICAgY29uY2F0OiBmdW5jdGlvbigpIHt2YXIgdmFsdWVzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMCk7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgY29uY2F0RmFjdG9yeSh0aGlzLCB2YWx1ZXMpKTtcbiAgICB9LFxuXG4gICAgaW5jbHVkZXM6IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5zb21lKGZ1bmN0aW9uKHZhbHVlICkge3JldHVybiBpcyh2YWx1ZSwgc2VhcmNoVmFsdWUpfSk7XG4gICAgfSxcblxuICAgIGVudHJpZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX19pdGVyYXRvcihJVEVSQVRFX0VOVFJJRVMpO1xuICAgIH0sXG5cbiAgICBldmVyeTogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICBhc3NlcnROb3RJbmZpbml0ZSh0aGlzLnNpemUpO1xuICAgICAgdmFyIHJldHVyblZhbHVlID0gdHJ1ZTtcbiAgICAgIHRoaXMuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGssIGMpICB7XG4gICAgICAgIGlmICghcHJlZGljYXRlLmNhbGwoY29udGV4dCwgdiwgaywgYykpIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfSxcblxuICAgIGZpbHRlcjogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgZmlsdGVyRmFjdG9yeSh0aGlzLCBwcmVkaWNhdGUsIGNvbnRleHQsIHRydWUpKTtcbiAgICB9LFxuXG4gICAgZmluZDogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0LCBub3RTZXRWYWx1ZSkge1xuICAgICAgdmFyIGVudHJ5ID0gdGhpcy5maW5kRW50cnkocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICAgIHJldHVybiBlbnRyeSA/IGVudHJ5WzFdIDogbm90U2V0VmFsdWU7XG4gICAgfSxcblxuICAgIGZvckVhY2g6IGZ1bmN0aW9uKHNpZGVFZmZlY3QsIGNvbnRleHQpIHtcbiAgICAgIGFzc2VydE5vdEluZmluaXRlKHRoaXMuc2l6ZSk7XG4gICAgICByZXR1cm4gdGhpcy5fX2l0ZXJhdGUoY29udGV4dCA/IHNpZGVFZmZlY3QuYmluZChjb250ZXh0KSA6IHNpZGVFZmZlY3QpO1xuICAgIH0sXG5cbiAgICBqb2luOiBmdW5jdGlvbihzZXBhcmF0b3IpIHtcbiAgICAgIGFzc2VydE5vdEluZmluaXRlKHRoaXMuc2l6ZSk7XG4gICAgICBzZXBhcmF0b3IgPSBzZXBhcmF0b3IgIT09IHVuZGVmaW5lZCA/ICcnICsgc2VwYXJhdG9yIDogJywnO1xuICAgICAgdmFyIGpvaW5lZCA9ICcnO1xuICAgICAgdmFyIGlzRmlyc3QgPSB0cnVlO1xuICAgICAgdGhpcy5fX2l0ZXJhdGUoZnVuY3Rpb24odiApIHtcbiAgICAgICAgaXNGaXJzdCA/IChpc0ZpcnN0ID0gZmFsc2UpIDogKGpvaW5lZCArPSBzZXBhcmF0b3IpO1xuICAgICAgICBqb2luZWQgKz0gdiAhPT0gbnVsbCAmJiB2ICE9PSB1bmRlZmluZWQgPyB2LnRvU3RyaW5nKCkgOiAnJztcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGpvaW5lZDtcbiAgICB9LFxuXG4gICAga2V5czogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX2l0ZXJhdG9yKElURVJBVEVfS0VZUyk7XG4gICAgfSxcblxuICAgIG1hcDogZnVuY3Rpb24obWFwcGVyLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgbWFwRmFjdG9yeSh0aGlzLCBtYXBwZXIsIGNvbnRleHQpKTtcbiAgICB9LFxuXG4gICAgcmVkdWNlOiBmdW5jdGlvbihyZWR1Y2VyLCBpbml0aWFsUmVkdWN0aW9uLCBjb250ZXh0KSB7XG4gICAgICBhc3NlcnROb3RJbmZpbml0ZSh0aGlzLnNpemUpO1xuICAgICAgdmFyIHJlZHVjdGlvbjtcbiAgICAgIHZhciB1c2VGaXJzdDtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgICB1c2VGaXJzdCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWR1Y3Rpb24gPSBpbml0aWFsUmVkdWN0aW9uO1xuICAgICAgfVxuICAgICAgdGhpcy5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaywgYykgIHtcbiAgICAgICAgaWYgKHVzZUZpcnN0KSB7XG4gICAgICAgICAgdXNlRmlyc3QgPSBmYWxzZTtcbiAgICAgICAgICByZWR1Y3Rpb24gPSB2O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlZHVjdGlvbiA9IHJlZHVjZXIuY2FsbChjb250ZXh0LCByZWR1Y3Rpb24sIHYsIGssIGMpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZWR1Y3Rpb247XG4gICAgfSxcblxuICAgIHJlZHVjZVJpZ2h0OiBmdW5jdGlvbihyZWR1Y2VyLCBpbml0aWFsUmVkdWN0aW9uLCBjb250ZXh0KSB7XG4gICAgICB2YXIgcmV2ZXJzZWQgPSB0aGlzLnRvS2V5ZWRTZXEoKS5yZXZlcnNlKCk7XG4gICAgICByZXR1cm4gcmV2ZXJzZWQucmVkdWNlLmFwcGx5KHJldmVyc2VkLCBhcmd1bWVudHMpO1xuICAgIH0sXG5cbiAgICByZXZlcnNlOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCByZXZlcnNlRmFjdG9yeSh0aGlzLCB0cnVlKSk7XG4gICAgfSxcblxuICAgIHNsaWNlOiBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgc2xpY2VGYWN0b3J5KHRoaXMsIGJlZ2luLCBlbmQsIHRydWUpKTtcbiAgICB9LFxuXG4gICAgc29tZTogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gIXRoaXMuZXZlcnkobm90KHByZWRpY2F0ZSksIGNvbnRleHQpO1xuICAgIH0sXG5cbiAgICBzb3J0OiBmdW5jdGlvbihjb21wYXJhdG9yKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgc29ydEZhY3RvcnkodGhpcywgY29tcGFyYXRvcikpO1xuICAgIH0sXG5cbiAgICB2YWx1ZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX19pdGVyYXRvcihJVEVSQVRFX1ZBTFVFUyk7XG4gICAgfSxcblxuXG4gICAgLy8gIyMjIE1vcmUgc2VxdWVudGlhbCBtZXRob2RzXG5cbiAgICBidXRMYXN0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnNsaWNlKDAsIC0xKTtcbiAgICB9LFxuXG4gICAgaXNFbXB0eTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5zaXplICE9PSB1bmRlZmluZWQgPyB0aGlzLnNpemUgPT09IDAgOiAhdGhpcy5zb21lKGZ1bmN0aW9uKCkgIHtyZXR1cm4gdHJ1ZX0pO1xuICAgIH0sXG5cbiAgICBjb3VudDogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gZW5zdXJlU2l6ZShcbiAgICAgICAgcHJlZGljYXRlID8gdGhpcy50b1NlcSgpLmZpbHRlcihwcmVkaWNhdGUsIGNvbnRleHQpIDogdGhpc1xuICAgICAgKTtcbiAgICB9LFxuXG4gICAgY291bnRCeTogZnVuY3Rpb24oZ3JvdXBlciwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIGNvdW50QnlGYWN0b3J5KHRoaXMsIGdyb3VwZXIsIGNvbnRleHQpO1xuICAgIH0sXG5cbiAgICBlcXVhbHM6IGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICByZXR1cm4gZGVlcEVxdWFsKHRoaXMsIG90aGVyKTtcbiAgICB9LFxuXG4gICAgZW50cnlTZXE6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcztcbiAgICAgIGlmIChpdGVyYWJsZS5fY2FjaGUpIHtcbiAgICAgICAgLy8gV2UgY2FjaGUgYXMgYW4gZW50cmllcyBhcnJheSwgc28gd2UgY2FuIGp1c3QgcmV0dXJuIHRoZSBjYWNoZSFcbiAgICAgICAgcmV0dXJuIG5ldyBBcnJheVNlcShpdGVyYWJsZS5fY2FjaGUpO1xuICAgICAgfVxuICAgICAgdmFyIGVudHJpZXNTZXF1ZW5jZSA9IGl0ZXJhYmxlLnRvU2VxKCkubWFwKGVudHJ5TWFwcGVyKS50b0luZGV4ZWRTZXEoKTtcbiAgICAgIGVudHJpZXNTZXF1ZW5jZS5mcm9tRW50cnlTZXEgPSBmdW5jdGlvbigpICB7cmV0dXJuIGl0ZXJhYmxlLnRvU2VxKCl9O1xuICAgICAgcmV0dXJuIGVudHJpZXNTZXF1ZW5jZTtcbiAgICB9LFxuXG4gICAgZmlsdGVyTm90OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiB0aGlzLmZpbHRlcihub3QocHJlZGljYXRlKSwgY29udGV4dCk7XG4gICAgfSxcblxuICAgIGZpbmRFbnRyeTogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0LCBub3RTZXRWYWx1ZSkge1xuICAgICAgdmFyIGZvdW5kID0gbm90U2V0VmFsdWU7XG4gICAgICB0aGlzLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrLCBjKSAge1xuICAgICAgICBpZiAocHJlZGljYXRlLmNhbGwoY29udGV4dCwgdiwgaywgYykpIHtcbiAgICAgICAgICBmb3VuZCA9IFtrLCB2XTtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGZvdW5kO1xuICAgIH0sXG5cbiAgICBmaW5kS2V5OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHZhciBlbnRyeSA9IHRoaXMuZmluZEVudHJ5KHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgICByZXR1cm4gZW50cnkgJiYgZW50cnlbMF07XG4gICAgfSxcblxuICAgIGZpbmRMYXN0OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQsIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy50b0tleWVkU2VxKCkucmV2ZXJzZSgpLmZpbmQocHJlZGljYXRlLCBjb250ZXh0LCBub3RTZXRWYWx1ZSk7XG4gICAgfSxcblxuICAgIGZpbmRMYXN0RW50cnk6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnRvS2V5ZWRTZXEoKS5yZXZlcnNlKCkuZmluZEVudHJ5KHByZWRpY2F0ZSwgY29udGV4dCwgbm90U2V0VmFsdWUpO1xuICAgIH0sXG5cbiAgICBmaW5kTGFzdEtleTogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gdGhpcy50b0tleWVkU2VxKCkucmV2ZXJzZSgpLmZpbmRLZXkocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICB9LFxuXG4gICAgZmlyc3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZmluZChyZXR1cm5UcnVlKTtcbiAgICB9LFxuXG4gICAgZmxhdE1hcDogZnVuY3Rpb24obWFwcGVyLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgZmxhdE1hcEZhY3RvcnkodGhpcywgbWFwcGVyLCBjb250ZXh0KSk7XG4gICAgfSxcblxuICAgIGZsYXR0ZW46IGZ1bmN0aW9uKGRlcHRoKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgZmxhdHRlbkZhY3RvcnkodGhpcywgZGVwdGgsIHRydWUpKTtcbiAgICB9LFxuXG4gICAgZnJvbUVudHJ5U2VxOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgRnJvbUVudHJpZXNTZXF1ZW5jZSh0aGlzKTtcbiAgICB9LFxuXG4gICAgZ2V0OiBmdW5jdGlvbihzZWFyY2hLZXksIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5maW5kKGZ1bmN0aW9uKF8sIGtleSkgIHtyZXR1cm4gaXMoa2V5LCBzZWFyY2hLZXkpfSwgdW5kZWZpbmVkLCBub3RTZXRWYWx1ZSk7XG4gICAgfSxcblxuICAgIGdldEluOiBmdW5jdGlvbihzZWFyY2hLZXlQYXRoLCBub3RTZXRWYWx1ZSkge1xuICAgICAgdmFyIG5lc3RlZCA9IHRoaXM7XG4gICAgICAvLyBOb3RlOiBpbiBhbiBFUzYgZW52aXJvbm1lbnQsIHdlIHdvdWxkIHByZWZlcjpcbiAgICAgIC8vIGZvciAodmFyIGtleSBvZiBzZWFyY2hLZXlQYXRoKSB7XG4gICAgICB2YXIgaXRlciA9IGZvcmNlSXRlcmF0b3Ioc2VhcmNoS2V5UGF0aCk7XG4gICAgICB2YXIgc3RlcDtcbiAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyLm5leHQoKSkuZG9uZSkge1xuICAgICAgICB2YXIga2V5ID0gc3RlcC52YWx1ZTtcbiAgICAgICAgbmVzdGVkID0gbmVzdGVkICYmIG5lc3RlZC5nZXQgPyBuZXN0ZWQuZ2V0KGtleSwgTk9UX1NFVCkgOiBOT1RfU0VUO1xuICAgICAgICBpZiAobmVzdGVkID09PSBOT1RfU0VUKSB7XG4gICAgICAgICAgcmV0dXJuIG5vdFNldFZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbmVzdGVkO1xuICAgIH0sXG5cbiAgICBncm91cEJ5OiBmdW5jdGlvbihncm91cGVyLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gZ3JvdXBCeUZhY3RvcnkodGhpcywgZ3JvdXBlciwgY29udGV4dCk7XG4gICAgfSxcblxuICAgIGhhczogZnVuY3Rpb24oc2VhcmNoS2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXQoc2VhcmNoS2V5LCBOT1RfU0VUKSAhPT0gTk9UX1NFVDtcbiAgICB9LFxuXG4gICAgaGFzSW46IGZ1bmN0aW9uKHNlYXJjaEtleVBhdGgpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEluKHNlYXJjaEtleVBhdGgsIE5PVF9TRVQpICE9PSBOT1RfU0VUO1xuICAgIH0sXG5cbiAgICBpc1N1YnNldDogZnVuY3Rpb24oaXRlcikge1xuICAgICAgaXRlciA9IHR5cGVvZiBpdGVyLmluY2x1ZGVzID09PSAnZnVuY3Rpb24nID8gaXRlciA6IEl0ZXJhYmxlKGl0ZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZXZlcnkoZnVuY3Rpb24odmFsdWUgKSB7cmV0dXJuIGl0ZXIuaW5jbHVkZXModmFsdWUpfSk7XG4gICAgfSxcblxuICAgIGlzU3VwZXJzZXQ6IGZ1bmN0aW9uKGl0ZXIpIHtcbiAgICAgIGl0ZXIgPSB0eXBlb2YgaXRlci5pc1N1YnNldCA9PT0gJ2Z1bmN0aW9uJyA/IGl0ZXIgOiBJdGVyYWJsZShpdGVyKTtcbiAgICAgIHJldHVybiBpdGVyLmlzU3Vic2V0KHRoaXMpO1xuICAgIH0sXG5cbiAgICBrZXlPZjogZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmZpbmRLZXkoZnVuY3Rpb24odmFsdWUgKSB7cmV0dXJuIGlzKHZhbHVlLCBzZWFyY2hWYWx1ZSl9KTtcbiAgICB9LFxuXG4gICAga2V5U2VxOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnRvU2VxKCkubWFwKGtleU1hcHBlcikudG9JbmRleGVkU2VxKCk7XG4gICAgfSxcblxuICAgIGxhc3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudG9TZXEoKS5yZXZlcnNlKCkuZmlyc3QoKTtcbiAgICB9LFxuXG4gICAgbGFzdEtleU9mOiBmdW5jdGlvbihzZWFyY2hWYWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMudG9LZXllZFNlcSgpLnJldmVyc2UoKS5rZXlPZihzZWFyY2hWYWx1ZSk7XG4gICAgfSxcblxuICAgIG1heDogZnVuY3Rpb24oY29tcGFyYXRvcikge1xuICAgICAgcmV0dXJuIG1heEZhY3RvcnkodGhpcywgY29tcGFyYXRvcik7XG4gICAgfSxcblxuICAgIG1heEJ5OiBmdW5jdGlvbihtYXBwZXIsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiBtYXhGYWN0b3J5KHRoaXMsIGNvbXBhcmF0b3IsIG1hcHBlcik7XG4gICAgfSxcblxuICAgIG1pbjogZnVuY3Rpb24oY29tcGFyYXRvcikge1xuICAgICAgcmV0dXJuIG1heEZhY3RvcnkodGhpcywgY29tcGFyYXRvciA/IG5lZyhjb21wYXJhdG9yKSA6IGRlZmF1bHROZWdDb21wYXJhdG9yKTtcbiAgICB9LFxuXG4gICAgbWluQnk6IGZ1bmN0aW9uKG1hcHBlciwgY29tcGFyYXRvcikge1xuICAgICAgcmV0dXJuIG1heEZhY3RvcnkodGhpcywgY29tcGFyYXRvciA/IG5lZyhjb21wYXJhdG9yKSA6IGRlZmF1bHROZWdDb21wYXJhdG9yLCBtYXBwZXIpO1xuICAgIH0sXG5cbiAgICByZXN0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnNsaWNlKDEpO1xuICAgIH0sXG5cbiAgICBza2lwOiBmdW5jdGlvbihhbW91bnQpIHtcbiAgICAgIHJldHVybiB0aGlzLnNsaWNlKE1hdGgubWF4KDAsIGFtb3VudCkpO1xuICAgIH0sXG5cbiAgICBza2lwTGFzdDogZnVuY3Rpb24oYW1vdW50KSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgdGhpcy50b1NlcSgpLnJldmVyc2UoKS5za2lwKGFtb3VudCkucmV2ZXJzZSgpKTtcbiAgICB9LFxuXG4gICAgc2tpcFdoaWxlOiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBza2lwV2hpbGVGYWN0b3J5KHRoaXMsIHByZWRpY2F0ZSwgY29udGV4dCwgdHJ1ZSkpO1xuICAgIH0sXG5cbiAgICBza2lwVW50aWw6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2tpcFdoaWxlKG5vdChwcmVkaWNhdGUpLCBjb250ZXh0KTtcbiAgICB9LFxuXG4gICAgc29ydEJ5OiBmdW5jdGlvbihtYXBwZXIsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBzb3J0RmFjdG9yeSh0aGlzLCBjb21wYXJhdG9yLCBtYXBwZXIpKTtcbiAgICB9LFxuXG4gICAgdGFrZTogZnVuY3Rpb24oYW1vdW50KSB7XG4gICAgICByZXR1cm4gdGhpcy5zbGljZSgwLCBNYXRoLm1heCgwLCBhbW91bnQpKTtcbiAgICB9LFxuXG4gICAgdGFrZUxhc3Q6IGZ1bmN0aW9uKGFtb3VudCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIHRoaXMudG9TZXEoKS5yZXZlcnNlKCkudGFrZShhbW91bnQpLnJldmVyc2UoKSk7XG4gICAgfSxcblxuICAgIHRha2VXaGlsZTogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgdGFrZVdoaWxlRmFjdG9yeSh0aGlzLCBwcmVkaWNhdGUsIGNvbnRleHQpKTtcbiAgICB9LFxuXG4gICAgdGFrZVVudGlsOiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiB0aGlzLnRha2VXaGlsZShub3QocHJlZGljYXRlKSwgY29udGV4dCk7XG4gICAgfSxcblxuICAgIHZhbHVlU2VxOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnRvSW5kZXhlZFNlcSgpO1xuICAgIH0sXG5cblxuICAgIC8vICMjIyBIYXNoYWJsZSBPYmplY3RcblxuICAgIGhhc2hDb2RlOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9faGFzaCB8fCAodGhpcy5fX2hhc2ggPSBoYXNoSXRlcmFibGUodGhpcykpO1xuICAgIH1cblxuXG4gICAgLy8gIyMjIEludGVybmFsXG5cbiAgICAvLyBhYnN0cmFjdCBfX2l0ZXJhdGUoZm4sIHJldmVyc2UpXG5cbiAgICAvLyBhYnN0cmFjdCBfX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpXG4gIH0pO1xuXG4gIC8vIHZhciBJU19JVEVSQUJMRV9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX0lURVJBQkxFX19AQCc7XG4gIC8vIHZhciBJU19LRVlFRF9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX0tFWUVEX19AQCc7XG4gIC8vIHZhciBJU19JTkRFWEVEX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfSU5ERVhFRF9fQEAnO1xuICAvLyB2YXIgSVNfT1JERVJFRF9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX09SREVSRURfX0BAJztcblxuICB2YXIgSXRlcmFibGVQcm90b3R5cGUgPSBJdGVyYWJsZS5wcm90b3R5cGU7XG4gIEl0ZXJhYmxlUHJvdG90eXBlW0lTX0lURVJBQkxFX1NFTlRJTkVMXSA9IHRydWU7XG4gIEl0ZXJhYmxlUHJvdG90eXBlW0lURVJBVE9SX1NZTUJPTF0gPSBJdGVyYWJsZVByb3RvdHlwZS52YWx1ZXM7XG4gIEl0ZXJhYmxlUHJvdG90eXBlLl9fdG9KUyA9IEl0ZXJhYmxlUHJvdG90eXBlLnRvQXJyYXk7XG4gIEl0ZXJhYmxlUHJvdG90eXBlLl9fdG9TdHJpbmdNYXBwZXIgPSBxdW90ZVN0cmluZztcbiAgSXRlcmFibGVQcm90b3R5cGUuaW5zcGVjdCA9XG4gIEl0ZXJhYmxlUHJvdG90eXBlLnRvU291cmNlID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLnRvU3RyaW5nKCk7IH07XG4gIEl0ZXJhYmxlUHJvdG90eXBlLmNoYWluID0gSXRlcmFibGVQcm90b3R5cGUuZmxhdE1hcDtcbiAgSXRlcmFibGVQcm90b3R5cGUuY29udGFpbnMgPSBJdGVyYWJsZVByb3RvdHlwZS5pbmNsdWRlcztcblxuICBtaXhpbihLZXllZEl0ZXJhYmxlLCB7XG5cbiAgICAvLyAjIyMgTW9yZSBzZXF1ZW50aWFsIG1ldGhvZHNcblxuICAgIGZsaXA6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIGZsaXBGYWN0b3J5KHRoaXMpKTtcbiAgICB9LFxuXG4gICAgbWFwRW50cmllczogZnVuY3Rpb24obWFwcGVyLCBjb250ZXh0KSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcyxcbiAgICAgICAgdGhpcy50b1NlcSgpLm1hcChcbiAgICAgICAgICBmdW5jdGlvbih2LCBrKSAge3JldHVybiBtYXBwZXIuY2FsbChjb250ZXh0LCBbaywgdl0sIGl0ZXJhdGlvbnMrKywgdGhpcyQwKX1cbiAgICAgICAgKS5mcm9tRW50cnlTZXEoKVxuICAgICAgKTtcbiAgICB9LFxuXG4gICAgbWFwS2V5czogZnVuY3Rpb24obWFwcGVyLCBjb250ZXh0KSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcyxcbiAgICAgICAgdGhpcy50b1NlcSgpLmZsaXAoKS5tYXAoXG4gICAgICAgICAgZnVuY3Rpb24oaywgdikgIHtyZXR1cm4gbWFwcGVyLmNhbGwoY29udGV4dCwgaywgdiwgdGhpcyQwKX1cbiAgICAgICAgKS5mbGlwKClcbiAgICAgICk7XG4gICAgfVxuXG4gIH0pO1xuXG4gIHZhciBLZXllZEl0ZXJhYmxlUHJvdG90eXBlID0gS2V5ZWRJdGVyYWJsZS5wcm90b3R5cGU7XG4gIEtleWVkSXRlcmFibGVQcm90b3R5cGVbSVNfS0VZRURfU0VOVElORUxdID0gdHJ1ZTtcbiAgS2V5ZWRJdGVyYWJsZVByb3RvdHlwZVtJVEVSQVRPUl9TWU1CT0xdID0gSXRlcmFibGVQcm90b3R5cGUuZW50cmllcztcbiAgS2V5ZWRJdGVyYWJsZVByb3RvdHlwZS5fX3RvSlMgPSBJdGVyYWJsZVByb3RvdHlwZS50b09iamVjdDtcbiAgS2V5ZWRJdGVyYWJsZVByb3RvdHlwZS5fX3RvU3RyaW5nTWFwcGVyID0gZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gSlNPTi5zdHJpbmdpZnkoaykgKyAnOiAnICsgcXVvdGVTdHJpbmcodil9O1xuXG5cblxuICBtaXhpbihJbmRleGVkSXRlcmFibGUsIHtcblxuICAgIC8vICMjIyBDb252ZXJzaW9uIHRvIG90aGVyIHR5cGVzXG5cbiAgICB0b0tleWVkU2VxOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgVG9LZXllZFNlcXVlbmNlKHRoaXMsIGZhbHNlKTtcbiAgICB9LFxuXG5cbiAgICAvLyAjIyMgRVM2IENvbGxlY3Rpb24gbWV0aG9kcyAoRVM2IEFycmF5IGFuZCBNYXApXG5cbiAgICBmaWx0ZXI6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIGZpbHRlckZhY3RvcnkodGhpcywgcHJlZGljYXRlLCBjb250ZXh0LCBmYWxzZSkpO1xuICAgIH0sXG5cbiAgICBmaW5kSW5kZXg6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgdmFyIGVudHJ5ID0gdGhpcy5maW5kRW50cnkocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICAgIHJldHVybiBlbnRyeSA/IGVudHJ5WzBdIDogLTE7XG4gICAgfSxcblxuICAgIGluZGV4T2Y6IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICB2YXIga2V5ID0gdGhpcy5rZXlPZihzZWFyY2hWYWx1ZSk7XG4gICAgICByZXR1cm4ga2V5ID09PSB1bmRlZmluZWQgPyAtMSA6IGtleTtcbiAgICB9LFxuXG4gICAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICB2YXIga2V5ID0gdGhpcy5sYXN0S2V5T2Yoc2VhcmNoVmFsdWUpO1xuICAgICAgcmV0dXJuIGtleSA9PT0gdW5kZWZpbmVkID8gLTEgOiBrZXk7XG4gICAgfSxcblxuICAgIHJldmVyc2U6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIHJldmVyc2VGYWN0b3J5KHRoaXMsIGZhbHNlKSk7XG4gICAgfSxcblxuICAgIHNsaWNlOiBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgc2xpY2VGYWN0b3J5KHRoaXMsIGJlZ2luLCBlbmQsIGZhbHNlKSk7XG4gICAgfSxcblxuICAgIHNwbGljZTogZnVuY3Rpb24oaW5kZXgsIHJlbW92ZU51bSAvKiwgLi4udmFsdWVzKi8pIHtcbiAgICAgIHZhciBudW1BcmdzID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgIHJlbW92ZU51bSA9IE1hdGgubWF4KHJlbW92ZU51bSB8IDAsIDApO1xuICAgICAgaWYgKG51bUFyZ3MgPT09IDAgfHwgKG51bUFyZ3MgPT09IDIgJiYgIXJlbW92ZU51bSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICAvLyBJZiBpbmRleCBpcyBuZWdhdGl2ZSwgaXQgc2hvdWxkIHJlc29sdmUgcmVsYXRpdmUgdG8gdGhlIHNpemUgb2YgdGhlXG4gICAgICAvLyBjb2xsZWN0aW9uLiBIb3dldmVyIHNpemUgbWF5IGJlIGV4cGVuc2l2ZSB0byBjb21wdXRlIGlmIG5vdCBjYWNoZWQsIHNvXG4gICAgICAvLyBvbmx5IGNhbGwgY291bnQoKSBpZiB0aGUgbnVtYmVyIGlzIGluIGZhY3QgbmVnYXRpdmUuXG4gICAgICBpbmRleCA9IHJlc29sdmVCZWdpbihpbmRleCwgaW5kZXggPCAwID8gdGhpcy5jb3VudCgpIDogdGhpcy5zaXplKTtcbiAgICAgIHZhciBzcGxpY2VkID0gdGhpcy5zbGljZSgwLCBpbmRleCk7XG4gICAgICByZXR1cm4gcmVpZnkoXG4gICAgICAgIHRoaXMsXG4gICAgICAgIG51bUFyZ3MgPT09IDEgP1xuICAgICAgICAgIHNwbGljZWQgOlxuICAgICAgICAgIHNwbGljZWQuY29uY2F0KGFyckNvcHkoYXJndW1lbnRzLCAyKSwgdGhpcy5zbGljZShpbmRleCArIHJlbW92ZU51bSkpXG4gICAgICApO1xuICAgIH0sXG5cblxuICAgIC8vICMjIyBNb3JlIGNvbGxlY3Rpb24gbWV0aG9kc1xuXG4gICAgZmluZExhc3RJbmRleDogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICB2YXIgZW50cnkgPSB0aGlzLmZpbmRMYXN0RW50cnkocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICAgIHJldHVybiBlbnRyeSA/IGVudHJ5WzBdIDogLTE7XG4gICAgfSxcblxuICAgIGZpcnN0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldCgwKTtcbiAgICB9LFxuXG4gICAgZmxhdHRlbjogZnVuY3Rpb24oZGVwdGgpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBmbGF0dGVuRmFjdG9yeSh0aGlzLCBkZXB0aCwgZmFsc2UpKTtcbiAgICB9LFxuXG4gICAgZ2V0OiBmdW5jdGlvbihpbmRleCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIGluZGV4ID0gd3JhcEluZGV4KHRoaXMsIGluZGV4KTtcbiAgICAgIHJldHVybiAoaW5kZXggPCAwIHx8ICh0aGlzLnNpemUgPT09IEluZmluaXR5IHx8XG4gICAgICAgICAgKHRoaXMuc2l6ZSAhPT0gdW5kZWZpbmVkICYmIGluZGV4ID4gdGhpcy5zaXplKSkpID9cbiAgICAgICAgbm90U2V0VmFsdWUgOlxuICAgICAgICB0aGlzLmZpbmQoZnVuY3Rpb24oXywga2V5KSAge3JldHVybiBrZXkgPT09IGluZGV4fSwgdW5kZWZpbmVkLCBub3RTZXRWYWx1ZSk7XG4gICAgfSxcblxuICAgIGhhczogZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgIGluZGV4ID0gd3JhcEluZGV4KHRoaXMsIGluZGV4KTtcbiAgICAgIHJldHVybiBpbmRleCA+PSAwICYmICh0aGlzLnNpemUgIT09IHVuZGVmaW5lZCA/XG4gICAgICAgIHRoaXMuc2l6ZSA9PT0gSW5maW5pdHkgfHwgaW5kZXggPCB0aGlzLnNpemUgOlxuICAgICAgICB0aGlzLmluZGV4T2YoaW5kZXgpICE9PSAtMVxuICAgICAgKTtcbiAgICB9LFxuXG4gICAgaW50ZXJwb3NlOiBmdW5jdGlvbihzZXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBpbnRlcnBvc2VGYWN0b3J5KHRoaXMsIHNlcGFyYXRvcikpO1xuICAgIH0sXG5cbiAgICBpbnRlcmxlYXZlOiBmdW5jdGlvbigvKi4uLml0ZXJhYmxlcyovKSB7XG4gICAgICB2YXIgaXRlcmFibGVzID0gW3RoaXNdLmNvbmNhdChhcnJDb3B5KGFyZ3VtZW50cykpO1xuICAgICAgdmFyIHppcHBlZCA9IHppcFdpdGhGYWN0b3J5KHRoaXMudG9TZXEoKSwgSW5kZXhlZFNlcS5vZiwgaXRlcmFibGVzKTtcbiAgICAgIHZhciBpbnRlcmxlYXZlZCA9IHppcHBlZC5mbGF0dGVuKHRydWUpO1xuICAgICAgaWYgKHppcHBlZC5zaXplKSB7XG4gICAgICAgIGludGVybGVhdmVkLnNpemUgPSB6aXBwZWQuc2l6ZSAqIGl0ZXJhYmxlcy5sZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgaW50ZXJsZWF2ZWQpO1xuICAgIH0sXG5cbiAgICBrZXlTZXE6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIFJhbmdlKDAsIHRoaXMuc2l6ZSk7XG4gICAgfSxcblxuICAgIGxhc3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0KC0xKTtcbiAgICB9LFxuXG4gICAgc2tpcFdoaWxlOiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBza2lwV2hpbGVGYWN0b3J5KHRoaXMsIHByZWRpY2F0ZSwgY29udGV4dCwgZmFsc2UpKTtcbiAgICB9LFxuXG4gICAgemlwOiBmdW5jdGlvbigvKiwgLi4uaXRlcmFibGVzICovKSB7XG4gICAgICB2YXIgaXRlcmFibGVzID0gW3RoaXNdLmNvbmNhdChhcnJDb3B5KGFyZ3VtZW50cykpO1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIHppcFdpdGhGYWN0b3J5KHRoaXMsIGRlZmF1bHRaaXBwZXIsIGl0ZXJhYmxlcykpO1xuICAgIH0sXG5cbiAgICB6aXBXaXRoOiBmdW5jdGlvbih6aXBwZXIvKiwgLi4uaXRlcmFibGVzICovKSB7XG4gICAgICB2YXIgaXRlcmFibGVzID0gYXJyQ29weShhcmd1bWVudHMpO1xuICAgICAgaXRlcmFibGVzWzBdID0gdGhpcztcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCB6aXBXaXRoRmFjdG9yeSh0aGlzLCB6aXBwZXIsIGl0ZXJhYmxlcykpO1xuICAgIH1cblxuICB9KTtcblxuICBJbmRleGVkSXRlcmFibGUucHJvdG90eXBlW0lTX0lOREVYRURfU0VOVElORUxdID0gdHJ1ZTtcbiAgSW5kZXhlZEl0ZXJhYmxlLnByb3RvdHlwZVtJU19PUkRFUkVEX1NFTlRJTkVMXSA9IHRydWU7XG5cblxuXG4gIG1peGluKFNldEl0ZXJhYmxlLCB7XG5cbiAgICAvLyAjIyMgRVM2IENvbGxlY3Rpb24gbWV0aG9kcyAoRVM2IEFycmF5IGFuZCBNYXApXG5cbiAgICBnZXQ6IGZ1bmN0aW9uKHZhbHVlLCBub3RTZXRWYWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFzKHZhbHVlKSA/IHZhbHVlIDogbm90U2V0VmFsdWU7XG4gICAgfSxcblxuICAgIGluY2x1ZGVzOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFzKHZhbHVlKTtcbiAgICB9LFxuXG5cbiAgICAvLyAjIyMgTW9yZSBzZXF1ZW50aWFsIG1ldGhvZHNcblxuICAgIGtleVNlcTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy52YWx1ZVNlcSgpO1xuICAgIH1cblxuICB9KTtcblxuICBTZXRJdGVyYWJsZS5wcm90b3R5cGUuaGFzID0gSXRlcmFibGVQcm90b3R5cGUuaW5jbHVkZXM7XG4gIFNldEl0ZXJhYmxlLnByb3RvdHlwZS5jb250YWlucyA9IFNldEl0ZXJhYmxlLnByb3RvdHlwZS5pbmNsdWRlcztcblxuXG4gIC8vIE1peGluIHN1YmNsYXNzZXNcblxuICBtaXhpbihLZXllZFNlcSwgS2V5ZWRJdGVyYWJsZS5wcm90b3R5cGUpO1xuICBtaXhpbihJbmRleGVkU2VxLCBJbmRleGVkSXRlcmFibGUucHJvdG90eXBlKTtcbiAgbWl4aW4oU2V0U2VxLCBTZXRJdGVyYWJsZS5wcm90b3R5cGUpO1xuXG4gIG1peGluKEtleWVkQ29sbGVjdGlvbiwgS2V5ZWRJdGVyYWJsZS5wcm90b3R5cGUpO1xuICBtaXhpbihJbmRleGVkQ29sbGVjdGlvbiwgSW5kZXhlZEl0ZXJhYmxlLnByb3RvdHlwZSk7XG4gIG1peGluKFNldENvbGxlY3Rpb24sIFNldEl0ZXJhYmxlLnByb3RvdHlwZSk7XG5cblxuICAvLyAjcHJhZ21hIEhlbHBlciBmdW5jdGlvbnNcblxuICBmdW5jdGlvbiBrZXlNYXBwZXIodiwgaykge1xuICAgIHJldHVybiBrO1xuICB9XG5cbiAgZnVuY3Rpb24gZW50cnlNYXBwZXIodiwgaykge1xuICAgIHJldHVybiBbaywgdl07XG4gIH1cblxuICBmdW5jdGlvbiBub3QocHJlZGljYXRlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuICFwcmVkaWNhdGUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBuZWcocHJlZGljYXRlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIC1wcmVkaWNhdGUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBxdW90ZVN0cmluZyh2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gSlNPTi5zdHJpbmdpZnkodmFsdWUpIDogU3RyaW5nKHZhbHVlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlZmF1bHRaaXBwZXIoKSB7XG4gICAgcmV0dXJuIGFyckNvcHkoYXJndW1lbnRzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlZmF1bHROZWdDb21wYXJhdG9yKGEsIGIpIHtcbiAgICByZXR1cm4gYSA8IGIgPyAxIDogYSA+IGIgPyAtMSA6IDA7XG4gIH1cblxuICBmdW5jdGlvbiBoYXNoSXRlcmFibGUoaXRlcmFibGUpIHtcbiAgICBpZiAoaXRlcmFibGUuc2l6ZSA9PT0gSW5maW5pdHkpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICB2YXIgb3JkZXJlZCA9IGlzT3JkZXJlZChpdGVyYWJsZSk7XG4gICAgdmFyIGtleWVkID0gaXNLZXllZChpdGVyYWJsZSk7XG4gICAgdmFyIGggPSBvcmRlcmVkID8gMSA6IDA7XG4gICAgdmFyIHNpemUgPSBpdGVyYWJsZS5fX2l0ZXJhdGUoXG4gICAgICBrZXllZCA/XG4gICAgICAgIG9yZGVyZWQgP1xuICAgICAgICAgIGZ1bmN0aW9uKHYsIGspICB7IGggPSAzMSAqIGggKyBoYXNoTWVyZ2UoaGFzaCh2KSwgaGFzaChrKSkgfCAwOyB9IDpcbiAgICAgICAgICBmdW5jdGlvbih2LCBrKSAgeyBoID0gaCArIGhhc2hNZXJnZShoYXNoKHYpLCBoYXNoKGspKSB8IDA7IH0gOlxuICAgICAgICBvcmRlcmVkID9cbiAgICAgICAgICBmdW5jdGlvbih2ICkgeyBoID0gMzEgKiBoICsgaGFzaCh2KSB8IDA7IH0gOlxuICAgICAgICAgIGZ1bmN0aW9uKHYgKSB7IGggPSBoICsgaGFzaCh2KSB8IDA7IH1cbiAgICApO1xuICAgIHJldHVybiBtdXJtdXJIYXNoT2ZTaXplKHNpemUsIGgpO1xuICB9XG5cbiAgZnVuY3Rpb24gbXVybXVySGFzaE9mU2l6ZShzaXplLCBoKSB7XG4gICAgaCA9IGltdWwoaCwgMHhDQzlFMkQ1MSk7XG4gICAgaCA9IGltdWwoaCA8PCAxNSB8IGggPj4+IC0xNSwgMHgxQjg3MzU5Myk7XG4gICAgaCA9IGltdWwoaCA8PCAxMyB8IGggPj4+IC0xMywgNSk7XG4gICAgaCA9IChoICsgMHhFNjU0NkI2NCB8IDApIF4gc2l6ZTtcbiAgICBoID0gaW11bChoIF4gaCA+Pj4gMTYsIDB4ODVFQkNBNkIpO1xuICAgIGggPSBpbXVsKGggXiBoID4+PiAxMywgMHhDMkIyQUUzNSk7XG4gICAgaCA9IHNtaShoIF4gaCA+Pj4gMTYpO1xuICAgIHJldHVybiBoO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFzaE1lcmdlKGEsIGIpIHtcbiAgICByZXR1cm4gYSBeIGIgKyAweDlFMzc3OUI5ICsgKGEgPDwgNikgKyAoYSA+PiAyKSB8IDA7IC8vIGludFxuICB9XG5cbiAgdmFyIEltbXV0YWJsZSA9IHtcblxuICAgIEl0ZXJhYmxlOiBJdGVyYWJsZSxcblxuICAgIFNlcTogU2VxLFxuICAgIENvbGxlY3Rpb246IENvbGxlY3Rpb24sXG4gICAgTWFwOiBNYXAsXG4gICAgT3JkZXJlZE1hcDogT3JkZXJlZE1hcCxcbiAgICBMaXN0OiBMaXN0LFxuICAgIFN0YWNrOiBTdGFjayxcbiAgICBTZXQ6IFNldCxcbiAgICBPcmRlcmVkU2V0OiBPcmRlcmVkU2V0LFxuXG4gICAgUmVjb3JkOiBSZWNvcmQsXG4gICAgUmFuZ2U6IFJhbmdlLFxuICAgIFJlcGVhdDogUmVwZWF0LFxuXG4gICAgaXM6IGlzLFxuICAgIGZyb21KUzogZnJvbUpTXG5cbiAgfTtcblxuICByZXR1cm4gSW1tdXRhYmxlO1xuXG59KSk7IiwiLy8gVXRpbGl0eSBwcm90b2NvbCBmb3IgbWVhc3VyaW5nIHdoZW4gYSBzdGF0ZUNoYW5nZSB0YWtlcyBlZmZlY3QuXG5cbnZhciBSYW5kb21JRCA9IHJlcXVpcmUoJy4vcmFuZG9taWQuanMnKTtcbnZhciBEYXRhc3BhY2UgPSByZXF1aXJlKCcuL2RhdGFzcGFjZS5qcycpLkRhdGFzcGFjZTtcbnZhciBTdHJ1Y3QgPSByZXF1aXJlKCcuL3N0cnVjdC5qcycpO1xudmFyIFBhdGNoID0gcmVxdWlyZSgnLi9wYXRjaC5qcycpO1xuXG52YXIgYWNrID0gU3RydWN0Lm1ha2VDb25zdHJ1Y3RvcignYWNrJywgWydpZCddKTtcblxuZnVuY3Rpb24gQWNrKG1ldGFMZXZlbCwgaWQpIHtcbiAgdGhpcy5tZXRhTGV2ZWwgPSBtZXRhTGV2ZWwgfHwgMDtcbiAgdGhpcy5pZCA9IGlkIHx8IFJhbmRvbUlELnJhbmRvbUlkKDE2KTtcbiAgdGhpcy5kb25lID0gZmFsc2U7XG59XG5cbkFjay5wcm90b3R5cGUuYXJtID0gZnVuY3Rpb24gKCkge1xuICBEYXRhc3BhY2Uuc3RhdGVDaGFuZ2UoUGF0Y2guc3ViKGFjayh0aGlzLmlkKSwgdGhpcy5tZXRhTGV2ZWwpKTtcbiAgRGF0YXNwYWNlLnNlbmQoYWNrKHRoaXMuaWQpLCB0aGlzLm1ldGFMZXZlbCk7XG59O1xuXG5BY2sucHJvdG90eXBlLmRpc2FybSA9IGZ1bmN0aW9uICgpIHtcbiAgRGF0YXNwYWNlLnN0YXRlQ2hhbmdlKFBhdGNoLnVuc3ViKGFjayh0aGlzLmlkKSwgdGhpcy5tZXRhTGV2ZWwpKTtcbn07XG5cbkFjay5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbiAoZSkge1xuICBpZiAoIXRoaXMuZG9uZSkge1xuICAgIGlmIChlLnR5cGUgPT09ICdtZXNzYWdlJykge1xuICAgICAgdmFyIG0gPSBQYXRjaC5zdHJpcEF0TWV0YShlLm1lc3NhZ2UsIHRoaXMubWV0YUxldmVsKTtcbiAgICAgIGlmIChhY2suaXNDbGFzc09mKG0pICYmIG1bMF0gPT09IHRoaXMuaWQpIHtcblx0dGhpcy5kaXNhcm0oKTtcblx0dGhpcy5kb25lID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoaXMuZG9uZTtcbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5hY2sgPSBhY2s7XG5tb2R1bGUuZXhwb3J0cy5BY2sgPSBBY2s7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBJbW11dGFibGUgPSByZXF1aXJlKCdpbW11dGFibGUnKTtcbnZhciBfRGF0YXNwYWNlID0gcmVxdWlyZSgnLi9kYXRhc3BhY2UuanMnKTtcbnZhciBEYXRhc3BhY2UgPSBfRGF0YXNwYWNlLkRhdGFzcGFjZTtcbnZhciBfXyA9IF9EYXRhc3BhY2UuX187XG52YXIgTXV4ID0gcmVxdWlyZSgnLi9tdXguanMnKTtcbnZhciBQYXRjaCA9IHJlcXVpcmUoJy4vcGF0Y2guanMnKTtcbnZhciBUcmllID0gcmVxdWlyZSgnLi90cmllLmpzJyk7XG52YXIgVXRpbCA9IHJlcXVpcmUoJy4vdXRpbC5qcycpO1xuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5mdW5jdGlvbiBzcGF3bkFjdG9yKHN0YXRlLCBib290Rm4sIG9wdE5hbWUpIHtcbiAgRGF0YXNwYWNlLnNwYXduKG5ldyBBY3RvcihzdGF0ZSwgYm9vdEZuLCBvcHROYW1lKSk7XG59XG5cbmZ1bmN0aW9uIEFjdG9yKHN0YXRlLCBib290Rm4sIG9wdE5hbWUpIHtcbiAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xuICB0aGlzLmZhY2V0cyA9IEltbXV0YWJsZS5TZXQoKTtcbiAgdGhpcy5tdXggPSBuZXcgTXV4Lk11eCgpO1xuICB0aGlzLnByZXZpb3VzS25vd2xlZGdlID0gVHJpZS5lbXB0eVRyaWU7XG4gIHRoaXMua25vd2xlZGdlID0gVHJpZS5lbXB0eVRyaWU7XG4gIHRoaXMucGVuZGluZ0FjdGlvbnMgPSBbXTtcblxuICBpZiAodHlwZW9mIG9wdE5hbWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhpcy5uYW1lID0gb3B0TmFtZTtcbiAgfVxuXG4gIHRoaXMuYm9vdCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB3aXRoQ3VycmVudEZhY2V0KG51bGwsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJvb3RGbi5jYWxsKHNlbGYuc3RhdGUpO1xuICAgIH0pO1xuICAgIHNlbGYuY2hlY2tGb3JUZXJtaW5hdGlvbigpO1xuICB9O1xufVxuXG5BY3Rvci5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbihlKSB7XG4gIGlmIChlLnR5cGUgPT09ICdzdGF0ZUNoYW5nZScpIHtcbiAgICB0aGlzLnByZXZpb3VzS25vd2xlZGdlID0gdGhpcy5rbm93bGVkZ2U7XG4gICAgdGhpcy5rbm93bGVkZ2UgPSBlLnBhdGNoLnVwZGF0ZUludGVyZXN0cyh0aGlzLmtub3dsZWRnZSk7XG4gIH1cbiAgaWYgKHRoaXMucGVuZGluZ0FjdGlvbnMubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU3luZGljYXRlOiBwZW5kaW5nQWN0aW9ucyBtdXN0IG5vdCBiZSBub25lbXB0eSBhdCBzdGFydCBvZiBoYW5kbGVFdmVudCcpO1xuICB9XG4gIHRoaXMuZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICB3aXRoQ3VycmVudEZhY2V0KGYsIGZ1bmN0aW9uICgpIHsgZi5oYW5kbGVFdmVudChlKTsgfSk7XG4gIH0pO1xuICB3aGlsZSAodGhpcy5wZW5kaW5nQWN0aW9ucy5sZW5ndGgpIHtcbiAgICB2YXIgZW50cnkgPSB0aGlzLnBlbmRpbmdBY3Rpb25zLnNoaWZ0KCk7XG4gICAgd2l0aEN1cnJlbnRGYWNldChlbnRyeS5mYWNldCwgZW50cnkuYWN0aW9uKTtcbiAgfVxuICB0aGlzLmZhY2V0cy5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgd2l0aEN1cnJlbnRGYWNldChmLCBmdW5jdGlvbiAoKSB7IGYucmVmcmVzaCgpOyB9KTtcbiAgfSk7XG4gIHRoaXMuY2hlY2tGb3JUZXJtaW5hdGlvbigpO1xufTtcblxuQWN0b3IucHJvdG90eXBlLnB1c2hBY3Rpb24gPSBmdW5jdGlvbiAoYSkge1xuICB0aGlzLnBlbmRpbmdBY3Rpb25zLnB1c2goe2ZhY2V0OiBGYWNldC5jdXJyZW50LCBhY3Rpb246IGF9KTtcbn07XG5cbkFjdG9yLnByb3RvdHlwZS5hZGRGYWNldCA9IGZ1bmN0aW9uKGZhY2V0KSB7XG4gIHRoaXMuZmFjZXRzID0gdGhpcy5mYWNldHMuYWRkKGZhY2V0KTtcbn07XG5cbkFjdG9yLnByb3RvdHlwZS5yZW1vdmVGYWNldCA9IGZ1bmN0aW9uKGZhY2V0KSB7XG4gIHRoaXMuZmFjZXRzID0gdGhpcy5mYWNldHMucmVtb3ZlKGZhY2V0KTtcbn07XG5cbkFjdG9yLnByb3RvdHlwZS5jaGVja0ZvclRlcm1pbmF0aW9uID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLmZhY2V0cy5pc0VtcHR5KCkpIHtcbiAgICBEYXRhc3BhY2UuZXhpdCgpO1xuICB9XG59O1xuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5mdW5jdGlvbiBjcmVhdGVGYWNldCgpIHtcbiAgcmV0dXJuIG5ldyBGYWNldChEYXRhc3BhY2UuYWN0aXZlQmVoYXZpb3IoKSk7XG59XG5cbmZ1bmN0aW9uIEZhY2V0KGFjdG9yKSB7XG4gIHRoaXMuYWN0b3IgPSBhY3RvcjtcbiAgdGhpcy5lbmRwb2ludHMgPSBJbW11dGFibGUuTWFwKCk7XG4gIHRoaXMuaW5pdEJsb2NrcyA9IEltbXV0YWJsZS5MaXN0KCk7XG4gIHRoaXMuZG9uZUJsb2NrcyA9IEltbXV0YWJsZS5MaXN0KCk7XG4gIHRoaXMuY2hpbGRyZW4gPSBJbW11dGFibGUuU2V0KCk7XG4gIHRoaXMucGFyZW50ID0gRmFjZXQuY3VycmVudDtcbiAgdGhpcy50ZXJtaW5hdGVkID0gZmFsc2U7XG59XG5cbkZhY2V0LmN1cnJlbnQgPSBudWxsO1xuXG5mdW5jdGlvbiB3aXRoQ3VycmVudEZhY2V0KGZhY2V0LCBmKSB7XG4gIHZhciBwcmV2aW91cyA9IEZhY2V0LmN1cnJlbnQ7XG4gIEZhY2V0LmN1cnJlbnQgPSBmYWNldDtcbiAgdmFyIHJlc3VsdDtcbiAgdHJ5IHtcbiAgICByZXN1bHQgPSBmKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBGYWNldC5jdXJyZW50ID0gcHJldmlvdXM7XG4gICAgdGhyb3cgZTtcbiAgfVxuICBGYWNldC5jdXJyZW50ID0gcHJldmlvdXM7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbkZhY2V0LnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uKGUpIHtcbiAgdmFyIGZhY2V0ID0gdGhpcztcbiAgZmFjZXQuZW5kcG9pbnRzLmZvckVhY2goZnVuY3Rpb24oZW5kcG9pbnQpIHtcbiAgICBlbmRwb2ludC5oYW5kbGVyRm4uY2FsbChmYWNldC5hY3Rvci5zdGF0ZSwgZSk7XG4gIH0pO1xufTtcblxuRmFjZXQucHJvdG90eXBlLmFkZEFzc2VydGlvbiA9IGZ1bmN0aW9uKGFzc2VydGlvbkZuKSB7XG4gIHJldHVybiB0aGlzLmFkZEVuZHBvaW50KG5ldyBFbmRwb2ludChhc3NlcnRpb25GbiwgZnVuY3Rpb24oZSkge30pKTtcbn07XG5cbkZhY2V0LnByb3RvdHlwZS5hZGRPbkV2ZW50SGFuZGxlciA9IGZ1bmN0aW9uKGhhbmRsZXIpIHtcbiAgdmFyIGZhY2V0ID0gdGhpcztcbiAgcmV0dXJuIHRoaXMuYWRkRW5kcG9pbnQobmV3IEVuZHBvaW50KGZ1bmN0aW9uICgpIHsgcmV0dXJuIFBhdGNoLmVtcHR5UGF0Y2g7IH0sIGZ1bmN0aW9uIChlKSB7XG4gICAgZmFjZXQuYWN0b3IucHVzaEFjdGlvbihmdW5jdGlvbiAoKSB7IGhhbmRsZXIoZSk7IH0pO1xuICB9KSk7XG59O1xuXG5GYWNldC5wcm90b3R5cGUub25FdmVudCA9IGZ1bmN0aW9uKGlzVGVybWluYWwsIGV2ZW50VHlwZSwgc3Vic2NyaXB0aW9uRm4sIHByb2plY3Rpb25GbiwgaGFuZGxlckZuKSB7XG4gIHZhciBmYWNldCA9IHRoaXM7XG4gIHN3aXRjaCAoZXZlbnRUeXBlKSB7XG5cbiAgY2FzZSAnbWVzc2FnZSc6XG4gICAgcmV0dXJuIHRoaXMuYWRkRW5kcG9pbnQobmV3IEVuZHBvaW50KHN1YnNjcmlwdGlvbkZuLCBmdW5jdGlvbihlKSB7XG4gICAgICBpZiAoZS50eXBlID09PSAnbWVzc2FnZScpIHtcbiAgICAgICAgdmFyIHByb2ogPSBwcm9qZWN0aW9uRm4uY2FsbChmYWNldC5hY3Rvci5zdGF0ZSk7XG4gICAgICAgIHZhciBzcGVjID0gUGF0Y2gucHJlcGVuZEF0TWV0YShwcm9qLmFzc2VydGlvbiwgcHJvai5tZXRhbGV2ZWwpO1xuICAgICAgICB2YXIgbWF0Y2ggPSBUcmllLm1hdGNoUGF0dGVybihlLm1lc3NhZ2UsIHNwZWMpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhtYXRjaCk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgIGlmIChpc1Rlcm1pbmFsKSB7IGZhY2V0LnRlcm1pbmF0ZSgpOyB9XG4gICAgICAgICAgZmFjZXQuYWN0b3IucHVzaEFjdGlvbihmdW5jdGlvbiAoKSB7IFV0aWwua3dBcHBseShoYW5kbGVyRm4sIGZhY2V0LmFjdG9yLnN0YXRlLCBtYXRjaCk7IH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSkpO1xuXG4gIGNhc2UgJ2Fzc2VydGVkJzogLyogZmFsbCB0aHJvdWdoICovXG4gIGNhc2UgJ3JldHJhY3RlZCc6XG4gICAgcmV0dXJuIHRoaXMuYWRkRW5kcG9pbnQobmV3IEVuZHBvaW50KHN1YnNjcmlwdGlvbkZuLCBmdW5jdGlvbihlKSB7XG4gICAgICBpZiAoZS50eXBlID09PSAnc3RhdGVDaGFuZ2UnKSB7XG4gICAgICAgIHZhciBwcm9qID0gcHJvamVjdGlvbkZuLmNhbGwoZmFjZXQuYWN0b3Iuc3RhdGUpO1xuICAgICAgICB2YXIgc3BlYyA9IFBhdGNoLnByZXBlbmRBdE1ldGEocHJvai5hc3NlcnRpb24sIHByb2oubWV0YWxldmVsKTtcbiAgICAgICAgdmFyIG9iamVjdHMgPSBUcmllLnByb2plY3RPYmplY3RzKGV2ZW50VHlwZSA9PT0gJ2Fzc2VydGVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBlLnBhdGNoLmFkZGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGUucGF0Y2gucmVtb3ZlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWMpO1xuICAgICAgICBpZiAob2JqZWN0cyAmJiBvYmplY3RzLnNpemUgPiAwKSB7XG4gICAgICAgICAgdmFyIHNob3VsZFRlcm1pbmF0ZSA9IGlzVGVybWluYWw7XG4gICAgICAgICAgb2JqZWN0cy5mb3JFYWNoKGZ1bmN0aW9uIChvKSB7XG4gICAgICAgICAgICB2YXIgaW5zdGFudGlhdGVkID0gVHJpZS5pbnN0YW50aWF0ZVByb2plY3Rpb24oc3BlYywgbyk7XG4gICAgICAgICAgICBpZiAoZmFjZXQuaW50ZXJlc3RXYXMoZXZlbnRUeXBlLCBpbnN0YW50aWF0ZWQpKSB7XG4gICAgICAgICAgICAgIGlmIChzaG91bGRUZXJtaW5hdGUpIHtcbiAgICAgICAgICAgICAgICBzaG91bGRUZXJtaW5hdGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBmYWNldC50ZXJtaW5hdGUoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBmYWNldC5hY3Rvci5wdXNoQWN0aW9uKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBVdGlsLmt3QXBwbHkoaGFuZGxlckZuLCBmYWNldC5hY3Rvci5zdGF0ZSwgbyk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSkpO1xuXG4gIGNhc2UgJ3Jpc2luZ0VkZ2UnOlxuICAgIHZhciBlbmRwb2ludCA9IG5ldyBFbmRwb2ludChmdW5jdGlvbigpIHsgcmV0dXJuIFBhdGNoLmVtcHR5UGF0Y2g7IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3VmFsdWUgPSBzdWJzY3JpcHRpb25Gbi5jYWxsKGZhY2V0LmFjdG9yLnN0YXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3VmFsdWUgJiYgIXRoaXMuY3VycmVudFZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNUZXJtaW5hbCkgeyBmYWNldC50ZXJtaW5hdGUoKTsgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjZXQuYWN0b3IucHVzaEFjdGlvbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXJGbi5jYWxsKGZhY2V0LmFjdG9yLnN0YXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICBlbmRwb2ludC5jdXJyZW50VmFsdWUgPSBmYWxzZTtcbiAgICByZXR1cm4gdGhpcy5hZGRFbmRwb2ludChlbmRwb2ludCk7XG5cbiAgZGVmYXVsdDpcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBGYWNldCBldmVudFR5cGU6IFwiICsgZXZlbnRUeXBlKTtcbiAgfVxufTtcblxuRmFjZXQucHJvdG90eXBlLmludGVyZXN0V2FzID0gZnVuY3Rpb24oYXNzZXJ0ZWRPclJldHJhY3RlZCwgcGF0KSB7XG4gIGZ1bmN0aW9uIG9yU3RhcihhLCBiKSB7IHJldHVybiAoYSB8fCBiKTsgfVxuICB2YXIgb2xkRXhpc3RzID0gVHJpZS5tYXRjaFZhbHVlKHRoaXMuYWN0b3IucHJldmlvdXNLbm93bGVkZ2UsIHBhdCwgZmFsc2UsIG9yU3Rhcik7XG4gIHZhciBuZXdFeGlzdHMgPSBUcmllLm1hdGNoVmFsdWUodGhpcy5hY3Rvci5rbm93bGVkZ2UsIHBhdCwgZmFsc2UsIG9yU3Rhcik7XG4gIHN3aXRjaCAoYXNzZXJ0ZWRPclJldHJhY3RlZCkge1xuICAgIGNhc2UgJ2Fzc2VydGVkJzpcbiAgICAgIHJldHVybiAhb2xkRXhpc3RzICYmIG5ld0V4aXN0cztcbiAgICBjYXNlICdyZXRyYWN0ZWQnOlxuICAgICAgcmV0dXJuIG9sZEV4aXN0cyAmJiAhbmV3RXhpc3RzO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIGFzc2VydGVkT3JSZXRyYWN0ZWQgaW4gRmFjZXQuaW50ZXJlc3RXYXM6IFwiICsgYXNzZXJ0ZWRPclJldHJhY3RlZCk7XG4gIH1cbn07XG5cbkZhY2V0LnByb3RvdHlwZS5hZGRFbmRwb2ludCA9IGZ1bmN0aW9uKGVuZHBvaW50KSB7XG4gIHZhciBwYXRjaCA9IGVuZHBvaW50LnN1YnNjcmlwdGlvbkZuLmNhbGwodGhpcy5hY3Rvci5zdGF0ZSk7XG4gIHZhciByID0gdGhpcy5hY3Rvci5tdXguYWRkU3RyZWFtKHBhdGNoKTtcbiAgdGhpcy5lbmRwb2ludHMgPSB0aGlzLmVuZHBvaW50cy5zZXQoci5waWQsIGVuZHBvaW50KTtcbiAgRGF0YXNwYWNlLnN0YXRlQ2hhbmdlKHIuZGVsdGFBZ2dyZWdhdGUpO1xuICByZXR1cm4gdGhpczsgLy8gZm9yIGNoYWluaW5nXG59O1xuXG5GYWNldC5wcm90b3R5cGUuYWRkSW5pdEJsb2NrID0gZnVuY3Rpb24odGh1bmspIHtcbiAgdGhpcy5pbml0QmxvY2tzID0gdGhpcy5pbml0QmxvY2tzLnB1c2godGh1bmspO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkZhY2V0LnByb3RvdHlwZS5hZGREb25lQmxvY2sgPSBmdW5jdGlvbih0aHVuaykge1xuICB0aGlzLmRvbmVCbG9ja3MgPSB0aGlzLmRvbmVCbG9ja3MucHVzaCh0aHVuayk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRmFjZXQucHJvdG90eXBlLnJlZnJlc2ggPSBmdW5jdGlvbigpIHtcbiAgdmFyIGZhY2V0ID0gdGhpcztcbiAgdmFyIGFnZ3JlZ2F0ZSA9IFBhdGNoLmVtcHR5UGF0Y2g7XG4gIHRoaXMuZW5kcG9pbnRzLmZvckVhY2goZnVuY3Rpb24oZW5kcG9pbnQsIGVpZCkge1xuICAgIHZhciBwYXRjaCA9IFBhdGNoLnJldHJhY3QoX18pLmFuZFRoZW4oZW5kcG9pbnQuc3Vic2NyaXB0aW9uRm4uY2FsbChmYWNldC5hY3Rvci5zdGF0ZSkpO1xuICAgIHZhciByID0gZmFjZXQuYWN0b3IubXV4LnVwZGF0ZVN0cmVhbShlaWQsIHBhdGNoKTtcbiAgICBhZ2dyZWdhdGUgPSBhZ2dyZWdhdGUuYW5kVGhlbihyLmRlbHRhQWdncmVnYXRlKTtcbiAgfSk7XG4gIERhdGFzcGFjZS5zdGF0ZUNoYW5nZShhZ2dyZWdhdGUpO1xufTtcblxuRmFjZXQucHJvdG90eXBlLmNvbXBsZXRlQnVpbGQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGZhY2V0ID0gdGhpcztcbiAgdGhpcy5hY3Rvci5hZGRGYWNldCh0aGlzKTtcbiAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgdGhpcy5wYXJlbnQuY2hpbGRyZW4gPSB0aGlzLnBhcmVudC5jaGlsZHJlbi5hZGQodGhpcyk7XG4gIH1cbiAgd2l0aEN1cnJlbnRGYWNldChmYWNldCwgZnVuY3Rpb24gKCkge1xuICAgIGZhY2V0LmluaXRCbG9ja3MuZm9yRWFjaChmdW5jdGlvbihiKSB7IGIuY2FsbChmYWNldC5hY3Rvci5zdGF0ZSk7IH0pO1xuICB9KTtcbiAgdmFyIGluaXRpYWxFdmVudCA9IF9EYXRhc3BhY2Uuc3RhdGVDaGFuZ2UobmV3IFBhdGNoLlBhdGNoKGZhY2V0LmFjdG9yLmtub3dsZWRnZSwgVHJpZS5lbXB0eVRyaWUpKTtcbiAgd2l0aEN1cnJlbnRGYWNldChmYWNldCwgZnVuY3Rpb24gKCkgeyBmYWNldC5oYW5kbGVFdmVudChpbml0aWFsRXZlbnQpOyB9KTtcbn07XG5cbkZhY2V0LnByb3RvdHlwZS50ZXJtaW5hdGUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGZhY2V0ID0gdGhpcztcblxuICBpZiAoZmFjZXQudGVybWluYXRlZCkgcmV0dXJuO1xuICBmYWNldC50ZXJtaW5hdGVkID0gdHJ1ZTtcblxuICB2YXIgYWdncmVnYXRlID0gUGF0Y2guZW1wdHlQYXRjaDtcbiAgdGhpcy5lbmRwb2ludHMuZm9yRWFjaChmdW5jdGlvbihlbmRwb2ludCwgZWlkKSB7XG4gICAgdmFyIHIgPSBmYWNldC5hY3Rvci5tdXgucmVtb3ZlU3RyZWFtKGVpZCk7XG4gICAgYWdncmVnYXRlID0gYWdncmVnYXRlLmFuZFRoZW4oci5kZWx0YUFnZ3JlZ2F0ZSk7XG4gIH0pO1xuICBEYXRhc3BhY2Uuc3RhdGVDaGFuZ2UoYWdncmVnYXRlKTtcblxuICB0aGlzLmVuZHBvaW50cyA9IEltbXV0YWJsZS5NYXAoKTtcbiAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgdGhpcy5wYXJlbnQuY2hpbGRyZW4gPSB0aGlzLnBhcmVudC5jaGlsZHJlbi5yZW1vdmUodGhpcyk7XG4gIH1cblxuICB0aGlzLmFjdG9yLnJlbW92ZUZhY2V0KHRoaXMpO1xuXG4gIHdpdGhDdXJyZW50RmFjZXQoZmFjZXQsIGZ1bmN0aW9uICgpIHtcbiAgICBmYWNldC5kb25lQmxvY2tzLmZvckVhY2goZnVuY3Rpb24oYikgeyBiLmNhbGwoZmFjZXQuYWN0b3Iuc3RhdGUpOyB9KTtcbiAgfSk7XG5cbiAgdGhpcy5jaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgIGNoaWxkLnRlcm1pbmF0ZSgpO1xuICB9KTtcbn07XG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmZ1bmN0aW9uIEVuZHBvaW50KHN1YnNjcmlwdGlvbkZuLCBoYW5kbGVyRm4pIHtcbiAgdGhpcy5zdWJzY3JpcHRpb25GbiA9IHN1YnNjcmlwdGlvbkZuO1xuICB0aGlzLmhhbmRsZXJGbiA9IGhhbmRsZXJGbjtcbn1cblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxubW9kdWxlLmV4cG9ydHMuc3Bhd25BY3RvciA9IHNwYXduQWN0b3I7XG5tb2R1bGUuZXhwb3J0cy5jcmVhdGVGYWNldCA9IGNyZWF0ZUZhY2V0O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vLyBXZWJTb2NrZXQtYmFzZWQgU3luZGljYXRlIGJyb2tlciBjbGllbnRcblxudmFyIEltbXV0YWJsZSA9IHJlcXVpcmUoJ2ltbXV0YWJsZScpO1xudmFyIFRyaWUgPSByZXF1aXJlKCcuL3RyaWUuanMnKTtcbnZhciBQYXRjaCA9IHJlcXVpcmUoJy4vcGF0Y2guanMnKTtcbnZhciBTdHJ1Y3QgPSByZXF1aXJlKCcuL3N0cnVjdC5qcycpO1xudmFyIERlbWFuZE1hdGNoZXIgPSByZXF1aXJlKCcuL2RlbWFuZC1tYXRjaGVyLmpzJykuRGVtYW5kTWF0Y2hlcjtcbnZhciBDb2RlYyA9IHJlcXVpcmUoJy4vY29kZWMnKTtcblxudmFyIERhdGFzcGFjZV8gPSByZXF1aXJlKFwiLi9kYXRhc3BhY2UuanNcIik7XG52YXIgRGF0YXNwYWNlID0gRGF0YXNwYWNlXy5EYXRhc3BhY2U7XG52YXIgX18gPSBEYXRhc3BhY2VfLl9fO1xudmFyIF8kID0gRGF0YXNwYWNlXy5fJDtcblxudmFyIERFRkFVTFRfUkVDT05ORUNUX0RFTEFZID0gMTAwOyAvLyBtc1xudmFyIE1BWF9SRUNPTk5FQ1RfREVMQVkgPSAzMDAwMDsgLy8gbXNcbnZhciBERUZBVUxUX0lETEVfVElNRU9VVCA9IDMwMDAwMDsgLy8gbXM7IGkuZS4sIDUgbWludXRlc1xudmFyIERFRkFVTFRfUElOR19JTlRFUlZBTCA9IERFRkFVTFRfSURMRV9USU1FT1VUIC0gMTAwMDA7IC8vIG1zXG5cbnZhciB0b0Jyb2tlciA9IFN0cnVjdC5tYWtlQ29uc3RydWN0b3IoJ3RvQnJva2VyJywgWyd1cmwnLCAnYXNzZXJ0aW9uJ10pO1xudmFyIGZyb21Ccm9rZXIgPSBTdHJ1Y3QubWFrZUNvbnN0cnVjdG9yKCdmcm9tQnJva2VyJywgWyd1cmwnLCAnYXNzZXJ0aW9uJ10pO1xudmFyIGJyb2tlckNvbm5lY3Rpb24gPSBTdHJ1Y3QubWFrZUNvbnN0cnVjdG9yKCdicm9rZXJDb25uZWN0aW9uJywgWyd1cmwnXSk7XG52YXIgYnJva2VyQ29ubmVjdGVkID0gU3RydWN0Lm1ha2VDb25zdHJ1Y3RvcignYnJva2VyQ29ubmVjdGVkJywgWyd1cmwnXSk7XG52YXIgZm9yY2VCcm9rZXJEaXNjb25uZWN0ID0gU3RydWN0Lm1ha2VDb25zdHJ1Y3RvcignZm9yY2VCcm9rZXJEaXNjb25uZWN0JywgWyd1cmwnXSk7XG5cbmZ1bmN0aW9uIHNwYXduQnJva2VyQ2xpZW50RHJpdmVyKCkge1xuICB2YXIgVVJMID0gXyQoJ3VybCcpOyAvLyBjYXB0dXJlIHVzZWQgdG8gZXh0cmFjdCBVUkxcbiAgRGF0YXNwYWNlLnNwYXduKFxuICAgIG5ldyBEYXRhc3BhY2UoZnVuY3Rpb24gKCkge1xuICAgICAgRGF0YXNwYWNlLnNwYXduKFxuICAgICAgICBuZXcgRGVtYW5kTWF0Y2hlcihbYnJva2VyQ29ubmVjdGlvbihVUkwpXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2Jyb2tlckNvbm5lY3Rpb24oVVJMKV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXNwYWNlLnNwYXduKG5ldyBCcm9rZXJDbGllbnRDb25uZWN0aW9uKGMudXJsKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZW1hbmRNZXRhTGV2ZWw6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwcGx5TWV0YUxldmVsOiAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICB9KSk7XG59XG5cbmZ1bmN0aW9uIEJyb2tlckNsaWVudENvbm5lY3Rpb24od3N1cmwpIHtcbiAgdGhpcy53c3VybCA9IHdzdXJsO1xuICB0aGlzLnNvY2sgPSBudWxsO1xuXG4gIHRoaXMuc2VuZHNBdHRlbXB0ZWQgPSAwO1xuICB0aGlzLnNlbmRzVHJhbnNtaXR0ZWQgPSAwO1xuICB0aGlzLnJlY2VpdmVDb3VudCA9IDA7XG4gIHRoaXMuY29ubmVjdGlvbkNvdW50ID0gMDtcblxuICB0aGlzLnJlY29ubmVjdERlbGF5ID0gREVGQVVMVF9SRUNPTk5FQ1RfREVMQVk7XG4gIHRoaXMuaWRsZVRpbWVvdXQgPSBERUZBVUxUX0lETEVfVElNRU9VVDtcbiAgdGhpcy5waW5nSW50ZXJ2YWwgPSBERUZBVUxUX1BJTkdfSU5URVJWQUw7XG5cbiAgdGhpcy5sb2NhbEFzc2VydGlvbnMgPSBUcmllLmVtcHR5VHJpZTtcbiAgdGhpcy5jb25uZWN0aW9uSW50ZXJydXB0ZWQgPSBmYWxzZTtcblxuICB0aGlzLmFjdGl2aXR5VGltZXN0YW1wID0gMDtcbiAgdGhpcy5pZGxlVGltZXIgPSBudWxsO1xuICB0aGlzLnBpbmdUaW1lciA9IG51bGw7XG59XG5cbkJyb2tlckNsaWVudENvbm5lY3Rpb24ucHJvdG90eXBlLmNsZWFySGVhcnRiZWF0VGltZXJzID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5pZGxlVGltZXIpIHsgY2xlYXJUaW1lb3V0KHRoaXMuaWRsZVRpbWVyKTsgdGhpcy5pZGxlVGltZXIgPSBudWxsOyB9XG4gIGlmICh0aGlzLnBpbmdUaW1lcikgeyBjbGVhclRpbWVvdXQodGhpcy5waW5nVGltZXIpOyB0aGlzLnBpbmdUaW1lciA9IG51bGw7IH1cbn07XG5cbkJyb2tlckNsaWVudENvbm5lY3Rpb24ucHJvdG90eXBlLnJlY29yZEFjdGl2aXR5ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuYWN0aXZpdHlUaW1lc3RhbXAgPSArKG5ldyBEYXRlKCkpO1xuICB0aGlzLmNsZWFySGVhcnRiZWF0VGltZXJzKCk7XG4gIHRoaXMuaWRsZVRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7IHNlbGYuZm9yY2VjbG9zZSgpOyB9LCB0aGlzLmlkbGVUaW1lb3V0KTtcbiAgdGhpcy5waW5nVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgc2VsZi5zYWZlU2VuZChKU09OLnN0cmluZ2lmeShcInBpbmdcIikpIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBpbmdJbnRlcnZhbCk7XG59O1xuXG5Ccm9rZXJDbGllbnRDb25uZWN0aW9uLnByb3RvdHlwZS5ib290ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnJlY29ubmVjdCgpO1xuICB2YXIgaW5pdGlhbEFzc2VydGlvbnMgPVxuICAgICAgUGF0Y2guc3ViKHRvQnJva2VyKHRoaXMud3N1cmwsIF9fKSwgMSkgLy8gcmVhZCBhc3NlcnRpb25zIHRvIGdvIG91dFxuICAgICAgLmFuZFRoZW4oUGF0Y2guc3ViKFBhdGNoLm9ic2VydmUoZnJvbUJyb2tlcih0aGlzLndzdXJsLCBfXykpLCAxKSkgLy8gYW5kIG1vbml0b3IgaW50ZXJlc3RzXG4gICAgICAuYW5kVGhlbihQYXRjaC5hc3NlcnQoYnJva2VyQ29ubmVjdGlvbih0aGlzLndzdXJsKSkpIC8vIHNpZ25hbCB0byBEZW1hbmRNYXRjaGVyIHRoYXQgd2UgZXhpc3RcbiAgICAgIC5hbmRUaGVuKFBhdGNoLnN1Yihicm9rZXJDb25uZWN0aW9uKHRoaXMud3N1cmwpLCAxKSkgLy8gdHJhY2sgZGVtYW5kXG4gICAgICAuYW5kVGhlbihQYXRjaC5zdWIoZm9yY2VCcm9rZXJEaXNjb25uZWN0KHRoaXMud3N1cmwpLCAxKSlcbiAgO1xuICByZXR1cm4gaW5pdGlhbEFzc2VydGlvbnM7XG59O1xuXG5Ccm9rZXJDbGllbnRDb25uZWN0aW9uLnByb3RvdHlwZS50cmFwZXhpdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5mb3JjZWNsb3NlKCk7XG59O1xuXG5Ccm9rZXJDbGllbnRDb25uZWN0aW9uLnByb3RvdHlwZS5pc0Nvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuc29jayAmJiB0aGlzLnNvY2sucmVhZHlTdGF0ZSA9PT0gdGhpcy5zb2NrLk9QRU47XG59O1xuXG5Ccm9rZXJDbGllbnRDb25uZWN0aW9uLnByb3RvdHlwZS5zYWZlU2VuZCA9IGZ1bmN0aW9uIChtKSB7XG4gIC8vIGNvbnNvbGUubG9nKCdzYWZlU2VuZCcsIG0pO1xuICB0cnkge1xuICAgIHRoaXMuc2VuZHNBdHRlbXB0ZWQrKztcbiAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICB0aGlzLnNvY2suc2VuZChtKTtcbiAgICAgIHRoaXMuc2VuZHNUcmFuc21pdHRlZCsrO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUud2FybihcIlRyYXBwZWQgZXhuIHdoaWxlIHNlbmRpbmdcIiwgZSk7XG4gIH1cbn07XG5cbkJyb2tlckNsaWVudENvbm5lY3Rpb24ucHJvdG90eXBlLnNlbmRQYXRjaCA9IGZ1bmN0aW9uIChwKSB7XG4gIHZhciBqID0gSlNPTi5zdHJpbmdpZnkoQ29kZWMuZW5jb2RlRXZlbnQoU3luZGljYXRlLnN0YXRlQ2hhbmdlKHApKSk7XG4gIHRoaXMuc2FmZVNlbmQoaik7XG59O1xuXG5Ccm9rZXJDbGllbnRDb25uZWN0aW9uLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gIC8vIGNvbnNvbGUubG9nKFwiQnJva2VyQ2xpZW50Q29ubmVjdGlvbi5oYW5kbGVFdmVudFwiLCBlKTtcbiAgc3dpdGNoIChlLnR5cGUpIHtcbiAgICBjYXNlIFwic3RhdGVDaGFuZ2VcIjpcbiAgICAgIGlmIChlLnBhdGNoLnByb2plY3QoUGF0Y2guYXRNZXRhKGJyb2tlckNvbm5lY3Rpb24oXyQpKSkuaGFzUmVtb3ZlZCgpKSB7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKFwiQ2xpZW50IGlzIG5vIGxvbmdlciBpbnRlcmVzdGVkIGluIHRoaXMgY29ubmVjdGlvblwiLCB0aGlzLndzdXJsKTtcbiAgICAgICAgRGF0YXNwYWNlLmV4aXQoKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHBUbyA9IGUucGF0Y2gucHJvamVjdChQYXRjaC5hdE1ldGEodG9Ccm9rZXIoX18sIF8kKSkpO1xuXG4gICAgICB2YXIgcE9ic0Zyb20gPSBlLnBhdGNoLnByb2plY3QoUGF0Y2guYXRNZXRhKFBhdGNoLm9ic2VydmUoZnJvbUJyb2tlcihfXywgXyQpKSkpO1xuICAgICAgcE9ic0Zyb20gPSBuZXcgUGF0Y2guUGF0Y2goXG4gICAgICAgIFRyaWUuY29tcGlsZVBhdHRlcm4odHJ1ZSwgUGF0Y2gub2JzZXJ2ZShUcmllLmVtYmVkZGVkVHJpZShwT2JzRnJvbS5hZGRlZCkpKSxcbiAgICAgICAgVHJpZS5jb21waWxlUGF0dGVybih0cnVlLCBQYXRjaC5vYnNlcnZlKFRyaWUuZW1iZWRkZWRUcmllKHBPYnNGcm9tLnJlbW92ZWQpKSkpO1xuXG4gICAgICB2YXIgbmV3TG9jYWxBc3NlcnRpb25zID0gdGhpcy5sb2NhbEFzc2VydGlvbnM7XG4gICAgICBuZXdMb2NhbEFzc2VydGlvbnMgPSBwVG8ubGFiZWwoSW1tdXRhYmxlLlNldC5vZihcInRvXCIpKS5hcHBseVRvKG5ld0xvY2FsQXNzZXJ0aW9ucyk7XG4gICAgICBuZXdMb2NhbEFzc2VydGlvbnMgPSBwT2JzRnJvbS5sYWJlbChJbW11dGFibGUuU2V0Lm9mKFwib2JzRnJvbVwiKSkuYXBwbHlUbyhuZXdMb2NhbEFzc2VydGlvbnMpO1xuXG4gICAgICB2YXIgdHJ1ZVNldCA9IEltbXV0YWJsZS5TZXQub2YodHJ1ZSk7XG4gICAgICB2YXIgYWx3YXlzVHJ1ZVNldCA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiB0cnVlU2V0OyB9O1xuICAgICAgdmFyIHAgPSBQYXRjaC5jb21wdXRlUGF0Y2goVHJpZS5yZWxhYmVsKHRoaXMubG9jYWxBc3NlcnRpb25zLCBhbHdheXNUcnVlU2V0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyaWUucmVsYWJlbChuZXdMb2NhbEFzc2VydGlvbnMsIGFsd2F5c1RydWVTZXQpKTtcblxuICAgICAgdGhpcy5sb2NhbEFzc2VydGlvbnMgPSBuZXdMb2NhbEFzc2VydGlvbnM7XG4gICAgICAvLyBjb25zb2xlLmxvZyhcImxvY2FsQXNzZXJ0aW9uc1wiKTtcbiAgICAgIC8vIGNvbnNvbGUubG9nKFRyaWUucHJldHR5VHJpZSh0aGlzLmxvY2FsQXNzZXJ0aW9ucykpO1xuICAgICAgLy8gY29uc29sZS5sb2cocC5wcmV0dHkoKSk7XG4gICAgICB0aGlzLnNlbmRQYXRjaChwKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcIm1lc3NhZ2VcIjpcbiAgICAgIHZhciBtID0gZS5tZXNzYWdlO1xuICAgICAgaWYgKFBhdGNoLmF0TWV0YS5pc0NsYXNzT2YobSkpIHtcbiAgICAgICAgbSA9IG1bMF07XG4gICAgICAgIGlmICh0b0Jyb2tlci5pc0NsYXNzT2YobSkpIHtcbiAgICAgICAgICB2YXIgaiA9IEpTT04uc3RyaW5naWZ5KENvZGVjLmVuY29kZUV2ZW50KFN5bmRpY2F0ZS5tZXNzYWdlKG1bMV0pKSk7XG4gICAgICAgICAgdGhpcy5zYWZlU2VuZChqKTtcbiAgICAgICAgfSBlbHNlIGlmIChmb3JjZUJyb2tlckRpc2Nvbm5lY3QuaXNDbGFzc09mKG0pKSB7XG4gICAgICAgICAgdGhpcy5mb3JjZWNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICB9XG59O1xuXG5Ccm9rZXJDbGllbnRDb25uZWN0aW9uLnByb3RvdHlwZS5mb3JjZWNsb3NlID0gZnVuY3Rpb24gKGtlZXBSZWNvbm5lY3REZWxheSkge1xuICBpZiAoIWtlZXBSZWNvbm5lY3REZWxheSkge1xuICAgIHRoaXMucmVjb25uZWN0RGVsYXkgPSBERUZBVUxUX1JFQ09OTkVDVF9ERUxBWTtcbiAgfVxuICB0aGlzLmNsZWFySGVhcnRiZWF0VGltZXJzKCk7XG4gIGlmICh0aGlzLnNvY2spIHtcbiAgICBjb25zb2xlLmxvZyhcIkJyb2tlckNsaWVudENvbm5lY3Rpb24uZm9yY2VjbG9zZSBjYWxsZWRcIik7XG4gICAgdGhpcy5zb2NrLmNsb3NlKCk7XG4gICAgdGhpcy5zb2NrID0gbnVsbDtcbiAgfVxufTtcblxuQnJva2VyQ2xpZW50Q29ubmVjdGlvbi5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuZm9yY2VjbG9zZSh0cnVlKTtcbiAgdGhpcy5jb25uZWN0aW9uQ291bnQrKztcbiAgdGhpcy5zb2NrID0gbmV3IFdlYlNvY2tldCh0aGlzLndzdXJsKTtcbiAgdGhpcy5zb2NrLm9ub3BlbiA9IERhdGFzcGFjZS53cmFwKGZ1bmN0aW9uIChlKSB7IHJldHVybiBzZWxmLm9ub3BlbihlKTsgfSk7XG4gIHRoaXMuc29jay5vbm1lc3NhZ2UgPSBEYXRhc3BhY2Uud3JhcChmdW5jdGlvbiAoZSkge1xuICAgIHNlbGYucmVjZWl2ZUNvdW50Kys7XG4gICAgcmV0dXJuIHNlbGYub25tZXNzYWdlKGUpO1xuICB9KTtcbiAgdGhpcy5zb2NrLm9uY2xvc2UgPSBEYXRhc3BhY2Uud3JhcChmdW5jdGlvbiAoZSkgeyByZXR1cm4gc2VsZi5vbmNsb3NlKGUpOyB9KTtcbn07XG5cbkJyb2tlckNsaWVudENvbm5lY3Rpb24ucHJvdG90eXBlLm9ub3BlbiA9IGZ1bmN0aW9uIChlKSB7XG4gIGNvbnNvbGUubG9nKFwiY29ubmVjdGVkIHRvIFwiICsgdGhpcy5zb2NrLnVybCk7XG4gIHRoaXMucmVjb3JkQWN0aXZpdHkoKTtcbiAgRGF0YXNwYWNlLnN0YXRlQ2hhbmdlKFBhdGNoLmFzc2VydChicm9rZXJDb25uZWN0ZWQodGhpcy53c3VybCksIDEpKTtcbiAgdGhpcy5yZWNvbm5lY3REZWxheSA9IERFRkFVTFRfUkVDT05ORUNUX0RFTEFZO1xuICB0aGlzLnNlbmRQYXRjaCgobmV3IFBhdGNoLlBhdGNoKHRoaXMubG9jYWxBc3NlcnRpb25zLCBUcmllLmVtcHR5VHJpZSkpLnN0cmlwKCkpO1xufTtcblxuQnJva2VyQ2xpZW50Q29ubmVjdGlvbi5wcm90b3R5cGUub25tZXNzYWdlID0gZnVuY3Rpb24gKHdzZSkge1xuICAvLyBjb25zb2xlLmxvZyhcIm9ubWVzc2FnZVwiLCB3c2UpO1xuICB0aGlzLnJlY29yZEFjdGl2aXR5KCk7XG5cbiAgdmFyIGogPSBKU09OLnBhcnNlKHdzZS5kYXRhLCBTdHJ1Y3QucmV2aXZlcik7XG4gIGlmIChqID09PSBcInBpbmdcIikge1xuICAgIHRoaXMuc2FmZVNlbmQoSlNPTi5zdHJpbmdpZnkoXCJwb25nXCIpKTtcbiAgICByZXR1cm47XG4gIH0gZWxzZSBpZiAoaiA9PT0gXCJwb25nXCIpIHtcbiAgICByZXR1cm47IC8vIHJlY29yZEFjdGl2aXR5IGFscmVhZHkgdG9vayBjYXJlIG9mIG91ciB0aW1lcnNcbiAgfVxuXG4gIHZhciBlID0gQ29kZWMuZGVjb2RlQWN0aW9uKGopO1xuICBzd2l0Y2ggKGUudHlwZSkge1xuICAgIGNhc2UgXCJzdGF0ZUNoYW5nZVwiOiB7XG4gICAgICB2YXIgYWRkZWQgPSBmcm9tQnJva2VyKHRoaXMud3N1cmwsIFRyaWUuZW1iZWRkZWRUcmllKGUucGF0Y2guYWRkZWQpKTtcbiAgICAgIHZhciByZW1vdmVkID0gZnJvbUJyb2tlcih0aGlzLndzdXJsLCBUcmllLmVtYmVkZGVkVHJpZShlLnBhdGNoLnJlbW92ZWQpKTtcbiAgICAgIHZhciBwID0gUGF0Y2guYXNzZXJ0KGFkZGVkLCAxKS5hbmRUaGVuKFBhdGNoLnJldHJhY3QocmVtb3ZlZCwgMSkpO1xuICAgICAgaWYgKCFwLmlzRW1wdHkoKSkge1xuICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uSW50ZXJydXB0ZWQpIHtcbiAgICAgICAgICBwID0gUGF0Y2gucmV0cmFjdChmcm9tQnJva2VyKHRoaXMud3N1cmwsIF9fKSwgMSkuYW5kVGhlbihwKTtcbiAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JbnRlcnJ1cHRlZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCdhcHBseWluZyBpbmNvbWluZyBzdGF0ZUNoYW5nZScpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhwLnByZXR0eSgpKTtcbiAgICAgICAgRGF0YXNwYWNlLnN0YXRlQ2hhbmdlKHApO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNhc2UgXCJtZXNzYWdlXCI6IHtcbiAgICAgIERhdGFzcGFjZS5zZW5kKGZyb21Ccm9rZXIodGhpcy53c3VybCwgZS5tZXNzYWdlKSwgMSk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbn07XG5cbkJyb2tlckNsaWVudENvbm5lY3Rpb24ucHJvdG90eXBlLm9uY2xvc2UgPSBmdW5jdGlvbiAoZSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgLy8gY29uc29sZS5sb2coXCJvbmNsb3NlXCIsIGUpO1xuICBEYXRhc3BhY2Uuc3RhdGVDaGFuZ2UoUGF0Y2gucmV0cmFjdChicm9rZXJDb25uZWN0ZWQodGhpcy53c3VybCksIDEpKTtcbiAgdGhpcy5jb25uZWN0aW9uSW50ZXJydXB0ZWQgPSB0cnVlO1xuXG4gIGNvbnNvbGUubG9nKFwicmVjb25uZWN0aW5nIHRvIFwiICsgdGhpcy53c3VybCArIFwiIGluIFwiICsgdGhpcy5yZWNvbm5lY3REZWxheSArIFwibXNcIik7XG4gIHNldFRpbWVvdXQoRGF0YXNwYWNlLndyYXAoZnVuY3Rpb24gKCkgeyBzZWxmLnJlY29ubmVjdCgpOyB9KSwgdGhpcy5yZWNvbm5lY3REZWxheSk7XG5cbiAgdGhpcy5yZWNvbm5lY3REZWxheSA9IHRoaXMucmVjb25uZWN0RGVsYXkgKiAxLjYxOCArIChNYXRoLnJhbmRvbSgpICogMTAwMCk7XG4gIHRoaXMucmVjb25uZWN0RGVsYXkgPVxuICAgIHRoaXMucmVjb25uZWN0RGVsYXkgPiBNQVhfUkVDT05ORUNUX0RFTEFZXG4gICAgPyBNQVhfUkVDT05ORUNUX0RFTEFZICsgKE1hdGgucmFuZG9tKCkgKiAxMDAwKVxuICAgIDogdGhpcy5yZWNvbm5lY3REZWxheTtcbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy50b0Jyb2tlciA9IHRvQnJva2VyO1xubW9kdWxlLmV4cG9ydHMuZnJvbUJyb2tlciA9IGZyb21Ccm9rZXI7XG5tb2R1bGUuZXhwb3J0cy5icm9rZXJDb25uZWN0aW9uID0gYnJva2VyQ29ubmVjdGlvbjtcbm1vZHVsZS5leHBvcnRzLmJyb2tlckNvbm5lY3RlZCA9IGJyb2tlckNvbm5lY3RlZDtcbm1vZHVsZS5leHBvcnRzLmZvcmNlQnJva2VyRGlzY29ubmVjdCA9IGZvcmNlQnJva2VyRGlzY29ubmVjdDtcblxubW9kdWxlLmV4cG9ydHMuc3Bhd25Ccm9rZXJDbGllbnREcml2ZXIgPSBzcGF3bkJyb2tlckNsaWVudERyaXZlcjtcbm1vZHVsZS5leHBvcnRzLkJyb2tlckNsaWVudENvbm5lY3Rpb24gPSBCcm9rZXJDbGllbnRDb25uZWN0aW9uO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vLyBXaXJlIHByb3RvY29sIHJlcHJlc2VudGF0aW9uIG9mIGV2ZW50cyBhbmQgYWN0aW9uc1xuXG52YXIgVHJpZSA9IHJlcXVpcmUoJy4vdHJpZS5qcycpO1xudmFyIFBhdGNoID0gcmVxdWlyZSgnLi9wYXRjaC5qcycpO1xudmFyIFN0cnVjdCA9IHJlcXVpcmUoJy4vc3RydWN0LmpzJyk7XG5cbmZ1bmN0aW9uIF9lbmNvZGUoZSkge1xuICBzd2l0Y2ggKGUudHlwZSkge1xuICAgIGNhc2UgXCJzdGF0ZUNoYW5nZVwiOlxuICAgICAgcmV0dXJuIFtcInBhdGNoXCIsIGUucGF0Y2gudG9KU09OKCldO1xuICAgIGNhc2UgXCJtZXNzYWdlXCI6XG4gICAgICByZXR1cm4gW1wibWVzc2FnZVwiLCBlLm1lc3NhZ2VdO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9kZWNvZGUod2hhdCkge1xuICByZXR1cm4gZnVuY3Rpb24gKGopIHtcbiAgICBzd2l0Y2ggKGpbMF0pIHtcbiAgICAgIGNhc2UgXCJwYXRjaFwiOlxuICAgICAgICByZXR1cm4gU3luZGljYXRlLnN0YXRlQ2hhbmdlKFBhdGNoLmZyb21KU09OKGpbMV0pKTtcbiAgICAgIGNhc2UgXCJtZXNzYWdlXCI6XG4gICAgICAgIHJldHVybiBTeW5kaWNhdGUubWVzc2FnZShqWzFdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgSlNPTi1lbmNvZGVkIFwiICsgd2hhdCArIFwiOiBcIiArIEpTT04uc3RyaW5naWZ5KGopKTtcbiAgICB9XG4gIH07XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5lbmNvZGVFdmVudCA9IF9lbmNvZGU7XG5tb2R1bGUuZXhwb3J0cy5kZWNvZGVFdmVudCA9IF9kZWNvZGUoXCJldmVudFwiKTtcbm1vZHVsZS5leHBvcnRzLmVuY29kZUFjdGlvbiA9IF9lbmNvZGU7XG5tb2R1bGUuZXhwb3J0cy5kZWNvZGVBY3Rpb24gPSBfZGVjb2RlKFwiYWN0aW9uXCIpO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBJbW11dGFibGUgPSByZXF1aXJlKCdpbW11dGFibGUnKTtcbnZhciBQYXRjaCA9IHJlcXVpcmUoJy4vcGF0Y2guanMnKTtcbnZhciBNdXggPSByZXF1aXJlKCcuL211eC5qcycpO1xuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4vKiBFdmVudHMgYW5kIEFjdGlvbnMgKi9cblxuZnVuY3Rpb24gc3RhdGVDaGFuZ2UocGF0Y2gpIHtcbiAgcmV0dXJuIHsgdHlwZTogJ3N0YXRlQ2hhbmdlJywgcGF0Y2g6IHBhdGNoIH07XG59XG5cbmZ1bmN0aW9uIG1lc3NhZ2UoYm9keSkge1xuICByZXR1cm4geyB0eXBlOiAnbWVzc2FnZScsIG1lc3NhZ2U6IGJvZHkgfTtcbn1cblxuZnVuY3Rpb24gc3Bhd24oYmVoYXZpb3IpIHtcbiAgcmV0dXJuIHsgdHlwZTogJ3NwYXduJywgYmVoYXZpb3I6IGJlaGF2aW9yIH07XG59XG5cbmZ1bmN0aW9uIHRlcm1pbmF0ZSgpIHtcbiAgcmV0dXJuIHsgdHlwZTogJ3Rlcm1pbmF0ZScgfTtcbn1cblxuZnVuY3Rpb24gdGVybWluYXRlRGF0YXNwYWNlKCkge1xuICByZXR1cm4geyB0eXBlOiAndGVybWluYXRlRGF0YXNwYWNlJyB9O1xufVxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4vKiBEYXRhc3BhY2UgKi9cblxuZnVuY3Rpb24gRGF0YXNwYWNlKGJvb3RGbikge1xuICB0aGlzLnBlbmRpbmdBY3Rpb25zID0gSW1tdXRhYmxlLkxpc3QoKTsgLy8gb2YgW3BpZCwgQWN0aW9uXVxuICB0aGlzLnByb2Nlc3NUYWJsZSA9IEltbXV0YWJsZS5NYXAoKTsgLy8gcGlkIC0+IEJlaGF2aW9yXG4gIHRoaXMucnVubmFibGVQaWRzID0gSW1tdXRhYmxlLlNldCgpOyAvLyBvZiBwaWRcbiAgdGhpcy5tdXggPSBuZXcgTXV4Lk11eCgpO1xuICB0aGlzLm9uU3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAobXV4LCBkZWx0YUFnZ3JlZ2F0ZSkge307XG4gIHRoaXMuYXNDaGlsZCgnbWV0YScsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJvb3RGbigpIH0sIHRydWUpO1xufVxuXG4vLyBDbGFzcyBzdGF0ZSBhbmQgbWV0aG9kc1xuXG5EYXRhc3BhY2Uubm9pc3kgPSBmYWxzZTtcbkRhdGFzcGFjZS5zdGFjayA9IEltbXV0YWJsZS5MaXN0KCk7XG5cbkRhdGFzcGFjZS5jdXJyZW50ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gRGF0YXNwYWNlLnN0YWNrLmxhc3QoKS5kYXRhc3BhY2U7XG59O1xuXG5EYXRhc3BhY2UuYWN0aXZlUGlkID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gRGF0YXNwYWNlLnN0YWNrLmxhc3QoKS5hY3RpdmVQaWQ7XG59O1xuXG5EYXRhc3BhY2UuYWN0aXZlQmVoYXZpb3IgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBlbnRyeSA9IERhdGFzcGFjZS5zdGFjay5sYXN0KCk7XG4gIHZhciBwID0gZW50cnkuZGF0YXNwYWNlLnByb2Nlc3NUYWJsZS5nZXQoZW50cnkuYWN0aXZlUGlkKTtcbiAgcmV0dXJuIHAgPyBwLmJlaGF2aW9yIDogbnVsbDtcbn07XG5cbkRhdGFzcGFjZS53aXRoRGF0YXNwYWNlU3RhY2sgPSBmdW5jdGlvbiAoc3RhY2ssIGYpIHtcbiAgdmFyIG9sZFN0YWNrID0gRGF0YXNwYWNlLnN0YWNrO1xuICBEYXRhc3BhY2Uuc3RhY2sgPSBzdGFjaztcbiAgdmFyIHJlc3VsdDtcbiAgdHJ5IHtcbiAgICByZXN1bHQgPSBmKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBEYXRhc3BhY2Uuc3RhY2sgPSBvbGRTdGFjaztcbiAgICB0aHJvdyBlO1xuICB9XG4gIERhdGFzcGFjZS5zdGFjayA9IG9sZFN0YWNrO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuRGF0YXNwYWNlLndyYXAgPSBmdW5jdGlvbiAoZikge1xuICB2YXIgc2F2ZWRTdGFjayA9IERhdGFzcGFjZS5zdGFjaztcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYWN0dWFscyA9IGFyZ3VtZW50cztcbiAgICByZXR1cm4gRGF0YXNwYWNlLndpdGhEYXRhc3BhY2VTdGFjayhzYXZlZFN0YWNrLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gRGF0YXNwYWNlLmN1cnJlbnQoKS5hc0NoaWxkKERhdGFzcGFjZS5hY3RpdmVQaWQoKSwgZnVuY3Rpb24gKCkge1xuXHRyZXR1cm4gZi5hcHBseShudWxsLCBhY3R1YWxzKTtcbiAgICAgIH0pO1xuICAgICAgRGF0YXNwYWNlLnN0YWNrLnJldmVyc2UoKS5mb3JFYWNoKGZ1bmN0aW9uIChlbnRyeSkge1xuXHRlbnRyeS5kYXRhc3BhY2UubWFya1J1bm5hYmxlKGVudHJ5LmFjdGl2ZVBpZCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG4gIH07XG59O1xuXG5EYXRhc3BhY2UuZW5xdWV1ZUFjdGlvbiA9IGZ1bmN0aW9uIChhY3Rpb24pIHtcbiAgdmFyIGVudHJ5ID0gRGF0YXNwYWNlLnN0YWNrLmxhc3QoKTtcbiAgZW50cnkuZGF0YXNwYWNlLmVucXVldWVBY3Rpb24oZW50cnkuYWN0aXZlUGlkLCBhY3Rpb24pO1xufTtcblxuRGF0YXNwYWNlLnNlbmQgPSBmdW5jdGlvbiAoYm9keSwgbWV0YUxldmVsKSB7XG4gIERhdGFzcGFjZS5lbnF1ZXVlQWN0aW9uKG1lc3NhZ2UoUGF0Y2gucHJlcGVuZEF0TWV0YShib2R5LCBtZXRhTGV2ZWwgfHwgMCkpKTtcbn07XG5cbkRhdGFzcGFjZS5zdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChwYXRjaCkge1xuICBEYXRhc3BhY2UuZW5xdWV1ZUFjdGlvbihzdGF0ZUNoYW5nZShwYXRjaCkpO1xufTtcblxuRGF0YXNwYWNlLnNwYXduID0gZnVuY3Rpb24gKGJlaGF2aW9yKSB7XG4gIERhdGFzcGFjZS5lbnF1ZXVlQWN0aW9uKHNwYXduKGJlaGF2aW9yKSk7XG59O1xuXG5EYXRhc3BhY2UuZXhpdCA9IGZ1bmN0aW9uIChleG4pIHtcbiAgRGF0YXNwYWNlLmN1cnJlbnQoKS5raWxsKERhdGFzcGFjZS5hY3RpdmVQaWQoKSwgZXhuKTtcbn07XG5cbkRhdGFzcGFjZS5leGl0RGF0YXNwYWNlID0gZnVuY3Rpb24gKCkge1xuICBEYXRhc3BhY2UuZW5xdWV1ZUFjdGlvbih0ZXJtaW5hdGVEYXRhc3BhY2UoKSk7XG59O1xuXG5EYXRhc3BhY2UuaW5lcnRCZWhhdmlvciA9IGZ1bmN0aW9uIChvbGRCZWhhdmlvcikge1xuICB2YXIgYiA9IHsgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uIChlKSB7fSB9O1xuICBpZiAoJ25hbWUnIGluIG9sZEJlaGF2aW9yKSB7XG4gICAgYi5uYW1lID0gb2xkQmVoYXZpb3IubmFtZTtcbiAgfVxuICByZXR1cm4gYjtcbn07XG5cbi8vIEluc3RhbmNlIG1ldGhvZHNcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5kZWJ1Z05hbWUgPSBmdW5jdGlvbiAocGlkKSB7XG4gIHZhciBwID0gdGhpcy5wcm9jZXNzVGFibGUuZ2V0KHBpZCwgbnVsbCk7XG4gIGlmIChwID09PSBudWxsKSB7XG4gICAgcmV0dXJuICcoZGVhZClbJyArIHBpZCArICddJztcbiAgfVxuICBpZiAoJ25hbWUnIGluIHAuYmVoYXZpb3IpIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocC5iZWhhdmlvci5uYW1lKSArICdbJyArIHBpZCArICddJztcbiAgfVxuICByZXR1cm4gJyhhbm9uKVsnICsgcGlkICsgJ10nO1xufTtcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5hc0NoaWxkID0gZnVuY3Rpb24gKHBpZCwgZiwgb21pdExpdmVuZXNzQ2hlY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgcCA9IHRoaXMucHJvY2Vzc1RhYmxlLmdldChwaWQsIG51bGwpO1xuICBpZiAoIW9taXRMaXZlbmVzc0NoZWNrICYmIChwID09PSBudWxsKSkge1xuICAgIGNvbnNvbGUud2FybihcIkRhdGFzcGFjZS5hc0NoaWxkIGVsaWRpbmcgaW52b2NhdGlvbiBvZiBkZWFkIHByb2Nlc3NcIiwgdGhpcy5kZWJ1Z05hbWUocGlkKSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmV0dXJuIERhdGFzcGFjZS53aXRoRGF0YXNwYWNlU3RhY2soXG4gICAgRGF0YXNwYWNlLnN0YWNrLnB1c2goeyBkYXRhc3BhY2U6IHRoaXMsIGFjdGl2ZVBpZDogcGlkIH0pLFxuICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyeSB7XG5cdHJldHVybiBmKHApO1xuICAgICAgfSBjYXRjaCAoZSkge1xuXHRzZWxmLmtpbGwocGlkLCBlKTtcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cbkRhdGFzcGFjZS5wcm90b3R5cGUua2lsbCA9IGZ1bmN0aW9uIChwaWQsIGV4bikge1xuICBpZiAoZXhuKSB7XG4gICAgaWYgKGV4bi5zdGFjaykge1xuICAgICAgY29uc29sZS5lcnJvcihcIlByb2Nlc3MgY3Jhc2hlZFwiLCB0aGlzLmRlYnVnTmFtZShwaWQpLCBleG4sIGV4bi5zdGFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJQcm9jZXNzIGNyYXNoZWRcIiwgdGhpcy5kZWJ1Z05hbWUocGlkKSwgZXhuKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoRGF0YXNwYWNlLm5vaXN5KSB7XG4gICAgY29uc29sZS5sb2coXCJQcm9jZXNzIGV4aXRpbmdcIiwgdGhpcy5kZWJ1Z05hbWUocGlkKSk7XG4gIH1cbiAgdmFyIHAgPSB0aGlzLnByb2Nlc3NUYWJsZS5nZXQocGlkKTtcbiAgdGhpcy5wcm9jZXNzVGFibGUgPSB0aGlzLnByb2Nlc3NUYWJsZS5zZXQocGlkLCB7XG4gICAgYmVoYXZpb3I6IERhdGFzcGFjZS5pbmVydEJlaGF2aW9yKHAuYmVoYXZpb3IpXG4gIH0pO1xuICBpZiAocCkge1xuICAgIGlmIChwLmJlaGF2aW9yLnRyYXBleGl0KSB7XG4gICAgICB0aGlzLmFzQ2hpbGQocGlkLCBmdW5jdGlvbiAoKSB7IHJldHVybiBwLmJlaGF2aW9yLnRyYXBleGl0KGV4bik7IH0sIHRydWUpO1xuICAgIH1cbiAgICB0aGlzLmVucXVldWVBY3Rpb24ocGlkLCB0ZXJtaW5hdGUoKSk7XG4gIH1cbn07XG5cbkRhdGFzcGFjZS5wcm90b3R5cGUuYm9vdCA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gTmVlZGVkIGluIG9yZGVyIGZvciBhIG5ldyBEYXRhc3BhY2UgdG8gYmUgbWFya2VkIGFzIFwicnVubmFibGVcIiwgc29cbiAgLy8gaXRzIGluaXRpYWwgYWN0aW9ucyBnZXQgcGVyZm9ybWVkLlxufTtcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gIHN3aXRjaCAoZS50eXBlKSB7XG4gIGNhc2UgJ3N0YXRlQ2hhbmdlJzpcbiAgICB0aGlzLmVucXVldWVBY3Rpb24oJ21ldGEnLCBzdGF0ZUNoYW5nZShlLnBhdGNoLmxpZnQoKSkpO1xuICAgIGJyZWFrO1xuICBjYXNlICdtZXNzYWdlJzpcbiAgICB0aGlzLmVucXVldWVBY3Rpb24oJ21ldGEnLCBtZXNzYWdlKFBhdGNoLmF0TWV0YShlLm1lc3NhZ2UpKSk7XG4gICAgYnJlYWs7XG4gIGRlZmF1bHQ6XG4gICAgdmFyIGV4biA9IG5ldyBFcnJvcihcIkV2ZW50IHR5cGUgXCIgKyBlLnR5cGUgKyBcIiBub3QgdW5kZXJzdG9vZFwiKTtcbiAgICBleG4uZXZlbnQgPSBlO1xuICAgIHRocm93IGV4bjtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkRhdGFzcGFjZS5wcm90b3R5cGUuc3RlcCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuZGlzcGF0Y2hBY3Rpb25zKClcbiAgICAmJiB0aGlzLnJ1blJ1bm5hYmxlUGlkcygpXG4gICAgJiYgKCh0aGlzLnBlbmRpbmdBY3Rpb25zLnNpemUgPiAwKSB8fCAodGhpcy5ydW5uYWJsZVBpZHMuc2l6ZSA+IDApKTtcbn07XG5cbkRhdGFzcGFjZS5wcm90b3R5cGUuZW5xdWV1ZUFjdGlvbiA9IGZ1bmN0aW9uIChwaWQsIGFjdGlvbikge1xuICB0aGlzLnBlbmRpbmdBY3Rpb25zID0gdGhpcy5wZW5kaW5nQWN0aW9ucy5wdXNoKFtwaWQsIGFjdGlvbl0pO1xufTtcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5kaXNwYXRjaEFjdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIGFjdGlvblF1ZXVlID0gdGhpcy5wZW5kaW5nQWN0aW9ucztcbiAgdGhpcy5wZW5kaW5nQWN0aW9ucyA9IEltbXV0YWJsZS5MaXN0KCk7XG4gIHZhciBhbGl2ZSA9IHRydWU7XG4gIGFjdGlvblF1ZXVlLmZvckVhY2goZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgdmFyIHBpZCA9IGVudHJ5WzBdO1xuICAgIHZhciBhY3Rpb24gPSBlbnRyeVsxXTtcbiAgICBpZiAoIXNlbGYuaW50ZXJwcmV0QWN0aW9uKHBpZCwgYWN0aW9uKSkge1xuICAgICAgYWxpdmUgPSBmYWxzZTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gYWxpdmU7XG59O1xuXG5EYXRhc3BhY2UucHJvdG90eXBlLm1hcmtSdW5uYWJsZSA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgdGhpcy5ydW5uYWJsZVBpZHMgPSB0aGlzLnJ1bm5hYmxlUGlkcy5hZGQocGlkKTtcbn07XG5cbkRhdGFzcGFjZS5wcm90b3R5cGUucnVuUnVubmFibGVQaWRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBwaWRTZXQgPSB0aGlzLnJ1bm5hYmxlUGlkcztcbiAgdGhpcy5ydW5uYWJsZVBpZHMgPSBJbW11dGFibGUuU2V0KCk7XG4gIHBpZFNldC5mb3JFYWNoKGZ1bmN0aW9uIChwaWQpIHtcbiAgICB2YXIgY2hpbGRCdXN5ID0gc2VsZi5hc0NoaWxkKHBpZCwgZnVuY3Rpb24gKHApIHtcbiAgICAgIHJldHVybiBwLmJlaGF2aW9yLnN0ZXAgLy8gZXhpc3RzLCBoYXZlbid0IGNhbGxlZCBpdCB5ZXRcblx0JiYgcC5iZWhhdmlvci5zdGVwKCk7XG4gICAgfSk7XG4gICAgaWYgKGNoaWxkQnVzeSkgc2VsZi5tYXJrUnVubmFibGUocGlkKTtcbiAgfSk7XG4gIHJldHVybiB0cnVlO1xufTtcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5pbnRlcnByZXRBY3Rpb24gPSBmdW5jdGlvbiAocGlkLCBhY3Rpb24pIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICBjYXNlICdzdGF0ZUNoYW5nZSc6XG4gICAgICB2YXIgb2xkTXV4ID0gdGhpcy5tdXguc2hhbGxvd0NvcHkoKTtcbiAgICAgIHRoaXMuZGVsaXZlclBhdGNoZXMob2xkTXV4LCB0aGlzLm11eC51cGRhdGVTdHJlYW0ocGlkLCBhY3Rpb24ucGF0Y2gpKTtcbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgY2FzZSAnbWVzc2FnZSc6XG4gICAgICBpZiAoUGF0Y2gub2JzZXJ2ZS5pc0NsYXNzT2YoYWN0aW9uLm1lc3NhZ2UpKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignUHJvY2VzcyAnICsgdGhpcy5kZWJ1Z05hbWUocGlkKSArICcgc2VudCBtZXNzYWdlIGNvbnRhaW5pbmcgcXVlcnknLFxuICAgICAgICAgICAgICAgICAgICAgYWN0aW9uLm1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgaWYgKHBpZCAhPT0gJ21ldGEnICYmIFBhdGNoLmF0TWV0YS5pc0NsYXNzT2YoYWN0aW9uLm1lc3NhZ2UpKSB7XG4gICAgICAgIERhdGFzcGFjZS5zZW5kKGFjdGlvbi5tZXNzYWdlWzBdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubXV4LnJvdXRlTWVzc2FnZShhY3Rpb24ubWVzc2FnZSkuZm9yRWFjaChmdW5jdGlvbiAocGlkKSB7XG5cdCAgc2VsZi5kZWxpdmVyRXZlbnQocGlkLCBhY3Rpb24pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgY2FzZSAnc3Bhd24nOlxuICAgICAgdmFyIG9sZE11eCA9IHRoaXMubXV4LnNoYWxsb3dDb3B5KCk7XG4gICAgICB2YXIgcCA9IHsgYmVoYXZpb3I6IGFjdGlvbi5iZWhhdmlvciB9O1xuICAgICAgdmFyIHBpZCA9IHRoaXMubXV4Lm5leHRQaWQ7XG4gICAgICB0aGlzLnByb2Nlc3NUYWJsZSA9IHRoaXMucHJvY2Vzc1RhYmxlLnNldChwaWQsIHApO1xuICAgICAgdmFyIGluaXRpYWxQYXRjaCA9IFBhdGNoLmVtcHR5UGF0Y2g7XG4gICAgICBpZiAocC5iZWhhdmlvci5ib290KSB7XG4gICAgICAgIGluaXRpYWxQYXRjaCA9IHRoaXMuYXNDaGlsZChwaWQsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHAuYmVoYXZpb3IuYm9vdCgpIH0pO1xuICAgICAgICBpbml0aWFsUGF0Y2ggPSBpbml0aWFsUGF0Y2ggfHwgUGF0Y2guZW1wdHlQYXRjaDtcbiAgICAgICAgdGhpcy5tYXJrUnVubmFibGUocGlkKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZGVsaXZlclBhdGNoZXMob2xkTXV4LCB0aGlzLm11eC5hZGRTdHJlYW0oaW5pdGlhbFBhdGNoKSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIGNhc2UgJ3Rlcm1pbmF0ZSc6XG4gICAgICB2YXIgb2xkTXV4ID0gdGhpcy5tdXguc2hhbGxvd0NvcHkoKTtcbiAgICAgIHRoaXMuZGVsaXZlclBhdGNoZXMob2xkTXV4LCB0aGlzLm11eC5yZW1vdmVTdHJlYW0ocGlkKSk7XG4gICAgICBpZiAoRGF0YXNwYWNlLm5vaXN5KSBjb25zb2xlLmxvZyhcIlByb2Nlc3MgZXhpdCBjb21wbGV0ZVwiLCB0aGlzLmRlYnVnTmFtZShwaWQpKTtcbiAgICAgIHRoaXMucHJvY2Vzc1RhYmxlID0gdGhpcy5wcm9jZXNzVGFibGUucmVtb3ZlKHBpZCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIGNhc2UgJ3Rlcm1pbmF0ZURhdGFzcGFjZSc6XG4gICAgICBEYXRhc3BhY2UuZXhpdCgpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHZhciBleG4gPSBuZXcgRXJyb3IoXCJBY3Rpb24gdHlwZSBcIiArIGFjdGlvbi50eXBlICsgXCIgbm90IHVuZGVyc3Rvb2RcIik7XG4gICAgICBleG4uYWN0aW9uID0gYWN0aW9uO1xuICAgICAgdGhyb3cgZXhuO1xuICB9XG59O1xuXG5EYXRhc3BhY2UucHJvdG90eXBlLmRlbGl2ZXJQYXRjaGVzID0gZnVuY3Rpb24gKG9sZE11eCwgdXBkYXRlU3RyZWFtUmVzdWx0KSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIGV2ZW50cyA9IE11eC5jb21wdXRlRXZlbnRzKG9sZE11eCwgdGhpcy5tdXgsIHVwZGF0ZVN0cmVhbVJlc3VsdCk7XG4gIGV2ZW50cy5ldmVudE1hcC5mb3JFYWNoKGZ1bmN0aW9uIChwYXRjaCwgcGlkKSB7XG4gICAgc2VsZi5kZWxpdmVyRXZlbnQocGlkLCBzdGF0ZUNoYW5nZShwYXRjaCkpO1xuICB9KTtcbiAgZXZlbnRzLm1ldGFFdmVudHMuZm9yRWFjaChEYXRhc3BhY2Uuc3RhdGVDaGFuZ2UpO1xuICBpZiAoIXVwZGF0ZVN0cmVhbVJlc3VsdC5kZWx0YUFnZ3JlZ2F0ZS5pc0VtcHR5KCkpIHtcbiAgICB0aGlzLm9uU3RhdGVDaGFuZ2UodGhpcy5tdXgsIHVwZGF0ZVN0cmVhbVJlc3VsdC5kZWx0YUFnZ3JlZ2F0ZSk7XG4gIH1cbn07XG5cbkRhdGFzcGFjZS5wcm90b3R5cGUuZGVsaXZlckV2ZW50ID0gZnVuY3Rpb24gKHBpZCwgZXZlbnQpIHtcbiAgdmFyIGNoaWxkQnVzeSA9IHRoaXMuYXNDaGlsZChwaWQsIGZ1bmN0aW9uIChwKSB7IHJldHVybiBwLmJlaGF2aW9yLmhhbmRsZUV2ZW50KGV2ZW50KTsgfSk7XG4gIGlmIChjaGlsZEJ1c3kpIHRoaXMubWFya1J1bm5hYmxlKHBpZCk7XG59O1xuXG5EYXRhc3BhY2UucHJvdG90eXBlLnNldE9uU3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICB0aGlzLm9uU3RhdGVDaGFuZ2UgPSBoYW5kbGVyO1xuICB0aGlzLm9uU3RhdGVDaGFuZ2UodGhpcy5tdXgsIFBhdGNoLmVtcHR5UGF0Y2gpO1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLnN0YXRlQ2hhbmdlID0gc3RhdGVDaGFuZ2U7XG5tb2R1bGUuZXhwb3J0cy5tZXNzYWdlID0gbWVzc2FnZTtcbm1vZHVsZS5leHBvcnRzLnNwYXduID0gc3Bhd247XG5tb2R1bGUuZXhwb3J0cy50ZXJtaW5hdGUgPSB0ZXJtaW5hdGU7XG5tb2R1bGUuZXhwb3J0cy50ZXJtaW5hdGVEYXRhc3BhY2UgPSB0ZXJtaW5hdGVEYXRhc3BhY2U7XG5cbm1vZHVsZS5leHBvcnRzLkRhdGFzcGFjZSA9IERhdGFzcGFjZTtcbiIsInZhciBJbW11dGFibGUgPSByZXF1aXJlKCdpbW11dGFibGUnKTtcbnZhciBUcmllID0gcmVxdWlyZSgnLi90cmllLmpzJyk7XG52YXIgUGF0Y2ggPSByZXF1aXJlKCcuL3BhdGNoLmpzJyk7XG52YXIgVXRpbCA9IHJlcXVpcmUoJy4vdXRpbC5qcycpO1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFByb3RvY29sIGJldHdlZW4gRGVtYW5kTWF0Y2hlciBhbmQgdGFza1N1cGVydmlzb3IgZnVuY3Rpb25zXG5cbi8vIEJpdHM6XG52YXIgSVNfQ0hBTkdJTkcgPSAxO1xudmFyIElTX1BSRVNFTlQgID0gMjtcblxuLy8gQml0IGNvbWJpbmF0aW9uczpcbnZhciBMT1cgICAgID0gMCAgICAgICAgICAgICAgICAgICAgICAgICAgO1xudmFyIFJJU0lORyAgPSAgICAgICAgICAgICAgICBJU19DSEFOR0lORyA7XG52YXIgSElHSCAgICA9ICAgSVNfUFJFU0VOVCAgICAgICAgICAgICAgIDtcbnZhciBGQUxMSU5HID0gICBJU19QUkVTRU5UIHwgSVNfQ0hBTkdJTkcgO1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIERlZmF1bHQgdGFzayBzdXBlcnZpc2lvbiBzdHJhdGVneS4gU2VlIHN5bmRpY2F0ZS9kb2MvZGVtYW5kLW1hdGNoZXIubWQuXG5cbmZ1bmN0aW9uIGRlZmF1bHRUYXNrU3VwZXJ2aXNvcihkZW1hbmRTdGF0ZSwgc3VwcGx5U3RhdGUsIHN1cGVydmlzaW9uU3RhdGUsIHRhc2tGbiwgb25UYXNrRXhpdCkge1xuICB2YXIgb2xkRVNJID0gc3VwZXJ2aXNpb25TdGF0ZSA/IHN1cGVydmlzaW9uU3RhdGUuZXhwZWN0U3VwcGx5SW5jcmVhc2UgOiBmYWxzZTtcbiAgdmFyIG9sZEVTRCA9IHN1cGVydmlzaW9uU3RhdGUgPyBzdXBlcnZpc2lvblN0YXRlLmV4cGVjdFN1cHBseURlY3JlYXNlIDogZmFsc2U7XG5cbiAgdmFyIG5ld0VTSSA9IG9sZEVTSTtcbiAgdmFyIG5ld0VTRCA9IG9sZEVTRDtcblxuICBpZiAoKGRlbWFuZFN0YXRlID09PSBGQUxMSU5HKSAmJiAoKHN1cHBseVN0YXRlID09PSBSSVNJTkcpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3VwcGx5U3RhdGUgPT09IEhJR0gpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRFU0kpKSB7XG4gICAgbmV3RVNEID0gdHJ1ZTtcbiAgfVxuXG4gIGlmICghb2xkRVNJICYmICgoZGVtYW5kU3RhdGUgPT09IFJJU0lORykgfHxcbiAgICAgICAgICAgICAgICAgIChkZW1hbmRTdGF0ZSA9PT0gSElHSCkpICYmICgoc3VwcGx5U3RhdGUgPT09IExPVykgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3VwcGx5U3RhdGUgPT09IEZBTExJTkcpKSkge1xuICAgIGlmICgoZGVtYW5kU3RhdGUgPT09IEhJR0gpICYmICFvbGRFU0QpIHtcbiAgICAgIG9uVGFza0V4aXQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGFza0ZuKCk7XG4gICAgICBuZXdFU0kgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdXBwbHlTdGF0ZSA9PT0gRkFMTElORykgbmV3RVNEID0gZmFsc2U7XG4gIGlmIChzdXBwbHlTdGF0ZSA9PT0gUklTSU5HKSAgbmV3RVNJID0gZmFsc2U7XG5cbiAgaWYgKG5ld0VTSSB8fCBuZXdFU0QpIHtcbiAgICByZXR1cm4geyBleHBlY3RTdXBwbHlJbmNyZWFzZTogbmV3RVNJLCBleHBlY3RTdXBwbHlEZWNyZWFzZTogbmV3RVNEIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVmYXVsdE9uVGFza0V4aXQoY2FwdHVyZXMpIHtcbiAgY29uc29sZS5lcnJvcihcIlN5bmRpY2F0ZTogRGVtYW5kTWF0Y2hlciBkZXRlY3RlZCB1bmV4cGVjdGVkIGRyb3AgaW4gc3VwcGx5XCIsIGNhcHR1cmVzKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBEZW1hbmRNYXRjaGVyIGl0c2VsZlxuXG5mdW5jdGlvbiBEZW1hbmRNYXRjaGVyKGRlbWFuZFNwZWNzLCBzdXBwbHlTcGVjcywgc3RhcnRUYXNrLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBVdGlsLmV4dGVuZCh7XG4gICAgbWV0YUxldmVsOiAwLFxuICAgIGRlbWFuZE1ldGFMZXZlbDogbnVsbCxcbiAgICBzdXBwbHlNZXRhTGV2ZWw6IG51bGwsXG4gICAgdGFza1N1cGVydmlzb3I6IGRlZmF1bHRUYXNrU3VwZXJ2aXNvcixcbiAgICBvblRhc2tFeGl0OiBkZWZhdWx0T25UYXNrRXhpdFxuICB9LCBvcHRpb25zKTtcblxuICBpZiAodHlwZW9mIHN0YXJ0VGFzayAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlN5bmRpY2F0ZTogRGVtYW5kTWF0Y2hlciBleHBlY3RzICdzdGFydFRhc2snIGZ1bmN0aW9uIGFzIHRoaXJkIGFyZ3VtZW50XCIpO1xuICB9XG5cbiAgdGhpcy5kZW1hbmRQcm9qZWN0aW9uTmFtZXMgPSBlbnN1cmVNYXRjaGluZ1Byb2plY3Rpb25OYW1lcyhkZW1hbmRTcGVjcyk7XG4gIHRoaXMuc3VwcGx5UHJvamVjdGlvbk5hbWVzID0gZW5zdXJlTWF0Y2hpbmdQcm9qZWN0aW9uTmFtZXMoc3VwcGx5U3BlY3MpO1xuICBlbnN1cmVNYXRjaGluZ1Byb2plY3Rpb25OYW1lcyhbZGVtYW5kU3BlY3NbMF0sIHN1cHBseVNwZWNzWzBdXSk7XG5cbiAgdGhpcy5kZW1hbmRTcGVjcyA9IGRlbWFuZFNwZWNzO1xuICB0aGlzLnN1cHBseVNwZWNzID0gc3VwcGx5U3BlY3M7XG5cbiAgdGhpcy5kZW1hbmRQYXR0ZXJucyA9IGRlbWFuZFNwZWNzLm1hcChmdW5jdGlvbiAocykgeyByZXR1cm4gVHJpZS5wcm9qZWN0aW9uVG9QYXR0ZXJuKHMpOyB9KTtcbiAgdGhpcy5zdXBwbHlQYXR0ZXJucyA9IHN1cHBseVNwZWNzLm1hcChmdW5jdGlvbiAocykgeyByZXR1cm4gVHJpZS5wcm9qZWN0aW9uVG9QYXR0ZXJuKHMpOyB9KTtcblxuICB0aGlzLmRlbWFuZE1ldGFMZXZlbCA9XG4gICAgKG9wdGlvbnMuZGVtYW5kTWV0YUxldmVsID09PSBudWxsKSA/IG9wdGlvbnMubWV0YUxldmVsIDogb3B0aW9ucy5kZW1hbmRNZXRhTGV2ZWw7XG4gIHRoaXMuc3VwcGx5TWV0YUxldmVsID1cbiAgICAob3B0aW9ucy5zdXBwbHlNZXRhTGV2ZWwgPT09IG51bGwpID8gb3B0aW9ucy5tZXRhTGV2ZWwgOiBvcHRpb25zLnN1cHBseU1ldGFMZXZlbDtcblxuICBmdW5jdGlvbiBtZXRhV3JhcChuKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChzKSB7IHJldHVybiBQYXRjaC5wcmVwZW5kQXRNZXRhKHMsIG4pOyB9O1xuICB9XG4gIHRoaXMuZGVtYW5kUHJvamVjdGlvbnMgPSBkZW1hbmRTcGVjcy5tYXAobWV0YVdyYXAodGhpcy5kZW1hbmRNZXRhTGV2ZWwpKTtcbiAgdGhpcy5zdXBwbHlQcm9qZWN0aW9ucyA9IHN1cHBseVNwZWNzLm1hcChtZXRhV3JhcCh0aGlzLnN1cHBseU1ldGFMZXZlbCkpO1xuXG4gIHRoaXMudGFza1N1cGVydmlzb3IgPSBvcHRpb25zLnRhc2tTdXBlcnZpc29yO1xuICB0aGlzLnN0YXJ0VGFzayA9IHN0YXJ0VGFzaztcbiAgdGhpcy5vblRhc2tFeGl0ID0gb3B0aW9ucy5vblRhc2tFeGl0O1xuXG4gIHRoaXMuY3VycmVudERlbWFuZCA9IEltbXV0YWJsZS5TZXQoKTtcbiAgdGhpcy5jdXJyZW50U3VwcGx5ID0gSW1tdXRhYmxlLlNldCgpO1xuICB0aGlzLnN1cGVydmlzaW9uU3RhdGVzID0gSW1tdXRhYmxlLk1hcCgpO1xuXG4gIGlmICgnbmFtZScgaW4gb3B0aW9ucykge1xuICAgIHRoaXMubmFtZSA9IG9wdGlvbnMubmFtZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbnN1cmVNYXRjaGluZ1Byb2plY3Rpb25OYW1lcyhzcGVjcykge1xuICBpZiAoIShzcGVjcy5sZW5ndGggPiAwKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlN5bmRpY2F0ZTogRGVtYW5kTWF0Y2hlciBuZWVkcyBhdCBsZWFzdCBvbmUgc3BlY1wiKTtcbiAgfVxuXG4gIHZhciBuYW1lcyA9IG51bGw7XG4gIHNwZWNzLmZvckVhY2goZnVuY3Rpb24gKHNwZWMpIHtcbiAgICBpZiAobmFtZXMgPT09IG51bGwpIHtcbiAgICAgIG5hbWVzID0gVHJpZS5wcm9qZWN0aW9uTmFtZXMoc3BlYyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChKU09OLnN0cmluZ2lmeShuYW1lcykgIT09IEpTT04uc3RyaW5naWZ5KFRyaWUucHJvamVjdGlvbk5hbWVzKHNwZWMpKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeW5kaWNhdGU6IERlbWFuZE1hdGNoZXIgbmVlZHMgaWRlbnRpY2FsIGNhcHR1cmUgbmFtZXNcIik7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG5hbWVzO1xufVxuXG5EZW1hbmRNYXRjaGVyLnByb3RvdHlwZS5ib290ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgcCA9IFBhdGNoLmVtcHR5UGF0Y2g7XG4gIGZ1bmN0aW9uIGV4dGVuZChtbCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAocGF0KSB7IHAgPSBwLmFuZFRoZW4oUGF0Y2guc3ViKHBhdCwgbWwpKTsgfTtcbiAgfVxuICB0aGlzLmRlbWFuZFBhdHRlcm5zLmZvckVhY2goZXh0ZW5kKHRoaXMuZGVtYW5kTWV0YUxldmVsKSk7XG4gIHRoaXMuc3VwcGx5UGF0dGVybnMuZm9yRWFjaChleHRlbmQodGhpcy5zdXBwbHlNZXRhTGV2ZWwpKTtcbiAgcmV0dXJuIHA7XG59O1xuXG5EZW1hbmRNYXRjaGVyLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gIGlmIChlLnR5cGUgPT09IFwic3RhdGVDaGFuZ2VcIikge1xuICAgIHRoaXMuaGFuZGxlUGF0Y2goZS5wYXRjaCk7XG4gIH1cbn07XG5cbkRlbWFuZE1hdGNoZXIucHJvdG90eXBlLmhhbmRsZVBhdGNoID0gZnVuY3Rpb24gKHApIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBkTiA9IHNlbGYuZGVtYW5kUHJvamVjdGlvbk5hbWVzLmxlbmd0aDtcbiAgdmFyIHNOID0gc2VsZi5zdXBwbHlQcm9qZWN0aW9uTmFtZXMubGVuZ3RoO1xuICB2YXIgYWRkZWREZW1hbmQgPSBzZWxmLmV4dHJhY3RLZXlzKHAuYWRkZWQsIHNlbGYuZGVtYW5kUHJvamVjdGlvbnMsIGROLCAnZGVtYW5kJyk7XG4gIHZhciByZW1vdmVkRGVtYW5kID0gc2VsZi5leHRyYWN0S2V5cyhwLnJlbW92ZWQsIHNlbGYuZGVtYW5kUHJvamVjdGlvbnMsIGROLCAnZGVtYW5kJyk7XG4gIHZhciBhZGRlZFN1cHBseSA9IHNlbGYuZXh0cmFjdEtleXMocC5hZGRlZCwgc2VsZi5zdXBwbHlQcm9qZWN0aW9ucywgc04sICdzdXBwbHknKTtcbiAgdmFyIHJlbW92ZWRTdXBwbHkgPSBzZWxmLmV4dHJhY3RLZXlzKHAucmVtb3ZlZCwgc2VsZi5zdXBwbHlQcm9qZWN0aW9ucywgc04sICdzdXBwbHknKTtcblxuICAvLyBUaG91Z2ggdGhlIGFkZGVkIGFuZCByZW1vdmVkIHNldHMgb2YgcGF0Y2hlcyBhcmUgYWx3YXlzIGRpc2pvaW50LFxuICAvLyAqYWZ0ZXIgcHJvamVjdGlvbiogdGhpcyBtYXkgbm90IGhvbGQuIENhbmNlbCBvdXQgYW55IG92ZXJsYXBzLlxuICB2YXIgZGVtYW5kT3ZlcmxhcCA9IGFkZGVkRGVtYW5kLmludGVyc2VjdChyZW1vdmVkRGVtYW5kKTtcbiAgdmFyIHN1cHBseU92ZXJsYXAgPSBhZGRlZFN1cHBseS5pbnRlcnNlY3QocmVtb3ZlZFN1cHBseSk7XG4gIGFkZGVkRGVtYW5kID0gYWRkZWREZW1hbmQuc3VidHJhY3QoZGVtYW5kT3ZlcmxhcCk7XG4gIHJlbW92ZWREZW1hbmQgPSByZW1vdmVkRGVtYW5kLnN1YnRyYWN0KGRlbWFuZE92ZXJsYXApO1xuICBhZGRlZFN1cHBseSA9IGFkZGVkU3VwcGx5LnN1YnRyYWN0KHN1cHBseU92ZXJsYXApO1xuICByZW1vdmVkU3VwcGx5ID0gcmVtb3ZlZFN1cHBseS5zdWJ0cmFjdChzdXBwbHlPdmVybGFwKTtcblxuICB2YXIgYWxsVGFza3MgPSBhZGRlZERlbWFuZC51bmlvbihhZGRlZFN1cHBseSkudW5pb24ocmVtb3ZlZERlbWFuZCkudW5pb24ocmVtb3ZlZFN1cHBseSk7XG5cbiAgYWxsVGFza3MuZm9yRWFjaChmdW5jdGlvbiAoY2FwdHVyZXMpIHtcbiAgICBmdW5jdGlvbiB0YXNrRm4oKSB7XG4gICAgICBzZWxmLnN0YXJ0VGFzayhUcmllLmNhcHR1cmVUb09iamVjdChjYXB0dXJlcywgc2VsZi5kZW1hbmRQcm9qZWN0aW9uTmFtZXMpKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gb25UYXNrRXhpdCgpIHtcbiAgICAgIHNlbGYub25UYXNrRXhpdChUcmllLmNhcHR1cmVUb09iamVjdChjYXB0dXJlcywgc2VsZi5kZW1hbmRQcm9qZWN0aW9uTmFtZXMpKTtcbiAgICB9XG5cbiAgICB2YXIgZGVtYW5kU3RhdGUgPSBjb21wdXRlU3RhdGUoc2VsZi5jdXJyZW50RGVtYW5kLCBhZGRlZERlbWFuZCwgcmVtb3ZlZERlbWFuZCwgY2FwdHVyZXMpO1xuICAgIHZhciBzdXBwbHlTdGF0ZSA9IGNvbXB1dGVTdGF0ZShzZWxmLmN1cnJlbnRTdXBwbHksIGFkZGVkU3VwcGx5LCByZW1vdmVkU3VwcGx5LCBjYXB0dXJlcyk7XG4gICAgdmFyIG9sZFN1cGVydmlzaW9uU3RhdGUgPSBzZWxmLnN1cGVydmlzaW9uU3RhdGVzLmdldChjYXB0dXJlcywgbnVsbCk7XG4gICAgdmFyIG5ld1N1cGVydmlzaW9uU3RhdGUgPSBzZWxmLnRhc2tTdXBlcnZpc29yKGRlbWFuZFN0YXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwbHlTdGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkU3VwZXJ2aXNpb25TdGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFza0ZuLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblRhc2tFeGl0KTtcbiAgICBpZiAobmV3U3VwZXJ2aXNpb25TdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgc2VsZi5zdXBlcnZpc2lvblN0YXRlcyA9IHNlbGYuc3VwZXJ2aXNpb25TdGF0ZXMucmVtb3ZlKGNhcHR1cmVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZi5zdXBlcnZpc2lvblN0YXRlcyA9IHNlbGYuc3VwZXJ2aXNpb25TdGF0ZXMuc2V0KGNhcHR1cmVzLCBuZXdTdXBlcnZpc2lvblN0YXRlKTtcbiAgICB9XG4gIH0pO1xuXG4gIHNlbGYuY3VycmVudFN1cHBseSA9IHNlbGYuY3VycmVudFN1cHBseS51bmlvbihhZGRlZFN1cHBseSkuc3VidHJhY3QocmVtb3ZlZFN1cHBseSk7XG4gIHNlbGYuY3VycmVudERlbWFuZCA9IHNlbGYuY3VycmVudERlbWFuZC51bmlvbihhZGRlZERlbWFuZCkuc3VidHJhY3QocmVtb3ZlZERlbWFuZCk7XG59O1xuXG5EZW1hbmRNYXRjaGVyLnByb3RvdHlwZS5leHRyYWN0S2V5cyA9IGZ1bmN0aW9uICh0cmllLCBwcm9qZWN0aW9ucywga2V5Q291bnQsIHdoaWNoU2lkZSkge1xuICB2YXIga3MgPSBJbW11dGFibGUuU2V0KCk7XG4gIHByb2plY3Rpb25zLmZvckVhY2goZnVuY3Rpb24gKHByb2opIHtcbiAgICB2YXIgbW9yZUtzID0gVHJpZS50cmllS2V5cyhUcmllLnByb2plY3QodHJpZSwgcHJvaiksIGtleUNvdW50KTtcbiAgICBpZiAoIW1vcmVLcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luZGljYXRlOiB3aWxkY2FyZCBcIit3aGljaFNpZGUrXCIgZGV0ZWN0ZWQ6XFxuXCIgK1xuICAgICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHByb2opICsgXCJcXG5cIiArXG4gICAgICAgICAgICAgICAgICAgICAgVHJpZS5wcmV0dHlUcmllKHRyaWUpKTtcbiAgICB9XG4gICAga3MgPSBrcy51bmlvbihtb3JlS3MpO1xuICB9KTtcbiAgcmV0dXJuIGtzO1xufTtcblxuZnVuY3Rpb24gY29tcHV0ZVN0YXRlKGN1cnJlbnQsIGFkZGVkLCByZW1vdmVkLCBjYXB0dXJlcykge1xuICB2YXIgaXNQcmVzZW50ID0gY3VycmVudC5oYXMoY2FwdHVyZXMpO1xuICB2YXIgaXNDaGFuZ2luZyA9IGFkZGVkLmhhcyhjYXB0dXJlcykgfHwgcmVtb3ZlZC5oYXMoY2FwdHVyZXMpO1xuICByZXR1cm4gKGlzUHJlc2VudCA/IElTX1BSRVNFTlQgOiAwKSB8IChpc0NoYW5naW5nID8gSVNfQ0hBTkdJTkcgOiAwKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLkRlbWFuZE1hdGNoZXIgPSBEZW1hbmRNYXRjaGVyO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBJbW11dGFibGUgPSByZXF1aXJlKCdpbW11dGFibGUnKTtcbnZhciBEYXRhc3BhY2UgPSByZXF1aXJlKCcuL2RhdGFzcGFjZS5qcycpLkRhdGFzcGFjZTtcblxuZnVuY3Rpb24gR3JvdW5kKGJvb3RGbikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuc3RlcHBlcklkID0gbnVsbDtcbiAgdGhpcy5zdGVwcGluZyA9IGZhbHNlO1xuICB0aGlzLnN0YXJ0aW5nRnVlbCA9IDEwMDtcbiAgdGhpcy5iYXNlU3RhY2sgPSBJbW11dGFibGUuTGlzdC5vZih7IGRhdGFzcGFjZTogdGhpcywgYWN0aXZlUGlkOiAtMSB9KTtcbiAgRGF0YXNwYWNlLndpdGhEYXRhc3BhY2VTdGFjayh0aGlzLmJhc2VTdGFjaywgZnVuY3Rpb24gKCkge1xuICAgIHNlbGYuZGF0YXNwYWNlID0gbmV3IERhdGFzcGFjZShib290Rm4pO1xuICB9KTtcbn1cblxuR3JvdW5kLnByb3RvdHlwZS5zdGVwID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHJldHVybiBEYXRhc3BhY2Uud2l0aERhdGFzcGFjZVN0YWNrKHRoaXMuYmFzZVN0YWNrLCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHNlbGYuZGF0YXNwYWNlLnN0ZXAoKTtcbiAgfSk7XG59O1xuXG5Hcm91bmQucHJvdG90eXBlLmNoZWNrUGlkID0gZnVuY3Rpb24gKHBpZCkge1xuICBpZiAocGlkICE9PSAtMSkgY29uc29sZS5lcnJvcignV2VpcmQgcGlkIGluIEdyb3VuZCcsIHBpZCk7XG59O1xuXG5Hcm91bmQucHJvdG90eXBlLm1hcmtSdW5uYWJsZSA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgdGhpcy5jaGVja1BpZChwaWQpO1xuICB0aGlzLnN0YXJ0U3RlcHBpbmcoKTtcbn07XG5cbkdyb3VuZC5wcm90b3R5cGUuc3RhcnRTdGVwcGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAodGhpcy5zdGVwcGVySWQpIHJldHVybjtcblxuICBpZiAodGhpcy5zdGVwcGluZykgcmV0dXJuO1xuICB0aGlzLnN0ZXBwaW5nID0gdHJ1ZTtcbiAgdHJ5IHtcbiAgICB2YXIgc3RpbGxCdXN5ID0gZmFsc2U7XG4gICAgZm9yICh2YXIgZnVlbCA9IHRoaXMuc3RhcnRpbmdGdWVsOyBmdWVsID4gMDsgZnVlbC0tKSB7XG4gICAgICBzdGlsbEJ1c3kgPSB0aGlzLnN0ZXAoKTtcbiAgICAgIGlmICghc3RpbGxCdXN5KSBicmVhaztcbiAgICB9XG4gICAgaWYgKHN0aWxsQnVzeSkge1xuICAgICAgdGhpcy5zdGVwcGVySWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5zdGVwcGVySWQgPSBudWxsO1xuICAgICAgICBzZWxmLnN0YXJ0U3RlcHBpbmcoKTtcbiAgICAgIH0sIDApO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIHRoaXMuc3RlcHBpbmcgPSBmYWxzZTtcbiAgICB0aHJvdyBlO1xuICB9XG4gIHRoaXMuc3RlcHBpbmcgPSBmYWxzZTtcblxuICByZXR1cm4gdGhpczsgLy8gYmVjYXVzZSB0aGUgc3luZGljYXRlYyBjb21waWxlciBjaGFpbnMgc3RhcnRTdGVwcGluZyBhZnRlciB0aGUgY3RvclxufTtcblxuR3JvdW5kLnByb3RvdHlwZS5zdG9wU3RlcHBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnN0ZXBwZXJJZCkge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnN0ZXBwZXJJZCk7XG4gICAgdGhpcy5zdGVwcGVySWQgPSBudWxsO1xuICB9XG59O1xuXG5Hcm91bmQucHJvdG90eXBlLmtpbGwgPSBmdW5jdGlvbiAocGlkLCBleG4pIHtcbiAgdGhpcy5jaGVja1BpZChwaWQpO1xuICBjb25zb2xlLmxvZyhcIkdyb3VuZCBkYXRhc3BhY2UgdGVybWluYXRlZFwiKTtcbiAgdGhpcy5zdG9wU3RlcHBpbmcoKTtcbn07XG5cbkdyb3VuZC5wcm90b3R5cGUuZW5xdWV1ZUFjdGlvbiA9IGZ1bmN0aW9uIChwaWQsIGFjdGlvbikge1xuICB0aGlzLmNoZWNrUGlkKHBpZCk7XG5cbiAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICBjYXNlICdzdGF0ZUNoYW5nZSc6XG4gICAgaWYgKGFjdGlvbi5wYXRjaC5pc05vbkVtcHR5KCkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1lvdSBoYXZlIHN1YnNjcmliZWQgdG8gYSBub25leGlzdGVudCBldmVudCBzb3VyY2UuJyxcblx0XHQgICAgYWN0aW9uLnBhdGNoLnByZXR0eSgpKTtcbiAgICB9XG4gICAgYnJlYWs7XG5cbiAgY2FzZSAnbWVzc2FnZSc6XG4gICAgY29uc29sZS5lcnJvcignWW91IGhhdmUgc2VudCBhIG1lc3NhZ2UgaW50byB0aGUgb3V0ZXIgdm9pZC4nLCBhY3Rpb24pO1xuICAgIGJyZWFrO1xuXG4gIGRlZmF1bHQ6XG4gICAgY29uc29sZS5lcnJvcignSW50ZXJuYWwgZXJyb3I6IHVuZXhwZWN0ZWQgYWN0aW9uIGF0IGdyb3VuZCBsZXZlbCcsIGFjdGlvbik7XG4gICAgYnJlYWs7XG4gIH1cbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5Hcm91bmQgPSBHcm91bmQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuZnVuY3Rpb24gY29weUtleXMoa2V5cywgdG8sIGZyb20pIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdG9ba2V5c1tpXV0gPSBmcm9tW2tleXNbaV1dO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vZGF0YXNwYWNlLmpzXCIpO1xuXG5tb2R1bGUuZXhwb3J0cy5UcmllID0gcmVxdWlyZShcIi4vdHJpZS5qc1wiKTtcbmNvcHlLZXlzKFsnX18nLCAnXyQnLCAnJENhcHR1cmUnLCAnJFNwZWNpYWwnLFxuXHQgICdpc19lbXB0eVRyaWUnLCAnZW1wdHlUcmllJyxcblx0ICAnZW1iZWRkZWRUcmllJywgJ2NvbXBpbGVQYXR0ZXJuJyxcblx0ICAncHJvamVjdCcsICdwcm9qZWN0T2JqZWN0cycsXG5cdCAgJ3ByZXR0eVRyaWUnXSxcblx0IG1vZHVsZS5leHBvcnRzLFxuXHQgbW9kdWxlLmV4cG9ydHMuVHJpZSk7XG5tb2R1bGUuZXhwb3J0cy5TdHJ1Y3QgPSByZXF1aXJlKCcuL3N0cnVjdC5qcycpO1xuXG52YXIgU2VhbCA9IHJlcXVpcmUoJy4vc2VhbC5qcycpXG5jb3B5S2V5cyhbJ1NlYWwnLCAnc2VhbCddLFxuXHQgbW9kdWxlLmV4cG9ydHMsXG5cdCBTZWFsKTtcblxubW9kdWxlLmV4cG9ydHMuRGVtYW5kTWF0Y2hlciA9IHJlcXVpcmUoJy4vZGVtYW5kLW1hdGNoZXIuanMnKS5EZW1hbmRNYXRjaGVyO1xubW9kdWxlLmV4cG9ydHMuQWNrID0gcmVxdWlyZSgnLi9hY2suanMnKS5BY2s7XG5cbm1vZHVsZS5leHBvcnRzLlJhbmRvbUlEID0gcmVxdWlyZSgnLi9yYW5kb21pZC5qcycpO1xubW9kdWxlLmV4cG9ydHMuVUkgPSByZXF1aXJlKCcuL3VpLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5UaW1lciA9IHJlcXVpcmUoXCIuL3RpbWVyLWRyaXZlci5qc1wiKTtcbm1vZHVsZS5leHBvcnRzLlJlZmxlY3QgPSByZXF1aXJlKFwiLi9yZWZsZWN0LmpzXCIpO1xubW9kdWxlLmV4cG9ydHMuV2FrZURldGVjdG9yID0gcmVxdWlyZShcIi4vd2FrZS1kZXRlY3Rvci1kcml2ZXIuanNcIik7XG5tb2R1bGUuZXhwb3J0cy5Db2RlYyA9IHJlcXVpcmUoXCIuL2NvZGVjLmpzXCIpO1xubW9kdWxlLmV4cG9ydHMuQnJva2VyID0gcmVxdWlyZShcIi4vYnJva2VyLmpzXCIpO1xuXG5tb2R1bGUuZXhwb3J0cy5QYXRjaCA9IHJlcXVpcmUoXCIuL3BhdGNoLmpzXCIpO1xuY29weUtleXMoWydlbXB0eVBhdGNoJyxcblx0ICAnb2JzZXJ2ZScsICdhdE1ldGEnLCAnYWR2ZXJ0aXNlJyxcblx0ICAnYXNzZXJ0JywgJ3JldHJhY3QnLCAnc3ViJywgJ3Vuc3ViJywgJ3B1YicsICd1bnB1YicsXG5cdCAgJ3BhdGNoU2VxJ10sXG5cdCBtb2R1bGUuZXhwb3J0cyxcblx0IG1vZHVsZS5leHBvcnRzLlBhdGNoKTtcblxubW9kdWxlLmV4cG9ydHMuR3JvdW5kID0gcmVxdWlyZShcIi4vZ3JvdW5kLmpzXCIpLkdyb3VuZDtcbm1vZHVsZS5leHBvcnRzLkFjdG9yID0gcmVxdWlyZShcIi4vYWN0b3IuanNcIik7XG4vLyBtb2R1bGUuZXhwb3J0cy5TcHkgPSByZXF1aXJlKFwiLi9zcHkuanNcIikuU3B5O1xuLy8gbW9kdWxlLmV4cG9ydHMuV2FrZURldGVjdG9yID0gcmVxdWlyZShcIi4vd2FrZS1kZXRlY3Rvci5qc1wiKS5XYWtlRGV0ZWN0b3I7XG5cbi8vIHZhciBXb3JrZXIgPSByZXF1aXJlKFwiLi93b3JrZXIuanNcIik7XG4vLyBtb2R1bGUuZXhwb3J0cy5Xb3JrZXIgPSBXb3JrZXIuV29ya2VyO1xuLy8gbW9kdWxlLmV4cG9ydHMuV29ya2VyR3JvdW5kID0gV29ya2VyLldvcmtlckdyb3VuZDtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgSW1tdXRhYmxlID0gcmVxdWlyZSgnaW1tdXRhYmxlJyk7XG52YXIgVHJpZSA9IHJlcXVpcmUoJy4vdHJpZS5qcycpO1xudmFyIFBhdGNoID0gcmVxdWlyZSgnLi9wYXRjaC5qcycpO1xuXG5mdW5jdGlvbiBNdXgobmV4dFBpZCwgcm91dGluZ1RhYmxlLCBpbnRlcmVzdFRhYmxlKSB7XG4gIHRoaXMubmV4dFBpZCA9IG5leHRQaWQgfHwgMDtcbiAgdGhpcy5yb3V0aW5nVGFibGUgPSByb3V0aW5nVGFibGUgfHwgVHJpZS5lbXB0eVRyaWU7XG4gIHRoaXMuaW50ZXJlc3RUYWJsZSA9IGludGVyZXN0VGFibGUgfHwgSW1tdXRhYmxlLk1hcCgpOyAvLyBwaWQgLT4gVHJpZVxufVxuXG5NdXgucHJvdG90eXBlLnNoYWxsb3dDb3B5ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gbmV3IE11eCh0aGlzLm5leHRQaWQsIHRoaXMucm91dGluZ1RhYmxlLCB0aGlzLmludGVyZXN0VGFibGUpO1xufTtcblxuTXV4LnByb3RvdHlwZS5hZGRTdHJlYW0gPSBmdW5jdGlvbiAoaW5pdGlhbFBhdGNoKSB7XG4gIHZhciBuZXdQaWQgPSB0aGlzLm5leHRQaWQrKztcbiAgcmV0dXJuIHRoaXMudXBkYXRlU3RyZWFtKG5ld1BpZCwgaW5pdGlhbFBhdGNoKTtcbn07XG5cbk11eC5wcm90b3R5cGUucmVtb3ZlU3RyZWFtID0gZnVuY3Rpb24gKHBpZCkge1xuICByZXR1cm4gdGhpcy51cGRhdGVTdHJlYW0ocGlkLCBQYXRjaC5yZW1vdmVFdmVyeXRoaW5nUGF0Y2gpO1xufTtcblxuTXV4LnByb3RvdHlwZS51cGRhdGVTdHJlYW0gPSBmdW5jdGlvbiAocGlkLCB1bmNsYW1wZWRQYXRjaCkge1xuICB2YXIgb2xkSW50ZXJlc3RzID0gdGhpcy5pbnRlcmVzdHNPZihwaWQpO1xuICB2YXIgb2xkUm91dGluZ1RhYmxlID0gdGhpcy5yb3V0aW5nVGFibGU7XG4gIHZhciBkZWx0YSA9IHVuY2xhbXBlZFBhdGNoLmxhYmVsKEltbXV0YWJsZS5TZXQub2YocGlkKSkubGltaXQob2xkSW50ZXJlc3RzKTtcbiAgdmFyIGRlbHRhQWdncmVnYXRlID0gZGVsdGEuY29tcHV0ZUFnZ3JlZ2F0ZShwaWQsIG9sZFJvdXRpbmdUYWJsZSk7XG4gIHZhciBuZXdJbnRlcmVzdHMgPSBkZWx0YS5hcHBseVRvKG9sZEludGVyZXN0cyk7XG4gIHZhciBuZXdSb3V0aW5nVGFibGUgPSBkZWx0YS5hcHBseVRvKG9sZFJvdXRpbmdUYWJsZSk7XG5cbiAgdGhpcy5yb3V0aW5nVGFibGUgPSBuZXdSb3V0aW5nVGFibGU7XG5cbiAgaWYgKFRyaWUuaXNfZW1wdHlUcmllKG5ld0ludGVyZXN0cykpIHtcbiAgICB0aGlzLmludGVyZXN0VGFibGUgPSB0aGlzLmludGVyZXN0VGFibGUucmVtb3ZlKHBpZCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5pbnRlcmVzdFRhYmxlID0gdGhpcy5pbnRlcmVzdFRhYmxlLnNldChwaWQsIG5ld0ludGVyZXN0cyk7XG4gIH1cblxuICByZXR1cm4geyBwaWQ6IHBpZCxcblx0ICAgZGVsdGE6IGRlbHRhLFxuXHQgICBkZWx0YUFnZ3JlZ2F0ZTogZGVsdGFBZ2dyZWdhdGUgfTtcbn07XG5cbnZhciBhdE1ldGFFdmVyeXRoaW5nID0gVHJpZS5jb21waWxlUGF0dGVybih0cnVlLCBQYXRjaC5hdE1ldGEoVHJpZS5fXykpO1xudmFyIGF0TWV0YUJyYW5jaEtleXMgPSBJbW11dGFibGUuTGlzdChbW1BhdGNoLmF0TWV0YS5tZXRhLmFyaXR5LCBQYXRjaC5hdE1ldGEubWV0YV1dKTtcbnZhciBvbmx5TWV0YSA9IFRyaWUudHJpZVN1Y2Nlc3MoSW1tdXRhYmxlLlNldC5vZihcIm1ldGFcIikpO1xuXG5mdW5jdGlvbiBlY2hvQ2FuY2VsbGVkVHJpZSh0KSB7XG4gIHJldHVybiBUcmllLnN1YnRyYWN0KHQsIGF0TWV0YUV2ZXJ5dGhpbmcsIGZ1bmN0aW9uICh2MSwgdjIpIHtcbiAgICByZXR1cm4gdjEuaGFzKFwibWV0YVwiKSA/IG9ubHlNZXRhIDogVHJpZS5lbXB0eVRyaWU7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlRXZlbnRzKG9sZE11eCwgbmV3TXV4LCB1cGRhdGVTdHJlYW1SZXN1bHQpIHtcbiAgdmFyIGFjdGluZ1BpZCA9IHVwZGF0ZVN0cmVhbVJlc3VsdC5waWQ7XG4gIHZhciBkZWx0YSA9IHVwZGF0ZVN0cmVhbVJlc3VsdC5kZWx0YTtcbiAgdmFyIGRlbHRhQWdncmVnYXRlID0gdXBkYXRlU3RyZWFtUmVzdWx0LmRlbHRhQWdncmVnYXRlO1xuICB2YXIgZGVsdGFBZ2dyZWdhdGVOb0VjaG8gPSAoYWN0aW5nUGlkID09PSBcIm1ldGFcIilcbiAgICAgID8gZGVsdGEgLy8gYmVjYXVzZSBlY2hvLWNhbmNlbGxhdGlvbiBtZWFucyB0aGF0IG1ldGEtU0NOcyBhcmUgYWx3YXlzIG5ldyBpbmZvcm1hdGlvblxuICAgICAgOiBkZWx0YUFnZ3JlZ2F0ZS53aXRob3V0QXRNZXRhKCk7XG4gIHZhciBvbGRSb3V0aW5nVGFibGUgPSBvbGRNdXgucm91dGluZ1RhYmxlO1xuICB2YXIgbmV3Um91dGluZ1RhYmxlID0gbmV3TXV4LnJvdXRpbmdUYWJsZTtcbiAgdmFyIGFmZmVjdGVkUGlkcyA9XG4gICAgICBjb21wdXRlQWZmZWN0ZWRQaWRzKG9sZFJvdXRpbmdUYWJsZSwgZGVsdGFBZ2dyZWdhdGVOb0VjaG8pLmFkZChhY3RpbmdQaWQpLnJlbW92ZShcIm1ldGFcIik7XG4gIHJldHVybiB7XG4gICAgZXZlbnRNYXA6IEltbXV0YWJsZS5NYXAoKS53aXRoTXV0YXRpb25zKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgIGFmZmVjdGVkUGlkcy5mb3JFYWNoKGZ1bmN0aW9uIChwaWQpIHtcblx0dmFyIHBhdGNoRm9yUGlkO1xuXHRpZiAocGlkID09PSBhY3RpbmdQaWQpIHtcblx0ICB2YXIgcGFydDEgPSBuZXcgUGF0Y2guUGF0Y2goXG5cdCAgICBlY2hvQ2FuY2VsbGVkVHJpZShQYXRjaC5iaWFzZWRJbnRlcnNlY3Rpb24obmV3Um91dGluZ1RhYmxlLCBkZWx0YS5hZGRlZCkpLFxuXHQgICAgZWNob0NhbmNlbGxlZFRyaWUoUGF0Y2guYmlhc2VkSW50ZXJzZWN0aW9uKG9sZFJvdXRpbmdUYWJsZSwgZGVsdGEucmVtb3ZlZCkpKTtcblx0ICB2YXIgcGFydDIgPSBuZXcgUGF0Y2guUGF0Y2goUGF0Y2guYmlhc2VkSW50ZXJzZWN0aW9uKGRlbHRhQWdncmVnYXRlTm9FY2hvLmFkZGVkLFxuXHRcdFx0XHRcdFx0XHQgICAgICAgbmV3TXV4LmludGVyZXN0c09mKHBpZCkpLFxuXHRcdFx0XHQgICAgICBQYXRjaC5iaWFzZWRJbnRlcnNlY3Rpb24oZGVsdGFBZ2dyZWdhdGVOb0VjaG8ucmVtb3ZlZCxcblx0XHRcdFx0XHRcdFx0ICAgICAgIG9sZE11eC5pbnRlcmVzdHNPZihwaWQpKSk7XG5cdCAgcGF0Y2hGb3JQaWQgPSBwYXJ0MS51bnNhZmVVbmlvbihwYXJ0Mik7XG5cdH0gZWxzZSB7XG5cdCAgcGF0Y2hGb3JQaWQgPSBkZWx0YUFnZ3JlZ2F0ZU5vRWNoby52aWV3RnJvbShvbGRNdXguaW50ZXJlc3RzT2YocGlkKSk7XG5cdH1cblx0aWYgKHBhdGNoRm9yUGlkLmlzTm9uRW1wdHkoKSkge1xuXHQgIHJlc3VsdC5zZXQocGlkLCBwYXRjaEZvclBpZCk7XG5cdH1cbiAgICAgIH0pO1xuICAgIH0pLFxuICAgIG1ldGFFdmVudHM6IChhY3RpbmdQaWQgPT09IFwibWV0YVwiKVxuICAgICAgPyBJbW11dGFibGUuTGlzdCgpXG4gICAgICA6IEltbXV0YWJsZS5MaXN0Lm9mKGRlbHRhLmNvbXB1dGVBZ2dyZWdhdGUoYWN0aW5nUGlkLCBvbGRSb3V0aW5nVGFibGUsIHRydWUpLmRyb3AoKSlcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZUFmZmVjdGVkUGlkcyhyb3V0aW5nVGFibGUsIGRlbHRhKSB7XG4gIHZhciBjb3ZlciA9IFRyaWUuX3VuaW9uKGRlbHRhLmFkZGVkLCBkZWx0YS5yZW1vdmVkKTtcbiAgcm91dGluZ1RhYmxlID0gVHJpZS50cmllU3RlcChyb3V0aW5nVGFibGUsIFBhdGNoLm9ic2VydmUubWV0YS5hcml0eSwgUGF0Y2gub2JzZXJ2ZS5tZXRhKTtcbiAgcmV0dXJuIFRyaWUubWF0Y2hUcmllKGNvdmVyLCByb3V0aW5nVGFibGUsIEltbXV0YWJsZS5TZXQoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICh2MSwgdjIsIGFjYykgeyByZXR1cm4gYWNjLnVuaW9uKHYyKTsgfSk7XG59XG5cbk11eC5wcm90b3R5cGUucm91dGVNZXNzYWdlID0gZnVuY3Rpb24gKGJvZHkpIHtcbiAgaWYgKFRyaWUubWF0Y2hWYWx1ZSh0aGlzLnJvdXRpbmdUYWJsZSwgYm9keSwgbnVsbCwgZnVuY3Rpb24oYSwgYikgeyByZXR1cm4gYXx8YiB9KSA9PT0gbnVsbCkge1xuICAgIHJldHVybiBUcmllLm1hdGNoVmFsdWUodGhpcy5yb3V0aW5nVGFibGUsIFBhdGNoLm9ic2VydmUoYm9keSksIEltbXV0YWJsZS5TZXQoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhLnVuaW9uKGIpIH0pO1xuICB9IGVsc2Uge1xuICAgIC8vIFNvbWUgb3RoZXIgc3RyZWFtIGhhcyBkZWNsYXJlZCBib2R5XG4gICAgcmV0dXJuIEltbXV0YWJsZS5TZXQoKTtcbiAgfVxufTtcblxuTXV4LnByb3RvdHlwZS5pbnRlcmVzdHNPZiA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgcmV0dXJuIHRoaXMuaW50ZXJlc3RUYWJsZS5nZXQocGlkLCBUcmllLmVtcHR5VHJpZSk7XG59O1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuTXV4ID0gTXV4O1xubW9kdWxlLmV4cG9ydHMuY29tcHV0ZUV2ZW50cyA9IGNvbXB1dGVFdmVudHM7XG5tb2R1bGUuZXhwb3J0cy5jb21wdXRlQWZmZWN0ZWRQaWRzID0gY29tcHV0ZUFmZmVjdGVkUGlkcztcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgVHJpZSA9IHJlcXVpcmUoXCIuL3RyaWUuanNcIik7XG52YXIgU3RydWN0ID0gcmVxdWlyZShcIi4vc3RydWN0LmpzXCIpO1xudmFyIEltbXV0YWJsZSA9IHJlcXVpcmUoXCJpbW11dGFibGVcIik7XG5cbnZhciBfXyA9IFRyaWUuX187XG52YXIgXyQgPSBUcmllLl8kO1xuXG5mdW5jdGlvbiBQYXRjaChhZGRlZCwgcmVtb3ZlZCkge1xuICB0aGlzLmFkZGVkID0gYWRkZWQ7XG4gIHRoaXMucmVtb3ZlZCA9IHJlbW92ZWQ7XG59XG5cbnZhciBlbXB0eVBhdGNoID0gbmV3IFBhdGNoKFRyaWUuZW1wdHlUcmllLCBUcmllLmVtcHR5VHJpZSk7XG52YXIgcmVtb3ZlRXZlcnl0aGluZ1BhdGNoID0gbmV3IFBhdGNoKFRyaWUuZW1wdHlUcmllLCBUcmllLmNvbXBpbGVQYXR0ZXJuKHRydWUsIF9fKSk7XG52YXIgdHJ1ZUxhYmVsID0gVHJpZS50cmllU3VjY2Vzcyh0cnVlKTtcblxudmFyIG9ic2VydmUgPSBTdHJ1Y3QubWFrZUNvbnN0cnVjdG9yKCdvYnNlcnZlJywgWydhc3NlcnRpb24nXSk7XG52YXIgYXRNZXRhID0gU3RydWN0Lm1ha2VDb25zdHJ1Y3RvcignYXQtbWV0YScsIFsnYXNzZXJ0aW9uJ10pO1xudmFyIGFkdmVydGlzZSA9IFN0cnVjdC5tYWtlQ29uc3RydWN0b3IoJ2FkdmVydGlzZScsIFsnYXNzZXJ0aW9uJ10pO1xuXG5mdW5jdGlvbiBwcmVwZW5kQXRNZXRhKHAsIGxldmVsKSB7XG4gIHdoaWxlIChsZXZlbC0tKSB7XG4gICAgcCA9IGF0TWV0YShwKTtcbiAgfVxuICByZXR1cm4gcDtcbn1cblxuZnVuY3Rpb24gc3RyaXBBdE1ldGEocCwgbGV2ZWwpIHtcbiAgd2hpbGUgKGxldmVsLS0pIHtcbiAgICBpZiAoYXRNZXRhLmlzQ2xhc3NPZihwKSkge1xuICAgICAgcCA9IHBbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcDtcbn1cblxuZnVuY3Rpb24gb2JzZXJ2ZUF0TWV0YShwLCBsZXZlbCkge1xuICBpZiAobGV2ZWwgPT09IDApIHtcbiAgICByZXR1cm4gVHJpZS5jb21waWxlUGF0dGVybih0cnVlLCBvYnNlcnZlKHApKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gVHJpZS5fdW5pb24oXG4gICAgICBUcmllLmNvbXBpbGVQYXR0ZXJuKHRydWUsIG9ic2VydmUocHJlcGVuZEF0TWV0YShwLCBsZXZlbCkpKSxcbiAgICAgIFRyaWUuY29tcGlsZVBhdHRlcm4odHJ1ZSwgYXRNZXRhKFRyaWUuZW1iZWRkZWRUcmllKG9ic2VydmVBdE1ldGEocCwgbGV2ZWwgLSAxKSkpKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX2NoZWNrKHApIHtcbiAgaWYgKHAgaW5zdGFuY2VvZiBQYXRjaCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjb25zdHJ1Y3QgcGF0Y2ggcGF0dGVybiB1c2luZyBhbiBlbWJlZGRlZCBwYXRjaFwiKTtcbiAgfVxuICByZXR1cm4gcDtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0KHAsIG1ldGFMZXZlbCkge1xuICByZXR1cm4gbmV3IFBhdGNoKFRyaWUuY29tcGlsZVBhdHRlcm4odHJ1ZSwgcHJlcGVuZEF0TWV0YShfY2hlY2socCksIG1ldGFMZXZlbCB8fCAwKSksXG5cdFx0ICAgVHJpZS5lbXB0eVRyaWUpO1xufVxuXG5mdW5jdGlvbiByZXRyYWN0KHAsIG1ldGFMZXZlbCkge1xuICByZXR1cm4gbmV3IFBhdGNoKFRyaWUuZW1wdHlUcmllLFxuXHRcdCAgIFRyaWUuY29tcGlsZVBhdHRlcm4odHJ1ZSwgcHJlcGVuZEF0TWV0YShfY2hlY2socCksIG1ldGFMZXZlbCB8fCAwKSkpO1xufVxuXG5mdW5jdGlvbiBzdWIocCwgbWV0YUxldmVsKSB7XG4gIHJldHVybiBuZXcgUGF0Y2gob2JzZXJ2ZUF0TWV0YShfY2hlY2socCksIG1ldGFMZXZlbCB8fCAwKSwgVHJpZS5lbXB0eVRyaWUpO1xufVxuXG5mdW5jdGlvbiB1bnN1YihwLCBtZXRhTGV2ZWwpIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChUcmllLmVtcHR5VHJpZSwgb2JzZXJ2ZUF0TWV0YShfY2hlY2socCksIG1ldGFMZXZlbCB8fCAwKSk7XG59XG5cbmZ1bmN0aW9uIHB1YihwLCBtZXRhTGV2ZWwpIHtcbiAgcmV0dXJuIGFzc2VydChhZHZlcnRpc2UoX2NoZWNrKHApKSwgbWV0YUxldmVsKTtcbn1cblxuZnVuY3Rpb24gdW5wdWIocCwgbWV0YUxldmVsKSB7XG4gIHJldHVybiByZXRyYWN0KGFkdmVydGlzZShfY2hlY2socCkpLCBtZXRhTGV2ZWwpO1xufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuUGF0Y2gucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFBhdGNoKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gSW1tdXRhYmxlLmlzKHRoaXMuYWRkZWQsIG90aGVyLmFkZGVkKSAmJiBJbW11dGFibGUuaXModGhpcy5yZW1vdmVkLCBvdGhlci5yZW1vdmVkKTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5hZGRlZCA9PT0gVHJpZS5lbXB0eVRyaWUgJiYgdGhpcy5yZW1vdmVkID09PSBUcmllLmVtcHR5VHJpZTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS5pc05vbkVtcHR5ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gIXRoaXMuaXNFbXB0eSgpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLmhhc0FkZGVkID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gIVRyaWUuaXNfZW1wdHlUcmllKHRoaXMuYWRkZWQpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLmhhc1JlbW92ZWQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhVHJpZS5pc19lbXB0eVRyaWUodGhpcy5yZW1vdmVkKTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS5saWZ0ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gbmV3IFBhdGNoKFRyaWUuY29tcGlsZVBhdHRlcm4odHJ1ZSwgYXRNZXRhKFRyaWUuZW1iZWRkZWRUcmllKHRoaXMuYWRkZWQpKSksXG5cdFx0ICAgVHJpZS5jb21waWxlUGF0dGVybih0cnVlLCBhdE1ldGEoVHJpZS5lbWJlZGRlZFRyaWUodGhpcy5yZW1vdmVkKSkpKTtcbn07XG5cbnZhciBhdE1ldGFQcm9qID0gYXRNZXRhKF8kKTtcblBhdGNoLnByb3RvdHlwZS5kcm9wID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gbmV3IFBhdGNoKFRyaWUucHJvamVjdCh0aGlzLmFkZGVkLCBhdE1ldGFQcm9qKSxcblx0XHQgICBUcmllLnByb2plY3QodGhpcy5yZW1vdmVkLCBhdE1ldGFQcm9qKSk7XG59O1xuXG5QYXRjaC5wcm90b3R5cGUuc3RyaXAgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBuZXcgUGF0Y2goVHJpZS5yZWxhYmVsKHRoaXMuYWRkZWQsIGZ1bmN0aW9uICh2KSB7IHJldHVybiB0cnVlOyB9KSxcblx0XHQgICBUcmllLnJlbGFiZWwodGhpcy5yZW1vdmVkLCBmdW5jdGlvbiAodikgeyByZXR1cm4gdHJ1ZTsgfSkpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLmxhYmVsID0gZnVuY3Rpb24gKGxhYmVsVmFsdWUpIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChUcmllLnJlbGFiZWwodGhpcy5hZGRlZCwgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIGxhYmVsVmFsdWU7IH0pLFxuXHRcdCAgIFRyaWUucmVsYWJlbCh0aGlzLnJlbW92ZWQsIGZ1bmN0aW9uICh2KSB7IHJldHVybiBsYWJlbFZhbHVlOyB9KSk7XG59O1xuXG5QYXRjaC5wcm90b3R5cGUubGltaXQgPSBmdW5jdGlvbiAoYm91bmQpIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChUcmllLnN1YnRyYWN0KHRoaXMuYWRkZWQsIGJvdW5kLCBmdW5jdGlvbiAodjEsIHYyKSB7IHJldHVybiBUcmllLmVtcHR5VHJpZTsgfSksXG5cdFx0ICAgVHJpZS5pbnRlcnNlY3QodGhpcy5yZW1vdmVkLCBib3VuZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAodjEsIHYyKSB7IHJldHVybiBUcmllLnRyaWVTdWNjZXNzKHYxKTsgfSkpO1xufTtcblxudmFyIG1ldGFMYWJlbFNldCA9IEltbXV0YWJsZS5TZXQoW1wibWV0YVwiXSk7XG5QYXRjaC5wcm90b3R5cGUuY29tcHV0ZUFnZ3JlZ2F0ZSA9IGZ1bmN0aW9uIChsYWJlbCwgYmFzZSwgcmVtb3ZlTWV0YSAvKiBvcHRpb25hbCBmbGFnICovKSB7XG4gIHJldHVybiBuZXcgUGF0Y2goVHJpZS5zdWJ0cmFjdCh0aGlzLmFkZGVkLCBiYXNlLCBhZGRDb21iaW5lciksXG5cdFx0ICAgVHJpZS5zdWJ0cmFjdCh0aGlzLnJlbW92ZWQsIGJhc2UsIHJlbW92ZUNvbWJpbmVyKSk7XG5cbiAgZnVuY3Rpb24gYWRkQ29tYmluZXIodjEsIHYyKSB7XG4gICAgaWYgKHJlbW92ZU1ldGEgJiYgSW1tdXRhYmxlLmlzKHYyLCBtZXRhTGFiZWxTZXQpKSB7XG4gICAgICByZXR1cm4gVHJpZS50cmllU3VjY2Vzcyh2MSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBUcmllLmVtcHR5VHJpZTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVDb21iaW5lcih2MSwgdjIpIHtcbiAgICBpZiAodjIuc2l6ZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIFRyaWUudHJpZVN1Y2Nlc3ModjEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocmVtb3ZlTWV0YSAmJiB2Mi5zaXplID09PSAyICYmIHYyLmhhcyhcIm1ldGFcIikpIHtcblx0cmV0dXJuIFRyaWUudHJpZVN1Y2Nlc3ModjEpO1xuICAgICAgfSBlbHNlIHtcblx0cmV0dXJuIFRyaWUuZW1wdHlUcmllO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuUGF0Y2gucHJvdG90eXBlLmFwcGx5VG8gPSBmdW5jdGlvbiAoYmFzZSkge1xuICByZXR1cm4gVHJpZS5fdW5pb24oVHJpZS5zdWJ0cmFjdChiYXNlLCB0aGlzLnJlbW92ZWQpLCB0aGlzLmFkZGVkKTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS51cGRhdGVJbnRlcmVzdHMgPSBmdW5jdGlvbiAoYmFzZSkge1xuICByZXR1cm4gVHJpZS5fdW5pb24oVHJpZS5zdWJ0cmFjdChiYXNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICh2MSwgdjIpIHsgcmV0dXJuIFRyaWUuZW1wdHlUcmllOyB9KSxcblx0XHQgICAgIHRoaXMuYWRkZWQsXG5cdFx0ICAgICBmdW5jdGlvbiAodjEsIHYyKSB7IHJldHVybiB0cnVlTGFiZWw7IH0pO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLnVuYXBwbHlUbyA9IGZ1bmN0aW9uIChiYXNlKSB7XG4gIHJldHVybiBUcmllLl91bmlvbihUcmllLnN1YnRyYWN0KGJhc2UsIHRoaXMuYWRkZWQpLCB0aGlzLnJlbW92ZWQpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLmFuZFRoZW4gPSBmdW5jdGlvbiAobmV4dFBhdGNoKSB7XG4gIHJldHVybiBuZXcgUGF0Y2gobmV4dFBhdGNoLnVwZGF0ZUludGVyZXN0cyh0aGlzLmFkZGVkKSxcblx0XHQgICBUcmllLl91bmlvbihUcmllLnN1YnRyYWN0KHRoaXMucmVtb3ZlZCxcblx0XHRcdFx0XHQgICAgIG5leHRQYXRjaC5hZGRlZCxcblx0XHRcdFx0XHQgICAgIGZ1bmN0aW9uICh2MSwgdjIpIHsgcmV0dXJuIFRyaWUuZW1wdHlUcmllOyB9KSxcblx0XHRcdCAgICAgICBuZXh0UGF0Y2gucmVtb3ZlZCxcblx0XHRcdCAgICAgICBmdW5jdGlvbiAodjEsIHYyKSB7IHJldHVybiB0cnVlTGFiZWw7IH0pKTtcbn07XG5cbmZ1bmN0aW9uIHBhdGNoU2VxKC8qIHBhdGNoLCBwYXRjaCwgLi4uICovKSB7XG4gIHZhciBwID0gZW1wdHlQYXRjaDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBwID0gcC5hbmRUaGVuKGFyZ3VtZW50c1tpXSk7XG4gIH1cbiAgcmV0dXJuIHA7XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVQYXRjaChvbGRCYXNlLCBuZXdCYXNlKSB7XG4gIHJldHVybiBuZXcgUGF0Y2goVHJpZS5zdWJ0cmFjdChuZXdCYXNlLCBvbGRCYXNlKSxcblx0XHQgICBUcmllLnN1YnRyYWN0KG9sZEJhc2UsIG5ld0Jhc2UpKTtcbn1cblxuZnVuY3Rpb24gYmlhc2VkSW50ZXJzZWN0aW9uKG9iamVjdCwgc3ViamVjdCkge1xuICBzdWJqZWN0ID0gVHJpZS50cmllU3RlcChzdWJqZWN0LCBvYnNlcnZlLm1ldGEuYXJpdHksIG9ic2VydmUubWV0YSk7XG4gIHJldHVybiBUcmllLmludGVyc2VjdChvYmplY3QsIHN1YmplY3QsIGZ1bmN0aW9uICh2MSwgdjIpIHsgcmV0dXJuIFRyaWUudHJpZVN1Y2Nlc3ModjEpOyB9KTtcbn1cblxuUGF0Y2gucHJvdG90eXBlLnZpZXdGcm9tID0gZnVuY3Rpb24gKGludGVyZXN0cykge1xuICByZXR1cm4gbmV3IFBhdGNoKGJpYXNlZEludGVyc2VjdGlvbih0aGlzLmFkZGVkLCBpbnRlcmVzdHMpLFxuXHRcdCAgIGJpYXNlZEludGVyc2VjdGlvbih0aGlzLnJlbW92ZWQsIGludGVyZXN0cykpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLnVuc2FmZVVuaW9uID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gIC8vIFVuc2FmZSBiZWNhdXNlIGRvZXMgbm90IG5lY2Vzc2FyaWx5IHByZXNlcnZlIGludmFyaWFudCB0aGF0IGFkZGVkXG4gIC8vIGFuZCByZW1vdmVkIGFyZSBkaXNqb2ludC5cbiAgcmV0dXJuIG5ldyBQYXRjaChUcmllLl91bmlvbih0aGlzLmFkZGVkLCBvdGhlci5hZGRlZCksXG5cdFx0ICAgVHJpZS5fdW5pb24odGhpcy5yZW1vdmVkLCBvdGhlci5yZW1vdmVkKSk7XG59O1xuXG5QYXRjaC5wcm90b3R5cGUucHJvamVjdCA9IGZ1bmN0aW9uIChjb21waWxlZFByb2plY3Rpb24pIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChUcmllLnByb2plY3QodGhpcy5hZGRlZCwgY29tcGlsZWRQcm9qZWN0aW9uKSxcblx0XHQgICBUcmllLnByb2plY3QodGhpcy5yZW1vdmVkLCBjb21waWxlZFByb2plY3Rpb24pKTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS5wcm9qZWN0T2JqZWN0cyA9IGZ1bmN0aW9uIChjb21waWxlZFByb2plY3Rpb24pIHtcbiAgcmV0dXJuIFtUcmllLnByb2plY3RPYmplY3RzKHRoaXMuYWRkZWQsIGNvbXBpbGVkUHJvamVjdGlvbiksXG5cdCAgVHJpZS5wcm9qZWN0T2JqZWN0cyh0aGlzLnJlbW92ZWQsIGNvbXBpbGVkUHJvamVjdGlvbildO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLnByZXR0eSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIChcIjw8PDw8PDw8IFJlbW92ZWQ6XFxuXCIgKyBUcmllLnByZXR0eVRyaWUodGhpcy5yZW1vdmVkKSArIFwiXFxuXCIgK1xuXHQgIFwiPT09PT09PT0gQWRkZWQ6XFxuXCIgKyBUcmllLnByZXR0eVRyaWUodGhpcy5hZGRlZCkgKyBcIlxcblwiICtcblx0ICBcIj4+Pj4+Pj4+XCIpO1xufTtcblxuLy8gQ29tcGxldGVseSBpZ25vcmVzIHN1Y2Nlc3MtdmFsdWVzIGluIHQuXG5QYXRjaC5wcm90b3R5cGUucHJ1bmVkQnkgPSBmdW5jdGlvbiAodCkge1xuICByZXR1cm4gbmV3IFBhdGNoKFRyaWUuc3VidHJhY3QodGhpcy5hZGRlZCwgdCwgZnVuY3Rpb24gKHYxLCB2MikgeyByZXR1cm4gVHJpZS5lbXB0eVRyaWU7IH0pLFxuICAgICAgICAgICAgICAgICAgIFRyaWUuc3VidHJhY3QodGhpcy5yZW1vdmVkLCB0LCBmdW5jdGlvbiAodjEsIHYyKSB7IHJldHVybiBUcmllLmVtcHR5VHJpZTsgfSkpO1xufTtcblxudmFyIGF0TWV0YUV2ZXJ5dGhpbmcgPSBUcmllLmNvbXBpbGVQYXR0ZXJuKHRydWUsIGF0TWV0YS5wYXR0ZXJuKTtcblBhdGNoLnByb3RvdHlwZS53aXRob3V0QXRNZXRhID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5wcnVuZWRCeShhdE1ldGFFdmVyeXRoaW5nKTtcbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5QYXRjaC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gW1RyaWUudHJpZVRvSlNPTih0aGlzLmFkZGVkKSwgVHJpZS50cmllVG9KU09OKHRoaXMucmVtb3ZlZCldO1xufTtcblxuZnVuY3Rpb24gZnJvbUpTT04oaikge1xuICByZXR1cm4gbmV3IFBhdGNoKFRyaWUudHJpZUZyb21KU09OKGpbMF0pLCBUcmllLnRyaWVGcm9tSlNPTihqWzFdKSk7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5QYXRjaCA9IFBhdGNoO1xubW9kdWxlLmV4cG9ydHMuZW1wdHlQYXRjaCA9IGVtcHR5UGF0Y2g7XG5tb2R1bGUuZXhwb3J0cy5yZW1vdmVFdmVyeXRoaW5nUGF0Y2ggPSByZW1vdmVFdmVyeXRoaW5nUGF0Y2g7XG5cbm1vZHVsZS5leHBvcnRzLm9ic2VydmUgPSBvYnNlcnZlO1xubW9kdWxlLmV4cG9ydHMuYXRNZXRhID0gYXRNZXRhO1xubW9kdWxlLmV4cG9ydHMuYWR2ZXJ0aXNlID0gYWR2ZXJ0aXNlO1xuXG5tb2R1bGUuZXhwb3J0cy5wcmVwZW5kQXRNZXRhID0gcHJlcGVuZEF0TWV0YTtcbm1vZHVsZS5leHBvcnRzLnN0cmlwQXRNZXRhID0gc3RyaXBBdE1ldGE7XG5tb2R1bGUuZXhwb3J0cy5vYnNlcnZlQXRNZXRhID0gb2JzZXJ2ZUF0TWV0YTtcbm1vZHVsZS5leHBvcnRzLmFzc2VydCA9IGFzc2VydDtcbm1vZHVsZS5leHBvcnRzLnJldHJhY3QgPSByZXRyYWN0O1xubW9kdWxlLmV4cG9ydHMuc3ViID0gc3ViO1xubW9kdWxlLmV4cG9ydHMudW5zdWIgPSB1bnN1Yjtcbm1vZHVsZS5leHBvcnRzLnB1YiA9IHB1Yjtcbm1vZHVsZS5leHBvcnRzLnVucHViID0gdW5wdWI7XG5cbm1vZHVsZS5leHBvcnRzLnBhdGNoU2VxID0gcGF0Y2hTZXE7XG5tb2R1bGUuZXhwb3J0cy5jb21wdXRlUGF0Y2ggPSBjb21wdXRlUGF0Y2g7XG5tb2R1bGUuZXhwb3J0cy5iaWFzZWRJbnRlcnNlY3Rpb24gPSBiaWFzZWRJbnRlcnNlY3Rpb247XG5cbm1vZHVsZS5leHBvcnRzLmZyb21KU09OID0gZnJvbUpTT047XG4iLCJ2YXIgcmFuZG9tSWQ7XG5cbmlmICgodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpICYmXG4gICAgKHR5cGVvZiB3aW5kb3cuY3J5cHRvICE9PSAndW5kZWZpbmVkJykgJiZcbiAgICAodHlwZW9mIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzICE9PSAndW5kZWZpbmVkJykpIHtcbiAgcmFuZG9tSWQgPSBmdW5jdGlvbiAoYnl0ZUNvdW50LCBoZXhPdXRwdXQpIHtcbiAgICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZUNvdW50KTtcbiAgICB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpO1xuICAgIGlmIChoZXhPdXRwdXQpIHtcbiAgICAgIHZhciBlbmNvZGVkID0gW107XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ1Zi5sZW5ndGg7IGkrKykge1xuXHRlbmNvZGVkLnB1c2goXCIwMTIzNDU2Nzg5YWJjZGVmXCJbKGJ1ZltpXSA+PiA0KSAmIDE1XSk7XG5cdGVuY29kZWQucHVzaChcIjAxMjM0NTY3ODlhYmNkZWZcIltidWZbaV0gJiAxNV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVuY29kZWQuam9pbignJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBidG9hKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgYnVmKSkucmVwbGFjZSgvPS9nLCcnKTtcbiAgICB9XG4gIH07XG59IGVsc2Uge1xuICB2YXIgY3J5cHRvO1xuICB0cnkge1xuICAgIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuICB9IGNhdGNoIChlKSB7fVxuICBpZiAoKHR5cGVvZiBjcnlwdG8gIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgKHR5cGVvZiBjcnlwdG8ucmFuZG9tQnl0ZXMgIT09ICd1bmRlZmluZWQnKSkge1xuICAgIHJhbmRvbUlkID0gZnVuY3Rpb24gKGJ5dGVDb3VudCwgaGV4T3V0cHV0KSB7XG4gICAgICBpZiAoaGV4T3V0cHV0KSB7XG4gICAgICAgIHJldHVybiBjcnlwdG8ucmFuZG9tQnl0ZXMoYnl0ZUNvdW50KS5oZXhTbGljZSgpLnJlcGxhY2UoLz0vZywnJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gY3J5cHRvLnJhbmRvbUJ5dGVzKGJ5dGVDb3VudCkuYmFzZTY0U2xpY2UoKS5yZXBsYWNlKC89L2csJycpO1xuICAgICAgfVxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS53YXJuKCdObyBzdWl0YWJsZSBpbXBsZW1lbnRhdGlvbiBmb3IgUmFuZG9tSUQucmFuZG9tSWQgYXZhaWxhYmxlLicpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzLnJhbmRvbUlkID0gcmFuZG9tSWQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuLy8gUmVmbGVjdGlvbiBvbiBmdW5jdGlvbiBmb3JtYWwgcGFyYW1ldGVyIGxpc3RzLlxuLy8gVGhpcyBtb2R1bGUgaXMgYmFzZWQgb24gQW5ndWxhcidzIFwiaW5qZWN0b3JcIiBjb2RlLFxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci5qcy9ibG9iL21hc3Rlci9zcmMvYXV0by9pbmplY3Rvci5qcyxcbi8vIE1JVCBsaWNlbnNlZCwgYW5kIGhlbmNlOlxuLy8gQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgR29vZ2xlLCBJbmMuIGh0dHA6Ly9hbmd1bGFyanMub3JnXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTQgVG9ueSBHYXJub2NrLUpvbmVzXG5cbnZhciBGTl9BUkdTID0gL15mdW5jdGlvblxccypbXlxcKF0qXFwoXFxzKihbXlxcKV0qKVxcKS9tO1xudmFyIEZOX0FSR19TUExJVCA9IC8sLztcbnZhciBTVFJJUF9DT01NRU5UUyA9IC8oKFxcL1xcLy4qJCl8KFxcL1xcKltcXHNcXFNdKj9cXCpcXC8pKS9tZztcblxuZnVuY3Rpb24gZm9ybWFsUGFyYW1ldGVycyhmbikge1xuICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgIHZhciBmblRleHQgPSBmbi50b1N0cmluZygpLnJlcGxhY2UoU1RSSVBfQ09NTUVOVFMsICcnKTtcbiAgICB2YXIgYXJnRGVjbCA9IGZuVGV4dC5tYXRjaChGTl9BUkdTKTtcbiAgICB2YXIgYXJncyA9IGFyZ0RlY2xbMV0uc3BsaXQoRk5fQVJHX1NQTElUKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcblx0dmFyIHRyaW1tZWQgPSBhcmdzW2ldLnRyaW0oKTtcblx0aWYgKHRyaW1tZWQpIHsgcmVzdWx0LnB1c2godHJpbW1lZCk7IH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cy5mb3JtYWxQYXJhbWV0ZXJzID0gZm9ybWFsUGFyYW1ldGVycztcbiIsInZhciBJbW11dGFibGUgPSByZXF1aXJlKCdpbW11dGFibGUnKTtcblxuZnVuY3Rpb24gU2VhbChjb250ZW50cykge1xuICB0aGlzLnNlYWxDb250ZW50cyA9IGNvbnRlbnRzO1xuICBPYmplY3QuZnJlZXplKHRoaXMpO1xufVxuXG5TZWFsLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZWFsKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gSW1tdXRhYmxlLmlzKHRoaXMuc2VhbENvbnRlbnRzLCBvdGhlci5zZWFsQ29udGVudHMpO1xufTtcblxuZnVuY3Rpb24gc2VhbChjb250ZW50cykge1xuICByZXR1cm4gbmV3IFNlYWwoY29udGVudHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cy5TZWFsID0gU2VhbDtcbm1vZHVsZS5leHBvcnRzLnNlYWwgPSBzZWFsO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vLyAkU3BlY2lhbDogQnVpbGRlciBvZiBzaW5nbGV0b24gXCJhdG9tc1wiLlxuXG5mdW5jdGlvbiAkU3BlY2lhbChuYW1lKSB7XG4gIHRoaXMubmFtZSA9IG5hbWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gJFNwZWNpYWw7XG4iLCJcInVzZSBzdHJpY3RcIjtcbi8vIFwiU3RydWN0dXJlc1wiOiBTaW1wbGUgbmFtZWQtdHVwbGUtbGlrZSByZWNvcmRzLlxuXG52YXIgSW1tdXRhYmxlID0gcmVxdWlyZShcImltbXV0YWJsZVwiKTtcbnZhciAkU3BlY2lhbCA9IHJlcXVpcmUoJy4vc3BlY2lhbC5qcycpO1xuXG4vKiBEZWZpbmVkIGhlcmUgcmF0aGVyIHRoYW4gaW4gdHJpZS5qcyBiZWNhdXNlIHdlIG5lZWQgaXQgaW4gbWFrZUNvbnN0cnVjdG9yLiAqL1xudmFyIF9fID0gbmV3ICRTcGVjaWFsKFwid2lsZGNhcmRcIik7IC8qIHdpbGRjYXJkIG1hcmtlciAqL1xuXG5mdW5jdGlvbiBTdHJ1Y3R1cmVUeXBlKGxhYmVsLCBhcml0eSkge1xuICB0aGlzLmxhYmVsID0gbGFiZWw7XG4gIHRoaXMuYXJpdHkgPSBhcml0eTtcbiAgdGhpcy5wYXR0ZXJuID0gdGhpcy5pbnN0YW50aWF0ZShJbW11dGFibGUuUmVwZWF0KF9fLCBhcml0eSkudG9BcnJheSgpKTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuY3RvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gc2VsZi5pbnN0YW50aWF0ZShBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKTtcbiAgfTtcbiAgdGhpcy5jdG9yLm1ldGEgPSB0aGlzO1xuICB0aGlzLmN0b3IucGF0dGVybiA9IHRoaXMucGF0dGVybjtcbiAgdGhpcy5jdG9yLmlzQ2xhc3NPZiA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBzZWxmLmlzQ2xhc3NPZih2KTsgfTtcbn1cblxuZnVuY3Rpb24gbWFrZUNvbnN0cnVjdG9yKGxhYmVsLCBmaWVsZE5hbWVzKSB7XG4gIHJldHVybiBuZXcgU3RydWN0dXJlVHlwZShsYWJlbCwgZmllbGROYW1lcy5sZW5ndGgpLmN0b3I7XG59XG5cblN0cnVjdHVyZVR5cGUucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFN0cnVjdHVyZVR5cGUpKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiB0aGlzLmFyaXR5ID09PSBvdGhlci5hcml0eSAmJiB0aGlzLmxhYmVsID09PSBvdGhlci5sYWJlbDtcbn07XG5cblN0cnVjdHVyZVR5cGUucHJvdG90eXBlLmluc3RhbnRpYXRlID0gZnVuY3Rpb24gKGZpZWxkcykge1xuICByZXR1cm4gbmV3IFN0cnVjdHVyZSh0aGlzLCBmaWVsZHMpO1xufTtcblxuU3RydWN0dXJlVHlwZS5wcm90b3R5cGUuaXNDbGFzc09mID0gZnVuY3Rpb24gKHYpIHtcbiAgcmV0dXJuIHYgJiYgKHYgaW5zdGFuY2VvZiBTdHJ1Y3R1cmUpICYmICh2Lm1ldGEuZXF1YWxzKHRoaXMpKTtcbn07XG5cbmZ1bmN0aW9uIFN0cnVjdHVyZShtZXRhLCBmaWVsZHMpIHtcbiAgaWYgKCFpc1N0cnVjdHVyZVR5cGUobWV0YSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJTdHJ1Y3R1cmU6IHJlcXVpcmVzIHN0cnVjdHVyZSB0eXBlXCIpO1xuICB9XG4gIGlmIChmaWVsZHMubGVuZ3RoICE9PSBtZXRhLmFyaXR5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiU3RydWN0dXJlOiBjYW5ub3QgaW5zdGFudGlhdGUgbWV0YSBcIitKU09OLnN0cmluZ2lmeShtZXRhLmxhYmVsKStcbiAgICAgICAgICAgICAgICAgICAgXCIgZXhwZWN0aW5nIFwiK21ldGEuYXJpdHkrXCIgZmllbGRzIHdpdGggXCIrZmllbGRzLmxlbmd0aCtcIiBmaWVsZHNcIik7XG4gIH1cbiAgdGhpcy5tZXRhID0gbWV0YTtcbiAgdGhpcy5sZW5ndGggPSBtZXRhLmFyaXR5O1xuICB0aGlzLmZpZWxkcyA9IGZpZWxkcy5zbGljZSgwKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWVsZHMubGVuZ3RoOyBpKyspIHtcbiAgICB0aGlzW2ldID0gZmllbGRzW2ldO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJldml2ZVN0cnVjdHMoaikge1xuICBpZiAoQXJyYXkuaXNBcnJheShqKSkge1xuICAgIHJldHVybiBqLm1hcChyZXZpdmVTdHJ1Y3RzKTtcbiAgfVxuXG4gIGlmICgoaiAhPT0gbnVsbCkgJiYgdHlwZW9mIGogPT09ICdvYmplY3QnKSB7XG4gICAgaWYgKCh0eXBlb2YgalsnQHR5cGUnXSA9PT0gJ3N0cmluZycpICYmIEFycmF5LmlzQXJyYXkoalsnZmllbGRzJ10pKSB7XG4gICAgICByZXR1cm4gKG5ldyBTdHJ1Y3R1cmVUeXBlKGpbJ0B0eXBlJ10sIGpbJ2ZpZWxkcyddLmxlbmd0aCkpLmluc3RhbnRpYXRlKGpbJ2ZpZWxkcyddKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgayBpbiBqKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoaiwgaykpIHtcbiAgICAgICAgICBqW2tdID0gcmV2aXZlU3RydWN0cyhqW2tdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGo7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGo7XG59XG5cbmZ1bmN0aW9uIHJldml2ZXIoaywgdikge1xuICBpZiAoayA9PT0gJycpIHtcbiAgICByZXR1cm4gcmV2aXZlU3RydWN0cyh2KTtcbiAgfVxuICByZXR1cm4gdjtcbn07XG5cblN0cnVjdHVyZS5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4geyAnQHR5cGUnOiB0aGlzLm1ldGEubGFiZWwsICdmaWVsZHMnOiB0aGlzLmZpZWxkcyB9O1xufTtcblxuZnVuY3Rpb24gaXNTdHJ1Y3R1cmVUeXBlKHYpIHtcbiAgcmV0dXJuIHYgJiYgKHYgaW5zdGFuY2VvZiBTdHJ1Y3R1cmVUeXBlKTtcbn1cblxuZnVuY3Rpb24gaXNTdHJ1Y3R1cmUodikge1xuICByZXR1cm4gdiAmJiAodiBpbnN0YW5jZW9mIFN0cnVjdHVyZSk7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5fXyA9IF9fO1xubW9kdWxlLmV4cG9ydHMuU3RydWN0dXJlVHlwZSA9IFN0cnVjdHVyZVR5cGU7XG5tb2R1bGUuZXhwb3J0cy5tYWtlQ29uc3RydWN0b3IgPSBtYWtlQ29uc3RydWN0b3I7XG5tb2R1bGUuZXhwb3J0cy5TdHJ1Y3R1cmUgPSBTdHJ1Y3R1cmU7XG5tb2R1bGUuZXhwb3J0cy5yZXZpdmVTdHJ1Y3RzID0gcmV2aXZlU3RydWN0cztcbm1vZHVsZS5leHBvcnRzLnJldml2ZXIgPSByZXZpdmVyO1xubW9kdWxlLmV4cG9ydHMuaXNTdHJ1Y3R1cmVUeXBlID0gaXNTdHJ1Y3R1cmVUeXBlO1xubW9kdWxlLmV4cG9ydHMuaXNTdHJ1Y3R1cmUgPSBpc1N0cnVjdHVyZTtcbiIsIi8vIFRpbWVyIGV2ZW50IGRyaXZlclxudmFyIFBhdGNoID0gcmVxdWlyZShcIi4vcGF0Y2guanNcIik7XG52YXIgRGVtYW5kTWF0Y2hlciA9IHJlcXVpcmUoJy4vZGVtYW5kLW1hdGNoZXIuanMnKS5EZW1hbmRNYXRjaGVyO1xudmFyIFN0cnVjdCA9IHJlcXVpcmUoJy4vc3RydWN0LmpzJyk7XG5cbnZhciBEYXRhc3BhY2VfID0gcmVxdWlyZShcIi4vZGF0YXNwYWNlLmpzXCIpO1xudmFyIERhdGFzcGFjZSA9IERhdGFzcGFjZV8uRGF0YXNwYWNlO1xudmFyIF9fID0gRGF0YXNwYWNlXy5fXztcbnZhciBfJCA9IERhdGFzcGFjZV8uXyQ7XG5cbnZhciBwZXJpb2RpY1RpY2sgPSBTdHJ1Y3QubWFrZUNvbnN0cnVjdG9yKCdwZXJpb2RpY1RpY2snLCBbJ2ludGVydmFsTVMnXSk7IC8vIG1lc3NhZ2VcbnZhciB0aW1lTGF0ZXJUaGFuID0gU3RydWN0Lm1ha2VDb25zdHJ1Y3RvcigndGltZUxhdGVyVGhhbicsIFsnZGVhZGxpbmVNUyddKTsgLy8gYXNzZXJ0aW9uXG5cbmZ1bmN0aW9uIHNwYXduVGltZXJEcml2ZXIoKSB7XG4gIERhdGFzcGFjZS5zcGF3bihcbiAgICBuZXcgRGVtYW5kTWF0Y2hlcihbUGF0Y2gub2JzZXJ2ZShwZXJpb2RpY1RpY2soXyQoJ2ludGVydmFsTVMnKSkpXSxcblx0XHQgICAgICBbUGF0Y2guYWR2ZXJ0aXNlKHBlcmlvZGljVGljayhfJCgnaW50ZXJ2YWxNUycpKSldLFxuICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChjKSB7XG5cdFx0XHREYXRhc3BhY2Uuc3Bhd24obmV3IFRpY2soYy5pbnRlcnZhbE1TKSk7XG5cdFx0ICAgICAgfSkpO1xuICBEYXRhc3BhY2Uuc3Bhd24oXG4gICAgbmV3IERlbWFuZE1hdGNoZXIoW1BhdGNoLm9ic2VydmUodGltZUxhdGVyVGhhbihfJCgnZGVhZGxpbmVNUycpKSldLFxuXHRcdCAgICAgIFtQYXRjaC5hZHZlcnRpc2UodGltZUxhdGVyVGhhbihfJCgnZGVhZGxpbmVNUycpKSldLFxuICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChjKSB7XG5cdFx0XHREYXRhc3BhY2Uuc3Bhd24obmV3IEFsYXJtKGMuZGVhZGxpbmVNUykpO1xuXHRcdCAgICAgIH0pKTtcbn1cblxuZnVuY3Rpb24gVGljayhpbnRlcnZhbE1TKSB7XG4gIHRoaXMuaW50ZXJ2YWxNUyA9IGludGVydmFsTVM7XG4gIHRoaXMuaGFuZGxlID0gbnVsbDtcbn1cblxuVGljay5wcm90b3R5cGUuYm9vdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLmhhbmRsZSA9IHNldEludGVydmFsKERhdGFzcGFjZS53cmFwKGZ1bmN0aW9uICgpIHtcbiAgICBEYXRhc3BhY2Uuc2VuZChwZXJpb2RpY1RpY2soc2VsZi5pbnRlcnZhbE1TKSk7XG4gIH0pLCB0aGlzLmludGVydmFsTVMpO1xuXG4gIHJldHVybiBQYXRjaC5zdWIoUGF0Y2gub2JzZXJ2ZShwZXJpb2RpY1RpY2sodGhpcy5pbnRlcnZhbE1TKSkpIC8vIG1vbml0b3IgaW50ZXJlc3RcbiAgICAuYW5kVGhlbihQYXRjaC5wdWIocGVyaW9kaWNUaWNrKHRoaXMuaW50ZXJ2YWxNUykpKSAvLyBzaWduYWwgd2UgZXhpc3QgdG8gRGVtYW5kTWF0Y2hlclxuICA7XG59O1xuXG5UaWNrLnByb3RvdHlwZS50cmFwZXhpdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5jYW5jZWxUaW1lcigpO1xufTtcblxuVGljay5wcm90b3R5cGUuY2FuY2VsVGltZXIgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmhhbmRsZSAhPT0gbnVsbCkge1xuICAgIGNsZWFySW50ZXJ2YWwodGhpcy5oYW5kbGUpO1xuICAgIHRoaXMuaGFuZGxlID0gbnVsbDtcbiAgfVxufTtcblxuVGljay5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICBpZiAoZS50eXBlID09PSAnc3RhdGVDaGFuZ2UnICYmIGUucGF0Y2guaGFzUmVtb3ZlZCgpKSB7XG4gICAgRGF0YXNwYWNlLmV4aXQoKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gQWxhcm0oZGVhZGxpbmVNUykge1xuICB0aGlzLmRlYWRsaW5lTVMgPSBkZWFkbGluZU1TO1xuICB0aGlzLmhhbmRsZSA9IG51bGw7XG59XG5cbkFsYXJtLnByb3RvdHlwZS5ib290ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmNoZWNrVGltZW91dCgpO1xuXG4gIHJldHVybiBQYXRjaC5zdWIoUGF0Y2gub2JzZXJ2ZSh0aW1lTGF0ZXJUaGFuKHRoaXMuZGVhZGxpbmVNUykpKSAvLyBtb25pdG9yIGludGVyZXN0XG4gICAgLmFuZFRoZW4oUGF0Y2gucHViKHRpbWVMYXRlclRoYW4odGhpcy5kZWFkbGluZU1TKSkpIC8vIHNpZ25hbCB3ZSBleGlzdCB0byBEZW1hbmRNYXRjaGVyXG4gIDtcbn07XG5cbkFsYXJtLnByb3RvdHlwZS5jaGVja1RpbWVvdXQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBub3cgPSArKG5ldyBEYXRlKCkpO1xuICB2YXIgZGVsdGEgPSB0aGlzLmRlYWRsaW5lTVMgLSBub3c7XG4gIGlmIChkZWx0YSA8PSAwKSB7XG4gICAgRGF0YXNwYWNlLnN0YXRlQ2hhbmdlKFBhdGNoLmFzc2VydCh0aW1lTGF0ZXJUaGFuKHRoaXMuZGVhZGxpbmVNUykpKTtcbiAgICB0aGlzLmNhbmNlbFRpbWVyKCk7XG4gIH0gZWxzZSBpZiAodGhpcy5oYW5kbGUgPT09IG51bGwpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5oYW5kbGUgPSBzZXRUaW1lb3V0KERhdGFzcGFjZS53cmFwKGZ1bmN0aW9uICgpIHsgc2VsZi5jaGVja1RpbWVvdXQoKTsgfSksIGRlbHRhKTtcbiAgfVxufTtcblxuQWxhcm0ucHJvdG90eXBlLmNhbmNlbFRpbWVyID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5oYW5kbGUgIT09IG51bGwpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5oYW5kbGUpO1xuICAgIHRoaXMuaGFuZGxlID0gbnVsbDtcbiAgfVxufTtcblxuQWxhcm0ucHJvdG90eXBlLnRyYXBleGl0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmNhbmNlbFRpbWVyKCk7XG59O1xuXG5BbGFybS5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICBpZiAoZS50eXBlID09PSAnc3RhdGVDaGFuZ2UnICYmIGUucGF0Y2guaGFzUmVtb3ZlZCgpKSB7XG4gICAgRGF0YXNwYWNlLmV4aXQoKTtcbiAgfVxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLnNwYXduVGltZXJEcml2ZXIgPSBzcGF3blRpbWVyRHJpdmVyO1xubW9kdWxlLmV4cG9ydHMucGVyaW9kaWNUaWNrID0gcGVyaW9kaWNUaWNrO1xubW9kdWxlLmV4cG9ydHMudGltZUxhdGVyVGhhbiA9IHRpbWVMYXRlclRoYW47XG5tb2R1bGUuZXhwb3J0cy5UaWNrID0gVGljaztcbm1vZHVsZS5leHBvcnRzLkFsYXJtID0gQWxhcm07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIEltbXV0YWJsZSA9IHJlcXVpcmUoXCJpbW11dGFibGVcIik7XG52YXIgU3RydWN0ID0gcmVxdWlyZSgnLi9zdHJ1Y3QuanMnKTtcbnZhciAkU3BlY2lhbCA9IHJlcXVpcmUoJy4vc3BlY2lhbC5qcycpO1xuXG5mdW5jdGlvbiBkaWUobWVzc2FnZSkge1xuICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gVHJpZSByZXByZXNlbnRhdGlvbnNcbi8vXG4vLyBBIFRyaWUgaXMgb25lIG9mXG4vLyAgLSBlbXB0eVRyaWVcbi8vICAtIGFuIGluc3RhbmNlIG9mICRTdWNjZXNzXG4vLyAgLSBhbiBpbnN0YW5jZSBvZiAkQnJhbmNoXG5cbnZhciBlbXB0eVRyaWUgPSBuZXcgJFNwZWNpYWwoXCJNdFwiKTtcblxuZnVuY3Rpb24gaXNfZW1wdHlUcmllKG0pIHtcbiAgcmV0dXJuIG0gPT09IGVtcHR5VHJpZTtcbn1cblxuZnVuY3Rpb24gJFN1Y2Nlc3ModmFsdWUpIHtcbiAgdGhpcy52YWx1ZSA9IHZhbHVlO1xufVxuXG4kU3VjY2Vzcy5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gIGlmICghKG90aGVyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBJbW11dGFibGUuaXModGhpcy52YWx1ZSwgb3RoZXIudmFsdWUpO1xufTtcblxuZnVuY3Rpb24gJEJyYW5jaCh3aWxkLCBlZGdlcywgY291bnQpIHtcbiAgdGhpcy53aWxkID0gd2lsZCB8fCBlbXB0eVRyaWU7IC8vIFRyaWVcbiAgdGhpcy5lZGdlcyA9IGVkZ2VzIHx8IEltbXV0YWJsZS5NYXAoKTsgLy8gTWFwIGZyb20gYXJpdHkgdG8gTWFwIGZyb20ga2V5LWxpa2UtdGhpbmcgdG8gVHJpZVxuICAvLyAoU2lnbWFzIGFyZSAwLWFyeS4pXG4gIHRoaXMuY291bnQgPSBjb3VudCB8fCAwO1xufVxuXG4kQnJhbmNoLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiAkQnJhbmNoKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gKHRoaXMuY291bnQgPT09IG90aGVyLmNvdW50KSAmJiBJbW11dGFibGUuaXModGhpcy53aWxkLCBvdGhlci53aWxkKSAmJiBJbW11dGFibGUuaXModGhpcy5lZGdlcywgb3RoZXIuZWRnZXMpO1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBQYXR0ZXJucywgcHJvamVjdGlvbnMgYW5kIGNhcHR1cmVzXG5cbnZhciBfXyA9IFN0cnVjdC5fXzsgLyogaW1wb3J0ZWQgcmF0aGVyIHRoYW4gZGVmaW5lZCBoZXJlIGJlY2F1c2Ugb2YgY3ljbGljIGRlcCBpbiBTdHJ1Y3QgKi9cbnZhciBTT0EgPSBuZXcgJFNwZWNpYWwoXCJhcnJheVwiKTsgLyoga2V5IGZvciBzdGFydC1vZi1hcnJheSAqL1xuXG5mdW5jdGlvbiAkRW1iZWRkZWQodHJpZSwgYXJyYXlMZW5ndGgpIHtcbiAgdGhpcy50cmllID0gdHJpZTtcbiAgdGhpcy5hcnJheUxlbmd0aCA9IGFycmF5TGVuZ3RoO1xufVxuXG5mdW5jdGlvbiBlbWJlZGRlZFRyaWUodHJpZSkge1xuICByZXR1cm4gbmV3ICRFbWJlZGRlZCh0cmllLCBudWxsKTtcbn1cblxuZnVuY3Rpb24gZW1iZWRkZWRUcmllQXJyYXkodHJpZSwgYXJyYXlMZW5ndGgpIHtcbiAgcmV0dXJuIG5ldyAkRW1iZWRkZWQodHJpZSwgYXJyYXlMZW5ndGgpO1xufVxuXG4vLyBUaGUgbmFtZSBhcmd1bWVudCBzaG91bGQgYmUgYSBzdHJpbmcgb3IgbnVsbDsgaXQgZGVmYXVsdHMgdG8gbnVsbC5cbi8vIFRoZSBwYXR0ZXJuIGFyZ3VtZW50IGRlZmF1bHRzIHRvIHdpbGRjYXJkLCBfXy5cbmZ1bmN0aW9uICRDYXB0dXJlKG5hbWUsIHBhdHRlcm4pIHtcbiAgdGhpcy5uYW1lID0gbmFtZSB8fCBudWxsO1xuICB0aGlzLnBhdHRlcm4gPSAodHlwZW9mIHBhdHRlcm4gPT09ICd1bmRlZmluZWQnID8gX18gOiBwYXR0ZXJuKTtcbn1cblxuLy8gQWJicmV2aWF0aW9uOiBfJCguLi4pIDw9PT4gbmV3ICRDYXB0dXJlKC4uLilcbmZ1bmN0aW9uIF8kKG5hbWUsIHBhdHRlcm4pIHtcbiAgcmV0dXJuIG5ldyAkQ2FwdHVyZShuYW1lLCBwYXR0ZXJuKTtcbn1cblxuZnVuY3Rpb24gaXNDYXB0dXJlKHgpIHsgcmV0dXJuIHggaW5zdGFuY2VvZiAkQ2FwdHVyZSB8fCB4ID09PSBfJDsgfVxuZnVuY3Rpb24gY2FwdHVyZU5hbWUoeCkgeyByZXR1cm4geCBpbnN0YW5jZW9mICRDYXB0dXJlID8geC5uYW1lIDogbnVsbDsgfVxuZnVuY3Rpb24gY2FwdHVyZVBhdHRlcm4oeCkgeyByZXR1cm4geCBpbnN0YW5jZW9mICRDYXB0dXJlID8geC5wYXR0ZXJuIDogX187IH1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBDb25zdHJ1Y3RvcnNcblxuZnVuY3Rpb24gcnN1Y2Nlc3Modikge1xuICByZXR1cm4gbmV3ICRTdWNjZXNzKHYpO1xufVxuXG5mdW5jdGlvbiByc2VxKGFyaXR5LCBrZXksIHIpIHtcbiAgaWYgKGlzX2VtcHR5VHJpZShyKSkgcmV0dXJuIGVtcHR5VHJpZTtcbiAgcmV0dXJuIG5ldyAkQnJhbmNoKGVtcHR5VHJpZSwgSW1tdXRhYmxlLk1hcC5vZihhcml0eSwgSW1tdXRhYmxlLk1hcC5vZihrZXksIHIpKSwgMSk7XG59XG5cbmZ1bmN0aW9uIHJ3aWxkKHIpIHtcbiAgaWYgKGlzX2VtcHR5VHJpZShyKSkgcmV0dXJuIGVtcHR5VHJpZTtcbiAgcmV0dXJuIG5ldyAkQnJhbmNoKHIsIEltbXV0YWJsZS5NYXAoKSwgMCk7XG59XG5cbmZ1bmN0aW9uIHJjb3B5YnJhbmNoKHIpIHtcbiAgcmV0dXJuIG5ldyAkQnJhbmNoKHIud2lsZCwgci5lZGdlcywgci5jb3VudCk7XG59XG5cbmZ1bmN0aW9uIHByZXBlbmRfd2lsZHMobiwgcikge1xuICB3aGlsZSAobi0tID4gMCkgeyByID0gcndpbGQocik7IH1cbiAgcmV0dXJuIHI7XG59XG5cbi8vIHRydWUgaWZmIHIxIGNvdWxkIGhhdmUgYmVlbiB0aGUgb3V0cHV0IG9mIHByZXBlbmRfd2lsZHMobiwgcjIpLlxuZnVuY3Rpb24gZXF1YWxfdXB0b193aWxkcyhuLCByMSwgcjIpIHtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAobiA9PT0gMCB8fCBpc19lbXB0eVRyaWUocjEpKSB7XG4gICAgICByZXR1cm4gSW1tdXRhYmxlLmlzKHIxLCByMik7XG4gICAgfVxuICAgIGlmICghKHIxIGluc3RhbmNlb2YgJEJyYW5jaCkgfHwgcjEuY291bnQgPiAwKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIG4gPSBuIC0gMTtcbiAgICByMSA9IHIxLndpbGQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gcnVwZGF0ZV9pbnBsYWNlKHIsIGFyaXR5LCBrZXksIGspIHtcbiAgaWYgKGVxdWFsX3VwdG9fd2lsZHMoYXJpdHksIGssIHIud2lsZCkpIHtcbiAgICB2YXIgbSA9IHIuZWRnZXMuZ2V0KGFyaXR5KTtcbiAgICBpZiAoIW0pIHJldHVybjtcbiAgICBpZiAobS5oYXMoa2V5KSkgci5jb3VudC0tO1xuICAgIG0gPSBtLnJlbW92ZShrZXkpO1xuICAgIHIuZWRnZXMgPSBtLmlzRW1wdHkoKSA/IHIuZWRnZXMucmVtb3ZlKGFyaXR5KSA6IHIuZWRnZXMuc2V0KGFyaXR5LCBtKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbSA9IHIuZWRnZXMuZ2V0KGFyaXR5KSB8fCBJbW11dGFibGUuTWFwKCk7XG4gICAgaWYgKCFtLmhhcyhrZXkpKSByLmNvdW50Kys7XG4gICAgci5lZGdlcyA9IHIuZWRnZXMuc2V0KGFyaXR5LCBtLnNldChrZXksIGspKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBybG9va3VwKHIsIGFyaXR5LCBrZXkpIHtcbiAgdmFyIG0gPSByLmVkZ2VzLmdldChhcml0eSk7XG4gIG0gPSBtICYmIG0uZ2V0KGtleSk7XG4gIHJldHVybiBtIHx8IHByZXBlbmRfd2lsZHMoYXJpdHksIHIud2lsZCk7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBjb2xsYXBzZShyKSB7XG4gIGlmICgociBpbnN0YW5jZW9mICRCcmFuY2gpICYmIGlzX2VtcHR5VHJpZShyLndpbGQpICYmIChyLmNvdW50ID09PSAwKSkge1xuICAgIHJldHVybiBlbXB0eVRyaWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHI7XG4gIH1cbn1cblxuLy8gdXNlIHdpdGggZXh0cmVtZSBjYXJlXG5mdW5jdGlvbiBuZXdFbXB0eUJyYW5jaCgpIHtcbiAgcmV0dXJuIG5ldyAkQnJhbmNoKGVtcHR5VHJpZSwgSW1tdXRhYmxlLk1hcCgpLCAwKTtcbn1cblxudmFyIGNhbm9uaWNhbEV4cGFuZGVkRW1wdHkgPSBuZXdFbXB0eUJyYW5jaCgpO1xuZnVuY3Rpb24gZXhwYW5kKHIpIHtcbiAgaWYgKGlzX2VtcHR5VHJpZShyKSkge1xuICAgIHJldHVybiBjYW5vbmljYWxFeHBhbmRlZEVtcHR5O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiByO1xuICB9XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBjb21waWxlUGF0dGVybih2LCBwKSB7XG4gIGlmICghcCkgZGllKFwiY29tcGlsZVBhdHRlcm46IG1pc3NpbmcgcGF0dGVyblwiKTtcbiAgcmV0dXJuIHdhbGsocCwgcnN1Y2Nlc3ModikpO1xuXG4gIGZ1bmN0aW9uIHdhbGsocCwgYWNjKSB7XG4gICAgaWYgKHAgPT09IF9fKSByZXR1cm4gcndpbGQoYWNjKTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KHApKSB7XG4gICAgICBmb3IgKHZhciBpID0gcC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuXHRhY2MgPSB3YWxrKHBbaV0sIGFjYyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcnNlcShwLmxlbmd0aCwgU09BLCBhY2MpO1xuICAgIH1cblxuICAgIGlmIChJbW11dGFibGUuTGlzdC5pc0xpc3QocCkpIHtcbiAgICAgIHAucmV2ZXJzZSgpLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcblx0YWNjID0gd2FsayhlbGVtZW50LCBhY2MpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcnNlcShwLnNpemUsIFNPQSwgYWNjKTtcbiAgICB9XG5cbiAgICBpZiAoU3RydWN0LmlzU3RydWN0dXJlKHApKSB7XG4gICAgICBmb3IgKHZhciBpID0gcC5tZXRhLmFyaXR5IC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYWNjID0gd2FsayhwW2ldLCBhY2MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJzZXEocC5tZXRhLmFyaXR5LCBwLm1ldGEsIGFjYyk7XG4gICAgfVxuXG4gICAgaWYgKHAgaW5zdGFuY2VvZiAkRW1iZWRkZWQpIHtcbiAgICAgIGFjYyA9IGFwcGVuZFRyaWUocC50cmllLCBmdW5jdGlvbiAodikgeyByZXR1cm4gYWNjOyB9KTtcbiAgICAgIGlmIChwLmFycmF5TGVuZ3RoICE9PSBudWxsKSB7XG4gICAgICAgIGFjYyA9IHJzZXEocC5hcnJheUxlbmd0aCwgU09BLCBhY2MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJzZXEoMCwgcCwgYWNjKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbWF0Y2hQYXR0ZXJuKHYsIHApIHtcbiAgdmFyIGNhcHR1cmVDb3VudCA9IDA7XG4gIHZhciByZXN1bHQgPSB7fTtcbiAgdHJ5IHtcbiAgICB3YWxrKHYsIHApO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGUubWF0Y2hQYXR0ZXJuRmFpbGVkKSByZXR1cm4gbnVsbDtcbiAgICB0aHJvdyBlO1xuICB9XG4gIHJlc3VsdC5sZW5ndGggPSBjYXB0dXJlQ291bnQ7XG4gIHJldHVybiByZXN1bHQ7XG5cbiAgZnVuY3Rpb24gd2Fsayh2LCBwKSB7XG4gICAgaWYgKHAgPT09IHYpIHJldHVybjtcblxuICAgIGlmIChwID09PSBfXykgcmV0dXJuO1xuXG4gICAgaWYgKFN0cnVjdC5pc1N0cnVjdHVyZShwKSAmJiBTdHJ1Y3QuaXNTdHJ1Y3R1cmUodikgJiYgKHAubWV0YS5lcXVhbHModi5tZXRhKSkpXG4gICAge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwLm1ldGEuYXJpdHk7IGkrKykge1xuICAgICAgICB3YWxrKHZbaV0sIHBbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHApICYmIEFycmF5LmlzQXJyYXkodikgJiYgcC5sZW5ndGggPT09IHYubGVuZ3RoKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHAubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgd2Fsayh2W2ldLCBwW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoaXNDYXB0dXJlKHApKSB7XG4gICAgICB2YXIgdGhpc0NhcHR1cmUgPSBjYXB0dXJlQ291bnQrKztcbiAgICAgIHdhbGsodiwgY2FwdHVyZVBhdHRlcm4ocCkpO1xuICAgICAgcmVzdWx0W2NhcHR1cmVOYW1lKHApIHx8ICgnJCcgKyB0aGlzQ2FwdHVyZSldID0gdjtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocCBpbnN0YW5jZW9mICRFbWJlZGRlZCkge1xuICAgICAgZGllKFwiJEVtYmVkZGVkIHBhdHRlcm5zIG5vdCBzdXBwb3J0ZWQgaW4gbWF0Y2hQYXR0ZXJuKClcIik7XG4gICAgfVxuXG4gICAgdGhyb3cge21hdGNoUGF0dGVybkZhaWxlZDogdHJ1ZX07XG4gIH1cbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNvbWJpbmUoY29tYmluZVN1Y2Nlc3MsIGxlZnRFbXB0eSwgcmlnaHRFbXB0eSwgbGVmdEJhc2UsIHJpZ2h0QmFzZSwgcjEsIHIyKSB7XG4gIHJldHVybiB3YWxrKHIxLCByMik7XG5cbiAgZnVuY3Rpb24gd2FsayhyMSwgcjIpIHtcbiAgICBpZiAoaXNfZW1wdHlUcmllKHIxKSkgcmV0dXJuIGNvbGxhcHNlKGxlZnRFbXB0eShyMikpO1xuICAgIGlmIChpc19lbXB0eVRyaWUocjIpKSByZXR1cm4gY29sbGFwc2UocmlnaHRFbXB0eShyMSkpO1xuXG4gICAgaWYgKChyMSBpbnN0YW5jZW9mICRTdWNjZXNzKSB8fCAocjIgaW5zdGFuY2VvZiAkU3VjY2VzcykpIHtcbiAgICAgIHJldHVybiBjb2xsYXBzZShjb21iaW5lU3VjY2VzcyhyMSwgcjIpKTtcbiAgICB9XG5cbiAgICBpZiAoIShyMSBpbnN0YW5jZW9mICRCcmFuY2gpIHx8ICEocjIgaW5zdGFuY2VvZiAkQnJhbmNoKSkge1xuICAgICAgZGllKFwiSW52YWxpZCB0cmllIGdpdmVuIHRvIGNvbWJpbmVcIik7XG4gICAgfVxuXG4gICAgLyogZm9sZC1vdmVyLWtleXMgKi9cbiAgICB2YXIgdyA9IHdhbGsocjEud2lsZCwgcjIud2lsZCk7XG5cbiAgICB2YXIgYWNjO1xuICAgIGlmICghaXNfZW1wdHlUcmllKHIxLndpbGQpICYmICFpc19lbXB0eVRyaWUocjIud2lsZCkpIHtcbiAgICAgIGFjYyA9IHJjb3B5YnJhbmNoKGV4cGFuZChyd2lsZCh3KSkpO1xuICAgICAgdmFyIHNlZW4gPSBJbW11dGFibGUuTWFwKCk7XG4gICAgICByMS5lZGdlcy5mb3JFYWNoKGZ1bmN0aW9uIChrZXltYXAsIGFyaXR5KSB7XG4gICAgICAgIGtleW1hcC5mb3JFYWNoKGZ1bmN0aW9uIChyMXYsIGtleSkge1xuICAgICAgICAgIHZhciByMnYgPSBybG9va3VwKHIyLCBhcml0eSwga2V5KTtcbiAgICAgICAgICBydXBkYXRlX2lucGxhY2UoYWNjLCBhcml0eSwga2V5LCB3YWxrKHIxdiwgcjJ2KSk7XG4gICAgICAgICAgc2VlbiA9IHNlZW4uc2V0KGFyaXR5LCAoc2Vlbi5nZXQoYXJpdHkpIHx8IEltbXV0YWJsZS5TZXQoKSkuYWRkKGtleSkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgcjIuZWRnZXMuZm9yRWFjaChmdW5jdGlvbiAoa2V5bWFwLCBhcml0eSkge1xuICAgICAgICBrZXltYXAuZm9yRWFjaChmdW5jdGlvbiAocjJ2LCBrZXkpIHtcbiAgICAgICAgICB2YXIgcjF2ID0gcmxvb2t1cChyMSwgYXJpdHksIGtleSk7XG4gICAgICAgICAgdmFyIHMgPSBzZWVuLmdldChhcml0eSk7XG4gICAgICAgICAgcyA9IHMgJiYgcy5oYXMoa2V5KTtcbiAgICAgICAgICBpZiAoIXMpIHJ1cGRhdGVfaW5wbGFjZShhY2MsIGFyaXR5LCBrZXksIHdhbGsocjF2LCByMnYpKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKCFpc19lbXB0eVRyaWUocjEud2lsZCkgfHwgKGlzX2VtcHR5VHJpZShyMi53aWxkKSAmJiAocjEuY291bnQgPiByMi5jb3VudCkpKSB7XG4gICAgICBhY2MgPSByY29weWJyYW5jaChleHBhbmQobGVmdEJhc2UocjEpKSk7XG4gICAgICBhY2Mud2lsZCA9IHc7XG4gICAgICByMi5lZGdlcy5mb3JFYWNoKGZ1bmN0aW9uIChrZXltYXAsIGFyaXR5KSB7XG4gICAgICAgIGtleW1hcC5mb3JFYWNoKGZ1bmN0aW9uIChyMnYsIGtleSkge1xuICAgICAgICAgIHZhciByMXYgPSBybG9va3VwKHIxLCBhcml0eSwga2V5KTtcbiAgICAgICAgICBydXBkYXRlX2lucGxhY2UoYWNjLCBhcml0eSwga2V5LCB3YWxrKHIxdiwgcjJ2KSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFjYyA9IHJjb3B5YnJhbmNoKGV4cGFuZChyaWdodEJhc2UocjIpKSk7XG4gICAgICBhY2Mud2lsZCA9IHc7XG4gICAgICByMS5lZGdlcy5mb3JFYWNoKGZ1bmN0aW9uIChrZXltYXAsIGFyaXR5KSB7XG4gICAgICAgIGtleW1hcC5mb3JFYWNoKGZ1bmN0aW9uIChyMXYsIGtleSkge1xuICAgICAgICAgIHZhciByMnYgPSBybG9va3VwKHIyLCBhcml0eSwga2V5KTtcbiAgICAgICAgICBydXBkYXRlX2lucGxhY2UoYWNjLCBhcml0eSwga2V5LCB3YWxrKHIxdiwgcjJ2KSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbGxhcHNlKGFjYyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXN5bW1ldHJpY1RyaWVFcnJvcihyMSwgcjIpIHtcbiAgZGllKFwiQXN5bW1ldHJpYyB0cmllczogXCIgKyByMSArIFwiLCBcIiArIHIyKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbnZhciB1bmlvblN1Y2Nlc3Nlc0RlZmF1bHQgPSBmdW5jdGlvbiAodjEsIHYyKSB7XG4gIHJldHVybiByc3VjY2Vzcyh2MS51bmlvbih2MikpO1xufTtcblxuZnVuY3Rpb24gdW5pb24obzEsIG8yLCB1bmlvblN1Y2Nlc3Nlc09wdCkge1xuICB2YXIgdW5pb25TdWNjZXNzZXMgPSB1bmlvblN1Y2Nlc3Nlc09wdCB8fCB1bmlvblN1Y2Nlc3Nlc0RlZmF1bHQ7XG4gIHJldHVybiBjb21iaW5lKHVuaW9uQ29tYmluZXIsXG4gICAgICAgICAgICAgICAgIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4OyB9LFxuICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoeCkgeyByZXR1cm4geDsgfSxcbiAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHg7IH0sXG4gICAgICAgICAgICAgICAgIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4OyB9LFxuICAgICAgICAgICAgICAgICBvMSxcbiAgICAgICAgICAgICAgICAgbzIpO1xuXG4gIGZ1bmN0aW9uIHVuaW9uQ29tYmluZXIocjEsIHIyKSB7XG4gICAgaWYgKChyMSBpbnN0YW5jZW9mICRTdWNjZXNzKSAmJiAocjIgaW5zdGFuY2VvZiAkU3VjY2VzcykpXG4gICAgICByZXR1cm4gdW5pb25TdWNjZXNzZXMocjEudmFsdWUsIHIyLnZhbHVlKTtcbiAgICBpZiAoaXNfZW1wdHlUcmllKHIxKSkgcmV0dXJuIHIyO1xuICAgIGlmIChpc19lbXB0eVRyaWUocjIpKSByZXR1cm4gcjE7XG4gICAgYXN5bW1ldHJpY1RyaWVFcnJvcihyMSwgcjIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuaW9uTigpIHtcbiAgdmFyIGFjYyA9IGVtcHR5VHJpZTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBhY2MgPSB1bmlvbihhY2MsIGFyZ3VtZW50c1tpXSk7XG4gIH1cbiAgcmV0dXJuIGFjYztcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbnZhciBpbnRlcnNlY3RTdWNjZXNzZXNEZWZhdWx0ID0gdW5pb25TdWNjZXNzZXNEZWZhdWx0O1xuXG5mdW5jdGlvbiBpbnRlcnNlY3QobzEsIG8yLCBpbnRlcnNlY3RTdWNjZXNzZXNPcHQpIHtcbiAgdmFyIGludGVyc2VjdFN1Y2Nlc3NlcyA9IGludGVyc2VjdFN1Y2Nlc3Nlc09wdCB8fCBpbnRlcnNlY3RTdWNjZXNzZXNEZWZhdWx0O1xuICByZXR1cm4gY29tYmluZShpbnRlcnNlY3RDb21iaW5lcixcbiAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIGVtcHR5VHJpZTsgfSxcbiAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIGVtcHR5VHJpZTsgfSxcbiAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIGVtcHR5VHJpZTsgfSxcbiAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIGVtcHR5VHJpZTsgfSxcbiAgICAgICAgICAgICAgICAgbzEsXG4gICAgICAgICAgICAgICAgIG8yKTtcblxuICBmdW5jdGlvbiBpbnRlcnNlY3RDb21iaW5lcihyMSwgcjIpIHtcbiAgICBpZiAoKHIxIGluc3RhbmNlb2YgJFN1Y2Nlc3MpICYmIChyMiBpbnN0YW5jZW9mICRTdWNjZXNzKSlcbiAgICAgIHJldHVybiBpbnRlcnNlY3RTdWNjZXNzZXMocjEudmFsdWUsIHIyLnZhbHVlKTtcbiAgICBpZiAoaXNfZW1wdHlUcmllKHIxKSkgcmV0dXJuIGVtcHR5VHJpZTtcbiAgICBpZiAoaXNfZW1wdHlUcmllKHIyKSkgcmV0dXJuIGVtcHR5VHJpZTtcbiAgICBhc3ltbWV0cmljVHJpZUVycm9yKHIxLCByMik7XG4gIH1cbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbnZhciBzdWJ0cmFjdFN1Y2Nlc3Nlc0RlZmF1bHQgPSBmdW5jdGlvbiAodjEsIHYyKSB7XG4gIHZhciByID0gdjEuc3VidHJhY3QodjIpO1xuICBpZiAoci5pc0VtcHR5KCkpIHJldHVybiBlbXB0eVRyaWU7XG4gIHJldHVybiByc3VjY2VzcyhyKTtcbn07XG5cbmZ1bmN0aW9uIHN1YnRyYWN0KG8xLCBvMiwgc3VidHJhY3RTdWNjZXNzZXNPcHQpIHtcbiAgdmFyIHN1YnRyYWN0U3VjY2Vzc2VzID0gc3VidHJhY3RTdWNjZXNzZXNPcHQgfHwgc3VidHJhY3RTdWNjZXNzZXNEZWZhdWx0O1xuICByZXR1cm4gY29tYmluZShzdWJ0cmFjdENvbWJpbmVyLFxuICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoeCkgeyByZXR1cm4gZW1wdHlUcmllOyB9LFxuICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoeCkgeyByZXR1cm4geDsgfSxcbiAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHg7IH0sXG4gICAgICAgICAgICAgICAgIGZ1bmN0aW9uICh4KSB7IHJldHVybiBlbXB0eVRyaWU7IH0sXG4gICAgICAgICAgICAgICAgIG8xLFxuICAgICAgICAgICAgICAgICBvMik7XG5cbiAgZnVuY3Rpb24gc3VidHJhY3RDb21iaW5lcihyMSwgcjIpIHtcbiAgICBpZiAoKHIxIGluc3RhbmNlb2YgJFN1Y2Nlc3MpICYmIChyMiBpbnN0YW5jZW9mICRTdWNjZXNzKSlcbiAgICAgIHJldHVybiBzdWJ0cmFjdFN1Y2Nlc3NlcyhyMS52YWx1ZSwgcjIudmFsdWUpO1xuICAgIGlmIChpc19lbXB0eVRyaWUocjEpKSByZXR1cm4gZW1wdHlUcmllO1xuICAgIGlmIChpc19lbXB0eVRyaWUocjIpKSByZXR1cm4gcjE7XG4gICAgYXN5bW1ldHJpY1RyaWVFcnJvcihyMSwgcjIpO1xuICB9XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vLyBSZXR1cm5zIGZhaWx1cmVSZXN1bHQgb24gZmFpbGVkIG1hdGNoLCBvdGhlcndpc2UgdGhlIGFwcHJvcHJpYXRlXG4vLyBzdWNjZXNzIHZhbHVlIGNvbnRhaW5lZCBpbiB0aGUgdHJpZSByLiBJZiB3aWxkY2FyZFVuaW9uT3B0XG4vLyBub24tZmFsc3ksIGFsbG93cyB3aWxkY2FyZHMgaW4gXCJtZXNzYWdlc1wiIHYuXG5mdW5jdGlvbiBtYXRjaFZhbHVlKHIsIHYsIGZhaWx1cmVSZXN1bHQsIHdpbGRjYXJkVW5pb25PcHQpIHtcbiAgcmV0dXJuIHdhbGsoSW1tdXRhYmxlLkxpc3Qub2YodiksIHIpO1xuXG4gIGZ1bmN0aW9uIHdhbGsodnMsIHIpIHtcbiAgICB3aGlsZSAoIWlzX2VtcHR5VHJpZShyKSkge1xuICAgICAgaWYgKHIgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuICAgICAgICByZXR1cm4gdnMuaXNFbXB0eSgpID8gci52YWx1ZSA6IGZhaWx1cmVSZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGlmICh2cy5pc0VtcHR5KCkpIHJldHVybiBmYWlsdXJlUmVzdWx0O1xuICAgICAgdmFyIHYgPSB2cy5maXJzdCgpO1xuICAgICAgdnMgPSB2cy5yZXN0KCk7XG5cbiAgICAgIGlmICh2ID09PSBfXykge1xuICAgICAgICBpZiAoIXdpbGRjYXJkVW5pb25PcHQpIHtcbiAgICAgICAgICBkaWUoXCJDYW5ub3QgbWF0Y2ggd2lsZGNhcmQgaW4gdmFsdWUgdW5sZXNzIHdpbGRjYXJkVW5pb25PcHQgbm9uLWZhbHN5XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHNlZWQgPSB3YWxrKHZzLCByLndpbGQpO1xuICAgICAgICByLmVkZ2VzLmZvckVhY2goZnVuY3Rpb24gKGtleW1hcCwgYXJpdHkpIHtcbiAgICAgICAgICBrZXltYXAuZm9yRWFjaChmdW5jdGlvbiAoaywga2V5KSB7XG4gICAgICAgICAgICBzZWVkID0gd2lsZGNhcmRVbmlvbk9wdCh3YWxrKEltbXV0YWJsZS5SZXBlYXQoX18sIGFyaXR5KS5jb25jYXQodnMpLCBrKSwgc2VlZCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2VlZDtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiB2ID09PSAnc3RyaW5nJyAmJiB2LnN1YnN0cmluZygwLCAyKSA9PT0gJ19fJykge1xuICAgICAgICBkaWUoXCJDYW5ub3QgbWF0Y2ggc3BlY2lhbCBzdHJpbmcgc3RhcnRpbmcgd2l0aCBfX1wiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodikpIHtcbiAgICAgICAgciA9IHJsb29rdXAociwgdi5sZW5ndGgsIFNPQSk7XG4gICAgICAgIHZzID0gSW1tdXRhYmxlLkxpc3QodikuY29uY2F0KHZzKTtcbiAgICAgIH0gZWxzZSBpZiAoU3RydWN0LmlzU3RydWN0dXJlKHYpKSB7XG4gICAgICAgIHIgPSBybG9va3VwKHIsIHYubWV0YS5hcml0eSwgdi5tZXRhKTtcbiAgICAgICAgdnMgPSBJbW11dGFibGUuTGlzdCh2LmZpZWxkcykuY29uY2F0KHZzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHIgPSBybG9va3VwKHIsIDAsIHYpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWlsdXJlUmVzdWx0O1xuICB9XG59XG5cbmZ1bmN0aW9uIG1hdGNoVHJpZShvMSwgbzIsIHNlZWQsIGNvbWJpbmVyKSB7XG4gIHZhciBhY2MgPSB0eXBlb2Ygc2VlZCA9PT0gJ3VuZGVmaW5lZCcgPyBJbW11dGFibGUuU2V0KCkgOiBzZWVkOyAvLyB2YXJpYWJsZSB1cGRhdGVkIGltcGVyYXRpdmVseVxuICB3YWxrKG8xLCBvMik7XG4gIHJldHVybiBhY2M7XG5cbiAgZnVuY3Rpb24gd2FsayhyMSwgcjIpIHtcbiAgICBpZiAoaXNfZW1wdHlUcmllKHIxKSB8fCBpc19lbXB0eVRyaWUocjIpKSByZXR1cm47XG5cbiAgICBpZiAoKHIxIGluc3RhbmNlb2YgJFN1Y2Nlc3MpICYmIChyMiBpbnN0YW5jZW9mICRTdWNjZXNzKSkge1xuICAgICAgYWNjID0gY29tYmluZXIocjEudmFsdWUsIHIyLnZhbHVlLCBhY2MpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghKHIxIGluc3RhbmNlb2YgJEJyYW5jaCkgfHwgIShyMiBpbnN0YW5jZW9mICRCcmFuY2gpKSB7XG4gICAgICBhc3ltbWV0cmljVHJpZUVycm9yKHIxLCByMik7XG4gICAgfVxuXG4gICAgd2FsayhyMS53aWxkLCByMi53aWxkKTtcblxuICAgIGZ1bmN0aW9uIGV4YW1pbmVLZXlzKGtleW1hcCwgYXJpdHkpIHtcbiAgICAgIGtleW1hcC5mb3JFYWNoKGZ1bmN0aW9uIChfdmFsLCBrZXkpIHtcbiAgICAgICAgd2FsayhybG9va3VwKHIxLCBhcml0eSwga2V5KSwgcmxvb2t1cChyMiwgYXJpdHksIGtleSkpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGlzX2VtcHR5VHJpZShyMS53aWxkKSkge1xuICAgICAgaWYgKGlzX2VtcHR5VHJpZShyMi53aWxkKSkge1xuXHQocjEuY291bnQgPCByMi5jb3VudCA/IHIxIDogcjIpLmVkZ2VzLmZvckVhY2goZXhhbWluZUtleXMpO1xuICAgICAgfSBlbHNlIHtcblx0cjEuZWRnZXMuZm9yRWFjaChleGFtaW5lS2V5cyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc19lbXB0eVRyaWUocjIud2lsZCkpIHtcblx0cjIuZWRnZXMuZm9yRWFjaChleGFtaW5lS2V5cyk7XG4gICAgICB9IGVsc2Uge1xuXHRyMS5lZGdlcy5mb3JFYWNoKGV4YW1pbmVLZXlzKTtcblx0cjIuZWRnZXMuZm9yRWFjaChleGFtaW5lS2V5cyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFwcGVuZFRyaWUobSwgbVRhaWxGbikge1xuICByZXR1cm4gd2FsayhtKTtcblxuICBmdW5jdGlvbiB3YWxrKG0pIHtcbiAgICBpZiAoaXNfZW1wdHlUcmllKG0pKSByZXR1cm4gZW1wdHlUcmllO1xuICAgIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHJldHVybiBtVGFpbEZuKG0udmFsdWUpO1xuXG4gICAgdmFyIHRhcmdldCA9IG5ld0VtcHR5QnJhbmNoKCk7XG4gICAgdGFyZ2V0LndpbGQgPSB3YWxrKG0ud2lsZCk7XG4gICAgbS5lZGdlcy5mb3JFYWNoKGZ1bmN0aW9uIChrZXltYXAsIGFyaXR5KSB7XG4gICAgICBrZXltYXAuZm9yRWFjaChmdW5jdGlvbiAoaywga2V5KSB7XG4gICAgICAgIHJ1cGRhdGVfaW5wbGFjZSh0YXJnZXQsIGFyaXR5LCBrZXksIHdhbGsoaykpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGNvbGxhcHNlKHRhcmdldCk7XG4gIH1cbn1cblxuLy8gREFOR0VST1VTOiBwcmVmZXIgc3VidHJhY3QoKSBpbnN0ZWFkLlxuLy9cbi8vIGZ1bmN0aW9uIHRyaWVQcnVuZUJyYW5jaChtLCBhcml0eUtleXMpIHtcbi8vICAgaWYgKGFyaXR5S2V5cy5pc0VtcHR5KCkpIHJldHVybiBlbXB0eVRyaWU7XG4vLyAgIGlmICghKG0gaW5zdGFuY2VvZiAkQnJhbmNoKSkgcmV0dXJuIG07XG4vLyAgIHZhciBhcml0eUtleSA9IGFyaXR5S2V5cy5maXJzdCgpO1xuLy8gICB2YXIgcmVzdCA9IGFyaXR5S2V5cy5zaGlmdCgpO1xuLy8gICB2YXIgYXJpdHkgPSBhcml0eUtleVswXTtcbi8vICAgdmFyIGtleSA9IGFyaXR5S2V5WzFdO1xuLy8gICBtID0gcmNvcHlicmFuY2gobSk7XG4vLyAgIHJ1cGRhdGVfaW5wbGFjZShtLCBhcml0eSwga2V5LCB0cmllUHJ1bmVCcmFuY2gocmxvb2t1cChtLCBhcml0eSwga2V5KSwgcmVzdCkpO1xuLy8gICByZXR1cm4gY29sbGFwc2UobSk7XG4vLyB9XG5cbmZ1bmN0aW9uIHRyaWVTdGVwKG0sIGFyaXR5LCBrZXkpIHtcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gQ29wZSB3aXRoIEFQSSBjaGFuZ2Ugd2hpY2ggd291bGQgb3RoZXJ3aXNlIHNpbGVudGx5IGNhdXNlIHByb2JsZW1zXG4gICAgZGllKFwidHJpZVN0ZXA6IG1pc3NpbmcgJ2tleScgYXJndW1lbnRcIik7XG4gIH1cbiAgaWYgKGlzX2VtcHR5VHJpZShtKSkgcmV0dXJuIGVtcHR5VHJpZTtcbiAgaWYgKG0gaW5zdGFuY2VvZiAkU3VjY2VzcykgcmV0dXJuIGVtcHR5VHJpZTtcbiAgcmV0dXJuIHJsb29rdXAobSwgYXJpdHksIGtleSk7XG59XG5cbmZ1bmN0aW9uIHJlbGFiZWwobSwgZikge1xuICByZXR1cm4gYXBwZW5kVHJpZShtLCBmdW5jdGlvbiAodikge1xuICAgIHZhciB2MSA9IGYodik7XG4gICAgcmV0dXJuIHYxID8gcnN1Y2Nlc3ModjEpIDogZW1wdHlUcmllO1xuICB9KTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIHByb2plY3Rpb25OYW1lcyhwKSB7XG4gIHZhciBuYW1lcyA9IFtdO1xuICB3YWxrKHApO1xuICByZXR1cm4gbmFtZXM7XG5cbiAgZnVuY3Rpb24gd2FsayhwKSB7XG4gICAgaWYgKGlzQ2FwdHVyZShwKSkge1xuICAgICAgbmFtZXMucHVzaChjYXB0dXJlTmFtZShwKSk7XG4gICAgICB3YWxrKGNhcHR1cmVQYXR0ZXJuKHApKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShwKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwLmxlbmd0aDsgaSsrKSB3YWxrKHBbaV0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChTdHJ1Y3QuaXNTdHJ1Y3R1cmUocCkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5tZXRhLmFyaXR5OyBpKyspIHdhbGsocFtpXSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHByb2plY3Rpb25Bcml0eShwKSB7XG4gIHJldHVybiBwcm9qZWN0aW9uTmFtZXMocCkubGVuZ3RoO1xufVxuXG5mdW5jdGlvbiBwcm9qZWN0aW9uVG9QYXR0ZXJuKHApIHtcbiAgcmV0dXJuIHdhbGsocCk7XG5cbiAgZnVuY3Rpb24gd2FsayhwKSB7XG4gICAgaWYgKGlzQ2FwdHVyZShwKSkgcmV0dXJuIHdhbGsoY2FwdHVyZVBhdHRlcm4ocCkpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocCkpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuXHRyZXN1bHQucHVzaCh3YWxrKHBbaV0pKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgaWYgKFN0cnVjdC5pc1N0cnVjdHVyZShwKSkge1xuICAgICAgdmFyIHJlc3VsdEZpZWxkcyA9IFtdO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwLm1ldGEuYXJpdHk7IGkrKykge1xuICAgICAgICByZXN1bHRGaWVsZHNbaV0gPSB3YWxrKHBbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBTdHJ1Y3QuU3RydWN0dXJlKHAubWV0YSwgcmVzdWx0RmllbGRzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcDtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9qZWN0KHQsIHdob2xlU3BlYywgcHJvamVjdFN1Y2Nlc3NPcHQsIGNvbWJpbmVyT3B0KSB7XG4gIHJldHVybiBwcm9qZWN0TWFueSh0LCBJbW11dGFibGUuTGlzdC5vZih3aG9sZVNwZWMpLCBwcm9qZWN0U3VjY2Vzc09wdCwgY29tYmluZXJPcHQpO1xufVxuXG5mdW5jdGlvbiBwcm9qZWN0TWFueSh0LCB3aG9sZVNwZWNzLCBwcm9qZWN0U3VjY2Vzc09wdCwgY29tYmluZXJPcHQpIHtcbiAgdmFyIHByb2plY3RTdWNjZXNzID0gcHJvamVjdFN1Y2Nlc3NPcHQgfHwgcnN1Y2Nlc3M7XG4gIHZhciBjb21iaW5lciA9IGNvbWJpbmVyT3B0IHx8IHVuaW9uU3VjY2Vzc2VzRGVmYXVsdDtcblxuICByZXR1cm4gd2FsayhmYWxzZSwgdCwgSW1tdXRhYmxlLkxpc3Qod2hvbGVTcGVjcyksIGZ1bmN0aW9uICh0KSB7XG4gICAgaWYgKHQgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuICAgICAgcmV0dXJuIHByb2plY3RTdWNjZXNzKHQudmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZW1wdHlUcmllO1xuICAgIH1cbiAgfSk7XG5cbiAgZnVuY3Rpb24gd2Fsayhpc0NhcHR1cmluZywgdCwgc3BlY3MsIGtvbnQpIHtcbiAgICBpZiAoc3BlY3MuaXNFbXB0eSgpKSByZXR1cm4ga29udCh0KTtcbiAgICBpZiAoISh0IGluc3RhbmNlb2YgJEJyYW5jaCkpIHJldHVybiBlbXB0eVRyaWU7XG5cbiAgICB2YXIgc3BlYyA9IHNwZWNzLmZpcnN0KCk7XG4gICAgdmFyIHNwZWNzUmVzdCA9IHNwZWNzLnJlc3QoKTtcblxuICAgIGlmIChpc0NhcHR1cmUoc3BlYykpIHtcbiAgICAgIGlmIChpc0NhcHR1cmluZykge1xuICAgICAgICBkaWUoXCJwcm9qZWN0TWFueTogbmVzdGVkIGNhcHR1cmUgaW4gcHJvamVjdGlvbjogXCIgKyB3aG9sZVNwZWNzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3YWxrKHRydWUsIHQsIEltbXV0YWJsZS5MaXN0Lm9mKGNhcHR1cmVQYXR0ZXJuKHNwZWMpKSwgZnVuY3Rpb24gKGludGVybWVkaWF0ZSkge1xuICAgICAgICByZXR1cm4gd2FsayhmYWxzZSwgaW50ZXJtZWRpYXRlLCBzcGVjc1Jlc3QsIGtvbnQpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHNwZWMgPT09IF9fKSB7XG4gICAgICBpZiAoaXNDYXB0dXJpbmcpIHtcbiAgICAgICAgdmFyIHRhcmdldCA9IG5ld0VtcHR5QnJhbmNoKCk7XG4gICAgICAgIHRhcmdldC53aWxkID0gd2Fsayhpc0NhcHR1cmluZywgdC53aWxkLCBzcGVjc1Jlc3QsIGtvbnQpO1xuICAgICAgICB0LmVkZ2VzLmZvckVhY2goZnVuY3Rpb24gKGtleW1hcCwgYXJpdHkpIHtcbiAgICAgICAgICB2YXIgaW5uZXJTcGVjcyA9IEltbXV0YWJsZS5SZXBlYXQoX18sIGFyaXR5KTtcbiAgICAgICAgICBrZXltYXAuZm9yRWFjaChmdW5jdGlvbiAoaywga2V5KSB7XG4gICAgICAgICAgICBydXBkYXRlX2lucGxhY2UodGFyZ2V0LCBhcml0eSwga2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhbGsoaXNDYXB0dXJpbmcsIGssIGlubmVyU3BlY3MsIGZ1bmN0aW9uIChpbnRlcm1lZGlhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB3YWxrKGlzQ2FwdHVyaW5nLCBpbnRlcm1lZGlhdGUsIHNwZWNzUmVzdCwga29udCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxhcHNlKHRhcmdldCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgc2VlZCA9IHdhbGsoaXNDYXB0dXJpbmcsIHQud2lsZCwgc3BlY3NSZXN0LCBrb250KTtcbiAgICAgICAgdC5lZGdlcy5mb3JFYWNoKGZ1bmN0aW9uIChrZXltYXAsIGFyaXR5KSB7XG4gICAgICAgICAgdmFyIGlubmVyU3BlY3MgPSBJbW11dGFibGUuUmVwZWF0KF9fLCBhcml0eSk7XG4gICAgICAgICAga2V5bWFwLmZvckVhY2goZnVuY3Rpb24gKGssIGtleSkge1xuICAgICAgICAgICAgc2VlZCA9IHVuaW9uKHNlZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgd2Fsayhpc0NhcHR1cmluZywgaywgaW5uZXJTcGVjcywgZnVuY3Rpb24gKGludGVybWVkaWF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdhbGsoaXNDYXB0dXJpbmcsIGludGVybWVkaWF0ZSwgc3BlY3NSZXN0LCBrb250KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICBjb21iaW5lcik7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2VlZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgaWYgKFN0cnVjdC5pc1N0cnVjdHVyZShzcGVjKSkge1xuICAgICAgdmFyIGludGVybWVkaWF0ZSA9IHdhbGsoaXNDYXB0dXJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBybG9va3VwKHQsIHNwZWMubWV0YS5hcml0eSwgc3BlYy5tZXRhKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEltbXV0YWJsZS5MaXN0KHNwZWMuZmllbGRzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChpbnRlcm1lZGlhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdhbGsoaXNDYXB0dXJpbmcsIGludGVybWVkaWF0ZSwgc3BlY3NSZXN0LCBrb250KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgcmV0dXJuIGlzQ2FwdHVyaW5nID8gcnNlcShzcGVjLm1ldGEuYXJpdHksIHNwZWMubWV0YSwgaW50ZXJtZWRpYXRlKSA6IGludGVybWVkaWF0ZTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShzcGVjKSkge1xuICAgICAgdmFyIGludGVybWVkaWF0ZSA9IHdhbGsoaXNDYXB0dXJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBybG9va3VwKHQsIHNwZWMubGVuZ3RoLCBTT0EpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW1tdXRhYmxlLkxpc3Qoc3BlYyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoaW50ZXJtZWRpYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB3YWxrKGlzQ2FwdHVyaW5nLCBpbnRlcm1lZGlhdGUsIHNwZWNzUmVzdCwga29udCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgIHJldHVybiBpc0NhcHR1cmluZyA/IHJzZXEoc3BlYy5sZW5ndGgsIFNPQSwgaW50ZXJtZWRpYXRlKSA6IGludGVybWVkaWF0ZTtcbiAgICB9XG5cbiAgICBpZiAoc3BlYyBpbnN0YW5jZW9mICRFbWJlZGRlZCkge1xuICAgICAgZGllKFwiJEVtYmVkZGVkIHBhdHRlcm5zIG5vdCBzdXBwb3J0ZWQgaW4gcHJvamVjdE1hbnkoKVwiKTtcbiAgICB9XG5cbiAgICAvKiBJdCBpcyBhIG5vcm1hbCBhdG9tICovXG4gICAgdmFyIGludGVybWVkaWF0ZSA9IHdhbGsoaXNDYXB0dXJpbmcsIHJsb29rdXAodCwgMCwgc3BlYyksIHNwZWNzUmVzdCwga29udCk7XG4gICAgcmV0dXJuIGlzQ2FwdHVyaW5nID8gcnNlcSgwLCBzcGVjLCBpbnRlcm1lZGlhdGUpIDogaW50ZXJtZWRpYXRlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlY29uc3RydWN0U2VxdWVuY2Uoa2V5LCBpdGVtcykge1xuICBpZiAoa2V5ID09PSBTT0EpIHtcbiAgICByZXR1cm4gaXRlbXMudG9BcnJheSgpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBrZXkuaW5zdGFudGlhdGUoaXRlbXMudG9BcnJheSgpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB0cmllS2V5cyhtLCB0YWtlQ291bnQwKSB7XG4gIGlmICh0eXBlb2YgdGFrZUNvdW50MCAhPT0gJ251bWJlcicpIHtcbiAgICAvLyBDb3BlIHdpdGggQVBJIGNoYW5nZSB3aGljaCB3b3VsZCBvdGhlcndpc2Ugc2lsZW50bHkgY2F1c2UgcHJvYmxlbXNcbiAgICBkaWUoXCJNaXNzaW5nIG1hbmRhdG9yeSBhcmd1bWVudCAndGFrZUNvdW50JyB0byBUcmllLnRyaWVLZXlzXCIpO1xuICB9XG5cbiAgaWYgKGlzX2VtcHR5VHJpZShtKSkgcmV0dXJuIEltbXV0YWJsZS5TZXQoKTtcbiAgcmV0dXJuIHdhbGsobSwgdGFrZUNvdW50MCwgSW1tdXRhYmxlLkxpc3QoKSxcbiAgICAgICAgICAgICAgZnVuY3Rpb24gKGl0ZW1zLCB0YWlsKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzX2VtcHR5VHJpZSh0YWlsKSkgcmV0dXJuIEltbXV0YWJsZS5TZXQoKTtcbiAgICAgICAgICAgICAgICBpZiAodGFpbCBpbnN0YW5jZW9mICRTdWNjZXNzKSByZXR1cm4gSW1tdXRhYmxlLlNldC5vZihpdGVtcyk7XG4gICAgICAgICAgICAgICAgZGllKFwiVHJpZSBjb250YWlucyBtb3JlIHRoYW4gdGhlIHJlcXVlc3RlZCBcIit0YWtlQ291bnQwK1wiIGl0ZW1zXCIpO1xuICAgICAgICAgICAgICB9KTtcblxuICBmdW5jdGlvbiB3YWxrKG0sIHRha2VDb3VudCwgdmFsc1Jldiwga29udCkge1xuICAgIGlmICh0YWtlQ291bnQgPT09IDApIHJldHVybiBrb250KHZhbHNSZXYucmV2ZXJzZSgpLCBtKTtcblxuICAgIGlmIChpc19lbXB0eVRyaWUobSkpIHJldHVybiBJbW11dGFibGUuU2V0KCk7XG4gICAgaWYgKG0gaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuICAgICAgZGllKFwiVHJpZSBjb250YWlucyBmZXdlciB0aGFuIHRoZSByZXF1ZXN0ZWQgXCIrdGFrZUNvdW50MCtcIiBpdGVtc1wiKTtcbiAgICB9XG5cbiAgICBpZiAoIWlzX2VtcHR5VHJpZShtLndpbGQpKSByZXR1cm4gZmFsc2U7XG5cbiAgICB2YXIgcmVzdWx0ID0gSW1tdXRhYmxlLlNldCgpO1xuICAgIG0uZWRnZXMuZm9yRWFjaChmdW5jdGlvbiAoa2V5bWFwLCBhcml0eSkge1xuICAgICAgaWYgKHJlc3VsdCA9PT0gZmFsc2UpIHJldHVybiBmYWxzZTsgLy8gYnJlYWsgb3V0IG9mIGl0ZXJhdGlvblxuICAgICAga2V5bWFwLmZvckVhY2goZnVuY3Rpb24gKGssIGtleSkge1xuICAgICAgICBpZiAocmVzdWx0ID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlOyAvLyBicmVhayBvdXQgb2YgaXRlcmF0aW9uXG5cbiAgICAgICAgdmFyIHBpZWNlO1xuICAgICAgICBpZiAoU3RydWN0LmlzU3RydWN0dXJlVHlwZShrZXkpIHx8IGtleSA9PT0gU09BKSB7XG4gICAgICAgICAgcGllY2UgPSB3YWxrKGssIGFyaXR5LCBJbW11dGFibGUuTGlzdCgpLCBmdW5jdGlvbiAoaXRlbXMsIG0xKSB7XG4gICAgICAgICAgICB2YXIgaXRlbSA9IHJlY29uc3RydWN0U2VxdWVuY2Uoa2V5LCBpdGVtcyk7XG4gICAgICAgICAgICByZXR1cm4gd2FsayhtMSwgdGFrZUNvdW50IC0gMSwgdmFsc1Jldi51bnNoaWZ0KGl0ZW0pLCBrb250KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwaWVjZSA9IHdhbGsoaywgdGFrZUNvdW50IC0gMSwgdmFsc1Jldi51bnNoaWZ0KGtleSksIGtvbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzdWx0ID0gKHBpZWNlID09PSBmYWxzZSkgPyBmYWxzZSA6IHJlc3VsdC51bmlvbihwaWVjZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG5cbmZ1bmN0aW9uIGNhcHR1cmVUb09iamVjdChjYXB0dXJlcywgbmFtZXMpIHtcbiAgdmFyIGQgPSB7fTtcbiAgY2FwdHVyZXMuZm9yRWFjaChmdW5jdGlvbiAoa2V5LCBpbmRleCkge1xuICAgIGRbbmFtZXNbaW5kZXhdIHx8ICgnJCcgKyBpbmRleCldID0ga2V5O1xuICB9KTtcbiAgcmV0dXJuIGQ7XG59XG5cbmZ1bmN0aW9uIHRyaWVLZXlzVG9PYmplY3RzKHRyaWVLZXlzUmVzdWx0LCBuYW1lcykge1xuICBpZiAodHJpZUtleXNSZXN1bHQgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiB0cmllS2V5c1Jlc3VsdC50b0xpc3QoKS5tYXAoZnVuY3Rpb24gKGUpIHsgcmV0dXJuIGNhcHR1cmVUb09iamVjdChlLCBuYW1lcyk7IH0pO1xufVxuXG5mdW5jdGlvbiBwcm9qZWN0T2JqZWN0cyhtLCBwcm9qZWN0aW9uKSB7XG4gIHZhciBuYW1lcyA9IHByb2plY3Rpb25OYW1lcyhwcm9qZWN0aW9uKTtcbiAgcmV0dXJuIHRyaWVLZXlzVG9PYmplY3RzKHRyaWVLZXlzKHByb2plY3QobSwgcHJvamVjdGlvbiksIG5hbWVzLmxlbmd0aCksIG5hbWVzKTtcbn1cblxuLy8gKFByb2plY3Rpb24sIENhcHR1cmVPYmplY3QpIC0+IFBhdHRlcm5cbmZ1bmN0aW9uIGluc3RhbnRpYXRlUHJvamVjdGlvbihwLCBvYmopIHtcbiAgdmFyIGNhcHR1cmVDb3VudCA9IDA7XG4gIHJldHVybiB3YWxrKHApO1xuXG4gIGZ1bmN0aW9uIHdhbGsocCkge1xuICAgIGlmIChpc0NhcHR1cmUocCkpIHtcbiAgICAgIHZhciB0aGlzQ2FwdHVyZSA9IGNhcHR1cmVDb3VudCsrO1xuICAgICAgdmFyIG5hbWUgPSBjYXB0dXJlTmFtZShwKTtcbiAgICAgIHJldHVybiAobmFtZSAhPT0gbnVsbCkgPyBvYmpbbmFtZV0gOiBvYmpbJyQnICsgdGhpc0NhcHR1cmVdO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHApKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHAubGVuZ3RoOyBpKyspIHtcblx0cmVzdWx0LnB1c2god2FsayhwW2ldKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGlmIChTdHJ1Y3QuaXNTdHJ1Y3R1cmUocCkpIHtcbiAgICAgIHZhciByZXN1bHRGaWVsZHMgPSBbXTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5tZXRhLmFyaXR5OyBpKyspIHtcbiAgICAgICAgcmVzdWx0RmllbGRzW2ldID0gd2FsayhwW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgU3RydWN0LlN0cnVjdHVyZShwLm1ldGEsIHJlc3VsdEZpZWxkcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHA7XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJldHR5VHJpZShtLCBvcHRpb25zT3B0KSB7XG4gIHZhciBhY2MgPSBbXTtcbiAgdmFyIG9wdGlvbnMgPSBvcHRpb25zT3B0IHx8IHt9O1xuICB3YWxrKG9wdGlvbnMuaW5pdGlhbEluZGVudCB8fCAwLCBtKTtcbiAgcmV0dXJuIGFjYy5qb2luKCcnKTtcblxuICBmdW5jdGlvbiB3YWxrKGksIG0pIHtcbiAgICBpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG4gICAgICB2YXIgdiA9IG0udmFsdWU7XG4gICAgICBpZiAoJ3ByZXR0eVN1Y2Nlc3MnIGluIG9wdGlvbnMpIHtcbiAgICAgICAgYWNjLnB1c2goXCIgXCIgKyBvcHRpb25zLnByZXR0eVN1Y2Nlc3ModikpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKEltbXV0YWJsZS5TZXQuaXNTZXQodikpIHsgdiA9IHYudG9BcnJheSgpOyB9XG4gICAgICAgIGFjYy5wdXNoKFwiIHtcIiArIEpTT04uc3RyaW5naWZ5KHYpICsgXCJ9XCIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChpc19lbXB0eVRyaWUobSkpIHtcbiAgICAgIGFjYy5wdXNoKFwiIDo6OiBub3RoaW5nXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBuZWVkU2VwID0gZmFsc2U7XG4gICAgaWYgKCFpc19lbXB0eVRyaWUobS53aWxkKSkge1xuICAgICAgdmFyIGtleSA9IFwi4piFXCI7XG4gICAgICBuZWVkU2VwID0gdHJ1ZTtcbiAgICAgIGFjYy5wdXNoKFwiIFwiKTtcbiAgICAgIGFjYy5wdXNoKGtleSk7XG4gICAgICB3YWxrKGkgKyBrZXkubGVuZ3RoICsgMSwgbS53aWxkKTtcbiAgICB9XG4gICAgbS5lZGdlc1xuICAgICAgLnRvT3JkZXJlZE1hcCgpXG4gICAgICAuc29ydEJ5KGZ1bmN0aW9uIChrZXltYXAsIGFyaXR5KSB7IHJldHVybiBhcml0eSB9KVxuICAgICAgLmZvckVhY2goZnVuY3Rpb24gKGtleW1hcCwgYXJpdHkpIHtcbiAgICAgICAga2V5bWFwXG4gICAgICAgICAgLnRvT3JkZXJlZE1hcCgpXG4gICAgICAgICAgLnNvcnRCeShmdW5jdGlvbiAoaywga2V5KSB7IHJldHVybiBrZXkgfSlcbiAgICAgICAgICAuZm9yRWFjaChmdW5jdGlvbiAoaywga2V5KSB7XG5cdCAgICBpZiAobmVlZFNlcCkge1xuXHQgICAgICBhY2MucHVzaChcIlxcblwiKTtcblx0ICAgICAgYWNjLnB1c2goaW5kZW50U3RyKGkpKTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIG5lZWRTZXAgPSB0cnVlO1xuXHQgICAgfVxuXHQgICAgYWNjLnB1c2goXCIgXCIpO1xuXHQgICAgaWYgKGtleSA9PT0gU09BKSBrZXkgPSAnPCcgKyBhcml0eSArICc+JztcbiAgICAgICAgICAgIGVsc2UgaWYgKFN0cnVjdC5pc1N0cnVjdHVyZVR5cGUoa2V5KSkga2V5ID0ga2V5LmxhYmVsICsgJzwnICsgYXJpdHkgKyAnPic7XG5cdCAgICBlbHNlIGlmIChrZXkgaW5zdGFuY2VvZiAkU3BlY2lhbCkga2V5ID0ga2V5Lm5hbWU7XG4gICAgICAgICAgICBlbHNlIGtleSA9IEpTT04uc3RyaW5naWZ5KGtleSk7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ID09PSAndW5kZWZpbmVkJykga2V5ID0gJ3VuZGVmaW5lZCc7XG5cdCAgICBhY2MucHVzaChrZXkpO1xuXHQgICAgd2FsayhpICsga2V5Lmxlbmd0aCArIDEsIGspO1xuICAgICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBpbmRlbnRTdHIoaSkge1xuICAgIHJldHVybiBuZXcgQXJyYXkoaSArIDEpLmpvaW4oJyAnKTsgLy8gZXd3XG4gIH1cbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIHBhcmVuVHlwZVRvU3RyaW5nKGtleSkge1xuICBpZiAoU3RydWN0LmlzU3RydWN0dXJlVHlwZShrZXkpKSB7XG4gICAgcmV0dXJuICc6JyArIGtleS5sYWJlbDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gJ0wnO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN0cmluZ1RvUGFyZW5UeXBlKGFyaXR5LCBrZXkpIHtcbiAgaWYgKGtleVswXSA9PT0gJzonKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJ1Y3QuU3RydWN0dXJlVHlwZShrZXkuc2xpY2UoMSksIGFyaXR5KTtcbiAgfSBlbHNlIGlmIChrZXkgPT09ICdMJykge1xuICAgIHJldHVybiBTT0E7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgSlNPTiB0cmllIHBhcmVuIHR5cGU6IFwiK2tleSk7XG59XG5cbmZ1bmN0aW9uIHRyaWVUb0pTT04odCkge1xuICBpZiAoaXNfZW1wdHlUcmllKHQpKSB7IHJldHVybiBbXTsgfVxuICBpZiAodCBpbnN0YW5jZW9mICRTdWNjZXNzKSB7IHJldHVybiBbdHJ1ZV07IH0gLy8gVE9ETzogY29uc2lkZXIgZ2VuZXJhbGl6aW5nXG5cbiAgLy8gSXQncyBhICRCcmFuY2guXG5cbiAgdmFyIGpQYXJlbnMgPSBbXTtcbiAgdmFyIGpBdG9tcyA9IFtdO1xuICB0LmVkZ2VzLmZvckVhY2goZnVuY3Rpb24gKGtleW1hcCwgYXJpdHkpIHtcbiAgICBrZXltYXAuZm9yRWFjaChmdW5jdGlvbiAoaywga2V5KSB7XG4gICAgICB2YXIgamsgPSB0cmllVG9KU09OKGspO1xuICAgICAgaWYgKFN0cnVjdC5pc1N0cnVjdHVyZVR5cGUoa2V5KSB8fCBrZXkgPT09IFNPQSkge1xuICAgICAgICBqUGFyZW5zLnB1c2goW2FyaXR5LCBwYXJlblR5cGVUb1N0cmluZyhrZXkpLCBqa10pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgakF0b21zLnB1c2goW2tleSwgamtdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBbalBhcmVucywgdHJpZVRvSlNPTih0LndpbGQpLCBqQXRvbXNdO1xufVxuXG5mdW5jdGlvbiBiYWRKU09OKGopIHtcbiAgZGllKFwiQ2Fubm90IGRlc2VyaWFsaXplIEpTT04gdHJpZTogXCIgKyBKU09OLnN0cmluZ2lmeShqKSk7XG59XG5cbmZ1bmN0aW9uIHRyaWVGcm9tSlNPTihqKSB7XG4gIHJldHVybiBkZWNvZGUoaik7XG5cbiAgZnVuY3Rpb24gZGVjb2RlKGopIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoaikpIGJhZEpTT04oaik7XG5cbiAgICBzd2l0Y2ggKGoubGVuZ3RoKSB7XG4gICAgY2FzZSAwOiByZXR1cm4gZW1wdHlUcmllO1xuICAgIGNhc2UgMTogcmV0dXJuIHJzdWNjZXNzKHRydWUpOyAvLyBUT0RPOiBjb25zaWRlciBnZW5lcmFsaXppbmdcbiAgICBjYXNlIDM6IHtcbiAgICAgIHZhciByZXN1bHQgPSByY29weWJyYW5jaChleHBhbmQocndpbGQoZGVjb2RlKGpbMV0pKSkpO1xuICAgICAgalswXS5mb3JFYWNoKGZ1bmN0aW9uIChlbnRyeSkge1xuICAgICAgICB2YXIgYXJpdHkgPSBlbnRyeVswXTtcbiAgICAgICAgaWYgKHR5cGVvZiBhcml0eSAhPT0gJ251bWJlcicpIGJhZEpTT04oaik7XG4gICAgICAgIHZhciBrZXkgPSBzdHJpbmdUb1BhcmVuVHlwZShhcml0eSwgZW50cnlbMV0pO1xuICAgICAgICBydXBkYXRlX2lucGxhY2UocmVzdWx0LCBhcml0eSwga2V5LCBkZWNvZGUoZW50cnlbMl0pKTtcbiAgICAgIH0pO1xuICAgICAgalsyXS5mb3JFYWNoKGZ1bmN0aW9uIChlbnRyeSkge1xuICAgICAgICB2YXIga2V5ID0gZW50cnlbMF07XG4gICAgICAgIHJ1cGRhdGVfaW5wbGFjZShyZXN1bHQsIDAsIGtleSwgZGVjb2RlKGVudHJ5WzFdKSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBjb2xsYXBzZShyZXN1bHQpO1xuICAgIH1cbiAgICBkZWZhdWx0OiBiYWRKU09OKGopO1xuICAgIH1cbiAgfVxufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuX18gPSBfXztcbm1vZHVsZS5leHBvcnRzLlNPQSA9IFNPQTtcbm1vZHVsZS5leHBvcnRzLiRDYXB0dXJlID0gJENhcHR1cmU7XG5tb2R1bGUuZXhwb3J0cy4kU3BlY2lhbCA9ICRTcGVjaWFsO1xubW9kdWxlLmV4cG9ydHMuXyQgPSBfJDtcbm1vZHVsZS5leHBvcnRzLmlzX2VtcHR5VHJpZSA9IGlzX2VtcHR5VHJpZTtcbm1vZHVsZS5leHBvcnRzLmVtcHR5VHJpZSA9IGVtcHR5VHJpZTtcbm1vZHVsZS5leHBvcnRzLmVtYmVkZGVkVHJpZSA9IGVtYmVkZGVkVHJpZTtcbm1vZHVsZS5leHBvcnRzLmVtYmVkZGVkVHJpZUFycmF5ID0gZW1iZWRkZWRUcmllQXJyYXk7XG5tb2R1bGUuZXhwb3J0cy5jb21waWxlUGF0dGVybiA9IGNvbXBpbGVQYXR0ZXJuO1xubW9kdWxlLmV4cG9ydHMubWF0Y2hQYXR0ZXJuID0gbWF0Y2hQYXR0ZXJuO1xubW9kdWxlLmV4cG9ydHMuX3VuaW9uID0gdW5pb247XG5tb2R1bGUuZXhwb3J0cy51bmlvbiA9IHVuaW9uTjtcbm1vZHVsZS5leHBvcnRzLmludGVyc2VjdCA9IGludGVyc2VjdDtcbm1vZHVsZS5leHBvcnRzLnN1YnRyYWN0ID0gc3VidHJhY3Q7XG5tb2R1bGUuZXhwb3J0cy5tYXRjaFZhbHVlID0gbWF0Y2hWYWx1ZTtcbm1vZHVsZS5leHBvcnRzLm1hdGNoVHJpZSA9IG1hdGNoVHJpZTtcbm1vZHVsZS5leHBvcnRzLmFwcGVuZFRyaWUgPSBhcHBlbmRUcmllO1xuLy8gbW9kdWxlLmV4cG9ydHMudHJpZVBydW5lQnJhbmNoID0gdHJpZVBydW5lQnJhbmNoO1xubW9kdWxlLmV4cG9ydHMudHJpZVN0ZXAgPSB0cmllU3RlcDtcbm1vZHVsZS5leHBvcnRzLnRyaWVTdWNjZXNzID0gcnN1Y2Nlc3M7XG5tb2R1bGUuZXhwb3J0cy5yZWxhYmVsID0gcmVsYWJlbDtcbm1vZHVsZS5leHBvcnRzLnByb2plY3Rpb25OYW1lcyA9IHByb2plY3Rpb25OYW1lcztcbm1vZHVsZS5leHBvcnRzLnByb2plY3Rpb25Bcml0eSA9IHByb2plY3Rpb25Bcml0eTtcbm1vZHVsZS5leHBvcnRzLnByb2plY3Rpb25Ub1BhdHRlcm4gPSBwcm9qZWN0aW9uVG9QYXR0ZXJuO1xubW9kdWxlLmV4cG9ydHMucHJvamVjdCA9IHByb2plY3Q7XG5tb2R1bGUuZXhwb3J0cy5wcm9qZWN0TWFueSA9IHByb2plY3RNYW55O1xubW9kdWxlLmV4cG9ydHMudHJpZUtleXMgPSB0cmllS2V5cztcbm1vZHVsZS5leHBvcnRzLmNhcHR1cmVUb09iamVjdCA9IGNhcHR1cmVUb09iamVjdDtcbm1vZHVsZS5leHBvcnRzLnRyaWVLZXlzVG9PYmplY3RzID0gdHJpZUtleXNUb09iamVjdHM7XG5tb2R1bGUuZXhwb3J0cy5wcm9qZWN0T2JqZWN0cyA9IHByb2plY3RPYmplY3RzO1xubW9kdWxlLmV4cG9ydHMuaW5zdGFudGlhdGVQcm9qZWN0aW9uID0gaW5zdGFudGlhdGVQcm9qZWN0aW9uO1xubW9kdWxlLmV4cG9ydHMucHJldHR5VHJpZSA9IHByZXR0eVRyaWU7XG5tb2R1bGUuZXhwb3J0cy50cmllVG9KU09OID0gdHJpZVRvSlNPTjtcbm1vZHVsZS5leHBvcnRzLnRyaWVGcm9tSlNPTiA9IHRyaWVGcm9tSlNPTjtcblxuLy8gRm9yIHRlc3Rpbmdcbm1vZHVsZS5leHBvcnRzLl90ZXN0aW5nID0ge1xuICByc3VjY2VzczogcnN1Y2Nlc3MsXG4gIHJzZXE6IHJzZXEsXG4gIHJ3aWxkOiByd2lsZFxufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuLy8gVUkgKERPTSArIGV2ZW50KSBzdXBwb3J0IGZvciBTeW5kaWNhdGVcbi8vXG4vLyBUaGUgcHJldmlvdXMgZG9tLWRyaXZlci5qcyArIGpxdWVyeS1kcml2ZXIuanMgYXBwcm9hY2ggd29ya2VkIGtpbmRcbi8vIG9mIE9LLCBidXQgc3RhcnRlZCB0byBmYWxsIGRvd24gaW4gYSBjb3VwbGUgb2YgYXJlYXM6IEFkZGVkIFVJXG4vLyBmcmFnbWVudHMgbGFja2VkIGlkZW50aXR5LCBzbyB3b3VsZCBzb21ldGltZXMgbW92ZSBhcm91bmQgdGhlIHRyZWVcbi8vIHVuZXhwZWN0ZWRseSBhcyB0aGV5IHdlcmUgdXBkYXRlZDsgYW5kIHRoZXJlIHdhcyBubyBjb252ZW5pZW50XG4vLyBtZWFucyBvZiBzY29waW5nIGV2ZW50IHNlbGVjdG9ycyB0byB3aXRoaW4gYSBwYXJ0aWN1bGFyIFVJXG4vLyBmcmFnbWVudCwgZGVzcGl0ZSB2YXJpb3VzIGF0dGVtcHRzIGF0IHRoaXMuXG4vL1xuLy8gVGhlIGRlc2lnbiBvZiB0aGlzIG1vZHVsZSBhaW1zIHRvIHRha2UgdGhlc2UgbGVzc29ucyBpbnRvIGFjY291bnQuXG5cbnZhciBJbW11dGFibGUgPSByZXF1aXJlKCdpbW11dGFibGUnKTtcbnZhciBQYXRjaCA9IHJlcXVpcmUoXCIuL3BhdGNoLmpzXCIpO1xudmFyIFRyaWUgPSByZXF1aXJlKFwiLi90cmllLmpzXCIpO1xudmFyIERlbWFuZE1hdGNoZXIgPSByZXF1aXJlKCcuL2RlbWFuZC1tYXRjaGVyLmpzJykuRGVtYW5kTWF0Y2hlcjtcbnZhciBTdHJ1Y3QgPSByZXF1aXJlKCcuL3N0cnVjdC5qcycpO1xudmFyIFJhbmRvbUlEID0gcmVxdWlyZSgnLi9yYW5kb21pZC5qcycpO1xuXG52YXIgRGF0YXNwYWNlXyA9IHJlcXVpcmUoXCIuL2RhdGFzcGFjZS5qc1wiKTtcbnZhciBEYXRhc3BhY2UgPSBEYXRhc3BhY2VfLkRhdGFzcGFjZTtcbnZhciBfXyA9IERhdGFzcGFjZV8uX187XG52YXIgXyQgPSBEYXRhc3BhY2VfLl8kO1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFByb3RvY29sXG5cbi8vIE1lc3NhZ2UuIEludGVyZXN0IGluIHRoaXMgY2F1c2VzIGV2ZW50IGxpc3RlbmVycyB0byBiZSBhZGRlZCBmb3Jcbi8vIHRoZSBnaXZlbiBldmVudFR5cGUgdG8gYWxsIG5vZGVzIG1hdGNoaW5nIHRoZSBnaXZlbiBzZWxlY3RvciAqYXRcbi8vIHRoZSB0aW1lIG9mIHRoZSBzdWJzY3JpcHRpb24qLiBBcyBub2RlcyAqZnJvbSB0aGlzIGxpYnJhcnkqIGNvbWVcbi8vIGFuZCBnbywgdGhleSB3aWxsIGhhdmUgZXZlbnQgaGFuZGxlcnMgaW5zdGFsbGVkIGFuZCByZW1vdmVkIGFzXG4vLyB3ZWxsLiBXQVJOSU5HOiBUaGUgc2ltcGxlIGltcGxlbWVudGF0aW9uIGJlbG93IGN1cnJlbnRseSBzY2FucyB0aGVcbi8vIHdob2xlIGRvY3VtZW50IGFueXRpbWUgYSBjaGFuZ2UgaXMgc2lnbmFsbGVkOyBpbiBmdXR1cmUsIGl0IG1heSBub3Rcbi8vIGRvIHN1Y2ggYSBzY2FuLlxudmFyIGdsb2JhbEV2ZW50ID0gU3RydWN0Lm1ha2VDb25zdHJ1Y3RvcignZ2xvYmFsLWV2ZW50JywgWydzZWxlY3RvcicsICdldmVudFR5cGUnLCAnZXZlbnQnXSk7XG5cbi8vIE1lc3NhZ2UuIEFzIGdsb2JhbEV2ZW50LCBidXQgaW5zdGVhZCBvZiB1c2luZyBhIHNlbGVjdG9yIHRvIGNob29zZVxuLy8gdGFyZ2V0IERPTSBub2RlcywgYXR0YWNoZXMgYW4gZXZlbnQgaGFuZGxlciB0byB0aGUgYnJvd3NlciBcIndpbmRvd1wiXG4vLyBvYmplY3QgaXRzZWxmLlxudmFyIHdpbmRvd0V2ZW50ID0gU3RydWN0Lm1ha2VDb25zdHJ1Y3Rvcignd2luZG93LWV2ZW50JywgWydldmVudFR5cGUnLCAnZXZlbnQnXSk7XG5cbi8vIE1lc3NhZ2UuIExpa2UgZ2xvYmFsRXZlbnQsIGJ1dCBhcHBsaWVzIG9ubHkgd2l0aGluIHRoZSBzY29wZSBvZiB0aGVcbi8vIFVJIGZyYWdtZW50IGlkZW50aWZpZWQuXG52YXIgdWlFdmVudCA9IFN0cnVjdC5tYWtlQ29uc3RydWN0b3IoJ3VpLWV2ZW50JywgWydmcmFnbWVudElkJywgJ3NlbGVjdG9yJywgJ2V2ZW50VHlwZScsICdldmVudCddKTtcblxuLy8gQXNzZXJ0aW9uLiBDYXVzZXMgdGhlIHNldHVwIG9mIERPTSBub2RlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlblxuLy8gSFRNTCBmcmFnbWVudCwgYXMgaW1tZWRpYXRlIGNoaWxkcmVuIG9mIGFsbCBub2RlcyBuYW1lZCBieSB0aGVcbi8vIGdpdmVuIHNlbGVjdG9yIHRoYXQgZXhpc3QgYXQgdGhlIHRpbWUgb2YgYXNzZXJ0aW9uLiBUaGUgb3JkZXJCeVxuLy8gZmllbGQgc2hvdWxkIGJlIG51bGwsIGEgc3RyaW5nLCBvciBhIG51bWJlci4gRnJhZ21lbnRzIGFyZSBvcmRlcmVkXG4vLyBwcmltYXJpbHkgYnkgb3JkZXJCeSwgYW5kIHNlY29uZGFyaWx5IGJ5IGZyYWdtZW50SWQuXG52YXIgdWlGcmFnbWVudCA9IFN0cnVjdC5tYWtlQ29uc3RydWN0b3IoJ3VpLWZyYWdtZW50JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbJ2ZyYWdtZW50SWQnLCAnc2VsZWN0b3InLCAnaHRtbCcsICdvcmRlckJ5J10pO1xuXG4vLyBBc3NlcnRpb24uIEFzc2VydGVkIGJ5IHJlc3BvbmRlbnQgdG8gYSBnaXZlbiB1aUZyYWdtZW50LlxudmFyIHVpRnJhZ21lbnRFeGlzdHMgPSBTdHJ1Y3QubWFrZUNvbnN0cnVjdG9yKCd1aS1mcmFnbWVudC1leGlzdHMnLCBbJ2ZyYWdtZW50SWQnXSk7XG5cbi8vIEFzc2VydGlvbi4gQ2F1c2VzIHRoZSBzZXR1cCBvZiBET00gYXR0cmlidXRlcyBvbiBhbGwgbm9kZXMgbmFtZWQgYnlcbi8vIHRoZSBnaXZlbiBzZWxlY3RvciB0aGF0IGV4aXN0IGF0IHRoZSB0aW1lIG9mIGFzc2VydGlvbi5cbi8vXG4vLyBOT1RFOiBBdHRyaWJ1dGUgXCJjbGFzc1wiIGlzIGEgc3BlY2lhbCBjYXNlOiBpdCB0cmVhdHMgdGhlIHZhbHVlIG9mXG4vLyB0aGUgYXR0cmlidXRlIGFzIGEgKHN0cmluZyBlbmNvZGluZyBvZiBhKSBzZXQuIFRoZSBnaXZlbiB2YWx1ZSBpc1xuLy8gc3BsaXQgb24gd2hpdGVzcGFjZSwgYW5kIGVhY2ggcGllY2UgaXMgYWRkZWQgdG8gdGhlIHNldCBvZiB0aGluZ3Ncbi8vIGFscmVhZHkgcHJlc2VudC4gKFNlZSB0aGUgaW1wbGVtZW50YXRpb24gZm9yIGRldGFpbHMuKVxudmFyIHVpQXR0cmlidXRlID0gU3RydWN0Lm1ha2VDb25zdHJ1Y3RvcigndWktYXR0cmlidXRlJywgWydzZWxlY3RvcicsICdhdHRyaWJ1dGUnLCAndmFsdWUnXSk7XG5cbi8vIEFzc2VydGlvbi4gU2ltaWxhciB0byB1aUF0dHJpYnV0ZSwgYnV0IGZvciBwcm9wZXJ0aWVzIG9mIERPTSBub2Rlcy5cbnZhciB1aVByb3BlcnR5ID0gU3RydWN0Lm1ha2VDb25zdHJ1Y3RvcigndWktcHJvcGVydHknLCBbJ3NlbGVjdG9yJywgJ3Byb3BlcnR5JywgJ3ZhbHVlJ10pO1xuXG4vLyBNZXNzYWdlcy5cbi8vIE5PVEU6IFRoZXNlIGRvIG5vdCB0cmVhdCBcImNsYXNzXCIgc3BlY2lhbGx5IVxudmFyIHNldEF0dHJpYnV0ZSA9IFN0cnVjdC5tYWtlQ29uc3RydWN0b3IoJ3NldC11aS1hdHRyaWJ1dGUnLCBbJ3NlbGVjdG9yJywgJ2F0dHJpYnV0ZScsICd2YWx1ZSddKTtcbnZhciByZW1vdmVBdHRyaWJ1dGUgPSBTdHJ1Y3QubWFrZUNvbnN0cnVjdG9yKCdyZW1vdmUtdWktYXR0cmlidXRlJywgWydzZWxlY3RvcicsICdhdHRyaWJ1dGUnXSk7XG52YXIgc2V0UHJvcGVydHkgPSBTdHJ1Y3QubWFrZUNvbnN0cnVjdG9yKCdzZXQtdWktcHJvcGVydHknLCBbJ3NlbGVjdG9yJywgJ3Byb3BlcnR5JywgJ3ZhbHVlJ10pO1xudmFyIHJlbW92ZVByb3BlcnR5ID0gU3RydWN0Lm1ha2VDb25zdHJ1Y3RvcigncmVtb3ZlLXVpLXByb3BlcnR5JywgWydzZWxlY3RvcicsICdwcm9wZXJ0eSddKTtcblxuLy8gQXNzZXJ0aW9uLiBDdXJyZW50IFwibG9jYXRpb24gaGFzaFwiIC0tIHRoZSBcIiMvcGF0aC9wYXJ0XCIgZnJhZ21lbnQgYXRcbi8vIHRoZSBlbmQgb2Ygd2luZG93LmxvY2F0aW9uLlxudmFyIGxvY2F0aW9uSGFzaCA9IFN0cnVjdC5tYWtlQ29uc3RydWN0b3IoJ2xvY2F0aW9uSGFzaCcsIFsndmFsdWUnXSk7XG5cbi8vIE1lc3NhZ2UuIENhdXNlcyB3aW5kb3cubG9jYXRpb24gdG8gYmUgdXBkYXRlZCB0byBoYXZlIHRoZSBnaXZlbiBuZXdcbi8vIFwibG9jYXRpb24gaGFzaFwiIHZhbHVlLlxudmFyIHNldExvY2F0aW9uSGFzaCA9IFN0cnVjdC5tYWtlQ29uc3RydWN0b3IoJ3NldExvY2F0aW9uSGFzaCcsIFsndmFsdWUnXSk7XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gSUQgYWxsb2NhdG9yc1xuXG52YXIgbW9kdWxlSW5zdGFuY2UgPSBSYW5kb21JRC5yYW5kb21JZCgxNiwgdHJ1ZSk7XG5cbnZhciBuZXh0RnJhZ21lbnRJZE51bWJlciA9IDA7XG5mdW5jdGlvbiBuZXdGcmFnbWVudElkKCkge1xuICByZXR1cm4gJ3VpXycgKyBtb2R1bGVJbnN0YW5jZSArICdfJyArIChuZXh0RnJhZ21lbnRJZE51bWJlcisrKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIHNwYXduVUlEcml2ZXIob3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgZ2xvYmFsRXZlbnRQcm9qID0gZ2xvYmFsRXZlbnQoXyQoJ3NlbGVjdG9yJyksIF8kKCdldmVudFR5cGUnKSwgX18pO1xuICBEYXRhc3BhY2Uuc3Bhd24oXG4gICAgbmV3IERlbWFuZE1hdGNoZXIoW1BhdGNoLm9ic2VydmUoZ2xvYmFsRXZlbnRQcm9qKV0sXG4gICAgICAgICAgICAgICAgICAgICAgW1BhdGNoLmFkdmVydGlzZShnbG9iYWxFdmVudFByb2opXSxcbiAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXNwYWNlLnNwYXduKG5ldyBHbG9iYWxFdmVudFN1cHBseShjLnNlbGVjdG9yLCBjLmV2ZW50VHlwZSkpO1xuICAgICAgICAgICAgICAgICAgICAgIH0sIHsgbmFtZTogJ2dsb2JhbEV2ZW50U3VwZXJ2aXNvcicgfSkpO1xuXG4gIHZhciB3aW5kb3dFdmVudFByb2ogPSB3aW5kb3dFdmVudChfJCgnZXZlbnRUeXBlJyksIF9fKTtcbiAgRGF0YXNwYWNlLnNwYXduKFxuICAgIG5ldyBEZW1hbmRNYXRjaGVyKFtQYXRjaC5vYnNlcnZlKHdpbmRvd0V2ZW50UHJvaildLFxuICAgICAgICAgICAgICAgICAgICAgIFtQYXRjaC5hZHZlcnRpc2Uod2luZG93RXZlbnRQcm9qKV0sXG4gICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIERhdGFzcGFjZS5zcGF3bihuZXcgV2luZG93RXZlbnRTdXBwbHkoYy5ldmVudFR5cGUpKTtcbiAgICAgICAgICAgICAgICAgICAgICB9LCB7IG5hbWU6ICd3aW5kb3dFdmVudFN1cGVydmlzb3InIH0pKTtcblxuICBEYXRhc3BhY2Uuc3Bhd24oXG4gICAgbmV3IERlbWFuZE1hdGNoZXIoW3VpRnJhZ21lbnQoXyQoJ2ZyYWdtZW50SWQnKSwgX18sIF9fLCBfXyldLFxuICAgICAgICAgICAgICAgICAgICAgIFt1aUZyYWdtZW50RXhpc3RzKF8kKCdmcmFnbWVudElkJykpXSxcbiAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXNwYWNlLnNwYXduKG5ldyBVSUZyYWdtZW50KGMuZnJhZ21lbnRJZCkpO1xuICAgICAgICAgICAgICAgICAgICAgIH0sIHsgbmFtZTogJ3VpRnJhZ21lbnRTdXBlcnZpc29yJyB9KSk7XG5cbiAgRGF0YXNwYWNlLnNwYXduKFxuICAgIG5ldyBEZW1hbmRNYXRjaGVyKFt1aUF0dHJpYnV0ZShfJCgnc2VsZWN0b3InKSwgXyQoJ2F0dHJpYnV0ZScpLCBfJCgndmFsdWUnKSldLFxuICAgICAgICAgICAgICAgICAgICAgIFtQYXRjaC5hZHZlcnRpc2UodWlBdHRyaWJ1dGUoXyQoJ3NlbGVjdG9yJyksIF8kKCdhdHRyaWJ1dGUnKSwgXyQoJ3ZhbHVlJykpKV0sXG4gICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIERhdGFzcGFjZS5zcGF3bihuZXcgVUlBdHRyaWJ1dGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGMuc2VsZWN0b3IsIGMuYXR0cmlidXRlLCBjLnZhbHVlLCAnYXR0cmlidXRlJykpO1xuICAgICAgICAgICAgICAgICAgICAgIH0sIHsgbmFtZTogJ3VpQXR0cmlidXRlU3VwZXJ2aXNvcicgfSkpO1xuXG4gIERhdGFzcGFjZS5zcGF3bihcbiAgICBuZXcgRGVtYW5kTWF0Y2hlcihbdWlQcm9wZXJ0eShfJCgnc2VsZWN0b3InKSwgXyQoJ3Byb3BlcnR5JyksIF8kKCd2YWx1ZScpKV0sXG4gICAgICAgICAgICAgICAgICAgICAgW1BhdGNoLmFkdmVydGlzZSh1aVByb3BlcnR5KF8kKCdzZWxlY3RvcicpLCBfJCgncHJvcGVydHknKSwgXyQoJ3ZhbHVlJykpKV0sXG4gICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIERhdGFzcGFjZS5zcGF3bihuZXcgVUlBdHRyaWJ1dGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGMuc2VsZWN0b3IsIGMucHJvcGVydHksIGMudmFsdWUsICdwcm9wZXJ0eScpKTtcbiAgICAgICAgICAgICAgICAgICAgICB9LCB7IG5hbWU6ICd1aVByb3BlcnR5U3VwZXJ2aXNvcicgfSkpO1xuXG4gIERhdGFzcGFjZS5zcGF3bihuZXcgQXR0cmlidXRlVXBkYXRlcigpKTtcbiAgRGF0YXNwYWNlLnNwYXduKG5ldyBMb2NhdGlvbkhhc2hUcmFja2VyKG9wdGlvbnMuZGVmYXVsdExvY2F0aW9uSGFzaCB8fCAnLycpKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIEdsb2JhbEV2ZW50U3VwcGx5KHNlbGVjdG9yLCBldmVudFR5cGUpIHtcbiAgdGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yO1xuICB0aGlzLmV2ZW50VHlwZSA9IGV2ZW50VHlwZTtcbiAgdGhpcy5kZW1hbmRQYXQgPSBQYXRjaC5vYnNlcnZlKGdsb2JhbEV2ZW50KHRoaXMuc2VsZWN0b3IsIHRoaXMuZXZlbnRUeXBlLCBfXykpO1xuICB0aGlzLm5hbWUgPSBbJ2dsb2JhbEV2ZW50Jywgc2VsZWN0b3IsIGV2ZW50VHlwZV07XG59XG5cbkdsb2JhbEV2ZW50U3VwcGx5LnByb3RvdHlwZS5ib290ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuaGFuZGxlckNsb3N1cmUgPSBEYXRhc3BhY2Uud3JhcChmdW5jdGlvbihlKSB7IHJldHVybiBzZWxmLmhhbmRsZURvbUV2ZW50KGUpOyB9KTtcbiAgdGhpcy51cGRhdGVFdmVudExpc3RlbmVycyh0cnVlKTtcblxuICByZXR1cm4gUGF0Y2guc3ViKHRoaXMuZGVtYW5kUGF0KSAvLyB0cmFjayBkZW1hbmRcbiAgICAuYW5kVGhlbihQYXRjaC5zdWIodWlGcmFnbWVudEV4aXN0cyhfXykpKSAvLyB0cmFjayBuZXcgZnJhZ21lbnRzXG4gICAgLmFuZFRoZW4oUGF0Y2gucHViKGdsb2JhbEV2ZW50KHRoaXMuc2VsZWN0b3IsIHRoaXMuZXZlbnRUeXBlLCBfXykpKSAvLyBpbmRpY2F0ZSBvdXIgcHJlc2VuY2VcbiAgO1xufTtcblxuR2xvYmFsRXZlbnRTdXBwbHkucHJvdG90eXBlLnVwZGF0ZUV2ZW50TGlzdGVuZXJzID0gZnVuY3Rpb24gKGluc3RhbGwpIHtcbiAgc2VsZWN0b3JNYXRjaChkb2N1bWVudCwgdGhpcy5zZWxlY3RvcikuZm9yRWFjaChcbiAgICBldmVudFVwZGF0ZXIoY2xlYW5FdmVudFR5cGUodGhpcy5ldmVudFR5cGUpLCB0aGlzLmhhbmRsZXJDbG9zdXJlLCBpbnN0YWxsKSk7XG59O1xuXG5HbG9iYWxFdmVudFN1cHBseS5wcm90b3R5cGUudHJhcGV4aXQgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnNvbGUubG9nKCdHbG9iYWxFdmVudFN1cHBseSB0cmFwZXhpdCBydW5uaW5nJywgdGhpcy5zZWxlY3RvciwgdGhpcy5ldmVudFR5cGUpO1xuICB0aGlzLnVwZGF0ZUV2ZW50TGlzdGVuZXJzKGZhbHNlKTtcbn07XG5cbkdsb2JhbEV2ZW50U3VwcGx5LnByb3RvdHlwZS5oYW5kbGVEb21FdmVudCA9IGZ1bmN0aW9uIChldmVudCkge1xuICBEYXRhc3BhY2Uuc2VuZChnbG9iYWxFdmVudCh0aGlzLnNlbGVjdG9yLCB0aGlzLmV2ZW50VHlwZSwgZXZlbnQpKTtcbiAgcmV0dXJuIGRlYWxXaXRoUHJldmVudERlZmF1bHQodGhpcy5ldmVudFR5cGUsIGV2ZW50KTtcbn07XG5cbkdsb2JhbEV2ZW50U3VwcGx5LnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gIHRoaXMudXBkYXRlRXZlbnRMaXN0ZW5lcnModHJ1ZSk7XG4gIC8vIFRPRE86IGRvbid0IGJlIHNvIGNydWRlIGFib3V0IHRoaXMgXi4gT24gdGhlIG9uZSBoYW5kLCB0aGlzIGxldHNcbiAgLy8gdXMgaWdub3JlIHVpRnJhZ21lbnRFeGlzdHMgcmVjb3JkcyBjb21pbmcgYW5kIGdvaW5nOyBvbiB0aGUgb3RoZXJcbiAgLy8gaGFuZCwgd2UgZG8gcG90ZW50aWFsbHkgYSBsb3Qgb2YgcmVkdW5kYW50IHdvcmsuXG4gIGlmIChlLnR5cGUgPT09ICdzdGF0ZUNoYW5nZScgJiYgZS5wYXRjaC5wcm9qZWN0KHRoaXMuZGVtYW5kUGF0KS5oYXNSZW1vdmVkKCkpIHtcbiAgICBEYXRhc3BhY2UuZXhpdCgpOyAvLyB0cmFwZXhpdCB3aWxsIHVuaW5zdGFsbCBldmVudCBsaXN0ZW5lcnNcbiAgfVxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIFdpbmRvd0V2ZW50U3VwcGx5KGV2ZW50VHlwZSkge1xuICB0aGlzLmV2ZW50VHlwZSA9IGV2ZW50VHlwZTtcbiAgdGhpcy5kZW1hbmRQYXQgPSBQYXRjaC5vYnNlcnZlKHdpbmRvd0V2ZW50KHRoaXMuZXZlbnRUeXBlLCBfXykpO1xuICB0aGlzLm5hbWUgPSBbJ3dpbmRvd0V2ZW50JywgZXZlbnRUeXBlXTtcbn1cblxuV2luZG93RXZlbnRTdXBwbHkucHJvdG90eXBlLmJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5oYW5kbGVyQ2xvc3VyZSA9IERhdGFzcGFjZS53cmFwKGZ1bmN0aW9uKGUpIHsgcmV0dXJuIHNlbGYuaGFuZGxlRG9tRXZlbnQoZSk7IH0pO1xuICB0aGlzLnVwZGF0ZUV2ZW50TGlzdGVuZXJzKHRydWUpO1xuXG4gIHJldHVybiBQYXRjaC5zdWIodGhpcy5kZW1hbmRQYXQpIC8vIHRyYWNrIGRlbWFuZFxuICAgIC5hbmRUaGVuKFBhdGNoLnB1Yih3aW5kb3dFdmVudCh0aGlzLmV2ZW50VHlwZSwgX18pKSkgLy8gaW5kaWNhdGUgb3VyIHByZXNlbmNlXG4gIDtcbn07XG5cbldpbmRvd0V2ZW50U3VwcGx5LnByb3RvdHlwZS51cGRhdGVFdmVudExpc3RlbmVycyA9IGZ1bmN0aW9uIChpbnN0YWxsKSB7XG4gIGlmIChpbnN0YWxsKSB7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoY2xlYW5FdmVudFR5cGUodGhpcy5ldmVudFR5cGUpLCB0aGlzLmhhbmRsZXJDbG9zdXJlKTtcbiAgfSBlbHNlIHtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihjbGVhbkV2ZW50VHlwZSh0aGlzLmV2ZW50VHlwZSksIHRoaXMuaGFuZGxlckNsb3N1cmUpO1xuICB9XG59O1xuXG5XaW5kb3dFdmVudFN1cHBseS5wcm90b3R5cGUudHJhcGV4aXQgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnNvbGUubG9nKCdXaW5kb3dFdmVudFN1cHBseSB0cmFwZXhpdCBydW5uaW5nJywgdGhpcy5ldmVudFR5cGUpO1xuICB0aGlzLnVwZGF0ZUV2ZW50TGlzdGVuZXJzKGZhbHNlKTtcbn07XG5cbldpbmRvd0V2ZW50U3VwcGx5LnByb3RvdHlwZS5oYW5kbGVEb21FdmVudCA9IGZ1bmN0aW9uIChldmVudCkge1xuICBEYXRhc3BhY2Uuc2VuZCh3aW5kb3dFdmVudCh0aGlzLmV2ZW50VHlwZSwgZXZlbnQpKTtcbiAgcmV0dXJuIGRlYWxXaXRoUHJldmVudERlZmF1bHQodGhpcy5ldmVudFR5cGUsIGV2ZW50KTtcbn07XG5cbldpbmRvd0V2ZW50U3VwcGx5LnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gIGlmIChlLnR5cGUgPT09ICdzdGF0ZUNoYW5nZScgJiYgZS5wYXRjaC5wcm9qZWN0KHRoaXMuZGVtYW5kUGF0KS5oYXNSZW1vdmVkKCkpIHtcbiAgICBEYXRhc3BhY2UuZXhpdCgpOyAvLyB0cmFwZXhpdCB3aWxsIHVuaW5zdGFsbCBldmVudCBsaXN0ZW5lcnNcbiAgfVxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIFVJRnJhZ21lbnQoZnJhZ21lbnRJZCkge1xuICB0aGlzLmZyYWdtZW50SWQgPSBmcmFnbWVudElkO1xuICB0aGlzLmRlbWFuZFByb2ogPSB1aUZyYWdtZW50KHRoaXMuZnJhZ21lbnRJZCwgXyQoJ3NlbGVjdG9yJyksIF8kKCdodG1sJyksIF8kKCdvcmRlckJ5JykpO1xuICB0aGlzLmV2ZW50RGVtYW5kUHJvaiA9XG4gICAgUGF0Y2gub2JzZXJ2ZSh1aUV2ZW50KHRoaXMuZnJhZ21lbnRJZCwgXyQoJ3NlbGVjdG9yJyksIF8kKCdldmVudFR5cGUnKSwgX18pKTtcblxuICB0aGlzLmN1cnJlbnRBbmNob3JOb2RlcyA9IFtdO1xuICB0aGlzLmN1cnJlbnRTZWxlY3RvciA9IG51bGw7XG4gIHRoaXMuY3VycmVudEh0bWwgPSBudWxsO1xuICB0aGlzLmN1cnJlbnRPcmRlckJ5ID0gbnVsbDtcblxuICB0aGlzLmN1cnJlbnRFdmVudFJlZ2lzdHJhdGlvbnMgPSBJbW11dGFibGUuTWFwKCk7XG4gIC8vIF4gTWFwIGZyb20gKE1hcCBvZiBzZWxlY3Rvci9ldmVudFR5cGUpIHRvIGNsb3N1cmUuXG5cbiAgdGhpcy5uYW1lID0gWyd1aUZyYWdtZW50JywgZnJhZ21lbnRJZF07XG59XG5cblVJRnJhZ21lbnQucHJvdG90eXBlLmJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBQYXRjaC5zdWIoVHJpZS5wcm9qZWN0aW9uVG9QYXR0ZXJuKHRoaXMuZGVtYW5kUHJvaikpIC8vIHRyYWNrIGRlbWFuZFxuICAgIC5hbmRUaGVuKFBhdGNoLmFzc2VydCh1aUZyYWdtZW50RXhpc3RzKHRoaXMuZnJhZ21lbnRJZCkpKSAvLyBhc3NlcnQgcHJlc2VuY2VcbiAgICAuYW5kVGhlbihQYXRjaC5zdWIoVHJpZS5wcm9qZWN0aW9uVG9QYXR0ZXJuKHRoaXMuZXZlbnREZW1hbmRQcm9qKSkpXG4gICAgLy8gXiB0cmFjayBkZW1hbmQgZm9yIGZyYWdtZW50LXNwZWNpZmljIGV2ZW50c1xuICA7XG59O1xuXG5VSUZyYWdtZW50LnByb3RvdHlwZS50cmFwZXhpdCA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc29sZS5sb2coJ1VJRnJhZ21lbnQgdHJhcGV4aXQgcnVubmluZycsIHRoaXMuZnJhZ21lbnRJZCk7XG4gIHRoaXMudXBkYXRlQ29udGVudChudWxsLCBudWxsLCBudWxsKTtcbn07XG5cbnZhciBTWU5ESUNBVEVfU09SVF9LRVkgPSAnX19zeW5kaWNhdGVfc29ydF9rZXknO1xuXG5mdW5jdGlvbiBzZXRTb3J0S2V5KG4sIG9yZGVyQnksIGZyYWdtZW50SWQpIHtcbiAgdmFyIHYgPSBKU09OLnN0cmluZ2lmeShbb3JkZXJCeSwgZnJhZ21lbnRJZF0pO1xuICBpZiAoJ2RhdGFzZXQnIGluIG4pIHtcbiAgICAvLyBodG1sIGVsZW1lbnQgbm9kZXMgZXRjLlxuICAgIG4uZGF0YXNldFtTWU5ESUNBVEVfU09SVF9LRVldID0gdjtcbiAgfSBlbHNlIHtcbiAgICAvLyB0ZXh0IG5vZGVzLCBzdmcgbm9kZXMsIGV0YyBldGMuXG4gICAgbltTWU5ESUNBVEVfU09SVF9LRVldID0gdjtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRTb3J0S2V5KG4pIHtcbiAgaWYgKCdkYXRhc2V0JyBpbiBuICYmIG4uZGF0YXNldFtTWU5ESUNBVEVfU09SVF9LRVldKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2Uobi5kYXRhc2V0W1NZTkRJQ0FURV9TT1JUX0tFWV0pO1xuICB9XG4gIGlmIChuW1NZTkRJQ0FURV9TT1JUX0tFWV0pIHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShuW1NZTkRJQ0FURV9TT1JUX0tFWV0pO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBoYXNTb3J0S2V5KG4sIG9yZGVyQnksIGZyYWdtZW50SWQpIHtcbiAgdmFyIHYgPSBnZXRTb3J0S2V5KG4pO1xuICBpZiAoIXYpIHJldHVybiBmYWxzZTtcbiAgaWYgKHZbMF0gIT09IG9yZGVyQnkpIHJldHVybiBmYWxzZTtcbiAgaWYgKHZbMV0gIT09IGZyYWdtZW50SWQpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGZpcnN0Q2hpbGROb2RlSW5kZXhfd2l0aFNvcnRLZXkobikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG4uY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChnZXRTb3J0S2V5KG4uY2hpbGROb2Rlc1tpXSkpIHJldHVybiBpO1xuICB9XG4gIHJldHVybiBuLmNoaWxkTm9kZXMubGVuZ3RoO1xufVxuXG4vLyBJZiAqbm8qIG5vZGVzIGhhdmUgYSBzb3J0IGtleSwgcmV0dXJucyBhIHZhbHVlIHRoYXQgeWllbGRzIGFuIGVtcHR5XG4vLyByYW5nZSBpbiBjb25qdW5jdGlvbiB3aXRoIGZpcnN0Q2hpbGROb2RlSW5kZXhfd2l0aFNvcnRLZXkuXG5mdW5jdGlvbiBsYXN0Q2hpbGROb2RlSW5kZXhfd2l0aFNvcnRLZXkobikge1xuICBmb3IgKHZhciBpID0gbi5jaGlsZE5vZGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKGdldFNvcnRLZXkobi5jaGlsZE5vZGVzW2ldKSkgcmV0dXJuIGk7XG4gIH1cbiAgcmV0dXJuIG4uY2hpbGROb2Rlcy5sZW5ndGggLSAxO1xufVxuXG5mdW5jdGlvbiBpc0dyZWF0ZXJUaGFuKGEsIGIpIHtcbiAgaWYgKHR5cGVvZiBhID4gdHlwZW9mIGIpIHJldHVybiB0cnVlO1xuICBpZiAodHlwZW9mIGEgPCB0eXBlb2YgYikgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gYSA+IGI7XG59XG5cbmZ1bmN0aW9uIGZpbmRJbnNlcnRpb25Qb2ludChuLCBvcmRlckJ5LCBmcmFnbWVudElkKSB7XG4gIHZhciBsbyA9IGZpcnN0Q2hpbGROb2RlSW5kZXhfd2l0aFNvcnRLZXkobik7XG4gIHZhciBoaSA9IGxhc3RDaGlsZE5vZGVJbmRleF93aXRoU29ydEtleShuKSArIDE7XG4gIC8vIGxvIDw9IGhpLCBhbmQgW2xvLCBoaSkgaGF2ZSBzb3J0IGtleXMuXG5cbiAgd2hpbGUgKGxvIDwgaGkpIHsgLy8gd2hlbiBsbyA9PT0gaGksIHRoZXJlJ3Mgbm90aGluZyBtb3JlIHRvIGV4YW1pbmUuXG4gICAgdmFyIHByb2JlID0gKGxvICsgaGkpID4+IDE7XG4gICAgdmFyIHByb2JlU29ydEtleSA9IGdldFNvcnRLZXkobi5jaGlsZE5vZGVzW3Byb2JlXSk7XG5cbiAgICBpZiAoKGlzR3JlYXRlclRoYW4ocHJvYmVTb3J0S2V5WzBdLCBvcmRlckJ5KSlcbiAgICAgICAgfHwgKChwcm9iZVNvcnRLZXlbMF0gPT09IG9yZGVyQnkpICYmIChwcm9iZVNvcnRLZXlbMV0gPiBmcmFnbWVudElkKSkpXG4gICAge1xuICAgICAgaGkgPSBwcm9iZTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG8gPSBwcm9iZSArIDE7XG4gICAgfVxuICB9XG5cbiAgLy8gbG8gPT09IGhpIG5vdy5cbiAgaWYgKGxvIDwgbi5jaGlsZE5vZGVzLmxlbmd0aCkge1xuICAgIHJldHVybiBuLmNoaWxkTm9kZXNbbG9dO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cblVJRnJhZ21lbnQucHJvdG90eXBlLnJlbW92ZU5vZGVzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgc2VsZi5jdXJyZW50QW5jaG9yTm9kZXMuZm9yRWFjaChmdW5jdGlvbiAoYW5jaG9yTm9kZSkge1xuICAgIHZhciBpbnNlcnRpb25Qb2ludCA9IGZpbmRJbnNlcnRpb25Qb2ludChhbmNob3JOb2RlLCBzZWxmLmN1cnJlbnRPcmRlckJ5LCBzZWxmLmZyYWdtZW50SWQpO1xuICAgIHdoaWxlICgxKSB7XG4gICAgICB2YXIgbiA9IGluc2VydGlvblBvaW50ID8gaW5zZXJ0aW9uUG9pbnQucHJldmlvdXNTaWJsaW5nIDogYW5jaG9yTm9kZS5sYXN0Q2hpbGQ7XG4gICAgICBpZiAoIShuICYmIGhhc1NvcnRLZXkobiwgc2VsZi5jdXJyZW50T3JkZXJCeSwgc2VsZi5mcmFnbWVudElkKSkpIGJyZWFrO1xuICAgICAgbi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG4pOyAvLyBhdXRvLXVwZGF0ZXMgcHJldmlvdXNTaWJsaW5nL2xhc3RDaGlsZFxuICAgIH1cbiAgfSk7XG59O1xuXG5mdW5jdGlvbiBodG1sVG9Ob2RlcyhwYXJlbnQsIGh0bWwpIHtcbiAgdmFyIGUgPSBwYXJlbnQuY2xvbmVOb2RlKGZhbHNlKTtcbiAgZS5pbm5lckhUTUwgPSBodG1sO1xuICByZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZS5jaGlsZE5vZGVzKTtcbn1cblxuZnVuY3Rpb24gY29uZmlndXJlTm9kZShuKSB7XG4gIC8vIFJ1bnMgcG9zdC1pbnNlcnRpb24gY29uZmlndXJhdGlvbiBvZiBub2Rlcy5cbiAgLy8gVE9ETzogcmV2aWV3IHRoaXMgZGVzaWduLlxuICBzZWxlY3Rvck1hdGNoKG4sICcuLXN5bmRpY2F0ZS1mb2N1cycpLmZvckVhY2goZnVuY3Rpb24gKG4pIHtcbiAgICBpZiAoJ2ZvY3VzJyBpbiBuICYmICdzZXRTZWxlY3Rpb25SYW5nZScgaW4gbikge1xuICAgICAgbi5mb2N1cygpO1xuICAgICAgbi5zZXRTZWxlY3Rpb25SYW5nZShuLnZhbHVlLmxlbmd0aCwgbi52YWx1ZS5sZW5ndGgpO1xuICAgIH1cbiAgfSk7XG59XG5cblVJRnJhZ21lbnQucHJvdG90eXBlLnVwZGF0ZUNvbnRlbnQgPSBmdW5jdGlvbiAobmV3U2VsZWN0b3IsIG5ld0h0bWwsIG5ld09yZGVyQnkpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHNlbGYucmVtb3ZlTm9kZXMoKTtcblxuICB2YXIgbmV3QW5jaG9ycyA9IChuZXdTZWxlY3RvciAhPT0gbnVsbCkgPyBzZWxlY3Rvck1hdGNoKGRvY3VtZW50LCBuZXdTZWxlY3RvcikgOiBbXTtcblxuICBuZXdBbmNob3JzLmZvckVhY2goZnVuY3Rpb24gKGFuY2hvck5vZGUpIHtcbiAgICB2YXIgaW5zZXJ0aW9uUG9pbnQgPSBmaW5kSW5zZXJ0aW9uUG9pbnQoYW5jaG9yTm9kZSwgbmV3T3JkZXJCeSwgc2VsZi5mcmFnbWVudElkKTtcbiAgICBodG1sVG9Ob2RlcyhhbmNob3JOb2RlLCBuZXdIdG1sKS5mb3JFYWNoKGZ1bmN0aW9uIChuZXdOb2RlKSB7XG4gICAgICBzZXRTb3J0S2V5KG5ld05vZGUsIG5ld09yZGVyQnksIHNlbGYuZnJhZ21lbnRJZCk7XG4gICAgICBhbmNob3JOb2RlLmluc2VydEJlZm9yZShuZXdOb2RlLCBpbnNlcnRpb25Qb2ludCk7XG4gICAgICBjb25maWd1cmVOb2RlKG5ld05vZGUpO1xuICAgIH0pO1xuICB9KTtcblxuICBzZWxmLmN1cnJlbnRBbmNob3JOb2RlcyA9IG5ld0FuY2hvcnM7XG4gIHNlbGYuY3VycmVudFNlbGVjdG9yID0gbmV3U2VsZWN0b3I7XG4gIHNlbGYuY3VycmVudEh0bWwgPSBuZXdIdG1sO1xuICBzZWxmLmN1cnJlbnRPcmRlckJ5ID0gbmV3T3JkZXJCeTtcblxuICBzZWxmLmN1cnJlbnRFdmVudFJlZ2lzdHJhdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAoX2hhbmRsZXJDbG9zdXJlLCBrZXkpIHtcbiAgICBzZWxmLnVwZGF0ZUV2ZW50TGlzdGVuZXJzKGtleS50b09iamVjdCgpLCB0cnVlKTsgLy8gKHJlKWluc3RhbGwgZXZlbnQgbGlzdGVuZXJzXG4gIH0pO1xufTtcblxuVUlGcmFnbWVudC5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKGUudHlwZSA9PT0gJ3N0YXRlQ2hhbmdlJykge1xuICAgIHZhciBmcmFnbWVudENoYW5nZXMgPSBlLnBhdGNoLnByb2plY3RPYmplY3RzKHNlbGYuZGVtYW5kUHJvaik7XG4gICAgZnJhZ21lbnRDaGFuZ2VzWzBdLmZvckVhY2goZnVuY3Rpb24gKGMpIHsgc2VsZi51cGRhdGVDb250ZW50KGMuc2VsZWN0b3IsIGMuaHRtbCwgYy5vcmRlckJ5KTsgfSk7XG4gICAgZnJhZ21lbnRDaGFuZ2VzWzFdLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcbiAgICAgIGlmIChjLnNlbGVjdG9yID09PSBzZWxmLmN1cnJlbnRTZWxlY3RvclxuICAgICAgICAgICYmIGMuaHRtbCA9PT0gc2VsZi5jdXJyZW50SHRtbFxuICAgICAgICAgICYmIGMub3JkZXJCeSA9PT0gc2VsZi5jdXJyZW50T3JkZXJCeSlcbiAgICAgIHtcbiAgICAgICAgRGF0YXNwYWNlLmV4aXQoKTsgLy8gdHJhcGV4aXQgd2lsbCByZW1vdmUgbm9kZXNcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHZhciBldmVudERlbWFuZCA9IGUucGF0Y2gucHJvamVjdE9iamVjdHMoc2VsZi5ldmVudERlbWFuZFByb2opO1xuICAgIGV2ZW50RGVtYW5kWzBdLmZvckVhY2goZnVuY3Rpb24gKGMpIHsgc2VsZi51cGRhdGVFdmVudExpc3RlbmVycyhjLCB0cnVlKTsgfSlcbiAgICBldmVudERlbWFuZFsxXS5mb3JFYWNoKGZ1bmN0aW9uIChjKSB7IHNlbGYudXBkYXRlRXZlbnRMaXN0ZW5lcnMoYywgZmFsc2UpOyB9KVxuICB9XG59O1xuXG5VSUZyYWdtZW50LnByb3RvdHlwZS5nZXRFdmVudENsb3N1cmUgPSBmdW5jdGlvbiAoYykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBrZXkgPSBJbW11dGFibGUuTWFwKGMpO1xuICBpZiAoIXNlbGYuY3VycmVudEV2ZW50UmVnaXN0cmF0aW9ucy5oYXMoa2V5KSkge1xuICAgIHZhciBoYW5kbGVyQ2xvc3VyZSA9IERhdGFzcGFjZS53cmFwKGZ1bmN0aW9uIChlKSB7IHJldHVybiBzZWxmLmhhbmRsZURvbUV2ZW50KGMsIGUpOyB9KTtcbiAgICBzZWxmLmN1cnJlbnRFdmVudFJlZ2lzdHJhdGlvbnMgPSBzZWxmLmN1cnJlbnRFdmVudFJlZ2lzdHJhdGlvbnMuc2V0KGtleSwgaGFuZGxlckNsb3N1cmUpO1xuICB9XG4gIHJldHVybiBzZWxmLmN1cnJlbnRFdmVudFJlZ2lzdHJhdGlvbnMuZ2V0KGtleSk7XG59O1xuXG5VSUZyYWdtZW50LnByb3RvdHlwZS5jbGVhckV2ZW50Q2xvc3VyZSA9IGZ1bmN0aW9uIChjKSB7XG4gIHZhciBrZXkgPSBJbW11dGFibGUuTWFwKGMpO1xuICB0aGlzLmN1cnJlbnRFdmVudFJlZ2lzdHJhdGlvbnMgPSB0aGlzLmN1cnJlbnRFdmVudFJlZ2lzdHJhdGlvbnMucmVtb3ZlKGtleSk7XG59O1xuXG5VSUZyYWdtZW50LnByb3RvdHlwZS51cGRhdGVFdmVudExpc3RlbmVycyA9IGZ1bmN0aW9uIChjLCBpbnN0YWxsKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIGhhbmRsZXJDbG9zdXJlID0gc2VsZi5nZXRFdmVudENsb3N1cmUoYyk7XG5cbiAgc2VsZi5jdXJyZW50QW5jaG9yTm9kZXMuZm9yRWFjaChmdW5jdGlvbiAoYW5jaG9yTm9kZSkge1xuICAgIHZhciBpbnNlcnRpb25Qb2ludCA9IGZpbmRJbnNlcnRpb25Qb2ludChhbmNob3JOb2RlLCBzZWxmLmN1cnJlbnRPcmRlckJ5LCBzZWxmLmZyYWdtZW50SWQpO1xuICAgIHdoaWxlICgxKSB7XG4gICAgICB2YXIgdWlOb2RlID0gaW5zZXJ0aW9uUG9pbnQgPyBpbnNlcnRpb25Qb2ludC5wcmV2aW91c1NpYmxpbmcgOiBhbmNob3JOb2RlLmxhc3RDaGlsZDtcbiAgICAgIGlmICghKHVpTm9kZSAmJiBoYXNTb3J0S2V5KHVpTm9kZSwgc2VsZi5jdXJyZW50T3JkZXJCeSwgc2VsZi5mcmFnbWVudElkKSkpIGJyZWFrO1xuICAgICAgaWYgKCdxdWVyeVNlbGVjdG9yQWxsJyBpbiB1aU5vZGUpIHtcbiAgICAgICAgc2VsZWN0b3JNYXRjaCh1aU5vZGUsIGMuc2VsZWN0b3IpLmZvckVhY2goXG4gICAgICAgICAgZXZlbnRVcGRhdGVyKGNsZWFuRXZlbnRUeXBlKGMuZXZlbnRUeXBlKSwgaGFuZGxlckNsb3N1cmUsIGluc3RhbGwpKTtcbiAgICAgIH1cbiAgICAgIGluc2VydGlvblBvaW50ID0gdWlOb2RlO1xuICAgIH1cbiAgfSk7XG5cbiAgaWYgKCFpbnN0YWxsKSB7XG4gICAgdGhpcy5jbGVhckV2ZW50Q2xvc3VyZShjKTtcbiAgfVxufTtcblxuVUlGcmFnbWVudC5wcm90b3R5cGUuaGFuZGxlRG9tRXZlbnQgPSBmdW5jdGlvbiAoYywgZSkge1xuICBEYXRhc3BhY2Uuc2VuZCh1aUV2ZW50KHRoaXMuZnJhZ21lbnRJZCwgYy5zZWxlY3RvciwgYy5ldmVudFR5cGUsIGUpKTtcbiAgcmV0dXJuIGRlYWxXaXRoUHJldmVudERlZmF1bHQoYy5ldmVudFR5cGUsIGUpO1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIFVJQXR0cmlidXRlKHNlbGVjdG9yLCBrZXksIHZhbHVlLCBraW5kKSB7XG4gIGlmIChbJ2F0dHJpYnV0ZScsICdwcm9wZXJ0eSddLmluZGV4T2Yoa2luZCkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVUlBdHRyaWJ1dGU6IGtpbmQgbXVzdCBiZSAnYXR0cmlidXRlJyBvciAncHJvcGVydHknOyBnb3QgXCIgKyBraW5kKTtcbiAgfVxuXG4gIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgdGhpcy5rZXkgPSBrZXk7XG4gIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgdGhpcy5raW5kID0ga2luZDtcblxuICB0aGlzLnNhdmVkVmFsdWVzID0gW107XG4gIC8vIF4gQXJyYXkgb2Yge25vZGU6IERPTU5vZGUsIHZhbHVlOiAoVSBOdWxsIFN0cmluZyl9LFxuICAvLyAgIHdoZW4gYXR0cmlidXRlICE9PSAnY2xhc3MnIG9yIGtpbmQgIT09ICdhdHRyaWJ1dGUnLlxuICAvLyBeIEFycmF5IG9mIHtub2RlOiBET01Ob2RlfSxcbiAgLy8gICB3aGVuIGF0dHJpYnV0ZSA9PT0gJ2NsYXNzJyBhbmQga2luZCA9PT0gJ2F0dHJpYnV0ZScuXG5cbiAgdGhpcy5uYW1lID0gWyd1aUF0dHJpYnV0ZScsIHNlbGVjdG9yLCBrZXksIHZhbHVlLCBraW5kXTtcbn1cblxuVUlBdHRyaWJ1dGUucHJvdG90eXBlLmJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBhID0gKCh0aGlzLmtpbmQgPT09ICdhdHRyaWJ1dGUnKSA/IHVpQXR0cmlidXRlIDogdWlQcm9wZXJ0eSkodGhpcy5zZWxlY3RvciwgdGhpcy5rZXksIHRoaXMudmFsdWUpO1xuICB0aGlzLmluc3RhbGwoKTtcbiAgcmV0dXJuIFBhdGNoLnN1YihhKS5hbmRUaGVuKFBhdGNoLnB1YihhKSk7XG59O1xuXG5VSUF0dHJpYnV0ZS5wcm90b3R5cGUudHJhcGV4aXQgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnNvbGUubG9nKCdVSUF0dHJpYnV0ZSB0cmFwZXhpdCBydW5uaW5nJywgdGhpcy5zZWxlY3RvciwgdGhpcy5rZXksIHRoaXMudmFsdWUsIHRoaXMua2luZCk7XG4gIHRoaXMucmVzdG9yZVNhdmVkVmFsdWVzKCk7XG59O1xuXG5mdW5jdGlvbiBzcGxpdENsYXNzVmFsdWUodikge1xuICB2ID0gKHYgfHwgJycpLnRyaW0oKTtcbiAgcmV0dXJuIHYgPyB2LnNwbGl0KC8gKy8pIDogW107XG59XG5cblVJQXR0cmlidXRlLnByb3RvdHlwZS5pbnN0YWxsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHNlbGVjdG9yTWF0Y2goZG9jdW1lbnQsIHNlbGYuc2VsZWN0b3IpLmZvckVhY2goZnVuY3Rpb24gKG5vZGUpIHtcbiAgICBzd2l0Y2ggKHNlbGYua2luZCkge1xuICAgICAgY2FzZSAnYXR0cmlidXRlJzpcbiAgICAgICAgaWYgKHNlbGYua2V5ID09PSAnY2xhc3MnKSB7XG4gICAgICAgICAgLy8gRGVsaWJlcmF0ZWx5IG1haW50YWlucyBkdXBsaWNhdGVzLCBzbyB3ZSBkb24ndCBpbnRlcmZlcmVcbiAgICAgICAgICAvLyB3aXRoIHBvdGVudGlhbCBvdGhlciBVSUF0dHJpYnV0ZSBpbnN0YW5jZXMgb24gdGhlIHNhbWVcbiAgICAgICAgICAvLyBvYmplY3RzIGZvciB0aGUgc2FtZSBhdHRyaWJ1dGUuIFNlZSBhbHNvXG4gICAgICAgICAgLy8gcmVzdG9yZVNhdmVkVmFsdWVzLlxuICAgICAgICAgIHZhciBleGlzdGluZyA9IHNwbGl0Q2xhc3NWYWx1ZShub2RlLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSk7XG4gICAgICAgICAgdmFyIHRvQWRkID0gc3BsaXRDbGFzc1ZhbHVlKHNlbGYudmFsdWUpO1xuICAgICAgICAgIHNlbGYuc2F2ZWRWYWx1ZXMucHVzaCh7bm9kZTogbm9kZX0pO1xuICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCdjbGFzcycsIGV4aXN0aW5nLmNvbmNhdCh0b0FkZCkuam9pbignICcpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZWxmLnNhdmVkVmFsdWVzLnB1c2goe25vZGU6IG5vZGUsIHZhbHVlOiBub2RlLmdldEF0dHJpYnV0ZShzZWxmLmtleSl9KTtcbiAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShzZWxmLmtleSwgc2VsZi52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdwcm9wZXJ0eSc6XG4gICAgICAgIHNlbGYuc2F2ZWRWYWx1ZXMucHVzaCh7bm9kZTogbm9kZSwgdmFsdWU6IG5vZGVbc2VsZi5rZXldfSk7XG4gICAgICAgIG5vZGVbc2VsZi5rZXldID0gc2VsZi52YWx1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9KTtcbn07XG5cblVJQXR0cmlidXRlLnByb3RvdHlwZS5yZXN0b3JlU2F2ZWRWYWx1ZXMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgc2VsZi5zYXZlZFZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uIChlbnRyeSkge1xuICAgIHN3aXRjaCAoc2VsZi5raW5kKSB7XG4gICAgICBjYXNlICdhdHRyaWJ1dGUnOlxuICAgICAgICBpZiAoc2VsZi5rZXkgPT09ICdjbGFzcycpIHtcbiAgICAgICAgICB2YXIgZXhpc3RpbmcgPSBzcGxpdENsYXNzVmFsdWUoZW50cnkubm9kZS5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykpO1xuICAgICAgICAgIHZhciB0b1JlbW92ZSA9IHNwbGl0Q2xhc3NWYWx1ZShzZWxmLnZhbHVlKTtcbiAgICAgICAgICB0b1JlbW92ZS5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICB2YXIgaSA9IGV4aXN0aW5nLmluZGV4T2Yodik7XG4gICAgICAgICAgICBpZiAoaSAhPT0gLTEpIHsgZXhpc3Rpbmcuc3BsaWNlKGksIDEpOyB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGV4aXN0aW5nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgZW50cnkubm9kZS5yZW1vdmVBdHRyaWJ1dGUoJ2NsYXNzJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVudHJ5Lm5vZGUuc2V0QXR0cmlidXRlKCdjbGFzcycsIGV4aXN0aW5nLmpvaW4oJyAnKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChlbnRyeS52YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgZW50cnkubm9kZS5yZW1vdmVBdHRyaWJ1dGUoc2VsZi5rZXkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlbnRyeS5ub2RlLnNldEF0dHJpYnV0ZShzZWxmLmtleSwgZW50cnkudmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3Byb3BlcnR5JzpcbiAgICAgICAgaWYgKHR5cGVvZiBlbnRyeS52YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBkZWxldGUgZW50cnkubm9kZVtzZWxmLmtleV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW50cnkubm9kZVtzZWxmLmtleV0gPSBlbnRyeS52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG4gIH0pO1xuICBzZWxmLnNhdmVkVmFsdWVzID0gW107XG59O1xuXG5VSUF0dHJpYnV0ZS5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICBpZiAoZS50eXBlID09PSAnc3RhdGVDaGFuZ2UnICYmIGUucGF0Y2guaGFzUmVtb3ZlZCgpKSB7XG4gICAgRGF0YXNwYWNlLmV4aXQoKTsgLy8gdHJhcGV4aXQgd2lsbCByZXN0b3JlIGF0dHJpYnV0ZXNcbiAgfVxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGVzY2FwZURhdGFBdHRyaWJ1dGVOYW1lKHMpIHtcbiAgLy8gUGVyIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IVE1MRWxlbWVudC9kYXRhc2V0LFxuICAvLyB0aGUgcnVsZXMgc2VlbSB0byBiZTpcbiAgLy9cbiAgLy8gMS4gTXVzdCBub3QgY29udGFpbiBhIGRhc2ggaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgYW4gQVNDSUkgbG93ZXJjYXNlIGxldHRlclxuICAvLyAyLiBNdXN0IG5vdCBjb250YWluIGFueXRoaW5nIG90aGVyIHRoYW46XG4gIC8vICAgICAtIGxldHRlcnNcbiAgLy8gICAgIC0gbnVtYmVyc1xuICAvLyAgICAgLSBkYXNoLCBkb3QsIGNvbG9uLCB1bmRlcnNjb3JlXG4gIC8vXG4gIC8vIEknbSBub3QgaW1wbGVtZW50aW5nIHRoaXMgZXhhY3RseSAtIEknbSBlc2NhcGluZyBzb21lIHRoaW5ncyB0aGF0XG4gIC8vIGRvbid0IGFic29sdXRlbHkgbmVlZCBlc2NhcGluZywgYmVjYXVzZSBpdCdzIHNpbXBsZXIgYW5kIEkgZG9uJ3RcbiAgLy8geWV0IG5lZWQgdG8gdW5kbyB0aGlzIHRyYW5zZm9ybWF0aW9uLlxuXG4gIGlmICh0eXBlb2YgcyAhPT0gJ3N0cmluZycpIHtcbiAgICBzID0gSlNPTi5zdHJpbmdpZnkocyk7XG4gIH1cblxuICB2YXIgcmVzdWx0ID0gJyc7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBjID0gc1tpXTtcbiAgICBpZiAoYyA+PSAnYScgJiYgYyA8PSAneicpIHsgcmVzdWx0ID0gcmVzdWx0ICsgYzsgY29udGludWU7IH1cbiAgICBpZiAoYyA+PSAnQScgJiYgYyA8PSAnWicpIHsgcmVzdWx0ID0gcmVzdWx0ICsgYzsgY29udGludWU7IH1cbiAgICBpZiAoYyA+PSAnMCcgJiYgYyA8PSAnOScpIHsgcmVzdWx0ID0gcmVzdWx0ICsgYzsgY29udGludWU7IH1cbiAgICBpZiAoYyA9PT0gJy4nIHx8IGMgPT09ICc6JykgeyByZXN1bHQgPSByZXN1bHQgKyBjOyBjb250aW51ZTsgfVxuXG4gICAgYyA9IGMuY2hhckNvZGVBdCgwKTtcbiAgICByZXN1bHQgPSByZXN1bHQgKyAnXycgKyBjICsgJ18nO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGRlYWxXaXRoUHJldmVudERlZmF1bHQoZXZlbnRUeXBlLCBldmVudCkge1xuICB2YXIgc2hvdWxkUHJldmVudERlZmF1bHQgPSBldmVudFR5cGUuY2hhckF0KDApICE9PSAnKyc7XG4gIGlmIChzaG91bGRQcmV2ZW50RGVmYXVsdCkgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgcmV0dXJuICFzaG91bGRQcmV2ZW50RGVmYXVsdDtcbn1cblxuZnVuY3Rpb24gY2xlYW5FdmVudFR5cGUoZXZlbnRUeXBlKSB7XG4gIHJldHVybiAoZXZlbnRUeXBlLmNoYXJBdCgwKSA9PT0gJysnKSA/IGV2ZW50VHlwZS5zbGljZSgxKSA6IGV2ZW50VHlwZTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0b3JNYXRjaChuLCBzZWxlY3Rvcikge1xuICBpZiAobiAmJiB0eXBlb2YgbiA9PT0gJ29iamVjdCcgJiYgJ3F1ZXJ5U2VsZWN0b3JBbGwnIGluIG4pIHtcbiAgICBpZiAoc2VsZWN0b3IgPT09ICcuJykge1xuICAgICAgcmV0dXJuIFtuXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG4ucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxuZnVuY3Rpb24gZXZlbnRVcGRhdGVyKGV2ZW50VHlwZSwgaGFuZGxlckNsb3N1cmUsIGluc3RhbGwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChuKSB7XG4gICAgLy8gYWRkRXZlbnRMaXN0ZW5lciBhbmQgcmVtb3ZlRXZlbnRMaXN0ZW5lciBhcmUgaWRlbXBvdGVudC5cbiAgICBpZiAoaW5zdGFsbCkge1xuICAgICAgbi5hZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgaGFuZGxlckNsb3N1cmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBoYW5kbGVyQ2xvc3VyZSk7XG4gICAgfVxuICB9O1xufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gQW5jaG9yKGV4cGxpY2l0RnJhZ21lbnRJZCkge1xuICB0aGlzLmZyYWdtZW50SWQgPVxuICAgICh0eXBlb2YgZXhwbGljaXRGcmFnbWVudElkID09PSAndW5kZWZpbmVkJykgPyBuZXdGcmFnbWVudElkKCkgOiBleHBsaWNpdEZyYWdtZW50SWQ7XG4gIHRoaXMuaHRtbFBhdHRlcm4gPSB1aUZyYWdtZW50KHRoaXMuZnJhZ21lbnRJZCwgX18sIF9fLCBfXyk7XG4gIHRoaXMuZXZlbnRQYXR0ZXJuID0gdWlFdmVudCh0aGlzLmZyYWdtZW50SWQsIF9fLCBfXywgX18pO1xufVxuXG5BbmNob3IucHJvdG90eXBlLmNvbnRleHQgPSBmdW5jdGlvbiAoLyogLi4uICovKSB7XG4gIHZhciBleHRuID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5tYXAoZXNjYXBlRGF0YUF0dHJpYnV0ZU5hbWUpLmpvaW4oJ19fJyk7XG4gIHJldHVybiBuZXcgQW5jaG9yKHRoaXMuZnJhZ21lbnRJZCArICdfXycgKyBleHRuKTtcbn07XG5cbkFuY2hvci5wcm90b3R5cGUuaHRtbCA9IGZ1bmN0aW9uIChzZWxlY3RvciwgaHRtbCwgb3JkZXJCeSkge1xuICByZXR1cm4gdWlGcmFnbWVudCh0aGlzLmZyYWdtZW50SWQsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yLFxuICAgICAgICAgICAgICAgICAgICBodG1sLFxuICAgICAgICAgICAgICAgICAgICB0eXBlb2Ygb3JkZXJCeSA9PT0gJ3VuZGVmaW5lZCcgPyBudWxsIDogb3JkZXJCeSk7XG59O1xuXG5BbmNob3IucHJvdG90eXBlLmV2ZW50ID0gZnVuY3Rpb24gKHNlbGVjdG9yLCBldmVudFR5cGUsIGV2ZW50KSB7XG4gIHJldHVybiB1aUV2ZW50KHRoaXMuZnJhZ21lbnRJZCwgc2VsZWN0b3IsIGV2ZW50VHlwZSwgZXZlbnQpO1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIExvY2F0aW9uSGFzaFRyYWNrZXIoZGVmYXVsdExvY2F0aW9uSGFzaCkge1xuICB0aGlzLmRlZmF1bHRMb2NhdGlvbkhhc2ggPSBkZWZhdWx0TG9jYXRpb25IYXNoO1xuICB0aGlzLmhhc2hWYWx1ZSA9IG51bGw7XG4gIHRoaXMubmFtZSA9ICdMb2NhdGlvbkhhc2hUcmFja2VyJztcbn1cblxuTG9jYXRpb25IYXNoVHJhY2tlci5wcm90b3R5cGUuYm9vdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLmxvYWRIYXNoKCk7XG4gIHRoaXMuaGFuZGxlckNsb3N1cmUgPSBEYXRhc3BhY2Uud3JhcChmdW5jdGlvbiAoZSkgeyBzZWxmLmhhbmRsZURvbUV2ZW50KGUpOyB9KTtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2hhc2hjaGFuZ2UnLCB0aGlzLmhhbmRsZXJDbG9zdXJlKTtcblxuICByZXR1cm4gUGF0Y2guYXNzZXJ0KGxvY2F0aW9uSGFzaCh0aGlzLmhhc2hWYWx1ZSkpXG4gICAgLmFuZFRoZW4oUGF0Y2guc3ViKHNldExvY2F0aW9uSGFzaChfXykpKTtcbn07XG5cbkxvY2F0aW9uSGFzaFRyYWNrZXIucHJvdG90eXBlLnRyYXBleGl0ID0gZnVuY3Rpb24gKCkge1xuICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignaGFzaGNoYW5nZScsIHRoaXMuaGFuZGxlckNsb3N1cmUpO1xufTtcblxuTG9jYXRpb25IYXNoVHJhY2tlci5wcm90b3R5cGUubG9hZEhhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuaGFzaFZhbHVlID0gd2luZG93LmxvY2F0aW9uLmhhc2g7XG4gIGlmICh0aGlzLmhhc2hWYWx1ZS5sZW5ndGggJiYgdGhpcy5oYXNoVmFsdWVbMF0gPT09ICcjJykge1xuICAgIHRoaXMuaGFzaFZhbHVlID0gdGhpcy5oYXNoVmFsdWUuc2xpY2UoMSk7XG4gIH1cbiAgaWYgKCF0aGlzLmhhc2hWYWx1ZSkge1xuICAgIHRoaXMuaGFzaFZhbHVlID0gdGhpcy5kZWZhdWx0TG9jYXRpb25IYXNoO1xuICB9XG59O1xuXG5Mb2NhdGlvbkhhc2hUcmFja2VyLnByb3RvdHlwZS5oYW5kbGVEb21FdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gIHRoaXMubG9hZEhhc2goKTtcbiAgRGF0YXNwYWNlLnN0YXRlQ2hhbmdlKFBhdGNoLnJldHJhY3QobG9jYXRpb25IYXNoKF9fKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hbmRUaGVuKFBhdGNoLmFzc2VydChsb2NhdGlvbkhhc2godGhpcy5oYXNoVmFsdWUpKSkpO1xufTtcblxuTG9jYXRpb25IYXNoVHJhY2tlci5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICBpZiAoZS50eXBlID09PSAnbWVzc2FnZScgJiYgc2V0TG9jYXRpb25IYXNoLmlzQ2xhc3NPZihlLm1lc3NhZ2UpKSB7XG4gICAgd2luZG93LmxvY2F0aW9uLmhhc2ggPSBlLm1lc3NhZ2VbMF07XG4gIH1cbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBBdHRyaWJ1dGVVcGRhdGVyKCkge1xuICB0aGlzLm5hbWUgPSAnQXR0cmlidXRlVXBkYXRlcic7XG59XG5cbkF0dHJpYnV0ZVVwZGF0ZXIucHJvdG90eXBlLmJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBQYXRjaC5zdWIoc2V0QXR0cmlidXRlKF9fLCBfXywgX18pKVxuICAgIC5hbmRUaGVuKFBhdGNoLnN1YihyZW1vdmVBdHRyaWJ1dGUoX18sIF9fKSkpXG4gICAgLmFuZFRoZW4oUGF0Y2guc3ViKHNldFByb3BlcnR5KF9fLCBfXywgX18pKSlcbiAgICAuYW5kVGhlbihQYXRjaC5zdWIocmVtb3ZlUHJvcGVydHkoX18sIF9fKSkpXG4gIDtcbn07XG5cbkF0dHJpYnV0ZVVwZGF0ZXIucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKGUpIHtcbiAgaWYgKGUudHlwZSA9PT0gJ21lc3NhZ2UnKSB7XG4gICAgdmFyIGYgPSBmYWxzZTtcbiAgICBpZiAoc2V0QXR0cmlidXRlLmlzQ2xhc3NPZihlLm1lc3NhZ2UpKSB7XG4gICAgICBmID0gZnVuY3Rpb24gKG4sIGspIHsgbi5zZXRBdHRyaWJ1dGUoaywgZS5tZXNzYWdlWzJdKTsgfTtcbiAgICB9IGVsc2UgaWYgKHJlbW92ZUF0dHJpYnV0ZS5pc0NsYXNzT2YoZS5tZXNzYWdlKSkge1xuICAgICAgZiA9IGZ1bmN0aW9uIChuLCBrKSB7IG4ucmVtb3ZlQXR0cmlidXRlKGspOyB9O1xuICAgIH0gZWxzZSBpZiAoc2V0UHJvcGVydHkuaXNDbGFzc09mKGUubWVzc2FnZSkpIHtcbiAgICAgIGYgPSBmdW5jdGlvbiAobiwgaykgeyBuW2tdID0gZS5tZXNzYWdlWzJdOyB9O1xuICAgIH0gZWxzZSBpZiAocmVtb3ZlUHJvcGVydHkuaXNDbGFzc09mKGUubWVzc2FnZSkpIHtcbiAgICAgIGYgPSBmdW5jdGlvbiAobiwgaykgeyBkZWxldGUgbltrXTsgfTtcbiAgICB9XG4gICAgaWYgKGYpIHtcbiAgICAgIHNlbGVjdG9yTWF0Y2goZG9jdW1lbnQsIGUubWVzc2FnZVswXSkuZm9yRWFjaChmdW5jdGlvbiAobikge1xuICAgICAgICBmKG4sIGUubWVzc2FnZVsxXSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5uZXdGcmFnbWVudElkID0gbmV3RnJhZ21lbnRJZDtcbm1vZHVsZS5leHBvcnRzLnNwYXduVUlEcml2ZXIgPSBzcGF3blVJRHJpdmVyO1xubW9kdWxlLmV4cG9ydHMuQW5jaG9yID0gQW5jaG9yO1xubW9kdWxlLmV4cG9ydHMuZ2xvYmFsRXZlbnQgPSBnbG9iYWxFdmVudDtcbm1vZHVsZS5leHBvcnRzLndpbmRvd0V2ZW50ID0gd2luZG93RXZlbnQ7XG5tb2R1bGUuZXhwb3J0cy51aUV2ZW50ID0gdWlFdmVudDtcbm1vZHVsZS5leHBvcnRzLnVpRnJhZ21lbnQgPSB1aUZyYWdtZW50O1xubW9kdWxlLmV4cG9ydHMudWlGcmFnbWVudEV4aXN0cyA9IHVpRnJhZ21lbnRFeGlzdHM7XG5tb2R1bGUuZXhwb3J0cy51aUF0dHJpYnV0ZSA9IHVpQXR0cmlidXRlO1xubW9kdWxlLmV4cG9ydHMudWlQcm9wZXJ0eSA9IHVpUHJvcGVydHk7XG5tb2R1bGUuZXhwb3J0cy5zZXRBdHRyaWJ1dGUgPSBzZXRBdHRyaWJ1dGU7XG5tb2R1bGUuZXhwb3J0cy5yZW1vdmVBdHRyaWJ1dGUgPSByZW1vdmVBdHRyaWJ1dGU7XG5tb2R1bGUuZXhwb3J0cy5zZXRQcm9wZXJ0eSA9IHNldFByb3BlcnR5O1xubW9kdWxlLmV4cG9ydHMucmVtb3ZlUHJvcGVydHkgPSByZW1vdmVQcm9wZXJ0eTtcbm1vZHVsZS5leHBvcnRzLmxvY2F0aW9uSGFzaCA9IGxvY2F0aW9uSGFzaDtcbm1vZHVsZS5leHBvcnRzLnNldExvY2F0aW9uSGFzaCA9IHNldExvY2F0aW9uSGFzaDtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgUmVmbGVjdCA9IHJlcXVpcmUoXCIuL3JlZmxlY3QuanNcIik7XG5cbm1vZHVsZS5leHBvcnRzLmV4dGVuZCA9IGZ1bmN0aW9uICh3aGF0LCBfd2l0aCkge1xuICBmb3IgKHZhciBwcm9wIGluIF93aXRoKSB7XG4gICAgaWYgKF93aXRoLmhhc093blByb3BlcnR5KHByb3ApKSB7XG4gICAgICB3aGF0W3Byb3BdID0gX3dpdGhbcHJvcF07XG4gICAgfVxuICB9XG4gIHJldHVybiB3aGF0O1xufTtcblxubW9kdWxlLmV4cG9ydHMua3dBcHBseSA9IGZ1bmN0aW9uIChmLCB0aGlzQXJnLCBhcmdzKSB7XG4gIHZhciBmb3JtYWxzID0gUmVmbGVjdC5mb3JtYWxQYXJhbWV0ZXJzKGYpO1xuICB2YXIgYWN0dWFscyA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZm9ybWFscy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBmb3JtYWwgPSBmb3JtYWxzW2ldO1xuICAgIGlmICghKGZvcm1hbCBpbiBhcmdzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRnVuY3Rpb24gcGFyYW1ldGVyICdcIitmb3JtYWwrXCInIG5vdCBwcmVzZW50IGluIGFyZ3NcIik7XG4gICAgfVxuICAgIGFjdHVhbHMucHVzaChhcmdzW2Zvcm1hbF0pO1xuICB9XG4gIHJldHVybiBmLmFwcGx5KHRoaXNBcmcsIGFjdHVhbHMpO1xufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuLy8gV2FrZSBkZXRlY3RvciAtIG5vdGljZXMgd2hlbiBzb21ldGhpbmcgKHN1Y2ggYXNcbi8vIHN1c3BlbnNpb24vc2xlZXBpbmchKSBoYXMgY2F1c2VkIHBlcmlvZGljIGFjdGl2aXRpZXMgdG8gYmVcbi8vIGludGVycnVwdGVkLCBhbmQgd2FybnMgb3RoZXJzIGFib3V0IGl0XG4vLyBJbnNwaXJlZCBieSBodHRwOi8vYmxvZy5hbGV4bWFjY2F3LmNvbS9qYXZhc2NyaXB0LXdha2UtZXZlbnRcblxudmFyIFBhdGNoID0gcmVxdWlyZShcIi4vcGF0Y2guanNcIik7XG52YXIgU3RydWN0ID0gcmVxdWlyZSgnLi9zdHJ1Y3QuanMnKTtcblxudmFyIERhdGFzcGFjZV8gPSByZXF1aXJlKFwiLi9kYXRhc3BhY2UuanNcIik7XG52YXIgRGF0YXNwYWNlID0gRGF0YXNwYWNlXy5EYXRhc3BhY2U7XG52YXIgX18gPSBEYXRhc3BhY2VfLl9fO1xudmFyIF8kID0gRGF0YXNwYWNlXy5fJDtcblxudmFyIHdha2VFdmVudCA9IFN0cnVjdC5tYWtlQ29uc3RydWN0b3IoJ3dha2VFdmVudCcsIFtdKTtcblxuZnVuY3Rpb24gc3Bhd25XYWtlRGV0ZWN0b3IocGVyaW9kT3B0KSB7XG4gIERhdGFzcGFjZS5zcGF3bihuZXcgV2FrZURldGVjdG9yKHBlcmlvZE9wdCkpO1xufVxuXG5mdW5jdGlvbiBXYWtlRGV0ZWN0b3IocGVyaW9kT3B0KSB7XG4gIHRoaXMucGVyaW9kID0gcGVyaW9kT3B0IHx8IDEwMDAwO1xuICB0aGlzLm1vc3RSZWNlbnRUcmlnZ2VyID0gKyhuZXcgRGF0ZSgpKTtcbiAgdGhpcy50aW1lcklkID0gbnVsbDtcbn1cblxuV2FrZURldGVjdG9yLnByb3RvdHlwZS5ib290ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMudGltZXJJZCA9IHNldEludGVydmFsKERhdGFzcGFjZS53cmFwKGZ1bmN0aW9uICgpIHsgc2VsZi50cmlnZ2VyKCk7IH0pLCB0aGlzLnBlcmlvZCk7XG4gIHJldHVybiBQYXRjaC5wdWIod2FrZUV2ZW50KCkpO1xufTtcblxuV2FrZURldGVjdG9yLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7fTtcblxuV2FrZURldGVjdG9yLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm93ID0gKyhuZXcgRGF0ZSgpKTtcbiAgaWYgKG5vdyAtIHRoaXMubW9zdFJlY2VudFRyaWdnZXIgPiB0aGlzLnBlcmlvZCAqIDEuNSkge1xuICAgIERhdGFzcGFjZS5zZW5kKHdha2VFdmVudCgpKTtcbiAgfVxuICB0aGlzLm1vc3RSZWNlbnRUcmlnZ2VyID0gbm93O1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLnNwYXduV2FrZURldGVjdG9yID0gc3Bhd25XYWtlRGV0ZWN0b3I7XG5tb2R1bGUuZXhwb3J0cy5XYWtlRGV0ZWN0b3IgPSBXYWtlRGV0ZWN0b3I7XG5tb2R1bGUuZXhwb3J0cy53YWtlRXZlbnQgPSB3YWtlRXZlbnQ7XG4iXX0=