27802 lines
2.3 MiB
27802 lines
2.3 MiB
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
'use strict'
|
|
|
|
exports.byteLength = byteLength
|
|
exports.toByteArray = toByteArray
|
|
exports.fromByteArray = fromByteArray
|
|
|
|
var lookup = []
|
|
var revLookup = []
|
|
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
|
|
|
|
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
|
for (var i = 0, len = code.length; i < len; ++i) {
|
|
lookup[i] = code[i]
|
|
revLookup[code.charCodeAt(i)] = i
|
|
}
|
|
|
|
// Support decoding URL-safe base64 strings, as Node.js does.
|
|
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
|
|
revLookup['-'.charCodeAt(0)] = 62
|
|
revLookup['_'.charCodeAt(0)] = 63
|
|
|
|
function getLens (b64) {
|
|
var len = b64.length
|
|
|
|
if (len % 4 > 0) {
|
|
throw new Error('Invalid string. Length must be a multiple of 4')
|
|
}
|
|
|
|
// Trim off extra bytes after placeholder bytes are found
|
|
// See: https://github.com/beatgammit/base64-js/issues/42
|
|
var validLen = b64.indexOf('=')
|
|
if (validLen === -1) validLen = len
|
|
|
|
var placeHoldersLen = validLen === len
|
|
? 0
|
|
: 4 - (validLen % 4)
|
|
|
|
return [validLen, placeHoldersLen]
|
|
}
|
|
|
|
// base64 is 4/3 + up to two characters of the original data
|
|
function byteLength (b64) {
|
|
var lens = getLens(b64)
|
|
var validLen = lens[0]
|
|
var placeHoldersLen = lens[1]
|
|
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
|
}
|
|
|
|
function _byteLength (b64, validLen, placeHoldersLen) {
|
|
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
|
}
|
|
|
|
function toByteArray (b64) {
|
|
var tmp
|
|
var lens = getLens(b64)
|
|
var validLen = lens[0]
|
|
var placeHoldersLen = lens[1]
|
|
|
|
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
|
|
|
|
var curByte = 0
|
|
|
|
// if there are placeholders, only get up to the last complete 4 chars
|
|
var len = placeHoldersLen > 0
|
|
? validLen - 4
|
|
: validLen
|
|
|
|
var i
|
|
for (i = 0; i < len; i += 4) {
|
|
tmp =
|
|
(revLookup[b64.charCodeAt(i)] << 18) |
|
|
(revLookup[b64.charCodeAt(i + 1)] << 12) |
|
|
(revLookup[b64.charCodeAt(i + 2)] << 6) |
|
|
revLookup[b64.charCodeAt(i + 3)]
|
|
arr[curByte++] = (tmp >> 16) & 0xFF
|
|
arr[curByte++] = (tmp >> 8) & 0xFF
|
|
arr[curByte++] = tmp & 0xFF
|
|
}
|
|
|
|
if (placeHoldersLen === 2) {
|
|
tmp =
|
|
(revLookup[b64.charCodeAt(i)] << 2) |
|
|
(revLookup[b64.charCodeAt(i + 1)] >> 4)
|
|
arr[curByte++] = tmp & 0xFF
|
|
}
|
|
|
|
if (placeHoldersLen === 1) {
|
|
tmp =
|
|
(revLookup[b64.charCodeAt(i)] << 10) |
|
|
(revLookup[b64.charCodeAt(i + 1)] << 4) |
|
|
(revLookup[b64.charCodeAt(i + 2)] >> 2)
|
|
arr[curByte++] = (tmp >> 8) & 0xFF
|
|
arr[curByte++] = 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) & 0xFF0000) +
|
|
((uint8[i + 1] << 8) & 0xFF00) +
|
|
(uint8[i + 2] & 0xFF)
|
|
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 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]
|
|
parts.push(
|
|
lookup[tmp >> 2] +
|
|
lookup[(tmp << 4) & 0x3F] +
|
|
'=='
|
|
)
|
|
} else if (extraBytes === 2) {
|
|
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
|
|
parts.push(
|
|
lookup[tmp >> 10] +
|
|
lookup[(tmp >> 4) & 0x3F] +
|
|
lookup[(tmp << 2) & 0x3F] +
|
|
'='
|
|
)
|
|
}
|
|
|
|
return parts.join('')
|
|
}
|
|
|
|
},{}],2:[function(require,module,exports){
|
|
|
|
},{}],3:[function(require,module,exports){
|
|
(function (Buffer){(function (){
|
|
/*!
|
|
* The buffer module from node.js, for the browser.
|
|
*
|
|
* @author Feross Aboukhadijeh <https://feross.org>
|
|
* @license MIT
|
|
*/
|
|
/* eslint-disable no-proto */
|
|
|
|
'use strict'
|
|
|
|
var base64 = require('base64-js')
|
|
var ieee754 = require('ieee754')
|
|
|
|
exports.Buffer = Buffer
|
|
exports.SlowBuffer = SlowBuffer
|
|
exports.INSPECT_MAX_BYTES = 50
|
|
|
|
var K_MAX_LENGTH = 0x7fffffff
|
|
exports.kMaxLength = K_MAX_LENGTH
|
|
|
|
/**
|
|
* If `Buffer.TYPED_ARRAY_SUPPORT`:
|
|
* === true Use Uint8Array implementation (fastest)
|
|
* === false Print warning and recommend using `buffer` v4.x which has an 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+.
|
|
*
|
|
* We report that the browser does not support typed arrays if the are not subclassable
|
|
* using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
|
|
* (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
|
|
* for __proto__ and has a buggy typed array implementation.
|
|
*/
|
|
Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
|
|
|
|
if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
|
|
typeof console.error === 'function') {
|
|
console.error(
|
|
'This browser lacks typed array (Uint8Array) support which is required by ' +
|
|
'`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
|
|
)
|
|
}
|
|
|
|
function typedArraySupport () {
|
|
// Can typed array instances can be augmented?
|
|
try {
|
|
var arr = new Uint8Array(1)
|
|
arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }
|
|
return arr.foo() === 42
|
|
} catch (e) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(Buffer.prototype, 'parent', {
|
|
enumerable: true,
|
|
get: function () {
|
|
if (!Buffer.isBuffer(this)) return undefined
|
|
return this.buffer
|
|
}
|
|
})
|
|
|
|
Object.defineProperty(Buffer.prototype, 'offset', {
|
|
enumerable: true,
|
|
get: function () {
|
|
if (!Buffer.isBuffer(this)) return undefined
|
|
return this.byteOffset
|
|
}
|
|
})
|
|
|
|
function createBuffer (length) {
|
|
if (length > K_MAX_LENGTH) {
|
|
throw new RangeError('The value "' + length + '" is invalid for option "size"')
|
|
}
|
|
// Return an augmented `Uint8Array` instance
|
|
var buf = new Uint8Array(length)
|
|
buf.__proto__ = Buffer.prototype
|
|
return buf
|
|
}
|
|
|
|
/**
|
|
* 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) {
|
|
// Common case.
|
|
if (typeof arg === 'number') {
|
|
if (typeof encodingOrOffset === 'string') {
|
|
throw new TypeError(
|
|
'The "string" argument must be of type string. Received type number'
|
|
)
|
|
}
|
|
return allocUnsafe(arg)
|
|
}
|
|
return from(arg, encodingOrOffset, length)
|
|
}
|
|
|
|
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
|
|
if (typeof Symbol !== 'undefined' && Symbol.species != null &&
|
|
Buffer[Symbol.species] === Buffer) {
|
|
Object.defineProperty(Buffer, Symbol.species, {
|
|
value: null,
|
|
configurable: true,
|
|
enumerable: false,
|
|
writable: false
|
|
})
|
|
}
|
|
|
|
Buffer.poolSize = 8192 // not used by this implementation
|
|
|
|
function from (value, encodingOrOffset, length) {
|
|
if (typeof value === 'string') {
|
|
return fromString(value, encodingOrOffset)
|
|
}
|
|
|
|
if (ArrayBuffer.isView(value)) {
|
|
return fromArrayLike(value)
|
|
}
|
|
|
|
if (value == null) {
|
|
throw TypeError(
|
|
'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
|
|
'or Array-like Object. Received type ' + (typeof value)
|
|
)
|
|
}
|
|
|
|
if (isInstance(value, ArrayBuffer) ||
|
|
(value && isInstance(value.buffer, ArrayBuffer))) {
|
|
return fromArrayBuffer(value, encodingOrOffset, length)
|
|
}
|
|
|
|
if (typeof value === 'number') {
|
|
throw new TypeError(
|
|
'The "value" argument must not be of type number. Received type number'
|
|
)
|
|
}
|
|
|
|
var valueOf = value.valueOf && value.valueOf()
|
|
if (valueOf != null && valueOf !== value) {
|
|
return Buffer.from(valueOf, encodingOrOffset, length)
|
|
}
|
|
|
|
var b = fromObject(value)
|
|
if (b) return b
|
|
|
|
if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
|
|
typeof value[Symbol.toPrimitive] === 'function') {
|
|
return Buffer.from(
|
|
value[Symbol.toPrimitive]('string'), encodingOrOffset, length
|
|
)
|
|
}
|
|
|
|
throw new TypeError(
|
|
'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
|
|
'or Array-like Object. Received type ' + (typeof 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(value, encodingOrOffset, length)
|
|
}
|
|
|
|
// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
|
|
// https://github.com/feross/buffer/pull/148
|
|
Buffer.prototype.__proto__ = Uint8Array.prototype
|
|
Buffer.__proto__ = Uint8Array
|
|
|
|
function assertSize (size) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('"size" argument must be of type number')
|
|
} else if (size < 0) {
|
|
throw new RangeError('The value "' + size + '" is invalid for option "size"')
|
|
}
|
|
}
|
|
|
|
function alloc (size, fill, encoding) {
|
|
assertSize(size)
|
|
if (size <= 0) {
|
|
return createBuffer(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(size).fill(fill, encoding)
|
|
: createBuffer(size).fill(fill)
|
|
}
|
|
return createBuffer(size)
|
|
}
|
|
|
|
/**
|
|
* Creates a new filled Buffer instance.
|
|
* alloc(size[, fill[, encoding]])
|
|
**/
|
|
Buffer.alloc = function (size, fill, encoding) {
|
|
return alloc(size, fill, encoding)
|
|
}
|
|
|
|
function allocUnsafe (size) {
|
|
assertSize(size)
|
|
return createBuffer(size < 0 ? 0 : checked(size) | 0)
|
|
}
|
|
|
|
/**
|
|
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
|
|
* */
|
|
Buffer.allocUnsafe = function (size) {
|
|
return allocUnsafe(size)
|
|
}
|
|
/**
|
|
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
|
|
*/
|
|
Buffer.allocUnsafeSlow = function (size) {
|
|
return allocUnsafe(size)
|
|
}
|
|
|
|
function fromString (string, encoding) {
|
|
if (typeof encoding !== 'string' || encoding === '') {
|
|
encoding = 'utf8'
|
|
}
|
|
|
|
if (!Buffer.isEncoding(encoding)) {
|
|
throw new TypeError('Unknown encoding: ' + encoding)
|
|
}
|
|
|
|
var length = byteLength(string, encoding) | 0
|
|
var buf = createBuffer(length)
|
|
|
|
var actual = buf.write(string, encoding)
|
|
|
|
if (actual !== length) {
|
|
// Writing a hex string, for example, that contains invalid characters will
|
|
// cause everything after the first invalid character to be ignored. (e.g.
|
|
// 'abxxcd' will be treated as 'ab')
|
|
buf = buf.slice(0, actual)
|
|
}
|
|
|
|
return buf
|
|
}
|
|
|
|
function fromArrayLike (array) {
|
|
var length = array.length < 0 ? 0 : checked(array.length) | 0
|
|
var buf = createBuffer(length)
|
|
for (var i = 0; i < length; i += 1) {
|
|
buf[i] = array[i] & 255
|
|
}
|
|
return buf
|
|
}
|
|
|
|
function fromArrayBuffer (array, byteOffset, length) {
|
|
if (byteOffset < 0 || array.byteLength < byteOffset) {
|
|
throw new RangeError('"offset" is outside of buffer bounds')
|
|
}
|
|
|
|
if (array.byteLength < byteOffset + (length || 0)) {
|
|
throw new RangeError('"length" is outside of buffer bounds')
|
|
}
|
|
|
|
var buf
|
|
if (byteOffset === undefined && length === undefined) {
|
|
buf = new Uint8Array(array)
|
|
} else if (length === undefined) {
|
|
buf = new Uint8Array(array, byteOffset)
|
|
} else {
|
|
buf = new Uint8Array(array, byteOffset, length)
|
|
}
|
|
|
|
// Return an augmented `Uint8Array` instance
|
|
buf.__proto__ = Buffer.prototype
|
|
return buf
|
|
}
|
|
|
|
function fromObject (obj) {
|
|
if (Buffer.isBuffer(obj)) {
|
|
var len = checked(obj.length) | 0
|
|
var buf = createBuffer(len)
|
|
|
|
if (buf.length === 0) {
|
|
return buf
|
|
}
|
|
|
|
obj.copy(buf, 0, 0, len)
|
|
return buf
|
|
}
|
|
|
|
if (obj.length !== undefined) {
|
|
if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
|
|
return createBuffer(0)
|
|
}
|
|
return fromArrayLike(obj)
|
|
}
|
|
|
|
if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
|
|
return fromArrayLike(obj.data)
|
|
}
|
|
}
|
|
|
|
function checked (length) {
|
|
// Note: cannot use `length < K_MAX_LENGTH` here because that fails when
|
|
// length is NaN (which is otherwise coerced to zero.)
|
|
if (length >= K_MAX_LENGTH) {
|
|
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
|
|
'size: 0x' + K_MAX_LENGTH.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 === true &&
|
|
b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
|
|
}
|
|
|
|
Buffer.compare = function compare (a, b) {
|
|
if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
|
|
if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
|
|
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
|
|
throw new TypeError(
|
|
'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
|
|
)
|
|
}
|
|
|
|
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 'latin1':
|
|
case 'binary':
|
|
case 'base64':
|
|
case 'ucs2':
|
|
case 'ucs-2':
|
|
case 'utf16le':
|
|
case 'utf-16le':
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
Buffer.concat = function concat (list, length) {
|
|
if (!Array.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 (isInstance(buf, Uint8Array)) {
|
|
buf = Buffer.from(buf)
|
|
}
|
|
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 (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
|
|
return string.byteLength
|
|
}
|
|
if (typeof string !== 'string') {
|
|
throw new TypeError(
|
|
'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
|
|
'Received type ' + typeof string
|
|
)
|
|
}
|
|
|
|
var len = string.length
|
|
var mustMatch = (arguments.length > 2 && arguments[2] === true)
|
|
if (!mustMatch && len === 0) return 0
|
|
|
|
// Use a for loop to avoid recursion
|
|
var loweredCase = false
|
|
for (;;) {
|
|
switch (encoding) {
|
|
case 'ascii':
|
|
case 'latin1':
|
|
case 'binary':
|
|
return len
|
|
case 'utf8':
|
|
case 'utf-8':
|
|
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 mustMatch ? -1 : 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 'latin1':
|
|
case 'binary':
|
|
return latin1Slice(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
|
|
}
|
|
}
|
|
}
|
|
|
|
// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
|
|
// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
|
|
// reliably in a browserify context because there could be multiple different
|
|
// copies of the 'buffer' package in use. This method works even for Buffer
|
|
// instances that were created from another copy of the `buffer` package.
|
|
// See: https://github.com/feross/buffer/issues/154
|
|
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.swap64 = function swap64 () {
|
|
var len = this.length
|
|
if (len % 8 !== 0) {
|
|
throw new RangeError('Buffer size must be a multiple of 64-bits')
|
|
}
|
|
for (var i = 0; i < len; i += 8) {
|
|
swap(this, i, i + 7)
|
|
swap(this, i + 1, i + 6)
|
|
swap(this, i + 2, i + 5)
|
|
swap(this, i + 3, i + 4)
|
|
}
|
|
return this
|
|
}
|
|
|
|
Buffer.prototype.toString = function toString () {
|
|
var length = this.length
|
|
if (length === 0) return ''
|
|
if (arguments.length === 0) return utf8Slice(this, 0, length)
|
|
return slowToString.apply(this, arguments)
|
|
}
|
|
|
|
Buffer.prototype.toLocaleString = Buffer.prototype.toString
|
|
|
|
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
|
|
str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
|
|
if (this.length > max) str += ' ... '
|
|
return '<Buffer ' + str + '>'
|
|
}
|
|
|
|
Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
|
|
if (isInstance(target, Uint8Array)) {
|
|
target = Buffer.from(target, target.offset, target.byteLength)
|
|
}
|
|
if (!Buffer.isBuffer(target)) {
|
|
throw new TypeError(
|
|
'The "target" argument must be one of type Buffer or Uint8Array. ' +
|
|
'Received type ' + (typeof target)
|
|
)
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
|
|
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
|
|
//
|
|
// Arguments:
|
|
// - buffer - a Buffer to search
|
|
// - val - a string, Buffer, or number
|
|
// - byteOffset - an index into `buffer`; will be clamped to an int32
|
|
// - encoding - an optional encoding, relevant is val is a string
|
|
// - dir - true for indexOf, false for lastIndexOf
|
|
function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
|
|
// Empty buffer means no match
|
|
if (buffer.length === 0) return -1
|
|
|
|
// Normalize byteOffset
|
|
if (typeof byteOffset === 'string') {
|
|
encoding = byteOffset
|
|
byteOffset = 0
|
|
} else if (byteOffset > 0x7fffffff) {
|
|
byteOffset = 0x7fffffff
|
|
} else if (byteOffset < -0x80000000) {
|
|
byteOffset = -0x80000000
|
|
}
|
|
byteOffset = +byteOffset // Coerce to Number.
|
|
if (numberIsNaN(byteOffset)) {
|
|
// byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
|
|
byteOffset = dir ? 0 : (buffer.length - 1)
|
|
}
|
|
|
|
// Normalize byteOffset: negative offsets start from the end of the buffer
|
|
if (byteOffset < 0) byteOffset = buffer.length + byteOffset
|
|
if (byteOffset >= buffer.length) {
|
|
if (dir) return -1
|
|
else byteOffset = buffer.length - 1
|
|
} else if (byteOffset < 0) {
|
|
if (dir) byteOffset = 0
|
|
else return -1
|
|
}
|
|
|
|
// Normalize val
|
|
if (typeof val === 'string') {
|
|
val = Buffer.from(val, encoding)
|
|
}
|
|
|
|
// Finally, search either indexOf (if dir is true) or lastIndexOf
|
|
if (Buffer.isBuffer(val)) {
|
|
// Special case: looking for empty string/buffer always fails
|
|
if (val.length === 0) {
|
|
return -1
|
|
}
|
|
return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
|
|
} else if (typeof val === 'number') {
|
|
val = val & 0xFF // Search for a byte value [0-255]
|
|
if (typeof Uint8Array.prototype.indexOf === 'function') {
|
|
if (dir) {
|
|
return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
|
|
} else {
|
|
return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
|
|
}
|
|
}
|
|
return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
|
|
}
|
|
|
|
throw new TypeError('val must be string, number or Buffer')
|
|
}
|
|
|
|
function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
|
|
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 i
|
|
if (dir) {
|
|
var foundIndex = -1
|
|
for (i = byteOffset; i < arrLength; i++) {
|
|
if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
|
|
if (foundIndex === -1) foundIndex = i
|
|
if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
|
|
} else {
|
|
if (foundIndex !== -1) i -= i - foundIndex
|
|
foundIndex = -1
|
|
}
|
|
}
|
|
} else {
|
|
if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
|
|
for (i = byteOffset; i >= 0; i--) {
|
|
var found = true
|
|
for (var j = 0; j < valLength; j++) {
|
|
if (read(arr, i + j) !== read(val, j)) {
|
|
found = false
|
|
break
|
|
}
|
|
}
|
|
if (found) return i
|
|
}
|
|
}
|
|
|
|
return -1
|
|
}
|
|
|
|
Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
|
|
return this.indexOf(val, byteOffset, encoding) !== -1
|
|
}
|
|
|
|
Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
|
|
return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
|
|
}
|
|
|
|
Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
|
|
return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
|
|
var strLen = string.length
|
|
|
|
if (length > strLen / 2) {
|
|
length = strLen / 2
|
|
}
|
|
for (var i = 0; i < length; ++i) {
|
|
var parsed = parseInt(string.substr(i * 2, 2), 16)
|
|
if (numberIsNaN(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 latin1Write (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
|
|
}
|
|
} 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 'latin1':
|
|
case 'binary':
|
|
return latin1Write(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 latin1Slice (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 = this.subarray(start, end)
|
|
// Return an augmented `Uint8Array` instance
|
|
newBuf.__proto__ = Buffer.prototype
|
|
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) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 1, this.length)
|
|
return this[offset]
|
|
}
|
|
|
|
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 2, this.length)
|
|
return this[offset] | (this[offset + 1] << 8)
|
|
}
|
|
|
|
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 2, this.length)
|
|
return (this[offset] << 8) | this[offset + 1]
|
|
}
|
|
|
|
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
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) {
|
|
offset = offset >>> 0
|
|
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) {
|
|
offset = offset >>> 0
|
|
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) {
|
|
offset = offset >>> 0
|
|
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) {
|
|
offset = offset >>> 0
|
|
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) {
|
|
offset = offset >>> 0
|
|
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) {
|
|
offset = offset >>> 0
|
|
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) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
return ieee754.read(this, offset, true, 23, 4)
|
|
}
|
|
|
|
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
return ieee754.read(this, offset, false, 23, 4)
|
|
}
|
|
|
|
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 8, this.length)
|
|
return ieee754.read(this, offset, true, 52, 8)
|
|
}
|
|
|
|
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
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)
|
|
this[offset] = (value & 0xff)
|
|
return offset + 1
|
|
}
|
|
|
|
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
|
|
this[offset] = (value & 0xff)
|
|
this[offset + 1] = (value >>> 8)
|
|
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)
|
|
this[offset] = (value >>> 8)
|
|
this[offset + 1] = (value & 0xff)
|
|
return offset + 2
|
|
}
|
|
|
|
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
|
|
this[offset + 3] = (value >>> 24)
|
|
this[offset + 2] = (value >>> 16)
|
|
this[offset + 1] = (value >>> 8)
|
|
this[offset] = (value & 0xff)
|
|
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)
|
|
this[offset] = (value >>> 24)
|
|
this[offset + 1] = (value >>> 16)
|
|
this[offset + 2] = (value >>> 8)
|
|
this[offset + 3] = (value & 0xff)
|
|
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 (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)
|
|
this[offset] = (value & 0xff)
|
|
this[offset + 1] = (value >>> 8)
|
|
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)
|
|
this[offset] = (value >>> 8)
|
|
this[offset + 1] = (value & 0xff)
|
|
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)
|
|
this[offset] = (value & 0xff)
|
|
this[offset + 1] = (value >>> 8)
|
|
this[offset + 2] = (value >>> 16)
|
|
this[offset + 3] = (value >>> 24)
|
|
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
|
|
this[offset] = (value >>> 24)
|
|
this[offset + 1] = (value >>> 16)
|
|
this[offset + 2] = (value >>> 8)
|
|
this[offset + 3] = (value & 0xff)
|
|
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) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
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) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
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 (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
|
|
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('Index out of range')
|
|
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
|
|
|
|
if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
|
|
// Use built-in when available, missing from IE11
|
|
this.copyWithin(targetStart, start, end)
|
|
} else if (this === target && start < targetStart && targetStart < end) {
|
|
// descending copy from end
|
|
for (var i = len - 1; i >= 0; --i) {
|
|
target[i + targetStart] = this[i + start]
|
|
}
|
|
} else {
|
|
Uint8Array.prototype.set.call(
|
|
target,
|
|
this.subarray(start, end),
|
|
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 (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)
|
|
}
|
|
if (val.length === 1) {
|
|
var code = val.charCodeAt(0)
|
|
if ((encoding === 'utf8' && code < 128) ||
|
|
encoding === 'latin1') {
|
|
// Fast path: If `val` fits into a single byte, use that numeric value.
|
|
val = code
|
|
}
|
|
}
|
|
} 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
|
|
: Buffer.from(val, encoding)
|
|
var len = bytes.length
|
|
if (len === 0) {
|
|
throw new TypeError('The value "' + val +
|
|
'" is invalid for argument "value"')
|
|
}
|
|
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 takes equal signs as end of the Base64 encoding
|
|
str = str.split('=')[0]
|
|
// Node strips out invalid characters like \n and \t from the string, base64-js does not
|
|
str = str.trim().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 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
|
|
}
|
|
|
|
// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
|
|
// the `instanceof` check but they should be treated as of that type.
|
|
// See: https://github.com/feross/buffer/issues/166
|
|
function isInstance (obj, type) {
|
|
return obj instanceof type ||
|
|
(obj != null && obj.constructor != null && obj.constructor.name != null &&
|
|
obj.constructor.name === type.name)
|
|
}
|
|
function numberIsNaN (obj) {
|
|
// For IE11 support
|
|
return obj !== obj // eslint-disable-line no-self-compare
|
|
}
|
|
|
|
}).call(this)}).call(this,require("buffer").Buffer)
|
|
|
|
},{"base64-js":1,"buffer":3,"ieee754":5}],4:[function(require,module,exports){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
'use strict';
|
|
|
|
var R = typeof Reflect === 'object' ? Reflect : null
|
|
var ReflectApply = R && typeof R.apply === 'function'
|
|
? R.apply
|
|
: function ReflectApply(target, receiver, args) {
|
|
return Function.prototype.apply.call(target, receiver, args);
|
|
}
|
|
|
|
var ReflectOwnKeys
|
|
if (R && typeof R.ownKeys === 'function') {
|
|
ReflectOwnKeys = R.ownKeys
|
|
} else if (Object.getOwnPropertySymbols) {
|
|
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
|
return Object.getOwnPropertyNames(target)
|
|
.concat(Object.getOwnPropertySymbols(target));
|
|
};
|
|
} else {
|
|
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
|
return Object.getOwnPropertyNames(target);
|
|
};
|
|
}
|
|
|
|
function ProcessEmitWarning(warning) {
|
|
if (console && console.warn) console.warn(warning);
|
|
}
|
|
|
|
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
|
|
return value !== value;
|
|
}
|
|
|
|
function EventEmitter() {
|
|
EventEmitter.init.call(this);
|
|
}
|
|
module.exports = EventEmitter;
|
|
module.exports.once = once;
|
|
|
|
// Backwards-compat with node 0.10.x
|
|
EventEmitter.EventEmitter = EventEmitter;
|
|
|
|
EventEmitter.prototype._events = undefined;
|
|
EventEmitter.prototype._eventsCount = 0;
|
|
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.
|
|
var defaultMaxListeners = 10;
|
|
|
|
function checkListener(listener) {
|
|
if (typeof listener !== 'function') {
|
|
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
|
|
enumerable: true,
|
|
get: function() {
|
|
return defaultMaxListeners;
|
|
},
|
|
set: function(arg) {
|
|
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
|
|
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
|
|
}
|
|
defaultMaxListeners = arg;
|
|
}
|
|
});
|
|
|
|
EventEmitter.init = function() {
|
|
|
|
if (this._events === undefined ||
|
|
this._events === Object.getPrototypeOf(this)._events) {
|
|
this._events = Object.create(null);
|
|
this._eventsCount = 0;
|
|
}
|
|
|
|
this._maxListeners = this._maxListeners || undefined;
|
|
};
|
|
|
|
// 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 setMaxListeners(n) {
|
|
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
|
|
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
|
|
}
|
|
this._maxListeners = n;
|
|
return this;
|
|
};
|
|
|
|
function _getMaxListeners(that) {
|
|
if (that._maxListeners === undefined)
|
|
return EventEmitter.defaultMaxListeners;
|
|
return that._maxListeners;
|
|
}
|
|
|
|
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
|
|
return _getMaxListeners(this);
|
|
};
|
|
|
|
EventEmitter.prototype.emit = function emit(type) {
|
|
var args = [];
|
|
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
|
|
var doError = (type === 'error');
|
|
|
|
var events = this._events;
|
|
if (events !== undefined)
|
|
doError = (doError && events.error === undefined);
|
|
else if (!doError)
|
|
return false;
|
|
|
|
// If there is no 'error' event listener then throw.
|
|
if (doError) {
|
|
var er;
|
|
if (args.length > 0)
|
|
er = args[0];
|
|
if (er instanceof Error) {
|
|
// Note: The comments on the `throw` lines are intentional, they show
|
|
// up in Node's output if this results in an unhandled exception.
|
|
throw er; // Unhandled 'error' event
|
|
}
|
|
// At least give some kind of context to the user
|
|
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
|
|
err.context = er;
|
|
throw err; // Unhandled 'error' event
|
|
}
|
|
|
|
var handler = events[type];
|
|
|
|
if (handler === undefined)
|
|
return false;
|
|
|
|
if (typeof handler === 'function') {
|
|
ReflectApply(handler, this, args);
|
|
} else {
|
|
var len = handler.length;
|
|
var listeners = arrayClone(handler, len);
|
|
for (var i = 0; i < len; ++i)
|
|
ReflectApply(listeners[i], this, args);
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
function _addListener(target, type, listener, prepend) {
|
|
var m;
|
|
var events;
|
|
var existing;
|
|
|
|
checkListener(listener);
|
|
|
|
events = target._events;
|
|
if (events === undefined) {
|
|
events = target._events = Object.create(null);
|
|
target._eventsCount = 0;
|
|
} else {
|
|
// To avoid recursion in the case that type === "newListener"! Before
|
|
// adding it to the listeners, first emit "newListener".
|
|
if (events.newListener !== undefined) {
|
|
target.emit('newListener', type,
|
|
listener.listener ? listener.listener : listener);
|
|
|
|
// Re-assign `events` because a newListener handler could have caused the
|
|
// this._events to be assigned to a new object
|
|
events = target._events;
|
|
}
|
|
existing = events[type];
|
|
}
|
|
|
|
if (existing === undefined) {
|
|
// Optimize the case of one listener. Don't need the extra array object.
|
|
existing = events[type] = listener;
|
|
++target._eventsCount;
|
|
} else {
|
|
if (typeof existing === 'function') {
|
|
// Adding the second element, need to change to array.
|
|
existing = events[type] =
|
|
prepend ? [listener, existing] : [existing, listener];
|
|
// If we've already got an array, just append.
|
|
} else if (prepend) {
|
|
existing.unshift(listener);
|
|
} else {
|
|
existing.push(listener);
|
|
}
|
|
|
|
// Check for listener leak
|
|
m = _getMaxListeners(target);
|
|
if (m > 0 && existing.length > m && !existing.warned) {
|
|
existing.warned = true;
|
|
// No error code for this since it is a Warning
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
var w = new Error('Possible EventEmitter memory leak detected. ' +
|
|
existing.length + ' ' + String(type) + ' listeners ' +
|
|
'added. Use emitter.setMaxListeners() to ' +
|
|
'increase limit');
|
|
w.name = 'MaxListenersExceededWarning';
|
|
w.emitter = target;
|
|
w.type = type;
|
|
w.count = existing.length;
|
|
ProcessEmitWarning(w);
|
|
}
|
|
}
|
|
|
|
return target;
|
|
}
|
|
|
|
EventEmitter.prototype.addListener = function addListener(type, listener) {
|
|
return _addListener(this, type, listener, false);
|
|
};
|
|
|
|
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
|
|
|
EventEmitter.prototype.prependListener =
|
|
function prependListener(type, listener) {
|
|
return _addListener(this, type, listener, true);
|
|
};
|
|
|
|
function onceWrapper() {
|
|
if (!this.fired) {
|
|
this.target.removeListener(this.type, this.wrapFn);
|
|
this.fired = true;
|
|
if (arguments.length === 0)
|
|
return this.listener.call(this.target);
|
|
return this.listener.apply(this.target, arguments);
|
|
}
|
|
}
|
|
|
|
function _onceWrap(target, type, listener) {
|
|
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
|
|
var wrapped = onceWrapper.bind(state);
|
|
wrapped.listener = listener;
|
|
state.wrapFn = wrapped;
|
|
return wrapped;
|
|
}
|
|
|
|
EventEmitter.prototype.once = function once(type, listener) {
|
|
checkListener(listener);
|
|
this.on(type, _onceWrap(this, type, listener));
|
|
return this;
|
|
};
|
|
|
|
EventEmitter.prototype.prependOnceListener =
|
|
function prependOnceListener(type, listener) {
|
|
checkListener(listener);
|
|
this.prependListener(type, _onceWrap(this, type, listener));
|
|
return this;
|
|
};
|
|
|
|
// Emits a 'removeListener' event if and only if the listener was removed.
|
|
EventEmitter.prototype.removeListener =
|
|
function removeListener(type, listener) {
|
|
var list, events, position, i, originalListener;
|
|
|
|
checkListener(listener);
|
|
|
|
events = this._events;
|
|
if (events === undefined)
|
|
return this;
|
|
|
|
list = events[type];
|
|
if (list === undefined)
|
|
return this;
|
|
|
|
if (list === listener || list.listener === listener) {
|
|
if (--this._eventsCount === 0)
|
|
this._events = Object.create(null);
|
|
else {
|
|
delete events[type];
|
|
if (events.removeListener)
|
|
this.emit('removeListener', type, list.listener || listener);
|
|
}
|
|
} else if (typeof list !== 'function') {
|
|
position = -1;
|
|
|
|
for (i = list.length - 1; i >= 0; i--) {
|
|
if (list[i] === listener || list[i].listener === listener) {
|
|
originalListener = list[i].listener;
|
|
position = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (position < 0)
|
|
return this;
|
|
|
|
if (position === 0)
|
|
list.shift();
|
|
else {
|
|
spliceOne(list, position);
|
|
}
|
|
|
|
if (list.length === 1)
|
|
events[type] = list[0];
|
|
|
|
if (events.removeListener !== undefined)
|
|
this.emit('removeListener', type, originalListener || listener);
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
|
|
|
EventEmitter.prototype.removeAllListeners =
|
|
function removeAllListeners(type) {
|
|
var listeners, events, i;
|
|
|
|
events = this._events;
|
|
if (events === undefined)
|
|
return this;
|
|
|
|
// not listening for removeListener, no need to emit
|
|
if (events.removeListener === undefined) {
|
|
if (arguments.length === 0) {
|
|
this._events = Object.create(null);
|
|
this._eventsCount = 0;
|
|
} else if (events[type] !== undefined) {
|
|
if (--this._eventsCount === 0)
|
|
this._events = Object.create(null);
|
|
else
|
|
delete events[type];
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// emit removeListener for all listeners on all events
|
|
if (arguments.length === 0) {
|
|
var keys = Object.keys(events);
|
|
var key;
|
|
for (i = 0; i < keys.length; ++i) {
|
|
key = keys[i];
|
|
if (key === 'removeListener') continue;
|
|
this.removeAllListeners(key);
|
|
}
|
|
this.removeAllListeners('removeListener');
|
|
this._events = Object.create(null);
|
|
this._eventsCount = 0;
|
|
return this;
|
|
}
|
|
|
|
listeners = events[type];
|
|
|
|
if (typeof listeners === 'function') {
|
|
this.removeListener(type, listeners);
|
|
} else if (listeners !== undefined) {
|
|
// LIFO order
|
|
for (i = listeners.length - 1; i >= 0; i--) {
|
|
this.removeListener(type, listeners[i]);
|
|
}
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
function _listeners(target, type, unwrap) {
|
|
var events = target._events;
|
|
|
|
if (events === undefined)
|
|
return [];
|
|
|
|
var evlistener = events[type];
|
|
if (evlistener === undefined)
|
|
return [];
|
|
|
|
if (typeof evlistener === 'function')
|
|
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
|
|
|
|
return unwrap ?
|
|
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
|
|
}
|
|
|
|
EventEmitter.prototype.listeners = function listeners(type) {
|
|
return _listeners(this, type, true);
|
|
};
|
|
|
|
EventEmitter.prototype.rawListeners = function rawListeners(type) {
|
|
return _listeners(this, type, false);
|
|
};
|
|
|
|
EventEmitter.listenerCount = function(emitter, type) {
|
|
if (typeof emitter.listenerCount === 'function') {
|
|
return emitter.listenerCount(type);
|
|
} else {
|
|
return listenerCount.call(emitter, type);
|
|
}
|
|
};
|
|
|
|
EventEmitter.prototype.listenerCount = listenerCount;
|
|
function listenerCount(type) {
|
|
var events = this._events;
|
|
|
|
if (events !== undefined) {
|
|
var evlistener = events[type];
|
|
|
|
if (typeof evlistener === 'function') {
|
|
return 1;
|
|
} else if (evlistener !== undefined) {
|
|
return evlistener.length;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
EventEmitter.prototype.eventNames = function eventNames() {
|
|
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
|
|
};
|
|
|
|
function arrayClone(arr, n) {
|
|
var copy = new Array(n);
|
|
for (var i = 0; i < n; ++i)
|
|
copy[i] = arr[i];
|
|
return copy;
|
|
}
|
|
|
|
function spliceOne(list, index) {
|
|
for (; index + 1 < list.length; index++)
|
|
list[index] = list[index + 1];
|
|
list.pop();
|
|
}
|
|
|
|
function unwrapListeners(arr) {
|
|
var ret = new Array(arr.length);
|
|
for (var i = 0; i < ret.length; ++i) {
|
|
ret[i] = arr[i].listener || arr[i];
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
function once(emitter, name) {
|
|
return new Promise(function (resolve, reject) {
|
|
function errorListener(err) {
|
|
emitter.removeListener(name, resolver);
|
|
reject(err);
|
|
}
|
|
|
|
function resolver() {
|
|
if (typeof emitter.removeListener === 'function') {
|
|
emitter.removeListener('error', errorListener);
|
|
}
|
|
resolve([].slice.call(arguments));
|
|
};
|
|
|
|
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
|
|
if (name !== 'error') {
|
|
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
|
|
}
|
|
});
|
|
}
|
|
|
|
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
|
|
if (typeof emitter.on === 'function') {
|
|
eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
|
|
}
|
|
}
|
|
|
|
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
|
|
if (typeof emitter.on === 'function') {
|
|
if (flags.once) {
|
|
emitter.once(name, listener);
|
|
} else {
|
|
emitter.on(name, listener);
|
|
}
|
|
} else if (typeof emitter.addEventListener === 'function') {
|
|
// EventTarget does not have `error` event semantics like Node
|
|
// EventEmitters, we do not listen for `error` events here.
|
|
emitter.addEventListener(name, function wrapListener(arg) {
|
|
// IE does not have builtin `{ once: true }` support so we
|
|
// have to do it manually.
|
|
if (flags.once) {
|
|
emitter.removeEventListener(name, wrapListener);
|
|
}
|
|
listener(arg);
|
|
});
|
|
} else {
|
|
throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
|
|
}
|
|
}
|
|
|
|
},{}],5:[function(require,module,exports){
|
|
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
|
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
|
|
}
|
|
|
|
},{}],6:[function(require,module,exports){
|
|
if (typeof Object.create === 'function') {
|
|
// implementation from standard node.js 'util' module
|
|
module.exports = function inherits(ctor, superCtor) {
|
|
if (superCtor) {
|
|
ctor.super_ = superCtor
|
|
ctor.prototype = Object.create(superCtor.prototype, {
|
|
constructor: {
|
|
value: ctor,
|
|
enumerable: false,
|
|
writable: true,
|
|
configurable: true
|
|
}
|
|
})
|
|
}
|
|
};
|
|
} else {
|
|
// old school shim for old browsers
|
|
module.exports = function inherits(ctor, superCtor) {
|
|
if (superCtor) {
|
|
ctor.super_ = superCtor
|
|
var TempCtor = function () {}
|
|
TempCtor.prototype = superCtor.prototype
|
|
ctor.prototype = new TempCtor()
|
|
ctor.prototype.constructor = ctor
|
|
}
|
|
}
|
|
}
|
|
|
|
},{}],7:[function(require,module,exports){
|
|
// shim for using process in browser
|
|
var process = module.exports = {};
|
|
|
|
// cached from whatever global is present so that test runners that stub it
|
|
// don't break things. But we need to wrap it in a try catch in case it is
|
|
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
|
// function because try/catches deoptimize in certain engines.
|
|
|
|
var cachedSetTimeout;
|
|
var cachedClearTimeout;
|
|
|
|
function defaultSetTimout() {
|
|
throw new Error('setTimeout has not been defined');
|
|
}
|
|
function defaultClearTimeout () {
|
|
throw new Error('clearTimeout has not been defined');
|
|
}
|
|
(function () {
|
|
try {
|
|
if (typeof setTimeout === 'function') {
|
|
cachedSetTimeout = setTimeout;
|
|
} else {
|
|
cachedSetTimeout = defaultSetTimout;
|
|
}
|
|
} catch (e) {
|
|
cachedSetTimeout = defaultSetTimout;
|
|
}
|
|
try {
|
|
if (typeof clearTimeout === 'function') {
|
|
cachedClearTimeout = clearTimeout;
|
|
} else {
|
|
cachedClearTimeout = defaultClearTimeout;
|
|
}
|
|
} catch (e) {
|
|
cachedClearTimeout = defaultClearTimeout;
|
|
}
|
|
} ())
|
|
function runTimeout(fun) {
|
|
if (cachedSetTimeout === setTimeout) {
|
|
//normal enviroments in sane situations
|
|
return setTimeout(fun, 0);
|
|
}
|
|
// if setTimeout wasn't available but was latter defined
|
|
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
|
|
cachedSetTimeout = setTimeout;
|
|
return setTimeout(fun, 0);
|
|
}
|
|
try {
|
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
return cachedSetTimeout(fun, 0);
|
|
} catch(e){
|
|
try {
|
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
return cachedSetTimeout.call(null, fun, 0);
|
|
} catch(e){
|
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
|
|
return cachedSetTimeout.call(this, fun, 0);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
function runClearTimeout(marker) {
|
|
if (cachedClearTimeout === clearTimeout) {
|
|
//normal enviroments in sane situations
|
|
return clearTimeout(marker);
|
|
}
|
|
// if clearTimeout wasn't available but was latter defined
|
|
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
|
|
cachedClearTimeout = clearTimeout;
|
|
return clearTimeout(marker);
|
|
}
|
|
try {
|
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
return cachedClearTimeout(marker);
|
|
} catch (e){
|
|
try {
|
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
return cachedClearTimeout.call(null, marker);
|
|
} catch (e){
|
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
|
|
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|
return cachedClearTimeout.call(this, marker);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
var queue = [];
|
|
var draining = false;
|
|
var currentQueue;
|
|
var queueIndex = -1;
|
|
|
|
function cleanUpNextTick() {
|
|
if (!draining || !currentQueue) {
|
|
return;
|
|
}
|
|
draining = false;
|
|
if (currentQueue.length) {
|
|
queue = currentQueue.concat(queue);
|
|
} else {
|
|
queueIndex = -1;
|
|
}
|
|
if (queue.length) {
|
|
drainQueue();
|
|
}
|
|
}
|
|
|
|
function drainQueue() {
|
|
if (draining) {
|
|
return;
|
|
}
|
|
var timeout = runTimeout(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;
|
|
runClearTimeout(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) {
|
|
runTimeout(drainQueue);
|
|
}
|
|
};
|
|
|
|
// 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.prependListener = noop;
|
|
process.prependOnceListener = noop;
|
|
|
|
process.listeners = function (name) { return [] }
|
|
|
|
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; };
|
|
|
|
},{}],8:[function(require,module,exports){
|
|
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
|
/* eslint-disable node/no-deprecated-api */
|
|
var buffer = require('buffer')
|
|
var Buffer = buffer.Buffer
|
|
|
|
// alternative to using Object.keys for old browsers
|
|
function copyProps (src, dst) {
|
|
for (var key in src) {
|
|
dst[key] = src[key]
|
|
}
|
|
}
|
|
if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
|
|
module.exports = buffer
|
|
} else {
|
|
// Copy properties from require('buffer')
|
|
copyProps(buffer, exports)
|
|
exports.Buffer = SafeBuffer
|
|
}
|
|
|
|
function SafeBuffer (arg, encodingOrOffset, length) {
|
|
return Buffer(arg, encodingOrOffset, length)
|
|
}
|
|
|
|
SafeBuffer.prototype = Object.create(Buffer.prototype)
|
|
|
|
// Copy static methods from Buffer
|
|
copyProps(Buffer, SafeBuffer)
|
|
|
|
SafeBuffer.from = function (arg, encodingOrOffset, length) {
|
|
if (typeof arg === 'number') {
|
|
throw new TypeError('Argument must not be a number')
|
|
}
|
|
return Buffer(arg, encodingOrOffset, length)
|
|
}
|
|
|
|
SafeBuffer.alloc = function (size, fill, encoding) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('Argument must be a number')
|
|
}
|
|
var buf = Buffer(size)
|
|
if (fill !== undefined) {
|
|
if (typeof encoding === 'string') {
|
|
buf.fill(fill, encoding)
|
|
} else {
|
|
buf.fill(fill)
|
|
}
|
|
} else {
|
|
buf.fill(0)
|
|
}
|
|
return buf
|
|
}
|
|
|
|
SafeBuffer.allocUnsafe = function (size) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('Argument must be a number')
|
|
}
|
|
return Buffer(size)
|
|
}
|
|
|
|
SafeBuffer.allocUnsafeSlow = function (size) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('Argument must be a number')
|
|
}
|
|
return buffer.SlowBuffer(size)
|
|
}
|
|
|
|
},{"buffer":3}],9:[function(require,module,exports){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
module.exports = Stream;
|
|
|
|
var EE = require('events').EventEmitter;
|
|
var inherits = require('inherits');
|
|
|
|
inherits(Stream, EE);
|
|
Stream.Readable = require('readable-stream/lib/_stream_readable.js');
|
|
Stream.Writable = require('readable-stream/lib/_stream_writable.js');
|
|
Stream.Duplex = require('readable-stream/lib/_stream_duplex.js');
|
|
Stream.Transform = require('readable-stream/lib/_stream_transform.js');
|
|
Stream.PassThrough = require('readable-stream/lib/_stream_passthrough.js');
|
|
Stream.finished = require('readable-stream/lib/internal/streams/end-of-stream.js')
|
|
Stream.pipeline = require('readable-stream/lib/internal/streams/pipeline.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":4,"inherits":6,"readable-stream/lib/_stream_duplex.js":11,"readable-stream/lib/_stream_passthrough.js":12,"readable-stream/lib/_stream_readable.js":13,"readable-stream/lib/_stream_transform.js":14,"readable-stream/lib/_stream_writable.js":15,"readable-stream/lib/internal/streams/end-of-stream.js":19,"readable-stream/lib/internal/streams/pipeline.js":21}],10:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
|
|
|
|
var codes = {};
|
|
|
|
function createErrorType(code, message, Base) {
|
|
if (!Base) {
|
|
Base = Error;
|
|
}
|
|
|
|
function getMessage(arg1, arg2, arg3) {
|
|
if (typeof message === 'string') {
|
|
return message;
|
|
} else {
|
|
return message(arg1, arg2, arg3);
|
|
}
|
|
}
|
|
|
|
var NodeError =
|
|
/*#__PURE__*/
|
|
function (_Base) {
|
|
_inheritsLoose(NodeError, _Base);
|
|
|
|
function NodeError(arg1, arg2, arg3) {
|
|
return _Base.call(this, getMessage(arg1, arg2, arg3)) || this;
|
|
}
|
|
|
|
return NodeError;
|
|
}(Base);
|
|
|
|
NodeError.prototype.name = Base.name;
|
|
NodeError.prototype.code = code;
|
|
codes[code] = NodeError;
|
|
} // https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js
|
|
|
|
|
|
function oneOf(expected, thing) {
|
|
if (Array.isArray(expected)) {
|
|
var len = expected.length;
|
|
expected = expected.map(function (i) {
|
|
return String(i);
|
|
});
|
|
|
|
if (len > 2) {
|
|
return "one of ".concat(thing, " ").concat(expected.slice(0, len - 1).join(', '), ", or ") + expected[len - 1];
|
|
} else if (len === 2) {
|
|
return "one of ".concat(thing, " ").concat(expected[0], " or ").concat(expected[1]);
|
|
} else {
|
|
return "of ".concat(thing, " ").concat(expected[0]);
|
|
}
|
|
} else {
|
|
return "of ".concat(thing, " ").concat(String(expected));
|
|
}
|
|
} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
|
|
|
|
|
|
function startsWith(str, search, pos) {
|
|
return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
|
|
} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
|
|
|
|
|
|
function endsWith(str, search, this_len) {
|
|
if (this_len === undefined || this_len > str.length) {
|
|
this_len = str.length;
|
|
}
|
|
|
|
return str.substring(this_len - search.length, this_len) === search;
|
|
} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes
|
|
|
|
|
|
function includes(str, search, start) {
|
|
if (typeof start !== 'number') {
|
|
start = 0;
|
|
}
|
|
|
|
if (start + search.length > str.length) {
|
|
return false;
|
|
} else {
|
|
return str.indexOf(search, start) !== -1;
|
|
}
|
|
}
|
|
|
|
createErrorType('ERR_INVALID_OPT_VALUE', function (name, value) {
|
|
return 'The value "' + value + '" is invalid for option "' + name + '"';
|
|
}, TypeError);
|
|
createErrorType('ERR_INVALID_ARG_TYPE', function (name, expected, actual) {
|
|
// determiner: 'must be' or 'must not be'
|
|
var determiner;
|
|
|
|
if (typeof expected === 'string' && startsWith(expected, 'not ')) {
|
|
determiner = 'must not be';
|
|
expected = expected.replace(/^not /, '');
|
|
} else {
|
|
determiner = 'must be';
|
|
}
|
|
|
|
var msg;
|
|
|
|
if (endsWith(name, ' argument')) {
|
|
// For cases like 'first argument'
|
|
msg = "The ".concat(name, " ").concat(determiner, " ").concat(oneOf(expected, 'type'));
|
|
} else {
|
|
var type = includes(name, '.') ? 'property' : 'argument';
|
|
msg = "The \"".concat(name, "\" ").concat(type, " ").concat(determiner, " ").concat(oneOf(expected, 'type'));
|
|
}
|
|
|
|
msg += ". Received type ".concat(typeof actual);
|
|
return msg;
|
|
}, TypeError);
|
|
createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF');
|
|
createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (name) {
|
|
return 'The ' + name + ' method is not implemented';
|
|
});
|
|
createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close');
|
|
createErrorType('ERR_STREAM_DESTROYED', function (name) {
|
|
return 'Cannot call ' + name + ' after a stream was destroyed';
|
|
});
|
|
createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times');
|
|
createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable');
|
|
createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end');
|
|
createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError);
|
|
createErrorType('ERR_UNKNOWN_ENCODING', function (arg) {
|
|
return 'Unknown encoding: ' + arg;
|
|
}, TypeError);
|
|
createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event');
|
|
module.exports.codes = codes;
|
|
|
|
},{}],11:[function(require,module,exports){
|
|
(function (process){(function (){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
// a duplex stream is just a stream that is both readable and writable.
|
|
// Since JS doesn't have multiple prototypal inheritance, this class
|
|
// prototypally inherits from Readable, and then parasitically from
|
|
// Writable.
|
|
'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;
|
|
|
|
var Readable = require('./_stream_readable');
|
|
|
|
var Writable = require('./_stream_writable');
|
|
|
|
require('inherits')(Duplex, Readable);
|
|
|
|
{
|
|
// Allow the keys array to be GC'ed.
|
|
var keys = objectKeys(Writable.prototype);
|
|
|
|
for (var v = 0; v < keys.length; v++) {
|
|
var method = keys[v];
|
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
}
|
|
}
|
|
|
|
function Duplex(options) {
|
|
if (!(this instanceof Duplex)) return new Duplex(options);
|
|
Readable.call(this, options);
|
|
Writable.call(this, options);
|
|
this.allowHalfOpen = true;
|
|
|
|
if (options) {
|
|
if (options.readable === false) this.readable = false;
|
|
if (options.writable === false) this.writable = false;
|
|
|
|
if (options.allowHalfOpen === false) {
|
|
this.allowHalfOpen = false;
|
|
this.once('end', onend);
|
|
}
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
return this._writableState.highWaterMark;
|
|
}
|
|
});
|
|
Object.defineProperty(Duplex.prototype, 'writableBuffer', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
return this._writableState && this._writableState.getBuffer();
|
|
}
|
|
});
|
|
Object.defineProperty(Duplex.prototype, 'writableLength', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
return this._writableState.length;
|
|
}
|
|
}); // the no-half-open enforcer
|
|
|
|
function onend() {
|
|
// If the writable side ended, then we're ok.
|
|
if (this._writableState.ended) return; // no more data can be written.
|
|
// But allow more writes to happen in this tick.
|
|
|
|
process.nextTick(onEndNT, this);
|
|
}
|
|
|
|
function onEndNT(self) {
|
|
self.end();
|
|
}
|
|
|
|
Object.defineProperty(Duplex.prototype, 'destroyed', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
if (this._readableState === undefined || this._writableState === undefined) {
|
|
return false;
|
|
}
|
|
|
|
return this._readableState.destroyed && this._writableState.destroyed;
|
|
},
|
|
set: function set(value) {
|
|
// we ignore the value if the stream
|
|
// has not been initialized yet
|
|
if (this._readableState === undefined || this._writableState === undefined) {
|
|
return;
|
|
} // backward compatibility, the user is explicitly
|
|
// managing destroyed
|
|
|
|
|
|
this._readableState.destroyed = value;
|
|
this._writableState.destroyed = value;
|
|
}
|
|
});
|
|
}).call(this)}).call(this,require('_process'))
|
|
|
|
},{"./_stream_readable":13,"./_stream_writable":15,"_process":7,"inherits":6}],12:[function(require,module,exports){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
// a 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');
|
|
|
|
require('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":14,"inherits":6}],13:[function(require,module,exports){
|
|
(function (process,global){(function (){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
'use strict';
|
|
|
|
module.exports = Readable;
|
|
/*<replacement>*/
|
|
|
|
var Duplex;
|
|
/*</replacement>*/
|
|
|
|
Readable.ReadableState = ReadableState;
|
|
/*<replacement>*/
|
|
|
|
var EE = require('events').EventEmitter;
|
|
|
|
var EElistenerCount = function EElistenerCount(emitter, type) {
|
|
return emitter.listeners(type).length;
|
|
};
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
|
|
|
|
var Stream = require('./internal/streams/stream');
|
|
/*</replacement>*/
|
|
|
|
|
|
var Buffer = require('buffer').Buffer;
|
|
|
|
var OurUint8Array = global.Uint8Array || function () {};
|
|
|
|
function _uint8ArrayToBuffer(chunk) {
|
|
return Buffer.from(chunk);
|
|
}
|
|
|
|
function _isUint8Array(obj) {
|
|
return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
|
|
}
|
|
/*<replacement>*/
|
|
|
|
|
|
var debugUtil = require('util');
|
|
|
|
var debug;
|
|
|
|
if (debugUtil && debugUtil.debuglog) {
|
|
debug = debugUtil.debuglog('stream');
|
|
} else {
|
|
debug = function debug() {};
|
|
}
|
|
/*</replacement>*/
|
|
|
|
|
|
var BufferList = require('./internal/streams/buffer_list');
|
|
|
|
var destroyImpl = require('./internal/streams/destroy');
|
|
|
|
var _require = require('./internal/streams/state'),
|
|
getHighWaterMark = _require.getHighWaterMark;
|
|
|
|
var _require$codes = require('../errors').codes,
|
|
ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
|
|
ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF,
|
|
ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
|
|
ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT; // Lazy loaded to improve the startup performance.
|
|
|
|
|
|
var StringDecoder;
|
|
var createReadableStreamAsyncIterator;
|
|
var from;
|
|
|
|
require('inherits')(Readable, Stream);
|
|
|
|
var errorOrDestroy = destroyImpl.errorOrDestroy;
|
|
var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
|
|
|
|
function prependListener(emitter, event, fn) {
|
|
// Sadly this is not cacheable as some libraries bundle their own
|
|
// event emitter implementation with them.
|
|
if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); // This is a hack to make sure that our error handler is attached before any
|
|
// userland ones. NEVER DO THIS. This is here only because this code needs
|
|
// to continue to work with older versions of Node.js that do not include
|
|
// the prependListener() method. The goal is to eventually remove this hack.
|
|
|
|
if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
|
|
}
|
|
|
|
function ReadableState(options, stream, isDuplex) {
|
|
Duplex = Duplex || require('./_stream_duplex');
|
|
options = options || {}; // Duplex streams are both readable and writable, but share
|
|
// the same options object.
|
|
// However, some cases require setting options to different
|
|
// values for the readable and the writable sides of the duplex stream.
|
|
// These options can be provided separately as readableXXX and writableXXX.
|
|
|
|
if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag. Used to make read(n) ignore n and to
|
|
// make all the buffer merging and length checks go away
|
|
|
|
this.objectMode = !!options.objectMode;
|
|
if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; // the point at which it stops calling _read() to fill the buffer
|
|
// Note: 0 is a valid value, means "don't call _read preemptively ever"
|
|
|
|
this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex); // A linked list is used to store data chunks instead of an array because the
|
|
// linked list can remove elements from the beginning faster than
|
|
// array.shift()
|
|
|
|
this.buffer = new BufferList();
|
|
this.length = 0;
|
|
this.pipes = null;
|
|
this.pipesCount = 0;
|
|
this.flowing = null;
|
|
this.ended = false;
|
|
this.endEmitted = false;
|
|
this.reading = false; // a flag to be able to tell if the event 'readable'/'data' is emitted
|
|
// immediately, or on a later tick. We set this to true at first, because
|
|
// any actions that shouldn't happen until "later" should generally also
|
|
// not happen before the first read call.
|
|
|
|
this.sync = true; // whenever we return null, then we set a flag to say
|
|
// that we're awaiting a 'readable' event emission.
|
|
|
|
this.needReadable = false;
|
|
this.emittedReadable = false;
|
|
this.readableListening = false;
|
|
this.resumeScheduled = false;
|
|
this.paused = true; // Should close be emitted on destroy. Defaults to true.
|
|
|
|
this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'end' (and potentially 'finish')
|
|
|
|
this.autoDestroy = !!options.autoDestroy; // has it been destroyed
|
|
|
|
this.destroyed = false; // Crypto is kind of old and crusty. Historically, its default string
|
|
// encoding is 'binary' so we have to make this configurable.
|
|
// Everything else in the universe uses 'utf8', though.
|
|
|
|
this.defaultEncoding = options.defaultEncoding || 'utf8'; // the number of writers that are awaiting a drain event in .pipe()s
|
|
|
|
this.awaitDrain = 0; // if true, a maybeReadMore has been scheduled
|
|
|
|
this.readingMore = false;
|
|
this.decoder = null;
|
|
this.encoding = null;
|
|
|
|
if (options.encoding) {
|
|
if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
|
|
this.decoder = new StringDecoder(options.encoding);
|
|
this.encoding = options.encoding;
|
|
}
|
|
}
|
|
|
|
function Readable(options) {
|
|
Duplex = Duplex || require('./_stream_duplex');
|
|
if (!(this instanceof Readable)) return new Readable(options); // Checking for a Stream.Duplex instance is faster here instead of inside
|
|
// the ReadableState constructor, at least with V8 6.5
|
|
|
|
var isDuplex = this instanceof Duplex;
|
|
this._readableState = new ReadableState(options, this, isDuplex); // legacy
|
|
|
|
this.readable = true;
|
|
|
|
if (options) {
|
|
if (typeof options.read === 'function') this._read = options.read;
|
|
if (typeof options.destroy === 'function') this._destroy = options.destroy;
|
|
}
|
|
|
|
Stream.call(this);
|
|
}
|
|
|
|
Object.defineProperty(Readable.prototype, 'destroyed', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
if (this._readableState === undefined) {
|
|
return false;
|
|
}
|
|
|
|
return this._readableState.destroyed;
|
|
},
|
|
set: function set(value) {
|
|
// we ignore the value if the stream
|
|
// has not been initialized yet
|
|
if (!this._readableState) {
|
|
return;
|
|
} // backward compatibility, the user is explicitly
|
|
// managing destroyed
|
|
|
|
|
|
this._readableState.destroyed = value;
|
|
}
|
|
});
|
|
Readable.prototype.destroy = destroyImpl.destroy;
|
|
Readable.prototype._undestroy = destroyImpl.undestroy;
|
|
|
|
Readable.prototype._destroy = function (err, cb) {
|
|
cb(err);
|
|
}; // Manually shove something into the read() buffer.
|
|
// This returns true if the highWaterMark has not been hit yet,
|
|
// similar to how Writable.write() returns true if you should
|
|
// write() some more.
|
|
|
|
|
|
Readable.prototype.push = function (chunk, encoding) {
|
|
var state = this._readableState;
|
|
var skipChunkCheck;
|
|
|
|
if (!state.objectMode) {
|
|
if (typeof chunk === 'string') {
|
|
encoding = encoding || state.defaultEncoding;
|
|
|
|
if (encoding !== state.encoding) {
|
|
chunk = Buffer.from(chunk, encoding);
|
|
encoding = '';
|
|
}
|
|
|
|
skipChunkCheck = true;
|
|
}
|
|
} else {
|
|
skipChunkCheck = true;
|
|
}
|
|
|
|
return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
|
|
}; // Unshift should *always* be something directly out of read()
|
|
|
|
|
|
Readable.prototype.unshift = function (chunk) {
|
|
return readableAddChunk(this, chunk, null, true, false);
|
|
};
|
|
|
|
function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
|
|
debug('readableAddChunk', chunk);
|
|
var state = stream._readableState;
|
|
|
|
if (chunk === null) {
|
|
state.reading = false;
|
|
onEofChunk(stream, state);
|
|
} else {
|
|
var er;
|
|
if (!skipChunkCheck) er = chunkInvalid(state, chunk);
|
|
|
|
if (er) {
|
|
errorOrDestroy(stream, er);
|
|
} else if (state.objectMode || chunk && chunk.length > 0) {
|
|
if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) {
|
|
chunk = _uint8ArrayToBuffer(chunk);
|
|
}
|
|
|
|
if (addToFront) {
|
|
if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true);
|
|
} else if (state.ended) {
|
|
errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF());
|
|
} else if (state.destroyed) {
|
|
return false;
|
|
} else {
|
|
state.reading = false;
|
|
|
|
if (state.decoder && !encoding) {
|
|
chunk = state.decoder.write(chunk);
|
|
if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
|
|
} else {
|
|
addChunk(stream, state, chunk, false);
|
|
}
|
|
}
|
|
} else if (!addToFront) {
|
|
state.reading = false;
|
|
maybeReadMore(stream, state);
|
|
}
|
|
} // We can push more data if we are below the highWaterMark.
|
|
// Also, if we have no data yet, we can stand some more bytes.
|
|
// This is to work around cases where hwm=0, such as the repl.
|
|
|
|
|
|
return !state.ended && (state.length < state.highWaterMark || state.length === 0);
|
|
}
|
|
|
|
function addChunk(stream, state, chunk, addToFront) {
|
|
if (state.flowing && state.length === 0 && !state.sync) {
|
|
state.awaitDrain = 0;
|
|
stream.emit('data', chunk);
|
|
} else {
|
|
// update the buffer info.
|
|
state.length += state.objectMode ? 1 : chunk.length;
|
|
if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
|
|
if (state.needReadable) emitReadable(stream);
|
|
}
|
|
|
|
maybeReadMore(stream, state);
|
|
}
|
|
|
|
function chunkInvalid(state, chunk) {
|
|
var er;
|
|
|
|
if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
|
|
er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk);
|
|
}
|
|
|
|
return er;
|
|
}
|
|
|
|
Readable.prototype.isPaused = function () {
|
|
return this._readableState.flowing === false;
|
|
}; // backwards compatibility.
|
|
|
|
|
|
Readable.prototype.setEncoding = function (enc) {
|
|
if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
|
|
var decoder = new StringDecoder(enc);
|
|
this._readableState.decoder = decoder; // If setEncoding(null), decoder.encoding equals utf8
|
|
|
|
this._readableState.encoding = this._readableState.decoder.encoding; // Iterate over current buffer to convert already stored Buffers:
|
|
|
|
var p = this._readableState.buffer.head;
|
|
var content = '';
|
|
|
|
while (p !== null) {
|
|
content += decoder.write(p.data);
|
|
p = p.next;
|
|
}
|
|
|
|
this._readableState.buffer.clear();
|
|
|
|
if (content !== '') this._readableState.buffer.push(content);
|
|
this._readableState.length = content.length;
|
|
return this;
|
|
}; // Don't raise the hwm > 1GB
|
|
|
|
|
|
var MAX_HWM = 0x40000000;
|
|
|
|
function computeNewHighWaterMark(n) {
|
|
if (n >= MAX_HWM) {
|
|
// TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE.
|
|
n = MAX_HWM;
|
|
} else {
|
|
// Get the next highest power of 2 to prevent increasing hwm excessively in
|
|
// tiny amounts
|
|
n--;
|
|
n |= n >>> 1;
|
|
n |= n >>> 2;
|
|
n |= n >>> 4;
|
|
n |= n >>> 8;
|
|
n |= n >>> 16;
|
|
n++;
|
|
}
|
|
|
|
return n;
|
|
} // This function is designed to be inlinable, so please take care when making
|
|
// changes to the function body.
|
|
|
|
|
|
function howMuchToRead(n, state) {
|
|
if (n <= 0 || state.length === 0 && state.ended) return 0;
|
|
if (state.objectMode) return 1;
|
|
|
|
if (n !== n) {
|
|
// Only flow one buffer at a time
|
|
if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
|
|
} // If we're asking for more than the current hwm, then raise the hwm.
|
|
|
|
|
|
if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
|
|
if (n <= state.length) return n; // Don't have enough
|
|
|
|
if (!state.ended) {
|
|
state.needReadable = true;
|
|
return 0;
|
|
}
|
|
|
|
return state.length;
|
|
} // you can override either this method, or the async _read(n) below.
|
|
|
|
|
|
Readable.prototype.read = function (n) {
|
|
debug('read', n);
|
|
n = parseInt(n, 10);
|
|
var state = this._readableState;
|
|
var nOrig = n;
|
|
if (n !== 0) state.emittedReadable = false; // if we're doing read(0) to trigger a readable event, but we
|
|
// already have a bunch of data in the buffer, then just trigger
|
|
// the 'readable' event and move on.
|
|
|
|
if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) {
|
|
debug('read: emitReadable', state.length, state.ended);
|
|
if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
|
|
return null;
|
|
}
|
|
|
|
n = howMuchToRead(n, state); // if we've ended, and we're now clear, then finish it up.
|
|
|
|
if (n === 0 && state.ended) {
|
|
if (state.length === 0) endReadable(this);
|
|
return null;
|
|
} // All the actual chunk generation logic needs to be
|
|
// *below* the call to _read. The reason is that in certain
|
|
// synthetic stream cases, such as passthrough streams, _read
|
|
// may be a completely synchronous operation which may change
|
|
// the state of the read buffer, providing enough data when
|
|
// before there was *not* enough.
|
|
//
|
|
// So, the steps are:
|
|
// 1. Figure out what the state of things will be after we do
|
|
// a read from the buffer.
|
|
//
|
|
// 2. If that resulting state will trigger a _read, then call _read.
|
|
// Note that this may be asynchronous, or synchronous. Yes, it is
|
|
// deeply ugly to write APIs this way, but that still doesn't mean
|
|
// that the Readable class should behave improperly, as streams are
|
|
// designed to be sync/async agnostic.
|
|
// Take note if the _read call is sync or async (ie, if the read call
|
|
// has returned yet), so that we know whether or not it's safe to emit
|
|
// 'readable' etc.
|
|
//
|
|
// 3. Actually pull the requested chunks out of the buffer and return.
|
|
// if we need a readable event, then we need to do some reading.
|
|
|
|
|
|
var doRead = state.needReadable;
|
|
debug('need readable', doRead); // if we currently have less than the highWaterMark, then also read some
|
|
|
|
if (state.length === 0 || state.length - n < state.highWaterMark) {
|
|
doRead = true;
|
|
debug('length less than watermark', doRead);
|
|
} // however, if we've ended, then there's no point, and if we're already
|
|
// reading, then it's unnecessary.
|
|
|
|
|
|
if (state.ended || state.reading) {
|
|
doRead = false;
|
|
debug('reading or ended', doRead);
|
|
} else if (doRead) {
|
|
debug('do read');
|
|
state.reading = true;
|
|
state.sync = true; // if the length is currently zero, then we *need* a readable event.
|
|
|
|
if (state.length === 0) state.needReadable = true; // call internal read method
|
|
|
|
this._read(state.highWaterMark);
|
|
|
|
state.sync = false; // If _read pushed data synchronously, then `reading` will be false,
|
|
// and we need to re-evaluate how much data we can return to the user.
|
|
|
|
if (!state.reading) n = howMuchToRead(nOrig, state);
|
|
}
|
|
|
|
var ret;
|
|
if (n > 0) ret = fromList(n, state);else ret = null;
|
|
|
|
if (ret === null) {
|
|
state.needReadable = state.length <= state.highWaterMark;
|
|
n = 0;
|
|
} else {
|
|
state.length -= n;
|
|
state.awaitDrain = 0;
|
|
}
|
|
|
|
if (state.length === 0) {
|
|
// If we have nothing in the buffer, then we want to know
|
|
// as soon as we *do* get something into the buffer.
|
|
if (!state.ended) state.needReadable = true; // If we tried to read() past the EOF, then emit end on the next tick.
|
|
|
|
if (nOrig !== n && state.ended) endReadable(this);
|
|
}
|
|
|
|
if (ret !== null) this.emit('data', ret);
|
|
return ret;
|
|
};
|
|
|
|
function onEofChunk(stream, state) {
|
|
debug('onEofChunk');
|
|
if (state.ended) return;
|
|
|
|
if (state.decoder) {
|
|
var chunk = state.decoder.end();
|
|
|
|
if (chunk && chunk.length) {
|
|
state.buffer.push(chunk);
|
|
state.length += state.objectMode ? 1 : chunk.length;
|
|
}
|
|
}
|
|
|
|
state.ended = true;
|
|
|
|
if (state.sync) {
|
|
// if we are sync, wait until next tick to emit the data.
|
|
// Otherwise we risk emitting data in the flow()
|
|
// the readable code triggers during a read() call
|
|
emitReadable(stream);
|
|
} else {
|
|
// emit 'readable' now to make sure it gets picked up.
|
|
state.needReadable = false;
|
|
|
|
if (!state.emittedReadable) {
|
|
state.emittedReadable = true;
|
|
emitReadable_(stream);
|
|
}
|
|
}
|
|
} // Don't emit readable right away in sync mode, because this can trigger
|
|
// another read() call => stack overflow. This way, it might trigger
|
|
// a nextTick recursion warning, but that's not so bad.
|
|
|
|
|
|
function emitReadable(stream) {
|
|
var state = stream._readableState;
|
|
debug('emitReadable', state.needReadable, state.emittedReadable);
|
|
state.needReadable = false;
|
|
|
|
if (!state.emittedReadable) {
|
|
debug('emitReadable', state.flowing);
|
|
state.emittedReadable = true;
|
|
process.nextTick(emitReadable_, stream);
|
|
}
|
|
}
|
|
|
|
function emitReadable_(stream) {
|
|
var state = stream._readableState;
|
|
debug('emitReadable_', state.destroyed, state.length, state.ended);
|
|
|
|
if (!state.destroyed && (state.length || state.ended)) {
|
|
stream.emit('readable');
|
|
state.emittedReadable = false;
|
|
} // The stream needs another readable event if
|
|
// 1. It is not flowing, as the flow mechanism will take
|
|
// care of it.
|
|
// 2. It is not ended.
|
|
// 3. It is below the highWaterMark, so we can schedule
|
|
// another readable later.
|
|
|
|
|
|
state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark;
|
|
flow(stream);
|
|
} // at this point, the user has presumably seen the 'readable' event,
|
|
// and called read() to consume some data. that may have triggered
|
|
// in turn another _read(n) call, in which case reading = true if
|
|
// it's in progress.
|
|
// However, if we're not ended, or reading, and the length < hwm,
|
|
// then go ahead and try to read some more preemptively.
|
|
|
|
|
|
function maybeReadMore(stream, state) {
|
|
if (!state.readingMore) {
|
|
state.readingMore = true;
|
|
process.nextTick(maybeReadMore_, stream, state);
|
|
}
|
|
}
|
|
|
|
function maybeReadMore_(stream, state) {
|
|
// Attempt to read more data if we should.
|
|
//
|
|
// The conditions for reading more data are (one of):
|
|
// - Not enough data buffered (state.length < state.highWaterMark). The loop
|
|
// is responsible for filling the buffer with enough data if such data
|
|
// is available. If highWaterMark is 0 and we are not in the flowing mode
|
|
// we should _not_ attempt to buffer any extra data. We'll get more data
|
|
// when the stream consumer calls read() instead.
|
|
// - No data in the buffer, and the stream is in flowing mode. In this mode
|
|
// the loop below is responsible for ensuring read() is called. Failing to
|
|
// call read here would abort the flow and there's no other mechanism for
|
|
// continuing the flow if the stream consumer has just subscribed to the
|
|
// 'data' event.
|
|
//
|
|
// In addition to the above conditions to keep reading data, the following
|
|
// conditions prevent the data from being read:
|
|
// - The stream has ended (state.ended).
|
|
// - There is already a pending 'read' operation (state.reading). This is a
|
|
// case where the the stream has called the implementation defined _read()
|
|
// method, but they are processing the call asynchronously and have _not_
|
|
// called push() with new data. In this case we skip performing more
|
|
// read()s. The execution ends in this method again after the _read() ends
|
|
// up calling push() with more data.
|
|
while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) {
|
|
var len = state.length;
|
|
debug('maybeReadMore read 0');
|
|
stream.read(0);
|
|
if (len === state.length) // didn't get any data, stop spinning.
|
|
break;
|
|
}
|
|
|
|
state.readingMore = false;
|
|
} // abstract method. to be overridden in specific implementation classes.
|
|
// call cb(er, data) where data is <= n in length.
|
|
// for virtual (non-string, non-buffer) streams, "length" is somewhat
|
|
// arbitrary, and perhaps not very meaningful.
|
|
|
|
|
|
Readable.prototype._read = function (n) {
|
|
errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()'));
|
|
};
|
|
|
|
Readable.prototype.pipe = function (dest, pipeOpts) {
|
|
var src = this;
|
|
var state = this._readableState;
|
|
|
|
switch (state.pipesCount) {
|
|
case 0:
|
|
state.pipes = dest;
|
|
break;
|
|
|
|
case 1:
|
|
state.pipes = [state.pipes, dest];
|
|
break;
|
|
|
|
default:
|
|
state.pipes.push(dest);
|
|
break;
|
|
}
|
|
|
|
state.pipesCount += 1;
|
|
debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
|
|
var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
|
|
var endFn = doEnd ? onend : unpipe;
|
|
if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn);
|
|
dest.on('unpipe', onunpipe);
|
|
|
|
function onunpipe(readable, unpipeInfo) {
|
|
debug('onunpipe');
|
|
|
|
if (readable === src) {
|
|
if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
|
|
unpipeInfo.hasUnpiped = true;
|
|
cleanup();
|
|
}
|
|
}
|
|
}
|
|
|
|
function onend() {
|
|
debug('onend');
|
|
dest.end();
|
|
} // when the dest drains, it reduces the awaitDrain counter
|
|
// on the source. This would be more elegant with a .once()
|
|
// handler in flow(), but adding and removing repeatedly is
|
|
// too slow.
|
|
|
|
|
|
var ondrain = pipeOnDrain(src);
|
|
dest.on('drain', ondrain);
|
|
var cleanedUp = false;
|
|
|
|
function cleanup() {
|
|
debug('cleanup'); // cleanup event handlers once the pipe is broken
|
|
|
|
dest.removeListener('close', onclose);
|
|
dest.removeListener('finish', onfinish);
|
|
dest.removeListener('drain', ondrain);
|
|
dest.removeListener('error', onerror);
|
|
dest.removeListener('unpipe', onunpipe);
|
|
src.removeListener('end', onend);
|
|
src.removeListener('end', unpipe);
|
|
src.removeListener('data', ondata);
|
|
cleanedUp = true; // if the reader is waiting for a drain event from this
|
|
// specific writer, then it would cause it to never start
|
|
// flowing again.
|
|
// So, if this is awaiting a drain, then we just call it now.
|
|
// If we don't know, then assume that we are waiting for one.
|
|
|
|
if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
|
|
}
|
|
|
|
src.on('data', ondata);
|
|
|
|
function ondata(chunk) {
|
|
debug('ondata');
|
|
var ret = dest.write(chunk);
|
|
debug('dest.write', ret);
|
|
|
|
if (ret === false) {
|
|
// If the user unpiped during `dest.write()`, it is possible
|
|
// to get stuck in a permanently paused state if that write
|
|
// also returned false.
|
|
// => Check whether `dest` is still a piping destination.
|
|
if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
|
|
debug('false write response, pause', state.awaitDrain);
|
|
state.awaitDrain++;
|
|
}
|
|
|
|
src.pause();
|
|
}
|
|
} // if the dest has an error, then stop piping into it.
|
|
// however, don't suppress the throwing behavior for this.
|
|
|
|
|
|
function onerror(er) {
|
|
debug('onerror', er);
|
|
unpipe();
|
|
dest.removeListener('error', onerror);
|
|
if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er);
|
|
} // Make sure our error handler is attached before userland ones.
|
|
|
|
|
|
prependListener(dest, 'error', onerror); // Both close and finish should trigger unpipe, but only once.
|
|
|
|
function onclose() {
|
|
dest.removeListener('finish', onfinish);
|
|
unpipe();
|
|
}
|
|
|
|
dest.once('close', onclose);
|
|
|
|
function onfinish() {
|
|
debug('onfinish');
|
|
dest.removeListener('close', onclose);
|
|
unpipe();
|
|
}
|
|
|
|
dest.once('finish', onfinish);
|
|
|
|
function unpipe() {
|
|
debug('unpipe');
|
|
src.unpipe(dest);
|
|
} // tell the dest that it's being piped to
|
|
|
|
|
|
dest.emit('pipe', src); // start the flow if it hasn't been started already.
|
|
|
|
if (!state.flowing) {
|
|
debug('pipe resume');
|
|
src.resume();
|
|
}
|
|
|
|
return dest;
|
|
};
|
|
|
|
function pipeOnDrain(src) {
|
|
return function pipeOnDrainFunctionResult() {
|
|
var state = src._readableState;
|
|
debug('pipeOnDrain', state.awaitDrain);
|
|
if (state.awaitDrain) state.awaitDrain--;
|
|
|
|
if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
|
|
state.flowing = true;
|
|
flow(src);
|
|
}
|
|
};
|
|
}
|
|
|
|
Readable.prototype.unpipe = function (dest) {
|
|
var state = this._readableState;
|
|
var unpipeInfo = {
|
|
hasUnpiped: false
|
|
}; // if we're not piping anywhere, then do nothing.
|
|
|
|
if (state.pipesCount === 0) return this; // just one destination. most common case.
|
|
|
|
if (state.pipesCount === 1) {
|
|
// passed in one, but it's not the right one.
|
|
if (dest && dest !== state.pipes) return this;
|
|
if (!dest) dest = state.pipes; // got a match.
|
|
|
|
state.pipes = null;
|
|
state.pipesCount = 0;
|
|
state.flowing = false;
|
|
if (dest) dest.emit('unpipe', this, unpipeInfo);
|
|
return this;
|
|
} // slow case. multiple pipe destinations.
|
|
|
|
|
|
if (!dest) {
|
|
// remove all.
|
|
var dests = state.pipes;
|
|
var len = state.pipesCount;
|
|
state.pipes = null;
|
|
state.pipesCount = 0;
|
|
state.flowing = false;
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
dests[i].emit('unpipe', this, {
|
|
hasUnpiped: false
|
|
});
|
|
}
|
|
|
|
return this;
|
|
} // try to find the right one.
|
|
|
|
|
|
var index = indexOf(state.pipes, dest);
|
|
if (index === -1) return this;
|
|
state.pipes.splice(index, 1);
|
|
state.pipesCount -= 1;
|
|
if (state.pipesCount === 1) state.pipes = state.pipes[0];
|
|
dest.emit('unpipe', this, unpipeInfo);
|
|
return this;
|
|
}; // set up data events if they are asked for
|
|
// Ensure readable listeners eventually get something
|
|
|
|
|
|
Readable.prototype.on = function (ev, fn) {
|
|
var res = Stream.prototype.on.call(this, ev, fn);
|
|
var state = this._readableState;
|
|
|
|
if (ev === 'data') {
|
|
// update readableListening so that resume() may be a no-op
|
|
// a few lines down. This is needed to support once('readable').
|
|
state.readableListening = this.listenerCount('readable') > 0; // Try start flowing on next tick if stream isn't explicitly paused
|
|
|
|
if (state.flowing !== false) this.resume();
|
|
} else if (ev === 'readable') {
|
|
if (!state.endEmitted && !state.readableListening) {
|
|
state.readableListening = state.needReadable = true;
|
|
state.flowing = false;
|
|
state.emittedReadable = false;
|
|
debug('on readable', state.length, state.reading);
|
|
|
|
if (state.length) {
|
|
emitReadable(this);
|
|
} else if (!state.reading) {
|
|
process.nextTick(nReadingNextTick, this);
|
|
}
|
|
}
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
Readable.prototype.addListener = Readable.prototype.on;
|
|
|
|
Readable.prototype.removeListener = function (ev, fn) {
|
|
var res = Stream.prototype.removeListener.call(this, ev, fn);
|
|
|
|
if (ev === 'readable') {
|
|
// We need to check if there is someone still listening to
|
|
// readable and reset the state. However this needs to happen
|
|
// after readable has been emitted but before I/O (nextTick) to
|
|
// support once('readable', fn) cycles. This means that calling
|
|
// resume within the same tick will have no
|
|
// effect.
|
|
process.nextTick(updateReadableListening, this);
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
Readable.prototype.removeAllListeners = function (ev) {
|
|
var res = Stream.prototype.removeAllListeners.apply(this, arguments);
|
|
|
|
if (ev === 'readable' || ev === undefined) {
|
|
// We need to check if there is someone still listening to
|
|
// readable and reset the state. However this needs to happen
|
|
// after readable has been emitted but before I/O (nextTick) to
|
|
// support once('readable', fn) cycles. This means that calling
|
|
// resume within the same tick will have no
|
|
// effect.
|
|
process.nextTick(updateReadableListening, this);
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
function updateReadableListening(self) {
|
|
var state = self._readableState;
|
|
state.readableListening = self.listenerCount('readable') > 0;
|
|
|
|
if (state.resumeScheduled && !state.paused) {
|
|
// flowing needs to be set to true now, otherwise
|
|
// the upcoming resume will not flow.
|
|
state.flowing = true; // crude way to check if we should resume
|
|
} else if (self.listenerCount('data') > 0) {
|
|
self.resume();
|
|
}
|
|
}
|
|
|
|
function nReadingNextTick(self) {
|
|
debug('readable nexttick read 0');
|
|
self.read(0);
|
|
} // pause() and resume() are remnants of the legacy readable stream API
|
|
// If the user uses them, then switch into old mode.
|
|
|
|
|
|
Readable.prototype.resume = function () {
|
|
var state = this._readableState;
|
|
|
|
if (!state.flowing) {
|
|
debug('resume'); // we flow only if there is no one listening
|
|
// for readable, but we still have to call
|
|
// resume()
|
|
|
|
state.flowing = !state.readableListening;
|
|
resume(this, state);
|
|
}
|
|
|
|
state.paused = false;
|
|
return this;
|
|
};
|
|
|
|
function resume(stream, state) {
|
|
if (!state.resumeScheduled) {
|
|
state.resumeScheduled = true;
|
|
process.nextTick(resume_, stream, state);
|
|
}
|
|
}
|
|
|
|
function resume_(stream, state) {
|
|
debug('resume', state.reading);
|
|
|
|
if (!state.reading) {
|
|
stream.read(0);
|
|
}
|
|
|
|
state.resumeScheduled = false;
|
|
stream.emit('resume');
|
|
flow(stream);
|
|
if (state.flowing && !state.reading) stream.read(0);
|
|
}
|
|
|
|
Readable.prototype.pause = function () {
|
|
debug('call pause flowing=%j', this._readableState.flowing);
|
|
|
|
if (this._readableState.flowing !== false) {
|
|
debug('pause');
|
|
this._readableState.flowing = false;
|
|
this.emit('pause');
|
|
}
|
|
|
|
this._readableState.paused = true;
|
|
return this;
|
|
};
|
|
|
|
function flow(stream) {
|
|
var state = stream._readableState;
|
|
debug('flow', state.flowing);
|
|
|
|
while (state.flowing && stream.read() !== null) {
|
|
;
|
|
}
|
|
} // wrap an old-style stream as the async data source.
|
|
// This is *not* part of the readable stream interface.
|
|
// It is an ugly unfortunate mess of history.
|
|
|
|
|
|
Readable.prototype.wrap = function (stream) {
|
|
var _this = this;
|
|
|
|
var state = this._readableState;
|
|
var paused = false;
|
|
stream.on('end', function () {
|
|
debug('wrapped end');
|
|
|
|
if (state.decoder && !state.ended) {
|
|
var chunk = state.decoder.end();
|
|
if (chunk && chunk.length) _this.push(chunk);
|
|
}
|
|
|
|
_this.push(null);
|
|
});
|
|
stream.on('data', function (chunk) {
|
|
debug('wrapped data');
|
|
if (state.decoder) chunk = state.decoder.write(chunk); // don't skip over falsy values in objectMode
|
|
|
|
if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
|
|
|
|
var ret = _this.push(chunk);
|
|
|
|
if (!ret) {
|
|
paused = true;
|
|
stream.pause();
|
|
}
|
|
}); // proxy all the other methods.
|
|
// important when wrapping filters and duplexes.
|
|
|
|
for (var i in stream) {
|
|
if (this[i] === undefined && typeof stream[i] === 'function') {
|
|
this[i] = function methodWrap(method) {
|
|
return function methodWrapReturnFunction() {
|
|
return stream[method].apply(stream, arguments);
|
|
};
|
|
}(i);
|
|
}
|
|
} // proxy certain important events.
|
|
|
|
|
|
for (var n = 0; n < kProxyEvents.length; n++) {
|
|
stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n]));
|
|
} // when we try to consume some more bytes, simply unpause the
|
|
// underlying stream.
|
|
|
|
|
|
this._read = function (n) {
|
|
debug('wrapped _read', n);
|
|
|
|
if (paused) {
|
|
paused = false;
|
|
stream.resume();
|
|
}
|
|
};
|
|
|
|
return this;
|
|
};
|
|
|
|
if (typeof Symbol === 'function') {
|
|
Readable.prototype[Symbol.asyncIterator] = function () {
|
|
if (createReadableStreamAsyncIterator === undefined) {
|
|
createReadableStreamAsyncIterator = require('./internal/streams/async_iterator');
|
|
}
|
|
|
|
return createReadableStreamAsyncIterator(this);
|
|
};
|
|
}
|
|
|
|
Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
return this._readableState.highWaterMark;
|
|
}
|
|
});
|
|
Object.defineProperty(Readable.prototype, 'readableBuffer', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
return this._readableState && this._readableState.buffer;
|
|
}
|
|
});
|
|
Object.defineProperty(Readable.prototype, 'readableFlowing', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
return this._readableState.flowing;
|
|
},
|
|
set: function set(state) {
|
|
if (this._readableState) {
|
|
this._readableState.flowing = state;
|
|
}
|
|
}
|
|
}); // exposed for testing purposes only.
|
|
|
|
Readable._fromList = fromList;
|
|
Object.defineProperty(Readable.prototype, 'readableLength', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
return this._readableState.length;
|
|
}
|
|
}); // Pluck off n bytes from an array of buffers.
|
|
// Length is the combined lengths of all the buffers in the list.
|
|
// This function is designed to be inlinable, so please take care when making
|
|
// changes to the function body.
|
|
|
|
function fromList(n, state) {
|
|
// nothing buffered
|
|
if (state.length === 0) return null;
|
|
var ret;
|
|
if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
|
|
// read it all, truncate the list
|
|
if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.first();else ret = state.buffer.concat(state.length);
|
|
state.buffer.clear();
|
|
} else {
|
|
// read part of list
|
|
ret = state.buffer.consume(n, state.decoder);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
function endReadable(stream) {
|
|
var state = stream._readableState;
|
|
debug('endReadable', state.endEmitted);
|
|
|
|
if (!state.endEmitted) {
|
|
state.ended = true;
|
|
process.nextTick(endReadableNT, state, stream);
|
|
}
|
|
}
|
|
|
|
function endReadableNT(state, stream) {
|
|
debug('endReadableNT', state.endEmitted, state.length); // Check that we didn't get one last unshift.
|
|
|
|
if (!state.endEmitted && state.length === 0) {
|
|
state.endEmitted = true;
|
|
stream.readable = false;
|
|
stream.emit('end');
|
|
|
|
if (state.autoDestroy) {
|
|
// In case of duplex streams we need a way to detect
|
|
// if the writable side is ready for autoDestroy as well
|
|
var wState = stream._writableState;
|
|
|
|
if (!wState || wState.autoDestroy && wState.finished) {
|
|
stream.destroy();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (typeof Symbol === 'function') {
|
|
Readable.from = function (iterable, opts) {
|
|
if (from === undefined) {
|
|
from = require('./internal/streams/from');
|
|
}
|
|
|
|
return from(Readable, iterable, opts);
|
|
};
|
|
}
|
|
|
|
function indexOf(xs, x) {
|
|
for (var i = 0, l = xs.length; i < l; i++) {
|
|
if (xs[i] === x) return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
}).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
|
|
},{"../errors":10,"./_stream_duplex":11,"./internal/streams/async_iterator":16,"./internal/streams/buffer_list":17,"./internal/streams/destroy":18,"./internal/streams/from":20,"./internal/streams/state":22,"./internal/streams/stream":23,"_process":7,"buffer":3,"events":4,"inherits":6,"string_decoder/":24,"util":2}],14:[function(require,module,exports){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
// 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 _require$codes = require('../errors').codes,
|
|
ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
|
|
ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK,
|
|
ERR_TRANSFORM_ALREADY_TRANSFORMING = _require$codes.ERR_TRANSFORM_ALREADY_TRANSFORMING,
|
|
ERR_TRANSFORM_WITH_LENGTH_0 = _require$codes.ERR_TRANSFORM_WITH_LENGTH_0;
|
|
|
|
var Duplex = require('./_stream_duplex');
|
|
|
|
require('inherits')(Transform, Duplex);
|
|
|
|
function afterTransform(er, data) {
|
|
var ts = this._transformState;
|
|
ts.transforming = false;
|
|
var cb = ts.writecb;
|
|
|
|
if (cb === null) {
|
|
return this.emit('error', new ERR_MULTIPLE_CALLBACK());
|
|
}
|
|
|
|
ts.writechunk = null;
|
|
ts.writecb = null;
|
|
if (data != null) // single equals check for both `null` and `undefined`
|
|
this.push(data);
|
|
cb(er);
|
|
var rs = this._readableState;
|
|
rs.reading = false;
|
|
|
|
if (rs.needReadable || rs.length < rs.highWaterMark) {
|
|
this._read(rs.highWaterMark);
|
|
}
|
|
}
|
|
|
|
function Transform(options) {
|
|
if (!(this instanceof Transform)) return new Transform(options);
|
|
Duplex.call(this, options);
|
|
this._transformState = {
|
|
afterTransform: afterTransform.bind(this),
|
|
needTransform: false,
|
|
transforming: false,
|
|
writecb: null,
|
|
writechunk: null,
|
|
writeencoding: null
|
|
}; // start out asking for a readable event once data is transformed.
|
|
|
|
this._readableState.needReadable = true; // we have implemented the _read method, and done the other things
|
|
// that Readable wants before the first _read call, so unset the
|
|
// sync guard flag.
|
|
|
|
this._readableState.sync = false;
|
|
|
|
if (options) {
|
|
if (typeof options.transform === 'function') this._transform = options.transform;
|
|
if (typeof options.flush === 'function') this._flush = options.flush;
|
|
} // When the writable side finishes, then flush out anything remaining.
|
|
|
|
|
|
this.on('prefinish', prefinish);
|
|
}
|
|
|
|
function prefinish() {
|
|
var _this = this;
|
|
|
|
if (typeof this._flush === 'function' && !this._readableState.destroyed) {
|
|
this._flush(function (er, data) {
|
|
done(_this, er, data);
|
|
});
|
|
} else {
|
|
done(this, null, null);
|
|
}
|
|
}
|
|
|
|
Transform.prototype.push = function (chunk, encoding) {
|
|
this._transformState.needTransform = false;
|
|
return Duplex.prototype.push.call(this, chunk, encoding);
|
|
}; // This is the part where you do stuff!
|
|
// override this function in implementation classes.
|
|
// 'chunk' is an input chunk.
|
|
//
|
|
// Call `push(newChunk)` to pass along transformed output
|
|
// to the readable side. You may call 'push' zero or more times.
|
|
//
|
|
// Call `cb(err)` when you are done with this chunk. If you pass
|
|
// an error, then that'll put the hurt on the whole operation. If you
|
|
// never call cb(), then you'll never get another chunk.
|
|
|
|
|
|
Transform.prototype._transform = function (chunk, encoding, cb) {
|
|
cb(new ERR_METHOD_NOT_IMPLEMENTED('_transform()'));
|
|
};
|
|
|
|
Transform.prototype._write = function (chunk, encoding, cb) {
|
|
var ts = this._transformState;
|
|
ts.writecb = cb;
|
|
ts.writechunk = chunk;
|
|
ts.writeencoding = encoding;
|
|
|
|
if (!ts.transforming) {
|
|
var rs = this._readableState;
|
|
if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
|
|
}
|
|
}; // Doesn't matter what the args are here.
|
|
// _transform does all the work.
|
|
// That we got here means that the readable side wants more data.
|
|
|
|
|
|
Transform.prototype._read = function (n) {
|
|
var ts = this._transformState;
|
|
|
|
if (ts.writechunk !== null && !ts.transforming) {
|
|
ts.transforming = true;
|
|
|
|
this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
|
|
} else {
|
|
// mark that we need a transform, so that any data that comes in
|
|
// will get processed, now that we've asked for it.
|
|
ts.needTransform = true;
|
|
}
|
|
};
|
|
|
|
Transform.prototype._destroy = function (err, cb) {
|
|
Duplex.prototype._destroy.call(this, err, function (err2) {
|
|
cb(err2);
|
|
});
|
|
};
|
|
|
|
function done(stream, er, data) {
|
|
if (er) return stream.emit('error', er);
|
|
if (data != null) // single equals check for both `null` and `undefined`
|
|
stream.push(data); // TODO(BridgeAR): Write a test for these two error cases
|
|
// if there's nothing in the write buffer, then that means
|
|
// that nothing more will ever be provided
|
|
|
|
if (stream._writableState.length) throw new ERR_TRANSFORM_WITH_LENGTH_0();
|
|
if (stream._transformState.transforming) throw new ERR_TRANSFORM_ALREADY_TRANSFORMING();
|
|
return stream.push(null);
|
|
}
|
|
},{"../errors":10,"./_stream_duplex":11,"inherits":6}],15:[function(require,module,exports){
|
|
(function (process,global){(function (){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
// A bit simpler than readable streams.
|
|
// Implement an async ._write(chunk, encoding, cb), and it'll handle all
|
|
// the drain event emission and buffering.
|
|
'use strict';
|
|
|
|
module.exports = Writable;
|
|
/* <replacement> */
|
|
|
|
function WriteReq(chunk, encoding, cb) {
|
|
this.chunk = chunk;
|
|
this.encoding = encoding;
|
|
this.callback = cb;
|
|
this.next = null;
|
|
} // It seems a linked list but it is not
|
|
// there will be only 2 of these for each stream
|
|
|
|
|
|
function CorkedRequest(state) {
|
|
var _this = this;
|
|
|
|
this.next = null;
|
|
this.entry = null;
|
|
|
|
this.finish = function () {
|
|
onCorkedFinish(_this, state);
|
|
};
|
|
}
|
|
/* </replacement> */
|
|
|
|
/*<replacement>*/
|
|
|
|
|
|
var Duplex;
|
|
/*</replacement>*/
|
|
|
|
Writable.WritableState = WritableState;
|
|
/*<replacement>*/
|
|
|
|
var internalUtil = {
|
|
deprecate: require('util-deprecate')
|
|
};
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
|
|
var Stream = require('./internal/streams/stream');
|
|
/*</replacement>*/
|
|
|
|
|
|
var Buffer = require('buffer').Buffer;
|
|
|
|
var OurUint8Array = global.Uint8Array || function () {};
|
|
|
|
function _uint8ArrayToBuffer(chunk) {
|
|
return Buffer.from(chunk);
|
|
}
|
|
|
|
function _isUint8Array(obj) {
|
|
return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
|
|
}
|
|
|
|
var destroyImpl = require('./internal/streams/destroy');
|
|
|
|
var _require = require('./internal/streams/state'),
|
|
getHighWaterMark = _require.getHighWaterMark;
|
|
|
|
var _require$codes = require('../errors').codes,
|
|
ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
|
|
ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
|
|
ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK,
|
|
ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE,
|
|
ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED,
|
|
ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES,
|
|
ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END,
|
|
ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING;
|
|
|
|
var errorOrDestroy = destroyImpl.errorOrDestroy;
|
|
|
|
require('inherits')(Writable, Stream);
|
|
|
|
function nop() {}
|
|
|
|
function WritableState(options, stream, isDuplex) {
|
|
Duplex = Duplex || require('./_stream_duplex');
|
|
options = options || {}; // Duplex streams are both readable and writable, but share
|
|
// the same options object.
|
|
// However, some cases require setting options to different
|
|
// values for the readable and the writable sides of the duplex stream,
|
|
// e.g. options.readableObjectMode vs. options.writableObjectMode, etc.
|
|
|
|
if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag to indicate whether or not this stream
|
|
// contains buffers or objects.
|
|
|
|
this.objectMode = !!options.objectMode;
|
|
if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; // the point at which write() starts returning false
|
|
// Note: 0 is a valid value, means that we always return false if
|
|
// the entire buffer is not flushed immediately on write()
|
|
|
|
this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex); // if _final has been called
|
|
|
|
this.finalCalled = false; // drain event flag.
|
|
|
|
this.needDrain = false; // at the start of calling end()
|
|
|
|
this.ending = false; // when end() has been called, and returned
|
|
|
|
this.ended = false; // when 'finish' is emitted
|
|
|
|
this.finished = false; // has it been destroyed
|
|
|
|
this.destroyed = false; // should we decode strings into buffers before passing to _write?
|
|
// this is here so that some node-core streams can optimize string
|
|
// handling at a lower level.
|
|
|
|
var noDecode = options.decodeStrings === false;
|
|
this.decodeStrings = !noDecode; // Crypto is kind of old and crusty. Historically, its default string
|
|
// encoding is 'binary' so we have to make this configurable.
|
|
// Everything else in the universe uses 'utf8', though.
|
|
|
|
this.defaultEncoding = options.defaultEncoding || 'utf8'; // not an actual buffer we keep track of, but a measurement
|
|
// of how much we're waiting to get pushed to some underlying
|
|
// socket or file.
|
|
|
|
this.length = 0; // a flag to see when we're in the middle of a write.
|
|
|
|
this.writing = false; // when true all writes will be buffered until .uncork() call
|
|
|
|
this.corked = 0; // a flag to be able to tell if the onwrite cb is called immediately,
|
|
// or on a later tick. We set this to true at first, because any
|
|
// actions that shouldn't happen until "later" should generally also
|
|
// not happen before the first write call.
|
|
|
|
this.sync = true; // a flag to know if we're processing previously buffered items, which
|
|
// may call the _write() callback in the same tick, so that we don't
|
|
// end up in an overlapped onwrite situation.
|
|
|
|
this.bufferProcessing = false; // the callback that's passed to _write(chunk,cb)
|
|
|
|
this.onwrite = function (er) {
|
|
onwrite(stream, er);
|
|
}; // the callback that the user supplies to write(chunk,encoding,cb)
|
|
|
|
|
|
this.writecb = null; // the amount that is being written when _write is called.
|
|
|
|
this.writelen = 0;
|
|
this.bufferedRequest = null;
|
|
this.lastBufferedRequest = null; // number of pending user-supplied write callbacks
|
|
// this must be 0 before 'finish' can be emitted
|
|
|
|
this.pendingcb = 0; // emit prefinish if the only thing we're waiting for is _write cbs
|
|
// This is relevant for synchronous Transform streams
|
|
|
|
this.prefinished = false; // True if the error was already emitted and should not be thrown again
|
|
|
|
this.errorEmitted = false; // Should close be emitted on destroy. Defaults to true.
|
|
|
|
this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'finish' (and potentially 'end')
|
|
|
|
this.autoDestroy = !!options.autoDestroy; // count buffered requests
|
|
|
|
this.bufferedRequestCount = 0; // allocate the first CorkedRequest, there is always
|
|
// one allocated and free to use, and we maintain at most two
|
|
|
|
this.corkedRequestsFree = new CorkedRequest(this);
|
|
}
|
|
|
|
WritableState.prototype.getBuffer = function getBuffer() {
|
|
var current = this.bufferedRequest;
|
|
var out = [];
|
|
|
|
while (current) {
|
|
out.push(current);
|
|
current = current.next;
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
(function () {
|
|
try {
|
|
Object.defineProperty(WritableState.prototype, 'buffer', {
|
|
get: internalUtil.deprecate(function writableStateBufferGetter() {
|
|
return this.getBuffer();
|
|
}, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
|
|
});
|
|
} catch (_) {}
|
|
})(); // Test _writableState for inheritance to account for Duplex streams,
|
|
// whose prototype chain only points to Readable.
|
|
|
|
|
|
var realHasInstance;
|
|
|
|
if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
|
|
realHasInstance = Function.prototype[Symbol.hasInstance];
|
|
Object.defineProperty(Writable, Symbol.hasInstance, {
|
|
value: function value(object) {
|
|
if (realHasInstance.call(this, object)) return true;
|
|
if (this !== Writable) return false;
|
|
return object && object._writableState instanceof WritableState;
|
|
}
|
|
});
|
|
} else {
|
|
realHasInstance = function realHasInstance(object) {
|
|
return object instanceof this;
|
|
};
|
|
}
|
|
|
|
function Writable(options) {
|
|
Duplex = Duplex || require('./_stream_duplex'); // Writable ctor is applied to Duplexes, too.
|
|
// `realHasInstance` is necessary because using plain `instanceof`
|
|
// would return false, as no `_writableState` property is attached.
|
|
// Trying to use the custom `instanceof` for Writable here will also break the
|
|
// Node.js LazyTransform implementation, which has a non-trivial getter for
|
|
// `_writableState` that would lead to infinite recursion.
|
|
// Checking for a Stream.Duplex instance is faster here instead of inside
|
|
// the WritableState constructor, at least with V8 6.5
|
|
|
|
var isDuplex = this instanceof Duplex;
|
|
if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options);
|
|
this._writableState = new WritableState(options, this, isDuplex); // legacy.
|
|
|
|
this.writable = true;
|
|
|
|
if (options) {
|
|
if (typeof options.write === 'function') this._write = options.write;
|
|
if (typeof options.writev === 'function') this._writev = options.writev;
|
|
if (typeof options.destroy === 'function') this._destroy = options.destroy;
|
|
if (typeof options.final === 'function') this._final = options.final;
|
|
}
|
|
|
|
Stream.call(this);
|
|
} // Otherwise people can pipe Writable streams, which is just wrong.
|
|
|
|
|
|
Writable.prototype.pipe = function () {
|
|
errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE());
|
|
};
|
|
|
|
function writeAfterEnd(stream, cb) {
|
|
var er = new ERR_STREAM_WRITE_AFTER_END(); // TODO: defer error events consistently everywhere, not just the cb
|
|
|
|
errorOrDestroy(stream, er);
|
|
process.nextTick(cb, er);
|
|
} // Checks that a user-supplied chunk is valid, especially for the particular
|
|
// mode the stream is in. Currently this means that `null` is never accepted
|
|
// and undefined/non-string values are only allowed in object mode.
|
|
|
|
|
|
function validChunk(stream, state, chunk, cb) {
|
|
var er;
|
|
|
|
if (chunk === null) {
|
|
er = new ERR_STREAM_NULL_VALUES();
|
|
} else if (typeof chunk !== 'string' && !state.objectMode) {
|
|
er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk);
|
|
}
|
|
|
|
if (er) {
|
|
errorOrDestroy(stream, er);
|
|
process.nextTick(cb, er);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
Writable.prototype.write = function (chunk, encoding, cb) {
|
|
var state = this._writableState;
|
|
var ret = false;
|
|
|
|
var isBuf = !state.objectMode && _isUint8Array(chunk);
|
|
|
|
if (isBuf && !Buffer.isBuffer(chunk)) {
|
|
chunk = _uint8ArrayToBuffer(chunk);
|
|
}
|
|
|
|
if (typeof encoding === 'function') {
|
|
cb = encoding;
|
|
encoding = null;
|
|
}
|
|
|
|
if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
|
|
if (typeof cb !== 'function') cb = nop;
|
|
if (state.ending) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
|
|
state.pendingcb++;
|
|
ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
|
|
}
|
|
return ret;
|
|
};
|
|
|
|
Writable.prototype.cork = function () {
|
|
this._writableState.corked++;
|
|
};
|
|
|
|
Writable.prototype.uncork = function () {
|
|
var state = this._writableState;
|
|
|
|
if (state.corked) {
|
|
state.corked--;
|
|
if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
|
|
}
|
|
};
|
|
|
|
Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
|
|
// node::ParseEncoding() requires lower case.
|
|
if (typeof encoding === 'string') encoding = encoding.toLowerCase();
|
|
if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new ERR_UNKNOWN_ENCODING(encoding);
|
|
this._writableState.defaultEncoding = encoding;
|
|
return this;
|
|
};
|
|
|
|
Object.defineProperty(Writable.prototype, 'writableBuffer', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
return this._writableState && this._writableState.getBuffer();
|
|
}
|
|
});
|
|
|
|
function decodeChunk(state, chunk, encoding) {
|
|
if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
|
|
chunk = Buffer.from(chunk, encoding);
|
|
}
|
|
|
|
return chunk;
|
|
}
|
|
|
|
Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
return this._writableState.highWaterMark;
|
|
}
|
|
}); // if we're already writing something, then just put this
|
|
// in the queue, and wait our turn. Otherwise, call _write
|
|
// If we return false, then we need a drain event, so set that flag.
|
|
|
|
function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
|
|
if (!isBuf) {
|
|
var newChunk = decodeChunk(state, chunk, encoding);
|
|
|
|
if (chunk !== newChunk) {
|
|
isBuf = true;
|
|
encoding = 'buffer';
|
|
chunk = newChunk;
|
|
}
|
|
}
|
|
|
|
var len = state.objectMode ? 1 : chunk.length;
|
|
state.length += len;
|
|
var ret = state.length < state.highWaterMark; // we must ensure that previous needDrain will not be reset to false.
|
|
|
|
if (!ret) state.needDrain = true;
|
|
|
|
if (state.writing || state.corked) {
|
|
var last = state.lastBufferedRequest;
|
|
state.lastBufferedRequest = {
|
|
chunk: chunk,
|
|
encoding: encoding,
|
|
isBuf: isBuf,
|
|
callback: cb,
|
|
next: null
|
|
};
|
|
|
|
if (last) {
|
|
last.next = state.lastBufferedRequest;
|
|
} else {
|
|
state.bufferedRequest = state.lastBufferedRequest;
|
|
}
|
|
|
|
state.bufferedRequestCount += 1;
|
|
} else {
|
|
doWrite(stream, state, false, len, chunk, encoding, cb);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function doWrite(stream, state, writev, len, chunk, encoding, cb) {
|
|
state.writelen = len;
|
|
state.writecb = cb;
|
|
state.writing = true;
|
|
state.sync = true;
|
|
if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));else if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
|
|
state.sync = false;
|
|
}
|
|
|
|
function onwriteError(stream, state, sync, er, cb) {
|
|
--state.pendingcb;
|
|
|
|
if (sync) {
|
|
// defer the callback if we are being called synchronously
|
|
// to avoid piling up things on the stack
|
|
process.nextTick(cb, er); // this can emit finish, and it will always happen
|
|
// after error
|
|
|
|
process.nextTick(finishMaybe, stream, state);
|
|
stream._writableState.errorEmitted = true;
|
|
errorOrDestroy(stream, er);
|
|
} else {
|
|
// the caller expect this to happen before if
|
|
// it is async
|
|
cb(er);
|
|
stream._writableState.errorEmitted = true;
|
|
errorOrDestroy(stream, er); // this can emit finish, but finish must
|
|
// always follow error
|
|
|
|
finishMaybe(stream, state);
|
|
}
|
|
}
|
|
|
|
function onwriteStateUpdate(state) {
|
|
state.writing = false;
|
|
state.writecb = null;
|
|
state.length -= state.writelen;
|
|
state.writelen = 0;
|
|
}
|
|
|
|
function onwrite(stream, er) {
|
|
var state = stream._writableState;
|
|
var sync = state.sync;
|
|
var cb = state.writecb;
|
|
if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK();
|
|
onwriteStateUpdate(state);
|
|
if (er) onwriteError(stream, state, sync, er, cb);else {
|
|
// Check if we're actually ready to finish, but don't emit yet
|
|
var finished = needFinish(state) || stream.destroyed;
|
|
|
|
if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
|
|
clearBuffer(stream, state);
|
|
}
|
|
|
|
if (sync) {
|
|
process.nextTick(afterWrite, stream, state, finished, cb);
|
|
} else {
|
|
afterWrite(stream, state, finished, cb);
|
|
}
|
|
}
|
|
}
|
|
|
|
function afterWrite(stream, state, finished, cb) {
|
|
if (!finished) onwriteDrain(stream, state);
|
|
state.pendingcb--;
|
|
cb();
|
|
finishMaybe(stream, state);
|
|
} // Must force callback to be called on nextTick, so that we don't
|
|
// emit 'drain' before the write() consumer gets the 'false' return
|
|
// value, and has a chance to attach a 'drain' listener.
|
|
|
|
|
|
function onwriteDrain(stream, state) {
|
|
if (state.length === 0 && state.needDrain) {
|
|
state.needDrain = false;
|
|
stream.emit('drain');
|
|
}
|
|
} // if there's something in the buffer waiting, then process it
|
|
|
|
|
|
function clearBuffer(stream, state) {
|
|
state.bufferProcessing = true;
|
|
var entry = state.bufferedRequest;
|
|
|
|
if (stream._writev && entry && entry.next) {
|
|
// Fast case, write everything using _writev()
|
|
var l = state.bufferedRequestCount;
|
|
var buffer = new Array(l);
|
|
var holder = state.corkedRequestsFree;
|
|
holder.entry = entry;
|
|
var count = 0;
|
|
var allBuffers = true;
|
|
|
|
while (entry) {
|
|
buffer[count] = entry;
|
|
if (!entry.isBuf) allBuffers = false;
|
|
entry = entry.next;
|
|
count += 1;
|
|
}
|
|
|
|
buffer.allBuffers = allBuffers;
|
|
doWrite(stream, state, true, state.length, buffer, '', holder.finish); // doWrite is almost always async, defer these to save a bit of time
|
|
// as the hot path ends with doWrite
|
|
|
|
state.pendingcb++;
|
|
state.lastBufferedRequest = null;
|
|
|
|
if (holder.next) {
|
|
state.corkedRequestsFree = holder.next;
|
|
holder.next = null;
|
|
} else {
|
|
state.corkedRequestsFree = new CorkedRequest(state);
|
|
}
|
|
|
|
state.bufferedRequestCount = 0;
|
|
} else {
|
|
// Slow case, write chunks one-by-one
|
|
while (entry) {
|
|
var chunk = entry.chunk;
|
|
var encoding = entry.encoding;
|
|
var cb = entry.callback;
|
|
var len = state.objectMode ? 1 : chunk.length;
|
|
doWrite(stream, state, false, len, chunk, encoding, cb);
|
|
entry = entry.next;
|
|
state.bufferedRequestCount--; // if we didn't call the onwrite immediately, then
|
|
// it means that we need to wait until it does.
|
|
// also, that means that the chunk and cb are currently
|
|
// being processed, so move the buffer counter past them.
|
|
|
|
if (state.writing) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (entry === null) state.lastBufferedRequest = null;
|
|
}
|
|
|
|
state.bufferedRequest = entry;
|
|
state.bufferProcessing = false;
|
|
}
|
|
|
|
Writable.prototype._write = function (chunk, encoding, cb) {
|
|
cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()'));
|
|
};
|
|
|
|
Writable.prototype._writev = null;
|
|
|
|
Writable.prototype.end = function (chunk, encoding, cb) {
|
|
var state = this._writableState;
|
|
|
|
if (typeof chunk === 'function') {
|
|
cb = chunk;
|
|
chunk = null;
|
|
encoding = null;
|
|
} else if (typeof encoding === 'function') {
|
|
cb = encoding;
|
|
encoding = null;
|
|
}
|
|
|
|
if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); // .end() fully uncorks
|
|
|
|
if (state.corked) {
|
|
state.corked = 1;
|
|
this.uncork();
|
|
} // ignore unnecessary end() calls.
|
|
|
|
|
|
if (!state.ending) endWritable(this, state, cb);
|
|
return this;
|
|
};
|
|
|
|
Object.defineProperty(Writable.prototype, 'writableLength', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
return this._writableState.length;
|
|
}
|
|
});
|
|
|
|
function needFinish(state) {
|
|
return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
|
|
}
|
|
|
|
function callFinal(stream, state) {
|
|
stream._final(function (err) {
|
|
state.pendingcb--;
|
|
|
|
if (err) {
|
|
errorOrDestroy(stream, err);
|
|
}
|
|
|
|
state.prefinished = true;
|
|
stream.emit('prefinish');
|
|
finishMaybe(stream, state);
|
|
});
|
|
}
|
|
|
|
function prefinish(stream, state) {
|
|
if (!state.prefinished && !state.finalCalled) {
|
|
if (typeof stream._final === 'function' && !state.destroyed) {
|
|
state.pendingcb++;
|
|
state.finalCalled = true;
|
|
process.nextTick(callFinal, stream, state);
|
|
} else {
|
|
state.prefinished = true;
|
|
stream.emit('prefinish');
|
|
}
|
|
}
|
|
}
|
|
|
|
function finishMaybe(stream, state) {
|
|
var need = needFinish(state);
|
|
|
|
if (need) {
|
|
prefinish(stream, state);
|
|
|
|
if (state.pendingcb === 0) {
|
|
state.finished = true;
|
|
stream.emit('finish');
|
|
|
|
if (state.autoDestroy) {
|
|
// In case of duplex streams we need a way to detect
|
|
// if the readable side is ready for autoDestroy as well
|
|
var rState = stream._readableState;
|
|
|
|
if (!rState || rState.autoDestroy && rState.endEmitted) {
|
|
stream.destroy();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return need;
|
|
}
|
|
|
|
function endWritable(stream, state, cb) {
|
|
state.ending = true;
|
|
finishMaybe(stream, state);
|
|
|
|
if (cb) {
|
|
if (state.finished) process.nextTick(cb);else stream.once('finish', cb);
|
|
}
|
|
|
|
state.ended = true;
|
|
stream.writable = false;
|
|
}
|
|
|
|
function onCorkedFinish(corkReq, state, err) {
|
|
var entry = corkReq.entry;
|
|
corkReq.entry = null;
|
|
|
|
while (entry) {
|
|
var cb = entry.callback;
|
|
state.pendingcb--;
|
|
cb(err);
|
|
entry = entry.next;
|
|
} // reuse the free corkReq.
|
|
|
|
|
|
state.corkedRequestsFree.next = corkReq;
|
|
}
|
|
|
|
Object.defineProperty(Writable.prototype, 'destroyed', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function get() {
|
|
if (this._writableState === undefined) {
|
|
return false;
|
|
}
|
|
|
|
return this._writableState.destroyed;
|
|
},
|
|
set: function set(value) {
|
|
// we ignore the value if the stream
|
|
// has not been initialized yet
|
|
if (!this._writableState) {
|
|
return;
|
|
} // backward compatibility, the user is explicitly
|
|
// managing destroyed
|
|
|
|
|
|
this._writableState.destroyed = value;
|
|
}
|
|
});
|
|
Writable.prototype.destroy = destroyImpl.destroy;
|
|
Writable.prototype._undestroy = destroyImpl.undestroy;
|
|
|
|
Writable.prototype._destroy = function (err, cb) {
|
|
cb(err);
|
|
};
|
|
}).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
|
|
},{"../errors":10,"./_stream_duplex":11,"./internal/streams/destroy":18,"./internal/streams/state":22,"./internal/streams/stream":23,"_process":7,"buffer":3,"inherits":6,"util-deprecate":26}],16:[function(require,module,exports){
|
|
(function (process){(function (){
|
|
'use strict';
|
|
|
|
var _Object$setPrototypeO;
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
var finished = require('./end-of-stream');
|
|
|
|
var kLastResolve = Symbol('lastResolve');
|
|
var kLastReject = Symbol('lastReject');
|
|
var kError = Symbol('error');
|
|
var kEnded = Symbol('ended');
|
|
var kLastPromise = Symbol('lastPromise');
|
|
var kHandlePromise = Symbol('handlePromise');
|
|
var kStream = Symbol('stream');
|
|
|
|
function createIterResult(value, done) {
|
|
return {
|
|
value: value,
|
|
done: done
|
|
};
|
|
}
|
|
|
|
function readAndResolve(iter) {
|
|
var resolve = iter[kLastResolve];
|
|
|
|
if (resolve !== null) {
|
|
var data = iter[kStream].read(); // we defer if data is null
|
|
// we can be expecting either 'end' or
|
|
// 'error'
|
|
|
|
if (data !== null) {
|
|
iter[kLastPromise] = null;
|
|
iter[kLastResolve] = null;
|
|
iter[kLastReject] = null;
|
|
resolve(createIterResult(data, false));
|
|
}
|
|
}
|
|
}
|
|
|
|
function onReadable(iter) {
|
|
// we wait for the next tick, because it might
|
|
// emit an error with process.nextTick
|
|
process.nextTick(readAndResolve, iter);
|
|
}
|
|
|
|
function wrapForNext(lastPromise, iter) {
|
|
return function (resolve, reject) {
|
|
lastPromise.then(function () {
|
|
if (iter[kEnded]) {
|
|
resolve(createIterResult(undefined, true));
|
|
return;
|
|
}
|
|
|
|
iter[kHandlePromise](resolve, reject);
|
|
}, reject);
|
|
};
|
|
}
|
|
|
|
var AsyncIteratorPrototype = Object.getPrototypeOf(function () {});
|
|
var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = {
|
|
get stream() {
|
|
return this[kStream];
|
|
},
|
|
|
|
next: function next() {
|
|
var _this = this;
|
|
|
|
// if we have detected an error in the meanwhile
|
|
// reject straight away
|
|
var error = this[kError];
|
|
|
|
if (error !== null) {
|
|
return Promise.reject(error);
|
|
}
|
|
|
|
if (this[kEnded]) {
|
|
return Promise.resolve(createIterResult(undefined, true));
|
|
}
|
|
|
|
if (this[kStream].destroyed) {
|
|
// We need to defer via nextTick because if .destroy(err) is
|
|
// called, the error will be emitted via nextTick, and
|
|
// we cannot guarantee that there is no error lingering around
|
|
// waiting to be emitted.
|
|
return new Promise(function (resolve, reject) {
|
|
process.nextTick(function () {
|
|
if (_this[kError]) {
|
|
reject(_this[kError]);
|
|
} else {
|
|
resolve(createIterResult(undefined, true));
|
|
}
|
|
});
|
|
});
|
|
} // if we have multiple next() calls
|
|
// we will wait for the previous Promise to finish
|
|
// this logic is optimized to support for await loops,
|
|
// where next() is only called once at a time
|
|
|
|
|
|
var lastPromise = this[kLastPromise];
|
|
var promise;
|
|
|
|
if (lastPromise) {
|
|
promise = new Promise(wrapForNext(lastPromise, this));
|
|
} else {
|
|
// fast path needed to support multiple this.push()
|
|
// without triggering the next() queue
|
|
var data = this[kStream].read();
|
|
|
|
if (data !== null) {
|
|
return Promise.resolve(createIterResult(data, false));
|
|
}
|
|
|
|
promise = new Promise(this[kHandlePromise]);
|
|
}
|
|
|
|
this[kLastPromise] = promise;
|
|
return promise;
|
|
}
|
|
}, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function () {
|
|
return this;
|
|
}), _defineProperty(_Object$setPrototypeO, "return", function _return() {
|
|
var _this2 = this;
|
|
|
|
// destroy(err, cb) is a private API
|
|
// we can guarantee we have that here, because we control the
|
|
// Readable class this is attached to
|
|
return new Promise(function (resolve, reject) {
|
|
_this2[kStream].destroy(null, function (err) {
|
|
if (err) {
|
|
reject(err);
|
|
return;
|
|
}
|
|
|
|
resolve(createIterResult(undefined, true));
|
|
});
|
|
});
|
|
}), _Object$setPrototypeO), AsyncIteratorPrototype);
|
|
|
|
var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) {
|
|
var _Object$create;
|
|
|
|
var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, {
|
|
value: stream,
|
|
writable: true
|
|
}), _defineProperty(_Object$create, kLastResolve, {
|
|
value: null,
|
|
writable: true
|
|
}), _defineProperty(_Object$create, kLastReject, {
|
|
value: null,
|
|
writable: true
|
|
}), _defineProperty(_Object$create, kError, {
|
|
value: null,
|
|
writable: true
|
|
}), _defineProperty(_Object$create, kEnded, {
|
|
value: stream._readableState.endEmitted,
|
|
writable: true
|
|
}), _defineProperty(_Object$create, kHandlePromise, {
|
|
value: function value(resolve, reject) {
|
|
var data = iterator[kStream].read();
|
|
|
|
if (data) {
|
|
iterator[kLastPromise] = null;
|
|
iterator[kLastResolve] = null;
|
|
iterator[kLastReject] = null;
|
|
resolve(createIterResult(data, false));
|
|
} else {
|
|
iterator[kLastResolve] = resolve;
|
|
iterator[kLastReject] = reject;
|
|
}
|
|
},
|
|
writable: true
|
|
}), _Object$create));
|
|
iterator[kLastPromise] = null;
|
|
finished(stream, function (err) {
|
|
if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {
|
|
var reject = iterator[kLastReject]; // reject if we are waiting for data in the Promise
|
|
// returned by next() and store the error
|
|
|
|
if (reject !== null) {
|
|
iterator[kLastPromise] = null;
|
|
iterator[kLastResolve] = null;
|
|
iterator[kLastReject] = null;
|
|
reject(err);
|
|
}
|
|
|
|
iterator[kError] = err;
|
|
return;
|
|
}
|
|
|
|
var resolve = iterator[kLastResolve];
|
|
|
|
if (resolve !== null) {
|
|
iterator[kLastPromise] = null;
|
|
iterator[kLastResolve] = null;
|
|
iterator[kLastReject] = null;
|
|
resolve(createIterResult(undefined, true));
|
|
}
|
|
|
|
iterator[kEnded] = true;
|
|
});
|
|
stream.on('readable', onReadable.bind(null, iterator));
|
|
return iterator;
|
|
};
|
|
|
|
module.exports = createReadableStreamAsyncIterator;
|
|
}).call(this)}).call(this,require('_process'))
|
|
|
|
},{"./end-of-stream":19,"_process":7}],17:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
|
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
|
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
|
|
var _require = require('buffer'),
|
|
Buffer = _require.Buffer;
|
|
|
|
var _require2 = require('util'),
|
|
inspect = _require2.inspect;
|
|
|
|
var custom = inspect && inspect.custom || 'inspect';
|
|
|
|
function copyBuffer(src, target, offset) {
|
|
Buffer.prototype.copy.call(src, target, offset);
|
|
}
|
|
|
|
module.exports =
|
|
/*#__PURE__*/
|
|
function () {
|
|
function BufferList() {
|
|
_classCallCheck(this, BufferList);
|
|
|
|
this.head = null;
|
|
this.tail = null;
|
|
this.length = 0;
|
|
}
|
|
|
|
_createClass(BufferList, [{
|
|
key: "push",
|
|
value: function push(v) {
|
|
var entry = {
|
|
data: v,
|
|
next: null
|
|
};
|
|
if (this.length > 0) this.tail.next = entry;else this.head = entry;
|
|
this.tail = entry;
|
|
++this.length;
|
|
}
|
|
}, {
|
|
key: "unshift",
|
|
value: function unshift(v) {
|
|
var entry = {
|
|
data: v,
|
|
next: this.head
|
|
};
|
|
if (this.length === 0) this.tail = entry;
|
|
this.head = entry;
|
|
++this.length;
|
|
}
|
|
}, {
|
|
key: "shift",
|
|
value: function shift() {
|
|
if (this.length === 0) return;
|
|
var ret = this.head.data;
|
|
if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
|
|
--this.length;
|
|
return ret;
|
|
}
|
|
}, {
|
|
key: "clear",
|
|
value: function clear() {
|
|
this.head = this.tail = null;
|
|
this.length = 0;
|
|
}
|
|
}, {
|
|
key: "join",
|
|
value: function join(s) {
|
|
if (this.length === 0) return '';
|
|
var p = this.head;
|
|
var ret = '' + p.data;
|
|
|
|
while (p = p.next) {
|
|
ret += s + p.data;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
}, {
|
|
key: "concat",
|
|
value: function concat(n) {
|
|
if (this.length === 0) return Buffer.alloc(0);
|
|
var ret = Buffer.allocUnsafe(n >>> 0);
|
|
var p = this.head;
|
|
var i = 0;
|
|
|
|
while (p) {
|
|
copyBuffer(p.data, ret, i);
|
|
i += p.data.length;
|
|
p = p.next;
|
|
}
|
|
|
|
return ret;
|
|
} // Consumes a specified amount of bytes or characters from the buffered data.
|
|
|
|
}, {
|
|
key: "consume",
|
|
value: function consume(n, hasStrings) {
|
|
var ret;
|
|
|
|
if (n < this.head.data.length) {
|
|
// `slice` is the same for buffers and strings.
|
|
ret = this.head.data.slice(0, n);
|
|
this.head.data = this.head.data.slice(n);
|
|
} else if (n === this.head.data.length) {
|
|
// First chunk is a perfect match.
|
|
ret = this.shift();
|
|
} else {
|
|
// Result spans more than one buffer.
|
|
ret = hasStrings ? this._getString(n) : this._getBuffer(n);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
}, {
|
|
key: "first",
|
|
value: function first() {
|
|
return this.head.data;
|
|
} // Consumes a specified amount of characters from the buffered data.
|
|
|
|
}, {
|
|
key: "_getString",
|
|
value: function _getString(n) {
|
|
var p = this.head;
|
|
var c = 1;
|
|
var ret = p.data;
|
|
n -= ret.length;
|
|
|
|
while (p = p.next) {
|
|
var str = p.data;
|
|
var nb = n > str.length ? str.length : n;
|
|
if (nb === str.length) ret += str;else ret += str.slice(0, n);
|
|
n -= nb;
|
|
|
|
if (n === 0) {
|
|
if (nb === str.length) {
|
|
++c;
|
|
if (p.next) this.head = p.next;else this.head = this.tail = null;
|
|
} else {
|
|
this.head = p;
|
|
p.data = str.slice(nb);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
++c;
|
|
}
|
|
|
|
this.length -= c;
|
|
return ret;
|
|
} // Consumes a specified amount of bytes from the buffered data.
|
|
|
|
}, {
|
|
key: "_getBuffer",
|
|
value: function _getBuffer(n) {
|
|
var ret = Buffer.allocUnsafe(n);
|
|
var p = this.head;
|
|
var c = 1;
|
|
p.data.copy(ret);
|
|
n -= p.data.length;
|
|
|
|
while (p = p.next) {
|
|
var buf = p.data;
|
|
var nb = n > buf.length ? buf.length : n;
|
|
buf.copy(ret, ret.length - n, 0, nb);
|
|
n -= nb;
|
|
|
|
if (n === 0) {
|
|
if (nb === buf.length) {
|
|
++c;
|
|
if (p.next) this.head = p.next;else this.head = this.tail = null;
|
|
} else {
|
|
this.head = p;
|
|
p.data = buf.slice(nb);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
++c;
|
|
}
|
|
|
|
this.length -= c;
|
|
return ret;
|
|
} // Make sure the linked list only shows the minimal necessary information.
|
|
|
|
}, {
|
|
key: custom,
|
|
value: function value(_, options) {
|
|
return inspect(this, _objectSpread({}, options, {
|
|
// Only inspect one level.
|
|
depth: 0,
|
|
// It should not recurse.
|
|
customInspect: false
|
|
}));
|
|
}
|
|
}]);
|
|
|
|
return BufferList;
|
|
}();
|
|
},{"buffer":3,"util":2}],18:[function(require,module,exports){
|
|
(function (process){(function (){
|
|
'use strict'; // undocumented cb() API, needed for core, not for public API
|
|
|
|
function destroy(err, cb) {
|
|
var _this = this;
|
|
|
|
var readableDestroyed = this._readableState && this._readableState.destroyed;
|
|
var writableDestroyed = this._writableState && this._writableState.destroyed;
|
|
|
|
if (readableDestroyed || writableDestroyed) {
|
|
if (cb) {
|
|
cb(err);
|
|
} else if (err) {
|
|
if (!this._writableState) {
|
|
process.nextTick(emitErrorNT, this, err);
|
|
} else if (!this._writableState.errorEmitted) {
|
|
this._writableState.errorEmitted = true;
|
|
process.nextTick(emitErrorNT, this, err);
|
|
}
|
|
}
|
|
|
|
return this;
|
|
} // we set destroyed to true before firing error callbacks in order
|
|
// to make it re-entrance safe in case destroy() is called within callbacks
|
|
|
|
|
|
if (this._readableState) {
|
|
this._readableState.destroyed = true;
|
|
} // if this is a duplex stream mark the writable part as destroyed as well
|
|
|
|
|
|
if (this._writableState) {
|
|
this._writableState.destroyed = true;
|
|
}
|
|
|
|
this._destroy(err || null, function (err) {
|
|
if (!cb && err) {
|
|
if (!_this._writableState) {
|
|
process.nextTick(emitErrorAndCloseNT, _this, err);
|
|
} else if (!_this._writableState.errorEmitted) {
|
|
_this._writableState.errorEmitted = true;
|
|
process.nextTick(emitErrorAndCloseNT, _this, err);
|
|
} else {
|
|
process.nextTick(emitCloseNT, _this);
|
|
}
|
|
} else if (cb) {
|
|
process.nextTick(emitCloseNT, _this);
|
|
cb(err);
|
|
} else {
|
|
process.nextTick(emitCloseNT, _this);
|
|
}
|
|
});
|
|
|
|
return this;
|
|
}
|
|
|
|
function emitErrorAndCloseNT(self, err) {
|
|
emitErrorNT(self, err);
|
|
emitCloseNT(self);
|
|
}
|
|
|
|
function emitCloseNT(self) {
|
|
if (self._writableState && !self._writableState.emitClose) return;
|
|
if (self._readableState && !self._readableState.emitClose) return;
|
|
self.emit('close');
|
|
}
|
|
|
|
function undestroy() {
|
|
if (this._readableState) {
|
|
this._readableState.destroyed = false;
|
|
this._readableState.reading = false;
|
|
this._readableState.ended = false;
|
|
this._readableState.endEmitted = false;
|
|
}
|
|
|
|
if (this._writableState) {
|
|
this._writableState.destroyed = false;
|
|
this._writableState.ended = false;
|
|
this._writableState.ending = false;
|
|
this._writableState.finalCalled = false;
|
|
this._writableState.prefinished = false;
|
|
this._writableState.finished = false;
|
|
this._writableState.errorEmitted = false;
|
|
}
|
|
}
|
|
|
|
function emitErrorNT(self, err) {
|
|
self.emit('error', err);
|
|
}
|
|
|
|
function errorOrDestroy(stream, err) {
|
|
// We have tests that rely on errors being emitted
|
|
// in the same tick, so changing this is semver major.
|
|
// For now when you opt-in to autoDestroy we allow
|
|
// the error to be emitted nextTick. In a future
|
|
// semver major update we should change the default to this.
|
|
var rState = stream._readableState;
|
|
var wState = stream._writableState;
|
|
if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err);
|
|
}
|
|
|
|
module.exports = {
|
|
destroy: destroy,
|
|
undestroy: undestroy,
|
|
errorOrDestroy: errorOrDestroy
|
|
};
|
|
}).call(this)}).call(this,require('_process'))
|
|
|
|
},{"_process":7}],19:[function(require,module,exports){
|
|
// Ported from https://github.com/mafintosh/end-of-stream with
|
|
// permission from the author, Mathias Buus (@mafintosh).
|
|
'use strict';
|
|
|
|
var ERR_STREAM_PREMATURE_CLOSE = require('../../../errors').codes.ERR_STREAM_PREMATURE_CLOSE;
|
|
|
|
function once(callback) {
|
|
var called = false;
|
|
return function () {
|
|
if (called) return;
|
|
called = true;
|
|
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
|
|
callback.apply(this, args);
|
|
};
|
|
}
|
|
|
|
function noop() {}
|
|
|
|
function isRequest(stream) {
|
|
return stream.setHeader && typeof stream.abort === 'function';
|
|
}
|
|
|
|
function eos(stream, opts, callback) {
|
|
if (typeof opts === 'function') return eos(stream, null, opts);
|
|
if (!opts) opts = {};
|
|
callback = once(callback || noop);
|
|
var readable = opts.readable || opts.readable !== false && stream.readable;
|
|
var writable = opts.writable || opts.writable !== false && stream.writable;
|
|
|
|
var onlegacyfinish = function onlegacyfinish() {
|
|
if (!stream.writable) onfinish();
|
|
};
|
|
|
|
var writableEnded = stream._writableState && stream._writableState.finished;
|
|
|
|
var onfinish = function onfinish() {
|
|
writable = false;
|
|
writableEnded = true;
|
|
if (!readable) callback.call(stream);
|
|
};
|
|
|
|
var readableEnded = stream._readableState && stream._readableState.endEmitted;
|
|
|
|
var onend = function onend() {
|
|
readable = false;
|
|
readableEnded = true;
|
|
if (!writable) callback.call(stream);
|
|
};
|
|
|
|
var onerror = function onerror(err) {
|
|
callback.call(stream, err);
|
|
};
|
|
|
|
var onclose = function onclose() {
|
|
var err;
|
|
|
|
if (readable && !readableEnded) {
|
|
if (!stream._readableState || !stream._readableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE();
|
|
return callback.call(stream, err);
|
|
}
|
|
|
|
if (writable && !writableEnded) {
|
|
if (!stream._writableState || !stream._writableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE();
|
|
return callback.call(stream, err);
|
|
}
|
|
};
|
|
|
|
var onrequest = function onrequest() {
|
|
stream.req.on('finish', onfinish);
|
|
};
|
|
|
|
if (isRequest(stream)) {
|
|
stream.on('complete', onfinish);
|
|
stream.on('abort', onclose);
|
|
if (stream.req) onrequest();else stream.on('request', onrequest);
|
|
} else if (writable && !stream._writableState) {
|
|
// legacy streams
|
|
stream.on('end', onlegacyfinish);
|
|
stream.on('close', onlegacyfinish);
|
|
}
|
|
|
|
stream.on('end', onend);
|
|
stream.on('finish', onfinish);
|
|
if (opts.error !== false) stream.on('error', onerror);
|
|
stream.on('close', onclose);
|
|
return function () {
|
|
stream.removeListener('complete', onfinish);
|
|
stream.removeListener('abort', onclose);
|
|
stream.removeListener('request', onrequest);
|
|
if (stream.req) stream.req.removeListener('finish', onfinish);
|
|
stream.removeListener('end', onlegacyfinish);
|
|
stream.removeListener('close', onlegacyfinish);
|
|
stream.removeListener('finish', onfinish);
|
|
stream.removeListener('end', onend);
|
|
stream.removeListener('error', onerror);
|
|
stream.removeListener('close', onclose);
|
|
};
|
|
}
|
|
|
|
module.exports = eos;
|
|
},{"../../../errors":10}],20:[function(require,module,exports){
|
|
module.exports = function () {
|
|
throw new Error('Readable.from is not available in the browser')
|
|
};
|
|
|
|
},{}],21:[function(require,module,exports){
|
|
// Ported from https://github.com/mafintosh/pump with
|
|
// permission from the author, Mathias Buus (@mafintosh).
|
|
'use strict';
|
|
|
|
var eos;
|
|
|
|
function once(callback) {
|
|
var called = false;
|
|
return function () {
|
|
if (called) return;
|
|
called = true;
|
|
callback.apply(void 0, arguments);
|
|
};
|
|
}
|
|
|
|
var _require$codes = require('../../../errors').codes,
|
|
ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS,
|
|
ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED;
|
|
|
|
function noop(err) {
|
|
// Rethrow the error if it exists to avoid swallowing it
|
|
if (err) throw err;
|
|
}
|
|
|
|
function isRequest(stream) {
|
|
return stream.setHeader && typeof stream.abort === 'function';
|
|
}
|
|
|
|
function destroyer(stream, reading, writing, callback) {
|
|
callback = once(callback);
|
|
var closed = false;
|
|
stream.on('close', function () {
|
|
closed = true;
|
|
});
|
|
if (eos === undefined) eos = require('./end-of-stream');
|
|
eos(stream, {
|
|
readable: reading,
|
|
writable: writing
|
|
}, function (err) {
|
|
if (err) return callback(err);
|
|
closed = true;
|
|
callback();
|
|
});
|
|
var destroyed = false;
|
|
return function (err) {
|
|
if (closed) return;
|
|
if (destroyed) return;
|
|
destroyed = true; // request.destroy just do .end - .abort is what we want
|
|
|
|
if (isRequest(stream)) return stream.abort();
|
|
if (typeof stream.destroy === 'function') return stream.destroy();
|
|
callback(err || new ERR_STREAM_DESTROYED('pipe'));
|
|
};
|
|
}
|
|
|
|
function call(fn) {
|
|
fn();
|
|
}
|
|
|
|
function pipe(from, to) {
|
|
return from.pipe(to);
|
|
}
|
|
|
|
function popCallback(streams) {
|
|
if (!streams.length) return noop;
|
|
if (typeof streams[streams.length - 1] !== 'function') return noop;
|
|
return streams.pop();
|
|
}
|
|
|
|
function pipeline() {
|
|
for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
streams[_key] = arguments[_key];
|
|
}
|
|
|
|
var callback = popCallback(streams);
|
|
if (Array.isArray(streams[0])) streams = streams[0];
|
|
|
|
if (streams.length < 2) {
|
|
throw new ERR_MISSING_ARGS('streams');
|
|
}
|
|
|
|
var error;
|
|
var destroys = streams.map(function (stream, i) {
|
|
var reading = i < streams.length - 1;
|
|
var writing = i > 0;
|
|
return destroyer(stream, reading, writing, function (err) {
|
|
if (!error) error = err;
|
|
if (err) destroys.forEach(call);
|
|
if (reading) return;
|
|
destroys.forEach(call);
|
|
callback(error);
|
|
});
|
|
});
|
|
return streams.reduce(pipe);
|
|
}
|
|
|
|
module.exports = pipeline;
|
|
},{"../../../errors":10,"./end-of-stream":19}],22:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var ERR_INVALID_OPT_VALUE = require('../../../errors').codes.ERR_INVALID_OPT_VALUE;
|
|
|
|
function highWaterMarkFrom(options, isDuplex, duplexKey) {
|
|
return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null;
|
|
}
|
|
|
|
function getHighWaterMark(state, options, duplexKey, isDuplex) {
|
|
var hwm = highWaterMarkFrom(options, isDuplex, duplexKey);
|
|
|
|
if (hwm != null) {
|
|
if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) {
|
|
var name = isDuplex ? duplexKey : 'highWaterMark';
|
|
throw new ERR_INVALID_OPT_VALUE(name, hwm);
|
|
}
|
|
|
|
return Math.floor(hwm);
|
|
} // Default value
|
|
|
|
|
|
return state.objectMode ? 16 : 16 * 1024;
|
|
}
|
|
|
|
module.exports = {
|
|
getHighWaterMark: getHighWaterMark
|
|
};
|
|
},{"../../../errors":10}],23:[function(require,module,exports){
|
|
module.exports = require('events').EventEmitter;
|
|
|
|
},{"events":4}],24:[function(require,module,exports){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
'use strict';
|
|
|
|
/*<replacement>*/
|
|
|
|
var Buffer = require('safe-buffer').Buffer;
|
|
/*</replacement>*/
|
|
|
|
var isEncoding = Buffer.isEncoding || function (encoding) {
|
|
encoding = '' + encoding;
|
|
switch (encoding && encoding.toLowerCase()) {
|
|
case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw':
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
};
|
|
|
|
function _normalizeEncoding(enc) {
|
|
if (!enc) return 'utf8';
|
|
var retried;
|
|
while (true) {
|
|
switch (enc) {
|
|
case 'utf8':
|
|
case 'utf-8':
|
|
return 'utf8';
|
|
case 'ucs2':
|
|
case 'ucs-2':
|
|
case 'utf16le':
|
|
case 'utf-16le':
|
|
return 'utf16le';
|
|
case 'latin1':
|
|
case 'binary':
|
|
return 'latin1';
|
|
case 'base64':
|
|
case 'ascii':
|
|
case 'hex':
|
|
return enc;
|
|
default:
|
|
if (retried) return; // undefined
|
|
enc = ('' + enc).toLowerCase();
|
|
retried = true;
|
|
}
|
|
}
|
|
};
|
|
|
|
// Do not cache `Buffer.isEncoding` when checking encoding names as some
|
|
// modules monkey-patch it to support additional encodings
|
|
function normalizeEncoding(enc) {
|
|
var nenc = _normalizeEncoding(enc);
|
|
if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
|
|
return nenc || enc;
|
|
}
|
|
|
|
// StringDecoder provides an interface for efficiently splitting a series of
|
|
// buffers into a series of JS strings without breaking apart multi-byte
|
|
// characters.
|
|
exports.StringDecoder = StringDecoder;
|
|
function StringDecoder(encoding) {
|
|
this.encoding = normalizeEncoding(encoding);
|
|
var nb;
|
|
switch (this.encoding) {
|
|
case 'utf16le':
|
|
this.text = utf16Text;
|
|
this.end = utf16End;
|
|
nb = 4;
|
|
break;
|
|
case 'utf8':
|
|
this.fillLast = utf8FillLast;
|
|
nb = 4;
|
|
break;
|
|
case 'base64':
|
|
this.text = base64Text;
|
|
this.end = base64End;
|
|
nb = 3;
|
|
break;
|
|
default:
|
|
this.write = simpleWrite;
|
|
this.end = simpleEnd;
|
|
return;
|
|
}
|
|
this.lastNeed = 0;
|
|
this.lastTotal = 0;
|
|
this.lastChar = Buffer.allocUnsafe(nb);
|
|
}
|
|
|
|
StringDecoder.prototype.write = function (buf) {
|
|
if (buf.length === 0) return '';
|
|
var r;
|
|
var i;
|
|
if (this.lastNeed) {
|
|
r = this.fillLast(buf);
|
|
if (r === undefined) return '';
|
|
i = this.lastNeed;
|
|
this.lastNeed = 0;
|
|
} else {
|
|
i = 0;
|
|
}
|
|
if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
|
|
return r || '';
|
|
};
|
|
|
|
StringDecoder.prototype.end = utf8End;
|
|
|
|
// Returns only complete characters in a Buffer
|
|
StringDecoder.prototype.text = utf8Text;
|
|
|
|
// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
|
|
StringDecoder.prototype.fillLast = function (buf) {
|
|
if (this.lastNeed <= buf.length) {
|
|
buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
|
|
return this.lastChar.toString(this.encoding, 0, this.lastTotal);
|
|
}
|
|
buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
|
|
this.lastNeed -= buf.length;
|
|
};
|
|
|
|
// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
|
|
// continuation byte. If an invalid byte is detected, -2 is returned.
|
|
function utf8CheckByte(byte) {
|
|
if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
|
|
return byte >> 6 === 0x02 ? -1 : -2;
|
|
}
|
|
|
|
// Checks at most 3 bytes at the end of a Buffer in order to detect an
|
|
// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
|
|
// needed to complete the UTF-8 character (if applicable) are returned.
|
|
function utf8CheckIncomplete(self, buf, i) {
|
|
var j = buf.length - 1;
|
|
if (j < i) return 0;
|
|
var nb = utf8CheckByte(buf[j]);
|
|
if (nb >= 0) {
|
|
if (nb > 0) self.lastNeed = nb - 1;
|
|
return nb;
|
|
}
|
|
if (--j < i || nb === -2) return 0;
|
|
nb = utf8CheckByte(buf[j]);
|
|
if (nb >= 0) {
|
|
if (nb > 0) self.lastNeed = nb - 2;
|
|
return nb;
|
|
}
|
|
if (--j < i || nb === -2) return 0;
|
|
nb = utf8CheckByte(buf[j]);
|
|
if (nb >= 0) {
|
|
if (nb > 0) {
|
|
if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
|
|
}
|
|
return nb;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Validates as many continuation bytes for a multi-byte UTF-8 character as
|
|
// needed or are available. If we see a non-continuation byte where we expect
|
|
// one, we "replace" the validated continuation bytes we've seen so far with
|
|
// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
|
|
// behavior. The continuation byte check is included three times in the case
|
|
// where all of the continuation bytes for a character exist in the same buffer.
|
|
// It is also done this way as a slight performance increase instead of using a
|
|
// loop.
|
|
function utf8CheckExtraBytes(self, buf, p) {
|
|
if ((buf[0] & 0xC0) !== 0x80) {
|
|
self.lastNeed = 0;
|
|
return '\ufffd';
|
|
}
|
|
if (self.lastNeed > 1 && buf.length > 1) {
|
|
if ((buf[1] & 0xC0) !== 0x80) {
|
|
self.lastNeed = 1;
|
|
return '\ufffd';
|
|
}
|
|
if (self.lastNeed > 2 && buf.length > 2) {
|
|
if ((buf[2] & 0xC0) !== 0x80) {
|
|
self.lastNeed = 2;
|
|
return '\ufffd';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
|
|
function utf8FillLast(buf) {
|
|
var p = this.lastTotal - this.lastNeed;
|
|
var r = utf8CheckExtraBytes(this, buf, p);
|
|
if (r !== undefined) return r;
|
|
if (this.lastNeed <= buf.length) {
|
|
buf.copy(this.lastChar, p, 0, this.lastNeed);
|
|
return this.lastChar.toString(this.encoding, 0, this.lastTotal);
|
|
}
|
|
buf.copy(this.lastChar, p, 0, buf.length);
|
|
this.lastNeed -= buf.length;
|
|
}
|
|
|
|
// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
|
|
// partial character, the character's bytes are buffered until the required
|
|
// number of bytes are available.
|
|
function utf8Text(buf, i) {
|
|
var total = utf8CheckIncomplete(this, buf, i);
|
|
if (!this.lastNeed) return buf.toString('utf8', i);
|
|
this.lastTotal = total;
|
|
var end = buf.length - (total - this.lastNeed);
|
|
buf.copy(this.lastChar, 0, end);
|
|
return buf.toString('utf8', i, end);
|
|
}
|
|
|
|
// For UTF-8, a replacement character is added when ending on a partial
|
|
// character.
|
|
function utf8End(buf) {
|
|
var r = buf && buf.length ? this.write(buf) : '';
|
|
if (this.lastNeed) return r + '\ufffd';
|
|
return r;
|
|
}
|
|
|
|
// UTF-16LE typically needs two bytes per character, but even if we have an even
|
|
// number of bytes available, we need to check if we end on a leading/high
|
|
// surrogate. In that case, we need to wait for the next two bytes in order to
|
|
// decode the last character properly.
|
|
function utf16Text(buf, i) {
|
|
if ((buf.length - i) % 2 === 0) {
|
|
var r = buf.toString('utf16le', i);
|
|
if (r) {
|
|
var c = r.charCodeAt(r.length - 1);
|
|
if (c >= 0xD800 && c <= 0xDBFF) {
|
|
this.lastNeed = 2;
|
|
this.lastTotal = 4;
|
|
this.lastChar[0] = buf[buf.length - 2];
|
|
this.lastChar[1] = buf[buf.length - 1];
|
|
return r.slice(0, -1);
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
this.lastNeed = 1;
|
|
this.lastTotal = 2;
|
|
this.lastChar[0] = buf[buf.length - 1];
|
|
return buf.toString('utf16le', i, buf.length - 1);
|
|
}
|
|
|
|
// For UTF-16LE we do not explicitly append special replacement characters if we
|
|
// end on a partial character, we simply let v8 handle that.
|
|
function utf16End(buf) {
|
|
var r = buf && buf.length ? this.write(buf) : '';
|
|
if (this.lastNeed) {
|
|
var end = this.lastTotal - this.lastNeed;
|
|
return r + this.lastChar.toString('utf16le', 0, end);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
function base64Text(buf, i) {
|
|
var n = (buf.length - i) % 3;
|
|
if (n === 0) return buf.toString('base64', i);
|
|
this.lastNeed = 3 - n;
|
|
this.lastTotal = 3;
|
|
if (n === 1) {
|
|
this.lastChar[0] = buf[buf.length - 1];
|
|
} else {
|
|
this.lastChar[0] = buf[buf.length - 2];
|
|
this.lastChar[1] = buf[buf.length - 1];
|
|
}
|
|
return buf.toString('base64', i, buf.length - n);
|
|
}
|
|
|
|
function base64End(buf) {
|
|
var r = buf && buf.length ? this.write(buf) : '';
|
|
if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
|
|
return r;
|
|
}
|
|
|
|
// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
|
|
function simpleWrite(buf) {
|
|
return buf.toString(this.encoding);
|
|
}
|
|
|
|
function simpleEnd(buf) {
|
|
return buf && buf.length ? this.write(buf) : '';
|
|
}
|
|
},{"safe-buffer":8}],25:[function(require,module,exports){
|
|
(function (setImmediate,clearImmediate){(function (){
|
|
var nextTick = require('process/browser.js').nextTick;
|
|
var apply = Function.prototype.apply;
|
|
var slice = Array.prototype.slice;
|
|
var immediateIds = {};
|
|
var nextImmediateId = 0;
|
|
|
|
// DOM APIs, for completeness
|
|
|
|
exports.setTimeout = function() {
|
|
return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
|
|
};
|
|
exports.setInterval = function() {
|
|
return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
|
|
};
|
|
exports.clearTimeout =
|
|
exports.clearInterval = function(timeout) { timeout.close(); };
|
|
|
|
function Timeout(id, clearFn) {
|
|
this._id = id;
|
|
this._clearFn = clearFn;
|
|
}
|
|
Timeout.prototype.unref = Timeout.prototype.ref = function() {};
|
|
Timeout.prototype.close = function() {
|
|
this._clearFn.call(window, this._id);
|
|
};
|
|
|
|
// Does not start the time, just sets up the members needed.
|
|
exports.enroll = function(item, msecs) {
|
|
clearTimeout(item._idleTimeoutId);
|
|
item._idleTimeout = msecs;
|
|
};
|
|
|
|
exports.unenroll = function(item) {
|
|
clearTimeout(item._idleTimeoutId);
|
|
item._idleTimeout = -1;
|
|
};
|
|
|
|
exports._unrefActive = exports.active = function(item) {
|
|
clearTimeout(item._idleTimeoutId);
|
|
|
|
var msecs = item._idleTimeout;
|
|
if (msecs >= 0) {
|
|
item._idleTimeoutId = setTimeout(function onTimeout() {
|
|
if (item._onTimeout)
|
|
item._onTimeout();
|
|
}, msecs);
|
|
}
|
|
};
|
|
|
|
// That's not how node.js implements it but the exposed api is the same.
|
|
exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) {
|
|
var id = nextImmediateId++;
|
|
var args = arguments.length < 2 ? false : slice.call(arguments, 1);
|
|
|
|
immediateIds[id] = true;
|
|
|
|
nextTick(function onNextTick() {
|
|
if (immediateIds[id]) {
|
|
// fn.call() is faster so we optimize for the common use-case
|
|
// @see http://jsperf.com/call-apply-segu
|
|
if (args) {
|
|
fn.apply(null, args);
|
|
} else {
|
|
fn.call(null);
|
|
}
|
|
// Prevent ids from leaking
|
|
exports.clearImmediate(id);
|
|
}
|
|
});
|
|
|
|
return id;
|
|
};
|
|
|
|
exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) {
|
|
delete immediateIds[id];
|
|
};
|
|
}).call(this)}).call(this,require("timers").setImmediate,require("timers").clearImmediate)
|
|
|
|
},{"process/browser.js":7,"timers":25}],26:[function(require,module,exports){
|
|
(function (global){(function (){
|
|
|
|
/**
|
|
* 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)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
|
|
},{}],27:[function(require,module,exports){
|
|
/**
|
|
* Panzoom for panning and zooming elements using CSS transforms
|
|
* Copyright Timmy Willison and other contributors
|
|
* https://github.com/timmywil/panzoom/blob/master/MIT-License.txt
|
|
*/
|
|
(function (global, factory) {
|
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Panzoom = factory());
|
|
}(this, (function () { 'use strict';
|
|
|
|
/*! *****************************************************************************
|
|
Copyright (c) Microsoft Corporation.
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|
***************************************************************************** */
|
|
|
|
var __assign = function() {
|
|
__assign = Object.assign || function __assign(t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
|
|
/* eslint-disable no-var */
|
|
if (typeof window !== 'undefined') {
|
|
// Support: IE11 only
|
|
if (window.NodeList && !NodeList.prototype.forEach) {
|
|
NodeList.prototype.forEach = Array.prototype.forEach;
|
|
}
|
|
// Support: IE11 only
|
|
// CustomEvent is an object instead of a constructor
|
|
if (typeof window.CustomEvent !== 'function') {
|
|
window.CustomEvent = function CustomEvent(event, params) {
|
|
params = params || { bubbles: false, cancelable: false, detail: null };
|
|
var evt = document.createEvent('CustomEvent');
|
|
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
|
|
return evt
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Utilites for working with multiple pointer events
|
|
*/
|
|
function findEventIndex(pointers, event) {
|
|
var i = pointers.length;
|
|
while (i--) {
|
|
if (pointers[i].pointerId === event.pointerId) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
function addPointer(pointers, event) {
|
|
var i;
|
|
// Add touches if applicable
|
|
if (event.touches) {
|
|
i = 0;
|
|
for (var _i = 0, _a = event.touches; _i < _a.length; _i++) {
|
|
var touch = _a[_i];
|
|
touch.pointerId = i++;
|
|
addPointer(pointers, touch);
|
|
}
|
|
return;
|
|
}
|
|
i = findEventIndex(pointers, event);
|
|
// Update if already present
|
|
if (i > -1) {
|
|
pointers.splice(i, 1);
|
|
}
|
|
pointers.push(event);
|
|
}
|
|
function removePointer(pointers, event) {
|
|
// Add touches if applicable
|
|
if (event.touches) {
|
|
// Remove all touches
|
|
while (pointers.length) {
|
|
pointers.pop();
|
|
}
|
|
return;
|
|
}
|
|
var i = findEventIndex(pointers, event);
|
|
if (i > -1) {
|
|
pointers.splice(i, 1);
|
|
}
|
|
}
|
|
/**
|
|
* Calculates a center point between
|
|
* the given pointer events, for panning
|
|
* with multiple pointers.
|
|
*/
|
|
function getMiddle(pointers) {
|
|
// Copy to avoid changing by reference
|
|
pointers = pointers.slice(0);
|
|
var event1 = pointers.pop();
|
|
var event2;
|
|
while ((event2 = pointers.pop())) {
|
|
event1 = {
|
|
clientX: (event2.clientX - event1.clientX) / 2 + event1.clientX,
|
|
clientY: (event2.clientY - event1.clientY) / 2 + event1.clientY
|
|
};
|
|
}
|
|
return event1;
|
|
}
|
|
/**
|
|
* Calculates the distance between two points
|
|
* for pinch zooming.
|
|
* Limits to the first 2
|
|
*/
|
|
function getDistance(pointers) {
|
|
if (pointers.length < 2) {
|
|
return 0;
|
|
}
|
|
var event1 = pointers[0];
|
|
var event2 = pointers[1];
|
|
return Math.sqrt(Math.pow(Math.abs(event2.clientX - event1.clientX), 2) +
|
|
Math.pow(Math.abs(event2.clientY - event1.clientY), 2));
|
|
}
|
|
|
|
var events = {
|
|
down: 'mousedown',
|
|
move: 'mousemove',
|
|
up: 'mouseup mouseleave'
|
|
};
|
|
if (typeof window !== 'undefined') {
|
|
if (typeof window.PointerEvent === 'function') {
|
|
events = {
|
|
down: 'pointerdown',
|
|
move: 'pointermove',
|
|
up: 'pointerup pointerleave pointercancel'
|
|
};
|
|
}
|
|
else if (typeof window.TouchEvent === 'function') {
|
|
events = {
|
|
down: 'touchstart',
|
|
move: 'touchmove',
|
|
up: 'touchend touchcancel'
|
|
};
|
|
}
|
|
}
|
|
function onPointer(event, elem, handler, eventOpts) {
|
|
events[event].split(' ').forEach(function (name) {
|
|
elem.addEventListener(name, handler, eventOpts);
|
|
});
|
|
}
|
|
function destroyPointer(event, elem, handler) {
|
|
events[event].split(' ').forEach(function (name) {
|
|
elem.removeEventListener(name, handler);
|
|
});
|
|
}
|
|
|
|
var isIE = typeof document !== 'undefined' && !!document.documentMode;
|
|
/**
|
|
* Lazy creation of a CSS style declaration
|
|
*/
|
|
var divStyle;
|
|
function createStyle() {
|
|
if (divStyle) {
|
|
return divStyle;
|
|
}
|
|
return (divStyle = document.createElement('div').style);
|
|
}
|
|
/**
|
|
* Proper prefixing for cross-browser compatibility
|
|
*/
|
|
var prefixes = ['webkit', 'moz', 'ms'];
|
|
var prefixCache = {};
|
|
function getPrefixedName(name) {
|
|
if (prefixCache[name]) {
|
|
return prefixCache[name];
|
|
}
|
|
var divStyle = createStyle();
|
|
if (name in divStyle) {
|
|
return (prefixCache[name] = name);
|
|
}
|
|
var capName = name[0].toUpperCase() + name.slice(1);
|
|
var i = prefixes.length;
|
|
while (i--) {
|
|
var prefixedName = "" + prefixes[i] + capName;
|
|
if (prefixedName in divStyle) {
|
|
return (prefixCache[name] = prefixedName);
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Gets a style value expected to be a number
|
|
*/
|
|
function getCSSNum(name, style) {
|
|
return parseFloat(style[getPrefixedName(name)]) || 0;
|
|
}
|
|
function getBoxStyle(elem, name, style) {
|
|
if (style === void 0) { style = window.getComputedStyle(elem); }
|
|
// Support: FF 68+
|
|
// Firefox requires specificity for border
|
|
var suffix = name === 'border' ? 'Width' : '';
|
|
return {
|
|
left: getCSSNum(name + "Left" + suffix, style),
|
|
right: getCSSNum(name + "Right" + suffix, style),
|
|
top: getCSSNum(name + "Top" + suffix, style),
|
|
bottom: getCSSNum(name + "Bottom" + suffix, style)
|
|
};
|
|
}
|
|
/**
|
|
* Set a style using the properly prefixed name
|
|
*/
|
|
function setStyle(elem, name, value) {
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
elem.style[getPrefixedName(name)] = value;
|
|
}
|
|
/**
|
|
* Constructs the transition from panzoom options
|
|
* and takes care of prefixing the transition and transform
|
|
*/
|
|
function setTransition(elem, options) {
|
|
var transform = getPrefixedName('transform');
|
|
setStyle(elem, 'transition', transform + " " + options.duration + "ms " + options.easing);
|
|
}
|
|
/**
|
|
* Set the transform using the proper prefix
|
|
*/
|
|
function setTransform(elem, _a, _options) {
|
|
var x = _a.x, y = _a.y, scale = _a.scale, isSVG = _a.isSVG;
|
|
setStyle(elem, 'transform', "scale(" + scale + ") translate(" + x + "px, " + y + "px)");
|
|
if (isSVG && isIE) {
|
|
var matrixValue = window.getComputedStyle(elem).getPropertyValue('transform');
|
|
elem.setAttribute('transform', matrixValue);
|
|
}
|
|
}
|
|
/**
|
|
* Dimensions used in containment and focal point zooming
|
|
*/
|
|
function getDimensions(elem) {
|
|
var parent = elem.parentNode;
|
|
var style = window.getComputedStyle(elem);
|
|
var parentStyle = window.getComputedStyle(parent);
|
|
var rectElem = elem.getBoundingClientRect();
|
|
var rectParent = parent.getBoundingClientRect();
|
|
return {
|
|
elem: {
|
|
style: style,
|
|
width: rectElem.width,
|
|
height: rectElem.height,
|
|
top: rectElem.top,
|
|
bottom: rectElem.bottom,
|
|
left: rectElem.left,
|
|
right: rectElem.right,
|
|
margin: getBoxStyle(elem, 'margin', style),
|
|
border: getBoxStyle(elem, 'border', style)
|
|
},
|
|
parent: {
|
|
style: parentStyle,
|
|
width: rectParent.width,
|
|
height: rectParent.height,
|
|
top: rectParent.top,
|
|
bottom: rectParent.bottom,
|
|
left: rectParent.left,
|
|
right: rectParent.right,
|
|
padding: getBoxStyle(parent, 'padding', parentStyle),
|
|
border: getBoxStyle(parent, 'border', parentStyle)
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Determine if an element is attached to the DOM
|
|
* Panzoom requires this so events work properly
|
|
*/
|
|
function isAttached(elem) {
|
|
var doc = elem.ownerDocument;
|
|
var parent = elem.parentNode;
|
|
return (doc &&
|
|
parent &&
|
|
doc.nodeType === 9 &&
|
|
parent.nodeType === 1 &&
|
|
doc.documentElement.contains(parent));
|
|
}
|
|
|
|
function getClass(elem) {
|
|
return (elem.getAttribute('class') || '').trim();
|
|
}
|
|
function hasClass(elem, className) {
|
|
return elem.nodeType === 1 && (" " + getClass(elem) + " ").indexOf(" " + className + " ") > -1;
|
|
}
|
|
function isExcluded(elem, options) {
|
|
for (var cur = elem; cur != null; cur = cur.parentNode) {
|
|
if (hasClass(cur, options.excludeClass) || options.exclude.indexOf(cur) > -1) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Determine if an element is SVG by checking the namespace
|
|
* Exception: the <svg> element itself should be treated like HTML
|
|
*/
|
|
var rsvg = /^http:[\w\.\/]+svg$/;
|
|
function isSVGElement(elem) {
|
|
return rsvg.test(elem.namespaceURI) && elem.nodeName.toLowerCase() !== 'svg';
|
|
}
|
|
|
|
function shallowClone(obj) {
|
|
var clone = {};
|
|
for (var key in obj) {
|
|
if (obj.hasOwnProperty(key)) {
|
|
clone[key] = obj[key];
|
|
}
|
|
}
|
|
return clone;
|
|
}
|
|
|
|
var defaultOptions = {
|
|
animate: false,
|
|
canvas: false,
|
|
cursor: 'move',
|
|
disablePan: false,
|
|
disableZoom: false,
|
|
disableXAxis: false,
|
|
disableYAxis: false,
|
|
duration: 200,
|
|
easing: 'ease-in-out',
|
|
exclude: [],
|
|
excludeClass: 'panzoom-exclude',
|
|
handleStartEvent: function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
},
|
|
maxScale: 4,
|
|
minScale: 0.125,
|
|
overflow: 'hidden',
|
|
panOnlyWhenZoomed: false,
|
|
relative: false,
|
|
setTransform: setTransform,
|
|
startX: 0,
|
|
startY: 0,
|
|
startScale: 1,
|
|
step: 0.3,
|
|
touchAction: 'none'
|
|
};
|
|
function Panzoom(elem, options) {
|
|
if (!elem) {
|
|
throw new Error('Panzoom requires an element as an argument');
|
|
}
|
|
if (elem.nodeType !== 1) {
|
|
throw new Error('Panzoom requires an element with a nodeType of 1');
|
|
}
|
|
if (!isAttached(elem)) {
|
|
throw new Error('Panzoom should be called on elements that have been attached to the DOM');
|
|
}
|
|
options = __assign(__assign({}, defaultOptions), options);
|
|
var isSVG = isSVGElement(elem);
|
|
var parent = elem.parentNode;
|
|
// Set parent styles
|
|
parent.style.overflow = options.overflow;
|
|
parent.style.userSelect = 'none';
|
|
// This is important for mobile to
|
|
// prevent scrolling while panning
|
|
parent.style.touchAction = options.touchAction;
|
|
(options.canvas ? parent : elem).style.cursor = options.cursor;
|
|
// Set element styles
|
|
elem.style.userSelect = 'none';
|
|
elem.style.touchAction = options.touchAction;
|
|
// The default for SVG is '0 0'
|
|
// SVG can't be changed in IE
|
|
setStyle(elem, 'transformOrigin', typeof options.origin === 'string' ? options.origin : isSVG ? '0 0' : '50% 50%');
|
|
function setOptions(opts) {
|
|
if (opts === void 0) { opts = {}; }
|
|
for (var key in opts) {
|
|
if (opts.hasOwnProperty(key)) {
|
|
options[key] = opts[key];
|
|
}
|
|
}
|
|
// Handle option side-effects
|
|
if (opts.hasOwnProperty('cursor')) {
|
|
elem.style.cursor = opts.cursor;
|
|
}
|
|
if (opts.hasOwnProperty('overflow')) {
|
|
parent.style.overflow = opts.overflow;
|
|
}
|
|
if (opts.hasOwnProperty('touchAction')) {
|
|
parent.style.touchAction = opts.touchAction;
|
|
elem.style.touchAction = opts.touchAction;
|
|
}
|
|
if (opts.hasOwnProperty('minScale') ||
|
|
opts.hasOwnProperty('maxScale') ||
|
|
opts.hasOwnProperty('contain')) {
|
|
setMinMax();
|
|
}
|
|
}
|
|
var x = 0;
|
|
var y = 0;
|
|
var scale = 1;
|
|
var isPanning = false;
|
|
zoom(options.startScale, { animate: false });
|
|
// Wait for scale to update
|
|
// for accurate dimensions
|
|
// to constrain initial values
|
|
setTimeout(function () {
|
|
setMinMax();
|
|
pan(options.startX, options.startY, { animate: false });
|
|
});
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
function trigger(eventName, detail, opts) {
|
|
if (opts.silent) {
|
|
return;
|
|
}
|
|
var event = new CustomEvent(eventName, { detail: detail });
|
|
elem.dispatchEvent(event);
|
|
}
|
|
function setTransformWithEvent(eventName, opts) {
|
|
var value = { x: x, y: y, scale: scale, isSVG: isSVG };
|
|
requestAnimationFrame(function () {
|
|
if (typeof opts.animate === 'boolean') {
|
|
if (opts.animate) {
|
|
setTransition(elem, opts);
|
|
}
|
|
else {
|
|
setStyle(elem, 'transition', 'none');
|
|
}
|
|
}
|
|
opts.setTransform(elem, value, opts);
|
|
});
|
|
trigger(eventName, value, opts);
|
|
trigger('panzoomchange', value, opts);
|
|
return value;
|
|
}
|
|
function setMinMax() {
|
|
if (options.contain) {
|
|
var dims = getDimensions(elem);
|
|
var parentWidth = dims.parent.width - dims.parent.border.left - dims.parent.border.right;
|
|
var parentHeight = dims.parent.height - dims.parent.border.top - dims.parent.border.bottom;
|
|
var elemWidth = dims.elem.width / scale;
|
|
var elemHeight = dims.elem.height / scale;
|
|
var elemScaledWidth = parentWidth / elemWidth;
|
|
var elemScaledHeight = parentHeight / elemHeight;
|
|
if (options.contain === 'inside') {
|
|
options.maxScale = Math.min(elemScaledWidth, elemScaledHeight);
|
|
}
|
|
else if (options.contain === 'outside') {
|
|
options.minScale = Math.max(elemScaledWidth, elemScaledHeight);
|
|
}
|
|
}
|
|
}
|
|
function constrainXY(toX, toY, toScale, panOptions) {
|
|
var opts = __assign(__assign({}, options), panOptions);
|
|
var result = { x: x, y: y, opts: opts };
|
|
if (!opts.force && (opts.disablePan || (opts.panOnlyWhenZoomed && scale === opts.startScale))) {
|
|
return result;
|
|
}
|
|
toX = parseFloat(toX);
|
|
toY = parseFloat(toY);
|
|
if (!opts.disableXAxis) {
|
|
result.x = (opts.relative ? x : 0) + toX;
|
|
}
|
|
if (!opts.disableYAxis) {
|
|
result.y = (opts.relative ? y : 0) + toY;
|
|
}
|
|
if (opts.contain === 'inside') {
|
|
var dims = getDimensions(elem);
|
|
result.x = Math.max(-dims.elem.margin.left - dims.parent.padding.left, Math.min(dims.parent.width -
|
|
dims.elem.width / toScale -
|
|
dims.parent.padding.left -
|
|
dims.elem.margin.left -
|
|
dims.parent.border.left -
|
|
dims.parent.border.right, result.x));
|
|
result.y = Math.max(-dims.elem.margin.top - dims.parent.padding.top, Math.min(dims.parent.height -
|
|
dims.elem.height / toScale -
|
|
dims.parent.padding.top -
|
|
dims.elem.margin.top -
|
|
dims.parent.border.top -
|
|
dims.parent.border.bottom, result.y));
|
|
}
|
|
else if (opts.contain === 'outside') {
|
|
var dims = getDimensions(elem);
|
|
var realWidth = dims.elem.width / scale;
|
|
var realHeight = dims.elem.height / scale;
|
|
var scaledWidth = realWidth * toScale;
|
|
var scaledHeight = realHeight * toScale;
|
|
var diffHorizontal = (scaledWidth - realWidth) / 2;
|
|
var diffVertical = (scaledHeight - realHeight) / 2;
|
|
var minX = (-(scaledWidth - dims.parent.width) -
|
|
dims.parent.padding.left -
|
|
dims.parent.border.left -
|
|
dims.parent.border.right +
|
|
diffHorizontal) /
|
|
toScale;
|
|
var maxX = (diffHorizontal - dims.parent.padding.left) / toScale;
|
|
result.x = Math.max(Math.min(result.x, maxX), minX);
|
|
var minY = (-(scaledHeight - dims.parent.height) -
|
|
dims.parent.padding.top -
|
|
dims.parent.border.top -
|
|
dims.parent.border.bottom +
|
|
diffVertical) /
|
|
toScale;
|
|
var maxY = (diffVertical - dims.parent.padding.top) / toScale;
|
|
result.y = Math.max(Math.min(result.y, maxY), minY);
|
|
}
|
|
return result;
|
|
}
|
|
function constrainScale(toScale, zoomOptions) {
|
|
var opts = __assign(__assign({}, options), zoomOptions);
|
|
var result = { scale: scale, opts: opts };
|
|
if (!opts.force && opts.disableZoom) {
|
|
return result;
|
|
}
|
|
result.scale = Math.min(Math.max(toScale, opts.minScale), opts.maxScale);
|
|
return result;
|
|
}
|
|
function pan(toX, toY, panOptions) {
|
|
var result = constrainXY(toX, toY, scale, panOptions);
|
|
var opts = result.opts;
|
|
x = result.x;
|
|
y = result.y;
|
|
return setTransformWithEvent('panzoompan', opts);
|
|
}
|
|
function zoom(toScale, zoomOptions) {
|
|
var result = constrainScale(toScale, zoomOptions);
|
|
var opts = result.opts;
|
|
if (!opts.force && opts.disableZoom) {
|
|
return;
|
|
}
|
|
toScale = result.scale;
|
|
var toX = x;
|
|
var toY = y;
|
|
if (opts.focal) {
|
|
// The difference between the point after the scale and the point before the scale
|
|
// plus the current translation after the scale
|
|
// neutralized to no scale (as the transform scale will apply to the translation)
|
|
var focal = opts.focal;
|
|
toX = (focal.x / toScale - focal.x / scale + x * toScale) / toScale;
|
|
toY = (focal.y / toScale - focal.y / scale + y * toScale) / toScale;
|
|
}
|
|
var panResult = constrainXY(toX, toY, toScale, { relative: false, force: true });
|
|
x = panResult.x;
|
|
y = panResult.y;
|
|
scale = toScale;
|
|
return setTransformWithEvent('panzoomzoom', opts);
|
|
}
|
|
function zoomInOut(isIn, zoomOptions) {
|
|
var opts = __assign(__assign(__assign({}, options), { animate: true }), zoomOptions);
|
|
return zoom(scale * Math.exp((isIn ? 1 : -1) * opts.step), opts);
|
|
}
|
|
function zoomIn(zoomOptions) {
|
|
return zoomInOut(true, zoomOptions);
|
|
}
|
|
function zoomOut(zoomOptions) {
|
|
return zoomInOut(false, zoomOptions);
|
|
}
|
|
function zoomToPoint(toScale, point, zoomOptions) {
|
|
var dims = getDimensions(elem);
|
|
// Instead of thinking of operating on the panzoom element,
|
|
// think of operating on the area inside the panzoom
|
|
// element's parent
|
|
// Subtract padding and border
|
|
var effectiveArea = {
|
|
width: dims.parent.width -
|
|
dims.parent.padding.left -
|
|
dims.parent.padding.right -
|
|
dims.parent.border.left -
|
|
dims.parent.border.right,
|
|
height: dims.parent.height -
|
|
dims.parent.padding.top -
|
|
dims.parent.padding.bottom -
|
|
dims.parent.border.top -
|
|
dims.parent.border.bottom
|
|
};
|
|
// Adjust the clientX/clientY to ignore the area
|
|
// outside the effective area
|
|
var clientX = point.clientX -
|
|
dims.parent.left -
|
|
dims.parent.padding.left -
|
|
dims.parent.border.left -
|
|
dims.elem.margin.left;
|
|
var clientY = point.clientY -
|
|
dims.parent.top -
|
|
dims.parent.padding.top -
|
|
dims.parent.border.top -
|
|
dims.elem.margin.top;
|
|
// Adjust the clientX/clientY for HTML elements,
|
|
// because they have a transform-origin of 50% 50%
|
|
if (!isSVG) {
|
|
clientX -= dims.elem.width / scale / 2;
|
|
clientY -= dims.elem.height / scale / 2;
|
|
}
|
|
// Convert the mouse point from it's position over the
|
|
// effective area before the scale to the position
|
|
// over the effective area after the scale.
|
|
var focal = {
|
|
x: (clientX / effectiveArea.width) * (effectiveArea.width * toScale),
|
|
y: (clientY / effectiveArea.height) * (effectiveArea.height * toScale)
|
|
};
|
|
return zoom(toScale, __assign(__assign({ animate: false }, zoomOptions), { focal: focal }));
|
|
}
|
|
function zoomWithWheel(event, zoomOptions) {
|
|
// Need to prevent the default here
|
|
// or it conflicts with regular page scroll
|
|
event.preventDefault();
|
|
var opts = __assign(__assign({}, options), zoomOptions);
|
|
// Normalize to deltaX in case shift modifier is used on Mac
|
|
var delta = event.deltaY === 0 && event.deltaX ? event.deltaX : event.deltaY;
|
|
var wheel = delta < 0 ? 1 : -1;
|
|
var toScale = constrainScale(scale * Math.exp((wheel * opts.step) / 3), opts).scale;
|
|
return zoomToPoint(toScale, event, opts);
|
|
}
|
|
function reset(resetOptions) {
|
|
var opts = __assign(__assign(__assign({}, options), { animate: true, force: true }), resetOptions);
|
|
scale = constrainScale(opts.startScale, opts).scale;
|
|
var panResult = constrainXY(opts.startX, opts.startY, scale, opts);
|
|
x = panResult.x;
|
|
y = panResult.y;
|
|
return setTransformWithEvent('panzoomreset', opts);
|
|
}
|
|
var origX;
|
|
var origY;
|
|
var startClientX;
|
|
var startClientY;
|
|
var startScale;
|
|
var startDistance;
|
|
var pointers = [];
|
|
function handleDown(event) {
|
|
// Don't handle this event if the target is excluded
|
|
if (isExcluded(event.target, options)) {
|
|
return;
|
|
}
|
|
addPointer(pointers, event);
|
|
isPanning = true;
|
|
options.handleStartEvent(event);
|
|
origX = x;
|
|
origY = y;
|
|
trigger('panzoomstart', { x: x, y: y, scale: scale }, options);
|
|
// This works whether there are multiple
|
|
// pointers or not
|
|
var point = getMiddle(pointers);
|
|
startClientX = point.clientX;
|
|
startClientY = point.clientY;
|
|
startScale = scale;
|
|
startDistance = getDistance(pointers);
|
|
}
|
|
function move(event) {
|
|
if (!isPanning ||
|
|
origX === undefined ||
|
|
origY === undefined ||
|
|
startClientX === undefined ||
|
|
startClientY === undefined) {
|
|
return;
|
|
}
|
|
addPointer(pointers, event);
|
|
var current = getMiddle(pointers);
|
|
if (pointers.length > 1) {
|
|
// Use the distance between the first 2 pointers
|
|
// to determine the current scale
|
|
var diff = getDistance(pointers) - startDistance;
|
|
var toScale = constrainScale((diff * options.step) / 80 + startScale).scale;
|
|
zoomToPoint(toScale, current);
|
|
}
|
|
pan(origX + (current.clientX - startClientX) / scale, origY + (current.clientY - startClientY) / scale, {
|
|
animate: false
|
|
});
|
|
}
|
|
function handleUp(event) {
|
|
// Don't call panzoomend when panning with 2 touches
|
|
// until both touches end
|
|
if (pointers.length === 1) {
|
|
trigger('panzoomend', { x: x, y: y, scale: scale }, options);
|
|
}
|
|
// Note: don't remove all pointers
|
|
// Can restart without having to reinitiate all of them
|
|
// Remove the pointer regardless of the isPanning state
|
|
removePointer(pointers, event);
|
|
if (!isPanning) {
|
|
return;
|
|
}
|
|
isPanning = false;
|
|
origX = origY = startClientX = startClientY = undefined;
|
|
}
|
|
var bound = false;
|
|
function bind() {
|
|
if (bound) {
|
|
return;
|
|
}
|
|
bound = true;
|
|
onPointer('down', options.canvas ? parent : elem, handleDown);
|
|
onPointer('move', document, move, { passive: true });
|
|
onPointer('up', document, handleUp, { passive: true });
|
|
}
|
|
function destroy() {
|
|
bound = false;
|
|
destroyPointer('down', options.canvas ? parent : elem, handleDown);
|
|
destroyPointer('move', document, move);
|
|
destroyPointer('up', document, handleUp);
|
|
}
|
|
if (!options.noBind) {
|
|
bind();
|
|
}
|
|
return {
|
|
bind: bind,
|
|
destroy: destroy,
|
|
eventNames: events,
|
|
getPan: function () { return ({ x: x, y: y }); },
|
|
getScale: function () { return scale; },
|
|
getOptions: function () { return shallowClone(options); },
|
|
pan: pan,
|
|
reset: reset,
|
|
setOptions: setOptions,
|
|
setStyle: function (name, value) { return setStyle(elem, name, value); },
|
|
zoom: zoom,
|
|
zoomIn: zoomIn,
|
|
zoomOut: zoomOut,
|
|
zoomToPoint: zoomToPoint,
|
|
zoomWithWheel: zoomWithWheel
|
|
};
|
|
}
|
|
Panzoom.defaultOptions = defaultOptions;
|
|
|
|
return Panzoom;
|
|
|
|
})));
|
|
|
|
},{}],28:[function(require,module,exports){
|
|
module.exports = require('./lib/axios');
|
|
},{"./lib/axios":30}],29:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./../utils');
|
|
var settle = require('./../core/settle');
|
|
var cookies = require('./../helpers/cookies');
|
|
var buildURL = require('./../helpers/buildURL');
|
|
var buildFullPath = require('../core/buildFullPath');
|
|
var parseHeaders = require('./../helpers/parseHeaders');
|
|
var isURLSameOrigin = require('./../helpers/isURLSameOrigin');
|
|
var createError = require('../core/createError');
|
|
|
|
module.exports = function xhrAdapter(config) {
|
|
return new Promise(function dispatchXhrRequest(resolve, reject) {
|
|
var requestData = config.data;
|
|
var requestHeaders = config.headers;
|
|
|
|
if (utils.isFormData(requestData)) {
|
|
delete requestHeaders['Content-Type']; // Let the browser set it
|
|
}
|
|
|
|
var request = new XMLHttpRequest();
|
|
|
|
// HTTP basic authentication
|
|
if (config.auth) {
|
|
var username = config.auth.username || '';
|
|
var password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : '';
|
|
requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);
|
|
}
|
|
|
|
var fullPath = buildFullPath(config.baseURL, config.url);
|
|
request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);
|
|
|
|
// Set the request timeout in MS
|
|
request.timeout = config.timeout;
|
|
|
|
// Listen for ready state
|
|
request.onreadystatechange = function handleLoad() {
|
|
if (!request || request.readyState !== 4) {
|
|
return;
|
|
}
|
|
|
|
// The request errored out and we didn't get a response, this will be
|
|
// handled by onerror instead
|
|
// With one exception: request that using file: protocol, most browsers
|
|
// will return status as 0 even though it's a successful request
|
|
if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
|
|
return;
|
|
}
|
|
|
|
// Prepare the response
|
|
var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;
|
|
var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
|
|
var response = {
|
|
data: responseData,
|
|
status: request.status,
|
|
statusText: request.statusText,
|
|
headers: responseHeaders,
|
|
config: config,
|
|
request: request
|
|
};
|
|
|
|
settle(resolve, reject, response);
|
|
|
|
// Clean up request
|
|
request = null;
|
|
};
|
|
|
|
// Handle browser request cancellation (as opposed to a manual cancellation)
|
|
request.onabort = function handleAbort() {
|
|
if (!request) {
|
|
return;
|
|
}
|
|
|
|
reject(createError('Request aborted', config, 'ECONNABORTED', request));
|
|
|
|
// Clean up request
|
|
request = null;
|
|
};
|
|
|
|
// Handle low level network errors
|
|
request.onerror = function handleError() {
|
|
// Real errors are hidden from us by the browser
|
|
// onerror should only fire if it's a network error
|
|
reject(createError('Network Error', config, null, request));
|
|
|
|
// Clean up request
|
|
request = null;
|
|
};
|
|
|
|
// Handle timeout
|
|
request.ontimeout = function handleTimeout() {
|
|
var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded';
|
|
if (config.timeoutErrorMessage) {
|
|
timeoutErrorMessage = config.timeoutErrorMessage;
|
|
}
|
|
reject(createError(timeoutErrorMessage, config, 'ECONNABORTED',
|
|
request));
|
|
|
|
// Clean up request
|
|
request = null;
|
|
};
|
|
|
|
// Add xsrf header
|
|
// This is only done if running in a standard browser environment.
|
|
// Specifically not if we're in a web worker, or react-native.
|
|
if (utils.isStandardBrowserEnv()) {
|
|
// Add xsrf header
|
|
var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ?
|
|
cookies.read(config.xsrfCookieName) :
|
|
undefined;
|
|
|
|
if (xsrfValue) {
|
|
requestHeaders[config.xsrfHeaderName] = xsrfValue;
|
|
}
|
|
}
|
|
|
|
// Add headers to the request
|
|
if ('setRequestHeader' in request) {
|
|
utils.forEach(requestHeaders, function setRequestHeader(val, key) {
|
|
if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
|
|
// Remove Content-Type if data is undefined
|
|
delete requestHeaders[key];
|
|
} else {
|
|
// Otherwise add header to the request
|
|
request.setRequestHeader(key, val);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Add withCredentials to request if needed
|
|
if (!utils.isUndefined(config.withCredentials)) {
|
|
request.withCredentials = !!config.withCredentials;
|
|
}
|
|
|
|
// Add responseType to request if needed
|
|
if (config.responseType) {
|
|
try {
|
|
request.responseType = config.responseType;
|
|
} catch (e) {
|
|
// Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.
|
|
// But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.
|
|
if (config.responseType !== 'json') {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle progress if needed
|
|
if (typeof config.onDownloadProgress === 'function') {
|
|
request.addEventListener('progress', config.onDownloadProgress);
|
|
}
|
|
|
|
// Not all browsers support upload events
|
|
if (typeof config.onUploadProgress === 'function' && request.upload) {
|
|
request.upload.addEventListener('progress', config.onUploadProgress);
|
|
}
|
|
|
|
if (config.cancelToken) {
|
|
// Handle cancellation
|
|
config.cancelToken.promise.then(function onCanceled(cancel) {
|
|
if (!request) {
|
|
return;
|
|
}
|
|
|
|
request.abort();
|
|
reject(cancel);
|
|
// Clean up request
|
|
request = null;
|
|
});
|
|
}
|
|
|
|
if (!requestData) {
|
|
requestData = null;
|
|
}
|
|
|
|
// Send the request
|
|
request.send(requestData);
|
|
});
|
|
};
|
|
|
|
},{"../core/buildFullPath":36,"../core/createError":37,"./../core/settle":41,"./../helpers/buildURL":45,"./../helpers/cookies":47,"./../helpers/isURLSameOrigin":50,"./../helpers/parseHeaders":52,"./../utils":54}],30:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./utils');
|
|
var bind = require('./helpers/bind');
|
|
var Axios = require('./core/Axios');
|
|
var mergeConfig = require('./core/mergeConfig');
|
|
var defaults = require('./defaults');
|
|
|
|
/**
|
|
* Create an instance of Axios
|
|
*
|
|
* @param {Object} defaultConfig The default config for the instance
|
|
* @return {Axios} A new instance of Axios
|
|
*/
|
|
function createInstance(defaultConfig) {
|
|
var context = new Axios(defaultConfig);
|
|
var instance = bind(Axios.prototype.request, context);
|
|
|
|
// Copy axios.prototype to instance
|
|
utils.extend(instance, Axios.prototype, context);
|
|
|
|
// Copy context to instance
|
|
utils.extend(instance, context);
|
|
|
|
return instance;
|
|
}
|
|
|
|
// Create the default instance to be exported
|
|
var axios = createInstance(defaults);
|
|
|
|
// Expose Axios class to allow class inheritance
|
|
axios.Axios = Axios;
|
|
|
|
// Factory for creating new instances
|
|
axios.create = function create(instanceConfig) {
|
|
return createInstance(mergeConfig(axios.defaults, instanceConfig));
|
|
};
|
|
|
|
// Expose Cancel & CancelToken
|
|
axios.Cancel = require('./cancel/Cancel');
|
|
axios.CancelToken = require('./cancel/CancelToken');
|
|
axios.isCancel = require('./cancel/isCancel');
|
|
|
|
// Expose all/spread
|
|
axios.all = function all(promises) {
|
|
return Promise.all(promises);
|
|
};
|
|
axios.spread = require('./helpers/spread');
|
|
|
|
// Expose isAxiosError
|
|
axios.isAxiosError = require('./helpers/isAxiosError');
|
|
|
|
module.exports = axios;
|
|
|
|
// Allow use of default import syntax in TypeScript
|
|
module.exports.default = axios;
|
|
|
|
},{"./cancel/Cancel":31,"./cancel/CancelToken":32,"./cancel/isCancel":33,"./core/Axios":34,"./core/mergeConfig":40,"./defaults":43,"./helpers/bind":44,"./helpers/isAxiosError":49,"./helpers/spread":53,"./utils":54}],31:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
/**
|
|
* A `Cancel` is an object that is thrown when an operation is canceled.
|
|
*
|
|
* @class
|
|
* @param {string=} message The message.
|
|
*/
|
|
function Cancel(message) {
|
|
this.message = message;
|
|
}
|
|
|
|
Cancel.prototype.toString = function toString() {
|
|
return 'Cancel' + (this.message ? ': ' + this.message : '');
|
|
};
|
|
|
|
Cancel.prototype.__CANCEL__ = true;
|
|
|
|
module.exports = Cancel;
|
|
|
|
},{}],32:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var Cancel = require('./Cancel');
|
|
|
|
/**
|
|
* A `CancelToken` is an object that can be used to request cancellation of an operation.
|
|
*
|
|
* @class
|
|
* @param {Function} executor The executor function.
|
|
*/
|
|
function CancelToken(executor) {
|
|
if (typeof executor !== 'function') {
|
|
throw new TypeError('executor must be a function.');
|
|
}
|
|
|
|
var resolvePromise;
|
|
this.promise = new Promise(function promiseExecutor(resolve) {
|
|
resolvePromise = resolve;
|
|
});
|
|
|
|
var token = this;
|
|
executor(function cancel(message) {
|
|
if (token.reason) {
|
|
// Cancellation has already been requested
|
|
return;
|
|
}
|
|
|
|
token.reason = new Cancel(message);
|
|
resolvePromise(token.reason);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Throws a `Cancel` if cancellation has been requested.
|
|
*/
|
|
CancelToken.prototype.throwIfRequested = function throwIfRequested() {
|
|
if (this.reason) {
|
|
throw this.reason;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns an object that contains a new `CancelToken` and a function that, when called,
|
|
* cancels the `CancelToken`.
|
|
*/
|
|
CancelToken.source = function source() {
|
|
var cancel;
|
|
var token = new CancelToken(function executor(c) {
|
|
cancel = c;
|
|
});
|
|
return {
|
|
token: token,
|
|
cancel: cancel
|
|
};
|
|
};
|
|
|
|
module.exports = CancelToken;
|
|
|
|
},{"./Cancel":31}],33:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
module.exports = function isCancel(value) {
|
|
return !!(value && value.__CANCEL__);
|
|
};
|
|
|
|
},{}],34:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./../utils');
|
|
var buildURL = require('../helpers/buildURL');
|
|
var InterceptorManager = require('./InterceptorManager');
|
|
var dispatchRequest = require('./dispatchRequest');
|
|
var mergeConfig = require('./mergeConfig');
|
|
|
|
/**
|
|
* Create a new instance of Axios
|
|
*
|
|
* @param {Object} instanceConfig The default config for the instance
|
|
*/
|
|
function Axios(instanceConfig) {
|
|
this.defaults = instanceConfig;
|
|
this.interceptors = {
|
|
request: new InterceptorManager(),
|
|
response: new InterceptorManager()
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Dispatch a request
|
|
*
|
|
* @param {Object} config The config specific for this request (merged with this.defaults)
|
|
*/
|
|
Axios.prototype.request = function request(config) {
|
|
/*eslint no-param-reassign:0*/
|
|
// Allow for axios('example/url'[, config]) a la fetch API
|
|
if (typeof config === 'string') {
|
|
config = arguments[1] || {};
|
|
config.url = arguments[0];
|
|
} else {
|
|
config = config || {};
|
|
}
|
|
|
|
config = mergeConfig(this.defaults, config);
|
|
|
|
// Set config.method
|
|
if (config.method) {
|
|
config.method = config.method.toLowerCase();
|
|
} else if (this.defaults.method) {
|
|
config.method = this.defaults.method.toLowerCase();
|
|
} else {
|
|
config.method = 'get';
|
|
}
|
|
|
|
// Hook up interceptors middleware
|
|
var chain = [dispatchRequest, undefined];
|
|
var promise = Promise.resolve(config);
|
|
|
|
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
|
|
chain.unshift(interceptor.fulfilled, interceptor.rejected);
|
|
});
|
|
|
|
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
|
|
chain.push(interceptor.fulfilled, interceptor.rejected);
|
|
});
|
|
|
|
while (chain.length) {
|
|
promise = promise.then(chain.shift(), chain.shift());
|
|
}
|
|
|
|
return promise;
|
|
};
|
|
|
|
Axios.prototype.getUri = function getUri(config) {
|
|
config = mergeConfig(this.defaults, config);
|
|
return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, '');
|
|
};
|
|
|
|
// Provide aliases for supported request methods
|
|
utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
|
|
/*eslint func-names:0*/
|
|
Axios.prototype[method] = function(url, config) {
|
|
return this.request(mergeConfig(config || {}, {
|
|
method: method,
|
|
url: url,
|
|
data: (config || {}).data
|
|
}));
|
|
};
|
|
});
|
|
|
|
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
|
|
/*eslint func-names:0*/
|
|
Axios.prototype[method] = function(url, data, config) {
|
|
return this.request(mergeConfig(config || {}, {
|
|
method: method,
|
|
url: url,
|
|
data: data
|
|
}));
|
|
};
|
|
});
|
|
|
|
module.exports = Axios;
|
|
|
|
},{"../helpers/buildURL":45,"./../utils":54,"./InterceptorManager":35,"./dispatchRequest":38,"./mergeConfig":40}],35:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./../utils');
|
|
|
|
function InterceptorManager() {
|
|
this.handlers = [];
|
|
}
|
|
|
|
/**
|
|
* Add a new interceptor to the stack
|
|
*
|
|
* @param {Function} fulfilled The function to handle `then` for a `Promise`
|
|
* @param {Function} rejected The function to handle `reject` for a `Promise`
|
|
*
|
|
* @return {Number} An ID used to remove interceptor later
|
|
*/
|
|
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
|
|
this.handlers.push({
|
|
fulfilled: fulfilled,
|
|
rejected: rejected
|
|
});
|
|
return this.handlers.length - 1;
|
|
};
|
|
|
|
/**
|
|
* Remove an interceptor from the stack
|
|
*
|
|
* @param {Number} id The ID that was returned by `use`
|
|
*/
|
|
InterceptorManager.prototype.eject = function eject(id) {
|
|
if (this.handlers[id]) {
|
|
this.handlers[id] = null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Iterate over all the registered interceptors
|
|
*
|
|
* This method is particularly useful for skipping over any
|
|
* interceptors that may have become `null` calling `eject`.
|
|
*
|
|
* @param {Function} fn The function to call for each interceptor
|
|
*/
|
|
InterceptorManager.prototype.forEach = function forEach(fn) {
|
|
utils.forEach(this.handlers, function forEachHandler(h) {
|
|
if (h !== null) {
|
|
fn(h);
|
|
}
|
|
});
|
|
};
|
|
|
|
module.exports = InterceptorManager;
|
|
|
|
},{"./../utils":54}],36:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var isAbsoluteURL = require('../helpers/isAbsoluteURL');
|
|
var combineURLs = require('../helpers/combineURLs');
|
|
|
|
/**
|
|
* Creates a new URL by combining the baseURL with the requestedURL,
|
|
* only when the requestedURL is not already an absolute URL.
|
|
* If the requestURL is absolute, this function returns the requestedURL untouched.
|
|
*
|
|
* @param {string} baseURL The base URL
|
|
* @param {string} requestedURL Absolute or relative URL to combine
|
|
* @returns {string} The combined full path
|
|
*/
|
|
module.exports = function buildFullPath(baseURL, requestedURL) {
|
|
if (baseURL && !isAbsoluteURL(requestedURL)) {
|
|
return combineURLs(baseURL, requestedURL);
|
|
}
|
|
return requestedURL;
|
|
};
|
|
|
|
},{"../helpers/combineURLs":46,"../helpers/isAbsoluteURL":48}],37:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var enhanceError = require('./enhanceError');
|
|
|
|
/**
|
|
* Create an Error with the specified message, config, error code, request and response.
|
|
*
|
|
* @param {string} message The error message.
|
|
* @param {Object} config The config.
|
|
* @param {string} [code] The error code (for example, 'ECONNABORTED').
|
|
* @param {Object} [request] The request.
|
|
* @param {Object} [response] The response.
|
|
* @returns {Error} The created error.
|
|
*/
|
|
module.exports = function createError(message, config, code, request, response) {
|
|
var error = new Error(message);
|
|
return enhanceError(error, config, code, request, response);
|
|
};
|
|
|
|
},{"./enhanceError":39}],38:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./../utils');
|
|
var transformData = require('./transformData');
|
|
var isCancel = require('../cancel/isCancel');
|
|
var defaults = require('../defaults');
|
|
|
|
/**
|
|
* Throws a `Cancel` if cancellation has been requested.
|
|
*/
|
|
function throwIfCancellationRequested(config) {
|
|
if (config.cancelToken) {
|
|
config.cancelToken.throwIfRequested();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Dispatch a request to the server using the configured adapter.
|
|
*
|
|
* @param {object} config The config that is to be used for the request
|
|
* @returns {Promise} The Promise to be fulfilled
|
|
*/
|
|
module.exports = function dispatchRequest(config) {
|
|
throwIfCancellationRequested(config);
|
|
|
|
// Ensure headers exist
|
|
config.headers = config.headers || {};
|
|
|
|
// Transform request data
|
|
config.data = transformData(
|
|
config.data,
|
|
config.headers,
|
|
config.transformRequest
|
|
);
|
|
|
|
// Flatten headers
|
|
config.headers = utils.merge(
|
|
config.headers.common || {},
|
|
config.headers[config.method] || {},
|
|
config.headers
|
|
);
|
|
|
|
utils.forEach(
|
|
['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
|
|
function cleanHeaderConfig(method) {
|
|
delete config.headers[method];
|
|
}
|
|
);
|
|
|
|
var adapter = config.adapter || defaults.adapter;
|
|
|
|
return adapter(config).then(function onAdapterResolution(response) {
|
|
throwIfCancellationRequested(config);
|
|
|
|
// Transform response data
|
|
response.data = transformData(
|
|
response.data,
|
|
response.headers,
|
|
config.transformResponse
|
|
);
|
|
|
|
return response;
|
|
}, function onAdapterRejection(reason) {
|
|
if (!isCancel(reason)) {
|
|
throwIfCancellationRequested(config);
|
|
|
|
// Transform response data
|
|
if (reason && reason.response) {
|
|
reason.response.data = transformData(
|
|
reason.response.data,
|
|
reason.response.headers,
|
|
config.transformResponse
|
|
);
|
|
}
|
|
}
|
|
|
|
return Promise.reject(reason);
|
|
});
|
|
};
|
|
|
|
},{"../cancel/isCancel":33,"../defaults":43,"./../utils":54,"./transformData":42}],39:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
/**
|
|
* Update an Error with the specified config, error code, and response.
|
|
*
|
|
* @param {Error} error The error to update.
|
|
* @param {Object} config The config.
|
|
* @param {string} [code] The error code (for example, 'ECONNABORTED').
|
|
* @param {Object} [request] The request.
|
|
* @param {Object} [response] The response.
|
|
* @returns {Error} The error.
|
|
*/
|
|
module.exports = function enhanceError(error, config, code, request, response) {
|
|
error.config = config;
|
|
if (code) {
|
|
error.code = code;
|
|
}
|
|
|
|
error.request = request;
|
|
error.response = response;
|
|
error.isAxiosError = true;
|
|
|
|
error.toJSON = function toJSON() {
|
|
return {
|
|
// Standard
|
|
message: this.message,
|
|
name: this.name,
|
|
// Microsoft
|
|
description: this.description,
|
|
number: this.number,
|
|
// Mozilla
|
|
fileName: this.fileName,
|
|
lineNumber: this.lineNumber,
|
|
columnNumber: this.columnNumber,
|
|
stack: this.stack,
|
|
// Axios
|
|
config: this.config,
|
|
code: this.code
|
|
};
|
|
};
|
|
return error;
|
|
};
|
|
|
|
},{}],40:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('../utils');
|
|
|
|
/**
|
|
* Config-specific merge-function which creates a new config-object
|
|
* by merging two configuration objects together.
|
|
*
|
|
* @param {Object} config1
|
|
* @param {Object} config2
|
|
* @returns {Object} New object resulting from merging config2 to config1
|
|
*/
|
|
module.exports = function mergeConfig(config1, config2) {
|
|
// eslint-disable-next-line no-param-reassign
|
|
config2 = config2 || {};
|
|
var config = {};
|
|
|
|
var valueFromConfig2Keys = ['url', 'method', 'data'];
|
|
var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy', 'params'];
|
|
var defaultToConfig2Keys = [
|
|
'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer',
|
|
'timeout', 'timeoutMessage', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',
|
|
'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'decompress',
|
|
'maxContentLength', 'maxBodyLength', 'maxRedirects', 'transport', 'httpAgent',
|
|
'httpsAgent', 'cancelToken', 'socketPath', 'responseEncoding'
|
|
];
|
|
var directMergeKeys = ['validateStatus'];
|
|
|
|
function getMergedValue(target, source) {
|
|
if (utils.isPlainObject(target) && utils.isPlainObject(source)) {
|
|
return utils.merge(target, source);
|
|
} else if (utils.isPlainObject(source)) {
|
|
return utils.merge({}, source);
|
|
} else if (utils.isArray(source)) {
|
|
return source.slice();
|
|
}
|
|
return source;
|
|
}
|
|
|
|
function mergeDeepProperties(prop) {
|
|
if (!utils.isUndefined(config2[prop])) {
|
|
config[prop] = getMergedValue(config1[prop], config2[prop]);
|
|
} else if (!utils.isUndefined(config1[prop])) {
|
|
config[prop] = getMergedValue(undefined, config1[prop]);
|
|
}
|
|
}
|
|
|
|
utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) {
|
|
if (!utils.isUndefined(config2[prop])) {
|
|
config[prop] = getMergedValue(undefined, config2[prop]);
|
|
}
|
|
});
|
|
|
|
utils.forEach(mergeDeepPropertiesKeys, mergeDeepProperties);
|
|
|
|
utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) {
|
|
if (!utils.isUndefined(config2[prop])) {
|
|
config[prop] = getMergedValue(undefined, config2[prop]);
|
|
} else if (!utils.isUndefined(config1[prop])) {
|
|
config[prop] = getMergedValue(undefined, config1[prop]);
|
|
}
|
|
});
|
|
|
|
utils.forEach(directMergeKeys, function merge(prop) {
|
|
if (prop in config2) {
|
|
config[prop] = getMergedValue(config1[prop], config2[prop]);
|
|
} else if (prop in config1) {
|
|
config[prop] = getMergedValue(undefined, config1[prop]);
|
|
}
|
|
});
|
|
|
|
var axiosKeys = valueFromConfig2Keys
|
|
.concat(mergeDeepPropertiesKeys)
|
|
.concat(defaultToConfig2Keys)
|
|
.concat(directMergeKeys);
|
|
|
|
var otherKeys = Object
|
|
.keys(config1)
|
|
.concat(Object.keys(config2))
|
|
.filter(function filterAxiosKeys(key) {
|
|
return axiosKeys.indexOf(key) === -1;
|
|
});
|
|
|
|
utils.forEach(otherKeys, mergeDeepProperties);
|
|
|
|
return config;
|
|
};
|
|
|
|
},{"../utils":54}],41:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var createError = require('./createError');
|
|
|
|
/**
|
|
* Resolve or reject a Promise based on response status.
|
|
*
|
|
* @param {Function} resolve A function that resolves the promise.
|
|
* @param {Function} reject A function that rejects the promise.
|
|
* @param {object} response The response.
|
|
*/
|
|
module.exports = function settle(resolve, reject, response) {
|
|
var validateStatus = response.config.validateStatus;
|
|
if (!response.status || !validateStatus || validateStatus(response.status)) {
|
|
resolve(response);
|
|
} else {
|
|
reject(createError(
|
|
'Request failed with status code ' + response.status,
|
|
response.config,
|
|
null,
|
|
response.request,
|
|
response
|
|
));
|
|
}
|
|
};
|
|
|
|
},{"./createError":37}],42:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./../utils');
|
|
|
|
/**
|
|
* Transform the data for a request or a response
|
|
*
|
|
* @param {Object|String} data The data to be transformed
|
|
* @param {Array} headers The headers for the request or response
|
|
* @param {Array|Function} fns A single function or Array of functions
|
|
* @returns {*} The resulting transformed data
|
|
*/
|
|
module.exports = function transformData(data, headers, fns) {
|
|
/*eslint no-param-reassign:0*/
|
|
utils.forEach(fns, function transform(fn) {
|
|
data = fn(data, headers);
|
|
});
|
|
|
|
return data;
|
|
};
|
|
|
|
},{"./../utils":54}],43:[function(require,module,exports){
|
|
(function (process){(function (){
|
|
'use strict';
|
|
|
|
var utils = require('./utils');
|
|
var normalizeHeaderName = require('./helpers/normalizeHeaderName');
|
|
|
|
var DEFAULT_CONTENT_TYPE = {
|
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
};
|
|
|
|
function setContentTypeIfUnset(headers, value) {
|
|
if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {
|
|
headers['Content-Type'] = value;
|
|
}
|
|
}
|
|
|
|
function getDefaultAdapter() {
|
|
var adapter;
|
|
if (typeof XMLHttpRequest !== 'undefined') {
|
|
// For browsers use XHR adapter
|
|
adapter = require('./adapters/xhr');
|
|
} else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
|
|
// For node use HTTP adapter
|
|
adapter = require('./adapters/http');
|
|
}
|
|
return adapter;
|
|
}
|
|
|
|
var defaults = {
|
|
adapter: getDefaultAdapter(),
|
|
|
|
transformRequest: [function transformRequest(data, headers) {
|
|
normalizeHeaderName(headers, 'Accept');
|
|
normalizeHeaderName(headers, 'Content-Type');
|
|
if (utils.isFormData(data) ||
|
|
utils.isArrayBuffer(data) ||
|
|
utils.isBuffer(data) ||
|
|
utils.isStream(data) ||
|
|
utils.isFile(data) ||
|
|
utils.isBlob(data)
|
|
) {
|
|
return data;
|
|
}
|
|
if (utils.isArrayBufferView(data)) {
|
|
return data.buffer;
|
|
}
|
|
if (utils.isURLSearchParams(data)) {
|
|
setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
|
|
return data.toString();
|
|
}
|
|
if (utils.isObject(data)) {
|
|
setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
|
|
return JSON.stringify(data);
|
|
}
|
|
return data;
|
|
}],
|
|
|
|
transformResponse: [function transformResponse(data) {
|
|
/*eslint no-param-reassign:0*/
|
|
if (typeof data === 'string') {
|
|
try {
|
|
data = JSON.parse(data);
|
|
} catch (e) { /* Ignore */ }
|
|
}
|
|
return data;
|
|
}],
|
|
|
|
/**
|
|
* A timeout in milliseconds to abort a request. If set to 0 (default) a
|
|
* timeout is not created.
|
|
*/
|
|
timeout: 0,
|
|
|
|
xsrfCookieName: 'XSRF-TOKEN',
|
|
xsrfHeaderName: 'X-XSRF-TOKEN',
|
|
|
|
maxContentLength: -1,
|
|
maxBodyLength: -1,
|
|
|
|
validateStatus: function validateStatus(status) {
|
|
return status >= 200 && status < 300;
|
|
}
|
|
};
|
|
|
|
defaults.headers = {
|
|
common: {
|
|
'Accept': 'application/json, text/plain, */*'
|
|
}
|
|
};
|
|
|
|
utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {
|
|
defaults.headers[method] = {};
|
|
});
|
|
|
|
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
|
|
defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
|
|
});
|
|
|
|
module.exports = defaults;
|
|
|
|
}).call(this)}).call(this,require('_process'))
|
|
|
|
},{"./adapters/http":29,"./adapters/xhr":29,"./helpers/normalizeHeaderName":51,"./utils":54,"_process":7}],44:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
module.exports = function bind(fn, thisArg) {
|
|
return function wrap() {
|
|
var args = new Array(arguments.length);
|
|
for (var i = 0; i < args.length; i++) {
|
|
args[i] = arguments[i];
|
|
}
|
|
return fn.apply(thisArg, args);
|
|
};
|
|
};
|
|
|
|
},{}],45:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./../utils');
|
|
|
|
function encode(val) {
|
|
return encodeURIComponent(val).
|
|
replace(/%3A/gi, ':').
|
|
replace(/%24/g, '$').
|
|
replace(/%2C/gi, ',').
|
|
replace(/%20/g, '+').
|
|
replace(/%5B/gi, '[').
|
|
replace(/%5D/gi, ']');
|
|
}
|
|
|
|
/**
|
|
* Build a URL by appending params to the end
|
|
*
|
|
* @param {string} url The base of the url (e.g., http://www.google.com)
|
|
* @param {object} [params] The params to be appended
|
|
* @returns {string} The formatted url
|
|
*/
|
|
module.exports = function buildURL(url, params, paramsSerializer) {
|
|
/*eslint no-param-reassign:0*/
|
|
if (!params) {
|
|
return url;
|
|
}
|
|
|
|
var serializedParams;
|
|
if (paramsSerializer) {
|
|
serializedParams = paramsSerializer(params);
|
|
} else if (utils.isURLSearchParams(params)) {
|
|
serializedParams = params.toString();
|
|
} else {
|
|
var parts = [];
|
|
|
|
utils.forEach(params, function serialize(val, key) {
|
|
if (val === null || typeof val === 'undefined') {
|
|
return;
|
|
}
|
|
|
|
if (utils.isArray(val)) {
|
|
key = key + '[]';
|
|
} else {
|
|
val = [val];
|
|
}
|
|
|
|
utils.forEach(val, function parseValue(v) {
|
|
if (utils.isDate(v)) {
|
|
v = v.toISOString();
|
|
} else if (utils.isObject(v)) {
|
|
v = JSON.stringify(v);
|
|
}
|
|
parts.push(encode(key) + '=' + encode(v));
|
|
});
|
|
});
|
|
|
|
serializedParams = parts.join('&');
|
|
}
|
|
|
|
if (serializedParams) {
|
|
var hashmarkIndex = url.indexOf('#');
|
|
if (hashmarkIndex !== -1) {
|
|
url = url.slice(0, hashmarkIndex);
|
|
}
|
|
|
|
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
|
|
}
|
|
|
|
return url;
|
|
};
|
|
|
|
},{"./../utils":54}],46:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
/**
|
|
* Creates a new URL by combining the specified URLs
|
|
*
|
|
* @param {string} baseURL The base URL
|
|
* @param {string} relativeURL The relative URL
|
|
* @returns {string} The combined URL
|
|
*/
|
|
module.exports = function combineURLs(baseURL, relativeURL) {
|
|
return relativeURL
|
|
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
|
|
: baseURL;
|
|
};
|
|
|
|
},{}],47:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./../utils');
|
|
|
|
module.exports = (
|
|
utils.isStandardBrowserEnv() ?
|
|
|
|
// Standard browser envs support document.cookie
|
|
(function standardBrowserEnv() {
|
|
return {
|
|
write: function write(name, value, expires, path, domain, secure) {
|
|
var cookie = [];
|
|
cookie.push(name + '=' + encodeURIComponent(value));
|
|
|
|
if (utils.isNumber(expires)) {
|
|
cookie.push('expires=' + new Date(expires).toGMTString());
|
|
}
|
|
|
|
if (utils.isString(path)) {
|
|
cookie.push('path=' + path);
|
|
}
|
|
|
|
if (utils.isString(domain)) {
|
|
cookie.push('domain=' + domain);
|
|
}
|
|
|
|
if (secure === true) {
|
|
cookie.push('secure');
|
|
}
|
|
|
|
document.cookie = cookie.join('; ');
|
|
},
|
|
|
|
read: function read(name) {
|
|
var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
|
|
return (match ? decodeURIComponent(match[3]) : null);
|
|
},
|
|
|
|
remove: function remove(name) {
|
|
this.write(name, '', Date.now() - 86400000);
|
|
}
|
|
};
|
|
})() :
|
|
|
|
// Non standard browser env (web workers, react-native) lack needed support.
|
|
(function nonStandardBrowserEnv() {
|
|
return {
|
|
write: function write() {},
|
|
read: function read() { return null; },
|
|
remove: function remove() {}
|
|
};
|
|
})()
|
|
);
|
|
|
|
},{"./../utils":54}],48:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
/**
|
|
* Determines whether the specified URL is absolute
|
|
*
|
|
* @param {string} url The URL to test
|
|
* @returns {boolean} True if the specified URL is absolute, otherwise false
|
|
*/
|
|
module.exports = function isAbsoluteURL(url) {
|
|
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
|
|
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
|
|
// by any combination of letters, digits, plus, period, or hyphen.
|
|
return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
|
|
};
|
|
|
|
},{}],49:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
/**
|
|
* Determines whether the payload is an error thrown by Axios
|
|
*
|
|
* @param {*} payload The value to test
|
|
* @returns {boolean} True if the payload is an error thrown by Axios, otherwise false
|
|
*/
|
|
module.exports = function isAxiosError(payload) {
|
|
return (typeof payload === 'object') && (payload.isAxiosError === true);
|
|
};
|
|
|
|
},{}],50:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./../utils');
|
|
|
|
module.exports = (
|
|
utils.isStandardBrowserEnv() ?
|
|
|
|
// Standard browser envs have full support of the APIs needed to test
|
|
// whether the request URL is of the same origin as current location.
|
|
(function standardBrowserEnv() {
|
|
var msie = /(msie|trident)/i.test(navigator.userAgent);
|
|
var urlParsingNode = document.createElement('a');
|
|
var originURL;
|
|
|
|
/**
|
|
* Parse a URL to discover it's components
|
|
*
|
|
* @param {String} url The URL to be parsed
|
|
* @returns {Object}
|
|
*/
|
|
function resolveURL(url) {
|
|
var href = url;
|
|
|
|
if (msie) {
|
|
// IE needs attribute set twice to normalize properties
|
|
urlParsingNode.setAttribute('href', href);
|
|
href = urlParsingNode.href;
|
|
}
|
|
|
|
urlParsingNode.setAttribute('href', href);
|
|
|
|
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
|
|
return {
|
|
href: urlParsingNode.href,
|
|
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
|
|
host: urlParsingNode.host,
|
|
search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
|
|
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
|
hostname: urlParsingNode.hostname,
|
|
port: urlParsingNode.port,
|
|
pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
|
|
urlParsingNode.pathname :
|
|
'/' + urlParsingNode.pathname
|
|
};
|
|
}
|
|
|
|
originURL = resolveURL(window.location.href);
|
|
|
|
/**
|
|
* Determine if a URL shares the same origin as the current location
|
|
*
|
|
* @param {String} requestURL The URL to test
|
|
* @returns {boolean} True if URL shares the same origin, otherwise false
|
|
*/
|
|
return function isURLSameOrigin(requestURL) {
|
|
var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
|
|
return (parsed.protocol === originURL.protocol &&
|
|
parsed.host === originURL.host);
|
|
};
|
|
})() :
|
|
|
|
// Non standard browser envs (web workers, react-native) lack needed support.
|
|
(function nonStandardBrowserEnv() {
|
|
return function isURLSameOrigin() {
|
|
return true;
|
|
};
|
|
})()
|
|
);
|
|
|
|
},{"./../utils":54}],51:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('../utils');
|
|
|
|
module.exports = function normalizeHeaderName(headers, normalizedName) {
|
|
utils.forEach(headers, function processHeader(value, name) {
|
|
if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
|
|
headers[normalizedName] = value;
|
|
delete headers[name];
|
|
}
|
|
});
|
|
};
|
|
|
|
},{"../utils":54}],52:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./../utils');
|
|
|
|
// Headers whose duplicates are ignored by node
|
|
// c.f. https://nodejs.org/api/http.html#http_message_headers
|
|
var ignoreDuplicateOf = [
|
|
'age', 'authorization', 'content-length', 'content-type', 'etag',
|
|
'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
|
|
'last-modified', 'location', 'max-forwards', 'proxy-authorization',
|
|
'referer', 'retry-after', 'user-agent'
|
|
];
|
|
|
|
/**
|
|
* Parse headers into an object
|
|
*
|
|
* ```
|
|
* Date: Wed, 27 Aug 2014 08:58:49 GMT
|
|
* Content-Type: application/json
|
|
* Connection: keep-alive
|
|
* Transfer-Encoding: chunked
|
|
* ```
|
|
*
|
|
* @param {String} headers Headers needing to be parsed
|
|
* @returns {Object} Headers parsed into an object
|
|
*/
|
|
module.exports = function parseHeaders(headers) {
|
|
var parsed = {};
|
|
var key;
|
|
var val;
|
|
var i;
|
|
|
|
if (!headers) { return parsed; }
|
|
|
|
utils.forEach(headers.split('\n'), function parser(line) {
|
|
i = line.indexOf(':');
|
|
key = utils.trim(line.substr(0, i)).toLowerCase();
|
|
val = utils.trim(line.substr(i + 1));
|
|
|
|
if (key) {
|
|
if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
|
|
return;
|
|
}
|
|
if (key === 'set-cookie') {
|
|
parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
|
|
} else {
|
|
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
|
|
}
|
|
}
|
|
});
|
|
|
|
return parsed;
|
|
};
|
|
|
|
},{"./../utils":54}],53:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
/**
|
|
* Syntactic sugar for invoking a function and expanding an array for arguments.
|
|
*
|
|
* Common use case would be to use `Function.prototype.apply`.
|
|
*
|
|
* ```js
|
|
* function f(x, y, z) {}
|
|
* var args = [1, 2, 3];
|
|
* f.apply(null, args);
|
|
* ```
|
|
*
|
|
* With `spread` this example can be re-written.
|
|
*
|
|
* ```js
|
|
* spread(function(x, y, z) {})([1, 2, 3]);
|
|
* ```
|
|
*
|
|
* @param {Function} callback
|
|
* @returns {Function}
|
|
*/
|
|
module.exports = function spread(callback) {
|
|
return function wrap(arr) {
|
|
return callback.apply(null, arr);
|
|
};
|
|
};
|
|
|
|
},{}],54:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var bind = require('./helpers/bind');
|
|
|
|
/*global toString:true*/
|
|
|
|
// utils is a library of generic helper functions non-specific to axios
|
|
|
|
var toString = Object.prototype.toString;
|
|
|
|
/**
|
|
* Determine if a value is an Array
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is an Array, otherwise false
|
|
*/
|
|
function isArray(val) {
|
|
return toString.call(val) === '[object Array]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is undefined
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if the value is undefined, otherwise false
|
|
*/
|
|
function isUndefined(val) {
|
|
return typeof val === 'undefined';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Buffer
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Buffer, otherwise false
|
|
*/
|
|
function isBuffer(val) {
|
|
return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)
|
|
&& typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val);
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is an ArrayBuffer
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is an ArrayBuffer, otherwise false
|
|
*/
|
|
function isArrayBuffer(val) {
|
|
return toString.call(val) === '[object ArrayBuffer]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a FormData
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is an FormData, otherwise false
|
|
*/
|
|
function isFormData(val) {
|
|
return (typeof FormData !== 'undefined') && (val instanceof FormData);
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a view on an ArrayBuffer
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
|
|
*/
|
|
function isArrayBufferView(val) {
|
|
var result;
|
|
if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {
|
|
result = ArrayBuffer.isView(val);
|
|
} else {
|
|
result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a String
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a String, otherwise false
|
|
*/
|
|
function isString(val) {
|
|
return typeof val === 'string';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Number
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Number, otherwise false
|
|
*/
|
|
function isNumber(val) {
|
|
return typeof val === 'number';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is an Object
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is an Object, otherwise false
|
|
*/
|
|
function isObject(val) {
|
|
return val !== null && typeof val === 'object';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a plain Object
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @return {boolean} True if value is a plain Object, otherwise false
|
|
*/
|
|
function isPlainObject(val) {
|
|
if (toString.call(val) !== '[object Object]') {
|
|
return false;
|
|
}
|
|
|
|
var prototype = Object.getPrototypeOf(val);
|
|
return prototype === null || prototype === Object.prototype;
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Date
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Date, otherwise false
|
|
*/
|
|
function isDate(val) {
|
|
return toString.call(val) === '[object Date]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a File
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a File, otherwise false
|
|
*/
|
|
function isFile(val) {
|
|
return toString.call(val) === '[object File]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Blob
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Blob, otherwise false
|
|
*/
|
|
function isBlob(val) {
|
|
return toString.call(val) === '[object Blob]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Function
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Function, otherwise false
|
|
*/
|
|
function isFunction(val) {
|
|
return toString.call(val) === '[object Function]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Stream
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Stream, otherwise false
|
|
*/
|
|
function isStream(val) {
|
|
return isObject(val) && isFunction(val.pipe);
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a URLSearchParams object
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
|
|
*/
|
|
function isURLSearchParams(val) {
|
|
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
|
|
}
|
|
|
|
/**
|
|
* Trim excess whitespace off the beginning and end of a string
|
|
*
|
|
* @param {String} str The String to trim
|
|
* @returns {String} The String freed of excess whitespace
|
|
*/
|
|
function trim(str) {
|
|
return str.replace(/^\s*/, '').replace(/\s*$/, '');
|
|
}
|
|
|
|
/**
|
|
* Determine if we're running in a standard browser environment
|
|
*
|
|
* This allows axios to run in a web worker, and react-native.
|
|
* Both environments support XMLHttpRequest, but not fully standard globals.
|
|
*
|
|
* web workers:
|
|
* typeof window -> undefined
|
|
* typeof document -> undefined
|
|
*
|
|
* react-native:
|
|
* navigator.product -> 'ReactNative'
|
|
* nativescript
|
|
* navigator.product -> 'NativeScript' or 'NS'
|
|
*/
|
|
function isStandardBrowserEnv() {
|
|
if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' ||
|
|
navigator.product === 'NativeScript' ||
|
|
navigator.product === 'NS')) {
|
|
return false;
|
|
}
|
|
return (
|
|
typeof window !== 'undefined' &&
|
|
typeof document !== 'undefined'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Iterate over an Array or an Object invoking a function for each item.
|
|
*
|
|
* If `obj` is an Array callback will be called passing
|
|
* the value, index, and complete array for each item.
|
|
*
|
|
* If 'obj' is an Object callback will be called passing
|
|
* the value, key, and complete object for each property.
|
|
*
|
|
* @param {Object|Array} obj The object to iterate
|
|
* @param {Function} fn The callback to invoke for each item
|
|
*/
|
|
function forEach(obj, fn) {
|
|
// Don't bother if no value provided
|
|
if (obj === null || typeof obj === 'undefined') {
|
|
return;
|
|
}
|
|
|
|
// Force an array if not already something iterable
|
|
if (typeof obj !== 'object') {
|
|
/*eslint no-param-reassign:0*/
|
|
obj = [obj];
|
|
}
|
|
|
|
if (isArray(obj)) {
|
|
// Iterate over array values
|
|
for (var i = 0, l = obj.length; i < l; i++) {
|
|
fn.call(null, obj[i], i, obj);
|
|
}
|
|
} else {
|
|
// Iterate over object keys
|
|
for (var key in obj) {
|
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
fn.call(null, obj[key], key, obj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Accepts varargs expecting each argument to be an object, then
|
|
* immutably merges the properties of each object and returns result.
|
|
*
|
|
* When multiple objects contain the same key the later object in
|
|
* the arguments list will take precedence.
|
|
*
|
|
* Example:
|
|
*
|
|
* ```js
|
|
* var result = merge({foo: 123}, {foo: 456});
|
|
* console.log(result.foo); // outputs 456
|
|
* ```
|
|
*
|
|
* @param {Object} obj1 Object to merge
|
|
* @returns {Object} Result of all merge properties
|
|
*/
|
|
function merge(/* obj1, obj2, obj3, ... */) {
|
|
var result = {};
|
|
function assignValue(val, key) {
|
|
if (isPlainObject(result[key]) && isPlainObject(val)) {
|
|
result[key] = merge(result[key], val);
|
|
} else if (isPlainObject(val)) {
|
|
result[key] = merge({}, val);
|
|
} else if (isArray(val)) {
|
|
result[key] = val.slice();
|
|
} else {
|
|
result[key] = val;
|
|
}
|
|
}
|
|
|
|
for (var i = 0, l = arguments.length; i < l; i++) {
|
|
forEach(arguments[i], assignValue);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extends object a by mutably adding to it the properties of object b.
|
|
*
|
|
* @param {Object} a The object to be extended
|
|
* @param {Object} b The object to copy properties from
|
|
* @param {Object} thisArg The object to bind function to
|
|
* @return {Object} The resulting value of object a
|
|
*/
|
|
function extend(a, b, thisArg) {
|
|
forEach(b, function assignValue(val, key) {
|
|
if (thisArg && typeof val === 'function') {
|
|
a[key] = bind(val, thisArg);
|
|
} else {
|
|
a[key] = val;
|
|
}
|
|
});
|
|
return a;
|
|
}
|
|
|
|
/**
|
|
* Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
|
|
*
|
|
* @param {string} content with BOM
|
|
* @return {string} content value without BOM
|
|
*/
|
|
function stripBOM(content) {
|
|
if (content.charCodeAt(0) === 0xFEFF) {
|
|
content = content.slice(1);
|
|
}
|
|
return content;
|
|
}
|
|
|
|
module.exports = {
|
|
isArray: isArray,
|
|
isArrayBuffer: isArrayBuffer,
|
|
isBuffer: isBuffer,
|
|
isFormData: isFormData,
|
|
isArrayBufferView: isArrayBufferView,
|
|
isString: isString,
|
|
isNumber: isNumber,
|
|
isObject: isObject,
|
|
isPlainObject: isPlainObject,
|
|
isUndefined: isUndefined,
|
|
isDate: isDate,
|
|
isFile: isFile,
|
|
isBlob: isBlob,
|
|
isFunction: isFunction,
|
|
isStream: isStream,
|
|
isURLSearchParams: isURLSearchParams,
|
|
isStandardBrowserEnv: isStandardBrowserEnv,
|
|
forEach: forEach,
|
|
merge: merge,
|
|
extend: extend,
|
|
trim: trim,
|
|
stripBOM: stripBOM
|
|
};
|
|
|
|
},{"./helpers/bind":44}],55:[function(require,module,exports){
|
|
'use strict';
|
|
// For more information about browser field, check out the browser field at https://github.com/substack/browserify-handbook#browser-field.
|
|
|
|
var styleElementsInsertedAtTop = [];
|
|
|
|
var insertStyleElement = function(styleElement, options) {
|
|
var head = document.head || document.getElementsByTagName('head')[0];
|
|
var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
|
|
|
|
options = options || {};
|
|
options.insertAt = options.insertAt || 'bottom';
|
|
|
|
if (options.insertAt === 'top') {
|
|
if (!lastStyleElementInsertedAtTop) {
|
|
head.insertBefore(styleElement, head.firstChild);
|
|
} else if (lastStyleElementInsertedAtTop.nextSibling) {
|
|
head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
|
|
} else {
|
|
head.appendChild(styleElement);
|
|
}
|
|
styleElementsInsertedAtTop.push(styleElement);
|
|
} else if (options.insertAt === 'bottom') {
|
|
head.appendChild(styleElement);
|
|
} else {
|
|
throw new Error('Invalid value for parameter \'insertAt\'. Must be \'top\' or \'bottom\'.');
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
// Create a <link> tag with optional data attributes
|
|
createLink: function(href, attributes) {
|
|
var head = document.head || document.getElementsByTagName('head')[0];
|
|
var link = document.createElement('link');
|
|
|
|
link.href = href;
|
|
link.rel = 'stylesheet';
|
|
|
|
for (var key in attributes) {
|
|
if ( ! attributes.hasOwnProperty(key)) {
|
|
continue;
|
|
}
|
|
var value = attributes[key];
|
|
link.setAttribute('data-' + key, value);
|
|
}
|
|
|
|
head.appendChild(link);
|
|
},
|
|
// Create a <style> tag with optional data attributes
|
|
createStyle: function(cssText, attributes, extraOptions) {
|
|
extraOptions = extraOptions || {};
|
|
|
|
var style = document.createElement('style');
|
|
style.type = 'text/css';
|
|
|
|
for (var key in attributes) {
|
|
if ( ! attributes.hasOwnProperty(key)) {
|
|
continue;
|
|
}
|
|
var value = attributes[key];
|
|
style.setAttribute('data-' + key, value);
|
|
}
|
|
|
|
if (style.sheet) { // for jsdom and IE9+
|
|
style.innerHTML = cssText;
|
|
style.sheet.cssText = cssText;
|
|
insertStyleElement(style, { insertAt: extraOptions.insertAt });
|
|
} else if (style.styleSheet) { // for IE8 and below
|
|
insertStyleElement(style, { insertAt: extraOptions.insertAt });
|
|
style.styleSheet.cssText = cssText;
|
|
} else { // for Chrome, Firefox, and Safari
|
|
style.appendChild(document.createTextNode(cssText));
|
|
insertStyleElement(style, { insertAt: extraOptions.insertAt });
|
|
}
|
|
}
|
|
};
|
|
|
|
},{}],56:[function(require,module,exports){
|
|
var css = ".jBox-wrapper {\n text-align: left;\n box-sizing: border-box;\n}\n.jBox-title,\n.jBox-content,\n.jBox-container {\n position: relative;\n word-break: break-word;\n box-sizing: border-box;\n}\n.jBox-container {\n background: #fff;\n}\n.jBox-content {\n padding: 8px 12px;\n overflow-x: hidden;\n overflow-y: auto;\n transition: opacity .2s;\n}\n.jBox-footer {\n box-sizing: border-box;\n}\n.jBox-Tooltip .jBox-container,\n.jBox-Mouse .jBox-container {\n border-radius: 4px;\n box-shadow: 0 0 3px rgba(0, 0, 0, 0.25);\n}\n.jBox-Tooltip .jBox-title,\n.jBox-Mouse .jBox-title {\n padding: 8px 10px 0;\n font-weight: bold;\n}\n.jBox-Tooltip.jBox-hasTitle .jBox-content,\n.jBox-Mouse.jBox-hasTitle .jBox-content {\n padding-top: 5px;\n}\n.jBox-Mouse {\n pointer-events: none;\n}\n.jBox-pointer {\n position: absolute;\n overflow: hidden;\n box-sizing: border-box;\n}\n.jBox-pointer:after {\n content: '';\n width: 20px;\n height: 20px;\n position: absolute;\n background: #fff;\n transform: rotate(45deg);\n box-sizing: border-box;\n}\n.jBox-pointer-top {\n top: 0;\n}\n.jBox-pointer-top:after {\n left: 5px;\n top: 6px;\n box-shadow: -1px -1px 2px rgba(0, 0, 0, 0.15);\n}\n.jBox-pointer-right {\n right: 0;\n}\n.jBox-pointer-right:after {\n top: 5px;\n right: 6px;\n box-shadow: 1px -1px 2px rgba(0, 0, 0, 0.15);\n}\n.jBox-pointer-left {\n left: 0;\n}\n.jBox-pointer-left:after {\n top: 5px;\n left: 6px;\n box-shadow: -1px 1px 2px rgba(0, 0, 0, 0.15);\n}\n.jBox-pointer-bottom {\n bottom: 0;\n}\n.jBox-pointer-bottom:after {\n left: 5px;\n bottom: 6px;\n box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.15);\n}\n.jBox-pointer-top,\n.jBox-pointer-bottom {\n width: 30px;\n height: 12px;\n}\n.jBox-pointer-left,\n.jBox-pointer-right {\n width: 12px;\n height: 30px;\n}\n.jBox-Modal .jBox-container {\n border-radius: 4px;\n}\n.jBox-Modal .jBox-container,\n.jBox-Modal.jBox-closeButton-box:before {\n box-shadow: 0 3px 15px rgba(0, 0, 0, 0.4), 0 0 5px rgba(0, 0, 0, 0.4);\n}\n.jBox-Modal .jBox-content {\n padding: 15px 20px;\n}\n.jBox-Modal .jBox-title {\n border-radius: 4px 4px 0 0;\n padding: 15px 20px;\n background: #fafafa;\n border-bottom: 1px solid #eee;\n}\n.jBox-Modal.jBox-closeButton-title .jBox-title {\n padding-right: 65px;\n}\n.jBox-Modal .jBox-footer {\n border-radius: 0 0 4px 4px;\n}\n.jBox-closeButton {\n z-index: 1;\n cursor: pointer;\n position: absolute;\n box-sizing: border-box;\n}\n.jBox-closeButton svg {\n position: absolute;\n top: 50%;\n right: 50%;\n}\n.jBox-closeButton path {\n fill: #aaa;\n transition: fill .2s;\n}\n.jBox-closeButton:hover path {\n fill: #888;\n}\n.jBox-overlay .jBox-closeButton {\n top: 0;\n right: 0;\n width: 40px;\n height: 40px;\n}\n.jBox-overlay .jBox-closeButton svg {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n margin-right: -10px;\n}\n.jBox-overlay .jBox-closeButton path {\n fill: #ddd;\n}\n.jBox-overlay .jBox-closeButton:hover path {\n fill: #fff;\n}\n.jBox-closeButton-title .jBox-closeButton {\n top: 0;\n right: 0;\n bottom: 0;\n width: 50px;\n}\n.jBox-closeButton-title svg {\n width: 12px;\n height: 12px;\n margin-top: -6px;\n margin-right: -6px;\n}\n.jBox-closeButton-box {\n box-sizing: border-box;\n}\n.jBox-closeButton-box .jBox-closeButton {\n top: -8px;\n right: -10px;\n width: 24px;\n height: 24px;\n background: #fff;\n border-radius: 50%;\n}\n.jBox-closeButton-box .jBox-closeButton svg {\n width: 10px;\n height: 10px;\n margin-top: -5px;\n margin-right: -5px;\n}\n.jBox-closeButton-box:before {\n content: '';\n position: absolute;\n top: -8px;\n right: -10px;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);\n}\n.jBox-closeButton-box.jBox-pointerPosition-top:before {\n top: 5px;\n}\n.jBox-closeButton-box.jBox-pointerPosition-right:before {\n right: 2px;\n}\n.jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton {\n background: #fafafa;\n}\n.jBox-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.82);\n}\n.jBox-footer {\n background: #fafafa;\n border-top: 1px solid #eee;\n padding: 8px 10px;\n border-radius: 0 0 3px 3px;\n}\nbody[class^=\"jBox-blockScroll-\"],\nbody[class*=\" jBox-blockScroll-\"] {\n overflow: hidden;\n}\n.jBox-draggable {\n cursor: move;\n}\n@keyframes jBoxLoading {\n to {\n transform: rotate(360deg);\n }\n}\n.jBox-loading .jBox-content {\n opacity: .2;\n}\n.jBox-loading-spinner .jBox-content {\n min-height: 38px !important;\n min-width: 38px !important;\n opacity: 0;\n}\n.jBox-spinner {\n box-sizing: border-box;\n position: absolute;\n top: 50%;\n left: 50%;\n width: 24px;\n height: 24px;\n margin-top: -12px;\n margin-left: -12px;\n}\n.jBox-spinner:before {\n display: block;\n box-sizing: border-box;\n content: '';\n width: 24px;\n height: 24px;\n border-radius: 50%;\n border: 2px solid rgba(0, 0, 0, 0.2);\n border-top-color: rgba(0, 0, 0, 0.8);\n animation: jBoxLoading .6s linear infinite;\n}\n.jBox-countdown {\n border-radius: 4px 4px 0 0;\n z-index: 0;\n background: #000;\n opacity: .2;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 3px;\n overflow: hidden;\n}\n.jBox-countdown-inner {\n top: 0;\n right: 0;\n width: 100%;\n height: 3px;\n position: absolute;\n background: #fff;\n}\n[class^=\"jBox-animated-\"],\n[class*=\" jBox-animated-\"] {\n animation-fill-mode: both;\n}\n@keyframes jBox-tada {\n 0% {\n transform: scale(1);\n }\n\n 10%, 20% {\n transform: scale(0.8) rotate(-4deg);\n }\n\n 30%, 50%, 70%, 90% {\n transform: scale(1.2) rotate(4deg);\n }\n\n 40%, 60%, 80% {\n transform: scale(1.2) rotate(-4deg);\n }\n\n 100% {\n transform: scale(1) rotate(0);\n }\n}\n.jBox-animated-tada {\n animation: jBox-tada 1s;\n}\n@keyframes jBox-tadaSmall {\n 0% {\n transform: scale(1);\n }\n\n 10%, 20% {\n transform: scale(0.9) rotate(-2deg);\n }\n\n 30%, 50%, 70%, 90% {\n transform: scale(1.1) rotate(2deg);\n }\n\n 40%, 60%, 80% {\n transform: scale(1.1) rotate(-2deg);\n }\n\n 100% {\n transform: scale(1) rotate(0);\n }\n}\n.jBox-animated-tadaSmall {\n animation: jBox-tadaSmall 1s;\n}\n@keyframes jBox-flash {\n 0%, 50%, 100% {\n opacity: 1;\n }\n\n 25%, 75% {\n opacity: 0;\n }\n}\n.jBox-animated-flash {\n animation: jBox-flash .5s;\n}\n@keyframes jBox-shake {\n 0%, 100% {\n transform: translateX(0);\n }\n\n 20%, 60% {\n transform: translateX(-6px);\n }\n\n 40%, 80% {\n transform: translateX(6px);\n }\n}\n.jBox-animated-shake {\n animation: jBox-shake .4s;\n}\n@keyframes jBox-pulseUp {\n 0% {\n transform: scale(1);\n }\n\n 50% {\n transform: scale(1.15);\n }\n\n 100% {\n transform: scale(1);\n }\n}\n.jBox-animated-pulseUp {\n animation: jBox-pulseUp .25s;\n}\n@keyframes jBox-pulseDown {\n 0% {\n transform: scale(1);\n }\n\n 50% {\n transform: scale(0.85);\n }\n\n 100% {\n transform: scale(1);\n }\n}\n.jBox-animated-pulseDown {\n animation: jBox-pulseDown .25s;\n}\n@keyframes jBox-popIn {\n 0% {\n transform: scale(0);\n }\n\n 50% {\n transform: scale(1.1);\n }\n\n 100% {\n transform: scale(1);\n }\n}\n.jBox-animated-popIn {\n animation: jBox-popIn .25s;\n}\n@keyframes jBox-popOut {\n 0% {\n transform: scale(1);\n }\n\n 50% {\n transform: scale(1.1);\n }\n\n 100% {\n transform: scale(0);\n }\n}\n.jBox-animated-popOut {\n animation: jBox-popOut .25s;\n}\n@keyframes jBox-fadeIn {\n 0% {\n opacity: 0;\n }\n\n 100% {\n opacity: 1;\n }\n}\n.jBox-animated-fadeIn {\n animation: jBox-fadeIn .2s;\n}\n@keyframes jBox-fadeOut {\n 0% {\n opacity: 1;\n }\n\n 100% {\n opacity: 0;\n }\n}\n.jBox-animated-fadeOut {\n animation: jBox-fadeOut .2s;\n}\n@keyframes jBox-slideUp {\n 0% {\n transform: translateY(0);\n }\n\n 100% {\n transform: translateY(-300px);\n opacity: 0;\n }\n}\n.jBox-animated-slideUp {\n animation: jBox-slideUp .4s;\n}\n@keyframes jBox-slideRight {\n 0% {\n transform: translateX(0);\n }\n\n 100% {\n transform: translateX(300px);\n opacity: 0;\n }\n}\n.jBox-animated-slideRight {\n animation: jBox-slideRight .4s;\n}\n@keyframes jBox-slideDown {\n 0% {\n transform: translateY(0);\n }\n\n 100% {\n transform: translateY(300px);\n opacity: 0;\n }\n}\n.jBox-animated-slideDown {\n animation: jBox-slideDown .4s;\n}\n@keyframes jBox-slideLeft {\n 0% {\n transform: translateX(0);\n }\n\n 100% {\n transform: translateX(-300px);\n opacity: 0;\n }\n}\n.jBox-animated-slideLeft {\n animation: jBox-slideLeft .4s;\n}\n.jBox-Confirm .jBox-content {\n text-align: center;\n padding: 46px 35px;\n}\n@media (max-width: 500px) {\n .jBox-Confirm .jBox-content {\n padding: 32px 20px;\n }\n}\n.jBox-Confirm-footer {\n height: 46px;\n}\n.jBox-Confirm-button {\n display: block;\n float: left;\n cursor: pointer;\n text-align: center;\n width: 50%;\n line-height: 46px;\n height: 46px;\n overflow: hidden;\n padding: 0 10px;\n transition: color .2s, background-color .2s;\n box-sizing: border-box;\n}\n.jBox-Confirm-button-cancel {\n border-bottom-left-radius: 4px;\n background: #ddd;\n color: #666;\n}\n.jBox-Confirm-button-cancel:hover,\n.jBox-Confirm-button-cancel:active {\n background: #ccc;\n}\n.jBox-Confirm-button-cancel:active {\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n.jBox-Confirm-button-submit {\n border-bottom-right-radius: 4px;\n background: #7d0;\n color: #fff;\n}\n.jBox-Confirm-button-submit:hover,\n.jBox-Confirm-button-submit:active {\n background: #6c0;\n}\n.jBox-Confirm-button-submit:active {\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n.jBox-Image .jBox-container {\n background-color: transparent;\n}\n.jBox-Image .jBox-content {\n padding: 0;\n width: 100%;\n height: 100%;\n}\n.jBox-image-container {\n background: center center no-repeat;\n position: absolute;\n width: 100%;\n height: 100%;\n opacity: 0;\n}\n.jBox-image-label-wrapper {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n height: 40px;\n z-index: 100;\n display: flex;\n}\n.jBox-image-label-container {\n position: relative;\n flex: 1;\n}\n.jBox-image-label {\n box-sizing: border-box;\n position: absolute;\n left: 0;\n bottom: 0;\n width: 100%;\n text-align: center;\n color: #fff;\n padding: 8px 12px;\n font-size: 15px;\n line-height: 24px;\n transition: opacity .36s;\n opacity: 0;\n z-index: 0;\n pointer-events: none;\n}\n.jBox-image-label.expanded {\n background: #000;\n}\n.jBox-image-label:not(.expanded) {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n}\n.jBox-image-label.active {\n opacity: 1;\n pointer-events: all;\n}\n@media (max-width: 600px) {\n .jBox-image-label {\n font-size: 13px;\n }\n}\n.jBox-image-pointer-next,\n.jBox-image-pointer-prev {\n flex-shrink: 0;\n width: 40px;\n height: 40px;\n cursor: pointer;\n opacity: .8;\n transition: opacity .2s;\n background: no-repeat center center url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ijc0LjcgMjI0IDE4LjcgMzIiPg0KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTkzLDIyNy40TDgwLjQsMjQwTDkzLDI1Mi42YzAuNCwwLjQsMC40LDEuMSwwLDEuNWwtMS42LDEuNmMtMC40LDAuNC0xLDAuNS0xLjUsMEw3NSwyNDAuN2MtMC40LTAuNC0wLjUtMSwwLTEuNWwxNC45LTE0LjljMC40LTAuNCwxLTAuNCwxLjUsMGwxLjYsMS42QzkzLjUsMjI2LjQsOTMuNCwyMjcsOTMsMjI3LjR6Ii8+DQo8L3N2Zz4=);\n background-size: 11px auto;\n user-select: none;\n z-index: 1;\n}\n.jBox-image-pointer-next:hover,\n.jBox-image-pointer-prev:hover {\n opacity: 1;\n}\n.jBox-image-pointer-next {\n transform: scaleX(-1);\n}\n.jBox-image-counter-container {\n flex-shrink: 0;\n white-space: nowrap;\n height: 40px;\n line-height: 40px;\n font-size: 13px;\n color: #fff;\n text-align: right;\n display: none;\n}\n.jBox-image-has-counter .jBox-image-counter-container {\n display: block;\n}\n.jBox-overlay.jBox-overlay-Image {\n background: #000;\n}\n.jBox-image-not-found {\n background: #000;\n}\n.jBox-image-not-found:before {\n content: '';\n box-sizing: border-box;\n display: block;\n width: 80px;\n height: 80px;\n margin-top: -40px;\n margin-left: -40px;\n position: absolute;\n top: 50%;\n left: 50%;\n border: 5px solid #222;\n border-radius: 50%;\n}\n.jBox-image-not-found:after {\n content: '';\n display: block;\n box-sizing: content-box;\n z-index: auto;\n width: 6px;\n height: 74px;\n margin-top: -37px;\n margin-left: -3px;\n position: absolute;\n top: 50%;\n left: 50%;\n background: #222;\n transform: rotateZ(45deg);\n transform-origin: 50% 50% 0;\n}\n.jBox-image-download-button-wrapper {\n position: absolute;\n top: -40px;\n right: 35px;\n height: 40px;\n display: flex;\n cursor: pointer;\n opacity: .8;\n transition: opacity .2s;\n}\n.jBox-image-download-button-wrapper:hover {\n opacity: 1;\n}\n.jBox-image-download-button-icon {\n width: 40px;\n height: 40px;\n background: center center no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNDE2IDI1NnYtMTkyaC0xOTJ2MTkyaC0xNjBsMjU2IDI1NiAyNTYtMjU2aC0xNjB6TTAgNTc2aDY0MHY2NGgtNjQwdi02NHoiPjwvcGF0aD48L3N2Zz4=);\n background-size: 60%;\n}\n.jBox-image-download-button-text {\n white-space: nowrap;\n line-height: 40px;\n padding: 0 10px 0 0;\n color: #fff;\n font-size: 14px;\n}\n@keyframes jBoxImageLoading {\n to {\n transform: rotate(360deg);\n }\n}\n.jBox-image-loading:before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n width: 32px;\n height: 32px;\n margin-top: -16px;\n margin-left: -16px;\n border: 4px solid #333;\n border-bottom-color: #666;\n animation: jBoxImageLoading 1.2s linear infinite;\n border-radius: 50%;\n}\n.jBox-Notice {\n transition: margin .2s;\n}\n.jBox-Notice .jBox-container {\n border-radius: 4px;\n box-shadow: inset 1px 1px 0 0 rgba(255, 255, 255, 0.25), inset -1px -1px 0 0 rgba(0, 0, 0, 0.1);\n}\n.jBox-Notice .jBox-content {\n border-radius: 4px;\n padding: 12px 20px;\n}\n@media (max-width: 768px) {\n .jBox-Notice .jBox-content {\n padding: 10px 15px;\n }\n}\n@media (max-width: 500px) {\n .jBox-Notice .jBox-content {\n padding: 8px 10px;\n }\n}\n.jBox-Notice.jBox-hasTitle .jBox-content {\n padding-top: 5px;\n}\n@media (max-width: 500px) {\n .jBox-Notice.jBox-hasTitle .jBox-content {\n padding-top: 0;\n }\n}\n.jBox-Notice.jBox-hasTitle .jBox-title {\n padding: 12px 20px 0;\n font-weight: bold;\n}\n@media (max-width: 768px) {\n .jBox-Notice.jBox-hasTitle .jBox-title {\n padding: 10px 15px 0;\n }\n}\n@media (max-width: 500px) {\n .jBox-Notice.jBox-hasTitle .jBox-title {\n padding: 8px 10px 0;\n }\n}\n.jBox-Notice.jBox-closeButton-title .jBox-title {\n padding-right: 55px;\n}\n.jBox-Notice.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton {\n width: 40px;\n}\n.jBox-Notice.jBox-Notice-black .jBox-container {\n color: #fff;\n background: #000;\n}\n.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,\n.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {\n fill: #fff;\n}\n.jBox-Notice.jBox-Notice-gray .jBox-container {\n color: #222;\n background: #f6f6f6;\n}\n.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,\n.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {\n fill: #222;\n}\n.jBox-Notice.jBox-Notice-red .jBox-container {\n color: #fff;\n background: #d00;\n}\n.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,\n.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {\n fill: #fff;\n}\n.jBox-Notice.jBox-Notice-green .jBox-container {\n color: #fff;\n background: #5d0;\n}\n.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,\n.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {\n fill: #fff;\n}\n.jBox-Notice.jBox-Notice-blue .jBox-container {\n color: #fff;\n background: #49d;\n}\n.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,\n.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {\n fill: #fff;\n}\n.jBox-Notice.jBox-Notice-yellow .jBox-container {\n color: #000;\n background: #fd0;\n}\n.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,\n.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {\n fill: #fff;\n}\n.jBox-NoticeFancy .jBox-content,\n.jBox-NoticeFancy .jBox-title {\n padding-left: 25px;\n}\n.jBox-NoticeFancy.jBox-Notice-color .jBox-container {\n color: #fff;\n background: #000;\n}\n.jBox-NoticeFancy.jBox-Notice-color .jBox-container:after {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 8px;\n border-radius: 4px 0 0 4px;\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.4) 75%, transparent 75%, transparent);\n background-size: 14px 14px;\n}\n.jBox-NoticeFancy.jBox-Notice-black .jBox-container:after,\n.jBox-NoticeFancy.jBox-Notice-gray .jBox-container:after {\n background-color: #888;\n}\n.jBox-NoticeFancy.jBox-Notice-red .jBox-container:after {\n background-color: #e00;\n}\n.jBox-NoticeFancy.jBox-Notice-green .jBox-container:after {\n background-color: #6c0;\n}\n.jBox-NoticeFancy.jBox-Notice-blue .jBox-container:after {\n background-color: #49d;\n}\n.jBox-NoticeFancy.jBox-Notice-yellow .jBox-container:after {\n background-color: #fb0;\n}\n.jBox-NoticeFancy .jBox-countdown {\n left: 8px;\n border-radius: 0 4px 0 0;\n}\n.jBox-TooltipBorder .jBox-container,\n.jBox-TooltipBorder .jBox-pointer:after {\n border: 2px solid #49d;\n}\n.jBox-TooltipBorder .jBox-pointer:after {\n width: 22px;\n height: 22px;\n}\n.jBox-TooltipBorder .jBox-pointer-top,\n.jBox-TooltipBorder .jBox-pointer-bottom {\n width: 34px;\n height: 13px;\n}\n.jBox-TooltipBorder .jBox-pointer-top:after,\n.jBox-TooltipBorder .jBox-pointer-bottom:after {\n left: 6px;\n}\n.jBox-TooltipBorder .jBox-pointer-left,\n.jBox-TooltipBorder .jBox-pointer-right {\n width: 13px;\n height: 34px;\n}\n.jBox-TooltipBorder .jBox-pointer-left:after,\n.jBox-TooltipBorder .jBox-pointer-right:after {\n top: 6px;\n}\n.jBox-TooltipBorder.jBox-closeButton-box:before {\n width: 28px;\n height: 28px;\n background: #49d;\n}\n.jBox-TooltipBorderThick .jBox-container {\n box-shadow: none;\n border-radius: 8px;\n border: 4px solid #ccc;\n}\n.jBox-TooltipBorderThick .jBox-pointer:after {\n box-shadow: none;\n border: 4px solid #ccc;\n width: 24px;\n height: 24px;\n}\n.jBox-TooltipBorderThick .jBox-pointer-top,\n.jBox-TooltipBorderThick .jBox-pointer-bottom {\n width: 38px;\n height: 13px;\n}\n.jBox-TooltipBorderThick .jBox-pointer-left,\n.jBox-TooltipBorderThick .jBox-pointer-right {\n width: 13px;\n height: 38px;\n}\n.jBox-TooltipBorderThick.jBox-closeButton-box:before {\n width: 32px;\n height: 32px;\n background: #ccc;\n}\n.jBox-TooltipDark .jBox-container {\n border-radius: 4px;\n background: #000;\n color: #fff;\n box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);\n}\n.jBox-TooltipDark .jBox-pointer:after {\n background: #000;\n}\n.jBox-TooltipDark .jBox-closeButton {\n background: #000;\n}\n.jBox-TooltipDark.jBox-closeButton-box:before {\n box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);\n}\n.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton path {\n fill: #ddd;\n}\n.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:hover path {\n fill: #fff;\n}\n.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:active path {\n fill: #bbb;\n}\n.jBox-TooltipError {\n pointer-events: none;\n}\n.jBox-TooltipError .jBox-container {\n border-radius: 2px;\n background: #d00;\n color: #fff;\n font-weight: bold;\n font-size: 13px;\n}\n.jBox-TooltipError .jBox-content {\n padding: 0 10px;\n line-height: 28px;\n}\n.jBox-TooltipError .jBox-pointer:after {\n background: #d00;\n width: 20px;\n height: 20px;\n}\n.jBox-TooltipError .jBox-pointer-top,\n.jBox-TooltipError .jBox-pointer-bottom {\n width: 22px;\n height: 8px;\n}\n.jBox-TooltipError .jBox-pointer-right,\n.jBox-TooltipError .jBox-pointer-left {\n width: 8px;\n height: 22px;\n}\n.jBox-TooltipError .jBox-pointer-top:after {\n left: 1px;\n top: 6px;\n}\n.jBox-TooltipError .jBox-pointer-right:after {\n top: 1px;\n right: 6px;\n}\n.jBox-TooltipError .jBox-pointer-bottom:after {\n left: 1px;\n bottom: 6px;\n}\n.jBox-TooltipError .jBox-pointer-left:after {\n top: 1px;\n left: 6px;\n}\n.jBox-TooltipSmall {\n pointer-events: none;\n}\n.jBox-TooltipSmall .jBox-container {\n border-radius: 2px;\n}\n.jBox-TooltipSmall .jBox-content {\n padding: 0 10px;\n line-height: 28px;\n}\n.jBox-TooltipSmall .jBox-pointer:after {\n width: 20px;\n height: 20px;\n}\n.jBox-TooltipSmall .jBox-pointer-top,\n.jBox-TooltipSmall .jBox-pointer-bottom {\n width: 22px;\n height: 8px;\n}\n.jBox-TooltipSmall .jBox-pointer-right,\n.jBox-TooltipSmall .jBox-pointer-left {\n width: 8px;\n height: 22px;\n}\n.jBox-TooltipSmall .jBox-pointer-top:after {\n left: 1px;\n top: 6px;\n}\n.jBox-TooltipSmall .jBox-pointer-right:after {\n top: 1px;\n right: 6px;\n}\n.jBox-TooltipSmall .jBox-pointer-bottom:after {\n left: 1px;\n bottom: 6px;\n}\n.jBox-TooltipSmall .jBox-pointer-left:after {\n top: 1px;\n left: 6px;\n}\n.jBox-TooltipSmallGray {\n pointer-events: none;\n}\n.jBox-TooltipSmallGray .jBox-container {\n font-size: 13px;\n line-height: 24px;\n border-radius: 12px;\n background-image: linear-gradient(to bottom, #fafafa, #f2f2f2);\n}\n.jBox-TooltipSmallGray .jBox-content {\n padding: 0 10px;\n}\n.jBox-TooltipSmallGray .jBox-pointer:after {\n width: 20px;\n height: 20px;\n}\n.jBox-TooltipSmallGray .jBox-pointer-top,\n.jBox-TooltipSmallGray .jBox-pointer-bottom {\n width: 22px;\n height: 8px;\n}\n.jBox-TooltipSmallGray .jBox-pointer-left,\n.jBox-TooltipSmallGray .jBox-pointer-right {\n width: 8px;\n height: 22px;\n}\n.jBox-TooltipSmallGray .jBox-pointer-top:after {\n background: #fafafa;\n left: 1px;\n top: 6px;\n}\n.jBox-TooltipSmallGray .jBox-pointer-right:after {\n top: 1px;\n right: 6px;\n}\n.jBox-TooltipSmallGray .jBox-pointer-bottom:after {\n background: #f2f2f2;\n left: 1px;\n bottom: 6px;\n}\n.jBox-TooltipSmallGray .jBox-pointer-left:after {\n top: 1px;\n left: 6px;\n}\n/*# sourceMappingURL=jBox.all.css.map */\n"; (require("browserify-css").createStyle(css, { "href": "node_modules/jbox/dist/jBox.all.css" }, { "insertAt": "bottom" })); module.exports = css;
|
|
},{"browserify-css":55}],57:[function(require,module,exports){
|
|
function jBoxWrapper(b){function h(t,i){return this.options={id:null,width:"auto",height:"auto",minWidth:null,minHeight:null,maxWidth:null,maxHeight:null,responsiveWidth:!0,responsiveHeight:!0,responsiveMinWidth:100,responsiveMinHeight:100,attach:null,trigger:"click",preventDefault:!1,content:null,getContent:null,title:null,getTitle:null,footer:null,isolateScroll:!0,ajax:{url:null,data:"",reload:!1,getURL:"data-url",getData:"data-ajax",setContent:!0,loadingClass:!0,spinner:!0,spinnerDelay:300,spinnerReposition:!0},cancelAjaxOnClose:!0,target:null,position:{x:"center",y:"center"},outside:null,offset:0,attributes:{x:"left",y:"top"},fixed:!1,adjustPosition:!0,adjustTracker:!1,adjustDistance:5,reposition:!0,repositionOnOpen:!0,repositionOnContent:!0,holdPosition:!0,pointer:!1,pointTo:"target",fade:180,animation:null,theme:"Default",addClass:null,overlay:!1,overlayClass:null,zIndex:1e4,delayOpen:0,delayClose:0,closeOnEsc:!1,closeOnClick:!1,closeOnMouseleave:!1,closeButton:!1,appendTo:b("body"),createOnInit:!1,blockScroll:!1,blockScrollAdjust:!0,draggable:!1,dragOver:!0,autoClose:!1,delayOnHover:!1,showCountdown:!1,preloadAudio:!0,audio:null,volume:100,onInit:null,onAttach:null,onPosition:null,onCreated:null,onOpen:null,onClose:null,onCloseComplete:null,onDragStart:null,onDragEnd:null},this._pluginOptions={Tooltip:{getContent:"title",trigger:"mouseenter",position:{x:"center",y:"top"},outside:"y",pointer:!0},Mouse:{responsiveWidth:!1,responsiveHeight:!1,adjustPosition:"flip",target:"mouse",trigger:"mouseenter",position:{x:"right",y:"bottom"},outside:"xy",offset:5},Modal:{target:b(window),fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"overlay",closeButton:!0,overlay:!0,animation:"zoomIn"}},this.options=b.extend(!0,this.options,this._pluginOptions[t]||h._pluginOptions[t],i),"string"==b.type(t)&&(this.type=t),this.isTouchDevice=function(){var t=" -webkit- -moz- -o- -ms- ".split(" ");if("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)return!0;var i,t=["(",t.join("touch-enabled),("),"heartz",")"].join("");return i=t,window.matchMedia(i).matches}(),this.isTouchDevice&&"mouseenter"===this.options.trigger&&!1===this.options.closeOnClick&&(this.options.closeOnClick="body"),this._fireEvent=function(t,i){this.options["_"+t]&&this.options["_"+t].bind(this)(i),this.options[t]&&this.options[t].bind(this)(i)},null===this.options.id&&(this.options.id="jBox"+h._getUniqueID()),this.id=this.options.id,("center"==this.options.position.x&&"x"==this.options.outside||"center"==this.options.position.y&&"y"==this.options.outside)&&(this.options.outside=null),"target"!=this.options.pointTo||this.options.outside&&"xy"!=this.options.outside||(this.options.pointer=!1),"object"!=b.type(this.options.offset)?this.options.offset={x:this.options.offset,y:this.options.offset}:this.options.offset=b.extend({x:0,y:0},this.options.offset),"object"!=b.type(this.options.adjustDistance)?this.options.adjustDistance={top:this.options.adjustDistance,right:this.options.adjustDistance,bottom:this.options.adjustDistance,left:this.options.adjustDistance}:this.options.adjustDistance=b.extend({top:5,left:5,right:5,bottom:5},this.options.adjustDistance),this.outside=!(!this.options.outside||"xy"==this.options.outside)&&this.options.position[this.options.outside],this.align=this.outside||("center"!=this.options.position.y&&"number"!=b.type(this.options.position.y)?this.options.position.x:"center"!=this.options.position.x&&"number"!=b.type(this.options.position.x)?this.options.position.y:this.options.attributes.x),h.zIndexMax=Math.max(h.zIndexMax||0,"auto"===this.options.zIndex?1e4:this.options.zIndex),"auto"===this.options.zIndex&&(this.adjustZIndexOnOpen=!0,h.zIndexMax+=2,this.options.zIndex=h.zIndexMax,this.trueModal=this.options.overlay),this._getOpp=function(t){return{left:"right",right:"left",top:"bottom",bottom:"top",x:"y",y:"x"}[t]},this._getXY=function(t){return{left:"x",right:"x",top:"y",bottom:"y",center:"x"}[t]},this._getTL=function(t){return{left:"left",right:"left",top:"top",bottom:"top",center:"left",x:"left",y:"top"}[t]},this._getInt=function(t,i){return"auto"==t?"auto":t&&"string"==b.type(t)&&"%"==t.slice(-1)?b(window)["height"==i?"innerHeight":"innerWidth"]()*parseInt(t.replace("%",""))/100:t},this._createSVG=function(t,i){var o=document.createElementNS("http://www.w3.org/2000/svg",t);return b.each(i,function(t,i){o.setAttribute(i[0],i[1]||"")}),o},this._isolateScroll=function(e){e&&e.length&&e.on("DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll",function(t){var i=t.wheelDelta||t.originalEvent&&t.originalEvent.wheelDelta||-t.detail,o=0<=this.scrollTop+e.outerHeight()-this.scrollHeight,s=this.scrollTop<=0;(i<0&&o||0<i&&s)&&t.preventDefault()})},this._setTitleWidth=function(){if(!this.titleContainer||"auto"==this.content[0].style.width&&!this.content[0].style.maxWidth)return null;var t;"none"==this.wrapper.css("display")?(this.wrapper.css("display","block"),t=this.content.outerWidth(),this.wrapper.css("display","none")):t=this.content.outerWidth(),this.titleContainer.css({maxWidth:Math.max(t,parseInt(this.content[0].style.maxWidth))||null})},this._draggable=function(){if(!this.options.draggable)return!1;var t="title"==this.options.draggable?this.titleContainer:this.options.draggable instanceof b?this.options.draggable:"string"==b.type(this.options.draggable)?b(this.options.draggable):this.wrapper;return!(!(t&&t instanceof b&&t.length)||t.data("jBox-draggable"))&&(t.addClass("jBox-draggable").data("jBox-draggable",!0).on("touchstart mousedown",function(t){var i,o,s,e,n,a;2==t.button||b(t.target).hasClass("jBox-noDrag")||b(t.target).parents(".jBox-noDrag").length?"touchstart"==t.type&&(b(t.target).hasClass("jBox-closeButton")||b(t.target).parents(".jBox-closeButton").length)&&this.close({ignoreDelay:!0}):(o="touchstart"==t.type&&t.touches&&t.touches[0]?(i=t.touches[0].pageX,t.touches[0].pageY):(i=t.pageX,t.pageY),this.draggingStartX=i,this.draggingStartY=o,this.options.dragOver&&!this.trueModal&&parseInt(this.wrapper.css("zIndex"),10)<=h.zIndexMaxDragover&&(h.zIndexMaxDragover+=1,this.wrapper.css("zIndex",h.zIndexMaxDragover)),s=this.wrapper.outerHeight(),e=this.wrapper.outerWidth(),n=this.wrapper.offset().top+s-o,a=this.wrapper.offset().left+e-i,b(document).on("touchmove.jBox-draggable-"+this.id+" mousemove.jBox-draggable-"+this.id,function(t){var i,t="touchmove"==t.type&&t.touches&&t.touches[0]?(i=t.touches[0].pageX,t.touches[0].pageY):(i=t.pageX,t.pageY);this.dragging||this.draggingStartX==i||this.draggingStartY==t||(this._fireEvent("onDragStart"),this.dragging=!0),this.wrapper.offset({top:t+n-s,left:i+a-e})}.bind(this)),t.preventDefault())}.bind(this)).on("touchend mouseup",function(){var t;b(document).off("touchmove.jBox-draggable-"+this.id+" mousemove.jBox-draggable-"+this.id),this.dragging&&this._fireEvent("onDragEnd"),this.dragging=!1,"Modal"!=this.type&&"Confirm"!=this.type||!this.options.holdPosition||(t={x:(t=b("#"+this.id).offset()).left-b(document).scrollLeft(),y:t.top-b(document).scrollTop()},this.position({position:t,offset:{x:0,y:0}}))}.bind(this)),this.trueModal||(h.zIndexMaxDragover=h.zIndexMaxDragover?Math.max(h.zIndexMaxDragover,this.options.zIndex):this.options.zIndex),this)},this._create=function(){var t;this.wrapper||(this.wrapper=b("<div/>",{id:this.id,class:"jBox-wrapper"+(this.type?" jBox-"+this.type:"")+(this.options.theme?" jBox-"+this.options.theme:"")+(this.options.addClass?" "+this.options.addClass:"")}).css({position:this.options.fixed?"fixed":"absolute",display:"none",opacity:0,zIndex:this.options.zIndex}).data("jBox",this),this.options.closeOnMouseleave&&this.wrapper.on("mouseleave",function(t){!this.source||t.relatedTarget!=this.source[0]&&-1===b.inArray(this.source[0],b(t.relatedTarget).parents("*"))&&this.close()}.bind(this)),"box"==this.options.closeOnClick&&this.wrapper.on("click tap",function(){this.close({ignoreDelay:!0})}.bind(this)),this.container=b('<div class="jBox-container"/>').appendTo(this.wrapper),this.content=b('<div class="jBox-content"/>').appendTo(this.container),this.options.footer&&(this.footer=b('<div class="jBox-footer"/>').append(this.options.footer).appendTo(this.container)),this.options.isolateScroll&&this._isolateScroll(this.content),this.options.closeButton&&((t=this._createSVG("svg",[["viewBox","0 0 24 24"]])).appendChild(this._createSVG("path",[["d","M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z"]])),this.closeButton=b('<div class="jBox-closeButton jBox-noDrag"/>').on("click tap",function(t){this.close({ignoreDelay:!0})}.bind(this)).append(t),"box"!=this.options.closeButton&&(!0!==this.options.closeButton||this.options.overlay||this.options.title||this.options.getTitle)||(this.wrapper.addClass("jBox-closeButton-box"),this.closeButton.appendTo(this.container))),this.wrapper.appendTo(this.options.appendTo),this.wrapper.find(".jBox-closeButton").length&&b.each(["top","right","bottom","left"],function(t,i){this.wrapper.find(".jBox-closeButton").css(i)&&"auto"!=this.wrapper.find(".jBox-closeButton").css(i)&&(this.options.adjustDistance[i]=Math.max(this.options.adjustDistance[i],this.options.adjustDistance[i]+-1*((parseInt(this.wrapper.find(".jBox-closeButton").css(i))||0)+(parseInt(this.container.css("border-"+i+"-width"))||0))))}.bind(this)),this.options.pointer&&(this.pointer={position:"target"!=this.options.pointTo?this.options.pointTo:this._getOpp(this.outside),xy:"target"!=this.options.pointTo?this._getXY(this.options.pointTo):this._getXY(this.outside),align:"center",offset:0},this.pointer.element=b('<div class="jBox-pointer jBox-pointer-'+this.pointer.position+'"/>').appendTo(this.wrapper),this.pointer.dimensions={x:this.pointer.element.outerWidth(),y:this.pointer.element.outerHeight()},"string"==b.type(this.options.pointer)&&((t=this.options.pointer.split(":"))[0]&&(this.pointer.align=t[0]),t[1]&&(this.pointer.offset=parseInt(t[1]))),this.pointer.alignAttribute="x"==this.pointer.xy?"bottom"==this.pointer.align?"bottom":"top":"right"==this.pointer.align?"right":"left",this.wrapper.css("padding-"+this.pointer.position,this.pointer.dimensions[this.pointer.xy]),this.pointer.element.css(this.pointer.alignAttribute,"center"==this.pointer.align?"50%":0).css("margin-"+this.pointer.alignAttribute,this.pointer.offset),this.pointer.margin={},this.pointer.margin["margin-"+this.pointer.alignAttribute]=this.pointer.offset,"center"==this.pointer.align&&this.pointer.element.css("transform","translate("+("y"==this.pointer.xy?-.5*this.pointer.dimensions.x+"px":0)+", "+("x"==this.pointer.xy?-.5*this.pointer.dimensions.y+"px":0)+")"),this.pointer.element.css("x"==this.pointer.xy?"width":"height",parseInt(this.pointer.dimensions[this.pointer.xy])+parseInt(this.container.css("border-"+this.pointer.alignAttribute+"-width"))),this.wrapper.addClass("jBox-pointerPosition-"+this.pointer.position)),this.setContent(this.options.content,!0),this.setTitle(this.options.title,!0),this.options.draggable&&this._draggable(),this._fireEvent("onCreated"))},this.options.createOnInit&&this._create(),this.options.attach&&this.attach(),this._attachEvents=function(){this.options.delayOnHover&&b("#"+this.id).on("mouseenter",function(t){this.isHovered=!0}.bind(this)),this.options.delayOnHover&&b("#"+this.id).on("mouseleave",function(t){this.isHovered=!1}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&!this.fixed&&this.outside&&(this.options.adjustTracker&&b(window).on("scroll.jBox-"+this.id,function(t){this.position()}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&b(window).on("resize.jBox-"+this.id,function(t){this.position()}.bind(this))),"mouse"==this.options.target&&b("body").on("mousemove.jBox-"+this.id,function(t){this.position({mouseTarget:{top:t.pageY,left:t.pageX}})}.bind(this))},this._detachEvents=function(){this.options.closeOnEsc&&b(document).off("keyup.jBox-"+this.id),!0!==this.options.closeOnClick&&"body"!=this.options.closeOnClick||b(document).off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.options.adjustTracker&&b(window).off("scroll.jBox-"+this.id),(this.options.adjustPosition||this.options.reposition)&&b(window).off("resize.jBox-"+this.id),"mouse"==this.options.target&&b("body").off("mousemove.jBox-"+this.id)},this._showOverlay=function(){this.overlay||(this.overlay=b('<div id="'+this.id+'-overlay"/>').addClass("jBox-overlay"+(this.type?" jBox-overlay-"+this.type:"")).css({display:"none",opacity:0,zIndex:this.options.zIndex-1}).appendTo(this.options.appendTo),this.options.overlayClass&&this.overlay.addClass(this.options.overlayClass),"overlay"!=this.options.closeButton&&!0!==this.options.closeButton||this.overlay.append(this.closeButton),"overlay"==this.options.closeOnClick&&this.overlay.on("click tap",function(){this.close({ignoreDelay:!0})}.bind(this)),b("#"+this.id+"-overlay .jBox-closeButton").length&&(this.options.adjustDistance.top=Math.max(b("#"+this.id+"-overlay .jBox-closeButton").outerHeight(),this.options.adjustDistance.top))),!0===this.adjustZIndexOnOpen&&this.overlay.css("zIndex",parseInt(this.wrapper.css("zIndex"),10)-1),"block"!=this.overlay.css("display")&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.overlay.css({display:"block"})}.bind(this)}):this.overlay.css({display:"block",opacity:1}))},this._hideOverlay=function(){this.overlay&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:0},{queue:!1,duration:this.options.fade,complete:function(){this.overlay.css({display:"none"})}.bind(this)}):this.overlay.css({display:"none",opacity:0}))},this._exposeDimensions=function(){this.wrapper.css({top:-1e4,left:-1e4,right:"auto",bottom:"auto"});var t={x:this.wrapper.outerWidth(),y:this.wrapper.outerHeight()};return this.wrapper.css({top:"auto",left:"auto"}),t},this._generateAnimationCSS=function(){if("object"!=b.type(this.options.animation)&&(this.options.animation={pulse:{open:"pulse",close:"zoomOut"},zoomIn:{open:"zoomIn",close:"zoomIn"},zoomOut:{open:"zoomOut",close:"zoomOut"},move:{open:"move",close:"move"},slide:{open:"slide",close:"slide"},flip:{open:"flip",close:"flip"},tada:{open:"tada",close:"zoomOut"}}[this.options.animation]),!this.options.animation)return null;this.options.animation.open&&(this.options.animation.open=this.options.animation.open.split(":")),this.options.animation.close&&(this.options.animation.close=this.options.animation.close.split(":")),this.options.animation.openDirection=this.options.animation.open[1]||null,this.options.animation.closeDirection=this.options.animation.close[1]||null,this.options.animation.open&&(this.options.animation.open=this.options.animation.open[0]),this.options.animation.close&&(this.options.animation.close=this.options.animation.close[0]),this.options.animation.open&&(this.options.animation.open+="Open"),this.options.animation.close&&(this.options.animation.close+="Close");var a={pulse:{duration:350,css:[["0%","scale(1)"],["50%","scale(1.1)"],["100%","scale(1)"]]},zoomInOpen:{duration:this.options.fade||180,css:[["0%","scale(0.9)"],["100%","scale(1)"]]},zoomInClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(0.9)"]]},zoomOutOpen:{duration:this.options.fade||180,css:[["0%","scale(1.1)"],["100%","scale(1)"]]},zoomOutClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(1.1)"]]},moveOpen:{duration:this.options.fade||180,positions:{top:{"0%":-12},right:{"0%":12},bottom:{"0%":12},left:{"0%":-12}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},moveClose:{duration:this.options.fade||180,timing:"ease-in",positions:{top:{"100%":-12},right:{"100%":12},bottom:{"100%":12},left:{"100%":-12}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},slideOpen:{duration:400,positions:{top:{"0%":-400},right:{"0%":400},bottom:{"0%":400},left:{"0%":-400}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},slideClose:{duration:400,timing:"ease-in",positions:{top:{"100%":-400},right:{"100%":400},bottom:{"100%":400},left:{"100%":-400}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},flipOpen:{duration:600,css:[["0%","perspective(400px) rotateX(90deg)"],["40%","perspective(400px) rotateX(-15deg)"],["70%","perspective(400px) rotateX(15deg)"],["100%","perspective(400px) rotateX(0deg)"]]},flipClose:{duration:this.options.fade||300,css:[["0%","perspective(400px) rotateX(0deg)"],["100%","perspective(400px) rotateX(90deg)"]]},tada:{duration:800,css:[["0%","scale(1)"],["10%, 20%","scale(0.9) rotate(-3deg)"],["30%, 50%, 70%, 90%","scale(1.1) rotate(3deg)"],["40%, 60%, 80%","scale(1.1) rotate(-3deg)"],["100%","scale(1) rotate(0)"]]}};b.each(["pulse","tada"],function(t,i){a[i+"Open"]=a[i+"Close"]=a[i]});var s=function(s,e){var n="@keyframes jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+" {";return b.each(a[this.options.animation[s]].css,function(t,i){var o=e?i[1].replace("%XY",this._getXY(e).toUpperCase()):i[1];a[this.options.animation[s]].positions&&(o=o.replace("%V",a[this.options.animation[s]].positions[e][i[0]])),n+=i[0]+" {transform:"+o+";}"}.bind(this)),n+="}",n+=".jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+" {",n+="animation-duration: "+a[this.options.animation[s]].duration+"ms;",n+="animation-name: jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+";",n+=a[this.options.animation[s]].timing?"animation-timing-function: "+a[this.options.animation[s]].timing+";":"",n+="}"}.bind(this);this._animationCSS="",b.each(["open","close"],function(t,o){if(!this.options.animation[o]||!a[this.options.animation[o]]||"close"==o&&!this.options.fade)return"";a[this.options.animation[o]].positions?b.each(["top","right","bottom","left"],function(t,i){this._animationCSS+=s(o,i)}.bind(this)):this._animationCSS+=s(o)}.bind(this))},this.options.animation&&this._generateAnimationCSS(),this._blockBodyClick=function(){this.blockBodyClick=!0,setTimeout(function(){this.blockBodyClick=!1}.bind(this),10)},this._animate=function(t){if(t=t||(this.isOpen?"open":"close"),!this.options.fade&&"close"==t)return null;var i=this.options.animation[t+"Direction"]||("center"!=this.align?this.align:this.options.attributes.x);this.flipped&&this._getXY(i)==this._getXY(this.align)&&(i=this._getOpp(i));var o="jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+" jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+"-"+i;this.wrapper.addClass(o);i=1e3*parseFloat(this.wrapper.css("animation-duration"));"close"==t&&(i=Math.min(i,this.options.fade)),setTimeout(function(){this.wrapper.removeClass(o)}.bind(this),i)},this._abortAnimation=function(){var t=this.wrapper.attr("class").split(" ").filter(function(t){return 0!==t.lastIndexOf("jBox-"+this.id+"-animation",0)}.bind(this));this.wrapper.attr("class",t.join(" "))},(this.options.responsiveWidth||this.options.responsiveHeight)&&b(window).on("resize.responsivejBox-"+this.id,function(t){this.isOpen&&this.position()}.bind(this)),"string"===b.type(this.options.preloadAudio)&&(this.options.preloadAudio=[this.options.preloadAudio]),"string"===b.type(this.options.audio)&&(this.options.audio={open:this.options.audio}),"number"===b.type(this.options.volume)&&(this.options.volume={open:this.options.volume,close:this.options.volume}),!0===this.options.preloadAudio&&this.options.audio&&(this.options.preloadAudio=[],b.each(this.options.audio,function(t,i){this.options.preloadAudio.push(i+".mp3"),this.options.preloadAudio.push(i+".ogg")}.bind(this))),this.options.preloadAudio.length&&b.each(this.options.preloadAudio,function(t,i){var o=new Audio;o.src=i,o.preload="auto"}),this._fireEvent("onInit"),this}var t,i;return h.prototype.attach=function(t,s){return t=t||this.options.attach,"string"==b.type(t)&&(t=b(t)),s=s||this.options.trigger,t&&t.length&&b.each(t,function(t,o){(o=b(o)).data("jBox-attached-"+this.id)||("title"==this.options.getContent&&null!=o.attr("title")&&o.data("jBox-getContent",o.attr("title")).removeAttr("title"),this.attachedElements||(this.attachedElements=[]),this.attachedElements.push(o[0]),o.on(s+".jBox-attach-"+this.id,function(t){var i;this.timer&&clearTimeout(this.timer),"mouseenter"==s&&this.isOpen&&this.source[0]==o[0]||(this.isOpen&&this.source&&this.source[0]!=o[0]&&(i=!0),this.source=o,this.options.target||(this.target=o),"click"==s&&this.options.preventDefault&&t.preventDefault(),this["click"!=s||i?"open":"toggle"]())}.bind(this)),"mouseenter"==this.options.trigger&&o.on("mouseleave",function(t){if(!this.wrapper)return null;this.options.closeOnMouseleave&&(t.relatedTarget==this.wrapper[0]||b(t.relatedTarget).parents("#"+this.id).length)||this.close()}.bind(this)),o.data("jBox-attached-"+this.id,s),this._fireEvent("onAttach",o))}.bind(this)),this},h.prototype.detach=function(t){return(t=t||(this.attachedElements||[]))&&t.length&&b.each(t,function(t,i){(i=b(i)).data("jBox-attached-"+this.id)&&(i.off(i.data("jBox-attached-"+this.id)+".jBox-attach-"+this.id),i.data("jBox-attached-"+this.id,null)),this.attachedElements=b.grep(this.attachedElements,function(t){return t!=i[0]})}.bind(this)),this},h.prototype.setTitle=function(t,i){if(null==t||null==t)return this;this.wrapper||this._create();var o=this.wrapper.outerHeight(),s=this.wrapper.outerWidth();return this.title||(this.titleContainer=b('<div class="jBox-title"/>'),this.title=b("<div/>").appendTo(this.titleContainer),"title"!=this.options.closeButton&&(!0!==this.options.closeButton||this.options.overlay)||(this.wrapper.addClass("jBox-closeButton-title"),this.closeButton.appendTo(this.titleContainer)),this.titleContainer.insertBefore(this.content),this._setTitleWidth()),this.wrapper[t?"addClass":"removeClass"]("jBox-hasTitle"),this.title.html(t),s!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),i||!this.options.repositionOnContent||o==this.wrapper.outerHeight()&&s==this.wrapper.outerWidth()||this.position(),this},h.prototype.setContent=function(t,i){if(null==t||null==t)return this;this.wrapper||this._create();var o=this.wrapper.outerHeight(),s=this.wrapper.outerWidth();switch(this.content.children("[data-jbox-content-appended]").appendTo("body").css({display:"none"}),b.type(t)){case"string":this.content.html(t);break;case"object":t&&(t instanceof b||t.constructor.prototype.jquery)?(this.content.html(""),t.attr("data-jbox-content-appended",1).appendTo(this.content).css({display:"block"})):this.content.html(JSON.stringify(t))}return s!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),i||!this.options.repositionOnContent||o==this.wrapper.outerHeight()&&s==this.wrapper.outerWidth()||this.position(),this},h.prototype.setDimensions=function(t,i,o){this.wrapper||this._create(),null==i&&(i="auto"),this.content.css(t,this._getInt(i)),"width"==t&&this._setTitleWidth(),this.options[t]=i,null!=o&&!o||this.position()},h.prototype.setWidth=function(t,i){this.setDimensions("width",t,i)},h.prototype.setHeight=function(t,i){this.setDimensions("height",t,i)},h.prototype.position=function(o){if(o=o||{},o=b.extend(!0,this.options,o),this.target=o.target||this.target||b(window),this.target instanceof b||"mouse"==this.target||(this.target=b(this.target)),!this.target.length)return this;this.content.css({width:this._getInt(o.width,"width"),height:this._getInt(o.height,"height"),minWidth:this._getInt(o.minWidth,"width"),minHeight:this._getInt(o.minHeight,"height"),maxWidth:this._getInt(o.maxWidth,"width"),maxHeight:this._getInt(o.maxHeight,"height")}),this._setTitleWidth();var s=this._exposeDimensions();"mouse"==this.target||this.target.data("jBox-"+this.id+"-fixed")||this.target.data("jBox-"+this.id+"-fixed",this.target[0]!=b(window)[0]&&("fixed"==this.target.css("position")||0<this.target.parents().filter(function(){return"fixed"==b(this).css("position")}).length)?"fixed":"static");var t={x:b(window).outerWidth(),y:b(window).outerHeight(),top:o.fixed&&this.target.data("jBox-"+this.id+"-fixed")?0:b(window).scrollTop(),left:o.fixed&&this.target.data("jBox-"+this.id+"-fixed")?0:b(window).scrollLeft()};t.bottom=t.top+t.y,t.right=t.left+t.x;try{var i=this.target.offset()}catch(t){i={top:0,left:0}}"mouse"!=this.target&&"fixed"==this.target.data("jBox-"+this.id+"-fixed")&&o.fixed&&(i.top=i.top-b(window).scrollTop(),i.left=i.left-b(window).scrollLeft());var e={x:"mouse"==this.target?12:this.target.outerWidth(),y:"mouse"==this.target?20:this.target.outerHeight(),top:"mouse"==this.target&&o.mouseTarget?o.mouseTarget.top:i?i.top:0,left:"mouse"==this.target&&o.mouseTarget?o.mouseTarget.left:i?i.left:0},n=o.outside&&!("center"==o.position.x&&"center"==o.position.y),a={x:t.x-o.adjustDistance.left-o.adjustDistance.right,y:t.y-o.adjustDistance.top-o.adjustDistance.bottom,left:n?e.left-b(window).scrollLeft()-o.adjustDistance.left:0,right:n?t.x-e.left+b(window).scrollLeft()-e.x-o.adjustDistance.right:0,top:n?e.top-b(window).scrollTop()-this.options.adjustDistance.top:0,bottom:n?t.y-e.top+b(window).scrollTop()-e.y-o.adjustDistance.bottom:0},h={x:"x"!=o.outside&&"xy"!=o.outside||"number"==b.type(o.position.x)?null:o.position.x,y:"y"!=o.outside&&"xy"!=o.outside||"number"==b.type(o.position.y)?null:o.position.y},r={x:!1,y:!1};h.x&&s.x>a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),h.y&&s.y>a[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0),(o.responsiveWidth||o.responsiveHeight)&&(f=function(){var t;o.responsiveWidth&&s.x>a[h.x||"x"]&&(t=a[h.x||"x"]-(this.pointer&&n&&"x"==o.outside?this.pointer.dimensions.x:0)-parseInt(this.container.css("border-left-width"))-parseInt(this.container.css("border-right-width")),this.content.css({width:t>this.options.responsiveMinWidth?t:null,minWidth:t<parseInt(this.content.css("minWidth"))?0:null}),this._setTitleWidth()),s=this._exposeDimensions()}.bind(this),o.responsiveWidth&&f(),o.responsiveWidth&&!r.y&&h.y&&s.y>a[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0),x=function(){var t;o.responsiveHeight&&s.y>a[h.y||"y"]&&(t=function(){return this.titleContainer||this.footer?("none"==this.wrapper.css("display")?(this.wrapper.css("display","block"),t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0),this.wrapper.css("display","none")):t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0),t||0):0;var t}.bind(this),t=a[h.y||"y"]-(this.pointer&&n&&"y"==o.outside?this.pointer.dimensions.y:0)-t()-parseInt(this.container.css("border-top-width"))-parseInt(this.container.css("border-bottom-width")),this.content.css({height:t>this.options.responsiveMinHeight?t:null}),this._setTitleWidth()),s=this._exposeDimensions()}.bind(this),o.responsiveHeight&&x(),o.responsiveHeight&&!r.x&&h.x&&s.x>a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),o.adjustPosition&&"move"!=o.adjustPosition&&(r.x&&f(),r.y&&x()));var p={},l=function(t){if("number"!=b.type(o.position[t])){var i=o.attributes[t]="x"==t?"left":"top";if(p[i]=e[i],"center"==o.position[t])return p[i]+=Math.ceil((e[t]-s[t])/2),void("mouse"!=this.target&&this.target[0]&&this.target[0]==b(window)[0]&&(p[i]+=.5*(o.adjustDistance[i]-o.adjustDistance[this._getOpp(i)])));i!=o.position[t]&&(p[i]+=e[t]-s[t]),o.outside!=t&&"xy"!=o.outside||(p[i]+=s[t]*(i!=o.position[t]?1:-1))}else p[o.attributes[t]]=o.position[t]}.bind(this);if(l("x"),l("y"),this.pointer&&"target"==o.pointTo&&"number"!=b.type(o.position.x)&&"number"!=b.type(o.position.y)&&(y=0,"center"===this.pointer.align?"center"!=o.position[this._getOpp(o.outside)]&&(y+=s[this._getOpp(o.outside)]/2):"center"===o.position[this._getOpp(o.outside)]?y+=(s[this._getOpp(o.outside)]/2-this.pointer.dimensions[this._getOpp(o.outside)]/2)*(this.pointer.align==this._getTL(this.pointer.align)?1:-1):y+=this.pointer.align!=o.position[this._getOpp(o.outside)]?this.dimensions[this._getOpp(o.outside)]*(-1!==b.inArray(this.pointer.align,["top","left"])?1:-1)+this.pointer.dimensions[this._getOpp(o.outside)]/2*(-1!==b.inArray(this.pointer.align,["top","left"])?-1:1):this.pointer.dimensions[this._getOpp(o.outside)]/2*(-1!==b.inArray(this.pointer.align,["top","left"])?1:-1),y*=o.position[this._getOpp(o.outside)]==this.pointer.alignAttribute?-1:1,y+=this.pointer.offset*(this.pointer.align==this._getOpp(this._getTL(this.pointer.align))?1:-1),p[this._getTL(this._getOpp(this.pointer.xy))]+=y),p[o.attributes.x]+=o.offset.x,p[o.attributes.y]+=o.offset.y,this.wrapper.css(p),o.adjustPosition){this.positionAdjusted&&(this.pointer&&this.wrapper.css("padding",0).css("padding-"+this._getOpp(this.outside),this.pointer.dimensions[this._getXY(this.outside)]).removeClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).addClass("jBox-pointerPosition-"+this.pointer.position),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+this._getOpp(this.outside)).css(this.pointer.margin),this.positionAdjusted=!1,this.flipped=!1);var d=t.top>p.top-(o.adjustDistance.top||0),c=t.right<p.left+s.x+(o.adjustDistance.right||0),u=t.bottom<p.top+s.y+(o.adjustDistance.bottom||0),g=t.left>p.left-(o.adjustDistance.left||0),m=g?"left":c?"right":null,f=d?"top":u?"bottom":null;if(m||f){if(("Modal"==this.type||"Confirm"==this.type)&&"number"==b.type(this.options.position.x)&&"number"==b.type(this.options.position.y)){var x=0,y=0;return this.options.holdPosition&&(g?x=t.left-(p.left-(o.adjustDistance.left||0)):c&&(x=t.right-(p.left+s.x+(o.adjustDistance.right||0))),d?y=t.top-(p.top-(o.adjustDistance.top||0)):u&&(y=t.bottom-(p.top+s.y+(o.adjustDistance.bottom||0))),this.options.position.x=Math.max(t.top,this.options.position.x+x),this.options.position.y=Math.max(t.left,this.options.position.y+y),l("x"),l("y"),this.wrapper.css(p)),this._fireEvent("onPosition"),this}!0!==o.adjustPosition&&"flip"!==o.adjustPosition||(j=function(t){this.wrapper.css(this._getTL(t),p[this._getTL(t)]+(s[this._getXY(t)]+o.offset[this._getXY(t)]*("top"==t||"left"==t?-2:2)+e[this._getXY(t)])*("top"==t||"left"==t?1:-1)),this.pointer&&this.wrapper.removeClass("jBox-pointerPosition-"+this.pointer.position).addClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).css("padding",0).css("padding-"+t,this.pointer.dimensions[this._getXY(t)]),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+t),this.positionAdjusted=!0,this.flipped=!0}.bind(this),r.x&&j(this.options.position.x),r.y&&j(this.options.position.y));var j="x"==this._getXY(this.outside)?f:m;this.pointer&&"target"==o.pointTo&&"flip"!=o.adjustPosition&&this._getXY(j)==this._getOpp(this._getXY(this.outside))&&(f="center"==this.pointer.align?s[this._getXY(j)]/2-this.pointer.dimensions[this._getOpp(this.pointer.xy)]/2-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))*(j!=this._getTL(j)?-1:1):j==this.pointer.alignAttribute?parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute)):s[this._getXY(j)]-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))-this.pointer.dimensions[this._getXY(j)],m=j==this._getTL(j)?t[this._getTL(j)]-p[this._getTL(j)]+o.adjustDistance[j]:-1*(t[this._getOpp(this._getTL(j))]-p[this._getTL(j)]-o.adjustDistance[j]-s[this._getXY(j)]),j==this._getOpp(this._getTL(j))&&p[this._getTL(j)]-m<t[this._getTL(j)]+o.adjustDistance[this._getTL(j)]&&(m-=t[this._getTL(j)]+o.adjustDistance[this._getTL(j)]-(p[this._getTL(j)]-m)),(m=Math.min(m,f))<=f&&0<m&&(this.pointer.element.css("margin-"+this.pointer.alignAttribute,parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))-m*(j!=this.pointer.alignAttribute?-1:1)),this.wrapper.css(this._getTL(j),p[this._getTL(j)]+m*(j!=this._getTL(j)?-1:1)),this.positionAdjusted=!0))}}return this._fireEvent("onPosition"),this},(h.prototype.unscroll=function(t){if(this.set=function(t,i){window.unscrollStore||(window.unscrollStore={}),window.unscrollStore[t]=i},this.get=function(t){return window.unscrollStore?window.unscrollStore[t]:null},this.getScrollbarWidth=function(){if(this.get("scrollbarWidth"))return this.get("scrollbarWidth")+"px";var t=document.createElement("div");t.style.width="100px",t.style.height="100px",t.style.overflow="scroll",t.style.position="absolute",t.style.top="-10000",document.body.appendChild(t);var i=t.offsetWidth-t.clientWidth;return document.body.removeChild(t),this.set("scrollbarWidth",i),i+"px"},this.getElementsToAdjust=function(o){(o="string"==typeof(o=o||[])?[[o,"padding-right"]]:o).forEach(function(t,i){"string"==typeof t&&(o[i]=[t,"padding-right"])});for(var t=!1,i=0;i<o.length;i++)-1!==o[i][0].indexOf("body")&&(t=!0);return!1===t&&o.push(["body","padding-right"]),o},this.pageHasScrollbar=function(){return this.getScrollbarWidth()&&document.body.offsetHeight>window.innerHeight},this.pageHasScrollbar()){t=this.getElementsToAdjust(t);for(var i=0;i<t.length;i++)for(var o=document.querySelectorAll(t[i][0]),s=0;s<o.length;s++){if(o[s].getAttribute("data-unscroll"))return;var e=t[i][1],n=window.getComputedStyle(o[s]).getPropertyValue(e);o[s].setAttribute("data-unscroll",e),n=n||"0px";var a="padding-right"==e||"right"==e?"+":"-";o[s].style[e]="calc("+n+" "+a+" "+this.getScrollbarWidth()+")"}}var h,r;document.getElementById("unscroll-class-name")||(h=document.head||document.getElementsByTagName("head")[0],(r=document.createElement("style")).type="text/css",r.setAttribute("id","unscroll-class-name"),r.appendChild(document.createTextNode(".unscrollable { overflow: hidden !important; }")),h.appendChild(r)),document.body.classList.add("unscrollable")}).reset=function(){for(var t=document.querySelectorAll("[data-unscroll]"),i=0;i<t.length;i++){var o=t[i].getAttribute("data-unscroll");t[i].style[o]=null,t[i].removeAttribute("data-unscroll")}document.body.classList.remove("unscrollable")},h.prototype.open=function(t){if(t=t||{},this.isDestroyed)return this;if(this.wrapper||this._create(),this._styles||(this._styles=b("<style/>").append(this._animationCSS).appendTo(b("head"))),this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;this.options.closeOnEsc&&b(document).on("keyup.jBox-"+this.id,function(t){27==t.keyCode&&this.close({ignoreDelay:!0})}.bind(this)),!0!==this.options.closeOnClick&&"body"!==this.options.closeOnClick||(b("body").on("click.jBox-"+this.id+" tap.jBox-"+this.id,function(t){this.blockBodyClick||"body"==this.options.closeOnClick&&(t.target==this.wrapper[0]||this.wrapper.has(t.target).length)||this.close({ignoreDelay:!0})}.bind(this)),this.isTouchDevice&&b("body > *").on("click.jBox-"+this.id+" tap.jBox-"+this.id,function(){return!0}));var i=function(){!0===this.adjustZIndexOnOpen&&(h.zIndexMax=Math.max(parseInt(this.wrapper.css("zIndex"),10),this.options.zIndex,h.zIndexMax||0,h.zIndexMaxDragover||0)+2,this.wrapper.css("zIndex",h.zIndexMax),this.options.zIndex=h.zIndexMax),this.source&&this.options.getTitle&&this.source.attr(this.options.getTitle)&&this.setTitle(this.source.attr(this.options.getTitle),!0),this.source&&this.options.getContent&&(this.source.data("jBox-getContent")?this.setContent(this.source.data("jBox-getContent"),!0):this.source.attr(this.options.getContent)?this.setContent(this.source.attr(this.options.getContent),!0):"html"==this.options.getContent&&this.setContent(this.source.html(),!0)),this._fireEvent("onOpen"),(this.options.ajax&&(this.options.ajax.url||this.source&&this.source.attr(this.options.ajax.getURL))&&(!this.ajaxLoaded||this.options.ajax.reload)||t.ajax&&(t.ajax.url||t.ajax.data))&&("strict"==this.options.ajax.reload||!this.source||!this.source.data("jBox-ajax-data")||t.ajax&&(t.ajax.url||t.ajax.data)?this.ajax(t.ajax||null,!0):this.setContent(this.source.data("jBox-ajax-data"))),this.positionedOnOpen&&!this.options.repositionOnOpen||!this.position(t)||(this.positionedOnOpen=!0),this.isClosing&&this._abortAnimation(),this.isOpen||(this.isOpen=!0,this.options.autoClose&&(this.options.delayClose=this.options.autoClose)&&this.close(),this._attachEvents(),this.options.blockScroll&&(this.options.blockScrollAdjust?h.blockScrollScopes?h.blockScrollScopes++:(h.blockScrollScopes=1,this.unscroll(Array.isArray(this.options.blockScrollAdjust)||"string"==typeof this.options.blockScrollAdjust?this.options.blockScrollAdjust:null)):b("body").addClass("jBox-blockScroll-"+this.id)),this.options.overlay&&(this._showOverlay(),this.position()),this.options.animation&&!this.isClosing&&this._animate("open"),this.options.audio&&this.options.audio.open&&this.audio(this.options.audio.open,this.options.volume.open),this.options.fade?this.wrapper.stop().animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.isOpening=!0,this.wrapper.css({display:"block"})}.bind(this),always:function(){this.isOpening=!1,setTimeout(function(){this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1)}.bind(this),10)}.bind(this)}):(this.wrapper.css({display:"block",opacity:1}),this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1)))}.bind(this);return!this.options.delayOpen||this.isOpen||this.isClosing||t.ignoreDelay?i():this.timer=setTimeout(i,this.options.delayOpen),this},h.prototype.close=function(t){if(t=t||{},b("body").off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.isTouchDevice&&b("body > *").off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.isDestroyed||this.isClosing)return this;if(this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;var i,o,s,e=function(){var t;this._fireEvent("onClose"),this.options.cancelAjaxOnClose&&this.cancelAjax(),this.isOpen&&(this.isOpen=!1,this._detachEvents(),this.options.blockScroll&&(this.options.blockScrollAdjust?(h.blockScrollScopes=h.blockScrollScopes?--h.blockScrollScopes:0)||this.unscroll.reset():b("body").removeClass("jBox-blockScroll-"+this.id)),this.options.overlay&&this._hideOverlay(),this.options.animation&&!this.isOpening&&this._animate("close"),this.options.audio&&this.options.audio.close&&this.audio(this.options.audio.close,this.options.volume.close),(t=this.isTouchDevice&&"mouse"==this.options.target?0:this.options.fade)?this.wrapper.stop().animate({opacity:0},{queue:!1,duration:t,start:function(){this.isClosing=!0}.bind(this),complete:function(){this.wrapper.css({display:"none"}),this._fireEvent("onCloseComplete")}.bind(this),always:function(){this.isClosing=!1}.bind(this)}):(this.wrapper.css({display:"none",opacity:0}),this._fireEvent("onCloseComplete")))}.bind(this);return t.ignoreDelay||this.isTouchDevice&&"mouse"==this.options.target?e():(this.options.delayOnHover||this.options.showCountdown)&&10<this.options.delayClose?(o=(i=this).options.delayClose,s=Date.now(),this.options.showCountdown&&!this.inner&&(t=b('<div class="jBox-countdown" />'),this.inner=b('<div class="jBox-countdown-inner" />'),t.prepend(this.inner),b("#"+this.id).append(t)),this.countdown=function(){var t=Date.now();i.isHovered||(o-=t-s),s=t,0<o?(i.options.showCountdown&&i.inner.css("width",100*o/i.options.delayClose+"%"),window.requestAnimationFrame(i.countdown)):e()},window.requestAnimationFrame(this.countdown)):this.timer=setTimeout(e,Math.max(this.options.delayClose,10)),this},h.prototype.toggle=function(t){return this[this.isOpen?"close":"open"](t),this},h.prototype.disable=function(){return this.isDisabled=!0,this},h.prototype.enable=function(){return this.isDisabled=!1,this},h.prototype.hide=function(){return this.disable(),this.wrapper&&(this.cacheWrapperDisplay=this.wrapper.css("display"),this.wrapper.css({display:"none"})),this.overlay&&(this.cacheOverlayDisplay=this.overlay.css("display"),this.overlay.css({display:"none"})),this},h.prototype.show=function(){return this.enable(),this.wrapper&&this.cacheWrapperDisplay&&(this.wrapper.css({display:this.cacheWrapperDisplay}),this.cacheWrapperDisplay=null),this.overlay&&this.cacheOverlayDisplay&&(this.overlay.css({display:this.cacheOverlayDisplay}),this.cacheOverlayDisplay=null),this},h.prototype.ajax=function(o,i){o=o||{},b.each([["getData","data"],["getURL","url"]],function(t,i){this.options.ajax[i[0]]&&!o[i[1]]&&this.source&&null!=this.source.attr(this.options.ajax[i[0]])&&(o[i[1]]=this.source.attr(this.options.ajax[i[0]])||"")}.bind(this));var t=b.extend(!0,{},this.options.ajax);this.cancelAjax();var s=o.beforeSend||t.beforeSend||function(){},e=o.complete||t.complete||function(){},n=o.success||t.success||function(){},a=o.error||t.error||function(){},h=b.extend(!0,t,o);return h.beforeSend=function(t){h.loadingClass&&this.wrapper.addClass(!0===h.loadingClass?"jBox-loading":h.loadingClass),h.spinner&&(this.spinnerDelay=setTimeout(function(){this.wrapper.addClass("jBox-loading-spinner"),h.spinnerReposition&&(i?this.positionOnFadeComplete=!0:this.position()),this.spinner=b(!0!==h.spinner?h.spinner:'<div class="jBox-spinner"></div>').appendTo(this.container),this.titleContainer&&"absolute"==this.spinner.css("position")&&this.spinner.css({transform:"translateY("+.5*this.titleContainer.outerHeight()+"px)"})}.bind(this),""!=this.content.html()&&h.spinnerDelay||0)),s.bind(this)(t)}.bind(this),h.complete=function(t){this.spinnerDelay&&clearTimeout(this.spinnerDelay),this.wrapper.removeClass("jBox-loading jBox-loading-spinner jBox-loading-spinner-delay"),this.spinner&&this.spinner.length&&this.spinner.remove()&&h.spinnerReposition&&(i?this.positionOnFadeComplete=!0:this.position()),this.ajaxLoaded=!0,e.bind(this)(t)}.bind(this),h.success=function(t){h.setContent&&this.setContent(t,!0)&&(i?this.positionOnFadeComplete=!0:this.position()),h.setContent&&this.source&&this.source.data("jBox-ajax-data",t),n.bind(this)(t)}.bind(this),h.error=function(t){a.bind(this)(t)}.bind(this),this.ajaxRequest=b.ajax(h),this},h.prototype.cancelAjax=function(){this.ajaxRequest&&(this.ajaxRequest.abort(),this.ajaxLoaded=!1)},h.prototype.audio=function(t,i){if(!t)return this;var o;(h._audio=!h._audio?{}:h._audio)[t]||(o=b("<audio/>"),b("<source/>",{src:t+".mp3"}).appendTo(o),b("<source/>",{src:t+".ogg"}).appendTo(o),h._audio[t]=o[0]),h._audio[t].volume=Math.min((null!=i?i:100)/100,1);try{h._audio[t].pause(),h._audio[t].currentTime=0}catch(t){}return h._audio[t].play(),this},h._animationSpeeds={tada:1e3,tadaSmall:1e3,flash:500,shake:400,pulseUp:250,pulseDown:250,popIn:250,popOut:250,fadeIn:200,fadeOut:200,slideUp:400,slideRight:400,slideLeft:400,slideDown:400},h.prototype.animate=function(t,i){i=i||{},this.animationTimeout||(this.animationTimeout={}),i.element||(i.element=this.wrapper),i.element.data("jBox-animating-id")||i.element.data("jBox-animating-id",h._getUniqueElementID()),i.element.data("jBox-animating")&&(i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),this.animationTimeout[i.element.data("jBox-animating-id")]&&clearTimeout(this.animationTimeout[i.element.data("jBox-animating-id")])),i.element.addClass("jBox-animated-"+t).data("jBox-animating","jBox-animated-"+t),this.animationTimeout[i.element.data("jBox-animating-id")]=setTimeout(function(){i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),i.complete&&i.complete()},h._animationSpeeds[t])},h.prototype.swipeDetector=function(i,o){var s=0,e=0,n=0,a=0,h=0,t={swipeThreshold:70,useOnlyTouch:!1};function r(t){o.useOnlyTouch&&!t.originalEvent.touches||(t.originalEvent.touches&&(t=t.originalEvent.touches[0]),0===s&&(s=1,e=t.clientX,n=t.clientY))}function p(t){2===s&&(s=0,Math.abs(a)>Math.abs(h)&&Math.abs(a)>o.swipeThreshold?a<0?i.trigger(b.Event("swipeLeft.sd")):i.trigger(b.Event("swipeRight.sd")):Math.abs(h)>o.swipeThreshold&&(h<0?i.trigger(b.Event("swipeUp.sd")):i.trigger(b.Event("swipeDown.sd"))))}function l(t){var i;1===s&&(i=(t=t.originalEvent.touches?t.originalEvent.touches[0]:t).clientX-e,t=t.clientY-n,(Math.abs(i)>o.swipeThreshold||Math.abs(t)>o.swipeThreshold)&&(s=2,a=i,h=t))}return o=b.extend(t,o),i.on("mousedown touchstart",r),b("html").on("mouseup touchend",p),b("html").on("mousemove touchmove",l),i},h.prototype.destroy=function(){return this.detach(),this.isOpen&&this.close({ignoreDelay:!0}),this.wrapper&&this.wrapper.remove(),this.overlay&&this.overlay.remove(),this._styles&&this._styles.remove(),this.isDestroyed=!0,this},h._getUniqueID=(t=1,function(){return t++}),h._getUniqueElementID=(i=1,function(){return i++}),h._pluginOptions={},h.plugin=function(t,i){h._pluginOptions[t]=i},b.fn.jBox=function(t,i){return i=i||{},new h(t=t||{},b.extend(i,{attach:this}))},h}function jBoxConfirmWrapper(jBox,jQuery){new jBox.plugin("Confirm",{confirmButton:"Submit",cancelButton:"Cancel",confirm:null,cancel:null,closeOnConfirm:!0,target:window,fixed:!0,attach:"[data-confirm]",getContent:"data-confirm",content:"Do you really want to do this?",minWidth:360,maxWidth:500,blockScroll:!0,closeOnEsc:!0,closeOnClick:!1,closeButton:!1,overlay:!0,animation:"zoomIn",preventDefault:!0,_onAttach:function(t){var i;this.options.confirm||(i=t.attr("onclick")?t.attr("onclick"):t.attr("href")?t.attr("target")?'window.open("'+t.attr("href")+'", "'+t.attr("target")+'");':'window.location.href = "'+t.attr("href")+'";':"",t.prop("onclick",null).data("jBox-Confirm-submit",i))},_onCreated:function(){this.wrapper.addClass("jBox-Modal"),this.footer=jQuery('<div class="jBox-Confirm-footer"/>'),jQuery('<div class="jBox-Confirm-button jBox-Confirm-button-cancel"/>').html(this.options.cancelButton).on("click tap",function(){this.options.cancel&&this.options.cancel(this.source),this.close()}.bind(this)).appendTo(this.footer),this.submitButton=jQuery('<div class="jBox-Confirm-button jBox-Confirm-button-submit"/>').html(this.options.confirmButton).appendTo(this.footer),this.footer.appendTo(this.container)},_onOpen:function(){this.submitButton.off("click.jBox-Confirm"+this.id+" tap.jBox-Confirm"+this.id).on("click.jBox-Confirm"+this.id+" tap.jBox-Confirm"+this.id,function(){this.options.confirm?this.options.confirm(this.source):eval(this.source.data("jBox-Confirm-submit")),this.options.closeOnConfirm&&this.close()}.bind(this))}})}function jBoxImageWrapper(t,a){new t.plugin("Image",{src:"href",gallery:"data-jbox-image",imageLabel:"title",imageFade:360,imageSize:"contain",imageCounter:!1,imageCounterSeparator:"/",downloadButton:!1,downloadButtonText:null,downloadButtonUrl:null,mobileImageAttr:null,mobileImageBreakpoint:null,preloadFirstImage:!1,target:window,attach:"[data-jbox-image]",fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"button",closeButton:!0,overlay:!0,animation:"zoomIn",preventDefault:!0,width:"100%",height:"100%",adjustDistance:{top:40,right:0,bottom:40,left:0},_onInit:function(){this.images=this.currentImage={},this.imageZIndex=1,this.initImage=function(t){var i,o;(t=a(t)).data("jBox-image-gallery")||(i=t.attr(this.options.src),this.options.mobileImageAttr&&this.options.mobileImageBreakpoint&&t.attr(this.options.mobileImageAttr)&&a(window).width()<=this.options.mobileImageBreakpoint&&(i=t.attr(this.options.mobileImageAttr)),o=t.attr(this.options.gallery)||"default",this.images[o]||(this.images[o]=[]),this.images[o].push({src:i,label:t.attr(this.options.imageLabel)||"",downloadUrl:this.options.downloadButtonUrl&&t.attr(this.options.downloadButtonUrl)?t.attr(this.options.downloadButtonUrl):null}),"title"==this.options.imageLabel&&t.removeAttr("title"),t.data("jBox-image-gallery",o),t.data("jBox-image-id",this.images[o].length-1))}.bind(this),this.attachedElements&&this.attachedElements.length&&a.each(this.attachedElements,function(t,i){this.initImage(i)}.bind(this));var n=function(t,i,o,s){if(!a("#jBox-image-"+t+"-"+i).length){var e=a("<div/>",{id:"jBox-image-"+t+"-"+i,class:"jBox-image-container"+(o?" jBox-image-"+t+"-current":"")}).css({backgroundSize:this.options.imageSize,opacity:s?1:0,zIndex:o?this.imageZIndex++:0}).appendTo(this.content);return this.swipeDetector(e).on("swipeLeft.sd swipeRight.sd",function(t){"swipeLeft"===t.type?this.showImage("next"):"swipeRight"===t.type&&this.showImage("prev")}.bind(this)),a("<div/>",{id:"jBox-image-label-"+t+"-"+i,class:"jBox-image-label"+(o?" active":"")}).html(this.images[t][i].label).on("click tap",function(){a(this).toggleClass("expanded")}).appendTo(this.imageLabelContainer),o&&e.animate({opacity:1},s?0:this.options.imageFade),e}}.bind(this);this.downloadImage=function(t){var i=document.createElement("a");i.href=t,i.setAttribute("download",t.substring(t.lastIndexOf("/")+1)),document.body.appendChild(i),i.click()};var e=function(i,o,t,s){var e=n(i,o,t,s);e.addClass("jBox-image-loading"),a('<img src="'+this.images[i][o].src+'" />').each(function(){var t=new Image;t.onload=function(){e.removeClass("jBox-image-loading"),e.css({backgroundImage:'url("'+this.images[i][o].src+'")'})}.bind(this),t.onerror=function(){e.removeClass("jBox-image-loading"),e.addClass("jBox-image-not-found")}.bind(this),t.src=this.images[i][o].src}.bind(this))}.bind(this);this.showImage=function(t){var i,o,s;if("open"!=t)i=this.currentImage.gallery,s=(s=this.currentImage.id+(+("prev"==t)?-1:1))>this.images[i].length-1?0:s<0?this.images[i].length-1:s;else{if(this.source)i=this.source.data("jBox-image-gallery"),s=this.source.data("jBox-image-id");else{if(!this.attachedElements||!this.attachedElements.length)return;i=a(this.attachedElements[0]).data("jBox-image-gallery"),s=a(this.attachedElements[0]).data("jBox-image-id")}this.images&&this.images[i]&&a(".jBox-image-pointer-prev, .jBox-image-pointer-next").css({display:1<this.images[i].length?"block":"none"})}a(".jBox-image-"+i+"-current").length&&a(".jBox-image-"+i+"-current").removeClass("jBox-image-"+i+"-current").animate({opacity:0},"open"==t?0:this.options.imageFade),this.currentImage={gallery:i,id:s},a("#jBox-image-"+i+"-"+s).length?a("#jBox-image-"+i+"-"+s).addClass("jBox-image-"+i+"-current").css({zIndex:this.imageZIndex++,opacity:0}).animate({opacity:1},"open"==t?0:this.options.imageFade):e(i,s,!0,"open"===t),o=i,t=s,a(".jBox-image-label.active").removeClass("active expanded"),a("#jBox-image-label-"+o+"-"+t).addClass("active"),this.imageCounter&&(this.images[i]&&1<this.images[i].length?(this.wrapper.addClass("jBox-image-has-counter"),this.imageCounter.find(".jBox-image-counter-all").html(this.images[i].length),this.imageCounter.find(".jBox-image-counter-current").html(s+1)):this.wrapper.removeClass("jBox-image-has-counter")),this.images[i]&&this.images[i].length-1&&(s=(s=s+1)>this.images[i].length-1?0:s<0?this.images[i].length-1:s,a("#jBox-image-"+i+"-"+s).length||e(i,s,!1,!1))},this.options.preloadFirstImage&&a(window).on("load",function(){this.showImage("open")}.bind(this))},_onAttach:function(t){this.initImage&&this.initImage(t)},_onCreated:function(){this.imageLabelWrapper=a('<div class="jBox-image-label-wrapper"/>').appendTo(this.wrapper),this.imagePrevButton=a('<div class="jBox-image-pointer-prev"/>').on("click tap",function(){this.showImage("prev")}.bind(this)),this.imageNextButton=a('<div class="jBox-image-pointer-next"/>').on("click tap",function(){this.showImage("next")}.bind(this)),this.imageLabelContainer=a('<div class="jBox-image-label-container"/>'),this.imageLabelWrapper.append(this.imagePrevButton).append(this.imageLabelContainer).append(this.imageNextButton),this.options.downloadButton&&(this.downloadButton=a("<div/>",{class:"jBox-image-download-button-wrapper"}).appendTo(this.wrapper).append(this.options.downloadButtonText?a("<div/>",{class:"jBox-image-download-button-text"}).html(this.options.downloadButtonText):null).append(a("<div/>",{class:"jBox-image-download-button-icon"})).on("click tap",function(){var t;t=this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl||this.wrapper.find(".jBox-image-"+this.currentImage.gallery+"-current")[0].style.backgroundImage.slice(4,-1).replace(/["']/g,""),this.downloadImage(t)}.bind(this))),this.options.imageCounter&&(this.imageCounter=a("<div/>",{class:"jBox-image-counter-container"}).insertAfter(this.imageLabelContainer),this.imageCounter.append(a("<span/>",{class:"jBox-image-counter-current"})).append(a("<span/>").html(this.options.imageCounterSeparator)).append(a("<span/>",{class:"jBox-image-counter-all"})))},_onOpen:function(){a(document).on("keyup.jBox-Image-"+this.id,function(t){37==t.keyCode&&this.showImage("prev"),39==t.keyCode&&this.showImage("next")}.bind(this)),this.showImage("open")},_onClose:function(){a(document).off("keyup.jBox-Image-"+this.id)},_onCloseComplete:function(){this.wrapper.find(".jBox-image-container").css("opacity",0)}})}function jBoxNoticeWrapper(t,a){new t.plugin("Notice",{color:null,stack:!0,stackSpacing:10,autoClose:6e3,attributes:{x:"right",y:"top"},position:{x:15,y:15},responsivePositions:{500:{x:5,y:5},768:{x:10,y:10}},target:window,fixed:!0,animation:"zoomIn",closeOnClick:"box",zIndex:12e3,_onInit:function(){this.defaultNoticePosition=a.extend({},this.options.position),this._adjustNoticePositon=function(){var t=a(window),o=t.width();t.height();this.options.position=a.extend({},this.defaultNoticePosition),a.each(this.options.responsivePositions,function(t,i){if(o<=t)return this.options.position=i,!1}.bind(this)),this.options.adjustDistance={top:this.options.position.y,right:this.options.position.x,bottom:this.options.position.y,left:this.options.position.x}},this.options.content instanceof a&&(this.options.content=this.options.content.clone().attr("id","")),a(window).on("resize.responsivejBoxNotice-"+this.id,function(t){this.isOpen&&this._adjustNoticePositon()}.bind(this)),this.open()},_onCreated:function(){this.wrapper.addClass("jBox-Notice-color jBox-Notice-"+(this.options.color||"gray")),this.wrapper.data("jBox-Notice-position",this.options.attributes.x+"-"+this.options.attributes.y)},_onOpen:function(){this.options.stack||(this._adjustNoticePositon(),a.each(a(".jBox-Notice"),function(t,i){(i=a(i)).attr("id")!=this.id&&i.data("jBox-Notice-position")==this.options.attributes.x+"-"+this.options.attributes.y&&(this.options.stack||i.data("jBox").close({ignoreDelay:!0}))}.bind(this)))},_onPosition:function(){var t,s={};for(t in a.each(a(".jBox-Notice"),function(t,i){var o=(i=a(i)).data("jBox-Notice-position");s[o]||(s[o]=[]),s[o].push(i)}),s){var i=t.split("-")[1];s[t].reverse();var o,e=0;for(o in s[t]){var n=a(s[t][o]);n.css("margin-"+i,e),e+=n.outerHeight()+this.options.stackSpacing}}},_onCloseComplete:function(){this.destroy(),this.options._onPosition.bind(this).call()}})}!function(i,o){"function"==typeof define&&define.amd?define(["jquery"],function(t){return i.jBox=o(t)}):"object"==typeof module&&module.exports?module.exports=i.jBox=o(require("jquery")):i.jBox=o(i.jQuery)}(this,function(t){var i=jBoxWrapper(t);try{void 0!==jBoxConfirmWrapper&&jBoxConfirmWrapper&&jBoxConfirmWrapper(i,t)}catch(t){console.error(t)}try{void 0!==jBoxImageWrapper&&jBoxImageWrapper&&jBoxImageWrapper(i,t)}catch(t){console.error(t)}try{void 0!==jBoxNoticeWrapper&&jBoxNoticeWrapper&&jBoxNoticeWrapper(i,t)}catch(t){console.error(t)}return i});
|
|
},{"jquery":58}],58:[function(require,module,exports){
|
|
/*!
|
|
* jQuery JavaScript Library v3.6.0
|
|
* https://jquery.com/
|
|
*
|
|
* Includes Sizzle.js
|
|
* https://sizzlejs.com/
|
|
*
|
|
* Copyright OpenJS Foundation and other contributors
|
|
* Released under the MIT license
|
|
* https://jquery.org/license
|
|
*
|
|
* Date: 2021-03-02T17:08Z
|
|
*/
|
|
( function( global, factory ) {
|
|
|
|
"use strict";
|
|
|
|
if ( typeof module === "object" && typeof module.exports === "object" ) {
|
|
|
|
// For CommonJS and CommonJS-like environments where a proper `window`
|
|
// is present, execute the factory and get jQuery.
|
|
// For environments that do not have a `window` with a `document`
|
|
// (such as Node.js), expose a factory as module.exports.
|
|
// This accentuates the need for the creation of a real `window`.
|
|
// e.g. var jQuery = require("jquery")(window);
|
|
// See ticket #14549 for more info.
|
|
module.exports = global.document ?
|
|
factory( global, true ) :
|
|
function( w ) {
|
|
if ( !w.document ) {
|
|
throw new Error( "jQuery requires a window with a document" );
|
|
}
|
|
return factory( w );
|
|
};
|
|
} else {
|
|
factory( global );
|
|
}
|
|
|
|
// Pass this if window is not defined yet
|
|
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
|
|
|
|
// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
|
|
// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
|
|
// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
|
|
// enough that all such attempts are guarded in a try block.
|
|
"use strict";
|
|
|
|
var arr = [];
|
|
|
|
var getProto = Object.getPrototypeOf;
|
|
|
|
var slice = arr.slice;
|
|
|
|
var flat = arr.flat ? function( array ) {
|
|
return arr.flat.call( array );
|
|
} : function( array ) {
|
|
return arr.concat.apply( [], array );
|
|
};
|
|
|
|
|
|
var push = arr.push;
|
|
|
|
var indexOf = arr.indexOf;
|
|
|
|
var class2type = {};
|
|
|
|
var toString = class2type.toString;
|
|
|
|
var hasOwn = class2type.hasOwnProperty;
|
|
|
|
var fnToString = hasOwn.toString;
|
|
|
|
var ObjectFunctionString = fnToString.call( Object );
|
|
|
|
var support = {};
|
|
|
|
var isFunction = function isFunction( obj ) {
|
|
|
|
// Support: Chrome <=57, Firefox <=52
|
|
// In some browsers, typeof returns "function" for HTML <object> elements
|
|
// (i.e., `typeof document.createElement( "object" ) === "function"`).
|
|
// We don't want to classify *any* DOM node as a function.
|
|
// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
|
|
// Plus for old WebKit, typeof returns "function" for HTML collections
|
|
// (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
|
|
return typeof obj === "function" && typeof obj.nodeType !== "number" &&
|
|
typeof obj.item !== "function";
|
|
};
|
|
|
|
|
|
var isWindow = function isWindow( obj ) {
|
|
return obj != null && obj === obj.window;
|
|
};
|
|
|
|
|
|
var document = window.document;
|
|
|
|
|
|
|
|
var preservedScriptAttributes = {
|
|
type: true,
|
|
src: true,
|
|
nonce: true,
|
|
noModule: true
|
|
};
|
|
|
|
function DOMEval( code, node, doc ) {
|
|
doc = doc || document;
|
|
|
|
var i, val,
|
|
script = doc.createElement( "script" );
|
|
|
|
script.text = code;
|
|
if ( node ) {
|
|
for ( i in preservedScriptAttributes ) {
|
|
|
|
// Support: Firefox 64+, Edge 18+
|
|
// Some browsers don't support the "nonce" property on scripts.
|
|
// On the other hand, just using `getAttribute` is not enough as
|
|
// the `nonce` attribute is reset to an empty string whenever it
|
|
// becomes browsing-context connected.
|
|
// See https://github.com/whatwg/html/issues/2369
|
|
// See https://html.spec.whatwg.org/#nonce-attributes
|
|
// The `node.getAttribute` check was added for the sake of
|
|
// `jQuery.globalEval` so that it can fake a nonce-containing node
|
|
// via an object.
|
|
val = node[ i ] || node.getAttribute && node.getAttribute( i );
|
|
if ( val ) {
|
|
script.setAttribute( i, val );
|
|
}
|
|
}
|
|
}
|
|
doc.head.appendChild( script ).parentNode.removeChild( script );
|
|
}
|
|
|
|
|
|
function toType( obj ) {
|
|
if ( obj == null ) {
|
|
return obj + "";
|
|
}
|
|
|
|
// Support: Android <=2.3 only (functionish RegExp)
|
|
return typeof obj === "object" || typeof obj === "function" ?
|
|
class2type[ toString.call( obj ) ] || "object" :
|
|
typeof obj;
|
|
}
|
|
/* global Symbol */
|
|
// Defining this global in .eslintrc.json would create a danger of using the global
|
|
// unguarded in another place, it seems safer to define global only for this module
|
|
|
|
|
|
|
|
var
|
|
version = "3.6.0",
|
|
|
|
// Define a local copy of jQuery
|
|
jQuery = function( selector, context ) {
|
|
|
|
// The jQuery object is actually just the init constructor 'enhanced'
|
|
// Need init if jQuery is called (just allow error to be thrown if not included)
|
|
return new jQuery.fn.init( selector, context );
|
|
};
|
|
|
|
jQuery.fn = jQuery.prototype = {
|
|
|
|
// The current version of jQuery being used
|
|
jquery: version,
|
|
|
|
constructor: jQuery,
|
|
|
|
// The default length of a jQuery object is 0
|
|
length: 0,
|
|
|
|
toArray: function() {
|
|
return slice.call( this );
|
|
},
|
|
|
|
// Get the Nth element in the matched element set OR
|
|
// Get the whole matched element set as a clean array
|
|
get: function( num ) {
|
|
|
|
// Return all the elements in a clean array
|
|
if ( num == null ) {
|
|
return slice.call( this );
|
|
}
|
|
|
|
// Return just the one element from the set
|
|
return num < 0 ? this[ num + this.length ] : this[ num ];
|
|
},
|
|
|
|
// Take an array of elements and push it onto the stack
|
|
// (returning the new matched element set)
|
|
pushStack: function( elems ) {
|
|
|
|
// Build a new jQuery matched element set
|
|
var ret = jQuery.merge( this.constructor(), elems );
|
|
|
|
// Add the old object onto the stack (as a reference)
|
|
ret.prevObject = this;
|
|
|
|
// Return the newly-formed element set
|
|
return ret;
|
|
},
|
|
|
|
// Execute a callback for every element in the matched set.
|
|
each: function( callback ) {
|
|
return jQuery.each( this, callback );
|
|
},
|
|
|
|
map: function( callback ) {
|
|
return this.pushStack( jQuery.map( this, function( elem, i ) {
|
|
return callback.call( elem, i, elem );
|
|
} ) );
|
|
},
|
|
|
|
slice: function() {
|
|
return this.pushStack( slice.apply( this, arguments ) );
|
|
},
|
|
|
|
first: function() {
|
|
return this.eq( 0 );
|
|
},
|
|
|
|
last: function() {
|
|
return this.eq( -1 );
|
|
},
|
|
|
|
even: function() {
|
|
return this.pushStack( jQuery.grep( this, function( _elem, i ) {
|
|
return ( i + 1 ) % 2;
|
|
} ) );
|
|
},
|
|
|
|
odd: function() {
|
|
return this.pushStack( jQuery.grep( this, function( _elem, i ) {
|
|
return i % 2;
|
|
} ) );
|
|
},
|
|
|
|
eq: function( i ) {
|
|
var len = this.length,
|
|
j = +i + ( i < 0 ? len : 0 );
|
|
return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
|
|
},
|
|
|
|
end: function() {
|
|
return this.prevObject || this.constructor();
|
|
},
|
|
|
|
// For internal use only.
|
|
// Behaves like an Array's method, not like a jQuery method.
|
|
push: push,
|
|
sort: arr.sort,
|
|
splice: arr.splice
|
|
};
|
|
|
|
jQuery.extend = jQuery.fn.extend = function() {
|
|
var options, name, src, copy, copyIsArray, clone,
|
|
target = arguments[ 0 ] || {},
|
|
i = 1,
|
|
length = arguments.length,
|
|
deep = false;
|
|
|
|
// Handle a deep copy situation
|
|
if ( typeof target === "boolean" ) {
|
|
deep = target;
|
|
|
|
// Skip the boolean and the target
|
|
target = arguments[ i ] || {};
|
|
i++;
|
|
}
|
|
|
|
// Handle case when target is a string or something (possible in deep copy)
|
|
if ( typeof target !== "object" && !isFunction( target ) ) {
|
|
target = {};
|
|
}
|
|
|
|
// Extend jQuery itself if only one argument is passed
|
|
if ( i === length ) {
|
|
target = this;
|
|
i--;
|
|
}
|
|
|
|
for ( ; i < length; i++ ) {
|
|
|
|
// Only deal with non-null/undefined values
|
|
if ( ( options = arguments[ i ] ) != null ) {
|
|
|
|
// Extend the base object
|
|
for ( name in options ) {
|
|
copy = options[ name ];
|
|
|
|
// Prevent Object.prototype pollution
|
|
// Prevent never-ending loop
|
|
if ( name === "__proto__" || target === copy ) {
|
|
continue;
|
|
}
|
|
|
|
// Recurse if we're merging plain objects or arrays
|
|
if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
|
|
( copyIsArray = Array.isArray( copy ) ) ) ) {
|
|
src = target[ name ];
|
|
|
|
// Ensure proper type for the source value
|
|
if ( copyIsArray && !Array.isArray( src ) ) {
|
|
clone = [];
|
|
} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
|
|
clone = {};
|
|
} else {
|
|
clone = src;
|
|
}
|
|
copyIsArray = false;
|
|
|
|
// Never move original objects, clone them
|
|
target[ name ] = jQuery.extend( deep, clone, copy );
|
|
|
|
// Don't bring in undefined values
|
|
} else if ( copy !== undefined ) {
|
|
target[ name ] = copy;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return the modified object
|
|
return target;
|
|
};
|
|
|
|
jQuery.extend( {
|
|
|
|
// Unique for each copy of jQuery on the page
|
|
expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
|
|
|
|
// Assume jQuery is ready without the ready module
|
|
isReady: true,
|
|
|
|
error: function( msg ) {
|
|
throw new Error( msg );
|
|
},
|
|
|
|
noop: function() {},
|
|
|
|
isPlainObject: function( obj ) {
|
|
var proto, Ctor;
|
|
|
|
// Detect obvious negatives
|
|
// Use toString instead of jQuery.type to catch host objects
|
|
if ( !obj || toString.call( obj ) !== "[object Object]" ) {
|
|
return false;
|
|
}
|
|
|
|
proto = getProto( obj );
|
|
|
|
// Objects with no prototype (e.g., `Object.create( null )`) are plain
|
|
if ( !proto ) {
|
|
return true;
|
|
}
|
|
|
|
// Objects with prototype are plain iff they were constructed by a global Object function
|
|
Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
|
|
return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
|
|
},
|
|
|
|
isEmptyObject: function( obj ) {
|
|
var name;
|
|
|
|
for ( name in obj ) {
|
|
return false;
|
|
}
|
|
return true;
|
|
},
|
|
|
|
// Evaluates a script in a provided context; falls back to the global one
|
|
// if not specified.
|
|
globalEval: function( code, options, doc ) {
|
|
DOMEval( code, { nonce: options && options.nonce }, doc );
|
|
},
|
|
|
|
each: function( obj, callback ) {
|
|
var length, i = 0;
|
|
|
|
if ( isArrayLike( obj ) ) {
|
|
length = obj.length;
|
|
for ( ; i < length; i++ ) {
|
|
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
for ( i in obj ) {
|
|
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return obj;
|
|
},
|
|
|
|
// results is for internal usage only
|
|
makeArray: function( arr, results ) {
|
|
var ret = results || [];
|
|
|
|
if ( arr != null ) {
|
|
if ( isArrayLike( Object( arr ) ) ) {
|
|
jQuery.merge( ret,
|
|
typeof arr === "string" ?
|
|
[ arr ] : arr
|
|
);
|
|
} else {
|
|
push.call( ret, arr );
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
},
|
|
|
|
inArray: function( elem, arr, i ) {
|
|
return arr == null ? -1 : indexOf.call( arr, elem, i );
|
|
},
|
|
|
|
// Support: Android <=4.0 only, PhantomJS 1 only
|
|
// push.apply(_, arraylike) throws on ancient WebKit
|
|
merge: function( first, second ) {
|
|
var len = +second.length,
|
|
j = 0,
|
|
i = first.length;
|
|
|
|
for ( ; j < len; j++ ) {
|
|
first[ i++ ] = second[ j ];
|
|
}
|
|
|
|
first.length = i;
|
|
|
|
return first;
|
|
},
|
|
|
|
grep: function( elems, callback, invert ) {
|
|
var callbackInverse,
|
|
matches = [],
|
|
i = 0,
|
|
length = elems.length,
|
|
callbackExpect = !invert;
|
|
|
|
// Go through the array, only saving the items
|
|
// that pass the validator function
|
|
for ( ; i < length; i++ ) {
|
|
callbackInverse = !callback( elems[ i ], i );
|
|
if ( callbackInverse !== callbackExpect ) {
|
|
matches.push( elems[ i ] );
|
|
}
|
|
}
|
|
|
|
return matches;
|
|
},
|
|
|
|
// arg is for internal usage only
|
|
map: function( elems, callback, arg ) {
|
|
var length, value,
|
|
i = 0,
|
|
ret = [];
|
|
|
|
// Go through the array, translating each of the items to their new values
|
|
if ( isArrayLike( elems ) ) {
|
|
length = elems.length;
|
|
for ( ; i < length; i++ ) {
|
|
value = callback( elems[ i ], i, arg );
|
|
|
|
if ( value != null ) {
|
|
ret.push( value );
|
|
}
|
|
}
|
|
|
|
// Go through every key on the object,
|
|
} else {
|
|
for ( i in elems ) {
|
|
value = callback( elems[ i ], i, arg );
|
|
|
|
if ( value != null ) {
|
|
ret.push( value );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Flatten any nested arrays
|
|
return flat( ret );
|
|
},
|
|
|
|
// A global GUID counter for objects
|
|
guid: 1,
|
|
|
|
// jQuery.support is not used in Core but other projects attach their
|
|
// properties to it so it needs to exist.
|
|
support: support
|
|
} );
|
|
|
|
if ( typeof Symbol === "function" ) {
|
|
jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
|
|
}
|
|
|
|
// Populate the class2type map
|
|
jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
|
|
function( _i, name ) {
|
|
class2type[ "[object " + name + "]" ] = name.toLowerCase();
|
|
} );
|
|
|
|
function isArrayLike( obj ) {
|
|
|
|
// Support: real iOS 8.2 only (not reproducible in simulator)
|
|
// `in` check used to prevent JIT error (gh-2145)
|
|
// hasOwn isn't used here due to false negatives
|
|
// regarding Nodelist length in IE
|
|
var length = !!obj && "length" in obj && obj.length,
|
|
type = toType( obj );
|
|
|
|
if ( isFunction( obj ) || isWindow( obj ) ) {
|
|
return false;
|
|
}
|
|
|
|
return type === "array" || length === 0 ||
|
|
typeof length === "number" && length > 0 && ( length - 1 ) in obj;
|
|
}
|
|
var Sizzle =
|
|
/*!
|
|
* Sizzle CSS Selector Engine v2.3.6
|
|
* https://sizzlejs.com/
|
|
*
|
|
* Copyright JS Foundation and other contributors
|
|
* Released under the MIT license
|
|
* https://js.foundation/
|
|
*
|
|
* Date: 2021-02-16
|
|
*/
|
|
( function( window ) {
|
|
var i,
|
|
support,
|
|
Expr,
|
|
getText,
|
|
isXML,
|
|
tokenize,
|
|
compile,
|
|
select,
|
|
outermostContext,
|
|
sortInput,
|
|
hasDuplicate,
|
|
|
|
// Local document vars
|
|
setDocument,
|
|
document,
|
|
docElem,
|
|
documentIsHTML,
|
|
rbuggyQSA,
|
|
rbuggyMatches,
|
|
matches,
|
|
contains,
|
|
|
|
// Instance-specific data
|
|
expando = "sizzle" + 1 * new Date(),
|
|
preferredDoc = window.document,
|
|
dirruns = 0,
|
|
done = 0,
|
|
classCache = createCache(),
|
|
tokenCache = createCache(),
|
|
compilerCache = createCache(),
|
|
nonnativeSelectorCache = createCache(),
|
|
sortOrder = function( a, b ) {
|
|
if ( a === b ) {
|
|
hasDuplicate = true;
|
|
}
|
|
return 0;
|
|
},
|
|
|
|
// Instance methods
|
|
hasOwn = ( {} ).hasOwnProperty,
|
|
arr = [],
|
|
pop = arr.pop,
|
|
pushNative = arr.push,
|
|
push = arr.push,
|
|
slice = arr.slice,
|
|
|
|
// Use a stripped-down indexOf as it's faster than native
|
|
// https://jsperf.com/thor-indexof-vs-for/5
|
|
indexOf = function( list, elem ) {
|
|
var i = 0,
|
|
len = list.length;
|
|
for ( ; i < len; i++ ) {
|
|
if ( list[ i ] === elem ) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
},
|
|
|
|
booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
|
|
"ismap|loop|multiple|open|readonly|required|scoped",
|
|
|
|
// Regular expressions
|
|
|
|
// http://www.w3.org/TR/css3-selectors/#whitespace
|
|
whitespace = "[\\x20\\t\\r\\n\\f]",
|
|
|
|
// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
|
|
identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
|
|
"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
|
|
|
|
// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
|
|
attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
|
|
|
|
// Operator (capture 2)
|
|
"*([*^$|!~]?=)" + whitespace +
|
|
|
|
// "Attribute values must be CSS identifiers [capture 5]
|
|
// or strings [capture 3 or capture 4]"
|
|
"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
|
|
whitespace + "*\\]",
|
|
|
|
pseudos = ":(" + identifier + ")(?:\\((" +
|
|
|
|
// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
|
|
// 1. quoted (capture 3; capture 4 or capture 5)
|
|
"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
|
|
|
|
// 2. simple (capture 6)
|
|
"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
|
|
|
|
// 3. anything else (capture 2)
|
|
".*" +
|
|
")\\)|)",
|
|
|
|
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
|
|
rwhitespace = new RegExp( whitespace + "+", "g" ),
|
|
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
|
|
whitespace + "+$", "g" ),
|
|
|
|
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
|
|
rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
|
|
"*" ),
|
|
rdescend = new RegExp( whitespace + "|>" ),
|
|
|
|
rpseudo = new RegExp( pseudos ),
|
|
ridentifier = new RegExp( "^" + identifier + "$" ),
|
|
|
|
matchExpr = {
|
|
"ID": new RegExp( "^#(" + identifier + ")" ),
|
|
"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
|
|
"TAG": new RegExp( "^(" + identifier + "|[*])" ),
|
|
"ATTR": new RegExp( "^" + attributes ),
|
|
"PSEUDO": new RegExp( "^" + pseudos ),
|
|
"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
|
|
whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
|
|
whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
|
|
"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
|
|
|
|
// For use in libraries implementing .is()
|
|
// We use this for POS matching in `select`
|
|
"needsContext": new RegExp( "^" + whitespace +
|
|
"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
|
|
"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
|
|
},
|
|
|
|
rhtml = /HTML$/i,
|
|
rinputs = /^(?:input|select|textarea|button)$/i,
|
|
rheader = /^h\d$/i,
|
|
|
|
rnative = /^[^{]+\{\s*\[native \w/,
|
|
|
|
// Easily-parseable/retrievable ID or TAG or CLASS selectors
|
|
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
|
|
|
|
rsibling = /[+~]/,
|
|
|
|
// CSS escapes
|
|
// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
|
|
runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
|
|
funescape = function( escape, nonHex ) {
|
|
var high = "0x" + escape.slice( 1 ) - 0x10000;
|
|
|
|
return nonHex ?
|
|
|
|
// Strip the backslash prefix from a non-hex escape sequence
|
|
nonHex :
|
|
|
|
// Replace a hexadecimal escape sequence with the encoded Unicode code point
|
|
// Support: IE <=11+
|
|
// For values outside the Basic Multilingual Plane (BMP), manually construct a
|
|
// surrogate pair
|
|
high < 0 ?
|
|
String.fromCharCode( high + 0x10000 ) :
|
|
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
|
|
},
|
|
|
|
// CSS string/identifier serialization
|
|
// https://drafts.csswg.org/cssom/#common-serializing-idioms
|
|
rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
|
|
fcssescape = function( ch, asCodePoint ) {
|
|
if ( asCodePoint ) {
|
|
|
|
// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
|
|
if ( ch === "\0" ) {
|
|
return "\uFFFD";
|
|
}
|
|
|
|
// Control characters and (dependent upon position) numbers get escaped as code points
|
|
return ch.slice( 0, -1 ) + "\\" +
|
|
ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
|
|
}
|
|
|
|
// Other potentially-special ASCII characters get backslash-escaped
|
|
return "\\" + ch;
|
|
},
|
|
|
|
// Used for iframes
|
|
// See setDocument()
|
|
// Removing the function wrapper causes a "Permission Denied"
|
|
// error in IE
|
|
unloadHandler = function() {
|
|
setDocument();
|
|
},
|
|
|
|
inDisabledFieldset = addCombinator(
|
|
function( elem ) {
|
|
return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
|
|
},
|
|
{ dir: "parentNode", next: "legend" }
|
|
);
|
|
|
|
// Optimize for push.apply( _, NodeList )
|
|
try {
|
|
push.apply(
|
|
( arr = slice.call( preferredDoc.childNodes ) ),
|
|
preferredDoc.childNodes
|
|
);
|
|
|
|
// Support: Android<4.0
|
|
// Detect silently failing push.apply
|
|
// eslint-disable-next-line no-unused-expressions
|
|
arr[ preferredDoc.childNodes.length ].nodeType;
|
|
} catch ( e ) {
|
|
push = { apply: arr.length ?
|
|
|
|
// Leverage slice if possible
|
|
function( target, els ) {
|
|
pushNative.apply( target, slice.call( els ) );
|
|
} :
|
|
|
|
// Support: IE<9
|
|
// Otherwise append directly
|
|
function( target, els ) {
|
|
var j = target.length,
|
|
i = 0;
|
|
|
|
// Can't trust NodeList.length
|
|
while ( ( target[ j++ ] = els[ i++ ] ) ) {}
|
|
target.length = j - 1;
|
|
}
|
|
};
|
|
}
|
|
|
|
function Sizzle( selector, context, results, seed ) {
|
|
var m, i, elem, nid, match, groups, newSelector,
|
|
newContext = context && context.ownerDocument,
|
|
|
|
// nodeType defaults to 9, since context defaults to document
|
|
nodeType = context ? context.nodeType : 9;
|
|
|
|
results = results || [];
|
|
|
|
// Return early from calls with invalid selector or context
|
|
if ( typeof selector !== "string" || !selector ||
|
|
nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
|
|
|
|
return results;
|
|
}
|
|
|
|
// Try to shortcut find operations (as opposed to filters) in HTML documents
|
|
if ( !seed ) {
|
|
setDocument( context );
|
|
context = context || document;
|
|
|
|
if ( documentIsHTML ) {
|
|
|
|
// If the selector is sufficiently simple, try using a "get*By*" DOM method
|
|
// (excepting DocumentFragment context, where the methods don't exist)
|
|
if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
|
|
|
|
// ID selector
|
|
if ( ( m = match[ 1 ] ) ) {
|
|
|
|
// Document context
|
|
if ( nodeType === 9 ) {
|
|
if ( ( elem = context.getElementById( m ) ) ) {
|
|
|
|
// Support: IE, Opera, Webkit
|
|
// TODO: identify versions
|
|
// getElementById can match elements by name instead of ID
|
|
if ( elem.id === m ) {
|
|
results.push( elem );
|
|
return results;
|
|
}
|
|
} else {
|
|
return results;
|
|
}
|
|
|
|
// Element context
|
|
} else {
|
|
|
|
// Support: IE, Opera, Webkit
|
|
// TODO: identify versions
|
|
// getElementById can match elements by name instead of ID
|
|
if ( newContext && ( elem = newContext.getElementById( m ) ) &&
|
|
contains( context, elem ) &&
|
|
elem.id === m ) {
|
|
|
|
results.push( elem );
|
|
return results;
|
|
}
|
|
}
|
|
|
|
// Type selector
|
|
} else if ( match[ 2 ] ) {
|
|
push.apply( results, context.getElementsByTagName( selector ) );
|
|
return results;
|
|
|
|
// Class selector
|
|
} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
|
|
context.getElementsByClassName ) {
|
|
|
|
push.apply( results, context.getElementsByClassName( m ) );
|
|
return results;
|
|
}
|
|
}
|
|
|
|
// Take advantage of querySelectorAll
|
|
if ( support.qsa &&
|
|
!nonnativeSelectorCache[ selector + " " ] &&
|
|
( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
|
|
|
|
// Support: IE 8 only
|
|
// Exclude object elements
|
|
( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {
|
|
|
|
newSelector = selector;
|
|
newContext = context;
|
|
|
|
// qSA considers elements outside a scoping root when evaluating child or
|
|
// descendant combinators, which is not what we want.
|
|
// In such cases, we work around the behavior by prefixing every selector in the
|
|
// list with an ID selector referencing the scope context.
|
|
// The technique has to be used as well when a leading combinator is used
|
|
// as such selectors are not recognized by querySelectorAll.
|
|
// Thanks to Andrew Dupont for this technique.
|
|
if ( nodeType === 1 &&
|
|
( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {
|
|
|
|
// Expand context for sibling selectors
|
|
newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
|
|
context;
|
|
|
|
// We can use :scope instead of the ID hack if the browser
|
|
// supports it & if we're not changing the context.
|
|
if ( newContext !== context || !support.scope ) {
|
|
|
|
// Capture the context ID, setting it first if necessary
|
|
if ( ( nid = context.getAttribute( "id" ) ) ) {
|
|
nid = nid.replace( rcssescape, fcssescape );
|
|
} else {
|
|
context.setAttribute( "id", ( nid = expando ) );
|
|
}
|
|
}
|
|
|
|
// Prefix every selector in the list
|
|
groups = tokenize( selector );
|
|
i = groups.length;
|
|
while ( i-- ) {
|
|
groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
|
|
toSelector( groups[ i ] );
|
|
}
|
|
newSelector = groups.join( "," );
|
|
}
|
|
|
|
try {
|
|
push.apply( results,
|
|
newContext.querySelectorAll( newSelector )
|
|
);
|
|
return results;
|
|
} catch ( qsaError ) {
|
|
nonnativeSelectorCache( selector, true );
|
|
} finally {
|
|
if ( nid === expando ) {
|
|
context.removeAttribute( "id" );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// All others
|
|
return select( selector.replace( rtrim, "$1" ), context, results, seed );
|
|
}
|
|
|
|
/**
|
|
* Create key-value caches of limited size
|
|
* @returns {function(string, object)} Returns the Object data after storing it on itself with
|
|
* property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
|
|
* deleting the oldest entry
|
|
*/
|
|
function createCache() {
|
|
var keys = [];
|
|
|
|
function cache( key, value ) {
|
|
|
|
// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
|
|
if ( keys.push( key + " " ) > Expr.cacheLength ) {
|
|
|
|
// Only keep the most recent entries
|
|
delete cache[ keys.shift() ];
|
|
}
|
|
return ( cache[ key + " " ] = value );
|
|
}
|
|
return cache;
|
|
}
|
|
|
|
/**
|
|
* Mark a function for special use by Sizzle
|
|
* @param {Function} fn The function to mark
|
|
*/
|
|
function markFunction( fn ) {
|
|
fn[ expando ] = true;
|
|
return fn;
|
|
}
|
|
|
|
/**
|
|
* Support testing using an element
|
|
* @param {Function} fn Passed the created element and returns a boolean result
|
|
*/
|
|
function assert( fn ) {
|
|
var el = document.createElement( "fieldset" );
|
|
|
|
try {
|
|
return !!fn( el );
|
|
} catch ( e ) {
|
|
return false;
|
|
} finally {
|
|
|
|
// Remove from its parent by default
|
|
if ( el.parentNode ) {
|
|
el.parentNode.removeChild( el );
|
|
}
|
|
|
|
// release memory in IE
|
|
el = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds the same handler for all of the specified attrs
|
|
* @param {String} attrs Pipe-separated list of attributes
|
|
* @param {Function} handler The method that will be applied
|
|
*/
|
|
function addHandle( attrs, handler ) {
|
|
var arr = attrs.split( "|" ),
|
|
i = arr.length;
|
|
|
|
while ( i-- ) {
|
|
Expr.attrHandle[ arr[ i ] ] = handler;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks document order of two siblings
|
|
* @param {Element} a
|
|
* @param {Element} b
|
|
* @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
|
|
*/
|
|
function siblingCheck( a, b ) {
|
|
var cur = b && a,
|
|
diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
|
|
a.sourceIndex - b.sourceIndex;
|
|
|
|
// Use IE sourceIndex if available on both nodes
|
|
if ( diff ) {
|
|
return diff;
|
|
}
|
|
|
|
// Check if b follows a
|
|
if ( cur ) {
|
|
while ( ( cur = cur.nextSibling ) ) {
|
|
if ( cur === b ) {
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return a ? 1 : -1;
|
|
}
|
|
|
|
/**
|
|
* Returns a function to use in pseudos for input types
|
|
* @param {String} type
|
|
*/
|
|
function createInputPseudo( type ) {
|
|
return function( elem ) {
|
|
var name = elem.nodeName.toLowerCase();
|
|
return name === "input" && elem.type === type;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns a function to use in pseudos for buttons
|
|
* @param {String} type
|
|
*/
|
|
function createButtonPseudo( type ) {
|
|
return function( elem ) {
|
|
var name = elem.nodeName.toLowerCase();
|
|
return ( name === "input" || name === "button" ) && elem.type === type;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns a function to use in pseudos for :enabled/:disabled
|
|
* @param {Boolean} disabled true for :disabled; false for :enabled
|
|
*/
|
|
function createDisabledPseudo( disabled ) {
|
|
|
|
// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
|
|
return function( elem ) {
|
|
|
|
// Only certain elements can match :enabled or :disabled
|
|
// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
|
|
// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
|
|
if ( "form" in elem ) {
|
|
|
|
// Check for inherited disabledness on relevant non-disabled elements:
|
|
// * listed form-associated elements in a disabled fieldset
|
|
// https://html.spec.whatwg.org/multipage/forms.html#category-listed
|
|
// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
|
|
// * option elements in a disabled optgroup
|
|
// https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
|
|
// All such elements have a "form" property.
|
|
if ( elem.parentNode && elem.disabled === false ) {
|
|
|
|
// Option elements defer to a parent optgroup if present
|
|
if ( "label" in elem ) {
|
|
if ( "label" in elem.parentNode ) {
|
|
return elem.parentNode.disabled === disabled;
|
|
} else {
|
|
return elem.disabled === disabled;
|
|
}
|
|
}
|
|
|
|
// Support: IE 6 - 11
|
|
// Use the isDisabled shortcut property to check for disabled fieldset ancestors
|
|
return elem.isDisabled === disabled ||
|
|
|
|
// Where there is no isDisabled, check manually
|
|
/* jshint -W018 */
|
|
elem.isDisabled !== !disabled &&
|
|
inDisabledFieldset( elem ) === disabled;
|
|
}
|
|
|
|
return elem.disabled === disabled;
|
|
|
|
// Try to winnow out elements that can't be disabled before trusting the disabled property.
|
|
// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
|
|
// even exist on them, let alone have a boolean value.
|
|
} else if ( "label" in elem ) {
|
|
return elem.disabled === disabled;
|
|
}
|
|
|
|
// Remaining elements are neither :enabled nor :disabled
|
|
return false;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns a function to use in pseudos for positionals
|
|
* @param {Function} fn
|
|
*/
|
|
function createPositionalPseudo( fn ) {
|
|
return markFunction( function( argument ) {
|
|
argument = +argument;
|
|
return markFunction( function( seed, matches ) {
|
|
var j,
|
|
matchIndexes = fn( [], seed.length, argument ),
|
|
i = matchIndexes.length;
|
|
|
|
// Match elements found at the specified indexes
|
|
while ( i-- ) {
|
|
if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
|
|
seed[ j ] = !( matches[ j ] = seed[ j ] );
|
|
}
|
|
}
|
|
} );
|
|
} );
|
|
}
|
|
|
|
/**
|
|
* Checks a node for validity as a Sizzle context
|
|
* @param {Element|Object=} context
|
|
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
|
|
*/
|
|
function testContext( context ) {
|
|
return context && typeof context.getElementsByTagName !== "undefined" && context;
|
|
}
|
|
|
|
// Expose support vars for convenience
|
|
support = Sizzle.support = {};
|
|
|
|
/**
|
|
* Detects XML nodes
|
|
* @param {Element|Object} elem An element or a document
|
|
* @returns {Boolean} True iff elem is a non-HTML XML node
|
|
*/
|
|
isXML = Sizzle.isXML = function( elem ) {
|
|
var namespace = elem && elem.namespaceURI,
|
|
docElem = elem && ( elem.ownerDocument || elem ).documentElement;
|
|
|
|
// Support: IE <=8
|
|
// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
|
|
// https://bugs.jquery.com/ticket/4833
|
|
return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
|
|
};
|
|
|
|
/**
|
|
* Sets document-related variables once based on the current document
|
|
* @param {Element|Object} [doc] An element or document object to use to set the document
|
|
* @returns {Object} Returns the current document
|
|
*/
|
|
setDocument = Sizzle.setDocument = function( node ) {
|
|
var hasCompare, subWindow,
|
|
doc = node ? node.ownerDocument || node : preferredDoc;
|
|
|
|
// Return early if doc is invalid or already selected
|
|
// Support: IE 11+, Edge 17 - 18+
|
|
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
|
// two documents; shallow comparisons work.
|
|
// eslint-disable-next-line eqeqeq
|
|
if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
|
|
return document;
|
|
}
|
|
|
|
// Update global variables
|
|
document = doc;
|
|
docElem = document.documentElement;
|
|
documentIsHTML = !isXML( document );
|
|
|
|
// Support: IE 9 - 11+, Edge 12 - 18+
|
|
// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
|
|
// Support: IE 11+, Edge 17 - 18+
|
|
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
|
// two documents; shallow comparisons work.
|
|
// eslint-disable-next-line eqeqeq
|
|
if ( preferredDoc != document &&
|
|
( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
|
|
|
|
// Support: IE 11, Edge
|
|
if ( subWindow.addEventListener ) {
|
|
subWindow.addEventListener( "unload", unloadHandler, false );
|
|
|
|
// Support: IE 9 - 10 only
|
|
} else if ( subWindow.attachEvent ) {
|
|
subWindow.attachEvent( "onunload", unloadHandler );
|
|
}
|
|
}
|
|
|
|
// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
|
|
// Safari 4 - 5 only, Opera <=11.6 - 12.x only
|
|
// IE/Edge & older browsers don't support the :scope pseudo-class.
|
|
// Support: Safari 6.0 only
|
|
// Safari 6.0 supports :scope but it's an alias of :root there.
|
|
support.scope = assert( function( el ) {
|
|
docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
|
|
return typeof el.querySelectorAll !== "undefined" &&
|
|
!el.querySelectorAll( ":scope fieldset div" ).length;
|
|
} );
|
|
|
|
/* Attributes
|
|
---------------------------------------------------------------------- */
|
|
|
|
// Support: IE<8
|
|
// Verify that getAttribute really returns attributes and not properties
|
|
// (excepting IE8 booleans)
|
|
support.attributes = assert( function( el ) {
|
|
el.className = "i";
|
|
return !el.getAttribute( "className" );
|
|
} );
|
|
|
|
/* getElement(s)By*
|
|
---------------------------------------------------------------------- */
|
|
|
|
// Check if getElementsByTagName("*") returns only elements
|
|
support.getElementsByTagName = assert( function( el ) {
|
|
el.appendChild( document.createComment( "" ) );
|
|
return !el.getElementsByTagName( "*" ).length;
|
|
} );
|
|
|
|
// Support: IE<9
|
|
support.getElementsByClassName = rnative.test( document.getElementsByClassName );
|
|
|
|
// Support: IE<10
|
|
// Check if getElementById returns elements by name
|
|
// The broken getElementById methods don't pick up programmatically-set names,
|
|
// so use a roundabout getElementsByName test
|
|
support.getById = assert( function( el ) {
|
|
docElem.appendChild( el ).id = expando;
|
|
return !document.getElementsByName || !document.getElementsByName( expando ).length;
|
|
} );
|
|
|
|
// ID filter and find
|
|
if ( support.getById ) {
|
|
Expr.filter[ "ID" ] = function( id ) {
|
|
var attrId = id.replace( runescape, funescape );
|
|
return function( elem ) {
|
|
return elem.getAttribute( "id" ) === attrId;
|
|
};
|
|
};
|
|
Expr.find[ "ID" ] = function( id, context ) {
|
|
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
|
|
var elem = context.getElementById( id );
|
|
return elem ? [ elem ] : [];
|
|
}
|
|
};
|
|
} else {
|
|
Expr.filter[ "ID" ] = function( id ) {
|
|
var attrId = id.replace( runescape, funescape );
|
|
return function( elem ) {
|
|
var node = typeof elem.getAttributeNode !== "undefined" &&
|
|
elem.getAttributeNode( "id" );
|
|
return node && node.value === attrId;
|
|
};
|
|
};
|
|
|
|
// Support: IE 6 - 7 only
|
|
// getElementById is not reliable as a find shortcut
|
|
Expr.find[ "ID" ] = function( id, context ) {
|
|
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
|
|
var node, i, elems,
|
|
elem = context.getElementById( id );
|
|
|
|
if ( elem ) {
|
|
|
|
// Verify the id attribute
|
|
node = elem.getAttributeNode( "id" );
|
|
if ( node && node.value === id ) {
|
|
return [ elem ];
|
|
}
|
|
|
|
// Fall back on getElementsByName
|
|
elems = context.getElementsByName( id );
|
|
i = 0;
|
|
while ( ( elem = elems[ i++ ] ) ) {
|
|
node = elem.getAttributeNode( "id" );
|
|
if ( node && node.value === id ) {
|
|
return [ elem ];
|
|
}
|
|
}
|
|
}
|
|
|
|
return [];
|
|
}
|
|
};
|
|
}
|
|
|
|
// Tag
|
|
Expr.find[ "TAG" ] = support.getElementsByTagName ?
|
|
function( tag, context ) {
|
|
if ( typeof context.getElementsByTagName !== "undefined" ) {
|
|
return context.getElementsByTagName( tag );
|
|
|
|
// DocumentFragment nodes don't have gEBTN
|
|
} else if ( support.qsa ) {
|
|
return context.querySelectorAll( tag );
|
|
}
|
|
} :
|
|
|
|
function( tag, context ) {
|
|
var elem,
|
|
tmp = [],
|
|
i = 0,
|
|
|
|
// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
|
|
results = context.getElementsByTagName( tag );
|
|
|
|
// Filter out possible comments
|
|
if ( tag === "*" ) {
|
|
while ( ( elem = results[ i++ ] ) ) {
|
|
if ( elem.nodeType === 1 ) {
|
|
tmp.push( elem );
|
|
}
|
|
}
|
|
|
|
return tmp;
|
|
}
|
|
return results;
|
|
};
|
|
|
|
// Class
|
|
Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
|
|
if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
|
|
return context.getElementsByClassName( className );
|
|
}
|
|
};
|
|
|
|
/* QSA/matchesSelector
|
|
---------------------------------------------------------------------- */
|
|
|
|
// QSA and matchesSelector support
|
|
|
|
// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
|
|
rbuggyMatches = [];
|
|
|
|
// qSa(:focus) reports false when true (Chrome 21)
|
|
// We allow this because of a bug in IE8/9 that throws an error
|
|
// whenever `document.activeElement` is accessed on an iframe
|
|
// So, we allow :focus to pass through QSA all the time to avoid the IE error
|
|
// See https://bugs.jquery.com/ticket/13378
|
|
rbuggyQSA = [];
|
|
|
|
if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {
|
|
|
|
// Build QSA regex
|
|
// Regex strategy adopted from Diego Perini
|
|
assert( function( el ) {
|
|
|
|
var input;
|
|
|
|
// Select is set to empty string on purpose
|
|
// This is to test IE's treatment of not explicitly
|
|
// setting a boolean content attribute,
|
|
// since its presence should be enough
|
|
// https://bugs.jquery.com/ticket/12359
|
|
docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
|
|
"<select id='" + expando + "-\r\\' msallowcapture=''>" +
|
|
"<option selected=''></option></select>";
|
|
|
|
// Support: IE8, Opera 11-12.16
|
|
// Nothing should be selected when empty strings follow ^= or $= or *=
|
|
// The test attribute must be unknown in Opera but "safe" for WinRT
|
|
// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
|
|
if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
|
|
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
|
|
}
|
|
|
|
// Support: IE8
|
|
// Boolean attributes and "value" are not treated correctly
|
|
if ( !el.querySelectorAll( "[selected]" ).length ) {
|
|
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
|
|
}
|
|
|
|
// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
|
|
if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
|
|
rbuggyQSA.push( "~=" );
|
|
}
|
|
|
|
// Support: IE 11+, Edge 15 - 18+
|
|
// IE 11/Edge don't find elements on a `[name='']` query in some cases.
|
|
// Adding a temporary attribute to the document before the selection works
|
|
// around the issue.
|
|
// Interestingly, IE 10 & older don't seem to have the issue.
|
|
input = document.createElement( "input" );
|
|
input.setAttribute( "name", "" );
|
|
el.appendChild( input );
|
|
if ( !el.querySelectorAll( "[name='']" ).length ) {
|
|
rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
|
|
whitespace + "*(?:''|\"\")" );
|
|
}
|
|
|
|
// Webkit/Opera - :checked should return selected option elements
|
|
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
|
|
// IE8 throws error here and will not see later tests
|
|
if ( !el.querySelectorAll( ":checked" ).length ) {
|
|
rbuggyQSA.push( ":checked" );
|
|
}
|
|
|
|
// Support: Safari 8+, iOS 8+
|
|
// https://bugs.webkit.org/show_bug.cgi?id=136851
|
|
// In-page `selector#id sibling-combinator selector` fails
|
|
if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
|
|
rbuggyQSA.push( ".#.+[+~]" );
|
|
}
|
|
|
|
// Support: Firefox <=3.6 - 5 only
|
|
// Old Firefox doesn't throw on a badly-escaped identifier.
|
|
el.querySelectorAll( "\\\f" );
|
|
rbuggyQSA.push( "[\\r\\n\\f]" );
|
|
} );
|
|
|
|
assert( function( el ) {
|
|
el.innerHTML = "<a href='' disabled='disabled'></a>" +
|
|
"<select disabled='disabled'><option/></select>";
|
|
|
|
// Support: Windows 8 Native Apps
|
|
// The type and name attributes are restricted during .innerHTML assignment
|
|
var input = document.createElement( "input" );
|
|
input.setAttribute( "type", "hidden" );
|
|
el.appendChild( input ).setAttribute( "name", "D" );
|
|
|
|
// Support: IE8
|
|
// Enforce case-sensitivity of name attribute
|
|
if ( el.querySelectorAll( "[name=d]" ).length ) {
|
|
rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
|
|
}
|
|
|
|
// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
|
|
// IE8 throws error here and will not see later tests
|
|
if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
|
|
rbuggyQSA.push( ":enabled", ":disabled" );
|
|
}
|
|
|
|
// Support: IE9-11+
|
|
// IE's :disabled selector does not pick up the children of disabled fieldsets
|
|
docElem.appendChild( el ).disabled = true;
|
|
if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
|
|
rbuggyQSA.push( ":enabled", ":disabled" );
|
|
}
|
|
|
|
// Support: Opera 10 - 11 only
|
|
// Opera 10-11 does not throw on post-comma invalid pseudos
|
|
el.querySelectorAll( "*,:x" );
|
|
rbuggyQSA.push( ",.*:" );
|
|
} );
|
|
}
|
|
|
|
if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
|
|
docElem.webkitMatchesSelector ||
|
|
docElem.mozMatchesSelector ||
|
|
docElem.oMatchesSelector ||
|
|
docElem.msMatchesSelector ) ) ) ) {
|
|
|
|
assert( function( el ) {
|
|
|
|
// Check to see if it's possible to do matchesSelector
|
|
// on a disconnected node (IE 9)
|
|
support.disconnectedMatch = matches.call( el, "*" );
|
|
|
|
// This should fail with an exception
|
|
// Gecko does not error, returns false instead
|
|
matches.call( el, "[s!='']:x" );
|
|
rbuggyMatches.push( "!=", pseudos );
|
|
} );
|
|
}
|
|
|
|
rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
|
|
rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );
|
|
|
|
/* Contains
|
|
---------------------------------------------------------------------- */
|
|
hasCompare = rnative.test( docElem.compareDocumentPosition );
|
|
|
|
// Element contains another
|
|
// Purposefully self-exclusive
|
|
// As in, an element does not contain itself
|
|
contains = hasCompare || rnative.test( docElem.contains ) ?
|
|
function( a, b ) {
|
|
var adown = a.nodeType === 9 ? a.documentElement : a,
|
|
bup = b && b.parentNode;
|
|
return a === bup || !!( bup && bup.nodeType === 1 && (
|
|
adown.contains ?
|
|
adown.contains( bup ) :
|
|
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
|
|
) );
|
|
} :
|
|
function( a, b ) {
|
|
if ( b ) {
|
|
while ( ( b = b.parentNode ) ) {
|
|
if ( b === a ) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/* Sorting
|
|
---------------------------------------------------------------------- */
|
|
|
|
// Document order sorting
|
|
sortOrder = hasCompare ?
|
|
function( a, b ) {
|
|
|
|
// Flag for duplicate removal
|
|
if ( a === b ) {
|
|
hasDuplicate = true;
|
|
return 0;
|
|
}
|
|
|
|
// Sort on method existence if only one input has compareDocumentPosition
|
|
var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
|
|
if ( compare ) {
|
|
return compare;
|
|
}
|
|
|
|
// Calculate position if both inputs belong to the same document
|
|
// Support: IE 11+, Edge 17 - 18+
|
|
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
|
// two documents; shallow comparisons work.
|
|
// eslint-disable-next-line eqeqeq
|
|
compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
|
|
a.compareDocumentPosition( b ) :
|
|
|
|
// Otherwise we know they are disconnected
|
|
1;
|
|
|
|
// Disconnected nodes
|
|
if ( compare & 1 ||
|
|
( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
|
|
|
|
// Choose the first element that is related to our preferred document
|
|
// Support: IE 11+, Edge 17 - 18+
|
|
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
|
// two documents; shallow comparisons work.
|
|
// eslint-disable-next-line eqeqeq
|
|
if ( a == document || a.ownerDocument == preferredDoc &&
|
|
contains( preferredDoc, a ) ) {
|
|
return -1;
|
|
}
|
|
|
|
// Support: IE 11+, Edge 17 - 18+
|
|
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
|
// two documents; shallow comparisons work.
|
|
// eslint-disable-next-line eqeqeq
|
|
if ( b == document || b.ownerDocument == preferredDoc &&
|
|
contains( preferredDoc, b ) ) {
|
|
return 1;
|
|
}
|
|
|
|
// Maintain original order
|
|
return sortInput ?
|
|
( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
|
|
0;
|
|
}
|
|
|
|
return compare & 4 ? -1 : 1;
|
|
} :
|
|
function( a, b ) {
|
|
|
|
// Exit early if the nodes are identical
|
|
if ( a === b ) {
|
|
hasDuplicate = true;
|
|
return 0;
|
|
}
|
|
|
|
var cur,
|
|
i = 0,
|
|
aup = a.parentNode,
|
|
bup = b.parentNode,
|
|
ap = [ a ],
|
|
bp = [ b ];
|
|
|
|
// Parentless nodes are either documents or disconnected
|
|
if ( !aup || !bup ) {
|
|
|
|
// Support: IE 11+, Edge 17 - 18+
|
|
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
|
// two documents; shallow comparisons work.
|
|
/* eslint-disable eqeqeq */
|
|
return a == document ? -1 :
|
|
b == document ? 1 :
|
|
/* eslint-enable eqeqeq */
|
|
aup ? -1 :
|
|
bup ? 1 :
|
|
sortInput ?
|
|
( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
|
|
0;
|
|
|
|
// If the nodes are siblings, we can do a quick check
|
|
} else if ( aup === bup ) {
|
|
return siblingCheck( a, b );
|
|
}
|
|
|
|
// Otherwise we need full lists of their ancestors for comparison
|
|
cur = a;
|
|
while ( ( cur = cur.parentNode ) ) {
|
|
ap.unshift( cur );
|
|
}
|
|
cur = b;
|
|
while ( ( cur = cur.parentNode ) ) {
|
|
bp.unshift( cur );
|
|
}
|
|
|
|
// Walk down the tree looking for a discrepancy
|
|
while ( ap[ i ] === bp[ i ] ) {
|
|
i++;
|
|
}
|
|
|
|
return i ?
|
|
|
|
// Do a sibling check if the nodes have a common ancestor
|
|
siblingCheck( ap[ i ], bp[ i ] ) :
|
|
|
|
// Otherwise nodes in our document sort first
|
|
// Support: IE 11+, Edge 17 - 18+
|
|
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
|
// two documents; shallow comparisons work.
|
|
/* eslint-disable eqeqeq */
|
|
ap[ i ] == preferredDoc ? -1 :
|
|
bp[ i ] == preferredDoc ? 1 :
|
|
/* eslint-enable eqeqeq */
|
|
0;
|
|
};
|
|
|
|
return document;
|
|
};
|
|
|
|
Sizzle.matches = function( expr, elements ) {
|
|
return Sizzle( expr, null, null, elements );
|
|
};
|
|
|
|
Sizzle.matchesSelector = function( elem, expr ) {
|
|
setDocument( elem );
|
|
|
|
if ( support.matchesSelector && documentIsHTML &&
|
|
!nonnativeSelectorCache[ expr + " " ] &&
|
|
( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
|
|
( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
|
|
|
|
try {
|
|
var ret = matches.call( elem, expr );
|
|
|
|
// IE 9's matchesSelector returns false on disconnected nodes
|
|
if ( ret || support.disconnectedMatch ||
|
|
|
|
// As well, disconnected nodes are said to be in a document
|
|
// fragment in IE 9
|
|
elem.document && elem.document.nodeType !== 11 ) {
|
|
return ret;
|
|
}
|
|
} catch ( e ) {
|
|
nonnativeSelectorCache( expr, true );
|
|
}
|
|
}
|
|
|
|
return Sizzle( expr, document, null, [ elem ] ).length > 0;
|
|
};
|
|
|
|
Sizzle.contains = function( context, elem ) {
|
|
|
|
// Set document vars if needed
|
|
// Support: IE 11+, Edge 17 - 18+
|
|
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
|
// two documents; shallow comparisons work.
|
|
// eslint-disable-next-line eqeqeq
|
|
if ( ( context.ownerDocument || context ) != document ) {
|
|
setDocument( context );
|
|
}
|
|
return contains( context, elem );
|
|
};
|
|
|
|
Sizzle.attr = function( elem, name ) {
|
|
|
|
// Set document vars if needed
|
|
// Support: IE 11+, Edge 17 - 18+
|
|
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
|
// two documents; shallow comparisons work.
|
|
// eslint-disable-next-line eqeqeq
|
|
if ( ( elem.ownerDocument || elem ) != document ) {
|
|
setDocument( elem );
|
|
}
|
|
|
|
var fn = Expr.attrHandle[ name.toLowerCase() ],
|
|
|
|
// Don't get fooled by Object.prototype properties (jQuery #13807)
|
|
val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
|
|
fn( elem, name, !documentIsHTML ) :
|
|
undefined;
|
|
|
|
return val !== undefined ?
|
|
val :
|
|
support.attributes || !documentIsHTML ?
|
|
elem.getAttribute( name ) :
|
|
( val = elem.getAttributeNode( name ) ) && val.specified ?
|
|
val.value :
|
|
null;
|
|
};
|
|
|
|
Sizzle.escape = function( sel ) {
|
|
return ( sel + "" ).replace( rcssescape, fcssescape );
|
|
};
|
|
|
|
Sizzle.error = function( msg ) {
|
|
throw new Error( "Syntax error, unrecognized expression: " + msg );
|
|
};
|
|
|
|
/**
|
|
* Document sorting and removing duplicates
|
|
* @param {ArrayLike} results
|
|
*/
|
|
Sizzle.uniqueSort = function( results ) {
|
|
var elem,
|
|
duplicates = [],
|
|
j = 0,
|
|
i = 0;
|
|
|
|
// Unless we *know* we can detect duplicates, assume their presence
|
|
hasDuplicate = !support.detectDuplicates;
|
|
sortInput = !support.sortStable && results.slice( 0 );
|
|
results.sort( sortOrder );
|
|
|
|
if ( hasDuplicate ) {
|
|
while ( ( elem = results[ i++ ] ) ) {
|
|
if ( elem === results[ i ] ) {
|
|
j = duplicates.push( i );
|
|
}
|
|
}
|
|
while ( j-- ) {
|
|
results.splice( duplicates[ j ], 1 );
|
|
}
|
|
}
|
|
|
|
// Clear input after sorting to release objects
|
|
// See https://github.com/jquery/sizzle/pull/225
|
|
sortInput = null;
|
|
|
|
return results;
|
|
};
|
|
|
|
/**
|
|
* Utility function for retrieving the text value of an array of DOM nodes
|
|
* @param {Array|Element} elem
|
|
*/
|
|
getText = Sizzle.getText = function( elem ) {
|
|
var node,
|
|
ret = "",
|
|
i = 0,
|
|
nodeType = elem.nodeType;
|
|
|
|
if ( !nodeType ) {
|
|
|
|
// If no nodeType, this is expected to be an array
|
|
while ( ( node = elem[ i++ ] ) ) {
|
|
|
|
// Do not traverse comment nodes
|
|
ret += getText( node );
|
|
}
|
|
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
|
|
|
|
// Use textContent for elements
|
|
// innerText usage removed for consistency of new lines (jQuery #11153)
|
|
if ( typeof elem.textContent === "string" ) {
|
|
return elem.textContent;
|
|
} else {
|
|
|
|
// Traverse its children
|
|
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
|
|
ret += getText( elem );
|
|
}
|
|
}
|
|
} else if ( nodeType === 3 || nodeType === 4 ) {
|
|
return elem.nodeValue;
|
|
}
|
|
|
|
// Do not include comment or processing instruction nodes
|
|
|
|
return ret;
|
|
};
|
|
|
|
Expr = Sizzle.selectors = {
|
|
|
|
// Can be adjusted by the user
|
|
cacheLength: 50,
|
|
|
|
createPseudo: markFunction,
|
|
|
|
match: matchExpr,
|
|
|
|
attrHandle: {},
|
|
|
|
find: {},
|
|
|
|
relative: {
|
|
">": { dir: "parentNode", first: true },
|
|
" ": { dir: "parentNode" },
|
|
"+": { dir: "previousSibling", first: true },
|
|
"~": { dir: "previousSibling" }
|
|
},
|
|
|
|
preFilter: {
|
|
"ATTR": function( match ) {
|
|
match[ 1 ] = match[ 1 ].replace( runescape, funescape );
|
|
|
|
// Move the given value to match[3] whether quoted or unquoted
|
|
match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
|
|
match[ 5 ] || "" ).replace( runescape, funescape );
|
|
|
|
if ( match[ 2 ] === "~=" ) {
|
|
match[ 3 ] = " " + match[ 3 ] + " ";
|
|
}
|
|
|
|
return match.slice( 0, 4 );
|
|
},
|
|
|
|
"CHILD": function( match ) {
|
|
|
|
/* matches from matchExpr["CHILD"]
|
|
1 type (only|nth|...)
|
|
2 what (child|of-type)
|
|
3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
|
|
4 xn-component of xn+y argument ([+-]?\d*n|)
|
|
5 sign of xn-component
|
|
6 x of xn-component
|
|
7 sign of y-component
|
|
8 y of y-component
|
|
*/
|
|
match[ 1 ] = match[ 1 ].toLowerCase();
|
|
|
|
if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
|
|
|
|
// nth-* requires argument
|
|
if ( !match[ 3 ] ) {
|
|
Sizzle.error( match[ 0 ] );
|
|
}
|
|
|
|
// numeric x and y parameters for Expr.filter.CHILD
|
|
// remember that false/true cast respectively to 0/1
|
|
match[ 4 ] = +( match[ 4 ] ?
|
|
match[ 5 ] + ( match[ 6 ] || 1 ) :
|
|
2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
|
|
match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
|
|
|
|
// other types prohibit arguments
|
|
} else if ( match[ 3 ] ) {
|
|
Sizzle.error( match[ 0 ] );
|
|
}
|
|
|
|
return match;
|
|
},
|
|
|
|
"PSEUDO": function( match ) {
|
|
var excess,
|
|
unquoted = !match[ 6 ] && match[ 2 ];
|
|
|
|
if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
|
|
return null;
|
|
}
|
|
|
|
// Accept quoted arguments as-is
|
|
if ( match[ 3 ] ) {
|
|
match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
|
|
|
|
// Strip excess characters from unquoted arguments
|
|
} else if ( unquoted && rpseudo.test( unquoted ) &&
|
|
|
|
// Get excess from tokenize (recursively)
|
|
( excess = tokenize( unquoted, true ) ) &&
|
|
|
|
// advance to the next closing parenthesis
|
|
( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
|
|
|
|
// excess is a negative index
|
|
match[ 0 ] = match[ 0 ].slice( 0, excess );
|
|
match[ 2 ] = unquoted.slice( 0, excess );
|
|
}
|
|
|
|
// Return only captures needed by the pseudo filter method (type and argument)
|
|
return match.slice( 0, 3 );
|
|
}
|
|
},
|
|
|
|
filter: {
|
|
|
|
"TAG": function( nodeNameSelector ) {
|
|
var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
|
|
return nodeNameSelector === "*" ?
|
|
function() {
|
|
return true;
|
|
} :
|
|
function( elem ) {
|
|
return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
|
|
};
|
|
},
|
|
|
|
"CLASS": function( className ) {
|
|
var pattern = classCache[ className + " " ];
|
|
|
|
return pattern ||
|
|
( pattern = new RegExp( "(^|" + whitespace +
|
|
")" + className + "(" + whitespace + "|$)" ) ) && classCache(
|
|
className, function( elem ) {
|
|
return pattern.test(
|
|
typeof elem.className === "string" && elem.className ||
|
|
typeof elem.getAttribute !== "undefined" &&
|
|
elem.getAttribute( "class" ) ||
|
|
""
|
|
);
|
|
} );
|
|
},
|
|
|
|
"ATTR": function( name, operator, check ) {
|
|
return function( elem ) {
|
|
var result = Sizzle.attr( elem, name );
|
|
|
|
if ( result == null ) {
|
|
return operator === "!=";
|
|
}
|
|
if ( !operator ) {
|
|
return true;
|
|
}
|
|
|
|
result += "";
|
|
|
|
/* eslint-disable max-len */
|
|
|
|
return operator === "=" ? result === check :
|
|
operator === "!=" ? result !== check :
|
|
operator === "^=" ? check && result.indexOf( check ) === 0 :
|
|
operator === "*=" ? check && result.indexOf( check ) > -1 :
|
|
operator === "$=" ? check && result.slice( -check.length ) === check :
|
|
operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
|
|
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
|
|
false;
|
|
/* eslint-enable max-len */
|
|
|
|
};
|
|
},
|
|
|
|
"CHILD": function( type, what, _argument, first, last ) {
|
|
var simple = type.slice( 0, 3 ) !== "nth",
|
|
forward = type.slice( -4 ) !== "last",
|
|
ofType = what === "of-type";
|
|
|
|
return first === 1 && last === 0 ?
|
|
|
|
// Shortcut for :nth-*(n)
|
|
function( elem ) {
|
|
return !!elem.parentNode;
|
|
} :
|
|
|
|
function( elem, _context, xml ) {
|
|
var cache, uniqueCache, outerCache, node, nodeIndex, start,
|
|
dir = simple !== forward ? "nextSibling" : "previousSibling",
|
|
parent = elem.parentNode,
|
|
name = ofType && elem.nodeName.toLowerCase(),
|
|
useCache = !xml && !ofType,
|
|
diff = false;
|
|
|
|
if ( parent ) {
|
|
|
|
// :(first|last|only)-(child|of-type)
|
|
if ( simple ) {
|
|
while ( dir ) {
|
|
node = elem;
|
|
while ( ( node = node[ dir ] ) ) {
|
|
if ( ofType ?
|
|
node.nodeName.toLowerCase() === name :
|
|
node.nodeType === 1 ) {
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Reverse direction for :only-* (if we haven't yet done so)
|
|
start = dir = type === "only" && !start && "nextSibling";
|
|
}
|
|
return true;
|
|
}
|
|
|
|
start = [ forward ? parent.firstChild : parent.lastChild ];
|
|
|
|
// non-xml :nth-child(...) stores cache data on `parent`
|
|
if ( forward && useCache ) {
|
|
|
|
// Seek `elem` from a previously-cached index
|
|
|
|
// ...in a gzip-friendly way
|
|
node = parent;
|
|
outerCache = node[ expando ] || ( node[ expando ] = {} );
|
|
|
|
// Support: IE <9 only
|
|
// Defend against cloned attroperties (jQuery gh-1709)
|
|
uniqueCache = outerCache[ node.uniqueID ] ||
|
|
( outerCache[ node.uniqueID ] = {} );
|
|
|
|
cache = uniqueCache[ type ] || [];
|
|
nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
|
|
diff = nodeIndex && cache[ 2 ];
|
|
node = nodeIndex && parent.childNodes[ nodeIndex ];
|
|
|
|
while ( ( node = ++nodeIndex && node && node[ dir ] ||
|
|
|
|
// Fallback to seeking `elem` from the start
|
|
( diff = nodeIndex = 0 ) || start.pop() ) ) {
|
|
|
|
// When found, cache indexes on `parent` and break
|
|
if ( node.nodeType === 1 && ++diff && node === elem ) {
|
|
uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
|
|
break;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
// Use previously-cached element index if available
|
|
if ( useCache ) {
|
|
|
|
// ...in a gzip-friendly way
|
|
node = elem;
|
|
outerCache = node[ expando ] || ( node[ expando ] = {} );
|
|
|
|
// Support: IE <9 only
|
|
// Defend against cloned attroperties (jQuery gh-1709)
|
|
uniqueCache = outerCache[ node.uniqueID ] ||
|
|
( outerCache[ node.uniqueID ] = {} );
|
|
|
|
cache = uniqueCache[ type ] || [];
|
|
nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
|
|
diff = nodeIndex;
|
|
}
|
|
|
|
// xml :nth-child(...)
|
|
// or :nth-last-child(...) or :nth(-last)?-of-type(...)
|
|
if ( diff === false ) {
|
|
|
|
// Use the same loop as above to seek `elem` from the start
|
|
while ( ( node = ++nodeIndex && node && node[ dir ] ||
|
|
( diff = nodeIndex = 0 ) || start.pop() ) ) {
|
|
|
|
if ( ( ofType ?
|
|
node.nodeName.toLowerCase() === name :
|
|
node.nodeType === 1 ) &&
|
|
++diff ) {
|
|
|
|
// Cache the index of each encountered element
|
|
if ( useCache ) {
|
|
outerCache = node[ expando ] ||
|
|
( node[ expando ] = {} );
|
|
|
|
// Support: IE <9 only
|
|
// Defend against cloned attroperties (jQuery gh-1709)
|
|
uniqueCache = outerCache[ node.uniqueID ] ||
|
|
( outerCache[ node.uniqueID ] = {} );
|
|
|
|
uniqueCache[ type ] = [ dirruns, diff ];
|
|
}
|
|
|
|
if ( node === elem ) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Incorporate the offset, then check against cycle size
|
|
diff -= last;
|
|
return diff === first || ( diff % first === 0 && diff / first >= 0 );
|
|
}
|
|
};
|
|
},
|
|
|
|
"PSEUDO": function( pseudo, argument ) {
|
|
|
|
// pseudo-class names are case-insensitive
|
|
// http://www.w3.org/TR/selectors/#pseudo-classes
|
|
// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
|
|
// Remember that setFilters inherits from pseudos
|
|
var args,
|
|
fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
|
|
Sizzle.error( "unsupported pseudo: " + pseudo );
|
|
|
|
// The user may use createPseudo to indicate that
|
|
// arguments are needed to create the filter function
|
|
// just as Sizzle does
|
|
if ( fn[ expando ] ) {
|
|
return fn( argument );
|
|
}
|
|
|
|
// But maintain support for old signatures
|
|
if ( fn.length > 1 ) {
|
|
args = [ pseudo, pseudo, "", argument ];
|
|
return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
|
|
markFunction( function( seed, matches ) {
|
|
var idx,
|
|
matched = fn( seed, argument ),
|
|
i = matched.length;
|
|
while ( i-- ) {
|
|
idx = indexOf( seed, matched[ i ] );
|
|
seed[ idx ] = !( matches[ idx ] = matched[ i ] );
|
|
}
|
|
} ) :
|
|
function( elem ) {
|
|
return fn( elem, 0, args );
|
|
};
|
|
}
|
|
|
|
return fn;
|
|
}
|
|
},
|
|
|
|
pseudos: {
|
|
|
|
// Potentially complex pseudos
|
|
"not": markFunction( function( selector ) {
|
|
|
|
// Trim the selector passed to compile
|
|
// to avoid treating leading and trailing
|
|
// spaces as combinators
|
|
var input = [],
|
|
results = [],
|
|
matcher = compile( selector.replace( rtrim, "$1" ) );
|
|
|
|
return matcher[ expando ] ?
|
|
markFunction( function( seed, matches, _context, xml ) {
|
|
var elem,
|
|
unmatched = matcher( seed, null, xml, [] ),
|
|
i = seed.length;
|
|
|
|
// Match elements unmatched by `matcher`
|
|
while ( i-- ) {
|
|
if ( ( elem = unmatched[ i ] ) ) {
|
|
seed[ i ] = !( matches[ i ] = elem );
|
|
}
|
|
}
|
|
} ) :
|
|
function( elem, _context, xml ) {
|
|
input[ 0 ] = elem;
|
|
matcher( input, null, xml, results );
|
|
|
|
// Don't keep the element (issue #299)
|
|
input[ 0 ] = null;
|
|
return !results.pop();
|
|
};
|
|
} ),
|
|
|
|
"has": markFunction( function( selector ) {
|
|
return function( elem ) {
|
|
return Sizzle( selector, elem ).length > 0;
|
|
};
|
|
} ),
|
|
|
|
"contains": markFunction( function( text ) {
|
|
text = text.replace( runescape, funescape );
|
|
return function( elem ) {
|
|
return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
|
|
};
|
|
} ),
|
|
|
|
// "Whether an element is represented by a :lang() selector
|
|
// is based solely on the element's language value
|
|
// being equal to the identifier C,
|
|
// or beginning with the identifier C immediately followed by "-".
|
|
// The matching of C against the element's language value is performed case-insensitively.
|
|
// The identifier C does not have to be a valid language name."
|
|
// http://www.w3.org/TR/selectors/#lang-pseudo
|
|
"lang": markFunction( function( lang ) {
|
|
|
|
// lang value must be a valid identifier
|
|
if ( !ridentifier.test( lang || "" ) ) {
|
|
Sizzle.error( "unsupported lang: " + lang );
|
|
}
|
|
lang = lang.replace( runescape, funescape ).toLowerCase();
|
|
return function( elem ) {
|
|
var elemLang;
|
|
do {
|
|
if ( ( elemLang = documentIsHTML ?
|
|
elem.lang :
|
|
elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
|
|
|
|
elemLang = elemLang.toLowerCase();
|
|
return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
|
|
}
|
|
} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
|
|
return false;
|
|
};
|
|
} ),
|
|
|
|
// Miscellaneous
|
|
"target": function( elem ) {
|
|
var hash = window.location && window.location.hash;
|
|
return hash && hash.slice( 1 ) === elem.id;
|
|
},
|
|
|
|
"root": function( elem ) {
|
|
return elem === docElem;
|
|
},
|
|
|
|
"focus": function( elem ) {
|
|
return elem === document.activeElement &&
|
|
( !document.hasFocus || document.hasFocus() ) &&
|
|
!!( elem.type || elem.href || ~elem.tabIndex );
|
|
},
|
|
|
|
// Boolean properties
|
|
"enabled": createDisabledPseudo( false ),
|
|
"disabled": createDisabledPseudo( true ),
|
|
|
|
"checked": function( elem ) {
|
|
|
|
// In CSS3, :checked should return both checked and selected elements
|
|
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
|
|
var nodeName = elem.nodeName.toLowerCase();
|
|
return ( nodeName === "input" && !!elem.checked ) ||
|
|
( nodeName === "option" && !!elem.selected );
|
|
},
|
|
|
|
"selected": function( elem ) {
|
|
|
|
// Accessing this property makes selected-by-default
|
|
// options in Safari work properly
|
|
if ( elem.parentNode ) {
|
|
// eslint-disable-next-line no-unused-expressions
|
|
elem.parentNode.selectedIndex;
|
|
}
|
|
|
|
return elem.selected === true;
|
|
},
|
|
|
|
// Contents
|
|
"empty": function( elem ) {
|
|
|
|
// http://www.w3.org/TR/selectors/#empty-pseudo
|
|
// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
|
|
// but not by others (comment: 8; processing instruction: 7; etc.)
|
|
// nodeType < 6 works because attributes (2) do not appear as children
|
|
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
|
|
if ( elem.nodeType < 6 ) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
},
|
|
|
|
"parent": function( elem ) {
|
|
return !Expr.pseudos[ "empty" ]( elem );
|
|
},
|
|
|
|
// Element/input types
|
|
"header": function( elem ) {
|
|
return rheader.test( elem.nodeName );
|
|
},
|
|
|
|
"input": function( elem ) {
|
|
return rinputs.test( elem.nodeName );
|
|
},
|
|
|
|
"button": function( elem ) {
|
|
var name = elem.nodeName.toLowerCase();
|
|
return name === "input" && elem.type === "button" || name === "button";
|
|
},
|
|
|
|
"text": function( elem ) {
|
|
var attr;
|
|
return elem.nodeName.toLowerCase() === "input" &&
|
|
elem.type === "text" &&
|
|
|
|
// Support: IE<8
|
|
// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
|
|
( ( attr = elem.getAttribute( "type" ) ) == null ||
|
|
attr.toLowerCase() === "text" );
|
|
},
|
|
|
|
// Position-in-collection
|
|
"first": createPositionalPseudo( function() {
|
|
return [ 0 ];
|
|
} ),
|
|
|
|
"last": createPositionalPseudo( function( _matchIndexes, length ) {
|
|
return [ length - 1 ];
|
|
} ),
|
|
|
|
"eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
|
|
return [ argument < 0 ? argument + length : argument ];
|
|
} ),
|
|
|
|
"even": createPositionalPseudo( function( matchIndexes, length ) {
|
|
var i = 0;
|
|
for ( ; i < length; i += 2 ) {
|
|
matchIndexes.push( i );
|
|
}
|
|
return matchIndexes;
|
|
} ),
|
|
|
|
"odd": createPositionalPseudo( function( matchIndexes, length ) {
|
|
var i = 1;
|
|
for ( ; i < length; i += 2 ) {
|
|
matchIndexes.push( i );
|
|
}
|
|
return matchIndexes;
|
|
} ),
|
|
|
|
"lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
|
|
var i = argument < 0 ?
|
|
argument + length :
|
|
argument > length ?
|
|
length :
|
|
argument;
|
|
for ( ; --i >= 0; ) {
|
|
matchIndexes.push( i );
|
|
}
|
|
return matchIndexes;
|
|
} ),
|
|
|
|
"gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
|
|
var i = argument < 0 ? argument + length : argument;
|
|
for ( ; ++i < length; ) {
|
|
matchIndexes.push( i );
|
|
}
|
|
return matchIndexes;
|
|
} )
|
|
}
|
|
};
|
|
|
|
Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
|
|
|
|
// Add button/input type pseudos
|
|
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
|
|
Expr.pseudos[ i ] = createInputPseudo( i );
|
|
}
|
|
for ( i in { submit: true, reset: true } ) {
|
|
Expr.pseudos[ i ] = createButtonPseudo( i );
|
|
}
|
|
|
|
// Easy API for creating new setFilters
|
|
function setFilters() {}
|
|
setFilters.prototype = Expr.filters = Expr.pseudos;
|
|
Expr.setFilters = new setFilters();
|
|
|
|
tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
|
|
var matched, match, tokens, type,
|
|
soFar, groups, preFilters,
|
|
cached = tokenCache[ selector + " " ];
|
|
|
|
if ( cached ) {
|
|
return parseOnly ? 0 : cached.slice( 0 );
|
|
}
|
|
|
|
soFar = selector;
|
|
groups = [];
|
|
preFilters = Expr.preFilter;
|
|
|
|
while ( soFar ) {
|
|
|
|
// Comma and first run
|
|
if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
|
|
if ( match ) {
|
|
|
|
// Don't consume trailing commas as valid
|
|
soFar = soFar.slice( match[ 0 ].length ) || soFar;
|
|
}
|
|
groups.push( ( tokens = [] ) );
|
|
}
|
|
|
|
matched = false;
|
|
|
|
// Combinators
|
|
if ( ( match = rcombinators.exec( soFar ) ) ) {
|
|
matched = match.shift();
|
|
tokens.push( {
|
|
value: matched,
|
|
|
|
// Cast descendant combinators to space
|
|
type: match[ 0 ].replace( rtrim, " " )
|
|
} );
|
|
soFar = soFar.slice( matched.length );
|
|
}
|
|
|
|
// Filters
|
|
for ( type in Expr.filter ) {
|
|
if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
|
|
( match = preFilters[ type ]( match ) ) ) ) {
|
|
matched = match.shift();
|
|
tokens.push( {
|
|
value: matched,
|
|
type: type,
|
|
matches: match
|
|
} );
|
|
soFar = soFar.slice( matched.length );
|
|
}
|
|
}
|
|
|
|
if ( !matched ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Return the length of the invalid excess
|
|
// if we're just parsing
|
|
// Otherwise, throw an error or return tokens
|
|
return parseOnly ?
|
|
soFar.length :
|
|
soFar ?
|
|
Sizzle.error( selector ) :
|
|
|
|
// Cache the tokens
|
|
tokenCache( selector, groups ).slice( 0 );
|
|
};
|
|
|
|
function toSelector( tokens ) {
|
|
var i = 0,
|
|
len = tokens.length,
|
|
selector = "";
|
|
for ( ; i < len; i++ ) {
|
|
selector += tokens[ i ].value;
|
|
}
|
|
return selector;
|
|
}
|
|
|
|
function addCombinator( matcher, combinator, base ) {
|
|
var dir = combinator.dir,
|
|
skip = combinator.next,
|
|
key = skip || dir,
|
|
checkNonElements = base && key === "parentNode",
|
|
doneName = done++;
|
|
|
|
return combinator.first ?
|
|
|
|
// Check against closest ancestor/preceding element
|
|
function( elem, context, xml ) {
|
|
while ( ( elem = elem[ dir ] ) ) {
|
|
if ( elem.nodeType === 1 || checkNonElements ) {
|
|
return matcher( elem, context, xml );
|
|
}
|
|
}
|
|
return false;
|
|
} :
|
|
|
|
// Check against all ancestor/preceding elements
|
|
function( elem, context, xml ) {
|
|
var oldCache, uniqueCache, outerCache,
|
|
newCache = [ dirruns, doneName ];
|
|
|
|
// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
|
|
if ( xml ) {
|
|
while ( ( elem = elem[ dir ] ) ) {
|
|
if ( elem.nodeType === 1 || checkNonElements ) {
|
|
if ( matcher( elem, context, xml ) ) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
while ( ( elem = elem[ dir ] ) ) {
|
|
if ( elem.nodeType === 1 || checkNonElements ) {
|
|
outerCache = elem[ expando ] || ( elem[ expando ] = {} );
|
|
|
|
// Support: IE <9 only
|
|
// Defend against cloned attroperties (jQuery gh-1709)
|
|
uniqueCache = outerCache[ elem.uniqueID ] ||
|
|
( outerCache[ elem.uniqueID ] = {} );
|
|
|
|
if ( skip && skip === elem.nodeName.toLowerCase() ) {
|
|
elem = elem[ dir ] || elem;
|
|
} else if ( ( oldCache = uniqueCache[ key ] ) &&
|
|
oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
|
|
|
|
// Assign to newCache so results back-propagate to previous elements
|
|
return ( newCache[ 2 ] = oldCache[ 2 ] );
|
|
} else {
|
|
|
|
// Reuse newcache so results back-propagate to previous elements
|
|
uniqueCache[ key ] = newCache;
|
|
|
|
// A match means we're done; a fail means we have to keep checking
|
|
if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
}
|
|
|
|
function elementMatcher( matchers ) {
|
|
return matchers.length > 1 ?
|
|
function( elem, context, xml ) {
|
|
var i = matchers.length;
|
|
while ( i-- ) {
|
|
if ( !matchers[ i ]( elem, context, xml ) ) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
} :
|
|
matchers[ 0 ];
|
|
}
|
|
|
|
function multipleContexts( selector, contexts, results ) {
|
|
var i = 0,
|
|
len = contexts.length;
|
|
for ( ; i < len; i++ ) {
|
|
Sizzle( selector, contexts[ i ], results );
|
|
}
|
|
return results;
|
|
}
|
|
|
|
function condense( unmatched, map, filter, context, xml ) {
|
|
var elem,
|
|
newUnmatched = [],
|
|
i = 0,
|
|
len = unmatched.length,
|
|
mapped = map != null;
|
|
|
|
for ( ; i < len; i++ ) {
|
|
if ( ( elem = unmatched[ i ] ) ) {
|
|
if ( !filter || filter( elem, context, xml ) ) {
|
|
newUnmatched.push( elem );
|
|
if ( mapped ) {
|
|
map.push( i );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return newUnmatched;
|
|
}
|
|
|
|
function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
|
|
if ( postFilter && !postFilter[ expando ] ) {
|
|
postFilter = setMatcher( postFilter );
|
|
}
|
|
if ( postFinder && !postFinder[ expando ] ) {
|
|
postFinder = setMatcher( postFinder, postSelector );
|
|
}
|
|
return markFunction( function( seed, results, context, xml ) {
|
|
var temp, i, elem,
|
|
preMap = [],
|
|
postMap = [],
|
|
preexisting = results.length,
|
|
|
|
// Get initial elements from seed or context
|
|
elems = seed || multipleContexts(
|
|
selector || "*",
|
|
context.nodeType ? [ context ] : context,
|
|
[]
|
|
),
|
|
|
|
// Prefilter to get matcher input, preserving a map for seed-results synchronization
|
|
matcherIn = preFilter && ( seed || !selector ) ?
|
|
condense( elems, preMap, preFilter, context, xml ) :
|
|
elems,
|
|
|
|
matcherOut = matcher ?
|
|
|
|
// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
|
|
postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
|
|
|
|
// ...intermediate processing is necessary
|
|
[] :
|
|
|
|
// ...otherwise use results directly
|
|
results :
|
|
matcherIn;
|
|
|
|
// Find primary matches
|
|
if ( matcher ) {
|
|
matcher( matcherIn, matcherOut, context, xml );
|
|
}
|
|
|
|
// Apply postFilter
|
|
if ( postFilter ) {
|
|
temp = condense( matcherOut, postMap );
|
|
postFilter( temp, [], context, xml );
|
|
|
|
// Un-match failing elements by moving them back to matcherIn
|
|
i = temp.length;
|
|
while ( i-- ) {
|
|
if ( ( elem = temp[ i ] ) ) {
|
|
matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( seed ) {
|
|
if ( postFinder || preFilter ) {
|
|
if ( postFinder ) {
|
|
|
|
// Get the final matcherOut by condensing this intermediate into postFinder contexts
|
|
temp = [];
|
|
i = matcherOut.length;
|
|
while ( i-- ) {
|
|
if ( ( elem = matcherOut[ i ] ) ) {
|
|
|
|
// Restore matcherIn since elem is not yet a final match
|
|
temp.push( ( matcherIn[ i ] = elem ) );
|
|
}
|
|
}
|
|
postFinder( null, ( matcherOut = [] ), temp, xml );
|
|
}
|
|
|
|
// Move matched elements from seed to results to keep them synchronized
|
|
i = matcherOut.length;
|
|
while ( i-- ) {
|
|
if ( ( elem = matcherOut[ i ] ) &&
|
|
( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {
|
|
|
|
seed[ temp ] = !( results[ temp ] = elem );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add elements to results, through postFinder if defined
|
|
} else {
|
|
matcherOut = condense(
|
|
matcherOut === results ?
|
|
matcherOut.splice( preexisting, matcherOut.length ) :
|
|
matcherOut
|
|
);
|
|
if ( postFinder ) {
|
|
postFinder( null, results, matcherOut, xml );
|
|
} else {
|
|
push.apply( results, matcherOut );
|
|
}
|
|
}
|
|
} );
|
|
}
|
|
|
|
function matcherFromTokens( tokens ) {
|
|
var checkContext, matcher, j,
|
|
len = tokens.length,
|
|
leadingRelative = Expr.relative[ tokens[ 0 ].type ],
|
|
implicitRelative = leadingRelative || Expr.relative[ " " ],
|
|
i = leadingRelative ? 1 : 0,
|
|
|
|
// The foundational matcher ensures that elements are reachable from top-level context(s)
|
|
matchContext = addCombinator( function( elem ) {
|
|
return elem === checkContext;
|
|
}, implicitRelative, true ),
|
|
matchAnyContext = addCombinator( function( elem ) {
|
|
return indexOf( checkContext, elem ) > -1;
|
|
}, implicitRelative, true ),
|
|
matchers = [ function( elem, context, xml ) {
|
|
var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
|
|
( checkContext = context ).nodeType ?
|
|
matchContext( elem, context, xml ) :
|
|
matchAnyContext( elem, context, xml ) );
|
|
|
|
// Avoid hanging onto element (issue #299)
|
|
checkContext = null;
|
|
return ret;
|
|
} ];
|
|
|
|
for ( ; i < len; i++ ) {
|
|
if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
|
|
matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
|
|
} else {
|
|
matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
|
|
|
|
// Return special upon seeing a positional matcher
|
|
if ( matcher[ expando ] ) {
|
|
|
|
// Find the next relative operator (if any) for proper handling
|
|
j = ++i;
|
|
for ( ; j < len; j++ ) {
|
|
if ( Expr.relative[ tokens[ j ].type ] ) {
|
|
break;
|
|
}
|
|
}
|
|
return setMatcher(
|
|
i > 1 && elementMatcher( matchers ),
|
|
i > 1 && toSelector(
|
|
|
|
// If the preceding token was a descendant combinator, insert an implicit any-element `*`
|
|
tokens
|
|
.slice( 0, i - 1 )
|
|
.concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
|
|
).replace( rtrim, "$1" ),
|
|
matcher,
|
|
i < j && matcherFromTokens( tokens.slice( i, j ) ),
|
|
j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
|
|
j < len && toSelector( tokens )
|
|
);
|
|
}
|
|
matchers.push( matcher );
|
|
}
|
|
}
|
|
|
|
return elementMatcher( matchers );
|
|
}
|
|
|
|
function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
|
|
var bySet = setMatchers.length > 0,
|
|
byElement = elementMatchers.length > 0,
|
|
superMatcher = function( seed, context, xml, results, outermost ) {
|
|
var elem, j, matcher,
|
|
matchedCount = 0,
|
|
i = "0",
|
|
unmatched = seed && [],
|
|
setMatched = [],
|
|
contextBackup = outermostContext,
|
|
|
|
// We must always have either seed elements or outermost context
|
|
elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),
|
|
|
|
// Use integer dirruns iff this is the outermost matcher
|
|
dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
|
|
len = elems.length;
|
|
|
|
if ( outermost ) {
|
|
|
|
// Support: IE 11+, Edge 17 - 18+
|
|
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
|
// two documents; shallow comparisons work.
|
|
// eslint-disable-next-line eqeqeq
|
|
outermostContext = context == document || context || outermost;
|
|
}
|
|
|
|
// Add elements passing elementMatchers directly to results
|
|
// Support: IE<9, Safari
|
|
// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
|
|
for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
|
|
if ( byElement && elem ) {
|
|
j = 0;
|
|
|
|
// Support: IE 11+, Edge 17 - 18+
|
|
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
|
|
// two documents; shallow comparisons work.
|
|
// eslint-disable-next-line eqeqeq
|
|
if ( !context && elem.ownerDocument != document ) {
|
|
setDocument( elem );
|
|
xml = !documentIsHTML;
|
|
}
|
|
while ( ( matcher = elementMatchers[ j++ ] ) ) {
|
|
if ( matcher( elem, context || document, xml ) ) {
|
|
results.push( elem );
|
|
break;
|
|
}
|
|
}
|
|
if ( outermost ) {
|
|
dirruns = dirrunsUnique;
|
|
}
|
|
}
|
|
|
|
// Track unmatched elements for set filters
|
|
if ( bySet ) {
|
|
|
|
// They will have gone through all possible matchers
|
|
if ( ( elem = !matcher && elem ) ) {
|
|
matchedCount--;
|
|
}
|
|
|
|
// Lengthen the array for every element, matched or not
|
|
if ( seed ) {
|
|
unmatched.push( elem );
|
|
}
|
|
}
|
|
}
|
|
|
|
// `i` is now the count of elements visited above, and adding it to `matchedCount`
|
|
// makes the latter nonnegative.
|
|
matchedCount += i;
|
|
|
|
// Apply set filters to unmatched elements
|
|
// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
|
|
// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
|
|
// no element matchers and no seed.
|
|
// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
|
|
// case, which will result in a "00" `matchedCount` that differs from `i` but is also
|
|
// numerically zero.
|
|
if ( bySet && i !== matchedCount ) {
|
|
j = 0;
|
|
while ( ( matcher = setMatchers[ j++ ] ) ) {
|
|
matcher( unmatched, setMatched, context, xml );
|
|
}
|
|
|
|
if ( seed ) {
|
|
|
|
// Reintegrate element matches to eliminate the need for sorting
|
|
if ( matchedCount > 0 ) {
|
|
while ( i-- ) {
|
|
if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
|
|
setMatched[ i ] = pop.call( results );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Discard index placeholder values to get only actual matches
|
|
setMatched = condense( setMatched );
|
|
}
|
|
|
|
// Add matches to results
|
|
push.apply( results, setMatched );
|
|
|
|
// Seedless set matches succeeding multiple successful matchers stipulate sorting
|
|
if ( outermost && !seed && setMatched.length > 0 &&
|
|
( matchedCount + setMatchers.length ) > 1 ) {
|
|
|
|
Sizzle.uniqueSort( results );
|
|
}
|
|
}
|
|
|
|
// Override manipulation of globals by nested matchers
|
|
if ( outermost ) {
|
|
dirruns = dirrunsUnique;
|
|
outermostContext = contextBackup;
|
|
}
|
|
|
|
return unmatched;
|
|
};
|
|
|
|
return bySet ?
|
|
markFunction( superMatcher ) :
|
|
superMatcher;
|
|
}
|
|
|
|
compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
|
|
var i,
|
|
setMatchers = [],
|
|
elementMatchers = [],
|
|
cached = compilerCache[ selector + " " ];
|
|
|
|
if ( !cached ) {
|
|
|
|
// Generate a function of recursive functions that can be used to check each element
|
|
if ( !match ) {
|
|
match = tokenize( selector );
|
|
}
|
|
i = match.length;
|
|
while ( i-- ) {
|
|
cached = matcherFromTokens( match[ i ] );
|
|
if ( cached[ expando ] ) {
|
|
setMatchers.push( cached );
|
|
} else {
|
|
elementMatchers.push( cached );
|
|
}
|
|
}
|
|
|
|
// Cache the compiled function
|
|
cached = compilerCache(
|
|
selector,
|
|
matcherFromGroupMatchers( elementMatchers, setMatchers )
|
|
);
|
|
|
|
// Save selector and tokenization
|
|
cached.selector = selector;
|
|
}
|
|
return cached;
|
|
};
|
|
|
|
/**
|
|
* A low-level selection function that works with Sizzle's compiled
|
|
* selector functions
|
|
* @param {String|Function} selector A selector or a pre-compiled
|
|
* selector function built with Sizzle.compile
|
|
* @param {Element} context
|
|
* @param {Array} [results]
|
|
* @param {Array} [seed] A set of elements to match against
|
|
*/
|
|
select = Sizzle.select = function( selector, context, results, seed ) {
|
|
var i, tokens, token, type, find,
|
|
compiled = typeof selector === "function" && selector,
|
|
match = !seed && tokenize( ( selector = compiled.selector || selector ) );
|
|
|
|
results = results || [];
|
|
|
|
// Try to minimize operations if there is only one selector in the list and no seed
|
|
// (the latter of which guarantees us context)
|
|
if ( match.length === 1 ) {
|
|
|
|
// Reduce context if the leading compound selector is an ID
|
|
tokens = match[ 0 ] = match[ 0 ].slice( 0 );
|
|
if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
|
|
context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
|
|
|
|
context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
|
|
.replace( runescape, funescape ), context ) || [] )[ 0 ];
|
|
if ( !context ) {
|
|
return results;
|
|
|
|
// Precompiled matchers will still verify ancestry, so step up a level
|
|
} else if ( compiled ) {
|
|
context = context.parentNode;
|
|
}
|
|
|
|
selector = selector.slice( tokens.shift().value.length );
|
|
}
|
|
|
|
// Fetch a seed set for right-to-left matching
|
|
i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
|
|
while ( i-- ) {
|
|
token = tokens[ i ];
|
|
|
|
// Abort if we hit a combinator
|
|
if ( Expr.relative[ ( type = token.type ) ] ) {
|
|
break;
|
|
}
|
|
if ( ( find = Expr.find[ type ] ) ) {
|
|
|
|
// Search, expanding context for leading sibling combinators
|
|
if ( ( seed = find(
|
|
token.matches[ 0 ].replace( runescape, funescape ),
|
|
rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
|
|
context
|
|
) ) ) {
|
|
|
|
// If seed is empty or no tokens remain, we can return early
|
|
tokens.splice( i, 1 );
|
|
selector = seed.length && toSelector( tokens );
|
|
if ( !selector ) {
|
|
push.apply( results, seed );
|
|
return results;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Compile and execute a filtering function if one is not provided
|
|
// Provide `match` to avoid retokenization if we modified the selector above
|
|
( compiled || compile( selector, match ) )(
|
|
seed,
|
|
context,
|
|
!documentIsHTML,
|
|
results,
|
|
!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
|
|
);
|
|
return results;
|
|
};
|
|
|
|
// One-time assignments
|
|
|
|
// Sort stability
|
|
support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
|
|
|
|
// Support: Chrome 14-35+
|
|
// Always assume duplicates if they aren't passed to the comparison function
|
|
support.detectDuplicates = !!hasDuplicate;
|
|
|
|
// Initialize against the default document
|
|
setDocument();
|
|
|
|
// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
|
|
// Detached nodes confoundingly follow *each other*
|
|
support.sortDetached = assert( function( el ) {
|
|
|
|
// Should return 1, but returns 4 (following)
|
|
return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
|
|
} );
|
|
|
|
// Support: IE<8
|
|
// Prevent attribute/property "interpolation"
|
|
// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
|
|
if ( !assert( function( el ) {
|
|
el.innerHTML = "<a href='#'></a>";
|
|
return el.firstChild.getAttribute( "href" ) === "#";
|
|
} ) ) {
|
|
addHandle( "type|href|height|width", function( elem, name, isXML ) {
|
|
if ( !isXML ) {
|
|
return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
|
|
}
|
|
} );
|
|
}
|
|
|
|
// Support: IE<9
|
|
// Use defaultValue in place of getAttribute("value")
|
|
if ( !support.attributes || !assert( function( el ) {
|
|
el.innerHTML = "<input/>";
|
|
el.firstChild.setAttribute( "value", "" );
|
|
return el.firstChild.getAttribute( "value" ) === "";
|
|
} ) ) {
|
|
addHandle( "value", function( elem, _name, isXML ) {
|
|
if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
|
|
return elem.defaultValue;
|
|
}
|
|
} );
|
|
}
|
|
|
|
// Support: IE<9
|
|
// Use getAttributeNode to fetch booleans when getAttribute lies
|
|
if ( !assert( function( el ) {
|
|
return el.getAttribute( "disabled" ) == null;
|
|
} ) ) {
|
|
addHandle( booleans, function( elem, name, isXML ) {
|
|
var val;
|
|
if ( !isXML ) {
|
|
return elem[ name ] === true ? name.toLowerCase() :
|
|
( val = elem.getAttributeNode( name ) ) && val.specified ?
|
|
val.value :
|
|
null;
|
|
}
|
|
} );
|
|
}
|
|
|
|
return Sizzle;
|
|
|
|
} )( window );
|
|
|
|
|
|
|
|
jQuery.find = Sizzle;
|
|
jQuery.expr = Sizzle.selectors;
|
|
|
|
// Deprecated
|
|
jQuery.expr[ ":" ] = jQuery.expr.pseudos;
|
|
jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
|
|
jQuery.text = Sizzle.getText;
|
|
jQuery.isXMLDoc = Sizzle.isXML;
|
|
jQuery.contains = Sizzle.contains;
|
|
jQuery.escapeSelector = Sizzle.escape;
|
|
|
|
|
|
|
|
|
|
var dir = function( elem, dir, until ) {
|
|
var matched = [],
|
|
truncate = until !== undefined;
|
|
|
|
while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
|
|
if ( elem.nodeType === 1 ) {
|
|
if ( truncate && jQuery( elem ).is( until ) ) {
|
|
break;
|
|
}
|
|
matched.push( elem );
|
|
}
|
|
}
|
|
return matched;
|
|
};
|
|
|
|
|
|
var siblings = function( n, elem ) {
|
|
var matched = [];
|
|
|
|
for ( ; n; n = n.nextSibling ) {
|
|
if ( n.nodeType === 1 && n !== elem ) {
|
|
matched.push( n );
|
|
}
|
|
}
|
|
|
|
return matched;
|
|
};
|
|
|
|
|
|
var rneedsContext = jQuery.expr.match.needsContext;
|
|
|
|
|
|
|
|
function nodeName( elem, name ) {
|
|
|
|
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
|
|
|
|
}
|
|
var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
|
|
|
|
|
|
|
|
// Implement the identical functionality for filter and not
|
|
function winnow( elements, qualifier, not ) {
|
|
if ( isFunction( qualifier ) ) {
|
|
return jQuery.grep( elements, function( elem, i ) {
|
|
return !!qualifier.call( elem, i, elem ) !== not;
|
|
} );
|
|
}
|
|
|
|
// Single element
|
|
if ( qualifier.nodeType ) {
|
|
return jQuery.grep( elements, function( elem ) {
|
|
return ( elem === qualifier ) !== not;
|
|
} );
|
|
}
|
|
|
|
// Arraylike of elements (jQuery, arguments, Array)
|
|
if ( typeof qualifier !== "string" ) {
|
|
return jQuery.grep( elements, function( elem ) {
|
|
return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
|
|
} );
|
|
}
|
|
|
|
// Filtered directly for both simple and complex selectors
|
|
return jQuery.filter( qualifier, elements, not );
|
|
}
|
|
|
|
jQuery.filter = function( expr, elems, not ) {
|
|
var elem = elems[ 0 ];
|
|
|
|
if ( not ) {
|
|
expr = ":not(" + expr + ")";
|
|
}
|
|
|
|
if ( elems.length === 1 && elem.nodeType === 1 ) {
|
|
return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
|
|
}
|
|
|
|
return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
|
|
return elem.nodeType === 1;
|
|
} ) );
|
|
};
|
|
|
|
jQuery.fn.extend( {
|
|
find: function( selector ) {
|
|
var i, ret,
|
|
len = this.length,
|
|
self = this;
|
|
|
|
if ( typeof selector !== "string" ) {
|
|
return this.pushStack( jQuery( selector ).filter( function() {
|
|
for ( i = 0; i < len; i++ ) {
|
|
if ( jQuery.contains( self[ i ], this ) ) {
|
|
return true;
|
|
}
|
|
}
|
|
} ) );
|
|
}
|
|
|
|
ret = this.pushStack( [] );
|
|
|
|
for ( i = 0; i < len; i++ ) {
|
|
jQuery.find( selector, self[ i ], ret );
|
|
}
|
|
|
|
return len > 1 ? jQuery.uniqueSort( ret ) : ret;
|
|
},
|
|
filter: function( selector ) {
|
|
return this.pushStack( winnow( this, selector || [], false ) );
|
|
},
|
|
not: function( selector ) {
|
|
return this.pushStack( winnow( this, selector || [], true ) );
|
|
},
|
|
is: function( selector ) {
|
|
return !!winnow(
|
|
this,
|
|
|
|
// If this is a positional/relative selector, check membership in the returned set
|
|
// so $("p:first").is("p:last") won't return true for a doc with two "p".
|
|
typeof selector === "string" && rneedsContext.test( selector ) ?
|
|
jQuery( selector ) :
|
|
selector || [],
|
|
false
|
|
).length;
|
|
}
|
|
} );
|
|
|
|
|
|
// Initialize a jQuery object
|
|
|
|
|
|
// A central reference to the root jQuery(document)
|
|
var rootjQuery,
|
|
|
|
// A simple way to check for HTML strings
|
|
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
|
|
// Strict HTML recognition (#11290: must start with <)
|
|
// Shortcut simple #id case for speed
|
|
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
|
|
|
|
init = jQuery.fn.init = function( selector, context, root ) {
|
|
var match, elem;
|
|
|
|
// HANDLE: $(""), $(null), $(undefined), $(false)
|
|
if ( !selector ) {
|
|
return this;
|
|
}
|
|
|
|
// Method init() accepts an alternate rootjQuery
|
|
// so migrate can support jQuery.sub (gh-2101)
|
|
root = root || rootjQuery;
|
|
|
|
// Handle HTML strings
|
|
if ( typeof selector === "string" ) {
|
|
if ( selector[ 0 ] === "<" &&
|
|
selector[ selector.length - 1 ] === ">" &&
|
|
selector.length >= 3 ) {
|
|
|
|
// Assume that strings that start and end with <> are HTML and skip the regex check
|
|
match = [ null, selector, null ];
|
|
|
|
} else {
|
|
match = rquickExpr.exec( selector );
|
|
}
|
|
|
|
// Match html or make sure no context is specified for #id
|
|
if ( match && ( match[ 1 ] || !context ) ) {
|
|
|
|
// HANDLE: $(html) -> $(array)
|
|
if ( match[ 1 ] ) {
|
|
context = context instanceof jQuery ? context[ 0 ] : context;
|
|
|
|
// Option to run scripts is true for back-compat
|
|
// Intentionally let the error be thrown if parseHTML is not present
|
|
jQuery.merge( this, jQuery.parseHTML(
|
|
match[ 1 ],
|
|
context && context.nodeType ? context.ownerDocument || context : document,
|
|
true
|
|
) );
|
|
|
|
// HANDLE: $(html, props)
|
|
if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
|
|
for ( match in context ) {
|
|
|
|
// Properties of context are called as methods if possible
|
|
if ( isFunction( this[ match ] ) ) {
|
|
this[ match ]( context[ match ] );
|
|
|
|
// ...and otherwise set as attributes
|
|
} else {
|
|
this.attr( match, context[ match ] );
|
|
}
|
|
}
|
|
}
|
|
|
|
return this;
|
|
|
|
// HANDLE: $(#id)
|
|
} else {
|
|
elem = document.getElementById( match[ 2 ] );
|
|
|
|
if ( elem ) {
|
|
|
|
// Inject the element directly into the jQuery object
|
|
this[ 0 ] = elem;
|
|
this.length = 1;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// HANDLE: $(expr, $(...))
|
|
} else if ( !context || context.jquery ) {
|
|
return ( context || root ).find( selector );
|
|
|
|
// HANDLE: $(expr, context)
|
|
// (which is just equivalent to: $(context).find(expr)
|
|
} else {
|
|
return this.constructor( context ).find( selector );
|
|
}
|
|
|
|
// HANDLE: $(DOMElement)
|
|
} else if ( selector.nodeType ) {
|
|
this[ 0 ] = selector;
|
|
this.length = 1;
|
|
return this;
|
|
|
|
// HANDLE: $(function)
|
|
// Shortcut for document ready
|
|
} else if ( isFunction( selector ) ) {
|
|
return root.ready !== undefined ?
|
|
root.ready( selector ) :
|
|
|
|
// Execute immediately if ready is not present
|
|
selector( jQuery );
|
|
}
|
|
|
|
return jQuery.makeArray( selector, this );
|
|
};
|
|
|
|
// Give the init function the jQuery prototype for later instantiation
|
|
init.prototype = jQuery.fn;
|
|
|
|
// Initialize central reference
|
|
rootjQuery = jQuery( document );
|
|
|
|
|
|
var rparentsprev = /^(?:parents|prev(?:Until|All))/,
|
|
|
|
// Methods guaranteed to produce a unique set when starting from a unique set
|
|
guaranteedUnique = {
|
|
children: true,
|
|
contents: true,
|
|
next: true,
|
|
prev: true
|
|
};
|
|
|
|
jQuery.fn.extend( {
|
|
has: function( target ) {
|
|
var targets = jQuery( target, this ),
|
|
l = targets.length;
|
|
|
|
return this.filter( function() {
|
|
var i = 0;
|
|
for ( ; i < l; i++ ) {
|
|
if ( jQuery.contains( this, targets[ i ] ) ) {
|
|
return true;
|
|
}
|
|
}
|
|
} );
|
|
},
|
|
|
|
closest: function( selectors, context ) {
|
|
var cur,
|
|
i = 0,
|
|
l = this.length,
|
|
matched = [],
|
|
targets = typeof selectors !== "string" && jQuery( selectors );
|
|
|
|
// Positional selectors never match, since there's no _selection_ context
|
|
if ( !rneedsContext.test( selectors ) ) {
|
|
for ( ; i < l; i++ ) {
|
|
for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
|
|
|
|
// Always skip document fragments
|
|
if ( cur.nodeType < 11 && ( targets ?
|
|
targets.index( cur ) > -1 :
|
|
|
|
// Don't pass non-elements to Sizzle
|
|
cur.nodeType === 1 &&
|
|
jQuery.find.matchesSelector( cur, selectors ) ) ) {
|
|
|
|
matched.push( cur );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
|
|
},
|
|
|
|
// Determine the position of an element within the set
|
|
index: function( elem ) {
|
|
|
|
// No argument, return index in parent
|
|
if ( !elem ) {
|
|
return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
|
|
}
|
|
|
|
// Index in selector
|
|
if ( typeof elem === "string" ) {
|
|
return indexOf.call( jQuery( elem ), this[ 0 ] );
|
|
}
|
|
|
|
// Locate the position of the desired element
|
|
return indexOf.call( this,
|
|
|
|
// If it receives a jQuery object, the first element is used
|
|
elem.jquery ? elem[ 0 ] : elem
|
|
);
|
|
},
|
|
|
|
add: function( selector, context ) {
|
|
return this.pushStack(
|
|
jQuery.uniqueSort(
|
|
jQuery.merge( this.get(), jQuery( selector, context ) )
|
|
)
|
|
);
|
|
},
|
|
|
|
addBack: function( selector ) {
|
|
return this.add( selector == null ?
|
|
this.prevObject : this.prevObject.filter( selector )
|
|
);
|
|
}
|
|
} );
|
|
|
|
function sibling( cur, dir ) {
|
|
while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
|
|
return cur;
|
|
}
|
|
|
|
jQuery.each( {
|
|
parent: function( elem ) {
|
|
var parent = elem.parentNode;
|
|
return parent && parent.nodeType !== 11 ? parent : null;
|
|
},
|
|
parents: function( elem ) {
|
|
return dir( elem, "parentNode" );
|
|
},
|
|
parentsUntil: function( elem, _i, until ) {
|
|
return dir( elem, "parentNode", until );
|
|
},
|
|
next: function( elem ) {
|
|
return sibling( elem, "nextSibling" );
|
|
},
|
|
prev: function( elem ) {
|
|
return sibling( elem, "previousSibling" );
|
|
},
|
|
nextAll: function( elem ) {
|
|
return dir( elem, "nextSibling" );
|
|
},
|
|
prevAll: function( elem ) {
|
|
return dir( elem, "previousSibling" );
|
|
},
|
|
nextUntil: function( elem, _i, until ) {
|
|
return dir( elem, "nextSibling", until );
|
|
},
|
|
prevUntil: function( elem, _i, until ) {
|
|
return dir( elem, "previousSibling", until );
|
|
},
|
|
siblings: function( elem ) {
|
|
return siblings( ( elem.parentNode || {} ).firstChild, elem );
|
|
},
|
|
children: function( elem ) {
|
|
return siblings( elem.firstChild );
|
|
},
|
|
contents: function( elem ) {
|
|
if ( elem.contentDocument != null &&
|
|
|
|
// Support: IE 11+
|
|
// <object> elements with no `data` attribute has an object
|
|
// `contentDocument` with a `null` prototype.
|
|
getProto( elem.contentDocument ) ) {
|
|
|
|
return elem.contentDocument;
|
|
}
|
|
|
|
// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
|
|
// Treat the template element as a regular one in browsers that
|
|
// don't support it.
|
|
if ( nodeName( elem, "template" ) ) {
|
|
elem = elem.content || elem;
|
|
}
|
|
|
|
return jQuery.merge( [], elem.childNodes );
|
|
}
|
|
}, function( name, fn ) {
|
|
jQuery.fn[ name ] = function( until, selector ) {
|
|
var matched = jQuery.map( this, fn, until );
|
|
|
|
if ( name.slice( -5 ) !== "Until" ) {
|
|
selector = until;
|
|
}
|
|
|
|
if ( selector && typeof selector === "string" ) {
|
|
matched = jQuery.filter( selector, matched );
|
|
}
|
|
|
|
if ( this.length > 1 ) {
|
|
|
|
// Remove duplicates
|
|
if ( !guaranteedUnique[ name ] ) {
|
|
jQuery.uniqueSort( matched );
|
|
}
|
|
|
|
// Reverse order for parents* and prev-derivatives
|
|
if ( rparentsprev.test( name ) ) {
|
|
matched.reverse();
|
|
}
|
|
}
|
|
|
|
return this.pushStack( matched );
|
|
};
|
|
} );
|
|
var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
|
|
|
|
|
|
|
|
// Convert String-formatted options into Object-formatted ones
|
|
function createOptions( options ) {
|
|
var object = {};
|
|
jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
|
|
object[ flag ] = true;
|
|
} );
|
|
return object;
|
|
}
|
|
|
|
/*
|
|
* Create a callback list using the following parameters:
|
|
*
|
|
* options: an optional list of space-separated options that will change how
|
|
* the callback list behaves or a more traditional option object
|
|
*
|
|
* By default a callback list will act like an event callback list and can be
|
|
* "fired" multiple times.
|
|
*
|
|
* Possible options:
|
|
*
|
|
* once: will ensure the callback list can only be fired once (like a Deferred)
|
|
*
|
|
* memory: will keep track of previous values and will call any callback added
|
|
* after the list has been fired right away with the latest "memorized"
|
|
* values (like a Deferred)
|
|
*
|
|
* unique: will ensure a callback can only be added once (no duplicate in the list)
|
|
*
|
|
* stopOnFalse: interrupt callings when a callback returns false
|
|
*
|
|
*/
|
|
jQuery.Callbacks = function( options ) {
|
|
|
|
// Convert options from String-formatted to Object-formatted if needed
|
|
// (we check in cache first)
|
|
options = typeof options === "string" ?
|
|
createOptions( options ) :
|
|
jQuery.extend( {}, options );
|
|
|
|
var // Flag to know if list is currently firing
|
|
firing,
|
|
|
|
// Last fire value for non-forgettable lists
|
|
memory,
|
|
|
|
// Flag to know if list was already fired
|
|
fired,
|
|
|
|
// Flag to prevent firing
|
|
locked,
|
|
|
|
// Actual callback list
|
|
list = [],
|
|
|
|
// Queue of execution data for repeatable lists
|
|
queue = [],
|
|
|
|
// Index of currently firing callback (modified by add/remove as needed)
|
|
firingIndex = -1,
|
|
|
|
// Fire callbacks
|
|
fire = function() {
|
|
|
|
// Enforce single-firing
|
|
locked = locked || options.once;
|
|
|
|
// Execute callbacks for all pending executions,
|
|
// respecting firingIndex overrides and runtime changes
|
|
fired = firing = true;
|
|
for ( ; queue.length; firingIndex = -1 ) {
|
|
memory = queue.shift();
|
|
while ( ++firingIndex < list.length ) {
|
|
|
|
// Run callback and check for early termination
|
|
if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
|
|
options.stopOnFalse ) {
|
|
|
|
// Jump to end and forget the data so .add doesn't re-fire
|
|
firingIndex = list.length;
|
|
memory = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Forget the data if we're done with it
|
|
if ( !options.memory ) {
|
|
memory = false;
|
|
}
|
|
|
|
firing = false;
|
|
|
|
// Clean up if we're done firing for good
|
|
if ( locked ) {
|
|
|
|
// Keep an empty list if we have data for future add calls
|
|
if ( memory ) {
|
|
list = [];
|
|
|
|
// Otherwise, this object is spent
|
|
} else {
|
|
list = "";
|
|
}
|
|
}
|
|
},
|
|
|
|
// Actual Callbacks object
|
|
self = {
|
|
|
|
// Add a callback or a collection of callbacks to the list
|
|
add: function() {
|
|
if ( list ) {
|
|
|
|
// If we have memory from a past run, we should fire after adding
|
|
if ( memory && !firing ) {
|
|
firingIndex = list.length - 1;
|
|
queue.push( memory );
|
|
}
|
|
|
|
( function add( args ) {
|
|
jQuery.each( args, function( _, arg ) {
|
|
if ( isFunction( arg ) ) {
|
|
if ( !options.unique || !self.has( arg ) ) {
|
|
list.push( arg );
|
|
}
|
|
} else if ( arg && arg.length && toType( arg ) !== "string" ) {
|
|
|
|
// Inspect recursively
|
|
add( arg );
|
|
}
|
|
} );
|
|
} )( arguments );
|
|
|
|
if ( memory && !firing ) {
|
|
fire();
|
|
}
|
|
}
|
|
return this;
|
|
},
|
|
|
|
// Remove a callback from the list
|
|
remove: function() {
|
|
jQuery.each( arguments, function( _, arg ) {
|
|
var index;
|
|
while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
|
|
list.splice( index, 1 );
|
|
|
|
// Handle firing indexes
|
|
if ( index <= firingIndex ) {
|
|
firingIndex--;
|
|
}
|
|
}
|
|
} );
|
|
return this;
|
|
},
|
|
|
|
// Check if a given callback is in the list.
|
|
// If no argument is given, return whether or not list has callbacks attached.
|
|
has: function( fn ) {
|
|
return fn ?
|
|
jQuery.inArray( fn, list ) > -1 :
|
|
list.length > 0;
|
|
},
|
|
|
|
// Remove all callbacks from the list
|
|
empty: function() {
|
|
if ( list ) {
|
|
list = [];
|
|
}
|
|
return this;
|
|
},
|
|
|
|
// Disable .fire and .add
|
|
// Abort any current/pending executions
|
|
// Clear all callbacks and values
|
|
disable: function() {
|
|
locked = queue = [];
|
|
list = memory = "";
|
|
return this;
|
|
},
|
|
disabled: function() {
|
|
return !list;
|
|
},
|
|
|
|
// Disable .fire
|
|
// Also disable .add unless we have memory (since it would have no effect)
|
|
// Abort any pending executions
|
|
lock: function() {
|
|
locked = queue = [];
|
|
if ( !memory && !firing ) {
|
|
list = memory = "";
|
|
}
|
|
return this;
|
|
},
|
|
locked: function() {
|
|
return !!locked;
|
|
},
|
|
|
|
// Call all callbacks with the given context and arguments
|
|
fireWith: function( context, args ) {
|
|
if ( !locked ) {
|
|
args = args || [];
|
|
args = [ context, args.slice ? args.slice() : args ];
|
|
queue.push( args );
|
|
if ( !firing ) {
|
|
fire();
|
|
}
|
|
}
|
|
return this;
|
|
},
|
|
|
|
// Call all the callbacks with the given arguments
|
|
fire: function() {
|
|
self.fireWith( this, arguments );
|
|
return this;
|
|
},
|
|
|
|
// To know if the callbacks have already been called at least once
|
|
fired: function() {
|
|
return !!fired;
|
|
}
|
|
};
|
|
|
|
return self;
|
|
};
|
|
|
|
|
|
function Identity( v ) {
|
|
return v;
|
|
}
|
|
function Thrower( ex ) {
|
|
throw ex;
|
|
}
|
|
|
|
function adoptValue( value, resolve, reject, noValue ) {
|
|
var method;
|
|
|
|
try {
|
|
|
|
// Check for promise aspect first to privilege synchronous behavior
|
|
if ( value && isFunction( ( method = value.promise ) ) ) {
|
|
method.call( value ).done( resolve ).fail( reject );
|
|
|
|
// Other thenables
|
|
} else if ( value && isFunction( ( method = value.then ) ) ) {
|
|
method.call( value, resolve, reject );
|
|
|
|
// Other non-thenables
|
|
} else {
|
|
|
|
// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
|
|
// * false: [ value ].slice( 0 ) => resolve( value )
|
|
// * true: [ value ].slice( 1 ) => resolve()
|
|
resolve.apply( undefined, [ value ].slice( noValue ) );
|
|
}
|
|
|
|
// For Promises/A+, convert exceptions into rejections
|
|
// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
|
|
// Deferred#then to conditionally suppress rejection.
|
|
} catch ( value ) {
|
|
|
|
// Support: Android 4.0 only
|
|
// Strict mode functions invoked without .call/.apply get global-object context
|
|
reject.apply( undefined, [ value ] );
|
|
}
|
|
}
|
|
|
|
jQuery.extend( {
|
|
|
|
Deferred: function( func ) {
|
|
var tuples = [
|
|
|
|
// action, add listener, callbacks,
|
|
// ... .then handlers, argument index, [final state]
|
|
[ "notify", "progress", jQuery.Callbacks( "memory" ),
|
|
jQuery.Callbacks( "memory" ), 2 ],
|
|
[ "resolve", "done", jQuery.Callbacks( "once memory" ),
|
|
jQuery.Callbacks( "once memory" ), 0, "resolved" ],
|
|
[ "reject", "fail", jQuery.Callbacks( "once memory" ),
|
|
jQuery.Callbacks( "once memory" ), 1, "rejected" ]
|
|
],
|
|
state = "pending",
|
|
promise = {
|
|
state: function() {
|
|
return state;
|
|
},
|
|
always: function() {
|
|
deferred.done( arguments ).fail( arguments );
|
|
return this;
|
|
},
|
|
"catch": function( fn ) {
|
|
return promise.then( null, fn );
|
|
},
|
|
|
|
// Keep pipe for back-compat
|
|
pipe: function( /* fnDone, fnFail, fnProgress */ ) {
|
|
var fns = arguments;
|
|
|
|
return jQuery.Deferred( function( newDefer ) {
|
|
jQuery.each( tuples, function( _i, tuple ) {
|
|
|
|
// Map tuples (progress, done, fail) to arguments (done, fail, progress)
|
|
var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
|
|
|
|
// deferred.progress(function() { bind to newDefer or newDefer.notify })
|
|
// deferred.done(function() { bind to newDefer or newDefer.resolve })
|
|
// deferred.fail(function() { bind to newDefer or newDefer.reject })
|
|
deferred[ tuple[ 1 ] ]( function() {
|
|
var returned = fn && fn.apply( this, arguments );
|
|
if ( returned && isFunction( returned.promise ) ) {
|
|
returned.promise()
|
|
.progress( newDefer.notify )
|
|
.done( newDefer.resolve )
|
|
.fail( newDefer.reject );
|
|
} else {
|
|
newDefer[ tuple[ 0 ] + "With" ](
|
|
this,
|
|
fn ? [ returned ] : arguments
|
|
);
|
|
}
|
|
} );
|
|
} );
|
|
fns = null;
|
|
} ).promise();
|
|
},
|
|
then: function( onFulfilled, onRejected, onProgress ) {
|
|
var maxDepth = 0;
|
|
function resolve( depth, deferred, handler, special ) {
|
|
return function() {
|
|
var that = this,
|
|
args = arguments,
|
|
mightThrow = function() {
|
|
var returned, then;
|
|
|
|
// Support: Promises/A+ section 2.3.3.3.3
|
|
// https://promisesaplus.com/#point-59
|
|
// Ignore double-resolution attempts
|
|
if ( depth < maxDepth ) {
|
|
return;
|
|
}
|
|
|
|
returned = handler.apply( that, args );
|
|
|
|
// Support: Promises/A+ section 2.3.1
|
|
// https://promisesaplus.com/#point-48
|
|
if ( returned === deferred.promise() ) {
|
|
throw new TypeError( "Thenable self-resolution" );
|
|
}
|
|
|
|
// Support: Promises/A+ sections 2.3.3.1, 3.5
|
|
// https://promisesaplus.com/#point-54
|
|
// https://promisesaplus.com/#point-75
|
|
// Retrieve `then` only once
|
|
then = returned &&
|
|
|
|
// Support: Promises/A+ section 2.3.4
|
|
// https://promisesaplus.com/#point-64
|
|
// Only check objects and functions for thenability
|
|
( typeof returned === "object" ||
|
|
typeof returned === "function" ) &&
|
|
returned.then;
|
|
|
|
// Handle a returned thenable
|
|
if ( isFunction( then ) ) {
|
|
|
|
// Special processors (notify) just wait for resolution
|
|
if ( special ) {
|
|
then.call(
|
|
returned,
|
|
resolve( maxDepth, deferred, Identity, special ),
|
|
resolve( maxDepth, deferred, Thrower, special )
|
|
);
|
|
|
|
// Normal processors (resolve) also hook into progress
|
|
} else {
|
|
|
|
// ...and disregard older resolution values
|
|
maxDepth++;
|
|
|
|
then.call(
|
|
returned,
|
|
resolve( maxDepth, deferred, Identity, special ),
|
|
resolve( maxDepth, deferred, Thrower, special ),
|
|
resolve( maxDepth, deferred, Identity,
|
|
deferred.notifyWith )
|
|
);
|
|
}
|
|
|
|
// Handle all other returned values
|
|
} else {
|
|
|
|
// Only substitute handlers pass on context
|
|
// and multiple values (non-spec behavior)
|
|
if ( handler !== Identity ) {
|
|
that = undefined;
|
|
args = [ returned ];
|
|
}
|
|
|
|
// Process the value(s)
|
|
// Default process is resolve
|
|
( special || deferred.resolveWith )( that, args );
|
|
}
|
|
},
|
|
|
|
// Only normal processors (resolve) catch and reject exceptions
|
|
process = special ?
|
|
mightThrow :
|
|
function() {
|
|
try {
|
|
mightThrow();
|
|
} catch ( e ) {
|
|
|
|
if ( jQuery.Deferred.exceptionHook ) {
|
|
jQuery.Deferred.exceptionHook( e,
|
|
process.stackTrace );
|
|
}
|
|
|
|
// Support: Promises/A+ section 2.3.3.3.4.1
|
|
// https://promisesaplus.com/#point-61
|
|
// Ignore post-resolution exceptions
|
|
if ( depth + 1 >= maxDepth ) {
|
|
|
|
// Only substitute handlers pass on context
|
|
// and multiple values (non-spec behavior)
|
|
if ( handler !== Thrower ) {
|
|
that = undefined;
|
|
args = [ e ];
|
|
}
|
|
|
|
deferred.rejectWith( that, args );
|
|
}
|
|
}
|
|
};
|
|
|
|
// Support: Promises/A+ section 2.3.3.3.1
|
|
// https://promisesaplus.com/#point-57
|
|
// Re-resolve promises immediately to dodge false rejection from
|
|
// subsequent errors
|
|
if ( depth ) {
|
|
process();
|
|
} else {
|
|
|
|
// Call an optional hook to record the stack, in case of exception
|
|
// since it's otherwise lost when execution goes async
|
|
if ( jQuery.Deferred.getStackHook ) {
|
|
process.stackTrace = jQuery.Deferred.getStackHook();
|
|
}
|
|
window.setTimeout( process );
|
|
}
|
|
};
|
|
}
|
|
|
|
return jQuery.Deferred( function( newDefer ) {
|
|
|
|
// progress_handlers.add( ... )
|
|
tuples[ 0 ][ 3 ].add(
|
|
resolve(
|
|
0,
|
|
newDefer,
|
|
isFunction( onProgress ) ?
|
|
onProgress :
|
|
Identity,
|
|
newDefer.notifyWith
|
|
)
|
|
);
|
|
|
|
// fulfilled_handlers.add( ... )
|
|
tuples[ 1 ][ 3 ].add(
|
|
resolve(
|
|
0,
|
|
newDefer,
|
|
isFunction( onFulfilled ) ?
|
|
onFulfilled :
|
|
Identity
|
|
)
|
|
);
|
|
|
|
// rejected_handlers.add( ... )
|
|
tuples[ 2 ][ 3 ].add(
|
|
resolve(
|
|
0,
|
|
newDefer,
|
|
isFunction( onRejected ) ?
|
|
onRejected :
|
|
Thrower
|
|
)
|
|
);
|
|
} ).promise();
|
|
},
|
|
|
|
// Get a promise for this deferred
|
|
// If obj is provided, the promise aspect is added to the object
|
|
promise: function( obj ) {
|
|
return obj != null ? jQuery.extend( obj, promise ) : promise;
|
|
}
|
|
},
|
|
deferred = {};
|
|
|
|
// Add list-specific methods
|
|
jQuery.each( tuples, function( i, tuple ) {
|
|
var list = tuple[ 2 ],
|
|
stateString = tuple[ 5 ];
|
|
|
|
// promise.progress = list.add
|
|
// promise.done = list.add
|
|
// promise.fail = list.add
|
|
promise[ tuple[ 1 ] ] = list.add;
|
|
|
|
// Handle state
|
|
if ( stateString ) {
|
|
list.add(
|
|
function() {
|
|
|
|
// state = "resolved" (i.e., fulfilled)
|
|
// state = "rejected"
|
|
state = stateString;
|
|
},
|
|
|
|
// rejected_callbacks.disable
|
|
// fulfilled_callbacks.disable
|
|
tuples[ 3 - i ][ 2 ].disable,
|
|
|
|
// rejected_handlers.disable
|
|
// fulfilled_handlers.disable
|
|
tuples[ 3 - i ][ 3 ].disable,
|
|
|
|
// progress_callbacks.lock
|
|
tuples[ 0 ][ 2 ].lock,
|
|
|
|
// progress_handlers.lock
|
|
tuples[ 0 ][ 3 ].lock
|
|
);
|
|
}
|
|
|
|
// progress_handlers.fire
|
|
// fulfilled_handlers.fire
|
|
// rejected_handlers.fire
|
|
list.add( tuple[ 3 ].fire );
|
|
|
|
// deferred.notify = function() { deferred.notifyWith(...) }
|
|
// deferred.resolve = function() { deferred.resolveWith(...) }
|
|
// deferred.reject = function() { deferred.rejectWith(...) }
|
|
deferred[ tuple[ 0 ] ] = function() {
|
|
deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
|
|
return this;
|
|
};
|
|
|
|
// deferred.notifyWith = list.fireWith
|
|
// deferred.resolveWith = list.fireWith
|
|
// deferred.rejectWith = list.fireWith
|
|
deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
|
|
} );
|
|
|
|
// Make the deferred a promise
|
|
promise.promise( deferred );
|
|
|
|
// Call given func if any
|
|
if ( func ) {
|
|
func.call( deferred, deferred );
|
|
}
|
|
|
|
// All done!
|
|
return deferred;
|
|
},
|
|
|
|
// Deferred helper
|
|
when: function( singleValue ) {
|
|
var
|
|
|
|
// count of uncompleted subordinates
|
|
remaining = arguments.length,
|
|
|
|
// count of unprocessed arguments
|
|
i = remaining,
|
|
|
|
// subordinate fulfillment data
|
|
resolveContexts = Array( i ),
|
|
resolveValues = slice.call( arguments ),
|
|
|
|
// the primary Deferred
|
|
primary = jQuery.Deferred(),
|
|
|
|
// subordinate callback factory
|
|
updateFunc = function( i ) {
|
|
return function( value ) {
|
|
resolveContexts[ i ] = this;
|
|
resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
|
|
if ( !( --remaining ) ) {
|
|
primary.resolveWith( resolveContexts, resolveValues );
|
|
}
|
|
};
|
|
};
|
|
|
|
// Single- and empty arguments are adopted like Promise.resolve
|
|
if ( remaining <= 1 ) {
|
|
adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
|
|
!remaining );
|
|
|
|
// Use .then() to unwrap secondary thenables (cf. gh-3000)
|
|
if ( primary.state() === "pending" ||
|
|
isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
|
|
|
|
return primary.then();
|
|
}
|
|
}
|
|
|
|
// Multiple arguments are aggregated like Promise.all array elements
|
|
while ( i-- ) {
|
|
adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );
|
|
}
|
|
|
|
return primary.promise();
|
|
}
|
|
} );
|
|
|
|
|
|
// These usually indicate a programmer mistake during development,
|
|
// warn about them ASAP rather than swallowing them by default.
|
|
var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
|
|
|
|
jQuery.Deferred.exceptionHook = function( error, stack ) {
|
|
|
|
// Support: IE 8 - 9 only
|
|
// Console exists when dev tools are open, which can happen at any time
|
|
if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
|
|
window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
jQuery.readyException = function( error ) {
|
|
window.setTimeout( function() {
|
|
throw error;
|
|
} );
|
|
};
|
|
|
|
|
|
|
|
|
|
// The deferred used on DOM ready
|
|
var readyList = jQuery.Deferred();
|
|
|
|
jQuery.fn.ready = function( fn ) {
|
|
|
|
readyList
|
|
.then( fn )
|
|
|
|
// Wrap jQuery.readyException in a function so that the lookup
|
|
// happens at the time of error handling instead of callback
|
|
// registration.
|
|
.catch( function( error ) {
|
|
jQuery.readyException( error );
|
|
} );
|
|
|
|
return this;
|
|
};
|
|
|
|
jQuery.extend( {
|
|
|
|
// Is the DOM ready to be used? Set to true once it occurs.
|
|
isReady: false,
|
|
|
|
// A counter to track how many items to wait for before
|
|
// the ready event fires. See #6781
|
|
readyWait: 1,
|
|
|
|
// Handle when the DOM is ready
|
|
ready: function( wait ) {
|
|
|
|
// Abort if there are pending holds or we're already ready
|
|
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
|
|
return;
|
|
}
|
|
|
|
// Remember that the DOM is ready
|
|
jQuery.isReady = true;
|
|
|
|
// If a normal DOM Ready event fired, decrement, and wait if need be
|
|
if ( wait !== true && --jQuery.readyWait > 0 ) {
|
|
return;
|
|
}
|
|
|
|
// If there are functions bound, to execute
|
|
readyList.resolveWith( document, [ jQuery ] );
|
|
}
|
|
} );
|
|
|
|
jQuery.ready.then = readyList.then;
|
|
|
|
// The ready event handler and self cleanup method
|
|
function completed() {
|
|
document.removeEventListener( "DOMContentLoaded", completed );
|
|
window.removeEventListener( "load", completed );
|
|
jQuery.ready();
|
|
}
|
|
|
|
// Catch cases where $(document).ready() is called
|
|
// after the browser event has already occurred.
|
|
// Support: IE <=9 - 10 only
|
|
// Older IE sometimes signals "interactive" too soon
|
|
if ( document.readyState === "complete" ||
|
|
( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
|
|
|
|
// Handle it asynchronously to allow scripts the opportunity to delay ready
|
|
window.setTimeout( jQuery.ready );
|
|
|
|
} else {
|
|
|
|
// Use the handy event callback
|
|
document.addEventListener( "DOMContentLoaded", completed );
|
|
|
|
// A fallback to window.onload, that will always work
|
|
window.addEventListener( "load", completed );
|
|
}
|
|
|
|
|
|
|
|
|
|
// Multifunctional method to get and set values of a collection
|
|
// The value/s can optionally be executed if it's a function
|
|
var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
|
|
var i = 0,
|
|
len = elems.length,
|
|
bulk = key == null;
|
|
|
|
// Sets many values
|
|
if ( toType( key ) === "object" ) {
|
|
chainable = true;
|
|
for ( i in key ) {
|
|
access( elems, fn, i, key[ i ], true, emptyGet, raw );
|
|
}
|
|
|
|
// Sets one value
|
|
} else if ( value !== undefined ) {
|
|
chainable = true;
|
|
|
|
if ( !isFunction( value ) ) {
|
|
raw = true;
|
|
}
|
|
|
|
if ( bulk ) {
|
|
|
|
// Bulk operations run against the entire set
|
|
if ( raw ) {
|
|
fn.call( elems, value );
|
|
fn = null;
|
|
|
|
// ...except when executing function values
|
|
} else {
|
|
bulk = fn;
|
|
fn = function( elem, _key, value ) {
|
|
return bulk.call( jQuery( elem ), value );
|
|
};
|
|
}
|
|
}
|
|
|
|
if ( fn ) {
|
|
for ( ; i < len; i++ ) {
|
|
fn(
|
|
elems[ i ], key, raw ?
|
|
value :
|
|
value.call( elems[ i ], i, fn( elems[ i ], key ) )
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( chainable ) {
|
|
return elems;
|
|
}
|
|
|
|
// Gets
|
|
if ( bulk ) {
|
|
return fn.call( elems );
|
|
}
|
|
|
|
return len ? fn( elems[ 0 ], key ) : emptyGet;
|
|
};
|
|
|
|
|
|
// Matches dashed string for camelizing
|
|
var rmsPrefix = /^-ms-/,
|
|
rdashAlpha = /-([a-z])/g;
|
|
|
|
// Used by camelCase as callback to replace()
|
|
function fcamelCase( _all, letter ) {
|
|
return letter.toUpperCase();
|
|
}
|
|
|
|
// Convert dashed to camelCase; used by the css and data modules
|
|
// Support: IE <=9 - 11, Edge 12 - 15
|
|
// Microsoft forgot to hump their vendor prefix (#9572)
|
|
function camelCase( string ) {
|
|
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
|
|
}
|
|
var acceptData = function( owner ) {
|
|
|
|
// Accepts only:
|
|
// - Node
|
|
// - Node.ELEMENT_NODE
|
|
// - Node.DOCUMENT_NODE
|
|
// - Object
|
|
// - Any
|
|
return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
|
|
};
|
|
|
|
|
|
|
|
|
|
function Data() {
|
|
this.expando = jQuery.expando + Data.uid++;
|
|
}
|
|
|
|
Data.uid = 1;
|
|
|
|
Data.prototype = {
|
|
|
|
cache: function( owner ) {
|
|
|
|
// Check if the owner object already has a cache
|
|
var value = owner[ this.expando ];
|
|
|
|
// If not, create one
|
|
if ( !value ) {
|
|
value = {};
|
|
|
|
// We can accept data for non-element nodes in modern browsers,
|
|
// but we should not, see #8335.
|
|
// Always return an empty object.
|
|
if ( acceptData( owner ) ) {
|
|
|
|
// If it is a node unlikely to be stringify-ed or looped over
|
|
// use plain assignment
|
|
if ( owner.nodeType ) {
|
|
owner[ this.expando ] = value;
|
|
|
|
// Otherwise secure it in a non-enumerable property
|
|
// configurable must be true to allow the property to be
|
|
// deleted when data is removed
|
|
} else {
|
|
Object.defineProperty( owner, this.expando, {
|
|
value: value,
|
|
configurable: true
|
|
} );
|
|
}
|
|
}
|
|
}
|
|
|
|
return value;
|
|
},
|
|
set: function( owner, data, value ) {
|
|
var prop,
|
|
cache = this.cache( owner );
|
|
|
|
// Handle: [ owner, key, value ] args
|
|
// Always use camelCase key (gh-2257)
|
|
if ( typeof data === "string" ) {
|
|
cache[ camelCase( data ) ] = value;
|
|
|
|
// Handle: [ owner, { properties } ] args
|
|
} else {
|
|
|
|
// Copy the properties one-by-one to the cache object
|
|
for ( prop in data ) {
|
|
cache[ camelCase( prop ) ] = data[ prop ];
|
|
}
|
|
}
|
|
return cache;
|
|
},
|
|
get: function( owner, key ) {
|
|
return key === undefined ?
|
|
this.cache( owner ) :
|
|
|
|
// Always use camelCase key (gh-2257)
|
|
owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
|
|
},
|
|
access: function( owner, key, value ) {
|
|
|
|
// In cases where either:
|
|
//
|
|
// 1. No key was specified
|
|
// 2. A string key was specified, but no value provided
|
|
//
|
|
// Take the "read" path and allow the get method to determine
|
|
// which value to return, respectively either:
|
|
//
|
|
// 1. The entire cache object
|
|
// 2. The data stored at the key
|
|
//
|
|
if ( key === undefined ||
|
|
( ( key && typeof key === "string" ) && value === undefined ) ) {
|
|
|
|
return this.get( owner, key );
|
|
}
|
|
|
|
// When the key is not a string, or both a key and value
|
|
// are specified, set or extend (existing objects) with either:
|
|
//
|
|
// 1. An object of properties
|
|
// 2. A key and value
|
|
//
|
|
this.set( owner, key, value );
|
|
|
|
// Since the "set" path can have two possible entry points
|
|
// return the expected data based on which path was taken[*]
|
|
return value !== undefined ? value : key;
|
|
},
|
|
remove: function( owner, key ) {
|
|
var i,
|
|
cache = owner[ this.expando ];
|
|
|
|
if ( cache === undefined ) {
|
|
return;
|
|
}
|
|
|
|
if ( key !== undefined ) {
|
|
|
|
// Support array or space separated string of keys
|
|
if ( Array.isArray( key ) ) {
|
|
|
|
// If key is an array of keys...
|
|
// We always set camelCase keys, so remove that.
|
|
key = key.map( camelCase );
|
|
} else {
|
|
key = camelCase( key );
|
|
|
|
// If a key with the spaces exists, use it.
|
|
// Otherwise, create an array by matching non-whitespace
|
|
key = key in cache ?
|
|
[ key ] :
|
|
( key.match( rnothtmlwhite ) || [] );
|
|
}
|
|
|
|
i = key.length;
|
|
|
|
while ( i-- ) {
|
|
delete cache[ key[ i ] ];
|
|
}
|
|
}
|
|
|
|
// Remove the expando if there's no more data
|
|
if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
|
|
|
|
// Support: Chrome <=35 - 45
|
|
// Webkit & Blink performance suffers when deleting properties
|
|
// from DOM nodes, so set to undefined instead
|
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
|
|
if ( owner.nodeType ) {
|
|
owner[ this.expando ] = undefined;
|
|
} else {
|
|
delete owner[ this.expando ];
|
|
}
|
|
}
|
|
},
|
|
hasData: function( owner ) {
|
|
var cache = owner[ this.expando ];
|
|
return cache !== undefined && !jQuery.isEmptyObject( cache );
|
|
}
|
|
};
|
|
var dataPriv = new Data();
|
|
|
|
var dataUser = new Data();
|
|
|
|
|
|
|
|
// Implementation Summary
|
|
//
|
|
// 1. Enforce API surface and semantic compatibility with 1.9.x branch
|
|
// 2. Improve the module's maintainability by reducing the storage
|
|
// paths to a single mechanism.
|
|
// 3. Use the same single mechanism to support "private" and "user" data.
|
|
// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
|
|
// 5. Avoid exposing implementation details on user objects (eg. expando properties)
|
|
// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
|
|
|
|
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
|
|
rmultiDash = /[A-Z]/g;
|
|
|
|
function getData( data ) {
|
|
if ( data === "true" ) {
|
|
return true;
|
|
}
|
|
|
|
if ( data === "false" ) {
|
|
return false;
|
|
}
|
|
|
|
if ( data === "null" ) {
|
|
return null;
|
|
}
|
|
|
|
// Only convert to a number if it doesn't change the string
|
|
if ( data === +data + "" ) {
|
|
return +data;
|
|
}
|
|
|
|
if ( rbrace.test( data ) ) {
|
|
return JSON.parse( data );
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
function dataAttr( elem, key, data ) {
|
|
var name;
|
|
|
|
// If nothing was found internally, try to fetch any
|
|
// data from the HTML5 data-* attribute
|
|
if ( data === undefined && elem.nodeType === 1 ) {
|
|
name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
|
|
data = elem.getAttribute( name );
|
|
|
|
if ( typeof data === "string" ) {
|
|
try {
|
|
data = getData( data );
|
|
} catch ( e ) {}
|
|
|
|
// Make sure we set the data so it isn't changed later
|
|
dataUser.set( elem, key, data );
|
|
} else {
|
|
data = undefined;
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
|
|
jQuery.extend( {
|
|
hasData: function( elem ) {
|
|
return dataUser.hasData( elem ) || dataPriv.hasData( elem );
|
|
},
|
|
|
|
data: function( elem, name, data ) {
|
|
return dataUser.access( elem, name, data );
|
|
},
|
|
|
|
removeData: function( elem, name ) {
|
|
dataUser.remove( elem, name );
|
|
},
|
|
|
|
// TODO: Now that all calls to _data and _removeData have been replaced
|
|
// with direct calls to dataPriv methods, these can be deprecated.
|
|
_data: function( elem, name, data ) {
|
|
return dataPriv.access( elem, name, data );
|
|
},
|
|
|
|
_removeData: function( elem, name ) {
|
|
dataPriv.remove( elem, name );
|
|
}
|
|
} );
|
|
|
|
jQuery.fn.extend( {
|
|
data: function( key, value ) {
|
|
var i, name, data,
|
|
elem = this[ 0 ],
|
|
attrs = elem && elem.attributes;
|
|
|
|
// Gets all values
|
|
if ( key === undefined ) {
|
|
if ( this.length ) {
|
|
data = dataUser.get( elem );
|
|
|
|
if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
|
|
i = attrs.length;
|
|
while ( i-- ) {
|
|
|
|
// Support: IE 11 only
|
|
// The attrs elements can be null (#14894)
|
|
if ( attrs[ i ] ) {
|
|
name = attrs[ i ].name;
|
|
if ( name.indexOf( "data-" ) === 0 ) {
|
|
name = camelCase( name.slice( 5 ) );
|
|
dataAttr( elem, name, data[ name ] );
|
|
}
|
|
}
|
|
}
|
|
dataPriv.set( elem, "hasDataAttrs", true );
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
// Sets multiple values
|
|
if ( typeof key === "object" ) {
|
|
return this.each( function() {
|
|
dataUser.set( this, key );
|
|
} );
|
|
}
|
|
|
|
return access( this, function( value ) {
|
|
var data;
|
|
|
|
// The calling jQuery object (element matches) is not empty
|
|
// (and therefore has an element appears at this[ 0 ]) and the
|
|
// `value` parameter was not undefined. An empty jQuery object
|
|
// will result in `undefined` for elem = this[ 0 ] which will
|
|
// throw an exception if an attempt to read a data cache is made.
|
|
if ( elem && value === undefined ) {
|
|
|
|
// Attempt to get data from the cache
|
|
// The key will always be camelCased in Data
|
|
data = dataUser.get( elem, key );
|
|
if ( data !== undefined ) {
|
|
return data;
|
|
}
|
|
|
|
// Attempt to "discover" the data in
|
|
// HTML5 custom data-* attrs
|
|
data = dataAttr( elem, key );
|
|
if ( data !== undefined ) {
|
|
return data;
|
|
}
|
|
|
|
// We tried really hard, but the data doesn't exist.
|
|
return;
|
|
}
|
|
|
|
// Set the data...
|
|
this.each( function() {
|
|
|
|
// We always store the camelCased key
|
|
dataUser.set( this, key, value );
|
|
} );
|
|
}, null, value, arguments.length > 1, null, true );
|
|
},
|
|
|
|
removeData: function( key ) {
|
|
return this.each( function() {
|
|
dataUser.remove( this, key );
|
|
} );
|
|
}
|
|
} );
|
|
|
|
|
|
jQuery.extend( {
|
|
queue: function( elem, type, data ) {
|
|
var queue;
|
|
|
|
if ( elem ) {
|
|
type = ( type || "fx" ) + "queue";
|
|
queue = dataPriv.get( elem, type );
|
|
|
|
// Speed up dequeue by getting out quickly if this is just a lookup
|
|
if ( data ) {
|
|
if ( !queue || Array.isArray( data ) ) {
|
|
queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
|
|
} else {
|
|
queue.push( data );
|
|
}
|
|
}
|
|
return queue || [];
|
|
}
|
|
},
|
|
|
|
dequeue: function( elem, type ) {
|
|
type = type || "fx";
|
|
|
|
var queue = jQuery.queue( elem, type ),
|
|
startLength = queue.length,
|
|
fn = queue.shift(),
|
|
hooks = jQuery._queueHooks( elem, type ),
|
|
next = function() {
|
|
jQuery.dequeue( elem, type );
|
|
};
|
|
|
|
// If the fx queue is dequeued, always remove the progress sentinel
|
|
if ( fn === "inprogress" ) {
|
|
fn = queue.shift();
|
|
startLength--;
|
|
}
|
|
|
|
if ( fn ) {
|
|
|
|
// Add a progress sentinel to prevent the fx queue from being
|
|
// automatically dequeued
|
|
if ( type === "fx" ) {
|
|
queue.unshift( "inprogress" );
|
|
}
|
|
|
|
// Clear up the last queue stop function
|
|
delete hooks.stop;
|
|
fn.call( elem, next, hooks );
|
|
}
|
|
|
|
if ( !startLength && hooks ) {
|
|
hooks.empty.fire();
|
|
}
|
|
},
|
|
|
|
// Not public - generate a queueHooks object, or return the current one
|
|
_queueHooks: function( elem, type ) {
|
|
var key = type + "queueHooks";
|
|
return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
|
|
empty: jQuery.Callbacks( "once memory" ).add( function() {
|
|
dataPriv.remove( elem, [ type + "queue", key ] );
|
|
} )
|
|
} );
|
|
}
|
|
} );
|
|
|
|
jQuery.fn.extend( {
|
|
queue: function( type, data ) {
|
|
var setter = 2;
|
|
|
|
if ( typeof type !== "string" ) {
|
|
data = type;
|
|
type = "fx";
|
|
setter--;
|
|
}
|
|
|
|
if ( arguments.length < setter ) {
|
|
return jQuery.queue( this[ 0 ], type );
|
|
}
|
|
|
|
return data === undefined ?
|
|
this :
|
|
this.each( function() {
|
|
var queue = jQuery.queue( this, type, data );
|
|
|
|
// Ensure a hooks for this queue
|
|
jQuery._queueHooks( this, type );
|
|
|
|
if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
|
|
jQuery.dequeue( this, type );
|
|
}
|
|
} );
|
|
},
|
|
dequeue: function( type ) {
|
|
return this.each( function() {
|
|
jQuery.dequeue( this, type );
|
|
} );
|
|
},
|
|
clearQueue: function( type ) {
|
|
return this.queue( type || "fx", [] );
|
|
},
|
|
|
|
// Get a promise resolved when queues of a certain type
|
|
// are emptied (fx is the type by default)
|
|
promise: function( type, obj ) {
|
|
var tmp,
|
|
count = 1,
|
|
defer = jQuery.Deferred(),
|
|
elements = this,
|
|
i = this.length,
|
|
resolve = function() {
|
|
if ( !( --count ) ) {
|
|
defer.resolveWith( elements, [ elements ] );
|
|
}
|
|
};
|
|
|
|
if ( typeof type !== "string" ) {
|
|
obj = type;
|
|
type = undefined;
|
|
}
|
|
type = type || "fx";
|
|
|
|
while ( i-- ) {
|
|
tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
|
|
if ( tmp && tmp.empty ) {
|
|
count++;
|
|
tmp.empty.add( resolve );
|
|
}
|
|
}
|
|
resolve();
|
|
return defer.promise( obj );
|
|
}
|
|
} );
|
|
var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
|
|
|
|
var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
|
|
|
|
|
|
var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
|
|
|
|
var documentElement = document.documentElement;
|
|
|
|
|
|
|
|
var isAttached = function( elem ) {
|
|
return jQuery.contains( elem.ownerDocument, elem );
|
|
},
|
|
composed = { composed: true };
|
|
|
|
// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
|
|
// Check attachment across shadow DOM boundaries when possible (gh-3504)
|
|
// Support: iOS 10.0-10.2 only
|
|
// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
|
|
// leading to errors. We need to check for `getRootNode`.
|
|
if ( documentElement.getRootNode ) {
|
|
isAttached = function( elem ) {
|
|
return jQuery.contains( elem.ownerDocument, elem ) ||
|
|
elem.getRootNode( composed ) === elem.ownerDocument;
|
|
};
|
|
}
|
|
var isHiddenWithinTree = function( elem, el ) {
|
|
|
|
// isHiddenWithinTree might be called from jQuery#filter function;
|
|
// in that case, element will be second argument
|
|
elem = el || elem;
|
|
|
|
// Inline style trumps all
|
|
return elem.style.display === "none" ||
|
|
elem.style.display === "" &&
|
|
|
|
// Otherwise, check computed style
|
|
// Support: Firefox <=43 - 45
|
|
// Disconnected elements can have computed display: none, so first confirm that elem is
|
|
// in the document.
|
|
isAttached( elem ) &&
|
|
|
|
jQuery.css( elem, "display" ) === "none";
|
|
};
|
|
|
|
|
|
|
|
function adjustCSS( elem, prop, valueParts, tween ) {
|
|
var adjusted, scale,
|
|
maxIterations = 20,
|
|
currentValue = tween ?
|
|
function() {
|
|
return tween.cur();
|
|
} :
|
|
function() {
|
|
return jQuery.css( elem, prop, "" );
|
|
},
|
|
initial = currentValue(),
|
|
unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
|
|
|
|
// Starting value computation is required for potential unit mismatches
|
|
initialInUnit = elem.nodeType &&
|
|
( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
|
|
rcssNum.exec( jQuery.css( elem, prop ) );
|
|
|
|
if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
|
|
|
|
// Support: Firefox <=54
|
|
// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
|
|
initial = initial / 2;
|
|
|
|
// Trust units reported by jQuery.css
|
|
unit = unit || initialInUnit[ 3 ];
|
|
|
|
// Iteratively approximate from a nonzero starting point
|
|
initialInUnit = +initial || 1;
|
|
|
|
while ( maxIterations-- ) {
|
|
|
|
// Evaluate and update our best guess (doubling guesses that zero out).
|
|
// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
|
|
jQuery.style( elem, prop, initialInUnit + unit );
|
|
if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
|
|
maxIterations = 0;
|
|
}
|
|
initialInUnit = initialInUnit / scale;
|
|
|
|
}
|
|
|
|
initialInUnit = initialInUnit * 2;
|
|
jQuery.style( elem, prop, initialInUnit + unit );
|
|
|
|
// Make sure we update the tween properties later on
|
|
valueParts = valueParts || [];
|
|
}
|
|
|
|
if ( valueParts ) {
|
|
initialInUnit = +initialInUnit || +initial || 0;
|
|
|
|
// Apply relative offset (+=/-=) if specified
|
|
adjusted = valueParts[ 1 ] ?
|
|
initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
|
|
+valueParts[ 2 ];
|
|
if ( tween ) {
|
|
tween.unit = unit;
|
|
tween.start = initialInUnit;
|
|
tween.end = adjusted;
|
|
}
|
|
}
|
|
return adjusted;
|
|
}
|
|
|
|
|
|
var defaultDisplayMap = {};
|
|
|
|
function getDefaultDisplay( elem ) {
|
|
var temp,
|
|
doc = elem.ownerDocument,
|
|
nodeName = elem.nodeName,
|
|
display = defaultDisplayMap[ nodeName ];
|
|
|
|
if ( display ) {
|
|
return display;
|
|
}
|
|
|
|
temp = doc.body.appendChild( doc.createElement( nodeName ) );
|
|
display = jQuery.css( temp, "display" );
|
|
|
|
temp.parentNode.removeChild( temp );
|
|
|
|
if ( display === "none" ) {
|
|
display = "block";
|
|
}
|
|
defaultDisplayMap[ nodeName ] = display;
|
|
|
|
return display;
|
|
}
|
|
|
|
function showHide( elements, show ) {
|
|
var display, elem,
|
|
values = [],
|
|
index = 0,
|
|
length = elements.length;
|
|
|
|
// Determine new display value for elements that need to change
|
|
for ( ; index < length; index++ ) {
|
|
elem = elements[ index ];
|
|
if ( !elem.style ) {
|
|
continue;
|
|
}
|
|
|
|
display = elem.style.display;
|
|
if ( show ) {
|
|
|
|
// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
|
|
// check is required in this first loop unless we have a nonempty display value (either
|
|
// inline or about-to-be-restored)
|
|
if ( display === "none" ) {
|
|
values[ index ] = dataPriv.get( elem, "display" ) || null;
|
|
if ( !values[ index ] ) {
|
|
elem.style.display = "";
|
|
}
|
|
}
|
|
if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
|
|
values[ index ] = getDefaultDisplay( elem );
|
|
}
|
|
} else {
|
|
if ( display !== "none" ) {
|
|
values[ index ] = "none";
|
|
|
|
// Remember what we're overwriting
|
|
dataPriv.set( elem, "display", display );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set the display of the elements in a second loop to avoid constant reflow
|
|
for ( index = 0; index < length; index++ ) {
|
|
if ( values[ index ] != null ) {
|
|
elements[ index ].style.display = values[ index ];
|
|
}
|
|
}
|
|
|
|
return elements;
|
|
}
|
|
|
|
jQuery.fn.extend( {
|
|
show: function() {
|
|
return showHide( this, true );
|
|
},
|
|
hide: function() {
|
|
return showHide( this );
|
|
},
|
|
toggle: function( state ) {
|
|
if ( typeof state === "boolean" ) {
|
|
return state ? this.show() : this.hide();
|
|
}
|
|
|
|
return this.each( function() {
|
|
if ( isHiddenWithinTree( this ) ) {
|
|
jQuery( this ).show();
|
|
} else {
|
|
jQuery( this ).hide();
|
|
}
|
|
} );
|
|
}
|
|
} );
|
|
var rcheckableType = ( /^(?:checkbox|radio)$/i );
|
|
|
|
var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
|
|
|
|
var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
|
|
|
|
|
|
|
|
( function() {
|
|
var fragment = document.createDocumentFragment(),
|
|
div = fragment.appendChild( document.createElement( "div" ) ),
|
|
input = document.createElement( "input" );
|
|
|
|
// Support: Android 4.0 - 4.3 only
|
|
// Check state lost if the name is set (#11217)
|
|
// Support: Windows Web Apps (WWA)
|
|
// `name` and `type` must use .setAttribute for WWA (#14901)
|
|
input.setAttribute( "type", "radio" );
|
|
input.setAttribute( "checked", "checked" );
|
|
input.setAttribute( "name", "t" );
|
|
|
|
div.appendChild( input );
|
|
|
|
// Support: Android <=4.1 only
|
|
// Older WebKit doesn't clone checked state correctly in fragments
|
|
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
|
|
|
|
// Support: IE <=11 only
|
|
// Make sure textarea (and checkbox) defaultValue is properly cloned
|
|
div.innerHTML = "<textarea>x</textarea>";
|
|
support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
|
|
|
|
// Support: IE <=9 only
|
|
// IE <=9 replaces <option> tags with their contents when inserted outside of
|
|
// the select element.
|
|
div.innerHTML = "<option></option>";
|
|
support.option = !!div.lastChild;
|
|
} )();
|
|
|
|
|
|
// We have to close these tags to support XHTML (#13200)
|
|
var wrapMap = {
|
|
|
|
// XHTML parsers do not magically insert elements in the
|
|
// same way that tag soup parsers do. So we cannot shorten
|
|
// this by omitting <tbody> or other required elements.
|
|
thead: [ 1, "<table>", "</table>" ],
|
|
col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
|
|
tr: [ 2, "<table><tbody>", "</tbody></table>" ],
|
|
td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
|
|
|
|
_default: [ 0, "", "" ]
|
|
};
|
|
|
|
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
|
|
wrapMap.th = wrapMap.td;
|
|
|
|
// Support: IE <=9 only
|
|
if ( !support.option ) {
|
|
wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
|
|
}
|
|
|
|
|
|
function getAll( context, tag ) {
|
|
|
|
// Support: IE <=9 - 11 only
|
|
// Use typeof to avoid zero-argument method invocation on host objects (#15151)
|
|
var ret;
|
|
|
|
if ( typeof context.getElementsByTagName !== "undefined" ) {
|
|
ret = context.getElementsByTagName( tag || "*" );
|
|
|
|
} else if ( typeof context.querySelectorAll !== "undefined" ) {
|
|
ret = context.querySelectorAll( tag || "*" );
|
|
|
|
} else {
|
|
ret = [];
|
|
}
|
|
|
|
if ( tag === undefined || tag && nodeName( context, tag ) ) {
|
|
return jQuery.merge( [ context ], ret );
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
// Mark scripts as having already been evaluated
|
|
function setGlobalEval( elems, refElements ) {
|
|
var i = 0,
|
|
l = elems.length;
|
|
|
|
for ( ; i < l; i++ ) {
|
|
dataPriv.set(
|
|
elems[ i ],
|
|
"globalEval",
|
|
!refElements || dataPriv.get( refElements[ i ], "globalEval" )
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
var rhtml = /<|&#?\w+;/;
|
|
|
|
function buildFragment( elems, context, scripts, selection, ignored ) {
|
|
var elem, tmp, tag, wrap, attached, j,
|
|
fragment = context.createDocumentFragment(),
|
|
nodes = [],
|
|
i = 0,
|
|
l = elems.length;
|
|
|
|
for ( ; i < l; i++ ) {
|
|
elem = elems[ i ];
|
|
|
|
if ( elem || elem === 0 ) {
|
|
|
|
// Add nodes directly
|
|
if ( toType( elem ) === "object" ) {
|
|
|
|
// Support: Android <=4.0 only, PhantomJS 1 only
|
|
// push.apply(_, arraylike) throws on ancient WebKit
|
|
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
|
|
|
|
// Convert non-html into a text node
|
|
} else if ( !rhtml.test( elem ) ) {
|
|
nodes.push( context.createTextNode( elem ) );
|
|
|
|
// Convert html into DOM nodes
|
|
} else {
|
|
tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
|
|
|
|
// Deserialize a standard representation
|
|
tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
|
|
wrap = wrapMap[ tag ] || wrapMap._default;
|
|
tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
|
|
|
|
// Descend through wrappers to the right content
|
|
j = wrap[ 0 ];
|
|
while ( j-- ) {
|
|
tmp = tmp.lastChild;
|
|
}
|
|
|
|
// Support: Android <=4.0 only, PhantomJS 1 only
|
|
// push.apply(_, arraylike) throws on ancient WebKit
|
|
jQuery.merge( nodes, tmp.childNodes );
|
|
|
|
// Remember the top-level container
|
|
tmp = fragment.firstChild;
|
|
|
|
// Ensure the created nodes are orphaned (#12392)
|
|
tmp.textContent = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove wrapper from fragment
|
|
fragment.textContent = "";
|
|
|
|
i = 0;
|
|
while ( ( elem = nodes[ i++ ] ) ) {
|
|
|
|
// Skip elements already in the context collection (trac-4087)
|
|
if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
|
|
if ( ignored ) {
|
|
ignored.push( elem );
|
|
}
|
|
continue;
|
|
}
|
|
|
|
attached = isAttached( elem );
|
|
|
|
// Append to fragment
|
|
tmp = getAll( fragment.appendChild( elem ), "script" );
|
|
|
|
// Preserve script evaluation history
|
|
if ( attached ) {
|
|
setGlobalEval( tmp );
|
|
}
|
|
|
|
// Capture executables
|
|
if ( scripts ) {
|
|
j = 0;
|
|
while ( ( elem = tmp[ j++ ] ) ) {
|
|
if ( rscriptType.test( elem.type || "" ) ) {
|
|
scripts.push( elem );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return fragment;
|
|
}
|
|
|
|
|
|
var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
|
|
|
|
function returnTrue() {
|
|
return true;
|
|
}
|
|
|
|
function returnFalse() {
|
|
return false;
|
|
}
|
|
|
|
// Support: IE <=9 - 11+
|
|
// focus() and blur() are asynchronous, except when they are no-op.
|
|
// So expect focus to be synchronous when the element is already active,
|
|
// and blur to be synchronous when the element is not already active.
|
|
// (focus and blur are always synchronous in other supported browsers,
|
|
// this just defines when we can count on it).
|
|
function expectSync( elem, type ) {
|
|
return ( elem === safeActiveElement() ) === ( type === "focus" );
|
|
}
|
|
|
|
// Support: IE <=9 only
|
|
// Accessing document.activeElement can throw unexpectedly
|
|
// https://bugs.jquery.com/ticket/13393
|
|
function safeActiveElement() {
|
|
try {
|
|
return document.activeElement;
|
|
} catch ( err ) { }
|
|
}
|
|
|
|
function on( elem, types, selector, data, fn, one ) {
|
|
var origFn, type;
|
|
|
|
// Types can be a map of types/handlers
|
|
if ( typeof types === "object" ) {
|
|
|
|
// ( types-Object, selector, data )
|
|
if ( typeof selector !== "string" ) {
|
|
|
|
// ( types-Object, data )
|
|
data = data || selector;
|
|
selector = undefined;
|
|
}
|
|
for ( type in types ) {
|
|
on( elem, type, selector, data, types[ type ], one );
|
|
}
|
|
return elem;
|
|
}
|
|
|
|
if ( data == null && fn == null ) {
|
|
|
|
// ( types, fn )
|
|
fn = selector;
|
|
data = selector = undefined;
|
|
} else if ( fn == null ) {
|
|
if ( typeof selector === "string" ) {
|
|
|
|
// ( types, selector, fn )
|
|
fn = data;
|
|
data = undefined;
|
|
} else {
|
|
|
|
// ( types, data, fn )
|
|
fn = data;
|
|
data = selector;
|
|
selector = undefined;
|
|
}
|
|
}
|
|
if ( fn === false ) {
|
|
fn = returnFalse;
|
|
} else if ( !fn ) {
|
|
return elem;
|
|
}
|
|
|
|
if ( one === 1 ) {
|
|
origFn = fn;
|
|
fn = function( event ) {
|
|
|
|
// Can use an empty set, since event contains the info
|
|
jQuery().off( event );
|
|
return origFn.apply( this, arguments );
|
|
};
|
|
|
|
// Use same guid so caller can remove using origFn
|
|
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
|
|
}
|
|
return elem.each( function() {
|
|
jQuery.event.add( this, types, fn, data, selector );
|
|
} );
|
|
}
|
|
|
|
/*
|
|
* Helper functions for managing events -- not part of the public interface.
|
|
* Props to Dean Edwards' addEvent library for many of the ideas.
|
|
*/
|
|
jQuery.event = {
|
|
|
|
global: {},
|
|
|
|
add: function( elem, types, handler, data, selector ) {
|
|
|
|
var handleObjIn, eventHandle, tmp,
|
|
events, t, handleObj,
|
|
special, handlers, type, namespaces, origType,
|
|
elemData = dataPriv.get( elem );
|
|
|
|
// Only attach events to objects that accept data
|
|
if ( !acceptData( elem ) ) {
|
|
return;
|
|
}
|
|
|
|
// Caller can pass in an object of custom data in lieu of the handler
|
|
if ( handler.handler ) {
|
|
handleObjIn = handler;
|
|
handler = handleObjIn.handler;
|
|
selector = handleObjIn.selector;
|
|
}
|
|
|
|
// Ensure that invalid selectors throw exceptions at attach time
|
|
// Evaluate against documentElement in case elem is a non-element node (e.g., document)
|
|
if ( selector ) {
|
|
jQuery.find.matchesSelector( documentElement, selector );
|
|
}
|
|
|
|
// Make sure that the handler has a unique ID, used to find/remove it later
|
|
if ( !handler.guid ) {
|
|
handler.guid = jQuery.guid++;
|
|
}
|
|
|
|
// Init the element's event structure and main handler, if this is the first
|
|
if ( !( events = elemData.events ) ) {
|
|
events = elemData.events = Object.create( null );
|
|
}
|
|
if ( !( eventHandle = elemData.handle ) ) {
|
|
eventHandle = elemData.handle = function( e ) {
|
|
|
|
// Discard the second event of a jQuery.event.trigger() and
|
|
// when an event is called after a page has unloaded
|
|
return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
|
|
jQuery.event.dispatch.apply( elem, arguments ) : undefined;
|
|
};
|
|
}
|
|
|
|
// Handle multiple events separated by a space
|
|
types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
|
|
t = types.length;
|
|
while ( t-- ) {
|
|
tmp = rtypenamespace.exec( types[ t ] ) || [];
|
|
type = origType = tmp[ 1 ];
|
|
namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
|
|
|
|
// There *must* be a type, no attaching namespace-only handlers
|
|
if ( !type ) {
|
|
continue;
|
|
}
|
|
|
|
// If event changes its type, use the special event handlers for the changed type
|
|
special = jQuery.event.special[ type ] || {};
|
|
|
|
// If selector defined, determine special event api type, otherwise given type
|
|
type = ( selector ? special.delegateType : special.bindType ) || type;
|
|
|
|
// Update special based on newly reset type
|
|
special = jQuery.event.special[ type ] || {};
|
|
|
|
// handleObj is passed to all event handlers
|
|
handleObj = jQuery.extend( {
|
|
type: type,
|
|
origType: origType,
|
|
data: data,
|
|
handler: handler,
|
|
guid: handler.guid,
|
|
selector: selector,
|
|
needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
|
|
namespace: namespaces.join( "." )
|
|
}, handleObjIn );
|
|
|
|
// Init the event handler queue if we're the first
|
|
if ( !( handlers = events[ type ] ) ) {
|
|
handlers = events[ type ] = [];
|
|
handlers.delegateCount = 0;
|
|
|
|
// Only use addEventListener if the special events handler returns false
|
|
if ( !special.setup ||
|
|
special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
|
|
|
|
if ( elem.addEventListener ) {
|
|
elem.addEventListener( type, eventHandle );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( special.add ) {
|
|
special.add.call( elem, handleObj );
|
|
|
|
if ( !handleObj.handler.guid ) {
|
|
handleObj.handler.guid = handler.guid;
|
|
}
|
|
}
|
|
|
|
// Add to the element's handler list, delegates in front
|
|
if ( selector ) {
|
|
handlers.splice( handlers.delegateCount++, 0, handleObj );
|
|
} else {
|
|
handlers.push( handleObj );
|
|
}
|
|
|
|
// Keep track of which events have ever been used, for event optimization
|
|
jQuery.event.global[ type ] = true;
|
|
}
|
|
|
|
},
|
|
|
|
// Detach an event or set of events from an element
|
|
remove: function( elem, types, handler, selector, mappedTypes ) {
|
|
|
|
var j, origCount, tmp,
|
|
events, t, handleObj,
|
|
special, handlers, type, namespaces, origType,
|
|
elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
|
|
|
|
if ( !elemData || !( events = elemData.events ) ) {
|
|
return;
|
|
}
|
|
|
|
// Once for each type.namespace in types; type may be omitted
|
|
types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
|
|
t = types.length;
|
|
while ( t-- ) {
|
|
tmp = rtypenamespace.exec( types[ t ] ) || [];
|
|
type = origType = tmp[ 1 ];
|
|
namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
|
|
|
|
// Unbind all events (on this namespace, if provided) for the element
|
|
if ( !type ) {
|
|
for ( type in events ) {
|
|
jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
|
|
}
|
|
continue;
|
|
}
|
|
|
|
special = jQuery.event.special[ type ] || {};
|
|
type = ( selector ? special.delegateType : special.bindType ) || type;
|
|
handlers = events[ type ] || [];
|
|
tmp = tmp[ 2 ] &&
|
|
new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
|
|
|
|
// Remove matching events
|
|
origCount = j = handlers.length;
|
|
while ( j-- ) {
|
|
handleObj = handlers[ j ];
|
|
|
|
if ( ( mappedTypes || origType === handleObj.origType ) &&
|
|
( !handler || handler.guid === handleObj.guid ) &&
|
|
( !tmp || tmp.test( handleObj.namespace ) ) &&
|
|
( !selector || selector === handleObj.selector ||
|
|
selector === "**" && handleObj.selector ) ) {
|
|
handlers.splice( j, 1 );
|
|
|
|
if ( handleObj.selector ) {
|
|
handlers.delegateCount--;
|
|
}
|
|
if ( special.remove ) {
|
|
special.remove.call( elem, handleObj );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove generic event handler if we removed something and no more handlers exist
|
|
// (avoids potential for endless recursion during removal of special event handlers)
|
|
if ( origCount && !handlers.length ) {
|
|
if ( !special.teardown ||
|
|
special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
|
|
|
|
jQuery.removeEvent( elem, type, elemData.handle );
|
|
}
|
|
|
|
delete events[ type ];
|
|
}
|
|
}
|
|
|
|
// Remove data and the expando if it's no longer used
|
|
if ( jQuery.isEmptyObject( events ) ) {
|
|
dataPriv.remove( elem, "handle events" );
|
|
}
|
|
},
|
|
|
|
dispatch: function( nativeEvent ) {
|
|
|
|
var i, j, ret, matched, handleObj, handlerQueue,
|
|
args = new Array( arguments.length ),
|
|
|
|
// Make a writable jQuery.Event from the native event object
|
|
event = jQuery.event.fix( nativeEvent ),
|
|
|
|
handlers = (
|
|
dataPriv.get( this, "events" ) || Object.create( null )
|
|
)[ event.type ] || [],
|
|
special = jQuery.event.special[ event.type ] || {};
|
|
|
|
// Use the fix-ed jQuery.Event rather than the (read-only) native event
|
|
args[ 0 ] = event;
|
|
|
|
for ( i = 1; i < arguments.length; i++ ) {
|
|
args[ i ] = arguments[ i ];
|
|
}
|
|
|
|
event.delegateTarget = this;
|
|
|
|
// Call the preDispatch hook for the mapped type, and let it bail if desired
|
|
if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
|
|
return;
|
|
}
|
|
|
|
// Determine handlers
|
|
handlerQueue = jQuery.event.handlers.call( this, event, handlers );
|
|
|
|
// Run delegates first; they may want to stop propagation beneath us
|
|
i = 0;
|
|
while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
|
|
event.currentTarget = matched.elem;
|
|
|
|
j = 0;
|
|
while ( ( handleObj = matched.handlers[ j++ ] ) &&
|
|
!event.isImmediatePropagationStopped() ) {
|
|
|
|
// If the event is namespaced, then each handler is only invoked if it is
|
|
// specially universal or its namespaces are a superset of the event's.
|
|
if ( !event.rnamespace || handleObj.namespace === false ||
|
|
event.rnamespace.test( handleObj.namespace ) ) {
|
|
|
|
event.handleObj = handleObj;
|
|
event.data = handleObj.data;
|
|
|
|
ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
|
|
handleObj.handler ).apply( matched.elem, args );
|
|
|
|
if ( ret !== undefined ) {
|
|
if ( ( event.result = ret ) === false ) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Call the postDispatch hook for the mapped type
|
|
if ( special.postDispatch ) {
|
|
special.postDispatch.call( this, event );
|
|
}
|
|
|
|
return event.result;
|
|
},
|
|
|
|
handlers: function( event, handlers ) {
|
|
var i, handleObj, sel, matchedHandlers, matchedSelectors,
|
|
handlerQueue = [],
|
|
delegateCount = handlers.delegateCount,
|
|
cur = event.target;
|
|
|
|
// Find delegate handlers
|
|
if ( delegateCount &&
|
|
|
|
// Support: IE <=9
|
|
// Black-hole SVG <use> instance trees (trac-13180)
|
|
cur.nodeType &&
|
|
|
|
// Support: Firefox <=42
|
|
// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
|
|
// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
|
|
// Support: IE 11 only
|
|
// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
|
|
!( event.type === "click" && event.button >= 1 ) ) {
|
|
|
|
for ( ; cur !== this; cur = cur.parentNode || this ) {
|
|
|
|
// Don't check non-elements (#13208)
|
|
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
|
|
if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
|
|
matchedHandlers = [];
|
|
matchedSelectors = {};
|
|
for ( i = 0; i < delegateCount; i++ ) {
|
|
handleObj = handlers[ i ];
|
|
|
|
// Don't conflict with Object.prototype properties (#13203)
|
|
sel = handleObj.selector + " ";
|
|
|
|
if ( matchedSelectors[ sel ] === undefined ) {
|
|
matchedSelectors[ sel ] = handleObj.needsContext ?
|
|
jQuery( sel, this ).index( cur ) > -1 :
|
|
jQuery.find( sel, this, null, [ cur ] ).length;
|
|
}
|
|
if ( matchedSelectors[ sel ] ) {
|
|
matchedHandlers.push( handleObj );
|
|
}
|
|
}
|
|
if ( matchedHandlers.length ) {
|
|
handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add the remaining (directly-bound) handlers
|
|
cur = this;
|
|
if ( delegateCount < handlers.length ) {
|
|
handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
|
|
}
|
|
|
|
return handlerQueue;
|
|
},
|
|
|
|
addProp: function( name, hook ) {
|
|
Object.defineProperty( jQuery.Event.prototype, name, {
|
|
enumerable: true,
|
|
configurable: true,
|
|
|
|
get: isFunction( hook ) ?
|
|
function() {
|
|
if ( this.originalEvent ) {
|
|
return hook( this.originalEvent );
|
|
}
|
|
} :
|
|
function() {
|
|
if ( this.originalEvent ) {
|
|
return this.originalEvent[ name ];
|
|
}
|
|
},
|
|
|
|
set: function( value ) {
|
|
Object.defineProperty( this, name, {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: value
|
|
} );
|
|
}
|
|
} );
|
|
},
|
|
|
|
fix: function( originalEvent ) {
|
|
return originalEvent[ jQuery.expando ] ?
|
|
originalEvent :
|
|
new jQuery.Event( originalEvent );
|
|
},
|
|
|
|
special: {
|
|
load: {
|
|
|
|
// Prevent triggered image.load events from bubbling to window.load
|
|
noBubble: true
|
|
},
|
|
click: {
|
|
|
|
// Utilize native event to ensure correct state for checkable inputs
|
|
setup: function( data ) {
|
|
|
|
// For mutual compressibility with _default, replace `this` access with a local var.
|
|
// `|| data` is dead code meant only to preserve the variable through minification.
|
|
var el = this || data;
|
|
|
|
// Claim the first handler
|
|
if ( rcheckableType.test( el.type ) &&
|
|
el.click && nodeName( el, "input" ) ) {
|
|
|
|
// dataPriv.set( el, "click", ... )
|
|
leverageNative( el, "click", returnTrue );
|
|
}
|
|
|
|
// Return false to allow normal processing in the caller
|
|
return false;
|
|
},
|
|
trigger: function( data ) {
|
|
|
|
// For mutual compressibility with _default, replace `this` access with a local var.
|
|
// `|| data` is dead code meant only to preserve the variable through minification.
|
|
var el = this || data;
|
|
|
|
// Force setup before triggering a click
|
|
if ( rcheckableType.test( el.type ) &&
|
|
el.click && nodeName( el, "input" ) ) {
|
|
|
|
leverageNative( el, "click" );
|
|
}
|
|
|
|
// Return non-false to allow normal event-path propagation
|
|
return true;
|
|
},
|
|
|
|
// For cross-browser consistency, suppress native .click() on links
|
|
// Also prevent it if we're currently inside a leveraged native-event stack
|
|
_default: function( event ) {
|
|
var target = event.target;
|
|
return rcheckableType.test( target.type ) &&
|
|
target.click && nodeName( target, "input" ) &&
|
|
dataPriv.get( target, "click" ) ||
|
|
nodeName( target, "a" );
|
|
}
|
|
},
|
|
|
|
beforeunload: {
|
|
postDispatch: function( event ) {
|
|
|
|
// Support: Firefox 20+
|
|
// Firefox doesn't alert if the returnValue field is not set.
|
|
if ( event.result !== undefined && event.originalEvent ) {
|
|
event.originalEvent.returnValue = event.result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// Ensure the presence of an event listener that handles manually-triggered
|
|
// synthetic events by interrupting progress until reinvoked in response to
|
|
// *native* events that it fires directly, ensuring that state changes have
|
|
// already occurred before other listeners are invoked.
|
|
function leverageNative( el, type, expectSync ) {
|
|
|
|
// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
|
|
if ( !expectSync ) {
|
|
if ( dataPriv.get( el, type ) === undefined ) {
|
|
jQuery.event.add( el, type, returnTrue );
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Register the controller as a special universal handler for all event namespaces
|
|
dataPriv.set( el, type, false );
|
|
jQuery.event.add( el, type, {
|
|
namespace: false,
|
|
handler: function( event ) {
|
|
var notAsync, result,
|
|
saved = dataPriv.get( this, type );
|
|
|
|
if ( ( event.isTrigger & 1 ) && this[ type ] ) {
|
|
|
|
// Interrupt processing of the outer synthetic .trigger()ed event
|
|
// Saved data should be false in such cases, but might be a leftover capture object
|
|
// from an async native handler (gh-4350)
|
|
if ( !saved.length ) {
|
|
|
|
// Store arguments for use when handling the inner native event
|
|
// There will always be at least one argument (an event object), so this array
|
|
// will not be confused with a leftover capture object.
|
|
saved = slice.call( arguments );
|
|
dataPriv.set( this, type, saved );
|
|
|
|
// Trigger the native event and capture its result
|
|
// Support: IE <=9 - 11+
|
|
// focus() and blur() are asynchronous
|
|
notAsync = expectSync( this, type );
|
|
this[ type ]();
|
|
result = dataPriv.get( this, type );
|
|
if ( saved !== result || notAsync ) {
|
|
dataPriv.set( this, type, false );
|
|
} else {
|
|
result = {};
|
|
}
|
|
if ( saved !== result ) {
|
|
|
|
// Cancel the outer synthetic event
|
|
event.stopImmediatePropagation();
|
|
event.preventDefault();
|
|
|
|
// Support: Chrome 86+
|
|
// In Chrome, if an element having a focusout handler is blurred by
|
|
// clicking outside of it, it invokes the handler synchronously. If
|
|
// that handler calls `.remove()` on the element, the data is cleared,
|
|
// leaving `result` undefined. We need to guard against this.
|
|
return result && result.value;
|
|
}
|
|
|
|
// If this is an inner synthetic event for an event with a bubbling surrogate
|
|
// (focus or blur), assume that the surrogate already propagated from triggering the
|
|
// native event and prevent that from happening again here.
|
|
// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
|
|
// bubbling surrogate propagates *after* the non-bubbling base), but that seems
|
|
// less bad than duplication.
|
|
} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
|
|
event.stopPropagation();
|
|
}
|
|
|
|
// If this is a native event triggered above, everything is now in order
|
|
// Fire an inner synthetic event with the original arguments
|
|
} else if ( saved.length ) {
|
|
|
|
// ...and capture the result
|
|
dataPriv.set( this, type, {
|
|
value: jQuery.event.trigger(
|
|
|
|
// Support: IE <=9 - 11+
|
|
// Extend with the prototype to reset the above stopImmediatePropagation()
|
|
jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
|
|
saved.slice( 1 ),
|
|
this
|
|
)
|
|
} );
|
|
|
|
// Abort handling of the native event
|
|
event.stopImmediatePropagation();
|
|
}
|
|
}
|
|
} );
|
|
}
|
|
|
|
jQuery.removeEvent = function( elem, type, handle ) {
|
|
|
|
// This "if" is needed for plain objects
|
|
if ( elem.removeEventListener ) {
|
|
elem.removeEventListener( type, handle );
|
|
}
|
|
};
|
|
|
|
jQuery.Event = function( src, props ) {
|
|
|
|
// Allow instantiation without the 'new' keyword
|
|
if ( !( this instanceof jQuery.Event ) ) {
|
|
return new jQuery.Event( src, props );
|
|
}
|
|
|
|
// Event object
|
|
if ( src && src.type ) {
|
|
this.originalEvent = src;
|
|
this.type = src.type;
|
|
|
|
// Events bubbling up the document may have been marked as prevented
|
|
// by a handler lower down the tree; reflect the correct value.
|
|
this.isDefaultPrevented = src.defaultPrevented ||
|
|
src.defaultPrevented === undefined &&
|
|
|
|
// Support: Android <=2.3 only
|
|
src.returnValue === false ?
|
|
returnTrue :
|
|
returnFalse;
|
|
|
|
// Create target properties
|
|
// Support: Safari <=6 - 7 only
|
|
// Target should not be a text node (#504, #13143)
|
|
this.target = ( src.target && src.target.nodeType === 3 ) ?
|
|
src.target.parentNode :
|
|
src.target;
|
|
|
|
this.currentTarget = src.currentTarget;
|
|
this.relatedTarget = src.relatedTarget;
|
|
|
|
// Event type
|
|
} else {
|
|
this.type = src;
|
|
}
|
|
|
|
// Put explicitly provided properties onto the event object
|
|
if ( props ) {
|
|
jQuery.extend( this, props );
|
|
}
|
|
|
|
// Create a timestamp if incoming event doesn't have one
|
|
this.timeStamp = src && src.timeStamp || Date.now();
|
|
|
|
// Mark it as fixed
|
|
this[ jQuery.expando ] = true;
|
|
};
|
|
|
|
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
|
|
// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
|
|
jQuery.Event.prototype = {
|
|
constructor: jQuery.Event,
|
|
isDefaultPrevented: returnFalse,
|
|
isPropagationStopped: returnFalse,
|
|
isImmediatePropagationStopped: returnFalse,
|
|
isSimulated: false,
|
|
|
|
preventDefault: function() {
|
|
var e = this.originalEvent;
|
|
|
|
this.isDefaultPrevented = returnTrue;
|
|
|
|
if ( e && !this.isSimulated ) {
|
|
e.preventDefault();
|
|
}
|
|
},
|
|
stopPropagation: function() {
|
|
var e = this.originalEvent;
|
|
|
|
this.isPropagationStopped = returnTrue;
|
|
|
|
if ( e && !this.isSimulated ) {
|
|
e.stopPropagation();
|
|
}
|
|
},
|
|
stopImmediatePropagation: function() {
|
|
var e = this.originalEvent;
|
|
|
|
this.isImmediatePropagationStopped = returnTrue;
|
|
|
|
if ( e && !this.isSimulated ) {
|
|
e.stopImmediatePropagation();
|
|
}
|
|
|
|
this.stopPropagation();
|
|
}
|
|
};
|
|
|
|
// Includes all common event props including KeyEvent and MouseEvent specific props
|
|
jQuery.each( {
|
|
altKey: true,
|
|
bubbles: true,
|
|
cancelable: true,
|
|
changedTouches: true,
|
|
ctrlKey: true,
|
|
detail: true,
|
|
eventPhase: true,
|
|
metaKey: true,
|
|
pageX: true,
|
|
pageY: true,
|
|
shiftKey: true,
|
|
view: true,
|
|
"char": true,
|
|
code: true,
|
|
charCode: true,
|
|
key: true,
|
|
keyCode: true,
|
|
button: true,
|
|
buttons: true,
|
|
clientX: true,
|
|
clientY: true,
|
|
offsetX: true,
|
|
offsetY: true,
|
|
pointerId: true,
|
|
pointerType: true,
|
|
screenX: true,
|
|
screenY: true,
|
|
targetTouches: true,
|
|
toElement: true,
|
|
touches: true,
|
|
which: true
|
|
}, jQuery.event.addProp );
|
|
|
|
jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
|
|
jQuery.event.special[ type ] = {
|
|
|
|
// Utilize native event if possible so blur/focus sequence is correct
|
|
setup: function() {
|
|
|
|
// Claim the first handler
|
|
// dataPriv.set( this, "focus", ... )
|
|
// dataPriv.set( this, "blur", ... )
|
|
leverageNative( this, type, expectSync );
|
|
|
|
// Return false to allow normal processing in the caller
|
|
return false;
|
|
},
|
|
trigger: function() {
|
|
|
|
// Force setup before trigger
|
|
leverageNative( this, type );
|
|
|
|
// Return non-false to allow normal event-path propagation
|
|
return true;
|
|
},
|
|
|
|
// Suppress native focus or blur as it's already being fired
|
|
// in leverageNative.
|
|
_default: function() {
|
|
return true;
|
|
},
|
|
|
|
delegateType: delegateType
|
|
};
|
|
} );
|
|
|
|
// Create mouseenter/leave events using mouseover/out and event-time checks
|
|
// so that event delegation works in jQuery.
|
|
// Do the same for pointerenter/pointerleave and pointerover/pointerout
|
|
//
|
|
// Support: Safari 7 only
|
|
// Safari sends mouseenter too often; see:
|
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
|
|
// for the description of the bug (it existed in older Chrome versions as well).
|
|
jQuery.each( {
|
|
mouseenter: "mouseover",
|
|
mouseleave: "mouseout",
|
|
pointerenter: "pointerover",
|
|
pointerleave: "pointerout"
|
|
}, function( orig, fix ) {
|
|
jQuery.event.special[ orig ] = {
|
|
delegateType: fix,
|
|
bindType: fix,
|
|
|
|
handle: function( event ) {
|
|
var ret,
|
|
target = this,
|
|
related = event.relatedTarget,
|
|
handleObj = event.handleObj;
|
|
|
|
// For mouseenter/leave call the handler if related is outside the target.
|
|
// NB: No relatedTarget if the mouse left/entered the browser window
|
|
if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
|
|
event.type = handleObj.origType;
|
|
ret = handleObj.handler.apply( this, arguments );
|
|
event.type = fix;
|
|
}
|
|
return ret;
|
|
}
|
|
};
|
|
} );
|
|
|
|
jQuery.fn.extend( {
|
|
|
|
on: function( types, selector, data, fn ) {
|
|
return on( this, types, selector, data, fn );
|
|
},
|
|
one: function( types, selector, data, fn ) {
|
|
return on( this, types, selector, data, fn, 1 );
|
|
},
|
|
off: function( types, selector, fn ) {
|
|
var handleObj, type;
|
|
if ( types && types.preventDefault && types.handleObj ) {
|
|
|
|
// ( event ) dispatched jQuery.Event
|
|
handleObj = types.handleObj;
|
|
jQuery( types.delegateTarget ).off(
|
|
handleObj.namespace ?
|
|
handleObj.origType + "." + handleObj.namespace :
|
|
handleObj.origType,
|
|
handleObj.selector,
|
|
handleObj.handler
|
|
);
|
|
return this;
|
|
}
|
|
if ( typeof types === "object" ) {
|
|
|
|
// ( types-object [, selector] )
|
|
for ( type in types ) {
|
|
this.off( type, selector, types[ type ] );
|
|
}
|
|
return this;
|
|
}
|
|
if ( selector === false || typeof selector === "function" ) {
|
|
|
|
// ( types [, fn] )
|
|
fn = selector;
|
|
selector = undefined;
|
|
}
|
|
if ( fn === false ) {
|
|
fn = returnFalse;
|
|
}
|
|
return this.each( function() {
|
|
jQuery.event.remove( this, types, fn, selector );
|
|
} );
|
|
}
|
|
} );
|
|
|
|
|
|
var
|
|
|
|
// Support: IE <=10 - 11, Edge 12 - 13 only
|
|
// In IE/Edge using regex groups here causes severe slowdowns.
|
|
// See https://connect.microsoft.com/IE/feedback/details/1736512/
|
|
rnoInnerhtml = /<script|<style|<link/i,
|
|
|
|
// checked="checked" or checked
|
|
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
|
|
rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
|
|
|
|
// Prefer a tbody over its parent table for containing new rows
|
|
function manipulationTarget( elem, content ) {
|
|
if ( nodeName( elem, "table" ) &&
|
|
nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
|
|
|
|
return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
|
|
}
|
|
|
|
return elem;
|
|
}
|
|
|
|
// Replace/restore the type attribute of script elements for safe DOM manipulation
|
|
function disableScript( elem ) {
|
|
elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
|
|
return elem;
|
|
}
|
|
function restoreScript( elem ) {
|
|
if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
|
|
elem.type = elem.type.slice( 5 );
|
|
} else {
|
|
elem.removeAttribute( "type" );
|
|
}
|
|
|
|
return elem;
|
|
}
|
|
|
|
function cloneCopyEvent( src, dest ) {
|
|
var i, l, type, pdataOld, udataOld, udataCur, events;
|
|
|
|
if ( dest.nodeType !== 1 ) {
|
|
return;
|
|
}
|
|
|
|
// 1. Copy private data: events, handlers, etc.
|
|
if ( dataPriv.hasData( src ) ) {
|
|
pdataOld = dataPriv.get( src );
|
|
events = pdataOld.events;
|
|
|
|
if ( events ) {
|
|
dataPriv.remove( dest, "handle events" );
|
|
|
|
for ( type in events ) {
|
|
for ( i = 0, l = events[ type ].length; i < l; i++ ) {
|
|
jQuery.event.add( dest, type, events[ type ][ i ] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2. Copy user data
|
|
if ( dataUser.hasData( src ) ) {
|
|
udataOld = dataUser.access( src );
|
|
udataCur = jQuery.extend( {}, udataOld );
|
|
|
|
dataUser.set( dest, udataCur );
|
|
}
|
|
}
|
|
|
|
// Fix IE bugs, see support tests
|
|
function fixInput( src, dest ) {
|
|
var nodeName = dest.nodeName.toLowerCase();
|
|
|
|
// Fails to persist the checked state of a cloned checkbox or radio button.
|
|
if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
|
|
dest.checked = src.checked;
|
|
|
|
// Fails to return the selected option to the default selected state when cloning options
|
|
} else if ( nodeName === "input" || nodeName === "textarea" ) {
|
|
dest.defaultValue = src.defaultValue;
|
|
}
|
|
}
|
|
|
|
function domManip( collection, args, callback, ignored ) {
|
|
|
|
// Flatten any nested arrays
|
|
args = flat( args );
|
|
|
|
var fragment, first, scripts, hasScripts, node, doc,
|
|
i = 0,
|
|
l = collection.length,
|
|
iNoClone = l - 1,
|
|
value = args[ 0 ],
|
|
valueIsFunction = isFunction( value );
|
|
|
|
// We can't cloneNode fragments that contain checked, in WebKit
|
|
if ( valueIsFunction ||
|
|
( l > 1 && typeof value === "string" &&
|
|
!support.checkClone && rchecked.test( value ) ) ) {
|
|
return collection.each( function( index ) {
|
|
var self = collection.eq( index );
|
|
if ( valueIsFunction ) {
|
|
args[ 0 ] = value.call( this, index, self.html() );
|
|
}
|
|
domManip( self, args, callback, ignored );
|
|
} );
|
|
}
|
|
|
|
if ( l ) {
|
|
fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
|
|
first = fragment.firstChild;
|
|
|
|
if ( fragment.childNodes.length === 1 ) {
|
|
fragment = first;
|
|
}
|
|
|
|
// Require either new content or an interest in ignored elements to invoke the callback
|
|
if ( first || ignored ) {
|
|
scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
|
|
hasScripts = scripts.length;
|
|
|
|
// Use the original fragment for the last item
|
|
// instead of the first because it can end up
|
|
// being emptied incorrectly in certain situations (#8070).
|
|
for ( ; i < l; i++ ) {
|
|
node = fragment;
|
|
|
|
if ( i !== iNoClone ) {
|
|
node = jQuery.clone( node, true, true );
|
|
|
|
// Keep references to cloned scripts for later restoration
|
|
if ( hasScripts ) {
|
|
|
|
// Support: Android <=4.0 only, PhantomJS 1 only
|
|
// push.apply(_, arraylike) throws on ancient WebKit
|
|
jQuery.merge( scripts, getAll( node, "script" ) );
|
|
}
|
|
}
|
|
|
|
callback.call( collection[ i ], node, i );
|
|
}
|
|
|
|
if ( hasScripts ) {
|
|
doc = scripts[ scripts.length - 1 ].ownerDocument;
|
|
|
|
// Reenable scripts
|
|
jQuery.map( scripts, restoreScript );
|
|
|
|
// Evaluate executable scripts on first document insertion
|
|
for ( i = 0; i < hasScripts; i++ ) {
|
|
node = scripts[ i ];
|
|
if ( rscriptType.test( node.type || "" ) &&
|
|
!dataPriv.access( node, "globalEval" ) &&
|
|
jQuery.contains( doc, node ) ) {
|
|
|
|
if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) {
|
|
|
|
// Optional AJAX dependency, but won't run scripts if not present
|
|
if ( jQuery._evalUrl && !node.noModule ) {
|
|
jQuery._evalUrl( node.src, {
|
|
nonce: node.nonce || node.getAttribute( "nonce" )
|
|
}, doc );
|
|
}
|
|
} else {
|
|
DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return collection;
|
|
}
|
|
|
|
function remove( elem, selector, keepData ) {
|
|
var node,
|
|
nodes = selector ? jQuery.filter( selector, elem ) : elem,
|
|
i = 0;
|
|
|
|
for ( ; ( node = nodes[ i ] ) != null; i++ ) {
|
|
if ( !keepData && node.nodeType === 1 ) {
|
|
jQuery.cleanData( getAll( node ) );
|
|
}
|
|
|
|
if ( node.parentNode ) {
|
|
if ( keepData && isAttached( node ) ) {
|
|
setGlobalEval( getAll( node, "script" ) );
|
|
}
|
|
node.parentNode.removeChild( node );
|
|
}
|
|
}
|
|
|
|
return elem;
|
|
}
|
|
|
|
jQuery.extend( {
|
|
htmlPrefilter: function( html ) {
|
|
return html;
|
|
},
|
|
|
|
clone: function( elem, dataAndEvents, deepDataAndEvents ) {
|
|
var i, l, srcElements, destElements,
|
|
clone = elem.cloneNode( true ),
|
|
inPage = isAttached( elem );
|
|
|
|
// Fix IE cloning issues
|
|
if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
|
|
!jQuery.isXMLDoc( elem ) ) {
|
|
|
|
// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
|
|
destElements = getAll( clone );
|
|
srcElements = getAll( elem );
|
|
|
|
for ( i = 0, l = srcElements.length; i < l; i++ ) {
|
|
fixInput( srcElements[ i ], destElements[ i ] );
|
|
}
|
|
}
|
|
|
|
// Copy the events from the original to the clone
|
|
if ( dataAndEvents ) {
|
|
if ( deepDataAndEvents ) {
|
|
srcElements = srcElements || getAll( elem );
|
|
destElements = destElements || getAll( clone );
|
|
|
|
for ( i = 0, l = srcElements.length; i < l; i++ ) {
|
|
cloneCopyEvent( srcElements[ i ], destElements[ i ] );
|
|
}
|
|
} else {
|
|
cloneCopyEvent( elem, clone );
|
|
}
|
|
}
|
|
|
|
// Preserve script evaluation history
|
|
destElements = getAll( clone, "script" );
|
|
if ( destElements.length > 0 ) {
|
|
setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
|
|
}
|
|
|
|
// Return the cloned set
|
|
return clone;
|
|
},
|
|
|
|
cleanData: function( elems ) {
|
|
var data, elem, type,
|
|
special = jQuery.event.special,
|
|
i = 0;
|
|
|
|
for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
|
|
if ( acceptData( elem ) ) {
|
|
if ( ( data = elem[ dataPriv.expando ] ) ) {
|
|
if ( data.events ) {
|
|
for ( type in data.events ) {
|
|
if ( special[ type ] ) {
|
|
jQuery.event.remove( elem, type );
|
|
|
|
// This is a shortcut to avoid jQuery.event.remove's overhead
|
|
} else {
|
|
jQuery.removeEvent( elem, type, data.handle );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Support: Chrome <=35 - 45+
|
|
// Assign undefined instead of using delete, see Data#remove
|
|
elem[ dataPriv.expando ] = undefined;
|
|
}
|
|
if ( elem[ dataUser.expando ] ) {
|
|
|
|
// Support: Chrome <=35 - 45+
|
|
// Assign undefined instead of using delete, see Data#remove
|
|
elem[ dataUser.expando ] = undefined;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} );
|
|
|
|
jQuery.fn.extend( {
|
|
detach: function( selector ) {
|
|
return remove( this, selector, true );
|
|
},
|
|
|
|
remove: function( selector ) {
|
|
return remove( this, selector );
|
|
},
|
|
|
|
text: function( value ) {
|
|
return access( this, function( value ) {
|
|
return value === undefined ?
|
|
jQuery.text( this ) :
|
|
this.empty().each( function() {
|
|
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
|
this.textContent = value;
|
|
}
|
|
} );
|
|
}, null, value, arguments.length );
|
|
},
|
|
|
|
append: function() {
|
|
return domManip( this, arguments, function( elem ) {
|
|
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
|
var target = manipulationTarget( this, elem );
|
|
target.appendChild( elem );
|
|
}
|
|
} );
|
|
},
|
|
|
|
prepend: function() {
|
|
return domManip( this, arguments, function( elem ) {
|
|
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
|
var target = manipulationTarget( this, elem );
|
|
target.insertBefore( elem, target.firstChild );
|
|
}
|
|
} );
|
|
},
|
|
|
|
before: function() {
|
|
return domManip( this, arguments, function( elem ) {
|
|
if ( this.parentNode ) {
|
|
this.parentNode.insertBefore( elem, this );
|
|
}
|
|
} );
|
|
},
|
|
|
|
after: function() {
|
|
return domManip( this, arguments, function( elem ) {
|
|
if ( this.parentNode ) {
|
|
this.parentNode.insertBefore( elem, this.nextSibling );
|
|
}
|
|
} );
|
|
},
|
|
|
|
empty: function() {
|
|
var elem,
|
|
i = 0;
|
|
|
|
for ( ; ( elem = this[ i ] ) != null; i++ ) {
|
|
if ( elem.nodeType === 1 ) {
|
|
|
|
// Prevent memory leaks
|
|
jQuery.cleanData( getAll( elem, false ) );
|
|
|
|
// Remove any remaining nodes
|
|
elem.textContent = "";
|
|
}
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
clone: function( dataAndEvents, deepDataAndEvents ) {
|
|
dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
|
|
deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
|
|
|
|
return this.map( function() {
|
|
return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
|
|
} );
|
|
},
|
|
|
|
html: function( value ) {
|
|
return access( this, function( value ) {
|
|
var elem = this[ 0 ] || {},
|
|
i = 0,
|
|
l = this.length;
|
|
|
|
if ( value === undefined && elem.nodeType === 1 ) {
|
|
return elem.innerHTML;
|
|
}
|
|
|
|
// See if we can take a shortcut and just use innerHTML
|
|
if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
|
|
!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
|
|
|
|
value = jQuery.htmlPrefilter( value );
|
|
|
|
try {
|
|
for ( ; i < l; i++ ) {
|
|
elem = this[ i ] || {};
|
|
|
|
// Remove element nodes and prevent memory leaks
|
|
if ( elem.nodeType === 1 ) {
|
|
jQuery.cleanData( getAll( elem, false ) );
|
|
elem.innerHTML = value;
|
|
}
|
|
}
|
|
|
|
elem = 0;
|
|
|
|
// If using innerHTML throws an exception, use the fallback method
|
|
} catch ( e ) {}
|
|
}
|
|
|
|
if ( elem ) {
|
|
this.empty().append( value );
|
|
}
|
|
}, null, value, arguments.length );
|
|
},
|
|
|
|
replaceWith: function() {
|
|
var ignored = [];
|
|
|
|
// Make the changes, replacing each non-ignored context element with the new content
|
|
return domManip( this, arguments, function( elem ) {
|
|
var parent = this.parentNode;
|
|
|
|
if ( jQuery.inArray( this, ignored ) < 0 ) {
|
|
jQuery.cleanData( getAll( this ) );
|
|
if ( parent ) {
|
|
parent.replaceChild( elem, this );
|
|
}
|
|
}
|
|
|
|
// Force callback invocation
|
|
}, ignored );
|
|
}
|
|
} );
|
|
|
|
jQuery.each( {
|
|
appendTo: "append",
|
|
prependTo: "prepend",
|
|
insertBefore: "before",
|
|
insertAfter: "after",
|
|
replaceAll: "replaceWith"
|
|
}, function( name, original ) {
|
|
jQuery.fn[ name ] = function( selector ) {
|
|
var elems,
|
|
ret = [],
|
|
insert = jQuery( selector ),
|
|
last = insert.length - 1,
|
|
i = 0;
|
|
|
|
for ( ; i <= last; i++ ) {
|
|
elems = i === last ? this : this.clone( true );
|
|
jQuery( insert[ i ] )[ original ]( elems );
|
|
|
|
// Support: Android <=4.0 only, PhantomJS 1 only
|
|
// .get() because push.apply(_, arraylike) throws on ancient WebKit
|
|
push.apply( ret, elems.get() );
|
|
}
|
|
|
|
return this.pushStack( ret );
|
|
};
|
|
} );
|
|
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
|
|
|
|
var getStyles = function( elem ) {
|
|
|
|
// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
|
|
// IE throws on elements created in popups
|
|
// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
|
|
var view = elem.ownerDocument.defaultView;
|
|
|
|
if ( !view || !view.opener ) {
|
|
view = window;
|
|
}
|
|
|
|
return view.getComputedStyle( elem );
|
|
};
|
|
|
|
var swap = function( elem, options, callback ) {
|
|
var ret, name,
|
|
old = {};
|
|
|
|
// Remember the old values, and insert the new ones
|
|
for ( name in options ) {
|
|
old[ name ] = elem.style[ name ];
|
|
elem.style[ name ] = options[ name ];
|
|
}
|
|
|
|
ret = callback.call( elem );
|
|
|
|
// Revert the old values
|
|
for ( name in options ) {
|
|
elem.style[ name ] = old[ name ];
|
|
}
|
|
|
|
return ret;
|
|
};
|
|
|
|
|
|
var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
|
|
|
|
|
|
|
|
( function() {
|
|
|
|
// Executing both pixelPosition & boxSizingReliable tests require only one layout
|
|
// so they're executed at the same time to save the second computation.
|
|
function computeStyleTests() {
|
|
|
|
// This is a singleton, we need to execute it only once
|
|
if ( !div ) {
|
|
return;
|
|
}
|
|
|
|
container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
|
|
"margin-top:1px;padding:0;border:0";
|
|
div.style.cssText =
|
|
"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
|
|
"margin:auto;border:1px;padding:1px;" +
|
|
"width:60%;top:1%";
|
|
documentElement.appendChild( container ).appendChild( div );
|
|
|
|
var divStyle = window.getComputedStyle( div );
|
|
pixelPositionVal = divStyle.top !== "1%";
|
|
|
|
// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
|
|
reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
|
|
|
|
// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
|
|
// Some styles come back with percentage values, even though they shouldn't
|
|
div.style.right = "60%";
|
|
pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
|
|
|
|
// Support: IE 9 - 11 only
|
|
// Detect misreporting of content dimensions for box-sizing:border-box elements
|
|
boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
|
|
|
|
// Support: IE 9 only
|
|
// Detect overflow:scroll screwiness (gh-3699)
|
|
// Support: Chrome <=64
|
|
// Don't get tricked when zoom affects offsetWidth (gh-4029)
|
|
div.style.position = "absolute";
|
|
scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
|
|
|
|
documentElement.removeChild( container );
|
|
|
|
// Nullify the div so it wouldn't be stored in the memory and
|
|
// it will also be a sign that checks already performed
|
|
div = null;
|
|
}
|
|
|
|
function roundPixelMeasures( measure ) {
|
|
return Math.round( parseFloat( measure ) );
|
|
}
|
|
|
|
var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
|
|
reliableTrDimensionsVal, reliableMarginLeftVal,
|
|
container = document.createElement( "div" ),
|
|
div = document.createElement( "div" );
|
|
|
|
// Finish early in limited (non-browser) environments
|
|
if ( !div.style ) {
|
|
return;
|
|
}
|
|
|
|
// Support: IE <=9 - 11 only
|
|
// Style of cloned element affects source element cloned (#8908)
|
|
div.style.backgroundClip = "content-box";
|
|
div.cloneNode( true ).style.backgroundClip = "";
|
|
support.clearCloneStyle = div.style.backgroundClip === "content-box";
|
|
|
|
jQuery.extend( support, {
|
|
boxSizingReliable: function() {
|
|
computeStyleTests();
|
|
return boxSizingReliableVal;
|
|
},
|
|
pixelBoxStyles: function() {
|
|
computeStyleTests();
|
|
return pixelBoxStylesVal;
|
|
},
|
|
pixelPosition: function() {
|
|
computeStyleTests();
|
|
return pixelPositionVal;
|
|
},
|
|
reliableMarginLeft: function() {
|
|
computeStyleTests();
|
|
return reliableMarginLeftVal;
|
|
},
|
|
scrollboxSize: function() {
|
|
computeStyleTests();
|
|
return scrollboxSizeVal;
|
|
},
|
|
|
|
// Support: IE 9 - 11+, Edge 15 - 18+
|
|
// IE/Edge misreport `getComputedStyle` of table rows with width/height
|
|
// set in CSS while `offset*` properties report correct values.
|
|
// Behavior in IE 9 is more subtle than in newer versions & it passes
|
|
// some versions of this test; make sure not to make it pass there!
|
|
//
|
|
// Support: Firefox 70+
|
|
// Only Firefox includes border widths
|
|
// in computed dimensions. (gh-4529)
|
|
reliableTrDimensions: function() {
|
|
var table, tr, trChild, trStyle;
|
|
if ( reliableTrDimensionsVal == null ) {
|
|
table = document.createElement( "table" );
|
|
tr = document.createElement( "tr" );
|
|
trChild = document.createElement( "div" );
|
|
|
|
table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
|
|
tr.style.cssText = "border:1px solid";
|
|
|
|
// Support: Chrome 86+
|
|
// Height set through cssText does not get applied.
|
|
// Computed height then comes back as 0.
|
|
tr.style.height = "1px";
|
|
trChild.style.height = "9px";
|
|
|
|
// Support: Android 8 Chrome 86+
|
|
// In our bodyBackground.html iframe,
|
|
// display for all div elements is set to "inline",
|
|
// which causes a problem only in Android 8 Chrome 86.
|
|
// Ensuring the div is display: block
|
|
// gets around this issue.
|
|
trChild.style.display = "block";
|
|
|
|
documentElement
|
|
.appendChild( table )
|
|
.appendChild( tr )
|
|
.appendChild( trChild );
|
|
|
|
trStyle = window.getComputedStyle( tr );
|
|
reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +
|
|
parseInt( trStyle.borderTopWidth, 10 ) +
|
|
parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;
|
|
|
|
documentElement.removeChild( table );
|
|
}
|
|
return reliableTrDimensionsVal;
|
|
}
|
|
} );
|
|
} )();
|
|
|
|
|
|
function curCSS( elem, name, computed ) {
|
|
var width, minWidth, maxWidth, ret,
|
|
|
|
// Support: Firefox 51+
|
|
// Retrieving style before computed somehow
|
|
// fixes an issue with getting wrong values
|
|
// on detached elements
|
|
style = elem.style;
|
|
|
|
computed = computed || getStyles( elem );
|
|
|
|
// getPropertyValue is needed for:
|
|
// .css('filter') (IE 9 only, #12537)
|
|
// .css('--customProperty) (#3144)
|
|
if ( computed ) {
|
|
ret = computed.getPropertyValue( name ) || computed[ name ];
|
|
|
|
if ( ret === "" && !isAttached( elem ) ) {
|
|
ret = jQuery.style( elem, name );
|
|
}
|
|
|
|
// A tribute to the "awesome hack by Dean Edwards"
|
|
// Android Browser returns percentage for some values,
|
|
// but width seems to be reliably pixels.
|
|
// This is against the CSSOM draft spec:
|
|
// https://drafts.csswg.org/cssom/#resolved-values
|
|
if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
|
|
|
|
// Remember the original values
|
|
width = style.width;
|
|
minWidth = style.minWidth;
|
|
maxWidth = style.maxWidth;
|
|
|
|
// Put in the new values to get a computed value out
|
|
style.minWidth = style.maxWidth = style.width = ret;
|
|
ret = computed.width;
|
|
|
|
// Revert the changed values
|
|
style.width = width;
|
|
style.minWidth = minWidth;
|
|
style.maxWidth = maxWidth;
|
|
}
|
|
}
|
|
|
|
return ret !== undefined ?
|
|
|
|
// Support: IE <=9 - 11 only
|
|
// IE returns zIndex value as an integer.
|
|
ret + "" :
|
|
ret;
|
|
}
|
|
|
|
|
|
function addGetHookIf( conditionFn, hookFn ) {
|
|
|
|
// Define the hook, we'll check on the first run if it's really needed.
|
|
return {
|
|
get: function() {
|
|
if ( conditionFn() ) {
|
|
|
|
// Hook not needed (or it's not possible to use it due
|
|
// to missing dependency), remove it.
|
|
delete this.get;
|
|
return;
|
|
}
|
|
|
|
// Hook needed; redefine it so that the support test is not executed again.
|
|
return ( this.get = hookFn ).apply( this, arguments );
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
var cssPrefixes = [ "Webkit", "Moz", "ms" ],
|
|
emptyStyle = document.createElement( "div" ).style,
|
|
vendorProps = {};
|
|
|
|
// Return a vendor-prefixed property or undefined
|
|
function vendorPropName( name ) {
|
|
|
|
// Check for vendor prefixed names
|
|
var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
|
|
i = cssPrefixes.length;
|
|
|
|
while ( i-- ) {
|
|
name = cssPrefixes[ i ] + capName;
|
|
if ( name in emptyStyle ) {
|
|
return name;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return a potentially-mapped jQuery.cssProps or vendor prefixed property
|
|
function finalPropName( name ) {
|
|
var final = jQuery.cssProps[ name ] || vendorProps[ name ];
|
|
|
|
if ( final ) {
|
|
return final;
|
|
}
|
|
if ( name in emptyStyle ) {
|
|
return name;
|
|
}
|
|
return vendorProps[ name ] = vendorPropName( name ) || name;
|
|
}
|
|
|
|
|
|
var
|
|
|
|
// Swappable if display is none or starts with table
|
|
// except "table", "table-cell", or "table-caption"
|
|
// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
|
|
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
|
|
rcustomProp = /^--/,
|
|
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
|
|
cssNormalTransform = {
|
|
letterSpacing: "0",
|
|
fontWeight: "400"
|
|
};
|
|
|
|
function setPositiveNumber( _elem, value, subtract ) {
|
|
|
|
// Any relative (+/-) values have already been
|
|
// normalized at this point
|
|
var matches = rcssNum.exec( value );
|
|
return matches ?
|
|
|
|
// Guard against undefined "subtract", e.g., when used as in cssHooks
|
|
Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
|
|
value;
|
|
}
|
|
|
|
function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
|
|
var i = dimension === "width" ? 1 : 0,
|
|
extra = 0,
|
|
delta = 0;
|
|
|
|
// Adjustment may not be necessary
|
|
if ( box === ( isBorderBox ? "border" : "content" ) ) {
|
|
return 0;
|
|
}
|
|
|
|
for ( ; i < 4; i += 2 ) {
|
|
|
|
// Both box models exclude margin
|
|
if ( box === "margin" ) {
|
|
delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
|
|
}
|
|
|
|
// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
|
|
if ( !isBorderBox ) {
|
|
|
|
// Add padding
|
|
delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
|
|
|
|
// For "border" or "margin", add border
|
|
if ( box !== "padding" ) {
|
|
delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
|
|
|
|
// But still keep track of it otherwise
|
|
} else {
|
|
extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
|
|
}
|
|
|
|
// If we get here with a border-box (content + padding + border), we're seeking "content" or
|
|
// "padding" or "margin"
|
|
} else {
|
|
|
|
// For "content", subtract padding
|
|
if ( box === "content" ) {
|
|
delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
|
|
}
|
|
|
|
// For "content" or "padding", subtract border
|
|
if ( box !== "margin" ) {
|
|
delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Account for positive content-box scroll gutter when requested by providing computedVal
|
|
if ( !isBorderBox && computedVal >= 0 ) {
|
|
|
|
// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
|
|
// Assuming integer scroll gutter, subtract the rest and round down
|
|
delta += Math.max( 0, Math.ceil(
|
|
elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
|
|
computedVal -
|
|
delta -
|
|
extra -
|
|
0.5
|
|
|
|
// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
|
|
// Use an explicit zero to avoid NaN (gh-3964)
|
|
) ) || 0;
|
|
}
|
|
|
|
return delta;
|
|
}
|
|
|
|
function getWidthOrHeight( elem, dimension, extra ) {
|
|
|
|
// Start with computed style
|
|
var styles = getStyles( elem ),
|
|
|
|
// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
|
|
// Fake content-box until we know it's needed to know the true value.
|
|
boxSizingNeeded = !support.boxSizingReliable() || extra,
|
|
isBorderBox = boxSizingNeeded &&
|
|
jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
|
|
valueIsBorderBox = isBorderBox,
|
|
|
|
val = curCSS( elem, dimension, styles ),
|
|
offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
|
|
|
|
// Support: Firefox <=54
|
|
// Return a confounding non-pixel value or feign ignorance, as appropriate.
|
|
if ( rnumnonpx.test( val ) ) {
|
|
if ( !extra ) {
|
|
return val;
|
|
}
|
|
val = "auto";
|
|
}
|
|
|
|
|
|
// Support: IE 9 - 11 only
|
|
// Use offsetWidth/offsetHeight for when box sizing is unreliable.
|
|
// In those cases, the computed value can be trusted to be border-box.
|
|
if ( ( !support.boxSizingReliable() && isBorderBox ||
|
|
|
|
// Support: IE 10 - 11+, Edge 15 - 18+
|
|
// IE/Edge misreport `getComputedStyle` of table rows with width/height
|
|
// set in CSS while `offset*` properties report correct values.
|
|
// Interestingly, in some cases IE 9 doesn't suffer from this issue.
|
|
!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
|
|
|
|
// Fall back to offsetWidth/offsetHeight when value is "auto"
|
|
// This happens for inline elements with no explicit setting (gh-3571)
|
|
val === "auto" ||
|
|
|
|
// Support: Android <=4.1 - 4.3 only
|
|
// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
|
|
!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
|
|
|
|
// Make sure the element is visible & connected
|
|
elem.getClientRects().length ) {
|
|
|
|
isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
|
|
|
|
// Where available, offsetWidth/offsetHeight approximate border box dimensions.
|
|
// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
|
|
// retrieved value as a content box dimension.
|
|
valueIsBorderBox = offsetProp in elem;
|
|
if ( valueIsBorderBox ) {
|
|
val = elem[ offsetProp ];
|
|
}
|
|
}
|
|
|
|
// Normalize "" and auto
|
|
val = parseFloat( val ) || 0;
|
|
|
|
// Adjust for the element's box model
|
|
return ( val +
|
|
boxModelAdjustment(
|
|
elem,
|
|
dimension,
|
|
extra || ( isBorderBox ? "border" : "content" ),
|
|
valueIsBorderBox,
|
|
styles,
|
|
|
|
// Provide the current computed size to request scroll gutter calculation (gh-3589)
|
|
val
|
|
)
|
|
) + "px";
|
|
}
|
|
|
|
jQuery.extend( {
|
|
|
|
// Add in style property hooks for overriding the default
|
|
// behavior of getting and setting a style property
|
|
cssHooks: {
|
|
opacity: {
|
|
get: function( elem, computed ) {
|
|
if ( computed ) {
|
|
|
|
// We should always get a number back from opacity
|
|
var ret = curCSS( elem, "opacity" );
|
|
return ret === "" ? "1" : ret;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
// Don't automatically add "px" to these possibly-unitless properties
|
|
cssNumber: {
|
|
"animationIterationCount": true,
|
|
"columnCount": true,
|
|
"fillOpacity": true,
|
|
"flexGrow": true,
|
|
"flexShrink": true,
|
|
"fontWeight": true,
|
|
"gridArea": true,
|
|
"gridColumn": true,
|
|
"gridColumnEnd": true,
|
|
"gridColumnStart": true,
|
|
"gridRow": true,
|
|
"gridRowEnd": true,
|
|
"gridRowStart": true,
|
|
"lineHeight": true,
|
|
"opacity": true,
|
|
"order": true,
|
|
"orphans": true,
|
|
"widows": true,
|
|
"zIndex": true,
|
|
"zoom": true
|
|
},
|
|
|
|
// Add in properties whose names you wish to fix before
|
|
// setting or getting the value
|
|
cssProps: {},
|
|
|
|
// Get and set the style property on a DOM Node
|
|
style: function( elem, name, value, extra ) {
|
|
|
|
// Don't set styles on text and comment nodes
|
|
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
|
|
return;
|
|
}
|
|
|
|
// Make sure that we're working with the right name
|
|
var ret, type, hooks,
|
|
origName = camelCase( name ),
|
|
isCustomProp = rcustomProp.test( name ),
|
|
style = elem.style;
|
|
|
|
// Make sure that we're working with the right name. We don't
|
|
// want to query the value if it is a CSS custom property
|
|
// since they are user-defined.
|
|
if ( !isCustomProp ) {
|
|
name = finalPropName( origName );
|
|
}
|
|
|
|
// Gets hook for the prefixed version, then unprefixed version
|
|
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
|
|
|
// Check if we're setting a value
|
|
if ( value !== undefined ) {
|
|
type = typeof value;
|
|
|
|
// Convert "+=" or "-=" to relative numbers (#7345)
|
|
if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
|
|
value = adjustCSS( elem, name, ret );
|
|
|
|
// Fixes bug #9237
|
|
type = "number";
|
|
}
|
|
|
|
// Make sure that null and NaN values aren't set (#7116)
|
|
if ( value == null || value !== value ) {
|
|
return;
|
|
}
|
|
|
|
// If a number was passed in, add the unit (except for certain CSS properties)
|
|
// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
|
|
// "px" to a few hardcoded values.
|
|
if ( type === "number" && !isCustomProp ) {
|
|
value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
|
|
}
|
|
|
|
// background-* props affect original clone's values
|
|
if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
|
|
style[ name ] = "inherit";
|
|
}
|
|
|
|
// If a hook was provided, use that value, otherwise just set the specified value
|
|
if ( !hooks || !( "set" in hooks ) ||
|
|
( value = hooks.set( elem, value, extra ) ) !== undefined ) {
|
|
|
|
if ( isCustomProp ) {
|
|
style.setProperty( name, value );
|
|
} else {
|
|
style[ name ] = value;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
// If a hook was provided get the non-computed value from there
|
|
if ( hooks && "get" in hooks &&
|
|
( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Otherwise just get the value from the style object
|
|
return style[ name ];
|
|
}
|
|
},
|
|
|
|
css: function( elem, name, extra, styles ) {
|
|
var val, num, hooks,
|
|
origName = camelCase( name ),
|
|
isCustomProp = rcustomProp.test( name );
|
|
|
|
// Make sure that we're working with the right name. We don't
|
|
// want to modify the value if it is a CSS custom property
|
|
// since they are user-defined.
|
|
if ( !isCustomProp ) {
|
|
name = finalPropName( origName );
|
|
}
|
|
|
|
// Try prefixed name followed by the unprefixed name
|
|
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
|
|
|
// If a hook was provided get the computed value from there
|
|
if ( hooks && "get" in hooks ) {
|
|
val = hooks.get( elem, true, extra );
|
|
}
|
|
|
|
// Otherwise, if a way to get the computed value exists, use that
|
|
if ( val === undefined ) {
|
|
val = curCSS( elem, name, styles );
|
|
}
|
|
|
|
// Convert "normal" to computed value
|
|
if ( val === "normal" && name in cssNormalTransform ) {
|
|
val = cssNormalTransform[ name ];
|
|
}
|
|
|
|
// Make numeric if forced or a qualifier was provided and val looks numeric
|
|
if ( extra === "" || extra ) {
|
|
num = parseFloat( val );
|
|
return extra === true || isFinite( num ) ? num || 0 : val;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
} );
|
|
|
|
jQuery.each( [ "height", "width" ], function( _i, dimension ) {
|
|
jQuery.cssHooks[ dimension ] = {
|
|
get: function( elem, computed, extra ) {
|
|
if ( computed ) {
|
|
|
|
// Certain elements can have dimension info if we invisibly show them
|
|
// but it must have a current display style that would benefit
|
|
return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
|
|
|
|
// Support: Safari 8+
|
|
// Table columns in Safari have non-zero offsetWidth & zero
|
|
// getBoundingClientRect().width unless display is changed.
|
|
// Support: IE <=11 only
|
|
// Running getBoundingClientRect on a disconnected node
|
|
// in IE throws an error.
|
|
( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
|
|
swap( elem, cssShow, function() {
|
|
return getWidthOrHeight( elem, dimension, extra );
|
|
} ) :
|
|
getWidthOrHeight( elem, dimension, extra );
|
|
}
|
|
},
|
|
|
|
set: function( elem, value, extra ) {
|
|
var matches,
|
|
styles = getStyles( elem ),
|
|
|
|
// Only read styles.position if the test has a chance to fail
|
|
// to avoid forcing a reflow.
|
|
scrollboxSizeBuggy = !support.scrollboxSize() &&
|
|
styles.position === "absolute",
|
|
|
|
// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
|
|
boxSizingNeeded = scrollboxSizeBuggy || extra,
|
|
isBorderBox = boxSizingNeeded &&
|
|
jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
|
|
subtract = extra ?
|
|
boxModelAdjustment(
|
|
elem,
|
|
dimension,
|
|
extra,
|
|
isBorderBox,
|
|
styles
|
|
) :
|
|
0;
|
|
|
|
// Account for unreliable border-box dimensions by comparing offset* to computed and
|
|
// faking a content-box to get border and padding (gh-3699)
|
|
if ( isBorderBox && scrollboxSizeBuggy ) {
|
|
subtract -= Math.ceil(
|
|
elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
|
|
parseFloat( styles[ dimension ] ) -
|
|
boxModelAdjustment( elem, dimension, "border", false, styles ) -
|
|
0.5
|
|
);
|
|
}
|
|
|
|
// Convert to pixels if value adjustment is needed
|
|
if ( subtract && ( matches = rcssNum.exec( value ) ) &&
|
|
( matches[ 3 ] || "px" ) !== "px" ) {
|
|
|
|
elem.style[ dimension ] = value;
|
|
value = jQuery.css( elem, dimension );
|
|
}
|
|
|
|
return setPositiveNumber( elem, value, subtract );
|
|
}
|
|
};
|
|
} );
|
|
|
|
jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
|
|
function( elem, computed ) {
|
|
if ( computed ) {
|
|
return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
|
|
elem.getBoundingClientRect().left -
|
|
swap( elem, { marginLeft: 0 }, function() {
|
|
return elem.getBoundingClientRect().left;
|
|
} )
|
|
) + "px";
|
|
}
|
|
}
|
|
);
|
|
|
|
// These hooks are used by animate to expand properties
|
|
jQuery.each( {
|
|
margin: "",
|
|
padding: "",
|
|
border: "Width"
|
|
}, function( prefix, suffix ) {
|
|
jQuery.cssHooks[ prefix + suffix ] = {
|
|
expand: function( value ) {
|
|
var i = 0,
|
|
expanded = {},
|
|
|
|
// Assumes a single number if not a string
|
|
parts = typeof value === "string" ? value.split( " " ) : [ value ];
|
|
|
|
for ( ; i < 4; i++ ) {
|
|
expanded[ prefix + cssExpand[ i ] + suffix ] =
|
|
parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
|
|
}
|
|
|
|
return expanded;
|
|
}
|
|
};
|
|
|
|
if ( prefix !== "margin" ) {
|
|
jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
|
|
}
|
|
} );
|
|
|
|
jQuery.fn.extend( {
|
|
css: function( name, value ) {
|
|
return access( this, function( elem, name, value ) {
|
|
var styles, len,
|
|
map = {},
|
|
i = 0;
|
|
|
|
if ( Array.isArray( name ) ) {
|
|
styles = getStyles( elem );
|
|
len = name.length;
|
|
|
|
for ( ; i < len; i++ ) {
|
|
map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
|
|
}
|
|
|
|
return map;
|
|
}
|
|
|
|
return value !== undefined ?
|
|
jQuery.style( elem, name, value ) :
|
|
jQuery.css( elem, name );
|
|
}, name, value, arguments.length > 1 );
|
|
}
|
|
} );
|
|
|
|
|
|
function Tween( elem, options, prop, end, easing ) {
|
|
return new Tween.prototype.init( elem, options, prop, end, easing );
|
|
}
|
|
jQuery.Tween = Tween;
|
|
|
|
Tween.prototype = {
|
|
constructor: Tween,
|
|
init: function( elem, options, prop, end, easing, unit ) {
|
|
this.elem = elem;
|
|
this.prop = prop;
|
|
this.easing = easing || jQuery.easing._default;
|
|
this.options = options;
|
|
this.start = this.now = this.cur();
|
|
this.end = end;
|
|
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
|
|
},
|
|
cur: function() {
|
|
var hooks = Tween.propHooks[ this.prop ];
|
|
|
|
return hooks && hooks.get ?
|
|
hooks.get( this ) :
|
|
Tween.propHooks._default.get( this );
|
|
},
|
|
run: function( percent ) {
|
|
var eased,
|
|
hooks = Tween.propHooks[ this.prop ];
|
|
|
|
if ( this.options.duration ) {
|
|
this.pos = eased = jQuery.easing[ this.easing ](
|
|
percent, this.options.duration * percent, 0, 1, this.options.duration
|
|
);
|
|
} else {
|
|
this.pos = eased = percent;
|
|
}
|
|
this.now = ( this.end - this.start ) * eased + this.start;
|
|
|
|
if ( this.options.step ) {
|
|
this.options.step.call( this.elem, this.now, this );
|
|
}
|
|
|
|
if ( hooks && hooks.set ) {
|
|
hooks.set( this );
|
|
} else {
|
|
Tween.propHooks._default.set( this );
|
|
}
|
|
return this;
|
|
}
|
|
};
|
|
|
|
Tween.prototype.init.prototype = Tween.prototype;
|
|
|
|
Tween.propHooks = {
|
|
_default: {
|
|
get: function( tween ) {
|
|
var result;
|
|
|
|
// Use a property on the element directly when it is not a DOM element,
|
|
// or when there is no matching style property that exists.
|
|
if ( tween.elem.nodeType !== 1 ||
|
|
tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
|
|
return tween.elem[ tween.prop ];
|
|
}
|
|
|
|
// Passing an empty string as a 3rd parameter to .css will automatically
|
|
// attempt a parseFloat and fallback to a string if the parse fails.
|
|
// Simple values such as "10px" are parsed to Float;
|
|
// complex values such as "rotate(1rad)" are returned as-is.
|
|
result = jQuery.css( tween.elem, tween.prop, "" );
|
|
|
|
// Empty strings, null, undefined and "auto" are converted to 0.
|
|
return !result || result === "auto" ? 0 : result;
|
|
},
|
|
set: function( tween ) {
|
|
|
|
// Use step hook for back compat.
|
|
// Use cssHook if its there.
|
|
// Use .style if available and use plain properties where available.
|
|
if ( jQuery.fx.step[ tween.prop ] ) {
|
|
jQuery.fx.step[ tween.prop ]( tween );
|
|
} else if ( tween.elem.nodeType === 1 && (
|
|
jQuery.cssHooks[ tween.prop ] ||
|
|
tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
|
|
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
|
|
} else {
|
|
tween.elem[ tween.prop ] = tween.now;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// Support: IE <=9 only
|
|
// Panic based approach to setting things on disconnected nodes
|
|
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
|
|
set: function( tween ) {
|
|
if ( tween.elem.nodeType && tween.elem.parentNode ) {
|
|
tween.elem[ tween.prop ] = tween.now;
|
|
}
|
|
}
|
|
};
|
|
|
|
jQuery.easing = {
|
|
linear: function( p ) {
|
|
return p;
|
|
},
|
|
swing: function( p ) {
|
|
return 0.5 - Math.cos( p * Math.PI ) / 2;
|
|
},
|
|
_default: "swing"
|
|
};
|
|
|
|
jQuery.fx = Tween.prototype.init;
|
|
|
|
// Back compat <1.8 extension point
|
|
jQuery.fx.step = {};
|
|
|
|
|
|
|
|
|
|
var
|
|
fxNow, inProgress,
|
|
rfxtypes = /^(?:toggle|show|hide)$/,
|
|
rrun = /queueHooks$/;
|
|
|
|
function schedule() {
|
|
if ( inProgress ) {
|
|
if ( document.hidden === false && window.requestAnimationFrame ) {
|
|
window.requestAnimationFrame( schedule );
|
|
} else {
|
|
window.setTimeout( schedule, jQuery.fx.interval );
|
|
}
|
|
|
|
jQuery.fx.tick();
|
|
}
|
|
}
|
|
|
|
// Animations created synchronously will run synchronously
|
|
function createFxNow() {
|
|
window.setTimeout( function() {
|
|
fxNow = undefined;
|
|
} );
|
|
return ( fxNow = Date.now() );
|
|
}
|
|
|
|
// Generate parameters to create a standard animation
|
|
function genFx( type, includeWidth ) {
|
|
var which,
|
|
i = 0,
|
|
attrs = { height: type };
|
|
|
|
// If we include width, step value is 1 to do all cssExpand values,
|
|
// otherwise step value is 2 to skip over Left and Right
|
|
includeWidth = includeWidth ? 1 : 0;
|
|
for ( ; i < 4; i += 2 - includeWidth ) {
|
|
which = cssExpand[ i ];
|
|
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
|
|
}
|
|
|
|
if ( includeWidth ) {
|
|
attrs.opacity = attrs.width = type;
|
|
}
|
|
|
|
return attrs;
|
|
}
|
|
|
|
function createTween( value, prop, animation ) {
|
|
var tween,
|
|
collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
|
|
index = 0,
|
|
length = collection.length;
|
|
for ( ; index < length; index++ ) {
|
|
if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
|
|
|
|
// We're done with this property
|
|
return tween;
|
|
}
|
|
}
|
|
}
|
|
|
|
function defaultPrefilter( elem, props, opts ) {
|
|
var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
|
|
isBox = "width" in props || "height" in props,
|
|
anim = this,
|
|
orig = {},
|
|
style = elem.style,
|
|
hidden = elem.nodeType && isHiddenWithinTree( elem ),
|
|
dataShow = dataPriv.get( elem, "fxshow" );
|
|
|
|
// Queue-skipping animations hijack the fx hooks
|
|
if ( !opts.queue ) {
|
|
hooks = jQuery._queueHooks( elem, "fx" );
|
|
if ( hooks.unqueued == null ) {
|
|
hooks.unqueued = 0;
|
|
oldfire = hooks.empty.fire;
|
|
hooks.empty.fire = function() {
|
|
if ( !hooks.unqueued ) {
|
|
oldfire();
|
|
}
|
|
};
|
|
}
|
|
hooks.unqueued++;
|
|
|
|
anim.always( function() {
|
|
|
|
// Ensure the complete handler is called before this completes
|
|
anim.always( function() {
|
|
hooks.unqueued--;
|
|
if ( !jQuery.queue( elem, "fx" ).length ) {
|
|
hooks.empty.fire();
|
|
}
|
|
} );
|
|
} );
|
|
}
|
|
|
|
// Detect show/hide animations
|
|
for ( prop in props ) {
|
|
value = props[ prop ];
|
|
if ( rfxtypes.test( value ) ) {
|
|
delete props[ prop ];
|
|
toggle = toggle || value === "toggle";
|
|
if ( value === ( hidden ? "hide" : "show" ) ) {
|
|
|
|
// Pretend to be hidden if this is a "show" and
|
|
// there is still data from a stopped show/hide
|
|
if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
|
|
hidden = true;
|
|
|
|
// Ignore all other no-op show/hide data
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
|
|
}
|
|
}
|
|
|
|
// Bail out if this is a no-op like .hide().hide()
|
|
propTween = !jQuery.isEmptyObject( props );
|
|
if ( !propTween && jQuery.isEmptyObject( orig ) ) {
|
|
return;
|
|
}
|
|
|
|
// Restrict "overflow" and "display" styles during box animations
|
|
if ( isBox && elem.nodeType === 1 ) {
|
|
|
|
// Support: IE <=9 - 11, Edge 12 - 15
|
|
// Record all 3 overflow attributes because IE does not infer the shorthand
|
|
// from identically-valued overflowX and overflowY and Edge just mirrors
|
|
// the overflowX value there.
|
|
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
|
|
|
|
// Identify a display type, preferring old show/hide data over the CSS cascade
|
|
restoreDisplay = dataShow && dataShow.display;
|
|
if ( restoreDisplay == null ) {
|
|
restoreDisplay = dataPriv.get( elem, "display" );
|
|
}
|
|
display = jQuery.css( elem, "display" );
|
|
if ( display === "none" ) {
|
|
if ( restoreDisplay ) {
|
|
display = restoreDisplay;
|
|
} else {
|
|
|
|
// Get nonempty value(s) by temporarily forcing visibility
|
|
showHide( [ elem ], true );
|
|
restoreDisplay = elem.style.display || restoreDisplay;
|
|
display = jQuery.css( elem, "display" );
|
|
showHide( [ elem ] );
|
|
}
|
|
}
|
|
|
|
// Animate inline elements as inline-block
|
|
if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
|
|
if ( jQuery.css( elem, "float" ) === "none" ) {
|
|
|
|
// Restore the original display value at the end of pure show/hide animations
|
|
if ( !propTween ) {
|
|
anim.done( function() {
|
|
style.display = restoreDisplay;
|
|
} );
|
|
if ( restoreDisplay == null ) {
|
|
display = style.display;
|
|
restoreDisplay = display === "none" ? "" : display;
|
|
}
|
|
}
|
|
style.display = "inline-block";
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( opts.overflow ) {
|
|
style.overflow = "hidden";
|
|
anim.always( function() {
|
|
style.overflow = opts.overflow[ 0 ];
|
|
style.overflowX = opts.overflow[ 1 ];
|
|
style.overflowY = opts.overflow[ 2 ];
|
|
} );
|
|
}
|
|
|
|
// Implement show/hide animations
|
|
propTween = false;
|
|
for ( prop in orig ) {
|
|
|
|
// General show/hide setup for this element animation
|
|
if ( !propTween ) {
|
|
if ( dataShow ) {
|
|
if ( "hidden" in dataShow ) {
|
|
hidden = dataShow.hidden;
|
|
}
|
|
} else {
|
|
dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
|
|
}
|
|
|
|
// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
|
|
if ( toggle ) {
|
|
dataShow.hidden = !hidden;
|
|
}
|
|
|
|
// Show elements before animating them
|
|
if ( hidden ) {
|
|
showHide( [ elem ], true );
|
|
}
|
|
|
|
/* eslint-disable no-loop-func */
|
|
|
|
anim.done( function() {
|
|
|
|
/* eslint-enable no-loop-func */
|
|
|
|
// The final step of a "hide" animation is actually hiding the element
|
|
if ( !hidden ) {
|
|
showHide( [ elem ] );
|
|
}
|
|
dataPriv.remove( elem, "fxshow" );
|
|
for ( prop in orig ) {
|
|
jQuery.style( elem, prop, orig[ prop ] );
|
|
}
|
|
} );
|
|
}
|
|
|
|
// Per-property setup
|
|
propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
|
|
if ( !( prop in dataShow ) ) {
|
|
dataShow[ prop ] = propTween.start;
|
|
if ( hidden ) {
|
|
propTween.end = propTween.start;
|
|
propTween.start = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function propFilter( props, specialEasing ) {
|
|
var index, name, easing, value, hooks;
|
|
|
|
// camelCase, specialEasing and expand cssHook pass
|
|
for ( index in props ) {
|
|
name = camelCase( index );
|
|
easing = specialEasing[ name ];
|
|
value = props[ index ];
|
|
if ( Array.isArray( value ) ) {
|
|
easing = value[ 1 ];
|
|
value = props[ index ] = value[ 0 ];
|
|
}
|
|
|
|
if ( index !== name ) {
|
|
props[ name ] = value;
|
|
delete props[ index ];
|
|
}
|
|
|
|
hooks = jQuery.cssHooks[ name ];
|
|
if ( hooks && "expand" in hooks ) {
|
|
value = hooks.expand( value );
|
|
delete props[ name ];
|
|
|
|
// Not quite $.extend, this won't overwrite existing keys.
|
|
// Reusing 'index' because we have the correct "name"
|
|
for ( index in value ) {
|
|
if ( !( index in props ) ) {
|
|
props[ index ] = value[ index ];
|
|
specialEasing[ index ] = easing;
|
|
}
|
|
}
|
|
} else {
|
|
specialEasing[ name ] = easing;
|
|
}
|
|
}
|
|
}
|
|
|
|
function Animation( elem, properties, options ) {
|
|
var result,
|
|
stopped,
|
|
index = 0,
|
|
length = Animation.prefilters.length,
|
|
deferred = jQuery.Deferred().always( function() {
|
|
|
|
// Don't match elem in the :animated selector
|
|
delete tick.elem;
|
|
} ),
|
|
tick = function() {
|
|
if ( stopped ) {
|
|
return false;
|
|
}
|
|
var currentTime = fxNow || createFxNow(),
|
|
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
|
|
|
|
// Support: Android 2.3 only
|
|
// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
|
|
temp = remaining / animation.duration || 0,
|
|
percent = 1 - temp,
|
|
index = 0,
|
|
length = animation.tweens.length;
|
|
|
|
for ( ; index < length; index++ ) {
|
|
animation.tweens[ index ].run( percent );
|
|
}
|
|
|
|
deferred.notifyWith( elem, [ animation, percent, remaining ] );
|
|
|
|
// If there's more to do, yield
|
|
if ( percent < 1 && length ) {
|
|
return remaining;
|
|
}
|
|
|
|
// If this was an empty animation, synthesize a final progress notification
|
|
if ( !length ) {
|
|
deferred.notifyWith( elem, [ animation, 1, 0 ] );
|
|
}
|
|
|
|
// Resolve the animation and report its conclusion
|
|
deferred.resolveWith( elem, [ animation ] );
|
|
return false;
|
|
},
|
|
animation = deferred.promise( {
|
|
elem: elem,
|
|
props: jQuery.extend( {}, properties ),
|
|
opts: jQuery.extend( true, {
|
|
specialEasing: {},
|
|
easing: jQuery.easing._default
|
|
}, options ),
|
|
originalProperties: properties,
|
|
originalOptions: options,
|
|
startTime: fxNow || createFxNow(),
|
|
duration: options.duration,
|
|
tweens: [],
|
|
createTween: function( prop, end ) {
|
|
var tween = jQuery.Tween( elem, animation.opts, prop, end,
|
|
animation.opts.specialEasing[ prop ] || animation.opts.easing );
|
|
animation.tweens.push( tween );
|
|
return tween;
|
|
},
|
|
stop: function( gotoEnd ) {
|
|
var index = 0,
|
|
|
|
// If we are going to the end, we want to run all the tweens
|
|
// otherwise we skip this part
|
|
length = gotoEnd ? animation.tweens.length : 0;
|
|
if ( stopped ) {
|
|
return this;
|
|
}
|
|
stopped = true;
|
|
for ( ; index < length; index++ ) {
|
|
animation.tweens[ index ].run( 1 );
|
|
}
|
|
|
|
// Resolve when we played the last frame; otherwise, reject
|
|
if ( gotoEnd ) {
|
|
deferred.notifyWith( elem, [ animation, 1, 0 ] );
|
|
deferred.resolveWith( elem, [ animation, gotoEnd ] );
|
|
} else {
|
|
deferred.rejectWith( elem, [ animation, gotoEnd ] );
|
|
}
|
|
return this;
|
|
}
|
|
} ),
|
|
props = animation.props;
|
|
|
|
propFilter( props, animation.opts.specialEasing );
|
|
|
|
for ( ; index < length; index++ ) {
|
|
result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
|
|
if ( result ) {
|
|
if ( isFunction( result.stop ) ) {
|
|
jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
|
|
result.stop.bind( result );
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
jQuery.map( props, createTween, animation );
|
|
|
|
if ( isFunction( animation.opts.start ) ) {
|
|
animation.opts.start.call( elem, animation );
|
|
}
|
|
|
|
// Attach callbacks from options
|
|
animation
|
|
.progress( animation.opts.progress )
|
|
.done( animation.opts.done, animation.opts.complete )
|
|
.fail( animation.opts.fail )
|
|
.always( animation.opts.always );
|
|
|
|
jQuery.fx.timer(
|
|
jQuery.extend( tick, {
|
|
elem: elem,
|
|
anim: animation,
|
|
queue: animation.opts.queue
|
|
} )
|
|
);
|
|
|
|
return animation;
|
|
}
|
|
|
|
jQuery.Animation = jQuery.extend( Animation, {
|
|
|
|
tweeners: {
|
|
"*": [ function( prop, value ) {
|
|
var tween = this.createTween( prop, value );
|
|
adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
|
|
return tween;
|
|
} ]
|
|
},
|
|
|
|
tweener: function( props, callback ) {
|
|
if ( isFunction( props ) ) {
|
|
callback = props;
|
|
props = [ "*" ];
|
|
} else {
|
|
props = props.match( rnothtmlwhite );
|
|
}
|
|
|
|
var prop,
|
|
index = 0,
|
|
length = props.length;
|
|
|
|
for ( ; index < length; index++ ) {
|
|
prop = props[ index ];
|
|
Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
|
|
Animation.tweeners[ prop ].unshift( callback );
|
|
}
|
|
},
|
|
|
|
prefilters: [ defaultPrefilter ],
|
|
|
|
prefilter: function( callback, prepend ) {
|
|
if ( prepend ) {
|
|
Animation.prefilters.unshift( callback );
|
|
} else {
|
|
Animation.prefilters.push( callback );
|
|
}
|
|
}
|
|
} );
|
|
|
|
jQuery.speed = function( speed, easing, fn ) {
|
|
var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
|
|
complete: fn || !fn && easing ||
|
|
isFunction( speed ) && speed,
|
|
duration: speed,
|
|
easing: fn && easing || easing && !isFunction( easing ) && easing
|
|
};
|
|
|
|
// Go to the end state if fx are off
|
|
if ( jQuery.fx.off ) {
|
|
opt.duration = 0;
|
|
|
|
} else {
|
|
if ( typeof opt.duration !== "number" ) {
|
|
if ( opt.duration in jQuery.fx.speeds ) {
|
|
opt.duration = jQuery.fx.speeds[ opt.duration ];
|
|
|
|
} else {
|
|
opt.duration = jQuery.fx.speeds._default;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Normalize opt.queue - true/undefined/null -> "fx"
|
|
if ( opt.queue == null || opt.queue === true ) {
|
|
opt.queue = "fx";
|
|
}
|
|
|
|
// Queueing
|
|
opt.old = opt.complete;
|
|
|
|
opt.complete = function() {
|
|
if ( isFunction( opt.old ) ) {
|
|
opt.old.call( this );
|
|
}
|
|
|
|
if ( opt.queue ) {
|
|
jQuery.dequeue( this, opt.queue );
|
|
}
|
|
};
|
|
|
|
return opt;
|
|
};
|
|
|
|
jQuery.fn.extend( {
|
|
fadeTo: function( speed, to, easing, callback ) {
|
|
|
|
// Show any hidden elements after setting opacity to 0
|
|
return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
|
|
|
|
// Animate to the value specified
|
|
.end().animate( { opacity: to }, speed, easing, callback );
|
|
},
|
|
animate: function( prop, speed, easing, callback ) {
|
|
var empty = jQuery.isEmptyObject( prop ),
|
|
optall = jQuery.speed( speed, easing, callback ),
|
|
doAnimation = function() {
|
|
|
|
// Operate on a copy of prop so per-property easing won't be lost
|
|
var anim = Animation( this, jQuery.extend( {}, prop ), optall );
|
|
|
|
// Empty animations, or finishing resolves immediately
|
|
if ( empty || dataPriv.get( this, "finish" ) ) {
|
|
anim.stop( true );
|
|
}
|
|
};
|
|
|
|
doAnimation.finish = doAnimation;
|
|
|
|
return empty || optall.queue === false ?
|
|
this.each( doAnimation ) :
|
|
this.queue( optall.queue, doAnimation );
|
|
},
|
|
stop: function( type, clearQueue, gotoEnd ) {
|
|
var stopQueue = function( hooks ) {
|
|
var stop = hooks.stop;
|
|
delete hooks.stop;
|
|
stop( gotoEnd );
|
|
};
|
|
|
|
if ( typeof type !== "string" ) {
|
|
gotoEnd = clearQueue;
|
|
clearQueue = type;
|
|
type = undefined;
|
|
}
|
|
if ( clearQueue ) {
|
|
this.queue( type || "fx", [] );
|
|
}
|
|
|
|
return this.each( function() {
|
|
var dequeue = true,
|
|
index = type != null && type + "queueHooks",
|
|
timers = jQuery.timers,
|
|
data = dataPriv.get( this );
|
|
|
|
if ( index ) {
|
|
if ( data[ index ] && data[ index ].stop ) {
|
|
stopQueue( data[ index ] );
|
|
}
|
|
} else {
|
|
for ( index in data ) {
|
|
if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
|
|
stopQueue( data[ index ] );
|
|
}
|
|
}
|
|
}
|
|
|
|
for ( index = timers.length; index--; ) {
|
|
if ( timers[ index ].elem === this &&
|
|
( type == null || timers[ index ].queue === type ) ) {
|
|
|
|
timers[ index ].anim.stop( gotoEnd );
|
|
dequeue = false;
|
|
timers.splice( index, 1 );
|
|
}
|
|
}
|
|
|
|
// Start the next in the queue if the last step wasn't forced.
|
|
// Timers currently will call their complete callbacks, which
|
|
// will dequeue but only if they were gotoEnd.
|
|
if ( dequeue || !gotoEnd ) {
|
|
jQuery.dequeue( this, type );
|
|
}
|
|
} );
|
|
},
|
|
finish: function( type ) {
|
|
if ( type !== false ) {
|
|
type = type || "fx";
|
|
}
|
|
return this.each( function() {
|
|
var index,
|
|
data = dataPriv.get( this ),
|
|
queue = data[ type + "queue" ],
|
|
hooks = data[ type + "queueHooks" ],
|
|
timers = jQuery.timers,
|
|
length = queue ? queue.length : 0;
|
|
|
|
// Enable finishing flag on private data
|
|
data.finish = true;
|
|
|
|
// Empty the queue first
|
|
jQuery.queue( this, type, [] );
|
|
|
|
if ( hooks && hooks.stop ) {
|
|
hooks.stop.call( this, true );
|
|
}
|
|
|
|
// Look for any active animations, and finish them
|
|
for ( index = timers.length; index--; ) {
|
|
if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
|
|
timers[ index ].anim.stop( true );
|
|
timers.splice( index, 1 );
|
|
}
|
|
}
|
|
|
|
// Look for any animations in the old queue and finish them
|
|
for ( index = 0; index < length; index++ ) {
|
|
if ( queue[ index ] && queue[ index ].finish ) {
|
|
queue[ index ].finish.call( this );
|
|
}
|
|
}
|
|
|
|
// Turn off finishing flag
|
|
delete data.finish;
|
|
} );
|
|
}
|
|
} );
|
|
|
|
jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
|
|
var cssFn = jQuery.fn[ name ];
|
|
jQuery.fn[ name ] = function( speed, easing, callback ) {
|
|
return speed == null || typeof speed === "boolean" ?
|
|
cssFn.apply( this, arguments ) :
|
|
this.animate( genFx( name, true ), speed, easing, callback );
|
|
};
|
|
} );
|
|
|
|
// Generate shortcuts for custom animations
|
|
jQuery.each( {
|
|
slideDown: genFx( "show" ),
|
|
slideUp: genFx( "hide" ),
|
|
slideToggle: genFx( "toggle" ),
|
|
fadeIn: { opacity: "show" },
|
|
fadeOut: { opacity: "hide" },
|
|
fadeToggle: { opacity: "toggle" }
|
|
}, function( name, props ) {
|
|
jQuery.fn[ name ] = function( speed, easing, callback ) {
|
|
return this.animate( props, speed, easing, callback );
|
|
};
|
|
} );
|
|
|
|
jQuery.timers = [];
|
|
jQuery.fx.tick = function() {
|
|
var timer,
|
|
i = 0,
|
|
timers = jQuery.timers;
|
|
|
|
fxNow = Date.now();
|
|
|
|
for ( ; i < timers.length; i++ ) {
|
|
timer = timers[ i ];
|
|
|
|
// Run the timer and safely remove it when done (allowing for external removal)
|
|
if ( !timer() && timers[ i ] === timer ) {
|
|
timers.splice( i--, 1 );
|
|
}
|
|
}
|
|
|
|
if ( !timers.length ) {
|
|
jQuery.fx.stop();
|
|
}
|
|
fxNow = undefined;
|
|
};
|
|
|
|
jQuery.fx.timer = function( timer ) {
|
|
jQuery.timers.push( timer );
|
|
jQuery.fx.start();
|
|
};
|
|
|
|
jQuery.fx.interval = 13;
|
|
jQuery.fx.start = function() {
|
|
if ( inProgress ) {
|
|
return;
|
|
}
|
|
|
|
inProgress = true;
|
|
schedule();
|
|
};
|
|
|
|
jQuery.fx.stop = function() {
|
|
inProgress = null;
|
|
};
|
|
|
|
jQuery.fx.speeds = {
|
|
slow: 600,
|
|
fast: 200,
|
|
|
|
// Default speed
|
|
_default: 400
|
|
};
|
|
|
|
|
|
// Based off of the plugin by Clint Helfers, with permission.
|
|
// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
|
|
jQuery.fn.delay = function( time, type ) {
|
|
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
|
|
type = type || "fx";
|
|
|
|
return this.queue( type, function( next, hooks ) {
|
|
var timeout = window.setTimeout( next, time );
|
|
hooks.stop = function() {
|
|
window.clearTimeout( timeout );
|
|
};
|
|
} );
|
|
};
|
|
|
|
|
|
( function() {
|
|
var input = document.createElement( "input" ),
|
|
select = document.createElement( "select" ),
|
|
opt = select.appendChild( document.createElement( "option" ) );
|
|
|
|
input.type = "checkbox";
|
|
|
|
// Support: Android <=4.3 only
|
|
// Default value for a checkbox should be "on"
|
|
support.checkOn = input.value !== "";
|
|
|
|
// Support: IE <=11 only
|
|
// Must access selectedIndex to make default options select
|
|
support.optSelected = opt.selected;
|
|
|
|
// Support: IE <=11 only
|
|
// An input loses its value after becoming a radio
|
|
input = document.createElement( "input" );
|
|
input.value = "t";
|
|
input.type = "radio";
|
|
support.radioValue = input.value === "t";
|
|
} )();
|
|
|
|
|
|
var boolHook,
|
|
attrHandle = jQuery.expr.attrHandle;
|
|
|
|
jQuery.fn.extend( {
|
|
attr: function( name, value ) {
|
|
return access( this, jQuery.attr, name, value, arguments.length > 1 );
|
|
},
|
|
|
|
removeAttr: function( name ) {
|
|
return this.each( function() {
|
|
jQuery.removeAttr( this, name );
|
|
} );
|
|
}
|
|
} );
|
|
|
|
jQuery.extend( {
|
|
attr: function( elem, name, value ) {
|
|
var ret, hooks,
|
|
nType = elem.nodeType;
|
|
|
|
// Don't get/set attributes on text, comment and attribute nodes
|
|
if ( nType === 3 || nType === 8 || nType === 2 ) {
|
|
return;
|
|
}
|
|
|
|
// Fallback to prop when attributes are not supported
|
|
if ( typeof elem.getAttribute === "undefined" ) {
|
|
return jQuery.prop( elem, name, value );
|
|
}
|
|
|
|
// Attribute hooks are determined by the lowercase version
|
|
// Grab necessary hook if one is defined
|
|
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
|
|
hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
|
|
( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
|
|
}
|
|
|
|
if ( value !== undefined ) {
|
|
if ( value === null ) {
|
|
jQuery.removeAttr( elem, name );
|
|
return;
|
|
}
|
|
|
|
if ( hooks && "set" in hooks &&
|
|
( ret = hooks.set( elem, value, name ) ) !== undefined ) {
|
|
return ret;
|
|
}
|
|
|
|
elem.setAttribute( name, value + "" );
|
|
return value;
|
|
}
|
|
|
|
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
|
|
return ret;
|
|
}
|
|
|
|
ret = jQuery.find.attr( elem, name );
|
|
|
|
// Non-existent attributes return null, we normalize to undefined
|
|
return ret == null ? undefined : ret;
|
|
},
|
|
|
|
attrHooks: {
|
|
type: {
|
|
set: function( elem, value ) {
|
|
if ( !support.radioValue && value === "radio" &&
|
|
nodeName( elem, "input" ) ) {
|
|
var val = elem.value;
|
|
elem.setAttribute( "type", value );
|
|
if ( val ) {
|
|
elem.value = val;
|
|
}
|
|
return value;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
removeAttr: function( elem, value ) {
|
|
var name,
|
|
i = 0,
|
|
|
|
// Attribute names can contain non-HTML whitespace characters
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
|
|
attrNames = value && value.match( rnothtmlwhite );
|
|
|
|
if ( attrNames && elem.nodeType === 1 ) {
|
|
while ( ( name = attrNames[ i++ ] ) ) {
|
|
elem.removeAttribute( name );
|
|
}
|
|
}
|
|
}
|
|
} );
|
|
|
|
// Hooks for boolean attributes
|
|
boolHook = {
|
|
set: function( elem, value, name ) {
|
|
if ( value === false ) {
|
|
|
|
// Remove boolean attributes when set to false
|
|
jQuery.removeAttr( elem, name );
|
|
} else {
|
|
elem.setAttribute( name, name );
|
|
}
|
|
return name;
|
|
}
|
|
};
|
|
|
|
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
|
|
var getter = attrHandle[ name ] || jQuery.find.attr;
|
|
|
|
attrHandle[ name ] = function( elem, name, isXML ) {
|
|
var ret, handle,
|
|
lowercaseName = name.toLowerCase();
|
|
|
|
if ( !isXML ) {
|
|
|
|
// Avoid an infinite loop by temporarily removing this function from the getter
|
|
handle = attrHandle[ lowercaseName ];
|
|
attrHandle[ lowercaseName ] = ret;
|
|
ret = getter( elem, name, isXML ) != null ?
|
|
lowercaseName :
|
|
null;
|
|
attrHandle[ lowercaseName ] = handle;
|
|
}
|
|
return ret;
|
|
};
|
|
} );
|
|
|
|
|
|
|
|
|
|
var rfocusable = /^(?:input|select|textarea|button)$/i,
|
|
rclickable = /^(?:a|area)$/i;
|
|
|
|
jQuery.fn.extend( {
|
|
prop: function( name, value ) {
|
|
return access( this, jQuery.prop, name, value, arguments.length > 1 );
|
|
},
|
|
|
|
removeProp: function( name ) {
|
|
return this.each( function() {
|
|
delete this[ jQuery.propFix[ name ] || name ];
|
|
} );
|
|
}
|
|
} );
|
|
|
|
jQuery.extend( {
|
|
prop: function( elem, name, value ) {
|
|
var ret, hooks,
|
|
nType = elem.nodeType;
|
|
|
|
// Don't get/set properties on text, comment and attribute nodes
|
|
if ( nType === 3 || nType === 8 || nType === 2 ) {
|
|
return;
|
|
}
|
|
|
|
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
|
|
|
|
// Fix name and attach hooks
|
|
name = jQuery.propFix[ name ] || name;
|
|
hooks = jQuery.propHooks[ name ];
|
|
}
|
|
|
|
if ( value !== undefined ) {
|
|
if ( hooks && "set" in hooks &&
|
|
( ret = hooks.set( elem, value, name ) ) !== undefined ) {
|
|
return ret;
|
|
}
|
|
|
|
return ( elem[ name ] = value );
|
|
}
|
|
|
|
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
|
|
return ret;
|
|
}
|
|
|
|
return elem[ name ];
|
|
},
|
|
|
|
propHooks: {
|
|
tabIndex: {
|
|
get: function( elem ) {
|
|
|
|
// Support: IE <=9 - 11 only
|
|
// elem.tabIndex doesn't always return the
|
|
// correct value when it hasn't been explicitly set
|
|
// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
|
|
// Use proper attribute retrieval(#12072)
|
|
var tabindex = jQuery.find.attr( elem, "tabindex" );
|
|
|
|
if ( tabindex ) {
|
|
return parseInt( tabindex, 10 );
|
|
}
|
|
|
|
if (
|
|
rfocusable.test( elem.nodeName ) ||
|
|
rclickable.test( elem.nodeName ) &&
|
|
elem.href
|
|
) {
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
}
|
|
},
|
|
|
|
propFix: {
|
|
"for": "htmlFor",
|
|
"class": "className"
|
|
}
|
|
} );
|
|
|
|
// Support: IE <=11 only
|
|
// Accessing the selectedIndex property
|
|
// forces the browser to respect setting selected
|
|
// on the option
|
|
// The getter ensures a default option is selected
|
|
// when in an optgroup
|
|
// eslint rule "no-unused-expressions" is disabled for this code
|
|
// since it considers such accessions noop
|
|
if ( !support.optSelected ) {
|
|
jQuery.propHooks.selected = {
|
|
get: function( elem ) {
|
|
|
|
/* eslint no-unused-expressions: "off" */
|
|
|
|
var parent = elem.parentNode;
|
|
if ( parent && parent.parentNode ) {
|
|
parent.parentNode.selectedIndex;
|
|
}
|
|
return null;
|
|
},
|
|
set: function( elem ) {
|
|
|
|
/* eslint no-unused-expressions: "off" */
|
|
|
|
var parent = elem.parentNode;
|
|
if ( parent ) {
|
|
parent.selectedIndex;
|
|
|
|
if ( parent.parentNode ) {
|
|
parent.parentNode.selectedIndex;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
jQuery.each( [
|
|
"tabIndex",
|
|
"readOnly",
|
|
"maxLength",
|
|
"cellSpacing",
|
|
"cellPadding",
|
|
"rowSpan",
|
|
"colSpan",
|
|
"useMap",
|
|
"frameBorder",
|
|
"contentEditable"
|
|
], function() {
|
|
jQuery.propFix[ this.toLowerCase() ] = this;
|
|
} );
|
|
|
|
|
|
|
|
|
|
// Strip and collapse whitespace according to HTML spec
|
|
// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
|
|
function stripAndCollapse( value ) {
|
|
var tokens = value.match( rnothtmlwhite ) || [];
|
|
return tokens.join( " " );
|
|
}
|
|
|
|
|
|
function getClass( elem ) {
|
|
return elem.getAttribute && elem.getAttribute( "class" ) || "";
|
|
}
|
|
|
|
function classesToArray( value ) {
|
|
if ( Array.isArray( value ) ) {
|
|
return value;
|
|
}
|
|
if ( typeof value === "string" ) {
|
|
return value.match( rnothtmlwhite ) || [];
|
|
}
|
|
return [];
|
|
}
|
|
|
|
jQuery.fn.extend( {
|
|
addClass: function( value ) {
|
|
var classes, elem, cur, curValue, clazz, j, finalValue,
|
|
i = 0;
|
|
|
|
if ( isFunction( value ) ) {
|
|
return this.each( function( j ) {
|
|
jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
|
|
} );
|
|
}
|
|
|
|
classes = classesToArray( value );
|
|
|
|
if ( classes.length ) {
|
|
while ( ( elem = this[ i++ ] ) ) {
|
|
curValue = getClass( elem );
|
|
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
|
|
|
if ( cur ) {
|
|
j = 0;
|
|
while ( ( clazz = classes[ j++ ] ) ) {
|
|
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
|
|
cur += clazz + " ";
|
|
}
|
|
}
|
|
|
|
// Only assign if different to avoid unneeded rendering.
|
|
finalValue = stripAndCollapse( cur );
|
|
if ( curValue !== finalValue ) {
|
|
elem.setAttribute( "class", finalValue );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
removeClass: function( value ) {
|
|
var classes, elem, cur, curValue, clazz, j, finalValue,
|
|
i = 0;
|
|
|
|
if ( isFunction( value ) ) {
|
|
return this.each( function( j ) {
|
|
jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
|
|
} );
|
|
}
|
|
|
|
if ( !arguments.length ) {
|
|
return this.attr( "class", "" );
|
|
}
|
|
|
|
classes = classesToArray( value );
|
|
|
|
if ( classes.length ) {
|
|
while ( ( elem = this[ i++ ] ) ) {
|
|
curValue = getClass( elem );
|
|
|
|
// This expression is here for better compressibility (see addClass)
|
|
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
|
|
|
if ( cur ) {
|
|
j = 0;
|
|
while ( ( clazz = classes[ j++ ] ) ) {
|
|
|
|
// Remove *all* instances
|
|
while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
|
|
cur = cur.replace( " " + clazz + " ", " " );
|
|
}
|
|
}
|
|
|
|
// Only assign if different to avoid unneeded rendering.
|
|
finalValue = stripAndCollapse( cur );
|
|
if ( curValue !== finalValue ) {
|
|
elem.setAttribute( "class", finalValue );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
toggleClass: function( value, stateVal ) {
|
|
var type = typeof value,
|
|
isValidValue = type === "string" || Array.isArray( value );
|
|
|
|
if ( typeof stateVal === "boolean" && isValidValue ) {
|
|
return stateVal ? this.addClass( value ) : this.removeClass( value );
|
|
}
|
|
|
|
if ( isFunction( value ) ) {
|
|
return this.each( function( i ) {
|
|
jQuery( this ).toggleClass(
|
|
value.call( this, i, getClass( this ), stateVal ),
|
|
stateVal
|
|
);
|
|
} );
|
|
}
|
|
|
|
return this.each( function() {
|
|
var className, i, self, classNames;
|
|
|
|
if ( isValidValue ) {
|
|
|
|
// Toggle individual class names
|
|
i = 0;
|
|
self = jQuery( this );
|
|
classNames = classesToArray( value );
|
|
|
|
while ( ( className = classNames[ i++ ] ) ) {
|
|
|
|
// Check each className given, space separated list
|
|
if ( self.hasClass( className ) ) {
|
|
self.removeClass( className );
|
|
} else {
|
|
self.addClass( className );
|
|
}
|
|
}
|
|
|
|
// Toggle whole class name
|
|
} else if ( value === undefined || type === "boolean" ) {
|
|
className = getClass( this );
|
|
if ( className ) {
|
|
|
|
// Store className if set
|
|
dataPriv.set( this, "__className__", className );
|
|
}
|
|
|
|
// If the element has a class name or if we're passed `false`,
|
|
// then remove the whole classname (if there was one, the above saved it).
|
|
// Otherwise bring back whatever was previously saved (if anything),
|
|
// falling back to the empty string if nothing was stored.
|
|
if ( this.setAttribute ) {
|
|
this.setAttribute( "class",
|
|
className || value === false ?
|
|
"" :
|
|
dataPriv.get( this, "__className__" ) || ""
|
|
);
|
|
}
|
|
}
|
|
} );
|
|
},
|
|
|
|
hasClass: function( selector ) {
|
|
var className, elem,
|
|
i = 0;
|
|
|
|
className = " " + selector + " ";
|
|
while ( ( elem = this[ i++ ] ) ) {
|
|
if ( elem.nodeType === 1 &&
|
|
( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
} );
|
|
|
|
|
|
|
|
|
|
var rreturn = /\r/g;
|
|
|
|
jQuery.fn.extend( {
|
|
val: function( value ) {
|
|
var hooks, ret, valueIsFunction,
|
|
elem = this[ 0 ];
|
|
|
|
if ( !arguments.length ) {
|
|
if ( elem ) {
|
|
hooks = jQuery.valHooks[ elem.type ] ||
|
|
jQuery.valHooks[ elem.nodeName.toLowerCase() ];
|
|
|
|
if ( hooks &&
|
|
"get" in hooks &&
|
|
( ret = hooks.get( elem, "value" ) ) !== undefined
|
|
) {
|
|
return ret;
|
|
}
|
|
|
|
ret = elem.value;
|
|
|
|
// Handle most common string cases
|
|
if ( typeof ret === "string" ) {
|
|
return ret.replace( rreturn, "" );
|
|
}
|
|
|
|
// Handle cases where value is null/undef or number
|
|
return ret == null ? "" : ret;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
valueIsFunction = isFunction( value );
|
|
|
|
return this.each( function( i ) {
|
|
var val;
|
|
|
|
if ( this.nodeType !== 1 ) {
|
|
return;
|
|
}
|
|
|
|
if ( valueIsFunction ) {
|
|
val = value.call( this, i, jQuery( this ).val() );
|
|
} else {
|
|
val = value;
|
|
}
|
|
|
|
// Treat null/undefined as ""; convert numbers to string
|
|
if ( val == null ) {
|
|
val = "";
|
|
|
|
} else if ( typeof val === "number" ) {
|
|
val += "";
|
|
|
|
} else if ( Array.isArray( val ) ) {
|
|
val = jQuery.map( val, function( value ) {
|
|
return value == null ? "" : value + "";
|
|
} );
|
|
}
|
|
|
|
hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
|
|
|
|
// If set returns undefined, fall back to normal setting
|
|
if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
|
|
this.value = val;
|
|
}
|
|
} );
|
|
}
|
|
} );
|
|
|
|
jQuery.extend( {
|
|
valHooks: {
|
|
option: {
|
|
get: function( elem ) {
|
|
|
|
var val = jQuery.find.attr( elem, "value" );
|
|
return val != null ?
|
|
val :
|
|
|
|
// Support: IE <=10 - 11 only
|
|
// option.text throws exceptions (#14686, #14858)
|
|
// Strip and collapse whitespace
|
|
// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
|
|
stripAndCollapse( jQuery.text( elem ) );
|
|
}
|
|
},
|
|
select: {
|
|
get: function( elem ) {
|
|
var value, option, i,
|
|
options = elem.options,
|
|
index = elem.selectedIndex,
|
|
one = elem.type === "select-one",
|
|
values = one ? null : [],
|
|
max = one ? index + 1 : options.length;
|
|
|
|
if ( index < 0 ) {
|
|
i = max;
|
|
|
|
} else {
|
|
i = one ? index : 0;
|
|
}
|
|
|
|
// Loop through all the selected options
|
|
for ( ; i < max; i++ ) {
|
|
option = options[ i ];
|
|
|
|
// Support: IE <=9 only
|
|
// IE8-9 doesn't update selected after form reset (#2551)
|
|
if ( ( option.selected || i === index ) &&
|
|
|
|
// Don't return options that are disabled or in a disabled optgroup
|
|
!option.disabled &&
|
|
( !option.parentNode.disabled ||
|
|
!nodeName( option.parentNode, "optgroup" ) ) ) {
|
|
|
|
// Get the specific value for the option
|
|
value = jQuery( option ).val();
|
|
|
|
// We don't need an array for one selects
|
|
if ( one ) {
|
|
return value;
|
|
}
|
|
|
|
// Multi-Selects return an array
|
|
values.push( value );
|
|
}
|
|
}
|
|
|
|
return values;
|
|
},
|
|
|
|
set: function( elem, value ) {
|
|
var optionSet, option,
|
|
options = elem.options,
|
|
values = jQuery.makeArray( value ),
|
|
i = options.length;
|
|
|
|
while ( i-- ) {
|
|
option = options[ i ];
|
|
|
|
/* eslint-disable no-cond-assign */
|
|
|
|
if ( option.selected =
|
|
jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
|
|
) {
|
|
optionSet = true;
|
|
}
|
|
|
|
/* eslint-enable no-cond-assign */
|
|
}
|
|
|
|
// Force browsers to behave consistently when non-matching value is set
|
|
if ( !optionSet ) {
|
|
elem.selectedIndex = -1;
|
|
}
|
|
return values;
|
|
}
|
|
}
|
|
}
|
|
} );
|
|
|
|
// Radios and checkboxes getter/setter
|
|
jQuery.each( [ "radio", "checkbox" ], function() {
|
|
jQuery.valHooks[ this ] = {
|
|
set: function( elem, value ) {
|
|
if ( Array.isArray( value ) ) {
|
|
return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
|
|
}
|
|
}
|
|
};
|
|
if ( !support.checkOn ) {
|
|
jQuery.valHooks[ this ].get = function( elem ) {
|
|
return elem.getAttribute( "value" ) === null ? "on" : elem.value;
|
|
};
|
|
}
|
|
} );
|
|
|
|
|
|
|
|
|
|
// Return jQuery for attributes-only inclusion
|
|
|
|
|
|
support.focusin = "onfocusin" in window;
|
|
|
|
|
|
var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
|
|
stopPropagationCallback = function( e ) {
|
|
e.stopPropagation();
|
|
};
|
|
|
|
jQuery.extend( jQuery.event, {
|
|
|
|
trigger: function( event, data, elem, onlyHandlers ) {
|
|
|
|
var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
|
|
eventPath = [ elem || document ],
|
|
type = hasOwn.call( event, "type" ) ? event.type : event,
|
|
namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
|
|
|
|
cur = lastElement = tmp = elem = elem || document;
|
|
|
|
// Don't do events on text and comment nodes
|
|
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
|
|
return;
|
|
}
|
|
|
|
// focus/blur morphs to focusin/out; ensure we're not firing them right now
|
|
if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
|
|
return;
|
|
}
|
|
|
|
if ( type.indexOf( "." ) > -1 ) {
|
|
|
|
// Namespaced trigger; create a regexp to match event type in handle()
|
|
namespaces = type.split( "." );
|
|
type = namespaces.shift();
|
|
namespaces.sort();
|
|
}
|
|
ontype = type.indexOf( ":" ) < 0 && "on" + type;
|
|
|
|
// Caller can pass in a jQuery.Event object, Object, or just an event type string
|
|
event = event[ jQuery.expando ] ?
|
|
event :
|
|
new jQuery.Event( type, typeof event === "object" && event );
|
|
|
|
// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
|
|
event.isTrigger = onlyHandlers ? 2 : 3;
|
|
event.namespace = namespaces.join( "." );
|
|
event.rnamespace = event.namespace ?
|
|
new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
|
|
null;
|
|
|
|
// Clean up the event in case it is being reused
|
|
event.result = undefined;
|
|
if ( !event.target ) {
|
|
event.target = elem;
|
|
}
|
|
|
|
// Clone any incoming data and prepend the event, creating the handler arg list
|
|
data = data == null ?
|
|
[ event ] :
|
|
jQuery.makeArray( data, [ event ] );
|
|
|
|
// Allow special events to draw outside the lines
|
|
special = jQuery.event.special[ type ] || {};
|
|
if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
|
|
return;
|
|
}
|
|
|
|
// Determine event propagation path in advance, per W3C events spec (#9951)
|
|
// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
|
|
if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
|
|
|
|
bubbleType = special.delegateType || type;
|
|
if ( !rfocusMorph.test( bubbleType + type ) ) {
|
|
cur = cur.parentNode;
|
|
}
|
|
for ( ; cur; cur = cur.parentNode ) {
|
|
eventPath.push( cur );
|
|
tmp = cur;
|
|
}
|
|
|
|
// Only add window if we got to document (e.g., not plain obj or detached DOM)
|
|
if ( tmp === ( elem.ownerDocument || document ) ) {
|
|
eventPath.push( tmp.defaultView || tmp.parentWindow || window );
|
|
}
|
|
}
|
|
|
|
// Fire handlers on the event path
|
|
i = 0;
|
|
while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
|
|
lastElement = cur;
|
|
event.type = i > 1 ?
|
|
bubbleType :
|
|
special.bindType || type;
|
|
|
|
// jQuery handler
|
|
handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] &&
|
|
dataPriv.get( cur, "handle" );
|
|
if ( handle ) {
|
|
handle.apply( cur, data );
|
|
}
|
|
|
|
// Native handler
|
|
handle = ontype && cur[ ontype ];
|
|
if ( handle && handle.apply && acceptData( cur ) ) {
|
|
event.result = handle.apply( cur, data );
|
|
if ( event.result === false ) {
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
}
|
|
event.type = type;
|
|
|
|
// If nobody prevented the default action, do it now
|
|
if ( !onlyHandlers && !event.isDefaultPrevented() ) {
|
|
|
|
if ( ( !special._default ||
|
|
special._default.apply( eventPath.pop(), data ) === false ) &&
|
|
acceptData( elem ) ) {
|
|
|
|
// Call a native DOM method on the target with the same name as the event.
|
|
// Don't do default actions on window, that's where global variables be (#6170)
|
|
if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
|
|
|
|
// Don't re-trigger an onFOO event when we call its FOO() method
|
|
tmp = elem[ ontype ];
|
|
|
|
if ( tmp ) {
|
|
elem[ ontype ] = null;
|
|
}
|
|
|
|
// Prevent re-triggering of the same event, since we already bubbled it above
|
|
jQuery.event.triggered = type;
|
|
|
|
if ( event.isPropagationStopped() ) {
|
|
lastElement.addEventListener( type, stopPropagationCallback );
|
|
}
|
|
|
|
elem[ type ]();
|
|
|
|
if ( event.isPropagationStopped() ) {
|
|
lastElement.removeEventListener( type, stopPropagationCallback );
|
|
}
|
|
|
|
jQuery.event.triggered = undefined;
|
|
|
|
if ( tmp ) {
|
|
elem[ ontype ] = tmp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return event.result;
|
|
},
|
|
|
|
// Piggyback on a donor event to simulate a different one
|
|
// Used only for `focus(in | out)` events
|
|
simulate: function( type, elem, event ) {
|
|
var e = jQuery.extend(
|
|
new jQuery.Event(),
|
|
event,
|
|
{
|
|
type: type,
|
|
isSimulated: true
|
|
}
|
|
);
|
|
|
|
jQuery.event.trigger( e, null, elem );
|
|
}
|
|
|
|
} );
|
|
|
|
jQuery.fn.extend( {
|
|
|
|
trigger: function( type, data ) {
|
|
return this.each( function() {
|
|
jQuery.event.trigger( type, data, this );
|
|
} );
|
|
},
|
|
triggerHandler: function( type, data ) {
|
|
var elem = this[ 0 ];
|
|
if ( elem ) {
|
|
return jQuery.event.trigger( type, data, elem, true );
|
|
}
|
|
}
|
|
} );
|
|
|
|
|
|
// Support: Firefox <=44
|
|
// Firefox doesn't have focus(in | out) events
|
|
// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
|
|
//
|
|
// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
|
|
// focus(in | out) events fire after focus & blur events,
|
|
// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
|
|
// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
|
|
if ( !support.focusin ) {
|
|
jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
|
|
|
|
// Attach a single capturing handler on the document while someone wants focusin/focusout
|
|
var handler = function( event ) {
|
|
jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
|
|
};
|
|
|
|
jQuery.event.special[ fix ] = {
|
|
setup: function() {
|
|
|
|
// Handle: regular nodes (via `this.ownerDocument`), window
|
|
// (via `this.document`) & document (via `this`).
|
|
var doc = this.ownerDocument || this.document || this,
|
|
attaches = dataPriv.access( doc, fix );
|
|
|
|
if ( !attaches ) {
|
|
doc.addEventListener( orig, handler, true );
|
|
}
|
|
dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
|
|
},
|
|
teardown: function() {
|
|
var doc = this.ownerDocument || this.document || this,
|
|
attaches = dataPriv.access( doc, fix ) - 1;
|
|
|
|
if ( !attaches ) {
|
|
doc.removeEventListener( orig, handler, true );
|
|
dataPriv.remove( doc, fix );
|
|
|
|
} else {
|
|
dataPriv.access( doc, fix, attaches );
|
|
}
|
|
}
|
|
};
|
|
} );
|
|
}
|
|
var location = window.location;
|
|
|
|
var nonce = { guid: Date.now() };
|
|
|
|
var rquery = ( /\?/ );
|
|
|
|
|
|
|
|
// Cross-browser xml parsing
|
|
jQuery.parseXML = function( data ) {
|
|
var xml, parserErrorElem;
|
|
if ( !data || typeof data !== "string" ) {
|
|
return null;
|
|
}
|
|
|
|
// Support: IE 9 - 11 only
|
|
// IE throws on parseFromString with invalid input.
|
|
try {
|
|
xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
|
|
} catch ( e ) {}
|
|
|
|
parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ];
|
|
if ( !xml || parserErrorElem ) {
|
|
jQuery.error( "Invalid XML: " + (
|
|
parserErrorElem ?
|
|
jQuery.map( parserErrorElem.childNodes, function( el ) {
|
|
return el.textContent;
|
|
} ).join( "\n" ) :
|
|
data
|
|
) );
|
|
}
|
|
return xml;
|
|
};
|
|
|
|
|
|
var
|
|
rbracket = /\[\]$/,
|
|
rCRLF = /\r?\n/g,
|
|
rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
|
|
rsubmittable = /^(?:input|select|textarea|keygen)/i;
|
|
|
|
function buildParams( prefix, obj, traditional, add ) {
|
|
var name;
|
|
|
|
if ( Array.isArray( obj ) ) {
|
|
|
|
// Serialize array item.
|
|
jQuery.each( obj, function( i, v ) {
|
|
if ( traditional || rbracket.test( prefix ) ) {
|
|
|
|
// Treat each array item as a scalar.
|
|
add( prefix, v );
|
|
|
|
} else {
|
|
|
|
// Item is non-scalar (array or object), encode its numeric index.
|
|
buildParams(
|
|
prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
|
|
v,
|
|
traditional,
|
|
add
|
|
);
|
|
}
|
|
} );
|
|
|
|
} else if ( !traditional && toType( obj ) === "object" ) {
|
|
|
|
// Serialize object item.
|
|
for ( name in obj ) {
|
|
buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
|
|
}
|
|
|
|
} else {
|
|
|
|
// Serialize scalar item.
|
|
add( prefix, obj );
|
|
}
|
|
}
|
|
|
|
// Serialize an array of form elements or a set of
|
|
// key/values into a query string
|
|
jQuery.param = function( a, traditional ) {
|
|
var prefix,
|
|
s = [],
|
|
add = function( key, valueOrFunction ) {
|
|
|
|
// If value is a function, invoke it and use its return value
|
|
var value = isFunction( valueOrFunction ) ?
|
|
valueOrFunction() :
|
|
valueOrFunction;
|
|
|
|
s[ s.length ] = encodeURIComponent( key ) + "=" +
|
|
encodeURIComponent( value == null ? "" : value );
|
|
};
|
|
|
|
if ( a == null ) {
|
|
return "";
|
|
}
|
|
|
|
// If an array was passed in, assume that it is an array of form elements.
|
|
if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
|
|
|
|
// Serialize the form elements
|
|
jQuery.each( a, function() {
|
|
add( this.name, this.value );
|
|
} );
|
|
|
|
} else {
|
|
|
|
// If traditional, encode the "old" way (the way 1.3.2 or older
|
|
// did it), otherwise encode params recursively.
|
|
for ( prefix in a ) {
|
|
buildParams( prefix, a[ prefix ], traditional, add );
|
|
}
|
|
}
|
|
|
|
// Return the resulting serialization
|
|
return s.join( "&" );
|
|
};
|
|
|
|
jQuery.fn.extend( {
|
|
serialize: function() {
|
|
return jQuery.param( this.serializeArray() );
|
|
},
|
|
serializeArray: function() {
|
|
return this.map( function() {
|
|
|
|
// Can add propHook for "elements" to filter or add form elements
|
|
var elements = jQuery.prop( this, "elements" );
|
|
return elements ? jQuery.makeArray( elements ) : this;
|
|
} ).filter( function() {
|
|
var type = this.type;
|
|
|
|
// Use .is( ":disabled" ) so that fieldset[disabled] works
|
|
return this.name && !jQuery( this ).is( ":disabled" ) &&
|
|
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
|
|
( this.checked || !rcheckableType.test( type ) );
|
|
} ).map( function( _i, elem ) {
|
|
var val = jQuery( this ).val();
|
|
|
|
if ( val == null ) {
|
|
return null;
|
|
}
|
|
|
|
if ( Array.isArray( val ) ) {
|
|
return jQuery.map( val, function( val ) {
|
|
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
|
|
} );
|
|
}
|
|
|
|
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
|
|
} ).get();
|
|
}
|
|
} );
|
|
|
|
|
|
var
|
|
r20 = /%20/g,
|
|
rhash = /#.*$/,
|
|
rantiCache = /([?&])_=[^&]*/,
|
|
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
|
|
|
|
// #7653, #8125, #8152: local protocol detection
|
|
rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
|
|
rnoContent = /^(?:GET|HEAD)$/,
|
|
rprotocol = /^\/\//,
|
|
|
|
/* Prefilters
|
|
* 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
|
|
* 2) These are called:
|
|
* - BEFORE asking for a transport
|
|
* - AFTER param serialization (s.data is a string if s.processData is true)
|
|
* 3) key is the dataType
|
|
* 4) the catchall symbol "*" can be used
|
|
* 5) execution will start with transport dataType and THEN continue down to "*" if needed
|
|
*/
|
|
prefilters = {},
|
|
|
|
/* Transports bindings
|
|
* 1) key is the dataType
|
|
* 2) the catchall symbol "*" can be used
|
|
* 3) selection will start with transport dataType and THEN go to "*" if needed
|
|
*/
|
|
transports = {},
|
|
|
|
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
|
|
allTypes = "*/".concat( "*" ),
|
|
|
|
// Anchor tag for parsing the document origin
|
|
originAnchor = document.createElement( "a" );
|
|
|
|
originAnchor.href = location.href;
|
|
|
|
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
|
|
function addToPrefiltersOrTransports( structure ) {
|
|
|
|
// dataTypeExpression is optional and defaults to "*"
|
|
return function( dataTypeExpression, func ) {
|
|
|
|
if ( typeof dataTypeExpression !== "string" ) {
|
|
func = dataTypeExpression;
|
|
dataTypeExpression = "*";
|
|
}
|
|
|
|
var dataType,
|
|
i = 0,
|
|
dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
|
|
|
|
if ( isFunction( func ) ) {
|
|
|
|
// For each dataType in the dataTypeExpression
|
|
while ( ( dataType = dataTypes[ i++ ] ) ) {
|
|
|
|
// Prepend if requested
|
|
if ( dataType[ 0 ] === "+" ) {
|
|
dataType = dataType.slice( 1 ) || "*";
|
|
( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
|
|
|
|
// Otherwise append
|
|
} else {
|
|
( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
// Base inspection function for prefilters and transports
|
|
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
|
|
|
|
var inspected = {},
|
|
seekingTransport = ( structure === transports );
|
|
|
|
function inspect( dataType ) {
|
|
var selected;
|
|
inspected[ dataType ] = true;
|
|
jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
|
|
var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
|
|
if ( typeof dataTypeOrTransport === "string" &&
|
|
!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
|
|
|
|
options.dataTypes.unshift( dataTypeOrTransport );
|
|
inspect( dataTypeOrTransport );
|
|
return false;
|
|
} else if ( seekingTransport ) {
|
|
return !( selected = dataTypeOrTransport );
|
|
}
|
|
} );
|
|
return selected;
|
|
}
|
|
|
|
return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
|
|
}
|
|
|
|
// A special extend for ajax options
|
|
// that takes "flat" options (not to be deep extended)
|
|
// Fixes #9887
|
|
function ajaxExtend( target, src ) {
|
|
var key, deep,
|
|
flatOptions = jQuery.ajaxSettings.flatOptions || {};
|
|
|
|
for ( key in src ) {
|
|
if ( src[ key ] !== undefined ) {
|
|
( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
|
|
}
|
|
}
|
|
if ( deep ) {
|
|
jQuery.extend( true, target, deep );
|
|
}
|
|
|
|
return target;
|
|
}
|
|
|
|
/* Handles responses to an ajax request:
|
|
* - finds the right dataType (mediates between content-type and expected dataType)
|
|
* - returns the corresponding response
|
|
*/
|
|
function ajaxHandleResponses( s, jqXHR, responses ) {
|
|
|
|
var ct, type, finalDataType, firstDataType,
|
|
contents = s.contents,
|
|
dataTypes = s.dataTypes;
|
|
|
|
// Remove auto dataType and get content-type in the process
|
|
while ( dataTypes[ 0 ] === "*" ) {
|
|
dataTypes.shift();
|
|
if ( ct === undefined ) {
|
|
ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
|
|
}
|
|
}
|
|
|
|
// Check if we're dealing with a known content-type
|
|
if ( ct ) {
|
|
for ( type in contents ) {
|
|
if ( contents[ type ] && contents[ type ].test( ct ) ) {
|
|
dataTypes.unshift( type );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check to see if we have a response for the expected dataType
|
|
if ( dataTypes[ 0 ] in responses ) {
|
|
finalDataType = dataTypes[ 0 ];
|
|
} else {
|
|
|
|
// Try convertible dataTypes
|
|
for ( type in responses ) {
|
|
if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
|
|
finalDataType = type;
|
|
break;
|
|
}
|
|
if ( !firstDataType ) {
|
|
firstDataType = type;
|
|
}
|
|
}
|
|
|
|
// Or just use first one
|
|
finalDataType = finalDataType || firstDataType;
|
|
}
|
|
|
|
// If we found a dataType
|
|
// We add the dataType to the list if needed
|
|
// and return the corresponding response
|
|
if ( finalDataType ) {
|
|
if ( finalDataType !== dataTypes[ 0 ] ) {
|
|
dataTypes.unshift( finalDataType );
|
|
}
|
|
return responses[ finalDataType ];
|
|
}
|
|
}
|
|
|
|
/* Chain conversions given the request and the original response
|
|
* Also sets the responseXXX fields on the jqXHR instance
|
|
*/
|
|
function ajaxConvert( s, response, jqXHR, isSuccess ) {
|
|
var conv2, current, conv, tmp, prev,
|
|
converters = {},
|
|
|
|
// Work with a copy of dataTypes in case we need to modify it for conversion
|
|
dataTypes = s.dataTypes.slice();
|
|
|
|
// Create converters map with lowercased keys
|
|
if ( dataTypes[ 1 ] ) {
|
|
for ( conv in s.converters ) {
|
|
converters[ conv.toLowerCase() ] = s.converters[ conv ];
|
|
}
|
|
}
|
|
|
|
current = dataTypes.shift();
|
|
|
|
// Convert to each sequential dataType
|
|
while ( current ) {
|
|
|
|
if ( s.responseFields[ current ] ) {
|
|
jqXHR[ s.responseFields[ current ] ] = response;
|
|
}
|
|
|
|
// Apply the dataFilter if provided
|
|
if ( !prev && isSuccess && s.dataFilter ) {
|
|
response = s.dataFilter( response, s.dataType );
|
|
}
|
|
|
|
prev = current;
|
|
current = dataTypes.shift();
|
|
|
|
if ( current ) {
|
|
|
|
// There's only work to do if current dataType is non-auto
|
|
if ( current === "*" ) {
|
|
|
|
current = prev;
|
|
|
|
// Convert response if prev dataType is non-auto and differs from current
|
|
} else if ( prev !== "*" && prev !== current ) {
|
|
|
|
// Seek a direct converter
|
|
conv = converters[ prev + " " + current ] || converters[ "* " + current ];
|
|
|
|
// If none found, seek a pair
|
|
if ( !conv ) {
|
|
for ( conv2 in converters ) {
|
|
|
|
// If conv2 outputs current
|
|
tmp = conv2.split( " " );
|
|
if ( tmp[ 1 ] === current ) {
|
|
|
|
// If prev can be converted to accepted input
|
|
conv = converters[ prev + " " + tmp[ 0 ] ] ||
|
|
converters[ "* " + tmp[ 0 ] ];
|
|
if ( conv ) {
|
|
|
|
// Condense equivalence converters
|
|
if ( conv === true ) {
|
|
conv = converters[ conv2 ];
|
|
|
|
// Otherwise, insert the intermediate dataType
|
|
} else if ( converters[ conv2 ] !== true ) {
|
|
current = tmp[ 0 ];
|
|
dataTypes.unshift( tmp[ 1 ] );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Apply converter (if not an equivalence)
|
|
if ( conv !== true ) {
|
|
|
|
// Unless errors are allowed to bubble, catch and return them
|
|
if ( conv && s.throws ) {
|
|
response = conv( response );
|
|
} else {
|
|
try {
|
|
response = conv( response );
|
|
} catch ( e ) {
|
|
return {
|
|
state: "parsererror",
|
|
error: conv ? e : "No conversion from " + prev + " to " + current
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return { state: "success", data: response };
|
|
}
|
|
|
|
jQuery.extend( {
|
|
|
|
// Counter for holding the number of active queries
|
|
active: 0,
|
|
|
|
// Last-Modified header cache for next request
|
|
lastModified: {},
|
|
etag: {},
|
|
|
|
ajaxSettings: {
|
|
url: location.href,
|
|
type: "GET",
|
|
isLocal: rlocalProtocol.test( location.protocol ),
|
|
global: true,
|
|
processData: true,
|
|
async: true,
|
|
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
|
|
|
|
/*
|
|
timeout: 0,
|
|
data: null,
|
|
dataType: null,
|
|
username: null,
|
|
password: null,
|
|
cache: null,
|
|
throws: false,
|
|
traditional: false,
|
|
headers: {},
|
|
*/
|
|
|
|
accepts: {
|
|
"*": allTypes,
|
|
text: "text/plain",
|
|
html: "text/html",
|
|
xml: "application/xml, text/xml",
|
|
json: "application/json, text/javascript"
|
|
},
|
|
|
|
contents: {
|
|
xml: /\bxml\b/,
|
|
html: /\bhtml/,
|
|
json: /\bjson\b/
|
|
},
|
|
|
|
responseFields: {
|
|
xml: "responseXML",
|
|
text: "responseText",
|
|
json: "responseJSON"
|
|
},
|
|
|
|
// Data converters
|
|
// Keys separate source (or catchall "*") and destination types with a single space
|
|
converters: {
|
|
|
|
// Convert anything to text
|
|
"* text": String,
|
|
|
|
// Text to html (true = no transformation)
|
|
"text html": true,
|
|
|
|
// Evaluate text as a json expression
|
|
"text json": JSON.parse,
|
|
|
|
// Parse text as xml
|
|
"text xml": jQuery.parseXML
|
|
},
|
|
|
|
// For options that shouldn't be deep extended:
|
|
// you can add your own custom options here if
|
|
// and when you create one that shouldn't be
|
|
// deep extended (see ajaxExtend)
|
|
flatOptions: {
|
|
url: true,
|
|
context: true
|
|
}
|
|
},
|
|
|
|
// Creates a full fledged settings object into target
|
|
// with both ajaxSettings and settings fields.
|
|
// If target is omitted, writes into ajaxSettings.
|
|
ajaxSetup: function( target, settings ) {
|
|
return settings ?
|
|
|
|
// Building a settings object
|
|
ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
|
|
|
|
// Extending ajaxSettings
|
|
ajaxExtend( jQuery.ajaxSettings, target );
|
|
},
|
|
|
|
ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
|
|
ajaxTransport: addToPrefiltersOrTransports( transports ),
|
|
|
|
// Main method
|
|
ajax: function( url, options ) {
|
|
|
|
// If url is an object, simulate pre-1.5 signature
|
|
if ( typeof url === "object" ) {
|
|
options = url;
|
|
url = undefined;
|
|
}
|
|
|
|
// Force options to be an object
|
|
options = options || {};
|
|
|
|
var transport,
|
|
|
|
// URL without anti-cache param
|
|
cacheURL,
|
|
|
|
// Response headers
|
|
responseHeadersString,
|
|
responseHeaders,
|
|
|
|
// timeout handle
|
|
timeoutTimer,
|
|
|
|
// Url cleanup var
|
|
urlAnchor,
|
|
|
|
// Request state (becomes false upon send and true upon completion)
|
|
completed,
|
|
|
|
// To know if global events are to be dispatched
|
|
fireGlobals,
|
|
|
|
// Loop variable
|
|
i,
|
|
|
|
// uncached part of the url
|
|
uncached,
|
|
|
|
// Create the final options object
|
|
s = jQuery.ajaxSetup( {}, options ),
|
|
|
|
// Callbacks context
|
|
callbackContext = s.context || s,
|
|
|
|
// Context for global events is callbackContext if it is a DOM node or jQuery collection
|
|
globalEventContext = s.context &&
|
|
( callbackContext.nodeType || callbackContext.jquery ) ?
|
|
jQuery( callbackContext ) :
|
|
jQuery.event,
|
|
|
|
// Deferreds
|
|
deferred = jQuery.Deferred(),
|
|
completeDeferred = jQuery.Callbacks( "once memory" ),
|
|
|
|
// Status-dependent callbacks
|
|
statusCode = s.statusCode || {},
|
|
|
|
// Headers (they are sent all at once)
|
|
requestHeaders = {},
|
|
requestHeadersNames = {},
|
|
|
|
// Default abort message
|
|
strAbort = "canceled",
|
|
|
|
// Fake xhr
|
|
jqXHR = {
|
|
readyState: 0,
|
|
|
|
// Builds headers hashtable if needed
|
|
getResponseHeader: function( key ) {
|
|
var match;
|
|
if ( completed ) {
|
|
if ( !responseHeaders ) {
|
|
responseHeaders = {};
|
|
while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
|
|
responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
|
|
( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
|
|
.concat( match[ 2 ] );
|
|
}
|
|
}
|
|
match = responseHeaders[ key.toLowerCase() + " " ];
|
|
}
|
|
return match == null ? null : match.join( ", " );
|
|
},
|
|
|
|
// Raw string
|
|
getAllResponseHeaders: function() {
|
|
return completed ? responseHeadersString : null;
|
|
},
|
|
|
|
// Caches the header
|
|
setRequestHeader: function( name, value ) {
|
|
if ( completed == null ) {
|
|
name = requestHeadersNames[ name.toLowerCase() ] =
|
|
requestHeadersNames[ name.toLowerCase() ] || name;
|
|
requestHeaders[ name ] = value;
|
|
}
|
|
return this;
|
|
},
|
|
|
|
// Overrides response content-type header
|
|
overrideMimeType: function( type ) {
|
|
if ( completed == null ) {
|
|
s.mimeType = type;
|
|
}
|
|
return this;
|
|
},
|
|
|
|
// Status-dependent callbacks
|
|
statusCode: function( map ) {
|
|
var code;
|
|
if ( map ) {
|
|
if ( completed ) {
|
|
|
|
// Execute the appropriate callbacks
|
|
jqXHR.always( map[ jqXHR.status ] );
|
|
} else {
|
|
|
|
// Lazy-add the new callbacks in a way that preserves old ones
|
|
for ( code in map ) {
|
|
statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
|
|
}
|
|
}
|
|
}
|
|
return this;
|
|
},
|
|
|
|
// Cancel the request
|
|
abort: function( statusText ) {
|
|
var finalText = statusText || strAbort;
|
|
if ( transport ) {
|
|
transport.abort( finalText );
|
|
}
|
|
done( 0, finalText );
|
|
return this;
|
|
}
|
|
};
|
|
|
|
// Attach deferreds
|
|
deferred.promise( jqXHR );
|
|
|
|
// Add protocol if not provided (prefilters might expect it)
|
|
// Handle falsy url in the settings object (#10093: consistency with old signature)
|
|
// We also use the url parameter if available
|
|
s.url = ( ( url || s.url || location.href ) + "" )
|
|
.replace( rprotocol, location.protocol + "//" );
|
|
|
|
// Alias method option to type as per ticket #12004
|
|
s.type = options.method || options.type || s.method || s.type;
|
|
|
|
// Extract dataTypes list
|
|
s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
|
|
|
|
// A cross-domain request is in order when the origin doesn't match the current origin.
|
|
if ( s.crossDomain == null ) {
|
|
urlAnchor = document.createElement( "a" );
|
|
|
|
// Support: IE <=8 - 11, Edge 12 - 15
|
|
// IE throws exception on accessing the href property if url is malformed,
|
|
// e.g. http://example.com:80x/
|
|
try {
|
|
urlAnchor.href = s.url;
|
|
|
|
// Support: IE <=8 - 11 only
|
|
// Anchor's host property isn't correctly set when s.url is relative
|
|
urlAnchor.href = urlAnchor.href;
|
|
s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
|
|
urlAnchor.protocol + "//" + urlAnchor.host;
|
|
} catch ( e ) {
|
|
|
|
// If there is an error parsing the URL, assume it is crossDomain,
|
|
// it can be rejected by the transport if it is invalid
|
|
s.crossDomain = true;
|
|
}
|
|
}
|
|
|
|
// Convert data if not already a string
|
|
if ( s.data && s.processData && typeof s.data !== "string" ) {
|
|
s.data = jQuery.param( s.data, s.traditional );
|
|
}
|
|
|
|
// Apply prefilters
|
|
inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
|
|
|
|
// If request was aborted inside a prefilter, stop there
|
|
if ( completed ) {
|
|
return jqXHR;
|
|
}
|
|
|
|
// We can fire global events as of now if asked to
|
|
// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
|
|
fireGlobals = jQuery.event && s.global;
|
|
|
|
// Watch for a new set of requests
|
|
if ( fireGlobals && jQuery.active++ === 0 ) {
|
|
jQuery.event.trigger( "ajaxStart" );
|
|
}
|
|
|
|
// Uppercase the type
|
|
s.type = s.type.toUpperCase();
|
|
|
|
// Determine if request has content
|
|
s.hasContent = !rnoContent.test( s.type );
|
|
|
|
// Save the URL in case we're toying with the If-Modified-Since
|
|
// and/or If-None-Match header later on
|
|
// Remove hash to simplify url manipulation
|
|
cacheURL = s.url.replace( rhash, "" );
|
|
|
|
// More options handling for requests with no content
|
|
if ( !s.hasContent ) {
|
|
|
|
// Remember the hash so we can put it back
|
|
uncached = s.url.slice( cacheURL.length );
|
|
|
|
// If data is available and should be processed, append data to url
|
|
if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
|
|
cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
|
|
|
|
// #9682: remove data so that it's not used in an eventual retry
|
|
delete s.data;
|
|
}
|
|
|
|
// Add or update anti-cache param if needed
|
|
if ( s.cache === false ) {
|
|
cacheURL = cacheURL.replace( rantiCache, "$1" );
|
|
uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
|
|
uncached;
|
|
}
|
|
|
|
// Put hash and anti-cache on the URL that will be requested (gh-1732)
|
|
s.url = cacheURL + uncached;
|
|
|
|
// Change '%20' to '+' if this is encoded form body content (gh-2658)
|
|
} else if ( s.data && s.processData &&
|
|
( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
|
|
s.data = s.data.replace( r20, "+" );
|
|
}
|
|
|
|
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
|
if ( s.ifModified ) {
|
|
if ( jQuery.lastModified[ cacheURL ] ) {
|
|
jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
|
|
}
|
|
if ( jQuery.etag[ cacheURL ] ) {
|
|
jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
|
|
}
|
|
}
|
|
|
|
// Set the correct header, if data is being sent
|
|
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
|
|
jqXHR.setRequestHeader( "Content-Type", s.contentType );
|
|
}
|
|
|
|
// Set the Accepts header for the server, depending on the dataType
|
|
jqXHR.setRequestHeader(
|
|
"Accept",
|
|
s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
|
|
s.accepts[ s.dataTypes[ 0 ] ] +
|
|
( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
|
|
s.accepts[ "*" ]
|
|
);
|
|
|
|
// Check for headers option
|
|
for ( i in s.headers ) {
|
|
jqXHR.setRequestHeader( i, s.headers[ i ] );
|
|
}
|
|
|
|
// Allow custom headers/mimetypes and early abort
|
|
if ( s.beforeSend &&
|
|
( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
|
|
|
|
// Abort if not done already and return
|
|
return jqXHR.abort();
|
|
}
|
|
|
|
// Aborting is no longer a cancellation
|
|
strAbort = "abort";
|
|
|
|
// Install callbacks on deferreds
|
|
completeDeferred.add( s.complete );
|
|
jqXHR.done( s.success );
|
|
jqXHR.fail( s.error );
|
|
|
|
// Get transport
|
|
transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
|
|
|
|
// If no transport, we auto-abort
|
|
if ( !transport ) {
|
|
done( -1, "No Transport" );
|
|
} else {
|
|
jqXHR.readyState = 1;
|
|
|
|
// Send global event
|
|
if ( fireGlobals ) {
|
|
globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
|
|
}
|
|
|
|
// If request was aborted inside ajaxSend, stop there
|
|
if ( completed ) {
|
|
return jqXHR;
|
|
}
|
|
|
|
// Timeout
|
|
if ( s.async && s.timeout > 0 ) {
|
|
timeoutTimer = window.setTimeout( function() {
|
|
jqXHR.abort( "timeout" );
|
|
}, s.timeout );
|
|
}
|
|
|
|
try {
|
|
completed = false;
|
|
transport.send( requestHeaders, done );
|
|
} catch ( e ) {
|
|
|
|
// Rethrow post-completion exceptions
|
|
if ( completed ) {
|
|
throw e;
|
|
}
|
|
|
|
// Propagate others as results
|
|
done( -1, e );
|
|
}
|
|
}
|
|
|
|
// Callback for when everything is done
|
|
function done( status, nativeStatusText, responses, headers ) {
|
|
var isSuccess, success, error, response, modified,
|
|
statusText = nativeStatusText;
|
|
|
|
// Ignore repeat invocations
|
|
if ( completed ) {
|
|
return;
|
|
}
|
|
|
|
completed = true;
|
|
|
|
// Clear timeout if it exists
|
|
if ( timeoutTimer ) {
|
|
window.clearTimeout( timeoutTimer );
|
|
}
|
|
|
|
// Dereference transport for early garbage collection
|
|
// (no matter how long the jqXHR object will be used)
|
|
transport = undefined;
|
|
|
|
// Cache response headers
|
|
responseHeadersString = headers || "";
|
|
|
|
// Set readyState
|
|
jqXHR.readyState = status > 0 ? 4 : 0;
|
|
|
|
// Determine if successful
|
|
isSuccess = status >= 200 && status < 300 || status === 304;
|
|
|
|
// Get response data
|
|
if ( responses ) {
|
|
response = ajaxHandleResponses( s, jqXHR, responses );
|
|
}
|
|
|
|
// Use a noop converter for missing script but not if jsonp
|
|
if ( !isSuccess &&
|
|
jQuery.inArray( "script", s.dataTypes ) > -1 &&
|
|
jQuery.inArray( "json", s.dataTypes ) < 0 ) {
|
|
s.converters[ "text script" ] = function() {};
|
|
}
|
|
|
|
// Convert no matter what (that way responseXXX fields are always set)
|
|
response = ajaxConvert( s, response, jqXHR, isSuccess );
|
|
|
|
// If successful, handle type chaining
|
|
if ( isSuccess ) {
|
|
|
|
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
|
if ( s.ifModified ) {
|
|
modified = jqXHR.getResponseHeader( "Last-Modified" );
|
|
if ( modified ) {
|
|
jQuery.lastModified[ cacheURL ] = modified;
|
|
}
|
|
modified = jqXHR.getResponseHeader( "etag" );
|
|
if ( modified ) {
|
|
jQuery.etag[ cacheURL ] = modified;
|
|
}
|
|
}
|
|
|
|
// if no content
|
|
if ( status === 204 || s.type === "HEAD" ) {
|
|
statusText = "nocontent";
|
|
|
|
// if not modified
|
|
} else if ( status === 304 ) {
|
|
statusText = "notmodified";
|
|
|
|
// If we have data, let's convert it
|
|
} else {
|
|
statusText = response.state;
|
|
success = response.data;
|
|
error = response.error;
|
|
isSuccess = !error;
|
|
}
|
|
} else {
|
|
|
|
// Extract error from statusText and normalize for non-aborts
|
|
error = statusText;
|
|
if ( status || !statusText ) {
|
|
statusText = "error";
|
|
if ( status < 0 ) {
|
|
status = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set data for the fake xhr object
|
|
jqXHR.status = status;
|
|
jqXHR.statusText = ( nativeStatusText || statusText ) + "";
|
|
|
|
// Success/Error
|
|
if ( isSuccess ) {
|
|
deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
|
|
} else {
|
|
deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
|
|
}
|
|
|
|
// Status-dependent callbacks
|
|
jqXHR.statusCode( statusCode );
|
|
statusCode = undefined;
|
|
|
|
if ( fireGlobals ) {
|
|
globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
|
|
[ jqXHR, s, isSuccess ? success : error ] );
|
|
}
|
|
|
|
// Complete
|
|
completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
|
|
|
|
if ( fireGlobals ) {
|
|
globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
|
|
|
|
// Handle the global AJAX counter
|
|
if ( !( --jQuery.active ) ) {
|
|
jQuery.event.trigger( "ajaxStop" );
|
|
}
|
|
}
|
|
}
|
|
|
|
return jqXHR;
|
|
},
|
|
|
|
getJSON: function( url, data, callback ) {
|
|
return jQuery.get( url, data, callback, "json" );
|
|
},
|
|
|
|
getScript: function( url, callback ) {
|
|
return jQuery.get( url, undefined, callback, "script" );
|
|
}
|
|
} );
|
|
|
|
jQuery.each( [ "get", "post" ], function( _i, method ) {
|
|
jQuery[ method ] = function( url, data, callback, type ) {
|
|
|
|
// Shift arguments if data argument was omitted
|
|
if ( isFunction( data ) ) {
|
|
type = type || callback;
|
|
callback = data;
|
|
data = undefined;
|
|
}
|
|
|
|
// The url can be an options object (which then must have .url)
|
|
return jQuery.ajax( jQuery.extend( {
|
|
url: url,
|
|
type: method,
|
|
dataType: type,
|
|
data: data,
|
|
success: callback
|
|
}, jQuery.isPlainObject( url ) && url ) );
|
|
};
|
|
} );
|
|
|
|
jQuery.ajaxPrefilter( function( s ) {
|
|
var i;
|
|
for ( i in s.headers ) {
|
|
if ( i.toLowerCase() === "content-type" ) {
|
|
s.contentType = s.headers[ i ] || "";
|
|
}
|
|
}
|
|
} );
|
|
|
|
|
|
jQuery._evalUrl = function( url, options, doc ) {
|
|
return jQuery.ajax( {
|
|
url: url,
|
|
|
|
// Make this explicit, since user can override this through ajaxSetup (#11264)
|
|
type: "GET",
|
|
dataType: "script",
|
|
cache: true,
|
|
async: false,
|
|
global: false,
|
|
|
|
// Only evaluate the response if it is successful (gh-4126)
|
|
// dataFilter is not invoked for failure responses, so using it instead
|
|
// of the default converter is kludgy but it works.
|
|
converters: {
|
|
"text script": function() {}
|
|
},
|
|
dataFilter: function( response ) {
|
|
jQuery.globalEval( response, options, doc );
|
|
}
|
|
} );
|
|
};
|
|
|
|
|
|
jQuery.fn.extend( {
|
|
wrapAll: function( html ) {
|
|
var wrap;
|
|
|
|
if ( this[ 0 ] ) {
|
|
if ( isFunction( html ) ) {
|
|
html = html.call( this[ 0 ] );
|
|
}
|
|
|
|
// The elements to wrap the target around
|
|
wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
|
|
|
|
if ( this[ 0 ].parentNode ) {
|
|
wrap.insertBefore( this[ 0 ] );
|
|
}
|
|
|
|
wrap.map( function() {
|
|
var elem = this;
|
|
|
|
while ( elem.firstElementChild ) {
|
|
elem = elem.firstElementChild;
|
|
}
|
|
|
|
return elem;
|
|
} ).append( this );
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
wrapInner: function( html ) {
|
|
if ( isFunction( html ) ) {
|
|
return this.each( function( i ) {
|
|
jQuery( this ).wrapInner( html.call( this, i ) );
|
|
} );
|
|
}
|
|
|
|
return this.each( function() {
|
|
var self = jQuery( this ),
|
|
contents = self.contents();
|
|
|
|
if ( contents.length ) {
|
|
contents.wrapAll( html );
|
|
|
|
} else {
|
|
self.append( html );
|
|
}
|
|
} );
|
|
},
|
|
|
|
wrap: function( html ) {
|
|
var htmlIsFunction = isFunction( html );
|
|
|
|
return this.each( function( i ) {
|
|
jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
|
|
} );
|
|
},
|
|
|
|
unwrap: function( selector ) {
|
|
this.parent( selector ).not( "body" ).each( function() {
|
|
jQuery( this ).replaceWith( this.childNodes );
|
|
} );
|
|
return this;
|
|
}
|
|
} );
|
|
|
|
|
|
jQuery.expr.pseudos.hidden = function( elem ) {
|
|
return !jQuery.expr.pseudos.visible( elem );
|
|
};
|
|
jQuery.expr.pseudos.visible = function( elem ) {
|
|
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
|
|
};
|
|
|
|
|
|
|
|
|
|
jQuery.ajaxSettings.xhr = function() {
|
|
try {
|
|
return new window.XMLHttpRequest();
|
|
} catch ( e ) {}
|
|
};
|
|
|
|
var xhrSuccessStatus = {
|
|
|
|
// File protocol always yields status code 0, assume 200
|
|
0: 200,
|
|
|
|
// Support: IE <=9 only
|
|
// #1450: sometimes IE returns 1223 when it should be 204
|
|
1223: 204
|
|
},
|
|
xhrSupported = jQuery.ajaxSettings.xhr();
|
|
|
|
support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
|
|
support.ajax = xhrSupported = !!xhrSupported;
|
|
|
|
jQuery.ajaxTransport( function( options ) {
|
|
var callback, errorCallback;
|
|
|
|
// Cross domain only allowed if supported through XMLHttpRequest
|
|
if ( support.cors || xhrSupported && !options.crossDomain ) {
|
|
return {
|
|
send: function( headers, complete ) {
|
|
var i,
|
|
xhr = options.xhr();
|
|
|
|
xhr.open(
|
|
options.type,
|
|
options.url,
|
|
options.async,
|
|
options.username,
|
|
options.password
|
|
);
|
|
|
|
// Apply custom fields if provided
|
|
if ( options.xhrFields ) {
|
|
for ( i in options.xhrFields ) {
|
|
xhr[ i ] = options.xhrFields[ i ];
|
|
}
|
|
}
|
|
|
|
// Override mime type if needed
|
|
if ( options.mimeType && xhr.overrideMimeType ) {
|
|
xhr.overrideMimeType( options.mimeType );
|
|
}
|
|
|
|
// X-Requested-With header
|
|
// For cross-domain requests, seeing as conditions for a preflight are
|
|
// akin to a jigsaw puzzle, we simply never set it to be sure.
|
|
// (it can always be set on a per-request basis or even using ajaxSetup)
|
|
// For same-domain requests, won't change header if already provided.
|
|
if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
|
|
headers[ "X-Requested-With" ] = "XMLHttpRequest";
|
|
}
|
|
|
|
// Set headers
|
|
for ( i in headers ) {
|
|
xhr.setRequestHeader( i, headers[ i ] );
|
|
}
|
|
|
|
// Callback
|
|
callback = function( type ) {
|
|
return function() {
|
|
if ( callback ) {
|
|
callback = errorCallback = xhr.onload =
|
|
xhr.onerror = xhr.onabort = xhr.ontimeout =
|
|
xhr.onreadystatechange = null;
|
|
|
|
if ( type === "abort" ) {
|
|
xhr.abort();
|
|
} else if ( type === "error" ) {
|
|
|
|
// Support: IE <=9 only
|
|
// On a manual native abort, IE9 throws
|
|
// errors on any property access that is not readyState
|
|
if ( typeof xhr.status !== "number" ) {
|
|
complete( 0, "error" );
|
|
} else {
|
|
complete(
|
|
|
|
// File: protocol always yields status 0; see #8605, #14207
|
|
xhr.status,
|
|
xhr.statusText
|
|
);
|
|
}
|
|
} else {
|
|
complete(
|
|
xhrSuccessStatus[ xhr.status ] || xhr.status,
|
|
xhr.statusText,
|
|
|
|
// Support: IE <=9 only
|
|
// IE9 has no XHR2 but throws on binary (trac-11426)
|
|
// For XHR2 non-text, let the caller handle it (gh-2498)
|
|
( xhr.responseType || "text" ) !== "text" ||
|
|
typeof xhr.responseText !== "string" ?
|
|
{ binary: xhr.response } :
|
|
{ text: xhr.responseText },
|
|
xhr.getAllResponseHeaders()
|
|
);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
// Listen to events
|
|
xhr.onload = callback();
|
|
errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
|
|
|
|
// Support: IE 9 only
|
|
// Use onreadystatechange to replace onabort
|
|
// to handle uncaught aborts
|
|
if ( xhr.onabort !== undefined ) {
|
|
xhr.onabort = errorCallback;
|
|
} else {
|
|
xhr.onreadystatechange = function() {
|
|
|
|
// Check readyState before timeout as it changes
|
|
if ( xhr.readyState === 4 ) {
|
|
|
|
// Allow onerror to be called first,
|
|
// but that will not handle a native abort
|
|
// Also, save errorCallback to a variable
|
|
// as xhr.onerror cannot be accessed
|
|
window.setTimeout( function() {
|
|
if ( callback ) {
|
|
errorCallback();
|
|
}
|
|
} );
|
|
}
|
|
};
|
|
}
|
|
|
|
// Create the abort callback
|
|
callback = callback( "abort" );
|
|
|
|
try {
|
|
|
|
// Do send the request (this may raise an exception)
|
|
xhr.send( options.hasContent && options.data || null );
|
|
} catch ( e ) {
|
|
|
|
// #14683: Only rethrow if this hasn't been notified as an error yet
|
|
if ( callback ) {
|
|
throw e;
|
|
}
|
|
}
|
|
},
|
|
|
|
abort: function() {
|
|
if ( callback ) {
|
|
callback();
|
|
}
|
|
}
|
|
};
|
|
}
|
|
} );
|
|
|
|
|
|
|
|
|
|
// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
|
|
jQuery.ajaxPrefilter( function( s ) {
|
|
if ( s.crossDomain ) {
|
|
s.contents.script = false;
|
|
}
|
|
} );
|
|
|
|
// Install script dataType
|
|
jQuery.ajaxSetup( {
|
|
accepts: {
|
|
script: "text/javascript, application/javascript, " +
|
|
"application/ecmascript, application/x-ecmascript"
|
|
},
|
|
contents: {
|
|
script: /\b(?:java|ecma)script\b/
|
|
},
|
|
converters: {
|
|
"text script": function( text ) {
|
|
jQuery.globalEval( text );
|
|
return text;
|
|
}
|
|
}
|
|
} );
|
|
|
|
// Handle cache's special case and crossDomain
|
|
jQuery.ajaxPrefilter( "script", function( s ) {
|
|
if ( s.cache === undefined ) {
|
|
s.cache = false;
|
|
}
|
|
if ( s.crossDomain ) {
|
|
s.type = "GET";
|
|
}
|
|
} );
|
|
|
|
// Bind script tag hack transport
|
|
jQuery.ajaxTransport( "script", function( s ) {
|
|
|
|
// This transport only deals with cross domain or forced-by-attrs requests
|
|
if ( s.crossDomain || s.scriptAttrs ) {
|
|
var script, callback;
|
|
return {
|
|
send: function( _, complete ) {
|
|
script = jQuery( "<script>" )
|
|
.attr( s.scriptAttrs || {} )
|
|
.prop( { charset: s.scriptCharset, src: s.url } )
|
|
.on( "load error", callback = function( evt ) {
|
|
script.remove();
|
|
callback = null;
|
|
if ( evt ) {
|
|
complete( evt.type === "error" ? 404 : 200, evt.type );
|
|
}
|
|
} );
|
|
|
|
// Use native DOM manipulation to avoid our domManip AJAX trickery
|
|
document.head.appendChild( script[ 0 ] );
|
|
},
|
|
abort: function() {
|
|
if ( callback ) {
|
|
callback();
|
|
}
|
|
}
|
|
};
|
|
}
|
|
} );
|
|
|
|
|
|
|
|
|
|
var oldCallbacks = [],
|
|
rjsonp = /(=)\?(?=&|$)|\?\?/;
|
|
|
|
// Default jsonp settings
|
|
jQuery.ajaxSetup( {
|
|
jsonp: "callback",
|
|
jsonpCallback: function() {
|
|
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
|
|
this[ callback ] = true;
|
|
return callback;
|
|
}
|
|
} );
|
|
|
|
// Detect, normalize options and install callbacks for jsonp requests
|
|
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
|
|
|
|
var callbackName, overwritten, responseContainer,
|
|
jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
|
|
"url" :
|
|
typeof s.data === "string" &&
|
|
( s.contentType || "" )
|
|
.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
|
|
rjsonp.test( s.data ) && "data"
|
|
);
|
|
|
|
// Handle iff the expected data type is "jsonp" or we have a parameter to set
|
|
if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
|
|
|
|
// Get callback name, remembering preexisting value associated with it
|
|
callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
|
|
s.jsonpCallback() :
|
|
s.jsonpCallback;
|
|
|
|
// Insert callback into url or form data
|
|
if ( jsonProp ) {
|
|
s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
|
|
} else if ( s.jsonp !== false ) {
|
|
s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
|
|
}
|
|
|
|
// Use data converter to retrieve json after script execution
|
|
s.converters[ "script json" ] = function() {
|
|
if ( !responseContainer ) {
|
|
jQuery.error( callbackName + " was not called" );
|
|
}
|
|
return responseContainer[ 0 ];
|
|
};
|
|
|
|
// Force json dataType
|
|
s.dataTypes[ 0 ] = "json";
|
|
|
|
// Install callback
|
|
overwritten = window[ callbackName ];
|
|
window[ callbackName ] = function() {
|
|
responseContainer = arguments;
|
|
};
|
|
|
|
// Clean-up function (fires after converters)
|
|
jqXHR.always( function() {
|
|
|
|
// If previous value didn't exist - remove it
|
|
if ( overwritten === undefined ) {
|
|
jQuery( window ).removeProp( callbackName );
|
|
|
|
// Otherwise restore preexisting value
|
|
} else {
|
|
window[ callbackName ] = overwritten;
|
|
}
|
|
|
|
// Save back as free
|
|
if ( s[ callbackName ] ) {
|
|
|
|
// Make sure that re-using the options doesn't screw things around
|
|
s.jsonpCallback = originalSettings.jsonpCallback;
|
|
|
|
// Save the callback name for future use
|
|
oldCallbacks.push( callbackName );
|
|
}
|
|
|
|
// Call if it was a function and we have a response
|
|
if ( responseContainer && isFunction( overwritten ) ) {
|
|
overwritten( responseContainer[ 0 ] );
|
|
}
|
|
|
|
responseContainer = overwritten = undefined;
|
|
} );
|
|
|
|
// Delegate to script
|
|
return "script";
|
|
}
|
|
} );
|
|
|
|
|
|
|
|
|
|
// Support: Safari 8 only
|
|
// In Safari 8 documents created via document.implementation.createHTMLDocument
|
|
// collapse sibling forms: the second one becomes a child of the first one.
|
|
// Because of that, this security measure has to be disabled in Safari 8.
|
|
// https://bugs.webkit.org/show_bug.cgi?id=137337
|
|
support.createHTMLDocument = ( function() {
|
|
var body = document.implementation.createHTMLDocument( "" ).body;
|
|
body.innerHTML = "<form></form><form></form>";
|
|
return body.childNodes.length === 2;
|
|
} )();
|
|
|
|
|
|
// Argument "data" should be string of html
|
|
// context (optional): If specified, the fragment will be created in this context,
|
|
// defaults to document
|
|
// keepScripts (optional): If true, will include scripts passed in the html string
|
|
jQuery.parseHTML = function( data, context, keepScripts ) {
|
|
if ( typeof data !== "string" ) {
|
|
return [];
|
|
}
|
|
if ( typeof context === "boolean" ) {
|
|
keepScripts = context;
|
|
context = false;
|
|
}
|
|
|
|
var base, parsed, scripts;
|
|
|
|
if ( !context ) {
|
|
|
|
// Stop scripts or inline event handlers from being executed immediately
|
|
// by using document.implementation
|
|
if ( support.createHTMLDocument ) {
|
|
context = document.implementation.createHTMLDocument( "" );
|
|
|
|
// Set the base href for the created document
|
|
// so any parsed elements with URLs
|
|
// are based on the document's URL (gh-2965)
|
|
base = context.createElement( "base" );
|
|
base.href = document.location.href;
|
|
context.head.appendChild( base );
|
|
} else {
|
|
context = document;
|
|
}
|
|
}
|
|
|
|
parsed = rsingleTag.exec( data );
|
|
scripts = !keepScripts && [];
|
|
|
|
// Single tag
|
|
if ( parsed ) {
|
|
return [ context.createElement( parsed[ 1 ] ) ];
|
|
}
|
|
|
|
parsed = buildFragment( [ data ], context, scripts );
|
|
|
|
if ( scripts && scripts.length ) {
|
|
jQuery( scripts ).remove();
|
|
}
|
|
|
|
return jQuery.merge( [], parsed.childNodes );
|
|
};
|
|
|
|
|
|
/**
|
|
* Load a url into a page
|
|
*/
|
|
jQuery.fn.load = function( url, params, callback ) {
|
|
var selector, type, response,
|
|
self = this,
|
|
off = url.indexOf( " " );
|
|
|
|
if ( off > -1 ) {
|
|
selector = stripAndCollapse( url.slice( off ) );
|
|
url = url.slice( 0, off );
|
|
}
|
|
|
|
// If it's a function
|
|
if ( isFunction( params ) ) {
|
|
|
|
// We assume that it's the callback
|
|
callback = params;
|
|
params = undefined;
|
|
|
|
// Otherwise, build a param string
|
|
} else if ( params && typeof params === "object" ) {
|
|
type = "POST";
|
|
}
|
|
|
|
// If we have elements to modify, make the request
|
|
if ( self.length > 0 ) {
|
|
jQuery.ajax( {
|
|
url: url,
|
|
|
|
// If "type" variable is undefined, then "GET" method will be used.
|
|
// Make value of this field explicit since
|
|
// user can override it through ajaxSetup method
|
|
type: type || "GET",
|
|
dataType: "html",
|
|
data: params
|
|
} ).done( function( responseText ) {
|
|
|
|
// Save response for use in complete callback
|
|
response = arguments;
|
|
|
|
self.html( selector ?
|
|
|
|
// If a selector was specified, locate the right elements in a dummy div
|
|
// Exclude scripts to avoid IE 'Permission Denied' errors
|
|
jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
|
|
|
|
// Otherwise use the full result
|
|
responseText );
|
|
|
|
// If the request succeeds, this function gets "data", "status", "jqXHR"
|
|
// but they are ignored because response was set above.
|
|
// If it fails, this function gets "jqXHR", "status", "error"
|
|
} ).always( callback && function( jqXHR, status ) {
|
|
self.each( function() {
|
|
callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
|
|
} );
|
|
} );
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
|
|
|
|
|
|
jQuery.expr.pseudos.animated = function( elem ) {
|
|
return jQuery.grep( jQuery.timers, function( fn ) {
|
|
return elem === fn.elem;
|
|
} ).length;
|
|
};
|
|
|
|
|
|
|
|
|
|
jQuery.offset = {
|
|
setOffset: function( elem, options, i ) {
|
|
var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
|
|
position = jQuery.css( elem, "position" ),
|
|
curElem = jQuery( elem ),
|
|
props = {};
|
|
|
|
// Set position first, in-case top/left are set even on static elem
|
|
if ( position === "static" ) {
|
|
elem.style.position = "relative";
|
|
}
|
|
|
|
curOffset = curElem.offset();
|
|
curCSSTop = jQuery.css( elem, "top" );
|
|
curCSSLeft = jQuery.css( elem, "left" );
|
|
calculatePosition = ( position === "absolute" || position === "fixed" ) &&
|
|
( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
|
|
|
|
// Need to be able to calculate position if either
|
|
// top or left is auto and position is either absolute or fixed
|
|
if ( calculatePosition ) {
|
|
curPosition = curElem.position();
|
|
curTop = curPosition.top;
|
|
curLeft = curPosition.left;
|
|
|
|
} else {
|
|
curTop = parseFloat( curCSSTop ) || 0;
|
|
curLeft = parseFloat( curCSSLeft ) || 0;
|
|
}
|
|
|
|
if ( isFunction( options ) ) {
|
|
|
|
// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
|
|
options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
|
|
}
|
|
|
|
if ( options.top != null ) {
|
|
props.top = ( options.top - curOffset.top ) + curTop;
|
|
}
|
|
if ( options.left != null ) {
|
|
props.left = ( options.left - curOffset.left ) + curLeft;
|
|
}
|
|
|
|
if ( "using" in options ) {
|
|
options.using.call( elem, props );
|
|
|
|
} else {
|
|
curElem.css( props );
|
|
}
|
|
}
|
|
};
|
|
|
|
jQuery.fn.extend( {
|
|
|
|
// offset() relates an element's border box to the document origin
|
|
offset: function( options ) {
|
|
|
|
// Preserve chaining for setter
|
|
if ( arguments.length ) {
|
|
return options === undefined ?
|
|
this :
|
|
this.each( function( i ) {
|
|
jQuery.offset.setOffset( this, options, i );
|
|
} );
|
|
}
|
|
|
|
var rect, win,
|
|
elem = this[ 0 ];
|
|
|
|
if ( !elem ) {
|
|
return;
|
|
}
|
|
|
|
// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
|
|
// Support: IE <=11 only
|
|
// Running getBoundingClientRect on a
|
|
// disconnected node in IE throws an error
|
|
if ( !elem.getClientRects().length ) {
|
|
return { top: 0, left: 0 };
|
|
}
|
|
|
|
// Get document-relative position by adding viewport scroll to viewport-relative gBCR
|
|
rect = elem.getBoundingClientRect();
|
|
win = elem.ownerDocument.defaultView;
|
|
return {
|
|
top: rect.top + win.pageYOffset,
|
|
left: rect.left + win.pageXOffset
|
|
};
|
|
},
|
|
|
|
// position() relates an element's margin box to its offset parent's padding box
|
|
// This corresponds to the behavior of CSS absolute positioning
|
|
position: function() {
|
|
if ( !this[ 0 ] ) {
|
|
return;
|
|
}
|
|
|
|
var offsetParent, offset, doc,
|
|
elem = this[ 0 ],
|
|
parentOffset = { top: 0, left: 0 };
|
|
|
|
// position:fixed elements are offset from the viewport, which itself always has zero offset
|
|
if ( jQuery.css( elem, "position" ) === "fixed" ) {
|
|
|
|
// Assume position:fixed implies availability of getBoundingClientRect
|
|
offset = elem.getBoundingClientRect();
|
|
|
|
} else {
|
|
offset = this.offset();
|
|
|
|
// Account for the *real* offset parent, which can be the document or its root element
|
|
// when a statically positioned element is identified
|
|
doc = elem.ownerDocument;
|
|
offsetParent = elem.offsetParent || doc.documentElement;
|
|
while ( offsetParent &&
|
|
( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
|
|
jQuery.css( offsetParent, "position" ) === "static" ) {
|
|
|
|
offsetParent = offsetParent.parentNode;
|
|
}
|
|
if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
|
|
|
|
// Incorporate borders into its offset, since they are outside its content origin
|
|
parentOffset = jQuery( offsetParent ).offset();
|
|
parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
|
|
parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
|
|
}
|
|
}
|
|
|
|
// Subtract parent offsets and element margins
|
|
return {
|
|
top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
|
|
left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
|
|
};
|
|
},
|
|
|
|
// This method will return documentElement in the following cases:
|
|
// 1) For the element inside the iframe without offsetParent, this method will return
|
|
// documentElement of the parent window
|
|
// 2) For the hidden or detached element
|
|
// 3) For body or html element, i.e. in case of the html node - it will return itself
|
|
//
|
|
// but those exceptions were never presented as a real life use-cases
|
|
// and might be considered as more preferable results.
|
|
//
|
|
// This logic, however, is not guaranteed and can change at any point in the future
|
|
offsetParent: function() {
|
|
return this.map( function() {
|
|
var offsetParent = this.offsetParent;
|
|
|
|
while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
|
|
offsetParent = offsetParent.offsetParent;
|
|
}
|
|
|
|
return offsetParent || documentElement;
|
|
} );
|
|
}
|
|
} );
|
|
|
|
// Create scrollLeft and scrollTop methods
|
|
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
|
|
var top = "pageYOffset" === prop;
|
|
|
|
jQuery.fn[ method ] = function( val ) {
|
|
return access( this, function( elem, method, val ) {
|
|
|
|
// Coalesce documents and windows
|
|
var win;
|
|
if ( isWindow( elem ) ) {
|
|
win = elem;
|
|
} else if ( elem.nodeType === 9 ) {
|
|
win = elem.defaultView;
|
|
}
|
|
|
|
if ( val === undefined ) {
|
|
return win ? win[ prop ] : elem[ method ];
|
|
}
|
|
|
|
if ( win ) {
|
|
win.scrollTo(
|
|
!top ? val : win.pageXOffset,
|
|
top ? val : win.pageYOffset
|
|
);
|
|
|
|
} else {
|
|
elem[ method ] = val;
|
|
}
|
|
}, method, val, arguments.length );
|
|
};
|
|
} );
|
|
|
|
// Support: Safari <=7 - 9.1, Chrome <=37 - 49
|
|
// Add the top/left cssHooks using jQuery.fn.position
|
|
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
|
|
// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
|
|
// getComputedStyle returns percent when specified for top/left/bottom/right;
|
|
// rather than make the css module depend on the offset module, just check for it here
|
|
jQuery.each( [ "top", "left" ], function( _i, prop ) {
|
|
jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
|
|
function( elem, computed ) {
|
|
if ( computed ) {
|
|
computed = curCSS( elem, prop );
|
|
|
|
// If curCSS returns percentage, fallback to offset
|
|
return rnumnonpx.test( computed ) ?
|
|
jQuery( elem ).position()[ prop ] + "px" :
|
|
computed;
|
|
}
|
|
}
|
|
);
|
|
} );
|
|
|
|
|
|
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
|
|
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
|
|
jQuery.each( {
|
|
padding: "inner" + name,
|
|
content: type,
|
|
"": "outer" + name
|
|
}, function( defaultExtra, funcName ) {
|
|
|
|
// Margin is only for outerHeight, outerWidth
|
|
jQuery.fn[ funcName ] = function( margin, value ) {
|
|
var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
|
|
extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
|
|
|
|
return access( this, function( elem, type, value ) {
|
|
var doc;
|
|
|
|
if ( isWindow( elem ) ) {
|
|
|
|
// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
|
|
return funcName.indexOf( "outer" ) === 0 ?
|
|
elem[ "inner" + name ] :
|
|
elem.document.documentElement[ "client" + name ];
|
|
}
|
|
|
|
// Get document width or height
|
|
if ( elem.nodeType === 9 ) {
|
|
doc = elem.documentElement;
|
|
|
|
// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
|
|
// whichever is greatest
|
|
return Math.max(
|
|
elem.body[ "scroll" + name ], doc[ "scroll" + name ],
|
|
elem.body[ "offset" + name ], doc[ "offset" + name ],
|
|
doc[ "client" + name ]
|
|
);
|
|
}
|
|
|
|
return value === undefined ?
|
|
|
|
// Get width or height on the element, requesting but not forcing parseFloat
|
|
jQuery.css( elem, type, extra ) :
|
|
|
|
// Set width or height on the element
|
|
jQuery.style( elem, type, value, extra );
|
|
}, type, chainable ? margin : undefined, chainable );
|
|
};
|
|
} );
|
|
} );
|
|
|
|
|
|
jQuery.each( [
|
|
"ajaxStart",
|
|
"ajaxStop",
|
|
"ajaxComplete",
|
|
"ajaxError",
|
|
"ajaxSuccess",
|
|
"ajaxSend"
|
|
], function( _i, type ) {
|
|
jQuery.fn[ type ] = function( fn ) {
|
|
return this.on( type, fn );
|
|
};
|
|
} );
|
|
|
|
|
|
|
|
|
|
jQuery.fn.extend( {
|
|
|
|
bind: function( types, data, fn ) {
|
|
return this.on( types, null, data, fn );
|
|
},
|
|
unbind: function( types, fn ) {
|
|
return this.off( types, null, fn );
|
|
},
|
|
|
|
delegate: function( selector, types, data, fn ) {
|
|
return this.on( types, selector, data, fn );
|
|
},
|
|
undelegate: function( selector, types, fn ) {
|
|
|
|
// ( namespace ) or ( selector, types [, fn] )
|
|
return arguments.length === 1 ?
|
|
this.off( selector, "**" ) :
|
|
this.off( types, selector || "**", fn );
|
|
},
|
|
|
|
hover: function( fnOver, fnOut ) {
|
|
return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
|
|
}
|
|
} );
|
|
|
|
jQuery.each(
|
|
( "blur focus focusin focusout resize scroll click dblclick " +
|
|
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
|
|
"change select submit keydown keypress keyup contextmenu" ).split( " " ),
|
|
function( _i, name ) {
|
|
|
|
// Handle event binding
|
|
jQuery.fn[ name ] = function( data, fn ) {
|
|
return arguments.length > 0 ?
|
|
this.on( name, null, data, fn ) :
|
|
this.trigger( name );
|
|
};
|
|
}
|
|
);
|
|
|
|
|
|
|
|
|
|
// Support: Android <=4.0 only
|
|
// Make sure we trim BOM and NBSP
|
|
var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
|
|
|
|
// Bind a function to a context, optionally partially applying any
|
|
// arguments.
|
|
// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
|
|
// However, it is not slated for removal any time soon
|
|
jQuery.proxy = function( fn, context ) {
|
|
var tmp, args, proxy;
|
|
|
|
if ( typeof context === "string" ) {
|
|
tmp = fn[ context ];
|
|
context = fn;
|
|
fn = tmp;
|
|
}
|
|
|
|
// Quick check to determine if target is callable, in the spec
|
|
// this throws a TypeError, but we will just return undefined.
|
|
if ( !isFunction( fn ) ) {
|
|
return undefined;
|
|
}
|
|
|
|
// Simulated bind
|
|
args = slice.call( arguments, 2 );
|
|
proxy = function() {
|
|
return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
|
|
};
|
|
|
|
// Set the guid of unique handler to the same of original handler, so it can be removed
|
|
proxy.guid = fn.guid = fn.guid || jQuery.guid++;
|
|
|
|
return proxy;
|
|
};
|
|
|
|
jQuery.holdReady = function( hold ) {
|
|
if ( hold ) {
|
|
jQuery.readyWait++;
|
|
} else {
|
|
jQuery.ready( true );
|
|
}
|
|
};
|
|
jQuery.isArray = Array.isArray;
|
|
jQuery.parseJSON = JSON.parse;
|
|
jQuery.nodeName = nodeName;
|
|
jQuery.isFunction = isFunction;
|
|
jQuery.isWindow = isWindow;
|
|
jQuery.camelCase = camelCase;
|
|
jQuery.type = toType;
|
|
|
|
jQuery.now = Date.now;
|
|
|
|
jQuery.isNumeric = function( obj ) {
|
|
|
|
// As of jQuery 3.0, isNumeric is limited to
|
|
// strings and numbers (primitives or objects)
|
|
// that can be coerced to finite numbers (gh-2662)
|
|
var type = jQuery.type( obj );
|
|
return ( type === "number" || type === "string" ) &&
|
|
|
|
// parseFloat NaNs numeric-cast false positives ("")
|
|
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
|
|
// subtraction forces infinities to NaN
|
|
!isNaN( obj - parseFloat( obj ) );
|
|
};
|
|
|
|
jQuery.trim = function( text ) {
|
|
return text == null ?
|
|
"" :
|
|
( text + "" ).replace( rtrim, "" );
|
|
};
|
|
|
|
|
|
|
|
// Register as a named AMD module, since jQuery can be concatenated with other
|
|
// files that may use define, but not via a proper concatenation script that
|
|
// understands anonymous AMD modules. A named AMD is safest and most robust
|
|
// way to register. Lowercase jquery is used because AMD module names are
|
|
// derived from file names, and jQuery is normally delivered in a lowercase
|
|
// file name. Do this after creating the global so that if an AMD module wants
|
|
// to call noConflict to hide this version of jQuery, it will work.
|
|
|
|
// Note that for maximum portability, libraries that are not jQuery should
|
|
// declare themselves as anonymous modules, and avoid setting a global if an
|
|
// AMD loader is present. jQuery is a special case. For more information, see
|
|
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
|
|
|
|
if ( typeof define === "function" && define.amd ) {
|
|
define( "jquery", [], function() {
|
|
return jQuery;
|
|
} );
|
|
}
|
|
|
|
|
|
|
|
|
|
var
|
|
|
|
// Map over jQuery in case of overwrite
|
|
_jQuery = window.jQuery,
|
|
|
|
// Map over the $ in case of overwrite
|
|
_$ = window.$;
|
|
|
|
jQuery.noConflict = function( deep ) {
|
|
if ( window.$ === jQuery ) {
|
|
window.$ = _$;
|
|
}
|
|
|
|
if ( deep && window.jQuery === jQuery ) {
|
|
window.jQuery = _jQuery;
|
|
}
|
|
|
|
return jQuery;
|
|
};
|
|
|
|
// Expose jQuery and $ identifiers, even in AMD
|
|
// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
|
|
// and CommonJS for browser emulators (#13566)
|
|
if ( typeof noGlobal === "undefined" ) {
|
|
window.jQuery = window.$ = jQuery;
|
|
}
|
|
|
|
|
|
|
|
|
|
return jQuery;
|
|
} );
|
|
|
|
},{}],59:[function(require,module,exports){
|
|
(function (Buffer){(function (){
|
|
;(function (sax) { // wrapper for non-node envs
|
|
sax.parser = function (strict, opt) { return new SAXParser(strict, opt) }
|
|
sax.SAXParser = SAXParser
|
|
sax.SAXStream = SAXStream
|
|
sax.createStream = createStream
|
|
|
|
// When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns.
|
|
// When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)),
|
|
// since that's the earliest that a buffer overrun could occur. This way, checks are
|
|
// as rare as required, but as often as necessary to ensure never crossing this bound.
|
|
// Furthermore, buffers are only tested at most once per write(), so passing a very
|
|
// large string into write() might have undesirable effects, but this is manageable by
|
|
// the caller, so it is assumed to be safe. Thus, a call to write() may, in the extreme
|
|
// edge case, result in creating at most one complete copy of the string passed in.
|
|
// Set to Infinity to have unlimited buffers.
|
|
sax.MAX_BUFFER_LENGTH = 64 * 1024
|
|
|
|
var buffers = [
|
|
'comment', 'sgmlDecl', 'textNode', 'tagName', 'doctype',
|
|
'procInstName', 'procInstBody', 'entity', 'attribName',
|
|
'attribValue', 'cdata', 'script'
|
|
]
|
|
|
|
sax.EVENTS = [
|
|
'text',
|
|
'processinginstruction',
|
|
'sgmldeclaration',
|
|
'doctype',
|
|
'comment',
|
|
'opentagstart',
|
|
'attribute',
|
|
'opentag',
|
|
'closetag',
|
|
'opencdata',
|
|
'cdata',
|
|
'closecdata',
|
|
'error',
|
|
'end',
|
|
'ready',
|
|
'script',
|
|
'opennamespace',
|
|
'closenamespace'
|
|
]
|
|
|
|
function SAXParser (strict, opt) {
|
|
if (!(this instanceof SAXParser)) {
|
|
return new SAXParser(strict, opt)
|
|
}
|
|
|
|
var parser = this
|
|
clearBuffers(parser)
|
|
parser.q = parser.c = ''
|
|
parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH
|
|
parser.opt = opt || {}
|
|
parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags
|
|
parser.looseCase = parser.opt.lowercase ? 'toLowerCase' : 'toUpperCase'
|
|
parser.tags = []
|
|
parser.closed = parser.closedRoot = parser.sawRoot = false
|
|
parser.tag = parser.error = null
|
|
parser.strict = !!strict
|
|
parser.noscript = !!(strict || parser.opt.noscript)
|
|
parser.state = S.BEGIN
|
|
parser.strictEntities = parser.opt.strictEntities
|
|
parser.ENTITIES = parser.strictEntities ? Object.create(sax.XML_ENTITIES) : Object.create(sax.ENTITIES)
|
|
parser.attribList = []
|
|
|
|
// namespaces form a prototype chain.
|
|
// it always points at the current tag,
|
|
// which protos to its parent tag.
|
|
if (parser.opt.xmlns) {
|
|
parser.ns = Object.create(rootNS)
|
|
}
|
|
|
|
// mostly just for error reporting
|
|
parser.trackPosition = parser.opt.position !== false
|
|
if (parser.trackPosition) {
|
|
parser.position = parser.line = parser.column = 0
|
|
}
|
|
emit(parser, 'onready')
|
|
}
|
|
|
|
if (!Object.create) {
|
|
Object.create = function (o) {
|
|
function F () {}
|
|
F.prototype = o
|
|
var newf = new F()
|
|
return newf
|
|
}
|
|
}
|
|
|
|
if (!Object.keys) {
|
|
Object.keys = function (o) {
|
|
var a = []
|
|
for (var i in o) if (o.hasOwnProperty(i)) a.push(i)
|
|
return a
|
|
}
|
|
}
|
|
|
|
function checkBufferLength (parser) {
|
|
var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10)
|
|
var maxActual = 0
|
|
for (var i = 0, l = buffers.length; i < l; i++) {
|
|
var len = parser[buffers[i]].length
|
|
if (len > maxAllowed) {
|
|
// Text/cdata nodes can get big, and since they're buffered,
|
|
// we can get here under normal conditions.
|
|
// Avoid issues by emitting the text node now,
|
|
// so at least it won't get any bigger.
|
|
switch (buffers[i]) {
|
|
case 'textNode':
|
|
closeText(parser)
|
|
break
|
|
|
|
case 'cdata':
|
|
emitNode(parser, 'oncdata', parser.cdata)
|
|
parser.cdata = ''
|
|
break
|
|
|
|
case 'script':
|
|
emitNode(parser, 'onscript', parser.script)
|
|
parser.script = ''
|
|
break
|
|
|
|
default:
|
|
error(parser, 'Max buffer length exceeded: ' + buffers[i])
|
|
}
|
|
}
|
|
maxActual = Math.max(maxActual, len)
|
|
}
|
|
// schedule the next check for the earliest possible buffer overrun.
|
|
var m = sax.MAX_BUFFER_LENGTH - maxActual
|
|
parser.bufferCheckPosition = m + parser.position
|
|
}
|
|
|
|
function clearBuffers (parser) {
|
|
for (var i = 0, l = buffers.length; i < l; i++) {
|
|
parser[buffers[i]] = ''
|
|
}
|
|
}
|
|
|
|
function flushBuffers (parser) {
|
|
closeText(parser)
|
|
if (parser.cdata !== '') {
|
|
emitNode(parser, 'oncdata', parser.cdata)
|
|
parser.cdata = ''
|
|
}
|
|
if (parser.script !== '') {
|
|
emitNode(parser, 'onscript', parser.script)
|
|
parser.script = ''
|
|
}
|
|
}
|
|
|
|
SAXParser.prototype = {
|
|
end: function () { end(this) },
|
|
write: write,
|
|
resume: function () { this.error = null; return this },
|
|
close: function () { return this.write(null) },
|
|
flush: function () { flushBuffers(this) }
|
|
}
|
|
|
|
var Stream
|
|
try {
|
|
Stream = require('stream').Stream
|
|
} catch (ex) {
|
|
Stream = function () {}
|
|
}
|
|
|
|
var streamWraps = sax.EVENTS.filter(function (ev) {
|
|
return ev !== 'error' && ev !== 'end'
|
|
})
|
|
|
|
function createStream (strict, opt) {
|
|
return new SAXStream(strict, opt)
|
|
}
|
|
|
|
function SAXStream (strict, opt) {
|
|
if (!(this instanceof SAXStream)) {
|
|
return new SAXStream(strict, opt)
|
|
}
|
|
|
|
Stream.apply(this)
|
|
|
|
this._parser = new SAXParser(strict, opt)
|
|
this.writable = true
|
|
this.readable = true
|
|
|
|
var me = this
|
|
|
|
this._parser.onend = function () {
|
|
me.emit('end')
|
|
}
|
|
|
|
this._parser.onerror = function (er) {
|
|
me.emit('error', er)
|
|
|
|
// if didn't throw, then means error was handled.
|
|
// go ahead and clear error, so we can write again.
|
|
me._parser.error = null
|
|
}
|
|
|
|
this._decoder = null
|
|
|
|
streamWraps.forEach(function (ev) {
|
|
Object.defineProperty(me, 'on' + ev, {
|
|
get: function () {
|
|
return me._parser['on' + ev]
|
|
},
|
|
set: function (h) {
|
|
if (!h) {
|
|
me.removeAllListeners(ev)
|
|
me._parser['on' + ev] = h
|
|
return h
|
|
}
|
|
me.on(ev, h)
|
|
},
|
|
enumerable: true,
|
|
configurable: false
|
|
})
|
|
})
|
|
}
|
|
|
|
SAXStream.prototype = Object.create(Stream.prototype, {
|
|
constructor: {
|
|
value: SAXStream
|
|
}
|
|
})
|
|
|
|
SAXStream.prototype.write = function (data) {
|
|
if (typeof Buffer === 'function' &&
|
|
typeof Buffer.isBuffer === 'function' &&
|
|
Buffer.isBuffer(data)) {
|
|
if (!this._decoder) {
|
|
var SD = require('string_decoder').StringDecoder
|
|
this._decoder = new SD('utf8')
|
|
}
|
|
data = this._decoder.write(data)
|
|
}
|
|
|
|
this._parser.write(data.toString())
|
|
this.emit('data', data)
|
|
return true
|
|
}
|
|
|
|
SAXStream.prototype.end = function (chunk) {
|
|
if (chunk && chunk.length) {
|
|
this.write(chunk)
|
|
}
|
|
this._parser.end()
|
|
return true
|
|
}
|
|
|
|
SAXStream.prototype.on = function (ev, handler) {
|
|
var me = this
|
|
if (!me._parser['on' + ev] && streamWraps.indexOf(ev) !== -1) {
|
|
me._parser['on' + ev] = function () {
|
|
var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments)
|
|
args.splice(0, 0, ev)
|
|
me.emit.apply(me, args)
|
|
}
|
|
}
|
|
|
|
return Stream.prototype.on.call(me, ev, handler)
|
|
}
|
|
|
|
// this really needs to be replaced with character classes.
|
|
// XML allows all manner of ridiculous numbers and digits.
|
|
var CDATA = '[CDATA['
|
|
var DOCTYPE = 'DOCTYPE'
|
|
var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'
|
|
var XMLNS_NAMESPACE = 'http://www.w3.org/2000/xmlns/'
|
|
var rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE }
|
|
|
|
// http://www.w3.org/TR/REC-xml/#NT-NameStartChar
|
|
// This implementation works on strings, a single character at a time
|
|
// as such, it cannot ever support astral-plane characters (10000-EFFFF)
|
|
// without a significant breaking change to either this parser, or the
|
|
// JavaScript language. Implementation of an emoji-capable xml parser
|
|
// is left as an exercise for the reader.
|
|
var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/
|
|
|
|
var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/
|
|
|
|
var entityStart = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/
|
|
var entityBody = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/
|
|
|
|
function isWhitespace (c) {
|
|
return c === ' ' || c === '\n' || c === '\r' || c === '\t'
|
|
}
|
|
|
|
function isQuote (c) {
|
|
return c === '"' || c === '\''
|
|
}
|
|
|
|
function isAttribEnd (c) {
|
|
return c === '>' || isWhitespace(c)
|
|
}
|
|
|
|
function isMatch (regex, c) {
|
|
return regex.test(c)
|
|
}
|
|
|
|
function notMatch (regex, c) {
|
|
return !isMatch(regex, c)
|
|
}
|
|
|
|
var S = 0
|
|
sax.STATE = {
|
|
BEGIN: S++, // leading byte order mark or whitespace
|
|
BEGIN_WHITESPACE: S++, // leading whitespace
|
|
TEXT: S++, // general stuff
|
|
TEXT_ENTITY: S++, // & and such.
|
|
OPEN_WAKA: S++, // <
|
|
SGML_DECL: S++, // <!BLARG
|
|
SGML_DECL_QUOTED: S++, // <!BLARG foo "bar
|
|
DOCTYPE: S++, // <!DOCTYPE
|
|
DOCTYPE_QUOTED: S++, // <!DOCTYPE "//blah
|
|
DOCTYPE_DTD: S++, // <!DOCTYPE "//blah" [ ...
|
|
DOCTYPE_DTD_QUOTED: S++, // <!DOCTYPE "//blah" [ "foo
|
|
COMMENT_STARTING: S++, // <!-
|
|
COMMENT: S++, // <!--
|
|
COMMENT_ENDING: S++, // <!-- blah -
|
|
COMMENT_ENDED: S++, // <!-- blah --
|
|
CDATA: S++, // <![CDATA[ something
|
|
CDATA_ENDING: S++, // ]
|
|
CDATA_ENDING_2: S++, // ]]
|
|
PROC_INST: S++, // <?hi
|
|
PROC_INST_BODY: S++, // <?hi there
|
|
PROC_INST_ENDING: S++, // <?hi "there" ?
|
|
OPEN_TAG: S++, // <strong
|
|
OPEN_TAG_SLASH: S++, // <strong /
|
|
ATTRIB: S++, // <a
|
|
ATTRIB_NAME: S++, // <a foo
|
|
ATTRIB_NAME_SAW_WHITE: S++, // <a foo _
|
|
ATTRIB_VALUE: S++, // <a foo=
|
|
ATTRIB_VALUE_QUOTED: S++, // <a foo="bar
|
|
ATTRIB_VALUE_CLOSED: S++, // <a foo="bar"
|
|
ATTRIB_VALUE_UNQUOTED: S++, // <a foo=bar
|
|
ATTRIB_VALUE_ENTITY_Q: S++, // <foo bar="""
|
|
ATTRIB_VALUE_ENTITY_U: S++, // <foo bar="
|
|
CLOSE_TAG: S++, // </a
|
|
CLOSE_TAG_SAW_WHITE: S++, // </a >
|
|
SCRIPT: S++, // <script> ...
|
|
SCRIPT_ENDING: S++ // <script> ... <
|
|
}
|
|
|
|
sax.XML_ENTITIES = {
|
|
'amp': '&',
|
|
'gt': '>',
|
|
'lt': '<',
|
|
'quot': '"',
|
|
'apos': "'"
|
|
}
|
|
|
|
sax.ENTITIES = {
|
|
'amp': '&',
|
|
'gt': '>',
|
|
'lt': '<',
|
|
'quot': '"',
|
|
'apos': "'",
|
|
'AElig': 198,
|
|
'Aacute': 193,
|
|
'Acirc': 194,
|
|
'Agrave': 192,
|
|
'Aring': 197,
|
|
'Atilde': 195,
|
|
'Auml': 196,
|
|
'Ccedil': 199,
|
|
'ETH': 208,
|
|
'Eacute': 201,
|
|
'Ecirc': 202,
|
|
'Egrave': 200,
|
|
'Euml': 203,
|
|
'Iacute': 205,
|
|
'Icirc': 206,
|
|
'Igrave': 204,
|
|
'Iuml': 207,
|
|
'Ntilde': 209,
|
|
'Oacute': 211,
|
|
'Ocirc': 212,
|
|
'Ograve': 210,
|
|
'Oslash': 216,
|
|
'Otilde': 213,
|
|
'Ouml': 214,
|
|
'THORN': 222,
|
|
'Uacute': 218,
|
|
'Ucirc': 219,
|
|
'Ugrave': 217,
|
|
'Uuml': 220,
|
|
'Yacute': 221,
|
|
'aacute': 225,
|
|
'acirc': 226,
|
|
'aelig': 230,
|
|
'agrave': 224,
|
|
'aring': 229,
|
|
'atilde': 227,
|
|
'auml': 228,
|
|
'ccedil': 231,
|
|
'eacute': 233,
|
|
'ecirc': 234,
|
|
'egrave': 232,
|
|
'eth': 240,
|
|
'euml': 235,
|
|
'iacute': 237,
|
|
'icirc': 238,
|
|
'igrave': 236,
|
|
'iuml': 239,
|
|
'ntilde': 241,
|
|
'oacute': 243,
|
|
'ocirc': 244,
|
|
'ograve': 242,
|
|
'oslash': 248,
|
|
'otilde': 245,
|
|
'ouml': 246,
|
|
'szlig': 223,
|
|
'thorn': 254,
|
|
'uacute': 250,
|
|
'ucirc': 251,
|
|
'ugrave': 249,
|
|
'uuml': 252,
|
|
'yacute': 253,
|
|
'yuml': 255,
|
|
'copy': 169,
|
|
'reg': 174,
|
|
'nbsp': 160,
|
|
'iexcl': 161,
|
|
'cent': 162,
|
|
'pound': 163,
|
|
'curren': 164,
|
|
'yen': 165,
|
|
'brvbar': 166,
|
|
'sect': 167,
|
|
'uml': 168,
|
|
'ordf': 170,
|
|
'laquo': 171,
|
|
'not': 172,
|
|
'shy': 173,
|
|
'macr': 175,
|
|
'deg': 176,
|
|
'plusmn': 177,
|
|
'sup1': 185,
|
|
'sup2': 178,
|
|
'sup3': 179,
|
|
'acute': 180,
|
|
'micro': 181,
|
|
'para': 182,
|
|
'middot': 183,
|
|
'cedil': 184,
|
|
'ordm': 186,
|
|
'raquo': 187,
|
|
'frac14': 188,
|
|
'frac12': 189,
|
|
'frac34': 190,
|
|
'iquest': 191,
|
|
'times': 215,
|
|
'divide': 247,
|
|
'OElig': 338,
|
|
'oelig': 339,
|
|
'Scaron': 352,
|
|
'scaron': 353,
|
|
'Yuml': 376,
|
|
'fnof': 402,
|
|
'circ': 710,
|
|
'tilde': 732,
|
|
'Alpha': 913,
|
|
'Beta': 914,
|
|
'Gamma': 915,
|
|
'Delta': 916,
|
|
'Epsilon': 917,
|
|
'Zeta': 918,
|
|
'Eta': 919,
|
|
'Theta': 920,
|
|
'Iota': 921,
|
|
'Kappa': 922,
|
|
'Lambda': 923,
|
|
'Mu': 924,
|
|
'Nu': 925,
|
|
'Xi': 926,
|
|
'Omicron': 927,
|
|
'Pi': 928,
|
|
'Rho': 929,
|
|
'Sigma': 931,
|
|
'Tau': 932,
|
|
'Upsilon': 933,
|
|
'Phi': 934,
|
|
'Chi': 935,
|
|
'Psi': 936,
|
|
'Omega': 937,
|
|
'alpha': 945,
|
|
'beta': 946,
|
|
'gamma': 947,
|
|
'delta': 948,
|
|
'epsilon': 949,
|
|
'zeta': 950,
|
|
'eta': 951,
|
|
'theta': 952,
|
|
'iota': 953,
|
|
'kappa': 954,
|
|
'lambda': 955,
|
|
'mu': 956,
|
|
'nu': 957,
|
|
'xi': 958,
|
|
'omicron': 959,
|
|
'pi': 960,
|
|
'rho': 961,
|
|
'sigmaf': 962,
|
|
'sigma': 963,
|
|
'tau': 964,
|
|
'upsilon': 965,
|
|
'phi': 966,
|
|
'chi': 967,
|
|
'psi': 968,
|
|
'omega': 969,
|
|
'thetasym': 977,
|
|
'upsih': 978,
|
|
'piv': 982,
|
|
'ensp': 8194,
|
|
'emsp': 8195,
|
|
'thinsp': 8201,
|
|
'zwnj': 8204,
|
|
'zwj': 8205,
|
|
'lrm': 8206,
|
|
'rlm': 8207,
|
|
'ndash': 8211,
|
|
'mdash': 8212,
|
|
'lsquo': 8216,
|
|
'rsquo': 8217,
|
|
'sbquo': 8218,
|
|
'ldquo': 8220,
|
|
'rdquo': 8221,
|
|
'bdquo': 8222,
|
|
'dagger': 8224,
|
|
'Dagger': 8225,
|
|
'bull': 8226,
|
|
'hellip': 8230,
|
|
'permil': 8240,
|
|
'prime': 8242,
|
|
'Prime': 8243,
|
|
'lsaquo': 8249,
|
|
'rsaquo': 8250,
|
|
'oline': 8254,
|
|
'frasl': 8260,
|
|
'euro': 8364,
|
|
'image': 8465,
|
|
'weierp': 8472,
|
|
'real': 8476,
|
|
'trade': 8482,
|
|
'alefsym': 8501,
|
|
'larr': 8592,
|
|
'uarr': 8593,
|
|
'rarr': 8594,
|
|
'darr': 8595,
|
|
'harr': 8596,
|
|
'crarr': 8629,
|
|
'lArr': 8656,
|
|
'uArr': 8657,
|
|
'rArr': 8658,
|
|
'dArr': 8659,
|
|
'hArr': 8660,
|
|
'forall': 8704,
|
|
'part': 8706,
|
|
'exist': 8707,
|
|
'empty': 8709,
|
|
'nabla': 8711,
|
|
'isin': 8712,
|
|
'notin': 8713,
|
|
'ni': 8715,
|
|
'prod': 8719,
|
|
'sum': 8721,
|
|
'minus': 8722,
|
|
'lowast': 8727,
|
|
'radic': 8730,
|
|
'prop': 8733,
|
|
'infin': 8734,
|
|
'ang': 8736,
|
|
'and': 8743,
|
|
'or': 8744,
|
|
'cap': 8745,
|
|
'cup': 8746,
|
|
'int': 8747,
|
|
'there4': 8756,
|
|
'sim': 8764,
|
|
'cong': 8773,
|
|
'asymp': 8776,
|
|
'ne': 8800,
|
|
'equiv': 8801,
|
|
'le': 8804,
|
|
'ge': 8805,
|
|
'sub': 8834,
|
|
'sup': 8835,
|
|
'nsub': 8836,
|
|
'sube': 8838,
|
|
'supe': 8839,
|
|
'oplus': 8853,
|
|
'otimes': 8855,
|
|
'perp': 8869,
|
|
'sdot': 8901,
|
|
'lceil': 8968,
|
|
'rceil': 8969,
|
|
'lfloor': 8970,
|
|
'rfloor': 8971,
|
|
'lang': 9001,
|
|
'rang': 9002,
|
|
'loz': 9674,
|
|
'spades': 9824,
|
|
'clubs': 9827,
|
|
'hearts': 9829,
|
|
'diams': 9830
|
|
}
|
|
|
|
Object.keys(sax.ENTITIES).forEach(function (key) {
|
|
var e = sax.ENTITIES[key]
|
|
var s = typeof e === 'number' ? String.fromCharCode(e) : e
|
|
sax.ENTITIES[key] = s
|
|
})
|
|
|
|
for (var s in sax.STATE) {
|
|
sax.STATE[sax.STATE[s]] = s
|
|
}
|
|
|
|
// shorthand
|
|
S = sax.STATE
|
|
|
|
function emit (parser, event, data) {
|
|
parser[event] && parser[event](data)
|
|
}
|
|
|
|
function emitNode (parser, nodeType, data) {
|
|
if (parser.textNode) closeText(parser)
|
|
emit(parser, nodeType, data)
|
|
}
|
|
|
|
function closeText (parser) {
|
|
parser.textNode = textopts(parser.opt, parser.textNode)
|
|
if (parser.textNode) emit(parser, 'ontext', parser.textNode)
|
|
parser.textNode = ''
|
|
}
|
|
|
|
function textopts (opt, text) {
|
|
if (opt.trim) text = text.trim()
|
|
if (opt.normalize) text = text.replace(/\s+/g, ' ')
|
|
return text
|
|
}
|
|
|
|
function error (parser, er) {
|
|
closeText(parser)
|
|
if (parser.trackPosition) {
|
|
er += '\nLine: ' + parser.line +
|
|
'\nColumn: ' + parser.column +
|
|
'\nChar: ' + parser.c
|
|
}
|
|
er = new Error(er)
|
|
parser.error = er
|
|
emit(parser, 'onerror', er)
|
|
return parser
|
|
}
|
|
|
|
function end (parser) {
|
|
if (parser.sawRoot && !parser.closedRoot) strictFail(parser, 'Unclosed root tag')
|
|
if ((parser.state !== S.BEGIN) &&
|
|
(parser.state !== S.BEGIN_WHITESPACE) &&
|
|
(parser.state !== S.TEXT)) {
|
|
error(parser, 'Unexpected end')
|
|
}
|
|
closeText(parser)
|
|
parser.c = ''
|
|
parser.closed = true
|
|
emit(parser, 'onend')
|
|
SAXParser.call(parser, parser.strict, parser.opt)
|
|
return parser
|
|
}
|
|
|
|
function strictFail (parser, message) {
|
|
if (typeof parser !== 'object' || !(parser instanceof SAXParser)) {
|
|
throw new Error('bad call to strictFail')
|
|
}
|
|
if (parser.strict) {
|
|
error(parser, message)
|
|
}
|
|
}
|
|
|
|
function newTag (parser) {
|
|
if (!parser.strict) parser.tagName = parser.tagName[parser.looseCase]()
|
|
var parent = parser.tags[parser.tags.length - 1] || parser
|
|
var tag = parser.tag = { name: parser.tagName, attributes: {} }
|
|
|
|
// will be overridden if tag contails an xmlns="foo" or xmlns:foo="bar"
|
|
if (parser.opt.xmlns) {
|
|
tag.ns = parent.ns
|
|
}
|
|
parser.attribList.length = 0
|
|
emitNode(parser, 'onopentagstart', tag)
|
|
}
|
|
|
|
function qname (name, attribute) {
|
|
var i = name.indexOf(':')
|
|
var qualName = i < 0 ? [ '', name ] : name.split(':')
|
|
var prefix = qualName[0]
|
|
var local = qualName[1]
|
|
|
|
// <x "xmlns"="http://foo">
|
|
if (attribute && name === 'xmlns') {
|
|
prefix = 'xmlns'
|
|
local = ''
|
|
}
|
|
|
|
return { prefix: prefix, local: local }
|
|
}
|
|
|
|
function attrib (parser) {
|
|
if (!parser.strict) {
|
|
parser.attribName = parser.attribName[parser.looseCase]()
|
|
}
|
|
|
|
if (parser.attribList.indexOf(parser.attribName) !== -1 ||
|
|
parser.tag.attributes.hasOwnProperty(parser.attribName)) {
|
|
parser.attribName = parser.attribValue = ''
|
|
return
|
|
}
|
|
|
|
if (parser.opt.xmlns) {
|
|
var qn = qname(parser.attribName, true)
|
|
var prefix = qn.prefix
|
|
var local = qn.local
|
|
|
|
if (prefix === 'xmlns') {
|
|
// namespace binding attribute. push the binding into scope
|
|
if (local === 'xml' && parser.attribValue !== XML_NAMESPACE) {
|
|
strictFail(parser,
|
|
'xml: prefix must be bound to ' + XML_NAMESPACE + '\n' +
|
|
'Actual: ' + parser.attribValue)
|
|
} else if (local === 'xmlns' && parser.attribValue !== XMLNS_NAMESPACE) {
|
|
strictFail(parser,
|
|
'xmlns: prefix must be bound to ' + XMLNS_NAMESPACE + '\n' +
|
|
'Actual: ' + parser.attribValue)
|
|
} else {
|
|
var tag = parser.tag
|
|
var parent = parser.tags[parser.tags.length - 1] || parser
|
|
if (tag.ns === parent.ns) {
|
|
tag.ns = Object.create(parent.ns)
|
|
}
|
|
tag.ns[local] = parser.attribValue
|
|
}
|
|
}
|
|
|
|
// defer onattribute events until all attributes have been seen
|
|
// so any new bindings can take effect. preserve attribute order
|
|
// so deferred events can be emitted in document order
|
|
parser.attribList.push([parser.attribName, parser.attribValue])
|
|
} else {
|
|
// in non-xmlns mode, we can emit the event right away
|
|
parser.tag.attributes[parser.attribName] = parser.attribValue
|
|
emitNode(parser, 'onattribute', {
|
|
name: parser.attribName,
|
|
value: parser.attribValue
|
|
})
|
|
}
|
|
|
|
parser.attribName = parser.attribValue = ''
|
|
}
|
|
|
|
function openTag (parser, selfClosing) {
|
|
if (parser.opt.xmlns) {
|
|
// emit namespace binding events
|
|
var tag = parser.tag
|
|
|
|
// add namespace info to tag
|
|
var qn = qname(parser.tagName)
|
|
tag.prefix = qn.prefix
|
|
tag.local = qn.local
|
|
tag.uri = tag.ns[qn.prefix] || ''
|
|
|
|
if (tag.prefix && !tag.uri) {
|
|
strictFail(parser, 'Unbound namespace prefix: ' +
|
|
JSON.stringify(parser.tagName))
|
|
tag.uri = qn.prefix
|
|
}
|
|
|
|
var parent = parser.tags[parser.tags.length - 1] || parser
|
|
if (tag.ns && parent.ns !== tag.ns) {
|
|
Object.keys(tag.ns).forEach(function (p) {
|
|
emitNode(parser, 'onopennamespace', {
|
|
prefix: p,
|
|
uri: tag.ns[p]
|
|
})
|
|
})
|
|
}
|
|
|
|
// handle deferred onattribute events
|
|
// Note: do not apply default ns to attributes:
|
|
// http://www.w3.org/TR/REC-xml-names/#defaulting
|
|
for (var i = 0, l = parser.attribList.length; i < l; i++) {
|
|
var nv = parser.attribList[i]
|
|
var name = nv[0]
|
|
var value = nv[1]
|
|
var qualName = qname(name, true)
|
|
var prefix = qualName.prefix
|
|
var local = qualName.local
|
|
var uri = prefix === '' ? '' : (tag.ns[prefix] || '')
|
|
var a = {
|
|
name: name,
|
|
value: value,
|
|
prefix: prefix,
|
|
local: local,
|
|
uri: uri
|
|
}
|
|
|
|
// if there's any attributes with an undefined namespace,
|
|
// then fail on them now.
|
|
if (prefix && prefix !== 'xmlns' && !uri) {
|
|
strictFail(parser, 'Unbound namespace prefix: ' +
|
|
JSON.stringify(prefix))
|
|
a.uri = prefix
|
|
}
|
|
parser.tag.attributes[name] = a
|
|
emitNode(parser, 'onattribute', a)
|
|
}
|
|
parser.attribList.length = 0
|
|
}
|
|
|
|
parser.tag.isSelfClosing = !!selfClosing
|
|
|
|
// process the tag
|
|
parser.sawRoot = true
|
|
parser.tags.push(parser.tag)
|
|
emitNode(parser, 'onopentag', parser.tag)
|
|
if (!selfClosing) {
|
|
// special case for <script> in non-strict mode.
|
|
if (!parser.noscript && parser.tagName.toLowerCase() === 'script') {
|
|
parser.state = S.SCRIPT
|
|
} else {
|
|
parser.state = S.TEXT
|
|
}
|
|
parser.tag = null
|
|
parser.tagName = ''
|
|
}
|
|
parser.attribName = parser.attribValue = ''
|
|
parser.attribList.length = 0
|
|
}
|
|
|
|
function closeTag (parser) {
|
|
if (!parser.tagName) {
|
|
strictFail(parser, 'Weird empty close tag.')
|
|
parser.textNode += '</>'
|
|
parser.state = S.TEXT
|
|
return
|
|
}
|
|
|
|
if (parser.script) {
|
|
if (parser.tagName !== 'script') {
|
|
parser.script += '</' + parser.tagName + '>'
|
|
parser.tagName = ''
|
|
parser.state = S.SCRIPT
|
|
return
|
|
}
|
|
emitNode(parser, 'onscript', parser.script)
|
|
parser.script = ''
|
|
}
|
|
|
|
// first make sure that the closing tag actually exists.
|
|
// <a><b></c></b></a> will close everything, otherwise.
|
|
var t = parser.tags.length
|
|
var tagName = parser.tagName
|
|
if (!parser.strict) {
|
|
tagName = tagName[parser.looseCase]()
|
|
}
|
|
var closeTo = tagName
|
|
while (t--) {
|
|
var close = parser.tags[t]
|
|
if (close.name !== closeTo) {
|
|
// fail the first time in strict mode
|
|
strictFail(parser, 'Unexpected close tag')
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
|
|
// didn't find it. we already failed for strict, so just abort.
|
|
if (t < 0) {
|
|
strictFail(parser, 'Unmatched closing tag: ' + parser.tagName)
|
|
parser.textNode += '</' + parser.tagName + '>'
|
|
parser.state = S.TEXT
|
|
return
|
|
}
|
|
parser.tagName = tagName
|
|
var s = parser.tags.length
|
|
while (s-- > t) {
|
|
var tag = parser.tag = parser.tags.pop()
|
|
parser.tagName = parser.tag.name
|
|
emitNode(parser, 'onclosetag', parser.tagName)
|
|
|
|
var x = {}
|
|
for (var i in tag.ns) {
|
|
x[i] = tag.ns[i]
|
|
}
|
|
|
|
var parent = parser.tags[parser.tags.length - 1] || parser
|
|
if (parser.opt.xmlns && tag.ns !== parent.ns) {
|
|
// remove namespace bindings introduced by tag
|
|
Object.keys(tag.ns).forEach(function (p) {
|
|
var n = tag.ns[p]
|
|
emitNode(parser, 'onclosenamespace', { prefix: p, uri: n })
|
|
})
|
|
}
|
|
}
|
|
if (t === 0) parser.closedRoot = true
|
|
parser.tagName = parser.attribValue = parser.attribName = ''
|
|
parser.attribList.length = 0
|
|
parser.state = S.TEXT
|
|
}
|
|
|
|
function parseEntity (parser) {
|
|
var entity = parser.entity
|
|
var entityLC = entity.toLowerCase()
|
|
var num
|
|
var numStr = ''
|
|
|
|
if (parser.ENTITIES[entity]) {
|
|
return parser.ENTITIES[entity]
|
|
}
|
|
if (parser.ENTITIES[entityLC]) {
|
|
return parser.ENTITIES[entityLC]
|
|
}
|
|
entity = entityLC
|
|
if (entity.charAt(0) === '#') {
|
|
if (entity.charAt(1) === 'x') {
|
|
entity = entity.slice(2)
|
|
num = parseInt(entity, 16)
|
|
numStr = num.toString(16)
|
|
} else {
|
|
entity = entity.slice(1)
|
|
num = parseInt(entity, 10)
|
|
numStr = num.toString(10)
|
|
}
|
|
}
|
|
entity = entity.replace(/^0+/, '')
|
|
if (isNaN(num) || numStr.toLowerCase() !== entity) {
|
|
strictFail(parser, 'Invalid character entity')
|
|
return '&' + parser.entity + ';'
|
|
}
|
|
|
|
return String.fromCodePoint(num)
|
|
}
|
|
|
|
function beginWhiteSpace (parser, c) {
|
|
if (c === '<') {
|
|
parser.state = S.OPEN_WAKA
|
|
parser.startTagPosition = parser.position
|
|
} else if (!isWhitespace(c)) {
|
|
// have to process this as a text node.
|
|
// weird, but happens.
|
|
strictFail(parser, 'Non-whitespace before first tag.')
|
|
parser.textNode = c
|
|
parser.state = S.TEXT
|
|
}
|
|
}
|
|
|
|
function charAt (chunk, i) {
|
|
var result = ''
|
|
if (i < chunk.length) {
|
|
result = chunk.charAt(i)
|
|
}
|
|
return result
|
|
}
|
|
|
|
function write (chunk) {
|
|
var parser = this
|
|
if (this.error) {
|
|
throw this.error
|
|
}
|
|
if (parser.closed) {
|
|
return error(parser,
|
|
'Cannot write after close. Assign an onready handler.')
|
|
}
|
|
if (chunk === null) {
|
|
return end(parser)
|
|
}
|
|
if (typeof chunk === 'object') {
|
|
chunk = chunk.toString()
|
|
}
|
|
var i = 0
|
|
var c = ''
|
|
while (true) {
|
|
c = charAt(chunk, i++)
|
|
parser.c = c
|
|
|
|
if (!c) {
|
|
break
|
|
}
|
|
|
|
if (parser.trackPosition) {
|
|
parser.position++
|
|
if (c === '\n') {
|
|
parser.line++
|
|
parser.column = 0
|
|
} else {
|
|
parser.column++
|
|
}
|
|
}
|
|
|
|
switch (parser.state) {
|
|
case S.BEGIN:
|
|
parser.state = S.BEGIN_WHITESPACE
|
|
if (c === '\uFEFF') {
|
|
continue
|
|
}
|
|
beginWhiteSpace(parser, c)
|
|
continue
|
|
|
|
case S.BEGIN_WHITESPACE:
|
|
beginWhiteSpace(parser, c)
|
|
continue
|
|
|
|
case S.TEXT:
|
|
if (parser.sawRoot && !parser.closedRoot) {
|
|
var starti = i - 1
|
|
while (c && c !== '<' && c !== '&') {
|
|
c = charAt(chunk, i++)
|
|
if (c && parser.trackPosition) {
|
|
parser.position++
|
|
if (c === '\n') {
|
|
parser.line++
|
|
parser.column = 0
|
|
} else {
|
|
parser.column++
|
|
}
|
|
}
|
|
}
|
|
parser.textNode += chunk.substring(starti, i - 1)
|
|
}
|
|
if (c === '<' && !(parser.sawRoot && parser.closedRoot && !parser.strict)) {
|
|
parser.state = S.OPEN_WAKA
|
|
parser.startTagPosition = parser.position
|
|
} else {
|
|
if (!isWhitespace(c) && (!parser.sawRoot || parser.closedRoot)) {
|
|
strictFail(parser, 'Text data outside of root node.')
|
|
}
|
|
if (c === '&') {
|
|
parser.state = S.TEXT_ENTITY
|
|
} else {
|
|
parser.textNode += c
|
|
}
|
|
}
|
|
continue
|
|
|
|
case S.SCRIPT:
|
|
// only non-strict
|
|
if (c === '<') {
|
|
parser.state = S.SCRIPT_ENDING
|
|
} else {
|
|
parser.script += c
|
|
}
|
|
continue
|
|
|
|
case S.SCRIPT_ENDING:
|
|
if (c === '/') {
|
|
parser.state = S.CLOSE_TAG
|
|
} else {
|
|
parser.script += '<' + c
|
|
parser.state = S.SCRIPT
|
|
}
|
|
continue
|
|
|
|
case S.OPEN_WAKA:
|
|
// either a /, ?, !, or text is coming next.
|
|
if (c === '!') {
|
|
parser.state = S.SGML_DECL
|
|
parser.sgmlDecl = ''
|
|
} else if (isWhitespace(c)) {
|
|
// wait for it...
|
|
} else if (isMatch(nameStart, c)) {
|
|
parser.state = S.OPEN_TAG
|
|
parser.tagName = c
|
|
} else if (c === '/') {
|
|
parser.state = S.CLOSE_TAG
|
|
parser.tagName = ''
|
|
} else if (c === '?') {
|
|
parser.state = S.PROC_INST
|
|
parser.procInstName = parser.procInstBody = ''
|
|
} else {
|
|
strictFail(parser, 'Unencoded <')
|
|
// if there was some whitespace, then add that in.
|
|
if (parser.startTagPosition + 1 < parser.position) {
|
|
var pad = parser.position - parser.startTagPosition
|
|
c = new Array(pad).join(' ') + c
|
|
}
|
|
parser.textNode += '<' + c
|
|
parser.state = S.TEXT
|
|
}
|
|
continue
|
|
|
|
case S.SGML_DECL:
|
|
if ((parser.sgmlDecl + c).toUpperCase() === CDATA) {
|
|
emitNode(parser, 'onopencdata')
|
|
parser.state = S.CDATA
|
|
parser.sgmlDecl = ''
|
|
parser.cdata = ''
|
|
} else if (parser.sgmlDecl + c === '--') {
|
|
parser.state = S.COMMENT
|
|
parser.comment = ''
|
|
parser.sgmlDecl = ''
|
|
} else if ((parser.sgmlDecl + c).toUpperCase() === DOCTYPE) {
|
|
parser.state = S.DOCTYPE
|
|
if (parser.doctype || parser.sawRoot) {
|
|
strictFail(parser,
|
|
'Inappropriately located doctype declaration')
|
|
}
|
|
parser.doctype = ''
|
|
parser.sgmlDecl = ''
|
|
} else if (c === '>') {
|
|
emitNode(parser, 'onsgmldeclaration', parser.sgmlDecl)
|
|
parser.sgmlDecl = ''
|
|
parser.state = S.TEXT
|
|
} else if (isQuote(c)) {
|
|
parser.state = S.SGML_DECL_QUOTED
|
|
parser.sgmlDecl += c
|
|
} else {
|
|
parser.sgmlDecl += c
|
|
}
|
|
continue
|
|
|
|
case S.SGML_DECL_QUOTED:
|
|
if (c === parser.q) {
|
|
parser.state = S.SGML_DECL
|
|
parser.q = ''
|
|
}
|
|
parser.sgmlDecl += c
|
|
continue
|
|
|
|
case S.DOCTYPE:
|
|
if (c === '>') {
|
|
parser.state = S.TEXT
|
|
emitNode(parser, 'ondoctype', parser.doctype)
|
|
parser.doctype = true // just remember that we saw it.
|
|
} else {
|
|
parser.doctype += c
|
|
if (c === '[') {
|
|
parser.state = S.DOCTYPE_DTD
|
|
} else if (isQuote(c)) {
|
|
parser.state = S.DOCTYPE_QUOTED
|
|
parser.q = c
|
|
}
|
|
}
|
|
continue
|
|
|
|
case S.DOCTYPE_QUOTED:
|
|
parser.doctype += c
|
|
if (c === parser.q) {
|
|
parser.q = ''
|
|
parser.state = S.DOCTYPE
|
|
}
|
|
continue
|
|
|
|
case S.DOCTYPE_DTD:
|
|
parser.doctype += c
|
|
if (c === ']') {
|
|
parser.state = S.DOCTYPE
|
|
} else if (isQuote(c)) {
|
|
parser.state = S.DOCTYPE_DTD_QUOTED
|
|
parser.q = c
|
|
}
|
|
continue
|
|
|
|
case S.DOCTYPE_DTD_QUOTED:
|
|
parser.doctype += c
|
|
if (c === parser.q) {
|
|
parser.state = S.DOCTYPE_DTD
|
|
parser.q = ''
|
|
}
|
|
continue
|
|
|
|
case S.COMMENT:
|
|
if (c === '-') {
|
|
parser.state = S.COMMENT_ENDING
|
|
} else {
|
|
parser.comment += c
|
|
}
|
|
continue
|
|
|
|
case S.COMMENT_ENDING:
|
|
if (c === '-') {
|
|
parser.state = S.COMMENT_ENDED
|
|
parser.comment = textopts(parser.opt, parser.comment)
|
|
if (parser.comment) {
|
|
emitNode(parser, 'oncomment', parser.comment)
|
|
}
|
|
parser.comment = ''
|
|
} else {
|
|
parser.comment += '-' + c
|
|
parser.state = S.COMMENT
|
|
}
|
|
continue
|
|
|
|
case S.COMMENT_ENDED:
|
|
if (c !== '>') {
|
|
strictFail(parser, 'Malformed comment')
|
|
// allow <!-- blah -- bloo --> in non-strict mode,
|
|
// which is a comment of " blah -- bloo "
|
|
parser.comment += '--' + c
|
|
parser.state = S.COMMENT
|
|
} else {
|
|
parser.state = S.TEXT
|
|
}
|
|
continue
|
|
|
|
case S.CDATA:
|
|
if (c === ']') {
|
|
parser.state = S.CDATA_ENDING
|
|
} else {
|
|
parser.cdata += c
|
|
}
|
|
continue
|
|
|
|
case S.CDATA_ENDING:
|
|
if (c === ']') {
|
|
parser.state = S.CDATA_ENDING_2
|
|
} else {
|
|
parser.cdata += ']' + c
|
|
parser.state = S.CDATA
|
|
}
|
|
continue
|
|
|
|
case S.CDATA_ENDING_2:
|
|
if (c === '>') {
|
|
if (parser.cdata) {
|
|
emitNode(parser, 'oncdata', parser.cdata)
|
|
}
|
|
emitNode(parser, 'onclosecdata')
|
|
parser.cdata = ''
|
|
parser.state = S.TEXT
|
|
} else if (c === ']') {
|
|
parser.cdata += ']'
|
|
} else {
|
|
parser.cdata += ']]' + c
|
|
parser.state = S.CDATA
|
|
}
|
|
continue
|
|
|
|
case S.PROC_INST:
|
|
if (c === '?') {
|
|
parser.state = S.PROC_INST_ENDING
|
|
} else if (isWhitespace(c)) {
|
|
parser.state = S.PROC_INST_BODY
|
|
} else {
|
|
parser.procInstName += c
|
|
}
|
|
continue
|
|
|
|
case S.PROC_INST_BODY:
|
|
if (!parser.procInstBody && isWhitespace(c)) {
|
|
continue
|
|
} else if (c === '?') {
|
|
parser.state = S.PROC_INST_ENDING
|
|
} else {
|
|
parser.procInstBody += c
|
|
}
|
|
continue
|
|
|
|
case S.PROC_INST_ENDING:
|
|
if (c === '>') {
|
|
emitNode(parser, 'onprocessinginstruction', {
|
|
name: parser.procInstName,
|
|
body: parser.procInstBody
|
|
})
|
|
parser.procInstName = parser.procInstBody = ''
|
|
parser.state = S.TEXT
|
|
} else {
|
|
parser.procInstBody += '?' + c
|
|
parser.state = S.PROC_INST_BODY
|
|
}
|
|
continue
|
|
|
|
case S.OPEN_TAG:
|
|
if (isMatch(nameBody, c)) {
|
|
parser.tagName += c
|
|
} else {
|
|
newTag(parser)
|
|
if (c === '>') {
|
|
openTag(parser)
|
|
} else if (c === '/') {
|
|
parser.state = S.OPEN_TAG_SLASH
|
|
} else {
|
|
if (!isWhitespace(c)) {
|
|
strictFail(parser, 'Invalid character in tag name')
|
|
}
|
|
parser.state = S.ATTRIB
|
|
}
|
|
}
|
|
continue
|
|
|
|
case S.OPEN_TAG_SLASH:
|
|
if (c === '>') {
|
|
openTag(parser, true)
|
|
closeTag(parser)
|
|
} else {
|
|
strictFail(parser, 'Forward-slash in opening tag not followed by >')
|
|
parser.state = S.ATTRIB
|
|
}
|
|
continue
|
|
|
|
case S.ATTRIB:
|
|
// haven't read the attribute name yet.
|
|
if (isWhitespace(c)) {
|
|
continue
|
|
} else if (c === '>') {
|
|
openTag(parser)
|
|
} else if (c === '/') {
|
|
parser.state = S.OPEN_TAG_SLASH
|
|
} else if (isMatch(nameStart, c)) {
|
|
parser.attribName = c
|
|
parser.attribValue = ''
|
|
parser.state = S.ATTRIB_NAME
|
|
} else {
|
|
strictFail(parser, 'Invalid attribute name')
|
|
}
|
|
continue
|
|
|
|
case S.ATTRIB_NAME:
|
|
if (c === '=') {
|
|
parser.state = S.ATTRIB_VALUE
|
|
} else if (c === '>') {
|
|
strictFail(parser, 'Attribute without value')
|
|
parser.attribValue = parser.attribName
|
|
attrib(parser)
|
|
openTag(parser)
|
|
} else if (isWhitespace(c)) {
|
|
parser.state = S.ATTRIB_NAME_SAW_WHITE
|
|
} else if (isMatch(nameBody, c)) {
|
|
parser.attribName += c
|
|
} else {
|
|
strictFail(parser, 'Invalid attribute name')
|
|
}
|
|
continue
|
|
|
|
case S.ATTRIB_NAME_SAW_WHITE:
|
|
if (c === '=') {
|
|
parser.state = S.ATTRIB_VALUE
|
|
} else if (isWhitespace(c)) {
|
|
continue
|
|
} else {
|
|
strictFail(parser, 'Attribute without value')
|
|
parser.tag.attributes[parser.attribName] = ''
|
|
parser.attribValue = ''
|
|
emitNode(parser, 'onattribute', {
|
|
name: parser.attribName,
|
|
value: ''
|
|
})
|
|
parser.attribName = ''
|
|
if (c === '>') {
|
|
openTag(parser)
|
|
} else if (isMatch(nameStart, c)) {
|
|
parser.attribName = c
|
|
parser.state = S.ATTRIB_NAME
|
|
} else {
|
|
strictFail(parser, 'Invalid attribute name')
|
|
parser.state = S.ATTRIB
|
|
}
|
|
}
|
|
continue
|
|
|
|
case S.ATTRIB_VALUE:
|
|
if (isWhitespace(c)) {
|
|
continue
|
|
} else if (isQuote(c)) {
|
|
parser.q = c
|
|
parser.state = S.ATTRIB_VALUE_QUOTED
|
|
} else {
|
|
strictFail(parser, 'Unquoted attribute value')
|
|
parser.state = S.ATTRIB_VALUE_UNQUOTED
|
|
parser.attribValue = c
|
|
}
|
|
continue
|
|
|
|
case S.ATTRIB_VALUE_QUOTED:
|
|
if (c !== parser.q) {
|
|
if (c === '&') {
|
|
parser.state = S.ATTRIB_VALUE_ENTITY_Q
|
|
} else {
|
|
parser.attribValue += c
|
|
}
|
|
continue
|
|
}
|
|
attrib(parser)
|
|
parser.q = ''
|
|
parser.state = S.ATTRIB_VALUE_CLOSED
|
|
continue
|
|
|
|
case S.ATTRIB_VALUE_CLOSED:
|
|
if (isWhitespace(c)) {
|
|
parser.state = S.ATTRIB
|
|
} else if (c === '>') {
|
|
openTag(parser)
|
|
} else if (c === '/') {
|
|
parser.state = S.OPEN_TAG_SLASH
|
|
} else if (isMatch(nameStart, c)) {
|
|
strictFail(parser, 'No whitespace between attributes')
|
|
parser.attribName = c
|
|
parser.attribValue = ''
|
|
parser.state = S.ATTRIB_NAME
|
|
} else {
|
|
strictFail(parser, 'Invalid attribute name')
|
|
}
|
|
continue
|
|
|
|
case S.ATTRIB_VALUE_UNQUOTED:
|
|
if (!isAttribEnd(c)) {
|
|
if (c === '&') {
|
|
parser.state = S.ATTRIB_VALUE_ENTITY_U
|
|
} else {
|
|
parser.attribValue += c
|
|
}
|
|
continue
|
|
}
|
|
attrib(parser)
|
|
if (c === '>') {
|
|
openTag(parser)
|
|
} else {
|
|
parser.state = S.ATTRIB
|
|
}
|
|
continue
|
|
|
|
case S.CLOSE_TAG:
|
|
if (!parser.tagName) {
|
|
if (isWhitespace(c)) {
|
|
continue
|
|
} else if (notMatch(nameStart, c)) {
|
|
if (parser.script) {
|
|
parser.script += '</' + c
|
|
parser.state = S.SCRIPT
|
|
} else {
|
|
strictFail(parser, 'Invalid tagname in closing tag.')
|
|
}
|
|
} else {
|
|
parser.tagName = c
|
|
}
|
|
} else if (c === '>') {
|
|
closeTag(parser)
|
|
} else if (isMatch(nameBody, c)) {
|
|
parser.tagName += c
|
|
} else if (parser.script) {
|
|
parser.script += '</' + parser.tagName
|
|
parser.tagName = ''
|
|
parser.state = S.SCRIPT
|
|
} else {
|
|
if (!isWhitespace(c)) {
|
|
strictFail(parser, 'Invalid tagname in closing tag')
|
|
}
|
|
parser.state = S.CLOSE_TAG_SAW_WHITE
|
|
}
|
|
continue
|
|
|
|
case S.CLOSE_TAG_SAW_WHITE:
|
|
if (isWhitespace(c)) {
|
|
continue
|
|
}
|
|
if (c === '>') {
|
|
closeTag(parser)
|
|
} else {
|
|
strictFail(parser, 'Invalid characters in closing tag')
|
|
}
|
|
continue
|
|
|
|
case S.TEXT_ENTITY:
|
|
case S.ATTRIB_VALUE_ENTITY_Q:
|
|
case S.ATTRIB_VALUE_ENTITY_U:
|
|
var returnState
|
|
var buffer
|
|
switch (parser.state) {
|
|
case S.TEXT_ENTITY:
|
|
returnState = S.TEXT
|
|
buffer = 'textNode'
|
|
break
|
|
|
|
case S.ATTRIB_VALUE_ENTITY_Q:
|
|
returnState = S.ATTRIB_VALUE_QUOTED
|
|
buffer = 'attribValue'
|
|
break
|
|
|
|
case S.ATTRIB_VALUE_ENTITY_U:
|
|
returnState = S.ATTRIB_VALUE_UNQUOTED
|
|
buffer = 'attribValue'
|
|
break
|
|
}
|
|
|
|
if (c === ';') {
|
|
parser[buffer] += parseEntity(parser)
|
|
parser.entity = ''
|
|
parser.state = returnState
|
|
} else if (isMatch(parser.entity.length ? entityBody : entityStart, c)) {
|
|
parser.entity += c
|
|
} else {
|
|
strictFail(parser, 'Invalid character in entity name')
|
|
parser[buffer] += '&' + parser.entity + c
|
|
parser.entity = ''
|
|
parser.state = returnState
|
|
}
|
|
|
|
continue
|
|
|
|
default:
|
|
throw new Error(parser, 'Unknown state: ' + parser.state)
|
|
}
|
|
} // while
|
|
|
|
if (parser.position >= parser.bufferCheckPosition) {
|
|
checkBufferLength(parser)
|
|
}
|
|
return parser
|
|
}
|
|
|
|
/*! http://mths.be/fromcodepoint v0.1.0 by @mathias */
|
|
/* istanbul ignore next */
|
|
if (!String.fromCodePoint) {
|
|
(function () {
|
|
var stringFromCharCode = String.fromCharCode
|
|
var floor = Math.floor
|
|
var fromCodePoint = function () {
|
|
var MAX_SIZE = 0x4000
|
|
var codeUnits = []
|
|
var highSurrogate
|
|
var lowSurrogate
|
|
var index = -1
|
|
var length = arguments.length
|
|
if (!length) {
|
|
return ''
|
|
}
|
|
var result = ''
|
|
while (++index < length) {
|
|
var codePoint = Number(arguments[index])
|
|
if (
|
|
!isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`
|
|
codePoint < 0 || // not a valid Unicode code point
|
|
codePoint > 0x10FFFF || // not a valid Unicode code point
|
|
floor(codePoint) !== codePoint // not an integer
|
|
) {
|
|
throw RangeError('Invalid code point: ' + codePoint)
|
|
}
|
|
if (codePoint <= 0xFFFF) { // BMP code point
|
|
codeUnits.push(codePoint)
|
|
} else { // Astral code point; split in surrogate halves
|
|
// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
|
codePoint -= 0x10000
|
|
highSurrogate = (codePoint >> 10) + 0xD800
|
|
lowSurrogate = (codePoint % 0x400) + 0xDC00
|
|
codeUnits.push(highSurrogate, lowSurrogate)
|
|
}
|
|
if (index + 1 === length || codeUnits.length > MAX_SIZE) {
|
|
result += stringFromCharCode.apply(null, codeUnits)
|
|
codeUnits.length = 0
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
/* istanbul ignore next */
|
|
if (Object.defineProperty) {
|
|
Object.defineProperty(String, 'fromCodePoint', {
|
|
value: fromCodePoint,
|
|
configurable: true,
|
|
writable: true
|
|
})
|
|
} else {
|
|
String.fromCodePoint = fromCodePoint
|
|
}
|
|
}())
|
|
}
|
|
})(typeof exports === 'undefined' ? this.sax = {} : exports)
|
|
|
|
}).call(this)}).call(this,require("buffer").Buffer)
|
|
|
|
},{"buffer":3,"stream":9,"string_decoder":24}],60:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
"use strict";
|
|
exports.stripBOM = function(str) {
|
|
if (str[0] === '\uFEFF') {
|
|
return str.substring(1);
|
|
} else {
|
|
return str;
|
|
}
|
|
};
|
|
|
|
}).call(this);
|
|
|
|
},{}],61:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
"use strict";
|
|
var builder, defaults, escapeCDATA, requiresCDATA, wrapCDATA,
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
builder = require('xmlbuilder');
|
|
|
|
defaults = require('./defaults').defaults;
|
|
|
|
requiresCDATA = function(entry) {
|
|
return typeof entry === "string" && (entry.indexOf('&') >= 0 || entry.indexOf('>') >= 0 || entry.indexOf('<') >= 0);
|
|
};
|
|
|
|
wrapCDATA = function(entry) {
|
|
return "<![CDATA[" + (escapeCDATA(entry)) + "]]>";
|
|
};
|
|
|
|
escapeCDATA = function(entry) {
|
|
return entry.replace(']]>', ']]]]><![CDATA[>');
|
|
};
|
|
|
|
exports.Builder = (function() {
|
|
function Builder(opts) {
|
|
var key, ref, value;
|
|
this.options = {};
|
|
ref = defaults["0.2"];
|
|
for (key in ref) {
|
|
if (!hasProp.call(ref, key)) continue;
|
|
value = ref[key];
|
|
this.options[key] = value;
|
|
}
|
|
for (key in opts) {
|
|
if (!hasProp.call(opts, key)) continue;
|
|
value = opts[key];
|
|
this.options[key] = value;
|
|
}
|
|
}
|
|
|
|
Builder.prototype.buildObject = function(rootObj) {
|
|
var attrkey, charkey, render, rootElement, rootName;
|
|
attrkey = this.options.attrkey;
|
|
charkey = this.options.charkey;
|
|
if ((Object.keys(rootObj).length === 1) && (this.options.rootName === defaults['0.2'].rootName)) {
|
|
rootName = Object.keys(rootObj)[0];
|
|
rootObj = rootObj[rootName];
|
|
} else {
|
|
rootName = this.options.rootName;
|
|
}
|
|
render = (function(_this) {
|
|
return function(element, obj) {
|
|
var attr, child, entry, index, key, value;
|
|
if (typeof obj !== 'object') {
|
|
if (_this.options.cdata && requiresCDATA(obj)) {
|
|
element.raw(wrapCDATA(obj));
|
|
} else {
|
|
element.txt(obj);
|
|
}
|
|
} else if (Array.isArray(obj)) {
|
|
for (index in obj) {
|
|
if (!hasProp.call(obj, index)) continue;
|
|
child = obj[index];
|
|
for (key in child) {
|
|
entry = child[key];
|
|
element = render(element.ele(key), entry).up();
|
|
}
|
|
}
|
|
} else {
|
|
for (key in obj) {
|
|
if (!hasProp.call(obj, key)) continue;
|
|
child = obj[key];
|
|
if (key === attrkey) {
|
|
if (typeof child === "object") {
|
|
for (attr in child) {
|
|
value = child[attr];
|
|
element = element.att(attr, value);
|
|
}
|
|
}
|
|
} else if (key === charkey) {
|
|
if (_this.options.cdata && requiresCDATA(child)) {
|
|
element = element.raw(wrapCDATA(child));
|
|
} else {
|
|
element = element.txt(child);
|
|
}
|
|
} else if (Array.isArray(child)) {
|
|
for (index in child) {
|
|
if (!hasProp.call(child, index)) continue;
|
|
entry = child[index];
|
|
if (typeof entry === 'string') {
|
|
if (_this.options.cdata && requiresCDATA(entry)) {
|
|
element = element.ele(key).raw(wrapCDATA(entry)).up();
|
|
} else {
|
|
element = element.ele(key, entry).up();
|
|
}
|
|
} else {
|
|
element = render(element.ele(key), entry).up();
|
|
}
|
|
}
|
|
} else if (typeof child === "object") {
|
|
element = render(element.ele(key), child).up();
|
|
} else {
|
|
if (typeof child === 'string' && _this.options.cdata && requiresCDATA(child)) {
|
|
element = element.ele(key).raw(wrapCDATA(child)).up();
|
|
} else {
|
|
if (child == null) {
|
|
child = '';
|
|
}
|
|
element = element.ele(key, child.toString()).up();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return element;
|
|
};
|
|
})(this);
|
|
rootElement = builder.create(rootName, this.options.xmldec, this.options.doctype, {
|
|
headless: this.options.headless,
|
|
allowSurrogateChars: this.options.allowSurrogateChars
|
|
});
|
|
return render(rootElement, rootObj).end(this.options.renderOpts);
|
|
};
|
|
|
|
return Builder;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{"./defaults":62,"xmlbuilder":98}],62:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
exports.defaults = {
|
|
"0.1": {
|
|
explicitCharkey: false,
|
|
trim: true,
|
|
normalize: true,
|
|
normalizeTags: false,
|
|
attrkey: "@",
|
|
charkey: "#",
|
|
explicitArray: false,
|
|
ignoreAttrs: false,
|
|
mergeAttrs: false,
|
|
explicitRoot: false,
|
|
validator: null,
|
|
xmlns: false,
|
|
explicitChildren: false,
|
|
childkey: '@@',
|
|
charsAsChildren: false,
|
|
includeWhiteChars: false,
|
|
async: false,
|
|
strict: true,
|
|
attrNameProcessors: null,
|
|
attrValueProcessors: null,
|
|
tagNameProcessors: null,
|
|
valueProcessors: null,
|
|
emptyTag: ''
|
|
},
|
|
"0.2": {
|
|
explicitCharkey: false,
|
|
trim: false,
|
|
normalize: false,
|
|
normalizeTags: false,
|
|
attrkey: "$",
|
|
charkey: "_",
|
|
explicitArray: true,
|
|
ignoreAttrs: false,
|
|
mergeAttrs: false,
|
|
explicitRoot: true,
|
|
validator: null,
|
|
xmlns: false,
|
|
explicitChildren: false,
|
|
preserveChildrenOrder: false,
|
|
childkey: '$$',
|
|
charsAsChildren: false,
|
|
includeWhiteChars: false,
|
|
async: false,
|
|
strict: true,
|
|
attrNameProcessors: null,
|
|
attrValueProcessors: null,
|
|
tagNameProcessors: null,
|
|
valueProcessors: null,
|
|
rootName: 'root',
|
|
xmldec: {
|
|
'version': '1.0',
|
|
'encoding': 'UTF-8',
|
|
'standalone': true
|
|
},
|
|
doctype: null,
|
|
renderOpts: {
|
|
'pretty': true,
|
|
'indent': ' ',
|
|
'newline': '\n'
|
|
},
|
|
headless: false,
|
|
chunkSize: 10000,
|
|
emptyTag: '',
|
|
cdata: false
|
|
}
|
|
};
|
|
|
|
}).call(this);
|
|
|
|
},{}],63:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
"use strict";
|
|
var bom, defaults, events, isEmpty, processItem, processors, sax, setImmediate,
|
|
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
sax = require('sax');
|
|
|
|
events = require('events');
|
|
|
|
bom = require('./bom');
|
|
|
|
processors = require('./processors');
|
|
|
|
setImmediate = require('timers').setImmediate;
|
|
|
|
defaults = require('./defaults').defaults;
|
|
|
|
isEmpty = function(thing) {
|
|
return typeof thing === "object" && (thing != null) && Object.keys(thing).length === 0;
|
|
};
|
|
|
|
processItem = function(processors, item, key) {
|
|
var i, len, process;
|
|
for (i = 0, len = processors.length; i < len; i++) {
|
|
process = processors[i];
|
|
item = process(item, key);
|
|
}
|
|
return item;
|
|
};
|
|
|
|
exports.Parser = (function(superClass) {
|
|
extend(Parser, superClass);
|
|
|
|
function Parser(opts) {
|
|
this.parseStringPromise = bind(this.parseStringPromise, this);
|
|
this.parseString = bind(this.parseString, this);
|
|
this.reset = bind(this.reset, this);
|
|
this.assignOrPush = bind(this.assignOrPush, this);
|
|
this.processAsync = bind(this.processAsync, this);
|
|
var key, ref, value;
|
|
if (!(this instanceof exports.Parser)) {
|
|
return new exports.Parser(opts);
|
|
}
|
|
this.options = {};
|
|
ref = defaults["0.2"];
|
|
for (key in ref) {
|
|
if (!hasProp.call(ref, key)) continue;
|
|
value = ref[key];
|
|
this.options[key] = value;
|
|
}
|
|
for (key in opts) {
|
|
if (!hasProp.call(opts, key)) continue;
|
|
value = opts[key];
|
|
this.options[key] = value;
|
|
}
|
|
if (this.options.xmlns) {
|
|
this.options.xmlnskey = this.options.attrkey + "ns";
|
|
}
|
|
if (this.options.normalizeTags) {
|
|
if (!this.options.tagNameProcessors) {
|
|
this.options.tagNameProcessors = [];
|
|
}
|
|
this.options.tagNameProcessors.unshift(processors.normalize);
|
|
}
|
|
this.reset();
|
|
}
|
|
|
|
Parser.prototype.processAsync = function() {
|
|
var chunk, err;
|
|
try {
|
|
if (this.remaining.length <= this.options.chunkSize) {
|
|
chunk = this.remaining;
|
|
this.remaining = '';
|
|
this.saxParser = this.saxParser.write(chunk);
|
|
return this.saxParser.close();
|
|
} else {
|
|
chunk = this.remaining.substr(0, this.options.chunkSize);
|
|
this.remaining = this.remaining.substr(this.options.chunkSize, this.remaining.length);
|
|
this.saxParser = this.saxParser.write(chunk);
|
|
return setImmediate(this.processAsync);
|
|
}
|
|
} catch (error1) {
|
|
err = error1;
|
|
if (!this.saxParser.errThrown) {
|
|
this.saxParser.errThrown = true;
|
|
return this.emit(err);
|
|
}
|
|
}
|
|
};
|
|
|
|
Parser.prototype.assignOrPush = function(obj, key, newValue) {
|
|
if (!(key in obj)) {
|
|
if (!this.options.explicitArray) {
|
|
return obj[key] = newValue;
|
|
} else {
|
|
return obj[key] = [newValue];
|
|
}
|
|
} else {
|
|
if (!(obj[key] instanceof Array)) {
|
|
obj[key] = [obj[key]];
|
|
}
|
|
return obj[key].push(newValue);
|
|
}
|
|
};
|
|
|
|
Parser.prototype.reset = function() {
|
|
var attrkey, charkey, ontext, stack;
|
|
this.removeAllListeners();
|
|
this.saxParser = sax.parser(this.options.strict, {
|
|
trim: false,
|
|
normalize: false,
|
|
xmlns: this.options.xmlns
|
|
});
|
|
this.saxParser.errThrown = false;
|
|
this.saxParser.onerror = (function(_this) {
|
|
return function(error) {
|
|
_this.saxParser.resume();
|
|
if (!_this.saxParser.errThrown) {
|
|
_this.saxParser.errThrown = true;
|
|
return _this.emit("error", error);
|
|
}
|
|
};
|
|
})(this);
|
|
this.saxParser.onend = (function(_this) {
|
|
return function() {
|
|
if (!_this.saxParser.ended) {
|
|
_this.saxParser.ended = true;
|
|
return _this.emit("end", _this.resultObject);
|
|
}
|
|
};
|
|
})(this);
|
|
this.saxParser.ended = false;
|
|
this.EXPLICIT_CHARKEY = this.options.explicitCharkey;
|
|
this.resultObject = null;
|
|
stack = [];
|
|
attrkey = this.options.attrkey;
|
|
charkey = this.options.charkey;
|
|
this.saxParser.onopentag = (function(_this) {
|
|
return function(node) {
|
|
var key, newValue, obj, processedKey, ref;
|
|
obj = {};
|
|
obj[charkey] = "";
|
|
if (!_this.options.ignoreAttrs) {
|
|
ref = node.attributes;
|
|
for (key in ref) {
|
|
if (!hasProp.call(ref, key)) continue;
|
|
if (!(attrkey in obj) && !_this.options.mergeAttrs) {
|
|
obj[attrkey] = {};
|
|
}
|
|
newValue = _this.options.attrValueProcessors ? processItem(_this.options.attrValueProcessors, node.attributes[key], key) : node.attributes[key];
|
|
processedKey = _this.options.attrNameProcessors ? processItem(_this.options.attrNameProcessors, key) : key;
|
|
if (_this.options.mergeAttrs) {
|
|
_this.assignOrPush(obj, processedKey, newValue);
|
|
} else {
|
|
obj[attrkey][processedKey] = newValue;
|
|
}
|
|
}
|
|
}
|
|
obj["#name"] = _this.options.tagNameProcessors ? processItem(_this.options.tagNameProcessors, node.name) : node.name;
|
|
if (_this.options.xmlns) {
|
|
obj[_this.options.xmlnskey] = {
|
|
uri: node.uri,
|
|
local: node.local
|
|
};
|
|
}
|
|
return stack.push(obj);
|
|
};
|
|
})(this);
|
|
this.saxParser.onclosetag = (function(_this) {
|
|
return function() {
|
|
var cdata, emptyStr, key, node, nodeName, obj, objClone, old, s, xpath;
|
|
obj = stack.pop();
|
|
nodeName = obj["#name"];
|
|
if (!_this.options.explicitChildren || !_this.options.preserveChildrenOrder) {
|
|
delete obj["#name"];
|
|
}
|
|
if (obj.cdata === true) {
|
|
cdata = obj.cdata;
|
|
delete obj.cdata;
|
|
}
|
|
s = stack[stack.length - 1];
|
|
if (obj[charkey].match(/^\s*$/) && !cdata) {
|
|
emptyStr = obj[charkey];
|
|
delete obj[charkey];
|
|
} else {
|
|
if (_this.options.trim) {
|
|
obj[charkey] = obj[charkey].trim();
|
|
}
|
|
if (_this.options.normalize) {
|
|
obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim();
|
|
}
|
|
obj[charkey] = _this.options.valueProcessors ? processItem(_this.options.valueProcessors, obj[charkey], nodeName) : obj[charkey];
|
|
if (Object.keys(obj).length === 1 && charkey in obj && !_this.EXPLICIT_CHARKEY) {
|
|
obj = obj[charkey];
|
|
}
|
|
}
|
|
if (isEmpty(obj)) {
|
|
obj = _this.options.emptyTag !== '' ? _this.options.emptyTag : emptyStr;
|
|
}
|
|
if (_this.options.validator != null) {
|
|
xpath = "/" + ((function() {
|
|
var i, len, results;
|
|
results = [];
|
|
for (i = 0, len = stack.length; i < len; i++) {
|
|
node = stack[i];
|
|
results.push(node["#name"]);
|
|
}
|
|
return results;
|
|
})()).concat(nodeName).join("/");
|
|
(function() {
|
|
var err;
|
|
try {
|
|
return obj = _this.options.validator(xpath, s && s[nodeName], obj);
|
|
} catch (error1) {
|
|
err = error1;
|
|
return _this.emit("error", err);
|
|
}
|
|
})();
|
|
}
|
|
if (_this.options.explicitChildren && !_this.options.mergeAttrs && typeof obj === 'object') {
|
|
if (!_this.options.preserveChildrenOrder) {
|
|
node = {};
|
|
if (_this.options.attrkey in obj) {
|
|
node[_this.options.attrkey] = obj[_this.options.attrkey];
|
|
delete obj[_this.options.attrkey];
|
|
}
|
|
if (!_this.options.charsAsChildren && _this.options.charkey in obj) {
|
|
node[_this.options.charkey] = obj[_this.options.charkey];
|
|
delete obj[_this.options.charkey];
|
|
}
|
|
if (Object.getOwnPropertyNames(obj).length > 0) {
|
|
node[_this.options.childkey] = obj;
|
|
}
|
|
obj = node;
|
|
} else if (s) {
|
|
s[_this.options.childkey] = s[_this.options.childkey] || [];
|
|
objClone = {};
|
|
for (key in obj) {
|
|
if (!hasProp.call(obj, key)) continue;
|
|
objClone[key] = obj[key];
|
|
}
|
|
s[_this.options.childkey].push(objClone);
|
|
delete obj["#name"];
|
|
if (Object.keys(obj).length === 1 && charkey in obj && !_this.EXPLICIT_CHARKEY) {
|
|
obj = obj[charkey];
|
|
}
|
|
}
|
|
}
|
|
if (stack.length > 0) {
|
|
return _this.assignOrPush(s, nodeName, obj);
|
|
} else {
|
|
if (_this.options.explicitRoot) {
|
|
old = obj;
|
|
obj = {};
|
|
obj[nodeName] = old;
|
|
}
|
|
_this.resultObject = obj;
|
|
_this.saxParser.ended = true;
|
|
return _this.emit("end", _this.resultObject);
|
|
}
|
|
};
|
|
})(this);
|
|
ontext = (function(_this) {
|
|
return function(text) {
|
|
var charChild, s;
|
|
s = stack[stack.length - 1];
|
|
if (s) {
|
|
s[charkey] += text;
|
|
if (_this.options.explicitChildren && _this.options.preserveChildrenOrder && _this.options.charsAsChildren && (_this.options.includeWhiteChars || text.replace(/\\n/g, '').trim() !== '')) {
|
|
s[_this.options.childkey] = s[_this.options.childkey] || [];
|
|
charChild = {
|
|
'#name': '__text__'
|
|
};
|
|
charChild[charkey] = text;
|
|
if (_this.options.normalize) {
|
|
charChild[charkey] = charChild[charkey].replace(/\s{2,}/g, " ").trim();
|
|
}
|
|
s[_this.options.childkey].push(charChild);
|
|
}
|
|
return s;
|
|
}
|
|
};
|
|
})(this);
|
|
this.saxParser.ontext = ontext;
|
|
return this.saxParser.oncdata = (function(_this) {
|
|
return function(text) {
|
|
var s;
|
|
s = ontext(text);
|
|
if (s) {
|
|
return s.cdata = true;
|
|
}
|
|
};
|
|
})(this);
|
|
};
|
|
|
|
Parser.prototype.parseString = function(str, cb) {
|
|
var err;
|
|
if ((cb != null) && typeof cb === "function") {
|
|
this.on("end", function(result) {
|
|
this.reset();
|
|
return cb(null, result);
|
|
});
|
|
this.on("error", function(err) {
|
|
this.reset();
|
|
return cb(err);
|
|
});
|
|
}
|
|
try {
|
|
str = str.toString();
|
|
if (str.trim() === '') {
|
|
this.emit("end", null);
|
|
return true;
|
|
}
|
|
str = bom.stripBOM(str);
|
|
if (this.options.async) {
|
|
this.remaining = str;
|
|
setImmediate(this.processAsync);
|
|
return this.saxParser;
|
|
}
|
|
return this.saxParser.write(str).close();
|
|
} catch (error1) {
|
|
err = error1;
|
|
if (!(this.saxParser.errThrown || this.saxParser.ended)) {
|
|
this.emit('error', err);
|
|
return this.saxParser.errThrown = true;
|
|
} else if (this.saxParser.ended) {
|
|
throw err;
|
|
}
|
|
}
|
|
};
|
|
|
|
Parser.prototype.parseStringPromise = function(str) {
|
|
return new Promise((function(_this) {
|
|
return function(resolve, reject) {
|
|
return _this.parseString(str, function(err, value) {
|
|
if (err) {
|
|
return reject(err);
|
|
} else {
|
|
return resolve(value);
|
|
}
|
|
});
|
|
};
|
|
})(this));
|
|
};
|
|
|
|
return Parser;
|
|
|
|
})(events);
|
|
|
|
exports.parseString = function(str, a, b) {
|
|
var cb, options, parser;
|
|
if (b != null) {
|
|
if (typeof b === 'function') {
|
|
cb = b;
|
|
}
|
|
if (typeof a === 'object') {
|
|
options = a;
|
|
}
|
|
} else {
|
|
if (typeof a === 'function') {
|
|
cb = a;
|
|
}
|
|
options = {};
|
|
}
|
|
parser = new exports.Parser(options);
|
|
return parser.parseString(str, cb);
|
|
};
|
|
|
|
exports.parseStringPromise = function(str, a) {
|
|
var options, parser;
|
|
if (typeof a === 'object') {
|
|
options = a;
|
|
}
|
|
parser = new exports.Parser(options);
|
|
return parser.parseStringPromise(str);
|
|
};
|
|
|
|
}).call(this);
|
|
|
|
},{"./bom":60,"./defaults":62,"./processors":64,"events":4,"sax":59,"timers":25}],64:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
"use strict";
|
|
var prefixMatch;
|
|
|
|
prefixMatch = new RegExp(/(?!xmlns)^.*:/);
|
|
|
|
exports.normalize = function(str) {
|
|
return str.toLowerCase();
|
|
};
|
|
|
|
exports.firstCharLowerCase = function(str) {
|
|
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
};
|
|
|
|
exports.stripPrefix = function(str) {
|
|
return str.replace(prefixMatch, '');
|
|
};
|
|
|
|
exports.parseNumbers = function(str) {
|
|
if (!isNaN(str)) {
|
|
str = str % 1 === 0 ? parseInt(str, 10) : parseFloat(str);
|
|
}
|
|
return str;
|
|
};
|
|
|
|
exports.parseBooleans = function(str) {
|
|
if (/^(?:true|false)$/i.test(str)) {
|
|
str = str.toLowerCase() === 'true';
|
|
}
|
|
return str;
|
|
};
|
|
|
|
}).call(this);
|
|
|
|
},{}],65:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
"use strict";
|
|
var builder, defaults, parser, processors,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
defaults = require('./defaults');
|
|
|
|
builder = require('./builder');
|
|
|
|
parser = require('./parser');
|
|
|
|
processors = require('./processors');
|
|
|
|
exports.defaults = defaults.defaults;
|
|
|
|
exports.processors = processors;
|
|
|
|
exports.ValidationError = (function(superClass) {
|
|
extend(ValidationError, superClass);
|
|
|
|
function ValidationError(message) {
|
|
this.message = message;
|
|
}
|
|
|
|
return ValidationError;
|
|
|
|
})(Error);
|
|
|
|
exports.Builder = builder.Builder;
|
|
|
|
exports.Parser = parser.Parser;
|
|
|
|
exports.parseString = parser.parseString;
|
|
|
|
exports.parseStringPromise = parser.parseStringPromise;
|
|
|
|
}).call(this);
|
|
|
|
},{"./builder":61,"./defaults":62,"./parser":63,"./processors":64}],66:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
module.exports = {
|
|
Disconnected: 1,
|
|
Preceding: 2,
|
|
Following: 4,
|
|
Contains: 8,
|
|
ContainedBy: 16,
|
|
ImplementationSpecific: 32
|
|
};
|
|
|
|
}).call(this);
|
|
|
|
},{}],67:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
module.exports = {
|
|
Element: 1,
|
|
Attribute: 2,
|
|
Text: 3,
|
|
CData: 4,
|
|
EntityReference: 5,
|
|
EntityDeclaration: 6,
|
|
ProcessingInstruction: 7,
|
|
Comment: 8,
|
|
Document: 9,
|
|
DocType: 10,
|
|
DocumentFragment: 11,
|
|
NotationDeclaration: 12,
|
|
Declaration: 201,
|
|
Raw: 202,
|
|
AttributeDeclaration: 203,
|
|
ElementDeclaration: 204,
|
|
Dummy: 205
|
|
};
|
|
|
|
}).call(this);
|
|
|
|
},{}],68:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var assign, getValue, isArray, isEmpty, isFunction, isObject, isPlainObject,
|
|
slice = [].slice,
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
assign = function() {
|
|
var i, key, len, source, sources, target;
|
|
target = arguments[0], sources = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
|
if (isFunction(Object.assign)) {
|
|
Object.assign.apply(null, arguments);
|
|
} else {
|
|
for (i = 0, len = sources.length; i < len; i++) {
|
|
source = sources[i];
|
|
if (source != null) {
|
|
for (key in source) {
|
|
if (!hasProp.call(source, key)) continue;
|
|
target[key] = source[key];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return target;
|
|
};
|
|
|
|
isFunction = function(val) {
|
|
return !!val && Object.prototype.toString.call(val) === '[object Function]';
|
|
};
|
|
|
|
isObject = function(val) {
|
|
var ref;
|
|
return !!val && ((ref = typeof val) === 'function' || ref === 'object');
|
|
};
|
|
|
|
isArray = function(val) {
|
|
if (isFunction(Array.isArray)) {
|
|
return Array.isArray(val);
|
|
} else {
|
|
return Object.prototype.toString.call(val) === '[object Array]';
|
|
}
|
|
};
|
|
|
|
isEmpty = function(val) {
|
|
var key;
|
|
if (isArray(val)) {
|
|
return !val.length;
|
|
} else {
|
|
for (key in val) {
|
|
if (!hasProp.call(val, key)) continue;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
isPlainObject = function(val) {
|
|
var ctor, proto;
|
|
return isObject(val) && (proto = Object.getPrototypeOf(val)) && (ctor = proto.constructor) && (typeof ctor === 'function') && (ctor instanceof ctor) && (Function.prototype.toString.call(ctor) === Function.prototype.toString.call(Object));
|
|
};
|
|
|
|
getValue = function(obj) {
|
|
if (isFunction(obj.valueOf)) {
|
|
return obj.valueOf();
|
|
} else {
|
|
return obj;
|
|
}
|
|
};
|
|
|
|
module.exports.assign = assign;
|
|
|
|
module.exports.isFunction = isFunction;
|
|
|
|
module.exports.isObject = isObject;
|
|
|
|
module.exports.isArray = isArray;
|
|
|
|
module.exports.isEmpty = isEmpty;
|
|
|
|
module.exports.isPlainObject = isPlainObject;
|
|
|
|
module.exports.getValue = getValue;
|
|
|
|
}).call(this);
|
|
|
|
},{}],69:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
module.exports = {
|
|
None: 0,
|
|
OpenTag: 1,
|
|
InsideTag: 2,
|
|
CloseTag: 3
|
|
};
|
|
|
|
}).call(this);
|
|
|
|
},{}],70:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLAttribute, XMLNode;
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
module.exports = XMLAttribute = (function() {
|
|
function XMLAttribute(parent, name, value) {
|
|
this.parent = parent;
|
|
if (this.parent) {
|
|
this.options = this.parent.options;
|
|
this.stringify = this.parent.stringify;
|
|
}
|
|
if (name == null) {
|
|
throw new Error("Missing attribute name. " + this.debugInfo(name));
|
|
}
|
|
this.name = this.stringify.name(name);
|
|
this.value = this.stringify.attValue(value);
|
|
this.type = NodeType.Attribute;
|
|
this.isId = false;
|
|
this.schemaTypeInfo = null;
|
|
}
|
|
|
|
Object.defineProperty(XMLAttribute.prototype, 'nodeType', {
|
|
get: function() {
|
|
return this.type;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLAttribute.prototype, 'ownerElement', {
|
|
get: function() {
|
|
return this.parent;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLAttribute.prototype, 'textContent', {
|
|
get: function() {
|
|
return this.value;
|
|
},
|
|
set: function(value) {
|
|
return this.value = value || '';
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLAttribute.prototype, 'namespaceURI', {
|
|
get: function() {
|
|
return '';
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLAttribute.prototype, 'prefix', {
|
|
get: function() {
|
|
return '';
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLAttribute.prototype, 'localName', {
|
|
get: function() {
|
|
return this.name;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLAttribute.prototype, 'specified', {
|
|
get: function() {
|
|
return true;
|
|
}
|
|
});
|
|
|
|
XMLAttribute.prototype.clone = function() {
|
|
return Object.create(this);
|
|
};
|
|
|
|
XMLAttribute.prototype.toString = function(options) {
|
|
return this.options.writer.attribute(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
XMLAttribute.prototype.debugInfo = function(name) {
|
|
name = name || this.name;
|
|
if (name == null) {
|
|
return "parent: <" + this.parent.name + ">";
|
|
} else {
|
|
return "attribute: {" + name + "}, parent: <" + this.parent.name + ">";
|
|
}
|
|
};
|
|
|
|
XMLAttribute.prototype.isEqualNode = function(node) {
|
|
if (node.namespaceURI !== this.namespaceURI) {
|
|
return false;
|
|
}
|
|
if (node.prefix !== this.prefix) {
|
|
return false;
|
|
}
|
|
if (node.localName !== this.localName) {
|
|
return false;
|
|
}
|
|
if (node.value !== this.value) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
return XMLAttribute;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./XMLNode":89}],71:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLCData, XMLCharacterData,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLCharacterData = require('./XMLCharacterData');
|
|
|
|
module.exports = XMLCData = (function(superClass) {
|
|
extend(XMLCData, superClass);
|
|
|
|
function XMLCData(parent, text) {
|
|
XMLCData.__super__.constructor.call(this, parent);
|
|
if (text == null) {
|
|
throw new Error("Missing CDATA text. " + this.debugInfo());
|
|
}
|
|
this.name = "#cdata-section";
|
|
this.type = NodeType.CData;
|
|
this.value = this.stringify.cdata(text);
|
|
}
|
|
|
|
XMLCData.prototype.clone = function() {
|
|
return Object.create(this);
|
|
};
|
|
|
|
XMLCData.prototype.toString = function(options) {
|
|
return this.options.writer.cdata(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
return XMLCData;
|
|
|
|
})(XMLCharacterData);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./XMLCharacterData":72}],72:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var XMLCharacterData, XMLNode,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
module.exports = XMLCharacterData = (function(superClass) {
|
|
extend(XMLCharacterData, superClass);
|
|
|
|
function XMLCharacterData(parent) {
|
|
XMLCharacterData.__super__.constructor.call(this, parent);
|
|
this.value = '';
|
|
}
|
|
|
|
Object.defineProperty(XMLCharacterData.prototype, 'data', {
|
|
get: function() {
|
|
return this.value;
|
|
},
|
|
set: function(value) {
|
|
return this.value = value || '';
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLCharacterData.prototype, 'length', {
|
|
get: function() {
|
|
return this.value.length;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLCharacterData.prototype, 'textContent', {
|
|
get: function() {
|
|
return this.value;
|
|
},
|
|
set: function(value) {
|
|
return this.value = value || '';
|
|
}
|
|
});
|
|
|
|
XMLCharacterData.prototype.clone = function() {
|
|
return Object.create(this);
|
|
};
|
|
|
|
XMLCharacterData.prototype.substringData = function(offset, count) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLCharacterData.prototype.appendData = function(arg) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLCharacterData.prototype.insertData = function(offset, arg) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLCharacterData.prototype.deleteData = function(offset, count) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLCharacterData.prototype.replaceData = function(offset, count, arg) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLCharacterData.prototype.isEqualNode = function(node) {
|
|
if (!XMLCharacterData.__super__.isEqualNode.apply(this, arguments).isEqualNode(node)) {
|
|
return false;
|
|
}
|
|
if (node.data !== this.data) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
return XMLCharacterData;
|
|
|
|
})(XMLNode);
|
|
|
|
}).call(this);
|
|
|
|
},{"./XMLNode":89}],73:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLCharacterData, XMLComment,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLCharacterData = require('./XMLCharacterData');
|
|
|
|
module.exports = XMLComment = (function(superClass) {
|
|
extend(XMLComment, superClass);
|
|
|
|
function XMLComment(parent, text) {
|
|
XMLComment.__super__.constructor.call(this, parent);
|
|
if (text == null) {
|
|
throw new Error("Missing comment text. " + this.debugInfo());
|
|
}
|
|
this.name = "#comment";
|
|
this.type = NodeType.Comment;
|
|
this.value = this.stringify.comment(text);
|
|
}
|
|
|
|
XMLComment.prototype.clone = function() {
|
|
return Object.create(this);
|
|
};
|
|
|
|
XMLComment.prototype.toString = function(options) {
|
|
return this.options.writer.comment(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
return XMLComment;
|
|
|
|
})(XMLCharacterData);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./XMLCharacterData":72}],74:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var XMLDOMConfiguration, XMLDOMErrorHandler, XMLDOMStringList;
|
|
|
|
XMLDOMErrorHandler = require('./XMLDOMErrorHandler');
|
|
|
|
XMLDOMStringList = require('./XMLDOMStringList');
|
|
|
|
module.exports = XMLDOMConfiguration = (function() {
|
|
function XMLDOMConfiguration() {
|
|
var clonedSelf;
|
|
this.defaultParams = {
|
|
"canonical-form": false,
|
|
"cdata-sections": false,
|
|
"comments": false,
|
|
"datatype-normalization": false,
|
|
"element-content-whitespace": true,
|
|
"entities": true,
|
|
"error-handler": new XMLDOMErrorHandler(),
|
|
"infoset": true,
|
|
"validate-if-schema": false,
|
|
"namespaces": true,
|
|
"namespace-declarations": true,
|
|
"normalize-characters": false,
|
|
"schema-location": '',
|
|
"schema-type": '',
|
|
"split-cdata-sections": true,
|
|
"validate": false,
|
|
"well-formed": true
|
|
};
|
|
this.params = clonedSelf = Object.create(this.defaultParams);
|
|
}
|
|
|
|
Object.defineProperty(XMLDOMConfiguration.prototype, 'parameterNames', {
|
|
get: function() {
|
|
return new XMLDOMStringList(Object.keys(this.defaultParams));
|
|
}
|
|
});
|
|
|
|
XMLDOMConfiguration.prototype.getParameter = function(name) {
|
|
if (this.params.hasOwnProperty(name)) {
|
|
return this.params[name];
|
|
} else {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
XMLDOMConfiguration.prototype.canSetParameter = function(name, value) {
|
|
return true;
|
|
};
|
|
|
|
XMLDOMConfiguration.prototype.setParameter = function(name, value) {
|
|
if (value != null) {
|
|
return this.params[name] = value;
|
|
} else {
|
|
return delete this.params[name];
|
|
}
|
|
};
|
|
|
|
return XMLDOMConfiguration;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{"./XMLDOMErrorHandler":75,"./XMLDOMStringList":77}],75:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var XMLDOMErrorHandler;
|
|
|
|
module.exports = XMLDOMErrorHandler = (function() {
|
|
function XMLDOMErrorHandler() {}
|
|
|
|
XMLDOMErrorHandler.prototype.handleError = function(error) {
|
|
throw new Error(error);
|
|
};
|
|
|
|
return XMLDOMErrorHandler;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{}],76:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var XMLDOMImplementation;
|
|
|
|
module.exports = XMLDOMImplementation = (function() {
|
|
function XMLDOMImplementation() {}
|
|
|
|
XMLDOMImplementation.prototype.hasFeature = function(feature, version) {
|
|
return true;
|
|
};
|
|
|
|
XMLDOMImplementation.prototype.createDocumentType = function(qualifiedName, publicId, systemId) {
|
|
throw new Error("This DOM method is not implemented.");
|
|
};
|
|
|
|
XMLDOMImplementation.prototype.createDocument = function(namespaceURI, qualifiedName, doctype) {
|
|
throw new Error("This DOM method is not implemented.");
|
|
};
|
|
|
|
XMLDOMImplementation.prototype.createHTMLDocument = function(title) {
|
|
throw new Error("This DOM method is not implemented.");
|
|
};
|
|
|
|
XMLDOMImplementation.prototype.getFeature = function(feature, version) {
|
|
throw new Error("This DOM method is not implemented.");
|
|
};
|
|
|
|
return XMLDOMImplementation;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{}],77:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var XMLDOMStringList;
|
|
|
|
module.exports = XMLDOMStringList = (function() {
|
|
function XMLDOMStringList(arr) {
|
|
this.arr = arr || [];
|
|
}
|
|
|
|
Object.defineProperty(XMLDOMStringList.prototype, 'length', {
|
|
get: function() {
|
|
return this.arr.length;
|
|
}
|
|
});
|
|
|
|
XMLDOMStringList.prototype.item = function(index) {
|
|
return this.arr[index] || null;
|
|
};
|
|
|
|
XMLDOMStringList.prototype.contains = function(str) {
|
|
return this.arr.indexOf(str) !== -1;
|
|
};
|
|
|
|
return XMLDOMStringList;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{}],78:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLDTDAttList, XMLNode,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
module.exports = XMLDTDAttList = (function(superClass) {
|
|
extend(XMLDTDAttList, superClass);
|
|
|
|
function XMLDTDAttList(parent, elementName, attributeName, attributeType, defaultValueType, defaultValue) {
|
|
XMLDTDAttList.__super__.constructor.call(this, parent);
|
|
if (elementName == null) {
|
|
throw new Error("Missing DTD element name. " + this.debugInfo());
|
|
}
|
|
if (attributeName == null) {
|
|
throw new Error("Missing DTD attribute name. " + this.debugInfo(elementName));
|
|
}
|
|
if (!attributeType) {
|
|
throw new Error("Missing DTD attribute type. " + this.debugInfo(elementName));
|
|
}
|
|
if (!defaultValueType) {
|
|
throw new Error("Missing DTD attribute default. " + this.debugInfo(elementName));
|
|
}
|
|
if (defaultValueType.indexOf('#') !== 0) {
|
|
defaultValueType = '#' + defaultValueType;
|
|
}
|
|
if (!defaultValueType.match(/^(#REQUIRED|#IMPLIED|#FIXED|#DEFAULT)$/)) {
|
|
throw new Error("Invalid default value type; expected: #REQUIRED, #IMPLIED, #FIXED or #DEFAULT. " + this.debugInfo(elementName));
|
|
}
|
|
if (defaultValue && !defaultValueType.match(/^(#FIXED|#DEFAULT)$/)) {
|
|
throw new Error("Default value only applies to #FIXED or #DEFAULT. " + this.debugInfo(elementName));
|
|
}
|
|
this.elementName = this.stringify.name(elementName);
|
|
this.type = NodeType.AttributeDeclaration;
|
|
this.attributeName = this.stringify.name(attributeName);
|
|
this.attributeType = this.stringify.dtdAttType(attributeType);
|
|
if (defaultValue) {
|
|
this.defaultValue = this.stringify.dtdAttDefault(defaultValue);
|
|
}
|
|
this.defaultValueType = defaultValueType;
|
|
}
|
|
|
|
XMLDTDAttList.prototype.toString = function(options) {
|
|
return this.options.writer.dtdAttList(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
return XMLDTDAttList;
|
|
|
|
})(XMLNode);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./XMLNode":89}],79:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLDTDElement, XMLNode,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
module.exports = XMLDTDElement = (function(superClass) {
|
|
extend(XMLDTDElement, superClass);
|
|
|
|
function XMLDTDElement(parent, name, value) {
|
|
XMLDTDElement.__super__.constructor.call(this, parent);
|
|
if (name == null) {
|
|
throw new Error("Missing DTD element name. " + this.debugInfo());
|
|
}
|
|
if (!value) {
|
|
value = '(#PCDATA)';
|
|
}
|
|
if (Array.isArray(value)) {
|
|
value = '(' + value.join(',') + ')';
|
|
}
|
|
this.name = this.stringify.name(name);
|
|
this.type = NodeType.ElementDeclaration;
|
|
this.value = this.stringify.dtdElementValue(value);
|
|
}
|
|
|
|
XMLDTDElement.prototype.toString = function(options) {
|
|
return this.options.writer.dtdElement(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
return XMLDTDElement;
|
|
|
|
})(XMLNode);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./XMLNode":89}],80:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLDTDEntity, XMLNode, isObject,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
isObject = require('./Utility').isObject;
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
module.exports = XMLDTDEntity = (function(superClass) {
|
|
extend(XMLDTDEntity, superClass);
|
|
|
|
function XMLDTDEntity(parent, pe, name, value) {
|
|
XMLDTDEntity.__super__.constructor.call(this, parent);
|
|
if (name == null) {
|
|
throw new Error("Missing DTD entity name. " + this.debugInfo(name));
|
|
}
|
|
if (value == null) {
|
|
throw new Error("Missing DTD entity value. " + this.debugInfo(name));
|
|
}
|
|
this.pe = !!pe;
|
|
this.name = this.stringify.name(name);
|
|
this.type = NodeType.EntityDeclaration;
|
|
if (!isObject(value)) {
|
|
this.value = this.stringify.dtdEntityValue(value);
|
|
this.internal = true;
|
|
} else {
|
|
if (!value.pubID && !value.sysID) {
|
|
throw new Error("Public and/or system identifiers are required for an external entity. " + this.debugInfo(name));
|
|
}
|
|
if (value.pubID && !value.sysID) {
|
|
throw new Error("System identifier is required for a public external entity. " + this.debugInfo(name));
|
|
}
|
|
this.internal = false;
|
|
if (value.pubID != null) {
|
|
this.pubID = this.stringify.dtdPubID(value.pubID);
|
|
}
|
|
if (value.sysID != null) {
|
|
this.sysID = this.stringify.dtdSysID(value.sysID);
|
|
}
|
|
if (value.nData != null) {
|
|
this.nData = this.stringify.dtdNData(value.nData);
|
|
}
|
|
if (this.pe && this.nData) {
|
|
throw new Error("Notation declaration is not allowed in a parameter entity. " + this.debugInfo(name));
|
|
}
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(XMLDTDEntity.prototype, 'publicId', {
|
|
get: function() {
|
|
return this.pubID;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDTDEntity.prototype, 'systemId', {
|
|
get: function() {
|
|
return this.sysID;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDTDEntity.prototype, 'notationName', {
|
|
get: function() {
|
|
return this.nData || null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDTDEntity.prototype, 'inputEncoding', {
|
|
get: function() {
|
|
return null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDTDEntity.prototype, 'xmlEncoding', {
|
|
get: function() {
|
|
return null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDTDEntity.prototype, 'xmlVersion', {
|
|
get: function() {
|
|
return null;
|
|
}
|
|
});
|
|
|
|
XMLDTDEntity.prototype.toString = function(options) {
|
|
return this.options.writer.dtdEntity(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
return XMLDTDEntity;
|
|
|
|
})(XMLNode);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./Utility":68,"./XMLNode":89}],81:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLDTDNotation, XMLNode,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
module.exports = XMLDTDNotation = (function(superClass) {
|
|
extend(XMLDTDNotation, superClass);
|
|
|
|
function XMLDTDNotation(parent, name, value) {
|
|
XMLDTDNotation.__super__.constructor.call(this, parent);
|
|
if (name == null) {
|
|
throw new Error("Missing DTD notation name. " + this.debugInfo(name));
|
|
}
|
|
if (!value.pubID && !value.sysID) {
|
|
throw new Error("Public or system identifiers are required for an external entity. " + this.debugInfo(name));
|
|
}
|
|
this.name = this.stringify.name(name);
|
|
this.type = NodeType.NotationDeclaration;
|
|
if (value.pubID != null) {
|
|
this.pubID = this.stringify.dtdPubID(value.pubID);
|
|
}
|
|
if (value.sysID != null) {
|
|
this.sysID = this.stringify.dtdSysID(value.sysID);
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(XMLDTDNotation.prototype, 'publicId', {
|
|
get: function() {
|
|
return this.pubID;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDTDNotation.prototype, 'systemId', {
|
|
get: function() {
|
|
return this.sysID;
|
|
}
|
|
});
|
|
|
|
XMLDTDNotation.prototype.toString = function(options) {
|
|
return this.options.writer.dtdNotation(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
return XMLDTDNotation;
|
|
|
|
})(XMLNode);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./XMLNode":89}],82:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLDeclaration, XMLNode, isObject,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
isObject = require('./Utility').isObject;
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
module.exports = XMLDeclaration = (function(superClass) {
|
|
extend(XMLDeclaration, superClass);
|
|
|
|
function XMLDeclaration(parent, version, encoding, standalone) {
|
|
var ref;
|
|
XMLDeclaration.__super__.constructor.call(this, parent);
|
|
if (isObject(version)) {
|
|
ref = version, version = ref.version, encoding = ref.encoding, standalone = ref.standalone;
|
|
}
|
|
if (!version) {
|
|
version = '1.0';
|
|
}
|
|
this.type = NodeType.Declaration;
|
|
this.version = this.stringify.xmlVersion(version);
|
|
if (encoding != null) {
|
|
this.encoding = this.stringify.xmlEncoding(encoding);
|
|
}
|
|
if (standalone != null) {
|
|
this.standalone = this.stringify.xmlStandalone(standalone);
|
|
}
|
|
}
|
|
|
|
XMLDeclaration.prototype.toString = function(options) {
|
|
return this.options.writer.declaration(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
return XMLDeclaration;
|
|
|
|
})(XMLNode);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./Utility":68,"./XMLNode":89}],83:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLDTDAttList, XMLDTDElement, XMLDTDEntity, XMLDTDNotation, XMLDocType, XMLNamedNodeMap, XMLNode, isObject,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
isObject = require('./Utility').isObject;
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLDTDAttList = require('./XMLDTDAttList');
|
|
|
|
XMLDTDEntity = require('./XMLDTDEntity');
|
|
|
|
XMLDTDElement = require('./XMLDTDElement');
|
|
|
|
XMLDTDNotation = require('./XMLDTDNotation');
|
|
|
|
XMLNamedNodeMap = require('./XMLNamedNodeMap');
|
|
|
|
module.exports = XMLDocType = (function(superClass) {
|
|
extend(XMLDocType, superClass);
|
|
|
|
function XMLDocType(parent, pubID, sysID) {
|
|
var child, i, len, ref, ref1, ref2;
|
|
XMLDocType.__super__.constructor.call(this, parent);
|
|
this.type = NodeType.DocType;
|
|
if (parent.children) {
|
|
ref = parent.children;
|
|
for (i = 0, len = ref.length; i < len; i++) {
|
|
child = ref[i];
|
|
if (child.type === NodeType.Element) {
|
|
this.name = child.name;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
this.documentObject = parent;
|
|
if (isObject(pubID)) {
|
|
ref1 = pubID, pubID = ref1.pubID, sysID = ref1.sysID;
|
|
}
|
|
if (sysID == null) {
|
|
ref2 = [pubID, sysID], sysID = ref2[0], pubID = ref2[1];
|
|
}
|
|
if (pubID != null) {
|
|
this.pubID = this.stringify.dtdPubID(pubID);
|
|
}
|
|
if (sysID != null) {
|
|
this.sysID = this.stringify.dtdSysID(sysID);
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(XMLDocType.prototype, 'entities', {
|
|
get: function() {
|
|
var child, i, len, nodes, ref;
|
|
nodes = {};
|
|
ref = this.children;
|
|
for (i = 0, len = ref.length; i < len; i++) {
|
|
child = ref[i];
|
|
if ((child.type === NodeType.EntityDeclaration) && !child.pe) {
|
|
nodes[child.name] = child;
|
|
}
|
|
}
|
|
return new XMLNamedNodeMap(nodes);
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocType.prototype, 'notations', {
|
|
get: function() {
|
|
var child, i, len, nodes, ref;
|
|
nodes = {};
|
|
ref = this.children;
|
|
for (i = 0, len = ref.length; i < len; i++) {
|
|
child = ref[i];
|
|
if (child.type === NodeType.NotationDeclaration) {
|
|
nodes[child.name] = child;
|
|
}
|
|
}
|
|
return new XMLNamedNodeMap(nodes);
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocType.prototype, 'publicId', {
|
|
get: function() {
|
|
return this.pubID;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocType.prototype, 'systemId', {
|
|
get: function() {
|
|
return this.sysID;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocType.prototype, 'internalSubset', {
|
|
get: function() {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
}
|
|
});
|
|
|
|
XMLDocType.prototype.element = function(name, value) {
|
|
var child;
|
|
child = new XMLDTDElement(this, name, value);
|
|
this.children.push(child);
|
|
return this;
|
|
};
|
|
|
|
XMLDocType.prototype.attList = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) {
|
|
var child;
|
|
child = new XMLDTDAttList(this, elementName, attributeName, attributeType, defaultValueType, defaultValue);
|
|
this.children.push(child);
|
|
return this;
|
|
};
|
|
|
|
XMLDocType.prototype.entity = function(name, value) {
|
|
var child;
|
|
child = new XMLDTDEntity(this, false, name, value);
|
|
this.children.push(child);
|
|
return this;
|
|
};
|
|
|
|
XMLDocType.prototype.pEntity = function(name, value) {
|
|
var child;
|
|
child = new XMLDTDEntity(this, true, name, value);
|
|
this.children.push(child);
|
|
return this;
|
|
};
|
|
|
|
XMLDocType.prototype.notation = function(name, value) {
|
|
var child;
|
|
child = new XMLDTDNotation(this, name, value);
|
|
this.children.push(child);
|
|
return this;
|
|
};
|
|
|
|
XMLDocType.prototype.toString = function(options) {
|
|
return this.options.writer.docType(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
XMLDocType.prototype.ele = function(name, value) {
|
|
return this.element(name, value);
|
|
};
|
|
|
|
XMLDocType.prototype.att = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) {
|
|
return this.attList(elementName, attributeName, attributeType, defaultValueType, defaultValue);
|
|
};
|
|
|
|
XMLDocType.prototype.ent = function(name, value) {
|
|
return this.entity(name, value);
|
|
};
|
|
|
|
XMLDocType.prototype.pent = function(name, value) {
|
|
return this.pEntity(name, value);
|
|
};
|
|
|
|
XMLDocType.prototype.not = function(name, value) {
|
|
return this.notation(name, value);
|
|
};
|
|
|
|
XMLDocType.prototype.up = function() {
|
|
return this.root() || this.documentObject;
|
|
};
|
|
|
|
XMLDocType.prototype.isEqualNode = function(node) {
|
|
if (!XMLDocType.__super__.isEqualNode.apply(this, arguments).isEqualNode(node)) {
|
|
return false;
|
|
}
|
|
if (node.name !== this.name) {
|
|
return false;
|
|
}
|
|
if (node.publicId !== this.publicId) {
|
|
return false;
|
|
}
|
|
if (node.systemId !== this.systemId) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
return XMLDocType;
|
|
|
|
})(XMLNode);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./Utility":68,"./XMLDTDAttList":78,"./XMLDTDElement":79,"./XMLDTDEntity":80,"./XMLDTDNotation":81,"./XMLNamedNodeMap":88,"./XMLNode":89}],84:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLDOMConfiguration, XMLDOMImplementation, XMLDocument, XMLNode, XMLStringWriter, XMLStringifier, isPlainObject,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
isPlainObject = require('./Utility').isPlainObject;
|
|
|
|
XMLDOMImplementation = require('./XMLDOMImplementation');
|
|
|
|
XMLDOMConfiguration = require('./XMLDOMConfiguration');
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLStringifier = require('./XMLStringifier');
|
|
|
|
XMLStringWriter = require('./XMLStringWriter');
|
|
|
|
module.exports = XMLDocument = (function(superClass) {
|
|
extend(XMLDocument, superClass);
|
|
|
|
function XMLDocument(options) {
|
|
XMLDocument.__super__.constructor.call(this, null);
|
|
this.name = "#document";
|
|
this.type = NodeType.Document;
|
|
this.documentURI = null;
|
|
this.domConfig = new XMLDOMConfiguration();
|
|
options || (options = {});
|
|
if (!options.writer) {
|
|
options.writer = new XMLStringWriter();
|
|
}
|
|
this.options = options;
|
|
this.stringify = new XMLStringifier(options);
|
|
}
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'implementation', {
|
|
value: new XMLDOMImplementation()
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'doctype', {
|
|
get: function() {
|
|
var child, i, len, ref;
|
|
ref = this.children;
|
|
for (i = 0, len = ref.length; i < len; i++) {
|
|
child = ref[i];
|
|
if (child.type === NodeType.DocType) {
|
|
return child;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'documentElement', {
|
|
get: function() {
|
|
return this.rootObject || null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'inputEncoding', {
|
|
get: function() {
|
|
return null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'strictErrorChecking', {
|
|
get: function() {
|
|
return false;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'xmlEncoding', {
|
|
get: function() {
|
|
if (this.children.length !== 0 && this.children[0].type === NodeType.Declaration) {
|
|
return this.children[0].encoding;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'xmlStandalone', {
|
|
get: function() {
|
|
if (this.children.length !== 0 && this.children[0].type === NodeType.Declaration) {
|
|
return this.children[0].standalone === 'yes';
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'xmlVersion', {
|
|
get: function() {
|
|
if (this.children.length !== 0 && this.children[0].type === NodeType.Declaration) {
|
|
return this.children[0].version;
|
|
} else {
|
|
return "1.0";
|
|
}
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'URL', {
|
|
get: function() {
|
|
return this.documentURI;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'origin', {
|
|
get: function() {
|
|
return null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'compatMode', {
|
|
get: function() {
|
|
return null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'characterSet', {
|
|
get: function() {
|
|
return null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLDocument.prototype, 'contentType', {
|
|
get: function() {
|
|
return null;
|
|
}
|
|
});
|
|
|
|
XMLDocument.prototype.end = function(writer) {
|
|
var writerOptions;
|
|
writerOptions = {};
|
|
if (!writer) {
|
|
writer = this.options.writer;
|
|
} else if (isPlainObject(writer)) {
|
|
writerOptions = writer;
|
|
writer = this.options.writer;
|
|
}
|
|
return writer.document(this, writer.filterOptions(writerOptions));
|
|
};
|
|
|
|
XMLDocument.prototype.toString = function(options) {
|
|
return this.options.writer.document(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
XMLDocument.prototype.createElement = function(tagName) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createDocumentFragment = function() {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createTextNode = function(data) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createComment = function(data) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createCDATASection = function(data) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createProcessingInstruction = function(target, data) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createAttribute = function(name) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createEntityReference = function(name) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.getElementsByTagName = function(tagname) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.importNode = function(importedNode, deep) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createElementNS = function(namespaceURI, qualifiedName) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createAttributeNS = function(namespaceURI, qualifiedName) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.getElementsByTagNameNS = function(namespaceURI, localName) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.getElementById = function(elementId) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.adoptNode = function(source) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.normalizeDocument = function() {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.renameNode = function(node, namespaceURI, qualifiedName) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.getElementsByClassName = function(classNames) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createEvent = function(eventInterface) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createRange = function() {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createNodeIterator = function(root, whatToShow, filter) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLDocument.prototype.createTreeWalker = function(root, whatToShow, filter) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
return XMLDocument;
|
|
|
|
})(XMLNode);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./Utility":68,"./XMLDOMConfiguration":74,"./XMLDOMImplementation":76,"./XMLNode":89,"./XMLStringWriter":94,"./XMLStringifier":95}],85:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, WriterState, XMLAttribute, XMLCData, XMLComment, XMLDTDAttList, XMLDTDElement, XMLDTDEntity, XMLDTDNotation, XMLDeclaration, XMLDocType, XMLDocument, XMLDocumentCB, XMLElement, XMLProcessingInstruction, XMLRaw, XMLStringWriter, XMLStringifier, XMLText, getValue, isFunction, isObject, isPlainObject, ref,
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
ref = require('./Utility'), isObject = ref.isObject, isFunction = ref.isFunction, isPlainObject = ref.isPlainObject, getValue = ref.getValue;
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLDocument = require('./XMLDocument');
|
|
|
|
XMLElement = require('./XMLElement');
|
|
|
|
XMLCData = require('./XMLCData');
|
|
|
|
XMLComment = require('./XMLComment');
|
|
|
|
XMLRaw = require('./XMLRaw');
|
|
|
|
XMLText = require('./XMLText');
|
|
|
|
XMLProcessingInstruction = require('./XMLProcessingInstruction');
|
|
|
|
XMLDeclaration = require('./XMLDeclaration');
|
|
|
|
XMLDocType = require('./XMLDocType');
|
|
|
|
XMLDTDAttList = require('./XMLDTDAttList');
|
|
|
|
XMLDTDEntity = require('./XMLDTDEntity');
|
|
|
|
XMLDTDElement = require('./XMLDTDElement');
|
|
|
|
XMLDTDNotation = require('./XMLDTDNotation');
|
|
|
|
XMLAttribute = require('./XMLAttribute');
|
|
|
|
XMLStringifier = require('./XMLStringifier');
|
|
|
|
XMLStringWriter = require('./XMLStringWriter');
|
|
|
|
WriterState = require('./WriterState');
|
|
|
|
module.exports = XMLDocumentCB = (function() {
|
|
function XMLDocumentCB(options, onData, onEnd) {
|
|
var writerOptions;
|
|
this.name = "?xml";
|
|
this.type = NodeType.Document;
|
|
options || (options = {});
|
|
writerOptions = {};
|
|
if (!options.writer) {
|
|
options.writer = new XMLStringWriter();
|
|
} else if (isPlainObject(options.writer)) {
|
|
writerOptions = options.writer;
|
|
options.writer = new XMLStringWriter();
|
|
}
|
|
this.options = options;
|
|
this.writer = options.writer;
|
|
this.writerOptions = this.writer.filterOptions(writerOptions);
|
|
this.stringify = new XMLStringifier(options);
|
|
this.onDataCallback = onData || function() {};
|
|
this.onEndCallback = onEnd || function() {};
|
|
this.currentNode = null;
|
|
this.currentLevel = -1;
|
|
this.openTags = {};
|
|
this.documentStarted = false;
|
|
this.documentCompleted = false;
|
|
this.root = null;
|
|
}
|
|
|
|
XMLDocumentCB.prototype.createChildNode = function(node) {
|
|
var att, attName, attributes, child, i, len, ref1, ref2;
|
|
switch (node.type) {
|
|
case NodeType.CData:
|
|
this.cdata(node.value);
|
|
break;
|
|
case NodeType.Comment:
|
|
this.comment(node.value);
|
|
break;
|
|
case NodeType.Element:
|
|
attributes = {};
|
|
ref1 = node.attribs;
|
|
for (attName in ref1) {
|
|
if (!hasProp.call(ref1, attName)) continue;
|
|
att = ref1[attName];
|
|
attributes[attName] = att.value;
|
|
}
|
|
this.node(node.name, attributes);
|
|
break;
|
|
case NodeType.Dummy:
|
|
this.dummy();
|
|
break;
|
|
case NodeType.Raw:
|
|
this.raw(node.value);
|
|
break;
|
|
case NodeType.Text:
|
|
this.text(node.value);
|
|
break;
|
|
case NodeType.ProcessingInstruction:
|
|
this.instruction(node.target, node.value);
|
|
break;
|
|
default:
|
|
throw new Error("This XML node type is not supported in a JS object: " + node.constructor.name);
|
|
}
|
|
ref2 = node.children;
|
|
for (i = 0, len = ref2.length; i < len; i++) {
|
|
child = ref2[i];
|
|
this.createChildNode(child);
|
|
if (child.type === NodeType.Element) {
|
|
this.up();
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.dummy = function() {
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.node = function(name, attributes, text) {
|
|
var ref1;
|
|
if (name == null) {
|
|
throw new Error("Missing node name.");
|
|
}
|
|
if (this.root && this.currentLevel === -1) {
|
|
throw new Error("Document can only have one root node. " + this.debugInfo(name));
|
|
}
|
|
this.openCurrent();
|
|
name = getValue(name);
|
|
if (attributes == null) {
|
|
attributes = {};
|
|
}
|
|
attributes = getValue(attributes);
|
|
if (!isObject(attributes)) {
|
|
ref1 = [attributes, text], text = ref1[0], attributes = ref1[1];
|
|
}
|
|
this.currentNode = new XMLElement(this, name, attributes);
|
|
this.currentNode.children = false;
|
|
this.currentLevel++;
|
|
this.openTags[this.currentLevel] = this.currentNode;
|
|
if (text != null) {
|
|
this.text(text);
|
|
}
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.element = function(name, attributes, text) {
|
|
var child, i, len, oldValidationFlag, ref1, root;
|
|
if (this.currentNode && this.currentNode.type === NodeType.DocType) {
|
|
this.dtdElement.apply(this, arguments);
|
|
} else {
|
|
if (Array.isArray(name) || isObject(name) || isFunction(name)) {
|
|
oldValidationFlag = this.options.noValidation;
|
|
this.options.noValidation = true;
|
|
root = new XMLDocument(this.options).element('TEMP_ROOT');
|
|
root.element(name);
|
|
this.options.noValidation = oldValidationFlag;
|
|
ref1 = root.children;
|
|
for (i = 0, len = ref1.length; i < len; i++) {
|
|
child = ref1[i];
|
|
this.createChildNode(child);
|
|
if (child.type === NodeType.Element) {
|
|
this.up();
|
|
}
|
|
}
|
|
} else {
|
|
this.node(name, attributes, text);
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.attribute = function(name, value) {
|
|
var attName, attValue;
|
|
if (!this.currentNode || this.currentNode.children) {
|
|
throw new Error("att() can only be used immediately after an ele() call in callback mode. " + this.debugInfo(name));
|
|
}
|
|
if (name != null) {
|
|
name = getValue(name);
|
|
}
|
|
if (isObject(name)) {
|
|
for (attName in name) {
|
|
if (!hasProp.call(name, attName)) continue;
|
|
attValue = name[attName];
|
|
this.attribute(attName, attValue);
|
|
}
|
|
} else {
|
|
if (isFunction(value)) {
|
|
value = value.apply();
|
|
}
|
|
if (this.options.keepNullAttributes && (value == null)) {
|
|
this.currentNode.attribs[name] = new XMLAttribute(this, name, "");
|
|
} else if (value != null) {
|
|
this.currentNode.attribs[name] = new XMLAttribute(this, name, value);
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.text = function(value) {
|
|
var node;
|
|
this.openCurrent();
|
|
node = new XMLText(this, value);
|
|
this.onData(this.writer.text(node, this.writerOptions, this.currentLevel + 1), this.currentLevel + 1);
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.cdata = function(value) {
|
|
var node;
|
|
this.openCurrent();
|
|
node = new XMLCData(this, value);
|
|
this.onData(this.writer.cdata(node, this.writerOptions, this.currentLevel + 1), this.currentLevel + 1);
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.comment = function(value) {
|
|
var node;
|
|
this.openCurrent();
|
|
node = new XMLComment(this, value);
|
|
this.onData(this.writer.comment(node, this.writerOptions, this.currentLevel + 1), this.currentLevel + 1);
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.raw = function(value) {
|
|
var node;
|
|
this.openCurrent();
|
|
node = new XMLRaw(this, value);
|
|
this.onData(this.writer.raw(node, this.writerOptions, this.currentLevel + 1), this.currentLevel + 1);
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.instruction = function(target, value) {
|
|
var i, insTarget, insValue, len, node;
|
|
this.openCurrent();
|
|
if (target != null) {
|
|
target = getValue(target);
|
|
}
|
|
if (value != null) {
|
|
value = getValue(value);
|
|
}
|
|
if (Array.isArray(target)) {
|
|
for (i = 0, len = target.length; i < len; i++) {
|
|
insTarget = target[i];
|
|
this.instruction(insTarget);
|
|
}
|
|
} else if (isObject(target)) {
|
|
for (insTarget in target) {
|
|
if (!hasProp.call(target, insTarget)) continue;
|
|
insValue = target[insTarget];
|
|
this.instruction(insTarget, insValue);
|
|
}
|
|
} else {
|
|
if (isFunction(value)) {
|
|
value = value.apply();
|
|
}
|
|
node = new XMLProcessingInstruction(this, target, value);
|
|
this.onData(this.writer.processingInstruction(node, this.writerOptions, this.currentLevel + 1), this.currentLevel + 1);
|
|
}
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.declaration = function(version, encoding, standalone) {
|
|
var node;
|
|
this.openCurrent();
|
|
if (this.documentStarted) {
|
|
throw new Error("declaration() must be the first node.");
|
|
}
|
|
node = new XMLDeclaration(this, version, encoding, standalone);
|
|
this.onData(this.writer.declaration(node, this.writerOptions, this.currentLevel + 1), this.currentLevel + 1);
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.doctype = function(root, pubID, sysID) {
|
|
this.openCurrent();
|
|
if (root == null) {
|
|
throw new Error("Missing root node name.");
|
|
}
|
|
if (this.root) {
|
|
throw new Error("dtd() must come before the root node.");
|
|
}
|
|
this.currentNode = new XMLDocType(this, pubID, sysID);
|
|
this.currentNode.rootNodeName = root;
|
|
this.currentNode.children = false;
|
|
this.currentLevel++;
|
|
this.openTags[this.currentLevel] = this.currentNode;
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.dtdElement = function(name, value) {
|
|
var node;
|
|
this.openCurrent();
|
|
node = new XMLDTDElement(this, name, value);
|
|
this.onData(this.writer.dtdElement(node, this.writerOptions, this.currentLevel + 1), this.currentLevel + 1);
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.attList = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) {
|
|
var node;
|
|
this.openCurrent();
|
|
node = new XMLDTDAttList(this, elementName, attributeName, attributeType, defaultValueType, defaultValue);
|
|
this.onData(this.writer.dtdAttList(node, this.writerOptions, this.currentLevel + 1), this.currentLevel + 1);
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.entity = function(name, value) {
|
|
var node;
|
|
this.openCurrent();
|
|
node = new XMLDTDEntity(this, false, name, value);
|
|
this.onData(this.writer.dtdEntity(node, this.writerOptions, this.currentLevel + 1), this.currentLevel + 1);
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.pEntity = function(name, value) {
|
|
var node;
|
|
this.openCurrent();
|
|
node = new XMLDTDEntity(this, true, name, value);
|
|
this.onData(this.writer.dtdEntity(node, this.writerOptions, this.currentLevel + 1), this.currentLevel + 1);
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.notation = function(name, value) {
|
|
var node;
|
|
this.openCurrent();
|
|
node = new XMLDTDNotation(this, name, value);
|
|
this.onData(this.writer.dtdNotation(node, this.writerOptions, this.currentLevel + 1), this.currentLevel + 1);
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.up = function() {
|
|
if (this.currentLevel < 0) {
|
|
throw new Error("The document node has no parent.");
|
|
}
|
|
if (this.currentNode) {
|
|
if (this.currentNode.children) {
|
|
this.closeNode(this.currentNode);
|
|
} else {
|
|
this.openNode(this.currentNode);
|
|
}
|
|
this.currentNode = null;
|
|
} else {
|
|
this.closeNode(this.openTags[this.currentLevel]);
|
|
}
|
|
delete this.openTags[this.currentLevel];
|
|
this.currentLevel--;
|
|
return this;
|
|
};
|
|
|
|
XMLDocumentCB.prototype.end = function() {
|
|
while (this.currentLevel >= 0) {
|
|
this.up();
|
|
}
|
|
return this.onEnd();
|
|
};
|
|
|
|
XMLDocumentCB.prototype.openCurrent = function() {
|
|
if (this.currentNode) {
|
|
this.currentNode.children = true;
|
|
return this.openNode(this.currentNode);
|
|
}
|
|
};
|
|
|
|
XMLDocumentCB.prototype.openNode = function(node) {
|
|
var att, chunk, name, ref1;
|
|
if (!node.isOpen) {
|
|
if (!this.root && this.currentLevel === 0 && node.type === NodeType.Element) {
|
|
this.root = node;
|
|
}
|
|
chunk = '';
|
|
if (node.type === NodeType.Element) {
|
|
this.writerOptions.state = WriterState.OpenTag;
|
|
chunk = this.writer.indent(node, this.writerOptions, this.currentLevel) + '<' + node.name;
|
|
ref1 = node.attribs;
|
|
for (name in ref1) {
|
|
if (!hasProp.call(ref1, name)) continue;
|
|
att = ref1[name];
|
|
chunk += this.writer.attribute(att, this.writerOptions, this.currentLevel);
|
|
}
|
|
chunk += (node.children ? '>' : '/>') + this.writer.endline(node, this.writerOptions, this.currentLevel);
|
|
this.writerOptions.state = WriterState.InsideTag;
|
|
} else {
|
|
this.writerOptions.state = WriterState.OpenTag;
|
|
chunk = this.writer.indent(node, this.writerOptions, this.currentLevel) + '<!DOCTYPE ' + node.rootNodeName;
|
|
if (node.pubID && node.sysID) {
|
|
chunk += ' PUBLIC "' + node.pubID + '" "' + node.sysID + '"';
|
|
} else if (node.sysID) {
|
|
chunk += ' SYSTEM "' + node.sysID + '"';
|
|
}
|
|
if (node.children) {
|
|
chunk += ' [';
|
|
this.writerOptions.state = WriterState.InsideTag;
|
|
} else {
|
|
this.writerOptions.state = WriterState.CloseTag;
|
|
chunk += '>';
|
|
}
|
|
chunk += this.writer.endline(node, this.writerOptions, this.currentLevel);
|
|
}
|
|
this.onData(chunk, this.currentLevel);
|
|
return node.isOpen = true;
|
|
}
|
|
};
|
|
|
|
XMLDocumentCB.prototype.closeNode = function(node) {
|
|
var chunk;
|
|
if (!node.isClosed) {
|
|
chunk = '';
|
|
this.writerOptions.state = WriterState.CloseTag;
|
|
if (node.type === NodeType.Element) {
|
|
chunk = this.writer.indent(node, this.writerOptions, this.currentLevel) + '</' + node.name + '>' + this.writer.endline(node, this.writerOptions, this.currentLevel);
|
|
} else {
|
|
chunk = this.writer.indent(node, this.writerOptions, this.currentLevel) + ']>' + this.writer.endline(node, this.writerOptions, this.currentLevel);
|
|
}
|
|
this.writerOptions.state = WriterState.None;
|
|
this.onData(chunk, this.currentLevel);
|
|
return node.isClosed = true;
|
|
}
|
|
};
|
|
|
|
XMLDocumentCB.prototype.onData = function(chunk, level) {
|
|
this.documentStarted = true;
|
|
return this.onDataCallback(chunk, level + 1);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.onEnd = function() {
|
|
this.documentCompleted = true;
|
|
return this.onEndCallback();
|
|
};
|
|
|
|
XMLDocumentCB.prototype.debugInfo = function(name) {
|
|
if (name == null) {
|
|
return "";
|
|
} else {
|
|
return "node: <" + name + ">";
|
|
}
|
|
};
|
|
|
|
XMLDocumentCB.prototype.ele = function() {
|
|
return this.element.apply(this, arguments);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.nod = function(name, attributes, text) {
|
|
return this.node(name, attributes, text);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.txt = function(value) {
|
|
return this.text(value);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.dat = function(value) {
|
|
return this.cdata(value);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.com = function(value) {
|
|
return this.comment(value);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.ins = function(target, value) {
|
|
return this.instruction(target, value);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.dec = function(version, encoding, standalone) {
|
|
return this.declaration(version, encoding, standalone);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.dtd = function(root, pubID, sysID) {
|
|
return this.doctype(root, pubID, sysID);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.e = function(name, attributes, text) {
|
|
return this.element(name, attributes, text);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.n = function(name, attributes, text) {
|
|
return this.node(name, attributes, text);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.t = function(value) {
|
|
return this.text(value);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.d = function(value) {
|
|
return this.cdata(value);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.c = function(value) {
|
|
return this.comment(value);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.r = function(value) {
|
|
return this.raw(value);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.i = function(target, value) {
|
|
return this.instruction(target, value);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.att = function() {
|
|
if (this.currentNode && this.currentNode.type === NodeType.DocType) {
|
|
return this.attList.apply(this, arguments);
|
|
} else {
|
|
return this.attribute.apply(this, arguments);
|
|
}
|
|
};
|
|
|
|
XMLDocumentCB.prototype.a = function() {
|
|
if (this.currentNode && this.currentNode.type === NodeType.DocType) {
|
|
return this.attList.apply(this, arguments);
|
|
} else {
|
|
return this.attribute.apply(this, arguments);
|
|
}
|
|
};
|
|
|
|
XMLDocumentCB.prototype.ent = function(name, value) {
|
|
return this.entity(name, value);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.pent = function(name, value) {
|
|
return this.pEntity(name, value);
|
|
};
|
|
|
|
XMLDocumentCB.prototype.not = function(name, value) {
|
|
return this.notation(name, value);
|
|
};
|
|
|
|
return XMLDocumentCB;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./Utility":68,"./WriterState":69,"./XMLAttribute":70,"./XMLCData":71,"./XMLComment":73,"./XMLDTDAttList":78,"./XMLDTDElement":79,"./XMLDTDEntity":80,"./XMLDTDNotation":81,"./XMLDeclaration":82,"./XMLDocType":83,"./XMLDocument":84,"./XMLElement":87,"./XMLProcessingInstruction":91,"./XMLRaw":92,"./XMLStringWriter":94,"./XMLStringifier":95,"./XMLText":96}],86:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLDummy, XMLNode,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
module.exports = XMLDummy = (function(superClass) {
|
|
extend(XMLDummy, superClass);
|
|
|
|
function XMLDummy(parent) {
|
|
XMLDummy.__super__.constructor.call(this, parent);
|
|
this.type = NodeType.Dummy;
|
|
}
|
|
|
|
XMLDummy.prototype.clone = function() {
|
|
return Object.create(this);
|
|
};
|
|
|
|
XMLDummy.prototype.toString = function(options) {
|
|
return '';
|
|
};
|
|
|
|
return XMLDummy;
|
|
|
|
})(XMLNode);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./XMLNode":89}],87:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLAttribute, XMLElement, XMLNamedNodeMap, XMLNode, getValue, isFunction, isObject, ref,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
ref = require('./Utility'), isObject = ref.isObject, isFunction = ref.isFunction, getValue = ref.getValue;
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLAttribute = require('./XMLAttribute');
|
|
|
|
XMLNamedNodeMap = require('./XMLNamedNodeMap');
|
|
|
|
module.exports = XMLElement = (function(superClass) {
|
|
extend(XMLElement, superClass);
|
|
|
|
function XMLElement(parent, name, attributes) {
|
|
var child, j, len, ref1;
|
|
XMLElement.__super__.constructor.call(this, parent);
|
|
if (name == null) {
|
|
throw new Error("Missing element name. " + this.debugInfo());
|
|
}
|
|
this.name = this.stringify.name(name);
|
|
this.type = NodeType.Element;
|
|
this.attribs = {};
|
|
this.schemaTypeInfo = null;
|
|
if (attributes != null) {
|
|
this.attribute(attributes);
|
|
}
|
|
if (parent.type === NodeType.Document) {
|
|
this.isRoot = true;
|
|
this.documentObject = parent;
|
|
parent.rootObject = this;
|
|
if (parent.children) {
|
|
ref1 = parent.children;
|
|
for (j = 0, len = ref1.length; j < len; j++) {
|
|
child = ref1[j];
|
|
if (child.type === NodeType.DocType) {
|
|
child.name = this.name;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(XMLElement.prototype, 'tagName', {
|
|
get: function() {
|
|
return this.name;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLElement.prototype, 'namespaceURI', {
|
|
get: function() {
|
|
return '';
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLElement.prototype, 'prefix', {
|
|
get: function() {
|
|
return '';
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLElement.prototype, 'localName', {
|
|
get: function() {
|
|
return this.name;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLElement.prototype, 'id', {
|
|
get: function() {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLElement.prototype, 'className', {
|
|
get: function() {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLElement.prototype, 'classList', {
|
|
get: function() {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLElement.prototype, 'attributes', {
|
|
get: function() {
|
|
if (!this.attributeMap || !this.attributeMap.nodes) {
|
|
this.attributeMap = new XMLNamedNodeMap(this.attribs);
|
|
}
|
|
return this.attributeMap;
|
|
}
|
|
});
|
|
|
|
XMLElement.prototype.clone = function() {
|
|
var att, attName, clonedSelf, ref1;
|
|
clonedSelf = Object.create(this);
|
|
if (clonedSelf.isRoot) {
|
|
clonedSelf.documentObject = null;
|
|
}
|
|
clonedSelf.attribs = {};
|
|
ref1 = this.attribs;
|
|
for (attName in ref1) {
|
|
if (!hasProp.call(ref1, attName)) continue;
|
|
att = ref1[attName];
|
|
clonedSelf.attribs[attName] = att.clone();
|
|
}
|
|
clonedSelf.children = [];
|
|
this.children.forEach(function(child) {
|
|
var clonedChild;
|
|
clonedChild = child.clone();
|
|
clonedChild.parent = clonedSelf;
|
|
return clonedSelf.children.push(clonedChild);
|
|
});
|
|
return clonedSelf;
|
|
};
|
|
|
|
XMLElement.prototype.attribute = function(name, value) {
|
|
var attName, attValue;
|
|
if (name != null) {
|
|
name = getValue(name);
|
|
}
|
|
if (isObject(name)) {
|
|
for (attName in name) {
|
|
if (!hasProp.call(name, attName)) continue;
|
|
attValue = name[attName];
|
|
this.attribute(attName, attValue);
|
|
}
|
|
} else {
|
|
if (isFunction(value)) {
|
|
value = value.apply();
|
|
}
|
|
if (this.options.keepNullAttributes && (value == null)) {
|
|
this.attribs[name] = new XMLAttribute(this, name, "");
|
|
} else if (value != null) {
|
|
this.attribs[name] = new XMLAttribute(this, name, value);
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
XMLElement.prototype.removeAttribute = function(name) {
|
|
var attName, j, len;
|
|
if (name == null) {
|
|
throw new Error("Missing attribute name. " + this.debugInfo());
|
|
}
|
|
name = getValue(name);
|
|
if (Array.isArray(name)) {
|
|
for (j = 0, len = name.length; j < len; j++) {
|
|
attName = name[j];
|
|
delete this.attribs[attName];
|
|
}
|
|
} else {
|
|
delete this.attribs[name];
|
|
}
|
|
return this;
|
|
};
|
|
|
|
XMLElement.prototype.toString = function(options) {
|
|
return this.options.writer.element(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
XMLElement.prototype.att = function(name, value) {
|
|
return this.attribute(name, value);
|
|
};
|
|
|
|
XMLElement.prototype.a = function(name, value) {
|
|
return this.attribute(name, value);
|
|
};
|
|
|
|
XMLElement.prototype.getAttribute = function(name) {
|
|
if (this.attribs.hasOwnProperty(name)) {
|
|
return this.attribs[name].value;
|
|
} else {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
XMLElement.prototype.setAttribute = function(name, value) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.getAttributeNode = function(name) {
|
|
if (this.attribs.hasOwnProperty(name)) {
|
|
return this.attribs[name];
|
|
} else {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
XMLElement.prototype.setAttributeNode = function(newAttr) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.removeAttributeNode = function(oldAttr) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.getElementsByTagName = function(name) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.getAttributeNS = function(namespaceURI, localName) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.setAttributeNS = function(namespaceURI, qualifiedName, value) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.removeAttributeNS = function(namespaceURI, localName) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.getAttributeNodeNS = function(namespaceURI, localName) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.setAttributeNodeNS = function(newAttr) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.getElementsByTagNameNS = function(namespaceURI, localName) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.hasAttribute = function(name) {
|
|
return this.attribs.hasOwnProperty(name);
|
|
};
|
|
|
|
XMLElement.prototype.hasAttributeNS = function(namespaceURI, localName) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.setIdAttribute = function(name, isId) {
|
|
if (this.attribs.hasOwnProperty(name)) {
|
|
return this.attribs[name].isId;
|
|
} else {
|
|
return isId;
|
|
}
|
|
};
|
|
|
|
XMLElement.prototype.setIdAttributeNS = function(namespaceURI, localName, isId) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.setIdAttributeNode = function(idAttr, isId) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.getElementsByTagName = function(tagname) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.getElementsByTagNameNS = function(namespaceURI, localName) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.getElementsByClassName = function(classNames) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLElement.prototype.isEqualNode = function(node) {
|
|
var i, j, ref1;
|
|
if (!XMLElement.__super__.isEqualNode.apply(this, arguments).isEqualNode(node)) {
|
|
return false;
|
|
}
|
|
if (node.namespaceURI !== this.namespaceURI) {
|
|
return false;
|
|
}
|
|
if (node.prefix !== this.prefix) {
|
|
return false;
|
|
}
|
|
if (node.localName !== this.localName) {
|
|
return false;
|
|
}
|
|
if (node.attribs.length !== this.attribs.length) {
|
|
return false;
|
|
}
|
|
for (i = j = 0, ref1 = this.attribs.length - 1; 0 <= ref1 ? j <= ref1 : j >= ref1; i = 0 <= ref1 ? ++j : --j) {
|
|
if (!this.attribs[i].isEqualNode(node.attribs[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
|
|
return XMLElement;
|
|
|
|
})(XMLNode);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./Utility":68,"./XMLAttribute":70,"./XMLNamedNodeMap":88,"./XMLNode":89}],88:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var XMLNamedNodeMap;
|
|
|
|
module.exports = XMLNamedNodeMap = (function() {
|
|
function XMLNamedNodeMap(nodes) {
|
|
this.nodes = nodes;
|
|
}
|
|
|
|
Object.defineProperty(XMLNamedNodeMap.prototype, 'length', {
|
|
get: function() {
|
|
return Object.keys(this.nodes).length || 0;
|
|
}
|
|
});
|
|
|
|
XMLNamedNodeMap.prototype.clone = function() {
|
|
return this.nodes = null;
|
|
};
|
|
|
|
XMLNamedNodeMap.prototype.getNamedItem = function(name) {
|
|
return this.nodes[name];
|
|
};
|
|
|
|
XMLNamedNodeMap.prototype.setNamedItem = function(node) {
|
|
var oldNode;
|
|
oldNode = this.nodes[node.nodeName];
|
|
this.nodes[node.nodeName] = node;
|
|
return oldNode || null;
|
|
};
|
|
|
|
XMLNamedNodeMap.prototype.removeNamedItem = function(name) {
|
|
var oldNode;
|
|
oldNode = this.nodes[name];
|
|
delete this.nodes[name];
|
|
return oldNode || null;
|
|
};
|
|
|
|
XMLNamedNodeMap.prototype.item = function(index) {
|
|
return this.nodes[Object.keys(this.nodes)[index]] || null;
|
|
};
|
|
|
|
XMLNamedNodeMap.prototype.getNamedItemNS = function(namespaceURI, localName) {
|
|
throw new Error("This DOM method is not implemented.");
|
|
};
|
|
|
|
XMLNamedNodeMap.prototype.setNamedItemNS = function(node) {
|
|
throw new Error("This DOM method is not implemented.");
|
|
};
|
|
|
|
XMLNamedNodeMap.prototype.removeNamedItemNS = function(namespaceURI, localName) {
|
|
throw new Error("This DOM method is not implemented.");
|
|
};
|
|
|
|
return XMLNamedNodeMap;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{}],89:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var DocumentPosition, NodeType, XMLCData, XMLComment, XMLDeclaration, XMLDocType, XMLDummy, XMLElement, XMLNamedNodeMap, XMLNode, XMLNodeList, XMLProcessingInstruction, XMLRaw, XMLText, getValue, isEmpty, isFunction, isObject, ref1,
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
ref1 = require('./Utility'), isObject = ref1.isObject, isFunction = ref1.isFunction, isEmpty = ref1.isEmpty, getValue = ref1.getValue;
|
|
|
|
XMLElement = null;
|
|
|
|
XMLCData = null;
|
|
|
|
XMLComment = null;
|
|
|
|
XMLDeclaration = null;
|
|
|
|
XMLDocType = null;
|
|
|
|
XMLRaw = null;
|
|
|
|
XMLText = null;
|
|
|
|
XMLProcessingInstruction = null;
|
|
|
|
XMLDummy = null;
|
|
|
|
NodeType = null;
|
|
|
|
XMLNodeList = null;
|
|
|
|
XMLNamedNodeMap = null;
|
|
|
|
DocumentPosition = null;
|
|
|
|
module.exports = XMLNode = (function() {
|
|
function XMLNode(parent1) {
|
|
this.parent = parent1;
|
|
if (this.parent) {
|
|
this.options = this.parent.options;
|
|
this.stringify = this.parent.stringify;
|
|
}
|
|
this.value = null;
|
|
this.children = [];
|
|
this.baseURI = null;
|
|
if (!XMLElement) {
|
|
XMLElement = require('./XMLElement');
|
|
XMLCData = require('./XMLCData');
|
|
XMLComment = require('./XMLComment');
|
|
XMLDeclaration = require('./XMLDeclaration');
|
|
XMLDocType = require('./XMLDocType');
|
|
XMLRaw = require('./XMLRaw');
|
|
XMLText = require('./XMLText');
|
|
XMLProcessingInstruction = require('./XMLProcessingInstruction');
|
|
XMLDummy = require('./XMLDummy');
|
|
NodeType = require('./NodeType');
|
|
XMLNodeList = require('./XMLNodeList');
|
|
XMLNamedNodeMap = require('./XMLNamedNodeMap');
|
|
DocumentPosition = require('./DocumentPosition');
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(XMLNode.prototype, 'nodeName', {
|
|
get: function() {
|
|
return this.name;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLNode.prototype, 'nodeType', {
|
|
get: function() {
|
|
return this.type;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLNode.prototype, 'nodeValue', {
|
|
get: function() {
|
|
return this.value;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLNode.prototype, 'parentNode', {
|
|
get: function() {
|
|
return this.parent;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLNode.prototype, 'childNodes', {
|
|
get: function() {
|
|
if (!this.childNodeList || !this.childNodeList.nodes) {
|
|
this.childNodeList = new XMLNodeList(this.children);
|
|
}
|
|
return this.childNodeList;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLNode.prototype, 'firstChild', {
|
|
get: function() {
|
|
return this.children[0] || null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLNode.prototype, 'lastChild', {
|
|
get: function() {
|
|
return this.children[this.children.length - 1] || null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLNode.prototype, 'previousSibling', {
|
|
get: function() {
|
|
var i;
|
|
i = this.parent.children.indexOf(this);
|
|
return this.parent.children[i - 1] || null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLNode.prototype, 'nextSibling', {
|
|
get: function() {
|
|
var i;
|
|
i = this.parent.children.indexOf(this);
|
|
return this.parent.children[i + 1] || null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLNode.prototype, 'ownerDocument', {
|
|
get: function() {
|
|
return this.document() || null;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLNode.prototype, 'textContent', {
|
|
get: function() {
|
|
var child, j, len, ref2, str;
|
|
if (this.nodeType === NodeType.Element || this.nodeType === NodeType.DocumentFragment) {
|
|
str = '';
|
|
ref2 = this.children;
|
|
for (j = 0, len = ref2.length; j < len; j++) {
|
|
child = ref2[j];
|
|
if (child.textContent) {
|
|
str += child.textContent;
|
|
}
|
|
}
|
|
return str;
|
|
} else {
|
|
return null;
|
|
}
|
|
},
|
|
set: function(value) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
}
|
|
});
|
|
|
|
XMLNode.prototype.setParent = function(parent) {
|
|
var child, j, len, ref2, results;
|
|
this.parent = parent;
|
|
if (parent) {
|
|
this.options = parent.options;
|
|
this.stringify = parent.stringify;
|
|
}
|
|
ref2 = this.children;
|
|
results = [];
|
|
for (j = 0, len = ref2.length; j < len; j++) {
|
|
child = ref2[j];
|
|
results.push(child.setParent(this));
|
|
}
|
|
return results;
|
|
};
|
|
|
|
XMLNode.prototype.element = function(name, attributes, text) {
|
|
var childNode, item, j, k, key, lastChild, len, len1, ref2, ref3, val;
|
|
lastChild = null;
|
|
if (attributes === null && (text == null)) {
|
|
ref2 = [{}, null], attributes = ref2[0], text = ref2[1];
|
|
}
|
|
if (attributes == null) {
|
|
attributes = {};
|
|
}
|
|
attributes = getValue(attributes);
|
|
if (!isObject(attributes)) {
|
|
ref3 = [attributes, text], text = ref3[0], attributes = ref3[1];
|
|
}
|
|
if (name != null) {
|
|
name = getValue(name);
|
|
}
|
|
if (Array.isArray(name)) {
|
|
for (j = 0, len = name.length; j < len; j++) {
|
|
item = name[j];
|
|
lastChild = this.element(item);
|
|
}
|
|
} else if (isFunction(name)) {
|
|
lastChild = this.element(name.apply());
|
|
} else if (isObject(name)) {
|
|
for (key in name) {
|
|
if (!hasProp.call(name, key)) continue;
|
|
val = name[key];
|
|
if (isFunction(val)) {
|
|
val = val.apply();
|
|
}
|
|
if (!this.options.ignoreDecorators && this.stringify.convertAttKey && key.indexOf(this.stringify.convertAttKey) === 0) {
|
|
lastChild = this.attribute(key.substr(this.stringify.convertAttKey.length), val);
|
|
} else if (!this.options.separateArrayItems && Array.isArray(val) && isEmpty(val)) {
|
|
lastChild = this.dummy();
|
|
} else if (isObject(val) && isEmpty(val)) {
|
|
lastChild = this.element(key);
|
|
} else if (!this.options.keepNullNodes && (val == null)) {
|
|
lastChild = this.dummy();
|
|
} else if (!this.options.separateArrayItems && Array.isArray(val)) {
|
|
for (k = 0, len1 = val.length; k < len1; k++) {
|
|
item = val[k];
|
|
childNode = {};
|
|
childNode[key] = item;
|
|
lastChild = this.element(childNode);
|
|
}
|
|
} else if (isObject(val)) {
|
|
if (!this.options.ignoreDecorators && this.stringify.convertTextKey && key.indexOf(this.stringify.convertTextKey) === 0) {
|
|
lastChild = this.element(val);
|
|
} else {
|
|
lastChild = this.element(key);
|
|
lastChild.element(val);
|
|
}
|
|
} else {
|
|
lastChild = this.element(key, val);
|
|
}
|
|
}
|
|
} else if (!this.options.keepNullNodes && text === null) {
|
|
lastChild = this.dummy();
|
|
} else {
|
|
if (!this.options.ignoreDecorators && this.stringify.convertTextKey && name.indexOf(this.stringify.convertTextKey) === 0) {
|
|
lastChild = this.text(text);
|
|
} else if (!this.options.ignoreDecorators && this.stringify.convertCDataKey && name.indexOf(this.stringify.convertCDataKey) === 0) {
|
|
lastChild = this.cdata(text);
|
|
} else if (!this.options.ignoreDecorators && this.stringify.convertCommentKey && name.indexOf(this.stringify.convertCommentKey) === 0) {
|
|
lastChild = this.comment(text);
|
|
} else if (!this.options.ignoreDecorators && this.stringify.convertRawKey && name.indexOf(this.stringify.convertRawKey) === 0) {
|
|
lastChild = this.raw(text);
|
|
} else if (!this.options.ignoreDecorators && this.stringify.convertPIKey && name.indexOf(this.stringify.convertPIKey) === 0) {
|
|
lastChild = this.instruction(name.substr(this.stringify.convertPIKey.length), text);
|
|
} else {
|
|
lastChild = this.node(name, attributes, text);
|
|
}
|
|
}
|
|
if (lastChild == null) {
|
|
throw new Error("Could not create any elements with: " + name + ". " + this.debugInfo());
|
|
}
|
|
return lastChild;
|
|
};
|
|
|
|
XMLNode.prototype.insertBefore = function(name, attributes, text) {
|
|
var child, i, newChild, refChild, removed;
|
|
if (name != null ? name.type : void 0) {
|
|
newChild = name;
|
|
refChild = attributes;
|
|
newChild.setParent(this);
|
|
if (refChild) {
|
|
i = children.indexOf(refChild);
|
|
removed = children.splice(i);
|
|
children.push(newChild);
|
|
Array.prototype.push.apply(children, removed);
|
|
} else {
|
|
children.push(newChild);
|
|
}
|
|
return newChild;
|
|
} else {
|
|
if (this.isRoot) {
|
|
throw new Error("Cannot insert elements at root level. " + this.debugInfo(name));
|
|
}
|
|
i = this.parent.children.indexOf(this);
|
|
removed = this.parent.children.splice(i);
|
|
child = this.parent.element(name, attributes, text);
|
|
Array.prototype.push.apply(this.parent.children, removed);
|
|
return child;
|
|
}
|
|
};
|
|
|
|
XMLNode.prototype.insertAfter = function(name, attributes, text) {
|
|
var child, i, removed;
|
|
if (this.isRoot) {
|
|
throw new Error("Cannot insert elements at root level. " + this.debugInfo(name));
|
|
}
|
|
i = this.parent.children.indexOf(this);
|
|
removed = this.parent.children.splice(i + 1);
|
|
child = this.parent.element(name, attributes, text);
|
|
Array.prototype.push.apply(this.parent.children, removed);
|
|
return child;
|
|
};
|
|
|
|
XMLNode.prototype.remove = function() {
|
|
var i, ref2;
|
|
if (this.isRoot) {
|
|
throw new Error("Cannot remove the root element. " + this.debugInfo());
|
|
}
|
|
i = this.parent.children.indexOf(this);
|
|
[].splice.apply(this.parent.children, [i, i - i + 1].concat(ref2 = [])), ref2;
|
|
return this.parent;
|
|
};
|
|
|
|
XMLNode.prototype.node = function(name, attributes, text) {
|
|
var child, ref2;
|
|
if (name != null) {
|
|
name = getValue(name);
|
|
}
|
|
attributes || (attributes = {});
|
|
attributes = getValue(attributes);
|
|
if (!isObject(attributes)) {
|
|
ref2 = [attributes, text], text = ref2[0], attributes = ref2[1];
|
|
}
|
|
child = new XMLElement(this, name, attributes);
|
|
if (text != null) {
|
|
child.text(text);
|
|
}
|
|
this.children.push(child);
|
|
return child;
|
|
};
|
|
|
|
XMLNode.prototype.text = function(value) {
|
|
var child;
|
|
if (isObject(value)) {
|
|
this.element(value);
|
|
}
|
|
child = new XMLText(this, value);
|
|
this.children.push(child);
|
|
return this;
|
|
};
|
|
|
|
XMLNode.prototype.cdata = function(value) {
|
|
var child;
|
|
child = new XMLCData(this, value);
|
|
this.children.push(child);
|
|
return this;
|
|
};
|
|
|
|
XMLNode.prototype.comment = function(value) {
|
|
var child;
|
|
child = new XMLComment(this, value);
|
|
this.children.push(child);
|
|
return this;
|
|
};
|
|
|
|
XMLNode.prototype.commentBefore = function(value) {
|
|
var child, i, removed;
|
|
i = this.parent.children.indexOf(this);
|
|
removed = this.parent.children.splice(i);
|
|
child = this.parent.comment(value);
|
|
Array.prototype.push.apply(this.parent.children, removed);
|
|
return this;
|
|
};
|
|
|
|
XMLNode.prototype.commentAfter = function(value) {
|
|
var child, i, removed;
|
|
i = this.parent.children.indexOf(this);
|
|
removed = this.parent.children.splice(i + 1);
|
|
child = this.parent.comment(value);
|
|
Array.prototype.push.apply(this.parent.children, removed);
|
|
return this;
|
|
};
|
|
|
|
XMLNode.prototype.raw = function(value) {
|
|
var child;
|
|
child = new XMLRaw(this, value);
|
|
this.children.push(child);
|
|
return this;
|
|
};
|
|
|
|
XMLNode.prototype.dummy = function() {
|
|
var child;
|
|
child = new XMLDummy(this);
|
|
return child;
|
|
};
|
|
|
|
XMLNode.prototype.instruction = function(target, value) {
|
|
var insTarget, insValue, instruction, j, len;
|
|
if (target != null) {
|
|
target = getValue(target);
|
|
}
|
|
if (value != null) {
|
|
value = getValue(value);
|
|
}
|
|
if (Array.isArray(target)) {
|
|
for (j = 0, len = target.length; j < len; j++) {
|
|
insTarget = target[j];
|
|
this.instruction(insTarget);
|
|
}
|
|
} else if (isObject(target)) {
|
|
for (insTarget in target) {
|
|
if (!hasProp.call(target, insTarget)) continue;
|
|
insValue = target[insTarget];
|
|
this.instruction(insTarget, insValue);
|
|
}
|
|
} else {
|
|
if (isFunction(value)) {
|
|
value = value.apply();
|
|
}
|
|
instruction = new XMLProcessingInstruction(this, target, value);
|
|
this.children.push(instruction);
|
|
}
|
|
return this;
|
|
};
|
|
|
|
XMLNode.prototype.instructionBefore = function(target, value) {
|
|
var child, i, removed;
|
|
i = this.parent.children.indexOf(this);
|
|
removed = this.parent.children.splice(i);
|
|
child = this.parent.instruction(target, value);
|
|
Array.prototype.push.apply(this.parent.children, removed);
|
|
return this;
|
|
};
|
|
|
|
XMLNode.prototype.instructionAfter = function(target, value) {
|
|
var child, i, removed;
|
|
i = this.parent.children.indexOf(this);
|
|
removed = this.parent.children.splice(i + 1);
|
|
child = this.parent.instruction(target, value);
|
|
Array.prototype.push.apply(this.parent.children, removed);
|
|
return this;
|
|
};
|
|
|
|
XMLNode.prototype.declaration = function(version, encoding, standalone) {
|
|
var doc, xmldec;
|
|
doc = this.document();
|
|
xmldec = new XMLDeclaration(doc, version, encoding, standalone);
|
|
if (doc.children.length === 0) {
|
|
doc.children.unshift(xmldec);
|
|
} else if (doc.children[0].type === NodeType.Declaration) {
|
|
doc.children[0] = xmldec;
|
|
} else {
|
|
doc.children.unshift(xmldec);
|
|
}
|
|
return doc.root() || doc;
|
|
};
|
|
|
|
XMLNode.prototype.dtd = function(pubID, sysID) {
|
|
var child, doc, doctype, i, j, k, len, len1, ref2, ref3;
|
|
doc = this.document();
|
|
doctype = new XMLDocType(doc, pubID, sysID);
|
|
ref2 = doc.children;
|
|
for (i = j = 0, len = ref2.length; j < len; i = ++j) {
|
|
child = ref2[i];
|
|
if (child.type === NodeType.DocType) {
|
|
doc.children[i] = doctype;
|
|
return doctype;
|
|
}
|
|
}
|
|
ref3 = doc.children;
|
|
for (i = k = 0, len1 = ref3.length; k < len1; i = ++k) {
|
|
child = ref3[i];
|
|
if (child.isRoot) {
|
|
doc.children.splice(i, 0, doctype);
|
|
return doctype;
|
|
}
|
|
}
|
|
doc.children.push(doctype);
|
|
return doctype;
|
|
};
|
|
|
|
XMLNode.prototype.up = function() {
|
|
if (this.isRoot) {
|
|
throw new Error("The root node has no parent. Use doc() if you need to get the document object.");
|
|
}
|
|
return this.parent;
|
|
};
|
|
|
|
XMLNode.prototype.root = function() {
|
|
var node;
|
|
node = this;
|
|
while (node) {
|
|
if (node.type === NodeType.Document) {
|
|
return node.rootObject;
|
|
} else if (node.isRoot) {
|
|
return node;
|
|
} else {
|
|
node = node.parent;
|
|
}
|
|
}
|
|
};
|
|
|
|
XMLNode.prototype.document = function() {
|
|
var node;
|
|
node = this;
|
|
while (node) {
|
|
if (node.type === NodeType.Document) {
|
|
return node;
|
|
} else {
|
|
node = node.parent;
|
|
}
|
|
}
|
|
};
|
|
|
|
XMLNode.prototype.end = function(options) {
|
|
return this.document().end(options);
|
|
};
|
|
|
|
XMLNode.prototype.prev = function() {
|
|
var i;
|
|
i = this.parent.children.indexOf(this);
|
|
if (i < 1) {
|
|
throw new Error("Already at the first node. " + this.debugInfo());
|
|
}
|
|
return this.parent.children[i - 1];
|
|
};
|
|
|
|
XMLNode.prototype.next = function() {
|
|
var i;
|
|
i = this.parent.children.indexOf(this);
|
|
if (i === -1 || i === this.parent.children.length - 1) {
|
|
throw new Error("Already at the last node. " + this.debugInfo());
|
|
}
|
|
return this.parent.children[i + 1];
|
|
};
|
|
|
|
XMLNode.prototype.importDocument = function(doc) {
|
|
var clonedRoot;
|
|
clonedRoot = doc.root().clone();
|
|
clonedRoot.parent = this;
|
|
clonedRoot.isRoot = false;
|
|
this.children.push(clonedRoot);
|
|
return this;
|
|
};
|
|
|
|
XMLNode.prototype.debugInfo = function(name) {
|
|
var ref2, ref3;
|
|
name = name || this.name;
|
|
if ((name == null) && !((ref2 = this.parent) != null ? ref2.name : void 0)) {
|
|
return "";
|
|
} else if (name == null) {
|
|
return "parent: <" + this.parent.name + ">";
|
|
} else if (!((ref3 = this.parent) != null ? ref3.name : void 0)) {
|
|
return "node: <" + name + ">";
|
|
} else {
|
|
return "node: <" + name + ">, parent: <" + this.parent.name + ">";
|
|
}
|
|
};
|
|
|
|
XMLNode.prototype.ele = function(name, attributes, text) {
|
|
return this.element(name, attributes, text);
|
|
};
|
|
|
|
XMLNode.prototype.nod = function(name, attributes, text) {
|
|
return this.node(name, attributes, text);
|
|
};
|
|
|
|
XMLNode.prototype.txt = function(value) {
|
|
return this.text(value);
|
|
};
|
|
|
|
XMLNode.prototype.dat = function(value) {
|
|
return this.cdata(value);
|
|
};
|
|
|
|
XMLNode.prototype.com = function(value) {
|
|
return this.comment(value);
|
|
};
|
|
|
|
XMLNode.prototype.ins = function(target, value) {
|
|
return this.instruction(target, value);
|
|
};
|
|
|
|
XMLNode.prototype.doc = function() {
|
|
return this.document();
|
|
};
|
|
|
|
XMLNode.prototype.dec = function(version, encoding, standalone) {
|
|
return this.declaration(version, encoding, standalone);
|
|
};
|
|
|
|
XMLNode.prototype.e = function(name, attributes, text) {
|
|
return this.element(name, attributes, text);
|
|
};
|
|
|
|
XMLNode.prototype.n = function(name, attributes, text) {
|
|
return this.node(name, attributes, text);
|
|
};
|
|
|
|
XMLNode.prototype.t = function(value) {
|
|
return this.text(value);
|
|
};
|
|
|
|
XMLNode.prototype.d = function(value) {
|
|
return this.cdata(value);
|
|
};
|
|
|
|
XMLNode.prototype.c = function(value) {
|
|
return this.comment(value);
|
|
};
|
|
|
|
XMLNode.prototype.r = function(value) {
|
|
return this.raw(value);
|
|
};
|
|
|
|
XMLNode.prototype.i = function(target, value) {
|
|
return this.instruction(target, value);
|
|
};
|
|
|
|
XMLNode.prototype.u = function() {
|
|
return this.up();
|
|
};
|
|
|
|
XMLNode.prototype.importXMLBuilder = function(doc) {
|
|
return this.importDocument(doc);
|
|
};
|
|
|
|
XMLNode.prototype.replaceChild = function(newChild, oldChild) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.removeChild = function(oldChild) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.appendChild = function(newChild) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.hasChildNodes = function() {
|
|
return this.children.length !== 0;
|
|
};
|
|
|
|
XMLNode.prototype.cloneNode = function(deep) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.normalize = function() {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.isSupported = function(feature, version) {
|
|
return true;
|
|
};
|
|
|
|
XMLNode.prototype.hasAttributes = function() {
|
|
return this.attribs.length !== 0;
|
|
};
|
|
|
|
XMLNode.prototype.compareDocumentPosition = function(other) {
|
|
var ref, res;
|
|
ref = this;
|
|
if (ref === other) {
|
|
return 0;
|
|
} else if (this.document() !== other.document()) {
|
|
res = DocumentPosition.Disconnected | DocumentPosition.ImplementationSpecific;
|
|
if (Math.random() < 0.5) {
|
|
res |= DocumentPosition.Preceding;
|
|
} else {
|
|
res |= DocumentPosition.Following;
|
|
}
|
|
return res;
|
|
} else if (ref.isAncestor(other)) {
|
|
return DocumentPosition.Contains | DocumentPosition.Preceding;
|
|
} else if (ref.isDescendant(other)) {
|
|
return DocumentPosition.Contains | DocumentPosition.Following;
|
|
} else if (ref.isPreceding(other)) {
|
|
return DocumentPosition.Preceding;
|
|
} else {
|
|
return DocumentPosition.Following;
|
|
}
|
|
};
|
|
|
|
XMLNode.prototype.isSameNode = function(other) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.lookupPrefix = function(namespaceURI) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.isDefaultNamespace = function(namespaceURI) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.lookupNamespaceURI = function(prefix) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.isEqualNode = function(node) {
|
|
var i, j, ref2;
|
|
if (node.nodeType !== this.nodeType) {
|
|
return false;
|
|
}
|
|
if (node.children.length !== this.children.length) {
|
|
return false;
|
|
}
|
|
for (i = j = 0, ref2 = this.children.length - 1; 0 <= ref2 ? j <= ref2 : j >= ref2; i = 0 <= ref2 ? ++j : --j) {
|
|
if (!this.children[i].isEqualNode(node.children[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
|
|
XMLNode.prototype.getFeature = function(feature, version) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.setUserData = function(key, data, handler) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.getUserData = function(key) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLNode.prototype.contains = function(other) {
|
|
if (!other) {
|
|
return false;
|
|
}
|
|
return other === this || this.isDescendant(other);
|
|
};
|
|
|
|
XMLNode.prototype.isDescendant = function(node) {
|
|
var child, isDescendantChild, j, len, ref2;
|
|
ref2 = this.children;
|
|
for (j = 0, len = ref2.length; j < len; j++) {
|
|
child = ref2[j];
|
|
if (node === child) {
|
|
return true;
|
|
}
|
|
isDescendantChild = child.isDescendant(node);
|
|
if (isDescendantChild) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
XMLNode.prototype.isAncestor = function(node) {
|
|
return node.isDescendant(this);
|
|
};
|
|
|
|
XMLNode.prototype.isPreceding = function(node) {
|
|
var nodePos, thisPos;
|
|
nodePos = this.treePosition(node);
|
|
thisPos = this.treePosition(this);
|
|
if (nodePos === -1 || thisPos === -1) {
|
|
return false;
|
|
} else {
|
|
return nodePos < thisPos;
|
|
}
|
|
};
|
|
|
|
XMLNode.prototype.isFollowing = function(node) {
|
|
var nodePos, thisPos;
|
|
nodePos = this.treePosition(node);
|
|
thisPos = this.treePosition(this);
|
|
if (nodePos === -1 || thisPos === -1) {
|
|
return false;
|
|
} else {
|
|
return nodePos > thisPos;
|
|
}
|
|
};
|
|
|
|
XMLNode.prototype.treePosition = function(node) {
|
|
var found, pos;
|
|
pos = 0;
|
|
found = false;
|
|
this.foreachTreeNode(this.document(), function(childNode) {
|
|
pos++;
|
|
if (!found && childNode === node) {
|
|
return found = true;
|
|
}
|
|
});
|
|
if (found) {
|
|
return pos;
|
|
} else {
|
|
return -1;
|
|
}
|
|
};
|
|
|
|
XMLNode.prototype.foreachTreeNode = function(node, func) {
|
|
var child, j, len, ref2, res;
|
|
node || (node = this.document());
|
|
ref2 = node.children;
|
|
for (j = 0, len = ref2.length; j < len; j++) {
|
|
child = ref2[j];
|
|
if (res = func(child)) {
|
|
return res;
|
|
} else {
|
|
res = this.foreachTreeNode(child, func);
|
|
if (res) {
|
|
return res;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
return XMLNode;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{"./DocumentPosition":66,"./NodeType":67,"./Utility":68,"./XMLCData":71,"./XMLComment":73,"./XMLDeclaration":82,"./XMLDocType":83,"./XMLDummy":86,"./XMLElement":87,"./XMLNamedNodeMap":88,"./XMLNodeList":90,"./XMLProcessingInstruction":91,"./XMLRaw":92,"./XMLText":96}],90:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var XMLNodeList;
|
|
|
|
module.exports = XMLNodeList = (function() {
|
|
function XMLNodeList(nodes) {
|
|
this.nodes = nodes;
|
|
}
|
|
|
|
Object.defineProperty(XMLNodeList.prototype, 'length', {
|
|
get: function() {
|
|
return this.nodes.length || 0;
|
|
}
|
|
});
|
|
|
|
XMLNodeList.prototype.clone = function() {
|
|
return this.nodes = null;
|
|
};
|
|
|
|
XMLNodeList.prototype.item = function(index) {
|
|
return this.nodes[index] || null;
|
|
};
|
|
|
|
return XMLNodeList;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{}],91:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLCharacterData, XMLProcessingInstruction,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLCharacterData = require('./XMLCharacterData');
|
|
|
|
module.exports = XMLProcessingInstruction = (function(superClass) {
|
|
extend(XMLProcessingInstruction, superClass);
|
|
|
|
function XMLProcessingInstruction(parent, target, value) {
|
|
XMLProcessingInstruction.__super__.constructor.call(this, parent);
|
|
if (target == null) {
|
|
throw new Error("Missing instruction target. " + this.debugInfo());
|
|
}
|
|
this.type = NodeType.ProcessingInstruction;
|
|
this.target = this.stringify.insTarget(target);
|
|
this.name = this.target;
|
|
if (value) {
|
|
this.value = this.stringify.insValue(value);
|
|
}
|
|
}
|
|
|
|
XMLProcessingInstruction.prototype.clone = function() {
|
|
return Object.create(this);
|
|
};
|
|
|
|
XMLProcessingInstruction.prototype.toString = function(options) {
|
|
return this.options.writer.processingInstruction(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
XMLProcessingInstruction.prototype.isEqualNode = function(node) {
|
|
if (!XMLProcessingInstruction.__super__.isEqualNode.apply(this, arguments).isEqualNode(node)) {
|
|
return false;
|
|
}
|
|
if (node.target !== this.target) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
return XMLProcessingInstruction;
|
|
|
|
})(XMLCharacterData);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./XMLCharacterData":72}],92:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLNode, XMLRaw,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLNode = require('./XMLNode');
|
|
|
|
module.exports = XMLRaw = (function(superClass) {
|
|
extend(XMLRaw, superClass);
|
|
|
|
function XMLRaw(parent, text) {
|
|
XMLRaw.__super__.constructor.call(this, parent);
|
|
if (text == null) {
|
|
throw new Error("Missing raw text. " + this.debugInfo());
|
|
}
|
|
this.type = NodeType.Raw;
|
|
this.value = this.stringify.raw(text);
|
|
}
|
|
|
|
XMLRaw.prototype.clone = function() {
|
|
return Object.create(this);
|
|
};
|
|
|
|
XMLRaw.prototype.toString = function(options) {
|
|
return this.options.writer.raw(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
return XMLRaw;
|
|
|
|
})(XMLNode);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./XMLNode":89}],93:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, WriterState, XMLStreamWriter, XMLWriterBase,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLWriterBase = require('./XMLWriterBase');
|
|
|
|
WriterState = require('./WriterState');
|
|
|
|
module.exports = XMLStreamWriter = (function(superClass) {
|
|
extend(XMLStreamWriter, superClass);
|
|
|
|
function XMLStreamWriter(stream, options) {
|
|
this.stream = stream;
|
|
XMLStreamWriter.__super__.constructor.call(this, options);
|
|
}
|
|
|
|
XMLStreamWriter.prototype.endline = function(node, options, level) {
|
|
if (node.isLastRootNode && options.state === WriterState.CloseTag) {
|
|
return '';
|
|
} else {
|
|
return XMLStreamWriter.__super__.endline.call(this, node, options, level);
|
|
}
|
|
};
|
|
|
|
XMLStreamWriter.prototype.document = function(doc, options) {
|
|
var child, i, j, k, len, len1, ref, ref1, results;
|
|
ref = doc.children;
|
|
for (i = j = 0, len = ref.length; j < len; i = ++j) {
|
|
child = ref[i];
|
|
child.isLastRootNode = i === doc.children.length - 1;
|
|
}
|
|
options = this.filterOptions(options);
|
|
ref1 = doc.children;
|
|
results = [];
|
|
for (k = 0, len1 = ref1.length; k < len1; k++) {
|
|
child = ref1[k];
|
|
results.push(this.writeChildNode(child, options, 0));
|
|
}
|
|
return results;
|
|
};
|
|
|
|
XMLStreamWriter.prototype.attribute = function(att, options, level) {
|
|
return this.stream.write(XMLStreamWriter.__super__.attribute.call(this, att, options, level));
|
|
};
|
|
|
|
XMLStreamWriter.prototype.cdata = function(node, options, level) {
|
|
return this.stream.write(XMLStreamWriter.__super__.cdata.call(this, node, options, level));
|
|
};
|
|
|
|
XMLStreamWriter.prototype.comment = function(node, options, level) {
|
|
return this.stream.write(XMLStreamWriter.__super__.comment.call(this, node, options, level));
|
|
};
|
|
|
|
XMLStreamWriter.prototype.declaration = function(node, options, level) {
|
|
return this.stream.write(XMLStreamWriter.__super__.declaration.call(this, node, options, level));
|
|
};
|
|
|
|
XMLStreamWriter.prototype.docType = function(node, options, level) {
|
|
var child, j, len, ref;
|
|
level || (level = 0);
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
this.stream.write(this.indent(node, options, level));
|
|
this.stream.write('<!DOCTYPE ' + node.root().name);
|
|
if (node.pubID && node.sysID) {
|
|
this.stream.write(' PUBLIC "' + node.pubID + '" "' + node.sysID + '"');
|
|
} else if (node.sysID) {
|
|
this.stream.write(' SYSTEM "' + node.sysID + '"');
|
|
}
|
|
if (node.children.length > 0) {
|
|
this.stream.write(' [');
|
|
this.stream.write(this.endline(node, options, level));
|
|
options.state = WriterState.InsideTag;
|
|
ref = node.children;
|
|
for (j = 0, len = ref.length; j < len; j++) {
|
|
child = ref[j];
|
|
this.writeChildNode(child, options, level + 1);
|
|
}
|
|
options.state = WriterState.CloseTag;
|
|
this.stream.write(']');
|
|
}
|
|
options.state = WriterState.CloseTag;
|
|
this.stream.write(options.spaceBeforeSlash + '>');
|
|
this.stream.write(this.endline(node, options, level));
|
|
options.state = WriterState.None;
|
|
return this.closeNode(node, options, level);
|
|
};
|
|
|
|
XMLStreamWriter.prototype.element = function(node, options, level) {
|
|
var att, child, childNodeCount, firstChildNode, j, len, name, prettySuppressed, ref, ref1;
|
|
level || (level = 0);
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
this.stream.write(this.indent(node, options, level) + '<' + node.name);
|
|
ref = node.attribs;
|
|
for (name in ref) {
|
|
if (!hasProp.call(ref, name)) continue;
|
|
att = ref[name];
|
|
this.attribute(att, options, level);
|
|
}
|
|
childNodeCount = node.children.length;
|
|
firstChildNode = childNodeCount === 0 ? null : node.children[0];
|
|
if (childNodeCount === 0 || node.children.every(function(e) {
|
|
return (e.type === NodeType.Text || e.type === NodeType.Raw) && e.value === '';
|
|
})) {
|
|
if (options.allowEmpty) {
|
|
this.stream.write('>');
|
|
options.state = WriterState.CloseTag;
|
|
this.stream.write('</' + node.name + '>');
|
|
} else {
|
|
options.state = WriterState.CloseTag;
|
|
this.stream.write(options.spaceBeforeSlash + '/>');
|
|
}
|
|
} else if (options.pretty && childNodeCount === 1 && (firstChildNode.type === NodeType.Text || firstChildNode.type === NodeType.Raw) && (firstChildNode.value != null)) {
|
|
this.stream.write('>');
|
|
options.state = WriterState.InsideTag;
|
|
options.suppressPrettyCount++;
|
|
prettySuppressed = true;
|
|
this.writeChildNode(firstChildNode, options, level + 1);
|
|
options.suppressPrettyCount--;
|
|
prettySuppressed = false;
|
|
options.state = WriterState.CloseTag;
|
|
this.stream.write('</' + node.name + '>');
|
|
} else {
|
|
this.stream.write('>' + this.endline(node, options, level));
|
|
options.state = WriterState.InsideTag;
|
|
ref1 = node.children;
|
|
for (j = 0, len = ref1.length; j < len; j++) {
|
|
child = ref1[j];
|
|
this.writeChildNode(child, options, level + 1);
|
|
}
|
|
options.state = WriterState.CloseTag;
|
|
this.stream.write(this.indent(node, options, level) + '</' + node.name + '>');
|
|
}
|
|
this.stream.write(this.endline(node, options, level));
|
|
options.state = WriterState.None;
|
|
return this.closeNode(node, options, level);
|
|
};
|
|
|
|
XMLStreamWriter.prototype.processingInstruction = function(node, options, level) {
|
|
return this.stream.write(XMLStreamWriter.__super__.processingInstruction.call(this, node, options, level));
|
|
};
|
|
|
|
XMLStreamWriter.prototype.raw = function(node, options, level) {
|
|
return this.stream.write(XMLStreamWriter.__super__.raw.call(this, node, options, level));
|
|
};
|
|
|
|
XMLStreamWriter.prototype.text = function(node, options, level) {
|
|
return this.stream.write(XMLStreamWriter.__super__.text.call(this, node, options, level));
|
|
};
|
|
|
|
XMLStreamWriter.prototype.dtdAttList = function(node, options, level) {
|
|
return this.stream.write(XMLStreamWriter.__super__.dtdAttList.call(this, node, options, level));
|
|
};
|
|
|
|
XMLStreamWriter.prototype.dtdElement = function(node, options, level) {
|
|
return this.stream.write(XMLStreamWriter.__super__.dtdElement.call(this, node, options, level));
|
|
};
|
|
|
|
XMLStreamWriter.prototype.dtdEntity = function(node, options, level) {
|
|
return this.stream.write(XMLStreamWriter.__super__.dtdEntity.call(this, node, options, level));
|
|
};
|
|
|
|
XMLStreamWriter.prototype.dtdNotation = function(node, options, level) {
|
|
return this.stream.write(XMLStreamWriter.__super__.dtdNotation.call(this, node, options, level));
|
|
};
|
|
|
|
return XMLStreamWriter;
|
|
|
|
})(XMLWriterBase);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./WriterState":69,"./XMLWriterBase":97}],94:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var XMLStringWriter, XMLWriterBase,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
XMLWriterBase = require('./XMLWriterBase');
|
|
|
|
module.exports = XMLStringWriter = (function(superClass) {
|
|
extend(XMLStringWriter, superClass);
|
|
|
|
function XMLStringWriter(options) {
|
|
XMLStringWriter.__super__.constructor.call(this, options);
|
|
}
|
|
|
|
XMLStringWriter.prototype.document = function(doc, options) {
|
|
var child, i, len, r, ref;
|
|
options = this.filterOptions(options);
|
|
r = '';
|
|
ref = doc.children;
|
|
for (i = 0, len = ref.length; i < len; i++) {
|
|
child = ref[i];
|
|
r += this.writeChildNode(child, options, 0);
|
|
}
|
|
if (options.pretty && r.slice(-options.newline.length) === options.newline) {
|
|
r = r.slice(0, -options.newline.length);
|
|
}
|
|
return r;
|
|
};
|
|
|
|
return XMLStringWriter;
|
|
|
|
})(XMLWriterBase);
|
|
|
|
}).call(this);
|
|
|
|
},{"./XMLWriterBase":97}],95:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var XMLStringifier,
|
|
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
module.exports = XMLStringifier = (function() {
|
|
function XMLStringifier(options) {
|
|
this.assertLegalName = bind(this.assertLegalName, this);
|
|
this.assertLegalChar = bind(this.assertLegalChar, this);
|
|
var key, ref, value;
|
|
options || (options = {});
|
|
this.options = options;
|
|
if (!this.options.version) {
|
|
this.options.version = '1.0';
|
|
}
|
|
ref = options.stringify || {};
|
|
for (key in ref) {
|
|
if (!hasProp.call(ref, key)) continue;
|
|
value = ref[key];
|
|
this[key] = value;
|
|
}
|
|
}
|
|
|
|
XMLStringifier.prototype.name = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return this.assertLegalName('' + val || '');
|
|
};
|
|
|
|
XMLStringifier.prototype.text = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return this.assertLegalChar(this.textEscape('' + val || ''));
|
|
};
|
|
|
|
XMLStringifier.prototype.cdata = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
val = '' + val || '';
|
|
val = val.replace(']]>', ']]]]><![CDATA[>');
|
|
return this.assertLegalChar(val);
|
|
};
|
|
|
|
XMLStringifier.prototype.comment = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
val = '' + val || '';
|
|
if (val.match(/--/)) {
|
|
throw new Error("Comment text cannot contain double-hypen: " + val);
|
|
}
|
|
return this.assertLegalChar(val);
|
|
};
|
|
|
|
XMLStringifier.prototype.raw = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return '' + val || '';
|
|
};
|
|
|
|
XMLStringifier.prototype.attValue = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return this.assertLegalChar(this.attEscape(val = '' + val || ''));
|
|
};
|
|
|
|
XMLStringifier.prototype.insTarget = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return this.assertLegalChar('' + val || '');
|
|
};
|
|
|
|
XMLStringifier.prototype.insValue = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
val = '' + val || '';
|
|
if (val.match(/\?>/)) {
|
|
throw new Error("Invalid processing instruction value: " + val);
|
|
}
|
|
return this.assertLegalChar(val);
|
|
};
|
|
|
|
XMLStringifier.prototype.xmlVersion = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
val = '' + val || '';
|
|
if (!val.match(/1\.[0-9]+/)) {
|
|
throw new Error("Invalid version number: " + val);
|
|
}
|
|
return val;
|
|
};
|
|
|
|
XMLStringifier.prototype.xmlEncoding = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
val = '' + val || '';
|
|
if (!val.match(/^[A-Za-z](?:[A-Za-z0-9._-])*$/)) {
|
|
throw new Error("Invalid encoding: " + val);
|
|
}
|
|
return this.assertLegalChar(val);
|
|
};
|
|
|
|
XMLStringifier.prototype.xmlStandalone = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
if (val) {
|
|
return "yes";
|
|
} else {
|
|
return "no";
|
|
}
|
|
};
|
|
|
|
XMLStringifier.prototype.dtdPubID = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return this.assertLegalChar('' + val || '');
|
|
};
|
|
|
|
XMLStringifier.prototype.dtdSysID = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return this.assertLegalChar('' + val || '');
|
|
};
|
|
|
|
XMLStringifier.prototype.dtdElementValue = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return this.assertLegalChar('' + val || '');
|
|
};
|
|
|
|
XMLStringifier.prototype.dtdAttType = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return this.assertLegalChar('' + val || '');
|
|
};
|
|
|
|
XMLStringifier.prototype.dtdAttDefault = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return this.assertLegalChar('' + val || '');
|
|
};
|
|
|
|
XMLStringifier.prototype.dtdEntityValue = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return this.assertLegalChar('' + val || '');
|
|
};
|
|
|
|
XMLStringifier.prototype.dtdNData = function(val) {
|
|
if (this.options.noValidation) {
|
|
return val;
|
|
}
|
|
return this.assertLegalChar('' + val || '');
|
|
};
|
|
|
|
XMLStringifier.prototype.convertAttKey = '@';
|
|
|
|
XMLStringifier.prototype.convertPIKey = '?';
|
|
|
|
XMLStringifier.prototype.convertTextKey = '#text';
|
|
|
|
XMLStringifier.prototype.convertCDataKey = '#cdata';
|
|
|
|
XMLStringifier.prototype.convertCommentKey = '#comment';
|
|
|
|
XMLStringifier.prototype.convertRawKey = '#raw';
|
|
|
|
XMLStringifier.prototype.assertLegalChar = function(str) {
|
|
var regex, res;
|
|
if (this.options.noValidation) {
|
|
return str;
|
|
}
|
|
regex = '';
|
|
if (this.options.version === '1.0') {
|
|
regex = /[\0-\x08\x0B\f\x0E-\x1F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
|
|
if (res = str.match(regex)) {
|
|
throw new Error("Invalid character in string: " + str + " at index " + res.index);
|
|
}
|
|
} else if (this.options.version === '1.1') {
|
|
regex = /[\0\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
|
|
if (res = str.match(regex)) {
|
|
throw new Error("Invalid character in string: " + str + " at index " + res.index);
|
|
}
|
|
}
|
|
return str;
|
|
};
|
|
|
|
XMLStringifier.prototype.assertLegalName = function(str) {
|
|
var regex;
|
|
if (this.options.noValidation) {
|
|
return str;
|
|
}
|
|
this.assertLegalChar(str);
|
|
regex = /^([:A-Z_a-z\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uDB7F][\uDC00-\uDFFF])([\x2D\.0-:A-Z_a-z\xB7\xC0-\xD6\xD8-\xF6\xF8-\u037D\u037F-\u1FFF\u200C\u200D\u203F\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uDB7F][\uDC00-\uDFFF])*$/;
|
|
if (!str.match(regex)) {
|
|
throw new Error("Invalid character in name");
|
|
}
|
|
return str;
|
|
};
|
|
|
|
XMLStringifier.prototype.textEscape = function(str) {
|
|
var ampregex;
|
|
if (this.options.noValidation) {
|
|
return str;
|
|
}
|
|
ampregex = this.options.noDoubleEncoding ? /(?!&\S+;)&/g : /&/g;
|
|
return str.replace(ampregex, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\r/g, '
');
|
|
};
|
|
|
|
XMLStringifier.prototype.attEscape = function(str) {
|
|
var ampregex;
|
|
if (this.options.noValidation) {
|
|
return str;
|
|
}
|
|
ampregex = this.options.noDoubleEncoding ? /(?!&\S+;)&/g : /&/g;
|
|
return str.replace(ampregex, '&').replace(/</g, '<').replace(/"/g, '"').replace(/\t/g, '	').replace(/\n/g, '
').replace(/\r/g, '
');
|
|
};
|
|
|
|
return XMLStringifier;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{}],96:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, XMLCharacterData, XMLText,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLCharacterData = require('./XMLCharacterData');
|
|
|
|
module.exports = XMLText = (function(superClass) {
|
|
extend(XMLText, superClass);
|
|
|
|
function XMLText(parent, text) {
|
|
XMLText.__super__.constructor.call(this, parent);
|
|
if (text == null) {
|
|
throw new Error("Missing element text. " + this.debugInfo());
|
|
}
|
|
this.name = "#text";
|
|
this.type = NodeType.Text;
|
|
this.value = this.stringify.text(text);
|
|
}
|
|
|
|
Object.defineProperty(XMLText.prototype, 'isElementContentWhitespace', {
|
|
get: function() {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(XMLText.prototype, 'wholeText', {
|
|
get: function() {
|
|
var next, prev, str;
|
|
str = '';
|
|
prev = this.previousSibling;
|
|
while (prev) {
|
|
str = prev.data + str;
|
|
prev = prev.previousSibling;
|
|
}
|
|
str += this.data;
|
|
next = this.nextSibling;
|
|
while (next) {
|
|
str = str + next.data;
|
|
next = next.nextSibling;
|
|
}
|
|
return str;
|
|
}
|
|
});
|
|
|
|
XMLText.prototype.clone = function() {
|
|
return Object.create(this);
|
|
};
|
|
|
|
XMLText.prototype.toString = function(options) {
|
|
return this.options.writer.text(this, this.options.writer.filterOptions(options));
|
|
};
|
|
|
|
XMLText.prototype.splitText = function(offset) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
XMLText.prototype.replaceWholeText = function(content) {
|
|
throw new Error("This DOM method is not implemented." + this.debugInfo());
|
|
};
|
|
|
|
return XMLText;
|
|
|
|
})(XMLCharacterData);
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./XMLCharacterData":72}],97:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, WriterState, XMLCData, XMLComment, XMLDTDAttList, XMLDTDElement, XMLDTDEntity, XMLDTDNotation, XMLDeclaration, XMLDocType, XMLDummy, XMLElement, XMLProcessingInstruction, XMLRaw, XMLText, XMLWriterBase, assign,
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
assign = require('./Utility').assign;
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
XMLDeclaration = require('./XMLDeclaration');
|
|
|
|
XMLDocType = require('./XMLDocType');
|
|
|
|
XMLCData = require('./XMLCData');
|
|
|
|
XMLComment = require('./XMLComment');
|
|
|
|
XMLElement = require('./XMLElement');
|
|
|
|
XMLRaw = require('./XMLRaw');
|
|
|
|
XMLText = require('./XMLText');
|
|
|
|
XMLProcessingInstruction = require('./XMLProcessingInstruction');
|
|
|
|
XMLDummy = require('./XMLDummy');
|
|
|
|
XMLDTDAttList = require('./XMLDTDAttList');
|
|
|
|
XMLDTDElement = require('./XMLDTDElement');
|
|
|
|
XMLDTDEntity = require('./XMLDTDEntity');
|
|
|
|
XMLDTDNotation = require('./XMLDTDNotation');
|
|
|
|
WriterState = require('./WriterState');
|
|
|
|
module.exports = XMLWriterBase = (function() {
|
|
function XMLWriterBase(options) {
|
|
var key, ref, value;
|
|
options || (options = {});
|
|
this.options = options;
|
|
ref = options.writer || {};
|
|
for (key in ref) {
|
|
if (!hasProp.call(ref, key)) continue;
|
|
value = ref[key];
|
|
this["_" + key] = this[key];
|
|
this[key] = value;
|
|
}
|
|
}
|
|
|
|
XMLWriterBase.prototype.filterOptions = function(options) {
|
|
var filteredOptions, ref, ref1, ref2, ref3, ref4, ref5, ref6;
|
|
options || (options = {});
|
|
options = assign({}, this.options, options);
|
|
filteredOptions = {
|
|
writer: this
|
|
};
|
|
filteredOptions.pretty = options.pretty || false;
|
|
filteredOptions.allowEmpty = options.allowEmpty || false;
|
|
filteredOptions.indent = (ref = options.indent) != null ? ref : ' ';
|
|
filteredOptions.newline = (ref1 = options.newline) != null ? ref1 : '\n';
|
|
filteredOptions.offset = (ref2 = options.offset) != null ? ref2 : 0;
|
|
filteredOptions.dontPrettyTextNodes = (ref3 = (ref4 = options.dontPrettyTextNodes) != null ? ref4 : options.dontprettytextnodes) != null ? ref3 : 0;
|
|
filteredOptions.spaceBeforeSlash = (ref5 = (ref6 = options.spaceBeforeSlash) != null ? ref6 : options.spacebeforeslash) != null ? ref5 : '';
|
|
if (filteredOptions.spaceBeforeSlash === true) {
|
|
filteredOptions.spaceBeforeSlash = ' ';
|
|
}
|
|
filteredOptions.suppressPrettyCount = 0;
|
|
filteredOptions.user = {};
|
|
filteredOptions.state = WriterState.None;
|
|
return filteredOptions;
|
|
};
|
|
|
|
XMLWriterBase.prototype.indent = function(node, options, level) {
|
|
var indentLevel;
|
|
if (!options.pretty || options.suppressPrettyCount) {
|
|
return '';
|
|
} else if (options.pretty) {
|
|
indentLevel = (level || 0) + options.offset + 1;
|
|
if (indentLevel > 0) {
|
|
return new Array(indentLevel).join(options.indent);
|
|
}
|
|
}
|
|
return '';
|
|
};
|
|
|
|
XMLWriterBase.prototype.endline = function(node, options, level) {
|
|
if (!options.pretty || options.suppressPrettyCount) {
|
|
return '';
|
|
} else {
|
|
return options.newline;
|
|
}
|
|
};
|
|
|
|
XMLWriterBase.prototype.attribute = function(att, options, level) {
|
|
var r;
|
|
this.openAttribute(att, options, level);
|
|
r = ' ' + att.name + '="' + att.value + '"';
|
|
this.closeAttribute(att, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.cdata = function(node, options, level) {
|
|
var r;
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r = this.indent(node, options, level) + '<![CDATA[';
|
|
options.state = WriterState.InsideTag;
|
|
r += node.value;
|
|
options.state = WriterState.CloseTag;
|
|
r += ']]>' + this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.comment = function(node, options, level) {
|
|
var r;
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r = this.indent(node, options, level) + '<!-- ';
|
|
options.state = WriterState.InsideTag;
|
|
r += node.value;
|
|
options.state = WriterState.CloseTag;
|
|
r += ' -->' + this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.declaration = function(node, options, level) {
|
|
var r;
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r = this.indent(node, options, level) + '<?xml';
|
|
options.state = WriterState.InsideTag;
|
|
r += ' version="' + node.version + '"';
|
|
if (node.encoding != null) {
|
|
r += ' encoding="' + node.encoding + '"';
|
|
}
|
|
if (node.standalone != null) {
|
|
r += ' standalone="' + node.standalone + '"';
|
|
}
|
|
options.state = WriterState.CloseTag;
|
|
r += options.spaceBeforeSlash + '?>';
|
|
r += this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.docType = function(node, options, level) {
|
|
var child, i, len, r, ref;
|
|
level || (level = 0);
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r = this.indent(node, options, level);
|
|
r += '<!DOCTYPE ' + node.root().name;
|
|
if (node.pubID && node.sysID) {
|
|
r += ' PUBLIC "' + node.pubID + '" "' + node.sysID + '"';
|
|
} else if (node.sysID) {
|
|
r += ' SYSTEM "' + node.sysID + '"';
|
|
}
|
|
if (node.children.length > 0) {
|
|
r += ' [';
|
|
r += this.endline(node, options, level);
|
|
options.state = WriterState.InsideTag;
|
|
ref = node.children;
|
|
for (i = 0, len = ref.length; i < len; i++) {
|
|
child = ref[i];
|
|
r += this.writeChildNode(child, options, level + 1);
|
|
}
|
|
options.state = WriterState.CloseTag;
|
|
r += ']';
|
|
}
|
|
options.state = WriterState.CloseTag;
|
|
r += options.spaceBeforeSlash + '>';
|
|
r += this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.element = function(node, options, level) {
|
|
var att, child, childNodeCount, firstChildNode, i, j, len, len1, name, prettySuppressed, r, ref, ref1, ref2;
|
|
level || (level = 0);
|
|
prettySuppressed = false;
|
|
r = '';
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r += this.indent(node, options, level) + '<' + node.name;
|
|
ref = node.attribs;
|
|
for (name in ref) {
|
|
if (!hasProp.call(ref, name)) continue;
|
|
att = ref[name];
|
|
r += this.attribute(att, options, level);
|
|
}
|
|
childNodeCount = node.children.length;
|
|
firstChildNode = childNodeCount === 0 ? null : node.children[0];
|
|
if (childNodeCount === 0 || node.children.every(function(e) {
|
|
return (e.type === NodeType.Text || e.type === NodeType.Raw) && e.value === '';
|
|
})) {
|
|
if (options.allowEmpty) {
|
|
r += '>';
|
|
options.state = WriterState.CloseTag;
|
|
r += '</' + node.name + '>' + this.endline(node, options, level);
|
|
} else {
|
|
options.state = WriterState.CloseTag;
|
|
r += options.spaceBeforeSlash + '/>' + this.endline(node, options, level);
|
|
}
|
|
} else if (options.pretty && childNodeCount === 1 && (firstChildNode.type === NodeType.Text || firstChildNode.type === NodeType.Raw) && (firstChildNode.value != null)) {
|
|
r += '>';
|
|
options.state = WriterState.InsideTag;
|
|
options.suppressPrettyCount++;
|
|
prettySuppressed = true;
|
|
r += this.writeChildNode(firstChildNode, options, level + 1);
|
|
options.suppressPrettyCount--;
|
|
prettySuppressed = false;
|
|
options.state = WriterState.CloseTag;
|
|
r += '</' + node.name + '>' + this.endline(node, options, level);
|
|
} else {
|
|
if (options.dontPrettyTextNodes) {
|
|
ref1 = node.children;
|
|
for (i = 0, len = ref1.length; i < len; i++) {
|
|
child = ref1[i];
|
|
if ((child.type === NodeType.Text || child.type === NodeType.Raw) && (child.value != null)) {
|
|
options.suppressPrettyCount++;
|
|
prettySuppressed = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
r += '>' + this.endline(node, options, level);
|
|
options.state = WriterState.InsideTag;
|
|
ref2 = node.children;
|
|
for (j = 0, len1 = ref2.length; j < len1; j++) {
|
|
child = ref2[j];
|
|
r += this.writeChildNode(child, options, level + 1);
|
|
}
|
|
options.state = WriterState.CloseTag;
|
|
r += this.indent(node, options, level) + '</' + node.name + '>';
|
|
if (prettySuppressed) {
|
|
options.suppressPrettyCount--;
|
|
}
|
|
r += this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
}
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.writeChildNode = function(node, options, level) {
|
|
switch (node.type) {
|
|
case NodeType.CData:
|
|
return this.cdata(node, options, level);
|
|
case NodeType.Comment:
|
|
return this.comment(node, options, level);
|
|
case NodeType.Element:
|
|
return this.element(node, options, level);
|
|
case NodeType.Raw:
|
|
return this.raw(node, options, level);
|
|
case NodeType.Text:
|
|
return this.text(node, options, level);
|
|
case NodeType.ProcessingInstruction:
|
|
return this.processingInstruction(node, options, level);
|
|
case NodeType.Dummy:
|
|
return '';
|
|
case NodeType.Declaration:
|
|
return this.declaration(node, options, level);
|
|
case NodeType.DocType:
|
|
return this.docType(node, options, level);
|
|
case NodeType.AttributeDeclaration:
|
|
return this.dtdAttList(node, options, level);
|
|
case NodeType.ElementDeclaration:
|
|
return this.dtdElement(node, options, level);
|
|
case NodeType.EntityDeclaration:
|
|
return this.dtdEntity(node, options, level);
|
|
case NodeType.NotationDeclaration:
|
|
return this.dtdNotation(node, options, level);
|
|
default:
|
|
throw new Error("Unknown XML node type: " + node.constructor.name);
|
|
}
|
|
};
|
|
|
|
XMLWriterBase.prototype.processingInstruction = function(node, options, level) {
|
|
var r;
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r = this.indent(node, options, level) + '<?';
|
|
options.state = WriterState.InsideTag;
|
|
r += node.target;
|
|
if (node.value) {
|
|
r += ' ' + node.value;
|
|
}
|
|
options.state = WriterState.CloseTag;
|
|
r += options.spaceBeforeSlash + '?>';
|
|
r += this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.raw = function(node, options, level) {
|
|
var r;
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r = this.indent(node, options, level);
|
|
options.state = WriterState.InsideTag;
|
|
r += node.value;
|
|
options.state = WriterState.CloseTag;
|
|
r += this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.text = function(node, options, level) {
|
|
var r;
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r = this.indent(node, options, level);
|
|
options.state = WriterState.InsideTag;
|
|
r += node.value;
|
|
options.state = WriterState.CloseTag;
|
|
r += this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.dtdAttList = function(node, options, level) {
|
|
var r;
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r = this.indent(node, options, level) + '<!ATTLIST';
|
|
options.state = WriterState.InsideTag;
|
|
r += ' ' + node.elementName + ' ' + node.attributeName + ' ' + node.attributeType;
|
|
if (node.defaultValueType !== '#DEFAULT') {
|
|
r += ' ' + node.defaultValueType;
|
|
}
|
|
if (node.defaultValue) {
|
|
r += ' "' + node.defaultValue + '"';
|
|
}
|
|
options.state = WriterState.CloseTag;
|
|
r += options.spaceBeforeSlash + '>' + this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.dtdElement = function(node, options, level) {
|
|
var r;
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r = this.indent(node, options, level) + '<!ELEMENT';
|
|
options.state = WriterState.InsideTag;
|
|
r += ' ' + node.name + ' ' + node.value;
|
|
options.state = WriterState.CloseTag;
|
|
r += options.spaceBeforeSlash + '>' + this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.dtdEntity = function(node, options, level) {
|
|
var r;
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r = this.indent(node, options, level) + '<!ENTITY';
|
|
options.state = WriterState.InsideTag;
|
|
if (node.pe) {
|
|
r += ' %';
|
|
}
|
|
r += ' ' + node.name;
|
|
if (node.value) {
|
|
r += ' "' + node.value + '"';
|
|
} else {
|
|
if (node.pubID && node.sysID) {
|
|
r += ' PUBLIC "' + node.pubID + '" "' + node.sysID + '"';
|
|
} else if (node.sysID) {
|
|
r += ' SYSTEM "' + node.sysID + '"';
|
|
}
|
|
if (node.nData) {
|
|
r += ' NDATA ' + node.nData;
|
|
}
|
|
}
|
|
options.state = WriterState.CloseTag;
|
|
r += options.spaceBeforeSlash + '>' + this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.dtdNotation = function(node, options, level) {
|
|
var r;
|
|
this.openNode(node, options, level);
|
|
options.state = WriterState.OpenTag;
|
|
r = this.indent(node, options, level) + '<!NOTATION';
|
|
options.state = WriterState.InsideTag;
|
|
r += ' ' + node.name;
|
|
if (node.pubID && node.sysID) {
|
|
r += ' PUBLIC "' + node.pubID + '" "' + node.sysID + '"';
|
|
} else if (node.pubID) {
|
|
r += ' PUBLIC "' + node.pubID + '"';
|
|
} else if (node.sysID) {
|
|
r += ' SYSTEM "' + node.sysID + '"';
|
|
}
|
|
options.state = WriterState.CloseTag;
|
|
r += options.spaceBeforeSlash + '>' + this.endline(node, options, level);
|
|
options.state = WriterState.None;
|
|
this.closeNode(node, options, level);
|
|
return r;
|
|
};
|
|
|
|
XMLWriterBase.prototype.openNode = function(node, options, level) {};
|
|
|
|
XMLWriterBase.prototype.closeNode = function(node, options, level) {};
|
|
|
|
XMLWriterBase.prototype.openAttribute = function(att, options, level) {};
|
|
|
|
XMLWriterBase.prototype.closeAttribute = function(att, options, level) {};
|
|
|
|
return XMLWriterBase;
|
|
|
|
})();
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./Utility":68,"./WriterState":69,"./XMLCData":71,"./XMLComment":73,"./XMLDTDAttList":78,"./XMLDTDElement":79,"./XMLDTDEntity":80,"./XMLDTDNotation":81,"./XMLDeclaration":82,"./XMLDocType":83,"./XMLDummy":86,"./XMLElement":87,"./XMLProcessingInstruction":91,"./XMLRaw":92,"./XMLText":96}],98:[function(require,module,exports){
|
|
// Generated by CoffeeScript 1.12.7
|
|
(function() {
|
|
var NodeType, WriterState, XMLDOMImplementation, XMLDocument, XMLDocumentCB, XMLStreamWriter, XMLStringWriter, assign, isFunction, ref;
|
|
|
|
ref = require('./Utility'), assign = ref.assign, isFunction = ref.isFunction;
|
|
|
|
XMLDOMImplementation = require('./XMLDOMImplementation');
|
|
|
|
XMLDocument = require('./XMLDocument');
|
|
|
|
XMLDocumentCB = require('./XMLDocumentCB');
|
|
|
|
XMLStringWriter = require('./XMLStringWriter');
|
|
|
|
XMLStreamWriter = require('./XMLStreamWriter');
|
|
|
|
NodeType = require('./NodeType');
|
|
|
|
WriterState = require('./WriterState');
|
|
|
|
module.exports.create = function(name, xmldec, doctype, options) {
|
|
var doc, root;
|
|
if (name == null) {
|
|
throw new Error("Root element needs a name.");
|
|
}
|
|
options = assign({}, xmldec, doctype, options);
|
|
doc = new XMLDocument(options);
|
|
root = doc.element(name);
|
|
if (!options.headless) {
|
|
doc.declaration(options);
|
|
if ((options.pubID != null) || (options.sysID != null)) {
|
|
doc.dtd(options);
|
|
}
|
|
}
|
|
return root;
|
|
};
|
|
|
|
module.exports.begin = function(options, onData, onEnd) {
|
|
var ref1;
|
|
if (isFunction(options)) {
|
|
ref1 = [options, onData], onData = ref1[0], onEnd = ref1[1];
|
|
options = {};
|
|
}
|
|
if (onData) {
|
|
return new XMLDocumentCB(options, onData, onEnd);
|
|
} else {
|
|
return new XMLDocument(options);
|
|
}
|
|
};
|
|
|
|
module.exports.stringWriter = function(options) {
|
|
return new XMLStringWriter(options);
|
|
};
|
|
|
|
module.exports.streamWriter = function(stream, options) {
|
|
return new XMLStreamWriter(stream, options);
|
|
};
|
|
|
|
module.exports.implementation = new XMLDOMImplementation();
|
|
|
|
module.exports.nodeType = NodeType;
|
|
|
|
module.exports.writerState = WriterState;
|
|
|
|
}).call(this);
|
|
|
|
},{"./NodeType":67,"./Utility":68,"./WriterState":69,"./XMLDOMImplementation":76,"./XMLDocument":84,"./XMLDocumentCB":85,"./XMLStreamWriter":93,"./XMLStringWriter":94}],99:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.showSeatmapBtnParent = exports.injectBookingBtn = void 0;
|
|
var Communication = __importStar(require("./communication"));
|
|
function injectBookingBtn() {
|
|
jQuery(".flash_seat_map_box").remove();
|
|
changeBookingBtnCSS();
|
|
appendBookingBtnHTML();
|
|
}
|
|
exports.injectBookingBtn = injectBookingBtn;
|
|
function showSeatmapBtnParent() {
|
|
console.log("child completely ready");
|
|
Communication.sendEventToParent("child_seatmap_ready");
|
|
}
|
|
exports.showSeatmapBtnParent = showSeatmapBtnParent;
|
|
function appendBookingBtnHTML() {
|
|
jQuery("#flash_seat_map_box_id").append("\n <div class=\"row_space\"></div>\n <div class=\"row_space\"></div>\n <div id=\"containerBookingBtn\">\n <a class=\"continue\" id=\"openSeatmap\">\n <span>Saalplanbuchung</span>\n </a>\n <div id=\"dialogSeatmap\" hidden=\"hidden\"></div>\n </div>\n ");
|
|
}
|
|
function changeBookingBtnCSS() {
|
|
jQuery('#flash_seat_map_box_id').css({
|
|
"display": "block",
|
|
"position": "relative",
|
|
"width": "100%"
|
|
});
|
|
}
|
|
|
|
},{"./communication":103}],100:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.generateCheckoutUrl = exports.initModalCart = exports.generateCartItems = exports.calcOverallPrice = exports.changedDropdownBuyerType = exports.removeCartItems = exports.addItem = void 0;
|
|
var XMLHelper = __importStar(require("./xmlhelper"));
|
|
var config_1 = require("./config");
|
|
var Events = __importStar(require("./events"));
|
|
var CartButtons = __importStar(require("./cartButtons"));
|
|
function addItem(inSeatObj) {
|
|
var color = "#" + XMLHelper.getVenuePricescalePropertyByPricescaleID("color", inSeatObj.data.seatsObj.id[0]);
|
|
var category = XMLHelper.getVenuePricescalePropertyByPricescaleID("desc", inSeatObj.data.seatsObj.id[0]);
|
|
var seat = config_1.config.state.layoutRows[inSeatObj.id][5];
|
|
var row = config_1.config.state.layoutRows[inSeatObj.id][4];
|
|
var sectionID = config_1.config.state.layoutRows[inSeatObj.id][3];
|
|
var sectionDesc = XMLHelper.getSectionDescBySectionID(sectionID);
|
|
var seatStr = sectionDesc + "<br/>Reihe " + row + " Platz " + seat;
|
|
var buyerTypes = XMLHelper.getBuyerTypesByPricescaleID(inSeatObj.data.seatsObj.id[0]);
|
|
var cartID = "cartItem-" + inSeatObj.id;
|
|
var dropdownBuyerTypesSelector = "#" + cartID + " .dropdownBuyerTypes";
|
|
appendHTML(cartID, color, category, seatStr);
|
|
addDropdownBuyerTypeOptions(buyerTypes, dropdownBuyerTypesSelector);
|
|
Events.addCartDropdownBuyerTypes(dropdownBuyerTypesSelector, inSeatObj);
|
|
}
|
|
exports.addItem = addItem;
|
|
function removeCartItems() {
|
|
jQuery("#cartItemHTML .cartItem").each(function () {
|
|
this.remove();
|
|
});
|
|
}
|
|
exports.removeCartItems = removeCartItems;
|
|
function changedDropdownBuyerType(inSelect, inSeatObj) {
|
|
var index = config_1.config.state.selectedSeatsArr.findIndex(function (arr) {
|
|
return arr[0] === inSeatObj.id;
|
|
});
|
|
config_1.config.state.selectedSeatsArr[index][1] = inSelect.value;
|
|
var buyerTypeCode = XMLHelper.getBuyerTypeCodeByBuyerTypeID(inSelect.value);
|
|
if (buyerTypeCode)
|
|
config_1.config.state.selectedSeatsArr[index][2] = buyerTypeCode;
|
|
calcOverallPrice();
|
|
CartButtons.setBtnCartText();
|
|
var url = generateCheckoutUrl();
|
|
Events.addRedirectCheckout(url);
|
|
}
|
|
exports.changedDropdownBuyerType = changedDropdownBuyerType;
|
|
function calcOverallPrice() {
|
|
if (!config_1.config.state.selectedSeatsArr.length) {
|
|
config_1.config.state.priceOverall = "0";
|
|
return "0";
|
|
}
|
|
config_1.config.state.priceOverall = sumSeatPrices();
|
|
return config_1.config.state.priceOverall;
|
|
}
|
|
exports.calcOverallPrice = calcOverallPrice;
|
|
function generateCartItems() {
|
|
if (!config_1.config.state.selectedSeatsArr.length)
|
|
return;
|
|
for (var key in config_1.config.state.selectedSeatsObj) {
|
|
if (Object.prototype.hasOwnProperty.call(config_1.config.state.selectedSeatsObj, key)) {
|
|
var element = config_1.config.state.selectedSeatsObj[key];
|
|
addItem(element);
|
|
}
|
|
}
|
|
}
|
|
exports.generateCartItems = generateCartItems;
|
|
function initModalCart() {
|
|
jQuery("#modalCart-overlay").hide();
|
|
Events.addCartBack();
|
|
Events.addCartClose();
|
|
}
|
|
exports.initModalCart = initModalCart;
|
|
function generateCheckoutUrl() {
|
|
if (!config_1.config.state.selectedSeatsArr.length)
|
|
return;
|
|
var inputsWithValue = config_1.config.state.inputsWithValue;
|
|
var selectedSeatIndexes = XMLHelper.generateSelectedSeatIndexes();
|
|
return inputsWithValue["ticketPurchaseUrl"] + "?user_context=" + inputsWithValue.user_context + "&pid=" + inputsWithValue["pid"] + "&selected_seat_indexes=" + selectedSeatIndexes + "&trxstate=148";
|
|
}
|
|
exports.generateCheckoutUrl = generateCheckoutUrl;
|
|
function appendHTML(inCartID, inColor, inCategory, inSeatStr) {
|
|
jQuery("#cartItemHTML .fl-html").append("\n <div class=\"cartItem\" id=\"" + inCartID + "\">\n <div class=\"cartItemColoredSquare\" style=\"background: " + inColor + ";\"></div>\n <div class=\"cartItemCategory\">" + inCategory + "</div>\n <h5 class=\"cartItemSeat\">" + inSeatStr + "</h5>\n <select name=\"dropdownBuyerTypes\" class=\"dropdownBuyerTypes\"></select>\n </div>");
|
|
}
|
|
function addDropdownBuyerTypeOptions(inBuyerTypes, inSelector) {
|
|
if (!inBuyerTypes)
|
|
return;
|
|
inBuyerTypes.forEach(function (arr) {
|
|
if (arr[0])
|
|
appendOption(inSelector, arr);
|
|
});
|
|
}
|
|
function appendOption(inSelector, inArr) {
|
|
var dropdownBuyerTypes = jQuery(inSelector).get(0);
|
|
var opt = document.createElement('option');
|
|
opt.value = inArr[0];
|
|
opt.innerHTML = inArr[2] + " \u20AC" + inArr[1];
|
|
dropdownBuyerTypes.appendChild(opt);
|
|
}
|
|
function sumSeatPrices() {
|
|
return config_1.config.state.selectedSeatsArr.map(getSeatPrice)
|
|
.reduce(function (prev, curr) { return prev + curr; })
|
|
.toFixed(2);
|
|
}
|
|
function getSeatPrice(arr) {
|
|
var seatID = arr[0];
|
|
var buyertypeID = arr[1];
|
|
var selectedSeat = config_1.config.state.selectedSeatsObj[seatID];
|
|
var pricescaleID = selectedSeat.data.seatsObj.id[0];
|
|
var pricescaleObj = XMLHelper.getVenuePriceStructurePropertyByPricescaleID(pricescaleID);
|
|
if (pricescaleObj) {
|
|
var seatPrice = XMLHelper.getPriceByBuyerTypeID(buyertypeID, pricescaleObj);
|
|
if (seatPrice)
|
|
return seatPrice;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
},{"./cartButtons":101,"./config":104,"./events":105,"./xmlhelper":115}],101:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.showHideBtnCartLoading = exports.setBtnCartText = void 0;
|
|
var config_1 = require("./config");
|
|
function setBtnCartText() {
|
|
jQuery("#modalCart .uabb-button-text")[0].innerText = createCartBtnText();
|
|
jQuery("#modalCartSum .uabb-heading-text")[0].textContent = createModalCartBtnText();
|
|
}
|
|
exports.setBtnCartText = setBtnCartText;
|
|
function createCartBtnText() {
|
|
var numTickets = config_1.config.state.selectedSeatsArr.length;
|
|
if (config_1.config.state.priceOverall !== "")
|
|
return numTickets === 1 ? numTickets + " Ticket f\u00FCr \u20AC" + config_1.config.state.priceOverall : numTickets + " Tickets f\u00FCr \u20AC" + config_1.config.state.priceOverall;
|
|
else
|
|
return "0 Tickets für €0.00";
|
|
}
|
|
function createModalCartBtnText() {
|
|
var numTickets = config_1.config.state.selectedSeatsArr.length;
|
|
if (config_1.config.state.priceOverall !== "")
|
|
return "Summe (" + numTickets + " Pl\u00E4tze) \u20AC" + config_1.config.state.priceOverall;
|
|
else
|
|
return "Summe (0 Pl\u00E4tze) \u20AC0,00";
|
|
}
|
|
function showHideBtnCartLoading(inSwitch) {
|
|
if (inSwitch === "show") {
|
|
jQuery("#modalCart .uabb-button").css("pointer-events", "none");
|
|
jQuery("#modalCart i").hide();
|
|
jQuery("#modalCart .uabb-button-text").addClass("dot-pulse");
|
|
}
|
|
else if (inSwitch === "hide") {
|
|
jQuery("#modalCart i").show();
|
|
jQuery("#modalCart .uabb-button-text").removeClass("dot-pulse");
|
|
jQuery("#modalCart .uabb-button").css("pointer-events", "all");
|
|
}
|
|
}
|
|
exports.showHideBtnCartLoading = showHideBtnCartLoading;
|
|
|
|
},{"./config":104}],102:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.sendCheckoutResponse = exports.sendSeatmapXML = exports.initSendInputsWithValue = exports.initSendVenueXML = exports.initVenue = void 0;
|
|
var Communication = __importStar(require("./communication"));
|
|
var UI = __importStar(require("./ui"));
|
|
var config_1 = require("./config");
|
|
var utils_1 = __importDefault(require("./utils"));
|
|
var Parser = __importStar(require("./parser"));
|
|
var JSC = __importStar(require("./jsc"));
|
|
var Legend = __importStar(require("./legend"));
|
|
var Events = __importStar(require("./events"));
|
|
var Trims = __importStar(require("./trims"));
|
|
var XMLHelper = __importStar(require("./xmlhelper"));
|
|
var Panzoom = __importStar(require("./panzoom"));
|
|
var jBoxHelper = __importStar(require("./jBoxHelper"));
|
|
var Cart = __importStar(require("./cart"));
|
|
var CartButtons = __importStar(require("./cartButtons"));
|
|
function initVenue() {
|
|
UI.controlLoftloader("show");
|
|
Communication.sendEventToParent("child_init_needInputsWithValue");
|
|
}
|
|
exports.initVenue = initVenue;
|
|
function initSendVenueXML(inE) {
|
|
var data = JSON.parse(inE.data);
|
|
config_1.config.state.inVenueXML = data.message.map_response;
|
|
var venueXML = config_1.config.state.inVenueXML;
|
|
var css = UI.generatePricescaleCSS();
|
|
utils_1.default.inject(css, "cssCustom", "body");
|
|
var eventInfo = Parser.getEventInfo();
|
|
UI.setEventInfo(eventInfo);
|
|
var seatmapListing = venueXML.seatmap_config[0].seatmap;
|
|
UI.setOptionSelect(seatmapListing, "dropdownSeatmap");
|
|
var id = seatmapListing[0].id[0];
|
|
jQuery("#dropdownSeatmap").val(id);
|
|
Communication.needSeatmapXML(id);
|
|
console.log(css);
|
|
console.log(seatmapListing);
|
|
}
|
|
exports.initSendVenueXML = initSendVenueXML;
|
|
function initSendInputsWithValue(inE) {
|
|
var data = JSON.parse(inE.data);
|
|
config_1.config.state.inputsWithValue = data.message;
|
|
UI.changeVenueImage();
|
|
Communication.sendEventToParent("child_init_needVenueXML");
|
|
}
|
|
exports.initSendInputsWithValue = initSendInputsWithValue;
|
|
function sendSeatmapXML(inE) {
|
|
var data = JSON.parse(inE.data);
|
|
config_1.config.state.seatmapXML = data.message.map_response;
|
|
var map = JSC.generateMap();
|
|
var rowsNaming = JSC.getRowsNaming();
|
|
var seats = JSC.getSeats();
|
|
var legend = JSC.generateLegend("#JSCLegendInner");
|
|
JSC.addSeatmap("#containerSeatmapInner", map, rowsNaming, seats, legend);
|
|
JSC.setUnavailableSeats();
|
|
JSC.selectSeatsInCart();
|
|
Legend.convertLegendToDropdown("dropdownLegend");
|
|
Events.dropdownLegendOnChange("#dropdownLegend");
|
|
Trims.addTrims();
|
|
XMLHelper.processSMAP();
|
|
config_1.config.state.panzoom = Panzoom.addPanzoom("#containerSeatmapInner", ".panzoomZoomIn", ".panzoomZoomOut", "#panzoomResetZoom");
|
|
UI.controlLoftloader("hide");
|
|
jBoxHelper.createSeatTooltips();
|
|
}
|
|
exports.sendSeatmapXML = sendSeatmapXML;
|
|
function sendCheckoutResponse(inE) {
|
|
var data = JSON.parse(inE.data);
|
|
config_1.config.state.isValidSeatSelection = data.message.isValidSeatSelection;
|
|
console.log(data.message);
|
|
if (!config_1.config.state.isValidSeatSelection) {
|
|
jBoxHelper.showJBoxNotice("Auswahl nicht m\u00F6glich: Bitte lassen Sie keinen einzelnen Platz frei.");
|
|
CartButtons.showHideBtnCartLoading("hide");
|
|
}
|
|
else {
|
|
Cart.removeCartItems();
|
|
Cart.generateCartItems();
|
|
var url = Cart.generateCheckoutUrl();
|
|
Events.addRedirectCheckout(url);
|
|
UI.fadeInCartModal();
|
|
CartButtons.showHideBtnCartLoading("hide");
|
|
}
|
|
config_1.config.state.cartChanged = false;
|
|
}
|
|
exports.sendCheckoutResponse = sendCheckoutResponse;
|
|
|
|
},{"./cart":100,"./cartButtons":101,"./communication":103,"./config":104,"./events":105,"./jBoxHelper":106,"./jsc":107,"./legend":108,"./panzoom":109,"./parser":110,"./trims":112,"./ui":113,"./utils":114,"./xmlhelper":115}],103:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.isValidSeatSelection = exports.cancelCheckout = exports.needSeatmapXML = exports.sendEventToParent = exports.sendEventToChild = exports.sendXML = exports.listenToMessages = exports.sendMessage = void 0;
|
|
var axios_1 = __importDefault(require("axios"));
|
|
var xml2jsParser = require('xml2js').parseString;
|
|
var UI = __importStar(require("./ui"));
|
|
var config_1 = require("./config");
|
|
var Cart = __importStar(require("./cart"));
|
|
function sendMessage(inData, inTo) {
|
|
if (inTo === "parent")
|
|
window.parent.postMessage(JSON.stringify(inData), '*');
|
|
else {
|
|
var child = document.getElementById(inTo);
|
|
if (child !== null && child.contentWindow !== null)
|
|
child.contentWindow.postMessage(JSON.stringify(inData), "*");
|
|
else
|
|
console.log("Element with ID " + inTo + " does not exist");
|
|
}
|
|
}
|
|
exports.sendMessage = sendMessage;
|
|
function listenToMessages(inHandler) {
|
|
window.addEventListener('message', function (e) {
|
|
inHandler(e);
|
|
});
|
|
}
|
|
exports.listenToMessages = listenToMessages;
|
|
function sendXML(inUrl, inTo, inEvent, inFrom, inDate) {
|
|
if (inDate === void 0) { inDate = Date.now(); }
|
|
getXMLPromise(inUrl).then(function (result) {
|
|
var message = {
|
|
date: inDate,
|
|
from: inFrom,
|
|
message: result,
|
|
event: inEvent
|
|
};
|
|
sendMessage(message, inTo);
|
|
})
|
|
.catch(function (err) {
|
|
console.error(err);
|
|
});
|
|
}
|
|
exports.sendXML = sendXML;
|
|
function sendEventToChild(inEvent) {
|
|
var message = {
|
|
message: null,
|
|
from: "parent",
|
|
event: inEvent,
|
|
date: Date.now()
|
|
};
|
|
sendMessage(message, "iframeSeatmap");
|
|
}
|
|
exports.sendEventToChild = sendEventToChild;
|
|
function sendEventToParent(inEvent) {
|
|
var message = {
|
|
message: null,
|
|
from: "child",
|
|
event: inEvent,
|
|
date: Date.now()
|
|
};
|
|
sendMessage(message, "parent");
|
|
}
|
|
exports.sendEventToParent = sendEventToParent;
|
|
function needSeatmapXML(inID) {
|
|
var message = {
|
|
message: inID,
|
|
from: "child",
|
|
event: "child_needSeatmapXML",
|
|
date: Date.now()
|
|
};
|
|
sendMessage(message, "parent");
|
|
}
|
|
exports.needSeatmapXML = needSeatmapXML;
|
|
function cancelCheckout(inUrl) {
|
|
fetch(inUrl, {
|
|
redirect: "manual"
|
|
})
|
|
.then(function () { return console.log(inUrl + " canceled"); })
|
|
.catch(function (error) {
|
|
console.log("error");
|
|
console.log(error);
|
|
});
|
|
}
|
|
exports.cancelCheckout = cancelCheckout;
|
|
function isValidSeatSelection() {
|
|
jQuery("#modalCart-overlay").hide();
|
|
if (!config_1.config.state.selectedSeatsArr.length)
|
|
return;
|
|
UI.adjustUIToLoading();
|
|
var url = Cart.generateCheckoutUrl();
|
|
var message = {
|
|
message: {
|
|
url: url,
|
|
},
|
|
from: "child",
|
|
event: "child_needCheckoutResponse",
|
|
date: Date.now()
|
|
};
|
|
sendMessage(message, "parent");
|
|
}
|
|
exports.isValidSeatSelection = isValidSeatSelection;
|
|
function getXMLPromise(inUrl) {
|
|
return axios_1.default.get(inUrl)
|
|
.then(function (response) {
|
|
return new Promise(function (resolve, reject) {
|
|
var AxiosResponse = response;
|
|
if (AxiosResponse.status === 200 && AxiosResponse.headers["content-type"] === "text/xml;charset=utf-8") {
|
|
xml2jsParser(AxiosResponse.data, { normalizeTags: true, normalize: true, mergeAttrs: true }, function (err, result) {
|
|
if (err)
|
|
reject(err);
|
|
else
|
|
resolve(result);
|
|
});
|
|
}
|
|
});
|
|
})
|
|
.catch(function (error) {
|
|
console.log(error);
|
|
});
|
|
}
|
|
|
|
},{"./cart":100,"./config":104,"./ui":113,"axios":28,"xml2js":65}],104:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.config = void 0;
|
|
exports.config = {
|
|
debug: true,
|
|
branch: "staging",
|
|
urlSeatmapStaging: "https://staging.tickets.zinomedia.de",
|
|
urlSeatmapMaster: "https://tickets.zinomedia.de",
|
|
urlCSSChildMaster: "https://tickets.zinomedia.de/dist/styleChild.css",
|
|
urlCSSChildStaging: "https://staging.tickets.zinomedia.de/dist/styleChild.css",
|
|
urlCSSParentMaster: "https://tickets.zinomedia.de/dist/styleParent.css",
|
|
urlCSSParentStaging: "https://staging.tickets.zinomedia.de/dist/styleParent.css",
|
|
urlJSCStaging: "https://staging.tickets.zinomedia.de/libs/jQuery-Seat-Charts/jquery.seat-charts.min.js",
|
|
urlJSCMaster: "https://tickets.zinomedia.de/libs/jQuery-Seat-Charts/jquery.seat-charts.min.js",
|
|
urlCSSJSCStaging: "https://staging.tickets.zinomedia.de/libs/jQuery-Seat-Charts/jquery.seat-charts.css",
|
|
urlCSSJSCMaster: "https://tickets.zinomedia.de/libs/jQuery-Seat-Charts/jquery.seat-charts.css",
|
|
urlCSSjQueryUI: "https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css",
|
|
childHasVenueXML: false,
|
|
maxSelectedSeats: 10,
|
|
state: {
|
|
priceOverall: "",
|
|
cartChanged: false,
|
|
selectedSeatsArr: [],
|
|
selectedSeatsObj: {},
|
|
layoutRows: {},
|
|
isValidSeatSelection: false,
|
|
inputsWithValue: undefined,
|
|
seatmap: undefined,
|
|
panzoom: undefined,
|
|
inVenueXML: undefined,
|
|
seatmapXML: undefined,
|
|
}
|
|
};
|
|
|
|
},{}],105:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.addOpenSeatmap = exports.addCartDropdownBuyerTypes = exports.dropdownLegendOnChange = exports.addCartBack = exports.addCartClose = exports.addRedirectCheckout = exports.addModalCart = exports.addDropdownSeatmap = exports.addCloseModal = void 0;
|
|
var Communication = __importStar(require("./communication"));
|
|
var UI = __importStar(require("./ui"));
|
|
var config_1 = require("./config");
|
|
var JSC = __importStar(require("./jsc"));
|
|
var Cart = __importStar(require("./cart"));
|
|
var Legend = __importStar(require("./legend"));
|
|
var jBoxHelper = __importStar(require("./jBoxHelper"));
|
|
function addCloseModal() {
|
|
var btnCloseModal = jQuery("#btnCloseModal").get(0);
|
|
if (btnCloseModal)
|
|
btnCloseModal.addEventListener("click", function () { return Communication.sendEventToParent("child_closeDialog"); });
|
|
}
|
|
exports.addCloseModal = addCloseModal;
|
|
function addDropdownSeatmap() {
|
|
var dropdownSeatmap = document.getElementById("dropdownSeatmap");
|
|
if (dropdownSeatmap) {
|
|
dropdownSeatmap.addEventListener("change", function () {
|
|
UI.controlLoftloader("show");
|
|
UI.destroyCurrentSeatmap("#containerSeatmapInner");
|
|
Communication.needSeatmapXML(this.value);
|
|
});
|
|
}
|
|
}
|
|
exports.addDropdownSeatmap = addDropdownSeatmap;
|
|
function addModalCart() {
|
|
var btnCart = jQuery("#modalCart .uabb-button").get(0);
|
|
if (btnCart) {
|
|
btnCart.addEventListener("click", function () {
|
|
if (!config_1.config.state.selectedSeatsArr.length)
|
|
jBoxHelper.showJBoxNotice("Sie haben bislang keinen Platz ausgew\u00E4hlt.");
|
|
else if (config_1.config.state.cartChanged)
|
|
Communication.isValidSeatSelection();
|
|
else if (!config_1.config.state.cartChanged && config_1.config.state.isValidSeatSelection)
|
|
UI.fadeInCartModal();
|
|
else if (!config_1.config.state.cartChanged && !config_1.config.state.isValidSeatSelection)
|
|
jBoxHelper.showJBoxNotice("Auswahl nicht m\u00F6glich: Bitte lassen Sie keinen einzelnen Platz frei.");
|
|
});
|
|
}
|
|
}
|
|
exports.addModalCart = addModalCart;
|
|
function addRedirectCheckout(inUrl) {
|
|
if (!inUrl)
|
|
return;
|
|
var btnCheckout = jQuery("#modalCart-overlay #checkout .fl-button").get(0);
|
|
if (btnCheckout) {
|
|
btnCheckout.addEventListener("click", function () {
|
|
var message = {
|
|
message: {
|
|
url: inUrl,
|
|
},
|
|
from: "child",
|
|
event: "child_click_checkout",
|
|
date: Date.now()
|
|
};
|
|
Communication.sendMessage(message, "parent");
|
|
});
|
|
}
|
|
}
|
|
exports.addRedirectCheckout = addRedirectCheckout;
|
|
function addCartClose() {
|
|
var btnClose = jQuery("#modalCart-overlay .uabb-close-icon").get(0);
|
|
if (btnClose)
|
|
btnClose.addEventListener("click", function () { return Communication.sendEventToParent("child_show_dialog_titlebar"); });
|
|
}
|
|
exports.addCartClose = addCartClose;
|
|
function addCartBack() {
|
|
var btnBack = jQuery("#modalCart-overlay #goBack .fl-button").get(0);
|
|
if (btnBack)
|
|
btnBack.addEventListener("click", function () { return jQuery("#modalCart-overlay .uabb-close-icon").trigger("click"); });
|
|
}
|
|
exports.addCartBack = addCartBack;
|
|
function dropdownLegendOnChange(inSelector) {
|
|
var seatmap = config_1.config.state.seatmap;
|
|
var dropdownLegend = jQuery(inSelector).get(0);
|
|
dropdownLegend.addEventListener("change", function () {
|
|
var value = this.value;
|
|
var className = "._" + value;
|
|
Legend.changeDropdownLegendBGColor(inSelector, value, className);
|
|
if (value === "all") {
|
|
seatmap.find('unavailable').status('available');
|
|
JSC.setUnavailableSeats();
|
|
}
|
|
else {
|
|
seatmap.find('available').status('unavailable');
|
|
JSC.activateSeatsBySectionID(value);
|
|
JSC.setUnavailableSeats();
|
|
}
|
|
});
|
|
}
|
|
exports.dropdownLegendOnChange = dropdownLegendOnChange;
|
|
function addCartDropdownBuyerTypes(inSelector, inSeatObj) {
|
|
jQuery(inSelector).on('change', function () {
|
|
Cart.changedDropdownBuyerType(this, inSeatObj);
|
|
});
|
|
}
|
|
exports.addCartDropdownBuyerTypes = addCartDropdownBuyerTypes;
|
|
function addOpenSeatmap() {
|
|
jQuery("#openSeatmap").on("click", function () {
|
|
if (!config_1.config.childHasVenueXML)
|
|
Communication.sendEventToChild("parent_init_venue");
|
|
jQuery('html, body').css('overflow', 'hidden');
|
|
jQuery("#dialogSeatmap").dialog('open');
|
|
});
|
|
}
|
|
exports.addOpenSeatmap = addOpenSeatmap;
|
|
|
|
},{"./cart":100,"./communication":103,"./config":104,"./jBoxHelper":106,"./jsc":107,"./legend":108,"./ui":113}],106:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.createSeatTooltips = exports.showJBoxNotice = void 0;
|
|
var jbox_1 = __importDefault(require("jbox"));
|
|
var config_1 = require("./config");
|
|
var XMLHelper = __importStar(require("./xmlhelper"));
|
|
function showJBoxNotice(inContent, inAutoClose) {
|
|
if (inAutoClose === void 0) { inAutoClose = 5000; }
|
|
new jbox_1.default('Notice', {
|
|
position: { x: 'center', y: 'top' },
|
|
offset: { x: 0, y: 320 },
|
|
content: inContent,
|
|
autoClose: inAutoClose,
|
|
animation: { open: "zoomIn", close: "zoomOut" },
|
|
closeOnEsc: false,
|
|
closeButton: true,
|
|
closeOnMouseleave: false,
|
|
closeOnClick: false,
|
|
draggable: false,
|
|
color: "red",
|
|
stack: true,
|
|
showCountdown: true,
|
|
reposition: true,
|
|
responsiveWidth: true,
|
|
responsiveHeight: true,
|
|
});
|
|
}
|
|
exports.showJBoxNotice = showJBoxNotice;
|
|
function createSeatTooltips() {
|
|
new jbox_1.default("Tooltip", {
|
|
attach: jQuery(".seatCharts-seat"),
|
|
onOpen: function () {
|
|
showSeatTooltip(this);
|
|
},
|
|
});
|
|
}
|
|
exports.createSeatTooltips = createSeatTooltips;
|
|
function showSeatTooltip(jBox) {
|
|
var seatID = jBox.source[0].id;
|
|
var seat = config_1.config.state.layoutRows[seatID][5];
|
|
var row = config_1.config.state.layoutRows[seatID][4];
|
|
var sectionID = config_1.config.state.layoutRows[seatID][3];
|
|
var sectionDesc = XMLHelper.getSectionDescBySectionID(sectionID);
|
|
var tooltipContent = sectionDesc + "<br/>Reihe " + row + " Platz " + seat;
|
|
jBox.setContent(tooltipContent);
|
|
}
|
|
|
|
},{"./config":104,"./xmlhelper":115,"jbox":57}],107:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.addSeatmap = exports.selectSeatsInCart = exports.createArrMatrix = exports.splitSeatStr = exports.getSeatsKey = exports.setUnavailableSeats = exports.generateLegend = exports.generateMap = exports.getRowsNaming = exports.activateSeatsBySectionID = exports.getSeats = void 0;
|
|
var config_1 = require("./config");
|
|
var State = __importStar(require("./state"));
|
|
var Cart = __importStar(require("./cart"));
|
|
var CartButtons = __importStar(require("./cartButtons"));
|
|
function getSeats() {
|
|
var seatmapXML = config_1.config.state.seatmapXML;
|
|
var pricescaleArr = seatmapXML.seatmap[0].pricescale_config[0].pricescale;
|
|
var seatmapInitSeats = {};
|
|
for (var key in pricescaleArr) {
|
|
var seatsObj = {
|
|
"classes": "_" + pricescaleArr[key].id[0],
|
|
"seatsObj": pricescaleArr[key]
|
|
};
|
|
var seatsKey = String.fromCharCode(97 + parseInt(key)).toLocaleUpperCase();
|
|
seatmapInitSeats[seatsKey] = seatsObj;
|
|
}
|
|
return seatmapInitSeats;
|
|
}
|
|
exports.getSeats = getSeats;
|
|
function activateSeatsBySectionID(inValue) {
|
|
var _a;
|
|
var seatmapXML = config_1.config.state.seatmapXML;
|
|
var seatmap = config_1.config.state.seatmap;
|
|
var pricescaleArr = seatmapXML.seatmap[0].pricescale_config[0].pricescale;
|
|
var seatsArr = (_a = pricescaleArr.find(function (arr) {
|
|
return arr.id[0] === inValue;
|
|
})) === null || _a === void 0 ? void 0 : _a.mask[0].split(",");
|
|
seatmap.status(seatsArr, "available");
|
|
}
|
|
exports.activateSeatsBySectionID = activateSeatsBySectionID;
|
|
function getRowsNaming() {
|
|
var seatmapXML = config_1.config.state.seatmapXML;
|
|
var layout = seatmapXML.seatmap[0].layouts[0].layout[0];
|
|
var height = parseInt(layout.height[0]);
|
|
var namingArr = Array.from({ length: height }, function (_) { return ""; });
|
|
var rowsArr = layout.rows[0].row;
|
|
rowsArr.forEach(function (element) {
|
|
var index = parseInt(element.y_cell_coord[0]);
|
|
var seatsArr = element.seats[0].split("|");
|
|
var seatArr = splitSeatStr(seatsArr[0]);
|
|
var row = seatArr[4];
|
|
namingArr[index] = row;
|
|
});
|
|
return namingArr;
|
|
}
|
|
exports.getRowsNaming = getRowsNaming;
|
|
function generateMap() {
|
|
var seatmapXML = config_1.config.state.seatmapXML;
|
|
var layout = seatmapXML.seatmap[0].layouts[0].layout[0];
|
|
var rows = layout.rows[0].row;
|
|
var pricescaleArr = seatmapXML.seatmap[0].pricescale_config[0].pricescale;
|
|
var availabilityArr = seatmapXML.seatmap[0].view_modes[0].view_mode[0].availability[0];
|
|
var arrMatrix = createArrMatrix(parseInt(layout.height[0]), parseInt(layout.width[0]), "_");
|
|
arrMatrix = enterSeatsInMatrix(rows, arrMatrix, pricescaleArr, availabilityArr);
|
|
return arrMatrix.map(function (element) { return element.join(""); });
|
|
}
|
|
exports.generateMap = generateMap;
|
|
function generateLegend(inNode) {
|
|
var seatmapXML = config_1.config.state.seatmapXML;
|
|
var venueXML = config_1.config.state.inVenueXML;
|
|
var pricescaleArr = seatmapXML.seatmap[0].pricescale_config[0].pricescale;
|
|
var venuePricescaleArr = venueXML.venue[0].pricescales[0].pricescale;
|
|
return {
|
|
node: jQuery(inNode),
|
|
items: createLegendItems(pricescaleArr, venuePricescaleArr)
|
|
};
|
|
}
|
|
exports.generateLegend = generateLegend;
|
|
function setUnavailableSeats() {
|
|
var seatmapXML = config_1.config.state.seatmapXML;
|
|
var seatmap = config_1.config.state.seatmap;
|
|
var availabilityArr = seatmapXML.seatmap[0].view_modes[0].view_mode[0].availability[0];
|
|
if (availabilityArr.unavailable_unselectable_mask[0] !== "") {
|
|
var unavailableArr = availabilityArr.unavailable_unselectable_mask[0].split(",");
|
|
seatmap.status(unavailableArr, "unavailable");
|
|
}
|
|
}
|
|
exports.setUnavailableSeats = setUnavailableSeats;
|
|
function getSeatsKey(inSeatID, inPricescaleArr) {
|
|
for (var key in inPricescaleArr) {
|
|
if (inPricescaleArr[key].mask[0].includes(inSeatID))
|
|
return String.fromCharCode(97 + parseInt(key)).toLocaleUpperCase();
|
|
}
|
|
return undefined;
|
|
}
|
|
exports.getSeatsKey = getSeatsKey;
|
|
function splitSeatStr(inSeatStr) {
|
|
return inSeatStr.split(",").map(function (item) { return item.trim(); });
|
|
}
|
|
exports.splitSeatStr = splitSeatStr;
|
|
function createArrMatrix(inNumrows, inNumcols, inCharacter) {
|
|
return Array(inNumrows).fill(null).map(function () { return Array(inNumcols).fill(inCharacter); });
|
|
}
|
|
exports.createArrMatrix = createArrMatrix;
|
|
function selectSeatsInCart() {
|
|
var seatmap = config_1.config.state.seatmap;
|
|
config_1.config.state.selectedSeatsArr.forEach(function (arr) {
|
|
var seatID = arr[0];
|
|
if (seatmap.get(seatID))
|
|
seatmap.status(seatID, "selected");
|
|
});
|
|
}
|
|
exports.selectSeatsInCart = selectSeatsInCart;
|
|
function addSeatmap(inSelector, inMap, inRowsNaming, inSeats, inLegend) {
|
|
var containerSeatmap = window.jQuery(inSelector);
|
|
config_1.config.state.seatmap = containerSeatmap.seatCharts({
|
|
naming: {
|
|
top: false,
|
|
left: false,
|
|
rows: inRowsNaming,
|
|
},
|
|
map: inMap,
|
|
seats: inSeats,
|
|
legend: inLegend,
|
|
click: function () {
|
|
return clickedSeat(this);
|
|
}
|
|
});
|
|
}
|
|
exports.addSeatmap = addSeatmap;
|
|
function createLegendItems(pricescaleArr, venuePricescaleArr) {
|
|
return pricescaleArr.map(function (arr, index) {
|
|
var _a;
|
|
var id = arr.id[0];
|
|
var seatsKey = String.fromCharCode(97 + index).toLocaleUpperCase();
|
|
var desc = (_a = venuePricescaleArr.find(function (obj) { return obj.id[0] === id; })) === null || _a === void 0 ? void 0 : _a.desc[0];
|
|
var description = desc + " \u20AC" + pricescaleArr[index].ref_price[0];
|
|
return [seatsKey, "available", description];
|
|
});
|
|
}
|
|
function enterSeatsInMatrix(inRows, inArrMatrix, inPricescaleArr, inAvailabilityArr) {
|
|
var availableArr = inAvailabilityArr.available_selectable_mask[0].split(",");
|
|
var unavailableArr = inAvailabilityArr.unavailable_unselectable_mask[0].split(",");
|
|
inRows.forEach(function (element) {
|
|
var row = element;
|
|
var Y = parseInt(row.y_cell_coord[0]) - 1;
|
|
var seatsArr = row.seats[0].split("|");
|
|
seatsArr.forEach(function (element) {
|
|
var seatStr = element;
|
|
var seatArr = splitSeatStr(seatStr);
|
|
if (!availableArr.includes(seatArr[0]) && !unavailableArr.includes(seatArr[0]))
|
|
return;
|
|
var X = parseInt(seatArr[2]) - 1;
|
|
var seatsKey = getSeatsKey(seatArr[0], inPricescaleArr);
|
|
if (seatsKey)
|
|
inArrMatrix[Y][X] = seatsKey + "[" + seatArr[0] + ", ]";
|
|
config_1.config.state.layoutRows[seatArr[0]] = seatArr;
|
|
});
|
|
});
|
|
return inArrMatrix;
|
|
}
|
|
function clickedSeat(inSeatmap) {
|
|
if (inSeatmap.status() == 'available') {
|
|
return clickAvailableSeat(inSeatmap);
|
|
}
|
|
else if (inSeatmap.status() === "selected") {
|
|
return clickedSelectedSeat(inSeatmap);
|
|
}
|
|
else if (inSeatmap.status() == 'unavailable') {
|
|
return "unavailable";
|
|
}
|
|
else {
|
|
return inSeatmap.style();
|
|
}
|
|
}
|
|
function clickAvailableSeat(inSeatmap) {
|
|
var selectedSeat = inSeatmap.settings;
|
|
console.log(selectedSeat);
|
|
if (State.maximumSelectedSeatsReached(selectedSeat))
|
|
return "available";
|
|
State.addSeatToState(selectedSeat);
|
|
Cart.calcOverallPrice();
|
|
CartButtons.setBtnCartText();
|
|
return "selected";
|
|
}
|
|
function clickedSelectedSeat(inSeatmap) {
|
|
var selectedSeat = inSeatmap.settings;
|
|
State.removeSeatFromState(selectedSeat);
|
|
Cart.calcOverallPrice();
|
|
CartButtons.setBtnCartText();
|
|
return "available";
|
|
}
|
|
|
|
},{"./cart":100,"./cartButtons":101,"./config":104,"./state":111}],108:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.changeDropdownLegendBGColor = exports.convertLegendToDropdown = void 0;
|
|
function convertLegendToDropdown(inID) {
|
|
jQuery('ul.seatCharts-legendList').each(function () {
|
|
var select = jQuery(document.createElement('select'))
|
|
.insertBefore(jQuery(this).hide());
|
|
select.attr({ id: inID });
|
|
appendFirstLegendOption(select);
|
|
appendLegendOptions(this, select);
|
|
});
|
|
}
|
|
exports.convertLegendToDropdown = convertLegendToDropdown;
|
|
function appendLegendOptions(element, inSelect) {
|
|
jQuery('>li', element).each(function () {
|
|
var className = jQuery(this)[0].children[0].classList[3];
|
|
var val = className.substring(1);
|
|
var text = jQuery(this)[0].children[1].innerText;
|
|
appendLegendOption(inSelect, className, val, text);
|
|
});
|
|
}
|
|
function appendLegendOption(inSelect, className, val, text) {
|
|
var option = jQuery('<option/>');
|
|
option.attr({ 'value': val, 'class': className }).text(text);
|
|
inSelect.append(option);
|
|
}
|
|
function appendFirstLegendOption(inSelect) {
|
|
var option = jQuery('<option/>');
|
|
option.attr({ 'value': 'all' }).text('Alle Preiskategorien');
|
|
option.css("color", "#5c5c5c");
|
|
inSelect.append(option);
|
|
}
|
|
function changeDropdownLegendBGColor(inSelector, inValue, inClassName) {
|
|
var bgColor = "#fafafa";
|
|
var color = "#5c5c5c";
|
|
if (inValue !== "all") {
|
|
color = "white";
|
|
bgColor = jQuery(inClassName).css("background-color");
|
|
}
|
|
jQuery(inSelector).css("color", color);
|
|
jQuery(inSelector).css("background-color", bgColor);
|
|
jQuery(inSelector + " option[value=\"all\"]").css("color", color);
|
|
}
|
|
exports.changeDropdownLegendBGColor = changeDropdownLegendBGColor;
|
|
|
|
},{}],109:[function(require,module,exports){
|
|
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.unbindPanzoomEvents = exports.addPanzoom = void 0;
|
|
var panzoom_1 = __importDefault(require("@panzoom/panzoom"));
|
|
var config_1 = require("./config");
|
|
function addPanzoom(inSelector, inBtnZoomIn, inBtnZoomOut, inBtnResetZoom) {
|
|
if (inBtnZoomIn === void 0) { inBtnZoomIn = undefined; }
|
|
if (inBtnZoomOut === void 0) { inBtnZoomOut = undefined; }
|
|
if (inBtnResetZoom === void 0) { inBtnResetZoom = undefined; }
|
|
var container = jQuery(inSelector).get(0);
|
|
if (container) {
|
|
var panzoom = panzoom_1.default(container, {
|
|
maxScale: 5,
|
|
animate: false,
|
|
overflow: "hidden",
|
|
startScale: "0.66"
|
|
});
|
|
addPanzoomEvents(inBtnZoomIn, inBtnZoomOut, inBtnResetZoom, container.parentElement, panzoom);
|
|
return panzoom;
|
|
}
|
|
return undefined;
|
|
}
|
|
exports.addPanzoom = addPanzoom;
|
|
function addPanzoomEvents(inBtnZoomIn, inBtnZoomOut, inBtnResetZoom, containerParent, panzoom) {
|
|
var eventMapping = [
|
|
{ Selector: inBtnZoomIn, PanzoomFunction: panzoom.zoomIn, Type: "Click" },
|
|
{ Selector: inBtnZoomOut, PanzoomFunction: panzoom.zoomOut, Type: "Click" },
|
|
{ Selector: inBtnResetZoom, PanzoomFunction: panzoom.reset, Type: "Click" },
|
|
{ HTMLElement: containerParent, PanzoomFunction: panzoom.zoomWithWheel, Type: "wheel" }
|
|
];
|
|
eventMapping.map(function (event) {
|
|
if (event.Selector) {
|
|
var btn = jQuery(event.Selector).get(0);
|
|
if (btn)
|
|
btn.addEventListener(event.Type, event.PanzoomFunction);
|
|
}
|
|
else if (event.HTMLElement) {
|
|
if (event.Type === "wheel")
|
|
event.HTMLElement.addEventListener(event.Type, event.PanzoomFunction);
|
|
}
|
|
});
|
|
}
|
|
function unbindPanzoomEvents(inSelector) {
|
|
var _a;
|
|
var container = jQuery(inSelector).get(0);
|
|
(_a = container.parentElement) === null || _a === void 0 ? void 0 : _a.removeEventListener('wheel', config_1.config.state.panzoom.zoomWithWheel);
|
|
}
|
|
exports.unbindPanzoomEvents = unbindPanzoomEvents;
|
|
|
|
},{"./config":104,"@panzoom/panzoom":27}],110:[function(require,module,exports){
|
|
"use strict";
|
|
var __assign = (this && this.__assign) || function () {
|
|
__assign = Object.assign || function(t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.getEventInfo = exports.getSMAP = exports.getVenueImage = exports.getAdditionalInputs = exports.getImportantNote = exports.getInputs = exports.getVenueLocation = void 0;
|
|
var config_1 = require("./config");
|
|
var jQuery = require("jquery");
|
|
var utils_1 = __importDefault(require("./utils"));
|
|
function getVenueLocation() {
|
|
var spanArr = [];
|
|
jQuery(".venue span").each(function () {
|
|
spanArr.push(jQuery(this).text());
|
|
});
|
|
return spanArr.join(", ");
|
|
}
|
|
exports.getVenueLocation = getVenueLocation;
|
|
function getInputs(inContent) {
|
|
var parsedHTML = jQuery.parseHTML(inContent);
|
|
var inputs = {};
|
|
jQuery(parsedHTML).find('input').each(function () {
|
|
var name = this.name;
|
|
var value = this.value;
|
|
if (value !== '')
|
|
inputs[name] = value;
|
|
});
|
|
return inputs;
|
|
}
|
|
exports.getInputs = getInputs;
|
|
function getImportantNote() {
|
|
if (jQuery(".important_note").length) {
|
|
var importantNote = jQuery(".important_note")[0].textContent;
|
|
if (importantNote === null || importantNote === void 0 ? void 0 : importantNote.trim().length) {
|
|
var importantNoteEncoded = encodeURIComponent(importantNote);
|
|
return {
|
|
"importantNote": importantNote,
|
|
"importantNoteEncoded": importantNoteEncoded
|
|
};
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
exports.getImportantNote = getImportantNote;
|
|
function getAdditionalInputs(inContent) {
|
|
var event = inContent.match(/event:"(.+?)"/)[1];
|
|
var holdcode = inContent.match(/holdcode:"(.+?)"/)[1];
|
|
var posturlRaw = inContent.match(/posturl:"(.+?)"/)[1];
|
|
var posturlRawDecoded = decodeURIComponent(posturlRaw);
|
|
var posturl = decodeURIComponent(posturlRaw + "&event=" + event + "&holdcode=" + holdcode + "&nocache=0&inclpkg=Y&incloffer=Y&inclcartdetails=Y&inclCart=Y&inclvenue=Y");
|
|
var venueLocation = getVenueLocation();
|
|
var ticketPurchaseUrl = posturlRawDecoded.split("?")[0].split('/').slice(0, -1).join('/') + "/TicketPurchase";
|
|
return {
|
|
"event": event,
|
|
"holdcode": holdcode,
|
|
"posturlRaw": posturlRaw,
|
|
"posturlRawDecoded": posturlRawDecoded,
|
|
"posturl": posturl,
|
|
"venueLocation": venueLocation,
|
|
"ticketPurchaseUrl": ticketPurchaseUrl
|
|
};
|
|
}
|
|
exports.getAdditionalInputs = getAdditionalInputs;
|
|
function getVenueImage() {
|
|
var img = jQuery("#static_venue_map img").get(0);
|
|
if (img) {
|
|
return {
|
|
venueImageSrc: img.src,
|
|
venueImageHeight: img.height,
|
|
venueImageWidth: img.width
|
|
};
|
|
}
|
|
return undefined;
|
|
}
|
|
exports.getVenueImage = getVenueImage;
|
|
function getSMAP() {
|
|
if (!jQuery("#seating_map_url").length)
|
|
return undefined;
|
|
var str = jQuery("#seating_map_url a").attr("onclick");
|
|
var re = /openNewWindow\(\'(\d+)\'/;
|
|
var found = str.match(re);
|
|
return found ? found[1] : undefined;
|
|
}
|
|
exports.getSMAP = getSMAP;
|
|
function getEventInfo() {
|
|
var venueXML = config_1.config.state.inVenueXML;
|
|
var sectionArr = venueXML.master_config[0].section_inventory[0].section;
|
|
var eventObj = venueXML.event[0];
|
|
var event = venueXML.event[0];
|
|
var venue_config = venueXML.venue_config[0];
|
|
var dateObj = new Date(parseInt(event.year[0]), parseInt(event.month[0]) - 1, parseInt(event.day[0]), parseInt(event.hour[0]), parseInt(event.minute[0]));
|
|
var start = [dateObj.toLocaleString(["de-DE"], { weekday: "long", day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", timeZoneName: "short" })];
|
|
var weekday = [utils_1.default.getDayName(dateObj, "de-DE")];
|
|
var seats_available = sectionArr.map(function (item) { return parseInt(item.available[0]); }).reduce(function (prev, curr) { return prev + curr; });
|
|
var eventExtend = {
|
|
venue_config_capacity: venue_config.capacity,
|
|
venue_config_code: venue_config.code,
|
|
venue_config_desc: venue_config.desc,
|
|
venue_config_id: venue_config.id,
|
|
venue_config_nav_image: venue_config.nav_image,
|
|
venue_config_nav_image_height: venue_config.nav_image_height,
|
|
venue_config_nav_image_width: venue_config.nav_image_width,
|
|
start: start,
|
|
weekday: weekday,
|
|
seats_available: seats_available,
|
|
};
|
|
return __assign(__assign({}, eventObj), eventExtend);
|
|
}
|
|
exports.getEventInfo = getEventInfo;
|
|
|
|
},{"./config":104,"./utils":114,"jquery":58}],111:[function(require,module,exports){
|
|
"use strict";
|
|
var __assign = (this && this.__assign) || function () {
|
|
__assign = Object.assign || function(t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.maximumSelectedSeatsReached = exports.removeSeatFromState = exports.addSeatToState = void 0;
|
|
var config_1 = require("./config");
|
|
var XMLHelper = __importStar(require("./xmlhelper"));
|
|
var jBoxHelper = __importStar(require("./jBoxHelper"));
|
|
function addSeatToState(inSelectedSeat) {
|
|
addSeatObjToState(inSelectedSeat);
|
|
var pricescaleID = config_1.config.state.selectedSeatsObj[inSelectedSeat.id].data.seatsObj.id[0];
|
|
var pricescaleObj = XMLHelper.getVenuePriceStructurePropertyByPricescaleID(pricescaleID);
|
|
if (pricescaleObj) {
|
|
var firstBuyerTypeID = pricescaleObj.buyer_type[0].id[0];
|
|
var buyerTypeCode = XMLHelper.getBuyerTypeCodeByBuyerTypeID(firstBuyerTypeID);
|
|
var selectedSeatsArrItem = [inSelectedSeat.id, firstBuyerTypeID, buyerTypeCode];
|
|
addSeatsItemToState(selectedSeatsArrItem);
|
|
}
|
|
else
|
|
console.warn("Cannot find corresponding venueXML pricescaleObj for pricescale with ID " + pricescaleID);
|
|
}
|
|
exports.addSeatToState = addSeatToState;
|
|
function removeSeatFromState(inSelectedSeat) {
|
|
delete config_1.config.state.selectedSeatsObj[inSelectedSeat.id];
|
|
var index = config_1.config.state.selectedSeatsArr.findIndex(function (arr) { return arr[0] === inSelectedSeat.id; });
|
|
config_1.config.state.selectedSeatsArr.splice(index, 1);
|
|
config_1.config.state.cartChanged = true;
|
|
if (!config_1.config.state.selectedSeatsArr.length)
|
|
jQuery("#modalCart-overlay").hide();
|
|
}
|
|
exports.removeSeatFromState = removeSeatFromState;
|
|
function maximumSelectedSeatsReached(inSeatObj) {
|
|
var seatmap = config_1.config.state.seatmap;
|
|
if (config_1.config.state.selectedSeatsArr.length >= config_1.config.maxSelectedSeats) {
|
|
jBoxHelper.showJBoxNotice("Sie k\u00F6nnen maximal " + config_1.config.maxSelectedSeats + " Pl\u00E4tze ausw\u00E4hlen.");
|
|
seatmap.status(inSeatObj.id, "available");
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
exports.maximumSelectedSeatsReached = maximumSelectedSeatsReached;
|
|
function addSeatsItemToState(inItem) {
|
|
if (inItem.every(function (v) { return v !== ("" || undefined || null); })) {
|
|
config_1.config.state.selectedSeatsArr.push(inItem);
|
|
config_1.config.state.cartChanged = true;
|
|
}
|
|
}
|
|
function addSeatObjToState(inSelectedSeat) {
|
|
var _a;
|
|
var seatID = inSelectedSeat.id;
|
|
var seatObj = (_a = {},
|
|
_a[seatID] = inSelectedSeat,
|
|
_a);
|
|
config_1.config.state.selectedSeatsObj = __assign(__assign({}, config_1.config.state.selectedSeatsObj), seatObj);
|
|
}
|
|
|
|
},{"./config":104,"./jBoxHelper":106,"./xmlhelper":115}],112:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.addTrims = void 0;
|
|
var config_1 = require("./config");
|
|
function addTrims() {
|
|
var seatmapXML = config_1.config.state.seatmapXML;
|
|
var trimArr = seatmapXML.seatmap[0].trims[0].trim;
|
|
trimArr.forEach(function (arr) {
|
|
var _a = arr.coord[0].split(",").map(Number), xTrim = _a[0], yTrim = _a[1];
|
|
var textArr = arr.text[0].split(";").filter(Boolean);
|
|
var x = xTrim / 20;
|
|
var y = Math.round(yTrim / 21.25);
|
|
decodeTrim(textArr, x, y);
|
|
});
|
|
}
|
|
exports.addTrims = addTrims;
|
|
function decodeTrim(textArr, x, y) {
|
|
var specialChar = new Map([
|
|
["Ž", "Ä"],
|
|
["™", "Ö"],
|
|
["š", "Ü"],
|
|
["„", "ä"],
|
|
["”", "ö"],
|
|
["", "ü"],
|
|
["á", "ß"]
|
|
]);
|
|
textArr.map(function (element, index) {
|
|
var character = specialChar.has(element) ? specialChar.get(element) : decodeNormalTrim(element);
|
|
if (character) {
|
|
var trimPos = getJSCTrimPos(x, y, index);
|
|
applyTrim(character, trimPos);
|
|
}
|
|
});
|
|
}
|
|
function decodeNormalTrim(element) {
|
|
var charCode = element.replace(/^\&\#/, "0");
|
|
return String.fromCharCode(parseInt(charCode, 16));
|
|
}
|
|
function applyTrim(inCharacter, inTrimPos) {
|
|
var regex = /[^a-zA-Z0-9äöüÄÖÜß$]/;
|
|
if (!regex.test(inCharacter)) {
|
|
console.log(inCharacter + " -> " + inTrimPos.xJSC + " " + inTrimPos.yJSC);
|
|
jQuery(".seatCharts-row")[inTrimPos.yJSC].children[inTrimPos.xJSC].innerHTML = "<span class=\"trimChar\">" + inCharacter + "</span>";
|
|
}
|
|
}
|
|
function getJSCTrimPos(inX, inY, index) {
|
|
return {
|
|
x: inX,
|
|
y: inY,
|
|
xJSC: (inX - 1) + index,
|
|
yJSC: inY - 1
|
|
};
|
|
}
|
|
|
|
},{"./config":104}],113:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.adjustUIToLoading = exports.generatePricescaleCSS = exports.fadeInCartModal = exports.changeVenueImage = exports.controlLoftloader = exports.destroyCurrentSeatmap = exports.createDialog = exports.setEventInfo = exports.setOptionSelect = void 0;
|
|
var Communication = __importStar(require("./communication"));
|
|
var config_1 = require("./config");
|
|
var Events = __importStar(require("./events"));
|
|
var Panzoom = __importStar(require("./panzoom"));
|
|
var CartButtons = __importStar(require("./cartButtons"));
|
|
function setOptionSelect(inSeatmapListing, inId) {
|
|
var seatmapDropdown = document.getElementById(inId);
|
|
if (seatmapDropdown) {
|
|
for (var _i = 0, inSeatmapListing_1 = inSeatmapListing; _i < inSeatmapListing_1.length; _i++) {
|
|
var seatmapObj = inSeatmapListing_1[_i];
|
|
var opt = document.createElement('option');
|
|
opt.value = seatmapObj.id[0];
|
|
opt.innerHTML = seatmapObj.desc[0];
|
|
seatmapDropdown.appendChild(opt);
|
|
}
|
|
}
|
|
}
|
|
exports.setOptionSelect = setOptionSelect;
|
|
function setEventInfo(inEventInfo) {
|
|
var inputsWithValue = config_1.config.state.inputsWithValue;
|
|
jQuery("#eventInfoDesc span.fl-heading-text")[0].childNodes[0].textContent = inEventInfo.desc[0];
|
|
jQuery("#eventInfoDate p")[0].childNodes[0].textContent = inEventInfo.start[0];
|
|
jQuery("#eventInfoLocation p")[0].childNodes[0].textContent = inputsWithValue.venueLocation;
|
|
jQuery("#eventInfoCapacity p")[0].childNodes[0].textContent = "Verf\u00FCgbare Pl\u00E4tze: " + inEventInfo.seats_available + " von " + inEventInfo.venue_config_capacity[0];
|
|
}
|
|
exports.setEventInfo = setEventInfo;
|
|
function createDialog() {
|
|
var iframeHTML = "<iframe id='iframeSeatmap' scrolling='no' frameborder='0' marginwidth='0' marginheight='0' allowfullscreen width='100%' />";
|
|
var src = config_1.config.branch === "staging" ? config_1.config.urlSeatmapStaging : config_1.config.urlSeatmapMaster;
|
|
jQuery("#dialogSeatmap").append(jQuery(iframeHTML)
|
|
.attr("src", src))
|
|
.dialog({
|
|
modal: true,
|
|
autoOpen: false,
|
|
closeOnEscape: true,
|
|
draggable: false,
|
|
hide: true,
|
|
show: true,
|
|
resizable: false,
|
|
title: "",
|
|
width: "100%",
|
|
height: "auto",
|
|
close: function () { return jQuery("html, body").css("overflow", "auto"); },
|
|
});
|
|
Events.addOpenSeatmap();
|
|
}
|
|
exports.createDialog = createDialog;
|
|
function destroyCurrentSeatmap(inSelector) {
|
|
if (config_1.config.state.panzoom)
|
|
Panzoom.unbindPanzoomEvents(inSelector);
|
|
jQuery("#containerSeatmapInner").remove();
|
|
jQuery("#htmlSeatmapInner .fl-html").removeAttr("style");
|
|
jQuery("#htmlSeatmapInner .fl-html").append('<div id="containerSeatmapInner"></div>');
|
|
jQuery("#JSCLegendInner").remove();
|
|
jQuery("#JSCLegend .fl-html").append('<div id="JSCLegendInner"></div>');
|
|
}
|
|
exports.destroyCurrentSeatmap = destroyCurrentSeatmap;
|
|
function controlLoftloader(inSwitch) {
|
|
if (inSwitch === "show")
|
|
jQuery("body").removeClass("loaded loftloader-loaded");
|
|
else if (inSwitch === "hide")
|
|
jQuery("body").addClass("loaded loftloader-loaded");
|
|
}
|
|
exports.controlLoftloader = controlLoftloader;
|
|
function changeVenueImage() {
|
|
var inputsWithValue = config_1.config.state.inputsWithValue;
|
|
if (inputsWithValue.venueImageSrc !== undefined)
|
|
jQuery("#venueImage img").attr("src", inputsWithValue.venueImageSrc);
|
|
}
|
|
exports.changeVenueImage = changeVenueImage;
|
|
function fadeInCartModal() {
|
|
jQuery("#modalCart-overlay").fadeIn(300);
|
|
Communication.sendEventToParent("child_hide_dialog_titlebar");
|
|
}
|
|
exports.fadeInCartModal = fadeInCartModal;
|
|
function generatePricescaleCSS() {
|
|
var venueXML = config_1.config.state.inVenueXML;
|
|
var venuePricescalesArr = venueXML.venue[0].pricescales[0].pricescale;
|
|
return venuePricescalesArr.map(function (arr) {
|
|
var ID = arr.id[0];
|
|
var color = "#" + arr.color[0] + " !important";
|
|
return "._" + ID + " { background-color: " + color + "; }";
|
|
}).join("\r\n");
|
|
}
|
|
exports.generatePricescaleCSS = generatePricescaleCSS;
|
|
function adjustUIToLoading() {
|
|
CartButtons.showHideBtnCartLoading("show");
|
|
jQuery("#modalCart i").hide();
|
|
jQuery("#modalCart .uabb-button-text").addClass("dot-pulse");
|
|
}
|
|
exports.adjustUIToLoading = adjustUIToLoading;
|
|
|
|
},{"./cartButtons":101,"./communication":103,"./config":104,"./events":105,"./panzoom":109}],114:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
var Utils = (function () {
|
|
function Utils() {
|
|
}
|
|
Utils.waitForElement = function (inSelector, inCallback, inSwitch, inCheckIntervalInMs, inTimeoutInMs) {
|
|
if (inSwitch === void 0) { inSwitch = "selector"; }
|
|
if (inCheckIntervalInMs === void 0) { inCheckIntervalInMs = 1000; }
|
|
if (inTimeoutInMs === void 0) { inTimeoutInMs = 10000; }
|
|
var startTimeInMs = Date.now();
|
|
(function loopSearch() {
|
|
var element = inSwitch === "selector" ? jQuery(inSelector).get(0) : Utils.getSeatmapElement();
|
|
if (element) {
|
|
console.log("ready");
|
|
inCallback();
|
|
}
|
|
else {
|
|
console.log("Repeating for " + inSwitch);
|
|
setTimeout(function () {
|
|
if (inTimeoutInMs && Date.now() - startTimeInMs > inTimeoutInMs)
|
|
return;
|
|
loopSearch();
|
|
}, inCheckIntervalInMs);
|
|
}
|
|
})();
|
|
};
|
|
Utils.getSeatmapElement = function () {
|
|
var seatCharts = window.jQuery("#containerSeatmap").seatCharts;
|
|
return Utils.isFunction(seatCharts);
|
|
};
|
|
Utils.waitForSeatmap = function (inCallback) {
|
|
var seatCharts = window.jQuery("#containerSeatmap").seatCharts;
|
|
this.waitForElement(seatCharts, inCallback, "seatmap");
|
|
};
|
|
Utils.querySelector = function (selector) {
|
|
if (document.querySelector(selector) != null)
|
|
return true;
|
|
else
|
|
return false;
|
|
};
|
|
Utils.isFunction = function (inSelector) {
|
|
return typeof inSelector === "function" ? true : false;
|
|
};
|
|
Utils.inject = function (inContent, inType, inLoc) {
|
|
if (inType === void 0) { inType = "js"; }
|
|
if (inLoc === void 0) { inLoc = "head"; }
|
|
var script;
|
|
switch (inType) {
|
|
case "js":
|
|
script = document.createElement('script');
|
|
script.type = 'text/javascript';
|
|
script.src = inContent;
|
|
break;
|
|
case "css":
|
|
script = document.createElement('link');
|
|
script.type = 'text/css';
|
|
script.rel = "stylesheet";
|
|
script.href = inContent;
|
|
break;
|
|
case "cssCustom":
|
|
script = document.createElement('style');
|
|
script.type = 'text/css';
|
|
script.innerHTML = inContent;
|
|
break;
|
|
case "script":
|
|
script = document.createElement('script');
|
|
script.type = 'text/javascript';
|
|
script.innerHTML = inContent;
|
|
break;
|
|
default:
|
|
script = undefined;
|
|
break;
|
|
}
|
|
if (script)
|
|
Utils.appendScript(script, inLoc);
|
|
};
|
|
Utils.appendScript = function (inScript, inLoc) {
|
|
if (inLoc === "body")
|
|
document.body.appendChild(inScript);
|
|
else if (inLoc === "head")
|
|
document.head.appendChild(inScript);
|
|
};
|
|
Utils.getDayName = function (inDate, inLocale) {
|
|
return inDate.toLocaleDateString(inLocale, { weekday: 'long' });
|
|
};
|
|
return Utils;
|
|
}());
|
|
exports.default = Utils;
|
|
|
|
},{}],115:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.generateSelectedSeatIndexes = exports.getBuyerTypesByPricescaleID = exports.getVenuePriceStructurePropertyByPricescaleID = exports.getPriceByBuyerTypeID = exports.getBuyerTypeCodeByBuyerTypeID = exports.getVenuePricescalePropertyByPricescaleID = exports.getSectionDescBySectionID = exports.processSMAP = void 0;
|
|
var config_1 = require("./config");
|
|
function processSMAP() {
|
|
var inputsWithValue = config_1.config.state.inputsWithValue;
|
|
if (!inputsWithValue.smap)
|
|
return;
|
|
var smapArr = inputsWithValue.smap.split("").map(Number);
|
|
if (!smapArr[0])
|
|
jQuery("#eventInfoCapacity").hide();
|
|
}
|
|
exports.processSMAP = processSMAP;
|
|
function getSectionDescBySectionID(inSectionID) {
|
|
var _a;
|
|
var venueXML = config_1.config.state.inVenueXML;
|
|
var sectionArr = venueXML.master_config[0].section_config[0].section;
|
|
return (_a = sectionArr.find(function (arr) { return inSectionID === arr.id[0]; })) === null || _a === void 0 ? void 0 : _a.desc[0];
|
|
}
|
|
exports.getSectionDescBySectionID = getSectionDescBySectionID;
|
|
function getVenuePricescalePropertyByPricescaleID(inProperty, inPricescaleID) {
|
|
var _a;
|
|
var venueXML = config_1.config.state.inVenueXML;
|
|
var venuePricescaleArr = venueXML.venue[0].pricescales[0].pricescale;
|
|
return (_a = venuePricescaleArr.find(function (obj) { return obj.id[0] === inPricescaleID ? obj : undefined; })) === null || _a === void 0 ? void 0 : _a[inProperty][0];
|
|
}
|
|
exports.getVenuePricescalePropertyByPricescaleID = getVenuePricescalePropertyByPricescaleID;
|
|
function getBuyerTypeCodeByBuyerTypeID(inBuyerTypeID) {
|
|
var _a;
|
|
var venueXML = config_1.config.state.inVenueXML;
|
|
var venueBuyerTypeArr = venueXML.venue[0].buyer_types[0].buyer_type;
|
|
return (_a = venueBuyerTypeArr.find(function (arr) { return inBuyerTypeID === arr.id[0]; })) === null || _a === void 0 ? void 0 : _a.code[0];
|
|
}
|
|
exports.getBuyerTypeCodeByBuyerTypeID = getBuyerTypeCodeByBuyerTypeID;
|
|
function getPriceByBuyerTypeID(inBuyertypeID, inPricescaleObj) {
|
|
var _a;
|
|
var price = (_a = inPricescaleObj === null || inPricescaleObj === void 0 ? void 0 : inPricescaleObj.buyer_type.find(function (arr) { return arr.id[0] === inBuyertypeID; })) === null || _a === void 0 ? void 0 : _a.price[0];
|
|
return price ? parseFloat(price) : undefined;
|
|
}
|
|
exports.getPriceByBuyerTypeID = getPriceByBuyerTypeID;
|
|
function getVenuePriceStructurePropertyByPricescaleID(inID) {
|
|
var venueXML = config_1.config.state.inVenueXML;
|
|
var venuePricescaleArr = venueXML.price_structure[0].pricescale;
|
|
return venuePricescaleArr.find(function (obj) { return obj.id[0] === inID; });
|
|
}
|
|
exports.getVenuePriceStructurePropertyByPricescaleID = getVenuePriceStructurePropertyByPricescaleID;
|
|
function getBuyerTypesByPricescaleID(inPricescaleID) {
|
|
var buyerTypesArr = findBuyerTypesArrByPricescaleID(inPricescaleID);
|
|
return buyerTypesArr ? buyerTypesArr.map(function (arr) { return [arr.id[0], arr.price[0], getBuyerTypeDesc(arr)]; }) : undefined;
|
|
}
|
|
exports.getBuyerTypesByPricescaleID = getBuyerTypesByPricescaleID;
|
|
function generateSelectedSeatIndexes() {
|
|
return (config_1.config.state.selectedSeatsArr.map(function (arr) { return arr.join(","); })).join("|");
|
|
}
|
|
exports.generateSelectedSeatIndexes = generateSelectedSeatIndexes;
|
|
function findBuyerTypesArrByPricescaleID(inPricescaleID) {
|
|
var _a;
|
|
var venueXML = config_1.config.state.inVenueXML;
|
|
var venuePricescaleArr = venueXML.price_structure[0].pricescale;
|
|
return (_a = venuePricescaleArr.find(function (obj) { return obj.id[0] === inPricescaleID; })) === null || _a === void 0 ? void 0 : _a.buyer_type;
|
|
}
|
|
function getBuyerTypeDesc(inArr) {
|
|
var _a;
|
|
var venueXML = config_1.config.state.inVenueXML;
|
|
var buyerTypeArr = venueXML.venue[0].buyer_types[0].buyer_type;
|
|
return (_a = buyerTypeArr.find(function (obj) { return obj.id[0] === inArr.id[0] ? obj.desc[0] : undefined; })) === null || _a === void 0 ? void 0 : _a.desc[0];
|
|
}
|
|
|
|
},{"./config":104}],116:[function(require,module,exports){
|
|
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
var jQuery = require("jquery");
|
|
var Communication = __importStar(require("./modules/communication"));
|
|
var config_1 = require("./modules/config");
|
|
var utils_1 = __importDefault(require("./modules/utils"));
|
|
var Events = __importStar(require("./modules/events"));
|
|
require("jbox/dist/jBox.all.css");
|
|
var Cart = __importStar(require("./modules/cart"));
|
|
var BookingBtn = __importStar(require("./modules/bookingButton"));
|
|
var Child = __importStar(require("./modules/child"));
|
|
window.addEventListener('load', function () {
|
|
utils_1.default.inject(config_1.config.urlJSCStaging, "js", "head");
|
|
utils_1.default.inject(config_1.config.urlCSSJSCStaging, "css", "body");
|
|
utils_1.default.inject(config_1.config.urlCSSChildStaging, "css", "body");
|
|
utils_1.default.inject(config_1.config.urlCSSjQueryUI, "css", "body");
|
|
Communication.listenToMessages(messageHandler);
|
|
utils_1.default.waitForSeatmap(BookingBtn.showSeatmapBtnParent);
|
|
utils_1.default.waitForElement("#modalCart-overlay", Cart.initModalCart);
|
|
Events.addCloseModal();
|
|
Events.addModalCart();
|
|
Events.addDropdownSeatmap();
|
|
});
|
|
window.onresize = function () {
|
|
var panzoom = config_1.config.state.panzoom;
|
|
var innerHeight = window.innerHeight;
|
|
if (innerHeight < 576) {
|
|
console.log("small");
|
|
jQuery("#containerEventInfoRow").hide();
|
|
panzoom === null || panzoom === void 0 ? void 0 : panzoom.reset();
|
|
}
|
|
else if (innerHeight >= 576) {
|
|
jQuery("#containerEventInfoRow").show();
|
|
panzoom === null || panzoom === void 0 ? void 0 : panzoom.reset();
|
|
}
|
|
};
|
|
function messageHandler(inE) {
|
|
if (typeof (inE.data) !== 'string')
|
|
return;
|
|
var data = JSON.parse(inE.data);
|
|
console.log("child: received from " + data.from);
|
|
console.log(data);
|
|
switch (data.event) {
|
|
case "parent_init_venue": {
|
|
Child.initVenue();
|
|
break;
|
|
}
|
|
case "parent_init_sendVenueXML": {
|
|
Child.initSendVenueXML(inE);
|
|
break;
|
|
}
|
|
case "parent_init_sendInputsWithValue": {
|
|
Child.initSendInputsWithValue(inE);
|
|
break;
|
|
}
|
|
case "parent_sendSeatmapXML": {
|
|
Child.sendSeatmapXML(inE);
|
|
break;
|
|
}
|
|
case "parent_sendCheckoutResponse": {
|
|
Child.sendCheckoutResponse(inE);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
},{"./modules/bookingButton":99,"./modules/cart":100,"./modules/child":102,"./modules/communication":103,"./modules/config":104,"./modules/events":105,"./modules/utils":114,"jbox/dist/jBox.all.css":56,"jquery":58}]},{},[116])
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy5udm0vdmVyc2lvbnMvbm9kZS92MTIuMjAuMC9saWIvbm9kZV9tb2R1bGVzL3dhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi8uLi8uLi8uLi8uLi8ubnZtL3ZlcnNpb25zL25vZGUvdjEyLjIwLjAvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzIiwiLi4vLi4vLi4vLi4vLi4vLm52bS92ZXJzaW9ucy9ub2RlL3YxMi4yMC4wL2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcmVzb2x2ZS9lbXB0eS5qcyIsIi4uLy4uLy4uLy4uLy4uLy5udm0vdmVyc2lvbnMvbm9kZS92MTIuMjAuMC9saWIvbm9kZV9tb2R1bGVzL3dhdGNoaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanMiLCIuLi8uLi8uLi8uLi8uLi8ubnZtL3ZlcnNpb25zL25vZGUvdjEyLjIwLjAvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uLy4uLy4uLy4uLy4uLy5udm0vdmVyc2lvbnMvbm9kZS92MTIuMjAuMC9saWIvbm9kZV9tb2R1bGVzL3dhdGNoaWZ5L25vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzIiwiLi4vLi4vLi4vLi4vLi4vLm52bS92ZXJzaW9ucy9ub2RlL3YxMi4yMC4wL2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCIuLi8uLi8uLi8uLi8uLi8ubnZtL3ZlcnNpb25zL25vZGUvdjEyLjIwLjAvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwiLi4vLi4vLi4vLi4vLi4vLm52bS92ZXJzaW9ucy9ub2RlL3YxMi4yMC4wL2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL3NhZmUtYnVmZmVyL2luZGV4LmpzIiwiLi4vLi4vLi4vLi4vLi4vLm52bS92ZXJzaW9ucy9ub2RlL3YxMi4yMC4wL2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2luZGV4LmpzIiwiLi4vLi4vLi4vLi4vLi4vLm52bS92ZXJzaW9ucy9ub2RlL3YxMi4yMC4wL2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vZXJyb3JzLWJyb3dzZXIuanMiLCIuLi8uLi8uLi8uLi8uLi8ubnZtL3ZlcnNpb25zL25vZGUvdjEyLjIwLjAvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9kdXBsZXguanMiLCIuLi8uLi8uLi8uLi8uLi8ubnZtL3ZlcnNpb25zL25vZGUvdjEyLjIwLjAvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcyIsIi4uLy4uLy4uLy4uLy4uLy5udm0vdmVyc2lvbnMvbm9kZS92MTIuMjAuMC9saWIvbm9kZV9tb2R1bGVzL3dhdGNoaWZ5L25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzIiwiLi4vLi4vLi4vLi4vLi4vLm52bS92ZXJzaW9ucy9ub2RlL3YxMi4yMC4wL2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzIiwiLi4vLi4vLi4vLi4vLi4vLm52bS92ZXJzaW9ucy9ub2RlL3YxMi4yMC4wL2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fd3JpdGFibGUuanMiLCIuLi8uLi8uLi8uLi8uLi8ubnZtL3ZlcnNpb25zL25vZGUvdjEyLjIwLjAvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9hc3luY19pdGVyYXRvci5qcyIsIi4uLy4uLy4uLy4uLy4uLy5udm0vdmVyc2lvbnMvbm9kZS92MTIuMjAuMC9saWIvbm9kZV9tb2R1bGVzL3dhdGNoaWZ5L25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2J1ZmZlcl9saXN0LmpzIiwiLi4vLi4vLi4vLi4vLi4vLm52bS92ZXJzaW9ucy9ub2RlL3YxMi4yMC4wL2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL2ludGVybmFsL3N0cmVhbXMvZGVzdHJveS5qcyIsIi4uLy4uLy4uLy4uLy4uLy5udm0vdmVyc2lvbnMvbm9kZS92MTIuMjAuMC9saWIvbm9kZV9tb2R1bGVzL3dhdGNoaWZ5L25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2VuZC1vZi1zdHJlYW0uanMiLCIuLi8uLi8uLi8uLi8uLi8ubnZtL3ZlcnNpb25zL25vZGUvdjEyLjIwLjAvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9mcm9tLWJyb3dzZXIuanMiLCIuLi8uLi8uLi8uLi8uLi8ubnZtL3ZlcnNpb25zL25vZGUvdjEyLjIwLjAvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9waXBlbGluZS5qcyIsIi4uLy4uLy4uLy4uLy4uLy5udm0vdmVyc2lvbnMvbm9kZS92MTIuMjAuMC9saWIvbm9kZV9tb2R1bGVzL3dhdGNoaWZ5L25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL3N0YXRlLmpzIiwiLi4vLi4vLi4vLi4vLi4vLm52bS92ZXJzaW9ucy9ub2RlL3YxMi4yMC4wL2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL2ludGVybmFsL3N0cmVhbXMvc3RyZWFtLWJyb3dzZXIuanMiLCIuLi8uLi8uLi8uLi8uLi8ubnZtL3ZlcnNpb25zL25vZGUvdjEyLjIwLjAvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvc3RyaW5nX2RlY29kZXIvbGliL3N0cmluZ19kZWNvZGVyLmpzIiwiLi4vLi4vLi4vLi4vLi4vLm52bS92ZXJzaW9ucy9ub2RlL3YxMi4yMC4wL2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL3RpbWVycy1icm93c2VyaWZ5L21haW4uanMiLCIuLi8uLi8uLi8uLi8uLi8ubnZtL3ZlcnNpb25zL25vZGUvdjEyLjIwLjAvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvdXRpbC1kZXByZWNhdGUvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9AcGFuem9vbS9wYW56b29tL2Rpc3QvcGFuem9vbS5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9saWIvYWRhcHRlcnMveGhyLmpzIiwibm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9heGlvcy5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9saWIvY2FuY2VsL0NhbmNlbC5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9saWIvY2FuY2VsL0NhbmNlbFRva2VuLmpzIiwibm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9jYW5jZWwvaXNDYW5jZWwuanMiLCJub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvQXhpb3MuanMiLCJub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvSW50ZXJjZXB0b3JNYW5hZ2VyLmpzIiwibm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9jb3JlL2J1aWxkRnVsbFBhdGguanMiLCJub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvY3JlYXRlRXJyb3IuanMiLCJub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvZGlzcGF0Y2hSZXF1ZXN0LmpzIiwibm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9jb3JlL2VuaGFuY2VFcnJvci5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9saWIvY29yZS9tZXJnZUNvbmZpZy5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9saWIvY29yZS9zZXR0bGUuanMiLCJub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvdHJhbnNmb3JtRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9saWIvZGVmYXVsdHMuanMiLCJub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvYmluZC5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9idWlsZFVSTC5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9jb21iaW5lVVJMcy5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9jb29raWVzLmpzIiwibm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL2lzQWJzb2x1dGVVUkwuanMiLCJub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvaXNBeGlvc0Vycm9yLmpzIiwibm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL2lzVVJMU2FtZU9yaWdpbi5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9ub3JtYWxpemVIZWFkZXJOYW1lLmpzIiwibm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL3BhcnNlSGVhZGVycy5qcyIsIm5vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9zcHJlYWQuanMiLCJub2RlX21vZHVsZXMvYXhpb3MvbGliL3V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY3NzL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvamJveC9kaXN0L2pCb3guYWxsLmNzcyIsIm5vZGVfbW9kdWxlcy9qYm94L2Rpc3QvakJveC5hbGwubWluLmpzIiwibm9kZV9tb2R1bGVzL2pxdWVyeS9kaXN0L2pxdWVyeS5qcyIsIm5vZGVfbW9kdWxlcy9zYXgvbGliL3NheC5qcyIsIm5vZGVfbW9kdWxlcy94bWwyanMvbGliL2JvbS5qcyIsIm5vZGVfbW9kdWxlcy94bWwyanMvbGliL2J1aWxkZXIuanMiLCJub2RlX21vZHVsZXMveG1sMmpzL2xpYi9kZWZhdWx0cy5qcyIsIm5vZGVfbW9kdWxlcy94bWwyanMvbGliL3BhcnNlci5qcyIsIm5vZGVfbW9kdWxlcy94bWwyanMvbGliL3Byb2Nlc3NvcnMuanMiLCJub2RlX21vZHVsZXMveG1sMmpzL2xpYi94bWwyanMuanMiLCJub2RlX21vZHVsZXMveG1sYnVpbGRlci9saWIvRG9jdW1lbnRQb3NpdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9Ob2RlVHlwZS5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9VdGlsaXR5LmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1dyaXRlclN0YXRlLmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1hNTEF0dHJpYnV0ZS5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9YTUxDRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9YTUxDaGFyYWN0ZXJEYXRhLmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1hNTENvbW1lbnQuanMiLCJub2RlX21vZHVsZXMveG1sYnVpbGRlci9saWIvWE1MRE9NQ29uZmlndXJhdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9YTUxET01FcnJvckhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMveG1sYnVpbGRlci9saWIvWE1MRE9NSW1wbGVtZW50YXRpb24uanMiLCJub2RlX21vZHVsZXMveG1sYnVpbGRlci9saWIvWE1MRE9NU3RyaW5nTGlzdC5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9YTUxEVERBdHRMaXN0LmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1hNTERUREVsZW1lbnQuanMiLCJub2RlX21vZHVsZXMveG1sYnVpbGRlci9saWIvWE1MRFRERW50aXR5LmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1hNTERURE5vdGF0aW9uLmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1hNTERlY2xhcmF0aW9uLmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1hNTERvY1R5cGUuanMiLCJub2RlX21vZHVsZXMveG1sYnVpbGRlci9saWIvWE1MRG9jdW1lbnQuanMiLCJub2RlX21vZHVsZXMveG1sYnVpbGRlci9saWIvWE1MRG9jdW1lbnRDQi5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9YTUxEdW1teS5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9YTUxFbGVtZW50LmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1hNTE5hbWVkTm9kZU1hcC5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9YTUxOb2RlLmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1hNTE5vZGVMaXN0LmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1hNTFByb2Nlc3NpbmdJbnN0cnVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9YTUxSYXcuanMiLCJub2RlX21vZHVsZXMveG1sYnVpbGRlci9saWIvWE1MU3RyZWFtV3JpdGVyLmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1hNTFN0cmluZ1dyaXRlci5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9YTUxTdHJpbmdpZmllci5qcyIsIm5vZGVfbW9kdWxlcy94bWxidWlsZGVyL2xpYi9YTUxUZXh0LmpzIiwibm9kZV9tb2R1bGVzL3htbGJ1aWxkZXIvbGliL1hNTFdyaXRlckJhc2UuanMiLCJub2RlX21vZHVsZXMveG1sYnVpbGRlci9saWIvaW5kZXguanMiLCJzcmMvbW9kdWxlcy9ib29raW5nQnV0dG9uLnRzIiwic3JjL21vZHVsZXMvY2FydC50cyIsInNyYy9tb2R1bGVzL2NhcnRCdXR0b25zLnRzIiwic3JjL21vZHVsZXMvY2hpbGQudHMiLCJzcmMvbW9kdWxlcy9jb21tdW5pY2F0aW9uLnRzIiwic3JjL21vZHVsZXMvY29uZmlnLnRzIiwic3JjL21vZHVsZXMvZXZlbnRzLnRzIiwic3JjL21vZHVsZXMvakJveEhlbHBlci50cyIsInNyYy9tb2R1bGVzL2pzYy50cyIsInNyYy9tb2R1bGVzL2xlZ2VuZC50cyIsInNyYy9tb2R1bGVzL3Bhbnpvb20udHMiLCJzcmMvbW9kdWxlcy9wYXJzZXIudHMiLCJzcmMvbW9kdWxlcy9zdGF0ZS50cyIsInNyYy9tb2R1bGVzL3RyaW1zLnRzIiwic3JjL21vZHVsZXMvdWkudHMiLCJzcmMvbW9kdWxlcy91dGlscy50cyIsInNyYy9tb2R1bGVzL3htbGhlbHBlci50cyIsInNyYy9zZWF0bWFwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEpBOzs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDanZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDamZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMvSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25tQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDeHJCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM5TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNqTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDeEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkdBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdlNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzdEJBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNsR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0VBOztBQ0FBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNqb1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzdoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbFBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2p4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNWFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDakVBLDZEQUFpRDtBQUVqRCxTQUFnQixnQkFBZ0I7SUFDNUIsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDdkMsbUJBQW1CLEVBQUUsQ0FBQztJQUN0QixvQkFBb0IsRUFBRSxDQUFDO0FBQzNCLENBQUM7QUFKRCw0Q0FJQztBQUVELFNBQWdCLG9CQUFvQjtJQUNoQyxPQUFPLENBQUMsR0FBRyxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDdEMsYUFBYSxDQUFDLGlCQUFpQixDQUFDLHFCQUFxQixDQUFDLENBQUM7QUFDM0QsQ0FBQztBQUhELG9EQUdDO0FBRUQsU0FBUyxvQkFBb0I7SUFDekIsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUMsTUFBTSxDQUFDLDJTQVN2QyxDQUFDLENBQUM7QUFDUCxDQUFDO0FBRUQsU0FBUyxtQkFBbUI7SUFDeEIsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ2pDLFNBQVMsRUFBRSxPQUFPO1FBQ2xCLFVBQVUsRUFBRSxVQUFVO1FBQ3RCLE9BQU8sRUFBRSxNQUFNO0tBQ2xCLENBQUMsQ0FBQztBQUNQLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNoQ0QscURBQXlDO0FBQ3pDLG1DQUFrQztBQUVsQywrQ0FBbUM7QUFDbkMseURBQTZDO0FBRTdDLFNBQWdCLE9BQU8sQ0FBQyxTQUE0QjtJQUNoRCxJQUFNLEtBQUssR0FBVyxNQUFJLFNBQVMsQ0FBQyx3Q0FBd0MsQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFHLENBQUM7SUFDdkgsSUFBTSxRQUFRLEdBQXVCLFNBQVMsQ0FBQyx3Q0FBd0MsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDL0gsSUFBTSxJQUFJLEdBQVcsZUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzlELElBQU0sR0FBRyxHQUFXLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3RCxJQUFNLFNBQVMsR0FBVyxlQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkUsSUFBTSxXQUFXLEdBQXVCLFNBQVMsQ0FBQyx5QkFBeUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN2RixJQUFNLE9BQU8sR0FBMEIsV0FBVyxtQkFBYyxHQUFHLGVBQVUsSUFBTSxDQUFDO0lBQ3BGLElBQU0sVUFBVSxHQUFvQixTQUFTLENBQUMsMkJBQTJCLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekcsSUFBTSxNQUFNLEdBQVcsY0FBWSxTQUFTLENBQUMsRUFBSSxDQUFDO0lBQ2xELElBQU0sMEJBQTBCLEdBQVcsTUFBSSxNQUFNLHlCQUFzQixDQUFDO0lBRTVFLFVBQVUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUM3QywyQkFBMkIsQ0FBQyxVQUFVLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztJQUNwRSxNQUFNLENBQUMseUJBQXlCLENBQUMsMEJBQTBCLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDNUUsQ0FBQztBQWZELDBCQWVDO0FBRUQsU0FBZ0IsZUFBZTtJQUMzQixNQUFNLENBQUMseUJBQXlCLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDbkMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2xCLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQUpELDBDQUlDO0FBRUQsU0FBZ0Isd0JBQXdCLENBQUMsUUFBMkIsRUFBRSxTQUE0QjtJQUM5RixJQUFNLEtBQUssR0FBVyxlQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxVQUFBLEdBQUc7UUFDN0QsT0FBQSxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUyxDQUFDLEVBQUU7SUFBdkIsQ0FBdUIsQ0FBQyxDQUFDO0lBRTdCLGVBQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQztJQUN6RCxJQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsNkJBQTZCLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRTlFLElBQUksYUFBYTtRQUNiLGVBQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsYUFBYSxDQUFDO0lBRTVELGdCQUFnQixFQUFFLENBQUM7SUFDbkIsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBRTdCLElBQU0sR0FBRyxHQUFHLG1CQUFtQixFQUFFLENBQUM7SUFDbEMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BDLENBQUM7QUFmRCw0REFlQztBQUVELFNBQWdCLGdCQUFnQjtJQUM1QixJQUFJLENBQUMsZUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7UUFDdkMsZUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLEdBQUcsR0FBRyxDQUFDO1FBQ2hDLE9BQU8sR0FBRyxDQUFDO0tBQ2Q7SUFFRCxlQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksR0FBRyxhQUFhLEVBQUUsQ0FBQztJQUM1QyxPQUFPLGVBQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDO0FBQ3JDLENBQUM7QUFSRCw0Q0FRQztBQUdELFNBQWdCLGlCQUFpQjtJQUM3QixJQUFJLENBQUMsZUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNO1FBQ3JDLE9BQU87SUFFWCxLQUFLLElBQU0sR0FBRyxJQUFJLGVBQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUU7UUFDN0MsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsZUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxHQUFHLENBQUMsRUFBRTtZQUMxRSxJQUFNLE9BQU8sR0FBRyxlQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ25ELE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNwQjtLQUNKO0FBQ0wsQ0FBQztBQVZELDhDQVVDO0FBRUQsU0FBZ0IsYUFBYTtJQUN6QixNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNwQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDckIsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO0FBQzFCLENBQUM7QUFKRCxzQ0FJQztBQUVELFNBQWdCLG1CQUFtQjtJQUMvQixJQUFJLENBQUMsZUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNO1FBQ3JDLE9BQU87SUFFWCxJQUFNLGVBQWUsR0FBRyxlQUFNLENBQUMsS0FBSyxDQUFDLGVBQWdCLENBQUM7SUFDdEQsSUFBTSxtQkFBbUIsR0FBVyxTQUFTLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztJQUM1RSxPQUFVLGVBQWUsQ0FBQyxtQkFBbUIsQ0FBQyxzQkFBaUIsZUFBZSxDQUFDLFlBQVksYUFBUSxlQUFlLENBQUMsS0FBSyxDQUFDLCtCQUEwQixtQkFBbUIsa0JBQWUsQ0FBQztBQUMxTCxDQUFDO0FBUEQsa0RBT0M7QUFFRCxTQUFTLFVBQVUsQ0FBQyxRQUFnQixFQUFFLE9BQWUsRUFBRSxVQUE4QixFQUFFLFNBQWlCO0lBQ3BHLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyx3Q0FDWixRQUFRLDhFQUN3QixPQUFPLDREQUMvQixVQUFVLG1EQUNmLFNBQVMsMEdBRWpDLENBQUMsQ0FBQztBQUNiLENBQUM7QUFHRCxTQUFTLDJCQUEyQixDQUFDLFlBQTZCLEVBQUUsVUFBa0I7SUFDbEYsSUFBSSxDQUFDLFlBQVk7UUFDYixPQUFPO0lBRVgsWUFBWSxDQUFDLE9BQU8sQ0FBQyxVQUFBLEdBQUc7UUFDcEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ04sWUFBWSxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUNyQyxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFFRCxTQUFTLFlBQVksQ0FBQyxVQUFrQixFQUFFLEtBQXlCO0lBQy9ELElBQU0sa0JBQWtCLEdBQWdCLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEUsSUFBSSxHQUFHLEdBQXNCLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDOUQsR0FBRyxDQUFDLEtBQUssR0FBVyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0IsR0FBRyxDQUFDLFNBQVMsR0FBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLGVBQUssS0FBSyxDQUFDLENBQUMsQ0FBRyxDQUFDO0lBQzNDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN4QyxDQUFDO0FBRUQsU0FBUyxhQUFhO0lBQ2xCLE9BQU8sZUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDO1NBQ2pELE1BQU0sQ0FBQyxVQUFDLElBQUksRUFBRSxJQUFJLElBQUssT0FBQSxJQUFJLEdBQUcsSUFBSSxFQUFYLENBQVcsQ0FBQztTQUNuQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEIsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLEdBQWE7SUFDL0IsSUFBTSxNQUFNLEdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFCLElBQU0sV0FBVyxHQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuQyxJQUFNLFlBQVksR0FBc0IsZUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM5RSxJQUFNLFlBQVksR0FBVyxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUQsSUFBTSxhQUFhLEdBQThCLFNBQVMsQ0FBQyw0Q0FBNEMsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUV0SCxJQUFJLGFBQWEsRUFBRTtRQUNmLElBQU0sU0FBUyxHQUF1QixTQUFTLENBQUMscUJBQXFCLENBQUMsV0FBVyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBRWxHLElBQUksU0FBUztZQUNULE9BQU8sU0FBUyxDQUFDO0tBQ3hCO0lBRUQsT0FBTyxDQUFDLENBQUM7QUFDakIsQ0FBQzs7Ozs7O0FDdElELG1DQUFrQztBQUVsQyxTQUFnQixjQUFjO0lBQzFCLE1BQU0sQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsR0FBRyxpQkFBaUIsRUFBRSxDQUFDO0lBQzFFLE1BQU0sQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsR0FBRyxzQkFBc0IsRUFBRSxDQUFDO0FBQ3pGLENBQUM7QUFIRCx3Q0FHQztBQUVELFNBQVMsaUJBQWlCO0lBQ3RCLElBQU0sVUFBVSxHQUFXLGVBQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDO0lBRWhFLElBQUksZUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLEtBQUssRUFBRTtRQUNoQyxPQUFPLFVBQVUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFJLFVBQVUsK0JBQWdCLGVBQU0sQ0FBQyxLQUFLLENBQUMsWUFBYyxDQUFDLENBQUMsQ0FBSSxVQUFVLGdDQUFpQixlQUFNLENBQUMsS0FBSyxDQUFDLFlBQWMsQ0FBQzs7UUFFL0ksT0FBTyxxQkFBcUIsQ0FBQztBQUNyQyxDQUFDO0FBRUQsU0FBUyxzQkFBc0I7SUFDM0IsSUFBTSxVQUFVLEdBQVcsZUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7SUFFaEUsSUFBSSxlQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksS0FBSyxFQUFFO1FBQ2hDLE9BQU8sWUFBVSxVQUFVLDRCQUFhLGVBQU0sQ0FBQyxLQUFLLENBQUMsWUFBYyxDQUFDOztRQUVwRSxPQUFPLGtDQUF3QixDQUFDO0FBQ3hDLENBQUM7QUFFRCxTQUFnQixzQkFBc0IsQ0FBQyxRQUFnQjtJQUNuRCxJQUFJLFFBQVEsS0FBSyxNQUFNLEVBQUU7UUFDckIsTUFBTSxDQUFDLHlCQUF5QixDQUFDLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM5QixNQUFNLENBQUMsOEJBQThCLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7S0FDaEU7U0FDSSxJQUFJLFFBQVEsS0FBSyxNQUFNLEVBQUU7UUFDMUIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzlCLE1BQU0sQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNoRSxNQUFNLENBQUMseUJBQXlCLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLENBQUM7S0FDbEU7QUFDTCxDQUFDO0FBWEQsd0RBV0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNwQ0QsNkRBQWlEO0FBQ2pELHVDQUEyQjtBQUMzQixtQ0FBa0M7QUFDbEMsa0RBQTRCO0FBQzVCLCtDQUFtQztBQUVuQyx5Q0FBNkI7QUFDN0IsK0NBQW1DO0FBQ25DLCtDQUFtQztBQUNuQyw2Q0FBaUM7QUFDakMscURBQXlDO0FBQ3pDLGlEQUFxQztBQUNyQyx1REFBMkM7QUFDM0MsMkNBQStCO0FBQy9CLHlEQUE2QztBQUU3QyxTQUFnQixTQUFTO0lBQ3JCLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM3QixhQUFhLENBQUMsaUJBQWlCLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztBQUN0RSxDQUFDO0FBSEQsOEJBR0M7QUFFRCxTQUFnQixnQkFBZ0IsQ0FBQyxHQUFRO0lBQ3JDLElBQU0sSUFBSSxHQUFjLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdDLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDO0lBQ3BELElBQU0sUUFBUSxHQUFHLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVyxDQUFDO0lBRzFDLElBQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0lBQ3ZDLGVBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUd2QyxJQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDeEMsRUFBRSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUczQixJQUFNLGNBQWMsR0FBZ0IsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7SUFDdkUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxjQUFjLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUd0RCxJQUFNLEVBQUUsR0FBVyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNuQyxhQUFhLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRWpDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUVoQyxDQUFDO0FBekJELDRDQXlCQztBQUVELFNBQWdCLHVCQUF1QixDQUFDLEdBQVE7SUFDNUMsSUFBTSxJQUFJLEdBQWMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDN0MsZUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUM1QyxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUN0QixhQUFhLENBQUMsaUJBQWlCLENBQUMseUJBQXlCLENBQUMsQ0FBQztBQUMvRCxDQUFDO0FBTEQsMERBS0M7QUFHRCxTQUFnQixjQUFjLENBQUMsR0FBUTtJQUNuQyxJQUFNLElBQUksR0FBYyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QyxlQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQztJQUNwRCxJQUFNLEdBQUcsR0FBYSxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDeEMsSUFBTSxVQUFVLEdBQWEsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ2pELElBQU0sS0FBSyxHQUFlLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUN6QyxJQUFNLE1BQU0sR0FBZ0IsR0FBRyxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBRWxFLEdBQUcsQ0FBQyxVQUFVLENBQUMsd0JBQXdCLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDekUsR0FBRyxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFDMUIsR0FBRyxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDeEIsTUFBTSxDQUFDLHVCQUF1QixDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDakQsTUFBTSxDQUFDLHNCQUFzQixDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDakQsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2pCLFNBQVMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN4QixlQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLHdCQUF3QixFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLG1CQUFtQixDQUFDLENBQUM7SUFDOUgsRUFBRSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzdCLFVBQVUsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0FBQ3BDLENBQUM7QUFsQkQsd0NBa0JDO0FBRUQsU0FBZ0Isb0JBQW9CLENBQUMsR0FBUTtJQUN6QyxJQUFNLElBQUksR0FBYyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QyxlQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUM7SUFFdEUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFMUIsSUFBSSxDQUFDLGVBQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQUU7UUFDcEMsVUFBVSxDQUFDLGNBQWMsQ0FBQywyRUFBc0UsQ0FBQyxDQUFDO1FBQ2xHLFdBQVcsQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztLQUM5QztTQUNJO1FBQ0QsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3pCLElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNoQyxFQUFFLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDckIsV0FBVyxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0tBQzlDO0lBRUQsZUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO0FBQ3JDLENBQUM7QUFwQkQsb0RBb0JDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDL0ZELGdEQUE2QztBQUM3QyxJQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsV0FBVyxDQUFDO0FBQ25ELHVDQUEyQjtBQUMzQixtQ0FBa0M7QUFDbEMsMkNBQStCO0FBRy9CLFNBQWdCLFdBQVcsQ0FBQyxNQUFpQixFQUFFLElBQVk7SUFDdkQsSUFBSSxJQUFJLEtBQUssUUFBUTtRQUNqQixNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQ3REO1FBQ0QsSUFBTSxLQUFLLEdBQVEsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVqRCxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxDQUFDLGFBQWEsS0FBSyxJQUFJO1lBQzlDLEtBQUssQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7O1lBRTdELE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQW1CLElBQUksb0JBQWlCLENBQUMsQ0FBQztLQUM3RDtBQUNMLENBQUM7QUFYRCxrQ0FXQztBQUVELFNBQWdCLGdCQUFnQixDQUFDLFNBQTJCO0lBQ3hELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsVUFBQyxDQUFNO1FBQ3RDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqQixDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFKRCw0Q0FJQztBQUVELFNBQWdCLE9BQU8sQ0FBQyxLQUFhLEVBQUUsSUFBWSxFQUFFLE9BQWUsRUFBRSxNQUFjLEVBQUUsTUFBMkI7SUFBM0IsdUJBQUEsRUFBQSxTQUFpQixJQUFJLENBQUMsR0FBRyxFQUFFO0lBQzdHLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBQyxNQUFlO1FBQ3RDLElBQU0sT0FBTyxHQUFjO1lBQ3ZCLElBQUksRUFBRSxNQUFNO1lBQ1osSUFBSSxFQUFFLE1BQU07WUFDWixPQUFPLEVBQUUsTUFBTTtZQUNmLEtBQUssRUFBRSxPQUFPO1NBQ2pCLENBQUE7UUFDRCxXQUFXLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQy9CLENBQUMsQ0FBQztTQUNHLEtBQUssQ0FBQyxVQUFVLEdBQUc7UUFDaEIsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN2QixDQUFDLENBQUMsQ0FBQztBQUNYLENBQUM7QUFiRCwwQkFhQztBQUVELFNBQWdCLGdCQUFnQixDQUFDLE9BQWU7SUFDNUMsSUFBTSxPQUFPLEdBQWM7UUFDdkIsT0FBTyxFQUFFLElBQUk7UUFDYixJQUFJLEVBQUUsUUFBUTtRQUNkLEtBQUssRUFBRSxPQUFPO1FBQ2QsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7S0FDbkIsQ0FBQztJQUNGLFdBQVcsQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUM7QUFDMUMsQ0FBQztBQVJELDRDQVFDO0FBRUQsU0FBZ0IsaUJBQWlCLENBQUMsT0FBZTtJQUM3QyxJQUFNLE9BQU8sR0FBYztRQUN2QixPQUFPLEVBQUUsSUFBSTtRQUNiLElBQUksRUFBRSxPQUFPO1FBQ2IsS0FBSyxFQUFFLE9BQU87UUFDZCxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtLQUNuQixDQUFDO0lBQ0YsV0FBVyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBUkQsOENBUUM7QUFFRCxTQUFnQixjQUFjLENBQUMsSUFBWTtJQUN2QyxJQUFNLE9BQU8sR0FBYztRQUN2QixPQUFPLEVBQUUsSUFBSTtRQUNiLElBQUksRUFBRSxPQUFPO1FBQ2IsS0FBSyxFQUFFLHNCQUFzQjtRQUM3QixJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtLQUNuQixDQUFDO0lBQ0YsV0FBVyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBUkQsd0NBUUM7QUFFRCxTQUFnQixjQUFjLENBQUMsS0FBYTtJQUd4QyxLQUFLLENBQUMsS0FBSyxFQUFFO1FBQ1QsUUFBUSxFQUFFLFFBQVE7S0FDckIsQ0FBQztTQUNHLElBQUksQ0FBQyxjQUFNLE9BQUEsT0FBTyxDQUFDLEdBQUcsQ0FBSSxLQUFLLGNBQVcsQ0FBQyxFQUFoQyxDQUFnQyxDQUFDO1NBQzVDLEtBQUssQ0FBQyxVQUFVLEtBQUs7UUFDbEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyQixPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZCLENBQUMsQ0FBQyxDQUFDO0FBQ1gsQ0FBQztBQVhELHdDQVdDO0FBRUQsU0FBZ0Isb0JBQW9CO0lBQ2hDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBRXBDLElBQUksQ0FBQyxlQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLE1BQU07UUFDckMsT0FBTztJQUVYLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQ3ZCLElBQU0sR0FBRyxHQUF1QixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztJQUUzRCxJQUFNLE9BQU8sR0FBYztRQUN2QixPQUFPLEVBQUU7WUFDTCxHQUFHLEVBQUUsR0FBRztTQUNYO1FBQ0QsSUFBSSxFQUFFLE9BQU87UUFDYixLQUFLLEVBQUUsNEJBQTRCO1FBQ25DLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO0tBQ25CLENBQUM7SUFFRixXQUFXLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFuQkQsb0RBbUJDO0FBRUQsU0FBUyxhQUFhLENBQUMsS0FBYTtJQUNoQyxPQUFPLGVBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDO1NBQ2xCLElBQUksQ0FBQyxVQUFDLFFBQW1DO1FBQ3RDLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFZLEVBQUUsTUFBVztZQUN6QyxJQUFNLGFBQWEsR0FBa0IsUUFBUSxDQUFDO1lBQzlDLElBQUksYUFBYSxDQUFDLE1BQU0sS0FBSyxHQUFHLElBQUksYUFBYSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsS0FBSyx3QkFBd0IsRUFBRTtnQkFDcEcsWUFBWSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQzNCLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsRUFDMUQsVUFBQyxHQUFRLEVBQUUsTUFBVztvQkFDbEIsSUFBSSxHQUFHO3dCQUNILE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQzs7d0JBRVosT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN4QixDQUFDLENBQUMsQ0FBQzthQUNWO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDLENBQUM7U0FDRCxLQUFLLENBQUMsVUFBQyxLQUFLO1FBQ1QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QixDQUFDLENBQUMsQ0FBQztBQUNYLENBQUM7Ozs7OztBQzVIWSxRQUFBLE1BQU0sR0FBYTtJQUM1QixLQUFLLEVBQUUsSUFBSTtJQUNYLE1BQU0sRUFBRSxTQUFTO0lBQ2pCLGlCQUFpQixFQUFFLHNDQUFzQztJQUN6RCxnQkFBZ0IsRUFBRSw4QkFBOEI7SUFDaEQsaUJBQWlCLEVBQUUsa0RBQWtEO0lBQ3JFLGtCQUFrQixFQUFFLDBEQUEwRDtJQUM5RSxrQkFBa0IsRUFBRSxtREFBbUQ7SUFDdkUsbUJBQW1CLEVBQUUsMkRBQTJEO0lBQ2hGLGFBQWEsRUFBRSx3RkFBd0Y7SUFDdkcsWUFBWSxFQUFFLGdGQUFnRjtJQUM5RixnQkFBZ0IsRUFBRSxxRkFBcUY7SUFDdkcsZUFBZSxFQUFFLDZFQUE2RTtJQUM5RixjQUFjLEVBQUUsNkRBQTZEO0lBQzdFLGdCQUFnQixFQUFFLEtBQUs7SUFDdkIsZ0JBQWdCLEVBQUUsRUFBRTtJQUNwQixLQUFLLEVBQUU7UUFDSCxZQUFZLEVBQUUsRUFBRTtRQUNoQixXQUFXLEVBQUUsS0FBSztRQUNsQixnQkFBZ0IsRUFBRSxFQUFFO1FBQ3BCLGdCQUFnQixFQUFFLEVBQUU7UUFDcEIsVUFBVSxFQUFFLEVBQUU7UUFDZCxvQkFBb0IsRUFBRSxLQUFLO1FBQzNCLGVBQWUsRUFBRSxTQUFTO1FBQzFCLE9BQU8sRUFBRSxTQUFTO1FBQ2xCLE9BQU8sRUFBRSxTQUFTO1FBQ2xCLFVBQVUsRUFBRSxTQUFTO1FBQ3JCLFVBQVUsRUFBRSxTQUFTO0tBQ3hCO0NBQ0osQ0FBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQy9CRCw2REFBaUQ7QUFDakQsdUNBQTJCO0FBQzNCLG1DQUFrQztBQUVsQyx5Q0FBNkI7QUFDN0IsMkNBQStCO0FBQy9CLCtDQUFtQztBQUNuQyx1REFBMkM7QUFFM0MsU0FBZ0IsYUFBYTtJQUN6QixJQUFNLGFBQWEsR0FBNEIsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQy9FLElBQUksYUFBYTtRQUNiLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsY0FBTSxPQUFBLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFwRCxDQUFvRCxDQUFDLENBQUM7QUFDNUcsQ0FBQztBQUpELHNDQUlDO0FBRUQsU0FBZ0Isa0JBQWtCO0lBQzlCLElBQU0sZUFBZSxHQUF1QixRQUFRLENBQUMsY0FBYyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFFdkYsSUFBSSxlQUFlLEVBQUU7UUFDakIsZUFBZSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRTtZQUN2QyxFQUFFLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDN0IsRUFBRSxDQUFDLHFCQUFxQixDQUFDLHdCQUF3QixDQUFDLENBQUM7WUFDbkQsYUFBYSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0MsQ0FBQyxDQUFDLENBQUM7S0FDTjtBQUNMLENBQUM7QUFWRCxnREFVQztBQUVELFNBQWdCLFlBQVk7SUFDeEIsSUFBTSxPQUFPLEdBQTRCLE1BQU0sQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUVsRixJQUFJLE9BQU8sRUFBRTtRQUNULE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUU7WUFDOUIsSUFBSSxDQUFDLGVBQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBTTtnQkFDckMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxpREFBNEMsQ0FBQyxDQUFDO2lCQUN2RSxJQUFJLGVBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVztnQkFDN0IsYUFBYSxDQUFDLG9CQUFvQixFQUFFLENBQUM7aUJBQ3BDLElBQUksQ0FBQyxlQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsSUFBSSxlQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtnQkFDbkUsRUFBRSxDQUFDLGVBQWUsRUFBRSxDQUFDO2lCQUNwQixJQUFJLENBQUMsZUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLElBQUksQ0FBQyxlQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtnQkFDcEUsVUFBVSxDQUFDLGNBQWMsQ0FBQywyRUFBc0UsQ0FBQyxDQUFDO1FBQzFHLENBQUMsQ0FBQyxDQUFDO0tBQ047QUFDTCxDQUFDO0FBZkQsb0NBZUM7QUFFRCxTQUFnQixtQkFBbUIsQ0FBQyxLQUF5QjtJQUN6RCxJQUFJLENBQUMsS0FBSztRQUNOLE9BQU87SUFFWCxJQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMseUNBQXlDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0UsSUFBSSxXQUFXLEVBQUU7UUFDYixXQUFXLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFO1lBQ2xDLElBQU0sT0FBTyxHQUFjO2dCQUN2QixPQUFPLEVBQUU7b0JBQ0wsR0FBRyxFQUFFLEtBQUs7aUJBQ2I7Z0JBQ0QsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsS0FBSyxFQUFFLHNCQUFzQjtnQkFDN0IsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7YUFDbkIsQ0FBQztZQUNGLGFBQWEsQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO0tBQ047QUFDTCxDQUFDO0FBbEJELGtEQWtCQztBQUVELFNBQWdCLFlBQVk7SUFDeEIsSUFBTSxRQUFRLEdBQWdCLE1BQU0sQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuRixJQUFJLFFBQVE7UUFDUixRQUFRLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLGNBQU0sT0FBQSxhQUFhLENBQUMsaUJBQWlCLENBQUMsNEJBQTRCLENBQUMsRUFBN0QsQ0FBNkQsQ0FBQyxDQUFDO0FBQ2hILENBQUM7QUFKRCxvQ0FJQztBQUVELFNBQWdCLFdBQVc7SUFDdkIsSUFBTSxPQUFPLEdBQWdCLE1BQU0sQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwRixJQUFJLE9BQU87UUFDUCxPQUFPLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLGNBQU0sT0FBQSxNQUFNLENBQUMscUNBQXFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQTlELENBQThELENBQUMsQ0FBQztBQUNoSCxDQUFDO0FBSkQsa0NBSUM7QUFFRCxTQUFnQixzQkFBc0IsQ0FBQyxVQUFrQjtJQUNyRCxJQUFNLE9BQU8sR0FBUSxlQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQztJQUMxQyxJQUFNLGNBQWMsR0FBZ0IsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUU5RCxjQUFjLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFO1FBQ3RDLElBQU0sS0FBSyxHQUFXLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDakMsSUFBTSxTQUFTLEdBQVcsT0FBSyxLQUFPLENBQUM7UUFFdkMsTUFBTSxDQUFDLDJCQUEyQixDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFakUsSUFBSSxLQUFLLEtBQUssS0FBSyxFQUFFO1lBQ2pCLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ2hELEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1NBQzdCO2FBQ0k7WUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoRCxHQUFHLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEMsR0FBRyxDQUFDLG1CQUFtQixFQUFFLENBQUM7U0FDN0I7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFwQkQsd0RBb0JDO0FBRUQsU0FBZ0IseUJBQXlCLENBQUMsVUFBa0IsRUFBRSxTQUE0QjtJQUV0RixNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRTtRQUM1QixJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ25ELENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQUxELDhEQUtDO0FBRUQsU0FBZ0IsY0FBYztJQUMxQixNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRTtRQUMvQixJQUFJLENBQUMsZUFBTSxDQUFDLGdCQUFnQjtZQUN4QixhQUFhLENBQUMsZ0JBQWdCLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUV4RCxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMvQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDNUMsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDO0FBUkQsd0NBUUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNqSEQsOENBQXdCO0FBQ3hCLG1DQUFrQztBQUNsQyxxREFBeUM7QUFFekMsU0FBZ0IsY0FBYyxDQUFDLFNBQWlCLEVBQUUsV0FBZ0Q7SUFBaEQsNEJBQUEsRUFBQSxrQkFBZ0Q7SUFDOUYsSUFBSSxjQUFJLENBQVksUUFBUSxFQUFFO1FBQzFCLFFBQVEsRUFBRSxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRTtRQUNuQyxNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUU7UUFDeEIsT0FBTyxFQUFFLFNBQVM7UUFDbEIsU0FBUyxFQUFFLFdBQVc7UUFDdEIsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFO1FBQy9DLFVBQVUsRUFBRSxLQUFLO1FBQ2pCLFdBQVcsRUFBRSxJQUFJO1FBQ2pCLGlCQUFpQixFQUFFLEtBQUs7UUFDeEIsWUFBWSxFQUFFLEtBQUs7UUFDbkIsU0FBUyxFQUFFLEtBQUs7UUFDaEIsS0FBSyxFQUFFLEtBQUs7UUFDWixLQUFLLEVBQUUsSUFBSTtRQUNYLGFBQWEsRUFBRSxJQUFJO1FBQ25CLFVBQVUsRUFBRSxJQUFJO1FBQ2hCLGVBQWUsRUFBRSxJQUFJO1FBQ3JCLGdCQUFnQixFQUFFLElBQUk7S0FDekIsQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQW5CRCx3Q0FtQkM7QUFFRCxTQUFnQixrQkFBa0I7SUFDOUIsSUFBSSxjQUFJLENBQWEsU0FBUyxFQUFFO1FBQzVCLE1BQU0sRUFBRSxNQUFNLENBQUMsa0JBQWtCLENBQUM7UUFDbEMsTUFBTSxFQUFFO1lBQ0osZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFCLENBQUM7S0FDSixDQUFDLENBQUM7QUFDUCxDQUFDO0FBUEQsZ0RBT0M7QUFFRCxTQUFTLGVBQWUsQ0FBQyxJQUFTO0lBQzlCLElBQU0sTUFBTSxHQUFXLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ3pDLElBQU0sSUFBSSxHQUFXLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hELElBQU0sR0FBRyxHQUFXLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZELElBQU0sU0FBUyxHQUFXLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdELElBQU0sV0FBVyxHQUF1QixTQUFTLENBQUMseUJBQXlCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdkYsSUFBTSxjQUFjLEdBQWMsV0FBVyxtQkFBYyxHQUFHLGVBQVUsSUFBTSxDQUFDO0lBRS9FLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDcEMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzFDRCxtQ0FBa0M7QUFDbEMsNkNBQWlDO0FBQ2pDLDJDQUErQjtBQUMvQix5REFBNkM7QUFFN0MsU0FBZ0IsUUFBUTtJQUNwQixJQUFNLFVBQVUsR0FBUSxlQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztJQUNoRCxJQUFNLGFBQWEsR0FBMEIsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7SUFDbkcsSUFBSSxnQkFBZ0IsR0FBZSxFQUFFLENBQUM7SUFFdEMsS0FBSyxJQUFJLEdBQUcsSUFBSSxhQUFhLEVBQUU7UUFDM0IsSUFBTSxRQUFRLEdBQWdCO1lBQzFCLFNBQVMsRUFBRSxNQUFJLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFHO1lBQ3pDLFVBQVUsRUFBRSxhQUFhLENBQUMsR0FBRyxDQUFDO1NBQ2pDLENBQUE7UUFDRCxJQUFNLFFBQVEsR0FBVyxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3JGLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxHQUFHLFFBQVEsQ0FBQztLQUN6QztJQUVELE9BQU8sZ0JBQWdCLENBQUM7QUFDNUIsQ0FBQztBQWZELDRCQWVDO0FBRUQsU0FBZ0Isd0JBQXdCLENBQUMsT0FBZTs7SUFDcEQsSUFBTSxVQUFVLEdBQVEsZUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7SUFDaEQsSUFBTSxPQUFPLEdBQVEsZUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7SUFDMUMsSUFBTSxhQUFhLEdBQTBCLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO0lBRW5HLElBQU0sUUFBUSxHQUF5QixNQUFBLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBQSxHQUFHO1FBQ3pELE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxPQUFPLENBQUM7SUFDakMsQ0FBQyxDQUFDLDBDQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRXZCLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQzFDLENBQUM7QUFWRCw0REFVQztBQUVELFNBQWdCLGFBQWE7SUFDekIsSUFBTSxVQUFVLEdBQVEsZUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7SUFDaEQsSUFBTSxNQUFNLEdBQW9CLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzRSxJQUFNLE1BQU0sR0FBVyxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xELElBQU0sU0FBUyxHQUFhLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEVBQUUsVUFBQyxDQUFDLElBQUssT0FBQSxFQUFFLEVBQUYsQ0FBRSxDQUFDLENBQUM7SUFDdEUsSUFBTSxPQUFPLEdBQW1CLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBRW5ELE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBQSxPQUFPO1FBQ25CLElBQU0sS0FBSyxHQUFXLFFBQVEsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEQsSUFBTSxRQUFRLEdBQWEsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkQsSUFBTSxPQUFPLEdBQWEsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BELElBQU0sR0FBRyxHQUFXLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQixTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBQzNCLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxTQUFTLENBQUM7QUFDckIsQ0FBQztBQWhCRCxzQ0FnQkM7QUFFRCxTQUFnQixXQUFXO0lBQ3ZCLElBQU0sVUFBVSxHQUFRLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO0lBQ2hELElBQU0sTUFBTSxHQUFvQixVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0UsSUFBTSxJQUFJLEdBQW1CLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQ2hELElBQU0sYUFBYSxHQUEwQixVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztJQUNuRyxJQUFNLGVBQWUsR0FBc0IsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUc1RyxJQUFJLFNBQVMsR0FBZSxlQUFlLENBQ3ZDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQzFCLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ3pCLEdBQUcsQ0FDTixDQUFDO0lBRUYsU0FBUyxHQUFHLGtCQUFrQixDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0lBQ2hGLE9BQU8sU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFBLE9BQU8sSUFBSSxPQUFBLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQWhCLENBQWdCLENBQUMsQ0FBQztBQUN0RCxDQUFDO0FBaEJELGtDQWdCQztBQUVELFNBQWdCLGNBQWMsQ0FBQyxNQUFjO0lBQ3pDLElBQU0sVUFBVSxHQUFRLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO0lBQ2hELElBQU0sUUFBUSxHQUFlLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVyxDQUFDO0lBQ3RELElBQU0sYUFBYSxHQUEwQixVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztJQUNuRyxJQUFNLGtCQUFrQixHQUFvQixRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7SUFFeEYsT0FBb0I7UUFDaEIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDcEIsS0FBSyxFQUFFLGlCQUFpQixDQUFDLGFBQWEsRUFBRSxrQkFBa0IsQ0FBQztLQUM5RCxDQUFBO0FBQ0wsQ0FBQztBQVZELHdDQVVDO0FBSUQsU0FBZ0IsbUJBQW1CO0lBQy9CLElBQU0sVUFBVSxHQUFRLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO0lBQ2hELElBQU0sT0FBTyxHQUFRLGVBQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQzFDLElBQU0sZUFBZSxHQUFzQixVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRTVHLElBQUksZUFBZSxDQUFDLDZCQUE2QixDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtRQUN6RCxJQUFNLGNBQWMsR0FBYSxlQUFlLENBQUMsNkJBQTZCLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdGLE9BQU8sQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0tBQ2pEO0FBQ0wsQ0FBQztBQVRELGtEQVNDO0FBRUQsU0FBZ0IsV0FBVyxDQUFDLFFBQWdCLEVBQUUsZUFBc0M7SUFDaEYsS0FBSyxJQUFJLEdBQUcsSUFBSSxlQUFlLEVBQUU7UUFDN0IsSUFBSSxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7WUFDL0MsT0FBTyxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0tBQzFFO0lBRUQsT0FBTyxTQUFTLENBQUM7QUFDckIsQ0FBQztBQVBELGtDQU9DO0FBRUQsU0FBZ0IsWUFBWSxDQUFDLFNBQWlCO0lBQzFDLE9BQU8sU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBQyxJQUFJLElBQUssT0FBQSxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQVgsQ0FBVyxDQUFDLENBQUM7QUFDM0QsQ0FBQztBQUZELG9DQUVDO0FBRUQsU0FBZ0IsZUFBZSxDQUFDLFNBQWlCLEVBQUUsU0FBaUIsRUFBRSxXQUFtQjtJQUNyRixPQUFPLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLGNBQU0sT0FBQSxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFsQyxDQUFrQyxDQUFDLENBQUM7QUFDckYsQ0FBQztBQUZELDBDQUVDO0FBRUQsU0FBZ0IsaUJBQWlCO0lBQzdCLElBQU0sT0FBTyxHQUFRLGVBQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQzFDLGVBQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLFVBQUEsR0FBRztRQUNyQyxJQUFNLE1BQU0sR0FBVyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFOUIsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztZQUNuQixPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztJQUMzQyxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFSRCw4Q0FRQztBQUVELFNBQWdCLFVBQVUsQ0FBQyxVQUFrQixFQUFFLEtBQWUsRUFBRSxZQUFzQixFQUFFLE9BQW1CLEVBQUUsUUFBcUI7SUFDOUgsSUFBTSxnQkFBZ0IsR0FBYyxNQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBTS9ELGVBQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLGdCQUFnQixDQUFDLFVBQVUsQ0FBQztRQUMvQyxNQUFNLEVBQUU7WUFDSixHQUFHLEVBQUUsS0FBSztZQUNWLElBQUksRUFBRSxLQUFLO1lBQ1gsSUFBSSxFQUFFLFlBQVk7U0FDckI7UUFDRCxHQUFHLEVBQUUsS0FBSztRQUNWLEtBQUssRUFBRSxPQUFPO1FBQ2QsTUFBTSxFQUFFLFFBQVE7UUFDaEIsS0FBSyxFQUFFO1lBQ0gsT0FBTyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0IsQ0FBQztLQUNKLENBQUMsQ0FBQztBQUNQLENBQUM7QUFwQkQsZ0NBb0JDO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxhQUFvQyxFQUFFLGtCQUFtQztJQUNoRyxPQUFPLGFBQWEsQ0FBQyxHQUFHLENBQUMsVUFBQyxHQUFHLEVBQUUsS0FBYTs7UUFDeEMsSUFBTSxFQUFFLEdBQVcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixJQUFNLFFBQVEsR0FBVyxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQzdFLElBQU0sSUFBSSxHQUF1QixNQUFBLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFBLEdBQUcsSUFBSSxPQUFBLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFoQixDQUFnQixDQUFDLDBDQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzRixJQUFNLFdBQVcsR0FBYyxJQUFJLGVBQUssYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUcsQ0FBQztRQUM1RSxPQUFPLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUNoRCxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFFRCxTQUFTLGtCQUFrQixDQUFDLE1BQXNCLEVBQUUsV0FBdUIsRUFBRSxlQUFzQyxFQUFFLGlCQUFvQztJQUNySixJQUFNLFlBQVksR0FBYSxpQkFBaUIsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDekYsSUFBTSxjQUFjLEdBQWEsaUJBQWlCLENBQUMsNkJBQTZCLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRS9GLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBQSxPQUFPO1FBQ2xCLElBQU0sR0FBRyxHQUFpQixPQUFPLENBQUM7UUFDbEMsSUFBTSxDQUFDLEdBQVcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDcEQsSUFBTSxRQUFRLEdBQWEsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFbkQsUUFBUSxDQUFDLE9BQU8sQ0FBQyxVQUFBLE9BQU87WUFDcEIsSUFBTSxPQUFPLEdBQVcsT0FBTyxDQUFDO1lBSWhDLElBQU0sT0FBTyxHQUFhLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQVVoRCxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMxRSxPQUFPO1lBR1gsSUFBTSxDQUFDLEdBQVcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMzQyxJQUFNLFFBQVEsR0FBdUIsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxlQUFlLENBQUMsQ0FBQztZQUU5RSxJQUFJLFFBQVE7Z0JBQ1IsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFNLFFBQVEsU0FBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLFFBQUssQ0FBQztZQUl2RCxlQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUM7UUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sV0FBVyxDQUFDO0FBQ3ZCLENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxTQUFjO0lBQy9CLElBQUksU0FBUyxDQUFDLE1BQU0sRUFBRSxJQUFJLFdBQVcsRUFBRTtRQUNuQyxPQUFPLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0tBQ3hDO1NBQ0ksSUFBSSxTQUFTLENBQUMsTUFBTSxFQUFFLEtBQUssVUFBVSxFQUFFO1FBQ3hDLE9BQU8sbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUM7S0FDekM7U0FDSSxJQUFJLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxhQUFhLEVBQUU7UUFDMUMsT0FBTyxhQUFhLENBQUM7S0FDeEI7U0FDSTtRQUNELE9BQU8sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO0tBQzVCO0FBQ0wsQ0FBQztBQUVELFNBQVMsa0JBQWtCLENBQUMsU0FBYztJQUN0QyxJQUFNLFlBQVksR0FBc0IsU0FBUyxDQUFDLFFBQVEsQ0FBQztJQUMzRCxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRTFCLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLFlBQVksQ0FBQztRQUMvQyxPQUFPLFdBQVcsQ0FBQztJQUV2QixLQUFLLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ25DLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQ3hCLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUU3QixPQUFPLFVBQVUsQ0FBQztBQUN0QixDQUFDO0FBRUQsU0FBUyxtQkFBbUIsQ0FBQyxTQUFjO0lBQ3ZDLElBQU0sWUFBWSxHQUFzQixTQUFTLENBQUMsUUFBUSxDQUFDO0lBQzNELEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN4QyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUN4QixXQUFXLENBQUMsY0FBYyxFQUFFLENBQUM7SUFFN0IsT0FBTyxXQUFXLENBQUM7QUFDdkIsQ0FBQzs7Ozs7O0FDMU9ELFNBQWdCLHVCQUF1QixDQUFDLElBQVk7SUFDaEQsTUFBTSxDQUFDLDBCQUEwQixDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3BDLElBQUksTUFBTSxHQUE4QixNQUFNLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUMzRSxZQUFZLENBQ1QsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUN0QixDQUFDO1FBRU4sTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzFCLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hDLG1CQUFtQixDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFYRCwwREFXQztBQUVELFNBQVMsbUJBQW1CLENBQUMsT0FBb0IsRUFBRSxRQUFtQztJQUNsRixNQUFNLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQztRQUN4QixJQUFNLFNBQVMsR0FBVyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRSxJQUFNLEdBQUcsR0FBVyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNDLElBQU0sSUFBSSxHQUF5QixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBRSxDQUFDLFNBQVMsQ0FBQztRQUUxRSxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN2RCxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFFRCxTQUFTLGtCQUFrQixDQUFDLFFBQW1DLEVBQUUsU0FBaUIsRUFBRSxHQUFXLEVBQUUsSUFBWTtJQUN6RyxJQUFJLE1BQU0sR0FBOEIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzVELE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3RCxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFFRCxTQUFTLHVCQUF1QixDQUFDLFFBQW1DO0lBQ2hFLElBQUksTUFBTSxHQUE4QixNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDNUQsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0lBQzdELE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQy9CLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDNUIsQ0FBQztBQUVELFNBQWdCLDJCQUEyQixDQUFDLFVBQWtCLEVBQUUsT0FBZSxFQUFFLFdBQW1CO0lBQ2hHLElBQUksT0FBTyxHQUFXLFNBQVMsQ0FBQztJQUNoQyxJQUFJLEtBQUssR0FBVyxTQUFTLENBQUM7SUFFOUIsSUFBSSxPQUFPLEtBQUssS0FBSyxFQUFFO1FBQ25CLEtBQUssR0FBRyxPQUFPLENBQUM7UUFDaEIsT0FBTyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsQ0FBQztLQUN6RDtJQUVELE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3ZDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDcEQsTUFBTSxDQUFJLFVBQVUsMkJBQXNCLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ3BFLENBQUM7QUFaRCxrRUFZQzs7Ozs7Ozs7O0FDaERELDZEQUF1QztBQUV2QyxtQ0FBa0M7QUFFbEMsU0FBZ0IsVUFBVSxDQUFDLFVBQWtCLEVBQUUsV0FBMkMsRUFBRSxZQUE0QyxFQUFFLGNBQThDO0lBQXpJLDRCQUFBLEVBQUEsdUJBQTJDO0lBQUUsNkJBQUEsRUFBQSx3QkFBNEM7SUFBRSwrQkFBQSxFQUFBLDBCQUE4QztJQUNwTCxJQUFNLFNBQVMsR0FBZ0IsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUV6RCxJQUFJLFNBQVMsRUFBRTtRQUNYLElBQU0sT0FBTyxHQUFrQixpQkFBTyxDQUFDLFNBQVMsRUFBRTtZQUM5QyxRQUFRLEVBQUUsQ0FBQztZQUNYLE9BQU8sRUFBRSxLQUFLO1lBQ2QsUUFBUSxFQUFFLFFBQVE7WUFDbEIsVUFBVSxFQUFFLE1BQU07U0FDckIsQ0FBQyxDQUFDO1FBRUgsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsU0FBUyxDQUFDLGFBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMvRixPQUFPLE9BQU8sQ0FBQztLQUNsQjtJQUVELE9BQU8sU0FBUyxDQUFDO0FBQ3JCLENBQUM7QUFoQkQsZ0NBZ0JDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxXQUErQixFQUFFLFlBQWdDLEVBQUUsY0FBa0MsRUFBRSxlQUE0QixFQUFFLE9BQXNCO0lBQ2pMLElBQU0sWUFBWSxHQUFHO1FBQ2pCLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO1FBQ3pFLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxlQUFlLEVBQUUsT0FBTyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO1FBQzNFLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsT0FBTyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO1FBQzNFLEVBQUUsV0FBVyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsT0FBTyxDQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO0tBQzFGLENBQUM7SUFFRixZQUFZLENBQUMsR0FBRyxDQUFDLFVBQUEsS0FBSztRQUNsQixJQUFJLEtBQUssQ0FBQyxRQUFRLEVBQUU7WUFDaEIsSUFBTSxHQUFHLEdBQTRCLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ25FLElBQUksR0FBRztnQkFDSCxHQUFHLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7U0FDL0Q7YUFDSSxJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUU7WUFDeEIsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU87Z0JBQ3RCLEtBQUssQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7U0FDN0U7SUFDTCxDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUM7QUFFRCxTQUFnQixtQkFBbUIsQ0FBQyxVQUFrQjs7SUFDbEQsSUFBTSxTQUFTLEdBQWdCLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekQsTUFBQSxTQUFTLENBQUMsYUFBYSwwQ0FBRSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsZUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFRLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDL0YsQ0FBQztBQUhELGtEQUdDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzdDRCxtQ0FBa0M7QUFDbEMsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQy9CLGtEQUE0QjtBQUU1QixTQUFnQixnQkFBZ0I7SUFDNUIsSUFBSSxPQUFPLEdBQWEsRUFBRSxDQUFDO0lBQzNCLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDdkIsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM5QixDQUFDO0FBUEQsNENBT0M7QUFFRCxTQUFnQixTQUFTLENBQUMsU0FBaUI7SUFDdkMsSUFBTSxVQUFVLEdBQVcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN2RCxJQUFJLE1BQU0sR0FBYSxFQUFFLENBQUM7SUFFMUIsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDbEMsSUFBTSxJQUFJLEdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUMvQixJQUFNLEtBQUssR0FBVyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBRWpDLElBQUksS0FBSyxLQUFLLEVBQUU7WUFDWixNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQzdCLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQztBQWJELDhCQWFDO0FBR0QsU0FBZ0IsZ0JBQWdCO0lBQzVCLElBQUksTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUMsTUFBTSxFQUFFO1FBQ2xDLElBQU0sYUFBYSxHQUFrQixNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUM7UUFFOUUsSUFBSSxhQUFhLGFBQWIsYUFBYSx1QkFBYixhQUFhLENBQUUsSUFBSSxHQUFHLE1BQU0sRUFBRTtZQUM5QixJQUFNLG9CQUFvQixHQUFXLGtCQUFrQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3ZFLE9BQXlCO2dCQUNyQixlQUFlLEVBQUUsYUFBYTtnQkFDOUIsc0JBQXNCLEVBQUUsb0JBQW9CO2FBQy9DLENBQUE7U0FDSjtLQUNKO0lBRUQsT0FBTyxTQUFTLENBQUM7QUFDckIsQ0FBQztBQWRELDRDQWNDO0FBRUQsU0FBZ0IsbUJBQW1CLENBQUMsU0FBaUI7SUFDakQsSUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuRCxJQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekQsSUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFELElBQU0saUJBQWlCLEdBQUcsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDekQsSUFBTSxPQUFPLEdBQUcsa0JBQWtCLENBQUksVUFBVSxlQUFVLEtBQUssa0JBQWEsUUFBUSw4RUFBMkUsQ0FBQyxDQUFDO0lBQ2pLLElBQU0sYUFBYSxHQUFHLGdCQUFnQixFQUFFLENBQUM7SUFDekMsSUFBTSxpQkFBaUIsR0FBTSxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLG9CQUFpQixDQUFDO0lBRS9HLE9BQWtCO1FBQ2QsT0FBTyxFQUFFLEtBQUs7UUFDZCxVQUFVLEVBQUUsUUFBUTtRQUNwQixZQUFZLEVBQUUsVUFBVTtRQUN4QixtQkFBbUIsRUFBRSxpQkFBaUI7UUFDdEMsU0FBUyxFQUFFLE9BQU87UUFDbEIsZUFBZSxFQUFFLGFBQWE7UUFDOUIsbUJBQW1CLEVBQUUsaUJBQWlCO0tBQ3pDLENBQUE7QUFDTCxDQUFDO0FBbEJELGtEQWtCQztBQUVELFNBQWdCLGFBQWE7SUFDekIsSUFBTSxHQUFHLEdBQXFCLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUVyRSxJQUFJLEdBQUcsRUFBRTtRQUNMLE9BQXNCO1lBQ2xCLGFBQWEsRUFBRSxHQUFHLENBQUMsR0FBRztZQUN0QixnQkFBZ0IsRUFBRSxHQUFHLENBQUMsTUFBTTtZQUM1QixlQUFlLEVBQUUsR0FBRyxDQUFDLEtBQUs7U0FDN0IsQ0FBQTtLQUNKO0lBRUQsT0FBTyxTQUFTLENBQUM7QUFDckIsQ0FBQztBQVpELHNDQVlDO0FBRUQsU0FBZ0IsT0FBTztJQUNuQixJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUMsTUFBTTtRQUNsQyxPQUFPLFNBQVMsQ0FBQztJQUVyQixJQUFNLEdBQUcsR0FBVyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDakUsSUFBTSxFQUFFLEdBQUcsMEJBQTBCLENBQUM7SUFDdEMsSUFBTSxLQUFLLEdBQTRCLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7SUFFckQsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ3hDLENBQUM7QUFURCwwQkFTQztBQUVELFNBQWdCLFlBQVk7SUFDeEIsSUFBTSxRQUFRLEdBQWUsZUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFXLENBQUM7SUFDdEQsSUFBTSxVQUFVLEdBQWlCLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ3hGLElBQU0sUUFBUSxHQUFZLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUMsSUFBTSxLQUFLLEdBQVksUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QyxJQUFNLFlBQVksR0FBa0IsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3RCxJQUFNLE9BQU8sR0FBUyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEssSUFBTSxLQUFLLEdBQWEsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQy9MLElBQU0sT0FBTyxHQUFhLENBQUMsZUFBSyxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUMvRCxJQUFNLGVBQWUsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLFVBQUEsSUFBSSxJQUFJLE9BQUEsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBM0IsQ0FBMkIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFDLElBQUksRUFBRSxJQUFJLElBQUssT0FBQSxJQUFJLEdBQUcsSUFBSSxFQUFYLENBQVcsQ0FBQyxDQUFDO0lBRWhILElBQU0sV0FBVyxHQUFrQjtRQUMvQixxQkFBcUIsRUFBRSxZQUFZLENBQUMsUUFBUTtRQUM1QyxpQkFBaUIsRUFBRSxZQUFZLENBQUMsSUFBSTtRQUNwQyxpQkFBaUIsRUFBRSxZQUFZLENBQUMsSUFBSTtRQUNwQyxlQUFlLEVBQUUsWUFBWSxDQUFDLEVBQUU7UUFDaEMsc0JBQXNCLEVBQUUsWUFBWSxDQUFDLFNBQVM7UUFDOUMsNkJBQTZCLEVBQUUsWUFBWSxDQUFDLGdCQUFnQjtRQUM1RCw0QkFBNEIsRUFBRSxZQUFZLENBQUMsZUFBZTtRQUMxRCxLQUFLLEVBQUUsS0FBSztRQUNaLE9BQU8sRUFBRSxPQUFPO1FBQ2hCLGVBQWUsRUFBRSxlQUFlO0tBQ25DLENBQUM7SUFFRixPQUFPLHNCQUFrQixRQUFRLEdBQUssV0FBVyxDQUFFLENBQUM7QUFDeEQsQ0FBQztBQXpCRCxvQ0F5QkM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3BIRCxtQ0FBa0M7QUFFbEMscURBQXlDO0FBQ3pDLHVEQUEyQztBQUUzQyxTQUFnQixjQUFjLENBQUMsY0FBaUM7SUFDNUQsaUJBQWlCLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDbEMsSUFBTSxZQUFZLEdBQVcsZUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEcsSUFBTSxhQUFhLEdBQThCLFNBQVMsQ0FBQyw0Q0FBNEMsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUV0SCxJQUFJLGFBQWEsRUFBRTtRQUNmLElBQU0sZ0JBQWdCLEdBQVcsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkUsSUFBTSxhQUFhLEdBQXVCLFNBQVMsQ0FBQyw2QkFBNkIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3BHLElBQU0sb0JBQW9CLEdBQTJCLENBQUMsY0FBYyxDQUFDLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUMxRyxtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0tBQzdDOztRQUVHLE9BQU8sQ0FBQyxJQUFJLENBQUMsNkVBQTJFLFlBQWMsQ0FBQyxDQUFDO0FBQ2hILENBQUM7QUFiRCx3Q0FhQztBQUVELFNBQWdCLG1CQUFtQixDQUFDLGNBQWlDO0lBQ2pFLE9BQU8sZUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUM7SUFFeEQsSUFBTSxLQUFLLEdBQVcsZUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsVUFBQSxHQUFHLElBQUksT0FBQSxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssY0FBYyxDQUFDLEVBQUUsRUFBNUIsQ0FBNEIsQ0FBQyxDQUFDO0lBQ25HLGVBQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztJQUUvQyxlQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFFaEMsSUFBSSxDQUFDLGVBQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBTTtRQUNyQyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUM1QyxDQUFDO0FBVkQsa0RBVUM7QUFFRCxTQUFnQiwyQkFBMkIsQ0FBQyxTQUE0QjtJQUNwRSxJQUFNLE9BQU8sR0FBUSxlQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQztJQUUxQyxJQUFJLGVBQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxJQUFJLGVBQU0sQ0FBQyxnQkFBZ0IsRUFBRTtRQUNqRSxVQUFVLENBQUMsY0FBYyxDQUFDLDZCQUFzQixlQUFNLENBQUMsZ0JBQWdCLGlDQUFvQixDQUFDLENBQUM7UUFDN0YsT0FBTyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQzFDLE9BQU8sSUFBSSxDQUFDO0tBQ2Y7SUFFRCxPQUFPLEtBQUssQ0FBQztBQUNqQixDQUFDO0FBVkQsa0VBVUM7QUFFRCxTQUFTLG1CQUFtQixDQUFDLE1BQThCO0lBQ3ZELElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFBLENBQUMsSUFBSSxPQUFBLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxTQUFTLElBQUksSUFBSSxDQUFDLEVBQS9CLENBQStCLENBQUMsRUFBRTtRQUNwRCxlQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBVyxNQUFNLENBQUMsQ0FBQztRQUNyRCxlQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7S0FDbkM7QUFDTCxDQUFDO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxjQUFpQzs7SUFDeEQsSUFBTSxNQUFNLEdBQVcsY0FBYyxDQUFDLEVBQUUsQ0FBQztJQUN6QyxJQUFNLE9BQU87UUFDVCxHQUFDLE1BQU0sSUFBRyxjQUFjO1dBQzNCLENBQUE7SUFFRCxlQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQix5QkFBUSxlQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixHQUFLLE9BQU8sQ0FBRSxDQUFBO0FBQ3BGLENBQUM7Ozs7OztBQzFERCxtQ0FBa0M7QUFHbEMsU0FBZ0IsUUFBUTtJQUNwQixJQUFNLFVBQVUsR0FBUSxlQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztJQUNoRCxJQUFNLE9BQU8sR0FBYSxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFFOUQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFBLEdBQUc7UUFDVCxJQUFBLEtBQWlCLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBbkQsS0FBSyxRQUFBLEVBQUUsS0FBSyxRQUF1QyxDQUFDO1FBQzNELElBQU0sT0FBTyxHQUFhLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNqRSxJQUFNLENBQUMsR0FBVyxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQzdCLElBQU0sQ0FBQyxHQUFXLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDO1FBRTVDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzlCLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQVpELDRCQVlDO0FBRUQsU0FBUyxVQUFVLENBQUMsT0FBaUIsRUFBRSxDQUFTLEVBQUUsQ0FBUztJQUN2RCxJQUFNLFdBQVcsR0FBd0IsSUFBSSxHQUFHLENBQUM7UUFDN0MsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDO1FBQ2QsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDO1FBQ2QsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDO1FBQ2QsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDO1FBQ2QsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDO1FBQ2QsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDO1FBQ2QsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDO0tBQ2pCLENBQUMsQ0FBQztJQUVILE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBQyxPQUFPLEVBQUUsS0FBSztRQUN2QixJQUFNLFNBQVMsR0FBdUIsV0FBVyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFdEgsSUFBSSxTQUFTLEVBQUU7WUFDWCxJQUFNLE9BQU8sR0FBYyxhQUFhLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN0RCxTQUFTLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1NBQ2pDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxPQUFlO0lBQ3JDLElBQU0sUUFBUSxHQUFXLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZELE9BQU8sTUFBTSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdkQsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLFdBQW1CLEVBQUUsU0FBb0I7SUFDeEQsSUFBTSxLQUFLLEdBQVcsc0JBQXNCLENBQUM7SUFFN0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUU7UUFDMUIsT0FBTyxDQUFDLEdBQUcsQ0FBSSxXQUFXLFlBQU8sU0FBUyxDQUFDLElBQUksU0FBSSxTQUFTLENBQUMsSUFBTSxDQUFDLENBQUM7UUFDckUsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxHQUFHLDhCQUEwQixXQUFXLFlBQVMsQ0FBQTtLQUNoSTtBQUNMLENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxHQUFXLEVBQUUsR0FBVyxFQUFFLEtBQWE7SUFDMUQsT0FBbUI7UUFDZixDQUFDLEVBQUUsR0FBRztRQUNOLENBQUMsRUFBRSxHQUFHO1FBQ04sSUFBSSxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUs7UUFDdkIsSUFBSSxFQUFFLEdBQUcsR0FBRyxDQUFDO0tBQ2hCLENBQUE7QUFDTCxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDMURELDZEQUFpRDtBQUNqRCxtQ0FBa0M7QUFDbEMsK0NBQW1DO0FBQ25DLGlEQUFxQztBQUNyQyx5REFBNkM7QUFFN0MsU0FBZ0IsZUFBZSxDQUFDLGdCQUE2QixFQUFFLElBQVk7SUFDdkUsSUFBTSxlQUFlLEdBQXVCLFFBQVEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFMUUsSUFBSSxlQUFlLEVBQUU7UUFDakIsS0FBdUIsVUFBZ0IsRUFBaEIscUNBQWdCLEVBQWhCLDhCQUFnQixFQUFoQixJQUFnQixFQUFFO1lBQXBDLElBQUksVUFBVSx5QkFBQTtZQUNmLElBQUksR0FBRyxHQUFzQixRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzlELEdBQUcsQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3QixHQUFHLENBQUMsU0FBUyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbkMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNwQztLQUNKO0FBQ0wsQ0FBQztBQVhELDBDQVdDO0FBRUQsU0FBZ0IsWUFBWSxDQUFDLFdBQXdCO0lBQ2pELElBQU0sZUFBZSxHQUFHLGVBQU0sQ0FBQyxLQUFLLENBQUMsZUFBZ0IsQ0FBQztJQUV0RCxNQUFNLENBQUMscUNBQXFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakcsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQy9FLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEdBQUcsZUFBZSxDQUFDLGFBQWEsQ0FBQztJQUM1RixNQUFNLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxHQUFHLGtDQUFzQixXQUFXLENBQUMsZUFBZSxhQUFRLFdBQVcsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUcsQ0FBQztBQUNsSyxDQUFDO0FBUEQsb0NBT0M7QUFFRCxTQUFnQixZQUFZO0lBQ3hCLElBQU0sVUFBVSxHQUFXLDRIQUE0SCxDQUFDO0lBQ3hKLElBQU0sR0FBRyxHQUFXLGVBQU0sQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxlQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLGVBQU0sQ0FBQyxnQkFBZ0IsQ0FBQztJQUVyRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxNQUFNLENBQzNCLE1BQU0sQ0FBQyxVQUFVLENBQUM7U0FDYixJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQ3JCLE1BQU0sQ0FBQztRQUNKLEtBQUssRUFBRSxJQUFJO1FBQ1gsUUFBUSxFQUFFLEtBQUs7UUFDZixhQUFhLEVBQUUsSUFBSTtRQUNuQixTQUFTLEVBQUUsS0FBSztRQUNoQixJQUFJLEVBQUUsSUFBSTtRQUNWLElBQUksRUFBRSxJQUFJO1FBQ1YsU0FBUyxFQUFFLEtBQUs7UUFDaEIsS0FBSyxFQUFFLEVBQUU7UUFDVCxLQUFLLEVBQUUsTUFBTTtRQUNiLE1BQU0sRUFBRSxNQUFNO1FBQ2QsS0FBSyxFQUFFLGNBQU0sT0FBQSxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsRUFBNUMsQ0FBNEM7S0FDNUQsQ0FBQyxDQUFDO0lBRVAsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQzVCLENBQUM7QUF0QkQsb0NBc0JDO0FBRUQsU0FBZ0IscUJBQXFCLENBQUMsVUFBa0I7SUFDcEQsSUFBSSxlQUFNLENBQUMsS0FBSyxDQUFDLE9BQU87UUFDcEIsT0FBTyxDQUFDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRTVDLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQzFDLE1BQU0sQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN6RCxNQUFNLENBQUMsNEJBQTRCLENBQUMsQ0FBQyxNQUFNLENBQUMsd0NBQXdDLENBQUMsQ0FBQztJQUN0RixNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNuQyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxNQUFNLENBQUMsaUNBQWlDLENBQUMsQ0FBQztBQUM1RSxDQUFDO0FBVEQsc0RBU0M7QUFFRCxTQUFnQixpQkFBaUIsQ0FBQyxRQUFnQjtJQUM5QyxJQUFJLFFBQVEsS0FBSyxNQUFNO1FBQ25CLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLENBQUMsMEJBQTBCLENBQUMsQ0FBQztTQUN0RCxJQUFJLFFBQVEsS0FBSyxNQUFNO1FBQ3hCLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsMEJBQTBCLENBQUMsQ0FBQztBQUM1RCxDQUFDO0FBTEQsOENBS0M7QUFFRCxTQUFnQixnQkFBZ0I7SUFDNUIsSUFBTSxlQUFlLEdBQXNCLGVBQU0sQ0FBQyxLQUFLLENBQUMsZUFBZ0IsQ0FBQztJQUV6RSxJQUFJLGVBQWUsQ0FBQyxhQUFhLEtBQUssU0FBUztRQUMzQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUM3RSxDQUFDO0FBTEQsNENBS0M7QUFFRCxTQUFnQixlQUFlO0lBQzNCLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN6QyxhQUFhLENBQUMsaUJBQWlCLENBQUMsNEJBQTRCLENBQUMsQ0FBQztBQUNsRSxDQUFDO0FBSEQsMENBR0M7QUFFRCxTQUFnQixxQkFBcUI7SUFDakMsSUFBTSxRQUFRLEdBQWUsZUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFXLENBQUM7SUFDdEQsSUFBTSxtQkFBbUIsR0FBb0IsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO0lBRXpGLE9BQU8sbUJBQW1CLENBQUMsR0FBRyxDQUFDLFVBQUEsR0FBRztRQUM5QixJQUFNLEVBQUUsR0FBVyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdCLElBQUksS0FBSyxHQUFXLE1BQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsZ0JBQWEsQ0FBQztRQUNsRCxPQUFPLE9BQUssRUFBRSw2QkFBd0IsS0FBSyxRQUFLLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3BCLENBQUM7QUFURCxzREFTQztBQUVELFNBQWdCLGlCQUFpQjtJQUM3QixXQUFXLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDM0MsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzlCLE1BQU0sQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUNqRSxDQUFDO0FBSkQsOENBSUM7Ozs7O0FDaEdEO0lBQUE7SUE2RkEsQ0FBQztJQTNGVSxvQkFBYyxHQUFyQixVQUFzQixVQUFxQyxFQUFFLFVBQW9CLEVBQUUsUUFBaUQsRUFBRSxtQkFBa0MsRUFBRSxhQUE2QjtRQUFwSCx5QkFBQSxFQUFBLHFCQUFpRDtRQUFFLG9DQUFBLEVBQUEsMEJBQWtDO1FBQUUsOEJBQUEsRUFBQSxxQkFBNkI7UUFDbk0sSUFBTSxhQUFhLEdBQVcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRXpDLENBQUMsU0FBUyxVQUFVO1lBQ2hCLElBQU0sT0FBTyxHQUEwQixRQUFRLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQVMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUUvSCxJQUFJLE9BQU8sRUFBRTtnQkFDVCxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNyQixVQUFVLEVBQUUsQ0FBQzthQUNoQjtpQkFDSTtnQkFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFpQixRQUFVLENBQUMsQ0FBQztnQkFDekMsVUFBVSxDQUFDO29CQUNQLElBQUksYUFBYSxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxhQUFhLEdBQUcsYUFBYTt3QkFDM0QsT0FBTztvQkFFWCxVQUFVLEVBQUUsQ0FBQztnQkFDakIsQ0FBQyxFQUFFLG1CQUFtQixDQUFDLENBQUM7YUFDM0I7UUFDTCxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ1QsQ0FBQztJQUVNLHVCQUFpQixHQUF4QjtRQUNJLElBQU0sVUFBVSxHQUEyQixNQUFPLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUMsVUFBVSxDQUFDO1FBQzFGLE9BQU8sS0FBSyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRU0sb0JBQWMsR0FBckIsVUFBc0IsVUFBb0I7UUFDdEMsSUFBTSxVQUFVLEdBQTJCLE1BQU8sQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxVQUFVLENBQUM7UUFDMUYsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFTSxtQkFBYSxHQUFwQixVQUFxQixRQUFnQjtRQUNqQyxJQUFJLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSTtZQUN4QyxPQUFPLElBQUksQ0FBQzs7WUFFWixPQUFPLEtBQUssQ0FBQztJQUNyQixDQUFDO0lBRU0sZ0JBQVUsR0FBakIsVUFBa0IsVUFBNEI7UUFDMUMsT0FBTyxPQUFPLFVBQVUsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQzNELENBQUM7SUFFTSxZQUFNLEdBQWIsVUFBYyxTQUFpQixFQUFFLE1BQXFCLEVBQUUsS0FBc0I7UUFBN0MsdUJBQUEsRUFBQSxhQUFxQjtRQUFFLHNCQUFBLEVBQUEsY0FBc0I7UUFDMUUsSUFBSSxNQUFzQyxDQUFDO1FBRTNDLFFBQVEsTUFBTSxFQUFFO1lBQ1osS0FBSyxJQUFJO2dCQUNMLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUMxQyxNQUFNLENBQUMsSUFBSSxHQUFHLGlCQUFpQixDQUFDO2dCQUNoQyxNQUFNLENBQUMsR0FBRyxHQUFHLFNBQVMsQ0FBQztnQkFDdkIsTUFBTTtZQUVWLEtBQUssS0FBSztnQkFDTixNQUFNLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDeEMsTUFBTSxDQUFDLElBQUksR0FBRyxVQUFVLENBQUM7Z0JBQ1AsTUFBTyxDQUFDLEdBQUcsR0FBRyxZQUFZLENBQUM7Z0JBQzNCLE1BQU8sQ0FBQyxJQUFJLEdBQUcsU0FBUyxDQUFDO2dCQUMzQyxNQUFNO1lBRVYsS0FBSyxXQUFXO2dCQUNaLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUN6QyxNQUFNLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQztnQkFDekIsTUFBTSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7Z0JBQzdCLE1BQU07WUFFVixLQUFLLFFBQVE7Z0JBQ1QsTUFBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQzFDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsaUJBQWlCLENBQUM7Z0JBQ2hDLE1BQU0sQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO2dCQUM3QixNQUFNO1lBRVY7Z0JBQ0ksTUFBTSxHQUFHLFNBQVMsQ0FBQztnQkFDbkIsTUFBTTtTQUNiO1FBRUQsSUFBSSxNQUFNO1lBQ04sS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVNLGtCQUFZLEdBQW5CLFVBQW9CLFFBQTRCLEVBQUUsS0FBYTtRQUMzRCxJQUFJLEtBQUssS0FBSyxNQUFNO1lBQ2hCLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ25DLElBQUksS0FBSyxLQUFLLE1BQU07WUFDckIsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVNLGdCQUFVLEdBQWpCLFVBQWtCLE1BQVksRUFBRSxRQUFnQjtRQUM1QyxPQUFPLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBQ0wsWUFBQztBQUFELENBN0ZBLEFBNkZDLElBQUE7Ozs7Ozs7QUM3RkQsbUNBQWtDO0FBRWxDLFNBQWdCLFdBQVc7SUFDdkIsSUFBTSxlQUFlLEdBQUcsZUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFnQixDQUFDO0lBRXRELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSTtRQUNyQixPQUFPO0lBRVgsSUFBTSxPQUFPLEdBQWEsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRXJFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ1gsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDNUMsQ0FBQztBQVZELGtDQVVDO0FBRUQsU0FBZ0IseUJBQXlCLENBQUMsV0FBbUI7O0lBQ3pELElBQU0sUUFBUSxHQUFlLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVyxDQUFDO0lBQ3RELElBQU0sVUFBVSxHQUFnQixRQUFRLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7SUFFcEYsT0FBTyxNQUFBLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBQSxHQUFHLElBQUksT0FBQSxXQUFXLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBekIsQ0FBeUIsQ0FBQywwQ0FBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEUsQ0FBQztBQUxELDhEQUtDO0FBRUQsU0FBZ0Isd0NBQXdDLENBQUMsVUFBbUMsRUFBRSxjQUFzQjs7SUFDaEgsSUFBTSxRQUFRLEdBQWUsZUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFXLENBQUM7SUFDdEQsSUFBTSxrQkFBa0IsR0FBb0IsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO0lBRXhGLE9BQU8sTUFBQSxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsVUFBQSxHQUFHLElBQUksT0FBQSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQTlDLENBQThDLENBQUMsMENBQUcsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzNHLENBQUM7QUFMRCw0RkFLQztBQUVELFNBQWdCLDZCQUE2QixDQUFDLGFBQXFCOztJQUMvRCxJQUFNLFFBQVEsR0FBZSxlQUFNLENBQUMsS0FBSyxDQUFDLFVBQVcsQ0FBQztJQUN0RCxJQUFNLGlCQUFpQixHQUFtQixRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7SUFFdEYsT0FBTyxNQUFBLGlCQUFpQixDQUFDLElBQUksQ0FBQyxVQUFBLEdBQUcsSUFBSSxPQUFBLGFBQWEsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUEzQixDQUEyQixDQUFDLDBDQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvRSxDQUFDO0FBTEQsc0VBS0M7QUFFRCxTQUFnQixxQkFBcUIsQ0FBQyxhQUFxQixFQUFFLGVBQThCOztJQUN2RixJQUFNLEtBQUssR0FBRyxNQUFBLGVBQWUsYUFBZixlQUFlLHVCQUFmLGVBQWUsQ0FBRSxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQUEsR0FBRyxJQUFJLE9BQUEsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxhQUFhLEVBQTNCLENBQTJCLENBQUMsMENBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdGLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUNqRCxDQUFDO0FBSEQsc0RBR0M7QUFFRCxTQUFnQiw0Q0FBNEMsQ0FBQyxJQUFZO0lBQ3JFLElBQU0sUUFBUSxHQUFlLGVBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVyxDQUFDO0lBQ3RELElBQU0sa0JBQWtCLEdBQW9CLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO0lBQ25GLE9BQU8sa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQUEsR0FBRyxJQUFJLE9BQUEsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQWxCLENBQWtCLENBQUMsQ0FBQztBQUM5RCxDQUFDO0FBSkQsb0dBSUM7QUFFRCxTQUFnQiwyQkFBMkIsQ0FBQyxjQUFzQjtJQUM5RCxJQUFNLGFBQWEsR0FBK0IsK0JBQStCLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDbEcsT0FBTyxhQUFhLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsVUFBQSxHQUFHLElBQUksT0FBQSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFoRCxDQUFnRCxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUNsSCxDQUFDO0FBSEQsa0VBR0M7QUFFRCxTQUFnQiwyQkFBMkI7SUFDdkMsT0FBTyxDQUFDLGVBQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLFVBQUEsR0FBRyxJQUFJLE9BQUEsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMvRSxDQUFDO0FBRkQsa0VBRUM7QUFFRCxTQUFTLCtCQUErQixDQUFDLGNBQXNCOztJQUMzRCxJQUFNLFFBQVEsR0FBZSxlQUFNLENBQUMsS0FBSyxDQUFDLFVBQVcsQ0FBQztJQUN0RCxJQUFNLGtCQUFrQixHQUFvQixRQUFRLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztJQUVuRixPQUFPLE1BQUEsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQUEsR0FBRyxJQUFJLE9BQUEsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxjQUFjLEVBQTVCLENBQTRCLENBQUMsMENBQUUsVUFBVSxDQUFDO0FBQ3BGLENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUFDLEtBQW1COztJQUN6QyxJQUFNLFFBQVEsR0FBZSxlQUFNLENBQUMsS0FBSyxDQUFDLFVBQVcsQ0FBQztJQUN0RCxJQUFNLFlBQVksR0FBbUIsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO0lBRWpGLE9BQU8sTUFBQSxZQUFZLENBQUMsSUFBSSxDQUFDLFVBQUEsR0FBRyxJQUFJLE9BQUEsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQW5ELENBQW1ELENBQUMsMENBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xHLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3JFRCwrQkFBa0M7QUFDbEMscUVBQXlEO0FBRXpELDJDQUEwQztBQUMxQywwREFBb0M7QUFDcEMsdURBQTJDO0FBQzNDLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBQ2xDLG1EQUF1QztBQUN2QyxrRUFBc0Q7QUFDdEQscURBQXlDO0FBRXpDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7SUFHNUIsZUFBSyxDQUFDLE1BQU0sQ0FBQyxlQUFNLENBQUMsYUFBYSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNqRCxlQUFLLENBQUMsTUFBTSxDQUFDLGVBQU0sQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDckQsZUFBSyxDQUFDLE1BQU0sQ0FBQyxlQUFNLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZELGVBQUssQ0FBQyxNQUFNLENBQUMsZUFBTSxDQUFDLGNBQWMsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFHbkQsYUFBYSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBRy9DLGVBQUssQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFHdEQsZUFBSyxDQUFDLGNBQWMsQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFHL0QsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3ZCLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN0QixNQUFNLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztBQUVoQyxDQUFDLENBQUMsQ0FBQztBQUlILE1BQU0sQ0FBQyxRQUFRLEdBQUc7SUFDZCxJQUFNLE9BQU8sR0FBRyxlQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQztJQUNyQyxJQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDO0lBRXZDLElBQUksV0FBVyxHQUFHLEdBQUcsRUFBRTtRQUNuQixPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JCLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3hDLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxLQUFLLEVBQUUsQ0FBQztLQUNwQjtTQUNJLElBQUksV0FBVyxJQUFJLEdBQUcsRUFBRTtRQUN6QixNQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN4QyxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsS0FBSyxFQUFFLENBQUM7S0FDcEI7QUFDTCxDQUFDLENBQUE7QUFFRCxTQUFTLGNBQWMsQ0FBQyxHQUFRO0lBQzVCLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxRQUFRO1FBQzlCLE9BQU87SUFFWCxJQUFNLElBQUksR0FBYyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUU3QyxPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUF3QixJQUFJLENBQUMsSUFBTSxDQUFDLENBQUM7SUFDakQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVsQixRQUFRLElBQUksQ0FBQyxLQUFLLEVBQUU7UUFDaEIsS0FBSyxtQkFBbUIsQ0FBQyxDQUFDO1lBQ3RCLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNsQixNQUFNO1NBQ1Q7UUFDRCxLQUFLLDBCQUEwQixDQUFDLENBQUM7WUFDN0IsS0FBSyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzVCLE1BQU07U0FDVDtRQUNELEtBQUssaUNBQWlDLENBQUMsQ0FBQztZQUNwQyxLQUFLLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbkMsTUFBTTtTQUNUO1FBQ0QsS0FBSyx1QkFBdUIsQ0FBQyxDQUFDO1lBQzFCLEtBQUssQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDMUIsTUFBTTtTQUNUO1FBQ0QsS0FBSyw2QkFBNkIsQ0FBQyxDQUFDO1lBQ2hDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNoQyxNQUFNO1NBQ1Q7UUFDRDtZQUNJLE1BQU07S0FDYjtBQUNMLENBQUMiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbnZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG5mb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxufVxuXG4vLyBTdXBwb3J0IGRlY29kaW5nIFVSTC1zYWZlIGJhc2U2NCBzdHJpbmdzLCBhcyBOb2RlLmpzIGRvZXMuXG4vLyBTZWU6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NCNVUkxfYXBwbGljYXRpb25zXG5yZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbnJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xuXG5mdW5jdGlvbiBnZXRMZW5zIChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gVHJpbSBvZmYgZXh0cmEgYnl0ZXMgYWZ0ZXIgcGxhY2Vob2xkZXIgYnl0ZXMgYXJlIGZvdW5kXG4gIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlYXRnYW1taXQvYmFzZTY0LWpzL2lzc3Vlcy80MlxuICB2YXIgdmFsaWRMZW4gPSBiNjQuaW5kZXhPZignPScpXG4gIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuXG5cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IHZhbGlkTGVuID09PSBsZW5cbiAgICA/IDBcbiAgICA6IDQgLSAodmFsaWRMZW4gJSA0KVxuXG4gIHJldHVybiBbdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbl1cbn1cblxuLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChiNjQpIHtcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gX2J5dGVMZW5ndGggKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikge1xuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cblxuICB2YXIgYXJyID0gbmV3IEFycihfYnl0ZUxlbmd0aChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pKVxuXG4gIHZhciBjdXJCeXRlID0gMFxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgdmFyIGxlbiA9IHBsYWNlSG9sZGVyc0xlbiA+IDBcbiAgICA/IHZhbGlkTGVuIC0gNFxuICAgIDogdmFsaWRMZW5cblxuICB2YXIgaVxuICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTgpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCAxMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHxcbiAgICAgIHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMyldXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDE2KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAyKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMSkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxMCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDQpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDYgJiAweDNGXSArXG4gICAgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9XG4gICAgICAoKHVpbnQ4W2ldIDw8IDE2KSAmIDB4RkYwMDAwKSArXG4gICAgICAoKHVpbnQ4W2kgKyAxXSA8PCA4KSAmIDB4RkYwMCkgK1xuICAgICAgKHVpbnQ4W2kgKyAyXSAmIDB4RkYpXG4gICAgb3V0cHV0LnB1c2godHJpcGxldFRvQmFzZTY0KHRtcCkpXG4gIH1cbiAgcmV0dXJuIG91dHB1dC5qb2luKCcnKVxufVxuXG5mdW5jdGlvbiBmcm9tQnl0ZUFycmF5ICh1aW50OCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW4gPSB1aW50OC5sZW5ndGhcbiAgdmFyIGV4dHJhQnl0ZXMgPSBsZW4gJSAzIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG4gIHZhciBwYXJ0cyA9IFtdXG4gIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzIC8vIG11c3QgYmUgbXVsdGlwbGUgb2YgM1xuXG4gIC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbjIgPSBsZW4gLSBleHRyYUJ5dGVzOyBpIDwgbGVuMjsgaSArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgIHBhcnRzLnB1c2goZW5jb2RlQ2h1bmsodWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKSkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiIsIiIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGh0dHBzOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuXG52YXIgS19NQVhfTEVOR1RIID0gMHg3ZmZmZmZmZlxuZXhwb3J0cy5rTWF4TGVuZ3RoID0gS19NQVhfTEVOR1RIXG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFByaW50IHdhcm5pbmcgYW5kIHJlY29tbWVuZCB1c2luZyBgYnVmZmVyYCB2NC54IHdoaWNoIGhhcyBhbiBPYmplY3RcbiAqICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIFdlIHJlcG9ydCB0aGF0IHRoZSBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGlmIHRoZSBhcmUgbm90IHN1YmNsYXNzYWJsZVxuICogdXNpbmcgX19wcm90b19fLiBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YFxuICogKFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4KS4gSUUgMTAgbGFja3Mgc3VwcG9ydFxuICogZm9yIF9fcHJvdG9fXyBhbmQgaGFzIGEgYnVnZ3kgdHlwZWQgYXJyYXkgaW1wbGVtZW50YXRpb24uXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gdHlwZWRBcnJheVN1cHBvcnQoKVxuXG5pZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJlxuICAgIHR5cGVvZiBjb25zb2xlLmVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gIGNvbnNvbGUuZXJyb3IoXG4gICAgJ1RoaXMgYnJvd3NlciBsYWNrcyB0eXBlZCBhcnJheSAoVWludDhBcnJheSkgc3VwcG9ydCB3aGljaCBpcyByZXF1aXJlZCBieSAnICtcbiAgICAnYGJ1ZmZlcmAgdjUueC4gVXNlIGBidWZmZXJgIHY0LnggaWYgeW91IHJlcXVpcmUgb2xkIGJyb3dzZXIgc3VwcG9ydC4nXG4gIClcbn1cblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICAvLyBDYW4gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWQ/XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLl9fcHJvdG9fXyA9IHsgX19wcm90b19fOiBVaW50OEFycmF5LnByb3RvdHlwZSwgZm9vOiBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9IH1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MlxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlci5wcm90b3R5cGUsICdwYXJlbnQnLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKHRoaXMpKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgcmV0dXJuIHRoaXMuYnVmZmVyXG4gIH1cbn0pXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIucHJvdG90eXBlLCAnb2Zmc2V0Jywge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0aGlzKSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIHJldHVybiB0aGlzLmJ5dGVPZmZzZXRcbiAgfVxufSlcblxuZnVuY3Rpb24gY3JlYXRlQnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKGxlbmd0aCA+IEtfTUFYX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgdmFsdWUgXCInICsgbGVuZ3RoICsgJ1wiIGlzIGludmFsaWQgZm9yIG9wdGlvbiBcInNpemVcIicpXG4gIH1cbiAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2VcbiAgdmFyIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGxlbmd0aClcbiAgYnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGJ1ZlxufVxuXG4vKipcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgaGF2ZSB0aGVpclxuICogcHJvdG90eXBlIGNoYW5nZWQgdG8gYEJ1ZmZlci5wcm90b3R5cGVgLiBGdXJ0aGVybW9yZSwgYEJ1ZmZlcmAgaXMgYSBzdWJjbGFzcyBvZlxuICogYFVpbnQ4QXJyYXlgLCBzbyB0aGUgcmV0dXJuZWQgaW5zdGFuY2VzIHdpbGwgaGF2ZSBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgbWV0aG9kc1xuICogYW5kIHRoZSBgVWludDhBcnJheWAgbWV0aG9kcy4gU3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXRcbiAqIHJldHVybnMgYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogVGhlIGBVaW50OEFycmF5YCBwcm90b3R5cGUgcmVtYWlucyB1bm1vZGlmaWVkLlxuICovXG5cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICdUaGUgXCJzdHJpbmdcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nLiBSZWNlaXZlZCB0eXBlIG51bWJlcidcbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIGFsbG9jVW5zYWZlKGFyZylcbiAgfVxuICByZXR1cm4gZnJvbShhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbmlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAhPSBudWxsICYmXG4gICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsIFN5bWJvbC5zcGVjaWVzLCB7XG4gICAgdmFsdWU6IG51bGwsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuZnVuY3Rpb24gZnJvbSAodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KVxuICB9XG5cbiAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh2YWx1ZSlcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksICcgK1xuICAgICAgJ29yIEFycmF5LWxpa2UgT2JqZWN0LiBSZWNlaXZlZCB0eXBlICcgKyAodHlwZW9mIHZhbHVlKVxuICAgIClcbiAgfVxuXG4gIGlmIChpc0luc3RhbmNlKHZhbHVlLCBBcnJheUJ1ZmZlcikgfHxcbiAgICAgICh2YWx1ZSAmJiBpc0luc3RhbmNlKHZhbHVlLmJ1ZmZlciwgQXJyYXlCdWZmZXIpKSkge1xuICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdUaGUgXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG9mIHR5cGUgbnVtYmVyLiBSZWNlaXZlZCB0eXBlIG51bWJlcidcbiAgICApXG4gIH1cblxuICB2YXIgdmFsdWVPZiA9IHZhbHVlLnZhbHVlT2YgJiYgdmFsdWUudmFsdWVPZigpXG4gIGlmICh2YWx1ZU9mICE9IG51bGwgJiYgdmFsdWVPZiAhPT0gdmFsdWUpIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20odmFsdWVPZiwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgdmFyIGIgPSBmcm9tT2JqZWN0KHZhbHVlKVxuICBpZiAoYikgcmV0dXJuIGJcblxuICBpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvUHJpbWl0aXZlICE9IG51bGwgJiZcbiAgICAgIHR5cGVvZiB2YWx1ZVtTeW1ib2wudG9QcmltaXRpdmVdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKFxuICAgICAgdmFsdWVbU3ltYm9sLnRvUHJpbWl0aXZlXSgnc3RyaW5nJyksIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aFxuICAgIClcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgJ1RoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksICcgK1xuICAgICdvciBBcnJheS1saWtlIE9iamVjdC4gUmVjZWl2ZWQgdHlwZSAnICsgKHR5cGVvZiB2YWx1ZSlcbiAgKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbi8vIE5vdGU6IENoYW5nZSBwcm90b3R5cGUgKmFmdGVyKiBCdWZmZXIuZnJvbSBpcyBkZWZpbmVkIHRvIHdvcmthcm91bmQgQ2hyb21lIGJ1Zzpcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvMTQ4XG5CdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG5CdWZmZXIuX19wcm90b19fID0gVWludDhBcnJheVxuXG5mdW5jdGlvbiBhc3NlcnRTaXplIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgbnVtYmVyJylcbiAgfSBlbHNlIGlmIChzaXplIDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgdmFsdWUgXCInICsgc2l6ZSArICdcIiBpcyBpbnZhbGlkIGZvciBvcHRpb24gXCJzaXplXCInKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIoc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybiBhbGxvYyhzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxufVxuXG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gQnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKHNpemUpXG59XG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gU2xvd0J1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICovXG5CdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKHNpemUpXG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgfVxuXG4gIGlmICghQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICB9XG5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHZhciBidWYgPSBjcmVhdGVCdWZmZXIobGVuZ3RoKVxuXG4gIHZhciBhY3R1YWwgPSBidWYud3JpdGUoc3RyaW5nLCBlbmNvZGluZylcblxuICBpZiAoYWN0dWFsICE9PSBsZW5ndGgpIHtcbiAgICAvLyBXcml0aW5nIGEgaGV4IHN0cmluZywgZm9yIGV4YW1wbGUsIHRoYXQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzIHdpbGxcbiAgICAvLyBjYXVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBmaXJzdCBpbnZhbGlkIGNoYXJhY3RlciB0byBiZSBpZ25vcmVkLiAoZS5nLlxuICAgIC8vICdhYnh4Y2QnIHdpbGwgYmUgdHJlYXRlZCBhcyAnYWInKVxuICAgIGJ1ZiA9IGJ1Zi5zbGljZSgwLCBhY3R1YWwpXG4gIH1cblxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGggPCAwID8gMCA6IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdmFyIGJ1ZiA9IGNyZWF0ZUJ1ZmZlcihsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICBidWZbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyIChhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmIChieXRlT2Zmc2V0IDwgMCB8fCBhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcIm9mZnNldFwiIGlzIG91dHNpZGUgb2YgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQgKyAobGVuZ3RoIHx8IDApKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wibGVuZ3RoXCIgaXMgb3V0c2lkZSBvZiBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIHZhciBidWZcbiAgaWYgKGJ5dGVPZmZzZXQgPT09IHVuZGVmaW5lZCAmJiBsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5KVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQpXG4gIH0gZWxzZSB7XG4gICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlXG4gIGJ1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gZnJvbU9iamVjdCAob2JqKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIob2JqKSkge1xuICAgIHZhciBsZW4gPSBjaGVja2VkKG9iai5sZW5ndGgpIHwgMFxuICAgIHZhciBidWYgPSBjcmVhdGVCdWZmZXIobGVuKVxuXG4gICAgaWYgKGJ1Zi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBidWZcbiAgICB9XG5cbiAgICBvYmouY29weShidWYsIDAsIDAsIGxlbilcbiAgICByZXR1cm4gYnVmXG4gIH1cblxuICBpZiAob2JqLmxlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBvYmoubGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBudW1iZXJJc05hTihvYmoubGVuZ3RoKSkge1xuICAgICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcigwKVxuICAgIH1cbiAgICByZXR1cm4gZnJvbUFycmF5TGlrZShvYmopXG4gIH1cblxuICBpZiAob2JqLnR5cGUgPT09ICdCdWZmZXInICYmIEFycmF5LmlzQXJyYXkob2JqLmRhdGEpKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUxpa2Uob2JqLmRhdGEpXG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IEtfTUFYX0xFTkdUSGAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBLX01BWF9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsgS19NQVhfTEVOR1RILnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAoK2xlbmd0aCAhPSBsZW5ndGgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICBsZW5ndGggPSAwXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyID09PSB0cnVlICYmXG4gICAgYiAhPT0gQnVmZmVyLnByb3RvdHlwZSAvLyBzbyBCdWZmZXIuaXNCdWZmZXIoQnVmZmVyLnByb3RvdHlwZSkgd2lsbCBiZSBmYWxzZVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKGlzSW5zdGFuY2UoYSwgVWludDhBcnJheSkpIGEgPSBCdWZmZXIuZnJvbShhLCBhLm9mZnNldCwgYS5ieXRlTGVuZ3RoKVxuICBpZiAoaXNJbnN0YW5jZShiLCBVaW50OEFycmF5KSkgYiA9IEJ1ZmZlci5mcm9tKGIsIGIub2Zmc2V0LCBiLmJ5dGVMZW5ndGgpXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBcImJ1ZjFcIiwgXCJidWYyXCIgYXJndW1lbnRzIG11c3QgYmUgb25lIG9mIHR5cGUgQnVmZmVyIG9yIFVpbnQ4QXJyYXknXG4gICAgKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV1cbiAgICAgIHkgPSBiW2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdsYXRpbjEnOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gIH1cblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBidWYgPSBsaXN0W2ldXG4gICAgaWYgKGlzSW5zdGFuY2UoYnVmLCBVaW50OEFycmF5KSkge1xuICAgICAgYnVmID0gQnVmZmVyLmZyb20oYnVmKVxuICAgIH1cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICAgIH1cbiAgICBidWYuY29weShidWZmZXIsIHBvcylcbiAgICBwb3MgKz0gYnVmLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHN0cmluZykpIHtcbiAgICByZXR1cm4gc3RyaW5nLmxlbmd0aFxuICB9XG4gIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcoc3RyaW5nKSB8fCBpc0luc3RhbmNlKHN0cmluZywgQXJyYXlCdWZmZXIpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdUaGUgXCJzdHJpbmdcIiBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIHN0cmluZywgQnVmZmVyLCBvciBBcnJheUJ1ZmZlci4gJyArXG4gICAgICAnUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIHN0cmluZ1xuICAgIClcbiAgfVxuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBtdXN0TWF0Y2ggPSAoYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdID09PSB0cnVlKVxuICBpZiAoIW11c3RNYXRjaCAmJiBsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHtcbiAgICAgICAgICByZXR1cm4gbXVzdE1hdGNoID8gLTEgOiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICB9XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG90ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhpcyBwcm9wZXJ0eSBpcyB1c2VkIGJ5IGBCdWZmZXIuaXNCdWZmZXJgIChhbmQgdGhlIGBpcy1idWZmZXJgIG5wbSBwYWNrYWdlKVxuLy8gdG8gZGV0ZWN0IGEgQnVmZmVyIGluc3RhbmNlLiBJdCdzIG5vdCBwb3NzaWJsZSB0byB1c2UgYGluc3RhbmNlb2YgQnVmZmVyYFxuLy8gcmVsaWFibHkgaW4gYSBicm93c2VyaWZ5IGNvbnRleHQgYmVjYXVzZSB0aGVyZSBjb3VsZCBiZSBtdWx0aXBsZSBkaWZmZXJlbnRcbi8vIGNvcGllcyBvZiB0aGUgJ2J1ZmZlcicgcGFja2FnZSBpbiB1c2UuIFRoaXMgbWV0aG9kIHdvcmtzIGV2ZW4gZm9yIEJ1ZmZlclxuLy8gaW5zdGFuY2VzIHRoYXQgd2VyZSBjcmVhdGVkIGZyb20gYW5vdGhlciBjb3B5IG9mIHRoZSBgYnVmZmVyYCBwYWNrYWdlLlxuLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9pc3N1ZXMvMTU0XG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcblxuZnVuY3Rpb24gc3dhcCAoYiwgbiwgbSkge1xuICB2YXIgaSA9IGJbbl1cbiAgYltuXSA9IGJbbV1cbiAgYlttXSA9IGlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMTYgPSBmdW5jdGlvbiBzd2FwMTYgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAxKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDMyID0gZnVuY3Rpb24gc3dhcDMyICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA0ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgMilcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXA2NCA9IGZ1bmN0aW9uIHN3YXA2NCAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgOCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gOCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDcpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDYpXG4gICAgc3dhcCh0aGlzLCBpICsgMiwgaSArIDUpXG4gICAgc3dhcCh0aGlzLCBpICsgMywgaSArIDQpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW5ndGggPT09IDApIHJldHVybiAnJ1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCAwLCBsZW5ndGgpXG4gIHJldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcywgYXJndW1lbnRzKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvTG9jYWxlU3RyaW5nID0gQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZ1xuXG5CdWZmZXIucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyAoYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIGlmICh0aGlzID09PSBiKSByZXR1cm4gdHJ1ZVxuICByZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcywgYikgPT09IDBcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gIHZhciBzdHIgPSAnJ1xuICB2YXIgbWF4ID0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFU1xuICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLnJlcGxhY2UoLyguezJ9KS9nLCAnJDEgJykudHJpbSgpXG4gIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgcmV0dXJuICc8QnVmZmVyICcgKyBzdHIgKyAnPidcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAodGFyZ2V0LCBzdGFydCwgZW5kLCB0aGlzU3RhcnQsIHRoaXNFbmQpIHtcbiAgaWYgKGlzSW5zdGFuY2UodGFyZ2V0LCBVaW50OEFycmF5KSkge1xuICAgIHRhcmdldCA9IEJ1ZmZlci5mcm9tKHRhcmdldCwgdGFyZ2V0Lm9mZnNldCwgdGFyZ2V0LmJ5dGVMZW5ndGgpXG4gIH1cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAnVGhlIFwidGFyZ2V0XCIgYXJndW1lbnQgbXVzdCBiZSBvbmUgb2YgdHlwZSBCdWZmZXIgb3IgVWludDhBcnJheS4gJyArXG4gICAgICAnUmVjZWl2ZWQgdHlwZSAnICsgKHR5cGVvZiB0YXJnZXQpXG4gICAgKVxuICB9XG5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmQgPSB0YXJnZXQgPyB0YXJnZXQubGVuZ3RoIDogMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNTdGFydCA9IDBcbiAgfVxuICBpZiAodGhpc0VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc0VuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IHRhcmdldC5sZW5ndGggfHwgdGhpc1N0YXJ0IDwgMCB8fCB0aGlzRW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCAmJiBzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCkge1xuICAgIHJldHVybiAtMVxuICB9XG4gIGlmIChzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMVxuICB9XG5cbiAgc3RhcnQgPj4+PSAwXG4gIGVuZCA+Pj49IDBcbiAgdGhpc1N0YXJ0ID4+Pj0gMFxuICB0aGlzRW5kID4+Pj0gMFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQpIHJldHVybiAwXG5cbiAgdmFyIHggPSB0aGlzRW5kIC0gdGhpc1N0YXJ0XG4gIHZhciB5ID0gZW5kIC0gc3RhcnRcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG5cbiAgdmFyIHRoaXNDb3B5ID0gdGhpcy5zbGljZSh0aGlzU3RhcnQsIHRoaXNFbmQpXG4gIHZhciB0YXJnZXRDb3B5ID0gdGFyZ2V0LnNsaWNlKHN0YXJ0LCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIGlmICh0aGlzQ29weVtpXSAhPT0gdGFyZ2V0Q29weVtpXSkge1xuICAgICAgeCA9IHRoaXNDb3B5W2ldXG4gICAgICB5ID0gdGFyZ2V0Q29weVtpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbi8vIEZpbmRzIGVpdGhlciB0aGUgZmlyc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0ID49IGBieXRlT2Zmc2V0YCxcbi8vIE9SIHRoZSBsYXN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA8PSBgYnl0ZU9mZnNldGAuXG4vL1xuLy8gQXJndW1lbnRzOlxuLy8gLSBidWZmZXIgLSBhIEJ1ZmZlciB0byBzZWFyY2hcbi8vIC0gdmFsIC0gYSBzdHJpbmcsIEJ1ZmZlciwgb3IgbnVtYmVyXG4vLyAtIGJ5dGVPZmZzZXQgLSBhbiBpbmRleCBpbnRvIGBidWZmZXJgOyB3aWxsIGJlIGNsYW1wZWQgdG8gYW4gaW50MzJcbi8vIC0gZW5jb2RpbmcgLSBhbiBvcHRpb25hbCBlbmNvZGluZywgcmVsZXZhbnQgaXMgdmFsIGlzIGEgc3RyaW5nXG4vLyAtIGRpciAtIHRydWUgZm9yIGluZGV4T2YsIGZhbHNlIGZvciBsYXN0SW5kZXhPZlxuZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YgKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIC8vIEVtcHR5IGJ1ZmZlciBtZWFucyBubyBtYXRjaFxuICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkgcmV0dXJuIC0xXG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXRcbiAgaWYgKHR5cGVvZiBieXRlT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gYnl0ZU9mZnNldFxuICAgIGJ5dGVPZmZzZXQgPSAwXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIHtcbiAgICBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkge1xuICAgIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICB9XG4gIGJ5dGVPZmZzZXQgPSArYnl0ZU9mZnNldCAvLyBDb2VyY2UgdG8gTnVtYmVyLlxuICBpZiAobnVtYmVySXNOYU4oYnl0ZU9mZnNldCkpIHtcbiAgICAvLyBieXRlT2Zmc2V0OiBpdCBpdCdzIHVuZGVmaW5lZCwgbnVsbCwgTmFOLCBcImZvb1wiLCBldGMsIHNlYXJjaCB3aG9sZSBidWZmZXJcbiAgICBieXRlT2Zmc2V0ID0gZGlyID8gMCA6IChidWZmZXIubGVuZ3RoIC0gMSlcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0OiBuZWdhdGl2ZSBvZmZzZXRzIHN0YXJ0IGZyb20gdGhlIGVuZCBvZiB0aGUgYnVmZmVyXG4gIGlmIChieXRlT2Zmc2V0IDwgMCkgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggKyBieXRlT2Zmc2V0XG4gIGlmIChieXRlT2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICBpZiAoZGlyKSByZXR1cm4gLTFcbiAgICBlbHNlIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoIC0gMVxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAwKSB7XG4gICAgaWYgKGRpcikgYnl0ZU9mZnNldCA9IDBcbiAgICBlbHNlIHJldHVybiAtMVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIHZhbFxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWwgPSBCdWZmZXIuZnJvbSh2YWwsIGVuY29kaW5nKVxuICB9XG5cbiAgLy8gRmluYWxseSwgc2VhcmNoIGVpdGhlciBpbmRleE9mIChpZiBkaXIgaXMgdHJ1ZSkgb3IgbGFzdEluZGV4T2ZcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWwpKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcvYnVmZmVyIGFsd2F5cyBmYWlsc1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDB4RkYgLy8gU2VhcmNoIGZvciBhIGJ5dGUgdmFsdWUgWzAtMjU1XVxuICAgIGlmICh0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKGRpcikge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCBbIHZhbCBdLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICB2YXIgaW5kZXhTaXplID0gMVxuICB2YXIgYXJyTGVuZ3RoID0gYXJyLmxlbmd0aFxuICB2YXIgdmFsTGVuZ3RoID0gdmFsLmxlbmd0aFxuXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICBpZiAoZW5jb2RpbmcgPT09ICd1Y3MyJyB8fCBlbmNvZGluZyA9PT0gJ3Vjcy0yJyB8fFxuICAgICAgICBlbmNvZGluZyA9PT0gJ3V0ZjE2bGUnIHx8IGVuY29kaW5nID09PSAndXRmLTE2bGUnKSB7XG4gICAgICBpZiAoYXJyLmxlbmd0aCA8IDIgfHwgdmFsLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9XG4gICAgICBpbmRleFNpemUgPSAyXG4gICAgICBhcnJMZW5ndGggLz0gMlxuICAgICAgdmFsTGVuZ3RoIC89IDJcbiAgICAgIGJ5dGVPZmZzZXQgLz0gMlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWQgKGJ1ZiwgaSkge1xuICAgIGlmIChpbmRleFNpemUgPT09IDEpIHtcbiAgICAgIHJldHVybiBidWZbaV1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJ1Zi5yZWFkVUludDE2QkUoaSAqIGluZGV4U2l6ZSlcbiAgICB9XG4gIH1cblxuICB2YXIgaVxuICBpZiAoZGlyKSB7XG4gICAgdmFyIGZvdW5kSW5kZXggPSAtMVxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPCBhcnJMZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHJlYWQoYXJyLCBpKSA9PT0gcmVhZCh2YWwsIGZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4KSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbExlbmd0aCkgcmV0dXJuIGZvdW5kSW5kZXggKiBpbmRleFNpemVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ICE9PSAtMSkgaSAtPSBpIC0gZm91bmRJbmRleFxuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGJ5dGVPZmZzZXQgKyB2YWxMZW5ndGggPiBhcnJMZW5ndGgpIGJ5dGVPZmZzZXQgPSBhcnJMZW5ndGggLSB2YWxMZW5ndGhcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIGZvdW5kID0gdHJ1ZVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWxMZW5ndGg7IGorKykge1xuICAgICAgICBpZiAocmVhZChhcnIsIGkgKyBqKSAhPT0gcmVhZCh2YWwsIGopKSB7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uIGluY2x1ZGVzICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiB0aGlzLmluZGV4T2YodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykgIT09IC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIHRydWUpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUubGFzdEluZGV4T2YgPSBmdW5jdGlvbiBsYXN0SW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAobnVtYmVySXNOYU4ocGFyc2VkKSkgcmV0dXJuIGlcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGxhdGluMVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggPj4+IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdCdWZmZXIud3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0WywgbGVuZ3RoXSkgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCdcbiAgICApXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICAvLyBXYXJuaW5nOiBtYXhMZW5ndGggbm90IHRha2VuIGludG8gYWNjb3VudCBpbiBiYXNlNjRXcml0ZVxuICAgICAgICByZXR1cm4gYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHVjczJXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiB1dGY4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG4gIHZhciByZXMgPSBbXVxuXG4gIHZhciBpID0gc3RhcnRcbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgZmlyc3RCeXRlID0gYnVmW2ldXG4gICAgdmFyIGNvZGVQb2ludCA9IG51bGxcbiAgICB2YXIgYnl0ZXNQZXJTZXF1ZW5jZSA9IChmaXJzdEJ5dGUgPiAweEVGKSA/IDRcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4REYpID8gM1xuICAgICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgICAgICA6IDFcblxuICAgIGlmIChpICsgYnl0ZXNQZXJTZXF1ZW5jZSA8PSBlbmQpIHtcbiAgICAgIHZhciBzZWNvbmRCeXRlLCB0aGlyZEJ5dGUsIGZvdXJ0aEJ5dGUsIHRlbXBDb2RlUG9pbnRcblxuICAgICAgc3dpdGNoIChieXRlc1BlclNlcXVlbmNlKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZmlyc3RCeXRlIDwgMHg4MCkge1xuICAgICAgICAgICAgY29kZVBvaW50ID0gZmlyc3RCeXRlXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4MUYpIDw8IDB4NiB8IChzZWNvbmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3Rikge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweEMgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4NiB8ICh0aGlyZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGRiAmJiAodGVtcENvZGVQb2ludCA8IDB4RDgwMCB8fCB0ZW1wQ29kZVBvaW50ID4gMHhERkZGKSkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBmb3VydGhCeXRlID0gYnVmW2kgKyAzXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAoZm91cnRoQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHgxMiB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHhDIHwgKHRoaXJkQnl0ZSAmIDB4M0YpIDw8IDB4NiB8IChmb3VydGhCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHhGRkZGICYmIHRlbXBDb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb2RlUG9pbnQgPT09IG51bGwpIHtcbiAgICAgIC8vIHdlIGRpZCBub3QgZ2VuZXJhdGUgYSB2YWxpZCBjb2RlUG9pbnQgc28gaW5zZXJ0IGFcbiAgICAgIC8vIHJlcGxhY2VtZW50IGNoYXIgKFUrRkZGRCkgYW5kIGFkdmFuY2Ugb25seSAxIGJ5dGVcbiAgICAgIGNvZGVQb2ludCA9IDB4RkZGRFxuICAgICAgYnl0ZXNQZXJTZXF1ZW5jZSA9IDFcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA+IDB4RkZGRikge1xuICAgICAgLy8gZW5jb2RlIHRvIHV0ZjE2IChzdXJyb2dhdGUgcGFpciBkYW5jZSlcbiAgICAgIGNvZGVQb2ludCAtPSAweDEwMDAwXG4gICAgICByZXMucHVzaChjb2RlUG9pbnQgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApXG4gICAgICBjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRlxuICAgIH1cblxuICAgIHJlcy5wdXNoKGNvZGVQb2ludClcbiAgICBpICs9IGJ5dGVzUGVyU2VxdWVuY2VcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkocmVzKVxufVxuXG4vLyBCYXNlZCBvbiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjc0NzI3Mi82ODA3NDIsIHRoZSBicm93c2VyIHdpdGhcbi8vIHRoZSBsb3dlc3QgbGltaXQgaXMgQ2hyb21lLCB3aXRoIDB4MTAwMDAgYXJncy5cbi8vIFdlIGdvIDEgbWFnbml0dWRlIGxlc3MsIGZvciBzYWZldHlcbnZhciBNQVhfQVJHVU1FTlRTX0xFTkdUSCA9IDB4MTAwMFxuXG5mdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkgKGNvZGVQb2ludHMpIHtcbiAgdmFyIGxlbiA9IGNvZGVQb2ludHMubGVuZ3RoXG4gIGlmIChsZW4gPD0gTUFYX0FSR1VNRU5UU19MRU5HVEgpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNvZGVQb2ludHMpIC8vIGF2b2lkIGV4dHJhIHNsaWNlKClcbiAgfVxuXG4gIC8vIERlY29kZSBpbiBjaHVua3MgdG8gYXZvaWQgXCJjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIi5cbiAgdmFyIHJlcyA9ICcnXG4gIHZhciBpID0gMFxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFxuICAgICAgU3RyaW5nLFxuICAgICAgY29kZVBvaW50cy5zbGljZShpLCBpICs9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKVxuICAgIClcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldICYgMHg3RilcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGxhdGluMVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGhleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYnVmLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHZhciByZXMgPSAnJ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0gKyAoYnl0ZXNbaSArIDFdICogMjU2KSlcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmID0gdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKVxuICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZVxuICBuZXdCdWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG4gIH1cblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdXG4gIHZhciBtdWwgPSAxXG4gIHdoaWxlIChieXRlTGVuZ3RoID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgOCkgfCB0aGlzW29mZnNldCArIDFdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludEJFID0gZnVuY3Rpb24gcmVhZEludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDI0KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiByZWFkRmxvYXRMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gcmVhZERvdWJsZUJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYnVmZmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludExFID0gZnVuY3Rpb24gd3JpdGVVSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsICg4ICogYnl0ZUxlbmd0aCkgLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpIC0gMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCAoOCAqIGJ5dGVMZW5ndGgpIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSArIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuZnVuY3Rpb24gY2hlY2tJRUVFNzU0IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDQsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24gd3JpdGVGbG9hdEJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRG91YmxlIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSkgdGhyb3cgbmV3IFR5cGVFcnJvcignYXJndW1lbnQgc2hvdWxkIGJlIGEgQnVmZmVyJylcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChlbmQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0ICsgc3RhcnRcbiAgfVxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQgJiYgdHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLmNvcHlXaXRoaW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBVc2UgYnVpbHQtaW4gd2hlbiBhdmFpbGFibGUsIG1pc3NpbmcgZnJvbSBJRTExXG4gICAgdGhpcy5jb3B5V2l0aGluKHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKVxuICB9IGVsc2UgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yICh2YXIgaSA9IGxlbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbChcbiAgICAgIHRhcmdldCxcbiAgICAgIHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZCksXG4gICAgICB0YXJnZXRTdGFydFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gVXNhZ2U6XG4vLyAgICBidWZmZXIuZmlsbChudW1iZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKGJ1ZmZlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoc3RyaW5nWywgb2Zmc2V0WywgZW5kXV1bLCBlbmNvZGluZ10pXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWwsIHN0YXJ0LCBlbmQsIGVuY29kaW5nKSB7XG4gIC8vIEhhbmRsZSBzdHJpbmcgY2FzZXM6XG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh0eXBlb2Ygc3RhcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IHN0YXJ0XG4gICAgICBzdGFydCA9IDBcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZW5kID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmRcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2VuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgfVxuICAgIGlmICh2YWwubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgY29kZSA9IHZhbC5jaGFyQ29kZUF0KDApXG4gICAgICBpZiAoKGVuY29kaW5nID09PSAndXRmOCcgJiYgY29kZSA8IDEyOCkgfHxcbiAgICAgICAgICBlbmNvZGluZyA9PT0gJ2xhdGluMScpIHtcbiAgICAgICAgLy8gRmFzdCBwYXRoOiBJZiBgdmFsYCBmaXRzIGludG8gYSBzaW5nbGUgYnl0ZSwgdXNlIHRoYXQgbnVtZXJpYyB2YWx1ZS5cbiAgICAgICAgdmFsID0gY29kZVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDI1NVxuICB9XG5cbiAgLy8gSW52YWxpZCByYW5nZXMgYXJlIG5vdCBzZXQgdG8gYSBkZWZhdWx0LCBzbyBjYW4gcmFuZ2UgY2hlY2sgZWFybHkuXG4gIGlmIChzdGFydCA8IDAgfHwgdGhpcy5sZW5ndGggPCBzdGFydCB8fCB0aGlzLmxlbmd0aCA8IGVuZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBzdGFydCA9IHN0YXJ0ID4+PiAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gdGhpcy5sZW5ndGggOiBlbmQgPj4+IDBcblxuICBpZiAoIXZhbCkgdmFsID0gMFxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICAgIHRoaXNbaV0gPSB2YWxcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gQnVmZmVyLmlzQnVmZmVyKHZhbClcbiAgICAgID8gdmFsXG4gICAgICA6IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGlmIChsZW4gPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSB2YWx1ZSBcIicgKyB2YWwgK1xuICAgICAgICAnXCIgaXMgaW52YWxpZCBmb3IgYXJndW1lbnQgXCJ2YWx1ZVwiJylcbiAgICB9XG4gICAgZm9yIChpID0gMDsgaSA8IGVuZCAtIHN0YXJ0OyArK2kpIHtcbiAgICAgIHRoaXNbaSArIHN0YXJ0XSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSB0YWtlcyBlcXVhbCBzaWducyBhcyBlbmQgb2YgdGhlIEJhc2U2NCBlbmNvZGluZ1xuICBzdHIgPSBzdHIuc3BsaXQoJz0nKVswXVxuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyLnRyaW0oKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gKGxlYWRTdXJyb2dhdGUgLSAweEQ4MDAgPDwgMTAgfCBjb2RlUG9pbnQgLSAweERDMDApICsgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbi8vIEFycmF5QnVmZmVyIG9yIFVpbnQ4QXJyYXkgb2JqZWN0cyBmcm9tIG90aGVyIGNvbnRleHRzIChpLmUuIGlmcmFtZXMpIGRvIG5vdCBwYXNzXG4vLyB0aGUgYGluc3RhbmNlb2ZgIGNoZWNrIGJ1dCB0aGV5IHNob3VsZCBiZSB0cmVhdGVkIGFzIG9mIHRoYXQgdHlwZS5cbi8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvaXNzdWVzLzE2NlxuZnVuY3Rpb24gaXNJbnN0YW5jZSAob2JqLCB0eXBlKSB7XG4gIHJldHVybiBvYmogaW5zdGFuY2VvZiB0eXBlIHx8XG4gICAgKG9iaiAhPSBudWxsICYmIG9iai5jb25zdHJ1Y3RvciAhPSBudWxsICYmIG9iai5jb25zdHJ1Y3Rvci5uYW1lICE9IG51bGwgJiZcbiAgICAgIG9iai5jb25zdHJ1Y3Rvci5uYW1lID09PSB0eXBlLm5hbWUpXG59XG5mdW5jdGlvbiBudW1iZXJJc05hTiAob2JqKSB7XG4gIC8vIEZvciBJRTExIHN1cHBvcnRcbiAgcmV0dXJuIG9iaiAhPT0gb2JqIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUiA9IHR5cGVvZiBSZWZsZWN0ID09PSAnb2JqZWN0JyA/IFJlZmxlY3QgOiBudWxsXG52YXIgUmVmbGVjdEFwcGx5ID0gUiAmJiB0eXBlb2YgUi5hcHBseSA9PT0gJ2Z1bmN0aW9uJ1xuICA/IFIuYXBwbHlcbiAgOiBmdW5jdGlvbiBSZWZsZWN0QXBwbHkodGFyZ2V0LCByZWNlaXZlciwgYXJncykge1xuICAgIHJldHVybiBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbCh0YXJnZXQsIHJlY2VpdmVyLCBhcmdzKTtcbiAgfVxuXG52YXIgUmVmbGVjdE93bktleXNcbmlmIChSICYmIHR5cGVvZiBSLm93bktleXMgPT09ICdmdW5jdGlvbicpIHtcbiAgUmVmbGVjdE93bktleXMgPSBSLm93bktleXNcbn0gZWxzZSBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpXG4gICAgICAuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModGFyZ2V0KSk7XG4gIH07XG59IGVsc2Uge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBQcm9jZXNzRW1pdFdhcm5pbmcod2FybmluZykge1xuICBpZiAoY29uc29sZSAmJiBjb25zb2xlLndhcm4pIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbn1cblxudmFyIE51bWJlcklzTmFOID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIE51bWJlcklzTmFOKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPT0gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgRXZlbnRFbWl0dGVyLmluaXQuY2FsbCh0aGlzKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xubW9kdWxlLmV4cG9ydHMub25jZSA9IG9uY2U7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzQ291bnQgPSAwO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG52YXIgZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG5mdW5jdGlvbiBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBGdW5jdGlvbi4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGxpc3RlbmVyKTtcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRFbWl0dGVyLCAnZGVmYXVsdE1heExpc3RlbmVycycsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZGVmYXVsdE1heExpc3RlbmVycztcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBOdW1iZXJJc05hTihhcmcpKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIG9mIFwiZGVmYXVsdE1heExpc3RlbmVyc1wiIGlzIG91dCBvZiByYW5nZS4gSXQgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuIFJlY2VpdmVkICcgKyBhcmcgKyAnLicpO1xuICAgIH1cbiAgICBkZWZhdWx0TWF4TGlzdGVuZXJzID0gYXJnO1xuICB9XG59KTtcblxuRXZlbnRFbWl0dGVyLmluaXQgPSBmdW5jdGlvbigpIHtcblxuICBpZiAodGhpcy5fZXZlbnRzID09PSB1bmRlZmluZWQgfHxcbiAgICAgIHRoaXMuX2V2ZW50cyA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpLl9ldmVudHMpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59O1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IE51bWJlcklzTmFOKG4pKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBvZiBcIm5cIiBpcyBvdXQgb2YgcmFuZ2UuIEl0IG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyLiBSZWNlaXZlZCAnICsgbiArICcuJyk7XG4gIH1cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBfZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiBfZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBhcmdzID0gW107XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTtcbiAgdmFyIGRvRXJyb3IgPSAodHlwZSA9PT0gJ2Vycm9yJyk7XG5cbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cyAhPT0gdW5kZWZpbmVkKVxuICAgIGRvRXJyb3IgPSAoZG9FcnJvciAmJiBldmVudHMuZXJyb3IgPT09IHVuZGVmaW5lZCk7XG4gIGVsc2UgaWYgKCFkb0Vycm9yKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmIChkb0Vycm9yKSB7XG4gICAgdmFyIGVyO1xuICAgIGlmIChhcmdzLmxlbmd0aCA+IDApXG4gICAgICBlciA9IGFyZ3NbMF07XG4gICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIC8vIE5vdGU6IFRoZSBjb21tZW50cyBvbiB0aGUgYHRocm93YCBsaW5lcyBhcmUgaW50ZW50aW9uYWwsIHRoZXkgc2hvd1xuICAgICAgLy8gdXAgaW4gTm9kZSdzIG91dHB1dCBpZiB0aGlzIHJlc3VsdHMgaW4gYW4gdW5oYW5kbGVkIGV4Y2VwdGlvbi5cbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgIH1cbiAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIGVycm9yLicgKyAoZXIgPyAnICgnICsgZXIubWVzc2FnZSArICcpJyA6ICcnKSk7XG4gICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICB0aHJvdyBlcnI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gIH1cblxuICB2YXIgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoaGFuZGxlciA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBSZWZsZWN0QXBwbHkoaGFuZGxlciwgdGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIFJlZmxlY3RBcHBseShsaXN0ZW5lcnNbaV0sIHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5mdW5jdGlvbiBfYWRkTGlzdGVuZXIodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lciwgcHJlcGVuZCkge1xuICB2YXIgbTtcbiAgdmFyIGV2ZW50cztcbiAgdmFyIGV4aXN0aW5nO1xuXG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgPyBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICAgICAgLy8gUmUtYXNzaWduIGBldmVudHNgIGJlY2F1c2UgYSBuZXdMaXN0ZW5lciBoYW5kbGVyIGNvdWxkIGhhdmUgY2F1c2VkIHRoZVxuICAgICAgLy8gdGhpcy5fZXZlbnRzIHRvIGJlIGFzc2lnbmVkIHRvIGEgbmV3IG9iamVjdFxuICAgICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gICAgfVxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdO1xuICB9XG5cbiAgaWYgKGV4aXN0aW5nID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgfSBlbHNlIGlmIChwcmVwZW5kKSB7XG4gICAgICBleGlzdGluZy51bnNoaWZ0KGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBtID0gX2dldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgIGlmIChtID4gMCAmJiBleGlzdGluZy5sZW5ndGggPiBtICYmICFleGlzdGluZy53YXJuZWQpIHtcbiAgICAgIGV4aXN0aW5nLndhcm5lZCA9IHRydWU7XG4gICAgICAvLyBObyBlcnJvciBjb2RlIGZvciB0aGlzIHNpbmNlIGl0IGlzIGEgV2FybmluZ1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG4gICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcubGVuZ3RoICsgJyAnICsgU3RyaW5nKHR5cGUpICsgJyBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdpbmNyZWFzZSBsaW1pdCcpO1xuICAgICAgdy5uYW1lID0gJ01heExpc3RlbmVyc0V4Y2VlZGVkV2FybmluZyc7XG4gICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgdy5jb3VudCA9IGV4aXN0aW5nLmxlbmd0aDtcbiAgICAgIFByb2Nlc3NFbWl0V2FybmluZyh3KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmd1bWVudHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IG9uY2VXcmFwcGVyLmJpbmQoc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKGxpc3QgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdC5saXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxpc3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcG9zaXRpb24gPSAtMTtcblxuICAgICAgICBmb3IgKGkgPSBsaXN0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8IGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBvcmlnaW5hbExpc3RlbmVyID0gbGlzdFtpXS5saXN0ZW5lcjtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAwKVxuICAgICAgICAgIGxpc3Quc2hpZnQoKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgb3JpZ2luYWxMaXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhldmVudHMpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIExJRk8gb3JkZXJcbiAgICAgICAgZm9yIChpID0gbGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbmZ1bmN0aW9uIF9saXN0ZW5lcnModGFyZ2V0LCB0eXBlLCB1bndyYXApIHtcbiAgdmFyIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmIChldmxpc3RlbmVyID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/XG4gICAgdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9IGVsc2UgaWYgKGV2bGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdE93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICg7IGluZGV4ICsgMSA8IGxpc3QubGVuZ3RoOyBpbmRleCsrKVxuICAgIGxpc3RbaW5kZXhdID0gbGlzdFtpbmRleCArIDFdO1xuICBsaXN0LnBvcCgpO1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvbmNlKGVtaXR0ZXIsIG5hbWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBmdW5jdGlvbiBlcnJvckxpc3RlbmVyKGVycikge1xuICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihuYW1lLCByZXNvbHZlcik7XG4gICAgICByZWplY3QoZXJyKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXNvbHZlcigpIHtcbiAgICAgIGlmICh0eXBlb2YgZW1pdHRlci5yZW1vdmVMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIGVycm9yTGlzdGVuZXIpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZShbXS5zbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgIH07XG5cbiAgICBldmVudFRhcmdldEFnbm9zdGljQWRkTGlzdGVuZXIoZW1pdHRlciwgbmFtZSwgcmVzb2x2ZXIsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICBpZiAobmFtZSAhPT0gJ2Vycm9yJykge1xuICAgICAgYWRkRXJyb3JIYW5kbGVySWZFdmVudEVtaXR0ZXIoZW1pdHRlciwgZXJyb3JMaXN0ZW5lciwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZEVycm9ySGFuZGxlcklmRXZlbnRFbWl0dGVyKGVtaXR0ZXIsIGhhbmRsZXIsIGZsYWdzKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5vbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGV2ZW50VGFyZ2V0QWdub3N0aWNBZGRMaXN0ZW5lcihlbWl0dGVyLCAnZXJyb3InLCBoYW5kbGVyLCBmbGFncyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXZlbnRUYXJnZXRBZ25vc3RpY0FkZExpc3RlbmVyKGVtaXR0ZXIsIG5hbWUsIGxpc3RlbmVyLCBmbGFncykge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIub24gPT09ICdmdW5jdGlvbicpIHtcbiAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgZW1pdHRlci5vbmNlKG5hbWUsIGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW1pdHRlci5vbihuYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiBlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBFdmVudFRhcmdldCBkb2VzIG5vdCBoYXZlIGBlcnJvcmAgZXZlbnQgc2VtYW50aWNzIGxpa2UgTm9kZVxuICAgIC8vIEV2ZW50RW1pdHRlcnMsIHdlIGRvIG5vdCBsaXN0ZW4gZm9yIGBlcnJvcmAgZXZlbnRzIGhlcmUuXG4gICAgZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGZ1bmN0aW9uIHdyYXBMaXN0ZW5lcihhcmcpIHtcbiAgICAgIC8vIElFIGRvZXMgbm90IGhhdmUgYnVpbHRpbiBgeyBvbmNlOiB0cnVlIH1gIHN1cHBvcnQgc28gd2VcbiAgICAgIC8vIGhhdmUgdG8gZG8gaXQgbWFudWFsbHkuXG4gICAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgd3JhcExpc3RlbmVyKTtcbiAgICAgIH1cbiAgICAgIGxpc3RlbmVyKGFyZyk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiZW1pdHRlclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBFdmVudEVtaXR0ZXIuIFJlY2VpdmVkIHR5cGUgJyArIHR5cGVvZiBlbWl0dGVyKTtcbiAgfVxufVxuIiwiLyohIGllZWU3NTQuIEJTRC0zLUNsYXVzZSBMaWNlbnNlLiBGZXJvc3MgQWJvdWtoYWRpamVoIDxodHRwczovL2Zlcm9zcy5vcmcvb3BlbnNvdXJjZT4gKi9cbmV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBuQml0cyA9IC03XG4gIHZhciBpID0gaXNMRSA/IChuQnl0ZXMgLSAxKSA6IDBcbiAgdmFyIGQgPSBpc0xFID8gLTEgOiAxXG4gIHZhciBzID0gYnVmZmVyW29mZnNldCArIGldXG5cbiAgaSArPSBkXG5cbiAgZSA9IHMgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgcyA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gZUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gKGUgKiAyNTYpICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gKG0gKiAyNTYpICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApXG4gIHZhciBpID0gaXNMRSA/IDAgOiAobkJ5dGVzIC0gMSlcbiAgdmFyIGQgPSBpc0xFID8gMSA6IC0xXG4gIHZhciBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwXG5cbiAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSlcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMFxuICAgIGUgPSBlTWF4XG4gIH0gZWxzZSB7XG4gICAgZSA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpIC8gTWF0aC5MTjIpXG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tXG4gICAgICBjICo9IDJcbiAgICB9XG4gICAgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICB2YWx1ZSArPSBydCAvIGNcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpXG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrXG4gICAgICBjIC89IDJcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwXG4gICAgICBlID0gZU1heFxuICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIG0gPSAoKHZhbHVlICogYykgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vLyBjYWNoZWQgZnJvbSB3aGF0ZXZlciBnbG9iYWwgaXMgcHJlc2VudCBzbyB0aGF0IHRlc3QgcnVubmVycyB0aGF0IHN0dWIgaXRcbi8vIGRvbid0IGJyZWFrIHRoaW5ncy4gIEJ1dCB3ZSBuZWVkIHRvIHdyYXAgaXQgaW4gYSB0cnkgY2F0Y2ggaW4gY2FzZSBpdCBpc1xuLy8gd3JhcHBlZCBpbiBzdHJpY3QgbW9kZSBjb2RlIHdoaWNoIGRvZXNuJ3QgZGVmaW5lIGFueSBnbG9iYWxzLiAgSXQncyBpbnNpZGUgYVxuLy8gZnVuY3Rpb24gYmVjYXVzZSB0cnkvY2F0Y2hlcyBkZW9wdGltaXplIGluIGNlcnRhaW4gZW5naW5lcy5cblxudmFyIGNhY2hlZFNldFRpbWVvdXQ7XG52YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O1xuXG5mdW5jdGlvbiBkZWZhdWx0U2V0VGltb3V0KCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2V0VGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuZnVuY3Rpb24gZGVmYXVsdENsZWFyVGltZW91dCAoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbihmdW5jdGlvbiAoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXRUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBjbGVhclRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgfVxufSAoKSlcbmZ1bmN0aW9uIHJ1blRpbWVvdXQoZnVuKSB7XG4gICAgaWYgKGNhY2hlZFNldFRpbWVvdXQgPT09IHNldFRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIC8vIGlmIHNldFRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRTZXRUaW1lb3V0ID09PSBkZWZhdWx0U2V0VGltb3V0IHx8ICFjYWNoZWRTZXRUaW1lb3V0KSAmJiBzZXRUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfSBjYXRjaChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbChudWxsLCBmdW4sIDApO1xuICAgICAgICB9IGNhdGNoKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3JcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwodGhpcywgZnVuLCAwKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG59XG5mdW5jdGlvbiBydW5DbGVhclRpbWVvdXQobWFya2VyKSB7XG4gICAgaWYgKGNhY2hlZENsZWFyVGltZW91dCA9PT0gY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIC8vIGlmIGNsZWFyVGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZENsZWFyVGltZW91dCA9PT0gZGVmYXVsdENsZWFyVGltZW91dCB8fCAhY2FjaGVkQ2xlYXJUaW1lb3V0KSAmJiBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0ICB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsIG1hcmtlcik7XG4gICAgICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3IuXG4gICAgICAgICAgICAvLyBTb21lIHZlcnNpb25zIG9mIEkuRS4gaGF2ZSBkaWZmZXJlbnQgcnVsZXMgZm9yIGNsZWFyVGltZW91dCB2cyBzZXRUaW1lb3V0XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwodGhpcywgbWFya2VyKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG5cbn1cbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG52YXIgY3VycmVudFF1ZXVlO1xudmFyIHF1ZXVlSW5kZXggPSAtMTtcblxuZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCkge1xuICAgIGlmICghZHJhaW5pbmcgfHwgIWN1cnJlbnRRdWV1ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcXVldWUgPSBjdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgfVxuICAgIGlmIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgZHJhaW5RdWV1ZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhaW5RdWV1ZSgpIHtcbiAgICBpZiAoZHJhaW5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZW91dCA9IHJ1blRpbWVvdXQoY2xlYW5VcE5leHRUaWNrKTtcbiAgICBkcmFpbmluZyA9IHRydWU7XG5cbiAgICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIHdoaWxlKGxlbikge1xuICAgICAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRRdWV1ZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgY3VycmVudFF1ZXVlID0gbnVsbDtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIHJ1bkNsZWFyVGltZW91dCh0aW1lb3V0KTtcbn1cblxucHJvY2Vzcy5uZXh0VGljayA9IGZ1bmN0aW9uIChmdW4pIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1biwgYXJncykpO1xuICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG4gICAgICAgIHJ1blRpbWVvdXQoZHJhaW5RdWV1ZSk7XG4gICAgfVxufTtcblxuLy8gdjggbGlrZXMgcHJlZGljdGlibGUgb2JqZWN0c1xuZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG4gICAgdGhpcy5mdW4gPSBmdW47XG4gICAgdGhpcy5hcnJheSA9IGFycmF5O1xufVxuSXRlbS5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZnVuLmFwcGx5KG51bGwsIHRoaXMuYXJyYXkpO1xufTtcbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xucHJvY2Vzcy52ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5wcm9jZXNzLnZlcnNpb25zID0ge307XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZE9uY2VMaXN0ZW5lciA9IG5vb3A7XG5cbnByb2Nlc3MubGlzdGVuZXJzID0gZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuIFtdIH1cblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCIvKiEgc2FmZS1idWZmZXIuIE1JVCBMaWNlbnNlLiBGZXJvc3MgQWJvdWtoYWRpamVoIDxodHRwczovL2Zlcm9zcy5vcmcvb3BlbnNvdXJjZT4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vZGUvbm8tZGVwcmVjYXRlZC1hcGkgKi9cbnZhciBidWZmZXIgPSByZXF1aXJlKCdidWZmZXInKVxudmFyIEJ1ZmZlciA9IGJ1ZmZlci5CdWZmZXJcblxuLy8gYWx0ZXJuYXRpdmUgdG8gdXNpbmcgT2JqZWN0LmtleXMgZm9yIG9sZCBicm93c2Vyc1xuZnVuY3Rpb24gY29weVByb3BzIChzcmMsIGRzdCkge1xuICBmb3IgKHZhciBrZXkgaW4gc3JjKSB7XG4gICAgZHN0W2tleV0gPSBzcmNba2V5XVxuICB9XG59XG5pZiAoQnVmZmVyLmZyb20gJiYgQnVmZmVyLmFsbG9jICYmIEJ1ZmZlci5hbGxvY1Vuc2FmZSAmJiBCdWZmZXIuYWxsb2NVbnNhZmVTbG93KSB7XG4gIG1vZHVsZS5leHBvcnRzID0gYnVmZmVyXG59IGVsc2Uge1xuICAvLyBDb3B5IHByb3BlcnRpZXMgZnJvbSByZXF1aXJlKCdidWZmZXInKVxuICBjb3B5UHJvcHMoYnVmZmVyLCBleHBvcnRzKVxuICBleHBvcnRzLkJ1ZmZlciA9IFNhZmVCdWZmZXJcbn1cblxuZnVuY3Rpb24gU2FmZUJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuU2FmZUJ1ZmZlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJ1ZmZlci5wcm90b3R5cGUpXG5cbi8vIENvcHkgc3RhdGljIG1ldGhvZHMgZnJvbSBCdWZmZXJcbmNvcHlQcm9wcyhCdWZmZXIsIFNhZmVCdWZmZXIpXG5cblNhZmVCdWZmZXIuZnJvbSA9IGZ1bmN0aW9uIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuU2FmZUJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgdmFyIGJ1ZiA9IEJ1ZmZlcihzaXplKVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGJ1Zi5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgIH0gZWxzZSB7XG4gICAgICBidWYuZmlsbChmaWxsKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBidWYuZmlsbCgwKVxuICB9XG4gIHJldHVybiBidWZcbn1cblxuU2FmZUJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfVxuICByZXR1cm4gQnVmZmVyKHNpemUpXG59XG5cblNhZmVCdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHJldHVybiBidWZmZXIuU2xvd0J1ZmZlcihzaXplKVxufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtO1xuXG52YXIgRUUgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG5pbmhlcml0cyhTdHJlYW0sIEVFKTtcblN0cmVhbS5SZWFkYWJsZSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9yZWFkYWJsZS5qcycpO1xuU3RyZWFtLldyaXRhYmxlID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzJyk7XG5TdHJlYW0uRHVwbGV4ID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qcycpO1xuU3RyZWFtLlRyYW5zZm9ybSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanMnKTtcblN0cmVhbS5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcycpO1xuU3RyZWFtLmZpbmlzaGVkID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2VuZC1vZi1zdHJlYW0uanMnKVxuU3RyZWFtLnBpcGVsaW5lID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL3BpcGVsaW5lLmpzJylcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC40LnhcblN0cmVhbS5TdHJlYW0gPSBTdHJlYW07XG5cblxuXG4vLyBvbGQtc3R5bGUgc3RyZWFtcy4gIE5vdGUgdGhhdCB0aGUgcGlwZSBtZXRob2QgKHRoZSBvbmx5IHJlbGV2YW50XG4vLyBwYXJ0IG9mIHRoaXMgY2xhc3MpIGlzIG92ZXJyaWRkZW4gaW4gdGhlIFJlYWRhYmxlIGNsYXNzLlxuXG5mdW5jdGlvbiBTdHJlYW0oKSB7XG4gIEVFLmNhbGwodGhpcyk7XG59XG5cblN0cmVhbS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uKGRlc3QsIG9wdGlvbnMpIHtcbiAgdmFyIHNvdXJjZSA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgaWYgKGRlc3Qud3JpdGFibGUpIHtcbiAgICAgIGlmIChmYWxzZSA9PT0gZGVzdC53cml0ZShjaHVuaykgJiYgc291cmNlLnBhdXNlKSB7XG4gICAgICAgIHNvdXJjZS5wYXVzZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZGF0YScsIG9uZGF0YSk7XG5cbiAgZnVuY3Rpb24gb25kcmFpbigpIHtcbiAgICBpZiAoc291cmNlLnJlYWRhYmxlICYmIHNvdXJjZS5yZXN1bWUpIHtcbiAgICAgIHNvdXJjZS5yZXN1bWUoKTtcbiAgICB9XG4gIH1cblxuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIC8vIElmIHRoZSAnZW5kJyBvcHRpb24gaXMgbm90IHN1cHBsaWVkLCBkZXN0LmVuZCgpIHdpbGwgYmUgY2FsbGVkIHdoZW5cbiAgLy8gc291cmNlIGdldHMgdGhlICdlbmQnIG9yICdjbG9zZScgZXZlbnRzLiAgT25seSBkZXN0LmVuZCgpIG9uY2UuXG4gIGlmICghZGVzdC5faXNTdGRpbyAmJiAoIW9wdGlvbnMgfHwgb3B0aW9ucy5lbmQgIT09IGZhbHNlKSkge1xuICAgIHNvdXJjZS5vbignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5vbignY2xvc2UnLCBvbmNsb3NlKTtcbiAgfVxuXG4gIHZhciBkaWRPbkVuZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBpZiAoZGlkT25FbmQpIHJldHVybjtcbiAgICBkaWRPbkVuZCA9IHRydWU7XG5cbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cblxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGlmICh0eXBlb2YgZGVzdC5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSBkZXN0LmRlc3Ryb3koKTtcbiAgfVxuXG4gIC8vIGRvbid0IGxlYXZlIGRhbmdsaW5nIHBpcGVzIHdoZW4gdGhlcmUgYXJlIGVycm9ycy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGNsZWFudXAoKTtcbiAgICBpZiAoRUUubGlzdGVuZXJDb3VudCh0aGlzLCAnZXJyb3InKSA9PT0gMCkge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCBzdHJlYW0gZXJyb3IgaW4gcGlwZS5cbiAgICB9XG4gIH1cblxuICBzb3VyY2Uub24oJ2Vycm9yJywgb25lcnJvcik7XG4gIGRlc3Qub24oJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gcmVtb3ZlIGFsbCB0aGUgZXZlbnQgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZC5cbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBvbmRhdGEpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBjbGVhbnVwKTtcbiAgfVxuXG4gIHNvdXJjZS5vbignZW5kJywgY2xlYW51cCk7XG4gIHNvdXJjZS5vbignY2xvc2UnLCBjbGVhbnVwKTtcblxuICBkZXN0Lm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3QuZW1pdCgncGlwZScsIHNvdXJjZSk7XG5cbiAgLy8gQWxsb3cgZm9yIHVuaXgtbGlrZSB1c2FnZTogQS5waXBlKEIpLnBpcGUoQylcbiAgcmV0dXJuIGRlc3Q7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBfaW5oZXJpdHNMb29zZShzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MucHJvdG90eXBlKTsgc3ViQ2xhc3MucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gc3ViQ2xhc3M7IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIGNvZGVzID0ge307XG5cbmZ1bmN0aW9uIGNyZWF0ZUVycm9yVHlwZShjb2RlLCBtZXNzYWdlLCBCYXNlKSB7XG4gIGlmICghQmFzZSkge1xuICAgIEJhc2UgPSBFcnJvcjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE1lc3NhZ2UoYXJnMSwgYXJnMiwgYXJnMykge1xuICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbWVzc2FnZShhcmcxLCBhcmcyLCBhcmczKTtcbiAgICB9XG4gIH1cblxuICB2YXIgTm9kZUVycm9yID1cbiAgLyojX19QVVJFX18qL1xuICBmdW5jdGlvbiAoX0Jhc2UpIHtcbiAgICBfaW5oZXJpdHNMb29zZShOb2RlRXJyb3IsIF9CYXNlKTtcblxuICAgIGZ1bmN0aW9uIE5vZGVFcnJvcihhcmcxLCBhcmcyLCBhcmczKSB7XG4gICAgICByZXR1cm4gX0Jhc2UuY2FsbCh0aGlzLCBnZXRNZXNzYWdlKGFyZzEsIGFyZzIsIGFyZzMpKSB8fCB0aGlzO1xuICAgIH1cblxuICAgIHJldHVybiBOb2RlRXJyb3I7XG4gIH0oQmFzZSk7XG5cbiAgTm9kZUVycm9yLnByb3RvdHlwZS5uYW1lID0gQmFzZS5uYW1lO1xuICBOb2RlRXJyb3IucHJvdG90eXBlLmNvZGUgPSBjb2RlO1xuICBjb2Rlc1tjb2RlXSA9IE5vZGVFcnJvcjtcbn0gLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2Jsb2IvdjEwLjguMC9saWIvaW50ZXJuYWwvZXJyb3JzLmpzXG5cblxuZnVuY3Rpb24gb25lT2YoZXhwZWN0ZWQsIHRoaW5nKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGV4cGVjdGVkKSkge1xuICAgIHZhciBsZW4gPSBleHBlY3RlZC5sZW5ndGg7XG4gICAgZXhwZWN0ZWQgPSBleHBlY3RlZC5tYXAoZnVuY3Rpb24gKGkpIHtcbiAgICAgIHJldHVybiBTdHJpbmcoaSk7XG4gICAgfSk7XG5cbiAgICBpZiAobGVuID4gMikge1xuICAgICAgcmV0dXJuIFwib25lIG9mIFwiLmNvbmNhdCh0aGluZywgXCIgXCIpLmNvbmNhdChleHBlY3RlZC5zbGljZSgwLCBsZW4gLSAxKS5qb2luKCcsICcpLCBcIiwgb3IgXCIpICsgZXhwZWN0ZWRbbGVuIC0gMV07XG4gICAgfSBlbHNlIGlmIChsZW4gPT09IDIpIHtcbiAgICAgIHJldHVybiBcIm9uZSBvZiBcIi5jb25jYXQodGhpbmcsIFwiIFwiKS5jb25jYXQoZXhwZWN0ZWRbMF0sIFwiIG9yIFwiKS5jb25jYXQoZXhwZWN0ZWRbMV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gXCJvZiBcIi5jb25jYXQodGhpbmcsIFwiIFwiKS5jb25jYXQoZXhwZWN0ZWRbMF0pO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gXCJvZiBcIi5jb25jYXQodGhpbmcsIFwiIFwiKS5jb25jYXQoU3RyaW5nKGV4cGVjdGVkKSk7XG4gIH1cbn0gLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvU3RyaW5nL3N0YXJ0c1dpdGhcblxuXG5mdW5jdGlvbiBzdGFydHNXaXRoKHN0ciwgc2VhcmNoLCBwb3MpIHtcbiAgcmV0dXJuIHN0ci5zdWJzdHIoIXBvcyB8fCBwb3MgPCAwID8gMCA6ICtwb3MsIHNlYXJjaC5sZW5ndGgpID09PSBzZWFyY2g7XG59IC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL1N0cmluZy9lbmRzV2l0aFxuXG5cbmZ1bmN0aW9uIGVuZHNXaXRoKHN0ciwgc2VhcmNoLCB0aGlzX2xlbikge1xuICBpZiAodGhpc19sZW4gPT09IHVuZGVmaW5lZCB8fCB0aGlzX2xlbiA+IHN0ci5sZW5ndGgpIHtcbiAgICB0aGlzX2xlbiA9IHN0ci5sZW5ndGg7XG4gIH1cblxuICByZXR1cm4gc3RyLnN1YnN0cmluZyh0aGlzX2xlbiAtIHNlYXJjaC5sZW5ndGgsIHRoaXNfbGVuKSA9PT0gc2VhcmNoO1xufSAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9TdHJpbmcvaW5jbHVkZXNcblxuXG5mdW5jdGlvbiBpbmNsdWRlcyhzdHIsIHNlYXJjaCwgc3RhcnQpIHtcbiAgaWYgKHR5cGVvZiBzdGFydCAhPT0gJ251bWJlcicpIHtcbiAgICBzdGFydCA9IDA7XG4gIH1cblxuICBpZiAoc3RhcnQgKyBzZWFyY2gubGVuZ3RoID4gc3RyLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyLmluZGV4T2Yoc2VhcmNoLCBzdGFydCkgIT09IC0xO1xuICB9XG59XG5cbmNyZWF0ZUVycm9yVHlwZSgnRVJSX0lOVkFMSURfT1BUX1ZBTFVFJywgZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiAnVGhlIHZhbHVlIFwiJyArIHZhbHVlICsgJ1wiIGlzIGludmFsaWQgZm9yIG9wdGlvbiBcIicgKyBuYW1lICsgJ1wiJztcbn0sIFR5cGVFcnJvcik7XG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9JTlZBTElEX0FSR19UWVBFJywgZnVuY3Rpb24gKG5hbWUsIGV4cGVjdGVkLCBhY3R1YWwpIHtcbiAgLy8gZGV0ZXJtaW5lcjogJ211c3QgYmUnIG9yICdtdXN0IG5vdCBiZSdcbiAgdmFyIGRldGVybWluZXI7XG5cbiAgaWYgKHR5cGVvZiBleHBlY3RlZCA9PT0gJ3N0cmluZycgJiYgc3RhcnRzV2l0aChleHBlY3RlZCwgJ25vdCAnKSkge1xuICAgIGRldGVybWluZXIgPSAnbXVzdCBub3QgYmUnO1xuICAgIGV4cGVjdGVkID0gZXhwZWN0ZWQucmVwbGFjZSgvXm5vdCAvLCAnJyk7XG4gIH0gZWxzZSB7XG4gICAgZGV0ZXJtaW5lciA9ICdtdXN0IGJlJztcbiAgfVxuXG4gIHZhciBtc2c7XG5cbiAgaWYgKGVuZHNXaXRoKG5hbWUsICcgYXJndW1lbnQnKSkge1xuICAgIC8vIEZvciBjYXNlcyBsaWtlICdmaXJzdCBhcmd1bWVudCdcbiAgICBtc2cgPSBcIlRoZSBcIi5jb25jYXQobmFtZSwgXCIgXCIpLmNvbmNhdChkZXRlcm1pbmVyLCBcIiBcIikuY29uY2F0KG9uZU9mKGV4cGVjdGVkLCAndHlwZScpKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgdHlwZSA9IGluY2x1ZGVzKG5hbWUsICcuJykgPyAncHJvcGVydHknIDogJ2FyZ3VtZW50JztcbiAgICBtc2cgPSBcIlRoZSBcXFwiXCIuY29uY2F0KG5hbWUsIFwiXFxcIiBcIikuY29uY2F0KHR5cGUsIFwiIFwiKS5jb25jYXQoZGV0ZXJtaW5lciwgXCIgXCIpLmNvbmNhdChvbmVPZihleHBlY3RlZCwgJ3R5cGUnKSk7XG4gIH1cblxuICBtc2cgKz0gXCIuIFJlY2VpdmVkIHR5cGUgXCIuY29uY2F0KHR5cGVvZiBhY3R1YWwpO1xuICByZXR1cm4gbXNnO1xufSwgVHlwZUVycm9yKTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX1NUUkVBTV9QVVNIX0FGVEVSX0VPRicsICdzdHJlYW0ucHVzaCgpIGFmdGVyIEVPRicpO1xuY3JlYXRlRXJyb3JUeXBlKCdFUlJfTUVUSE9EX05PVF9JTVBMRU1FTlRFRCcsIGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiAnVGhlICcgKyBuYW1lICsgJyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkJztcbn0pO1xuY3JlYXRlRXJyb3JUeXBlKCdFUlJfU1RSRUFNX1BSRU1BVFVSRV9DTE9TRScsICdQcmVtYXR1cmUgY2xvc2UnKTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX1NUUkVBTV9ERVNUUk9ZRUQnLCBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gJ0Nhbm5vdCBjYWxsICcgKyBuYW1lICsgJyBhZnRlciBhIHN0cmVhbSB3YXMgZGVzdHJveWVkJztcbn0pO1xuY3JlYXRlRXJyb3JUeXBlKCdFUlJfTVVMVElQTEVfQ0FMTEJBQ0snLCAnQ2FsbGJhY2sgY2FsbGVkIG11bHRpcGxlIHRpbWVzJyk7XG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9TVFJFQU1fQ0FOTk9UX1BJUEUnLCAnQ2Fubm90IHBpcGUsIG5vdCByZWFkYWJsZScpO1xuY3JlYXRlRXJyb3JUeXBlKCdFUlJfU1RSRUFNX1dSSVRFX0FGVEVSX0VORCcsICd3cml0ZSBhZnRlciBlbmQnKTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX1NUUkVBTV9OVUxMX1ZBTFVFUycsICdNYXkgbm90IHdyaXRlIG51bGwgdmFsdWVzIHRvIHN0cmVhbScsIFR5cGVFcnJvcik7XG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9VTktOT1dOX0VOQ09ESU5HJywgZnVuY3Rpb24gKGFyZykge1xuICByZXR1cm4gJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBhcmc7XG59LCBUeXBlRXJyb3IpO1xuY3JlYXRlRXJyb3JUeXBlKCdFUlJfU1RSRUFNX1VOU0hJRlRfQUZURVJfRU5EX0VWRU5UJywgJ3N0cmVhbS51bnNoaWZ0KCkgYWZ0ZXIgZW5kIGV2ZW50Jyk7XG5tb2R1bGUuZXhwb3J0cy5jb2RlcyA9IGNvZGVzO1xuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG4vLyBhIGR1cGxleCBzdHJlYW0gaXMganVzdCBhIHN0cmVhbSB0aGF0IGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLlxuLy8gU2luY2UgSlMgZG9lc24ndCBoYXZlIG11bHRpcGxlIHByb3RvdHlwYWwgaW5oZXJpdGFuY2UsIHRoaXMgY2xhc3Ncbi8vIHByb3RvdHlwYWxseSBpbmhlcml0cyBmcm9tIFJlYWRhYmxlLCBhbmQgdGhlbiBwYXJhc2l0aWNhbGx5IGZyb21cbi8vIFdyaXRhYmxlLlxuJ3VzZSBzdHJpY3QnO1xuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG5cbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGtleXMucHVzaChrZXkpO1xuICB9XG5cbiAgcmV0dXJuIGtleXM7XG59O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblxubW9kdWxlLmV4cG9ydHMgPSBEdXBsZXg7XG5cbnZhciBSZWFkYWJsZSA9IHJlcXVpcmUoJy4vX3N0cmVhbV9yZWFkYWJsZScpO1xuXG52YXIgV3JpdGFibGUgPSByZXF1aXJlKCcuL19zdHJlYW1fd3JpdGFibGUnKTtcblxucmVxdWlyZSgnaW5oZXJpdHMnKShEdXBsZXgsIFJlYWRhYmxlKTtcblxue1xuICAvLyBBbGxvdyB0aGUga2V5cyBhcnJheSB0byBiZSBHQydlZC5cbiAgdmFyIGtleXMgPSBvYmplY3RLZXlzKFdyaXRhYmxlLnByb3RvdHlwZSk7XG5cbiAgZm9yICh2YXIgdiA9IDA7IHYgPCBrZXlzLmxlbmd0aDsgdisrKSB7XG4gICAgdmFyIG1ldGhvZCA9IGtleXNbdl07XG4gICAgaWYgKCFEdXBsZXgucHJvdG90eXBlW21ldGhvZF0pIER1cGxleC5wcm90b3R5cGVbbWV0aG9kXSA9IFdyaXRhYmxlLnByb3RvdHlwZVttZXRob2RdO1xuICB9XG59XG5cbmZ1bmN0aW9uIER1cGxleChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKSByZXR1cm4gbmV3IER1cGxleChvcHRpb25zKTtcbiAgUmVhZGFibGUuY2FsbCh0aGlzLCBvcHRpb25zKTtcbiAgV3JpdGFibGUuY2FsbCh0aGlzLCBvcHRpb25zKTtcbiAgdGhpcy5hbGxvd0hhbGZPcGVuID0gdHJ1ZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmIChvcHRpb25zLnJlYWRhYmxlID09PSBmYWxzZSkgdGhpcy5yZWFkYWJsZSA9IGZhbHNlO1xuICAgIGlmIChvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSkgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuXG4gICAgaWYgKG9wdGlvbnMuYWxsb3dIYWxmT3BlbiA9PT0gZmFsc2UpIHtcbiAgICAgIHRoaXMuYWxsb3dIYWxmT3BlbiA9IGZhbHNlO1xuICAgICAgdGhpcy5vbmNlKCdlbmQnLCBvbmVuZCk7XG4gICAgfVxuICB9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShEdXBsZXgucHJvdG90eXBlLCAnd3JpdGFibGVIaWdoV2F0ZXJNYXJrJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fd3JpdGFibGVTdGF0ZS5oaWdoV2F0ZXJNYXJrO1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShEdXBsZXgucHJvdG90eXBlLCAnd3JpdGFibGVCdWZmZXInLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl93cml0YWJsZVN0YXRlICYmIHRoaXMuX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyKCk7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KER1cGxleC5wcm90b3R5cGUsICd3cml0YWJsZUxlbmd0aCcsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUubGVuZ3RoO1xuICB9XG59KTsgLy8gdGhlIG5vLWhhbGYtb3BlbiBlbmZvcmNlclxuXG5mdW5jdGlvbiBvbmVuZCgpIHtcbiAgLy8gSWYgdGhlIHdyaXRhYmxlIHNpZGUgZW5kZWQsIHRoZW4gd2UncmUgb2suXG4gIGlmICh0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKSByZXR1cm47IC8vIG5vIG1vcmUgZGF0YSBjYW4gYmUgd3JpdHRlbi5cbiAgLy8gQnV0IGFsbG93IG1vcmUgd3JpdGVzIHRvIGhhcHBlbiBpbiB0aGlzIHRpY2suXG5cbiAgcHJvY2Vzcy5uZXh0VGljayhvbkVuZE5ULCB0aGlzKTtcbn1cblxuZnVuY3Rpb24gb25FbmROVChzZWxmKSB7XG4gIHNlbGYuZW5kKCk7XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShEdXBsZXgucHJvdG90eXBlLCAnZGVzdHJveWVkJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZSA9PT0gdW5kZWZpbmVkIHx8IHRoaXMuX3dyaXRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCAmJiB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiBzZXQodmFsdWUpIHtcbiAgICAvLyB3ZSBpZ25vcmUgdGhlIHZhbHVlIGlmIHRoZSBzdHJlYW1cbiAgICAvLyBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCB8fCB0aGlzLl93cml0YWJsZVN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHRoZSB1c2VyIGlzIGV4cGxpY2l0bHlcbiAgICAvLyBtYW5hZ2luZyBkZXN0cm95ZWRcblxuXG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB2YWx1ZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICB9XG59KTsiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cbi8vIGEgcGFzc3Rocm91Z2ggc3RyZWFtLlxuLy8gYmFzaWNhbGx5IGp1c3QgdGhlIG1vc3QgbWluaW1hbCBzb3J0IG9mIFRyYW5zZm9ybSBzdHJlYW0uXG4vLyBFdmVyeSB3cml0dGVuIGNodW5rIGdldHMgb3V0cHV0IGFzLWlzLlxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBhc3NUaHJvdWdoO1xuXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnLi9fc3RyZWFtX3RyYW5zZm9ybScpO1xuXG5yZXF1aXJlKCdpbmhlcml0cycpKFBhc3NUaHJvdWdoLCBUcmFuc2Zvcm0pO1xuXG5mdW5jdGlvbiBQYXNzVGhyb3VnaChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBQYXNzVGhyb3VnaCkpIHJldHVybiBuZXcgUGFzc1Rocm91Z2gob3B0aW9ucyk7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5QYXNzVGhyb3VnaC5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG51bGwsIGNodW5rKTtcbn07IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhZGFibGU7XG4vKjxyZXBsYWNlbWVudD4qL1xuXG52YXIgRHVwbGV4O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblJlYWRhYmxlLlJlYWRhYmxlU3RhdGUgPSBSZWFkYWJsZVN0YXRlO1xuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgRUVsaXN0ZW5lckNvdW50ID0gZnVuY3Rpb24gRUVsaXN0ZW5lckNvdW50KGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJzKHR5cGUpLmxlbmd0aDtcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxuXG52YXIgU3RyZWFtID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL3N0cmVhbScpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxudmFyIE91clVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheSB8fCBmdW5jdGlvbiAoKSB7fTtcblxuZnVuY3Rpb24gX3VpbnQ4QXJyYXlUb0J1ZmZlcihjaHVuaykge1xuICByZXR1cm4gQnVmZmVyLmZyb20oY2h1bmspO1xufVxuXG5mdW5jdGlvbiBfaXNVaW50OEFycmF5KG9iaikge1xuICByZXR1cm4gQnVmZmVyLmlzQnVmZmVyKG9iaikgfHwgb2JqIGluc3RhbmNlb2YgT3VyVWludDhBcnJheTtcbn1cbi8qPHJlcGxhY2VtZW50PiovXG5cblxudmFyIGRlYnVnVXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcblxudmFyIGRlYnVnO1xuXG5pZiAoZGVidWdVdGlsICYmIGRlYnVnVXRpbC5kZWJ1Z2xvZykge1xuICBkZWJ1ZyA9IGRlYnVnVXRpbC5kZWJ1Z2xvZygnc3RyZWFtJyk7XG59IGVsc2Uge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uIGRlYnVnKCkge307XG59XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuXG52YXIgQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9idWZmZXJfbGlzdCcpO1xuXG52YXIgZGVzdHJveUltcGwgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvZGVzdHJveScpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvc3RhdGUnKSxcbiAgICBnZXRIaWdoV2F0ZXJNYXJrID0gX3JlcXVpcmUuZ2V0SGlnaFdhdGVyTWFyaztcblxudmFyIF9yZXF1aXJlJGNvZGVzID0gcmVxdWlyZSgnLi4vZXJyb3JzJykuY29kZXMsXG4gICAgRVJSX0lOVkFMSURfQVJHX1RZUEUgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfSU5WQUxJRF9BUkdfVFlQRSxcbiAgICBFUlJfU1RSRUFNX1BVU0hfQUZURVJfRU9GID0gX3JlcXVpcmUkY29kZXMuRVJSX1NUUkVBTV9QVVNIX0FGVEVSX0VPRixcbiAgICBFUlJfTUVUSE9EX05PVF9JTVBMRU1FTlRFRCA9IF9yZXF1aXJlJGNvZGVzLkVSUl9NRVRIT0RfTk9UX0lNUExFTUVOVEVELFxuICAgIEVSUl9TVFJFQU1fVU5TSElGVF9BRlRFUl9FTkRfRVZFTlQgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfU1RSRUFNX1VOU0hJRlRfQUZURVJfRU5EX0VWRU5UOyAvLyBMYXp5IGxvYWRlZCB0byBpbXByb3ZlIHRoZSBzdGFydHVwIHBlcmZvcm1hbmNlLlxuXG5cbnZhciBTdHJpbmdEZWNvZGVyO1xudmFyIGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcjtcbnZhciBmcm9tO1xuXG5yZXF1aXJlKCdpbmhlcml0cycpKFJlYWRhYmxlLCBTdHJlYW0pO1xuXG52YXIgZXJyb3JPckRlc3Ryb3kgPSBkZXN0cm95SW1wbC5lcnJvck9yRGVzdHJveTtcbnZhciBrUHJveHlFdmVudHMgPSBbJ2Vycm9yJywgJ2Nsb3NlJywgJ2Rlc3Ryb3knLCAncGF1c2UnLCAncmVzdW1lJ107XG5cbmZ1bmN0aW9uIHByZXBlbmRMaXN0ZW5lcihlbWl0dGVyLCBldmVudCwgZm4pIHtcbiAgLy8gU2FkbHkgdGhpcyBpcyBub3QgY2FjaGVhYmxlIGFzIHNvbWUgbGlicmFyaWVzIGJ1bmRsZSB0aGVpciBvd25cbiAgLy8gZXZlbnQgZW1pdHRlciBpbXBsZW1lbnRhdGlvbiB3aXRoIHRoZW0uXG4gIGlmICh0eXBlb2YgZW1pdHRlci5wcmVwZW5kTGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHJldHVybiBlbWl0dGVyLnByZXBlbmRMaXN0ZW5lcihldmVudCwgZm4pOyAvLyBUaGlzIGlzIGEgaGFjayB0byBtYWtlIHN1cmUgdGhhdCBvdXIgZXJyb3IgaGFuZGxlciBpcyBhdHRhY2hlZCBiZWZvcmUgYW55XG4gIC8vIHVzZXJsYW5kIG9uZXMuICBORVZFUiBETyBUSElTLiBUaGlzIGlzIGhlcmUgb25seSBiZWNhdXNlIHRoaXMgY29kZSBuZWVkc1xuICAvLyB0byBjb250aW51ZSB0byB3b3JrIHdpdGggb2xkZXIgdmVyc2lvbnMgb2YgTm9kZS5qcyB0aGF0IGRvIG5vdCBpbmNsdWRlXG4gIC8vIHRoZSBwcmVwZW5kTGlzdGVuZXIoKSBtZXRob2QuIFRoZSBnb2FsIGlzIHRvIGV2ZW50dWFsbHkgcmVtb3ZlIHRoaXMgaGFjay5cblxuICBpZiAoIWVtaXR0ZXIuX2V2ZW50cyB8fCAhZW1pdHRlci5fZXZlbnRzW2V2ZW50XSkgZW1pdHRlci5vbihldmVudCwgZm4pO2Vsc2UgaWYgKEFycmF5LmlzQXJyYXkoZW1pdHRlci5fZXZlbnRzW2V2ZW50XSkpIGVtaXR0ZXIuX2V2ZW50c1tldmVudF0udW5zaGlmdChmbik7ZWxzZSBlbWl0dGVyLl9ldmVudHNbZXZlbnRdID0gW2ZuLCBlbWl0dGVyLl9ldmVudHNbZXZlbnRdXTtcbn1cblxuZnVuY3Rpb24gUmVhZGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0sIGlzRHVwbGV4KSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OyAvLyBEdXBsZXggc3RyZWFtcyBhcmUgYm90aCByZWFkYWJsZSBhbmQgd3JpdGFibGUsIGJ1dCBzaGFyZVxuICAvLyB0aGUgc2FtZSBvcHRpb25zIG9iamVjdC5cbiAgLy8gSG93ZXZlciwgc29tZSBjYXNlcyByZXF1aXJlIHNldHRpbmcgb3B0aW9ucyB0byBkaWZmZXJlbnRcbiAgLy8gdmFsdWVzIGZvciB0aGUgcmVhZGFibGUgYW5kIHRoZSB3cml0YWJsZSBzaWRlcyBvZiB0aGUgZHVwbGV4IHN0cmVhbS5cbiAgLy8gVGhlc2Ugb3B0aW9ucyBjYW4gYmUgcHJvdmlkZWQgc2VwYXJhdGVseSBhcyByZWFkYWJsZVhYWCBhbmQgd3JpdGFibGVYWFguXG5cbiAgaWYgKHR5cGVvZiBpc0R1cGxleCAhPT0gJ2Jvb2xlYW4nKSBpc0R1cGxleCA9IHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleDsgLy8gb2JqZWN0IHN0cmVhbSBmbGFnLiBVc2VkIHRvIG1ha2UgcmVhZChuKSBpZ25vcmUgbiBhbmQgdG9cbiAgLy8gbWFrZSBhbGwgdGhlIGJ1ZmZlciBtZXJnaW5nIGFuZCBsZW5ndGggY2hlY2tzIGdvIGF3YXlcblxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcbiAgaWYgKGlzRHVwbGV4KSB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLnJlYWRhYmxlT2JqZWN0TW9kZTsgLy8gdGhlIHBvaW50IGF0IHdoaWNoIGl0IHN0b3BzIGNhbGxpbmcgX3JlYWQoKSB0byBmaWxsIHRoZSBidWZmZXJcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyBcImRvbid0IGNhbGwgX3JlYWQgcHJlZW1wdGl2ZWx5IGV2ZXJcIlxuXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IGdldEhpZ2hXYXRlck1hcmsodGhpcywgb3B0aW9ucywgJ3JlYWRhYmxlSGlnaFdhdGVyTWFyaycsIGlzRHVwbGV4KTsgLy8gQSBsaW5rZWQgbGlzdCBpcyB1c2VkIHRvIHN0b3JlIGRhdGEgY2h1bmtzIGluc3RlYWQgb2YgYW4gYXJyYXkgYmVjYXVzZSB0aGVcbiAgLy8gbGlua2VkIGxpc3QgY2FuIHJlbW92ZSBlbGVtZW50cyBmcm9tIHRoZSBiZWdpbm5pbmcgZmFzdGVyIHRoYW5cbiAgLy8gYXJyYXkuc2hpZnQoKVxuXG4gIHRoaXMuYnVmZmVyID0gbmV3IEJ1ZmZlckxpc3QoKTtcbiAgdGhpcy5sZW5ndGggPSAwO1xuICB0aGlzLnBpcGVzID0gbnVsbDtcbiAgdGhpcy5waXBlc0NvdW50ID0gMDtcbiAgdGhpcy5mbG93aW5nID0gbnVsbDtcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICB0aGlzLmVuZEVtaXR0ZWQgPSBmYWxzZTtcbiAgdGhpcy5yZWFkaW5nID0gZmFsc2U7IC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIGV2ZW50ICdyZWFkYWJsZScvJ2RhdGEnIGlzIGVtaXR0ZWRcbiAgLy8gaW1tZWRpYXRlbHksIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY2F1c2VcbiAgLy8gYW55IGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHJlYWQgY2FsbC5cblxuICB0aGlzLnN5bmMgPSB0cnVlOyAvLyB3aGVuZXZlciB3ZSByZXR1cm4gbnVsbCwgdGhlbiB3ZSBzZXQgYSBmbGFnIHRvIHNheVxuICAvLyB0aGF0IHdlJ3JlIGF3YWl0aW5nIGEgJ3JlYWRhYmxlJyBldmVudCBlbWlzc2lvbi5cblxuICB0aGlzLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLnJlYWRhYmxlTGlzdGVuaW5nID0gZmFsc2U7XG4gIHRoaXMucmVzdW1lU2NoZWR1bGVkID0gZmFsc2U7XG4gIHRoaXMucGF1c2VkID0gdHJ1ZTsgLy8gU2hvdWxkIGNsb3NlIGJlIGVtaXR0ZWQgb24gZGVzdHJveS4gRGVmYXVsdHMgdG8gdHJ1ZS5cblxuICB0aGlzLmVtaXRDbG9zZSA9IG9wdGlvbnMuZW1pdENsb3NlICE9PSBmYWxzZTsgLy8gU2hvdWxkIC5kZXN0cm95KCkgYmUgY2FsbGVkIGFmdGVyICdlbmQnIChhbmQgcG90ZW50aWFsbHkgJ2ZpbmlzaCcpXG5cbiAgdGhpcy5hdXRvRGVzdHJveSA9ICEhb3B0aW9ucy5hdXRvRGVzdHJveTsgLy8gaGFzIGl0IGJlZW4gZGVzdHJveWVkXG5cbiAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTsgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cblxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JzsgLy8gdGhlIG51bWJlciBvZiB3cml0ZXJzIHRoYXQgYXJlIGF3YWl0aW5nIGEgZHJhaW4gZXZlbnQgaW4gLnBpcGUoKXNcblxuICB0aGlzLmF3YWl0RHJhaW4gPSAwOyAvLyBpZiB0cnVlLCBhIG1heWJlUmVhZE1vcmUgaGFzIGJlZW4gc2NoZWR1bGVkXG5cbiAgdGhpcy5yZWFkaW5nTW9yZSA9IGZhbHNlO1xuICB0aGlzLmRlY29kZXIgPSBudWxsO1xuICB0aGlzLmVuY29kaW5nID0gbnVsbDtcblxuICBpZiAob3B0aW9ucy5lbmNvZGluZykge1xuICAgIGlmICghU3RyaW5nRGVjb2RlcikgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyLycpLlN0cmluZ0RlY29kZXI7XG4gICAgdGhpcy5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIob3B0aW9ucy5lbmNvZGluZyk7XG4gICAgdGhpcy5lbmNvZGluZyA9IG9wdGlvbnMuZW5jb2Rpbmc7XG4gIH1cbn1cblxuZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVhZGFibGUpKSByZXR1cm4gbmV3IFJlYWRhYmxlKG9wdGlvbnMpOyAvLyBDaGVja2luZyBmb3IgYSBTdHJlYW0uRHVwbGV4IGluc3RhbmNlIGlzIGZhc3RlciBoZXJlIGluc3RlYWQgb2YgaW5zaWRlXG4gIC8vIHRoZSBSZWFkYWJsZVN0YXRlIGNvbnN0cnVjdG9yLCBhdCBsZWFzdCB3aXRoIFY4IDYuNVxuXG4gIHZhciBpc0R1cGxleCA9IHRoaXMgaW5zdGFuY2VvZiBEdXBsZXg7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUgPSBuZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLCB0aGlzLCBpc0R1cGxleCk7IC8vIGxlZ2FjeVxuXG4gIHRoaXMucmVhZGFibGUgPSB0cnVlO1xuXG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnJlYWQgPT09ICdmdW5jdGlvbicpIHRoaXMuX3JlYWQgPSBvcHRpb25zLnJlYWQ7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIHRoaXMuX2Rlc3Ryb3kgPSBvcHRpb25zLmRlc3Ryb3k7XG4gIH1cblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ2Rlc3Ryb3llZCcsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiBzZXQodmFsdWUpIHtcbiAgICAvLyB3ZSBpZ25vcmUgdGhlIHZhbHVlIGlmIHRoZSBzdHJlYW1cbiAgICAvLyBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0XG4gICAgaWYgKCF0aGlzLl9yZWFkYWJsZVN0YXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfSAvLyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB0aGUgdXNlciBpcyBleHBsaWNpdGx5XG4gICAgLy8gbWFuYWdpbmcgZGVzdHJveWVkXG5cblxuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkID0gdmFsdWU7XG4gIH1cbn0pO1xuUmVhZGFibGUucHJvdG90eXBlLmRlc3Ryb3kgPSBkZXN0cm95SW1wbC5kZXN0cm95O1xuUmVhZGFibGUucHJvdG90eXBlLl91bmRlc3Ryb3kgPSBkZXN0cm95SW1wbC51bmRlc3Ryb3k7XG5cblJlYWRhYmxlLnByb3RvdHlwZS5fZGVzdHJveSA9IGZ1bmN0aW9uIChlcnIsIGNiKSB7XG4gIGNiKGVycik7XG59OyAvLyBNYW51YWxseSBzaG92ZSBzb21ldGhpbmcgaW50byB0aGUgcmVhZCgpIGJ1ZmZlci5cbi8vIFRoaXMgcmV0dXJucyB0cnVlIGlmIHRoZSBoaWdoV2F0ZXJNYXJrIGhhcyBub3QgYmVlbiBoaXQgeWV0LFxuLy8gc2ltaWxhciB0byBob3cgV3JpdGFibGUud3JpdGUoKSByZXR1cm5zIHRydWUgaWYgeW91IHNob3VsZFxuLy8gd3JpdGUoKSBzb21lIG1vcmUuXG5cblxuUmVhZGFibGUucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBza2lwQ2h1bmtDaGVjaztcblxuICBpZiAoIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBpZiAodHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmNvZGluZyB8fCBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG5cbiAgICAgIGlmIChlbmNvZGluZyAhPT0gc3RhdGUuZW5jb2RpbmcpIHtcbiAgICAgICAgY2h1bmsgPSBCdWZmZXIuZnJvbShjaHVuaywgZW5jb2RpbmcpO1xuICAgICAgICBlbmNvZGluZyA9ICcnO1xuICAgICAgfVxuXG4gICAgICBza2lwQ2h1bmtDaGVjayA9IHRydWU7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHNraXBDaHVua0NoZWNrID0gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIGNodW5rLCBlbmNvZGluZywgZmFsc2UsIHNraXBDaHVua0NoZWNrKTtcbn07IC8vIFVuc2hpZnQgc2hvdWxkICphbHdheXMqIGJlIHNvbWV0aGluZyBkaXJlY3RseSBvdXQgb2YgcmVhZCgpXG5cblxuUmVhZGFibGUucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgY2h1bmssIG51bGwsIHRydWUsIGZhbHNlKTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLCBjaHVuaywgZW5jb2RpbmcsIGFkZFRvRnJvbnQsIHNraXBDaHVua0NoZWNrKSB7XG4gIGRlYnVnKCdyZWFkYWJsZUFkZENodW5rJywgY2h1bmspO1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG5cbiAgaWYgKGNodW5rID09PSBudWxsKSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGVyO1xuICAgIGlmICghc2tpcENodW5rQ2hlY2spIGVyID0gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuayk7XG5cbiAgICBpZiAoZXIpIHtcbiAgICAgIGVycm9yT3JEZXN0cm95KHN0cmVhbSwgZXIpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUub2JqZWN0TW9kZSB8fCBjaHVuayAmJiBjaHVuay5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAodHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiAhc3RhdGUub2JqZWN0TW9kZSAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY2h1bmspICE9PSBCdWZmZXIucHJvdG90eXBlKSB7XG4gICAgICAgIGNodW5rID0gX3VpbnQ4QXJyYXlUb0J1ZmZlcihjaHVuayk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhZGRUb0Zyb250KSB7XG4gICAgICAgIGlmIChzdGF0ZS5lbmRFbWl0dGVkKSBlcnJvck9yRGVzdHJveShzdHJlYW0sIG5ldyBFUlJfU1RSRUFNX1VOU0hJRlRfQUZURVJfRU5EX0VWRU5UKCkpO2Vsc2UgYWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIHRydWUpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5lbmRlZCkge1xuICAgICAgICBlcnJvck9yRGVzdHJveShzdHJlYW0sIG5ldyBFUlJfU1RSRUFNX1BVU0hfQUZURVJfRU9GKCkpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5kZXN0cm95ZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFlbmNvZGluZykge1xuICAgICAgICAgIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG4gICAgICAgICAgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsubGVuZ3RoICE9PSAwKSBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZmFsc2UpO2Vsc2UgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghYWRkVG9Gcm9udCkge1xuICAgICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgICAgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gIH0gLy8gV2UgY2FuIHB1c2ggbW9yZSBkYXRhIGlmIHdlIGFyZSBiZWxvdyB0aGUgaGlnaFdhdGVyTWFyay5cbiAgLy8gQWxzbywgaWYgd2UgaGF2ZSBubyBkYXRhIHlldCwgd2UgY2FuIHN0YW5kIHNvbWUgbW9yZSBieXRlcy5cbiAgLy8gVGhpcyBpcyB0byB3b3JrIGFyb3VuZCBjYXNlcyB3aGVyZSBod209MCwgc3VjaCBhcyB0aGUgcmVwbC5cblxuXG4gIHJldHVybiAhc3RhdGUuZW5kZWQgJiYgKHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHwgc3RhdGUubGVuZ3RoID09PSAwKTtcbn1cblxuZnVuY3Rpb24gYWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGFkZFRvRnJvbnQpIHtcbiAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwICYmICFzdGF0ZS5zeW5jKSB7XG4gICAgc3RhdGUuYXdhaXREcmFpbiA9IDA7XG4gICAgc3RyZWFtLmVtaXQoJ2RhdGEnLCBjaHVuayk7XG4gIH0gZWxzZSB7XG4gICAgLy8gdXBkYXRlIHRoZSBidWZmZXIgaW5mby5cbiAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgaWYgKGFkZFRvRnJvbnQpIHN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtlbHNlIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcbiAgICBpZiAoc3RhdGUubmVlZFJlYWRhYmxlKSBlbWl0UmVhZGFibGUoc3RyZWFtKTtcbiAgfVxuXG4gIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5cbmZ1bmN0aW9uIGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspIHtcbiAgdmFyIGVyO1xuXG4gIGlmICghX2lzVWludDhBcnJheShjaHVuaykgJiYgdHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgRVJSX0lOVkFMSURfQVJHX1RZUEUoJ2NodW5rJywgWydzdHJpbmcnLCAnQnVmZmVyJywgJ1VpbnQ4QXJyYXknXSwgY2h1bmspO1xuICB9XG5cbiAgcmV0dXJuIGVyO1xufVxuXG5SZWFkYWJsZS5wcm90b3R5cGUuaXNQYXVzZWQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPT09IGZhbHNlO1xufTsgLy8gYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuXG5cblxuUmVhZGFibGUucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24gKGVuYykge1xuICBpZiAoIVN0cmluZ0RlY29kZXIpIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2Rlci8nKS5TdHJpbmdEZWNvZGVyO1xuICB2YXIgZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYyk7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVjb2RlciA9IGRlY29kZXI7IC8vIElmIHNldEVuY29kaW5nKG51bGwpLCBkZWNvZGVyLmVuY29kaW5nIGVxdWFscyB1dGY4XG5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmNvZGluZyA9IHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVjb2Rlci5lbmNvZGluZzsgLy8gSXRlcmF0ZSBvdmVyIGN1cnJlbnQgYnVmZmVyIHRvIGNvbnZlcnQgYWxyZWFkeSBzdG9yZWQgQnVmZmVyczpcblxuICB2YXIgcCA9IHRoaXMuX3JlYWRhYmxlU3RhdGUuYnVmZmVyLmhlYWQ7XG4gIHZhciBjb250ZW50ID0gJyc7XG5cbiAgd2hpbGUgKHAgIT09IG51bGwpIHtcbiAgICBjb250ZW50ICs9IGRlY29kZXIud3JpdGUocC5kYXRhKTtcbiAgICBwID0gcC5uZXh0O1xuICB9XG5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5idWZmZXIuY2xlYXIoKTtcblxuICBpZiAoY29udGVudCAhPT0gJycpIHRoaXMuX3JlYWRhYmxlU3RhdGUuYnVmZmVyLnB1c2goY29udGVudCk7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUubGVuZ3RoID0gY29udGVudC5sZW5ndGg7XG4gIHJldHVybiB0aGlzO1xufTsgLy8gRG9uJ3QgcmFpc2UgdGhlIGh3bSA+IDFHQlxuXG5cbnZhciBNQVhfSFdNID0gMHg0MDAwMDAwMDtcblxuZnVuY3Rpb24gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobikge1xuICBpZiAobiA+PSBNQVhfSFdNKSB7XG4gICAgLy8gVE9ETyhyb25hZyk6IFRocm93IEVSUl9WQUxVRV9PVVRfT0ZfUkFOR0UuXG4gICAgbiA9IE1BWF9IV007XG4gIH0gZWxzZSB7XG4gICAgLy8gR2V0IHRoZSBuZXh0IGhpZ2hlc3QgcG93ZXIgb2YgMiB0byBwcmV2ZW50IGluY3JlYXNpbmcgaHdtIGV4Y2Vzc2l2ZWx5IGluXG4gICAgLy8gdGlueSBhbW91bnRzXG4gICAgbi0tO1xuICAgIG4gfD0gbiA+Pj4gMTtcbiAgICBuIHw9IG4gPj4+IDI7XG4gICAgbiB8PSBuID4+PiA0O1xuICAgIG4gfD0gbiA+Pj4gODtcbiAgICBuIHw9IG4gPj4+IDE2O1xuICAgIG4rKztcbiAgfVxuXG4gIHJldHVybiBuO1xufSAvLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cblxuXG5mdW5jdGlvbiBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKSB7XG4gIGlmIChuIDw9IDAgfHwgc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKSByZXR1cm4gMDtcbiAgaWYgKHN0YXRlLm9iamVjdE1vZGUpIHJldHVybiAxO1xuXG4gIGlmIChuICE9PSBuKSB7XG4gICAgLy8gT25seSBmbG93IG9uZSBidWZmZXIgYXQgYSB0aW1lXG4gICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoKSByZXR1cm4gc3RhdGUuYnVmZmVyLmhlYWQuZGF0YS5sZW5ndGg7ZWxzZSByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICB9IC8vIElmIHdlJ3JlIGFza2luZyBmb3IgbW9yZSB0aGFuIHRoZSBjdXJyZW50IGh3bSwgdGhlbiByYWlzZSB0aGUgaHdtLlxuXG5cbiAgaWYgKG4gPiBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSBzdGF0ZS5oaWdoV2F0ZXJNYXJrID0gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobik7XG4gIGlmIChuIDw9IHN0YXRlLmxlbmd0aCkgcmV0dXJuIG47IC8vIERvbid0IGhhdmUgZW5vdWdoXG5cbiAgaWYgKCFzdGF0ZS5lbmRlZCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICByZXR1cm4gc3RhdGUubGVuZ3RoO1xufSAvLyB5b3UgY2FuIG92ZXJyaWRlIGVpdGhlciB0aGlzIG1ldGhvZCwgb3IgdGhlIGFzeW5jIF9yZWFkKG4pIGJlbG93LlxuXG5cblJlYWRhYmxlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgZGVidWcoJ3JlYWQnLCBuKTtcbiAgbiA9IHBhcnNlSW50KG4sIDEwKTtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIG5PcmlnID0gbjtcbiAgaWYgKG4gIT09IDApIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlOyAvLyBpZiB3ZSdyZSBkb2luZyByZWFkKDApIHRvIHRyaWdnZXIgYSByZWFkYWJsZSBldmVudCwgYnV0IHdlXG4gIC8vIGFscmVhZHkgaGF2ZSBhIGJ1bmNoIG9mIGRhdGEgaW4gdGhlIGJ1ZmZlciwgdGhlbiBqdXN0IHRyaWdnZXJcbiAgLy8gdGhlICdyZWFkYWJsZScgZXZlbnQgYW5kIG1vdmUgb24uXG5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUubmVlZFJlYWRhYmxlICYmICgoc3RhdGUuaGlnaFdhdGVyTWFyayAhPT0gMCA/IHN0YXRlLmxlbmd0aCA+PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrIDogc3RhdGUubGVuZ3RoID4gMCkgfHwgc3RhdGUuZW5kZWQpKSB7XG4gICAgZGVidWcoJ3JlYWQ6IGVtaXRSZWFkYWJsZScsIHN0YXRlLmxlbmd0aCwgc3RhdGUuZW5kZWQpO1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpIGVuZFJlYWRhYmxlKHRoaXMpO2Vsc2UgZW1pdFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgbiA9IGhvd011Y2hUb1JlYWQobiwgc3RhdGUpOyAvLyBpZiB3ZSd2ZSBlbmRlZCwgYW5kIHdlJ3JlIG5vdyBjbGVhciwgdGhlbiBmaW5pc2ggaXQgdXAuXG5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUuZW5kZWQpIHtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSBlbmRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSAvLyBBbGwgdGhlIGFjdHVhbCBjaHVuayBnZW5lcmF0aW9uIGxvZ2ljIG5lZWRzIHRvIGJlXG4gIC8vICpiZWxvdyogdGhlIGNhbGwgdG8gX3JlYWQuICBUaGUgcmVhc29uIGlzIHRoYXQgaW4gY2VydGFpblxuICAvLyBzeW50aGV0aWMgc3RyZWFtIGNhc2VzLCBzdWNoIGFzIHBhc3N0aHJvdWdoIHN0cmVhbXMsIF9yZWFkXG4gIC8vIG1heSBiZSBhIGNvbXBsZXRlbHkgc3luY2hyb25vdXMgb3BlcmF0aW9uIHdoaWNoIG1heSBjaGFuZ2VcbiAgLy8gdGhlIHN0YXRlIG9mIHRoZSByZWFkIGJ1ZmZlciwgcHJvdmlkaW5nIGVub3VnaCBkYXRhIHdoZW5cbiAgLy8gYmVmb3JlIHRoZXJlIHdhcyAqbm90KiBlbm91Z2guXG4gIC8vXG4gIC8vIFNvLCB0aGUgc3RlcHMgYXJlOlxuICAvLyAxLiBGaWd1cmUgb3V0IHdoYXQgdGhlIHN0YXRlIG9mIHRoaW5ncyB3aWxsIGJlIGFmdGVyIHdlIGRvXG4gIC8vIGEgcmVhZCBmcm9tIHRoZSBidWZmZXIuXG4gIC8vXG4gIC8vIDIuIElmIHRoYXQgcmVzdWx0aW5nIHN0YXRlIHdpbGwgdHJpZ2dlciBhIF9yZWFkLCB0aGVuIGNhbGwgX3JlYWQuXG4gIC8vIE5vdGUgdGhhdCB0aGlzIG1heSBiZSBhc3luY2hyb25vdXMsIG9yIHN5bmNocm9ub3VzLiAgWWVzLCBpdCBpc1xuICAvLyBkZWVwbHkgdWdseSB0byB3cml0ZSBBUElzIHRoaXMgd2F5LCBidXQgdGhhdCBzdGlsbCBkb2Vzbid0IG1lYW5cbiAgLy8gdGhhdCB0aGUgUmVhZGFibGUgY2xhc3Mgc2hvdWxkIGJlaGF2ZSBpbXByb3Blcmx5LCBhcyBzdHJlYW1zIGFyZVxuICAvLyBkZXNpZ25lZCB0byBiZSBzeW5jL2FzeW5jIGFnbm9zdGljLlxuICAvLyBUYWtlIG5vdGUgaWYgdGhlIF9yZWFkIGNhbGwgaXMgc3luYyBvciBhc3luYyAoaWUsIGlmIHRoZSByZWFkIGNhbGxcbiAgLy8gaGFzIHJldHVybmVkIHlldCksIHNvIHRoYXQgd2Uga25vdyB3aGV0aGVyIG9yIG5vdCBpdCdzIHNhZmUgdG8gZW1pdFxuICAvLyAncmVhZGFibGUnIGV0Yy5cbiAgLy9cbiAgLy8gMy4gQWN0dWFsbHkgcHVsbCB0aGUgcmVxdWVzdGVkIGNodW5rcyBvdXQgb2YgdGhlIGJ1ZmZlciBhbmQgcmV0dXJuLlxuICAvLyBpZiB3ZSBuZWVkIGEgcmVhZGFibGUgZXZlbnQsIHRoZW4gd2UgbmVlZCB0byBkbyBzb21lIHJlYWRpbmcuXG5cblxuICB2YXIgZG9SZWFkID0gc3RhdGUubmVlZFJlYWRhYmxlO1xuICBkZWJ1ZygnbmVlZCByZWFkYWJsZScsIGRvUmVhZCk7IC8vIGlmIHdlIGN1cnJlbnRseSBoYXZlIGxlc3MgdGhhbiB0aGUgaGlnaFdhdGVyTWFyaywgdGhlbiBhbHNvIHJlYWQgc29tZVxuXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgfHwgc3RhdGUubGVuZ3RoIC0gbiA8IHN0YXRlLmhpZ2hXYXRlck1hcmspIHtcbiAgICBkb1JlYWQgPSB0cnVlO1xuICAgIGRlYnVnKCdsZW5ndGggbGVzcyB0aGFuIHdhdGVybWFyaycsIGRvUmVhZCk7XG4gIH0gLy8gaG93ZXZlciwgaWYgd2UndmUgZW5kZWQsIHRoZW4gdGhlcmUncyBubyBwb2ludCwgYW5kIGlmIHdlJ3JlIGFscmVhZHlcbiAgLy8gcmVhZGluZywgdGhlbiBpdCdzIHVubmVjZXNzYXJ5LlxuXG5cbiAgaWYgKHN0YXRlLmVuZGVkIHx8IHN0YXRlLnJlYWRpbmcpIHtcbiAgICBkb1JlYWQgPSBmYWxzZTtcbiAgICBkZWJ1ZygncmVhZGluZyBvciBlbmRlZCcsIGRvUmVhZCk7XG4gIH0gZWxzZSBpZiAoZG9SZWFkKSB7XG4gICAgZGVidWcoJ2RvIHJlYWQnKTtcbiAgICBzdGF0ZS5yZWFkaW5nID0gdHJ1ZTtcbiAgICBzdGF0ZS5zeW5jID0gdHJ1ZTsgLy8gaWYgdGhlIGxlbmd0aCBpcyBjdXJyZW50bHkgemVybywgdGhlbiB3ZSAqbmVlZCogYSByZWFkYWJsZSBldmVudC5cblxuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7IC8vIGNhbGwgaW50ZXJuYWwgcmVhZCBtZXRob2RcblxuICAgIHRoaXMuX3JlYWQoc3RhdGUuaGlnaFdhdGVyTWFyayk7XG5cbiAgICBzdGF0ZS5zeW5jID0gZmFsc2U7IC8vIElmIF9yZWFkIHB1c2hlZCBkYXRhIHN5bmNocm9ub3VzbHksIHRoZW4gYHJlYWRpbmdgIHdpbGwgYmUgZmFsc2UsXG4gICAgLy8gYW5kIHdlIG5lZWQgdG8gcmUtZXZhbHVhdGUgaG93IG11Y2ggZGF0YSB3ZSBjYW4gcmV0dXJuIHRvIHRoZSB1c2VyLlxuXG4gICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSBuID0gaG93TXVjaFRvUmVhZChuT3JpZywgc3RhdGUpO1xuICB9XG5cbiAgdmFyIHJldDtcbiAgaWYgKG4gPiAwKSByZXQgPSBmcm9tTGlzdChuLCBzdGF0ZSk7ZWxzZSByZXQgPSBudWxsO1xuXG4gIGlmIChyZXQgPT09IG51bGwpIHtcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSBzdGF0ZS5sZW5ndGggPD0gc3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgICBuID0gMDtcbiAgfSBlbHNlIHtcbiAgICBzdGF0ZS5sZW5ndGggLT0gbjtcbiAgICBzdGF0ZS5hd2FpdERyYWluID0gMDtcbiAgfVxuXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICAvLyBJZiB3ZSBoYXZlIG5vdGhpbmcgaW4gdGhlIGJ1ZmZlciwgdGhlbiB3ZSB3YW50IHRvIGtub3dcbiAgICAvLyBhcyBzb29uIGFzIHdlICpkbyogZ2V0IHNvbWV0aGluZyBpbnRvIHRoZSBidWZmZXIuXG4gICAgaWYgKCFzdGF0ZS5lbmRlZCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTsgLy8gSWYgd2UgdHJpZWQgdG8gcmVhZCgpIHBhc3QgdGhlIEVPRiwgdGhlbiBlbWl0IGVuZCBvbiB0aGUgbmV4dCB0aWNrLlxuXG4gICAgaWYgKG5PcmlnICE9PSBuICYmIHN0YXRlLmVuZGVkKSBlbmRSZWFkYWJsZSh0aGlzKTtcbiAgfVxuXG4gIGlmIChyZXQgIT09IG51bGwpIHRoaXMuZW1pdCgnZGF0YScsIHJldCk7XG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpIHtcbiAgZGVidWcoJ29uRW9mQ2h1bmsnKTtcbiAgaWYgKHN0YXRlLmVuZGVkKSByZXR1cm47XG5cbiAgaWYgKHN0YXRlLmRlY29kZXIpIHtcbiAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuXG4gICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkge1xuICAgICAgc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuICAgICAgc3RhdGUubGVuZ3RoICs9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcblxuICBpZiAoc3RhdGUuc3luYykge1xuICAgIC8vIGlmIHdlIGFyZSBzeW5jLCB3YWl0IHVudGlsIG5leHQgdGljayB0byBlbWl0IHRoZSBkYXRhLlxuICAgIC8vIE90aGVyd2lzZSB3ZSByaXNrIGVtaXR0aW5nIGRhdGEgaW4gdGhlIGZsb3coKVxuICAgIC8vIHRoZSByZWFkYWJsZSBjb2RlIHRyaWdnZXJzIGR1cmluZyBhIHJlYWQoKSBjYWxsXG4gICAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gZW1pdCAncmVhZGFibGUnIG5vdyB0byBtYWtlIHN1cmUgaXQgZ2V0cyBwaWNrZWQgdXAuXG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG5cbiAgICBpZiAoIXN0YXRlLmVtaXR0ZWRSZWFkYWJsZSkge1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAgIGVtaXRSZWFkYWJsZV8oc3RyZWFtKTtcbiAgICB9XG4gIH1cbn0gLy8gRG9uJ3QgZW1pdCByZWFkYWJsZSByaWdodCBhd2F5IGluIHN5bmMgbW9kZSwgYmVjYXVzZSB0aGlzIGNhbiB0cmlnZ2VyXG4vLyBhbm90aGVyIHJlYWQoKSBjYWxsID0+IHN0YWNrIG92ZXJmbG93LiAgVGhpcyB3YXksIGl0IG1pZ2h0IHRyaWdnZXJcbi8vIGEgbmV4dFRpY2sgcmVjdXJzaW9uIHdhcm5pbmcsIGJ1dCB0aGF0J3Mgbm90IHNvIGJhZC5cblxuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgZGVidWcoJ2VtaXRSZWFkYWJsZScsIHN0YXRlLm5lZWRSZWFkYWJsZSwgc3RhdGUuZW1pdHRlZFJlYWRhYmxlKTtcbiAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG5cbiAgaWYgKCFzdGF0ZS5lbWl0dGVkUmVhZGFibGUpIHtcbiAgICBkZWJ1ZygnZW1pdFJlYWRhYmxlJywgc3RhdGUuZmxvd2luZyk7XG4gICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBwcm9jZXNzLm5leHRUaWNrKGVtaXRSZWFkYWJsZV8sIHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlXyhzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBkZWJ1ZygnZW1pdFJlYWRhYmxlXycsIHN0YXRlLmRlc3Ryb3llZCwgc3RhdGUubGVuZ3RoLCBzdGF0ZS5lbmRlZCk7XG5cbiAgaWYgKCFzdGF0ZS5kZXN0cm95ZWQgJiYgKHN0YXRlLmxlbmd0aCB8fCBzdGF0ZS5lbmRlZCkpIHtcbiAgICBzdHJlYW0uZW1pdCgncmVhZGFibGUnKTtcbiAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgfSAvLyBUaGUgc3RyZWFtIG5lZWRzIGFub3RoZXIgcmVhZGFibGUgZXZlbnQgaWZcbiAgLy8gMS4gSXQgaXMgbm90IGZsb3dpbmcsIGFzIHRoZSBmbG93IG1lY2hhbmlzbSB3aWxsIHRha2VcbiAgLy8gICAgY2FyZSBvZiBpdC5cbiAgLy8gMi4gSXQgaXMgbm90IGVuZGVkLlxuICAvLyAzLiBJdCBpcyBiZWxvdyB0aGUgaGlnaFdhdGVyTWFyaywgc28gd2UgY2FuIHNjaGVkdWxlXG4gIC8vICAgIGFub3RoZXIgcmVhZGFibGUgbGF0ZXIuXG5cblxuICBzdGF0ZS5uZWVkUmVhZGFibGUgPSAhc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUuZW5kZWQgJiYgc3RhdGUubGVuZ3RoIDw9IHN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIGZsb3coc3RyZWFtKTtcbn0gLy8gYXQgdGhpcyBwb2ludCwgdGhlIHVzZXIgaGFzIHByZXN1bWFibHkgc2VlbiB0aGUgJ3JlYWRhYmxlJyBldmVudCxcbi8vIGFuZCBjYWxsZWQgcmVhZCgpIHRvIGNvbnN1bWUgc29tZSBkYXRhLiAgdGhhdCBtYXkgaGF2ZSB0cmlnZ2VyZWRcbi8vIGluIHR1cm4gYW5vdGhlciBfcmVhZChuKSBjYWxsLCBpbiB3aGljaCBjYXNlIHJlYWRpbmcgPSB0cnVlIGlmXG4vLyBpdCdzIGluIHByb2dyZXNzLlxuLy8gSG93ZXZlciwgaWYgd2UncmUgbm90IGVuZGVkLCBvciByZWFkaW5nLCBhbmQgdGhlIGxlbmd0aCA8IGh3bSxcbi8vIHRoZW4gZ28gYWhlYWQgYW5kIHRyeSB0byByZWFkIHNvbWUgbW9yZSBwcmVlbXB0aXZlbHkuXG5cblxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZ01vcmUpIHtcbiAgICBzdGF0ZS5yZWFkaW5nTW9yZSA9IHRydWU7XG4gICAgcHJvY2Vzcy5uZXh0VGljayhtYXliZVJlYWRNb3JlXywgc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZV8oc3RyZWFtLCBzdGF0ZSkge1xuICAvLyBBdHRlbXB0IHRvIHJlYWQgbW9yZSBkYXRhIGlmIHdlIHNob3VsZC5cbiAgLy9cbiAgLy8gVGhlIGNvbmRpdGlvbnMgZm9yIHJlYWRpbmcgbW9yZSBkYXRhIGFyZSAob25lIG9mKTpcbiAgLy8gLSBOb3QgZW5vdWdoIGRhdGEgYnVmZmVyZWQgKHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmspLiBUaGUgbG9vcFxuICAvLyAgIGlzIHJlc3BvbnNpYmxlIGZvciBmaWxsaW5nIHRoZSBidWZmZXIgd2l0aCBlbm91Z2ggZGF0YSBpZiBzdWNoIGRhdGFcbiAgLy8gICBpcyBhdmFpbGFibGUuIElmIGhpZ2hXYXRlck1hcmsgaXMgMCBhbmQgd2UgYXJlIG5vdCBpbiB0aGUgZmxvd2luZyBtb2RlXG4gIC8vICAgd2Ugc2hvdWxkIF9ub3RfIGF0dGVtcHQgdG8gYnVmZmVyIGFueSBleHRyYSBkYXRhLiBXZSdsbCBnZXQgbW9yZSBkYXRhXG4gIC8vICAgd2hlbiB0aGUgc3RyZWFtIGNvbnN1bWVyIGNhbGxzIHJlYWQoKSBpbnN0ZWFkLlxuICAvLyAtIE5vIGRhdGEgaW4gdGhlIGJ1ZmZlciwgYW5kIHRoZSBzdHJlYW0gaXMgaW4gZmxvd2luZyBtb2RlLiBJbiB0aGlzIG1vZGVcbiAgLy8gICB0aGUgbG9vcCBiZWxvdyBpcyByZXNwb25zaWJsZSBmb3IgZW5zdXJpbmcgcmVhZCgpIGlzIGNhbGxlZC4gRmFpbGluZyB0b1xuICAvLyAgIGNhbGwgcmVhZCBoZXJlIHdvdWxkIGFib3J0IHRoZSBmbG93IGFuZCB0aGVyZSdzIG5vIG90aGVyIG1lY2hhbmlzbSBmb3JcbiAgLy8gICBjb250aW51aW5nIHRoZSBmbG93IGlmIHRoZSBzdHJlYW0gY29uc3VtZXIgaGFzIGp1c3Qgc3Vic2NyaWJlZCB0byB0aGVcbiAgLy8gICAnZGF0YScgZXZlbnQuXG4gIC8vXG4gIC8vIEluIGFkZGl0aW9uIHRvIHRoZSBhYm92ZSBjb25kaXRpb25zIHRvIGtlZXAgcmVhZGluZyBkYXRhLCB0aGUgZm9sbG93aW5nXG4gIC8vIGNvbmRpdGlvbnMgcHJldmVudCB0aGUgZGF0YSBmcm9tIGJlaW5nIHJlYWQ6XG4gIC8vIC0gVGhlIHN0cmVhbSBoYXMgZW5kZWQgKHN0YXRlLmVuZGVkKS5cbiAgLy8gLSBUaGVyZSBpcyBhbHJlYWR5IGEgcGVuZGluZyAncmVhZCcgb3BlcmF0aW9uIChzdGF0ZS5yZWFkaW5nKS4gVGhpcyBpcyBhXG4gIC8vICAgY2FzZSB3aGVyZSB0aGUgdGhlIHN0cmVhbSBoYXMgY2FsbGVkIHRoZSBpbXBsZW1lbnRhdGlvbiBkZWZpbmVkIF9yZWFkKClcbiAgLy8gICBtZXRob2QsIGJ1dCB0aGV5IGFyZSBwcm9jZXNzaW5nIHRoZSBjYWxsIGFzeW5jaHJvbm91c2x5IGFuZCBoYXZlIF9ub3RfXG4gIC8vICAgY2FsbGVkIHB1c2goKSB3aXRoIG5ldyBkYXRhLiBJbiB0aGlzIGNhc2Ugd2Ugc2tpcCBwZXJmb3JtaW5nIG1vcmVcbiAgLy8gICByZWFkKClzLiBUaGUgZXhlY3V0aW9uIGVuZHMgaW4gdGhpcyBtZXRob2QgYWdhaW4gYWZ0ZXIgdGhlIF9yZWFkKCkgZW5kc1xuICAvLyAgIHVwIGNhbGxpbmcgcHVzaCgpIHdpdGggbW9yZSBkYXRhLlxuICB3aGlsZSAoIXN0YXRlLnJlYWRpbmcgJiYgIXN0YXRlLmVuZGVkICYmIChzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwKSkge1xuICAgIHZhciBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gICAgZGVidWcoJ21heWJlUmVhZE1vcmUgcmVhZCAwJyk7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgaWYgKGxlbiA9PT0gc3RhdGUubGVuZ3RoKSAvLyBkaWRuJ3QgZ2V0IGFueSBkYXRhLCBzdG9wIHNwaW5uaW5nLlxuICAgICAgYnJlYWs7XG4gIH1cblxuICBzdGF0ZS5yZWFkaW5nTW9yZSA9IGZhbHNlO1xufSAvLyBhYnN0cmFjdCBtZXRob2QuICB0byBiZSBvdmVycmlkZGVuIGluIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyBjYWxsIGNiKGVyLCBkYXRhKSB3aGVyZSBkYXRhIGlzIDw9IG4gaW4gbGVuZ3RoLlxuLy8gZm9yIHZpcnR1YWwgKG5vbi1zdHJpbmcsIG5vbi1idWZmZXIpIHN0cmVhbXMsIFwibGVuZ3RoXCIgaXMgc29tZXdoYXRcbi8vIGFyYml0cmFyeSwgYW5kIHBlcmhhcHMgbm90IHZlcnkgbWVhbmluZ2Z1bC5cblxuXG5SZWFkYWJsZS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICBlcnJvck9yRGVzdHJveSh0aGlzLCBuZXcgRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQoJ19yZWFkKCknKSk7XG59O1xuXG5SZWFkYWJsZS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uIChkZXN0LCBwaXBlT3B0cykge1xuICB2YXIgc3JjID0gdGhpcztcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBzd2l0Y2ggKHN0YXRlLnBpcGVzQ291bnQpIHtcbiAgICBjYXNlIDA6XG4gICAgICBzdGF0ZS5waXBlcyA9IGRlc3Q7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgMTpcbiAgICAgIHN0YXRlLnBpcGVzID0gW3N0YXRlLnBpcGVzLCBkZXN0XTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHN0YXRlLnBpcGVzLnB1c2goZGVzdCk7XG4gICAgICBicmVhaztcbiAgfVxuXG4gIHN0YXRlLnBpcGVzQ291bnQgKz0gMTtcbiAgZGVidWcoJ3BpcGUgY291bnQ9JWQgb3B0cz0laicsIHN0YXRlLnBpcGVzQ291bnQsIHBpcGVPcHRzKTtcbiAgdmFyIGRvRW5kID0gKCFwaXBlT3B0cyB8fCBwaXBlT3B0cy5lbmQgIT09IGZhbHNlKSAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZG91dCAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZGVycjtcbiAgdmFyIGVuZEZuID0gZG9FbmQgPyBvbmVuZCA6IHVucGlwZTtcbiAgaWYgKHN0YXRlLmVuZEVtaXR0ZWQpIHByb2Nlc3MubmV4dFRpY2soZW5kRm4pO2Vsc2Ugc3JjLm9uY2UoJ2VuZCcsIGVuZEZuKTtcbiAgZGVzdC5vbigndW5waXBlJywgb251bnBpcGUpO1xuXG4gIGZ1bmN0aW9uIG9udW5waXBlKHJlYWRhYmxlLCB1bnBpcGVJbmZvKSB7XG4gICAgZGVidWcoJ29udW5waXBlJyk7XG5cbiAgICBpZiAocmVhZGFibGUgPT09IHNyYykge1xuICAgICAgaWYgKHVucGlwZUluZm8gJiYgdW5waXBlSW5mby5oYXNVbnBpcGVkID09PSBmYWxzZSkge1xuICAgICAgICB1bnBpcGVJbmZvLmhhc1VucGlwZWQgPSB0cnVlO1xuICAgICAgICBjbGVhbnVwKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgZGVidWcoJ29uZW5kJyk7XG4gICAgZGVzdC5lbmQoKTtcbiAgfSAvLyB3aGVuIHRoZSBkZXN0IGRyYWlucywgaXQgcmVkdWNlcyB0aGUgYXdhaXREcmFpbiBjb3VudGVyXG4gIC8vIG9uIHRoZSBzb3VyY2UuICBUaGlzIHdvdWxkIGJlIG1vcmUgZWxlZ2FudCB3aXRoIGEgLm9uY2UoKVxuICAvLyBoYW5kbGVyIGluIGZsb3coKSwgYnV0IGFkZGluZyBhbmQgcmVtb3ZpbmcgcmVwZWF0ZWRseSBpc1xuICAvLyB0b28gc2xvdy5cblxuXG4gIHZhciBvbmRyYWluID0gcGlwZU9uRHJhaW4oc3JjKTtcbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcbiAgdmFyIGNsZWFuZWRVcCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgZGVidWcoJ2NsZWFudXAnKTsgLy8gY2xlYW51cCBldmVudCBoYW5kbGVycyBvbmNlIHRoZSBwaXBlIGlzIGJyb2tlblxuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ3VucGlwZScsIG9udW5waXBlKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIHVucGlwZSk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcbiAgICBjbGVhbmVkVXAgPSB0cnVlOyAvLyBpZiB0aGUgcmVhZGVyIGlzIHdhaXRpbmcgZm9yIGEgZHJhaW4gZXZlbnQgZnJvbSB0aGlzXG4gICAgLy8gc3BlY2lmaWMgd3JpdGVyLCB0aGVuIGl0IHdvdWxkIGNhdXNlIGl0IHRvIG5ldmVyIHN0YXJ0XG4gICAgLy8gZmxvd2luZyBhZ2Fpbi5cbiAgICAvLyBTbywgaWYgdGhpcyBpcyBhd2FpdGluZyBhIGRyYWluLCB0aGVuIHdlIGp1c3QgY2FsbCBpdCBub3cuXG4gICAgLy8gSWYgd2UgZG9uJ3Qga25vdywgdGhlbiBhc3N1bWUgdGhhdCB3ZSBhcmUgd2FpdGluZyBmb3Igb25lLlxuXG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gJiYgKCFkZXN0Ll93cml0YWJsZVN0YXRlIHx8IGRlc3QuX3dyaXRhYmxlU3RhdGUubmVlZERyYWluKSkgb25kcmFpbigpO1xuICB9XG5cbiAgc3JjLm9uKCdkYXRhJywgb25kYXRhKTtcblxuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBkZWJ1Zygnb25kYXRhJyk7XG4gICAgdmFyIHJldCA9IGRlc3Qud3JpdGUoY2h1bmspO1xuICAgIGRlYnVnKCdkZXN0LndyaXRlJywgcmV0KTtcblxuICAgIGlmIChyZXQgPT09IGZhbHNlKSB7XG4gICAgICAvLyBJZiB0aGUgdXNlciB1bnBpcGVkIGR1cmluZyBgZGVzdC53cml0ZSgpYCwgaXQgaXMgcG9zc2libGVcbiAgICAgIC8vIHRvIGdldCBzdHVjayBpbiBhIHBlcm1hbmVudGx5IHBhdXNlZCBzdGF0ZSBpZiB0aGF0IHdyaXRlXG4gICAgICAvLyBhbHNvIHJldHVybmVkIGZhbHNlLlxuICAgICAgLy8gPT4gQ2hlY2sgd2hldGhlciBgZGVzdGAgaXMgc3RpbGwgYSBwaXBpbmcgZGVzdGluYXRpb24uXG4gICAgICBpZiAoKHN0YXRlLnBpcGVzQ291bnQgPT09IDEgJiYgc3RhdGUucGlwZXMgPT09IGRlc3QgfHwgc3RhdGUucGlwZXNDb3VudCA+IDEgJiYgaW5kZXhPZihzdGF0ZS5waXBlcywgZGVzdCkgIT09IC0xKSAmJiAhY2xlYW5lZFVwKSB7XG4gICAgICAgIGRlYnVnKCdmYWxzZSB3cml0ZSByZXNwb25zZSwgcGF1c2UnLCBzdGF0ZS5hd2FpdERyYWluKTtcbiAgICAgICAgc3RhdGUuYXdhaXREcmFpbisrO1xuICAgICAgfVxuXG4gICAgICBzcmMucGF1c2UoKTtcbiAgICB9XG4gIH0gLy8gaWYgdGhlIGRlc3QgaGFzIGFuIGVycm9yLCB0aGVuIHN0b3AgcGlwaW5nIGludG8gaXQuXG4gIC8vIGhvd2V2ZXIsIGRvbid0IHN1cHByZXNzIHRoZSB0aHJvd2luZyBiZWhhdmlvciBmb3IgdGhpcy5cblxuXG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXIpIHtcbiAgICBkZWJ1Zygnb25lcnJvcicsIGVyKTtcbiAgICB1bnBpcGUoKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGlmIChFRWxpc3RlbmVyQ291bnQoZGVzdCwgJ2Vycm9yJykgPT09IDApIGVycm9yT3JEZXN0cm95KGRlc3QsIGVyKTtcbiAgfSAvLyBNYWtlIHN1cmUgb3VyIGVycm9yIGhhbmRsZXIgaXMgYXR0YWNoZWQgYmVmb3JlIHVzZXJsYW5kIG9uZXMuXG5cblxuICBwcmVwZW5kTGlzdGVuZXIoZGVzdCwgJ2Vycm9yJywgb25lcnJvcik7IC8vIEJvdGggY2xvc2UgYW5kIGZpbmlzaCBzaG91bGQgdHJpZ2dlciB1bnBpcGUsIGJ1dCBvbmx5IG9uY2UuXG5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgdW5waXBlKCk7XG4gIH1cblxuICBkZXN0Lm9uY2UoJ2Nsb3NlJywgb25jbG9zZSk7XG5cbiAgZnVuY3Rpb24gb25maW5pc2goKSB7XG4gICAgZGVidWcoJ29uZmluaXNoJyk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICB1bnBpcGUoKTtcbiAgfVxuXG4gIGRlc3Qub25jZSgnZmluaXNoJywgb25maW5pc2gpO1xuXG4gIGZ1bmN0aW9uIHVucGlwZSgpIHtcbiAgICBkZWJ1ZygndW5waXBlJyk7XG4gICAgc3JjLnVucGlwZShkZXN0KTtcbiAgfSAvLyB0ZWxsIHRoZSBkZXN0IHRoYXQgaXQncyBiZWluZyBwaXBlZCB0b1xuXG5cbiAgZGVzdC5lbWl0KCdwaXBlJywgc3JjKTsgLy8gc3RhcnQgdGhlIGZsb3cgaWYgaXQgaGFzbid0IGJlZW4gc3RhcnRlZCBhbHJlYWR5LlxuXG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdwaXBlIHJlc3VtZScpO1xuICAgIHNyYy5yZXN1bWUoKTtcbiAgfVxuXG4gIHJldHVybiBkZXN0O1xufTtcblxuZnVuY3Rpb24gcGlwZU9uRHJhaW4oc3JjKSB7XG4gIHJldHVybiBmdW5jdGlvbiBwaXBlT25EcmFpbkZ1bmN0aW9uUmVzdWx0KCkge1xuICAgIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgICBkZWJ1ZygncGlwZU9uRHJhaW4nLCBzdGF0ZS5hd2FpdERyYWluKTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbikgc3RhdGUuYXdhaXREcmFpbi0tO1xuXG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gPT09IDAgJiYgRUVsaXN0ZW5lckNvdW50KHNyYywgJ2RhdGEnKSkge1xuICAgICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG4gICAgICBmbG93KHNyYyk7XG4gICAgfVxuICB9O1xufVxuXG5SZWFkYWJsZS5wcm90b3R5cGUudW5waXBlID0gZnVuY3Rpb24gKGRlc3QpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHVucGlwZUluZm8gPSB7XG4gICAgaGFzVW5waXBlZDogZmFsc2VcbiAgfTsgLy8gaWYgd2UncmUgbm90IHBpcGluZyBhbnl3aGVyZSwgdGhlbiBkbyBub3RoaW5nLlxuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAwKSByZXR1cm4gdGhpczsgLy8ganVzdCBvbmUgZGVzdGluYXRpb24uICBtb3N0IGNvbW1vbiBjYXNlLlxuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSB7XG4gICAgLy8gcGFzc2VkIGluIG9uZSwgYnV0IGl0J3Mgbm90IHRoZSByaWdodCBvbmUuXG4gICAgaWYgKGRlc3QgJiYgZGVzdCAhPT0gc3RhdGUucGlwZXMpIHJldHVybiB0aGlzO1xuICAgIGlmICghZGVzdCkgZGVzdCA9IHN0YXRlLnBpcGVzOyAvLyBnb3QgYSBtYXRjaC5cblxuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgaWYgKGRlc3QpIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcywgdW5waXBlSW5mbyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0gLy8gc2xvdyBjYXNlLiBtdWx0aXBsZSBwaXBlIGRlc3RpbmF0aW9ucy5cblxuXG4gIGlmICghZGVzdCkge1xuICAgIC8vIHJlbW92ZSBhbGwuXG4gICAgdmFyIGRlc3RzID0gc3RhdGUucGlwZXM7XG4gICAgdmFyIGxlbiA9IHN0YXRlLnBpcGVzQ291bnQ7XG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGRlc3RzW2ldLmVtaXQoJ3VucGlwZScsIHRoaXMsIHtcbiAgICAgICAgaGFzVW5waXBlZDogZmFsc2VcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9IC8vIHRyeSB0byBmaW5kIHRoZSByaWdodCBvbmUuXG5cblxuICB2YXIgaW5kZXggPSBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KTtcbiAgaWYgKGluZGV4ID09PSAtMSkgcmV0dXJuIHRoaXM7XG4gIHN0YXRlLnBpcGVzLnNwbGljZShpbmRleCwgMSk7XG4gIHN0YXRlLnBpcGVzQ291bnQgLT0gMTtcbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHN0YXRlLnBpcGVzID0gc3RhdGUucGlwZXNbMF07XG4gIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcywgdW5waXBlSW5mbyk7XG4gIHJldHVybiB0aGlzO1xufTsgLy8gc2V0IHVwIGRhdGEgZXZlbnRzIGlmIHRoZXkgYXJlIGFza2VkIGZvclxuLy8gRW5zdXJlIHJlYWRhYmxlIGxpc3RlbmVycyBldmVudHVhbGx5IGdldCBzb21ldGhpbmdcblxuXG5SZWFkYWJsZS5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXYsIGZuKSB7XG4gIHZhciByZXMgPSBTdHJlYW0ucHJvdG90eXBlLm9uLmNhbGwodGhpcywgZXYsIGZuKTtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBpZiAoZXYgPT09ICdkYXRhJykge1xuICAgIC8vIHVwZGF0ZSByZWFkYWJsZUxpc3RlbmluZyBzbyB0aGF0IHJlc3VtZSgpIG1heSBiZSBhIG5vLW9wXG4gICAgLy8gYSBmZXcgbGluZXMgZG93bi4gVGhpcyBpcyBuZWVkZWQgdG8gc3VwcG9ydCBvbmNlKCdyZWFkYWJsZScpLlxuICAgIHN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nID0gdGhpcy5saXN0ZW5lckNvdW50KCdyZWFkYWJsZScpID4gMDsgLy8gVHJ5IHN0YXJ0IGZsb3dpbmcgb24gbmV4dCB0aWNrIGlmIHN0cmVhbSBpc24ndCBleHBsaWNpdGx5IHBhdXNlZFxuXG4gICAgaWYgKHN0YXRlLmZsb3dpbmcgIT09IGZhbHNlKSB0aGlzLnJlc3VtZSgpO1xuICB9IGVsc2UgaWYgKGV2ID09PSAncmVhZGFibGUnKSB7XG4gICAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmICFzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZykge1xuICAgICAgc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcgPSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBkZWJ1Zygnb24gcmVhZGFibGUnLCBzdGF0ZS5sZW5ndGgsIHN0YXRlLnJlYWRpbmcpO1xuXG4gICAgICBpZiAoc3RhdGUubGVuZ3RoKSB7XG4gICAgICAgIGVtaXRSZWFkYWJsZSh0aGlzKTtcbiAgICAgIH0gZWxzZSBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhuUmVhZGluZ05leHRUaWNrLCB0aGlzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLmFkZExpc3RlbmVyID0gUmVhZGFibGUucHJvdG90eXBlLm9uO1xuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiAoZXYsIGZuKSB7XG4gIHZhciByZXMgPSBTdHJlYW0ucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyLmNhbGwodGhpcywgZXYsIGZuKTtcblxuICBpZiAoZXYgPT09ICdyZWFkYWJsZScpIHtcbiAgICAvLyBXZSBuZWVkIHRvIGNoZWNrIGlmIHRoZXJlIGlzIHNvbWVvbmUgc3RpbGwgbGlzdGVuaW5nIHRvXG4gICAgLy8gcmVhZGFibGUgYW5kIHJlc2V0IHRoZSBzdGF0ZS4gSG93ZXZlciB0aGlzIG5lZWRzIHRvIGhhcHBlblxuICAgIC8vIGFmdGVyIHJlYWRhYmxlIGhhcyBiZWVuIGVtaXR0ZWQgYnV0IGJlZm9yZSBJL08gKG5leHRUaWNrKSB0b1xuICAgIC8vIHN1cHBvcnQgb25jZSgncmVhZGFibGUnLCBmbikgY3ljbGVzLiBUaGlzIG1lYW5zIHRoYXQgY2FsbGluZ1xuICAgIC8vIHJlc3VtZSB3aXRoaW4gdGhlIHNhbWUgdGljayB3aWxsIGhhdmUgbm9cbiAgICAvLyBlZmZlY3QuXG4gICAgcHJvY2Vzcy5uZXh0VGljayh1cGRhdGVSZWFkYWJsZUxpc3RlbmluZywgdGhpcyk7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uIChldikge1xuICB2YXIgcmVzID0gU3RyZWFtLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICBpZiAoZXYgPT09ICdyZWFkYWJsZScgfHwgZXYgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIFdlIG5lZWQgdG8gY2hlY2sgaWYgdGhlcmUgaXMgc29tZW9uZSBzdGlsbCBsaXN0ZW5pbmcgdG9cbiAgICAvLyByZWFkYWJsZSBhbmQgcmVzZXQgdGhlIHN0YXRlLiBIb3dldmVyIHRoaXMgbmVlZHMgdG8gaGFwcGVuXG4gICAgLy8gYWZ0ZXIgcmVhZGFibGUgaGFzIGJlZW4gZW1pdHRlZCBidXQgYmVmb3JlIEkvTyAobmV4dFRpY2spIHRvXG4gICAgLy8gc3VwcG9ydCBvbmNlKCdyZWFkYWJsZScsIGZuKSBjeWNsZXMuIFRoaXMgbWVhbnMgdGhhdCBjYWxsaW5nXG4gICAgLy8gcmVzdW1lIHdpdGhpbiB0aGUgc2FtZSB0aWNrIHdpbGwgaGF2ZSBub1xuICAgIC8vIGVmZmVjdC5cbiAgICBwcm9jZXNzLm5leHRUaWNrKHVwZGF0ZVJlYWRhYmxlTGlzdGVuaW5nLCB0aGlzKTtcbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiB1cGRhdGVSZWFkYWJsZUxpc3RlbmluZyhzZWxmKSB7XG4gIHZhciBzdGF0ZSA9IHNlbGYuX3JlYWRhYmxlU3RhdGU7XG4gIHN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nID0gc2VsZi5saXN0ZW5lckNvdW50KCdyZWFkYWJsZScpID4gMDtcblxuICBpZiAoc3RhdGUucmVzdW1lU2NoZWR1bGVkICYmICFzdGF0ZS5wYXVzZWQpIHtcbiAgICAvLyBmbG93aW5nIG5lZWRzIHRvIGJlIHNldCB0byB0cnVlIG5vdywgb3RoZXJ3aXNlXG4gICAgLy8gdGhlIHVwY29taW5nIHJlc3VtZSB3aWxsIG5vdCBmbG93LlxuICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlOyAvLyBjcnVkZSB3YXkgdG8gY2hlY2sgaWYgd2Ugc2hvdWxkIHJlc3VtZVxuICB9IGVsc2UgaWYgKHNlbGYubGlzdGVuZXJDb3VudCgnZGF0YScpID4gMCkge1xuICAgIHNlbGYucmVzdW1lKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gblJlYWRpbmdOZXh0VGljayhzZWxmKSB7XG4gIGRlYnVnKCdyZWFkYWJsZSBuZXh0dGljayByZWFkIDAnKTtcbiAgc2VsZi5yZWFkKDApO1xufSAvLyBwYXVzZSgpIGFuZCByZXN1bWUoKSBhcmUgcmVtbmFudHMgb2YgdGhlIGxlZ2FjeSByZWFkYWJsZSBzdHJlYW0gQVBJXG4vLyBJZiB0aGUgdXNlciB1c2VzIHRoZW0sIHRoZW4gc3dpdGNoIGludG8gb2xkIG1vZGUuXG5cblxuUmVhZGFibGUucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncmVzdW1lJyk7IC8vIHdlIGZsb3cgb25seSBpZiB0aGVyZSBpcyBubyBvbmUgbGlzdGVuaW5nXG4gICAgLy8gZm9yIHJlYWRhYmxlLCBidXQgd2Ugc3RpbGwgaGF2ZSB0byBjYWxsXG4gICAgLy8gcmVzdW1lKClcblxuICAgIHN0YXRlLmZsb3dpbmcgPSAhc3RhdGUucmVhZGFibGVMaXN0ZW5pbmc7XG4gICAgcmVzdW1lKHRoaXMsIHN0YXRlKTtcbiAgfVxuXG4gIHN0YXRlLnBhdXNlZCA9IGZhbHNlO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHJlc3VtZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVzdW1lU2NoZWR1bGVkKSB7XG4gICAgc3RhdGUucmVzdW1lU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICBwcm9jZXNzLm5leHRUaWNrKHJlc3VtZV8sIHN0cmVhbSwgc3RhdGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc3VtZV8oc3RyZWFtLCBzdGF0ZSkge1xuICBkZWJ1ZygncmVzdW1lJywgc3RhdGUucmVhZGluZyk7XG5cbiAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gIH1cblxuICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgc3RyZWFtLmVtaXQoJ3Jlc3VtZScpO1xuICBmbG93KHN0cmVhbSk7XG4gIGlmIChzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5yZWFkaW5nKSBzdHJlYW0ucmVhZCgwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2FsbCBwYXVzZSBmbG93aW5nPSVqJywgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKTtcblxuICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nICE9PSBmYWxzZSkge1xuICAgIGRlYnVnKCdwYXVzZScpO1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgIHRoaXMuZW1pdCgncGF1c2UnKTtcbiAgfVxuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUucGF1c2VkID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmbG93KHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGRlYnVnKCdmbG93Jywgc3RhdGUuZmxvd2luZyk7XG5cbiAgd2hpbGUgKHN0YXRlLmZsb3dpbmcgJiYgc3RyZWFtLnJlYWQoKSAhPT0gbnVsbCkge1xuICAgIDtcbiAgfVxufSAvLyB3cmFwIGFuIG9sZC1zdHlsZSBzdHJlYW0gYXMgdGhlIGFzeW5jIGRhdGEgc291cmNlLlxuLy8gVGhpcyBpcyAqbm90KiBwYXJ0IG9mIHRoZSByZWFkYWJsZSBzdHJlYW0gaW50ZXJmYWNlLlxuLy8gSXQgaXMgYW4gdWdseSB1bmZvcnR1bmF0ZSBtZXNzIG9mIGhpc3RvcnkuXG5cblxuUmVhZGFibGUucHJvdG90eXBlLndyYXAgPSBmdW5jdGlvbiAoc3RyZWFtKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHBhdXNlZCA9IGZhbHNlO1xuICBzdHJlYW0ub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBlbmQnKTtcblxuICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFzdGF0ZS5lbmRlZCkge1xuICAgICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICAgIGlmIChjaHVuayAmJiBjaHVuay5sZW5ndGgpIF90aGlzLnB1c2goY2h1bmspO1xuICAgIH1cblxuICAgIF90aGlzLnB1c2gobnVsbCk7XG4gIH0pO1xuICBzdHJlYW0ub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBkYXRhJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7IC8vIGRvbid0IHNraXAgb3ZlciBmYWxzeSB2YWx1ZXMgaW4gb2JqZWN0TW9kZVxuXG4gICAgaWYgKHN0YXRlLm9iamVjdE1vZGUgJiYgKGNodW5rID09PSBudWxsIHx8IGNodW5rID09PSB1bmRlZmluZWQpKSByZXR1cm47ZWxzZSBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgKCFjaHVuayB8fCAhY2h1bmsubGVuZ3RoKSkgcmV0dXJuO1xuXG4gICAgdmFyIHJldCA9IF90aGlzLnB1c2goY2h1bmspO1xuXG4gICAgaWYgKCFyZXQpIHtcbiAgICAgIHBhdXNlZCA9IHRydWU7XG4gICAgICBzdHJlYW0ucGF1c2UoKTtcbiAgICB9XG4gIH0pOyAvLyBwcm94eSBhbGwgdGhlIG90aGVyIG1ldGhvZHMuXG4gIC8vIGltcG9ydGFudCB3aGVuIHdyYXBwaW5nIGZpbHRlcnMgYW5kIGR1cGxleGVzLlxuXG4gIGZvciAodmFyIGkgaW4gc3RyZWFtKSB7XG4gICAgaWYgKHRoaXNbaV0gPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygc3RyZWFtW2ldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzW2ldID0gZnVuY3Rpb24gbWV0aG9kV3JhcChtZXRob2QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG1ldGhvZFdyYXBSZXR1cm5GdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gc3RyZWFtW21ldGhvZF0uYXBwbHkoc3RyZWFtLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgICAgfShpKTtcbiAgICB9XG4gIH0gLy8gcHJveHkgY2VydGFpbiBpbXBvcnRhbnQgZXZlbnRzLlxuXG5cbiAgZm9yICh2YXIgbiA9IDA7IG4gPCBrUHJveHlFdmVudHMubGVuZ3RoOyBuKyspIHtcbiAgICBzdHJlYW0ub24oa1Byb3h5RXZlbnRzW25dLCB0aGlzLmVtaXQuYmluZCh0aGlzLCBrUHJveHlFdmVudHNbbl0pKTtcbiAgfSAvLyB3aGVuIHdlIHRyeSB0byBjb25zdW1lIHNvbWUgbW9yZSBieXRlcywgc2ltcGx5IHVucGF1c2UgdGhlXG4gIC8vIHVuZGVybHlpbmcgc3RyZWFtLlxuXG5cbiAgdGhpcy5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgX3JlYWQnLCBuKTtcblxuICAgIGlmIChwYXVzZWQpIHtcbiAgICAgIHBhdXNlZCA9IGZhbHNlO1xuICAgICAgc3RyZWFtLnJlc3VtZSgpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbmlmICh0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nKSB7XG4gIFJlYWRhYmxlLnByb3RvdHlwZVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjcmVhdGVSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvYXN5bmNfaXRlcmF0b3InKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3JlYXRlUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yKHRoaXMpO1xuICB9O1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGFibGUucHJvdG90eXBlLCAncmVhZGFibGVIaWdoV2F0ZXJNYXJrJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5oaWdoV2F0ZXJNYXJrO1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZS5wcm90b3R5cGUsICdyZWFkYWJsZUJ1ZmZlcicsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUgJiYgdGhpcy5fcmVhZGFibGVTdGF0ZS5idWZmZXI7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ3JlYWRhYmxlRmxvd2luZycsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZztcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiBzZXQoc3RhdGUpIHtcbiAgICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZSkge1xuICAgICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID0gc3RhdGU7XG4gICAgfVxuICB9XG59KTsgLy8gZXhwb3NlZCBmb3IgdGVzdGluZyBwdXJwb3NlcyBvbmx5LlxuXG5SZWFkYWJsZS5fZnJvbUxpc3QgPSBmcm9tTGlzdDtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZS5wcm90b3R5cGUsICdyZWFkYWJsZUxlbmd0aCcsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUubGVuZ3RoO1xuICB9XG59KTsgLy8gUGx1Y2sgb2ZmIG4gYnl0ZXMgZnJvbSBhbiBhcnJheSBvZiBidWZmZXJzLlxuLy8gTGVuZ3RoIGlzIHRoZSBjb21iaW5lZCBsZW5ndGhzIG9mIGFsbCB0aGUgYnVmZmVycyBpbiB0aGUgbGlzdC5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuXG5mdW5jdGlvbiBmcm9tTGlzdChuLCBzdGF0ZSkge1xuICAvLyBub3RoaW5nIGJ1ZmZlcmVkXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuICB2YXIgcmV0O1xuICBpZiAoc3RhdGUub2JqZWN0TW9kZSkgcmV0ID0gc3RhdGUuYnVmZmVyLnNoaWZ0KCk7ZWxzZSBpZiAoIW4gfHwgbiA+PSBzdGF0ZS5sZW5ndGgpIHtcbiAgICAvLyByZWFkIGl0IGFsbCwgdHJ1bmNhdGUgdGhlIGxpc3RcbiAgICBpZiAoc3RhdGUuZGVjb2RlcikgcmV0ID0gc3RhdGUuYnVmZmVyLmpvaW4oJycpO2Vsc2UgaWYgKHN0YXRlLmJ1ZmZlci5sZW5ndGggPT09IDEpIHJldCA9IHN0YXRlLmJ1ZmZlci5maXJzdCgpO2Vsc2UgcmV0ID0gc3RhdGUuYnVmZmVyLmNvbmNhdChzdGF0ZS5sZW5ndGgpO1xuICAgIHN0YXRlLmJ1ZmZlci5jbGVhcigpO1xuICB9IGVsc2Uge1xuICAgIC8vIHJlYWQgcGFydCBvZiBsaXN0XG4gICAgcmV0ID0gc3RhdGUuYnVmZmVyLmNvbnN1bWUobiwgc3RhdGUuZGVjb2Rlcik7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgZGVidWcoJ2VuZFJlYWRhYmxlJywgc3RhdGUuZW5kRW1pdHRlZCk7XG5cbiAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkKSB7XG4gICAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuICAgIHByb2Nlc3MubmV4dFRpY2soZW5kUmVhZGFibGVOVCwgc3RhdGUsIHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGVOVChzdGF0ZSwgc3RyZWFtKSB7XG4gIGRlYnVnKCdlbmRSZWFkYWJsZU5UJywgc3RhdGUuZW5kRW1pdHRlZCwgc3RhdGUubGVuZ3RoKTsgLy8gQ2hlY2sgdGhhdCB3ZSBkaWRuJ3QgZ2V0IG9uZSBsYXN0IHVuc2hpZnQuXG5cbiAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmIHN0YXRlLmxlbmd0aCA9PT0gMCkge1xuICAgIHN0YXRlLmVuZEVtaXR0ZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5yZWFkYWJsZSA9IGZhbHNlO1xuICAgIHN0cmVhbS5lbWl0KCdlbmQnKTtcblxuICAgIGlmIChzdGF0ZS5hdXRvRGVzdHJveSkge1xuICAgICAgLy8gSW4gY2FzZSBvZiBkdXBsZXggc3RyZWFtcyB3ZSBuZWVkIGEgd2F5IHRvIGRldGVjdFxuICAgICAgLy8gaWYgdGhlIHdyaXRhYmxlIHNpZGUgaXMgcmVhZHkgZm9yIGF1dG9EZXN0cm95IGFzIHdlbGxcbiAgICAgIHZhciB3U3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG5cbiAgICAgIGlmICghd1N0YXRlIHx8IHdTdGF0ZS5hdXRvRGVzdHJveSAmJiB3U3RhdGUuZmluaXNoZWQpIHtcbiAgICAgICAgc3RyZWFtLmRlc3Ryb3koKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicpIHtcbiAgUmVhZGFibGUuZnJvbSA9IGZ1bmN0aW9uIChpdGVyYWJsZSwgb3B0cykge1xuICAgIGlmIChmcm9tID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGZyb20gPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvZnJvbScpO1xuICAgIH1cblxuICAgIHJldHVybiBmcm9tKFJlYWRhYmxlLCBpdGVyYWJsZSwgb3B0cyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBpZiAoeHNbaV0gPT09IHgpIHJldHVybiBpO1xuICB9XG5cbiAgcmV0dXJuIC0xO1xufSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuLy8gYSB0cmFuc2Zvcm0gc3RyZWFtIGlzIGEgcmVhZGFibGUvd3JpdGFibGUgc3RyZWFtIHdoZXJlIHlvdSBkb1xuLy8gc29tZXRoaW5nIHdpdGggdGhlIGRhdGEuICBTb21ldGltZXMgaXQncyBjYWxsZWQgYSBcImZpbHRlclwiLFxuLy8gYnV0IHRoYXQncyBub3QgYSBncmVhdCBuYW1lIGZvciBpdCwgc2luY2UgdGhhdCBpbXBsaWVzIGEgdGhpbmcgd2hlcmVcbi8vIHNvbWUgYml0cyBwYXNzIHRocm91Z2gsIGFuZCBvdGhlcnMgYXJlIHNpbXBseSBpZ25vcmVkLiAgKFRoYXQgd291bGRcbi8vIGJlIGEgdmFsaWQgZXhhbXBsZSBvZiBhIHRyYW5zZm9ybSwgb2YgY291cnNlLilcbi8vXG4vLyBXaGlsZSB0aGUgb3V0cHV0IGlzIGNhdXNhbGx5IHJlbGF0ZWQgdG8gdGhlIGlucHV0LCBpdCdzIG5vdCBhXG4vLyBuZWNlc3NhcmlseSBzeW1tZXRyaWMgb3Igc3luY2hyb25vdXMgdHJhbnNmb3JtYXRpb24uICBGb3IgZXhhbXBsZSxcbi8vIGEgemxpYiBzdHJlYW0gbWlnaHQgdGFrZSBtdWx0aXBsZSBwbGFpbi10ZXh0IHdyaXRlcygpLCBhbmQgdGhlblxuLy8gZW1pdCBhIHNpbmdsZSBjb21wcmVzc2VkIGNodW5rIHNvbWUgdGltZSBpbiB0aGUgZnV0dXJlLlxuLy9cbi8vIEhlcmUncyBob3cgdGhpcyB3b3Jrczpcbi8vXG4vLyBUaGUgVHJhbnNmb3JtIHN0cmVhbSBoYXMgYWxsIHRoZSBhc3BlY3RzIG9mIHRoZSByZWFkYWJsZSBhbmQgd3JpdGFibGVcbi8vIHN0cmVhbSBjbGFzc2VzLiAgV2hlbiB5b3Ugd3JpdGUoY2h1bmspLCB0aGF0IGNhbGxzIF93cml0ZShjaHVuayxjYilcbi8vIGludGVybmFsbHksIGFuZCByZXR1cm5zIGZhbHNlIGlmIHRoZXJlJ3MgYSBsb3Qgb2YgcGVuZGluZyB3cml0ZXNcbi8vIGJ1ZmZlcmVkIHVwLiAgV2hlbiB5b3UgY2FsbCByZWFkKCksIHRoYXQgY2FsbHMgX3JlYWQobikgdW50aWxcbi8vIHRoZXJlJ3MgZW5vdWdoIHBlbmRpbmcgcmVhZGFibGUgZGF0YSBidWZmZXJlZCB1cC5cbi8vXG4vLyBJbiBhIHRyYW5zZm9ybSBzdHJlYW0sIHRoZSB3cml0dGVuIGRhdGEgaXMgcGxhY2VkIGluIGEgYnVmZmVyLiAgV2hlblxuLy8gX3JlYWQobikgaXMgY2FsbGVkLCBpdCB0cmFuc2Zvcm1zIHRoZSBxdWV1ZWQgdXAgZGF0YSwgY2FsbGluZyB0aGVcbi8vIGJ1ZmZlcmVkIF93cml0ZSBjYidzIGFzIGl0IGNvbnN1bWVzIGNodW5rcy4gIElmIGNvbnN1bWluZyBhIHNpbmdsZVxuLy8gd3JpdHRlbiBjaHVuayB3b3VsZCByZXN1bHQgaW4gbXVsdGlwbGUgb3V0cHV0IGNodW5rcywgdGhlbiB0aGUgZmlyc3Rcbi8vIG91dHB1dHRlZCBiaXQgY2FsbHMgdGhlIHJlYWRjYiwgYW5kIHN1YnNlcXVlbnQgY2h1bmtzIGp1c3QgZ28gaW50b1xuLy8gdGhlIHJlYWQgYnVmZmVyLCBhbmQgd2lsbCBjYXVzZSBpdCB0byBlbWl0ICdyZWFkYWJsZScgaWYgbmVjZXNzYXJ5LlxuLy9cbi8vIFRoaXMgd2F5LCBiYWNrLXByZXNzdXJlIGlzIGFjdHVhbGx5IGRldGVybWluZWQgYnkgdGhlIHJlYWRpbmcgc2lkZSxcbi8vIHNpbmNlIF9yZWFkIGhhcyB0byBiZSBjYWxsZWQgdG8gc3RhcnQgcHJvY2Vzc2luZyBhIG5ldyBjaHVuay4gIEhvd2V2ZXIsXG4vLyBhIHBhdGhvbG9naWNhbCBpbmZsYXRlIHR5cGUgb2YgdHJhbnNmb3JtIGNhbiBjYXVzZSBleGNlc3NpdmUgYnVmZmVyaW5nXG4vLyBoZXJlLiAgRm9yIGV4YW1wbGUsIGltYWdpbmUgYSBzdHJlYW0gd2hlcmUgZXZlcnkgYnl0ZSBvZiBpbnB1dCBpc1xuLy8gaW50ZXJwcmV0ZWQgYXMgYW4gaW50ZWdlciBmcm9tIDAtMjU1LCBhbmQgdGhlbiByZXN1bHRzIGluIHRoYXQgbWFueVxuLy8gYnl0ZXMgb2Ygb3V0cHV0LiAgV3JpdGluZyB0aGUgNCBieXRlcyB7ZmYsZmYsZmYsZmZ9IHdvdWxkIHJlc3VsdCBpblxuLy8gMWtiIG9mIGRhdGEgYmVpbmcgb3V0cHV0LiAgSW4gdGhpcyBjYXNlLCB5b3UgY291bGQgd3JpdGUgYSB2ZXJ5IHNtYWxsXG4vLyBhbW91bnQgb2YgaW5wdXQsIGFuZCBlbmQgdXAgd2l0aCBhIHZlcnkgbGFyZ2UgYW1vdW50IG9mIG91dHB1dC4gIEluXG4vLyBzdWNoIGEgcGF0aG9sb2dpY2FsIGluZmxhdGluZyBtZWNoYW5pc20sIHRoZXJlJ2QgYmUgbm8gd2F5IHRvIHRlbGxcbi8vIHRoZSBzeXN0ZW0gdG8gc3RvcCBkb2luZyB0aGUgdHJhbnNmb3JtLiAgQSBzaW5nbGUgNE1CIHdyaXRlIGNvdWxkXG4vLyBjYXVzZSB0aGUgc3lzdGVtIHRvIHJ1biBvdXQgb2YgbWVtb3J5LlxuLy9cbi8vIEhvd2V2ZXIsIGV2ZW4gaW4gc3VjaCBhIHBhdGhvbG9naWNhbCBjYXNlLCBvbmx5IGEgc2luZ2xlIHdyaXR0ZW4gY2h1bmtcbi8vIHdvdWxkIGJlIGNvbnN1bWVkLCBhbmQgdGhlbiB0aGUgcmVzdCB3b3VsZCB3YWl0ICh1bi10cmFuc2Zvcm1lZCkgdW50aWxcbi8vIHRoZSByZXN1bHRzIG9mIHRoZSBwcmV2aW91cyB0cmFuc2Zvcm1lZCBjaHVuayB3ZXJlIGNvbnN1bWVkLlxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zZm9ybTtcblxudmFyIF9yZXF1aXJlJGNvZGVzID0gcmVxdWlyZSgnLi4vZXJyb3JzJykuY29kZXMsXG4gICAgRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfTUVUSE9EX05PVF9JTVBMRU1FTlRFRCxcbiAgICBFUlJfTVVMVElQTEVfQ0FMTEJBQ0sgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfTVVMVElQTEVfQ0FMTEJBQ0ssXG4gICAgRVJSX1RSQU5TRk9STV9BTFJFQURZX1RSQU5TRk9STUlORyA9IF9yZXF1aXJlJGNvZGVzLkVSUl9UUkFOU0ZPUk1fQUxSRUFEWV9UUkFOU0ZPUk1JTkcsXG4gICAgRVJSX1RSQU5TRk9STV9XSVRIX0xFTkdUSF8wID0gX3JlcXVpcmUkY29kZXMuRVJSX1RSQU5TRk9STV9XSVRIX0xFTkdUSF8wO1xuXG52YXIgRHVwbGV4ID0gcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG5yZXF1aXJlKCdpbmhlcml0cycpKFRyYW5zZm9ybSwgRHVwbGV4KTtcblxuZnVuY3Rpb24gYWZ0ZXJUcmFuc2Zvcm0oZXIsIGRhdGEpIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG4gIHRzLnRyYW5zZm9ybWluZyA9IGZhbHNlO1xuICB2YXIgY2IgPSB0cy53cml0ZWNiO1xuXG4gIGlmIChjYiA9PT0gbnVsbCkge1xuICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVSUl9NVUxUSVBMRV9DQUxMQkFDSygpKTtcbiAgfVxuXG4gIHRzLndyaXRlY2h1bmsgPSBudWxsO1xuICB0cy53cml0ZWNiID0gbnVsbDtcbiAgaWYgKGRhdGEgIT0gbnVsbCkgLy8gc2luZ2xlIGVxdWFscyBjaGVjayBmb3IgYm90aCBgbnVsbGAgYW5kIGB1bmRlZmluZWRgXG4gICAgdGhpcy5wdXNoKGRhdGEpO1xuICBjYihlcik7XG4gIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHJzLnJlYWRpbmcgPSBmYWxzZTtcblxuICBpZiAocnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHtcbiAgICB0aGlzLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspO1xuICB9XG59XG5cbmZ1bmN0aW9uIFRyYW5zZm9ybShvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBUcmFuc2Zvcm0pKSByZXR1cm4gbmV3IFRyYW5zZm9ybShvcHRpb25zKTtcbiAgRHVwbGV4LmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlID0ge1xuICAgIGFmdGVyVHJhbnNmb3JtOiBhZnRlclRyYW5zZm9ybS5iaW5kKHRoaXMpLFxuICAgIG5lZWRUcmFuc2Zvcm06IGZhbHNlLFxuICAgIHRyYW5zZm9ybWluZzogZmFsc2UsXG4gICAgd3JpdGVjYjogbnVsbCxcbiAgICB3cml0ZWNodW5rOiBudWxsLFxuICAgIHdyaXRlZW5jb2Rpbmc6IG51bGxcbiAgfTsgLy8gc3RhcnQgb3V0IGFza2luZyBmb3IgYSByZWFkYWJsZSBldmVudCBvbmNlIGRhdGEgaXMgdHJhbnNmb3JtZWQuXG5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlOyAvLyB3ZSBoYXZlIGltcGxlbWVudGVkIHRoZSBfcmVhZCBtZXRob2QsIGFuZCBkb25lIHRoZSBvdGhlciB0aGluZ3NcbiAgLy8gdGhhdCBSZWFkYWJsZSB3YW50cyBiZWZvcmUgdGhlIGZpcnN0IF9yZWFkIGNhbGwsIHNvIHVuc2V0IHRoZVxuICAvLyBzeW5jIGd1YXJkIGZsYWcuXG5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5zeW5jID0gZmFsc2U7XG5cbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMudHJhbnNmb3JtID09PSAnZnVuY3Rpb24nKSB0aGlzLl90cmFuc2Zvcm0gPSBvcHRpb25zLnRyYW5zZm9ybTtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZmx1c2ggPT09ICdmdW5jdGlvbicpIHRoaXMuX2ZsdXNoID0gb3B0aW9ucy5mbHVzaDtcbiAgfSAvLyBXaGVuIHRoZSB3cml0YWJsZSBzaWRlIGZpbmlzaGVzLCB0aGVuIGZsdXNoIG91dCBhbnl0aGluZyByZW1haW5pbmcuXG5cblxuICB0aGlzLm9uKCdwcmVmaW5pc2gnLCBwcmVmaW5pc2gpO1xufVxuXG5mdW5jdGlvbiBwcmVmaW5pc2goKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgaWYgKHR5cGVvZiB0aGlzLl9mbHVzaCA9PT0gJ2Z1bmN0aW9uJyAmJiAhdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQpIHtcbiAgICB0aGlzLl9mbHVzaChmdW5jdGlvbiAoZXIsIGRhdGEpIHtcbiAgICAgIGRvbmUoX3RoaXMsIGVyLCBkYXRhKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBkb25lKHRoaXMsIG51bGwsIG51bGwpO1xuICB9XG59XG5cblRyYW5zZm9ybS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcpIHtcbiAgdGhpcy5fdHJhbnNmb3JtU3RhdGUubmVlZFRyYW5zZm9ybSA9IGZhbHNlO1xuICByZXR1cm4gRHVwbGV4LnByb3RvdHlwZS5wdXNoLmNhbGwodGhpcywgY2h1bmssIGVuY29kaW5nKTtcbn07IC8vIFRoaXMgaXMgdGhlIHBhcnQgd2hlcmUgeW91IGRvIHN0dWZmIVxuLy8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBpbiBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLlxuLy8gJ2NodW5rJyBpcyBhbiBpbnB1dCBjaHVuay5cbi8vXG4vLyBDYWxsIGBwdXNoKG5ld0NodW5rKWAgdG8gcGFzcyBhbG9uZyB0cmFuc2Zvcm1lZCBvdXRwdXRcbi8vIHRvIHRoZSByZWFkYWJsZSBzaWRlLiAgWW91IG1heSBjYWxsICdwdXNoJyB6ZXJvIG9yIG1vcmUgdGltZXMuXG4vL1xuLy8gQ2FsbCBgY2IoZXJyKWAgd2hlbiB5b3UgYXJlIGRvbmUgd2l0aCB0aGlzIGNodW5rLiAgSWYgeW91IHBhc3Ncbi8vIGFuIGVycm9yLCB0aGVuIHRoYXQnbGwgcHV0IHRoZSBodXJ0IG9uIHRoZSB3aG9sZSBvcGVyYXRpb24uICBJZiB5b3Vcbi8vIG5ldmVyIGNhbGwgY2IoKSwgdGhlbiB5b3UnbGwgbmV2ZXIgZ2V0IGFub3RoZXIgY2h1bmsuXG5cblxuVHJhbnNmb3JtLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobmV3IEVSUl9NRVRIT0RfTk9UX0lNUExFTUVOVEVEKCdfdHJhbnNmb3JtKCknKSk7XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICB0cy53cml0ZWNiID0gY2I7XG4gIHRzLndyaXRlY2h1bmsgPSBjaHVuaztcbiAgdHMud3JpdGVlbmNvZGluZyA9IGVuY29kaW5nO1xuXG4gIGlmICghdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdmFyIHJzID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgICBpZiAodHMubmVlZFRyYW5zZm9ybSB8fCBycy5uZWVkUmVhZGFibGUgfHwgcnMubGVuZ3RoIDwgcnMuaGlnaFdhdGVyTWFyaykgdGhpcy5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufTsgLy8gRG9lc24ndCBtYXR0ZXIgd2hhdCB0aGUgYXJncyBhcmUgaGVyZS5cbi8vIF90cmFuc2Zvcm0gZG9lcyBhbGwgdGhlIHdvcmsuXG4vLyBUaGF0IHdlIGdvdCBoZXJlIG1lYW5zIHRoYXQgdGhlIHJlYWRhYmxlIHNpZGUgd2FudHMgbW9yZSBkYXRhLlxuXG5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAodHMud3JpdGVjaHVuayAhPT0gbnVsbCAmJiAhdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdHMudHJhbnNmb3JtaW5nID0gdHJ1ZTtcblxuICAgIHRoaXMuX3RyYW5zZm9ybSh0cy53cml0ZWNodW5rLCB0cy53cml0ZWVuY29kaW5nLCB0cy5hZnRlclRyYW5zZm9ybSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbWFyayB0aGF0IHdlIG5lZWQgYSB0cmFuc2Zvcm0sIHNvIHRoYXQgYW55IGRhdGEgdGhhdCBjb21lcyBpblxuICAgIC8vIHdpbGwgZ2V0IHByb2Nlc3NlZCwgbm93IHRoYXQgd2UndmUgYXNrZWQgZm9yIGl0LlxuICAgIHRzLm5lZWRUcmFuc2Zvcm0gPSB0cnVlO1xuICB9XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gKGVyciwgY2IpIHtcbiAgRHVwbGV4LnByb3RvdHlwZS5fZGVzdHJveS5jYWxsKHRoaXMsIGVyciwgZnVuY3Rpb24gKGVycjIpIHtcbiAgICBjYihlcnIyKTtcbiAgfSk7XG59O1xuXG5mdW5jdGlvbiBkb25lKHN0cmVhbSwgZXIsIGRhdGEpIHtcbiAgaWYgKGVyKSByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICBpZiAoZGF0YSAhPSBudWxsKSAvLyBzaW5nbGUgZXF1YWxzIGNoZWNrIGZvciBib3RoIGBudWxsYCBhbmQgYHVuZGVmaW5lZGBcbiAgICBzdHJlYW0ucHVzaChkYXRhKTsgLy8gVE9ETyhCcmlkZ2VBUik6IFdyaXRlIGEgdGVzdCBmb3IgdGhlc2UgdHdvIGVycm9yIGNhc2VzXG4gIC8vIGlmIHRoZXJlJ3Mgbm90aGluZyBpbiB0aGUgd3JpdGUgYnVmZmVyLCB0aGVuIHRoYXQgbWVhbnNcbiAgLy8gdGhhdCBub3RoaW5nIG1vcmUgd2lsbCBldmVyIGJlIHByb3ZpZGVkXG5cbiAgaWYgKHN0cmVhbS5fd3JpdGFibGVTdGF0ZS5sZW5ndGgpIHRocm93IG5ldyBFUlJfVFJBTlNGT1JNX1dJVEhfTEVOR1RIXzAoKTtcbiAgaWYgKHN0cmVhbS5fdHJhbnNmb3JtU3RhdGUudHJhbnNmb3JtaW5nKSB0aHJvdyBuZXcgRVJSX1RSQU5TRk9STV9BTFJFQURZX1RSQU5TRk9STUlORygpO1xuICByZXR1cm4gc3RyZWFtLnB1c2gobnVsbCk7XG59IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG4vLyBBIGJpdCBzaW1wbGVyIHRoYW4gcmVhZGFibGUgc3RyZWFtcy5cbi8vIEltcGxlbWVudCBhbiBhc3luYyAuX3dyaXRlKGNodW5rLCBlbmNvZGluZywgY2IpLCBhbmQgaXQnbGwgaGFuZGxlIGFsbFxuLy8gdGhlIGRyYWluIGV2ZW50IGVtaXNzaW9uIGFuZCBidWZmZXJpbmcuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gV3JpdGFibGU7XG4vKiA8cmVwbGFjZW1lbnQ+ICovXG5cbmZ1bmN0aW9uIFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhpcy5jaHVuayA9IGNodW5rO1xuICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHRoaXMuY2FsbGJhY2sgPSBjYjtcbiAgdGhpcy5uZXh0ID0gbnVsbDtcbn0gLy8gSXQgc2VlbXMgYSBsaW5rZWQgbGlzdCBidXQgaXQgaXMgbm90XG4vLyB0aGVyZSB3aWxsIGJlIG9ubHkgMiBvZiB0aGVzZSBmb3IgZWFjaCBzdHJlYW1cblxuXG5mdW5jdGlvbiBDb3JrZWRSZXF1ZXN0KHN0YXRlKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgdGhpcy5uZXh0ID0gbnVsbDtcbiAgdGhpcy5lbnRyeSA9IG51bGw7XG5cbiAgdGhpcy5maW5pc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgb25Db3JrZWRGaW5pc2goX3RoaXMsIHN0YXRlKTtcbiAgfTtcbn1cbi8qIDwvcmVwbGFjZW1lbnQ+ICovXG5cbi8qPHJlcGxhY2VtZW50PiovXG5cblxudmFyIER1cGxleDtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5Xcml0YWJsZS5Xcml0YWJsZVN0YXRlID0gV3JpdGFibGVTdGF0ZTtcbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBpbnRlcm5hbFV0aWwgPSB7XG4gIGRlcHJlY2F0ZTogcmVxdWlyZSgndXRpbC1kZXByZWNhdGUnKVxufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xuXG52YXIgU3RyZWFtID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL3N0cmVhbScpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxudmFyIE91clVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheSB8fCBmdW5jdGlvbiAoKSB7fTtcblxuZnVuY3Rpb24gX3VpbnQ4QXJyYXlUb0J1ZmZlcihjaHVuaykge1xuICByZXR1cm4gQnVmZmVyLmZyb20oY2h1bmspO1xufVxuXG5mdW5jdGlvbiBfaXNVaW50OEFycmF5KG9iaikge1xuICByZXR1cm4gQnVmZmVyLmlzQnVmZmVyKG9iaikgfHwgb2JqIGluc3RhbmNlb2YgT3VyVWludDhBcnJheTtcbn1cblxudmFyIGRlc3Ryb3lJbXBsID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL2Rlc3Ryb3knKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL3N0YXRlJyksXG4gICAgZ2V0SGlnaFdhdGVyTWFyayA9IF9yZXF1aXJlLmdldEhpZ2hXYXRlck1hcms7XG5cbnZhciBfcmVxdWlyZSRjb2RlcyA9IHJlcXVpcmUoJy4uL2Vycm9ycycpLmNvZGVzLFxuICAgIEVSUl9JTlZBTElEX0FSR19UWVBFID0gX3JlcXVpcmUkY29kZXMuRVJSX0lOVkFMSURfQVJHX1RZUEUsXG4gICAgRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfTUVUSE9EX05PVF9JTVBMRU1FTlRFRCxcbiAgICBFUlJfTVVMVElQTEVfQ0FMTEJBQ0sgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfTVVMVElQTEVfQ0FMTEJBQ0ssXG4gICAgRVJSX1NUUkVBTV9DQU5OT1RfUElQRSA9IF9yZXF1aXJlJGNvZGVzLkVSUl9TVFJFQU1fQ0FOTk9UX1BJUEUsXG4gICAgRVJSX1NUUkVBTV9ERVNUUk9ZRUQgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfU1RSRUFNX0RFU1RST1lFRCxcbiAgICBFUlJfU1RSRUFNX05VTExfVkFMVUVTID0gX3JlcXVpcmUkY29kZXMuRVJSX1NUUkVBTV9OVUxMX1ZBTFVFUyxcbiAgICBFUlJfU1RSRUFNX1dSSVRFX0FGVEVSX0VORCA9IF9yZXF1aXJlJGNvZGVzLkVSUl9TVFJFQU1fV1JJVEVfQUZURVJfRU5ELFxuICAgIEVSUl9VTktOT1dOX0VOQ09ESU5HID0gX3JlcXVpcmUkY29kZXMuRVJSX1VOS05PV05fRU5DT0RJTkc7XG5cbnZhciBlcnJvck9yRGVzdHJveSA9IGRlc3Ryb3lJbXBsLmVycm9yT3JEZXN0cm95O1xuXG5yZXF1aXJlKCdpbmhlcml0cycpKFdyaXRhYmxlLCBTdHJlYW0pO1xuXG5mdW5jdGlvbiBub3AoKSB7fVxuXG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSwgaXNEdXBsZXgpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307IC8vIER1cGxleCBzdHJlYW1zIGFyZSBib3RoIHJlYWRhYmxlIGFuZCB3cml0YWJsZSwgYnV0IHNoYXJlXG4gIC8vIHRoZSBzYW1lIG9wdGlvbnMgb2JqZWN0LlxuICAvLyBIb3dldmVyLCBzb21lIGNhc2VzIHJlcXVpcmUgc2V0dGluZyBvcHRpb25zIHRvIGRpZmZlcmVudFxuICAvLyB2YWx1ZXMgZm9yIHRoZSByZWFkYWJsZSBhbmQgdGhlIHdyaXRhYmxlIHNpZGVzIG9mIHRoZSBkdXBsZXggc3RyZWFtLFxuICAvLyBlLmcuIG9wdGlvbnMucmVhZGFibGVPYmplY3RNb2RlIHZzLiBvcHRpb25zLndyaXRhYmxlT2JqZWN0TW9kZSwgZXRjLlxuXG4gIGlmICh0eXBlb2YgaXNEdXBsZXggIT09ICdib29sZWFuJykgaXNEdXBsZXggPSBzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXg7IC8vIG9iamVjdCBzdHJlYW0gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGlzIHN0cmVhbVxuICAvLyBjb250YWlucyBidWZmZXJzIG9yIG9iamVjdHMuXG5cbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG4gIGlmIChpc0R1cGxleCkgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy53cml0YWJsZU9iamVjdE1vZGU7IC8vIHRoZSBwb2ludCBhdCB3aGljaCB3cml0ZSgpIHN0YXJ0cyByZXR1cm5pbmcgZmFsc2VcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyB0aGF0IHdlIGFsd2F5cyByZXR1cm4gZmFsc2UgaWZcbiAgLy8gdGhlIGVudGlyZSBidWZmZXIgaXMgbm90IGZsdXNoZWQgaW1tZWRpYXRlbHkgb24gd3JpdGUoKVxuXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IGdldEhpZ2hXYXRlck1hcmsodGhpcywgb3B0aW9ucywgJ3dyaXRhYmxlSGlnaFdhdGVyTWFyaycsIGlzRHVwbGV4KTsgLy8gaWYgX2ZpbmFsIGhhcyBiZWVuIGNhbGxlZFxuXG4gIHRoaXMuZmluYWxDYWxsZWQgPSBmYWxzZTsgLy8gZHJhaW4gZXZlbnQgZmxhZy5cblxuICB0aGlzLm5lZWREcmFpbiA9IGZhbHNlOyAvLyBhdCB0aGUgc3RhcnQgb2YgY2FsbGluZyBlbmQoKVxuXG4gIHRoaXMuZW5kaW5nID0gZmFsc2U7IC8vIHdoZW4gZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgcmV0dXJuZWRcblxuICB0aGlzLmVuZGVkID0gZmFsc2U7IC8vIHdoZW4gJ2ZpbmlzaCcgaXMgZW1pdHRlZFxuXG4gIHRoaXMuZmluaXNoZWQgPSBmYWxzZTsgLy8gaGFzIGl0IGJlZW4gZGVzdHJveWVkXG5cbiAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTsgLy8gc2hvdWxkIHdlIGRlY29kZSBzdHJpbmdzIGludG8gYnVmZmVycyBiZWZvcmUgcGFzc2luZyB0byBfd3JpdGU/XG4gIC8vIHRoaXMgaXMgaGVyZSBzbyB0aGF0IHNvbWUgbm9kZS1jb3JlIHN0cmVhbXMgY2FuIG9wdGltaXplIHN0cmluZ1xuICAvLyBoYW5kbGluZyBhdCBhIGxvd2VyIGxldmVsLlxuXG4gIHZhciBub0RlY29kZSA9IG9wdGlvbnMuZGVjb2RlU3RyaW5ncyA9PT0gZmFsc2U7XG4gIHRoaXMuZGVjb2RlU3RyaW5ncyA9ICFub0RlY29kZTsgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cblxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JzsgLy8gbm90IGFuIGFjdHVhbCBidWZmZXIgd2Uga2VlcCB0cmFjayBvZiwgYnV0IGEgbWVhc3VyZW1lbnRcbiAgLy8gb2YgaG93IG11Y2ggd2UncmUgd2FpdGluZyB0byBnZXQgcHVzaGVkIHRvIHNvbWUgdW5kZXJseWluZ1xuICAvLyBzb2NrZXQgb3IgZmlsZS5cblxuICB0aGlzLmxlbmd0aCA9IDA7IC8vIGEgZmxhZyB0byBzZWUgd2hlbiB3ZSdyZSBpbiB0aGUgbWlkZGxlIG9mIGEgd3JpdGUuXG5cbiAgdGhpcy53cml0aW5nID0gZmFsc2U7IC8vIHdoZW4gdHJ1ZSBhbGwgd3JpdGVzIHdpbGwgYmUgYnVmZmVyZWQgdW50aWwgLnVuY29yaygpIGNhbGxcblxuICB0aGlzLmNvcmtlZCA9IDA7IC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIG9ud3JpdGUgY2IgaXMgY2FsbGVkIGltbWVkaWF0ZWx5LFxuICAvLyBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWNhdXNlIGFueVxuICAvLyBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBjYWxsLlxuXG4gIHRoaXMuc3luYyA9IHRydWU7IC8vIGEgZmxhZyB0byBrbm93IGlmIHdlJ3JlIHByb2Nlc3NpbmcgcHJldmlvdXNseSBidWZmZXJlZCBpdGVtcywgd2hpY2hcbiAgLy8gbWF5IGNhbGwgdGhlIF93cml0ZSgpIGNhbGxiYWNrIGluIHRoZSBzYW1lIHRpY2ssIHNvIHRoYXQgd2UgZG9uJ3RcbiAgLy8gZW5kIHVwIGluIGFuIG92ZXJsYXBwZWQgb253cml0ZSBzaXR1YXRpb24uXG5cbiAgdGhpcy5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7IC8vIHRoZSBjYWxsYmFjayB0aGF0J3MgcGFzc2VkIHRvIF93cml0ZShjaHVuayxjYilcblxuICB0aGlzLm9ud3JpdGUgPSBmdW5jdGlvbiAoZXIpIHtcbiAgICBvbndyaXRlKHN0cmVhbSwgZXIpO1xuICB9OyAvLyB0aGUgY2FsbGJhY2sgdGhhdCB0aGUgdXNlciBzdXBwbGllcyB0byB3cml0ZShjaHVuayxlbmNvZGluZyxjYilcblxuXG4gIHRoaXMud3JpdGVjYiA9IG51bGw7IC8vIHRoZSBhbW91bnQgdGhhdCBpcyBiZWluZyB3cml0dGVuIHdoZW4gX3dyaXRlIGlzIGNhbGxlZC5cblxuICB0aGlzLndyaXRlbGVuID0gMDtcbiAgdGhpcy5idWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICB0aGlzLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsOyAvLyBudW1iZXIgb2YgcGVuZGluZyB1c2VyLXN1cHBsaWVkIHdyaXRlIGNhbGxiYWNrc1xuICAvLyB0aGlzIG11c3QgYmUgMCBiZWZvcmUgJ2ZpbmlzaCcgY2FuIGJlIGVtaXR0ZWRcblxuICB0aGlzLnBlbmRpbmdjYiA9IDA7IC8vIGVtaXQgcHJlZmluaXNoIGlmIHRoZSBvbmx5IHRoaW5nIHdlJ3JlIHdhaXRpbmcgZm9yIGlzIF93cml0ZSBjYnNcbiAgLy8gVGhpcyBpcyByZWxldmFudCBmb3Igc3luY2hyb25vdXMgVHJhbnNmb3JtIHN0cmVhbXNcblxuICB0aGlzLnByZWZpbmlzaGVkID0gZmFsc2U7IC8vIFRydWUgaWYgdGhlIGVycm9yIHdhcyBhbHJlYWR5IGVtaXR0ZWQgYW5kIHNob3VsZCBub3QgYmUgdGhyb3duIGFnYWluXG5cbiAgdGhpcy5lcnJvckVtaXR0ZWQgPSBmYWxzZTsgLy8gU2hvdWxkIGNsb3NlIGJlIGVtaXR0ZWQgb24gZGVzdHJveS4gRGVmYXVsdHMgdG8gdHJ1ZS5cblxuICB0aGlzLmVtaXRDbG9zZSA9IG9wdGlvbnMuZW1pdENsb3NlICE9PSBmYWxzZTsgLy8gU2hvdWxkIC5kZXN0cm95KCkgYmUgY2FsbGVkIGFmdGVyICdmaW5pc2gnIChhbmQgcG90ZW50aWFsbHkgJ2VuZCcpXG5cbiAgdGhpcy5hdXRvRGVzdHJveSA9ICEhb3B0aW9ucy5hdXRvRGVzdHJveTsgLy8gY291bnQgYnVmZmVyZWQgcmVxdWVzdHNcblxuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdENvdW50ID0gMDsgLy8gYWxsb2NhdGUgdGhlIGZpcnN0IENvcmtlZFJlcXVlc3QsIHRoZXJlIGlzIGFsd2F5c1xuICAvLyBvbmUgYWxsb2NhdGVkIGFuZCBmcmVlIHRvIHVzZSwgYW5kIHdlIG1haW50YWluIGF0IG1vc3QgdHdvXG5cbiAgdGhpcy5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBuZXcgQ29ya2VkUmVxdWVzdCh0aGlzKTtcbn1cblxuV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUuZ2V0QnVmZmVyID0gZnVuY3Rpb24gZ2V0QnVmZmVyKCkge1xuICB2YXIgY3VycmVudCA9IHRoaXMuYnVmZmVyZWRSZXF1ZXN0O1xuICB2YXIgb3V0ID0gW107XG5cbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBvdXQucHVzaChjdXJyZW50KTtcbiAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbihmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlU3RhdGUucHJvdG90eXBlLCAnYnVmZmVyJywge1xuICAgICAgZ2V0OiBpbnRlcm5hbFV0aWwuZGVwcmVjYXRlKGZ1bmN0aW9uIHdyaXRhYmxlU3RhdGVCdWZmZXJHZXR0ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJ1ZmZlcigpO1xuICAgICAgfSwgJ193cml0YWJsZVN0YXRlLmJ1ZmZlciBpcyBkZXByZWNhdGVkLiBVc2UgX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyICcgKyAnaW5zdGVhZC4nLCAnREVQMDAwMycpXG4gICAgfSk7XG4gIH0gY2F0Y2ggKF8pIHt9XG59KSgpOyAvLyBUZXN0IF93cml0YWJsZVN0YXRlIGZvciBpbmhlcml0YW5jZSB0byBhY2NvdW50IGZvciBEdXBsZXggc3RyZWFtcyxcbi8vIHdob3NlIHByb3RvdHlwZSBjaGFpbiBvbmx5IHBvaW50cyB0byBSZWFkYWJsZS5cblxuXG52YXIgcmVhbEhhc0luc3RhbmNlO1xuXG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wuaGFzSW5zdGFuY2UgJiYgdHlwZW9mIEZ1bmN0aW9uLnByb3RvdHlwZVtTeW1ib2wuaGFzSW5zdGFuY2VdID09PSAnZnVuY3Rpb24nKSB7XG4gIHJlYWxIYXNJbnN0YW5jZSA9IEZ1bmN0aW9uLnByb3RvdHlwZVtTeW1ib2wuaGFzSW5zdGFuY2VdO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUsIFN5bWJvbC5oYXNJbnN0YW5jZSwge1xuICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZShvYmplY3QpIHtcbiAgICAgIGlmIChyZWFsSGFzSW5zdGFuY2UuY2FsbCh0aGlzLCBvYmplY3QpKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGlmICh0aGlzICE9PSBXcml0YWJsZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIG9iamVjdCAmJiBvYmplY3QuX3dyaXRhYmxlU3RhdGUgaW5zdGFuY2VvZiBXcml0YWJsZVN0YXRlO1xuICAgIH1cbiAgfSk7XG59IGVsc2Uge1xuICByZWFsSGFzSW5zdGFuY2UgPSBmdW5jdGlvbiByZWFsSGFzSW5zdGFuY2Uob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIHRoaXM7XG4gIH07XG59XG5cbmZ1bmN0aW9uIFdyaXRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTsgLy8gV3JpdGFibGUgY3RvciBpcyBhcHBsaWVkIHRvIER1cGxleGVzLCB0b28uXG4gIC8vIGByZWFsSGFzSW5zdGFuY2VgIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHVzaW5nIHBsYWluIGBpbnN0YW5jZW9mYFxuICAvLyB3b3VsZCByZXR1cm4gZmFsc2UsIGFzIG5vIGBfd3JpdGFibGVTdGF0ZWAgcHJvcGVydHkgaXMgYXR0YWNoZWQuXG4gIC8vIFRyeWluZyB0byB1c2UgdGhlIGN1c3RvbSBgaW5zdGFuY2VvZmAgZm9yIFdyaXRhYmxlIGhlcmUgd2lsbCBhbHNvIGJyZWFrIHRoZVxuICAvLyBOb2RlLmpzIExhenlUcmFuc2Zvcm0gaW1wbGVtZW50YXRpb24sIHdoaWNoIGhhcyBhIG5vbi10cml2aWFsIGdldHRlciBmb3JcbiAgLy8gYF93cml0YWJsZVN0YXRlYCB0aGF0IHdvdWxkIGxlYWQgdG8gaW5maW5pdGUgcmVjdXJzaW9uLlxuICAvLyBDaGVja2luZyBmb3IgYSBTdHJlYW0uRHVwbGV4IGluc3RhbmNlIGlzIGZhc3RlciBoZXJlIGluc3RlYWQgb2YgaW5zaWRlXG4gIC8vIHRoZSBXcml0YWJsZVN0YXRlIGNvbnN0cnVjdG9yLCBhdCBsZWFzdCB3aXRoIFY4IDYuNVxuXG4gIHZhciBpc0R1cGxleCA9IHRoaXMgaW5zdGFuY2VvZiBEdXBsZXg7XG4gIGlmICghaXNEdXBsZXggJiYgIXJlYWxIYXNJbnN0YW5jZS5jYWxsKFdyaXRhYmxlLCB0aGlzKSkgcmV0dXJuIG5ldyBXcml0YWJsZShvcHRpb25zKTtcbiAgdGhpcy5fd3JpdGFibGVTdGF0ZSA9IG5ldyBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMsIGlzRHVwbGV4KTsgLy8gbGVnYWN5LlxuXG4gIHRoaXMud3JpdGFibGUgPSB0cnVlO1xuXG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRlID09PSAnZnVuY3Rpb24nKSB0aGlzLl93cml0ZSA9IG9wdGlvbnMud3JpdGU7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRldiA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGV2ID0gb3B0aW9ucy53cml0ZXY7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIHRoaXMuX2Rlc3Ryb3kgPSBvcHRpb25zLmRlc3Ryb3k7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmZpbmFsID09PSAnZnVuY3Rpb24nKSB0aGlzLl9maW5hbCA9IG9wdGlvbnMuZmluYWw7XG4gIH1cblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn0gLy8gT3RoZXJ3aXNlIHBlb3BsZSBjYW4gcGlwZSBXcml0YWJsZSBzdHJlYW1zLCB3aGljaCBpcyBqdXN0IHdyb25nLlxuXG5cbldyaXRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKCkge1xuICBlcnJvck9yRGVzdHJveSh0aGlzLCBuZXcgRVJSX1NUUkVBTV9DQU5OT1RfUElQRSgpKTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLCBjYikge1xuICB2YXIgZXIgPSBuZXcgRVJSX1NUUkVBTV9XUklURV9BRlRFUl9FTkQoKTsgLy8gVE9ETzogZGVmZXIgZXJyb3IgZXZlbnRzIGNvbnNpc3RlbnRseSBldmVyeXdoZXJlLCBub3QganVzdCB0aGUgY2JcblxuICBlcnJvck9yRGVzdHJveShzdHJlYW0sIGVyKTtcbiAgcHJvY2Vzcy5uZXh0VGljayhjYiwgZXIpO1xufSAvLyBDaGVja3MgdGhhdCBhIHVzZXItc3VwcGxpZWQgY2h1bmsgaXMgdmFsaWQsIGVzcGVjaWFsbHkgZm9yIHRoZSBwYXJ0aWN1bGFyXG4vLyBtb2RlIHRoZSBzdHJlYW0gaXMgaW4uIEN1cnJlbnRseSB0aGlzIG1lYW5zIHRoYXQgYG51bGxgIGlzIG5ldmVyIGFjY2VwdGVkXG4vLyBhbmQgdW5kZWZpbmVkL25vbi1zdHJpbmcgdmFsdWVzIGFyZSBvbmx5IGFsbG93ZWQgaW4gb2JqZWN0IG1vZGUuXG5cblxuZnVuY3Rpb24gdmFsaWRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgY2IpIHtcbiAgdmFyIGVyO1xuXG4gIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgIGVyID0gbmV3IEVSUl9TVFJFQU1fTlVMTF9WQUxVRVMoKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgRVJSX0lOVkFMSURfQVJHX1RZUEUoJ2NodW5rJywgWydzdHJpbmcnLCAnQnVmZmVyJ10sIGNodW5rKTtcbiAgfVxuXG4gIGlmIChlcikge1xuICAgIGVycm9yT3JEZXN0cm95KHN0cmVhbSwgZXIpO1xuICAgIHByb2Nlc3MubmV4dFRpY2soY2IsIGVyKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuV3JpdGFibGUucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHJldCA9IGZhbHNlO1xuXG4gIHZhciBpc0J1ZiA9ICFzdGF0ZS5vYmplY3RNb2RlICYmIF9pc1VpbnQ4QXJyYXkoY2h1bmspO1xuXG4gIGlmIChpc0J1ZiAmJiAhQnVmZmVyLmlzQnVmZmVyKGNodW5rKSkge1xuICAgIGNodW5rID0gX3VpbnQ4QXJyYXlUb0J1ZmZlcihjaHVuayk7XG4gIH1cblxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoaXNCdWYpIGVuY29kaW5nID0gJ2J1ZmZlcic7ZWxzZSBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcbiAgaWYgKHR5cGVvZiBjYiAhPT0gJ2Z1bmN0aW9uJykgY2IgPSBub3A7XG4gIGlmIChzdGF0ZS5lbmRpbmcpIHdyaXRlQWZ0ZXJFbmQodGhpcywgY2IpO2Vsc2UgaWYgKGlzQnVmIHx8IHZhbGlkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBjYikpIHtcbiAgICBzdGF0ZS5wZW5kaW5nY2IrKztcbiAgICByZXQgPSB3cml0ZU9yQnVmZmVyKHRoaXMsIHN0YXRlLCBpc0J1ZiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5jb3JrID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl93cml0YWJsZVN0YXRlLmNvcmtlZCsrO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLnVuY29yayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAoc3RhdGUuY29ya2VkKSB7XG4gICAgc3RhdGUuY29ya2VkLS07XG4gICAgaWYgKCFzdGF0ZS53cml0aW5nICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSBjbGVhckJ1ZmZlcih0aGlzLCBzdGF0ZSk7XG4gIH1cbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5zZXREZWZhdWx0RW5jb2RpbmcgPSBmdW5jdGlvbiBzZXREZWZhdWx0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgLy8gbm9kZTo6UGFyc2VFbmNvZGluZygpIHJlcXVpcmVzIGxvd2VyIGNhc2UuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnKSBlbmNvZGluZyA9IGVuY29kaW5nLnRvTG93ZXJDYXNlKCk7XG4gIGlmICghKFsnaGV4JywgJ3V0ZjgnLCAndXRmLTgnLCAnYXNjaWknLCAnYmluYXJ5JywgJ2Jhc2U2NCcsICd1Y3MyJywgJ3Vjcy0yJywgJ3V0ZjE2bGUnLCAndXRmLTE2bGUnLCAncmF3J10uaW5kZXhPZigoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKSkgPiAtMSkpIHRocm93IG5ldyBFUlJfVU5LTk9XTl9FTkNPRElORyhlbmNvZGluZyk7XG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVmYXVsdEVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHJldHVybiB0aGlzO1xufTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlLnByb3RvdHlwZSwgJ3dyaXRhYmxlQnVmZmVyJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fd3JpdGFibGVTdGF0ZSAmJiB0aGlzLl93cml0YWJsZVN0YXRlLmdldEJ1ZmZlcigpO1xuICB9XG59KTtcblxuZnVuY3Rpb24gZGVjb2RlQ2h1bmsoc3RhdGUsIGNodW5rLCBlbmNvZGluZykge1xuICBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgc3RhdGUuZGVjb2RlU3RyaW5ncyAhPT0gZmFsc2UgJiYgdHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgIGNodW5rID0gQnVmZmVyLmZyb20oY2h1bmssIGVuY29kaW5nKTtcbiAgfVxuXG4gIHJldHVybiBjaHVuaztcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlLnByb3RvdHlwZSwgJ3dyaXRhYmxlSGlnaFdhdGVyTWFyaycsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgfVxufSk7IC8vIGlmIHdlJ3JlIGFscmVhZHkgd3JpdGluZyBzb21ldGhpbmcsIHRoZW4ganVzdCBwdXQgdGhpc1xuLy8gaW4gdGhlIHF1ZXVlLCBhbmQgd2FpdCBvdXIgdHVybi4gIE90aGVyd2lzZSwgY2FsbCBfd3JpdGVcbi8vIElmIHdlIHJldHVybiBmYWxzZSwgdGhlbiB3ZSBuZWVkIGEgZHJhaW4gZXZlbnQsIHNvIHNldCB0aGF0IGZsYWcuXG5cbmZ1bmN0aW9uIHdyaXRlT3JCdWZmZXIoc3RyZWFtLCBzdGF0ZSwgaXNCdWYsIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgaWYgKCFpc0J1Zikge1xuICAgIHZhciBuZXdDaHVuayA9IGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpO1xuXG4gICAgaWYgKGNodW5rICE9PSBuZXdDaHVuaykge1xuICAgICAgaXNCdWYgPSB0cnVlO1xuICAgICAgZW5jb2RpbmcgPSAnYnVmZmVyJztcbiAgICAgIGNodW5rID0gbmV3Q2h1bms7XG4gICAgfVxuICB9XG5cbiAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuICBzdGF0ZS5sZW5ndGggKz0gbGVuO1xuICB2YXIgcmV0ID0gc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyazsgLy8gd2UgbXVzdCBlbnN1cmUgdGhhdCBwcmV2aW91cyBuZWVkRHJhaW4gd2lsbCBub3QgYmUgcmVzZXQgdG8gZmFsc2UuXG5cbiAgaWYgKCFyZXQpIHN0YXRlLm5lZWREcmFpbiA9IHRydWU7XG5cbiAgaWYgKHN0YXRlLndyaXRpbmcgfHwgc3RhdGUuY29ya2VkKSB7XG4gICAgdmFyIGxhc3QgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSB7XG4gICAgICBjaHVuazogY2h1bmssXG4gICAgICBlbmNvZGluZzogZW5jb2RpbmcsXG4gICAgICBpc0J1ZjogaXNCdWYsXG4gICAgICBjYWxsYmFjazogY2IsXG4gICAgICBuZXh0OiBudWxsXG4gICAgfTtcblxuICAgIGlmIChsYXN0KSB7XG4gICAgICBsYXN0Lm5leHQgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIH1cblxuICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ICs9IDE7XG4gIH0gZWxzZSB7XG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgd3JpdGV2LCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgc3RhdGUud3JpdGVsZW4gPSBsZW47XG4gIHN0YXRlLndyaXRlY2IgPSBjYjtcbiAgc3RhdGUud3JpdGluZyA9IHRydWU7XG4gIHN0YXRlLnN5bmMgPSB0cnVlO1xuICBpZiAoc3RhdGUuZGVzdHJveWVkKSBzdGF0ZS5vbndyaXRlKG5ldyBFUlJfU1RSRUFNX0RFU1RST1lFRCgnd3JpdGUnKSk7ZWxzZSBpZiAod3JpdGV2KSBzdHJlYW0uX3dyaXRldihjaHVuaywgc3RhdGUub253cml0ZSk7ZWxzZSBzdHJlYW0uX3dyaXRlKGNodW5rLCBlbmNvZGluZywgc3RhdGUub253cml0ZSk7XG4gIHN0YXRlLnN5bmMgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYikge1xuICAtLXN0YXRlLnBlbmRpbmdjYjtcblxuICBpZiAoc3luYykge1xuICAgIC8vIGRlZmVyIHRoZSBjYWxsYmFjayBpZiB3ZSBhcmUgYmVpbmcgY2FsbGVkIHN5bmNocm9ub3VzbHlcbiAgICAvLyB0byBhdm9pZCBwaWxpbmcgdXAgdGhpbmdzIG9uIHRoZSBzdGFja1xuICAgIHByb2Nlc3MubmV4dFRpY2soY2IsIGVyKTsgLy8gdGhpcyBjYW4gZW1pdCBmaW5pc2gsIGFuZCBpdCB3aWxsIGFsd2F5cyBoYXBwZW5cbiAgICAvLyBhZnRlciBlcnJvclxuXG4gICAgcHJvY2Vzcy5uZXh0VGljayhmaW5pc2hNYXliZSwgc3RyZWFtLCBzdGF0ZSk7XG4gICAgc3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gICAgZXJyb3JPckRlc3Ryb3koc3RyZWFtLCBlcik7XG4gIH0gZWxzZSB7XG4gICAgLy8gdGhlIGNhbGxlciBleHBlY3QgdGhpcyB0byBoYXBwZW4gYmVmb3JlIGlmXG4gICAgLy8gaXQgaXMgYXN5bmNcbiAgICBjYihlcik7XG4gICAgc3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gICAgZXJyb3JPckRlc3Ryb3koc3RyZWFtLCBlcik7IC8vIHRoaXMgY2FuIGVtaXQgZmluaXNoLCBidXQgZmluaXNoIG11c3RcbiAgICAvLyBhbHdheXMgZm9sbG93IGVycm9yXG5cbiAgICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpIHtcbiAgc3RhdGUud3JpdGluZyA9IGZhbHNlO1xuICBzdGF0ZS53cml0ZWNiID0gbnVsbDtcbiAgc3RhdGUubGVuZ3RoIC09IHN0YXRlLndyaXRlbGVuO1xuICBzdGF0ZS53cml0ZWxlbiA9IDA7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGUoc3RyZWFtLCBlcikge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBzeW5jID0gc3RhdGUuc3luYztcbiAgdmFyIGNiID0gc3RhdGUud3JpdGVjYjtcbiAgaWYgKHR5cGVvZiBjYiAhPT0gJ2Z1bmN0aW9uJykgdGhyb3cgbmV3IEVSUl9NVUxUSVBMRV9DQUxMQkFDSygpO1xuICBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO1xuICBpZiAoZXIpIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpO2Vsc2Uge1xuICAgIC8vIENoZWNrIGlmIHdlJ3JlIGFjdHVhbGx5IHJlYWR5IHRvIGZpbmlzaCwgYnV0IGRvbid0IGVtaXQgeWV0XG4gICAgdmFyIGZpbmlzaGVkID0gbmVlZEZpbmlzaChzdGF0ZSkgfHwgc3RyZWFtLmRlc3Ryb3llZDtcblxuICAgIGlmICghZmluaXNoZWQgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIHtcbiAgICAgIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cblxuICAgIGlmIChzeW5jKSB7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKGFmdGVyV3JpdGUsIHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZCkgb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpO1xuICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgY2IoKTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG59IC8vIE11c3QgZm9yY2UgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIG9uIG5leHRUaWNrLCBzbyB0aGF0IHdlIGRvbid0XG4vLyBlbWl0ICdkcmFpbicgYmVmb3JlIHRoZSB3cml0ZSgpIGNvbnN1bWVyIGdldHMgdGhlICdmYWxzZScgcmV0dXJuXG4vLyB2YWx1ZSwgYW5kIGhhcyBhIGNoYW5jZSB0byBhdHRhY2ggYSAnZHJhaW4nIGxpc3RlbmVyLlxuXG5cbmZ1bmN0aW9uIG9ud3JpdGVEcmFpbihzdHJlYW0sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUubmVlZERyYWluKSB7XG4gICAgc3RhdGUubmVlZERyYWluID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2RyYWluJyk7XG4gIH1cbn0gLy8gaWYgdGhlcmUncyBzb21ldGhpbmcgaW4gdGhlIGJ1ZmZlciB3YWl0aW5nLCB0aGVuIHByb2Nlc3MgaXRcblxuXG5mdW5jdGlvbiBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKSB7XG4gIHN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgPSB0cnVlO1xuICB2YXIgZW50cnkgPSBzdGF0ZS5idWZmZXJlZFJlcXVlc3Q7XG5cbiAgaWYgKHN0cmVhbS5fd3JpdGV2ICYmIGVudHJ5ICYmIGVudHJ5Lm5leHQpIHtcbiAgICAvLyBGYXN0IGNhc2UsIHdyaXRlIGV2ZXJ5dGhpbmcgdXNpbmcgX3dyaXRldigpXG4gICAgdmFyIGwgPSBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudDtcbiAgICB2YXIgYnVmZmVyID0gbmV3IEFycmF5KGwpO1xuICAgIHZhciBob2xkZXIgPSBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWU7XG4gICAgaG9sZGVyLmVudHJ5ID0gZW50cnk7XG4gICAgdmFyIGNvdW50ID0gMDtcbiAgICB2YXIgYWxsQnVmZmVycyA9IHRydWU7XG5cbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIGJ1ZmZlcltjb3VudF0gPSBlbnRyeTtcbiAgICAgIGlmICghZW50cnkuaXNCdWYpIGFsbEJ1ZmZlcnMgPSBmYWxzZTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIGNvdW50ICs9IDE7XG4gICAgfVxuXG4gICAgYnVmZmVyLmFsbEJ1ZmZlcnMgPSBhbGxCdWZmZXJzO1xuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgdHJ1ZSwgc3RhdGUubGVuZ3RoLCBidWZmZXIsICcnLCBob2xkZXIuZmluaXNoKTsgLy8gZG9Xcml0ZSBpcyBhbG1vc3QgYWx3YXlzIGFzeW5jLCBkZWZlciB0aGVzZSB0byBzYXZlIGEgYml0IG9mIHRpbWVcbiAgICAvLyBhcyB0aGUgaG90IHBhdGggZW5kcyB3aXRoIGRvV3JpdGVcblxuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuXG4gICAgaWYgKGhvbGRlci5uZXh0KSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBob2xkZXIubmV4dDtcbiAgICAgIGhvbGRlci5uZXh0ID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gbmV3IENvcmtlZFJlcXVlc3Qoc3RhdGUpO1xuICAgIH1cblxuICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBTbG93IGNhc2UsIHdyaXRlIGNodW5rcyBvbmUtYnktb25lXG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICB2YXIgY2h1bmsgPSBlbnRyeS5jaHVuaztcbiAgICAgIHZhciBlbmNvZGluZyA9IGVudHJ5LmVuY29kaW5nO1xuICAgICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIGZhbHNlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQtLTsgLy8gaWYgd2UgZGlkbid0IGNhbGwgdGhlIG9ud3JpdGUgaW1tZWRpYXRlbHksIHRoZW5cbiAgICAgIC8vIGl0IG1lYW5zIHRoYXQgd2UgbmVlZCB0byB3YWl0IHVudGlsIGl0IGRvZXMuXG4gICAgICAvLyBhbHNvLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGNodW5rIGFuZCBjYiBhcmUgY3VycmVudGx5XG4gICAgICAvLyBiZWluZyBwcm9jZXNzZWQsIHNvIG1vdmUgdGhlIGJ1ZmZlciBjb3VudGVyIHBhc3QgdGhlbS5cblxuICAgICAgaWYgKHN0YXRlLndyaXRpbmcpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVudHJ5ID09PSBudWxsKSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgfVxuXG4gIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IGVudHJ5O1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihuZXcgRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQoJ193cml0ZSgpJykpO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLl93cml0ZXYgPSBudWxsO1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAodHlwZW9mIGNodW5rID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBjaHVuaztcbiAgICBjaHVuayA9IG51bGw7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKGNodW5rICE9PSBudWxsICYmIGNodW5rICE9PSB1bmRlZmluZWQpIHRoaXMud3JpdGUoY2h1bmssIGVuY29kaW5nKTsgLy8gLmVuZCgpIGZ1bGx5IHVuY29ya3NcblxuICBpZiAoc3RhdGUuY29ya2VkKSB7XG4gICAgc3RhdGUuY29ya2VkID0gMTtcbiAgICB0aGlzLnVuY29yaygpO1xuICB9IC8vIGlnbm9yZSB1bm5lY2Vzc2FyeSBlbmQoKSBjYWxscy5cblxuXG4gIGlmICghc3RhdGUuZW5kaW5nKSBlbmRXcml0YWJsZSh0aGlzLCBzdGF0ZSwgY2IpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZS5wcm90b3R5cGUsICd3cml0YWJsZUxlbmd0aCcsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUubGVuZ3RoO1xuICB9XG59KTtcblxuZnVuY3Rpb24gbmVlZEZpbmlzaChzdGF0ZSkge1xuICByZXR1cm4gc3RhdGUuZW5kaW5nICYmIHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPT09IG51bGwgJiYgIXN0YXRlLmZpbmlzaGVkICYmICFzdGF0ZS53cml0aW5nO1xufVxuXG5mdW5jdGlvbiBjYWxsRmluYWwoc3RyZWFtLCBzdGF0ZSkge1xuICBzdHJlYW0uX2ZpbmFsKGZ1bmN0aW9uIChlcnIpIHtcbiAgICBzdGF0ZS5wZW5kaW5nY2ItLTtcblxuICAgIGlmIChlcnIpIHtcbiAgICAgIGVycm9yT3JEZXN0cm95KHN0cmVhbSwgZXJyKTtcbiAgICB9XG5cbiAgICBzdGF0ZS5wcmVmaW5pc2hlZCA9IHRydWU7XG4gICAgc3RyZWFtLmVtaXQoJ3ByZWZpbmlzaCcpO1xuICAgIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5wcmVmaW5pc2hlZCAmJiAhc3RhdGUuZmluYWxDYWxsZWQpIHtcbiAgICBpZiAodHlwZW9mIHN0cmVhbS5fZmluYWwgPT09ICdmdW5jdGlvbicgJiYgIXN0YXRlLmRlc3Ryb3llZCkge1xuICAgICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgICBzdGF0ZS5maW5hbENhbGxlZCA9IHRydWU7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKGNhbGxGaW5hbCwgc3RyZWFtLCBzdGF0ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLnByZWZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5lbWl0KCdwcmVmaW5pc2gnKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbmVlZCA9IG5lZWRGaW5pc2goc3RhdGUpO1xuXG4gIGlmIChuZWVkKSB7XG4gICAgcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuXG4gICAgaWYgKHN0YXRlLnBlbmRpbmdjYiA9PT0gMCkge1xuICAgICAgc3RhdGUuZmluaXNoZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLmVtaXQoJ2ZpbmlzaCcpO1xuXG4gICAgICBpZiAoc3RhdGUuYXV0b0Rlc3Ryb3kpIHtcbiAgICAgICAgLy8gSW4gY2FzZSBvZiBkdXBsZXggc3RyZWFtcyB3ZSBuZWVkIGEgd2F5IHRvIGRldGVjdFxuICAgICAgICAvLyBpZiB0aGUgcmVhZGFibGUgc2lkZSBpcyByZWFkeSBmb3IgYXV0b0Rlc3Ryb3kgYXMgd2VsbFxuICAgICAgICB2YXIgclN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuXG4gICAgICAgIGlmICghclN0YXRlIHx8IHJTdGF0ZS5hdXRvRGVzdHJveSAmJiByU3RhdGUuZW5kRW1pdHRlZCkge1xuICAgICAgICAgIHN0cmVhbS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmVlZDtcbn1cblxuZnVuY3Rpb24gZW5kV3JpdGFibGUoc3RyZWFtLCBzdGF0ZSwgY2IpIHtcbiAgc3RhdGUuZW5kaW5nID0gdHJ1ZTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG5cbiAgaWYgKGNiKSB7XG4gICAgaWYgKHN0YXRlLmZpbmlzaGVkKSBwcm9jZXNzLm5leHRUaWNrKGNiKTtlbHNlIHN0cmVhbS5vbmNlKCdmaW5pc2gnLCBjYik7XG4gIH1cblxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG4gIHN0cmVhbS53cml0YWJsZSA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBvbkNvcmtlZEZpbmlzaChjb3JrUmVxLCBzdGF0ZSwgZXJyKSB7XG4gIHZhciBlbnRyeSA9IGNvcmtSZXEuZW50cnk7XG4gIGNvcmtSZXEuZW50cnkgPSBudWxsO1xuXG4gIHdoaWxlIChlbnRyeSkge1xuICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgIHN0YXRlLnBlbmRpbmdjYi0tO1xuICAgIGNiKGVycik7XG4gICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICB9IC8vIHJldXNlIHRoZSBmcmVlIGNvcmtSZXEuXG5cblxuICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dCA9IGNvcmtSZXE7XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZS5wcm90b3R5cGUsICdkZXN0cm95ZWQnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIGlmICh0aGlzLl93cml0YWJsZVN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fd3JpdGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24gc2V0KHZhbHVlKSB7XG4gICAgLy8gd2UgaWdub3JlIHRoZSB2YWx1ZSBpZiB0aGUgc3RyZWFtXG4gICAgLy8gaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIHlldFxuICAgIGlmICghdGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdGhlIHVzZXIgaXMgZXhwbGljaXRseVxuICAgIC8vIG1hbmFnaW5nIGRlc3Ryb3llZFxuXG5cbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICB9XG59KTtcbldyaXRhYmxlLnByb3RvdHlwZS5kZXN0cm95ID0gZGVzdHJveUltcGwuZGVzdHJveTtcbldyaXRhYmxlLnByb3RvdHlwZS5fdW5kZXN0cm95ID0gZGVzdHJveUltcGwudW5kZXN0cm95O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuX2Rlc3Ryb3kgPSBmdW5jdGlvbiAoZXJyLCBjYikge1xuICBjYihlcnIpO1xufTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfT2JqZWN0JHNldFByb3RvdHlwZU87XG5cbmZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgdmFsdWUpIHsgaWYgKGtleSBpbiBvYmopIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7IHZhbHVlOiB2YWx1ZSwgZW51bWVyYWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlLCB3cml0YWJsZTogdHJ1ZSB9KTsgfSBlbHNlIHsgb2JqW2tleV0gPSB2YWx1ZTsgfSByZXR1cm4gb2JqOyB9XG5cbnZhciBmaW5pc2hlZCA9IHJlcXVpcmUoJy4vZW5kLW9mLXN0cmVhbScpO1xuXG52YXIga0xhc3RSZXNvbHZlID0gU3ltYm9sKCdsYXN0UmVzb2x2ZScpO1xudmFyIGtMYXN0UmVqZWN0ID0gU3ltYm9sKCdsYXN0UmVqZWN0Jyk7XG52YXIga0Vycm9yID0gU3ltYm9sKCdlcnJvcicpO1xudmFyIGtFbmRlZCA9IFN5bWJvbCgnZW5kZWQnKTtcbnZhciBrTGFzdFByb21pc2UgPSBTeW1ib2woJ2xhc3RQcm9taXNlJyk7XG52YXIga0hhbmRsZVByb21pc2UgPSBTeW1ib2woJ2hhbmRsZVByb21pc2UnKTtcbnZhciBrU3RyZWFtID0gU3ltYm9sKCdzdHJlYW0nKTtcblxuZnVuY3Rpb24gY3JlYXRlSXRlclJlc3VsdCh2YWx1ZSwgZG9uZSkge1xuICByZXR1cm4ge1xuICAgIHZhbHVlOiB2YWx1ZSxcbiAgICBkb25lOiBkb25lXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlYWRBbmRSZXNvbHZlKGl0ZXIpIHtcbiAgdmFyIHJlc29sdmUgPSBpdGVyW2tMYXN0UmVzb2x2ZV07XG5cbiAgaWYgKHJlc29sdmUgIT09IG51bGwpIHtcbiAgICB2YXIgZGF0YSA9IGl0ZXJba1N0cmVhbV0ucmVhZCgpOyAvLyB3ZSBkZWZlciBpZiBkYXRhIGlzIG51bGxcbiAgICAvLyB3ZSBjYW4gYmUgZXhwZWN0aW5nIGVpdGhlciAnZW5kJyBvclxuICAgIC8vICdlcnJvcidcblxuICAgIGlmIChkYXRhICE9PSBudWxsKSB7XG4gICAgICBpdGVyW2tMYXN0UHJvbWlzZV0gPSBudWxsO1xuICAgICAgaXRlcltrTGFzdFJlc29sdmVdID0gbnVsbDtcbiAgICAgIGl0ZXJba0xhc3RSZWplY3RdID0gbnVsbDtcbiAgICAgIHJlc29sdmUoY3JlYXRlSXRlclJlc3VsdChkYXRhLCBmYWxzZSkpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBvblJlYWRhYmxlKGl0ZXIpIHtcbiAgLy8gd2Ugd2FpdCBmb3IgdGhlIG5leHQgdGljaywgYmVjYXVzZSBpdCBtaWdodFxuICAvLyBlbWl0IGFuIGVycm9yIHdpdGggcHJvY2Vzcy5uZXh0VGlja1xuICBwcm9jZXNzLm5leHRUaWNrKHJlYWRBbmRSZXNvbHZlLCBpdGVyKTtcbn1cblxuZnVuY3Rpb24gd3JhcEZvck5leHQobGFzdFByb21pc2UsIGl0ZXIpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBsYXN0UHJvbWlzZS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChpdGVyW2tFbmRlZF0pIHtcbiAgICAgICAgcmVzb2x2ZShjcmVhdGVJdGVyUmVzdWx0KHVuZGVmaW5lZCwgdHJ1ZSkpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGl0ZXJba0hhbmRsZVByb21pc2VdKHJlc29sdmUsIHJlamVjdCk7XG4gICAgfSwgcmVqZWN0KTtcbiAgfTtcbn1cblxudmFyIEFzeW5jSXRlcmF0b3JQcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoZnVuY3Rpb24gKCkge30pO1xudmFyIFJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvclByb3RvdHlwZSA9IE9iamVjdC5zZXRQcm90b3R5cGVPZigoX09iamVjdCRzZXRQcm90b3R5cGVPID0ge1xuICBnZXQgc3RyZWFtKCkge1xuICAgIHJldHVybiB0aGlzW2tTdHJlYW1dO1xuICB9LFxuXG4gIG5leHQ6IGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIC8vIGlmIHdlIGhhdmUgZGV0ZWN0ZWQgYW4gZXJyb3IgaW4gdGhlIG1lYW53aGlsZVxuICAgIC8vIHJlamVjdCBzdHJhaWdodCBhd2F5XG4gICAgdmFyIGVycm9yID0gdGhpc1trRXJyb3JdO1xuXG4gICAgaWYgKGVycm9yICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgIH1cblxuICAgIGlmICh0aGlzW2tFbmRlZF0pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoY3JlYXRlSXRlclJlc3VsdCh1bmRlZmluZWQsIHRydWUpKTtcbiAgICB9XG5cbiAgICBpZiAodGhpc1trU3RyZWFtXS5kZXN0cm95ZWQpIHtcbiAgICAgIC8vIFdlIG5lZWQgdG8gZGVmZXIgdmlhIG5leHRUaWNrIGJlY2F1c2UgaWYgLmRlc3Ryb3koZXJyKSBpc1xuICAgICAgLy8gY2FsbGVkLCB0aGUgZXJyb3Igd2lsbCBiZSBlbWl0dGVkIHZpYSBuZXh0VGljaywgYW5kXG4gICAgICAvLyB3ZSBjYW5ub3QgZ3VhcmFudGVlIHRoYXQgdGhlcmUgaXMgbm8gZXJyb3IgbGluZ2VyaW5nIGFyb3VuZFxuICAgICAgLy8gd2FpdGluZyB0byBiZSBlbWl0dGVkLlxuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKF90aGlzW2tFcnJvcl0pIHtcbiAgICAgICAgICAgIHJlamVjdChfdGhpc1trRXJyb3JdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzb2x2ZShjcmVhdGVJdGVyUmVzdWx0KHVuZGVmaW5lZCwgdHJ1ZSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IC8vIGlmIHdlIGhhdmUgbXVsdGlwbGUgbmV4dCgpIGNhbGxzXG4gICAgLy8gd2Ugd2lsbCB3YWl0IGZvciB0aGUgcHJldmlvdXMgUHJvbWlzZSB0byBmaW5pc2hcbiAgICAvLyB0aGlzIGxvZ2ljIGlzIG9wdGltaXplZCB0byBzdXBwb3J0IGZvciBhd2FpdCBsb29wcyxcbiAgICAvLyB3aGVyZSBuZXh0KCkgaXMgb25seSBjYWxsZWQgb25jZSBhdCBhIHRpbWVcblxuXG4gICAgdmFyIGxhc3RQcm9taXNlID0gdGhpc1trTGFzdFByb21pc2VdO1xuICAgIHZhciBwcm9taXNlO1xuXG4gICAgaWYgKGxhc3RQcm9taXNlKSB7XG4gICAgICBwcm9taXNlID0gbmV3IFByb21pc2Uod3JhcEZvck5leHQobGFzdFByb21pc2UsIHRoaXMpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZmFzdCBwYXRoIG5lZWRlZCB0byBzdXBwb3J0IG11bHRpcGxlIHRoaXMucHVzaCgpXG4gICAgICAvLyB3aXRob3V0IHRyaWdnZXJpbmcgdGhlIG5leHQoKSBxdWV1ZVxuICAgICAgdmFyIGRhdGEgPSB0aGlzW2tTdHJlYW1dLnJlYWQoKTtcblxuICAgICAgaWYgKGRhdGEgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShjcmVhdGVJdGVyUmVzdWx0KGRhdGEsIGZhbHNlKSk7XG4gICAgICB9XG5cbiAgICAgIHByb21pc2UgPSBuZXcgUHJvbWlzZSh0aGlzW2tIYW5kbGVQcm9taXNlXSk7XG4gICAgfVxuXG4gICAgdGhpc1trTGFzdFByb21pc2VdID0gcHJvbWlzZTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxufSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3Qkc2V0UHJvdG90eXBlTywgU3ltYm9sLmFzeW5jSXRlcmF0b3IsIGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXM7XG59KSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3Qkc2V0UHJvdG90eXBlTywgXCJyZXR1cm5cIiwgZnVuY3Rpb24gX3JldHVybigpIHtcbiAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgLy8gZGVzdHJveShlcnIsIGNiKSBpcyBhIHByaXZhdGUgQVBJXG4gIC8vIHdlIGNhbiBndWFyYW50ZWUgd2UgaGF2ZSB0aGF0IGhlcmUsIGJlY2F1c2Ugd2UgY29udHJvbCB0aGVcbiAgLy8gUmVhZGFibGUgY2xhc3MgdGhpcyBpcyBhdHRhY2hlZCB0b1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIF90aGlzMltrU3RyZWFtXS5kZXN0cm95KG51bGwsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcmVzb2x2ZShjcmVhdGVJdGVyUmVzdWx0KHVuZGVmaW5lZCwgdHJ1ZSkpO1xuICAgIH0pO1xuICB9KTtcbn0pLCBfT2JqZWN0JHNldFByb3RvdHlwZU8pLCBBc3luY0l0ZXJhdG9yUHJvdG90eXBlKTtcblxudmFyIGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvciA9IGZ1bmN0aW9uIGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcihzdHJlYW0pIHtcbiAgdmFyIF9PYmplY3QkY3JlYXRlO1xuXG4gIHZhciBpdGVyYXRvciA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yUHJvdG90eXBlLCAoX09iamVjdCRjcmVhdGUgPSB7fSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3QkY3JlYXRlLCBrU3RyZWFtLCB7XG4gICAgdmFsdWU6IHN0cmVhbSxcbiAgICB3cml0YWJsZTogdHJ1ZVxuICB9KSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3QkY3JlYXRlLCBrTGFzdFJlc29sdmUsIHtcbiAgICB2YWx1ZTogbnVsbCxcbiAgICB3cml0YWJsZTogdHJ1ZVxuICB9KSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3QkY3JlYXRlLCBrTGFzdFJlamVjdCwge1xuICAgIHZhbHVlOiBudWxsLFxuICAgIHdyaXRhYmxlOiB0cnVlXG4gIH0pLCBfZGVmaW5lUHJvcGVydHkoX09iamVjdCRjcmVhdGUsIGtFcnJvciwge1xuICAgIHZhbHVlOiBudWxsLFxuICAgIHdyaXRhYmxlOiB0cnVlXG4gIH0pLCBfZGVmaW5lUHJvcGVydHkoX09iamVjdCRjcmVhdGUsIGtFbmRlZCwge1xuICAgIHZhbHVlOiBzdHJlYW0uX3JlYWRhYmxlU3RhdGUuZW5kRW1pdHRlZCxcbiAgICB3cml0YWJsZTogdHJ1ZVxuICB9KSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3QkY3JlYXRlLCBrSGFuZGxlUHJvbWlzZSwge1xuICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZShyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciBkYXRhID0gaXRlcmF0b3Jba1N0cmVhbV0ucmVhZCgpO1xuXG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICBpdGVyYXRvcltrTGFzdFByb21pc2VdID0gbnVsbDtcbiAgICAgICAgaXRlcmF0b3Jba0xhc3RSZXNvbHZlXSA9IG51bGw7XG4gICAgICAgIGl0ZXJhdG9yW2tMYXN0UmVqZWN0XSA9IG51bGw7XG4gICAgICAgIHJlc29sdmUoY3JlYXRlSXRlclJlc3VsdChkYXRhLCBmYWxzZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXRlcmF0b3Jba0xhc3RSZXNvbHZlXSA9IHJlc29sdmU7XG4gICAgICAgIGl0ZXJhdG9yW2tMYXN0UmVqZWN0XSA9IHJlamVjdDtcbiAgICAgIH1cbiAgICB9LFxuICAgIHdyaXRhYmxlOiB0cnVlXG4gIH0pLCBfT2JqZWN0JGNyZWF0ZSkpO1xuICBpdGVyYXRvcltrTGFzdFByb21pc2VdID0gbnVsbDtcbiAgZmluaXNoZWQoc3RyZWFtLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKGVyciAmJiBlcnIuY29kZSAhPT0gJ0VSUl9TVFJFQU1fUFJFTUFUVVJFX0NMT1NFJykge1xuICAgICAgdmFyIHJlamVjdCA9IGl0ZXJhdG9yW2tMYXN0UmVqZWN0XTsgLy8gcmVqZWN0IGlmIHdlIGFyZSB3YWl0aW5nIGZvciBkYXRhIGluIHRoZSBQcm9taXNlXG4gICAgICAvLyByZXR1cm5lZCBieSBuZXh0KCkgYW5kIHN0b3JlIHRoZSBlcnJvclxuXG4gICAgICBpZiAocmVqZWN0ICE9PSBudWxsKSB7XG4gICAgICAgIGl0ZXJhdG9yW2tMYXN0UHJvbWlzZV0gPSBudWxsO1xuICAgICAgICBpdGVyYXRvcltrTGFzdFJlc29sdmVdID0gbnVsbDtcbiAgICAgICAgaXRlcmF0b3Jba0xhc3RSZWplY3RdID0gbnVsbDtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICB9XG5cbiAgICAgIGl0ZXJhdG9yW2tFcnJvcl0gPSBlcnI7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHJlc29sdmUgPSBpdGVyYXRvcltrTGFzdFJlc29sdmVdO1xuXG4gICAgaWYgKHJlc29sdmUgIT09IG51bGwpIHtcbiAgICAgIGl0ZXJhdG9yW2tMYXN0UHJvbWlzZV0gPSBudWxsO1xuICAgICAgaXRlcmF0b3Jba0xhc3RSZXNvbHZlXSA9IG51bGw7XG4gICAgICBpdGVyYXRvcltrTGFzdFJlamVjdF0gPSBudWxsO1xuICAgICAgcmVzb2x2ZShjcmVhdGVJdGVyUmVzdWx0KHVuZGVmaW5lZCwgdHJ1ZSkpO1xuICAgIH1cblxuICAgIGl0ZXJhdG9yW2tFbmRlZF0gPSB0cnVlO1xuICB9KTtcbiAgc3RyZWFtLm9uKCdyZWFkYWJsZScsIG9uUmVhZGFibGUuYmluZChudWxsLCBpdGVyYXRvcikpO1xuICByZXR1cm4gaXRlcmF0b3I7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcjsiLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIG93bktleXMob2JqZWN0LCBlbnVtZXJhYmxlT25seSkgeyB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdCk7IGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7IHZhciBzeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmplY3QpOyBpZiAoZW51bWVyYWJsZU9ubHkpIHN5bWJvbHMgPSBzeW1ib2xzLmZpbHRlcihmdW5jdGlvbiAoc3ltKSB7IHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgc3ltKS5lbnVtZXJhYmxlOyB9KTsga2V5cy5wdXNoLmFwcGx5KGtleXMsIHN5bWJvbHMpOyB9IHJldHVybiBrZXlzOyB9XG5cbmZ1bmN0aW9uIF9vYmplY3RTcHJlYWQodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV0gIT0gbnVsbCA/IGFyZ3VtZW50c1tpXSA6IHt9OyBpZiAoaSAlIDIpIHsgb3duS2V5cyhPYmplY3Qoc291cmNlKSwgdHJ1ZSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IF9kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgc291cmNlW2tleV0pOyB9KTsgfSBlbHNlIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycykgeyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKHNvdXJjZSkpOyB9IGVsc2UgeyBvd25LZXlzKE9iamVjdChzb3VyY2UpKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNvdXJjZSwga2V5KSk7IH0pOyB9IH0gcmV0dXJuIHRhcmdldDsgfVxuXG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHZhbHVlKSB7IGlmIChrZXkgaW4gb2JqKSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgeyB2YWx1ZTogdmFsdWUsIGVudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSwgd3JpdGFibGU6IHRydWUgfSk7IH0gZWxzZSB7IG9ialtrZXldID0gdmFsdWU7IH0gcmV0dXJuIG9iajsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9XG5cbmZ1bmN0aW9uIF9jcmVhdGVDbGFzcyhDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ2J1ZmZlcicpLFxuICAgIEJ1ZmZlciA9IF9yZXF1aXJlLkJ1ZmZlcjtcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ3V0aWwnKSxcbiAgICBpbnNwZWN0ID0gX3JlcXVpcmUyLmluc3BlY3Q7XG5cbnZhciBjdXN0b20gPSBpbnNwZWN0ICYmIGluc3BlY3QuY3VzdG9tIHx8ICdpbnNwZWN0JztcblxuZnVuY3Rpb24gY29weUJ1ZmZlcihzcmMsIHRhcmdldCwgb2Zmc2V0KSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuY29weS5jYWxsKHNyYywgdGFyZ2V0LCBvZmZzZXQpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9XG4vKiNfX1BVUkVfXyovXG5mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEJ1ZmZlckxpc3QoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEJ1ZmZlckxpc3QpO1xuXG4gICAgdGhpcy5oZWFkID0gbnVsbDtcbiAgICB0aGlzLnRhaWwgPSBudWxsO1xuICAgIHRoaXMubGVuZ3RoID0gMDtcbiAgfVxuXG4gIF9jcmVhdGVDbGFzcyhCdWZmZXJMaXN0LCBbe1xuICAgIGtleTogXCJwdXNoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHB1c2godikge1xuICAgICAgdmFyIGVudHJ5ID0ge1xuICAgICAgICBkYXRhOiB2LFxuICAgICAgICBuZXh0OiBudWxsXG4gICAgICB9O1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID4gMCkgdGhpcy50YWlsLm5leHQgPSBlbnRyeTtlbHNlIHRoaXMuaGVhZCA9IGVudHJ5O1xuICAgICAgdGhpcy50YWlsID0gZW50cnk7XG4gICAgICArK3RoaXMubGVuZ3RoO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJ1bnNoaWZ0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHVuc2hpZnQodikge1xuICAgICAgdmFyIGVudHJ5ID0ge1xuICAgICAgICBkYXRhOiB2LFxuICAgICAgICBuZXh0OiB0aGlzLmhlYWRcbiAgICAgIH07XG4gICAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHRoaXMudGFpbCA9IGVudHJ5O1xuICAgICAgdGhpcy5oZWFkID0gZW50cnk7XG4gICAgICArK3RoaXMubGVuZ3RoO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzaGlmdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzaGlmdCgpIHtcbiAgICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgdmFyIHJldCA9IHRoaXMuaGVhZC5kYXRhO1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAxKSB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBudWxsO2Vsc2UgdGhpcy5oZWFkID0gdGhpcy5oZWFkLm5leHQ7XG4gICAgICAtLXRoaXMubGVuZ3RoO1xuICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY2xlYXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY2xlYXIoKSB7XG4gICAgICB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBudWxsO1xuICAgICAgdGhpcy5sZW5ndGggPSAwO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJqb2luXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGpvaW4ocykge1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gICAgICB2YXIgcCA9IHRoaXMuaGVhZDtcbiAgICAgIHZhciByZXQgPSAnJyArIHAuZGF0YTtcblxuICAgICAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICAgICAgcmV0ICs9IHMgKyBwLmRhdGE7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNvbmNhdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb25jYXQobikge1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gQnVmZmVyLmFsbG9jKDApO1xuICAgICAgdmFyIHJldCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShuID4+PiAwKTtcbiAgICAgIHZhciBwID0gdGhpcy5oZWFkO1xuICAgICAgdmFyIGkgPSAwO1xuXG4gICAgICB3aGlsZSAocCkge1xuICAgICAgICBjb3B5QnVmZmVyKHAuZGF0YSwgcmV0LCBpKTtcbiAgICAgICAgaSArPSBwLmRhdGEubGVuZ3RoO1xuICAgICAgICBwID0gcC5uZXh0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmV0O1xuICAgIH0gLy8gQ29uc3VtZXMgYSBzcGVjaWZpZWQgYW1vdW50IG9mIGJ5dGVzIG9yIGNoYXJhY3RlcnMgZnJvbSB0aGUgYnVmZmVyZWQgZGF0YS5cblxuICB9LCB7XG4gICAga2V5OiBcImNvbnN1bWVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29uc3VtZShuLCBoYXNTdHJpbmdzKSB7XG4gICAgICB2YXIgcmV0O1xuXG4gICAgICBpZiAobiA8IHRoaXMuaGVhZC5kYXRhLmxlbmd0aCkge1xuICAgICAgICAvLyBgc2xpY2VgIGlzIHRoZSBzYW1lIGZvciBidWZmZXJzIGFuZCBzdHJpbmdzLlxuICAgICAgICByZXQgPSB0aGlzLmhlYWQuZGF0YS5zbGljZSgwLCBuKTtcbiAgICAgICAgdGhpcy5oZWFkLmRhdGEgPSB0aGlzLmhlYWQuZGF0YS5zbGljZShuKTtcbiAgICAgIH0gZWxzZSBpZiAobiA9PT0gdGhpcy5oZWFkLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgIC8vIEZpcnN0IGNodW5rIGlzIGEgcGVyZmVjdCBtYXRjaC5cbiAgICAgICAgcmV0ID0gdGhpcy5zaGlmdCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gUmVzdWx0IHNwYW5zIG1vcmUgdGhhbiBvbmUgYnVmZmVyLlxuICAgICAgICByZXQgPSBoYXNTdHJpbmdzID8gdGhpcy5fZ2V0U3RyaW5nKG4pIDogdGhpcy5fZ2V0QnVmZmVyKG4pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmV0O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJmaXJzdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBmaXJzdCgpIHtcbiAgICAgIHJldHVybiB0aGlzLmhlYWQuZGF0YTtcbiAgICB9IC8vIENvbnN1bWVzIGEgc3BlY2lmaWVkIGFtb3VudCBvZiBjaGFyYWN0ZXJzIGZyb20gdGhlIGJ1ZmZlcmVkIGRhdGEuXG5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0U3RyaW5nXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRTdHJpbmcobikge1xuICAgICAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gICAgICB2YXIgYyA9IDE7XG4gICAgICB2YXIgcmV0ID0gcC5kYXRhO1xuICAgICAgbiAtPSByZXQubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAocCA9IHAubmV4dCkge1xuICAgICAgICB2YXIgc3RyID0gcC5kYXRhO1xuICAgICAgICB2YXIgbmIgPSBuID4gc3RyLmxlbmd0aCA/IHN0ci5sZW5ndGggOiBuO1xuICAgICAgICBpZiAobmIgPT09IHN0ci5sZW5ndGgpIHJldCArPSBzdHI7ZWxzZSByZXQgKz0gc3RyLnNsaWNlKDAsIG4pO1xuICAgICAgICBuIC09IG5iO1xuXG4gICAgICAgIGlmIChuID09PSAwKSB7XG4gICAgICAgICAgaWYgKG5iID09PSBzdHIubGVuZ3RoKSB7XG4gICAgICAgICAgICArK2M7XG4gICAgICAgICAgICBpZiAocC5uZXh0KSB0aGlzLmhlYWQgPSBwLm5leHQ7ZWxzZSB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBudWxsO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmhlYWQgPSBwO1xuICAgICAgICAgICAgcC5kYXRhID0gc3RyLnNsaWNlKG5iKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgICsrYztcbiAgICAgIH1cblxuICAgICAgdGhpcy5sZW5ndGggLT0gYztcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfSAvLyBDb25zdW1lcyBhIHNwZWNpZmllZCBhbW91bnQgb2YgYnl0ZXMgZnJvbSB0aGUgYnVmZmVyZWQgZGF0YS5cblxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRCdWZmZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldEJ1ZmZlcihuKSB7XG4gICAgICB2YXIgcmV0ID0gQnVmZmVyLmFsbG9jVW5zYWZlKG4pO1xuICAgICAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gICAgICB2YXIgYyA9IDE7XG4gICAgICBwLmRhdGEuY29weShyZXQpO1xuICAgICAgbiAtPSBwLmRhdGEubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAocCA9IHAubmV4dCkge1xuICAgICAgICB2YXIgYnVmID0gcC5kYXRhO1xuICAgICAgICB2YXIgbmIgPSBuID4gYnVmLmxlbmd0aCA/IGJ1Zi5sZW5ndGggOiBuO1xuICAgICAgICBidWYuY29weShyZXQsIHJldC5sZW5ndGggLSBuLCAwLCBuYik7XG4gICAgICAgIG4gLT0gbmI7XG5cbiAgICAgICAgaWYgKG4gPT09IDApIHtcbiAgICAgICAgICBpZiAobmIgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICAgICAgICAgICsrYztcbiAgICAgICAgICAgIGlmIChwLm5leHQpIHRoaXMuaGVhZCA9IHAubmV4dDtlbHNlIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaGVhZCA9IHA7XG4gICAgICAgICAgICBwLmRhdGEgPSBidWYuc2xpY2UobmIpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgKytjO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmxlbmd0aCAtPSBjO1xuICAgICAgcmV0dXJuIHJldDtcbiAgICB9IC8vIE1ha2Ugc3VyZSB0aGUgbGlua2VkIGxpc3Qgb25seSBzaG93cyB0aGUgbWluaW1hbCBuZWNlc3NhcnkgaW5mb3JtYXRpb24uXG5cbiAgfSwge1xuICAgIGtleTogY3VzdG9tLFxuICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZShfLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gaW5zcGVjdCh0aGlzLCBfb2JqZWN0U3ByZWFkKHt9LCBvcHRpb25zLCB7XG4gICAgICAgIC8vIE9ubHkgaW5zcGVjdCBvbmUgbGV2ZWwuXG4gICAgICAgIGRlcHRoOiAwLFxuICAgICAgICAvLyBJdCBzaG91bGQgbm90IHJlY3Vyc2UuXG4gICAgICAgIGN1c3RvbUluc3BlY3Q6IGZhbHNlXG4gICAgICB9KSk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIEJ1ZmZlckxpc3Q7XG59KCk7IiwiJ3VzZSBzdHJpY3QnOyAvLyB1bmRvY3VtZW50ZWQgY2IoKSBBUEksIG5lZWRlZCBmb3IgY29yZSwgbm90IGZvciBwdWJsaWMgQVBJXG5cbmZ1bmN0aW9uIGRlc3Ryb3koZXJyLCBjYikge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHZhciByZWFkYWJsZURlc3Ryb3llZCA9IHRoaXMuX3JlYWRhYmxlU3RhdGUgJiYgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIHZhciB3cml0YWJsZURlc3Ryb3llZCA9IHRoaXMuX3dyaXRhYmxlU3RhdGUgJiYgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG5cbiAgaWYgKHJlYWRhYmxlRGVzdHJveWVkIHx8IHdyaXRhYmxlRGVzdHJveWVkKSB7XG4gICAgaWYgKGNiKSB7XG4gICAgICBjYihlcnIpO1xuICAgIH0gZWxzZSBpZiAoZXJyKSB7XG4gICAgICBpZiAoIXRoaXMuX3dyaXRhYmxlU3RhdGUpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhlbWl0RXJyb3JOVCwgdGhpcywgZXJyKTtcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMuX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkKSB7XG4gICAgICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkID0gdHJ1ZTtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhlbWl0RXJyb3JOVCwgdGhpcywgZXJyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSAvLyB3ZSBzZXQgZGVzdHJveWVkIHRvIHRydWUgYmVmb3JlIGZpcmluZyBlcnJvciBjYWxsYmFja3MgaW4gb3JkZXJcbiAgLy8gdG8gbWFrZSBpdCByZS1lbnRyYW5jZSBzYWZlIGluIGNhc2UgZGVzdHJveSgpIGlzIGNhbGxlZCB3aXRoaW4gY2FsbGJhY2tzXG5cblxuICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkID0gdHJ1ZTtcbiAgfSAvLyBpZiB0aGlzIGlzIGEgZHVwbGV4IHN0cmVhbSBtYXJrIHRoZSB3cml0YWJsZSBwYXJ0IGFzIGRlc3Ryb3llZCBhcyB3ZWxsXG5cblxuICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdHJ1ZTtcbiAgfVxuXG4gIHRoaXMuX2Rlc3Ryb3koZXJyIHx8IG51bGwsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoIWNiICYmIGVycikge1xuICAgICAgaWYgKCFfdGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgICAgICBwcm9jZXNzLm5leHRUaWNrKGVtaXRFcnJvckFuZENsb3NlTlQsIF90aGlzLCBlcnIpO1xuICAgICAgfSBlbHNlIGlmICghX3RoaXMuX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkKSB7XG4gICAgICAgIF90aGlzLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soZW1pdEVycm9yQW5kQ2xvc2VOVCwgX3RoaXMsIGVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcm9jZXNzLm5leHRUaWNrKGVtaXRDbG9zZU5ULCBfdGhpcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjYikge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhlbWl0Q2xvc2VOVCwgX3RoaXMpO1xuICAgICAgY2IoZXJyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhlbWl0Q2xvc2VOVCwgX3RoaXMpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIGVtaXRFcnJvckFuZENsb3NlTlQoc2VsZiwgZXJyKSB7XG4gIGVtaXRFcnJvck5UKHNlbGYsIGVycik7XG4gIGVtaXRDbG9zZU5UKHNlbGYpO1xufVxuXG5mdW5jdGlvbiBlbWl0Q2xvc2VOVChzZWxmKSB7XG4gIGlmIChzZWxmLl93cml0YWJsZVN0YXRlICYmICFzZWxmLl93cml0YWJsZVN0YXRlLmVtaXRDbG9zZSkgcmV0dXJuO1xuICBpZiAoc2VsZi5fcmVhZGFibGVTdGF0ZSAmJiAhc2VsZi5fcmVhZGFibGVTdGF0ZS5lbWl0Q2xvc2UpIHJldHVybjtcbiAgc2VsZi5lbWl0KCdjbG9zZScpO1xufVxuXG5mdW5jdGlvbiB1bmRlc3Ryb3koKSB7XG4gIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlKSB7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmVuZGVkID0gZmFsc2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmRFbWl0dGVkID0gZmFsc2U7XG4gIH1cblxuICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5lbmRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kaW5nID0gZmFsc2U7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5maW5hbENhbGxlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUucHJlZmluaXNoZWQgPSBmYWxzZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmZpbmlzaGVkID0gZmFsc2U7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0RXJyb3JOVChzZWxmLCBlcnIpIHtcbiAgc2VsZi5lbWl0KCdlcnJvcicsIGVycik7XG59XG5cbmZ1bmN0aW9uIGVycm9yT3JEZXN0cm95KHN0cmVhbSwgZXJyKSB7XG4gIC8vIFdlIGhhdmUgdGVzdHMgdGhhdCByZWx5IG9uIGVycm9ycyBiZWluZyBlbWl0dGVkXG4gIC8vIGluIHRoZSBzYW1lIHRpY2ssIHNvIGNoYW5naW5nIHRoaXMgaXMgc2VtdmVyIG1ham9yLlxuICAvLyBGb3Igbm93IHdoZW4geW91IG9wdC1pbiB0byBhdXRvRGVzdHJveSB3ZSBhbGxvd1xuICAvLyB0aGUgZXJyb3IgdG8gYmUgZW1pdHRlZCBuZXh0VGljay4gSW4gYSBmdXR1cmVcbiAgLy8gc2VtdmVyIG1ham9yIHVwZGF0ZSB3ZSBzaG91bGQgY2hhbmdlIHRoZSBkZWZhdWx0IHRvIHRoaXMuXG4gIHZhciByU3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIHZhciB3U3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIGlmIChyU3RhdGUgJiYgclN0YXRlLmF1dG9EZXN0cm95IHx8IHdTdGF0ZSAmJiB3U3RhdGUuYXV0b0Rlc3Ryb3kpIHN0cmVhbS5kZXN0cm95KGVycik7ZWxzZSBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcnIpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZGVzdHJveTogZGVzdHJveSxcbiAgdW5kZXN0cm95OiB1bmRlc3Ryb3ksXG4gIGVycm9yT3JEZXN0cm95OiBlcnJvck9yRGVzdHJveVxufTsiLCIvLyBQb3J0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbWFmaW50b3NoL2VuZC1vZi1zdHJlYW0gd2l0aFxuLy8gcGVybWlzc2lvbiBmcm9tIHRoZSBhdXRob3IsIE1hdGhpYXMgQnV1cyAoQG1hZmludG9zaCkuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBFUlJfU1RSRUFNX1BSRU1BVFVSRV9DTE9TRSA9IHJlcXVpcmUoJy4uLy4uLy4uL2Vycm9ycycpLmNvZGVzLkVSUl9TVFJFQU1fUFJFTUFUVVJFX0NMT1NFO1xuXG5mdW5jdGlvbiBvbmNlKGNhbGxiYWNrKSB7XG4gIHZhciBjYWxsZWQgPSBmYWxzZTtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoY2FsbGVkKSByZXR1cm47XG4gICAgY2FsbGVkID0gdHJ1ZTtcblxuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG5cbiAgICBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbmZ1bmN0aW9uIGlzUmVxdWVzdChzdHJlYW0pIHtcbiAgcmV0dXJuIHN0cmVhbS5zZXRIZWFkZXIgJiYgdHlwZW9mIHN0cmVhbS5hYm9ydCA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gZW9zKHN0cmVhbSwgb3B0cywgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBvcHRzID09PSAnZnVuY3Rpb24nKSByZXR1cm4gZW9zKHN0cmVhbSwgbnVsbCwgb3B0cyk7XG4gIGlmICghb3B0cykgb3B0cyA9IHt9O1xuICBjYWxsYmFjayA9IG9uY2UoY2FsbGJhY2sgfHwgbm9vcCk7XG4gIHZhciByZWFkYWJsZSA9IG9wdHMucmVhZGFibGUgfHwgb3B0cy5yZWFkYWJsZSAhPT0gZmFsc2UgJiYgc3RyZWFtLnJlYWRhYmxlO1xuICB2YXIgd3JpdGFibGUgPSBvcHRzLndyaXRhYmxlIHx8IG9wdHMud3JpdGFibGUgIT09IGZhbHNlICYmIHN0cmVhbS53cml0YWJsZTtcblxuICB2YXIgb25sZWdhY3lmaW5pc2ggPSBmdW5jdGlvbiBvbmxlZ2FjeWZpbmlzaCgpIHtcbiAgICBpZiAoIXN0cmVhbS53cml0YWJsZSkgb25maW5pc2goKTtcbiAgfTtcblxuICB2YXIgd3JpdGFibGVFbmRlZCA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZSAmJiBzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZmluaXNoZWQ7XG5cbiAgdmFyIG9uZmluaXNoID0gZnVuY3Rpb24gb25maW5pc2goKSB7XG4gICAgd3JpdGFibGUgPSBmYWxzZTtcbiAgICB3cml0YWJsZUVuZGVkID0gdHJ1ZTtcbiAgICBpZiAoIXJlYWRhYmxlKSBjYWxsYmFjay5jYWxsKHN0cmVhbSk7XG4gIH07XG5cbiAgdmFyIHJlYWRhYmxlRW5kZWQgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGUgJiYgc3RyZWFtLl9yZWFkYWJsZVN0YXRlLmVuZEVtaXR0ZWQ7XG5cbiAgdmFyIG9uZW5kID0gZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgcmVhZGFibGUgPSBmYWxzZTtcbiAgICByZWFkYWJsZUVuZGVkID0gdHJ1ZTtcbiAgICBpZiAoIXdyaXRhYmxlKSBjYWxsYmFjay5jYWxsKHN0cmVhbSk7XG4gIH07XG5cbiAgdmFyIG9uZXJyb3IgPSBmdW5jdGlvbiBvbmVycm9yKGVycikge1xuICAgIGNhbGxiYWNrLmNhbGwoc3RyZWFtLCBlcnIpO1xuICB9O1xuXG4gIHZhciBvbmNsb3NlID0gZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICB2YXIgZXJyO1xuXG4gICAgaWYgKHJlYWRhYmxlICYmICFyZWFkYWJsZUVuZGVkKSB7XG4gICAgICBpZiAoIXN0cmVhbS5fcmVhZGFibGVTdGF0ZSB8fCAhc3RyZWFtLl9yZWFkYWJsZVN0YXRlLmVuZGVkKSBlcnIgPSBuZXcgRVJSX1NUUkVBTV9QUkVNQVRVUkVfQ0xPU0UoKTtcbiAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKHN0cmVhbSwgZXJyKTtcbiAgICB9XG5cbiAgICBpZiAod3JpdGFibGUgJiYgIXdyaXRhYmxlRW5kZWQpIHtcbiAgICAgIGlmICghc3RyZWFtLl93cml0YWJsZVN0YXRlIHx8ICFzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZW5kZWQpIGVyciA9IG5ldyBFUlJfU1RSRUFNX1BSRU1BVFVSRV9DTE9TRSgpO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoc3RyZWFtLCBlcnIpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgb25yZXF1ZXN0ID0gZnVuY3Rpb24gb25yZXF1ZXN0KCkge1xuICAgIHN0cmVhbS5yZXEub24oJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgfTtcblxuICBpZiAoaXNSZXF1ZXN0KHN0cmVhbSkpIHtcbiAgICBzdHJlYW0ub24oJ2NvbXBsZXRlJywgb25maW5pc2gpO1xuICAgIHN0cmVhbS5vbignYWJvcnQnLCBvbmNsb3NlKTtcbiAgICBpZiAoc3RyZWFtLnJlcSkgb25yZXF1ZXN0KCk7ZWxzZSBzdHJlYW0ub24oJ3JlcXVlc3QnLCBvbnJlcXVlc3QpO1xuICB9IGVsc2UgaWYgKHdyaXRhYmxlICYmICFzdHJlYW0uX3dyaXRhYmxlU3RhdGUpIHtcbiAgICAvLyBsZWdhY3kgc3RyZWFtc1xuICAgIHN0cmVhbS5vbignZW5kJywgb25sZWdhY3lmaW5pc2gpO1xuICAgIHN0cmVhbS5vbignY2xvc2UnLCBvbmxlZ2FjeWZpbmlzaCk7XG4gIH1cblxuICBzdHJlYW0ub24oJ2VuZCcsIG9uZW5kKTtcbiAgc3RyZWFtLm9uKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gIGlmIChvcHRzLmVycm9yICE9PSBmYWxzZSkgc3RyZWFtLm9uKCdlcnJvcicsIG9uZXJyb3IpO1xuICBzdHJlYW0ub24oJ2Nsb3NlJywgb25jbG9zZSk7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdjb21wbGV0ZScsIG9uZmluaXNoKTtcbiAgICBzdHJlYW0ucmVtb3ZlTGlzdGVuZXIoJ2Fib3J0Jywgb25jbG9zZSk7XG4gICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdyZXF1ZXN0Jywgb25yZXF1ZXN0KTtcbiAgICBpZiAoc3RyZWFtLnJlcSkgc3RyZWFtLnJlcS5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25sZWdhY3lmaW5pc2gpO1xuICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmxlZ2FjeWZpbmlzaCk7XG4gICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlb3M7IiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignUmVhZGFibGUuZnJvbSBpcyBub3QgYXZhaWxhYmxlIGluIHRoZSBicm93c2VyJylcbn07XG4iLCIvLyBQb3J0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbWFmaW50b3NoL3B1bXAgd2l0aFxuLy8gcGVybWlzc2lvbiBmcm9tIHRoZSBhdXRob3IsIE1hdGhpYXMgQnV1cyAoQG1hZmludG9zaCkuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBlb3M7XG5cbmZ1bmN0aW9uIG9uY2UoY2FsbGJhY2spIHtcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmIChjYWxsZWQpIHJldHVybjtcbiAgICBjYWxsZWQgPSB0cnVlO1xuICAgIGNhbGxiYWNrLmFwcGx5KHZvaWQgMCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cblxudmFyIF9yZXF1aXJlJGNvZGVzID0gcmVxdWlyZSgnLi4vLi4vLi4vZXJyb3JzJykuY29kZXMsXG4gICAgRVJSX01JU1NJTkdfQVJHUyA9IF9yZXF1aXJlJGNvZGVzLkVSUl9NSVNTSU5HX0FSR1MsXG4gICAgRVJSX1NUUkVBTV9ERVNUUk9ZRUQgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfU1RSRUFNX0RFU1RST1lFRDtcblxuZnVuY3Rpb24gbm9vcChlcnIpIHtcbiAgLy8gUmV0aHJvdyB0aGUgZXJyb3IgaWYgaXQgZXhpc3RzIHRvIGF2b2lkIHN3YWxsb3dpbmcgaXRcbiAgaWYgKGVycikgdGhyb3cgZXJyO1xufVxuXG5mdW5jdGlvbiBpc1JlcXVlc3Qoc3RyZWFtKSB7XG4gIHJldHVybiBzdHJlYW0uc2V0SGVhZGVyICYmIHR5cGVvZiBzdHJlYW0uYWJvcnQgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGRlc3Ryb3llcihzdHJlYW0sIHJlYWRpbmcsIHdyaXRpbmcsIGNhbGxiYWNrKSB7XG4gIGNhbGxiYWNrID0gb25jZShjYWxsYmFjayk7XG4gIHZhciBjbG9zZWQgPSBmYWxzZTtcbiAgc3RyZWFtLm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtcbiAgICBjbG9zZWQgPSB0cnVlO1xuICB9KTtcbiAgaWYgKGVvcyA9PT0gdW5kZWZpbmVkKSBlb3MgPSByZXF1aXJlKCcuL2VuZC1vZi1zdHJlYW0nKTtcbiAgZW9zKHN0cmVhbSwge1xuICAgIHJlYWRhYmxlOiByZWFkaW5nLFxuICAgIHdyaXRhYmxlOiB3cml0aW5nXG4gIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoZXJyKSByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICBjbG9zZWQgPSB0cnVlO1xuICAgIGNhbGxiYWNrKCk7XG4gIH0pO1xuICB2YXIgZGVzdHJveWVkID0gZmFsc2U7XG4gIHJldHVybiBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKGNsb3NlZCkgcmV0dXJuO1xuICAgIGlmIChkZXN0cm95ZWQpIHJldHVybjtcbiAgICBkZXN0cm95ZWQgPSB0cnVlOyAvLyByZXF1ZXN0LmRlc3Ryb3kganVzdCBkbyAuZW5kIC0gLmFib3J0IGlzIHdoYXQgd2Ugd2FudFxuXG4gICAgaWYgKGlzUmVxdWVzdChzdHJlYW0pKSByZXR1cm4gc3RyZWFtLmFib3J0KCk7XG4gICAgaWYgKHR5cGVvZiBzdHJlYW0uZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykgcmV0dXJuIHN0cmVhbS5kZXN0cm95KCk7XG4gICAgY2FsbGJhY2soZXJyIHx8IG5ldyBFUlJfU1RSRUFNX0RFU1RST1lFRCgncGlwZScpKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2FsbChmbikge1xuICBmbigpO1xufVxuXG5mdW5jdGlvbiBwaXBlKGZyb20sIHRvKSB7XG4gIHJldHVybiBmcm9tLnBpcGUodG8pO1xufVxuXG5mdW5jdGlvbiBwb3BDYWxsYmFjayhzdHJlYW1zKSB7XG4gIGlmICghc3RyZWFtcy5sZW5ndGgpIHJldHVybiBub29wO1xuICBpZiAodHlwZW9mIHN0cmVhbXNbc3RyZWFtcy5sZW5ndGggLSAxXSAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIG5vb3A7XG4gIHJldHVybiBzdHJlYW1zLnBvcCgpO1xufVxuXG5mdW5jdGlvbiBwaXBlbGluZSgpIHtcbiAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIHN0cmVhbXMgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgc3RyZWFtc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgfVxuXG4gIHZhciBjYWxsYmFjayA9IHBvcENhbGxiYWNrKHN0cmVhbXMpO1xuICBpZiAoQXJyYXkuaXNBcnJheShzdHJlYW1zWzBdKSkgc3RyZWFtcyA9IHN0cmVhbXNbMF07XG5cbiAgaWYgKHN0cmVhbXMubGVuZ3RoIDwgMikge1xuICAgIHRocm93IG5ldyBFUlJfTUlTU0lOR19BUkdTKCdzdHJlYW1zJyk7XG4gIH1cblxuICB2YXIgZXJyb3I7XG4gIHZhciBkZXN0cm95cyA9IHN0cmVhbXMubWFwKGZ1bmN0aW9uIChzdHJlYW0sIGkpIHtcbiAgICB2YXIgcmVhZGluZyA9IGkgPCBzdHJlYW1zLmxlbmd0aCAtIDE7XG4gICAgdmFyIHdyaXRpbmcgPSBpID4gMDtcbiAgICByZXR1cm4gZGVzdHJveWVyKHN0cmVhbSwgcmVhZGluZywgd3JpdGluZywgZnVuY3Rpb24gKGVycikge1xuICAgICAgaWYgKCFlcnJvcikgZXJyb3IgPSBlcnI7XG4gICAgICBpZiAoZXJyKSBkZXN0cm95cy5mb3JFYWNoKGNhbGwpO1xuICAgICAgaWYgKHJlYWRpbmcpIHJldHVybjtcbiAgICAgIGRlc3Ryb3lzLmZvckVhY2goY2FsbCk7XG4gICAgICBjYWxsYmFjayhlcnJvcik7XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gc3RyZWFtcy5yZWR1Y2UocGlwZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcGlwZWxpbmU7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgRVJSX0lOVkFMSURfT1BUX1ZBTFVFID0gcmVxdWlyZSgnLi4vLi4vLi4vZXJyb3JzJykuY29kZXMuRVJSX0lOVkFMSURfT1BUX1ZBTFVFO1xuXG5mdW5jdGlvbiBoaWdoV2F0ZXJNYXJrRnJvbShvcHRpb25zLCBpc0R1cGxleCwgZHVwbGV4S2V5KSB7XG4gIHJldHVybiBvcHRpb25zLmhpZ2hXYXRlck1hcmsgIT0gbnVsbCA/IG9wdGlvbnMuaGlnaFdhdGVyTWFyayA6IGlzRHVwbGV4ID8gb3B0aW9uc1tkdXBsZXhLZXldIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gZ2V0SGlnaFdhdGVyTWFyayhzdGF0ZSwgb3B0aW9ucywgZHVwbGV4S2V5LCBpc0R1cGxleCkge1xuICB2YXIgaHdtID0gaGlnaFdhdGVyTWFya0Zyb20ob3B0aW9ucywgaXNEdXBsZXgsIGR1cGxleEtleSk7XG5cbiAgaWYgKGh3bSAhPSBudWxsKSB7XG4gICAgaWYgKCEoaXNGaW5pdGUoaHdtKSAmJiBNYXRoLmZsb29yKGh3bSkgPT09IGh3bSkgfHwgaHdtIDwgMCkge1xuICAgICAgdmFyIG5hbWUgPSBpc0R1cGxleCA/IGR1cGxleEtleSA6ICdoaWdoV2F0ZXJNYXJrJztcbiAgICAgIHRocm93IG5ldyBFUlJfSU5WQUxJRF9PUFRfVkFMVUUobmFtZSwgaHdtKTtcbiAgICB9XG5cbiAgICByZXR1cm4gTWF0aC5mbG9vcihod20pO1xuICB9IC8vIERlZmF1bHQgdmFsdWVcblxuXG4gIHJldHVybiBzdGF0ZS5vYmplY3RNb2RlID8gMTYgOiAxNiAqIDEwMjQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRIaWdoV2F0ZXJNYXJrOiBnZXRIaWdoV2F0ZXJNYXJrXG59OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBpc0VuY29kaW5nID0gQnVmZmVyLmlzRW5jb2RpbmcgfHwgZnVuY3Rpb24gKGVuY29kaW5nKSB7XG4gIGVuY29kaW5nID0gJycgKyBlbmNvZGluZztcbiAgc3dpdGNoIChlbmNvZGluZyAmJiBlbmNvZGluZy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpjYXNlICd1dGY4JzpjYXNlICd1dGYtOCc6Y2FzZSAnYXNjaWknOmNhc2UgJ2JpbmFyeSc6Y2FzZSAnYmFzZTY0JzpjYXNlICd1Y3MyJzpjYXNlICd1Y3MtMic6Y2FzZSAndXRmMTZsZSc6Y2FzZSAndXRmLTE2bGUnOmNhc2UgJ3Jhdyc6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBfbm9ybWFsaXplRW5jb2RpbmcoZW5jKSB7XG4gIGlmICghZW5jKSByZXR1cm4gJ3V0ZjgnO1xuICB2YXIgcmV0cmllZDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuYykge1xuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiAndXRmOCc7XG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gJ3V0ZjE2bGUnO1xuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiAnbGF0aW4xJztcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gZW5jO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKHJldHJpZWQpIHJldHVybjsgLy8gdW5kZWZpbmVkXG4gICAgICAgIGVuYyA9ICgnJyArIGVuYykudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0cmllZCA9IHRydWU7XG4gICAgfVxuICB9XG59O1xuXG4vLyBEbyBub3QgY2FjaGUgYEJ1ZmZlci5pc0VuY29kaW5nYCB3aGVuIGNoZWNraW5nIGVuY29kaW5nIG5hbWVzIGFzIHNvbWVcbi8vIG1vZHVsZXMgbW9ua2V5LXBhdGNoIGl0IHRvIHN1cHBvcnQgYWRkaXRpb25hbCBlbmNvZGluZ3NcbmZ1bmN0aW9uIG5vcm1hbGl6ZUVuY29kaW5nKGVuYykge1xuICB2YXIgbmVuYyA9IF9ub3JtYWxpemVFbmNvZGluZyhlbmMpO1xuICBpZiAodHlwZW9mIG5lbmMgIT09ICdzdHJpbmcnICYmIChCdWZmZXIuaXNFbmNvZGluZyA9PT0gaXNFbmNvZGluZyB8fCAhaXNFbmNvZGluZyhlbmMpKSkgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jKTtcbiAgcmV0dXJuIG5lbmMgfHwgZW5jO1xufVxuXG4vLyBTdHJpbmdEZWNvZGVyIHByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgZWZmaWNpZW50bHkgc3BsaXR0aW5nIGEgc2VyaWVzIG9mXG4vLyBidWZmZXJzIGludG8gYSBzZXJpZXMgb2YgSlMgc3RyaW5ncyB3aXRob3V0IGJyZWFraW5nIGFwYXJ0IG11bHRpLWJ5dGVcbi8vIGNoYXJhY3RlcnMuXG5leHBvcnRzLlN0cmluZ0RlY29kZXIgPSBTdHJpbmdEZWNvZGVyO1xuZnVuY3Rpb24gU3RyaW5nRGVjb2RlcihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gbm9ybWFsaXplRW5jb2RpbmcoZW5jb2RpbmcpO1xuICB2YXIgbmI7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgdGhpcy50ZXh0ID0gdXRmMTZUZXh0O1xuICAgICAgdGhpcy5lbmQgPSB1dGYxNkVuZDtcbiAgICAgIG5iID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgdGhpcy5maWxsTGFzdCA9IHV0ZjhGaWxsTGFzdDtcbiAgICAgIG5iID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICB0aGlzLnRleHQgPSBiYXNlNjRUZXh0O1xuICAgICAgdGhpcy5lbmQgPSBiYXNlNjRFbmQ7XG4gICAgICBuYiA9IDM7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhpcy53cml0ZSA9IHNpbXBsZVdyaXRlO1xuICAgICAgdGhpcy5lbmQgPSBzaW1wbGVFbmQ7XG4gICAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5sYXN0TmVlZCA9IDA7XG4gIHRoaXMubGFzdFRvdGFsID0gMDtcbiAgdGhpcy5sYXN0Q2hhciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShuYik7XG59XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGJ1Zikge1xuICBpZiAoYnVmLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnO1xuICB2YXIgcjtcbiAgdmFyIGk7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSB7XG4gICAgciA9IHRoaXMuZmlsbExhc3QoYnVmKTtcbiAgICBpZiAociA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJyc7XG4gICAgaSA9IHRoaXMubGFzdE5lZWQ7XG4gICAgdGhpcy5sYXN0TmVlZCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgaSA9IDA7XG4gIH1cbiAgaWYgKGkgPCBidWYubGVuZ3RoKSByZXR1cm4gciA/IHIgKyB0aGlzLnRleHQoYnVmLCBpKSA6IHRoaXMudGV4dChidWYsIGkpO1xuICByZXR1cm4gciB8fCAnJztcbn07XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmVuZCA9IHV0ZjhFbmQ7XG5cbi8vIFJldHVybnMgb25seSBjb21wbGV0ZSBjaGFyYWN0ZXJzIGluIGEgQnVmZmVyXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS50ZXh0ID0gdXRmOFRleHQ7XG5cbi8vIEF0dGVtcHRzIHRvIGNvbXBsZXRlIGEgcGFydGlhbCBub24tVVRGLTggY2hhcmFjdGVyIHVzaW5nIGJ5dGVzIGZyb20gYSBCdWZmZXJcblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmZpbGxMYXN0ID0gZnVuY3Rpb24gKGJ1Zikge1xuICBpZiAodGhpcy5sYXN0TmVlZCA8PSBidWYubGVuZ3RoKSB7XG4gICAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkLCAwLCB0aGlzLmxhc3ROZWVkKTtcbiAgICByZXR1cm4gdGhpcy5sYXN0Q2hhci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCB0aGlzLmxhc3RUb3RhbCk7XG4gIH1cbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkLCAwLCBidWYubGVuZ3RoKTtcbiAgdGhpcy5sYXN0TmVlZCAtPSBidWYubGVuZ3RoO1xufTtcblxuLy8gQ2hlY2tzIHRoZSB0eXBlIG9mIGEgVVRGLTggYnl0ZSwgd2hldGhlciBpdCdzIEFTQ0lJLCBhIGxlYWRpbmcgYnl0ZSwgb3IgYVxuLy8gY29udGludWF0aW9uIGJ5dGUuIElmIGFuIGludmFsaWQgYnl0ZSBpcyBkZXRlY3RlZCwgLTIgaXMgcmV0dXJuZWQuXG5mdW5jdGlvbiB1dGY4Q2hlY2tCeXRlKGJ5dGUpIHtcbiAgaWYgKGJ5dGUgPD0gMHg3RikgcmV0dXJuIDA7ZWxzZSBpZiAoYnl0ZSA+PiA1ID09PSAweDA2KSByZXR1cm4gMjtlbHNlIGlmIChieXRlID4+IDQgPT09IDB4MEUpIHJldHVybiAzO2Vsc2UgaWYgKGJ5dGUgPj4gMyA9PT0gMHgxRSkgcmV0dXJuIDQ7XG4gIHJldHVybiBieXRlID4+IDYgPT09IDB4MDIgPyAtMSA6IC0yO1xufVxuXG4vLyBDaGVja3MgYXQgbW9zdCAzIGJ5dGVzIGF0IHRoZSBlbmQgb2YgYSBCdWZmZXIgaW4gb3JkZXIgdG8gZGV0ZWN0IGFuXG4vLyBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyLiBUaGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzICgyLCAzLCBvciA0KVxuLy8gbmVlZGVkIHRvIGNvbXBsZXRlIHRoZSBVVEYtOCBjaGFyYWN0ZXIgKGlmIGFwcGxpY2FibGUpIGFyZSByZXR1cm5lZC5cbmZ1bmN0aW9uIHV0ZjhDaGVja0luY29tcGxldGUoc2VsZiwgYnVmLCBpKSB7XG4gIHZhciBqID0gYnVmLmxlbmd0aCAtIDE7XG4gIGlmIChqIDwgaSkgcmV0dXJuIDA7XG4gIHZhciBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSBzZWxmLmxhc3ROZWVkID0gbmIgLSAxO1xuICAgIHJldHVybiBuYjtcbiAgfVxuICBpZiAoLS1qIDwgaSB8fCBuYiA9PT0gLTIpIHJldHVybiAwO1xuICBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSBzZWxmLmxhc3ROZWVkID0gbmIgLSAyO1xuICAgIHJldHVybiBuYjtcbiAgfVxuICBpZiAoLS1qIDwgaSB8fCBuYiA9PT0gLTIpIHJldHVybiAwO1xuICBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSB7XG4gICAgICBpZiAobmIgPT09IDIpIG5iID0gMDtlbHNlIHNlbGYubGFzdE5lZWQgPSBuYiAtIDM7XG4gICAgfVxuICAgIHJldHVybiBuYjtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy8gVmFsaWRhdGVzIGFzIG1hbnkgY29udGludWF0aW9uIGJ5dGVzIGZvciBhIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyIGFzXG4vLyBuZWVkZWQgb3IgYXJlIGF2YWlsYWJsZS4gSWYgd2Ugc2VlIGEgbm9uLWNvbnRpbnVhdGlvbiBieXRlIHdoZXJlIHdlIGV4cGVjdFxuLy8gb25lLCB3ZSBcInJlcGxhY2VcIiB0aGUgdmFsaWRhdGVkIGNvbnRpbnVhdGlvbiBieXRlcyB3ZSd2ZSBzZWVuIHNvIGZhciB3aXRoXG4vLyBhIHNpbmdsZSBVVEYtOCByZXBsYWNlbWVudCBjaGFyYWN0ZXIgKCdcXHVmZmZkJyksIHRvIG1hdGNoIHY4J3MgVVRGLTggZGVjb2Rpbmdcbi8vIGJlaGF2aW9yLiBUaGUgY29udGludWF0aW9uIGJ5dGUgY2hlY2sgaXMgaW5jbHVkZWQgdGhyZWUgdGltZXMgaW4gdGhlIGNhc2Vcbi8vIHdoZXJlIGFsbCBvZiB0aGUgY29udGludWF0aW9uIGJ5dGVzIGZvciBhIGNoYXJhY3RlciBleGlzdCBpbiB0aGUgc2FtZSBidWZmZXIuXG4vLyBJdCBpcyBhbHNvIGRvbmUgdGhpcyB3YXkgYXMgYSBzbGlnaHQgcGVyZm9ybWFuY2UgaW5jcmVhc2UgaW5zdGVhZCBvZiB1c2luZyBhXG4vLyBsb29wLlxuZnVuY3Rpb24gdXRmOENoZWNrRXh0cmFCeXRlcyhzZWxmLCBidWYsIHApIHtcbiAgaWYgKChidWZbMF0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgIHNlbGYubGFzdE5lZWQgPSAwO1xuICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gIH1cbiAgaWYgKHNlbGYubGFzdE5lZWQgPiAxICYmIGJ1Zi5sZW5ndGggPiAxKSB7XG4gICAgaWYgKChidWZbMV0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgICAgc2VsZi5sYXN0TmVlZCA9IDE7XG4gICAgICByZXR1cm4gJ1xcdWZmZmQnO1xuICAgIH1cbiAgICBpZiAoc2VsZi5sYXN0TmVlZCA+IDIgJiYgYnVmLmxlbmd0aCA+IDIpIHtcbiAgICAgIGlmICgoYnVmWzJdICYgMHhDMCkgIT09IDB4ODApIHtcbiAgICAgICAgc2VsZi5sYXN0TmVlZCA9IDI7XG4gICAgICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIEF0dGVtcHRzIHRvIGNvbXBsZXRlIGEgbXVsdGktYnl0ZSBVVEYtOCBjaGFyYWN0ZXIgdXNpbmcgYnl0ZXMgZnJvbSBhIEJ1ZmZlci5cbmZ1bmN0aW9uIHV0ZjhGaWxsTGFzdChidWYpIHtcbiAgdmFyIHAgPSB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQ7XG4gIHZhciByID0gdXRmOENoZWNrRXh0cmFCeXRlcyh0aGlzLCBidWYsIHApO1xuICBpZiAociAhPT0gdW5kZWZpbmVkKSByZXR1cm4gcjtcbiAgaWYgKHRoaXMubGFzdE5lZWQgPD0gYnVmLmxlbmd0aCkge1xuICAgIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHAsIDAsIHRoaXMubGFzdE5lZWQpO1xuICAgIHJldHVybiB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIHRoaXMubGFzdFRvdGFsKTtcbiAgfVxuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCBwLCAwLCBidWYubGVuZ3RoKTtcbiAgdGhpcy5sYXN0TmVlZCAtPSBidWYubGVuZ3RoO1xufVxuXG4vLyBSZXR1cm5zIGFsbCBjb21wbGV0ZSBVVEYtOCBjaGFyYWN0ZXJzIGluIGEgQnVmZmVyLiBJZiB0aGUgQnVmZmVyIGVuZGVkIG9uIGFcbi8vIHBhcnRpYWwgY2hhcmFjdGVyLCB0aGUgY2hhcmFjdGVyJ3MgYnl0ZXMgYXJlIGJ1ZmZlcmVkIHVudGlsIHRoZSByZXF1aXJlZFxuLy8gbnVtYmVyIG9mIGJ5dGVzIGFyZSBhdmFpbGFibGUuXG5mdW5jdGlvbiB1dGY4VGV4dChidWYsIGkpIHtcbiAgdmFyIHRvdGFsID0gdXRmOENoZWNrSW5jb21wbGV0ZSh0aGlzLCBidWYsIGkpO1xuICBpZiAoIXRoaXMubGFzdE5lZWQpIHJldHVybiBidWYudG9TdHJpbmcoJ3V0ZjgnLCBpKTtcbiAgdGhpcy5sYXN0VG90YWwgPSB0b3RhbDtcbiAgdmFyIGVuZCA9IGJ1Zi5sZW5ndGggLSAodG90YWwgLSB0aGlzLmxhc3ROZWVkKTtcbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgMCwgZW5kKTtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmOCcsIGksIGVuZCk7XG59XG5cbi8vIEZvciBVVEYtOCwgYSByZXBsYWNlbWVudCBjaGFyYWN0ZXIgaXMgYWRkZWQgd2hlbiBlbmRpbmcgb24gYSBwYXJ0aWFsXG4vLyBjaGFyYWN0ZXIuXG5mdW5jdGlvbiB1dGY4RW5kKGJ1Zikge1xuICB2YXIgciA9IGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSByZXR1cm4gciArICdcXHVmZmZkJztcbiAgcmV0dXJuIHI7XG59XG5cbi8vIFVURi0xNkxFIHR5cGljYWxseSBuZWVkcyB0d28gYnl0ZXMgcGVyIGNoYXJhY3RlciwgYnV0IGV2ZW4gaWYgd2UgaGF2ZSBhbiBldmVuXG4vLyBudW1iZXIgb2YgYnl0ZXMgYXZhaWxhYmxlLCB3ZSBuZWVkIHRvIGNoZWNrIGlmIHdlIGVuZCBvbiBhIGxlYWRpbmcvaGlnaFxuLy8gc3Vycm9nYXRlLiBJbiB0aGF0IGNhc2UsIHdlIG5lZWQgdG8gd2FpdCBmb3IgdGhlIG5leHQgdHdvIGJ5dGVzIGluIG9yZGVyIHRvXG4vLyBkZWNvZGUgdGhlIGxhc3QgY2hhcmFjdGVyIHByb3Blcmx5LlxuZnVuY3Rpb24gdXRmMTZUZXh0KGJ1ZiwgaSkge1xuICBpZiAoKGJ1Zi5sZW5ndGggLSBpKSAlIDIgPT09IDApIHtcbiAgICB2YXIgciA9IGJ1Zi50b1N0cmluZygndXRmMTZsZScsIGkpO1xuICAgIGlmIChyKSB7XG4gICAgICB2YXIgYyA9IHIuY2hhckNvZGVBdChyLmxlbmd0aCAtIDEpO1xuICAgICAgaWYgKGMgPj0gMHhEODAwICYmIGMgPD0gMHhEQkZGKSB7XG4gICAgICAgIHRoaXMubGFzdE5lZWQgPSAyO1xuICAgICAgICB0aGlzLmxhc3RUb3RhbCA9IDQ7XG4gICAgICAgIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDJdO1xuICAgICAgICB0aGlzLmxhc3RDaGFyWzFdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgICAgICAgcmV0dXJuIHIuc2xpY2UoMCwgLTEpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfVxuICB0aGlzLmxhc3ROZWVkID0gMTtcbiAgdGhpcy5sYXN0VG90YWwgPSAyO1xuICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmMTZsZScsIGksIGJ1Zi5sZW5ndGggLSAxKTtcbn1cblxuLy8gRm9yIFVURi0xNkxFIHdlIGRvIG5vdCBleHBsaWNpdGx5IGFwcGVuZCBzcGVjaWFsIHJlcGxhY2VtZW50IGNoYXJhY3RlcnMgaWYgd2Vcbi8vIGVuZCBvbiBhIHBhcnRpYWwgY2hhcmFjdGVyLCB3ZSBzaW1wbHkgbGV0IHY4IGhhbmRsZSB0aGF0LlxuZnVuY3Rpb24gdXRmMTZFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHtcbiAgICB2YXIgZW5kID0gdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkO1xuICAgIHJldHVybiByICsgdGhpcy5sYXN0Q2hhci50b1N0cmluZygndXRmMTZsZScsIDAsIGVuZCk7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRleHQoYnVmLCBpKSB7XG4gIHZhciBuID0gKGJ1Zi5sZW5ndGggLSBpKSAlIDM7XG4gIGlmIChuID09PSAwKSByZXR1cm4gYnVmLnRvU3RyaW5nKCdiYXNlNjQnLCBpKTtcbiAgdGhpcy5sYXN0TmVlZCA9IDMgLSBuO1xuICB0aGlzLmxhc3RUb3RhbCA9IDM7XG4gIGlmIChuID09PSAxKSB7XG4gICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMl07XG4gICAgdGhpcy5sYXN0Q2hhclsxXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIH1cbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygnYmFzZTY0JywgaSwgYnVmLmxlbmd0aCAtIG4pO1xufVxuXG5mdW5jdGlvbiBiYXNlNjRFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHJldHVybiByICsgdGhpcy5sYXN0Q2hhci50b1N0cmluZygnYmFzZTY0JywgMCwgMyAtIHRoaXMubGFzdE5lZWQpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gUGFzcyBieXRlcyBvbiB0aHJvdWdoIGZvciBzaW5nbGUtYnl0ZSBlbmNvZGluZ3MgKGUuZy4gYXNjaWksIGxhdGluMSwgaGV4KVxuZnVuY3Rpb24gc2ltcGxlV3JpdGUoYnVmKSB7XG4gIHJldHVybiBidWYudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG59XG5cbmZ1bmN0aW9uIHNpbXBsZUVuZChidWYpIHtcbiAgcmV0dXJuIGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG59IiwidmFyIG5leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy9icm93c2VyLmpzJykubmV4dFRpY2s7XG52YXIgYXBwbHkgPSBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHk7XG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgaW1tZWRpYXRlSWRzID0ge307XG52YXIgbmV4dEltbWVkaWF0ZUlkID0gMDtcblxuLy8gRE9NIEFQSXMsIGZvciBjb21wbGV0ZW5lc3NcblxuZXhwb3J0cy5zZXRUaW1lb3V0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgVGltZW91dChhcHBseS5jYWxsKHNldFRpbWVvdXQsIHdpbmRvdywgYXJndW1lbnRzKSwgY2xlYXJUaW1lb3V0KTtcbn07XG5leHBvcnRzLnNldEludGVydmFsID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgVGltZW91dChhcHBseS5jYWxsKHNldEludGVydmFsLCB3aW5kb3csIGFyZ3VtZW50cyksIGNsZWFySW50ZXJ2YWwpO1xufTtcbmV4cG9ydHMuY2xlYXJUaW1lb3V0ID1cbmV4cG9ydHMuY2xlYXJJbnRlcnZhbCA9IGZ1bmN0aW9uKHRpbWVvdXQpIHsgdGltZW91dC5jbG9zZSgpOyB9O1xuXG5mdW5jdGlvbiBUaW1lb3V0KGlkLCBjbGVhckZuKSB7XG4gIHRoaXMuX2lkID0gaWQ7XG4gIHRoaXMuX2NsZWFyRm4gPSBjbGVhckZuO1xufVxuVGltZW91dC5wcm90b3R5cGUudW5yZWYgPSBUaW1lb3V0LnByb3RvdHlwZS5yZWYgPSBmdW5jdGlvbigpIHt9O1xuVGltZW91dC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fY2xlYXJGbi5jYWxsKHdpbmRvdywgdGhpcy5faWQpO1xufTtcblxuLy8gRG9lcyBub3Qgc3RhcnQgdGhlIHRpbWUsIGp1c3Qgc2V0cyB1cCB0aGUgbWVtYmVycyBuZWVkZWQuXG5leHBvcnRzLmVucm9sbCA9IGZ1bmN0aW9uKGl0ZW0sIG1zZWNzKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcbiAgaXRlbS5faWRsZVRpbWVvdXQgPSBtc2Vjcztcbn07XG5cbmV4cG9ydHMudW5lbnJvbGwgPSBmdW5jdGlvbihpdGVtKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcbiAgaXRlbS5faWRsZVRpbWVvdXQgPSAtMTtcbn07XG5cbmV4cG9ydHMuX3VucmVmQWN0aXZlID0gZXhwb3J0cy5hY3RpdmUgPSBmdW5jdGlvbihpdGVtKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcblxuICB2YXIgbXNlY3MgPSBpdGVtLl9pZGxlVGltZW91dDtcbiAgaWYgKG1zZWNzID49IDApIHtcbiAgICBpdGVtLl9pZGxlVGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiBvblRpbWVvdXQoKSB7XG4gICAgICBpZiAoaXRlbS5fb25UaW1lb3V0KVxuICAgICAgICBpdGVtLl9vblRpbWVvdXQoKTtcbiAgICB9LCBtc2Vjcyk7XG4gIH1cbn07XG5cbi8vIFRoYXQncyBub3QgaG93IG5vZGUuanMgaW1wbGVtZW50cyBpdCBidXQgdGhlIGV4cG9zZWQgYXBpIGlzIHRoZSBzYW1lLlxuZXhwb3J0cy5zZXRJbW1lZGlhdGUgPSB0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSBcImZ1bmN0aW9uXCIgPyBzZXRJbW1lZGlhdGUgOiBmdW5jdGlvbihmbikge1xuICB2YXIgaWQgPSBuZXh0SW1tZWRpYXRlSWQrKztcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IGZhbHNlIDogc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gIGltbWVkaWF0ZUlkc1tpZF0gPSB0cnVlO1xuXG4gIG5leHRUaWNrKGZ1bmN0aW9uIG9uTmV4dFRpY2soKSB7XG4gICAgaWYgKGltbWVkaWF0ZUlkc1tpZF0pIHtcbiAgICAgIC8vIGZuLmNhbGwoKSBpcyBmYXN0ZXIgc28gd2Ugb3B0aW1pemUgZm9yIHRoZSBjb21tb24gdXNlLWNhc2VcbiAgICAgIC8vIEBzZWUgaHR0cDovL2pzcGVyZi5jb20vY2FsbC1hcHBseS1zZWd1XG4gICAgICBpZiAoYXJncykge1xuICAgICAgICBmbi5hcHBseShudWxsLCBhcmdzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZuLmNhbGwobnVsbCk7XG4gICAgICB9XG4gICAgICAvLyBQcmV2ZW50IGlkcyBmcm9tIGxlYWtpbmdcbiAgICAgIGV4cG9ydHMuY2xlYXJJbW1lZGlhdGUoaWQpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGlkO1xufTtcblxuZXhwb3J0cy5jbGVhckltbWVkaWF0ZSA9IHR5cGVvZiBjbGVhckltbWVkaWF0ZSA9PT0gXCJmdW5jdGlvblwiID8gY2xlYXJJbW1lZGlhdGUgOiBmdW5jdGlvbihpZCkge1xuICBkZWxldGUgaW1tZWRpYXRlSWRzW2lkXTtcbn07IiwiXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZGVwcmVjYXRlO1xuXG4vKipcbiAqIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4gKiBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2Uubm9EZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudGhyb3dEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCB0aHJvdyBhbiBFcnJvciB3aGVuIGludm9rZWQuXG4gKlxuICogSWYgYGxvY2FsU3RvcmFnZS50cmFjZURlcHJlY2F0aW9uID0gdHJ1ZWAgaXMgc2V0LCB0aGVuIGRlcHJlY2F0ZWQgZnVuY3Rpb25zXG4gKiB3aWxsIGludm9rZSBgY29uc29sZS50cmFjZSgpYCBpbnN0ZWFkIG9mIGBjb25zb2xlLmVycm9yKClgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGRlcHJlY2F0ZVxuICogQHBhcmFtIHtTdHJpbmd9IG1zZyAtIHRoZSBzdHJpbmcgdG8gcHJpbnQgdG8gdGhlIGNvbnNvbGUgd2hlbiBgZm5gIGlzIGludm9rZWRcbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gYSBuZXcgXCJkZXByZWNhdGVkXCIgdmVyc2lvbiBvZiBgZm5gXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZSAoZm4sIG1zZykge1xuICBpZiAoY29uZmlnKCdub0RlcHJlY2F0aW9uJykpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChjb25maWcoJ3Rocm93RGVwcmVjYXRpb24nKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAoY29uZmlnKCd0cmFjZURlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgY29uc29sZS50cmFjZShtc2cpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufVxuXG4vKipcbiAqIENoZWNrcyBgbG9jYWxTdG9yYWdlYCBmb3IgYm9vbGVhbiB2YWx1ZXMgZm9yIHRoZSBnaXZlbiBgbmFtZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm5zIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gY29uZmlnIChuYW1lKSB7XG4gIC8vIGFjY2Vzc2luZyBnbG9iYWwubG9jYWxTdG9yYWdlIGNhbiB0cmlnZ2VyIGEgRE9NRXhjZXB0aW9uIGluIHNhbmRib3hlZCBpZnJhbWVzXG4gIHRyeSB7XG4gICAgaWYgKCFnbG9iYWwubG9jYWxTdG9yYWdlKSByZXR1cm4gZmFsc2U7XG4gIH0gY2F0Y2ggKF8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHZhbCA9IGdsb2JhbC5sb2NhbFN0b3JhZ2VbbmFtZV07XG4gIGlmIChudWxsID09IHZhbCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gU3RyaW5nKHZhbCkudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnO1xufVxuIiwiLyoqXG4qIFBhbnpvb20gZm9yIHBhbm5pbmcgYW5kIHpvb21pbmcgZWxlbWVudHMgdXNpbmcgQ1NTIHRyYW5zZm9ybXNcbiogQ29weXJpZ2h0IFRpbW15IFdpbGxpc29uIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiogaHR0cHM6Ly9naXRodWIuY29tL3RpbW15d2lsL3Bhbnpvb20vYmxvYi9tYXN0ZXIvTUlULUxpY2Vuc2UudHh0XG4qL1xuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG4gICAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgICAoZ2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwuUGFuem9vbSA9IGZhY3RvcnkoKSk7XG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuICAgIC8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gICAgQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG4gICAgUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbiAgICBwdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG4gICAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG4gICAgUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbiAgICBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbiAgICBJTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuICAgIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbiAgICBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcbiAgICBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuXHJcbiAgICB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB0O1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbiAgICB9O1xuXG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tdmFyICovXG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAvLyBTdXBwb3J0OiBJRTExIG9ubHlcbiAgICAgIGlmICh3aW5kb3cuTm9kZUxpc3QgJiYgIU5vZGVMaXN0LnByb3RvdHlwZS5mb3JFYWNoKSB7XG4gICAgICAgIE5vZGVMaXN0LnByb3RvdHlwZS5mb3JFYWNoID0gQXJyYXkucHJvdG90eXBlLmZvckVhY2g7XG4gICAgICB9XG4gICAgICAvLyBTdXBwb3J0OiBJRTExIG9ubHlcbiAgICAgIC8vIEN1c3RvbUV2ZW50IGlzIGFuIG9iamVjdCBpbnN0ZWFkIG9mIGEgY29uc3RydWN0b3JcbiAgICAgIGlmICh0eXBlb2Ygd2luZG93LkN1c3RvbUV2ZW50ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHdpbmRvdy5DdXN0b21FdmVudCA9IGZ1bmN0aW9uIEN1c3RvbUV2ZW50KGV2ZW50LCBwYXJhbXMpIHtcbiAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMgfHwgeyBidWJibGVzOiBmYWxzZSwgY2FuY2VsYWJsZTogZmFsc2UsIGRldGFpbDogbnVsbCB9O1xuICAgICAgICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTtcbiAgICAgICAgICBldnQuaW5pdEN1c3RvbUV2ZW50KGV2ZW50LCBwYXJhbXMuYnViYmxlcywgcGFyYW1zLmNhbmNlbGFibGUsIHBhcmFtcy5kZXRhaWwpO1xuICAgICAgICAgIHJldHVybiBldnRcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcclxuICAgICAqIFV0aWxpdGVzIGZvciB3b3JraW5nIHdpdGggbXVsdGlwbGUgcG9pbnRlciBldmVudHNcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZmluZEV2ZW50SW5kZXgocG9pbnRlcnMsIGV2ZW50KSB7XHJcbiAgICAgICAgdmFyIGkgPSBwb2ludGVycy5sZW5ndGg7XHJcbiAgICAgICAgd2hpbGUgKGktLSkge1xyXG4gICAgICAgICAgICBpZiAocG9pbnRlcnNbaV0ucG9pbnRlcklkID09PSBldmVudC5wb2ludGVySWQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAtMTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGFkZFBvaW50ZXIocG9pbnRlcnMsIGV2ZW50KSB7XHJcbiAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgLy8gQWRkIHRvdWNoZXMgaWYgYXBwbGljYWJsZVxyXG4gICAgICAgIGlmIChldmVudC50b3VjaGVzKSB7XHJcbiAgICAgICAgICAgIGkgPSAwO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gZXZlbnQudG91Y2hlczsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgIHZhciB0b3VjaCA9IF9hW19pXTtcclxuICAgICAgICAgICAgICAgIHRvdWNoLnBvaW50ZXJJZCA9IGkrKztcclxuICAgICAgICAgICAgICAgIGFkZFBvaW50ZXIocG9pbnRlcnMsIHRvdWNoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGkgPSBmaW5kRXZlbnRJbmRleChwb2ludGVycywgZXZlbnQpO1xyXG4gICAgICAgIC8vIFVwZGF0ZSBpZiBhbHJlYWR5IHByZXNlbnRcclxuICAgICAgICBpZiAoaSA+IC0xKSB7XHJcbiAgICAgICAgICAgIHBvaW50ZXJzLnNwbGljZShpLCAxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcG9pbnRlcnMucHVzaChldmVudCk7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiByZW1vdmVQb2ludGVyKHBvaW50ZXJzLCBldmVudCkge1xyXG4gICAgICAgIC8vIEFkZCB0b3VjaGVzIGlmIGFwcGxpY2FibGVcclxuICAgICAgICBpZiAoZXZlbnQudG91Y2hlcykge1xyXG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIHRvdWNoZXNcclxuICAgICAgICAgICAgd2hpbGUgKHBvaW50ZXJzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgcG9pbnRlcnMucG9wKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgaSA9IGZpbmRFdmVudEluZGV4KHBvaW50ZXJzLCBldmVudCk7XHJcbiAgICAgICAgaWYgKGkgPiAtMSkge1xyXG4gICAgICAgICAgICBwb2ludGVycy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxjdWxhdGVzIGEgY2VudGVyIHBvaW50IGJldHdlZW5cclxuICAgICAqIHRoZSBnaXZlbiBwb2ludGVyIGV2ZW50cywgZm9yIHBhbm5pbmdcclxuICAgICAqIHdpdGggbXVsdGlwbGUgcG9pbnRlcnMuXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGdldE1pZGRsZShwb2ludGVycykge1xyXG4gICAgICAgIC8vIENvcHkgdG8gYXZvaWQgY2hhbmdpbmcgYnkgcmVmZXJlbmNlXHJcbiAgICAgICAgcG9pbnRlcnMgPSBwb2ludGVycy5zbGljZSgwKTtcclxuICAgICAgICB2YXIgZXZlbnQxID0gcG9pbnRlcnMucG9wKCk7XHJcbiAgICAgICAgdmFyIGV2ZW50MjtcclxuICAgICAgICB3aGlsZSAoKGV2ZW50MiA9IHBvaW50ZXJzLnBvcCgpKSkge1xyXG4gICAgICAgICAgICBldmVudDEgPSB7XHJcbiAgICAgICAgICAgICAgICBjbGllbnRYOiAoZXZlbnQyLmNsaWVudFggLSBldmVudDEuY2xpZW50WCkgLyAyICsgZXZlbnQxLmNsaWVudFgsXHJcbiAgICAgICAgICAgICAgICBjbGllbnRZOiAoZXZlbnQyLmNsaWVudFkgLSBldmVudDEuY2xpZW50WSkgLyAyICsgZXZlbnQxLmNsaWVudFlcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGV2ZW50MTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0d28gcG9pbnRzXHJcbiAgICAgKiBmb3IgcGluY2ggem9vbWluZy5cclxuICAgICAqIExpbWl0cyB0byB0aGUgZmlyc3QgMlxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBnZXREaXN0YW5jZShwb2ludGVycykge1xyXG4gICAgICAgIGlmIChwb2ludGVycy5sZW5ndGggPCAyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgZXZlbnQxID0gcG9pbnRlcnNbMF07XHJcbiAgICAgICAgdmFyIGV2ZW50MiA9IHBvaW50ZXJzWzFdO1xyXG4gICAgICAgIHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3coTWF0aC5hYnMoZXZlbnQyLmNsaWVudFggLSBldmVudDEuY2xpZW50WCksIDIpICtcclxuICAgICAgICAgICAgTWF0aC5wb3coTWF0aC5hYnMoZXZlbnQyLmNsaWVudFkgLSBldmVudDEuY2xpZW50WSksIDIpKTtcclxuICAgIH1cblxuICAgIHZhciBldmVudHMgPSB7XHJcbiAgICAgICAgZG93bjogJ21vdXNlZG93bicsXHJcbiAgICAgICAgbW92ZTogJ21vdXNlbW92ZScsXHJcbiAgICAgICAgdXA6ICdtb3VzZXVwIG1vdXNlbGVhdmUnXHJcbiAgICB9O1xyXG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cuUG9pbnRlckV2ZW50ID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgIGV2ZW50cyA9IHtcclxuICAgICAgICAgICAgICAgIGRvd246ICdwb2ludGVyZG93bicsXHJcbiAgICAgICAgICAgICAgICBtb3ZlOiAncG9pbnRlcm1vdmUnLFxyXG4gICAgICAgICAgICAgICAgdXA6ICdwb2ludGVydXAgcG9pbnRlcmxlYXZlIHBvaW50ZXJjYW5jZWwnXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cuVG91Y2hFdmVudCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICBldmVudHMgPSB7XHJcbiAgICAgICAgICAgICAgICBkb3duOiAndG91Y2hzdGFydCcsXHJcbiAgICAgICAgICAgICAgICBtb3ZlOiAndG91Y2htb3ZlJyxcclxuICAgICAgICAgICAgICAgIHVwOiAndG91Y2hlbmQgdG91Y2hjYW5jZWwnXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gb25Qb2ludGVyKGV2ZW50LCBlbGVtLCBoYW5kbGVyLCBldmVudE9wdHMpIHtcclxuICAgICAgICBldmVudHNbZXZlbnRdLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xyXG4gICAgICAgICAgICBlbGVtLmFkZEV2ZW50TGlzdGVuZXIobmFtZSwgaGFuZGxlciwgZXZlbnRPcHRzKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGRlc3Ryb3lQb2ludGVyKGV2ZW50LCBlbGVtLCBoYW5kbGVyKSB7XHJcbiAgICAgICAgZXZlbnRzW2V2ZW50XS5zcGxpdCgnICcpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcclxuICAgICAgICAgICAgZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyKG5hbWUsIGhhbmRsZXIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxuXG4gICAgdmFyIGlzSUUgPSB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmICEhZG9jdW1lbnQuZG9jdW1lbnRNb2RlO1xyXG4gICAgLyoqXHJcbiAgICAgKiBMYXp5IGNyZWF0aW9uIG9mIGEgQ1NTIHN0eWxlIGRlY2xhcmF0aW9uXHJcbiAgICAgKi9cclxuICAgIHZhciBkaXZTdHlsZTtcclxuICAgIGZ1bmN0aW9uIGNyZWF0ZVN0eWxlKCkge1xyXG4gICAgICAgIGlmIChkaXZTdHlsZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZGl2U3R5bGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAoZGl2U3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKS5zdHlsZSk7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFByb3BlciBwcmVmaXhpbmcgZm9yIGNyb3NzLWJyb3dzZXIgY29tcGF0aWJpbGl0eVxyXG4gICAgICovXHJcbiAgICB2YXIgcHJlZml4ZXMgPSBbJ3dlYmtpdCcsICdtb3onLCAnbXMnXTtcclxuICAgIHZhciBwcmVmaXhDYWNoZSA9IHt9O1xyXG4gICAgZnVuY3Rpb24gZ2V0UHJlZml4ZWROYW1lKG5hbWUpIHtcclxuICAgICAgICBpZiAocHJlZml4Q2FjaGVbbmFtZV0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHByZWZpeENhY2hlW25hbWVdO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgZGl2U3R5bGUgPSBjcmVhdGVTdHlsZSgpO1xyXG4gICAgICAgIGlmIChuYW1lIGluIGRpdlN0eWxlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAocHJlZml4Q2FjaGVbbmFtZV0gPSBuYW1lKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGNhcE5hbWUgPSBuYW1lWzBdLnRvVXBwZXJDYXNlKCkgKyBuYW1lLnNsaWNlKDEpO1xyXG4gICAgICAgIHZhciBpID0gcHJlZml4ZXMubGVuZ3RoO1xyXG4gICAgICAgIHdoaWxlIChpLS0pIHtcclxuICAgICAgICAgICAgdmFyIHByZWZpeGVkTmFtZSA9IFwiXCIgKyBwcmVmaXhlc1tpXSArIGNhcE5hbWU7XHJcbiAgICAgICAgICAgIGlmIChwcmVmaXhlZE5hbWUgaW4gZGl2U3R5bGUpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAocHJlZml4Q2FjaGVbbmFtZV0gPSBwcmVmaXhlZE5hbWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIGEgc3R5bGUgdmFsdWUgZXhwZWN0ZWQgdG8gYmUgYSBudW1iZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZ2V0Q1NTTnVtKG5hbWUsIHN0eWxlKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhcnNlRmxvYXQoc3R5bGVbZ2V0UHJlZml4ZWROYW1lKG5hbWUpXSkgfHwgMDtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGdldEJveFN0eWxlKGVsZW0sIG5hbWUsIHN0eWxlKSB7XHJcbiAgICAgICAgaWYgKHN0eWxlID09PSB2b2lkIDApIHsgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtKTsgfVxyXG4gICAgICAgIC8vIFN1cHBvcnQ6IEZGIDY4K1xyXG4gICAgICAgIC8vIEZpcmVmb3ggcmVxdWlyZXMgc3BlY2lmaWNpdHkgZm9yIGJvcmRlclxyXG4gICAgICAgIHZhciBzdWZmaXggPSBuYW1lID09PSAnYm9yZGVyJyA/ICdXaWR0aCcgOiAnJztcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBsZWZ0OiBnZXRDU1NOdW0obmFtZSArIFwiTGVmdFwiICsgc3VmZml4LCBzdHlsZSksXHJcbiAgICAgICAgICAgIHJpZ2h0OiBnZXRDU1NOdW0obmFtZSArIFwiUmlnaHRcIiArIHN1ZmZpeCwgc3R5bGUpLFxyXG4gICAgICAgICAgICB0b3A6IGdldENTU051bShuYW1lICsgXCJUb3BcIiArIHN1ZmZpeCwgc3R5bGUpLFxyXG4gICAgICAgICAgICBib3R0b206IGdldENTU051bShuYW1lICsgXCJCb3R0b21cIiArIHN1ZmZpeCwgc3R5bGUpXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogU2V0IGEgc3R5bGUgdXNpbmcgdGhlIHByb3Blcmx5IHByZWZpeGVkIG5hbWVcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gc2V0U3R5bGUoZWxlbSwgbmFtZSwgdmFsdWUpIHtcclxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxyXG4gICAgICAgIGVsZW0uc3R5bGVbZ2V0UHJlZml4ZWROYW1lKG5hbWUpXSA9IHZhbHVlO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3RzIHRoZSB0cmFuc2l0aW9uIGZyb20gcGFuem9vbSBvcHRpb25zXHJcbiAgICAgKiBhbmQgdGFrZXMgY2FyZSBvZiBwcmVmaXhpbmcgdGhlIHRyYW5zaXRpb24gYW5kIHRyYW5zZm9ybVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBzZXRUcmFuc2l0aW9uKGVsZW0sIG9wdGlvbnMpIHtcclxuICAgICAgICB2YXIgdHJhbnNmb3JtID0gZ2V0UHJlZml4ZWROYW1lKCd0cmFuc2Zvcm0nKTtcclxuICAgICAgICBzZXRTdHlsZShlbGVtLCAndHJhbnNpdGlvbicsIHRyYW5zZm9ybSArIFwiIFwiICsgb3B0aW9ucy5kdXJhdGlvbiArIFwibXMgXCIgKyBvcHRpb25zLmVhc2luZyk7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFNldCB0aGUgdHJhbnNmb3JtIHVzaW5nIHRoZSBwcm9wZXIgcHJlZml4XHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHNldFRyYW5zZm9ybShlbGVtLCBfYSwgX29wdGlvbnMpIHtcclxuICAgICAgICB2YXIgeCA9IF9hLngsIHkgPSBfYS55LCBzY2FsZSA9IF9hLnNjYWxlLCBpc1NWRyA9IF9hLmlzU1ZHO1xyXG4gICAgICAgIHNldFN0eWxlKGVsZW0sICd0cmFuc2Zvcm0nLCBcInNjYWxlKFwiICsgc2NhbGUgKyBcIikgdHJhbnNsYXRlKFwiICsgeCArIFwicHgsIFwiICsgeSArIFwicHgpXCIpO1xyXG4gICAgICAgIGlmIChpc1NWRyAmJiBpc0lFKSB7XHJcbiAgICAgICAgICAgIHZhciBtYXRyaXhWYWx1ZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW0pLmdldFByb3BlcnR5VmFsdWUoJ3RyYW5zZm9ybScpO1xyXG4gICAgICAgICAgICBlbGVtLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywgbWF0cml4VmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogRGltZW5zaW9ucyB1c2VkIGluIGNvbnRhaW5tZW50IGFuZCBmb2NhbCBwb2ludCB6b29taW5nXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGdldERpbWVuc2lvbnMoZWxlbSkge1xyXG4gICAgICAgIHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7XHJcbiAgICAgICAgdmFyIHN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbSk7XHJcbiAgICAgICAgdmFyIHBhcmVudFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUocGFyZW50KTtcclxuICAgICAgICB2YXIgcmVjdEVsZW0gPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgIHZhciByZWN0UGFyZW50ID0gcGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGVsZW06IHtcclxuICAgICAgICAgICAgICAgIHN0eWxlOiBzdHlsZSxcclxuICAgICAgICAgICAgICAgIHdpZHRoOiByZWN0RWxlbS53aWR0aCxcclxuICAgICAgICAgICAgICAgIGhlaWdodDogcmVjdEVsZW0uaGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgdG9wOiByZWN0RWxlbS50b3AsXHJcbiAgICAgICAgICAgICAgICBib3R0b206IHJlY3RFbGVtLmJvdHRvbSxcclxuICAgICAgICAgICAgICAgIGxlZnQ6IHJlY3RFbGVtLmxlZnQsXHJcbiAgICAgICAgICAgICAgICByaWdodDogcmVjdEVsZW0ucmlnaHQsXHJcbiAgICAgICAgICAgICAgICBtYXJnaW46IGdldEJveFN0eWxlKGVsZW0sICdtYXJnaW4nLCBzdHlsZSksXHJcbiAgICAgICAgICAgICAgICBib3JkZXI6IGdldEJveFN0eWxlKGVsZW0sICdib3JkZXInLCBzdHlsZSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcGFyZW50OiB7XHJcbiAgICAgICAgICAgICAgICBzdHlsZTogcGFyZW50U3R5bGUsXHJcbiAgICAgICAgICAgICAgICB3aWR0aDogcmVjdFBhcmVudC53aWR0aCxcclxuICAgICAgICAgICAgICAgIGhlaWdodDogcmVjdFBhcmVudC5oZWlnaHQsXHJcbiAgICAgICAgICAgICAgICB0b3A6IHJlY3RQYXJlbnQudG9wLFxyXG4gICAgICAgICAgICAgICAgYm90dG9tOiByZWN0UGFyZW50LmJvdHRvbSxcclxuICAgICAgICAgICAgICAgIGxlZnQ6IHJlY3RQYXJlbnQubGVmdCxcclxuICAgICAgICAgICAgICAgIHJpZ2h0OiByZWN0UGFyZW50LnJpZ2h0LFxyXG4gICAgICAgICAgICAgICAgcGFkZGluZzogZ2V0Qm94U3R5bGUocGFyZW50LCAncGFkZGluZycsIHBhcmVudFN0eWxlKSxcclxuICAgICAgICAgICAgICAgIGJvcmRlcjogZ2V0Qm94U3R5bGUocGFyZW50LCAnYm9yZGVyJywgcGFyZW50U3R5bGUpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxuXG4gICAgLyoqXHJcbiAgICAgKiBEZXRlcm1pbmUgaWYgYW4gZWxlbWVudCBpcyBhdHRhY2hlZCB0byB0aGUgRE9NXHJcbiAgICAgKiBQYW56b29tIHJlcXVpcmVzIHRoaXMgc28gZXZlbnRzIHdvcmsgcHJvcGVybHlcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gaXNBdHRhY2hlZChlbGVtKSB7XHJcbiAgICAgICAgdmFyIGRvYyA9IGVsZW0ub3duZXJEb2N1bWVudDtcclxuICAgICAgICB2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xyXG4gICAgICAgIHJldHVybiAoZG9jICYmXHJcbiAgICAgICAgICAgIHBhcmVudCAmJlxyXG4gICAgICAgICAgICBkb2Mubm9kZVR5cGUgPT09IDkgJiZcclxuICAgICAgICAgICAgcGFyZW50Lm5vZGVUeXBlID09PSAxICYmXHJcbiAgICAgICAgICAgIGRvYy5kb2N1bWVudEVsZW1lbnQuY29udGFpbnMocGFyZW50KSk7XHJcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRDbGFzcyhlbGVtKSB7XHJcbiAgICAgICAgcmV0dXJuIChlbGVtLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSB8fCAnJykudHJpbSgpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gaGFzQ2xhc3MoZWxlbSwgY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgcmV0dXJuIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKFwiIFwiICsgZ2V0Q2xhc3MoZWxlbSkgKyBcIiBcIikuaW5kZXhPZihcIiBcIiArIGNsYXNzTmFtZSArIFwiIFwiKSA+IC0xO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gaXNFeGNsdWRlZChlbGVtLCBvcHRpb25zKSB7XHJcbiAgICAgICAgZm9yICh2YXIgY3VyID0gZWxlbTsgY3VyICE9IG51bGw7IGN1ciA9IGN1ci5wYXJlbnROb2RlKSB7XHJcbiAgICAgICAgICAgIGlmIChoYXNDbGFzcyhjdXIsIG9wdGlvbnMuZXhjbHVkZUNsYXNzKSB8fCBvcHRpb25zLmV4Y2x1ZGUuaW5kZXhPZihjdXIpID4gLTEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cblxuICAgIC8qKlxyXG4gICAgICogRGV0ZXJtaW5lIGlmIGFuIGVsZW1lbnQgaXMgU1ZHIGJ5IGNoZWNraW5nIHRoZSBuYW1lc3BhY2VcclxuICAgICAqIEV4Y2VwdGlvbjogdGhlIDxzdmc+IGVsZW1lbnQgaXRzZWxmIHNob3VsZCBiZSB0cmVhdGVkIGxpa2UgSFRNTFxyXG4gICAgICovXHJcbiAgICB2YXIgcnN2ZyA9IC9eaHR0cDpbXFx3XFwuXFwvXStzdmckLztcclxuICAgIGZ1bmN0aW9uIGlzU1ZHRWxlbWVudChlbGVtKSB7XHJcbiAgICAgICAgcmV0dXJuIHJzdmcudGVzdChlbGVtLm5hbWVzcGFjZVVSSSkgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAnc3ZnJztcclxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNoYWxsb3dDbG9uZShvYmopIHtcclxuICAgICAgICB2YXIgY2xvbmUgPSB7fTtcclxuICAgICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XHJcbiAgICAgICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgY2xvbmVba2V5XSA9IG9ialtrZXldO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjbG9uZTtcclxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0T3B0aW9ucyA9IHtcclxuICAgICAgICBhbmltYXRlOiBmYWxzZSxcclxuICAgICAgICBjYW52YXM6IGZhbHNlLFxyXG4gICAgICAgIGN1cnNvcjogJ21vdmUnLFxyXG4gICAgICAgIGRpc2FibGVQYW46IGZhbHNlLFxyXG4gICAgICAgIGRpc2FibGVab29tOiBmYWxzZSxcclxuICAgICAgICBkaXNhYmxlWEF4aXM6IGZhbHNlLFxyXG4gICAgICAgIGRpc2FibGVZQXhpczogZmFsc2UsXHJcbiAgICAgICAgZHVyYXRpb246IDIwMCxcclxuICAgICAgICBlYXNpbmc6ICdlYXNlLWluLW91dCcsXHJcbiAgICAgICAgZXhjbHVkZTogW10sXHJcbiAgICAgICAgZXhjbHVkZUNsYXNzOiAncGFuem9vbS1leGNsdWRlJyxcclxuICAgICAgICBoYW5kbGVTdGFydEV2ZW50OiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBtYXhTY2FsZTogNCxcclxuICAgICAgICBtaW5TY2FsZTogMC4xMjUsXHJcbiAgICAgICAgb3ZlcmZsb3c6ICdoaWRkZW4nLFxyXG4gICAgICAgIHBhbk9ubHlXaGVuWm9vbWVkOiBmYWxzZSxcclxuICAgICAgICByZWxhdGl2ZTogZmFsc2UsXHJcbiAgICAgICAgc2V0VHJhbnNmb3JtOiBzZXRUcmFuc2Zvcm0sXHJcbiAgICAgICAgc3RhcnRYOiAwLFxyXG4gICAgICAgIHN0YXJ0WTogMCxcclxuICAgICAgICBzdGFydFNjYWxlOiAxLFxyXG4gICAgICAgIHN0ZXA6IDAuMyxcclxuICAgICAgICB0b3VjaEFjdGlvbjogJ25vbmUnXHJcbiAgICB9O1xyXG4gICAgZnVuY3Rpb24gUGFuem9vbShlbGVtLCBvcHRpb25zKSB7XHJcbiAgICAgICAgaWYgKCFlbGVtKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGFuem9vbSByZXF1aXJlcyBhbiBlbGVtZW50IGFzIGFuIGFyZ3VtZW50Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChlbGVtLm5vZGVUeXBlICE9PSAxKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGFuem9vbSByZXF1aXJlcyBhbiBlbGVtZW50IHdpdGggYSBub2RlVHlwZSBvZiAxJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghaXNBdHRhY2hlZChlbGVtKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Bhbnpvb20gc2hvdWxkIGJlIGNhbGxlZCBvbiBlbGVtZW50cyB0aGF0IGhhdmUgYmVlbiBhdHRhY2hlZCB0byB0aGUgRE9NJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG9wdGlvbnMgPSBfX2Fzc2lnbihfX2Fzc2lnbih7fSwgZGVmYXVsdE9wdGlvbnMpLCBvcHRpb25zKTtcclxuICAgICAgICB2YXIgaXNTVkcgPSBpc1NWR0VsZW1lbnQoZWxlbSk7XHJcbiAgICAgICAgdmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcclxuICAgICAgICAvLyBTZXQgcGFyZW50IHN0eWxlc1xyXG4gICAgICAgIHBhcmVudC5zdHlsZS5vdmVyZmxvdyA9IG9wdGlvbnMub3ZlcmZsb3c7XHJcbiAgICAgICAgcGFyZW50LnN0eWxlLnVzZXJTZWxlY3QgPSAnbm9uZSc7XHJcbiAgICAgICAgLy8gVGhpcyBpcyBpbXBvcnRhbnQgZm9yIG1vYmlsZSB0b1xyXG4gICAgICAgIC8vIHByZXZlbnQgc2Nyb2xsaW5nIHdoaWxlIHBhbm5pbmdcclxuICAgICAgICBwYXJlbnQuc3R5bGUudG91Y2hBY3Rpb24gPSBvcHRpb25zLnRvdWNoQWN0aW9uO1xyXG4gICAgICAgIChvcHRpb25zLmNhbnZhcyA/IHBhcmVudCA6IGVsZW0pLnN0eWxlLmN1cnNvciA9IG9wdGlvbnMuY3Vyc29yO1xyXG4gICAgICAgIC8vIFNldCBlbGVtZW50IHN0eWxlc1xyXG4gICAgICAgIGVsZW0uc3R5bGUudXNlclNlbGVjdCA9ICdub25lJztcclxuICAgICAgICBlbGVtLnN0eWxlLnRvdWNoQWN0aW9uID0gb3B0aW9ucy50b3VjaEFjdGlvbjtcclxuICAgICAgICAvLyBUaGUgZGVmYXVsdCBmb3IgU1ZHIGlzICcwIDAnXHJcbiAgICAgICAgLy8gU1ZHIGNhbid0IGJlIGNoYW5nZWQgaW4gSUVcclxuICAgICAgICBzZXRTdHlsZShlbGVtLCAndHJhbnNmb3JtT3JpZ2luJywgdHlwZW9mIG9wdGlvbnMub3JpZ2luID09PSAnc3RyaW5nJyA/IG9wdGlvbnMub3JpZ2luIDogaXNTVkcgPyAnMCAwJyA6ICc1MCUgNTAlJyk7XHJcbiAgICAgICAgZnVuY3Rpb24gc2V0T3B0aW9ucyhvcHRzKSB7XHJcbiAgICAgICAgICAgIGlmIChvcHRzID09PSB2b2lkIDApIHsgb3B0cyA9IHt9OyB9XHJcbiAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBvcHRzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAob3B0cy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9uc1trZXldID0gb3B0c1trZXldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIEhhbmRsZSBvcHRpb24gc2lkZS1lZmZlY3RzXHJcbiAgICAgICAgICAgIGlmIChvcHRzLmhhc093blByb3BlcnR5KCdjdXJzb3InKSkge1xyXG4gICAgICAgICAgICAgICAgZWxlbS5zdHlsZS5jdXJzb3IgPSBvcHRzLmN1cnNvcjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAob3B0cy5oYXNPd25Qcm9wZXJ0eSgnb3ZlcmZsb3cnKSkge1xyXG4gICAgICAgICAgICAgICAgcGFyZW50LnN0eWxlLm92ZXJmbG93ID0gb3B0cy5vdmVyZmxvdztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAob3B0cy5oYXNPd25Qcm9wZXJ0eSgndG91Y2hBY3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgcGFyZW50LnN0eWxlLnRvdWNoQWN0aW9uID0gb3B0cy50b3VjaEFjdGlvbjtcclxuICAgICAgICAgICAgICAgIGVsZW0uc3R5bGUudG91Y2hBY3Rpb24gPSBvcHRzLnRvdWNoQWN0aW9uO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChvcHRzLmhhc093blByb3BlcnR5KCdtaW5TY2FsZScpIHx8XHJcbiAgICAgICAgICAgICAgICBvcHRzLmhhc093blByb3BlcnR5KCdtYXhTY2FsZScpIHx8XHJcbiAgICAgICAgICAgICAgICBvcHRzLmhhc093blByb3BlcnR5KCdjb250YWluJykpIHtcclxuICAgICAgICAgICAgICAgIHNldE1pbk1heCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB4ID0gMDtcclxuICAgICAgICB2YXIgeSA9IDA7XHJcbiAgICAgICAgdmFyIHNjYWxlID0gMTtcclxuICAgICAgICB2YXIgaXNQYW5uaW5nID0gZmFsc2U7XHJcbiAgICAgICAgem9vbShvcHRpb25zLnN0YXJ0U2NhbGUsIHsgYW5pbWF0ZTogZmFsc2UgfSk7XHJcbiAgICAgICAgLy8gV2FpdCBmb3Igc2NhbGUgdG8gdXBkYXRlXHJcbiAgICAgICAgLy8gZm9yIGFjY3VyYXRlIGRpbWVuc2lvbnNcclxuICAgICAgICAvLyB0byBjb25zdHJhaW4gaW5pdGlhbCB2YWx1ZXNcclxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgc2V0TWluTWF4KCk7XHJcbiAgICAgICAgICAgIHBhbihvcHRpb25zLnN0YXJ0WCwgb3B0aW9ucy5zdGFydFksIHsgYW5pbWF0ZTogZmFsc2UgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcclxuICAgICAgICBmdW5jdGlvbiB0cmlnZ2VyKGV2ZW50TmFtZSwgZGV0YWlsLCBvcHRzKSB7XHJcbiAgICAgICAgICAgIGlmIChvcHRzLnNpbGVudCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBldmVudCA9IG5ldyBDdXN0b21FdmVudChldmVudE5hbWUsIHsgZGV0YWlsOiBkZXRhaWwgfSk7XHJcbiAgICAgICAgICAgIGVsZW0uZGlzcGF0Y2hFdmVudChldmVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHNldFRyYW5zZm9ybVdpdGhFdmVudChldmVudE5hbWUsIG9wdHMpIHtcclxuICAgICAgICAgICAgdmFyIHZhbHVlID0geyB4OiB4LCB5OiB5LCBzY2FsZTogc2NhbGUsIGlzU1ZHOiBpc1NWRyB9O1xyXG4gICAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRzLmFuaW1hdGUgPT09ICdib29sZWFuJykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRzLmFuaW1hdGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VHJhbnNpdGlvbihlbGVtLCBvcHRzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFN0eWxlKGVsZW0sICd0cmFuc2l0aW9uJywgJ25vbmUnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBvcHRzLnNldFRyYW5zZm9ybShlbGVtLCB2YWx1ZSwgb3B0cyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0cmlnZ2VyKGV2ZW50TmFtZSwgdmFsdWUsIG9wdHMpO1xyXG4gICAgICAgICAgICB0cmlnZ2VyKCdwYW56b29tY2hhbmdlJywgdmFsdWUsIG9wdHMpO1xyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHNldE1pbk1heCgpIHtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuY29udGFpbikge1xyXG4gICAgICAgICAgICAgICAgdmFyIGRpbXMgPSBnZXREaW1lbnNpb25zKGVsZW0pO1xyXG4gICAgICAgICAgICAgICAgdmFyIHBhcmVudFdpZHRoID0gZGltcy5wYXJlbnQud2lkdGggLSBkaW1zLnBhcmVudC5ib3JkZXIubGVmdCAtIGRpbXMucGFyZW50LmJvcmRlci5yaWdodDtcclxuICAgICAgICAgICAgICAgIHZhciBwYXJlbnRIZWlnaHQgPSBkaW1zLnBhcmVudC5oZWlnaHQgLSBkaW1zLnBhcmVudC5ib3JkZXIudG9wIC0gZGltcy5wYXJlbnQuYm9yZGVyLmJvdHRvbTtcclxuICAgICAgICAgICAgICAgIHZhciBlbGVtV2lkdGggPSBkaW1zLmVsZW0ud2lkdGggLyBzY2FsZTtcclxuICAgICAgICAgICAgICAgIHZhciBlbGVtSGVpZ2h0ID0gZGltcy5lbGVtLmhlaWdodCAvIHNjYWxlO1xyXG4gICAgICAgICAgICAgICAgdmFyIGVsZW1TY2FsZWRXaWR0aCA9IHBhcmVudFdpZHRoIC8gZWxlbVdpZHRoO1xyXG4gICAgICAgICAgICAgICAgdmFyIGVsZW1TY2FsZWRIZWlnaHQgPSBwYXJlbnRIZWlnaHQgLyBlbGVtSGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuY29udGFpbiA9PT0gJ2luc2lkZScpIHtcclxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLm1heFNjYWxlID0gTWF0aC5taW4oZWxlbVNjYWxlZFdpZHRoLCBlbGVtU2NhbGVkSGVpZ2h0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbnMuY29udGFpbiA9PT0gJ291dHNpZGUnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5taW5TY2FsZSA9IE1hdGgubWF4KGVsZW1TY2FsZWRXaWR0aCwgZWxlbVNjYWxlZEhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZnVuY3Rpb24gY29uc3RyYWluWFkodG9YLCB0b1ksIHRvU2NhbGUsIHBhbk9wdGlvbnMpIHtcclxuICAgICAgICAgICAgdmFyIG9wdHMgPSBfX2Fzc2lnbihfX2Fzc2lnbih7fSwgb3B0aW9ucyksIHBhbk9wdGlvbnMpO1xyXG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0geyB4OiB4LCB5OiB5LCBvcHRzOiBvcHRzIH07XHJcbiAgICAgICAgICAgIGlmICghb3B0cy5mb3JjZSAmJiAob3B0cy5kaXNhYmxlUGFuIHx8IChvcHRzLnBhbk9ubHlXaGVuWm9vbWVkICYmIHNjYWxlID09PSBvcHRzLnN0YXJ0U2NhbGUpKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0b1ggPSBwYXJzZUZsb2F0KHRvWCk7XHJcbiAgICAgICAgICAgIHRvWSA9IHBhcnNlRmxvYXQodG9ZKTtcclxuICAgICAgICAgICAgaWYgKCFvcHRzLmRpc2FibGVYQXhpcykge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0LnggPSAob3B0cy5yZWxhdGl2ZSA/IHggOiAwKSArIHRvWDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoIW9wdHMuZGlzYWJsZVlBeGlzKSB7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQueSA9IChvcHRzLnJlbGF0aXZlID8geSA6IDApICsgdG9ZO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChvcHRzLmNvbnRhaW4gPT09ICdpbnNpZGUnKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZGltcyA9IGdldERpbWVuc2lvbnMoZWxlbSk7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQueCA9IE1hdGgubWF4KC1kaW1zLmVsZW0ubWFyZ2luLmxlZnQgLSBkaW1zLnBhcmVudC5wYWRkaW5nLmxlZnQsIE1hdGgubWluKGRpbXMucGFyZW50LndpZHRoIC1cclxuICAgICAgICAgICAgICAgICAgICBkaW1zLmVsZW0ud2lkdGggLyB0b1NjYWxlIC1cclxuICAgICAgICAgICAgICAgICAgICBkaW1zLnBhcmVudC5wYWRkaW5nLmxlZnQgLVxyXG4gICAgICAgICAgICAgICAgICAgIGRpbXMuZWxlbS5tYXJnaW4ubGVmdCAtXHJcbiAgICAgICAgICAgICAgICAgICAgZGltcy5wYXJlbnQuYm9yZGVyLmxlZnQgLVxyXG4gICAgICAgICAgICAgICAgICAgIGRpbXMucGFyZW50LmJvcmRlci5yaWdodCwgcmVzdWx0LngpKTtcclxuICAgICAgICAgICAgICAgIHJlc3VsdC55ID0gTWF0aC5tYXgoLWRpbXMuZWxlbS5tYXJnaW4udG9wIC0gZGltcy5wYXJlbnQucGFkZGluZy50b3AsIE1hdGgubWluKGRpbXMucGFyZW50LmhlaWdodCAtXHJcbiAgICAgICAgICAgICAgICAgICAgZGltcy5lbGVtLmhlaWdodCAvIHRvU2NhbGUgLVxyXG4gICAgICAgICAgICAgICAgICAgIGRpbXMucGFyZW50LnBhZGRpbmcudG9wIC1cclxuICAgICAgICAgICAgICAgICAgICBkaW1zLmVsZW0ubWFyZ2luLnRvcCAtXHJcbiAgICAgICAgICAgICAgICAgICAgZGltcy5wYXJlbnQuYm9yZGVyLnRvcCAtXHJcbiAgICAgICAgICAgICAgICAgICAgZGltcy5wYXJlbnQuYm9yZGVyLmJvdHRvbSwgcmVzdWx0LnkpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChvcHRzLmNvbnRhaW4gPT09ICdvdXRzaWRlJykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGRpbXMgPSBnZXREaW1lbnNpb25zKGVsZW0pO1xyXG4gICAgICAgICAgICAgICAgdmFyIHJlYWxXaWR0aCA9IGRpbXMuZWxlbS53aWR0aCAvIHNjYWxlO1xyXG4gICAgICAgICAgICAgICAgdmFyIHJlYWxIZWlnaHQgPSBkaW1zLmVsZW0uaGVpZ2h0IC8gc2NhbGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgc2NhbGVkV2lkdGggPSByZWFsV2lkdGggKiB0b1NjYWxlO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNjYWxlZEhlaWdodCA9IHJlYWxIZWlnaHQgKiB0b1NjYWxlO1xyXG4gICAgICAgICAgICAgICAgdmFyIGRpZmZIb3Jpem9udGFsID0gKHNjYWxlZFdpZHRoIC0gcmVhbFdpZHRoKSAvIDI7XHJcbiAgICAgICAgICAgICAgICB2YXIgZGlmZlZlcnRpY2FsID0gKHNjYWxlZEhlaWdodCAtIHJlYWxIZWlnaHQpIC8gMjtcclxuICAgICAgICAgICAgICAgIHZhciBtaW5YID0gKC0oc2NhbGVkV2lkdGggLSBkaW1zLnBhcmVudC53aWR0aCkgLVxyXG4gICAgICAgICAgICAgICAgICAgIGRpbXMucGFyZW50LnBhZGRpbmcubGVmdCAtXHJcbiAgICAgICAgICAgICAgICAgICAgZGltcy5wYXJlbnQuYm9yZGVyLmxlZnQgLVxyXG4gICAgICAgICAgICAgICAgICAgIGRpbXMucGFyZW50LmJvcmRlci5yaWdodCArXHJcbiAgICAgICAgICAgICAgICAgICAgZGlmZkhvcml6b250YWwpIC9cclxuICAgICAgICAgICAgICAgICAgICB0b1NjYWxlO1xyXG4gICAgICAgICAgICAgICAgdmFyIG1heFggPSAoZGlmZkhvcml6b250YWwgLSBkaW1zLnBhcmVudC5wYWRkaW5nLmxlZnQpIC8gdG9TY2FsZTtcclxuICAgICAgICAgICAgICAgIHJlc3VsdC54ID0gTWF0aC5tYXgoTWF0aC5taW4ocmVzdWx0LngsIG1heFgpLCBtaW5YKTtcclxuICAgICAgICAgICAgICAgIHZhciBtaW5ZID0gKC0oc2NhbGVkSGVpZ2h0IC0gZGltcy5wYXJlbnQuaGVpZ2h0KSAtXHJcbiAgICAgICAgICAgICAgICAgICAgZGltcy5wYXJlbnQucGFkZGluZy50b3AgLVxyXG4gICAgICAgICAgICAgICAgICAgIGRpbXMucGFyZW50LmJvcmRlci50b3AgLVxyXG4gICAgICAgICAgICAgICAgICAgIGRpbXMucGFyZW50LmJvcmRlci5ib3R0b20gK1xyXG4gICAgICAgICAgICAgICAgICAgIGRpZmZWZXJ0aWNhbCkgL1xyXG4gICAgICAgICAgICAgICAgICAgIHRvU2NhbGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgbWF4WSA9IChkaWZmVmVydGljYWwgLSBkaW1zLnBhcmVudC5wYWRkaW5nLnRvcCkgLyB0b1NjYWxlO1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0LnkgPSBNYXRoLm1heChNYXRoLm1pbihyZXN1bHQueSwgbWF4WSksIG1pblkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIGNvbnN0cmFpblNjYWxlKHRvU2NhbGUsIHpvb21PcHRpb25zKSB7XHJcbiAgICAgICAgICAgIHZhciBvcHRzID0gX19hc3NpZ24oX19hc3NpZ24oe30sIG9wdGlvbnMpLCB6b29tT3B0aW9ucyk7XHJcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSB7IHNjYWxlOiBzY2FsZSwgb3B0czogb3B0cyB9O1xyXG4gICAgICAgICAgICBpZiAoIW9wdHMuZm9yY2UgJiYgb3B0cy5kaXNhYmxlWm9vbSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXN1bHQuc2NhbGUgPSBNYXRoLm1pbihNYXRoLm1heCh0b1NjYWxlLCBvcHRzLm1pblNjYWxlKSwgb3B0cy5tYXhTY2FsZSk7XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHBhbih0b1gsIHRvWSwgcGFuT3B0aW9ucykge1xyXG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gY29uc3RyYWluWFkodG9YLCB0b1ksIHNjYWxlLCBwYW5PcHRpb25zKTtcclxuICAgICAgICAgICAgdmFyIG9wdHMgPSByZXN1bHQub3B0cztcclxuICAgICAgICAgICAgeCA9IHJlc3VsdC54O1xyXG4gICAgICAgICAgICB5ID0gcmVzdWx0Lnk7XHJcbiAgICAgICAgICAgIHJldHVybiBzZXRUcmFuc2Zvcm1XaXRoRXZlbnQoJ3Bhbnpvb21wYW4nLCBvcHRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZnVuY3Rpb24gem9vbSh0b1NjYWxlLCB6b29tT3B0aW9ucykge1xyXG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gY29uc3RyYWluU2NhbGUodG9TY2FsZSwgem9vbU9wdGlvbnMpO1xyXG4gICAgICAgICAgICB2YXIgb3B0cyA9IHJlc3VsdC5vcHRzO1xyXG4gICAgICAgICAgICBpZiAoIW9wdHMuZm9yY2UgJiYgb3B0cy5kaXNhYmxlWm9vbSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRvU2NhbGUgPSByZXN1bHQuc2NhbGU7XHJcbiAgICAgICAgICAgIHZhciB0b1ggPSB4O1xyXG4gICAgICAgICAgICB2YXIgdG9ZID0geTtcclxuICAgICAgICAgICAgaWYgKG9wdHMuZm9jYWwpIHtcclxuICAgICAgICAgICAgICAgIC8vIFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHBvaW50IGFmdGVyIHRoZSBzY2FsZSBhbmQgdGhlIHBvaW50IGJlZm9yZSB0aGUgc2NhbGVcclxuICAgICAgICAgICAgICAgIC8vIHBsdXMgdGhlIGN1cnJlbnQgdHJhbnNsYXRpb24gYWZ0ZXIgdGhlIHNjYWxlXHJcbiAgICAgICAgICAgICAgICAvLyBuZXV0cmFsaXplZCB0byBubyBzY2FsZSAoYXMgdGhlIHRyYW5zZm9ybSBzY2FsZSB3aWxsIGFwcGx5IHRvIHRoZSB0cmFuc2xhdGlvbilcclxuICAgICAgICAgICAgICAgIHZhciBmb2NhbCA9IG9wdHMuZm9jYWw7XHJcbiAgICAgICAgICAgICAgICB0b1ggPSAoZm9jYWwueCAvIHRvU2NhbGUgLSBmb2NhbC54IC8gc2NhbGUgKyB4ICogdG9TY2FsZSkgLyB0b1NjYWxlO1xyXG4gICAgICAgICAgICAgICAgdG9ZID0gKGZvY2FsLnkgLyB0b1NjYWxlIC0gZm9jYWwueSAvIHNjYWxlICsgeSAqIHRvU2NhbGUpIC8gdG9TY2FsZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgcGFuUmVzdWx0ID0gY29uc3RyYWluWFkodG9YLCB0b1ksIHRvU2NhbGUsIHsgcmVsYXRpdmU6IGZhbHNlLCBmb3JjZTogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgeCA9IHBhblJlc3VsdC54O1xyXG4gICAgICAgICAgICB5ID0gcGFuUmVzdWx0Lnk7XHJcbiAgICAgICAgICAgIHNjYWxlID0gdG9TY2FsZTtcclxuICAgICAgICAgICAgcmV0dXJuIHNldFRyYW5zZm9ybVdpdGhFdmVudCgncGFuem9vbXpvb20nLCBvcHRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZnVuY3Rpb24gem9vbUluT3V0KGlzSW4sIHpvb21PcHRpb25zKSB7XHJcbiAgICAgICAgICAgIHZhciBvcHRzID0gX19hc3NpZ24oX19hc3NpZ24oX19hc3NpZ24oe30sIG9wdGlvbnMpLCB7IGFuaW1hdGU6IHRydWUgfSksIHpvb21PcHRpb25zKTtcclxuICAgICAgICAgICAgcmV0dXJuIHpvb20oc2NhbGUgKiBNYXRoLmV4cCgoaXNJbiA/IDEgOiAtMSkgKiBvcHRzLnN0ZXApLCBvcHRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZnVuY3Rpb24gem9vbUluKHpvb21PcHRpb25zKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB6b29tSW5PdXQodHJ1ZSwgem9vbU9wdGlvbnMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmdW5jdGlvbiB6b29tT3V0KHpvb21PcHRpb25zKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB6b29tSW5PdXQoZmFsc2UsIHpvb21PcHRpb25zKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZnVuY3Rpb24gem9vbVRvUG9pbnQodG9TY2FsZSwgcG9pbnQsIHpvb21PcHRpb25zKSB7XHJcbiAgICAgICAgICAgIHZhciBkaW1zID0gZ2V0RGltZW5zaW9ucyhlbGVtKTtcclxuICAgICAgICAgICAgLy8gSW5zdGVhZCBvZiB0aGlua2luZyBvZiBvcGVyYXRpbmcgb24gdGhlIHBhbnpvb20gZWxlbWVudCxcclxuICAgICAgICAgICAgLy8gdGhpbmsgb2Ygb3BlcmF0aW5nIG9uIHRoZSBhcmVhIGluc2lkZSB0aGUgcGFuem9vbVxyXG4gICAgICAgICAgICAvLyBlbGVtZW50J3MgcGFyZW50XHJcbiAgICAgICAgICAgIC8vIFN1YnRyYWN0IHBhZGRpbmcgYW5kIGJvcmRlclxyXG4gICAgICAgICAgICB2YXIgZWZmZWN0aXZlQXJlYSA9IHtcclxuICAgICAgICAgICAgICAgIHdpZHRoOiBkaW1zLnBhcmVudC53aWR0aCAtXHJcbiAgICAgICAgICAgICAgICAgICAgZGltcy5wYXJlbnQucGFkZGluZy5sZWZ0IC1cclxuICAgICAgICAgICAgICAgICAgICBkaW1zLnBhcmVudC5wYWRkaW5nLnJpZ2h0IC1cclxuICAgICAgICAgICAgICAgICAgICBkaW1zLnBhcmVudC5ib3JkZXIubGVmdCAtXHJcbiAgICAgICAgICAgICAgICAgICAgZGltcy5wYXJlbnQuYm9yZGVyLnJpZ2h0LFxyXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBkaW1zLnBhcmVudC5oZWlnaHQgLVxyXG4gICAgICAgICAgICAgICAgICAgIGRpbXMucGFyZW50LnBhZGRpbmcudG9wIC1cclxuICAgICAgICAgICAgICAgICAgICBkaW1zLnBhcmVudC5wYWRkaW5nLmJvdHRvbSAtXHJcbiAgICAgICAgICAgICAgICAgICAgZGltcy5wYXJlbnQuYm9yZGVyLnRvcCAtXHJcbiAgICAgICAgICAgICAgICAgICAgZGltcy5wYXJlbnQuYm9yZGVyLmJvdHRvbVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAvLyBBZGp1c3QgdGhlIGNsaWVudFgvY2xpZW50WSB0byBpZ25vcmUgdGhlIGFyZWFcclxuICAgICAgICAgICAgLy8gb3V0c2lkZSB0aGUgZWZmZWN0aXZlIGFyZWFcclxuICAgICAgICAgICAgdmFyIGNsaWVudFggPSBwb2ludC5jbGllbnRYIC1cclxuICAgICAgICAgICAgICAgIGRpbXMucGFyZW50LmxlZnQgLVxyXG4gICAgICAgICAgICAgICAgZGltcy5wYXJlbnQucGFkZGluZy5sZWZ0IC1cclxuICAgICAgICAgICAgICAgIGRpbXMucGFyZW50LmJvcmRlci5sZWZ0IC1cclxuICAgICAgICAgICAgICAgIGRpbXMuZWxlbS5tYXJnaW4ubGVmdDtcclxuICAgICAgICAgICAgdmFyIGNsaWVudFkgPSBwb2ludC5jbGllbnRZIC1cclxuICAgICAgICAgICAgICAgIGRpbXMucGFyZW50LnRvcCAtXHJcbiAgICAgICAgICAgICAgICBkaW1zLnBhcmVudC5wYWRkaW5nLnRvcCAtXHJcbiAgICAgICAgICAgICAgICBkaW1zLnBhcmVudC5ib3JkZXIudG9wIC1cclxuICAgICAgICAgICAgICAgIGRpbXMuZWxlbS5tYXJnaW4udG9wO1xyXG4gICAgICAgICAgICAvLyBBZGp1c3QgdGhlIGNsaWVudFgvY2xpZW50WSBmb3IgSFRNTCBlbGVtZW50cyxcclxuICAgICAgICAgICAgLy8gYmVjYXVzZSB0aGV5IGhhdmUgYSB0cmFuc2Zvcm0tb3JpZ2luIG9mIDUwJSA1MCVcclxuICAgICAgICAgICAgaWYgKCFpc1NWRykge1xyXG4gICAgICAgICAgICAgICAgY2xpZW50WCAtPSBkaW1zLmVsZW0ud2lkdGggLyBzY2FsZSAvIDI7XHJcbiAgICAgICAgICAgICAgICBjbGllbnRZIC09IGRpbXMuZWxlbS5oZWlnaHQgLyBzY2FsZSAvIDI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gQ29udmVydCB0aGUgbW91c2UgcG9pbnQgZnJvbSBpdCdzIHBvc2l0aW9uIG92ZXIgdGhlXHJcbiAgICAgICAgICAgIC8vIGVmZmVjdGl2ZSBhcmVhIGJlZm9yZSB0aGUgc2NhbGUgdG8gdGhlIHBvc2l0aW9uXHJcbiAgICAgICAgICAgIC8vIG92ZXIgdGhlIGVmZmVjdGl2ZSBhcmVhIGFmdGVyIHRoZSBzY2FsZS5cclxuICAgICAgICAgICAgdmFyIGZvY2FsID0ge1xyXG4gICAgICAgICAgICAgICAgeDogKGNsaWVudFggLyBlZmZlY3RpdmVBcmVhLndpZHRoKSAqIChlZmZlY3RpdmVBcmVhLndpZHRoICogdG9TY2FsZSksXHJcbiAgICAgICAgICAgICAgICB5OiAoY2xpZW50WSAvIGVmZmVjdGl2ZUFyZWEuaGVpZ2h0KSAqIChlZmZlY3RpdmVBcmVhLmhlaWdodCAqIHRvU2NhbGUpXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHJldHVybiB6b29tKHRvU2NhbGUsIF9fYXNzaWduKF9fYXNzaWduKHsgYW5pbWF0ZTogZmFsc2UgfSwgem9vbU9wdGlvbnMpLCB7IGZvY2FsOiBmb2NhbCB9KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHpvb21XaXRoV2hlZWwoZXZlbnQsIHpvb21PcHRpb25zKSB7XHJcbiAgICAgICAgICAgIC8vIE5lZWQgdG8gcHJldmVudCB0aGUgZGVmYXVsdCBoZXJlXHJcbiAgICAgICAgICAgIC8vIG9yIGl0IGNvbmZsaWN0cyB3aXRoIHJlZ3VsYXIgcGFnZSBzY3JvbGxcclxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgdmFyIG9wdHMgPSBfX2Fzc2lnbihfX2Fzc2lnbih7fSwgb3B0aW9ucyksIHpvb21PcHRpb25zKTtcclxuICAgICAgICAgICAgLy8gTm9ybWFsaXplIHRvIGRlbHRhWCBpbiBjYXNlIHNoaWZ0IG1vZGlmaWVyIGlzIHVzZWQgb24gTWFjXHJcbiAgICAgICAgICAgIHZhciBkZWx0YSA9IGV2ZW50LmRlbHRhWSA9PT0gMCAmJiBldmVudC5kZWx0YVggPyBldmVudC5kZWx0YVggOiBldmVudC5kZWx0YVk7XHJcbiAgICAgICAgICAgIHZhciB3aGVlbCA9IGRlbHRhIDwgMCA/IDEgOiAtMTtcclxuICAgICAgICAgICAgdmFyIHRvU2NhbGUgPSBjb25zdHJhaW5TY2FsZShzY2FsZSAqIE1hdGguZXhwKCh3aGVlbCAqIG9wdHMuc3RlcCkgLyAzKSwgb3B0cykuc2NhbGU7XHJcbiAgICAgICAgICAgIHJldHVybiB6b29tVG9Qb2ludCh0b1NjYWxlLCBldmVudCwgb3B0cyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlc2V0KHJlc2V0T3B0aW9ucykge1xyXG4gICAgICAgICAgICB2YXIgb3B0cyA9IF9fYXNzaWduKF9fYXNzaWduKF9fYXNzaWduKHt9LCBvcHRpb25zKSwgeyBhbmltYXRlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KSwgcmVzZXRPcHRpb25zKTtcclxuICAgICAgICAgICAgc2NhbGUgPSBjb25zdHJhaW5TY2FsZShvcHRzLnN0YXJ0U2NhbGUsIG9wdHMpLnNjYWxlO1xyXG4gICAgICAgICAgICB2YXIgcGFuUmVzdWx0ID0gY29uc3RyYWluWFkob3B0cy5zdGFydFgsIG9wdHMuc3RhcnRZLCBzY2FsZSwgb3B0cyk7XHJcbiAgICAgICAgICAgIHggPSBwYW5SZXN1bHQueDtcclxuICAgICAgICAgICAgeSA9IHBhblJlc3VsdC55O1xyXG4gICAgICAgICAgICByZXR1cm4gc2V0VHJhbnNmb3JtV2l0aEV2ZW50KCdwYW56b29tcmVzZXQnLCBvcHRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIG9yaWdYO1xyXG4gICAgICAgIHZhciBvcmlnWTtcclxuICAgICAgICB2YXIgc3RhcnRDbGllbnRYO1xyXG4gICAgICAgIHZhciBzdGFydENsaWVudFk7XHJcbiAgICAgICAgdmFyIHN0YXJ0U2NhbGU7XHJcbiAgICAgICAgdmFyIHN0YXJ0RGlzdGFuY2U7XHJcbiAgICAgICAgdmFyIHBvaW50ZXJzID0gW107XHJcbiAgICAgICAgZnVuY3Rpb24gaGFuZGxlRG93bihldmVudCkge1xyXG4gICAgICAgICAgICAvLyBEb24ndCBoYW5kbGUgdGhpcyBldmVudCBpZiB0aGUgdGFyZ2V0IGlzIGV4Y2x1ZGVkXHJcbiAgICAgICAgICAgIGlmIChpc0V4Y2x1ZGVkKGV2ZW50LnRhcmdldCwgb3B0aW9ucykpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBhZGRQb2ludGVyKHBvaW50ZXJzLCBldmVudCk7XHJcbiAgICAgICAgICAgIGlzUGFubmluZyA9IHRydWU7XHJcbiAgICAgICAgICAgIG9wdGlvbnMuaGFuZGxlU3RhcnRFdmVudChldmVudCk7XHJcbiAgICAgICAgICAgIG9yaWdYID0geDtcclxuICAgICAgICAgICAgb3JpZ1kgPSB5O1xyXG4gICAgICAgICAgICB0cmlnZ2VyKCdwYW56b29tc3RhcnQnLCB7IHg6IHgsIHk6IHksIHNjYWxlOiBzY2FsZSB9LCBvcHRpb25zKTtcclxuICAgICAgICAgICAgLy8gVGhpcyB3b3JrcyB3aGV0aGVyIHRoZXJlIGFyZSBtdWx0aXBsZVxyXG4gICAgICAgICAgICAvLyBwb2ludGVycyBvciBub3RcclxuICAgICAgICAgICAgdmFyIHBvaW50ID0gZ2V0TWlkZGxlKHBvaW50ZXJzKTtcclxuICAgICAgICAgICAgc3RhcnRDbGllbnRYID0gcG9pbnQuY2xpZW50WDtcclxuICAgICAgICAgICAgc3RhcnRDbGllbnRZID0gcG9pbnQuY2xpZW50WTtcclxuICAgICAgICAgICAgc3RhcnRTY2FsZSA9IHNjYWxlO1xyXG4gICAgICAgICAgICBzdGFydERpc3RhbmNlID0gZ2V0RGlzdGFuY2UocG9pbnRlcnMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmdW5jdGlvbiBtb3ZlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIGlmICghaXNQYW5uaW5nIHx8XHJcbiAgICAgICAgICAgICAgICBvcmlnWCA9PT0gdW5kZWZpbmVkIHx8XHJcbiAgICAgICAgICAgICAgICBvcmlnWSA9PT0gdW5kZWZpbmVkIHx8XHJcbiAgICAgICAgICAgICAgICBzdGFydENsaWVudFggPT09IHVuZGVmaW5lZCB8fFxyXG4gICAgICAgICAgICAgICAgc3RhcnRDbGllbnRZID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBhZGRQb2ludGVyKHBvaW50ZXJzLCBldmVudCk7XHJcbiAgICAgICAgICAgIHZhciBjdXJyZW50ID0gZ2V0TWlkZGxlKHBvaW50ZXJzKTtcclxuICAgICAgICAgICAgaWYgKHBvaW50ZXJzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgIC8vIFVzZSB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgZmlyc3QgMiBwb2ludGVyc1xyXG4gICAgICAgICAgICAgICAgLy8gdG8gZGV0ZXJtaW5lIHRoZSBjdXJyZW50IHNjYWxlXHJcbiAgICAgICAgICAgICAgICB2YXIgZGlmZiA9IGdldERpc3RhbmNlKHBvaW50ZXJzKSAtIHN0YXJ0RGlzdGFuY2U7XHJcbiAgICAgICAgICAgICAgICB2YXIgdG9TY2FsZSA9IGNvbnN0cmFpblNjYWxlKChkaWZmICogb3B0aW9ucy5zdGVwKSAvIDgwICsgc3RhcnRTY2FsZSkuc2NhbGU7XHJcbiAgICAgICAgICAgICAgICB6b29tVG9Qb2ludCh0b1NjYWxlLCBjdXJyZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBwYW4ob3JpZ1ggKyAoY3VycmVudC5jbGllbnRYIC0gc3RhcnRDbGllbnRYKSAvIHNjYWxlLCBvcmlnWSArIChjdXJyZW50LmNsaWVudFkgLSBzdGFydENsaWVudFkpIC8gc2NhbGUsIHtcclxuICAgICAgICAgICAgICAgIGFuaW1hdGU6IGZhbHNlXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmdW5jdGlvbiBoYW5kbGVVcChldmVudCkge1xyXG4gICAgICAgICAgICAvLyBEb24ndCBjYWxsIHBhbnpvb21lbmQgd2hlbiBwYW5uaW5nIHdpdGggMiB0b3VjaGVzXHJcbiAgICAgICAgICAgIC8vIHVudGlsIGJvdGggdG91Y2hlcyBlbmRcclxuICAgICAgICAgICAgaWYgKHBvaW50ZXJzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgICAgICAgICAgdHJpZ2dlcigncGFuem9vbWVuZCcsIHsgeDogeCwgeTogeSwgc2NhbGU6IHNjYWxlIH0sIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIE5vdGU6IGRvbid0IHJlbW92ZSBhbGwgcG9pbnRlcnNcclxuICAgICAgICAgICAgLy8gQ2FuIHJlc3RhcnQgd2l0aG91dCBoYXZpbmcgdG8gcmVpbml0aWF0ZSBhbGwgb2YgdGhlbVxyXG4gICAgICAgICAgICAvLyBSZW1vdmUgdGhlIHBvaW50ZXIgcmVnYXJkbGVzcyBvZiB0aGUgaXNQYW5uaW5nIHN0YXRlXHJcbiAgICAgICAgICAgIHJlbW92ZVBvaW50ZXIocG9pbnRlcnMsIGV2ZW50KTtcclxuICAgICAgICAgICAgaWYgKCFpc1Bhbm5pbmcpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpc1Bhbm5pbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgb3JpZ1ggPSBvcmlnWSA9IHN0YXJ0Q2xpZW50WCA9IHN0YXJ0Q2xpZW50WSA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGJvdW5kID0gZmFsc2U7XHJcbiAgICAgICAgZnVuY3Rpb24gYmluZCgpIHtcclxuICAgICAgICAgICAgaWYgKGJvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYm91bmQgPSB0cnVlO1xyXG4gICAgICAgICAgICBvblBvaW50ZXIoJ2Rvd24nLCBvcHRpb25zLmNhbnZhcyA/IHBhcmVudCA6IGVsZW0sIGhhbmRsZURvd24pO1xyXG4gICAgICAgICAgICBvblBvaW50ZXIoJ21vdmUnLCBkb2N1bWVudCwgbW92ZSwgeyBwYXNzaXZlOiB0cnVlIH0pO1xyXG4gICAgICAgICAgICBvblBvaW50ZXIoJ3VwJywgZG9jdW1lbnQsIGhhbmRsZVVwLCB7IHBhc3NpdmU6IHRydWUgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIGRlc3Ryb3koKSB7XHJcbiAgICAgICAgICAgIGJvdW5kID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGRlc3Ryb3lQb2ludGVyKCdkb3duJywgb3B0aW9ucy5jYW52YXMgPyBwYXJlbnQgOiBlbGVtLCBoYW5kbGVEb3duKTtcclxuICAgICAgICAgICAgZGVzdHJveVBvaW50ZXIoJ21vdmUnLCBkb2N1bWVudCwgbW92ZSk7XHJcbiAgICAgICAgICAgIGRlc3Ryb3lQb2ludGVyKCd1cCcsIGRvY3VtZW50LCBoYW5kbGVVcCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghb3B0aW9ucy5ub0JpbmQpIHtcclxuICAgICAgICAgICAgYmluZCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBiaW5kOiBiaW5kLFxyXG4gICAgICAgICAgICBkZXN0cm95OiBkZXN0cm95LFxyXG4gICAgICAgICAgICBldmVudE5hbWVzOiBldmVudHMsXHJcbiAgICAgICAgICAgIGdldFBhbjogZnVuY3Rpb24gKCkgeyByZXR1cm4gKHsgeDogeCwgeTogeSB9KTsgfSxcclxuICAgICAgICAgICAgZ2V0U2NhbGU6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNjYWxlOyB9LFxyXG4gICAgICAgICAgICBnZXRPcHRpb25zOiBmdW5jdGlvbiAoKSB7IHJldHVybiBzaGFsbG93Q2xvbmUob3B0aW9ucyk7IH0sXHJcbiAgICAgICAgICAgIHBhbjogcGFuLFxyXG4gICAgICAgICAgICByZXNldDogcmVzZXQsXHJcbiAgICAgICAgICAgIHNldE9wdGlvbnM6IHNldE9wdGlvbnMsXHJcbiAgICAgICAgICAgIHNldFN0eWxlOiBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHsgcmV0dXJuIHNldFN0eWxlKGVsZW0sIG5hbWUsIHZhbHVlKTsgfSxcclxuICAgICAgICAgICAgem9vbTogem9vbSxcclxuICAgICAgICAgICAgem9vbUluOiB6b29tSW4sXHJcbiAgICAgICAgICAgIHpvb21PdXQ6IHpvb21PdXQsXHJcbiAgICAgICAgICAgIHpvb21Ub1BvaW50OiB6b29tVG9Qb2ludCxcclxuICAgICAgICAgICAgem9vbVdpdGhXaGVlbDogem9vbVdpdGhXaGVlbFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBQYW56b29tLmRlZmF1bHRPcHRpb25zID0gZGVmYXVsdE9wdGlvbnM7XG5cbiAgICByZXR1cm4gUGFuem9vbTtcblxufSkpKTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvYXhpb3MnKTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcbnZhciBzZXR0bGUgPSByZXF1aXJlKCcuLy4uL2NvcmUvc2V0dGxlJyk7XG52YXIgY29va2llcyA9IHJlcXVpcmUoJy4vLi4vaGVscGVycy9jb29raWVzJyk7XG52YXIgYnVpbGRVUkwgPSByZXF1aXJlKCcuLy4uL2hlbHBlcnMvYnVpbGRVUkwnKTtcbnZhciBidWlsZEZ1bGxQYXRoID0gcmVxdWlyZSgnLi4vY29yZS9idWlsZEZ1bGxQYXRoJyk7XG52YXIgcGFyc2VIZWFkZXJzID0gcmVxdWlyZSgnLi8uLi9oZWxwZXJzL3BhcnNlSGVhZGVycycpO1xudmFyIGlzVVJMU2FtZU9yaWdpbiA9IHJlcXVpcmUoJy4vLi4vaGVscGVycy9pc1VSTFNhbWVPcmlnaW4nKTtcbnZhciBjcmVhdGVFcnJvciA9IHJlcXVpcmUoJy4uL2NvcmUvY3JlYXRlRXJyb3InKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB4aHJBZGFwdGVyKGNvbmZpZykge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gZGlzcGF0Y2hYaHJSZXF1ZXN0KHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciByZXF1ZXN0RGF0YSA9IGNvbmZpZy5kYXRhO1xuICAgIHZhciByZXF1ZXN0SGVhZGVycyA9IGNvbmZpZy5oZWFkZXJzO1xuXG4gICAgaWYgKHV0aWxzLmlzRm9ybURhdGEocmVxdWVzdERhdGEpKSB7XG4gICAgICBkZWxldGUgcmVxdWVzdEhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddOyAvLyBMZXQgdGhlIGJyb3dzZXIgc2V0IGl0XG4gICAgfVxuXG4gICAgdmFyIHJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcblxuICAgIC8vIEhUVFAgYmFzaWMgYXV0aGVudGljYXRpb25cbiAgICBpZiAoY29uZmlnLmF1dGgpIHtcbiAgICAgIHZhciB1c2VybmFtZSA9IGNvbmZpZy5hdXRoLnVzZXJuYW1lIHx8ICcnO1xuICAgICAgdmFyIHBhc3N3b3JkID0gY29uZmlnLmF1dGgucGFzc3dvcmQgPyB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoY29uZmlnLmF1dGgucGFzc3dvcmQpKSA6ICcnO1xuICAgICAgcmVxdWVzdEhlYWRlcnMuQXV0aG9yaXphdGlvbiA9ICdCYXNpYyAnICsgYnRvYSh1c2VybmFtZSArICc6JyArIHBhc3N3b3JkKTtcbiAgICB9XG5cbiAgICB2YXIgZnVsbFBhdGggPSBidWlsZEZ1bGxQYXRoKGNvbmZpZy5iYXNlVVJMLCBjb25maWcudXJsKTtcbiAgICByZXF1ZXN0Lm9wZW4oY29uZmlnLm1ldGhvZC50b1VwcGVyQ2FzZSgpLCBidWlsZFVSTChmdWxsUGF0aCwgY29uZmlnLnBhcmFtcywgY29uZmlnLnBhcmFtc1NlcmlhbGl6ZXIpLCB0cnVlKTtcblxuICAgIC8vIFNldCB0aGUgcmVxdWVzdCB0aW1lb3V0IGluIE1TXG4gICAgcmVxdWVzdC50aW1lb3V0ID0gY29uZmlnLnRpbWVvdXQ7XG5cbiAgICAvLyBMaXN0ZW4gZm9yIHJlYWR5IHN0YXRlXG4gICAgcmVxdWVzdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiBoYW5kbGVMb2FkKCkge1xuICAgICAgaWYgKCFyZXF1ZXN0IHx8IHJlcXVlc3QucmVhZHlTdGF0ZSAhPT0gNCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFRoZSByZXF1ZXN0IGVycm9yZWQgb3V0IGFuZCB3ZSBkaWRuJ3QgZ2V0IGEgcmVzcG9uc2UsIHRoaXMgd2lsbCBiZVxuICAgICAgLy8gaGFuZGxlZCBieSBvbmVycm9yIGluc3RlYWRcbiAgICAgIC8vIFdpdGggb25lIGV4Y2VwdGlvbjogcmVxdWVzdCB0aGF0IHVzaW5nIGZpbGU6IHByb3RvY29sLCBtb3N0IGJyb3dzZXJzXG4gICAgICAvLyB3aWxsIHJldHVybiBzdGF0dXMgYXMgMCBldmVuIHRob3VnaCBpdCdzIGEgc3VjY2Vzc2Z1bCByZXF1ZXN0XG4gICAgICBpZiAocmVxdWVzdC5zdGF0dXMgPT09IDAgJiYgIShyZXF1ZXN0LnJlc3BvbnNlVVJMICYmIHJlcXVlc3QucmVzcG9uc2VVUkwuaW5kZXhPZignZmlsZTonKSA9PT0gMCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBQcmVwYXJlIHRoZSByZXNwb25zZVxuICAgICAgdmFyIHJlc3BvbnNlSGVhZGVycyA9ICdnZXRBbGxSZXNwb25zZUhlYWRlcnMnIGluIHJlcXVlc3QgPyBwYXJzZUhlYWRlcnMocmVxdWVzdC5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSkgOiBudWxsO1xuICAgICAgdmFyIHJlc3BvbnNlRGF0YSA9ICFjb25maWcucmVzcG9uc2VUeXBlIHx8IGNvbmZpZy5yZXNwb25zZVR5cGUgPT09ICd0ZXh0JyA/IHJlcXVlc3QucmVzcG9uc2VUZXh0IDogcmVxdWVzdC5yZXNwb25zZTtcbiAgICAgIHZhciByZXNwb25zZSA9IHtcbiAgICAgICAgZGF0YTogcmVzcG9uc2VEYXRhLFxuICAgICAgICBzdGF0dXM6IHJlcXVlc3Quc3RhdHVzLFxuICAgICAgICBzdGF0dXNUZXh0OiByZXF1ZXN0LnN0YXR1c1RleHQsXG4gICAgICAgIGhlYWRlcnM6IHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgY29uZmlnOiBjb25maWcsXG4gICAgICAgIHJlcXVlc3Q6IHJlcXVlc3RcbiAgICAgIH07XG5cbiAgICAgIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdFxuICAgICAgcmVxdWVzdCA9IG51bGw7XG4gICAgfTtcblxuICAgIC8vIEhhbmRsZSBicm93c2VyIHJlcXVlc3QgY2FuY2VsbGF0aW9uIChhcyBvcHBvc2VkIHRvIGEgbWFudWFsIGNhbmNlbGxhdGlvbilcbiAgICByZXF1ZXN0Lm9uYWJvcnQgPSBmdW5jdGlvbiBoYW5kbGVBYm9ydCgpIHtcbiAgICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJlamVjdChjcmVhdGVFcnJvcignUmVxdWVzdCBhYm9ydGVkJywgY29uZmlnLCAnRUNPTk5BQk9SVEVEJywgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIGxvdyBsZXZlbCBuZXR3b3JrIGVycm9yc1xuICAgIHJlcXVlc3Qub25lcnJvciA9IGZ1bmN0aW9uIGhhbmRsZUVycm9yKCkge1xuICAgICAgLy8gUmVhbCBlcnJvcnMgYXJlIGhpZGRlbiBmcm9tIHVzIGJ5IHRoZSBicm93c2VyXG4gICAgICAvLyBvbmVycm9yIHNob3VsZCBvbmx5IGZpcmUgaWYgaXQncyBhIG5ldHdvcmsgZXJyb3JcbiAgICAgIHJlamVjdChjcmVhdGVFcnJvcignTmV0d29yayBFcnJvcicsIGNvbmZpZywgbnVsbCwgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIHRpbWVvdXRcbiAgICByZXF1ZXN0Lm9udGltZW91dCA9IGZ1bmN0aW9uIGhhbmRsZVRpbWVvdXQoKSB7XG4gICAgICB2YXIgdGltZW91dEVycm9yTWVzc2FnZSA9ICd0aW1lb3V0IG9mICcgKyBjb25maWcudGltZW91dCArICdtcyBleGNlZWRlZCc7XG4gICAgICBpZiAoY29uZmlnLnRpbWVvdXRFcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgdGltZW91dEVycm9yTWVzc2FnZSA9IGNvbmZpZy50aW1lb3V0RXJyb3JNZXNzYWdlO1xuICAgICAgfVxuICAgICAgcmVqZWN0KGNyZWF0ZUVycm9yKHRpbWVvdXRFcnJvck1lc3NhZ2UsIGNvbmZpZywgJ0VDT05OQUJPUlRFRCcsXG4gICAgICAgIHJlcXVlc3QpKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdFxuICAgICAgcmVxdWVzdCA9IG51bGw7XG4gICAgfTtcblxuICAgIC8vIEFkZCB4c3JmIGhlYWRlclxuICAgIC8vIFRoaXMgaXMgb25seSBkb25lIGlmIHJ1bm5pbmcgaW4gYSBzdGFuZGFyZCBicm93c2VyIGVudmlyb25tZW50LlxuICAgIC8vIFNwZWNpZmljYWxseSBub3QgaWYgd2UncmUgaW4gYSB3ZWIgd29ya2VyLCBvciByZWFjdC1uYXRpdmUuXG4gICAgaWYgKHV0aWxzLmlzU3RhbmRhcmRCcm93c2VyRW52KCkpIHtcbiAgICAgIC8vIEFkZCB4c3JmIGhlYWRlclxuICAgICAgdmFyIHhzcmZWYWx1ZSA9IChjb25maWcud2l0aENyZWRlbnRpYWxzIHx8IGlzVVJMU2FtZU9yaWdpbihmdWxsUGF0aCkpICYmIGNvbmZpZy54c3JmQ29va2llTmFtZSA/XG4gICAgICAgIGNvb2tpZXMucmVhZChjb25maWcueHNyZkNvb2tpZU5hbWUpIDpcbiAgICAgICAgdW5kZWZpbmVkO1xuXG4gICAgICBpZiAoeHNyZlZhbHVlKSB7XG4gICAgICAgIHJlcXVlc3RIZWFkZXJzW2NvbmZpZy54c3JmSGVhZGVyTmFtZV0gPSB4c3JmVmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWRkIGhlYWRlcnMgdG8gdGhlIHJlcXVlc3RcbiAgICBpZiAoJ3NldFJlcXVlc3RIZWFkZXInIGluIHJlcXVlc3QpIHtcbiAgICAgIHV0aWxzLmZvckVhY2gocmVxdWVzdEhlYWRlcnMsIGZ1bmN0aW9uIHNldFJlcXVlc3RIZWFkZXIodmFsLCBrZXkpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXF1ZXN0RGF0YSA9PT0gJ3VuZGVmaW5lZCcgJiYga2V5LnRvTG93ZXJDYXNlKCkgPT09ICdjb250ZW50LXR5cGUnKSB7XG4gICAgICAgICAgLy8gUmVtb3ZlIENvbnRlbnQtVHlwZSBpZiBkYXRhIGlzIHVuZGVmaW5lZFxuICAgICAgICAgIGRlbGV0ZSByZXF1ZXN0SGVhZGVyc1trZXldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE90aGVyd2lzZSBhZGQgaGVhZGVyIHRvIHRoZSByZXF1ZXN0XG4gICAgICAgICAgcmVxdWVzdC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgdmFsKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQWRkIHdpdGhDcmVkZW50aWFscyB0byByZXF1ZXN0IGlmIG5lZWRlZFxuICAgIGlmICghdXRpbHMuaXNVbmRlZmluZWQoY29uZmlnLndpdGhDcmVkZW50aWFscykpIHtcbiAgICAgIHJlcXVlc3Qud2l0aENyZWRlbnRpYWxzID0gISFjb25maWcud2l0aENyZWRlbnRpYWxzO1xuICAgIH1cblxuICAgIC8vIEFkZCByZXNwb25zZVR5cGUgdG8gcmVxdWVzdCBpZiBuZWVkZWRcbiAgICBpZiAoY29uZmlnLnJlc3BvbnNlVHlwZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVxdWVzdC5yZXNwb25zZVR5cGUgPSBjb25maWcucmVzcG9uc2VUeXBlO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBFeHBlY3RlZCBET01FeGNlcHRpb24gdGhyb3duIGJ5IGJyb3dzZXJzIG5vdCBjb21wYXRpYmxlIFhNTEh0dHBSZXF1ZXN0IExldmVsIDIuXG4gICAgICAgIC8vIEJ1dCwgdGhpcyBjYW4gYmUgc3VwcHJlc3NlZCBmb3IgJ2pzb24nIHR5cGUgYXMgaXQgY2FuIGJlIHBhcnNlZCBieSBkZWZhdWx0ICd0cmFuc2Zvcm1SZXNwb25zZScgZnVuY3Rpb24uXG4gICAgICAgIGlmIChjb25maWcucmVzcG9uc2VUeXBlICE9PSAnanNvbicpIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHByb2dyZXNzIGlmIG5lZWRlZFxuICAgIGlmICh0eXBlb2YgY29uZmlnLm9uRG93bmxvYWRQcm9ncmVzcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCdwcm9ncmVzcycsIGNvbmZpZy5vbkRvd25sb2FkUHJvZ3Jlc3MpO1xuICAgIH1cblxuICAgIC8vIE5vdCBhbGwgYnJvd3NlcnMgc3VwcG9ydCB1cGxvYWQgZXZlbnRzXG4gICAgaWYgKHR5cGVvZiBjb25maWcub25VcGxvYWRQcm9ncmVzcyA9PT0gJ2Z1bmN0aW9uJyAmJiByZXF1ZXN0LnVwbG9hZCkge1xuICAgICAgcmVxdWVzdC51cGxvYWQuYWRkRXZlbnRMaXN0ZW5lcigncHJvZ3Jlc3MnLCBjb25maWcub25VcGxvYWRQcm9ncmVzcyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5jYW5jZWxUb2tlbikge1xuICAgICAgLy8gSGFuZGxlIGNhbmNlbGxhdGlvblxuICAgICAgY29uZmlnLmNhbmNlbFRva2VuLnByb21pc2UudGhlbihmdW5jdGlvbiBvbkNhbmNlbGVkKGNhbmNlbCkge1xuICAgICAgICBpZiAoIXJlcXVlc3QpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0LmFib3J0KCk7XG4gICAgICAgIHJlamVjdChjYW5jZWwpO1xuICAgICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICAgIHJlcXVlc3QgPSBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCFyZXF1ZXN0RGF0YSkge1xuICAgICAgcmVxdWVzdERhdGEgPSBudWxsO1xuICAgIH1cblxuICAgIC8vIFNlbmQgdGhlIHJlcXVlc3RcbiAgICByZXF1ZXN0LnNlbmQocmVxdWVzdERhdGEpO1xuICB9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBiaW5kID0gcmVxdWlyZSgnLi9oZWxwZXJzL2JpbmQnKTtcbnZhciBBeGlvcyA9IHJlcXVpcmUoJy4vY29yZS9BeGlvcycpO1xudmFyIG1lcmdlQ29uZmlnID0gcmVxdWlyZSgnLi9jb3JlL21lcmdlQ29uZmlnJyk7XG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2RlZmF1bHRzJyk7XG5cbi8qKlxuICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIEF4aW9zXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGRlZmF1bHRDb25maWcgVGhlIGRlZmF1bHQgY29uZmlnIGZvciB0aGUgaW5zdGFuY2VcbiAqIEByZXR1cm4ge0F4aW9zfSBBIG5ldyBpbnN0YW5jZSBvZiBBeGlvc1xuICovXG5mdW5jdGlvbiBjcmVhdGVJbnN0YW5jZShkZWZhdWx0Q29uZmlnKSB7XG4gIHZhciBjb250ZXh0ID0gbmV3IEF4aW9zKGRlZmF1bHRDb25maWcpO1xuICB2YXIgaW5zdGFuY2UgPSBiaW5kKEF4aW9zLnByb3RvdHlwZS5yZXF1ZXN0LCBjb250ZXh0KTtcblxuICAvLyBDb3B5IGF4aW9zLnByb3RvdHlwZSB0byBpbnN0YW5jZVxuICB1dGlscy5leHRlbmQoaW5zdGFuY2UsIEF4aW9zLnByb3RvdHlwZSwgY29udGV4dCk7XG5cbiAgLy8gQ29weSBjb250ZXh0IHRvIGluc3RhbmNlXG4gIHV0aWxzLmV4dGVuZChpbnN0YW5jZSwgY29udGV4dCk7XG5cbiAgcmV0dXJuIGluc3RhbmNlO1xufVxuXG4vLyBDcmVhdGUgdGhlIGRlZmF1bHQgaW5zdGFuY2UgdG8gYmUgZXhwb3J0ZWRcbnZhciBheGlvcyA9IGNyZWF0ZUluc3RhbmNlKGRlZmF1bHRzKTtcblxuLy8gRXhwb3NlIEF4aW9zIGNsYXNzIHRvIGFsbG93IGNsYXNzIGluaGVyaXRhbmNlXG5heGlvcy5BeGlvcyA9IEF4aW9zO1xuXG4vLyBGYWN0b3J5IGZvciBjcmVhdGluZyBuZXcgaW5zdGFuY2VzXG5heGlvcy5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUoaW5zdGFuY2VDb25maWcpIHtcbiAgcmV0dXJuIGNyZWF0ZUluc3RhbmNlKG1lcmdlQ29uZmlnKGF4aW9zLmRlZmF1bHRzLCBpbnN0YW5jZUNvbmZpZykpO1xufTtcblxuLy8gRXhwb3NlIENhbmNlbCAmIENhbmNlbFRva2VuXG5heGlvcy5DYW5jZWwgPSByZXF1aXJlKCcuL2NhbmNlbC9DYW5jZWwnKTtcbmF4aW9zLkNhbmNlbFRva2VuID0gcmVxdWlyZSgnLi9jYW5jZWwvQ2FuY2VsVG9rZW4nKTtcbmF4aW9zLmlzQ2FuY2VsID0gcmVxdWlyZSgnLi9jYW5jZWwvaXNDYW5jZWwnKTtcblxuLy8gRXhwb3NlIGFsbC9zcHJlYWRcbmF4aW9zLmFsbCA9IGZ1bmN0aW9uIGFsbChwcm9taXNlcykge1xuICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xufTtcbmF4aW9zLnNwcmVhZCA9IHJlcXVpcmUoJy4vaGVscGVycy9zcHJlYWQnKTtcblxuLy8gRXhwb3NlIGlzQXhpb3NFcnJvclxuYXhpb3MuaXNBeGlvc0Vycm9yID0gcmVxdWlyZSgnLi9oZWxwZXJzL2lzQXhpb3NFcnJvcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGF4aW9zO1xuXG4vLyBBbGxvdyB1c2Ugb2YgZGVmYXVsdCBpbXBvcnQgc3ludGF4IGluIFR5cGVTY3JpcHRcbm1vZHVsZS5leHBvcnRzLmRlZmF1bHQgPSBheGlvcztcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBBIGBDYW5jZWxgIGlzIGFuIG9iamVjdCB0aGF0IGlzIHRocm93biB3aGVuIGFuIG9wZXJhdGlvbiBpcyBjYW5jZWxlZC5cbiAqXG4gKiBAY2xhc3NcbiAqIEBwYXJhbSB7c3RyaW5nPX0gbWVzc2FnZSBUaGUgbWVzc2FnZS5cbiAqL1xuZnVuY3Rpb24gQ2FuY2VsKG1lc3NhZ2UpIHtcbiAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbn1cblxuQ2FuY2VsLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICByZXR1cm4gJ0NhbmNlbCcgKyAodGhpcy5tZXNzYWdlID8gJzogJyArIHRoaXMubWVzc2FnZSA6ICcnKTtcbn07XG5cbkNhbmNlbC5wcm90b3R5cGUuX19DQU5DRUxfXyA9IHRydWU7XG5cbm1vZHVsZS5leHBvcnRzID0gQ2FuY2VsO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ2FuY2VsID0gcmVxdWlyZSgnLi9DYW5jZWwnKTtcblxuLyoqXG4gKiBBIGBDYW5jZWxUb2tlbmAgaXMgYW4gb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gcmVxdWVzdCBjYW5jZWxsYXRpb24gb2YgYW4gb3BlcmF0aW9uLlxuICpcbiAqIEBjbGFzc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZXhlY3V0b3IgVGhlIGV4ZWN1dG9yIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBDYW5jZWxUb2tlbihleGVjdXRvcikge1xuICBpZiAodHlwZW9mIGV4ZWN1dG9yICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZXhlY3V0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uLicpO1xuICB9XG5cbiAgdmFyIHJlc29sdmVQcm9taXNlO1xuICB0aGlzLnByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiBwcm9taXNlRXhlY3V0b3IocmVzb2x2ZSkge1xuICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgfSk7XG5cbiAgdmFyIHRva2VuID0gdGhpcztcbiAgZXhlY3V0b3IoZnVuY3Rpb24gY2FuY2VsKG1lc3NhZ2UpIHtcbiAgICBpZiAodG9rZW4ucmVhc29uKSB7XG4gICAgICAvLyBDYW5jZWxsYXRpb24gaGFzIGFscmVhZHkgYmVlbiByZXF1ZXN0ZWRcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0b2tlbi5yZWFzb24gPSBuZXcgQ2FuY2VsKG1lc3NhZ2UpO1xuICAgIHJlc29sdmVQcm9taXNlKHRva2VuLnJlYXNvbik7XG4gIH0pO1xufVxuXG4vKipcbiAqIFRocm93cyBhIGBDYW5jZWxgIGlmIGNhbmNlbGxhdGlvbiBoYXMgYmVlbiByZXF1ZXN0ZWQuXG4gKi9cbkNhbmNlbFRva2VuLnByb3RvdHlwZS50aHJvd0lmUmVxdWVzdGVkID0gZnVuY3Rpb24gdGhyb3dJZlJlcXVlc3RlZCgpIHtcbiAgaWYgKHRoaXMucmVhc29uKSB7XG4gICAgdGhyb3cgdGhpcy5yZWFzb247XG4gIH1cbn07XG5cbi8qKlxuICogUmV0dXJucyBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhIG5ldyBgQ2FuY2VsVG9rZW5gIGFuZCBhIGZ1bmN0aW9uIHRoYXQsIHdoZW4gY2FsbGVkLFxuICogY2FuY2VscyB0aGUgYENhbmNlbFRva2VuYC5cbiAqL1xuQ2FuY2VsVG9rZW4uc291cmNlID0gZnVuY3Rpb24gc291cmNlKCkge1xuICB2YXIgY2FuY2VsO1xuICB2YXIgdG9rZW4gPSBuZXcgQ2FuY2VsVG9rZW4oZnVuY3Rpb24gZXhlY3V0b3IoYykge1xuICAgIGNhbmNlbCA9IGM7XG4gIH0pO1xuICByZXR1cm4ge1xuICAgIHRva2VuOiB0b2tlbixcbiAgICBjYW5jZWw6IGNhbmNlbFxuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBDYW5jZWxUb2tlbjtcbiIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0NhbmNlbCh2YWx1ZSkge1xuICByZXR1cm4gISEodmFsdWUgJiYgdmFsdWUuX19DQU5DRUxfXyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG52YXIgYnVpbGRVUkwgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2J1aWxkVVJMJyk7XG52YXIgSW50ZXJjZXB0b3JNYW5hZ2VyID0gcmVxdWlyZSgnLi9JbnRlcmNlcHRvck1hbmFnZXInKTtcbnZhciBkaXNwYXRjaFJlcXVlc3QgPSByZXF1aXJlKCcuL2Rpc3BhdGNoUmVxdWVzdCcpO1xudmFyIG1lcmdlQ29uZmlnID0gcmVxdWlyZSgnLi9tZXJnZUNvbmZpZycpO1xuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBBeGlvc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBpbnN0YW5jZUNvbmZpZyBUaGUgZGVmYXVsdCBjb25maWcgZm9yIHRoZSBpbnN0YW5jZVxuICovXG5mdW5jdGlvbiBBeGlvcyhpbnN0YW5jZUNvbmZpZykge1xuICB0aGlzLmRlZmF1bHRzID0gaW5zdGFuY2VDb25maWc7XG4gIHRoaXMuaW50ZXJjZXB0b3JzID0ge1xuICAgIHJlcXVlc3Q6IG5ldyBJbnRlcmNlcHRvck1hbmFnZXIoKSxcbiAgICByZXNwb25zZTogbmV3IEludGVyY2VwdG9yTWFuYWdlcigpXG4gIH07XG59XG5cbi8qKlxuICogRGlzcGF0Y2ggYSByZXF1ZXN0XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyBUaGUgY29uZmlnIHNwZWNpZmljIGZvciB0aGlzIHJlcXVlc3QgKG1lcmdlZCB3aXRoIHRoaXMuZGVmYXVsdHMpXG4gKi9cbkF4aW9zLnByb3RvdHlwZS5yZXF1ZXN0ID0gZnVuY3Rpb24gcmVxdWVzdChjb25maWcpIHtcbiAgLyplc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246MCovXG4gIC8vIEFsbG93IGZvciBheGlvcygnZXhhbXBsZS91cmwnWywgY29uZmlnXSkgYSBsYSBmZXRjaCBBUElcbiAgaWYgKHR5cGVvZiBjb25maWcgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uZmlnID0gYXJndW1lbnRzWzFdIHx8IHt9O1xuICAgIGNvbmZpZy51cmwgPSBhcmd1bWVudHNbMF07XG4gIH0gZWxzZSB7XG4gICAgY29uZmlnID0gY29uZmlnIHx8IHt9O1xuICB9XG5cbiAgY29uZmlnID0gbWVyZ2VDb25maWcodGhpcy5kZWZhdWx0cywgY29uZmlnKTtcblxuICAvLyBTZXQgY29uZmlnLm1ldGhvZFxuICBpZiAoY29uZmlnLm1ldGhvZCkge1xuICAgIGNvbmZpZy5tZXRob2QgPSBjb25maWcubWV0aG9kLnRvTG93ZXJDYXNlKCk7XG4gIH0gZWxzZSBpZiAodGhpcy5kZWZhdWx0cy5tZXRob2QpIHtcbiAgICBjb25maWcubWV0aG9kID0gdGhpcy5kZWZhdWx0cy5tZXRob2QudG9Mb3dlckNhc2UoKTtcbiAgfSBlbHNlIHtcbiAgICBjb25maWcubWV0aG9kID0gJ2dldCc7XG4gIH1cblxuICAvLyBIb29rIHVwIGludGVyY2VwdG9ycyBtaWRkbGV3YXJlXG4gIHZhciBjaGFpbiA9IFtkaXNwYXRjaFJlcXVlc3QsIHVuZGVmaW5lZF07XG4gIHZhciBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKGNvbmZpZyk7XG5cbiAgdGhpcy5pbnRlcmNlcHRvcnMucmVxdWVzdC5mb3JFYWNoKGZ1bmN0aW9uIHVuc2hpZnRSZXF1ZXN0SW50ZXJjZXB0b3JzKGludGVyY2VwdG9yKSB7XG4gICAgY2hhaW4udW5zaGlmdChpbnRlcmNlcHRvci5mdWxmaWxsZWQsIGludGVyY2VwdG9yLnJlamVjdGVkKTtcbiAgfSk7XG5cbiAgdGhpcy5pbnRlcmNlcHRvcnMucmVzcG9uc2UuZm9yRWFjaChmdW5jdGlvbiBwdXNoUmVzcG9uc2VJbnRlcmNlcHRvcnMoaW50ZXJjZXB0b3IpIHtcbiAgICBjaGFpbi5wdXNoKGludGVyY2VwdG9yLmZ1bGZpbGxlZCwgaW50ZXJjZXB0b3IucmVqZWN0ZWQpO1xuICB9KTtcblxuICB3aGlsZSAoY2hhaW4ubGVuZ3RoKSB7XG4gICAgcHJvbWlzZSA9IHByb21pc2UudGhlbihjaGFpbi5zaGlmdCgpLCBjaGFpbi5zaGlmdCgpKTtcbiAgfVxuXG4gIHJldHVybiBwcm9taXNlO1xufTtcblxuQXhpb3MucHJvdG90eXBlLmdldFVyaSA9IGZ1bmN0aW9uIGdldFVyaShjb25maWcpIHtcbiAgY29uZmlnID0gbWVyZ2VDb25maWcodGhpcy5kZWZhdWx0cywgY29uZmlnKTtcbiAgcmV0dXJuIGJ1aWxkVVJMKGNvbmZpZy51cmwsIGNvbmZpZy5wYXJhbXMsIGNvbmZpZy5wYXJhbXNTZXJpYWxpemVyKS5yZXBsYWNlKC9eXFw/LywgJycpO1xufTtcblxuLy8gUHJvdmlkZSBhbGlhc2VzIGZvciBzdXBwb3J0ZWQgcmVxdWVzdCBtZXRob2RzXG51dGlscy5mb3JFYWNoKFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ29wdGlvbnMnXSwgZnVuY3Rpb24gZm9yRWFjaE1ldGhvZE5vRGF0YShtZXRob2QpIHtcbiAgLyplc2xpbnQgZnVuYy1uYW1lczowKi9cbiAgQXhpb3MucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbih1cmwsIGNvbmZpZykge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QobWVyZ2VDb25maWcoY29uZmlnIHx8IHt9LCB7XG4gICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgIHVybDogdXJsLFxuICAgICAgZGF0YTogKGNvbmZpZyB8fCB7fSkuZGF0YVxuICAgIH0pKTtcbiAgfTtcbn0pO1xuXG51dGlscy5mb3JFYWNoKFsncG9zdCcsICdwdXQnLCAncGF0Y2gnXSwgZnVuY3Rpb24gZm9yRWFjaE1ldGhvZFdpdGhEYXRhKG1ldGhvZCkge1xuICAvKmVzbGludCBmdW5jLW5hbWVzOjAqL1xuICBBeGlvcy5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChtZXJnZUNvbmZpZyhjb25maWcgfHwge30sIHtcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgdXJsOiB1cmwsXG4gICAgICBkYXRhOiBkYXRhXG4gICAgfSkpO1xuICB9O1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gQXhpb3M7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcblxuZnVuY3Rpb24gSW50ZXJjZXB0b3JNYW5hZ2VyKCkge1xuICB0aGlzLmhhbmRsZXJzID0gW107XG59XG5cbi8qKlxuICogQWRkIGEgbmV3IGludGVyY2VwdG9yIHRvIHRoZSBzdGFja1xuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bGZpbGxlZCBUaGUgZnVuY3Rpb24gdG8gaGFuZGxlIGB0aGVuYCBmb3IgYSBgUHJvbWlzZWBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHJlamVjdGVkIFRoZSBmdW5jdGlvbiB0byBoYW5kbGUgYHJlamVjdGAgZm9yIGEgYFByb21pc2VgXG4gKlxuICogQHJldHVybiB7TnVtYmVyfSBBbiBJRCB1c2VkIHRvIHJlbW92ZSBpbnRlcmNlcHRvciBsYXRlclxuICovXG5JbnRlcmNlcHRvck1hbmFnZXIucHJvdG90eXBlLnVzZSA9IGZ1bmN0aW9uIHVzZShmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gIHRoaXMuaGFuZGxlcnMucHVzaCh7XG4gICAgZnVsZmlsbGVkOiBmdWxmaWxsZWQsXG4gICAgcmVqZWN0ZWQ6IHJlamVjdGVkXG4gIH0pO1xuICByZXR1cm4gdGhpcy5oYW5kbGVycy5sZW5ndGggLSAxO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgYW4gaW50ZXJjZXB0b3IgZnJvbSB0aGUgc3RhY2tcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gaWQgVGhlIElEIHRoYXQgd2FzIHJldHVybmVkIGJ5IGB1c2VgXG4gKi9cbkludGVyY2VwdG9yTWFuYWdlci5wcm90b3R5cGUuZWplY3QgPSBmdW5jdGlvbiBlamVjdChpZCkge1xuICBpZiAodGhpcy5oYW5kbGVyc1tpZF0pIHtcbiAgICB0aGlzLmhhbmRsZXJzW2lkXSA9IG51bGw7XG4gIH1cbn07XG5cbi8qKlxuICogSXRlcmF0ZSBvdmVyIGFsbCB0aGUgcmVnaXN0ZXJlZCBpbnRlcmNlcHRvcnNcbiAqXG4gKiBUaGlzIG1ldGhvZCBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIGZvciBza2lwcGluZyBvdmVyIGFueVxuICogaW50ZXJjZXB0b3JzIHRoYXQgbWF5IGhhdmUgYmVjb21lIGBudWxsYCBjYWxsaW5nIGBlamVjdGAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggaW50ZXJjZXB0b3JcbiAqL1xuSW50ZXJjZXB0b3JNYW5hZ2VyLnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24gZm9yRWFjaChmbikge1xuICB1dGlscy5mb3JFYWNoKHRoaXMuaGFuZGxlcnMsIGZ1bmN0aW9uIGZvckVhY2hIYW5kbGVyKGgpIHtcbiAgICBpZiAoaCAhPT0gbnVsbCkge1xuICAgICAgZm4oaCk7XG4gICAgfVxuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gSW50ZXJjZXB0b3JNYW5hZ2VyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaXNBYnNvbHV0ZVVSTCA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNBYnNvbHV0ZVVSTCcpO1xudmFyIGNvbWJpbmVVUkxzID0gcmVxdWlyZSgnLi4vaGVscGVycy9jb21iaW5lVVJMcycpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgVVJMIGJ5IGNvbWJpbmluZyB0aGUgYmFzZVVSTCB3aXRoIHRoZSByZXF1ZXN0ZWRVUkwsXG4gKiBvbmx5IHdoZW4gdGhlIHJlcXVlc3RlZFVSTCBpcyBub3QgYWxyZWFkeSBhbiBhYnNvbHV0ZSBVUkwuXG4gKiBJZiB0aGUgcmVxdWVzdFVSTCBpcyBhYnNvbHV0ZSwgdGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSByZXF1ZXN0ZWRVUkwgdW50b3VjaGVkLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlVVJMIFRoZSBiYXNlIFVSTFxuICogQHBhcmFtIHtzdHJpbmd9IHJlcXVlc3RlZFVSTCBBYnNvbHV0ZSBvciByZWxhdGl2ZSBVUkwgdG8gY29tYmluZVxuICogQHJldHVybnMge3N0cmluZ30gVGhlIGNvbWJpbmVkIGZ1bGwgcGF0aFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJ1aWxkRnVsbFBhdGgoYmFzZVVSTCwgcmVxdWVzdGVkVVJMKSB7XG4gIGlmIChiYXNlVVJMICYmICFpc0Fic29sdXRlVVJMKHJlcXVlc3RlZFVSTCkpIHtcbiAgICByZXR1cm4gY29tYmluZVVSTHMoYmFzZVVSTCwgcmVxdWVzdGVkVVJMKTtcbiAgfVxuICByZXR1cm4gcmVxdWVzdGVkVVJMO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGVuaGFuY2VFcnJvciA9IHJlcXVpcmUoJy4vZW5oYW5jZUVycm9yJyk7XG5cbi8qKlxuICogQ3JlYXRlIGFuIEVycm9yIHdpdGggdGhlIHNwZWNpZmllZCBtZXNzYWdlLCBjb25maWcsIGVycm9yIGNvZGUsIHJlcXVlc3QgYW5kIHJlc3BvbnNlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyBUaGUgY29uZmlnLlxuICogQHBhcmFtIHtzdHJpbmd9IFtjb2RlXSBUaGUgZXJyb3IgY29kZSAoZm9yIGV4YW1wbGUsICdFQ09OTkFCT1JURUQnKS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVxdWVzdF0gVGhlIHJlcXVlc3QuXG4gKiBAcGFyYW0ge09iamVjdH0gW3Jlc3BvbnNlXSBUaGUgcmVzcG9uc2UuXG4gKiBAcmV0dXJucyB7RXJyb3J9IFRoZSBjcmVhdGVkIGVycm9yLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZUVycm9yKG1lc3NhZ2UsIGNvbmZpZywgY29kZSwgcmVxdWVzdCwgcmVzcG9uc2UpIHtcbiAgdmFyIGVycm9yID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xuICByZXR1cm4gZW5oYW5jZUVycm9yKGVycm9yLCBjb25maWcsIGNvZGUsIHJlcXVlc3QsIHJlc3BvbnNlKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcbnZhciB0cmFuc2Zvcm1EYXRhID0gcmVxdWlyZSgnLi90cmFuc2Zvcm1EYXRhJyk7XG52YXIgaXNDYW5jZWwgPSByZXF1aXJlKCcuLi9jYW5jZWwvaXNDYW5jZWwnKTtcbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2RlZmF1bHRzJyk7XG5cbi8qKlxuICogVGhyb3dzIGEgYENhbmNlbGAgaWYgY2FuY2VsbGF0aW9uIGhhcyBiZWVuIHJlcXVlc3RlZC5cbiAqL1xuZnVuY3Rpb24gdGhyb3dJZkNhbmNlbGxhdGlvblJlcXVlc3RlZChjb25maWcpIHtcbiAgaWYgKGNvbmZpZy5jYW5jZWxUb2tlbikge1xuICAgIGNvbmZpZy5jYW5jZWxUb2tlbi50aHJvd0lmUmVxdWVzdGVkKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBEaXNwYXRjaCBhIHJlcXVlc3QgdG8gdGhlIHNlcnZlciB1c2luZyB0aGUgY29uZmlndXJlZCBhZGFwdGVyLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgVGhlIGNvbmZpZyB0aGF0IGlzIHRvIGJlIHVzZWQgZm9yIHRoZSByZXF1ZXN0XG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gVGhlIFByb21pc2UgdG8gYmUgZnVsZmlsbGVkXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZGlzcGF0Y2hSZXF1ZXN0KGNvbmZpZykge1xuICB0aHJvd0lmQ2FuY2VsbGF0aW9uUmVxdWVzdGVkKGNvbmZpZyk7XG5cbiAgLy8gRW5zdXJlIGhlYWRlcnMgZXhpc3RcbiAgY29uZmlnLmhlYWRlcnMgPSBjb25maWcuaGVhZGVycyB8fCB7fTtcblxuICAvLyBUcmFuc2Zvcm0gcmVxdWVzdCBkYXRhXG4gIGNvbmZpZy5kYXRhID0gdHJhbnNmb3JtRGF0YShcbiAgICBjb25maWcuZGF0YSxcbiAgICBjb25maWcuaGVhZGVycyxcbiAgICBjb25maWcudHJhbnNmb3JtUmVxdWVzdFxuICApO1xuXG4gIC8vIEZsYXR0ZW4gaGVhZGVyc1xuICBjb25maWcuaGVhZGVycyA9IHV0aWxzLm1lcmdlKFxuICAgIGNvbmZpZy5oZWFkZXJzLmNvbW1vbiB8fCB7fSxcbiAgICBjb25maWcuaGVhZGVyc1tjb25maWcubWV0aG9kXSB8fCB7fSxcbiAgICBjb25maWcuaGVhZGVyc1xuICApO1xuXG4gIHV0aWxzLmZvckVhY2goXG4gICAgWydkZWxldGUnLCAnZ2V0JywgJ2hlYWQnLCAncG9zdCcsICdwdXQnLCAncGF0Y2gnLCAnY29tbW9uJ10sXG4gICAgZnVuY3Rpb24gY2xlYW5IZWFkZXJDb25maWcobWV0aG9kKSB7XG4gICAgICBkZWxldGUgY29uZmlnLmhlYWRlcnNbbWV0aG9kXTtcbiAgICB9XG4gICk7XG5cbiAgdmFyIGFkYXB0ZXIgPSBjb25maWcuYWRhcHRlciB8fCBkZWZhdWx0cy5hZGFwdGVyO1xuXG4gIHJldHVybiBhZGFwdGVyKGNvbmZpZykudGhlbihmdW5jdGlvbiBvbkFkYXB0ZXJSZXNvbHV0aW9uKHJlc3BvbnNlKSB7XG4gICAgdGhyb3dJZkNhbmNlbGxhdGlvblJlcXVlc3RlZChjb25maWcpO1xuXG4gICAgLy8gVHJhbnNmb3JtIHJlc3BvbnNlIGRhdGFcbiAgICByZXNwb25zZS5kYXRhID0gdHJhbnNmb3JtRGF0YShcbiAgICAgIHJlc3BvbnNlLmRhdGEsXG4gICAgICByZXNwb25zZS5oZWFkZXJzLFxuICAgICAgY29uZmlnLnRyYW5zZm9ybVJlc3BvbnNlXG4gICAgKTtcblxuICAgIHJldHVybiByZXNwb25zZTtcbiAgfSwgZnVuY3Rpb24gb25BZGFwdGVyUmVqZWN0aW9uKHJlYXNvbikge1xuICAgIGlmICghaXNDYW5jZWwocmVhc29uKSkge1xuICAgICAgdGhyb3dJZkNhbmNlbGxhdGlvblJlcXVlc3RlZChjb25maWcpO1xuXG4gICAgICAvLyBUcmFuc2Zvcm0gcmVzcG9uc2UgZGF0YVxuICAgICAgaWYgKHJlYXNvbiAmJiByZWFzb24ucmVzcG9uc2UpIHtcbiAgICAgICAgcmVhc29uLnJlc3BvbnNlLmRhdGEgPSB0cmFuc2Zvcm1EYXRhKFxuICAgICAgICAgIHJlYXNvbi5yZXNwb25zZS5kYXRhLFxuICAgICAgICAgIHJlYXNvbi5yZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICAgIGNvbmZpZy50cmFuc2Zvcm1SZXNwb25zZVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChyZWFzb24pO1xuICB9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogVXBkYXRlIGFuIEVycm9yIHdpdGggdGhlIHNwZWNpZmllZCBjb25maWcsIGVycm9yIGNvZGUsIGFuZCByZXNwb25zZS5cbiAqXG4gKiBAcGFyYW0ge0Vycm9yfSBlcnJvciBUaGUgZXJyb3IgdG8gdXBkYXRlLlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyBUaGUgY29uZmlnLlxuICogQHBhcmFtIHtzdHJpbmd9IFtjb2RlXSBUaGUgZXJyb3IgY29kZSAoZm9yIGV4YW1wbGUsICdFQ09OTkFCT1JURUQnKS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVxdWVzdF0gVGhlIHJlcXVlc3QuXG4gKiBAcGFyYW0ge09iamVjdH0gW3Jlc3BvbnNlXSBUaGUgcmVzcG9uc2UuXG4gKiBAcmV0dXJucyB7RXJyb3J9IFRoZSBlcnJvci5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBlbmhhbmNlRXJyb3IoZXJyb3IsIGNvbmZpZywgY29kZSwgcmVxdWVzdCwgcmVzcG9uc2UpIHtcbiAgZXJyb3IuY29uZmlnID0gY29uZmlnO1xuICBpZiAoY29kZSkge1xuICAgIGVycm9yLmNvZGUgPSBjb2RlO1xuICB9XG5cbiAgZXJyb3IucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIGVycm9yLnJlc3BvbnNlID0gcmVzcG9uc2U7XG4gIGVycm9yLmlzQXhpb3NFcnJvciA9IHRydWU7XG5cbiAgZXJyb3IudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgIHJldHVybiB7XG4gICAgICAvLyBTdGFuZGFyZFxuICAgICAgbWVzc2FnZTogdGhpcy5tZXNzYWdlLFxuICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgLy8gTWljcm9zb2Z0XG4gICAgICBkZXNjcmlwdGlvbjogdGhpcy5kZXNjcmlwdGlvbixcbiAgICAgIG51bWJlcjogdGhpcy5udW1iZXIsXG4gICAgICAvLyBNb3ppbGxhXG4gICAgICBmaWxlTmFtZTogdGhpcy5maWxlTmFtZSxcbiAgICAgIGxpbmVOdW1iZXI6IHRoaXMubGluZU51bWJlcixcbiAgICAgIGNvbHVtbk51bWJlcjogdGhpcy5jb2x1bW5OdW1iZXIsXG4gICAgICBzdGFjazogdGhpcy5zdGFjayxcbiAgICAgIC8vIEF4aW9zXG4gICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgY29kZTogdGhpcy5jb2RlXG4gICAgfTtcbiAgfTtcbiAgcmV0dXJuIGVycm9yO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcblxuLyoqXG4gKiBDb25maWctc3BlY2lmaWMgbWVyZ2UtZnVuY3Rpb24gd2hpY2ggY3JlYXRlcyBhIG5ldyBjb25maWctb2JqZWN0XG4gKiBieSBtZXJnaW5nIHR3byBjb25maWd1cmF0aW9uIG9iamVjdHMgdG9nZXRoZXIuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZzFcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcyXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBOZXcgb2JqZWN0IHJlc3VsdGluZyBmcm9tIG1lcmdpbmcgY29uZmlnMiB0byBjb25maWcxXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbWVyZ2VDb25maWcoY29uZmlnMSwgY29uZmlnMikge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgY29uZmlnMiA9IGNvbmZpZzIgfHwge307XG4gIHZhciBjb25maWcgPSB7fTtcblxuICB2YXIgdmFsdWVGcm9tQ29uZmlnMktleXMgPSBbJ3VybCcsICdtZXRob2QnLCAnZGF0YSddO1xuICB2YXIgbWVyZ2VEZWVwUHJvcGVydGllc0tleXMgPSBbJ2hlYWRlcnMnLCAnYXV0aCcsICdwcm94eScsICdwYXJhbXMnXTtcbiAgdmFyIGRlZmF1bHRUb0NvbmZpZzJLZXlzID0gW1xuICAgICdiYXNlVVJMJywgJ3RyYW5zZm9ybVJlcXVlc3QnLCAndHJhbnNmb3JtUmVzcG9uc2UnLCAncGFyYW1zU2VyaWFsaXplcicsXG4gICAgJ3RpbWVvdXQnLCAndGltZW91dE1lc3NhZ2UnLCAnd2l0aENyZWRlbnRpYWxzJywgJ2FkYXB0ZXInLCAncmVzcG9uc2VUeXBlJywgJ3hzcmZDb29raWVOYW1lJyxcbiAgICAneHNyZkhlYWRlck5hbWUnLCAnb25VcGxvYWRQcm9ncmVzcycsICdvbkRvd25sb2FkUHJvZ3Jlc3MnLCAnZGVjb21wcmVzcycsXG4gICAgJ21heENvbnRlbnRMZW5ndGgnLCAnbWF4Qm9keUxlbmd0aCcsICdtYXhSZWRpcmVjdHMnLCAndHJhbnNwb3J0JywgJ2h0dHBBZ2VudCcsXG4gICAgJ2h0dHBzQWdlbnQnLCAnY2FuY2VsVG9rZW4nLCAnc29ja2V0UGF0aCcsICdyZXNwb25zZUVuY29kaW5nJ1xuICBdO1xuICB2YXIgZGlyZWN0TWVyZ2VLZXlzID0gWyd2YWxpZGF0ZVN0YXR1cyddO1xuXG4gIGZ1bmN0aW9uIGdldE1lcmdlZFZhbHVlKHRhcmdldCwgc291cmNlKSB7XG4gICAgaWYgKHV0aWxzLmlzUGxhaW5PYmplY3QodGFyZ2V0KSAmJiB1dGlscy5pc1BsYWluT2JqZWN0KHNvdXJjZSkpIHtcbiAgICAgIHJldHVybiB1dGlscy5tZXJnZSh0YXJnZXQsIHNvdXJjZSk7XG4gICAgfSBlbHNlIGlmICh1dGlscy5pc1BsYWluT2JqZWN0KHNvdXJjZSkpIHtcbiAgICAgIHJldHVybiB1dGlscy5tZXJnZSh7fSwgc291cmNlKTtcbiAgICB9IGVsc2UgaWYgKHV0aWxzLmlzQXJyYXkoc291cmNlKSkge1xuICAgICAgcmV0dXJuIHNvdXJjZS5zbGljZSgpO1xuICAgIH1cbiAgICByZXR1cm4gc291cmNlO1xuICB9XG5cbiAgZnVuY3Rpb24gbWVyZ2VEZWVwUHJvcGVydGllcyhwcm9wKSB7XG4gICAgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChjb25maWcyW3Byb3BdKSkge1xuICAgICAgY29uZmlnW3Byb3BdID0gZ2V0TWVyZ2VkVmFsdWUoY29uZmlnMVtwcm9wXSwgY29uZmlnMltwcm9wXSk7XG4gICAgfSBlbHNlIGlmICghdXRpbHMuaXNVbmRlZmluZWQoY29uZmlnMVtwcm9wXSkpIHtcbiAgICAgIGNvbmZpZ1twcm9wXSA9IGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgY29uZmlnMVtwcm9wXSk7XG4gICAgfVxuICB9XG5cbiAgdXRpbHMuZm9yRWFjaCh2YWx1ZUZyb21Db25maWcyS2V5cywgZnVuY3Rpb24gdmFsdWVGcm9tQ29uZmlnMihwcm9wKSB7XG4gICAgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChjb25maWcyW3Byb3BdKSkge1xuICAgICAgY29uZmlnW3Byb3BdID0gZ2V0TWVyZ2VkVmFsdWUodW5kZWZpbmVkLCBjb25maWcyW3Byb3BdKTtcbiAgICB9XG4gIH0pO1xuXG4gIHV0aWxzLmZvckVhY2gobWVyZ2VEZWVwUHJvcGVydGllc0tleXMsIG1lcmdlRGVlcFByb3BlcnRpZXMpO1xuXG4gIHV0aWxzLmZvckVhY2goZGVmYXVsdFRvQ29uZmlnMktleXMsIGZ1bmN0aW9uIGRlZmF1bHRUb0NvbmZpZzIocHJvcCkge1xuICAgIGlmICghdXRpbHMuaXNVbmRlZmluZWQoY29uZmlnMltwcm9wXSkpIHtcbiAgICAgIGNvbmZpZ1twcm9wXSA9IGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgY29uZmlnMltwcm9wXSk7XG4gICAgfSBlbHNlIGlmICghdXRpbHMuaXNVbmRlZmluZWQoY29uZmlnMVtwcm9wXSkpIHtcbiAgICAgIGNvbmZpZ1twcm9wXSA9IGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgY29uZmlnMVtwcm9wXSk7XG4gICAgfVxuICB9KTtcblxuICB1dGlscy5mb3JFYWNoKGRpcmVjdE1lcmdlS2V5cywgZnVuY3Rpb24gbWVyZ2UocHJvcCkge1xuICAgIGlmIChwcm9wIGluIGNvbmZpZzIpIHtcbiAgICAgIGNvbmZpZ1twcm9wXSA9IGdldE1lcmdlZFZhbHVlKGNvbmZpZzFbcHJvcF0sIGNvbmZpZzJbcHJvcF0pO1xuICAgIH0gZWxzZSBpZiAocHJvcCBpbiBjb25maWcxKSB7XG4gICAgICBjb25maWdbcHJvcF0gPSBnZXRNZXJnZWRWYWx1ZSh1bmRlZmluZWQsIGNvbmZpZzFbcHJvcF0pO1xuICAgIH1cbiAgfSk7XG5cbiAgdmFyIGF4aW9zS2V5cyA9IHZhbHVlRnJvbUNvbmZpZzJLZXlzXG4gICAgLmNvbmNhdChtZXJnZURlZXBQcm9wZXJ0aWVzS2V5cylcbiAgICAuY29uY2F0KGRlZmF1bHRUb0NvbmZpZzJLZXlzKVxuICAgIC5jb25jYXQoZGlyZWN0TWVyZ2VLZXlzKTtcblxuICB2YXIgb3RoZXJLZXlzID0gT2JqZWN0XG4gICAgLmtleXMoY29uZmlnMSlcbiAgICAuY29uY2F0KE9iamVjdC5rZXlzKGNvbmZpZzIpKVxuICAgIC5maWx0ZXIoZnVuY3Rpb24gZmlsdGVyQXhpb3NLZXlzKGtleSkge1xuICAgICAgcmV0dXJuIGF4aW9zS2V5cy5pbmRleE9mKGtleSkgPT09IC0xO1xuICAgIH0pO1xuXG4gIHV0aWxzLmZvckVhY2gob3RoZXJLZXlzLCBtZXJnZURlZXBQcm9wZXJ0aWVzKTtcblxuICByZXR1cm4gY29uZmlnO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNyZWF0ZUVycm9yID0gcmVxdWlyZSgnLi9jcmVhdGVFcnJvcicpO1xuXG4vKipcbiAqIFJlc29sdmUgb3IgcmVqZWN0IGEgUHJvbWlzZSBiYXNlZCBvbiByZXNwb25zZSBzdGF0dXMuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVzb2x2ZSBBIGZ1bmN0aW9uIHRoYXQgcmVzb2x2ZXMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3QgQSBmdW5jdGlvbiB0aGF0IHJlamVjdHMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge29iamVjdH0gcmVzcG9uc2UgVGhlIHJlc3BvbnNlLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlKSB7XG4gIHZhciB2YWxpZGF0ZVN0YXR1cyA9IHJlc3BvbnNlLmNvbmZpZy52YWxpZGF0ZVN0YXR1cztcbiAgaWYgKCFyZXNwb25zZS5zdGF0dXMgfHwgIXZhbGlkYXRlU3RhdHVzIHx8IHZhbGlkYXRlU3RhdHVzKHJlc3BvbnNlLnN0YXR1cykpIHtcbiAgICByZXNvbHZlKHJlc3BvbnNlKTtcbiAgfSBlbHNlIHtcbiAgICByZWplY3QoY3JlYXRlRXJyb3IoXG4gICAgICAnUmVxdWVzdCBmYWlsZWQgd2l0aCBzdGF0dXMgY29kZSAnICsgcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgcmVzcG9uc2UuY29uZmlnLFxuICAgICAgbnVsbCxcbiAgICAgIHJlc3BvbnNlLnJlcXVlc3QsXG4gICAgICByZXNwb25zZVxuICAgICkpO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG5cbi8qKlxuICogVHJhbnNmb3JtIHRoZSBkYXRhIGZvciBhIHJlcXVlc3Qgb3IgYSByZXNwb25zZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fFN0cmluZ30gZGF0YSBUaGUgZGF0YSB0byBiZSB0cmFuc2Zvcm1lZFxuICogQHBhcmFtIHtBcnJheX0gaGVhZGVycyBUaGUgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3Qgb3IgcmVzcG9uc2VcbiAqIEBwYXJhbSB7QXJyYXl8RnVuY3Rpb259IGZucyBBIHNpbmdsZSBmdW5jdGlvbiBvciBBcnJheSBvZiBmdW5jdGlvbnNcbiAqIEByZXR1cm5zIHsqfSBUaGUgcmVzdWx0aW5nIHRyYW5zZm9ybWVkIGRhdGFcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB0cmFuc2Zvcm1EYXRhKGRhdGEsIGhlYWRlcnMsIGZucykge1xuICAvKmVzbGludCBuby1wYXJhbS1yZWFzc2lnbjowKi9cbiAgdXRpbHMuZm9yRWFjaChmbnMsIGZ1bmN0aW9uIHRyYW5zZm9ybShmbikge1xuICAgIGRhdGEgPSBmbihkYXRhLCBoZWFkZXJzKTtcbiAgfSk7XG5cbiAgcmV0dXJuIGRhdGE7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgbm9ybWFsaXplSGVhZGVyTmFtZSA9IHJlcXVpcmUoJy4vaGVscGVycy9ub3JtYWxpemVIZWFkZXJOYW1lJyk7XG5cbnZhciBERUZBVUxUX0NPTlRFTlRfVFlQRSA9IHtcbiAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXG59O1xuXG5mdW5jdGlvbiBzZXRDb250ZW50VHlwZUlmVW5zZXQoaGVhZGVycywgdmFsdWUpIHtcbiAgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChoZWFkZXJzKSAmJiB1dGlscy5pc1VuZGVmaW5lZChoZWFkZXJzWydDb250ZW50LVR5cGUnXSkpIHtcbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IHZhbHVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldERlZmF1bHRBZGFwdGVyKCkge1xuICB2YXIgYWRhcHRlcjtcbiAgaWYgKHR5cGVvZiBYTUxIdHRwUmVxdWVzdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAvLyBGb3IgYnJvd3NlcnMgdXNlIFhIUiBhZGFwdGVyXG4gICAgYWRhcHRlciA9IHJlcXVpcmUoJy4vYWRhcHRlcnMveGhyJyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChwcm9jZXNzKSA9PT0gJ1tvYmplY3QgcHJvY2Vzc10nKSB7XG4gICAgLy8gRm9yIG5vZGUgdXNlIEhUVFAgYWRhcHRlclxuICAgIGFkYXB0ZXIgPSByZXF1aXJlKCcuL2FkYXB0ZXJzL2h0dHAnKTtcbiAgfVxuICByZXR1cm4gYWRhcHRlcjtcbn1cblxudmFyIGRlZmF1bHRzID0ge1xuICBhZGFwdGVyOiBnZXREZWZhdWx0QWRhcHRlcigpLFxuXG4gIHRyYW5zZm9ybVJlcXVlc3Q6IFtmdW5jdGlvbiB0cmFuc2Zvcm1SZXF1ZXN0KGRhdGEsIGhlYWRlcnMpIHtcbiAgICBub3JtYWxpemVIZWFkZXJOYW1lKGhlYWRlcnMsICdBY2NlcHQnKTtcbiAgICBub3JtYWxpemVIZWFkZXJOYW1lKGhlYWRlcnMsICdDb250ZW50LVR5cGUnKTtcbiAgICBpZiAodXRpbHMuaXNGb3JtRGF0YShkYXRhKSB8fFxuICAgICAgdXRpbHMuaXNBcnJheUJ1ZmZlcihkYXRhKSB8fFxuICAgICAgdXRpbHMuaXNCdWZmZXIoZGF0YSkgfHxcbiAgICAgIHV0aWxzLmlzU3RyZWFtKGRhdGEpIHx8XG4gICAgICB1dGlscy5pc0ZpbGUoZGF0YSkgfHxcbiAgICAgIHV0aWxzLmlzQmxvYihkYXRhKVxuICAgICkge1xuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuICAgIGlmICh1dGlscy5pc0FycmF5QnVmZmVyVmlldyhkYXRhKSkge1xuICAgICAgcmV0dXJuIGRhdGEuYnVmZmVyO1xuICAgIH1cbiAgICBpZiAodXRpbHMuaXNVUkxTZWFyY2hQYXJhbXMoZGF0YSkpIHtcbiAgICAgIHNldENvbnRlbnRUeXBlSWZVbnNldChoZWFkZXJzLCAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkO2NoYXJzZXQ9dXRmLTgnKTtcbiAgICAgIHJldHVybiBkYXRhLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIGlmICh1dGlscy5pc09iamVjdChkYXRhKSkge1xuICAgICAgc2V0Q29udGVudFR5cGVJZlVuc2V0KGhlYWRlcnMsICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTgnKTtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShkYXRhKTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1dLFxuXG4gIHRyYW5zZm9ybVJlc3BvbnNlOiBbZnVuY3Rpb24gdHJhbnNmb3JtUmVzcG9uc2UoZGF0YSkge1xuICAgIC8qZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOjAqL1xuICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGRhdGEgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgfSBjYXRjaCAoZSkgeyAvKiBJZ25vcmUgKi8gfVxuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfV0sXG5cbiAgLyoqXG4gICAqIEEgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgdG8gYWJvcnQgYSByZXF1ZXN0LiBJZiBzZXQgdG8gMCAoZGVmYXVsdCkgYVxuICAgKiB0aW1lb3V0IGlzIG5vdCBjcmVhdGVkLlxuICAgKi9cbiAgdGltZW91dDogMCxcblxuICB4c3JmQ29va2llTmFtZTogJ1hTUkYtVE9LRU4nLFxuICB4c3JmSGVhZGVyTmFtZTogJ1gtWFNSRi1UT0tFTicsXG5cbiAgbWF4Q29udGVudExlbmd0aDogLTEsXG4gIG1heEJvZHlMZW5ndGg6IC0xLFxuXG4gIHZhbGlkYXRlU3RhdHVzOiBmdW5jdGlvbiB2YWxpZGF0ZVN0YXR1cyhzdGF0dXMpIHtcbiAgICByZXR1cm4gc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDA7XG4gIH1cbn07XG5cbmRlZmF1bHRzLmhlYWRlcnMgPSB7XG4gIGNvbW1vbjoge1xuICAgICdBY2NlcHQnOiAnYXBwbGljYXRpb24vanNvbiwgdGV4dC9wbGFpbiwgKi8qJ1xuICB9XG59O1xuXG51dGlscy5mb3JFYWNoKFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJ10sIGZ1bmN0aW9uIGZvckVhY2hNZXRob2ROb0RhdGEobWV0aG9kKSB7XG4gIGRlZmF1bHRzLmhlYWRlcnNbbWV0aG9kXSA9IHt9O1xufSk7XG5cbnV0aWxzLmZvckVhY2goWydwb3N0JywgJ3B1dCcsICdwYXRjaCddLCBmdW5jdGlvbiBmb3JFYWNoTWV0aG9kV2l0aERhdGEobWV0aG9kKSB7XG4gIGRlZmF1bHRzLmhlYWRlcnNbbWV0aG9kXSA9IHV0aWxzLm1lcmdlKERFRkFVTFRfQ09OVEVOVF9UWVBFKTtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlZmF1bHRzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJpbmQoZm4sIHRoaXNBcmcpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHdyYXAoKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJncyk7XG4gIH07XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG5cbmZ1bmN0aW9uIGVuY29kZSh2YWwpIHtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudCh2YWwpLlxuICAgIHJlcGxhY2UoLyUzQS9naSwgJzonKS5cbiAgICByZXBsYWNlKC8lMjQvZywgJyQnKS5cbiAgICByZXBsYWNlKC8lMkMvZ2ksICcsJykuXG4gICAgcmVwbGFjZSgvJTIwL2csICcrJykuXG4gICAgcmVwbGFjZSgvJTVCL2dpLCAnWycpLlxuICAgIHJlcGxhY2UoLyU1RC9naSwgJ10nKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIFVSTCBieSBhcHBlbmRpbmcgcGFyYW1zIHRvIHRoZSBlbmRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdXJsIFRoZSBiYXNlIG9mIHRoZSB1cmwgKGUuZy4sIGh0dHA6Ly93d3cuZ29vZ2xlLmNvbSlcbiAqIEBwYXJhbSB7b2JqZWN0fSBbcGFyYW1zXSBUaGUgcGFyYW1zIHRvIGJlIGFwcGVuZGVkXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHVybFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJ1aWxkVVJMKHVybCwgcGFyYW1zLCBwYXJhbXNTZXJpYWxpemVyKSB7XG4gIC8qZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOjAqL1xuICBpZiAoIXBhcmFtcykge1xuICAgIHJldHVybiB1cmw7XG4gIH1cblxuICB2YXIgc2VyaWFsaXplZFBhcmFtcztcbiAgaWYgKHBhcmFtc1NlcmlhbGl6ZXIpIHtcbiAgICBzZXJpYWxpemVkUGFyYW1zID0gcGFyYW1zU2VyaWFsaXplcihwYXJhbXMpO1xuICB9IGVsc2UgaWYgKHV0aWxzLmlzVVJMU2VhcmNoUGFyYW1zKHBhcmFtcykpIHtcbiAgICBzZXJpYWxpemVkUGFyYW1zID0gcGFyYW1zLnRvU3RyaW5nKCk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHBhcnRzID0gW107XG5cbiAgICB1dGlscy5mb3JFYWNoKHBhcmFtcywgZnVuY3Rpb24gc2VyaWFsaXplKHZhbCwga2V5KSB7XG4gICAgICBpZiAodmFsID09PSBudWxsIHx8IHR5cGVvZiB2YWwgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHV0aWxzLmlzQXJyYXkodmFsKSkge1xuICAgICAgICBrZXkgPSBrZXkgKyAnW10nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsID0gW3ZhbF07XG4gICAgICB9XG5cbiAgICAgIHV0aWxzLmZvckVhY2godmFsLCBmdW5jdGlvbiBwYXJzZVZhbHVlKHYpIHtcbiAgICAgICAgaWYgKHV0aWxzLmlzRGF0ZSh2KSkge1xuICAgICAgICAgIHYgPSB2LnRvSVNPU3RyaW5nKCk7XG4gICAgICAgIH0gZWxzZSBpZiAodXRpbHMuaXNPYmplY3QodikpIHtcbiAgICAgICAgICB2ID0gSlNPTi5zdHJpbmdpZnkodik7XG4gICAgICAgIH1cbiAgICAgICAgcGFydHMucHVzaChlbmNvZGUoa2V5KSArICc9JyArIGVuY29kZSh2KSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHNlcmlhbGl6ZWRQYXJhbXMgPSBwYXJ0cy5qb2luKCcmJyk7XG4gIH1cblxuICBpZiAoc2VyaWFsaXplZFBhcmFtcykge1xuICAgIHZhciBoYXNobWFya0luZGV4ID0gdXJsLmluZGV4T2YoJyMnKTtcbiAgICBpZiAoaGFzaG1hcmtJbmRleCAhPT0gLTEpIHtcbiAgICAgIHVybCA9IHVybC5zbGljZSgwLCBoYXNobWFya0luZGV4KTtcbiAgICB9XG5cbiAgICB1cmwgKz0gKHVybC5pbmRleE9mKCc/JykgPT09IC0xID8gJz8nIDogJyYnKSArIHNlcmlhbGl6ZWRQYXJhbXM7XG4gIH1cblxuICByZXR1cm4gdXJsO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IFVSTCBieSBjb21iaW5pbmcgdGhlIHNwZWNpZmllZCBVUkxzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2VVUkwgVGhlIGJhc2UgVVJMXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVsYXRpdmVVUkwgVGhlIHJlbGF0aXZlIFVSTFxuICogQHJldHVybnMge3N0cmluZ30gVGhlIGNvbWJpbmVkIFVSTFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNvbWJpbmVVUkxzKGJhc2VVUkwsIHJlbGF0aXZlVVJMKSB7XG4gIHJldHVybiByZWxhdGl2ZVVSTFxuICAgID8gYmFzZVVSTC5yZXBsYWNlKC9cXC8rJC8sICcnKSArICcvJyArIHJlbGF0aXZlVVJMLnJlcGxhY2UoL15cXC8rLywgJycpXG4gICAgOiBiYXNlVVJMO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi8uLi91dGlscycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChcbiAgdXRpbHMuaXNTdGFuZGFyZEJyb3dzZXJFbnYoKSA/XG5cbiAgLy8gU3RhbmRhcmQgYnJvd3NlciBlbnZzIHN1cHBvcnQgZG9jdW1lbnQuY29va2llXG4gICAgKGZ1bmN0aW9uIHN0YW5kYXJkQnJvd3NlckVudigpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHdyaXRlOiBmdW5jdGlvbiB3cml0ZShuYW1lLCB2YWx1ZSwgZXhwaXJlcywgcGF0aCwgZG9tYWluLCBzZWN1cmUpIHtcbiAgICAgICAgICB2YXIgY29va2llID0gW107XG4gICAgICAgICAgY29va2llLnB1c2gobmFtZSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSkpO1xuXG4gICAgICAgICAgaWYgKHV0aWxzLmlzTnVtYmVyKGV4cGlyZXMpKSB7XG4gICAgICAgICAgICBjb29raWUucHVzaCgnZXhwaXJlcz0nICsgbmV3IERhdGUoZXhwaXJlcykudG9HTVRTdHJpbmcoKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHV0aWxzLmlzU3RyaW5nKHBhdGgpKSB7XG4gICAgICAgICAgICBjb29raWUucHVzaCgncGF0aD0nICsgcGF0aCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHV0aWxzLmlzU3RyaW5nKGRvbWFpbikpIHtcbiAgICAgICAgICAgIGNvb2tpZS5wdXNoKCdkb21haW49JyArIGRvbWFpbik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNlY3VyZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgY29va2llLnB1c2goJ3NlY3VyZScpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRvY3VtZW50LmNvb2tpZSA9IGNvb2tpZS5qb2luKCc7ICcpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHJlYWQ6IGZ1bmN0aW9uIHJlYWQobmFtZSkge1xuICAgICAgICAgIHZhciBtYXRjaCA9IGRvY3VtZW50LmNvb2tpZS5tYXRjaChuZXcgUmVnRXhwKCcoXnw7XFxcXHMqKSgnICsgbmFtZSArICcpPShbXjtdKiknKSk7XG4gICAgICAgICAgcmV0dXJuIChtYXRjaCA/IGRlY29kZVVSSUNvbXBvbmVudChtYXRjaFszXSkgOiBudWxsKTtcbiAgICAgICAgfSxcblxuICAgICAgICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZShuYW1lKSB7XG4gICAgICAgICAgdGhpcy53cml0ZShuYW1lLCAnJywgRGF0ZS5ub3coKSAtIDg2NDAwMDAwKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9KSgpIDpcblxuICAvLyBOb24gc3RhbmRhcmQgYnJvd3NlciBlbnYgKHdlYiB3b3JrZXJzLCByZWFjdC1uYXRpdmUpIGxhY2sgbmVlZGVkIHN1cHBvcnQuXG4gICAgKGZ1bmN0aW9uIG5vblN0YW5kYXJkQnJvd3NlckVudigpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHdyaXRlOiBmdW5jdGlvbiB3cml0ZSgpIHt9LFxuICAgICAgICByZWFkOiBmdW5jdGlvbiByZWFkKCkgeyByZXR1cm4gbnVsbDsgfSxcbiAgICAgICAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUoKSB7fVxuICAgICAgfTtcbiAgICB9KSgpXG4pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIFVSTCBpcyBhYnNvbHV0ZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIFVSTCB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIFVSTCBpcyBhYnNvbHV0ZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBYnNvbHV0ZVVSTCh1cmwpIHtcbiAgLy8gQSBVUkwgaXMgY29uc2lkZXJlZCBhYnNvbHV0ZSBpZiBpdCBiZWdpbnMgd2l0aCBcIjxzY2hlbWU+Oi8vXCIgb3IgXCIvL1wiIChwcm90b2NvbC1yZWxhdGl2ZSBVUkwpLlxuICAvLyBSRkMgMzk4NiBkZWZpbmVzIHNjaGVtZSBuYW1lIGFzIGEgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyBiZWdpbm5pbmcgd2l0aCBhIGxldHRlciBhbmQgZm9sbG93ZWRcbiAgLy8gYnkgYW55IGNvbWJpbmF0aW9uIG9mIGxldHRlcnMsIGRpZ2l0cywgcGx1cywgcGVyaW9kLCBvciBoeXBoZW4uXG4gIHJldHVybiAvXihbYS16XVthLXpcXGRcXCtcXC1cXC5dKjopP1xcL1xcLy9pLnRlc3QodXJsKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBwYXlsb2FkIGlzIGFuIGVycm9yIHRocm93biBieSBBeGlvc1xuICpcbiAqIEBwYXJhbSB7Kn0gcGF5bG9hZCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHBheWxvYWQgaXMgYW4gZXJyb3IgdGhyb3duIGJ5IEF4aW9zLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0F4aW9zRXJyb3IocGF5bG9hZCkge1xuICByZXR1cm4gKHR5cGVvZiBwYXlsb2FkID09PSAnb2JqZWN0JykgJiYgKHBheWxvYWQuaXNBeGlvc0Vycm9yID09PSB0cnVlKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAoXG4gIHV0aWxzLmlzU3RhbmRhcmRCcm93c2VyRW52KCkgP1xuXG4gIC8vIFN0YW5kYXJkIGJyb3dzZXIgZW52cyBoYXZlIGZ1bGwgc3VwcG9ydCBvZiB0aGUgQVBJcyBuZWVkZWQgdG8gdGVzdFxuICAvLyB3aGV0aGVyIHRoZSByZXF1ZXN0IFVSTCBpcyBvZiB0aGUgc2FtZSBvcmlnaW4gYXMgY3VycmVudCBsb2NhdGlvbi5cbiAgICAoZnVuY3Rpb24gc3RhbmRhcmRCcm93c2VyRW52KCkge1xuICAgICAgdmFyIG1zaWUgPSAvKG1zaWV8dHJpZGVudCkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICAgICAgdmFyIHVybFBhcnNpbmdOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgICAgdmFyIG9yaWdpblVSTDtcblxuICAgICAgLyoqXG4gICAgKiBQYXJzZSBhIFVSTCB0byBkaXNjb3ZlciBpdCdzIGNvbXBvbmVudHNcbiAgICAqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gdXJsIFRoZSBVUkwgdG8gYmUgcGFyc2VkXG4gICAgKiBAcmV0dXJucyB7T2JqZWN0fVxuICAgICovXG4gICAgICBmdW5jdGlvbiByZXNvbHZlVVJMKHVybCkge1xuICAgICAgICB2YXIgaHJlZiA9IHVybDtcblxuICAgICAgICBpZiAobXNpZSkge1xuICAgICAgICAvLyBJRSBuZWVkcyBhdHRyaWJ1dGUgc2V0IHR3aWNlIHRvIG5vcm1hbGl6ZSBwcm9wZXJ0aWVzXG4gICAgICAgICAgdXJsUGFyc2luZ05vZGUuc2V0QXR0cmlidXRlKCdocmVmJywgaHJlZik7XG4gICAgICAgICAgaHJlZiA9IHVybFBhcnNpbmdOb2RlLmhyZWY7XG4gICAgICAgIH1cblxuICAgICAgICB1cmxQYXJzaW5nTm9kZS5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBocmVmKTtcblxuICAgICAgICAvLyB1cmxQYXJzaW5nTm9kZSBwcm92aWRlcyB0aGUgVXJsVXRpbHMgaW50ZXJmYWNlIC0gaHR0cDovL3VybC5zcGVjLndoYXR3Zy5vcmcvI3VybHV0aWxzXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgaHJlZjogdXJsUGFyc2luZ05vZGUuaHJlZixcbiAgICAgICAgICBwcm90b2NvbDogdXJsUGFyc2luZ05vZGUucHJvdG9jb2wgPyB1cmxQYXJzaW5nTm9kZS5wcm90b2NvbC5yZXBsYWNlKC86JC8sICcnKSA6ICcnLFxuICAgICAgICAgIGhvc3Q6IHVybFBhcnNpbmdOb2RlLmhvc3QsXG4gICAgICAgICAgc2VhcmNoOiB1cmxQYXJzaW5nTm9kZS5zZWFyY2ggPyB1cmxQYXJzaW5nTm9kZS5zZWFyY2gucmVwbGFjZSgvXlxcPy8sICcnKSA6ICcnLFxuICAgICAgICAgIGhhc2g6IHVybFBhcnNpbmdOb2RlLmhhc2ggPyB1cmxQYXJzaW5nTm9kZS5oYXNoLnJlcGxhY2UoL14jLywgJycpIDogJycsXG4gICAgICAgICAgaG9zdG5hbWU6IHVybFBhcnNpbmdOb2RlLmhvc3RuYW1lLFxuICAgICAgICAgIHBvcnQ6IHVybFBhcnNpbmdOb2RlLnBvcnQsXG4gICAgICAgICAgcGF0aG5hbWU6ICh1cmxQYXJzaW5nTm9kZS5wYXRobmFtZS5jaGFyQXQoMCkgPT09ICcvJykgP1xuICAgICAgICAgICAgdXJsUGFyc2luZ05vZGUucGF0aG5hbWUgOlxuICAgICAgICAgICAgJy8nICsgdXJsUGFyc2luZ05vZGUucGF0aG5hbWVcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgb3JpZ2luVVJMID0gcmVzb2x2ZVVSTCh3aW5kb3cubG9jYXRpb24uaHJlZik7XG5cbiAgICAgIC8qKlxuICAgICogRGV0ZXJtaW5lIGlmIGEgVVJMIHNoYXJlcyB0aGUgc2FtZSBvcmlnaW4gYXMgdGhlIGN1cnJlbnQgbG9jYXRpb25cbiAgICAqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gcmVxdWVzdFVSTCBUaGUgVVJMIHRvIHRlc3RcbiAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIFVSTCBzaGFyZXMgdGhlIHNhbWUgb3JpZ2luLCBvdGhlcndpc2UgZmFsc2VcbiAgICAqL1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGlzVVJMU2FtZU9yaWdpbihyZXF1ZXN0VVJMKSB7XG4gICAgICAgIHZhciBwYXJzZWQgPSAodXRpbHMuaXNTdHJpbmcocmVxdWVzdFVSTCkpID8gcmVzb2x2ZVVSTChyZXF1ZXN0VVJMKSA6IHJlcXVlc3RVUkw7XG4gICAgICAgIHJldHVybiAocGFyc2VkLnByb3RvY29sID09PSBvcmlnaW5VUkwucHJvdG9jb2wgJiZcbiAgICAgICAgICAgIHBhcnNlZC5ob3N0ID09PSBvcmlnaW5VUkwuaG9zdCk7XG4gICAgICB9O1xuICAgIH0pKCkgOlxuXG4gIC8vIE5vbiBzdGFuZGFyZCBicm93c2VyIGVudnMgKHdlYiB3b3JrZXJzLCByZWFjdC1uYXRpdmUpIGxhY2sgbmVlZGVkIHN1cHBvcnQuXG4gICAgKGZ1bmN0aW9uIG5vblN0YW5kYXJkQnJvd3NlckVudigpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbiBpc1VSTFNhbWVPcmlnaW4oKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfTtcbiAgICB9KSgpXG4pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG5vcm1hbGl6ZUhlYWRlck5hbWUoaGVhZGVycywgbm9ybWFsaXplZE5hbWUpIHtcbiAgdXRpbHMuZm9yRWFjaChoZWFkZXJzLCBmdW5jdGlvbiBwcm9jZXNzSGVhZGVyKHZhbHVlLCBuYW1lKSB7XG4gICAgaWYgKG5hbWUgIT09IG5vcm1hbGl6ZWROYW1lICYmIG5hbWUudG9VcHBlckNhc2UoKSA9PT0gbm9ybWFsaXplZE5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgaGVhZGVyc1tub3JtYWxpemVkTmFtZV0gPSB2YWx1ZTtcbiAgICAgIGRlbGV0ZSBoZWFkZXJzW25hbWVdO1xuICAgIH1cbiAgfSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG5cbi8vIEhlYWRlcnMgd2hvc2UgZHVwbGljYXRlcyBhcmUgaWdub3JlZCBieSBub2RlXG4vLyBjLmYuIGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvaHR0cC5odG1sI2h0dHBfbWVzc2FnZV9oZWFkZXJzXG52YXIgaWdub3JlRHVwbGljYXRlT2YgPSBbXG4gICdhZ2UnLCAnYXV0aG9yaXphdGlvbicsICdjb250ZW50LWxlbmd0aCcsICdjb250ZW50LXR5cGUnLCAnZXRhZycsXG4gICdleHBpcmVzJywgJ2Zyb20nLCAnaG9zdCcsICdpZi1tb2RpZmllZC1zaW5jZScsICdpZi11bm1vZGlmaWVkLXNpbmNlJyxcbiAgJ2xhc3QtbW9kaWZpZWQnLCAnbG9jYXRpb24nLCAnbWF4LWZvcndhcmRzJywgJ3Byb3h5LWF1dGhvcml6YXRpb24nLFxuICAncmVmZXJlcicsICdyZXRyeS1hZnRlcicsICd1c2VyLWFnZW50J1xuXTtcblxuLyoqXG4gKiBQYXJzZSBoZWFkZXJzIGludG8gYW4gb2JqZWN0XG4gKlxuICogYGBgXG4gKiBEYXRlOiBXZWQsIDI3IEF1ZyAyMDE0IDA4OjU4OjQ5IEdNVFxuICogQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uXG4gKiBDb25uZWN0aW9uOiBrZWVwLWFsaXZlXG4gKiBUcmFuc2Zlci1FbmNvZGluZzogY2h1bmtlZFxuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGhlYWRlcnMgSGVhZGVycyBuZWVkaW5nIHRvIGJlIHBhcnNlZFxuICogQHJldHVybnMge09iamVjdH0gSGVhZGVycyBwYXJzZWQgaW50byBhbiBvYmplY3RcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYXJzZUhlYWRlcnMoaGVhZGVycykge1xuICB2YXIgcGFyc2VkID0ge307XG4gIHZhciBrZXk7XG4gIHZhciB2YWw7XG4gIHZhciBpO1xuXG4gIGlmICghaGVhZGVycykgeyByZXR1cm4gcGFyc2VkOyB9XG5cbiAgdXRpbHMuZm9yRWFjaChoZWFkZXJzLnNwbGl0KCdcXG4nKSwgZnVuY3Rpb24gcGFyc2VyKGxpbmUpIHtcbiAgICBpID0gbGluZS5pbmRleE9mKCc6Jyk7XG4gICAga2V5ID0gdXRpbHMudHJpbShsaW5lLnN1YnN0cigwLCBpKSkudG9Mb3dlckNhc2UoKTtcbiAgICB2YWwgPSB1dGlscy50cmltKGxpbmUuc3Vic3RyKGkgKyAxKSk7XG5cbiAgICBpZiAoa2V5KSB7XG4gICAgICBpZiAocGFyc2VkW2tleV0gJiYgaWdub3JlRHVwbGljYXRlT2YuaW5kZXhPZihrZXkpID49IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGtleSA9PT0gJ3NldC1jb29raWUnKSB7XG4gICAgICAgIHBhcnNlZFtrZXldID0gKHBhcnNlZFtrZXldID8gcGFyc2VkW2tleV0gOiBbXSkuY29uY2F0KFt2YWxdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcnNlZFtrZXldID0gcGFyc2VkW2tleV0gPyBwYXJzZWRba2V5XSArICcsICcgKyB2YWwgOiB2YWw7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcGFyc2VkO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTeW50YWN0aWMgc3VnYXIgZm9yIGludm9raW5nIGEgZnVuY3Rpb24gYW5kIGV4cGFuZGluZyBhbiBhcnJheSBmb3IgYXJndW1lbnRzLlxuICpcbiAqIENvbW1vbiB1c2UgY2FzZSB3b3VsZCBiZSB0byB1c2UgYEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseWAuXG4gKlxuICogIGBgYGpzXG4gKiAgZnVuY3Rpb24gZih4LCB5LCB6KSB7fVxuICogIHZhciBhcmdzID0gWzEsIDIsIDNdO1xuICogIGYuYXBwbHkobnVsbCwgYXJncyk7XG4gKiAgYGBgXG4gKlxuICogV2l0aCBgc3ByZWFkYCB0aGlzIGV4YW1wbGUgY2FuIGJlIHJlLXdyaXR0ZW4uXG4gKlxuICogIGBgYGpzXG4gKiAgc3ByZWFkKGZ1bmN0aW9uKHgsIHksIHopIHt9KShbMSwgMiwgM10pO1xuICogIGBgYFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259XG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc3ByZWFkKGNhbGxiYWNrKSB7XG4gIHJldHVybiBmdW5jdGlvbiB3cmFwKGFycikge1xuICAgIHJldHVybiBjYWxsYmFjay5hcHBseShudWxsLCBhcnIpO1xuICB9O1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGJpbmQgPSByZXF1aXJlKCcuL2hlbHBlcnMvYmluZCcpO1xuXG4vKmdsb2JhbCB0b1N0cmluZzp0cnVlKi9cblxuLy8gdXRpbHMgaXMgYSBsaWJyYXJ5IG9mIGdlbmVyaWMgaGVscGVyIGZ1bmN0aW9ucyBub24tc3BlY2lmaWMgdG8gYXhpb3NcblxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhbiBBcnJheVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGFuIEFycmF5LCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcnJheSh2YWwpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyB1bmRlZmluZWRcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgdW5kZWZpbmVkLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNVbmRlZmluZWQodmFsKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsID09PSAndW5kZWZpbmVkJztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEJ1ZmZlclxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgQnVmZmVyLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNCdWZmZXIodmFsKSB7XG4gIHJldHVybiB2YWwgIT09IG51bGwgJiYgIWlzVW5kZWZpbmVkKHZhbCkgJiYgdmFsLmNvbnN0cnVjdG9yICE9PSBudWxsICYmICFpc1VuZGVmaW5lZCh2YWwuY29uc3RydWN0b3IpXG4gICAgJiYgdHlwZW9mIHZhbC5jb25zdHJ1Y3Rvci5pc0J1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJiB2YWwuY29uc3RydWN0b3IuaXNCdWZmZXIodmFsKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhbiBBcnJheUJ1ZmZlclxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGFuIEFycmF5QnVmZmVyLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcnJheUJ1ZmZlcih2YWwpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsKSA9PT0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEZvcm1EYXRhXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYW4gRm9ybURhdGEsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0Zvcm1EYXRhKHZhbCkge1xuICByZXR1cm4gKHR5cGVvZiBGb3JtRGF0YSAhPT0gJ3VuZGVmaW5lZCcpICYmICh2YWwgaW5zdGFuY2VvZiBGb3JtRGF0YSk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSB2aWV3IG9uIGFuIEFycmF5QnVmZmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSB2aWV3IG9uIGFuIEFycmF5QnVmZmVyLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcnJheUJ1ZmZlclZpZXcodmFsKSB7XG4gIHZhciByZXN1bHQ7XG4gIGlmICgodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJykgJiYgKEFycmF5QnVmZmVyLmlzVmlldykpIHtcbiAgICByZXN1bHQgPSBBcnJheUJ1ZmZlci5pc1ZpZXcodmFsKTtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSAodmFsKSAmJiAodmFsLmJ1ZmZlcikgJiYgKHZhbC5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcik7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIFN0cmluZ1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgU3RyaW5nLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTdHJpbmcodmFsKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsID09PSAnc3RyaW5nJztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIE51bWJlclxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgTnVtYmVyLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNOdW1iZXIodmFsKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsID09PSAnbnVtYmVyJztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhbiBPYmplY3RcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhbiBPYmplY3QsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWwpIHtcbiAgcmV0dXJuIHZhbCAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsID09PSAnb2JqZWN0Jztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIHBsYWluIE9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBwbGFpbiBPYmplY3QsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KHZhbCkge1xuICBpZiAodG9TdHJpbmcuY2FsbCh2YWwpICE9PSAnW29iamVjdCBPYmplY3RdJykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsKTtcbiAgcmV0dXJuIHByb3RvdHlwZSA9PT0gbnVsbCB8fCBwcm90b3R5cGUgPT09IE9iamVjdC5wcm90b3R5cGU7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBEYXRlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBEYXRlLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNEYXRlKHZhbCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWwpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBGaWxlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBGaWxlLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNGaWxlKHZhbCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWwpID09PSAnW29iamVjdCBGaWxlXSc7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBCbG9iXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBCbG9iLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNCbG9iKHZhbCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWwpID09PSAnW29iamVjdCBCbG9iXSc7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBGdW5jdGlvblxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRnVuY3Rpb24sIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWwpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgU3RyZWFtXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBTdHJlYW0sIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1N0cmVhbSh2YWwpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHZhbCkgJiYgaXNGdW5jdGlvbih2YWwucGlwZSk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBVUkxTZWFyY2hQYXJhbXMgb2JqZWN0XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBVUkxTZWFyY2hQYXJhbXMgb2JqZWN0LCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNVUkxTZWFyY2hQYXJhbXModmFsKSB7XG4gIHJldHVybiB0eXBlb2YgVVJMU2VhcmNoUGFyYW1zICE9PSAndW5kZWZpbmVkJyAmJiB2YWwgaW5zdGFuY2VvZiBVUkxTZWFyY2hQYXJhbXM7XG59XG5cbi8qKlxuICogVHJpbSBleGNlc3Mgd2hpdGVzcGFjZSBvZmYgdGhlIGJlZ2lubmluZyBhbmQgZW5kIG9mIGEgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0ciBUaGUgU3RyaW5nIHRvIHRyaW1cbiAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBTdHJpbmcgZnJlZWQgb2YgZXhjZXNzIHdoaXRlc3BhY2VcbiAqL1xuZnVuY3Rpb24gdHJpbShzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzKi8sICcnKS5yZXBsYWNlKC9cXHMqJC8sICcnKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgd2UncmUgcnVubmluZyBpbiBhIHN0YW5kYXJkIGJyb3dzZXIgZW52aXJvbm1lbnRcbiAqXG4gKiBUaGlzIGFsbG93cyBheGlvcyB0byBydW4gaW4gYSB3ZWIgd29ya2VyLCBhbmQgcmVhY3QtbmF0aXZlLlxuICogQm90aCBlbnZpcm9ubWVudHMgc3VwcG9ydCBYTUxIdHRwUmVxdWVzdCwgYnV0IG5vdCBmdWxseSBzdGFuZGFyZCBnbG9iYWxzLlxuICpcbiAqIHdlYiB3b3JrZXJzOlxuICogIHR5cGVvZiB3aW5kb3cgLT4gdW5kZWZpbmVkXG4gKiAgdHlwZW9mIGRvY3VtZW50IC0+IHVuZGVmaW5lZFxuICpcbiAqIHJlYWN0LW5hdGl2ZTpcbiAqICBuYXZpZ2F0b3IucHJvZHVjdCAtPiAnUmVhY3ROYXRpdmUnXG4gKiBuYXRpdmVzY3JpcHRcbiAqICBuYXZpZ2F0b3IucHJvZHVjdCAtPiAnTmF0aXZlU2NyaXB0JyBvciAnTlMnXG4gKi9cbmZ1bmN0aW9uIGlzU3RhbmRhcmRCcm93c2VyRW52KCkge1xuICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgKG5hdmlnYXRvci5wcm9kdWN0ID09PSAnUmVhY3ROYXRpdmUnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLnByb2R1Y3QgPT09ICdOYXRpdmVTY3JpcHQnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLnByb2R1Y3QgPT09ICdOUycpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnXG4gICk7XG59XG5cbi8qKlxuICogSXRlcmF0ZSBvdmVyIGFuIEFycmF5IG9yIGFuIE9iamVjdCBpbnZva2luZyBhIGZ1bmN0aW9uIGZvciBlYWNoIGl0ZW0uXG4gKlxuICogSWYgYG9iamAgaXMgYW4gQXJyYXkgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgcGFzc2luZ1xuICogdGhlIHZhbHVlLCBpbmRleCwgYW5kIGNvbXBsZXRlIGFycmF5IGZvciBlYWNoIGl0ZW0uXG4gKlxuICogSWYgJ29iaicgaXMgYW4gT2JqZWN0IGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHBhc3NpbmdcbiAqIHRoZSB2YWx1ZSwga2V5LCBhbmQgY29tcGxldGUgb2JqZWN0IGZvciBlYWNoIHByb3BlcnR5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBvYmogVGhlIG9iamVjdCB0byBpdGVyYXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIGZvciBlYWNoIGl0ZW1cbiAqL1xuZnVuY3Rpb24gZm9yRWFjaChvYmosIGZuKSB7XG4gIC8vIERvbid0IGJvdGhlciBpZiBubyB2YWx1ZSBwcm92aWRlZFxuICBpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRm9yY2UgYW4gYXJyYXkgaWYgbm90IGFscmVhZHkgc29tZXRoaW5nIGl0ZXJhYmxlXG4gIGlmICh0eXBlb2Ygb2JqICE9PSAnb2JqZWN0Jykge1xuICAgIC8qZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOjAqL1xuICAgIG9iaiA9IFtvYmpdO1xuICB9XG5cbiAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgIC8vIEl0ZXJhdGUgb3ZlciBhcnJheSB2YWx1ZXNcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IG9iai5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgb2JqW2ldLCBpLCBvYmopO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBJdGVyYXRlIG92ZXIgb2JqZWN0IGtleXNcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICBmbi5jYWxsKG51bGwsIG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQWNjZXB0cyB2YXJhcmdzIGV4cGVjdGluZyBlYWNoIGFyZ3VtZW50IHRvIGJlIGFuIG9iamVjdCwgdGhlblxuICogaW1tdXRhYmx5IG1lcmdlcyB0aGUgcHJvcGVydGllcyBvZiBlYWNoIG9iamVjdCBhbmQgcmV0dXJucyByZXN1bHQuXG4gKlxuICogV2hlbiBtdWx0aXBsZSBvYmplY3RzIGNvbnRhaW4gdGhlIHNhbWUga2V5IHRoZSBsYXRlciBvYmplY3QgaW5cbiAqIHRoZSBhcmd1bWVudHMgbGlzdCB3aWxsIHRha2UgcHJlY2VkZW5jZS5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqIGBgYGpzXG4gKiB2YXIgcmVzdWx0ID0gbWVyZ2Uoe2ZvbzogMTIzfSwge2ZvbzogNDU2fSk7XG4gKiBjb25zb2xlLmxvZyhyZXN1bHQuZm9vKTsgLy8gb3V0cHV0cyA0NTZcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmoxIE9iamVjdCB0byBtZXJnZVxuICogQHJldHVybnMge09iamVjdH0gUmVzdWx0IG9mIGFsbCBtZXJnZSBwcm9wZXJ0aWVzXG4gKi9cbmZ1bmN0aW9uIG1lcmdlKC8qIG9iajEsIG9iajIsIG9iajMsIC4uLiAqLykge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIGZ1bmN0aW9uIGFzc2lnblZhbHVlKHZhbCwga2V5KSB7XG4gICAgaWYgKGlzUGxhaW5PYmplY3QocmVzdWx0W2tleV0pICYmIGlzUGxhaW5PYmplY3QodmFsKSkge1xuICAgICAgcmVzdWx0W2tleV0gPSBtZXJnZShyZXN1bHRba2V5XSwgdmFsKTtcbiAgICB9IGVsc2UgaWYgKGlzUGxhaW5PYmplY3QodmFsKSkge1xuICAgICAgcmVzdWx0W2tleV0gPSBtZXJnZSh7fSwgdmFsKTtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkodmFsKSkge1xuICAgICAgcmVzdWx0W2tleV0gPSB2YWwuc2xpY2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0W2tleV0gPSB2YWw7XG4gICAgfVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgZm9yRWFjaChhcmd1bWVudHNbaV0sIGFzc2lnblZhbHVlKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEV4dGVuZHMgb2JqZWN0IGEgYnkgbXV0YWJseSBhZGRpbmcgdG8gaXQgdGhlIHByb3BlcnRpZXMgb2Ygb2JqZWN0IGIuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGEgVGhlIG9iamVjdCB0byBiZSBleHRlbmRlZFxuICogQHBhcmFtIHtPYmplY3R9IGIgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbVxuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgVGhlIG9iamVjdCB0byBiaW5kIGZ1bmN0aW9uIHRvXG4gKiBAcmV0dXJuIHtPYmplY3R9IFRoZSByZXN1bHRpbmcgdmFsdWUgb2Ygb2JqZWN0IGFcbiAqL1xuZnVuY3Rpb24gZXh0ZW5kKGEsIGIsIHRoaXNBcmcpIHtcbiAgZm9yRWFjaChiLCBmdW5jdGlvbiBhc3NpZ25WYWx1ZSh2YWwsIGtleSkge1xuICAgIGlmICh0aGlzQXJnICYmIHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGFba2V5XSA9IGJpbmQodmFsLCB0aGlzQXJnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYVtrZXldID0gdmFsO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBhO1xufVxuXG4vKipcbiAqIFJlbW92ZSBieXRlIG9yZGVyIG1hcmtlci4gVGhpcyBjYXRjaGVzIEVGIEJCIEJGICh0aGUgVVRGLTggQk9NKVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50IHdpdGggQk9NXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGNvbnRlbnQgdmFsdWUgd2l0aG91dCBCT01cbiAqL1xuZnVuY3Rpb24gc3RyaXBCT00oY29udGVudCkge1xuICBpZiAoY29udGVudC5jaGFyQ29kZUF0KDApID09PSAweEZFRkYpIHtcbiAgICBjb250ZW50ID0gY29udGVudC5zbGljZSgxKTtcbiAgfVxuICByZXR1cm4gY29udGVudDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGlzQXJyYXk6IGlzQXJyYXksXG4gIGlzQXJyYXlCdWZmZXI6IGlzQXJyYXlCdWZmZXIsXG4gIGlzQnVmZmVyOiBpc0J1ZmZlcixcbiAgaXNGb3JtRGF0YTogaXNGb3JtRGF0YSxcbiAgaXNBcnJheUJ1ZmZlclZpZXc6IGlzQXJyYXlCdWZmZXJWaWV3LFxuICBpc1N0cmluZzogaXNTdHJpbmcsXG4gIGlzTnVtYmVyOiBpc051bWJlcixcbiAgaXNPYmplY3Q6IGlzT2JqZWN0LFxuICBpc1BsYWluT2JqZWN0OiBpc1BsYWluT2JqZWN0LFxuICBpc1VuZGVmaW5lZDogaXNVbmRlZmluZWQsXG4gIGlzRGF0ZTogaXNEYXRlLFxuICBpc0ZpbGU6IGlzRmlsZSxcbiAgaXNCbG9iOiBpc0Jsb2IsXG4gIGlzRnVuY3Rpb246IGlzRnVuY3Rpb24sXG4gIGlzU3RyZWFtOiBpc1N0cmVhbSxcbiAgaXNVUkxTZWFyY2hQYXJhbXM6IGlzVVJMU2VhcmNoUGFyYW1zLFxuICBpc1N0YW5kYXJkQnJvd3NlckVudjogaXNTdGFuZGFyZEJyb3dzZXJFbnYsXG4gIGZvckVhY2g6IGZvckVhY2gsXG4gIG1lcmdlOiBtZXJnZSxcbiAgZXh0ZW5kOiBleHRlbmQsXG4gIHRyaW06IHRyaW0sXG4gIHN0cmlwQk9NOiBzdHJpcEJPTVxufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGJyb3dzZXIgZmllbGQsIGNoZWNrIG91dCB0aGUgYnJvd3NlciBmaWVsZCBhdCBodHRwczovL2dpdGh1Yi5jb20vc3Vic3RhY2svYnJvd3NlcmlmeS1oYW5kYm9vayNicm93c2VyLWZpZWxkLlxuXG52YXIgc3R5bGVFbGVtZW50c0luc2VydGVkQXRUb3AgPSBbXTtcblxudmFyIGluc2VydFN0eWxlRWxlbWVudCA9IGZ1bmN0aW9uKHN0eWxlRWxlbWVudCwgb3B0aW9ucykge1xuICAgIHZhciBoZWFkID0gZG9jdW1lbnQuaGVhZCB8fCBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdO1xuICAgIHZhciBsYXN0U3R5bGVFbGVtZW50SW5zZXJ0ZWRBdFRvcCA9IHN0eWxlRWxlbWVudHNJbnNlcnRlZEF0VG9wW3N0eWxlRWxlbWVudHNJbnNlcnRlZEF0VG9wLmxlbmd0aCAtIDFdO1xuXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgb3B0aW9ucy5pbnNlcnRBdCA9IG9wdGlvbnMuaW5zZXJ0QXQgfHwgJ2JvdHRvbSc7XG5cbiAgICBpZiAob3B0aW9ucy5pbnNlcnRBdCA9PT0gJ3RvcCcpIHtcbiAgICAgICAgaWYgKCFsYXN0U3R5bGVFbGVtZW50SW5zZXJ0ZWRBdFRvcCkge1xuICAgICAgICAgICAgaGVhZC5pbnNlcnRCZWZvcmUoc3R5bGVFbGVtZW50LCBoZWFkLmZpcnN0Q2hpbGQpO1xuICAgICAgICB9IGVsc2UgaWYgKGxhc3RTdHlsZUVsZW1lbnRJbnNlcnRlZEF0VG9wLm5leHRTaWJsaW5nKSB7XG4gICAgICAgICAgICBoZWFkLmluc2VydEJlZm9yZShzdHlsZUVsZW1lbnQsIGxhc3RTdHlsZUVsZW1lbnRJbnNlcnRlZEF0VG9wLm5leHRTaWJsaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcC5wdXNoKHN0eWxlRWxlbWVudCk7XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLmluc2VydEF0ID09PSAnYm90dG9tJykge1xuICAgICAgICBoZWFkLmFwcGVuZENoaWxkKHN0eWxlRWxlbWVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHZhbHVlIGZvciBwYXJhbWV0ZXIgXFwnaW5zZXJ0QXRcXCcuIE11c3QgYmUgXFwndG9wXFwnIG9yIFxcJ2JvdHRvbVxcJy4nKTtcbiAgICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICAvLyBDcmVhdGUgYSA8bGluaz4gdGFnIHdpdGggb3B0aW9uYWwgZGF0YSBhdHRyaWJ1dGVzXG4gICAgY3JlYXRlTGluazogZnVuY3Rpb24oaHJlZiwgYXR0cmlidXRlcykge1xuICAgICAgICB2YXIgaGVhZCA9IGRvY3VtZW50LmhlYWQgfHwgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXTtcbiAgICAgICAgdmFyIGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaW5rJyk7XG5cbiAgICAgICAgbGluay5ocmVmID0gaHJlZjtcbiAgICAgICAgbGluay5yZWwgPSAnc3R5bGVzaGVldCc7XG5cbiAgICAgICAgZm9yICh2YXIga2V5IGluIGF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgIGlmICggISBhdHRyaWJ1dGVzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IGF0dHJpYnV0ZXNba2V5XTtcbiAgICAgICAgICAgIGxpbmsuc2V0QXR0cmlidXRlKCdkYXRhLScgKyBrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhlYWQuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgfSxcbiAgICAvLyBDcmVhdGUgYSA8c3R5bGU+IHRhZyB3aXRoIG9wdGlvbmFsIGRhdGEgYXR0cmlidXRlc1xuICAgIGNyZWF0ZVN0eWxlOiBmdW5jdGlvbihjc3NUZXh0LCBhdHRyaWJ1dGVzLCBleHRyYU9wdGlvbnMpIHtcbiAgICAgICAgZXh0cmFPcHRpb25zID0gZXh0cmFPcHRpb25zIHx8IHt9O1xuXG4gICAgICAgIHZhciBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gICAgICAgIHN0eWxlLnR5cGUgPSAndGV4dC9jc3MnO1xuXG4gICAgICAgIGZvciAodmFyIGtleSBpbiBhdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgICBpZiAoICEgYXR0cmlidXRlcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBhdHRyaWJ1dGVzW2tleV07XG4gICAgICAgICAgICBzdHlsZS5zZXRBdHRyaWJ1dGUoJ2RhdGEtJyArIGtleSwgdmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN0eWxlLnNoZWV0KSB7IC8vIGZvciBqc2RvbSBhbmQgSUU5K1xuICAgICAgICAgICAgc3R5bGUuaW5uZXJIVE1MID0gY3NzVGV4dDtcbiAgICAgICAgICAgIHN0eWxlLnNoZWV0LmNzc1RleHQgPSBjc3NUZXh0O1xuICAgICAgICAgICAgaW5zZXJ0U3R5bGVFbGVtZW50KHN0eWxlLCB7IGluc2VydEF0OiBleHRyYU9wdGlvbnMuaW5zZXJ0QXQgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoc3R5bGUuc3R5bGVTaGVldCkgeyAvLyBmb3IgSUU4IGFuZCBiZWxvd1xuICAgICAgICAgICAgaW5zZXJ0U3R5bGVFbGVtZW50KHN0eWxlLCB7IGluc2VydEF0OiBleHRyYU9wdGlvbnMuaW5zZXJ0QXQgfSk7XG4gICAgICAgICAgICBzdHlsZS5zdHlsZVNoZWV0LmNzc1RleHQgPSBjc3NUZXh0O1xuICAgICAgICB9IGVsc2UgeyAvLyBmb3IgQ2hyb21lLCBGaXJlZm94LCBhbmQgU2FmYXJpXG4gICAgICAgICAgICBzdHlsZS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShjc3NUZXh0KSk7XG4gICAgICAgICAgICBpbnNlcnRTdHlsZUVsZW1lbnQoc3R5bGUsIHsgaW5zZXJ0QXQ6IGV4dHJhT3B0aW9ucy5pbnNlcnRBdCB9KTtcbiAgICAgICAgfVxuICAgIH1cbn07XG4iLCJ2YXIgY3NzID0gXCIuakJveC13cmFwcGVyIHtcXG4gIHRleHQtYWxpZ246IGxlZnQ7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbn1cXG4uakJveC10aXRsZSxcXG4uakJveC1jb250ZW50LFxcbi5qQm94LWNvbnRhaW5lciB7XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICB3b3JkLWJyZWFrOiBicmVhay13b3JkO1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG59XFxuLmpCb3gtY29udGFpbmVyIHtcXG4gIGJhY2tncm91bmQ6ICNmZmY7XFxufVxcbi5qQm94LWNvbnRlbnQge1xcbiAgcGFkZGluZzogOHB4IDEycHg7XFxuICBvdmVyZmxvdy14OiBoaWRkZW47XFxuICBvdmVyZmxvdy15OiBhdXRvO1xcbiAgdHJhbnNpdGlvbjogb3BhY2l0eSAuMnM7XFxufVxcbi5qQm94LWZvb3RlciB7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbn1cXG4uakJveC1Ub29sdGlwIC5qQm94LWNvbnRhaW5lcixcXG4uakJveC1Nb3VzZSAuakJveC1jb250YWluZXIge1xcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xcbiAgYm94LXNoYWRvdzogMCAwIDNweCByZ2JhKDAsIDAsIDAsIDAuMjUpO1xcbn1cXG4uakJveC1Ub29sdGlwIC5qQm94LXRpdGxlLFxcbi5qQm94LU1vdXNlIC5qQm94LXRpdGxlIHtcXG4gIHBhZGRpbmc6IDhweCAxMHB4IDA7XFxuICBmb250LXdlaWdodDogYm9sZDtcXG59XFxuLmpCb3gtVG9vbHRpcC5qQm94LWhhc1RpdGxlIC5qQm94LWNvbnRlbnQsXFxuLmpCb3gtTW91c2UuakJveC1oYXNUaXRsZSAuakJveC1jb250ZW50IHtcXG4gIHBhZGRpbmctdG9wOiA1cHg7XFxufVxcbi5qQm94LU1vdXNlIHtcXG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xcbn1cXG4uakJveC1wb2ludGVyIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIG92ZXJmbG93OiBoaWRkZW47XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbn1cXG4uakJveC1wb2ludGVyOmFmdGVyIHtcXG4gIGNvbnRlbnQ6ICcnO1xcbiAgd2lkdGg6IDIwcHg7XFxuICBoZWlnaHQ6IDIwcHg7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICBiYWNrZ3JvdW5kOiAjZmZmO1xcbiAgdHJhbnNmb3JtOiByb3RhdGUoNDVkZWcpO1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG59XFxuLmpCb3gtcG9pbnRlci10b3Age1xcbiAgdG9wOiAwO1xcbn1cXG4uakJveC1wb2ludGVyLXRvcDphZnRlciB7XFxuICBsZWZ0OiA1cHg7XFxuICB0b3A6IDZweDtcXG4gIGJveC1zaGFkb3c6IC0xcHggLTFweCAycHggcmdiYSgwLCAwLCAwLCAwLjE1KTtcXG59XFxuLmpCb3gtcG9pbnRlci1yaWdodCB7XFxuICByaWdodDogMDtcXG59XFxuLmpCb3gtcG9pbnRlci1yaWdodDphZnRlciB7XFxuICB0b3A6IDVweDtcXG4gIHJpZ2h0OiA2cHg7XFxuICBib3gtc2hhZG93OiAxcHggLTFweCAycHggcmdiYSgwLCAwLCAwLCAwLjE1KTtcXG59XFxuLmpCb3gtcG9pbnRlci1sZWZ0IHtcXG4gIGxlZnQ6IDA7XFxufVxcbi5qQm94LXBvaW50ZXItbGVmdDphZnRlciB7XFxuICB0b3A6IDVweDtcXG4gIGxlZnQ6IDZweDtcXG4gIGJveC1zaGFkb3c6IC0xcHggMXB4IDJweCByZ2JhKDAsIDAsIDAsIDAuMTUpO1xcbn1cXG4uakJveC1wb2ludGVyLWJvdHRvbSB7XFxuICBib3R0b206IDA7XFxufVxcbi5qQm94LXBvaW50ZXItYm90dG9tOmFmdGVyIHtcXG4gIGxlZnQ6IDVweDtcXG4gIGJvdHRvbTogNnB4O1xcbiAgYm94LXNoYWRvdzogMXB4IDFweCAycHggcmdiYSgwLCAwLCAwLCAwLjE1KTtcXG59XFxuLmpCb3gtcG9pbnRlci10b3AsXFxuLmpCb3gtcG9pbnRlci1ib3R0b20ge1xcbiAgd2lkdGg6IDMwcHg7XFxuICBoZWlnaHQ6IDEycHg7XFxufVxcbi5qQm94LXBvaW50ZXItbGVmdCxcXG4uakJveC1wb2ludGVyLXJpZ2h0IHtcXG4gIHdpZHRoOiAxMnB4O1xcbiAgaGVpZ2h0OiAzMHB4O1xcbn1cXG4uakJveC1Nb2RhbCAuakJveC1jb250YWluZXIge1xcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xcbn1cXG4uakJveC1Nb2RhbCAuakJveC1jb250YWluZXIsXFxuLmpCb3gtTW9kYWwuakJveC1jbG9zZUJ1dHRvbi1ib3g6YmVmb3JlIHtcXG4gIGJveC1zaGFkb3c6IDAgM3B4IDE1cHggcmdiYSgwLCAwLCAwLCAwLjQpLCAwIDAgNXB4IHJnYmEoMCwgMCwgMCwgMC40KTtcXG59XFxuLmpCb3gtTW9kYWwgLmpCb3gtY29udGVudCB7XFxuICBwYWRkaW5nOiAxNXB4IDIwcHg7XFxufVxcbi5qQm94LU1vZGFsIC5qQm94LXRpdGxlIHtcXG4gIGJvcmRlci1yYWRpdXM6IDRweCA0cHggMCAwO1xcbiAgcGFkZGluZzogMTVweCAyMHB4O1xcbiAgYmFja2dyb3VuZDogI2ZhZmFmYTtcXG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZWVlO1xcbn1cXG4uakJveC1Nb2RhbC5qQm94LWNsb3NlQnV0dG9uLXRpdGxlIC5qQm94LXRpdGxlIHtcXG4gIHBhZGRpbmctcmlnaHQ6IDY1cHg7XFxufVxcbi5qQm94LU1vZGFsIC5qQm94LWZvb3RlciB7XFxuICBib3JkZXItcmFkaXVzOiAwIDAgNHB4IDRweDtcXG59XFxuLmpCb3gtY2xvc2VCdXR0b24ge1xcbiAgei1pbmRleDogMTtcXG4gIGN1cnNvcjogcG9pbnRlcjtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxufVxcbi5qQm94LWNsb3NlQnV0dG9uIHN2ZyB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB0b3A6IDUwJTtcXG4gIHJpZ2h0OiA1MCU7XFxufVxcbi5qQm94LWNsb3NlQnV0dG9uIHBhdGgge1xcbiAgZmlsbDogI2FhYTtcXG4gIHRyYW5zaXRpb246IGZpbGwgLjJzO1xcbn1cXG4uakJveC1jbG9zZUJ1dHRvbjpob3ZlciBwYXRoIHtcXG4gIGZpbGw6ICM4ODg7XFxufVxcbi5qQm94LW92ZXJsYXkgLmpCb3gtY2xvc2VCdXR0b24ge1xcbiAgdG9wOiAwO1xcbiAgcmlnaHQ6IDA7XFxuICB3aWR0aDogNDBweDtcXG4gIGhlaWdodDogNDBweDtcXG59XFxuLmpCb3gtb3ZlcmxheSAuakJveC1jbG9zZUJ1dHRvbiBzdmcge1xcbiAgd2lkdGg6IDIwcHg7XFxuICBoZWlnaHQ6IDIwcHg7XFxuICBtYXJnaW4tdG9wOiAtMTBweDtcXG4gIG1hcmdpbi1yaWdodDogLTEwcHg7XFxufVxcbi5qQm94LW92ZXJsYXkgLmpCb3gtY2xvc2VCdXR0b24gcGF0aCB7XFxuICBmaWxsOiAjZGRkO1xcbn1cXG4uakJveC1vdmVybGF5IC5qQm94LWNsb3NlQnV0dG9uOmhvdmVyIHBhdGgge1xcbiAgZmlsbDogI2ZmZjtcXG59XFxuLmpCb3gtY2xvc2VCdXR0b24tdGl0bGUgLmpCb3gtY2xvc2VCdXR0b24ge1xcbiAgdG9wOiAwO1xcbiAgcmlnaHQ6IDA7XFxuICBib3R0b206IDA7XFxuICB3aWR0aDogNTBweDtcXG59XFxuLmpCb3gtY2xvc2VCdXR0b24tdGl0bGUgc3ZnIHtcXG4gIHdpZHRoOiAxMnB4O1xcbiAgaGVpZ2h0OiAxMnB4O1xcbiAgbWFyZ2luLXRvcDogLTZweDtcXG4gIG1hcmdpbi1yaWdodDogLTZweDtcXG59XFxuLmpCb3gtY2xvc2VCdXR0b24tYm94IHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxufVxcbi5qQm94LWNsb3NlQnV0dG9uLWJveCAuakJveC1jbG9zZUJ1dHRvbiB7XFxuICB0b3A6IC04cHg7XFxuICByaWdodDogLTEwcHg7XFxuICB3aWR0aDogMjRweDtcXG4gIGhlaWdodDogMjRweDtcXG4gIGJhY2tncm91bmQ6ICNmZmY7XFxuICBib3JkZXItcmFkaXVzOiA1MCU7XFxufVxcbi5qQm94LWNsb3NlQnV0dG9uLWJveCAuakJveC1jbG9zZUJ1dHRvbiBzdmcge1xcbiAgd2lkdGg6IDEwcHg7XFxuICBoZWlnaHQ6IDEwcHg7XFxuICBtYXJnaW4tdG9wOiAtNXB4O1xcbiAgbWFyZ2luLXJpZ2h0OiAtNXB4O1xcbn1cXG4uakJveC1jbG9zZUJ1dHRvbi1ib3g6YmVmb3JlIHtcXG4gIGNvbnRlbnQ6ICcnO1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgdG9wOiAtOHB4O1xcbiAgcmlnaHQ6IC0xMHB4O1xcbiAgd2lkdGg6IDI0cHg7XFxuICBoZWlnaHQ6IDI0cHg7XFxuICBib3JkZXItcmFkaXVzOiA1MCU7XFxuICBib3gtc2hhZG93OiAwIDAgNXB4IHJnYmEoMCwgMCwgMCwgMC4zKTtcXG59XFxuLmpCb3gtY2xvc2VCdXR0b24tYm94LmpCb3gtcG9pbnRlclBvc2l0aW9uLXRvcDpiZWZvcmUge1xcbiAgdG9wOiA1cHg7XFxufVxcbi5qQm94LWNsb3NlQnV0dG9uLWJveC5qQm94LXBvaW50ZXJQb3NpdGlvbi1yaWdodDpiZWZvcmUge1xcbiAgcmlnaHQ6IDJweDtcXG59XFxuLmpCb3gtTW9kYWwuakJveC1oYXNUaXRsZS5qQm94LWNsb3NlQnV0dG9uLWJveCAuakJveC1jbG9zZUJ1dHRvbiB7XFxuICBiYWNrZ3JvdW5kOiAjZmFmYWZhO1xcbn1cXG4uakJveC1vdmVybGF5IHtcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXG4gIHRvcDogMDtcXG4gIGxlZnQ6IDA7XFxuICB3aWR0aDogMTAwJTtcXG4gIGhlaWdodDogMTAwJTtcXG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC44Mik7XFxufVxcbi5qQm94LWZvb3RlciB7XFxuICBiYWNrZ3JvdW5kOiAjZmFmYWZhO1xcbiAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICNlZWU7XFxuICBwYWRkaW5nOiA4cHggMTBweDtcXG4gIGJvcmRlci1yYWRpdXM6IDAgMCAzcHggM3B4O1xcbn1cXG5ib2R5W2NsYXNzXj1cXFwiakJveC1ibG9ja1Njcm9sbC1cXFwiXSxcXG5ib2R5W2NsYXNzKj1cXFwiIGpCb3gtYmxvY2tTY3JvbGwtXFxcIl0ge1xcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcXG59XFxuLmpCb3gtZHJhZ2dhYmxlIHtcXG4gIGN1cnNvcjogbW92ZTtcXG59XFxuQGtleWZyYW1lcyBqQm94TG9hZGluZyB7XFxuICB0byB7XFxuICAgIHRyYW5zZm9ybTogcm90YXRlKDM2MGRlZyk7XFxuICB9XFxufVxcbi5qQm94LWxvYWRpbmcgLmpCb3gtY29udGVudCB7XFxuICBvcGFjaXR5OiAuMjtcXG59XFxuLmpCb3gtbG9hZGluZy1zcGlubmVyIC5qQm94LWNvbnRlbnQge1xcbiAgbWluLWhlaWdodDogMzhweCAhaW1wb3J0YW50O1xcbiAgbWluLXdpZHRoOiAzOHB4ICFpbXBvcnRhbnQ7XFxuICBvcGFjaXR5OiAwO1xcbn1cXG4uakJveC1zcGlubmVyIHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB0b3A6IDUwJTtcXG4gIGxlZnQ6IDUwJTtcXG4gIHdpZHRoOiAyNHB4O1xcbiAgaGVpZ2h0OiAyNHB4O1xcbiAgbWFyZ2luLXRvcDogLTEycHg7XFxuICBtYXJnaW4tbGVmdDogLTEycHg7XFxufVxcbi5qQm94LXNwaW5uZXI6YmVmb3JlIHtcXG4gIGRpc3BsYXk6IGJsb2NrO1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gIGNvbnRlbnQ6ICcnO1xcbiAgd2lkdGg6IDI0cHg7XFxuICBoZWlnaHQ6IDI0cHg7XFxuICBib3JkZXItcmFkaXVzOiA1MCU7XFxuICBib3JkZXI6IDJweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMik7XFxuICBib3JkZXItdG9wLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuOCk7XFxuICBhbmltYXRpb246IGpCb3hMb2FkaW5nIC42cyBsaW5lYXIgaW5maW5pdGU7XFxufVxcbi5qQm94LWNvdW50ZG93biB7XFxuICBib3JkZXItcmFkaXVzOiA0cHggNHB4IDAgMDtcXG4gIHotaW5kZXg6IDA7XFxuICBiYWNrZ3JvdW5kOiAjMDAwO1xcbiAgb3BhY2l0eTogLjI7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB0b3A6IDA7XFxuICBsZWZ0OiAwO1xcbiAgcmlnaHQ6IDA7XFxuICBoZWlnaHQ6IDNweDtcXG4gIG92ZXJmbG93OiBoaWRkZW47XFxufVxcbi5qQm94LWNvdW50ZG93bi1pbm5lciB7XFxuICB0b3A6IDA7XFxuICByaWdodDogMDtcXG4gIHdpZHRoOiAxMDAlO1xcbiAgaGVpZ2h0OiAzcHg7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICBiYWNrZ3JvdW5kOiAjZmZmO1xcbn1cXG5bY2xhc3NePVxcXCJqQm94LWFuaW1hdGVkLVxcXCJdLFxcbltjbGFzcyo9XFxcIiBqQm94LWFuaW1hdGVkLVxcXCJdIHtcXG4gIGFuaW1hdGlvbi1maWxsLW1vZGU6IGJvdGg7XFxufVxcbkBrZXlmcmFtZXMgakJveC10YWRhIHtcXG4gIDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxKTtcXG4gIH1cXG5cXG4gIDEwJSwgMjAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwLjgpIHJvdGF0ZSgtNGRlZyk7XFxuICB9XFxuXFxuICAzMCUsIDUwJSwgNzAlLCA5MCUge1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDEuMikgcm90YXRlKDRkZWcpO1xcbiAgfVxcblxcbiAgNDAlLCA2MCUsIDgwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4yKSByb3RhdGUoLTRkZWcpO1xcbiAgfVxcblxcbiAgMTAwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMSkgcm90YXRlKDApO1xcbiAgfVxcbn1cXG4uakJveC1hbmltYXRlZC10YWRhIHtcXG4gIGFuaW1hdGlvbjogakJveC10YWRhIDFzO1xcbn1cXG5Aa2V5ZnJhbWVzIGpCb3gtdGFkYVNtYWxsIHtcXG4gIDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxKTtcXG4gIH1cXG5cXG4gIDEwJSwgMjAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwLjkpIHJvdGF0ZSgtMmRlZyk7XFxuICB9XFxuXFxuICAzMCUsIDUwJSwgNzAlLCA5MCUge1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDEuMSkgcm90YXRlKDJkZWcpO1xcbiAgfVxcblxcbiAgNDAlLCA2MCUsIDgwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4xKSByb3RhdGUoLTJkZWcpO1xcbiAgfVxcblxcbiAgMTAwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMSkgcm90YXRlKDApO1xcbiAgfVxcbn1cXG4uakJveC1hbmltYXRlZC10YWRhU21hbGwge1xcbiAgYW5pbWF0aW9uOiBqQm94LXRhZGFTbWFsbCAxcztcXG59XFxuQGtleWZyYW1lcyBqQm94LWZsYXNoIHtcXG4gIDAlLCA1MCUsIDEwMCUge1xcbiAgICBvcGFjaXR5OiAxO1xcbiAgfVxcblxcbiAgMjUlLCA3NSUge1xcbiAgICBvcGFjaXR5OiAwO1xcbiAgfVxcbn1cXG4uakJveC1hbmltYXRlZC1mbGFzaCB7XFxuICBhbmltYXRpb246IGpCb3gtZmxhc2ggLjVzO1xcbn1cXG5Aa2V5ZnJhbWVzIGpCb3gtc2hha2Uge1xcbiAgMCUsIDEwMCUge1xcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMCk7XFxuICB9XFxuXFxuICAyMCUsIDYwJSB7XFxuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNnB4KTtcXG4gIH1cXG5cXG4gIDQwJSwgODAlIHtcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDZweCk7XFxuICB9XFxufVxcbi5qQm94LWFuaW1hdGVkLXNoYWtlIHtcXG4gIGFuaW1hdGlvbjogakJveC1zaGFrZSAuNHM7XFxufVxcbkBrZXlmcmFtZXMgakJveC1wdWxzZVVwIHtcXG4gIDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxKTtcXG4gIH1cXG5cXG4gIDUwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4xNSk7XFxuICB9XFxuXFxuICAxMDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxKTtcXG4gIH1cXG59XFxuLmpCb3gtYW5pbWF0ZWQtcHVsc2VVcCB7XFxuICBhbmltYXRpb246IGpCb3gtcHVsc2VVcCAuMjVzO1xcbn1cXG5Aa2V5ZnJhbWVzIGpCb3gtcHVsc2VEb3duIHtcXG4gIDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxKTtcXG4gIH1cXG5cXG4gIDUwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMC44NSk7XFxuICB9XFxuXFxuICAxMDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxKTtcXG4gIH1cXG59XFxuLmpCb3gtYW5pbWF0ZWQtcHVsc2VEb3duIHtcXG4gIGFuaW1hdGlvbjogakJveC1wdWxzZURvd24gLjI1cztcXG59XFxuQGtleWZyYW1lcyBqQm94LXBvcEluIHtcXG4gIDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwKTtcXG4gIH1cXG5cXG4gIDUwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4xKTtcXG4gIH1cXG5cXG4gIDEwMCUge1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDEpO1xcbiAgfVxcbn1cXG4uakJveC1hbmltYXRlZC1wb3BJbiB7XFxuICBhbmltYXRpb246IGpCb3gtcG9wSW4gLjI1cztcXG59XFxuQGtleWZyYW1lcyBqQm94LXBvcE91dCB7XFxuICAwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMSk7XFxuICB9XFxuXFxuICA1MCUge1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDEuMSk7XFxuICB9XFxuXFxuICAxMDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwKTtcXG4gIH1cXG59XFxuLmpCb3gtYW5pbWF0ZWQtcG9wT3V0IHtcXG4gIGFuaW1hdGlvbjogakJveC1wb3BPdXQgLjI1cztcXG59XFxuQGtleWZyYW1lcyBqQm94LWZhZGVJbiB7XFxuICAwJSB7XFxuICAgIG9wYWNpdHk6IDA7XFxuICB9XFxuXFxuICAxMDAlIHtcXG4gICAgb3BhY2l0eTogMTtcXG4gIH1cXG59XFxuLmpCb3gtYW5pbWF0ZWQtZmFkZUluIHtcXG4gIGFuaW1hdGlvbjogakJveC1mYWRlSW4gLjJzO1xcbn1cXG5Aa2V5ZnJhbWVzIGpCb3gtZmFkZU91dCB7XFxuICAwJSB7XFxuICAgIG9wYWNpdHk6IDE7XFxuICB9XFxuXFxuICAxMDAlIHtcXG4gICAgb3BhY2l0eTogMDtcXG4gIH1cXG59XFxuLmpCb3gtYW5pbWF0ZWQtZmFkZU91dCB7XFxuICBhbmltYXRpb246IGpCb3gtZmFkZU91dCAuMnM7XFxufVxcbkBrZXlmcmFtZXMgakJveC1zbGlkZVVwIHtcXG4gIDAlIHtcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDApO1xcbiAgfVxcblxcbiAgMTAwJSB7XFxuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtMzAwcHgpO1xcbiAgICBvcGFjaXR5OiAwO1xcbiAgfVxcbn1cXG4uakJveC1hbmltYXRlZC1zbGlkZVVwIHtcXG4gIGFuaW1hdGlvbjogakJveC1zbGlkZVVwIC40cztcXG59XFxuQGtleWZyYW1lcyBqQm94LXNsaWRlUmlnaHQge1xcbiAgMCUge1xcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMCk7XFxuICB9XFxuXFxuICAxMDAlIHtcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDMwMHB4KTtcXG4gICAgb3BhY2l0eTogMDtcXG4gIH1cXG59XFxuLmpCb3gtYW5pbWF0ZWQtc2xpZGVSaWdodCB7XFxuICBhbmltYXRpb246IGpCb3gtc2xpZGVSaWdodCAuNHM7XFxufVxcbkBrZXlmcmFtZXMgakJveC1zbGlkZURvd24ge1xcbiAgMCUge1xcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMCk7XFxuICB9XFxuXFxuICAxMDAlIHtcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDMwMHB4KTtcXG4gICAgb3BhY2l0eTogMDtcXG4gIH1cXG59XFxuLmpCb3gtYW5pbWF0ZWQtc2xpZGVEb3duIHtcXG4gIGFuaW1hdGlvbjogakJveC1zbGlkZURvd24gLjRzO1xcbn1cXG5Aa2V5ZnJhbWVzIGpCb3gtc2xpZGVMZWZ0IHtcXG4gIDAlIHtcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDApO1xcbiAgfVxcblxcbiAgMTAwJSB7XFxuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtMzAwcHgpO1xcbiAgICBvcGFjaXR5OiAwO1xcbiAgfVxcbn1cXG4uakJveC1hbmltYXRlZC1zbGlkZUxlZnQge1xcbiAgYW5pbWF0aW9uOiBqQm94LXNsaWRlTGVmdCAuNHM7XFxufVxcbi5qQm94LUNvbmZpcm0gLmpCb3gtY29udGVudCB7XFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICBwYWRkaW5nOiA0NnB4IDM1cHg7XFxufVxcbkBtZWRpYSAobWF4LXdpZHRoOiA1MDBweCkge1xcbiAgLmpCb3gtQ29uZmlybSAuakJveC1jb250ZW50IHtcXG4gICAgcGFkZGluZzogMzJweCAyMHB4O1xcbiAgfVxcbn1cXG4uakJveC1Db25maXJtLWZvb3RlciB7XFxuICBoZWlnaHQ6IDQ2cHg7XFxufVxcbi5qQm94LUNvbmZpcm0tYnV0dG9uIHtcXG4gIGRpc3BsYXk6IGJsb2NrO1xcbiAgZmxvYXQ6IGxlZnQ7XFxuICBjdXJzb3I6IHBvaW50ZXI7XFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICB3aWR0aDogNTAlO1xcbiAgbGluZS1oZWlnaHQ6IDQ2cHg7XFxuICBoZWlnaHQ6IDQ2cHg7XFxuICBvdmVyZmxvdzogaGlkZGVuO1xcbiAgcGFkZGluZzogMCAxMHB4O1xcbiAgdHJhbnNpdGlvbjogY29sb3IgLjJzLCBiYWNrZ3JvdW5kLWNvbG9yIC4ycztcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxufVxcbi5qQm94LUNvbmZpcm0tYnV0dG9uLWNhbmNlbCB7XFxuICBib3JkZXItYm90dG9tLWxlZnQtcmFkaXVzOiA0cHg7XFxuICBiYWNrZ3JvdW5kOiAjZGRkO1xcbiAgY29sb3I6ICM2NjY7XFxufVxcbi5qQm94LUNvbmZpcm0tYnV0dG9uLWNhbmNlbDpob3ZlcixcXG4uakJveC1Db25maXJtLWJ1dHRvbi1jYW5jZWw6YWN0aXZlIHtcXG4gIGJhY2tncm91bmQ6ICNjY2M7XFxufVxcbi5qQm94LUNvbmZpcm0tYnV0dG9uLWNhbmNlbDphY3RpdmUge1xcbiAgYm94LXNoYWRvdzogaW5zZXQgMCAxcHggM3B4IHJnYmEoMCwgMCwgMCwgMC4yKTtcXG59XFxuLmpCb3gtQ29uZmlybS1idXR0b24tc3VibWl0IHtcXG4gIGJvcmRlci1ib3R0b20tcmlnaHQtcmFkaXVzOiA0cHg7XFxuICBiYWNrZ3JvdW5kOiAjN2QwO1xcbiAgY29sb3I6ICNmZmY7XFxufVxcbi5qQm94LUNvbmZpcm0tYnV0dG9uLXN1Ym1pdDpob3ZlcixcXG4uakJveC1Db25maXJtLWJ1dHRvbi1zdWJtaXQ6YWN0aXZlIHtcXG4gIGJhY2tncm91bmQ6ICM2YzA7XFxufVxcbi5qQm94LUNvbmZpcm0tYnV0dG9uLXN1Ym1pdDphY3RpdmUge1xcbiAgYm94LXNoYWRvdzogaW5zZXQgMCAxcHggM3B4IHJnYmEoMCwgMCwgMCwgMC4yKTtcXG59XFxuLmpCb3gtSW1hZ2UgLmpCb3gtY29udGFpbmVyIHtcXG4gIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xcbn1cXG4uakJveC1JbWFnZSAuakJveC1jb250ZW50IHtcXG4gIHBhZGRpbmc6IDA7XFxuICB3aWR0aDogMTAwJTtcXG4gIGhlaWdodDogMTAwJTtcXG59XFxuLmpCb3gtaW1hZ2UtY29udGFpbmVyIHtcXG4gIGJhY2tncm91bmQ6IGNlbnRlciBjZW50ZXIgbm8tcmVwZWF0O1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgd2lkdGg6IDEwMCU7XFxuICBoZWlnaHQ6IDEwMCU7XFxuICBvcGFjaXR5OiAwO1xcbn1cXG4uakJveC1pbWFnZS1sYWJlbC13cmFwcGVyIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHRvcDogMTAwJTtcXG4gIGxlZnQ6IDA7XFxuICByaWdodDogMDtcXG4gIGhlaWdodDogNDBweDtcXG4gIHotaW5kZXg6IDEwMDtcXG4gIGRpc3BsYXk6IGZsZXg7XFxufVxcbi5qQm94LWltYWdlLWxhYmVsLWNvbnRhaW5lciB7XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICBmbGV4OiAxO1xcbn1cXG4uakJveC1pbWFnZS1sYWJlbCB7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgbGVmdDogMDtcXG4gIGJvdHRvbTogMDtcXG4gIHdpZHRoOiAxMDAlO1xcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcbiAgY29sb3I6ICNmZmY7XFxuICBwYWRkaW5nOiA4cHggMTJweDtcXG4gIGZvbnQtc2l6ZTogMTVweDtcXG4gIGxpbmUtaGVpZ2h0OiAyNHB4O1xcbiAgdHJhbnNpdGlvbjogb3BhY2l0eSAuMzZzO1xcbiAgb3BhY2l0eTogMDtcXG4gIHotaW5kZXg6IDA7XFxuICBwb2ludGVyLWV2ZW50czogbm9uZTtcXG59XFxuLmpCb3gtaW1hZ2UtbGFiZWwuZXhwYW5kZWQge1xcbiAgYmFja2dyb3VuZDogIzAwMDtcXG59XFxuLmpCb3gtaW1hZ2UtbGFiZWw6bm90KC5leHBhbmRlZCkge1xcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XFxuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcXG59XFxuLmpCb3gtaW1hZ2UtbGFiZWwuYWN0aXZlIHtcXG4gIG9wYWNpdHk6IDE7XFxuICBwb2ludGVyLWV2ZW50czogYWxsO1xcbn1cXG5AbWVkaWEgKG1heC13aWR0aDogNjAwcHgpIHtcXG4gIC5qQm94LWltYWdlLWxhYmVsIHtcXG4gICAgZm9udC1zaXplOiAxM3B4O1xcbiAgfVxcbn1cXG4uakJveC1pbWFnZS1wb2ludGVyLW5leHQsXFxuLmpCb3gtaW1hZ2UtcG9pbnRlci1wcmV2IHtcXG4gIGZsZXgtc2hyaW5rOiAwO1xcbiAgd2lkdGg6IDQwcHg7XFxuICBoZWlnaHQ6IDQwcHg7XFxuICBjdXJzb3I6IHBvaW50ZXI7XFxuICBvcGFjaXR5OiAuODtcXG4gIHRyYW5zaXRpb246IG9wYWNpdHkgLjJzO1xcbiAgYmFja2dyb3VuZDogbm8tcmVwZWF0IGNlbnRlciBjZW50ZXIgdXJsKGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaUlIWnBaWGRDYjNnOUlqYzBMamNnTWpJMElERTRMamNnTXpJaVBnMEtQSEJoZEdnZ1ptbHNiRDBpSTJabVptWm1aaUlnWkQwaVRUa3pMREl5Tnk0MFREZ3dMalFzTWpRd1REa3pMREkxTWk0Mll6QXVOQ3d3TGpRc01DNDBMREV1TVN3d0xERXVOV3d0TVM0MkxERXVObU10TUM0MExEQXVOQzB4TERBdU5TMHhMalVzTUV3M05Td3lOREF1TjJNdE1DNDBMVEF1TkMwd0xqVXRNU3d3TFRFdU5Xd3hOQzQ1TFRFMExqbGpNQzQwTFRBdU5Dd3hMVEF1TkN3eExqVXNNR3d4TGpZc01TNDJRemt6TGpVc01qSTJMalFzT1RNdU5Dd3lNamNzT1RNc01qSTNMalI2SWk4K0RRbzhMM04yWno0PSk7XFxuICBiYWNrZ3JvdW5kLXNpemU6IDExcHggYXV0bztcXG4gIHVzZXItc2VsZWN0OiBub25lO1xcbiAgei1pbmRleDogMTtcXG59XFxuLmpCb3gtaW1hZ2UtcG9pbnRlci1uZXh0OmhvdmVyLFxcbi5qQm94LWltYWdlLXBvaW50ZXItcHJldjpob3ZlciB7XFxuICBvcGFjaXR5OiAxO1xcbn1cXG4uakJveC1pbWFnZS1wb2ludGVyLW5leHQge1xcbiAgdHJhbnNmb3JtOiBzY2FsZVgoLTEpO1xcbn1cXG4uakJveC1pbWFnZS1jb3VudGVyLWNvbnRhaW5lciB7XFxuICBmbGV4LXNocmluazogMDtcXG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XFxuICBoZWlnaHQ6IDQwcHg7XFxuICBsaW5lLWhlaWdodDogNDBweDtcXG4gIGZvbnQtc2l6ZTogMTNweDtcXG4gIGNvbG9yOiAjZmZmO1xcbiAgdGV4dC1hbGlnbjogcmlnaHQ7XFxuICBkaXNwbGF5OiBub25lO1xcbn1cXG4uakJveC1pbWFnZS1oYXMtY291bnRlciAuakJveC1pbWFnZS1jb3VudGVyLWNvbnRhaW5lciB7XFxuICBkaXNwbGF5OiBibG9jaztcXG59XFxuLmpCb3gtb3ZlcmxheS5qQm94LW92ZXJsYXktSW1hZ2Uge1xcbiAgYmFja2dyb3VuZDogIzAwMDtcXG59XFxuLmpCb3gtaW1hZ2Utbm90LWZvdW5kIHtcXG4gIGJhY2tncm91bmQ6ICMwMDA7XFxufVxcbi5qQm94LWltYWdlLW5vdC1mb3VuZDpiZWZvcmUge1xcbiAgY29udGVudDogJyc7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICB3aWR0aDogODBweDtcXG4gIGhlaWdodDogODBweDtcXG4gIG1hcmdpbi10b3A6IC00MHB4O1xcbiAgbWFyZ2luLWxlZnQ6IC00MHB4O1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgdG9wOiA1MCU7XFxuICBsZWZ0OiA1MCU7XFxuICBib3JkZXI6IDVweCBzb2xpZCAjMjIyO1xcbiAgYm9yZGVyLXJhZGl1czogNTAlO1xcbn1cXG4uakJveC1pbWFnZS1ub3QtZm91bmQ6YWZ0ZXIge1xcbiAgY29udGVudDogJyc7XFxuICBkaXNwbGF5OiBibG9jaztcXG4gIGJveC1zaXppbmc6IGNvbnRlbnQtYm94O1xcbiAgei1pbmRleDogYXV0bztcXG4gIHdpZHRoOiA2cHg7XFxuICBoZWlnaHQ6IDc0cHg7XFxuICBtYXJnaW4tdG9wOiAtMzdweDtcXG4gIG1hcmdpbi1sZWZ0OiAtM3B4O1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgdG9wOiA1MCU7XFxuICBsZWZ0OiA1MCU7XFxuICBiYWNrZ3JvdW5kOiAjMjIyO1xcbiAgdHJhbnNmb3JtOiByb3RhdGVaKDQ1ZGVnKTtcXG4gIHRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCUgMDtcXG59XFxuLmpCb3gtaW1hZ2UtZG93bmxvYWQtYnV0dG9uLXdyYXBwZXIge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgdG9wOiAtNDBweDtcXG4gIHJpZ2h0OiAzNXB4O1xcbiAgaGVpZ2h0OiA0MHB4O1xcbiAgZGlzcGxheTogZmxleDtcXG4gIGN1cnNvcjogcG9pbnRlcjtcXG4gIG9wYWNpdHk6IC44O1xcbiAgdHJhbnNpdGlvbjogb3BhY2l0eSAuMnM7XFxufVxcbi5qQm94LWltYWdlLWRvd25sb2FkLWJ1dHRvbi13cmFwcGVyOmhvdmVyIHtcXG4gIG9wYWNpdHk6IDE7XFxufVxcbi5qQm94LWltYWdlLWRvd25sb2FkLWJ1dHRvbi1pY29uIHtcXG4gIHdpZHRoOiA0MHB4O1xcbiAgaGVpZ2h0OiA0MHB4O1xcbiAgYmFja2dyb3VuZDogY2VudGVyIGNlbnRlciBuby1yZXBlYXQgdXJsKGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaUlIWnBaWGRDYjNnOUlqQWdNQ0EyTkRBZ05qUXdJajQ4Y0dGMGFDQm1hV3hzUFNJalJrWkdSa1pHSWlCa1BTSk5OREUySURJMU5uWXRNVGt5YUMweE9USjJNVGt5YUMweE5qQnNNalUySURJMU5pQXlOVFl0TWpVMmFDMHhOakI2VFRBZ05UYzJhRFkwTUhZMk5HZ3ROalF3ZGkwMk5Ib2lQand2Y0dGMGFENDhMM04yWno0PSk7XFxuICBiYWNrZ3JvdW5kLXNpemU6IDYwJTtcXG59XFxuLmpCb3gtaW1hZ2UtZG93bmxvYWQtYnV0dG9uLXRleHQge1xcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcXG4gIGxpbmUtaGVpZ2h0OiA0MHB4O1xcbiAgcGFkZGluZzogMCAxMHB4IDAgMDtcXG4gIGNvbG9yOiAjZmZmO1xcbiAgZm9udC1zaXplOiAxNHB4O1xcbn1cXG5Aa2V5ZnJhbWVzIGpCb3hJbWFnZUxvYWRpbmcge1xcbiAgdG8ge1xcbiAgICB0cmFuc2Zvcm06IHJvdGF0ZSgzNjBkZWcpO1xcbiAgfVxcbn1cXG4uakJveC1pbWFnZS1sb2FkaW5nOmJlZm9yZSB7XFxuICBjb250ZW50OiAnJztcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHRvcDogNTAlO1xcbiAgbGVmdDogNTAlO1xcbiAgd2lkdGg6IDMycHg7XFxuICBoZWlnaHQ6IDMycHg7XFxuICBtYXJnaW4tdG9wOiAtMTZweDtcXG4gIG1hcmdpbi1sZWZ0OiAtMTZweDtcXG4gIGJvcmRlcjogNHB4IHNvbGlkICMzMzM7XFxuICBib3JkZXItYm90dG9tLWNvbG9yOiAjNjY2O1xcbiAgYW5pbWF0aW9uOiBqQm94SW1hZ2VMb2FkaW5nIDEuMnMgbGluZWFyIGluZmluaXRlO1xcbiAgYm9yZGVyLXJhZGl1czogNTAlO1xcbn1cXG4uakJveC1Ob3RpY2Uge1xcbiAgdHJhbnNpdGlvbjogbWFyZ2luIC4ycztcXG59XFxuLmpCb3gtTm90aWNlIC5qQm94LWNvbnRhaW5lciB7XFxuICBib3JkZXItcmFkaXVzOiA0cHg7XFxuICBib3gtc2hhZG93OiBpbnNldCAxcHggMXB4IDAgMCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMjUpLCBpbnNldCAtMXB4IC0xcHggMCAwIHJnYmEoMCwgMCwgMCwgMC4xKTtcXG59XFxuLmpCb3gtTm90aWNlIC5qQm94LWNvbnRlbnQge1xcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xcbiAgcGFkZGluZzogMTJweCAyMHB4O1xcbn1cXG5AbWVkaWEgKG1heC13aWR0aDogNzY4cHgpIHtcXG4gIC5qQm94LU5vdGljZSAuakJveC1jb250ZW50IHtcXG4gICAgcGFkZGluZzogMTBweCAxNXB4O1xcbiAgfVxcbn1cXG5AbWVkaWEgKG1heC13aWR0aDogNTAwcHgpIHtcXG4gIC5qQm94LU5vdGljZSAuakJveC1jb250ZW50IHtcXG4gICAgcGFkZGluZzogOHB4IDEwcHg7XFxuICB9XFxufVxcbi5qQm94LU5vdGljZS5qQm94LWhhc1RpdGxlIC5qQm94LWNvbnRlbnQge1xcbiAgcGFkZGluZy10b3A6IDVweDtcXG59XFxuQG1lZGlhIChtYXgtd2lkdGg6IDUwMHB4KSB7XFxuICAuakJveC1Ob3RpY2UuakJveC1oYXNUaXRsZSAuakJveC1jb250ZW50IHtcXG4gICAgcGFkZGluZy10b3A6IDA7XFxuICB9XFxufVxcbi5qQm94LU5vdGljZS5qQm94LWhhc1RpdGxlIC5qQm94LXRpdGxlIHtcXG4gIHBhZGRpbmc6IDEycHggMjBweCAwO1xcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XFxufVxcbkBtZWRpYSAobWF4LXdpZHRoOiA3NjhweCkge1xcbiAgLmpCb3gtTm90aWNlLmpCb3gtaGFzVGl0bGUgLmpCb3gtdGl0bGUge1xcbiAgICBwYWRkaW5nOiAxMHB4IDE1cHggMDtcXG4gIH1cXG59XFxuQG1lZGlhIChtYXgtd2lkdGg6IDUwMHB4KSB7XFxuICAuakJveC1Ob3RpY2UuakJveC1oYXNUaXRsZSAuakJveC10aXRsZSB7XFxuICAgIHBhZGRpbmc6IDhweCAxMHB4IDA7XFxuICB9XFxufVxcbi5qQm94LU5vdGljZS5qQm94LWNsb3NlQnV0dG9uLXRpdGxlIC5qQm94LXRpdGxlIHtcXG4gIHBhZGRpbmctcmlnaHQ6IDU1cHg7XFxufVxcbi5qQm94LU5vdGljZS5qQm94LWNsb3NlQnV0dG9uLXRpdGxlLmpCb3gtaGFzVGl0bGUgLmpCb3gtY2xvc2VCdXR0b24ge1xcbiAgd2lkdGg6IDQwcHg7XFxufVxcbi5qQm94LU5vdGljZS5qQm94LU5vdGljZS1ibGFjayAuakJveC1jb250YWluZXIge1xcbiAgY29sb3I6ICNmZmY7XFxuICBiYWNrZ3JvdW5kOiAjMDAwO1xcbn1cXG4uakJveC1Ob3RpY2UuakJveC1Ob3RpY2UtYmxhY2suakJveC1jbG9zZUJ1dHRvbi10aXRsZS5qQm94LWhhc1RpdGxlIC5qQm94LWNsb3NlQnV0dG9uIHBhdGgsXFxuLmpCb3gtTm90aWNlLmpCb3gtTm90aWNlLWJsYWNrLmpCb3gtY2xvc2VCdXR0b24tdGl0bGUuakJveC1oYXNUaXRsZSAuakJveC1jbG9zZUJ1dHRvbjpob3ZlciBwYXRoIHtcXG4gIGZpbGw6ICNmZmY7XFxufVxcbi5qQm94LU5vdGljZS5qQm94LU5vdGljZS1ncmF5IC5qQm94LWNvbnRhaW5lciB7XFxuICBjb2xvcjogIzIyMjtcXG4gIGJhY2tncm91bmQ6ICNmNmY2ZjY7XFxufVxcbi5qQm94LU5vdGljZS5qQm94LU5vdGljZS1ncmF5LmpCb3gtY2xvc2VCdXR0b24tdGl0bGUuakJveC1oYXNUaXRsZSAuakJveC1jbG9zZUJ1dHRvbiBwYXRoLFxcbi5qQm94LU5vdGljZS5qQm94LU5vdGljZS1ncmF5LmpCb3gtY2xvc2VCdXR0b24tdGl0bGUuakJveC1oYXNUaXRsZSAuakJveC1jbG9zZUJ1dHRvbjpob3ZlciBwYXRoIHtcXG4gIGZpbGw6ICMyMjI7XFxufVxcbi5qQm94LU5vdGljZS5qQm94LU5vdGljZS1yZWQgLmpCb3gtY29udGFpbmVyIHtcXG4gIGNvbG9yOiAjZmZmO1xcbiAgYmFja2dyb3VuZDogI2QwMDtcXG59XFxuLmpCb3gtTm90aWNlLmpCb3gtTm90aWNlLXJlZC5qQm94LWNsb3NlQnV0dG9uLXRpdGxlLmpCb3gtaGFzVGl0bGUgLmpCb3gtY2xvc2VCdXR0b24gcGF0aCxcXG4uakJveC1Ob3RpY2UuakJveC1Ob3RpY2UtcmVkLmpCb3gtY2xvc2VCdXR0b24tdGl0bGUuakJveC1oYXNUaXRsZSAuakJveC1jbG9zZUJ1dHRvbjpob3ZlciBwYXRoIHtcXG4gIGZpbGw6ICNmZmY7XFxufVxcbi5qQm94LU5vdGljZS5qQm94LU5vdGljZS1ncmVlbiAuakJveC1jb250YWluZXIge1xcbiAgY29sb3I6ICNmZmY7XFxuICBiYWNrZ3JvdW5kOiAjNWQwO1xcbn1cXG4uakJveC1Ob3RpY2UuakJveC1Ob3RpY2UtZ3JlZW4uakJveC1jbG9zZUJ1dHRvbi10aXRsZS5qQm94LWhhc1RpdGxlIC5qQm94LWNsb3NlQnV0dG9uIHBhdGgsXFxuLmpCb3gtTm90aWNlLmpCb3gtTm90aWNlLWdyZWVuLmpCb3gtY2xvc2VCdXR0b24tdGl0bGUuakJveC1oYXNUaXRsZSAuakJveC1jbG9zZUJ1dHRvbjpob3ZlciBwYXRoIHtcXG4gIGZpbGw6ICNmZmY7XFxufVxcbi5qQm94LU5vdGljZS5qQm94LU5vdGljZS1ibHVlIC5qQm94LWNvbnRhaW5lciB7XFxuICBjb2xvcjogI2ZmZjtcXG4gIGJhY2tncm91bmQ6ICM0OWQ7XFxufVxcbi5qQm94LU5vdGljZS5qQm94LU5vdGljZS1ibHVlLmpCb3gtY2xvc2VCdXR0b24tdGl0bGUuakJveC1oYXNUaXRsZSAuakJveC1jbG9zZUJ1dHRvbiBwYXRoLFxcbi5qQm94LU5vdGljZS5qQm94LU5vdGljZS1ibHVlLmpCb3gtY2xvc2VCdXR0b24tdGl0bGUuakJveC1oYXNUaXRsZSAuakJveC1jbG9zZUJ1dHRvbjpob3ZlciBwYXRoIHtcXG4gIGZpbGw6ICNmZmY7XFxufVxcbi5qQm94LU5vdGljZS5qQm94LU5vdGljZS15ZWxsb3cgLmpCb3gtY29udGFpbmVyIHtcXG4gIGNvbG9yOiAjMDAwO1xcbiAgYmFja2dyb3VuZDogI2ZkMDtcXG59XFxuLmpCb3gtTm90aWNlLmpCb3gtTm90aWNlLXllbGxvdy5qQm94LWNsb3NlQnV0dG9uLXRpdGxlLmpCb3gtaGFzVGl0bGUgLmpCb3gtY2xvc2VCdXR0b24gcGF0aCxcXG4uakJveC1Ob3RpY2UuakJveC1Ob3RpY2UteWVsbG93LmpCb3gtY2xvc2VCdXR0b24tdGl0bGUuakJveC1oYXNUaXRsZSAuakJveC1jbG9zZUJ1dHRvbjpob3ZlciBwYXRoIHtcXG4gIGZpbGw6ICNmZmY7XFxufVxcbi5qQm94LU5vdGljZUZhbmN5IC5qQm94LWNvbnRlbnQsXFxuLmpCb3gtTm90aWNlRmFuY3kgLmpCb3gtdGl0bGUge1xcbiAgcGFkZGluZy1sZWZ0OiAyNXB4O1xcbn1cXG4uakJveC1Ob3RpY2VGYW5jeS5qQm94LU5vdGljZS1jb2xvciAuakJveC1jb250YWluZXIge1xcbiAgY29sb3I6ICNmZmY7XFxuICBiYWNrZ3JvdW5kOiAjMDAwO1xcbn1cXG4uakJveC1Ob3RpY2VGYW5jeS5qQm94LU5vdGljZS1jb2xvciAuakJveC1jb250YWluZXI6YWZ0ZXIge1xcbiAgY29udGVudDogJyc7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB0b3A6IDA7XFxuICBsZWZ0OiAwO1xcbiAgYm90dG9tOiAwO1xcbiAgd2lkdGg6IDhweDtcXG4gIGJvcmRlci1yYWRpdXM6IDRweCAwIDAgNHB4O1xcbiAgYmFja2dyb3VuZC1pbWFnZTogbGluZWFyLWdyYWRpZW50KDQ1ZGVnLCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNCkgMjUlLCB0cmFuc3BhcmVudCAyNSUsIHRyYW5zcGFyZW50IDUwJSwgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjQpIDUwJSwgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjQpIDc1JSwgdHJhbnNwYXJlbnQgNzUlLCB0cmFuc3BhcmVudCk7XFxuICBiYWNrZ3JvdW5kLXNpemU6IDE0cHggMTRweDtcXG59XFxuLmpCb3gtTm90aWNlRmFuY3kuakJveC1Ob3RpY2UtYmxhY2sgLmpCb3gtY29udGFpbmVyOmFmdGVyLFxcbi5qQm94LU5vdGljZUZhbmN5LmpCb3gtTm90aWNlLWdyYXkgLmpCb3gtY29udGFpbmVyOmFmdGVyIHtcXG4gIGJhY2tncm91bmQtY29sb3I6ICM4ODg7XFxufVxcbi5qQm94LU5vdGljZUZhbmN5LmpCb3gtTm90aWNlLXJlZCAuakJveC1jb250YWluZXI6YWZ0ZXIge1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2UwMDtcXG59XFxuLmpCb3gtTm90aWNlRmFuY3kuakJveC1Ob3RpY2UtZ3JlZW4gLmpCb3gtY29udGFpbmVyOmFmdGVyIHtcXG4gIGJhY2tncm91bmQtY29sb3I6ICM2YzA7XFxufVxcbi5qQm94LU5vdGljZUZhbmN5LmpCb3gtTm90aWNlLWJsdWUgLmpCb3gtY29udGFpbmVyOmFmdGVyIHtcXG4gIGJhY2tncm91bmQtY29sb3I6ICM0OWQ7XFxufVxcbi5qQm94LU5vdGljZUZhbmN5LmpCb3gtTm90aWNlLXllbGxvdyAuakJveC1jb250YWluZXI6YWZ0ZXIge1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZiMDtcXG59XFxuLmpCb3gtTm90aWNlRmFuY3kgLmpCb3gtY291bnRkb3duIHtcXG4gIGxlZnQ6IDhweDtcXG4gIGJvcmRlci1yYWRpdXM6IDAgNHB4IDAgMDtcXG59XFxuLmpCb3gtVG9vbHRpcEJvcmRlciAuakJveC1jb250YWluZXIsXFxuLmpCb3gtVG9vbHRpcEJvcmRlciAuakJveC1wb2ludGVyOmFmdGVyIHtcXG4gIGJvcmRlcjogMnB4IHNvbGlkICM0OWQ7XFxufVxcbi5qQm94LVRvb2x0aXBCb3JkZXIgLmpCb3gtcG9pbnRlcjphZnRlciB7XFxuICB3aWR0aDogMjJweDtcXG4gIGhlaWdodDogMjJweDtcXG59XFxuLmpCb3gtVG9vbHRpcEJvcmRlciAuakJveC1wb2ludGVyLXRvcCxcXG4uakJveC1Ub29sdGlwQm9yZGVyIC5qQm94LXBvaW50ZXItYm90dG9tIHtcXG4gIHdpZHRoOiAzNHB4O1xcbiAgaGVpZ2h0OiAxM3B4O1xcbn1cXG4uakJveC1Ub29sdGlwQm9yZGVyIC5qQm94LXBvaW50ZXItdG9wOmFmdGVyLFxcbi5qQm94LVRvb2x0aXBCb3JkZXIgLmpCb3gtcG9pbnRlci1ib3R0b206YWZ0ZXIge1xcbiAgbGVmdDogNnB4O1xcbn1cXG4uakJveC1Ub29sdGlwQm9yZGVyIC5qQm94LXBvaW50ZXItbGVmdCxcXG4uakJveC1Ub29sdGlwQm9yZGVyIC5qQm94LXBvaW50ZXItcmlnaHQge1xcbiAgd2lkdGg6IDEzcHg7XFxuICBoZWlnaHQ6IDM0cHg7XFxufVxcbi5qQm94LVRvb2x0aXBCb3JkZXIgLmpCb3gtcG9pbnRlci1sZWZ0OmFmdGVyLFxcbi5qQm94LVRvb2x0aXBCb3JkZXIgLmpCb3gtcG9pbnRlci1yaWdodDphZnRlciB7XFxuICB0b3A6IDZweDtcXG59XFxuLmpCb3gtVG9vbHRpcEJvcmRlci5qQm94LWNsb3NlQnV0dG9uLWJveDpiZWZvcmUge1xcbiAgd2lkdGg6IDI4cHg7XFxuICBoZWlnaHQ6IDI4cHg7XFxuICBiYWNrZ3JvdW5kOiAjNDlkO1xcbn1cXG4uakJveC1Ub29sdGlwQm9yZGVyVGhpY2sgLmpCb3gtY29udGFpbmVyIHtcXG4gIGJveC1zaGFkb3c6IG5vbmU7XFxuICBib3JkZXItcmFkaXVzOiA4cHg7XFxuICBib3JkZXI6IDRweCBzb2xpZCAjY2NjO1xcbn1cXG4uakJveC1Ub29sdGlwQm9yZGVyVGhpY2sgLmpCb3gtcG9pbnRlcjphZnRlciB7XFxuICBib3gtc2hhZG93OiBub25lO1xcbiAgYm9yZGVyOiA0cHggc29saWQgI2NjYztcXG4gIHdpZHRoOiAyNHB4O1xcbiAgaGVpZ2h0OiAyNHB4O1xcbn1cXG4uakJveC1Ub29sdGlwQm9yZGVyVGhpY2sgLmpCb3gtcG9pbnRlci10b3AsXFxuLmpCb3gtVG9vbHRpcEJvcmRlclRoaWNrIC5qQm94LXBvaW50ZXItYm90dG9tIHtcXG4gIHdpZHRoOiAzOHB4O1xcbiAgaGVpZ2h0OiAxM3B4O1xcbn1cXG4uakJveC1Ub29sdGlwQm9yZGVyVGhpY2sgLmpCb3gtcG9pbnRlci1sZWZ0LFxcbi5qQm94LVRvb2x0aXBCb3JkZXJUaGljayAuakJveC1wb2ludGVyLXJpZ2h0IHtcXG4gIHdpZHRoOiAxM3B4O1xcbiAgaGVpZ2h0OiAzOHB4O1xcbn1cXG4uakJveC1Ub29sdGlwQm9yZGVyVGhpY2suakJveC1jbG9zZUJ1dHRvbi1ib3g6YmVmb3JlIHtcXG4gIHdpZHRoOiAzMnB4O1xcbiAgaGVpZ2h0OiAzMnB4O1xcbiAgYmFja2dyb3VuZDogI2NjYztcXG59XFxuLmpCb3gtVG9vbHRpcERhcmsgLmpCb3gtY29udGFpbmVyIHtcXG4gIGJvcmRlci1yYWRpdXM6IDRweDtcXG4gIGJhY2tncm91bmQ6ICMwMDA7XFxuICBjb2xvcjogI2ZmZjtcXG4gIGJveC1zaGFkb3c6IDAgMCA2cHggcmdiYSgwLCAwLCAwLCAwLjQpO1xcbn1cXG4uakJveC1Ub29sdGlwRGFyayAuakJveC1wb2ludGVyOmFmdGVyIHtcXG4gIGJhY2tncm91bmQ6ICMwMDA7XFxufVxcbi5qQm94LVRvb2x0aXBEYXJrIC5qQm94LWNsb3NlQnV0dG9uIHtcXG4gIGJhY2tncm91bmQ6ICMwMDA7XFxufVxcbi5qQm94LVRvb2x0aXBEYXJrLmpCb3gtY2xvc2VCdXR0b24tYm94OmJlZm9yZSB7XFxuICBib3gtc2hhZG93OiAwIDAgNnB4IHJnYmEoMCwgMCwgMCwgMC40KTtcXG59XFxuLmpCb3gtVG9vbHRpcERhcmsuakJveC1jbG9zZUJ1dHRvbi1ib3ggLmpCb3gtY2xvc2VCdXR0b24gcGF0aCB7XFxuICBmaWxsOiAjZGRkO1xcbn1cXG4uakJveC1Ub29sdGlwRGFyay5qQm94LWNsb3NlQnV0dG9uLWJveCAuakJveC1jbG9zZUJ1dHRvbjpob3ZlciBwYXRoIHtcXG4gIGZpbGw6ICNmZmY7XFxufVxcbi5qQm94LVRvb2x0aXBEYXJrLmpCb3gtY2xvc2VCdXR0b24tYm94IC5qQm94LWNsb3NlQnV0dG9uOmFjdGl2ZSBwYXRoIHtcXG4gIGZpbGw6ICNiYmI7XFxufVxcbi5qQm94LVRvb2x0aXBFcnJvciB7XFxuICBwb2ludGVyLWV2ZW50czogbm9uZTtcXG59XFxuLmpCb3gtVG9vbHRpcEVycm9yIC5qQm94LWNvbnRhaW5lciB7XFxuICBib3JkZXItcmFkaXVzOiAycHg7XFxuICBiYWNrZ3JvdW5kOiAjZDAwO1xcbiAgY29sb3I6ICNmZmY7XFxuICBmb250LXdlaWdodDogYm9sZDtcXG4gIGZvbnQtc2l6ZTogMTNweDtcXG59XFxuLmpCb3gtVG9vbHRpcEVycm9yIC5qQm94LWNvbnRlbnQge1xcbiAgcGFkZGluZzogMCAxMHB4O1xcbiAgbGluZS1oZWlnaHQ6IDI4cHg7XFxufVxcbi5qQm94LVRvb2x0aXBFcnJvciAuakJveC1wb2ludGVyOmFmdGVyIHtcXG4gIGJhY2tncm91bmQ6ICNkMDA7XFxuICB3aWR0aDogMjBweDtcXG4gIGhlaWdodDogMjBweDtcXG59XFxuLmpCb3gtVG9vbHRpcEVycm9yIC5qQm94LXBvaW50ZXItdG9wLFxcbi5qQm94LVRvb2x0aXBFcnJvciAuakJveC1wb2ludGVyLWJvdHRvbSB7XFxuICB3aWR0aDogMjJweDtcXG4gIGhlaWdodDogOHB4O1xcbn1cXG4uakJveC1Ub29sdGlwRXJyb3IgLmpCb3gtcG9pbnRlci1yaWdodCxcXG4uakJveC1Ub29sdGlwRXJyb3IgLmpCb3gtcG9pbnRlci1sZWZ0IHtcXG4gIHdpZHRoOiA4cHg7XFxuICBoZWlnaHQ6IDIycHg7XFxufVxcbi5qQm94LVRvb2x0aXBFcnJvciAuakJveC1wb2ludGVyLXRvcDphZnRlciB7XFxuICBsZWZ0OiAxcHg7XFxuICB0b3A6IDZweDtcXG59XFxuLmpCb3gtVG9vbHRpcEVycm9yIC5qQm94LXBvaW50ZXItcmlnaHQ6YWZ0ZXIge1xcbiAgdG9wOiAxcHg7XFxuICByaWdodDogNnB4O1xcbn1cXG4uakJveC1Ub29sdGlwRXJyb3IgLmpCb3gtcG9pbnRlci1ib3R0b206YWZ0ZXIge1xcbiAgbGVmdDogMXB4O1xcbiAgYm90dG9tOiA2cHg7XFxufVxcbi5qQm94LVRvb2x0aXBFcnJvciAuakJveC1wb2ludGVyLWxlZnQ6YWZ0ZXIge1xcbiAgdG9wOiAxcHg7XFxuICBsZWZ0OiA2cHg7XFxufVxcbi5qQm94LVRvb2x0aXBTbWFsbCB7XFxuICBwb2ludGVyLWV2ZW50czogbm9uZTtcXG59XFxuLmpCb3gtVG9vbHRpcFNtYWxsIC5qQm94LWNvbnRhaW5lciB7XFxuICBib3JkZXItcmFkaXVzOiAycHg7XFxufVxcbi5qQm94LVRvb2x0aXBTbWFsbCAuakJveC1jb250ZW50IHtcXG4gIHBhZGRpbmc6IDAgMTBweDtcXG4gIGxpbmUtaGVpZ2h0OiAyOHB4O1xcbn1cXG4uakJveC1Ub29sdGlwU21hbGwgLmpCb3gtcG9pbnRlcjphZnRlciB7XFxuICB3aWR0aDogMjBweDtcXG4gIGhlaWdodDogMjBweDtcXG59XFxuLmpCb3gtVG9vbHRpcFNtYWxsIC5qQm94LXBvaW50ZXItdG9wLFxcbi5qQm94LVRvb2x0aXBTbWFsbCAuakJveC1wb2ludGVyLWJvdHRvbSB7XFxuICB3aWR0aDogMjJweDtcXG4gIGhlaWdodDogOHB4O1xcbn1cXG4uakJveC1Ub29sdGlwU21hbGwgLmpCb3gtcG9pbnRlci1yaWdodCxcXG4uakJveC1Ub29sdGlwU21hbGwgLmpCb3gtcG9pbnRlci1sZWZ0IHtcXG4gIHdpZHRoOiA4cHg7XFxuICBoZWlnaHQ6IDIycHg7XFxufVxcbi5qQm94LVRvb2x0aXBTbWFsbCAuakJveC1wb2ludGVyLXRvcDphZnRlciB7XFxuICBsZWZ0OiAxcHg7XFxuICB0b3A6IDZweDtcXG59XFxuLmpCb3gtVG9vbHRpcFNtYWxsIC5qQm94LXBvaW50ZXItcmlnaHQ6YWZ0ZXIge1xcbiAgdG9wOiAxcHg7XFxuICByaWdodDogNnB4O1xcbn1cXG4uakJveC1Ub29sdGlwU21hbGwgLmpCb3gtcG9pbnRlci1ib3R0b206YWZ0ZXIge1xcbiAgbGVmdDogMXB4O1xcbiAgYm90dG9tOiA2cHg7XFxufVxcbi5qQm94LVRvb2x0aXBTbWFsbCAuakJveC1wb2ludGVyLWxlZnQ6YWZ0ZXIge1xcbiAgdG9wOiAxcHg7XFxuICBsZWZ0OiA2cHg7XFxufVxcbi5qQm94LVRvb2x0aXBTbWFsbEdyYXkge1xcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XFxufVxcbi5qQm94LVRvb2x0aXBTbWFsbEdyYXkgLmpCb3gtY29udGFpbmVyIHtcXG4gIGZvbnQtc2l6ZTogMTNweDtcXG4gIGxpbmUtaGVpZ2h0OiAyNHB4O1xcbiAgYm9yZGVyLXJhZGl1czogMTJweDtcXG4gIGJhY2tncm91bmQtaW1hZ2U6IGxpbmVhci1ncmFkaWVudCh0byBib3R0b20sICNmYWZhZmEsICNmMmYyZjIpO1xcbn1cXG4uakJveC1Ub29sdGlwU21hbGxHcmF5IC5qQm94LWNvbnRlbnQge1xcbiAgcGFkZGluZzogMCAxMHB4O1xcbn1cXG4uakJveC1Ub29sdGlwU21hbGxHcmF5IC5qQm94LXBvaW50ZXI6YWZ0ZXIge1xcbiAgd2lkdGg6IDIwcHg7XFxuICBoZWlnaHQ6IDIwcHg7XFxufVxcbi5qQm94LVRvb2x0aXBTbWFsbEdyYXkgLmpCb3gtcG9pbnRlci10b3AsXFxuLmpCb3gtVG9vbHRpcFNtYWxsR3JheSAuakJveC1wb2ludGVyLWJvdHRvbSB7XFxuICB3aWR0aDogMjJweDtcXG4gIGhlaWdodDogOHB4O1xcbn1cXG4uakJveC1Ub29sdGlwU21hbGxHcmF5IC5qQm94LXBvaW50ZXItbGVmdCxcXG4uakJveC1Ub29sdGlwU21hbGxHcmF5IC5qQm94LXBvaW50ZXItcmlnaHQge1xcbiAgd2lkdGg6IDhweDtcXG4gIGhlaWdodDogMjJweDtcXG59XFxuLmpCb3gtVG9vbHRpcFNtYWxsR3JheSAuakJveC1wb2ludGVyLXRvcDphZnRlciB7XFxuICBiYWNrZ3JvdW5kOiAjZmFmYWZhO1xcbiAgbGVmdDogMXB4O1xcbiAgdG9wOiA2cHg7XFxufVxcbi5qQm94LVRvb2x0aXBTbWFsbEdyYXkgLmpCb3gtcG9pbnRlci1yaWdodDphZnRlciB7XFxuICB0b3A6IDFweDtcXG4gIHJpZ2h0OiA2cHg7XFxufVxcbi5qQm94LVRvb2x0aXBTbWFsbEdyYXkgLmpCb3gtcG9pbnRlci1ib3R0b206YWZ0ZXIge1xcbiAgYmFja2dyb3VuZDogI2YyZjJmMjtcXG4gIGxlZnQ6IDFweDtcXG4gIGJvdHRvbTogNnB4O1xcbn1cXG4uakJveC1Ub29sdGlwU21hbGxHcmF5IC5qQm94LXBvaW50ZXItbGVmdDphZnRlciB7XFxuICB0b3A6IDFweDtcXG4gIGxlZnQ6IDZweDtcXG59XFxuLyojIHNvdXJjZU1hcHBpbmdVUkw9akJveC5hbGwuY3NzLm1hcCAqL1xcblwiOyAocmVxdWlyZShcImJyb3dzZXJpZnktY3NzXCIpLmNyZWF0ZVN0eWxlKGNzcywgeyBcImhyZWZcIjogXCJub2RlX21vZHVsZXMvamJveC9kaXN0L2pCb3guYWxsLmNzc1wiIH0sIHsgXCJpbnNlcnRBdFwiOiBcImJvdHRvbVwiIH0pKTsgbW9kdWxlLmV4cG9ydHMgPSBjc3M7IiwiZnVuY3Rpb24gakJveFdyYXBwZXIoYil7ZnVuY3Rpb24gaCh0LGkpe3JldHVybiB0aGlzLm9wdGlvbnM9e2lkOm51bGwsd2lkdGg6XCJhdXRvXCIsaGVpZ2h0OlwiYXV0b1wiLG1pbldpZHRoOm51bGwsbWluSGVpZ2h0Om51bGwsbWF4V2lkdGg6bnVsbCxtYXhIZWlnaHQ6bnVsbCxyZXNwb25zaXZlV2lkdGg6ITAscmVzcG9uc2l2ZUhlaWdodDohMCxyZXNwb25zaXZlTWluV2lkdGg6MTAwLHJlc3BvbnNpdmVNaW5IZWlnaHQ6MTAwLGF0dGFjaDpudWxsLHRyaWdnZXI6XCJjbGlja1wiLHByZXZlbnREZWZhdWx0OiExLGNvbnRlbnQ6bnVsbCxnZXRDb250ZW50Om51bGwsdGl0bGU6bnVsbCxnZXRUaXRsZTpudWxsLGZvb3RlcjpudWxsLGlzb2xhdGVTY3JvbGw6ITAsYWpheDp7dXJsOm51bGwsZGF0YTpcIlwiLHJlbG9hZDohMSxnZXRVUkw6XCJkYXRhLXVybFwiLGdldERhdGE6XCJkYXRhLWFqYXhcIixzZXRDb250ZW50OiEwLGxvYWRpbmdDbGFzczohMCxzcGlubmVyOiEwLHNwaW5uZXJEZWxheTozMDAsc3Bpbm5lclJlcG9zaXRpb246ITB9LGNhbmNlbEFqYXhPbkNsb3NlOiEwLHRhcmdldDpudWxsLHBvc2l0aW9uOnt4OlwiY2VudGVyXCIseTpcImNlbnRlclwifSxvdXRzaWRlOm51bGwsb2Zmc2V0OjAsYXR0cmlidXRlczp7eDpcImxlZnRcIix5OlwidG9wXCJ9LGZpeGVkOiExLGFkanVzdFBvc2l0aW9uOiEwLGFkanVzdFRyYWNrZXI6ITEsYWRqdXN0RGlzdGFuY2U6NSxyZXBvc2l0aW9uOiEwLHJlcG9zaXRpb25Pbk9wZW46ITAscmVwb3NpdGlvbk9uQ29udGVudDohMCxob2xkUG9zaXRpb246ITAscG9pbnRlcjohMSxwb2ludFRvOlwidGFyZ2V0XCIsZmFkZToxODAsYW5pbWF0aW9uOm51bGwsdGhlbWU6XCJEZWZhdWx0XCIsYWRkQ2xhc3M6bnVsbCxvdmVybGF5OiExLG92ZXJsYXlDbGFzczpudWxsLHpJbmRleDoxZTQsZGVsYXlPcGVuOjAsZGVsYXlDbG9zZTowLGNsb3NlT25Fc2M6ITEsY2xvc2VPbkNsaWNrOiExLGNsb3NlT25Nb3VzZWxlYXZlOiExLGNsb3NlQnV0dG9uOiExLGFwcGVuZFRvOmIoXCJib2R5XCIpLGNyZWF0ZU9uSW5pdDohMSxibG9ja1Njcm9sbDohMSxibG9ja1Njcm9sbEFkanVzdDohMCxkcmFnZ2FibGU6ITEsZHJhZ092ZXI6ITAsYXV0b0Nsb3NlOiExLGRlbGF5T25Ib3ZlcjohMSxzaG93Q291bnRkb3duOiExLHByZWxvYWRBdWRpbzohMCxhdWRpbzpudWxsLHZvbHVtZToxMDAsb25Jbml0Om51bGwsb25BdHRhY2g6bnVsbCxvblBvc2l0aW9uOm51bGwsb25DcmVhdGVkOm51bGwsb25PcGVuOm51bGwsb25DbG9zZTpudWxsLG9uQ2xvc2VDb21wbGV0ZTpudWxsLG9uRHJhZ1N0YXJ0Om51bGwsb25EcmFnRW5kOm51bGx9LHRoaXMuX3BsdWdpbk9wdGlvbnM9e1Rvb2x0aXA6e2dldENvbnRlbnQ6XCJ0aXRsZVwiLHRyaWdnZXI6XCJtb3VzZWVudGVyXCIscG9zaXRpb246e3g6XCJjZW50ZXJcIix5OlwidG9wXCJ9LG91dHNpZGU6XCJ5XCIscG9pbnRlcjohMH0sTW91c2U6e3Jlc3BvbnNpdmVXaWR0aDohMSxyZXNwb25zaXZlSGVpZ2h0OiExLGFkanVzdFBvc2l0aW9uOlwiZmxpcFwiLHRhcmdldDpcIm1vdXNlXCIsdHJpZ2dlcjpcIm1vdXNlZW50ZXJcIixwb3NpdGlvbjp7eDpcInJpZ2h0XCIseTpcImJvdHRvbVwifSxvdXRzaWRlOlwieHlcIixvZmZzZXQ6NX0sTW9kYWw6e3RhcmdldDpiKHdpbmRvdyksZml4ZWQ6ITAsYmxvY2tTY3JvbGw6ITAsY2xvc2VPbkVzYzohMCxjbG9zZU9uQ2xpY2s6XCJvdmVybGF5XCIsY2xvc2VCdXR0b246ITAsb3ZlcmxheTohMCxhbmltYXRpb246XCJ6b29tSW5cIn19LHRoaXMub3B0aW9ucz1iLmV4dGVuZCghMCx0aGlzLm9wdGlvbnMsdGhpcy5fcGx1Z2luT3B0aW9uc1t0XXx8aC5fcGx1Z2luT3B0aW9uc1t0XSxpKSxcInN0cmluZ1wiPT1iLnR5cGUodCkmJih0aGlzLnR5cGU9dCksdGhpcy5pc1RvdWNoRGV2aWNlPWZ1bmN0aW9uKCl7dmFyIHQ9XCIgLXdlYmtpdC0gLW1vei0gLW8tIC1tcy0gXCIuc3BsaXQoXCIgXCIpO2lmKFwib250b3VjaHN0YXJ0XCJpbiB3aW5kb3d8fHdpbmRvdy5Eb2N1bWVudFRvdWNoJiZkb2N1bWVudCBpbnN0YW5jZW9mIERvY3VtZW50VG91Y2gpcmV0dXJuITA7dmFyIGksdD1bXCIoXCIsdC5qb2luKFwidG91Y2gtZW5hYmxlZCksKFwiKSxcImhlYXJ0elwiLFwiKVwiXS5qb2luKFwiXCIpO3JldHVybiBpPXQsd2luZG93Lm1hdGNoTWVkaWEoaSkubWF0Y2hlc30oKSx0aGlzLmlzVG91Y2hEZXZpY2UmJlwibW91c2VlbnRlclwiPT09dGhpcy5vcHRpb25zLnRyaWdnZXImJiExPT09dGhpcy5vcHRpb25zLmNsb3NlT25DbGljayYmKHRoaXMub3B0aW9ucy5jbG9zZU9uQ2xpY2s9XCJib2R5XCIpLHRoaXMuX2ZpcmVFdmVudD1mdW5jdGlvbih0LGkpe3RoaXMub3B0aW9uc1tcIl9cIit0XSYmdGhpcy5vcHRpb25zW1wiX1wiK3RdLmJpbmQodGhpcykoaSksdGhpcy5vcHRpb25zW3RdJiZ0aGlzLm9wdGlvbnNbdF0uYmluZCh0aGlzKShpKX0sbnVsbD09PXRoaXMub3B0aW9ucy5pZCYmKHRoaXMub3B0aW9ucy5pZD1cImpCb3hcIitoLl9nZXRVbmlxdWVJRCgpKSx0aGlzLmlkPXRoaXMub3B0aW9ucy5pZCwoXCJjZW50ZXJcIj09dGhpcy5vcHRpb25zLnBvc2l0aW9uLngmJlwieFwiPT10aGlzLm9wdGlvbnMub3V0c2lkZXx8XCJjZW50ZXJcIj09dGhpcy5vcHRpb25zLnBvc2l0aW9uLnkmJlwieVwiPT10aGlzLm9wdGlvbnMub3V0c2lkZSkmJih0aGlzLm9wdGlvbnMub3V0c2lkZT1udWxsKSxcInRhcmdldFwiIT10aGlzLm9wdGlvbnMucG9pbnRUb3x8dGhpcy5vcHRpb25zLm91dHNpZGUmJlwieHlcIiE9dGhpcy5vcHRpb25zLm91dHNpZGV8fCh0aGlzLm9wdGlvbnMucG9pbnRlcj0hMSksXCJvYmplY3RcIiE9Yi50eXBlKHRoaXMub3B0aW9ucy5vZmZzZXQpP3RoaXMub3B0aW9ucy5vZmZzZXQ9e3g6dGhpcy5vcHRpb25zLm9mZnNldCx5OnRoaXMub3B0aW9ucy5vZmZzZXR9OnRoaXMub3B0aW9ucy5vZmZzZXQ9Yi5leHRlbmQoe3g6MCx5OjB9LHRoaXMub3B0aW9ucy5vZmZzZXQpLFwib2JqZWN0XCIhPWIudHlwZSh0aGlzLm9wdGlvbnMuYWRqdXN0RGlzdGFuY2UpP3RoaXMub3B0aW9ucy5hZGp1c3REaXN0YW5jZT17dG9wOnRoaXMub3B0aW9ucy5hZGp1c3REaXN0YW5jZSxyaWdodDp0aGlzLm9wdGlvbnMuYWRqdXN0RGlzdGFuY2UsYm90dG9tOnRoaXMub3B0aW9ucy5hZGp1c3REaXN0YW5jZSxsZWZ0OnRoaXMub3B0aW9ucy5hZGp1c3REaXN0YW5jZX06dGhpcy5vcHRpb25zLmFkanVzdERpc3RhbmNlPWIuZXh0ZW5kKHt0b3A6NSxsZWZ0OjUscmlnaHQ6NSxib3R0b206NX0sdGhpcy5vcHRpb25zLmFkanVzdERpc3RhbmNlKSx0aGlzLm91dHNpZGU9ISghdGhpcy5vcHRpb25zLm91dHNpZGV8fFwieHlcIj09dGhpcy5vcHRpb25zLm91dHNpZGUpJiZ0aGlzLm9wdGlvbnMucG9zaXRpb25bdGhpcy5vcHRpb25zLm91dHNpZGVdLHRoaXMuYWxpZ249dGhpcy5vdXRzaWRlfHwoXCJjZW50ZXJcIiE9dGhpcy5vcHRpb25zLnBvc2l0aW9uLnkmJlwibnVtYmVyXCIhPWIudHlwZSh0aGlzLm9wdGlvbnMucG9zaXRpb24ueSk/dGhpcy5vcHRpb25zLnBvc2l0aW9uLng6XCJjZW50ZXJcIiE9dGhpcy5vcHRpb25zLnBvc2l0aW9uLngmJlwibnVtYmVyXCIhPWIudHlwZSh0aGlzLm9wdGlvbnMucG9zaXRpb24ueCk/dGhpcy5vcHRpb25zLnBvc2l0aW9uLnk6dGhpcy5vcHRpb25zLmF0dHJpYnV0ZXMueCksaC56SW5kZXhNYXg9TWF0aC5tYXgoaC56SW5kZXhNYXh8fDAsXCJhdXRvXCI9PT10aGlzLm9wdGlvbnMuekluZGV4PzFlNDp0aGlzLm9wdGlvbnMuekluZGV4KSxcImF1dG9cIj09PXRoaXMub3B0aW9ucy56SW5kZXgmJih0aGlzLmFkanVzdFpJbmRleE9uT3Blbj0hMCxoLnpJbmRleE1heCs9Mix0aGlzLm9wdGlvbnMuekluZGV4PWguekluZGV4TWF4LHRoaXMudHJ1ZU1vZGFsPXRoaXMub3B0aW9ucy5vdmVybGF5KSx0aGlzLl9nZXRPcHA9ZnVuY3Rpb24odCl7cmV0dXJue2xlZnQ6XCJyaWdodFwiLHJpZ2h0OlwibGVmdFwiLHRvcDpcImJvdHRvbVwiLGJvdHRvbTpcInRvcFwiLHg6XCJ5XCIseTpcInhcIn1bdF19LHRoaXMuX2dldFhZPWZ1bmN0aW9uKHQpe3JldHVybntsZWZ0OlwieFwiLHJpZ2h0OlwieFwiLHRvcDpcInlcIixib3R0b206XCJ5XCIsY2VudGVyOlwieFwifVt0XX0sdGhpcy5fZ2V0VEw9ZnVuY3Rpb24odCl7cmV0dXJue2xlZnQ6XCJsZWZ0XCIscmlnaHQ6XCJsZWZ0XCIsdG9wOlwidG9wXCIsYm90dG9tOlwidG9wXCIsY2VudGVyOlwibGVmdFwiLHg6XCJsZWZ0XCIseTpcInRvcFwifVt0XX0sdGhpcy5fZ2V0SW50PWZ1bmN0aW9uKHQsaSl7cmV0dXJuXCJhdXRvXCI9PXQ/XCJhdXRvXCI6dCYmXCJzdHJpbmdcIj09Yi50eXBlKHQpJiZcIiVcIj09dC5zbGljZSgtMSk/Yih3aW5kb3cpW1wiaGVpZ2h0XCI9PWk/XCJpbm5lckhlaWdodFwiOlwiaW5uZXJXaWR0aFwiXSgpKnBhcnNlSW50KHQucmVwbGFjZShcIiVcIixcIlwiKSkvMTAwOnR9LHRoaXMuX2NyZWF0ZVNWRz1mdW5jdGlvbih0LGkpe3ZhciBvPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsdCk7cmV0dXJuIGIuZWFjaChpLGZ1bmN0aW9uKHQsaSl7by5zZXRBdHRyaWJ1dGUoaVswXSxpWzFdfHxcIlwiKX0pLG99LHRoaXMuX2lzb2xhdGVTY3JvbGw9ZnVuY3Rpb24oZSl7ZSYmZS5sZW5ndGgmJmUub24oXCJET01Nb3VzZVNjcm9sbC5qQm94SXNvbGF0ZVNjcm9sbCBtb3VzZXdoZWVsLmpCb3hJc29sYXRlU2Nyb2xsXCIsZnVuY3Rpb24odCl7dmFyIGk9dC53aGVlbERlbHRhfHx0Lm9yaWdpbmFsRXZlbnQmJnQub3JpZ2luYWxFdmVudC53aGVlbERlbHRhfHwtdC5kZXRhaWwsbz0wPD10aGlzLnNjcm9sbFRvcCtlLm91dGVySGVpZ2h0KCktdGhpcy5zY3JvbGxIZWlnaHQscz10aGlzLnNjcm9sbFRvcDw9MDsoaTwwJiZvfHwwPGkmJnMpJiZ0LnByZXZlbnREZWZhdWx0KCl9KX0sdGhpcy5fc2V0VGl0bGVXaWR0aD1mdW5jdGlvbigpe2lmKCF0aGlzLnRpdGxlQ29udGFpbmVyfHxcImF1dG9cIj09dGhpcy5jb250ZW50WzBdLnN0eWxlLndpZHRoJiYhdGhpcy5jb250ZW50WzBdLnN0eWxlLm1heFdpZHRoKXJldHVybiBudWxsO3ZhciB0O1wibm9uZVwiPT10aGlzLndyYXBwZXIuY3NzKFwiZGlzcGxheVwiKT8odGhpcy53cmFwcGVyLmNzcyhcImRpc3BsYXlcIixcImJsb2NrXCIpLHQ9dGhpcy5jb250ZW50Lm91dGVyV2lkdGgoKSx0aGlzLndyYXBwZXIuY3NzKFwiZGlzcGxheVwiLFwibm9uZVwiKSk6dD10aGlzLmNvbnRlbnQub3V0ZXJXaWR0aCgpLHRoaXMudGl0bGVDb250YWluZXIuY3NzKHttYXhXaWR0aDpNYXRoLm1heCh0LHBhcnNlSW50KHRoaXMuY29udGVudFswXS5zdHlsZS5tYXhXaWR0aCkpfHxudWxsfSl9LHRoaXMuX2RyYWdnYWJsZT1mdW5jdGlvbigpe2lmKCF0aGlzLm9wdGlvbnMuZHJhZ2dhYmxlKXJldHVybiExO3ZhciB0PVwidGl0bGVcIj09dGhpcy5vcHRpb25zLmRyYWdnYWJsZT90aGlzLnRpdGxlQ29udGFpbmVyOnRoaXMub3B0aW9ucy5kcmFnZ2FibGUgaW5zdGFuY2VvZiBiP3RoaXMub3B0aW9ucy5kcmFnZ2FibGU6XCJzdHJpbmdcIj09Yi50eXBlKHRoaXMub3B0aW9ucy5kcmFnZ2FibGUpP2IodGhpcy5vcHRpb25zLmRyYWdnYWJsZSk6dGhpcy53cmFwcGVyO3JldHVybiEoISh0JiZ0IGluc3RhbmNlb2YgYiYmdC5sZW5ndGgpfHx0LmRhdGEoXCJqQm94LWRyYWdnYWJsZVwiKSkmJih0LmFkZENsYXNzKFwiakJveC1kcmFnZ2FibGVcIikuZGF0YShcImpCb3gtZHJhZ2dhYmxlXCIsITApLm9uKFwidG91Y2hzdGFydCBtb3VzZWRvd25cIixmdW5jdGlvbih0KXt2YXIgaSxvLHMsZSxuLGE7Mj09dC5idXR0b258fGIodC50YXJnZXQpLmhhc0NsYXNzKFwiakJveC1ub0RyYWdcIil8fGIodC50YXJnZXQpLnBhcmVudHMoXCIuakJveC1ub0RyYWdcIikubGVuZ3RoP1widG91Y2hzdGFydFwiPT10LnR5cGUmJihiKHQudGFyZ2V0KS5oYXNDbGFzcyhcImpCb3gtY2xvc2VCdXR0b25cIil8fGIodC50YXJnZXQpLnBhcmVudHMoXCIuakJveC1jbG9zZUJ1dHRvblwiKS5sZW5ndGgpJiZ0aGlzLmNsb3NlKHtpZ25vcmVEZWxheTohMH0pOihvPVwidG91Y2hzdGFydFwiPT10LnR5cGUmJnQudG91Y2hlcyYmdC50b3VjaGVzWzBdPyhpPXQudG91Y2hlc1swXS5wYWdlWCx0LnRvdWNoZXNbMF0ucGFnZVkpOihpPXQucGFnZVgsdC5wYWdlWSksdGhpcy5kcmFnZ2luZ1N0YXJ0WD1pLHRoaXMuZHJhZ2dpbmdTdGFydFk9byx0aGlzLm9wdGlvbnMuZHJhZ092ZXImJiF0aGlzLnRydWVNb2RhbCYmcGFyc2VJbnQodGhpcy53cmFwcGVyLmNzcyhcInpJbmRleFwiKSwxMCk8PWguekluZGV4TWF4RHJhZ292ZXImJihoLnpJbmRleE1heERyYWdvdmVyKz0xLHRoaXMud3JhcHBlci5jc3MoXCJ6SW5kZXhcIixoLnpJbmRleE1heERyYWdvdmVyKSkscz10aGlzLndyYXBwZXIub3V0ZXJIZWlnaHQoKSxlPXRoaXMud3JhcHBlci5vdXRlcldpZHRoKCksbj10aGlzLndyYXBwZXIub2Zmc2V0KCkudG9wK3MtbyxhPXRoaXMud3JhcHBlci5vZmZzZXQoKS5sZWZ0K2UtaSxiKGRvY3VtZW50KS5vbihcInRvdWNobW92ZS5qQm94LWRyYWdnYWJsZS1cIit0aGlzLmlkK1wiIG1vdXNlbW92ZS5qQm94LWRyYWdnYWJsZS1cIit0aGlzLmlkLGZ1bmN0aW9uKHQpe3ZhciBpLHQ9XCJ0b3VjaG1vdmVcIj09dC50eXBlJiZ0LnRvdWNoZXMmJnQudG91Y2hlc1swXT8oaT10LnRvdWNoZXNbMF0ucGFnZVgsdC50b3VjaGVzWzBdLnBhZ2VZKTooaT10LnBhZ2VYLHQucGFnZVkpO3RoaXMuZHJhZ2dpbmd8fHRoaXMuZHJhZ2dpbmdTdGFydFg9PWl8fHRoaXMuZHJhZ2dpbmdTdGFydFk9PXR8fCh0aGlzLl9maXJlRXZlbnQoXCJvbkRyYWdTdGFydFwiKSx0aGlzLmRyYWdnaW5nPSEwKSx0aGlzLndyYXBwZXIub2Zmc2V0KHt0b3A6dCtuLXMsbGVmdDppK2EtZX0pfS5iaW5kKHRoaXMpKSx0LnByZXZlbnREZWZhdWx0KCkpfS5iaW5kKHRoaXMpKS5vbihcInRvdWNoZW5kIG1vdXNldXBcIixmdW5jdGlvbigpe3ZhciB0O2IoZG9jdW1lbnQpLm9mZihcInRvdWNobW92ZS5qQm94LWRyYWdnYWJsZS1cIit0aGlzLmlkK1wiIG1vdXNlbW92ZS5qQm94LWRyYWdnYWJsZS1cIit0aGlzLmlkKSx0aGlzLmRyYWdnaW5nJiZ0aGlzLl9maXJlRXZlbnQoXCJvbkRyYWdFbmRcIiksdGhpcy5kcmFnZ2luZz0hMSxcIk1vZGFsXCIhPXRoaXMudHlwZSYmXCJDb25maXJtXCIhPXRoaXMudHlwZXx8IXRoaXMub3B0aW9ucy5ob2xkUG9zaXRpb258fCh0PXt4Oih0PWIoXCIjXCIrdGhpcy5pZCkub2Zmc2V0KCkpLmxlZnQtYihkb2N1bWVudCkuc2Nyb2xsTGVmdCgpLHk6dC50b3AtYihkb2N1bWVudCkuc2Nyb2xsVG9wKCl9LHRoaXMucG9zaXRpb24oe3Bvc2l0aW9uOnQsb2Zmc2V0Ont4OjAseTowfX0pKX0uYmluZCh0aGlzKSksdGhpcy50cnVlTW9kYWx8fChoLnpJbmRleE1heERyYWdvdmVyPWguekluZGV4TWF4RHJhZ292ZXI/TWF0aC5tYXgoaC56SW5kZXhNYXhEcmFnb3Zlcix0aGlzLm9wdGlvbnMuekluZGV4KTp0aGlzLm9wdGlvbnMuekluZGV4KSx0aGlzKX0sdGhpcy5fY3JlYXRlPWZ1bmN0aW9uKCl7dmFyIHQ7dGhpcy53cmFwcGVyfHwodGhpcy53cmFwcGVyPWIoXCI8ZGl2Lz5cIix7aWQ6dGhpcy5pZCxjbGFzczpcImpCb3gtd3JhcHBlclwiKyh0aGlzLnR5cGU/XCIgakJveC1cIit0aGlzLnR5cGU6XCJcIikrKHRoaXMub3B0aW9ucy50aGVtZT9cIiBqQm94LVwiK3RoaXMub3B0aW9ucy50aGVtZTpcIlwiKSsodGhpcy5vcHRpb25zLmFkZENsYXNzP1wiIFwiK3RoaXMub3B0aW9ucy5hZGRDbGFzczpcIlwiKX0pLmNzcyh7cG9zaXRpb246dGhpcy5vcHRpb25zLmZpeGVkP1wiZml4ZWRcIjpcImFic29sdXRlXCIsZGlzcGxheTpcIm5vbmVcIixvcGFjaXR5OjAsekluZGV4OnRoaXMub3B0aW9ucy56SW5kZXh9KS5kYXRhKFwiakJveFwiLHRoaXMpLHRoaXMub3B0aW9ucy5jbG9zZU9uTW91c2VsZWF2ZSYmdGhpcy53cmFwcGVyLm9uKFwibW91c2VsZWF2ZVwiLGZ1bmN0aW9uKHQpeyF0aGlzLnNvdXJjZXx8dC5yZWxhdGVkVGFyZ2V0IT10aGlzLnNvdXJjZVswXSYmLTE9PT1iLmluQXJyYXkodGhpcy5zb3VyY2VbMF0sYih0LnJlbGF0ZWRUYXJnZXQpLnBhcmVudHMoXCIqXCIpKSYmdGhpcy5jbG9zZSgpfS5iaW5kKHRoaXMpKSxcImJveFwiPT10aGlzLm9wdGlvbnMuY2xvc2VPbkNsaWNrJiZ0aGlzLndyYXBwZXIub24oXCJjbGljayB0YXBcIixmdW5jdGlvbigpe3RoaXMuY2xvc2Uoe2lnbm9yZURlbGF5OiEwfSl9LmJpbmQodGhpcykpLHRoaXMuY29udGFpbmVyPWIoJzxkaXYgY2xhc3M9XCJqQm94LWNvbnRhaW5lclwiLz4nKS5hcHBlbmRUbyh0aGlzLndyYXBwZXIpLHRoaXMuY29udGVudD1iKCc8ZGl2IGNsYXNzPVwiakJveC1jb250ZW50XCIvPicpLmFwcGVuZFRvKHRoaXMuY29udGFpbmVyKSx0aGlzLm9wdGlvbnMuZm9vdGVyJiYodGhpcy5mb290ZXI9YignPGRpdiBjbGFzcz1cImpCb3gtZm9vdGVyXCIvPicpLmFwcGVuZCh0aGlzLm9wdGlvbnMuZm9vdGVyKS5hcHBlbmRUbyh0aGlzLmNvbnRhaW5lcikpLHRoaXMub3B0aW9ucy5pc29sYXRlU2Nyb2xsJiZ0aGlzLl9pc29sYXRlU2Nyb2xsKHRoaXMuY29udGVudCksdGhpcy5vcHRpb25zLmNsb3NlQnV0dG9uJiYoKHQ9dGhpcy5fY3JlYXRlU1ZHKFwic3ZnXCIsW1tcInZpZXdCb3hcIixcIjAgMCAyNCAyNFwiXV0pKS5hcHBlbmRDaGlsZCh0aGlzLl9jcmVhdGVTVkcoXCJwYXRoXCIsW1tcImRcIixcIk0yMi4yLDRjMCwwLDAuNSwwLjYsMCwxLjFsLTYuOCw2LjhsNi45LDYuOWMwLjUsMC41LDAsMS4xLDAsMS4xTDIwLDIyLjNjMCwwLTAuNiwwLjUtMS4xLDBMMTIsMTUuNGwtNi45LDYuOWMtMC41LDAuNS0xLjEsMC0xLjEsMEwxLjcsMjBjMCwwLTAuNS0wLjYsMC0xLjFMOC42LDEyTDEuNyw1LjFDMS4yLDQuNiwxLjcsNCwxLjcsNEw0LDEuN2MwLDAsMC42LTAuNSwxLjEsMEwxMiw4LjVsNi44LTYuOGMwLjUtMC41LDEuMSwwLDEuMSwwTDIyLjIsNHpcIl1dKSksdGhpcy5jbG9zZUJ1dHRvbj1iKCc8ZGl2IGNsYXNzPVwiakJveC1jbG9zZUJ1dHRvbiBqQm94LW5vRHJhZ1wiLz4nKS5vbihcImNsaWNrIHRhcFwiLGZ1bmN0aW9uKHQpe3RoaXMuY2xvc2Uoe2lnbm9yZURlbGF5OiEwfSl9LmJpbmQodGhpcykpLmFwcGVuZCh0KSxcImJveFwiIT10aGlzLm9wdGlvbnMuY2xvc2VCdXR0b24mJighMCE9PXRoaXMub3B0aW9ucy5jbG9zZUJ1dHRvbnx8dGhpcy5vcHRpb25zLm92ZXJsYXl8fHRoaXMub3B0aW9ucy50aXRsZXx8dGhpcy5vcHRpb25zLmdldFRpdGxlKXx8KHRoaXMud3JhcHBlci5hZGRDbGFzcyhcImpCb3gtY2xvc2VCdXR0b24tYm94XCIpLHRoaXMuY2xvc2VCdXR0b24uYXBwZW5kVG8odGhpcy5jb250YWluZXIpKSksdGhpcy53cmFwcGVyLmFwcGVuZFRvKHRoaXMub3B0aW9ucy5hcHBlbmRUbyksdGhpcy53cmFwcGVyLmZpbmQoXCIuakJveC1jbG9zZUJ1dHRvblwiKS5sZW5ndGgmJmIuZWFjaChbXCJ0b3BcIixcInJpZ2h0XCIsXCJib3R0b21cIixcImxlZnRcIl0sZnVuY3Rpb24odCxpKXt0aGlzLndyYXBwZXIuZmluZChcIi5qQm94LWNsb3NlQnV0dG9uXCIpLmNzcyhpKSYmXCJhdXRvXCIhPXRoaXMud3JhcHBlci5maW5kKFwiLmpCb3gtY2xvc2VCdXR0b25cIikuY3NzKGkpJiYodGhpcy5vcHRpb25zLmFkanVzdERpc3RhbmNlW2ldPU1hdGgubWF4KHRoaXMub3B0aW9ucy5hZGp1c3REaXN0YW5jZVtpXSx0aGlzLm9wdGlvbnMuYWRqdXN0RGlzdGFuY2VbaV0rLTEqKChwYXJzZUludCh0aGlzLndyYXBwZXIuZmluZChcIi5qQm94LWNsb3NlQnV0dG9uXCIpLmNzcyhpKSl8fDApKyhwYXJzZUludCh0aGlzLmNvbnRhaW5lci5jc3MoXCJib3JkZXItXCIraStcIi13aWR0aFwiKSl8fDApKSkpfS5iaW5kKHRoaXMpKSx0aGlzLm9wdGlvbnMucG9pbnRlciYmKHRoaXMucG9pbnRlcj17cG9zaXRpb246XCJ0YXJnZXRcIiE9dGhpcy5vcHRpb25zLnBvaW50VG8/dGhpcy5vcHRpb25zLnBvaW50VG86dGhpcy5fZ2V0T3BwKHRoaXMub3V0c2lkZSkseHk6XCJ0YXJnZXRcIiE9dGhpcy5vcHRpb25zLnBvaW50VG8/dGhpcy5fZ2V0WFkodGhpcy5vcHRpb25zLnBvaW50VG8pOnRoaXMuX2dldFhZKHRoaXMub3V0c2lkZSksYWxpZ246XCJjZW50ZXJcIixvZmZzZXQ6MH0sdGhpcy5wb2ludGVyLmVsZW1lbnQ9YignPGRpdiBjbGFzcz1cImpCb3gtcG9pbnRlciBqQm94LXBvaW50ZXItJyt0aGlzLnBvaW50ZXIucG9zaXRpb24rJ1wiLz4nKS5hcHBlbmRUbyh0aGlzLndyYXBwZXIpLHRoaXMucG9pbnRlci5kaW1lbnNpb25zPXt4OnRoaXMucG9pbnRlci5lbGVtZW50Lm91dGVyV2lkdGgoKSx5OnRoaXMucG9pbnRlci5lbGVtZW50Lm91dGVySGVpZ2h0KCl9LFwic3RyaW5nXCI9PWIudHlwZSh0aGlzLm9wdGlvbnMucG9pbnRlcikmJigodD10aGlzLm9wdGlvbnMucG9pbnRlci5zcGxpdChcIjpcIikpWzBdJiYodGhpcy5wb2ludGVyLmFsaWduPXRbMF0pLHRbMV0mJih0aGlzLnBvaW50ZXIub2Zmc2V0PXBhcnNlSW50KHRbMV0pKSksdGhpcy5wb2ludGVyLmFsaWduQXR0cmlidXRlPVwieFwiPT10aGlzLnBvaW50ZXIueHk/XCJib3R0b21cIj09dGhpcy5wb2ludGVyLmFsaWduP1wiYm90dG9tXCI6XCJ0b3BcIjpcInJpZ2h0XCI9PXRoaXMucG9pbnRlci5hbGlnbj9cInJpZ2h0XCI6XCJsZWZ0XCIsdGhpcy53cmFwcGVyLmNzcyhcInBhZGRpbmctXCIrdGhpcy5wb2ludGVyLnBvc2l0aW9uLHRoaXMucG9pbnRlci5kaW1lbnNpb25zW3RoaXMucG9pbnRlci54eV0pLHRoaXMucG9pbnRlci5lbGVtZW50LmNzcyh0aGlzLnBvaW50ZXIuYWxpZ25BdHRyaWJ1dGUsXCJjZW50ZXJcIj09dGhpcy5wb2ludGVyLmFsaWduP1wiNTAlXCI6MCkuY3NzKFwibWFyZ2luLVwiK3RoaXMucG9pbnRlci5hbGlnbkF0dHJpYnV0ZSx0aGlzLnBvaW50ZXIub2Zmc2V0KSx0aGlzLnBvaW50ZXIubWFyZ2luPXt9LHRoaXMucG9pbnRlci5tYXJnaW5bXCJtYXJnaW4tXCIrdGhpcy5wb2ludGVyLmFsaWduQXR0cmlidXRlXT10aGlzLnBvaW50ZXIub2Zmc2V0LFwiY2VudGVyXCI9PXRoaXMucG9pbnRlci5hbGlnbiYmdGhpcy5wb2ludGVyLmVsZW1lbnQuY3NzKFwidHJhbnNmb3JtXCIsXCJ0cmFuc2xhdGUoXCIrKFwieVwiPT10aGlzLnBvaW50ZXIueHk/LS41KnRoaXMucG9pbnRlci5kaW1lbnNpb25zLngrXCJweFwiOjApK1wiLCBcIisoXCJ4XCI9PXRoaXMucG9pbnRlci54eT8tLjUqdGhpcy5wb2ludGVyLmRpbWVuc2lvbnMueStcInB4XCI6MCkrXCIpXCIpLHRoaXMucG9pbnRlci5lbGVtZW50LmNzcyhcInhcIj09dGhpcy5wb2ludGVyLnh5P1wid2lkdGhcIjpcImhlaWdodFwiLHBhcnNlSW50KHRoaXMucG9pbnRlci5kaW1lbnNpb25zW3RoaXMucG9pbnRlci54eV0pK3BhcnNlSW50KHRoaXMuY29udGFpbmVyLmNzcyhcImJvcmRlci1cIit0aGlzLnBvaW50ZXIuYWxpZ25BdHRyaWJ1dGUrXCItd2lkdGhcIikpKSx0aGlzLndyYXBwZXIuYWRkQ2xhc3MoXCJqQm94LXBvaW50ZXJQb3NpdGlvbi1cIit0aGlzLnBvaW50ZXIucG9zaXRpb24pKSx0aGlzLnNldENvbnRlbnQodGhpcy5vcHRpb25zLmNvbnRlbnQsITApLHRoaXMuc2V0VGl0bGUodGhpcy5vcHRpb25zLnRpdGxlLCEwKSx0aGlzLm9wdGlvbnMuZHJhZ2dhYmxlJiZ0aGlzLl9kcmFnZ2FibGUoKSx0aGlzLl9maXJlRXZlbnQoXCJvbkNyZWF0ZWRcIikpfSx0aGlzLm9wdGlvbnMuY3JlYXRlT25Jbml0JiZ0aGlzLl9jcmVhdGUoKSx0aGlzLm9wdGlvbnMuYXR0YWNoJiZ0aGlzLmF0dGFjaCgpLHRoaXMuX2F0dGFjaEV2ZW50cz1mdW5jdGlvbigpe3RoaXMub3B0aW9ucy5kZWxheU9uSG92ZXImJmIoXCIjXCIrdGhpcy5pZCkub24oXCJtb3VzZWVudGVyXCIsZnVuY3Rpb24odCl7dGhpcy5pc0hvdmVyZWQ9ITB9LmJpbmQodGhpcykpLHRoaXMub3B0aW9ucy5kZWxheU9uSG92ZXImJmIoXCIjXCIrdGhpcy5pZCkub24oXCJtb3VzZWxlYXZlXCIsZnVuY3Rpb24odCl7dGhpcy5pc0hvdmVyZWQ9ITF9LmJpbmQodGhpcykpLCh0aGlzLm9wdGlvbnMuYWRqdXN0UG9zaXRpb258fHRoaXMub3B0aW9ucy5yZXBvc2l0aW9uKSYmIXRoaXMuZml4ZWQmJnRoaXMub3V0c2lkZSYmKHRoaXMub3B0aW9ucy5hZGp1c3RUcmFja2VyJiZiKHdpbmRvdykub24oXCJzY3JvbGwuakJveC1cIit0aGlzLmlkLGZ1bmN0aW9uKHQpe3RoaXMucG9zaXRpb24oKX0uYmluZCh0aGlzKSksKHRoaXMub3B0aW9ucy5hZGp1c3RQb3NpdGlvbnx8dGhpcy5vcHRpb25zLnJlcG9zaXRpb24pJiZiKHdpbmRvdykub24oXCJyZXNpemUuakJveC1cIit0aGlzLmlkLGZ1bmN0aW9uKHQpe3RoaXMucG9zaXRpb24oKX0uYmluZCh0aGlzKSkpLFwibW91c2VcIj09dGhpcy5vcHRpb25zLnRhcmdldCYmYihcImJvZHlcIikub24oXCJtb3VzZW1vdmUuakJveC1cIit0aGlzLmlkLGZ1bmN0aW9uKHQpe3RoaXMucG9zaXRpb24oe21vdXNlVGFyZ2V0Ont0b3A6dC5wYWdlWSxsZWZ0OnQucGFnZVh9fSl9LmJpbmQodGhpcykpfSx0aGlzLl9kZXRhY2hFdmVudHM9ZnVuY3Rpb24oKXt0aGlzLm9wdGlvbnMuY2xvc2VPbkVzYyYmYihkb2N1bWVudCkub2ZmKFwia2V5dXAuakJveC1cIit0aGlzLmlkKSwhMCE9PXRoaXMub3B0aW9ucy5jbG9zZU9uQ2xpY2smJlwiYm9keVwiIT10aGlzLm9wdGlvbnMuY2xvc2VPbkNsaWNrfHxiKGRvY3VtZW50KS5vZmYoXCJjbGljay5qQm94LVwiK3RoaXMuaWQrXCIgdGFwLmpCb3gtXCIrdGhpcy5pZCksdGhpcy5vcHRpb25zLmFkanVzdFRyYWNrZXImJmIod2luZG93KS5vZmYoXCJzY3JvbGwuakJveC1cIit0aGlzLmlkKSwodGhpcy5vcHRpb25zLmFkanVzdFBvc2l0aW9ufHx0aGlzLm9wdGlvbnMucmVwb3NpdGlvbikmJmIod2luZG93KS5vZmYoXCJyZXNpemUuakJveC1cIit0aGlzLmlkKSxcIm1vdXNlXCI9PXRoaXMub3B0aW9ucy50YXJnZXQmJmIoXCJib2R5XCIpLm9mZihcIm1vdXNlbW92ZS5qQm94LVwiK3RoaXMuaWQpfSx0aGlzLl9zaG93T3ZlcmxheT1mdW5jdGlvbigpe3RoaXMub3ZlcmxheXx8KHRoaXMub3ZlcmxheT1iKCc8ZGl2IGlkPVwiJyt0aGlzLmlkKyctb3ZlcmxheVwiLz4nKS5hZGRDbGFzcyhcImpCb3gtb3ZlcmxheVwiKyh0aGlzLnR5cGU/XCIgakJveC1vdmVybGF5LVwiK3RoaXMudHlwZTpcIlwiKSkuY3NzKHtkaXNwbGF5Olwibm9uZVwiLG9wYWNpdHk6MCx6SW5kZXg6dGhpcy5vcHRpb25zLnpJbmRleC0xfSkuYXBwZW5kVG8odGhpcy5vcHRpb25zLmFwcGVuZFRvKSx0aGlzLm9wdGlvbnMub3ZlcmxheUNsYXNzJiZ0aGlzLm92ZXJsYXkuYWRkQ2xhc3ModGhpcy5vcHRpb25zLm92ZXJsYXlDbGFzcyksXCJvdmVybGF5XCIhPXRoaXMub3B0aW9ucy5jbG9zZUJ1dHRvbiYmITAhPT10aGlzLm9wdGlvbnMuY2xvc2VCdXR0b258fHRoaXMub3ZlcmxheS5hcHBlbmQodGhpcy5jbG9zZUJ1dHRvbiksXCJvdmVybGF5XCI9PXRoaXMub3B0aW9ucy5jbG9zZU9uQ2xpY2smJnRoaXMub3ZlcmxheS5vbihcImNsaWNrIHRhcFwiLGZ1bmN0aW9uKCl7dGhpcy5jbG9zZSh7aWdub3JlRGVsYXk6ITB9KX0uYmluZCh0aGlzKSksYihcIiNcIit0aGlzLmlkK1wiLW92ZXJsYXkgLmpCb3gtY2xvc2VCdXR0b25cIikubGVuZ3RoJiYodGhpcy5vcHRpb25zLmFkanVzdERpc3RhbmNlLnRvcD1NYXRoLm1heChiKFwiI1wiK3RoaXMuaWQrXCItb3ZlcmxheSAuakJveC1jbG9zZUJ1dHRvblwiKS5vdXRlckhlaWdodCgpLHRoaXMub3B0aW9ucy5hZGp1c3REaXN0YW5jZS50b3ApKSksITA9PT10aGlzLmFkanVzdFpJbmRleE9uT3BlbiYmdGhpcy5vdmVybGF5LmNzcyhcInpJbmRleFwiLHBhcnNlSW50KHRoaXMud3JhcHBlci5jc3MoXCJ6SW5kZXhcIiksMTApLTEpLFwiYmxvY2tcIiE9dGhpcy5vdmVybGF5LmNzcyhcImRpc3BsYXlcIikmJih0aGlzLm9wdGlvbnMuZmFkZT90aGlzLm92ZXJsYXkuc3RvcCgpJiZ0aGlzLm92ZXJsYXkuYW5pbWF0ZSh7b3BhY2l0eToxfSx7cXVldWU6ITEsZHVyYXRpb246dGhpcy5vcHRpb25zLmZhZGUsc3RhcnQ6ZnVuY3Rpb24oKXt0aGlzLm92ZXJsYXkuY3NzKHtkaXNwbGF5OlwiYmxvY2tcIn0pfS5iaW5kKHRoaXMpfSk6dGhpcy5vdmVybGF5LmNzcyh7ZGlzcGxheTpcImJsb2NrXCIsb3BhY2l0eToxfSkpfSx0aGlzLl9oaWRlT3ZlcmxheT1mdW5jdGlvbigpe3RoaXMub3ZlcmxheSYmKHRoaXMub3B0aW9ucy5mYWRlP3RoaXMub3ZlcmxheS5zdG9wKCkmJnRoaXMub3ZlcmxheS5hbmltYXRlKHtvcGFjaXR5OjB9LHtxdWV1ZTohMSxkdXJhdGlvbjp0aGlzLm9wdGlvbnMuZmFkZSxjb21wbGV0ZTpmdW5jdGlvbigpe3RoaXMub3ZlcmxheS5jc3Moe2Rpc3BsYXk6XCJub25lXCJ9KX0uYmluZCh0aGlzKX0pOnRoaXMub3ZlcmxheS5jc3Moe2Rpc3BsYXk6XCJub25lXCIsb3BhY2l0eTowfSkpfSx0aGlzLl9leHBvc2VEaW1lbnNpb25zPWZ1bmN0aW9uKCl7dGhpcy53cmFwcGVyLmNzcyh7dG9wOi0xZTQsbGVmdDotMWU0LHJpZ2h0OlwiYXV0b1wiLGJvdHRvbTpcImF1dG9cIn0pO3ZhciB0PXt4OnRoaXMud3JhcHBlci5vdXRlcldpZHRoKCkseTp0aGlzLndyYXBwZXIub3V0ZXJIZWlnaHQoKX07cmV0dXJuIHRoaXMud3JhcHBlci5jc3Moe3RvcDpcImF1dG9cIixsZWZ0OlwiYXV0b1wifSksdH0sdGhpcy5fZ2VuZXJhdGVBbmltYXRpb25DU1M9ZnVuY3Rpb24oKXtpZihcIm9iamVjdFwiIT1iLnR5cGUodGhpcy5vcHRpb25zLmFuaW1hdGlvbikmJih0aGlzLm9wdGlvbnMuYW5pbWF0aW9uPXtwdWxzZTp7b3BlbjpcInB1bHNlXCIsY2xvc2U6XCJ6b29tT3V0XCJ9LHpvb21Jbjp7b3BlbjpcInpvb21JblwiLGNsb3NlOlwiem9vbUluXCJ9LHpvb21PdXQ6e29wZW46XCJ6b29tT3V0XCIsY2xvc2U6XCJ6b29tT3V0XCJ9LG1vdmU6e29wZW46XCJtb3ZlXCIsY2xvc2U6XCJtb3ZlXCJ9LHNsaWRlOntvcGVuOlwic2xpZGVcIixjbG9zZTpcInNsaWRlXCJ9LGZsaXA6e29wZW46XCJmbGlwXCIsY2xvc2U6XCJmbGlwXCJ9LHRhZGE6e29wZW46XCJ0YWRhXCIsY2xvc2U6XCJ6b29tT3V0XCJ9fVt0aGlzLm9wdGlvbnMuYW5pbWF0aW9uXSksIXRoaXMub3B0aW9ucy5hbmltYXRpb24pcmV0dXJuIG51bGw7dGhpcy5vcHRpb25zLmFuaW1hdGlvbi5vcGVuJiYodGhpcy5vcHRpb25zLmFuaW1hdGlvbi5vcGVuPXRoaXMub3B0aW9ucy5hbmltYXRpb24ub3Blbi5zcGxpdChcIjpcIikpLHRoaXMub3B0aW9ucy5hbmltYXRpb24uY2xvc2UmJih0aGlzLm9wdGlvbnMuYW5pbWF0aW9uLmNsb3NlPXRoaXMub3B0aW9ucy5hbmltYXRpb24uY2xvc2Uuc3BsaXQoXCI6XCIpKSx0aGlzLm9wdGlvbnMuYW5pbWF0aW9uLm9wZW5EaXJlY3Rpb249dGhpcy5vcHRpb25zLmFuaW1hdGlvbi5vcGVuWzFdfHxudWxsLHRoaXMub3B0aW9ucy5hbmltYXRpb24uY2xvc2VEaXJlY3Rpb249dGhpcy5vcHRpb25zLmFuaW1hdGlvbi5jbG9zZVsxXXx8bnVsbCx0aGlzLm9wdGlvbnMuYW5pbWF0aW9uLm9wZW4mJih0aGlzLm9wdGlvbnMuYW5pbWF0aW9uLm9wZW49dGhpcy5vcHRpb25zLmFuaW1hdGlvbi5vcGVuWzBdKSx0aGlzLm9wdGlvbnMuYW5pbWF0aW9uLmNsb3NlJiYodGhpcy5vcHRpb25zLmFuaW1hdGlvbi5jbG9zZT10aGlzLm9wdGlvbnMuYW5pbWF0aW9uLmNsb3NlWzBdKSx0aGlzLm9wdGlvbnMuYW5pbWF0aW9uLm9wZW4mJih0aGlzLm9wdGlvbnMuYW5pbWF0aW9uLm9wZW4rPVwiT3BlblwiKSx0aGlzLm9wdGlvbnMuYW5pbWF0aW9uLmNsb3NlJiYodGhpcy5vcHRpb25zLmFuaW1hdGlvbi5jbG9zZSs9XCJDbG9zZVwiKTt2YXIgYT17cHVsc2U6e2R1cmF0aW9uOjM1MCxjc3M6W1tcIjAlXCIsXCJzY2FsZSgxKVwiXSxbXCI1MCVcIixcInNjYWxlKDEuMSlcIl0sW1wiMTAwJVwiLFwic2NhbGUoMSlcIl1dfSx6b29tSW5PcGVuOntkdXJhdGlvbjp0aGlzLm9wdGlvbnMuZmFkZXx8MTgwLGNzczpbW1wiMCVcIixcInNjYWxlKDAuOSlcIl0sW1wiMTAwJVwiLFwic2NhbGUoMSlcIl1dfSx6b29tSW5DbG9zZTp7ZHVyYXRpb246dGhpcy5vcHRpb25zLmZhZGV8fDE4MCxjc3M6W1tcIjAlXCIsXCJzY2FsZSgxKVwiXSxbXCIxMDAlXCIsXCJzY2FsZSgwLjkpXCJdXX0sem9vbU91dE9wZW46e2R1cmF0aW9uOnRoaXMub3B0aW9ucy5mYWRlfHwxODAsY3NzOltbXCIwJVwiLFwic2NhbGUoMS4xKVwiXSxbXCIxMDAlXCIsXCJzY2FsZSgxKVwiXV19LHpvb21PdXRDbG9zZTp7ZHVyYXRpb246dGhpcy5vcHRpb25zLmZhZGV8fDE4MCxjc3M6W1tcIjAlXCIsXCJzY2FsZSgxKVwiXSxbXCIxMDAlXCIsXCJzY2FsZSgxLjEpXCJdXX0sbW92ZU9wZW46e2R1cmF0aW9uOnRoaXMub3B0aW9ucy5mYWRlfHwxODAscG9zaXRpb25zOnt0b3A6e1wiMCVcIjotMTJ9LHJpZ2h0OntcIjAlXCI6MTJ9LGJvdHRvbTp7XCIwJVwiOjEyfSxsZWZ0OntcIjAlXCI6LTEyfX0sY3NzOltbXCIwJVwiLFwidHJhbnNsYXRlJVhZKCVWcHgpXCJdLFtcIjEwMCVcIixcInRyYW5zbGF0ZSVYWSgwcHgpXCJdXX0sbW92ZUNsb3NlOntkdXJhdGlvbjp0aGlzLm9wdGlvbnMuZmFkZXx8MTgwLHRpbWluZzpcImVhc2UtaW5cIixwb3NpdGlvbnM6e3RvcDp7XCIxMDAlXCI6LTEyfSxyaWdodDp7XCIxMDAlXCI6MTJ9LGJvdHRvbTp7XCIxMDAlXCI6MTJ9LGxlZnQ6e1wiMTAwJVwiOi0xMn19LGNzczpbW1wiMCVcIixcInRyYW5zbGF0ZSVYWSgwcHgpXCJdLFtcIjEwMCVcIixcInRyYW5zbGF0ZSVYWSglVnB4KVwiXV19LHNsaWRlT3Blbjp7ZHVyYXRpb246NDAwLHBvc2l0aW9uczp7dG9wOntcIjAlXCI6LTQwMH0scmlnaHQ6e1wiMCVcIjo0MDB9LGJvdHRvbTp7XCIwJVwiOjQwMH0sbGVmdDp7XCIwJVwiOi00MDB9fSxjc3M6W1tcIjAlXCIsXCJ0cmFuc2xhdGUlWFkoJVZweClcIl0sW1wiMTAwJVwiLFwidHJhbnNsYXRlJVhZKDBweClcIl1dfSxzbGlkZUNsb3NlOntkdXJhdGlvbjo0MDAsdGltaW5nOlwiZWFzZS1pblwiLHBvc2l0aW9uczp7dG9wOntcIjEwMCVcIjotNDAwfSxyaWdodDp7XCIxMDAlXCI6NDAwfSxib3R0b206e1wiMTAwJVwiOjQwMH0sbGVmdDp7XCIxMDAlXCI6LTQwMH19LGNzczpbW1wiMCVcIixcInRyYW5zbGF0ZSVYWSgwcHgpXCJdLFtcIjEwMCVcIixcInRyYW5zbGF0ZSVYWSglVnB4KVwiXV19LGZsaXBPcGVuOntkdXJhdGlvbjo2MDAsY3NzOltbXCIwJVwiLFwicGVyc3BlY3RpdmUoNDAwcHgpIHJvdGF0ZVgoOTBkZWcpXCJdLFtcIjQwJVwiLFwicGVyc3BlY3RpdmUoNDAwcHgpIHJvdGF0ZVgoLTE1ZGVnKVwiXSxbXCI3MCVcIixcInBlcnNwZWN0aXZlKDQwMHB4KSByb3RhdGVYKDE1ZGVnKVwiXSxbXCIxMDAlXCIsXCJwZXJzcGVjdGl2ZSg0MDBweCkgcm90YXRlWCgwZGVnKVwiXV19LGZsaXBDbG9zZTp7ZHVyYXRpb246dGhpcy5vcHRpb25zLmZhZGV8fDMwMCxjc3M6W1tcIjAlXCIsXCJwZXJzcGVjdGl2ZSg0MDBweCkgcm90YXRlWCgwZGVnKVwiXSxbXCIxMDAlXCIsXCJwZXJzcGVjdGl2ZSg0MDBweCkgcm90YXRlWCg5MGRlZylcIl1dfSx0YWRhOntkdXJhdGlvbjo4MDAsY3NzOltbXCIwJVwiLFwic2NhbGUoMSlcIl0sW1wiMTAlLCAyMCVcIixcInNjYWxlKDAuOSkgcm90YXRlKC0zZGVnKVwiXSxbXCIzMCUsIDUwJSwgNzAlLCA5MCVcIixcInNjYWxlKDEuMSkgcm90YXRlKDNkZWcpXCJdLFtcIjQwJSwgNjAlLCA4MCVcIixcInNjYWxlKDEuMSkgcm90YXRlKC0zZGVnKVwiXSxbXCIxMDAlXCIsXCJzY2FsZSgxKSByb3RhdGUoMClcIl1dfX07Yi5lYWNoKFtcInB1bHNlXCIsXCJ0YWRhXCJdLGZ1bmN0aW9uKHQsaSl7YVtpK1wiT3BlblwiXT1hW2krXCJDbG9zZVwiXT1hW2ldfSk7dmFyIHM9ZnVuY3Rpb24ocyxlKXt2YXIgbj1cIkBrZXlmcmFtZXMgakJveC1cIit0aGlzLmlkK1wiLWFuaW1hdGlvbi1cIit0aGlzLm9wdGlvbnMuYW5pbWF0aW9uW3NdK1wiLVwiK3MrKGU/XCItXCIrZTpcIlwiKStcIiB7XCI7cmV0dXJuIGIuZWFjaChhW3RoaXMub3B0aW9ucy5hbmltYXRpb25bc11dLmNzcyxmdW5jdGlvbih0LGkpe3ZhciBvPWU/aVsxXS5yZXBsYWNlKFwiJVhZXCIsdGhpcy5fZ2V0WFkoZSkudG9VcHBlckNhc2UoKSk6aVsxXTthW3RoaXMub3B0aW9ucy5hbmltYXRpb25bc11dLnBvc2l0aW9ucyYmKG89by5yZXBsYWNlKFwiJVZcIixhW3RoaXMub3B0aW9ucy5hbmltYXRpb25bc11dLnBvc2l0aW9uc1tlXVtpWzBdXSkpLG4rPWlbMF0rXCIge3RyYW5zZm9ybTpcIitvK1wiO31cIn0uYmluZCh0aGlzKSksbis9XCJ9XCIsbis9XCIuakJveC1cIit0aGlzLmlkK1wiLWFuaW1hdGlvbi1cIit0aGlzLm9wdGlvbnMuYW5pbWF0aW9uW3NdK1wiLVwiK3MrKGU/XCItXCIrZTpcIlwiKStcIiB7XCIsbis9XCJhbmltYXRpb24tZHVyYXRpb246IFwiK2FbdGhpcy5vcHRpb25zLmFuaW1hdGlvbltzXV0uZHVyYXRpb24rXCJtcztcIixuKz1cImFuaW1hdGlvbi1uYW1lOiBqQm94LVwiK3RoaXMuaWQrXCItYW5pbWF0aW9uLVwiK3RoaXMub3B0aW9ucy5hbmltYXRpb25bc10rXCItXCIrcysoZT9cIi1cIitlOlwiXCIpK1wiO1wiLG4rPWFbdGhpcy5vcHRpb25zLmFuaW1hdGlvbltzXV0udGltaW5nP1wiYW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjogXCIrYVt0aGlzLm9wdGlvbnMuYW5pbWF0aW9uW3NdXS50aW1pbmcrXCI7XCI6XCJcIixuKz1cIn1cIn0uYmluZCh0aGlzKTt0aGlzLl9hbmltYXRpb25DU1M9XCJcIixiLmVhY2goW1wib3BlblwiLFwiY2xvc2VcIl0sZnVuY3Rpb24odCxvKXtpZighdGhpcy5vcHRpb25zLmFuaW1hdGlvbltvXXx8IWFbdGhpcy5vcHRpb25zLmFuaW1hdGlvbltvXV18fFwiY2xvc2VcIj09byYmIXRoaXMub3B0aW9ucy5mYWRlKXJldHVyblwiXCI7YVt0aGlzLm9wdGlvbnMuYW5pbWF0aW9uW29dXS5wb3NpdGlvbnM/Yi5lYWNoKFtcInRvcFwiLFwicmlnaHRcIixcImJvdHRvbVwiLFwibGVmdFwiXSxmdW5jdGlvbih0LGkpe3RoaXMuX2FuaW1hdGlvbkNTUys9cyhvLGkpfS5iaW5kKHRoaXMpKTp0aGlzLl9hbmltYXRpb25DU1MrPXMobyl9LmJpbmQodGhpcykpfSx0aGlzLm9wdGlvbnMuYW5pbWF0aW9uJiZ0aGlzLl9nZW5lcmF0ZUFuaW1hdGlvbkNTUygpLHRoaXMuX2Jsb2NrQm9keUNsaWNrPWZ1bmN0aW9uKCl7dGhpcy5ibG9ja0JvZHlDbGljaz0hMCxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dGhpcy5ibG9ja0JvZHlDbGljaz0hMX0uYmluZCh0aGlzKSwxMCl9LHRoaXMuX2FuaW1hdGU9ZnVuY3Rpb24odCl7aWYodD10fHwodGhpcy5pc09wZW4/XCJvcGVuXCI6XCJjbG9zZVwiKSwhdGhpcy5vcHRpb25zLmZhZGUmJlwiY2xvc2VcIj09dClyZXR1cm4gbnVsbDt2YXIgaT10aGlzLm9wdGlvbnMuYW5pbWF0aW9uW3QrXCJEaXJlY3Rpb25cIl18fChcImNlbnRlclwiIT10aGlzLmFsaWduP3RoaXMuYWxpZ246dGhpcy5vcHRpb25zLmF0dHJpYnV0ZXMueCk7dGhpcy5mbGlwcGVkJiZ0aGlzLl9nZXRYWShpKT09dGhpcy5fZ2V0WFkodGhpcy5hbGlnbikmJihpPXRoaXMuX2dldE9wcChpKSk7dmFyIG89XCJqQm94LVwiK3RoaXMuaWQrXCItYW5pbWF0aW9uLVwiK3RoaXMub3B0aW9ucy5hbmltYXRpb25bdF0rXCItXCIrdCtcIiBqQm94LVwiK3RoaXMuaWQrXCItYW5pbWF0aW9uLVwiK3RoaXMub3B0aW9ucy5hbmltYXRpb25bdF0rXCItXCIrdCtcIi1cIitpO3RoaXMud3JhcHBlci5hZGRDbGFzcyhvKTtpPTFlMypwYXJzZUZsb2F0KHRoaXMud3JhcHBlci5jc3MoXCJhbmltYXRpb24tZHVyYXRpb25cIikpO1wiY2xvc2VcIj09dCYmKGk9TWF0aC5taW4oaSx0aGlzLm9wdGlvbnMuZmFkZSkpLHNldFRpbWVvdXQoZnVuY3Rpb24oKXt0aGlzLndyYXBwZXIucmVtb3ZlQ2xhc3Mobyl9LmJpbmQodGhpcyksaSl9LHRoaXMuX2Fib3J0QW5pbWF0aW9uPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy53cmFwcGVyLmF0dHIoXCJjbGFzc1wiKS5zcGxpdChcIiBcIikuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVybiAwIT09dC5sYXN0SW5kZXhPZihcImpCb3gtXCIrdGhpcy5pZCtcIi1hbmltYXRpb25cIiwwKX0uYmluZCh0aGlzKSk7dGhpcy53cmFwcGVyLmF0dHIoXCJjbGFzc1wiLHQuam9pbihcIiBcIikpfSwodGhpcy5vcHRpb25zLnJlc3BvbnNpdmVXaWR0aHx8dGhpcy5vcHRpb25zLnJlc3BvbnNpdmVIZWlnaHQpJiZiKHdpbmRvdykub24oXCJyZXNpemUucmVzcG9uc2l2ZWpCb3gtXCIrdGhpcy5pZCxmdW5jdGlvbih0KXt0aGlzLmlzT3BlbiYmdGhpcy5wb3NpdGlvbigpfS5iaW5kKHRoaXMpKSxcInN0cmluZ1wiPT09Yi50eXBlKHRoaXMub3B0aW9ucy5wcmVsb2FkQXVkaW8pJiYodGhpcy5vcHRpb25zLnByZWxvYWRBdWRpbz1bdGhpcy5vcHRpb25zLnByZWxvYWRBdWRpb10pLFwic3RyaW5nXCI9PT1iLnR5cGUodGhpcy5vcHRpb25zLmF1ZGlvKSYmKHRoaXMub3B0aW9ucy5hdWRpbz17b3Blbjp0aGlzLm9wdGlvbnMuYXVkaW99KSxcIm51bWJlclwiPT09Yi50eXBlKHRoaXMub3B0aW9ucy52b2x1bWUpJiYodGhpcy5vcHRpb25zLnZvbHVtZT17b3Blbjp0aGlzLm9wdGlvbnMudm9sdW1lLGNsb3NlOnRoaXMub3B0aW9ucy52b2x1bWV9KSwhMD09PXRoaXMub3B0aW9ucy5wcmVsb2FkQXVkaW8mJnRoaXMub3B0aW9ucy5hdWRpbyYmKHRoaXMub3B0aW9ucy5wcmVsb2FkQXVkaW89W10sYi5lYWNoKHRoaXMub3B0aW9ucy5hdWRpbyxmdW5jdGlvbih0LGkpe3RoaXMub3B0aW9ucy5wcmVsb2FkQXVkaW8ucHVzaChpK1wiLm1wM1wiKSx0aGlzLm9wdGlvbnMucHJlbG9hZEF1ZGlvLnB1c2goaStcIi5vZ2dcIil9LmJpbmQodGhpcykpKSx0aGlzLm9wdGlvbnMucHJlbG9hZEF1ZGlvLmxlbmd0aCYmYi5lYWNoKHRoaXMub3B0aW9ucy5wcmVsb2FkQXVkaW8sZnVuY3Rpb24odCxpKXt2YXIgbz1uZXcgQXVkaW87by5zcmM9aSxvLnByZWxvYWQ9XCJhdXRvXCJ9KSx0aGlzLl9maXJlRXZlbnQoXCJvbkluaXRcIiksdGhpc312YXIgdCxpO3JldHVybiBoLnByb3RvdHlwZS5hdHRhY2g9ZnVuY3Rpb24odCxzKXtyZXR1cm4gdD10fHx0aGlzLm9wdGlvbnMuYXR0YWNoLFwic3RyaW5nXCI9PWIudHlwZSh0KSYmKHQ9Yih0KSkscz1zfHx0aGlzLm9wdGlvbnMudHJpZ2dlcix0JiZ0Lmxlbmd0aCYmYi5lYWNoKHQsZnVuY3Rpb24odCxvKXsobz1iKG8pKS5kYXRhKFwiakJveC1hdHRhY2hlZC1cIit0aGlzLmlkKXx8KFwidGl0bGVcIj09dGhpcy5vcHRpb25zLmdldENvbnRlbnQmJm51bGwhPW8uYXR0cihcInRpdGxlXCIpJiZvLmRhdGEoXCJqQm94LWdldENvbnRlbnRcIixvLmF0dHIoXCJ0aXRsZVwiKSkucmVtb3ZlQXR0cihcInRpdGxlXCIpLHRoaXMuYXR0YWNoZWRFbGVtZW50c3x8KHRoaXMuYXR0YWNoZWRFbGVtZW50cz1bXSksdGhpcy5hdHRhY2hlZEVsZW1lbnRzLnB1c2gob1swXSksby5vbihzK1wiLmpCb3gtYXR0YWNoLVwiK3RoaXMuaWQsZnVuY3Rpb24odCl7dmFyIGk7dGhpcy50aW1lciYmY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLFwibW91c2VlbnRlclwiPT1zJiZ0aGlzLmlzT3BlbiYmdGhpcy5zb3VyY2VbMF09PW9bMF18fCh0aGlzLmlzT3BlbiYmdGhpcy5zb3VyY2UmJnRoaXMuc291cmNlWzBdIT1vWzBdJiYoaT0hMCksdGhpcy5zb3VyY2U9byx0aGlzLm9wdGlvbnMudGFyZ2V0fHwodGhpcy50YXJnZXQ9byksXCJjbGlja1wiPT1zJiZ0aGlzLm9wdGlvbnMucHJldmVudERlZmF1bHQmJnQucHJldmVudERlZmF1bHQoKSx0aGlzW1wiY2xpY2tcIiE9c3x8aT9cIm9wZW5cIjpcInRvZ2dsZVwiXSgpKX0uYmluZCh0aGlzKSksXCJtb3VzZWVudGVyXCI9PXRoaXMub3B0aW9ucy50cmlnZ2VyJiZvLm9uKFwibW91c2VsZWF2ZVwiLGZ1bmN0aW9uKHQpe2lmKCF0aGlzLndyYXBwZXIpcmV0dXJuIG51bGw7dGhpcy5vcHRpb25zLmNsb3NlT25Nb3VzZWxlYXZlJiYodC5yZWxhdGVkVGFyZ2V0PT10aGlzLndyYXBwZXJbMF18fGIodC5yZWxhdGVkVGFyZ2V0KS5wYXJlbnRzKFwiI1wiK3RoaXMuaWQpLmxlbmd0aCl8fHRoaXMuY2xvc2UoKX0uYmluZCh0aGlzKSksby5kYXRhKFwiakJveC1hdHRhY2hlZC1cIit0aGlzLmlkLHMpLHRoaXMuX2ZpcmVFdmVudChcIm9uQXR0YWNoXCIsbykpfS5iaW5kKHRoaXMpKSx0aGlzfSxoLnByb3RvdHlwZS5kZXRhY2g9ZnVuY3Rpb24odCl7cmV0dXJuKHQ9dHx8KHRoaXMuYXR0YWNoZWRFbGVtZW50c3x8W10pKSYmdC5sZW5ndGgmJmIuZWFjaCh0LGZ1bmN0aW9uKHQsaSl7KGk9YihpKSkuZGF0YShcImpCb3gtYXR0YWNoZWQtXCIrdGhpcy5pZCkmJihpLm9mZihpLmRhdGEoXCJqQm94LWF0dGFjaGVkLVwiK3RoaXMuaWQpK1wiLmpCb3gtYXR0YWNoLVwiK3RoaXMuaWQpLGkuZGF0YShcImpCb3gtYXR0YWNoZWQtXCIrdGhpcy5pZCxudWxsKSksdGhpcy5hdHRhY2hlZEVsZW1lbnRzPWIuZ3JlcCh0aGlzLmF0dGFjaGVkRWxlbWVudHMsZnVuY3Rpb24odCl7cmV0dXJuIHQhPWlbMF19KX0uYmluZCh0aGlzKSksdGhpc30saC5wcm90b3R5cGUuc2V0VGl0bGU9ZnVuY3Rpb24odCxpKXtpZihudWxsPT10fHxudWxsPT10KXJldHVybiB0aGlzO3RoaXMud3JhcHBlcnx8dGhpcy5fY3JlYXRlKCk7dmFyIG89dGhpcy53cmFwcGVyLm91dGVySGVpZ2h0KCkscz10aGlzLndyYXBwZXIub3V0ZXJXaWR0aCgpO3JldHVybiB0aGlzLnRpdGxlfHwodGhpcy50aXRsZUNvbnRhaW5lcj1iKCc8ZGl2IGNsYXNzPVwiakJveC10aXRsZVwiLz4nKSx0aGlzLnRpdGxlPWIoXCI8ZGl2Lz5cIikuYXBwZW5kVG8odGhpcy50aXRsZUNvbnRhaW5lciksXCJ0aXRsZVwiIT10aGlzLm9wdGlvbnMuY2xvc2VCdXR0b24mJighMCE9PXRoaXMub3B0aW9ucy5jbG9zZUJ1dHRvbnx8dGhpcy5vcHRpb25zLm92ZXJsYXkpfHwodGhpcy53cmFwcGVyLmFkZENsYXNzKFwiakJveC1jbG9zZUJ1dHRvbi10aXRsZVwiKSx0aGlzLmNsb3NlQnV0dG9uLmFwcGVuZFRvKHRoaXMudGl0bGVDb250YWluZXIpKSx0aGlzLnRpdGxlQ29udGFpbmVyLmluc2VydEJlZm9yZSh0aGlzLmNvbnRlbnQpLHRoaXMuX3NldFRpdGxlV2lkdGgoKSksdGhpcy53cmFwcGVyW3Q/XCJhZGRDbGFzc1wiOlwicmVtb3ZlQ2xhc3NcIl0oXCJqQm94LWhhc1RpdGxlXCIpLHRoaXMudGl0bGUuaHRtbCh0KSxzIT10aGlzLndyYXBwZXIub3V0ZXJXaWR0aCgpJiZ0aGlzLl9zZXRUaXRsZVdpZHRoKCksdGhpcy5vcHRpb25zLmRyYWdnYWJsZSYmdGhpcy5fZHJhZ2dhYmxlKCksaXx8IXRoaXMub3B0aW9ucy5yZXBvc2l0aW9uT25Db250ZW50fHxvPT10aGlzLndyYXBwZXIub3V0ZXJIZWlnaHQoKSYmcz09dGhpcy53cmFwcGVyLm91dGVyV2lkdGgoKXx8dGhpcy5wb3NpdGlvbigpLHRoaXN9LGgucHJvdG90eXBlLnNldENvbnRlbnQ9ZnVuY3Rpb24odCxpKXtpZihudWxsPT10fHxudWxsPT10KXJldHVybiB0aGlzO3RoaXMud3JhcHBlcnx8dGhpcy5fY3JlYXRlKCk7dmFyIG89dGhpcy53cmFwcGVyLm91dGVySGVpZ2h0KCkscz10aGlzLndyYXBwZXIub3V0ZXJXaWR0aCgpO3N3aXRjaCh0aGlzLmNvbnRlbnQuY2hpbGRyZW4oXCJbZGF0YS1qYm94LWNvbnRlbnQtYXBwZW5kZWRdXCIpLmFwcGVuZFRvKFwiYm9keVwiKS5jc3Moe2Rpc3BsYXk6XCJub25lXCJ9KSxiLnR5cGUodCkpe2Nhc2VcInN0cmluZ1wiOnRoaXMuY29udGVudC5odG1sKHQpO2JyZWFrO2Nhc2VcIm9iamVjdFwiOnQmJih0IGluc3RhbmNlb2YgYnx8dC5jb25zdHJ1Y3Rvci5wcm90b3R5cGUuanF1ZXJ5KT8odGhpcy5jb250ZW50Lmh0bWwoXCJcIiksdC5hdHRyKFwiZGF0YS1qYm94LWNvbnRlbnQtYXBwZW5kZWRcIiwxKS5hcHBlbmRUbyh0aGlzLmNvbnRlbnQpLmNzcyh7ZGlzcGxheTpcImJsb2NrXCJ9KSk6dGhpcy5jb250ZW50Lmh0bWwoSlNPTi5zdHJpbmdpZnkodCkpfXJldHVybiBzIT10aGlzLndyYXBwZXIub3V0ZXJXaWR0aCgpJiZ0aGlzLl9zZXRUaXRsZVdpZHRoKCksdGhpcy5vcHRpb25zLmRyYWdnYWJsZSYmdGhpcy5fZHJhZ2dhYmxlKCksaXx8IXRoaXMub3B0aW9ucy5yZXBvc2l0aW9uT25Db250ZW50fHxvPT10aGlzLndyYXBwZXIub3V0ZXJIZWlnaHQoKSYmcz09dGhpcy53cmFwcGVyLm91dGVyV2lkdGgoKXx8dGhpcy5wb3NpdGlvbigpLHRoaXN9LGgucHJvdG90eXBlLnNldERpbWVuc2lvbnM9ZnVuY3Rpb24odCxpLG8pe3RoaXMud3JhcHBlcnx8dGhpcy5fY3JlYXRlKCksbnVsbD09aSYmKGk9XCJhdXRvXCIpLHRoaXMuY29udGVudC5jc3ModCx0aGlzLl9nZXRJbnQoaSkpLFwid2lkdGhcIj09dCYmdGhpcy5fc2V0VGl0bGVXaWR0aCgpLHRoaXMub3B0aW9uc1t0XT1pLG51bGwhPW8mJiFvfHx0aGlzLnBvc2l0aW9uKCl9LGgucHJvdG90eXBlLnNldFdpZHRoPWZ1bmN0aW9uKHQsaSl7dGhpcy5zZXREaW1lbnNpb25zKFwid2lkdGhcIix0LGkpfSxoLnByb3RvdHlwZS5zZXRIZWlnaHQ9ZnVuY3Rpb24odCxpKXt0aGlzLnNldERpbWVuc2lvbnMoXCJoZWlnaHRcIix0LGkpfSxoLnByb3RvdHlwZS5wb3NpdGlvbj1mdW5jdGlvbihvKXtpZihvPW98fHt9LG89Yi5leHRlbmQoITAsdGhpcy5vcHRpb25zLG8pLHRoaXMudGFyZ2V0PW8udGFyZ2V0fHx0aGlzLnRhcmdldHx8Yih3aW5kb3cpLHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgYnx8XCJtb3VzZVwiPT10aGlzLnRhcmdldHx8KHRoaXMudGFyZ2V0PWIodGhpcy50YXJnZXQpKSwhdGhpcy50YXJnZXQubGVuZ3RoKXJldHVybiB0aGlzO3RoaXMuY29udGVudC5jc3Moe3dpZHRoOnRoaXMuX2dldEludChvLndpZHRoLFwid2lkdGhcIiksaGVpZ2h0OnRoaXMuX2dldEludChvLmhlaWdodCxcImhlaWdodFwiKSxtaW5XaWR0aDp0aGlzLl9nZXRJbnQoby5taW5XaWR0aCxcIndpZHRoXCIpLG1pbkhlaWdodDp0aGlzLl9nZXRJbnQoby5taW5IZWlnaHQsXCJoZWlnaHRcIiksbWF4V2lkdGg6dGhpcy5fZ2V0SW50KG8ubWF4V2lkdGgsXCJ3aWR0aFwiKSxtYXhIZWlnaHQ6dGhpcy5fZ2V0SW50KG8ubWF4SGVpZ2h0LFwiaGVpZ2h0XCIpfSksdGhpcy5fc2V0VGl0bGVXaWR0aCgpO3ZhciBzPXRoaXMuX2V4cG9zZURpbWVuc2lvbnMoKTtcIm1vdXNlXCI9PXRoaXMudGFyZ2V0fHx0aGlzLnRhcmdldC5kYXRhKFwiakJveC1cIit0aGlzLmlkK1wiLWZpeGVkXCIpfHx0aGlzLnRhcmdldC5kYXRhKFwiakJveC1cIit0aGlzLmlkK1wiLWZpeGVkXCIsdGhpcy50YXJnZXRbMF0hPWIod2luZG93KVswXSYmKFwiZml4ZWRcIj09dGhpcy50YXJnZXQuY3NzKFwicG9zaXRpb25cIil8fDA8dGhpcy50YXJnZXQucGFyZW50cygpLmZpbHRlcihmdW5jdGlvbigpe3JldHVyblwiZml4ZWRcIj09Yih0aGlzKS5jc3MoXCJwb3NpdGlvblwiKX0pLmxlbmd0aCk/XCJmaXhlZFwiOlwic3RhdGljXCIpO3ZhciB0PXt4OmIod2luZG93KS5vdXRlcldpZHRoKCkseTpiKHdpbmRvdykub3V0ZXJIZWlnaHQoKSx0b3A6by5maXhlZCYmdGhpcy50YXJnZXQuZGF0YShcImpCb3gtXCIrdGhpcy5pZCtcIi1maXhlZFwiKT8wOmIod2luZG93KS5zY3JvbGxUb3AoKSxsZWZ0Om8uZml4ZWQmJnRoaXMudGFyZ2V0LmRhdGEoXCJqQm94LVwiK3RoaXMuaWQrXCItZml4ZWRcIik/MDpiKHdpbmRvdykuc2Nyb2xsTGVmdCgpfTt0LmJvdHRvbT10LnRvcCt0LnksdC5yaWdodD10LmxlZnQrdC54O3RyeXt2YXIgaT10aGlzLnRhcmdldC5vZmZzZXQoKX1jYXRjaCh0KXtpPXt0b3A6MCxsZWZ0OjB9fVwibW91c2VcIiE9dGhpcy50YXJnZXQmJlwiZml4ZWRcIj09dGhpcy50YXJnZXQuZGF0YShcImpCb3gtXCIrdGhpcy5pZCtcIi1maXhlZFwiKSYmby5maXhlZCYmKGkudG9wPWkudG9wLWIod2luZG93KS5zY3JvbGxUb3AoKSxpLmxlZnQ9aS5sZWZ0LWIod2luZG93KS5zY3JvbGxMZWZ0KCkpO3ZhciBlPXt4OlwibW91c2VcIj09dGhpcy50YXJnZXQ/MTI6dGhpcy50YXJnZXQub3V0ZXJXaWR0aCgpLHk6XCJtb3VzZVwiPT10aGlzLnRhcmdldD8yMDp0aGlzLnRhcmdldC5vdXRlckhlaWdodCgpLHRvcDpcIm1vdXNlXCI9PXRoaXMudGFyZ2V0JiZvLm1vdXNlVGFyZ2V0P28ubW91c2VUYXJnZXQudG9wOmk/aS50b3A6MCxsZWZ0OlwibW91c2VcIj09dGhpcy50YXJnZXQmJm8ubW91c2VUYXJnZXQ/by5tb3VzZVRhcmdldC5sZWZ0Omk/aS5sZWZ0OjB9LG49by5vdXRzaWRlJiYhKFwiY2VudGVyXCI9PW8ucG9zaXRpb24ueCYmXCJjZW50ZXJcIj09by5wb3NpdGlvbi55KSxhPXt4OnQueC1vLmFkanVzdERpc3RhbmNlLmxlZnQtby5hZGp1c3REaXN0YW5jZS5yaWdodCx5OnQueS1vLmFkanVzdERpc3RhbmNlLnRvcC1vLmFkanVzdERpc3RhbmNlLmJvdHRvbSxsZWZ0Om4/ZS5sZWZ0LWIod2luZG93KS5zY3JvbGxMZWZ0KCktby5hZGp1c3REaXN0YW5jZS5sZWZ0OjAscmlnaHQ6bj90LngtZS5sZWZ0K2Iod2luZG93KS5zY3JvbGxMZWZ0KCktZS54LW8uYWRqdXN0RGlzdGFuY2UucmlnaHQ6MCx0b3A6bj9lLnRvcC1iKHdpbmRvdykuc2Nyb2xsVG9wKCktdGhpcy5vcHRpb25zLmFkanVzdERpc3RhbmNlLnRvcDowLGJvdHRvbTpuP3QueS1lLnRvcCtiKHdpbmRvdykuc2Nyb2xsVG9wKCktZS55LW8uYWRqdXN0RGlzdGFuY2UuYm90dG9tOjB9LGg9e3g6XCJ4XCIhPW8ub3V0c2lkZSYmXCJ4eVwiIT1vLm91dHNpZGV8fFwibnVtYmVyXCI9PWIudHlwZShvLnBvc2l0aW9uLngpP251bGw6by5wb3NpdGlvbi54LHk6XCJ5XCIhPW8ub3V0c2lkZSYmXCJ4eVwiIT1vLm91dHNpZGV8fFwibnVtYmVyXCI9PWIudHlwZShvLnBvc2l0aW9uLnkpP251bGw6by5wb3NpdGlvbi55fSxyPXt4OiExLHk6ITF9O2gueCYmcy54PmFbaC54XSYmYVt0aGlzLl9nZXRPcHAoaC54KV0+YVtoLnhdJiYoaC54PXRoaXMuX2dldE9wcChoLngpKSYmKHIueD0hMCksaC55JiZzLnk+YVtoLnldJiZhW3RoaXMuX2dldE9wcChoLnkpXT5hW2gueV0mJihoLnk9dGhpcy5fZ2V0T3BwKGgueSkpJiYoci55PSEwKSwoby5yZXNwb25zaXZlV2lkdGh8fG8ucmVzcG9uc2l2ZUhlaWdodCkmJihmPWZ1bmN0aW9uKCl7dmFyIHQ7by5yZXNwb25zaXZlV2lkdGgmJnMueD5hW2gueHx8XCJ4XCJdJiYodD1hW2gueHx8XCJ4XCJdLSh0aGlzLnBvaW50ZXImJm4mJlwieFwiPT1vLm91dHNpZGU/dGhpcy5wb2ludGVyLmRpbWVuc2lvbnMueDowKS1wYXJzZUludCh0aGlzLmNvbnRhaW5lci5jc3MoXCJib3JkZXItbGVmdC13aWR0aFwiKSktcGFyc2VJbnQodGhpcy5jb250YWluZXIuY3NzKFwiYm9yZGVyLXJpZ2h0LXdpZHRoXCIpKSx0aGlzLmNvbnRlbnQuY3NzKHt3aWR0aDp0PnRoaXMub3B0aW9ucy5yZXNwb25zaXZlTWluV2lkdGg/dDpudWxsLG1pbldpZHRoOnQ8cGFyc2VJbnQodGhpcy5jb250ZW50LmNzcyhcIm1pbldpZHRoXCIpKT8wOm51bGx9KSx0aGlzLl9zZXRUaXRsZVdpZHRoKCkpLHM9dGhpcy5fZXhwb3NlRGltZW5zaW9ucygpfS5iaW5kKHRoaXMpLG8ucmVzcG9uc2l2ZVdpZHRoJiZmKCksby5yZXNwb25zaXZlV2lkdGgmJiFyLnkmJmgueSYmcy55PmFbaC55XSYmYVt0aGlzLl9nZXRPcHAoaC55KV0+YVtoLnldJiYoaC55PXRoaXMuX2dldE9wcChoLnkpKSYmKHIueT0hMCkseD1mdW5jdGlvbigpe3ZhciB0O28ucmVzcG9uc2l2ZUhlaWdodCYmcy55PmFbaC55fHxcInlcIl0mJih0PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGl0bGVDb250YWluZXJ8fHRoaXMuZm9vdGVyPyhcIm5vbmVcIj09dGhpcy53cmFwcGVyLmNzcyhcImRpc3BsYXlcIik/KHRoaXMud3JhcHBlci5jc3MoXCJkaXNwbGF5XCIsXCJibG9ja1wiKSx0PSh0aGlzLnRpdGxlQ29udGFpbmVyP3RoaXMudGl0bGVDb250YWluZXIub3V0ZXJIZWlnaHQoKTowKSsodGhpcy5mb290ZXI/dGhpcy5mb290ZXIub3V0ZXJIZWlnaHQoKTowKSx0aGlzLndyYXBwZXIuY3NzKFwiZGlzcGxheVwiLFwibm9uZVwiKSk6dD0odGhpcy50aXRsZUNvbnRhaW5lcj90aGlzLnRpdGxlQ29udGFpbmVyLm91dGVySGVpZ2h0KCk6MCkrKHRoaXMuZm9vdGVyP3RoaXMuZm9vdGVyLm91dGVySGVpZ2h0KCk6MCksdHx8MCk6MDt2YXIgdH0uYmluZCh0aGlzKSx0PWFbaC55fHxcInlcIl0tKHRoaXMucG9pbnRlciYmbiYmXCJ5XCI9PW8ub3V0c2lkZT90aGlzLnBvaW50ZXIuZGltZW5zaW9ucy55OjApLXQoKS1wYXJzZUludCh0aGlzLmNvbnRhaW5lci5jc3MoXCJib3JkZXItdG9wLXdpZHRoXCIpKS1wYXJzZUludCh0aGlzLmNvbnRhaW5lci5jc3MoXCJib3JkZXItYm90dG9tLXdpZHRoXCIpKSx0aGlzLmNvbnRlbnQuY3NzKHtoZWlnaHQ6dD50aGlzLm9wdGlvbnMucmVzcG9uc2l2ZU1pbkhlaWdodD90Om51bGx9KSx0aGlzLl9zZXRUaXRsZVdpZHRoKCkpLHM9dGhpcy5fZXhwb3NlRGltZW5zaW9ucygpfS5iaW5kKHRoaXMpLG8ucmVzcG9uc2l2ZUhlaWdodCYmeCgpLG8ucmVzcG9uc2l2ZUhlaWdodCYmIXIueCYmaC54JiZzLng+YVtoLnhdJiZhW3RoaXMuX2dldE9wcChoLngpXT5hW2gueF0mJihoLng9dGhpcy5fZ2V0T3BwKGgueCkpJiYoci54PSEwKSxvLmFkanVzdFBvc2l0aW9uJiZcIm1vdmVcIiE9by5hZGp1c3RQb3NpdGlvbiYmKHIueCYmZigpLHIueSYmeCgpKSk7dmFyIHA9e30sbD1mdW5jdGlvbih0KXtpZihcIm51bWJlclwiIT1iLnR5cGUoby5wb3NpdGlvblt0XSkpe3ZhciBpPW8uYXR0cmlidXRlc1t0XT1cInhcIj09dD9cImxlZnRcIjpcInRvcFwiO2lmKHBbaV09ZVtpXSxcImNlbnRlclwiPT1vLnBvc2l0aW9uW3RdKXJldHVybiBwW2ldKz1NYXRoLmNlaWwoKGVbdF0tc1t0XSkvMiksdm9pZChcIm1vdXNlXCIhPXRoaXMudGFyZ2V0JiZ0aGlzLnRhcmdldFswXSYmdGhpcy50YXJnZXRbMF09PWIod2luZG93KVswXSYmKHBbaV0rPS41KihvLmFkanVzdERpc3RhbmNlW2ldLW8uYWRqdXN0RGlzdGFuY2VbdGhpcy5fZ2V0T3BwKGkpXSkpKTtpIT1vLnBvc2l0aW9uW3RdJiYocFtpXSs9ZVt0XS1zW3RdKSxvLm91dHNpZGUhPXQmJlwieHlcIiE9by5vdXRzaWRlfHwocFtpXSs9c1t0XSooaSE9by5wb3NpdGlvblt0XT8xOi0xKSl9ZWxzZSBwW28uYXR0cmlidXRlc1t0XV09by5wb3NpdGlvblt0XX0uYmluZCh0aGlzKTtpZihsKFwieFwiKSxsKFwieVwiKSx0aGlzLnBvaW50ZXImJlwidGFyZ2V0XCI9PW8ucG9pbnRUbyYmXCJudW1iZXJcIiE9Yi50eXBlKG8ucG9zaXRpb24ueCkmJlwibnVtYmVyXCIhPWIudHlwZShvLnBvc2l0aW9uLnkpJiYoeT0wLFwiY2VudGVyXCI9PT10aGlzLnBvaW50ZXIuYWxpZ24/XCJjZW50ZXJcIiE9by5wb3NpdGlvblt0aGlzLl9nZXRPcHAoby5vdXRzaWRlKV0mJih5Kz1zW3RoaXMuX2dldE9wcChvLm91dHNpZGUpXS8yKTpcImNlbnRlclwiPT09by5wb3NpdGlvblt0aGlzLl9nZXRPcHAoby5vdXRzaWRlKV0/eSs9KHNbdGhpcy5fZ2V0T3BwKG8ub3V0c2lkZSldLzItdGhpcy5wb2ludGVyLmRpbWVuc2lvbnNbdGhpcy5fZ2V0T3BwKG8ub3V0c2lkZSldLzIpKih0aGlzLnBvaW50ZXIuYWxpZ249PXRoaXMuX2dldFRMKHRoaXMucG9pbnRlci5hbGlnbik/MTotMSk6eSs9dGhpcy5wb2ludGVyLmFsaWduIT1vLnBvc2l0aW9uW3RoaXMuX2dldE9wcChvLm91dHNpZGUpXT90aGlzLmRpbWVuc2lvbnNbdGhpcy5fZ2V0T3BwKG8ub3V0c2lkZSldKigtMSE9PWIuaW5BcnJheSh0aGlzLnBvaW50ZXIuYWxpZ24sW1widG9wXCIsXCJsZWZ0XCJdKT8xOi0xKSt0aGlzLnBvaW50ZXIuZGltZW5zaW9uc1t0aGlzLl9nZXRPcHAoby5vdXRzaWRlKV0vMiooLTEhPT1iLmluQXJyYXkodGhpcy5wb2ludGVyLmFsaWduLFtcInRvcFwiLFwibGVmdFwiXSk/LTE6MSk6dGhpcy5wb2ludGVyLmRpbWVuc2lvbnNbdGhpcy5fZ2V0T3BwKG8ub3V0c2lkZSldLzIqKC0xIT09Yi5pbkFycmF5KHRoaXMucG9pbnRlci5hbGlnbixbXCJ0b3BcIixcImxlZnRcIl0pPzE6LTEpLHkqPW8ucG9zaXRpb25bdGhpcy5fZ2V0T3BwKG8ub3V0c2lkZSldPT10aGlzLnBvaW50ZXIuYWxpZ25BdHRyaWJ1dGU/LTE6MSx5Kz10aGlzLnBvaW50ZXIub2Zmc2V0Kih0aGlzLnBvaW50ZXIuYWxpZ249PXRoaXMuX2dldE9wcCh0aGlzLl9nZXRUTCh0aGlzLnBvaW50ZXIuYWxpZ24pKT8xOi0xKSxwW3RoaXMuX2dldFRMKHRoaXMuX2dldE9wcCh0aGlzLnBvaW50ZXIueHkpKV0rPXkpLHBbby5hdHRyaWJ1dGVzLnhdKz1vLm9mZnNldC54LHBbby5hdHRyaWJ1dGVzLnldKz1vLm9mZnNldC55LHRoaXMud3JhcHBlci5jc3MocCksby5hZGp1c3RQb3NpdGlvbil7dGhpcy5wb3NpdGlvbkFkanVzdGVkJiYodGhpcy5wb2ludGVyJiZ0aGlzLndyYXBwZXIuY3NzKFwicGFkZGluZ1wiLDApLmNzcyhcInBhZGRpbmctXCIrdGhpcy5fZ2V0T3BwKHRoaXMub3V0c2lkZSksdGhpcy5wb2ludGVyLmRpbWVuc2lvbnNbdGhpcy5fZ2V0WFkodGhpcy5vdXRzaWRlKV0pLnJlbW92ZUNsYXNzKFwiakJveC1wb2ludGVyUG9zaXRpb24tXCIrdGhpcy5fZ2V0T3BwKHRoaXMucG9pbnRlci5wb3NpdGlvbikpLmFkZENsYXNzKFwiakJveC1wb2ludGVyUG9zaXRpb24tXCIrdGhpcy5wb2ludGVyLnBvc2l0aW9uKSx0aGlzLnBvaW50ZXImJnRoaXMucG9pbnRlci5lbGVtZW50LmF0dHIoXCJjbGFzc1wiLFwiakJveC1wb2ludGVyIGpCb3gtcG9pbnRlci1cIit0aGlzLl9nZXRPcHAodGhpcy5vdXRzaWRlKSkuY3NzKHRoaXMucG9pbnRlci5tYXJnaW4pLHRoaXMucG9zaXRpb25BZGp1c3RlZD0hMSx0aGlzLmZsaXBwZWQ9ITEpO3ZhciBkPXQudG9wPnAudG9wLShvLmFkanVzdERpc3RhbmNlLnRvcHx8MCksYz10LnJpZ2h0PHAubGVmdCtzLngrKG8uYWRqdXN0RGlzdGFuY2UucmlnaHR8fDApLHU9dC5ib3R0b208cC50b3Arcy55KyhvLmFkanVzdERpc3RhbmNlLmJvdHRvbXx8MCksZz10LmxlZnQ+cC5sZWZ0LShvLmFkanVzdERpc3RhbmNlLmxlZnR8fDApLG09Zz9cImxlZnRcIjpjP1wicmlnaHRcIjpudWxsLGY9ZD9cInRvcFwiOnU/XCJib3R0b21cIjpudWxsO2lmKG18fGYpe2lmKChcIk1vZGFsXCI9PXRoaXMudHlwZXx8XCJDb25maXJtXCI9PXRoaXMudHlwZSkmJlwibnVtYmVyXCI9PWIudHlwZSh0aGlzLm9wdGlvbnMucG9zaXRpb24ueCkmJlwibnVtYmVyXCI9PWIudHlwZSh0aGlzLm9wdGlvbnMucG9zaXRpb24ueSkpe3ZhciB4PTAseT0wO3JldHVybiB0aGlzLm9wdGlvbnMuaG9sZFBvc2l0aW9uJiYoZz94PXQubGVmdC0ocC5sZWZ0LShvLmFkanVzdERpc3RhbmNlLmxlZnR8fDApKTpjJiYoeD10LnJpZ2h0LShwLmxlZnQrcy54KyhvLmFkanVzdERpc3RhbmNlLnJpZ2h0fHwwKSkpLGQ/eT10LnRvcC0ocC50b3AtKG8uYWRqdXN0RGlzdGFuY2UudG9wfHwwKSk6dSYmKHk9dC5ib3R0b20tKHAudG9wK3MueSsoby5hZGp1c3REaXN0YW5jZS5ib3R0b218fDApKSksdGhpcy5vcHRpb25zLnBvc2l0aW9uLng9TWF0aC5tYXgodC50b3AsdGhpcy5vcHRpb25zLnBvc2l0aW9uLngreCksdGhpcy5vcHRpb25zLnBvc2l0aW9uLnk9TWF0aC5tYXgodC5sZWZ0LHRoaXMub3B0aW9ucy5wb3NpdGlvbi55K3kpLGwoXCJ4XCIpLGwoXCJ5XCIpLHRoaXMud3JhcHBlci5jc3MocCkpLHRoaXMuX2ZpcmVFdmVudChcIm9uUG9zaXRpb25cIiksdGhpc30hMCE9PW8uYWRqdXN0UG9zaXRpb24mJlwiZmxpcFwiIT09by5hZGp1c3RQb3NpdGlvbnx8KGo9ZnVuY3Rpb24odCl7dGhpcy53cmFwcGVyLmNzcyh0aGlzLl9nZXRUTCh0KSxwW3RoaXMuX2dldFRMKHQpXSsoc1t0aGlzLl9nZXRYWSh0KV0rby5vZmZzZXRbdGhpcy5fZ2V0WFkodCldKihcInRvcFwiPT10fHxcImxlZnRcIj09dD8tMjoyKStlW3RoaXMuX2dldFhZKHQpXSkqKFwidG9wXCI9PXR8fFwibGVmdFwiPT10PzE6LTEpKSx0aGlzLnBvaW50ZXImJnRoaXMud3JhcHBlci5yZW1vdmVDbGFzcyhcImpCb3gtcG9pbnRlclBvc2l0aW9uLVwiK3RoaXMucG9pbnRlci5wb3NpdGlvbikuYWRkQ2xhc3MoXCJqQm94LXBvaW50ZXJQb3NpdGlvbi1cIit0aGlzLl9nZXRPcHAodGhpcy5wb2ludGVyLnBvc2l0aW9uKSkuY3NzKFwicGFkZGluZ1wiLDApLmNzcyhcInBhZGRpbmctXCIrdCx0aGlzLnBvaW50ZXIuZGltZW5zaW9uc1t0aGlzLl9nZXRYWSh0KV0pLHRoaXMucG9pbnRlciYmdGhpcy5wb2ludGVyLmVsZW1lbnQuYXR0cihcImNsYXNzXCIsXCJqQm94LXBvaW50ZXIgakJveC1wb2ludGVyLVwiK3QpLHRoaXMucG9zaXRpb25BZGp1c3RlZD0hMCx0aGlzLmZsaXBwZWQ9ITB9LmJpbmQodGhpcyksci54JiZqKHRoaXMub3B0aW9ucy5wb3NpdGlvbi54KSxyLnkmJmoodGhpcy5vcHRpb25zLnBvc2l0aW9uLnkpKTt2YXIgaj1cInhcIj09dGhpcy5fZ2V0WFkodGhpcy5vdXRzaWRlKT9mOm07dGhpcy5wb2ludGVyJiZcInRhcmdldFwiPT1vLnBvaW50VG8mJlwiZmxpcFwiIT1vLmFkanVzdFBvc2l0aW9uJiZ0aGlzLl9nZXRYWShqKT09dGhpcy5fZ2V0T3BwKHRoaXMuX2dldFhZKHRoaXMub3V0c2lkZSkpJiYoZj1cImNlbnRlclwiPT10aGlzLnBvaW50ZXIuYWxpZ24/c1t0aGlzLl9nZXRYWShqKV0vMi10aGlzLnBvaW50ZXIuZGltZW5zaW9uc1t0aGlzLl9nZXRPcHAodGhpcy5wb2ludGVyLnh5KV0vMi1wYXJzZUludCh0aGlzLnBvaW50ZXIuZWxlbWVudC5jc3MoXCJtYXJnaW4tXCIrdGhpcy5wb2ludGVyLmFsaWduQXR0cmlidXRlKSkqKGohPXRoaXMuX2dldFRMKGopPy0xOjEpOmo9PXRoaXMucG9pbnRlci5hbGlnbkF0dHJpYnV0ZT9wYXJzZUludCh0aGlzLnBvaW50ZXIuZWxlbWVudC5jc3MoXCJtYXJnaW4tXCIrdGhpcy5wb2ludGVyLmFsaWduQXR0cmlidXRlKSk6c1t0aGlzLl9nZXRYWShqKV0tcGFyc2VJbnQodGhpcy5wb2ludGVyLmVsZW1lbnQuY3NzKFwibWFyZ2luLVwiK3RoaXMucG9pbnRlci5hbGlnbkF0dHJpYnV0ZSkpLXRoaXMucG9pbnRlci5kaW1lbnNpb25zW3RoaXMuX2dldFhZKGopXSxtPWo9PXRoaXMuX2dldFRMKGopP3RbdGhpcy5fZ2V0VEwoaildLXBbdGhpcy5fZ2V0VEwoaildK28uYWRqdXN0RGlzdGFuY2Vbal06LTEqKHRbdGhpcy5fZ2V0T3BwKHRoaXMuX2dldFRMKGopKV0tcFt0aGlzLl9nZXRUTChqKV0tby5hZGp1c3REaXN0YW5jZVtqXS1zW3RoaXMuX2dldFhZKGopXSksaj09dGhpcy5fZ2V0T3BwKHRoaXMuX2dldFRMKGopKSYmcFt0aGlzLl9nZXRUTChqKV0tbTx0W3RoaXMuX2dldFRMKGopXStvLmFkanVzdERpc3RhbmNlW3RoaXMuX2dldFRMKGopXSYmKG0tPXRbdGhpcy5fZ2V0VEwoaildK28uYWRqdXN0RGlzdGFuY2VbdGhpcy5fZ2V0VEwoaildLShwW3RoaXMuX2dldFRMKGopXS1tKSksKG09TWF0aC5taW4obSxmKSk8PWYmJjA8bSYmKHRoaXMucG9pbnRlci5lbGVtZW50LmNzcyhcIm1hcmdpbi1cIit0aGlzLnBvaW50ZXIuYWxpZ25BdHRyaWJ1dGUscGFyc2VJbnQodGhpcy5wb2ludGVyLmVsZW1lbnQuY3NzKFwibWFyZ2luLVwiK3RoaXMucG9pbnRlci5hbGlnbkF0dHJpYnV0ZSkpLW0qKGohPXRoaXMucG9pbnRlci5hbGlnbkF0dHJpYnV0ZT8tMToxKSksdGhpcy53cmFwcGVyLmNzcyh0aGlzLl9nZXRUTChqKSxwW3RoaXMuX2dldFRMKGopXSttKihqIT10aGlzLl9nZXRUTChqKT8tMToxKSksdGhpcy5wb3NpdGlvbkFkanVzdGVkPSEwKSl9fXJldHVybiB0aGlzLl9maXJlRXZlbnQoXCJvblBvc2l0aW9uXCIpLHRoaXN9LChoLnByb3RvdHlwZS51bnNjcm9sbD1mdW5jdGlvbih0KXtpZih0aGlzLnNldD1mdW5jdGlvbih0LGkpe3dpbmRvdy51bnNjcm9sbFN0b3JlfHwod2luZG93LnVuc2Nyb2xsU3RvcmU9e30pLHdpbmRvdy51bnNjcm9sbFN0b3JlW3RdPWl9LHRoaXMuZ2V0PWZ1bmN0aW9uKHQpe3JldHVybiB3aW5kb3cudW5zY3JvbGxTdG9yZT93aW5kb3cudW5zY3JvbGxTdG9yZVt0XTpudWxsfSx0aGlzLmdldFNjcm9sbGJhcldpZHRoPWZ1bmN0aW9uKCl7aWYodGhpcy5nZXQoXCJzY3JvbGxiYXJXaWR0aFwiKSlyZXR1cm4gdGhpcy5nZXQoXCJzY3JvbGxiYXJXaWR0aFwiKStcInB4XCI7dmFyIHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTt0LnN0eWxlLndpZHRoPVwiMTAwcHhcIix0LnN0eWxlLmhlaWdodD1cIjEwMHB4XCIsdC5zdHlsZS5vdmVyZmxvdz1cInNjcm9sbFwiLHQuc3R5bGUucG9zaXRpb249XCJhYnNvbHV0ZVwiLHQuc3R5bGUudG9wPVwiLTEwMDAwXCIsZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0KTt2YXIgaT10Lm9mZnNldFdpZHRoLXQuY2xpZW50V2lkdGg7cmV0dXJuIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodCksdGhpcy5zZXQoXCJzY3JvbGxiYXJXaWR0aFwiLGkpLGkrXCJweFwifSx0aGlzLmdldEVsZW1lbnRzVG9BZGp1c3Q9ZnVuY3Rpb24obyl7KG89XCJzdHJpbmdcIj09dHlwZW9mKG89b3x8W10pP1tbbyxcInBhZGRpbmctcmlnaHRcIl1dOm8pLmZvckVhY2goZnVuY3Rpb24odCxpKXtcInN0cmluZ1wiPT10eXBlb2YgdCYmKG9baV09W3QsXCJwYWRkaW5nLXJpZ2h0XCJdKX0pO2Zvcih2YXIgdD0hMSxpPTA7aTxvLmxlbmd0aDtpKyspLTEhPT1vW2ldWzBdLmluZGV4T2YoXCJib2R5XCIpJiYodD0hMCk7cmV0dXJuITE9PT10JiZvLnB1c2goW1wiYm9keVwiLFwicGFkZGluZy1yaWdodFwiXSksb30sdGhpcy5wYWdlSGFzU2Nyb2xsYmFyPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZ2V0U2Nyb2xsYmFyV2lkdGgoKSYmZG9jdW1lbnQuYm9keS5vZmZzZXRIZWlnaHQ+d2luZG93LmlubmVySGVpZ2h0fSx0aGlzLnBhZ2VIYXNTY3JvbGxiYXIoKSl7dD10aGlzLmdldEVsZW1lbnRzVG9BZGp1c3QodCk7Zm9yKHZhciBpPTA7aTx0Lmxlbmd0aDtpKyspZm9yKHZhciBvPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwodFtpXVswXSkscz0wO3M8by5sZW5ndGg7cysrKXtpZihvW3NdLmdldEF0dHJpYnV0ZShcImRhdGEtdW5zY3JvbGxcIikpcmV0dXJuO3ZhciBlPXRbaV1bMV0sbj13aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShvW3NdKS5nZXRQcm9wZXJ0eVZhbHVlKGUpO29bc10uc2V0QXR0cmlidXRlKFwiZGF0YS11bnNjcm9sbFwiLGUpLG49bnx8XCIwcHhcIjt2YXIgYT1cInBhZGRpbmctcmlnaHRcIj09ZXx8XCJyaWdodFwiPT1lP1wiK1wiOlwiLVwiO29bc10uc3R5bGVbZV09XCJjYWxjKFwiK24rXCIgXCIrYStcIiBcIit0aGlzLmdldFNjcm9sbGJhcldpZHRoKCkrXCIpXCJ9fXZhciBoLHI7ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJ1bnNjcm9sbC1jbGFzcy1uYW1lXCIpfHwoaD1kb2N1bWVudC5oZWFkfHxkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0sKHI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpKS50eXBlPVwidGV4dC9jc3NcIixyLnNldEF0dHJpYnV0ZShcImlkXCIsXCJ1bnNjcm9sbC1jbGFzcy1uYW1lXCIpLHIuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoXCIudW5zY3JvbGxhYmxlIHsgb3ZlcmZsb3c6IGhpZGRlbiAhaW1wb3J0YW50OyB9XCIpKSxoLmFwcGVuZENoaWxkKHIpKSxkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoXCJ1bnNjcm9sbGFibGVcIil9KS5yZXNldD1mdW5jdGlvbigpe2Zvcih2YXIgdD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtdW5zY3JvbGxdXCIpLGk9MDtpPHQubGVuZ3RoO2krKyl7dmFyIG89dFtpXS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXVuc2Nyb2xsXCIpO3RbaV0uc3R5bGVbb109bnVsbCx0W2ldLnJlbW92ZUF0dHJpYnV0ZShcImRhdGEtdW5zY3JvbGxcIil9ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKFwidW5zY3JvbGxhYmxlXCIpfSxoLnByb3RvdHlwZS5vcGVuPWZ1bmN0aW9uKHQpe2lmKHQ9dHx8e30sdGhpcy5pc0Rlc3Ryb3llZClyZXR1cm4gdGhpcztpZih0aGlzLndyYXBwZXJ8fHRoaXMuX2NyZWF0ZSgpLHRoaXMuX3N0eWxlc3x8KHRoaXMuX3N0eWxlcz1iKFwiPHN0eWxlLz5cIikuYXBwZW5kKHRoaXMuX2FuaW1hdGlvbkNTUykuYXBwZW5kVG8oYihcImhlYWRcIikpKSx0aGlzLnRpbWVyJiZjbGVhclRpbWVvdXQodGhpcy50aW1lciksdGhpcy5fYmxvY2tCb2R5Q2xpY2soKSx0aGlzLmlzRGlzYWJsZWQpcmV0dXJuIHRoaXM7dGhpcy5vcHRpb25zLmNsb3NlT25Fc2MmJmIoZG9jdW1lbnQpLm9uKFwia2V5dXAuakJveC1cIit0aGlzLmlkLGZ1bmN0aW9uKHQpezI3PT10LmtleUNvZGUmJnRoaXMuY2xvc2Uoe2lnbm9yZURlbGF5OiEwfSl9LmJpbmQodGhpcykpLCEwIT09dGhpcy5vcHRpb25zLmNsb3NlT25DbGljayYmXCJib2R5XCIhPT10aGlzLm9wdGlvbnMuY2xvc2VPbkNsaWNrfHwoYihcImJvZHlcIikub24oXCJjbGljay5qQm94LVwiK3RoaXMuaWQrXCIgdGFwLmpCb3gtXCIrdGhpcy5pZCxmdW5jdGlvbih0KXt0aGlzLmJsb2NrQm9keUNsaWNrfHxcImJvZHlcIj09dGhpcy5vcHRpb25zLmNsb3NlT25DbGljayYmKHQudGFyZ2V0PT10aGlzLndyYXBwZXJbMF18fHRoaXMud3JhcHBlci5oYXModC50YXJnZXQpLmxlbmd0aCl8fHRoaXMuY2xvc2Uoe2lnbm9yZURlbGF5OiEwfSl9LmJpbmQodGhpcykpLHRoaXMuaXNUb3VjaERldmljZSYmYihcImJvZHkgPiAqXCIpLm9uKFwiY2xpY2suakJveC1cIit0aGlzLmlkK1wiIHRhcC5qQm94LVwiK3RoaXMuaWQsZnVuY3Rpb24oKXtyZXR1cm4hMH0pKTt2YXIgaT1mdW5jdGlvbigpeyEwPT09dGhpcy5hZGp1c3RaSW5kZXhPbk9wZW4mJihoLnpJbmRleE1heD1NYXRoLm1heChwYXJzZUludCh0aGlzLndyYXBwZXIuY3NzKFwiekluZGV4XCIpLDEwKSx0aGlzLm9wdGlvbnMuekluZGV4LGguekluZGV4TWF4fHwwLGguekluZGV4TWF4RHJhZ292ZXJ8fDApKzIsdGhpcy53cmFwcGVyLmNzcyhcInpJbmRleFwiLGguekluZGV4TWF4KSx0aGlzLm9wdGlvbnMuekluZGV4PWguekluZGV4TWF4KSx0aGlzLnNvdXJjZSYmdGhpcy5vcHRpb25zLmdldFRpdGxlJiZ0aGlzLnNvdXJjZS5hdHRyKHRoaXMub3B0aW9ucy5nZXRUaXRsZSkmJnRoaXMuc2V0VGl0bGUodGhpcy5zb3VyY2UuYXR0cih0aGlzLm9wdGlvbnMuZ2V0VGl0bGUpLCEwKSx0aGlzLnNvdXJjZSYmdGhpcy5vcHRpb25zLmdldENvbnRlbnQmJih0aGlzLnNvdXJjZS5kYXRhKFwiakJveC1nZXRDb250ZW50XCIpP3RoaXMuc2V0Q29udGVudCh0aGlzLnNvdXJjZS5kYXRhKFwiakJveC1nZXRDb250ZW50XCIpLCEwKTp0aGlzLnNvdXJjZS5hdHRyKHRoaXMub3B0aW9ucy5nZXRDb250ZW50KT90aGlzLnNldENvbnRlbnQodGhpcy5zb3VyY2UuYXR0cih0aGlzLm9wdGlvbnMuZ2V0Q29udGVudCksITApOlwiaHRtbFwiPT10aGlzLm9wdGlvbnMuZ2V0Q29udGVudCYmdGhpcy5zZXRDb250ZW50KHRoaXMuc291cmNlLmh0bWwoKSwhMCkpLHRoaXMuX2ZpcmVFdmVudChcIm9uT3BlblwiKSwodGhpcy5vcHRpb25zLmFqYXgmJih0aGlzLm9wdGlvbnMuYWpheC51cmx8fHRoaXMuc291cmNlJiZ0aGlzLnNvdXJjZS5hdHRyKHRoaXMub3B0aW9ucy5hamF4LmdldFVSTCkpJiYoIXRoaXMuYWpheExvYWRlZHx8dGhpcy5vcHRpb25zLmFqYXgucmVsb2FkKXx8dC5hamF4JiYodC5hamF4LnVybHx8dC5hamF4LmRhdGEpKSYmKFwic3RyaWN0XCI9PXRoaXMub3B0aW9ucy5hamF4LnJlbG9hZHx8IXRoaXMuc291cmNlfHwhdGhpcy5zb3VyY2UuZGF0YShcImpCb3gtYWpheC1kYXRhXCIpfHx0LmFqYXgmJih0LmFqYXgudXJsfHx0LmFqYXguZGF0YSk/dGhpcy5hamF4KHQuYWpheHx8bnVsbCwhMCk6dGhpcy5zZXRDb250ZW50KHRoaXMuc291cmNlLmRhdGEoXCJqQm94LWFqYXgtZGF0YVwiKSkpLHRoaXMucG9zaXRpb25lZE9uT3BlbiYmIXRoaXMub3B0aW9ucy5yZXBvc2l0aW9uT25PcGVufHwhdGhpcy5wb3NpdGlvbih0KXx8KHRoaXMucG9zaXRpb25lZE9uT3Blbj0hMCksdGhpcy5pc0Nsb3NpbmcmJnRoaXMuX2Fib3J0QW5pbWF0aW9uKCksdGhpcy5pc09wZW58fCh0aGlzLmlzT3Blbj0hMCx0aGlzLm9wdGlvbnMuYXV0b0Nsb3NlJiYodGhpcy5vcHRpb25zLmRlbGF5Q2xvc2U9dGhpcy5vcHRpb25zLmF1dG9DbG9zZSkmJnRoaXMuY2xvc2UoKSx0aGlzLl9hdHRhY2hFdmVudHMoKSx0aGlzLm9wdGlvbnMuYmxvY2tTY3JvbGwmJih0aGlzLm9wdGlvbnMuYmxvY2tTY3JvbGxBZGp1c3Q/aC5ibG9ja1Njcm9sbFNjb3Blcz9oLmJsb2NrU2Nyb2xsU2NvcGVzKys6KGguYmxvY2tTY3JvbGxTY29wZXM9MSx0aGlzLnVuc2Nyb2xsKEFycmF5LmlzQXJyYXkodGhpcy5vcHRpb25zLmJsb2NrU2Nyb2xsQWRqdXN0KXx8XCJzdHJpbmdcIj09dHlwZW9mIHRoaXMub3B0aW9ucy5ibG9ja1Njcm9sbEFkanVzdD90aGlzLm9wdGlvbnMuYmxvY2tTY3JvbGxBZGp1c3Q6bnVsbCkpOmIoXCJib2R5XCIpLmFkZENsYXNzKFwiakJveC1ibG9ja1Njcm9sbC1cIit0aGlzLmlkKSksdGhpcy5vcHRpb25zLm92ZXJsYXkmJih0aGlzLl9zaG93T3ZlcmxheSgpLHRoaXMucG9zaXRpb24oKSksdGhpcy5vcHRpb25zLmFuaW1hdGlvbiYmIXRoaXMuaXNDbG9zaW5nJiZ0aGlzLl9hbmltYXRlKFwib3BlblwiKSx0aGlzLm9wdGlvbnMuYXVkaW8mJnRoaXMub3B0aW9ucy5hdWRpby5vcGVuJiZ0aGlzLmF1ZGlvKHRoaXMub3B0aW9ucy5hdWRpby5vcGVuLHRoaXMub3B0aW9ucy52b2x1bWUub3BlbiksdGhpcy5vcHRpb25zLmZhZGU/dGhpcy53cmFwcGVyLnN0b3AoKS5hbmltYXRlKHtvcGFjaXR5OjF9LHtxdWV1ZTohMSxkdXJhdGlvbjp0aGlzLm9wdGlvbnMuZmFkZSxzdGFydDpmdW5jdGlvbigpe3RoaXMuaXNPcGVuaW5nPSEwLHRoaXMud3JhcHBlci5jc3Moe2Rpc3BsYXk6XCJibG9ja1wifSl9LmJpbmQodGhpcyksYWx3YXlzOmZ1bmN0aW9uKCl7dGhpcy5pc09wZW5pbmc9ITEsc2V0VGltZW91dChmdW5jdGlvbigpe3RoaXMucG9zaXRpb25PbkZhZGVDb21wbGV0ZSYmdGhpcy5wb3NpdGlvbigpJiYodGhpcy5wb3NpdGlvbk9uRmFkZUNvbXBsZXRlPSExKX0uYmluZCh0aGlzKSwxMCl9LmJpbmQodGhpcyl9KToodGhpcy53cmFwcGVyLmNzcyh7ZGlzcGxheTpcImJsb2NrXCIsb3BhY2l0eToxfSksdGhpcy5wb3NpdGlvbk9uRmFkZUNvbXBsZXRlJiZ0aGlzLnBvc2l0aW9uKCkmJih0aGlzLnBvc2l0aW9uT25GYWRlQ29tcGxldGU9ITEpKSl9LmJpbmQodGhpcyk7cmV0dXJuIXRoaXMub3B0aW9ucy5kZWxheU9wZW58fHRoaXMuaXNPcGVufHx0aGlzLmlzQ2xvc2luZ3x8dC5pZ25vcmVEZWxheT9pKCk6dGhpcy50aW1lcj1zZXRUaW1lb3V0KGksdGhpcy5vcHRpb25zLmRlbGF5T3BlbiksdGhpc30saC5wcm90b3R5cGUuY2xvc2U9ZnVuY3Rpb24odCl7aWYodD10fHx7fSxiKFwiYm9keVwiKS5vZmYoXCJjbGljay5qQm94LVwiK3RoaXMuaWQrXCIgdGFwLmpCb3gtXCIrdGhpcy5pZCksdGhpcy5pc1RvdWNoRGV2aWNlJiZiKFwiYm9keSA+ICpcIikub2ZmKFwiY2xpY2suakJveC1cIit0aGlzLmlkK1wiIHRhcC5qQm94LVwiK3RoaXMuaWQpLHRoaXMuaXNEZXN0cm95ZWR8fHRoaXMuaXNDbG9zaW5nKXJldHVybiB0aGlzO2lmKHRoaXMudGltZXImJmNsZWFyVGltZW91dCh0aGlzLnRpbWVyKSx0aGlzLl9ibG9ja0JvZHlDbGljaygpLHRoaXMuaXNEaXNhYmxlZClyZXR1cm4gdGhpczt2YXIgaSxvLHMsZT1mdW5jdGlvbigpe3ZhciB0O3RoaXMuX2ZpcmVFdmVudChcIm9uQ2xvc2VcIiksdGhpcy5vcHRpb25zLmNhbmNlbEFqYXhPbkNsb3NlJiZ0aGlzLmNhbmNlbEFqYXgoKSx0aGlzLmlzT3BlbiYmKHRoaXMuaXNPcGVuPSExLHRoaXMuX2RldGFjaEV2ZW50cygpLHRoaXMub3B0aW9ucy5ibG9ja1Njcm9sbCYmKHRoaXMub3B0aW9ucy5ibG9ja1Njcm9sbEFkanVzdD8oaC5ibG9ja1Njcm9sbFNjb3Blcz1oLmJsb2NrU2Nyb2xsU2NvcGVzPy0taC5ibG9ja1Njcm9sbFNjb3BlczowKXx8dGhpcy51bnNjcm9sbC5yZXNldCgpOmIoXCJib2R5XCIpLnJlbW92ZUNsYXNzKFwiakJveC1ibG9ja1Njcm9sbC1cIit0aGlzLmlkKSksdGhpcy5vcHRpb25zLm92ZXJsYXkmJnRoaXMuX2hpZGVPdmVybGF5KCksdGhpcy5vcHRpb25zLmFuaW1hdGlvbiYmIXRoaXMuaXNPcGVuaW5nJiZ0aGlzLl9hbmltYXRlKFwiY2xvc2VcIiksdGhpcy5vcHRpb25zLmF1ZGlvJiZ0aGlzLm9wdGlvbnMuYXVkaW8uY2xvc2UmJnRoaXMuYXVkaW8odGhpcy5vcHRpb25zLmF1ZGlvLmNsb3NlLHRoaXMub3B0aW9ucy52b2x1bWUuY2xvc2UpLCh0PXRoaXMuaXNUb3VjaERldmljZSYmXCJtb3VzZVwiPT10aGlzLm9wdGlvbnMudGFyZ2V0PzA6dGhpcy5vcHRpb25zLmZhZGUpP3RoaXMud3JhcHBlci5zdG9wKCkuYW5pbWF0ZSh7b3BhY2l0eTowfSx7cXVldWU6ITEsZHVyYXRpb246dCxzdGFydDpmdW5jdGlvbigpe3RoaXMuaXNDbG9zaW5nPSEwfS5iaW5kKHRoaXMpLGNvbXBsZXRlOmZ1bmN0aW9uKCl7dGhpcy53cmFwcGVyLmNzcyh7ZGlzcGxheTpcIm5vbmVcIn0pLHRoaXMuX2ZpcmVFdmVudChcIm9uQ2xvc2VDb21wbGV0ZVwiKX0uYmluZCh0aGlzKSxhbHdheXM6ZnVuY3Rpb24oKXt0aGlzLmlzQ2xvc2luZz0hMX0uYmluZCh0aGlzKX0pOih0aGlzLndyYXBwZXIuY3NzKHtkaXNwbGF5Olwibm9uZVwiLG9wYWNpdHk6MH0pLHRoaXMuX2ZpcmVFdmVudChcIm9uQ2xvc2VDb21wbGV0ZVwiKSkpfS5iaW5kKHRoaXMpO3JldHVybiB0Lmlnbm9yZURlbGF5fHx0aGlzLmlzVG91Y2hEZXZpY2UmJlwibW91c2VcIj09dGhpcy5vcHRpb25zLnRhcmdldD9lKCk6KHRoaXMub3B0aW9ucy5kZWxheU9uSG92ZXJ8fHRoaXMub3B0aW9ucy5zaG93Q291bnRkb3duKSYmMTA8dGhpcy5vcHRpb25zLmRlbGF5Q2xvc2U/KG89KGk9dGhpcykub3B0aW9ucy5kZWxheUNsb3NlLHM9RGF0ZS5ub3coKSx0aGlzLm9wdGlvbnMuc2hvd0NvdW50ZG93biYmIXRoaXMuaW5uZXImJih0PWIoJzxkaXYgY2xhc3M9XCJqQm94LWNvdW50ZG93blwiIC8+JyksdGhpcy5pbm5lcj1iKCc8ZGl2IGNsYXNzPVwiakJveC1jb3VudGRvd24taW5uZXJcIiAvPicpLHQucHJlcGVuZCh0aGlzLmlubmVyKSxiKFwiI1wiK3RoaXMuaWQpLmFwcGVuZCh0KSksdGhpcy5jb3VudGRvd249ZnVuY3Rpb24oKXt2YXIgdD1EYXRlLm5vdygpO2kuaXNIb3ZlcmVkfHwoby09dC1zKSxzPXQsMDxvPyhpLm9wdGlvbnMuc2hvd0NvdW50ZG93biYmaS5pbm5lci5jc3MoXCJ3aWR0aFwiLDEwMCpvL2kub3B0aW9ucy5kZWxheUNsb3NlK1wiJVwiKSx3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGkuY291bnRkb3duKSk6ZSgpfSx3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuY291bnRkb3duKSk6dGhpcy50aW1lcj1zZXRUaW1lb3V0KGUsTWF0aC5tYXgodGhpcy5vcHRpb25zLmRlbGF5Q2xvc2UsMTApKSx0aGlzfSxoLnByb3RvdHlwZS50b2dnbGU9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXNbdGhpcy5pc09wZW4/XCJjbG9zZVwiOlwib3BlblwiXSh0KSx0aGlzfSxoLnByb3RvdHlwZS5kaXNhYmxlPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaXNEaXNhYmxlZD0hMCx0aGlzfSxoLnByb3RvdHlwZS5lbmFibGU9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5pc0Rpc2FibGVkPSExLHRoaXN9LGgucHJvdG90eXBlLmhpZGU9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kaXNhYmxlKCksdGhpcy53cmFwcGVyJiYodGhpcy5jYWNoZVdyYXBwZXJEaXNwbGF5PXRoaXMud3JhcHBlci5jc3MoXCJkaXNwbGF5XCIpLHRoaXMud3JhcHBlci5jc3Moe2Rpc3BsYXk6XCJub25lXCJ9KSksdGhpcy5vdmVybGF5JiYodGhpcy5jYWNoZU92ZXJsYXlEaXNwbGF5PXRoaXMub3ZlcmxheS5jc3MoXCJkaXNwbGF5XCIpLHRoaXMub3ZlcmxheS5jc3Moe2Rpc3BsYXk6XCJub25lXCJ9KSksdGhpc30saC5wcm90b3R5cGUuc2hvdz1mdW5jdGlvbigpe3JldHVybiB0aGlzLmVuYWJsZSgpLHRoaXMud3JhcHBlciYmdGhpcy5jYWNoZVdyYXBwZXJEaXNwbGF5JiYodGhpcy53cmFwcGVyLmNzcyh7ZGlzcGxheTp0aGlzLmNhY2hlV3JhcHBlckRpc3BsYXl9KSx0aGlzLmNhY2hlV3JhcHBlckRpc3BsYXk9bnVsbCksdGhpcy5vdmVybGF5JiZ0aGlzLmNhY2hlT3ZlcmxheURpc3BsYXkmJih0aGlzLm92ZXJsYXkuY3NzKHtkaXNwbGF5OnRoaXMuY2FjaGVPdmVybGF5RGlzcGxheX0pLHRoaXMuY2FjaGVPdmVybGF5RGlzcGxheT1udWxsKSx0aGlzfSxoLnByb3RvdHlwZS5hamF4PWZ1bmN0aW9uKG8saSl7bz1vfHx7fSxiLmVhY2goW1tcImdldERhdGFcIixcImRhdGFcIl0sW1wiZ2V0VVJMXCIsXCJ1cmxcIl1dLGZ1bmN0aW9uKHQsaSl7dGhpcy5vcHRpb25zLmFqYXhbaVswXV0mJiFvW2lbMV1dJiZ0aGlzLnNvdXJjZSYmbnVsbCE9dGhpcy5zb3VyY2UuYXR0cih0aGlzLm9wdGlvbnMuYWpheFtpWzBdXSkmJihvW2lbMV1dPXRoaXMuc291cmNlLmF0dHIodGhpcy5vcHRpb25zLmFqYXhbaVswXV0pfHxcIlwiKX0uYmluZCh0aGlzKSk7dmFyIHQ9Yi5leHRlbmQoITAse30sdGhpcy5vcHRpb25zLmFqYXgpO3RoaXMuY2FuY2VsQWpheCgpO3ZhciBzPW8uYmVmb3JlU2VuZHx8dC5iZWZvcmVTZW5kfHxmdW5jdGlvbigpe30sZT1vLmNvbXBsZXRlfHx0LmNvbXBsZXRlfHxmdW5jdGlvbigpe30sbj1vLnN1Y2Nlc3N8fHQuc3VjY2Vzc3x8ZnVuY3Rpb24oKXt9LGE9by5lcnJvcnx8dC5lcnJvcnx8ZnVuY3Rpb24oKXt9LGg9Yi5leHRlbmQoITAsdCxvKTtyZXR1cm4gaC5iZWZvcmVTZW5kPWZ1bmN0aW9uKHQpe2gubG9hZGluZ0NsYXNzJiZ0aGlzLndyYXBwZXIuYWRkQ2xhc3MoITA9PT1oLmxvYWRpbmdDbGFzcz9cImpCb3gtbG9hZGluZ1wiOmgubG9hZGluZ0NsYXNzKSxoLnNwaW5uZXImJih0aGlzLnNwaW5uZXJEZWxheT1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dGhpcy53cmFwcGVyLmFkZENsYXNzKFwiakJveC1sb2FkaW5nLXNwaW5uZXJcIiksaC5zcGlubmVyUmVwb3NpdGlvbiYmKGk/dGhpcy5wb3NpdGlvbk9uRmFkZUNvbXBsZXRlPSEwOnRoaXMucG9zaXRpb24oKSksdGhpcy5zcGlubmVyPWIoITAhPT1oLnNwaW5uZXI/aC5zcGlubmVyOic8ZGl2IGNsYXNzPVwiakJveC1zcGlubmVyXCI+PC9kaXY+JykuYXBwZW5kVG8odGhpcy5jb250YWluZXIpLHRoaXMudGl0bGVDb250YWluZXImJlwiYWJzb2x1dGVcIj09dGhpcy5zcGlubmVyLmNzcyhcInBvc2l0aW9uXCIpJiZ0aGlzLnNwaW5uZXIuY3NzKHt0cmFuc2Zvcm06XCJ0cmFuc2xhdGVZKFwiKy41KnRoaXMudGl0bGVDb250YWluZXIub3V0ZXJIZWlnaHQoKStcInB4KVwifSl9LmJpbmQodGhpcyksXCJcIiE9dGhpcy5jb250ZW50Lmh0bWwoKSYmaC5zcGlubmVyRGVsYXl8fDApKSxzLmJpbmQodGhpcykodCl9LmJpbmQodGhpcyksaC5jb21wbGV0ZT1mdW5jdGlvbih0KXt0aGlzLnNwaW5uZXJEZWxheSYmY2xlYXJUaW1lb3V0KHRoaXMuc3Bpbm5lckRlbGF5KSx0aGlzLndyYXBwZXIucmVtb3ZlQ2xhc3MoXCJqQm94LWxvYWRpbmcgakJveC1sb2FkaW5nLXNwaW5uZXIgakJveC1sb2FkaW5nLXNwaW5uZXItZGVsYXlcIiksdGhpcy5zcGlubmVyJiZ0aGlzLnNwaW5uZXIubGVuZ3RoJiZ0aGlzLnNwaW5uZXIucmVtb3ZlKCkmJmguc3Bpbm5lclJlcG9zaXRpb24mJihpP3RoaXMucG9zaXRpb25PbkZhZGVDb21wbGV0ZT0hMDp0aGlzLnBvc2l0aW9uKCkpLHRoaXMuYWpheExvYWRlZD0hMCxlLmJpbmQodGhpcykodCl9LmJpbmQodGhpcyksaC5zdWNjZXNzPWZ1bmN0aW9uKHQpe2guc2V0Q29udGVudCYmdGhpcy5zZXRDb250ZW50KHQsITApJiYoaT90aGlzLnBvc2l0aW9uT25GYWRlQ29tcGxldGU9ITA6dGhpcy5wb3NpdGlvbigpKSxoLnNldENvbnRlbnQmJnRoaXMuc291cmNlJiZ0aGlzLnNvdXJjZS5kYXRhKFwiakJveC1hamF4LWRhdGFcIix0KSxuLmJpbmQodGhpcykodCl9LmJpbmQodGhpcyksaC5lcnJvcj1mdW5jdGlvbih0KXthLmJpbmQodGhpcykodCl9LmJpbmQodGhpcyksdGhpcy5hamF4UmVxdWVzdD1iLmFqYXgoaCksdGhpc30saC5wcm90b3R5cGUuY2FuY2VsQWpheD1mdW5jdGlvbigpe3RoaXMuYWpheFJlcXVlc3QmJih0aGlzLmFqYXhSZXF1ZXN0LmFib3J0KCksdGhpcy5hamF4TG9hZGVkPSExKX0saC5wcm90b3R5cGUuYXVkaW89ZnVuY3Rpb24odCxpKXtpZighdClyZXR1cm4gdGhpczt2YXIgbzsoaC5fYXVkaW89IWguX2F1ZGlvP3t9OmguX2F1ZGlvKVt0XXx8KG89YihcIjxhdWRpby8+XCIpLGIoXCI8c291cmNlLz5cIix7c3JjOnQrXCIubXAzXCJ9KS5hcHBlbmRUbyhvKSxiKFwiPHNvdXJjZS8+XCIse3NyYzp0K1wiLm9nZ1wifSkuYXBwZW5kVG8obyksaC5fYXVkaW9bdF09b1swXSksaC5fYXVkaW9bdF0udm9sdW1lPU1hdGgubWluKChudWxsIT1pP2k6MTAwKS8xMDAsMSk7dHJ5e2guX2F1ZGlvW3RdLnBhdXNlKCksaC5fYXVkaW9bdF0uY3VycmVudFRpbWU9MH1jYXRjaCh0KXt9cmV0dXJuIGguX2F1ZGlvW3RdLnBsYXkoKSx0aGlzfSxoLl9hbmltYXRpb25TcGVlZHM9e3RhZGE6MWUzLHRhZGFTbWFsbDoxZTMsZmxhc2g6NTAwLHNoYWtlOjQwMCxwdWxzZVVwOjI1MCxwdWxzZURvd246MjUwLHBvcEluOjI1MCxwb3BPdXQ6MjUwLGZhZGVJbjoyMDAsZmFkZU91dDoyMDAsc2xpZGVVcDo0MDAsc2xpZGVSaWdodDo0MDAsc2xpZGVMZWZ0OjQwMCxzbGlkZURvd246NDAwfSxoLnByb3RvdHlwZS5hbmltYXRlPWZ1bmN0aW9uKHQsaSl7aT1pfHx7fSx0aGlzLmFuaW1hdGlvblRpbWVvdXR8fCh0aGlzLmFuaW1hdGlvblRpbWVvdXQ9e30pLGkuZWxlbWVudHx8KGkuZWxlbWVudD10aGlzLndyYXBwZXIpLGkuZWxlbWVudC5kYXRhKFwiakJveC1hbmltYXRpbmctaWRcIil8fGkuZWxlbWVudC5kYXRhKFwiakJveC1hbmltYXRpbmctaWRcIixoLl9nZXRVbmlxdWVFbGVtZW50SUQoKSksaS5lbGVtZW50LmRhdGEoXCJqQm94LWFuaW1hdGluZ1wiKSYmKGkuZWxlbWVudC5yZW1vdmVDbGFzcyhpLmVsZW1lbnQuZGF0YShcImpCb3gtYW5pbWF0aW5nXCIpKS5kYXRhKFwiakJveC1hbmltYXRpbmdcIixudWxsKSx0aGlzLmFuaW1hdGlvblRpbWVvdXRbaS5lbGVtZW50LmRhdGEoXCJqQm94LWFuaW1hdGluZy1pZFwiKV0mJmNsZWFyVGltZW91dCh0aGlzLmFuaW1hdGlvblRpbWVvdXRbaS5lbGVtZW50LmRhdGEoXCJqQm94LWFuaW1hdGluZy1pZFwiKV0pKSxpLmVsZW1lbnQuYWRkQ2xhc3MoXCJqQm94LWFuaW1hdGVkLVwiK3QpLmRhdGEoXCJqQm94LWFuaW1hdGluZ1wiLFwiakJveC1hbmltYXRlZC1cIit0KSx0aGlzLmFuaW1hdGlvblRpbWVvdXRbaS5lbGVtZW50LmRhdGEoXCJqQm94LWFuaW1hdGluZy1pZFwiKV09c2V0VGltZW91dChmdW5jdGlvbigpe2kuZWxlbWVudC5yZW1vdmVDbGFzcyhpLmVsZW1lbnQuZGF0YShcImpCb3gtYW5pbWF0aW5nXCIpKS5kYXRhKFwiakJveC1hbmltYXRpbmdcIixudWxsKSxpLmNvbXBsZXRlJiZpLmNvbXBsZXRlKCl9LGguX2FuaW1hdGlvblNwZWVkc1t0XSl9LGgucHJvdG90eXBlLnN3aXBlRGV0ZWN0b3I9ZnVuY3Rpb24oaSxvKXt2YXIgcz0wLGU9MCxuPTAsYT0wLGg9MCx0PXtzd2lwZVRocmVzaG9sZDo3MCx1c2VPbmx5VG91Y2g6ITF9O2Z1bmN0aW9uIHIodCl7by51c2VPbmx5VG91Y2gmJiF0Lm9yaWdpbmFsRXZlbnQudG91Y2hlc3x8KHQub3JpZ2luYWxFdmVudC50b3VjaGVzJiYodD10Lm9yaWdpbmFsRXZlbnQudG91Y2hlc1swXSksMD09PXMmJihzPTEsZT10LmNsaWVudFgsbj10LmNsaWVudFkpKX1mdW5jdGlvbiBwKHQpezI9PT1zJiYocz0wLE1hdGguYWJzKGEpPk1hdGguYWJzKGgpJiZNYXRoLmFicyhhKT5vLnN3aXBlVGhyZXNob2xkP2E8MD9pLnRyaWdnZXIoYi5FdmVudChcInN3aXBlTGVmdC5zZFwiKSk6aS50cmlnZ2VyKGIuRXZlbnQoXCJzd2lwZVJpZ2h0LnNkXCIpKTpNYXRoLmFicyhoKT5vLnN3aXBlVGhyZXNob2xkJiYoaDwwP2kudHJpZ2dlcihiLkV2ZW50KFwic3dpcGVVcC5zZFwiKSk6aS50cmlnZ2VyKGIuRXZlbnQoXCJzd2lwZURvd24uc2RcIikpKSl9ZnVuY3Rpb24gbCh0KXt2YXIgaTsxPT09cyYmKGk9KHQ9dC5vcmlnaW5hbEV2ZW50LnRvdWNoZXM/dC5vcmlnaW5hbEV2ZW50LnRvdWNoZXNbMF06dCkuY2xpZW50WC1lLHQ9dC5jbGllbnRZLW4sKE1hdGguYWJzKGkpPm8uc3dpcGVUaHJlc2hvbGR8fE1hdGguYWJzKHQpPm8uc3dpcGVUaHJlc2hvbGQpJiYocz0yLGE9aSxoPXQpKX1yZXR1cm4gbz1iLmV4dGVuZCh0LG8pLGkub24oXCJtb3VzZWRvd24gdG91Y2hzdGFydFwiLHIpLGIoXCJodG1sXCIpLm9uKFwibW91c2V1cCB0b3VjaGVuZFwiLHApLGIoXCJodG1sXCIpLm9uKFwibW91c2Vtb3ZlIHRvdWNobW92ZVwiLGwpLGl9LGgucHJvdG90eXBlLmRlc3Ryb3k9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kZXRhY2goKSx0aGlzLmlzT3BlbiYmdGhpcy5jbG9zZSh7aWdub3JlRGVsYXk6ITB9KSx0aGlzLndyYXBwZXImJnRoaXMud3JhcHBlci5yZW1vdmUoKSx0aGlzLm92ZXJsYXkmJnRoaXMub3ZlcmxheS5yZW1vdmUoKSx0aGlzLl9zdHlsZXMmJnRoaXMuX3N0eWxlcy5yZW1vdmUoKSx0aGlzLmlzRGVzdHJveWVkPSEwLHRoaXN9LGguX2dldFVuaXF1ZUlEPSh0PTEsZnVuY3Rpb24oKXtyZXR1cm4gdCsrfSksaC5fZ2V0VW5pcXVlRWxlbWVudElEPShpPTEsZnVuY3Rpb24oKXtyZXR1cm4gaSsrfSksaC5fcGx1Z2luT3B0aW9ucz17fSxoLnBsdWdpbj1mdW5jdGlvbih0LGkpe2guX3BsdWdpbk9wdGlvbnNbdF09aX0sYi5mbi5qQm94PWZ1bmN0aW9uKHQsaSl7cmV0dXJuIGk9aXx8e30sbmV3IGgodD10fHx7fSxiLmV4dGVuZChpLHthdHRhY2g6dGhpc30pKX0saH1mdW5jdGlvbiBqQm94Q29uZmlybVdyYXBwZXIoakJveCxqUXVlcnkpe25ldyBqQm94LnBsdWdpbihcIkNvbmZpcm1cIix7Y29uZmlybUJ1dHRvbjpcIlN1Ym1pdFwiLGNhbmNlbEJ1dHRvbjpcIkNhbmNlbFwiLGNvbmZpcm06bnVsbCxjYW5jZWw6bnVsbCxjbG9zZU9uQ29uZmlybTohMCx0YXJnZXQ6d2luZG93LGZpeGVkOiEwLGF0dGFjaDpcIltkYXRhLWNvbmZpcm1dXCIsZ2V0Q29udGVudDpcImRhdGEtY29uZmlybVwiLGNvbnRlbnQ6XCJEbyB5b3UgcmVhbGx5IHdhbnQgdG8gZG8gdGhpcz9cIixtaW5XaWR0aDozNjAsbWF4V2lkdGg6NTAwLGJsb2NrU2Nyb2xsOiEwLGNsb3NlT25Fc2M6ITAsY2xvc2VPbkNsaWNrOiExLGNsb3NlQnV0dG9uOiExLG92ZXJsYXk6ITAsYW5pbWF0aW9uOlwiem9vbUluXCIscHJldmVudERlZmF1bHQ6ITAsX29uQXR0YWNoOmZ1bmN0aW9uKHQpe3ZhciBpO3RoaXMub3B0aW9ucy5jb25maXJtfHwoaT10LmF0dHIoXCJvbmNsaWNrXCIpP3QuYXR0cihcIm9uY2xpY2tcIik6dC5hdHRyKFwiaHJlZlwiKT90LmF0dHIoXCJ0YXJnZXRcIik/J3dpbmRvdy5vcGVuKFwiJyt0LmF0dHIoXCJocmVmXCIpKydcIiwgXCInK3QuYXR0cihcInRhcmdldFwiKSsnXCIpOyc6J3dpbmRvdy5sb2NhdGlvbi5ocmVmID0gXCInK3QuYXR0cihcImhyZWZcIikrJ1wiOyc6XCJcIix0LnByb3AoXCJvbmNsaWNrXCIsbnVsbCkuZGF0YShcImpCb3gtQ29uZmlybS1zdWJtaXRcIixpKSl9LF9vbkNyZWF0ZWQ6ZnVuY3Rpb24oKXt0aGlzLndyYXBwZXIuYWRkQ2xhc3MoXCJqQm94LU1vZGFsXCIpLHRoaXMuZm9vdGVyPWpRdWVyeSgnPGRpdiBjbGFzcz1cImpCb3gtQ29uZmlybS1mb290ZXJcIi8+JyksalF1ZXJ5KCc8ZGl2IGNsYXNzPVwiakJveC1Db25maXJtLWJ1dHRvbiBqQm94LUNvbmZpcm0tYnV0dG9uLWNhbmNlbFwiLz4nKS5odG1sKHRoaXMub3B0aW9ucy5jYW5jZWxCdXR0b24pLm9uKFwiY2xpY2sgdGFwXCIsZnVuY3Rpb24oKXt0aGlzLm9wdGlvbnMuY2FuY2VsJiZ0aGlzLm9wdGlvbnMuY2FuY2VsKHRoaXMuc291cmNlKSx0aGlzLmNsb3NlKCl9LmJpbmQodGhpcykpLmFwcGVuZFRvKHRoaXMuZm9vdGVyKSx0aGlzLnN1Ym1pdEJ1dHRvbj1qUXVlcnkoJzxkaXYgY2xhc3M9XCJqQm94LUNvbmZpcm0tYnV0dG9uIGpCb3gtQ29uZmlybS1idXR0b24tc3VibWl0XCIvPicpLmh0bWwodGhpcy5vcHRpb25zLmNvbmZpcm1CdXR0b24pLmFwcGVuZFRvKHRoaXMuZm9vdGVyKSx0aGlzLmZvb3Rlci5hcHBlbmRUbyh0aGlzLmNvbnRhaW5lcil9LF9vbk9wZW46ZnVuY3Rpb24oKXt0aGlzLnN1Ym1pdEJ1dHRvbi5vZmYoXCJjbGljay5qQm94LUNvbmZpcm1cIit0aGlzLmlkK1wiIHRhcC5qQm94LUNvbmZpcm1cIit0aGlzLmlkKS5vbihcImNsaWNrLmpCb3gtQ29uZmlybVwiK3RoaXMuaWQrXCIgdGFwLmpCb3gtQ29uZmlybVwiK3RoaXMuaWQsZnVuY3Rpb24oKXt0aGlzLm9wdGlvbnMuY29uZmlybT90aGlzLm9wdGlvbnMuY29uZmlybSh0aGlzLnNvdXJjZSk6ZXZhbCh0aGlzLnNvdXJjZS5kYXRhKFwiakJveC1Db25maXJtLXN1Ym1pdFwiKSksdGhpcy5vcHRpb25zLmNsb3NlT25Db25maXJtJiZ0aGlzLmNsb3NlKCl9LmJpbmQodGhpcykpfX0pfWZ1bmN0aW9uIGpCb3hJbWFnZVdyYXBwZXIodCxhKXtuZXcgdC5wbHVnaW4oXCJJbWFnZVwiLHtzcmM6XCJocmVmXCIsZ2FsbGVyeTpcImRhdGEtamJveC1pbWFnZVwiLGltYWdlTGFiZWw6XCJ0aXRsZVwiLGltYWdlRmFkZTozNjAsaW1hZ2VTaXplOlwiY29udGFpblwiLGltYWdlQ291bnRlcjohMSxpbWFnZUNvdW50ZXJTZXBhcmF0b3I6XCIvXCIsZG93bmxvYWRCdXR0b246ITEsZG93bmxvYWRCdXR0b25UZXh0Om51bGwsZG93bmxvYWRCdXR0b25Vcmw6bnVsbCxtb2JpbGVJbWFnZUF0dHI6bnVsbCxtb2JpbGVJbWFnZUJyZWFrcG9pbnQ6bnVsbCxwcmVsb2FkRmlyc3RJbWFnZTohMSx0YXJnZXQ6d2luZG93LGF0dGFjaDpcIltkYXRhLWpib3gtaW1hZ2VdXCIsZml4ZWQ6ITAsYmxvY2tTY3JvbGw6ITAsY2xvc2VPbkVzYzohMCxjbG9zZU9uQ2xpY2s6XCJidXR0b25cIixjbG9zZUJ1dHRvbjohMCxvdmVybGF5OiEwLGFuaW1hdGlvbjpcInpvb21JblwiLHByZXZlbnREZWZhdWx0OiEwLHdpZHRoOlwiMTAwJVwiLGhlaWdodDpcIjEwMCVcIixhZGp1c3REaXN0YW5jZTp7dG9wOjQwLHJpZ2h0OjAsYm90dG9tOjQwLGxlZnQ6MH0sX29uSW5pdDpmdW5jdGlvbigpe3RoaXMuaW1hZ2VzPXRoaXMuY3VycmVudEltYWdlPXt9LHRoaXMuaW1hZ2VaSW5kZXg9MSx0aGlzLmluaXRJbWFnZT1mdW5jdGlvbih0KXt2YXIgaSxvOyh0PWEodCkpLmRhdGEoXCJqQm94LWltYWdlLWdhbGxlcnlcIil8fChpPXQuYXR0cih0aGlzLm9wdGlvbnMuc3JjKSx0aGlzLm9wdGlvbnMubW9iaWxlSW1hZ2VBdHRyJiZ0aGlzLm9wdGlvbnMubW9iaWxlSW1hZ2VCcmVha3BvaW50JiZ0LmF0dHIodGhpcy5vcHRpb25zLm1vYmlsZUltYWdlQXR0cikmJmEod2luZG93KS53aWR0aCgpPD10aGlzLm9wdGlvbnMubW9iaWxlSW1hZ2VCcmVha3BvaW50JiYoaT10LmF0dHIodGhpcy5vcHRpb25zLm1vYmlsZUltYWdlQXR0cikpLG89dC5hdHRyKHRoaXMub3B0aW9ucy5nYWxsZXJ5KXx8XCJkZWZhdWx0XCIsdGhpcy5pbWFnZXNbb118fCh0aGlzLmltYWdlc1tvXT1bXSksdGhpcy5pbWFnZXNbb10ucHVzaCh7c3JjOmksbGFiZWw6dC5hdHRyKHRoaXMub3B0aW9ucy5pbWFnZUxhYmVsKXx8XCJcIixkb3dubG9hZFVybDp0aGlzLm9wdGlvbnMuZG93bmxvYWRCdXR0b25VcmwmJnQuYXR0cih0aGlzLm9wdGlvbnMuZG93bmxvYWRCdXR0b25VcmwpP3QuYXR0cih0aGlzLm9wdGlvbnMuZG93bmxvYWRCdXR0b25VcmwpOm51bGx9KSxcInRpdGxlXCI9PXRoaXMub3B0aW9ucy5pbWFnZUxhYmVsJiZ0LnJlbW92ZUF0dHIoXCJ0aXRsZVwiKSx0LmRhdGEoXCJqQm94LWltYWdlLWdhbGxlcnlcIixvKSx0LmRhdGEoXCJqQm94LWltYWdlLWlkXCIsdGhpcy5pbWFnZXNbb10ubGVuZ3RoLTEpKX0uYmluZCh0aGlzKSx0aGlzLmF0dGFjaGVkRWxlbWVudHMmJnRoaXMuYXR0YWNoZWRFbGVtZW50cy5sZW5ndGgmJmEuZWFjaCh0aGlzLmF0dGFjaGVkRWxlbWVudHMsZnVuY3Rpb24odCxpKXt0aGlzLmluaXRJbWFnZShpKX0uYmluZCh0aGlzKSk7dmFyIG49ZnVuY3Rpb24odCxpLG8scyl7aWYoIWEoXCIjakJveC1pbWFnZS1cIit0K1wiLVwiK2kpLmxlbmd0aCl7dmFyIGU9YShcIjxkaXYvPlwiLHtpZDpcImpCb3gtaW1hZ2UtXCIrdCtcIi1cIitpLGNsYXNzOlwiakJveC1pbWFnZS1jb250YWluZXJcIisobz9cIiBqQm94LWltYWdlLVwiK3QrXCItY3VycmVudFwiOlwiXCIpfSkuY3NzKHtiYWNrZ3JvdW5kU2l6ZTp0aGlzLm9wdGlvbnMuaW1hZ2VTaXplLG9wYWNpdHk6cz8xOjAsekluZGV4Om8/dGhpcy5pbWFnZVpJbmRleCsrOjB9KS5hcHBlbmRUbyh0aGlzLmNvbnRlbnQpO3JldHVybiB0aGlzLnN3aXBlRGV0ZWN0b3IoZSkub24oXCJzd2lwZUxlZnQuc2Qgc3dpcGVSaWdodC5zZFwiLGZ1bmN0aW9uKHQpe1wic3dpcGVMZWZ0XCI9PT10LnR5cGU/dGhpcy5zaG93SW1hZ2UoXCJuZXh0XCIpOlwic3dpcGVSaWdodFwiPT09dC50eXBlJiZ0aGlzLnNob3dJbWFnZShcInByZXZcIil9LmJpbmQodGhpcykpLGEoXCI8ZGl2Lz5cIix7aWQ6XCJqQm94LWltYWdlLWxhYmVsLVwiK3QrXCItXCIraSxjbGFzczpcImpCb3gtaW1hZ2UtbGFiZWxcIisobz9cIiBhY3RpdmVcIjpcIlwiKX0pLmh0bWwodGhpcy5pbWFnZXNbdF1baV0ubGFiZWwpLm9uKFwiY2xpY2sgdGFwXCIsZnVuY3Rpb24oKXthKHRoaXMpLnRvZ2dsZUNsYXNzKFwiZXhwYW5kZWRcIil9KS5hcHBlbmRUbyh0aGlzLmltYWdlTGFiZWxDb250YWluZXIpLG8mJmUuYW5pbWF0ZSh7b3BhY2l0eToxfSxzPzA6dGhpcy5vcHRpb25zLmltYWdlRmFkZSksZX19LmJpbmQodGhpcyk7dGhpcy5kb3dubG9hZEltYWdlPWZ1bmN0aW9uKHQpe3ZhciBpPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO2kuaHJlZj10LGkuc2V0QXR0cmlidXRlKFwiZG93bmxvYWRcIix0LnN1YnN0cmluZyh0Lmxhc3RJbmRleE9mKFwiL1wiKSsxKSksZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChpKSxpLmNsaWNrKCl9O3ZhciBlPWZ1bmN0aW9uKGksbyx0LHMpe3ZhciBlPW4oaSxvLHQscyk7ZS5hZGRDbGFzcyhcImpCb3gtaW1hZ2UtbG9hZGluZ1wiKSxhKCc8aW1nIHNyYz1cIicrdGhpcy5pbWFnZXNbaV1bb10uc3JjKydcIiAvPicpLmVhY2goZnVuY3Rpb24oKXt2YXIgdD1uZXcgSW1hZ2U7dC5vbmxvYWQ9ZnVuY3Rpb24oKXtlLnJlbW92ZUNsYXNzKFwiakJveC1pbWFnZS1sb2FkaW5nXCIpLGUuY3NzKHtiYWNrZ3JvdW5kSW1hZ2U6J3VybChcIicrdGhpcy5pbWFnZXNbaV1bb10uc3JjKydcIiknfSl9LmJpbmQodGhpcyksdC5vbmVycm9yPWZ1bmN0aW9uKCl7ZS5yZW1vdmVDbGFzcyhcImpCb3gtaW1hZ2UtbG9hZGluZ1wiKSxlLmFkZENsYXNzKFwiakJveC1pbWFnZS1ub3QtZm91bmRcIil9LmJpbmQodGhpcyksdC5zcmM9dGhpcy5pbWFnZXNbaV1bb10uc3JjfS5iaW5kKHRoaXMpKX0uYmluZCh0aGlzKTt0aGlzLnNob3dJbWFnZT1mdW5jdGlvbih0KXt2YXIgaSxvLHM7aWYoXCJvcGVuXCIhPXQpaT10aGlzLmN1cnJlbnRJbWFnZS5nYWxsZXJ5LHM9KHM9dGhpcy5jdXJyZW50SW1hZ2UuaWQrKCsoXCJwcmV2XCI9PXQpPy0xOjEpKT50aGlzLmltYWdlc1tpXS5sZW5ndGgtMT8wOnM8MD90aGlzLmltYWdlc1tpXS5sZW5ndGgtMTpzO2Vsc2V7aWYodGhpcy5zb3VyY2UpaT10aGlzLnNvdXJjZS5kYXRhKFwiakJveC1pbWFnZS1nYWxsZXJ5XCIpLHM9dGhpcy5zb3VyY2UuZGF0YShcImpCb3gtaW1hZ2UtaWRcIik7ZWxzZXtpZighdGhpcy5hdHRhY2hlZEVsZW1lbnRzfHwhdGhpcy5hdHRhY2hlZEVsZW1lbnRzLmxlbmd0aClyZXR1cm47aT1hKHRoaXMuYXR0YWNoZWRFbGVtZW50c1swXSkuZGF0YShcImpCb3gtaW1hZ2UtZ2FsbGVyeVwiKSxzPWEodGhpcy5hdHRhY2hlZEVsZW1lbnRzWzBdKS5kYXRhKFwiakJveC1pbWFnZS1pZFwiKX10aGlzLmltYWdlcyYmdGhpcy5pbWFnZXNbaV0mJmEoXCIuakJveC1pbWFnZS1wb2ludGVyLXByZXYsIC5qQm94LWltYWdlLXBvaW50ZXItbmV4dFwiKS5jc3Moe2Rpc3BsYXk6MTx0aGlzLmltYWdlc1tpXS5sZW5ndGg/XCJibG9ja1wiOlwibm9uZVwifSl9YShcIi5qQm94LWltYWdlLVwiK2krXCItY3VycmVudFwiKS5sZW5ndGgmJmEoXCIuakJveC1pbWFnZS1cIitpK1wiLWN1cnJlbnRcIikucmVtb3ZlQ2xhc3MoXCJqQm94LWltYWdlLVwiK2krXCItY3VycmVudFwiKS5hbmltYXRlKHtvcGFjaXR5OjB9LFwib3BlblwiPT10PzA6dGhpcy5vcHRpb25zLmltYWdlRmFkZSksdGhpcy5jdXJyZW50SW1hZ2U9e2dhbGxlcnk6aSxpZDpzfSxhKFwiI2pCb3gtaW1hZ2UtXCIraStcIi1cIitzKS5sZW5ndGg/YShcIiNqQm94LWltYWdlLVwiK2krXCItXCIrcykuYWRkQ2xhc3MoXCJqQm94LWltYWdlLVwiK2krXCItY3VycmVudFwiKS5jc3Moe3pJbmRleDp0aGlzLmltYWdlWkluZGV4Kyssb3BhY2l0eTowfSkuYW5pbWF0ZSh7b3BhY2l0eToxfSxcIm9wZW5cIj09dD8wOnRoaXMub3B0aW9ucy5pbWFnZUZhZGUpOmUoaSxzLCEwLFwib3BlblwiPT09dCksbz1pLHQ9cyxhKFwiLmpCb3gtaW1hZ2UtbGFiZWwuYWN0aXZlXCIpLnJlbW92ZUNsYXNzKFwiYWN0aXZlIGV4cGFuZGVkXCIpLGEoXCIjakJveC1pbWFnZS1sYWJlbC1cIitvK1wiLVwiK3QpLmFkZENsYXNzKFwiYWN0aXZlXCIpLHRoaXMuaW1hZ2VDb3VudGVyJiYodGhpcy5pbWFnZXNbaV0mJjE8dGhpcy5pbWFnZXNbaV0ubGVuZ3RoPyh0aGlzLndyYXBwZXIuYWRkQ2xhc3MoXCJqQm94LWltYWdlLWhhcy1jb3VudGVyXCIpLHRoaXMuaW1hZ2VDb3VudGVyLmZpbmQoXCIuakJveC1pbWFnZS1jb3VudGVyLWFsbFwiKS5odG1sKHRoaXMuaW1hZ2VzW2ldLmxlbmd0aCksdGhpcy5pbWFnZUNvdW50ZXIuZmluZChcIi5qQm94LWltYWdlLWNvdW50ZXItY3VycmVudFwiKS5odG1sKHMrMSkpOnRoaXMud3JhcHBlci5yZW1vdmVDbGFzcyhcImpCb3gtaW1hZ2UtaGFzLWNvdW50ZXJcIikpLHRoaXMuaW1hZ2VzW2ldJiZ0aGlzLmltYWdlc1tpXS5sZW5ndGgtMSYmKHM9KHM9cysxKT50aGlzLmltYWdlc1tpXS5sZW5ndGgtMT8wOnM8MD90aGlzLmltYWdlc1tpXS5sZW5ndGgtMTpzLGEoXCIjakJveC1pbWFnZS1cIitpK1wiLVwiK3MpLmxlbmd0aHx8ZShpLHMsITEsITEpKX0sdGhpcy5vcHRpb25zLnByZWxvYWRGaXJzdEltYWdlJiZhKHdpbmRvdykub24oXCJsb2FkXCIsZnVuY3Rpb24oKXt0aGlzLnNob3dJbWFnZShcIm9wZW5cIil9LmJpbmQodGhpcykpfSxfb25BdHRhY2g6ZnVuY3Rpb24odCl7dGhpcy5pbml0SW1hZ2UmJnRoaXMuaW5pdEltYWdlKHQpfSxfb25DcmVhdGVkOmZ1bmN0aW9uKCl7dGhpcy5pbWFnZUxhYmVsV3JhcHBlcj1hKCc8ZGl2IGNsYXNzPVwiakJveC1pbWFnZS1sYWJlbC13cmFwcGVyXCIvPicpLmFwcGVuZFRvKHRoaXMud3JhcHBlciksdGhpcy5pbWFnZVByZXZCdXR0b249YSgnPGRpdiBjbGFzcz1cImpCb3gtaW1hZ2UtcG9pbnRlci1wcmV2XCIvPicpLm9uKFwiY2xpY2sgdGFwXCIsZnVuY3Rpb24oKXt0aGlzLnNob3dJbWFnZShcInByZXZcIil9LmJpbmQodGhpcykpLHRoaXMuaW1hZ2VOZXh0QnV0dG9uPWEoJzxkaXYgY2xhc3M9XCJqQm94LWltYWdlLXBvaW50ZXItbmV4dFwiLz4nKS5vbihcImNsaWNrIHRhcFwiLGZ1bmN0aW9uKCl7dGhpcy5zaG93SW1hZ2UoXCJuZXh0XCIpfS5iaW5kKHRoaXMpKSx0aGlzLmltYWdlTGFiZWxDb250YWluZXI9YSgnPGRpdiBjbGFzcz1cImpCb3gtaW1hZ2UtbGFiZWwtY29udGFpbmVyXCIvPicpLHRoaXMuaW1hZ2VMYWJlbFdyYXBwZXIuYXBwZW5kKHRoaXMuaW1hZ2VQcmV2QnV0dG9uKS5hcHBlbmQodGhpcy5pbWFnZUxhYmVsQ29udGFpbmVyKS5hcHBlbmQodGhpcy5pbWFnZU5leHRCdXR0b24pLHRoaXMub3B0aW9ucy5kb3dubG9hZEJ1dHRvbiYmKHRoaXMuZG93bmxvYWRCdXR0b249YShcIjxkaXYvPlwiLHtjbGFzczpcImpCb3gtaW1hZ2UtZG93bmxvYWQtYnV0dG9uLXdyYXBwZXJcIn0pLmFwcGVuZFRvKHRoaXMud3JhcHBlcikuYXBwZW5kKHRoaXMub3B0aW9ucy5kb3dubG9hZEJ1dHRvblRleHQ/YShcIjxkaXYvPlwiLHtjbGFzczpcImpCb3gtaW1hZ2UtZG93bmxvYWQtYnV0dG9uLXRleHRcIn0pLmh0bWwodGhpcy5vcHRpb25zLmRvd25sb2FkQnV0dG9uVGV4dCk6bnVsbCkuYXBwZW5kKGEoXCI8ZGl2Lz5cIix7Y2xhc3M6XCJqQm94LWltYWdlLWRvd25sb2FkLWJ1dHRvbi1pY29uXCJ9KSkub24oXCJjbGljayB0YXBcIixmdW5jdGlvbigpe3ZhciB0O3Q9dGhpcy5pbWFnZXNbdGhpcy5jdXJyZW50SW1hZ2UuZ2FsbGVyeV1bdGhpcy5jdXJyZW50SW1hZ2UuaWRdLmRvd25sb2FkVXJsfHx0aGlzLndyYXBwZXIuZmluZChcIi5qQm94LWltYWdlLVwiK3RoaXMuY3VycmVudEltYWdlLmdhbGxlcnkrXCItY3VycmVudFwiKVswXS5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2Uuc2xpY2UoNCwtMSkucmVwbGFjZSgvW1wiJ10vZyxcIlwiKSx0aGlzLmRvd25sb2FkSW1hZ2UodCl9LmJpbmQodGhpcykpKSx0aGlzLm9wdGlvbnMuaW1hZ2VDb3VudGVyJiYodGhpcy5pbWFnZUNvdW50ZXI9YShcIjxkaXYvPlwiLHtjbGFzczpcImpCb3gtaW1hZ2UtY291bnRlci1jb250YWluZXJcIn0pLmluc2VydEFmdGVyKHRoaXMuaW1hZ2VMYWJlbENvbnRhaW5lciksdGhpcy5pbWFnZUNvdW50ZXIuYXBwZW5kKGEoXCI8c3Bhbi8+XCIse2NsYXNzOlwiakJveC1pbWFnZS1jb3VudGVyLWN1cnJlbnRcIn0pKS5hcHBlbmQoYShcIjxzcGFuLz5cIikuaHRtbCh0aGlzLm9wdGlvbnMuaW1hZ2VDb3VudGVyU2VwYXJhdG9yKSkuYXBwZW5kKGEoXCI8c3Bhbi8+XCIse2NsYXNzOlwiakJveC1pbWFnZS1jb3VudGVyLWFsbFwifSkpKX0sX29uT3BlbjpmdW5jdGlvbigpe2EoZG9jdW1lbnQpLm9uKFwia2V5dXAuakJveC1JbWFnZS1cIit0aGlzLmlkLGZ1bmN0aW9uKHQpezM3PT10LmtleUNvZGUmJnRoaXMuc2hvd0ltYWdlKFwicHJldlwiKSwzOT09dC5rZXlDb2RlJiZ0aGlzLnNob3dJbWFnZShcIm5leHRcIil9LmJpbmQodGhpcykpLHRoaXMuc2hvd0ltYWdlKFwib3BlblwiKX0sX29uQ2xvc2U6ZnVuY3Rpb24oKXthKGRvY3VtZW50KS5vZmYoXCJrZXl1cC5qQm94LUltYWdlLVwiK3RoaXMuaWQpfSxfb25DbG9zZUNvbXBsZXRlOmZ1bmN0aW9uKCl7dGhpcy53cmFwcGVyLmZpbmQoXCIuakJveC1pbWFnZS1jb250YWluZXJcIikuY3NzKFwib3BhY2l0eVwiLDApfX0pfWZ1bmN0aW9uIGpCb3hOb3RpY2VXcmFwcGVyKHQsYSl7bmV3IHQucGx1Z2luKFwiTm90aWNlXCIse2NvbG9yOm51bGwsc3RhY2s6ITAsc3RhY2tTcGFjaW5nOjEwLGF1dG9DbG9zZTo2ZTMsYXR0cmlidXRlczp7eDpcInJpZ2h0XCIseTpcInRvcFwifSxwb3NpdGlvbjp7eDoxNSx5OjE1fSxyZXNwb25zaXZlUG9zaXRpb25zOns1MDA6e3g6NSx5OjV9LDc2ODp7eDoxMCx5OjEwfX0sdGFyZ2V0OndpbmRvdyxmaXhlZDohMCxhbmltYXRpb246XCJ6b29tSW5cIixjbG9zZU9uQ2xpY2s6XCJib3hcIix6SW5kZXg6MTJlMyxfb25Jbml0OmZ1bmN0aW9uKCl7dGhpcy5kZWZhdWx0Tm90aWNlUG9zaXRpb249YS5leHRlbmQoe30sdGhpcy5vcHRpb25zLnBvc2l0aW9uKSx0aGlzLl9hZGp1c3ROb3RpY2VQb3NpdG9uPWZ1bmN0aW9uKCl7dmFyIHQ9YSh3aW5kb3cpLG89dC53aWR0aCgpO3QuaGVpZ2h0KCk7dGhpcy5vcHRpb25zLnBvc2l0aW9uPWEuZXh0ZW5kKHt9LHRoaXMuZGVmYXVsdE5vdGljZVBvc2l0aW9uKSxhLmVhY2godGhpcy5vcHRpb25zLnJlc3BvbnNpdmVQb3NpdGlvbnMsZnVuY3Rpb24odCxpKXtpZihvPD10KXJldHVybiB0aGlzLm9wdGlvbnMucG9zaXRpb249aSwhMX0uYmluZCh0aGlzKSksdGhpcy5vcHRpb25zLmFkanVzdERpc3RhbmNlPXt0b3A6dGhpcy5vcHRpb25zLnBvc2l0aW9uLnkscmlnaHQ6dGhpcy5vcHRpb25zLnBvc2l0aW9uLngsYm90dG9tOnRoaXMub3B0aW9ucy5wb3NpdGlvbi55LGxlZnQ6dGhpcy5vcHRpb25zLnBvc2l0aW9uLnh9fSx0aGlzLm9wdGlvbnMuY29udGVudCBpbnN0YW5jZW9mIGEmJih0aGlzLm9wdGlvbnMuY29udGVudD10aGlzLm9wdGlvbnMuY29udGVudC5jbG9uZSgpLmF0dHIoXCJpZFwiLFwiXCIpKSxhKHdpbmRvdykub24oXCJyZXNpemUucmVzcG9uc2l2ZWpCb3hOb3RpY2UtXCIrdGhpcy5pZCxmdW5jdGlvbih0KXt0aGlzLmlzT3BlbiYmdGhpcy5fYWRqdXN0Tm90aWNlUG9zaXRvbigpfS5iaW5kKHRoaXMpKSx0aGlzLm9wZW4oKX0sX29uQ3JlYXRlZDpmdW5jdGlvbigpe3RoaXMud3JhcHBlci5hZGRDbGFzcyhcImpCb3gtTm90aWNlLWNvbG9yIGpCb3gtTm90aWNlLVwiKyh0aGlzLm9wdGlvbnMuY29sb3J8fFwiZ3JheVwiKSksdGhpcy53cmFwcGVyLmRhdGEoXCJqQm94LU5vdGljZS1wb3NpdGlvblwiLHRoaXMub3B0aW9ucy5hdHRyaWJ1dGVzLngrXCItXCIrdGhpcy5vcHRpb25zLmF0dHJpYnV0ZXMueSl9LF9vbk9wZW46ZnVuY3Rpb24oKXt0aGlzLm9wdGlvbnMuc3RhY2t8fCh0aGlzLl9hZGp1c3ROb3RpY2VQb3NpdG9uKCksYS5lYWNoKGEoXCIuakJveC1Ob3RpY2VcIiksZnVuY3Rpb24odCxpKXsoaT1hKGkpKS5hdHRyKFwiaWRcIikhPXRoaXMuaWQmJmkuZGF0YShcImpCb3gtTm90aWNlLXBvc2l0aW9uXCIpPT10aGlzLm9wdGlvbnMuYXR0cmlidXRlcy54K1wiLVwiK3RoaXMub3B0aW9ucy5hdHRyaWJ1dGVzLnkmJih0aGlzLm9wdGlvbnMuc3RhY2t8fGkuZGF0YShcImpCb3hcIikuY2xvc2Uoe2lnbm9yZURlbGF5OiEwfSkpfS5iaW5kKHRoaXMpKSl9LF9vblBvc2l0aW9uOmZ1bmN0aW9uKCl7dmFyIHQscz17fTtmb3IodCBpbiBhLmVhY2goYShcIi5qQm94LU5vdGljZVwiKSxmdW5jdGlvbih0LGkpe3ZhciBvPShpPWEoaSkpLmRhdGEoXCJqQm94LU5vdGljZS1wb3NpdGlvblwiKTtzW29dfHwoc1tvXT1bXSksc1tvXS5wdXNoKGkpfSkscyl7dmFyIGk9dC5zcGxpdChcIi1cIilbMV07c1t0XS5yZXZlcnNlKCk7dmFyIG8sZT0wO2ZvcihvIGluIHNbdF0pe3ZhciBuPWEoc1t0XVtvXSk7bi5jc3MoXCJtYXJnaW4tXCIraSxlKSxlKz1uLm91dGVySGVpZ2h0KCkrdGhpcy5vcHRpb25zLnN0YWNrU3BhY2luZ319fSxfb25DbG9zZUNvbXBsZXRlOmZ1bmN0aW9uKCl7dGhpcy5kZXN0cm95KCksdGhpcy5vcHRpb25zLl9vblBvc2l0aW9uLmJpbmQodGhpcykuY2FsbCgpfX0pfSFmdW5jdGlvbihpLG8pe1wiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoW1wianF1ZXJ5XCJdLGZ1bmN0aW9uKHQpe3JldHVybiBpLmpCb3g9byh0KX0pOlwib2JqZWN0XCI9PXR5cGVvZiBtb2R1bGUmJm1vZHVsZS5leHBvcnRzP21vZHVsZS5leHBvcnRzPWkuakJveD1vKHJlcXVpcmUoXCJqcXVlcnlcIikpOmkuakJveD1vKGkualF1ZXJ5KX0odGhpcyxmdW5jdGlvbih0KXt2YXIgaT1qQm94V3JhcHBlcih0KTt0cnl7dm9pZCAwIT09akJveENvbmZpcm1XcmFwcGVyJiZqQm94Q29uZmlybVdyYXBwZXImJmpCb3hDb25maXJtV3JhcHBlcihpLHQpfWNhdGNoKHQpe2NvbnNvbGUuZXJyb3IodCl9dHJ5e3ZvaWQgMCE9PWpCb3hJbWFnZVdyYXBwZXImJmpCb3hJbWFnZVdyYXBwZXImJmpCb3hJbWFnZVdyYXBwZXIoaSx0KX1jYXRjaCh0KXtjb25zb2xlLmVycm9yKHQpfXRyeXt2b2lkIDAhPT1qQm94Tm90aWNlV3JhcHBlciYmakJveE5vdGljZVdyYXBwZXImJmpCb3hOb3RpY2VXcmFwcGVyKGksdCl9Y2F0Y2godCl7Y29uc29sZS5lcnJvcih0KX1yZXR1cm4gaX0pOyIsIi8qIVxuICogalF1ZXJ5IEphdmFTY3JpcHQgTGlicmFyeSB2My42LjBcbiAqIGh0dHBzOi8vanF1ZXJ5LmNvbS9cbiAqXG4gKiBJbmNsdWRlcyBTaXp6bGUuanNcbiAqIGh0dHBzOi8vc2l6emxlanMuY29tL1xuICpcbiAqIENvcHlyaWdodCBPcGVuSlMgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2VcbiAqIGh0dHBzOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogRGF0ZTogMjAyMS0wMy0wMlQxNzowOFpcbiAqL1xuKCBmdW5jdGlvbiggZ2xvYmFsLCBmYWN0b3J5ICkge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXG5cdGlmICggdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHQvLyBGb3IgQ29tbW9uSlMgYW5kIENvbW1vbkpTLWxpa2UgZW52aXJvbm1lbnRzIHdoZXJlIGEgcHJvcGVyIGB3aW5kb3dgXG5cdFx0Ly8gaXMgcHJlc2VudCwgZXhlY3V0ZSB0aGUgZmFjdG9yeSBhbmQgZ2V0IGpRdWVyeS5cblx0XHQvLyBGb3IgZW52aXJvbm1lbnRzIHRoYXQgZG8gbm90IGhhdmUgYSBgd2luZG93YCB3aXRoIGEgYGRvY3VtZW50YFxuXHRcdC8vIChzdWNoIGFzIE5vZGUuanMpLCBleHBvc2UgYSBmYWN0b3J5IGFzIG1vZHVsZS5leHBvcnRzLlxuXHRcdC8vIFRoaXMgYWNjZW50dWF0ZXMgdGhlIG5lZWQgZm9yIHRoZSBjcmVhdGlvbiBvZiBhIHJlYWwgYHdpbmRvd2AuXG5cdFx0Ly8gZS5nLiB2YXIgalF1ZXJ5ID0gcmVxdWlyZShcImpxdWVyeVwiKSh3aW5kb3cpO1xuXHRcdC8vIFNlZSB0aWNrZXQgIzE0NTQ5IGZvciBtb3JlIGluZm8uXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBnbG9iYWwuZG9jdW1lbnQgP1xuXHRcdFx0ZmFjdG9yeSggZ2xvYmFsLCB0cnVlICkgOlxuXHRcdFx0ZnVuY3Rpb24oIHcgKSB7XG5cdFx0XHRcdGlmICggIXcuZG9jdW1lbnQgKSB7XG5cdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCBcImpRdWVyeSByZXF1aXJlcyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1lbnRcIiApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBmYWN0b3J5KCB3ICk7XG5cdFx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdGZhY3RvcnkoIGdsb2JhbCApO1xuXHR9XG5cbi8vIFBhc3MgdGhpcyBpZiB3aW5kb3cgaXMgbm90IGRlZmluZWQgeWV0XG59ICkoIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0aGlzLCBmdW5jdGlvbiggd2luZG93LCBub0dsb2JhbCApIHtcblxuLy8gRWRnZSA8PSAxMiAtIDEzKywgRmlyZWZveCA8PTE4IC0gNDUrLCBJRSAxMCAtIDExLCBTYWZhcmkgNS4xIC0gOSssIGlPUyA2IC0gOS4xXG4vLyB0aHJvdyBleGNlcHRpb25zIHdoZW4gbm9uLXN0cmljdCBjb2RlIChlLmcuLCBBU1AuTkVUIDQuNSkgYWNjZXNzZXMgc3RyaWN0IG1vZGVcbi8vIGFyZ3VtZW50cy5jYWxsZWUuY2FsbGVyICh0cmFjLTEzMzM1KS4gQnV0IGFzIG9mIGpRdWVyeSAzLjAgKDIwMTYpLCBzdHJpY3QgbW9kZSBzaG91bGQgYmUgY29tbW9uXG4vLyBlbm91Z2ggdGhhdCBhbGwgc3VjaCBhdHRlbXB0cyBhcmUgZ3VhcmRlZCBpbiBhIHRyeSBibG9jay5cblwidXNlIHN0cmljdFwiO1xuXG52YXIgYXJyID0gW107XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjtcblxudmFyIHNsaWNlID0gYXJyLnNsaWNlO1xuXG52YXIgZmxhdCA9IGFyci5mbGF0ID8gZnVuY3Rpb24oIGFycmF5ICkge1xuXHRyZXR1cm4gYXJyLmZsYXQuY2FsbCggYXJyYXkgKTtcbn0gOiBmdW5jdGlvbiggYXJyYXkgKSB7XG5cdHJldHVybiBhcnIuY29uY2F0LmFwcGx5KCBbXSwgYXJyYXkgKTtcbn07XG5cblxudmFyIHB1c2ggPSBhcnIucHVzaDtcblxudmFyIGluZGV4T2YgPSBhcnIuaW5kZXhPZjtcblxudmFyIGNsYXNzMnR5cGUgPSB7fTtcblxudmFyIHRvU3RyaW5nID0gY2xhc3MydHlwZS50b1N0cmluZztcblxudmFyIGhhc093biA9IGNsYXNzMnR5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBmblRvU3RyaW5nID0gaGFzT3duLnRvU3RyaW5nO1xuXG52YXIgT2JqZWN0RnVuY3Rpb25TdHJpbmcgPSBmblRvU3RyaW5nLmNhbGwoIE9iamVjdCApO1xuXG52YXIgc3VwcG9ydCA9IHt9O1xuXG52YXIgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIGlzRnVuY3Rpb24oIG9iaiApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PTU3LCBGaXJlZm94IDw9NTJcblx0XHQvLyBJbiBzb21lIGJyb3dzZXJzLCB0eXBlb2YgcmV0dXJucyBcImZ1bmN0aW9uXCIgZm9yIEhUTUwgPG9iamVjdD4gZWxlbWVudHNcblx0XHQvLyAoaS5lLiwgYHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcIm9iamVjdFwiICkgPT09IFwiZnVuY3Rpb25cImApLlxuXHRcdC8vIFdlIGRvbid0IHdhbnQgdG8gY2xhc3NpZnkgKmFueSogRE9NIG5vZGUgYXMgYSBmdW5jdGlvbi5cblx0XHQvLyBTdXBwb3J0OiBRdFdlYiA8PTMuOC41LCBXZWJLaXQgPD01MzQuMzQsIHdraHRtbHRvcGRmIHRvb2wgPD0wLjEyLjVcblx0XHQvLyBQbHVzIGZvciBvbGQgV2ViS2l0LCB0eXBlb2YgcmV0dXJucyBcImZ1bmN0aW9uXCIgZm9yIEhUTUwgY29sbGVjdGlvbnNcblx0XHQvLyAoZS5nLiwgYHR5cGVvZiBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImRpdlwiKSA9PT0gXCJmdW5jdGlvblwiYCkuIChnaC00NzU2KVxuXHRcdHJldHVybiB0eXBlb2Ygb2JqID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIG9iai5ub2RlVHlwZSAhPT0gXCJudW1iZXJcIiAmJlxuXHRcdFx0dHlwZW9mIG9iai5pdGVtICE9PSBcImZ1bmN0aW9uXCI7XG5cdH07XG5cblxudmFyIGlzV2luZG93ID0gZnVuY3Rpb24gaXNXaW5kb3coIG9iaiApIHtcblx0XHRyZXR1cm4gb2JqICE9IG51bGwgJiYgb2JqID09PSBvYmoud2luZG93O1xuXHR9O1xuXG5cbnZhciBkb2N1bWVudCA9IHdpbmRvdy5kb2N1bWVudDtcblxuXG5cblx0dmFyIHByZXNlcnZlZFNjcmlwdEF0dHJpYnV0ZXMgPSB7XG5cdFx0dHlwZTogdHJ1ZSxcblx0XHRzcmM6IHRydWUsXG5cdFx0bm9uY2U6IHRydWUsXG5cdFx0bm9Nb2R1bGU6IHRydWVcblx0fTtcblxuXHRmdW5jdGlvbiBET01FdmFsKCBjb2RlLCBub2RlLCBkb2MgKSB7XG5cdFx0ZG9jID0gZG9jIHx8IGRvY3VtZW50O1xuXG5cdFx0dmFyIGksIHZhbCxcblx0XHRcdHNjcmlwdCA9IGRvYy5jcmVhdGVFbGVtZW50KCBcInNjcmlwdFwiICk7XG5cblx0XHRzY3JpcHQudGV4dCA9IGNvZGU7XG5cdFx0aWYgKCBub2RlICkge1xuXHRcdFx0Zm9yICggaSBpbiBwcmVzZXJ2ZWRTY3JpcHRBdHRyaWJ1dGVzICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggNjQrLCBFZGdlIDE4K1xuXHRcdFx0XHQvLyBTb21lIGJyb3dzZXJzIGRvbid0IHN1cHBvcnQgdGhlIFwibm9uY2VcIiBwcm9wZXJ0eSBvbiBzY3JpcHRzLlxuXHRcdFx0XHQvLyBPbiB0aGUgb3RoZXIgaGFuZCwganVzdCB1c2luZyBgZ2V0QXR0cmlidXRlYCBpcyBub3QgZW5vdWdoIGFzXG5cdFx0XHRcdC8vIHRoZSBgbm9uY2VgIGF0dHJpYnV0ZSBpcyByZXNldCB0byBhbiBlbXB0eSBzdHJpbmcgd2hlbmV2ZXIgaXRcblx0XHRcdFx0Ly8gYmVjb21lcyBicm93c2luZy1jb250ZXh0IGNvbm5lY3RlZC5cblx0XHRcdFx0Ly8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS93aGF0d2cvaHRtbC9pc3N1ZXMvMjM2OVxuXHRcdFx0XHQvLyBTZWUgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jbm9uY2UtYXR0cmlidXRlc1xuXHRcdFx0XHQvLyBUaGUgYG5vZGUuZ2V0QXR0cmlidXRlYCBjaGVjayB3YXMgYWRkZWQgZm9yIHRoZSBzYWtlIG9mXG5cdFx0XHRcdC8vIGBqUXVlcnkuZ2xvYmFsRXZhbGAgc28gdGhhdCBpdCBjYW4gZmFrZSBhIG5vbmNlLWNvbnRhaW5pbmcgbm9kZVxuXHRcdFx0XHQvLyB2aWEgYW4gb2JqZWN0LlxuXHRcdFx0XHR2YWwgPSBub2RlWyBpIF0gfHwgbm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoIGkgKTtcblx0XHRcdFx0aWYgKCB2YWwgKSB7XG5cdFx0XHRcdFx0c2NyaXB0LnNldEF0dHJpYnV0ZSggaSwgdmFsICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0ZG9jLmhlYWQuYXBwZW5kQ2hpbGQoIHNjcmlwdCApLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHNjcmlwdCApO1xuXHR9XG5cblxuZnVuY3Rpb24gdG9UeXBlKCBvYmogKSB7XG5cdGlmICggb2JqID09IG51bGwgKSB7XG5cdFx0cmV0dXJuIG9iaiArIFwiXCI7XG5cdH1cblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9Mi4zIG9ubHkgKGZ1bmN0aW9uaXNoIFJlZ0V4cClcblx0cmV0dXJuIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIG9iaiA9PT0gXCJmdW5jdGlvblwiID9cblx0XHRjbGFzczJ0eXBlWyB0b1N0cmluZy5jYWxsKCBvYmogKSBdIHx8IFwib2JqZWN0XCIgOlxuXHRcdHR5cGVvZiBvYmo7XG59XG4vKiBnbG9iYWwgU3ltYm9sICovXG4vLyBEZWZpbmluZyB0aGlzIGdsb2JhbCBpbiAuZXNsaW50cmMuanNvbiB3b3VsZCBjcmVhdGUgYSBkYW5nZXIgb2YgdXNpbmcgdGhlIGdsb2JhbFxuLy8gdW5ndWFyZGVkIGluIGFub3RoZXIgcGxhY2UsIGl0IHNlZW1zIHNhZmVyIHRvIGRlZmluZSBnbG9iYWwgb25seSBmb3IgdGhpcyBtb2R1bGVcblxuXG5cbnZhclxuXHR2ZXJzaW9uID0gXCIzLjYuMFwiLFxuXG5cdC8vIERlZmluZSBhIGxvY2FsIGNvcHkgb2YgalF1ZXJ5XG5cdGpRdWVyeSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHtcblxuXHRcdC8vIFRoZSBqUXVlcnkgb2JqZWN0IGlzIGFjdHVhbGx5IGp1c3QgdGhlIGluaXQgY29uc3RydWN0b3IgJ2VuaGFuY2VkJ1xuXHRcdC8vIE5lZWQgaW5pdCBpZiBqUXVlcnkgaXMgY2FsbGVkIChqdXN0IGFsbG93IGVycm9yIHRvIGJlIHRocm93biBpZiBub3QgaW5jbHVkZWQpXG5cdFx0cmV0dXJuIG5ldyBqUXVlcnkuZm4uaW5pdCggc2VsZWN0b3IsIGNvbnRleHQgKTtcblx0fTtcblxualF1ZXJ5LmZuID0galF1ZXJ5LnByb3RvdHlwZSA9IHtcblxuXHQvLyBUaGUgY3VycmVudCB2ZXJzaW9uIG9mIGpRdWVyeSBiZWluZyB1c2VkXG5cdGpxdWVyeTogdmVyc2lvbixcblxuXHRjb25zdHJ1Y3RvcjogalF1ZXJ5LFxuXG5cdC8vIFRoZSBkZWZhdWx0IGxlbmd0aCBvZiBhIGpRdWVyeSBvYmplY3QgaXMgMFxuXHRsZW5ndGg6IDAsXG5cblx0dG9BcnJheTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHNsaWNlLmNhbGwoIHRoaXMgKTtcblx0fSxcblxuXHQvLyBHZXQgdGhlIE50aCBlbGVtZW50IGluIHRoZSBtYXRjaGVkIGVsZW1lbnQgc2V0IE9SXG5cdC8vIEdldCB0aGUgd2hvbGUgbWF0Y2hlZCBlbGVtZW50IHNldCBhcyBhIGNsZWFuIGFycmF5XG5cdGdldDogZnVuY3Rpb24oIG51bSApIHtcblxuXHRcdC8vIFJldHVybiBhbGwgdGhlIGVsZW1lbnRzIGluIGEgY2xlYW4gYXJyYXlcblx0XHRpZiAoIG51bSA9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIHNsaWNlLmNhbGwoIHRoaXMgKTtcblx0XHR9XG5cblx0XHQvLyBSZXR1cm4ganVzdCB0aGUgb25lIGVsZW1lbnQgZnJvbSB0aGUgc2V0XG5cdFx0cmV0dXJuIG51bSA8IDAgPyB0aGlzWyBudW0gKyB0aGlzLmxlbmd0aCBdIDogdGhpc1sgbnVtIF07XG5cdH0sXG5cblx0Ly8gVGFrZSBhbiBhcnJheSBvZiBlbGVtZW50cyBhbmQgcHVzaCBpdCBvbnRvIHRoZSBzdGFja1xuXHQvLyAocmV0dXJuaW5nIHRoZSBuZXcgbWF0Y2hlZCBlbGVtZW50IHNldClcblx0cHVzaFN0YWNrOiBmdW5jdGlvbiggZWxlbXMgKSB7XG5cblx0XHQvLyBCdWlsZCBhIG5ldyBqUXVlcnkgbWF0Y2hlZCBlbGVtZW50IHNldFxuXHRcdHZhciByZXQgPSBqUXVlcnkubWVyZ2UoIHRoaXMuY29uc3RydWN0b3IoKSwgZWxlbXMgKTtcblxuXHRcdC8vIEFkZCB0aGUgb2xkIG9iamVjdCBvbnRvIHRoZSBzdGFjayAoYXMgYSByZWZlcmVuY2UpXG5cdFx0cmV0LnByZXZPYmplY3QgPSB0aGlzO1xuXG5cdFx0Ly8gUmV0dXJuIHRoZSBuZXdseS1mb3JtZWQgZWxlbWVudCBzZXRcblx0XHRyZXR1cm4gcmV0O1xuXHR9LFxuXG5cdC8vIEV4ZWN1dGUgYSBjYWxsYmFjayBmb3IgZXZlcnkgZWxlbWVudCBpbiB0aGUgbWF0Y2hlZCBzZXQuXG5cdGVhY2g6IGZ1bmN0aW9uKCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmVhY2goIHRoaXMsIGNhbGxiYWNrICk7XG5cdH0sXG5cblx0bWFwOiBmdW5jdGlvbiggY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkubWFwKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgaSApIHtcblx0XHRcdHJldHVybiBjYWxsYmFjay5jYWxsKCBlbGVtLCBpLCBlbGVtICk7XG5cdFx0fSApICk7XG5cdH0sXG5cblx0c2xpY2U6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggc2xpY2UuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApICk7XG5cdH0sXG5cblx0Zmlyc3Q6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVxKCAwICk7XG5cdH0sXG5cblx0bGFzdDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZXEoIC0xICk7XG5cdH0sXG5cblx0ZXZlbjogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkuZ3JlcCggdGhpcywgZnVuY3Rpb24oIF9lbGVtLCBpICkge1xuXHRcdFx0cmV0dXJuICggaSArIDEgKSAlIDI7XG5cdFx0fSApICk7XG5cdH0sXG5cblx0b2RkOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeS5ncmVwKCB0aGlzLCBmdW5jdGlvbiggX2VsZW0sIGkgKSB7XG5cdFx0XHRyZXR1cm4gaSAlIDI7XG5cdFx0fSApICk7XG5cdH0sXG5cblx0ZXE6IGZ1bmN0aW9uKCBpICkge1xuXHRcdHZhciBsZW4gPSB0aGlzLmxlbmd0aCxcblx0XHRcdGogPSAraSArICggaSA8IDAgPyBsZW4gOiAwICk7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqID49IDAgJiYgaiA8IGxlbiA/IFsgdGhpc1sgaiBdIF0gOiBbXSApO1xuXHR9LFxuXG5cdGVuZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMucHJldk9iamVjdCB8fCB0aGlzLmNvbnN0cnVjdG9yKCk7XG5cdH0sXG5cblx0Ly8gRm9yIGludGVybmFsIHVzZSBvbmx5LlxuXHQvLyBCZWhhdmVzIGxpa2UgYW4gQXJyYXkncyBtZXRob2QsIG5vdCBsaWtlIGEgalF1ZXJ5IG1ldGhvZC5cblx0cHVzaDogcHVzaCxcblx0c29ydDogYXJyLnNvcnQsXG5cdHNwbGljZTogYXJyLnNwbGljZVxufTtcblxualF1ZXJ5LmV4dGVuZCA9IGpRdWVyeS5mbi5leHRlbmQgPSBmdW5jdGlvbigpIHtcblx0dmFyIG9wdGlvbnMsIG5hbWUsIHNyYywgY29weSwgY29weUlzQXJyYXksIGNsb25lLFxuXHRcdHRhcmdldCA9IGFyZ3VtZW50c1sgMCBdIHx8IHt9LFxuXHRcdGkgPSAxLFxuXHRcdGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG5cdFx0ZGVlcCA9IGZhbHNlO1xuXG5cdC8vIEhhbmRsZSBhIGRlZXAgY29weSBzaXR1YXRpb25cblx0aWYgKCB0eXBlb2YgdGFyZ2V0ID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRkZWVwID0gdGFyZ2V0O1xuXG5cdFx0Ly8gU2tpcCB0aGUgYm9vbGVhbiBhbmQgdGhlIHRhcmdldFxuXHRcdHRhcmdldCA9IGFyZ3VtZW50c1sgaSBdIHx8IHt9O1xuXHRcdGkrKztcblx0fVxuXG5cdC8vIEhhbmRsZSBjYXNlIHdoZW4gdGFyZ2V0IGlzIGEgc3RyaW5nIG9yIHNvbWV0aGluZyAocG9zc2libGUgaW4gZGVlcCBjb3B5KVxuXHRpZiAoIHR5cGVvZiB0YXJnZXQgIT09IFwib2JqZWN0XCIgJiYgIWlzRnVuY3Rpb24oIHRhcmdldCApICkge1xuXHRcdHRhcmdldCA9IHt9O1xuXHR9XG5cblx0Ly8gRXh0ZW5kIGpRdWVyeSBpdHNlbGYgaWYgb25seSBvbmUgYXJndW1lbnQgaXMgcGFzc2VkXG5cdGlmICggaSA9PT0gbGVuZ3RoICkge1xuXHRcdHRhcmdldCA9IHRoaXM7XG5cdFx0aS0tO1xuXHR9XG5cblx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cblx0XHQvLyBPbmx5IGRlYWwgd2l0aCBub24tbnVsbC91bmRlZmluZWQgdmFsdWVzXG5cdFx0aWYgKCAoIG9wdGlvbnMgPSBhcmd1bWVudHNbIGkgXSApICE9IG51bGwgKSB7XG5cblx0XHRcdC8vIEV4dGVuZCB0aGUgYmFzZSBvYmplY3Rcblx0XHRcdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRcdFx0Y29weSA9IG9wdGlvbnNbIG5hbWUgXTtcblxuXHRcdFx0XHQvLyBQcmV2ZW50IE9iamVjdC5wcm90b3R5cGUgcG9sbHV0aW9uXG5cdFx0XHRcdC8vIFByZXZlbnQgbmV2ZXItZW5kaW5nIGxvb3Bcblx0XHRcdFx0aWYgKCBuYW1lID09PSBcIl9fcHJvdG9fX1wiIHx8IHRhcmdldCA9PT0gY29weSApIHtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFJlY3Vyc2UgaWYgd2UncmUgbWVyZ2luZyBwbGFpbiBvYmplY3RzIG9yIGFycmF5c1xuXHRcdFx0XHRpZiAoIGRlZXAgJiYgY29weSAmJiAoIGpRdWVyeS5pc1BsYWluT2JqZWN0KCBjb3B5ICkgfHxcblx0XHRcdFx0XHQoIGNvcHlJc0FycmF5ID0gQXJyYXkuaXNBcnJheSggY29weSApICkgKSApIHtcblx0XHRcdFx0XHRzcmMgPSB0YXJnZXRbIG5hbWUgXTtcblxuXHRcdFx0XHRcdC8vIEVuc3VyZSBwcm9wZXIgdHlwZSBmb3IgdGhlIHNvdXJjZSB2YWx1ZVxuXHRcdFx0XHRcdGlmICggY29weUlzQXJyYXkgJiYgIUFycmF5LmlzQXJyYXkoIHNyYyApICkge1xuXHRcdFx0XHRcdFx0Y2xvbmUgPSBbXTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCAhY29weUlzQXJyYXkgJiYgIWpRdWVyeS5pc1BsYWluT2JqZWN0KCBzcmMgKSApIHtcblx0XHRcdFx0XHRcdGNsb25lID0ge307XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGNsb25lID0gc3JjO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb3B5SXNBcnJheSA9IGZhbHNlO1xuXG5cdFx0XHRcdFx0Ly8gTmV2ZXIgbW92ZSBvcmlnaW5hbCBvYmplY3RzLCBjbG9uZSB0aGVtXG5cdFx0XHRcdFx0dGFyZ2V0WyBuYW1lIF0gPSBqUXVlcnkuZXh0ZW5kKCBkZWVwLCBjbG9uZSwgY29weSApO1xuXG5cdFx0XHRcdC8vIERvbid0IGJyaW5nIGluIHVuZGVmaW5lZCB2YWx1ZXNcblx0XHRcdFx0fSBlbHNlIGlmICggY29weSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHRhcmdldFsgbmFtZSBdID0gY29weTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIFJldHVybiB0aGUgbW9kaWZpZWQgb2JqZWN0XG5cdHJldHVybiB0YXJnZXQ7XG59O1xuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cblx0Ly8gVW5pcXVlIGZvciBlYWNoIGNvcHkgb2YgalF1ZXJ5IG9uIHRoZSBwYWdlXG5cdGV4cGFuZG86IFwialF1ZXJ5XCIgKyAoIHZlcnNpb24gKyBNYXRoLnJhbmRvbSgpICkucmVwbGFjZSggL1xcRC9nLCBcIlwiICksXG5cblx0Ly8gQXNzdW1lIGpRdWVyeSBpcyByZWFkeSB3aXRob3V0IHRoZSByZWFkeSBtb2R1bGVcblx0aXNSZWFkeTogdHJ1ZSxcblxuXHRlcnJvcjogZnVuY3Rpb24oIG1zZyApIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoIG1zZyApO1xuXHR9LFxuXG5cdG5vb3A6IGZ1bmN0aW9uKCkge30sXG5cblx0aXNQbGFpbk9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcblx0XHR2YXIgcHJvdG8sIEN0b3I7XG5cblx0XHQvLyBEZXRlY3Qgb2J2aW91cyBuZWdhdGl2ZXNcblx0XHQvLyBVc2UgdG9TdHJpbmcgaW5zdGVhZCBvZiBqUXVlcnkudHlwZSB0byBjYXRjaCBob3N0IG9iamVjdHNcblx0XHRpZiAoICFvYmogfHwgdG9TdHJpbmcuY2FsbCggb2JqICkgIT09IFwiW29iamVjdCBPYmplY3RdXCIgKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cHJvdG8gPSBnZXRQcm90byggb2JqICk7XG5cblx0XHQvLyBPYmplY3RzIHdpdGggbm8gcHJvdG90eXBlIChlLmcuLCBgT2JqZWN0LmNyZWF0ZSggbnVsbCApYCkgYXJlIHBsYWluXG5cdFx0aWYgKCAhcHJvdG8gKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyBPYmplY3RzIHdpdGggcHJvdG90eXBlIGFyZSBwbGFpbiBpZmYgdGhleSB3ZXJlIGNvbnN0cnVjdGVkIGJ5IGEgZ2xvYmFsIE9iamVjdCBmdW5jdGlvblxuXHRcdEN0b3IgPSBoYXNPd24uY2FsbCggcHJvdG8sIFwiY29uc3RydWN0b3JcIiApICYmIHByb3RvLmNvbnN0cnVjdG9yO1xuXHRcdHJldHVybiB0eXBlb2YgQ3RvciA9PT0gXCJmdW5jdGlvblwiICYmIGZuVG9TdHJpbmcuY2FsbCggQ3RvciApID09PSBPYmplY3RGdW5jdGlvblN0cmluZztcblx0fSxcblxuXHRpc0VtcHR5T2JqZWN0OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdHZhciBuYW1lO1xuXG5cdFx0Zm9yICggbmFtZSBpbiBvYmogKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9LFxuXG5cdC8vIEV2YWx1YXRlcyBhIHNjcmlwdCBpbiBhIHByb3ZpZGVkIGNvbnRleHQ7IGZhbGxzIGJhY2sgdG8gdGhlIGdsb2JhbCBvbmVcblx0Ly8gaWYgbm90IHNwZWNpZmllZC5cblx0Z2xvYmFsRXZhbDogZnVuY3Rpb24oIGNvZGUsIG9wdGlvbnMsIGRvYyApIHtcblx0XHRET01FdmFsKCBjb2RlLCB7IG5vbmNlOiBvcHRpb25zICYmIG9wdGlvbnMubm9uY2UgfSwgZG9jICk7XG5cdH0sXG5cblx0ZWFjaDogZnVuY3Rpb24oIG9iaiwgY2FsbGJhY2sgKSB7XG5cdFx0dmFyIGxlbmd0aCwgaSA9IDA7XG5cblx0XHRpZiAoIGlzQXJyYXlMaWtlKCBvYmogKSApIHtcblx0XHRcdGxlbmd0aCA9IG9iai5sZW5ndGg7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0aWYgKCBjYWxsYmFjay5jYWxsKCBvYmpbIGkgXSwgaSwgb2JqWyBpIF0gKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICggaSBpbiBvYmogKSB7XG5cdFx0XHRcdGlmICggY2FsbGJhY2suY2FsbCggb2JqWyBpIF0sIGksIG9ialsgaSBdICkgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG9iajtcblx0fSxcblxuXHQvLyByZXN1bHRzIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XG5cdG1ha2VBcnJheTogZnVuY3Rpb24oIGFyciwgcmVzdWx0cyApIHtcblx0XHR2YXIgcmV0ID0gcmVzdWx0cyB8fCBbXTtcblxuXHRcdGlmICggYXJyICE9IG51bGwgKSB7XG5cdFx0XHRpZiAoIGlzQXJyYXlMaWtlKCBPYmplY3QoIGFyciApICkgKSB7XG5cdFx0XHRcdGpRdWVyeS5tZXJnZSggcmV0LFxuXHRcdFx0XHRcdHR5cGVvZiBhcnIgPT09IFwic3RyaW5nXCIgP1xuXHRcdFx0XHRcdFx0WyBhcnIgXSA6IGFyclxuXHRcdFx0XHQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cHVzaC5jYWxsKCByZXQsIGFyciApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0aW5BcnJheTogZnVuY3Rpb24oIGVsZW0sIGFyciwgaSApIHtcblx0XHRyZXR1cm4gYXJyID09IG51bGwgPyAtMSA6IGluZGV4T2YuY2FsbCggYXJyLCBlbGVtLCBpICk7XG5cdH0sXG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5XG5cdC8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXRcblx0bWVyZ2U6IGZ1bmN0aW9uKCBmaXJzdCwgc2Vjb25kICkge1xuXHRcdHZhciBsZW4gPSArc2Vjb25kLmxlbmd0aCxcblx0XHRcdGogPSAwLFxuXHRcdFx0aSA9IGZpcnN0Lmxlbmd0aDtcblxuXHRcdGZvciAoIDsgaiA8IGxlbjsgaisrICkge1xuXHRcdFx0Zmlyc3RbIGkrKyBdID0gc2Vjb25kWyBqIF07XG5cdFx0fVxuXG5cdFx0Zmlyc3QubGVuZ3RoID0gaTtcblxuXHRcdHJldHVybiBmaXJzdDtcblx0fSxcblxuXHRncmVwOiBmdW5jdGlvbiggZWxlbXMsIGNhbGxiYWNrLCBpbnZlcnQgKSB7XG5cdFx0dmFyIGNhbGxiYWNrSW52ZXJzZSxcblx0XHRcdG1hdGNoZXMgPSBbXSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoLFxuXHRcdFx0Y2FsbGJhY2tFeHBlY3QgPSAhaW52ZXJ0O1xuXG5cdFx0Ly8gR28gdGhyb3VnaCB0aGUgYXJyYXksIG9ubHkgc2F2aW5nIHRoZSBpdGVtc1xuXHRcdC8vIHRoYXQgcGFzcyB0aGUgdmFsaWRhdG9yIGZ1bmN0aW9uXG5cdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRjYWxsYmFja0ludmVyc2UgPSAhY2FsbGJhY2soIGVsZW1zWyBpIF0sIGkgKTtcblx0XHRcdGlmICggY2FsbGJhY2tJbnZlcnNlICE9PSBjYWxsYmFja0V4cGVjdCApIHtcblx0XHRcdFx0bWF0Y2hlcy5wdXNoKCBlbGVtc1sgaSBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG1hdGNoZXM7XG5cdH0sXG5cblx0Ly8gYXJnIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XG5cdG1hcDogZnVuY3Rpb24oIGVsZW1zLCBjYWxsYmFjaywgYXJnICkge1xuXHRcdHZhciBsZW5ndGgsIHZhbHVlLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRyZXQgPSBbXTtcblxuXHRcdC8vIEdvIHRocm91Z2ggdGhlIGFycmF5LCB0cmFuc2xhdGluZyBlYWNoIG9mIHRoZSBpdGVtcyB0byB0aGVpciBuZXcgdmFsdWVzXG5cdFx0aWYgKCBpc0FycmF5TGlrZSggZWxlbXMgKSApIHtcblx0XHRcdGxlbmd0aCA9IGVsZW1zLmxlbmd0aDtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHR2YWx1ZSA9IGNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpLCBhcmcgKTtcblxuXHRcdFx0XHRpZiAoIHZhbHVlICE9IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0LnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEdvIHRocm91Z2ggZXZlcnkga2V5IG9uIHRoZSBvYmplY3QsXG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAoIGkgaW4gZWxlbXMgKSB7XG5cdFx0XHRcdHZhbHVlID0gY2FsbGJhY2soIGVsZW1zWyBpIF0sIGksIGFyZyApO1xuXG5cdFx0XHRcdGlmICggdmFsdWUgIT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXQucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZsYXR0ZW4gYW55IG5lc3RlZCBhcnJheXNcblx0XHRyZXR1cm4gZmxhdCggcmV0ICk7XG5cdH0sXG5cblx0Ly8gQSBnbG9iYWwgR1VJRCBjb3VudGVyIGZvciBvYmplY3RzXG5cdGd1aWQ6IDEsXG5cblx0Ly8galF1ZXJ5LnN1cHBvcnQgaXMgbm90IHVzZWQgaW4gQ29yZSBidXQgb3RoZXIgcHJvamVjdHMgYXR0YWNoIHRoZWlyXG5cdC8vIHByb3BlcnRpZXMgdG8gaXQgc28gaXQgbmVlZHMgdG8gZXhpc3QuXG5cdHN1cHBvcnQ6IHN1cHBvcnRcbn0gKTtcblxuaWYgKCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgKSB7XG5cdGpRdWVyeS5mblsgU3ltYm9sLml0ZXJhdG9yIF0gPSBhcnJbIFN5bWJvbC5pdGVyYXRvciBdO1xufVxuXG4vLyBQb3B1bGF0ZSB0aGUgY2xhc3MydHlwZSBtYXBcbmpRdWVyeS5lYWNoKCBcIkJvb2xlYW4gTnVtYmVyIFN0cmluZyBGdW5jdGlvbiBBcnJheSBEYXRlIFJlZ0V4cCBPYmplY3QgRXJyb3IgU3ltYm9sXCIuc3BsaXQoIFwiIFwiICksXG5cdGZ1bmN0aW9uKCBfaSwgbmFtZSApIHtcblx0XHRjbGFzczJ0eXBlWyBcIltvYmplY3QgXCIgKyBuYW1lICsgXCJdXCIgXSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0fSApO1xuXG5mdW5jdGlvbiBpc0FycmF5TGlrZSggb2JqICkge1xuXG5cdC8vIFN1cHBvcnQ6IHJlYWwgaU9TIDguMiBvbmx5IChub3QgcmVwcm9kdWNpYmxlIGluIHNpbXVsYXRvcilcblx0Ly8gYGluYCBjaGVjayB1c2VkIHRvIHByZXZlbnQgSklUIGVycm9yIChnaC0yMTQ1KVxuXHQvLyBoYXNPd24gaXNuJ3QgdXNlZCBoZXJlIGR1ZSB0byBmYWxzZSBuZWdhdGl2ZXNcblx0Ly8gcmVnYXJkaW5nIE5vZGVsaXN0IGxlbmd0aCBpbiBJRVxuXHR2YXIgbGVuZ3RoID0gISFvYmogJiYgXCJsZW5ndGhcIiBpbiBvYmogJiYgb2JqLmxlbmd0aCxcblx0XHR0eXBlID0gdG9UeXBlKCBvYmogKTtcblxuXHRpZiAoIGlzRnVuY3Rpb24oIG9iaiApIHx8IGlzV2luZG93KCBvYmogKSApIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRyZXR1cm4gdHlwZSA9PT0gXCJhcnJheVwiIHx8IGxlbmd0aCA9PT0gMCB8fFxuXHRcdHR5cGVvZiBsZW5ndGggPT09IFwibnVtYmVyXCIgJiYgbGVuZ3RoID4gMCAmJiAoIGxlbmd0aCAtIDEgKSBpbiBvYmo7XG59XG52YXIgU2l6emxlID1cbi8qIVxuICogU2l6emxlIENTUyBTZWxlY3RvciBFbmdpbmUgdjIuMy42XG4gKiBodHRwczovL3NpenpsZWpzLmNvbS9cbiAqXG4gKiBDb3B5cmlnaHQgSlMgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2VcbiAqIGh0dHBzOi8vanMuZm91bmRhdGlvbi9cbiAqXG4gKiBEYXRlOiAyMDIxLTAyLTE2XG4gKi9cbiggZnVuY3Rpb24oIHdpbmRvdyApIHtcbnZhciBpLFxuXHRzdXBwb3J0LFxuXHRFeHByLFxuXHRnZXRUZXh0LFxuXHRpc1hNTCxcblx0dG9rZW5pemUsXG5cdGNvbXBpbGUsXG5cdHNlbGVjdCxcblx0b3V0ZXJtb3N0Q29udGV4dCxcblx0c29ydElucHV0LFxuXHRoYXNEdXBsaWNhdGUsXG5cblx0Ly8gTG9jYWwgZG9jdW1lbnQgdmFyc1xuXHRzZXREb2N1bWVudCxcblx0ZG9jdW1lbnQsXG5cdGRvY0VsZW0sXG5cdGRvY3VtZW50SXNIVE1MLFxuXHRyYnVnZ3lRU0EsXG5cdHJidWdneU1hdGNoZXMsXG5cdG1hdGNoZXMsXG5cdGNvbnRhaW5zLFxuXG5cdC8vIEluc3RhbmNlLXNwZWNpZmljIGRhdGFcblx0ZXhwYW5kbyA9IFwic2l6emxlXCIgKyAxICogbmV3IERhdGUoKSxcblx0cHJlZmVycmVkRG9jID0gd2luZG93LmRvY3VtZW50LFxuXHRkaXJydW5zID0gMCxcblx0ZG9uZSA9IDAsXG5cdGNsYXNzQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHR0b2tlbkNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0Y29tcGlsZXJDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdG5vbm5hdGl2ZVNlbGVjdG9yQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHRzb3J0T3JkZXIgPSBmdW5jdGlvbiggYSwgYiApIHtcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gMDtcblx0fSxcblxuXHQvLyBJbnN0YW5jZSBtZXRob2RzXG5cdGhhc093biA9ICgge30gKS5oYXNPd25Qcm9wZXJ0eSxcblx0YXJyID0gW10sXG5cdHBvcCA9IGFyci5wb3AsXG5cdHB1c2hOYXRpdmUgPSBhcnIucHVzaCxcblx0cHVzaCA9IGFyci5wdXNoLFxuXHRzbGljZSA9IGFyci5zbGljZSxcblxuXHQvLyBVc2UgYSBzdHJpcHBlZC1kb3duIGluZGV4T2YgYXMgaXQncyBmYXN0ZXIgdGhhbiBuYXRpdmVcblx0Ly8gaHR0cHM6Ly9qc3BlcmYuY29tL3Rob3ItaW5kZXhvZi12cy1mb3IvNVxuXHRpbmRleE9mID0gZnVuY3Rpb24oIGxpc3QsIGVsZW0gKSB7XG5cdFx0dmFyIGkgPSAwLFxuXHRcdFx0bGVuID0gbGlzdC5sZW5ndGg7XG5cdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRpZiAoIGxpc3RbIGkgXSA9PT0gZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuIGk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiAtMTtcblx0fSxcblxuXHRib29sZWFucyA9IFwiY2hlY2tlZHxzZWxlY3RlZHxhc3luY3xhdXRvZm9jdXN8YXV0b3BsYXl8Y29udHJvbHN8ZGVmZXJ8ZGlzYWJsZWR8aGlkZGVufFwiICtcblx0XHRcImlzbWFwfGxvb3B8bXVsdGlwbGV8b3BlbnxyZWFkb25seXxyZXF1aXJlZHxzY29wZWRcIixcblxuXHQvLyBSZWd1bGFyIGV4cHJlc3Npb25zXG5cblx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy1zZWxlY3RvcnMvI3doaXRlc3BhY2Vcblx0d2hpdGVzcGFjZSA9IFwiW1xcXFx4MjBcXFxcdFxcXFxyXFxcXG5cXFxcZl1cIixcblxuXHQvLyBodHRwczovL3d3dy53My5vcmcvVFIvY3NzLXN5bnRheC0zLyNpZGVudC10b2tlbi1kaWFncmFtXG5cdGlkZW50aWZpZXIgPSBcIig/OlxcXFxcXFxcW1xcXFxkYS1mQS1GXXsxLDZ9XCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcIj98XFxcXFxcXFxbXlxcXFxyXFxcXG5cXFxcZl18W1xcXFx3LV18W15cXDAtXFxcXHg3Zl0pK1wiLFxuXG5cdC8vIEF0dHJpYnV0ZSBzZWxlY3RvcnM6IGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jYXR0cmlidXRlLXNlbGVjdG9yc1xuXHRhdHRyaWJ1dGVzID0gXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKihcIiArIGlkZW50aWZpZXIgKyBcIikoPzpcIiArIHdoaXRlc3BhY2UgK1xuXG5cdFx0Ly8gT3BlcmF0b3IgKGNhcHR1cmUgMilcblx0XHRcIiooWypeJHwhfl0/PSlcIiArIHdoaXRlc3BhY2UgK1xuXG5cdFx0Ly8gXCJBdHRyaWJ1dGUgdmFsdWVzIG11c3QgYmUgQ1NTIGlkZW50aWZpZXJzIFtjYXB0dXJlIDVdXG5cdFx0Ly8gb3Igc3RyaW5ncyBbY2FwdHVyZSAzIG9yIGNhcHR1cmUgNF1cIlxuXHRcdFwiKig/OicoKD86XFxcXFxcXFwufFteXFxcXFxcXFwnXSkqKSd8XFxcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXFxcXCJdKSopXFxcInwoXCIgKyBpZGVudGlmaWVyICsgXCIpKXwpXCIgK1xuXHRcdHdoaXRlc3BhY2UgKyBcIipcXFxcXVwiLFxuXG5cdHBzZXVkb3MgPSBcIjooXCIgKyBpZGVudGlmaWVyICsgXCIpKD86XFxcXCgoXCIgK1xuXG5cdFx0Ly8gVG8gcmVkdWNlIHRoZSBudW1iZXIgb2Ygc2VsZWN0b3JzIG5lZWRpbmcgdG9rZW5pemUgaW4gdGhlIHByZUZpbHRlciwgcHJlZmVyIGFyZ3VtZW50czpcblx0XHQvLyAxLiBxdW90ZWQgKGNhcHR1cmUgMzsgY2FwdHVyZSA0IG9yIGNhcHR1cmUgNSlcblx0XHRcIignKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcJ10pKiknfFxcXCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFxcXFwiXSkqKVxcXCIpfFwiICtcblxuXHRcdC8vIDIuIHNpbXBsZSAoY2FwdHVyZSA2KVxuXHRcdFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcKClbXFxcXF1dfFwiICsgYXR0cmlidXRlcyArIFwiKSopfFwiICtcblxuXHRcdC8vIDMuIGFueXRoaW5nIGVsc2UgKGNhcHR1cmUgMilcblx0XHRcIi4qXCIgK1xuXHRcdFwiKVxcXFwpfClcIixcblxuXHQvLyBMZWFkaW5nIGFuZCBub24tZXNjYXBlZCB0cmFpbGluZyB3aGl0ZXNwYWNlLCBjYXB0dXJpbmcgc29tZSBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXJzIHByZWNlZGluZyB0aGUgbGF0dGVyXG5cdHJ3aGl0ZXNwYWNlID0gbmV3IFJlZ0V4cCggd2hpdGVzcGFjZSArIFwiK1wiLCBcImdcIiApLFxuXHRydHJpbSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiK3woKD86XnxbXlxcXFxcXFxcXSkoPzpcXFxcXFxcXC4pKilcIiArXG5cdFx0d2hpdGVzcGFjZSArIFwiKyRcIiwgXCJnXCIgKSxcblxuXHRyY29tbWEgPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIiosXCIgKyB3aGl0ZXNwYWNlICsgXCIqXCIgKSxcblx0cmNvbWJpbmF0b3JzID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIqKFs+K35dfFwiICsgd2hpdGVzcGFjZSArIFwiKVwiICsgd2hpdGVzcGFjZSArXG5cdFx0XCIqXCIgKSxcblx0cmRlc2NlbmQgPSBuZXcgUmVnRXhwKCB3aGl0ZXNwYWNlICsgXCJ8PlwiICksXG5cblx0cnBzZXVkbyA9IG5ldyBSZWdFeHAoIHBzZXVkb3MgKSxcblx0cmlkZW50aWZpZXIgPSBuZXcgUmVnRXhwKCBcIl5cIiArIGlkZW50aWZpZXIgKyBcIiRcIiApLFxuXG5cdG1hdGNoRXhwciA9IHtcblx0XHRcIklEXCI6IG5ldyBSZWdFeHAoIFwiXiMoXCIgKyBpZGVudGlmaWVyICsgXCIpXCIgKSxcblx0XHRcIkNMQVNTXCI6IG5ldyBSZWdFeHAoIFwiXlxcXFwuKFwiICsgaWRlbnRpZmllciArIFwiKVwiICksXG5cdFx0XCJUQUdcIjogbmV3IFJlZ0V4cCggXCJeKFwiICsgaWRlbnRpZmllciArIFwifFsqXSlcIiApLFxuXHRcdFwiQVRUUlwiOiBuZXcgUmVnRXhwKCBcIl5cIiArIGF0dHJpYnV0ZXMgKSxcblx0XHRcIlBTRVVET1wiOiBuZXcgUmVnRXhwKCBcIl5cIiArIHBzZXVkb3MgKSxcblx0XHRcIkNISUxEXCI6IG5ldyBSZWdFeHAoIFwiXjoob25seXxmaXJzdHxsYXN0fG50aHxudGgtbGFzdCktKGNoaWxkfG9mLXR5cGUpKD86XFxcXChcIiArXG5cdFx0XHR3aGl0ZXNwYWNlICsgXCIqKGV2ZW58b2RkfCgoWystXXwpKFxcXFxkKilufClcIiArIHdoaXRlc3BhY2UgKyBcIiooPzooWystXXwpXCIgK1xuXHRcdFx0d2hpdGVzcGFjZSArIFwiKihcXFxcZCspfCkpXCIgKyB3aGl0ZXNwYWNlICsgXCIqXFxcXCl8KVwiLCBcImlcIiApLFxuXHRcdFwiYm9vbFwiOiBuZXcgUmVnRXhwKCBcIl4oPzpcIiArIGJvb2xlYW5zICsgXCIpJFwiLCBcImlcIiApLFxuXG5cdFx0Ly8gRm9yIHVzZSBpbiBsaWJyYXJpZXMgaW1wbGVtZW50aW5nIC5pcygpXG5cdFx0Ly8gV2UgdXNlIHRoaXMgZm9yIFBPUyBtYXRjaGluZyBpbiBgc2VsZWN0YFxuXHRcdFwibmVlZHNDb250ZXh0XCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArXG5cdFx0XHRcIipbPit+XXw6KGV2ZW58b2RkfGVxfGd0fGx0fG50aHxmaXJzdHxsYXN0KSg/OlxcXFwoXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcdFwiKigoPzotXFxcXGQpP1xcXFxkKilcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcKXwpKD89W14tXXwkKVwiLCBcImlcIiApXG5cdH0sXG5cblx0cmh0bWwgPSAvSFRNTCQvaSxcblx0cmlucHV0cyA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbikkL2ksXG5cdHJoZWFkZXIgPSAvXmhcXGQkL2ksXG5cblx0cm5hdGl2ZSA9IC9eW157XStcXHtcXHMqXFxbbmF0aXZlIFxcdy8sXG5cblx0Ly8gRWFzaWx5LXBhcnNlYWJsZS9yZXRyaWV2YWJsZSBJRCBvciBUQUcgb3IgQ0xBU1Mgc2VsZWN0b3JzXG5cdHJxdWlja0V4cHIgPSAvXig/OiMoW1xcdy1dKyl8KFxcdyspfFxcLihbXFx3LV0rKSkkLyxcblxuXHRyc2libGluZyA9IC9bK35dLyxcblxuXHQvLyBDU1MgZXNjYXBlc1xuXHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9DU1MyMS9zeW5kYXRhLmh0bWwjZXNjYXBlZC1jaGFyYWN0ZXJzXG5cdHJ1bmVzY2FwZSA9IG5ldyBSZWdFeHAoIFwiXFxcXFxcXFxbXFxcXGRhLWZBLUZdezEsNn1cIiArIHdoaXRlc3BhY2UgKyBcIj98XFxcXFxcXFwoW15cXFxcclxcXFxuXFxcXGZdKVwiLCBcImdcIiApLFxuXHRmdW5lc2NhcGUgPSBmdW5jdGlvbiggZXNjYXBlLCBub25IZXggKSB7XG5cdFx0dmFyIGhpZ2ggPSBcIjB4XCIgKyBlc2NhcGUuc2xpY2UoIDEgKSAtIDB4MTAwMDA7XG5cblx0XHRyZXR1cm4gbm9uSGV4ID9cblxuXHRcdFx0Ly8gU3RyaXAgdGhlIGJhY2tzbGFzaCBwcmVmaXggZnJvbSBhIG5vbi1oZXggZXNjYXBlIHNlcXVlbmNlXG5cdFx0XHRub25IZXggOlxuXG5cdFx0XHQvLyBSZXBsYWNlIGEgaGV4YWRlY2ltYWwgZXNjYXBlIHNlcXVlbmNlIHdpdGggdGhlIGVuY29kZWQgVW5pY29kZSBjb2RlIHBvaW50XG5cdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTExK1xuXHRcdFx0Ly8gRm9yIHZhbHVlcyBvdXRzaWRlIHRoZSBCYXNpYyBNdWx0aWxpbmd1YWwgUGxhbmUgKEJNUCksIG1hbnVhbGx5IGNvbnN0cnVjdCBhXG5cdFx0XHQvLyBzdXJyb2dhdGUgcGFpclxuXHRcdFx0aGlnaCA8IDAgP1xuXHRcdFx0XHRTdHJpbmcuZnJvbUNoYXJDb2RlKCBoaWdoICsgMHgxMDAwMCApIDpcblx0XHRcdFx0U3RyaW5nLmZyb21DaGFyQ29kZSggaGlnaCA+PiAxMCB8IDB4RDgwMCwgaGlnaCAmIDB4M0ZGIHwgMHhEQzAwICk7XG5cdH0sXG5cblx0Ly8gQ1NTIHN0cmluZy9pZGVudGlmaWVyIHNlcmlhbGl6YXRpb25cblx0Ly8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNjb21tb24tc2VyaWFsaXppbmctaWRpb21zXG5cdHJjc3Nlc2NhcGUgPSAvKFtcXDAtXFx4MWZcXHg3Zl18Xi0/XFxkKXxeLSR8W15cXDAtXFx4MWZcXHg3Zi1cXHVGRkZGXFx3LV0vZyxcblx0ZmNzc2VzY2FwZSA9IGZ1bmN0aW9uKCBjaCwgYXNDb2RlUG9pbnQgKSB7XG5cdFx0aWYgKCBhc0NvZGVQb2ludCApIHtcblxuXHRcdFx0Ly8gVSswMDAwIE5VTEwgYmVjb21lcyBVK0ZGRkQgUkVQTEFDRU1FTlQgQ0hBUkFDVEVSXG5cdFx0XHRpZiAoIGNoID09PSBcIlxcMFwiICkge1xuXHRcdFx0XHRyZXR1cm4gXCJcXHVGRkZEXCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbnRyb2wgY2hhcmFjdGVycyBhbmQgKGRlcGVuZGVudCB1cG9uIHBvc2l0aW9uKSBudW1iZXJzIGdldCBlc2NhcGVkIGFzIGNvZGUgcG9pbnRzXG5cdFx0XHRyZXR1cm4gY2guc2xpY2UoIDAsIC0xICkgKyBcIlxcXFxcIiArXG5cdFx0XHRcdGNoLmNoYXJDb2RlQXQoIGNoLmxlbmd0aCAtIDEgKS50b1N0cmluZyggMTYgKSArIFwiIFwiO1xuXHRcdH1cblxuXHRcdC8vIE90aGVyIHBvdGVudGlhbGx5LXNwZWNpYWwgQVNDSUkgY2hhcmFjdGVycyBnZXQgYmFja3NsYXNoLWVzY2FwZWRcblx0XHRyZXR1cm4gXCJcXFxcXCIgKyBjaDtcblx0fSxcblxuXHQvLyBVc2VkIGZvciBpZnJhbWVzXG5cdC8vIFNlZSBzZXREb2N1bWVudCgpXG5cdC8vIFJlbW92aW5nIHRoZSBmdW5jdGlvbiB3cmFwcGVyIGNhdXNlcyBhIFwiUGVybWlzc2lvbiBEZW5pZWRcIlxuXHQvLyBlcnJvciBpbiBJRVxuXHR1bmxvYWRIYW5kbGVyID0gZnVuY3Rpb24oKSB7XG5cdFx0c2V0RG9jdW1lbnQoKTtcblx0fSxcblxuXHRpbkRpc2FibGVkRmllbGRzZXQgPSBhZGRDb21iaW5hdG9yKFxuXHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IHRydWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImZpZWxkc2V0XCI7XG5cdFx0fSxcblx0XHR7IGRpcjogXCJwYXJlbnROb2RlXCIsIG5leHQ6IFwibGVnZW5kXCIgfVxuXHQpO1xuXG4vLyBPcHRpbWl6ZSBmb3IgcHVzaC5hcHBseSggXywgTm9kZUxpc3QgKVxudHJ5IHtcblx0cHVzaC5hcHBseShcblx0XHQoIGFyciA9IHNsaWNlLmNhbGwoIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzICkgKSxcblx0XHRwcmVmZXJyZWREb2MuY2hpbGROb2Rlc1xuXHQpO1xuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4wXG5cdC8vIERldGVjdCBzaWxlbnRseSBmYWlsaW5nIHB1c2guYXBwbHlcblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC1leHByZXNzaW9uc1xuXHRhcnJbIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzLmxlbmd0aCBdLm5vZGVUeXBlO1xufSBjYXRjaCAoIGUgKSB7XG5cdHB1c2ggPSB7IGFwcGx5OiBhcnIubGVuZ3RoID9cblxuXHRcdC8vIExldmVyYWdlIHNsaWNlIGlmIHBvc3NpYmxlXG5cdFx0ZnVuY3Rpb24oIHRhcmdldCwgZWxzICkge1xuXHRcdFx0cHVzaE5hdGl2ZS5hcHBseSggdGFyZ2V0LCBzbGljZS5jYWxsKCBlbHMgKSApO1xuXHRcdH0gOlxuXG5cdFx0Ly8gU3VwcG9ydDogSUU8OVxuXHRcdC8vIE90aGVyd2lzZSBhcHBlbmQgZGlyZWN0bHlcblx0XHRmdW5jdGlvbiggdGFyZ2V0LCBlbHMgKSB7XG5cdFx0XHR2YXIgaiA9IHRhcmdldC5sZW5ndGgsXG5cdFx0XHRcdGkgPSAwO1xuXG5cdFx0XHQvLyBDYW4ndCB0cnVzdCBOb2RlTGlzdC5sZW5ndGhcblx0XHRcdHdoaWxlICggKCB0YXJnZXRbIGorKyBdID0gZWxzWyBpKysgXSApICkge31cblx0XHRcdHRhcmdldC5sZW5ndGggPSBqIC0gMTtcblx0XHR9XG5cdH07XG59XG5cbmZ1bmN0aW9uIFNpenpsZSggc2VsZWN0b3IsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKSB7XG5cdHZhciBtLCBpLCBlbGVtLCBuaWQsIG1hdGNoLCBncm91cHMsIG5ld1NlbGVjdG9yLFxuXHRcdG5ld0NvbnRleHQgPSBjb250ZXh0ICYmIGNvbnRleHQub3duZXJEb2N1bWVudCxcblxuXHRcdC8vIG5vZGVUeXBlIGRlZmF1bHRzIHRvIDksIHNpbmNlIGNvbnRleHQgZGVmYXVsdHMgdG8gZG9jdW1lbnRcblx0XHRub2RlVHlwZSA9IGNvbnRleHQgPyBjb250ZXh0Lm5vZGVUeXBlIDogOTtcblxuXHRyZXN1bHRzID0gcmVzdWx0cyB8fCBbXTtcblxuXHQvLyBSZXR1cm4gZWFybHkgZnJvbSBjYWxscyB3aXRoIGludmFsaWQgc2VsZWN0b3Igb3IgY29udGV4dFxuXHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiB8fCAhc2VsZWN0b3IgfHxcblx0XHRub2RlVHlwZSAhPT0gMSAmJiBub2RlVHlwZSAhPT0gOSAmJiBub2RlVHlwZSAhPT0gMTEgKSB7XG5cblx0XHRyZXR1cm4gcmVzdWx0cztcblx0fVxuXG5cdC8vIFRyeSB0byBzaG9ydGN1dCBmaW5kIG9wZXJhdGlvbnMgKGFzIG9wcG9zZWQgdG8gZmlsdGVycykgaW4gSFRNTCBkb2N1bWVudHNcblx0aWYgKCAhc2VlZCApIHtcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xuXHRcdGNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50O1xuXG5cdFx0aWYgKCBkb2N1bWVudElzSFRNTCApIHtcblxuXHRcdFx0Ly8gSWYgdGhlIHNlbGVjdG9yIGlzIHN1ZmZpY2llbnRseSBzaW1wbGUsIHRyeSB1c2luZyBhIFwiZ2V0KkJ5KlwiIERPTSBtZXRob2Rcblx0XHRcdC8vIChleGNlcHRpbmcgRG9jdW1lbnRGcmFnbWVudCBjb250ZXh0LCB3aGVyZSB0aGUgbWV0aG9kcyBkb24ndCBleGlzdClcblx0XHRcdGlmICggbm9kZVR5cGUgIT09IDExICYmICggbWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICkgKSApIHtcblxuXHRcdFx0XHQvLyBJRCBzZWxlY3RvclxuXHRcdFx0XHRpZiAoICggbSA9IG1hdGNoWyAxIF0gKSApIHtcblxuXHRcdFx0XHRcdC8vIERvY3VtZW50IGNvbnRleHRcblx0XHRcdFx0XHRpZiAoIG5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoIGVsZW0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKCBtICkgKSApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSwgT3BlcmEsIFdlYmtpdFxuXHRcdFx0XHRcdFx0XHQvLyBUT0RPOiBpZGVudGlmeSB2ZXJzaW9uc1xuXHRcdFx0XHRcdFx0XHQvLyBnZXRFbGVtZW50QnlJZCBjYW4gbWF0Y2ggZWxlbWVudHMgYnkgbmFtZSBpbnN0ZWFkIG9mIElEXG5cdFx0XHRcdFx0XHRcdGlmICggZWxlbS5pZCA9PT0gbSApIHtcblx0XHRcdFx0XHRcdFx0XHRyZXN1bHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBFbGVtZW50IGNvbnRleHRcblx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSwgT3BlcmEsIFdlYmtpdFxuXHRcdFx0XHRcdFx0Ly8gVE9ETzogaWRlbnRpZnkgdmVyc2lvbnNcblx0XHRcdFx0XHRcdC8vIGdldEVsZW1lbnRCeUlkIGNhbiBtYXRjaCBlbGVtZW50cyBieSBuYW1lIGluc3RlYWQgb2YgSURcblx0XHRcdFx0XHRcdGlmICggbmV3Q29udGV4dCAmJiAoIGVsZW0gPSBuZXdDb250ZXh0LmdldEVsZW1lbnRCeUlkKCBtICkgKSAmJlxuXHRcdFx0XHRcdFx0XHRjb250YWlucyggY29udGV4dCwgZWxlbSApICYmXG5cdFx0XHRcdFx0XHRcdGVsZW0uaWQgPT09IG0gKSB7XG5cblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBUeXBlIHNlbGVjdG9yXG5cdFx0XHRcdH0gZWxzZSBpZiAoIG1hdGNoWyAyIF0gKSB7XG5cdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggc2VsZWN0b3IgKSApO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXG5cdFx0XHRcdC8vIENsYXNzIHNlbGVjdG9yXG5cdFx0XHRcdH0gZWxzZSBpZiAoICggbSA9IG1hdGNoWyAzIF0gKSAmJiBzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgJiZcblx0XHRcdFx0XHRjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKSB7XG5cblx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoIG0gKSApO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRha2UgYWR2YW50YWdlIG9mIHF1ZXJ5U2VsZWN0b3JBbGxcblx0XHRcdGlmICggc3VwcG9ydC5xc2EgJiZcblx0XHRcdFx0IW5vbm5hdGl2ZVNlbGVjdG9yQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXSAmJlxuXHRcdFx0XHQoICFyYnVnZ3lRU0EgfHwgIXJidWdneVFTQS50ZXN0KCBzZWxlY3RvciApICkgJiZcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA4IG9ubHlcblx0XHRcdFx0Ly8gRXhjbHVkZSBvYmplY3QgZWxlbWVudHNcblx0XHRcdFx0KCBub2RlVHlwZSAhPT0gMSB8fCBjb250ZXh0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgIT09IFwib2JqZWN0XCIgKSApIHtcblxuXHRcdFx0XHRuZXdTZWxlY3RvciA9IHNlbGVjdG9yO1xuXHRcdFx0XHRuZXdDb250ZXh0ID0gY29udGV4dDtcblxuXHRcdFx0XHQvLyBxU0EgY29uc2lkZXJzIGVsZW1lbnRzIG91dHNpZGUgYSBzY29waW5nIHJvb3Qgd2hlbiBldmFsdWF0aW5nIGNoaWxkIG9yXG5cdFx0XHRcdC8vIGRlc2NlbmRhbnQgY29tYmluYXRvcnMsIHdoaWNoIGlzIG5vdCB3aGF0IHdlIHdhbnQuXG5cdFx0XHRcdC8vIEluIHN1Y2ggY2FzZXMsIHdlIHdvcmsgYXJvdW5kIHRoZSBiZWhhdmlvciBieSBwcmVmaXhpbmcgZXZlcnkgc2VsZWN0b3IgaW4gdGhlXG5cdFx0XHRcdC8vIGxpc3Qgd2l0aCBhbiBJRCBzZWxlY3RvciByZWZlcmVuY2luZyB0aGUgc2NvcGUgY29udGV4dC5cblx0XHRcdFx0Ly8gVGhlIHRlY2huaXF1ZSBoYXMgdG8gYmUgdXNlZCBhcyB3ZWxsIHdoZW4gYSBsZWFkaW5nIGNvbWJpbmF0b3IgaXMgdXNlZFxuXHRcdFx0XHQvLyBhcyBzdWNoIHNlbGVjdG9ycyBhcmUgbm90IHJlY29nbml6ZWQgYnkgcXVlcnlTZWxlY3RvckFsbC5cblx0XHRcdFx0Ly8gVGhhbmtzIHRvIEFuZHJldyBEdXBvbnQgZm9yIHRoaXMgdGVjaG5pcXVlLlxuXHRcdFx0XHRpZiAoIG5vZGVUeXBlID09PSAxICYmXG5cdFx0XHRcdFx0KCByZGVzY2VuZC50ZXN0KCBzZWxlY3RvciApIHx8IHJjb21iaW5hdG9ycy50ZXN0KCBzZWxlY3RvciApICkgKSB7XG5cblx0XHRcdFx0XHQvLyBFeHBhbmQgY29udGV4dCBmb3Igc2libGluZyBzZWxlY3RvcnNcblx0XHRcdFx0XHRuZXdDb250ZXh0ID0gcnNpYmxpbmcudGVzdCggc2VsZWN0b3IgKSAmJiB0ZXN0Q29udGV4dCggY29udGV4dC5wYXJlbnROb2RlICkgfHxcblx0XHRcdFx0XHRcdGNvbnRleHQ7XG5cblx0XHRcdFx0XHQvLyBXZSBjYW4gdXNlIDpzY29wZSBpbnN0ZWFkIG9mIHRoZSBJRCBoYWNrIGlmIHRoZSBicm93c2VyXG5cdFx0XHRcdFx0Ly8gc3VwcG9ydHMgaXQgJiBpZiB3ZSdyZSBub3QgY2hhbmdpbmcgdGhlIGNvbnRleHQuXG5cdFx0XHRcdFx0aWYgKCBuZXdDb250ZXh0ICE9PSBjb250ZXh0IHx8ICFzdXBwb3J0LnNjb3BlICkge1xuXG5cdFx0XHRcdFx0XHQvLyBDYXB0dXJlIHRoZSBjb250ZXh0IElELCBzZXR0aW5nIGl0IGZpcnN0IGlmIG5lY2Vzc2FyeVxuXHRcdFx0XHRcdFx0aWYgKCAoIG5pZCA9IGNvbnRleHQuZ2V0QXR0cmlidXRlKCBcImlkXCIgKSApICkge1xuXHRcdFx0XHRcdFx0XHRuaWQgPSBuaWQucmVwbGFjZSggcmNzc2VzY2FwZSwgZmNzc2VzY2FwZSApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Y29udGV4dC5zZXRBdHRyaWJ1dGUoIFwiaWRcIiwgKCBuaWQgPSBleHBhbmRvICkgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBQcmVmaXggZXZlcnkgc2VsZWN0b3IgaW4gdGhlIGxpc3Rcblx0XHRcdFx0XHRncm91cHMgPSB0b2tlbml6ZSggc2VsZWN0b3IgKTtcblx0XHRcdFx0XHRpID0gZ3JvdXBzLmxlbmd0aDtcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdGdyb3Vwc1sgaSBdID0gKCBuaWQgPyBcIiNcIiArIG5pZCA6IFwiOnNjb3BlXCIgKSArIFwiIFwiICtcblx0XHRcdFx0XHRcdFx0dG9TZWxlY3RvciggZ3JvdXBzWyBpIF0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0bmV3U2VsZWN0b3IgPSBncm91cHMuam9pbiggXCIsXCIgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cyxcblx0XHRcdFx0XHRcdG5ld0NvbnRleHQucXVlcnlTZWxlY3RvckFsbCggbmV3U2VsZWN0b3IgKVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdH0gY2F0Y2ggKCBxc2FFcnJvciApIHtcblx0XHRcdFx0XHRub25uYXRpdmVTZWxlY3RvckNhY2hlKCBzZWxlY3RvciwgdHJ1ZSApO1xuXHRcdFx0XHR9IGZpbmFsbHkge1xuXHRcdFx0XHRcdGlmICggbmlkID09PSBleHBhbmRvICkge1xuXHRcdFx0XHRcdFx0Y29udGV4dC5yZW1vdmVBdHRyaWJ1dGUoIFwiaWRcIiApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIEFsbCBvdGhlcnNcblx0cmV0dXJuIHNlbGVjdCggc2VsZWN0b3IucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGtleS12YWx1ZSBjYWNoZXMgb2YgbGltaXRlZCBzaXplXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb24oc3RyaW5nLCBvYmplY3QpfSBSZXR1cm5zIHRoZSBPYmplY3QgZGF0YSBhZnRlciBzdG9yaW5nIGl0IG9uIGl0c2VsZiB3aXRoXG4gKlx0cHJvcGVydHkgbmFtZSB0aGUgKHNwYWNlLXN1ZmZpeGVkKSBzdHJpbmcgYW5kIChpZiB0aGUgY2FjaGUgaXMgbGFyZ2VyIHRoYW4gRXhwci5jYWNoZUxlbmd0aClcbiAqXHRkZWxldGluZyB0aGUgb2xkZXN0IGVudHJ5XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUNhY2hlKCkge1xuXHR2YXIga2V5cyA9IFtdO1xuXG5cdGZ1bmN0aW9uIGNhY2hlKCBrZXksIHZhbHVlICkge1xuXG5cdFx0Ly8gVXNlIChrZXkgKyBcIiBcIikgdG8gYXZvaWQgY29sbGlzaW9uIHdpdGggbmF0aXZlIHByb3RvdHlwZSBwcm9wZXJ0aWVzIChzZWUgSXNzdWUgIzE1Nylcblx0XHRpZiAoIGtleXMucHVzaCgga2V5ICsgXCIgXCIgKSA+IEV4cHIuY2FjaGVMZW5ndGggKSB7XG5cblx0XHRcdC8vIE9ubHkga2VlcCB0aGUgbW9zdCByZWNlbnQgZW50cmllc1xuXHRcdFx0ZGVsZXRlIGNhY2hlWyBrZXlzLnNoaWZ0KCkgXTtcblx0XHR9XG5cdFx0cmV0dXJuICggY2FjaGVbIGtleSArIFwiIFwiIF0gPSB2YWx1ZSApO1xuXHR9XG5cdHJldHVybiBjYWNoZTtcbn1cblxuLyoqXG4gKiBNYXJrIGEgZnVuY3Rpb24gZm9yIHNwZWNpYWwgdXNlIGJ5IFNpenpsZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIG1hcmtcbiAqL1xuZnVuY3Rpb24gbWFya0Z1bmN0aW9uKCBmbiApIHtcblx0Zm5bIGV4cGFuZG8gXSA9IHRydWU7XG5cdHJldHVybiBmbjtcbn1cblxuLyoqXG4gKiBTdXBwb3J0IHRlc3RpbmcgdXNpbmcgYW4gZWxlbWVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gUGFzc2VkIHRoZSBjcmVhdGVkIGVsZW1lbnQgYW5kIHJldHVybnMgYSBib29sZWFuIHJlc3VsdFxuICovXG5mdW5jdGlvbiBhc3NlcnQoIGZuICkge1xuXHR2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImZpZWxkc2V0XCIgKTtcblxuXHR0cnkge1xuXHRcdHJldHVybiAhIWZuKCBlbCApO1xuXHR9IGNhdGNoICggZSApIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH0gZmluYWxseSB7XG5cblx0XHQvLyBSZW1vdmUgZnJvbSBpdHMgcGFyZW50IGJ5IGRlZmF1bHRcblx0XHRpZiAoIGVsLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRlbC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBlbCApO1xuXHRcdH1cblxuXHRcdC8vIHJlbGVhc2UgbWVtb3J5IGluIElFXG5cdFx0ZWwgPSBudWxsO1xuXHR9XG59XG5cbi8qKlxuICogQWRkcyB0aGUgc2FtZSBoYW5kbGVyIGZvciBhbGwgb2YgdGhlIHNwZWNpZmllZCBhdHRyc1xuICogQHBhcmFtIHtTdHJpbmd9IGF0dHJzIFBpcGUtc2VwYXJhdGVkIGxpc3Qgb2YgYXR0cmlidXRlc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlciBUaGUgbWV0aG9kIHRoYXQgd2lsbCBiZSBhcHBsaWVkXG4gKi9cbmZ1bmN0aW9uIGFkZEhhbmRsZSggYXR0cnMsIGhhbmRsZXIgKSB7XG5cdHZhciBhcnIgPSBhdHRycy5zcGxpdCggXCJ8XCIgKSxcblx0XHRpID0gYXJyLmxlbmd0aDtcblxuXHR3aGlsZSAoIGktLSApIHtcblx0XHRFeHByLmF0dHJIYW5kbGVbIGFyclsgaSBdIF0gPSBoYW5kbGVyO1xuXHR9XG59XG5cbi8qKlxuICogQ2hlY2tzIGRvY3VtZW50IG9yZGVyIG9mIHR3byBzaWJsaW5nc1xuICogQHBhcmFtIHtFbGVtZW50fSBhXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFJldHVybnMgbGVzcyB0aGFuIDAgaWYgYSBwcmVjZWRlcyBiLCBncmVhdGVyIHRoYW4gMCBpZiBhIGZvbGxvd3MgYlxuICovXG5mdW5jdGlvbiBzaWJsaW5nQ2hlY2soIGEsIGIgKSB7XG5cdHZhciBjdXIgPSBiICYmIGEsXG5cdFx0ZGlmZiA9IGN1ciAmJiBhLm5vZGVUeXBlID09PSAxICYmIGIubm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdGEuc291cmNlSW5kZXggLSBiLnNvdXJjZUluZGV4O1xuXG5cdC8vIFVzZSBJRSBzb3VyY2VJbmRleCBpZiBhdmFpbGFibGUgb24gYm90aCBub2Rlc1xuXHRpZiAoIGRpZmYgKSB7XG5cdFx0cmV0dXJuIGRpZmY7XG5cdH1cblxuXHQvLyBDaGVjayBpZiBiIGZvbGxvd3MgYVxuXHRpZiAoIGN1ciApIHtcblx0XHR3aGlsZSAoICggY3VyID0gY3VyLm5leHRTaWJsaW5nICkgKSB7XG5cdFx0XHRpZiAoIGN1ciA9PT0gYiApIHtcblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBhID8gMSA6IC0xO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgaW5wdXQgdHlwZXNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUlucHV0UHNldWRvKCB0eXBlICkge1xuXHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0dmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IHR5cGU7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBidXR0b25zXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICovXG5mdW5jdGlvbiBjcmVhdGVCdXR0b25Qc2V1ZG8oIHR5cGUgKSB7XG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgbmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRyZXR1cm4gKCBuYW1lID09PSBcImlucHV0XCIgfHwgbmFtZSA9PT0gXCJidXR0b25cIiApICYmIGVsZW0udHlwZSA9PT0gdHlwZTtcblx0fTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIDplbmFibGVkLzpkaXNhYmxlZFxuICogQHBhcmFtIHtCb29sZWFufSBkaXNhYmxlZCB0cnVlIGZvciA6ZGlzYWJsZWQ7IGZhbHNlIGZvciA6ZW5hYmxlZFxuICovXG5mdW5jdGlvbiBjcmVhdGVEaXNhYmxlZFBzZXVkbyggZGlzYWJsZWQgKSB7XG5cblx0Ly8gS25vd24gOmRpc2FibGVkIGZhbHNlIHBvc2l0aXZlczogZmllbGRzZXRbZGlzYWJsZWRdID4gbGVnZW5kOm50aC1vZi10eXBlKG4rMikgOmNhbi1kaXNhYmxlXG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdC8vIE9ubHkgY2VydGFpbiBlbGVtZW50cyBjYW4gbWF0Y2ggOmVuYWJsZWQgb3IgOmRpc2FibGVkXG5cdFx0Ly8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc2NyaXB0aW5nLmh0bWwjc2VsZWN0b3ItZW5hYmxlZFxuXHRcdC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3NjcmlwdGluZy5odG1sI3NlbGVjdG9yLWRpc2FibGVkXG5cdFx0aWYgKCBcImZvcm1cIiBpbiBlbGVtICkge1xuXG5cdFx0XHQvLyBDaGVjayBmb3IgaW5oZXJpdGVkIGRpc2FibGVkbmVzcyBvbiByZWxldmFudCBub24tZGlzYWJsZWQgZWxlbWVudHM6XG5cdFx0XHQvLyAqIGxpc3RlZCBmb3JtLWFzc29jaWF0ZWQgZWxlbWVudHMgaW4gYSBkaXNhYmxlZCBmaWVsZHNldFxuXHRcdFx0Ly8gICBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9mb3Jtcy5odG1sI2NhdGVnb3J5LWxpc3RlZFxuXHRcdFx0Ly8gICBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9mb3Jtcy5odG1sI2NvbmNlcHQtZmUtZGlzYWJsZWRcblx0XHRcdC8vICogb3B0aW9uIGVsZW1lbnRzIGluIGEgZGlzYWJsZWQgb3B0Z3JvdXBcblx0XHRcdC8vICAgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZm9ybXMuaHRtbCNjb25jZXB0LW9wdGlvbi1kaXNhYmxlZFxuXHRcdFx0Ly8gQWxsIHN1Y2ggZWxlbWVudHMgaGF2ZSBhIFwiZm9ybVwiIHByb3BlcnR5LlxuXHRcdFx0aWYgKCBlbGVtLnBhcmVudE5vZGUgJiYgZWxlbS5kaXNhYmxlZCA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdFx0Ly8gT3B0aW9uIGVsZW1lbnRzIGRlZmVyIHRvIGEgcGFyZW50IG9wdGdyb3VwIGlmIHByZXNlbnRcblx0XHRcdFx0aWYgKCBcImxhYmVsXCIgaW4gZWxlbSApIHtcblx0XHRcdFx0XHRpZiAoIFwibGFiZWxcIiBpbiBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbS5wYXJlbnROb2RlLmRpc2FibGVkID09PSBkaXNhYmxlZDtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IGRpc2FibGVkO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDYgLSAxMVxuXHRcdFx0XHQvLyBVc2UgdGhlIGlzRGlzYWJsZWQgc2hvcnRjdXQgcHJvcGVydHkgdG8gY2hlY2sgZm9yIGRpc2FibGVkIGZpZWxkc2V0IGFuY2VzdG9yc1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5pc0Rpc2FibGVkID09PSBkaXNhYmxlZCB8fFxuXG5cdFx0XHRcdFx0Ly8gV2hlcmUgdGhlcmUgaXMgbm8gaXNEaXNhYmxlZCwgY2hlY2sgbWFudWFsbHlcblx0XHRcdFx0XHQvKiBqc2hpbnQgLVcwMTggKi9cblx0XHRcdFx0XHRlbGVtLmlzRGlzYWJsZWQgIT09ICFkaXNhYmxlZCAmJlxuXHRcdFx0XHRcdGluRGlzYWJsZWRGaWVsZHNldCggZWxlbSApID09PSBkaXNhYmxlZDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IGRpc2FibGVkO1xuXG5cdFx0Ly8gVHJ5IHRvIHdpbm5vdyBvdXQgZWxlbWVudHMgdGhhdCBjYW4ndCBiZSBkaXNhYmxlZCBiZWZvcmUgdHJ1c3RpbmcgdGhlIGRpc2FibGVkIHByb3BlcnR5LlxuXHRcdC8vIFNvbWUgdmljdGltcyBnZXQgY2F1Z2h0IGluIG91ciBuZXQgKGxhYmVsLCBsZWdlbmQsIG1lbnUsIHRyYWNrKSwgYnV0IGl0IHNob3VsZG4ndFxuXHRcdC8vIGV2ZW4gZXhpc3Qgb24gdGhlbSwgbGV0IGFsb25lIGhhdmUgYSBib29sZWFuIHZhbHVlLlxuXHRcdH0gZWxzZSBpZiAoIFwibGFiZWxcIiBpbiBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IGRpc2FibGVkO1xuXHRcdH1cblxuXHRcdC8vIFJlbWFpbmluZyBlbGVtZW50cyBhcmUgbmVpdGhlciA6ZW5hYmxlZCBub3IgOmRpc2FibGVkXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgcG9zaXRpb25hbHNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZuICkge1xuXHRyZXR1cm4gbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggYXJndW1lbnQgKSB7XG5cdFx0YXJndW1lbnQgPSArYXJndW1lbnQ7XG5cdFx0cmV0dXJuIG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMgKSB7XG5cdFx0XHR2YXIgaixcblx0XHRcdFx0bWF0Y2hJbmRleGVzID0gZm4oIFtdLCBzZWVkLmxlbmd0aCwgYXJndW1lbnQgKSxcblx0XHRcdFx0aSA9IG1hdGNoSW5kZXhlcy5sZW5ndGg7XG5cblx0XHRcdC8vIE1hdGNoIGVsZW1lbnRzIGZvdW5kIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXhlc1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggc2VlZFsgKCBqID0gbWF0Y2hJbmRleGVzWyBpIF0gKSBdICkge1xuXHRcdFx0XHRcdHNlZWRbIGogXSA9ICEoIG1hdGNoZXNbIGogXSA9IHNlZWRbIGogXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9ICk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGEgbm9kZSBmb3IgdmFsaWRpdHkgYXMgYSBTaXp6bGUgY29udGV4dFxuICogQHBhcmFtIHtFbGVtZW50fE9iamVjdD19IGNvbnRleHRcbiAqIEByZXR1cm5zIHtFbGVtZW50fE9iamVjdHxCb29sZWFufSBUaGUgaW5wdXQgbm9kZSBpZiBhY2NlcHRhYmxlLCBvdGhlcndpc2UgYSBmYWxzeSB2YWx1ZVxuICovXG5mdW5jdGlvbiB0ZXN0Q29udGV4dCggY29udGV4dCApIHtcblx0cmV0dXJuIGNvbnRleHQgJiYgdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IFwidW5kZWZpbmVkXCIgJiYgY29udGV4dDtcbn1cblxuLy8gRXhwb3NlIHN1cHBvcnQgdmFycyBmb3IgY29udmVuaWVuY2VcbnN1cHBvcnQgPSBTaXp6bGUuc3VwcG9ydCA9IHt9O1xuXG4vKipcbiAqIERldGVjdHMgWE1MIG5vZGVzXG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0fSBlbGVtIEFuIGVsZW1lbnQgb3IgYSBkb2N1bWVudFxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWZmIGVsZW0gaXMgYSBub24tSFRNTCBYTUwgbm9kZVxuICovXG5pc1hNTCA9IFNpenpsZS5pc1hNTCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHR2YXIgbmFtZXNwYWNlID0gZWxlbSAmJiBlbGVtLm5hbWVzcGFjZVVSSSxcblx0XHRkb2NFbGVtID0gZWxlbSAmJiAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkuZG9jdW1lbnRFbGVtZW50O1xuXG5cdC8vIFN1cHBvcnQ6IElFIDw9OFxuXHQvLyBBc3N1bWUgSFRNTCB3aGVuIGRvY3VtZW50RWxlbWVudCBkb2Vzbid0IHlldCBleGlzdCwgc3VjaCBhcyBpbnNpZGUgbG9hZGluZyBpZnJhbWVzXG5cdC8vIGh0dHBzOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC80ODMzXG5cdHJldHVybiAhcmh0bWwudGVzdCggbmFtZXNwYWNlIHx8IGRvY0VsZW0gJiYgZG9jRWxlbS5ub2RlTmFtZSB8fCBcIkhUTUxcIiApO1xufTtcblxuLyoqXG4gKiBTZXRzIGRvY3VtZW50LXJlbGF0ZWQgdmFyaWFibGVzIG9uY2UgYmFzZWQgb24gdGhlIGN1cnJlbnQgZG9jdW1lbnRcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IFtkb2NdIEFuIGVsZW1lbnQgb3IgZG9jdW1lbnQgb2JqZWN0IHRvIHVzZSB0byBzZXQgdGhlIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjdXJyZW50IGRvY3VtZW50XG4gKi9cbnNldERvY3VtZW50ID0gU2l6emxlLnNldERvY3VtZW50ID0gZnVuY3Rpb24oIG5vZGUgKSB7XG5cdHZhciBoYXNDb21wYXJlLCBzdWJXaW5kb3csXG5cdFx0ZG9jID0gbm9kZSA/IG5vZGUub3duZXJEb2N1bWVudCB8fCBub2RlIDogcHJlZmVycmVkRG9jO1xuXG5cdC8vIFJldHVybiBlYXJseSBpZiBkb2MgaXMgaW52YWxpZCBvciBhbHJlYWR5IHNlbGVjdGVkXG5cdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdGlmICggZG9jID09IGRvY3VtZW50IHx8IGRvYy5ub2RlVHlwZSAhPT0gOSB8fCAhZG9jLmRvY3VtZW50RWxlbWVudCApIHtcblx0XHRyZXR1cm4gZG9jdW1lbnQ7XG5cdH1cblxuXHQvLyBVcGRhdGUgZ2xvYmFsIHZhcmlhYmxlc1xuXHRkb2N1bWVudCA9IGRvYztcblx0ZG9jRWxlbSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblx0ZG9jdW1lbnRJc0hUTUwgPSAhaXNYTUwoIGRvY3VtZW50ICk7XG5cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExKywgRWRnZSAxMiAtIDE4K1xuXHQvLyBBY2Nlc3NpbmcgaWZyYW1lIGRvY3VtZW50cyBhZnRlciB1bmxvYWQgdGhyb3dzIFwicGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvcnMgKGpRdWVyeSAjMTM5MzYpXG5cdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdGlmICggcHJlZmVycmVkRG9jICE9IGRvY3VtZW50ICYmXG5cdFx0KCBzdWJXaW5kb3cgPSBkb2N1bWVudC5kZWZhdWx0VmlldyApICYmIHN1YldpbmRvdy50b3AgIT09IHN1YldpbmRvdyApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDExLCBFZGdlXG5cdFx0aWYgKCBzdWJXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lciApIHtcblx0XHRcdHN1YldpbmRvdy5hZGRFdmVudExpc3RlbmVyKCBcInVubG9hZFwiLCB1bmxvYWRIYW5kbGVyLCBmYWxzZSApO1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgOSAtIDEwIG9ubHlcblx0XHR9IGVsc2UgaWYgKCBzdWJXaW5kb3cuYXR0YWNoRXZlbnQgKSB7XG5cdFx0XHRzdWJXaW5kb3cuYXR0YWNoRXZlbnQoIFwib251bmxvYWRcIiwgdW5sb2FkSGFuZGxlciApO1xuXHRcdH1cblx0fVxuXG5cdC8vIFN1cHBvcnQ6IElFIDggLSAxMSssIEVkZ2UgMTIgLSAxOCssIENocm9tZSA8PTE2IC0gMjUgb25seSwgRmlyZWZveCA8PTMuNiAtIDMxIG9ubHksXG5cdC8vIFNhZmFyaSA0IC0gNSBvbmx5LCBPcGVyYSA8PTExLjYgLSAxMi54IG9ubHlcblx0Ly8gSUUvRWRnZSAmIG9sZGVyIGJyb3dzZXJzIGRvbid0IHN1cHBvcnQgdGhlIDpzY29wZSBwc2V1ZG8tY2xhc3MuXG5cdC8vIFN1cHBvcnQ6IFNhZmFyaSA2LjAgb25seVxuXHQvLyBTYWZhcmkgNi4wIHN1cHBvcnRzIDpzY29wZSBidXQgaXQncyBhbiBhbGlhcyBvZiA6cm9vdCB0aGVyZS5cblx0c3VwcG9ydC5zY29wZSA9IGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGVsICkuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApO1xuXHRcdHJldHVybiB0eXBlb2YgZWwucXVlcnlTZWxlY3RvckFsbCAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuXHRcdFx0IWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiOnNjb3BlIGZpZWxkc2V0IGRpdlwiICkubGVuZ3RoO1xuXHR9ICk7XG5cblx0LyogQXR0cmlidXRlc1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gU3VwcG9ydDogSUU8OFxuXHQvLyBWZXJpZnkgdGhhdCBnZXRBdHRyaWJ1dGUgcmVhbGx5IHJldHVybnMgYXR0cmlidXRlcyBhbmQgbm90IHByb3BlcnRpZXNcblx0Ly8gKGV4Y2VwdGluZyBJRTggYm9vbGVhbnMpXG5cdHN1cHBvcnQuYXR0cmlidXRlcyA9IGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXHRcdGVsLmNsYXNzTmFtZSA9IFwiaVwiO1xuXHRcdHJldHVybiAhZWwuZ2V0QXR0cmlidXRlKCBcImNsYXNzTmFtZVwiICk7XG5cdH0gKTtcblxuXHQvKiBnZXRFbGVtZW50KHMpQnkqXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBDaGVjayBpZiBnZXRFbGVtZW50c0J5VGFnTmFtZShcIipcIikgcmV0dXJucyBvbmx5IGVsZW1lbnRzXG5cdHN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgPSBhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0XHRlbC5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlQ29tbWVudCggXCJcIiApICk7XG5cdFx0cmV0dXJuICFlbC5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCIqXCIgKS5sZW5ndGg7XG5cdH0gKTtcblxuXHQvLyBTdXBwb3J0OiBJRTw5XG5cdHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSA9IHJuYXRpdmUudGVzdCggZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSApO1xuXG5cdC8vIFN1cHBvcnQ6IElFPDEwXG5cdC8vIENoZWNrIGlmIGdldEVsZW1lbnRCeUlkIHJldHVybnMgZWxlbWVudHMgYnkgbmFtZVxuXHQvLyBUaGUgYnJva2VuIGdldEVsZW1lbnRCeUlkIG1ldGhvZHMgZG9uJ3QgcGljayB1cCBwcm9ncmFtbWF0aWNhbGx5LXNldCBuYW1lcyxcblx0Ly8gc28gdXNlIGEgcm91bmRhYm91dCBnZXRFbGVtZW50c0J5TmFtZSB0ZXN0XG5cdHN1cHBvcnQuZ2V0QnlJZCA9IGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGVsICkuaWQgPSBleHBhbmRvO1xuXHRcdHJldHVybiAhZG9jdW1lbnQuZ2V0RWxlbWVudHNCeU5hbWUgfHwgIWRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lKCBleHBhbmRvICkubGVuZ3RoO1xuXHR9ICk7XG5cblx0Ly8gSUQgZmlsdGVyIGFuZCBmaW5kXG5cdGlmICggc3VwcG9ydC5nZXRCeUlkICkge1xuXHRcdEV4cHIuZmlsdGVyWyBcIklEXCIgXSA9IGZ1bmN0aW9uKCBpZCApIHtcblx0XHRcdHZhciBhdHRySWQgPSBpZC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoIFwiaWRcIiApID09PSBhdHRySWQ7XG5cdFx0XHR9O1xuXHRcdH07XG5cdFx0RXhwci5maW5kWyBcIklEXCIgXSA9IGZ1bmN0aW9uKCBpZCwgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRcdHZhciBlbGVtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggaWQgKTtcblx0XHRcdFx0cmV0dXJuIGVsZW0gPyBbIGVsZW0gXSA6IFtdO1xuXHRcdFx0fVxuXHRcdH07XG5cdH0gZWxzZSB7XG5cdFx0RXhwci5maWx0ZXJbIFwiSURcIiBdID0gIGZ1bmN0aW9uKCBpZCApIHtcblx0XHRcdHZhciBhdHRySWQgPSBpZC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgbm9kZSA9IHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZU5vZGUgIT09IFwidW5kZWZpbmVkXCIgJiZcblx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIFwiaWRcIiApO1xuXHRcdFx0XHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlID09PSBhdHRySWQ7XG5cdFx0XHR9O1xuXHRcdH07XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA2IC0gNyBvbmx5XG5cdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgaXMgbm90IHJlbGlhYmxlIGFzIGEgZmluZCBzaG9ydGN1dFxuXHRcdEV4cHIuZmluZFsgXCJJRFwiIF0gPSBmdW5jdGlvbiggaWQsIGNvbnRleHQgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRCeUlkICE9PSBcInVuZGVmaW5lZFwiICYmIGRvY3VtZW50SXNIVE1MICkge1xuXHRcdFx0XHR2YXIgbm9kZSwgaSwgZWxlbXMsXG5cdFx0XHRcdFx0ZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIGlkICk7XG5cblx0XHRcdFx0aWYgKCBlbGVtICkge1xuXG5cdFx0XHRcdFx0Ly8gVmVyaWZ5IHRoZSBpZCBhdHRyaWJ1dGVcblx0XHRcdFx0XHRub2RlID0gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCBcImlkXCIgKTtcblx0XHRcdFx0XHRpZiAoIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gaWQgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gWyBlbGVtIF07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gRmFsbCBiYWNrIG9uIGdldEVsZW1lbnRzQnlOYW1lXG5cdFx0XHRcdFx0ZWxlbXMgPSBjb250ZXh0LmdldEVsZW1lbnRzQnlOYW1lKCBpZCApO1xuXHRcdFx0XHRcdGkgPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKCBlbGVtID0gZWxlbXNbIGkrKyBdICkgKSB7XG5cdFx0XHRcdFx0XHRub2RlID0gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCBcImlkXCIgKTtcblx0XHRcdFx0XHRcdGlmICggbm9kZSAmJiBub2RlLnZhbHVlID09PSBpZCApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIFsgZWxlbSBdO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBbXTtcblx0XHRcdH1cblx0XHR9O1xuXHR9XG5cblx0Ly8gVGFnXG5cdEV4cHIuZmluZFsgXCJUQUdcIiBdID0gc3VwcG9ydC5nZXRFbGVtZW50c0J5VGFnTmFtZSA/XG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IFwidW5kZWZpbmVkXCIgKSB7XG5cdFx0XHRcdHJldHVybiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCB0YWcgKTtcblxuXHRcdFx0Ly8gRG9jdW1lbnRGcmFnbWVudCBub2RlcyBkb24ndCBoYXZlIGdFQlROXG5cdFx0XHR9IGVsc2UgaWYgKCBzdXBwb3J0LnFzYSApIHtcblx0XHRcdFx0cmV0dXJuIGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCggdGFnICk7XG5cdFx0XHR9XG5cdFx0fSA6XG5cblx0XHRmdW5jdGlvbiggdGFnLCBjb250ZXh0ICkge1xuXHRcdFx0dmFyIGVsZW0sXG5cdFx0XHRcdHRtcCA9IFtdLFxuXHRcdFx0XHRpID0gMCxcblxuXHRcdFx0XHQvLyBCeSBoYXBweSBjb2luY2lkZW5jZSwgYSAoYnJva2VuKSBnRUJUTiBhcHBlYXJzIG9uIERvY3VtZW50RnJhZ21lbnQgbm9kZXMgdG9vXG5cdFx0XHRcdHJlc3VsdHMgPSBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCB0YWcgKTtcblxuXHRcdFx0Ly8gRmlsdGVyIG91dCBwb3NzaWJsZSBjb21tZW50c1xuXHRcdFx0aWYgKCB0YWcgPT09IFwiKlwiICkge1xuXHRcdFx0XHR3aGlsZSAoICggZWxlbSA9IHJlc3VsdHNbIGkrKyBdICkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRcdFx0dG1wLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gdG1wO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0fTtcblxuXHQvLyBDbGFzc1xuXHRFeHByLmZpbmRbIFwiQ0xBU1NcIiBdID0gc3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICYmIGZ1bmN0aW9uKCBjbGFzc05hbWUsIGNvbnRleHQgKSB7XG5cdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICE9PSBcInVuZGVmaW5lZFwiICYmIGRvY3VtZW50SXNIVE1MICkge1xuXHRcdFx0cmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggY2xhc3NOYW1lICk7XG5cdFx0fVxuXHR9O1xuXG5cdC8qIFFTQS9tYXRjaGVzU2VsZWN0b3Jcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIFFTQSBhbmQgbWF0Y2hlc1NlbGVjdG9yIHN1cHBvcnRcblxuXHQvLyBtYXRjaGVzU2VsZWN0b3IoOmFjdGl2ZSkgcmVwb3J0cyBmYWxzZSB3aGVuIHRydWUgKElFOS9PcGVyYSAxMS41KVxuXHRyYnVnZ3lNYXRjaGVzID0gW107XG5cblx0Ly8gcVNhKDpmb2N1cykgcmVwb3J0cyBmYWxzZSB3aGVuIHRydWUgKENocm9tZSAyMSlcblx0Ly8gV2UgYWxsb3cgdGhpcyBiZWNhdXNlIG9mIGEgYnVnIGluIElFOC85IHRoYXQgdGhyb3dzIGFuIGVycm9yXG5cdC8vIHdoZW5ldmVyIGBkb2N1bWVudC5hY3RpdmVFbGVtZW50YCBpcyBhY2Nlc3NlZCBvbiBhbiBpZnJhbWVcblx0Ly8gU28sIHdlIGFsbG93IDpmb2N1cyB0byBwYXNzIHRocm91Z2ggUVNBIGFsbCB0aGUgdGltZSB0byBhdm9pZCB0aGUgSUUgZXJyb3Jcblx0Ly8gU2VlIGh0dHBzOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC8xMzM3OFxuXHRyYnVnZ3lRU0EgPSBbXTtcblxuXHRpZiAoICggc3VwcG9ydC5xc2EgPSBybmF0aXZlLnRlc3QoIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwgKSApICkge1xuXG5cdFx0Ly8gQnVpbGQgUVNBIHJlZ2V4XG5cdFx0Ly8gUmVnZXggc3RyYXRlZ3kgYWRvcHRlZCBmcm9tIERpZWdvIFBlcmluaVxuXHRcdGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXG5cdFx0XHR2YXIgaW5wdXQ7XG5cblx0XHRcdC8vIFNlbGVjdCBpcyBzZXQgdG8gZW1wdHkgc3RyaW5nIG9uIHB1cnBvc2Vcblx0XHRcdC8vIFRoaXMgaXMgdG8gdGVzdCBJRSdzIHRyZWF0bWVudCBvZiBub3QgZXhwbGljaXRseVxuXHRcdFx0Ly8gc2V0dGluZyBhIGJvb2xlYW4gY29udGVudCBhdHRyaWJ1dGUsXG5cdFx0XHQvLyBzaW5jZSBpdHMgcHJlc2VuY2Ugc2hvdWxkIGJlIGVub3VnaFxuXHRcdFx0Ly8gaHR0cHM6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEyMzU5XG5cdFx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBlbCApLmlubmVySFRNTCA9IFwiPGEgaWQ9J1wiICsgZXhwYW5kbyArIFwiJz48L2E+XCIgK1xuXHRcdFx0XHRcIjxzZWxlY3QgaWQ9J1wiICsgZXhwYW5kbyArIFwiLVxcclxcXFwnIG1zYWxsb3djYXB0dXJlPScnPlwiICtcblx0XHRcdFx0XCI8b3B0aW9uIHNlbGVjdGVkPScnPjwvb3B0aW9uPjwvc2VsZWN0PlwiO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRTgsIE9wZXJhIDExLTEyLjE2XG5cdFx0XHQvLyBOb3RoaW5nIHNob3VsZCBiZSBzZWxlY3RlZCB3aGVuIGVtcHR5IHN0cmluZ3MgZm9sbG93IF49IG9yICQ9IG9yICo9XG5cdFx0XHQvLyBUaGUgdGVzdCBhdHRyaWJ1dGUgbXVzdCBiZSB1bmtub3duIGluIE9wZXJhIGJ1dCBcInNhZmVcIiBmb3IgV2luUlRcblx0XHRcdC8vIGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvaGg0NjUzODguYXNweCNhdHRyaWJ1dGVfc2VjdGlvblxuXHRcdFx0aWYgKCBlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIlttc2FsbG93Y2FwdHVyZV49JyddXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIlsqXiRdPVwiICsgd2hpdGVzcGFjZSArIFwiKig/OicnfFxcXCJcXFwiKVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFOFxuXHRcdFx0Ly8gQm9vbGVhbiBhdHRyaWJ1dGVzIGFuZCBcInZhbHVlXCIgYXJlIG5vdCB0cmVhdGVkIGNvcnJlY3RseVxuXHRcdFx0aWYgKCAhZWwucXVlcnlTZWxlY3RvckFsbCggXCJbc2VsZWN0ZWRdXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIlxcXFxbXCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86dmFsdWV8XCIgKyBib29sZWFucyArIFwiKVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZTwyOSwgQW5kcm9pZDw0LjQsIFNhZmFyaTw3LjArLCBpT1M8Ny4wKywgUGhhbnRvbUpTPDEuOS44K1xuXHRcdFx0aWYgKCAhZWwucXVlcnlTZWxlY3RvckFsbCggXCJbaWR+PVwiICsgZXhwYW5kbyArIFwiLV1cIiApLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwifj1cIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTUgLSAxOCtcblx0XHRcdC8vIElFIDExL0VkZ2UgZG9uJ3QgZmluZCBlbGVtZW50cyBvbiBhIGBbbmFtZT0nJ11gIHF1ZXJ5IGluIHNvbWUgY2FzZXMuXG5cdFx0XHQvLyBBZGRpbmcgYSB0ZW1wb3JhcnkgYXR0cmlidXRlIHRvIHRoZSBkb2N1bWVudCBiZWZvcmUgdGhlIHNlbGVjdGlvbiB3b3Jrc1xuXHRcdFx0Ly8gYXJvdW5kIHRoZSBpc3N1ZS5cblx0XHRcdC8vIEludGVyZXN0aW5nbHksIElFIDEwICYgb2xkZXIgZG9uJ3Qgc2VlbSB0byBoYXZlIHRoZSBpc3N1ZS5cblx0XHRcdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cdFx0XHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwibmFtZVwiLCBcIlwiICk7XG5cdFx0XHRlbC5hcHBlbmRDaGlsZCggaW5wdXQgKTtcblx0XHRcdGlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiW25hbWU9JyddXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIlxcXFxbXCIgKyB3aGl0ZXNwYWNlICsgXCIqbmFtZVwiICsgd2hpdGVzcGFjZSArIFwiKj1cIiArXG5cdFx0XHRcdFx0d2hpdGVzcGFjZSArIFwiKig/OicnfFxcXCJcXFwiKVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFdlYmtpdC9PcGVyYSAtIDpjaGVja2VkIHNob3VsZCByZXR1cm4gc2VsZWN0ZWQgb3B0aW9uIGVsZW1lbnRzXG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDExL1JFQy1jc3MzLXNlbGVjdG9ycy0yMDExMDkyOS8jY2hlY2tlZFxuXHRcdFx0Ly8gSUU4IHRocm93cyBlcnJvciBoZXJlIGFuZCB3aWxsIG5vdCBzZWUgbGF0ZXIgdGVzdHNcblx0XHRcdGlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiOmNoZWNrZWRcIiApLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiOmNoZWNrZWRcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBTYWZhcmkgOCssIGlPUyA4K1xuXHRcdFx0Ly8gaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTEzNjg1MVxuXHRcdFx0Ly8gSW4tcGFnZSBgc2VsZWN0b3IjaWQgc2libGluZy1jb21iaW5hdG9yIHNlbGVjdG9yYCBmYWlsc1xuXHRcdFx0aWYgKCAhZWwucXVlcnlTZWxlY3RvckFsbCggXCJhI1wiICsgZXhwYW5kbyArIFwiKypcIiApLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiLiMuK1srfl1cIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDw9My42IC0gNSBvbmx5XG5cdFx0XHQvLyBPbGQgRmlyZWZveCBkb2Vzbid0IHRocm93IG9uIGEgYmFkbHktZXNjYXBlZCBpZGVudGlmaWVyLlxuXHRcdFx0ZWwucXVlcnlTZWxlY3RvckFsbCggXCJcXFxcXFxmXCIgKTtcblx0XHRcdHJidWdneVFTQS5wdXNoKCBcIltcXFxcclxcXFxuXFxcXGZdXCIgKTtcblx0XHR9ICk7XG5cblx0XHRhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0XHRcdGVsLmlubmVySFRNTCA9IFwiPGEgaHJlZj0nJyBkaXNhYmxlZD0nZGlzYWJsZWQnPjwvYT5cIiArXG5cdFx0XHRcdFwiPHNlbGVjdCBkaXNhYmxlZD0nZGlzYWJsZWQnPjxvcHRpb24vPjwvc2VsZWN0PlwiO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBXaW5kb3dzIDggTmF0aXZlIEFwcHNcblx0XHRcdC8vIFRoZSB0eXBlIGFuZCBuYW1lIGF0dHJpYnV0ZXMgYXJlIHJlc3RyaWN0ZWQgZHVyaW5nIC5pbm5lckhUTUwgYXNzaWdubWVudFxuXHRcdFx0dmFyIGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cdFx0XHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCBcImhpZGRlblwiICk7XG5cdFx0XHRlbC5hcHBlbmRDaGlsZCggaW5wdXQgKS5zZXRBdHRyaWJ1dGUoIFwibmFtZVwiLCBcIkRcIiApO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRThcblx0XHRcdC8vIEVuZm9yY2UgY2FzZS1zZW5zaXRpdml0eSBvZiBuYW1lIGF0dHJpYnV0ZVxuXHRcdFx0aWYgKCBlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIltuYW1lPWRdXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIm5hbWVcIiArIHdoaXRlc3BhY2UgKyBcIipbKl4kfCF+XT89XCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRkYgMy41IC0gOmVuYWJsZWQvOmRpc2FibGVkIGFuZCBoaWRkZW4gZWxlbWVudHMgKGhpZGRlbiBlbGVtZW50cyBhcmUgc3RpbGwgZW5hYmxlZClcblx0XHRcdC8vIElFOCB0aHJvd3MgZXJyb3IgaGVyZSBhbmQgd2lsbCBub3Qgc2VlIGxhdGVyIHRlc3RzXG5cdFx0XHRpZiAoIGVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiOmVuYWJsZWRcIiApLmxlbmd0aCAhPT0gMiApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiOmVuYWJsZWRcIiwgXCI6ZGlzYWJsZWRcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRTktMTErXG5cdFx0XHQvLyBJRSdzIDpkaXNhYmxlZCBzZWxlY3RvciBkb2VzIG5vdCBwaWNrIHVwIHRoZSBjaGlsZHJlbiBvZiBkaXNhYmxlZCBmaWVsZHNldHNcblx0XHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGVsICkuZGlzYWJsZWQgPSB0cnVlO1xuXHRcdFx0aWYgKCBlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIjpkaXNhYmxlZFwiICkubGVuZ3RoICE9PSAyICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCI6ZW5hYmxlZFwiLCBcIjpkaXNhYmxlZFwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IE9wZXJhIDEwIC0gMTEgb25seVxuXHRcdFx0Ly8gT3BlcmEgMTAtMTEgZG9lcyBub3QgdGhyb3cgb24gcG9zdC1jb21tYSBpbnZhbGlkIHBzZXVkb3Ncblx0XHRcdGVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiKiw6eFwiICk7XG5cdFx0XHRyYnVnZ3lRU0EucHVzaCggXCIsLio6XCIgKTtcblx0XHR9ICk7XG5cdH1cblxuXHRpZiAoICggc3VwcG9ydC5tYXRjaGVzU2VsZWN0b3IgPSBybmF0aXZlLnRlc3QoICggbWF0Y2hlcyA9IGRvY0VsZW0ubWF0Y2hlcyB8fFxuXHRcdGRvY0VsZW0ud2Via2l0TWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5tb3pNYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRkb2NFbGVtLm9NYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRkb2NFbGVtLm1zTWF0Y2hlc1NlbGVjdG9yICkgKSApICkge1xuXG5cdFx0YXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cblx0XHRcdC8vIENoZWNrIHRvIHNlZSBpZiBpdCdzIHBvc3NpYmxlIHRvIGRvIG1hdGNoZXNTZWxlY3RvclxuXHRcdFx0Ly8gb24gYSBkaXNjb25uZWN0ZWQgbm9kZSAoSUUgOSlcblx0XHRcdHN1cHBvcnQuZGlzY29ubmVjdGVkTWF0Y2ggPSBtYXRjaGVzLmNhbGwoIGVsLCBcIipcIiApO1xuXG5cdFx0XHQvLyBUaGlzIHNob3VsZCBmYWlsIHdpdGggYW4gZXhjZXB0aW9uXG5cdFx0XHQvLyBHZWNrbyBkb2VzIG5vdCBlcnJvciwgcmV0dXJucyBmYWxzZSBpbnN0ZWFkXG5cdFx0XHRtYXRjaGVzLmNhbGwoIGVsLCBcIltzIT0nJ106eFwiICk7XG5cdFx0XHRyYnVnZ3lNYXRjaGVzLnB1c2goIFwiIT1cIiwgcHNldWRvcyApO1xuXHRcdH0gKTtcblx0fVxuXG5cdHJidWdneVFTQSA9IHJidWdneVFTQS5sZW5ndGggJiYgbmV3IFJlZ0V4cCggcmJ1Z2d5UVNBLmpvaW4oIFwifFwiICkgKTtcblx0cmJ1Z2d5TWF0Y2hlcyA9IHJidWdneU1hdGNoZXMubGVuZ3RoICYmIG5ldyBSZWdFeHAoIHJidWdneU1hdGNoZXMuam9pbiggXCJ8XCIgKSApO1xuXG5cdC8qIENvbnRhaW5zXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblx0aGFzQ29tcGFyZSA9IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiApO1xuXG5cdC8vIEVsZW1lbnQgY29udGFpbnMgYW5vdGhlclxuXHQvLyBQdXJwb3NlZnVsbHkgc2VsZi1leGNsdXNpdmVcblx0Ly8gQXMgaW4sIGFuIGVsZW1lbnQgZG9lcyBub3QgY29udGFpbiBpdHNlbGZcblx0Y29udGFpbnMgPSBoYXNDb21wYXJlIHx8IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb250YWlucyApID9cblx0XHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHRcdHZhciBhZG93biA9IGEubm9kZVR5cGUgPT09IDkgPyBhLmRvY3VtZW50RWxlbWVudCA6IGEsXG5cdFx0XHRcdGJ1cCA9IGIgJiYgYi5wYXJlbnROb2RlO1xuXHRcdFx0cmV0dXJuIGEgPT09IGJ1cCB8fCAhISggYnVwICYmIGJ1cC5ub2RlVHlwZSA9PT0gMSAmJiAoXG5cdFx0XHRcdGFkb3duLmNvbnRhaW5zID9cblx0XHRcdFx0XHRhZG93bi5jb250YWlucyggYnVwICkgOlxuXHRcdFx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gJiYgYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYnVwICkgJiAxNlxuXHRcdFx0KSApO1xuXHRcdH0gOlxuXHRcdGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdFx0aWYgKCBiICkge1xuXHRcdFx0XHR3aGlsZSAoICggYiA9IGIucGFyZW50Tm9kZSApICkge1xuXHRcdFx0XHRcdGlmICggYiA9PT0gYSApIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH07XG5cblx0LyogU29ydGluZ1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gRG9jdW1lbnQgb3JkZXIgc29ydGluZ1xuXHRzb3J0T3JkZXIgPSBoYXNDb21wYXJlID9cblx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cblx0XHQvLyBGbGFnIGZvciBkdXBsaWNhdGUgcmVtb3ZhbFxuXHRcdGlmICggYSA9PT0gYiApIHtcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHQvLyBTb3J0IG9uIG1ldGhvZCBleGlzdGVuY2UgaWYgb25seSBvbmUgaW5wdXQgaGFzIGNvbXBhcmVEb2N1bWVudFBvc2l0aW9uXG5cdFx0dmFyIGNvbXBhcmUgPSAhYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiAtICFiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uO1xuXHRcdGlmICggY29tcGFyZSApIHtcblx0XHRcdHJldHVybiBjb21wYXJlO1xuXHRcdH1cblxuXHRcdC8vIENhbGN1bGF0ZSBwb3NpdGlvbiBpZiBib3RoIGlucHV0cyBiZWxvbmcgdG8gdGhlIHNhbWUgZG9jdW1lbnRcblx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0XHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdGNvbXBhcmUgPSAoIGEub3duZXJEb2N1bWVudCB8fCBhICkgPT0gKCBiLm93bmVyRG9jdW1lbnQgfHwgYiApID9cblx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGIgKSA6XG5cblx0XHRcdC8vIE90aGVyd2lzZSB3ZSBrbm93IHRoZXkgYXJlIGRpc2Nvbm5lY3RlZFxuXHRcdFx0MTtcblxuXHRcdC8vIERpc2Nvbm5lY3RlZCBub2Rlc1xuXHRcdGlmICggY29tcGFyZSAmIDEgfHxcblx0XHRcdCggIXN1cHBvcnQuc29ydERldGFjaGVkICYmIGIuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGEgKSA9PT0gY29tcGFyZSApICkge1xuXG5cdFx0XHQvLyBDaG9vc2UgdGhlIGZpcnN0IGVsZW1lbnQgdGhhdCBpcyByZWxhdGVkIHRvIG91ciBwcmVmZXJyZWQgZG9jdW1lbnRcblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0XHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdFx0XHRpZiAoIGEgPT0gZG9jdW1lbnQgfHwgYS5vd25lckRvY3VtZW50ID09IHByZWZlcnJlZERvYyAmJlxuXHRcdFx0XHRjb250YWlucyggcHJlZmVycmVkRG9jLCBhICkgKSB7XG5cdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0XHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0XHRcdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0XHRcdGlmICggYiA9PSBkb2N1bWVudCB8fCBiLm93bmVyRG9jdW1lbnQgPT0gcHJlZmVycmVkRG9jICYmXG5cdFx0XHRcdGNvbnRhaW5zKCBwcmVmZXJyZWREb2MsIGIgKSApIHtcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1haW50YWluIG9yaWdpbmFsIG9yZGVyXG5cdFx0XHRyZXR1cm4gc29ydElucHV0ID9cblx0XHRcdFx0KCBpbmRleE9mKCBzb3J0SW5wdXQsIGEgKSAtIGluZGV4T2YoIHNvcnRJbnB1dCwgYiApICkgOlxuXHRcdFx0XHQwO1xuXHRcdH1cblxuXHRcdHJldHVybiBjb21wYXJlICYgNCA/IC0xIDogMTtcblx0fSA6XG5cdGZ1bmN0aW9uKCBhLCBiICkge1xuXG5cdFx0Ly8gRXhpdCBlYXJseSBpZiB0aGUgbm9kZXMgYXJlIGlkZW50aWNhbFxuXHRcdGlmICggYSA9PT0gYiApIHtcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHR2YXIgY3VyLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRhdXAgPSBhLnBhcmVudE5vZGUsXG5cdFx0XHRidXAgPSBiLnBhcmVudE5vZGUsXG5cdFx0XHRhcCA9IFsgYSBdLFxuXHRcdFx0YnAgPSBbIGIgXTtcblxuXHRcdC8vIFBhcmVudGxlc3Mgbm9kZXMgYXJlIGVpdGhlciBkb2N1bWVudHMgb3IgZGlzY29ubmVjdGVkXG5cdFx0aWYgKCAhYXVwIHx8ICFidXAgKSB7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0XHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBlcWVxZXEgKi9cblx0XHRcdHJldHVybiBhID09IGRvY3VtZW50ID8gLTEgOlxuXHRcdFx0XHRiID09IGRvY3VtZW50ID8gMSA6XG5cdFx0XHRcdC8qIGVzbGludC1lbmFibGUgZXFlcWVxICovXG5cdFx0XHRcdGF1cCA/IC0xIDpcblx0XHRcdFx0YnVwID8gMSA6XG5cdFx0XHRcdHNvcnRJbnB1dCA/XG5cdFx0XHRcdCggaW5kZXhPZiggc29ydElucHV0LCBhICkgLSBpbmRleE9mKCBzb3J0SW5wdXQsIGIgKSApIDpcblx0XHRcdFx0MDtcblxuXHRcdC8vIElmIHRoZSBub2RlcyBhcmUgc2libGluZ3MsIHdlIGNhbiBkbyBhIHF1aWNrIGNoZWNrXG5cdFx0fSBlbHNlIGlmICggYXVwID09PSBidXAgKSB7XG5cdFx0XHRyZXR1cm4gc2libGluZ0NoZWNrKCBhLCBiICk7XG5cdFx0fVxuXG5cdFx0Ly8gT3RoZXJ3aXNlIHdlIG5lZWQgZnVsbCBsaXN0cyBvZiB0aGVpciBhbmNlc3RvcnMgZm9yIGNvbXBhcmlzb25cblx0XHRjdXIgPSBhO1xuXHRcdHdoaWxlICggKCBjdXIgPSBjdXIucGFyZW50Tm9kZSApICkge1xuXHRcdFx0YXAudW5zaGlmdCggY3VyICk7XG5cdFx0fVxuXHRcdGN1ciA9IGI7XG5cdFx0d2hpbGUgKCAoIGN1ciA9IGN1ci5wYXJlbnROb2RlICkgKSB7XG5cdFx0XHRicC51bnNoaWZ0KCBjdXIgKTtcblx0XHR9XG5cblx0XHQvLyBXYWxrIGRvd24gdGhlIHRyZWUgbG9va2luZyBmb3IgYSBkaXNjcmVwYW5jeVxuXHRcdHdoaWxlICggYXBbIGkgXSA9PT0gYnBbIGkgXSApIHtcblx0XHRcdGkrKztcblx0XHR9XG5cblx0XHRyZXR1cm4gaSA/XG5cblx0XHRcdC8vIERvIGEgc2libGluZyBjaGVjayBpZiB0aGUgbm9kZXMgaGF2ZSBhIGNvbW1vbiBhbmNlc3RvclxuXHRcdFx0c2libGluZ0NoZWNrKCBhcFsgaSBdLCBicFsgaSBdICkgOlxuXG5cdFx0XHQvLyBPdGhlcndpc2Ugbm9kZXMgaW4gb3VyIGRvY3VtZW50IHNvcnQgZmlyc3Rcblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0XHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBlcWVxZXEgKi9cblx0XHRcdGFwWyBpIF0gPT0gcHJlZmVycmVkRG9jID8gLTEgOlxuXHRcdFx0YnBbIGkgXSA9PSBwcmVmZXJyZWREb2MgPyAxIDpcblx0XHRcdC8qIGVzbGludC1lbmFibGUgZXFlcWVxICovXG5cdFx0XHQwO1xuXHR9O1xuXG5cdHJldHVybiBkb2N1bWVudDtcbn07XG5cblNpenpsZS5tYXRjaGVzID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1lbnRzICkge1xuXHRyZXR1cm4gU2l6emxlKCBleHByLCBudWxsLCBudWxsLCBlbGVtZW50cyApO1xufTtcblxuU2l6emxlLm1hdGNoZXNTZWxlY3RvciA9IGZ1bmN0aW9uKCBlbGVtLCBleHByICkge1xuXHRzZXREb2N1bWVudCggZWxlbSApO1xuXG5cdGlmICggc3VwcG9ydC5tYXRjaGVzU2VsZWN0b3IgJiYgZG9jdW1lbnRJc0hUTUwgJiZcblx0XHQhbm9ubmF0aXZlU2VsZWN0b3JDYWNoZVsgZXhwciArIFwiIFwiIF0gJiZcblx0XHQoICFyYnVnZ3lNYXRjaGVzIHx8ICFyYnVnZ3lNYXRjaGVzLnRlc3QoIGV4cHIgKSApICYmXG5cdFx0KCAhcmJ1Z2d5UVNBICAgICB8fCAhcmJ1Z2d5UVNBLnRlc3QoIGV4cHIgKSApICkge1xuXG5cdFx0dHJ5IHtcblx0XHRcdHZhciByZXQgPSBtYXRjaGVzLmNhbGwoIGVsZW0sIGV4cHIgKTtcblxuXHRcdFx0Ly8gSUUgOSdzIG1hdGNoZXNTZWxlY3RvciByZXR1cm5zIGZhbHNlIG9uIGRpc2Nvbm5lY3RlZCBub2Rlc1xuXHRcdFx0aWYgKCByZXQgfHwgc3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCB8fFxuXG5cdFx0XHRcdC8vIEFzIHdlbGwsIGRpc2Nvbm5lY3RlZCBub2RlcyBhcmUgc2FpZCB0byBiZSBpbiBhIGRvY3VtZW50XG5cdFx0XHRcdC8vIGZyYWdtZW50IGluIElFIDlcblx0XHRcdFx0ZWxlbS5kb2N1bWVudCAmJiBlbGVtLmRvY3VtZW50Lm5vZGVUeXBlICE9PSAxMSApIHtcblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH1cblx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdG5vbm5hdGl2ZVNlbGVjdG9yQ2FjaGUoIGV4cHIsIHRydWUgKTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gU2l6emxlKCBleHByLCBkb2N1bWVudCwgbnVsbCwgWyBlbGVtIF0gKS5sZW5ndGggPiAwO1xufTtcblxuU2l6emxlLmNvbnRhaW5zID0gZnVuY3Rpb24oIGNvbnRleHQsIGVsZW0gKSB7XG5cblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXG5cdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdGlmICggKCBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCApICE9IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XG5cdH1cblx0cmV0dXJuIGNvbnRhaW5zKCBjb250ZXh0LCBlbGVtICk7XG59O1xuXG5TaXp6bGUuYXR0ciA9IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXG5cdC8vIFNldCBkb2N1bWVudCB2YXJzIGlmIG5lZWRlZFxuXHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRpZiAoICggZWxlbS5vd25lckRvY3VtZW50IHx8IGVsZW0gKSAhPSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggZWxlbSApO1xuXHR9XG5cblx0dmFyIGZuID0gRXhwci5hdHRySGFuZGxlWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSxcblxuXHRcdC8vIERvbid0IGdldCBmb29sZWQgYnkgT2JqZWN0LnByb3RvdHlwZSBwcm9wZXJ0aWVzIChqUXVlcnkgIzEzODA3KVxuXHRcdHZhbCA9IGZuICYmIGhhc093bi5jYWxsKCBFeHByLmF0dHJIYW5kbGUsIG5hbWUudG9Mb3dlckNhc2UoKSApID9cblx0XHRcdGZuKCBlbGVtLCBuYW1lLCAhZG9jdW1lbnRJc0hUTUwgKSA6XG5cdFx0XHR1bmRlZmluZWQ7XG5cblx0cmV0dXJuIHZhbCAhPT0gdW5kZWZpbmVkID9cblx0XHR2YWwgOlxuXHRcdHN1cHBvcnQuYXR0cmlidXRlcyB8fCAhZG9jdW1lbnRJc0hUTUwgP1xuXHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKSA6XG5cdFx0XHQoIHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggbmFtZSApICkgJiYgdmFsLnNwZWNpZmllZCA/XG5cdFx0XHRcdHZhbC52YWx1ZSA6XG5cdFx0XHRcdG51bGw7XG59O1xuXG5TaXp6bGUuZXNjYXBlID0gZnVuY3Rpb24oIHNlbCApIHtcblx0cmV0dXJuICggc2VsICsgXCJcIiApLnJlcGxhY2UoIHJjc3Nlc2NhcGUsIGZjc3Nlc2NhcGUgKTtcbn07XG5cblNpenpsZS5lcnJvciA9IGZ1bmN0aW9uKCBtc2cgKSB7XG5cdHRocm93IG5ldyBFcnJvciggXCJTeW50YXggZXJyb3IsIHVucmVjb2duaXplZCBleHByZXNzaW9uOiBcIiArIG1zZyApO1xufTtcblxuLyoqXG4gKiBEb2N1bWVudCBzb3J0aW5nIGFuZCByZW1vdmluZyBkdXBsaWNhdGVzXG4gKiBAcGFyYW0ge0FycmF5TGlrZX0gcmVzdWx0c1xuICovXG5TaXp6bGUudW5pcXVlU29ydCA9IGZ1bmN0aW9uKCByZXN1bHRzICkge1xuXHR2YXIgZWxlbSxcblx0XHRkdXBsaWNhdGVzID0gW10sXG5cdFx0aiA9IDAsXG5cdFx0aSA9IDA7XG5cblx0Ly8gVW5sZXNzIHdlICprbm93KiB3ZSBjYW4gZGV0ZWN0IGR1cGxpY2F0ZXMsIGFzc3VtZSB0aGVpciBwcmVzZW5jZVxuXHRoYXNEdXBsaWNhdGUgPSAhc3VwcG9ydC5kZXRlY3REdXBsaWNhdGVzO1xuXHRzb3J0SW5wdXQgPSAhc3VwcG9ydC5zb3J0U3RhYmxlICYmIHJlc3VsdHMuc2xpY2UoIDAgKTtcblx0cmVzdWx0cy5zb3J0KCBzb3J0T3JkZXIgKTtcblxuXHRpZiAoIGhhc0R1cGxpY2F0ZSApIHtcblx0XHR3aGlsZSAoICggZWxlbSA9IHJlc3VsdHNbIGkrKyBdICkgKSB7XG5cdFx0XHRpZiAoIGVsZW0gPT09IHJlc3VsdHNbIGkgXSApIHtcblx0XHRcdFx0aiA9IGR1cGxpY2F0ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHR3aGlsZSAoIGotLSApIHtcblx0XHRcdHJlc3VsdHMuc3BsaWNlKCBkdXBsaWNhdGVzWyBqIF0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBDbGVhciBpbnB1dCBhZnRlciBzb3J0aW5nIHRvIHJlbGVhc2Ugb2JqZWN0c1xuXHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9zaXp6bGUvcHVsbC8yMjVcblx0c29ydElucHV0ID0gbnVsbDtcblxuXHRyZXR1cm4gcmVzdWx0cztcbn07XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbiBmb3IgcmV0cmlldmluZyB0aGUgdGV4dCB2YWx1ZSBvZiBhbiBhcnJheSBvZiBET00gbm9kZXNcbiAqIEBwYXJhbSB7QXJyYXl8RWxlbWVudH0gZWxlbVxuICovXG5nZXRUZXh0ID0gU2l6emxlLmdldFRleHQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0dmFyIG5vZGUsXG5cdFx0cmV0ID0gXCJcIixcblx0XHRpID0gMCxcblx0XHRub2RlVHlwZSA9IGVsZW0ubm9kZVR5cGU7XG5cblx0aWYgKCAhbm9kZVR5cGUgKSB7XG5cblx0XHQvLyBJZiBubyBub2RlVHlwZSwgdGhpcyBpcyBleHBlY3RlZCB0byBiZSBhbiBhcnJheVxuXHRcdHdoaWxlICggKCBub2RlID0gZWxlbVsgaSsrIF0gKSApIHtcblxuXHRcdFx0Ly8gRG8gbm90IHRyYXZlcnNlIGNvbW1lbnQgbm9kZXNcblx0XHRcdHJldCArPSBnZXRUZXh0KCBub2RlICk7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKCBub2RlVHlwZSA9PT0gMSB8fCBub2RlVHlwZSA9PT0gOSB8fCBub2RlVHlwZSA9PT0gMTEgKSB7XG5cblx0XHQvLyBVc2UgdGV4dENvbnRlbnQgZm9yIGVsZW1lbnRzXG5cdFx0Ly8gaW5uZXJUZXh0IHVzYWdlIHJlbW92ZWQgZm9yIGNvbnNpc3RlbmN5IG9mIG5ldyBsaW5lcyAoalF1ZXJ5ICMxMTE1Mylcblx0XHRpZiAoIHR5cGVvZiBlbGVtLnRleHRDb250ZW50ID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0cmV0dXJuIGVsZW0udGV4dENvbnRlbnQ7XG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gVHJhdmVyc2UgaXRzIGNoaWxkcmVuXG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcblx0XHRcdFx0cmV0ICs9IGdldFRleHQoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSBpZiAoIG5vZGVUeXBlID09PSAzIHx8IG5vZGVUeXBlID09PSA0ICkge1xuXHRcdHJldHVybiBlbGVtLm5vZGVWYWx1ZTtcblx0fVxuXG5cdC8vIERvIG5vdCBpbmNsdWRlIGNvbW1lbnQgb3IgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBub2Rlc1xuXG5cdHJldHVybiByZXQ7XG59O1xuXG5FeHByID0gU2l6emxlLnNlbGVjdG9ycyA9IHtcblxuXHQvLyBDYW4gYmUgYWRqdXN0ZWQgYnkgdGhlIHVzZXJcblx0Y2FjaGVMZW5ndGg6IDUwLFxuXG5cdGNyZWF0ZVBzZXVkbzogbWFya0Z1bmN0aW9uLFxuXG5cdG1hdGNoOiBtYXRjaEV4cHIsXG5cblx0YXR0ckhhbmRsZToge30sXG5cblx0ZmluZDoge30sXG5cblx0cmVsYXRpdmU6IHtcblx0XHRcIj5cIjogeyBkaXI6IFwicGFyZW50Tm9kZVwiLCBmaXJzdDogdHJ1ZSB9LFxuXHRcdFwiIFwiOiB7IGRpcjogXCJwYXJlbnROb2RlXCIgfSxcblx0XHRcIitcIjogeyBkaXI6IFwicHJldmlvdXNTaWJsaW5nXCIsIGZpcnN0OiB0cnVlIH0sXG5cdFx0XCJ+XCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiIH1cblx0fSxcblxuXHRwcmVGaWx0ZXI6IHtcblx0XHRcIkFUVFJcIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0bWF0Y2hbIDEgXSA9IG1hdGNoWyAxIF0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0Ly8gTW92ZSB0aGUgZ2l2ZW4gdmFsdWUgdG8gbWF0Y2hbM10gd2hldGhlciBxdW90ZWQgb3IgdW5xdW90ZWRcblx0XHRcdG1hdGNoWyAzIF0gPSAoIG1hdGNoWyAzIF0gfHwgbWF0Y2hbIDQgXSB8fFxuXHRcdFx0XHRtYXRjaFsgNSBdIHx8IFwiXCIgKS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXG5cdFx0XHRpZiAoIG1hdGNoWyAyIF0gPT09IFwifj1cIiApIHtcblx0XHRcdFx0bWF0Y2hbIDMgXSA9IFwiIFwiICsgbWF0Y2hbIDMgXSArIFwiIFwiO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbWF0Y2guc2xpY2UoIDAsIDQgKTtcblx0XHR9LFxuXG5cdFx0XCJDSElMRFwiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XG5cblx0XHRcdC8qIG1hdGNoZXMgZnJvbSBtYXRjaEV4cHJbXCJDSElMRFwiXVxuXHRcdFx0XHQxIHR5cGUgKG9ubHl8bnRofC4uLilcblx0XHRcdFx0MiB3aGF0IChjaGlsZHxvZi10eXBlKVxuXHRcdFx0XHQzIGFyZ3VtZW50IChldmVufG9kZHxcXGQqfFxcZCpuKFsrLV1cXGQrKT98Li4uKVxuXHRcdFx0XHQ0IHhuLWNvbXBvbmVudCBvZiB4bit5IGFyZ3VtZW50IChbKy1dP1xcZCpufClcblx0XHRcdFx0NSBzaWduIG9mIHhuLWNvbXBvbmVudFxuXHRcdFx0XHQ2IHggb2YgeG4tY29tcG9uZW50XG5cdFx0XHRcdDcgc2lnbiBvZiB5LWNvbXBvbmVudFxuXHRcdFx0XHQ4IHkgb2YgeS1jb21wb25lbnRcblx0XHRcdCovXG5cdFx0XHRtYXRjaFsgMSBdID0gbWF0Y2hbIDEgXS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0XHRpZiAoIG1hdGNoWyAxIF0uc2xpY2UoIDAsIDMgKSA9PT0gXCJudGhcIiApIHtcblxuXHRcdFx0XHQvLyBudGgtKiByZXF1aXJlcyBhcmd1bWVudFxuXHRcdFx0XHRpZiAoICFtYXRjaFsgMyBdICkge1xuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggbWF0Y2hbIDAgXSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gbnVtZXJpYyB4IGFuZCB5IHBhcmFtZXRlcnMgZm9yIEV4cHIuZmlsdGVyLkNISUxEXG5cdFx0XHRcdC8vIHJlbWVtYmVyIHRoYXQgZmFsc2UvdHJ1ZSBjYXN0IHJlc3BlY3RpdmVseSB0byAwLzFcblx0XHRcdFx0bWF0Y2hbIDQgXSA9ICsoIG1hdGNoWyA0IF0gP1xuXHRcdFx0XHRcdG1hdGNoWyA1IF0gKyAoIG1hdGNoWyA2IF0gfHwgMSApIDpcblx0XHRcdFx0XHQyICogKCBtYXRjaFsgMyBdID09PSBcImV2ZW5cIiB8fCBtYXRjaFsgMyBdID09PSBcIm9kZFwiICkgKTtcblx0XHRcdFx0bWF0Y2hbIDUgXSA9ICsoICggbWF0Y2hbIDcgXSArIG1hdGNoWyA4IF0gKSB8fCBtYXRjaFsgMyBdID09PSBcIm9kZFwiICk7XG5cblx0XHRcdFx0Ly8gb3RoZXIgdHlwZXMgcHJvaGliaXQgYXJndW1lbnRzXG5cdFx0XHR9IGVsc2UgaWYgKCBtYXRjaFsgMyBdICkge1xuXHRcdFx0XHRTaXp6bGUuZXJyb3IoIG1hdGNoWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoO1xuXHRcdH0sXG5cblx0XHRcIlBTRVVET1wiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XG5cdFx0XHR2YXIgZXhjZXNzLFxuXHRcdFx0XHR1bnF1b3RlZCA9ICFtYXRjaFsgNiBdICYmIG1hdGNoWyAyIF07XG5cblx0XHRcdGlmICggbWF0Y2hFeHByWyBcIkNISUxEXCIgXS50ZXN0KCBtYXRjaFsgMCBdICkgKSB7XG5cdFx0XHRcdHJldHVybiBudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBY2NlcHQgcXVvdGVkIGFyZ3VtZW50cyBhcy1pc1xuXHRcdFx0aWYgKCBtYXRjaFsgMyBdICkge1xuXHRcdFx0XHRtYXRjaFsgMiBdID0gbWF0Y2hbIDQgXSB8fCBtYXRjaFsgNSBdIHx8IFwiXCI7XG5cblx0XHRcdC8vIFN0cmlwIGV4Y2VzcyBjaGFyYWN0ZXJzIGZyb20gdW5xdW90ZWQgYXJndW1lbnRzXG5cdFx0XHR9IGVsc2UgaWYgKCB1bnF1b3RlZCAmJiBycHNldWRvLnRlc3QoIHVucXVvdGVkICkgJiZcblxuXHRcdFx0XHQvLyBHZXQgZXhjZXNzIGZyb20gdG9rZW5pemUgKHJlY3Vyc2l2ZWx5KVxuXHRcdFx0XHQoIGV4Y2VzcyA9IHRva2VuaXplKCB1bnF1b3RlZCwgdHJ1ZSApICkgJiZcblxuXHRcdFx0XHQvLyBhZHZhbmNlIHRvIHRoZSBuZXh0IGNsb3NpbmcgcGFyZW50aGVzaXNcblx0XHRcdFx0KCBleGNlc3MgPSB1bnF1b3RlZC5pbmRleE9mKCBcIilcIiwgdW5xdW90ZWQubGVuZ3RoIC0gZXhjZXNzICkgLSB1bnF1b3RlZC5sZW5ndGggKSApIHtcblxuXHRcdFx0XHQvLyBleGNlc3MgaXMgYSBuZWdhdGl2ZSBpbmRleFxuXHRcdFx0XHRtYXRjaFsgMCBdID0gbWF0Y2hbIDAgXS5zbGljZSggMCwgZXhjZXNzICk7XG5cdFx0XHRcdG1hdGNoWyAyIF0gPSB1bnF1b3RlZC5zbGljZSggMCwgZXhjZXNzICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJldHVybiBvbmx5IGNhcHR1cmVzIG5lZWRlZCBieSB0aGUgcHNldWRvIGZpbHRlciBtZXRob2QgKHR5cGUgYW5kIGFyZ3VtZW50KVxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCAzICk7XG5cdFx0fVxuXHR9LFxuXG5cdGZpbHRlcjoge1xuXG5cdFx0XCJUQUdcIjogZnVuY3Rpb24oIG5vZGVOYW1lU2VsZWN0b3IgKSB7XG5cdFx0XHR2YXIgbm9kZU5hbWUgPSBub2RlTmFtZVNlbGVjdG9yLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICkudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBub2RlTmFtZVNlbGVjdG9yID09PSBcIipcIiA/XG5cdFx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9IDpcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGVsZW0ubm9kZU5hbWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBub2RlTmFtZTtcblx0XHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJDTEFTU1wiOiBmdW5jdGlvbiggY2xhc3NOYW1lICkge1xuXHRcdFx0dmFyIHBhdHRlcm4gPSBjbGFzc0NhY2hlWyBjbGFzc05hbWUgKyBcIiBcIiBdO1xuXG5cdFx0XHRyZXR1cm4gcGF0dGVybiB8fFxuXHRcdFx0XHQoIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCBcIihefFwiICsgd2hpdGVzcGFjZSArXG5cdFx0XHRcdFx0XCIpXCIgKyBjbGFzc05hbWUgKyBcIihcIiArIHdoaXRlc3BhY2UgKyBcInwkKVwiICkgKSAmJiBjbGFzc0NhY2hlKFxuXHRcdFx0XHRcdFx0Y2xhc3NOYW1lLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHBhdHRlcm4udGVzdChcblx0XHRcdFx0XHRcdFx0XHR0eXBlb2YgZWxlbS5jbGFzc05hbWUgPT09IFwic3RyaW5nXCIgJiYgZWxlbS5jbGFzc05hbWUgfHxcblx0XHRcdFx0XHRcdFx0XHR0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGUgIT09IFwidW5kZWZpbmVkXCIgJiZcblx0XHRcdFx0XHRcdFx0XHRcdGVsZW0uZ2V0QXR0cmlidXRlKCBcImNsYXNzXCIgKSB8fFxuXHRcdFx0XHRcdFx0XHRcdFwiXCJcblx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0fSApO1xuXHRcdH0sXG5cblx0XHRcIkFUVFJcIjogZnVuY3Rpb24oIG5hbWUsIG9wZXJhdG9yLCBjaGVjayApIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIHJlc3VsdCA9IFNpenpsZS5hdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHRcdFx0aWYgKCByZXN1bHQgPT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXR1cm4gb3BlcmF0b3IgPT09IFwiIT1cIjtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoICFvcGVyYXRvciApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJlc3VsdCArPSBcIlwiO1xuXG5cdFx0XHRcdC8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxuXHRcdFx0XHRyZXR1cm4gb3BlcmF0b3IgPT09IFwiPVwiID8gcmVzdWx0ID09PSBjaGVjayA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiIT1cIiA/IHJlc3VsdCAhPT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIl49XCIgPyBjaGVjayAmJiByZXN1bHQuaW5kZXhPZiggY2hlY2sgKSA9PT0gMCA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiKj1cIiA/IGNoZWNrICYmIHJlc3VsdC5pbmRleE9mKCBjaGVjayApID4gLTEgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIiQ9XCIgPyBjaGVjayAmJiByZXN1bHQuc2xpY2UoIC1jaGVjay5sZW5ndGggKSA9PT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIn49XCIgPyAoIFwiIFwiICsgcmVzdWx0LnJlcGxhY2UoIHJ3aGl0ZXNwYWNlLCBcIiBcIiApICsgXCIgXCIgKS5pbmRleE9mKCBjaGVjayApID4gLTEgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcInw9XCIgPyByZXN1bHQgPT09IGNoZWNrIHx8IHJlc3VsdC5zbGljZSggMCwgY2hlY2subGVuZ3RoICsgMSApID09PSBjaGVjayArIFwiLVwiIDpcblx0XHRcdFx0XHRmYWxzZTtcblx0XHRcdFx0LyogZXNsaW50LWVuYWJsZSBtYXgtbGVuICovXG5cblx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIHR5cGUsIHdoYXQsIF9hcmd1bWVudCwgZmlyc3QsIGxhc3QgKSB7XG5cdFx0XHR2YXIgc2ltcGxlID0gdHlwZS5zbGljZSggMCwgMyApICE9PSBcIm50aFwiLFxuXHRcdFx0XHRmb3J3YXJkID0gdHlwZS5zbGljZSggLTQgKSAhPT0gXCJsYXN0XCIsXG5cdFx0XHRcdG9mVHlwZSA9IHdoYXQgPT09IFwib2YtdHlwZVwiO1xuXG5cdFx0XHRyZXR1cm4gZmlyc3QgPT09IDEgJiYgbGFzdCA9PT0gMCA/XG5cblx0XHRcdFx0Ly8gU2hvcnRjdXQgZm9yIDpudGgtKihuKVxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRyZXR1cm4gISFlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRcdH0gOlxuXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBfY29udGV4dCwgeG1sICkge1xuXHRcdFx0XHRcdHZhciBjYWNoZSwgdW5pcXVlQ2FjaGUsIG91dGVyQ2FjaGUsIG5vZGUsIG5vZGVJbmRleCwgc3RhcnQsXG5cdFx0XHRcdFx0XHRkaXIgPSBzaW1wbGUgIT09IGZvcndhcmQgPyBcIm5leHRTaWJsaW5nXCIgOiBcInByZXZpb3VzU2libGluZ1wiLFxuXHRcdFx0XHRcdFx0cGFyZW50ID0gZWxlbS5wYXJlbnROb2RlLFxuXHRcdFx0XHRcdFx0bmFtZSA9IG9mVHlwZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCksXG5cdFx0XHRcdFx0XHR1c2VDYWNoZSA9ICF4bWwgJiYgIW9mVHlwZSxcblx0XHRcdFx0XHRcdGRpZmYgPSBmYWxzZTtcblxuXHRcdFx0XHRcdGlmICggcGFyZW50ICkge1xuXG5cdFx0XHRcdFx0XHQvLyA6KGZpcnN0fGxhc3R8b25seSktKGNoaWxkfG9mLXR5cGUpXG5cdFx0XHRcdFx0XHRpZiAoIHNpbXBsZSApIHtcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCBkaXIgKSB7XG5cdFx0XHRcdFx0XHRcdFx0bm9kZSA9IGVsZW07XG5cdFx0XHRcdFx0XHRcdFx0d2hpbGUgKCAoIG5vZGUgPSBub2RlWyBkaXIgXSApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBvZlR5cGUgP1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUgOlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRub2RlLm5vZGVUeXBlID09PSAxICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBSZXZlcnNlIGRpcmVjdGlvbiBmb3IgOm9ubHktKiAoaWYgd2UgaGF2ZW4ndCB5ZXQgZG9uZSBzbylcblx0XHRcdFx0XHRcdFx0XHRzdGFydCA9IGRpciA9IHR5cGUgPT09IFwib25seVwiICYmICFzdGFydCAmJiBcIm5leHRTaWJsaW5nXCI7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHN0YXJ0ID0gWyBmb3J3YXJkID8gcGFyZW50LmZpcnN0Q2hpbGQgOiBwYXJlbnQubGFzdENoaWxkIF07XG5cblx0XHRcdFx0XHRcdC8vIG5vbi14bWwgOm50aC1jaGlsZCguLi4pIHN0b3JlcyBjYWNoZSBkYXRhIG9uIGBwYXJlbnRgXG5cdFx0XHRcdFx0XHRpZiAoIGZvcndhcmQgJiYgdXNlQ2FjaGUgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gU2VlayBgZWxlbWAgZnJvbSBhIHByZXZpb3VzbHktY2FjaGVkIGluZGV4XG5cblx0XHRcdFx0XHRcdFx0Ly8gLi4uaW4gYSBnemlwLWZyaWVuZGx5IHdheVxuXHRcdFx0XHRcdFx0XHRub2RlID0gcGFyZW50O1xuXHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gbm9kZVsgZXhwYW5kbyBdIHx8ICggbm9kZVsgZXhwYW5kbyBdID0ge30gKTtcblxuXHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8OSBvbmx5XG5cdFx0XHRcdFx0XHRcdC8vIERlZmVuZCBhZ2FpbnN0IGNsb25lZCBhdHRyb3BlcnRpZXMgKGpRdWVyeSBnaC0xNzA5KVxuXHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZSA9IG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSB8fFxuXHRcdFx0XHRcdFx0XHRcdCggb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdID0ge30gKTtcblxuXHRcdFx0XHRcdFx0XHRjYWNoZSA9IHVuaXF1ZUNhY2hlWyB0eXBlIF0gfHwgW107XG5cdFx0XHRcdFx0XHRcdG5vZGVJbmRleCA9IGNhY2hlWyAwIF0gPT09IGRpcnJ1bnMgJiYgY2FjaGVbIDEgXTtcblx0XHRcdFx0XHRcdFx0ZGlmZiA9IG5vZGVJbmRleCAmJiBjYWNoZVsgMiBdO1xuXHRcdFx0XHRcdFx0XHRub2RlID0gbm9kZUluZGV4ICYmIHBhcmVudC5jaGlsZE5vZGVzWyBub2RlSW5kZXggXTtcblxuXHRcdFx0XHRcdFx0XHR3aGlsZSAoICggbm9kZSA9ICsrbm9kZUluZGV4ICYmIG5vZGUgJiYgbm9kZVsgZGlyIF0gfHxcblxuXHRcdFx0XHRcdFx0XHRcdC8vIEZhbGxiYWNrIHRvIHNlZWtpbmcgYGVsZW1gIGZyb20gdGhlIHN0YXJ0XG5cdFx0XHRcdFx0XHRcdFx0KCBkaWZmID0gbm9kZUluZGV4ID0gMCApIHx8IHN0YXJ0LnBvcCgpICkgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBXaGVuIGZvdW5kLCBjYWNoZSBpbmRleGVzIG9uIGBwYXJlbnRgIGFuZCBicmVha1xuXHRcdFx0XHRcdFx0XHRcdGlmICggbm9kZS5ub2RlVHlwZSA9PT0gMSAmJiArK2RpZmYgJiYgbm9kZSA9PT0gZWxlbSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlWyB0eXBlIF0gPSBbIGRpcnJ1bnMsIG5vZGVJbmRleCwgZGlmZiBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gVXNlIHByZXZpb3VzbHktY2FjaGVkIGVsZW1lbnQgaW5kZXggaWYgYXZhaWxhYmxlXG5cdFx0XHRcdFx0XHRcdGlmICggdXNlQ2FjaGUgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyAuLi5pbiBhIGd6aXAtZnJpZW5kbHkgd2F5XG5cdFx0XHRcdFx0XHRcdFx0bm9kZSA9IGVsZW07XG5cdFx0XHRcdFx0XHRcdFx0b3V0ZXJDYWNoZSA9IG5vZGVbIGV4cGFuZG8gXSB8fCAoIG5vZGVbIGV4cGFuZG8gXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8OSBvbmx5XG5cdFx0XHRcdFx0XHRcdFx0Ly8gRGVmZW5kIGFnYWluc3QgY2xvbmVkIGF0dHJvcGVydGllcyAoalF1ZXJ5IGdoLTE3MDkpXG5cdFx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGUgPSBvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gfHxcblx0XHRcdFx0XHRcdFx0XHRcdCggb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdID0ge30gKTtcblxuXHRcdFx0XHRcdFx0XHRcdGNhY2hlID0gdW5pcXVlQ2FjaGVbIHR5cGUgXSB8fCBbXTtcblx0XHRcdFx0XHRcdFx0XHRub2RlSW5kZXggPSBjYWNoZVsgMCBdID09PSBkaXJydW5zICYmIGNhY2hlWyAxIF07XG5cdFx0XHRcdFx0XHRcdFx0ZGlmZiA9IG5vZGVJbmRleDtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdC8vIHhtbCA6bnRoLWNoaWxkKC4uLilcblx0XHRcdFx0XHRcdFx0Ly8gb3IgOm50aC1sYXN0LWNoaWxkKC4uLikgb3IgOm50aCgtbGFzdCk/LW9mLXR5cGUoLi4uKVxuXHRcdFx0XHRcdFx0XHRpZiAoIGRpZmYgPT09IGZhbHNlICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gVXNlIHRoZSBzYW1lIGxvb3AgYXMgYWJvdmUgdG8gc2VlayBgZWxlbWAgZnJvbSB0aGUgc3RhcnRcblx0XHRcdFx0XHRcdFx0XHR3aGlsZSAoICggbm9kZSA9ICsrbm9kZUluZGV4ICYmIG5vZGUgJiYgbm9kZVsgZGlyIF0gfHxcblx0XHRcdFx0XHRcdFx0XHRcdCggZGlmZiA9IG5vZGVJbmRleCA9IDAgKSB8fCBzdGFydC5wb3AoKSApICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoICggb2ZUeXBlID9cblx0XHRcdFx0XHRcdFx0XHRcdFx0bm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBuYW1lIDpcblx0XHRcdFx0XHRcdFx0XHRcdFx0bm9kZS5ub2RlVHlwZSA9PT0gMSApICYmXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCsrZGlmZiApIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBDYWNoZSB0aGUgaW5kZXggb2YgZWFjaCBlbmNvdW50ZXJlZCBlbGVtZW50XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggdXNlQ2FjaGUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b3V0ZXJDYWNoZSA9IG5vZGVbIGV4cGFuZG8gXSB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KCBub2RlWyBleHBhbmRvIF0gPSB7fSApO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPDkgb25seVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIERlZmVuZCBhZ2FpbnN0IGNsb25lZCBhdHRyb3BlcnRpZXMgKGpRdWVyeSBnaC0xNzA5KVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQoIG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZVsgdHlwZSBdID0gWyBkaXJydW5zLCBkaWZmIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUgPT09IGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gSW5jb3Jwb3JhdGUgdGhlIG9mZnNldCwgdGhlbiBjaGVjayBhZ2FpbnN0IGN5Y2xlIHNpemVcblx0XHRcdFx0XHRcdGRpZmYgLT0gbGFzdDtcblx0XHRcdFx0XHRcdHJldHVybiBkaWZmID09PSBmaXJzdCB8fCAoIGRpZmYgJSBmaXJzdCA9PT0gMCAmJiBkaWZmIC8gZmlyc3QgPj0gMCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJQU0VVRE9cIjogZnVuY3Rpb24oIHBzZXVkbywgYXJndW1lbnQgKSB7XG5cblx0XHRcdC8vIHBzZXVkby1jbGFzcyBuYW1lcyBhcmUgY2FzZS1pbnNlbnNpdGl2ZVxuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNwc2V1ZG8tY2xhc3Nlc1xuXHRcdFx0Ly8gUHJpb3JpdGl6ZSBieSBjYXNlIHNlbnNpdGl2aXR5IGluIGNhc2UgY3VzdG9tIHBzZXVkb3MgYXJlIGFkZGVkIHdpdGggdXBwZXJjYXNlIGxldHRlcnNcblx0XHRcdC8vIFJlbWVtYmVyIHRoYXQgc2V0RmlsdGVycyBpbmhlcml0cyBmcm9tIHBzZXVkb3Ncblx0XHRcdHZhciBhcmdzLFxuXHRcdFx0XHRmbiA9IEV4cHIucHNldWRvc1sgcHNldWRvIF0gfHwgRXhwci5zZXRGaWx0ZXJzWyBwc2V1ZG8udG9Mb3dlckNhc2UoKSBdIHx8XG5cdFx0XHRcdFx0U2l6emxlLmVycm9yKCBcInVuc3VwcG9ydGVkIHBzZXVkbzogXCIgKyBwc2V1ZG8gKTtcblxuXHRcdFx0Ly8gVGhlIHVzZXIgbWF5IHVzZSBjcmVhdGVQc2V1ZG8gdG8gaW5kaWNhdGUgdGhhdFxuXHRcdFx0Ly8gYXJndW1lbnRzIGFyZSBuZWVkZWQgdG8gY3JlYXRlIHRoZSBmaWx0ZXIgZnVuY3Rpb25cblx0XHRcdC8vIGp1c3QgYXMgU2l6emxlIGRvZXNcblx0XHRcdGlmICggZm5bIGV4cGFuZG8gXSApIHtcblx0XHRcdFx0cmV0dXJuIGZuKCBhcmd1bWVudCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBCdXQgbWFpbnRhaW4gc3VwcG9ydCBmb3Igb2xkIHNpZ25hdHVyZXNcblx0XHRcdGlmICggZm4ubGVuZ3RoID4gMSApIHtcblx0XHRcdFx0YXJncyA9IFsgcHNldWRvLCBwc2V1ZG8sIFwiXCIsIGFyZ3VtZW50IF07XG5cdFx0XHRcdHJldHVybiBFeHByLnNldEZpbHRlcnMuaGFzT3duUHJvcGVydHkoIHBzZXVkby50b0xvd2VyQ2FzZSgpICkgP1xuXHRcdFx0XHRcdG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMgKSB7XG5cdFx0XHRcdFx0XHR2YXIgaWR4LFxuXHRcdFx0XHRcdFx0XHRtYXRjaGVkID0gZm4oIHNlZWQsIGFyZ3VtZW50ICksXG5cdFx0XHRcdFx0XHRcdGkgPSBtYXRjaGVkLmxlbmd0aDtcblx0XHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0XHRpZHggPSBpbmRleE9mKCBzZWVkLCBtYXRjaGVkWyBpIF0gKTtcblx0XHRcdFx0XHRcdFx0c2VlZFsgaWR4IF0gPSAhKCBtYXRjaGVzWyBpZHggXSA9IG1hdGNoZWRbIGkgXSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gKSA6XG5cdFx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZm4oIGVsZW0sIDAsIGFyZ3MgKTtcblx0XHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZm47XG5cdFx0fVxuXHR9LFxuXG5cdHBzZXVkb3M6IHtcblxuXHRcdC8vIFBvdGVudGlhbGx5IGNvbXBsZXggcHNldWRvc1xuXHRcdFwibm90XCI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXG5cdFx0XHQvLyBUcmltIHRoZSBzZWxlY3RvciBwYXNzZWQgdG8gY29tcGlsZVxuXHRcdFx0Ly8gdG8gYXZvaWQgdHJlYXRpbmcgbGVhZGluZyBhbmQgdHJhaWxpbmdcblx0XHRcdC8vIHNwYWNlcyBhcyBjb21iaW5hdG9yc1xuXHRcdFx0dmFyIGlucHV0ID0gW10sXG5cdFx0XHRcdHJlc3VsdHMgPSBbXSxcblx0XHRcdFx0bWF0Y2hlciA9IGNvbXBpbGUoIHNlbGVjdG9yLnJlcGxhY2UoIHJ0cmltLCBcIiQxXCIgKSApO1xuXG5cdFx0XHRyZXR1cm4gbWF0Y2hlclsgZXhwYW5kbyBdID9cblx0XHRcdFx0bWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcywgX2NvbnRleHQsIHhtbCApIHtcblx0XHRcdFx0XHR2YXIgZWxlbSxcblx0XHRcdFx0XHRcdHVubWF0Y2hlZCA9IG1hdGNoZXIoIHNlZWQsIG51bGwsIHhtbCwgW10gKSxcblx0XHRcdFx0XHRcdGkgPSBzZWVkLmxlbmd0aDtcblxuXHRcdFx0XHRcdC8vIE1hdGNoIGVsZW1lbnRzIHVubWF0Y2hlZCBieSBgbWF0Y2hlcmBcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdGlmICggKCBlbGVtID0gdW5tYXRjaGVkWyBpIF0gKSApIHtcblx0XHRcdFx0XHRcdFx0c2VlZFsgaSBdID0gISggbWF0Y2hlc1sgaSBdID0gZWxlbSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSApIDpcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0sIF9jb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0aW5wdXRbIDAgXSA9IGVsZW07XG5cdFx0XHRcdFx0bWF0Y2hlciggaW5wdXQsIG51bGwsIHhtbCwgcmVzdWx0cyApO1xuXG5cdFx0XHRcdFx0Ly8gRG9uJ3Qga2VlcCB0aGUgZWxlbWVudCAoaXNzdWUgIzI5OSlcblx0XHRcdFx0XHRpbnB1dFsgMCBdID0gbnVsbDtcblx0XHRcdFx0XHRyZXR1cm4gIXJlc3VsdHMucG9wKCk7XG5cdFx0XHRcdH07XG5cdFx0fSApLFxuXG5cdFx0XCJoYXNcIjogbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiBTaXp6bGUoIHNlbGVjdG9yLCBlbGVtICkubGVuZ3RoID4gMDtcblx0XHRcdH07XG5cdFx0fSApLFxuXG5cdFx0XCJjb250YWluc1wiOiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCB0ZXh0ICkge1xuXHRcdFx0dGV4dCA9IHRleHQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuICggZWxlbS50ZXh0Q29udGVudCB8fCBnZXRUZXh0KCBlbGVtICkgKS5pbmRleE9mKCB0ZXh0ICkgPiAtMTtcblx0XHRcdH07XG5cdFx0fSApLFxuXG5cdFx0Ly8gXCJXaGV0aGVyIGFuIGVsZW1lbnQgaXMgcmVwcmVzZW50ZWQgYnkgYSA6bGFuZygpIHNlbGVjdG9yXG5cdFx0Ly8gaXMgYmFzZWQgc29sZWx5IG9uIHRoZSBlbGVtZW50J3MgbGFuZ3VhZ2UgdmFsdWVcblx0XHQvLyBiZWluZyBlcXVhbCB0byB0aGUgaWRlbnRpZmllciBDLFxuXHRcdC8vIG9yIGJlZ2lubmluZyB3aXRoIHRoZSBpZGVudGlmaWVyIEMgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgXCItXCIuXG5cdFx0Ly8gVGhlIG1hdGNoaW5nIG9mIEMgYWdhaW5zdCB0aGUgZWxlbWVudCdzIGxhbmd1YWdlIHZhbHVlIGlzIHBlcmZvcm1lZCBjYXNlLWluc2Vuc2l0aXZlbHkuXG5cdFx0Ly8gVGhlIGlkZW50aWZpZXIgQyBkb2VzIG5vdCBoYXZlIHRvIGJlIGEgdmFsaWQgbGFuZ3VhZ2UgbmFtZS5cIlxuXHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jbGFuZy1wc2V1ZG9cblx0XHRcImxhbmdcIjogbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggbGFuZyApIHtcblxuXHRcdFx0Ly8gbGFuZyB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgaWRlbnRpZmllclxuXHRcdFx0aWYgKCAhcmlkZW50aWZpZXIudGVzdCggbGFuZyB8fCBcIlwiICkgKSB7XG5cdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBsYW5nOiBcIiArIGxhbmcgKTtcblx0XHRcdH1cblx0XHRcdGxhbmcgPSBsYW5nLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICkudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIGVsZW1MYW5nO1xuXHRcdFx0XHRkbyB7XG5cdFx0XHRcdFx0aWYgKCAoIGVsZW1MYW5nID0gZG9jdW1lbnRJc0hUTUwgP1xuXHRcdFx0XHRcdFx0ZWxlbS5sYW5nIDpcblx0XHRcdFx0XHRcdGVsZW0uZ2V0QXR0cmlidXRlKCBcInhtbDpsYW5nXCIgKSB8fCBlbGVtLmdldEF0dHJpYnV0ZSggXCJsYW5nXCIgKSApICkge1xuXG5cdFx0XHRcdFx0XHRlbGVtTGFuZyA9IGVsZW1MYW5nLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbUxhbmcgPT09IGxhbmcgfHwgZWxlbUxhbmcuaW5kZXhPZiggbGFuZyArIFwiLVwiICkgPT09IDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IHdoaWxlICggKCBlbGVtID0gZWxlbS5wYXJlbnROb2RlICkgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApO1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9O1xuXHRcdH0gKSxcblxuXHRcdC8vIE1pc2NlbGxhbmVvdXNcblx0XHRcInRhcmdldFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBoYXNoID0gd2luZG93LmxvY2F0aW9uICYmIHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHRcdFx0cmV0dXJuIGhhc2ggJiYgaGFzaC5zbGljZSggMSApID09PSBlbGVtLmlkO1xuXHRcdH0sXG5cblx0XHRcInJvb3RcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gZG9jRWxlbTtcblx0XHR9LFxuXG5cdFx0XCJmb2N1c1wiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmXG5cdFx0XHRcdCggIWRvY3VtZW50Lmhhc0ZvY3VzIHx8IGRvY3VtZW50Lmhhc0ZvY3VzKCkgKSAmJlxuXHRcdFx0XHQhISggZWxlbS50eXBlIHx8IGVsZW0uaHJlZiB8fCB+ZWxlbS50YWJJbmRleCApO1xuXHRcdH0sXG5cblx0XHQvLyBCb29sZWFuIHByb3BlcnRpZXNcblx0XHRcImVuYWJsZWRcIjogY3JlYXRlRGlzYWJsZWRQc2V1ZG8oIGZhbHNlICksXG5cdFx0XCJkaXNhYmxlZFwiOiBjcmVhdGVEaXNhYmxlZFBzZXVkbyggdHJ1ZSApLFxuXG5cdFx0XCJjaGVja2VkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHQvLyBJbiBDU1MzLCA6Y2hlY2tlZCBzaG91bGQgcmV0dXJuIGJvdGggY2hlY2tlZCBhbmQgc2VsZWN0ZWQgZWxlbWVudHNcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXG5cdFx0XHR2YXIgbm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gKCBub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmICEhZWxlbS5jaGVja2VkICkgfHxcblx0XHRcdFx0KCBub2RlTmFtZSA9PT0gXCJvcHRpb25cIiAmJiAhIWVsZW0uc2VsZWN0ZWQgKTtcblx0XHR9LFxuXG5cdFx0XCJzZWxlY3RlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0Ly8gQWNjZXNzaW5nIHRoaXMgcHJvcGVydHkgbWFrZXMgc2VsZWN0ZWQtYnktZGVmYXVsdFxuXHRcdFx0Ly8gb3B0aW9ucyBpbiBTYWZhcmkgd29yayBwcm9wZXJseVxuXHRcdFx0aWYgKCBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcblx0XHRcdFx0ZWxlbS5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXg7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBlbGVtLnNlbGVjdGVkID09PSB0cnVlO1xuXHRcdH0sXG5cblx0XHQvLyBDb250ZW50c1xuXHRcdFwiZW1wdHlcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jZW1wdHktcHNldWRvXG5cdFx0XHQvLyA6ZW1wdHkgaXMgbmVnYXRlZCBieSBlbGVtZW50ICgxKSBvciBjb250ZW50IG5vZGVzICh0ZXh0OiAzOyBjZGF0YTogNDsgZW50aXR5IHJlZjogNSksXG5cdFx0XHQvLyAgIGJ1dCBub3QgYnkgb3RoZXJzIChjb21tZW50OiA4OyBwcm9jZXNzaW5nIGluc3RydWN0aW9uOiA3OyBldGMuKVxuXHRcdFx0Ly8gbm9kZVR5cGUgPCA2IHdvcmtzIGJlY2F1c2UgYXR0cmlidXRlcyAoMikgZG8gbm90IGFwcGVhciBhcyBjaGlsZHJlblxuXHRcdFx0Zm9yICggZWxlbSA9IGVsZW0uZmlyc3RDaGlsZDsgZWxlbTsgZWxlbSA9IGVsZW0ubmV4dFNpYmxpbmcgKSB7XG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA8IDYgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9LFxuXG5cdFx0XCJwYXJlbnRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gIUV4cHIucHNldWRvc1sgXCJlbXB0eVwiIF0oIGVsZW0gKTtcblx0XHR9LFxuXG5cdFx0Ly8gRWxlbWVudC9pbnB1dCB0eXBlc1xuXHRcdFwiaGVhZGVyXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJoZWFkZXIudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImlucHV0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJpbnB1dHMudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImJ1dHRvblwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IFwiYnV0dG9uXCIgfHwgbmFtZSA9PT0gXCJidXR0b25cIjtcblx0XHR9LFxuXG5cdFx0XCJ0ZXh0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIGF0dHI7XG5cdFx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImlucHV0XCIgJiZcblx0XHRcdFx0ZWxlbS50eXBlID09PSBcInRleHRcIiAmJlxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFPDhcblx0XHRcdFx0Ly8gTmV3IEhUTUw1IGF0dHJpYnV0ZSB2YWx1ZXMgKGUuZy4sIFwic2VhcmNoXCIpIGFwcGVhciB3aXRoIGVsZW0udHlwZSA9PT0gXCJ0ZXh0XCJcblx0XHRcdFx0KCAoIGF0dHIgPSBlbGVtLmdldEF0dHJpYnV0ZSggXCJ0eXBlXCIgKSApID09IG51bGwgfHxcblx0XHRcdFx0XHRhdHRyLnRvTG93ZXJDYXNlKCkgPT09IFwidGV4dFwiICk7XG5cdFx0fSxcblxuXHRcdC8vIFBvc2l0aW9uLWluLWNvbGxlY3Rpb25cblx0XHRcImZpcnN0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIFsgMCBdO1xuXHRcdH0gKSxcblxuXHRcdFwibGFzdFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmdW5jdGlvbiggX21hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xuXHRcdFx0cmV0dXJuIFsgbGVuZ3RoIC0gMSBdO1xuXHRcdH0gKSxcblxuXHRcdFwiZXFcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oIF9tYXRjaEluZGV4ZXMsIGxlbmd0aCwgYXJndW1lbnQgKSB7XG5cdFx0XHRyZXR1cm4gWyBhcmd1bWVudCA8IDAgPyBhcmd1bWVudCArIGxlbmd0aCA6IGFyZ3VtZW50IF07XG5cdFx0fSApLFxuXG5cdFx0XCJldmVuXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHZhciBpID0gMDtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9ICksXG5cblx0XHRcIm9kZFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHR2YXIgaSA9IDE7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkgKz0gMiApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSApLFxuXG5cdFx0XCJsdFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xuXHRcdFx0dmFyIGkgPSBhcmd1bWVudCA8IDAgP1xuXHRcdFx0XHRhcmd1bWVudCArIGxlbmd0aCA6XG5cdFx0XHRcdGFyZ3VtZW50ID4gbGVuZ3RoID9cblx0XHRcdFx0XHRsZW5ndGggOlxuXHRcdFx0XHRcdGFyZ3VtZW50O1xuXHRcdFx0Zm9yICggOyAtLWkgPj0gMDsgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0gKSxcblxuXHRcdFwiZ3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpID0gYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudDtcblx0XHRcdGZvciAoIDsgKytpIDwgbGVuZ3RoOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSApXG5cdH1cbn07XG5cbkV4cHIucHNldWRvc1sgXCJudGhcIiBdID0gRXhwci5wc2V1ZG9zWyBcImVxXCIgXTtcblxuLy8gQWRkIGJ1dHRvbi9pbnB1dCB0eXBlIHBzZXVkb3NcbmZvciAoIGkgaW4geyByYWRpbzogdHJ1ZSwgY2hlY2tib3g6IHRydWUsIGZpbGU6IHRydWUsIHBhc3N3b3JkOiB0cnVlLCBpbWFnZTogdHJ1ZSB9ICkge1xuXHRFeHByLnBzZXVkb3NbIGkgXSA9IGNyZWF0ZUlucHV0UHNldWRvKCBpICk7XG59XG5mb3IgKCBpIGluIHsgc3VibWl0OiB0cnVlLCByZXNldDogdHJ1ZSB9ICkge1xuXHRFeHByLnBzZXVkb3NbIGkgXSA9IGNyZWF0ZUJ1dHRvblBzZXVkbyggaSApO1xufVxuXG4vLyBFYXN5IEFQSSBmb3IgY3JlYXRpbmcgbmV3IHNldEZpbHRlcnNcbmZ1bmN0aW9uIHNldEZpbHRlcnMoKSB7fVxuc2V0RmlsdGVycy5wcm90b3R5cGUgPSBFeHByLmZpbHRlcnMgPSBFeHByLnBzZXVkb3M7XG5FeHByLnNldEZpbHRlcnMgPSBuZXcgc2V0RmlsdGVycygpO1xuXG50b2tlbml6ZSA9IFNpenpsZS50b2tlbml6ZSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgcGFyc2VPbmx5ICkge1xuXHR2YXIgbWF0Y2hlZCwgbWF0Y2gsIHRva2VucywgdHlwZSxcblx0XHRzb0ZhciwgZ3JvdXBzLCBwcmVGaWx0ZXJzLFxuXHRcdGNhY2hlZCA9IHRva2VuQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXTtcblxuXHRpZiAoIGNhY2hlZCApIHtcblx0XHRyZXR1cm4gcGFyc2VPbmx5ID8gMCA6IGNhY2hlZC5zbGljZSggMCApO1xuXHR9XG5cblx0c29GYXIgPSBzZWxlY3Rvcjtcblx0Z3JvdXBzID0gW107XG5cdHByZUZpbHRlcnMgPSBFeHByLnByZUZpbHRlcjtcblxuXHR3aGlsZSAoIHNvRmFyICkge1xuXG5cdFx0Ly8gQ29tbWEgYW5kIGZpcnN0IHJ1blxuXHRcdGlmICggIW1hdGNoZWQgfHwgKCBtYXRjaCA9IHJjb21tYS5leGVjKCBzb0ZhciApICkgKSB7XG5cdFx0XHRpZiAoIG1hdGNoICkge1xuXG5cdFx0XHRcdC8vIERvbid0IGNvbnN1bWUgdHJhaWxpbmcgY29tbWFzIGFzIHZhbGlkXG5cdFx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoWyAwIF0ubGVuZ3RoICkgfHwgc29GYXI7XG5cdFx0XHR9XG5cdFx0XHRncm91cHMucHVzaCggKCB0b2tlbnMgPSBbXSApICk7XG5cdFx0fVxuXG5cdFx0bWF0Y2hlZCA9IGZhbHNlO1xuXG5cdFx0Ly8gQ29tYmluYXRvcnNcblx0XHRpZiAoICggbWF0Y2ggPSByY29tYmluYXRvcnMuZXhlYyggc29GYXIgKSApICkge1xuXHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XG5cdFx0XHR0b2tlbnMucHVzaCgge1xuXHRcdFx0XHR2YWx1ZTogbWF0Y2hlZCxcblxuXHRcdFx0XHQvLyBDYXN0IGRlc2NlbmRhbnQgY29tYmluYXRvcnMgdG8gc3BhY2Vcblx0XHRcdFx0dHlwZTogbWF0Y2hbIDAgXS5yZXBsYWNlKCBydHJpbSwgXCIgXCIgKVxuXHRcdFx0fSApO1xuXHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHR9XG5cblx0XHQvLyBGaWx0ZXJzXG5cdFx0Zm9yICggdHlwZSBpbiBFeHByLmZpbHRlciApIHtcblx0XHRcdGlmICggKCBtYXRjaCA9IG1hdGNoRXhwclsgdHlwZSBdLmV4ZWMoIHNvRmFyICkgKSAmJiAoICFwcmVGaWx0ZXJzWyB0eXBlIF0gfHxcblx0XHRcdFx0KCBtYXRjaCA9IHByZUZpbHRlcnNbIHR5cGUgXSggbWF0Y2ggKSApICkgKSB7XG5cdFx0XHRcdG1hdGNoZWQgPSBtYXRjaC5zaGlmdCgpO1xuXHRcdFx0XHR0b2tlbnMucHVzaCgge1xuXHRcdFx0XHRcdHZhbHVlOiBtYXRjaGVkLFxuXHRcdFx0XHRcdHR5cGU6IHR5cGUsXG5cdFx0XHRcdFx0bWF0Y2hlczogbWF0Y2hcblx0XHRcdFx0fSApO1xuXHRcdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaGVkLmxlbmd0aCApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggIW1hdGNoZWQgKSB7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgaW52YWxpZCBleGNlc3Ncblx0Ly8gaWYgd2UncmUganVzdCBwYXJzaW5nXG5cdC8vIE90aGVyd2lzZSwgdGhyb3cgYW4gZXJyb3Igb3IgcmV0dXJuIHRva2Vuc1xuXHRyZXR1cm4gcGFyc2VPbmx5ID9cblx0XHRzb0Zhci5sZW5ndGggOlxuXHRcdHNvRmFyID9cblx0XHRcdFNpenpsZS5lcnJvciggc2VsZWN0b3IgKSA6XG5cblx0XHRcdC8vIENhY2hlIHRoZSB0b2tlbnNcblx0XHRcdHRva2VuQ2FjaGUoIHNlbGVjdG9yLCBncm91cHMgKS5zbGljZSggMCApO1xufTtcblxuZnVuY3Rpb24gdG9TZWxlY3RvciggdG9rZW5zICkge1xuXHR2YXIgaSA9IDAsXG5cdFx0bGVuID0gdG9rZW5zLmxlbmd0aCxcblx0XHRzZWxlY3RvciA9IFwiXCI7XG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdHNlbGVjdG9yICs9IHRva2Vuc1sgaSBdLnZhbHVlO1xuXHR9XG5cdHJldHVybiBzZWxlY3Rvcjtcbn1cblxuZnVuY3Rpb24gYWRkQ29tYmluYXRvciggbWF0Y2hlciwgY29tYmluYXRvciwgYmFzZSApIHtcblx0dmFyIGRpciA9IGNvbWJpbmF0b3IuZGlyLFxuXHRcdHNraXAgPSBjb21iaW5hdG9yLm5leHQsXG5cdFx0a2V5ID0gc2tpcCB8fCBkaXIsXG5cdFx0Y2hlY2tOb25FbGVtZW50cyA9IGJhc2UgJiYga2V5ID09PSBcInBhcmVudE5vZGVcIixcblx0XHRkb25lTmFtZSA9IGRvbmUrKztcblxuXHRyZXR1cm4gY29tYmluYXRvci5maXJzdCA/XG5cblx0XHQvLyBDaGVjayBhZ2FpbnN0IGNsb3Nlc3QgYW5jZXN0b3IvcHJlY2VkaW5nIGVsZW1lbnRcblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSBlbGVtWyBkaXIgXSApICkge1xuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRyZXR1cm4gbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9IDpcblxuXHRcdC8vIENoZWNrIGFnYWluc3QgYWxsIGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50c1xuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR2YXIgb2xkQ2FjaGUsIHVuaXF1ZUNhY2hlLCBvdXRlckNhY2hlLFxuXHRcdFx0XHRuZXdDYWNoZSA9IFsgZGlycnVucywgZG9uZU5hbWUgXTtcblxuXHRcdFx0Ly8gV2UgY2FuJ3Qgc2V0IGFyYml0cmFyeSBkYXRhIG9uIFhNTCBub2Rlcywgc28gdGhleSBkb24ndCBiZW5lZml0IGZyb20gY29tYmluYXRvciBjYWNoaW5nXG5cdFx0XHRpZiAoIHhtbCApIHtcblx0XHRcdFx0d2hpbGUgKCAoIGVsZW0gPSBlbGVtWyBkaXIgXSApICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR3aGlsZSAoICggZWxlbSA9IGVsZW1bIGRpciBdICkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gZWxlbVsgZXhwYW5kbyBdIHx8ICggZWxlbVsgZXhwYW5kbyBdID0ge30gKTtcblxuXHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPDkgb25seVxuXHRcdFx0XHRcdFx0Ly8gRGVmZW5kIGFnYWluc3QgY2xvbmVkIGF0dHJvcGVydGllcyAoalF1ZXJ5IGdoLTE3MDkpXG5cdFx0XHRcdFx0XHR1bmlxdWVDYWNoZSA9IG91dGVyQ2FjaGVbIGVsZW0udW5pcXVlSUQgXSB8fFxuXHRcdFx0XHRcdFx0XHQoIG91dGVyQ2FjaGVbIGVsZW0udW5pcXVlSUQgXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdGlmICggc2tpcCAmJiBza2lwID09PSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgKSB7XG5cdFx0XHRcdFx0XHRcdGVsZW0gPSBlbGVtWyBkaXIgXSB8fCBlbGVtO1xuXHRcdFx0XHRcdFx0fSBlbHNlIGlmICggKCBvbGRDYWNoZSA9IHVuaXF1ZUNhY2hlWyBrZXkgXSApICYmXG5cdFx0XHRcdFx0XHRcdG9sZENhY2hlWyAwIF0gPT09IGRpcnJ1bnMgJiYgb2xkQ2FjaGVbIDEgXSA9PT0gZG9uZU5hbWUgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQXNzaWduIHRvIG5ld0NhY2hlIHNvIHJlc3VsdHMgYmFjay1wcm9wYWdhdGUgdG8gcHJldmlvdXMgZWxlbWVudHNcblx0XHRcdFx0XHRcdFx0cmV0dXJuICggbmV3Q2FjaGVbIDIgXSA9IG9sZENhY2hlWyAyIF0gKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gUmV1c2UgbmV3Y2FjaGUgc28gcmVzdWx0cyBiYWNrLXByb3BhZ2F0ZSB0byBwcmV2aW91cyBlbGVtZW50c1xuXHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZVsga2V5IF0gPSBuZXdDYWNoZTtcblxuXHRcdFx0XHRcdFx0XHQvLyBBIG1hdGNoIG1lYW5zIHdlJ3JlIGRvbmU7IGEgZmFpbCBtZWFucyB3ZSBoYXZlIHRvIGtlZXAgY2hlY2tpbmdcblx0XHRcdFx0XHRcdFx0aWYgKCAoIG5ld0NhY2hlWyAyIF0gPSBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApICkge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fTtcbn1cblxuZnVuY3Rpb24gZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICkge1xuXHRyZXR1cm4gbWF0Y2hlcnMubGVuZ3RoID4gMSA/XG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciBpID0gbWF0Y2hlcnMubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggIW1hdGNoZXJzWyBpIF0oIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSA6XG5cdFx0bWF0Y2hlcnNbIDAgXTtcbn1cblxuZnVuY3Rpb24gbXVsdGlwbGVDb250ZXh0cyggc2VsZWN0b3IsIGNvbnRleHRzLCByZXN1bHRzICkge1xuXHR2YXIgaSA9IDAsXG5cdFx0bGVuID0gY29udGV4dHMubGVuZ3RoO1xuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRTaXp6bGUoIHNlbGVjdG9yLCBjb250ZXh0c1sgaSBdLCByZXN1bHRzICk7XG5cdH1cblx0cmV0dXJuIHJlc3VsdHM7XG59XG5cbmZ1bmN0aW9uIGNvbmRlbnNlKCB1bm1hdGNoZWQsIG1hcCwgZmlsdGVyLCBjb250ZXh0LCB4bWwgKSB7XG5cdHZhciBlbGVtLFxuXHRcdG5ld1VubWF0Y2hlZCA9IFtdLFxuXHRcdGkgPSAwLFxuXHRcdGxlbiA9IHVubWF0Y2hlZC5sZW5ndGgsXG5cdFx0bWFwcGVkID0gbWFwICE9IG51bGw7XG5cblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0aWYgKCAoIGVsZW0gPSB1bm1hdGNoZWRbIGkgXSApICkge1xuXHRcdFx0aWYgKCAhZmlsdGVyIHx8IGZpbHRlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdG5ld1VubWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdGlmICggbWFwcGVkICkge1xuXHRcdFx0XHRcdG1hcC5wdXNoKCBpICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gbmV3VW5tYXRjaGVkO1xufVxuXG5mdW5jdGlvbiBzZXRNYXRjaGVyKCBwcmVGaWx0ZXIsIHNlbGVjdG9yLCBtYXRjaGVyLCBwb3N0RmlsdGVyLCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKSB7XG5cdGlmICggcG9zdEZpbHRlciAmJiAhcG9zdEZpbHRlclsgZXhwYW5kbyBdICkge1xuXHRcdHBvc3RGaWx0ZXIgPSBzZXRNYXRjaGVyKCBwb3N0RmlsdGVyICk7XG5cdH1cblx0aWYgKCBwb3N0RmluZGVyICYmICFwb3N0RmluZGVyWyBleHBhbmRvIF0gKSB7XG5cdFx0cG9zdEZpbmRlciA9IHNldE1hdGNoZXIoIHBvc3RGaW5kZXIsIHBvc3RTZWxlY3RvciApO1xuXHR9XG5cdHJldHVybiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBzZWVkLCByZXN1bHRzLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0dmFyIHRlbXAsIGksIGVsZW0sXG5cdFx0XHRwcmVNYXAgPSBbXSxcblx0XHRcdHBvc3RNYXAgPSBbXSxcblx0XHRcdHByZWV4aXN0aW5nID0gcmVzdWx0cy5sZW5ndGgsXG5cblx0XHRcdC8vIEdldCBpbml0aWFsIGVsZW1lbnRzIGZyb20gc2VlZCBvciBjb250ZXh0XG5cdFx0XHRlbGVtcyA9IHNlZWQgfHwgbXVsdGlwbGVDb250ZXh0cyhcblx0XHRcdFx0c2VsZWN0b3IgfHwgXCIqXCIsXG5cdFx0XHRcdGNvbnRleHQubm9kZVR5cGUgPyBbIGNvbnRleHQgXSA6IGNvbnRleHQsXG5cdFx0XHRcdFtdXG5cdFx0XHQpLFxuXG5cdFx0XHQvLyBQcmVmaWx0ZXIgdG8gZ2V0IG1hdGNoZXIgaW5wdXQsIHByZXNlcnZpbmcgYSBtYXAgZm9yIHNlZWQtcmVzdWx0cyBzeW5jaHJvbml6YXRpb25cblx0XHRcdG1hdGNoZXJJbiA9IHByZUZpbHRlciAmJiAoIHNlZWQgfHwgIXNlbGVjdG9yICkgP1xuXHRcdFx0XHRjb25kZW5zZSggZWxlbXMsIHByZU1hcCwgcHJlRmlsdGVyLCBjb250ZXh0LCB4bWwgKSA6XG5cdFx0XHRcdGVsZW1zLFxuXG5cdFx0XHRtYXRjaGVyT3V0ID0gbWF0Y2hlciA/XG5cblx0XHRcdFx0Ly8gSWYgd2UgaGF2ZSBhIHBvc3RGaW5kZXIsIG9yIGZpbHRlcmVkIHNlZWQsIG9yIG5vbi1zZWVkIHBvc3RGaWx0ZXIgb3IgcHJlZXhpc3RpbmcgcmVzdWx0cyxcblx0XHRcdFx0cG9zdEZpbmRlciB8fCAoIHNlZWQgPyBwcmVGaWx0ZXIgOiBwcmVleGlzdGluZyB8fCBwb3N0RmlsdGVyICkgP1xuXG5cdFx0XHRcdFx0Ly8gLi4uaW50ZXJtZWRpYXRlIHByb2Nlc3NpbmcgaXMgbmVjZXNzYXJ5XG5cdFx0XHRcdFx0W10gOlxuXG5cdFx0XHRcdFx0Ly8gLi4ub3RoZXJ3aXNlIHVzZSByZXN1bHRzIGRpcmVjdGx5XG5cdFx0XHRcdFx0cmVzdWx0cyA6XG5cdFx0XHRcdG1hdGNoZXJJbjtcblxuXHRcdC8vIEZpbmQgcHJpbWFyeSBtYXRjaGVzXG5cdFx0aWYgKCBtYXRjaGVyICkge1xuXHRcdFx0bWF0Y2hlciggbWF0Y2hlckluLCBtYXRjaGVyT3V0LCBjb250ZXh0LCB4bWwgKTtcblx0XHR9XG5cblx0XHQvLyBBcHBseSBwb3N0RmlsdGVyXG5cdFx0aWYgKCBwb3N0RmlsdGVyICkge1xuXHRcdFx0dGVtcCA9IGNvbmRlbnNlKCBtYXRjaGVyT3V0LCBwb3N0TWFwICk7XG5cdFx0XHRwb3N0RmlsdGVyKCB0ZW1wLCBbXSwgY29udGV4dCwgeG1sICk7XG5cblx0XHRcdC8vIFVuLW1hdGNoIGZhaWxpbmcgZWxlbWVudHMgYnkgbW92aW5nIHRoZW0gYmFjayB0byBtYXRjaGVySW5cblx0XHRcdGkgPSB0ZW1wLmxlbmd0aDtcblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRpZiAoICggZWxlbSA9IHRlbXBbIGkgXSApICkge1xuXHRcdFx0XHRcdG1hdGNoZXJPdXRbIHBvc3RNYXBbIGkgXSBdID0gISggbWF0Y2hlckluWyBwb3N0TWFwWyBpIF0gXSA9IGVsZW0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggc2VlZCApIHtcblx0XHRcdGlmICggcG9zdEZpbmRlciB8fCBwcmVGaWx0ZXIgKSB7XG5cdFx0XHRcdGlmICggcG9zdEZpbmRlciApIHtcblxuXHRcdFx0XHRcdC8vIEdldCB0aGUgZmluYWwgbWF0Y2hlck91dCBieSBjb25kZW5zaW5nIHRoaXMgaW50ZXJtZWRpYXRlIGludG8gcG9zdEZpbmRlciBjb250ZXh0c1xuXHRcdFx0XHRcdHRlbXAgPSBbXTtcblx0XHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRpZiAoICggZWxlbSA9IG1hdGNoZXJPdXRbIGkgXSApICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFJlc3RvcmUgbWF0Y2hlckluIHNpbmNlIGVsZW0gaXMgbm90IHlldCBhIGZpbmFsIG1hdGNoXG5cdFx0XHRcdFx0XHRcdHRlbXAucHVzaCggKCBtYXRjaGVySW5bIGkgXSA9IGVsZW0gKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRwb3N0RmluZGVyKCBudWxsLCAoIG1hdGNoZXJPdXQgPSBbXSApLCB0ZW1wLCB4bWwgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIE1vdmUgbWF0Y2hlZCBlbGVtZW50cyBmcm9tIHNlZWQgdG8gcmVzdWx0cyB0byBrZWVwIHRoZW0gc3luY2hyb25pemVkXG5cdFx0XHRcdGkgPSBtYXRjaGVyT3V0Lmxlbmd0aDtcblx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0aWYgKCAoIGVsZW0gPSBtYXRjaGVyT3V0WyBpIF0gKSAmJlxuXHRcdFx0XHRcdFx0KCB0ZW1wID0gcG9zdEZpbmRlciA/IGluZGV4T2YoIHNlZWQsIGVsZW0gKSA6IHByZU1hcFsgaSBdICkgPiAtMSApIHtcblxuXHRcdFx0XHRcdFx0c2VlZFsgdGVtcCBdID0gISggcmVzdWx0c1sgdGVtcCBdID0gZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0Ly8gQWRkIGVsZW1lbnRzIHRvIHJlc3VsdHMsIHRocm91Z2ggcG9zdEZpbmRlciBpZiBkZWZpbmVkXG5cdFx0fSBlbHNlIHtcblx0XHRcdG1hdGNoZXJPdXQgPSBjb25kZW5zZShcblx0XHRcdFx0bWF0Y2hlck91dCA9PT0gcmVzdWx0cyA/XG5cdFx0XHRcdFx0bWF0Y2hlck91dC5zcGxpY2UoIHByZWV4aXN0aW5nLCBtYXRjaGVyT3V0Lmxlbmd0aCApIDpcblx0XHRcdFx0XHRtYXRjaGVyT3V0XG5cdFx0XHQpO1xuXHRcdFx0aWYgKCBwb3N0RmluZGVyICkge1xuXHRcdFx0XHRwb3N0RmluZGVyKCBudWxsLCByZXN1bHRzLCBtYXRjaGVyT3V0LCB4bWwgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIG1hdGNoZXJPdXQgKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gKTtcbn1cblxuZnVuY3Rpb24gbWF0Y2hlckZyb21Ub2tlbnMoIHRva2VucyApIHtcblx0dmFyIGNoZWNrQ29udGV4dCwgbWF0Y2hlciwgaixcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxuXHRcdGxlYWRpbmdSZWxhdGl2ZSA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1sgMCBdLnR5cGUgXSxcblx0XHRpbXBsaWNpdFJlbGF0aXZlID0gbGVhZGluZ1JlbGF0aXZlIHx8IEV4cHIucmVsYXRpdmVbIFwiIFwiIF0sXG5cdFx0aSA9IGxlYWRpbmdSZWxhdGl2ZSA/IDEgOiAwLFxuXG5cdFx0Ly8gVGhlIGZvdW5kYXRpb25hbCBtYXRjaGVyIGVuc3VyZXMgdGhhdCBlbGVtZW50cyBhcmUgcmVhY2hhYmxlIGZyb20gdG9wLWxldmVsIGNvbnRleHQocylcblx0XHRtYXRjaENvbnRleHQgPSBhZGRDb21iaW5hdG9yKCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBjaGVja0NvbnRleHQ7XG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxuXHRcdG1hdGNoQW55Q29udGV4dCA9IGFkZENvbWJpbmF0b3IoIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGluZGV4T2YoIGNoZWNrQ29udGV4dCwgZWxlbSApID4gLTE7XG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxuXHRcdG1hdGNoZXJzID0gWyBmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0dmFyIHJldCA9ICggIWxlYWRpbmdSZWxhdGl2ZSAmJiAoIHhtbCB8fCBjb250ZXh0ICE9PSBvdXRlcm1vc3RDb250ZXh0ICkgKSB8fCAoXG5cdFx0XHRcdCggY2hlY2tDb250ZXh0ID0gY29udGV4dCApLm5vZGVUeXBlID9cblx0XHRcdFx0XHRtYXRjaENvbnRleHQoIGVsZW0sIGNvbnRleHQsIHhtbCApIDpcblx0XHRcdFx0XHRtYXRjaEFueUNvbnRleHQoIGVsZW0sIGNvbnRleHQsIHhtbCApICk7XG5cblx0XHRcdC8vIEF2b2lkIGhhbmdpbmcgb250byBlbGVtZW50IChpc3N1ZSAjMjk5KVxuXHRcdFx0Y2hlY2tDb250ZXh0ID0gbnVsbDtcblx0XHRcdHJldHVybiByZXQ7XG5cdFx0fSBdO1xuXG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdGlmICggKCBtYXRjaGVyID0gRXhwci5yZWxhdGl2ZVsgdG9rZW5zWyBpIF0udHlwZSBdICkgKSB7XG5cdFx0XHRtYXRjaGVycyA9IFsgYWRkQ29tYmluYXRvciggZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICksIG1hdGNoZXIgKSBdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRtYXRjaGVyID0gRXhwci5maWx0ZXJbIHRva2Vuc1sgaSBdLnR5cGUgXS5hcHBseSggbnVsbCwgdG9rZW5zWyBpIF0ubWF0Y2hlcyApO1xuXG5cdFx0XHQvLyBSZXR1cm4gc3BlY2lhbCB1cG9uIHNlZWluZyBhIHBvc2l0aW9uYWwgbWF0Y2hlclxuXHRcdFx0aWYgKCBtYXRjaGVyWyBleHBhbmRvIF0gKSB7XG5cblx0XHRcdFx0Ly8gRmluZCB0aGUgbmV4dCByZWxhdGl2ZSBvcGVyYXRvciAoaWYgYW55KSBmb3IgcHJvcGVyIGhhbmRsaW5nXG5cdFx0XHRcdGogPSArK2k7XG5cdFx0XHRcdGZvciAoIDsgaiA8IGxlbjsgaisrICkge1xuXHRcdFx0XHRcdGlmICggRXhwci5yZWxhdGl2ZVsgdG9rZW5zWyBqIF0udHlwZSBdICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBzZXRNYXRjaGVyKFxuXHRcdFx0XHRcdGkgPiAxICYmIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApLFxuXHRcdFx0XHRcdGkgPiAxICYmIHRvU2VsZWN0b3IoXG5cblx0XHRcdFx0XHQvLyBJZiB0aGUgcHJlY2VkaW5nIHRva2VuIHdhcyBhIGRlc2NlbmRhbnQgY29tYmluYXRvciwgaW5zZXJ0IGFuIGltcGxpY2l0IGFueS1lbGVtZW50IGAqYFxuXHRcdFx0XHRcdHRva2Vuc1xuXHRcdFx0XHRcdFx0LnNsaWNlKCAwLCBpIC0gMSApXG5cdFx0XHRcdFx0XHQuY29uY2F0KCB7IHZhbHVlOiB0b2tlbnNbIGkgLSAyIF0udHlwZSA9PT0gXCIgXCIgPyBcIipcIiA6IFwiXCIgfSApXG5cdFx0XHRcdFx0KS5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksXG5cdFx0XHRcdFx0bWF0Y2hlcixcblx0XHRcdFx0XHRpIDwgaiAmJiBtYXRjaGVyRnJvbVRva2VucyggdG9rZW5zLnNsaWNlKCBpLCBqICkgKSxcblx0XHRcdFx0XHRqIDwgbGVuICYmIG1hdGNoZXJGcm9tVG9rZW5zKCAoIHRva2VucyA9IHRva2Vucy5zbGljZSggaiApICkgKSxcblx0XHRcdFx0XHRqIDwgbGVuICYmIHRvU2VsZWN0b3IoIHRva2VucyApXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRtYXRjaGVycy5wdXNoKCBtYXRjaGVyICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApO1xufVxuXG5mdW5jdGlvbiBtYXRjaGVyRnJvbUdyb3VwTWF0Y2hlcnMoIGVsZW1lbnRNYXRjaGVycywgc2V0TWF0Y2hlcnMgKSB7XG5cdHZhciBieVNldCA9IHNldE1hdGNoZXJzLmxlbmd0aCA+IDAsXG5cdFx0YnlFbGVtZW50ID0gZWxlbWVudE1hdGNoZXJzLmxlbmd0aCA+IDAsXG5cdFx0c3VwZXJNYXRjaGVyID0gZnVuY3Rpb24oIHNlZWQsIGNvbnRleHQsIHhtbCwgcmVzdWx0cywgb3V0ZXJtb3N0ICkge1xuXHRcdFx0dmFyIGVsZW0sIGosIG1hdGNoZXIsXG5cdFx0XHRcdG1hdGNoZWRDb3VudCA9IDAsXG5cdFx0XHRcdGkgPSBcIjBcIixcblx0XHRcdFx0dW5tYXRjaGVkID0gc2VlZCAmJiBbXSxcblx0XHRcdFx0c2V0TWF0Y2hlZCA9IFtdLFxuXHRcdFx0XHRjb250ZXh0QmFja3VwID0gb3V0ZXJtb3N0Q29udGV4dCxcblxuXHRcdFx0XHQvLyBXZSBtdXN0IGFsd2F5cyBoYXZlIGVpdGhlciBzZWVkIGVsZW1lbnRzIG9yIG91dGVybW9zdCBjb250ZXh0XG5cdFx0XHRcdGVsZW1zID0gc2VlZCB8fCBieUVsZW1lbnQgJiYgRXhwci5maW5kWyBcIlRBR1wiIF0oIFwiKlwiLCBvdXRlcm1vc3QgKSxcblxuXHRcdFx0XHQvLyBVc2UgaW50ZWdlciBkaXJydW5zIGlmZiB0aGlzIGlzIHRoZSBvdXRlcm1vc3QgbWF0Y2hlclxuXHRcdFx0XHRkaXJydW5zVW5pcXVlID0gKCBkaXJydW5zICs9IGNvbnRleHRCYWNrdXAgPT0gbnVsbCA/IDEgOiBNYXRoLnJhbmRvbSgpIHx8IDAuMSApLFxuXHRcdFx0XHRsZW4gPSBlbGVtcy5sZW5ndGg7XG5cblx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHRcdFx0XHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0XHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdFx0XHRcdG91dGVybW9zdENvbnRleHQgPSBjb250ZXh0ID09IGRvY3VtZW50IHx8IGNvbnRleHQgfHwgb3V0ZXJtb3N0O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgZWxlbWVudHMgcGFzc2luZyBlbGVtZW50TWF0Y2hlcnMgZGlyZWN0bHkgdG8gcmVzdWx0c1xuXHRcdFx0Ly8gU3VwcG9ydDogSUU8OSwgU2FmYXJpXG5cdFx0XHQvLyBUb2xlcmF0ZSBOb2RlTGlzdCBwcm9wZXJ0aWVzIChJRTogXCJsZW5ndGhcIjsgU2FmYXJpOiA8bnVtYmVyPikgbWF0Y2hpbmcgZWxlbWVudHMgYnkgaWRcblx0XHRcdGZvciAoIDsgaSAhPT0gbGVuICYmICggZWxlbSA9IGVsZW1zWyBpIF0gKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHRcdGlmICggYnlFbGVtZW50ICYmIGVsZW0gKSB7XG5cdFx0XHRcdFx0aiA9IDA7XG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdFx0XHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0XHRcdFx0XHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdFx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdFx0XHRcdGlmICggIWNvbnRleHQgJiYgZWxlbS5vd25lckRvY3VtZW50ICE9IGRvY3VtZW50ICkge1xuXHRcdFx0XHRcdFx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcblx0XHRcdFx0XHRcdHhtbCA9ICFkb2N1bWVudElzSFRNTDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0d2hpbGUgKCAoIG1hdGNoZXIgPSBlbGVtZW50TWF0Y2hlcnNbIGorKyBdICkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQgfHwgZG9jdW1lbnQsIHhtbCApICkge1xuXHRcdFx0XHRcdFx0XHRyZXN1bHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xuXHRcdFx0XHRcdFx0ZGlycnVucyA9IGRpcnJ1bnNVbmlxdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gVHJhY2sgdW5tYXRjaGVkIGVsZW1lbnRzIGZvciBzZXQgZmlsdGVyc1xuXHRcdFx0XHRpZiAoIGJ5U2V0ICkge1xuXG5cdFx0XHRcdFx0Ly8gVGhleSB3aWxsIGhhdmUgZ29uZSB0aHJvdWdoIGFsbCBwb3NzaWJsZSBtYXRjaGVyc1xuXHRcdFx0XHRcdGlmICggKCBlbGVtID0gIW1hdGNoZXIgJiYgZWxlbSApICkge1xuXHRcdFx0XHRcdFx0bWF0Y2hlZENvdW50LS07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gTGVuZ3RoZW4gdGhlIGFycmF5IGZvciBldmVyeSBlbGVtZW50LCBtYXRjaGVkIG9yIG5vdFxuXHRcdFx0XHRcdGlmICggc2VlZCApIHtcblx0XHRcdFx0XHRcdHVubWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIGBpYCBpcyBub3cgdGhlIGNvdW50IG9mIGVsZW1lbnRzIHZpc2l0ZWQgYWJvdmUsIGFuZCBhZGRpbmcgaXQgdG8gYG1hdGNoZWRDb3VudGBcblx0XHRcdC8vIG1ha2VzIHRoZSBsYXR0ZXIgbm9ubmVnYXRpdmUuXG5cdFx0XHRtYXRjaGVkQ291bnQgKz0gaTtcblxuXHRcdFx0Ly8gQXBwbHkgc2V0IGZpbHRlcnMgdG8gdW5tYXRjaGVkIGVsZW1lbnRzXG5cdFx0XHQvLyBOT1RFOiBUaGlzIGNhbiBiZSBza2lwcGVkIGlmIHRoZXJlIGFyZSBubyB1bm1hdGNoZWQgZWxlbWVudHMgKGkuZS4sIGBtYXRjaGVkQ291bnRgXG5cdFx0XHQvLyBlcXVhbHMgYGlgKSwgdW5sZXNzIHdlIGRpZG4ndCB2aXNpdCBfYW55XyBlbGVtZW50cyBpbiB0aGUgYWJvdmUgbG9vcCBiZWNhdXNlIHdlIGhhdmVcblx0XHRcdC8vIG5vIGVsZW1lbnQgbWF0Y2hlcnMgYW5kIG5vIHNlZWQuXG5cdFx0XHQvLyBJbmNyZW1lbnRpbmcgYW4gaW5pdGlhbGx5LXN0cmluZyBcIjBcIiBgaWAgYWxsb3dzIGBpYCB0byByZW1haW4gYSBzdHJpbmcgb25seSBpbiB0aGF0XG5cdFx0XHQvLyBjYXNlLCB3aGljaCB3aWxsIHJlc3VsdCBpbiBhIFwiMDBcIiBgbWF0Y2hlZENvdW50YCB0aGF0IGRpZmZlcnMgZnJvbSBgaWAgYnV0IGlzIGFsc29cblx0XHRcdC8vIG51bWVyaWNhbGx5IHplcm8uXG5cdFx0XHRpZiAoIGJ5U2V0ICYmIGkgIT09IG1hdGNoZWRDb3VudCApIHtcblx0XHRcdFx0aiA9IDA7XG5cdFx0XHRcdHdoaWxlICggKCBtYXRjaGVyID0gc2V0TWF0Y2hlcnNbIGorKyBdICkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlciggdW5tYXRjaGVkLCBzZXRNYXRjaGVkLCBjb250ZXh0LCB4bWwgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggc2VlZCApIHtcblxuXHRcdFx0XHRcdC8vIFJlaW50ZWdyYXRlIGVsZW1lbnQgbWF0Y2hlcyB0byBlbGltaW5hdGUgdGhlIG5lZWQgZm9yIHNvcnRpbmdcblx0XHRcdFx0XHRpZiAoIG1hdGNoZWRDb3VudCA+IDAgKSB7XG5cdFx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCAhKCB1bm1hdGNoZWRbIGkgXSB8fCBzZXRNYXRjaGVkWyBpIF0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHRzZXRNYXRjaGVkWyBpIF0gPSBwb3AuY2FsbCggcmVzdWx0cyApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gRGlzY2FyZCBpbmRleCBwbGFjZWhvbGRlciB2YWx1ZXMgdG8gZ2V0IG9ubHkgYWN0dWFsIG1hdGNoZXNcblx0XHRcdFx0XHRzZXRNYXRjaGVkID0gY29uZGVuc2UoIHNldE1hdGNoZWQgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFkZCBtYXRjaGVzIHRvIHJlc3VsdHNcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgc2V0TWF0Y2hlZCApO1xuXG5cdFx0XHRcdC8vIFNlZWRsZXNzIHNldCBtYXRjaGVzIHN1Y2NlZWRpbmcgbXVsdGlwbGUgc3VjY2Vzc2Z1bCBtYXRjaGVycyBzdGlwdWxhdGUgc29ydGluZ1xuXHRcdFx0XHRpZiAoIG91dGVybW9zdCAmJiAhc2VlZCAmJiBzZXRNYXRjaGVkLmxlbmd0aCA+IDAgJiZcblx0XHRcdFx0XHQoIG1hdGNoZWRDb3VudCArIHNldE1hdGNoZXJzLmxlbmd0aCApID4gMSApIHtcblxuXHRcdFx0XHRcdFNpenpsZS51bmlxdWVTb3J0KCByZXN1bHRzICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gT3ZlcnJpZGUgbWFuaXB1bGF0aW9uIG9mIGdsb2JhbHMgYnkgbmVzdGVkIG1hdGNoZXJzXG5cdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblx0XHRcdFx0ZGlycnVucyA9IGRpcnJ1bnNVbmlxdWU7XG5cdFx0XHRcdG91dGVybW9zdENvbnRleHQgPSBjb250ZXh0QmFja3VwO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdW5tYXRjaGVkO1xuXHRcdH07XG5cblx0cmV0dXJuIGJ5U2V0ID9cblx0XHRtYXJrRnVuY3Rpb24oIHN1cGVyTWF0Y2hlciApIDpcblx0XHRzdXBlck1hdGNoZXI7XG59XG5cbmNvbXBpbGUgPSBTaXp6bGUuY29tcGlsZSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgbWF0Y2ggLyogSW50ZXJuYWwgVXNlIE9ubHkgKi8gKSB7XG5cdHZhciBpLFxuXHRcdHNldE1hdGNoZXJzID0gW10sXG5cdFx0ZWxlbWVudE1hdGNoZXJzID0gW10sXG5cdFx0Y2FjaGVkID0gY29tcGlsZXJDYWNoZVsgc2VsZWN0b3IgKyBcIiBcIiBdO1xuXG5cdGlmICggIWNhY2hlZCApIHtcblxuXHRcdC8vIEdlbmVyYXRlIGEgZnVuY3Rpb24gb2YgcmVjdXJzaXZlIGZ1bmN0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRvIGNoZWNrIGVhY2ggZWxlbWVudFxuXHRcdGlmICggIW1hdGNoICkge1xuXHRcdFx0bWF0Y2ggPSB0b2tlbml6ZSggc2VsZWN0b3IgKTtcblx0XHR9XG5cdFx0aSA9IG1hdGNoLmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdGNhY2hlZCA9IG1hdGNoZXJGcm9tVG9rZW5zKCBtYXRjaFsgaSBdICk7XG5cdFx0XHRpZiAoIGNhY2hlZFsgZXhwYW5kbyBdICkge1xuXHRcdFx0XHRzZXRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1lbnRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWNoZSB0aGUgY29tcGlsZWQgZnVuY3Rpb25cblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlKFxuXHRcdFx0c2VsZWN0b3IsXG5cdFx0XHRtYXRjaGVyRnJvbUdyb3VwTWF0Y2hlcnMoIGVsZW1lbnRNYXRjaGVycywgc2V0TWF0Y2hlcnMgKVxuXHRcdCk7XG5cblx0XHQvLyBTYXZlIHNlbGVjdG9yIGFuZCB0b2tlbml6YXRpb25cblx0XHRjYWNoZWQuc2VsZWN0b3IgPSBzZWxlY3Rvcjtcblx0fVxuXHRyZXR1cm4gY2FjaGVkO1xufTtcblxuLyoqXG4gKiBBIGxvdy1sZXZlbCBzZWxlY3Rpb24gZnVuY3Rpb24gdGhhdCB3b3JrcyB3aXRoIFNpenpsZSdzIGNvbXBpbGVkXG4gKiAgc2VsZWN0b3IgZnVuY3Rpb25zXG4gKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gc2VsZWN0b3IgQSBzZWxlY3RvciBvciBhIHByZS1jb21waWxlZFxuICogIHNlbGVjdG9yIGZ1bmN0aW9uIGJ1aWx0IHdpdGggU2l6emxlLmNvbXBpbGVcbiAqIEBwYXJhbSB7RWxlbWVudH0gY29udGV4dFxuICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdHNdXG4gKiBAcGFyYW0ge0FycmF5fSBbc2VlZF0gQSBzZXQgb2YgZWxlbWVudHMgdG8gbWF0Y2ggYWdhaW5zdFxuICovXG5zZWxlY3QgPSBTaXp6bGUuc2VsZWN0ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICkge1xuXHR2YXIgaSwgdG9rZW5zLCB0b2tlbiwgdHlwZSwgZmluZCxcblx0XHRjb21waWxlZCA9IHR5cGVvZiBzZWxlY3RvciA9PT0gXCJmdW5jdGlvblwiICYmIHNlbGVjdG9yLFxuXHRcdG1hdGNoID0gIXNlZWQgJiYgdG9rZW5pemUoICggc2VsZWN0b3IgPSBjb21waWxlZC5zZWxlY3RvciB8fCBzZWxlY3RvciApICk7XG5cblx0cmVzdWx0cyA9IHJlc3VsdHMgfHwgW107XG5cblx0Ly8gVHJ5IHRvIG1pbmltaXplIG9wZXJhdGlvbnMgaWYgdGhlcmUgaXMgb25seSBvbmUgc2VsZWN0b3IgaW4gdGhlIGxpc3QgYW5kIG5vIHNlZWRcblx0Ly8gKHRoZSBsYXR0ZXIgb2Ygd2hpY2ggZ3VhcmFudGVlcyB1cyBjb250ZXh0KVxuXHRpZiAoIG1hdGNoLmxlbmd0aCA9PT0gMSApIHtcblxuXHRcdC8vIFJlZHVjZSBjb250ZXh0IGlmIHRoZSBsZWFkaW5nIGNvbXBvdW5kIHNlbGVjdG9yIGlzIGFuIElEXG5cdFx0dG9rZW5zID0gbWF0Y2hbIDAgXSA9IG1hdGNoWyAwIF0uc2xpY2UoIDAgKTtcblx0XHRpZiAoIHRva2Vucy5sZW5ndGggPiAyICYmICggdG9rZW4gPSB0b2tlbnNbIDAgXSApLnR5cGUgPT09IFwiSURcIiAmJlxuXHRcdFx0Y29udGV4dC5ub2RlVHlwZSA9PT0gOSAmJiBkb2N1bWVudElzSFRNTCAmJiBFeHByLnJlbGF0aXZlWyB0b2tlbnNbIDEgXS50eXBlIF0gKSB7XG5cblx0XHRcdGNvbnRleHQgPSAoIEV4cHIuZmluZFsgXCJJRFwiIF0oIHRva2VuLm1hdGNoZXNbIDAgXVxuXHRcdFx0XHQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKSwgY29udGV4dCApIHx8IFtdIClbIDAgXTtcblx0XHRcdGlmICggIWNvbnRleHQgKSB7XG5cdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXG5cdFx0XHQvLyBQcmVjb21waWxlZCBtYXRjaGVycyB3aWxsIHN0aWxsIHZlcmlmeSBhbmNlc3RyeSwgc28gc3RlcCB1cCBhIGxldmVsXG5cdFx0XHR9IGVsc2UgaWYgKCBjb21waWxlZCApIHtcblx0XHRcdFx0Y29udGV4dCA9IGNvbnRleHQucGFyZW50Tm9kZTtcblx0XHRcdH1cblxuXHRcdFx0c2VsZWN0b3IgPSBzZWxlY3Rvci5zbGljZSggdG9rZW5zLnNoaWZ0KCkudmFsdWUubGVuZ3RoICk7XG5cdFx0fVxuXG5cdFx0Ly8gRmV0Y2ggYSBzZWVkIHNldCBmb3IgcmlnaHQtdG8tbGVmdCBtYXRjaGluZ1xuXHRcdGkgPSBtYXRjaEV4cHJbIFwibmVlZHNDb250ZXh0XCIgXS50ZXN0KCBzZWxlY3RvciApID8gMCA6IHRva2Vucy5sZW5ndGg7XG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHR0b2tlbiA9IHRva2Vuc1sgaSBdO1xuXG5cdFx0XHQvLyBBYm9ydCBpZiB3ZSBoaXQgYSBjb21iaW5hdG9yXG5cdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbICggdHlwZSA9IHRva2VuLnR5cGUgKSBdICkge1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGlmICggKCBmaW5kID0gRXhwci5maW5kWyB0eXBlIF0gKSApIHtcblxuXHRcdFx0XHQvLyBTZWFyY2gsIGV4cGFuZGluZyBjb250ZXh0IGZvciBsZWFkaW5nIHNpYmxpbmcgY29tYmluYXRvcnNcblx0XHRcdFx0aWYgKCAoIHNlZWQgPSBmaW5kKFxuXHRcdFx0XHRcdHRva2VuLm1hdGNoZXNbIDAgXS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLFxuXHRcdFx0XHRcdHJzaWJsaW5nLnRlc3QoIHRva2Vuc1sgMCBdLnR5cGUgKSAmJiB0ZXN0Q29udGV4dCggY29udGV4dC5wYXJlbnROb2RlICkgfHxcblx0XHRcdFx0XHRcdGNvbnRleHRcblx0XHRcdFx0KSApICkge1xuXG5cdFx0XHRcdFx0Ly8gSWYgc2VlZCBpcyBlbXB0eSBvciBubyB0b2tlbnMgcmVtYWluLCB3ZSBjYW4gcmV0dXJuIGVhcmx5XG5cdFx0XHRcdFx0dG9rZW5zLnNwbGljZSggaSwgMSApO1xuXHRcdFx0XHRcdHNlbGVjdG9yID0gc2VlZC5sZW5ndGggJiYgdG9TZWxlY3RvciggdG9rZW5zICk7XG5cdFx0XHRcdFx0aWYgKCAhc2VsZWN0b3IgKSB7XG5cdFx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBzZWVkICk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIENvbXBpbGUgYW5kIGV4ZWN1dGUgYSBmaWx0ZXJpbmcgZnVuY3Rpb24gaWYgb25lIGlzIG5vdCBwcm92aWRlZFxuXHQvLyBQcm92aWRlIGBtYXRjaGAgdG8gYXZvaWQgcmV0b2tlbml6YXRpb24gaWYgd2UgbW9kaWZpZWQgdGhlIHNlbGVjdG9yIGFib3ZlXG5cdCggY29tcGlsZWQgfHwgY29tcGlsZSggc2VsZWN0b3IsIG1hdGNoICkgKShcblx0XHRzZWVkLFxuXHRcdGNvbnRleHQsXG5cdFx0IWRvY3VtZW50SXNIVE1MLFxuXHRcdHJlc3VsdHMsXG5cdFx0IWNvbnRleHQgfHwgcnNpYmxpbmcudGVzdCggc2VsZWN0b3IgKSAmJiB0ZXN0Q29udGV4dCggY29udGV4dC5wYXJlbnROb2RlICkgfHwgY29udGV4dFxuXHQpO1xuXHRyZXR1cm4gcmVzdWx0cztcbn07XG5cbi8vIE9uZS10aW1lIGFzc2lnbm1lbnRzXG5cbi8vIFNvcnQgc3RhYmlsaXR5XG5zdXBwb3J0LnNvcnRTdGFibGUgPSBleHBhbmRvLnNwbGl0KCBcIlwiICkuc29ydCggc29ydE9yZGVyICkuam9pbiggXCJcIiApID09PSBleHBhbmRvO1xuXG4vLyBTdXBwb3J0OiBDaHJvbWUgMTQtMzUrXG4vLyBBbHdheXMgYXNzdW1lIGR1cGxpY2F0ZXMgaWYgdGhleSBhcmVuJ3QgcGFzc2VkIHRvIHRoZSBjb21wYXJpc29uIGZ1bmN0aW9uXG5zdXBwb3J0LmRldGVjdER1cGxpY2F0ZXMgPSAhIWhhc0R1cGxpY2F0ZTtcblxuLy8gSW5pdGlhbGl6ZSBhZ2FpbnN0IHRoZSBkZWZhdWx0IGRvY3VtZW50XG5zZXREb2N1bWVudCgpO1xuXG4vLyBTdXBwb3J0OiBXZWJraXQ8NTM3LjMyIC0gU2FmYXJpIDYuMC4zL0Nocm9tZSAyNSAoZml4ZWQgaW4gQ2hyb21lIDI3KVxuLy8gRGV0YWNoZWQgbm9kZXMgY29uZm91bmRpbmdseSBmb2xsb3cgKmVhY2ggb3RoZXIqXG5zdXBwb3J0LnNvcnREZXRhY2hlZCA9IGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXG5cdC8vIFNob3VsZCByZXR1cm4gMSwgYnV0IHJldHVybnMgNCAoZm9sbG93aW5nKVxuXHRyZXR1cm4gZWwuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZmllbGRzZXRcIiApICkgJiAxO1xufSApO1xuXG4vLyBTdXBwb3J0OiBJRTw4XG4vLyBQcmV2ZW50IGF0dHJpYnV0ZS9wcm9wZXJ0eSBcImludGVycG9sYXRpb25cIlxuLy8gaHR0cHM6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNjQyOSUyOFZTLjg1JTI5LmFzcHhcbmlmICggIWFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXHRlbC5pbm5lckhUTUwgPSBcIjxhIGhyZWY9JyMnPjwvYT5cIjtcblx0cmV0dXJuIGVsLmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKCBcImhyZWZcIiApID09PSBcIiNcIjtcbn0gKSApIHtcblx0YWRkSGFuZGxlKCBcInR5cGV8aHJlZnxoZWlnaHR8d2lkdGhcIiwgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkge1xuXHRcdGlmICggIWlzWE1MICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lLCBuYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwidHlwZVwiID8gMSA6IDIgKTtcblx0XHR9XG5cdH0gKTtcbn1cblxuLy8gU3VwcG9ydDogSUU8OVxuLy8gVXNlIGRlZmF1bHRWYWx1ZSBpbiBwbGFjZSBvZiBnZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiKVxuaWYgKCAhc3VwcG9ydC5hdHRyaWJ1dGVzIHx8ICFhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0ZWwuaW5uZXJIVE1MID0gXCI8aW5wdXQvPlwiO1xuXHRlbC5maXJzdENoaWxkLnNldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiLCBcIlwiICk7XG5cdHJldHVybiBlbC5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiICkgPT09IFwiXCI7XG59ICkgKSB7XG5cdGFkZEhhbmRsZSggXCJ2YWx1ZVwiLCBmdW5jdGlvbiggZWxlbSwgX25hbWUsIGlzWE1MICkge1xuXHRcdGlmICggIWlzWE1MICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJpbnB1dFwiICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGVmYXVsdFZhbHVlO1xuXHRcdH1cblx0fSApO1xufVxuXG4vLyBTdXBwb3J0OiBJRTw5XG4vLyBVc2UgZ2V0QXR0cmlidXRlTm9kZSB0byBmZXRjaCBib29sZWFucyB3aGVuIGdldEF0dHJpYnV0ZSBsaWVzXG5pZiAoICFhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0cmV0dXJuIGVsLmdldEF0dHJpYnV0ZSggXCJkaXNhYmxlZFwiICkgPT0gbnVsbDtcbn0gKSApIHtcblx0YWRkSGFuZGxlKCBib29sZWFucywgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkge1xuXHRcdHZhciB2YWw7XG5cdFx0aWYgKCAhaXNYTUwgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbVsgbmFtZSBdID09PSB0cnVlID8gbmFtZS50b0xvd2VyQ2FzZSgpIDpcblx0XHRcdFx0KCB2YWwgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIG5hbWUgKSApICYmIHZhbC5zcGVjaWZpZWQgP1xuXHRcdFx0XHRcdHZhbC52YWx1ZSA6XG5cdFx0XHRcdFx0bnVsbDtcblx0XHR9XG5cdH0gKTtcbn1cblxucmV0dXJuIFNpenpsZTtcblxufSApKCB3aW5kb3cgKTtcblxuXG5cbmpRdWVyeS5maW5kID0gU2l6emxlO1xualF1ZXJ5LmV4cHIgPSBTaXp6bGUuc2VsZWN0b3JzO1xuXG4vLyBEZXByZWNhdGVkXG5qUXVlcnkuZXhwclsgXCI6XCIgXSA9IGpRdWVyeS5leHByLnBzZXVkb3M7XG5qUXVlcnkudW5pcXVlU29ydCA9IGpRdWVyeS51bmlxdWUgPSBTaXp6bGUudW5pcXVlU29ydDtcbmpRdWVyeS50ZXh0ID0gU2l6emxlLmdldFRleHQ7XG5qUXVlcnkuaXNYTUxEb2MgPSBTaXp6bGUuaXNYTUw7XG5qUXVlcnkuY29udGFpbnMgPSBTaXp6bGUuY29udGFpbnM7XG5qUXVlcnkuZXNjYXBlU2VsZWN0b3IgPSBTaXp6bGUuZXNjYXBlO1xuXG5cblxuXG52YXIgZGlyID0gZnVuY3Rpb24oIGVsZW0sIGRpciwgdW50aWwgKSB7XG5cdHZhciBtYXRjaGVkID0gW10sXG5cdFx0dHJ1bmNhdGUgPSB1bnRpbCAhPT0gdW5kZWZpbmVkO1xuXG5cdHdoaWxlICggKCBlbGVtID0gZWxlbVsgZGlyIF0gKSAmJiBlbGVtLm5vZGVUeXBlICE9PSA5ICkge1xuXHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdGlmICggdHJ1bmNhdGUgJiYgalF1ZXJ5KCBlbGVtICkuaXMoIHVudGlsICkgKSB7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0bWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBtYXRjaGVkO1xufTtcblxuXG52YXIgc2libGluZ3MgPSBmdW5jdGlvbiggbiwgZWxlbSApIHtcblx0dmFyIG1hdGNoZWQgPSBbXTtcblxuXHRmb3IgKCA7IG47IG4gPSBuLm5leHRTaWJsaW5nICkge1xuXHRcdGlmICggbi5ub2RlVHlwZSA9PT0gMSAmJiBuICE9PSBlbGVtICkge1xuXHRcdFx0bWF0Y2hlZC5wdXNoKCBuICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIG1hdGNoZWQ7XG59O1xuXG5cbnZhciBybmVlZHNDb250ZXh0ID0galF1ZXJ5LmV4cHIubWF0Y2gubmVlZHNDb250ZXh0O1xuXG5cblxuZnVuY3Rpb24gbm9kZU5hbWUoIGVsZW0sIG5hbWUgKSB7XG5cblx0cmV0dXJuIGVsZW0ubm9kZU5hbWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cbn1cbnZhciByc2luZ2xlVGFnID0gKCAvXjwoW2Etel1bXlxcL1xcMD46XFx4MjBcXHRcXHJcXG5cXGZdKilbXFx4MjBcXHRcXHJcXG5cXGZdKlxcLz8+KD86PFxcL1xcMT58KSQvaSApO1xuXG5cblxuLy8gSW1wbGVtZW50IHRoZSBpZGVudGljYWwgZnVuY3Rpb25hbGl0eSBmb3IgZmlsdGVyIGFuZCBub3RcbmZ1bmN0aW9uIHdpbm5vdyggZWxlbWVudHMsIHF1YWxpZmllciwgbm90ICkge1xuXHRpZiAoIGlzRnVuY3Rpb24oIHF1YWxpZmllciApICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ3JlcCggZWxlbWVudHMsIGZ1bmN0aW9uKCBlbGVtLCBpICkge1xuXHRcdFx0cmV0dXJuICEhcXVhbGlmaWVyLmNhbGwoIGVsZW0sIGksIGVsZW0gKSAhPT0gbm90O1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIFNpbmdsZSBlbGVtZW50XG5cdGlmICggcXVhbGlmaWVyLm5vZGVUeXBlICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ3JlcCggZWxlbWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuICggZWxlbSA9PT0gcXVhbGlmaWVyICkgIT09IG5vdDtcblx0XHR9ICk7XG5cdH1cblxuXHQvLyBBcnJheWxpa2Ugb2YgZWxlbWVudHMgKGpRdWVyeSwgYXJndW1lbnRzLCBBcnJheSlcblx0aWYgKCB0eXBlb2YgcXVhbGlmaWVyICE9PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ3JlcCggZWxlbWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuICggaW5kZXhPZi5jYWxsKCBxdWFsaWZpZXIsIGVsZW0gKSA+IC0xICkgIT09IG5vdDtcblx0XHR9ICk7XG5cdH1cblxuXHQvLyBGaWx0ZXJlZCBkaXJlY3RseSBmb3IgYm90aCBzaW1wbGUgYW5kIGNvbXBsZXggc2VsZWN0b3JzXG5cdHJldHVybiBqUXVlcnkuZmlsdGVyKCBxdWFsaWZpZXIsIGVsZW1lbnRzLCBub3QgKTtcbn1cblxualF1ZXJ5LmZpbHRlciA9IGZ1bmN0aW9uKCBleHByLCBlbGVtcywgbm90ICkge1xuXHR2YXIgZWxlbSA9IGVsZW1zWyAwIF07XG5cblx0aWYgKCBub3QgKSB7XG5cdFx0ZXhwciA9IFwiOm5vdChcIiArIGV4cHIgKyBcIilcIjtcblx0fVxuXG5cdGlmICggZWxlbXMubGVuZ3RoID09PSAxICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvciggZWxlbSwgZXhwciApID8gWyBlbGVtIF0gOiBbXTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnkuZmluZC5tYXRjaGVzKCBleHByLCBqUXVlcnkuZ3JlcCggZWxlbXMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBlbGVtLm5vZGVUeXBlID09PSAxO1xuXHR9ICkgKTtcbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0ZmluZDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBpLCByZXQsXG5cdFx0XHRsZW4gPSB0aGlzLmxlbmd0aCxcblx0XHRcdHNlbGYgPSB0aGlzO1xuXG5cdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeSggc2VsZWN0b3IgKS5maWx0ZXIoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRcdGlmICggalF1ZXJ5LmNvbnRhaW5zKCBzZWxmWyBpIF0sIHRoaXMgKSApIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSApICk7XG5cdFx0fVxuXG5cdFx0cmV0ID0gdGhpcy5wdXNoU3RhY2soIFtdICk7XG5cblx0XHRmb3IgKCBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0alF1ZXJ5LmZpbmQoIHNlbGVjdG9yLCBzZWxmWyBpIF0sIHJldCApO1xuXHRcdH1cblxuXHRcdHJldHVybiBsZW4gPiAxID8galF1ZXJ5LnVuaXF1ZVNvcnQoIHJldCApIDogcmV0O1xuXHR9LFxuXHRmaWx0ZXI6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHdpbm5vdyggdGhpcywgc2VsZWN0b3IgfHwgW10sIGZhbHNlICkgKTtcblx0fSxcblx0bm90OiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCB3aW5ub3coIHRoaXMsIHNlbGVjdG9yIHx8IFtdLCB0cnVlICkgKTtcblx0fSxcblx0aXM6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gISF3aW5ub3coXG5cdFx0XHR0aGlzLFxuXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGEgcG9zaXRpb25hbC9yZWxhdGl2ZSBzZWxlY3RvciwgY2hlY2sgbWVtYmVyc2hpcCBpbiB0aGUgcmV0dXJuZWQgc2V0XG5cdFx0XHQvLyBzbyAkKFwicDpmaXJzdFwiKS5pcyhcInA6bGFzdFwiKSB3b24ndCByZXR1cm4gdHJ1ZSBmb3IgYSBkb2Mgd2l0aCB0d28gXCJwXCIuXG5cdFx0XHR0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgJiYgcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvciApID9cblx0XHRcdFx0alF1ZXJ5KCBzZWxlY3RvciApIDpcblx0XHRcdFx0c2VsZWN0b3IgfHwgW10sXG5cdFx0XHRmYWxzZVxuXHRcdCkubGVuZ3RoO1xuXHR9XG59ICk7XG5cblxuLy8gSW5pdGlhbGl6ZSBhIGpRdWVyeSBvYmplY3RcblxuXG4vLyBBIGNlbnRyYWwgcmVmZXJlbmNlIHRvIHRoZSByb290IGpRdWVyeShkb2N1bWVudClcbnZhciByb290alF1ZXJ5LFxuXG5cdC8vIEEgc2ltcGxlIHdheSB0byBjaGVjayBmb3IgSFRNTCBzdHJpbmdzXG5cdC8vIFByaW9yaXRpemUgI2lkIG92ZXIgPHRhZz4gdG8gYXZvaWQgWFNTIHZpYSBsb2NhdGlvbi5oYXNoICgjOTUyMSlcblx0Ly8gU3RyaWN0IEhUTUwgcmVjb2duaXRpb24gKCMxMTI5MDogbXVzdCBzdGFydCB3aXRoIDwpXG5cdC8vIFNob3J0Y3V0IHNpbXBsZSAjaWQgY2FzZSBmb3Igc3BlZWRcblx0cnF1aWNrRXhwciA9IC9eKD86XFxzKig8W1xcd1xcV10rPilbXj5dKnwjKFtcXHctXSspKSQvLFxuXG5cdGluaXQgPSBqUXVlcnkuZm4uaW5pdCA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCwgcm9vdCApIHtcblx0XHR2YXIgbWF0Y2gsIGVsZW07XG5cblx0XHQvLyBIQU5ETEU6ICQoXCJcIiksICQobnVsbCksICQodW5kZWZpbmVkKSwgJChmYWxzZSlcblx0XHRpZiAoICFzZWxlY3RvciApIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdC8vIE1ldGhvZCBpbml0KCkgYWNjZXB0cyBhbiBhbHRlcm5hdGUgcm9vdGpRdWVyeVxuXHRcdC8vIHNvIG1pZ3JhdGUgY2FuIHN1cHBvcnQgalF1ZXJ5LnN1YiAoZ2gtMjEwMSlcblx0XHRyb290ID0gcm9vdCB8fCByb290alF1ZXJ5O1xuXG5cdFx0Ly8gSGFuZGxlIEhUTUwgc3RyaW5nc1xuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0aWYgKCBzZWxlY3RvclsgMCBdID09PSBcIjxcIiAmJlxuXHRcdFx0XHRzZWxlY3Rvclsgc2VsZWN0b3IubGVuZ3RoIC0gMSBdID09PSBcIj5cIiAmJlxuXHRcdFx0XHRzZWxlY3Rvci5sZW5ndGggPj0gMyApIHtcblxuXHRcdFx0XHQvLyBBc3N1bWUgdGhhdCBzdHJpbmdzIHRoYXQgc3RhcnQgYW5kIGVuZCB3aXRoIDw+IGFyZSBIVE1MIGFuZCBza2lwIHRoZSByZWdleCBjaGVja1xuXHRcdFx0XHRtYXRjaCA9IFsgbnVsbCwgc2VsZWN0b3IsIG51bGwgXTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1hdGNoIGh0bWwgb3IgbWFrZSBzdXJlIG5vIGNvbnRleHQgaXMgc3BlY2lmaWVkIGZvciAjaWRcblx0XHRcdGlmICggbWF0Y2ggJiYgKCBtYXRjaFsgMSBdIHx8ICFjb250ZXh0ICkgKSB7XG5cblx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwpIC0+ICQoYXJyYXkpXG5cdFx0XHRcdGlmICggbWF0Y2hbIDEgXSApIHtcblx0XHRcdFx0XHRjb250ZXh0ID0gY29udGV4dCBpbnN0YW5jZW9mIGpRdWVyeSA/IGNvbnRleHRbIDAgXSA6IGNvbnRleHQ7XG5cblx0XHRcdFx0XHQvLyBPcHRpb24gdG8gcnVuIHNjcmlwdHMgaXMgdHJ1ZSBmb3IgYmFjay1jb21wYXRcblx0XHRcdFx0XHQvLyBJbnRlbnRpb25hbGx5IGxldCB0aGUgZXJyb3IgYmUgdGhyb3duIGlmIHBhcnNlSFRNTCBpcyBub3QgcHJlc2VudFxuXHRcdFx0XHRcdGpRdWVyeS5tZXJnZSggdGhpcywgalF1ZXJ5LnBhcnNlSFRNTChcblx0XHRcdFx0XHRcdG1hdGNoWyAxIF0sXG5cdFx0XHRcdFx0XHRjb250ZXh0ICYmIGNvbnRleHQubm9kZVR5cGUgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IGRvY3VtZW50LFxuXHRcdFx0XHRcdFx0dHJ1ZVxuXHRcdFx0XHRcdCkgKTtcblxuXHRcdFx0XHRcdC8vIEhBTkRMRTogJChodG1sLCBwcm9wcylcblx0XHRcdFx0XHRpZiAoIHJzaW5nbGVUYWcudGVzdCggbWF0Y2hbIDEgXSApICYmIGpRdWVyeS5pc1BsYWluT2JqZWN0KCBjb250ZXh0ICkgKSB7XG5cdFx0XHRcdFx0XHRmb3IgKCBtYXRjaCBpbiBjb250ZXh0ICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFByb3BlcnRpZXMgb2YgY29udGV4dCBhcmUgY2FsbGVkIGFzIG1ldGhvZHMgaWYgcG9zc2libGVcblx0XHRcdFx0XHRcdFx0aWYgKCBpc0Z1bmN0aW9uKCB0aGlzWyBtYXRjaCBdICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpc1sgbWF0Y2ggXSggY29udGV4dFsgbWF0Y2ggXSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIC4uLmFuZCBvdGhlcndpc2Ugc2V0IGFzIGF0dHJpYnV0ZXNcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmF0dHIoIG1hdGNoLCBjb250ZXh0WyBtYXRjaCBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdFx0XHQvLyBIQU5ETEU6ICQoI2lkKVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGVsZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCggbWF0Y2hbIDIgXSApO1xuXG5cdFx0XHRcdFx0aWYgKCBlbGVtICkge1xuXG5cdFx0XHRcdFx0XHQvLyBJbmplY3QgdGhlIGVsZW1lbnQgZGlyZWN0bHkgaW50byB0aGUgalF1ZXJ5IG9iamVjdFxuXHRcdFx0XHRcdFx0dGhpc1sgMCBdID0gZWxlbTtcblx0XHRcdFx0XHRcdHRoaXMubGVuZ3RoID0gMTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gSEFORExFOiAkKGV4cHIsICQoLi4uKSlcblx0XHRcdH0gZWxzZSBpZiAoICFjb250ZXh0IHx8IGNvbnRleHQuanF1ZXJ5ICkge1xuXHRcdFx0XHRyZXR1cm4gKCBjb250ZXh0IHx8IHJvb3QgKS5maW5kKCBzZWxlY3RvciApO1xuXG5cdFx0XHQvLyBIQU5ETEU6ICQoZXhwciwgY29udGV4dClcblx0XHRcdC8vICh3aGljaCBpcyBqdXN0IGVxdWl2YWxlbnQgdG86ICQoY29udGV4dCkuZmluZChleHByKVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIHRoaXMuY29uc3RydWN0b3IoIGNvbnRleHQgKS5maW5kKCBzZWxlY3RvciApO1xuXHRcdFx0fVxuXG5cdFx0Ly8gSEFORExFOiAkKERPTUVsZW1lbnQpXG5cdFx0fSBlbHNlIGlmICggc2VsZWN0b3Iubm9kZVR5cGUgKSB7XG5cdFx0XHR0aGlzWyAwIF0gPSBzZWxlY3Rvcjtcblx0XHRcdHRoaXMubGVuZ3RoID0gMTtcblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0Ly8gSEFORExFOiAkKGZ1bmN0aW9uKVxuXHRcdC8vIFNob3J0Y3V0IGZvciBkb2N1bWVudCByZWFkeVxuXHRcdH0gZWxzZSBpZiAoIGlzRnVuY3Rpb24oIHNlbGVjdG9yICkgKSB7XG5cdFx0XHRyZXR1cm4gcm9vdC5yZWFkeSAhPT0gdW5kZWZpbmVkID9cblx0XHRcdFx0cm9vdC5yZWFkeSggc2VsZWN0b3IgKSA6XG5cblx0XHRcdFx0Ly8gRXhlY3V0ZSBpbW1lZGlhdGVseSBpZiByZWFkeSBpcyBub3QgcHJlc2VudFxuXHRcdFx0XHRzZWxlY3RvciggalF1ZXJ5ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpRdWVyeS5tYWtlQXJyYXkoIHNlbGVjdG9yLCB0aGlzICk7XG5cdH07XG5cbi8vIEdpdmUgdGhlIGluaXQgZnVuY3Rpb24gdGhlIGpRdWVyeSBwcm90b3R5cGUgZm9yIGxhdGVyIGluc3RhbnRpYXRpb25cbmluaXQucHJvdG90eXBlID0galF1ZXJ5LmZuO1xuXG4vLyBJbml0aWFsaXplIGNlbnRyYWwgcmVmZXJlbmNlXG5yb290alF1ZXJ5ID0galF1ZXJ5KCBkb2N1bWVudCApO1xuXG5cbnZhciBycGFyZW50c3ByZXYgPSAvXig/OnBhcmVudHN8cHJldig/OlVudGlsfEFsbCkpLyxcblxuXHQvLyBNZXRob2RzIGd1YXJhbnRlZWQgdG8gcHJvZHVjZSBhIHVuaXF1ZSBzZXQgd2hlbiBzdGFydGluZyBmcm9tIGEgdW5pcXVlIHNldFxuXHRndWFyYW50ZWVkVW5pcXVlID0ge1xuXHRcdGNoaWxkcmVuOiB0cnVlLFxuXHRcdGNvbnRlbnRzOiB0cnVlLFxuXHRcdG5leHQ6IHRydWUsXG5cdFx0cHJldjogdHJ1ZVxuXHR9O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGhhczogZnVuY3Rpb24oIHRhcmdldCApIHtcblx0XHR2YXIgdGFyZ2V0cyA9IGpRdWVyeSggdGFyZ2V0LCB0aGlzICksXG5cdFx0XHRsID0gdGFyZ2V0cy5sZW5ndGg7XG5cblx0XHRyZXR1cm4gdGhpcy5maWx0ZXIoIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGkgPSAwO1xuXHRcdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRpZiAoIGpRdWVyeS5jb250YWlucyggdGhpcywgdGFyZ2V0c1sgaSBdICkgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0Y2xvc2VzdDogZnVuY3Rpb24oIHNlbGVjdG9ycywgY29udGV4dCApIHtcblx0XHR2YXIgY3VyLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRtYXRjaGVkID0gW10sXG5cdFx0XHR0YXJnZXRzID0gdHlwZW9mIHNlbGVjdG9ycyAhPT0gXCJzdHJpbmdcIiAmJiBqUXVlcnkoIHNlbGVjdG9ycyApO1xuXG5cdFx0Ly8gUG9zaXRpb25hbCBzZWxlY3RvcnMgbmV2ZXIgbWF0Y2gsIHNpbmNlIHRoZXJlJ3Mgbm8gX3NlbGVjdGlvbl8gY29udGV4dFxuXHRcdGlmICggIXJuZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3JzICkgKSB7XG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdGZvciAoIGN1ciA9IHRoaXNbIGkgXTsgY3VyICYmIGN1ciAhPT0gY29udGV4dDsgY3VyID0gY3VyLnBhcmVudE5vZGUgKSB7XG5cblx0XHRcdFx0XHQvLyBBbHdheXMgc2tpcCBkb2N1bWVudCBmcmFnbWVudHNcblx0XHRcdFx0XHRpZiAoIGN1ci5ub2RlVHlwZSA8IDExICYmICggdGFyZ2V0cyA/XG5cdFx0XHRcdFx0XHR0YXJnZXRzLmluZGV4KCBjdXIgKSA+IC0xIDpcblxuXHRcdFx0XHRcdFx0Ly8gRG9uJ3QgcGFzcyBub24tZWxlbWVudHMgdG8gU2l6emxlXG5cdFx0XHRcdFx0XHRjdXIubm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdFx0XHRcdFx0alF1ZXJ5LmZpbmQubWF0Y2hlc1NlbGVjdG9yKCBjdXIsIHNlbGVjdG9ycyApICkgKSB7XG5cblx0XHRcdFx0XHRcdG1hdGNoZWQucHVzaCggY3VyICk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIG1hdGNoZWQubGVuZ3RoID4gMSA/IGpRdWVyeS51bmlxdWVTb3J0KCBtYXRjaGVkICkgOiBtYXRjaGVkICk7XG5cdH0sXG5cblx0Ly8gRGV0ZXJtaW5lIHRoZSBwb3NpdGlvbiBvZiBhbiBlbGVtZW50IHdpdGhpbiB0aGUgc2V0XG5cdGluZGV4OiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdC8vIE5vIGFyZ3VtZW50LCByZXR1cm4gaW5kZXggaW4gcGFyZW50XG5cdFx0aWYgKCAhZWxlbSApIHtcblx0XHRcdHJldHVybiAoIHRoaXNbIDAgXSAmJiB0aGlzWyAwIF0ucGFyZW50Tm9kZSApID8gdGhpcy5maXJzdCgpLnByZXZBbGwoKS5sZW5ndGggOiAtMTtcblx0XHR9XG5cblx0XHQvLyBJbmRleCBpbiBzZWxlY3RvclxuXHRcdGlmICggdHlwZW9mIGVsZW0gPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdGhpc1sgMCBdICk7XG5cdFx0fVxuXG5cdFx0Ly8gTG9jYXRlIHRoZSBwb3NpdGlvbiBvZiB0aGUgZGVzaXJlZCBlbGVtZW50XG5cdFx0cmV0dXJuIGluZGV4T2YuY2FsbCggdGhpcyxcblxuXHRcdFx0Ly8gSWYgaXQgcmVjZWl2ZXMgYSBqUXVlcnkgb2JqZWN0LCB0aGUgZmlyc3QgZWxlbWVudCBpcyB1c2VkXG5cdFx0XHRlbGVtLmpxdWVyeSA/IGVsZW1bIDAgXSA6IGVsZW1cblx0XHQpO1xuXHR9LFxuXG5cdGFkZDogZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0ICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayhcblx0XHRcdGpRdWVyeS51bmlxdWVTb3J0KFxuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIHRoaXMuZ2V0KCksIGpRdWVyeSggc2VsZWN0b3IsIGNvbnRleHQgKSApXG5cdFx0XHQpXG5cdFx0KTtcblx0fSxcblxuXHRhZGRCYWNrOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHRoaXMuYWRkKCBzZWxlY3RvciA9PSBudWxsID9cblx0XHRcdHRoaXMucHJldk9iamVjdCA6IHRoaXMucHJldk9iamVjdC5maWx0ZXIoIHNlbGVjdG9yIClcblx0XHQpO1xuXHR9XG59ICk7XG5cbmZ1bmN0aW9uIHNpYmxpbmcoIGN1ciwgZGlyICkge1xuXHR3aGlsZSAoICggY3VyID0gY3VyWyBkaXIgXSApICYmIGN1ci5ub2RlVHlwZSAhPT0gMSApIHt9XG5cdHJldHVybiBjdXI7XG59XG5cbmpRdWVyeS5lYWNoKCB7XG5cdHBhcmVudDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcblx0XHRyZXR1cm4gcGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSAhPT0gMTEgPyBwYXJlbnQgOiBudWxsO1xuXHR9LFxuXHRwYXJlbnRzOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcInBhcmVudE5vZGVcIiApO1xuXHR9LFxuXHRwYXJlbnRzVW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBfaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwYXJlbnROb2RlXCIsIHVudGlsICk7XG5cdH0sXG5cdG5leHQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBzaWJsaW5nKCBlbGVtLCBcIm5leHRTaWJsaW5nXCIgKTtcblx0fSxcblx0cHJldjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIHNpYmxpbmcoIGVsZW0sIFwicHJldmlvdXNTaWJsaW5nXCIgKTtcblx0fSxcblx0bmV4dEFsbDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJuZXh0U2libGluZ1wiICk7XG5cdH0sXG5cdHByZXZBbGw6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicHJldmlvdXNTaWJsaW5nXCIgKTtcblx0fSxcblx0bmV4dFVudGlsOiBmdW5jdGlvbiggZWxlbSwgX2ksIHVudGlsICkge1xuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiwgdW50aWwgKTtcblx0fSxcblx0cHJldlVudGlsOiBmdW5jdGlvbiggZWxlbSwgX2ksIHVudGlsICkge1xuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicHJldmlvdXNTaWJsaW5nXCIsIHVudGlsICk7XG5cdH0sXG5cdHNpYmxpbmdzOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZ3MoICggZWxlbS5wYXJlbnROb2RlIHx8IHt9ICkuZmlyc3RDaGlsZCwgZWxlbSApO1xuXHR9LFxuXHRjaGlsZHJlbjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIHNpYmxpbmdzKCBlbGVtLmZpcnN0Q2hpbGQgKTtcblx0fSxcblx0Y29udGVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdGlmICggZWxlbS5jb250ZW50RG9jdW1lbnQgIT0gbnVsbCAmJlxuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMStcblx0XHRcdC8vIDxvYmplY3Q+IGVsZW1lbnRzIHdpdGggbm8gYGRhdGFgIGF0dHJpYnV0ZSBoYXMgYW4gb2JqZWN0XG5cdFx0XHQvLyBgY29udGVudERvY3VtZW50YCB3aXRoIGEgYG51bGxgIHByb3RvdHlwZS5cblx0XHRcdGdldFByb3RvKCBlbGVtLmNvbnRlbnREb2N1bWVudCApICkge1xuXG5cdFx0XHRyZXR1cm4gZWxlbS5jb250ZW50RG9jdW1lbnQ7XG5cdFx0fVxuXG5cdFx0Ly8gU3VwcG9ydDogSUUgOSAtIDExIG9ubHksIGlPUyA3IG9ubHksIEFuZHJvaWQgQnJvd3NlciA8PTQuMyBvbmx5XG5cdFx0Ly8gVHJlYXQgdGhlIHRlbXBsYXRlIGVsZW1lbnQgYXMgYSByZWd1bGFyIG9uZSBpbiBicm93c2VycyB0aGF0XG5cdFx0Ly8gZG9uJ3Qgc3VwcG9ydCBpdC5cblx0XHRpZiAoIG5vZGVOYW1lKCBlbGVtLCBcInRlbXBsYXRlXCIgKSApIHtcblx0XHRcdGVsZW0gPSBlbGVtLmNvbnRlbnQgfHwgZWxlbTtcblx0XHR9XG5cblx0XHRyZXR1cm4galF1ZXJ5Lm1lcmdlKCBbXSwgZWxlbS5jaGlsZE5vZGVzICk7XG5cdH1cbn0sIGZ1bmN0aW9uKCBuYW1lLCBmbiApIHtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggdW50aWwsIHNlbGVjdG9yICkge1xuXHRcdHZhciBtYXRjaGVkID0galF1ZXJ5Lm1hcCggdGhpcywgZm4sIHVudGlsICk7XG5cblx0XHRpZiAoIG5hbWUuc2xpY2UoIC01ICkgIT09IFwiVW50aWxcIiApIHtcblx0XHRcdHNlbGVjdG9yID0gdW50aWw7XG5cdFx0fVxuXG5cdFx0aWYgKCBzZWxlY3RvciAmJiB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRtYXRjaGVkID0galF1ZXJ5LmZpbHRlciggc2VsZWN0b3IsIG1hdGNoZWQgKTtcblx0XHR9XG5cblx0XHRpZiAoIHRoaXMubGVuZ3RoID4gMSApIHtcblxuXHRcdFx0Ly8gUmVtb3ZlIGR1cGxpY2F0ZXNcblx0XHRcdGlmICggIWd1YXJhbnRlZWRVbmlxdWVbIG5hbWUgXSApIHtcblx0XHRcdFx0alF1ZXJ5LnVuaXF1ZVNvcnQoIG1hdGNoZWQgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUmV2ZXJzZSBvcmRlciBmb3IgcGFyZW50cyogYW5kIHByZXYtZGVyaXZhdGl2ZXNcblx0XHRcdGlmICggcnBhcmVudHNwcmV2LnRlc3QoIG5hbWUgKSApIHtcblx0XHRcdFx0bWF0Y2hlZC5yZXZlcnNlKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBtYXRjaGVkICk7XG5cdH07XG59ICk7XG52YXIgcm5vdGh0bWx3aGl0ZSA9ICggL1teXFx4MjBcXHRcXHJcXG5cXGZdKy9nICk7XG5cblxuXG4vLyBDb252ZXJ0IFN0cmluZy1mb3JtYXR0ZWQgb3B0aW9ucyBpbnRvIE9iamVjdC1mb3JtYXR0ZWQgb25lc1xuZnVuY3Rpb24gY3JlYXRlT3B0aW9ucyggb3B0aW9ucyApIHtcblx0dmFyIG9iamVjdCA9IHt9O1xuXHRqUXVlcnkuZWFjaCggb3B0aW9ucy5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdLCBmdW5jdGlvbiggXywgZmxhZyApIHtcblx0XHRvYmplY3RbIGZsYWcgXSA9IHRydWU7XG5cdH0gKTtcblx0cmV0dXJuIG9iamVjdDtcbn1cblxuLypcbiAqIENyZWF0ZSBhIGNhbGxiYWNrIGxpc3QgdXNpbmcgdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzOlxuICpcbiAqXHRvcHRpb25zOiBhbiBvcHRpb25hbCBsaXN0IG9mIHNwYWNlLXNlcGFyYXRlZCBvcHRpb25zIHRoYXQgd2lsbCBjaGFuZ2UgaG93XG4gKlx0XHRcdHRoZSBjYWxsYmFjayBsaXN0IGJlaGF2ZXMgb3IgYSBtb3JlIHRyYWRpdGlvbmFsIG9wdGlvbiBvYmplY3RcbiAqXG4gKiBCeSBkZWZhdWx0IGEgY2FsbGJhY2sgbGlzdCB3aWxsIGFjdCBsaWtlIGFuIGV2ZW50IGNhbGxiYWNrIGxpc3QgYW5kIGNhbiBiZVxuICogXCJmaXJlZFwiIG11bHRpcGxlIHRpbWVzLlxuICpcbiAqIFBvc3NpYmxlIG9wdGlvbnM6XG4gKlxuICpcdG9uY2U6XHRcdFx0d2lsbCBlbnN1cmUgdGhlIGNhbGxiYWNrIGxpc3QgY2FuIG9ubHkgYmUgZmlyZWQgb25jZSAobGlrZSBhIERlZmVycmVkKVxuICpcbiAqXHRtZW1vcnk6XHRcdFx0d2lsbCBrZWVwIHRyYWNrIG9mIHByZXZpb3VzIHZhbHVlcyBhbmQgd2lsbCBjYWxsIGFueSBjYWxsYmFjayBhZGRlZFxuICpcdFx0XHRcdFx0YWZ0ZXIgdGhlIGxpc3QgaGFzIGJlZW4gZmlyZWQgcmlnaHQgYXdheSB3aXRoIHRoZSBsYXRlc3QgXCJtZW1vcml6ZWRcIlxuICpcdFx0XHRcdFx0dmFsdWVzIChsaWtlIGEgRGVmZXJyZWQpXG4gKlxuICpcdHVuaXF1ZTpcdFx0XHR3aWxsIGVuc3VyZSBhIGNhbGxiYWNrIGNhbiBvbmx5IGJlIGFkZGVkIG9uY2UgKG5vIGR1cGxpY2F0ZSBpbiB0aGUgbGlzdClcbiAqXG4gKlx0c3RvcE9uRmFsc2U6XHRpbnRlcnJ1cHQgY2FsbGluZ3Mgd2hlbiBhIGNhbGxiYWNrIHJldHVybnMgZmFsc2VcbiAqXG4gKi9cbmpRdWVyeS5DYWxsYmFja3MgPSBmdW5jdGlvbiggb3B0aW9ucyApIHtcblxuXHQvLyBDb252ZXJ0IG9wdGlvbnMgZnJvbSBTdHJpbmctZm9ybWF0dGVkIHRvIE9iamVjdC1mb3JtYXR0ZWQgaWYgbmVlZGVkXG5cdC8vICh3ZSBjaGVjayBpbiBjYWNoZSBmaXJzdClcblx0b3B0aW9ucyA9IHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiID9cblx0XHRjcmVhdGVPcHRpb25zKCBvcHRpb25zICkgOlxuXHRcdGpRdWVyeS5leHRlbmQoIHt9LCBvcHRpb25zICk7XG5cblx0dmFyIC8vIEZsYWcgdG8ga25vdyBpZiBsaXN0IGlzIGN1cnJlbnRseSBmaXJpbmdcblx0XHRmaXJpbmcsXG5cblx0XHQvLyBMYXN0IGZpcmUgdmFsdWUgZm9yIG5vbi1mb3JnZXR0YWJsZSBsaXN0c1xuXHRcdG1lbW9yeSxcblxuXHRcdC8vIEZsYWcgdG8ga25vdyBpZiBsaXN0IHdhcyBhbHJlYWR5IGZpcmVkXG5cdFx0ZmlyZWQsXG5cblx0XHQvLyBGbGFnIHRvIHByZXZlbnQgZmlyaW5nXG5cdFx0bG9ja2VkLFxuXG5cdFx0Ly8gQWN0dWFsIGNhbGxiYWNrIGxpc3Rcblx0XHRsaXN0ID0gW10sXG5cblx0XHQvLyBRdWV1ZSBvZiBleGVjdXRpb24gZGF0YSBmb3IgcmVwZWF0YWJsZSBsaXN0c1xuXHRcdHF1ZXVlID0gW10sXG5cblx0XHQvLyBJbmRleCBvZiBjdXJyZW50bHkgZmlyaW5nIGNhbGxiYWNrIChtb2RpZmllZCBieSBhZGQvcmVtb3ZlIGFzIG5lZWRlZClcblx0XHRmaXJpbmdJbmRleCA9IC0xLFxuXG5cdFx0Ly8gRmlyZSBjYWxsYmFja3Ncblx0XHRmaXJlID0gZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIEVuZm9yY2Ugc2luZ2xlLWZpcmluZ1xuXHRcdFx0bG9ja2VkID0gbG9ja2VkIHx8IG9wdGlvbnMub25jZTtcblxuXHRcdFx0Ly8gRXhlY3V0ZSBjYWxsYmFja3MgZm9yIGFsbCBwZW5kaW5nIGV4ZWN1dGlvbnMsXG5cdFx0XHQvLyByZXNwZWN0aW5nIGZpcmluZ0luZGV4IG92ZXJyaWRlcyBhbmQgcnVudGltZSBjaGFuZ2VzXG5cdFx0XHRmaXJlZCA9IGZpcmluZyA9IHRydWU7XG5cdFx0XHRmb3IgKCA7IHF1ZXVlLmxlbmd0aDsgZmlyaW5nSW5kZXggPSAtMSApIHtcblx0XHRcdFx0bWVtb3J5ID0gcXVldWUuc2hpZnQoKTtcblx0XHRcdFx0d2hpbGUgKCArK2ZpcmluZ0luZGV4IDwgbGlzdC5sZW5ndGggKSB7XG5cblx0XHRcdFx0XHQvLyBSdW4gY2FsbGJhY2sgYW5kIGNoZWNrIGZvciBlYXJseSB0ZXJtaW5hdGlvblxuXHRcdFx0XHRcdGlmICggbGlzdFsgZmlyaW5nSW5kZXggXS5hcHBseSggbWVtb3J5WyAwIF0sIG1lbW9yeVsgMSBdICkgPT09IGZhbHNlICYmXG5cdFx0XHRcdFx0XHRvcHRpb25zLnN0b3BPbkZhbHNlICkge1xuXG5cdFx0XHRcdFx0XHQvLyBKdW1wIHRvIGVuZCBhbmQgZm9yZ2V0IHRoZSBkYXRhIHNvIC5hZGQgZG9lc24ndCByZS1maXJlXG5cdFx0XHRcdFx0XHRmaXJpbmdJbmRleCA9IGxpc3QubGVuZ3RoO1xuXHRcdFx0XHRcdFx0bWVtb3J5ID0gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZvcmdldCB0aGUgZGF0YSBpZiB3ZSdyZSBkb25lIHdpdGggaXRcblx0XHRcdGlmICggIW9wdGlvbnMubWVtb3J5ICkge1xuXHRcdFx0XHRtZW1vcnkgPSBmYWxzZTtcblx0XHRcdH1cblxuXHRcdFx0ZmlyaW5nID0gZmFsc2U7XG5cblx0XHRcdC8vIENsZWFuIHVwIGlmIHdlJ3JlIGRvbmUgZmlyaW5nIGZvciBnb29kXG5cdFx0XHRpZiAoIGxvY2tlZCApIHtcblxuXHRcdFx0XHQvLyBLZWVwIGFuIGVtcHR5IGxpc3QgaWYgd2UgaGF2ZSBkYXRhIGZvciBmdXR1cmUgYWRkIGNhbGxzXG5cdFx0XHRcdGlmICggbWVtb3J5ICkge1xuXHRcdFx0XHRcdGxpc3QgPSBbXTtcblxuXHRcdFx0XHQvLyBPdGhlcndpc2UsIHRoaXMgb2JqZWN0IGlzIHNwZW50XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bGlzdCA9IFwiXCI7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0Ly8gQWN0dWFsIENhbGxiYWNrcyBvYmplY3Rcblx0XHRzZWxmID0ge1xuXG5cdFx0XHQvLyBBZGQgYSBjYWxsYmFjayBvciBhIGNvbGxlY3Rpb24gb2YgY2FsbGJhY2tzIHRvIHRoZSBsaXN0XG5cdFx0XHRhZGQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGxpc3QgKSB7XG5cblx0XHRcdFx0XHQvLyBJZiB3ZSBoYXZlIG1lbW9yeSBmcm9tIGEgcGFzdCBydW4sIHdlIHNob3VsZCBmaXJlIGFmdGVyIGFkZGluZ1xuXHRcdFx0XHRcdGlmICggbWVtb3J5ICYmICFmaXJpbmcgKSB7XG5cdFx0XHRcdFx0XHRmaXJpbmdJbmRleCA9IGxpc3QubGVuZ3RoIC0gMTtcblx0XHRcdFx0XHRcdHF1ZXVlLnB1c2goIG1lbW9yeSApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdCggZnVuY3Rpb24gYWRkKCBhcmdzICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5LmVhY2goIGFyZ3MsIGZ1bmN0aW9uKCBfLCBhcmcgKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggaXNGdW5jdGlvbiggYXJnICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCAhb3B0aW9ucy51bmlxdWUgfHwgIXNlbGYuaGFzKCBhcmcgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGxpc3QucHVzaCggYXJnICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBhcmcgJiYgYXJnLmxlbmd0aCAmJiB0b1R5cGUoIGFyZyApICE9PSBcInN0cmluZ1wiICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gSW5zcGVjdCByZWN1cnNpdmVseVxuXHRcdFx0XHRcdFx0XHRcdGFkZCggYXJnICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHR9ICkoIGFyZ3VtZW50cyApO1xuXG5cdFx0XHRcdFx0aWYgKCBtZW1vcnkgJiYgIWZpcmluZyApIHtcblx0XHRcdFx0XHRcdGZpcmUoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBSZW1vdmUgYSBjYWxsYmFjayBmcm9tIHRoZSBsaXN0XG5cdFx0XHRyZW1vdmU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRqUXVlcnkuZWFjaCggYXJndW1lbnRzLCBmdW5jdGlvbiggXywgYXJnICkge1xuXHRcdFx0XHRcdHZhciBpbmRleDtcblx0XHRcdFx0XHR3aGlsZSAoICggaW5kZXggPSBqUXVlcnkuaW5BcnJheSggYXJnLCBsaXN0LCBpbmRleCApICkgPiAtMSApIHtcblx0XHRcdFx0XHRcdGxpc3Quc3BsaWNlKCBpbmRleCwgMSApO1xuXG5cdFx0XHRcdFx0XHQvLyBIYW5kbGUgZmlyaW5nIGluZGV4ZXNcblx0XHRcdFx0XHRcdGlmICggaW5kZXggPD0gZmlyaW5nSW5kZXggKSB7XG5cdFx0XHRcdFx0XHRcdGZpcmluZ0luZGV4LS07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICk7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gQ2hlY2sgaWYgYSBnaXZlbiBjYWxsYmFjayBpcyBpbiB0aGUgbGlzdC5cblx0XHRcdC8vIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCByZXR1cm4gd2hldGhlciBvciBub3QgbGlzdCBoYXMgY2FsbGJhY2tzIGF0dGFjaGVkLlxuXHRcdFx0aGFzOiBmdW5jdGlvbiggZm4gKSB7XG5cdFx0XHRcdHJldHVybiBmbiA/XG5cdFx0XHRcdFx0alF1ZXJ5LmluQXJyYXkoIGZuLCBsaXN0ICkgPiAtMSA6XG5cdFx0XHRcdFx0bGlzdC5sZW5ndGggPiAwO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gUmVtb3ZlIGFsbCBjYWxsYmFja3MgZnJvbSB0aGUgbGlzdFxuXHRcdFx0ZW1wdHk6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGxpc3QgKSB7XG5cdFx0XHRcdFx0bGlzdCA9IFtdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gRGlzYWJsZSAuZmlyZSBhbmQgLmFkZFxuXHRcdFx0Ly8gQWJvcnQgYW55IGN1cnJlbnQvcGVuZGluZyBleGVjdXRpb25zXG5cdFx0XHQvLyBDbGVhciBhbGwgY2FsbGJhY2tzIGFuZCB2YWx1ZXNcblx0XHRcdGRpc2FibGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRsb2NrZWQgPSBxdWV1ZSA9IFtdO1xuXHRcdFx0XHRsaXN0ID0gbWVtb3J5ID0gXCJcIjtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0ZGlzYWJsZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gIWxpc3Q7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBEaXNhYmxlIC5maXJlXG5cdFx0XHQvLyBBbHNvIGRpc2FibGUgLmFkZCB1bmxlc3Mgd2UgaGF2ZSBtZW1vcnkgKHNpbmNlIGl0IHdvdWxkIGhhdmUgbm8gZWZmZWN0KVxuXHRcdFx0Ly8gQWJvcnQgYW55IHBlbmRpbmcgZXhlY3V0aW9uc1xuXHRcdFx0bG9jazogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGxvY2tlZCA9IHF1ZXVlID0gW107XG5cdFx0XHRcdGlmICggIW1lbW9yeSAmJiAhZmlyaW5nICkge1xuXHRcdFx0XHRcdGxpc3QgPSBtZW1vcnkgPSBcIlwiO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdGxvY2tlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhIWxvY2tlZDtcblx0XHRcdH0sXG5cblx0XHRcdC8vIENhbGwgYWxsIGNhbGxiYWNrcyB3aXRoIHRoZSBnaXZlbiBjb250ZXh0IGFuZCBhcmd1bWVudHNcblx0XHRcdGZpcmVXaXRoOiBmdW5jdGlvbiggY29udGV4dCwgYXJncyApIHtcblx0XHRcdFx0aWYgKCAhbG9ja2VkICkge1xuXHRcdFx0XHRcdGFyZ3MgPSBhcmdzIHx8IFtdO1xuXHRcdFx0XHRcdGFyZ3MgPSBbIGNvbnRleHQsIGFyZ3Muc2xpY2UgPyBhcmdzLnNsaWNlKCkgOiBhcmdzIF07XG5cdFx0XHRcdFx0cXVldWUucHVzaCggYXJncyApO1xuXHRcdFx0XHRcdGlmICggIWZpcmluZyApIHtcblx0XHRcdFx0XHRcdGZpcmUoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBDYWxsIGFsbCB0aGUgY2FsbGJhY2tzIHdpdGggdGhlIGdpdmVuIGFyZ3VtZW50c1xuXHRcdFx0ZmlyZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHNlbGYuZmlyZVdpdGgoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cblx0XHRcdC8vIFRvIGtub3cgaWYgdGhlIGNhbGxiYWNrcyBoYXZlIGFscmVhZHkgYmVlbiBjYWxsZWQgYXQgbGVhc3Qgb25jZVxuXHRcdFx0ZmlyZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gISFmaXJlZDtcblx0XHRcdH1cblx0XHR9O1xuXG5cdHJldHVybiBzZWxmO1xufTtcblxuXG5mdW5jdGlvbiBJZGVudGl0eSggdiApIHtcblx0cmV0dXJuIHY7XG59XG5mdW5jdGlvbiBUaHJvd2VyKCBleCApIHtcblx0dGhyb3cgZXg7XG59XG5cbmZ1bmN0aW9uIGFkb3B0VmFsdWUoIHZhbHVlLCByZXNvbHZlLCByZWplY3QsIG5vVmFsdWUgKSB7XG5cdHZhciBtZXRob2Q7XG5cblx0dHJ5IHtcblxuXHRcdC8vIENoZWNrIGZvciBwcm9taXNlIGFzcGVjdCBmaXJzdCB0byBwcml2aWxlZ2Ugc3luY2hyb25vdXMgYmVoYXZpb3Jcblx0XHRpZiAoIHZhbHVlICYmIGlzRnVuY3Rpb24oICggbWV0aG9kID0gdmFsdWUucHJvbWlzZSApICkgKSB7XG5cdFx0XHRtZXRob2QuY2FsbCggdmFsdWUgKS5kb25lKCByZXNvbHZlICkuZmFpbCggcmVqZWN0ICk7XG5cblx0XHQvLyBPdGhlciB0aGVuYWJsZXNcblx0XHR9IGVsc2UgaWYgKCB2YWx1ZSAmJiBpc0Z1bmN0aW9uKCAoIG1ldGhvZCA9IHZhbHVlLnRoZW4gKSApICkge1xuXHRcdFx0bWV0aG9kLmNhbGwoIHZhbHVlLCByZXNvbHZlLCByZWplY3QgKTtcblxuXHRcdC8vIE90aGVyIG5vbi10aGVuYWJsZXNcblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBDb250cm9sIGByZXNvbHZlYCBhcmd1bWVudHMgYnkgbGV0dGluZyBBcnJheSNzbGljZSBjYXN0IGJvb2xlYW4gYG5vVmFsdWVgIHRvIGludGVnZXI6XG5cdFx0XHQvLyAqIGZhbHNlOiBbIHZhbHVlIF0uc2xpY2UoIDAgKSA9PiByZXNvbHZlKCB2YWx1ZSApXG5cdFx0XHQvLyAqIHRydWU6IFsgdmFsdWUgXS5zbGljZSggMSApID0+IHJlc29sdmUoKVxuXHRcdFx0cmVzb2x2ZS5hcHBseSggdW5kZWZpbmVkLCBbIHZhbHVlIF0uc2xpY2UoIG5vVmFsdWUgKSApO1xuXHRcdH1cblxuXHQvLyBGb3IgUHJvbWlzZXMvQSssIGNvbnZlcnQgZXhjZXB0aW9ucyBpbnRvIHJlamVjdGlvbnNcblx0Ly8gU2luY2UgalF1ZXJ5LndoZW4gZG9lc24ndCB1bndyYXAgdGhlbmFibGVzLCB3ZSBjYW4gc2tpcCB0aGUgZXh0cmEgY2hlY2tzIGFwcGVhcmluZyBpblxuXHQvLyBEZWZlcnJlZCN0aGVuIHRvIGNvbmRpdGlvbmFsbHkgc3VwcHJlc3MgcmVqZWN0aW9uLlxuXHR9IGNhdGNoICggdmFsdWUgKSB7XG5cblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCBvbmx5XG5cdFx0Ly8gU3RyaWN0IG1vZGUgZnVuY3Rpb25zIGludm9rZWQgd2l0aG91dCAuY2FsbC8uYXBwbHkgZ2V0IGdsb2JhbC1vYmplY3QgY29udGV4dFxuXHRcdHJlamVjdC5hcHBseSggdW5kZWZpbmVkLCBbIHZhbHVlIF0gKTtcblx0fVxufVxuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cblx0RGVmZXJyZWQ6IGZ1bmN0aW9uKCBmdW5jICkge1xuXHRcdHZhciB0dXBsZXMgPSBbXG5cblx0XHRcdFx0Ly8gYWN0aW9uLCBhZGQgbGlzdGVuZXIsIGNhbGxiYWNrcyxcblx0XHRcdFx0Ly8gLi4uIC50aGVuIGhhbmRsZXJzLCBhcmd1bWVudCBpbmRleCwgW2ZpbmFsIHN0YXRlXVxuXHRcdFx0XHRbIFwibm90aWZ5XCIsIFwicHJvZ3Jlc3NcIiwgalF1ZXJ5LkNhbGxiYWNrcyggXCJtZW1vcnlcIiApLFxuXHRcdFx0XHRcdGpRdWVyeS5DYWxsYmFja3MoIFwibWVtb3J5XCIgKSwgMiBdLFxuXHRcdFx0XHRbIFwicmVzb2x2ZVwiLCBcImRvbmVcIiwgalF1ZXJ5LkNhbGxiYWNrcyggXCJvbmNlIG1lbW9yeVwiICksXG5cdFx0XHRcdFx0alF1ZXJ5LkNhbGxiYWNrcyggXCJvbmNlIG1lbW9yeVwiICksIDAsIFwicmVzb2x2ZWRcIiBdLFxuXHRcdFx0XHRbIFwicmVqZWN0XCIsIFwiZmFpbFwiLCBqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSxcblx0XHRcdFx0XHRqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSwgMSwgXCJyZWplY3RlZFwiIF1cblx0XHRcdF0sXG5cdFx0XHRzdGF0ZSA9IFwicGVuZGluZ1wiLFxuXHRcdFx0cHJvbWlzZSA9IHtcblx0XHRcdFx0c3RhdGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHJldHVybiBzdGF0ZTtcblx0XHRcdFx0fSxcblx0XHRcdFx0YWx3YXlzOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5kb25lKCBhcmd1bWVudHMgKS5mYWlsKCBhcmd1bWVudHMgKTtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fSxcblx0XHRcdFx0XCJjYXRjaFwiOiBmdW5jdGlvbiggZm4gKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHByb21pc2UudGhlbiggbnVsbCwgZm4gKTtcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBLZWVwIHBpcGUgZm9yIGJhY2stY29tcGF0XG5cdFx0XHRcdHBpcGU6IGZ1bmN0aW9uKCAvKiBmbkRvbmUsIGZuRmFpbCwgZm5Qcm9ncmVzcyAqLyApIHtcblx0XHRcdFx0XHR2YXIgZm5zID0gYXJndW1lbnRzO1xuXG5cdFx0XHRcdFx0cmV0dXJuIGpRdWVyeS5EZWZlcnJlZCggZnVuY3Rpb24oIG5ld0RlZmVyICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5LmVhY2goIHR1cGxlcywgZnVuY3Rpb24oIF9pLCB0dXBsZSApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBNYXAgdHVwbGVzIChwcm9ncmVzcywgZG9uZSwgZmFpbCkgdG8gYXJndW1lbnRzIChkb25lLCBmYWlsLCBwcm9ncmVzcylcblx0XHRcdFx0XHRcdFx0dmFyIGZuID0gaXNGdW5jdGlvbiggZm5zWyB0dXBsZVsgNCBdIF0gKSAmJiBmbnNbIHR1cGxlWyA0IF0gXTtcblxuXHRcdFx0XHRcdFx0XHQvLyBkZWZlcnJlZC5wcm9ncmVzcyhmdW5jdGlvbigpIHsgYmluZCB0byBuZXdEZWZlciBvciBuZXdEZWZlci5ub3RpZnkgfSlcblx0XHRcdFx0XHRcdFx0Ly8gZGVmZXJyZWQuZG9uZShmdW5jdGlvbigpIHsgYmluZCB0byBuZXdEZWZlciBvciBuZXdEZWZlci5yZXNvbHZlIH0pXG5cdFx0XHRcdFx0XHRcdC8vIGRlZmVycmVkLmZhaWwoZnVuY3Rpb24oKSB7IGJpbmQgdG8gbmV3RGVmZXIgb3IgbmV3RGVmZXIucmVqZWN0IH0pXG5cdFx0XHRcdFx0XHRcdGRlZmVycmVkWyB0dXBsZVsgMSBdIF0oIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdHZhciByZXR1cm5lZCA9IGZuICYmIGZuLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIHJldHVybmVkICYmIGlzRnVuY3Rpb24oIHJldHVybmVkLnByb21pc2UgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLnByb21pc2UoKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQucHJvZ3Jlc3MoIG5ld0RlZmVyLm5vdGlmeSApXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5kb25lKCBuZXdEZWZlci5yZXNvbHZlIClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmZhaWwoIG5ld0RlZmVyLnJlamVjdCApO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRuZXdEZWZlclsgdHVwbGVbIDAgXSArIFwiV2l0aFwiIF0oXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRoaXMsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGZuID8gWyByZXR1cm5lZCBdIDogYXJndW1lbnRzXG5cdFx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0Zm5zID0gbnVsbDtcblx0XHRcdFx0XHR9ICkucHJvbWlzZSgpO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR0aGVuOiBmdW5jdGlvbiggb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIG9uUHJvZ3Jlc3MgKSB7XG5cdFx0XHRcdFx0dmFyIG1heERlcHRoID0gMDtcblx0XHRcdFx0XHRmdW5jdGlvbiByZXNvbHZlKCBkZXB0aCwgZGVmZXJyZWQsIGhhbmRsZXIsIHNwZWNpYWwgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdHZhciB0aGF0ID0gdGhpcyxcblx0XHRcdFx0XHRcdFx0XHRhcmdzID0gYXJndW1lbnRzLFxuXHRcdFx0XHRcdFx0XHRcdG1pZ2h0VGhyb3cgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHZhciByZXR1cm5lZCwgdGhlbjtcblxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuMy4zLjNcblx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTU5XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBJZ25vcmUgZG91YmxlLXJlc29sdXRpb24gYXR0ZW1wdHNcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggZGVwdGggPCBtYXhEZXB0aCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm5lZCA9IGhhbmRsZXIuYXBwbHkoIHRoYXQsIGFyZ3MgKTtcblxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuMVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNDhcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggcmV0dXJuZWQgPT09IGRlZmVycmVkLnByb21pc2UoKSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvciggXCJUaGVuYWJsZSBzZWxmLXJlc29sdXRpb25cIiApO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9ucyAyLjMuMy4xLCAzLjVcblx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTU0XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC03NVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gUmV0cmlldmUgYHRoZW5gIG9ubHkgb25jZVxuXHRcdFx0XHRcdFx0XHRcdFx0dGhlbiA9IHJldHVybmVkICYmXG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuNFxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC02NFxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBPbmx5IGNoZWNrIG9iamVjdHMgYW5kIGZ1bmN0aW9ucyBmb3IgdGhlbmFiaWxpdHlcblx0XHRcdFx0XHRcdFx0XHRcdFx0KCB0eXBlb2YgcmV0dXJuZWQgPT09IFwib2JqZWN0XCIgfHxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0eXBlb2YgcmV0dXJuZWQgPT09IFwiZnVuY3Rpb25cIiApICYmXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLnRoZW47XG5cblx0XHRcdFx0XHRcdFx0XHRcdC8vIEhhbmRsZSBhIHJldHVybmVkIHRoZW5hYmxlXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIGlzRnVuY3Rpb24oIHRoZW4gKSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTcGVjaWFsIHByb2Nlc3NvcnMgKG5vdGlmeSkganVzdCB3YWl0IGZvciByZXNvbHV0aW9uXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggc3BlY2lhbCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGVuLmNhbGwoXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm5lZCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgSWRlbnRpdHksIHNwZWNpYWwgKSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgVGhyb3dlciwgc3BlY2lhbCApXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBOb3JtYWwgcHJvY2Vzc29ycyAocmVzb2x2ZSkgYWxzbyBob29rIGludG8gcHJvZ3Jlc3Ncblx0XHRcdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIC4uLmFuZCBkaXNyZWdhcmQgb2xkZXIgcmVzb2x1dGlvbiB2YWx1ZXNcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtYXhEZXB0aCsrO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhlbi5jYWxsKFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXNvbHZlKCBtYXhEZXB0aCwgZGVmZXJyZWQsIElkZW50aXR5LCBzcGVjaWFsICksXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXNvbHZlKCBtYXhEZXB0aCwgZGVmZXJyZWQsIFRocm93ZXIsIHNwZWNpYWwgKSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgSWRlbnRpdHksXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGRlZmVycmVkLm5vdGlmeVdpdGggKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSGFuZGxlIGFsbCBvdGhlciByZXR1cm5lZCB2YWx1ZXNcblx0XHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gT25seSBzdWJzdGl0dXRlIGhhbmRsZXJzIHBhc3Mgb24gY29udGV4dFxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBhbmQgbXVsdGlwbGUgdmFsdWVzIChub24tc3BlYyBiZWhhdmlvcilcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBoYW5kbGVyICE9PSBJZGVudGl0eSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGF0ID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGFyZ3MgPSBbIHJldHVybmVkIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBQcm9jZXNzIHRoZSB2YWx1ZShzKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBEZWZhdWx0IHByb2Nlc3MgaXMgcmVzb2x2ZVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQoIHNwZWNpYWwgfHwgZGVmZXJyZWQucmVzb2x2ZVdpdGggKSggdGhhdCwgYXJncyApO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH0sXG5cblx0XHRcdFx0XHRcdFx0XHQvLyBPbmx5IG5vcm1hbCBwcm9jZXNzb3JzIChyZXNvbHZlKSBjYXRjaCBhbmQgcmVqZWN0IGV4Y2VwdGlvbnNcblx0XHRcdFx0XHRcdFx0XHRwcm9jZXNzID0gc3BlY2lhbCA/XG5cdFx0XHRcdFx0XHRcdFx0XHRtaWdodFRocm93IDpcblx0XHRcdFx0XHRcdFx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1pZ2h0VGhyb3coKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5EZWZlcnJlZC5leGNlcHRpb25Ib29rICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LkRlZmVycmVkLmV4Y2VwdGlvbkhvb2soIGUsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHByb2Nlc3Muc3RhY2tUcmFjZSApO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFByb21pc2VzL0ErIHNlY3Rpb24gMi4zLjMuMy40LjFcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC02MVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIElnbm9yZSBwb3N0LXJlc29sdXRpb24gZXhjZXB0aW9uc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggZGVwdGggKyAxID49IG1heERlcHRoICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBPbmx5IHN1YnN0aXR1dGUgaGFuZGxlcnMgcGFzcyBvbiBjb250ZXh0XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBhbmQgbXVsdGlwbGUgdmFsdWVzIChub24tc3BlYyBiZWhhdmlvcilcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggaGFuZGxlciAhPT0gVGhyb3dlciApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhhdCA9IHVuZGVmaW5lZDtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0YXJncyA9IFsgZSBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCB0aGF0LCBhcmdzICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHR9O1xuXG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFByb21pc2VzL0ErIHNlY3Rpb24gMi4zLjMuMy4xXG5cdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTU3XG5cdFx0XHRcdFx0XHRcdC8vIFJlLXJlc29sdmUgcHJvbWlzZXMgaW1tZWRpYXRlbHkgdG8gZG9kZ2UgZmFsc2UgcmVqZWN0aW9uIGZyb21cblx0XHRcdFx0XHRcdFx0Ly8gc3Vic2VxdWVudCBlcnJvcnNcblx0XHRcdFx0XHRcdFx0aWYgKCBkZXB0aCApIHtcblx0XHRcdFx0XHRcdFx0XHRwcm9jZXNzKCk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBDYWxsIGFuIG9wdGlvbmFsIGhvb2sgdG8gcmVjb3JkIHRoZSBzdGFjaywgaW4gY2FzZSBvZiBleGNlcHRpb25cblx0XHRcdFx0XHRcdFx0XHQvLyBzaW5jZSBpdCdzIG90aGVyd2lzZSBsb3N0IHdoZW4gZXhlY3V0aW9uIGdvZXMgYXN5bmNcblx0XHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5EZWZlcnJlZC5nZXRTdGFja0hvb2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRwcm9jZXNzLnN0YWNrVHJhY2UgPSBqUXVlcnkuRGVmZXJyZWQuZ2V0U3RhY2tIb29rKCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdHdpbmRvdy5zZXRUaW1lb3V0KCBwcm9jZXNzICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIGpRdWVyeS5EZWZlcnJlZCggZnVuY3Rpb24oIG5ld0RlZmVyICkge1xuXG5cdFx0XHRcdFx0XHQvLyBwcm9ncmVzc19oYW5kbGVycy5hZGQoIC4uLiApXG5cdFx0XHRcdFx0XHR0dXBsZXNbIDAgXVsgMyBdLmFkZChcblx0XHRcdFx0XHRcdFx0cmVzb2x2ZShcblx0XHRcdFx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdFx0XHRcdG5ld0RlZmVyLFxuXHRcdFx0XHRcdFx0XHRcdGlzRnVuY3Rpb24oIG9uUHJvZ3Jlc3MgKSA/XG5cdFx0XHRcdFx0XHRcdFx0XHRvblByb2dyZXNzIDpcblx0XHRcdFx0XHRcdFx0XHRcdElkZW50aXR5LFxuXHRcdFx0XHRcdFx0XHRcdG5ld0RlZmVyLm5vdGlmeVdpdGhcblx0XHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdFx0Ly8gZnVsZmlsbGVkX2hhbmRsZXJzLmFkZCggLi4uIClcblx0XHRcdFx0XHRcdHR1cGxlc1sgMSBdWyAzIF0uYWRkKFxuXHRcdFx0XHRcdFx0XHRyZXNvbHZlKFxuXHRcdFx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXIsXG5cdFx0XHRcdFx0XHRcdFx0aXNGdW5jdGlvbiggb25GdWxmaWxsZWQgKSA/XG5cdFx0XHRcdFx0XHRcdFx0XHRvbkZ1bGZpbGxlZCA6XG5cdFx0XHRcdFx0XHRcdFx0XHRJZGVudGl0eVxuXHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHQvLyByZWplY3RlZF9oYW5kbGVycy5hZGQoIC4uLiApXG5cdFx0XHRcdFx0XHR0dXBsZXNbIDIgXVsgMyBdLmFkZChcblx0XHRcdFx0XHRcdFx0cmVzb2x2ZShcblx0XHRcdFx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdFx0XHRcdG5ld0RlZmVyLFxuXHRcdFx0XHRcdFx0XHRcdGlzRnVuY3Rpb24oIG9uUmVqZWN0ZWQgKSA/XG5cdFx0XHRcdFx0XHRcdFx0XHRvblJlamVjdGVkIDpcblx0XHRcdFx0XHRcdFx0XHRcdFRocm93ZXJcblx0XHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9ICkucHJvbWlzZSgpO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIEdldCBhIHByb21pc2UgZm9yIHRoaXMgZGVmZXJyZWRcblx0XHRcdFx0Ly8gSWYgb2JqIGlzIHByb3ZpZGVkLCB0aGUgcHJvbWlzZSBhc3BlY3QgaXMgYWRkZWQgdG8gdGhlIG9iamVjdFxuXHRcdFx0XHRwcm9taXNlOiBmdW5jdGlvbiggb2JqICkge1xuXHRcdFx0XHRcdHJldHVybiBvYmogIT0gbnVsbCA/IGpRdWVyeS5leHRlbmQoIG9iaiwgcHJvbWlzZSApIDogcHJvbWlzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGRlZmVycmVkID0ge307XG5cblx0XHQvLyBBZGQgbGlzdC1zcGVjaWZpYyBtZXRob2RzXG5cdFx0alF1ZXJ5LmVhY2goIHR1cGxlcywgZnVuY3Rpb24oIGksIHR1cGxlICkge1xuXHRcdFx0dmFyIGxpc3QgPSB0dXBsZVsgMiBdLFxuXHRcdFx0XHRzdGF0ZVN0cmluZyA9IHR1cGxlWyA1IF07XG5cblx0XHRcdC8vIHByb21pc2UucHJvZ3Jlc3MgPSBsaXN0LmFkZFxuXHRcdFx0Ly8gcHJvbWlzZS5kb25lID0gbGlzdC5hZGRcblx0XHRcdC8vIHByb21pc2UuZmFpbCA9IGxpc3QuYWRkXG5cdFx0XHRwcm9taXNlWyB0dXBsZVsgMSBdIF0gPSBsaXN0LmFkZDtcblxuXHRcdFx0Ly8gSGFuZGxlIHN0YXRlXG5cdFx0XHRpZiAoIHN0YXRlU3RyaW5nICkge1xuXHRcdFx0XHRsaXN0LmFkZChcblx0XHRcdFx0XHRmdW5jdGlvbigpIHtcblxuXHRcdFx0XHRcdFx0Ly8gc3RhdGUgPSBcInJlc29sdmVkXCIgKGkuZS4sIGZ1bGZpbGxlZClcblx0XHRcdFx0XHRcdC8vIHN0YXRlID0gXCJyZWplY3RlZFwiXG5cdFx0XHRcdFx0XHRzdGF0ZSA9IHN0YXRlU3RyaW5nO1xuXHRcdFx0XHRcdH0sXG5cblx0XHRcdFx0XHQvLyByZWplY3RlZF9jYWxsYmFja3MuZGlzYWJsZVxuXHRcdFx0XHRcdC8vIGZ1bGZpbGxlZF9jYWxsYmFja3MuZGlzYWJsZVxuXHRcdFx0XHRcdHR1cGxlc1sgMyAtIGkgXVsgMiBdLmRpc2FibGUsXG5cblx0XHRcdFx0XHQvLyByZWplY3RlZF9oYW5kbGVycy5kaXNhYmxlXG5cdFx0XHRcdFx0Ly8gZnVsZmlsbGVkX2hhbmRsZXJzLmRpc2FibGVcblx0XHRcdFx0XHR0dXBsZXNbIDMgLSBpIF1bIDMgXS5kaXNhYmxlLFxuXG5cdFx0XHRcdFx0Ly8gcHJvZ3Jlc3NfY2FsbGJhY2tzLmxvY2tcblx0XHRcdFx0XHR0dXBsZXNbIDAgXVsgMiBdLmxvY2ssXG5cblx0XHRcdFx0XHQvLyBwcm9ncmVzc19oYW5kbGVycy5sb2NrXG5cdFx0XHRcdFx0dHVwbGVzWyAwIF1bIDMgXS5sb2NrXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIHByb2dyZXNzX2hhbmRsZXJzLmZpcmVcblx0XHRcdC8vIGZ1bGZpbGxlZF9oYW5kbGVycy5maXJlXG5cdFx0XHQvLyByZWplY3RlZF9oYW5kbGVycy5maXJlXG5cdFx0XHRsaXN0LmFkZCggdHVwbGVbIDMgXS5maXJlICk7XG5cblx0XHRcdC8vIGRlZmVycmVkLm5vdGlmeSA9IGZ1bmN0aW9uKCkgeyBkZWZlcnJlZC5ub3RpZnlXaXRoKC4uLikgfVxuXHRcdFx0Ly8gZGVmZXJyZWQucmVzb2x2ZSA9IGZ1bmN0aW9uKCkgeyBkZWZlcnJlZC5yZXNvbHZlV2l0aCguLi4pIH1cblx0XHRcdC8vIGRlZmVycmVkLnJlamVjdCA9IGZ1bmN0aW9uKCkgeyBkZWZlcnJlZC5yZWplY3RXaXRoKC4uLikgfVxuXHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAwIF0gXSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkZWZlcnJlZFsgdHVwbGVbIDAgXSArIFwiV2l0aFwiIF0oIHRoaXMgPT09IGRlZmVycmVkID8gdW5kZWZpbmVkIDogdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fTtcblxuXHRcdFx0Ly8gZGVmZXJyZWQubm90aWZ5V2l0aCA9IGxpc3QuZmlyZVdpdGhcblx0XHRcdC8vIGRlZmVycmVkLnJlc29sdmVXaXRoID0gbGlzdC5maXJlV2l0aFxuXHRcdFx0Ly8gZGVmZXJyZWQucmVqZWN0V2l0aCA9IGxpc3QuZmlyZVdpdGhcblx0XHRcdGRlZmVycmVkWyB0dXBsZVsgMCBdICsgXCJXaXRoXCIgXSA9IGxpc3QuZmlyZVdpdGg7XG5cdFx0fSApO1xuXG5cdFx0Ly8gTWFrZSB0aGUgZGVmZXJyZWQgYSBwcm9taXNlXG5cdFx0cHJvbWlzZS5wcm9taXNlKCBkZWZlcnJlZCApO1xuXG5cdFx0Ly8gQ2FsbCBnaXZlbiBmdW5jIGlmIGFueVxuXHRcdGlmICggZnVuYyApIHtcblx0XHRcdGZ1bmMuY2FsbCggZGVmZXJyZWQsIGRlZmVycmVkICk7XG5cdFx0fVxuXG5cdFx0Ly8gQWxsIGRvbmUhXG5cdFx0cmV0dXJuIGRlZmVycmVkO1xuXHR9LFxuXG5cdC8vIERlZmVycmVkIGhlbHBlclxuXHR3aGVuOiBmdW5jdGlvbiggc2luZ2xlVmFsdWUgKSB7XG5cdFx0dmFyXG5cblx0XHRcdC8vIGNvdW50IG9mIHVuY29tcGxldGVkIHN1Ym9yZGluYXRlc1xuXHRcdFx0cmVtYWluaW5nID0gYXJndW1lbnRzLmxlbmd0aCxcblxuXHRcdFx0Ly8gY291bnQgb2YgdW5wcm9jZXNzZWQgYXJndW1lbnRzXG5cdFx0XHRpID0gcmVtYWluaW5nLFxuXG5cdFx0XHQvLyBzdWJvcmRpbmF0ZSBmdWxmaWxsbWVudCBkYXRhXG5cdFx0XHRyZXNvbHZlQ29udGV4dHMgPSBBcnJheSggaSApLFxuXHRcdFx0cmVzb2x2ZVZhbHVlcyA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApLFxuXG5cdFx0XHQvLyB0aGUgcHJpbWFyeSBEZWZlcnJlZFxuXHRcdFx0cHJpbWFyeSA9IGpRdWVyeS5EZWZlcnJlZCgpLFxuXG5cdFx0XHQvLyBzdWJvcmRpbmF0ZSBjYWxsYmFjayBmYWN0b3J5XG5cdFx0XHR1cGRhdGVGdW5jID0gZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmVzb2x2ZUNvbnRleHRzWyBpIF0gPSB0aGlzO1xuXHRcdFx0XHRcdHJlc29sdmVWYWx1ZXNbIGkgXSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gc2xpY2UuY2FsbCggYXJndW1lbnRzICkgOiB2YWx1ZTtcblx0XHRcdFx0XHRpZiAoICEoIC0tcmVtYWluaW5nICkgKSB7XG5cdFx0XHRcdFx0XHRwcmltYXJ5LnJlc29sdmVXaXRoKCByZXNvbHZlQ29udGV4dHMsIHJlc29sdmVWYWx1ZXMgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cdFx0XHR9O1xuXG5cdFx0Ly8gU2luZ2xlLSBhbmQgZW1wdHkgYXJndW1lbnRzIGFyZSBhZG9wdGVkIGxpa2UgUHJvbWlzZS5yZXNvbHZlXG5cdFx0aWYgKCByZW1haW5pbmcgPD0gMSApIHtcblx0XHRcdGFkb3B0VmFsdWUoIHNpbmdsZVZhbHVlLCBwcmltYXJ5LmRvbmUoIHVwZGF0ZUZ1bmMoIGkgKSApLnJlc29sdmUsIHByaW1hcnkucmVqZWN0LFxuXHRcdFx0XHQhcmVtYWluaW5nICk7XG5cblx0XHRcdC8vIFVzZSAudGhlbigpIHRvIHVud3JhcCBzZWNvbmRhcnkgdGhlbmFibGVzIChjZi4gZ2gtMzAwMClcblx0XHRcdGlmICggcHJpbWFyeS5zdGF0ZSgpID09PSBcInBlbmRpbmdcIiB8fFxuXHRcdFx0XHRpc0Z1bmN0aW9uKCByZXNvbHZlVmFsdWVzWyBpIF0gJiYgcmVzb2x2ZVZhbHVlc1sgaSBdLnRoZW4gKSApIHtcblxuXHRcdFx0XHRyZXR1cm4gcHJpbWFyeS50aGVuKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gTXVsdGlwbGUgYXJndW1lbnRzIGFyZSBhZ2dyZWdhdGVkIGxpa2UgUHJvbWlzZS5hbGwgYXJyYXkgZWxlbWVudHNcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdGFkb3B0VmFsdWUoIHJlc29sdmVWYWx1ZXNbIGkgXSwgdXBkYXRlRnVuYyggaSApLCBwcmltYXJ5LnJlamVjdCApO1xuXHRcdH1cblxuXHRcdHJldHVybiBwcmltYXJ5LnByb21pc2UoKTtcblx0fVxufSApO1xuXG5cbi8vIFRoZXNlIHVzdWFsbHkgaW5kaWNhdGUgYSBwcm9ncmFtbWVyIG1pc3Rha2UgZHVyaW5nIGRldmVsb3BtZW50LFxuLy8gd2FybiBhYm91dCB0aGVtIEFTQVAgcmF0aGVyIHRoYW4gc3dhbGxvd2luZyB0aGVtIGJ5IGRlZmF1bHQuXG52YXIgcmVycm9yTmFtZXMgPSAvXihFdmFsfEludGVybmFsfFJhbmdlfFJlZmVyZW5jZXxTeW50YXh8VHlwZXxVUkkpRXJyb3IkLztcblxualF1ZXJ5LkRlZmVycmVkLmV4Y2VwdGlvbkhvb2sgPSBmdW5jdGlvbiggZXJyb3IsIHN0YWNrICkge1xuXG5cdC8vIFN1cHBvcnQ6IElFIDggLSA5IG9ubHlcblx0Ly8gQ29uc29sZSBleGlzdHMgd2hlbiBkZXYgdG9vbHMgYXJlIG9wZW4sIHdoaWNoIGNhbiBoYXBwZW4gYXQgYW55IHRpbWVcblx0aWYgKCB3aW5kb3cuY29uc29sZSAmJiB3aW5kb3cuY29uc29sZS53YXJuICYmIGVycm9yICYmIHJlcnJvck5hbWVzLnRlc3QoIGVycm9yLm5hbWUgKSApIHtcblx0XHR3aW5kb3cuY29uc29sZS53YXJuKCBcImpRdWVyeS5EZWZlcnJlZCBleGNlcHRpb246IFwiICsgZXJyb3IubWVzc2FnZSwgZXJyb3Iuc3RhY2ssIHN0YWNrICk7XG5cdH1cbn07XG5cblxuXG5cbmpRdWVyeS5yZWFkeUV4Y2VwdGlvbiA9IGZ1bmN0aW9uKCBlcnJvciApIHtcblx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdHRocm93IGVycm9yO1xuXHR9ICk7XG59O1xuXG5cblxuXG4vLyBUaGUgZGVmZXJyZWQgdXNlZCBvbiBET00gcmVhZHlcbnZhciByZWFkeUxpc3QgPSBqUXVlcnkuRGVmZXJyZWQoKTtcblxualF1ZXJ5LmZuLnJlYWR5ID0gZnVuY3Rpb24oIGZuICkge1xuXG5cdHJlYWR5TGlzdFxuXHRcdC50aGVuKCBmbiApXG5cblx0XHQvLyBXcmFwIGpRdWVyeS5yZWFkeUV4Y2VwdGlvbiBpbiBhIGZ1bmN0aW9uIHNvIHRoYXQgdGhlIGxvb2t1cFxuXHRcdC8vIGhhcHBlbnMgYXQgdGhlIHRpbWUgb2YgZXJyb3IgaGFuZGxpbmcgaW5zdGVhZCBvZiBjYWxsYmFja1xuXHRcdC8vIHJlZ2lzdHJhdGlvbi5cblx0XHQuY2F0Y2goIGZ1bmN0aW9uKCBlcnJvciApIHtcblx0XHRcdGpRdWVyeS5yZWFkeUV4Y2VwdGlvbiggZXJyb3IgKTtcblx0XHR9ICk7XG5cblx0cmV0dXJuIHRoaXM7XG59O1xuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cblx0Ly8gSXMgdGhlIERPTSByZWFkeSB0byBiZSB1c2VkPyBTZXQgdG8gdHJ1ZSBvbmNlIGl0IG9jY3Vycy5cblx0aXNSZWFkeTogZmFsc2UsXG5cblx0Ly8gQSBjb3VudGVyIHRvIHRyYWNrIGhvdyBtYW55IGl0ZW1zIHRvIHdhaXQgZm9yIGJlZm9yZVxuXHQvLyB0aGUgcmVhZHkgZXZlbnQgZmlyZXMuIFNlZSAjNjc4MVxuXHRyZWFkeVdhaXQ6IDEsXG5cblx0Ly8gSGFuZGxlIHdoZW4gdGhlIERPTSBpcyByZWFkeVxuXHRyZWFkeTogZnVuY3Rpb24oIHdhaXQgKSB7XG5cblx0XHQvLyBBYm9ydCBpZiB0aGVyZSBhcmUgcGVuZGluZyBob2xkcyBvciB3ZSdyZSBhbHJlYWR5IHJlYWR5XG5cdFx0aWYgKCB3YWl0ID09PSB0cnVlID8gLS1qUXVlcnkucmVhZHlXYWl0IDogalF1ZXJ5LmlzUmVhZHkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gUmVtZW1iZXIgdGhhdCB0aGUgRE9NIGlzIHJlYWR5XG5cdFx0alF1ZXJ5LmlzUmVhZHkgPSB0cnVlO1xuXG5cdFx0Ly8gSWYgYSBub3JtYWwgRE9NIFJlYWR5IGV2ZW50IGZpcmVkLCBkZWNyZW1lbnQsIGFuZCB3YWl0IGlmIG5lZWQgYmVcblx0XHRpZiAoIHdhaXQgIT09IHRydWUgJiYgLS1qUXVlcnkucmVhZHlXYWl0ID4gMCApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBJZiB0aGVyZSBhcmUgZnVuY3Rpb25zIGJvdW5kLCB0byBleGVjdXRlXG5cdFx0cmVhZHlMaXN0LnJlc29sdmVXaXRoKCBkb2N1bWVudCwgWyBqUXVlcnkgXSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5yZWFkeS50aGVuID0gcmVhZHlMaXN0LnRoZW47XG5cbi8vIFRoZSByZWFkeSBldmVudCBoYW5kbGVyIGFuZCBzZWxmIGNsZWFudXAgbWV0aG9kXG5mdW5jdGlvbiBjb21wbGV0ZWQoKSB7XG5cdGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoIFwiRE9NQ29udGVudExvYWRlZFwiLCBjb21wbGV0ZWQgKTtcblx0d2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoIFwibG9hZFwiLCBjb21wbGV0ZWQgKTtcblx0alF1ZXJ5LnJlYWR5KCk7XG59XG5cbi8vIENhdGNoIGNhc2VzIHdoZXJlICQoZG9jdW1lbnQpLnJlYWR5KCkgaXMgY2FsbGVkXG4vLyBhZnRlciB0aGUgYnJvd3NlciBldmVudCBoYXMgYWxyZWFkeSBvY2N1cnJlZC5cbi8vIFN1cHBvcnQ6IElFIDw9OSAtIDEwIG9ubHlcbi8vIE9sZGVyIElFIHNvbWV0aW1lcyBzaWduYWxzIFwiaW50ZXJhY3RpdmVcIiB0b28gc29vblxuaWYgKCBkb2N1bWVudC5yZWFkeVN0YXRlID09PSBcImNvbXBsZXRlXCIgfHxcblx0KCBkb2N1bWVudC5yZWFkeVN0YXRlICE9PSBcImxvYWRpbmdcIiAmJiAhZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmRvU2Nyb2xsICkgKSB7XG5cblx0Ly8gSGFuZGxlIGl0IGFzeW5jaHJvbm91c2x5IHRvIGFsbG93IHNjcmlwdHMgdGhlIG9wcG9ydHVuaXR5IHRvIGRlbGF5IHJlYWR5XG5cdHdpbmRvdy5zZXRUaW1lb3V0KCBqUXVlcnkucmVhZHkgKTtcblxufSBlbHNlIHtcblxuXHQvLyBVc2UgdGhlIGhhbmR5IGV2ZW50IGNhbGxiYWNrXG5cdGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoIFwiRE9NQ29udGVudExvYWRlZFwiLCBjb21wbGV0ZWQgKTtcblxuXHQvLyBBIGZhbGxiYWNrIHRvIHdpbmRvdy5vbmxvYWQsIHRoYXQgd2lsbCBhbHdheXMgd29ya1xuXHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lciggXCJsb2FkXCIsIGNvbXBsZXRlZCApO1xufVxuXG5cblxuXG4vLyBNdWx0aWZ1bmN0aW9uYWwgbWV0aG9kIHRvIGdldCBhbmQgc2V0IHZhbHVlcyBvZiBhIGNvbGxlY3Rpb25cbi8vIFRoZSB2YWx1ZS9zIGNhbiBvcHRpb25hbGx5IGJlIGV4ZWN1dGVkIGlmIGl0J3MgYSBmdW5jdGlvblxudmFyIGFjY2VzcyA9IGZ1bmN0aW9uKCBlbGVtcywgZm4sIGtleSwgdmFsdWUsIGNoYWluYWJsZSwgZW1wdHlHZXQsIHJhdyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IGVsZW1zLmxlbmd0aCxcblx0XHRidWxrID0ga2V5ID09IG51bGw7XG5cblx0Ly8gU2V0cyBtYW55IHZhbHVlc1xuXHRpZiAoIHRvVHlwZSgga2V5ICkgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcblx0XHRmb3IgKCBpIGluIGtleSApIHtcblx0XHRcdGFjY2VzcyggZWxlbXMsIGZuLCBpLCBrZXlbIGkgXSwgdHJ1ZSwgZW1wdHlHZXQsIHJhdyApO1xuXHRcdH1cblxuXHQvLyBTZXRzIG9uZSB2YWx1ZVxuXHR9IGVsc2UgaWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdGNoYWluYWJsZSA9IHRydWU7XG5cblx0XHRpZiAoICFpc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmF3ID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpZiAoIGJ1bGsgKSB7XG5cblx0XHRcdC8vIEJ1bGsgb3BlcmF0aW9ucyBydW4gYWdhaW5zdCB0aGUgZW50aXJlIHNldFxuXHRcdFx0aWYgKCByYXcgKSB7XG5cdFx0XHRcdGZuLmNhbGwoIGVsZW1zLCB2YWx1ZSApO1xuXHRcdFx0XHRmbiA9IG51bGw7XG5cblx0XHRcdC8vIC4uLmV4Y2VwdCB3aGVuIGV4ZWN1dGluZyBmdW5jdGlvbiB2YWx1ZXNcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGJ1bGsgPSBmbjtcblx0XHRcdFx0Zm4gPSBmdW5jdGlvbiggZWxlbSwgX2tleSwgdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGJ1bGsuY2FsbCggalF1ZXJ5KCBlbGVtICksIHZhbHVlICk7XG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBmbiApIHtcblx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRmbihcblx0XHRcdFx0XHRlbGVtc1sgaSBdLCBrZXksIHJhdyA/XG5cdFx0XHRcdFx0XHR2YWx1ZSA6XG5cdFx0XHRcdFx0XHR2YWx1ZS5jYWxsKCBlbGVtc1sgaSBdLCBpLCBmbiggZWxlbXNbIGkgXSwga2V5ICkgKVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGlmICggY2hhaW5hYmxlICkge1xuXHRcdHJldHVybiBlbGVtcztcblx0fVxuXG5cdC8vIEdldHNcblx0aWYgKCBidWxrICkge1xuXHRcdHJldHVybiBmbi5jYWxsKCBlbGVtcyApO1xuXHR9XG5cblx0cmV0dXJuIGxlbiA/IGZuKCBlbGVtc1sgMCBdLCBrZXkgKSA6IGVtcHR5R2V0O1xufTtcblxuXG4vLyBNYXRjaGVzIGRhc2hlZCBzdHJpbmcgZm9yIGNhbWVsaXppbmdcbnZhciBybXNQcmVmaXggPSAvXi1tcy0vLFxuXHRyZGFzaEFscGhhID0gLy0oW2Etel0pL2c7XG5cbi8vIFVzZWQgYnkgY2FtZWxDYXNlIGFzIGNhbGxiYWNrIHRvIHJlcGxhY2UoKVxuZnVuY3Rpb24gZmNhbWVsQ2FzZSggX2FsbCwgbGV0dGVyICkge1xuXHRyZXR1cm4gbGV0dGVyLnRvVXBwZXJDYXNlKCk7XG59XG5cbi8vIENvbnZlcnQgZGFzaGVkIHRvIGNhbWVsQ2FzZTsgdXNlZCBieSB0aGUgY3NzIGFuZCBkYXRhIG1vZHVsZXNcbi8vIFN1cHBvcnQ6IElFIDw9OSAtIDExLCBFZGdlIDEyIC0gMTVcbi8vIE1pY3Jvc29mdCBmb3Jnb3QgdG8gaHVtcCB0aGVpciB2ZW5kb3IgcHJlZml4ICgjOTU3MilcbmZ1bmN0aW9uIGNhbWVsQ2FzZSggc3RyaW5nICkge1xuXHRyZXR1cm4gc3RyaW5nLnJlcGxhY2UoIHJtc1ByZWZpeCwgXCJtcy1cIiApLnJlcGxhY2UoIHJkYXNoQWxwaGEsIGZjYW1lbENhc2UgKTtcbn1cbnZhciBhY2NlcHREYXRhID0gZnVuY3Rpb24oIG93bmVyICkge1xuXG5cdC8vIEFjY2VwdHMgb25seTpcblx0Ly8gIC0gTm9kZVxuXHQvLyAgICAtIE5vZGUuRUxFTUVOVF9OT0RFXG5cdC8vICAgIC0gTm9kZS5ET0NVTUVOVF9OT0RFXG5cdC8vICAtIE9iamVjdFxuXHQvLyAgICAtIEFueVxuXHRyZXR1cm4gb3duZXIubm9kZVR5cGUgPT09IDEgfHwgb3duZXIubm9kZVR5cGUgPT09IDkgfHwgISggK293bmVyLm5vZGVUeXBlICk7XG59O1xuXG5cblxuXG5mdW5jdGlvbiBEYXRhKCkge1xuXHR0aGlzLmV4cGFuZG8gPSBqUXVlcnkuZXhwYW5kbyArIERhdGEudWlkKys7XG59XG5cbkRhdGEudWlkID0gMTtcblxuRGF0YS5wcm90b3R5cGUgPSB7XG5cblx0Y2FjaGU6IGZ1bmN0aW9uKCBvd25lciApIHtcblxuXHRcdC8vIENoZWNrIGlmIHRoZSBvd25lciBvYmplY3QgYWxyZWFkeSBoYXMgYSBjYWNoZVxuXHRcdHZhciB2YWx1ZSA9IG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcblxuXHRcdC8vIElmIG5vdCwgY3JlYXRlIG9uZVxuXHRcdGlmICggIXZhbHVlICkge1xuXHRcdFx0dmFsdWUgPSB7fTtcblxuXHRcdFx0Ly8gV2UgY2FuIGFjY2VwdCBkYXRhIGZvciBub24tZWxlbWVudCBub2RlcyBpbiBtb2Rlcm4gYnJvd3NlcnMsXG5cdFx0XHQvLyBidXQgd2Ugc2hvdWxkIG5vdCwgc2VlICM4MzM1LlxuXHRcdFx0Ly8gQWx3YXlzIHJldHVybiBhbiBlbXB0eSBvYmplY3QuXG5cdFx0XHRpZiAoIGFjY2VwdERhdGEoIG93bmVyICkgKSB7XG5cblx0XHRcdFx0Ly8gSWYgaXQgaXMgYSBub2RlIHVubGlrZWx5IHRvIGJlIHN0cmluZ2lmeS1lZCBvciBsb29wZWQgb3ZlclxuXHRcdFx0XHQvLyB1c2UgcGxhaW4gYXNzaWdubWVudFxuXHRcdFx0XHRpZiAoIG93bmVyLm5vZGVUeXBlICkge1xuXHRcdFx0XHRcdG93bmVyWyB0aGlzLmV4cGFuZG8gXSA9IHZhbHVlO1xuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBzZWN1cmUgaXQgaW4gYSBub24tZW51bWVyYWJsZSBwcm9wZXJ0eVxuXHRcdFx0XHQvLyBjb25maWd1cmFibGUgbXVzdCBiZSB0cnVlIHRvIGFsbG93IHRoZSBwcm9wZXJ0eSB0byBiZVxuXHRcdFx0XHQvLyBkZWxldGVkIHdoZW4gZGF0YSBpcyByZW1vdmVkXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCBvd25lciwgdGhpcy5leHBhbmRvLCB7XG5cdFx0XHRcdFx0XHR2YWx1ZTogdmFsdWUsXG5cdFx0XHRcdFx0XHRjb25maWd1cmFibGU6IHRydWVcblx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdmFsdWU7XG5cdH0sXG5cdHNldDogZnVuY3Rpb24oIG93bmVyLCBkYXRhLCB2YWx1ZSApIHtcblx0XHR2YXIgcHJvcCxcblx0XHRcdGNhY2hlID0gdGhpcy5jYWNoZSggb3duZXIgKTtcblxuXHRcdC8vIEhhbmRsZTogWyBvd25lciwga2V5LCB2YWx1ZSBdIGFyZ3Ncblx0XHQvLyBBbHdheXMgdXNlIGNhbWVsQ2FzZSBrZXkgKGdoLTIyNTcpXG5cdFx0aWYgKCB0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGNhY2hlWyBjYW1lbENhc2UoIGRhdGEgKSBdID0gdmFsdWU7XG5cblx0XHQvLyBIYW5kbGU6IFsgb3duZXIsIHsgcHJvcGVydGllcyB9IF0gYXJnc1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIENvcHkgdGhlIHByb3BlcnRpZXMgb25lLWJ5LW9uZSB0byB0aGUgY2FjaGUgb2JqZWN0XG5cdFx0XHRmb3IgKCBwcm9wIGluIGRhdGEgKSB7XG5cdFx0XHRcdGNhY2hlWyBjYW1lbENhc2UoIHByb3AgKSBdID0gZGF0YVsgcHJvcCBdO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gY2FjaGU7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24oIG93bmVyLCBrZXkgKSB7XG5cdFx0cmV0dXJuIGtleSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdHRoaXMuY2FjaGUoIG93bmVyICkgOlxuXG5cdFx0XHQvLyBBbHdheXMgdXNlIGNhbWVsQ2FzZSBrZXkgKGdoLTIyNTcpXG5cdFx0XHRvd25lclsgdGhpcy5leHBhbmRvIF0gJiYgb3duZXJbIHRoaXMuZXhwYW5kbyBdWyBjYW1lbENhc2UoIGtleSApIF07XG5cdH0sXG5cdGFjY2VzczogZnVuY3Rpb24oIG93bmVyLCBrZXksIHZhbHVlICkge1xuXG5cdFx0Ly8gSW4gY2FzZXMgd2hlcmUgZWl0aGVyOlxuXHRcdC8vXG5cdFx0Ly8gICAxLiBObyBrZXkgd2FzIHNwZWNpZmllZFxuXHRcdC8vICAgMi4gQSBzdHJpbmcga2V5IHdhcyBzcGVjaWZpZWQsIGJ1dCBubyB2YWx1ZSBwcm92aWRlZFxuXHRcdC8vXG5cdFx0Ly8gVGFrZSB0aGUgXCJyZWFkXCIgcGF0aCBhbmQgYWxsb3cgdGhlIGdldCBtZXRob2QgdG8gZGV0ZXJtaW5lXG5cdFx0Ly8gd2hpY2ggdmFsdWUgdG8gcmV0dXJuLCByZXNwZWN0aXZlbHkgZWl0aGVyOlxuXHRcdC8vXG5cdFx0Ly8gICAxLiBUaGUgZW50aXJlIGNhY2hlIG9iamVjdFxuXHRcdC8vICAgMi4gVGhlIGRhdGEgc3RvcmVkIGF0IHRoZSBrZXlcblx0XHQvL1xuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgfHxcblx0XHRcdFx0KCAoIGtleSAmJiB0eXBlb2Yga2V5ID09PSBcInN0cmluZ1wiICkgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCApICkge1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5nZXQoIG93bmVyLCBrZXkgKTtcblx0XHR9XG5cblx0XHQvLyBXaGVuIHRoZSBrZXkgaXMgbm90IGEgc3RyaW5nLCBvciBib3RoIGEga2V5IGFuZCB2YWx1ZVxuXHRcdC8vIGFyZSBzcGVjaWZpZWQsIHNldCBvciBleHRlbmQgKGV4aXN0aW5nIG9iamVjdHMpIHdpdGggZWl0aGVyOlxuXHRcdC8vXG5cdFx0Ly8gICAxLiBBbiBvYmplY3Qgb2YgcHJvcGVydGllc1xuXHRcdC8vICAgMi4gQSBrZXkgYW5kIHZhbHVlXG5cdFx0Ly9cblx0XHR0aGlzLnNldCggb3duZXIsIGtleSwgdmFsdWUgKTtcblxuXHRcdC8vIFNpbmNlIHRoZSBcInNldFwiIHBhdGggY2FuIGhhdmUgdHdvIHBvc3NpYmxlIGVudHJ5IHBvaW50c1xuXHRcdC8vIHJldHVybiB0aGUgZXhwZWN0ZWQgZGF0YSBiYXNlZCBvbiB3aGljaCBwYXRoIHdhcyB0YWtlblsqXVxuXHRcdHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkID8gdmFsdWUgOiBrZXk7XG5cdH0sXG5cdHJlbW92ZTogZnVuY3Rpb24oIG93bmVyLCBrZXkgKSB7XG5cdFx0dmFyIGksXG5cdFx0XHRjYWNoZSA9IG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcblxuXHRcdGlmICggY2FjaGUgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIGtleSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHQvLyBTdXBwb3J0IGFycmF5IG9yIHNwYWNlIHNlcGFyYXRlZCBzdHJpbmcgb2Yga2V5c1xuXHRcdFx0aWYgKCBBcnJheS5pc0FycmF5KCBrZXkgKSApIHtcblxuXHRcdFx0XHQvLyBJZiBrZXkgaXMgYW4gYXJyYXkgb2Yga2V5cy4uLlxuXHRcdFx0XHQvLyBXZSBhbHdheXMgc2V0IGNhbWVsQ2FzZSBrZXlzLCBzbyByZW1vdmUgdGhhdC5cblx0XHRcdFx0a2V5ID0ga2V5Lm1hcCggY2FtZWxDYXNlICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRrZXkgPSBjYW1lbENhc2UoIGtleSApO1xuXG5cdFx0XHRcdC8vIElmIGEga2V5IHdpdGggdGhlIHNwYWNlcyBleGlzdHMsIHVzZSBpdC5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlLCBjcmVhdGUgYW4gYXJyYXkgYnkgbWF0Y2hpbmcgbm9uLXdoaXRlc3BhY2Vcblx0XHRcdFx0a2V5ID0ga2V5IGluIGNhY2hlID9cblx0XHRcdFx0XHRbIGtleSBdIDpcblx0XHRcdFx0XHQoIGtleS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdICk7XG5cdFx0XHR9XG5cblx0XHRcdGkgPSBrZXkubGVuZ3RoO1xuXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0ZGVsZXRlIGNhY2hlWyBrZXlbIGkgXSBdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSB0aGUgZXhwYW5kbyBpZiB0aGVyZSdzIG5vIG1vcmUgZGF0YVxuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgfHwgalF1ZXJ5LmlzRW1wdHlPYmplY3QoIGNhY2hlICkgKSB7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PTM1IC0gNDVcblx0XHRcdC8vIFdlYmtpdCAmIEJsaW5rIHBlcmZvcm1hbmNlIHN1ZmZlcnMgd2hlbiBkZWxldGluZyBwcm9wZXJ0aWVzXG5cdFx0XHQvLyBmcm9tIERPTSBub2Rlcywgc28gc2V0IHRvIHVuZGVmaW5lZCBpbnN0ZWFkXG5cdFx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0zNzg2MDcgKGJ1ZyByZXN0cmljdGVkKVxuXHRcdFx0aWYgKCBvd25lci5ub2RlVHlwZSApIHtcblx0XHRcdFx0b3duZXJbIHRoaXMuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGVsZXRlIG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cdGhhc0RhdGE6IGZ1bmN0aW9uKCBvd25lciApIHtcblx0XHR2YXIgY2FjaGUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07XG5cdFx0cmV0dXJuIGNhY2hlICE9PSB1bmRlZmluZWQgJiYgIWpRdWVyeS5pc0VtcHR5T2JqZWN0KCBjYWNoZSApO1xuXHR9XG59O1xudmFyIGRhdGFQcml2ID0gbmV3IERhdGEoKTtcblxudmFyIGRhdGFVc2VyID0gbmV3IERhdGEoKTtcblxuXG5cbi8vXHRJbXBsZW1lbnRhdGlvbiBTdW1tYXJ5XG4vL1xuLy9cdDEuIEVuZm9yY2UgQVBJIHN1cmZhY2UgYW5kIHNlbWFudGljIGNvbXBhdGliaWxpdHkgd2l0aCAxLjkueCBicmFuY2hcbi8vXHQyLiBJbXByb3ZlIHRoZSBtb2R1bGUncyBtYWludGFpbmFiaWxpdHkgYnkgcmVkdWNpbmcgdGhlIHN0b3JhZ2Vcbi8vXHRcdHBhdGhzIHRvIGEgc2luZ2xlIG1lY2hhbmlzbS5cbi8vXHQzLiBVc2UgdGhlIHNhbWUgc2luZ2xlIG1lY2hhbmlzbSB0byBzdXBwb3J0IFwicHJpdmF0ZVwiIGFuZCBcInVzZXJcIiBkYXRhLlxuLy9cdDQuIF9OZXZlcl8gZXhwb3NlIFwicHJpdmF0ZVwiIGRhdGEgdG8gdXNlciBjb2RlIChUT0RPOiBEcm9wIF9kYXRhLCBfcmVtb3ZlRGF0YSlcbi8vXHQ1LiBBdm9pZCBleHBvc2luZyBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzIG9uIHVzZXIgb2JqZWN0cyAoZWcuIGV4cGFuZG8gcHJvcGVydGllcylcbi8vXHQ2LiBQcm92aWRlIGEgY2xlYXIgcGF0aCBmb3IgaW1wbGVtZW50YXRpb24gdXBncmFkZSB0byBXZWFrTWFwIGluIDIwMTRcblxudmFyIHJicmFjZSA9IC9eKD86XFx7W1xcd1xcV10qXFx9fFxcW1tcXHdcXFddKlxcXSkkLyxcblx0cm11bHRpRGFzaCA9IC9bQS1aXS9nO1xuXG5mdW5jdGlvbiBnZXREYXRhKCBkYXRhICkge1xuXHRpZiAoIGRhdGEgPT09IFwidHJ1ZVwiICkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0aWYgKCBkYXRhID09PSBcImZhbHNlXCIgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0aWYgKCBkYXRhID09PSBcIm51bGxcIiApIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIE9ubHkgY29udmVydCB0byBhIG51bWJlciBpZiBpdCBkb2Vzbid0IGNoYW5nZSB0aGUgc3RyaW5nXG5cdGlmICggZGF0YSA9PT0gK2RhdGEgKyBcIlwiICkge1xuXHRcdHJldHVybiArZGF0YTtcblx0fVxuXG5cdGlmICggcmJyYWNlLnRlc3QoIGRhdGEgKSApIHtcblx0XHRyZXR1cm4gSlNPTi5wYXJzZSggZGF0YSApO1xuXHR9XG5cblx0cmV0dXJuIGRhdGE7XG59XG5cbmZ1bmN0aW9uIGRhdGFBdHRyKCBlbGVtLCBrZXksIGRhdGEgKSB7XG5cdHZhciBuYW1lO1xuXG5cdC8vIElmIG5vdGhpbmcgd2FzIGZvdW5kIGludGVybmFsbHksIHRyeSB0byBmZXRjaCBhbnlcblx0Ly8gZGF0YSBmcm9tIHRoZSBIVE1MNSBkYXRhLSogYXR0cmlidXRlXG5cdGlmICggZGF0YSA9PT0gdW5kZWZpbmVkICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0bmFtZSA9IFwiZGF0YS1cIiArIGtleS5yZXBsYWNlKCBybXVsdGlEYXNoLCBcIi0kJlwiICkudG9Mb3dlckNhc2UoKTtcblx0XHRkYXRhID0gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKTtcblxuXHRcdGlmICggdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRkYXRhID0gZ2V0RGF0YSggZGF0YSApO1xuXHRcdFx0fSBjYXRjaCAoIGUgKSB7fVxuXG5cdFx0XHQvLyBNYWtlIHN1cmUgd2Ugc2V0IHRoZSBkYXRhIHNvIGl0IGlzbid0IGNoYW5nZWQgbGF0ZXJcblx0XHRcdGRhdGFVc2VyLnNldCggZWxlbSwga2V5LCBkYXRhICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBkYXRhO1xufVxuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdGhhc0RhdGE6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBkYXRhVXNlci5oYXNEYXRhKCBlbGVtICkgfHwgZGF0YVByaXYuaGFzRGF0YSggZWxlbSApO1xuXHR9LFxuXG5cdGRhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xuXHRcdHJldHVybiBkYXRhVXNlci5hY2Nlc3MoIGVsZW0sIG5hbWUsIGRhdGEgKTtcblx0fSxcblxuXHRyZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0XHRkYXRhVXNlci5yZW1vdmUoIGVsZW0sIG5hbWUgKTtcblx0fSxcblxuXHQvLyBUT0RPOiBOb3cgdGhhdCBhbGwgY2FsbHMgdG8gX2RhdGEgYW5kIF9yZW1vdmVEYXRhIGhhdmUgYmVlbiByZXBsYWNlZFxuXHQvLyB3aXRoIGRpcmVjdCBjYWxscyB0byBkYXRhUHJpdiBtZXRob2RzLCB0aGVzZSBjYW4gYmUgZGVwcmVjYXRlZC5cblx0X2RhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xuXHRcdHJldHVybiBkYXRhUHJpdi5hY2Nlc3MoIGVsZW0sIG5hbWUsIGRhdGEgKTtcblx0fSxcblxuXHRfcmVtb3ZlRGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XG5cdFx0ZGF0YVByaXYucmVtb3ZlKCBlbGVtLCBuYW1lICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRkYXRhOiBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHtcblx0XHR2YXIgaSwgbmFtZSwgZGF0YSxcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXG5cdFx0XHRhdHRycyA9IGVsZW0gJiYgZWxlbS5hdHRyaWJ1dGVzO1xuXG5cdFx0Ly8gR2V0cyBhbGwgdmFsdWVzXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGlmICggdGhpcy5sZW5ndGggKSB7XG5cdFx0XHRcdGRhdGEgPSBkYXRhVXNlci5nZXQoIGVsZW0gKTtcblxuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgIWRhdGFQcml2LmdldCggZWxlbSwgXCJoYXNEYXRhQXR0cnNcIiApICkge1xuXHRcdFx0XHRcdGkgPSBhdHRycy5sZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDExIG9ubHlcblx0XHRcdFx0XHRcdC8vIFRoZSBhdHRycyBlbGVtZW50cyBjYW4gYmUgbnVsbCAoIzE0ODk0KVxuXHRcdFx0XHRcdFx0aWYgKCBhdHRyc1sgaSBdICkge1xuXHRcdFx0XHRcdFx0XHRuYW1lID0gYXR0cnNbIGkgXS5uYW1lO1xuXHRcdFx0XHRcdFx0XHRpZiAoIG5hbWUuaW5kZXhPZiggXCJkYXRhLVwiICkgPT09IDAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0bmFtZSA9IGNhbWVsQ2FzZSggbmFtZS5zbGljZSggNSApICk7XG5cdFx0XHRcdFx0XHRcdFx0ZGF0YUF0dHIoIGVsZW0sIG5hbWUsIGRhdGFbIG5hbWUgXSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGRhdGFQcml2LnNldCggZWxlbSwgXCJoYXNEYXRhQXR0cnNcIiwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBkYXRhO1xuXHRcdH1cblxuXHRcdC8vIFNldHMgbXVsdGlwbGUgdmFsdWVzXG5cdFx0aWYgKCB0eXBlb2Yga2V5ID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGRhdGFVc2VyLnNldCggdGhpcywga2V5ICk7XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0dmFyIGRhdGE7XG5cblx0XHRcdC8vIFRoZSBjYWxsaW5nIGpRdWVyeSBvYmplY3QgKGVsZW1lbnQgbWF0Y2hlcykgaXMgbm90IGVtcHR5XG5cdFx0XHQvLyAoYW5kIHRoZXJlZm9yZSBoYXMgYW4gZWxlbWVudCBhcHBlYXJzIGF0IHRoaXNbIDAgXSkgYW5kIHRoZVxuXHRcdFx0Ly8gYHZhbHVlYCBwYXJhbWV0ZXIgd2FzIG5vdCB1bmRlZmluZWQuIEFuIGVtcHR5IGpRdWVyeSBvYmplY3Rcblx0XHRcdC8vIHdpbGwgcmVzdWx0IGluIGB1bmRlZmluZWRgIGZvciBlbGVtID0gdGhpc1sgMCBdIHdoaWNoIHdpbGxcblx0XHRcdC8vIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBhbiBhdHRlbXB0IHRvIHJlYWQgYSBkYXRhIGNhY2hlIGlzIG1hZGUuXG5cdFx0XHRpZiAoIGVsZW0gJiYgdmFsdWUgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHQvLyBBdHRlbXB0IHRvIGdldCBkYXRhIGZyb20gdGhlIGNhY2hlXG5cdFx0XHRcdC8vIFRoZSBrZXkgd2lsbCBhbHdheXMgYmUgY2FtZWxDYXNlZCBpbiBEYXRhXG5cdFx0XHRcdGRhdGEgPSBkYXRhVXNlci5nZXQoIGVsZW0sIGtleSApO1xuXHRcdFx0XHRpZiAoIGRhdGEgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRyZXR1cm4gZGF0YTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEF0dGVtcHQgdG8gXCJkaXNjb3ZlclwiIHRoZSBkYXRhIGluXG5cdFx0XHRcdC8vIEhUTUw1IGN1c3RvbSBkYXRhLSogYXR0cnNcblx0XHRcdFx0ZGF0YSA9IGRhdGFBdHRyKCBlbGVtLCBrZXkgKTtcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGRhdGE7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBXZSB0cmllZCByZWFsbHkgaGFyZCwgYnV0IHRoZSBkYXRhIGRvZXNuJ3QgZXhpc3QuXG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2V0IHRoZSBkYXRhLi4uXG5cdFx0XHR0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdC8vIFdlIGFsd2F5cyBzdG9yZSB0aGUgY2FtZWxDYXNlZCBrZXlcblx0XHRcdFx0ZGF0YVVzZXIuc2V0KCB0aGlzLCBrZXksIHZhbHVlICk7XG5cdFx0XHR9ICk7XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxLCBudWxsLCB0cnVlICk7XG5cdH0sXG5cblx0cmVtb3ZlRGF0YTogZnVuY3Rpb24oIGtleSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGRhdGFVc2VyLnJlbW92ZSggdGhpcywga2V5ICk7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cblxualF1ZXJ5LmV4dGVuZCgge1xuXHRxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUsIGRhdGEgKSB7XG5cdFx0dmFyIHF1ZXVlO1xuXG5cdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0dHlwZSA9ICggdHlwZSB8fCBcImZ4XCIgKSArIFwicXVldWVcIjtcblx0XHRcdHF1ZXVlID0gZGF0YVByaXYuZ2V0KCBlbGVtLCB0eXBlICk7XG5cblx0XHRcdC8vIFNwZWVkIHVwIGRlcXVldWUgYnkgZ2V0dGluZyBvdXQgcXVpY2tseSBpZiB0aGlzIGlzIGp1c3QgYSBsb29rdXBcblx0XHRcdGlmICggZGF0YSApIHtcblx0XHRcdFx0aWYgKCAhcXVldWUgfHwgQXJyYXkuaXNBcnJheSggZGF0YSApICkge1xuXHRcdFx0XHRcdHF1ZXVlID0gZGF0YVByaXYuYWNjZXNzKCBlbGVtLCB0eXBlLCBqUXVlcnkubWFrZUFycmF5KCBkYXRhICkgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRxdWV1ZS5wdXNoKCBkYXRhICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBxdWV1ZSB8fCBbXTtcblx0XHR9XG5cdH0sXG5cblx0ZGVxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUgKSB7XG5cdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXG5cdFx0dmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCBlbGVtLCB0eXBlICksXG5cdFx0XHRzdGFydExlbmd0aCA9IHF1ZXVlLmxlbmd0aCxcblx0XHRcdGZuID0gcXVldWUuc2hpZnQoKSxcblx0XHRcdGhvb2tzID0galF1ZXJ5Ll9xdWV1ZUhvb2tzKCBlbGVtLCB0eXBlICksXG5cdFx0XHRuZXh0ID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCBlbGVtLCB0eXBlICk7XG5cdFx0XHR9O1xuXG5cdFx0Ly8gSWYgdGhlIGZ4IHF1ZXVlIGlzIGRlcXVldWVkLCBhbHdheXMgcmVtb3ZlIHRoZSBwcm9ncmVzcyBzZW50aW5lbFxuXHRcdGlmICggZm4gPT09IFwiaW5wcm9ncmVzc1wiICkge1xuXHRcdFx0Zm4gPSBxdWV1ZS5zaGlmdCgpO1xuXHRcdFx0c3RhcnRMZW5ndGgtLTtcblx0XHR9XG5cblx0XHRpZiAoIGZuICkge1xuXG5cdFx0XHQvLyBBZGQgYSBwcm9ncmVzcyBzZW50aW5lbCB0byBwcmV2ZW50IHRoZSBmeCBxdWV1ZSBmcm9tIGJlaW5nXG5cdFx0XHQvLyBhdXRvbWF0aWNhbGx5IGRlcXVldWVkXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwiZnhcIiApIHtcblx0XHRcdFx0cXVldWUudW5zaGlmdCggXCJpbnByb2dyZXNzXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2xlYXIgdXAgdGhlIGxhc3QgcXVldWUgc3RvcCBmdW5jdGlvblxuXHRcdFx0ZGVsZXRlIGhvb2tzLnN0b3A7XG5cdFx0XHRmbi5jYWxsKCBlbGVtLCBuZXh0LCBob29rcyApO1xuXHRcdH1cblxuXHRcdGlmICggIXN0YXJ0TGVuZ3RoICYmIGhvb2tzICkge1xuXHRcdFx0aG9va3MuZW1wdHkuZmlyZSgpO1xuXHRcdH1cblx0fSxcblxuXHQvLyBOb3QgcHVibGljIC0gZ2VuZXJhdGUgYSBxdWV1ZUhvb2tzIG9iamVjdCwgb3IgcmV0dXJuIHRoZSBjdXJyZW50IG9uZVxuXHRfcXVldWVIb29rczogZnVuY3Rpb24oIGVsZW0sIHR5cGUgKSB7XG5cdFx0dmFyIGtleSA9IHR5cGUgKyBcInF1ZXVlSG9va3NcIjtcblx0XHRyZXR1cm4gZGF0YVByaXYuZ2V0KCBlbGVtLCBrZXkgKSB8fCBkYXRhUHJpdi5hY2Nlc3MoIGVsZW0sIGtleSwge1xuXHRcdFx0ZW1wdHk6IGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLmFkZCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgWyB0eXBlICsgXCJxdWV1ZVwiLCBrZXkgXSApO1xuXHRcdFx0fSApXG5cdFx0fSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0cXVldWU6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHZhciBzZXR0ZXIgPSAyO1xuXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGRhdGEgPSB0eXBlO1xuXHRcdFx0dHlwZSA9IFwiZnhcIjtcblx0XHRcdHNldHRlci0tO1xuXHRcdH1cblxuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCA8IHNldHRlciApIHtcblx0XHRcdHJldHVybiBqUXVlcnkucXVldWUoIHRoaXNbIDAgXSwgdHlwZSApO1xuXHRcdH1cblxuXHRcdHJldHVybiBkYXRhID09PSB1bmRlZmluZWQgP1xuXHRcdFx0dGhpcyA6XG5cdFx0XHR0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgcXVldWUgPSBqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIGRhdGEgKTtcblxuXHRcdFx0XHQvLyBFbnN1cmUgYSBob29rcyBmb3IgdGhpcyBxdWV1ZVxuXHRcdFx0XHRqUXVlcnkuX3F1ZXVlSG9va3MoIHRoaXMsIHR5cGUgKTtcblxuXHRcdFx0XHRpZiAoIHR5cGUgPT09IFwiZnhcIiAmJiBxdWV1ZVsgMCBdICE9PSBcImlucHJvZ3Jlc3NcIiApIHtcblx0XHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cdH0sXG5cdGRlcXVldWU6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcblx0XHR9ICk7XG5cdH0sXG5cdGNsZWFyUXVldWU6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdHJldHVybiB0aGlzLnF1ZXVlKCB0eXBlIHx8IFwiZnhcIiwgW10gKTtcblx0fSxcblxuXHQvLyBHZXQgYSBwcm9taXNlIHJlc29sdmVkIHdoZW4gcXVldWVzIG9mIGEgY2VydGFpbiB0eXBlXG5cdC8vIGFyZSBlbXB0aWVkIChmeCBpcyB0aGUgdHlwZSBieSBkZWZhdWx0KVxuXHRwcm9taXNlOiBmdW5jdGlvbiggdHlwZSwgb2JqICkge1xuXHRcdHZhciB0bXAsXG5cdFx0XHRjb3VudCA9IDEsXG5cdFx0XHRkZWZlciA9IGpRdWVyeS5EZWZlcnJlZCgpLFxuXHRcdFx0ZWxlbWVudHMgPSB0aGlzLFxuXHRcdFx0aSA9IHRoaXMubGVuZ3RoLFxuXHRcdFx0cmVzb2x2ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoICEoIC0tY291bnQgKSApIHtcblx0XHRcdFx0XHRkZWZlci5yZXNvbHZlV2l0aCggZWxlbWVudHMsIFsgZWxlbWVudHMgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdG9iaiA9IHR5cGU7XG5cdFx0XHR0eXBlID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdHRtcCA9IGRhdGFQcml2LmdldCggZWxlbWVudHNbIGkgXSwgdHlwZSArIFwicXVldWVIb29rc1wiICk7XG5cdFx0XHRpZiAoIHRtcCAmJiB0bXAuZW1wdHkgKSB7XG5cdFx0XHRcdGNvdW50Kys7XG5cdFx0XHRcdHRtcC5lbXB0eS5hZGQoIHJlc29sdmUgKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmVzb2x2ZSgpO1xuXHRcdHJldHVybiBkZWZlci5wcm9taXNlKCBvYmogKTtcblx0fVxufSApO1xudmFyIHBudW0gPSAoIC9bKy1dPyg/OlxcZCpcXC58KVxcZCsoPzpbZUVdWystXT9cXGQrfCkvICkuc291cmNlO1xuXG52YXIgcmNzc051bSA9IG5ldyBSZWdFeHAoIFwiXig/OihbKy1dKT18KShcIiArIHBudW0gKyBcIikoW2EteiVdKikkXCIsIFwiaVwiICk7XG5cblxudmFyIGNzc0V4cGFuZCA9IFsgXCJUb3BcIiwgXCJSaWdodFwiLCBcIkJvdHRvbVwiLCBcIkxlZnRcIiBdO1xuXG52YXIgZG9jdW1lbnRFbGVtZW50ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXG5cblxuXHR2YXIgaXNBdHRhY2hlZCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XG5cdFx0fSxcblx0XHRjb21wb3NlZCA9IHsgY29tcG9zZWQ6IHRydWUgfTtcblxuXHQvLyBTdXBwb3J0OiBJRSA5IC0gMTErLCBFZGdlIDEyIC0gMTgrLCBpT1MgMTAuMCAtIDEwLjIgb25seVxuXHQvLyBDaGVjayBhdHRhY2htZW50IGFjcm9zcyBzaGFkb3cgRE9NIGJvdW5kYXJpZXMgd2hlbiBwb3NzaWJsZSAoZ2gtMzUwNClcblx0Ly8gU3VwcG9ydDogaU9TIDEwLjAtMTAuMiBvbmx5XG5cdC8vIEVhcmx5IGlPUyAxMCB2ZXJzaW9ucyBzdXBwb3J0IGBhdHRhY2hTaGFkb3dgIGJ1dCBub3QgYGdldFJvb3ROb2RlYCxcblx0Ly8gbGVhZGluZyB0byBlcnJvcnMuIFdlIG5lZWQgdG8gY2hlY2sgZm9yIGBnZXRSb290Tm9kZWAuXG5cdGlmICggZG9jdW1lbnRFbGVtZW50LmdldFJvb3ROb2RlICkge1xuXHRcdGlzQXR0YWNoZWQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApIHx8XG5cdFx0XHRcdGVsZW0uZ2V0Um9vdE5vZGUoIGNvbXBvc2VkICkgPT09IGVsZW0ub3duZXJEb2N1bWVudDtcblx0XHR9O1xuXHR9XG52YXIgaXNIaWRkZW5XaXRoaW5UcmVlID0gZnVuY3Rpb24oIGVsZW0sIGVsICkge1xuXG5cdFx0Ly8gaXNIaWRkZW5XaXRoaW5UcmVlIG1pZ2h0IGJlIGNhbGxlZCBmcm9tIGpRdWVyeSNmaWx0ZXIgZnVuY3Rpb247XG5cdFx0Ly8gaW4gdGhhdCBjYXNlLCBlbGVtZW50IHdpbGwgYmUgc2Vjb25kIGFyZ3VtZW50XG5cdFx0ZWxlbSA9IGVsIHx8IGVsZW07XG5cblx0XHQvLyBJbmxpbmUgc3R5bGUgdHJ1bXBzIGFsbFxuXHRcdHJldHVybiBlbGVtLnN0eWxlLmRpc3BsYXkgPT09IFwibm9uZVwiIHx8XG5cdFx0XHRlbGVtLnN0eWxlLmRpc3BsYXkgPT09IFwiXCIgJiZcblxuXHRcdFx0Ly8gT3RoZXJ3aXNlLCBjaGVjayBjb21wdXRlZCBzdHlsZVxuXHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveCA8PTQzIC0gNDVcblx0XHRcdC8vIERpc2Nvbm5lY3RlZCBlbGVtZW50cyBjYW4gaGF2ZSBjb21wdXRlZCBkaXNwbGF5OiBub25lLCBzbyBmaXJzdCBjb25maXJtIHRoYXQgZWxlbSBpc1xuXHRcdFx0Ly8gaW4gdGhlIGRvY3VtZW50LlxuXHRcdFx0aXNBdHRhY2hlZCggZWxlbSApICYmXG5cblx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICkgPT09IFwibm9uZVwiO1xuXHR9O1xuXG5cblxuZnVuY3Rpb24gYWRqdXN0Q1NTKCBlbGVtLCBwcm9wLCB2YWx1ZVBhcnRzLCB0d2VlbiApIHtcblx0dmFyIGFkanVzdGVkLCBzY2FsZSxcblx0XHRtYXhJdGVyYXRpb25zID0gMjAsXG5cdFx0Y3VycmVudFZhbHVlID0gdHdlZW4gP1xuXHRcdFx0ZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiB0d2Vlbi5jdXIoKTtcblx0XHRcdH0gOlxuXHRcdFx0ZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiBqUXVlcnkuY3NzKCBlbGVtLCBwcm9wLCBcIlwiICk7XG5cdFx0XHR9LFxuXHRcdGluaXRpYWwgPSBjdXJyZW50VmFsdWUoKSxcblx0XHR1bml0ID0gdmFsdWVQYXJ0cyAmJiB2YWx1ZVBhcnRzWyAzIF0gfHwgKCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gPyBcIlwiIDogXCJweFwiICksXG5cblx0XHQvLyBTdGFydGluZyB2YWx1ZSBjb21wdXRhdGlvbiBpcyByZXF1aXJlZCBmb3IgcG90ZW50aWFsIHVuaXQgbWlzbWF0Y2hlc1xuXHRcdGluaXRpYWxJblVuaXQgPSBlbGVtLm5vZGVUeXBlICYmXG5cdFx0XHQoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSB8fCB1bml0ICE9PSBcInB4XCIgJiYgK2luaXRpYWwgKSAmJlxuXHRcdFx0cmNzc051bS5leGVjKCBqUXVlcnkuY3NzKCBlbGVtLCBwcm9wICkgKTtcblxuXHRpZiAoIGluaXRpYWxJblVuaXQgJiYgaW5pdGlhbEluVW5pdFsgMyBdICE9PSB1bml0ICkge1xuXG5cdFx0Ly8gU3VwcG9ydDogRmlyZWZveCA8PTU0XG5cdFx0Ly8gSGFsdmUgdGhlIGl0ZXJhdGlvbiB0YXJnZXQgdmFsdWUgdG8gcHJldmVudCBpbnRlcmZlcmVuY2UgZnJvbSBDU1MgdXBwZXIgYm91bmRzIChnaC0yMTQ0KVxuXHRcdGluaXRpYWwgPSBpbml0aWFsIC8gMjtcblxuXHRcdC8vIFRydXN0IHVuaXRzIHJlcG9ydGVkIGJ5IGpRdWVyeS5jc3Ncblx0XHR1bml0ID0gdW5pdCB8fCBpbml0aWFsSW5Vbml0WyAzIF07XG5cblx0XHQvLyBJdGVyYXRpdmVseSBhcHByb3hpbWF0ZSBmcm9tIGEgbm9uemVybyBzdGFydGluZyBwb2ludFxuXHRcdGluaXRpYWxJblVuaXQgPSAraW5pdGlhbCB8fCAxO1xuXG5cdFx0d2hpbGUgKCBtYXhJdGVyYXRpb25zLS0gKSB7XG5cblx0XHRcdC8vIEV2YWx1YXRlIGFuZCB1cGRhdGUgb3VyIGJlc3QgZ3Vlc3MgKGRvdWJsaW5nIGd1ZXNzZXMgdGhhdCB6ZXJvIG91dCkuXG5cdFx0XHQvLyBGaW5pc2ggaWYgdGhlIHNjYWxlIGVxdWFscyBvciBjcm9zc2VzIDEgKG1ha2luZyB0aGUgb2xkKm5ldyBwcm9kdWN0IG5vbi1wb3NpdGl2ZSkuXG5cdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AsIGluaXRpYWxJblVuaXQgKyB1bml0ICk7XG5cdFx0XHRpZiAoICggMSAtIHNjYWxlICkgKiAoIDEgLSAoIHNjYWxlID0gY3VycmVudFZhbHVlKCkgLyBpbml0aWFsIHx8IDAuNSApICkgPD0gMCApIHtcblx0XHRcdFx0bWF4SXRlcmF0aW9ucyA9IDA7XG5cdFx0XHR9XG5cdFx0XHRpbml0aWFsSW5Vbml0ID0gaW5pdGlhbEluVW5pdCAvIHNjYWxlO1xuXG5cdFx0fVxuXG5cdFx0aW5pdGlhbEluVW5pdCA9IGluaXRpYWxJblVuaXQgKiAyO1xuXHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCwgaW5pdGlhbEluVW5pdCArIHVuaXQgKTtcblxuXHRcdC8vIE1ha2Ugc3VyZSB3ZSB1cGRhdGUgdGhlIHR3ZWVuIHByb3BlcnRpZXMgbGF0ZXIgb25cblx0XHR2YWx1ZVBhcnRzID0gdmFsdWVQYXJ0cyB8fCBbXTtcblx0fVxuXG5cdGlmICggdmFsdWVQYXJ0cyApIHtcblx0XHRpbml0aWFsSW5Vbml0ID0gK2luaXRpYWxJblVuaXQgfHwgK2luaXRpYWwgfHwgMDtcblxuXHRcdC8vIEFwcGx5IHJlbGF0aXZlIG9mZnNldCAoKz0vLT0pIGlmIHNwZWNpZmllZFxuXHRcdGFkanVzdGVkID0gdmFsdWVQYXJ0c1sgMSBdID9cblx0XHRcdGluaXRpYWxJblVuaXQgKyAoIHZhbHVlUGFydHNbIDEgXSArIDEgKSAqIHZhbHVlUGFydHNbIDIgXSA6XG5cdFx0XHQrdmFsdWVQYXJ0c1sgMiBdO1xuXHRcdGlmICggdHdlZW4gKSB7XG5cdFx0XHR0d2Vlbi51bml0ID0gdW5pdDtcblx0XHRcdHR3ZWVuLnN0YXJ0ID0gaW5pdGlhbEluVW5pdDtcblx0XHRcdHR3ZWVuLmVuZCA9IGFkanVzdGVkO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gYWRqdXN0ZWQ7XG59XG5cblxudmFyIGRlZmF1bHREaXNwbGF5TWFwID0ge307XG5cbmZ1bmN0aW9uIGdldERlZmF1bHREaXNwbGF5KCBlbGVtICkge1xuXHR2YXIgdGVtcCxcblx0XHRkb2MgPSBlbGVtLm93bmVyRG9jdW1lbnQsXG5cdFx0bm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lLFxuXHRcdGRpc3BsYXkgPSBkZWZhdWx0RGlzcGxheU1hcFsgbm9kZU5hbWUgXTtcblxuXHRpZiAoIGRpc3BsYXkgKSB7XG5cdFx0cmV0dXJuIGRpc3BsYXk7XG5cdH1cblxuXHR0ZW1wID0gZG9jLmJvZHkuYXBwZW5kQ2hpbGQoIGRvYy5jcmVhdGVFbGVtZW50KCBub2RlTmFtZSApICk7XG5cdGRpc3BsYXkgPSBqUXVlcnkuY3NzKCB0ZW1wLCBcImRpc3BsYXlcIiApO1xuXG5cdHRlbXAucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggdGVtcCApO1xuXG5cdGlmICggZGlzcGxheSA9PT0gXCJub25lXCIgKSB7XG5cdFx0ZGlzcGxheSA9IFwiYmxvY2tcIjtcblx0fVxuXHRkZWZhdWx0RGlzcGxheU1hcFsgbm9kZU5hbWUgXSA9IGRpc3BsYXk7XG5cblx0cmV0dXJuIGRpc3BsYXk7XG59XG5cbmZ1bmN0aW9uIHNob3dIaWRlKCBlbGVtZW50cywgc2hvdyApIHtcblx0dmFyIGRpc3BsYXksIGVsZW0sXG5cdFx0dmFsdWVzID0gW10sXG5cdFx0aW5kZXggPSAwLFxuXHRcdGxlbmd0aCA9IGVsZW1lbnRzLmxlbmd0aDtcblxuXHQvLyBEZXRlcm1pbmUgbmV3IGRpc3BsYXkgdmFsdWUgZm9yIGVsZW1lbnRzIHRoYXQgbmVlZCB0byBjaGFuZ2Vcblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRlbGVtID0gZWxlbWVudHNbIGluZGV4IF07XG5cdFx0aWYgKCAhZWxlbS5zdHlsZSApIHtcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblxuXHRcdGRpc3BsYXkgPSBlbGVtLnN0eWxlLmRpc3BsYXk7XG5cdFx0aWYgKCBzaG93ICkge1xuXG5cdFx0XHQvLyBTaW5jZSB3ZSBmb3JjZSB2aXNpYmlsaXR5IHVwb24gY2FzY2FkZS1oaWRkZW4gZWxlbWVudHMsIGFuIGltbWVkaWF0ZSAoYW5kIHNsb3cpXG5cdFx0XHQvLyBjaGVjayBpcyByZXF1aXJlZCBpbiB0aGlzIGZpcnN0IGxvb3AgdW5sZXNzIHdlIGhhdmUgYSBub25lbXB0eSBkaXNwbGF5IHZhbHVlIChlaXRoZXJcblx0XHRcdC8vIGlubGluZSBvciBhYm91dC10by1iZS1yZXN0b3JlZClcblx0XHRcdGlmICggZGlzcGxheSA9PT0gXCJub25lXCIgKSB7XG5cdFx0XHRcdHZhbHVlc1sgaW5kZXggXSA9IGRhdGFQcml2LmdldCggZWxlbSwgXCJkaXNwbGF5XCIgKSB8fCBudWxsO1xuXHRcdFx0XHRpZiAoICF2YWx1ZXNbIGluZGV4IF0gKSB7XG5cdFx0XHRcdFx0ZWxlbS5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKCBlbGVtLnN0eWxlLmRpc3BsYXkgPT09IFwiXCIgJiYgaXNIaWRkZW5XaXRoaW5UcmVlKCBlbGVtICkgKSB7XG5cdFx0XHRcdHZhbHVlc1sgaW5kZXggXSA9IGdldERlZmF1bHREaXNwbGF5KCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmICggZGlzcGxheSAhPT0gXCJub25lXCIgKSB7XG5cdFx0XHRcdHZhbHVlc1sgaW5kZXggXSA9IFwibm9uZVwiO1xuXG5cdFx0XHRcdC8vIFJlbWVtYmVyIHdoYXQgd2UncmUgb3ZlcndyaXRpbmdcblx0XHRcdFx0ZGF0YVByaXYuc2V0KCBlbGVtLCBcImRpc3BsYXlcIiwgZGlzcGxheSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIFNldCB0aGUgZGlzcGxheSBvZiB0aGUgZWxlbWVudHMgaW4gYSBzZWNvbmQgbG9vcCB0byBhdm9pZCBjb25zdGFudCByZWZsb3dcblx0Zm9yICggaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRpZiAoIHZhbHVlc1sgaW5kZXggXSAhPSBudWxsICkge1xuXHRcdFx0ZWxlbWVudHNbIGluZGV4IF0uc3R5bGUuZGlzcGxheSA9IHZhbHVlc1sgaW5kZXggXTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZWxlbWVudHM7XG59XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0c2hvdzogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHNob3dIaWRlKCB0aGlzLCB0cnVlICk7XG5cdH0sXG5cdGhpZGU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzaG93SGlkZSggdGhpcyApO1xuXHR9LFxuXHR0b2dnbGU6IGZ1bmN0aW9uKCBzdGF0ZSApIHtcblx0XHRpZiAoIHR5cGVvZiBzdGF0ZSA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0XHRyZXR1cm4gc3RhdGUgPyB0aGlzLnNob3coKSA6IHRoaXMuaGlkZSgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBpc0hpZGRlbldpdGhpblRyZWUoIHRoaXMgKSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuc2hvdygpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuaGlkZSgpO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxufSApO1xudmFyIHJjaGVja2FibGVUeXBlID0gKCAvXig/OmNoZWNrYm94fHJhZGlvKSQvaSApO1xuXG52YXIgcnRhZ05hbWUgPSAoIC88KFthLXpdW15cXC9cXDA+XFx4MjBcXHRcXHJcXG5cXGZdKikvaSApO1xuXG52YXIgcnNjcmlwdFR5cGUgPSAoIC9eJHxebW9kdWxlJHxcXC8oPzpqYXZhfGVjbWEpc2NyaXB0L2kgKTtcblxuXG5cbiggZnVuY3Rpb24oKSB7XG5cdHZhciBmcmFnbWVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSxcblx0XHRkaXYgPSBmcmFnbWVudC5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApICksXG5cdFx0aW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5XG5cdC8vIENoZWNrIHN0YXRlIGxvc3QgaWYgdGhlIG5hbWUgaXMgc2V0ICgjMTEyMTcpXG5cdC8vIFN1cHBvcnQ6IFdpbmRvd3MgV2ViIEFwcHMgKFdXQSlcblx0Ly8gYG5hbWVgIGFuZCBgdHlwZWAgbXVzdCB1c2UgLnNldEF0dHJpYnV0ZSBmb3IgV1dBICgjMTQ5MDEpXG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIFwicmFkaW9cIiApO1xuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwiY2hlY2tlZFwiLCBcImNoZWNrZWRcIiApO1xuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwibmFtZVwiLCBcInRcIiApO1xuXG5cdGRpdi5hcHBlbmRDaGlsZCggaW5wdXQgKTtcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4xIG9ubHlcblx0Ly8gT2xkZXIgV2ViS2l0IGRvZXNuJ3QgY2xvbmUgY2hlY2tlZCBzdGF0ZSBjb3JyZWN0bHkgaW4gZnJhZ21lbnRzXG5cdHN1cHBvcnQuY2hlY2tDbG9uZSA9IGRpdi5jbG9uZU5vZGUoIHRydWUgKS5jbG9uZU5vZGUoIHRydWUgKS5sYXN0Q2hpbGQuY2hlY2tlZDtcblxuXHQvLyBTdXBwb3J0OiBJRSA8PTExIG9ubHlcblx0Ly8gTWFrZSBzdXJlIHRleHRhcmVhIChhbmQgY2hlY2tib3gpIGRlZmF1bHRWYWx1ZSBpcyBwcm9wZXJseSBjbG9uZWRcblx0ZGl2LmlubmVySFRNTCA9IFwiPHRleHRhcmVhPng8L3RleHRhcmVhPlwiO1xuXHRzdXBwb3J0Lm5vQ2xvbmVDaGVja2VkID0gISFkaXYuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmRlZmF1bHRWYWx1ZTtcblxuXHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHQvLyBJRSA8PTkgcmVwbGFjZXMgPG9wdGlvbj4gdGFncyB3aXRoIHRoZWlyIGNvbnRlbnRzIHdoZW4gaW5zZXJ0ZWQgb3V0c2lkZSBvZlxuXHQvLyB0aGUgc2VsZWN0IGVsZW1lbnQuXG5cdGRpdi5pbm5lckhUTUwgPSBcIjxvcHRpb24+PC9vcHRpb24+XCI7XG5cdHN1cHBvcnQub3B0aW9uID0gISFkaXYubGFzdENoaWxkO1xufSApKCk7XG5cblxuLy8gV2UgaGF2ZSB0byBjbG9zZSB0aGVzZSB0YWdzIHRvIHN1cHBvcnQgWEhUTUwgKCMxMzIwMClcbnZhciB3cmFwTWFwID0ge1xuXG5cdC8vIFhIVE1MIHBhcnNlcnMgZG8gbm90IG1hZ2ljYWxseSBpbnNlcnQgZWxlbWVudHMgaW4gdGhlXG5cdC8vIHNhbWUgd2F5IHRoYXQgdGFnIHNvdXAgcGFyc2VycyBkby4gU28gd2UgY2Fubm90IHNob3J0ZW5cblx0Ly8gdGhpcyBieSBvbWl0dGluZyA8dGJvZHk+IG9yIG90aGVyIHJlcXVpcmVkIGVsZW1lbnRzLlxuXHR0aGVhZDogWyAxLCBcIjx0YWJsZT5cIiwgXCI8L3RhYmxlPlwiIF0sXG5cdGNvbDogWyAyLCBcIjx0YWJsZT48Y29sZ3JvdXA+XCIsIFwiPC9jb2xncm91cD48L3RhYmxlPlwiIF0sXG5cdHRyOiBbIDIsIFwiPHRhYmxlPjx0Ym9keT5cIiwgXCI8L3Rib2R5PjwvdGFibGU+XCIgXSxcblx0dGQ6IFsgMywgXCI8dGFibGU+PHRib2R5Pjx0cj5cIiwgXCI8L3RyPjwvdGJvZHk+PC90YWJsZT5cIiBdLFxuXG5cdF9kZWZhdWx0OiBbIDAsIFwiXCIsIFwiXCIgXVxufTtcblxud3JhcE1hcC50Ym9keSA9IHdyYXBNYXAudGZvb3QgPSB3cmFwTWFwLmNvbGdyb3VwID0gd3JhcE1hcC5jYXB0aW9uID0gd3JhcE1hcC50aGVhZDtcbndyYXBNYXAudGggPSB3cmFwTWFwLnRkO1xuXG4vLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuaWYgKCAhc3VwcG9ydC5vcHRpb24gKSB7XG5cdHdyYXBNYXAub3B0Z3JvdXAgPSB3cmFwTWFwLm9wdGlvbiA9IFsgMSwgXCI8c2VsZWN0IG11bHRpcGxlPSdtdWx0aXBsZSc+XCIsIFwiPC9zZWxlY3Q+XCIgXTtcbn1cblxuXG5mdW5jdGlvbiBnZXRBbGwoIGNvbnRleHQsIHRhZyApIHtcblxuXHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSBvbmx5XG5cdC8vIFVzZSB0eXBlb2YgdG8gYXZvaWQgemVyby1hcmd1bWVudCBtZXRob2QgaW52b2NhdGlvbiBvbiBob3N0IG9iamVjdHMgKCMxNTE1MSlcblx0dmFyIHJldDtcblxuXHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdHJldCA9IGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyB8fCBcIipcIiApO1xuXG5cdH0gZWxzZSBpZiAoIHR5cGVvZiBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwgIT09IFwidW5kZWZpbmVkXCIgKSB7XG5cdFx0cmV0ID0gY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCB0YWcgfHwgXCIqXCIgKTtcblxuXHR9IGVsc2Uge1xuXHRcdHJldCA9IFtdO1xuXHR9XG5cblx0aWYgKCB0YWcgPT09IHVuZGVmaW5lZCB8fCB0YWcgJiYgbm9kZU5hbWUoIGNvbnRleHQsIHRhZyApICkge1xuXHRcdHJldHVybiBqUXVlcnkubWVyZ2UoIFsgY29udGV4dCBdLCByZXQgKTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59XG5cblxuLy8gTWFyayBzY3JpcHRzIGFzIGhhdmluZyBhbHJlYWR5IGJlZW4gZXZhbHVhdGVkXG5mdW5jdGlvbiBzZXRHbG9iYWxFdmFsKCBlbGVtcywgcmVmRWxlbWVudHMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsID0gZWxlbXMubGVuZ3RoO1xuXG5cdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRkYXRhUHJpdi5zZXQoXG5cdFx0XHRlbGVtc1sgaSBdLFxuXHRcdFx0XCJnbG9iYWxFdmFsXCIsXG5cdFx0XHQhcmVmRWxlbWVudHMgfHwgZGF0YVByaXYuZ2V0KCByZWZFbGVtZW50c1sgaSBdLCBcImdsb2JhbEV2YWxcIiApXG5cdFx0KTtcblx0fVxufVxuXG5cbnZhciByaHRtbCA9IC88fCYjP1xcdys7LztcblxuZnVuY3Rpb24gYnVpbGRGcmFnbWVudCggZWxlbXMsIGNvbnRleHQsIHNjcmlwdHMsIHNlbGVjdGlvbiwgaWdub3JlZCApIHtcblx0dmFyIGVsZW0sIHRtcCwgdGFnLCB3cmFwLCBhdHRhY2hlZCwgaixcblx0XHRmcmFnbWVudCA9IGNvbnRleHQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxuXHRcdG5vZGVzID0gW10sXG5cdFx0aSA9IDAsXG5cdFx0bCA9IGVsZW1zLmxlbmd0aDtcblxuXHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0ZWxlbSA9IGVsZW1zWyBpIF07XG5cblx0XHRpZiAoIGVsZW0gfHwgZWxlbSA9PT0gMCApIHtcblxuXHRcdFx0Ly8gQWRkIG5vZGVzIGRpcmVjdGx5XG5cdFx0XHRpZiAoIHRvVHlwZSggZWxlbSApID09PSBcIm9iamVjdFwiICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seSwgUGhhbnRvbUpTIDEgb25seVxuXHRcdFx0XHQvLyBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XG5cdFx0XHRcdGpRdWVyeS5tZXJnZSggbm9kZXMsIGVsZW0ubm9kZVR5cGUgPyBbIGVsZW0gXSA6IGVsZW0gKTtcblxuXHRcdFx0Ly8gQ29udmVydCBub24taHRtbCBpbnRvIGEgdGV4dCBub2RlXG5cdFx0XHR9IGVsc2UgaWYgKCAhcmh0bWwudGVzdCggZWxlbSApICkge1xuXHRcdFx0XHRub2Rlcy5wdXNoKCBjb250ZXh0LmNyZWF0ZVRleHROb2RlKCBlbGVtICkgKTtcblxuXHRcdFx0Ly8gQ29udmVydCBodG1sIGludG8gRE9NIG5vZGVzXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0bXAgPSB0bXAgfHwgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGNvbnRleHQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApICk7XG5cblx0XHRcdFx0Ly8gRGVzZXJpYWxpemUgYSBzdGFuZGFyZCByZXByZXNlbnRhdGlvblxuXHRcdFx0XHR0YWcgPSAoIHJ0YWdOYW1lLmV4ZWMoIGVsZW0gKSB8fCBbIFwiXCIsIFwiXCIgXSApWyAxIF0udG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0d3JhcCA9IHdyYXBNYXBbIHRhZyBdIHx8IHdyYXBNYXAuX2RlZmF1bHQ7XG5cdFx0XHRcdHRtcC5pbm5lckhUTUwgPSB3cmFwWyAxIF0gKyBqUXVlcnkuaHRtbFByZWZpbHRlciggZWxlbSApICsgd3JhcFsgMiBdO1xuXG5cdFx0XHRcdC8vIERlc2NlbmQgdGhyb3VnaCB3cmFwcGVycyB0byB0aGUgcmlnaHQgY29udGVudFxuXHRcdFx0XHRqID0gd3JhcFsgMCBdO1xuXHRcdFx0XHR3aGlsZSAoIGotLSApIHtcblx0XHRcdFx0XHR0bXAgPSB0bXAubGFzdENoaWxkO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5XG5cdFx0XHRcdC8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXRcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgdG1wLmNoaWxkTm9kZXMgKTtcblxuXHRcdFx0XHQvLyBSZW1lbWJlciB0aGUgdG9wLWxldmVsIGNvbnRhaW5lclxuXHRcdFx0XHR0bXAgPSBmcmFnbWVudC5maXJzdENoaWxkO1xuXG5cdFx0XHRcdC8vIEVuc3VyZSB0aGUgY3JlYXRlZCBub2RlcyBhcmUgb3JwaGFuZWQgKCMxMjM5Milcblx0XHRcdFx0dG1wLnRleHRDb250ZW50ID0gXCJcIjtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBSZW1vdmUgd3JhcHBlciBmcm9tIGZyYWdtZW50XG5cdGZyYWdtZW50LnRleHRDb250ZW50ID0gXCJcIjtcblxuXHRpID0gMDtcblx0d2hpbGUgKCAoIGVsZW0gPSBub2Rlc1sgaSsrIF0gKSApIHtcblxuXHRcdC8vIFNraXAgZWxlbWVudHMgYWxyZWFkeSBpbiB0aGUgY29udGV4dCBjb2xsZWN0aW9uICh0cmFjLTQwODcpXG5cdFx0aWYgKCBzZWxlY3Rpb24gJiYgalF1ZXJ5LmluQXJyYXkoIGVsZW0sIHNlbGVjdGlvbiApID4gLTEgKSB7XG5cdFx0XHRpZiAoIGlnbm9yZWQgKSB7XG5cdFx0XHRcdGlnbm9yZWQucHVzaCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdFx0Y29udGludWU7XG5cdFx0fVxuXG5cdFx0YXR0YWNoZWQgPSBpc0F0dGFjaGVkKCBlbGVtICk7XG5cblx0XHQvLyBBcHBlbmQgdG8gZnJhZ21lbnRcblx0XHR0bXAgPSBnZXRBbGwoIGZyYWdtZW50LmFwcGVuZENoaWxkKCBlbGVtICksIFwic2NyaXB0XCIgKTtcblxuXHRcdC8vIFByZXNlcnZlIHNjcmlwdCBldmFsdWF0aW9uIGhpc3Rvcnlcblx0XHRpZiAoIGF0dGFjaGVkICkge1xuXHRcdFx0c2V0R2xvYmFsRXZhbCggdG1wICk7XG5cdFx0fVxuXG5cdFx0Ly8gQ2FwdHVyZSBleGVjdXRhYmxlc1xuXHRcdGlmICggc2NyaXB0cyApIHtcblx0XHRcdGogPSAwO1xuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0bXBbIGorKyBdICkgKSB7XG5cdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggZWxlbS50eXBlIHx8IFwiXCIgKSApIHtcblx0XHRcdFx0XHRzY3JpcHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBmcmFnbWVudDtcbn1cblxuXG52YXIgcnR5cGVuYW1lc3BhY2UgPSAvXihbXi5dKikoPzpcXC4oLispfCkvO1xuXG5mdW5jdGlvbiByZXR1cm5UcnVlKCkge1xuXHRyZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmV0dXJuRmFsc2UoKSB7XG5cdHJldHVybiBmYWxzZTtcbn1cblxuLy8gU3VwcG9ydDogSUUgPD05IC0gMTErXG4vLyBmb2N1cygpIGFuZCBibHVyKCkgYXJlIGFzeW5jaHJvbm91cywgZXhjZXB0IHdoZW4gdGhleSBhcmUgbm8tb3AuXG4vLyBTbyBleHBlY3QgZm9jdXMgdG8gYmUgc3luY2hyb25vdXMgd2hlbiB0aGUgZWxlbWVudCBpcyBhbHJlYWR5IGFjdGl2ZSxcbi8vIGFuZCBibHVyIHRvIGJlIHN5bmNocm9ub3VzIHdoZW4gdGhlIGVsZW1lbnQgaXMgbm90IGFscmVhZHkgYWN0aXZlLlxuLy8gKGZvY3VzIGFuZCBibHVyIGFyZSBhbHdheXMgc3luY2hyb25vdXMgaW4gb3RoZXIgc3VwcG9ydGVkIGJyb3dzZXJzLFxuLy8gdGhpcyBqdXN0IGRlZmluZXMgd2hlbiB3ZSBjYW4gY291bnQgb24gaXQpLlxuZnVuY3Rpb24gZXhwZWN0U3luYyggZWxlbSwgdHlwZSApIHtcblx0cmV0dXJuICggZWxlbSA9PT0gc2FmZUFjdGl2ZUVsZW1lbnQoKSApID09PSAoIHR5cGUgPT09IFwiZm9jdXNcIiApO1xufVxuXG4vLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuLy8gQWNjZXNzaW5nIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgY2FuIHRocm93IHVuZXhwZWN0ZWRseVxuLy8gaHR0cHM6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEzMzkzXG5mdW5jdGlvbiBzYWZlQWN0aXZlRWxlbWVudCgpIHtcblx0dHJ5IHtcblx0XHRyZXR1cm4gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcblx0fSBjYXRjaCAoIGVyciApIHsgfVxufVxuXG5mdW5jdGlvbiBvbiggZWxlbSwgdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiwgb25lICkge1xuXHR2YXIgb3JpZ0ZuLCB0eXBlO1xuXG5cdC8vIFR5cGVzIGNhbiBiZSBhIG1hcCBvZiB0eXBlcy9oYW5kbGVyc1xuXHRpZiAoIHR5cGVvZiB0eXBlcyA9PT0gXCJvYmplY3RcIiApIHtcblxuXHRcdC8vICggdHlwZXMtT2JqZWN0LCBzZWxlY3RvciwgZGF0YSApXG5cdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgIT09IFwic3RyaW5nXCIgKSB7XG5cblx0XHRcdC8vICggdHlwZXMtT2JqZWN0LCBkYXRhIClcblx0XHRcdGRhdGEgPSBkYXRhIHx8IHNlbGVjdG9yO1xuXHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGZvciAoIHR5cGUgaW4gdHlwZXMgKSB7XG5cdFx0XHRvbiggZWxlbSwgdHlwZSwgc2VsZWN0b3IsIGRhdGEsIHR5cGVzWyB0eXBlIF0sIG9uZSApO1xuXHRcdH1cblx0XHRyZXR1cm4gZWxlbTtcblx0fVxuXG5cdGlmICggZGF0YSA9PSBudWxsICYmIGZuID09IG51bGwgKSB7XG5cblx0XHQvLyAoIHR5cGVzLCBmbiApXG5cdFx0Zm4gPSBzZWxlY3Rvcjtcblx0XHRkYXRhID0gc2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdH0gZWxzZSBpZiAoIGZuID09IG51bGwgKSB7XG5cdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XG5cblx0XHRcdC8vICggdHlwZXMsIHNlbGVjdG9yLCBmbiApXG5cdFx0XHRmbiA9IGRhdGE7XG5cdFx0XHRkYXRhID0gdW5kZWZpbmVkO1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vICggdHlwZXMsIGRhdGEsIGZuIClcblx0XHRcdGZuID0gZGF0YTtcblx0XHRcdGRhdGEgPSBzZWxlY3Rvcjtcblx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0fVxuXHRpZiAoIGZuID09PSBmYWxzZSApIHtcblx0XHRmbiA9IHJldHVybkZhbHNlO1xuXHR9IGVsc2UgaWYgKCAhZm4gKSB7XG5cdFx0cmV0dXJuIGVsZW07XG5cdH1cblxuXHRpZiAoIG9uZSA9PT0gMSApIHtcblx0XHRvcmlnRm4gPSBmbjtcblx0XHRmbiA9IGZ1bmN0aW9uKCBldmVudCApIHtcblxuXHRcdFx0Ly8gQ2FuIHVzZSBhbiBlbXB0eSBzZXQsIHNpbmNlIGV2ZW50IGNvbnRhaW5zIHRoZSBpbmZvXG5cdFx0XHRqUXVlcnkoKS5vZmYoIGV2ZW50ICk7XG5cdFx0XHRyZXR1cm4gb3JpZ0ZuLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHR9O1xuXG5cdFx0Ly8gVXNlIHNhbWUgZ3VpZCBzbyBjYWxsZXIgY2FuIHJlbW92ZSB1c2luZyBvcmlnRm5cblx0XHRmbi5ndWlkID0gb3JpZ0ZuLmd1aWQgfHwgKCBvcmlnRm4uZ3VpZCA9IGpRdWVyeS5ndWlkKysgKTtcblx0fVxuXHRyZXR1cm4gZWxlbS5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRqUXVlcnkuZXZlbnQuYWRkKCB0aGlzLCB0eXBlcywgZm4sIGRhdGEsIHNlbGVjdG9yICk7XG5cdH0gKTtcbn1cblxuLypcbiAqIEhlbHBlciBmdW5jdGlvbnMgZm9yIG1hbmFnaW5nIGV2ZW50cyAtLSBub3QgcGFydCBvZiB0aGUgcHVibGljIGludGVyZmFjZS5cbiAqIFByb3BzIHRvIERlYW4gRWR3YXJkcycgYWRkRXZlbnQgbGlicmFyeSBmb3IgbWFueSBvZiB0aGUgaWRlYXMuXG4gKi9cbmpRdWVyeS5ldmVudCA9IHtcblxuXHRnbG9iYWw6IHt9LFxuXG5cdGFkZDogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBkYXRhLCBzZWxlY3RvciApIHtcblxuXHRcdHZhciBoYW5kbGVPYmpJbiwgZXZlbnRIYW5kbGUsIHRtcCxcblx0XHRcdGV2ZW50cywgdCwgaGFuZGxlT2JqLFxuXHRcdFx0c3BlY2lhbCwgaGFuZGxlcnMsIHR5cGUsIG5hbWVzcGFjZXMsIG9yaWdUeXBlLFxuXHRcdFx0ZWxlbURhdGEgPSBkYXRhUHJpdi5nZXQoIGVsZW0gKTtcblxuXHRcdC8vIE9ubHkgYXR0YWNoIGV2ZW50cyB0byBvYmplY3RzIHRoYXQgYWNjZXB0IGRhdGFcblx0XHRpZiAoICFhY2NlcHREYXRhKCBlbGVtICkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsbGVyIGNhbiBwYXNzIGluIGFuIG9iamVjdCBvZiBjdXN0b20gZGF0YSBpbiBsaWV1IG9mIHRoZSBoYW5kbGVyXG5cdFx0aWYgKCBoYW5kbGVyLmhhbmRsZXIgKSB7XG5cdFx0XHRoYW5kbGVPYmpJbiA9IGhhbmRsZXI7XG5cdFx0XHRoYW5kbGVyID0gaGFuZGxlT2JqSW4uaGFuZGxlcjtcblx0XHRcdHNlbGVjdG9yID0gaGFuZGxlT2JqSW4uc2VsZWN0b3I7XG5cdFx0fVxuXG5cdFx0Ly8gRW5zdXJlIHRoYXQgaW52YWxpZCBzZWxlY3RvcnMgdGhyb3cgZXhjZXB0aW9ucyBhdCBhdHRhY2ggdGltZVxuXHRcdC8vIEV2YWx1YXRlIGFnYWluc3QgZG9jdW1lbnRFbGVtZW50IGluIGNhc2UgZWxlbSBpcyBhIG5vbi1lbGVtZW50IG5vZGUgKGUuZy4sIGRvY3VtZW50KVxuXHRcdGlmICggc2VsZWN0b3IgKSB7XG5cdFx0XHRqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoIGRvY3VtZW50RWxlbWVudCwgc2VsZWN0b3IgKTtcblx0XHR9XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB0aGUgaGFuZGxlciBoYXMgYSB1bmlxdWUgSUQsIHVzZWQgdG8gZmluZC9yZW1vdmUgaXQgbGF0ZXJcblx0XHRpZiAoICFoYW5kbGVyLmd1aWQgKSB7XG5cdFx0XHRoYW5kbGVyLmd1aWQgPSBqUXVlcnkuZ3VpZCsrO1xuXHRcdH1cblxuXHRcdC8vIEluaXQgdGhlIGVsZW1lbnQncyBldmVudCBzdHJ1Y3R1cmUgYW5kIG1haW4gaGFuZGxlciwgaWYgdGhpcyBpcyB0aGUgZmlyc3Rcblx0XHRpZiAoICEoIGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyApICkge1xuXHRcdFx0ZXZlbnRzID0gZWxlbURhdGEuZXZlbnRzID0gT2JqZWN0LmNyZWF0ZSggbnVsbCApO1xuXHRcdH1cblx0XHRpZiAoICEoIGV2ZW50SGFuZGxlID0gZWxlbURhdGEuaGFuZGxlICkgKSB7XG5cdFx0XHRldmVudEhhbmRsZSA9IGVsZW1EYXRhLmhhbmRsZSA9IGZ1bmN0aW9uKCBlICkge1xuXG5cdFx0XHRcdC8vIERpc2NhcmQgdGhlIHNlY29uZCBldmVudCBvZiBhIGpRdWVyeS5ldmVudC50cmlnZ2VyKCkgYW5kXG5cdFx0XHRcdC8vIHdoZW4gYW4gZXZlbnQgaXMgY2FsbGVkIGFmdGVyIGEgcGFnZSBoYXMgdW5sb2FkZWRcblx0XHRcdFx0cmV0dXJuIHR5cGVvZiBqUXVlcnkgIT09IFwidW5kZWZpbmVkXCIgJiYgalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCAhPT0gZS50eXBlID9cblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQuZGlzcGF0Y2guYXBwbHkoIGVsZW0sIGFyZ3VtZW50cyApIDogdW5kZWZpbmVkO1xuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyBIYW5kbGUgbXVsdGlwbGUgZXZlbnRzIHNlcGFyYXRlZCBieSBhIHNwYWNlXG5cdFx0dHlwZXMgPSAoIHR5cGVzIHx8IFwiXCIgKS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFsgXCJcIiBdO1xuXHRcdHQgPSB0eXBlcy5sZW5ndGg7XG5cdFx0d2hpbGUgKCB0LS0gKSB7XG5cdFx0XHR0bXAgPSBydHlwZW5hbWVzcGFjZS5leGVjKCB0eXBlc1sgdCBdICkgfHwgW107XG5cdFx0XHR0eXBlID0gb3JpZ1R5cGUgPSB0bXBbIDEgXTtcblx0XHRcdG5hbWVzcGFjZXMgPSAoIHRtcFsgMiBdIHx8IFwiXCIgKS5zcGxpdCggXCIuXCIgKS5zb3J0KCk7XG5cblx0XHRcdC8vIFRoZXJlICptdXN0KiBiZSBhIHR5cGUsIG5vIGF0dGFjaGluZyBuYW1lc3BhY2Utb25seSBoYW5kbGVyc1xuXHRcdFx0aWYgKCAhdHlwZSApIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIGV2ZW50IGNoYW5nZXMgaXRzIHR5cGUsIHVzZSB0aGUgc3BlY2lhbCBldmVudCBoYW5kbGVycyBmb3IgdGhlIGNoYW5nZWQgdHlwZVxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cblx0XHRcdC8vIElmIHNlbGVjdG9yIGRlZmluZWQsIGRldGVybWluZSBzcGVjaWFsIGV2ZW50IGFwaSB0eXBlLCBvdGhlcndpc2UgZ2l2ZW4gdHlwZVxuXHRcdFx0dHlwZSA9ICggc2VsZWN0b3IgPyBzcGVjaWFsLmRlbGVnYXRlVHlwZSA6IHNwZWNpYWwuYmluZFR5cGUgKSB8fCB0eXBlO1xuXG5cdFx0XHQvLyBVcGRhdGUgc3BlY2lhbCBiYXNlZCBvbiBuZXdseSByZXNldCB0eXBlXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblxuXHRcdFx0Ly8gaGFuZGxlT2JqIGlzIHBhc3NlZCB0byBhbGwgZXZlbnQgaGFuZGxlcnNcblx0XHRcdGhhbmRsZU9iaiA9IGpRdWVyeS5leHRlbmQoIHtcblx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0b3JpZ1R5cGU6IG9yaWdUeXBlLFxuXHRcdFx0XHRkYXRhOiBkYXRhLFxuXHRcdFx0XHRoYW5kbGVyOiBoYW5kbGVyLFxuXHRcdFx0XHRndWlkOiBoYW5kbGVyLmd1aWQsXG5cdFx0XHRcdHNlbGVjdG9yOiBzZWxlY3Rvcixcblx0XHRcdFx0bmVlZHNDb250ZXh0OiBzZWxlY3RvciAmJiBqUXVlcnkuZXhwci5tYXRjaC5uZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSxcblx0XHRcdFx0bmFtZXNwYWNlOiBuYW1lc3BhY2VzLmpvaW4oIFwiLlwiIClcblx0XHRcdH0sIGhhbmRsZU9iakluICk7XG5cblx0XHRcdC8vIEluaXQgdGhlIGV2ZW50IGhhbmRsZXIgcXVldWUgaWYgd2UncmUgdGhlIGZpcnN0XG5cdFx0XHRpZiAoICEoIGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gKSApIHtcblx0XHRcdFx0aGFuZGxlcnMgPSBldmVudHNbIHR5cGUgXSA9IFtdO1xuXHRcdFx0XHRoYW5kbGVycy5kZWxlZ2F0ZUNvdW50ID0gMDtcblxuXHRcdFx0XHQvLyBPbmx5IHVzZSBhZGRFdmVudExpc3RlbmVyIGlmIHRoZSBzcGVjaWFsIGV2ZW50cyBoYW5kbGVyIHJldHVybnMgZmFsc2Vcblx0XHRcdFx0aWYgKCAhc3BlY2lhbC5zZXR1cCB8fFxuXHRcdFx0XHRcdHNwZWNpYWwuc2V0dXAuY2FsbCggZWxlbSwgZGF0YSwgbmFtZXNwYWNlcywgZXZlbnRIYW5kbGUgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdFx0XHRpZiAoIGVsZW0uYWRkRXZlbnRMaXN0ZW5lciApIHtcblx0XHRcdFx0XHRcdGVsZW0uYWRkRXZlbnRMaXN0ZW5lciggdHlwZSwgZXZlbnRIYW5kbGUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBzcGVjaWFsLmFkZCApIHtcblx0XHRcdFx0c3BlY2lhbC5hZGQuY2FsbCggZWxlbSwgaGFuZGxlT2JqICk7XG5cblx0XHRcdFx0aWYgKCAhaGFuZGxlT2JqLmhhbmRsZXIuZ3VpZCApIHtcblx0XHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlci5ndWlkID0gaGFuZGxlci5ndWlkO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCB0byB0aGUgZWxlbWVudCdzIGhhbmRsZXIgbGlzdCwgZGVsZWdhdGVzIGluIGZyb250XG5cdFx0XHRpZiAoIHNlbGVjdG9yICkge1xuXHRcdFx0XHRoYW5kbGVycy5zcGxpY2UoIGhhbmRsZXJzLmRlbGVnYXRlQ291bnQrKywgMCwgaGFuZGxlT2JqICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRoYW5kbGVycy5wdXNoKCBoYW5kbGVPYmogKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gS2VlcCB0cmFjayBvZiB3aGljaCBldmVudHMgaGF2ZSBldmVyIGJlZW4gdXNlZCwgZm9yIGV2ZW50IG9wdGltaXphdGlvblxuXHRcdFx0alF1ZXJ5LmV2ZW50Lmdsb2JhbFsgdHlwZSBdID0gdHJ1ZTtcblx0XHR9XG5cblx0fSxcblxuXHQvLyBEZXRhY2ggYW4gZXZlbnQgb3Igc2V0IG9mIGV2ZW50cyBmcm9tIGFuIGVsZW1lbnRcblx0cmVtb3ZlOiBmdW5jdGlvbiggZWxlbSwgdHlwZXMsIGhhbmRsZXIsIHNlbGVjdG9yLCBtYXBwZWRUeXBlcyApIHtcblxuXHRcdHZhciBqLCBvcmlnQ291bnQsIHRtcCxcblx0XHRcdGV2ZW50cywgdCwgaGFuZGxlT2JqLFxuXHRcdFx0c3BlY2lhbCwgaGFuZGxlcnMsIHR5cGUsIG5hbWVzcGFjZXMsIG9yaWdUeXBlLFxuXHRcdFx0ZWxlbURhdGEgPSBkYXRhUHJpdi5oYXNEYXRhKCBlbGVtICkgJiYgZGF0YVByaXYuZ2V0KCBlbGVtICk7XG5cblx0XHRpZiAoICFlbGVtRGF0YSB8fCAhKCBldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgKSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBPbmNlIGZvciBlYWNoIHR5cGUubmFtZXNwYWNlIGluIHR5cGVzOyB0eXBlIG1heSBiZSBvbWl0dGVkXG5cdFx0dHlwZXMgPSAoIHR5cGVzIHx8IFwiXCIgKS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFsgXCJcIiBdO1xuXHRcdHQgPSB0eXBlcy5sZW5ndGg7XG5cdFx0d2hpbGUgKCB0LS0gKSB7XG5cdFx0XHR0bXAgPSBydHlwZW5hbWVzcGFjZS5leGVjKCB0eXBlc1sgdCBdICkgfHwgW107XG5cdFx0XHR0eXBlID0gb3JpZ1R5cGUgPSB0bXBbIDEgXTtcblx0XHRcdG5hbWVzcGFjZXMgPSAoIHRtcFsgMiBdIHx8IFwiXCIgKS5zcGxpdCggXCIuXCIgKS5zb3J0KCk7XG5cblx0XHRcdC8vIFVuYmluZCBhbGwgZXZlbnRzIChvbiB0aGlzIG5hbWVzcGFjZSwgaWYgcHJvdmlkZWQpIGZvciB0aGUgZWxlbWVudFxuXHRcdFx0aWYgKCAhdHlwZSApIHtcblx0XHRcdFx0Zm9yICggdHlwZSBpbiBldmVudHMgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggZWxlbSwgdHlwZSArIHR5cGVzWyB0IF0sIGhhbmRsZXIsIHNlbGVjdG9yLCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXHRcdFx0dHlwZSA9ICggc2VsZWN0b3IgPyBzcGVjaWFsLmRlbGVnYXRlVHlwZSA6IHNwZWNpYWwuYmluZFR5cGUgKSB8fCB0eXBlO1xuXHRcdFx0aGFuZGxlcnMgPSBldmVudHNbIHR5cGUgXSB8fCBbXTtcblx0XHRcdHRtcCA9IHRtcFsgMiBdICYmXG5cdFx0XHRcdG5ldyBSZWdFeHAoIFwiKF58XFxcXC4pXCIgKyBuYW1lc3BhY2VzLmpvaW4oIFwiXFxcXC4oPzouKlxcXFwufClcIiApICsgXCIoXFxcXC58JClcIiApO1xuXG5cdFx0XHQvLyBSZW1vdmUgbWF0Y2hpbmcgZXZlbnRzXG5cdFx0XHRvcmlnQ291bnQgPSBqID0gaGFuZGxlcnMubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRcdGhhbmRsZU9iaiA9IGhhbmRsZXJzWyBqIF07XG5cblx0XHRcdFx0aWYgKCAoIG1hcHBlZFR5cGVzIHx8IG9yaWdUeXBlID09PSBoYW5kbGVPYmoub3JpZ1R5cGUgKSAmJlxuXHRcdFx0XHRcdCggIWhhbmRsZXIgfHwgaGFuZGxlci5ndWlkID09PSBoYW5kbGVPYmouZ3VpZCApICYmXG5cdFx0XHRcdFx0KCAhdG1wIHx8IHRtcC50ZXN0KCBoYW5kbGVPYmoubmFtZXNwYWNlICkgKSAmJlxuXHRcdFx0XHRcdCggIXNlbGVjdG9yIHx8IHNlbGVjdG9yID09PSBoYW5kbGVPYmouc2VsZWN0b3IgfHxcblx0XHRcdFx0XHRcdHNlbGVjdG9yID09PSBcIioqXCIgJiYgaGFuZGxlT2JqLnNlbGVjdG9yICkgKSB7XG5cdFx0XHRcdFx0aGFuZGxlcnMuc3BsaWNlKCBqLCAxICk7XG5cblx0XHRcdFx0XHRpZiAoIGhhbmRsZU9iai5zZWxlY3RvciApIHtcblx0XHRcdFx0XHRcdGhhbmRsZXJzLmRlbGVnYXRlQ291bnQtLTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBzcGVjaWFsLnJlbW92ZSApIHtcblx0XHRcdFx0XHRcdHNwZWNpYWwucmVtb3ZlLmNhbGwoIGVsZW0sIGhhbmRsZU9iaiApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZW1vdmUgZ2VuZXJpYyBldmVudCBoYW5kbGVyIGlmIHdlIHJlbW92ZWQgc29tZXRoaW5nIGFuZCBubyBtb3JlIGhhbmRsZXJzIGV4aXN0XG5cdFx0XHQvLyAoYXZvaWRzIHBvdGVudGlhbCBmb3IgZW5kbGVzcyByZWN1cnNpb24gZHVyaW5nIHJlbW92YWwgb2Ygc3BlY2lhbCBldmVudCBoYW5kbGVycylcblx0XHRcdGlmICggb3JpZ0NvdW50ICYmICFoYW5kbGVycy5sZW5ndGggKSB7XG5cdFx0XHRcdGlmICggIXNwZWNpYWwudGVhcmRvd24gfHxcblx0XHRcdFx0XHRzcGVjaWFsLnRlYXJkb3duLmNhbGwoIGVsZW0sIG5hbWVzcGFjZXMsIGVsZW1EYXRhLmhhbmRsZSApID09PSBmYWxzZSApIHtcblxuXHRcdFx0XHRcdGpRdWVyeS5yZW1vdmVFdmVudCggZWxlbSwgdHlwZSwgZWxlbURhdGEuaGFuZGxlICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRkZWxldGUgZXZlbnRzWyB0eXBlIF07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUmVtb3ZlIGRhdGEgYW5kIHRoZSBleHBhbmRvIGlmIGl0J3Mgbm8gbG9uZ2VyIHVzZWRcblx0XHRpZiAoIGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBldmVudHMgKSApIHtcblx0XHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgXCJoYW5kbGUgZXZlbnRzXCIgKTtcblx0XHR9XG5cdH0sXG5cblx0ZGlzcGF0Y2g6IGZ1bmN0aW9uKCBuYXRpdmVFdmVudCApIHtcblxuXHRcdHZhciBpLCBqLCByZXQsIG1hdGNoZWQsIGhhbmRsZU9iaiwgaGFuZGxlclF1ZXVlLFxuXHRcdFx0YXJncyA9IG5ldyBBcnJheSggYXJndW1lbnRzLmxlbmd0aCApLFxuXG5cdFx0XHQvLyBNYWtlIGEgd3JpdGFibGUgalF1ZXJ5LkV2ZW50IGZyb20gdGhlIG5hdGl2ZSBldmVudCBvYmplY3Rcblx0XHRcdGV2ZW50ID0galF1ZXJ5LmV2ZW50LmZpeCggbmF0aXZlRXZlbnQgKSxcblxuXHRcdFx0aGFuZGxlcnMgPSAoXG5cdFx0XHRcdGRhdGFQcml2LmdldCggdGhpcywgXCJldmVudHNcIiApIHx8IE9iamVjdC5jcmVhdGUoIG51bGwgKVxuXHRcdFx0KVsgZXZlbnQudHlwZSBdIHx8IFtdLFxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyBldmVudC50eXBlIF0gfHwge307XG5cblx0XHQvLyBVc2UgdGhlIGZpeC1lZCBqUXVlcnkuRXZlbnQgcmF0aGVyIHRoYW4gdGhlIChyZWFkLW9ubHkpIG5hdGl2ZSBldmVudFxuXHRcdGFyZ3NbIDAgXSA9IGV2ZW50O1xuXG5cdFx0Zm9yICggaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRhcmdzWyBpIF0gPSBhcmd1bWVudHNbIGkgXTtcblx0XHR9XG5cblx0XHRldmVudC5kZWxlZ2F0ZVRhcmdldCA9IHRoaXM7XG5cblx0XHQvLyBDYWxsIHRoZSBwcmVEaXNwYXRjaCBob29rIGZvciB0aGUgbWFwcGVkIHR5cGUsIGFuZCBsZXQgaXQgYmFpbCBpZiBkZXNpcmVkXG5cdFx0aWYgKCBzcGVjaWFsLnByZURpc3BhdGNoICYmIHNwZWNpYWwucHJlRGlzcGF0Y2guY2FsbCggdGhpcywgZXZlbnQgKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRGV0ZXJtaW5lIGhhbmRsZXJzXG5cdFx0aGFuZGxlclF1ZXVlID0galF1ZXJ5LmV2ZW50LmhhbmRsZXJzLmNhbGwoIHRoaXMsIGV2ZW50LCBoYW5kbGVycyApO1xuXG5cdFx0Ly8gUnVuIGRlbGVnYXRlcyBmaXJzdDsgdGhleSBtYXkgd2FudCB0byBzdG9wIHByb3BhZ2F0aW9uIGJlbmVhdGggdXNcblx0XHRpID0gMDtcblx0XHR3aGlsZSAoICggbWF0Y2hlZCA9IGhhbmRsZXJRdWV1ZVsgaSsrIF0gKSAmJiAhZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblx0XHRcdGV2ZW50LmN1cnJlbnRUYXJnZXQgPSBtYXRjaGVkLmVsZW07XG5cblx0XHRcdGogPSAwO1xuXHRcdFx0d2hpbGUgKCAoIGhhbmRsZU9iaiA9IG1hdGNoZWQuaGFuZGxlcnNbIGorKyBdICkgJiZcblx0XHRcdFx0IWV2ZW50LmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cblx0XHRcdFx0Ly8gSWYgdGhlIGV2ZW50IGlzIG5hbWVzcGFjZWQsIHRoZW4gZWFjaCBoYW5kbGVyIGlzIG9ubHkgaW52b2tlZCBpZiBpdCBpc1xuXHRcdFx0XHQvLyBzcGVjaWFsbHkgdW5pdmVyc2FsIG9yIGl0cyBuYW1lc3BhY2VzIGFyZSBhIHN1cGVyc2V0IG9mIHRoZSBldmVudCdzLlxuXHRcdFx0XHRpZiAoICFldmVudC5ybmFtZXNwYWNlIHx8IGhhbmRsZU9iai5uYW1lc3BhY2UgPT09IGZhbHNlIHx8XG5cdFx0XHRcdFx0ZXZlbnQucm5hbWVzcGFjZS50ZXN0KCBoYW5kbGVPYmoubmFtZXNwYWNlICkgKSB7XG5cblx0XHRcdFx0XHRldmVudC5oYW5kbGVPYmogPSBoYW5kbGVPYmo7XG5cdFx0XHRcdFx0ZXZlbnQuZGF0YSA9IGhhbmRsZU9iai5kYXRhO1xuXG5cdFx0XHRcdFx0cmV0ID0gKCAoIGpRdWVyeS5ldmVudC5zcGVjaWFsWyBoYW5kbGVPYmoub3JpZ1R5cGUgXSB8fCB7fSApLmhhbmRsZSB8fFxuXHRcdFx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXIgKS5hcHBseSggbWF0Y2hlZC5lbGVtLCBhcmdzICk7XG5cblx0XHRcdFx0XHRpZiAoIHJldCAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoIGV2ZW50LnJlc3VsdCA9IHJldCApID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsbCB0aGUgcG9zdERpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZVxuXHRcdGlmICggc3BlY2lhbC5wb3N0RGlzcGF0Y2ggKSB7XG5cdFx0XHRzcGVjaWFsLnBvc3REaXNwYXRjaC5jYWxsKCB0aGlzLCBldmVudCApO1xuXHRcdH1cblxuXHRcdHJldHVybiBldmVudC5yZXN1bHQ7XG5cdH0sXG5cblx0aGFuZGxlcnM6IGZ1bmN0aW9uKCBldmVudCwgaGFuZGxlcnMgKSB7XG5cdFx0dmFyIGksIGhhbmRsZU9iaiwgc2VsLCBtYXRjaGVkSGFuZGxlcnMsIG1hdGNoZWRTZWxlY3RvcnMsXG5cdFx0XHRoYW5kbGVyUXVldWUgPSBbXSxcblx0XHRcdGRlbGVnYXRlQ291bnQgPSBoYW5kbGVycy5kZWxlZ2F0ZUNvdW50LFxuXHRcdFx0Y3VyID0gZXZlbnQudGFyZ2V0O1xuXG5cdFx0Ly8gRmluZCBkZWxlZ2F0ZSBoYW5kbGVyc1xuXHRcdGlmICggZGVsZWdhdGVDb3VudCAmJlxuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTlcblx0XHRcdC8vIEJsYWNrLWhvbGUgU1ZHIDx1c2U+IGluc3RhbmNlIHRyZWVzICh0cmFjLTEzMTgwKVxuXHRcdFx0Y3VyLm5vZGVUeXBlICYmXG5cblx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD00MlxuXHRcdFx0Ly8gU3VwcHJlc3Mgc3BlYy12aW9sYXRpbmcgY2xpY2tzIGluZGljYXRpbmcgYSBub24tcHJpbWFyeSBwb2ludGVyIGJ1dHRvbiAodHJhYy0zODYxKVxuXHRcdFx0Ly8gaHR0cHM6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy8jZXZlbnQtdHlwZS1jbGlja1xuXHRcdFx0Ly8gU3VwcG9ydDogSUUgMTEgb25seVxuXHRcdFx0Ly8gLi4uYnV0IG5vdCBhcnJvdyBrZXkgXCJjbGlja3NcIiBvZiByYWRpbyBpbnB1dHMsIHdoaWNoIGNhbiBoYXZlIGBidXR0b25gIC0xIChnaC0yMzQzKVxuXHRcdFx0ISggZXZlbnQudHlwZSA9PT0gXCJjbGlja1wiICYmIGV2ZW50LmJ1dHRvbiA+PSAxICkgKSB7XG5cblx0XHRcdGZvciAoIDsgY3VyICE9PSB0aGlzOyBjdXIgPSBjdXIucGFyZW50Tm9kZSB8fCB0aGlzICkge1xuXG5cdFx0XHRcdC8vIERvbid0IGNoZWNrIG5vbi1lbGVtZW50cyAoIzEzMjA4KVxuXHRcdFx0XHQvLyBEb24ndCBwcm9jZXNzIGNsaWNrcyBvbiBkaXNhYmxlZCBlbGVtZW50cyAoIzY5MTEsICM4MTY1LCAjMTEzODIsICMxMTc2NClcblx0XHRcdFx0aWYgKCBjdXIubm9kZVR5cGUgPT09IDEgJiYgISggZXZlbnQudHlwZSA9PT0gXCJjbGlja1wiICYmIGN1ci5kaXNhYmxlZCA9PT0gdHJ1ZSApICkge1xuXHRcdFx0XHRcdG1hdGNoZWRIYW5kbGVycyA9IFtdO1xuXHRcdFx0XHRcdG1hdGNoZWRTZWxlY3RvcnMgPSB7fTtcblx0XHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGRlbGVnYXRlQ291bnQ7IGkrKyApIHtcblx0XHRcdFx0XHRcdGhhbmRsZU9iaiA9IGhhbmRsZXJzWyBpIF07XG5cblx0XHRcdFx0XHRcdC8vIERvbid0IGNvbmZsaWN0IHdpdGggT2JqZWN0LnByb3RvdHlwZSBwcm9wZXJ0aWVzICgjMTMyMDMpXG5cdFx0XHRcdFx0XHRzZWwgPSBoYW5kbGVPYmouc2VsZWN0b3IgKyBcIiBcIjtcblxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVkU2VsZWN0b3JzWyBzZWwgXSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdFx0XHRtYXRjaGVkU2VsZWN0b3JzWyBzZWwgXSA9IGhhbmRsZU9iai5uZWVkc0NvbnRleHQgP1xuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeSggc2VsLCB0aGlzICkuaW5kZXgoIGN1ciApID4gLTEgOlxuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5maW5kKCBzZWwsIHRoaXMsIG51bGwsIFsgY3VyIF0gKS5sZW5ndGg7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZWRTZWxlY3RvcnNbIHNlbCBdICkge1xuXHRcdFx0XHRcdFx0XHRtYXRjaGVkSGFuZGxlcnMucHVzaCggaGFuZGxlT2JqICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggbWF0Y2hlZEhhbmRsZXJzLmxlbmd0aCApIHtcblx0XHRcdFx0XHRcdGhhbmRsZXJRdWV1ZS5wdXNoKCB7IGVsZW06IGN1ciwgaGFuZGxlcnM6IG1hdGNoZWRIYW5kbGVycyB9ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQWRkIHRoZSByZW1haW5pbmcgKGRpcmVjdGx5LWJvdW5kKSBoYW5kbGVyc1xuXHRcdGN1ciA9IHRoaXM7XG5cdFx0aWYgKCBkZWxlZ2F0ZUNvdW50IDwgaGFuZGxlcnMubGVuZ3RoICkge1xuXHRcdFx0aGFuZGxlclF1ZXVlLnB1c2goIHsgZWxlbTogY3VyLCBoYW5kbGVyczogaGFuZGxlcnMuc2xpY2UoIGRlbGVnYXRlQ291bnQgKSB9ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGhhbmRsZXJRdWV1ZTtcblx0fSxcblxuXHRhZGRQcm9wOiBmdW5jdGlvbiggbmFtZSwgaG9vayApIHtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoIGpRdWVyeS5FdmVudC5wcm90b3R5cGUsIG5hbWUsIHtcblx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cblx0XHRcdGdldDogaXNGdW5jdGlvbiggaG9vayApID9cblx0XHRcdFx0ZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKCB0aGlzLm9yaWdpbmFsRXZlbnQgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gaG9vayggdGhpcy5vcmlnaW5hbEV2ZW50ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IDpcblx0XHRcdFx0ZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKCB0aGlzLm9yaWdpbmFsRXZlbnQgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdGhpcy5vcmlnaW5hbEV2ZW50WyBuYW1lIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LFxuXG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCB0aGlzLCBuYW1lLCB7XG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0XHRcdFx0d3JpdGFibGU6IHRydWUsXG5cdFx0XHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0XHRcdH0gKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0Zml4OiBmdW5jdGlvbiggb3JpZ2luYWxFdmVudCApIHtcblx0XHRyZXR1cm4gb3JpZ2luYWxFdmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/XG5cdFx0XHRvcmlnaW5hbEV2ZW50IDpcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoIG9yaWdpbmFsRXZlbnQgKTtcblx0fSxcblxuXHRzcGVjaWFsOiB7XG5cdFx0bG9hZDoge1xuXG5cdFx0XHQvLyBQcmV2ZW50IHRyaWdnZXJlZCBpbWFnZS5sb2FkIGV2ZW50cyBmcm9tIGJ1YmJsaW5nIHRvIHdpbmRvdy5sb2FkXG5cdFx0XHRub0J1YmJsZTogdHJ1ZVxuXHRcdH0sXG5cdFx0Y2xpY2s6IHtcblxuXHRcdFx0Ly8gVXRpbGl6ZSBuYXRpdmUgZXZlbnQgdG8gZW5zdXJlIGNvcnJlY3Qgc3RhdGUgZm9yIGNoZWNrYWJsZSBpbnB1dHNcblx0XHRcdHNldHVwOiBmdW5jdGlvbiggZGF0YSApIHtcblxuXHRcdFx0XHQvLyBGb3IgbXV0dWFsIGNvbXByZXNzaWJpbGl0eSB3aXRoIF9kZWZhdWx0LCByZXBsYWNlIGB0aGlzYCBhY2Nlc3Mgd2l0aCBhIGxvY2FsIHZhci5cblx0XHRcdFx0Ly8gYHx8IGRhdGFgIGlzIGRlYWQgY29kZSBtZWFudCBvbmx5IHRvIHByZXNlcnZlIHRoZSB2YXJpYWJsZSB0aHJvdWdoIG1pbmlmaWNhdGlvbi5cblx0XHRcdFx0dmFyIGVsID0gdGhpcyB8fCBkYXRhO1xuXG5cdFx0XHRcdC8vIENsYWltIHRoZSBmaXJzdCBoYW5kbGVyXG5cdFx0XHRcdGlmICggcmNoZWNrYWJsZVR5cGUudGVzdCggZWwudHlwZSApICYmXG5cdFx0XHRcdFx0ZWwuY2xpY2sgJiYgbm9kZU5hbWUoIGVsLCBcImlucHV0XCIgKSApIHtcblxuXHRcdFx0XHRcdC8vIGRhdGFQcml2LnNldCggZWwsIFwiY2xpY2tcIiwgLi4uIClcblx0XHRcdFx0XHRsZXZlcmFnZU5hdGl2ZSggZWwsIFwiY2xpY2tcIiwgcmV0dXJuVHJ1ZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmV0dXJuIGZhbHNlIHRvIGFsbG93IG5vcm1hbCBwcm9jZXNzaW5nIGluIHRoZSBjYWxsZXJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fSxcblx0XHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCBkYXRhICkge1xuXG5cdFx0XHRcdC8vIEZvciBtdXR1YWwgY29tcHJlc3NpYmlsaXR5IHdpdGggX2RlZmF1bHQsIHJlcGxhY2UgYHRoaXNgIGFjY2VzcyB3aXRoIGEgbG9jYWwgdmFyLlxuXHRcdFx0XHQvLyBgfHwgZGF0YWAgaXMgZGVhZCBjb2RlIG1lYW50IG9ubHkgdG8gcHJlc2VydmUgdGhlIHZhcmlhYmxlIHRocm91Z2ggbWluaWZpY2F0aW9uLlxuXHRcdFx0XHR2YXIgZWwgPSB0aGlzIHx8IGRhdGE7XG5cblx0XHRcdFx0Ly8gRm9yY2Ugc2V0dXAgYmVmb3JlIHRyaWdnZXJpbmcgYSBjbGlja1xuXHRcdFx0XHRpZiAoIHJjaGVja2FibGVUeXBlLnRlc3QoIGVsLnR5cGUgKSAmJlxuXHRcdFx0XHRcdGVsLmNsaWNrICYmIG5vZGVOYW1lKCBlbCwgXCJpbnB1dFwiICkgKSB7XG5cblx0XHRcdFx0XHRsZXZlcmFnZU5hdGl2ZSggZWwsIFwiY2xpY2tcIiApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmV0dXJuIG5vbi1mYWxzZSB0byBhbGxvdyBub3JtYWwgZXZlbnQtcGF0aCBwcm9wYWdhdGlvblxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH0sXG5cblx0XHRcdC8vIEZvciBjcm9zcy1icm93c2VyIGNvbnNpc3RlbmN5LCBzdXBwcmVzcyBuYXRpdmUgLmNsaWNrKCkgb24gbGlua3Ncblx0XHRcdC8vIEFsc28gcHJldmVudCBpdCBpZiB3ZSdyZSBjdXJyZW50bHkgaW5zaWRlIGEgbGV2ZXJhZ2VkIG5hdGl2ZS1ldmVudCBzdGFja1xuXHRcdFx0X2RlZmF1bHQ6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldDtcblx0XHRcdFx0cmV0dXJuIHJjaGVja2FibGVUeXBlLnRlc3QoIHRhcmdldC50eXBlICkgJiZcblx0XHRcdFx0XHR0YXJnZXQuY2xpY2sgJiYgbm9kZU5hbWUoIHRhcmdldCwgXCJpbnB1dFwiICkgJiZcblx0XHRcdFx0XHRkYXRhUHJpdi5nZXQoIHRhcmdldCwgXCJjbGlja1wiICkgfHxcblx0XHRcdFx0XHRub2RlTmFtZSggdGFyZ2V0LCBcImFcIiApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRiZWZvcmV1bmxvYWQ6IHtcblx0XHRcdHBvc3REaXNwYXRjaDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggMjArXG5cdFx0XHRcdC8vIEZpcmVmb3ggZG9lc24ndCBhbGVydCBpZiB0aGUgcmV0dXJuVmFsdWUgZmllbGQgaXMgbm90IHNldC5cblx0XHRcdFx0aWYgKCBldmVudC5yZXN1bHQgIT09IHVuZGVmaW5lZCAmJiBldmVudC5vcmlnaW5hbEV2ZW50ICkge1xuXHRcdFx0XHRcdGV2ZW50Lm9yaWdpbmFsRXZlbnQucmV0dXJuVmFsdWUgPSBldmVudC5yZXN1bHQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbi8vIEVuc3VyZSB0aGUgcHJlc2VuY2Ugb2YgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBoYW5kbGVzIG1hbnVhbGx5LXRyaWdnZXJlZFxuLy8gc3ludGhldGljIGV2ZW50cyBieSBpbnRlcnJ1cHRpbmcgcHJvZ3Jlc3MgdW50aWwgcmVpbnZva2VkIGluIHJlc3BvbnNlIHRvXG4vLyAqbmF0aXZlKiBldmVudHMgdGhhdCBpdCBmaXJlcyBkaXJlY3RseSwgZW5zdXJpbmcgdGhhdCBzdGF0ZSBjaGFuZ2VzIGhhdmVcbi8vIGFscmVhZHkgb2NjdXJyZWQgYmVmb3JlIG90aGVyIGxpc3RlbmVycyBhcmUgaW52b2tlZC5cbmZ1bmN0aW9uIGxldmVyYWdlTmF0aXZlKCBlbCwgdHlwZSwgZXhwZWN0U3luYyApIHtcblxuXHQvLyBNaXNzaW5nIGV4cGVjdFN5bmMgaW5kaWNhdGVzIGEgdHJpZ2dlciBjYWxsLCB3aGljaCBtdXN0IGZvcmNlIHNldHVwIHRocm91Z2ggalF1ZXJ5LmV2ZW50LmFkZFxuXHRpZiAoICFleHBlY3RTeW5jICkge1xuXHRcdGlmICggZGF0YVByaXYuZ2V0KCBlbCwgdHlwZSApID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQuYWRkKCBlbCwgdHlwZSwgcmV0dXJuVHJ1ZSApO1xuXHRcdH1cblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyBSZWdpc3RlciB0aGUgY29udHJvbGxlciBhcyBhIHNwZWNpYWwgdW5pdmVyc2FsIGhhbmRsZXIgZm9yIGFsbCBldmVudCBuYW1lc3BhY2VzXG5cdGRhdGFQcml2LnNldCggZWwsIHR5cGUsIGZhbHNlICk7XG5cdGpRdWVyeS5ldmVudC5hZGQoIGVsLCB0eXBlLCB7XG5cdFx0bmFtZXNwYWNlOiBmYWxzZSxcblx0XHRoYW5kbGVyOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHR2YXIgbm90QXN5bmMsIHJlc3VsdCxcblx0XHRcdFx0c2F2ZWQgPSBkYXRhUHJpdi5nZXQoIHRoaXMsIHR5cGUgKTtcblxuXHRcdFx0aWYgKCAoIGV2ZW50LmlzVHJpZ2dlciAmIDEgKSAmJiB0aGlzWyB0eXBlIF0gKSB7XG5cblx0XHRcdFx0Ly8gSW50ZXJydXB0IHByb2Nlc3Npbmcgb2YgdGhlIG91dGVyIHN5bnRoZXRpYyAudHJpZ2dlcigpZWQgZXZlbnRcblx0XHRcdFx0Ly8gU2F2ZWQgZGF0YSBzaG91bGQgYmUgZmFsc2UgaW4gc3VjaCBjYXNlcywgYnV0IG1pZ2h0IGJlIGEgbGVmdG92ZXIgY2FwdHVyZSBvYmplY3Rcblx0XHRcdFx0Ly8gZnJvbSBhbiBhc3luYyBuYXRpdmUgaGFuZGxlciAoZ2gtNDM1MClcblx0XHRcdFx0aWYgKCAhc2F2ZWQubGVuZ3RoICkge1xuXG5cdFx0XHRcdFx0Ly8gU3RvcmUgYXJndW1lbnRzIGZvciB1c2Ugd2hlbiBoYW5kbGluZyB0aGUgaW5uZXIgbmF0aXZlIGV2ZW50XG5cdFx0XHRcdFx0Ly8gVGhlcmUgd2lsbCBhbHdheXMgYmUgYXQgbGVhc3Qgb25lIGFyZ3VtZW50IChhbiBldmVudCBvYmplY3QpLCBzbyB0aGlzIGFycmF5XG5cdFx0XHRcdFx0Ly8gd2lsbCBub3QgYmUgY29uZnVzZWQgd2l0aCBhIGxlZnRvdmVyIGNhcHR1cmUgb2JqZWN0LlxuXHRcdFx0XHRcdHNhdmVkID0gc2xpY2UuY2FsbCggYXJndW1lbnRzICk7XG5cdFx0XHRcdFx0ZGF0YVByaXYuc2V0KCB0aGlzLCB0eXBlLCBzYXZlZCApO1xuXG5cdFx0XHRcdFx0Ly8gVHJpZ2dlciB0aGUgbmF0aXZlIGV2ZW50IGFuZCBjYXB0dXJlIGl0cyByZXN1bHRcblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMStcblx0XHRcdFx0XHQvLyBmb2N1cygpIGFuZCBibHVyKCkgYXJlIGFzeW5jaHJvbm91c1xuXHRcdFx0XHRcdG5vdEFzeW5jID0gZXhwZWN0U3luYyggdGhpcywgdHlwZSApO1xuXHRcdFx0XHRcdHRoaXNbIHR5cGUgXSgpO1xuXHRcdFx0XHRcdHJlc3VsdCA9IGRhdGFQcml2LmdldCggdGhpcywgdHlwZSApO1xuXHRcdFx0XHRcdGlmICggc2F2ZWQgIT09IHJlc3VsdCB8fCBub3RBc3luYyApIHtcblx0XHRcdFx0XHRcdGRhdGFQcml2LnNldCggdGhpcywgdHlwZSwgZmFsc2UgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmVzdWx0ID0ge307XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggc2F2ZWQgIT09IHJlc3VsdCApIHtcblxuXHRcdFx0XHRcdFx0Ly8gQ2FuY2VsIHRoZSBvdXRlciBzeW50aGV0aWMgZXZlbnRcblx0XHRcdFx0XHRcdGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuXHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogQ2hyb21lIDg2K1xuXHRcdFx0XHRcdFx0Ly8gSW4gQ2hyb21lLCBpZiBhbiBlbGVtZW50IGhhdmluZyBhIGZvY3Vzb3V0IGhhbmRsZXIgaXMgYmx1cnJlZCBieVxuXHRcdFx0XHRcdFx0Ly8gY2xpY2tpbmcgb3V0c2lkZSBvZiBpdCwgaXQgaW52b2tlcyB0aGUgaGFuZGxlciBzeW5jaHJvbm91c2x5LiBJZlxuXHRcdFx0XHRcdFx0Ly8gdGhhdCBoYW5kbGVyIGNhbGxzIGAucmVtb3ZlKClgIG9uIHRoZSBlbGVtZW50LCB0aGUgZGF0YSBpcyBjbGVhcmVkLFxuXHRcdFx0XHRcdFx0Ly8gbGVhdmluZyBgcmVzdWx0YCB1bmRlZmluZWQuIFdlIG5lZWQgdG8gZ3VhcmQgYWdhaW5zdCB0aGlzLlxuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdCAmJiByZXN1bHQudmFsdWU7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIElmIHRoaXMgaXMgYW4gaW5uZXIgc3ludGhldGljIGV2ZW50IGZvciBhbiBldmVudCB3aXRoIGEgYnViYmxpbmcgc3Vycm9nYXRlXG5cdFx0XHRcdC8vIChmb2N1cyBvciBibHVyKSwgYXNzdW1lIHRoYXQgdGhlIHN1cnJvZ2F0ZSBhbHJlYWR5IHByb3BhZ2F0ZWQgZnJvbSB0cmlnZ2VyaW5nIHRoZVxuXHRcdFx0XHQvLyBuYXRpdmUgZXZlbnQgYW5kIHByZXZlbnQgdGhhdCBmcm9tIGhhcHBlbmluZyBhZ2FpbiBoZXJlLlxuXHRcdFx0XHQvLyBUaGlzIHRlY2huaWNhbGx5IGdldHMgdGhlIG9yZGVyaW5nIHdyb25nIHcuci50LiB0byBgLnRyaWdnZXIoKWAgKGluIHdoaWNoIHRoZVxuXHRcdFx0XHQvLyBidWJibGluZyBzdXJyb2dhdGUgcHJvcGFnYXRlcyAqYWZ0ZXIqIHRoZSBub24tYnViYmxpbmcgYmFzZSksIGJ1dCB0aGF0IHNlZW1zXG5cdFx0XHRcdC8vIGxlc3MgYmFkIHRoYW4gZHVwbGljYXRpb24uXG5cdFx0XHRcdH0gZWxzZSBpZiAoICggalF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fSApLmRlbGVnYXRlVHlwZSApIHtcblx0XHRcdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGEgbmF0aXZlIGV2ZW50IHRyaWdnZXJlZCBhYm92ZSwgZXZlcnl0aGluZyBpcyBub3cgaW4gb3JkZXJcblx0XHRcdC8vIEZpcmUgYW4gaW5uZXIgc3ludGhldGljIGV2ZW50IHdpdGggdGhlIG9yaWdpbmFsIGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggc2F2ZWQubGVuZ3RoICkge1xuXG5cdFx0XHRcdC8vIC4uLmFuZCBjYXB0dXJlIHRoZSByZXN1bHRcblx0XHRcdFx0ZGF0YVByaXYuc2V0KCB0aGlzLCB0eXBlLCB7XG5cdFx0XHRcdFx0dmFsdWU6IGpRdWVyeS5ldmVudC50cmlnZ2VyKFxuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMStcblx0XHRcdFx0XHRcdC8vIEV4dGVuZCB3aXRoIHRoZSBwcm90b3R5cGUgdG8gcmVzZXQgdGhlIGFib3ZlIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpXG5cdFx0XHRcdFx0XHRqUXVlcnkuZXh0ZW5kKCBzYXZlZFsgMCBdLCBqUXVlcnkuRXZlbnQucHJvdG90eXBlICksXG5cdFx0XHRcdFx0XHRzYXZlZC5zbGljZSggMSApLFxuXHRcdFx0XHRcdFx0dGhpc1xuXHRcdFx0XHRcdClcblx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdC8vIEFib3J0IGhhbmRsaW5nIG9mIHRoZSBuYXRpdmUgZXZlbnRcblx0XHRcdFx0ZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59XG5cbmpRdWVyeS5yZW1vdmVFdmVudCA9IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBoYW5kbGUgKSB7XG5cblx0Ly8gVGhpcyBcImlmXCIgaXMgbmVlZGVkIGZvciBwbGFpbiBvYmplY3RzXG5cdGlmICggZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyICkge1xuXHRcdGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciggdHlwZSwgaGFuZGxlICk7XG5cdH1cbn07XG5cbmpRdWVyeS5FdmVudCA9IGZ1bmN0aW9uKCBzcmMsIHByb3BzICkge1xuXG5cdC8vIEFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCB0aGUgJ25ldycga2V5d29yZFxuXHRpZiAoICEoIHRoaXMgaW5zdGFuY2VvZiBqUXVlcnkuRXZlbnQgKSApIHtcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5FdmVudCggc3JjLCBwcm9wcyApO1xuXHR9XG5cblx0Ly8gRXZlbnQgb2JqZWN0XG5cdGlmICggc3JjICYmIHNyYy50eXBlICkge1xuXHRcdHRoaXMub3JpZ2luYWxFdmVudCA9IHNyYztcblx0XHR0aGlzLnR5cGUgPSBzcmMudHlwZTtcblxuXHRcdC8vIEV2ZW50cyBidWJibGluZyB1cCB0aGUgZG9jdW1lbnQgbWF5IGhhdmUgYmVlbiBtYXJrZWQgYXMgcHJldmVudGVkXG5cdFx0Ly8gYnkgYSBoYW5kbGVyIGxvd2VyIGRvd24gdGhlIHRyZWU7IHJlZmxlY3QgdGhlIGNvcnJlY3QgdmFsdWUuXG5cdFx0dGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQgPSBzcmMuZGVmYXVsdFByZXZlbnRlZCB8fFxuXHRcdFx0XHRzcmMuZGVmYXVsdFByZXZlbnRlZCA9PT0gdW5kZWZpbmVkICYmXG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTIuMyBvbmx5XG5cdFx0XHRcdHNyYy5yZXR1cm5WYWx1ZSA9PT0gZmFsc2UgP1xuXHRcdFx0cmV0dXJuVHJ1ZSA6XG5cdFx0XHRyZXR1cm5GYWxzZTtcblxuXHRcdC8vIENyZWF0ZSB0YXJnZXQgcHJvcGVydGllc1xuXHRcdC8vIFN1cHBvcnQ6IFNhZmFyaSA8PTYgLSA3IG9ubHlcblx0XHQvLyBUYXJnZXQgc2hvdWxkIG5vdCBiZSBhIHRleHQgbm9kZSAoIzUwNCwgIzEzMTQzKVxuXHRcdHRoaXMudGFyZ2V0ID0gKCBzcmMudGFyZ2V0ICYmIHNyYy50YXJnZXQubm9kZVR5cGUgPT09IDMgKSA/XG5cdFx0XHRzcmMudGFyZ2V0LnBhcmVudE5vZGUgOlxuXHRcdFx0c3JjLnRhcmdldDtcblxuXHRcdHRoaXMuY3VycmVudFRhcmdldCA9IHNyYy5jdXJyZW50VGFyZ2V0O1xuXHRcdHRoaXMucmVsYXRlZFRhcmdldCA9IHNyYy5yZWxhdGVkVGFyZ2V0O1xuXG5cdC8vIEV2ZW50IHR5cGVcblx0fSBlbHNlIHtcblx0XHR0aGlzLnR5cGUgPSBzcmM7XG5cdH1cblxuXHQvLyBQdXQgZXhwbGljaXRseSBwcm92aWRlZCBwcm9wZXJ0aWVzIG9udG8gdGhlIGV2ZW50IG9iamVjdFxuXHRpZiAoIHByb3BzICkge1xuXHRcdGpRdWVyeS5leHRlbmQoIHRoaXMsIHByb3BzICk7XG5cdH1cblxuXHQvLyBDcmVhdGUgYSB0aW1lc3RhbXAgaWYgaW5jb21pbmcgZXZlbnQgZG9lc24ndCBoYXZlIG9uZVxuXHR0aGlzLnRpbWVTdGFtcCA9IHNyYyAmJiBzcmMudGltZVN0YW1wIHx8IERhdGUubm93KCk7XG5cblx0Ly8gTWFyayBpdCBhcyBmaXhlZFxuXHR0aGlzWyBqUXVlcnkuZXhwYW5kbyBdID0gdHJ1ZTtcbn07XG5cbi8vIGpRdWVyeS5FdmVudCBpcyBiYXNlZCBvbiBET00zIEV2ZW50cyBhcyBzcGVjaWZpZWQgYnkgdGhlIEVDTUFTY3JpcHQgTGFuZ3VhZ2UgQmluZGluZ1xuLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMDMvV0QtRE9NLUxldmVsLTMtRXZlbnRzLTIwMDMwMzMxL2VjbWEtc2NyaXB0LWJpbmRpbmcuaHRtbFxualF1ZXJ5LkV2ZW50LnByb3RvdHlwZSA9IHtcblx0Y29uc3RydWN0b3I6IGpRdWVyeS5FdmVudCxcblx0aXNEZWZhdWx0UHJldmVudGVkOiByZXR1cm5GYWxzZSxcblx0aXNQcm9wYWdhdGlvblN0b3BwZWQ6IHJldHVybkZhbHNlLFxuXHRpc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZDogcmV0dXJuRmFsc2UsXG5cdGlzU2ltdWxhdGVkOiBmYWxzZSxcblxuXHRwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9LFxuXHRzdG9wUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XG5cdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdH1cblx0fSxcblx0c3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgZSA9IHRoaXMub3JpZ2luYWxFdmVudDtcblxuXHRcdHRoaXMuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSByZXR1cm5UcnVlO1xuXG5cdFx0aWYgKCBlICYmICF0aGlzLmlzU2ltdWxhdGVkICkge1xuXHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcblx0XHR9XG5cblx0XHR0aGlzLnN0b3BQcm9wYWdhdGlvbigpO1xuXHR9XG59O1xuXG4vLyBJbmNsdWRlcyBhbGwgY29tbW9uIGV2ZW50IHByb3BzIGluY2x1ZGluZyBLZXlFdmVudCBhbmQgTW91c2VFdmVudCBzcGVjaWZpYyBwcm9wc1xualF1ZXJ5LmVhY2goIHtcblx0YWx0S2V5OiB0cnVlLFxuXHRidWJibGVzOiB0cnVlLFxuXHRjYW5jZWxhYmxlOiB0cnVlLFxuXHRjaGFuZ2VkVG91Y2hlczogdHJ1ZSxcblx0Y3RybEtleTogdHJ1ZSxcblx0ZGV0YWlsOiB0cnVlLFxuXHRldmVudFBoYXNlOiB0cnVlLFxuXHRtZXRhS2V5OiB0cnVlLFxuXHRwYWdlWDogdHJ1ZSxcblx0cGFnZVk6IHRydWUsXG5cdHNoaWZ0S2V5OiB0cnVlLFxuXHR2aWV3OiB0cnVlLFxuXHRcImNoYXJcIjogdHJ1ZSxcblx0Y29kZTogdHJ1ZSxcblx0Y2hhckNvZGU6IHRydWUsXG5cdGtleTogdHJ1ZSxcblx0a2V5Q29kZTogdHJ1ZSxcblx0YnV0dG9uOiB0cnVlLFxuXHRidXR0b25zOiB0cnVlLFxuXHRjbGllbnRYOiB0cnVlLFxuXHRjbGllbnRZOiB0cnVlLFxuXHRvZmZzZXRYOiB0cnVlLFxuXHRvZmZzZXRZOiB0cnVlLFxuXHRwb2ludGVySWQ6IHRydWUsXG5cdHBvaW50ZXJUeXBlOiB0cnVlLFxuXHRzY3JlZW5YOiB0cnVlLFxuXHRzY3JlZW5ZOiB0cnVlLFxuXHR0YXJnZXRUb3VjaGVzOiB0cnVlLFxuXHR0b0VsZW1lbnQ6IHRydWUsXG5cdHRvdWNoZXM6IHRydWUsXG5cdHdoaWNoOiB0cnVlXG59LCBqUXVlcnkuZXZlbnQuYWRkUHJvcCApO1xuXG5qUXVlcnkuZWFjaCggeyBmb2N1czogXCJmb2N1c2luXCIsIGJsdXI6IFwiZm9jdXNvdXRcIiB9LCBmdW5jdGlvbiggdHlwZSwgZGVsZWdhdGVUeXBlICkge1xuXHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdID0ge1xuXG5cdFx0Ly8gVXRpbGl6ZSBuYXRpdmUgZXZlbnQgaWYgcG9zc2libGUgc28gYmx1ci9mb2N1cyBzZXF1ZW5jZSBpcyBjb3JyZWN0XG5cdFx0c2V0dXA6IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBDbGFpbSB0aGUgZmlyc3QgaGFuZGxlclxuXHRcdFx0Ly8gZGF0YVByaXYuc2V0KCB0aGlzLCBcImZvY3VzXCIsIC4uLiApXG5cdFx0XHQvLyBkYXRhUHJpdi5zZXQoIHRoaXMsIFwiYmx1clwiLCAuLi4gKVxuXHRcdFx0bGV2ZXJhZ2VOYXRpdmUoIHRoaXMsIHR5cGUsIGV4cGVjdFN5bmMgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIGZhbHNlIHRvIGFsbG93IG5vcm1hbCBwcm9jZXNzaW5nIGluIHRoZSBjYWxsZXJcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBGb3JjZSBzZXR1cCBiZWZvcmUgdHJpZ2dlclxuXHRcdFx0bGV2ZXJhZ2VOYXRpdmUoIHRoaXMsIHR5cGUgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIG5vbi1mYWxzZSB0byBhbGxvdyBub3JtYWwgZXZlbnQtcGF0aCBwcm9wYWdhdGlvblxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblxuXHRcdC8vIFN1cHByZXNzIG5hdGl2ZSBmb2N1cyBvciBibHVyIGFzIGl0J3MgYWxyZWFkeSBiZWluZyBmaXJlZFxuXHRcdC8vIGluIGxldmVyYWdlTmF0aXZlLlxuXHRcdF9kZWZhdWx0OiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0sXG5cblx0XHRkZWxlZ2F0ZVR5cGU6IGRlbGVnYXRlVHlwZVxuXHR9O1xufSApO1xuXG4vLyBDcmVhdGUgbW91c2VlbnRlci9sZWF2ZSBldmVudHMgdXNpbmcgbW91c2VvdmVyL291dCBhbmQgZXZlbnQtdGltZSBjaGVja3Ncbi8vIHNvIHRoYXQgZXZlbnQgZGVsZWdhdGlvbiB3b3JrcyBpbiBqUXVlcnkuXG4vLyBEbyB0aGUgc2FtZSBmb3IgcG9pbnRlcmVudGVyL3BvaW50ZXJsZWF2ZSBhbmQgcG9pbnRlcm92ZXIvcG9pbnRlcm91dFxuLy9cbi8vIFN1cHBvcnQ6IFNhZmFyaSA3IG9ubHlcbi8vIFNhZmFyaSBzZW5kcyBtb3VzZWVudGVyIHRvbyBvZnRlbjsgc2VlOlxuLy8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NDcwMjU4XG4vLyBmb3IgdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBidWcgKGl0IGV4aXN0ZWQgaW4gb2xkZXIgQ2hyb21lIHZlcnNpb25zIGFzIHdlbGwpLlxualF1ZXJ5LmVhY2goIHtcblx0bW91c2VlbnRlcjogXCJtb3VzZW92ZXJcIixcblx0bW91c2VsZWF2ZTogXCJtb3VzZW91dFwiLFxuXHRwb2ludGVyZW50ZXI6IFwicG9pbnRlcm92ZXJcIixcblx0cG9pbnRlcmxlYXZlOiBcInBvaW50ZXJvdXRcIlxufSwgZnVuY3Rpb24oIG9yaWcsIGZpeCApIHtcblx0alF1ZXJ5LmV2ZW50LnNwZWNpYWxbIG9yaWcgXSA9IHtcblx0XHRkZWxlZ2F0ZVR5cGU6IGZpeCxcblx0XHRiaW5kVHlwZTogZml4LFxuXG5cdFx0aGFuZGxlOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHR2YXIgcmV0LFxuXHRcdFx0XHR0YXJnZXQgPSB0aGlzLFxuXHRcdFx0XHRyZWxhdGVkID0gZXZlbnQucmVsYXRlZFRhcmdldCxcblx0XHRcdFx0aGFuZGxlT2JqID0gZXZlbnQuaGFuZGxlT2JqO1xuXG5cdFx0XHQvLyBGb3IgbW91c2VlbnRlci9sZWF2ZSBjYWxsIHRoZSBoYW5kbGVyIGlmIHJlbGF0ZWQgaXMgb3V0c2lkZSB0aGUgdGFyZ2V0LlxuXHRcdFx0Ly8gTkI6IE5vIHJlbGF0ZWRUYXJnZXQgaWYgdGhlIG1vdXNlIGxlZnQvZW50ZXJlZCB0aGUgYnJvd3NlciB3aW5kb3dcblx0XHRcdGlmICggIXJlbGF0ZWQgfHwgKCByZWxhdGVkICE9PSB0YXJnZXQgJiYgIWpRdWVyeS5jb250YWlucyggdGFyZ2V0LCByZWxhdGVkICkgKSApIHtcblx0XHRcdFx0ZXZlbnQudHlwZSA9IGhhbmRsZU9iai5vcmlnVHlwZTtcblx0XHRcdFx0cmV0ID0gaGFuZGxlT2JqLmhhbmRsZXIuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRldmVudC50eXBlID0gZml4O1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9XG5cdH07XG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblxuXHRvbjogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIG9uKCB0aGlzLCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuICk7XG5cdH0sXG5cdG9uZTogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIG9uKCB0aGlzLCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuLCAxICk7XG5cdH0sXG5cdG9mZjogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZm4gKSB7XG5cdFx0dmFyIGhhbmRsZU9iaiwgdHlwZTtcblx0XHRpZiAoIHR5cGVzICYmIHR5cGVzLnByZXZlbnREZWZhdWx0ICYmIHR5cGVzLmhhbmRsZU9iaiApIHtcblxuXHRcdFx0Ly8gKCBldmVudCApICBkaXNwYXRjaGVkIGpRdWVyeS5FdmVudFxuXHRcdFx0aGFuZGxlT2JqID0gdHlwZXMuaGFuZGxlT2JqO1xuXHRcdFx0alF1ZXJ5KCB0eXBlcy5kZWxlZ2F0ZVRhcmdldCApLm9mZihcblx0XHRcdFx0aGFuZGxlT2JqLm5hbWVzcGFjZSA/XG5cdFx0XHRcdFx0aGFuZGxlT2JqLm9yaWdUeXBlICsgXCIuXCIgKyBoYW5kbGVPYmoubmFtZXNwYWNlIDpcblx0XHRcdFx0XHRoYW5kbGVPYmoub3JpZ1R5cGUsXG5cdFx0XHRcdGhhbmRsZU9iai5zZWxlY3Rvcixcblx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXJcblx0XHRcdCk7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cdFx0aWYgKCB0eXBlb2YgdHlwZXMgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHRcdC8vICggdHlwZXMtb2JqZWN0IFssIHNlbGVjdG9yXSApXG5cdFx0XHRmb3IgKCB0eXBlIGluIHR5cGVzICkge1xuXHRcdFx0XHR0aGlzLm9mZiggdHlwZSwgc2VsZWN0b3IsIHR5cGVzWyB0eXBlIF0gKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblx0XHRpZiAoIHNlbGVjdG9yID09PSBmYWxzZSB8fCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwiZnVuY3Rpb25cIiApIHtcblxuXHRcdFx0Ly8gKCB0eXBlcyBbLCBmbl0gKVxuXHRcdFx0Zm4gPSBzZWxlY3Rvcjtcblx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRpZiAoIGZuID09PSBmYWxzZSApIHtcblx0XHRcdGZuID0gcmV0dXJuRmFsc2U7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggdGhpcywgdHlwZXMsIGZuLCBzZWxlY3RvciApO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5cbnZhclxuXG5cdC8vIFN1cHBvcnQ6IElFIDw9MTAgLSAxMSwgRWRnZSAxMiAtIDEzIG9ubHlcblx0Ly8gSW4gSUUvRWRnZSB1c2luZyByZWdleCBncm91cHMgaGVyZSBjYXVzZXMgc2V2ZXJlIHNsb3dkb3ducy5cblx0Ly8gU2VlIGh0dHBzOi8vY29ubmVjdC5taWNyb3NvZnQuY29tL0lFL2ZlZWRiYWNrL2RldGFpbHMvMTczNjUxMi9cblx0cm5vSW5uZXJodG1sID0gLzxzY3JpcHR8PHN0eWxlfDxsaW5rL2ksXG5cblx0Ly8gY2hlY2tlZD1cImNoZWNrZWRcIiBvciBjaGVja2VkXG5cdHJjaGVja2VkID0gL2NoZWNrZWRcXHMqKD86W149XXw9XFxzKi5jaGVja2VkLikvaSxcblx0cmNsZWFuU2NyaXB0ID0gL15cXHMqPCEoPzpcXFtDREFUQVxcW3wtLSl8KD86XFxdXFxdfC0tKT5cXHMqJC9nO1xuXG4vLyBQcmVmZXIgYSB0Ym9keSBvdmVyIGl0cyBwYXJlbnQgdGFibGUgZm9yIGNvbnRhaW5pbmcgbmV3IHJvd3NcbmZ1bmN0aW9uIG1hbmlwdWxhdGlvblRhcmdldCggZWxlbSwgY29udGVudCApIHtcblx0aWYgKCBub2RlTmFtZSggZWxlbSwgXCJ0YWJsZVwiICkgJiZcblx0XHRub2RlTmFtZSggY29udGVudC5ub2RlVHlwZSAhPT0gMTEgPyBjb250ZW50IDogY29udGVudC5maXJzdENoaWxkLCBcInRyXCIgKSApIHtcblxuXHRcdHJldHVybiBqUXVlcnkoIGVsZW0gKS5jaGlsZHJlbiggXCJ0Ym9keVwiIClbIDAgXSB8fCBlbGVtO1xuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbi8vIFJlcGxhY2UvcmVzdG9yZSB0aGUgdHlwZSBhdHRyaWJ1dGUgb2Ygc2NyaXB0IGVsZW1lbnRzIGZvciBzYWZlIERPTSBtYW5pcHVsYXRpb25cbmZ1bmN0aW9uIGRpc2FibGVTY3JpcHQoIGVsZW0gKSB7XG5cdGVsZW0udHlwZSA9ICggZWxlbS5nZXRBdHRyaWJ1dGUoIFwidHlwZVwiICkgIT09IG51bGwgKSArIFwiL1wiICsgZWxlbS50eXBlO1xuXHRyZXR1cm4gZWxlbTtcbn1cbmZ1bmN0aW9uIHJlc3RvcmVTY3JpcHQoIGVsZW0gKSB7XG5cdGlmICggKCBlbGVtLnR5cGUgfHwgXCJcIiApLnNsaWNlKCAwLCA1ICkgPT09IFwidHJ1ZS9cIiApIHtcblx0XHRlbGVtLnR5cGUgPSBlbGVtLnR5cGUuc2xpY2UoIDUgKTtcblx0fSBlbHNlIHtcblx0XHRlbGVtLnJlbW92ZUF0dHJpYnV0ZSggXCJ0eXBlXCIgKTtcblx0fVxuXG5cdHJldHVybiBlbGVtO1xufVxuXG5mdW5jdGlvbiBjbG9uZUNvcHlFdmVudCggc3JjLCBkZXN0ICkge1xuXHR2YXIgaSwgbCwgdHlwZSwgcGRhdGFPbGQsIHVkYXRhT2xkLCB1ZGF0YUN1ciwgZXZlbnRzO1xuXG5cdGlmICggZGVzdC5ub2RlVHlwZSAhPT0gMSApIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyAxLiBDb3B5IHByaXZhdGUgZGF0YTogZXZlbnRzLCBoYW5kbGVycywgZXRjLlxuXHRpZiAoIGRhdGFQcml2Lmhhc0RhdGEoIHNyYyApICkge1xuXHRcdHBkYXRhT2xkID0gZGF0YVByaXYuZ2V0KCBzcmMgKTtcblx0XHRldmVudHMgPSBwZGF0YU9sZC5ldmVudHM7XG5cblx0XHRpZiAoIGV2ZW50cyApIHtcblx0XHRcdGRhdGFQcml2LnJlbW92ZSggZGVzdCwgXCJoYW5kbGUgZXZlbnRzXCIgKTtcblxuXHRcdFx0Zm9yICggdHlwZSBpbiBldmVudHMgKSB7XG5cdFx0XHRcdGZvciAoIGkgPSAwLCBsID0gZXZlbnRzWyB0eXBlIF0ubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5hZGQoIGRlc3QsIHR5cGUsIGV2ZW50c1sgdHlwZSBdWyBpIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIDIuIENvcHkgdXNlciBkYXRhXG5cdGlmICggZGF0YVVzZXIuaGFzRGF0YSggc3JjICkgKSB7XG5cdFx0dWRhdGFPbGQgPSBkYXRhVXNlci5hY2Nlc3MoIHNyYyApO1xuXHRcdHVkYXRhQ3VyID0galF1ZXJ5LmV4dGVuZCgge30sIHVkYXRhT2xkICk7XG5cblx0XHRkYXRhVXNlci5zZXQoIGRlc3QsIHVkYXRhQ3VyICk7XG5cdH1cbn1cblxuLy8gRml4IElFIGJ1Z3MsIHNlZSBzdXBwb3J0IHRlc3RzXG5mdW5jdGlvbiBmaXhJbnB1dCggc3JjLCBkZXN0ICkge1xuXHR2YXIgbm9kZU5hbWUgPSBkZXN0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cblx0Ly8gRmFpbHMgdG8gcGVyc2lzdCB0aGUgY2hlY2tlZCBzdGF0ZSBvZiBhIGNsb25lZCBjaGVja2JveCBvciByYWRpbyBidXR0b24uXG5cdGlmICggbm9kZU5hbWUgPT09IFwiaW5wdXRcIiAmJiByY2hlY2thYmxlVHlwZS50ZXN0KCBzcmMudHlwZSApICkge1xuXHRcdGRlc3QuY2hlY2tlZCA9IHNyYy5jaGVja2VkO1xuXG5cdC8vIEZhaWxzIHRvIHJldHVybiB0aGUgc2VsZWN0ZWQgb3B0aW9uIHRvIHRoZSBkZWZhdWx0IHNlbGVjdGVkIHN0YXRlIHdoZW4gY2xvbmluZyBvcHRpb25zXG5cdH0gZWxzZSBpZiAoIG5vZGVOYW1lID09PSBcImlucHV0XCIgfHwgbm9kZU5hbWUgPT09IFwidGV4dGFyZWFcIiApIHtcblx0XHRkZXN0LmRlZmF1bHRWYWx1ZSA9IHNyYy5kZWZhdWx0VmFsdWU7XG5cdH1cbn1cblxuZnVuY3Rpb24gZG9tTWFuaXAoIGNvbGxlY3Rpb24sIGFyZ3MsIGNhbGxiYWNrLCBpZ25vcmVkICkge1xuXG5cdC8vIEZsYXR0ZW4gYW55IG5lc3RlZCBhcnJheXNcblx0YXJncyA9IGZsYXQoIGFyZ3MgKTtcblxuXHR2YXIgZnJhZ21lbnQsIGZpcnN0LCBzY3JpcHRzLCBoYXNTY3JpcHRzLCBub2RlLCBkb2MsXG5cdFx0aSA9IDAsXG5cdFx0bCA9IGNvbGxlY3Rpb24ubGVuZ3RoLFxuXHRcdGlOb0Nsb25lID0gbCAtIDEsXG5cdFx0dmFsdWUgPSBhcmdzWyAwIF0sXG5cdFx0dmFsdWVJc0Z1bmN0aW9uID0gaXNGdW5jdGlvbiggdmFsdWUgKTtcblxuXHQvLyBXZSBjYW4ndCBjbG9uZU5vZGUgZnJhZ21lbnRzIHRoYXQgY29udGFpbiBjaGVja2VkLCBpbiBXZWJLaXRcblx0aWYgKCB2YWx1ZUlzRnVuY3Rpb24gfHxcblx0XHRcdCggbCA+IDEgJiYgdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmXG5cdFx0XHRcdCFzdXBwb3J0LmNoZWNrQ2xvbmUgJiYgcmNoZWNrZWQudGVzdCggdmFsdWUgKSApICkge1xuXHRcdHJldHVybiBjb2xsZWN0aW9uLmVhY2goIGZ1bmN0aW9uKCBpbmRleCApIHtcblx0XHRcdHZhciBzZWxmID0gY29sbGVjdGlvbi5lcSggaW5kZXggKTtcblx0XHRcdGlmICggdmFsdWVJc0Z1bmN0aW9uICkge1xuXHRcdFx0XHRhcmdzWyAwIF0gPSB2YWx1ZS5jYWxsKCB0aGlzLCBpbmRleCwgc2VsZi5odG1sKCkgKTtcblx0XHRcdH1cblx0XHRcdGRvbU1hbmlwKCBzZWxmLCBhcmdzLCBjYWxsYmFjaywgaWdub3JlZCApO1xuXHRcdH0gKTtcblx0fVxuXG5cdGlmICggbCApIHtcblx0XHRmcmFnbWVudCA9IGJ1aWxkRnJhZ21lbnQoIGFyZ3MsIGNvbGxlY3Rpb25bIDAgXS5vd25lckRvY3VtZW50LCBmYWxzZSwgY29sbGVjdGlvbiwgaWdub3JlZCApO1xuXHRcdGZpcnN0ID0gZnJhZ21lbnQuZmlyc3RDaGlsZDtcblxuXHRcdGlmICggZnJhZ21lbnQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDEgKSB7XG5cdFx0XHRmcmFnbWVudCA9IGZpcnN0O1xuXHRcdH1cblxuXHRcdC8vIFJlcXVpcmUgZWl0aGVyIG5ldyBjb250ZW50IG9yIGFuIGludGVyZXN0IGluIGlnbm9yZWQgZWxlbWVudHMgdG8gaW52b2tlIHRoZSBjYWxsYmFja1xuXHRcdGlmICggZmlyc3QgfHwgaWdub3JlZCApIHtcblx0XHRcdHNjcmlwdHMgPSBqUXVlcnkubWFwKCBnZXRBbGwoIGZyYWdtZW50LCBcInNjcmlwdFwiICksIGRpc2FibGVTY3JpcHQgKTtcblx0XHRcdGhhc1NjcmlwdHMgPSBzY3JpcHRzLmxlbmd0aDtcblxuXHRcdFx0Ly8gVXNlIHRoZSBvcmlnaW5hbCBmcmFnbWVudCBmb3IgdGhlIGxhc3QgaXRlbVxuXHRcdFx0Ly8gaW5zdGVhZCBvZiB0aGUgZmlyc3QgYmVjYXVzZSBpdCBjYW4gZW5kIHVwXG5cdFx0XHQvLyBiZWluZyBlbXB0aWVkIGluY29ycmVjdGx5IGluIGNlcnRhaW4gc2l0dWF0aW9ucyAoIzgwNzApLlxuXHRcdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRub2RlID0gZnJhZ21lbnQ7XG5cblx0XHRcdFx0aWYgKCBpICE9PSBpTm9DbG9uZSApIHtcblx0XHRcdFx0XHRub2RlID0galF1ZXJ5LmNsb25lKCBub2RlLCB0cnVlLCB0cnVlICk7XG5cblx0XHRcdFx0XHQvLyBLZWVwIHJlZmVyZW5jZXMgdG8gY2xvbmVkIHNjcmlwdHMgZm9yIGxhdGVyIHJlc3RvcmF0aW9uXG5cdFx0XHRcdFx0aWYgKCBoYXNTY3JpcHRzICkge1xuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHlcblx0XHRcdFx0XHRcdC8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXRcblx0XHRcdFx0XHRcdGpRdWVyeS5tZXJnZSggc2NyaXB0cywgZ2V0QWxsKCBub2RlLCBcInNjcmlwdFwiICkgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRjYWxsYmFjay5jYWxsKCBjb2xsZWN0aW9uWyBpIF0sIG5vZGUsIGkgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBoYXNTY3JpcHRzICkge1xuXHRcdFx0XHRkb2MgPSBzY3JpcHRzWyBzY3JpcHRzLmxlbmd0aCAtIDEgXS5vd25lckRvY3VtZW50O1xuXG5cdFx0XHRcdC8vIFJlZW5hYmxlIHNjcmlwdHNcblx0XHRcdFx0alF1ZXJ5Lm1hcCggc2NyaXB0cywgcmVzdG9yZVNjcmlwdCApO1xuXG5cdFx0XHRcdC8vIEV2YWx1YXRlIGV4ZWN1dGFibGUgc2NyaXB0cyBvbiBmaXJzdCBkb2N1bWVudCBpbnNlcnRpb25cblx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBoYXNTY3JpcHRzOyBpKysgKSB7XG5cdFx0XHRcdFx0bm9kZSA9IHNjcmlwdHNbIGkgXTtcblx0XHRcdFx0XHRpZiAoIHJzY3JpcHRUeXBlLnRlc3QoIG5vZGUudHlwZSB8fCBcIlwiICkgJiZcblx0XHRcdFx0XHRcdCFkYXRhUHJpdi5hY2Nlc3MoIG5vZGUsIFwiZ2xvYmFsRXZhbFwiICkgJiZcblx0XHRcdFx0XHRcdGpRdWVyeS5jb250YWlucyggZG9jLCBub2RlICkgKSB7XG5cblx0XHRcdFx0XHRcdGlmICggbm9kZS5zcmMgJiYgKCBub2RlLnR5cGUgfHwgXCJcIiApLnRvTG93ZXJDYXNlKCkgICE9PSBcIm1vZHVsZVwiICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIE9wdGlvbmFsIEFKQVggZGVwZW5kZW5jeSwgYnV0IHdvbid0IHJ1biBzY3JpcHRzIGlmIG5vdCBwcmVzZW50XG5cdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5Ll9ldmFsVXJsICYmICFub2RlLm5vTW9kdWxlICkge1xuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5fZXZhbFVybCggbm9kZS5zcmMsIHtcblx0XHRcdFx0XHRcdFx0XHRcdG5vbmNlOiBub2RlLm5vbmNlIHx8IG5vZGUuZ2V0QXR0cmlidXRlKCBcIm5vbmNlXCIgKVxuXHRcdFx0XHRcdFx0XHRcdH0sIGRvYyApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRET01FdmFsKCBub2RlLnRleHRDb250ZW50LnJlcGxhY2UoIHJjbGVhblNjcmlwdCwgXCJcIiApLCBub2RlLCBkb2MgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gY29sbGVjdGlvbjtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlKCBlbGVtLCBzZWxlY3Rvciwga2VlcERhdGEgKSB7XG5cdHZhciBub2RlLFxuXHRcdG5vZGVzID0gc2VsZWN0b3IgPyBqUXVlcnkuZmlsdGVyKCBzZWxlY3RvciwgZWxlbSApIDogZWxlbSxcblx0XHRpID0gMDtcblxuXHRmb3IgKCA7ICggbm9kZSA9IG5vZGVzWyBpIF0gKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0aWYgKCAha2VlcERhdGEgJiYgbm9kZS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggbm9kZSApICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBub2RlLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRpZiAoIGtlZXBEYXRhICYmIGlzQXR0YWNoZWQoIG5vZGUgKSApIHtcblx0XHRcdFx0c2V0R2xvYmFsRXZhbCggZ2V0QWxsKCBub2RlLCBcInNjcmlwdFwiICkgKTtcblx0XHRcdH1cblx0XHRcdG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggbm9kZSApO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtO1xufVxuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdGh0bWxQcmVmaWx0ZXI6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHJldHVybiBodG1sO1xuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiggZWxlbSwgZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKSB7XG5cdFx0dmFyIGksIGwsIHNyY0VsZW1lbnRzLCBkZXN0RWxlbWVudHMsXG5cdFx0XHRjbG9uZSA9IGVsZW0uY2xvbmVOb2RlKCB0cnVlICksXG5cdFx0XHRpblBhZ2UgPSBpc0F0dGFjaGVkKCBlbGVtICk7XG5cblx0XHQvLyBGaXggSUUgY2xvbmluZyBpc3N1ZXNcblx0XHRpZiAoICFzdXBwb3J0Lm5vQ2xvbmVDaGVja2VkICYmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBlbGVtLm5vZGVUeXBlID09PSAxMSApICYmXG5cdFx0XHRcdCFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKSApIHtcblxuXHRcdFx0Ly8gV2UgZXNjaGV3IFNpenpsZSBoZXJlIGZvciBwZXJmb3JtYW5jZSByZWFzb25zOiBodHRwczovL2pzcGVyZi5jb20vZ2V0YWxsLXZzLXNpenpsZS8yXG5cdFx0XHRkZXN0RWxlbWVudHMgPSBnZXRBbGwoIGNsb25lICk7XG5cdFx0XHRzcmNFbGVtZW50cyA9IGdldEFsbCggZWxlbSApO1xuXG5cdFx0XHRmb3IgKCBpID0gMCwgbCA9IHNyY0VsZW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0Zml4SW5wdXQoIHNyY0VsZW1lbnRzWyBpIF0sIGRlc3RFbGVtZW50c1sgaSBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ29weSB0aGUgZXZlbnRzIGZyb20gdGhlIG9yaWdpbmFsIHRvIHRoZSBjbG9uZVxuXHRcdGlmICggZGF0YUFuZEV2ZW50cyApIHtcblx0XHRcdGlmICggZGVlcERhdGFBbmRFdmVudHMgKSB7XG5cdFx0XHRcdHNyY0VsZW1lbnRzID0gc3JjRWxlbWVudHMgfHwgZ2V0QWxsKCBlbGVtICk7XG5cdFx0XHRcdGRlc3RFbGVtZW50cyA9IGRlc3RFbGVtZW50cyB8fCBnZXRBbGwoIGNsb25lICk7XG5cblx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSBzcmNFbGVtZW50cy5sZW5ndGg7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0Y2xvbmVDb3B5RXZlbnQoIHNyY0VsZW1lbnRzWyBpIF0sIGRlc3RFbGVtZW50c1sgaSBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNsb25lQ29weUV2ZW50KCBlbGVtLCBjbG9uZSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFByZXNlcnZlIHNjcmlwdCBldmFsdWF0aW9uIGhpc3Rvcnlcblx0XHRkZXN0RWxlbWVudHMgPSBnZXRBbGwoIGNsb25lLCBcInNjcmlwdFwiICk7XG5cdFx0aWYgKCBkZXN0RWxlbWVudHMubGVuZ3RoID4gMCApIHtcblx0XHRcdHNldEdsb2JhbEV2YWwoIGRlc3RFbGVtZW50cywgIWluUGFnZSAmJiBnZXRBbGwoIGVsZW0sIFwic2NyaXB0XCIgKSApO1xuXHRcdH1cblxuXHRcdC8vIFJldHVybiB0aGUgY2xvbmVkIHNldFxuXHRcdHJldHVybiBjbG9uZTtcblx0fSxcblxuXHRjbGVhbkRhdGE6IGZ1bmN0aW9uKCBlbGVtcyApIHtcblx0XHR2YXIgZGF0YSwgZWxlbSwgdHlwZSxcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbCxcblx0XHRcdGkgPSAwO1xuXG5cdFx0Zm9yICggOyAoIGVsZW0gPSBlbGVtc1sgaSBdICkgIT09IHVuZGVmaW5lZDsgaSsrICkge1xuXHRcdFx0aWYgKCBhY2NlcHREYXRhKCBlbGVtICkgKSB7XG5cdFx0XHRcdGlmICggKCBkYXRhID0gZWxlbVsgZGF0YVByaXYuZXhwYW5kbyBdICkgKSB7XG5cdFx0XHRcdFx0aWYgKCBkYXRhLmV2ZW50cyApIHtcblx0XHRcdFx0XHRcdGZvciAoIHR5cGUgaW4gZGF0YS5ldmVudHMgKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggc3BlY2lhbFsgdHlwZSBdICkge1xuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIGVsZW0sIHR5cGUgKTtcblxuXHRcdFx0XHRcdFx0XHQvLyBUaGlzIGlzIGEgc2hvcnRjdXQgdG8gYXZvaWQgalF1ZXJ5LmV2ZW50LnJlbW92ZSdzIG92ZXJoZWFkXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LnJlbW92ZUV2ZW50KCBlbGVtLCB0eXBlLCBkYXRhLmhhbmRsZSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogQ2hyb21lIDw9MzUgLSA0NStcblx0XHRcdFx0XHQvLyBBc3NpZ24gdW5kZWZpbmVkIGluc3RlYWQgb2YgdXNpbmcgZGVsZXRlLCBzZWUgRGF0YSNyZW1vdmVcblx0XHRcdFx0XHRlbGVtWyBkYXRhUHJpdi5leHBhbmRvIF0gPSB1bmRlZmluZWQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCBlbGVtWyBkYXRhVXNlci5leHBhbmRvIF0gKSB7XG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD0zNSAtIDQ1K1xuXHRcdFx0XHRcdC8vIEFzc2lnbiB1bmRlZmluZWQgaW5zdGVhZCBvZiB1c2luZyBkZWxldGUsIHNlZSBEYXRhI3JlbW92ZVxuXHRcdFx0XHRcdGVsZW1bIGRhdGFVc2VyLmV4cGFuZG8gXSA9IHVuZGVmaW5lZDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxufSApO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGRldGFjaDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiByZW1vdmUoIHRoaXMsIHNlbGVjdG9yLCB0cnVlICk7XG5cdH0sXG5cblx0cmVtb3ZlOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHJlbW92ZSggdGhpcywgc2VsZWN0b3IgKTtcblx0fSxcblxuXHR0ZXh0OiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0cmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRqUXVlcnkudGV4dCggdGhpcyApIDpcblx0XHRcdFx0dGhpcy5lbXB0eSgpLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHRcdFx0dGhpcy50ZXh0Q29udGVudCA9IHZhbHVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSApO1xuXHRcdH0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoICk7XG5cdH0sXG5cblx0YXBwZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IG1hbmlwdWxhdGlvblRhcmdldCggdGhpcywgZWxlbSApO1xuXHRcdFx0XHR0YXJnZXQuYXBwZW5kQ2hpbGQoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0cHJlcGVuZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGRvbU1hbmlwKCB0aGlzLCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdHZhciB0YXJnZXQgPSBtYW5pcHVsYXRpb25UYXJnZXQoIHRoaXMsIGVsZW0gKTtcblx0XHRcdFx0dGFyZ2V0Lmluc2VydEJlZm9yZSggZWxlbSwgdGFyZ2V0LmZpcnN0Q2hpbGQgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0YmVmb3JlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0dGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSggZWxlbSwgdGhpcyApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRhZnRlcjogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGRvbU1hbmlwKCB0aGlzLCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0aWYgKCB0aGlzLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdHRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoIGVsZW0sIHRoaXMubmV4dFNpYmxpbmcgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0ZW1wdHk6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlbGVtLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7ICggZWxlbSA9IHRoaXNbIGkgXSApICE9IG51bGw7IGkrKyApIHtcblx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblxuXHRcdFx0XHQvLyBQcmV2ZW50IG1lbW9yeSBsZWFrc1xuXHRcdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIGVsZW0sIGZhbHNlICkgKTtcblxuXHRcdFx0XHQvLyBSZW1vdmUgYW55IHJlbWFpbmluZyBub2Rlc1xuXHRcdFx0XHRlbGVtLnRleHRDb250ZW50ID0gXCJcIjtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24oIGRhdGFBbmRFdmVudHMsIGRlZXBEYXRhQW5kRXZlbnRzICkge1xuXHRcdGRhdGFBbmRFdmVudHMgPSBkYXRhQW5kRXZlbnRzID09IG51bGwgPyBmYWxzZSA6IGRhdGFBbmRFdmVudHM7XG5cdFx0ZGVlcERhdGFBbmRFdmVudHMgPSBkZWVwRGF0YUFuZEV2ZW50cyA9PSBudWxsID8gZGF0YUFuZEV2ZW50cyA6IGRlZXBEYXRhQW5kRXZlbnRzO1xuXG5cdFx0cmV0dXJuIHRoaXMubWFwKCBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBqUXVlcnkuY2xvbmUoIHRoaXMsIGRhdGFBbmRFdmVudHMsIGRlZXBEYXRhQW5kRXZlbnRzICk7XG5cdFx0fSApO1xuXHR9LFxuXG5cdGh0bWw6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHR2YXIgZWxlbSA9IHRoaXNbIDAgXSB8fCB7fSxcblx0XHRcdFx0aSA9IDAsXG5cdFx0XHRcdGwgPSB0aGlzLmxlbmd0aDtcblxuXHRcdFx0aWYgKCB2YWx1ZSA9PT0gdW5kZWZpbmVkICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRcdHJldHVybiBlbGVtLmlubmVySFRNTDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2VlIGlmIHdlIGNhbiB0YWtlIGEgc2hvcnRjdXQgYW5kIGp1c3QgdXNlIGlubmVySFRNTFxuXHRcdFx0aWYgKCB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgIXJub0lubmVyaHRtbC50ZXN0KCB2YWx1ZSApICYmXG5cdFx0XHRcdCF3cmFwTWFwWyAoIHJ0YWdOYW1lLmV4ZWMoIHZhbHVlICkgfHwgWyBcIlwiLCBcIlwiIF0gKVsgMSBdLnRvTG93ZXJDYXNlKCkgXSApIHtcblxuXHRcdFx0XHR2YWx1ZSA9IGpRdWVyeS5odG1sUHJlZmlsdGVyKCB2YWx1ZSApO1xuXG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRcdFx0ZWxlbSA9IHRoaXNbIGkgXSB8fCB7fTtcblxuXHRcdFx0XHRcdFx0Ly8gUmVtb3ZlIGVsZW1lbnQgbm9kZXMgYW5kIHByZXZlbnQgbWVtb3J5IGxlYWtzXG5cdFx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRcdFx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggZWxlbSwgZmFsc2UgKSApO1xuXHRcdFx0XHRcdFx0XHRlbGVtLmlubmVySFRNTCA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGVsZW0gPSAwO1xuXG5cdFx0XHRcdC8vIElmIHVzaW5nIGlubmVySFRNTCB0aHJvd3MgYW4gZXhjZXB0aW9uLCB1c2UgdGhlIGZhbGxiYWNrIG1ldGhvZFxuXHRcdFx0XHR9IGNhdGNoICggZSApIHt9XG5cdFx0XHR9XG5cblx0XHRcdGlmICggZWxlbSApIHtcblx0XHRcdFx0dGhpcy5lbXB0eSgpLmFwcGVuZCggdmFsdWUgKTtcblx0XHRcdH1cblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApO1xuXHR9LFxuXG5cdHJlcGxhY2VXaXRoOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgaWdub3JlZCA9IFtdO1xuXG5cdFx0Ly8gTWFrZSB0aGUgY2hhbmdlcywgcmVwbGFjaW5nIGVhY2ggbm9uLWlnbm9yZWQgY29udGV4dCBlbGVtZW50IHdpdGggdGhlIG5ldyBjb250ZW50XG5cdFx0cmV0dXJuIGRvbU1hbmlwKCB0aGlzLCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIHBhcmVudCA9IHRoaXMucGFyZW50Tm9kZTtcblxuXHRcdFx0aWYgKCBqUXVlcnkuaW5BcnJheSggdGhpcywgaWdub3JlZCApIDwgMCApIHtcblx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCB0aGlzICkgKTtcblx0XHRcdFx0aWYgKCBwYXJlbnQgKSB7XG5cdFx0XHRcdFx0cGFyZW50LnJlcGxhY2VDaGlsZCggZWxlbSwgdGhpcyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHQvLyBGb3JjZSBjYWxsYmFjayBpbnZvY2F0aW9uXG5cdFx0fSwgaWdub3JlZCApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5lYWNoKCB7XG5cdGFwcGVuZFRvOiBcImFwcGVuZFwiLFxuXHRwcmVwZW5kVG86IFwicHJlcGVuZFwiLFxuXHRpbnNlcnRCZWZvcmU6IFwiYmVmb3JlXCIsXG5cdGluc2VydEFmdGVyOiBcImFmdGVyXCIsXG5cdHJlcGxhY2VBbGw6IFwicmVwbGFjZVdpdGhcIlxufSwgZnVuY3Rpb24oIG5hbWUsIG9yaWdpbmFsICkge1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHR2YXIgZWxlbXMsXG5cdFx0XHRyZXQgPSBbXSxcblx0XHRcdGluc2VydCA9IGpRdWVyeSggc2VsZWN0b3IgKSxcblx0XHRcdGxhc3QgPSBpbnNlcnQubGVuZ3RoIC0gMSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0Zm9yICggOyBpIDw9IGxhc3Q7IGkrKyApIHtcblx0XHRcdGVsZW1zID0gaSA9PT0gbGFzdCA/IHRoaXMgOiB0aGlzLmNsb25lKCB0cnVlICk7XG5cdFx0XHRqUXVlcnkoIGluc2VydFsgaSBdIClbIG9yaWdpbmFsIF0oIGVsZW1zICk7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seSwgUGhhbnRvbUpTIDEgb25seVxuXHRcdFx0Ly8gLmdldCgpIGJlY2F1c2UgcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRcdFx0cHVzaC5hcHBseSggcmV0LCBlbGVtcy5nZXQoKSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggcmV0ICk7XG5cdH07XG59ICk7XG52YXIgcm51bW5vbnB4ID0gbmV3IFJlZ0V4cCggXCJeKFwiICsgcG51bSArIFwiKSg/IXB4KVthLXolXSskXCIsIFwiaVwiICk7XG5cbnZhciBnZXRTdHlsZXMgPSBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDw9MTEgb25seSwgRmlyZWZveCA8PTMwICgjMTUwOTgsICMxNDE1MClcblx0XHQvLyBJRSB0aHJvd3Mgb24gZWxlbWVudHMgY3JlYXRlZCBpbiBwb3B1cHNcblx0XHQvLyBGRiBtZWFud2hpbGUgdGhyb3dzIG9uIGZyYW1lIGVsZW1lbnRzIHRocm91Z2ggXCJkZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlXCJcblx0XHR2YXIgdmlldyA9IGVsZW0ub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldztcblxuXHRcdGlmICggIXZpZXcgfHwgIXZpZXcub3BlbmVyICkge1xuXHRcdFx0dmlldyA9IHdpbmRvdztcblx0XHR9XG5cblx0XHRyZXR1cm4gdmlldy5nZXRDb21wdXRlZFN0eWxlKCBlbGVtICk7XG5cdH07XG5cbnZhciBzd2FwID0gZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIGNhbGxiYWNrICkge1xuXHR2YXIgcmV0LCBuYW1lLFxuXHRcdG9sZCA9IHt9O1xuXG5cdC8vIFJlbWVtYmVyIHRoZSBvbGQgdmFsdWVzLCBhbmQgaW5zZXJ0IHRoZSBuZXcgb25lc1xuXHRmb3IgKCBuYW1lIGluIG9wdGlvbnMgKSB7XG5cdFx0b2xkWyBuYW1lIF0gPSBlbGVtLnN0eWxlWyBuYW1lIF07XG5cdFx0ZWxlbS5zdHlsZVsgbmFtZSBdID0gb3B0aW9uc1sgbmFtZSBdO1xuXHR9XG5cblx0cmV0ID0gY2FsbGJhY2suY2FsbCggZWxlbSApO1xuXG5cdC8vIFJldmVydCB0aGUgb2xkIHZhbHVlc1xuXHRmb3IgKCBuYW1lIGluIG9wdGlvbnMgKSB7XG5cdFx0ZWxlbS5zdHlsZVsgbmFtZSBdID0gb2xkWyBuYW1lIF07XG5cdH1cblxuXHRyZXR1cm4gcmV0O1xufTtcblxuXG52YXIgcmJveFN0eWxlID0gbmV3IFJlZ0V4cCggY3NzRXhwYW5kLmpvaW4oIFwifFwiICksIFwiaVwiICk7XG5cblxuXG4oIGZ1bmN0aW9uKCkge1xuXG5cdC8vIEV4ZWN1dGluZyBib3RoIHBpeGVsUG9zaXRpb24gJiBib3hTaXppbmdSZWxpYWJsZSB0ZXN0cyByZXF1aXJlIG9ubHkgb25lIGxheW91dFxuXHQvLyBzbyB0aGV5J3JlIGV4ZWN1dGVkIGF0IHRoZSBzYW1lIHRpbWUgdG8gc2F2ZSB0aGUgc2Vjb25kIGNvbXB1dGF0aW9uLlxuXHRmdW5jdGlvbiBjb21wdXRlU3R5bGVUZXN0cygpIHtcblxuXHRcdC8vIFRoaXMgaXMgYSBzaW5nbGV0b24sIHdlIG5lZWQgdG8gZXhlY3V0ZSBpdCBvbmx5IG9uY2Vcblx0XHRpZiAoICFkaXYgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29udGFpbmVyLnN0eWxlLmNzc1RleHQgPSBcInBvc2l0aW9uOmFic29sdXRlO2xlZnQ6LTExMTExcHg7d2lkdGg6NjBweDtcIiArXG5cdFx0XHRcIm1hcmdpbi10b3A6MXB4O3BhZGRpbmc6MDtib3JkZXI6MFwiO1xuXHRcdGRpdi5zdHlsZS5jc3NUZXh0ID1cblx0XHRcdFwicG9zaXRpb246cmVsYXRpdmU7ZGlzcGxheTpibG9jaztib3gtc2l6aW5nOmJvcmRlci1ib3g7b3ZlcmZsb3c6c2Nyb2xsO1wiICtcblx0XHRcdFwibWFyZ2luOmF1dG87Ym9yZGVyOjFweDtwYWRkaW5nOjFweDtcIiArXG5cdFx0XHRcIndpZHRoOjYwJTt0b3A6MSVcIjtcblx0XHRkb2N1bWVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoIGNvbnRhaW5lciApLmFwcGVuZENoaWxkKCBkaXYgKTtcblxuXHRcdHZhciBkaXZTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKCBkaXYgKTtcblx0XHRwaXhlbFBvc2l0aW9uVmFsID0gZGl2U3R5bGUudG9wICE9PSBcIjElXCI7XG5cblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5LCBGaXJlZm94IDw9MyAtIDQ0XG5cdFx0cmVsaWFibGVNYXJnaW5MZWZ0VmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXZTdHlsZS5tYXJnaW5MZWZ0ICkgPT09IDEyO1xuXG5cdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA0LjAgLSA0LjMgb25seSwgU2FmYXJpIDw9OS4xIC0gMTAuMSwgaU9TIDw9Ny4wIC0gOS4zXG5cdFx0Ly8gU29tZSBzdHlsZXMgY29tZSBiYWNrIHdpdGggcGVyY2VudGFnZSB2YWx1ZXMsIGV2ZW4gdGhvdWdoIHRoZXkgc2hvdWxkbid0XG5cdFx0ZGl2LnN0eWxlLnJpZ2h0ID0gXCI2MCVcIjtcblx0XHRwaXhlbEJveFN0eWxlc1ZhbCA9IHJvdW5kUGl4ZWxNZWFzdXJlcyggZGl2U3R5bGUucmlnaHQgKSA9PT0gMzY7XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTEgb25seVxuXHRcdC8vIERldGVjdCBtaXNyZXBvcnRpbmcgb2YgY29udGVudCBkaW1lbnNpb25zIGZvciBib3gtc2l6aW5nOmJvcmRlci1ib3ggZWxlbWVudHNcblx0XHRib3hTaXppbmdSZWxpYWJsZVZhbCA9IHJvdW5kUGl4ZWxNZWFzdXJlcyggZGl2U3R5bGUud2lkdGggKSA9PT0gMzY7XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA5IG9ubHlcblx0XHQvLyBEZXRlY3Qgb3ZlcmZsb3c6c2Nyb2xsIHNjcmV3aW5lc3MgKGdoLTM2OTkpXG5cdFx0Ly8gU3VwcG9ydDogQ2hyb21lIDw9NjRcblx0XHQvLyBEb24ndCBnZXQgdHJpY2tlZCB3aGVuIHpvb20gYWZmZWN0cyBvZmZzZXRXaWR0aCAoZ2gtNDAyOSlcblx0XHRkaXYuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG5cdFx0c2Nyb2xsYm94U2l6ZVZhbCA9IHJvdW5kUGl4ZWxNZWFzdXJlcyggZGl2Lm9mZnNldFdpZHRoIC8gMyApID09PSAxMjtcblxuXHRcdGRvY3VtZW50RWxlbWVudC5yZW1vdmVDaGlsZCggY29udGFpbmVyICk7XG5cblx0XHQvLyBOdWxsaWZ5IHRoZSBkaXYgc28gaXQgd291bGRuJ3QgYmUgc3RvcmVkIGluIHRoZSBtZW1vcnkgYW5kXG5cdFx0Ly8gaXQgd2lsbCBhbHNvIGJlIGEgc2lnbiB0aGF0IGNoZWNrcyBhbHJlYWR5IHBlcmZvcm1lZFxuXHRcdGRpdiA9IG51bGw7XG5cdH1cblxuXHRmdW5jdGlvbiByb3VuZFBpeGVsTWVhc3VyZXMoIG1lYXN1cmUgKSB7XG5cdFx0cmV0dXJuIE1hdGgucm91bmQoIHBhcnNlRmxvYXQoIG1lYXN1cmUgKSApO1xuXHR9XG5cblx0dmFyIHBpeGVsUG9zaXRpb25WYWwsIGJveFNpemluZ1JlbGlhYmxlVmFsLCBzY3JvbGxib3hTaXplVmFsLCBwaXhlbEJveFN0eWxlc1ZhbCxcblx0XHRyZWxpYWJsZVRyRGltZW5zaW9uc1ZhbCwgcmVsaWFibGVNYXJnaW5MZWZ0VmFsLFxuXHRcdGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSxcblx0XHRkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICk7XG5cblx0Ly8gRmluaXNoIGVhcmx5IGluIGxpbWl0ZWQgKG5vbi1icm93c2VyKSBlbnZpcm9ubWVudHNcblx0aWYgKCAhZGl2LnN0eWxlICkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIFN1cHBvcnQ6IElFIDw9OSAtIDExIG9ubHlcblx0Ly8gU3R5bGUgb2YgY2xvbmVkIGVsZW1lbnQgYWZmZWN0cyBzb3VyY2UgZWxlbWVudCBjbG9uZWQgKCM4OTA4KVxuXHRkaXYuc3R5bGUuYmFja2dyb3VuZENsaXAgPSBcImNvbnRlbnQtYm94XCI7XG5cdGRpdi5jbG9uZU5vZGUoIHRydWUgKS5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9IFwiXCI7XG5cdHN1cHBvcnQuY2xlYXJDbG9uZVN0eWxlID0gZGl2LnN0eWxlLmJhY2tncm91bmRDbGlwID09PSBcImNvbnRlbnQtYm94XCI7XG5cblx0alF1ZXJ5LmV4dGVuZCggc3VwcG9ydCwge1xuXHRcdGJveFNpemluZ1JlbGlhYmxlOiBmdW5jdGlvbigpIHtcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XG5cdFx0XHRyZXR1cm4gYm94U2l6aW5nUmVsaWFibGVWYWw7XG5cdFx0fSxcblx0XHRwaXhlbEJveFN0eWxlczogZnVuY3Rpb24oKSB7XG5cdFx0XHRjb21wdXRlU3R5bGVUZXN0cygpO1xuXHRcdFx0cmV0dXJuIHBpeGVsQm94U3R5bGVzVmFsO1xuXHRcdH0sXG5cdFx0cGl4ZWxQb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0XHRjb21wdXRlU3R5bGVUZXN0cygpO1xuXHRcdFx0cmV0dXJuIHBpeGVsUG9zaXRpb25WYWw7XG5cdFx0fSxcblx0XHRyZWxpYWJsZU1hcmdpbkxlZnQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdHJldHVybiByZWxpYWJsZU1hcmdpbkxlZnRWYWw7XG5cdFx0fSxcblx0XHRzY3JvbGxib3hTaXplOiBmdW5jdGlvbigpIHtcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XG5cdFx0XHRyZXR1cm4gc2Nyb2xsYm94U2l6ZVZhbDtcblx0XHR9LFxuXG5cdFx0Ly8gU3VwcG9ydDogSUUgOSAtIDExKywgRWRnZSAxNSAtIDE4K1xuXHRcdC8vIElFL0VkZ2UgbWlzcmVwb3J0IGBnZXRDb21wdXRlZFN0eWxlYCBvZiB0YWJsZSByb3dzIHdpdGggd2lkdGgvaGVpZ2h0XG5cdFx0Ly8gc2V0IGluIENTUyB3aGlsZSBgb2Zmc2V0KmAgcHJvcGVydGllcyByZXBvcnQgY29ycmVjdCB2YWx1ZXMuXG5cdFx0Ly8gQmVoYXZpb3IgaW4gSUUgOSBpcyBtb3JlIHN1YnRsZSB0aGFuIGluIG5ld2VyIHZlcnNpb25zICYgaXQgcGFzc2VzXG5cdFx0Ly8gc29tZSB2ZXJzaW9ucyBvZiB0aGlzIHRlc3Q7IG1ha2Ugc3VyZSBub3QgdG8gbWFrZSBpdCBwYXNzIHRoZXJlIVxuXHRcdC8vXG5cdFx0Ly8gU3VwcG9ydDogRmlyZWZveCA3MCtcblx0XHQvLyBPbmx5IEZpcmVmb3ggaW5jbHVkZXMgYm9yZGVyIHdpZHRoc1xuXHRcdC8vIGluIGNvbXB1dGVkIGRpbWVuc2lvbnMuIChnaC00NTI5KVxuXHRcdHJlbGlhYmxlVHJEaW1lbnNpb25zOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciB0YWJsZSwgdHIsIHRyQ2hpbGQsIHRyU3R5bGU7XG5cdFx0XHRpZiAoIHJlbGlhYmxlVHJEaW1lbnNpb25zVmFsID09IG51bGwgKSB7XG5cdFx0XHRcdHRhYmxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJ0YWJsZVwiICk7XG5cdFx0XHRcdHRyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJ0clwiICk7XG5cdFx0XHRcdHRyQ2hpbGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICk7XG5cblx0XHRcdFx0dGFibGUuc3R5bGUuY3NzVGV4dCA9IFwicG9zaXRpb246YWJzb2x1dGU7bGVmdDotMTExMTFweDtib3JkZXItY29sbGFwc2U6c2VwYXJhdGVcIjtcblx0XHRcdFx0dHIuc3R5bGUuY3NzVGV4dCA9IFwiYm9yZGVyOjFweCBzb2xpZFwiO1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA4Nitcblx0XHRcdFx0Ly8gSGVpZ2h0IHNldCB0aHJvdWdoIGNzc1RleHQgZG9lcyBub3QgZ2V0IGFwcGxpZWQuXG5cdFx0XHRcdC8vIENvbXB1dGVkIGhlaWdodCB0aGVuIGNvbWVzIGJhY2sgYXMgMC5cblx0XHRcdFx0dHIuc3R5bGUuaGVpZ2h0ID0gXCIxcHhcIjtcblx0XHRcdFx0dHJDaGlsZC5zdHlsZS5oZWlnaHQgPSBcIjlweFwiO1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgOCBDaHJvbWUgODYrXG5cdFx0XHRcdC8vIEluIG91ciBib2R5QmFja2dyb3VuZC5odG1sIGlmcmFtZSxcblx0XHRcdFx0Ly8gZGlzcGxheSBmb3IgYWxsIGRpdiBlbGVtZW50cyBpcyBzZXQgdG8gXCJpbmxpbmVcIixcblx0XHRcdFx0Ly8gd2hpY2ggY2F1c2VzIGEgcHJvYmxlbSBvbmx5IGluIEFuZHJvaWQgOCBDaHJvbWUgODYuXG5cdFx0XHRcdC8vIEVuc3VyaW5nIHRoZSBkaXYgaXMgZGlzcGxheTogYmxvY2tcblx0XHRcdFx0Ly8gZ2V0cyBhcm91bmQgdGhpcyBpc3N1ZS5cblx0XHRcdFx0dHJDaGlsZC5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuXG5cdFx0XHRcdGRvY3VtZW50RWxlbWVudFxuXHRcdFx0XHRcdC5hcHBlbmRDaGlsZCggdGFibGUgKVxuXHRcdFx0XHRcdC5hcHBlbmRDaGlsZCggdHIgKVxuXHRcdFx0XHRcdC5hcHBlbmRDaGlsZCggdHJDaGlsZCApO1xuXG5cdFx0XHRcdHRyU3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSggdHIgKTtcblx0XHRcdFx0cmVsaWFibGVUckRpbWVuc2lvbnNWYWwgPSAoIHBhcnNlSW50KCB0clN0eWxlLmhlaWdodCwgMTAgKSArXG5cdFx0XHRcdFx0cGFyc2VJbnQoIHRyU3R5bGUuYm9yZGVyVG9wV2lkdGgsIDEwICkgK1xuXHRcdFx0XHRcdHBhcnNlSW50KCB0clN0eWxlLmJvcmRlckJvdHRvbVdpZHRoLCAxMCApICkgPT09IHRyLm9mZnNldEhlaWdodDtcblxuXHRcdFx0XHRkb2N1bWVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoIHRhYmxlICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVsaWFibGVUckRpbWVuc2lvbnNWYWw7XG5cdFx0fVxuXHR9ICk7XG59ICkoKTtcblxuXG5mdW5jdGlvbiBjdXJDU1MoIGVsZW0sIG5hbWUsIGNvbXB1dGVkICkge1xuXHR2YXIgd2lkdGgsIG1pbldpZHRoLCBtYXhXaWR0aCwgcmV0LFxuXG5cdFx0Ly8gU3VwcG9ydDogRmlyZWZveCA1MStcblx0XHQvLyBSZXRyaWV2aW5nIHN0eWxlIGJlZm9yZSBjb21wdXRlZCBzb21laG93XG5cdFx0Ly8gZml4ZXMgYW4gaXNzdWUgd2l0aCBnZXR0aW5nIHdyb25nIHZhbHVlc1xuXHRcdC8vIG9uIGRldGFjaGVkIGVsZW1lbnRzXG5cdFx0c3R5bGUgPSBlbGVtLnN0eWxlO1xuXG5cdGNvbXB1dGVkID0gY29tcHV0ZWQgfHwgZ2V0U3R5bGVzKCBlbGVtICk7XG5cblx0Ly8gZ2V0UHJvcGVydHlWYWx1ZSBpcyBuZWVkZWQgZm9yOlxuXHQvLyAgIC5jc3MoJ2ZpbHRlcicpIChJRSA5IG9ubHksICMxMjUzNylcblx0Ly8gICAuY3NzKCctLWN1c3RvbVByb3BlcnR5KSAoIzMxNDQpXG5cdGlmICggY29tcHV0ZWQgKSB7XG5cdFx0cmV0ID0gY29tcHV0ZWQuZ2V0UHJvcGVydHlWYWx1ZSggbmFtZSApIHx8IGNvbXB1dGVkWyBuYW1lIF07XG5cblx0XHRpZiAoIHJldCA9PT0gXCJcIiAmJiAhaXNBdHRhY2hlZCggZWxlbSApICkge1xuXHRcdFx0cmV0ID0galF1ZXJ5LnN0eWxlKCBlbGVtLCBuYW1lICk7XG5cdFx0fVxuXG5cdFx0Ly8gQSB0cmlidXRlIHRvIHRoZSBcImF3ZXNvbWUgaGFjayBieSBEZWFuIEVkd2FyZHNcIlxuXHRcdC8vIEFuZHJvaWQgQnJvd3NlciByZXR1cm5zIHBlcmNlbnRhZ2UgZm9yIHNvbWUgdmFsdWVzLFxuXHRcdC8vIGJ1dCB3aWR0aCBzZWVtcyB0byBiZSByZWxpYWJseSBwaXhlbHMuXG5cdFx0Ly8gVGhpcyBpcyBhZ2FpbnN0IHRoZSBDU1NPTSBkcmFmdCBzcGVjOlxuXHRcdC8vIGh0dHBzOi8vZHJhZnRzLmNzc3dnLm9yZy9jc3NvbS8jcmVzb2x2ZWQtdmFsdWVzXG5cdFx0aWYgKCAhc3VwcG9ydC5waXhlbEJveFN0eWxlcygpICYmIHJudW1ub25weC50ZXN0KCByZXQgKSAmJiByYm94U3R5bGUudGVzdCggbmFtZSApICkge1xuXG5cdFx0XHQvLyBSZW1lbWJlciB0aGUgb3JpZ2luYWwgdmFsdWVzXG5cdFx0XHR3aWR0aCA9IHN0eWxlLndpZHRoO1xuXHRcdFx0bWluV2lkdGggPSBzdHlsZS5taW5XaWR0aDtcblx0XHRcdG1heFdpZHRoID0gc3R5bGUubWF4V2lkdGg7XG5cblx0XHRcdC8vIFB1dCBpbiB0aGUgbmV3IHZhbHVlcyB0byBnZXQgYSBjb21wdXRlZCB2YWx1ZSBvdXRcblx0XHRcdHN0eWxlLm1pbldpZHRoID0gc3R5bGUubWF4V2lkdGggPSBzdHlsZS53aWR0aCA9IHJldDtcblx0XHRcdHJldCA9IGNvbXB1dGVkLndpZHRoO1xuXG5cdFx0XHQvLyBSZXZlcnQgdGhlIGNoYW5nZWQgdmFsdWVzXG5cdFx0XHRzdHlsZS53aWR0aCA9IHdpZHRoO1xuXHRcdFx0c3R5bGUubWluV2lkdGggPSBtaW5XaWR0aDtcblx0XHRcdHN0eWxlLm1heFdpZHRoID0gbWF4V2lkdGg7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHJldCAhPT0gdW5kZWZpbmVkID9cblxuXHRcdC8vIFN1cHBvcnQ6IElFIDw9OSAtIDExIG9ubHlcblx0XHQvLyBJRSByZXR1cm5zIHpJbmRleCB2YWx1ZSBhcyBhbiBpbnRlZ2VyLlxuXHRcdHJldCArIFwiXCIgOlxuXHRcdHJldDtcbn1cblxuXG5mdW5jdGlvbiBhZGRHZXRIb29rSWYoIGNvbmRpdGlvbkZuLCBob29rRm4gKSB7XG5cblx0Ly8gRGVmaW5lIHRoZSBob29rLCB3ZSdsbCBjaGVjayBvbiB0aGUgZmlyc3QgcnVuIGlmIGl0J3MgcmVhbGx5IG5lZWRlZC5cblx0cmV0dXJuIHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBjb25kaXRpb25GbigpICkge1xuXG5cdFx0XHRcdC8vIEhvb2sgbm90IG5lZWRlZCAob3IgaXQncyBub3QgcG9zc2libGUgdG8gdXNlIGl0IGR1ZVxuXHRcdFx0XHQvLyB0byBtaXNzaW5nIGRlcGVuZGVuY3kpLCByZW1vdmUgaXQuXG5cdFx0XHRcdGRlbGV0ZSB0aGlzLmdldDtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBIb29rIG5lZWRlZDsgcmVkZWZpbmUgaXQgc28gdGhhdCB0aGUgc3VwcG9ydCB0ZXN0IGlzIG5vdCBleGVjdXRlZCBhZ2Fpbi5cblx0XHRcdHJldHVybiAoIHRoaXMuZ2V0ID0gaG9va0ZuICkuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdH1cblx0fTtcbn1cblxuXG52YXIgY3NzUHJlZml4ZXMgPSBbIFwiV2Via2l0XCIsIFwiTW96XCIsIFwibXNcIiBdLFxuXHRlbXB0eVN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApLnN0eWxlLFxuXHR2ZW5kb3JQcm9wcyA9IHt9O1xuXG4vLyBSZXR1cm4gYSB2ZW5kb3ItcHJlZml4ZWQgcHJvcGVydHkgb3IgdW5kZWZpbmVkXG5mdW5jdGlvbiB2ZW5kb3JQcm9wTmFtZSggbmFtZSApIHtcblxuXHQvLyBDaGVjayBmb3IgdmVuZG9yIHByZWZpeGVkIG5hbWVzXG5cdHZhciBjYXBOYW1lID0gbmFtZVsgMCBdLnRvVXBwZXJDYXNlKCkgKyBuYW1lLnNsaWNlKCAxICksXG5cdFx0aSA9IGNzc1ByZWZpeGVzLmxlbmd0aDtcblxuXHR3aGlsZSAoIGktLSApIHtcblx0XHRuYW1lID0gY3NzUHJlZml4ZXNbIGkgXSArIGNhcE5hbWU7XG5cdFx0aWYgKCBuYW1lIGluIGVtcHR5U3R5bGUgKSB7XG5cdFx0XHRyZXR1cm4gbmFtZTtcblx0XHR9XG5cdH1cbn1cblxuLy8gUmV0dXJuIGEgcG90ZW50aWFsbHktbWFwcGVkIGpRdWVyeS5jc3NQcm9wcyBvciB2ZW5kb3IgcHJlZml4ZWQgcHJvcGVydHlcbmZ1bmN0aW9uIGZpbmFsUHJvcE5hbWUoIG5hbWUgKSB7XG5cdHZhciBmaW5hbCA9IGpRdWVyeS5jc3NQcm9wc1sgbmFtZSBdIHx8IHZlbmRvclByb3BzWyBuYW1lIF07XG5cblx0aWYgKCBmaW5hbCApIHtcblx0XHRyZXR1cm4gZmluYWw7XG5cdH1cblx0aWYgKCBuYW1lIGluIGVtcHR5U3R5bGUgKSB7XG5cdFx0cmV0dXJuIG5hbWU7XG5cdH1cblx0cmV0dXJuIHZlbmRvclByb3BzWyBuYW1lIF0gPSB2ZW5kb3JQcm9wTmFtZSggbmFtZSApIHx8IG5hbWU7XG59XG5cblxudmFyXG5cblx0Ly8gU3dhcHBhYmxlIGlmIGRpc3BsYXkgaXMgbm9uZSBvciBzdGFydHMgd2l0aCB0YWJsZVxuXHQvLyBleGNlcHQgXCJ0YWJsZVwiLCBcInRhYmxlLWNlbGxcIiwgb3IgXCJ0YWJsZS1jYXB0aW9uXCJcblx0Ly8gU2VlIGhlcmUgZm9yIGRpc3BsYXkgdmFsdWVzOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL0NTUy9kaXNwbGF5XG5cdHJkaXNwbGF5c3dhcCA9IC9eKG5vbmV8dGFibGUoPyEtY1tlYV0pLispLyxcblx0cmN1c3RvbVByb3AgPSAvXi0tLyxcblx0Y3NzU2hvdyA9IHsgcG9zaXRpb246IFwiYWJzb2x1dGVcIiwgdmlzaWJpbGl0eTogXCJoaWRkZW5cIiwgZGlzcGxheTogXCJibG9ja1wiIH0sXG5cdGNzc05vcm1hbFRyYW5zZm9ybSA9IHtcblx0XHRsZXR0ZXJTcGFjaW5nOiBcIjBcIixcblx0XHRmb250V2VpZ2h0OiBcIjQwMFwiXG5cdH07XG5cbmZ1bmN0aW9uIHNldFBvc2l0aXZlTnVtYmVyKCBfZWxlbSwgdmFsdWUsIHN1YnRyYWN0ICkge1xuXG5cdC8vIEFueSByZWxhdGl2ZSAoKy8tKSB2YWx1ZXMgaGF2ZSBhbHJlYWR5IGJlZW5cblx0Ly8gbm9ybWFsaXplZCBhdCB0aGlzIHBvaW50XG5cdHZhciBtYXRjaGVzID0gcmNzc051bS5leGVjKCB2YWx1ZSApO1xuXHRyZXR1cm4gbWF0Y2hlcyA/XG5cblx0XHQvLyBHdWFyZCBhZ2FpbnN0IHVuZGVmaW5lZCBcInN1YnRyYWN0XCIsIGUuZy4sIHdoZW4gdXNlZCBhcyBpbiBjc3NIb29rc1xuXHRcdE1hdGgubWF4KCAwLCBtYXRjaGVzWyAyIF0gLSAoIHN1YnRyYWN0IHx8IDAgKSApICsgKCBtYXRjaGVzWyAzIF0gfHwgXCJweFwiICkgOlxuXHRcdHZhbHVlO1xufVxuXG5mdW5jdGlvbiBib3hNb2RlbEFkanVzdG1lbnQoIGVsZW0sIGRpbWVuc2lvbiwgYm94LCBpc0JvcmRlckJveCwgc3R5bGVzLCBjb21wdXRlZFZhbCApIHtcblx0dmFyIGkgPSBkaW1lbnNpb24gPT09IFwid2lkdGhcIiA/IDEgOiAwLFxuXHRcdGV4dHJhID0gMCxcblx0XHRkZWx0YSA9IDA7XG5cblx0Ly8gQWRqdXN0bWVudCBtYXkgbm90IGJlIG5lY2Vzc2FyeVxuXHRpZiAoIGJveCA9PT0gKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApICkge1xuXHRcdHJldHVybiAwO1xuXHR9XG5cblx0Zm9yICggOyBpIDwgNDsgaSArPSAyICkge1xuXG5cdFx0Ly8gQm90aCBib3ggbW9kZWxzIGV4Y2x1ZGUgbWFyZ2luXG5cdFx0aWYgKCBib3ggPT09IFwibWFyZ2luXCIgKSB7XG5cdFx0XHRkZWx0YSArPSBqUXVlcnkuY3NzKCBlbGVtLCBib3ggKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgd2UgZ2V0IGhlcmUgd2l0aCBhIGNvbnRlbnQtYm94LCB3ZSdyZSBzZWVraW5nIFwicGFkZGluZ1wiIG9yIFwiYm9yZGVyXCIgb3IgXCJtYXJnaW5cIlxuXHRcdGlmICggIWlzQm9yZGVyQm94ICkge1xuXG5cdFx0XHQvLyBBZGQgcGFkZGluZ1xuXHRcdFx0ZGVsdGEgKz0galF1ZXJ5LmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XG5cblx0XHRcdC8vIEZvciBcImJvcmRlclwiIG9yIFwibWFyZ2luXCIsIGFkZCBib3JkZXJcblx0XHRcdGlmICggYm94ICE9PSBcInBhZGRpbmdcIiApIHtcblx0XHRcdFx0ZGVsdGEgKz0galF1ZXJ5LmNzcyggZWxlbSwgXCJib3JkZXJcIiArIGNzc0V4cGFuZFsgaSBdICsgXCJXaWR0aFwiLCB0cnVlLCBzdHlsZXMgKTtcblxuXHRcdFx0Ly8gQnV0IHN0aWxsIGtlZXAgdHJhY2sgb2YgaXQgb3RoZXJ3aXNlXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRleHRyYSArPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXHRcdFx0fVxuXG5cdFx0Ly8gSWYgd2UgZ2V0IGhlcmUgd2l0aCBhIGJvcmRlci1ib3ggKGNvbnRlbnQgKyBwYWRkaW5nICsgYm9yZGVyKSwgd2UncmUgc2Vla2luZyBcImNvbnRlbnRcIiBvclxuXHRcdC8vIFwicGFkZGluZ1wiIG9yIFwibWFyZ2luXCJcblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBGb3IgXCJjb250ZW50XCIsIHN1YnRyYWN0IHBhZGRpbmdcblx0XHRcdGlmICggYm94ID09PSBcImNvbnRlbnRcIiApIHtcblx0XHRcdFx0ZGVsdGEgLT0galF1ZXJ5LmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZvciBcImNvbnRlbnRcIiBvciBcInBhZGRpbmdcIiwgc3VidHJhY3QgYm9yZGVyXG5cdFx0XHRpZiAoIGJveCAhPT0gXCJtYXJnaW5cIiApIHtcblx0XHRcdFx0ZGVsdGEgLT0galF1ZXJ5LmNzcyggZWxlbSwgXCJib3JkZXJcIiArIGNzc0V4cGFuZFsgaSBdICsgXCJXaWR0aFwiLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBBY2NvdW50IGZvciBwb3NpdGl2ZSBjb250ZW50LWJveCBzY3JvbGwgZ3V0dGVyIHdoZW4gcmVxdWVzdGVkIGJ5IHByb3ZpZGluZyBjb21wdXRlZFZhbFxuXHRpZiAoICFpc0JvcmRlckJveCAmJiBjb21wdXRlZFZhbCA+PSAwICkge1xuXG5cdFx0Ly8gb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IGlzIGEgcm91bmRlZCBzdW0gb2YgY29udGVudCwgcGFkZGluZywgc2Nyb2xsIGd1dHRlciwgYW5kIGJvcmRlclxuXHRcdC8vIEFzc3VtaW5nIGludGVnZXIgc2Nyb2xsIGd1dHRlciwgc3VidHJhY3QgdGhlIHJlc3QgYW5kIHJvdW5kIGRvd25cblx0XHRkZWx0YSArPSBNYXRoLm1heCggMCwgTWF0aC5jZWlsKFxuXHRcdFx0ZWxlbVsgXCJvZmZzZXRcIiArIGRpbWVuc2lvblsgMCBdLnRvVXBwZXJDYXNlKCkgKyBkaW1lbnNpb24uc2xpY2UoIDEgKSBdIC1cblx0XHRcdGNvbXB1dGVkVmFsIC1cblx0XHRcdGRlbHRhIC1cblx0XHRcdGV4dHJhIC1cblx0XHRcdDAuNVxuXG5cdFx0Ly8gSWYgb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IGlzIHVua25vd24sIHRoZW4gd2UgY2FuJ3QgZGV0ZXJtaW5lIGNvbnRlbnQtYm94IHNjcm9sbCBndXR0ZXJcblx0XHQvLyBVc2UgYW4gZXhwbGljaXQgemVybyB0byBhdm9pZCBOYU4gKGdoLTM5NjQpXG5cdFx0KSApIHx8IDA7XG5cdH1cblxuXHRyZXR1cm4gZGVsdGE7XG59XG5cbmZ1bmN0aW9uIGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIGRpbWVuc2lvbiwgZXh0cmEgKSB7XG5cblx0Ly8gU3RhcnQgd2l0aCBjb21wdXRlZCBzdHlsZVxuXHR2YXIgc3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICksXG5cblx0XHQvLyBUbyBhdm9pZCBmb3JjaW5nIGEgcmVmbG93LCBvbmx5IGZldGNoIGJveFNpemluZyBpZiB3ZSBuZWVkIGl0IChnaC00MzIyKS5cblx0XHQvLyBGYWtlIGNvbnRlbnQtYm94IHVudGlsIHdlIGtub3cgaXQncyBuZWVkZWQgdG8ga25vdyB0aGUgdHJ1ZSB2YWx1ZS5cblx0XHRib3hTaXppbmdOZWVkZWQgPSAhc3VwcG9ydC5ib3hTaXppbmdSZWxpYWJsZSgpIHx8IGV4dHJhLFxuXHRcdGlzQm9yZGVyQm94ID0gYm94U2l6aW5nTmVlZGVkICYmXG5cdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCBcImJveFNpemluZ1wiLCBmYWxzZSwgc3R5bGVzICkgPT09IFwiYm9yZGVyLWJveFwiLFxuXHRcdHZhbHVlSXNCb3JkZXJCb3ggPSBpc0JvcmRlckJveCxcblxuXHRcdHZhbCA9IGN1ckNTUyggZWxlbSwgZGltZW5zaW9uLCBzdHlsZXMgKSxcblx0XHRvZmZzZXRQcm9wID0gXCJvZmZzZXRcIiArIGRpbWVuc2lvblsgMCBdLnRvVXBwZXJDYXNlKCkgKyBkaW1lbnNpb24uc2xpY2UoIDEgKTtcblxuXHQvLyBTdXBwb3J0OiBGaXJlZm94IDw9NTRcblx0Ly8gUmV0dXJuIGEgY29uZm91bmRpbmcgbm9uLXBpeGVsIHZhbHVlIG9yIGZlaWduIGlnbm9yYW5jZSwgYXMgYXBwcm9wcmlhdGUuXG5cdGlmICggcm51bW5vbnB4LnRlc3QoIHZhbCApICkge1xuXHRcdGlmICggIWV4dHJhICkge1xuXHRcdFx0cmV0dXJuIHZhbDtcblx0XHR9XG5cdFx0dmFsID0gXCJhdXRvXCI7XG5cdH1cblxuXG5cdC8vIFN1cHBvcnQ6IElFIDkgLSAxMSBvbmx5XG5cdC8vIFVzZSBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgZm9yIHdoZW4gYm94IHNpemluZyBpcyB1bnJlbGlhYmxlLlxuXHQvLyBJbiB0aG9zZSBjYXNlcywgdGhlIGNvbXB1dGVkIHZhbHVlIGNhbiBiZSB0cnVzdGVkIHRvIGJlIGJvcmRlci1ib3guXG5cdGlmICggKCAhc3VwcG9ydC5ib3hTaXppbmdSZWxpYWJsZSgpICYmIGlzQm9yZGVyQm94IHx8XG5cblx0XHQvLyBTdXBwb3J0OiBJRSAxMCAtIDExKywgRWRnZSAxNSAtIDE4K1xuXHRcdC8vIElFL0VkZ2UgbWlzcmVwb3J0IGBnZXRDb21wdXRlZFN0eWxlYCBvZiB0YWJsZSByb3dzIHdpdGggd2lkdGgvaGVpZ2h0XG5cdFx0Ly8gc2V0IGluIENTUyB3aGlsZSBgb2Zmc2V0KmAgcHJvcGVydGllcyByZXBvcnQgY29ycmVjdCB2YWx1ZXMuXG5cdFx0Ly8gSW50ZXJlc3RpbmdseSwgaW4gc29tZSBjYXNlcyBJRSA5IGRvZXNuJ3Qgc3VmZmVyIGZyb20gdGhpcyBpc3N1ZS5cblx0XHQhc3VwcG9ydC5yZWxpYWJsZVRyRGltZW5zaW9ucygpICYmIG5vZGVOYW1lKCBlbGVtLCBcInRyXCIgKSB8fFxuXG5cdFx0Ly8gRmFsbCBiYWNrIHRvIG9mZnNldFdpZHRoL29mZnNldEhlaWdodCB3aGVuIHZhbHVlIGlzIFwiYXV0b1wiXG5cdFx0Ly8gVGhpcyBoYXBwZW5zIGZvciBpbmxpbmUgZWxlbWVudHMgd2l0aCBubyBleHBsaWNpdCBzZXR0aW5nIChnaC0zNTcxKVxuXHRcdHZhbCA9PT0gXCJhdXRvXCIgfHxcblxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjEgLSA0LjMgb25seVxuXHRcdC8vIEFsc28gdXNlIG9mZnNldFdpZHRoL29mZnNldEhlaWdodCBmb3IgbWlzcmVwb3J0ZWQgaW5saW5lIGRpbWVuc2lvbnMgKGdoLTM2MDIpXG5cdFx0IXBhcnNlRmxvYXQoIHZhbCApICYmIGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiLCBmYWxzZSwgc3R5bGVzICkgPT09IFwiaW5saW5lXCIgKSAmJlxuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoZSBlbGVtZW50IGlzIHZpc2libGUgJiBjb25uZWN0ZWRcblx0XHRlbGVtLmdldENsaWVudFJlY3RzKCkubGVuZ3RoICkge1xuXG5cdFx0aXNCb3JkZXJCb3ggPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJveFNpemluZ1wiLCBmYWxzZSwgc3R5bGVzICkgPT09IFwiYm9yZGVyLWJveFwiO1xuXG5cdFx0Ly8gV2hlcmUgYXZhaWxhYmxlLCBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgYXBwcm94aW1hdGUgYm9yZGVyIGJveCBkaW1lbnNpb25zLlxuXHRcdC8vIFdoZXJlIG5vdCBhdmFpbGFibGUgKGUuZy4sIFNWRyksIGFzc3VtZSB1bnJlbGlhYmxlIGJveC1zaXppbmcgYW5kIGludGVycHJldCB0aGVcblx0XHQvLyByZXRyaWV2ZWQgdmFsdWUgYXMgYSBjb250ZW50IGJveCBkaW1lbnNpb24uXG5cdFx0dmFsdWVJc0JvcmRlckJveCA9IG9mZnNldFByb3AgaW4gZWxlbTtcblx0XHRpZiAoIHZhbHVlSXNCb3JkZXJCb3ggKSB7XG5cdFx0XHR2YWwgPSBlbGVtWyBvZmZzZXRQcm9wIF07XG5cdFx0fVxuXHR9XG5cblx0Ly8gTm9ybWFsaXplIFwiXCIgYW5kIGF1dG9cblx0dmFsID0gcGFyc2VGbG9hdCggdmFsICkgfHwgMDtcblxuXHQvLyBBZGp1c3QgZm9yIHRoZSBlbGVtZW50J3MgYm94IG1vZGVsXG5cdHJldHVybiAoIHZhbCArXG5cdFx0Ym94TW9kZWxBZGp1c3RtZW50KFxuXHRcdFx0ZWxlbSxcblx0XHRcdGRpbWVuc2lvbixcblx0XHRcdGV4dHJhIHx8ICggaXNCb3JkZXJCb3ggPyBcImJvcmRlclwiIDogXCJjb250ZW50XCIgKSxcblx0XHRcdHZhbHVlSXNCb3JkZXJCb3gsXG5cdFx0XHRzdHlsZXMsXG5cblx0XHRcdC8vIFByb3ZpZGUgdGhlIGN1cnJlbnQgY29tcHV0ZWQgc2l6ZSB0byByZXF1ZXN0IHNjcm9sbCBndXR0ZXIgY2FsY3VsYXRpb24gKGdoLTM1ODkpXG5cdFx0XHR2YWxcblx0XHQpXG5cdCkgKyBcInB4XCI7XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHQvLyBBZGQgaW4gc3R5bGUgcHJvcGVydHkgaG9va3MgZm9yIG92ZXJyaWRpbmcgdGhlIGRlZmF1bHRcblx0Ly8gYmVoYXZpb3Igb2YgZ2V0dGluZyBhbmQgc2V0dGluZyBhIHN0eWxlIHByb3BlcnR5XG5cdGNzc0hvb2tzOiB7XG5cdFx0b3BhY2l0eToge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0XHRcdGlmICggY29tcHV0ZWQgKSB7XG5cblx0XHRcdFx0XHQvLyBXZSBzaG91bGQgYWx3YXlzIGdldCBhIG51bWJlciBiYWNrIGZyb20gb3BhY2l0eVxuXHRcdFx0XHRcdHZhciByZXQgPSBjdXJDU1MoIGVsZW0sIFwib3BhY2l0eVwiICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJldCA9PT0gXCJcIiA/IFwiMVwiIDogcmV0O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8vIERvbid0IGF1dG9tYXRpY2FsbHkgYWRkIFwicHhcIiB0byB0aGVzZSBwb3NzaWJseS11bml0bGVzcyBwcm9wZXJ0aWVzXG5cdGNzc051bWJlcjoge1xuXHRcdFwiYW5pbWF0aW9uSXRlcmF0aW9uQ291bnRcIjogdHJ1ZSxcblx0XHRcImNvbHVtbkNvdW50XCI6IHRydWUsXG5cdFx0XCJmaWxsT3BhY2l0eVwiOiB0cnVlLFxuXHRcdFwiZmxleEdyb3dcIjogdHJ1ZSxcblx0XHRcImZsZXhTaHJpbmtcIjogdHJ1ZSxcblx0XHRcImZvbnRXZWlnaHRcIjogdHJ1ZSxcblx0XHRcImdyaWRBcmVhXCI6IHRydWUsXG5cdFx0XCJncmlkQ29sdW1uXCI6IHRydWUsXG5cdFx0XCJncmlkQ29sdW1uRW5kXCI6IHRydWUsXG5cdFx0XCJncmlkQ29sdW1uU3RhcnRcIjogdHJ1ZSxcblx0XHRcImdyaWRSb3dcIjogdHJ1ZSxcblx0XHRcImdyaWRSb3dFbmRcIjogdHJ1ZSxcblx0XHRcImdyaWRSb3dTdGFydFwiOiB0cnVlLFxuXHRcdFwibGluZUhlaWdodFwiOiB0cnVlLFxuXHRcdFwib3BhY2l0eVwiOiB0cnVlLFxuXHRcdFwib3JkZXJcIjogdHJ1ZSxcblx0XHRcIm9ycGhhbnNcIjogdHJ1ZSxcblx0XHRcIndpZG93c1wiOiB0cnVlLFxuXHRcdFwiekluZGV4XCI6IHRydWUsXG5cdFx0XCJ6b29tXCI6IHRydWVcblx0fSxcblxuXHQvLyBBZGQgaW4gcHJvcGVydGllcyB3aG9zZSBuYW1lcyB5b3Ugd2lzaCB0byBmaXggYmVmb3JlXG5cdC8vIHNldHRpbmcgb3IgZ2V0dGluZyB0aGUgdmFsdWVcblx0Y3NzUHJvcHM6IHt9LFxuXG5cdC8vIEdldCBhbmQgc2V0IHRoZSBzdHlsZSBwcm9wZXJ0eSBvbiBhIERPTSBOb2RlXG5cdHN0eWxlOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUsIGV4dHJhICkge1xuXG5cdFx0Ly8gRG9uJ3Qgc2V0IHN0eWxlcyBvbiB0ZXh0IGFuZCBjb21tZW50IG5vZGVzXG5cdFx0aWYgKCAhZWxlbSB8fCBlbGVtLm5vZGVUeXBlID09PSAzIHx8IGVsZW0ubm9kZVR5cGUgPT09IDggfHwgIWVsZW0uc3R5bGUgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgd2UncmUgd29ya2luZyB3aXRoIHRoZSByaWdodCBuYW1lXG5cdFx0dmFyIHJldCwgdHlwZSwgaG9va3MsXG5cdFx0XHRvcmlnTmFtZSA9IGNhbWVsQ2FzZSggbmFtZSApLFxuXHRcdFx0aXNDdXN0b21Qcm9wID0gcmN1c3RvbVByb3AudGVzdCggbmFtZSApLFxuXHRcdFx0c3R5bGUgPSBlbGVtLnN0eWxlO1xuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgd2UncmUgd29ya2luZyB3aXRoIHRoZSByaWdodCBuYW1lLiBXZSBkb24ndFxuXHRcdC8vIHdhbnQgdG8gcXVlcnkgdGhlIHZhbHVlIGlmIGl0IGlzIGEgQ1NTIGN1c3RvbSBwcm9wZXJ0eVxuXHRcdC8vIHNpbmNlIHRoZXkgYXJlIHVzZXItZGVmaW5lZC5cblx0XHRpZiAoICFpc0N1c3RvbVByb3AgKSB7XG5cdFx0XHRuYW1lID0gZmluYWxQcm9wTmFtZSggb3JpZ05hbWUgKTtcblx0XHR9XG5cblx0XHQvLyBHZXRzIGhvb2sgZm9yIHRoZSBwcmVmaXhlZCB2ZXJzaW9uLCB0aGVuIHVucHJlZml4ZWQgdmVyc2lvblxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF0gfHwgalF1ZXJ5LmNzc0hvb2tzWyBvcmlnTmFtZSBdO1xuXG5cdFx0Ly8gQ2hlY2sgaWYgd2UncmUgc2V0dGluZyBhIHZhbHVlXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0dHlwZSA9IHR5cGVvZiB2YWx1ZTtcblxuXHRcdFx0Ly8gQ29udmVydCBcIis9XCIgb3IgXCItPVwiIHRvIHJlbGF0aXZlIG51bWJlcnMgKCM3MzQ1KVxuXHRcdFx0aWYgKCB0eXBlID09PSBcInN0cmluZ1wiICYmICggcmV0ID0gcmNzc051bS5leGVjKCB2YWx1ZSApICkgJiYgcmV0WyAxIF0gKSB7XG5cdFx0XHRcdHZhbHVlID0gYWRqdXN0Q1NTKCBlbGVtLCBuYW1lLCByZXQgKTtcblxuXHRcdFx0XHQvLyBGaXhlcyBidWcgIzkyMzdcblx0XHRcdFx0dHlwZSA9IFwibnVtYmVyXCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1ha2Ugc3VyZSB0aGF0IG51bGwgYW5kIE5hTiB2YWx1ZXMgYXJlbid0IHNldCAoIzcxMTYpXG5cdFx0XHRpZiAoIHZhbHVlID09IG51bGwgfHwgdmFsdWUgIT09IHZhbHVlICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIGEgbnVtYmVyIHdhcyBwYXNzZWQgaW4sIGFkZCB0aGUgdW5pdCAoZXhjZXB0IGZvciBjZXJ0YWluIENTUyBwcm9wZXJ0aWVzKVxuXHRcdFx0Ly8gVGhlIGlzQ3VzdG9tUHJvcCBjaGVjayBjYW4gYmUgcmVtb3ZlZCBpbiBqUXVlcnkgNC4wIHdoZW4gd2Ugb25seSBhdXRvLWFwcGVuZFxuXHRcdFx0Ly8gXCJweFwiIHRvIGEgZmV3IGhhcmRjb2RlZCB2YWx1ZXMuXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwibnVtYmVyXCIgJiYgIWlzQ3VzdG9tUHJvcCApIHtcblx0XHRcdFx0dmFsdWUgKz0gcmV0ICYmIHJldFsgMyBdIHx8ICggalF1ZXJ5LmNzc051bWJlclsgb3JpZ05hbWUgXSA/IFwiXCIgOiBcInB4XCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gYmFja2dyb3VuZC0qIHByb3BzIGFmZmVjdCBvcmlnaW5hbCBjbG9uZSdzIHZhbHVlc1xuXHRcdFx0aWYgKCAhc3VwcG9ydC5jbGVhckNsb25lU3R5bGUgJiYgdmFsdWUgPT09IFwiXCIgJiYgbmFtZS5pbmRleE9mKCBcImJhY2tncm91bmRcIiApID09PSAwICkge1xuXHRcdFx0XHRzdHlsZVsgbmFtZSBdID0gXCJpbmhlcml0XCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQsIHVzZSB0aGF0IHZhbHVlLCBvdGhlcndpc2UganVzdCBzZXQgdGhlIHNwZWNpZmllZCB2YWx1ZVxuXHRcdFx0aWYgKCAhaG9va3MgfHwgISggXCJzZXRcIiBpbiBob29rcyApIHx8XG5cdFx0XHRcdCggdmFsdWUgPSBob29rcy5zZXQoIGVsZW0sIHZhbHVlLCBleHRyYSApICkgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRpZiAoIGlzQ3VzdG9tUHJvcCApIHtcblx0XHRcdFx0XHRzdHlsZS5zZXRQcm9wZXJ0eSggbmFtZSwgdmFsdWUgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzdHlsZVsgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQgZ2V0IHRoZSBub24tY29tcHV0ZWQgdmFsdWUgZnJvbSB0aGVyZVxuXHRcdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmXG5cdFx0XHRcdCggcmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBmYWxzZSwgZXh0cmEgKSApICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIGp1c3QgZ2V0IHRoZSB2YWx1ZSBmcm9tIHRoZSBzdHlsZSBvYmplY3Rcblx0XHRcdHJldHVybiBzdHlsZVsgbmFtZSBdO1xuXHRcdH1cblx0fSxcblxuXHRjc3M6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBleHRyYSwgc3R5bGVzICkge1xuXHRcdHZhciB2YWwsIG51bSwgaG9va3MsXG5cdFx0XHRvcmlnTmFtZSA9IGNhbWVsQ2FzZSggbmFtZSApLFxuXHRcdFx0aXNDdXN0b21Qcm9wID0gcmN1c3RvbVByb3AudGVzdCggbmFtZSApO1xuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgd2UncmUgd29ya2luZyB3aXRoIHRoZSByaWdodCBuYW1lLiBXZSBkb24ndFxuXHRcdC8vIHdhbnQgdG8gbW9kaWZ5IHRoZSB2YWx1ZSBpZiBpdCBpcyBhIENTUyBjdXN0b20gcHJvcGVydHlcblx0XHQvLyBzaW5jZSB0aGV5IGFyZSB1c2VyLWRlZmluZWQuXG5cdFx0aWYgKCAhaXNDdXN0b21Qcm9wICkge1xuXHRcdFx0bmFtZSA9IGZpbmFsUHJvcE5hbWUoIG9yaWdOYW1lICk7XG5cdFx0fVxuXG5cdFx0Ly8gVHJ5IHByZWZpeGVkIG5hbWUgZm9sbG93ZWQgYnkgdGhlIHVucHJlZml4ZWQgbmFtZVxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF0gfHwgalF1ZXJ5LmNzc0hvb2tzWyBvcmlnTmFtZSBdO1xuXG5cdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCBnZXQgdGhlIGNvbXB1dGVkIHZhbHVlIGZyb20gdGhlcmVcblx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgKSB7XG5cdFx0XHR2YWwgPSBob29rcy5nZXQoIGVsZW0sIHRydWUsIGV4dHJhICk7XG5cdFx0fVxuXG5cdFx0Ly8gT3RoZXJ3aXNlLCBpZiBhIHdheSB0byBnZXQgdGhlIGNvbXB1dGVkIHZhbHVlIGV4aXN0cywgdXNlIHRoYXRcblx0XHRpZiAoIHZhbCA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0dmFsID0gY3VyQ1NTKCBlbGVtLCBuYW1lLCBzdHlsZXMgKTtcblx0XHR9XG5cblx0XHQvLyBDb252ZXJ0IFwibm9ybWFsXCIgdG8gY29tcHV0ZWQgdmFsdWVcblx0XHRpZiAoIHZhbCA9PT0gXCJub3JtYWxcIiAmJiBuYW1lIGluIGNzc05vcm1hbFRyYW5zZm9ybSApIHtcblx0XHRcdHZhbCA9IGNzc05vcm1hbFRyYW5zZm9ybVsgbmFtZSBdO1xuXHRcdH1cblxuXHRcdC8vIE1ha2UgbnVtZXJpYyBpZiBmb3JjZWQgb3IgYSBxdWFsaWZpZXIgd2FzIHByb3ZpZGVkIGFuZCB2YWwgbG9va3MgbnVtZXJpY1xuXHRcdGlmICggZXh0cmEgPT09IFwiXCIgfHwgZXh0cmEgKSB7XG5cdFx0XHRudW0gPSBwYXJzZUZsb2F0KCB2YWwgKTtcblx0XHRcdHJldHVybiBleHRyYSA9PT0gdHJ1ZSB8fCBpc0Zpbml0ZSggbnVtICkgPyBudW0gfHwgMCA6IHZhbDtcblx0XHR9XG5cblx0XHRyZXR1cm4gdmFsO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5lYWNoKCBbIFwiaGVpZ2h0XCIsIFwid2lkdGhcIiBdLCBmdW5jdGlvbiggX2ksIGRpbWVuc2lvbiApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBkaW1lbnNpb24gXSA9IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCwgZXh0cmEgKSB7XG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xuXG5cdFx0XHRcdC8vIENlcnRhaW4gZWxlbWVudHMgY2FuIGhhdmUgZGltZW5zaW9uIGluZm8gaWYgd2UgaW52aXNpYmx5IHNob3cgdGhlbVxuXHRcdFx0XHQvLyBidXQgaXQgbXVzdCBoYXZlIGEgY3VycmVudCBkaXNwbGF5IHN0eWxlIHRoYXQgd291bGQgYmVuZWZpdFxuXHRcdFx0XHRyZXR1cm4gcmRpc3BsYXlzd2FwLnRlc3QoIGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICkgKSAmJlxuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogU2FmYXJpIDgrXG5cdFx0XHRcdFx0Ly8gVGFibGUgY29sdW1ucyBpbiBTYWZhcmkgaGF2ZSBub24temVybyBvZmZzZXRXaWR0aCAmIHplcm9cblx0XHRcdFx0XHQvLyBnZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCB1bmxlc3MgZGlzcGxheSBpcyBjaGFuZ2VkLlxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxuXHRcdFx0XHRcdC8vIFJ1bm5pbmcgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IG9uIGEgZGlzY29ubmVjdGVkIG5vZGVcblx0XHRcdFx0XHQvLyBpbiBJRSB0aHJvd3MgYW4gZXJyb3IuXG5cdFx0XHRcdFx0KCAhZWxlbS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCB8fCAhZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCApID9cblx0XHRcdFx0XHRzd2FwKCBlbGVtLCBjc3NTaG93LCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdHJldHVybiBnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBkaW1lbnNpb24sIGV4dHJhICk7XG5cdFx0XHRcdFx0fSApIDpcblx0XHRcdFx0XHRnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBkaW1lbnNpb24sIGV4dHJhICk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlLCBleHRyYSApIHtcblx0XHRcdHZhciBtYXRjaGVzLFxuXHRcdFx0XHRzdHlsZXMgPSBnZXRTdHlsZXMoIGVsZW0gKSxcblxuXHRcdFx0XHQvLyBPbmx5IHJlYWQgc3R5bGVzLnBvc2l0aW9uIGlmIHRoZSB0ZXN0IGhhcyBhIGNoYW5jZSB0byBmYWlsXG5cdFx0XHRcdC8vIHRvIGF2b2lkIGZvcmNpbmcgYSByZWZsb3cuXG5cdFx0XHRcdHNjcm9sbGJveFNpemVCdWdneSA9ICFzdXBwb3J0LnNjcm9sbGJveFNpemUoKSAmJlxuXHRcdFx0XHRcdHN0eWxlcy5wb3NpdGlvbiA9PT0gXCJhYnNvbHV0ZVwiLFxuXG5cdFx0XHRcdC8vIFRvIGF2b2lkIGZvcmNpbmcgYSByZWZsb3csIG9ubHkgZmV0Y2ggYm94U2l6aW5nIGlmIHdlIG5lZWQgaXQgKGdoLTM5OTEpXG5cdFx0XHRcdGJveFNpemluZ05lZWRlZCA9IHNjcm9sbGJveFNpemVCdWdneSB8fCBleHRyYSxcblx0XHRcdFx0aXNCb3JkZXJCb3ggPSBib3hTaXppbmdOZWVkZWQgJiZcblx0XHRcdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCBcImJveFNpemluZ1wiLCBmYWxzZSwgc3R5bGVzICkgPT09IFwiYm9yZGVyLWJveFwiLFxuXHRcdFx0XHRzdWJ0cmFjdCA9IGV4dHJhID9cblx0XHRcdFx0XHRib3hNb2RlbEFkanVzdG1lbnQoXG5cdFx0XHRcdFx0XHRlbGVtLFxuXHRcdFx0XHRcdFx0ZGltZW5zaW9uLFxuXHRcdFx0XHRcdFx0ZXh0cmEsXG5cdFx0XHRcdFx0XHRpc0JvcmRlckJveCxcblx0XHRcdFx0XHRcdHN0eWxlc1xuXHRcdFx0XHRcdCkgOlxuXHRcdFx0XHRcdDA7XG5cblx0XHRcdC8vIEFjY291bnQgZm9yIHVucmVsaWFibGUgYm9yZGVyLWJveCBkaW1lbnNpb25zIGJ5IGNvbXBhcmluZyBvZmZzZXQqIHRvIGNvbXB1dGVkIGFuZFxuXHRcdFx0Ly8gZmFraW5nIGEgY29udGVudC1ib3ggdG8gZ2V0IGJvcmRlciBhbmQgcGFkZGluZyAoZ2gtMzY5OSlcblx0XHRcdGlmICggaXNCb3JkZXJCb3ggJiYgc2Nyb2xsYm94U2l6ZUJ1Z2d5ICkge1xuXHRcdFx0XHRzdWJ0cmFjdCAtPSBNYXRoLmNlaWwoXG5cdFx0XHRcdFx0ZWxlbVsgXCJvZmZzZXRcIiArIGRpbWVuc2lvblsgMCBdLnRvVXBwZXJDYXNlKCkgKyBkaW1lbnNpb24uc2xpY2UoIDEgKSBdIC1cblx0XHRcdFx0XHRwYXJzZUZsb2F0KCBzdHlsZXNbIGRpbWVuc2lvbiBdICkgLVxuXHRcdFx0XHRcdGJveE1vZGVsQWRqdXN0bWVudCggZWxlbSwgZGltZW5zaW9uLCBcImJvcmRlclwiLCBmYWxzZSwgc3R5bGVzICkgLVxuXHRcdFx0XHRcdDAuNVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDb252ZXJ0IHRvIHBpeGVscyBpZiB2YWx1ZSBhZGp1c3RtZW50IGlzIG5lZWRlZFxuXHRcdFx0aWYgKCBzdWJ0cmFjdCAmJiAoIG1hdGNoZXMgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICkgKSAmJlxuXHRcdFx0XHQoIG1hdGNoZXNbIDMgXSB8fCBcInB4XCIgKSAhPT0gXCJweFwiICkge1xuXG5cdFx0XHRcdGVsZW0uc3R5bGVbIGRpbWVuc2lvbiBdID0gdmFsdWU7XG5cdFx0XHRcdHZhbHVlID0galF1ZXJ5LmNzcyggZWxlbSwgZGltZW5zaW9uICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBzZXRQb3NpdGl2ZU51bWJlciggZWxlbSwgdmFsdWUsIHN1YnRyYWN0ICk7XG5cdFx0fVxuXHR9O1xufSApO1xuXG5qUXVlcnkuY3NzSG9va3MubWFyZ2luTGVmdCA9IGFkZEdldEhvb2tJZiggc3VwcG9ydC5yZWxpYWJsZU1hcmdpbkxlZnQsXG5cdGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRpZiAoIGNvbXB1dGVkICkge1xuXHRcdFx0cmV0dXJuICggcGFyc2VGbG9hdCggY3VyQ1NTKCBlbGVtLCBcIm1hcmdpbkxlZnRcIiApICkgfHxcblx0XHRcdFx0ZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0IC1cblx0XHRcdFx0XHRzd2FwKCBlbGVtLCB7IG1hcmdpbkxlZnQ6IDAgfSwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0O1xuXHRcdFx0XHRcdH0gKVxuXHRcdFx0KSArIFwicHhcIjtcblx0XHR9XG5cdH1cbik7XG5cbi8vIFRoZXNlIGhvb2tzIGFyZSB1c2VkIGJ5IGFuaW1hdGUgdG8gZXhwYW5kIHByb3BlcnRpZXNcbmpRdWVyeS5lYWNoKCB7XG5cdG1hcmdpbjogXCJcIixcblx0cGFkZGluZzogXCJcIixcblx0Ym9yZGVyOiBcIldpZHRoXCJcbn0sIGZ1bmN0aW9uKCBwcmVmaXgsIHN1ZmZpeCApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBwcmVmaXggKyBzdWZmaXggXSA9IHtcblx0XHRleHBhbmQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBpID0gMCxcblx0XHRcdFx0ZXhwYW5kZWQgPSB7fSxcblxuXHRcdFx0XHQvLyBBc3N1bWVzIGEgc2luZ2xlIG51bWJlciBpZiBub3QgYSBzdHJpbmdcblx0XHRcdFx0cGFydHMgPSB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyB2YWx1ZS5zcGxpdCggXCIgXCIgKSA6IFsgdmFsdWUgXTtcblxuXHRcdFx0Zm9yICggOyBpIDwgNDsgaSsrICkge1xuXHRcdFx0XHRleHBhbmRlZFsgcHJlZml4ICsgY3NzRXhwYW5kWyBpIF0gKyBzdWZmaXggXSA9XG5cdFx0XHRcdFx0cGFydHNbIGkgXSB8fCBwYXJ0c1sgaSAtIDIgXSB8fCBwYXJ0c1sgMCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZXhwYW5kZWQ7XG5cdFx0fVxuXHR9O1xuXG5cdGlmICggcHJlZml4ICE9PSBcIm1hcmdpblwiICkge1xuXHRcdGpRdWVyeS5jc3NIb29rc1sgcHJlZml4ICsgc3VmZml4IF0uc2V0ID0gc2V0UG9zaXRpdmVOdW1iZXI7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRjc3M6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7XG5cdFx0XHR2YXIgc3R5bGVzLCBsZW4sXG5cdFx0XHRcdG1hcCA9IHt9LFxuXHRcdFx0XHRpID0gMDtcblxuXHRcdFx0aWYgKCBBcnJheS5pc0FycmF5KCBuYW1lICkgKSB7XG5cdFx0XHRcdHN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApO1xuXHRcdFx0XHRsZW4gPSBuYW1lLmxlbmd0aDtcblxuXHRcdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRtYXBbIG5hbWVbIGkgXSBdID0galF1ZXJ5LmNzcyggZWxlbSwgbmFtZVsgaSBdLCBmYWxzZSwgc3R5bGVzICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gbWFwO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgbmFtZSwgdmFsdWUgKSA6XG5cdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIG5hbWUgKTtcblx0XHR9LCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fVxufSApO1xuXG5cbmZ1bmN0aW9uIFR3ZWVuKCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApIHtcblx0cmV0dXJuIG5ldyBUd2Vlbi5wcm90b3R5cGUuaW5pdCggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcgKTtcbn1cbmpRdWVyeS5Ud2VlbiA9IFR3ZWVuO1xuXG5Ud2Vlbi5wcm90b3R5cGUgPSB7XG5cdGNvbnN0cnVjdG9yOiBUd2Vlbixcblx0aW5pdDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nLCB1bml0ICkge1xuXHRcdHRoaXMuZWxlbSA9IGVsZW07XG5cdFx0dGhpcy5wcm9wID0gcHJvcDtcblx0XHR0aGlzLmVhc2luZyA9IGVhc2luZyB8fCBqUXVlcnkuZWFzaW5nLl9kZWZhdWx0O1xuXHRcdHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cdFx0dGhpcy5zdGFydCA9IHRoaXMubm93ID0gdGhpcy5jdXIoKTtcblx0XHR0aGlzLmVuZCA9IGVuZDtcblx0XHR0aGlzLnVuaXQgPSB1bml0IHx8ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdID8gXCJcIiA6IFwicHhcIiApO1xuXHR9LFxuXHRjdXI6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBob29rcyA9IFR3ZWVuLnByb3BIb29rc1sgdGhpcy5wcm9wIF07XG5cblx0XHRyZXR1cm4gaG9va3MgJiYgaG9va3MuZ2V0ID9cblx0XHRcdGhvb2tzLmdldCggdGhpcyApIDpcblx0XHRcdFR3ZWVuLnByb3BIb29rcy5fZGVmYXVsdC5nZXQoIHRoaXMgKTtcblx0fSxcblx0cnVuOiBmdW5jdGlvbiggcGVyY2VudCApIHtcblx0XHR2YXIgZWFzZWQsXG5cdFx0XHRob29rcyA9IFR3ZWVuLnByb3BIb29rc1sgdGhpcy5wcm9wIF07XG5cblx0XHRpZiAoIHRoaXMub3B0aW9ucy5kdXJhdGlvbiApIHtcblx0XHRcdHRoaXMucG9zID0gZWFzZWQgPSBqUXVlcnkuZWFzaW5nWyB0aGlzLmVhc2luZyBdKFxuXHRcdFx0XHRwZXJjZW50LCB0aGlzLm9wdGlvbnMuZHVyYXRpb24gKiBwZXJjZW50LCAwLCAxLCB0aGlzLm9wdGlvbnMuZHVyYXRpb25cblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMucG9zID0gZWFzZWQgPSBwZXJjZW50O1xuXHRcdH1cblx0XHR0aGlzLm5vdyA9ICggdGhpcy5lbmQgLSB0aGlzLnN0YXJ0ICkgKiBlYXNlZCArIHRoaXMuc3RhcnQ7XG5cblx0XHRpZiAoIHRoaXMub3B0aW9ucy5zdGVwICkge1xuXHRcdFx0dGhpcy5vcHRpb25zLnN0ZXAuY2FsbCggdGhpcy5lbGVtLCB0aGlzLm5vdywgdGhpcyApO1xuXHRcdH1cblxuXHRcdGlmICggaG9va3MgJiYgaG9va3Muc2V0ICkge1xuXHRcdFx0aG9va3Muc2V0KCB0aGlzICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFR3ZWVuLnByb3BIb29rcy5fZGVmYXVsdC5zZXQoIHRoaXMgKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cbn07XG5cblR3ZWVuLnByb3RvdHlwZS5pbml0LnByb3RvdHlwZSA9IFR3ZWVuLnByb3RvdHlwZTtcblxuVHdlZW4ucHJvcEhvb2tzID0ge1xuXHRfZGVmYXVsdDoge1xuXHRcdGdldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXHRcdFx0dmFyIHJlc3VsdDtcblxuXHRcdFx0Ly8gVXNlIGEgcHJvcGVydHkgb24gdGhlIGVsZW1lbnQgZGlyZWN0bHkgd2hlbiBpdCBpcyBub3QgYSBET00gZWxlbWVudCxcblx0XHRcdC8vIG9yIHdoZW4gdGhlcmUgaXMgbm8gbWF0Y2hpbmcgc3R5bGUgcHJvcGVydHkgdGhhdCBleGlzdHMuXG5cdFx0XHRpZiAoIHR3ZWVuLmVsZW0ubm9kZVR5cGUgIT09IDEgfHxcblx0XHRcdFx0dHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdICE9IG51bGwgJiYgdHdlZW4uZWxlbS5zdHlsZVsgdHdlZW4ucHJvcCBdID09IG51bGwgKSB7XG5cdFx0XHRcdHJldHVybiB0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF07XG5cdFx0XHR9XG5cblx0XHRcdC8vIFBhc3NpbmcgYW4gZW1wdHkgc3RyaW5nIGFzIGEgM3JkIHBhcmFtZXRlciB0byAuY3NzIHdpbGwgYXV0b21hdGljYWxseVxuXHRcdFx0Ly8gYXR0ZW1wdCBhIHBhcnNlRmxvYXQgYW5kIGZhbGxiYWNrIHRvIGEgc3RyaW5nIGlmIHRoZSBwYXJzZSBmYWlscy5cblx0XHRcdC8vIFNpbXBsZSB2YWx1ZXMgc3VjaCBhcyBcIjEwcHhcIiBhcmUgcGFyc2VkIHRvIEZsb2F0O1xuXHRcdFx0Ly8gY29tcGxleCB2YWx1ZXMgc3VjaCBhcyBcInJvdGF0ZSgxcmFkKVwiIGFyZSByZXR1cm5lZCBhcy1pcy5cblx0XHRcdHJlc3VsdCA9IGpRdWVyeS5jc3MoIHR3ZWVuLmVsZW0sIHR3ZWVuLnByb3AsIFwiXCIgKTtcblxuXHRcdFx0Ly8gRW1wdHkgc3RyaW5ncywgbnVsbCwgdW5kZWZpbmVkIGFuZCBcImF1dG9cIiBhcmUgY29udmVydGVkIHRvIDAuXG5cdFx0XHRyZXR1cm4gIXJlc3VsdCB8fCByZXN1bHQgPT09IFwiYXV0b1wiID8gMCA6IHJlc3VsdDtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXG5cdFx0XHQvLyBVc2Ugc3RlcCBob29rIGZvciBiYWNrIGNvbXBhdC5cblx0XHRcdC8vIFVzZSBjc3NIb29rIGlmIGl0cyB0aGVyZS5cblx0XHRcdC8vIFVzZSAuc3R5bGUgaWYgYXZhaWxhYmxlIGFuZCB1c2UgcGxhaW4gcHJvcGVydGllcyB3aGVyZSBhdmFpbGFibGUuXG5cdFx0XHRpZiAoIGpRdWVyeS5meC5zdGVwWyB0d2Vlbi5wcm9wIF0gKSB7XG5cdFx0XHRcdGpRdWVyeS5meC5zdGVwWyB0d2Vlbi5wcm9wIF0oIHR3ZWVuICk7XG5cdFx0XHR9IGVsc2UgaWYgKCB0d2Vlbi5lbGVtLm5vZGVUeXBlID09PSAxICYmIChcblx0XHRcdFx0alF1ZXJ5LmNzc0hvb2tzWyB0d2Vlbi5wcm9wIF0gfHxcblx0XHRcdFx0XHR0d2Vlbi5lbGVtLnN0eWxlWyBmaW5hbFByb3BOYW1lKCB0d2Vlbi5wcm9wICkgXSAhPSBudWxsICkgKSB7XG5cdFx0XHRcdGpRdWVyeS5zdHlsZSggdHdlZW4uZWxlbSwgdHdlZW4ucHJvcCwgdHdlZW4ubm93ICsgdHdlZW4udW5pdCApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdID0gdHdlZW4ubm93O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufTtcblxuLy8gU3VwcG9ydDogSUUgPD05IG9ubHlcbi8vIFBhbmljIGJhc2VkIGFwcHJvYWNoIHRvIHNldHRpbmcgdGhpbmdzIG9uIGRpc2Nvbm5lY3RlZCBub2Rlc1xuVHdlZW4ucHJvcEhvb2tzLnNjcm9sbFRvcCA9IFR3ZWVuLnByb3BIb29rcy5zY3JvbGxMZWZ0ID0ge1xuXHRzZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcblx0XHRpZiAoIHR3ZWVuLmVsZW0ubm9kZVR5cGUgJiYgdHdlZW4uZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0dHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdID0gdHdlZW4ubm93O1xuXHRcdH1cblx0fVxufTtcblxualF1ZXJ5LmVhc2luZyA9IHtcblx0bGluZWFyOiBmdW5jdGlvbiggcCApIHtcblx0XHRyZXR1cm4gcDtcblx0fSxcblx0c3dpbmc6IGZ1bmN0aW9uKCBwICkge1xuXHRcdHJldHVybiAwLjUgLSBNYXRoLmNvcyggcCAqIE1hdGguUEkgKSAvIDI7XG5cdH0sXG5cdF9kZWZhdWx0OiBcInN3aW5nXCJcbn07XG5cbmpRdWVyeS5meCA9IFR3ZWVuLnByb3RvdHlwZS5pbml0O1xuXG4vLyBCYWNrIGNvbXBhdCA8MS44IGV4dGVuc2lvbiBwb2ludFxualF1ZXJ5LmZ4LnN0ZXAgPSB7fTtcblxuXG5cblxudmFyXG5cdGZ4Tm93LCBpblByb2dyZXNzLFxuXHRyZnh0eXBlcyA9IC9eKD86dG9nZ2xlfHNob3d8aGlkZSkkLyxcblx0cnJ1biA9IC9xdWV1ZUhvb2tzJC87XG5cbmZ1bmN0aW9uIHNjaGVkdWxlKCkge1xuXHRpZiAoIGluUHJvZ3Jlc3MgKSB7XG5cdFx0aWYgKCBkb2N1bWVudC5oaWRkZW4gPT09IGZhbHNlICYmIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgKSB7XG5cdFx0XHR3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCBzY2hlZHVsZSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR3aW5kb3cuc2V0VGltZW91dCggc2NoZWR1bGUsIGpRdWVyeS5meC5pbnRlcnZhbCApO1xuXHRcdH1cblxuXHRcdGpRdWVyeS5meC50aWNrKCk7XG5cdH1cbn1cblxuLy8gQW5pbWF0aW9ucyBjcmVhdGVkIHN5bmNocm9ub3VzbHkgd2lsbCBydW4gc3luY2hyb25vdXNseVxuZnVuY3Rpb24gY3JlYXRlRnhOb3coKSB7XG5cdHdpbmRvdy5zZXRUaW1lb3V0KCBmdW5jdGlvbigpIHtcblx0XHRmeE5vdyA9IHVuZGVmaW5lZDtcblx0fSApO1xuXHRyZXR1cm4gKCBmeE5vdyA9IERhdGUubm93KCkgKTtcbn1cblxuLy8gR2VuZXJhdGUgcGFyYW1ldGVycyB0byBjcmVhdGUgYSBzdGFuZGFyZCBhbmltYXRpb25cbmZ1bmN0aW9uIGdlbkZ4KCB0eXBlLCBpbmNsdWRlV2lkdGggKSB7XG5cdHZhciB3aGljaCxcblx0XHRpID0gMCxcblx0XHRhdHRycyA9IHsgaGVpZ2h0OiB0eXBlIH07XG5cblx0Ly8gSWYgd2UgaW5jbHVkZSB3aWR0aCwgc3RlcCB2YWx1ZSBpcyAxIHRvIGRvIGFsbCBjc3NFeHBhbmQgdmFsdWVzLFxuXHQvLyBvdGhlcndpc2Ugc3RlcCB2YWx1ZSBpcyAyIHRvIHNraXAgb3ZlciBMZWZ0IGFuZCBSaWdodFxuXHRpbmNsdWRlV2lkdGggPSBpbmNsdWRlV2lkdGggPyAxIDogMDtcblx0Zm9yICggOyBpIDwgNDsgaSArPSAyIC0gaW5jbHVkZVdpZHRoICkge1xuXHRcdHdoaWNoID0gY3NzRXhwYW5kWyBpIF07XG5cdFx0YXR0cnNbIFwibWFyZ2luXCIgKyB3aGljaCBdID0gYXR0cnNbIFwicGFkZGluZ1wiICsgd2hpY2ggXSA9IHR5cGU7XG5cdH1cblxuXHRpZiAoIGluY2x1ZGVXaWR0aCApIHtcblx0XHRhdHRycy5vcGFjaXR5ID0gYXR0cnMud2lkdGggPSB0eXBlO1xuXHR9XG5cblx0cmV0dXJuIGF0dHJzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVUd2VlbiggdmFsdWUsIHByb3AsIGFuaW1hdGlvbiApIHtcblx0dmFyIHR3ZWVuLFxuXHRcdGNvbGxlY3Rpb24gPSAoIEFuaW1hdGlvbi50d2VlbmVyc1sgcHJvcCBdIHx8IFtdICkuY29uY2F0KCBBbmltYXRpb24udHdlZW5lcnNbIFwiKlwiIF0gKSxcblx0XHRpbmRleCA9IDAsXG5cdFx0bGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGg7XG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0aWYgKCAoIHR3ZWVuID0gY29sbGVjdGlvblsgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIHByb3AsIHZhbHVlICkgKSApIHtcblxuXHRcdFx0Ly8gV2UncmUgZG9uZSB3aXRoIHRoaXMgcHJvcGVydHlcblx0XHRcdHJldHVybiB0d2Vlbjtcblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gZGVmYXVsdFByZWZpbHRlciggZWxlbSwgcHJvcHMsIG9wdHMgKSB7XG5cdHZhciBwcm9wLCB2YWx1ZSwgdG9nZ2xlLCBob29rcywgb2xkZmlyZSwgcHJvcFR3ZWVuLCByZXN0b3JlRGlzcGxheSwgZGlzcGxheSxcblx0XHRpc0JveCA9IFwid2lkdGhcIiBpbiBwcm9wcyB8fCBcImhlaWdodFwiIGluIHByb3BzLFxuXHRcdGFuaW0gPSB0aGlzLFxuXHRcdG9yaWcgPSB7fSxcblx0XHRzdHlsZSA9IGVsZW0uc3R5bGUsXG5cdFx0aGlkZGVuID0gZWxlbS5ub2RlVHlwZSAmJiBpc0hpZGRlbldpdGhpblRyZWUoIGVsZW0gKSxcblx0XHRkYXRhU2hvdyA9IGRhdGFQcml2LmdldCggZWxlbSwgXCJmeHNob3dcIiApO1xuXG5cdC8vIFF1ZXVlLXNraXBwaW5nIGFuaW1hdGlvbnMgaGlqYWNrIHRoZSBmeCBob29rc1xuXHRpZiAoICFvcHRzLnF1ZXVlICkge1xuXHRcdGhvb2tzID0galF1ZXJ5Ll9xdWV1ZUhvb2tzKCBlbGVtLCBcImZ4XCIgKTtcblx0XHRpZiAoIGhvb2tzLnVucXVldWVkID09IG51bGwgKSB7XG5cdFx0XHRob29rcy51bnF1ZXVlZCA9IDA7XG5cdFx0XHRvbGRmaXJlID0gaG9va3MuZW1wdHkuZmlyZTtcblx0XHRcdGhvb2tzLmVtcHR5LmZpcmUgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCAhaG9va3MudW5xdWV1ZWQgKSB7XG5cdFx0XHRcdFx0b2xkZmlyZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdH1cblx0XHRob29rcy51bnF1ZXVlZCsrO1xuXG5cdFx0YW5pbS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBFbnN1cmUgdGhlIGNvbXBsZXRlIGhhbmRsZXIgaXMgY2FsbGVkIGJlZm9yZSB0aGlzIGNvbXBsZXRlc1xuXHRcdFx0YW5pbS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRob29rcy51bnF1ZXVlZC0tO1xuXHRcdFx0XHRpZiAoICFqUXVlcnkucXVldWUoIGVsZW0sIFwiZnhcIiApLmxlbmd0aCApIHtcblx0XHRcdFx0XHRob29rcy5lbXB0eS5maXJlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0XHR9ICk7XG5cdH1cblxuXHQvLyBEZXRlY3Qgc2hvdy9oaWRlIGFuaW1hdGlvbnNcblx0Zm9yICggcHJvcCBpbiBwcm9wcyApIHtcblx0XHR2YWx1ZSA9IHByb3BzWyBwcm9wIF07XG5cdFx0aWYgKCByZnh0eXBlcy50ZXN0KCB2YWx1ZSApICkge1xuXHRcdFx0ZGVsZXRlIHByb3BzWyBwcm9wIF07XG5cdFx0XHR0b2dnbGUgPSB0b2dnbGUgfHwgdmFsdWUgPT09IFwidG9nZ2xlXCI7XG5cdFx0XHRpZiAoIHZhbHVlID09PSAoIGhpZGRlbiA/IFwiaGlkZVwiIDogXCJzaG93XCIgKSApIHtcblxuXHRcdFx0XHQvLyBQcmV0ZW5kIHRvIGJlIGhpZGRlbiBpZiB0aGlzIGlzIGEgXCJzaG93XCIgYW5kXG5cdFx0XHRcdC8vIHRoZXJlIGlzIHN0aWxsIGRhdGEgZnJvbSBhIHN0b3BwZWQgc2hvdy9oaWRlXG5cdFx0XHRcdGlmICggdmFsdWUgPT09IFwic2hvd1wiICYmIGRhdGFTaG93ICYmIGRhdGFTaG93WyBwcm9wIF0gIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRoaWRkZW4gPSB0cnVlO1xuXG5cdFx0XHRcdC8vIElnbm9yZSBhbGwgb3RoZXIgbm8tb3Agc2hvdy9oaWRlIGRhdGFcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0b3JpZ1sgcHJvcCBdID0gZGF0YVNob3cgJiYgZGF0YVNob3dbIHByb3AgXSB8fCBqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBCYWlsIG91dCBpZiB0aGlzIGlzIGEgbm8tb3AgbGlrZSAuaGlkZSgpLmhpZGUoKVxuXHRwcm9wVHdlZW4gPSAhalF1ZXJ5LmlzRW1wdHlPYmplY3QoIHByb3BzICk7XG5cdGlmICggIXByb3BUd2VlbiAmJiBqUXVlcnkuaXNFbXB0eU9iamVjdCggb3JpZyApICkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIFJlc3RyaWN0IFwib3ZlcmZsb3dcIiBhbmQgXCJkaXNwbGF5XCIgc3R5bGVzIGR1cmluZyBib3ggYW5pbWF0aW9uc1xuXHRpZiAoIGlzQm94ICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSwgRWRnZSAxMiAtIDE1XG5cdFx0Ly8gUmVjb3JkIGFsbCAzIG92ZXJmbG93IGF0dHJpYnV0ZXMgYmVjYXVzZSBJRSBkb2VzIG5vdCBpbmZlciB0aGUgc2hvcnRoYW5kXG5cdFx0Ly8gZnJvbSBpZGVudGljYWxseS12YWx1ZWQgb3ZlcmZsb3dYIGFuZCBvdmVyZmxvd1kgYW5kIEVkZ2UganVzdCBtaXJyb3JzXG5cdFx0Ly8gdGhlIG92ZXJmbG93WCB2YWx1ZSB0aGVyZS5cblx0XHRvcHRzLm92ZXJmbG93ID0gWyBzdHlsZS5vdmVyZmxvdywgc3R5bGUub3ZlcmZsb3dYLCBzdHlsZS5vdmVyZmxvd1kgXTtcblxuXHRcdC8vIElkZW50aWZ5IGEgZGlzcGxheSB0eXBlLCBwcmVmZXJyaW5nIG9sZCBzaG93L2hpZGUgZGF0YSBvdmVyIHRoZSBDU1MgY2FzY2FkZVxuXHRcdHJlc3RvcmVEaXNwbGF5ID0gZGF0YVNob3cgJiYgZGF0YVNob3cuZGlzcGxheTtcblx0XHRpZiAoIHJlc3RvcmVEaXNwbGF5ID09IG51bGwgKSB7XG5cdFx0XHRyZXN0b3JlRGlzcGxheSA9IGRhdGFQcml2LmdldCggZWxlbSwgXCJkaXNwbGF5XCIgKTtcblx0XHR9XG5cdFx0ZGlzcGxheSA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICk7XG5cdFx0aWYgKCBkaXNwbGF5ID09PSBcIm5vbmVcIiApIHtcblx0XHRcdGlmICggcmVzdG9yZURpc3BsYXkgKSB7XG5cdFx0XHRcdGRpc3BsYXkgPSByZXN0b3JlRGlzcGxheTtcblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gR2V0IG5vbmVtcHR5IHZhbHVlKHMpIGJ5IHRlbXBvcmFyaWx5IGZvcmNpbmcgdmlzaWJpbGl0eVxuXHRcdFx0XHRzaG93SGlkZSggWyBlbGVtIF0sIHRydWUgKTtcblx0XHRcdFx0cmVzdG9yZURpc3BsYXkgPSBlbGVtLnN0eWxlLmRpc3BsYXkgfHwgcmVzdG9yZURpc3BsYXk7XG5cdFx0XHRcdGRpc3BsYXkgPSBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApO1xuXHRcdFx0XHRzaG93SGlkZSggWyBlbGVtIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBBbmltYXRlIGlubGluZSBlbGVtZW50cyBhcyBpbmxpbmUtYmxvY2tcblx0XHRpZiAoIGRpc3BsYXkgPT09IFwiaW5saW5lXCIgfHwgZGlzcGxheSA9PT0gXCJpbmxpbmUtYmxvY2tcIiAmJiByZXN0b3JlRGlzcGxheSAhPSBudWxsICkge1xuXHRcdFx0aWYgKCBqUXVlcnkuY3NzKCBlbGVtLCBcImZsb2F0XCIgKSA9PT0gXCJub25lXCIgKSB7XG5cblx0XHRcdFx0Ly8gUmVzdG9yZSB0aGUgb3JpZ2luYWwgZGlzcGxheSB2YWx1ZSBhdCB0aGUgZW5kIG9mIHB1cmUgc2hvdy9oaWRlIGFuaW1hdGlvbnNcblx0XHRcdFx0aWYgKCAhcHJvcFR3ZWVuICkge1xuXHRcdFx0XHRcdGFuaW0uZG9uZSggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRzdHlsZS5kaXNwbGF5ID0gcmVzdG9yZURpc3BsYXk7XG5cdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdGlmICggcmVzdG9yZURpc3BsYXkgPT0gbnVsbCApIHtcblx0XHRcdFx0XHRcdGRpc3BsYXkgPSBzdHlsZS5kaXNwbGF5O1xuXHRcdFx0XHRcdFx0cmVzdG9yZURpc3BsYXkgPSBkaXNwbGF5ID09PSBcIm5vbmVcIiA/IFwiXCIgOiBkaXNwbGF5O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRzdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIjtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRpZiAoIG9wdHMub3ZlcmZsb3cgKSB7XG5cdFx0c3R5bGUub3ZlcmZsb3cgPSBcImhpZGRlblwiO1xuXHRcdGFuaW0uYWx3YXlzKCBmdW5jdGlvbigpIHtcblx0XHRcdHN0eWxlLm92ZXJmbG93ID0gb3B0cy5vdmVyZmxvd1sgMCBdO1xuXHRcdFx0c3R5bGUub3ZlcmZsb3dYID0gb3B0cy5vdmVyZmxvd1sgMSBdO1xuXHRcdFx0c3R5bGUub3ZlcmZsb3dZID0gb3B0cy5vdmVyZmxvd1sgMiBdO1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIEltcGxlbWVudCBzaG93L2hpZGUgYW5pbWF0aW9uc1xuXHRwcm9wVHdlZW4gPSBmYWxzZTtcblx0Zm9yICggcHJvcCBpbiBvcmlnICkge1xuXG5cdFx0Ly8gR2VuZXJhbCBzaG93L2hpZGUgc2V0dXAgZm9yIHRoaXMgZWxlbWVudCBhbmltYXRpb25cblx0XHRpZiAoICFwcm9wVHdlZW4gKSB7XG5cdFx0XHRpZiAoIGRhdGFTaG93ICkge1xuXHRcdFx0XHRpZiAoIFwiaGlkZGVuXCIgaW4gZGF0YVNob3cgKSB7XG5cdFx0XHRcdFx0aGlkZGVuID0gZGF0YVNob3cuaGlkZGVuO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRkYXRhU2hvdyA9IGRhdGFQcml2LmFjY2VzcyggZWxlbSwgXCJmeHNob3dcIiwgeyBkaXNwbGF5OiByZXN0b3JlRGlzcGxheSB9ICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0b3JlIGhpZGRlbi92aXNpYmxlIGZvciB0b2dnbGUgc28gYC5zdG9wKCkudG9nZ2xlKClgIFwicmV2ZXJzZXNcIlxuXHRcdFx0aWYgKCB0b2dnbGUgKSB7XG5cdFx0XHRcdGRhdGFTaG93LmhpZGRlbiA9ICFoaWRkZW47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNob3cgZWxlbWVudHMgYmVmb3JlIGFuaW1hdGluZyB0aGVtXG5cdFx0XHRpZiAoIGhpZGRlbiApIHtcblx0XHRcdFx0c2hvd0hpZGUoIFsgZWxlbSBdLCB0cnVlICk7XG5cdFx0XHR9XG5cblx0XHRcdC8qIGVzbGludC1kaXNhYmxlIG5vLWxvb3AtZnVuYyAqL1xuXG5cdFx0XHRhbmltLmRvbmUoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdC8qIGVzbGludC1lbmFibGUgbm8tbG9vcC1mdW5jICovXG5cblx0XHRcdFx0Ly8gVGhlIGZpbmFsIHN0ZXAgb2YgYSBcImhpZGVcIiBhbmltYXRpb24gaXMgYWN0dWFsbHkgaGlkaW5nIHRoZSBlbGVtZW50XG5cdFx0XHRcdGlmICggIWhpZGRlbiApIHtcblx0XHRcdFx0XHRzaG93SGlkZSggWyBlbGVtIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIFwiZnhzaG93XCIgKTtcblx0XHRcdFx0Zm9yICggcHJvcCBpbiBvcmlnICkge1xuXHRcdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCwgb3JpZ1sgcHJvcCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHQvLyBQZXItcHJvcGVydHkgc2V0dXBcblx0XHRwcm9wVHdlZW4gPSBjcmVhdGVUd2VlbiggaGlkZGVuID8gZGF0YVNob3dbIHByb3AgXSA6IDAsIHByb3AsIGFuaW0gKTtcblx0XHRpZiAoICEoIHByb3AgaW4gZGF0YVNob3cgKSApIHtcblx0XHRcdGRhdGFTaG93WyBwcm9wIF0gPSBwcm9wVHdlZW4uc3RhcnQ7XG5cdFx0XHRpZiAoIGhpZGRlbiApIHtcblx0XHRcdFx0cHJvcFR3ZWVuLmVuZCA9IHByb3BUd2Vlbi5zdGFydDtcblx0XHRcdFx0cHJvcFR3ZWVuLnN0YXJ0ID0gMDtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gcHJvcEZpbHRlciggcHJvcHMsIHNwZWNpYWxFYXNpbmcgKSB7XG5cdHZhciBpbmRleCwgbmFtZSwgZWFzaW5nLCB2YWx1ZSwgaG9va3M7XG5cblx0Ly8gY2FtZWxDYXNlLCBzcGVjaWFsRWFzaW5nIGFuZCBleHBhbmQgY3NzSG9vayBwYXNzXG5cdGZvciAoIGluZGV4IGluIHByb3BzICkge1xuXHRcdG5hbWUgPSBjYW1lbENhc2UoIGluZGV4ICk7XG5cdFx0ZWFzaW5nID0gc3BlY2lhbEVhc2luZ1sgbmFtZSBdO1xuXHRcdHZhbHVlID0gcHJvcHNbIGluZGV4IF07XG5cdFx0aWYgKCBBcnJheS5pc0FycmF5KCB2YWx1ZSApICkge1xuXHRcdFx0ZWFzaW5nID0gdmFsdWVbIDEgXTtcblx0XHRcdHZhbHVlID0gcHJvcHNbIGluZGV4IF0gPSB2YWx1ZVsgMCBdO1xuXHRcdH1cblxuXHRcdGlmICggaW5kZXggIT09IG5hbWUgKSB7XG5cdFx0XHRwcm9wc1sgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHRkZWxldGUgcHJvcHNbIGluZGV4IF07XG5cdFx0fVxuXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXTtcblx0XHRpZiAoIGhvb2tzICYmIFwiZXhwYW5kXCIgaW4gaG9va3MgKSB7XG5cdFx0XHR2YWx1ZSA9IGhvb2tzLmV4cGFuZCggdmFsdWUgKTtcblx0XHRcdGRlbGV0ZSBwcm9wc1sgbmFtZSBdO1xuXG5cdFx0XHQvLyBOb3QgcXVpdGUgJC5leHRlbmQsIHRoaXMgd29uJ3Qgb3ZlcndyaXRlIGV4aXN0aW5nIGtleXMuXG5cdFx0XHQvLyBSZXVzaW5nICdpbmRleCcgYmVjYXVzZSB3ZSBoYXZlIHRoZSBjb3JyZWN0IFwibmFtZVwiXG5cdFx0XHRmb3IgKCBpbmRleCBpbiB2YWx1ZSApIHtcblx0XHRcdFx0aWYgKCAhKCBpbmRleCBpbiBwcm9wcyApICkge1xuXHRcdFx0XHRcdHByb3BzWyBpbmRleCBdID0gdmFsdWVbIGluZGV4IF07XG5cdFx0XHRcdFx0c3BlY2lhbEVhc2luZ1sgaW5kZXggXSA9IGVhc2luZztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRzcGVjaWFsRWFzaW5nWyBuYW1lIF0gPSBlYXNpbmc7XG5cdFx0fVxuXHR9XG59XG5cbmZ1bmN0aW9uIEFuaW1hdGlvbiggZWxlbSwgcHJvcGVydGllcywgb3B0aW9ucyApIHtcblx0dmFyIHJlc3VsdCxcblx0XHRzdG9wcGVkLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBBbmltYXRpb24ucHJlZmlsdGVycy5sZW5ndGgsXG5cdFx0ZGVmZXJyZWQgPSBqUXVlcnkuRGVmZXJyZWQoKS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBEb24ndCBtYXRjaCBlbGVtIGluIHRoZSA6YW5pbWF0ZWQgc2VsZWN0b3Jcblx0XHRcdGRlbGV0ZSB0aWNrLmVsZW07XG5cdFx0fSApLFxuXHRcdHRpY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggc3RvcHBlZCApIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0dmFyIGN1cnJlbnRUaW1lID0gZnhOb3cgfHwgY3JlYXRlRnhOb3coKSxcblx0XHRcdFx0cmVtYWluaW5nID0gTWF0aC5tYXgoIDAsIGFuaW1hdGlvbi5zdGFydFRpbWUgKyBhbmltYXRpb24uZHVyYXRpb24gLSBjdXJyZW50VGltZSApLFxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgMi4zIG9ubHlcblx0XHRcdFx0Ly8gQXJjaGFpYyBjcmFzaCBidWcgd29uJ3QgYWxsb3cgdXMgdG8gdXNlIGAxIC0gKCAwLjUgfHwgMCApYCAoIzEyNDk3KVxuXHRcdFx0XHR0ZW1wID0gcmVtYWluaW5nIC8gYW5pbWF0aW9uLmR1cmF0aW9uIHx8IDAsXG5cdFx0XHRcdHBlcmNlbnQgPSAxIC0gdGVtcCxcblx0XHRcdFx0aW5kZXggPSAwLFxuXHRcdFx0XHRsZW5ndGggPSBhbmltYXRpb24udHdlZW5zLmxlbmd0aDtcblxuXHRcdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVuc1sgaW5kZXggXS5ydW4oIHBlcmNlbnQgKTtcblx0XHRcdH1cblxuXHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIHBlcmNlbnQsIHJlbWFpbmluZyBdICk7XG5cblx0XHRcdC8vIElmIHRoZXJlJ3MgbW9yZSB0byBkbywgeWllbGRcblx0XHRcdGlmICggcGVyY2VudCA8IDEgJiYgbGVuZ3RoICkge1xuXHRcdFx0XHRyZXR1cm4gcmVtYWluaW5nO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiB0aGlzIHdhcyBhbiBlbXB0eSBhbmltYXRpb24sIHN5bnRoZXNpemUgYSBmaW5hbCBwcm9ncmVzcyBub3RpZmljYXRpb25cblx0XHRcdGlmICggIWxlbmd0aCApIHtcblx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIDEsIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXNvbHZlIHRoZSBhbmltYXRpb24gYW5kIHJlcG9ydCBpdHMgY29uY2x1c2lvblxuXHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uIF0gKTtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdGFuaW1hdGlvbiA9IGRlZmVycmVkLnByb21pc2UoIHtcblx0XHRcdGVsZW06IGVsZW0sXG5cdFx0XHRwcm9wczogalF1ZXJ5LmV4dGVuZCgge30sIHByb3BlcnRpZXMgKSxcblx0XHRcdG9wdHM6IGpRdWVyeS5leHRlbmQoIHRydWUsIHtcblx0XHRcdFx0c3BlY2lhbEVhc2luZzoge30sXG5cdFx0XHRcdGVhc2luZzogalF1ZXJ5LmVhc2luZy5fZGVmYXVsdFxuXHRcdFx0fSwgb3B0aW9ucyApLFxuXHRcdFx0b3JpZ2luYWxQcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzLFxuXHRcdFx0b3JpZ2luYWxPcHRpb25zOiBvcHRpb25zLFxuXHRcdFx0c3RhcnRUaW1lOiBmeE5vdyB8fCBjcmVhdGVGeE5vdygpLFxuXHRcdFx0ZHVyYXRpb246IG9wdGlvbnMuZHVyYXRpb24sXG5cdFx0XHR0d2VlbnM6IFtdLFxuXHRcdFx0Y3JlYXRlVHdlZW46IGZ1bmN0aW9uKCBwcm9wLCBlbmQgKSB7XG5cdFx0XHRcdHZhciB0d2VlbiA9IGpRdWVyeS5Ud2VlbiggZWxlbSwgYW5pbWF0aW9uLm9wdHMsIHByb3AsIGVuZCxcblx0XHRcdFx0XHRhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nWyBwcm9wIF0gfHwgYW5pbWF0aW9uLm9wdHMuZWFzaW5nICk7XG5cdFx0XHRcdGFuaW1hdGlvbi50d2VlbnMucHVzaCggdHdlZW4gKTtcblx0XHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdFx0fSxcblx0XHRcdHN0b3A6IGZ1bmN0aW9uKCBnb3RvRW5kICkge1xuXHRcdFx0XHR2YXIgaW5kZXggPSAwLFxuXG5cdFx0XHRcdFx0Ly8gSWYgd2UgYXJlIGdvaW5nIHRvIHRoZSBlbmQsIHdlIHdhbnQgdG8gcnVuIGFsbCB0aGUgdHdlZW5zXG5cdFx0XHRcdFx0Ly8gb3RoZXJ3aXNlIHdlIHNraXAgdGhpcyBwYXJ0XG5cdFx0XHRcdFx0bGVuZ3RoID0gZ290b0VuZCA/IGFuaW1hdGlvbi50d2VlbnMubGVuZ3RoIDogMDtcblx0XHRcdFx0aWYgKCBzdG9wcGVkICkge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHN0b3BwZWQgPSB0cnVlO1xuXHRcdFx0XHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdFx0XHRcdGFuaW1hdGlvbi50d2VlbnNbIGluZGV4IF0ucnVuKCAxICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBSZXNvbHZlIHdoZW4gd2UgcGxheWVkIHRoZSBsYXN0IGZyYW1lOyBvdGhlcndpc2UsIHJlamVjdFxuXHRcdFx0XHRpZiAoIGdvdG9FbmQgKSB7XG5cdFx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIDEsIDAgXSApO1xuXHRcdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgZ290b0VuZCBdICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZGVmZXJyZWQucmVqZWN0V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIGdvdG9FbmQgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fVxuXHRcdH0gKSxcblx0XHRwcm9wcyA9IGFuaW1hdGlvbi5wcm9wcztcblxuXHRwcm9wRmlsdGVyKCBwcm9wcywgYW5pbWF0aW9uLm9wdHMuc3BlY2lhbEVhc2luZyApO1xuXG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0cmVzdWx0ID0gQW5pbWF0aW9uLnByZWZpbHRlcnNbIGluZGV4IF0uY2FsbCggYW5pbWF0aW9uLCBlbGVtLCBwcm9wcywgYW5pbWF0aW9uLm9wdHMgKTtcblx0XHRpZiAoIHJlc3VsdCApIHtcblx0XHRcdGlmICggaXNGdW5jdGlvbiggcmVzdWx0LnN0b3AgKSApIHtcblx0XHRcdFx0alF1ZXJ5Ll9xdWV1ZUhvb2tzKCBhbmltYXRpb24uZWxlbSwgYW5pbWF0aW9uLm9wdHMucXVldWUgKS5zdG9wID1cblx0XHRcdFx0XHRyZXN1bHQuc3RvcC5iaW5kKCByZXN1bHQgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXHR9XG5cblx0alF1ZXJ5Lm1hcCggcHJvcHMsIGNyZWF0ZVR3ZWVuLCBhbmltYXRpb24gKTtcblxuXHRpZiAoIGlzRnVuY3Rpb24oIGFuaW1hdGlvbi5vcHRzLnN0YXJ0ICkgKSB7XG5cdFx0YW5pbWF0aW9uLm9wdHMuc3RhcnQuY2FsbCggZWxlbSwgYW5pbWF0aW9uICk7XG5cdH1cblxuXHQvLyBBdHRhY2ggY2FsbGJhY2tzIGZyb20gb3B0aW9uc1xuXHRhbmltYXRpb25cblx0XHQucHJvZ3Jlc3MoIGFuaW1hdGlvbi5vcHRzLnByb2dyZXNzIClcblx0XHQuZG9uZSggYW5pbWF0aW9uLm9wdHMuZG9uZSwgYW5pbWF0aW9uLm9wdHMuY29tcGxldGUgKVxuXHRcdC5mYWlsKCBhbmltYXRpb24ub3B0cy5mYWlsIClcblx0XHQuYWx3YXlzKCBhbmltYXRpb24ub3B0cy5hbHdheXMgKTtcblxuXHRqUXVlcnkuZngudGltZXIoXG5cdFx0alF1ZXJ5LmV4dGVuZCggdGljaywge1xuXHRcdFx0ZWxlbTogZWxlbSxcblx0XHRcdGFuaW06IGFuaW1hdGlvbixcblx0XHRcdHF1ZXVlOiBhbmltYXRpb24ub3B0cy5xdWV1ZVxuXHRcdH0gKVxuXHQpO1xuXG5cdHJldHVybiBhbmltYXRpb247XG59XG5cbmpRdWVyeS5BbmltYXRpb24gPSBqUXVlcnkuZXh0ZW5kKCBBbmltYXRpb24sIHtcblxuXHR0d2VlbmVyczoge1xuXHRcdFwiKlwiOiBbIGZ1bmN0aW9uKCBwcm9wLCB2YWx1ZSApIHtcblx0XHRcdHZhciB0d2VlbiA9IHRoaXMuY3JlYXRlVHdlZW4oIHByb3AsIHZhbHVlICk7XG5cdFx0XHRhZGp1c3RDU1MoIHR3ZWVuLmVsZW0sIHByb3AsIHJjc3NOdW0uZXhlYyggdmFsdWUgKSwgdHdlZW4gKTtcblx0XHRcdHJldHVybiB0d2Vlbjtcblx0XHR9IF1cblx0fSxcblxuXHR0d2VlbmVyOiBmdW5jdGlvbiggcHJvcHMsIGNhbGxiYWNrICkge1xuXHRcdGlmICggaXNGdW5jdGlvbiggcHJvcHMgKSApIHtcblx0XHRcdGNhbGxiYWNrID0gcHJvcHM7XG5cdFx0XHRwcm9wcyA9IFsgXCIqXCIgXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cHJvcHMgPSBwcm9wcy5tYXRjaCggcm5vdGh0bWx3aGl0ZSApO1xuXHRcdH1cblxuXHRcdHZhciBwcm9wLFxuXHRcdFx0aW5kZXggPSAwLFxuXHRcdFx0bGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG5cdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdHByb3AgPSBwcm9wc1sgaW5kZXggXTtcblx0XHRcdEFuaW1hdGlvbi50d2VlbmVyc1sgcHJvcCBdID0gQW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0gfHwgW107XG5cdFx0XHRBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXS51bnNoaWZ0KCBjYWxsYmFjayApO1xuXHRcdH1cblx0fSxcblxuXHRwcmVmaWx0ZXJzOiBbIGRlZmF1bHRQcmVmaWx0ZXIgXSxcblxuXHRwcmVmaWx0ZXI6IGZ1bmN0aW9uKCBjYWxsYmFjaywgcHJlcGVuZCApIHtcblx0XHRpZiAoIHByZXBlbmQgKSB7XG5cdFx0XHRBbmltYXRpb24ucHJlZmlsdGVycy51bnNoaWZ0KCBjYWxsYmFjayApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRBbmltYXRpb24ucHJlZmlsdGVycy5wdXNoKCBjYWxsYmFjayApO1xuXHRcdH1cblx0fVxufSApO1xuXG5qUXVlcnkuc3BlZWQgPSBmdW5jdGlvbiggc3BlZWQsIGVhc2luZywgZm4gKSB7XG5cdHZhciBvcHQgPSBzcGVlZCAmJiB0eXBlb2Ygc3BlZWQgPT09IFwib2JqZWN0XCIgPyBqUXVlcnkuZXh0ZW5kKCB7fSwgc3BlZWQgKSA6IHtcblx0XHRjb21wbGV0ZTogZm4gfHwgIWZuICYmIGVhc2luZyB8fFxuXHRcdFx0aXNGdW5jdGlvbiggc3BlZWQgKSAmJiBzcGVlZCxcblx0XHRkdXJhdGlvbjogc3BlZWQsXG5cdFx0ZWFzaW5nOiBmbiAmJiBlYXNpbmcgfHwgZWFzaW5nICYmICFpc0Z1bmN0aW9uKCBlYXNpbmcgKSAmJiBlYXNpbmdcblx0fTtcblxuXHQvLyBHbyB0byB0aGUgZW5kIHN0YXRlIGlmIGZ4IGFyZSBvZmZcblx0aWYgKCBqUXVlcnkuZngub2ZmICkge1xuXHRcdG9wdC5kdXJhdGlvbiA9IDA7XG5cblx0fSBlbHNlIHtcblx0XHRpZiAoIHR5cGVvZiBvcHQuZHVyYXRpb24gIT09IFwibnVtYmVyXCIgKSB7XG5cdFx0XHRpZiAoIG9wdC5kdXJhdGlvbiBpbiBqUXVlcnkuZnguc3BlZWRzICkge1xuXHRcdFx0XHRvcHQuZHVyYXRpb24gPSBqUXVlcnkuZnguc3BlZWRzWyBvcHQuZHVyYXRpb24gXTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0b3B0LmR1cmF0aW9uID0galF1ZXJ5LmZ4LnNwZWVkcy5fZGVmYXVsdDtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBOb3JtYWxpemUgb3B0LnF1ZXVlIC0gdHJ1ZS91bmRlZmluZWQvbnVsbCAtPiBcImZ4XCJcblx0aWYgKCBvcHQucXVldWUgPT0gbnVsbCB8fCBvcHQucXVldWUgPT09IHRydWUgKSB7XG5cdFx0b3B0LnF1ZXVlID0gXCJmeFwiO1xuXHR9XG5cblx0Ly8gUXVldWVpbmdcblx0b3B0Lm9sZCA9IG9wdC5jb21wbGV0ZTtcblxuXHRvcHQuY29tcGxldGUgPSBmdW5jdGlvbigpIHtcblx0XHRpZiAoIGlzRnVuY3Rpb24oIG9wdC5vbGQgKSApIHtcblx0XHRcdG9wdC5vbGQuY2FsbCggdGhpcyApO1xuXHRcdH1cblxuXHRcdGlmICggb3B0LnF1ZXVlICkge1xuXHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIG9wdC5xdWV1ZSApO1xuXHRcdH1cblx0fTtcblxuXHRyZXR1cm4gb3B0O1xufTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRmYWRlVG86IGZ1bmN0aW9uKCBzcGVlZCwgdG8sIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cblx0XHQvLyBTaG93IGFueSBoaWRkZW4gZWxlbWVudHMgYWZ0ZXIgc2V0dGluZyBvcGFjaXR5IHRvIDBcblx0XHRyZXR1cm4gdGhpcy5maWx0ZXIoIGlzSGlkZGVuV2l0aGluVHJlZSApLmNzcyggXCJvcGFjaXR5XCIsIDAgKS5zaG93KClcblxuXHRcdFx0Ly8gQW5pbWF0ZSB0byB0aGUgdmFsdWUgc3BlY2lmaWVkXG5cdFx0XHQuZW5kKCkuYW5pbWF0ZSggeyBvcGFjaXR5OiB0byB9LCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9LFxuXHRhbmltYXRlOiBmdW5jdGlvbiggcHJvcCwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cdFx0dmFyIGVtcHR5ID0galF1ZXJ5LmlzRW1wdHlPYmplY3QoIHByb3AgKSxcblx0XHRcdG9wdGFsbCA9IGpRdWVyeS5zcGVlZCggc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSxcblx0XHRcdGRvQW5pbWF0aW9uID0gZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0Ly8gT3BlcmF0ZSBvbiBhIGNvcHkgb2YgcHJvcCBzbyBwZXItcHJvcGVydHkgZWFzaW5nIHdvbid0IGJlIGxvc3Rcblx0XHRcdFx0dmFyIGFuaW0gPSBBbmltYXRpb24oIHRoaXMsIGpRdWVyeS5leHRlbmQoIHt9LCBwcm9wICksIG9wdGFsbCApO1xuXG5cdFx0XHRcdC8vIEVtcHR5IGFuaW1hdGlvbnMsIG9yIGZpbmlzaGluZyByZXNvbHZlcyBpbW1lZGlhdGVseVxuXHRcdFx0XHRpZiAoIGVtcHR5IHx8IGRhdGFQcml2LmdldCggdGhpcywgXCJmaW5pc2hcIiApICkge1xuXHRcdFx0XHRcdGFuaW0uc3RvcCggdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0ZG9BbmltYXRpb24uZmluaXNoID0gZG9BbmltYXRpb247XG5cblx0XHRyZXR1cm4gZW1wdHkgfHwgb3B0YWxsLnF1ZXVlID09PSBmYWxzZSA/XG5cdFx0XHR0aGlzLmVhY2goIGRvQW5pbWF0aW9uICkgOlxuXHRcdFx0dGhpcy5xdWV1ZSggb3B0YWxsLnF1ZXVlLCBkb0FuaW1hdGlvbiApO1xuXHR9LFxuXHRzdG9wOiBmdW5jdGlvbiggdHlwZSwgY2xlYXJRdWV1ZSwgZ290b0VuZCApIHtcblx0XHR2YXIgc3RvcFF1ZXVlID0gZnVuY3Rpb24oIGhvb2tzICkge1xuXHRcdFx0dmFyIHN0b3AgPSBob29rcy5zdG9wO1xuXHRcdFx0ZGVsZXRlIGhvb2tzLnN0b3A7XG5cdFx0XHRzdG9wKCBnb3RvRW5kICk7XG5cdFx0fTtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRnb3RvRW5kID0gY2xlYXJRdWV1ZTtcblx0XHRcdGNsZWFyUXVldWUgPSB0eXBlO1xuXHRcdFx0dHlwZSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0aWYgKCBjbGVhclF1ZXVlICkge1xuXHRcdFx0dGhpcy5xdWV1ZSggdHlwZSB8fCBcImZ4XCIsIFtdICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgZGVxdWV1ZSA9IHRydWUsXG5cdFx0XHRcdGluZGV4ID0gdHlwZSAhPSBudWxsICYmIHR5cGUgKyBcInF1ZXVlSG9va3NcIixcblx0XHRcdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycyxcblx0XHRcdFx0ZGF0YSA9IGRhdGFQcml2LmdldCggdGhpcyApO1xuXG5cdFx0XHRpZiAoIGluZGV4ICkge1xuXHRcdFx0XHRpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICkge1xuXHRcdFx0XHRcdHN0b3BRdWV1ZSggZGF0YVsgaW5kZXggXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmb3IgKCBpbmRleCBpbiBkYXRhICkge1xuXHRcdFx0XHRcdGlmICggZGF0YVsgaW5kZXggXSAmJiBkYXRhWyBpbmRleCBdLnN0b3AgJiYgcnJ1bi50ZXN0KCBpbmRleCApICkge1xuXHRcdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGZvciAoIGluZGV4ID0gdGltZXJzLmxlbmd0aDsgaW5kZXgtLTsgKSB7XG5cdFx0XHRcdGlmICggdGltZXJzWyBpbmRleCBdLmVsZW0gPT09IHRoaXMgJiZcblx0XHRcdFx0XHQoIHR5cGUgPT0gbnVsbCB8fCB0aW1lcnNbIGluZGV4IF0ucXVldWUgPT09IHR5cGUgKSApIHtcblxuXHRcdFx0XHRcdHRpbWVyc1sgaW5kZXggXS5hbmltLnN0b3AoIGdvdG9FbmQgKTtcblx0XHRcdFx0XHRkZXF1ZXVlID0gZmFsc2U7XG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdGFydCB0aGUgbmV4dCBpbiB0aGUgcXVldWUgaWYgdGhlIGxhc3Qgc3RlcCB3YXNuJ3QgZm9yY2VkLlxuXHRcdFx0Ly8gVGltZXJzIGN1cnJlbnRseSB3aWxsIGNhbGwgdGhlaXIgY29tcGxldGUgY2FsbGJhY2tzLCB3aGljaFxuXHRcdFx0Ly8gd2lsbCBkZXF1ZXVlIGJ1dCBvbmx5IGlmIHRoZXkgd2VyZSBnb3RvRW5kLlxuXHRcdFx0aWYgKCBkZXF1ZXVlIHx8ICFnb3RvRW5kICkge1xuXHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblx0ZmluaXNoOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRpZiAoIHR5cGUgIT09IGZhbHNlICkge1xuXHRcdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBpbmRleCxcblx0XHRcdFx0ZGF0YSA9IGRhdGFQcml2LmdldCggdGhpcyApLFxuXHRcdFx0XHRxdWV1ZSA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlXCIgXSxcblx0XHRcdFx0aG9va3MgPSBkYXRhWyB0eXBlICsgXCJxdWV1ZUhvb2tzXCIgXSxcblx0XHRcdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycyxcblx0XHRcdFx0bGVuZ3RoID0gcXVldWUgPyBxdWV1ZS5sZW5ndGggOiAwO1xuXG5cdFx0XHQvLyBFbmFibGUgZmluaXNoaW5nIGZsYWcgb24gcHJpdmF0ZSBkYXRhXG5cdFx0XHRkYXRhLmZpbmlzaCA9IHRydWU7XG5cblx0XHRcdC8vIEVtcHR5IHRoZSBxdWV1ZSBmaXJzdFxuXHRcdFx0alF1ZXJ5LnF1ZXVlKCB0aGlzLCB0eXBlLCBbXSApO1xuXG5cdFx0XHRpZiAoIGhvb2tzICYmIGhvb2tzLnN0b3AgKSB7XG5cdFx0XHRcdGhvb2tzLnN0b3AuY2FsbCggdGhpcywgdHJ1ZSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBMb29rIGZvciBhbnkgYWN0aXZlIGFuaW1hdGlvbnMsIGFuZCBmaW5pc2ggdGhlbVxuXHRcdFx0Zm9yICggaW5kZXggPSB0aW1lcnMubGVuZ3RoOyBpbmRleC0tOyApIHtcblx0XHRcdFx0aWYgKCB0aW1lcnNbIGluZGV4IF0uZWxlbSA9PT0gdGhpcyAmJiB0aW1lcnNbIGluZGV4IF0ucXVldWUgPT09IHR5cGUgKSB7XG5cdFx0XHRcdFx0dGltZXJzWyBpbmRleCBdLmFuaW0uc3RvcCggdHJ1ZSApO1xuXHRcdFx0XHRcdHRpbWVycy5zcGxpY2UoIGluZGV4LCAxICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gTG9vayBmb3IgYW55IGFuaW1hdGlvbnMgaW4gdGhlIG9sZCBxdWV1ZSBhbmQgZmluaXNoIHRoZW1cblx0XHRcdGZvciAoIGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0XHRcdGlmICggcXVldWVbIGluZGV4IF0gJiYgcXVldWVbIGluZGV4IF0uZmluaXNoICkge1xuXHRcdFx0XHRcdHF1ZXVlWyBpbmRleCBdLmZpbmlzaC5jYWxsKCB0aGlzICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gVHVybiBvZmYgZmluaXNoaW5nIGZsYWdcblx0XHRcdGRlbGV0ZSBkYXRhLmZpbmlzaDtcblx0XHR9ICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goIFsgXCJ0b2dnbGVcIiwgXCJzaG93XCIsIFwiaGlkZVwiIF0sIGZ1bmN0aW9uKCBfaSwgbmFtZSApIHtcblx0dmFyIGNzc0ZuID0galF1ZXJ5LmZuWyBuYW1lIF07XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBzcGVlZCA9PSBudWxsIHx8IHR5cGVvZiBzcGVlZCA9PT0gXCJib29sZWFuXCIgP1xuXHRcdFx0Y3NzRm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApIDpcblx0XHRcdHRoaXMuYW5pbWF0ZSggZ2VuRngoIG5hbWUsIHRydWUgKSwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcblx0fTtcbn0gKTtcblxuLy8gR2VuZXJhdGUgc2hvcnRjdXRzIGZvciBjdXN0b20gYW5pbWF0aW9uc1xualF1ZXJ5LmVhY2goIHtcblx0c2xpZGVEb3duOiBnZW5GeCggXCJzaG93XCIgKSxcblx0c2xpZGVVcDogZ2VuRngoIFwiaGlkZVwiICksXG5cdHNsaWRlVG9nZ2xlOiBnZW5GeCggXCJ0b2dnbGVcIiApLFxuXHRmYWRlSW46IHsgb3BhY2l0eTogXCJzaG93XCIgfSxcblx0ZmFkZU91dDogeyBvcGFjaXR5OiBcImhpZGVcIiB9LFxuXHRmYWRlVG9nZ2xlOiB7IG9wYWNpdHk6IFwidG9nZ2xlXCIgfVxufSwgZnVuY3Rpb24oIG5hbWUsIHByb3BzICkge1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4gdGhpcy5hbmltYXRlKCBwcm9wcywgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcblx0fTtcbn0gKTtcblxualF1ZXJ5LnRpbWVycyA9IFtdO1xualF1ZXJ5LmZ4LnRpY2sgPSBmdW5jdGlvbigpIHtcblx0dmFyIHRpbWVyLFxuXHRcdGkgPSAwLFxuXHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnM7XG5cblx0ZnhOb3cgPSBEYXRlLm5vdygpO1xuXG5cdGZvciAoIDsgaSA8IHRpbWVycy5sZW5ndGg7IGkrKyApIHtcblx0XHR0aW1lciA9IHRpbWVyc1sgaSBdO1xuXG5cdFx0Ly8gUnVuIHRoZSB0aW1lciBhbmQgc2FmZWx5IHJlbW92ZSBpdCB3aGVuIGRvbmUgKGFsbG93aW5nIGZvciBleHRlcm5hbCByZW1vdmFsKVxuXHRcdGlmICggIXRpbWVyKCkgJiYgdGltZXJzWyBpIF0gPT09IHRpbWVyICkge1xuXHRcdFx0dGltZXJzLnNwbGljZSggaS0tLCAxICk7XG5cdFx0fVxuXHR9XG5cblx0aWYgKCAhdGltZXJzLmxlbmd0aCApIHtcblx0XHRqUXVlcnkuZnguc3RvcCgpO1xuXHR9XG5cdGZ4Tm93ID0gdW5kZWZpbmVkO1xufTtcblxualF1ZXJ5LmZ4LnRpbWVyID0gZnVuY3Rpb24oIHRpbWVyICkge1xuXHRqUXVlcnkudGltZXJzLnB1c2goIHRpbWVyICk7XG5cdGpRdWVyeS5meC5zdGFydCgpO1xufTtcblxualF1ZXJ5LmZ4LmludGVydmFsID0gMTM7XG5qUXVlcnkuZnguc3RhcnQgPSBmdW5jdGlvbigpIHtcblx0aWYgKCBpblByb2dyZXNzICkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGluUHJvZ3Jlc3MgPSB0cnVlO1xuXHRzY2hlZHVsZSgpO1xufTtcblxualF1ZXJ5LmZ4LnN0b3AgPSBmdW5jdGlvbigpIHtcblx0aW5Qcm9ncmVzcyA9IG51bGw7XG59O1xuXG5qUXVlcnkuZnguc3BlZWRzID0ge1xuXHRzbG93OiA2MDAsXG5cdGZhc3Q6IDIwMCxcblxuXHQvLyBEZWZhdWx0IHNwZWVkXG5cdF9kZWZhdWx0OiA0MDBcbn07XG5cblxuLy8gQmFzZWQgb2ZmIG9mIHRoZSBwbHVnaW4gYnkgQ2xpbnQgSGVsZmVycywgd2l0aCBwZXJtaXNzaW9uLlxuLy8gaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTAwMzI0MDE0NzQ3L2h0dHA6Ly9ibGluZHNpZ25hbHMuY29tL2luZGV4LnBocC8yMDA5LzA3L2pxdWVyeS1kZWxheS9cbmpRdWVyeS5mbi5kZWxheSA9IGZ1bmN0aW9uKCB0aW1lLCB0eXBlICkge1xuXHR0aW1lID0galF1ZXJ5LmZ4ID8galF1ZXJ5LmZ4LnNwZWVkc1sgdGltZSBdIHx8IHRpbWUgOiB0aW1lO1xuXHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cblx0cmV0dXJuIHRoaXMucXVldWUoIHR5cGUsIGZ1bmN0aW9uKCBuZXh0LCBob29rcyApIHtcblx0XHR2YXIgdGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCBuZXh0LCB0aW1lICk7XG5cdFx0aG9va3Muc3RvcCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0d2luZG93LmNsZWFyVGltZW91dCggdGltZW91dCApO1xuXHRcdH07XG5cdH0gKTtcbn07XG5cblxuKCBmdW5jdGlvbigpIHtcblx0dmFyIGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICksXG5cdFx0c2VsZWN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJzZWxlY3RcIiApLFxuXHRcdG9wdCA9IHNlbGVjdC5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJvcHRpb25cIiApICk7XG5cblx0aW5wdXQudHlwZSA9IFwiY2hlY2tib3hcIjtcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4zIG9ubHlcblx0Ly8gRGVmYXVsdCB2YWx1ZSBmb3IgYSBjaGVja2JveCBzaG91bGQgYmUgXCJvblwiXG5cdHN1cHBvcnQuY2hlY2tPbiA9IGlucHV0LnZhbHVlICE9PSBcIlwiO1xuXG5cdC8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxuXHQvLyBNdXN0IGFjY2VzcyBzZWxlY3RlZEluZGV4IHRvIG1ha2UgZGVmYXVsdCBvcHRpb25zIHNlbGVjdFxuXHRzdXBwb3J0Lm9wdFNlbGVjdGVkID0gb3B0LnNlbGVjdGVkO1xuXG5cdC8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxuXHQvLyBBbiBpbnB1dCBsb3NlcyBpdHMgdmFsdWUgYWZ0ZXIgYmVjb21pbmcgYSByYWRpb1xuXHRpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApO1xuXHRpbnB1dC52YWx1ZSA9IFwidFwiO1xuXHRpbnB1dC50eXBlID0gXCJyYWRpb1wiO1xuXHRzdXBwb3J0LnJhZGlvVmFsdWUgPSBpbnB1dC52YWx1ZSA9PT0gXCJ0XCI7XG59ICkoKTtcblxuXG52YXIgYm9vbEhvb2ssXG5cdGF0dHJIYW5kbGUgPSBqUXVlcnkuZXhwci5hdHRySGFuZGxlO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGF0dHI6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBqUXVlcnkuYXR0ciwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XG5cdH0sXG5cblx0cmVtb3ZlQXR0cjogZnVuY3Rpb24oIG5hbWUgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggdGhpcywgbmFtZSApO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdGF0dHI6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHR2YXIgcmV0LCBob29rcyxcblx0XHRcdG5UeXBlID0gZWxlbS5ub2RlVHlwZTtcblxuXHRcdC8vIERvbid0IGdldC9zZXQgYXR0cmlidXRlcyBvbiB0ZXh0LCBjb21tZW50IGFuZCBhdHRyaWJ1dGUgbm9kZXNcblx0XHRpZiAoIG5UeXBlID09PSAzIHx8IG5UeXBlID09PSA4IHx8IG5UeXBlID09PSAyICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIEZhbGxiYWNrIHRvIHByb3Agd2hlbiBhdHRyaWJ1dGVzIGFyZSBub3Qgc3VwcG9ydGVkXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGUgPT09IFwidW5kZWZpbmVkXCIgKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LnByb3AoIGVsZW0sIG5hbWUsIHZhbHVlICk7XG5cdFx0fVxuXG5cdFx0Ly8gQXR0cmlidXRlIGhvb2tzIGFyZSBkZXRlcm1pbmVkIGJ5IHRoZSBsb3dlcmNhc2UgdmVyc2lvblxuXHRcdC8vIEdyYWIgbmVjZXNzYXJ5IGhvb2sgaWYgb25lIGlzIGRlZmluZWRcblx0XHRpZiAoIG5UeXBlICE9PSAxIHx8ICFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKSApIHtcblx0XHRcdGhvb2tzID0galF1ZXJ5LmF0dHJIb29rc1sgbmFtZS50b0xvd2VyQ2FzZSgpIF0gfHxcblx0XHRcdFx0KCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnRlc3QoIG5hbWUgKSA/IGJvb2xIb29rIDogdW5kZWZpbmVkICk7XG5cdFx0fVxuXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0aWYgKCB2YWx1ZSA9PT0gbnVsbCApIHtcblx0XHRcdFx0alF1ZXJ5LnJlbW92ZUF0dHIoIGVsZW0sIG5hbWUgKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGhvb2tzICYmIFwic2V0XCIgaW4gaG9va3MgJiZcblx0XHRcdFx0KCByZXQgPSBob29rcy5zZXQoIGVsZW0sIHZhbHVlLCBuYW1lICkgKSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggbmFtZSwgdmFsdWUgKyBcIlwiICk7XG5cdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0fVxuXG5cdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmICggcmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkgKSAhPT0gbnVsbCApIHtcblx0XHRcdHJldHVybiByZXQ7XG5cdFx0fVxuXG5cdFx0cmV0ID0galF1ZXJ5LmZpbmQuYXR0ciggZWxlbSwgbmFtZSApO1xuXG5cdFx0Ly8gTm9uLWV4aXN0ZW50IGF0dHJpYnV0ZXMgcmV0dXJuIG51bGwsIHdlIG5vcm1hbGl6ZSB0byB1bmRlZmluZWRcblx0XHRyZXR1cm4gcmV0ID09IG51bGwgPyB1bmRlZmluZWQgOiByZXQ7XG5cdH0sXG5cblx0YXR0ckhvb2tzOiB7XG5cdFx0dHlwZToge1xuXHRcdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XG5cdFx0XHRcdGlmICggIXN1cHBvcnQucmFkaW9WYWx1ZSAmJiB2YWx1ZSA9PT0gXCJyYWRpb1wiICYmXG5cdFx0XHRcdFx0bm9kZU5hbWUoIGVsZW0sIFwiaW5wdXRcIiApICkge1xuXHRcdFx0XHRcdHZhciB2YWwgPSBlbGVtLnZhbHVlO1xuXHRcdFx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgdmFsdWUgKTtcblx0XHRcdFx0XHRpZiAoIHZhbCApIHtcblx0XHRcdFx0XHRcdGVsZW0udmFsdWUgPSB2YWw7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHRyZW1vdmVBdHRyOiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XG5cdFx0dmFyIG5hbWUsXG5cdFx0XHRpID0gMCxcblxuXHRcdFx0Ly8gQXR0cmlidXRlIG5hbWVzIGNhbiBjb250YWluIG5vbi1IVE1MIHdoaXRlc3BhY2UgY2hhcmFjdGVyc1xuXHRcdFx0Ly8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjYXR0cmlidXRlcy0yXG5cdFx0XHRhdHRyTmFtZXMgPSB2YWx1ZSAmJiB2YWx1ZS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApO1xuXG5cdFx0aWYgKCBhdHRyTmFtZXMgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdHdoaWxlICggKCBuYW1lID0gYXR0ck5hbWVzWyBpKysgXSApICkge1xuXHRcdFx0XHRlbGVtLnJlbW92ZUF0dHJpYnV0ZSggbmFtZSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufSApO1xuXG4vLyBIb29rcyBmb3IgYm9vbGVhbiBhdHRyaWJ1dGVzXG5ib29sSG9vayA9IHtcblx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUsIG5hbWUgKSB7XG5cdFx0aWYgKCB2YWx1ZSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdC8vIFJlbW92ZSBib29sZWFuIGF0dHJpYnV0ZXMgd2hlbiBzZXQgdG8gZmFsc2Vcblx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCBlbGVtLCBuYW1lICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCBuYW1lICk7XG5cdFx0fVxuXHRcdHJldHVybiBuYW1lO1xuXHR9XG59O1xuXG5qUXVlcnkuZWFjaCggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC5zb3VyY2UubWF0Y2goIC9cXHcrL2cgKSwgZnVuY3Rpb24oIF9pLCBuYW1lICkge1xuXHR2YXIgZ2V0dGVyID0gYXR0ckhhbmRsZVsgbmFtZSBdIHx8IGpRdWVyeS5maW5kLmF0dHI7XG5cblx0YXR0ckhhbmRsZVsgbmFtZSBdID0gZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkge1xuXHRcdHZhciByZXQsIGhhbmRsZSxcblx0XHRcdGxvd2VyY2FzZU5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cblx0XHRpZiAoICFpc1hNTCApIHtcblxuXHRcdFx0Ly8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcCBieSB0ZW1wb3JhcmlseSByZW1vdmluZyB0aGlzIGZ1bmN0aW9uIGZyb20gdGhlIGdldHRlclxuXHRcdFx0aGFuZGxlID0gYXR0ckhhbmRsZVsgbG93ZXJjYXNlTmFtZSBdO1xuXHRcdFx0YXR0ckhhbmRsZVsgbG93ZXJjYXNlTmFtZSBdID0gcmV0O1xuXHRcdFx0cmV0ID0gZ2V0dGVyKCBlbGVtLCBuYW1lLCBpc1hNTCApICE9IG51bGwgP1xuXHRcdFx0XHRsb3dlcmNhc2VOYW1lIDpcblx0XHRcdFx0bnVsbDtcblx0XHRcdGF0dHJIYW5kbGVbIGxvd2VyY2FzZU5hbWUgXSA9IGhhbmRsZTtcblx0XHR9XG5cdFx0cmV0dXJuIHJldDtcblx0fTtcbn0gKTtcblxuXG5cblxudmFyIHJmb2N1c2FibGUgPSAvXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b24pJC9pLFxuXHRyY2xpY2thYmxlID0gL14oPzphfGFyZWEpJC9pO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHByb3A6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBqUXVlcnkucHJvcCwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XG5cdH0sXG5cblx0cmVtb3ZlUHJvcDogZnVuY3Rpb24oIG5hbWUgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRkZWxldGUgdGhpc1sgalF1ZXJ5LnByb3BGaXhbIG5hbWUgXSB8fCBuYW1lIF07XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0cHJvcDogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xuXHRcdHZhciByZXQsIGhvb2tzLFxuXHRcdFx0blR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdFx0Ly8gRG9uJ3QgZ2V0L3NldCBwcm9wZXJ0aWVzIG9uIHRleHQsIGNvbW1lbnQgYW5kIGF0dHJpYnV0ZSBub2Rlc1xuXHRcdGlmICggblR5cGUgPT09IDMgfHwgblR5cGUgPT09IDggfHwgblR5cGUgPT09IDIgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCBuVHlwZSAhPT0gMSB8fCAhalF1ZXJ5LmlzWE1MRG9jKCBlbGVtICkgKSB7XG5cblx0XHRcdC8vIEZpeCBuYW1lIGFuZCBhdHRhY2ggaG9va3Ncblx0XHRcdG5hbWUgPSBqUXVlcnkucHJvcEZpeFsgbmFtZSBdIHx8IG5hbWU7XG5cdFx0XHRob29rcyA9IGpRdWVyeS5wcm9wSG9va3NbIG5hbWUgXTtcblx0XHR9XG5cblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRpZiAoIGhvb2tzICYmIFwic2V0XCIgaW4gaG9va3MgJiZcblx0XHRcdFx0KCByZXQgPSBob29rcy5zZXQoIGVsZW0sIHZhbHVlLCBuYW1lICkgKSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gKCBlbGVtWyBuYW1lIF0gPSB2YWx1ZSApO1xuXHRcdH1cblxuXHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAoIHJldCA9IGhvb2tzLmdldCggZWxlbSwgbmFtZSApICkgIT09IG51bGwgKSB7XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH1cblxuXHRcdHJldHVybiBlbGVtWyBuYW1lIF07XG5cdH0sXG5cblx0cHJvcEhvb2tzOiB7XG5cdFx0dGFiSW5kZXg6IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHRcdFx0XHQvLyBlbGVtLnRhYkluZGV4IGRvZXNuJ3QgYWx3YXlzIHJldHVybiB0aGVcblx0XHRcdFx0Ly8gY29ycmVjdCB2YWx1ZSB3aGVuIGl0IGhhc24ndCBiZWVuIGV4cGxpY2l0bHkgc2V0XG5cdFx0XHRcdC8vIGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDE0MTExNjIzMzM0Ny9odHRwOi8vZmx1aWRwcm9qZWN0Lm9yZy9ibG9nLzIwMDgvMDEvMDkvZ2V0dGluZy1zZXR0aW5nLWFuZC1yZW1vdmluZy10YWJpbmRleC12YWx1ZXMtd2l0aC1qYXZhc2NyaXB0L1xuXHRcdFx0XHQvLyBVc2UgcHJvcGVyIGF0dHJpYnV0ZSByZXRyaWV2YWwoIzEyMDcyKVxuXHRcdFx0XHR2YXIgdGFiaW5kZXggPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBcInRhYmluZGV4XCIgKTtcblxuXHRcdFx0XHRpZiAoIHRhYmluZGV4ICkge1xuXHRcdFx0XHRcdHJldHVybiBwYXJzZUludCggdGFiaW5kZXgsIDEwICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0cmZvY3VzYWJsZS50ZXN0KCBlbGVtLm5vZGVOYW1lICkgfHxcblx0XHRcdFx0XHRyY2xpY2thYmxlLnRlc3QoIGVsZW0ubm9kZU5hbWUgKSAmJlxuXHRcdFx0XHRcdGVsZW0uaHJlZlxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0cHJvcEZpeDoge1xuXHRcdFwiZm9yXCI6IFwiaHRtbEZvclwiLFxuXHRcdFwiY2xhc3NcIjogXCJjbGFzc05hbWVcIlxuXHR9XG59ICk7XG5cbi8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxuLy8gQWNjZXNzaW5nIHRoZSBzZWxlY3RlZEluZGV4IHByb3BlcnR5XG4vLyBmb3JjZXMgdGhlIGJyb3dzZXIgdG8gcmVzcGVjdCBzZXR0aW5nIHNlbGVjdGVkXG4vLyBvbiB0aGUgb3B0aW9uXG4vLyBUaGUgZ2V0dGVyIGVuc3VyZXMgYSBkZWZhdWx0IG9wdGlvbiBpcyBzZWxlY3RlZFxuLy8gd2hlbiBpbiBhbiBvcHRncm91cFxuLy8gZXNsaW50IHJ1bGUgXCJuby11bnVzZWQtZXhwcmVzc2lvbnNcIiBpcyBkaXNhYmxlZCBmb3IgdGhpcyBjb2RlXG4vLyBzaW5jZSBpdCBjb25zaWRlcnMgc3VjaCBhY2Nlc3Npb25zIG5vb3BcbmlmICggIXN1cHBvcnQub3B0U2VsZWN0ZWQgKSB7XG5cdGpRdWVyeS5wcm9wSG9va3Muc2VsZWN0ZWQgPSB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0LyogZXNsaW50IG5vLXVudXNlZC1leHByZXNzaW9uczogXCJvZmZcIiAqL1xuXG5cdFx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdFx0aWYgKCBwYXJlbnQgJiYgcGFyZW50LnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdHBhcmVudC5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXg7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHRcdC8qIGVzbGludCBuby11bnVzZWQtZXhwcmVzc2lvbnM6IFwib2ZmXCIgKi9cblxuXHRcdFx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcblx0XHRcdGlmICggcGFyZW50ICkge1xuXHRcdFx0XHRwYXJlbnQuc2VsZWN0ZWRJbmRleDtcblxuXHRcdFx0XHRpZiAoIHBhcmVudC5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRcdHBhcmVudC5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXg7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH07XG59XG5cbmpRdWVyeS5lYWNoKCBbXG5cdFwidGFiSW5kZXhcIixcblx0XCJyZWFkT25seVwiLFxuXHRcIm1heExlbmd0aFwiLFxuXHRcImNlbGxTcGFjaW5nXCIsXG5cdFwiY2VsbFBhZGRpbmdcIixcblx0XCJyb3dTcGFuXCIsXG5cdFwiY29sU3BhblwiLFxuXHRcInVzZU1hcFwiLFxuXHRcImZyYW1lQm9yZGVyXCIsXG5cdFwiY29udGVudEVkaXRhYmxlXCJcbl0sIGZ1bmN0aW9uKCkge1xuXHRqUXVlcnkucHJvcEZpeFsgdGhpcy50b0xvd2VyQ2FzZSgpIF0gPSB0aGlzO1xufSApO1xuXG5cblxuXG5cdC8vIFN0cmlwIGFuZCBjb2xsYXBzZSB3aGl0ZXNwYWNlIGFjY29yZGluZyB0byBIVE1MIHNwZWNcblx0Ly8gaHR0cHM6Ly9pbmZyYS5zcGVjLndoYXR3Zy5vcmcvI3N0cmlwLWFuZC1jb2xsYXBzZS1hc2NpaS13aGl0ZXNwYWNlXG5cdGZ1bmN0aW9uIHN0cmlwQW5kQ29sbGFwc2UoIHZhbHVlICkge1xuXHRcdHZhciB0b2tlbnMgPSB2YWx1ZS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdO1xuXHRcdHJldHVybiB0b2tlbnMuam9pbiggXCIgXCIgKTtcblx0fVxuXG5cbmZ1bmN0aW9uIGdldENsYXNzKCBlbGVtICkge1xuXHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUgJiYgZWxlbS5nZXRBdHRyaWJ1dGUoIFwiY2xhc3NcIiApIHx8IFwiXCI7XG59XG5cbmZ1bmN0aW9uIGNsYXNzZXNUb0FycmF5KCB2YWx1ZSApIHtcblx0aWYgKCBBcnJheS5pc0FycmF5KCB2YWx1ZSApICkge1xuXHRcdHJldHVybiB2YWx1ZTtcblx0fVxuXHRpZiAoIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4gdmFsdWUubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbXTtcblx0fVxuXHRyZXR1cm4gW107XG59XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0YWRkQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjdXJWYWx1ZSwgY2xhenosIGosIGZpbmFsVmFsdWUsXG5cdFx0XHRpID0gMDtcblxuXHRcdGlmICggaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBqICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5hZGRDbGFzcyggdmFsdWUuY2FsbCggdGhpcywgaiwgZ2V0Q2xhc3MoIHRoaXMgKSApICk7XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0Y2xhc3NlcyA9IGNsYXNzZXNUb0FycmF5KCB2YWx1ZSApO1xuXG5cdFx0aWYgKCBjbGFzc2VzLmxlbmd0aCApIHtcblx0XHRcdHdoaWxlICggKCBlbGVtID0gdGhpc1sgaSsrIF0gKSApIHtcblx0XHRcdFx0Y3VyVmFsdWUgPSBnZXRDbGFzcyggZWxlbSApO1xuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmICggXCIgXCIgKyBzdHJpcEFuZENvbGxhcHNlKCBjdXJWYWx1ZSApICsgXCIgXCIgKTtcblxuXHRcdFx0XHRpZiAoIGN1ciApIHtcblx0XHRcdFx0XHRqID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoICggY2xhenogPSBjbGFzc2VzWyBqKysgXSApICkge1xuXHRcdFx0XHRcdFx0aWYgKCBjdXIuaW5kZXhPZiggXCIgXCIgKyBjbGF6eiArIFwiIFwiICkgPCAwICkge1xuXHRcdFx0XHRcdFx0XHRjdXIgKz0gY2xhenogKyBcIiBcIjtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBPbmx5IGFzc2lnbiBpZiBkaWZmZXJlbnQgdG8gYXZvaWQgdW5uZWVkZWQgcmVuZGVyaW5nLlxuXHRcdFx0XHRcdGZpbmFsVmFsdWUgPSBzdHJpcEFuZENvbGxhcHNlKCBjdXIgKTtcblx0XHRcdFx0XHRpZiAoIGN1clZhbHVlICE9PSBmaW5hbFZhbHVlICkge1xuXHRcdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwiY2xhc3NcIiwgZmluYWxWYWx1ZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHJlbW92ZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dmFyIGNsYXNzZXMsIGVsZW0sIGN1ciwgY3VyVmFsdWUsIGNsYXp6LCBqLCBmaW5hbFZhbHVlLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRpZiAoIGlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaiApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkucmVtb3ZlQ2xhc3MoIHZhbHVlLmNhbGwoIHRoaXMsIGosIGdldENsYXNzKCB0aGlzICkgKSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdGlmICggIWFyZ3VtZW50cy5sZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5hdHRyKCBcImNsYXNzXCIsIFwiXCIgKTtcblx0XHR9XG5cblx0XHRjbGFzc2VzID0gY2xhc3Nlc1RvQXJyYXkoIHZhbHVlICk7XG5cblx0XHRpZiAoIGNsYXNzZXMubGVuZ3RoICkge1xuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkge1xuXHRcdFx0XHRjdXJWYWx1ZSA9IGdldENsYXNzKCBlbGVtICk7XG5cblx0XHRcdFx0Ly8gVGhpcyBleHByZXNzaW9uIGlzIGhlcmUgZm9yIGJldHRlciBjb21wcmVzc2liaWxpdHkgKHNlZSBhZGRDbGFzcylcblx0XHRcdFx0Y3VyID0gZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAoIFwiIFwiICsgc3RyaXBBbmRDb2xsYXBzZSggY3VyVmFsdWUgKSArIFwiIFwiICk7XG5cblx0XHRcdFx0aWYgKCBjdXIgKSB7XG5cdFx0XHRcdFx0aiA9IDA7XG5cdFx0XHRcdFx0d2hpbGUgKCAoIGNsYXp6ID0gY2xhc3Nlc1sgaisrIF0gKSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gUmVtb3ZlICphbGwqIGluc3RhbmNlc1xuXHRcdFx0XHRcdFx0d2hpbGUgKCBjdXIuaW5kZXhPZiggXCIgXCIgKyBjbGF6eiArIFwiIFwiICkgPiAtMSApIHtcblx0XHRcdFx0XHRcdFx0Y3VyID0gY3VyLnJlcGxhY2UoIFwiIFwiICsgY2xhenogKyBcIiBcIiwgXCIgXCIgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBPbmx5IGFzc2lnbiBpZiBkaWZmZXJlbnQgdG8gYXZvaWQgdW5uZWVkZWQgcmVuZGVyaW5nLlxuXHRcdFx0XHRcdGZpbmFsVmFsdWUgPSBzdHJpcEFuZENvbGxhcHNlKCBjdXIgKTtcblx0XHRcdFx0XHRpZiAoIGN1clZhbHVlICE9PSBmaW5hbFZhbHVlICkge1xuXHRcdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwiY2xhc3NcIiwgZmluYWxWYWx1ZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHRvZ2dsZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUsIHN0YXRlVmFsICkge1xuXHRcdHZhciB0eXBlID0gdHlwZW9mIHZhbHVlLFxuXHRcdFx0aXNWYWxpZFZhbHVlID0gdHlwZSA9PT0gXCJzdHJpbmdcIiB8fCBBcnJheS5pc0FycmF5KCB2YWx1ZSApO1xuXG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGVWYWwgPT09IFwiYm9vbGVhblwiICYmIGlzVmFsaWRWYWx1ZSApIHtcblx0XHRcdHJldHVybiBzdGF0ZVZhbCA/IHRoaXMuYWRkQ2xhc3MoIHZhbHVlICkgOiB0aGlzLnJlbW92ZUNsYXNzKCB2YWx1ZSApO1xuXHRcdH1cblxuXHRcdGlmICggaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS50b2dnbGVDbGFzcyhcblx0XHRcdFx0XHR2YWx1ZS5jYWxsKCB0aGlzLCBpLCBnZXRDbGFzcyggdGhpcyApLCBzdGF0ZVZhbCApLFxuXHRcdFx0XHRcdHN0YXRlVmFsXG5cdFx0XHRcdCk7XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgY2xhc3NOYW1lLCBpLCBzZWxmLCBjbGFzc05hbWVzO1xuXG5cdFx0XHRpZiAoIGlzVmFsaWRWYWx1ZSApIHtcblxuXHRcdFx0XHQvLyBUb2dnbGUgaW5kaXZpZHVhbCBjbGFzcyBuYW1lc1xuXHRcdFx0XHRpID0gMDtcblx0XHRcdFx0c2VsZiA9IGpRdWVyeSggdGhpcyApO1xuXHRcdFx0XHRjbGFzc05hbWVzID0gY2xhc3Nlc1RvQXJyYXkoIHZhbHVlICk7XG5cblx0XHRcdFx0d2hpbGUgKCAoIGNsYXNzTmFtZSA9IGNsYXNzTmFtZXNbIGkrKyBdICkgKSB7XG5cblx0XHRcdFx0XHQvLyBDaGVjayBlYWNoIGNsYXNzTmFtZSBnaXZlbiwgc3BhY2Ugc2VwYXJhdGVkIGxpc3Rcblx0XHRcdFx0XHRpZiAoIHNlbGYuaGFzQ2xhc3MoIGNsYXNzTmFtZSApICkge1xuXHRcdFx0XHRcdFx0c2VsZi5yZW1vdmVDbGFzcyggY2xhc3NOYW1lICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHNlbGYuYWRkQ2xhc3MoIGNsYXNzTmFtZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBUb2dnbGUgd2hvbGUgY2xhc3MgbmFtZVxuXHRcdFx0fSBlbHNlIGlmICggdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB0eXBlID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRcdFx0Y2xhc3NOYW1lID0gZ2V0Q2xhc3MoIHRoaXMgKTtcblx0XHRcdFx0aWYgKCBjbGFzc05hbWUgKSB7XG5cblx0XHRcdFx0XHQvLyBTdG9yZSBjbGFzc05hbWUgaWYgc2V0XG5cdFx0XHRcdFx0ZGF0YVByaXYuc2V0KCB0aGlzLCBcIl9fY2xhc3NOYW1lX19cIiwgY2xhc3NOYW1lICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBJZiB0aGUgZWxlbWVudCBoYXMgYSBjbGFzcyBuYW1lIG9yIGlmIHdlJ3JlIHBhc3NlZCBgZmFsc2VgLFxuXHRcdFx0XHQvLyB0aGVuIHJlbW92ZSB0aGUgd2hvbGUgY2xhc3NuYW1lIChpZiB0aGVyZSB3YXMgb25lLCB0aGUgYWJvdmUgc2F2ZWQgaXQpLlxuXHRcdFx0XHQvLyBPdGhlcndpc2UgYnJpbmcgYmFjayB3aGF0ZXZlciB3YXMgcHJldmlvdXNseSBzYXZlZCAoaWYgYW55dGhpbmcpLFxuXHRcdFx0XHQvLyBmYWxsaW5nIGJhY2sgdG8gdGhlIGVtcHR5IHN0cmluZyBpZiBub3RoaW5nIHdhcyBzdG9yZWQuXG5cdFx0XHRcdGlmICggdGhpcy5zZXRBdHRyaWJ1dGUgKSB7XG5cdFx0XHRcdFx0dGhpcy5zZXRBdHRyaWJ1dGUoIFwiY2xhc3NcIixcblx0XHRcdFx0XHRcdGNsYXNzTmFtZSB8fCB2YWx1ZSA9PT0gZmFsc2UgP1xuXHRcdFx0XHRcdFx0XHRcIlwiIDpcblx0XHRcdFx0XHRcdFx0ZGF0YVByaXYuZ2V0KCB0aGlzLCBcIl9fY2xhc3NOYW1lX19cIiApIHx8IFwiXCJcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdGhhc0NsYXNzOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGNsYXNzTmFtZSwgZWxlbSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0Y2xhc3NOYW1lID0gXCIgXCIgKyBzZWxlY3RvciArIFwiIFwiO1xuXHRcdHdoaWxlICggKCBlbGVtID0gdGhpc1sgaSsrIF0gKSApIHtcblx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0XHQoIFwiIFwiICsgc3RyaXBBbmRDb2xsYXBzZSggZ2V0Q2xhc3MoIGVsZW0gKSApICsgXCIgXCIgKS5pbmRleE9mKCBjbGFzc05hbWUgKSA+IC0xICkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0gKTtcblxuXG5cblxudmFyIHJyZXR1cm4gPSAvXFxyL2c7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0dmFsOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dmFyIGhvb2tzLCByZXQsIHZhbHVlSXNGdW5jdGlvbixcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF07XG5cblx0XHRpZiAoICFhcmd1bWVudHMubGVuZ3RoICkge1xuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHRob29rcyA9IGpRdWVyeS52YWxIb29rc1sgZWxlbS50eXBlIF0gfHxcblx0XHRcdFx0XHRqUXVlcnkudmFsSG9va3NbIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSBdO1xuXG5cdFx0XHRcdGlmICggaG9va3MgJiZcblx0XHRcdFx0XHRcImdldFwiIGluIGhvb2tzICYmXG5cdFx0XHRcdFx0KCByZXQgPSBob29rcy5nZXQoIGVsZW0sIFwidmFsdWVcIiApICkgIT09IHVuZGVmaW5lZFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0ID0gZWxlbS52YWx1ZTtcblxuXHRcdFx0XHQvLyBIYW5kbGUgbW9zdCBjb21tb24gc3RyaW5nIGNhc2VzXG5cdFx0XHRcdGlmICggdHlwZW9mIHJldCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0XHRyZXR1cm4gcmV0LnJlcGxhY2UoIHJyZXR1cm4sIFwiXCIgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEhhbmRsZSBjYXNlcyB3aGVyZSB2YWx1ZSBpcyBudWxsL3VuZGVmIG9yIG51bWJlclxuXHRcdFx0XHRyZXR1cm4gcmV0ID09IG51bGwgPyBcIlwiIDogcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFsdWVJc0Z1bmN0aW9uID0gaXNGdW5jdGlvbiggdmFsdWUgKTtcblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0dmFyIHZhbDtcblxuXHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlICE9PSAxICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmICggdmFsdWVJc0Z1bmN0aW9uICkge1xuXHRcdFx0XHR2YWwgPSB2YWx1ZS5jYWxsKCB0aGlzLCBpLCBqUXVlcnkoIHRoaXMgKS52YWwoKSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dmFsID0gdmFsdWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRyZWF0IG51bGwvdW5kZWZpbmVkIGFzIFwiXCI7IGNvbnZlcnQgbnVtYmVycyB0byBzdHJpbmdcblx0XHRcdGlmICggdmFsID09IG51bGwgKSB7XG5cdFx0XHRcdHZhbCA9IFwiXCI7XG5cblx0XHRcdH0gZWxzZSBpZiAoIHR5cGVvZiB2YWwgPT09IFwibnVtYmVyXCIgKSB7XG5cdFx0XHRcdHZhbCArPSBcIlwiO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBBcnJheS5pc0FycmF5KCB2YWwgKSApIHtcblx0XHRcdFx0dmFsID0galF1ZXJ5Lm1hcCggdmFsLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlID09IG51bGwgPyBcIlwiIDogdmFsdWUgKyBcIlwiO1xuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cblx0XHRcdGhvb2tzID0galF1ZXJ5LnZhbEhvb2tzWyB0aGlzLnR5cGUgXSB8fCBqUXVlcnkudmFsSG9va3NbIHRoaXMubm9kZU5hbWUudG9Mb3dlckNhc2UoKSBdO1xuXG5cdFx0XHQvLyBJZiBzZXQgcmV0dXJucyB1bmRlZmluZWQsIGZhbGwgYmFjayB0byBub3JtYWwgc2V0dGluZ1xuXHRcdFx0aWYgKCAhaG9va3MgfHwgISggXCJzZXRcIiBpbiBob29rcyApIHx8IGhvb2tzLnNldCggdGhpcywgdmFsLCBcInZhbHVlXCIgKSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHR0aGlzLnZhbHVlID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdHZhbEhvb2tzOiB7XG5cdFx0b3B0aW9uOiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHRcdHZhciB2YWwgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBcInZhbHVlXCIgKTtcblx0XHRcdFx0cmV0dXJuIHZhbCAhPSBudWxsID9cblx0XHRcdFx0XHR2YWwgOlxuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD0xMCAtIDExIG9ubHlcblx0XHRcdFx0XHQvLyBvcHRpb24udGV4dCB0aHJvd3MgZXhjZXB0aW9ucyAoIzE0Njg2LCAjMTQ4NTgpXG5cdFx0XHRcdFx0Ly8gU3RyaXAgYW5kIGNvbGxhcHNlIHdoaXRlc3BhY2Vcblx0XHRcdFx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnLyNzdHJpcC1hbmQtY29sbGFwc2Utd2hpdGVzcGFjZVxuXHRcdFx0XHRcdHN0cmlwQW5kQ29sbGFwc2UoIGpRdWVyeS50ZXh0KCBlbGVtICkgKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdHNlbGVjdDoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIHZhbHVlLCBvcHRpb24sIGksXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcblx0XHRcdFx0XHRpbmRleCA9IGVsZW0uc2VsZWN0ZWRJbmRleCxcblx0XHRcdFx0XHRvbmUgPSBlbGVtLnR5cGUgPT09IFwic2VsZWN0LW9uZVwiLFxuXHRcdFx0XHRcdHZhbHVlcyA9IG9uZSA/IG51bGwgOiBbXSxcblx0XHRcdFx0XHRtYXggPSBvbmUgPyBpbmRleCArIDEgOiBvcHRpb25zLmxlbmd0aDtcblxuXHRcdFx0XHRpZiAoIGluZGV4IDwgMCApIHtcblx0XHRcdFx0XHRpID0gbWF4O1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aSA9IG9uZSA/IGluZGV4IDogMDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIExvb3AgdGhyb3VnaCBhbGwgdGhlIHNlbGVjdGVkIG9wdGlvbnNcblx0XHRcdFx0Zm9yICggOyBpIDwgbWF4OyBpKysgKSB7XG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD05IG9ubHlcblx0XHRcdFx0XHQvLyBJRTgtOSBkb2Vzbid0IHVwZGF0ZSBzZWxlY3RlZCBhZnRlciBmb3JtIHJlc2V0ICgjMjU1MSlcblx0XHRcdFx0XHRpZiAoICggb3B0aW9uLnNlbGVjdGVkIHx8IGkgPT09IGluZGV4ICkgJiZcblxuXHRcdFx0XHRcdFx0XHQvLyBEb24ndCByZXR1cm4gb3B0aW9ucyB0aGF0IGFyZSBkaXNhYmxlZCBvciBpbiBhIGRpc2FibGVkIG9wdGdyb3VwXG5cdFx0XHRcdFx0XHRcdCFvcHRpb24uZGlzYWJsZWQgJiZcblx0XHRcdFx0XHRcdFx0KCAhb3B0aW9uLnBhcmVudE5vZGUuZGlzYWJsZWQgfHxcblx0XHRcdFx0XHRcdFx0XHQhbm9kZU5hbWUoIG9wdGlvbi5wYXJlbnROb2RlLCBcIm9wdGdyb3VwXCIgKSApICkge1xuXG5cdFx0XHRcdFx0XHQvLyBHZXQgdGhlIHNwZWNpZmljIHZhbHVlIGZvciB0aGUgb3B0aW9uXG5cdFx0XHRcdFx0XHR2YWx1ZSA9IGpRdWVyeSggb3B0aW9uICkudmFsKCk7XG5cblx0XHRcdFx0XHRcdC8vIFdlIGRvbid0IG5lZWQgYW4gYXJyYXkgZm9yIG9uZSBzZWxlY3RzXG5cdFx0XHRcdFx0XHRpZiAoIG9uZSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBNdWx0aS1TZWxlY3RzIHJldHVybiBhbiBhcnJheVxuXHRcdFx0XHRcdFx0dmFsdWVzLnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHRcdH0sXG5cblx0XHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgb3B0aW9uU2V0LCBvcHRpb24sXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcblx0XHRcdFx0XHR2YWx1ZXMgPSBqUXVlcnkubWFrZUFycmF5KCB2YWx1ZSApLFxuXHRcdFx0XHRcdGkgPSBvcHRpb25zLmxlbmd0aDtcblxuXHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRvcHRpb24gPSBvcHRpb25zWyBpIF07XG5cblx0XHRcdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25kLWFzc2lnbiAqL1xuXG5cdFx0XHRcdFx0aWYgKCBvcHRpb24uc2VsZWN0ZWQgPVxuXHRcdFx0XHRcdFx0alF1ZXJ5LmluQXJyYXkoIGpRdWVyeS52YWxIb29rcy5vcHRpb24uZ2V0KCBvcHRpb24gKSwgdmFsdWVzICkgPiAtMVxuXHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0b3B0aW9uU2V0ID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvKiBlc2xpbnQtZW5hYmxlIG5vLWNvbmQtYXNzaWduICovXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBGb3JjZSBicm93c2VycyB0byBiZWhhdmUgY29uc2lzdGVudGx5IHdoZW4gbm9uLW1hdGNoaW5nIHZhbHVlIGlzIHNldFxuXHRcdFx0XHRpZiAoICFvcHRpb25TZXQgKSB7XG5cdFx0XHRcdFx0ZWxlbS5zZWxlY3RlZEluZGV4ID0gLTE7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn0gKTtcblxuLy8gUmFkaW9zIGFuZCBjaGVja2JveGVzIGdldHRlci9zZXR0ZXJcbmpRdWVyeS5lYWNoKCBbIFwicmFkaW9cIiwgXCJjaGVja2JveFwiIF0sIGZ1bmN0aW9uKCkge1xuXHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXSA9IHtcblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdGlmICggQXJyYXkuaXNBcnJheSggdmFsdWUgKSApIHtcblx0XHRcdFx0cmV0dXJuICggZWxlbS5jaGVja2VkID0galF1ZXJ5LmluQXJyYXkoIGpRdWVyeSggZWxlbSApLnZhbCgpLCB2YWx1ZSApID4gLTEgKTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cdGlmICggIXN1cHBvcnQuY2hlY2tPbiApIHtcblx0XHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXS5nZXQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiICkgPT09IG51bGwgPyBcIm9uXCIgOiBlbGVtLnZhbHVlO1xuXHRcdH07XG5cdH1cbn0gKTtcblxuXG5cblxuLy8gUmV0dXJuIGpRdWVyeSBmb3IgYXR0cmlidXRlcy1vbmx5IGluY2x1c2lvblxuXG5cbnN1cHBvcnQuZm9jdXNpbiA9IFwib25mb2N1c2luXCIgaW4gd2luZG93O1xuXG5cbnZhciByZm9jdXNNb3JwaCA9IC9eKD86Zm9jdXNpbmZvY3VzfGZvY3Vzb3V0Ymx1cikkLyxcblx0c3RvcFByb3BhZ2F0aW9uQ2FsbGJhY2sgPSBmdW5jdGlvbiggZSApIHtcblx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHR9O1xuXG5qUXVlcnkuZXh0ZW5kKCBqUXVlcnkuZXZlbnQsIHtcblxuXHR0cmlnZ2VyOiBmdW5jdGlvbiggZXZlbnQsIGRhdGEsIGVsZW0sIG9ubHlIYW5kbGVycyApIHtcblxuXHRcdHZhciBpLCBjdXIsIHRtcCwgYnViYmxlVHlwZSwgb250eXBlLCBoYW5kbGUsIHNwZWNpYWwsIGxhc3RFbGVtZW50LFxuXHRcdFx0ZXZlbnRQYXRoID0gWyBlbGVtIHx8IGRvY3VtZW50IF0sXG5cdFx0XHR0eXBlID0gaGFzT3duLmNhbGwoIGV2ZW50LCBcInR5cGVcIiApID8gZXZlbnQudHlwZSA6IGV2ZW50LFxuXHRcdFx0bmFtZXNwYWNlcyA9IGhhc093bi5jYWxsKCBldmVudCwgXCJuYW1lc3BhY2VcIiApID8gZXZlbnQubmFtZXNwYWNlLnNwbGl0KCBcIi5cIiApIDogW107XG5cblx0XHRjdXIgPSBsYXN0RWxlbWVudCA9IHRtcCA9IGVsZW0gPSBlbGVtIHx8IGRvY3VtZW50O1xuXG5cdFx0Ly8gRG9uJ3QgZG8gZXZlbnRzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcblx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBmb2N1cy9ibHVyIG1vcnBocyB0byBmb2N1c2luL291dDsgZW5zdXJlIHdlJ3JlIG5vdCBmaXJpbmcgdGhlbSByaWdodCBub3dcblx0XHRpZiAoIHJmb2N1c01vcnBoLnRlc3QoIHR5cGUgKyBqUXVlcnkuZXZlbnQudHJpZ2dlcmVkICkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCB0eXBlLmluZGV4T2YoIFwiLlwiICkgPiAtMSApIHtcblxuXHRcdFx0Ly8gTmFtZXNwYWNlZCB0cmlnZ2VyOyBjcmVhdGUgYSByZWdleHAgdG8gbWF0Y2ggZXZlbnQgdHlwZSBpbiBoYW5kbGUoKVxuXHRcdFx0bmFtZXNwYWNlcyA9IHR5cGUuc3BsaXQoIFwiLlwiICk7XG5cdFx0XHR0eXBlID0gbmFtZXNwYWNlcy5zaGlmdCgpO1xuXHRcdFx0bmFtZXNwYWNlcy5zb3J0KCk7XG5cdFx0fVxuXHRcdG9udHlwZSA9IHR5cGUuaW5kZXhPZiggXCI6XCIgKSA8IDAgJiYgXCJvblwiICsgdHlwZTtcblxuXHRcdC8vIENhbGxlciBjYW4gcGFzcyBpbiBhIGpRdWVyeS5FdmVudCBvYmplY3QsIE9iamVjdCwgb3IganVzdCBhbiBldmVudCB0eXBlIHN0cmluZ1xuXHRcdGV2ZW50ID0gZXZlbnRbIGpRdWVyeS5leHBhbmRvIF0gP1xuXHRcdFx0ZXZlbnQgOlxuXHRcdFx0bmV3IGpRdWVyeS5FdmVudCggdHlwZSwgdHlwZW9mIGV2ZW50ID09PSBcIm9iamVjdFwiICYmIGV2ZW50ICk7XG5cblx0XHQvLyBUcmlnZ2VyIGJpdG1hc2s6ICYgMSBmb3IgbmF0aXZlIGhhbmRsZXJzOyAmIDIgZm9yIGpRdWVyeSAoYWx3YXlzIHRydWUpXG5cdFx0ZXZlbnQuaXNUcmlnZ2VyID0gb25seUhhbmRsZXJzID8gMiA6IDM7XG5cdFx0ZXZlbnQubmFtZXNwYWNlID0gbmFtZXNwYWNlcy5qb2luKCBcIi5cIiApO1xuXHRcdGV2ZW50LnJuYW1lc3BhY2UgPSBldmVudC5uYW1lc3BhY2UgP1xuXHRcdFx0bmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbiggXCJcXFxcLig/Oi4qXFxcXC58KVwiICkgKyBcIihcXFxcLnwkKVwiICkgOlxuXHRcdFx0bnVsbDtcblxuXHRcdC8vIENsZWFuIHVwIHRoZSBldmVudCBpbiBjYXNlIGl0IGlzIGJlaW5nIHJldXNlZFxuXHRcdGV2ZW50LnJlc3VsdCA9IHVuZGVmaW5lZDtcblx0XHRpZiAoICFldmVudC50YXJnZXQgKSB7XG5cdFx0XHRldmVudC50YXJnZXQgPSBlbGVtO1xuXHRcdH1cblxuXHRcdC8vIENsb25lIGFueSBpbmNvbWluZyBkYXRhIGFuZCBwcmVwZW5kIHRoZSBldmVudCwgY3JlYXRpbmcgdGhlIGhhbmRsZXIgYXJnIGxpc3Rcblx0XHRkYXRhID0gZGF0YSA9PSBudWxsID9cblx0XHRcdFsgZXZlbnQgXSA6XG5cdFx0XHRqUXVlcnkubWFrZUFycmF5KCBkYXRhLCBbIGV2ZW50IF0gKTtcblxuXHRcdC8vIEFsbG93IHNwZWNpYWwgZXZlbnRzIHRvIGRyYXcgb3V0c2lkZSB0aGUgbGluZXNcblx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgc3BlY2lhbC50cmlnZ2VyICYmIHNwZWNpYWwudHJpZ2dlci5hcHBseSggZWxlbSwgZGF0YSApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgZXZlbnQgcHJvcGFnYXRpb24gcGF0aCBpbiBhZHZhbmNlLCBwZXIgVzNDIGV2ZW50cyBzcGVjICgjOTk1MSlcblx0XHQvLyBCdWJibGUgdXAgdG8gZG9jdW1lbnQsIHRoZW4gdG8gd2luZG93OyB3YXRjaCBmb3IgYSBnbG9iYWwgb3duZXJEb2N1bWVudCB2YXIgKCM5NzI0KVxuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiAhc3BlY2lhbC5ub0J1YmJsZSAmJiAhaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0YnViYmxlVHlwZSA9IHNwZWNpYWwuZGVsZWdhdGVUeXBlIHx8IHR5cGU7XG5cdFx0XHRpZiAoICFyZm9jdXNNb3JwaC50ZXN0KCBidWJibGVUeXBlICsgdHlwZSApICkge1xuXHRcdFx0XHRjdXIgPSBjdXIucGFyZW50Tm9kZTtcblx0XHRcdH1cblx0XHRcdGZvciAoIDsgY3VyOyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0ZXZlbnRQYXRoLnB1c2goIGN1ciApO1xuXHRcdFx0XHR0bXAgPSBjdXI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE9ubHkgYWRkIHdpbmRvdyBpZiB3ZSBnb3QgdG8gZG9jdW1lbnQgKGUuZy4sIG5vdCBwbGFpbiBvYmogb3IgZGV0YWNoZWQgRE9NKVxuXHRcdFx0aWYgKCB0bXAgPT09ICggZWxlbS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50ICkgKSB7XG5cdFx0XHRcdGV2ZW50UGF0aC5wdXNoKCB0bXAuZGVmYXVsdFZpZXcgfHwgdG1wLnBhcmVudFdpbmRvdyB8fCB3aW5kb3cgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBGaXJlIGhhbmRsZXJzIG9uIHRoZSBldmVudCBwYXRoXG5cdFx0aSA9IDA7XG5cdFx0d2hpbGUgKCAoIGN1ciA9IGV2ZW50UGF0aFsgaSsrIF0gKSAmJiAhZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblx0XHRcdGxhc3RFbGVtZW50ID0gY3VyO1xuXHRcdFx0ZXZlbnQudHlwZSA9IGkgPiAxID9cblx0XHRcdFx0YnViYmxlVHlwZSA6XG5cdFx0XHRcdHNwZWNpYWwuYmluZFR5cGUgfHwgdHlwZTtcblxuXHRcdFx0Ly8galF1ZXJ5IGhhbmRsZXJcblx0XHRcdGhhbmRsZSA9ICggZGF0YVByaXYuZ2V0KCBjdXIsIFwiZXZlbnRzXCIgKSB8fCBPYmplY3QuY3JlYXRlKCBudWxsICkgKVsgZXZlbnQudHlwZSBdICYmXG5cdFx0XHRcdGRhdGFQcml2LmdldCggY3VyLCBcImhhbmRsZVwiICk7XG5cdFx0XHRpZiAoIGhhbmRsZSApIHtcblx0XHRcdFx0aGFuZGxlLmFwcGx5KCBjdXIsIGRhdGEgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTmF0aXZlIGhhbmRsZXJcblx0XHRcdGhhbmRsZSA9IG9udHlwZSAmJiBjdXJbIG9udHlwZSBdO1xuXHRcdFx0aWYgKCBoYW5kbGUgJiYgaGFuZGxlLmFwcGx5ICYmIGFjY2VwdERhdGEoIGN1ciApICkge1xuXHRcdFx0XHRldmVudC5yZXN1bHQgPSBoYW5kbGUuYXBwbHkoIGN1ciwgZGF0YSApO1xuXHRcdFx0XHRpZiAoIGV2ZW50LnJlc3VsdCA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRldmVudC50eXBlID0gdHlwZTtcblxuXHRcdC8vIElmIG5vYm9keSBwcmV2ZW50ZWQgdGhlIGRlZmF1bHQgYWN0aW9uLCBkbyBpdCBub3dcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgIWV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpICkge1xuXG5cdFx0XHRpZiAoICggIXNwZWNpYWwuX2RlZmF1bHQgfHxcblx0XHRcdFx0c3BlY2lhbC5fZGVmYXVsdC5hcHBseSggZXZlbnRQYXRoLnBvcCgpLCBkYXRhICkgPT09IGZhbHNlICkgJiZcblx0XHRcdFx0YWNjZXB0RGF0YSggZWxlbSApICkge1xuXG5cdFx0XHRcdC8vIENhbGwgYSBuYXRpdmUgRE9NIG1ldGhvZCBvbiB0aGUgdGFyZ2V0IHdpdGggdGhlIHNhbWUgbmFtZSBhcyB0aGUgZXZlbnQuXG5cdFx0XHRcdC8vIERvbid0IGRvIGRlZmF1bHQgYWN0aW9ucyBvbiB3aW5kb3csIHRoYXQncyB3aGVyZSBnbG9iYWwgdmFyaWFibGVzIGJlICgjNjE3MClcblx0XHRcdFx0aWYgKCBvbnR5cGUgJiYgaXNGdW5jdGlvbiggZWxlbVsgdHlwZSBdICkgJiYgIWlzV2luZG93KCBlbGVtICkgKSB7XG5cblx0XHRcdFx0XHQvLyBEb24ndCByZS10cmlnZ2VyIGFuIG9uRk9PIGV2ZW50IHdoZW4gd2UgY2FsbCBpdHMgRk9PKCkgbWV0aG9kXG5cdFx0XHRcdFx0dG1wID0gZWxlbVsgb250eXBlIF07XG5cblx0XHRcdFx0XHRpZiAoIHRtcCApIHtcblx0XHRcdFx0XHRcdGVsZW1bIG9udHlwZSBdID0gbnVsbDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBQcmV2ZW50IHJlLXRyaWdnZXJpbmcgb2YgdGhlIHNhbWUgZXZlbnQsIHNpbmNlIHdlIGFscmVhZHkgYnViYmxlZCBpdCBhYm92ZVxuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgPSB0eXBlO1xuXG5cdFx0XHRcdFx0aWYgKCBldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXHRcdFx0XHRcdFx0bGFzdEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggdHlwZSwgc3RvcFByb3BhZ2F0aW9uQ2FsbGJhY2sgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRlbGVtWyB0eXBlIF0oKTtcblxuXHRcdFx0XHRcdGlmICggZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblx0XHRcdFx0XHRcdGxhc3RFbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoIHR5cGUsIHN0b3BQcm9wYWdhdGlvbkNhbGxiYWNrICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCA9IHVuZGVmaW5lZDtcblxuXHRcdFx0XHRcdGlmICggdG1wICkge1xuXHRcdFx0XHRcdFx0ZWxlbVsgb250eXBlIF0gPSB0bXA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV2ZW50LnJlc3VsdDtcblx0fSxcblxuXHQvLyBQaWdneWJhY2sgb24gYSBkb25vciBldmVudCB0byBzaW11bGF0ZSBhIGRpZmZlcmVudCBvbmVcblx0Ly8gVXNlZCBvbmx5IGZvciBgZm9jdXMoaW4gfCBvdXQpYCBldmVudHNcblx0c2ltdWxhdGU6IGZ1bmN0aW9uKCB0eXBlLCBlbGVtLCBldmVudCApIHtcblx0XHR2YXIgZSA9IGpRdWVyeS5leHRlbmQoXG5cdFx0XHRuZXcgalF1ZXJ5LkV2ZW50KCksXG5cdFx0XHRldmVudCxcblx0XHRcdHtcblx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0aXNTaW11bGF0ZWQ6IHRydWVcblx0XHRcdH1cblx0XHQpO1xuXG5cdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIGUsIG51bGwsIGVsZW0gKTtcblx0fVxuXG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblxuXHR0cmlnZ2VyOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKCB0eXBlLCBkYXRhLCB0aGlzICk7XG5cdFx0fSApO1xuXHR9LFxuXHR0cmlnZ2VySGFuZGxlcjogZnVuY3Rpb24oIHR5cGUsIGRhdGEgKSB7XG5cdFx0dmFyIGVsZW0gPSB0aGlzWyAwIF07XG5cdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5ldmVudC50cmlnZ2VyKCB0eXBlLCBkYXRhLCBlbGVtLCB0cnVlICk7XG5cdFx0fVxuXHR9XG59ICk7XG5cblxuLy8gU3VwcG9ydDogRmlyZWZveCA8PTQ0XG4vLyBGaXJlZm94IGRvZXNuJ3QgaGF2ZSBmb2N1cyhpbiB8IG91dCkgZXZlbnRzXG4vLyBSZWxhdGVkIHRpY2tldCAtIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY4Nzc4N1xuLy9cbi8vIFN1cHBvcnQ6IENocm9tZSA8PTQ4IC0gNDksIFNhZmFyaSA8PTkuMCAtIDkuMVxuLy8gZm9jdXMoaW4gfCBvdXQpIGV2ZW50cyBmaXJlIGFmdGVyIGZvY3VzICYgYmx1ciBldmVudHMsXG4vLyB3aGljaCBpcyBzcGVjIHZpb2xhdGlvbiAtIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy8jZXZlbnRzLWZvY3VzZXZlbnQtZXZlbnQtb3JkZXJcbi8vIFJlbGF0ZWQgdGlja2V0IC0gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NDQ5ODU3XG5pZiAoICFzdXBwb3J0LmZvY3VzaW4gKSB7XG5cdGpRdWVyeS5lYWNoKCB7IGZvY3VzOiBcImZvY3VzaW5cIiwgYmx1cjogXCJmb2N1c291dFwiIH0sIGZ1bmN0aW9uKCBvcmlnLCBmaXggKSB7XG5cblx0XHQvLyBBdHRhY2ggYSBzaW5nbGUgY2FwdHVyaW5nIGhhbmRsZXIgb24gdGhlIGRvY3VtZW50IHdoaWxlIHNvbWVvbmUgd2FudHMgZm9jdXNpbi9mb2N1c291dFxuXHRcdHZhciBoYW5kbGVyID0gZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnNpbXVsYXRlKCBmaXgsIGV2ZW50LnRhcmdldCwgalF1ZXJ5LmV2ZW50LmZpeCggZXZlbnQgKSApO1xuXHRcdH07XG5cblx0XHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgZml4IF0gPSB7XG5cdFx0XHRzZXR1cDogZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0Ly8gSGFuZGxlOiByZWd1bGFyIG5vZGVzICh2aWEgYHRoaXMub3duZXJEb2N1bWVudGApLCB3aW5kb3dcblx0XHRcdFx0Ly8gKHZpYSBgdGhpcy5kb2N1bWVudGApICYgZG9jdW1lbnQgKHZpYSBgdGhpc2ApLlxuXHRcdFx0XHR2YXIgZG9jID0gdGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMuZG9jdW1lbnQgfHwgdGhpcyxcblx0XHRcdFx0XHRhdHRhY2hlcyA9IGRhdGFQcml2LmFjY2VzcyggZG9jLCBmaXggKTtcblxuXHRcdFx0XHRpZiAoICFhdHRhY2hlcyApIHtcblx0XHRcdFx0XHRkb2MuYWRkRXZlbnRMaXN0ZW5lciggb3JpZywgaGFuZGxlciwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGRhdGFQcml2LmFjY2VzcyggZG9jLCBmaXgsICggYXR0YWNoZXMgfHwgMCApICsgMSApO1xuXHRcdFx0fSxcblx0XHRcdHRlYXJkb3duOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGRvYyA9IHRoaXMub3duZXJEb2N1bWVudCB8fCB0aGlzLmRvY3VtZW50IHx8IHRoaXMsXG5cdFx0XHRcdFx0YXR0YWNoZXMgPSBkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4ICkgLSAxO1xuXG5cdFx0XHRcdGlmICggIWF0dGFjaGVzICkge1xuXHRcdFx0XHRcdGRvYy5yZW1vdmVFdmVudExpc3RlbmVyKCBvcmlnLCBoYW5kbGVyLCB0cnVlICk7XG5cdFx0XHRcdFx0ZGF0YVByaXYucmVtb3ZlKCBkb2MsIGZpeCApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZGF0YVByaXYuYWNjZXNzKCBkb2MsIGZpeCwgYXR0YWNoZXMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cdH0gKTtcbn1cbnZhciBsb2NhdGlvbiA9IHdpbmRvdy5sb2NhdGlvbjtcblxudmFyIG5vbmNlID0geyBndWlkOiBEYXRlLm5vdygpIH07XG5cbnZhciBycXVlcnkgPSAoIC9cXD8vICk7XG5cblxuXG4vLyBDcm9zcy1icm93c2VyIHhtbCBwYXJzaW5nXG5qUXVlcnkucGFyc2VYTUwgPSBmdW5jdGlvbiggZGF0YSApIHtcblx0dmFyIHhtbCwgcGFyc2VyRXJyb3JFbGVtO1xuXHRpZiAoICFkYXRhIHx8IHR5cGVvZiBkYXRhICE9PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExIG9ubHlcblx0Ly8gSUUgdGhyb3dzIG9uIHBhcnNlRnJvbVN0cmluZyB3aXRoIGludmFsaWQgaW5wdXQuXG5cdHRyeSB7XG5cdFx0eG1sID0gKCBuZXcgd2luZG93LkRPTVBhcnNlcigpICkucGFyc2VGcm9tU3RyaW5nKCBkYXRhLCBcInRleHQveG1sXCIgKTtcblx0fSBjYXRjaCAoIGUgKSB7fVxuXG5cdHBhcnNlckVycm9yRWxlbSA9IHhtbCAmJiB4bWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwicGFyc2VyZXJyb3JcIiApWyAwIF07XG5cdGlmICggIXhtbCB8fCBwYXJzZXJFcnJvckVsZW0gKSB7XG5cdFx0alF1ZXJ5LmVycm9yKCBcIkludmFsaWQgWE1MOiBcIiArIChcblx0XHRcdHBhcnNlckVycm9yRWxlbSA/XG5cdFx0XHRcdGpRdWVyeS5tYXAoIHBhcnNlckVycm9yRWxlbS5jaGlsZE5vZGVzLCBmdW5jdGlvbiggZWwgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGVsLnRleHRDb250ZW50O1xuXHRcdFx0XHR9ICkuam9pbiggXCJcXG5cIiApIDpcblx0XHRcdFx0ZGF0YVxuXHRcdCkgKTtcblx0fVxuXHRyZXR1cm4geG1sO1xufTtcblxuXG52YXJcblx0cmJyYWNrZXQgPSAvXFxbXFxdJC8sXG5cdHJDUkxGID0gL1xccj9cXG4vZyxcblx0cnN1Ym1pdHRlclR5cGVzID0gL14oPzpzdWJtaXR8YnV0dG9ufGltYWdlfHJlc2V0fGZpbGUpJC9pLFxuXHRyc3VibWl0dGFibGUgPSAvXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxrZXlnZW4pL2k7XG5cbmZ1bmN0aW9uIGJ1aWxkUGFyYW1zKCBwcmVmaXgsIG9iaiwgdHJhZGl0aW9uYWwsIGFkZCApIHtcblx0dmFyIG5hbWU7XG5cblx0aWYgKCBBcnJheS5pc0FycmF5KCBvYmogKSApIHtcblxuXHRcdC8vIFNlcmlhbGl6ZSBhcnJheSBpdGVtLlxuXHRcdGpRdWVyeS5lYWNoKCBvYmosIGZ1bmN0aW9uKCBpLCB2ICkge1xuXHRcdFx0aWYgKCB0cmFkaXRpb25hbCB8fCByYnJhY2tldC50ZXN0KCBwcmVmaXggKSApIHtcblxuXHRcdFx0XHQvLyBUcmVhdCBlYWNoIGFycmF5IGl0ZW0gYXMgYSBzY2FsYXIuXG5cdFx0XHRcdGFkZCggcHJlZml4LCB2ICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gSXRlbSBpcyBub24tc2NhbGFyIChhcnJheSBvciBvYmplY3QpLCBlbmNvZGUgaXRzIG51bWVyaWMgaW5kZXguXG5cdFx0XHRcdGJ1aWxkUGFyYW1zKFxuXHRcdFx0XHRcdHByZWZpeCArIFwiW1wiICsgKCB0eXBlb2YgdiA9PT0gXCJvYmplY3RcIiAmJiB2ICE9IG51bGwgPyBpIDogXCJcIiApICsgXCJdXCIsXG5cdFx0XHRcdFx0dixcblx0XHRcdFx0XHR0cmFkaXRpb25hbCxcblx0XHRcdFx0XHRhZGRcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9ICk7XG5cblx0fSBlbHNlIGlmICggIXRyYWRpdGlvbmFsICYmIHRvVHlwZSggb2JqICkgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHQvLyBTZXJpYWxpemUgb2JqZWN0IGl0ZW0uXG5cdFx0Zm9yICggbmFtZSBpbiBvYmogKSB7XG5cdFx0XHRidWlsZFBhcmFtcyggcHJlZml4ICsgXCJbXCIgKyBuYW1lICsgXCJdXCIsIG9ialsgbmFtZSBdLCB0cmFkaXRpb25hbCwgYWRkICk7XG5cdFx0fVxuXG5cdH0gZWxzZSB7XG5cblx0XHQvLyBTZXJpYWxpemUgc2NhbGFyIGl0ZW0uXG5cdFx0YWRkKCBwcmVmaXgsIG9iaiApO1xuXHR9XG59XG5cbi8vIFNlcmlhbGl6ZSBhbiBhcnJheSBvZiBmb3JtIGVsZW1lbnRzIG9yIGEgc2V0IG9mXG4vLyBrZXkvdmFsdWVzIGludG8gYSBxdWVyeSBzdHJpbmdcbmpRdWVyeS5wYXJhbSA9IGZ1bmN0aW9uKCBhLCB0cmFkaXRpb25hbCApIHtcblx0dmFyIHByZWZpeCxcblx0XHRzID0gW10sXG5cdFx0YWRkID0gZnVuY3Rpb24oIGtleSwgdmFsdWVPckZ1bmN0aW9uICkge1xuXG5cdFx0XHQvLyBJZiB2YWx1ZSBpcyBhIGZ1bmN0aW9uLCBpbnZva2UgaXQgYW5kIHVzZSBpdHMgcmV0dXJuIHZhbHVlXG5cdFx0XHR2YXIgdmFsdWUgPSBpc0Z1bmN0aW9uKCB2YWx1ZU9yRnVuY3Rpb24gKSA/XG5cdFx0XHRcdHZhbHVlT3JGdW5jdGlvbigpIDpcblx0XHRcdFx0dmFsdWVPckZ1bmN0aW9uO1xuXG5cdFx0XHRzWyBzLmxlbmd0aCBdID0gZW5jb2RlVVJJQ29tcG9uZW50KCBrZXkgKSArIFwiPVwiICtcblx0XHRcdFx0ZW5jb2RlVVJJQ29tcG9uZW50KCB2YWx1ZSA9PSBudWxsID8gXCJcIiA6IHZhbHVlICk7XG5cdFx0fTtcblxuXHRpZiAoIGEgPT0gbnVsbCApIHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXG5cdC8vIElmIGFuIGFycmF5IHdhcyBwYXNzZWQgaW4sIGFzc3VtZSB0aGF0IGl0IGlzIGFuIGFycmF5IG9mIGZvcm0gZWxlbWVudHMuXG5cdGlmICggQXJyYXkuaXNBcnJheSggYSApIHx8ICggYS5qcXVlcnkgJiYgIWpRdWVyeS5pc1BsYWluT2JqZWN0KCBhICkgKSApIHtcblxuXHRcdC8vIFNlcmlhbGl6ZSB0aGUgZm9ybSBlbGVtZW50c1xuXHRcdGpRdWVyeS5lYWNoKCBhLCBmdW5jdGlvbigpIHtcblx0XHRcdGFkZCggdGhpcy5uYW1lLCB0aGlzLnZhbHVlICk7XG5cdFx0fSApO1xuXG5cdH0gZWxzZSB7XG5cblx0XHQvLyBJZiB0cmFkaXRpb25hbCwgZW5jb2RlIHRoZSBcIm9sZFwiIHdheSAodGhlIHdheSAxLjMuMiBvciBvbGRlclxuXHRcdC8vIGRpZCBpdCksIG90aGVyd2lzZSBlbmNvZGUgcGFyYW1zIHJlY3Vyc2l2ZWx5LlxuXHRcdGZvciAoIHByZWZpeCBpbiBhICkge1xuXHRcdFx0YnVpbGRQYXJhbXMoIHByZWZpeCwgYVsgcHJlZml4IF0sIHRyYWRpdGlvbmFsLCBhZGQgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIHJlc3VsdGluZyBzZXJpYWxpemF0aW9uXG5cdHJldHVybiBzLmpvaW4oIFwiJlwiICk7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHNlcmlhbGl6ZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5wYXJhbSggdGhpcy5zZXJpYWxpemVBcnJheSgpICk7XG5cdH0sXG5cdHNlcmlhbGl6ZUFycmF5OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5tYXAoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBDYW4gYWRkIHByb3BIb29rIGZvciBcImVsZW1lbnRzXCIgdG8gZmlsdGVyIG9yIGFkZCBmb3JtIGVsZW1lbnRzXG5cdFx0XHR2YXIgZWxlbWVudHMgPSBqUXVlcnkucHJvcCggdGhpcywgXCJlbGVtZW50c1wiICk7XG5cdFx0XHRyZXR1cm4gZWxlbWVudHMgPyBqUXVlcnkubWFrZUFycmF5KCBlbGVtZW50cyApIDogdGhpcztcblx0XHR9ICkuZmlsdGVyKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciB0eXBlID0gdGhpcy50eXBlO1xuXG5cdFx0XHQvLyBVc2UgLmlzKCBcIjpkaXNhYmxlZFwiICkgc28gdGhhdCBmaWVsZHNldFtkaXNhYmxlZF0gd29ya3Ncblx0XHRcdHJldHVybiB0aGlzLm5hbWUgJiYgIWpRdWVyeSggdGhpcyApLmlzKCBcIjpkaXNhYmxlZFwiICkgJiZcblx0XHRcdFx0cnN1Ym1pdHRhYmxlLnRlc3QoIHRoaXMubm9kZU5hbWUgKSAmJiAhcnN1Ym1pdHRlclR5cGVzLnRlc3QoIHR5cGUgKSAmJlxuXHRcdFx0XHQoIHRoaXMuY2hlY2tlZCB8fCAhcmNoZWNrYWJsZVR5cGUudGVzdCggdHlwZSApICk7XG5cdFx0fSApLm1hcCggZnVuY3Rpb24oIF9pLCBlbGVtICkge1xuXHRcdFx0dmFyIHZhbCA9IGpRdWVyeSggdGhpcyApLnZhbCgpO1xuXG5cdFx0XHRpZiAoIHZhbCA9PSBudWxsICkge1xuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBBcnJheS5pc0FycmF5KCB2YWwgKSApIHtcblx0XHRcdFx0cmV0dXJuIGpRdWVyeS5tYXAoIHZhbCwgZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdFx0XHRyZXR1cm4geyBuYW1lOiBlbGVtLm5hbWUsIHZhbHVlOiB2YWwucmVwbGFjZSggckNSTEYsIFwiXFxyXFxuXCIgKSB9O1xuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB7IG5hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbC5yZXBsYWNlKCByQ1JMRiwgXCJcXHJcXG5cIiApIH07XG5cdFx0fSApLmdldCgpO1xuXHR9XG59ICk7XG5cblxudmFyXG5cdHIyMCA9IC8lMjAvZyxcblx0cmhhc2ggPSAvIy4qJC8sXG5cdHJhbnRpQ2FjaGUgPSAvKFs/Jl0pXz1bXiZdKi8sXG5cdHJoZWFkZXJzID0gL14oLio/KTpbIFxcdF0qKFteXFxyXFxuXSopJC9tZyxcblxuXHQvLyAjNzY1MywgIzgxMjUsICM4MTUyOiBsb2NhbCBwcm90b2NvbCBkZXRlY3Rpb25cblx0cmxvY2FsUHJvdG9jb2wgPSAvXig/OmFib3V0fGFwcHxhcHAtc3RvcmFnZXwuKy1leHRlbnNpb258ZmlsZXxyZXN8d2lkZ2V0KTokLyxcblx0cm5vQ29udGVudCA9IC9eKD86R0VUfEhFQUQpJC8sXG5cdHJwcm90b2NvbCA9IC9eXFwvXFwvLyxcblxuXHQvKiBQcmVmaWx0ZXJzXG5cdCAqIDEpIFRoZXkgYXJlIHVzZWZ1bCB0byBpbnRyb2R1Y2UgY3VzdG9tIGRhdGFUeXBlcyAoc2VlIGFqYXgvanNvbnAuanMgZm9yIGFuIGV4YW1wbGUpXG5cdCAqIDIpIFRoZXNlIGFyZSBjYWxsZWQ6XG5cdCAqICAgIC0gQkVGT1JFIGFza2luZyBmb3IgYSB0cmFuc3BvcnRcblx0ICogICAgLSBBRlRFUiBwYXJhbSBzZXJpYWxpemF0aW9uIChzLmRhdGEgaXMgYSBzdHJpbmcgaWYgcy5wcm9jZXNzRGF0YSBpcyB0cnVlKVxuXHQgKiAzKSBrZXkgaXMgdGhlIGRhdGFUeXBlXG5cdCAqIDQpIHRoZSBjYXRjaGFsbCBzeW1ib2wgXCIqXCIgY2FuIGJlIHVzZWRcblx0ICogNSkgZXhlY3V0aW9uIHdpbGwgc3RhcnQgd2l0aCB0cmFuc3BvcnQgZGF0YVR5cGUgYW5kIFRIRU4gY29udGludWUgZG93biB0byBcIipcIiBpZiBuZWVkZWRcblx0ICovXG5cdHByZWZpbHRlcnMgPSB7fSxcblxuXHQvKiBUcmFuc3BvcnRzIGJpbmRpbmdzXG5cdCAqIDEpIGtleSBpcyB0aGUgZGF0YVR5cGVcblx0ICogMikgdGhlIGNhdGNoYWxsIHN5bWJvbCBcIipcIiBjYW4gYmUgdXNlZFxuXHQgKiAzKSBzZWxlY3Rpb24gd2lsbCBzdGFydCB3aXRoIHRyYW5zcG9ydCBkYXRhVHlwZSBhbmQgVEhFTiBnbyB0byBcIipcIiBpZiBuZWVkZWRcblx0ICovXG5cdHRyYW5zcG9ydHMgPSB7fSxcblxuXHQvLyBBdm9pZCBjb21tZW50LXByb2xvZyBjaGFyIHNlcXVlbmNlICgjMTAwOTgpOyBtdXN0IGFwcGVhc2UgbGludCBhbmQgZXZhZGUgY29tcHJlc3Npb25cblx0YWxsVHlwZXMgPSBcIiovXCIuY29uY2F0KCBcIipcIiApLFxuXG5cdC8vIEFuY2hvciB0YWcgZm9yIHBhcnNpbmcgdGhlIGRvY3VtZW50IG9yaWdpblxuXHRvcmlnaW5BbmNob3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImFcIiApO1xuXG5vcmlnaW5BbmNob3IuaHJlZiA9IGxvY2F0aW9uLmhyZWY7XG5cbi8vIEJhc2UgXCJjb25zdHJ1Y3RvclwiIGZvciBqUXVlcnkuYWpheFByZWZpbHRlciBhbmQgalF1ZXJ5LmFqYXhUcmFuc3BvcnRcbmZ1bmN0aW9uIGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggc3RydWN0dXJlICkge1xuXG5cdC8vIGRhdGFUeXBlRXhwcmVzc2lvbiBpcyBvcHRpb25hbCBhbmQgZGVmYXVsdHMgdG8gXCIqXCJcblx0cmV0dXJuIGZ1bmN0aW9uKCBkYXRhVHlwZUV4cHJlc3Npb24sIGZ1bmMgKSB7XG5cblx0XHRpZiAoIHR5cGVvZiBkYXRhVHlwZUV4cHJlc3Npb24gIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRmdW5jID0gZGF0YVR5cGVFeHByZXNzaW9uO1xuXHRcdFx0ZGF0YVR5cGVFeHByZXNzaW9uID0gXCIqXCI7XG5cdFx0fVxuXG5cdFx0dmFyIGRhdGFUeXBlLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRkYXRhVHlwZXMgPSBkYXRhVHlwZUV4cHJlc3Npb24udG9Mb3dlckNhc2UoKS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdO1xuXG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCBmdW5jICkgKSB7XG5cblx0XHRcdC8vIEZvciBlYWNoIGRhdGFUeXBlIGluIHRoZSBkYXRhVHlwZUV4cHJlc3Npb25cblx0XHRcdHdoaWxlICggKCBkYXRhVHlwZSA9IGRhdGFUeXBlc1sgaSsrIF0gKSApIHtcblxuXHRcdFx0XHQvLyBQcmVwZW5kIGlmIHJlcXVlc3RlZFxuXHRcdFx0XHRpZiAoIGRhdGFUeXBlWyAwIF0gPT09IFwiK1wiICkge1xuXHRcdFx0XHRcdGRhdGFUeXBlID0gZGF0YVR5cGUuc2xpY2UoIDEgKSB8fCBcIipcIjtcblx0XHRcdFx0XHQoIHN0cnVjdHVyZVsgZGF0YVR5cGUgXSA9IHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSApLnVuc2hpZnQoIGZ1bmMgKTtcblxuXHRcdFx0XHQvLyBPdGhlcndpc2UgYXBwZW5kXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0KCBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gPSBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10gKS5wdXNoKCBmdW5jICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH07XG59XG5cbi8vIEJhc2UgaW5zcGVjdGlvbiBmdW5jdGlvbiBmb3IgcHJlZmlsdGVycyBhbmQgdHJhbnNwb3J0c1xuZnVuY3Rpb24gaW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHN0cnVjdHVyZSwgb3B0aW9ucywgb3JpZ2luYWxPcHRpb25zLCBqcVhIUiApIHtcblxuXHR2YXIgaW5zcGVjdGVkID0ge30sXG5cdFx0c2Vla2luZ1RyYW5zcG9ydCA9ICggc3RydWN0dXJlID09PSB0cmFuc3BvcnRzICk7XG5cblx0ZnVuY3Rpb24gaW5zcGVjdCggZGF0YVR5cGUgKSB7XG5cdFx0dmFyIHNlbGVjdGVkO1xuXHRcdGluc3BlY3RlZFsgZGF0YVR5cGUgXSA9IHRydWU7XG5cdFx0alF1ZXJ5LmVhY2goIHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSwgZnVuY3Rpb24oIF8sIHByZWZpbHRlck9yRmFjdG9yeSApIHtcblx0XHRcdHZhciBkYXRhVHlwZU9yVHJhbnNwb3J0ID0gcHJlZmlsdGVyT3JGYWN0b3J5KCBvcHRpb25zLCBvcmlnaW5hbE9wdGlvbnMsIGpxWEhSICk7XG5cdFx0XHRpZiAoIHR5cGVvZiBkYXRhVHlwZU9yVHJhbnNwb3J0ID09PSBcInN0cmluZ1wiICYmXG5cdFx0XHRcdCFzZWVraW5nVHJhbnNwb3J0ICYmICFpbnNwZWN0ZWRbIGRhdGFUeXBlT3JUcmFuc3BvcnQgXSApIHtcblxuXHRcdFx0XHRvcHRpb25zLmRhdGFUeXBlcy51bnNoaWZ0KCBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7XG5cdFx0XHRcdGluc3BlY3QoIGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fSBlbHNlIGlmICggc2Vla2luZ1RyYW5zcG9ydCApIHtcblx0XHRcdFx0cmV0dXJuICEoIHNlbGVjdGVkID0gZGF0YVR5cGVPclRyYW5zcG9ydCApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0XHRyZXR1cm4gc2VsZWN0ZWQ7XG5cdH1cblxuXHRyZXR1cm4gaW5zcGVjdCggb3B0aW9ucy5kYXRhVHlwZXNbIDAgXSApIHx8ICFpbnNwZWN0ZWRbIFwiKlwiIF0gJiYgaW5zcGVjdCggXCIqXCIgKTtcbn1cblxuLy8gQSBzcGVjaWFsIGV4dGVuZCBmb3IgYWpheCBvcHRpb25zXG4vLyB0aGF0IHRha2VzIFwiZmxhdFwiIG9wdGlvbnMgKG5vdCB0byBiZSBkZWVwIGV4dGVuZGVkKVxuLy8gRml4ZXMgIzk4ODdcbmZ1bmN0aW9uIGFqYXhFeHRlbmQoIHRhcmdldCwgc3JjICkge1xuXHR2YXIga2V5LCBkZWVwLFxuXHRcdGZsYXRPcHRpb25zID0galF1ZXJ5LmFqYXhTZXR0aW5ncy5mbGF0T3B0aW9ucyB8fCB7fTtcblxuXHRmb3IgKCBrZXkgaW4gc3JjICkge1xuXHRcdGlmICggc3JjWyBrZXkgXSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0KCBmbGF0T3B0aW9uc1sga2V5IF0gPyB0YXJnZXQgOiAoIGRlZXAgfHwgKCBkZWVwID0ge30gKSApIClbIGtleSBdID0gc3JjWyBrZXkgXTtcblx0XHR9XG5cdH1cblx0aWYgKCBkZWVwICkge1xuXHRcdGpRdWVyeS5leHRlbmQoIHRydWUsIHRhcmdldCwgZGVlcCApO1xuXHR9XG5cblx0cmV0dXJuIHRhcmdldDtcbn1cblxuLyogSGFuZGxlcyByZXNwb25zZXMgdG8gYW4gYWpheCByZXF1ZXN0OlxuICogLSBmaW5kcyB0aGUgcmlnaHQgZGF0YVR5cGUgKG1lZGlhdGVzIGJldHdlZW4gY29udGVudC10eXBlIGFuZCBleHBlY3RlZCBkYXRhVHlwZSlcbiAqIC0gcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZVxuICovXG5mdW5jdGlvbiBhamF4SGFuZGxlUmVzcG9uc2VzKCBzLCBqcVhIUiwgcmVzcG9uc2VzICkge1xuXG5cdHZhciBjdCwgdHlwZSwgZmluYWxEYXRhVHlwZSwgZmlyc3REYXRhVHlwZSxcblx0XHRjb250ZW50cyA9IHMuY29udGVudHMsXG5cdFx0ZGF0YVR5cGVzID0gcy5kYXRhVHlwZXM7XG5cblx0Ly8gUmVtb3ZlIGF1dG8gZGF0YVR5cGUgYW5kIGdldCBjb250ZW50LXR5cGUgaW4gdGhlIHByb2Nlc3Ncblx0d2hpbGUgKCBkYXRhVHlwZXNbIDAgXSA9PT0gXCIqXCIgKSB7XG5cdFx0ZGF0YVR5cGVzLnNoaWZ0KCk7XG5cdFx0aWYgKCBjdCA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0Y3QgPSBzLm1pbWVUeXBlIHx8IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKCBcIkNvbnRlbnQtVHlwZVwiICk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ2hlY2sgaWYgd2UncmUgZGVhbGluZyB3aXRoIGEga25vd24gY29udGVudC10eXBlXG5cdGlmICggY3QgKSB7XG5cdFx0Zm9yICggdHlwZSBpbiBjb250ZW50cyApIHtcblx0XHRcdGlmICggY29udGVudHNbIHR5cGUgXSAmJiBjb250ZW50c1sgdHlwZSBdLnRlc3QoIGN0ICkgKSB7XG5cdFx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCB0eXBlICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIENoZWNrIHRvIHNlZSBpZiB3ZSBoYXZlIGEgcmVzcG9uc2UgZm9yIHRoZSBleHBlY3RlZCBkYXRhVHlwZVxuXHRpZiAoIGRhdGFUeXBlc1sgMCBdIGluIHJlc3BvbnNlcyApIHtcblx0XHRmaW5hbERhdGFUeXBlID0gZGF0YVR5cGVzWyAwIF07XG5cdH0gZWxzZSB7XG5cblx0XHQvLyBUcnkgY29udmVydGlibGUgZGF0YVR5cGVzXG5cdFx0Zm9yICggdHlwZSBpbiByZXNwb25zZXMgKSB7XG5cdFx0XHRpZiAoICFkYXRhVHlwZXNbIDAgXSB8fCBzLmNvbnZlcnRlcnNbIHR5cGUgKyBcIiBcIiArIGRhdGFUeXBlc1sgMCBdIF0gKSB7XG5cdFx0XHRcdGZpbmFsRGF0YVR5cGUgPSB0eXBlO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGlmICggIWZpcnN0RGF0YVR5cGUgKSB7XG5cdFx0XHRcdGZpcnN0RGF0YVR5cGUgPSB0eXBlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIE9yIGp1c3QgdXNlIGZpcnN0IG9uZVxuXHRcdGZpbmFsRGF0YVR5cGUgPSBmaW5hbERhdGFUeXBlIHx8IGZpcnN0RGF0YVR5cGU7XG5cdH1cblxuXHQvLyBJZiB3ZSBmb3VuZCBhIGRhdGFUeXBlXG5cdC8vIFdlIGFkZCB0aGUgZGF0YVR5cGUgdG8gdGhlIGxpc3QgaWYgbmVlZGVkXG5cdC8vIGFuZCByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgcmVzcG9uc2Vcblx0aWYgKCBmaW5hbERhdGFUeXBlICkge1xuXHRcdGlmICggZmluYWxEYXRhVHlwZSAhPT0gZGF0YVR5cGVzWyAwIF0gKSB7XG5cdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggZmluYWxEYXRhVHlwZSApO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVzcG9uc2VzWyBmaW5hbERhdGFUeXBlIF07XG5cdH1cbn1cblxuLyogQ2hhaW4gY29udmVyc2lvbnMgZ2l2ZW4gdGhlIHJlcXVlc3QgYW5kIHRoZSBvcmlnaW5hbCByZXNwb25zZVxuICogQWxzbyBzZXRzIHRoZSByZXNwb25zZVhYWCBmaWVsZHMgb24gdGhlIGpxWEhSIGluc3RhbmNlXG4gKi9cbmZ1bmN0aW9uIGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApIHtcblx0dmFyIGNvbnYyLCBjdXJyZW50LCBjb252LCB0bXAsIHByZXYsXG5cdFx0Y29udmVydGVycyA9IHt9LFxuXG5cdFx0Ly8gV29yayB3aXRoIGEgY29weSBvZiBkYXRhVHlwZXMgaW4gY2FzZSB3ZSBuZWVkIHRvIG1vZGlmeSBpdCBmb3IgY29udmVyc2lvblxuXHRcdGRhdGFUeXBlcyA9IHMuZGF0YVR5cGVzLnNsaWNlKCk7XG5cblx0Ly8gQ3JlYXRlIGNvbnZlcnRlcnMgbWFwIHdpdGggbG93ZXJjYXNlZCBrZXlzXG5cdGlmICggZGF0YVR5cGVzWyAxIF0gKSB7XG5cdFx0Zm9yICggY29udiBpbiBzLmNvbnZlcnRlcnMgKSB7XG5cdFx0XHRjb252ZXJ0ZXJzWyBjb252LnRvTG93ZXJDYXNlKCkgXSA9IHMuY29udmVydGVyc1sgY29udiBdO1xuXHRcdH1cblx0fVxuXG5cdGN1cnJlbnQgPSBkYXRhVHlwZXMuc2hpZnQoKTtcblxuXHQvLyBDb252ZXJ0IHRvIGVhY2ggc2VxdWVudGlhbCBkYXRhVHlwZVxuXHR3aGlsZSAoIGN1cnJlbnQgKSB7XG5cblx0XHRpZiAoIHMucmVzcG9uc2VGaWVsZHNbIGN1cnJlbnQgXSApIHtcblx0XHRcdGpxWEhSWyBzLnJlc3BvbnNlRmllbGRzWyBjdXJyZW50IF0gXSA9IHJlc3BvbnNlO1xuXHRcdH1cblxuXHRcdC8vIEFwcGx5IHRoZSBkYXRhRmlsdGVyIGlmIHByb3ZpZGVkXG5cdFx0aWYgKCAhcHJldiAmJiBpc1N1Y2Nlc3MgJiYgcy5kYXRhRmlsdGVyICkge1xuXHRcdFx0cmVzcG9uc2UgPSBzLmRhdGFGaWx0ZXIoIHJlc3BvbnNlLCBzLmRhdGFUeXBlICk7XG5cdFx0fVxuXG5cdFx0cHJldiA9IGN1cnJlbnQ7XG5cdFx0Y3VycmVudCA9IGRhdGFUeXBlcy5zaGlmdCgpO1xuXG5cdFx0aWYgKCBjdXJyZW50ICkge1xuXG5cdFx0XHQvLyBUaGVyZSdzIG9ubHkgd29yayB0byBkbyBpZiBjdXJyZW50IGRhdGFUeXBlIGlzIG5vbi1hdXRvXG5cdFx0XHRpZiAoIGN1cnJlbnQgPT09IFwiKlwiICkge1xuXG5cdFx0XHRcdGN1cnJlbnQgPSBwcmV2O1xuXG5cdFx0XHQvLyBDb252ZXJ0IHJlc3BvbnNlIGlmIHByZXYgZGF0YVR5cGUgaXMgbm9uLWF1dG8gYW5kIGRpZmZlcnMgZnJvbSBjdXJyZW50XG5cdFx0XHR9IGVsc2UgaWYgKCBwcmV2ICE9PSBcIipcIiAmJiBwcmV2ICE9PSBjdXJyZW50ICkge1xuXG5cdFx0XHRcdC8vIFNlZWsgYSBkaXJlY3QgY29udmVydGVyXG5cdFx0XHRcdGNvbnYgPSBjb252ZXJ0ZXJzWyBwcmV2ICsgXCIgXCIgKyBjdXJyZW50IF0gfHwgY29udmVydGVyc1sgXCIqIFwiICsgY3VycmVudCBdO1xuXG5cdFx0XHRcdC8vIElmIG5vbmUgZm91bmQsIHNlZWsgYSBwYWlyXG5cdFx0XHRcdGlmICggIWNvbnYgKSB7XG5cdFx0XHRcdFx0Zm9yICggY29udjIgaW4gY29udmVydGVycyApIHtcblxuXHRcdFx0XHRcdFx0Ly8gSWYgY29udjIgb3V0cHV0cyBjdXJyZW50XG5cdFx0XHRcdFx0XHR0bXAgPSBjb252Mi5zcGxpdCggXCIgXCIgKTtcblx0XHRcdFx0XHRcdGlmICggdG1wWyAxIF0gPT09IGN1cnJlbnQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gSWYgcHJldiBjYW4gYmUgY29udmVydGVkIHRvIGFjY2VwdGVkIGlucHV0XG5cdFx0XHRcdFx0XHRcdGNvbnYgPSBjb252ZXJ0ZXJzWyBwcmV2ICsgXCIgXCIgKyB0bXBbIDAgXSBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0Y29udmVydGVyc1sgXCIqIFwiICsgdG1wWyAwIF0gXTtcblx0XHRcdFx0XHRcdFx0aWYgKCBjb252ICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gQ29uZGVuc2UgZXF1aXZhbGVuY2UgY29udmVydGVyc1xuXHRcdFx0XHRcdFx0XHRcdGlmICggY29udiA9PT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnYgPSBjb252ZXJ0ZXJzWyBjb252MiBdO1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gT3RoZXJ3aXNlLCBpbnNlcnQgdGhlIGludGVybWVkaWF0ZSBkYXRhVHlwZVxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGNvbnZlcnRlcnNbIGNvbnYyIF0gIT09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjdXJyZW50ID0gdG1wWyAwIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggdG1wWyAxIF0gKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBcHBseSBjb252ZXJ0ZXIgKGlmIG5vdCBhbiBlcXVpdmFsZW5jZSlcblx0XHRcdFx0aWYgKCBjb252ICE9PSB0cnVlICkge1xuXG5cdFx0XHRcdFx0Ly8gVW5sZXNzIGVycm9ycyBhcmUgYWxsb3dlZCB0byBidWJibGUsIGNhdGNoIGFuZCByZXR1cm4gdGhlbVxuXHRcdFx0XHRcdGlmICggY29udiAmJiBzLnRocm93cyApIHtcblx0XHRcdFx0XHRcdHJlc3BvbnNlID0gY29udiggcmVzcG9uc2UgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBjb252KCByZXNwb25zZSApO1xuXHRcdFx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRcdFx0c3RhdGU6IFwicGFyc2VyZXJyb3JcIixcblx0XHRcdFx0XHRcdFx0XHRlcnJvcjogY29udiA/IGUgOiBcIk5vIGNvbnZlcnNpb24gZnJvbSBcIiArIHByZXYgKyBcIiB0byBcIiArIGN1cnJlbnRcblx0XHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4geyBzdGF0ZTogXCJzdWNjZXNzXCIsIGRhdGE6IHJlc3BvbnNlIH07XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHQvLyBDb3VudGVyIGZvciBob2xkaW5nIHRoZSBudW1iZXIgb2YgYWN0aXZlIHF1ZXJpZXNcblx0YWN0aXZlOiAwLFxuXG5cdC8vIExhc3QtTW9kaWZpZWQgaGVhZGVyIGNhY2hlIGZvciBuZXh0IHJlcXVlc3Rcblx0bGFzdE1vZGlmaWVkOiB7fSxcblx0ZXRhZzoge30sXG5cblx0YWpheFNldHRpbmdzOiB7XG5cdFx0dXJsOiBsb2NhdGlvbi5ocmVmLFxuXHRcdHR5cGU6IFwiR0VUXCIsXG5cdFx0aXNMb2NhbDogcmxvY2FsUHJvdG9jb2wudGVzdCggbG9jYXRpb24ucHJvdG9jb2wgKSxcblx0XHRnbG9iYWw6IHRydWUsXG5cdFx0cHJvY2Vzc0RhdGE6IHRydWUsXG5cdFx0YXN5bmM6IHRydWUsXG5cdFx0Y29udGVudFR5cGU6IFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04XCIsXG5cblx0XHQvKlxuXHRcdHRpbWVvdXQ6IDAsXG5cdFx0ZGF0YTogbnVsbCxcblx0XHRkYXRhVHlwZTogbnVsbCxcblx0XHR1c2VybmFtZTogbnVsbCxcblx0XHRwYXNzd29yZDogbnVsbCxcblx0XHRjYWNoZTogbnVsbCxcblx0XHR0aHJvd3M6IGZhbHNlLFxuXHRcdHRyYWRpdGlvbmFsOiBmYWxzZSxcblx0XHRoZWFkZXJzOiB7fSxcblx0XHQqL1xuXG5cdFx0YWNjZXB0czoge1xuXHRcdFx0XCIqXCI6IGFsbFR5cGVzLFxuXHRcdFx0dGV4dDogXCJ0ZXh0L3BsYWluXCIsXG5cdFx0XHRodG1sOiBcInRleHQvaHRtbFwiLFxuXHRcdFx0eG1sOiBcImFwcGxpY2F0aW9uL3htbCwgdGV4dC94bWxcIixcblx0XHRcdGpzb246IFwiYXBwbGljYXRpb24vanNvbiwgdGV4dC9qYXZhc2NyaXB0XCJcblx0XHR9LFxuXG5cdFx0Y29udGVudHM6IHtcblx0XHRcdHhtbDogL1xcYnhtbFxcYi8sXG5cdFx0XHRodG1sOiAvXFxiaHRtbC8sXG5cdFx0XHRqc29uOiAvXFxianNvblxcYi9cblx0XHR9LFxuXG5cdFx0cmVzcG9uc2VGaWVsZHM6IHtcblx0XHRcdHhtbDogXCJyZXNwb25zZVhNTFwiLFxuXHRcdFx0dGV4dDogXCJyZXNwb25zZVRleHRcIixcblx0XHRcdGpzb246IFwicmVzcG9uc2VKU09OXCJcblx0XHR9LFxuXG5cdFx0Ly8gRGF0YSBjb252ZXJ0ZXJzXG5cdFx0Ly8gS2V5cyBzZXBhcmF0ZSBzb3VyY2UgKG9yIGNhdGNoYWxsIFwiKlwiKSBhbmQgZGVzdGluYXRpb24gdHlwZXMgd2l0aCBhIHNpbmdsZSBzcGFjZVxuXHRcdGNvbnZlcnRlcnM6IHtcblxuXHRcdFx0Ly8gQ29udmVydCBhbnl0aGluZyB0byB0ZXh0XG5cdFx0XHRcIiogdGV4dFwiOiBTdHJpbmcsXG5cblx0XHRcdC8vIFRleHQgdG8gaHRtbCAodHJ1ZSA9IG5vIHRyYW5zZm9ybWF0aW9uKVxuXHRcdFx0XCJ0ZXh0IGh0bWxcIjogdHJ1ZSxcblxuXHRcdFx0Ly8gRXZhbHVhdGUgdGV4dCBhcyBhIGpzb24gZXhwcmVzc2lvblxuXHRcdFx0XCJ0ZXh0IGpzb25cIjogSlNPTi5wYXJzZSxcblxuXHRcdFx0Ly8gUGFyc2UgdGV4dCBhcyB4bWxcblx0XHRcdFwidGV4dCB4bWxcIjogalF1ZXJ5LnBhcnNlWE1MXG5cdFx0fSxcblxuXHRcdC8vIEZvciBvcHRpb25zIHRoYXQgc2hvdWxkbid0IGJlIGRlZXAgZXh0ZW5kZWQ6XG5cdFx0Ly8geW91IGNhbiBhZGQgeW91ciBvd24gY3VzdG9tIG9wdGlvbnMgaGVyZSBpZlxuXHRcdC8vIGFuZCB3aGVuIHlvdSBjcmVhdGUgb25lIHRoYXQgc2hvdWxkbid0IGJlXG5cdFx0Ly8gZGVlcCBleHRlbmRlZCAoc2VlIGFqYXhFeHRlbmQpXG5cdFx0ZmxhdE9wdGlvbnM6IHtcblx0XHRcdHVybDogdHJ1ZSxcblx0XHRcdGNvbnRleHQ6IHRydWVcblx0XHR9XG5cdH0sXG5cblx0Ly8gQ3JlYXRlcyBhIGZ1bGwgZmxlZGdlZCBzZXR0aW5ncyBvYmplY3QgaW50byB0YXJnZXRcblx0Ly8gd2l0aCBib3RoIGFqYXhTZXR0aW5ncyBhbmQgc2V0dGluZ3MgZmllbGRzLlxuXHQvLyBJZiB0YXJnZXQgaXMgb21pdHRlZCwgd3JpdGVzIGludG8gYWpheFNldHRpbmdzLlxuXHRhamF4U2V0dXA6IGZ1bmN0aW9uKCB0YXJnZXQsIHNldHRpbmdzICkge1xuXHRcdHJldHVybiBzZXR0aW5ncyA/XG5cblx0XHRcdC8vIEJ1aWxkaW5nIGEgc2V0dGluZ3Mgb2JqZWN0XG5cdFx0XHRhamF4RXh0ZW5kKCBhamF4RXh0ZW5kKCB0YXJnZXQsIGpRdWVyeS5hamF4U2V0dGluZ3MgKSwgc2V0dGluZ3MgKSA6XG5cblx0XHRcdC8vIEV4dGVuZGluZyBhamF4U2V0dGluZ3Ncblx0XHRcdGFqYXhFeHRlbmQoIGpRdWVyeS5hamF4U2V0dGluZ3MsIHRhcmdldCApO1xuXHR9LFxuXG5cdGFqYXhQcmVmaWx0ZXI6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggcHJlZmlsdGVycyApLFxuXHRhamF4VHJhbnNwb3J0OiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHRyYW5zcG9ydHMgKSxcblxuXHQvLyBNYWluIG1ldGhvZFxuXHRhamF4OiBmdW5jdGlvbiggdXJsLCBvcHRpb25zICkge1xuXG5cdFx0Ly8gSWYgdXJsIGlzIGFuIG9iamVjdCwgc2ltdWxhdGUgcHJlLTEuNSBzaWduYXR1cmVcblx0XHRpZiAoIHR5cGVvZiB1cmwgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHRvcHRpb25zID0gdXJsO1xuXHRcdFx0dXJsID0gdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdC8vIEZvcmNlIG9wdGlvbnMgdG8gYmUgYW4gb2JqZWN0XG5cdFx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cblx0XHR2YXIgdHJhbnNwb3J0LFxuXG5cdFx0XHQvLyBVUkwgd2l0aG91dCBhbnRpLWNhY2hlIHBhcmFtXG5cdFx0XHRjYWNoZVVSTCxcblxuXHRcdFx0Ly8gUmVzcG9uc2UgaGVhZGVyc1xuXHRcdFx0cmVzcG9uc2VIZWFkZXJzU3RyaW5nLFxuXHRcdFx0cmVzcG9uc2VIZWFkZXJzLFxuXG5cdFx0XHQvLyB0aW1lb3V0IGhhbmRsZVxuXHRcdFx0dGltZW91dFRpbWVyLFxuXG5cdFx0XHQvLyBVcmwgY2xlYW51cCB2YXJcblx0XHRcdHVybEFuY2hvcixcblxuXHRcdFx0Ly8gUmVxdWVzdCBzdGF0ZSAoYmVjb21lcyBmYWxzZSB1cG9uIHNlbmQgYW5kIHRydWUgdXBvbiBjb21wbGV0aW9uKVxuXHRcdFx0Y29tcGxldGVkLFxuXG5cdFx0XHQvLyBUbyBrbm93IGlmIGdsb2JhbCBldmVudHMgYXJlIHRvIGJlIGRpc3BhdGNoZWRcblx0XHRcdGZpcmVHbG9iYWxzLFxuXG5cdFx0XHQvLyBMb29wIHZhcmlhYmxlXG5cdFx0XHRpLFxuXG5cdFx0XHQvLyB1bmNhY2hlZCBwYXJ0IG9mIHRoZSB1cmxcblx0XHRcdHVuY2FjaGVkLFxuXG5cdFx0XHQvLyBDcmVhdGUgdGhlIGZpbmFsIG9wdGlvbnMgb2JqZWN0XG5cdFx0XHRzID0galF1ZXJ5LmFqYXhTZXR1cCgge30sIG9wdGlvbnMgKSxcblxuXHRcdFx0Ly8gQ2FsbGJhY2tzIGNvbnRleHRcblx0XHRcdGNhbGxiYWNrQ29udGV4dCA9IHMuY29udGV4dCB8fCBzLFxuXG5cdFx0XHQvLyBDb250ZXh0IGZvciBnbG9iYWwgZXZlbnRzIGlzIGNhbGxiYWNrQ29udGV4dCBpZiBpdCBpcyBhIERPTSBub2RlIG9yIGpRdWVyeSBjb2xsZWN0aW9uXG5cdFx0XHRnbG9iYWxFdmVudENvbnRleHQgPSBzLmNvbnRleHQgJiZcblx0XHRcdFx0KCBjYWxsYmFja0NvbnRleHQubm9kZVR5cGUgfHwgY2FsbGJhY2tDb250ZXh0LmpxdWVyeSApID9cblx0XHRcdFx0alF1ZXJ5KCBjYWxsYmFja0NvbnRleHQgKSA6XG5cdFx0XHRcdGpRdWVyeS5ldmVudCxcblxuXHRcdFx0Ly8gRGVmZXJyZWRzXG5cdFx0XHRkZWZlcnJlZCA9IGpRdWVyeS5EZWZlcnJlZCgpLFxuXHRcdFx0Y29tcGxldGVEZWZlcnJlZCA9IGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLFxuXG5cdFx0XHQvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrc1xuXHRcdFx0c3RhdHVzQ29kZSA9IHMuc3RhdHVzQ29kZSB8fCB7fSxcblxuXHRcdFx0Ly8gSGVhZGVycyAodGhleSBhcmUgc2VudCBhbGwgYXQgb25jZSlcblx0XHRcdHJlcXVlc3RIZWFkZXJzID0ge30sXG5cdFx0XHRyZXF1ZXN0SGVhZGVyc05hbWVzID0ge30sXG5cblx0XHRcdC8vIERlZmF1bHQgYWJvcnQgbWVzc2FnZVxuXHRcdFx0c3RyQWJvcnQgPSBcImNhbmNlbGVkXCIsXG5cblx0XHRcdC8vIEZha2UgeGhyXG5cdFx0XHRqcVhIUiA9IHtcblx0XHRcdFx0cmVhZHlTdGF0ZTogMCxcblxuXHRcdFx0XHQvLyBCdWlsZHMgaGVhZGVycyBoYXNodGFibGUgaWYgbmVlZGVkXG5cdFx0XHRcdGdldFJlc3BvbnNlSGVhZGVyOiBmdW5jdGlvbigga2V5ICkge1xuXHRcdFx0XHRcdHZhciBtYXRjaDtcblx0XHRcdFx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblx0XHRcdFx0XHRcdGlmICggIXJlc3BvbnNlSGVhZGVycyApIHtcblx0XHRcdFx0XHRcdFx0cmVzcG9uc2VIZWFkZXJzID0ge307XG5cdFx0XHRcdFx0XHRcdHdoaWxlICggKCBtYXRjaCA9IHJoZWFkZXJzLmV4ZWMoIHJlc3BvbnNlSGVhZGVyc1N0cmluZyApICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzcG9uc2VIZWFkZXJzWyBtYXRjaFsgMSBdLnRvTG93ZXJDYXNlKCkgKyBcIiBcIiBdID1cblx0XHRcdFx0XHRcdFx0XHRcdCggcmVzcG9uc2VIZWFkZXJzWyBtYXRjaFsgMSBdLnRvTG93ZXJDYXNlKCkgKyBcIiBcIiBdIHx8IFtdIClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmNvbmNhdCggbWF0Y2hbIDIgXSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRtYXRjaCA9IHJlc3BvbnNlSGVhZGVyc1sga2V5LnRvTG93ZXJDYXNlKCkgKyBcIiBcIiBdO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gbWF0Y2ggPT0gbnVsbCA/IG51bGwgOiBtYXRjaC5qb2luKCBcIiwgXCIgKTtcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBSYXcgc3RyaW5nXG5cdFx0XHRcdGdldEFsbFJlc3BvbnNlSGVhZGVyczogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbXBsZXRlZCA/IHJlc3BvbnNlSGVhZGVyc1N0cmluZyA6IG51bGw7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gQ2FjaGVzIHRoZSBoZWFkZXJcblx0XHRcdFx0c2V0UmVxdWVzdEhlYWRlcjogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdFx0XHRcdGlmICggY29tcGxldGVkID09IG51bGwgKSB7XG5cdFx0XHRcdFx0XHRuYW1lID0gcmVxdWVzdEhlYWRlcnNOYW1lc1sgbmFtZS50b0xvd2VyQ2FzZSgpIF0gPVxuXHRcdFx0XHRcdFx0XHRyZXF1ZXN0SGVhZGVyc05hbWVzWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSB8fCBuYW1lO1xuXHRcdFx0XHRcdFx0cmVxdWVzdEhlYWRlcnNbIG5hbWUgXSA9IHZhbHVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBPdmVycmlkZXMgcmVzcG9uc2UgY29udGVudC10eXBlIGhlYWRlclxuXHRcdFx0XHRvdmVycmlkZU1pbWVUeXBlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRcdFx0XHRpZiAoIGNvbXBsZXRlZCA9PSBudWxsICkge1xuXHRcdFx0XHRcdFx0cy5taW1lVHlwZSA9IHR5cGU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXG5cdFx0XHRcdHN0YXR1c0NvZGU6IGZ1bmN0aW9uKCBtYXAgKSB7XG5cdFx0XHRcdFx0dmFyIGNvZGU7XG5cdFx0XHRcdFx0aWYgKCBtYXAgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBFeGVjdXRlIHRoZSBhcHByb3ByaWF0ZSBjYWxsYmFja3Ncblx0XHRcdFx0XHRcdFx0anFYSFIuYWx3YXlzKCBtYXBbIGpxWEhSLnN0YXR1cyBdICk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdC8vIExhenktYWRkIHRoZSBuZXcgY2FsbGJhY2tzIGluIGEgd2F5IHRoYXQgcHJlc2VydmVzIG9sZCBvbmVzXG5cdFx0XHRcdFx0XHRcdGZvciAoIGNvZGUgaW4gbWFwICkge1xuXHRcdFx0XHRcdFx0XHRcdHN0YXR1c0NvZGVbIGNvZGUgXSA9IFsgc3RhdHVzQ29kZVsgY29kZSBdLCBtYXBbIGNvZGUgXSBdO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIENhbmNlbCB0aGUgcmVxdWVzdFxuXHRcdFx0XHRhYm9ydDogZnVuY3Rpb24oIHN0YXR1c1RleHQgKSB7XG5cdFx0XHRcdFx0dmFyIGZpbmFsVGV4dCA9IHN0YXR1c1RleHQgfHwgc3RyQWJvcnQ7XG5cdFx0XHRcdFx0aWYgKCB0cmFuc3BvcnQgKSB7XG5cdFx0XHRcdFx0XHR0cmFuc3BvcnQuYWJvcnQoIGZpbmFsVGV4dCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRkb25lKCAwLCBmaW5hbFRleHQgKTtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdC8vIEF0dGFjaCBkZWZlcnJlZHNcblx0XHRkZWZlcnJlZC5wcm9taXNlKCBqcVhIUiApO1xuXG5cdFx0Ly8gQWRkIHByb3RvY29sIGlmIG5vdCBwcm92aWRlZCAocHJlZmlsdGVycyBtaWdodCBleHBlY3QgaXQpXG5cdFx0Ly8gSGFuZGxlIGZhbHN5IHVybCBpbiB0aGUgc2V0dGluZ3Mgb2JqZWN0ICgjMTAwOTM6IGNvbnNpc3RlbmN5IHdpdGggb2xkIHNpZ25hdHVyZSlcblx0XHQvLyBXZSBhbHNvIHVzZSB0aGUgdXJsIHBhcmFtZXRlciBpZiBhdmFpbGFibGVcblx0XHRzLnVybCA9ICggKCB1cmwgfHwgcy51cmwgfHwgbG9jYXRpb24uaHJlZiApICsgXCJcIiApXG5cdFx0XHQucmVwbGFjZSggcnByb3RvY29sLCBsb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiApO1xuXG5cdFx0Ly8gQWxpYXMgbWV0aG9kIG9wdGlvbiB0byB0eXBlIGFzIHBlciB0aWNrZXQgIzEyMDA0XG5cdFx0cy50eXBlID0gb3B0aW9ucy5tZXRob2QgfHwgb3B0aW9ucy50eXBlIHx8IHMubWV0aG9kIHx8IHMudHlwZTtcblxuXHRcdC8vIEV4dHJhY3QgZGF0YVR5cGVzIGxpc3Rcblx0XHRzLmRhdGFUeXBlcyA9ICggcy5kYXRhVHlwZSB8fCBcIipcIiApLnRvTG93ZXJDYXNlKCkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbIFwiXCIgXTtcblxuXHRcdC8vIEEgY3Jvc3MtZG9tYWluIHJlcXVlc3QgaXMgaW4gb3JkZXIgd2hlbiB0aGUgb3JpZ2luIGRvZXNuJ3QgbWF0Y2ggdGhlIGN1cnJlbnQgb3JpZ2luLlxuXHRcdGlmICggcy5jcm9zc0RvbWFpbiA9PSBudWxsICkge1xuXHRcdFx0dXJsQW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJhXCIgKTtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgPD04IC0gMTEsIEVkZ2UgMTIgLSAxNVxuXHRcdFx0Ly8gSUUgdGhyb3dzIGV4Y2VwdGlvbiBvbiBhY2Nlc3NpbmcgdGhlIGhyZWYgcHJvcGVydHkgaWYgdXJsIGlzIG1hbGZvcm1lZCxcblx0XHRcdC8vIGUuZy4gaHR0cDovL2V4YW1wbGUuY29tOjgweC9cblx0XHRcdHRyeSB7XG5cdFx0XHRcdHVybEFuY2hvci5ocmVmID0gcy51cmw7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD04IC0gMTEgb25seVxuXHRcdFx0XHQvLyBBbmNob3IncyBob3N0IHByb3BlcnR5IGlzbid0IGNvcnJlY3RseSBzZXQgd2hlbiBzLnVybCBpcyByZWxhdGl2ZVxuXHRcdFx0XHR1cmxBbmNob3IuaHJlZiA9IHVybEFuY2hvci5ocmVmO1xuXHRcdFx0XHRzLmNyb3NzRG9tYWluID0gb3JpZ2luQW5jaG9yLnByb3RvY29sICsgXCIvL1wiICsgb3JpZ2luQW5jaG9yLmhvc3QgIT09XG5cdFx0XHRcdFx0dXJsQW5jaG9yLnByb3RvY29sICsgXCIvL1wiICsgdXJsQW5jaG9yLmhvc3Q7XG5cdFx0XHR9IGNhdGNoICggZSApIHtcblxuXHRcdFx0XHQvLyBJZiB0aGVyZSBpcyBhbiBlcnJvciBwYXJzaW5nIHRoZSBVUkwsIGFzc3VtZSBpdCBpcyBjcm9zc0RvbWFpbixcblx0XHRcdFx0Ly8gaXQgY2FuIGJlIHJlamVjdGVkIGJ5IHRoZSB0cmFuc3BvcnQgaWYgaXQgaXMgaW52YWxpZFxuXHRcdFx0XHRzLmNyb3NzRG9tYWluID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDb252ZXJ0IGRhdGEgaWYgbm90IGFscmVhZHkgYSBzdHJpbmdcblx0XHRpZiAoIHMuZGF0YSAmJiBzLnByb2Nlc3NEYXRhICYmIHR5cGVvZiBzLmRhdGEgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRzLmRhdGEgPSBqUXVlcnkucGFyYW0oIHMuZGF0YSwgcy50cmFkaXRpb25hbCApO1xuXHRcdH1cblxuXHRcdC8vIEFwcGx5IHByZWZpbHRlcnNcblx0XHRpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggcHJlZmlsdGVycywgcywgb3B0aW9ucywganFYSFIgKTtcblxuXHRcdC8vIElmIHJlcXVlc3Qgd2FzIGFib3J0ZWQgaW5zaWRlIGEgcHJlZmlsdGVyLCBzdG9wIHRoZXJlXG5cdFx0aWYgKCBjb21wbGV0ZWQgKSB7XG5cdFx0XHRyZXR1cm4ganFYSFI7XG5cdFx0fVxuXG5cdFx0Ly8gV2UgY2FuIGZpcmUgZ2xvYmFsIGV2ZW50cyBhcyBvZiBub3cgaWYgYXNrZWQgdG9cblx0XHQvLyBEb24ndCBmaXJlIGV2ZW50cyBpZiBqUXVlcnkuZXZlbnQgaXMgdW5kZWZpbmVkIGluIGFuIEFNRC11c2FnZSBzY2VuYXJpbyAoIzE1MTE4KVxuXHRcdGZpcmVHbG9iYWxzID0galF1ZXJ5LmV2ZW50ICYmIHMuZ2xvYmFsO1xuXG5cdFx0Ly8gV2F0Y2ggZm9yIGEgbmV3IHNldCBvZiByZXF1ZXN0c1xuXHRcdGlmICggZmlyZUdsb2JhbHMgJiYgalF1ZXJ5LmFjdGl2ZSsrID09PSAwICkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIFwiYWpheFN0YXJ0XCIgKTtcblx0XHR9XG5cblx0XHQvLyBVcHBlcmNhc2UgdGhlIHR5cGVcblx0XHRzLnR5cGUgPSBzLnR5cGUudG9VcHBlckNhc2UoKTtcblxuXHRcdC8vIERldGVybWluZSBpZiByZXF1ZXN0IGhhcyBjb250ZW50XG5cdFx0cy5oYXNDb250ZW50ID0gIXJub0NvbnRlbnQudGVzdCggcy50eXBlICk7XG5cblx0XHQvLyBTYXZlIHRoZSBVUkwgaW4gY2FzZSB3ZSdyZSB0b3lpbmcgd2l0aCB0aGUgSWYtTW9kaWZpZWQtU2luY2Vcblx0XHQvLyBhbmQvb3IgSWYtTm9uZS1NYXRjaCBoZWFkZXIgbGF0ZXIgb25cblx0XHQvLyBSZW1vdmUgaGFzaCB0byBzaW1wbGlmeSB1cmwgbWFuaXB1bGF0aW9uXG5cdFx0Y2FjaGVVUkwgPSBzLnVybC5yZXBsYWNlKCByaGFzaCwgXCJcIiApO1xuXG5cdFx0Ly8gTW9yZSBvcHRpb25zIGhhbmRsaW5nIGZvciByZXF1ZXN0cyB3aXRoIG5vIGNvbnRlbnRcblx0XHRpZiAoICFzLmhhc0NvbnRlbnQgKSB7XG5cblx0XHRcdC8vIFJlbWVtYmVyIHRoZSBoYXNoIHNvIHdlIGNhbiBwdXQgaXQgYmFja1xuXHRcdFx0dW5jYWNoZWQgPSBzLnVybC5zbGljZSggY2FjaGVVUkwubGVuZ3RoICk7XG5cblx0XHRcdC8vIElmIGRhdGEgaXMgYXZhaWxhYmxlIGFuZCBzaG91bGQgYmUgcHJvY2Vzc2VkLCBhcHBlbmQgZGF0YSB0byB1cmxcblx0XHRcdGlmICggcy5kYXRhICYmICggcy5wcm9jZXNzRGF0YSB8fCB0eXBlb2Ygcy5kYXRhID09PSBcInN0cmluZ1wiICkgKSB7XG5cdFx0XHRcdGNhY2hlVVJMICs9ICggcnF1ZXJ5LnRlc3QoIGNhY2hlVVJMICkgPyBcIiZcIiA6IFwiP1wiICkgKyBzLmRhdGE7XG5cblx0XHRcdFx0Ly8gIzk2ODI6IHJlbW92ZSBkYXRhIHNvIHRoYXQgaXQncyBub3QgdXNlZCBpbiBhbiBldmVudHVhbCByZXRyeVxuXHRcdFx0XHRkZWxldGUgcy5kYXRhO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgb3IgdXBkYXRlIGFudGktY2FjaGUgcGFyYW0gaWYgbmVlZGVkXG5cdFx0XHRpZiAoIHMuY2FjaGUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRjYWNoZVVSTCA9IGNhY2hlVVJMLnJlcGxhY2UoIHJhbnRpQ2FjaGUsIFwiJDFcIiApO1xuXHRcdFx0XHR1bmNhY2hlZCA9ICggcnF1ZXJ5LnRlc3QoIGNhY2hlVVJMICkgPyBcIiZcIiA6IFwiP1wiICkgKyBcIl89XCIgKyAoIG5vbmNlLmd1aWQrKyApICtcblx0XHRcdFx0XHR1bmNhY2hlZDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUHV0IGhhc2ggYW5kIGFudGktY2FjaGUgb24gdGhlIFVSTCB0aGF0IHdpbGwgYmUgcmVxdWVzdGVkIChnaC0xNzMyKVxuXHRcdFx0cy51cmwgPSBjYWNoZVVSTCArIHVuY2FjaGVkO1xuXG5cdFx0Ly8gQ2hhbmdlICclMjAnIHRvICcrJyBpZiB0aGlzIGlzIGVuY29kZWQgZm9ybSBib2R5IGNvbnRlbnQgKGdoLTI2NTgpXG5cdFx0fSBlbHNlIGlmICggcy5kYXRhICYmIHMucHJvY2Vzc0RhdGEgJiZcblx0XHRcdCggcy5jb250ZW50VHlwZSB8fCBcIlwiICkuaW5kZXhPZiggXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcIiApID09PSAwICkge1xuXHRcdFx0cy5kYXRhID0gcy5kYXRhLnJlcGxhY2UoIHIyMCwgXCIrXCIgKTtcblx0XHR9XG5cblx0XHQvLyBTZXQgdGhlIElmLU1vZGlmaWVkLVNpbmNlIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciwgaWYgaW4gaWZNb2RpZmllZCBtb2RlLlxuXHRcdGlmICggcy5pZk1vZGlmaWVkICkge1xuXHRcdFx0aWYgKCBqUXVlcnkubGFzdE1vZGlmaWVkWyBjYWNoZVVSTCBdICkge1xuXHRcdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIklmLU1vZGlmaWVkLVNpbmNlXCIsIGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gKTtcblx0XHRcdH1cblx0XHRcdGlmICggalF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gKSB7XG5cdFx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiSWYtTm9uZS1NYXRjaFwiLCBqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgY29ycmVjdCBoZWFkZXIsIGlmIGRhdGEgaXMgYmVpbmcgc2VudFxuXHRcdGlmICggcy5kYXRhICYmIHMuaGFzQ29udGVudCAmJiBzLmNvbnRlbnRUeXBlICE9PSBmYWxzZSB8fCBvcHRpb25zLmNvbnRlbnRUeXBlICkge1xuXHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJDb250ZW50LVR5cGVcIiwgcy5jb250ZW50VHlwZSApO1xuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgQWNjZXB0cyBoZWFkZXIgZm9yIHRoZSBzZXJ2ZXIsIGRlcGVuZGluZyBvbiB0aGUgZGF0YVR5cGVcblx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKFxuXHRcdFx0XCJBY2NlcHRcIixcblx0XHRcdHMuZGF0YVR5cGVzWyAwIF0gJiYgcy5hY2NlcHRzWyBzLmRhdGFUeXBlc1sgMCBdIF0gP1xuXHRcdFx0XHRzLmFjY2VwdHNbIHMuZGF0YVR5cGVzWyAwIF0gXSArXG5cdFx0XHRcdFx0KCBzLmRhdGFUeXBlc1sgMCBdICE9PSBcIipcIiA/IFwiLCBcIiArIGFsbFR5cGVzICsgXCI7IHE9MC4wMVwiIDogXCJcIiApIDpcblx0XHRcdFx0cy5hY2NlcHRzWyBcIipcIiBdXG5cdFx0KTtcblxuXHRcdC8vIENoZWNrIGZvciBoZWFkZXJzIG9wdGlvblxuXHRcdGZvciAoIGkgaW4gcy5oZWFkZXJzICkge1xuXHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggaSwgcy5oZWFkZXJzWyBpIF0gKTtcblx0XHR9XG5cblx0XHQvLyBBbGxvdyBjdXN0b20gaGVhZGVycy9taW1ldHlwZXMgYW5kIGVhcmx5IGFib3J0XG5cdFx0aWYgKCBzLmJlZm9yZVNlbmQgJiZcblx0XHRcdCggcy5iZWZvcmVTZW5kLmNhbGwoIGNhbGxiYWNrQ29udGV4dCwganFYSFIsIHMgKSA9PT0gZmFsc2UgfHwgY29tcGxldGVkICkgKSB7XG5cblx0XHRcdC8vIEFib3J0IGlmIG5vdCBkb25lIGFscmVhZHkgYW5kIHJldHVyblxuXHRcdFx0cmV0dXJuIGpxWEhSLmFib3J0KCk7XG5cdFx0fVxuXG5cdFx0Ly8gQWJvcnRpbmcgaXMgbm8gbG9uZ2VyIGEgY2FuY2VsbGF0aW9uXG5cdFx0c3RyQWJvcnQgPSBcImFib3J0XCI7XG5cblx0XHQvLyBJbnN0YWxsIGNhbGxiYWNrcyBvbiBkZWZlcnJlZHNcblx0XHRjb21wbGV0ZURlZmVycmVkLmFkZCggcy5jb21wbGV0ZSApO1xuXHRcdGpxWEhSLmRvbmUoIHMuc3VjY2VzcyApO1xuXHRcdGpxWEhSLmZhaWwoIHMuZXJyb3IgKTtcblxuXHRcdC8vIEdldCB0cmFuc3BvcnRcblx0XHR0cmFuc3BvcnQgPSBpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggdHJhbnNwb3J0cywgcywgb3B0aW9ucywganFYSFIgKTtcblxuXHRcdC8vIElmIG5vIHRyYW5zcG9ydCwgd2UgYXV0by1hYm9ydFxuXHRcdGlmICggIXRyYW5zcG9ydCApIHtcblx0XHRcdGRvbmUoIC0xLCBcIk5vIFRyYW5zcG9ydFwiICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGpxWEhSLnJlYWR5U3RhdGUgPSAxO1xuXG5cdFx0XHQvLyBTZW5kIGdsb2JhbCBldmVudFxuXHRcdFx0aWYgKCBmaXJlR2xvYmFscyApIHtcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIFwiYWpheFNlbmRcIiwgWyBqcVhIUiwgcyBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIHJlcXVlc3Qgd2FzIGFib3J0ZWQgaW5zaWRlIGFqYXhTZW5kLCBzdG9wIHRoZXJlXG5cdFx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblx0XHRcdFx0cmV0dXJuIGpxWEhSO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBUaW1lb3V0XG5cdFx0XHRpZiAoIHMuYXN5bmMgJiYgcy50aW1lb3V0ID4gMCApIHtcblx0XHRcdFx0dGltZW91dFRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGpxWEhSLmFib3J0KCBcInRpbWVvdXRcIiApO1xuXHRcdFx0XHR9LCBzLnRpbWVvdXQgKTtcblx0XHRcdH1cblxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Y29tcGxldGVkID0gZmFsc2U7XG5cdFx0XHRcdHRyYW5zcG9ydC5zZW5kKCByZXF1ZXN0SGVhZGVycywgZG9uZSApO1xuXHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cblx0XHRcdFx0Ly8gUmV0aHJvdyBwb3N0LWNvbXBsZXRpb24gZXhjZXB0aW9uc1xuXHRcdFx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblx0XHRcdFx0XHR0aHJvdyBlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUHJvcGFnYXRlIG90aGVycyBhcyByZXN1bHRzXG5cdFx0XHRcdGRvbmUoIC0xLCBlICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsbGJhY2sgZm9yIHdoZW4gZXZlcnl0aGluZyBpcyBkb25lXG5cdFx0ZnVuY3Rpb24gZG9uZSggc3RhdHVzLCBuYXRpdmVTdGF0dXNUZXh0LCByZXNwb25zZXMsIGhlYWRlcnMgKSB7XG5cdFx0XHR2YXIgaXNTdWNjZXNzLCBzdWNjZXNzLCBlcnJvciwgcmVzcG9uc2UsIG1vZGlmaWVkLFxuXHRcdFx0XHRzdGF0dXNUZXh0ID0gbmF0aXZlU3RhdHVzVGV4dDtcblxuXHRcdFx0Ly8gSWdub3JlIHJlcGVhdCBpbnZvY2F0aW9uc1xuXHRcdFx0aWYgKCBjb21wbGV0ZWQgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Y29tcGxldGVkID0gdHJ1ZTtcblxuXHRcdFx0Ly8gQ2xlYXIgdGltZW91dCBpZiBpdCBleGlzdHNcblx0XHRcdGlmICggdGltZW91dFRpbWVyICkge1xuXHRcdFx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0VGltZXIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRGVyZWZlcmVuY2UgdHJhbnNwb3J0IGZvciBlYXJseSBnYXJiYWdlIGNvbGxlY3Rpb25cblx0XHRcdC8vIChubyBtYXR0ZXIgaG93IGxvbmcgdGhlIGpxWEhSIG9iamVjdCB3aWxsIGJlIHVzZWQpXG5cdFx0XHR0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG5cblx0XHRcdC8vIENhY2hlIHJlc3BvbnNlIGhlYWRlcnNcblx0XHRcdHJlc3BvbnNlSGVhZGVyc1N0cmluZyA9IGhlYWRlcnMgfHwgXCJcIjtcblxuXHRcdFx0Ly8gU2V0IHJlYWR5U3RhdGVcblx0XHRcdGpxWEhSLnJlYWR5U3RhdGUgPSBzdGF0dXMgPiAwID8gNCA6IDA7XG5cblx0XHRcdC8vIERldGVybWluZSBpZiBzdWNjZXNzZnVsXG5cdFx0XHRpc1N1Y2Nlc3MgPSBzdGF0dXMgPj0gMjAwICYmIHN0YXR1cyA8IDMwMCB8fCBzdGF0dXMgPT09IDMwNDtcblxuXHRcdFx0Ly8gR2V0IHJlc3BvbnNlIGRhdGFcblx0XHRcdGlmICggcmVzcG9uc2VzICkge1xuXHRcdFx0XHRyZXNwb25zZSA9IGFqYXhIYW5kbGVSZXNwb25zZXMoIHMsIGpxWEhSLCByZXNwb25zZXMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVXNlIGEgbm9vcCBjb252ZXJ0ZXIgZm9yIG1pc3Npbmcgc2NyaXB0IGJ1dCBub3QgaWYganNvbnBcblx0XHRcdGlmICggIWlzU3VjY2VzcyAmJlxuXHRcdFx0XHRqUXVlcnkuaW5BcnJheSggXCJzY3JpcHRcIiwgcy5kYXRhVHlwZXMgKSA+IC0xICYmXG5cdFx0XHRcdGpRdWVyeS5pbkFycmF5KCBcImpzb25cIiwgcy5kYXRhVHlwZXMgKSA8IDAgKSB7XG5cdFx0XHRcdHMuY29udmVydGVyc1sgXCJ0ZXh0IHNjcmlwdFwiIF0gPSBmdW5jdGlvbigpIHt9O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDb252ZXJ0IG5vIG1hdHRlciB3aGF0ICh0aGF0IHdheSByZXNwb25zZVhYWCBmaWVsZHMgYXJlIGFsd2F5cyBzZXQpXG5cdFx0XHRyZXNwb25zZSA9IGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApO1xuXG5cdFx0XHQvLyBJZiBzdWNjZXNzZnVsLCBoYW5kbGUgdHlwZSBjaGFpbmluZ1xuXHRcdFx0aWYgKCBpc1N1Y2Nlc3MgKSB7XG5cblx0XHRcdFx0Ly8gU2V0IHRoZSBJZi1Nb2RpZmllZC1TaW5jZSBhbmQvb3IgSWYtTm9uZS1NYXRjaCBoZWFkZXIsIGlmIGluIGlmTW9kaWZpZWQgbW9kZS5cblx0XHRcdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XG5cdFx0XHRcdFx0bW9kaWZpZWQgPSBqcVhIUi5nZXRSZXNwb25zZUhlYWRlciggXCJMYXN0LU1vZGlmaWVkXCIgKTtcblx0XHRcdFx0XHRpZiAoIG1vZGlmaWVkICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSA9IG1vZGlmaWVkO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRtb2RpZmllZCA9IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKCBcImV0YWdcIiApO1xuXHRcdFx0XHRcdGlmICggbW9kaWZpZWQgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSA9IG1vZGlmaWVkO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIGlmIG5vIGNvbnRlbnRcblx0XHRcdFx0aWYgKCBzdGF0dXMgPT09IDIwNCB8fCBzLnR5cGUgPT09IFwiSEVBRFwiICkge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSBcIm5vY29udGVudFwiO1xuXG5cdFx0XHRcdC8vIGlmIG5vdCBtb2RpZmllZFxuXHRcdFx0XHR9IGVsc2UgaWYgKCBzdGF0dXMgPT09IDMwNCApIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJub3Rtb2RpZmllZFwiO1xuXG5cdFx0XHRcdC8vIElmIHdlIGhhdmUgZGF0YSwgbGV0J3MgY29udmVydCBpdFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSByZXNwb25zZS5zdGF0ZTtcblx0XHRcdFx0XHRzdWNjZXNzID0gcmVzcG9uc2UuZGF0YTtcblx0XHRcdFx0XHRlcnJvciA9IHJlc3BvbnNlLmVycm9yO1xuXHRcdFx0XHRcdGlzU3VjY2VzcyA9ICFlcnJvcjtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBFeHRyYWN0IGVycm9yIGZyb20gc3RhdHVzVGV4dCBhbmQgbm9ybWFsaXplIGZvciBub24tYWJvcnRzXG5cdFx0XHRcdGVycm9yID0gc3RhdHVzVGV4dDtcblx0XHRcdFx0aWYgKCBzdGF0dXMgfHwgIXN0YXR1c1RleHQgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwiZXJyb3JcIjtcblx0XHRcdFx0XHRpZiAoIHN0YXR1cyA8IDAgKSB7XG5cdFx0XHRcdFx0XHRzdGF0dXMgPSAwO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgZGF0YSBmb3IgdGhlIGZha2UgeGhyIG9iamVjdFxuXHRcdFx0anFYSFIuc3RhdHVzID0gc3RhdHVzO1xuXHRcdFx0anFYSFIuc3RhdHVzVGV4dCA9ICggbmF0aXZlU3RhdHVzVGV4dCB8fCBzdGF0dXNUZXh0ICkgKyBcIlwiO1xuXG5cdFx0XHQvLyBTdWNjZXNzL0Vycm9yXG5cdFx0XHRpZiAoIGlzU3VjY2VzcyApIHtcblx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBzdWNjZXNzLCBzdGF0dXNUZXh0LCBqcVhIUiBdICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsganFYSFIsIHN0YXR1c1RleHQsIGVycm9yIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdGpxWEhSLnN0YXR1c0NvZGUoIHN0YXR1c0NvZGUgKTtcblx0XHRcdHN0YXR1c0NvZGUgPSB1bmRlZmluZWQ7XG5cblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBpc1N1Y2Nlc3MgPyBcImFqYXhTdWNjZXNzXCIgOiBcImFqYXhFcnJvclwiLFxuXHRcdFx0XHRcdFsganFYSFIsIHMsIGlzU3VjY2VzcyA/IHN1Y2Nlc3MgOiBlcnJvciBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbXBsZXRlXG5cdFx0XHRjb21wbGV0ZURlZmVycmVkLmZpcmVXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsganFYSFIsIHN0YXR1c1RleHQgXSApO1xuXG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xuXHRcdFx0XHRnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggXCJhamF4Q29tcGxldGVcIiwgWyBqcVhIUiwgcyBdICk7XG5cblx0XHRcdFx0Ly8gSGFuZGxlIHRoZSBnbG9iYWwgQUpBWCBjb3VudGVyXG5cdFx0XHRcdGlmICggISggLS1qUXVlcnkuYWN0aXZlICkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIFwiYWpheFN0b3BcIiApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpxWEhSO1xuXHR9LFxuXG5cdGdldEpTT046IGZ1bmN0aW9uKCB1cmwsIGRhdGEsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ2V0KCB1cmwsIGRhdGEsIGNhbGxiYWNrLCBcImpzb25cIiApO1xuXHR9LFxuXG5cdGdldFNjcmlwdDogZnVuY3Rpb24oIHVybCwgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5nZXQoIHVybCwgdW5kZWZpbmVkLCBjYWxsYmFjaywgXCJzY3JpcHRcIiApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5lYWNoKCBbIFwiZ2V0XCIsIFwicG9zdFwiIF0sIGZ1bmN0aW9uKCBfaSwgbWV0aG9kICkge1xuXHRqUXVlcnlbIG1ldGhvZCBdID0gZnVuY3Rpb24oIHVybCwgZGF0YSwgY2FsbGJhY2ssIHR5cGUgKSB7XG5cblx0XHQvLyBTaGlmdCBhcmd1bWVudHMgaWYgZGF0YSBhcmd1bWVudCB3YXMgb21pdHRlZFxuXHRcdGlmICggaXNGdW5jdGlvbiggZGF0YSApICkge1xuXHRcdFx0dHlwZSA9IHR5cGUgfHwgY2FsbGJhY2s7XG5cdFx0XHRjYWxsYmFjayA9IGRhdGE7XG5cdFx0XHRkYXRhID0gdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdC8vIFRoZSB1cmwgY2FuIGJlIGFuIG9wdGlvbnMgb2JqZWN0ICh3aGljaCB0aGVuIG11c3QgaGF2ZSAudXJsKVxuXHRcdHJldHVybiBqUXVlcnkuYWpheCggalF1ZXJ5LmV4dGVuZCgge1xuXHRcdFx0dXJsOiB1cmwsXG5cdFx0XHR0eXBlOiBtZXRob2QsXG5cdFx0XHRkYXRhVHlwZTogdHlwZSxcblx0XHRcdGRhdGE6IGRhdGEsXG5cdFx0XHRzdWNjZXNzOiBjYWxsYmFja1xuXHRcdH0sIGpRdWVyeS5pc1BsYWluT2JqZWN0KCB1cmwgKSAmJiB1cmwgKSApO1xuXHR9O1xufSApO1xuXG5qUXVlcnkuYWpheFByZWZpbHRlciggZnVuY3Rpb24oIHMgKSB7XG5cdHZhciBpO1xuXHRmb3IgKCBpIGluIHMuaGVhZGVycyApIHtcblx0XHRpZiAoIGkudG9Mb3dlckNhc2UoKSA9PT0gXCJjb250ZW50LXR5cGVcIiApIHtcblx0XHRcdHMuY29udGVudFR5cGUgPSBzLmhlYWRlcnNbIGkgXSB8fCBcIlwiO1xuXHRcdH1cblx0fVxufSApO1xuXG5cbmpRdWVyeS5fZXZhbFVybCA9IGZ1bmN0aW9uKCB1cmwsIG9wdGlvbnMsIGRvYyApIHtcblx0cmV0dXJuIGpRdWVyeS5hamF4KCB7XG5cdFx0dXJsOiB1cmwsXG5cblx0XHQvLyBNYWtlIHRoaXMgZXhwbGljaXQsIHNpbmNlIHVzZXIgY2FuIG92ZXJyaWRlIHRoaXMgdGhyb3VnaCBhamF4U2V0dXAgKCMxMTI2NClcblx0XHR0eXBlOiBcIkdFVFwiLFxuXHRcdGRhdGFUeXBlOiBcInNjcmlwdFwiLFxuXHRcdGNhY2hlOiB0cnVlLFxuXHRcdGFzeW5jOiBmYWxzZSxcblx0XHRnbG9iYWw6IGZhbHNlLFxuXG5cdFx0Ly8gT25seSBldmFsdWF0ZSB0aGUgcmVzcG9uc2UgaWYgaXQgaXMgc3VjY2Vzc2Z1bCAoZ2gtNDEyNilcblx0XHQvLyBkYXRhRmlsdGVyIGlzIG5vdCBpbnZva2VkIGZvciBmYWlsdXJlIHJlc3BvbnNlcywgc28gdXNpbmcgaXQgaW5zdGVhZFxuXHRcdC8vIG9mIHRoZSBkZWZhdWx0IGNvbnZlcnRlciBpcyBrbHVkZ3kgYnV0IGl0IHdvcmtzLlxuXHRcdGNvbnZlcnRlcnM6IHtcblx0XHRcdFwidGV4dCBzY3JpcHRcIjogZnVuY3Rpb24oKSB7fVxuXHRcdH0sXG5cdFx0ZGF0YUZpbHRlcjogZnVuY3Rpb24oIHJlc3BvbnNlICkge1xuXHRcdFx0alF1ZXJ5Lmdsb2JhbEV2YWwoIHJlc3BvbnNlLCBvcHRpb25zLCBkb2MgKTtcblx0XHR9XG5cdH0gKTtcbn07XG5cblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHR3cmFwQWxsOiBmdW5jdGlvbiggaHRtbCApIHtcblx0XHR2YXIgd3JhcDtcblxuXHRcdGlmICggdGhpc1sgMCBdICkge1xuXHRcdFx0aWYgKCBpc0Z1bmN0aW9uKCBodG1sICkgKSB7XG5cdFx0XHRcdGh0bWwgPSBodG1sLmNhbGwoIHRoaXNbIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBUaGUgZWxlbWVudHMgdG8gd3JhcCB0aGUgdGFyZ2V0IGFyb3VuZFxuXHRcdFx0d3JhcCA9IGpRdWVyeSggaHRtbCwgdGhpc1sgMCBdLm93bmVyRG9jdW1lbnQgKS5lcSggMCApLmNsb25lKCB0cnVlICk7XG5cblx0XHRcdGlmICggdGhpc1sgMCBdLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdHdyYXAuaW5zZXJ0QmVmb3JlKCB0aGlzWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0d3JhcC5tYXAoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZWxlbSA9IHRoaXM7XG5cblx0XHRcdFx0d2hpbGUgKCBlbGVtLmZpcnN0RWxlbWVudENoaWxkICkge1xuXHRcdFx0XHRcdGVsZW0gPSBlbGVtLmZpcnN0RWxlbWVudENoaWxkO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIGVsZW07XG5cdFx0XHR9ICkuYXBwZW5kKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0d3JhcElubmVyOiBmdW5jdGlvbiggaHRtbCApIHtcblx0XHRpZiAoIGlzRnVuY3Rpb24oIGh0bWwgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS53cmFwSW5uZXIoIGh0bWwuY2FsbCggdGhpcywgaSApICk7XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgc2VsZiA9IGpRdWVyeSggdGhpcyApLFxuXHRcdFx0XHRjb250ZW50cyA9IHNlbGYuY29udGVudHMoKTtcblxuXHRcdFx0aWYgKCBjb250ZW50cy5sZW5ndGggKSB7XG5cdFx0XHRcdGNvbnRlbnRzLndyYXBBbGwoIGh0bWwgKTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0c2VsZi5hcHBlbmQoIGh0bWwgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0d3JhcDogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0dmFyIGh0bWxJc0Z1bmN0aW9uID0gaXNGdW5jdGlvbiggaHRtbCApO1xuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRqUXVlcnkoIHRoaXMgKS53cmFwQWxsKCBodG1sSXNGdW5jdGlvbiA/IGh0bWwuY2FsbCggdGhpcywgaSApIDogaHRtbCApO1xuXHRcdH0gKTtcblx0fSxcblxuXHR1bndyYXA6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHR0aGlzLnBhcmVudCggc2VsZWN0b3IgKS5ub3QoIFwiYm9keVwiICkuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkoIHRoaXMgKS5yZXBsYWNlV2l0aCggdGhpcy5jaGlsZE5vZGVzICk7XG5cdFx0fSApO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG59ICk7XG5cblxualF1ZXJ5LmV4cHIucHNldWRvcy5oaWRkZW4gPSBmdW5jdGlvbiggZWxlbSApIHtcblx0cmV0dXJuICFqUXVlcnkuZXhwci5wc2V1ZG9zLnZpc2libGUoIGVsZW0gKTtcbn07XG5qUXVlcnkuZXhwci5wc2V1ZG9zLnZpc2libGUgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0cmV0dXJuICEhKCBlbGVtLm9mZnNldFdpZHRoIHx8IGVsZW0ub2Zmc2V0SGVpZ2h0IHx8IGVsZW0uZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGggKTtcbn07XG5cblxuXG5cbmpRdWVyeS5hamF4U2V0dGluZ3MueGhyID0gZnVuY3Rpb24oKSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIG5ldyB3aW5kb3cuWE1MSHR0cFJlcXVlc3QoKTtcblx0fSBjYXRjaCAoIGUgKSB7fVxufTtcblxudmFyIHhoclN1Y2Nlc3NTdGF0dXMgPSB7XG5cblx0XHQvLyBGaWxlIHByb3RvY29sIGFsd2F5cyB5aWVsZHMgc3RhdHVzIGNvZGUgMCwgYXNzdW1lIDIwMFxuXHRcdDA6IDIwMCxcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5XG5cdFx0Ly8gIzE0NTA6IHNvbWV0aW1lcyBJRSByZXR1cm5zIDEyMjMgd2hlbiBpdCBzaG91bGQgYmUgMjA0XG5cdFx0MTIyMzogMjA0XG5cdH0sXG5cdHhoclN1cHBvcnRlZCA9IGpRdWVyeS5hamF4U2V0dGluZ3MueGhyKCk7XG5cbnN1cHBvcnQuY29ycyA9ICEheGhyU3VwcG9ydGVkICYmICggXCJ3aXRoQ3JlZGVudGlhbHNcIiBpbiB4aHJTdXBwb3J0ZWQgKTtcbnN1cHBvcnQuYWpheCA9IHhoclN1cHBvcnRlZCA9ICEheGhyU3VwcG9ydGVkO1xuXG5qUXVlcnkuYWpheFRyYW5zcG9ydCggZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdHZhciBjYWxsYmFjaywgZXJyb3JDYWxsYmFjaztcblxuXHQvLyBDcm9zcyBkb21haW4gb25seSBhbGxvd2VkIGlmIHN1cHBvcnRlZCB0aHJvdWdoIFhNTEh0dHBSZXF1ZXN0XG5cdGlmICggc3VwcG9ydC5jb3JzIHx8IHhoclN1cHBvcnRlZCAmJiAhb3B0aW9ucy5jcm9zc0RvbWFpbiApIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0c2VuZDogZnVuY3Rpb24oIGhlYWRlcnMsIGNvbXBsZXRlICkge1xuXHRcdFx0XHR2YXIgaSxcblx0XHRcdFx0XHR4aHIgPSBvcHRpb25zLnhocigpO1xuXG5cdFx0XHRcdHhoci5vcGVuKFxuXHRcdFx0XHRcdG9wdGlvbnMudHlwZSxcblx0XHRcdFx0XHRvcHRpb25zLnVybCxcblx0XHRcdFx0XHRvcHRpb25zLmFzeW5jLFxuXHRcdFx0XHRcdG9wdGlvbnMudXNlcm5hbWUsXG5cdFx0XHRcdFx0b3B0aW9ucy5wYXNzd29yZFxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdC8vIEFwcGx5IGN1c3RvbSBmaWVsZHMgaWYgcHJvdmlkZWRcblx0XHRcdFx0aWYgKCBvcHRpb25zLnhockZpZWxkcyApIHtcblx0XHRcdFx0XHRmb3IgKCBpIGluIG9wdGlvbnMueGhyRmllbGRzICkge1xuXHRcdFx0XHRcdFx0eGhyWyBpIF0gPSBvcHRpb25zLnhockZpZWxkc1sgaSBdO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIE92ZXJyaWRlIG1pbWUgdHlwZSBpZiBuZWVkZWRcblx0XHRcdFx0aWYgKCBvcHRpb25zLm1pbWVUeXBlICYmIHhoci5vdmVycmlkZU1pbWVUeXBlICkge1xuXHRcdFx0XHRcdHhoci5vdmVycmlkZU1pbWVUeXBlKCBvcHRpb25zLm1pbWVUeXBlICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBYLVJlcXVlc3RlZC1XaXRoIGhlYWRlclxuXHRcdFx0XHQvLyBGb3IgY3Jvc3MtZG9tYWluIHJlcXVlc3RzLCBzZWVpbmcgYXMgY29uZGl0aW9ucyBmb3IgYSBwcmVmbGlnaHQgYXJlXG5cdFx0XHRcdC8vIGFraW4gdG8gYSBqaWdzYXcgcHV6emxlLCB3ZSBzaW1wbHkgbmV2ZXIgc2V0IGl0IHRvIGJlIHN1cmUuXG5cdFx0XHRcdC8vIChpdCBjYW4gYWx3YXlzIGJlIHNldCBvbiBhIHBlci1yZXF1ZXN0IGJhc2lzIG9yIGV2ZW4gdXNpbmcgYWpheFNldHVwKVxuXHRcdFx0XHQvLyBGb3Igc2FtZS1kb21haW4gcmVxdWVzdHMsIHdvbid0IGNoYW5nZSBoZWFkZXIgaWYgYWxyZWFkeSBwcm92aWRlZC5cblx0XHRcdFx0aWYgKCAhb3B0aW9ucy5jcm9zc0RvbWFpbiAmJiAhaGVhZGVyc1sgXCJYLVJlcXVlc3RlZC1XaXRoXCIgXSApIHtcblx0XHRcdFx0XHRoZWFkZXJzWyBcIlgtUmVxdWVzdGVkLVdpdGhcIiBdID0gXCJYTUxIdHRwUmVxdWVzdFwiO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gU2V0IGhlYWRlcnNcblx0XHRcdFx0Zm9yICggaSBpbiBoZWFkZXJzICkge1xuXHRcdFx0XHRcdHhoci5zZXRSZXF1ZXN0SGVhZGVyKCBpLCBoZWFkZXJzWyBpIF0gKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIENhbGxiYWNrXG5cdFx0XHRcdGNhbGxiYWNrID0gZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRcdFx0Y2FsbGJhY2sgPSBlcnJvckNhbGxiYWNrID0geGhyLm9ubG9hZCA9XG5cdFx0XHRcdFx0XHRcdFx0eGhyLm9uZXJyb3IgPSB4aHIub25hYm9ydCA9IHhoci5vbnRpbWVvdXQgPVxuXHRcdFx0XHRcdFx0XHRcdFx0eGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IG51bGw7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCB0eXBlID09PSBcImFib3J0XCIgKSB7XG5cdFx0XHRcdFx0XHRcdFx0eGhyLmFib3J0KCk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIHR5cGUgPT09IFwiZXJyb3JcIiApIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5XG5cdFx0XHRcdFx0XHRcdFx0Ly8gT24gYSBtYW51YWwgbmF0aXZlIGFib3J0LCBJRTkgdGhyb3dzXG5cdFx0XHRcdFx0XHRcdFx0Ly8gZXJyb3JzIG9uIGFueSBwcm9wZXJ0eSBhY2Nlc3MgdGhhdCBpcyBub3QgcmVhZHlTdGF0ZVxuXHRcdFx0XHRcdFx0XHRcdGlmICggdHlwZW9mIHhoci5zdGF0dXMgIT09IFwibnVtYmVyXCIgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjb21wbGV0ZSggMCwgXCJlcnJvclwiICk7XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdGNvbXBsZXRlKFxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpbGU6IHByb3RvY29sIGFsd2F5cyB5aWVsZHMgc3RhdHVzIDA7IHNlZSAjODYwNSwgIzE0MjA3XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXMsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXNUZXh0XG5cdFx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRjb21wbGV0ZShcblx0XHRcdFx0XHRcdFx0XHRcdHhoclN1Y2Nlc3NTdGF0dXNbIHhoci5zdGF0dXMgXSB8fCB4aHIuc3RhdHVzLFxuXHRcdFx0XHRcdFx0XHRcdFx0eGhyLnN0YXR1c1RleHQsXG5cblx0XHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBJRTkgaGFzIG5vIFhIUjIgYnV0IHRocm93cyBvbiBiaW5hcnkgKHRyYWMtMTE0MjYpXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBGb3IgWEhSMiBub24tdGV4dCwgbGV0IHRoZSBjYWxsZXIgaGFuZGxlIGl0IChnaC0yNDk4KVxuXHRcdFx0XHRcdFx0XHRcdFx0KCB4aHIucmVzcG9uc2VUeXBlIHx8IFwidGV4dFwiICkgIT09IFwidGV4dFwiICB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0dHlwZW9mIHhoci5yZXNwb25zZVRleHQgIT09IFwic3RyaW5nXCIgP1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR7IGJpbmFyeTogeGhyLnJlc3BvbnNlIH0gOlxuXHRcdFx0XHRcdFx0XHRcdFx0XHR7IHRleHQ6IHhoci5yZXNwb25zZVRleHQgfSxcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKVxuXHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9O1xuXG5cdFx0XHRcdC8vIExpc3RlbiB0byBldmVudHNcblx0XHRcdFx0eGhyLm9ubG9hZCA9IGNhbGxiYWNrKCk7XG5cdFx0XHRcdGVycm9yQ2FsbGJhY2sgPSB4aHIub25lcnJvciA9IHhoci5vbnRpbWVvdXQgPSBjYWxsYmFjayggXCJlcnJvclwiICk7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgOSBvbmx5XG5cdFx0XHRcdC8vIFVzZSBvbnJlYWR5c3RhdGVjaGFuZ2UgdG8gcmVwbGFjZSBvbmFib3J0XG5cdFx0XHRcdC8vIHRvIGhhbmRsZSB1bmNhdWdodCBhYm9ydHNcblx0XHRcdFx0aWYgKCB4aHIub25hYm9ydCAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHhoci5vbmFib3J0ID0gZXJyb3JDYWxsYmFjaztcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0XHRcdC8vIENoZWNrIHJlYWR5U3RhdGUgYmVmb3JlIHRpbWVvdXQgYXMgaXQgY2hhbmdlc1xuXHRcdFx0XHRcdFx0aWYgKCB4aHIucmVhZHlTdGF0ZSA9PT0gNCApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBBbGxvdyBvbmVycm9yIHRvIGJlIGNhbGxlZCBmaXJzdCxcblx0XHRcdFx0XHRcdFx0Ly8gYnV0IHRoYXQgd2lsbCBub3QgaGFuZGxlIGEgbmF0aXZlIGFib3J0XG5cdFx0XHRcdFx0XHRcdC8vIEFsc28sIHNhdmUgZXJyb3JDYWxsYmFjayB0byBhIHZhcmlhYmxlXG5cdFx0XHRcdFx0XHRcdC8vIGFzIHhoci5vbmVycm9yIGNhbm5vdCBiZSBhY2Nlc3NlZFxuXHRcdFx0XHRcdFx0XHR3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGVycm9yQ2FsbGJhY2soKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQ3JlYXRlIHRoZSBhYm9ydCBjYWxsYmFja1xuXHRcdFx0XHRjYWxsYmFjayA9IGNhbGxiYWNrKCBcImFib3J0XCIgKTtcblxuXHRcdFx0XHR0cnkge1xuXG5cdFx0XHRcdFx0Ly8gRG8gc2VuZCB0aGUgcmVxdWVzdCAodGhpcyBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uKVxuXHRcdFx0XHRcdHhoci5zZW5kKCBvcHRpb25zLmhhc0NvbnRlbnQgJiYgb3B0aW9ucy5kYXRhIHx8IG51bGwgKTtcblx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cblx0XHRcdFx0XHQvLyAjMTQ2ODM6IE9ubHkgcmV0aHJvdyBpZiB0aGlzIGhhc24ndCBiZWVuIG5vdGlmaWVkIGFzIGFuIGVycm9yIHlldFxuXHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0XHR0aHJvdyBlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSxcblxuXHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9XG59ICk7XG5cblxuXG5cbi8vIFByZXZlbnQgYXV0by1leGVjdXRpb24gb2Ygc2NyaXB0cyB3aGVuIG5vIGV4cGxpY2l0IGRhdGFUeXBlIHdhcyBwcm92aWRlZCAoU2VlIGdoLTI0MzIpXG5qUXVlcnkuYWpheFByZWZpbHRlciggZnVuY3Rpb24oIHMgKSB7XG5cdGlmICggcy5jcm9zc0RvbWFpbiApIHtcblx0XHRzLmNvbnRlbnRzLnNjcmlwdCA9IGZhbHNlO1xuXHR9XG59ICk7XG5cbi8vIEluc3RhbGwgc2NyaXB0IGRhdGFUeXBlXG5qUXVlcnkuYWpheFNldHVwKCB7XG5cdGFjY2VwdHM6IHtcblx0XHRzY3JpcHQ6IFwidGV4dC9qYXZhc2NyaXB0LCBhcHBsaWNhdGlvbi9qYXZhc2NyaXB0LCBcIiArXG5cdFx0XHRcImFwcGxpY2F0aW9uL2VjbWFzY3JpcHQsIGFwcGxpY2F0aW9uL3gtZWNtYXNjcmlwdFwiXG5cdH0sXG5cdGNvbnRlbnRzOiB7XG5cdFx0c2NyaXB0OiAvXFxiKD86amF2YXxlY21hKXNjcmlwdFxcYi9cblx0fSxcblx0Y29udmVydGVyczoge1xuXHRcdFwidGV4dCBzY3JpcHRcIjogZnVuY3Rpb24oIHRleHQgKSB7XG5cdFx0XHRqUXVlcnkuZ2xvYmFsRXZhbCggdGV4dCApO1xuXHRcdFx0cmV0dXJuIHRleHQ7XG5cdFx0fVxuXHR9XG59ICk7XG5cbi8vIEhhbmRsZSBjYWNoZSdzIHNwZWNpYWwgY2FzZSBhbmQgY3Jvc3NEb21haW5cbmpRdWVyeS5hamF4UHJlZmlsdGVyKCBcInNjcmlwdFwiLCBmdW5jdGlvbiggcyApIHtcblx0aWYgKCBzLmNhY2hlID09PSB1bmRlZmluZWQgKSB7XG5cdFx0cy5jYWNoZSA9IGZhbHNlO1xuXHR9XG5cdGlmICggcy5jcm9zc0RvbWFpbiApIHtcblx0XHRzLnR5cGUgPSBcIkdFVFwiO1xuXHR9XG59ICk7XG5cbi8vIEJpbmQgc2NyaXB0IHRhZyBoYWNrIHRyYW5zcG9ydFxualF1ZXJ5LmFqYXhUcmFuc3BvcnQoIFwic2NyaXB0XCIsIGZ1bmN0aW9uKCBzICkge1xuXG5cdC8vIFRoaXMgdHJhbnNwb3J0IG9ubHkgZGVhbHMgd2l0aCBjcm9zcyBkb21haW4gb3IgZm9yY2VkLWJ5LWF0dHJzIHJlcXVlc3RzXG5cdGlmICggcy5jcm9zc0RvbWFpbiB8fCBzLnNjcmlwdEF0dHJzICkge1xuXHRcdHZhciBzY3JpcHQsIGNhbGxiYWNrO1xuXHRcdHJldHVybiB7XG5cdFx0XHRzZW5kOiBmdW5jdGlvbiggXywgY29tcGxldGUgKSB7XG5cdFx0XHRcdHNjcmlwdCA9IGpRdWVyeSggXCI8c2NyaXB0PlwiIClcblx0XHRcdFx0XHQuYXR0ciggcy5zY3JpcHRBdHRycyB8fCB7fSApXG5cdFx0XHRcdFx0LnByb3AoIHsgY2hhcnNldDogcy5zY3JpcHRDaGFyc2V0LCBzcmM6IHMudXJsIH0gKVxuXHRcdFx0XHRcdC5vbiggXCJsb2FkIGVycm9yXCIsIGNhbGxiYWNrID0gZnVuY3Rpb24oIGV2dCApIHtcblx0XHRcdFx0XHRcdHNjcmlwdC5yZW1vdmUoKTtcblx0XHRcdFx0XHRcdGNhbGxiYWNrID0gbnVsbDtcblx0XHRcdFx0XHRcdGlmICggZXZ0ICkge1xuXHRcdFx0XHRcdFx0XHRjb21wbGV0ZSggZXZ0LnR5cGUgPT09IFwiZXJyb3JcIiA/IDQwNCA6IDIwMCwgZXZ0LnR5cGUgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9ICk7XG5cblx0XHRcdFx0Ly8gVXNlIG5hdGl2ZSBET00gbWFuaXB1bGF0aW9uIHRvIGF2b2lkIG91ciBkb21NYW5pcCBBSkFYIHRyaWNrZXJ5XG5cdFx0XHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoIHNjcmlwdFsgMCBdICk7XG5cdFx0XHR9LFxuXHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9XG59ICk7XG5cblxuXG5cbnZhciBvbGRDYWxsYmFja3MgPSBbXSxcblx0cmpzb25wID0gLyg9KVxcPyg/PSZ8JCl8XFw/XFw/LztcblxuLy8gRGVmYXVsdCBqc29ucCBzZXR0aW5nc1xualF1ZXJ5LmFqYXhTZXR1cCgge1xuXHRqc29ucDogXCJjYWxsYmFja1wiLFxuXHRqc29ucENhbGxiYWNrOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgY2FsbGJhY2sgPSBvbGRDYWxsYmFja3MucG9wKCkgfHwgKCBqUXVlcnkuZXhwYW5kbyArIFwiX1wiICsgKCBub25jZS5ndWlkKysgKSApO1xuXHRcdHRoaXNbIGNhbGxiYWNrIF0gPSB0cnVlO1xuXHRcdHJldHVybiBjYWxsYmFjaztcblx0fVxufSApO1xuXG4vLyBEZXRlY3QsIG5vcm1hbGl6ZSBvcHRpb25zIGFuZCBpbnN0YWxsIGNhbGxiYWNrcyBmb3IganNvbnAgcmVxdWVzdHNcbmpRdWVyeS5hamF4UHJlZmlsdGVyKCBcImpzb24ganNvbnBcIiwgZnVuY3Rpb24oIHMsIG9yaWdpbmFsU2V0dGluZ3MsIGpxWEhSICkge1xuXG5cdHZhciBjYWxsYmFja05hbWUsIG92ZXJ3cml0dGVuLCByZXNwb25zZUNvbnRhaW5lcixcblx0XHRqc29uUHJvcCA9IHMuanNvbnAgIT09IGZhbHNlICYmICggcmpzb25wLnRlc3QoIHMudXJsICkgP1xuXHRcdFx0XCJ1cmxcIiA6XG5cdFx0XHR0eXBlb2Ygcy5kYXRhID09PSBcInN0cmluZ1wiICYmXG5cdFx0XHRcdCggcy5jb250ZW50VHlwZSB8fCBcIlwiIClcblx0XHRcdFx0XHQuaW5kZXhPZiggXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcIiApID09PSAwICYmXG5cdFx0XHRcdHJqc29ucC50ZXN0KCBzLmRhdGEgKSAmJiBcImRhdGFcIlxuXHRcdCk7XG5cblx0Ly8gSGFuZGxlIGlmZiB0aGUgZXhwZWN0ZWQgZGF0YSB0eXBlIGlzIFwianNvbnBcIiBvciB3ZSBoYXZlIGEgcGFyYW1ldGVyIHRvIHNldFxuXHRpZiAoIGpzb25Qcm9wIHx8IHMuZGF0YVR5cGVzWyAwIF0gPT09IFwianNvbnBcIiApIHtcblxuXHRcdC8vIEdldCBjYWxsYmFjayBuYW1lLCByZW1lbWJlcmluZyBwcmVleGlzdGluZyB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggaXRcblx0XHRjYWxsYmFja05hbWUgPSBzLmpzb25wQ2FsbGJhY2sgPSBpc0Z1bmN0aW9uKCBzLmpzb25wQ2FsbGJhY2sgKSA/XG5cdFx0XHRzLmpzb25wQ2FsbGJhY2soKSA6XG5cdFx0XHRzLmpzb25wQ2FsbGJhY2s7XG5cblx0XHQvLyBJbnNlcnQgY2FsbGJhY2sgaW50byB1cmwgb3IgZm9ybSBkYXRhXG5cdFx0aWYgKCBqc29uUHJvcCApIHtcblx0XHRcdHNbIGpzb25Qcm9wIF0gPSBzWyBqc29uUHJvcCBdLnJlcGxhY2UoIHJqc29ucCwgXCIkMVwiICsgY2FsbGJhY2tOYW1lICk7XG5cdFx0fSBlbHNlIGlmICggcy5qc29ucCAhPT0gZmFsc2UgKSB7XG5cdFx0XHRzLnVybCArPSAoIHJxdWVyeS50ZXN0KCBzLnVybCApID8gXCImXCIgOiBcIj9cIiApICsgcy5qc29ucCArIFwiPVwiICsgY2FsbGJhY2tOYW1lO1xuXHRcdH1cblxuXHRcdC8vIFVzZSBkYXRhIGNvbnZlcnRlciB0byByZXRyaWV2ZSBqc29uIGFmdGVyIHNjcmlwdCBleGVjdXRpb25cblx0XHRzLmNvbnZlcnRlcnNbIFwic2NyaXB0IGpzb25cIiBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoICFyZXNwb25zZUNvbnRhaW5lciApIHtcblx0XHRcdFx0alF1ZXJ5LmVycm9yKCBjYWxsYmFja05hbWUgKyBcIiB3YXMgbm90IGNhbGxlZFwiICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVzcG9uc2VDb250YWluZXJbIDAgXTtcblx0XHR9O1xuXG5cdFx0Ly8gRm9yY2UganNvbiBkYXRhVHlwZVxuXHRcdHMuZGF0YVR5cGVzWyAwIF0gPSBcImpzb25cIjtcblxuXHRcdC8vIEluc3RhbGwgY2FsbGJhY2tcblx0XHRvdmVyd3JpdHRlbiA9IHdpbmRvd1sgY2FsbGJhY2tOYW1lIF07XG5cdFx0d2luZG93WyBjYWxsYmFja05hbWUgXSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmVzcG9uc2VDb250YWluZXIgPSBhcmd1bWVudHM7XG5cdFx0fTtcblxuXHRcdC8vIENsZWFuLXVwIGZ1bmN0aW9uIChmaXJlcyBhZnRlciBjb252ZXJ0ZXJzKVxuXHRcdGpxWEhSLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIElmIHByZXZpb3VzIHZhbHVlIGRpZG4ndCBleGlzdCAtIHJlbW92ZSBpdFxuXHRcdFx0aWYgKCBvdmVyd3JpdHRlbiA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRqUXVlcnkoIHdpbmRvdyApLnJlbW92ZVByb3AoIGNhbGxiYWNrTmFtZSApO1xuXG5cdFx0XHQvLyBPdGhlcndpc2UgcmVzdG9yZSBwcmVleGlzdGluZyB2YWx1ZVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0d2luZG93WyBjYWxsYmFja05hbWUgXSA9IG92ZXJ3cml0dGVuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTYXZlIGJhY2sgYXMgZnJlZVxuXHRcdFx0aWYgKCBzWyBjYWxsYmFja05hbWUgXSApIHtcblxuXHRcdFx0XHQvLyBNYWtlIHN1cmUgdGhhdCByZS11c2luZyB0aGUgb3B0aW9ucyBkb2Vzbid0IHNjcmV3IHRoaW5ncyBhcm91bmRcblx0XHRcdFx0cy5qc29ucENhbGxiYWNrID0gb3JpZ2luYWxTZXR0aW5ncy5qc29ucENhbGxiYWNrO1xuXG5cdFx0XHRcdC8vIFNhdmUgdGhlIGNhbGxiYWNrIG5hbWUgZm9yIGZ1dHVyZSB1c2Vcblx0XHRcdFx0b2xkQ2FsbGJhY2tzLnB1c2goIGNhbGxiYWNrTmFtZSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDYWxsIGlmIGl0IHdhcyBhIGZ1bmN0aW9uIGFuZCB3ZSBoYXZlIGEgcmVzcG9uc2Vcblx0XHRcdGlmICggcmVzcG9uc2VDb250YWluZXIgJiYgaXNGdW5jdGlvbiggb3ZlcndyaXR0ZW4gKSApIHtcblx0XHRcdFx0b3ZlcndyaXR0ZW4oIHJlc3BvbnNlQ29udGFpbmVyWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0cmVzcG9uc2VDb250YWluZXIgPSBvdmVyd3JpdHRlbiA9IHVuZGVmaW5lZDtcblx0XHR9ICk7XG5cblx0XHQvLyBEZWxlZ2F0ZSB0byBzY3JpcHRcblx0XHRyZXR1cm4gXCJzY3JpcHRcIjtcblx0fVxufSApO1xuXG5cblxuXG4vLyBTdXBwb3J0OiBTYWZhcmkgOCBvbmx5XG4vLyBJbiBTYWZhcmkgOCBkb2N1bWVudHMgY3JlYXRlZCB2aWEgZG9jdW1lbnQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50XG4vLyBjb2xsYXBzZSBzaWJsaW5nIGZvcm1zOiB0aGUgc2Vjb25kIG9uZSBiZWNvbWVzIGEgY2hpbGQgb2YgdGhlIGZpcnN0IG9uZS5cbi8vIEJlY2F1c2Ugb2YgdGhhdCwgdGhpcyBzZWN1cml0eSBtZWFzdXJlIGhhcyB0byBiZSBkaXNhYmxlZCBpbiBTYWZhcmkgOC5cbi8vIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzczMzdcbnN1cHBvcnQuY3JlYXRlSFRNTERvY3VtZW50ID0gKCBmdW5jdGlvbigpIHtcblx0dmFyIGJvZHkgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoIFwiXCIgKS5ib2R5O1xuXHRib2R5LmlubmVySFRNTCA9IFwiPGZvcm0+PC9mb3JtPjxmb3JtPjwvZm9ybT5cIjtcblx0cmV0dXJuIGJvZHkuY2hpbGROb2Rlcy5sZW5ndGggPT09IDI7XG59ICkoKTtcblxuXG4vLyBBcmd1bWVudCBcImRhdGFcIiBzaG91bGQgYmUgc3RyaW5nIG9mIGh0bWxcbi8vIGNvbnRleHQgKG9wdGlvbmFsKTogSWYgc3BlY2lmaWVkLCB0aGUgZnJhZ21lbnQgd2lsbCBiZSBjcmVhdGVkIGluIHRoaXMgY29udGV4dCxcbi8vIGRlZmF1bHRzIHRvIGRvY3VtZW50XG4vLyBrZWVwU2NyaXB0cyAob3B0aW9uYWwpOiBJZiB0cnVlLCB3aWxsIGluY2x1ZGUgc2NyaXB0cyBwYXNzZWQgaW4gdGhlIGh0bWwgc3RyaW5nXG5qUXVlcnkucGFyc2VIVE1MID0gZnVuY3Rpb24oIGRhdGEsIGNvbnRleHQsIGtlZXBTY3JpcHRzICkge1xuXHRpZiAoIHR5cGVvZiBkYXRhICE9PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiBbXTtcblx0fVxuXHRpZiAoIHR5cGVvZiBjb250ZXh0ID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRrZWVwU2NyaXB0cyA9IGNvbnRleHQ7XG5cdFx0Y29udGV4dCA9IGZhbHNlO1xuXHR9XG5cblx0dmFyIGJhc2UsIHBhcnNlZCwgc2NyaXB0cztcblxuXHRpZiAoICFjb250ZXh0ICkge1xuXG5cdFx0Ly8gU3RvcCBzY3JpcHRzIG9yIGlubGluZSBldmVudCBoYW5kbGVycyBmcm9tIGJlaW5nIGV4ZWN1dGVkIGltbWVkaWF0ZWx5XG5cdFx0Ly8gYnkgdXNpbmcgZG9jdW1lbnQuaW1wbGVtZW50YXRpb25cblx0XHRpZiAoIHN1cHBvcnQuY3JlYXRlSFRNTERvY3VtZW50ICkge1xuXHRcdFx0Y29udGV4dCA9IGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCggXCJcIiApO1xuXG5cdFx0XHQvLyBTZXQgdGhlIGJhc2UgaHJlZiBmb3IgdGhlIGNyZWF0ZWQgZG9jdW1lbnRcblx0XHRcdC8vIHNvIGFueSBwYXJzZWQgZWxlbWVudHMgd2l0aCBVUkxzXG5cdFx0XHQvLyBhcmUgYmFzZWQgb24gdGhlIGRvY3VtZW50J3MgVVJMIChnaC0yOTY1KVxuXHRcdFx0YmFzZSA9IGNvbnRleHQuY3JlYXRlRWxlbWVudCggXCJiYXNlXCIgKTtcblx0XHRcdGJhc2UuaHJlZiA9IGRvY3VtZW50LmxvY2F0aW9uLmhyZWY7XG5cdFx0XHRjb250ZXh0LmhlYWQuYXBwZW5kQ2hpbGQoIGJhc2UgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29udGV4dCA9IGRvY3VtZW50O1xuXHRcdH1cblx0fVxuXG5cdHBhcnNlZCA9IHJzaW5nbGVUYWcuZXhlYyggZGF0YSApO1xuXHRzY3JpcHRzID0gIWtlZXBTY3JpcHRzICYmIFtdO1xuXG5cdC8vIFNpbmdsZSB0YWdcblx0aWYgKCBwYXJzZWQgKSB7XG5cdFx0cmV0dXJuIFsgY29udGV4dC5jcmVhdGVFbGVtZW50KCBwYXJzZWRbIDEgXSApIF07XG5cdH1cblxuXHRwYXJzZWQgPSBidWlsZEZyYWdtZW50KCBbIGRhdGEgXSwgY29udGV4dCwgc2NyaXB0cyApO1xuXG5cdGlmICggc2NyaXB0cyAmJiBzY3JpcHRzLmxlbmd0aCApIHtcblx0XHRqUXVlcnkoIHNjcmlwdHMgKS5yZW1vdmUoKTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnkubWVyZ2UoIFtdLCBwYXJzZWQuY2hpbGROb2RlcyApO1xufTtcblxuXG4vKipcbiAqIExvYWQgYSB1cmwgaW50byBhIHBhZ2VcbiAqL1xualF1ZXJ5LmZuLmxvYWQgPSBmdW5jdGlvbiggdXJsLCBwYXJhbXMsIGNhbGxiYWNrICkge1xuXHR2YXIgc2VsZWN0b3IsIHR5cGUsIHJlc3BvbnNlLFxuXHRcdHNlbGYgPSB0aGlzLFxuXHRcdG9mZiA9IHVybC5pbmRleE9mKCBcIiBcIiApO1xuXG5cdGlmICggb2ZmID4gLTEgKSB7XG5cdFx0c2VsZWN0b3IgPSBzdHJpcEFuZENvbGxhcHNlKCB1cmwuc2xpY2UoIG9mZiApICk7XG5cdFx0dXJsID0gdXJsLnNsaWNlKCAwLCBvZmYgKTtcblx0fVxuXG5cdC8vIElmIGl0J3MgYSBmdW5jdGlvblxuXHRpZiAoIGlzRnVuY3Rpb24oIHBhcmFtcyApICkge1xuXG5cdFx0Ly8gV2UgYXNzdW1lIHRoYXQgaXQncyB0aGUgY2FsbGJhY2tcblx0XHRjYWxsYmFjayA9IHBhcmFtcztcblx0XHRwYXJhbXMgPSB1bmRlZmluZWQ7XG5cblx0Ly8gT3RoZXJ3aXNlLCBidWlsZCBhIHBhcmFtIHN0cmluZ1xuXHR9IGVsc2UgaWYgKCBwYXJhbXMgJiYgdHlwZW9mIHBhcmFtcyA9PT0gXCJvYmplY3RcIiApIHtcblx0XHR0eXBlID0gXCJQT1NUXCI7XG5cdH1cblxuXHQvLyBJZiB3ZSBoYXZlIGVsZW1lbnRzIHRvIG1vZGlmeSwgbWFrZSB0aGUgcmVxdWVzdFxuXHRpZiAoIHNlbGYubGVuZ3RoID4gMCApIHtcblx0XHRqUXVlcnkuYWpheCgge1xuXHRcdFx0dXJsOiB1cmwsXG5cblx0XHRcdC8vIElmIFwidHlwZVwiIHZhcmlhYmxlIGlzIHVuZGVmaW5lZCwgdGhlbiBcIkdFVFwiIG1ldGhvZCB3aWxsIGJlIHVzZWQuXG5cdFx0XHQvLyBNYWtlIHZhbHVlIG9mIHRoaXMgZmllbGQgZXhwbGljaXQgc2luY2Vcblx0XHRcdC8vIHVzZXIgY2FuIG92ZXJyaWRlIGl0IHRocm91Z2ggYWpheFNldHVwIG1ldGhvZFxuXHRcdFx0dHlwZTogdHlwZSB8fCBcIkdFVFwiLFxuXHRcdFx0ZGF0YVR5cGU6IFwiaHRtbFwiLFxuXHRcdFx0ZGF0YTogcGFyYW1zXG5cdFx0fSApLmRvbmUoIGZ1bmN0aW9uKCByZXNwb25zZVRleHQgKSB7XG5cblx0XHRcdC8vIFNhdmUgcmVzcG9uc2UgZm9yIHVzZSBpbiBjb21wbGV0ZSBjYWxsYmFja1xuXHRcdFx0cmVzcG9uc2UgPSBhcmd1bWVudHM7XG5cblx0XHRcdHNlbGYuaHRtbCggc2VsZWN0b3IgP1xuXG5cdFx0XHRcdC8vIElmIGEgc2VsZWN0b3Igd2FzIHNwZWNpZmllZCwgbG9jYXRlIHRoZSByaWdodCBlbGVtZW50cyBpbiBhIGR1bW15IGRpdlxuXHRcdFx0XHQvLyBFeGNsdWRlIHNjcmlwdHMgdG8gYXZvaWQgSUUgJ1Blcm1pc3Npb24gRGVuaWVkJyBlcnJvcnNcblx0XHRcdFx0alF1ZXJ5KCBcIjxkaXY+XCIgKS5hcHBlbmQoIGpRdWVyeS5wYXJzZUhUTUwoIHJlc3BvbnNlVGV4dCApICkuZmluZCggc2VsZWN0b3IgKSA6XG5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIHVzZSB0aGUgZnVsbCByZXN1bHRcblx0XHRcdFx0cmVzcG9uc2VUZXh0ICk7XG5cblx0XHQvLyBJZiB0aGUgcmVxdWVzdCBzdWNjZWVkcywgdGhpcyBmdW5jdGlvbiBnZXRzIFwiZGF0YVwiLCBcInN0YXR1c1wiLCBcImpxWEhSXCJcblx0XHQvLyBidXQgdGhleSBhcmUgaWdub3JlZCBiZWNhdXNlIHJlc3BvbnNlIHdhcyBzZXQgYWJvdmUuXG5cdFx0Ly8gSWYgaXQgZmFpbHMsIHRoaXMgZnVuY3Rpb24gZ2V0cyBcImpxWEhSXCIsIFwic3RhdHVzXCIsIFwiZXJyb3JcIlxuXHRcdH0gKS5hbHdheXMoIGNhbGxiYWNrICYmIGZ1bmN0aW9uKCBqcVhIUiwgc3RhdHVzICkge1xuXHRcdFx0c2VsZi5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0Y2FsbGJhY2suYXBwbHkoIHRoaXMsIHJlc3BvbnNlIHx8IFsganFYSFIucmVzcG9uc2VUZXh0LCBzdGF0dXMsIGpxWEhSIF0gKTtcblx0XHRcdH0gKTtcblx0XHR9ICk7XG5cdH1cblxuXHRyZXR1cm4gdGhpcztcbn07XG5cblxuXG5cbmpRdWVyeS5leHByLnBzZXVkb3MuYW5pbWF0ZWQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0cmV0dXJuIGpRdWVyeS5ncmVwKCBqUXVlcnkudGltZXJzLCBmdW5jdGlvbiggZm4gKSB7XG5cdFx0cmV0dXJuIGVsZW0gPT09IGZuLmVsZW07XG5cdH0gKS5sZW5ndGg7XG59O1xuXG5cblxuXG5qUXVlcnkub2Zmc2V0ID0ge1xuXHRzZXRPZmZzZXQ6IGZ1bmN0aW9uKCBlbGVtLCBvcHRpb25zLCBpICkge1xuXHRcdHZhciBjdXJQb3NpdGlvbiwgY3VyTGVmdCwgY3VyQ1NTVG9wLCBjdXJUb3AsIGN1ck9mZnNldCwgY3VyQ1NTTGVmdCwgY2FsY3VsYXRlUG9zaXRpb24sXG5cdFx0XHRwb3NpdGlvbiA9IGpRdWVyeS5jc3MoIGVsZW0sIFwicG9zaXRpb25cIiApLFxuXHRcdFx0Y3VyRWxlbSA9IGpRdWVyeSggZWxlbSApLFxuXHRcdFx0cHJvcHMgPSB7fTtcblxuXHRcdC8vIFNldCBwb3NpdGlvbiBmaXJzdCwgaW4tY2FzZSB0b3AvbGVmdCBhcmUgc2V0IGV2ZW4gb24gc3RhdGljIGVsZW1cblx0XHRpZiAoIHBvc2l0aW9uID09PSBcInN0YXRpY1wiICkge1xuXHRcdFx0ZWxlbS5zdHlsZS5wb3NpdGlvbiA9IFwicmVsYXRpdmVcIjtcblx0XHR9XG5cblx0XHRjdXJPZmZzZXQgPSBjdXJFbGVtLm9mZnNldCgpO1xuXHRcdGN1ckNTU1RvcCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwidG9wXCIgKTtcblx0XHRjdXJDU1NMZWZ0ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJsZWZ0XCIgKTtcblx0XHRjYWxjdWxhdGVQb3NpdGlvbiA9ICggcG9zaXRpb24gPT09IFwiYWJzb2x1dGVcIiB8fCBwb3NpdGlvbiA9PT0gXCJmaXhlZFwiICkgJiZcblx0XHRcdCggY3VyQ1NTVG9wICsgY3VyQ1NTTGVmdCApLmluZGV4T2YoIFwiYXV0b1wiICkgPiAtMTtcblxuXHRcdC8vIE5lZWQgdG8gYmUgYWJsZSB0byBjYWxjdWxhdGUgcG9zaXRpb24gaWYgZWl0aGVyXG5cdFx0Ly8gdG9wIG9yIGxlZnQgaXMgYXV0byBhbmQgcG9zaXRpb24gaXMgZWl0aGVyIGFic29sdXRlIG9yIGZpeGVkXG5cdFx0aWYgKCBjYWxjdWxhdGVQb3NpdGlvbiApIHtcblx0XHRcdGN1clBvc2l0aW9uID0gY3VyRWxlbS5wb3NpdGlvbigpO1xuXHRcdFx0Y3VyVG9wID0gY3VyUG9zaXRpb24udG9wO1xuXHRcdFx0Y3VyTGVmdCA9IGN1clBvc2l0aW9uLmxlZnQ7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0Y3VyVG9wID0gcGFyc2VGbG9hdCggY3VyQ1NTVG9wICkgfHwgMDtcblx0XHRcdGN1ckxlZnQgPSBwYXJzZUZsb2F0KCBjdXJDU1NMZWZ0ICkgfHwgMDtcblx0XHR9XG5cblx0XHRpZiAoIGlzRnVuY3Rpb24oIG9wdGlvbnMgKSApIHtcblxuXHRcdFx0Ly8gVXNlIGpRdWVyeS5leHRlbmQgaGVyZSB0byBhbGxvdyBtb2RpZmljYXRpb24gb2YgY29vcmRpbmF0ZXMgYXJndW1lbnQgKGdoLTE4NDgpXG5cdFx0XHRvcHRpb25zID0gb3B0aW9ucy5jYWxsKCBlbGVtLCBpLCBqUXVlcnkuZXh0ZW5kKCB7fSwgY3VyT2Zmc2V0ICkgKTtcblx0XHR9XG5cblx0XHRpZiAoIG9wdGlvbnMudG9wICE9IG51bGwgKSB7XG5cdFx0XHRwcm9wcy50b3AgPSAoIG9wdGlvbnMudG9wIC0gY3VyT2Zmc2V0LnRvcCApICsgY3VyVG9wO1xuXHRcdH1cblx0XHRpZiAoIG9wdGlvbnMubGVmdCAhPSBudWxsICkge1xuXHRcdFx0cHJvcHMubGVmdCA9ICggb3B0aW9ucy5sZWZ0IC0gY3VyT2Zmc2V0LmxlZnQgKSArIGN1ckxlZnQ7XG5cdFx0fVxuXG5cdFx0aWYgKCBcInVzaW5nXCIgaW4gb3B0aW9ucyApIHtcblx0XHRcdG9wdGlvbnMudXNpbmcuY2FsbCggZWxlbSwgcHJvcHMgKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjdXJFbGVtLmNzcyggcHJvcHMgKTtcblx0XHR9XG5cdH1cbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblxuXHQvLyBvZmZzZXQoKSByZWxhdGVzIGFuIGVsZW1lbnQncyBib3JkZXIgYm94IHRvIHRoZSBkb2N1bWVudCBvcmlnaW5cblx0b2Zmc2V0OiBmdW5jdGlvbiggb3B0aW9ucyApIHtcblxuXHRcdC8vIFByZXNlcnZlIGNoYWluaW5nIGZvciBzZXR0ZXJcblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gb3B0aW9ucyA9PT0gdW5kZWZpbmVkID9cblx0XHRcdFx0dGhpcyA6XG5cdFx0XHRcdHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5Lm9mZnNldC5zZXRPZmZzZXQoIHRoaXMsIG9wdGlvbnMsIGkgKTtcblx0XHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHZhciByZWN0LCB3aW4sXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdO1xuXG5cdFx0aWYgKCAhZWxlbSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBSZXR1cm4gemVyb3MgZm9yIGRpc2Nvbm5lY3RlZCBhbmQgaGlkZGVuIChkaXNwbGF5OiBub25lKSBlbGVtZW50cyAoZ2gtMjMxMClcblx0XHQvLyBTdXBwb3J0OiBJRSA8PTExIG9ubHlcblx0XHQvLyBSdW5uaW5nIGdldEJvdW5kaW5nQ2xpZW50UmVjdCBvbiBhXG5cdFx0Ly8gZGlzY29ubmVjdGVkIG5vZGUgaW4gSUUgdGhyb3dzIGFuIGVycm9yXG5cdFx0aWYgKCAhZWxlbS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCApIHtcblx0XHRcdHJldHVybiB7IHRvcDogMCwgbGVmdDogMCB9O1xuXHRcdH1cblxuXHRcdC8vIEdldCBkb2N1bWVudC1yZWxhdGl2ZSBwb3NpdGlvbiBieSBhZGRpbmcgdmlld3BvcnQgc2Nyb2xsIHRvIHZpZXdwb3J0LXJlbGF0aXZlIGdCQ1Jcblx0XHRyZWN0ID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHR3aW4gPSBlbGVtLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXc7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHRvcDogcmVjdC50b3AgKyB3aW4ucGFnZVlPZmZzZXQsXG5cdFx0XHRsZWZ0OiByZWN0LmxlZnQgKyB3aW4ucGFnZVhPZmZzZXRcblx0XHR9O1xuXHR9LFxuXG5cdC8vIHBvc2l0aW9uKCkgcmVsYXRlcyBhbiBlbGVtZW50J3MgbWFyZ2luIGJveCB0byBpdHMgb2Zmc2V0IHBhcmVudCdzIHBhZGRpbmcgYm94XG5cdC8vIFRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIGJlaGF2aW9yIG9mIENTUyBhYnNvbHV0ZSBwb3NpdGlvbmluZ1xuXHRwb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCAhdGhpc1sgMCBdICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBvZmZzZXRQYXJlbnQsIG9mZnNldCwgZG9jLFxuXHRcdFx0ZWxlbSA9IHRoaXNbIDAgXSxcblx0XHRcdHBhcmVudE9mZnNldCA9IHsgdG9wOiAwLCBsZWZ0OiAwIH07XG5cblx0XHQvLyBwb3NpdGlvbjpmaXhlZCBlbGVtZW50cyBhcmUgb2Zmc2V0IGZyb20gdGhlIHZpZXdwb3J0LCB3aGljaCBpdHNlbGYgYWx3YXlzIGhhcyB6ZXJvIG9mZnNldFxuXHRcdGlmICggalF1ZXJ5LmNzcyggZWxlbSwgXCJwb3NpdGlvblwiICkgPT09IFwiZml4ZWRcIiApIHtcblxuXHRcdFx0Ly8gQXNzdW1lIHBvc2l0aW9uOmZpeGVkIGltcGxpZXMgYXZhaWxhYmlsaXR5IG9mIGdldEJvdW5kaW5nQ2xpZW50UmVjdFxuXHRcdFx0b2Zmc2V0ID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRvZmZzZXQgPSB0aGlzLm9mZnNldCgpO1xuXG5cdFx0XHQvLyBBY2NvdW50IGZvciB0aGUgKnJlYWwqIG9mZnNldCBwYXJlbnQsIHdoaWNoIGNhbiBiZSB0aGUgZG9jdW1lbnQgb3IgaXRzIHJvb3QgZWxlbWVudFxuXHRcdFx0Ly8gd2hlbiBhIHN0YXRpY2FsbHkgcG9zaXRpb25lZCBlbGVtZW50IGlzIGlkZW50aWZpZWRcblx0XHRcdGRvYyA9IGVsZW0ub3duZXJEb2N1bWVudDtcblx0XHRcdG9mZnNldFBhcmVudCA9IGVsZW0ub2Zmc2V0UGFyZW50IHx8IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG5cdFx0XHR3aGlsZSAoIG9mZnNldFBhcmVudCAmJlxuXHRcdFx0XHQoIG9mZnNldFBhcmVudCA9PT0gZG9jLmJvZHkgfHwgb2Zmc2V0UGFyZW50ID09PSBkb2MuZG9jdW1lbnRFbGVtZW50ICkgJiZcblx0XHRcdFx0alF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcInBvc2l0aW9uXCIgKSA9PT0gXCJzdGF0aWNcIiApIHtcblxuXHRcdFx0XHRvZmZzZXRQYXJlbnQgPSBvZmZzZXRQYXJlbnQucGFyZW50Tm9kZTtcblx0XHRcdH1cblx0XHRcdGlmICggb2Zmc2V0UGFyZW50ICYmIG9mZnNldFBhcmVudCAhPT0gZWxlbSAmJiBvZmZzZXRQYXJlbnQubm9kZVR5cGUgPT09IDEgKSB7XG5cblx0XHRcdFx0Ly8gSW5jb3Jwb3JhdGUgYm9yZGVycyBpbnRvIGl0cyBvZmZzZXQsIHNpbmNlIHRoZXkgYXJlIG91dHNpZGUgaXRzIGNvbnRlbnQgb3JpZ2luXG5cdFx0XHRcdHBhcmVudE9mZnNldCA9IGpRdWVyeSggb2Zmc2V0UGFyZW50ICkub2Zmc2V0KCk7XG5cdFx0XHRcdHBhcmVudE9mZnNldC50b3AgKz0galF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcImJvcmRlclRvcFdpZHRoXCIsIHRydWUgKTtcblx0XHRcdFx0cGFyZW50T2Zmc2V0LmxlZnQgKz0galF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcImJvcmRlckxlZnRXaWR0aFwiLCB0cnVlICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU3VidHJhY3QgcGFyZW50IG9mZnNldHMgYW5kIGVsZW1lbnQgbWFyZ2luc1xuXHRcdHJldHVybiB7XG5cdFx0XHR0b3A6IG9mZnNldC50b3AgLSBwYXJlbnRPZmZzZXQudG9wIC0galF1ZXJ5LmNzcyggZWxlbSwgXCJtYXJnaW5Ub3BcIiwgdHJ1ZSApLFxuXHRcdFx0bGVmdDogb2Zmc2V0LmxlZnQgLSBwYXJlbnRPZmZzZXQubGVmdCAtIGpRdWVyeS5jc3MoIGVsZW0sIFwibWFyZ2luTGVmdFwiLCB0cnVlIClcblx0XHR9O1xuXHR9LFxuXG5cdC8vIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIGRvY3VtZW50RWxlbWVudCBpbiB0aGUgZm9sbG93aW5nIGNhc2VzOlxuXHQvLyAxKSBGb3IgdGhlIGVsZW1lbnQgaW5zaWRlIHRoZSBpZnJhbWUgd2l0aG91dCBvZmZzZXRQYXJlbnQsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuXG5cdC8vICAgIGRvY3VtZW50RWxlbWVudCBvZiB0aGUgcGFyZW50IHdpbmRvd1xuXHQvLyAyKSBGb3IgdGhlIGhpZGRlbiBvciBkZXRhY2hlZCBlbGVtZW50XG5cdC8vIDMpIEZvciBib2R5IG9yIGh0bWwgZWxlbWVudCwgaS5lLiBpbiBjYXNlIG9mIHRoZSBodG1sIG5vZGUgLSBpdCB3aWxsIHJldHVybiBpdHNlbGZcblx0Ly9cblx0Ly8gYnV0IHRob3NlIGV4Y2VwdGlvbnMgd2VyZSBuZXZlciBwcmVzZW50ZWQgYXMgYSByZWFsIGxpZmUgdXNlLWNhc2VzXG5cdC8vIGFuZCBtaWdodCBiZSBjb25zaWRlcmVkIGFzIG1vcmUgcHJlZmVyYWJsZSByZXN1bHRzLlxuXHQvL1xuXHQvLyBUaGlzIGxvZ2ljLCBob3dldmVyLCBpcyBub3QgZ3VhcmFudGVlZCBhbmQgY2FuIGNoYW5nZSBhdCBhbnkgcG9pbnQgaW4gdGhlIGZ1dHVyZVxuXHRvZmZzZXRQYXJlbnQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLm1hcCggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgb2Zmc2V0UGFyZW50ID0gdGhpcy5vZmZzZXRQYXJlbnQ7XG5cblx0XHRcdHdoaWxlICggb2Zmc2V0UGFyZW50ICYmIGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudCwgXCJwb3NpdGlvblwiICkgPT09IFwic3RhdGljXCIgKSB7XG5cdFx0XHRcdG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudC5vZmZzZXRQYXJlbnQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBvZmZzZXRQYXJlbnQgfHwgZG9jdW1lbnRFbGVtZW50O1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG4vLyBDcmVhdGUgc2Nyb2xsTGVmdCBhbmQgc2Nyb2xsVG9wIG1ldGhvZHNcbmpRdWVyeS5lYWNoKCB7IHNjcm9sbExlZnQ6IFwicGFnZVhPZmZzZXRcIiwgc2Nyb2xsVG9wOiBcInBhZ2VZT2Zmc2V0XCIgfSwgZnVuY3Rpb24oIG1ldGhvZCwgcHJvcCApIHtcblx0dmFyIHRvcCA9IFwicGFnZVlPZmZzZXRcIiA9PT0gcHJvcDtcblxuXHRqUXVlcnkuZm5bIG1ldGhvZCBdID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbWV0aG9kLCB2YWwgKSB7XG5cblx0XHRcdC8vIENvYWxlc2NlIGRvY3VtZW50cyBhbmQgd2luZG93c1xuXHRcdFx0dmFyIHdpbjtcblx0XHRcdGlmICggaXNXaW5kb3coIGVsZW0gKSApIHtcblx0XHRcdFx0d2luID0gZWxlbTtcblx0XHRcdH0gZWxzZSBpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdHdpbiA9IGVsZW0uZGVmYXVsdFZpZXc7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggdmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiB3aW4gPyB3aW5bIHByb3AgXSA6IGVsZW1bIG1ldGhvZCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHdpbiApIHtcblx0XHRcdFx0d2luLnNjcm9sbFRvKFxuXHRcdFx0XHRcdCF0b3AgPyB2YWwgOiB3aW4ucGFnZVhPZmZzZXQsXG5cdFx0XHRcdFx0dG9wID8gdmFsIDogd2luLnBhZ2VZT2Zmc2V0XG5cdFx0XHRcdCk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1bIG1ldGhvZCBdID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0sIG1ldGhvZCwgdmFsLCBhcmd1bWVudHMubGVuZ3RoICk7XG5cdH07XG59ICk7XG5cbi8vIFN1cHBvcnQ6IFNhZmFyaSA8PTcgLSA5LjEsIENocm9tZSA8PTM3IC0gNDlcbi8vIEFkZCB0aGUgdG9wL2xlZnQgY3NzSG9va3MgdXNpbmcgalF1ZXJ5LmZuLnBvc2l0aW9uXG4vLyBXZWJraXQgYnVnOiBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjkwODRcbi8vIEJsaW5rIGJ1ZzogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NTg5MzQ3XG4vLyBnZXRDb21wdXRlZFN0eWxlIHJldHVybnMgcGVyY2VudCB3aGVuIHNwZWNpZmllZCBmb3IgdG9wL2xlZnQvYm90dG9tL3JpZ2h0O1xuLy8gcmF0aGVyIHRoYW4gbWFrZSB0aGUgY3NzIG1vZHVsZSBkZXBlbmQgb24gdGhlIG9mZnNldCBtb2R1bGUsIGp1c3QgY2hlY2sgZm9yIGl0IGhlcmVcbmpRdWVyeS5lYWNoKCBbIFwidG9wXCIsIFwibGVmdFwiIF0sIGZ1bmN0aW9uKCBfaSwgcHJvcCApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBwcm9wIF0gPSBhZGRHZXRIb29rSWYoIHN1cHBvcnQucGl4ZWxQb3NpdGlvbixcblx0XHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xuXHRcdFx0XHRjb21wdXRlZCA9IGN1ckNTUyggZWxlbSwgcHJvcCApO1xuXG5cdFx0XHRcdC8vIElmIGN1ckNTUyByZXR1cm5zIHBlcmNlbnRhZ2UsIGZhbGxiYWNrIHRvIG9mZnNldFxuXHRcdFx0XHRyZXR1cm4gcm51bW5vbnB4LnRlc3QoIGNvbXB1dGVkICkgP1xuXHRcdFx0XHRcdGpRdWVyeSggZWxlbSApLnBvc2l0aW9uKClbIHByb3AgXSArIFwicHhcIiA6XG5cdFx0XHRcdFx0Y29tcHV0ZWQ7XG5cdFx0XHR9XG5cdFx0fVxuXHQpO1xufSApO1xuXG5cbi8vIENyZWF0ZSBpbm5lckhlaWdodCwgaW5uZXJXaWR0aCwgaGVpZ2h0LCB3aWR0aCwgb3V0ZXJIZWlnaHQgYW5kIG91dGVyV2lkdGggbWV0aG9kc1xualF1ZXJ5LmVhY2goIHsgSGVpZ2h0OiBcImhlaWdodFwiLCBXaWR0aDogXCJ3aWR0aFwiIH0sIGZ1bmN0aW9uKCBuYW1lLCB0eXBlICkge1xuXHRqUXVlcnkuZWFjaCgge1xuXHRcdHBhZGRpbmc6IFwiaW5uZXJcIiArIG5hbWUsXG5cdFx0Y29udGVudDogdHlwZSxcblx0XHRcIlwiOiBcIm91dGVyXCIgKyBuYW1lXG5cdH0sIGZ1bmN0aW9uKCBkZWZhdWx0RXh0cmEsIGZ1bmNOYW1lICkge1xuXG5cdFx0Ly8gTWFyZ2luIGlzIG9ubHkgZm9yIG91dGVySGVpZ2h0LCBvdXRlcldpZHRoXG5cdFx0alF1ZXJ5LmZuWyBmdW5jTmFtZSBdID0gZnVuY3Rpb24oIG1hcmdpbiwgdmFsdWUgKSB7XG5cdFx0XHR2YXIgY2hhaW5hYmxlID0gYXJndW1lbnRzLmxlbmd0aCAmJiAoIGRlZmF1bHRFeHRyYSB8fCB0eXBlb2YgbWFyZ2luICE9PSBcImJvb2xlYW5cIiApLFxuXHRcdFx0XHRleHRyYSA9IGRlZmF1bHRFeHRyYSB8fCAoIG1hcmdpbiA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gdHJ1ZSA/IFwibWFyZ2luXCIgOiBcImJvcmRlclwiICk7XG5cblx0XHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCB2YWx1ZSApIHtcblx0XHRcdFx0dmFyIGRvYztcblxuXHRcdFx0XHRpZiAoIGlzV2luZG93KCBlbGVtICkgKSB7XG5cblx0XHRcdFx0XHQvLyAkKCB3aW5kb3cgKS5vdXRlcldpZHRoL0hlaWdodCByZXR1cm4gdy9oIGluY2x1ZGluZyBzY3JvbGxiYXJzIChnaC0xNzI5KVxuXHRcdFx0XHRcdHJldHVybiBmdW5jTmFtZS5pbmRleE9mKCBcIm91dGVyXCIgKSA9PT0gMCA/XG5cdFx0XHRcdFx0XHRlbGVtWyBcImlubmVyXCIgKyBuYW1lIF0gOlxuXHRcdFx0XHRcdFx0ZWxlbS5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbIFwiY2xpZW50XCIgKyBuYW1lIF07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBHZXQgZG9jdW1lbnQgd2lkdGggb3IgaGVpZ2h0XG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0XHRkb2MgPSBlbGVtLmRvY3VtZW50RWxlbWVudDtcblxuXHRcdFx0XHRcdC8vIEVpdGhlciBzY3JvbGxbV2lkdGgvSGVpZ2h0XSBvciBvZmZzZXRbV2lkdGgvSGVpZ2h0XSBvciBjbGllbnRbV2lkdGgvSGVpZ2h0XSxcblx0XHRcdFx0XHQvLyB3aGljaGV2ZXIgaXMgZ3JlYXRlc3Rcblx0XHRcdFx0XHRyZXR1cm4gTWF0aC5tYXgoXG5cdFx0XHRcdFx0XHRlbGVtLmJvZHlbIFwic2Nyb2xsXCIgKyBuYW1lIF0sIGRvY1sgXCJzY3JvbGxcIiArIG5hbWUgXSxcblx0XHRcdFx0XHRcdGVsZW0uYm9keVsgXCJvZmZzZXRcIiArIG5hbWUgXSwgZG9jWyBcIm9mZnNldFwiICsgbmFtZSBdLFxuXHRcdFx0XHRcdFx0ZG9jWyBcImNsaWVudFwiICsgbmFtZSBdXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID9cblxuXHRcdFx0XHRcdC8vIEdldCB3aWR0aCBvciBoZWlnaHQgb24gdGhlIGVsZW1lbnQsIHJlcXVlc3RpbmcgYnV0IG5vdCBmb3JjaW5nIHBhcnNlRmxvYXRcblx0XHRcdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCB0eXBlLCBleHRyYSApIDpcblxuXHRcdFx0XHRcdC8vIFNldCB3aWR0aCBvciBoZWlnaHQgb24gdGhlIGVsZW1lbnRcblx0XHRcdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHR5cGUsIHZhbHVlLCBleHRyYSApO1xuXHRcdFx0fSwgdHlwZSwgY2hhaW5hYmxlID8gbWFyZ2luIDogdW5kZWZpbmVkLCBjaGFpbmFibGUgKTtcblx0XHR9O1xuXHR9ICk7XG59ICk7XG5cblxualF1ZXJ5LmVhY2goIFtcblx0XCJhamF4U3RhcnRcIixcblx0XCJhamF4U3RvcFwiLFxuXHRcImFqYXhDb21wbGV0ZVwiLFxuXHRcImFqYXhFcnJvclwiLFxuXHRcImFqYXhTdWNjZXNzXCIsXG5cdFwiYWpheFNlbmRcIlxuXSwgZnVuY3Rpb24oIF9pLCB0eXBlICkge1xuXHRqUXVlcnkuZm5bIHR5cGUgXSA9IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZSwgZm4gKTtcblx0fTtcbn0gKTtcblxuXG5cblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdGJpbmQ6IGZ1bmN0aW9uKCB0eXBlcywgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub24oIHR5cGVzLCBudWxsLCBkYXRhLCBmbiApO1xuXHR9LFxuXHR1bmJpbmQ6IGZ1bmN0aW9uKCB0eXBlcywgZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub2ZmKCB0eXBlcywgbnVsbCwgZm4gKTtcblx0fSxcblxuXHRkZWxlZ2F0ZTogZnVuY3Rpb24oIHNlbGVjdG9yLCB0eXBlcywgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKTtcblx0fSxcblx0dW5kZWxlZ2F0ZTogZnVuY3Rpb24oIHNlbGVjdG9yLCB0eXBlcywgZm4gKSB7XG5cblx0XHQvLyAoIG5hbWVzcGFjZSApIG9yICggc2VsZWN0b3IsIHR5cGVzIFssIGZuXSApXG5cdFx0cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgP1xuXHRcdFx0dGhpcy5vZmYoIHNlbGVjdG9yLCBcIioqXCIgKSA6XG5cdFx0XHR0aGlzLm9mZiggdHlwZXMsIHNlbGVjdG9yIHx8IFwiKipcIiwgZm4gKTtcblx0fSxcblxuXHRob3ZlcjogZnVuY3Rpb24oIGZuT3ZlciwgZm5PdXQgKSB7XG5cdFx0cmV0dXJuIHRoaXMubW91c2VlbnRlciggZm5PdmVyICkubW91c2VsZWF2ZSggZm5PdXQgfHwgZm5PdmVyICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goXG5cdCggXCJibHVyIGZvY3VzIGZvY3VzaW4gZm9jdXNvdXQgcmVzaXplIHNjcm9sbCBjbGljayBkYmxjbGljayBcIiArXG5cdFwibW91c2Vkb3duIG1vdXNldXAgbW91c2Vtb3ZlIG1vdXNlb3ZlciBtb3VzZW91dCBtb3VzZWVudGVyIG1vdXNlbGVhdmUgXCIgK1xuXHRcImNoYW5nZSBzZWxlY3Qgc3VibWl0IGtleWRvd24ga2V5cHJlc3Mga2V5dXAgY29udGV4dG1lbnVcIiApLnNwbGl0KCBcIiBcIiApLFxuXHRmdW5jdGlvbiggX2ksIG5hbWUgKSB7XG5cblx0XHQvLyBIYW5kbGUgZXZlbnQgYmluZGluZ1xuXHRcdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIGRhdGEsIGZuICkge1xuXHRcdFx0cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPiAwID9cblx0XHRcdFx0dGhpcy5vbiggbmFtZSwgbnVsbCwgZGF0YSwgZm4gKSA6XG5cdFx0XHRcdHRoaXMudHJpZ2dlciggbmFtZSApO1xuXHRcdH07XG5cdH1cbik7XG5cblxuXG5cbi8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seVxuLy8gTWFrZSBzdXJlIHdlIHRyaW0gQk9NIGFuZCBOQlNQXG52YXIgcnRyaW0gPSAvXltcXHNcXHVGRUZGXFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2c7XG5cbi8vIEJpbmQgYSBmdW5jdGlvbiB0byBhIGNvbnRleHQsIG9wdGlvbmFsbHkgcGFydGlhbGx5IGFwcGx5aW5nIGFueVxuLy8gYXJndW1lbnRzLlxuLy8galF1ZXJ5LnByb3h5IGlzIGRlcHJlY2F0ZWQgdG8gcHJvbW90ZSBzdGFuZGFyZHMgKHNwZWNpZmljYWxseSBGdW5jdGlvbiNiaW5kKVxuLy8gSG93ZXZlciwgaXQgaXMgbm90IHNsYXRlZCBmb3IgcmVtb3ZhbCBhbnkgdGltZSBzb29uXG5qUXVlcnkucHJveHkgPSBmdW5jdGlvbiggZm4sIGNvbnRleHQgKSB7XG5cdHZhciB0bXAsIGFyZ3MsIHByb3h5O1xuXG5cdGlmICggdHlwZW9mIGNvbnRleHQgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0dG1wID0gZm5bIGNvbnRleHQgXTtcblx0XHRjb250ZXh0ID0gZm47XG5cdFx0Zm4gPSB0bXA7XG5cdH1cblxuXHQvLyBRdWljayBjaGVjayB0byBkZXRlcm1pbmUgaWYgdGFyZ2V0IGlzIGNhbGxhYmxlLCBpbiB0aGUgc3BlY1xuXHQvLyB0aGlzIHRocm93cyBhIFR5cGVFcnJvciwgYnV0IHdlIHdpbGwganVzdCByZXR1cm4gdW5kZWZpbmVkLlxuXHRpZiAoICFpc0Z1bmN0aW9uKCBmbiApICkge1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblxuXHQvLyBTaW11bGF0ZWQgYmluZFxuXHRhcmdzID0gc2xpY2UuY2FsbCggYXJndW1lbnRzLCAyICk7XG5cdHByb3h5ID0gZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGZuLmFwcGx5KCBjb250ZXh0IHx8IHRoaXMsIGFyZ3MuY29uY2F0KCBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSApICk7XG5cdH07XG5cblx0Ly8gU2V0IHRoZSBndWlkIG9mIHVuaXF1ZSBoYW5kbGVyIHRvIHRoZSBzYW1lIG9mIG9yaWdpbmFsIGhhbmRsZXIsIHNvIGl0IGNhbiBiZSByZW1vdmVkXG5cdHByb3h5Lmd1aWQgPSBmbi5ndWlkID0gZm4uZ3VpZCB8fCBqUXVlcnkuZ3VpZCsrO1xuXG5cdHJldHVybiBwcm94eTtcbn07XG5cbmpRdWVyeS5ob2xkUmVhZHkgPSBmdW5jdGlvbiggaG9sZCApIHtcblx0aWYgKCBob2xkICkge1xuXHRcdGpRdWVyeS5yZWFkeVdhaXQrKztcblx0fSBlbHNlIHtcblx0XHRqUXVlcnkucmVhZHkoIHRydWUgKTtcblx0fVxufTtcbmpRdWVyeS5pc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcbmpRdWVyeS5wYXJzZUpTT04gPSBKU09OLnBhcnNlO1xualF1ZXJ5Lm5vZGVOYW1lID0gbm9kZU5hbWU7XG5qUXVlcnkuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5qUXVlcnkuaXNXaW5kb3cgPSBpc1dpbmRvdztcbmpRdWVyeS5jYW1lbENhc2UgPSBjYW1lbENhc2U7XG5qUXVlcnkudHlwZSA9IHRvVHlwZTtcblxualF1ZXJ5Lm5vdyA9IERhdGUubm93O1xuXG5qUXVlcnkuaXNOdW1lcmljID0gZnVuY3Rpb24oIG9iaiApIHtcblxuXHQvLyBBcyBvZiBqUXVlcnkgMy4wLCBpc051bWVyaWMgaXMgbGltaXRlZCB0b1xuXHQvLyBzdHJpbmdzIGFuZCBudW1iZXJzIChwcmltaXRpdmVzIG9yIG9iamVjdHMpXG5cdC8vIHRoYXQgY2FuIGJlIGNvZXJjZWQgdG8gZmluaXRlIG51bWJlcnMgKGdoLTI2NjIpXG5cdHZhciB0eXBlID0galF1ZXJ5LnR5cGUoIG9iaiApO1xuXHRyZXR1cm4gKCB0eXBlID09PSBcIm51bWJlclwiIHx8IHR5cGUgPT09IFwic3RyaW5nXCIgKSAmJlxuXG5cdFx0Ly8gcGFyc2VGbG9hdCBOYU5zIG51bWVyaWMtY2FzdCBmYWxzZSBwb3NpdGl2ZXMgKFwiXCIpXG5cdFx0Ly8gLi4uYnV0IG1pc2ludGVycHJldHMgbGVhZGluZy1udW1iZXIgc3RyaW5ncywgcGFydGljdWxhcmx5IGhleCBsaXRlcmFscyAoXCIweC4uLlwiKVxuXHRcdC8vIHN1YnRyYWN0aW9uIGZvcmNlcyBpbmZpbml0aWVzIHRvIE5hTlxuXHRcdCFpc05hTiggb2JqIC0gcGFyc2VGbG9hdCggb2JqICkgKTtcbn07XG5cbmpRdWVyeS50cmltID0gZnVuY3Rpb24oIHRleHQgKSB7XG5cdHJldHVybiB0ZXh0ID09IG51bGwgP1xuXHRcdFwiXCIgOlxuXHRcdCggdGV4dCArIFwiXCIgKS5yZXBsYWNlKCBydHJpbSwgXCJcIiApO1xufTtcblxuXG5cbi8vIFJlZ2lzdGVyIGFzIGEgbmFtZWQgQU1EIG1vZHVsZSwgc2luY2UgalF1ZXJ5IGNhbiBiZSBjb25jYXRlbmF0ZWQgd2l0aCBvdGhlclxuLy8gZmlsZXMgdGhhdCBtYXkgdXNlIGRlZmluZSwgYnV0IG5vdCB2aWEgYSBwcm9wZXIgY29uY2F0ZW5hdGlvbiBzY3JpcHQgdGhhdFxuLy8gdW5kZXJzdGFuZHMgYW5vbnltb3VzIEFNRCBtb2R1bGVzLiBBIG5hbWVkIEFNRCBpcyBzYWZlc3QgYW5kIG1vc3Qgcm9idXN0XG4vLyB3YXkgdG8gcmVnaXN0ZXIuIExvd2VyY2FzZSBqcXVlcnkgaXMgdXNlZCBiZWNhdXNlIEFNRCBtb2R1bGUgbmFtZXMgYXJlXG4vLyBkZXJpdmVkIGZyb20gZmlsZSBuYW1lcywgYW5kIGpRdWVyeSBpcyBub3JtYWxseSBkZWxpdmVyZWQgaW4gYSBsb3dlcmNhc2Vcbi8vIGZpbGUgbmFtZS4gRG8gdGhpcyBhZnRlciBjcmVhdGluZyB0aGUgZ2xvYmFsIHNvIHRoYXQgaWYgYW4gQU1EIG1vZHVsZSB3YW50c1xuLy8gdG8gY2FsbCBub0NvbmZsaWN0IHRvIGhpZGUgdGhpcyB2ZXJzaW9uIG9mIGpRdWVyeSwgaXQgd2lsbCB3b3JrLlxuXG4vLyBOb3RlIHRoYXQgZm9yIG1heGltdW0gcG9ydGFiaWxpdHksIGxpYnJhcmllcyB0aGF0IGFyZSBub3QgalF1ZXJ5IHNob3VsZFxuLy8gZGVjbGFyZSB0aGVtc2VsdmVzIGFzIGFub255bW91cyBtb2R1bGVzLCBhbmQgYXZvaWQgc2V0dGluZyBhIGdsb2JhbCBpZiBhblxuLy8gQU1EIGxvYWRlciBpcyBwcmVzZW50LiBqUXVlcnkgaXMgYSBzcGVjaWFsIGNhc2UuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWVcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qcmJ1cmtlL3JlcXVpcmVqcy93aWtpL1VwZGF0aW5nLWV4aXN0aW5nLWxpYnJhcmllcyN3aWtpLWFub25cblxuaWYgKCB0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCApIHtcblx0ZGVmaW5lKCBcImpxdWVyeVwiLCBbXSwgZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGpRdWVyeTtcblx0fSApO1xufVxuXG5cblxuXG52YXJcblxuXHQvLyBNYXAgb3ZlciBqUXVlcnkgaW4gY2FzZSBvZiBvdmVyd3JpdGVcblx0X2pRdWVyeSA9IHdpbmRvdy5qUXVlcnksXG5cblx0Ly8gTWFwIG92ZXIgdGhlICQgaW4gY2FzZSBvZiBvdmVyd3JpdGVcblx0XyQgPSB3aW5kb3cuJDtcblxualF1ZXJ5Lm5vQ29uZmxpY3QgPSBmdW5jdGlvbiggZGVlcCApIHtcblx0aWYgKCB3aW5kb3cuJCA9PT0galF1ZXJ5ICkge1xuXHRcdHdpbmRvdy4kID0gXyQ7XG5cdH1cblxuXHRpZiAoIGRlZXAgJiYgd2luZG93LmpRdWVyeSA9PT0galF1ZXJ5ICkge1xuXHRcdHdpbmRvdy5qUXVlcnkgPSBfalF1ZXJ5O1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeTtcbn07XG5cbi8vIEV4cG9zZSBqUXVlcnkgYW5kICQgaWRlbnRpZmllcnMsIGV2ZW4gaW4gQU1EXG4vLyAoIzcxMDIjY29tbWVudDoxMCwgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9qcXVlcnkvcHVsbC81NTcpXG4vLyBhbmQgQ29tbW9uSlMgZm9yIGJyb3dzZXIgZW11bGF0b3JzICgjMTM1NjYpXG5pZiAoIHR5cGVvZiBub0dsb2JhbCA9PT0gXCJ1bmRlZmluZWRcIiApIHtcblx0d2luZG93LmpRdWVyeSA9IHdpbmRvdy4kID0galF1ZXJ5O1xufVxuXG5cblxuXG5yZXR1cm4galF1ZXJ5O1xufSApO1xuIiwiOyhmdW5jdGlvbiAoc2F4KSB7IC8vIHdyYXBwZXIgZm9yIG5vbi1ub2RlIGVudnNcbiAgc2F4LnBhcnNlciA9IGZ1bmN0aW9uIChzdHJpY3QsIG9wdCkgeyByZXR1cm4gbmV3IFNBWFBhcnNlcihzdHJpY3QsIG9wdCkgfVxuICBzYXguU0FYUGFyc2VyID0gU0FYUGFyc2VyXG4gIHNheC5TQVhTdHJlYW0gPSBTQVhTdHJlYW1cbiAgc2F4LmNyZWF0ZVN0cmVhbSA9IGNyZWF0ZVN0cmVhbVxuXG4gIC8vIFdoZW4gd2UgcGFzcyB0aGUgTUFYX0JVRkZFUl9MRU5HVEggcG9zaXRpb24sIHN0YXJ0IGNoZWNraW5nIGZvciBidWZmZXIgb3ZlcnJ1bnMuXG4gIC8vIFdoZW4gd2UgY2hlY2ssIHNjaGVkdWxlIHRoZSBuZXh0IGNoZWNrIGZvciBNQVhfQlVGRkVSX0xFTkdUSCAtIChtYXgoYnVmZmVyIGxlbmd0aHMpKSxcbiAgLy8gc2luY2UgdGhhdCdzIHRoZSBlYXJsaWVzdCB0aGF0IGEgYnVmZmVyIG92ZXJydW4gY291bGQgb2NjdXIuICBUaGlzIHdheSwgY2hlY2tzIGFyZVxuICAvLyBhcyByYXJlIGFzIHJlcXVpcmVkLCBidXQgYXMgb2Z0ZW4gYXMgbmVjZXNzYXJ5IHRvIGVuc3VyZSBuZXZlciBjcm9zc2luZyB0aGlzIGJvdW5kLlxuICAvLyBGdXJ0aGVybW9yZSwgYnVmZmVycyBhcmUgb25seSB0ZXN0ZWQgYXQgbW9zdCBvbmNlIHBlciB3cml0ZSgpLCBzbyBwYXNzaW5nIGEgdmVyeVxuICAvLyBsYXJnZSBzdHJpbmcgaW50byB3cml0ZSgpIG1pZ2h0IGhhdmUgdW5kZXNpcmFibGUgZWZmZWN0cywgYnV0IHRoaXMgaXMgbWFuYWdlYWJsZSBieVxuICAvLyB0aGUgY2FsbGVyLCBzbyBpdCBpcyBhc3N1bWVkIHRvIGJlIHNhZmUuICBUaHVzLCBhIGNhbGwgdG8gd3JpdGUoKSBtYXksIGluIHRoZSBleHRyZW1lXG4gIC8vIGVkZ2UgY2FzZSwgcmVzdWx0IGluIGNyZWF0aW5nIGF0IG1vc3Qgb25lIGNvbXBsZXRlIGNvcHkgb2YgdGhlIHN0cmluZyBwYXNzZWQgaW4uXG4gIC8vIFNldCB0byBJbmZpbml0eSB0byBoYXZlIHVubGltaXRlZCBidWZmZXJzLlxuICBzYXguTUFYX0JVRkZFUl9MRU5HVEggPSA2NCAqIDEwMjRcblxuICB2YXIgYnVmZmVycyA9IFtcbiAgICAnY29tbWVudCcsICdzZ21sRGVjbCcsICd0ZXh0Tm9kZScsICd0YWdOYW1lJywgJ2RvY3R5cGUnLFxuICAgICdwcm9jSW5zdE5hbWUnLCAncHJvY0luc3RCb2R5JywgJ2VudGl0eScsICdhdHRyaWJOYW1lJyxcbiAgICAnYXR0cmliVmFsdWUnLCAnY2RhdGEnLCAnc2NyaXB0J1xuICBdXG5cbiAgc2F4LkVWRU5UUyA9IFtcbiAgICAndGV4dCcsXG4gICAgJ3Byb2Nlc3NpbmdpbnN0cnVjdGlvbicsXG4gICAgJ3NnbWxkZWNsYXJhdGlvbicsXG4gICAgJ2RvY3R5cGUnLFxuICAgICdjb21tZW50JyxcbiAgICAnb3BlbnRhZ3N0YXJ0JyxcbiAgICAnYXR0cmlidXRlJyxcbiAgICAnb3BlbnRhZycsXG4gICAgJ2Nsb3NldGFnJyxcbiAgICAnb3BlbmNkYXRhJyxcbiAgICAnY2RhdGEnLFxuICAgICdjbG9zZWNkYXRhJyxcbiAgICAnZXJyb3InLFxuICAgICdlbmQnLFxuICAgICdyZWFkeScsXG4gICAgJ3NjcmlwdCcsXG4gICAgJ29wZW5uYW1lc3BhY2UnLFxuICAgICdjbG9zZW5hbWVzcGFjZSdcbiAgXVxuXG4gIGZ1bmN0aW9uIFNBWFBhcnNlciAoc3RyaWN0LCBvcHQpIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0FYUGFyc2VyKSkge1xuICAgICAgcmV0dXJuIG5ldyBTQVhQYXJzZXIoc3RyaWN0LCBvcHQpXG4gICAgfVxuXG4gICAgdmFyIHBhcnNlciA9IHRoaXNcbiAgICBjbGVhckJ1ZmZlcnMocGFyc2VyKVxuICAgIHBhcnNlci5xID0gcGFyc2VyLmMgPSAnJ1xuICAgIHBhcnNlci5idWZmZXJDaGVja1Bvc2l0aW9uID0gc2F4Lk1BWF9CVUZGRVJfTEVOR1RIXG4gICAgcGFyc2VyLm9wdCA9IG9wdCB8fCB7fVxuICAgIHBhcnNlci5vcHQubG93ZXJjYXNlID0gcGFyc2VyLm9wdC5sb3dlcmNhc2UgfHwgcGFyc2VyLm9wdC5sb3dlcmNhc2V0YWdzXG4gICAgcGFyc2VyLmxvb3NlQ2FzZSA9IHBhcnNlci5vcHQubG93ZXJjYXNlID8gJ3RvTG93ZXJDYXNlJyA6ICd0b1VwcGVyQ2FzZSdcbiAgICBwYXJzZXIudGFncyA9IFtdXG4gICAgcGFyc2VyLmNsb3NlZCA9IHBhcnNlci5jbG9zZWRSb290ID0gcGFyc2VyLnNhd1Jvb3QgPSBmYWxzZVxuICAgIHBhcnNlci50YWcgPSBwYXJzZXIuZXJyb3IgPSBudWxsXG4gICAgcGFyc2VyLnN0cmljdCA9ICEhc3RyaWN0XG4gICAgcGFyc2VyLm5vc2NyaXB0ID0gISEoc3RyaWN0IHx8IHBhcnNlci5vcHQubm9zY3JpcHQpXG4gICAgcGFyc2VyLnN0YXRlID0gUy5CRUdJTlxuICAgIHBhcnNlci5zdHJpY3RFbnRpdGllcyA9IHBhcnNlci5vcHQuc3RyaWN0RW50aXRpZXNcbiAgICBwYXJzZXIuRU5USVRJRVMgPSBwYXJzZXIuc3RyaWN0RW50aXRpZXMgPyBPYmplY3QuY3JlYXRlKHNheC5YTUxfRU5USVRJRVMpIDogT2JqZWN0LmNyZWF0ZShzYXguRU5USVRJRVMpXG4gICAgcGFyc2VyLmF0dHJpYkxpc3QgPSBbXVxuXG4gICAgLy8gbmFtZXNwYWNlcyBmb3JtIGEgcHJvdG90eXBlIGNoYWluLlxuICAgIC8vIGl0IGFsd2F5cyBwb2ludHMgYXQgdGhlIGN1cnJlbnQgdGFnLFxuICAgIC8vIHdoaWNoIHByb3RvcyB0byBpdHMgcGFyZW50IHRhZy5cbiAgICBpZiAocGFyc2VyLm9wdC54bWxucykge1xuICAgICAgcGFyc2VyLm5zID0gT2JqZWN0LmNyZWF0ZShyb290TlMpXG4gICAgfVxuXG4gICAgLy8gbW9zdGx5IGp1c3QgZm9yIGVycm9yIHJlcG9ydGluZ1xuICAgIHBhcnNlci50cmFja1Bvc2l0aW9uID0gcGFyc2VyLm9wdC5wb3NpdGlvbiAhPT0gZmFsc2VcbiAgICBpZiAocGFyc2VyLnRyYWNrUG9zaXRpb24pIHtcbiAgICAgIHBhcnNlci5wb3NpdGlvbiA9IHBhcnNlci5saW5lID0gcGFyc2VyLmNvbHVtbiA9IDBcbiAgICB9XG4gICAgZW1pdChwYXJzZXIsICdvbnJlYWR5JylcbiAgfVxuXG4gIGlmICghT2JqZWN0LmNyZWF0ZSkge1xuICAgIE9iamVjdC5jcmVhdGUgPSBmdW5jdGlvbiAobykge1xuICAgICAgZnVuY3Rpb24gRiAoKSB7fVxuICAgICAgRi5wcm90b3R5cGUgPSBvXG4gICAgICB2YXIgbmV3ZiA9IG5ldyBGKClcbiAgICAgIHJldHVybiBuZXdmXG4gICAgfVxuICB9XG5cbiAgaWYgKCFPYmplY3Qua2V5cykge1xuICAgIE9iamVjdC5rZXlzID0gZnVuY3Rpb24gKG8pIHtcbiAgICAgIHZhciBhID0gW11cbiAgICAgIGZvciAodmFyIGkgaW4gbykgaWYgKG8uaGFzT3duUHJvcGVydHkoaSkpIGEucHVzaChpKVxuICAgICAgcmV0dXJuIGFcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjaGVja0J1ZmZlckxlbmd0aCAocGFyc2VyKSB7XG4gICAgdmFyIG1heEFsbG93ZWQgPSBNYXRoLm1heChzYXguTUFYX0JVRkZFUl9MRU5HVEgsIDEwKVxuICAgIHZhciBtYXhBY3R1YWwgPSAwXG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBidWZmZXJzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdmFyIGxlbiA9IHBhcnNlcltidWZmZXJzW2ldXS5sZW5ndGhcbiAgICAgIGlmIChsZW4gPiBtYXhBbGxvd2VkKSB7XG4gICAgICAgIC8vIFRleHQvY2RhdGEgbm9kZXMgY2FuIGdldCBiaWcsIGFuZCBzaW5jZSB0aGV5J3JlIGJ1ZmZlcmVkLFxuICAgICAgICAvLyB3ZSBjYW4gZ2V0IGhlcmUgdW5kZXIgbm9ybWFsIGNvbmRpdGlvbnMuXG4gICAgICAgIC8vIEF2b2lkIGlzc3VlcyBieSBlbWl0dGluZyB0aGUgdGV4dCBub2RlIG5vdyxcbiAgICAgICAgLy8gc28gYXQgbGVhc3QgaXQgd29uJ3QgZ2V0IGFueSBiaWdnZXIuXG4gICAgICAgIHN3aXRjaCAoYnVmZmVyc1tpXSkge1xuICAgICAgICAgIGNhc2UgJ3RleHROb2RlJzpcbiAgICAgICAgICAgIGNsb3NlVGV4dChwYXJzZXIpXG4gICAgICAgICAgICBicmVha1xuXG4gICAgICAgICAgY2FzZSAnY2RhdGEnOlxuICAgICAgICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25jZGF0YScsIHBhcnNlci5jZGF0YSlcbiAgICAgICAgICAgIHBhcnNlci5jZGF0YSA9ICcnXG4gICAgICAgICAgICBicmVha1xuXG4gICAgICAgICAgY2FzZSAnc2NyaXB0JzpcbiAgICAgICAgICAgIGVtaXROb2RlKHBhcnNlciwgJ29uc2NyaXB0JywgcGFyc2VyLnNjcmlwdClcbiAgICAgICAgICAgIHBhcnNlci5zY3JpcHQgPSAnJ1xuICAgICAgICAgICAgYnJlYWtcblxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBlcnJvcihwYXJzZXIsICdNYXggYnVmZmVyIGxlbmd0aCBleGNlZWRlZDogJyArIGJ1ZmZlcnNbaV0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG1heEFjdHVhbCA9IE1hdGgubWF4KG1heEFjdHVhbCwgbGVuKVxuICAgIH1cbiAgICAvLyBzY2hlZHVsZSB0aGUgbmV4dCBjaGVjayBmb3IgdGhlIGVhcmxpZXN0IHBvc3NpYmxlIGJ1ZmZlciBvdmVycnVuLlxuICAgIHZhciBtID0gc2F4Lk1BWF9CVUZGRVJfTEVOR1RIIC0gbWF4QWN0dWFsXG4gICAgcGFyc2VyLmJ1ZmZlckNoZWNrUG9zaXRpb24gPSBtICsgcGFyc2VyLnBvc2l0aW9uXG4gIH1cblxuICBmdW5jdGlvbiBjbGVhckJ1ZmZlcnMgKHBhcnNlcikge1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gYnVmZmVycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHBhcnNlcltidWZmZXJzW2ldXSA9ICcnXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZmx1c2hCdWZmZXJzIChwYXJzZXIpIHtcbiAgICBjbG9zZVRleHQocGFyc2VyKVxuICAgIGlmIChwYXJzZXIuY2RhdGEgIT09ICcnKSB7XG4gICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbmNkYXRhJywgcGFyc2VyLmNkYXRhKVxuICAgICAgcGFyc2VyLmNkYXRhID0gJydcbiAgICB9XG4gICAgaWYgKHBhcnNlci5zY3JpcHQgIT09ICcnKSB7XG4gICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbnNjcmlwdCcsIHBhcnNlci5zY3JpcHQpXG4gICAgICBwYXJzZXIuc2NyaXB0ID0gJydcbiAgICB9XG4gIH1cblxuICBTQVhQYXJzZXIucHJvdG90eXBlID0ge1xuICAgIGVuZDogZnVuY3Rpb24gKCkgeyBlbmQodGhpcykgfSxcbiAgICB3cml0ZTogd3JpdGUsXG4gICAgcmVzdW1lOiBmdW5jdGlvbiAoKSB7IHRoaXMuZXJyb3IgPSBudWxsOyByZXR1cm4gdGhpcyB9LFxuICAgIGNsb3NlOiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLndyaXRlKG51bGwpIH0sXG4gICAgZmx1c2g6IGZ1bmN0aW9uICgpIHsgZmx1c2hCdWZmZXJzKHRoaXMpIH1cbiAgfVxuXG4gIHZhciBTdHJlYW1cbiAgdHJ5IHtcbiAgICBTdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKS5TdHJlYW1cbiAgfSBjYXRjaCAoZXgpIHtcbiAgICBTdHJlYW0gPSBmdW5jdGlvbiAoKSB7fVxuICB9XG5cbiAgdmFyIHN0cmVhbVdyYXBzID0gc2F4LkVWRU5UUy5maWx0ZXIoZnVuY3Rpb24gKGV2KSB7XG4gICAgcmV0dXJuIGV2ICE9PSAnZXJyb3InICYmIGV2ICE9PSAnZW5kJ1xuICB9KVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVN0cmVhbSAoc3RyaWN0LCBvcHQpIHtcbiAgICByZXR1cm4gbmV3IFNBWFN0cmVhbShzdHJpY3QsIG9wdClcbiAgfVxuXG4gIGZ1bmN0aW9uIFNBWFN0cmVhbSAoc3RyaWN0LCBvcHQpIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0FYU3RyZWFtKSkge1xuICAgICAgcmV0dXJuIG5ldyBTQVhTdHJlYW0oc3RyaWN0LCBvcHQpXG4gICAgfVxuXG4gICAgU3RyZWFtLmFwcGx5KHRoaXMpXG5cbiAgICB0aGlzLl9wYXJzZXIgPSBuZXcgU0FYUGFyc2VyKHN0cmljdCwgb3B0KVxuICAgIHRoaXMud3JpdGFibGUgPSB0cnVlXG4gICAgdGhpcy5yZWFkYWJsZSA9IHRydWVcblxuICAgIHZhciBtZSA9IHRoaXNcblxuICAgIHRoaXMuX3BhcnNlci5vbmVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIG1lLmVtaXQoJ2VuZCcpXG4gICAgfVxuXG4gICAgdGhpcy5fcGFyc2VyLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXIpIHtcbiAgICAgIG1lLmVtaXQoJ2Vycm9yJywgZXIpXG5cbiAgICAgIC8vIGlmIGRpZG4ndCB0aHJvdywgdGhlbiBtZWFucyBlcnJvciB3YXMgaGFuZGxlZC5cbiAgICAgIC8vIGdvIGFoZWFkIGFuZCBjbGVhciBlcnJvciwgc28gd2UgY2FuIHdyaXRlIGFnYWluLlxuICAgICAgbWUuX3BhcnNlci5lcnJvciA9IG51bGxcbiAgICB9XG5cbiAgICB0aGlzLl9kZWNvZGVyID0gbnVsbFxuXG4gICAgc3RyZWFtV3JhcHMuZm9yRWFjaChmdW5jdGlvbiAoZXYpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtZSwgJ29uJyArIGV2LCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBtZS5fcGFyc2VyWydvbicgKyBldl1cbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoaCkge1xuICAgICAgICAgIGlmICghaCkge1xuICAgICAgICAgICAgbWUucmVtb3ZlQWxsTGlzdGVuZXJzKGV2KVxuICAgICAgICAgICAgbWUuX3BhcnNlclsnb24nICsgZXZdID0gaFxuICAgICAgICAgICAgcmV0dXJuIGhcbiAgICAgICAgICB9XG4gICAgICAgICAgbWUub24oZXYsIGgpXG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2VcbiAgICAgIH0pXG4gICAgfSlcbiAgfVxuXG4gIFNBWFN0cmVhbS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgdmFsdWU6IFNBWFN0cmVhbVxuICAgIH1cbiAgfSlcblxuICBTQVhTdHJlYW0ucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBpZiAodHlwZW9mIEJ1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgdHlwZW9mIEJ1ZmZlci5pc0J1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgQnVmZmVyLmlzQnVmZmVyKGRhdGEpKSB7XG4gICAgICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICAgICAgdmFyIFNEID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyXG4gICAgICAgIHRoaXMuX2RlY29kZXIgPSBuZXcgU0QoJ3V0ZjgnKVxuICAgICAgfVxuICAgICAgZGF0YSA9IHRoaXMuX2RlY29kZXIud3JpdGUoZGF0YSlcbiAgICB9XG5cbiAgICB0aGlzLl9wYXJzZXIud3JpdGUoZGF0YS50b1N0cmluZygpKVxuICAgIHRoaXMuZW1pdCgnZGF0YScsIGRhdGEpXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIFNBWFN0cmVhbS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkge1xuICAgICAgdGhpcy53cml0ZShjaHVuaylcbiAgICB9XG4gICAgdGhpcy5fcGFyc2VyLmVuZCgpXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIFNBWFN0cmVhbS5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXYsIGhhbmRsZXIpIHtcbiAgICB2YXIgbWUgPSB0aGlzXG4gICAgaWYgKCFtZS5fcGFyc2VyWydvbicgKyBldl0gJiYgc3RyZWFtV3JhcHMuaW5kZXhPZihldikgIT09IC0xKSB7XG4gICAgICBtZS5fcGFyc2VyWydvbicgKyBldl0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/IFthcmd1bWVudHNbMF1dIDogQXJyYXkuYXBwbHkobnVsbCwgYXJndW1lbnRzKVxuICAgICAgICBhcmdzLnNwbGljZSgwLCAwLCBldilcbiAgICAgICAgbWUuZW1pdC5hcHBseShtZSwgYXJncylcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gU3RyZWFtLnByb3RvdHlwZS5vbi5jYWxsKG1lLCBldiwgaGFuZGxlcilcbiAgfVxuXG4gIC8vIHRoaXMgcmVhbGx5IG5lZWRzIHRvIGJlIHJlcGxhY2VkIHdpdGggY2hhcmFjdGVyIGNsYXNzZXMuXG4gIC8vIFhNTCBhbGxvd3MgYWxsIG1hbm5lciBvZiByaWRpY3Vsb3VzIG51bWJlcnMgYW5kIGRpZ2l0cy5cbiAgdmFyIENEQVRBID0gJ1tDREFUQVsnXG4gIHZhciBET0NUWVBFID0gJ0RPQ1RZUEUnXG4gIHZhciBYTUxfTkFNRVNQQUNFID0gJ2h0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSdcbiAgdmFyIFhNTE5TX05BTUVTUEFDRSA9ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLydcbiAgdmFyIHJvb3ROUyA9IHsgeG1sOiBYTUxfTkFNRVNQQUNFLCB4bWxuczogWE1MTlNfTkFNRVNQQUNFIH1cblxuICAvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLyNOVC1OYW1lU3RhcnRDaGFyXG4gIC8vIFRoaXMgaW1wbGVtZW50YXRpb24gd29ya3Mgb24gc3RyaW5ncywgYSBzaW5nbGUgY2hhcmFjdGVyIGF0IGEgdGltZVxuICAvLyBhcyBzdWNoLCBpdCBjYW5ub3QgZXZlciBzdXBwb3J0IGFzdHJhbC1wbGFuZSBjaGFyYWN0ZXJzICgxMDAwMC1FRkZGRilcbiAgLy8gd2l0aG91dCBhIHNpZ25pZmljYW50IGJyZWFraW5nIGNoYW5nZSB0byBlaXRoZXIgdGhpcyAgcGFyc2VyLCBvciB0aGVcbiAgLy8gSmF2YVNjcmlwdCBsYW5ndWFnZS4gIEltcGxlbWVudGF0aW9uIG9mIGFuIGVtb2ppLWNhcGFibGUgeG1sIHBhcnNlclxuICAvLyBpcyBsZWZ0IGFzIGFuIGV4ZXJjaXNlIGZvciB0aGUgcmVhZGVyLlxuICB2YXIgbmFtZVN0YXJ0ID0gL1s6X0EtWmEtelxcdTAwQzAtXFx1MDBENlxcdTAwRDgtXFx1MDBGNlxcdTAwRjgtXFx1MDJGRlxcdTAzNzAtXFx1MDM3RFxcdTAzN0YtXFx1MUZGRlxcdTIwMEMtXFx1MjAwRFxcdTIwNzAtXFx1MjE4RlxcdTJDMDAtXFx1MkZFRlxcdTMwMDEtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZGRF0vXG5cbiAgdmFyIG5hbWVCb2R5ID0gL1s6X0EtWmEtelxcdTAwQzAtXFx1MDBENlxcdTAwRDgtXFx1MDBGNlxcdTAwRjgtXFx1MDJGRlxcdTAzNzAtXFx1MDM3RFxcdTAzN0YtXFx1MUZGRlxcdTIwMEMtXFx1MjAwRFxcdTIwNzAtXFx1MjE4RlxcdTJDMDAtXFx1MkZFRlxcdTMwMDEtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZGRFxcdTAwQjdcXHUwMzAwLVxcdTAzNkZcXHUyMDNGLVxcdTIwNDAuXFxkLV0vXG5cbiAgdmFyIGVudGl0eVN0YXJ0ID0gL1sjOl9BLVphLXpcXHUwMEMwLVxcdTAwRDZcXHUwMEQ4LVxcdTAwRjZcXHUwMEY4LVxcdTAyRkZcXHUwMzcwLVxcdTAzN0RcXHUwMzdGLVxcdTFGRkZcXHUyMDBDLVxcdTIwMERcXHUyMDcwLVxcdTIxOEZcXHUyQzAwLVxcdTJGRUZcXHUzMDAxLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRkRdL1xuICB2YXIgZW50aXR5Qm9keSA9IC9bIzpfQS1aYS16XFx1MDBDMC1cXHUwMEQ2XFx1MDBEOC1cXHUwMEY2XFx1MDBGOC1cXHUwMkZGXFx1MDM3MC1cXHUwMzdEXFx1MDM3Ri1cXHUxRkZGXFx1MjAwQy1cXHUyMDBEXFx1MjA3MC1cXHUyMThGXFx1MkMwMC1cXHUyRkVGXFx1MzAwMS1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkZEXFx1MDBCN1xcdTAzMDAtXFx1MDM2RlxcdTIwM0YtXFx1MjA0MC5cXGQtXS9cblxuICBmdW5jdGlvbiBpc1doaXRlc3BhY2UgKGMpIHtcbiAgICByZXR1cm4gYyA9PT0gJyAnIHx8IGMgPT09ICdcXG4nIHx8IGMgPT09ICdcXHInIHx8IGMgPT09ICdcXHQnXG4gIH1cblxuICBmdW5jdGlvbiBpc1F1b3RlIChjKSB7XG4gICAgcmV0dXJuIGMgPT09ICdcIicgfHwgYyA9PT0gJ1xcJydcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzQXR0cmliRW5kIChjKSB7XG4gICAgcmV0dXJuIGMgPT09ICc+JyB8fCBpc1doaXRlc3BhY2UoYylcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzTWF0Y2ggKHJlZ2V4LCBjKSB7XG4gICAgcmV0dXJuIHJlZ2V4LnRlc3QoYylcbiAgfVxuXG4gIGZ1bmN0aW9uIG5vdE1hdGNoIChyZWdleCwgYykge1xuICAgIHJldHVybiAhaXNNYXRjaChyZWdleCwgYylcbiAgfVxuXG4gIHZhciBTID0gMFxuICBzYXguU1RBVEUgPSB7XG4gICAgQkVHSU46IFMrKywgLy8gbGVhZGluZyBieXRlIG9yZGVyIG1hcmsgb3Igd2hpdGVzcGFjZVxuICAgIEJFR0lOX1dISVRFU1BBQ0U6IFMrKywgLy8gbGVhZGluZyB3aGl0ZXNwYWNlXG4gICAgVEVYVDogUysrLCAvLyBnZW5lcmFsIHN0dWZmXG4gICAgVEVYVF9FTlRJVFk6IFMrKywgLy8gJmFtcCBhbmQgc3VjaC5cbiAgICBPUEVOX1dBS0E6IFMrKywgLy8gPFxuICAgIFNHTUxfREVDTDogUysrLCAvLyA8IUJMQVJHXG4gICAgU0dNTF9ERUNMX1FVT1RFRDogUysrLCAvLyA8IUJMQVJHIGZvbyBcImJhclxuICAgIERPQ1RZUEU6IFMrKywgLy8gPCFET0NUWVBFXG4gICAgRE9DVFlQRV9RVU9URUQ6IFMrKywgLy8gPCFET0NUWVBFIFwiLy9ibGFoXG4gICAgRE9DVFlQRV9EVEQ6IFMrKywgLy8gPCFET0NUWVBFIFwiLy9ibGFoXCIgWyAuLi5cbiAgICBET0NUWVBFX0RURF9RVU9URUQ6IFMrKywgLy8gPCFET0NUWVBFIFwiLy9ibGFoXCIgWyBcImZvb1xuICAgIENPTU1FTlRfU1RBUlRJTkc6IFMrKywgLy8gPCEtXG4gICAgQ09NTUVOVDogUysrLCAvLyA8IS0tXG4gICAgQ09NTUVOVF9FTkRJTkc6IFMrKywgLy8gPCEtLSBibGFoIC1cbiAgICBDT01NRU5UX0VOREVEOiBTKyssIC8vIDwhLS0gYmxhaCAtLVxuICAgIENEQVRBOiBTKyssIC8vIDwhW0NEQVRBWyBzb21ldGhpbmdcbiAgICBDREFUQV9FTkRJTkc6IFMrKywgLy8gXVxuICAgIENEQVRBX0VORElOR18yOiBTKyssIC8vIF1dXG4gICAgUFJPQ19JTlNUOiBTKyssIC8vIDw/aGlcbiAgICBQUk9DX0lOU1RfQk9EWTogUysrLCAvLyA8P2hpIHRoZXJlXG4gICAgUFJPQ19JTlNUX0VORElORzogUysrLCAvLyA8P2hpIFwidGhlcmVcIiA/XG4gICAgT1BFTl9UQUc6IFMrKywgLy8gPHN0cm9uZ1xuICAgIE9QRU5fVEFHX1NMQVNIOiBTKyssIC8vIDxzdHJvbmcgL1xuICAgIEFUVFJJQjogUysrLCAvLyA8YVxuICAgIEFUVFJJQl9OQU1FOiBTKyssIC8vIDxhIGZvb1xuICAgIEFUVFJJQl9OQU1FX1NBV19XSElURTogUysrLCAvLyA8YSBmb28gX1xuICAgIEFUVFJJQl9WQUxVRTogUysrLCAvLyA8YSBmb289XG4gICAgQVRUUklCX1ZBTFVFX1FVT1RFRDogUysrLCAvLyA8YSBmb289XCJiYXJcbiAgICBBVFRSSUJfVkFMVUVfQ0xPU0VEOiBTKyssIC8vIDxhIGZvbz1cImJhclwiXG4gICAgQVRUUklCX1ZBTFVFX1VOUVVPVEVEOiBTKyssIC8vIDxhIGZvbz1iYXJcbiAgICBBVFRSSUJfVkFMVUVfRU5USVRZX1E6IFMrKywgLy8gPGZvbyBiYXI9XCImcXVvdDtcIlxuICAgIEFUVFJJQl9WQUxVRV9FTlRJVFlfVTogUysrLCAvLyA8Zm9vIGJhcj0mcXVvdFxuICAgIENMT1NFX1RBRzogUysrLCAvLyA8L2FcbiAgICBDTE9TRV9UQUdfU0FXX1dISVRFOiBTKyssIC8vIDwvYSAgID5cbiAgICBTQ1JJUFQ6IFMrKywgLy8gPHNjcmlwdD4gLi4uXG4gICAgU0NSSVBUX0VORElORzogUysrIC8vIDxzY3JpcHQ+IC4uLiA8XG4gIH1cblxuICBzYXguWE1MX0VOVElUSUVTID0ge1xuICAgICdhbXAnOiAnJicsXG4gICAgJ2d0JzogJz4nLFxuICAgICdsdCc6ICc8JyxcbiAgICAncXVvdCc6ICdcIicsXG4gICAgJ2Fwb3MnOiBcIidcIlxuICB9XG5cbiAgc2F4LkVOVElUSUVTID0ge1xuICAgICdhbXAnOiAnJicsXG4gICAgJ2d0JzogJz4nLFxuICAgICdsdCc6ICc8JyxcbiAgICAncXVvdCc6ICdcIicsXG4gICAgJ2Fwb3MnOiBcIidcIixcbiAgICAnQUVsaWcnOiAxOTgsXG4gICAgJ0FhY3V0ZSc6IDE5MyxcbiAgICAnQWNpcmMnOiAxOTQsXG4gICAgJ0FncmF2ZSc6IDE5MixcbiAgICAnQXJpbmcnOiAxOTcsXG4gICAgJ0F0aWxkZSc6IDE5NSxcbiAgICAnQXVtbCc6IDE5NixcbiAgICAnQ2NlZGlsJzogMTk5LFxuICAgICdFVEgnOiAyMDgsXG4gICAgJ0VhY3V0ZSc6IDIwMSxcbiAgICAnRWNpcmMnOiAyMDIsXG4gICAgJ0VncmF2ZSc6IDIwMCxcbiAgICAnRXVtbCc6IDIwMyxcbiAgICAnSWFjdXRlJzogMjA1LFxuICAgICdJY2lyYyc6IDIwNixcbiAgICAnSWdyYXZlJzogMjA0LFxuICAgICdJdW1sJzogMjA3LFxuICAgICdOdGlsZGUnOiAyMDksXG4gICAgJ09hY3V0ZSc6IDIxMSxcbiAgICAnT2NpcmMnOiAyMTIsXG4gICAgJ09ncmF2ZSc6IDIxMCxcbiAgICAnT3NsYXNoJzogMjE2LFxuICAgICdPdGlsZGUnOiAyMTMsXG4gICAgJ091bWwnOiAyMTQsXG4gICAgJ1RIT1JOJzogMjIyLFxuICAgICdVYWN1dGUnOiAyMTgsXG4gICAgJ1VjaXJjJzogMjE5LFxuICAgICdVZ3JhdmUnOiAyMTcsXG4gICAgJ1V1bWwnOiAyMjAsXG4gICAgJ1lhY3V0ZSc6IDIyMSxcbiAgICAnYWFjdXRlJzogMjI1LFxuICAgICdhY2lyYyc6IDIyNixcbiAgICAnYWVsaWcnOiAyMzAsXG4gICAgJ2FncmF2ZSc6IDIyNCxcbiAgICAnYXJpbmcnOiAyMjksXG4gICAgJ2F0aWxkZSc6IDIyNyxcbiAgICAnYXVtbCc6IDIyOCxcbiAgICAnY2NlZGlsJzogMjMxLFxuICAgICdlYWN1dGUnOiAyMzMsXG4gICAgJ2VjaXJjJzogMjM0LFxuICAgICdlZ3JhdmUnOiAyMzIsXG4gICAgJ2V0aCc6IDI0MCxcbiAgICAnZXVtbCc6IDIzNSxcbiAgICAnaWFjdXRlJzogMjM3LFxuICAgICdpY2lyYyc6IDIzOCxcbiAgICAnaWdyYXZlJzogMjM2LFxuICAgICdpdW1sJzogMjM5LFxuICAgICdudGlsZGUnOiAyNDEsXG4gICAgJ29hY3V0ZSc6IDI0MyxcbiAgICAnb2NpcmMnOiAyNDQsXG4gICAgJ29ncmF2ZSc6IDI0MixcbiAgICAnb3NsYXNoJzogMjQ4LFxuICAgICdvdGlsZGUnOiAyNDUsXG4gICAgJ291bWwnOiAyNDYsXG4gICAgJ3N6bGlnJzogMjIzLFxuICAgICd0aG9ybic6IDI1NCxcbiAgICAndWFjdXRlJzogMjUwLFxuICAgICd1Y2lyYyc6IDI1MSxcbiAgICAndWdyYXZlJzogMjQ5LFxuICAgICd1dW1sJzogMjUyLFxuICAgICd5YWN1dGUnOiAyNTMsXG4gICAgJ3l1bWwnOiAyNTUsXG4gICAgJ2NvcHknOiAxNjksXG4gICAgJ3JlZyc6IDE3NCxcbiAgICAnbmJzcCc6IDE2MCxcbiAgICAnaWV4Y2wnOiAxNjEsXG4gICAgJ2NlbnQnOiAxNjIsXG4gICAgJ3BvdW5kJzogMTYzLFxuICAgICdjdXJyZW4nOiAxNjQsXG4gICAgJ3llbic6IDE2NSxcbiAgICAnYnJ2YmFyJzogMTY2LFxuICAgICdzZWN0JzogMTY3LFxuICAgICd1bWwnOiAxNjgsXG4gICAgJ29yZGYnOiAxNzAsXG4gICAgJ2xhcXVvJzogMTcxLFxuICAgICdub3QnOiAxNzIsXG4gICAgJ3NoeSc6IDE3MyxcbiAgICAnbWFjcic6IDE3NSxcbiAgICAnZGVnJzogMTc2LFxuICAgICdwbHVzbW4nOiAxNzcsXG4gICAgJ3N1cDEnOiAxODUsXG4gICAgJ3N1cDInOiAxNzgsXG4gICAgJ3N1cDMnOiAxNzksXG4gICAgJ2FjdXRlJzogMTgwLFxuICAgICdtaWNybyc6IDE4MSxcbiAgICAncGFyYSc6IDE4MixcbiAgICAnbWlkZG90JzogMTgzLFxuICAgICdjZWRpbCc6IDE4NCxcbiAgICAnb3JkbSc6IDE4NixcbiAgICAncmFxdW8nOiAxODcsXG4gICAgJ2ZyYWMxNCc6IDE4OCxcbiAgICAnZnJhYzEyJzogMTg5LFxuICAgICdmcmFjMzQnOiAxOTAsXG4gICAgJ2lxdWVzdCc6IDE5MSxcbiAgICAndGltZXMnOiAyMTUsXG4gICAgJ2RpdmlkZSc6IDI0NyxcbiAgICAnT0VsaWcnOiAzMzgsXG4gICAgJ29lbGlnJzogMzM5LFxuICAgICdTY2Fyb24nOiAzNTIsXG4gICAgJ3NjYXJvbic6IDM1MyxcbiAgICAnWXVtbCc6IDM3NixcbiAgICAnZm5vZic6IDQwMixcbiAgICAnY2lyYyc6IDcxMCxcbiAgICAndGlsZGUnOiA3MzIsXG4gICAgJ0FscGhhJzogOTEzLFxuICAgICdCZXRhJzogOTE0LFxuICAgICdHYW1tYSc6IDkxNSxcbiAgICAnRGVsdGEnOiA5MTYsXG4gICAgJ0Vwc2lsb24nOiA5MTcsXG4gICAgJ1pldGEnOiA5MTgsXG4gICAgJ0V0YSc6IDkxOSxcbiAgICAnVGhldGEnOiA5MjAsXG4gICAgJ0lvdGEnOiA5MjEsXG4gICAgJ0thcHBhJzogOTIyLFxuICAgICdMYW1iZGEnOiA5MjMsXG4gICAgJ011JzogOTI0LFxuICAgICdOdSc6IDkyNSxcbiAgICAnWGknOiA5MjYsXG4gICAgJ09taWNyb24nOiA5MjcsXG4gICAgJ1BpJzogOTI4LFxuICAgICdSaG8nOiA5MjksXG4gICAgJ1NpZ21hJzogOTMxLFxuICAgICdUYXUnOiA5MzIsXG4gICAgJ1Vwc2lsb24nOiA5MzMsXG4gICAgJ1BoaSc6IDkzNCxcbiAgICAnQ2hpJzogOTM1LFxuICAgICdQc2knOiA5MzYsXG4gICAgJ09tZWdhJzogOTM3LFxuICAgICdhbHBoYSc6IDk0NSxcbiAgICAnYmV0YSc6IDk0NixcbiAgICAnZ2FtbWEnOiA5NDcsXG4gICAgJ2RlbHRhJzogOTQ4LFxuICAgICdlcHNpbG9uJzogOTQ5LFxuICAgICd6ZXRhJzogOTUwLFxuICAgICdldGEnOiA5NTEsXG4gICAgJ3RoZXRhJzogOTUyLFxuICAgICdpb3RhJzogOTUzLFxuICAgICdrYXBwYSc6IDk1NCxcbiAgICAnbGFtYmRhJzogOTU1LFxuICAgICdtdSc6IDk1NixcbiAgICAnbnUnOiA5NTcsXG4gICAgJ3hpJzogOTU4LFxuICAgICdvbWljcm9uJzogOTU5LFxuICAgICdwaSc6IDk2MCxcbiAgICAncmhvJzogOTYxLFxuICAgICdzaWdtYWYnOiA5NjIsXG4gICAgJ3NpZ21hJzogOTYzLFxuICAgICd0YXUnOiA5NjQsXG4gICAgJ3Vwc2lsb24nOiA5NjUsXG4gICAgJ3BoaSc6IDk2NixcbiAgICAnY2hpJzogOTY3LFxuICAgICdwc2knOiA5NjgsXG4gICAgJ29tZWdhJzogOTY5LFxuICAgICd0aGV0YXN5bSc6IDk3NyxcbiAgICAndXBzaWgnOiA5NzgsXG4gICAgJ3Bpdic6IDk4MixcbiAgICAnZW5zcCc6IDgxOTQsXG4gICAgJ2Vtc3AnOiA4MTk1LFxuICAgICd0aGluc3AnOiA4MjAxLFxuICAgICd6d25qJzogODIwNCxcbiAgICAnendqJzogODIwNSxcbiAgICAnbHJtJzogODIwNixcbiAgICAncmxtJzogODIwNyxcbiAgICAnbmRhc2gnOiA4MjExLFxuICAgICdtZGFzaCc6IDgyMTIsXG4gICAgJ2xzcXVvJzogODIxNixcbiAgICAncnNxdW8nOiA4MjE3LFxuICAgICdzYnF1byc6IDgyMTgsXG4gICAgJ2xkcXVvJzogODIyMCxcbiAgICAncmRxdW8nOiA4MjIxLFxuICAgICdiZHF1byc6IDgyMjIsXG4gICAgJ2RhZ2dlcic6IDgyMjQsXG4gICAgJ0RhZ2dlcic6IDgyMjUsXG4gICAgJ2J1bGwnOiA4MjI2LFxuICAgICdoZWxsaXAnOiA4MjMwLFxuICAgICdwZXJtaWwnOiA4MjQwLFxuICAgICdwcmltZSc6IDgyNDIsXG4gICAgJ1ByaW1lJzogODI0MyxcbiAgICAnbHNhcXVvJzogODI0OSxcbiAgICAncnNhcXVvJzogODI1MCxcbiAgICAnb2xpbmUnOiA4MjU0LFxuICAgICdmcmFzbCc6IDgyNjAsXG4gICAgJ2V1cm8nOiA4MzY0LFxuICAgICdpbWFnZSc6IDg0NjUsXG4gICAgJ3dlaWVycCc6IDg0NzIsXG4gICAgJ3JlYWwnOiA4NDc2LFxuICAgICd0cmFkZSc6IDg0ODIsXG4gICAgJ2FsZWZzeW0nOiA4NTAxLFxuICAgICdsYXJyJzogODU5MixcbiAgICAndWFycic6IDg1OTMsXG4gICAgJ3JhcnInOiA4NTk0LFxuICAgICdkYXJyJzogODU5NSxcbiAgICAnaGFycic6IDg1OTYsXG4gICAgJ2NyYXJyJzogODYyOSxcbiAgICAnbEFycic6IDg2NTYsXG4gICAgJ3VBcnInOiA4NjU3LFxuICAgICdyQXJyJzogODY1OCxcbiAgICAnZEFycic6IDg2NTksXG4gICAgJ2hBcnInOiA4NjYwLFxuICAgICdmb3JhbGwnOiA4NzA0LFxuICAgICdwYXJ0JzogODcwNixcbiAgICAnZXhpc3QnOiA4NzA3LFxuICAgICdlbXB0eSc6IDg3MDksXG4gICAgJ25hYmxhJzogODcxMSxcbiAgICAnaXNpbic6IDg3MTIsXG4gICAgJ25vdGluJzogODcxMyxcbiAgICAnbmknOiA4NzE1LFxuICAgICdwcm9kJzogODcxOSxcbiAgICAnc3VtJzogODcyMSxcbiAgICAnbWludXMnOiA4NzIyLFxuICAgICdsb3dhc3QnOiA4NzI3LFxuICAgICdyYWRpYyc6IDg3MzAsXG4gICAgJ3Byb3AnOiA4NzMzLFxuICAgICdpbmZpbic6IDg3MzQsXG4gICAgJ2FuZyc6IDg3MzYsXG4gICAgJ2FuZCc6IDg3NDMsXG4gICAgJ29yJzogODc0NCxcbiAgICAnY2FwJzogODc0NSxcbiAgICAnY3VwJzogODc0NixcbiAgICAnaW50JzogODc0NyxcbiAgICAndGhlcmU0JzogODc1NixcbiAgICAnc2ltJzogODc2NCxcbiAgICAnY29uZyc6IDg3NzMsXG4gICAgJ2FzeW1wJzogODc3NixcbiAgICAnbmUnOiA4ODAwLFxuICAgICdlcXVpdic6IDg4MDEsXG4gICAgJ2xlJzogODgwNCxcbiAgICAnZ2UnOiA4ODA1LFxuICAgICdzdWInOiA4ODM0LFxuICAgICdzdXAnOiA4ODM1LFxuICAgICduc3ViJzogODgzNixcbiAgICAnc3ViZSc6IDg4MzgsXG4gICAgJ3N1cGUnOiA4ODM5LFxuICAgICdvcGx1cyc6IDg4NTMsXG4gICAgJ290aW1lcyc6IDg4NTUsXG4gICAgJ3BlcnAnOiA4ODY5LFxuICAgICdzZG90JzogODkwMSxcbiAgICAnbGNlaWwnOiA4OTY4LFxuICAgICdyY2VpbCc6IDg5NjksXG4gICAgJ2xmbG9vcic6IDg5NzAsXG4gICAgJ3JmbG9vcic6IDg5NzEsXG4gICAgJ2xhbmcnOiA5MDAxLFxuICAgICdyYW5nJzogOTAwMixcbiAgICAnbG96JzogOTY3NCxcbiAgICAnc3BhZGVzJzogOTgyNCxcbiAgICAnY2x1YnMnOiA5ODI3LFxuICAgICdoZWFydHMnOiA5ODI5LFxuICAgICdkaWFtcyc6IDk4MzBcbiAgfVxuXG4gIE9iamVjdC5rZXlzKHNheC5FTlRJVElFUykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgdmFyIGUgPSBzYXguRU5USVRJRVNba2V5XVxuICAgIHZhciBzID0gdHlwZW9mIGUgPT09ICdudW1iZXInID8gU3RyaW5nLmZyb21DaGFyQ29kZShlKSA6IGVcbiAgICBzYXguRU5USVRJRVNba2V5XSA9IHNcbiAgfSlcblxuICBmb3IgKHZhciBzIGluIHNheC5TVEFURSkge1xuICAgIHNheC5TVEFURVtzYXguU1RBVEVbc11dID0gc1xuICB9XG5cbiAgLy8gc2hvcnRoYW5kXG4gIFMgPSBzYXguU1RBVEVcblxuICBmdW5jdGlvbiBlbWl0IChwYXJzZXIsIGV2ZW50LCBkYXRhKSB7XG4gICAgcGFyc2VyW2V2ZW50XSAmJiBwYXJzZXJbZXZlbnRdKGRhdGEpXG4gIH1cblxuICBmdW5jdGlvbiBlbWl0Tm9kZSAocGFyc2VyLCBub2RlVHlwZSwgZGF0YSkge1xuICAgIGlmIChwYXJzZXIudGV4dE5vZGUpIGNsb3NlVGV4dChwYXJzZXIpXG4gICAgZW1pdChwYXJzZXIsIG5vZGVUeXBlLCBkYXRhKVxuICB9XG5cbiAgZnVuY3Rpb24gY2xvc2VUZXh0IChwYXJzZXIpIHtcbiAgICBwYXJzZXIudGV4dE5vZGUgPSB0ZXh0b3B0cyhwYXJzZXIub3B0LCBwYXJzZXIudGV4dE5vZGUpXG4gICAgaWYgKHBhcnNlci50ZXh0Tm9kZSkgZW1pdChwYXJzZXIsICdvbnRleHQnLCBwYXJzZXIudGV4dE5vZGUpXG4gICAgcGFyc2VyLnRleHROb2RlID0gJydcbiAgfVxuXG4gIGZ1bmN0aW9uIHRleHRvcHRzIChvcHQsIHRleHQpIHtcbiAgICBpZiAob3B0LnRyaW0pIHRleHQgPSB0ZXh0LnRyaW0oKVxuICAgIGlmIChvcHQubm9ybWFsaXplKSB0ZXh0ID0gdGV4dC5yZXBsYWNlKC9cXHMrL2csICcgJylcbiAgICByZXR1cm4gdGV4dFxuICB9XG5cbiAgZnVuY3Rpb24gZXJyb3IgKHBhcnNlciwgZXIpIHtcbiAgICBjbG9zZVRleHQocGFyc2VyKVxuICAgIGlmIChwYXJzZXIudHJhY2tQb3NpdGlvbikge1xuICAgICAgZXIgKz0gJ1xcbkxpbmU6ICcgKyBwYXJzZXIubGluZSArXG4gICAgICAgICdcXG5Db2x1bW46ICcgKyBwYXJzZXIuY29sdW1uICtcbiAgICAgICAgJ1xcbkNoYXI6ICcgKyBwYXJzZXIuY1xuICAgIH1cbiAgICBlciA9IG5ldyBFcnJvcihlcilcbiAgICBwYXJzZXIuZXJyb3IgPSBlclxuICAgIGVtaXQocGFyc2VyLCAnb25lcnJvcicsIGVyKVxuICAgIHJldHVybiBwYXJzZXJcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuZCAocGFyc2VyKSB7XG4gICAgaWYgKHBhcnNlci5zYXdSb290ICYmICFwYXJzZXIuY2xvc2VkUm9vdCkgc3RyaWN0RmFpbChwYXJzZXIsICdVbmNsb3NlZCByb290IHRhZycpXG4gICAgaWYgKChwYXJzZXIuc3RhdGUgIT09IFMuQkVHSU4pICYmXG4gICAgICAocGFyc2VyLnN0YXRlICE9PSBTLkJFR0lOX1dISVRFU1BBQ0UpICYmXG4gICAgICAocGFyc2VyLnN0YXRlICE9PSBTLlRFWFQpKSB7XG4gICAgICBlcnJvcihwYXJzZXIsICdVbmV4cGVjdGVkIGVuZCcpXG4gICAgfVxuICAgIGNsb3NlVGV4dChwYXJzZXIpXG4gICAgcGFyc2VyLmMgPSAnJ1xuICAgIHBhcnNlci5jbG9zZWQgPSB0cnVlXG4gICAgZW1pdChwYXJzZXIsICdvbmVuZCcpXG4gICAgU0FYUGFyc2VyLmNhbGwocGFyc2VyLCBwYXJzZXIuc3RyaWN0LCBwYXJzZXIub3B0KVxuICAgIHJldHVybiBwYXJzZXJcbiAgfVxuXG4gIGZ1bmN0aW9uIHN0cmljdEZhaWwgKHBhcnNlciwgbWVzc2FnZSkge1xuICAgIGlmICh0eXBlb2YgcGFyc2VyICE9PSAnb2JqZWN0JyB8fCAhKHBhcnNlciBpbnN0YW5jZW9mIFNBWFBhcnNlcikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYmFkIGNhbGwgdG8gc3RyaWN0RmFpbCcpXG4gICAgfVxuICAgIGlmIChwYXJzZXIuc3RyaWN0KSB7XG4gICAgICBlcnJvcihwYXJzZXIsIG1lc3NhZ2UpXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbmV3VGFnIChwYXJzZXIpIHtcbiAgICBpZiAoIXBhcnNlci5zdHJpY3QpIHBhcnNlci50YWdOYW1lID0gcGFyc2VyLnRhZ05hbWVbcGFyc2VyLmxvb3NlQ2FzZV0oKVxuICAgIHZhciBwYXJlbnQgPSBwYXJzZXIudGFnc1twYXJzZXIudGFncy5sZW5ndGggLSAxXSB8fCBwYXJzZXJcbiAgICB2YXIgdGFnID0gcGFyc2VyLnRhZyA9IHsgbmFtZTogcGFyc2VyLnRhZ05hbWUsIGF0dHJpYnV0ZXM6IHt9IH1cblxuICAgIC8vIHdpbGwgYmUgb3ZlcnJpZGRlbiBpZiB0YWcgY29udGFpbHMgYW4geG1sbnM9XCJmb29cIiBvciB4bWxuczpmb289XCJiYXJcIlxuICAgIGlmIChwYXJzZXIub3B0LnhtbG5zKSB7XG4gICAgICB0YWcubnMgPSBwYXJlbnQubnNcbiAgICB9XG4gICAgcGFyc2VyLmF0dHJpYkxpc3QubGVuZ3RoID0gMFxuICAgIGVtaXROb2RlKHBhcnNlciwgJ29ub3BlbnRhZ3N0YXJ0JywgdGFnKVxuICB9XG5cbiAgZnVuY3Rpb24gcW5hbWUgKG5hbWUsIGF0dHJpYnV0ZSkge1xuICAgIHZhciBpID0gbmFtZS5pbmRleE9mKCc6JylcbiAgICB2YXIgcXVhbE5hbWUgPSBpIDwgMCA/IFsgJycsIG5hbWUgXSA6IG5hbWUuc3BsaXQoJzonKVxuICAgIHZhciBwcmVmaXggPSBxdWFsTmFtZVswXVxuICAgIHZhciBsb2NhbCA9IHF1YWxOYW1lWzFdXG5cbiAgICAvLyA8eCBcInhtbG5zXCI9XCJodHRwOi8vZm9vXCI+XG4gICAgaWYgKGF0dHJpYnV0ZSAmJiBuYW1lID09PSAneG1sbnMnKSB7XG4gICAgICBwcmVmaXggPSAneG1sbnMnXG4gICAgICBsb2NhbCA9ICcnXG4gICAgfVxuXG4gICAgcmV0dXJuIHsgcHJlZml4OiBwcmVmaXgsIGxvY2FsOiBsb2NhbCB9XG4gIH1cblxuICBmdW5jdGlvbiBhdHRyaWIgKHBhcnNlcikge1xuICAgIGlmICghcGFyc2VyLnN0cmljdCkge1xuICAgICAgcGFyc2VyLmF0dHJpYk5hbWUgPSBwYXJzZXIuYXR0cmliTmFtZVtwYXJzZXIubG9vc2VDYXNlXSgpXG4gICAgfVxuXG4gICAgaWYgKHBhcnNlci5hdHRyaWJMaXN0LmluZGV4T2YocGFyc2VyLmF0dHJpYk5hbWUpICE9PSAtMSB8fFxuICAgICAgcGFyc2VyLnRhZy5hdHRyaWJ1dGVzLmhhc093blByb3BlcnR5KHBhcnNlci5hdHRyaWJOYW1lKSkge1xuICAgICAgcGFyc2VyLmF0dHJpYk5hbWUgPSBwYXJzZXIuYXR0cmliVmFsdWUgPSAnJ1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHBhcnNlci5vcHQueG1sbnMpIHtcbiAgICAgIHZhciBxbiA9IHFuYW1lKHBhcnNlci5hdHRyaWJOYW1lLCB0cnVlKVxuICAgICAgdmFyIHByZWZpeCA9IHFuLnByZWZpeFxuICAgICAgdmFyIGxvY2FsID0gcW4ubG9jYWxcblxuICAgICAgaWYgKHByZWZpeCA9PT0gJ3htbG5zJykge1xuICAgICAgICAvLyBuYW1lc3BhY2UgYmluZGluZyBhdHRyaWJ1dGUuIHB1c2ggdGhlIGJpbmRpbmcgaW50byBzY29wZVxuICAgICAgICBpZiAobG9jYWwgPT09ICd4bWwnICYmIHBhcnNlci5hdHRyaWJWYWx1ZSAhPT0gWE1MX05BTUVTUEFDRSkge1xuICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLFxuICAgICAgICAgICAgJ3htbDogcHJlZml4IG11c3QgYmUgYm91bmQgdG8gJyArIFhNTF9OQU1FU1BBQ0UgKyAnXFxuJyArXG4gICAgICAgICAgICAnQWN0dWFsOiAnICsgcGFyc2VyLmF0dHJpYlZhbHVlKVxuICAgICAgICB9IGVsc2UgaWYgKGxvY2FsID09PSAneG1sbnMnICYmIHBhcnNlci5hdHRyaWJWYWx1ZSAhPT0gWE1MTlNfTkFNRVNQQUNFKSB7XG4gICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsXG4gICAgICAgICAgICAneG1sbnM6IHByZWZpeCBtdXN0IGJlIGJvdW5kIHRvICcgKyBYTUxOU19OQU1FU1BBQ0UgKyAnXFxuJyArXG4gICAgICAgICAgICAnQWN0dWFsOiAnICsgcGFyc2VyLmF0dHJpYlZhbHVlKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciB0YWcgPSBwYXJzZXIudGFnXG4gICAgICAgICAgdmFyIHBhcmVudCA9IHBhcnNlci50YWdzW3BhcnNlci50YWdzLmxlbmd0aCAtIDFdIHx8IHBhcnNlclxuICAgICAgICAgIGlmICh0YWcubnMgPT09IHBhcmVudC5ucykge1xuICAgICAgICAgICAgdGFnLm5zID0gT2JqZWN0LmNyZWF0ZShwYXJlbnQubnMpXG4gICAgICAgICAgfVxuICAgICAgICAgIHRhZy5uc1tsb2NhbF0gPSBwYXJzZXIuYXR0cmliVmFsdWVcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBkZWZlciBvbmF0dHJpYnV0ZSBldmVudHMgdW50aWwgYWxsIGF0dHJpYnV0ZXMgaGF2ZSBiZWVuIHNlZW5cbiAgICAgIC8vIHNvIGFueSBuZXcgYmluZGluZ3MgY2FuIHRha2UgZWZmZWN0LiBwcmVzZXJ2ZSBhdHRyaWJ1dGUgb3JkZXJcbiAgICAgIC8vIHNvIGRlZmVycmVkIGV2ZW50cyBjYW4gYmUgZW1pdHRlZCBpbiBkb2N1bWVudCBvcmRlclxuICAgICAgcGFyc2VyLmF0dHJpYkxpc3QucHVzaChbcGFyc2VyLmF0dHJpYk5hbWUsIHBhcnNlci5hdHRyaWJWYWx1ZV0pXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGluIG5vbi14bWxucyBtb2RlLCB3ZSBjYW4gZW1pdCB0aGUgZXZlbnQgcmlnaHQgYXdheVxuICAgICAgcGFyc2VyLnRhZy5hdHRyaWJ1dGVzW3BhcnNlci5hdHRyaWJOYW1lXSA9IHBhcnNlci5hdHRyaWJWYWx1ZVxuICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25hdHRyaWJ1dGUnLCB7XG4gICAgICAgIG5hbWU6IHBhcnNlci5hdHRyaWJOYW1lLFxuICAgICAgICB2YWx1ZTogcGFyc2VyLmF0dHJpYlZhbHVlXG4gICAgICB9KVxuICAgIH1cblxuICAgIHBhcnNlci5hdHRyaWJOYW1lID0gcGFyc2VyLmF0dHJpYlZhbHVlID0gJydcbiAgfVxuXG4gIGZ1bmN0aW9uIG9wZW5UYWcgKHBhcnNlciwgc2VsZkNsb3NpbmcpIHtcbiAgICBpZiAocGFyc2VyLm9wdC54bWxucykge1xuICAgICAgLy8gZW1pdCBuYW1lc3BhY2UgYmluZGluZyBldmVudHNcbiAgICAgIHZhciB0YWcgPSBwYXJzZXIudGFnXG5cbiAgICAgIC8vIGFkZCBuYW1lc3BhY2UgaW5mbyB0byB0YWdcbiAgICAgIHZhciBxbiA9IHFuYW1lKHBhcnNlci50YWdOYW1lKVxuICAgICAgdGFnLnByZWZpeCA9IHFuLnByZWZpeFxuICAgICAgdGFnLmxvY2FsID0gcW4ubG9jYWxcbiAgICAgIHRhZy51cmkgPSB0YWcubnNbcW4ucHJlZml4XSB8fCAnJ1xuXG4gICAgICBpZiAodGFnLnByZWZpeCAmJiAhdGFnLnVyaSkge1xuICAgICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ1VuYm91bmQgbmFtZXNwYWNlIHByZWZpeDogJyArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkocGFyc2VyLnRhZ05hbWUpKVxuICAgICAgICB0YWcudXJpID0gcW4ucHJlZml4XG4gICAgICB9XG5cbiAgICAgIHZhciBwYXJlbnQgPSBwYXJzZXIudGFnc1twYXJzZXIudGFncy5sZW5ndGggLSAxXSB8fCBwYXJzZXJcbiAgICAgIGlmICh0YWcubnMgJiYgcGFyZW50Lm5zICE9PSB0YWcubnMpIHtcbiAgICAgICAgT2JqZWN0LmtleXModGFnLm5zKS5mb3JFYWNoKGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25vcGVubmFtZXNwYWNlJywge1xuICAgICAgICAgICAgcHJlZml4OiBwLFxuICAgICAgICAgICAgdXJpOiB0YWcubnNbcF1cbiAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICAvLyBoYW5kbGUgZGVmZXJyZWQgb25hdHRyaWJ1dGUgZXZlbnRzXG4gICAgICAvLyBOb3RlOiBkbyBub3QgYXBwbHkgZGVmYXVsdCBucyB0byBhdHRyaWJ1dGVzOlxuICAgICAgLy8gICBodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNkZWZhdWx0aW5nXG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHBhcnNlci5hdHRyaWJMaXN0Lmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB2YXIgbnYgPSBwYXJzZXIuYXR0cmliTGlzdFtpXVxuICAgICAgICB2YXIgbmFtZSA9IG52WzBdXG4gICAgICAgIHZhciB2YWx1ZSA9IG52WzFdXG4gICAgICAgIHZhciBxdWFsTmFtZSA9IHFuYW1lKG5hbWUsIHRydWUpXG4gICAgICAgIHZhciBwcmVmaXggPSBxdWFsTmFtZS5wcmVmaXhcbiAgICAgICAgdmFyIGxvY2FsID0gcXVhbE5hbWUubG9jYWxcbiAgICAgICAgdmFyIHVyaSA9IHByZWZpeCA9PT0gJycgPyAnJyA6ICh0YWcubnNbcHJlZml4XSB8fCAnJylcbiAgICAgICAgdmFyIGEgPSB7XG4gICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgcHJlZml4OiBwcmVmaXgsXG4gICAgICAgICAgbG9jYWw6IGxvY2FsLFxuICAgICAgICAgIHVyaTogdXJpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB0aGVyZSdzIGFueSBhdHRyaWJ1dGVzIHdpdGggYW4gdW5kZWZpbmVkIG5hbWVzcGFjZSxcbiAgICAgICAgLy8gdGhlbiBmYWlsIG9uIHRoZW0gbm93LlxuICAgICAgICBpZiAocHJlZml4ICYmIHByZWZpeCAhPT0gJ3htbG5zJyAmJiAhdXJpKSB7XG4gICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdVbmJvdW5kIG5hbWVzcGFjZSBwcmVmaXg6ICcgK1xuICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkocHJlZml4KSlcbiAgICAgICAgICBhLnVyaSA9IHByZWZpeFxuICAgICAgICB9XG4gICAgICAgIHBhcnNlci50YWcuYXR0cmlidXRlc1tuYW1lXSA9IGFcbiAgICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25hdHRyaWJ1dGUnLCBhKVxuICAgICAgfVxuICAgICAgcGFyc2VyLmF0dHJpYkxpc3QubGVuZ3RoID0gMFxuICAgIH1cblxuICAgIHBhcnNlci50YWcuaXNTZWxmQ2xvc2luZyA9ICEhc2VsZkNsb3NpbmdcblxuICAgIC8vIHByb2Nlc3MgdGhlIHRhZ1xuICAgIHBhcnNlci5zYXdSb290ID0gdHJ1ZVxuICAgIHBhcnNlci50YWdzLnB1c2gocGFyc2VyLnRhZylcbiAgICBlbWl0Tm9kZShwYXJzZXIsICdvbm9wZW50YWcnLCBwYXJzZXIudGFnKVxuICAgIGlmICghc2VsZkNsb3NpbmcpIHtcbiAgICAgIC8vIHNwZWNpYWwgY2FzZSBmb3IgPHNjcmlwdD4gaW4gbm9uLXN0cmljdCBtb2RlLlxuICAgICAgaWYgKCFwYXJzZXIubm9zY3JpcHQgJiYgcGFyc2VyLnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ3NjcmlwdCcpIHtcbiAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5TQ1JJUFRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuVEVYVFxuICAgICAgfVxuICAgICAgcGFyc2VyLnRhZyA9IG51bGxcbiAgICAgIHBhcnNlci50YWdOYW1lID0gJydcbiAgICB9XG4gICAgcGFyc2VyLmF0dHJpYk5hbWUgPSBwYXJzZXIuYXR0cmliVmFsdWUgPSAnJ1xuICAgIHBhcnNlci5hdHRyaWJMaXN0Lmxlbmd0aCA9IDBcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsb3NlVGFnIChwYXJzZXIpIHtcbiAgICBpZiAoIXBhcnNlci50YWdOYW1lKSB7XG4gICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ1dlaXJkIGVtcHR5IGNsb3NlIHRhZy4nKVxuICAgICAgcGFyc2VyLnRleHROb2RlICs9ICc8Lz4nXG4gICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChwYXJzZXIuc2NyaXB0KSB7XG4gICAgICBpZiAocGFyc2VyLnRhZ05hbWUgIT09ICdzY3JpcHQnKSB7XG4gICAgICAgIHBhcnNlci5zY3JpcHQgKz0gJzwvJyArIHBhcnNlci50YWdOYW1lICsgJz4nXG4gICAgICAgIHBhcnNlci50YWdOYW1lID0gJydcbiAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5TQ1JJUFRcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbnNjcmlwdCcsIHBhcnNlci5zY3JpcHQpXG4gICAgICBwYXJzZXIuc2NyaXB0ID0gJydcbiAgICB9XG5cbiAgICAvLyBmaXJzdCBtYWtlIHN1cmUgdGhhdCB0aGUgY2xvc2luZyB0YWcgYWN0dWFsbHkgZXhpc3RzLlxuICAgIC8vIDxhPjxiPjwvYz48L2I+PC9hPiB3aWxsIGNsb3NlIGV2ZXJ5dGhpbmcsIG90aGVyd2lzZS5cbiAgICB2YXIgdCA9IHBhcnNlci50YWdzLmxlbmd0aFxuICAgIHZhciB0YWdOYW1lID0gcGFyc2VyLnRhZ05hbWVcbiAgICBpZiAoIXBhcnNlci5zdHJpY3QpIHtcbiAgICAgIHRhZ05hbWUgPSB0YWdOYW1lW3BhcnNlci5sb29zZUNhc2VdKClcbiAgICB9XG4gICAgdmFyIGNsb3NlVG8gPSB0YWdOYW1lXG4gICAgd2hpbGUgKHQtLSkge1xuICAgICAgdmFyIGNsb3NlID0gcGFyc2VyLnRhZ3NbdF1cbiAgICAgIGlmIChjbG9zZS5uYW1lICE9PSBjbG9zZVRvKSB7XG4gICAgICAgIC8vIGZhaWwgdGhlIGZpcnN0IHRpbWUgaW4gc3RyaWN0IG1vZGVcbiAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdVbmV4cGVjdGVkIGNsb3NlIHRhZycpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGRpZG4ndCBmaW5kIGl0LiAgd2UgYWxyZWFkeSBmYWlsZWQgZm9yIHN0cmljdCwgc28ganVzdCBhYm9ydC5cbiAgICBpZiAodCA8IDApIHtcbiAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnVW5tYXRjaGVkIGNsb3NpbmcgdGFnOiAnICsgcGFyc2VyLnRhZ05hbWUpXG4gICAgICBwYXJzZXIudGV4dE5vZGUgKz0gJzwvJyArIHBhcnNlci50YWdOYW1lICsgJz4nXG4gICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBwYXJzZXIudGFnTmFtZSA9IHRhZ05hbWVcbiAgICB2YXIgcyA9IHBhcnNlci50YWdzLmxlbmd0aFxuICAgIHdoaWxlIChzLS0gPiB0KSB7XG4gICAgICB2YXIgdGFnID0gcGFyc2VyLnRhZyA9IHBhcnNlci50YWdzLnBvcCgpXG4gICAgICBwYXJzZXIudGFnTmFtZSA9IHBhcnNlci50YWcubmFtZVxuICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25jbG9zZXRhZycsIHBhcnNlci50YWdOYW1lKVxuXG4gICAgICB2YXIgeCA9IHt9XG4gICAgICBmb3IgKHZhciBpIGluIHRhZy5ucykge1xuICAgICAgICB4W2ldID0gdGFnLm5zW2ldXG4gICAgICB9XG5cbiAgICAgIHZhciBwYXJlbnQgPSBwYXJzZXIudGFnc1twYXJzZXIudGFncy5sZW5ndGggLSAxXSB8fCBwYXJzZXJcbiAgICAgIGlmIChwYXJzZXIub3B0LnhtbG5zICYmIHRhZy5ucyAhPT0gcGFyZW50Lm5zKSB7XG4gICAgICAgIC8vIHJlbW92ZSBuYW1lc3BhY2UgYmluZGluZ3MgaW50cm9kdWNlZCBieSB0YWdcbiAgICAgICAgT2JqZWN0LmtleXModGFnLm5zKS5mb3JFYWNoKGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgdmFyIG4gPSB0YWcubnNbcF1cbiAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbmNsb3NlbmFtZXNwYWNlJywgeyBwcmVmaXg6IHAsIHVyaTogbiB9KVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAodCA9PT0gMCkgcGFyc2VyLmNsb3NlZFJvb3QgPSB0cnVlXG4gICAgcGFyc2VyLnRhZ05hbWUgPSBwYXJzZXIuYXR0cmliVmFsdWUgPSBwYXJzZXIuYXR0cmliTmFtZSA9ICcnXG4gICAgcGFyc2VyLmF0dHJpYkxpc3QubGVuZ3RoID0gMFxuICAgIHBhcnNlci5zdGF0ZSA9IFMuVEVYVFxuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VFbnRpdHkgKHBhcnNlcikge1xuICAgIHZhciBlbnRpdHkgPSBwYXJzZXIuZW50aXR5XG4gICAgdmFyIGVudGl0eUxDID0gZW50aXR5LnRvTG93ZXJDYXNlKClcbiAgICB2YXIgbnVtXG4gICAgdmFyIG51bVN0ciA9ICcnXG5cbiAgICBpZiAocGFyc2VyLkVOVElUSUVTW2VudGl0eV0pIHtcbiAgICAgIHJldHVybiBwYXJzZXIuRU5USVRJRVNbZW50aXR5XVxuICAgIH1cbiAgICBpZiAocGFyc2VyLkVOVElUSUVTW2VudGl0eUxDXSkge1xuICAgICAgcmV0dXJuIHBhcnNlci5FTlRJVElFU1tlbnRpdHlMQ11cbiAgICB9XG4gICAgZW50aXR5ID0gZW50aXR5TENcbiAgICBpZiAoZW50aXR5LmNoYXJBdCgwKSA9PT0gJyMnKSB7XG4gICAgICBpZiAoZW50aXR5LmNoYXJBdCgxKSA9PT0gJ3gnKSB7XG4gICAgICAgIGVudGl0eSA9IGVudGl0eS5zbGljZSgyKVxuICAgICAgICBudW0gPSBwYXJzZUludChlbnRpdHksIDE2KVxuICAgICAgICBudW1TdHIgPSBudW0udG9TdHJpbmcoMTYpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnRpdHkgPSBlbnRpdHkuc2xpY2UoMSlcbiAgICAgICAgbnVtID0gcGFyc2VJbnQoZW50aXR5LCAxMClcbiAgICAgICAgbnVtU3RyID0gbnVtLnRvU3RyaW5nKDEwKVxuICAgICAgfVxuICAgIH1cbiAgICBlbnRpdHkgPSBlbnRpdHkucmVwbGFjZSgvXjArLywgJycpXG4gICAgaWYgKGlzTmFOKG51bSkgfHwgbnVtU3RyLnRvTG93ZXJDYXNlKCkgIT09IGVudGl0eSkge1xuICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdJbnZhbGlkIGNoYXJhY3RlciBlbnRpdHknKVxuICAgICAgcmV0dXJuICcmJyArIHBhcnNlci5lbnRpdHkgKyAnOydcbiAgICB9XG5cbiAgICByZXR1cm4gU3RyaW5nLmZyb21Db2RlUG9pbnQobnVtKVxuICB9XG5cbiAgZnVuY3Rpb24gYmVnaW5XaGl0ZVNwYWNlIChwYXJzZXIsIGMpIHtcbiAgICBpZiAoYyA9PT0gJzwnKSB7XG4gICAgICBwYXJzZXIuc3RhdGUgPSBTLk9QRU5fV0FLQVxuICAgICAgcGFyc2VyLnN0YXJ0VGFnUG9zaXRpb24gPSBwYXJzZXIucG9zaXRpb25cbiAgICB9IGVsc2UgaWYgKCFpc1doaXRlc3BhY2UoYykpIHtcbiAgICAgIC8vIGhhdmUgdG8gcHJvY2VzcyB0aGlzIGFzIGEgdGV4dCBub2RlLlxuICAgICAgLy8gd2VpcmQsIGJ1dCBoYXBwZW5zLlxuICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdOb24td2hpdGVzcGFjZSBiZWZvcmUgZmlyc3QgdGFnLicpXG4gICAgICBwYXJzZXIudGV4dE5vZGUgPSBjXG4gICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjaGFyQXQgKGNodW5rLCBpKSB7XG4gICAgdmFyIHJlc3VsdCA9ICcnXG4gICAgaWYgKGkgPCBjaHVuay5sZW5ndGgpIHtcbiAgICAgIHJlc3VsdCA9IGNodW5rLmNoYXJBdChpKVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICBmdW5jdGlvbiB3cml0ZSAoY2h1bmspIHtcbiAgICB2YXIgcGFyc2VyID0gdGhpc1xuICAgIGlmICh0aGlzLmVycm9yKSB7XG4gICAgICB0aHJvdyB0aGlzLmVycm9yXG4gICAgfVxuICAgIGlmIChwYXJzZXIuY2xvc2VkKSB7XG4gICAgICByZXR1cm4gZXJyb3IocGFyc2VyLFxuICAgICAgICAnQ2Fubm90IHdyaXRlIGFmdGVyIGNsb3NlLiBBc3NpZ24gYW4gb25yZWFkeSBoYW5kbGVyLicpXG4gICAgfVxuICAgIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGVuZChwYXJzZXIpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgY2h1bmsgPT09ICdvYmplY3QnKSB7XG4gICAgICBjaHVuayA9IGNodW5rLnRvU3RyaW5nKClcbiAgICB9XG4gICAgdmFyIGkgPSAwXG4gICAgdmFyIGMgPSAnJ1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBjID0gY2hhckF0KGNodW5rLCBpKyspXG4gICAgICBwYXJzZXIuYyA9IGNcblxuICAgICAgaWYgKCFjKSB7XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJzZXIudHJhY2tQb3NpdGlvbikge1xuICAgICAgICBwYXJzZXIucG9zaXRpb24rK1xuICAgICAgICBpZiAoYyA9PT0gJ1xcbicpIHtcbiAgICAgICAgICBwYXJzZXIubGluZSsrXG4gICAgICAgICAgcGFyc2VyLmNvbHVtbiA9IDBcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwYXJzZXIuY29sdW1uKytcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHBhcnNlci5zdGF0ZSkge1xuICAgICAgICBjYXNlIFMuQkVHSU46XG4gICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5CRUdJTl9XSElURVNQQUNFXG4gICAgICAgICAgaWYgKGMgPT09ICdcXHVGRUZGJykge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG4gICAgICAgICAgYmVnaW5XaGl0ZVNwYWNlKHBhcnNlciwgYylcbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5CRUdJTl9XSElURVNQQUNFOlxuICAgICAgICAgIGJlZ2luV2hpdGVTcGFjZShwYXJzZXIsIGMpXG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuVEVYVDpcbiAgICAgICAgICBpZiAocGFyc2VyLnNhd1Jvb3QgJiYgIXBhcnNlci5jbG9zZWRSb290KSB7XG4gICAgICAgICAgICB2YXIgc3RhcnRpID0gaSAtIDFcbiAgICAgICAgICAgIHdoaWxlIChjICYmIGMgIT09ICc8JyAmJiBjICE9PSAnJicpIHtcbiAgICAgICAgICAgICAgYyA9IGNoYXJBdChjaHVuaywgaSsrKVxuICAgICAgICAgICAgICBpZiAoYyAmJiBwYXJzZXIudHJhY2tQb3NpdGlvbikge1xuICAgICAgICAgICAgICAgIHBhcnNlci5wb3NpdGlvbisrXG4gICAgICAgICAgICAgICAgaWYgKGMgPT09ICdcXG4nKSB7XG4gICAgICAgICAgICAgICAgICBwYXJzZXIubGluZSsrXG4gICAgICAgICAgICAgICAgICBwYXJzZXIuY29sdW1uID0gMFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBwYXJzZXIuY29sdW1uKytcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhcnNlci50ZXh0Tm9kZSArPSBjaHVuay5zdWJzdHJpbmcoc3RhcnRpLCBpIC0gMSlcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGMgPT09ICc8JyAmJiAhKHBhcnNlci5zYXdSb290ICYmIHBhcnNlci5jbG9zZWRSb290ICYmICFwYXJzZXIuc3RyaWN0KSkge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5PUEVOX1dBS0FcbiAgICAgICAgICAgIHBhcnNlci5zdGFydFRhZ1Bvc2l0aW9uID0gcGFyc2VyLnBvc2l0aW9uXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaXNXaGl0ZXNwYWNlKGMpICYmICghcGFyc2VyLnNhd1Jvb3QgfHwgcGFyc2VyLmNsb3NlZFJvb3QpKSB7XG4gICAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnVGV4dCBkYXRhIG91dHNpZGUgb2Ygcm9vdCBub2RlLicpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYyA9PT0gJyYnKSB7XG4gICAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuVEVYVF9FTlRJVFlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHBhcnNlci50ZXh0Tm9kZSArPSBjXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLlNDUklQVDpcbiAgICAgICAgICAvLyBvbmx5IG5vbi1zdHJpY3RcbiAgICAgICAgICBpZiAoYyA9PT0gJzwnKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlNDUklQVF9FTkRJTkdcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnNjcmlwdCArPSBjXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLlNDUklQVF9FTkRJTkc6XG4gICAgICAgICAgaWYgKGMgPT09ICcvJykge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5DTE9TRV9UQUdcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnNjcmlwdCArPSAnPCcgKyBjXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlNDUklQVFxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5PUEVOX1dBS0E6XG4gICAgICAgICAgLy8gZWl0aGVyIGEgLywgPywgISwgb3IgdGV4dCBpcyBjb21pbmcgbmV4dC5cbiAgICAgICAgICBpZiAoYyA9PT0gJyEnKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlNHTUxfREVDTFxuICAgICAgICAgICAgcGFyc2VyLnNnbWxEZWNsID0gJydcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzV2hpdGVzcGFjZShjKSkge1xuICAgICAgICAgICAgLy8gd2FpdCBmb3IgaXQuLi5cbiAgICAgICAgICB9IGVsc2UgaWYgKGlzTWF0Y2gobmFtZVN0YXJ0LCBjKSkge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5PUEVOX1RBR1xuICAgICAgICAgICAgcGFyc2VyLnRhZ05hbWUgPSBjXG4gICAgICAgICAgfSBlbHNlIGlmIChjID09PSAnLycpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ0xPU0VfVEFHXG4gICAgICAgICAgICBwYXJzZXIudGFnTmFtZSA9ICcnXG4gICAgICAgICAgfSBlbHNlIGlmIChjID09PSAnPycpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuUFJPQ19JTlNUXG4gICAgICAgICAgICBwYXJzZXIucHJvY0luc3ROYW1lID0gcGFyc2VyLnByb2NJbnN0Qm9keSA9ICcnXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnVW5lbmNvZGVkIDwnKVxuICAgICAgICAgICAgLy8gaWYgdGhlcmUgd2FzIHNvbWUgd2hpdGVzcGFjZSwgdGhlbiBhZGQgdGhhdCBpbi5cbiAgICAgICAgICAgIGlmIChwYXJzZXIuc3RhcnRUYWdQb3NpdGlvbiArIDEgPCBwYXJzZXIucG9zaXRpb24pIHtcbiAgICAgICAgICAgICAgdmFyIHBhZCA9IHBhcnNlci5wb3NpdGlvbiAtIHBhcnNlci5zdGFydFRhZ1Bvc2l0aW9uXG4gICAgICAgICAgICAgIGMgPSBuZXcgQXJyYXkocGFkKS5qb2luKCcgJykgKyBjXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXJzZXIudGV4dE5vZGUgKz0gJzwnICsgY1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5URVhUXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLlNHTUxfREVDTDpcbiAgICAgICAgICBpZiAoKHBhcnNlci5zZ21sRGVjbCArIGMpLnRvVXBwZXJDYXNlKCkgPT09IENEQVRBKSB7XG4gICAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbm9wZW5jZGF0YScpXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkNEQVRBXG4gICAgICAgICAgICBwYXJzZXIuc2dtbERlY2wgPSAnJ1xuICAgICAgICAgICAgcGFyc2VyLmNkYXRhID0gJydcbiAgICAgICAgICB9IGVsc2UgaWYgKHBhcnNlci5zZ21sRGVjbCArIGMgPT09ICctLScpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ09NTUVOVFxuICAgICAgICAgICAgcGFyc2VyLmNvbW1lbnQgPSAnJ1xuICAgICAgICAgICAgcGFyc2VyLnNnbWxEZWNsID0gJydcbiAgICAgICAgICB9IGVsc2UgaWYgKChwYXJzZXIuc2dtbERlY2wgKyBjKS50b1VwcGVyQ2FzZSgpID09PSBET0NUWVBFKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkRPQ1RZUEVcbiAgICAgICAgICAgIGlmIChwYXJzZXIuZG9jdHlwZSB8fCBwYXJzZXIuc2F3Um9vdCkge1xuICAgICAgICAgICAgICBzdHJpY3RGYWlsKHBhcnNlcixcbiAgICAgICAgICAgICAgICAnSW5hcHByb3ByaWF0ZWx5IGxvY2F0ZWQgZG9jdHlwZSBkZWNsYXJhdGlvbicpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXJzZXIuZG9jdHlwZSA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc2dtbERlY2wgPSAnJ1xuICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gJz4nKSB7XG4gICAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbnNnbWxkZWNsYXJhdGlvbicsIHBhcnNlci5zZ21sRGVjbClcbiAgICAgICAgICAgIHBhcnNlci5zZ21sRGVjbCA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzUXVvdGUoYykpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuU0dNTF9ERUNMX1FVT1RFRFxuICAgICAgICAgICAgcGFyc2VyLnNnbWxEZWNsICs9IGNcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnNnbWxEZWNsICs9IGNcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuU0dNTF9ERUNMX1FVT1RFRDpcbiAgICAgICAgICBpZiAoYyA9PT0gcGFyc2VyLnEpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuU0dNTF9ERUNMXG4gICAgICAgICAgICBwYXJzZXIucSA9ICcnXG4gICAgICAgICAgfVxuICAgICAgICAgIHBhcnNlci5zZ21sRGVjbCArPSBjXG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuRE9DVFlQRTpcbiAgICAgICAgICBpZiAoYyA9PT0gJz4nKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICAgIGVtaXROb2RlKHBhcnNlciwgJ29uZG9jdHlwZScsIHBhcnNlci5kb2N0eXBlKVxuICAgICAgICAgICAgcGFyc2VyLmRvY3R5cGUgPSB0cnVlIC8vIGp1c3QgcmVtZW1iZXIgdGhhdCB3ZSBzYXcgaXQuXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhcnNlci5kb2N0eXBlICs9IGNcbiAgICAgICAgICAgIGlmIChjID09PSAnWycpIHtcbiAgICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5ET0NUWVBFX0RURFxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc1F1b3RlKGMpKSB7XG4gICAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuRE9DVFlQRV9RVU9URURcbiAgICAgICAgICAgICAgcGFyc2VyLnEgPSBjXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkRPQ1RZUEVfUVVPVEVEOlxuICAgICAgICAgIHBhcnNlci5kb2N0eXBlICs9IGNcbiAgICAgICAgICBpZiAoYyA9PT0gcGFyc2VyLnEpIHtcbiAgICAgICAgICAgIHBhcnNlci5xID0gJydcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuRE9DVFlQRVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5ET0NUWVBFX0RURDpcbiAgICAgICAgICBwYXJzZXIuZG9jdHlwZSArPSBjXG4gICAgICAgICAgaWYgKGMgPT09ICddJykge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5ET0NUWVBFXG4gICAgICAgICAgfSBlbHNlIGlmIChpc1F1b3RlKGMpKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkRPQ1RZUEVfRFREX1FVT1RFRFxuICAgICAgICAgICAgcGFyc2VyLnEgPSBjXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkRPQ1RZUEVfRFREX1FVT1RFRDpcbiAgICAgICAgICBwYXJzZXIuZG9jdHlwZSArPSBjXG4gICAgICAgICAgaWYgKGMgPT09IHBhcnNlci5xKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkRPQ1RZUEVfRFREXG4gICAgICAgICAgICBwYXJzZXIucSA9ICcnXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkNPTU1FTlQ6XG4gICAgICAgICAgaWYgKGMgPT09ICctJykge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5DT01NRU5UX0VORElOR1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJzZXIuY29tbWVudCArPSBjXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkNPTU1FTlRfRU5ESU5HOlxuICAgICAgICAgIGlmIChjID09PSAnLScpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ09NTUVOVF9FTkRFRFxuICAgICAgICAgICAgcGFyc2VyLmNvbW1lbnQgPSB0ZXh0b3B0cyhwYXJzZXIub3B0LCBwYXJzZXIuY29tbWVudClcbiAgICAgICAgICAgIGlmIChwYXJzZXIuY29tbWVudCkge1xuICAgICAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbmNvbW1lbnQnLCBwYXJzZXIuY29tbWVudClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhcnNlci5jb21tZW50ID0gJydcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLmNvbW1lbnQgKz0gJy0nICsgY1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5DT01NRU5UXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkNPTU1FTlRfRU5ERUQ6XG4gICAgICAgICAgaWYgKGMgIT09ICc+Jykge1xuICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdNYWxmb3JtZWQgY29tbWVudCcpXG4gICAgICAgICAgICAvLyBhbGxvdyA8IS0tIGJsYWggLS0gYmxvbyAtLT4gaW4gbm9uLXN0cmljdCBtb2RlLFxuICAgICAgICAgICAgLy8gd2hpY2ggaXMgYSBjb21tZW50IG9mIFwiIGJsYWggLS0gYmxvbyBcIlxuICAgICAgICAgICAgcGFyc2VyLmNvbW1lbnQgKz0gJy0tJyArIGNcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ09NTUVOVFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuQ0RBVEE6XG4gICAgICAgICAgaWYgKGMgPT09ICddJykge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5DREFUQV9FTkRJTkdcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLmNkYXRhICs9IGNcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuQ0RBVEFfRU5ESU5HOlxuICAgICAgICAgIGlmIChjID09PSAnXScpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ0RBVEFfRU5ESU5HXzJcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLmNkYXRhICs9ICddJyArIGNcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ0RBVEFcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuQ0RBVEFfRU5ESU5HXzI6XG4gICAgICAgICAgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgaWYgKHBhcnNlci5jZGF0YSkge1xuICAgICAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbmNkYXRhJywgcGFyc2VyLmNkYXRhKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25jbG9zZWNkYXRhJylcbiAgICAgICAgICAgIHBhcnNlci5jZGF0YSA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICB9IGVsc2UgaWYgKGMgPT09ICddJykge1xuICAgICAgICAgICAgcGFyc2VyLmNkYXRhICs9ICddJ1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJzZXIuY2RhdGEgKz0gJ11dJyArIGNcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ0RBVEFcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuUFJPQ19JTlNUOlxuICAgICAgICAgIGlmIChjID09PSAnPycpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuUFJPQ19JTlNUX0VORElOR1xuICAgICAgICAgIH0gZWxzZSBpZiAoaXNXaGl0ZXNwYWNlKGMpKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlBST0NfSU5TVF9CT0RZXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhcnNlci5wcm9jSW5zdE5hbWUgKz0gY1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5QUk9DX0lOU1RfQk9EWTpcbiAgICAgICAgICBpZiAoIXBhcnNlci5wcm9jSW5zdEJvZHkgJiYgaXNXaGl0ZXNwYWNlKGMpKSB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gJz8nKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlBST0NfSU5TVF9FTkRJTkdcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnByb2NJbnN0Qm9keSArPSBjXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLlBST0NfSU5TVF9FTkRJTkc6XG4gICAgICAgICAgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24nLCB7XG4gICAgICAgICAgICAgIG5hbWU6IHBhcnNlci5wcm9jSW5zdE5hbWUsXG4gICAgICAgICAgICAgIGJvZHk6IHBhcnNlci5wcm9jSW5zdEJvZHlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBwYXJzZXIucHJvY0luc3ROYW1lID0gcGFyc2VyLnByb2NJbnN0Qm9keSA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnByb2NJbnN0Qm9keSArPSAnPycgKyBjXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlBST0NfSU5TVF9CT0RZXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLk9QRU5fVEFHOlxuICAgICAgICAgIGlmIChpc01hdGNoKG5hbWVCb2R5LCBjKSkge1xuICAgICAgICAgICAgcGFyc2VyLnRhZ05hbWUgKz0gY1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdUYWcocGFyc2VyKVxuICAgICAgICAgICAgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgICBvcGVuVGFnKHBhcnNlcilcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gJy8nKSB7XG4gICAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuT1BFTl9UQUdfU0xBU0hcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICghaXNXaGl0ZXNwYWNlKGMpKSB7XG4gICAgICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdJbnZhbGlkIGNoYXJhY3RlciBpbiB0YWcgbmFtZScpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuT1BFTl9UQUdfU0xBU0g6XG4gICAgICAgICAgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgb3BlblRhZyhwYXJzZXIsIHRydWUpXG4gICAgICAgICAgICBjbG9zZVRhZyhwYXJzZXIpXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnRm9yd2FyZC1zbGFzaCBpbiBvcGVuaW5nIHRhZyBub3QgZm9sbG93ZWQgYnkgPicpXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkFUVFJJQlxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5BVFRSSUI6XG4gICAgICAgICAgLy8gaGF2ZW4ndCByZWFkIHRoZSBhdHRyaWJ1dGUgbmFtZSB5ZXQuXG4gICAgICAgICAgaWYgKGlzV2hpdGVzcGFjZShjKSkge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9IGVsc2UgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgb3BlblRhZyhwYXJzZXIpXG4gICAgICAgICAgfSBlbHNlIGlmIChjID09PSAnLycpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuT1BFTl9UQUdfU0xBU0hcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzTWF0Y2gobmFtZVN0YXJ0LCBjKSkge1xuICAgICAgICAgICAgcGFyc2VyLmF0dHJpYk5hbWUgPSBjXG4gICAgICAgICAgICBwYXJzZXIuYXR0cmliVmFsdWUgPSAnJ1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJfTkFNRVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ0ludmFsaWQgYXR0cmlidXRlIG5hbWUnKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5BVFRSSUJfTkFNRTpcbiAgICAgICAgICBpZiAoYyA9PT0gJz0nKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkFUVFJJQl9WQUxVRVxuICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gJz4nKSB7XG4gICAgICAgICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ0F0dHJpYnV0ZSB3aXRob3V0IHZhbHVlJylcbiAgICAgICAgICAgIHBhcnNlci5hdHRyaWJWYWx1ZSA9IHBhcnNlci5hdHRyaWJOYW1lXG4gICAgICAgICAgICBhdHRyaWIocGFyc2VyKVxuICAgICAgICAgICAgb3BlblRhZyhwYXJzZXIpXG4gICAgICAgICAgfSBlbHNlIGlmIChpc1doaXRlc3BhY2UoYykpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQVRUUklCX05BTUVfU0FXX1dISVRFXG4gICAgICAgICAgfSBlbHNlIGlmIChpc01hdGNoKG5hbWVCb2R5LCBjKSkge1xuICAgICAgICAgICAgcGFyc2VyLmF0dHJpYk5hbWUgKz0gY1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ0ludmFsaWQgYXR0cmlidXRlIG5hbWUnKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5BVFRSSUJfTkFNRV9TQVdfV0hJVEU6XG4gICAgICAgICAgaWYgKGMgPT09ICc9Jykge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJfVkFMVUVcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzV2hpdGVzcGFjZShjKSkge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdBdHRyaWJ1dGUgd2l0aG91dCB2YWx1ZScpXG4gICAgICAgICAgICBwYXJzZXIudGFnLmF0dHJpYnV0ZXNbcGFyc2VyLmF0dHJpYk5hbWVdID0gJydcbiAgICAgICAgICAgIHBhcnNlci5hdHRyaWJWYWx1ZSA9ICcnXG4gICAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbmF0dHJpYnV0ZScsIHtcbiAgICAgICAgICAgICAgbmFtZTogcGFyc2VyLmF0dHJpYk5hbWUsXG4gICAgICAgICAgICAgIHZhbHVlOiAnJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHBhcnNlci5hdHRyaWJOYW1lID0gJydcbiAgICAgICAgICAgIGlmIChjID09PSAnPicpIHtcbiAgICAgICAgICAgICAgb3BlblRhZyhwYXJzZXIpXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzTWF0Y2gobmFtZVN0YXJ0LCBjKSkge1xuICAgICAgICAgICAgICBwYXJzZXIuYXR0cmliTmFtZSA9IGNcbiAgICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJfTkFNRVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdJbnZhbGlkIGF0dHJpYnV0ZSBuYW1lJylcbiAgICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuQVRUUklCX1ZBTFVFOlxuICAgICAgICAgIGlmIChpc1doaXRlc3BhY2UoYykpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfSBlbHNlIGlmIChpc1F1b3RlKGMpKSB7XG4gICAgICAgICAgICBwYXJzZXIucSA9IGNcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQVRUUklCX1ZBTFVFX1FVT1RFRFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ1VucXVvdGVkIGF0dHJpYnV0ZSB2YWx1ZScpXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkFUVFJJQl9WQUxVRV9VTlFVT1RFRFxuICAgICAgICAgICAgcGFyc2VyLmF0dHJpYlZhbHVlID0gY1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5BVFRSSUJfVkFMVUVfUVVPVEVEOlxuICAgICAgICAgIGlmIChjICE9PSBwYXJzZXIucSkge1xuICAgICAgICAgICAgaWYgKGMgPT09ICcmJykge1xuICAgICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkFUVFJJQl9WQUxVRV9FTlRJVFlfUVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcGFyc2VyLmF0dHJpYlZhbHVlICs9IGNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuICAgICAgICAgIGF0dHJpYihwYXJzZXIpXG4gICAgICAgICAgcGFyc2VyLnEgPSAnJ1xuICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQVRUUklCX1ZBTFVFX0NMT1NFRFxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkFUVFJJQl9WQUxVRV9DTE9TRUQ6XG4gICAgICAgICAgaWYgKGlzV2hpdGVzcGFjZShjKSkge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJcbiAgICAgICAgICB9IGVsc2UgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgb3BlblRhZyhwYXJzZXIpXG4gICAgICAgICAgfSBlbHNlIGlmIChjID09PSAnLycpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuT1BFTl9UQUdfU0xBU0hcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzTWF0Y2gobmFtZVN0YXJ0LCBjKSkge1xuICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdObyB3aGl0ZXNwYWNlIGJldHdlZW4gYXR0cmlidXRlcycpXG4gICAgICAgICAgICBwYXJzZXIuYXR0cmliTmFtZSA9IGNcbiAgICAgICAgICAgIHBhcnNlci5hdHRyaWJWYWx1ZSA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkFUVFJJQl9OQU1FXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnSW52YWxpZCBhdHRyaWJ1dGUgbmFtZScpXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkFUVFJJQl9WQUxVRV9VTlFVT1RFRDpcbiAgICAgICAgICBpZiAoIWlzQXR0cmliRW5kKGMpKSB7XG4gICAgICAgICAgICBpZiAoYyA9PT0gJyYnKSB7XG4gICAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQVRUUklCX1ZBTFVFX0VOVElUWV9VXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwYXJzZXIuYXR0cmliVmFsdWUgKz0gY1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG4gICAgICAgICAgYXR0cmliKHBhcnNlcilcbiAgICAgICAgICBpZiAoYyA9PT0gJz4nKSB7XG4gICAgICAgICAgICBvcGVuVGFnKHBhcnNlcilcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuQ0xPU0VfVEFHOlxuICAgICAgICAgIGlmICghcGFyc2VyLnRhZ05hbWUpIHtcbiAgICAgICAgICAgIGlmIChpc1doaXRlc3BhY2UoYykpIHtcbiAgICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobm90TWF0Y2gobmFtZVN0YXJ0LCBjKSkge1xuICAgICAgICAgICAgICBpZiAocGFyc2VyLnNjcmlwdCkge1xuICAgICAgICAgICAgICAgIHBhcnNlci5zY3JpcHQgKz0gJzwvJyArIGNcbiAgICAgICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlNDUklQVFxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnSW52YWxpZCB0YWduYW1lIGluIGNsb3NpbmcgdGFnLicpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHBhcnNlci50YWdOYW1lID0gY1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gJz4nKSB7XG4gICAgICAgICAgICBjbG9zZVRhZyhwYXJzZXIpXG4gICAgICAgICAgfSBlbHNlIGlmIChpc01hdGNoKG5hbWVCb2R5LCBjKSkge1xuICAgICAgICAgICAgcGFyc2VyLnRhZ05hbWUgKz0gY1xuICAgICAgICAgIH0gZWxzZSBpZiAocGFyc2VyLnNjcmlwdCkge1xuICAgICAgICAgICAgcGFyc2VyLnNjcmlwdCArPSAnPC8nICsgcGFyc2VyLnRhZ05hbWVcbiAgICAgICAgICAgIHBhcnNlci50YWdOYW1lID0gJydcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuU0NSSVBUXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaXNXaGl0ZXNwYWNlKGMpKSB7XG4gICAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnSW52YWxpZCB0YWduYW1lIGluIGNsb3NpbmcgdGFnJylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ0xPU0VfVEFHX1NBV19XSElURVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5DTE9TRV9UQUdfU0FXX1dISVRFOlxuICAgICAgICAgIGlmIChpc1doaXRlc3BhY2UoYykpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjID09PSAnPicpIHtcbiAgICAgICAgICAgIGNsb3NlVGFnKHBhcnNlcilcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdJbnZhbGlkIGNoYXJhY3RlcnMgaW4gY2xvc2luZyB0YWcnKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5URVhUX0VOVElUWTpcbiAgICAgICAgY2FzZSBTLkFUVFJJQl9WQUxVRV9FTlRJVFlfUTpcbiAgICAgICAgY2FzZSBTLkFUVFJJQl9WQUxVRV9FTlRJVFlfVTpcbiAgICAgICAgICB2YXIgcmV0dXJuU3RhdGVcbiAgICAgICAgICB2YXIgYnVmZmVyXG4gICAgICAgICAgc3dpdGNoIChwYXJzZXIuc3RhdGUpIHtcbiAgICAgICAgICAgIGNhc2UgUy5URVhUX0VOVElUWTpcbiAgICAgICAgICAgICAgcmV0dXJuU3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICAgICAgYnVmZmVyID0gJ3RleHROb2RlJ1xuICAgICAgICAgICAgICBicmVha1xuXG4gICAgICAgICAgICBjYXNlIFMuQVRUUklCX1ZBTFVFX0VOVElUWV9ROlxuICAgICAgICAgICAgICByZXR1cm5TdGF0ZSA9IFMuQVRUUklCX1ZBTFVFX1FVT1RFRFxuICAgICAgICAgICAgICBidWZmZXIgPSAnYXR0cmliVmFsdWUnXG4gICAgICAgICAgICAgIGJyZWFrXG5cbiAgICAgICAgICAgIGNhc2UgUy5BVFRSSUJfVkFMVUVfRU5USVRZX1U6XG4gICAgICAgICAgICAgIHJldHVyblN0YXRlID0gUy5BVFRSSUJfVkFMVUVfVU5RVU9URURcbiAgICAgICAgICAgICAgYnVmZmVyID0gJ2F0dHJpYlZhbHVlJ1xuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChjID09PSAnOycpIHtcbiAgICAgICAgICAgIHBhcnNlcltidWZmZXJdICs9IHBhcnNlRW50aXR5KHBhcnNlcilcbiAgICAgICAgICAgIHBhcnNlci5lbnRpdHkgPSAnJ1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gcmV0dXJuU3RhdGVcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzTWF0Y2gocGFyc2VyLmVudGl0eS5sZW5ndGggPyBlbnRpdHlCb2R5IDogZW50aXR5U3RhcnQsIGMpKSB7XG4gICAgICAgICAgICBwYXJzZXIuZW50aXR5ICs9IGNcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdJbnZhbGlkIGNoYXJhY3RlciBpbiBlbnRpdHkgbmFtZScpXG4gICAgICAgICAgICBwYXJzZXJbYnVmZmVyXSArPSAnJicgKyBwYXJzZXIuZW50aXR5ICsgY1xuICAgICAgICAgICAgcGFyc2VyLmVudGl0eSA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSByZXR1cm5TdGF0ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IocGFyc2VyLCAnVW5rbm93biBzdGF0ZTogJyArIHBhcnNlci5zdGF0ZSlcbiAgICAgIH1cbiAgICB9IC8vIHdoaWxlXG5cbiAgICBpZiAocGFyc2VyLnBvc2l0aW9uID49IHBhcnNlci5idWZmZXJDaGVja1Bvc2l0aW9uKSB7XG4gICAgICBjaGVja0J1ZmZlckxlbmd0aChwYXJzZXIpXG4gICAgfVxuICAgIHJldHVybiBwYXJzZXJcbiAgfVxuXG4gIC8qISBodHRwOi8vbXRocy5iZS9mcm9tY29kZXBvaW50IHYwLjEuMCBieSBAbWF0aGlhcyAqL1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAoIVN0cmluZy5mcm9tQ29kZVBvaW50KSB7XG4gICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBzdHJpbmdGcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlXG4gICAgICB2YXIgZmxvb3IgPSBNYXRoLmZsb29yXG4gICAgICB2YXIgZnJvbUNvZGVQb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIE1BWF9TSVpFID0gMHg0MDAwXG4gICAgICAgIHZhciBjb2RlVW5pdHMgPSBbXVxuICAgICAgICB2YXIgaGlnaFN1cnJvZ2F0ZVxuICAgICAgICB2YXIgbG93U3Vycm9nYXRlXG4gICAgICAgIHZhciBpbmRleCA9IC0xXG4gICAgICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoXG4gICAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuICcnXG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlc3VsdCA9ICcnXG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgdmFyIGNvZGVQb2ludCA9IE51bWJlcihhcmd1bWVudHNbaW5kZXhdKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFpc0Zpbml0ZShjb2RlUG9pbnQpIHx8IC8vIGBOYU5gLCBgK0luZmluaXR5YCwgb3IgYC1JbmZpbml0eWBcbiAgICAgICAgICAgIGNvZGVQb2ludCA8IDAgfHwgLy8gbm90IGEgdmFsaWQgVW5pY29kZSBjb2RlIHBvaW50XG4gICAgICAgICAgICBjb2RlUG9pbnQgPiAweDEwRkZGRiB8fCAvLyBub3QgYSB2YWxpZCBVbmljb2RlIGNvZGUgcG9pbnRcbiAgICAgICAgICAgIGZsb29yKGNvZGVQb2ludCkgIT09IGNvZGVQb2ludCAvLyBub3QgYW4gaW50ZWdlclxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcignSW52YWxpZCBjb2RlIHBvaW50OiAnICsgY29kZVBvaW50KVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY29kZVBvaW50IDw9IDB4RkZGRikgeyAvLyBCTVAgY29kZSBwb2ludFxuICAgICAgICAgICAgY29kZVVuaXRzLnB1c2goY29kZVBvaW50KVxuICAgICAgICAgIH0gZWxzZSB7IC8vIEFzdHJhbCBjb2RlIHBvaW50OyBzcGxpdCBpbiBzdXJyb2dhdGUgaGFsdmVzXG4gICAgICAgICAgICAvLyBodHRwOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9qYXZhc2NyaXB0LWVuY29kaW5nI3N1cnJvZ2F0ZS1mb3JtdWxhZVxuICAgICAgICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgICAgICAgIGhpZ2hTdXJyb2dhdGUgPSAoY29kZVBvaW50ID4+IDEwKSArIDB4RDgwMFxuICAgICAgICAgICAgbG93U3Vycm9nYXRlID0gKGNvZGVQb2ludCAlIDB4NDAwKSArIDB4REMwMFxuICAgICAgICAgICAgY29kZVVuaXRzLnB1c2goaGlnaFN1cnJvZ2F0ZSwgbG93U3Vycm9nYXRlKVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaW5kZXggKyAxID09PSBsZW5ndGggfHwgY29kZVVuaXRzLmxlbmd0aCA+IE1BWF9TSVpFKSB7XG4gICAgICAgICAgICByZXN1bHQgKz0gc3RyaW5nRnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGNvZGVVbml0cylcbiAgICAgICAgICAgIGNvZGVVbml0cy5sZW5ndGggPSAwXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgIH1cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTdHJpbmcsICdmcm9tQ29kZVBvaW50Jywge1xuICAgICAgICAgIHZhbHVlOiBmcm9tQ29kZVBvaW50LFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgU3RyaW5nLmZyb21Db2RlUG9pbnQgPSBmcm9tQ29kZVBvaW50XG4gICAgICB9XG4gICAgfSgpKVxuICB9XG59KSh0eXBlb2YgZXhwb3J0cyA9PT0gJ3VuZGVmaW5lZCcgPyB0aGlzLnNheCA9IHt9IDogZXhwb3J0cylcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuICBleHBvcnRzLnN0cmlwQk9NID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgaWYgKHN0clswXSA9PT0gJ1xcdUZFRkYnKSB7XG4gICAgICByZXR1cm4gc3RyLnN1YnN0cmluZygxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gIH07XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICBcInVzZSBzdHJpY3RcIjtcbiAgdmFyIGJ1aWxkZXIsIGRlZmF1bHRzLCBlc2NhcGVDREFUQSwgcmVxdWlyZXNDREFUQSwgd3JhcENEQVRBLFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBidWlsZGVyID0gcmVxdWlyZSgneG1sYnVpbGRlcicpO1xuXG4gIGRlZmF1bHRzID0gcmVxdWlyZSgnLi9kZWZhdWx0cycpLmRlZmF1bHRzO1xuXG4gIHJlcXVpcmVzQ0RBVEEgPSBmdW5jdGlvbihlbnRyeSkge1xuICAgIHJldHVybiB0eXBlb2YgZW50cnkgPT09IFwic3RyaW5nXCIgJiYgKGVudHJ5LmluZGV4T2YoJyYnKSA+PSAwIHx8IGVudHJ5LmluZGV4T2YoJz4nKSA+PSAwIHx8IGVudHJ5LmluZGV4T2YoJzwnKSA+PSAwKTtcbiAgfTtcblxuICB3cmFwQ0RBVEEgPSBmdW5jdGlvbihlbnRyeSkge1xuICAgIHJldHVybiBcIjwhW0NEQVRBW1wiICsgKGVzY2FwZUNEQVRBKGVudHJ5KSkgKyBcIl1dPlwiO1xuICB9O1xuXG4gIGVzY2FwZUNEQVRBID0gZnVuY3Rpb24oZW50cnkpIHtcbiAgICByZXR1cm4gZW50cnkucmVwbGFjZSgnXV0+JywgJ11dXV0+PCFbQ0RBVEFbPicpO1xuICB9O1xuXG4gIGV4cG9ydHMuQnVpbGRlciA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBCdWlsZGVyKG9wdHMpIHtcbiAgICAgIHZhciBrZXksIHJlZiwgdmFsdWU7XG4gICAgICB0aGlzLm9wdGlvbnMgPSB7fTtcbiAgICAgIHJlZiA9IGRlZmF1bHRzW1wiMC4yXCJdO1xuICAgICAgZm9yIChrZXkgaW4gcmVmKSB7XG4gICAgICAgIGlmICghaGFzUHJvcC5jYWxsKHJlZiwga2V5KSkgY29udGludWU7XG4gICAgICAgIHZhbHVlID0gcmVmW2tleV07XG4gICAgICAgIHRoaXMub3B0aW9uc1trZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBmb3IgKGtleSBpbiBvcHRzKSB7XG4gICAgICAgIGlmICghaGFzUHJvcC5jYWxsKG9wdHMsIGtleSkpIGNvbnRpbnVlO1xuICAgICAgICB2YWx1ZSA9IG9wdHNba2V5XTtcbiAgICAgICAgdGhpcy5vcHRpb25zW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBCdWlsZGVyLnByb3RvdHlwZS5idWlsZE9iamVjdCA9IGZ1bmN0aW9uKHJvb3RPYmopIHtcbiAgICAgIHZhciBhdHRya2V5LCBjaGFya2V5LCByZW5kZXIsIHJvb3RFbGVtZW50LCByb290TmFtZTtcbiAgICAgIGF0dHJrZXkgPSB0aGlzLm9wdGlvbnMuYXR0cmtleTtcbiAgICAgIGNoYXJrZXkgPSB0aGlzLm9wdGlvbnMuY2hhcmtleTtcbiAgICAgIGlmICgoT2JqZWN0LmtleXMocm9vdE9iaikubGVuZ3RoID09PSAxKSAmJiAodGhpcy5vcHRpb25zLnJvb3ROYW1lID09PSBkZWZhdWx0c1snMC4yJ10ucm9vdE5hbWUpKSB7XG4gICAgICAgIHJvb3ROYW1lID0gT2JqZWN0LmtleXMocm9vdE9iailbMF07XG4gICAgICAgIHJvb3RPYmogPSByb290T2JqW3Jvb3ROYW1lXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJvb3ROYW1lID0gdGhpcy5vcHRpb25zLnJvb3ROYW1lO1xuICAgICAgfVxuICAgICAgcmVuZGVyID0gKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBvYmopIHtcbiAgICAgICAgICB2YXIgYXR0ciwgY2hpbGQsIGVudHJ5LCBpbmRleCwga2V5LCB2YWx1ZTtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmIChfdGhpcy5vcHRpb25zLmNkYXRhICYmIHJlcXVpcmVzQ0RBVEEob2JqKSkge1xuICAgICAgICAgICAgICBlbGVtZW50LnJhdyh3cmFwQ0RBVEEob2JqKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBlbGVtZW50LnR4dChvYmopO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICBmb3IgKGluZGV4IGluIG9iaikge1xuICAgICAgICAgICAgICBpZiAoIWhhc1Byb3AuY2FsbChvYmosIGluZGV4KSkgY29udGludWU7XG4gICAgICAgICAgICAgIGNoaWxkID0gb2JqW2luZGV4XTtcbiAgICAgICAgICAgICAgZm9yIChrZXkgaW4gY2hpbGQpIHtcbiAgICAgICAgICAgICAgICBlbnRyeSA9IGNoaWxkW2tleV07XG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IHJlbmRlcihlbGVtZW50LmVsZShrZXkpLCBlbnRyeSkudXAoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgICAgICAgICAgaWYgKCFoYXNQcm9wLmNhbGwob2JqLCBrZXkpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgY2hpbGQgPSBvYmpba2V5XTtcbiAgICAgICAgICAgICAgaWYgKGtleSA9PT0gYXR0cmtleSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY2hpbGQgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICAgIGZvciAoYXR0ciBpbiBjaGlsZCkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGNoaWxkW2F0dHJdO1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5hdHQoYXR0ciwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09IGNoYXJrZXkpIHtcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy5jZGF0YSAmJiByZXF1aXJlc0NEQVRBKGNoaWxkKSkge1xuICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQucmF3KHdyYXBDREFUQShjaGlsZCkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudC50eHQoY2hpbGQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGNoaWxkKSkge1xuICAgICAgICAgICAgICAgIGZvciAoaW5kZXggaW4gY2hpbGQpIHtcbiAgICAgICAgICAgICAgICAgIGlmICghaGFzUHJvcC5jYWxsKGNoaWxkLCBpbmRleCkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgZW50cnkgPSBjaGlsZFtpbmRleF07XG4gICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGVudHJ5ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy5jZGF0YSAmJiByZXF1aXJlc0NEQVRBKGVudHJ5KSkge1xuICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LmVsZShrZXkpLnJhdyh3cmFwQ0RBVEEoZW50cnkpKS51cCgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LmVsZShrZXksIGVudHJ5KS51cCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gcmVuZGVyKGVsZW1lbnQuZWxlKGtleSksIGVudHJ5KS51cCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgY2hpbGQgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50ID0gcmVuZGVyKGVsZW1lbnQuZWxlKGtleSksIGNoaWxkKS51cCgpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY2hpbGQgPT09ICdzdHJpbmcnICYmIF90aGlzLm9wdGlvbnMuY2RhdGEgJiYgcmVxdWlyZXNDREFUQShjaGlsZCkpIHtcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LmVsZShrZXkpLnJhdyh3cmFwQ0RBVEEoY2hpbGQpKS51cCgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBpZiAoY2hpbGQgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBjaGlsZCA9ICcnO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQuZWxlKGtleSwgY2hpbGQudG9TdHJpbmcoKSkudXAoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKTtcbiAgICAgIHJvb3RFbGVtZW50ID0gYnVpbGRlci5jcmVhdGUocm9vdE5hbWUsIHRoaXMub3B0aW9ucy54bWxkZWMsIHRoaXMub3B0aW9ucy5kb2N0eXBlLCB7XG4gICAgICAgIGhlYWRsZXNzOiB0aGlzLm9wdGlvbnMuaGVhZGxlc3MsXG4gICAgICAgIGFsbG93U3Vycm9nYXRlQ2hhcnM6IHRoaXMub3B0aW9ucy5hbGxvd1N1cnJvZ2F0ZUNoYXJzXG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZW5kZXIocm9vdEVsZW1lbnQsIHJvb3RPYmopLmVuZCh0aGlzLm9wdGlvbnMucmVuZGVyT3B0cyk7XG4gICAgfTtcblxuICAgIHJldHVybiBCdWlsZGVyO1xuXG4gIH0pKCk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICBleHBvcnRzLmRlZmF1bHRzID0ge1xuICAgIFwiMC4xXCI6IHtcbiAgICAgIGV4cGxpY2l0Q2hhcmtleTogZmFsc2UsXG4gICAgICB0cmltOiB0cnVlLFxuICAgICAgbm9ybWFsaXplOiB0cnVlLFxuICAgICAgbm9ybWFsaXplVGFnczogZmFsc2UsXG4gICAgICBhdHRya2V5OiBcIkBcIixcbiAgICAgIGNoYXJrZXk6IFwiI1wiLFxuICAgICAgZXhwbGljaXRBcnJheTogZmFsc2UsXG4gICAgICBpZ25vcmVBdHRyczogZmFsc2UsXG4gICAgICBtZXJnZUF0dHJzOiBmYWxzZSxcbiAgICAgIGV4cGxpY2l0Um9vdDogZmFsc2UsXG4gICAgICB2YWxpZGF0b3I6IG51bGwsXG4gICAgICB4bWxuczogZmFsc2UsXG4gICAgICBleHBsaWNpdENoaWxkcmVuOiBmYWxzZSxcbiAgICAgIGNoaWxka2V5OiAnQEAnLFxuICAgICAgY2hhcnNBc0NoaWxkcmVuOiBmYWxzZSxcbiAgICAgIGluY2x1ZGVXaGl0ZUNoYXJzOiBmYWxzZSxcbiAgICAgIGFzeW5jOiBmYWxzZSxcbiAgICAgIHN0cmljdDogdHJ1ZSxcbiAgICAgIGF0dHJOYW1lUHJvY2Vzc29yczogbnVsbCxcbiAgICAgIGF0dHJWYWx1ZVByb2Nlc3NvcnM6IG51bGwsXG4gICAgICB0YWdOYW1lUHJvY2Vzc29yczogbnVsbCxcbiAgICAgIHZhbHVlUHJvY2Vzc29yczogbnVsbCxcbiAgICAgIGVtcHR5VGFnOiAnJ1xuICAgIH0sXG4gICAgXCIwLjJcIjoge1xuICAgICAgZXhwbGljaXRDaGFya2V5OiBmYWxzZSxcbiAgICAgIHRyaW06IGZhbHNlLFxuICAgICAgbm9ybWFsaXplOiBmYWxzZSxcbiAgICAgIG5vcm1hbGl6ZVRhZ3M6IGZhbHNlLFxuICAgICAgYXR0cmtleTogXCIkXCIsXG4gICAgICBjaGFya2V5OiBcIl9cIixcbiAgICAgIGV4cGxpY2l0QXJyYXk6IHRydWUsXG4gICAgICBpZ25vcmVBdHRyczogZmFsc2UsXG4gICAgICBtZXJnZUF0dHJzOiBmYWxzZSxcbiAgICAgIGV4cGxpY2l0Um9vdDogdHJ1ZSxcbiAgICAgIHZhbGlkYXRvcjogbnVsbCxcbiAgICAgIHhtbG5zOiBmYWxzZSxcbiAgICAgIGV4cGxpY2l0Q2hpbGRyZW46IGZhbHNlLFxuICAgICAgcHJlc2VydmVDaGlsZHJlbk9yZGVyOiBmYWxzZSxcbiAgICAgIGNoaWxka2V5OiAnJCQnLFxuICAgICAgY2hhcnNBc0NoaWxkcmVuOiBmYWxzZSxcbiAgICAgIGluY2x1ZGVXaGl0ZUNoYXJzOiBmYWxzZSxcbiAgICAgIGFzeW5jOiBmYWxzZSxcbiAgICAgIHN0cmljdDogdHJ1ZSxcbiAgICAgIGF0dHJOYW1lUHJvY2Vzc29yczogbnVsbCxcbiAgICAgIGF0dHJWYWx1ZVByb2Nlc3NvcnM6IG51bGwsXG4gICAgICB0YWdOYW1lUHJvY2Vzc29yczogbnVsbCxcbiAgICAgIHZhbHVlUHJvY2Vzc29yczogbnVsbCxcbiAgICAgIHJvb3ROYW1lOiAncm9vdCcsXG4gICAgICB4bWxkZWM6IHtcbiAgICAgICAgJ3ZlcnNpb24nOiAnMS4wJyxcbiAgICAgICAgJ2VuY29kaW5nJzogJ1VURi04JyxcbiAgICAgICAgJ3N0YW5kYWxvbmUnOiB0cnVlXG4gICAgICB9LFxuICAgICAgZG9jdHlwZTogbnVsbCxcbiAgICAgIHJlbmRlck9wdHM6IHtcbiAgICAgICAgJ3ByZXR0eSc6IHRydWUsXG4gICAgICAgICdpbmRlbnQnOiAnICAnLFxuICAgICAgICAnbmV3bGluZSc6ICdcXG4nXG4gICAgICB9LFxuICAgICAgaGVhZGxlc3M6IGZhbHNlLFxuICAgICAgY2h1bmtTaXplOiAxMDAwMCxcbiAgICAgIGVtcHR5VGFnOiAnJyxcbiAgICAgIGNkYXRhOiBmYWxzZVxuICAgIH1cbiAgfTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuICB2YXIgYm9tLCBkZWZhdWx0cywgZXZlbnRzLCBpc0VtcHR5LCBwcm9jZXNzSXRlbSwgcHJvY2Vzc29ycywgc2F4LCBzZXRJbW1lZGlhdGUsXG4gICAgYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBzYXggPSByZXF1aXJlKCdzYXgnKTtcblxuICBldmVudHMgPSByZXF1aXJlKCdldmVudHMnKTtcblxuICBib20gPSByZXF1aXJlKCcuL2JvbScpO1xuXG4gIHByb2Nlc3NvcnMgPSByZXF1aXJlKCcuL3Byb2Nlc3NvcnMnKTtcblxuICBzZXRJbW1lZGlhdGUgPSByZXF1aXJlKCd0aW1lcnMnKS5zZXRJbW1lZGlhdGU7XG5cbiAgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2RlZmF1bHRzJykuZGVmYXVsdHM7XG5cbiAgaXNFbXB0eSA9IGZ1bmN0aW9uKHRoaW5nKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gXCJvYmplY3RcIiAmJiAodGhpbmcgIT0gbnVsbCkgJiYgT2JqZWN0LmtleXModGhpbmcpLmxlbmd0aCA9PT0gMDtcbiAgfTtcblxuICBwcm9jZXNzSXRlbSA9IGZ1bmN0aW9uKHByb2Nlc3NvcnMsIGl0ZW0sIGtleSkge1xuICAgIHZhciBpLCBsZW4sIHByb2Nlc3M7XG4gICAgZm9yIChpID0gMCwgbGVuID0gcHJvY2Vzc29ycy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgcHJvY2VzcyA9IHByb2Nlc3NvcnNbaV07XG4gICAgICBpdGVtID0gcHJvY2VzcyhpdGVtLCBrZXkpO1xuICAgIH1cbiAgICByZXR1cm4gaXRlbTtcbiAgfTtcblxuICBleHBvcnRzLlBhcnNlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFBhcnNlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBQYXJzZXIob3B0cykge1xuICAgICAgdGhpcy5wYXJzZVN0cmluZ1Byb21pc2UgPSBiaW5kKHRoaXMucGFyc2VTdHJpbmdQcm9taXNlLCB0aGlzKTtcbiAgICAgIHRoaXMucGFyc2VTdHJpbmcgPSBiaW5kKHRoaXMucGFyc2VTdHJpbmcsIHRoaXMpO1xuICAgICAgdGhpcy5yZXNldCA9IGJpbmQodGhpcy5yZXNldCwgdGhpcyk7XG4gICAgICB0aGlzLmFzc2lnbk9yUHVzaCA9IGJpbmQodGhpcy5hc3NpZ25PclB1c2gsIHRoaXMpO1xuICAgICAgdGhpcy5wcm9jZXNzQXN5bmMgPSBiaW5kKHRoaXMucHJvY2Vzc0FzeW5jLCB0aGlzKTtcbiAgICAgIHZhciBrZXksIHJlZiwgdmFsdWU7XG4gICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgZXhwb3J0cy5QYXJzZXIpKSB7XG4gICAgICAgIHJldHVybiBuZXcgZXhwb3J0cy5QYXJzZXIob3B0cyk7XG4gICAgICB9XG4gICAgICB0aGlzLm9wdGlvbnMgPSB7fTtcbiAgICAgIHJlZiA9IGRlZmF1bHRzW1wiMC4yXCJdO1xuICAgICAgZm9yIChrZXkgaW4gcmVmKSB7XG4gICAgICAgIGlmICghaGFzUHJvcC5jYWxsKHJlZiwga2V5KSkgY29udGludWU7XG4gICAgICAgIHZhbHVlID0gcmVmW2tleV07XG4gICAgICAgIHRoaXMub3B0aW9uc1trZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBmb3IgKGtleSBpbiBvcHRzKSB7XG4gICAgICAgIGlmICghaGFzUHJvcC5jYWxsKG9wdHMsIGtleSkpIGNvbnRpbnVlO1xuICAgICAgICB2YWx1ZSA9IG9wdHNba2V5XTtcbiAgICAgICAgdGhpcy5vcHRpb25zW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm9wdGlvbnMueG1sbnMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zLnhtbG5za2V5ID0gdGhpcy5vcHRpb25zLmF0dHJrZXkgKyBcIm5zXCI7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm5vcm1hbGl6ZVRhZ3MpIHtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMudGFnTmFtZVByb2Nlc3NvcnMpIHtcbiAgICAgICAgICB0aGlzLm9wdGlvbnMudGFnTmFtZVByb2Nlc3NvcnMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wdGlvbnMudGFnTmFtZVByb2Nlc3NvcnMudW5zaGlmdChwcm9jZXNzb3JzLm5vcm1hbGl6ZSk7XG4gICAgICB9XG4gICAgICB0aGlzLnJlc2V0KCk7XG4gICAgfVxuXG4gICAgUGFyc2VyLnByb3RvdHlwZS5wcm9jZXNzQXN5bmMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjaHVuaywgZXJyO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHRoaXMucmVtYWluaW5nLmxlbmd0aCA8PSB0aGlzLm9wdGlvbnMuY2h1bmtTaXplKSB7XG4gICAgICAgICAgY2h1bmsgPSB0aGlzLnJlbWFpbmluZztcbiAgICAgICAgICB0aGlzLnJlbWFpbmluZyA9ICcnO1xuICAgICAgICAgIHRoaXMuc2F4UGFyc2VyID0gdGhpcy5zYXhQYXJzZXIud3JpdGUoY2h1bmspO1xuICAgICAgICAgIHJldHVybiB0aGlzLnNheFBhcnNlci5jbG9zZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNodW5rID0gdGhpcy5yZW1haW5pbmcuc3Vic3RyKDAsIHRoaXMub3B0aW9ucy5jaHVua1NpemUpO1xuICAgICAgICAgIHRoaXMucmVtYWluaW5nID0gdGhpcy5yZW1haW5pbmcuc3Vic3RyKHRoaXMub3B0aW9ucy5jaHVua1NpemUsIHRoaXMucmVtYWluaW5nLmxlbmd0aCk7XG4gICAgICAgICAgdGhpcy5zYXhQYXJzZXIgPSB0aGlzLnNheFBhcnNlci53cml0ZShjaHVuayk7XG4gICAgICAgICAgcmV0dXJuIHNldEltbWVkaWF0ZSh0aGlzLnByb2Nlc3NBc3luYyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yMSkge1xuICAgICAgICBlcnIgPSBlcnJvcjE7XG4gICAgICAgIGlmICghdGhpcy5zYXhQYXJzZXIuZXJyVGhyb3duKSB7XG4gICAgICAgICAgdGhpcy5zYXhQYXJzZXIuZXJyVGhyb3duID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KGVycik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgUGFyc2VyLnByb3RvdHlwZS5hc3NpZ25PclB1c2ggPSBmdW5jdGlvbihvYmosIGtleSwgbmV3VmFsdWUpIHtcbiAgICAgIGlmICghKGtleSBpbiBvYmopKSB7XG4gICAgICAgIGlmICghdGhpcy5vcHRpb25zLmV4cGxpY2l0QXJyYXkpIHtcbiAgICAgICAgICByZXR1cm4gb2JqW2tleV0gPSBuZXdWYWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gb2JqW2tleV0gPSBbbmV3VmFsdWVdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIShvYmpba2V5XSBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgIG9ialtrZXldID0gW29ialtrZXldXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqW2tleV0ucHVzaChuZXdWYWx1ZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFBhcnNlci5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhdHRya2V5LCBjaGFya2V5LCBvbnRleHQsIHN0YWNrO1xuICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICAgIHRoaXMuc2F4UGFyc2VyID0gc2F4LnBhcnNlcih0aGlzLm9wdGlvbnMuc3RyaWN0LCB7XG4gICAgICAgIHRyaW06IGZhbHNlLFxuICAgICAgICBub3JtYWxpemU6IGZhbHNlLFxuICAgICAgICB4bWxuczogdGhpcy5vcHRpb25zLnhtbG5zXG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2F4UGFyc2VyLmVyclRocm93biA9IGZhbHNlO1xuICAgICAgdGhpcy5zYXhQYXJzZXIub25lcnJvciA9IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZXJyb3IpIHtcbiAgICAgICAgICBfdGhpcy5zYXhQYXJzZXIucmVzdW1lKCk7XG4gICAgICAgICAgaWYgKCFfdGhpcy5zYXhQYXJzZXIuZXJyVGhyb3duKSB7XG4gICAgICAgICAgICBfdGhpcy5zYXhQYXJzZXIuZXJyVGhyb3duID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KFwiZXJyb3JcIiwgZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpO1xuICAgICAgdGhpcy5zYXhQYXJzZXIub25lbmQgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGlmICghX3RoaXMuc2F4UGFyc2VyLmVuZGVkKSB7XG4gICAgICAgICAgICBfdGhpcy5zYXhQYXJzZXIuZW5kZWQgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoXCJlbmRcIiwgX3RoaXMucmVzdWx0T2JqZWN0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKTtcbiAgICAgIHRoaXMuc2F4UGFyc2VyLmVuZGVkID0gZmFsc2U7XG4gICAgICB0aGlzLkVYUExJQ0lUX0NIQVJLRVkgPSB0aGlzLm9wdGlvbnMuZXhwbGljaXRDaGFya2V5O1xuICAgICAgdGhpcy5yZXN1bHRPYmplY3QgPSBudWxsO1xuICAgICAgc3RhY2sgPSBbXTtcbiAgICAgIGF0dHJrZXkgPSB0aGlzLm9wdGlvbnMuYXR0cmtleTtcbiAgICAgIGNoYXJrZXkgPSB0aGlzLm9wdGlvbnMuY2hhcmtleTtcbiAgICAgIHRoaXMuc2F4UGFyc2VyLm9ub3BlbnRhZyA9IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24obm9kZSkge1xuICAgICAgICAgIHZhciBrZXksIG5ld1ZhbHVlLCBvYmosIHByb2Nlc3NlZEtleSwgcmVmO1xuICAgICAgICAgIG9iaiA9IHt9O1xuICAgICAgICAgIG9ialtjaGFya2V5XSA9IFwiXCI7XG4gICAgICAgICAgaWYgKCFfdGhpcy5vcHRpb25zLmlnbm9yZUF0dHJzKSB7XG4gICAgICAgICAgICByZWYgPSBub2RlLmF0dHJpYnV0ZXM7XG4gICAgICAgICAgICBmb3IgKGtleSBpbiByZWYpIHtcbiAgICAgICAgICAgICAgaWYgKCFoYXNQcm9wLmNhbGwocmVmLCBrZXkpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgaWYgKCEoYXR0cmtleSBpbiBvYmopICYmICFfdGhpcy5vcHRpb25zLm1lcmdlQXR0cnMpIHtcbiAgICAgICAgICAgICAgICBvYmpbYXR0cmtleV0gPSB7fTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBuZXdWYWx1ZSA9IF90aGlzLm9wdGlvbnMuYXR0clZhbHVlUHJvY2Vzc29ycyA/IHByb2Nlc3NJdGVtKF90aGlzLm9wdGlvbnMuYXR0clZhbHVlUHJvY2Vzc29ycywgbm9kZS5hdHRyaWJ1dGVzW2tleV0sIGtleSkgOiBub2RlLmF0dHJpYnV0ZXNba2V5XTtcbiAgICAgICAgICAgICAgcHJvY2Vzc2VkS2V5ID0gX3RoaXMub3B0aW9ucy5hdHRyTmFtZVByb2Nlc3NvcnMgPyBwcm9jZXNzSXRlbShfdGhpcy5vcHRpb25zLmF0dHJOYW1lUHJvY2Vzc29ycywga2V5KSA6IGtleTtcbiAgICAgICAgICAgICAgaWYgKF90aGlzLm9wdGlvbnMubWVyZ2VBdHRycykge1xuICAgICAgICAgICAgICAgIF90aGlzLmFzc2lnbk9yUHVzaChvYmosIHByb2Nlc3NlZEtleSwgbmV3VmFsdWUpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG9ialthdHRya2V5XVtwcm9jZXNzZWRLZXldID0gbmV3VmFsdWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgb2JqW1wiI25hbWVcIl0gPSBfdGhpcy5vcHRpb25zLnRhZ05hbWVQcm9jZXNzb3JzID8gcHJvY2Vzc0l0ZW0oX3RoaXMub3B0aW9ucy50YWdOYW1lUHJvY2Vzc29ycywgbm9kZS5uYW1lKSA6IG5vZGUubmFtZTtcbiAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy54bWxucykge1xuICAgICAgICAgICAgb2JqW190aGlzLm9wdGlvbnMueG1sbnNrZXldID0ge1xuICAgICAgICAgICAgICB1cmk6IG5vZGUudXJpLFxuICAgICAgICAgICAgICBsb2NhbDogbm9kZS5sb2NhbFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHN0YWNrLnB1c2gob2JqKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpO1xuICAgICAgdGhpcy5zYXhQYXJzZXIub25jbG9zZXRhZyA9IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdmFyIGNkYXRhLCBlbXB0eVN0ciwga2V5LCBub2RlLCBub2RlTmFtZSwgb2JqLCBvYmpDbG9uZSwgb2xkLCBzLCB4cGF0aDtcbiAgICAgICAgICBvYmogPSBzdGFjay5wb3AoKTtcbiAgICAgICAgICBub2RlTmFtZSA9IG9ialtcIiNuYW1lXCJdO1xuICAgICAgICAgIGlmICghX3RoaXMub3B0aW9ucy5leHBsaWNpdENoaWxkcmVuIHx8ICFfdGhpcy5vcHRpb25zLnByZXNlcnZlQ2hpbGRyZW5PcmRlcikge1xuICAgICAgICAgICAgZGVsZXRlIG9ialtcIiNuYW1lXCJdO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAob2JqLmNkYXRhID09PSB0cnVlKSB7XG4gICAgICAgICAgICBjZGF0YSA9IG9iai5jZGF0YTtcbiAgICAgICAgICAgIGRlbGV0ZSBvYmouY2RhdGE7XG4gICAgICAgICAgfVxuICAgICAgICAgIHMgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXTtcbiAgICAgICAgICBpZiAob2JqW2NoYXJrZXldLm1hdGNoKC9eXFxzKiQvKSAmJiAhY2RhdGEpIHtcbiAgICAgICAgICAgIGVtcHR5U3RyID0gb2JqW2NoYXJrZXldO1xuICAgICAgICAgICAgZGVsZXRlIG9ialtjaGFya2V5XTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKF90aGlzLm9wdGlvbnMudHJpbSkge1xuICAgICAgICAgICAgICBvYmpbY2hhcmtleV0gPSBvYmpbY2hhcmtleV0udHJpbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKF90aGlzLm9wdGlvbnMubm9ybWFsaXplKSB7XG4gICAgICAgICAgICAgIG9ialtjaGFya2V5XSA9IG9ialtjaGFya2V5XS5yZXBsYWNlKC9cXHN7Mix9L2csIFwiIFwiKS50cmltKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvYmpbY2hhcmtleV0gPSBfdGhpcy5vcHRpb25zLnZhbHVlUHJvY2Vzc29ycyA/IHByb2Nlc3NJdGVtKF90aGlzLm9wdGlvbnMudmFsdWVQcm9jZXNzb3JzLCBvYmpbY2hhcmtleV0sIG5vZGVOYW1lKSA6IG9ialtjaGFya2V5XTtcbiAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyhvYmopLmxlbmd0aCA9PT0gMSAmJiBjaGFya2V5IGluIG9iaiAmJiAhX3RoaXMuRVhQTElDSVRfQ0hBUktFWSkge1xuICAgICAgICAgICAgICBvYmogPSBvYmpbY2hhcmtleV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChpc0VtcHR5KG9iaikpIHtcbiAgICAgICAgICAgIG9iaiA9IF90aGlzLm9wdGlvbnMuZW1wdHlUYWcgIT09ICcnID8gX3RoaXMub3B0aW9ucy5lbXB0eVRhZyA6IGVtcHR5U3RyO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy52YWxpZGF0b3IgIT0gbnVsbCkge1xuICAgICAgICAgICAgeHBhdGggPSBcIi9cIiArICgoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHZhciBpLCBsZW4sIHJlc3VsdHM7XG4gICAgICAgICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gc3RhY2subGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBub2RlID0gc3RhY2tbaV07XG4gICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKG5vZGVbXCIjbmFtZVwiXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICAgICAgICB9KSgpKS5jb25jYXQobm9kZU5hbWUpLmpvaW4oXCIvXCIpO1xuICAgICAgICAgICAgKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICB2YXIgZXJyO1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvYmogPSBfdGhpcy5vcHRpb25zLnZhbGlkYXRvcih4cGF0aCwgcyAmJiBzW25vZGVOYW1lXSwgb2JqKTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IxKSB7XG4gICAgICAgICAgICAgICAgZXJyID0gZXJyb3IxO1xuICAgICAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KFwiZXJyb3JcIiwgZXJyKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKF90aGlzLm9wdGlvbnMuZXhwbGljaXRDaGlsZHJlbiAmJiAhX3RoaXMub3B0aW9ucy5tZXJnZUF0dHJzICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBpZiAoIV90aGlzLm9wdGlvbnMucHJlc2VydmVDaGlsZHJlbk9yZGVyKSB7XG4gICAgICAgICAgICAgIG5vZGUgPSB7fTtcbiAgICAgICAgICAgICAgaWYgKF90aGlzLm9wdGlvbnMuYXR0cmtleSBpbiBvYmopIHtcbiAgICAgICAgICAgICAgICBub2RlW190aGlzLm9wdGlvbnMuYXR0cmtleV0gPSBvYmpbX3RoaXMub3B0aW9ucy5hdHRya2V5XTtcbiAgICAgICAgICAgICAgICBkZWxldGUgb2JqW190aGlzLm9wdGlvbnMuYXR0cmtleV07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKCFfdGhpcy5vcHRpb25zLmNoYXJzQXNDaGlsZHJlbiAmJiBfdGhpcy5vcHRpb25zLmNoYXJrZXkgaW4gb2JqKSB7XG4gICAgICAgICAgICAgICAgbm9kZVtfdGhpcy5vcHRpb25zLmNoYXJrZXldID0gb2JqW190aGlzLm9wdGlvbnMuY2hhcmtleV07XG4gICAgICAgICAgICAgICAgZGVsZXRlIG9ialtfdGhpcy5vcHRpb25zLmNoYXJrZXldO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBub2RlW190aGlzLm9wdGlvbnMuY2hpbGRrZXldID0gb2JqO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIG9iaiA9IG5vZGU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHMpIHtcbiAgICAgICAgICAgICAgc1tfdGhpcy5vcHRpb25zLmNoaWxka2V5XSA9IHNbX3RoaXMub3B0aW9ucy5jaGlsZGtleV0gfHwgW107XG4gICAgICAgICAgICAgIG9iakNsb25lID0ge307XG4gICAgICAgICAgICAgIGZvciAoa2V5IGluIG9iaikge1xuICAgICAgICAgICAgICAgIGlmICghaGFzUHJvcC5jYWxsKG9iaiwga2V5KSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgb2JqQ2xvbmVba2V5XSA9IG9ialtrZXldO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHNbX3RoaXMub3B0aW9ucy5jaGlsZGtleV0ucHVzaChvYmpDbG9uZSk7XG4gICAgICAgICAgICAgIGRlbGV0ZSBvYmpbXCIjbmFtZVwiXTtcbiAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKG9iaikubGVuZ3RoID09PSAxICYmIGNoYXJrZXkgaW4gb2JqICYmICFfdGhpcy5FWFBMSUNJVF9DSEFSS0VZKSB7XG4gICAgICAgICAgICAgICAgb2JqID0gb2JqW2NoYXJrZXldO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzdGFjay5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuYXNzaWduT3JQdXNoKHMsIG5vZGVOYW1lLCBvYmopO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy5leHBsaWNpdFJvb3QpIHtcbiAgICAgICAgICAgICAgb2xkID0gb2JqO1xuICAgICAgICAgICAgICBvYmogPSB7fTtcbiAgICAgICAgICAgICAgb2JqW25vZGVOYW1lXSA9IG9sZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF90aGlzLnJlc3VsdE9iamVjdCA9IG9iajtcbiAgICAgICAgICAgIF90aGlzLnNheFBhcnNlci5lbmRlZCA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdChcImVuZFwiLCBfdGhpcy5yZXN1bHRPYmplY3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpO1xuICAgICAgb250ZXh0ID0gKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbih0ZXh0KSB7XG4gICAgICAgICAgdmFyIGNoYXJDaGlsZCwgcztcbiAgICAgICAgICBzID0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV07XG4gICAgICAgICAgaWYgKHMpIHtcbiAgICAgICAgICAgIHNbY2hhcmtleV0gKz0gdGV4dDtcbiAgICAgICAgICAgIGlmIChfdGhpcy5vcHRpb25zLmV4cGxpY2l0Q2hpbGRyZW4gJiYgX3RoaXMub3B0aW9ucy5wcmVzZXJ2ZUNoaWxkcmVuT3JkZXIgJiYgX3RoaXMub3B0aW9ucy5jaGFyc0FzQ2hpbGRyZW4gJiYgKF90aGlzLm9wdGlvbnMuaW5jbHVkZVdoaXRlQ2hhcnMgfHwgdGV4dC5yZXBsYWNlKC9cXFxcbi9nLCAnJykudHJpbSgpICE9PSAnJykpIHtcbiAgICAgICAgICAgICAgc1tfdGhpcy5vcHRpb25zLmNoaWxka2V5XSA9IHNbX3RoaXMub3B0aW9ucy5jaGlsZGtleV0gfHwgW107XG4gICAgICAgICAgICAgIGNoYXJDaGlsZCA9IHtcbiAgICAgICAgICAgICAgICAnI25hbWUnOiAnX190ZXh0X18nXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIGNoYXJDaGlsZFtjaGFya2V5XSA9IHRleHQ7XG4gICAgICAgICAgICAgIGlmIChfdGhpcy5vcHRpb25zLm5vcm1hbGl6ZSkge1xuICAgICAgICAgICAgICAgIGNoYXJDaGlsZFtjaGFya2V5XSA9IGNoYXJDaGlsZFtjaGFya2V5XS5yZXBsYWNlKC9cXHN7Mix9L2csIFwiIFwiKS50cmltKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc1tfdGhpcy5vcHRpb25zLmNoaWxka2V5XS5wdXNoKGNoYXJDaGlsZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcztcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKTtcbiAgICAgIHRoaXMuc2F4UGFyc2VyLm9udGV4dCA9IG9udGV4dDtcbiAgICAgIHJldHVybiB0aGlzLnNheFBhcnNlci5vbmNkYXRhID0gKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbih0ZXh0KSB7XG4gICAgICAgICAgdmFyIHM7XG4gICAgICAgICAgcyA9IG9udGV4dCh0ZXh0KTtcbiAgICAgICAgICBpZiAocykge1xuICAgICAgICAgICAgcmV0dXJuIHMuY2RhdGEgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpO1xuICAgIH07XG5cbiAgICBQYXJzZXIucHJvdG90eXBlLnBhcnNlU3RyaW5nID0gZnVuY3Rpb24oc3RyLCBjYikge1xuICAgICAgdmFyIGVycjtcbiAgICAgIGlmICgoY2IgIT0gbnVsbCkgJiYgdHlwZW9mIGNiID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhpcy5vbihcImVuZFwiLCBmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgICAgICAgcmV0dXJuIGNiKG51bGwsIHJlc3VsdCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9uKFwiZXJyb3JcIiwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICAgIHJldHVybiBjYihlcnIpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIHN0ciA9IHN0ci50b1N0cmluZygpO1xuICAgICAgICBpZiAoc3RyLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgICAgICB0aGlzLmVtaXQoXCJlbmRcIiwgbnVsbCk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgc3RyID0gYm9tLnN0cmlwQk9NKHN0cik7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYXN5bmMpIHtcbiAgICAgICAgICB0aGlzLnJlbWFpbmluZyA9IHN0cjtcbiAgICAgICAgICBzZXRJbW1lZGlhdGUodGhpcy5wcm9jZXNzQXN5bmMpO1xuICAgICAgICAgIHJldHVybiB0aGlzLnNheFBhcnNlcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5zYXhQYXJzZXIud3JpdGUoc3RyKS5jbG9zZSgpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IxKSB7XG4gICAgICAgIGVyciA9IGVycm9yMTtcbiAgICAgICAgaWYgKCEodGhpcy5zYXhQYXJzZXIuZXJyVGhyb3duIHx8IHRoaXMuc2F4UGFyc2VyLmVuZGVkKSkge1xuICAgICAgICAgIHRoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgICAgICAgIHJldHVybiB0aGlzLnNheFBhcnNlci5lcnJUaHJvd24gPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc2F4UGFyc2VyLmVuZGVkKSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIFBhcnNlci5wcm90b3R5cGUucGFyc2VTdHJpbmdQcm9taXNlID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICByZXR1cm4gX3RoaXMucGFyc2VTdHJpbmcoc3RyLCBmdW5jdGlvbihlcnIsIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFBhcnNlcjtcblxuICB9KShldmVudHMpO1xuXG4gIGV4cG9ydHMucGFyc2VTdHJpbmcgPSBmdW5jdGlvbihzdHIsIGEsIGIpIHtcbiAgICB2YXIgY2IsIG9wdGlvbnMsIHBhcnNlcjtcbiAgICBpZiAoYiAhPSBudWxsKSB7XG4gICAgICBpZiAodHlwZW9mIGIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY2IgPSBiO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBhID09PSAnb2JqZWN0Jykge1xuICAgICAgICBvcHRpb25zID0gYTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBhID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNiID0gYTtcbiAgICAgIH1cbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG4gICAgcGFyc2VyID0gbmV3IGV4cG9ydHMuUGFyc2VyKG9wdGlvbnMpO1xuICAgIHJldHVybiBwYXJzZXIucGFyc2VTdHJpbmcoc3RyLCBjYik7XG4gIH07XG5cbiAgZXhwb3J0cy5wYXJzZVN0cmluZ1Byb21pc2UgPSBmdW5jdGlvbihzdHIsIGEpIHtcbiAgICB2YXIgb3B0aW9ucywgcGFyc2VyO1xuICAgIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIG9wdGlvbnMgPSBhO1xuICAgIH1cbiAgICBwYXJzZXIgPSBuZXcgZXhwb3J0cy5QYXJzZXIob3B0aW9ucyk7XG4gICAgcmV0dXJuIHBhcnNlci5wYXJzZVN0cmluZ1Byb21pc2Uoc3RyKTtcbiAgfTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuICB2YXIgcHJlZml4TWF0Y2g7XG5cbiAgcHJlZml4TWF0Y2ggPSBuZXcgUmVnRXhwKC8oPyF4bWxucyleLio6Lyk7XG5cbiAgZXhwb3J0cy5ub3JtYWxpemUgPSBmdW5jdGlvbihzdHIpIHtcbiAgICByZXR1cm4gc3RyLnRvTG93ZXJDYXNlKCk7XG4gIH07XG5cbiAgZXhwb3J0cy5maXJzdENoYXJMb3dlckNhc2UgPSBmdW5jdGlvbihzdHIpIHtcbiAgICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xuICB9O1xuXG4gIGV4cG9ydHMuc3RyaXBQcmVmaXggPSBmdW5jdGlvbihzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UocHJlZml4TWF0Y2gsICcnKTtcbiAgfTtcblxuICBleHBvcnRzLnBhcnNlTnVtYmVycyA9IGZ1bmN0aW9uKHN0cikge1xuICAgIGlmICghaXNOYU4oc3RyKSkge1xuICAgICAgc3RyID0gc3RyICUgMSA9PT0gMCA/IHBhcnNlSW50KHN0ciwgMTApIDogcGFyc2VGbG9hdChzdHIpO1xuICAgIH1cbiAgICByZXR1cm4gc3RyO1xuICB9O1xuXG4gIGV4cG9ydHMucGFyc2VCb29sZWFucyA9IGZ1bmN0aW9uKHN0cikge1xuICAgIGlmICgvXig/OnRydWV8ZmFsc2UpJC9pLnRlc3Qoc3RyKSkge1xuICAgICAgc3RyID0gc3RyLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJztcbiAgICB9XG4gICAgcmV0dXJuIHN0cjtcbiAgfTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuICB2YXIgYnVpbGRlciwgZGVmYXVsdHMsIHBhcnNlciwgcHJvY2Vzc29ycyxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIGRlZmF1bHRzID0gcmVxdWlyZSgnLi9kZWZhdWx0cycpO1xuXG4gIGJ1aWxkZXIgPSByZXF1aXJlKCcuL2J1aWxkZXInKTtcblxuICBwYXJzZXIgPSByZXF1aXJlKCcuL3BhcnNlcicpO1xuXG4gIHByb2Nlc3NvcnMgPSByZXF1aXJlKCcuL3Byb2Nlc3NvcnMnKTtcblxuICBleHBvcnRzLmRlZmF1bHRzID0gZGVmYXVsdHMuZGVmYXVsdHM7XG5cbiAgZXhwb3J0cy5wcm9jZXNzb3JzID0gcHJvY2Vzc29ycztcblxuICBleHBvcnRzLlZhbGlkYXRpb25FcnJvciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFZhbGlkYXRpb25FcnJvciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBWYWxpZGF0aW9uRXJyb3IobWVzc2FnZSkge1xuICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB9XG5cbiAgICByZXR1cm4gVmFsaWRhdGlvbkVycm9yO1xuXG4gIH0pKEVycm9yKTtcblxuICBleHBvcnRzLkJ1aWxkZXIgPSBidWlsZGVyLkJ1aWxkZXI7XG5cbiAgZXhwb3J0cy5QYXJzZXIgPSBwYXJzZXIuUGFyc2VyO1xuXG4gIGV4cG9ydHMucGFyc2VTdHJpbmcgPSBwYXJzZXIucGFyc2VTdHJpbmc7XG5cbiAgZXhwb3J0cy5wYXJzZVN0cmluZ1Byb21pc2UgPSBwYXJzZXIucGFyc2VTdHJpbmdQcm9taXNlO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgRGlzY29ubmVjdGVkOiAxLFxuICAgIFByZWNlZGluZzogMixcbiAgICBGb2xsb3dpbmc6IDQsXG4gICAgQ29udGFpbnM6IDgsXG4gICAgQ29udGFpbmVkQnk6IDE2LFxuICAgIEltcGxlbWVudGF0aW9uU3BlY2lmaWM6IDMyXG4gIH07XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBFbGVtZW50OiAxLFxuICAgIEF0dHJpYnV0ZTogMixcbiAgICBUZXh0OiAzLFxuICAgIENEYXRhOiA0LFxuICAgIEVudGl0eVJlZmVyZW5jZTogNSxcbiAgICBFbnRpdHlEZWNsYXJhdGlvbjogNixcbiAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb246IDcsXG4gICAgQ29tbWVudDogOCxcbiAgICBEb2N1bWVudDogOSxcbiAgICBEb2NUeXBlOiAxMCxcbiAgICBEb2N1bWVudEZyYWdtZW50OiAxMSxcbiAgICBOb3RhdGlvbkRlY2xhcmF0aW9uOiAxMixcbiAgICBEZWNsYXJhdGlvbjogMjAxLFxuICAgIFJhdzogMjAyLFxuICAgIEF0dHJpYnV0ZURlY2xhcmF0aW9uOiAyMDMsXG4gICAgRWxlbWVudERlY2xhcmF0aW9uOiAyMDQsXG4gICAgRHVtbXk6IDIwNVxuICB9O1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIGFzc2lnbiwgZ2V0VmFsdWUsIGlzQXJyYXksIGlzRW1wdHksIGlzRnVuY3Rpb24sIGlzT2JqZWN0LCBpc1BsYWluT2JqZWN0LFxuICAgIHNsaWNlID0gW10uc2xpY2UsXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIGFzc2lnbiA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBpLCBrZXksIGxlbiwgc291cmNlLCBzb3VyY2VzLCB0YXJnZXQ7XG4gICAgdGFyZ2V0ID0gYXJndW1lbnRzWzBdLCBzb3VyY2VzID0gMiA8PSBhcmd1bWVudHMubGVuZ3RoID8gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpIDogW107XG4gICAgaWYgKGlzRnVuY3Rpb24oT2JqZWN0LmFzc2lnbikpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24uYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChpID0gMCwgbGVuID0gc291cmNlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBzb3VyY2UgPSBzb3VyY2VzW2ldO1xuICAgICAgICBpZiAoc291cmNlICE9IG51bGwpIHtcbiAgICAgICAgICBmb3IgKGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIGlmICghaGFzUHJvcC5jYWxsKHNvdXJjZSwga2V5KSkgY29udGludWU7XG4gICAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9O1xuXG4gIGlzRnVuY3Rpb24gPSBmdW5jdGlvbih2YWwpIHtcbiAgICByZXR1cm4gISF2YWwgJiYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG4gIH07XG5cbiAgaXNPYmplY3QgPSBmdW5jdGlvbih2YWwpIHtcbiAgICB2YXIgcmVmO1xuICAgIHJldHVybiAhIXZhbCAmJiAoKHJlZiA9IHR5cGVvZiB2YWwpID09PSAnZnVuY3Rpb24nIHx8IHJlZiA9PT0gJ29iamVjdCcpO1xuICB9O1xuXG4gIGlzQXJyYXkgPSBmdW5jdGlvbih2YWwpIHtcbiAgICBpZiAoaXNGdW5jdGlvbihBcnJheS5pc0FycmF5KSkge1xuICAgICAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWwpID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH1cbiAgfTtcblxuICBpc0VtcHR5ID0gZnVuY3Rpb24odmFsKSB7XG4gICAgdmFyIGtleTtcbiAgICBpZiAoaXNBcnJheSh2YWwpKSB7XG4gICAgICByZXR1cm4gIXZhbC5sZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoa2V5IGluIHZhbCkge1xuICAgICAgICBpZiAoIWhhc1Byb3AuY2FsbCh2YWwsIGtleSkpIGNvbnRpbnVlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH07XG5cbiAgaXNQbGFpbk9iamVjdCA9IGZ1bmN0aW9uKHZhbCkge1xuICAgIHZhciBjdG9yLCBwcm90bztcbiAgICByZXR1cm4gaXNPYmplY3QodmFsKSAmJiAocHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsKSkgJiYgKGN0b3IgPSBwcm90by5jb25zdHJ1Y3RvcikgJiYgKHR5cGVvZiBjdG9yID09PSAnZnVuY3Rpb24nKSAmJiAoY3RvciBpbnN0YW5jZW9mIGN0b3IpICYmIChGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChjdG9yKSA9PT0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoT2JqZWN0KSk7XG4gIH07XG5cbiAgZ2V0VmFsdWUgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAoaXNGdW5jdGlvbihvYmoudmFsdWVPZikpIHtcbiAgICAgIHJldHVybiBvYmoudmFsdWVPZigpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gb2JqO1xuICAgIH1cbiAgfTtcblxuICBtb2R1bGUuZXhwb3J0cy5hc3NpZ24gPSBhc3NpZ247XG5cbiAgbW9kdWxlLmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbiAgbW9kdWxlLmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuICBtb2R1bGUuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuICBtb2R1bGUuZXhwb3J0cy5pc0VtcHR5ID0gaXNFbXB0eTtcblxuICBtb2R1bGUuZXhwb3J0cy5pc1BsYWluT2JqZWN0ID0gaXNQbGFpbk9iamVjdDtcblxuICBtb2R1bGUuZXhwb3J0cy5nZXRWYWx1ZSA9IGdldFZhbHVlO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgTm9uZTogMCxcbiAgICBPcGVuVGFnOiAxLFxuICAgIEluc2lkZVRhZzogMixcbiAgICBDbG9zZVRhZzogM1xuICB9O1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIE5vZGVUeXBlLCBYTUxBdHRyaWJ1dGUsIFhNTE5vZGU7XG5cbiAgTm9kZVR5cGUgPSByZXF1aXJlKCcuL05vZGVUeXBlJyk7XG5cbiAgWE1MTm9kZSA9IHJlcXVpcmUoJy4vWE1MTm9kZScpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MQXR0cmlidXRlID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIFhNTEF0dHJpYnV0ZShwYXJlbnQsIG5hbWUsIHZhbHVlKSB7XG4gICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDtcbiAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSB0aGlzLnBhcmVudC5vcHRpb25zO1xuICAgICAgICB0aGlzLnN0cmluZ2lmeSA9IHRoaXMucGFyZW50LnN0cmluZ2lmeTtcbiAgICAgIH1cbiAgICAgIGlmIChuYW1lID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGUgbmFtZS4gXCIgKyB0aGlzLmRlYnVnSW5mbyhuYW1lKSk7XG4gICAgICB9XG4gICAgICB0aGlzLm5hbWUgPSB0aGlzLnN0cmluZ2lmeS5uYW1lKG5hbWUpO1xuICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuc3RyaW5naWZ5LmF0dFZhbHVlKHZhbHVlKTtcbiAgICAgIHRoaXMudHlwZSA9IE5vZGVUeXBlLkF0dHJpYnV0ZTtcbiAgICAgIHRoaXMuaXNJZCA9IGZhbHNlO1xuICAgICAgdGhpcy5zY2hlbWFUeXBlSW5mbyA9IG51bGw7XG4gICAgfVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTEF0dHJpYnV0ZS5wcm90b3R5cGUsICdub2RlVHlwZScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MQXR0cmlidXRlLnByb3RvdHlwZSwgJ293bmVyRWxlbWVudCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmVudDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxBdHRyaWJ1dGUucHJvdG90eXBlLCAndGV4dENvbnRlbnQnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICAgIH0sXG4gICAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlID0gdmFsdWUgfHwgJyc7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MQXR0cmlidXRlLnByb3RvdHlwZSwgJ25hbWVzcGFjZVVSSScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxBdHRyaWJ1dGUucHJvdG90eXBlLCAncHJlZml4Jywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTEF0dHJpYnV0ZS5wcm90b3R5cGUsICdsb2NhbE5hbWUnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uYW1lO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTEF0dHJpYnV0ZS5wcm90b3R5cGUsICdzcGVjaWZpZWQnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIFhNTEF0dHJpYnV0ZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBPYmplY3QuY3JlYXRlKHRoaXMpO1xuICAgIH07XG5cbiAgICBYTUxBdHRyaWJ1dGUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy53cml0ZXIuYXR0cmlidXRlKHRoaXMsIHRoaXMub3B0aW9ucy53cml0ZXIuZmlsdGVyT3B0aW9ucyhvcHRpb25zKSk7XG4gICAgfTtcblxuICAgIFhNTEF0dHJpYnV0ZS5wcm90b3R5cGUuZGVidWdJbmZvID0gZnVuY3Rpb24obmFtZSkge1xuICAgICAgbmFtZSA9IG5hbWUgfHwgdGhpcy5uYW1lO1xuICAgICAgaWYgKG5hbWUgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gXCJwYXJlbnQ6IDxcIiArIHRoaXMucGFyZW50Lm5hbWUgKyBcIj5cIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBcImF0dHJpYnV0ZToge1wiICsgbmFtZSArIFwifSwgcGFyZW50OiA8XCIgKyB0aGlzLnBhcmVudC5uYW1lICsgXCI+XCI7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFhNTEF0dHJpYnV0ZS5wcm90b3R5cGUuaXNFcXVhbE5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgICBpZiAobm9kZS5uYW1lc3BhY2VVUkkgIT09IHRoaXMubmFtZXNwYWNlVVJJKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChub2RlLnByZWZpeCAhPT0gdGhpcy5wcmVmaXgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKG5vZGUubG9jYWxOYW1lICE9PSB0aGlzLmxvY2FsTmFtZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobm9kZS52YWx1ZSAhPT0gdGhpcy52YWx1ZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTEF0dHJpYnV0ZTtcblxuICB9KSgpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIE5vZGVUeXBlLCBYTUxDRGF0YSwgWE1MQ2hhcmFjdGVyRGF0YSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIE5vZGVUeXBlID0gcmVxdWlyZSgnLi9Ob2RlVHlwZScpO1xuXG4gIFhNTENoYXJhY3RlckRhdGEgPSByZXF1aXJlKCcuL1hNTENoYXJhY3RlckRhdGEnKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFhNTENEYXRhID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoWE1MQ0RhdGEsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gWE1MQ0RhdGEocGFyZW50LCB0ZXh0KSB7XG4gICAgICBYTUxDRGF0YS5fX3N1cGVyX18uY29uc3RydWN0b3IuY2FsbCh0aGlzLCBwYXJlbnQpO1xuICAgICAgaWYgKHRleHQgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIENEQVRBIHRleHQuIFwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgICB9XG4gICAgICB0aGlzLm5hbWUgPSBcIiNjZGF0YS1zZWN0aW9uXCI7XG4gICAgICB0aGlzLnR5cGUgPSBOb2RlVHlwZS5DRGF0YTtcbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLnN0cmluZ2lmeS5jZGF0YSh0ZXh0KTtcbiAgICB9XG5cbiAgICBYTUxDRGF0YS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBPYmplY3QuY3JlYXRlKHRoaXMpO1xuICAgIH07XG5cbiAgICBYTUxDRGF0YS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLndyaXRlci5jZGF0YSh0aGlzLCB0aGlzLm9wdGlvbnMud3JpdGVyLmZpbHRlck9wdGlvbnMob3B0aW9ucykpO1xuICAgIH07XG5cbiAgICByZXR1cm4gWE1MQ0RhdGE7XG5cbiAgfSkoWE1MQ2hhcmFjdGVyRGF0YSk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgWE1MQ2hhcmFjdGVyRGF0YSwgWE1MTm9kZSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIFhNTE5vZGUgPSByZXF1aXJlKCcuL1hNTE5vZGUnKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFhNTENoYXJhY3RlckRhdGEgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChYTUxDaGFyYWN0ZXJEYXRhLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIFhNTENoYXJhY3RlckRhdGEocGFyZW50KSB7XG4gICAgICBYTUxDaGFyYWN0ZXJEYXRhLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsIHBhcmVudCk7XG4gICAgICB0aGlzLnZhbHVlID0gJyc7XG4gICAgfVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTENoYXJhY3RlckRhdGEucHJvdG90eXBlLCAnZGF0YScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgICAgfSxcbiAgICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWUgPSB2YWx1ZSB8fCAnJztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxDaGFyYWN0ZXJEYXRhLnByb3RvdHlwZSwgJ2xlbmd0aCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlLmxlbmd0aDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxDaGFyYWN0ZXJEYXRhLnByb3RvdHlwZSwgJ3RleHRDb250ZW50Jywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gICAgICB9LFxuICAgICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZSA9IHZhbHVlIHx8ICcnO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgWE1MQ2hhcmFjdGVyRGF0YS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBPYmplY3QuY3JlYXRlKHRoaXMpO1xuICAgIH07XG5cbiAgICBYTUxDaGFyYWN0ZXJEYXRhLnByb3RvdHlwZS5zdWJzdHJpbmdEYXRhID0gZnVuY3Rpb24ob2Zmc2V0LCBjb3VudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxDaGFyYWN0ZXJEYXRhLnByb3RvdHlwZS5hcHBlbmREYXRhID0gZnVuY3Rpb24oYXJnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTENoYXJhY3RlckRhdGEucHJvdG90eXBlLmluc2VydERhdGEgPSBmdW5jdGlvbihvZmZzZXQsIGFyZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxDaGFyYWN0ZXJEYXRhLnByb3RvdHlwZS5kZWxldGVEYXRhID0gZnVuY3Rpb24ob2Zmc2V0LCBjb3VudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxDaGFyYWN0ZXJEYXRhLnByb3RvdHlwZS5yZXBsYWNlRGF0YSA9IGZ1bmN0aW9uKG9mZnNldCwgY291bnQsIGFyZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxDaGFyYWN0ZXJEYXRhLnByb3RvdHlwZS5pc0VxdWFsTm9kZSA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIGlmICghWE1MQ2hhcmFjdGVyRGF0YS5fX3N1cGVyX18uaXNFcXVhbE5vZGUuYXBwbHkodGhpcywgYXJndW1lbnRzKS5pc0VxdWFsTm9kZShub2RlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobm9kZS5kYXRhICE9PSB0aGlzLmRhdGEpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIHJldHVybiBYTUxDaGFyYWN0ZXJEYXRhO1xuXG4gIH0pKFhNTE5vZGUpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIE5vZGVUeXBlLCBYTUxDaGFyYWN0ZXJEYXRhLCBYTUxDb21tZW50LFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgTm9kZVR5cGUgPSByZXF1aXJlKCcuL05vZGVUeXBlJyk7XG5cbiAgWE1MQ2hhcmFjdGVyRGF0YSA9IHJlcXVpcmUoJy4vWE1MQ2hhcmFjdGVyRGF0YScpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MQ29tbWVudCA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFhNTENvbW1lbnQsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gWE1MQ29tbWVudChwYXJlbnQsIHRleHQpIHtcbiAgICAgIFhNTENvbW1lbnQuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmNhbGwodGhpcywgcGFyZW50KTtcbiAgICAgIGlmICh0ZXh0ID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBjb21tZW50IHRleHQuIFwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgICB9XG4gICAgICB0aGlzLm5hbWUgPSBcIiNjb21tZW50XCI7XG4gICAgICB0aGlzLnR5cGUgPSBOb2RlVHlwZS5Db21tZW50O1xuICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuc3RyaW5naWZ5LmNvbW1lbnQodGV4dCk7XG4gICAgfVxuXG4gICAgWE1MQ29tbWVudC5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBPYmplY3QuY3JlYXRlKHRoaXMpO1xuICAgIH07XG5cbiAgICBYTUxDb21tZW50LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMud3JpdGVyLmNvbW1lbnQodGhpcywgdGhpcy5vcHRpb25zLndyaXRlci5maWx0ZXJPcHRpb25zKG9wdGlvbnMpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTENvbW1lbnQ7XG5cbiAgfSkoWE1MQ2hhcmFjdGVyRGF0YSk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgWE1MRE9NQ29uZmlndXJhdGlvbiwgWE1MRE9NRXJyb3JIYW5kbGVyLCBYTUxET01TdHJpbmdMaXN0O1xuXG4gIFhNTERPTUVycm9ySGFuZGxlciA9IHJlcXVpcmUoJy4vWE1MRE9NRXJyb3JIYW5kbGVyJyk7XG5cbiAgWE1MRE9NU3RyaW5nTGlzdCA9IHJlcXVpcmUoJy4vWE1MRE9NU3RyaW5nTGlzdCcpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MRE9NQ29uZmlndXJhdGlvbiA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBYTUxET01Db25maWd1cmF0aW9uKCkge1xuICAgICAgdmFyIGNsb25lZFNlbGY7XG4gICAgICB0aGlzLmRlZmF1bHRQYXJhbXMgPSB7XG4gICAgICAgIFwiY2Fub25pY2FsLWZvcm1cIjogZmFsc2UsXG4gICAgICAgIFwiY2RhdGEtc2VjdGlvbnNcIjogZmFsc2UsXG4gICAgICAgIFwiY29tbWVudHNcIjogZmFsc2UsXG4gICAgICAgIFwiZGF0YXR5cGUtbm9ybWFsaXphdGlvblwiOiBmYWxzZSxcbiAgICAgICAgXCJlbGVtZW50LWNvbnRlbnQtd2hpdGVzcGFjZVwiOiB0cnVlLFxuICAgICAgICBcImVudGl0aWVzXCI6IHRydWUsXG4gICAgICAgIFwiZXJyb3ItaGFuZGxlclwiOiBuZXcgWE1MRE9NRXJyb3JIYW5kbGVyKCksXG4gICAgICAgIFwiaW5mb3NldFwiOiB0cnVlLFxuICAgICAgICBcInZhbGlkYXRlLWlmLXNjaGVtYVwiOiBmYWxzZSxcbiAgICAgICAgXCJuYW1lc3BhY2VzXCI6IHRydWUsXG4gICAgICAgIFwibmFtZXNwYWNlLWRlY2xhcmF0aW9uc1wiOiB0cnVlLFxuICAgICAgICBcIm5vcm1hbGl6ZS1jaGFyYWN0ZXJzXCI6IGZhbHNlLFxuICAgICAgICBcInNjaGVtYS1sb2NhdGlvblwiOiAnJyxcbiAgICAgICAgXCJzY2hlbWEtdHlwZVwiOiAnJyxcbiAgICAgICAgXCJzcGxpdC1jZGF0YS1zZWN0aW9uc1wiOiB0cnVlLFxuICAgICAgICBcInZhbGlkYXRlXCI6IGZhbHNlLFxuICAgICAgICBcIndlbGwtZm9ybWVkXCI6IHRydWVcbiAgICAgIH07XG4gICAgICB0aGlzLnBhcmFtcyA9IGNsb25lZFNlbGYgPSBPYmplY3QuY3JlYXRlKHRoaXMuZGVmYXVsdFBhcmFtcyk7XG4gICAgfVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERPTUNvbmZpZ3VyYXRpb24ucHJvdG90eXBlLCAncGFyYW1ldGVyTmFtZXMnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gbmV3IFhNTERPTVN0cmluZ0xpc3QoT2JqZWN0LmtleXModGhpcy5kZWZhdWx0UGFyYW1zKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBYTUxET01Db25maWd1cmF0aW9uLnByb3RvdHlwZS5nZXRQYXJhbWV0ZXIgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICBpZiAodGhpcy5wYXJhbXMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyYW1zW25hbWVdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFhNTERPTUNvbmZpZ3VyYXRpb24ucHJvdG90eXBlLmNhblNldFBhcmFtZXRlciA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgWE1MRE9NQ29uZmlndXJhdGlvbi5wcm90b3R5cGUuc2V0UGFyYW1ldGVyID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmFtc1tuYW1lXSA9IHZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGRlbGV0ZSB0aGlzLnBhcmFtc1tuYW1lXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTERPTUNvbmZpZ3VyYXRpb247XG5cbiAgfSkoKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBYTUxET01FcnJvckhhbmRsZXI7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBYTUxET01FcnJvckhhbmRsZXIgPSAoZnVuY3Rpb24oKSB7XG4gICAgZnVuY3Rpb24gWE1MRE9NRXJyb3JIYW5kbGVyKCkge31cblxuICAgIFhNTERPTUVycm9ySGFuZGxlci5wcm90b3R5cGUuaGFuZGxlRXJyb3IgPSBmdW5jdGlvbihlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTERPTUVycm9ySGFuZGxlcjtcblxuICB9KSgpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIFhNTERPTUltcGxlbWVudGF0aW9uO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MRE9NSW1wbGVtZW50YXRpb24gPSAoZnVuY3Rpb24oKSB7XG4gICAgZnVuY3Rpb24gWE1MRE9NSW1wbGVtZW50YXRpb24oKSB7fVxuXG4gICAgWE1MRE9NSW1wbGVtZW50YXRpb24ucHJvdG90eXBlLmhhc0ZlYXR1cmUgPSBmdW5jdGlvbihmZWF0dXJlLCB2ZXJzaW9uKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgWE1MRE9NSW1wbGVtZW50YXRpb24ucHJvdG90eXBlLmNyZWF0ZURvY3VtZW50VHlwZSA9IGZ1bmN0aW9uKHF1YWxpZmllZE5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgfTtcblxuICAgIFhNTERPTUltcGxlbWVudGF0aW9uLnByb3RvdHlwZS5jcmVhdGVEb2N1bWVudCA9IGZ1bmN0aW9uKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgZG9jdHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgfTtcblxuICAgIFhNTERPTUltcGxlbWVudGF0aW9uLnByb3RvdHlwZS5jcmVhdGVIVE1MRG9jdW1lbnQgPSBmdW5jdGlvbih0aXRsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgfTtcblxuICAgIFhNTERPTUltcGxlbWVudGF0aW9uLnByb3RvdHlwZS5nZXRGZWF0dXJlID0gZnVuY3Rpb24oZmVhdHVyZSwgdmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgfTtcblxuICAgIHJldHVybiBYTUxET01JbXBsZW1lbnRhdGlvbjtcblxuICB9KSgpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIFhNTERPTVN0cmluZ0xpc3Q7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBYTUxET01TdHJpbmdMaXN0ID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIFhNTERPTVN0cmluZ0xpc3QoYXJyKSB7XG4gICAgICB0aGlzLmFyciA9IGFyciB8fCBbXTtcbiAgICB9XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MRE9NU3RyaW5nTGlzdC5wcm90b3R5cGUsICdsZW5ndGgnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcnIubGVuZ3RoO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgWE1MRE9NU3RyaW5nTGlzdC5wcm90b3R5cGUuaXRlbSA9IGZ1bmN0aW9uKGluZGV4KSB7XG4gICAgICByZXR1cm4gdGhpcy5hcnJbaW5kZXhdIHx8IG51bGw7XG4gICAgfTtcblxuICAgIFhNTERPTVN0cmluZ0xpc3QucHJvdG90eXBlLmNvbnRhaW5zID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgICByZXR1cm4gdGhpcy5hcnIuaW5kZXhPZihzdHIpICE9PSAtMTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTERPTVN0cmluZ0xpc3Q7XG5cbiAgfSkoKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBOb2RlVHlwZSwgWE1MRFREQXR0TGlzdCwgWE1MTm9kZSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIFhNTE5vZGUgPSByZXF1aXJlKCcuL1hNTE5vZGUnKTtcblxuICBOb2RlVHlwZSA9IHJlcXVpcmUoJy4vTm9kZVR5cGUnKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFhNTERUREF0dExpc3QgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChYTUxEVERBdHRMaXN0LCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIFhNTERUREF0dExpc3QocGFyZW50LCBlbGVtZW50TmFtZSwgYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlVHlwZSwgZGVmYXVsdFZhbHVlVHlwZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICBYTUxEVERBdHRMaXN0Ll9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsIHBhcmVudCk7XG4gICAgICBpZiAoZWxlbWVudE5hbWUgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIERURCBlbGVtZW50IG5hbWUuIFwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgICB9XG4gICAgICBpZiAoYXR0cmlidXRlTmFtZSA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgRFREIGF0dHJpYnV0ZSBuYW1lLiBcIiArIHRoaXMuZGVidWdJbmZvKGVsZW1lbnROYW1lKSk7XG4gICAgICB9XG4gICAgICBpZiAoIWF0dHJpYnV0ZVR5cGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBEVEQgYXR0cmlidXRlIHR5cGUuIFwiICsgdGhpcy5kZWJ1Z0luZm8oZWxlbWVudE5hbWUpKTtcbiAgICAgIH1cbiAgICAgIGlmICghZGVmYXVsdFZhbHVlVHlwZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIERURCBhdHRyaWJ1dGUgZGVmYXVsdC4gXCIgKyB0aGlzLmRlYnVnSW5mbyhlbGVtZW50TmFtZSkpO1xuICAgICAgfVxuICAgICAgaWYgKGRlZmF1bHRWYWx1ZVR5cGUuaW5kZXhPZignIycpICE9PSAwKSB7XG4gICAgICAgIGRlZmF1bHRWYWx1ZVR5cGUgPSAnIycgKyBkZWZhdWx0VmFsdWVUeXBlO1xuICAgICAgfVxuICAgICAgaWYgKCFkZWZhdWx0VmFsdWVUeXBlLm1hdGNoKC9eKCNSRVFVSVJFRHwjSU1QTElFRHwjRklYRUR8I0RFRkFVTFQpJC8pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgZGVmYXVsdCB2YWx1ZSB0eXBlOyBleHBlY3RlZDogI1JFUVVJUkVELCAjSU1QTElFRCwgI0ZJWEVEIG9yICNERUZBVUxULiBcIiArIHRoaXMuZGVidWdJbmZvKGVsZW1lbnROYW1lKSk7XG4gICAgICB9XG4gICAgICBpZiAoZGVmYXVsdFZhbHVlICYmICFkZWZhdWx0VmFsdWVUeXBlLm1hdGNoKC9eKCNGSVhFRHwjREVGQVVMVCkkLykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGVmYXVsdCB2YWx1ZSBvbmx5IGFwcGxpZXMgdG8gI0ZJWEVEIG9yICNERUZBVUxULiBcIiArIHRoaXMuZGVidWdJbmZvKGVsZW1lbnROYW1lKSk7XG4gICAgICB9XG4gICAgICB0aGlzLmVsZW1lbnROYW1lID0gdGhpcy5zdHJpbmdpZnkubmFtZShlbGVtZW50TmFtZSk7XG4gICAgICB0aGlzLnR5cGUgPSBOb2RlVHlwZS5BdHRyaWJ1dGVEZWNsYXJhdGlvbjtcbiAgICAgIHRoaXMuYXR0cmlidXRlTmFtZSA9IHRoaXMuc3RyaW5naWZ5Lm5hbWUoYXR0cmlidXRlTmFtZSk7XG4gICAgICB0aGlzLmF0dHJpYnV0ZVR5cGUgPSB0aGlzLnN0cmluZ2lmeS5kdGRBdHRUeXBlKGF0dHJpYnV0ZVR5cGUpO1xuICAgICAgaWYgKGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICB0aGlzLmRlZmF1bHRWYWx1ZSA9IHRoaXMuc3RyaW5naWZ5LmR0ZEF0dERlZmF1bHQoZGVmYXVsdFZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZGVmYXVsdFZhbHVlVHlwZSA9IGRlZmF1bHRWYWx1ZVR5cGU7XG4gICAgfVxuXG4gICAgWE1MRFREQXR0TGlzdC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLndyaXRlci5kdGRBdHRMaXN0KHRoaXMsIHRoaXMub3B0aW9ucy53cml0ZXIuZmlsdGVyT3B0aW9ucyhvcHRpb25zKSk7XG4gICAgfTtcblxuICAgIHJldHVybiBYTUxEVERBdHRMaXN0O1xuXG4gIH0pKFhNTE5vZGUpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIE5vZGVUeXBlLCBYTUxEVERFbGVtZW50LCBYTUxOb2RlLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgWE1MTm9kZSA9IHJlcXVpcmUoJy4vWE1MTm9kZScpO1xuXG4gIE5vZGVUeXBlID0gcmVxdWlyZSgnLi9Ob2RlVHlwZScpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MRFRERWxlbWVudCA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFhNTERUREVsZW1lbnQsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gWE1MRFRERWxlbWVudChwYXJlbnQsIG5hbWUsIHZhbHVlKSB7XG4gICAgICBYTUxEVERFbGVtZW50Ll9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsIHBhcmVudCk7XG4gICAgICBpZiAobmFtZSA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgRFREIGVsZW1lbnQgbmFtZS4gXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICAgIH1cbiAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgdmFsdWUgPSAnKCNQQ0RBVEEpJztcbiAgICAgIH1cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9ICcoJyArIHZhbHVlLmpvaW4oJywnKSArICcpJztcbiAgICAgIH1cbiAgICAgIHRoaXMubmFtZSA9IHRoaXMuc3RyaW5naWZ5Lm5hbWUobmFtZSk7XG4gICAgICB0aGlzLnR5cGUgPSBOb2RlVHlwZS5FbGVtZW50RGVjbGFyYXRpb247XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5zdHJpbmdpZnkuZHRkRWxlbWVudFZhbHVlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBYTUxEVERFbGVtZW50LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMud3JpdGVyLmR0ZEVsZW1lbnQodGhpcywgdGhpcy5vcHRpb25zLndyaXRlci5maWx0ZXJPcHRpb25zKG9wdGlvbnMpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTERUREVsZW1lbnQ7XG5cbiAgfSkoWE1MTm9kZSk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgTm9kZVR5cGUsIFhNTERUREVudGl0eSwgWE1MTm9kZSwgaXNPYmplY3QsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBpc09iamVjdCA9IHJlcXVpcmUoJy4vVXRpbGl0eScpLmlzT2JqZWN0O1xuXG4gIFhNTE5vZGUgPSByZXF1aXJlKCcuL1hNTE5vZGUnKTtcblxuICBOb2RlVHlwZSA9IHJlcXVpcmUoJy4vTm9kZVR5cGUnKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFhNTERUREVudGl0eSA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFhNTERUREVudGl0eSwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBYTUxEVERFbnRpdHkocGFyZW50LCBwZSwgbmFtZSwgdmFsdWUpIHtcbiAgICAgIFhNTERUREVudGl0eS5fX3N1cGVyX18uY29uc3RydWN0b3IuY2FsbCh0aGlzLCBwYXJlbnQpO1xuICAgICAgaWYgKG5hbWUgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIERURCBlbnRpdHkgbmFtZS4gXCIgKyB0aGlzLmRlYnVnSW5mbyhuYW1lKSk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIERURCBlbnRpdHkgdmFsdWUuIFwiICsgdGhpcy5kZWJ1Z0luZm8obmFtZSkpO1xuICAgICAgfVxuICAgICAgdGhpcy5wZSA9ICEhcGU7XG4gICAgICB0aGlzLm5hbWUgPSB0aGlzLnN0cmluZ2lmeS5uYW1lKG5hbWUpO1xuICAgICAgdGhpcy50eXBlID0gTm9kZVR5cGUuRW50aXR5RGVjbGFyYXRpb247XG4gICAgICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5zdHJpbmdpZnkuZHRkRW50aXR5VmFsdWUodmFsdWUpO1xuICAgICAgICB0aGlzLmludGVybmFsID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghdmFsdWUucHViSUQgJiYgIXZhbHVlLnN5c0lEKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUHVibGljIGFuZC9vciBzeXN0ZW0gaWRlbnRpZmllcnMgYXJlIHJlcXVpcmVkIGZvciBhbiBleHRlcm5hbCBlbnRpdHkuIFwiICsgdGhpcy5kZWJ1Z0luZm8obmFtZSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZS5wdWJJRCAmJiAhdmFsdWUuc3lzSUQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeXN0ZW0gaWRlbnRpZmllciBpcyByZXF1aXJlZCBmb3IgYSBwdWJsaWMgZXh0ZXJuYWwgZW50aXR5LiBcIiArIHRoaXMuZGVidWdJbmZvKG5hbWUpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmludGVybmFsID0gZmFsc2U7XG4gICAgICAgIGlmICh2YWx1ZS5wdWJJRCAhPSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5wdWJJRCA9IHRoaXMuc3RyaW5naWZ5LmR0ZFB1YklEKHZhbHVlLnB1YklEKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUuc3lzSUQgIT0gbnVsbCkge1xuICAgICAgICAgIHRoaXMuc3lzSUQgPSB0aGlzLnN0cmluZ2lmeS5kdGRTeXNJRCh2YWx1ZS5zeXNJRCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlLm5EYXRhICE9IG51bGwpIHtcbiAgICAgICAgICB0aGlzLm5EYXRhID0gdGhpcy5zdHJpbmdpZnkuZHRkTkRhdGEodmFsdWUubkRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnBlICYmIHRoaXMubkRhdGEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3RhdGlvbiBkZWNsYXJhdGlvbiBpcyBub3QgYWxsb3dlZCBpbiBhIHBhcmFtZXRlciBlbnRpdHkuIFwiICsgdGhpcy5kZWJ1Z0luZm8obmFtZSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERUREVudGl0eS5wcm90b3R5cGUsICdwdWJsaWNJZCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnB1YklEO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERUREVudGl0eS5wcm90b3R5cGUsICdzeXN0ZW1JZCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN5c0lEO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERUREVudGl0eS5wcm90b3R5cGUsICdub3RhdGlvbk5hbWUnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uRGF0YSB8fCBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERUREVudGl0eS5wcm90b3R5cGUsICdpbnB1dEVuY29kaW5nJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MRFRERW50aXR5LnByb3RvdHlwZSwgJ3htbEVuY29kaW5nJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MRFRERW50aXR5LnByb3RvdHlwZSwgJ3htbFZlcnNpb24nLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIFhNTERUREVudGl0eS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLndyaXRlci5kdGRFbnRpdHkodGhpcywgdGhpcy5vcHRpb25zLndyaXRlci5maWx0ZXJPcHRpb25zKG9wdGlvbnMpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTERUREVudGl0eTtcblxuICB9KShYTUxOb2RlKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBOb2RlVHlwZSwgWE1MRFRETm90YXRpb24sIFhNTE5vZGUsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBYTUxOb2RlID0gcmVxdWlyZSgnLi9YTUxOb2RlJyk7XG5cbiAgTm9kZVR5cGUgPSByZXF1aXJlKCcuL05vZGVUeXBlJyk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBYTUxEVEROb3RhdGlvbiA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFhNTERURE5vdGF0aW9uLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIFhNTERURE5vdGF0aW9uKHBhcmVudCwgbmFtZSwgdmFsdWUpIHtcbiAgICAgIFhNTERURE5vdGF0aW9uLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsIHBhcmVudCk7XG4gICAgICBpZiAobmFtZSA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgRFREIG5vdGF0aW9uIG5hbWUuIFwiICsgdGhpcy5kZWJ1Z0luZm8obmFtZSkpO1xuICAgICAgfVxuICAgICAgaWYgKCF2YWx1ZS5wdWJJRCAmJiAhdmFsdWUuc3lzSUQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUHVibGljIG9yIHN5c3RlbSBpZGVudGlmaWVycyBhcmUgcmVxdWlyZWQgZm9yIGFuIGV4dGVybmFsIGVudGl0eS4gXCIgKyB0aGlzLmRlYnVnSW5mbyhuYW1lKSk7XG4gICAgICB9XG4gICAgICB0aGlzLm5hbWUgPSB0aGlzLnN0cmluZ2lmeS5uYW1lKG5hbWUpO1xuICAgICAgdGhpcy50eXBlID0gTm9kZVR5cGUuTm90YXRpb25EZWNsYXJhdGlvbjtcbiAgICAgIGlmICh2YWx1ZS5wdWJJRCAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMucHViSUQgPSB0aGlzLnN0cmluZ2lmeS5kdGRQdWJJRCh2YWx1ZS5wdWJJRCk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUuc3lzSUQgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLnN5c0lEID0gdGhpcy5zdHJpbmdpZnkuZHRkU3lzSUQodmFsdWUuc3lzSUQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxEVEROb3RhdGlvbi5wcm90b3R5cGUsICdwdWJsaWNJZCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnB1YklEO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERURE5vdGF0aW9uLnByb3RvdHlwZSwgJ3N5c3RlbUlkJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3lzSUQ7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBYTUxEVEROb3RhdGlvbi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLndyaXRlci5kdGROb3RhdGlvbih0aGlzLCB0aGlzLm9wdGlvbnMud3JpdGVyLmZpbHRlck9wdGlvbnMob3B0aW9ucykpO1xuICAgIH07XG5cbiAgICByZXR1cm4gWE1MRFRETm90YXRpb247XG5cbiAgfSkoWE1MTm9kZSk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgTm9kZVR5cGUsIFhNTERlY2xhcmF0aW9uLCBYTUxOb2RlLCBpc09iamVjdCxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9VdGlsaXR5JykuaXNPYmplY3Q7XG5cbiAgWE1MTm9kZSA9IHJlcXVpcmUoJy4vWE1MTm9kZScpO1xuXG4gIE5vZGVUeXBlID0gcmVxdWlyZSgnLi9Ob2RlVHlwZScpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MRGVjbGFyYXRpb24gPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChYTUxEZWNsYXJhdGlvbiwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBYTUxEZWNsYXJhdGlvbihwYXJlbnQsIHZlcnNpb24sIGVuY29kaW5nLCBzdGFuZGFsb25lKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgWE1MRGVjbGFyYXRpb24uX19zdXBlcl9fLmNvbnN0cnVjdG9yLmNhbGwodGhpcywgcGFyZW50KTtcbiAgICAgIGlmIChpc09iamVjdCh2ZXJzaW9uKSkge1xuICAgICAgICByZWYgPSB2ZXJzaW9uLCB2ZXJzaW9uID0gcmVmLnZlcnNpb24sIGVuY29kaW5nID0gcmVmLmVuY29kaW5nLCBzdGFuZGFsb25lID0gcmVmLnN0YW5kYWxvbmU7XG4gICAgICB9XG4gICAgICBpZiAoIXZlcnNpb24pIHtcbiAgICAgICAgdmVyc2lvbiA9ICcxLjAnO1xuICAgICAgfVxuICAgICAgdGhpcy50eXBlID0gTm9kZVR5cGUuRGVjbGFyYXRpb247XG4gICAgICB0aGlzLnZlcnNpb24gPSB0aGlzLnN0cmluZ2lmeS54bWxWZXJzaW9uKHZlcnNpb24pO1xuICAgICAgaWYgKGVuY29kaW5nICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5lbmNvZGluZyA9IHRoaXMuc3RyaW5naWZ5LnhtbEVuY29kaW5nKGVuY29kaW5nKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFuZGFsb25lICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5zdGFuZGFsb25lID0gdGhpcy5zdHJpbmdpZnkueG1sU3RhbmRhbG9uZShzdGFuZGFsb25lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBYTUxEZWNsYXJhdGlvbi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLndyaXRlci5kZWNsYXJhdGlvbih0aGlzLCB0aGlzLm9wdGlvbnMud3JpdGVyLmZpbHRlck9wdGlvbnMob3B0aW9ucykpO1xuICAgIH07XG5cbiAgICByZXR1cm4gWE1MRGVjbGFyYXRpb247XG5cbiAgfSkoWE1MTm9kZSk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgTm9kZVR5cGUsIFhNTERUREF0dExpc3QsIFhNTERUREVsZW1lbnQsIFhNTERUREVudGl0eSwgWE1MRFRETm90YXRpb24sIFhNTERvY1R5cGUsIFhNTE5hbWVkTm9kZU1hcCwgWE1MTm9kZSwgaXNPYmplY3QsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBpc09iamVjdCA9IHJlcXVpcmUoJy4vVXRpbGl0eScpLmlzT2JqZWN0O1xuXG4gIFhNTE5vZGUgPSByZXF1aXJlKCcuL1hNTE5vZGUnKTtcblxuICBOb2RlVHlwZSA9IHJlcXVpcmUoJy4vTm9kZVR5cGUnKTtcblxuICBYTUxEVERBdHRMaXN0ID0gcmVxdWlyZSgnLi9YTUxEVERBdHRMaXN0Jyk7XG5cbiAgWE1MRFRERW50aXR5ID0gcmVxdWlyZSgnLi9YTUxEVERFbnRpdHknKTtcblxuICBYTUxEVERFbGVtZW50ID0gcmVxdWlyZSgnLi9YTUxEVERFbGVtZW50Jyk7XG5cbiAgWE1MRFRETm90YXRpb24gPSByZXF1aXJlKCcuL1hNTERURE5vdGF0aW9uJyk7XG5cbiAgWE1MTmFtZWROb2RlTWFwID0gcmVxdWlyZSgnLi9YTUxOYW1lZE5vZGVNYXAnKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFhNTERvY1R5cGUgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChYTUxEb2NUeXBlLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIFhNTERvY1R5cGUocGFyZW50LCBwdWJJRCwgc3lzSUQpIHtcbiAgICAgIHZhciBjaGlsZCwgaSwgbGVuLCByZWYsIHJlZjEsIHJlZjI7XG4gICAgICBYTUxEb2NUeXBlLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsIHBhcmVudCk7XG4gICAgICB0aGlzLnR5cGUgPSBOb2RlVHlwZS5Eb2NUeXBlO1xuICAgICAgaWYgKHBhcmVudC5jaGlsZHJlbikge1xuICAgICAgICByZWYgPSBwYXJlbnQuY2hpbGRyZW47XG4gICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IHJlZi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIGNoaWxkID0gcmVmW2ldO1xuICAgICAgICAgIGlmIChjaGlsZC50eXBlID09PSBOb2RlVHlwZS5FbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBjaGlsZC5uYW1lO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmRvY3VtZW50T2JqZWN0ID0gcGFyZW50O1xuICAgICAgaWYgKGlzT2JqZWN0KHB1YklEKSkge1xuICAgICAgICByZWYxID0gcHViSUQsIHB1YklEID0gcmVmMS5wdWJJRCwgc3lzSUQgPSByZWYxLnN5c0lEO1xuICAgICAgfVxuICAgICAgaWYgKHN5c0lEID09IG51bGwpIHtcbiAgICAgICAgcmVmMiA9IFtwdWJJRCwgc3lzSURdLCBzeXNJRCA9IHJlZjJbMF0sIHB1YklEID0gcmVmMlsxXTtcbiAgICAgIH1cbiAgICAgIGlmIChwdWJJRCAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMucHViSUQgPSB0aGlzLnN0cmluZ2lmeS5kdGRQdWJJRChwdWJJRCk7XG4gICAgICB9XG4gICAgICBpZiAoc3lzSUQgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLnN5c0lEID0gdGhpcy5zdHJpbmdpZnkuZHRkU3lzSUQoc3lzSUQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxEb2NUeXBlLnByb3RvdHlwZSwgJ2VudGl0aWVzJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGNoaWxkLCBpLCBsZW4sIG5vZGVzLCByZWY7XG4gICAgICAgIG5vZGVzID0ge307XG4gICAgICAgIHJlZiA9IHRoaXMuY2hpbGRyZW47XG4gICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IHJlZi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIGNoaWxkID0gcmVmW2ldO1xuICAgICAgICAgIGlmICgoY2hpbGQudHlwZSA9PT0gTm9kZVR5cGUuRW50aXR5RGVjbGFyYXRpb24pICYmICFjaGlsZC5wZSkge1xuICAgICAgICAgICAgbm9kZXNbY2hpbGQubmFtZV0gPSBjaGlsZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBYTUxOYW1lZE5vZGVNYXAobm9kZXMpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERvY1R5cGUucHJvdG90eXBlLCAnbm90YXRpb25zJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGNoaWxkLCBpLCBsZW4sIG5vZGVzLCByZWY7XG4gICAgICAgIG5vZGVzID0ge307XG4gICAgICAgIHJlZiA9IHRoaXMuY2hpbGRyZW47XG4gICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IHJlZi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIGNoaWxkID0gcmVmW2ldO1xuICAgICAgICAgIGlmIChjaGlsZC50eXBlID09PSBOb2RlVHlwZS5Ob3RhdGlvbkRlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICBub2Rlc1tjaGlsZC5uYW1lXSA9IGNoaWxkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFhNTE5hbWVkTm9kZU1hcChub2Rlcyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MRG9jVHlwZS5wcm90b3R5cGUsICdwdWJsaWNJZCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnB1YklEO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERvY1R5cGUucHJvdG90eXBlLCAnc3lzdGVtSWQnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zeXNJRDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxEb2NUeXBlLnByb3RvdHlwZSwgJ2ludGVybmFsU3Vic2V0Jywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgWE1MRG9jVHlwZS5wcm90b3R5cGUuZWxlbWVudCA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICB2YXIgY2hpbGQ7XG4gICAgICBjaGlsZCA9IG5ldyBYTUxEVERFbGVtZW50KHRoaXMsIG5hbWUsIHZhbHVlKTtcbiAgICAgIHRoaXMuY2hpbGRyZW4ucHVzaChjaGlsZCk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MRG9jVHlwZS5wcm90b3R5cGUuYXR0TGlzdCA9IGZ1bmN0aW9uKGVsZW1lbnROYW1lLCBhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVUeXBlLCBkZWZhdWx0VmFsdWVUeXBlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHZhciBjaGlsZDtcbiAgICAgIGNoaWxkID0gbmV3IFhNTERUREF0dExpc3QodGhpcywgZWxlbWVudE5hbWUsIGF0dHJpYnV0ZU5hbWUsIGF0dHJpYnV0ZVR5cGUsIGRlZmF1bHRWYWx1ZVR5cGUsIGRlZmF1bHRWYWx1ZSk7XG4gICAgICB0aGlzLmNoaWxkcmVuLnB1c2goY2hpbGQpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTERvY1R5cGUucHJvdG90eXBlLmVudGl0eSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICB2YXIgY2hpbGQ7XG4gICAgICBjaGlsZCA9IG5ldyBYTUxEVERFbnRpdHkodGhpcywgZmFsc2UsIG5hbWUsIHZhbHVlKTtcbiAgICAgIHRoaXMuY2hpbGRyZW4ucHVzaChjaGlsZCk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MRG9jVHlwZS5wcm90b3R5cGUucEVudGl0eSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICB2YXIgY2hpbGQ7XG4gICAgICBjaGlsZCA9IG5ldyBYTUxEVERFbnRpdHkodGhpcywgdHJ1ZSwgbmFtZSwgdmFsdWUpO1xuICAgICAgdGhpcy5jaGlsZHJlbi5wdXNoKGNoaWxkKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBYTUxEb2NUeXBlLnByb3RvdHlwZS5ub3RhdGlvbiA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICB2YXIgY2hpbGQ7XG4gICAgICBjaGlsZCA9IG5ldyBYTUxEVEROb3RhdGlvbih0aGlzLCBuYW1lLCB2YWx1ZSk7XG4gICAgICB0aGlzLmNoaWxkcmVuLnB1c2goY2hpbGQpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTERvY1R5cGUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy53cml0ZXIuZG9jVHlwZSh0aGlzLCB0aGlzLm9wdGlvbnMud3JpdGVyLmZpbHRlck9wdGlvbnMob3B0aW9ucykpO1xuICAgIH07XG5cbiAgICBYTUxEb2NUeXBlLnByb3RvdHlwZS5lbGUgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudChuYW1lLCB2YWx1ZSk7XG4gICAgfTtcblxuICAgIFhNTERvY1R5cGUucHJvdG90eXBlLmF0dCA9IGZ1bmN0aW9uKGVsZW1lbnROYW1lLCBhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVUeXBlLCBkZWZhdWx0VmFsdWVUeXBlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmF0dExpc3QoZWxlbWVudE5hbWUsIGF0dHJpYnV0ZU5hbWUsIGF0dHJpYnV0ZVR5cGUsIGRlZmF1bHRWYWx1ZVR5cGUsIGRlZmF1bHRWYWx1ZSk7XG4gICAgfTtcblxuICAgIFhNTERvY1R5cGUucHJvdG90eXBlLmVudCA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbnRpdHkobmFtZSwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxEb2NUeXBlLnByb3RvdHlwZS5wZW50ID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnBFbnRpdHkobmFtZSwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxEb2NUeXBlLnByb3RvdHlwZS5ub3QgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMubm90YXRpb24obmFtZSwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxEb2NUeXBlLnByb3RvdHlwZS51cCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMucm9vdCgpIHx8IHRoaXMuZG9jdW1lbnRPYmplY3Q7XG4gICAgfTtcblxuICAgIFhNTERvY1R5cGUucHJvdG90eXBlLmlzRXF1YWxOb2RlID0gZnVuY3Rpb24obm9kZSkge1xuICAgICAgaWYgKCFYTUxEb2NUeXBlLl9fc3VwZXJfXy5pc0VxdWFsTm9kZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpLmlzRXF1YWxOb2RlKG5vZGUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChub2RlLm5hbWUgIT09IHRoaXMubmFtZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobm9kZS5wdWJsaWNJZCAhPT0gdGhpcy5wdWJsaWNJZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobm9kZS5zeXN0ZW1JZCAhPT0gdGhpcy5zeXN0ZW1JZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTERvY1R5cGU7XG5cbiAgfSkoWE1MTm9kZSk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgTm9kZVR5cGUsIFhNTERPTUNvbmZpZ3VyYXRpb24sIFhNTERPTUltcGxlbWVudGF0aW9uLCBYTUxEb2N1bWVudCwgWE1MTm9kZSwgWE1MU3RyaW5nV3JpdGVyLCBYTUxTdHJpbmdpZmllciwgaXNQbGFpbk9iamVjdCxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIGlzUGxhaW5PYmplY3QgPSByZXF1aXJlKCcuL1V0aWxpdHknKS5pc1BsYWluT2JqZWN0O1xuXG4gIFhNTERPTUltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9YTUxET01JbXBsZW1lbnRhdGlvbicpO1xuXG4gIFhNTERPTUNvbmZpZ3VyYXRpb24gPSByZXF1aXJlKCcuL1hNTERPTUNvbmZpZ3VyYXRpb24nKTtcblxuICBYTUxOb2RlID0gcmVxdWlyZSgnLi9YTUxOb2RlJyk7XG5cbiAgTm9kZVR5cGUgPSByZXF1aXJlKCcuL05vZGVUeXBlJyk7XG5cbiAgWE1MU3RyaW5naWZpZXIgPSByZXF1aXJlKCcuL1hNTFN0cmluZ2lmaWVyJyk7XG5cbiAgWE1MU3RyaW5nV3JpdGVyID0gcmVxdWlyZSgnLi9YTUxTdHJpbmdXcml0ZXInKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFhNTERvY3VtZW50ID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoWE1MRG9jdW1lbnQsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gWE1MRG9jdW1lbnQob3B0aW9ucykge1xuICAgICAgWE1MRG9jdW1lbnQuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmNhbGwodGhpcywgbnVsbCk7XG4gICAgICB0aGlzLm5hbWUgPSBcIiNkb2N1bWVudFwiO1xuICAgICAgdGhpcy50eXBlID0gTm9kZVR5cGUuRG9jdW1lbnQ7XG4gICAgICB0aGlzLmRvY3VtZW50VVJJID0gbnVsbDtcbiAgICAgIHRoaXMuZG9tQ29uZmlnID0gbmV3IFhNTERPTUNvbmZpZ3VyYXRpb24oKTtcbiAgICAgIG9wdGlvbnMgfHwgKG9wdGlvbnMgPSB7fSk7XG4gICAgICBpZiAoIW9wdGlvbnMud3JpdGVyKSB7XG4gICAgICAgIG9wdGlvbnMud3JpdGVyID0gbmV3IFhNTFN0cmluZ1dyaXRlcigpO1xuICAgICAgfVxuICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICAgIHRoaXMuc3RyaW5naWZ5ID0gbmV3IFhNTFN0cmluZ2lmaWVyKG9wdGlvbnMpO1xuICAgIH1cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxEb2N1bWVudC5wcm90b3R5cGUsICdpbXBsZW1lbnRhdGlvbicsIHtcbiAgICAgIHZhbHVlOiBuZXcgWE1MRE9NSW1wbGVtZW50YXRpb24oKVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERvY3VtZW50LnByb3RvdHlwZSwgJ2RvY3R5cGUnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgY2hpbGQsIGksIGxlbiwgcmVmO1xuICAgICAgICByZWYgPSB0aGlzLmNoaWxkcmVuO1xuICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSByZWYubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICBjaGlsZCA9IHJlZltpXTtcbiAgICAgICAgICBpZiAoY2hpbGQudHlwZSA9PT0gTm9kZVR5cGUuRG9jVHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxEb2N1bWVudC5wcm90b3R5cGUsICdkb2N1bWVudEVsZW1lbnQnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yb290T2JqZWN0IHx8IG51bGw7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MRG9jdW1lbnQucHJvdG90eXBlLCAnaW5wdXRFbmNvZGluZycsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERvY3VtZW50LnByb3RvdHlwZSwgJ3N0cmljdEVycm9yQ2hlY2tpbmcnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MRG9jdW1lbnQucHJvdG90eXBlLCAneG1sRW5jb2RpbmcnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGggIT09IDAgJiYgdGhpcy5jaGlsZHJlblswXS50eXBlID09PSBOb2RlVHlwZS5EZWNsYXJhdGlvbikge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNoaWxkcmVuWzBdLmVuY29kaW5nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MRG9jdW1lbnQucHJvdG90eXBlLCAneG1sU3RhbmRhbG9uZScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLmNoaWxkcmVuLmxlbmd0aCAhPT0gMCAmJiB0aGlzLmNoaWxkcmVuWzBdLnR5cGUgPT09IE5vZGVUeXBlLkRlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5bMF0uc3RhbmRhbG9uZSA9PT0gJ3llcyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MRG9jdW1lbnQucHJvdG90eXBlLCAneG1sVmVyc2lvbicsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLmNoaWxkcmVuLmxlbmd0aCAhPT0gMCAmJiB0aGlzLmNoaWxkcmVuWzBdLnR5cGUgPT09IE5vZGVUeXBlLkRlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5bMF0udmVyc2lvbjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gXCIxLjBcIjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERvY3VtZW50LnByb3RvdHlwZSwgJ1VSTCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRvY3VtZW50VVJJO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERvY3VtZW50LnByb3RvdHlwZSwgJ29yaWdpbicsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTERvY3VtZW50LnByb3RvdHlwZSwgJ2NvbXBhdE1vZGUnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxEb2N1bWVudC5wcm90b3R5cGUsICdjaGFyYWN0ZXJTZXQnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxEb2N1bWVudC5wcm90b3R5cGUsICdjb250ZW50VHlwZScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgWE1MRG9jdW1lbnQucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKHdyaXRlcikge1xuICAgICAgdmFyIHdyaXRlck9wdGlvbnM7XG4gICAgICB3cml0ZXJPcHRpb25zID0ge307XG4gICAgICBpZiAoIXdyaXRlcikge1xuICAgICAgICB3cml0ZXIgPSB0aGlzLm9wdGlvbnMud3JpdGVyO1xuICAgICAgfSBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHdyaXRlcikpIHtcbiAgICAgICAgd3JpdGVyT3B0aW9ucyA9IHdyaXRlcjtcbiAgICAgICAgd3JpdGVyID0gdGhpcy5vcHRpb25zLndyaXRlcjtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cml0ZXIuZG9jdW1lbnQodGhpcywgd3JpdGVyLmZpbHRlck9wdGlvbnMod3JpdGVyT3B0aW9ucykpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLndyaXRlci5kb2N1bWVudCh0aGlzLCB0aGlzLm9wdGlvbnMud3JpdGVyLmZpbHRlck9wdGlvbnMob3B0aW9ucykpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudC5wcm90b3R5cGUuY3JlYXRlRWxlbWVudCA9IGZ1bmN0aW9uKHRhZ05hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnQucHJvdG90eXBlLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnQucHJvdG90eXBlLmNyZWF0ZVRleHROb2RlID0gZnVuY3Rpb24oZGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudC5wcm90b3R5cGUuY3JlYXRlQ29tbWVudCA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnQucHJvdG90eXBlLmNyZWF0ZUNEQVRBU2VjdGlvbiA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnQucHJvdG90eXBlLmNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbiA9IGZ1bmN0aW9uKHRhcmdldCwgZGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudC5wcm90b3R5cGUuY3JlYXRlQXR0cmlidXRlID0gZnVuY3Rpb24obmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudC5wcm90b3R5cGUuY3JlYXRlRW50aXR5UmVmZXJlbmNlID0gZnVuY3Rpb24obmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudC5wcm90b3R5cGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUgPSBmdW5jdGlvbih0YWduYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50LnByb3RvdHlwZS5pbXBvcnROb2RlID0gZnVuY3Rpb24oaW1wb3J0ZWROb2RlLCBkZWVwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVFbGVtZW50TlMgPSBmdW5jdGlvbihuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnQucHJvdG90eXBlLmNyZWF0ZUF0dHJpYnV0ZU5TID0gZnVuY3Rpb24obmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50LnByb3RvdHlwZS5nZXRFbGVtZW50c0J5VGFnTmFtZU5TID0gZnVuY3Rpb24obmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnQucHJvdG90eXBlLmdldEVsZW1lbnRCeUlkID0gZnVuY3Rpb24oZWxlbWVudElkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50LnByb3RvdHlwZS5hZG9wdE5vZGUgPSBmdW5jdGlvbihzb3VyY2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnQucHJvdG90eXBlLm5vcm1hbGl6ZURvY3VtZW50ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50LnByb3RvdHlwZS5yZW5hbWVOb2RlID0gZnVuY3Rpb24obm9kZSwgbmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50LnByb3RvdHlwZS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lID0gZnVuY3Rpb24oY2xhc3NOYW1lcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudC5wcm90b3R5cGUuY3JlYXRlRXZlbnQgPSBmdW5jdGlvbihldmVudEludGVyZmFjZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudC5wcm90b3R5cGUuY3JlYXRlUmFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnQucHJvdG90eXBlLmNyZWF0ZU5vZGVJdGVyYXRvciA9IGZ1bmN0aW9uKHJvb3QsIHdoYXRUb1Nob3csIGZpbHRlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudC5wcm90b3R5cGUuY3JlYXRlVHJlZVdhbGtlciA9IGZ1bmN0aW9uKHJvb3QsIHdoYXRUb1Nob3csIGZpbHRlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICByZXR1cm4gWE1MRG9jdW1lbnQ7XG5cbiAgfSkoWE1MTm9kZSk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgTm9kZVR5cGUsIFdyaXRlclN0YXRlLCBYTUxBdHRyaWJ1dGUsIFhNTENEYXRhLCBYTUxDb21tZW50LCBYTUxEVERBdHRMaXN0LCBYTUxEVERFbGVtZW50LCBYTUxEVERFbnRpdHksIFhNTERURE5vdGF0aW9uLCBYTUxEZWNsYXJhdGlvbiwgWE1MRG9jVHlwZSwgWE1MRG9jdW1lbnQsIFhNTERvY3VtZW50Q0IsIFhNTEVsZW1lbnQsIFhNTFByb2Nlc3NpbmdJbnN0cnVjdGlvbiwgWE1MUmF3LCBYTUxTdHJpbmdXcml0ZXIsIFhNTFN0cmluZ2lmaWVyLCBYTUxUZXh0LCBnZXRWYWx1ZSwgaXNGdW5jdGlvbiwgaXNPYmplY3QsIGlzUGxhaW5PYmplY3QsIHJlZixcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgcmVmID0gcmVxdWlyZSgnLi9VdGlsaXR5JyksIGlzT2JqZWN0ID0gcmVmLmlzT2JqZWN0LCBpc0Z1bmN0aW9uID0gcmVmLmlzRnVuY3Rpb24sIGlzUGxhaW5PYmplY3QgPSByZWYuaXNQbGFpbk9iamVjdCwgZ2V0VmFsdWUgPSByZWYuZ2V0VmFsdWU7XG5cbiAgTm9kZVR5cGUgPSByZXF1aXJlKCcuL05vZGVUeXBlJyk7XG5cbiAgWE1MRG9jdW1lbnQgPSByZXF1aXJlKCcuL1hNTERvY3VtZW50Jyk7XG5cbiAgWE1MRWxlbWVudCA9IHJlcXVpcmUoJy4vWE1MRWxlbWVudCcpO1xuXG4gIFhNTENEYXRhID0gcmVxdWlyZSgnLi9YTUxDRGF0YScpO1xuXG4gIFhNTENvbW1lbnQgPSByZXF1aXJlKCcuL1hNTENvbW1lbnQnKTtcblxuICBYTUxSYXcgPSByZXF1aXJlKCcuL1hNTFJhdycpO1xuXG4gIFhNTFRleHQgPSByZXF1aXJlKCcuL1hNTFRleHQnKTtcblxuICBYTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL1hNTFByb2Nlc3NpbmdJbnN0cnVjdGlvbicpO1xuXG4gIFhNTERlY2xhcmF0aW9uID0gcmVxdWlyZSgnLi9YTUxEZWNsYXJhdGlvbicpO1xuXG4gIFhNTERvY1R5cGUgPSByZXF1aXJlKCcuL1hNTERvY1R5cGUnKTtcblxuICBYTUxEVERBdHRMaXN0ID0gcmVxdWlyZSgnLi9YTUxEVERBdHRMaXN0Jyk7XG5cbiAgWE1MRFRERW50aXR5ID0gcmVxdWlyZSgnLi9YTUxEVERFbnRpdHknKTtcblxuICBYTUxEVERFbGVtZW50ID0gcmVxdWlyZSgnLi9YTUxEVERFbGVtZW50Jyk7XG5cbiAgWE1MRFRETm90YXRpb24gPSByZXF1aXJlKCcuL1hNTERURE5vdGF0aW9uJyk7XG5cbiAgWE1MQXR0cmlidXRlID0gcmVxdWlyZSgnLi9YTUxBdHRyaWJ1dGUnKTtcblxuICBYTUxTdHJpbmdpZmllciA9IHJlcXVpcmUoJy4vWE1MU3RyaW5naWZpZXInKTtcblxuICBYTUxTdHJpbmdXcml0ZXIgPSByZXF1aXJlKCcuL1hNTFN0cmluZ1dyaXRlcicpO1xuXG4gIFdyaXRlclN0YXRlID0gcmVxdWlyZSgnLi9Xcml0ZXJTdGF0ZScpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MRG9jdW1lbnRDQiA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBYTUxEb2N1bWVudENCKG9wdGlvbnMsIG9uRGF0YSwgb25FbmQpIHtcbiAgICAgIHZhciB3cml0ZXJPcHRpb25zO1xuICAgICAgdGhpcy5uYW1lID0gXCI/eG1sXCI7XG4gICAgICB0aGlzLnR5cGUgPSBOb2RlVHlwZS5Eb2N1bWVudDtcbiAgICAgIG9wdGlvbnMgfHwgKG9wdGlvbnMgPSB7fSk7XG4gICAgICB3cml0ZXJPcHRpb25zID0ge307XG4gICAgICBpZiAoIW9wdGlvbnMud3JpdGVyKSB7XG4gICAgICAgIG9wdGlvbnMud3JpdGVyID0gbmV3IFhNTFN0cmluZ1dyaXRlcigpO1xuICAgICAgfSBlbHNlIGlmIChpc1BsYWluT2JqZWN0KG9wdGlvbnMud3JpdGVyKSkge1xuICAgICAgICB3cml0ZXJPcHRpb25zID0gb3B0aW9ucy53cml0ZXI7XG4gICAgICAgIG9wdGlvbnMud3JpdGVyID0gbmV3IFhNTFN0cmluZ1dyaXRlcigpO1xuICAgICAgfVxuICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICAgIHRoaXMud3JpdGVyID0gb3B0aW9ucy53cml0ZXI7XG4gICAgICB0aGlzLndyaXRlck9wdGlvbnMgPSB0aGlzLndyaXRlci5maWx0ZXJPcHRpb25zKHdyaXRlck9wdGlvbnMpO1xuICAgICAgdGhpcy5zdHJpbmdpZnkgPSBuZXcgWE1MU3RyaW5naWZpZXIob3B0aW9ucyk7XG4gICAgICB0aGlzLm9uRGF0YUNhbGxiYWNrID0gb25EYXRhIHx8IGZ1bmN0aW9uKCkge307XG4gICAgICB0aGlzLm9uRW5kQ2FsbGJhY2sgPSBvbkVuZCB8fCBmdW5jdGlvbigpIHt9O1xuICAgICAgdGhpcy5jdXJyZW50Tm9kZSA9IG51bGw7XG4gICAgICB0aGlzLmN1cnJlbnRMZXZlbCA9IC0xO1xuICAgICAgdGhpcy5vcGVuVGFncyA9IHt9O1xuICAgICAgdGhpcy5kb2N1bWVudFN0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuZG9jdW1lbnRDb21wbGV0ZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMucm9vdCA9IG51bGw7XG4gICAgfVxuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUuY3JlYXRlQ2hpbGROb2RlID0gZnVuY3Rpb24obm9kZSkge1xuICAgICAgdmFyIGF0dCwgYXR0TmFtZSwgYXR0cmlidXRlcywgY2hpbGQsIGksIGxlbiwgcmVmMSwgcmVmMjtcbiAgICAgIHN3aXRjaCAobm9kZS50eXBlKSB7XG4gICAgICAgIGNhc2UgTm9kZVR5cGUuQ0RhdGE6XG4gICAgICAgICAgdGhpcy5jZGF0YShub2RlLnZhbHVlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBOb2RlVHlwZS5Db21tZW50OlxuICAgICAgICAgIHRoaXMuY29tbWVudChub2RlLnZhbHVlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBOb2RlVHlwZS5FbGVtZW50OlxuICAgICAgICAgIGF0dHJpYnV0ZXMgPSB7fTtcbiAgICAgICAgICByZWYxID0gbm9kZS5hdHRyaWJzO1xuICAgICAgICAgIGZvciAoYXR0TmFtZSBpbiByZWYxKSB7XG4gICAgICAgICAgICBpZiAoIWhhc1Byb3AuY2FsbChyZWYxLCBhdHROYW1lKSkgY29udGludWU7XG4gICAgICAgICAgICBhdHQgPSByZWYxW2F0dE5hbWVdO1xuICAgICAgICAgICAgYXR0cmlidXRlc1thdHROYW1lXSA9IGF0dC52YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5ub2RlKG5vZGUubmFtZSwgYXR0cmlidXRlcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgTm9kZVR5cGUuRHVtbXk6XG4gICAgICAgICAgdGhpcy5kdW1teSgpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIE5vZGVUeXBlLlJhdzpcbiAgICAgICAgICB0aGlzLnJhdyhub2RlLnZhbHVlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBOb2RlVHlwZS5UZXh0OlxuICAgICAgICAgIHRoaXMudGV4dChub2RlLnZhbHVlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBOb2RlVHlwZS5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb246XG4gICAgICAgICAgdGhpcy5pbnN0cnVjdGlvbihub2RlLnRhcmdldCwgbm9kZS52YWx1ZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBYTUwgbm9kZSB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQgaW4gYSBKUyBvYmplY3Q6IFwiICsgbm9kZS5jb25zdHJ1Y3Rvci5uYW1lKTtcbiAgICAgIH1cbiAgICAgIHJlZjIgPSBub2RlLmNoaWxkcmVuO1xuICAgICAgZm9yIChpID0gMCwgbGVuID0gcmVmMi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBjaGlsZCA9IHJlZjJbaV07XG4gICAgICAgIHRoaXMuY3JlYXRlQ2hpbGROb2RlKGNoaWxkKTtcbiAgICAgICAgaWYgKGNoaWxkLnR5cGUgPT09IE5vZGVUeXBlLkVsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLnVwKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5kdW1teSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50Q0IucHJvdG90eXBlLm5vZGUgPSBmdW5jdGlvbihuYW1lLCBhdHRyaWJ1dGVzLCB0ZXh0KSB7XG4gICAgICB2YXIgcmVmMTtcbiAgICAgIGlmIChuYW1lID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBub2RlIG5hbWUuXCIpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMucm9vdCAmJiB0aGlzLmN1cnJlbnRMZXZlbCA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRG9jdW1lbnQgY2FuIG9ubHkgaGF2ZSBvbmUgcm9vdCBub2RlLiBcIiArIHRoaXMuZGVidWdJbmZvKG5hbWUpKTtcbiAgICAgIH1cbiAgICAgIHRoaXMub3BlbkN1cnJlbnQoKTtcbiAgICAgIG5hbWUgPSBnZXRWYWx1ZShuYW1lKTtcbiAgICAgIGlmIChhdHRyaWJ1dGVzID09IG51bGwpIHtcbiAgICAgICAgYXR0cmlidXRlcyA9IHt9O1xuICAgICAgfVxuICAgICAgYXR0cmlidXRlcyA9IGdldFZhbHVlKGF0dHJpYnV0ZXMpO1xuICAgICAgaWYgKCFpc09iamVjdChhdHRyaWJ1dGVzKSkge1xuICAgICAgICByZWYxID0gW2F0dHJpYnV0ZXMsIHRleHRdLCB0ZXh0ID0gcmVmMVswXSwgYXR0cmlidXRlcyA9IHJlZjFbMV07XG4gICAgICB9XG4gICAgICB0aGlzLmN1cnJlbnROb2RlID0gbmV3IFhNTEVsZW1lbnQodGhpcywgbmFtZSwgYXR0cmlidXRlcyk7XG4gICAgICB0aGlzLmN1cnJlbnROb2RlLmNoaWxkcmVuID0gZmFsc2U7XG4gICAgICB0aGlzLmN1cnJlbnRMZXZlbCsrO1xuICAgICAgdGhpcy5vcGVuVGFnc1t0aGlzLmN1cnJlbnRMZXZlbF0gPSB0aGlzLmN1cnJlbnROb2RlO1xuICAgICAgaWYgKHRleHQgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLnRleHQodGV4dCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUuZWxlbWVudCA9IGZ1bmN0aW9uKG5hbWUsIGF0dHJpYnV0ZXMsIHRleHQpIHtcbiAgICAgIHZhciBjaGlsZCwgaSwgbGVuLCBvbGRWYWxpZGF0aW9uRmxhZywgcmVmMSwgcm9vdDtcbiAgICAgIGlmICh0aGlzLmN1cnJlbnROb2RlICYmIHRoaXMuY3VycmVudE5vZGUudHlwZSA9PT0gTm9kZVR5cGUuRG9jVHlwZSkge1xuICAgICAgICB0aGlzLmR0ZEVsZW1lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG5hbWUpIHx8IGlzT2JqZWN0KG5hbWUpIHx8IGlzRnVuY3Rpb24obmFtZSkpIHtcbiAgICAgICAgICBvbGRWYWxpZGF0aW9uRmxhZyA9IHRoaXMub3B0aW9ucy5ub1ZhbGlkYXRpb247XG4gICAgICAgICAgdGhpcy5vcHRpb25zLm5vVmFsaWRhdGlvbiA9IHRydWU7XG4gICAgICAgICAgcm9vdCA9IG5ldyBYTUxEb2N1bWVudCh0aGlzLm9wdGlvbnMpLmVsZW1lbnQoJ1RFTVBfUk9PVCcpO1xuICAgICAgICAgIHJvb3QuZWxlbWVudChuYW1lKTtcbiAgICAgICAgICB0aGlzLm9wdGlvbnMubm9WYWxpZGF0aW9uID0gb2xkVmFsaWRhdGlvbkZsYWc7XG4gICAgICAgICAgcmVmMSA9IHJvb3QuY2hpbGRyZW47XG4gICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gcmVmMS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgY2hpbGQgPSByZWYxW2ldO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVDaGlsZE5vZGUoY2hpbGQpO1xuICAgICAgICAgICAgaWYgKGNoaWxkLnR5cGUgPT09IE5vZGVUeXBlLkVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgdGhpcy51cCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm5vZGUobmFtZSwgYXR0cmlidXRlcywgdGV4dCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5hdHRyaWJ1dGUgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICAgICAgdmFyIGF0dE5hbWUsIGF0dFZhbHVlO1xuICAgICAgaWYgKCF0aGlzLmN1cnJlbnROb2RlIHx8IHRoaXMuY3VycmVudE5vZGUuY2hpbGRyZW4pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYXR0KCkgY2FuIG9ubHkgYmUgdXNlZCBpbW1lZGlhdGVseSBhZnRlciBhbiBlbGUoKSBjYWxsIGluIGNhbGxiYWNrIG1vZGUuIFwiICsgdGhpcy5kZWJ1Z0luZm8obmFtZSkpO1xuICAgICAgfVxuICAgICAgaWYgKG5hbWUgIT0gbnVsbCkge1xuICAgICAgICBuYW1lID0gZ2V0VmFsdWUobmFtZSk7XG4gICAgICB9XG4gICAgICBpZiAoaXNPYmplY3QobmFtZSkpIHtcbiAgICAgICAgZm9yIChhdHROYW1lIGluIG5hbWUpIHtcbiAgICAgICAgICBpZiAoIWhhc1Byb3AuY2FsbChuYW1lLCBhdHROYW1lKSkgY29udGludWU7XG4gICAgICAgICAgYXR0VmFsdWUgPSBuYW1lW2F0dE5hbWVdO1xuICAgICAgICAgIHRoaXMuYXR0cmlidXRlKGF0dE5hbWUsIGF0dFZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZS5hcHBseSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMua2VlcE51bGxBdHRyaWJ1dGVzICYmICh2YWx1ZSA9PSBudWxsKSkge1xuICAgICAgICAgIHRoaXMuY3VycmVudE5vZGUuYXR0cmlic1tuYW1lXSA9IG5ldyBYTUxBdHRyaWJ1dGUodGhpcywgbmFtZSwgXCJcIik7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgICAgIHRoaXMuY3VycmVudE5vZGUuYXR0cmlic1tuYW1lXSA9IG5ldyBYTUxBdHRyaWJ1dGUodGhpcywgbmFtZSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUudGV4dCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICB2YXIgbm9kZTtcbiAgICAgIHRoaXMub3BlbkN1cnJlbnQoKTtcbiAgICAgIG5vZGUgPSBuZXcgWE1MVGV4dCh0aGlzLCB2YWx1ZSk7XG4gICAgICB0aGlzLm9uRGF0YSh0aGlzLndyaXRlci50ZXh0KG5vZGUsIHRoaXMud3JpdGVyT3B0aW9ucywgdGhpcy5jdXJyZW50TGV2ZWwgKyAxKSwgdGhpcy5jdXJyZW50TGV2ZWwgKyAxKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5jZGF0YSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICB2YXIgbm9kZTtcbiAgICAgIHRoaXMub3BlbkN1cnJlbnQoKTtcbiAgICAgIG5vZGUgPSBuZXcgWE1MQ0RhdGEodGhpcywgdmFsdWUpO1xuICAgICAgdGhpcy5vbkRhdGEodGhpcy53cml0ZXIuY2RhdGEobm9kZSwgdGhpcy53cml0ZXJPcHRpb25zLCB0aGlzLmN1cnJlbnRMZXZlbCArIDEpLCB0aGlzLmN1cnJlbnRMZXZlbCArIDEpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50Q0IucHJvdG90eXBlLmNvbW1lbnQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgdmFyIG5vZGU7XG4gICAgICB0aGlzLm9wZW5DdXJyZW50KCk7XG4gICAgICBub2RlID0gbmV3IFhNTENvbW1lbnQodGhpcywgdmFsdWUpO1xuICAgICAgdGhpcy5vbkRhdGEodGhpcy53cml0ZXIuY29tbWVudChub2RlLCB0aGlzLndyaXRlck9wdGlvbnMsIHRoaXMuY3VycmVudExldmVsICsgMSksIHRoaXMuY3VycmVudExldmVsICsgMSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUucmF3ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHZhciBub2RlO1xuICAgICAgdGhpcy5vcGVuQ3VycmVudCgpO1xuICAgICAgbm9kZSA9IG5ldyBYTUxSYXcodGhpcywgdmFsdWUpO1xuICAgICAgdGhpcy5vbkRhdGEodGhpcy53cml0ZXIucmF3KG5vZGUsIHRoaXMud3JpdGVyT3B0aW9ucywgdGhpcy5jdXJyZW50TGV2ZWwgKyAxKSwgdGhpcy5jdXJyZW50TGV2ZWwgKyAxKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5pbnN0cnVjdGlvbiA9IGZ1bmN0aW9uKHRhcmdldCwgdmFsdWUpIHtcbiAgICAgIHZhciBpLCBpbnNUYXJnZXQsIGluc1ZhbHVlLCBsZW4sIG5vZGU7XG4gICAgICB0aGlzLm9wZW5DdXJyZW50KCk7XG4gICAgICBpZiAodGFyZ2V0ICE9IG51bGwpIHtcbiAgICAgICAgdGFyZ2V0ID0gZ2V0VmFsdWUodGFyZ2V0KTtcbiAgICAgIH1cbiAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgIHZhbHVlID0gZ2V0VmFsdWUodmFsdWUpO1xuICAgICAgfVxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGFyZ2V0KSkge1xuICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSB0YXJnZXQubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICBpbnNUYXJnZXQgPSB0YXJnZXRbaV07XG4gICAgICAgICAgdGhpcy5pbnN0cnVjdGlvbihpbnNUYXJnZXQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHRhcmdldCkpIHtcbiAgICAgICAgZm9yIChpbnNUYXJnZXQgaW4gdGFyZ2V0KSB7XG4gICAgICAgICAgaWYgKCFoYXNQcm9wLmNhbGwodGFyZ2V0LCBpbnNUYXJnZXQpKSBjb250aW51ZTtcbiAgICAgICAgICBpbnNWYWx1ZSA9IHRhcmdldFtpbnNUYXJnZXRdO1xuICAgICAgICAgIHRoaXMuaW5zdHJ1Y3Rpb24oaW5zVGFyZ2V0LCBpbnNWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlID0gdmFsdWUuYXBwbHkoKTtcbiAgICAgICAgfVxuICAgICAgICBub2RlID0gbmV3IFhNTFByb2Nlc3NpbmdJbnN0cnVjdGlvbih0aGlzLCB0YXJnZXQsIHZhbHVlKTtcbiAgICAgICAgdGhpcy5vbkRhdGEodGhpcy53cml0ZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKG5vZGUsIHRoaXMud3JpdGVyT3B0aW9ucywgdGhpcy5jdXJyZW50TGV2ZWwgKyAxKSwgdGhpcy5jdXJyZW50TGV2ZWwgKyAxKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5kZWNsYXJhdGlvbiA9IGZ1bmN0aW9uKHZlcnNpb24sIGVuY29kaW5nLCBzdGFuZGFsb25lKSB7XG4gICAgICB2YXIgbm9kZTtcbiAgICAgIHRoaXMub3BlbkN1cnJlbnQoKTtcbiAgICAgIGlmICh0aGlzLmRvY3VtZW50U3RhcnRlZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJkZWNsYXJhdGlvbigpIG11c3QgYmUgdGhlIGZpcnN0IG5vZGUuXCIpO1xuICAgICAgfVxuICAgICAgbm9kZSA9IG5ldyBYTUxEZWNsYXJhdGlvbih0aGlzLCB2ZXJzaW9uLCBlbmNvZGluZywgc3RhbmRhbG9uZSk7XG4gICAgICB0aGlzLm9uRGF0YSh0aGlzLndyaXRlci5kZWNsYXJhdGlvbihub2RlLCB0aGlzLndyaXRlck9wdGlvbnMsIHRoaXMuY3VycmVudExldmVsICsgMSksIHRoaXMuY3VycmVudExldmVsICsgMSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUuZG9jdHlwZSA9IGZ1bmN0aW9uKHJvb3QsIHB1YklELCBzeXNJRCkge1xuICAgICAgdGhpcy5vcGVuQ3VycmVudCgpO1xuICAgICAgaWYgKHJvb3QgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIHJvb3Qgbm9kZSBuYW1lLlwiKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnJvb3QpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZHRkKCkgbXVzdCBjb21lIGJlZm9yZSB0aGUgcm9vdCBub2RlLlwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY3VycmVudE5vZGUgPSBuZXcgWE1MRG9jVHlwZSh0aGlzLCBwdWJJRCwgc3lzSUQpO1xuICAgICAgdGhpcy5jdXJyZW50Tm9kZS5yb290Tm9kZU5hbWUgPSByb290O1xuICAgICAgdGhpcy5jdXJyZW50Tm9kZS5jaGlsZHJlbiA9IGZhbHNlO1xuICAgICAgdGhpcy5jdXJyZW50TGV2ZWwrKztcbiAgICAgIHRoaXMub3BlblRhZ3NbdGhpcy5jdXJyZW50TGV2ZWxdID0gdGhpcy5jdXJyZW50Tm9kZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5kdGRFbGVtZW50ID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICAgIHZhciBub2RlO1xuICAgICAgdGhpcy5vcGVuQ3VycmVudCgpO1xuICAgICAgbm9kZSA9IG5ldyBYTUxEVERFbGVtZW50KHRoaXMsIG5hbWUsIHZhbHVlKTtcbiAgICAgIHRoaXMub25EYXRhKHRoaXMud3JpdGVyLmR0ZEVsZW1lbnQobm9kZSwgdGhpcy53cml0ZXJPcHRpb25zLCB0aGlzLmN1cnJlbnRMZXZlbCArIDEpLCB0aGlzLmN1cnJlbnRMZXZlbCArIDEpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50Q0IucHJvdG90eXBlLmF0dExpc3QgPSBmdW5jdGlvbihlbGVtZW50TmFtZSwgYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlVHlwZSwgZGVmYXVsdFZhbHVlVHlwZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICB2YXIgbm9kZTtcbiAgICAgIHRoaXMub3BlbkN1cnJlbnQoKTtcbiAgICAgIG5vZGUgPSBuZXcgWE1MRFREQXR0TGlzdCh0aGlzLCBlbGVtZW50TmFtZSwgYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlVHlwZSwgZGVmYXVsdFZhbHVlVHlwZSwgZGVmYXVsdFZhbHVlKTtcbiAgICAgIHRoaXMub25EYXRhKHRoaXMud3JpdGVyLmR0ZEF0dExpc3Qobm9kZSwgdGhpcy53cml0ZXJPcHRpb25zLCB0aGlzLmN1cnJlbnRMZXZlbCArIDEpLCB0aGlzLmN1cnJlbnRMZXZlbCArIDEpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50Q0IucHJvdG90eXBlLmVudGl0eSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICB2YXIgbm9kZTtcbiAgICAgIHRoaXMub3BlbkN1cnJlbnQoKTtcbiAgICAgIG5vZGUgPSBuZXcgWE1MRFRERW50aXR5KHRoaXMsIGZhbHNlLCBuYW1lLCB2YWx1ZSk7XG4gICAgICB0aGlzLm9uRGF0YSh0aGlzLndyaXRlci5kdGRFbnRpdHkobm9kZSwgdGhpcy53cml0ZXJPcHRpb25zLCB0aGlzLmN1cnJlbnRMZXZlbCArIDEpLCB0aGlzLmN1cnJlbnRMZXZlbCArIDEpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50Q0IucHJvdG90eXBlLnBFbnRpdHkgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICAgICAgdmFyIG5vZGU7XG4gICAgICB0aGlzLm9wZW5DdXJyZW50KCk7XG4gICAgICBub2RlID0gbmV3IFhNTERUREVudGl0eSh0aGlzLCB0cnVlLCBuYW1lLCB2YWx1ZSk7XG4gICAgICB0aGlzLm9uRGF0YSh0aGlzLndyaXRlci5kdGRFbnRpdHkobm9kZSwgdGhpcy53cml0ZXJPcHRpb25zLCB0aGlzLmN1cnJlbnRMZXZlbCArIDEpLCB0aGlzLmN1cnJlbnRMZXZlbCArIDEpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50Q0IucHJvdG90eXBlLm5vdGF0aW9uID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICAgIHZhciBub2RlO1xuICAgICAgdGhpcy5vcGVuQ3VycmVudCgpO1xuICAgICAgbm9kZSA9IG5ldyBYTUxEVEROb3RhdGlvbih0aGlzLCBuYW1lLCB2YWx1ZSk7XG4gICAgICB0aGlzLm9uRGF0YSh0aGlzLndyaXRlci5kdGROb3RhdGlvbihub2RlLCB0aGlzLndyaXRlck9wdGlvbnMsIHRoaXMuY3VycmVudExldmVsICsgMSksIHRoaXMuY3VycmVudExldmVsICsgMSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUudXAgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRMZXZlbCA8IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIGRvY3VtZW50IG5vZGUgaGFzIG5vIHBhcmVudC5cIik7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5jdXJyZW50Tm9kZSkge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50Tm9kZS5jaGlsZHJlbikge1xuICAgICAgICAgIHRoaXMuY2xvc2VOb2RlKHRoaXMuY3VycmVudE5vZGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMub3Blbk5vZGUodGhpcy5jdXJyZW50Tm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jdXJyZW50Tm9kZSA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNsb3NlTm9kZSh0aGlzLm9wZW5UYWdzW3RoaXMuY3VycmVudExldmVsXSk7XG4gICAgICB9XG4gICAgICBkZWxldGUgdGhpcy5vcGVuVGFnc1t0aGlzLmN1cnJlbnRMZXZlbF07XG4gICAgICB0aGlzLmN1cnJlbnRMZXZlbC0tO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50Q0IucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgd2hpbGUgKHRoaXMuY3VycmVudExldmVsID49IDApIHtcbiAgICAgICAgdGhpcy51cCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMub25FbmQoKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUub3BlbkN1cnJlbnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmN1cnJlbnROb2RlKSB7XG4gICAgICAgIHRoaXMuY3VycmVudE5vZGUuY2hpbGRyZW4gPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcy5vcGVuTm9kZSh0aGlzLmN1cnJlbnROb2RlKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUub3Blbk5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgICB2YXIgYXR0LCBjaHVuaywgbmFtZSwgcmVmMTtcbiAgICAgIGlmICghbm9kZS5pc09wZW4pIHtcbiAgICAgICAgaWYgKCF0aGlzLnJvb3QgJiYgdGhpcy5jdXJyZW50TGV2ZWwgPT09IDAgJiYgbm9kZS50eXBlID09PSBOb2RlVHlwZS5FbGVtZW50KSB7XG4gICAgICAgICAgdGhpcy5yb290ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBjaHVuayA9ICcnO1xuICAgICAgICBpZiAobm9kZS50eXBlID09PSBOb2RlVHlwZS5FbGVtZW50KSB7XG4gICAgICAgICAgdGhpcy53cml0ZXJPcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuT3BlblRhZztcbiAgICAgICAgICBjaHVuayA9IHRoaXMud3JpdGVyLmluZGVudChub2RlLCB0aGlzLndyaXRlck9wdGlvbnMsIHRoaXMuY3VycmVudExldmVsKSArICc8JyArIG5vZGUubmFtZTtcbiAgICAgICAgICByZWYxID0gbm9kZS5hdHRyaWJzO1xuICAgICAgICAgIGZvciAobmFtZSBpbiByZWYxKSB7XG4gICAgICAgICAgICBpZiAoIWhhc1Byb3AuY2FsbChyZWYxLCBuYW1lKSkgY29udGludWU7XG4gICAgICAgICAgICBhdHQgPSByZWYxW25hbWVdO1xuICAgICAgICAgICAgY2h1bmsgKz0gdGhpcy53cml0ZXIuYXR0cmlidXRlKGF0dCwgdGhpcy53cml0ZXJPcHRpb25zLCB0aGlzLmN1cnJlbnRMZXZlbCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNodW5rICs9IChub2RlLmNoaWxkcmVuID8gJz4nIDogJy8+JykgKyB0aGlzLndyaXRlci5lbmRsaW5lKG5vZGUsIHRoaXMud3JpdGVyT3B0aW9ucywgdGhpcy5jdXJyZW50TGV2ZWwpO1xuICAgICAgICAgIHRoaXMud3JpdGVyT3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkluc2lkZVRhZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLndyaXRlck9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5PcGVuVGFnO1xuICAgICAgICAgIGNodW5rID0gdGhpcy53cml0ZXIuaW5kZW50KG5vZGUsIHRoaXMud3JpdGVyT3B0aW9ucywgdGhpcy5jdXJyZW50TGV2ZWwpICsgJzwhRE9DVFlQRSAnICsgbm9kZS5yb290Tm9kZU5hbWU7XG4gICAgICAgICAgaWYgKG5vZGUucHViSUQgJiYgbm9kZS5zeXNJRCkge1xuICAgICAgICAgICAgY2h1bmsgKz0gJyBQVUJMSUMgXCInICsgbm9kZS5wdWJJRCArICdcIiBcIicgKyBub2RlLnN5c0lEICsgJ1wiJztcbiAgICAgICAgICB9IGVsc2UgaWYgKG5vZGUuc3lzSUQpIHtcbiAgICAgICAgICAgIGNodW5rICs9ICcgU1lTVEVNIFwiJyArIG5vZGUuc3lzSUQgKyAnXCInO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobm9kZS5jaGlsZHJlbikge1xuICAgICAgICAgICAgY2h1bmsgKz0gJyBbJztcbiAgICAgICAgICAgIHRoaXMud3JpdGVyT3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkluc2lkZVRhZztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy53cml0ZXJPcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuQ2xvc2VUYWc7XG4gICAgICAgICAgICBjaHVuayArPSAnPic7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNodW5rICs9IHRoaXMud3JpdGVyLmVuZGxpbmUobm9kZSwgdGhpcy53cml0ZXJPcHRpb25zLCB0aGlzLmN1cnJlbnRMZXZlbCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbkRhdGEoY2h1bmssIHRoaXMuY3VycmVudExldmVsKTtcbiAgICAgICAgcmV0dXJuIG5vZGUuaXNPcGVuID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUuY2xvc2VOb2RlID0gZnVuY3Rpb24obm9kZSkge1xuICAgICAgdmFyIGNodW5rO1xuICAgICAgaWYgKCFub2RlLmlzQ2xvc2VkKSB7XG4gICAgICAgIGNodW5rID0gJyc7XG4gICAgICAgIHRoaXMud3JpdGVyT3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkNsb3NlVGFnO1xuICAgICAgICBpZiAobm9kZS50eXBlID09PSBOb2RlVHlwZS5FbGVtZW50KSB7XG4gICAgICAgICAgY2h1bmsgPSB0aGlzLndyaXRlci5pbmRlbnQobm9kZSwgdGhpcy53cml0ZXJPcHRpb25zLCB0aGlzLmN1cnJlbnRMZXZlbCkgKyAnPC8nICsgbm9kZS5uYW1lICsgJz4nICsgdGhpcy53cml0ZXIuZW5kbGluZShub2RlLCB0aGlzLndyaXRlck9wdGlvbnMsIHRoaXMuY3VycmVudExldmVsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjaHVuayA9IHRoaXMud3JpdGVyLmluZGVudChub2RlLCB0aGlzLndyaXRlck9wdGlvbnMsIHRoaXMuY3VycmVudExldmVsKSArICddPicgKyB0aGlzLndyaXRlci5lbmRsaW5lKG5vZGUsIHRoaXMud3JpdGVyT3B0aW9ucywgdGhpcy5jdXJyZW50TGV2ZWwpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud3JpdGVyT3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLk5vbmU7XG4gICAgICAgIHRoaXMub25EYXRhKGNodW5rLCB0aGlzLmN1cnJlbnRMZXZlbCk7XG4gICAgICAgIHJldHVybiBub2RlLmlzQ2xvc2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24oY2h1bmssIGxldmVsKSB7XG4gICAgICB0aGlzLmRvY3VtZW50U3RhcnRlZCA9IHRydWU7XG4gICAgICByZXR1cm4gdGhpcy5vbkRhdGFDYWxsYmFjayhjaHVuaywgbGV2ZWwgKyAxKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUub25FbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuZG9jdW1lbnRDb21wbGV0ZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIHRoaXMub25FbmRDYWxsYmFjaygpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5kZWJ1Z0luZm8gPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICBpZiAobmFtZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFwibm9kZTogPFwiICsgbmFtZSArIFwiPlwiO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5lbGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUubm9kID0gZnVuY3Rpb24obmFtZSwgYXR0cmlidXRlcywgdGV4dCkge1xuICAgICAgcmV0dXJuIHRoaXMubm9kZShuYW1lLCBhdHRyaWJ1dGVzLCB0ZXh0KTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUudHh0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnRleHQodmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5kYXQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuY2RhdGEodmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5jb20gPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuY29tbWVudCh2YWx1ZSk7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50Q0IucHJvdG90eXBlLmlucyA9IGZ1bmN0aW9uKHRhcmdldCwgdmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmluc3RydWN0aW9uKHRhcmdldCwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5kZWMgPSBmdW5jdGlvbih2ZXJzaW9uLCBlbmNvZGluZywgc3RhbmRhbG9uZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVjbGFyYXRpb24odmVyc2lvbiwgZW5jb2RpbmcsIHN0YW5kYWxvbmUpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5kdGQgPSBmdW5jdGlvbihyb290LCBwdWJJRCwgc3lzSUQpIHtcbiAgICAgIHJldHVybiB0aGlzLmRvY3R5cGUocm9vdCwgcHViSUQsIHN5c0lEKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUuZSA9IGZ1bmN0aW9uKG5hbWUsIGF0dHJpYnV0ZXMsIHRleHQpIHtcbiAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQobmFtZSwgYXR0cmlidXRlcywgdGV4dCk7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50Q0IucHJvdG90eXBlLm4gPSBmdW5jdGlvbihuYW1lLCBhdHRyaWJ1dGVzLCB0ZXh0KSB7XG4gICAgICByZXR1cm4gdGhpcy5ub2RlKG5hbWUsIGF0dHJpYnV0ZXMsIHRleHQpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS50ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnRleHQodmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5kID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmNkYXRhKHZhbHVlKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUuYyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb21tZW50KHZhbHVlKTtcbiAgICB9O1xuXG4gICAgWE1MRG9jdW1lbnRDQi5wcm90b3R5cGUuciA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5yYXcodmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5pID0gZnVuY3Rpb24odGFyZ2V0LCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaW5zdHJ1Y3Rpb24odGFyZ2V0LCB2YWx1ZSk7XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50Q0IucHJvdG90eXBlLmF0dCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuY3VycmVudE5vZGUgJiYgdGhpcy5jdXJyZW50Tm9kZS50eXBlID09PSBOb2RlVHlwZS5Eb2NUeXBlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmF0dExpc3QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmF0dHJpYnV0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5hID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5jdXJyZW50Tm9kZSAmJiB0aGlzLmN1cnJlbnROb2RlLnR5cGUgPT09IE5vZGVUeXBlLkRvY1R5cGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXR0TGlzdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXR0cmlidXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFhNTERvY3VtZW50Q0IucHJvdG90eXBlLmVudCA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbnRpdHkobmFtZSwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5wZW50ID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnBFbnRpdHkobmFtZSwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxEb2N1bWVudENCLnByb3RvdHlwZS5ub3QgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMubm90YXRpb24obmFtZSwgdmFsdWUpO1xuICAgIH07XG5cbiAgICByZXR1cm4gWE1MRG9jdW1lbnRDQjtcblxuICB9KSgpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIE5vZGVUeXBlLCBYTUxEdW1teSwgWE1MTm9kZSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIFhNTE5vZGUgPSByZXF1aXJlKCcuL1hNTE5vZGUnKTtcblxuICBOb2RlVHlwZSA9IHJlcXVpcmUoJy4vTm9kZVR5cGUnKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFhNTER1bW15ID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoWE1MRHVtbXksIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gWE1MRHVtbXkocGFyZW50KSB7XG4gICAgICBYTUxEdW1teS5fX3N1cGVyX18uY29uc3RydWN0b3IuY2FsbCh0aGlzLCBwYXJlbnQpO1xuICAgICAgdGhpcy50eXBlID0gTm9kZVR5cGUuRHVtbXk7XG4gICAgfVxuXG4gICAgWE1MRHVtbXkucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZSh0aGlzKTtcbiAgICB9O1xuXG4gICAgWE1MRHVtbXkucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH07XG5cbiAgICByZXR1cm4gWE1MRHVtbXk7XG5cbiAgfSkoWE1MTm9kZSk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgTm9kZVR5cGUsIFhNTEF0dHJpYnV0ZSwgWE1MRWxlbWVudCwgWE1MTmFtZWROb2RlTWFwLCBYTUxOb2RlLCBnZXRWYWx1ZSwgaXNGdW5jdGlvbiwgaXNPYmplY3QsIHJlZixcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIHJlZiA9IHJlcXVpcmUoJy4vVXRpbGl0eScpLCBpc09iamVjdCA9IHJlZi5pc09iamVjdCwgaXNGdW5jdGlvbiA9IHJlZi5pc0Z1bmN0aW9uLCBnZXRWYWx1ZSA9IHJlZi5nZXRWYWx1ZTtcblxuICBYTUxOb2RlID0gcmVxdWlyZSgnLi9YTUxOb2RlJyk7XG5cbiAgTm9kZVR5cGUgPSByZXF1aXJlKCcuL05vZGVUeXBlJyk7XG5cbiAgWE1MQXR0cmlidXRlID0gcmVxdWlyZSgnLi9YTUxBdHRyaWJ1dGUnKTtcblxuICBYTUxOYW1lZE5vZGVNYXAgPSByZXF1aXJlKCcuL1hNTE5hbWVkTm9kZU1hcCcpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MRWxlbWVudCA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFhNTEVsZW1lbnQsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gWE1MRWxlbWVudChwYXJlbnQsIG5hbWUsIGF0dHJpYnV0ZXMpIHtcbiAgICAgIHZhciBjaGlsZCwgaiwgbGVuLCByZWYxO1xuICAgICAgWE1MRWxlbWVudC5fX3N1cGVyX18uY29uc3RydWN0b3IuY2FsbCh0aGlzLCBwYXJlbnQpO1xuICAgICAgaWYgKG5hbWUgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGVsZW1lbnQgbmFtZS4gXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubmFtZSA9IHRoaXMuc3RyaW5naWZ5Lm5hbWUobmFtZSk7XG4gICAgICB0aGlzLnR5cGUgPSBOb2RlVHlwZS5FbGVtZW50O1xuICAgICAgdGhpcy5hdHRyaWJzID0ge307XG4gICAgICB0aGlzLnNjaGVtYVR5cGVJbmZvID0gbnVsbDtcbiAgICAgIGlmIChhdHRyaWJ1dGVzICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGUoYXR0cmlidXRlcyk7XG4gICAgICB9XG4gICAgICBpZiAocGFyZW50LnR5cGUgPT09IE5vZGVUeXBlLkRvY3VtZW50KSB7XG4gICAgICAgIHRoaXMuaXNSb290ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5kb2N1bWVudE9iamVjdCA9IHBhcmVudDtcbiAgICAgICAgcGFyZW50LnJvb3RPYmplY3QgPSB0aGlzO1xuICAgICAgICBpZiAocGFyZW50LmNoaWxkcmVuKSB7XG4gICAgICAgICAgcmVmMSA9IHBhcmVudC5jaGlsZHJlbjtcbiAgICAgICAgICBmb3IgKGogPSAwLCBsZW4gPSByZWYxLmxlbmd0aDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgICBjaGlsZCA9IHJlZjFbal07XG4gICAgICAgICAgICBpZiAoY2hpbGQudHlwZSA9PT0gTm9kZVR5cGUuRG9jVHlwZSkge1xuICAgICAgICAgICAgICBjaGlsZC5uYW1lID0gdGhpcy5uYW1lO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MRWxlbWVudC5wcm90b3R5cGUsICd0YWdOYW1lJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxFbGVtZW50LnByb3RvdHlwZSwgJ25hbWVzcGFjZVVSSScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxFbGVtZW50LnByb3RvdHlwZSwgJ3ByZWZpeCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxFbGVtZW50LnByb3RvdHlwZSwgJ2xvY2FsTmFtZScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MRWxlbWVudC5wcm90b3R5cGUsICdpZCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxFbGVtZW50LnByb3RvdHlwZSwgJ2NsYXNzTmFtZScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxFbGVtZW50LnByb3RvdHlwZSwgJ2NsYXNzTGlzdCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxFbGVtZW50LnByb3RvdHlwZSwgJ2F0dHJpYnV0ZXMnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoIXRoaXMuYXR0cmlidXRlTWFwIHx8ICF0aGlzLmF0dHJpYnV0ZU1hcC5ub2Rlcykge1xuICAgICAgICAgIHRoaXMuYXR0cmlidXRlTWFwID0gbmV3IFhNTE5hbWVkTm9kZU1hcCh0aGlzLmF0dHJpYnMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmF0dHJpYnV0ZU1hcDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYXR0LCBhdHROYW1lLCBjbG9uZWRTZWxmLCByZWYxO1xuICAgICAgY2xvbmVkU2VsZiA9IE9iamVjdC5jcmVhdGUodGhpcyk7XG4gICAgICBpZiAoY2xvbmVkU2VsZi5pc1Jvb3QpIHtcbiAgICAgICAgY2xvbmVkU2VsZi5kb2N1bWVudE9iamVjdCA9IG51bGw7XG4gICAgICB9XG4gICAgICBjbG9uZWRTZWxmLmF0dHJpYnMgPSB7fTtcbiAgICAgIHJlZjEgPSB0aGlzLmF0dHJpYnM7XG4gICAgICBmb3IgKGF0dE5hbWUgaW4gcmVmMSkge1xuICAgICAgICBpZiAoIWhhc1Byb3AuY2FsbChyZWYxLCBhdHROYW1lKSkgY29udGludWU7XG4gICAgICAgIGF0dCA9IHJlZjFbYXR0TmFtZV07XG4gICAgICAgIGNsb25lZFNlbGYuYXR0cmlic1thdHROYW1lXSA9IGF0dC5jbG9uZSgpO1xuICAgICAgfVxuICAgICAgY2xvbmVkU2VsZi5jaGlsZHJlbiA9IFtdO1xuICAgICAgdGhpcy5jaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICAgIHZhciBjbG9uZWRDaGlsZDtcbiAgICAgICAgY2xvbmVkQ2hpbGQgPSBjaGlsZC5jbG9uZSgpO1xuICAgICAgICBjbG9uZWRDaGlsZC5wYXJlbnQgPSBjbG9uZWRTZWxmO1xuICAgICAgICByZXR1cm4gY2xvbmVkU2VsZi5jaGlsZHJlbi5wdXNoKGNsb25lZENoaWxkKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGNsb25lZFNlbGY7XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLmF0dHJpYnV0ZSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICB2YXIgYXR0TmFtZSwgYXR0VmFsdWU7XG4gICAgICBpZiAobmFtZSAhPSBudWxsKSB7XG4gICAgICAgIG5hbWUgPSBnZXRWYWx1ZShuYW1lKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc09iamVjdChuYW1lKSkge1xuICAgICAgICBmb3IgKGF0dE5hbWUgaW4gbmFtZSkge1xuICAgICAgICAgIGlmICghaGFzUHJvcC5jYWxsKG5hbWUsIGF0dE5hbWUpKSBjb250aW51ZTtcbiAgICAgICAgICBhdHRWYWx1ZSA9IG5hbWVbYXR0TmFtZV07XG4gICAgICAgICAgdGhpcy5hdHRyaWJ1dGUoYXR0TmFtZSwgYXR0VmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmFwcGx5KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5rZWVwTnVsbEF0dHJpYnV0ZXMgJiYgKHZhbHVlID09IG51bGwpKSB7XG4gICAgICAgICAgdGhpcy5hdHRyaWJzW25hbWVdID0gbmV3IFhNTEF0dHJpYnV0ZSh0aGlzLCBuYW1lLCBcIlwiKTtcbiAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5hdHRyaWJzW25hbWVdID0gbmV3IFhNTEF0dHJpYnV0ZSh0aGlzLCBuYW1lLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBYTUxFbGVtZW50LnByb3RvdHlwZS5yZW1vdmVBdHRyaWJ1dGUgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICB2YXIgYXR0TmFtZSwgaiwgbGVuO1xuICAgICAgaWYgKG5hbWUgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZSBuYW1lLiBcIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgICAgfVxuICAgICAgbmFtZSA9IGdldFZhbHVlKG5hbWUpO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkobmFtZSkpIHtcbiAgICAgICAgZm9yIChqID0gMCwgbGVuID0gbmFtZS5sZW5ndGg7IGogPCBsZW47IGorKykge1xuICAgICAgICAgIGF0dE5hbWUgPSBuYW1lW2pdO1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLmF0dHJpYnNbYXR0TmFtZV07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmF0dHJpYnNbbmFtZV07XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MRWxlbWVudC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLndyaXRlci5lbGVtZW50KHRoaXMsIHRoaXMub3B0aW9ucy53cml0ZXIuZmlsdGVyT3B0aW9ucyhvcHRpb25zKSk7XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLmF0dCA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5hdHRyaWJ1dGUobmFtZSwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxFbGVtZW50LnByb3RvdHlwZS5hID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmF0dHJpYnV0ZShuYW1lLCB2YWx1ZSk7XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLmdldEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIGlmICh0aGlzLmF0dHJpYnMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXR0cmlic1tuYW1lXS52YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBYTUxFbGVtZW50LnByb3RvdHlwZS5zZXRBdHRyaWJ1dGUgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxFbGVtZW50LnByb3RvdHlwZS5nZXRBdHRyaWJ1dGVOb2RlID0gZnVuY3Rpb24obmFtZSkge1xuICAgICAgaWYgKHRoaXMuYXR0cmlicy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5hdHRyaWJzW25hbWVdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLnNldEF0dHJpYnV0ZU5vZGUgPSBmdW5jdGlvbihuZXdBdHRyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLnJlbW92ZUF0dHJpYnV0ZU5vZGUgPSBmdW5jdGlvbihvbGRBdHRyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLmdldEVsZW1lbnRzQnlUYWdOYW1lID0gZnVuY3Rpb24obmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxFbGVtZW50LnByb3RvdHlwZS5nZXRBdHRyaWJ1dGVOUyA9IGZ1bmN0aW9uKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLnNldEF0dHJpYnV0ZU5TID0gZnVuY3Rpb24obmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lLCB2YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxFbGVtZW50LnByb3RvdHlwZS5yZW1vdmVBdHRyaWJ1dGVOUyA9IGZ1bmN0aW9uKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLmdldEF0dHJpYnV0ZU5vZGVOUyA9IGZ1bmN0aW9uKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLnNldEF0dHJpYnV0ZU5vZGVOUyA9IGZ1bmN0aW9uKG5ld0F0dHIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRWxlbWVudC5wcm90b3R5cGUuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyA9IGZ1bmN0aW9uKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLmhhc0F0dHJpYnV0ZSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmF0dHJpYnMuaGFzT3duUHJvcGVydHkobmFtZSk7XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLmhhc0F0dHJpYnV0ZU5TID0gZnVuY3Rpb24obmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRWxlbWVudC5wcm90b3R5cGUuc2V0SWRBdHRyaWJ1dGUgPSBmdW5jdGlvbihuYW1lLCBpc0lkKSB7XG4gICAgICBpZiAodGhpcy5hdHRyaWJzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmF0dHJpYnNbbmFtZV0uaXNJZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBpc0lkO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBYTUxFbGVtZW50LnByb3RvdHlwZS5zZXRJZEF0dHJpYnV0ZU5TID0gZnVuY3Rpb24obmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIGlzSWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRWxlbWVudC5wcm90b3R5cGUuc2V0SWRBdHRyaWJ1dGVOb2RlID0gZnVuY3Rpb24oaWRBdHRyLCBpc0lkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTEVsZW1lbnQucHJvdG90eXBlLmdldEVsZW1lbnRzQnlUYWdOYW1lID0gZnVuY3Rpb24odGFnbmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxFbGVtZW50LnByb3RvdHlwZS5nZXRFbGVtZW50c0J5VGFnTmFtZU5TID0gZnVuY3Rpb24obmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRWxlbWVudC5wcm90b3R5cGUuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSA9IGZ1bmN0aW9uKGNsYXNzTmFtZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MRWxlbWVudC5wcm90b3R5cGUuaXNFcXVhbE5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgICB2YXIgaSwgaiwgcmVmMTtcbiAgICAgIGlmICghWE1MRWxlbWVudC5fX3N1cGVyX18uaXNFcXVhbE5vZGUuYXBwbHkodGhpcywgYXJndW1lbnRzKS5pc0VxdWFsTm9kZShub2RlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobm9kZS5uYW1lc3BhY2VVUkkgIT09IHRoaXMubmFtZXNwYWNlVVJJKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChub2RlLnByZWZpeCAhPT0gdGhpcy5wcmVmaXgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKG5vZGUubG9jYWxOYW1lICE9PSB0aGlzLmxvY2FsTmFtZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobm9kZS5hdHRyaWJzLmxlbmd0aCAhPT0gdGhpcy5hdHRyaWJzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBmb3IgKGkgPSBqID0gMCwgcmVmMSA9IHRoaXMuYXR0cmlicy5sZW5ndGggLSAxOyAwIDw9IHJlZjEgPyBqIDw9IHJlZjEgOiBqID49IHJlZjE7IGkgPSAwIDw9IHJlZjEgPyArK2ogOiAtLWopIHtcbiAgICAgICAgaWYgKCF0aGlzLmF0dHJpYnNbaV0uaXNFcXVhbE5vZGUobm9kZS5hdHRyaWJzW2ldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIHJldHVybiBYTUxFbGVtZW50O1xuXG4gIH0pKFhNTE5vZGUpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIFhNTE5hbWVkTm9kZU1hcDtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFhNTE5hbWVkTm9kZU1hcCA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBYTUxOYW1lZE5vZGVNYXAobm9kZXMpIHtcbiAgICAgIHRoaXMubm9kZXMgPSBub2RlcztcbiAgICB9XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MTmFtZWROb2RlTWFwLnByb3RvdHlwZSwgJ2xlbmd0aCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLm5vZGVzKS5sZW5ndGggfHwgMDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIFhNTE5hbWVkTm9kZU1hcC5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLm5vZGVzID0gbnVsbDtcbiAgICB9O1xuXG4gICAgWE1MTmFtZWROb2RlTWFwLnByb3RvdHlwZS5nZXROYW1lZEl0ZW0gPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5ub2Rlc1tuYW1lXTtcbiAgICB9O1xuXG4gICAgWE1MTmFtZWROb2RlTWFwLnByb3RvdHlwZS5zZXROYW1lZEl0ZW0gPSBmdW5jdGlvbihub2RlKSB7XG4gICAgICB2YXIgb2xkTm9kZTtcbiAgICAgIG9sZE5vZGUgPSB0aGlzLm5vZGVzW25vZGUubm9kZU5hbWVdO1xuICAgICAgdGhpcy5ub2Rlc1tub2RlLm5vZGVOYW1lXSA9IG5vZGU7XG4gICAgICByZXR1cm4gb2xkTm9kZSB8fCBudWxsO1xuICAgIH07XG5cbiAgICBYTUxOYW1lZE5vZGVNYXAucHJvdG90eXBlLnJlbW92ZU5hbWVkSXRlbSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIHZhciBvbGROb2RlO1xuICAgICAgb2xkTm9kZSA9IHRoaXMubm9kZXNbbmFtZV07XG4gICAgICBkZWxldGUgdGhpcy5ub2Rlc1tuYW1lXTtcbiAgICAgIHJldHVybiBvbGROb2RlIHx8IG51bGw7XG4gICAgfTtcblxuICAgIFhNTE5hbWVkTm9kZU1hcC5wcm90b3R5cGUuaXRlbSA9IGZ1bmN0aW9uKGluZGV4KSB7XG4gICAgICByZXR1cm4gdGhpcy5ub2Rlc1tPYmplY3Qua2V5cyh0aGlzLm5vZGVzKVtpbmRleF1dIHx8IG51bGw7XG4gICAgfTtcblxuICAgIFhNTE5hbWVkTm9kZU1hcC5wcm90b3R5cGUuZ2V0TmFtZWRJdGVtTlMgPSBmdW5jdGlvbihuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgfTtcblxuICAgIFhNTE5hbWVkTm9kZU1hcC5wcm90b3R5cGUuc2V0TmFtZWRJdGVtTlMgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiKTtcbiAgICB9O1xuXG4gICAgWE1MTmFtZWROb2RlTWFwLnByb3RvdHlwZS5yZW1vdmVOYW1lZEl0ZW1OUyA9IGZ1bmN0aW9uKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTE5hbWVkTm9kZU1hcDtcblxuICB9KSgpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIERvY3VtZW50UG9zaXRpb24sIE5vZGVUeXBlLCBYTUxDRGF0YSwgWE1MQ29tbWVudCwgWE1MRGVjbGFyYXRpb24sIFhNTERvY1R5cGUsIFhNTER1bW15LCBYTUxFbGVtZW50LCBYTUxOYW1lZE5vZGVNYXAsIFhNTE5vZGUsIFhNTE5vZGVMaXN0LCBYTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24sIFhNTFJhdywgWE1MVGV4dCwgZ2V0VmFsdWUsIGlzRW1wdHksIGlzRnVuY3Rpb24sIGlzT2JqZWN0LCByZWYxLFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICByZWYxID0gcmVxdWlyZSgnLi9VdGlsaXR5JyksIGlzT2JqZWN0ID0gcmVmMS5pc09iamVjdCwgaXNGdW5jdGlvbiA9IHJlZjEuaXNGdW5jdGlvbiwgaXNFbXB0eSA9IHJlZjEuaXNFbXB0eSwgZ2V0VmFsdWUgPSByZWYxLmdldFZhbHVlO1xuXG4gIFhNTEVsZW1lbnQgPSBudWxsO1xuXG4gIFhNTENEYXRhID0gbnVsbDtcblxuICBYTUxDb21tZW50ID0gbnVsbDtcblxuICBYTUxEZWNsYXJhdGlvbiA9IG51bGw7XG5cbiAgWE1MRG9jVHlwZSA9IG51bGw7XG5cbiAgWE1MUmF3ID0gbnVsbDtcblxuICBYTUxUZXh0ID0gbnVsbDtcblxuICBYTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gPSBudWxsO1xuXG4gIFhNTER1bW15ID0gbnVsbDtcblxuICBOb2RlVHlwZSA9IG51bGw7XG5cbiAgWE1MTm9kZUxpc3QgPSBudWxsO1xuXG4gIFhNTE5hbWVkTm9kZU1hcCA9IG51bGw7XG5cbiAgRG9jdW1lbnRQb3NpdGlvbiA9IG51bGw7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBYTUxOb2RlID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIFhNTE5vZGUocGFyZW50MSkge1xuICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQxO1xuICAgICAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IHRoaXMucGFyZW50Lm9wdGlvbnM7XG4gICAgICAgIHRoaXMuc3RyaW5naWZ5ID0gdGhpcy5wYXJlbnQuc3RyaW5naWZ5O1xuICAgICAgfVxuICAgICAgdGhpcy52YWx1ZSA9IG51bGw7XG4gICAgICB0aGlzLmNoaWxkcmVuID0gW107XG4gICAgICB0aGlzLmJhc2VVUkkgPSBudWxsO1xuICAgICAgaWYgKCFYTUxFbGVtZW50KSB7XG4gICAgICAgIFhNTEVsZW1lbnQgPSByZXF1aXJlKCcuL1hNTEVsZW1lbnQnKTtcbiAgICAgICAgWE1MQ0RhdGEgPSByZXF1aXJlKCcuL1hNTENEYXRhJyk7XG4gICAgICAgIFhNTENvbW1lbnQgPSByZXF1aXJlKCcuL1hNTENvbW1lbnQnKTtcbiAgICAgICAgWE1MRGVjbGFyYXRpb24gPSByZXF1aXJlKCcuL1hNTERlY2xhcmF0aW9uJyk7XG4gICAgICAgIFhNTERvY1R5cGUgPSByZXF1aXJlKCcuL1hNTERvY1R5cGUnKTtcbiAgICAgICAgWE1MUmF3ID0gcmVxdWlyZSgnLi9YTUxSYXcnKTtcbiAgICAgICAgWE1MVGV4dCA9IHJlcXVpcmUoJy4vWE1MVGV4dCcpO1xuICAgICAgICBYTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL1hNTFByb2Nlc3NpbmdJbnN0cnVjdGlvbicpO1xuICAgICAgICBYTUxEdW1teSA9IHJlcXVpcmUoJy4vWE1MRHVtbXknKTtcbiAgICAgICAgTm9kZVR5cGUgPSByZXF1aXJlKCcuL05vZGVUeXBlJyk7XG4gICAgICAgIFhNTE5vZGVMaXN0ID0gcmVxdWlyZSgnLi9YTUxOb2RlTGlzdCcpO1xuICAgICAgICBYTUxOYW1lZE5vZGVNYXAgPSByZXF1aXJlKCcuL1hNTE5hbWVkTm9kZU1hcCcpO1xuICAgICAgICBEb2N1bWVudFBvc2l0aW9uID0gcmVxdWlyZSgnLi9Eb2N1bWVudFBvc2l0aW9uJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTE5vZGUucHJvdG90eXBlLCAnbm9kZU5hbWUnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uYW1lO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTE5vZGUucHJvdG90eXBlLCAnbm9kZVR5cGUnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTE5vZGUucHJvdG90eXBlLCAnbm9kZVZhbHVlJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MTm9kZS5wcm90b3R5cGUsICdwYXJlbnROb2RlJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50O1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTE5vZGUucHJvdG90eXBlLCAnY2hpbGROb2RlcycsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICghdGhpcy5jaGlsZE5vZGVMaXN0IHx8ICF0aGlzLmNoaWxkTm9kZUxpc3Qubm9kZXMpIHtcbiAgICAgICAgICB0aGlzLmNoaWxkTm9kZUxpc3QgPSBuZXcgWE1MTm9kZUxpc3QodGhpcy5jaGlsZHJlbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuY2hpbGROb2RlTGlzdDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxOb2RlLnByb3RvdHlwZSwgJ2ZpcnN0Q2hpbGQnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jaGlsZHJlblswXSB8fCBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTE5vZGUucHJvdG90eXBlLCAnbGFzdENoaWxkJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5bdGhpcy5jaGlsZHJlbi5sZW5ndGggLSAxXSB8fCBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTE5vZGUucHJvdG90eXBlLCAncHJldmlvdXNTaWJsaW5nJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIGkgPSB0aGlzLnBhcmVudC5jaGlsZHJlbi5pbmRleE9mKHRoaXMpO1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQuY2hpbGRyZW5baSAtIDFdIHx8IG51bGw7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MTm9kZS5wcm90b3R5cGUsICduZXh0U2libGluZycsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICBpID0gdGhpcy5wYXJlbnQuY2hpbGRyZW4uaW5kZXhPZih0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmNoaWxkcmVuW2kgKyAxXSB8fCBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTE5vZGUucHJvdG90eXBlLCAnb3duZXJEb2N1bWVudCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRvY3VtZW50KCkgfHwgbnVsbDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShYTUxOb2RlLnByb3RvdHlwZSwgJ3RleHRDb250ZW50Jywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGNoaWxkLCBqLCBsZW4sIHJlZjIsIHN0cjtcbiAgICAgICAgaWYgKHRoaXMubm9kZVR5cGUgPT09IE5vZGVUeXBlLkVsZW1lbnQgfHwgdGhpcy5ub2RlVHlwZSA9PT0gTm9kZVR5cGUuRG9jdW1lbnRGcmFnbWVudCkge1xuICAgICAgICAgIHN0ciA9ICcnO1xuICAgICAgICAgIHJlZjIgPSB0aGlzLmNoaWxkcmVuO1xuICAgICAgICAgIGZvciAoaiA9IDAsIGxlbiA9IHJlZjIubGVuZ3RoOyBqIDwgbGVuOyBqKyspIHtcbiAgICAgICAgICAgIGNoaWxkID0gcmVmMltqXTtcbiAgICAgICAgICAgIGlmIChjaGlsZC50ZXh0Q29udGVudCkge1xuICAgICAgICAgICAgICBzdHIgKz0gY2hpbGQudGV4dENvbnRlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBzdHI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLnNldFBhcmVudCA9IGZ1bmN0aW9uKHBhcmVudCkge1xuICAgICAgdmFyIGNoaWxkLCBqLCBsZW4sIHJlZjIsIHJlc3VsdHM7XG4gICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDtcbiAgICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gcGFyZW50Lm9wdGlvbnM7XG4gICAgICAgIHRoaXMuc3RyaW5naWZ5ID0gcGFyZW50LnN0cmluZ2lmeTtcbiAgICAgIH1cbiAgICAgIHJlZjIgPSB0aGlzLmNoaWxkcmVuO1xuICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgZm9yIChqID0gMCwgbGVuID0gcmVmMi5sZW5ndGg7IGogPCBsZW47IGorKykge1xuICAgICAgICBjaGlsZCA9IHJlZjJbal07XG4gICAgICAgIHJlc3VsdHMucHVzaChjaGlsZC5zZXRQYXJlbnQodGhpcykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmVsZW1lbnQgPSBmdW5jdGlvbihuYW1lLCBhdHRyaWJ1dGVzLCB0ZXh0KSB7XG4gICAgICB2YXIgY2hpbGROb2RlLCBpdGVtLCBqLCBrLCBrZXksIGxhc3RDaGlsZCwgbGVuLCBsZW4xLCByZWYyLCByZWYzLCB2YWw7XG4gICAgICBsYXN0Q2hpbGQgPSBudWxsO1xuICAgICAgaWYgKGF0dHJpYnV0ZXMgPT09IG51bGwgJiYgKHRleHQgPT0gbnVsbCkpIHtcbiAgICAgICAgcmVmMiA9IFt7fSwgbnVsbF0sIGF0dHJpYnV0ZXMgPSByZWYyWzBdLCB0ZXh0ID0gcmVmMlsxXTtcbiAgICAgIH1cbiAgICAgIGlmIChhdHRyaWJ1dGVzID09IG51bGwpIHtcbiAgICAgICAgYXR0cmlidXRlcyA9IHt9O1xuICAgICAgfVxuICAgICAgYXR0cmlidXRlcyA9IGdldFZhbHVlKGF0dHJpYnV0ZXMpO1xuICAgICAgaWYgKCFpc09iamVjdChhdHRyaWJ1dGVzKSkge1xuICAgICAgICByZWYzID0gW2F0dHJpYnV0ZXMsIHRleHRdLCB0ZXh0ID0gcmVmM1swXSwgYXR0cmlidXRlcyA9IHJlZjNbMV07XG4gICAgICB9XG4gICAgICBpZiAobmFtZSAhPSBudWxsKSB7XG4gICAgICAgIG5hbWUgPSBnZXRWYWx1ZShuYW1lKTtcbiAgICAgIH1cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KG5hbWUpKSB7XG4gICAgICAgIGZvciAoaiA9IDAsIGxlbiA9IG5hbWUubGVuZ3RoOyBqIDwgbGVuOyBqKyspIHtcbiAgICAgICAgICBpdGVtID0gbmFtZVtqXTtcbiAgICAgICAgICBsYXN0Q2hpbGQgPSB0aGlzLmVsZW1lbnQoaXRlbSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihuYW1lKSkge1xuICAgICAgICBsYXN0Q2hpbGQgPSB0aGlzLmVsZW1lbnQobmFtZS5hcHBseSgpKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QobmFtZSkpIHtcbiAgICAgICAgZm9yIChrZXkgaW4gbmFtZSkge1xuICAgICAgICAgIGlmICghaGFzUHJvcC5jYWxsKG5hbWUsIGtleSkpIGNvbnRpbnVlO1xuICAgICAgICAgIHZhbCA9IG5hbWVba2V5XTtcbiAgICAgICAgICBpZiAoaXNGdW5jdGlvbih2YWwpKSB7XG4gICAgICAgICAgICB2YWwgPSB2YWwuYXBwbHkoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuaWdub3JlRGVjb3JhdG9ycyAmJiB0aGlzLnN0cmluZ2lmeS5jb252ZXJ0QXR0S2V5ICYmIGtleS5pbmRleE9mKHRoaXMuc3RyaW5naWZ5LmNvbnZlcnRBdHRLZXkpID09PSAwKSB7XG4gICAgICAgICAgICBsYXN0Q2hpbGQgPSB0aGlzLmF0dHJpYnV0ZShrZXkuc3Vic3RyKHRoaXMuc3RyaW5naWZ5LmNvbnZlcnRBdHRLZXkubGVuZ3RoKSwgdmFsKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLm9wdGlvbnMuc2VwYXJhdGVBcnJheUl0ZW1zICYmIEFycmF5LmlzQXJyYXkodmFsKSAmJiBpc0VtcHR5KHZhbCkpIHtcbiAgICAgICAgICAgIGxhc3RDaGlsZCA9IHRoaXMuZHVtbXkoKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHZhbCkgJiYgaXNFbXB0eSh2YWwpKSB7XG4gICAgICAgICAgICBsYXN0Q2hpbGQgPSB0aGlzLmVsZW1lbnQoa2V5KTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLm9wdGlvbnMua2VlcE51bGxOb2RlcyAmJiAodmFsID09IG51bGwpKSB7XG4gICAgICAgICAgICBsYXN0Q2hpbGQgPSB0aGlzLmR1bW15KCk7XG4gICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5vcHRpb25zLnNlcGFyYXRlQXJyYXlJdGVtcyAmJiBBcnJheS5pc0FycmF5KHZhbCkpIHtcbiAgICAgICAgICAgIGZvciAoayA9IDAsIGxlbjEgPSB2YWwubGVuZ3RoOyBrIDwgbGVuMTsgaysrKSB7XG4gICAgICAgICAgICAgIGl0ZW0gPSB2YWxba107XG4gICAgICAgICAgICAgIGNoaWxkTm9kZSA9IHt9O1xuICAgICAgICAgICAgICBjaGlsZE5vZGVba2V5XSA9IGl0ZW07XG4gICAgICAgICAgICAgIGxhc3RDaGlsZCA9IHRoaXMuZWxlbWVudChjaGlsZE5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QodmFsKSkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuaWdub3JlRGVjb3JhdG9ycyAmJiB0aGlzLnN0cmluZ2lmeS5jb252ZXJ0VGV4dEtleSAmJiBrZXkuaW5kZXhPZih0aGlzLnN0cmluZ2lmeS5jb252ZXJ0VGV4dEtleSkgPT09IDApIHtcbiAgICAgICAgICAgICAgbGFzdENoaWxkID0gdGhpcy5lbGVtZW50KHZhbCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBsYXN0Q2hpbGQgPSB0aGlzLmVsZW1lbnQoa2V5KTtcbiAgICAgICAgICAgICAgbGFzdENoaWxkLmVsZW1lbnQodmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGFzdENoaWxkID0gdGhpcy5lbGVtZW50KGtleSwgdmFsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMub3B0aW9ucy5rZWVwTnVsbE5vZGVzICYmIHRleHQgPT09IG51bGwpIHtcbiAgICAgICAgbGFzdENoaWxkID0gdGhpcy5kdW1teSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuaWdub3JlRGVjb3JhdG9ycyAmJiB0aGlzLnN0cmluZ2lmeS5jb252ZXJ0VGV4dEtleSAmJiBuYW1lLmluZGV4T2YodGhpcy5zdHJpbmdpZnkuY29udmVydFRleHRLZXkpID09PSAwKSB7XG4gICAgICAgICAgbGFzdENoaWxkID0gdGhpcy50ZXh0KHRleHQpO1xuICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLm9wdGlvbnMuaWdub3JlRGVjb3JhdG9ycyAmJiB0aGlzLnN0cmluZ2lmeS5jb252ZXJ0Q0RhdGFLZXkgJiYgbmFtZS5pbmRleE9mKHRoaXMuc3RyaW5naWZ5LmNvbnZlcnRDRGF0YUtleSkgPT09IDApIHtcbiAgICAgICAgICBsYXN0Q2hpbGQgPSB0aGlzLmNkYXRhKHRleHQpO1xuICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLm9wdGlvbnMuaWdub3JlRGVjb3JhdG9ycyAmJiB0aGlzLnN0cmluZ2lmeS5jb252ZXJ0Q29tbWVudEtleSAmJiBuYW1lLmluZGV4T2YodGhpcy5zdHJpbmdpZnkuY29udmVydENvbW1lbnRLZXkpID09PSAwKSB7XG4gICAgICAgICAgbGFzdENoaWxkID0gdGhpcy5jb21tZW50KHRleHQpO1xuICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLm9wdGlvbnMuaWdub3JlRGVjb3JhdG9ycyAmJiB0aGlzLnN0cmluZ2lmeS5jb252ZXJ0UmF3S2V5ICYmIG5hbWUuaW5kZXhPZih0aGlzLnN0cmluZ2lmeS5jb252ZXJ0UmF3S2V5KSA9PT0gMCkge1xuICAgICAgICAgIGxhc3RDaGlsZCA9IHRoaXMucmF3KHRleHQpO1xuICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLm9wdGlvbnMuaWdub3JlRGVjb3JhdG9ycyAmJiB0aGlzLnN0cmluZ2lmeS5jb252ZXJ0UElLZXkgJiYgbmFtZS5pbmRleE9mKHRoaXMuc3RyaW5naWZ5LmNvbnZlcnRQSUtleSkgPT09IDApIHtcbiAgICAgICAgICBsYXN0Q2hpbGQgPSB0aGlzLmluc3RydWN0aW9uKG5hbWUuc3Vic3RyKHRoaXMuc3RyaW5naWZ5LmNvbnZlcnRQSUtleS5sZW5ndGgpLCB0ZXh0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsYXN0Q2hpbGQgPSB0aGlzLm5vZGUobmFtZSwgYXR0cmlidXRlcywgdGV4dCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChsYXN0Q2hpbGQgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgY3JlYXRlIGFueSBlbGVtZW50cyB3aXRoOiBcIiArIG5hbWUgKyBcIi4gXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBsYXN0Q2hpbGQ7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmluc2VydEJlZm9yZSA9IGZ1bmN0aW9uKG5hbWUsIGF0dHJpYnV0ZXMsIHRleHQpIHtcbiAgICAgIHZhciBjaGlsZCwgaSwgbmV3Q2hpbGQsIHJlZkNoaWxkLCByZW1vdmVkO1xuICAgICAgaWYgKG5hbWUgIT0gbnVsbCA/IG5hbWUudHlwZSA6IHZvaWQgMCkge1xuICAgICAgICBuZXdDaGlsZCA9IG5hbWU7XG4gICAgICAgIHJlZkNoaWxkID0gYXR0cmlidXRlcztcbiAgICAgICAgbmV3Q2hpbGQuc2V0UGFyZW50KHRoaXMpO1xuICAgICAgICBpZiAocmVmQ2hpbGQpIHtcbiAgICAgICAgICBpID0gY2hpbGRyZW4uaW5kZXhPZihyZWZDaGlsZCk7XG4gICAgICAgICAgcmVtb3ZlZCA9IGNoaWxkcmVuLnNwbGljZShpKTtcbiAgICAgICAgICBjaGlsZHJlbi5wdXNoKG5ld0NoaWxkKTtcbiAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShjaGlsZHJlbiwgcmVtb3ZlZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2hpbGRyZW4ucHVzaChuZXdDaGlsZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ld0NoaWxkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuaXNSb290KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGluc2VydCBlbGVtZW50cyBhdCByb290IGxldmVsLiBcIiArIHRoaXMuZGVidWdJbmZvKG5hbWUpKTtcbiAgICAgICAgfVxuICAgICAgICBpID0gdGhpcy5wYXJlbnQuY2hpbGRyZW4uaW5kZXhPZih0aGlzKTtcbiAgICAgICAgcmVtb3ZlZCA9IHRoaXMucGFyZW50LmNoaWxkcmVuLnNwbGljZShpKTtcbiAgICAgICAgY2hpbGQgPSB0aGlzLnBhcmVudC5lbGVtZW50KG5hbWUsIGF0dHJpYnV0ZXMsIHRleHQpO1xuICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseSh0aGlzLnBhcmVudC5jaGlsZHJlbiwgcmVtb3ZlZCk7XG4gICAgICAgIHJldHVybiBjaGlsZDtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuaW5zZXJ0QWZ0ZXIgPSBmdW5jdGlvbihuYW1lLCBhdHRyaWJ1dGVzLCB0ZXh0KSB7XG4gICAgICB2YXIgY2hpbGQsIGksIHJlbW92ZWQ7XG4gICAgICBpZiAodGhpcy5pc1Jvb3QpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGluc2VydCBlbGVtZW50cyBhdCByb290IGxldmVsLiBcIiArIHRoaXMuZGVidWdJbmZvKG5hbWUpKTtcbiAgICAgIH1cbiAgICAgIGkgPSB0aGlzLnBhcmVudC5jaGlsZHJlbi5pbmRleE9mKHRoaXMpO1xuICAgICAgcmVtb3ZlZCA9IHRoaXMucGFyZW50LmNoaWxkcmVuLnNwbGljZShpICsgMSk7XG4gICAgICBjaGlsZCA9IHRoaXMucGFyZW50LmVsZW1lbnQobmFtZSwgYXR0cmlidXRlcywgdGV4dCk7XG4gICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseSh0aGlzLnBhcmVudC5jaGlsZHJlbiwgcmVtb3ZlZCk7XG4gICAgICByZXR1cm4gY2hpbGQ7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGksIHJlZjI7XG4gICAgICBpZiAodGhpcy5pc1Jvb3QpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IHJlbW92ZSB0aGUgcm9vdCBlbGVtZW50LiBcIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgICAgfVxuICAgICAgaSA9IHRoaXMucGFyZW50LmNoaWxkcmVuLmluZGV4T2YodGhpcyk7XG4gICAgICBbXS5zcGxpY2UuYXBwbHkodGhpcy5wYXJlbnQuY2hpbGRyZW4sIFtpLCBpIC0gaSArIDFdLmNvbmNhdChyZWYyID0gW10pKSwgcmVmMjtcbiAgICAgIHJldHVybiB0aGlzLnBhcmVudDtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUubm9kZSA9IGZ1bmN0aW9uKG5hbWUsIGF0dHJpYnV0ZXMsIHRleHQpIHtcbiAgICAgIHZhciBjaGlsZCwgcmVmMjtcbiAgICAgIGlmIChuYW1lICE9IG51bGwpIHtcbiAgICAgICAgbmFtZSA9IGdldFZhbHVlKG5hbWUpO1xuICAgICAgfVxuICAgICAgYXR0cmlidXRlcyB8fCAoYXR0cmlidXRlcyA9IHt9KTtcbiAgICAgIGF0dHJpYnV0ZXMgPSBnZXRWYWx1ZShhdHRyaWJ1dGVzKTtcbiAgICAgIGlmICghaXNPYmplY3QoYXR0cmlidXRlcykpIHtcbiAgICAgICAgcmVmMiA9IFthdHRyaWJ1dGVzLCB0ZXh0XSwgdGV4dCA9IHJlZjJbMF0sIGF0dHJpYnV0ZXMgPSByZWYyWzFdO1xuICAgICAgfVxuICAgICAgY2hpbGQgPSBuZXcgWE1MRWxlbWVudCh0aGlzLCBuYW1lLCBhdHRyaWJ1dGVzKTtcbiAgICAgIGlmICh0ZXh0ICE9IG51bGwpIHtcbiAgICAgICAgY2hpbGQudGV4dCh0ZXh0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2hpbGRyZW4ucHVzaChjaGlsZCk7XG4gICAgICByZXR1cm4gY2hpbGQ7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLnRleHQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgdmFyIGNoaWxkO1xuICAgICAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICB0aGlzLmVsZW1lbnQodmFsdWUpO1xuICAgICAgfVxuICAgICAgY2hpbGQgPSBuZXcgWE1MVGV4dCh0aGlzLCB2YWx1ZSk7XG4gICAgICB0aGlzLmNoaWxkcmVuLnB1c2goY2hpbGQpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmNkYXRhID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHZhciBjaGlsZDtcbiAgICAgIGNoaWxkID0gbmV3IFhNTENEYXRhKHRoaXMsIHZhbHVlKTtcbiAgICAgIHRoaXMuY2hpbGRyZW4ucHVzaChjaGlsZCk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuY29tbWVudCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICB2YXIgY2hpbGQ7XG4gICAgICBjaGlsZCA9IG5ldyBYTUxDb21tZW50KHRoaXMsIHZhbHVlKTtcbiAgICAgIHRoaXMuY2hpbGRyZW4ucHVzaChjaGlsZCk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuY29tbWVudEJlZm9yZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICB2YXIgY2hpbGQsIGksIHJlbW92ZWQ7XG4gICAgICBpID0gdGhpcy5wYXJlbnQuY2hpbGRyZW4uaW5kZXhPZih0aGlzKTtcbiAgICAgIHJlbW92ZWQgPSB0aGlzLnBhcmVudC5jaGlsZHJlbi5zcGxpY2UoaSk7XG4gICAgICBjaGlsZCA9IHRoaXMucGFyZW50LmNvbW1lbnQodmFsdWUpO1xuICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkodGhpcy5wYXJlbnQuY2hpbGRyZW4sIHJlbW92ZWQpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmNvbW1lbnRBZnRlciA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICB2YXIgY2hpbGQsIGksIHJlbW92ZWQ7XG4gICAgICBpID0gdGhpcy5wYXJlbnQuY2hpbGRyZW4uaW5kZXhPZih0aGlzKTtcbiAgICAgIHJlbW92ZWQgPSB0aGlzLnBhcmVudC5jaGlsZHJlbi5zcGxpY2UoaSArIDEpO1xuICAgICAgY2hpbGQgPSB0aGlzLnBhcmVudC5jb21tZW50KHZhbHVlKTtcbiAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHRoaXMucGFyZW50LmNoaWxkcmVuLCByZW1vdmVkKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5yYXcgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgdmFyIGNoaWxkO1xuICAgICAgY2hpbGQgPSBuZXcgWE1MUmF3KHRoaXMsIHZhbHVlKTtcbiAgICAgIHRoaXMuY2hpbGRyZW4ucHVzaChjaGlsZCk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuZHVtbXkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjaGlsZDtcbiAgICAgIGNoaWxkID0gbmV3IFhNTER1bW15KHRoaXMpO1xuICAgICAgcmV0dXJuIGNoaWxkO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5pbnN0cnVjdGlvbiA9IGZ1bmN0aW9uKHRhcmdldCwgdmFsdWUpIHtcbiAgICAgIHZhciBpbnNUYXJnZXQsIGluc1ZhbHVlLCBpbnN0cnVjdGlvbiwgaiwgbGVuO1xuICAgICAgaWYgKHRhcmdldCAhPSBudWxsKSB7XG4gICAgICAgIHRhcmdldCA9IGdldFZhbHVlKHRhcmdldCk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgICB2YWx1ZSA9IGdldFZhbHVlKHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHRhcmdldCkpIHtcbiAgICAgICAgZm9yIChqID0gMCwgbGVuID0gdGFyZ2V0Lmxlbmd0aDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgaW5zVGFyZ2V0ID0gdGFyZ2V0W2pdO1xuICAgICAgICAgIHRoaXMuaW5zdHJ1Y3Rpb24oaW5zVGFyZ2V0KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpc09iamVjdCh0YXJnZXQpKSB7XG4gICAgICAgIGZvciAoaW5zVGFyZ2V0IGluIHRhcmdldCkge1xuICAgICAgICAgIGlmICghaGFzUHJvcC5jYWxsKHRhcmdldCwgaW5zVGFyZ2V0KSkgY29udGludWU7XG4gICAgICAgICAgaW5zVmFsdWUgPSB0YXJnZXRbaW5zVGFyZ2V0XTtcbiAgICAgICAgICB0aGlzLmluc3RydWN0aW9uKGluc1RhcmdldCwgaW5zVmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmFwcGx5KCk7XG4gICAgICAgIH1cbiAgICAgICAgaW5zdHJ1Y3Rpb24gPSBuZXcgWE1MUHJvY2Vzc2luZ0luc3RydWN0aW9uKHRoaXMsIHRhcmdldCwgdmFsdWUpO1xuICAgICAgICB0aGlzLmNoaWxkcmVuLnB1c2goaW5zdHJ1Y3Rpb24pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmluc3RydWN0aW9uQmVmb3JlID0gZnVuY3Rpb24odGFyZ2V0LCB2YWx1ZSkge1xuICAgICAgdmFyIGNoaWxkLCBpLCByZW1vdmVkO1xuICAgICAgaSA9IHRoaXMucGFyZW50LmNoaWxkcmVuLmluZGV4T2YodGhpcyk7XG4gICAgICByZW1vdmVkID0gdGhpcy5wYXJlbnQuY2hpbGRyZW4uc3BsaWNlKGkpO1xuICAgICAgY2hpbGQgPSB0aGlzLnBhcmVudC5pbnN0cnVjdGlvbih0YXJnZXQsIHZhbHVlKTtcbiAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHRoaXMucGFyZW50LmNoaWxkcmVuLCByZW1vdmVkKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5pbnN0cnVjdGlvbkFmdGVyID0gZnVuY3Rpb24odGFyZ2V0LCB2YWx1ZSkge1xuICAgICAgdmFyIGNoaWxkLCBpLCByZW1vdmVkO1xuICAgICAgaSA9IHRoaXMucGFyZW50LmNoaWxkcmVuLmluZGV4T2YodGhpcyk7XG4gICAgICByZW1vdmVkID0gdGhpcy5wYXJlbnQuY2hpbGRyZW4uc3BsaWNlKGkgKyAxKTtcbiAgICAgIGNoaWxkID0gdGhpcy5wYXJlbnQuaW5zdHJ1Y3Rpb24odGFyZ2V0LCB2YWx1ZSk7XG4gICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseSh0aGlzLnBhcmVudC5jaGlsZHJlbiwgcmVtb3ZlZCk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuZGVjbGFyYXRpb24gPSBmdW5jdGlvbih2ZXJzaW9uLCBlbmNvZGluZywgc3RhbmRhbG9uZSkge1xuICAgICAgdmFyIGRvYywgeG1sZGVjO1xuICAgICAgZG9jID0gdGhpcy5kb2N1bWVudCgpO1xuICAgICAgeG1sZGVjID0gbmV3IFhNTERlY2xhcmF0aW9uKGRvYywgdmVyc2lvbiwgZW5jb2RpbmcsIHN0YW5kYWxvbmUpO1xuICAgICAgaWYgKGRvYy5jaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgZG9jLmNoaWxkcmVuLnVuc2hpZnQoeG1sZGVjKTtcbiAgICAgIH0gZWxzZSBpZiAoZG9jLmNoaWxkcmVuWzBdLnR5cGUgPT09IE5vZGVUeXBlLkRlY2xhcmF0aW9uKSB7XG4gICAgICAgIGRvYy5jaGlsZHJlblswXSA9IHhtbGRlYztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRvYy5jaGlsZHJlbi51bnNoaWZ0KHhtbGRlYyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZG9jLnJvb3QoKSB8fCBkb2M7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmR0ZCA9IGZ1bmN0aW9uKHB1YklELCBzeXNJRCkge1xuICAgICAgdmFyIGNoaWxkLCBkb2MsIGRvY3R5cGUsIGksIGosIGssIGxlbiwgbGVuMSwgcmVmMiwgcmVmMztcbiAgICAgIGRvYyA9IHRoaXMuZG9jdW1lbnQoKTtcbiAgICAgIGRvY3R5cGUgPSBuZXcgWE1MRG9jVHlwZShkb2MsIHB1YklELCBzeXNJRCk7XG4gICAgICByZWYyID0gZG9jLmNoaWxkcmVuO1xuICAgICAgZm9yIChpID0gaiA9IDAsIGxlbiA9IHJlZjIubGVuZ3RoOyBqIDwgbGVuOyBpID0gKytqKSB7XG4gICAgICAgIGNoaWxkID0gcmVmMltpXTtcbiAgICAgICAgaWYgKGNoaWxkLnR5cGUgPT09IE5vZGVUeXBlLkRvY1R5cGUpIHtcbiAgICAgICAgICBkb2MuY2hpbGRyZW5baV0gPSBkb2N0eXBlO1xuICAgICAgICAgIHJldHVybiBkb2N0eXBlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZWYzID0gZG9jLmNoaWxkcmVuO1xuICAgICAgZm9yIChpID0gayA9IDAsIGxlbjEgPSByZWYzLmxlbmd0aDsgayA8IGxlbjE7IGkgPSArK2spIHtcbiAgICAgICAgY2hpbGQgPSByZWYzW2ldO1xuICAgICAgICBpZiAoY2hpbGQuaXNSb290KSB7XG4gICAgICAgICAgZG9jLmNoaWxkcmVuLnNwbGljZShpLCAwLCBkb2N0eXBlKTtcbiAgICAgICAgICByZXR1cm4gZG9jdHlwZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZG9jLmNoaWxkcmVuLnB1c2goZG9jdHlwZSk7XG4gICAgICByZXR1cm4gZG9jdHlwZTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUudXAgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmlzUm9vdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcm9vdCBub2RlIGhhcyBubyBwYXJlbnQuIFVzZSBkb2MoKSBpZiB5b3UgbmVlZCB0byBnZXQgdGhlIGRvY3VtZW50IG9iamVjdC5cIik7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5wYXJlbnQ7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLnJvb3QgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBub2RlO1xuICAgICAgbm9kZSA9IHRoaXM7XG4gICAgICB3aGlsZSAobm9kZSkge1xuICAgICAgICBpZiAobm9kZS50eXBlID09PSBOb2RlVHlwZS5Eb2N1bWVudCkge1xuICAgICAgICAgIHJldHVybiBub2RlLnJvb3RPYmplY3Q7XG4gICAgICAgIH0gZWxzZSBpZiAobm9kZS5pc1Jvb3QpIHtcbiAgICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuZG9jdW1lbnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBub2RlO1xuICAgICAgbm9kZSA9IHRoaXM7XG4gICAgICB3aGlsZSAobm9kZSkge1xuICAgICAgICBpZiAobm9kZS50eXBlID09PSBOb2RlVHlwZS5Eb2N1bWVudCkge1xuICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICByZXR1cm4gdGhpcy5kb2N1bWVudCgpLmVuZChvcHRpb25zKTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUucHJldiA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGk7XG4gICAgICBpID0gdGhpcy5wYXJlbnQuY2hpbGRyZW4uaW5kZXhPZih0aGlzKTtcbiAgICAgIGlmIChpIDwgMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBbHJlYWR5IGF0IHRoZSBmaXJzdCBub2RlLiBcIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmNoaWxkcmVuW2kgLSAxXTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGk7XG4gICAgICBpID0gdGhpcy5wYXJlbnQuY2hpbGRyZW4uaW5kZXhPZih0aGlzKTtcbiAgICAgIGlmIChpID09PSAtMSB8fCBpID09PSB0aGlzLnBhcmVudC5jaGlsZHJlbi5sZW5ndGggLSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkFscmVhZHkgYXQgdGhlIGxhc3Qgbm9kZS4gXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnBhcmVudC5jaGlsZHJlbltpICsgMV07XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmltcG9ydERvY3VtZW50ID0gZnVuY3Rpb24oZG9jKSB7XG4gICAgICB2YXIgY2xvbmVkUm9vdDtcbiAgICAgIGNsb25lZFJvb3QgPSBkb2Mucm9vdCgpLmNsb25lKCk7XG4gICAgICBjbG9uZWRSb290LnBhcmVudCA9IHRoaXM7XG4gICAgICBjbG9uZWRSb290LmlzUm9vdCA9IGZhbHNlO1xuICAgICAgdGhpcy5jaGlsZHJlbi5wdXNoKGNsb25lZFJvb3QpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmRlYnVnSW5mbyA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIHZhciByZWYyLCByZWYzO1xuICAgICAgbmFtZSA9IG5hbWUgfHwgdGhpcy5uYW1lO1xuICAgICAgaWYgKChuYW1lID09IG51bGwpICYmICEoKHJlZjIgPSB0aGlzLnBhcmVudCkgIT0gbnVsbCA/IHJlZjIubmFtZSA6IHZvaWQgMCkpIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICB9IGVsc2UgaWYgKG5hbWUgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gXCJwYXJlbnQ6IDxcIiArIHRoaXMucGFyZW50Lm5hbWUgKyBcIj5cIjtcbiAgICAgIH0gZWxzZSBpZiAoISgocmVmMyA9IHRoaXMucGFyZW50KSAhPSBudWxsID8gcmVmMy5uYW1lIDogdm9pZCAwKSkge1xuICAgICAgICByZXR1cm4gXCJub2RlOiA8XCIgKyBuYW1lICsgXCI+XCI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gXCJub2RlOiA8XCIgKyBuYW1lICsgXCI+LCBwYXJlbnQ6IDxcIiArIHRoaXMucGFyZW50Lm5hbWUgKyBcIj5cIjtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuZWxlID0gZnVuY3Rpb24obmFtZSwgYXR0cmlidXRlcywgdGV4dCkge1xuICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudChuYW1lLCBhdHRyaWJ1dGVzLCB0ZXh0KTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUubm9kID0gZnVuY3Rpb24obmFtZSwgYXR0cmlidXRlcywgdGV4dCkge1xuICAgICAgcmV0dXJuIHRoaXMubm9kZShuYW1lLCBhdHRyaWJ1dGVzLCB0ZXh0KTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUudHh0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnRleHQodmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5kYXQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuY2RhdGEodmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5jb20gPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuY29tbWVudCh2YWx1ZSk7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmlucyA9IGZ1bmN0aW9uKHRhcmdldCwgdmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmluc3RydWN0aW9uKHRhcmdldCwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5kb2MgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmRvY3VtZW50KCk7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmRlYyA9IGZ1bmN0aW9uKHZlcnNpb24sIGVuY29kaW5nLCBzdGFuZGFsb25lKSB7XG4gICAgICByZXR1cm4gdGhpcy5kZWNsYXJhdGlvbih2ZXJzaW9uLCBlbmNvZGluZywgc3RhbmRhbG9uZSk7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmUgPSBmdW5jdGlvbihuYW1lLCBhdHRyaWJ1dGVzLCB0ZXh0KSB7XG4gICAgICByZXR1cm4gdGhpcy5lbGVtZW50KG5hbWUsIGF0dHJpYnV0ZXMsIHRleHQpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5uID0gZnVuY3Rpb24obmFtZSwgYXR0cmlidXRlcywgdGV4dCkge1xuICAgICAgcmV0dXJuIHRoaXMubm9kZShuYW1lLCBhdHRyaWJ1dGVzLCB0ZXh0KTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUudCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy50ZXh0KHZhbHVlKTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuZCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5jZGF0YSh2YWx1ZSk7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmMgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuY29tbWVudCh2YWx1ZSk7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLnIgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMucmF3KHZhbHVlKTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuaSA9IGZ1bmN0aW9uKHRhcmdldCwgdmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmluc3RydWN0aW9uKHRhcmdldCwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS51ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy51cCgpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5pbXBvcnRYTUxCdWlsZGVyID0gZnVuY3Rpb24oZG9jKSB7XG4gICAgICByZXR1cm4gdGhpcy5pbXBvcnREb2N1bWVudChkb2MpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5yZXBsYWNlQ2hpbGQgPSBmdW5jdGlvbihuZXdDaGlsZCwgb2xkQ2hpbGQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUucmVtb3ZlQ2hpbGQgPSBmdW5jdGlvbihvbGRDaGlsZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5hcHBlbmRDaGlsZCA9IGZ1bmN0aW9uKG5ld0NoaWxkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmhhc0NoaWxkTm9kZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNoaWxkcmVuLmxlbmd0aCAhPT0gMDtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuY2xvbmVOb2RlID0gZnVuY3Rpb24oZGVlcCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5ub3JtYWxpemUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuaXNTdXBwb3J0ZWQgPSBmdW5jdGlvbihmZWF0dXJlLCB2ZXJzaW9uKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuaGFzQXR0cmlidXRlcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuYXR0cmlicy5sZW5ndGggIT09IDA7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uID0gZnVuY3Rpb24ob3RoZXIpIHtcbiAgICAgIHZhciByZWYsIHJlcztcbiAgICAgIHJlZiA9IHRoaXM7XG4gICAgICBpZiAocmVmID09PSBvdGhlcikge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5kb2N1bWVudCgpICE9PSBvdGhlci5kb2N1bWVudCgpKSB7XG4gICAgICAgIHJlcyA9IERvY3VtZW50UG9zaXRpb24uRGlzY29ubmVjdGVkIHwgRG9jdW1lbnRQb3NpdGlvbi5JbXBsZW1lbnRhdGlvblNwZWNpZmljO1xuICAgICAgICBpZiAoTWF0aC5yYW5kb20oKSA8IDAuNSkge1xuICAgICAgICAgIHJlcyB8PSBEb2N1bWVudFBvc2l0aW9uLlByZWNlZGluZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXMgfD0gRG9jdW1lbnRQb3NpdGlvbi5Gb2xsb3dpbmc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgIH0gZWxzZSBpZiAocmVmLmlzQW5jZXN0b3Iob3RoZXIpKSB7XG4gICAgICAgIHJldHVybiBEb2N1bWVudFBvc2l0aW9uLkNvbnRhaW5zIHwgRG9jdW1lbnRQb3NpdGlvbi5QcmVjZWRpbmc7XG4gICAgICB9IGVsc2UgaWYgKHJlZi5pc0Rlc2NlbmRhbnQob3RoZXIpKSB7XG4gICAgICAgIHJldHVybiBEb2N1bWVudFBvc2l0aW9uLkNvbnRhaW5zIHwgRG9jdW1lbnRQb3NpdGlvbi5Gb2xsb3dpbmc7XG4gICAgICB9IGVsc2UgaWYgKHJlZi5pc1ByZWNlZGluZyhvdGhlcikpIHtcbiAgICAgICAgcmV0dXJuIERvY3VtZW50UG9zaXRpb24uUHJlY2VkaW5nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIERvY3VtZW50UG9zaXRpb24uRm9sbG93aW5nO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5pc1NhbWVOb2RlID0gZnVuY3Rpb24ob3RoZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUubG9va3VwUHJlZml4ID0gZnVuY3Rpb24obmFtZXNwYWNlVVJJKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmlzRGVmYXVsdE5hbWVzcGFjZSA9IGZ1bmN0aW9uKG5hbWVzcGFjZVVSSSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5sb29rdXBOYW1lc3BhY2VVUkkgPSBmdW5jdGlvbihwcmVmaXgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuaXNFcXVhbE5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgICB2YXIgaSwgaiwgcmVmMjtcbiAgICAgIGlmIChub2RlLm5vZGVUeXBlICE9PSB0aGlzLm5vZGVUeXBlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChub2RlLmNoaWxkcmVuLmxlbmd0aCAhPT0gdGhpcy5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZm9yIChpID0gaiA9IDAsIHJlZjIgPSB0aGlzLmNoaWxkcmVuLmxlbmd0aCAtIDE7IDAgPD0gcmVmMiA/IGogPD0gcmVmMiA6IGogPj0gcmVmMjsgaSA9IDAgPD0gcmVmMiA/ICsraiA6IC0taikge1xuICAgICAgICBpZiAoIXRoaXMuY2hpbGRyZW5baV0uaXNFcXVhbE5vZGUobm9kZS5jaGlsZHJlbltpXSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5nZXRGZWF0dXJlID0gZnVuY3Rpb24oZmVhdHVyZSwgdmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5zZXRVc2VyRGF0YSA9IGZ1bmN0aW9uKGtleSwgZGF0YSwgaGFuZGxlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5nZXRVc2VyRGF0YSA9IGZ1bmN0aW9uKGtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBET00gbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC5cIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICBpZiAoIW90aGVyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvdGhlciA9PT0gdGhpcyB8fCB0aGlzLmlzRGVzY2VuZGFudChvdGhlcik7XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLmlzRGVzY2VuZGFudCA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIHZhciBjaGlsZCwgaXNEZXNjZW5kYW50Q2hpbGQsIGosIGxlbiwgcmVmMjtcbiAgICAgIHJlZjIgPSB0aGlzLmNoaWxkcmVuO1xuICAgICAgZm9yIChqID0gMCwgbGVuID0gcmVmMi5sZW5ndGg7IGogPCBsZW47IGorKykge1xuICAgICAgICBjaGlsZCA9IHJlZjJbal07XG4gICAgICAgIGlmIChub2RlID09PSBjaGlsZCkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlzRGVzY2VuZGFudENoaWxkID0gY2hpbGQuaXNEZXNjZW5kYW50KG5vZGUpO1xuICAgICAgICBpZiAoaXNEZXNjZW5kYW50Q2hpbGQpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5pc0FuY2VzdG9yID0gZnVuY3Rpb24obm9kZSkge1xuICAgICAgcmV0dXJuIG5vZGUuaXNEZXNjZW5kYW50KHRoaXMpO1xuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5pc1ByZWNlZGluZyA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIHZhciBub2RlUG9zLCB0aGlzUG9zO1xuICAgICAgbm9kZVBvcyA9IHRoaXMudHJlZVBvc2l0aW9uKG5vZGUpO1xuICAgICAgdGhpc1BvcyA9IHRoaXMudHJlZVBvc2l0aW9uKHRoaXMpO1xuICAgICAgaWYgKG5vZGVQb3MgPT09IC0xIHx8IHRoaXNQb3MgPT09IC0xKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBub2RlUG9zIDwgdGhpc1BvcztcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgWE1MTm9kZS5wcm90b3R5cGUuaXNGb2xsb3dpbmcgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgICB2YXIgbm9kZVBvcywgdGhpc1BvcztcbiAgICAgIG5vZGVQb3MgPSB0aGlzLnRyZWVQb3NpdGlvbihub2RlKTtcbiAgICAgIHRoaXNQb3MgPSB0aGlzLnRyZWVQb3NpdGlvbih0aGlzKTtcbiAgICAgIGlmIChub2RlUG9zID09PSAtMSB8fCB0aGlzUG9zID09PSAtMSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbm9kZVBvcyA+IHRoaXNQb3M7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFhNTE5vZGUucHJvdG90eXBlLnRyZWVQb3NpdGlvbiA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIHZhciBmb3VuZCwgcG9zO1xuICAgICAgcG9zID0gMDtcbiAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICB0aGlzLmZvcmVhY2hUcmVlTm9kZSh0aGlzLmRvY3VtZW50KCksIGZ1bmN0aW9uKGNoaWxkTm9kZSkge1xuICAgICAgICBwb3MrKztcbiAgICAgICAgaWYgKCFmb3VuZCAmJiBjaGlsZE5vZGUgPT09IG5vZGUpIHtcbiAgICAgICAgICByZXR1cm4gZm91bmQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmIChmb3VuZCkge1xuICAgICAgICByZXR1cm4gcG9zO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBYTUxOb2RlLnByb3RvdHlwZS5mb3JlYWNoVHJlZU5vZGUgPSBmdW5jdGlvbihub2RlLCBmdW5jKSB7XG4gICAgICB2YXIgY2hpbGQsIGosIGxlbiwgcmVmMiwgcmVzO1xuICAgICAgbm9kZSB8fCAobm9kZSA9IHRoaXMuZG9jdW1lbnQoKSk7XG4gICAgICByZWYyID0gbm9kZS5jaGlsZHJlbjtcbiAgICAgIGZvciAoaiA9IDAsIGxlbiA9IHJlZjIubGVuZ3RoOyBqIDwgbGVuOyBqKyspIHtcbiAgICAgICAgY2hpbGQgPSByZWYyW2pdO1xuICAgICAgICBpZiAocmVzID0gZnVuYyhjaGlsZCkpIHtcbiAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlcyA9IHRoaXMuZm9yZWFjaFRyZWVOb2RlKGNoaWxkLCBmdW5jKTtcbiAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gWE1MTm9kZTtcblxuICB9KSgpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIFhNTE5vZGVMaXN0O1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MTm9kZUxpc3QgPSAoZnVuY3Rpb24oKSB7XG4gICAgZnVuY3Rpb24gWE1MTm9kZUxpc3Qobm9kZXMpIHtcbiAgICAgIHRoaXMubm9kZXMgPSBub2RlcztcbiAgICB9XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MTm9kZUxpc3QucHJvdG90eXBlLCAnbGVuZ3RoJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubm9kZXMubGVuZ3RoIHx8IDA7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBYTUxOb2RlTGlzdC5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLm5vZGVzID0gbnVsbDtcbiAgICB9O1xuXG4gICAgWE1MTm9kZUxpc3QucHJvdG90eXBlLml0ZW0gPSBmdW5jdGlvbihpbmRleCkge1xuICAgICAgcmV0dXJuIHRoaXMubm9kZXNbaW5kZXhdIHx8IG51bGw7XG4gICAgfTtcblxuICAgIHJldHVybiBYTUxOb2RlTGlzdDtcblxuICB9KSgpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIE5vZGVUeXBlLCBYTUxDaGFyYWN0ZXJEYXRhLCBYTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBOb2RlVHlwZSA9IHJlcXVpcmUoJy4vTm9kZVR5cGUnKTtcblxuICBYTUxDaGFyYWN0ZXJEYXRhID0gcmVxdWlyZSgnLi9YTUxDaGFyYWN0ZXJEYXRhJyk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBYTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChYTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24sIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gWE1MUHJvY2Vzc2luZ0luc3RydWN0aW9uKHBhcmVudCwgdGFyZ2V0LCB2YWx1ZSkge1xuICAgICAgWE1MUHJvY2Vzc2luZ0luc3RydWN0aW9uLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsIHBhcmVudCk7XG4gICAgICBpZiAodGFyZ2V0ID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQuIFwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgICB9XG4gICAgICB0aGlzLnR5cGUgPSBOb2RlVHlwZS5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb247XG4gICAgICB0aGlzLnRhcmdldCA9IHRoaXMuc3RyaW5naWZ5Lmluc1RhcmdldCh0YXJnZXQpO1xuICAgICAgdGhpcy5uYW1lID0gdGhpcy50YXJnZXQ7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuc3RyaW5naWZ5Lmluc1ZhbHVlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBYTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24ucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZSh0aGlzKTtcbiAgICB9O1xuXG4gICAgWE1MUHJvY2Vzc2luZ0luc3RydWN0aW9uLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMud3JpdGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0aGlzLCB0aGlzLm9wdGlvbnMud3JpdGVyLmZpbHRlck9wdGlvbnMob3B0aW9ucykpO1xuICAgIH07XG5cbiAgICBYTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24ucHJvdG90eXBlLmlzRXF1YWxOb2RlID0gZnVuY3Rpb24obm9kZSkge1xuICAgICAgaWYgKCFYTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24uX19zdXBlcl9fLmlzRXF1YWxOb2RlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykuaXNFcXVhbE5vZGUobm9kZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKG5vZGUudGFyZ2V0ICE9PSB0aGlzLnRhcmdldCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTFByb2Nlc3NpbmdJbnN0cnVjdGlvbjtcblxuICB9KShYTUxDaGFyYWN0ZXJEYXRhKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBOb2RlVHlwZSwgWE1MTm9kZSwgWE1MUmF3LFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgTm9kZVR5cGUgPSByZXF1aXJlKCcuL05vZGVUeXBlJyk7XG5cbiAgWE1MTm9kZSA9IHJlcXVpcmUoJy4vWE1MTm9kZScpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MUmF3ID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoWE1MUmF3LCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIFhNTFJhdyhwYXJlbnQsIHRleHQpIHtcbiAgICAgIFhNTFJhdy5fX3N1cGVyX18uY29uc3RydWN0b3IuY2FsbCh0aGlzLCBwYXJlbnQpO1xuICAgICAgaWYgKHRleHQgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIHJhdyB0ZXh0LiBcIiArIHRoaXMuZGVidWdJbmZvKCkpO1xuICAgICAgfVxuICAgICAgdGhpcy50eXBlID0gTm9kZVR5cGUuUmF3O1xuICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuc3RyaW5naWZ5LnJhdyh0ZXh0KTtcbiAgICB9XG5cbiAgICBYTUxSYXcucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZSh0aGlzKTtcbiAgICB9O1xuXG4gICAgWE1MUmF3LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMud3JpdGVyLnJhdyh0aGlzLCB0aGlzLm9wdGlvbnMud3JpdGVyLmZpbHRlck9wdGlvbnMob3B0aW9ucykpO1xuICAgIH07XG5cbiAgICByZXR1cm4gWE1MUmF3O1xuXG4gIH0pKFhNTE5vZGUpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIE5vZGVUeXBlLCBXcml0ZXJTdGF0ZSwgWE1MU3RyZWFtV3JpdGVyLCBYTUxXcml0ZXJCYXNlLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgTm9kZVR5cGUgPSByZXF1aXJlKCcuL05vZGVUeXBlJyk7XG5cbiAgWE1MV3JpdGVyQmFzZSA9IHJlcXVpcmUoJy4vWE1MV3JpdGVyQmFzZScpO1xuXG4gIFdyaXRlclN0YXRlID0gcmVxdWlyZSgnLi9Xcml0ZXJTdGF0ZScpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MU3RyZWFtV3JpdGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoWE1MU3RyZWFtV3JpdGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIFhNTFN0cmVhbVdyaXRlcihzdHJlYW0sIG9wdGlvbnMpIHtcbiAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgWE1MU3RyZWFtV3JpdGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIFhNTFN0cmVhbVdyaXRlci5wcm90b3R5cGUuZW5kbGluZSA9IGZ1bmN0aW9uKG5vZGUsIG9wdGlvbnMsIGxldmVsKSB7XG4gICAgICBpZiAobm9kZS5pc0xhc3RSb290Tm9kZSAmJiBvcHRpb25zLnN0YXRlID09PSBXcml0ZXJTdGF0ZS5DbG9zZVRhZykge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gWE1MU3RyZWFtV3JpdGVyLl9fc3VwZXJfXy5lbmRsaW5lLmNhbGwodGhpcywgbm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBYTUxTdHJlYW1Xcml0ZXIucHJvdG90eXBlLmRvY3VtZW50ID0gZnVuY3Rpb24oZG9jLCBvcHRpb25zKSB7XG4gICAgICB2YXIgY2hpbGQsIGksIGosIGssIGxlbiwgbGVuMSwgcmVmLCByZWYxLCByZXN1bHRzO1xuICAgICAgcmVmID0gZG9jLmNoaWxkcmVuO1xuICAgICAgZm9yIChpID0gaiA9IDAsIGxlbiA9IHJlZi5sZW5ndGg7IGogPCBsZW47IGkgPSArK2opIHtcbiAgICAgICAgY2hpbGQgPSByZWZbaV07XG4gICAgICAgIGNoaWxkLmlzTGFzdFJvb3ROb2RlID0gaSA9PT0gZG9jLmNoaWxkcmVuLmxlbmd0aCAtIDE7XG4gICAgICB9XG4gICAgICBvcHRpb25zID0gdGhpcy5maWx0ZXJPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgcmVmMSA9IGRvYy5jaGlsZHJlbjtcbiAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgIGZvciAoayA9IDAsIGxlbjEgPSByZWYxLmxlbmd0aDsgayA8IGxlbjE7IGsrKykge1xuICAgICAgICBjaGlsZCA9IHJlZjFba107XG4gICAgICAgIHJlc3VsdHMucHVzaCh0aGlzLndyaXRlQ2hpbGROb2RlKGNoaWxkLCBvcHRpb25zLCAwKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9O1xuXG4gICAgWE1MU3RyZWFtV3JpdGVyLnByb3RvdHlwZS5hdHRyaWJ1dGUgPSBmdW5jdGlvbihhdHQsIG9wdGlvbnMsIGxldmVsKSB7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0ud3JpdGUoWE1MU3RyZWFtV3JpdGVyLl9fc3VwZXJfXy5hdHRyaWJ1dGUuY2FsbCh0aGlzLCBhdHQsIG9wdGlvbnMsIGxldmVsKSk7XG4gICAgfTtcblxuICAgIFhNTFN0cmVhbVdyaXRlci5wcm90b3R5cGUuY2RhdGEgPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLndyaXRlKFhNTFN0cmVhbVdyaXRlci5fX3N1cGVyX18uY2RhdGEuY2FsbCh0aGlzLCBub2RlLCBvcHRpb25zLCBsZXZlbCkpO1xuICAgIH07XG5cbiAgICBYTUxTdHJlYW1Xcml0ZXIucHJvdG90eXBlLmNvbW1lbnQgPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLndyaXRlKFhNTFN0cmVhbVdyaXRlci5fX3N1cGVyX18uY29tbWVudC5jYWxsKHRoaXMsIG5vZGUsIG9wdGlvbnMsIGxldmVsKSk7XG4gICAgfTtcblxuICAgIFhNTFN0cmVhbVdyaXRlci5wcm90b3R5cGUuZGVjbGFyYXRpb24gPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLndyaXRlKFhNTFN0cmVhbVdyaXRlci5fX3N1cGVyX18uZGVjbGFyYXRpb24uY2FsbCh0aGlzLCBub2RlLCBvcHRpb25zLCBsZXZlbCkpO1xuICAgIH07XG5cbiAgICBYTUxTdHJlYW1Xcml0ZXIucHJvdG90eXBlLmRvY1R5cGUgPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge1xuICAgICAgdmFyIGNoaWxkLCBqLCBsZW4sIHJlZjtcbiAgICAgIGxldmVsIHx8IChsZXZlbCA9IDApO1xuICAgICAgdGhpcy5vcGVuTm9kZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuT3BlblRhZztcbiAgICAgIHRoaXMuc3RyZWFtLndyaXRlKHRoaXMuaW5kZW50KG5vZGUsIG9wdGlvbnMsIGxldmVsKSk7XG4gICAgICB0aGlzLnN0cmVhbS53cml0ZSgnPCFET0NUWVBFICcgKyBub2RlLnJvb3QoKS5uYW1lKTtcbiAgICAgIGlmIChub2RlLnB1YklEICYmIG5vZGUuc3lzSUQpIHtcbiAgICAgICAgdGhpcy5zdHJlYW0ud3JpdGUoJyBQVUJMSUMgXCInICsgbm9kZS5wdWJJRCArICdcIiBcIicgKyBub2RlLnN5c0lEICsgJ1wiJyk7XG4gICAgICB9IGVsc2UgaWYgKG5vZGUuc3lzSUQpIHtcbiAgICAgICAgdGhpcy5zdHJlYW0ud3JpdGUoJyBTWVNURU0gXCInICsgbm9kZS5zeXNJRCArICdcIicpO1xuICAgICAgfVxuICAgICAgaWYgKG5vZGUuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLnN0cmVhbS53cml0ZSgnIFsnKTtcbiAgICAgICAgdGhpcy5zdHJlYW0ud3JpdGUodGhpcy5lbmRsaW5lKG5vZGUsIG9wdGlvbnMsIGxldmVsKSk7XG4gICAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5JbnNpZGVUYWc7XG4gICAgICAgIHJlZiA9IG5vZGUuY2hpbGRyZW47XG4gICAgICAgIGZvciAoaiA9IDAsIGxlbiA9IHJlZi5sZW5ndGg7IGogPCBsZW47IGorKykge1xuICAgICAgICAgIGNoaWxkID0gcmVmW2pdO1xuICAgICAgICAgIHRoaXMud3JpdGVDaGlsZE5vZGUoY2hpbGQsIG9wdGlvbnMsIGxldmVsICsgMSk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkNsb3NlVGFnO1xuICAgICAgICB0aGlzLnN0cmVhbS53cml0ZSgnXScpO1xuICAgICAgfVxuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkNsb3NlVGFnO1xuICAgICAgdGhpcy5zdHJlYW0ud3JpdGUob3B0aW9ucy5zcGFjZUJlZm9yZVNsYXNoICsgJz4nKTtcbiAgICAgIHRoaXMuc3RyZWFtLndyaXRlKHRoaXMuZW5kbGluZShub2RlLCBvcHRpb25zLCBsZXZlbCkpO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLk5vbmU7XG4gICAgICByZXR1cm4gdGhpcy5jbG9zZU5vZGUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgIH07XG5cbiAgICBYTUxTdHJlYW1Xcml0ZXIucHJvdG90eXBlLmVsZW1lbnQgPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge1xuICAgICAgdmFyIGF0dCwgY2hpbGQsIGNoaWxkTm9kZUNvdW50LCBmaXJzdENoaWxkTm9kZSwgaiwgbGVuLCBuYW1lLCBwcmV0dHlTdXBwcmVzc2VkLCByZWYsIHJlZjE7XG4gICAgICBsZXZlbCB8fCAobGV2ZWwgPSAwKTtcbiAgICAgIHRoaXMub3Blbk5vZGUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLk9wZW5UYWc7XG4gICAgICB0aGlzLnN0cmVhbS53cml0ZSh0aGlzLmluZGVudChub2RlLCBvcHRpb25zLCBsZXZlbCkgKyAnPCcgKyBub2RlLm5hbWUpO1xuICAgICAgcmVmID0gbm9kZS5hdHRyaWJzO1xuICAgICAgZm9yIChuYW1lIGluIHJlZikge1xuICAgICAgICBpZiAoIWhhc1Byb3AuY2FsbChyZWYsIG5hbWUpKSBjb250aW51ZTtcbiAgICAgICAgYXR0ID0gcmVmW25hbWVdO1xuICAgICAgICB0aGlzLmF0dHJpYnV0ZShhdHQsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIH1cbiAgICAgIGNoaWxkTm9kZUNvdW50ID0gbm9kZS5jaGlsZHJlbi5sZW5ndGg7XG4gICAgICBmaXJzdENoaWxkTm9kZSA9IGNoaWxkTm9kZUNvdW50ID09PSAwID8gbnVsbCA6IG5vZGUuY2hpbGRyZW5bMF07XG4gICAgICBpZiAoY2hpbGROb2RlQ291bnQgPT09IDAgfHwgbm9kZS5jaGlsZHJlbi5ldmVyeShmdW5jdGlvbihlKSB7XG4gICAgICAgIHJldHVybiAoZS50eXBlID09PSBOb2RlVHlwZS5UZXh0IHx8IGUudHlwZSA9PT0gTm9kZVR5cGUuUmF3KSAmJiBlLnZhbHVlID09PSAnJztcbiAgICAgIH0pKSB7XG4gICAgICAgIGlmIChvcHRpb25zLmFsbG93RW1wdHkpIHtcbiAgICAgICAgICB0aGlzLnN0cmVhbS53cml0ZSgnPicpO1xuICAgICAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5DbG9zZVRhZztcbiAgICAgICAgICB0aGlzLnN0cmVhbS53cml0ZSgnPC8nICsgbm9kZS5uYW1lICsgJz4nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuQ2xvc2VUYWc7XG4gICAgICAgICAgdGhpcy5zdHJlYW0ud3JpdGUob3B0aW9ucy5zcGFjZUJlZm9yZVNsYXNoICsgJy8+Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAob3B0aW9ucy5wcmV0dHkgJiYgY2hpbGROb2RlQ291bnQgPT09IDEgJiYgKGZpcnN0Q2hpbGROb2RlLnR5cGUgPT09IE5vZGVUeXBlLlRleHQgfHwgZmlyc3RDaGlsZE5vZGUudHlwZSA9PT0gTm9kZVR5cGUuUmF3KSAmJiAoZmlyc3RDaGlsZE5vZGUudmFsdWUgIT0gbnVsbCkpIHtcbiAgICAgICAgdGhpcy5zdHJlYW0ud3JpdGUoJz4nKTtcbiAgICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkluc2lkZVRhZztcbiAgICAgICAgb3B0aW9ucy5zdXBwcmVzc1ByZXR0eUNvdW50Kys7XG4gICAgICAgIHByZXR0eVN1cHByZXNzZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLndyaXRlQ2hpbGROb2RlKGZpcnN0Q2hpbGROb2RlLCBvcHRpb25zLCBsZXZlbCArIDEpO1xuICAgICAgICBvcHRpb25zLnN1cHByZXNzUHJldHR5Q291bnQtLTtcbiAgICAgICAgcHJldHR5U3VwcHJlc3NlZCA9IGZhbHNlO1xuICAgICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuQ2xvc2VUYWc7XG4gICAgICAgIHRoaXMuc3RyZWFtLndyaXRlKCc8LycgKyBub2RlLm5hbWUgKyAnPicpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zdHJlYW0ud3JpdGUoJz4nICsgdGhpcy5lbmRsaW5lKG5vZGUsIG9wdGlvbnMsIGxldmVsKSk7XG4gICAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5JbnNpZGVUYWc7XG4gICAgICAgIHJlZjEgPSBub2RlLmNoaWxkcmVuO1xuICAgICAgICBmb3IgKGogPSAwLCBsZW4gPSByZWYxLmxlbmd0aDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgY2hpbGQgPSByZWYxW2pdO1xuICAgICAgICAgIHRoaXMud3JpdGVDaGlsZE5vZGUoY2hpbGQsIG9wdGlvbnMsIGxldmVsICsgMSk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkNsb3NlVGFnO1xuICAgICAgICB0aGlzLnN0cmVhbS53cml0ZSh0aGlzLmluZGVudChub2RlLCBvcHRpb25zLCBsZXZlbCkgKyAnPC8nICsgbm9kZS5uYW1lICsgJz4nKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RyZWFtLndyaXRlKHRoaXMuZW5kbGluZShub2RlLCBvcHRpb25zLCBsZXZlbCkpO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLk5vbmU7XG4gICAgICByZXR1cm4gdGhpcy5jbG9zZU5vZGUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgIH07XG5cbiAgICBYTUxTdHJlYW1Xcml0ZXIucHJvdG90eXBlLnByb2Nlc3NpbmdJbnN0cnVjdGlvbiA9IGZ1bmN0aW9uKG5vZGUsIG9wdGlvbnMsIGxldmVsKSB7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0ud3JpdGUoWE1MU3RyZWFtV3JpdGVyLl9fc3VwZXJfXy5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24uY2FsbCh0aGlzLCBub2RlLCBvcHRpb25zLCBsZXZlbCkpO1xuICAgIH07XG5cbiAgICBYTUxTdHJlYW1Xcml0ZXIucHJvdG90eXBlLnJhdyA9IGZ1bmN0aW9uKG5vZGUsIG9wdGlvbnMsIGxldmVsKSB7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0ud3JpdGUoWE1MU3RyZWFtV3JpdGVyLl9fc3VwZXJfXy5yYXcuY2FsbCh0aGlzLCBub2RlLCBvcHRpb25zLCBsZXZlbCkpO1xuICAgIH07XG5cbiAgICBYTUxTdHJlYW1Xcml0ZXIucHJvdG90eXBlLnRleHQgPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLndyaXRlKFhNTFN0cmVhbVdyaXRlci5fX3N1cGVyX18udGV4dC5jYWxsKHRoaXMsIG5vZGUsIG9wdGlvbnMsIGxldmVsKSk7XG4gICAgfTtcblxuICAgIFhNTFN0cmVhbVdyaXRlci5wcm90b3R5cGUuZHRkQXR0TGlzdCA9IGZ1bmN0aW9uKG5vZGUsIG9wdGlvbnMsIGxldmVsKSB7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0ud3JpdGUoWE1MU3RyZWFtV3JpdGVyLl9fc3VwZXJfXy5kdGRBdHRMaXN0LmNhbGwodGhpcywgbm9kZSwgb3B0aW9ucywgbGV2ZWwpKTtcbiAgICB9O1xuXG4gICAgWE1MU3RyZWFtV3JpdGVyLnByb3RvdHlwZS5kdGRFbGVtZW50ID0gZnVuY3Rpb24obm9kZSwgb3B0aW9ucywgbGV2ZWwpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS53cml0ZShYTUxTdHJlYW1Xcml0ZXIuX19zdXBlcl9fLmR0ZEVsZW1lbnQuY2FsbCh0aGlzLCBub2RlLCBvcHRpb25zLCBsZXZlbCkpO1xuICAgIH07XG5cbiAgICBYTUxTdHJlYW1Xcml0ZXIucHJvdG90eXBlLmR0ZEVudGl0eSA9IGZ1bmN0aW9uKG5vZGUsIG9wdGlvbnMsIGxldmVsKSB7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0ud3JpdGUoWE1MU3RyZWFtV3JpdGVyLl9fc3VwZXJfXy5kdGRFbnRpdHkuY2FsbCh0aGlzLCBub2RlLCBvcHRpb25zLCBsZXZlbCkpO1xuICAgIH07XG5cbiAgICBYTUxTdHJlYW1Xcml0ZXIucHJvdG90eXBlLmR0ZE5vdGF0aW9uID0gZnVuY3Rpb24obm9kZSwgb3B0aW9ucywgbGV2ZWwpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS53cml0ZShYTUxTdHJlYW1Xcml0ZXIuX19zdXBlcl9fLmR0ZE5vdGF0aW9uLmNhbGwodGhpcywgbm9kZSwgb3B0aW9ucywgbGV2ZWwpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTFN0cmVhbVdyaXRlcjtcblxuICB9KShYTUxXcml0ZXJCYXNlKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBYTUxTdHJpbmdXcml0ZXIsIFhNTFdyaXRlckJhc2UsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBYTUxXcml0ZXJCYXNlID0gcmVxdWlyZSgnLi9YTUxXcml0ZXJCYXNlJyk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBYTUxTdHJpbmdXcml0ZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChYTUxTdHJpbmdXcml0ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gWE1MU3RyaW5nV3JpdGVyKG9wdGlvbnMpIHtcbiAgICAgIFhNTFN0cmluZ1dyaXRlci5fX3N1cGVyX18uY29uc3RydWN0b3IuY2FsbCh0aGlzLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBYTUxTdHJpbmdXcml0ZXIucHJvdG90eXBlLmRvY3VtZW50ID0gZnVuY3Rpb24oZG9jLCBvcHRpb25zKSB7XG4gICAgICB2YXIgY2hpbGQsIGksIGxlbiwgciwgcmVmO1xuICAgICAgb3B0aW9ucyA9IHRoaXMuZmlsdGVyT3B0aW9ucyhvcHRpb25zKTtcbiAgICAgIHIgPSAnJztcbiAgICAgIHJlZiA9IGRvYy5jaGlsZHJlbjtcbiAgICAgIGZvciAoaSA9IDAsIGxlbiA9IHJlZi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBjaGlsZCA9IHJlZltpXTtcbiAgICAgICAgciArPSB0aGlzLndyaXRlQ2hpbGROb2RlKGNoaWxkLCBvcHRpb25zLCAwKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLnByZXR0eSAmJiByLnNsaWNlKC1vcHRpb25zLm5ld2xpbmUubGVuZ3RoKSA9PT0gb3B0aW9ucy5uZXdsaW5lKSB7XG4gICAgICAgIHIgPSByLnNsaWNlKDAsIC1vcHRpb25zLm5ld2xpbmUubGVuZ3RoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByO1xuICAgIH07XG5cbiAgICByZXR1cm4gWE1MU3RyaW5nV3JpdGVyO1xuXG4gIH0pKFhNTFdyaXRlckJhc2UpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIFhNTFN0cmluZ2lmaWVyLFxuICAgIGJpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFhNTFN0cmluZ2lmaWVyID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIFhNTFN0cmluZ2lmaWVyKG9wdGlvbnMpIHtcbiAgICAgIHRoaXMuYXNzZXJ0TGVnYWxOYW1lID0gYmluZCh0aGlzLmFzc2VydExlZ2FsTmFtZSwgdGhpcyk7XG4gICAgICB0aGlzLmFzc2VydExlZ2FsQ2hhciA9IGJpbmQodGhpcy5hc3NlcnRMZWdhbENoYXIsIHRoaXMpO1xuICAgICAgdmFyIGtleSwgcmVmLCB2YWx1ZTtcbiAgICAgIG9wdGlvbnMgfHwgKG9wdGlvbnMgPSB7fSk7XG4gICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgaWYgKCF0aGlzLm9wdGlvbnMudmVyc2lvbikge1xuICAgICAgICB0aGlzLm9wdGlvbnMudmVyc2lvbiA9ICcxLjAnO1xuICAgICAgfVxuICAgICAgcmVmID0gb3B0aW9ucy5zdHJpbmdpZnkgfHwge307XG4gICAgICBmb3IgKGtleSBpbiByZWYpIHtcbiAgICAgICAgaWYgKCFoYXNQcm9wLmNhbGwocmVmLCBrZXkpKSBjb250aW51ZTtcbiAgICAgICAgdmFsdWUgPSByZWZba2V5XTtcbiAgICAgICAgdGhpc1trZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgWE1MU3RyaW5naWZpZXIucHJvdG90eXBlLm5hbWUgPSBmdW5jdGlvbih2YWwpIHtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMubm9WYWxpZGF0aW9uKSB7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5hc3NlcnRMZWdhbE5hbWUoJycgKyB2YWwgfHwgJycpO1xuICAgIH07XG5cbiAgICBYTUxTdHJpbmdpZmllci5wcm90b3R5cGUudGV4dCA9IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5ub1ZhbGlkYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmFzc2VydExlZ2FsQ2hhcih0aGlzLnRleHRFc2NhcGUoJycgKyB2YWwgfHwgJycpKTtcbiAgICB9O1xuXG4gICAgWE1MU3RyaW5naWZpZXIucHJvdG90eXBlLmNkYXRhID0gZnVuY3Rpb24odmFsKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm5vVmFsaWRhdGlvbikge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgfVxuICAgICAgdmFsID0gJycgKyB2YWwgfHwgJyc7XG4gICAgICB2YWwgPSB2YWwucmVwbGFjZSgnXV0+JywgJ11dXV0+PCFbQ0RBVEFbPicpO1xuICAgICAgcmV0dXJuIHRoaXMuYXNzZXJ0TGVnYWxDaGFyKHZhbCk7XG4gICAgfTtcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS5jb21tZW50ID0gZnVuY3Rpb24odmFsKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm5vVmFsaWRhdGlvbikge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgfVxuICAgICAgdmFsID0gJycgKyB2YWwgfHwgJyc7XG4gICAgICBpZiAodmFsLm1hdGNoKC8tLS8pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvbW1lbnQgdGV4dCBjYW5ub3QgY29udGFpbiBkb3VibGUtaHlwZW46IFwiICsgdmFsKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmFzc2VydExlZ2FsQ2hhcih2YWwpO1xuICAgIH07XG5cbiAgICBYTUxTdHJpbmdpZmllci5wcm90b3R5cGUucmF3ID0gZnVuY3Rpb24odmFsKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm5vVmFsaWRhdGlvbikge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuICcnICsgdmFsIHx8ICcnO1xuICAgIH07XG5cbiAgICBYTUxTdHJpbmdpZmllci5wcm90b3R5cGUuYXR0VmFsdWUgPSBmdW5jdGlvbih2YWwpIHtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMubm9WYWxpZGF0aW9uKSB7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5hc3NlcnRMZWdhbENoYXIodGhpcy5hdHRFc2NhcGUodmFsID0gJycgKyB2YWwgfHwgJycpKTtcbiAgICB9O1xuXG4gICAgWE1MU3RyaW5naWZpZXIucHJvdG90eXBlLmluc1RhcmdldCA9IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5ub1ZhbGlkYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmFzc2VydExlZ2FsQ2hhcignJyArIHZhbCB8fCAnJyk7XG4gICAgfTtcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS5pbnNWYWx1ZSA9IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5ub1ZhbGlkYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgIH1cbiAgICAgIHZhbCA9ICcnICsgdmFsIHx8ICcnO1xuICAgICAgaWYgKHZhbC5tYXRjaCgvXFw/Pi8pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB2YWx1ZTogXCIgKyB2YWwpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYXNzZXJ0TGVnYWxDaGFyKHZhbCk7XG4gICAgfTtcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS54bWxWZXJzaW9uID0gZnVuY3Rpb24odmFsKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm5vVmFsaWRhdGlvbikge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgfVxuICAgICAgdmFsID0gJycgKyB2YWwgfHwgJyc7XG4gICAgICBpZiAoIXZhbC5tYXRjaCgvMVxcLlswLTldKy8pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdmVyc2lvbiBudW1iZXI6IFwiICsgdmFsKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWw7XG4gICAgfTtcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS54bWxFbmNvZGluZyA9IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5ub1ZhbGlkYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgIH1cbiAgICAgIHZhbCA9ICcnICsgdmFsIHx8ICcnO1xuICAgICAgaWYgKCF2YWwubWF0Y2goL15bQS1aYS16XSg/OltBLVphLXowLTkuXy1dKSokLykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBlbmNvZGluZzogXCIgKyB2YWwpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYXNzZXJ0TGVnYWxDaGFyKHZhbCk7XG4gICAgfTtcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS54bWxTdGFuZGFsb25lID0gZnVuY3Rpb24odmFsKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm5vVmFsaWRhdGlvbikge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgfVxuICAgICAgaWYgKHZhbCkge1xuICAgICAgICByZXR1cm4gXCJ5ZXNcIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBcIm5vXCI7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS5kdGRQdWJJRCA9IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5ub1ZhbGlkYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmFzc2VydExlZ2FsQ2hhcignJyArIHZhbCB8fCAnJyk7XG4gICAgfTtcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS5kdGRTeXNJRCA9IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5ub1ZhbGlkYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmFzc2VydExlZ2FsQ2hhcignJyArIHZhbCB8fCAnJyk7XG4gICAgfTtcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS5kdGRFbGVtZW50VmFsdWUgPSBmdW5jdGlvbih2YWwpIHtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMubm9WYWxpZGF0aW9uKSB7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5hc3NlcnRMZWdhbENoYXIoJycgKyB2YWwgfHwgJycpO1xuICAgIH07XG5cbiAgICBYTUxTdHJpbmdpZmllci5wcm90b3R5cGUuZHRkQXR0VHlwZSA9IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5ub1ZhbGlkYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmFzc2VydExlZ2FsQ2hhcignJyArIHZhbCB8fCAnJyk7XG4gICAgfTtcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS5kdGRBdHREZWZhdWx0ID0gZnVuY3Rpb24odmFsKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm5vVmFsaWRhdGlvbikge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYXNzZXJ0TGVnYWxDaGFyKCcnICsgdmFsIHx8ICcnKTtcbiAgICB9O1xuXG4gICAgWE1MU3RyaW5naWZpZXIucHJvdG90eXBlLmR0ZEVudGl0eVZhbHVlID0gZnVuY3Rpb24odmFsKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm5vVmFsaWRhdGlvbikge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYXNzZXJ0TGVnYWxDaGFyKCcnICsgdmFsIHx8ICcnKTtcbiAgICB9O1xuXG4gICAgWE1MU3RyaW5naWZpZXIucHJvdG90eXBlLmR0ZE5EYXRhID0gZnVuY3Rpb24odmFsKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm5vVmFsaWRhdGlvbikge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYXNzZXJ0TGVnYWxDaGFyKCcnICsgdmFsIHx8ICcnKTtcbiAgICB9O1xuXG4gICAgWE1MU3RyaW5naWZpZXIucHJvdG90eXBlLmNvbnZlcnRBdHRLZXkgPSAnQCc7XG5cbiAgICBYTUxTdHJpbmdpZmllci5wcm90b3R5cGUuY29udmVydFBJS2V5ID0gJz8nO1xuXG4gICAgWE1MU3RyaW5naWZpZXIucHJvdG90eXBlLmNvbnZlcnRUZXh0S2V5ID0gJyN0ZXh0JztcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS5jb252ZXJ0Q0RhdGFLZXkgPSAnI2NkYXRhJztcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS5jb252ZXJ0Q29tbWVudEtleSA9ICcjY29tbWVudCc7XG5cbiAgICBYTUxTdHJpbmdpZmllci5wcm90b3R5cGUuY29udmVydFJhd0tleSA9ICcjcmF3JztcblxuICAgIFhNTFN0cmluZ2lmaWVyLnByb3RvdHlwZS5hc3NlcnRMZWdhbENoYXIgPSBmdW5jdGlvbihzdHIpIHtcbiAgICAgIHZhciByZWdleCwgcmVzO1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5ub1ZhbGlkYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICAgIH1cbiAgICAgIHJlZ2V4ID0gJyc7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnZlcnNpb24gPT09ICcxLjAnKSB7XG4gICAgICAgIHJlZ2V4ID0gL1tcXDAtXFx4MDhcXHgwQlxcZlxceDBFLVxceDFGXFx1RkZGRVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdLztcbiAgICAgICAgaWYgKHJlcyA9IHN0ci5tYXRjaChyZWdleCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGNoYXJhY3RlciBpbiBzdHJpbmc6IFwiICsgc3RyICsgXCIgYXQgaW5kZXggXCIgKyByZXMuaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9ucy52ZXJzaW9uID09PSAnMS4xJykge1xuICAgICAgICByZWdleCA9IC9bXFwwXFx1RkZGRVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdLztcbiAgICAgICAgaWYgKHJlcyA9IHN0ci5tYXRjaChyZWdleCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGNoYXJhY3RlciBpbiBzdHJpbmc6IFwiICsgc3RyICsgXCIgYXQgaW5kZXggXCIgKyByZXMuaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH07XG5cbiAgICBYTUxTdHJpbmdpZmllci5wcm90b3R5cGUuYXNzZXJ0TGVnYWxOYW1lID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgICB2YXIgcmVnZXg7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm5vVmFsaWRhdGlvbikge1xuICAgICAgICByZXR1cm4gc3RyO1xuICAgICAgfVxuICAgICAgdGhpcy5hc3NlcnRMZWdhbENoYXIoc3RyKTtcbiAgICAgIHJlZ2V4ID0gL14oWzpBLVpfYS16XFx4QzAtXFx4RDZcXHhEOC1cXHhGNlxceEY4LVxcdTAyRkZcXHUwMzcwLVxcdTAzN0RcXHUwMzdGLVxcdTFGRkZcXHUyMDBDXFx1MjAwRFxcdTIwNzAtXFx1MjE4RlxcdTJDMDAtXFx1MkZFRlxcdTMwMDEtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZGRF18W1xcdUQ4MDAtXFx1REI3Rl1bXFx1REMwMC1cXHVERkZGXSkoW1xceDJEXFwuMC06QS1aX2EtelxceEI3XFx4QzAtXFx4RDZcXHhEOC1cXHhGNlxceEY4LVxcdTAzN0RcXHUwMzdGLVxcdTFGRkZcXHUyMDBDXFx1MjAwRFxcdTIwM0ZcXHUyMDQwXFx1MjA3MC1cXHUyMThGXFx1MkMwMC1cXHUyRkVGXFx1MzAwMS1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkZEXXxbXFx1RDgwMC1cXHVEQjdGXVtcXHVEQzAwLVxcdURGRkZdKSokLztcbiAgICAgIGlmICghc3RyLm1hdGNoKHJlZ2V4KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGNoYXJhY3RlciBpbiBuYW1lXCIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9O1xuXG4gICAgWE1MU3RyaW5naWZpZXIucHJvdG90eXBlLnRleHRFc2NhcGUgPSBmdW5jdGlvbihzdHIpIHtcbiAgICAgIHZhciBhbXByZWdleDtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMubm9WYWxpZGF0aW9uKSB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgICB9XG4gICAgICBhbXByZWdleCA9IHRoaXMub3B0aW9ucy5ub0RvdWJsZUVuY29kaW5nID8gLyg/ISZcXFMrOykmL2cgOiAvJi9nO1xuICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKGFtcHJlZ2V4LCAnJmFtcDsnKS5yZXBsYWNlKC88L2csICcmbHQ7JykucmVwbGFjZSgvPi9nLCAnJmd0OycpLnJlcGxhY2UoL1xcci9nLCAnJiN4RDsnKTtcbiAgICB9O1xuXG4gICAgWE1MU3RyaW5naWZpZXIucHJvdG90eXBlLmF0dEVzY2FwZSA9IGZ1bmN0aW9uKHN0cikge1xuICAgICAgdmFyIGFtcHJlZ2V4O1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5ub1ZhbGlkYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICAgIH1cbiAgICAgIGFtcHJlZ2V4ID0gdGhpcy5vcHRpb25zLm5vRG91YmxlRW5jb2RpbmcgPyAvKD8hJlxcUys7KSYvZyA6IC8mL2c7XG4gICAgICByZXR1cm4gc3RyLnJlcGxhY2UoYW1wcmVnZXgsICcmYW1wOycpLnJlcGxhY2UoLzwvZywgJyZsdDsnKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7JykucmVwbGFjZSgvXFx0L2csICcmI3g5OycpLnJlcGxhY2UoL1xcbi9nLCAnJiN4QTsnKS5yZXBsYWNlKC9cXHIvZywgJyYjeEQ7Jyk7XG4gICAgfTtcblxuICAgIHJldHVybiBYTUxTdHJpbmdpZmllcjtcblxuICB9KSgpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIE5vZGVUeXBlLCBYTUxDaGFyYWN0ZXJEYXRhLCBYTUxUZXh0LFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgTm9kZVR5cGUgPSByZXF1aXJlKCcuL05vZGVUeXBlJyk7XG5cbiAgWE1MQ2hhcmFjdGVyRGF0YSA9IHJlcXVpcmUoJy4vWE1MQ2hhcmFjdGVyRGF0YScpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gWE1MVGV4dCA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFhNTFRleHQsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gWE1MVGV4dChwYXJlbnQsIHRleHQpIHtcbiAgICAgIFhNTFRleHQuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmNhbGwodGhpcywgcGFyZW50KTtcbiAgICAgIGlmICh0ZXh0ID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBlbGVtZW50IHRleHQuIFwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgICB9XG4gICAgICB0aGlzLm5hbWUgPSBcIiN0ZXh0XCI7XG4gICAgICB0aGlzLnR5cGUgPSBOb2RlVHlwZS5UZXh0O1xuICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuc3RyaW5naWZ5LnRleHQodGV4dCk7XG4gICAgfVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFhNTFRleHQucHJvdG90eXBlLCAnaXNFbGVtZW50Q29udGVudFdoaXRlc3BhY2UnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIERPTSBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkLlwiICsgdGhpcy5kZWJ1Z0luZm8oKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoWE1MVGV4dC5wcm90b3R5cGUsICd3aG9sZVRleHQnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbmV4dCwgcHJldiwgc3RyO1xuICAgICAgICBzdHIgPSAnJztcbiAgICAgICAgcHJldiA9IHRoaXMucHJldmlvdXNTaWJsaW5nO1xuICAgICAgICB3aGlsZSAocHJldikge1xuICAgICAgICAgIHN0ciA9IHByZXYuZGF0YSArIHN0cjtcbiAgICAgICAgICBwcmV2ID0gcHJldi5wcmV2aW91c1NpYmxpbmc7XG4gICAgICAgIH1cbiAgICAgICAgc3RyICs9IHRoaXMuZGF0YTtcbiAgICAgICAgbmV4dCA9IHRoaXMubmV4dFNpYmxpbmc7XG4gICAgICAgIHdoaWxlIChuZXh0KSB7XG4gICAgICAgICAgc3RyID0gc3RyICsgbmV4dC5kYXRhO1xuICAgICAgICAgIG5leHQgPSBuZXh0Lm5leHRTaWJsaW5nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBYTUxUZXh0LnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIE9iamVjdC5jcmVhdGUodGhpcyk7XG4gICAgfTtcblxuICAgIFhNTFRleHQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy53cml0ZXIudGV4dCh0aGlzLCB0aGlzLm9wdGlvbnMud3JpdGVyLmZpbHRlck9wdGlvbnMob3B0aW9ucykpO1xuICAgIH07XG5cbiAgICBYTUxUZXh0LnByb3RvdHlwZS5zcGxpdFRleHQgPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgWE1MVGV4dC5wcm90b3R5cGUucmVwbGFjZVdob2xlVGV4dCA9IGZ1bmN0aW9uKGNvbnRlbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgRE9NIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQuXCIgKyB0aGlzLmRlYnVnSW5mbygpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTFRleHQ7XG5cbiAgfSkoWE1MQ2hhcmFjdGVyRGF0YSk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgTm9kZVR5cGUsIFdyaXRlclN0YXRlLCBYTUxDRGF0YSwgWE1MQ29tbWVudCwgWE1MRFREQXR0TGlzdCwgWE1MRFRERWxlbWVudCwgWE1MRFRERW50aXR5LCBYTUxEVEROb3RhdGlvbiwgWE1MRGVjbGFyYXRpb24sIFhNTERvY1R5cGUsIFhNTER1bW15LCBYTUxFbGVtZW50LCBYTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24sIFhNTFJhdywgWE1MVGV4dCwgWE1MV3JpdGVyQmFzZSwgYXNzaWduLFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBhc3NpZ24gPSByZXF1aXJlKCcuL1V0aWxpdHknKS5hc3NpZ247XG5cbiAgTm9kZVR5cGUgPSByZXF1aXJlKCcuL05vZGVUeXBlJyk7XG5cbiAgWE1MRGVjbGFyYXRpb24gPSByZXF1aXJlKCcuL1hNTERlY2xhcmF0aW9uJyk7XG5cbiAgWE1MRG9jVHlwZSA9IHJlcXVpcmUoJy4vWE1MRG9jVHlwZScpO1xuXG4gIFhNTENEYXRhID0gcmVxdWlyZSgnLi9YTUxDRGF0YScpO1xuXG4gIFhNTENvbW1lbnQgPSByZXF1aXJlKCcuL1hNTENvbW1lbnQnKTtcblxuICBYTUxFbGVtZW50ID0gcmVxdWlyZSgnLi9YTUxFbGVtZW50Jyk7XG5cbiAgWE1MUmF3ID0gcmVxdWlyZSgnLi9YTUxSYXcnKTtcblxuICBYTUxUZXh0ID0gcmVxdWlyZSgnLi9YTUxUZXh0Jyk7XG5cbiAgWE1MUHJvY2Vzc2luZ0luc3RydWN0aW9uID0gcmVxdWlyZSgnLi9YTUxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24nKTtcblxuICBYTUxEdW1teSA9IHJlcXVpcmUoJy4vWE1MRHVtbXknKTtcblxuICBYTUxEVERBdHRMaXN0ID0gcmVxdWlyZSgnLi9YTUxEVERBdHRMaXN0Jyk7XG5cbiAgWE1MRFRERWxlbWVudCA9IHJlcXVpcmUoJy4vWE1MRFRERWxlbWVudCcpO1xuXG4gIFhNTERUREVudGl0eSA9IHJlcXVpcmUoJy4vWE1MRFRERW50aXR5Jyk7XG5cbiAgWE1MRFRETm90YXRpb24gPSByZXF1aXJlKCcuL1hNTERURE5vdGF0aW9uJyk7XG5cbiAgV3JpdGVyU3RhdGUgPSByZXF1aXJlKCcuL1dyaXRlclN0YXRlJyk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBYTUxXcml0ZXJCYXNlID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIFhNTFdyaXRlckJhc2Uob3B0aW9ucykge1xuICAgICAgdmFyIGtleSwgcmVmLCB2YWx1ZTtcbiAgICAgIG9wdGlvbnMgfHwgKG9wdGlvbnMgPSB7fSk7XG4gICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgcmVmID0gb3B0aW9ucy53cml0ZXIgfHwge307XG4gICAgICBmb3IgKGtleSBpbiByZWYpIHtcbiAgICAgICAgaWYgKCFoYXNQcm9wLmNhbGwocmVmLCBrZXkpKSBjb250aW51ZTtcbiAgICAgICAgdmFsdWUgPSByZWZba2V5XTtcbiAgICAgICAgdGhpc1tcIl9cIiArIGtleV0gPSB0aGlzW2tleV07XG4gICAgICAgIHRoaXNba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIFhNTFdyaXRlckJhc2UucHJvdG90eXBlLmZpbHRlck9wdGlvbnMgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICB2YXIgZmlsdGVyZWRPcHRpb25zLCByZWYsIHJlZjEsIHJlZjIsIHJlZjMsIHJlZjQsIHJlZjUsIHJlZjY7XG4gICAgICBvcHRpb25zIHx8IChvcHRpb25zID0ge30pO1xuICAgICAgb3B0aW9ucyA9IGFzc2lnbih7fSwgdGhpcy5vcHRpb25zLCBvcHRpb25zKTtcbiAgICAgIGZpbHRlcmVkT3B0aW9ucyA9IHtcbiAgICAgICAgd3JpdGVyOiB0aGlzXG4gICAgICB9O1xuICAgICAgZmlsdGVyZWRPcHRpb25zLnByZXR0eSA9IG9wdGlvbnMucHJldHR5IHx8IGZhbHNlO1xuICAgICAgZmlsdGVyZWRPcHRpb25zLmFsbG93RW1wdHkgPSBvcHRpb25zLmFsbG93RW1wdHkgfHwgZmFsc2U7XG4gICAgICBmaWx0ZXJlZE9wdGlvbnMuaW5kZW50ID0gKHJlZiA9IG9wdGlvbnMuaW5kZW50KSAhPSBudWxsID8gcmVmIDogJyAgJztcbiAgICAgIGZpbHRlcmVkT3B0aW9ucy5uZXdsaW5lID0gKHJlZjEgPSBvcHRpb25zLm5ld2xpbmUpICE9IG51bGwgPyByZWYxIDogJ1xcbic7XG4gICAgICBmaWx0ZXJlZE9wdGlvbnMub2Zmc2V0ID0gKHJlZjIgPSBvcHRpb25zLm9mZnNldCkgIT0gbnVsbCA/IHJlZjIgOiAwO1xuICAgICAgZmlsdGVyZWRPcHRpb25zLmRvbnRQcmV0dHlUZXh0Tm9kZXMgPSAocmVmMyA9IChyZWY0ID0gb3B0aW9ucy5kb250UHJldHR5VGV4dE5vZGVzKSAhPSBudWxsID8gcmVmNCA6IG9wdGlvbnMuZG9udHByZXR0eXRleHRub2RlcykgIT0gbnVsbCA/IHJlZjMgOiAwO1xuICAgICAgZmlsdGVyZWRPcHRpb25zLnNwYWNlQmVmb3JlU2xhc2ggPSAocmVmNSA9IChyZWY2ID0gb3B0aW9ucy5zcGFjZUJlZm9yZVNsYXNoKSAhPSBudWxsID8gcmVmNiA6IG9wdGlvbnMuc3BhY2ViZWZvcmVzbGFzaCkgIT0gbnVsbCA/IHJlZjUgOiAnJztcbiAgICAgIGlmIChmaWx0ZXJlZE9wdGlvbnMuc3BhY2VCZWZvcmVTbGFzaCA9PT0gdHJ1ZSkge1xuICAgICAgICBmaWx0ZXJlZE9wdGlvbnMuc3BhY2VCZWZvcmVTbGFzaCA9ICcgJztcbiAgICAgIH1cbiAgICAgIGZpbHRlcmVkT3B0aW9ucy5zdXBwcmVzc1ByZXR0eUNvdW50ID0gMDtcbiAgICAgIGZpbHRlcmVkT3B0aW9ucy51c2VyID0ge307XG4gICAgICBmaWx0ZXJlZE9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5Ob25lO1xuICAgICAgcmV0dXJuIGZpbHRlcmVkT3B0aW9ucztcbiAgICB9O1xuXG4gICAgWE1MV3JpdGVyQmFzZS5wcm90b3R5cGUuaW5kZW50ID0gZnVuY3Rpb24obm9kZSwgb3B0aW9ucywgbGV2ZWwpIHtcbiAgICAgIHZhciBpbmRlbnRMZXZlbDtcbiAgICAgIGlmICghb3B0aW9ucy5wcmV0dHkgfHwgb3B0aW9ucy5zdXBwcmVzc1ByZXR0eUNvdW50KSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH0gZWxzZSBpZiAob3B0aW9ucy5wcmV0dHkpIHtcbiAgICAgICAgaW5kZW50TGV2ZWwgPSAobGV2ZWwgfHwgMCkgKyBvcHRpb25zLm9mZnNldCArIDE7XG4gICAgICAgIGlmIChpbmRlbnRMZXZlbCA+IDApIHtcbiAgICAgICAgICByZXR1cm4gbmV3IEFycmF5KGluZGVudExldmVsKS5qb2luKG9wdGlvbnMuaW5kZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuICcnO1xuICAgIH07XG5cbiAgICBYTUxXcml0ZXJCYXNlLnByb3RvdHlwZS5lbmRsaW5lID0gZnVuY3Rpb24obm9kZSwgb3B0aW9ucywgbGV2ZWwpIHtcbiAgICAgIGlmICghb3B0aW9ucy5wcmV0dHkgfHwgb3B0aW9ucy5zdXBwcmVzc1ByZXR0eUNvdW50KSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBvcHRpb25zLm5ld2xpbmU7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFhNTFdyaXRlckJhc2UucHJvdG90eXBlLmF0dHJpYnV0ZSA9IGZ1bmN0aW9uKGF0dCwgb3B0aW9ucywgbGV2ZWwpIHtcbiAgICAgIHZhciByO1xuICAgICAgdGhpcy5vcGVuQXR0cmlidXRlKGF0dCwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgciA9ICcgJyArIGF0dC5uYW1lICsgJz1cIicgKyBhdHQudmFsdWUgKyAnXCInO1xuICAgICAgdGhpcy5jbG9zZUF0dHJpYnV0ZShhdHQsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIHJldHVybiByO1xuICAgIH07XG5cbiAgICBYTUxXcml0ZXJCYXNlLnByb3RvdHlwZS5jZGF0YSA9IGZ1bmN0aW9uKG5vZGUsIG9wdGlvbnMsIGxldmVsKSB7XG4gICAgICB2YXIgcjtcbiAgICAgIHRoaXMub3Blbk5vZGUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLk9wZW5UYWc7XG4gICAgICByID0gdGhpcy5pbmRlbnQobm9kZSwgb3B0aW9ucywgbGV2ZWwpICsgJzwhW0NEQVRBWyc7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuSW5zaWRlVGFnO1xuICAgICAgciArPSBub2RlLnZhbHVlO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkNsb3NlVGFnO1xuICAgICAgciArPSAnXV0+JyArIHRoaXMuZW5kbGluZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuTm9uZTtcbiAgICAgIHRoaXMuY2xvc2VOb2RlKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIHJldHVybiByO1xuICAgIH07XG5cbiAgICBYTUxXcml0ZXJCYXNlLnByb3RvdHlwZS5jb21tZW50ID0gZnVuY3Rpb24obm9kZSwgb3B0aW9ucywgbGV2ZWwpIHtcbiAgICAgIHZhciByO1xuICAgICAgdGhpcy5vcGVuTm9kZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuT3BlblRhZztcbiAgICAgIHIgPSB0aGlzLmluZGVudChub2RlLCBvcHRpb25zLCBsZXZlbCkgKyAnPCEtLSAnO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkluc2lkZVRhZztcbiAgICAgIHIgKz0gbm9kZS52YWx1ZTtcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5DbG9zZVRhZztcbiAgICAgIHIgKz0gJyAtLT4nICsgdGhpcy5lbmRsaW5lKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5Ob25lO1xuICAgICAgdGhpcy5jbG9zZU5vZGUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfTtcblxuICAgIFhNTFdyaXRlckJhc2UucHJvdG90eXBlLmRlY2xhcmF0aW9uID0gZnVuY3Rpb24obm9kZSwgb3B0aW9ucywgbGV2ZWwpIHtcbiAgICAgIHZhciByO1xuICAgICAgdGhpcy5vcGVuTm9kZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuT3BlblRhZztcbiAgICAgIHIgPSB0aGlzLmluZGVudChub2RlLCBvcHRpb25zLCBsZXZlbCkgKyAnPD94bWwnO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkluc2lkZVRhZztcbiAgICAgIHIgKz0gJyB2ZXJzaW9uPVwiJyArIG5vZGUudmVyc2lvbiArICdcIic7XG4gICAgICBpZiAobm9kZS5lbmNvZGluZyAhPSBudWxsKSB7XG4gICAgICAgIHIgKz0gJyBlbmNvZGluZz1cIicgKyBub2RlLmVuY29kaW5nICsgJ1wiJztcbiAgICAgIH1cbiAgICAgIGlmIChub2RlLnN0YW5kYWxvbmUgIT0gbnVsbCkge1xuICAgICAgICByICs9ICcgc3RhbmRhbG9uZT1cIicgKyBub2RlLnN0YW5kYWxvbmUgKyAnXCInO1xuICAgICAgfVxuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkNsb3NlVGFnO1xuICAgICAgciArPSBvcHRpb25zLnNwYWNlQmVmb3JlU2xhc2ggKyAnPz4nO1xuICAgICAgciArPSB0aGlzLmVuZGxpbmUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLk5vbmU7XG4gICAgICB0aGlzLmNsb3NlTm9kZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICByZXR1cm4gcjtcbiAgICB9O1xuXG4gICAgWE1MV3JpdGVyQmFzZS5wcm90b3R5cGUuZG9jVHlwZSA9IGZ1bmN0aW9uKG5vZGUsIG9wdGlvbnMsIGxldmVsKSB7XG4gICAgICB2YXIgY2hpbGQsIGksIGxlbiwgciwgcmVmO1xuICAgICAgbGV2ZWwgfHwgKGxldmVsID0gMCk7XG4gICAgICB0aGlzLm9wZW5Ob2RlKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5PcGVuVGFnO1xuICAgICAgciA9IHRoaXMuaW5kZW50KG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIHIgKz0gJzwhRE9DVFlQRSAnICsgbm9kZS5yb290KCkubmFtZTtcbiAgICAgIGlmIChub2RlLnB1YklEICYmIG5vZGUuc3lzSUQpIHtcbiAgICAgICAgciArPSAnIFBVQkxJQyBcIicgKyBub2RlLnB1YklEICsgJ1wiIFwiJyArIG5vZGUuc3lzSUQgKyAnXCInO1xuICAgICAgfSBlbHNlIGlmIChub2RlLnN5c0lEKSB7XG4gICAgICAgIHIgKz0gJyBTWVNURU0gXCInICsgbm9kZS5zeXNJRCArICdcIic7XG4gICAgICB9XG4gICAgICBpZiAobm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAgIHIgKz0gJyBbJztcbiAgICAgICAgciArPSB0aGlzLmVuZGxpbmUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuSW5zaWRlVGFnO1xuICAgICAgICByZWYgPSBub2RlLmNoaWxkcmVuO1xuICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSByZWYubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICBjaGlsZCA9IHJlZltpXTtcbiAgICAgICAgICByICs9IHRoaXMud3JpdGVDaGlsZE5vZGUoY2hpbGQsIG9wdGlvbnMsIGxldmVsICsgMSk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkNsb3NlVGFnO1xuICAgICAgICByICs9ICddJztcbiAgICAgIH1cbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5DbG9zZVRhZztcbiAgICAgIHIgKz0gb3B0aW9ucy5zcGFjZUJlZm9yZVNsYXNoICsgJz4nO1xuICAgICAgciArPSB0aGlzLmVuZGxpbmUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLk5vbmU7XG4gICAgICB0aGlzLmNsb3NlTm9kZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICByZXR1cm4gcjtcbiAgICB9O1xuXG4gICAgWE1MV3JpdGVyQmFzZS5wcm90b3R5cGUuZWxlbWVudCA9IGZ1bmN0aW9uKG5vZGUsIG9wdGlvbnMsIGxldmVsKSB7XG4gICAgICB2YXIgYXR0LCBjaGlsZCwgY2hpbGROb2RlQ291bnQsIGZpcnN0Q2hpbGROb2RlLCBpLCBqLCBsZW4sIGxlbjEsIG5hbWUsIHByZXR0eVN1cHByZXNzZWQsIHIsIHJlZiwgcmVmMSwgcmVmMjtcbiAgICAgIGxldmVsIHx8IChsZXZlbCA9IDApO1xuICAgICAgcHJldHR5U3VwcHJlc3NlZCA9IGZhbHNlO1xuICAgICAgciA9ICcnO1xuICAgICAgdGhpcy5vcGVuTm9kZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuT3BlblRhZztcbiAgICAgIHIgKz0gdGhpcy5pbmRlbnQobm9kZSwgb3B0aW9ucywgbGV2ZWwpICsgJzwnICsgbm9kZS5uYW1lO1xuICAgICAgcmVmID0gbm9kZS5hdHRyaWJzO1xuICAgICAgZm9yIChuYW1lIGluIHJlZikge1xuICAgICAgICBpZiAoIWhhc1Byb3AuY2FsbChyZWYsIG5hbWUpKSBjb250aW51ZTtcbiAgICAgICAgYXR0ID0gcmVmW25hbWVdO1xuICAgICAgICByICs9IHRoaXMuYXR0cmlidXRlKGF0dCwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgfVxuICAgICAgY2hpbGROb2RlQ291bnQgPSBub2RlLmNoaWxkcmVuLmxlbmd0aDtcbiAgICAgIGZpcnN0Q2hpbGROb2RlID0gY2hpbGROb2RlQ291bnQgPT09IDAgPyBudWxsIDogbm9kZS5jaGlsZHJlblswXTtcbiAgICAgIGlmIChjaGlsZE5vZGVDb3VudCA9PT0gMCB8fCBub2RlLmNoaWxkcmVuLmV2ZXJ5KGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgcmV0dXJuIChlLnR5cGUgPT09IE5vZGVUeXBlLlRleHQgfHwgZS50eXBlID09PSBOb2RlVHlwZS5SYXcpICYmIGUudmFsdWUgPT09ICcnO1xuICAgICAgfSkpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuYWxsb3dFbXB0eSkge1xuICAgICAgICAgIHIgKz0gJz4nO1xuICAgICAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5DbG9zZVRhZztcbiAgICAgICAgICByICs9ICc8LycgKyBub2RlLm5hbWUgKyAnPicgKyB0aGlzLmVuZGxpbmUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5DbG9zZVRhZztcbiAgICAgICAgICByICs9IG9wdGlvbnMuc3BhY2VCZWZvcmVTbGFzaCArICcvPicgKyB0aGlzLmVuZGxpbmUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG9wdGlvbnMucHJldHR5ICYmIGNoaWxkTm9kZUNvdW50ID09PSAxICYmIChmaXJzdENoaWxkTm9kZS50eXBlID09PSBOb2RlVHlwZS5UZXh0IHx8IGZpcnN0Q2hpbGROb2RlLnR5cGUgPT09IE5vZGVUeXBlLlJhdykgJiYgKGZpcnN0Q2hpbGROb2RlLnZhbHVlICE9IG51bGwpKSB7XG4gICAgICAgIHIgKz0gJz4nO1xuICAgICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuSW5zaWRlVGFnO1xuICAgICAgICBvcHRpb25zLnN1cHByZXNzUHJldHR5Q291bnQrKztcbiAgICAgICAgcHJldHR5U3VwcHJlc3NlZCA9IHRydWU7XG4gICAgICAgIHIgKz0gdGhpcy53cml0ZUNoaWxkTm9kZShmaXJzdENoaWxkTm9kZSwgb3B0aW9ucywgbGV2ZWwgKyAxKTtcbiAgICAgICAgb3B0aW9ucy5zdXBwcmVzc1ByZXR0eUNvdW50LS07XG4gICAgICAgIHByZXR0eVN1cHByZXNzZWQgPSBmYWxzZTtcbiAgICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkNsb3NlVGFnO1xuICAgICAgICByICs9ICc8LycgKyBub2RlLm5hbWUgKyAnPicgKyB0aGlzLmVuZGxpbmUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZG9udFByZXR0eVRleHROb2Rlcykge1xuICAgICAgICAgIHJlZjEgPSBub2RlLmNoaWxkcmVuO1xuICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IHJlZjEubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGNoaWxkID0gcmVmMVtpXTtcbiAgICAgICAgICAgIGlmICgoY2hpbGQudHlwZSA9PT0gTm9kZVR5cGUuVGV4dCB8fCBjaGlsZC50eXBlID09PSBOb2RlVHlwZS5SYXcpICYmIChjaGlsZC52YWx1ZSAhPSBudWxsKSkge1xuICAgICAgICAgICAgICBvcHRpb25zLnN1cHByZXNzUHJldHR5Q291bnQrKztcbiAgICAgICAgICAgICAgcHJldHR5U3VwcHJlc3NlZCA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByICs9ICc+JyArIHRoaXMuZW5kbGluZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5JbnNpZGVUYWc7XG4gICAgICAgIHJlZjIgPSBub2RlLmNoaWxkcmVuO1xuICAgICAgICBmb3IgKGogPSAwLCBsZW4xID0gcmVmMi5sZW5ndGg7IGogPCBsZW4xOyBqKyspIHtcbiAgICAgICAgICBjaGlsZCA9IHJlZjJbal07XG4gICAgICAgICAgciArPSB0aGlzLndyaXRlQ2hpbGROb2RlKGNoaWxkLCBvcHRpb25zLCBsZXZlbCArIDEpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5DbG9zZVRhZztcbiAgICAgICAgciArPSB0aGlzLmluZGVudChub2RlLCBvcHRpb25zLCBsZXZlbCkgKyAnPC8nICsgbm9kZS5uYW1lICsgJz4nO1xuICAgICAgICBpZiAocHJldHR5U3VwcHJlc3NlZCkge1xuICAgICAgICAgIG9wdGlvbnMuc3VwcHJlc3NQcmV0dHlDb3VudC0tO1xuICAgICAgICB9XG4gICAgICAgIHIgKz0gdGhpcy5lbmRsaW5lKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLk5vbmU7XG4gICAgICB9XG4gICAgICB0aGlzLmNsb3NlTm9kZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICByZXR1cm4gcjtcbiAgICB9O1xuXG4gICAgWE1MV3JpdGVyQmFzZS5wcm90b3R5cGUud3JpdGVDaGlsZE5vZGUgPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge1xuICAgICAgc3dpdGNoIChub2RlLnR5cGUpIHtcbiAgICAgICAgY2FzZSBOb2RlVHlwZS5DRGF0YTpcbiAgICAgICAgICByZXR1cm4gdGhpcy5jZGF0YShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICAgIGNhc2UgTm9kZVR5cGUuQ29tbWVudDpcbiAgICAgICAgICByZXR1cm4gdGhpcy5jb21tZW50KG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgICAgY2FzZSBOb2RlVHlwZS5FbGVtZW50OlxuICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgICBjYXNlIE5vZGVUeXBlLlJhdzpcbiAgICAgICAgICByZXR1cm4gdGhpcy5yYXcobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgICBjYXNlIE5vZGVUeXBlLlRleHQ6XG4gICAgICAgICAgcmV0dXJuIHRoaXMudGV4dChub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICAgIGNhc2UgTm9kZVR5cGUuUHJvY2Vzc2luZ0luc3RydWN0aW9uOlxuICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NpbmdJbnN0cnVjdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICAgIGNhc2UgTm9kZVR5cGUuRHVtbXk6XG4gICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICBjYXNlIE5vZGVUeXBlLkRlY2xhcmF0aW9uOlxuICAgICAgICAgIHJldHVybiB0aGlzLmRlY2xhcmF0aW9uKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgICAgY2FzZSBOb2RlVHlwZS5Eb2NUeXBlOlxuICAgICAgICAgIHJldHVybiB0aGlzLmRvY1R5cGUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgICBjYXNlIE5vZGVUeXBlLkF0dHJpYnV0ZURlY2xhcmF0aW9uOlxuICAgICAgICAgIHJldHVybiB0aGlzLmR0ZEF0dExpc3Qobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgICBjYXNlIE5vZGVUeXBlLkVsZW1lbnREZWNsYXJhdGlvbjpcbiAgICAgICAgICByZXR1cm4gdGhpcy5kdGRFbGVtZW50KG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgICAgY2FzZSBOb2RlVHlwZS5FbnRpdHlEZWNsYXJhdGlvbjpcbiAgICAgICAgICByZXR1cm4gdGhpcy5kdGRFbnRpdHkobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgICBjYXNlIE5vZGVUeXBlLk5vdGF0aW9uRGVjbGFyYXRpb246XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZHRkTm90YXRpb24obm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gWE1MIG5vZGUgdHlwZTogXCIgKyBub2RlLmNvbnN0cnVjdG9yLm5hbWUpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBYTUxXcml0ZXJCYXNlLnByb3RvdHlwZS5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge1xuICAgICAgdmFyIHI7XG4gICAgICB0aGlzLm9wZW5Ob2RlKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5PcGVuVGFnO1xuICAgICAgciA9IHRoaXMuaW5kZW50KG5vZGUsIG9wdGlvbnMsIGxldmVsKSArICc8Pyc7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuSW5zaWRlVGFnO1xuICAgICAgciArPSBub2RlLnRhcmdldDtcbiAgICAgIGlmIChub2RlLnZhbHVlKSB7XG4gICAgICAgIHIgKz0gJyAnICsgbm9kZS52YWx1ZTtcbiAgICAgIH1cbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5DbG9zZVRhZztcbiAgICAgIHIgKz0gb3B0aW9ucy5zcGFjZUJlZm9yZVNsYXNoICsgJz8+JztcbiAgICAgIHIgKz0gdGhpcy5lbmRsaW5lKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5Ob25lO1xuICAgICAgdGhpcy5jbG9zZU5vZGUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfTtcblxuICAgIFhNTFdyaXRlckJhc2UucHJvdG90eXBlLnJhdyA9IGZ1bmN0aW9uKG5vZGUsIG9wdGlvbnMsIGxldmVsKSB7XG4gICAgICB2YXIgcjtcbiAgICAgIHRoaXMub3Blbk5vZGUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLk9wZW5UYWc7XG4gICAgICByID0gdGhpcy5pbmRlbnQobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkluc2lkZVRhZztcbiAgICAgIHIgKz0gbm9kZS52YWx1ZTtcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5DbG9zZVRhZztcbiAgICAgIHIgKz0gdGhpcy5lbmRsaW5lKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5Ob25lO1xuICAgICAgdGhpcy5jbG9zZU5vZGUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfTtcblxuICAgIFhNTFdyaXRlckJhc2UucHJvdG90eXBlLnRleHQgPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge1xuICAgICAgdmFyIHI7XG4gICAgICB0aGlzLm9wZW5Ob2RlKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5PcGVuVGFnO1xuICAgICAgciA9IHRoaXMuaW5kZW50KG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5JbnNpZGVUYWc7XG4gICAgICByICs9IG5vZGUudmFsdWU7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuQ2xvc2VUYWc7XG4gICAgICByICs9IHRoaXMuZW5kbGluZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuTm9uZTtcbiAgICAgIHRoaXMuY2xvc2VOb2RlKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIHJldHVybiByO1xuICAgIH07XG5cbiAgICBYTUxXcml0ZXJCYXNlLnByb3RvdHlwZS5kdGRBdHRMaXN0ID0gZnVuY3Rpb24obm9kZSwgb3B0aW9ucywgbGV2ZWwpIHtcbiAgICAgIHZhciByO1xuICAgICAgdGhpcy5vcGVuTm9kZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuT3BlblRhZztcbiAgICAgIHIgPSB0aGlzLmluZGVudChub2RlLCBvcHRpb25zLCBsZXZlbCkgKyAnPCFBVFRMSVNUJztcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5JbnNpZGVUYWc7XG4gICAgICByICs9ICcgJyArIG5vZGUuZWxlbWVudE5hbWUgKyAnICcgKyBub2RlLmF0dHJpYnV0ZU5hbWUgKyAnICcgKyBub2RlLmF0dHJpYnV0ZVR5cGU7XG4gICAgICBpZiAobm9kZS5kZWZhdWx0VmFsdWVUeXBlICE9PSAnI0RFRkFVTFQnKSB7XG4gICAgICAgIHIgKz0gJyAnICsgbm9kZS5kZWZhdWx0VmFsdWVUeXBlO1xuICAgICAgfVxuICAgICAgaWYgKG5vZGUuZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIHIgKz0gJyBcIicgKyBub2RlLmRlZmF1bHRWYWx1ZSArICdcIic7XG4gICAgICB9XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuQ2xvc2VUYWc7XG4gICAgICByICs9IG9wdGlvbnMuc3BhY2VCZWZvcmVTbGFzaCArICc+JyArIHRoaXMuZW5kbGluZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuTm9uZTtcbiAgICAgIHRoaXMuY2xvc2VOb2RlKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIHJldHVybiByO1xuICAgIH07XG5cbiAgICBYTUxXcml0ZXJCYXNlLnByb3RvdHlwZS5kdGRFbGVtZW50ID0gZnVuY3Rpb24obm9kZSwgb3B0aW9ucywgbGV2ZWwpIHtcbiAgICAgIHZhciByO1xuICAgICAgdGhpcy5vcGVuTm9kZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuT3BlblRhZztcbiAgICAgIHIgPSB0aGlzLmluZGVudChub2RlLCBvcHRpb25zLCBsZXZlbCkgKyAnPCFFTEVNRU5UJztcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5JbnNpZGVUYWc7XG4gICAgICByICs9ICcgJyArIG5vZGUubmFtZSArICcgJyArIG5vZGUudmFsdWU7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuQ2xvc2VUYWc7XG4gICAgICByICs9IG9wdGlvbnMuc3BhY2VCZWZvcmVTbGFzaCArICc+JyArIHRoaXMuZW5kbGluZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuTm9uZTtcbiAgICAgIHRoaXMuY2xvc2VOb2RlKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIHJldHVybiByO1xuICAgIH07XG5cbiAgICBYTUxXcml0ZXJCYXNlLnByb3RvdHlwZS5kdGRFbnRpdHkgPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge1xuICAgICAgdmFyIHI7XG4gICAgICB0aGlzLm9wZW5Ob2RlKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIG9wdGlvbnMuc3RhdGUgPSBXcml0ZXJTdGF0ZS5PcGVuVGFnO1xuICAgICAgciA9IHRoaXMuaW5kZW50KG5vZGUsIG9wdGlvbnMsIGxldmVsKSArICc8IUVOVElUWSc7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuSW5zaWRlVGFnO1xuICAgICAgaWYgKG5vZGUucGUpIHtcbiAgICAgICAgciArPSAnICUnO1xuICAgICAgfVxuICAgICAgciArPSAnICcgKyBub2RlLm5hbWU7XG4gICAgICBpZiAobm9kZS52YWx1ZSkge1xuICAgICAgICByICs9ICcgXCInICsgbm9kZS52YWx1ZSArICdcIic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAobm9kZS5wdWJJRCAmJiBub2RlLnN5c0lEKSB7XG4gICAgICAgICAgciArPSAnIFBVQkxJQyBcIicgKyBub2RlLnB1YklEICsgJ1wiIFwiJyArIG5vZGUuc3lzSUQgKyAnXCInO1xuICAgICAgICB9IGVsc2UgaWYgKG5vZGUuc3lzSUQpIHtcbiAgICAgICAgICByICs9ICcgU1lTVEVNIFwiJyArIG5vZGUuc3lzSUQgKyAnXCInO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub2RlLm5EYXRhKSB7XG4gICAgICAgICAgciArPSAnIE5EQVRBICcgKyBub2RlLm5EYXRhO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuQ2xvc2VUYWc7XG4gICAgICByICs9IG9wdGlvbnMuc3BhY2VCZWZvcmVTbGFzaCArICc+JyArIHRoaXMuZW5kbGluZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICBvcHRpb25zLnN0YXRlID0gV3JpdGVyU3RhdGUuTm9uZTtcbiAgICAgIHRoaXMuY2xvc2VOb2RlKG5vZGUsIG9wdGlvbnMsIGxldmVsKTtcbiAgICAgIHJldHVybiByO1xuICAgIH07XG5cbiAgICBYTUxXcml0ZXJCYXNlLnByb3RvdHlwZS5kdGROb3RhdGlvbiA9IGZ1bmN0aW9uKG5vZGUsIG9wdGlvbnMsIGxldmVsKSB7XG4gICAgICB2YXIgcjtcbiAgICAgIHRoaXMub3Blbk5vZGUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLk9wZW5UYWc7XG4gICAgICByID0gdGhpcy5pbmRlbnQobm9kZSwgb3B0aW9ucywgbGV2ZWwpICsgJzwhTk9UQVRJT04nO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkluc2lkZVRhZztcbiAgICAgIHIgKz0gJyAnICsgbm9kZS5uYW1lO1xuICAgICAgaWYgKG5vZGUucHViSUQgJiYgbm9kZS5zeXNJRCkge1xuICAgICAgICByICs9ICcgUFVCTElDIFwiJyArIG5vZGUucHViSUQgKyAnXCIgXCInICsgbm9kZS5zeXNJRCArICdcIic7XG4gICAgICB9IGVsc2UgaWYgKG5vZGUucHViSUQpIHtcbiAgICAgICAgciArPSAnIFBVQkxJQyBcIicgKyBub2RlLnB1YklEICsgJ1wiJztcbiAgICAgIH0gZWxzZSBpZiAobm9kZS5zeXNJRCkge1xuICAgICAgICByICs9ICcgU1lTVEVNIFwiJyArIG5vZGUuc3lzSUQgKyAnXCInO1xuICAgICAgfVxuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLkNsb3NlVGFnO1xuICAgICAgciArPSBvcHRpb25zLnNwYWNlQmVmb3JlU2xhc2ggKyAnPicgKyB0aGlzLmVuZGxpbmUobm9kZSwgb3B0aW9ucywgbGV2ZWwpO1xuICAgICAgb3B0aW9ucy5zdGF0ZSA9IFdyaXRlclN0YXRlLk5vbmU7XG4gICAgICB0aGlzLmNsb3NlTm9kZShub2RlLCBvcHRpb25zLCBsZXZlbCk7XG4gICAgICByZXR1cm4gcjtcbiAgICB9O1xuXG4gICAgWE1MV3JpdGVyQmFzZS5wcm90b3R5cGUub3Blbk5vZGUgPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge307XG5cbiAgICBYTUxXcml0ZXJCYXNlLnByb3RvdHlwZS5jbG9zZU5vZGUgPSBmdW5jdGlvbihub2RlLCBvcHRpb25zLCBsZXZlbCkge307XG5cbiAgICBYTUxXcml0ZXJCYXNlLnByb3RvdHlwZS5vcGVuQXR0cmlidXRlID0gZnVuY3Rpb24oYXR0LCBvcHRpb25zLCBsZXZlbCkge307XG5cbiAgICBYTUxXcml0ZXJCYXNlLnByb3RvdHlwZS5jbG9zZUF0dHJpYnV0ZSA9IGZ1bmN0aW9uKGF0dCwgb3B0aW9ucywgbGV2ZWwpIHt9O1xuXG4gICAgcmV0dXJuIFhNTFdyaXRlckJhc2U7XG5cbiAgfSkoKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBOb2RlVHlwZSwgV3JpdGVyU3RhdGUsIFhNTERPTUltcGxlbWVudGF0aW9uLCBYTUxEb2N1bWVudCwgWE1MRG9jdW1lbnRDQiwgWE1MU3RyZWFtV3JpdGVyLCBYTUxTdHJpbmdXcml0ZXIsIGFzc2lnbiwgaXNGdW5jdGlvbiwgcmVmO1xuXG4gIHJlZiA9IHJlcXVpcmUoJy4vVXRpbGl0eScpLCBhc3NpZ24gPSByZWYuYXNzaWduLCBpc0Z1bmN0aW9uID0gcmVmLmlzRnVuY3Rpb247XG5cbiAgWE1MRE9NSW1wbGVtZW50YXRpb24gPSByZXF1aXJlKCcuL1hNTERPTUltcGxlbWVudGF0aW9uJyk7XG5cbiAgWE1MRG9jdW1lbnQgPSByZXF1aXJlKCcuL1hNTERvY3VtZW50Jyk7XG5cbiAgWE1MRG9jdW1lbnRDQiA9IHJlcXVpcmUoJy4vWE1MRG9jdW1lbnRDQicpO1xuXG4gIFhNTFN0cmluZ1dyaXRlciA9IHJlcXVpcmUoJy4vWE1MU3RyaW5nV3JpdGVyJyk7XG5cbiAgWE1MU3RyZWFtV3JpdGVyID0gcmVxdWlyZSgnLi9YTUxTdHJlYW1Xcml0ZXInKTtcblxuICBOb2RlVHlwZSA9IHJlcXVpcmUoJy4vTm9kZVR5cGUnKTtcblxuICBXcml0ZXJTdGF0ZSA9IHJlcXVpcmUoJy4vV3JpdGVyU3RhdGUnKTtcblxuICBtb2R1bGUuZXhwb3J0cy5jcmVhdGUgPSBmdW5jdGlvbihuYW1lLCB4bWxkZWMsIGRvY3R5cGUsIG9wdGlvbnMpIHtcbiAgICB2YXIgZG9jLCByb290O1xuICAgIGlmIChuYW1lID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlJvb3QgZWxlbWVudCBuZWVkcyBhIG5hbWUuXCIpO1xuICAgIH1cbiAgICBvcHRpb25zID0gYXNzaWduKHt9LCB4bWxkZWMsIGRvY3R5cGUsIG9wdGlvbnMpO1xuICAgIGRvYyA9IG5ldyBYTUxEb2N1bWVudChvcHRpb25zKTtcbiAgICByb290ID0gZG9jLmVsZW1lbnQobmFtZSk7XG4gICAgaWYgKCFvcHRpb25zLmhlYWRsZXNzKSB7XG4gICAgICBkb2MuZGVjbGFyYXRpb24ob3B0aW9ucyk7XG4gICAgICBpZiAoKG9wdGlvbnMucHViSUQgIT0gbnVsbCkgfHwgKG9wdGlvbnMuc3lzSUQgIT0gbnVsbCkpIHtcbiAgICAgICAgZG9jLmR0ZChvcHRpb25zKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH07XG5cbiAgbW9kdWxlLmV4cG9ydHMuYmVnaW4gPSBmdW5jdGlvbihvcHRpb25zLCBvbkRhdGEsIG9uRW5kKSB7XG4gICAgdmFyIHJlZjE7XG4gICAgaWYgKGlzRnVuY3Rpb24ob3B0aW9ucykpIHtcbiAgICAgIHJlZjEgPSBbb3B0aW9ucywgb25EYXRhXSwgb25EYXRhID0gcmVmMVswXSwgb25FbmQgPSByZWYxWzFdO1xuICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cbiAgICBpZiAob25EYXRhKSB7XG4gICAgICByZXR1cm4gbmV3IFhNTERvY3VtZW50Q0Iob3B0aW9ucywgb25EYXRhLCBvbkVuZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgWE1MRG9jdW1lbnQob3B0aW9ucyk7XG4gICAgfVxuICB9O1xuXG4gIG1vZHVsZS5leHBvcnRzLnN0cmluZ1dyaXRlciA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IFhNTFN0cmluZ1dyaXRlcihvcHRpb25zKTtcbiAgfTtcblxuICBtb2R1bGUuZXhwb3J0cy5zdHJlYW1Xcml0ZXIgPSBmdW5jdGlvbihzdHJlYW0sIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IFhNTFN0cmVhbVdyaXRlcihzdHJlYW0sIG9wdGlvbnMpO1xuICB9O1xuXG4gIG1vZHVsZS5leHBvcnRzLmltcGxlbWVudGF0aW9uID0gbmV3IFhNTERPTUltcGxlbWVudGF0aW9uKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMubm9kZVR5cGUgPSBOb2RlVHlwZTtcblxuICBtb2R1bGUuZXhwb3J0cy53cml0ZXJTdGF0ZSA9IFdyaXRlclN0YXRlO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiaW1wb3J0ICogYXMgQ29tbXVuaWNhdGlvbiBmcm9tIFwiLi9jb21tdW5pY2F0aW9uXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RCb29raW5nQnRuKCk6IHZvaWQge1xuICAgIGpRdWVyeShcIi5mbGFzaF9zZWF0X21hcF9ib3hcIikucmVtb3ZlKCk7XG4gICAgY2hhbmdlQm9va2luZ0J0bkNTUygpO1xuICAgIGFwcGVuZEJvb2tpbmdCdG5IVE1MKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzaG93U2VhdG1hcEJ0blBhcmVudCgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyhcImNoaWxkIGNvbXBsZXRlbHkgcmVhZHlcIik7XG4gICAgQ29tbXVuaWNhdGlvbi5zZW5kRXZlbnRUb1BhcmVudChcImNoaWxkX3NlYXRtYXBfcmVhZHlcIik7XG59XG5cbmZ1bmN0aW9uIGFwcGVuZEJvb2tpbmdCdG5IVE1MKCk6IHZvaWQge1xuICAgIGpRdWVyeShcIiNmbGFzaF9zZWF0X21hcF9ib3hfaWRcIikuYXBwZW5kKGBcbiAgICA8ZGl2IGNsYXNzPVwicm93X3NwYWNlXCI+PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInJvd19zcGFjZVwiPjwvZGl2PlxuICAgIDxkaXYgaWQ9XCJjb250YWluZXJCb29raW5nQnRuXCI+XG4gICAgICAgIDxhIGNsYXNzPVwiY29udGludWVcIiBpZD1cIm9wZW5TZWF0bWFwXCI+XG4gICAgICAgICAgICA8c3Bhbj5TYWFscGxhbmJ1Y2h1bmc8L3NwYW4+XG4gICAgICAgIDwvYT5cbiAgICAgICAgPGRpdiBpZD1cImRpYWxvZ1NlYXRtYXBcIiBoaWRkZW49XCJoaWRkZW5cIj48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICBgKTtcbn1cblxuZnVuY3Rpb24gY2hhbmdlQm9va2luZ0J0bkNTUygpOiB2b2lkIHtcbiAgICBqUXVlcnkoJyNmbGFzaF9zZWF0X21hcF9ib3hfaWQnKS5jc3Moe1xuICAgICAgICBcImRpc3BsYXlcIjogXCJibG9ja1wiLFxuICAgICAgICBcInBvc2l0aW9uXCI6IFwicmVsYXRpdmVcIixcbiAgICAgICAgXCJ3aWR0aFwiOiBcIjEwMCVcIlxuICAgIH0pO1xufSIsImltcG9ydCAqIGFzIFhNTEhlbHBlciBmcm9tIFwiLi94bWxoZWxwZXJcIjtcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gXCIuL2NvbmZpZ1wiO1xuaW1wb3J0ICogYXMgSSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCAqIGFzIEV2ZW50cyBmcm9tIFwiLi9ldmVudHNcIjtcbmltcG9ydCAqIGFzIENhcnRCdXR0b25zIGZyb20gXCIuL2NhcnRCdXR0b25zXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRJdGVtKGluU2VhdE9iajogSS5KU0NTZWxlY3RlZFNlYXQpOiB2b2lkIHsgXG4gICAgY29uc3QgY29sb3I6IHN0cmluZyA9IGAjJHtYTUxIZWxwZXIuZ2V0VmVudWVQcmljZXNjYWxlUHJvcGVydHlCeVByaWNlc2NhbGVJRChcImNvbG9yXCIsIGluU2VhdE9iai5kYXRhLnNlYXRzT2JqLmlkWzBdKX1gO1xuICAgIGNvbnN0IGNhdGVnb3J5OiBzdHJpbmcgfCB1bmRlZmluZWQgPSBYTUxIZWxwZXIuZ2V0VmVudWVQcmljZXNjYWxlUHJvcGVydHlCeVByaWNlc2NhbGVJRChcImRlc2NcIiwgaW5TZWF0T2JqLmRhdGEuc2VhdHNPYmouaWRbMF0pO1xuICAgIGNvbnN0IHNlYXQ6IHN0cmluZyA9IGNvbmZpZy5zdGF0ZS5sYXlvdXRSb3dzW2luU2VhdE9iai5pZF1bNV07XG4gICAgY29uc3Qgcm93OiBzdHJpbmcgPSBjb25maWcuc3RhdGUubGF5b3V0Um93c1tpblNlYXRPYmouaWRdWzRdO1xuICAgIGNvbnN0IHNlY3Rpb25JRDogc3RyaW5nID0gY29uZmlnLnN0YXRlLmxheW91dFJvd3NbaW5TZWF0T2JqLmlkXVszXTtcbiAgICBjb25zdCBzZWN0aW9uRGVzYzogc3RyaW5nIHwgdW5kZWZpbmVkID0gWE1MSGVscGVyLmdldFNlY3Rpb25EZXNjQnlTZWN0aW9uSUQoc2VjdGlvbklEKTtcbiAgICBjb25zdCBzZWF0U3RyOiBzdHJpbmcgfCB1bmRlZmluZWQgPSBgJHtzZWN0aW9uRGVzY308YnIvPlJlaWhlICR7cm93fSBQbGF0eiAke3NlYXR9YDtcbiAgICBjb25zdCBidXllclR5cGVzOiBJLlR5cGVCdXllclR5cGUgPSBYTUxIZWxwZXIuZ2V0QnV5ZXJUeXBlc0J5UHJpY2VzY2FsZUlEKGluU2VhdE9iai5kYXRhLnNlYXRzT2JqLmlkWzBdKTtcbiAgICBjb25zdCBjYXJ0SUQ6IHN0cmluZyA9IGBjYXJ0SXRlbS0ke2luU2VhdE9iai5pZH1gO1xuICAgIGNvbnN0IGRyb3Bkb3duQnV5ZXJUeXBlc1NlbGVjdG9yOiBzdHJpbmcgPSBgIyR7Y2FydElEfSAuZHJvcGRvd25CdXllclR5cGVzYDtcblxuICAgIGFwcGVuZEhUTUwoY2FydElELCBjb2xvciwgY2F0ZWdvcnksIHNlYXRTdHIpO1xuICAgIGFkZERyb3Bkb3duQnV5ZXJUeXBlT3B0aW9ucyhidXllclR5cGVzLCBkcm9wZG93bkJ1eWVyVHlwZXNTZWxlY3Rvcik7XG4gICAgRXZlbnRzLmFkZENhcnREcm9wZG93bkJ1eWVyVHlwZXMoZHJvcGRvd25CdXllclR5cGVzU2VsZWN0b3IsIGluU2VhdE9iaik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVDYXJ0SXRlbXMoKTogdm9pZCB7XG4gICAgalF1ZXJ5KFwiI2NhcnRJdGVtSFRNTCAuY2FydEl0ZW1cIikuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlKCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjaGFuZ2VkRHJvcGRvd25CdXllclR5cGUoaW5TZWxlY3Q6IEhUTUxTZWxlY3RFbGVtZW50LCBpblNlYXRPYmo6IEkuSlNDU2VsZWN0ZWRTZWF0KTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXg6IG51bWJlciA9IGNvbmZpZy5zdGF0ZS5zZWxlY3RlZFNlYXRzQXJyLmZpbmRJbmRleChhcnIgPT5cbiAgICAgICAgYXJyWzBdID09PSBpblNlYXRPYmouaWQpO1xuXG4gICAgY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNBcnJbaW5kZXhdWzFdID0gaW5TZWxlY3QudmFsdWU7XG4gICAgY29uc3QgYnV5ZXJUeXBlQ29kZSA9IFhNTEhlbHBlci5nZXRCdXllclR5cGVDb2RlQnlCdXllclR5cGVJRChpblNlbGVjdC52YWx1ZSk7XG5cbiAgICBpZiAoYnV5ZXJUeXBlQ29kZSlcbiAgICAgICAgY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNBcnJbaW5kZXhdWzJdID0gYnV5ZXJUeXBlQ29kZTtcblxuICAgIGNhbGNPdmVyYWxsUHJpY2UoKTtcbiAgICBDYXJ0QnV0dG9ucy5zZXRCdG5DYXJ0VGV4dCgpO1xuXG4gICAgY29uc3QgdXJsID0gZ2VuZXJhdGVDaGVja291dFVybCgpO1xuICAgIEV2ZW50cy5hZGRSZWRpcmVjdENoZWNrb3V0KHVybCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxjT3ZlcmFsbFByaWNlKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFjb25maWcuc3RhdGUuc2VsZWN0ZWRTZWF0c0Fyci5sZW5ndGgpIHtcbiAgICAgICAgY29uZmlnLnN0YXRlLnByaWNlT3ZlcmFsbCA9IFwiMFwiO1xuICAgICAgICByZXR1cm4gXCIwXCI7XG4gICAgfVxuXG4gICAgY29uZmlnLnN0YXRlLnByaWNlT3ZlcmFsbCA9IHN1bVNlYXRQcmljZXMoKTtcbiAgICByZXR1cm4gY29uZmlnLnN0YXRlLnByaWNlT3ZlcmFsbDtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVDYXJ0SXRlbXMoKTogdm9pZCB7XG4gICAgaWYgKCFjb25maWcuc3RhdGUuc2VsZWN0ZWRTZWF0c0Fyci5sZW5ndGgpXG4gICAgICAgIHJldHVybjtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIGNvbmZpZy5zdGF0ZS5zZWxlY3RlZFNlYXRzT2JqKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNPYmosIGtleSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBjb25maWcuc3RhdGUuc2VsZWN0ZWRTZWF0c09ialtrZXldO1xuICAgICAgICAgICAgYWRkSXRlbShlbGVtZW50KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRNb2RhbENhcnQoKTogdm9pZCB7XG4gICAgalF1ZXJ5KFwiI21vZGFsQ2FydC1vdmVybGF5XCIpLmhpZGUoKTtcbiAgICBFdmVudHMuYWRkQ2FydEJhY2soKTtcbiAgICBFdmVudHMuYWRkQ2FydENsb3NlKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUNoZWNrb3V0VXJsKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFjb25maWcuc3RhdGUuc2VsZWN0ZWRTZWF0c0Fyci5sZW5ndGgpXG4gICAgICAgIHJldHVybjtcblxuICAgIGNvbnN0IGlucHV0c1dpdGhWYWx1ZSA9IGNvbmZpZy5zdGF0ZS5pbnB1dHNXaXRoVmFsdWUhO1xuICAgIGNvbnN0IHNlbGVjdGVkU2VhdEluZGV4ZXM6IHN0cmluZyA9IFhNTEhlbHBlci5nZW5lcmF0ZVNlbGVjdGVkU2VhdEluZGV4ZXMoKTtcbiAgICByZXR1cm4gYCR7aW5wdXRzV2l0aFZhbHVlW1widGlja2V0UHVyY2hhc2VVcmxcIl19P3VzZXJfY29udGV4dD0ke2lucHV0c1dpdGhWYWx1ZS51c2VyX2NvbnRleHR9JnBpZD0ke2lucHV0c1dpdGhWYWx1ZVtcInBpZFwiXX0mc2VsZWN0ZWRfc2VhdF9pbmRleGVzPSR7c2VsZWN0ZWRTZWF0SW5kZXhlc30mdHJ4c3RhdGU9MTQ4YDtcbn1cblxuZnVuY3Rpb24gYXBwZW5kSFRNTChpbkNhcnRJRDogc3RyaW5nLCBpbkNvbG9yOiBzdHJpbmcsIGluQ2F0ZWdvcnk6IHN0cmluZyB8IHVuZGVmaW5lZCwgaW5TZWF0U3RyOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBqUXVlcnkoXCIjY2FydEl0ZW1IVE1MIC5mbC1odG1sXCIpLmFwcGVuZChgXG4gICAgPGRpdiBjbGFzcz1cImNhcnRJdGVtXCIgaWQ9XCIke2luQ2FydElEfVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2FydEl0ZW1Db2xvcmVkU3F1YXJlXCIgc3R5bGU9XCJiYWNrZ3JvdW5kOiAke2luQ29sb3J9O1wiPjwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2FydEl0ZW1DYXRlZ29yeVwiPiR7aW5DYXRlZ29yeX08L2Rpdj5cbiAgICAgICAgPGg1IGNsYXNzPVwiY2FydEl0ZW1TZWF0XCI+JHtpblNlYXRTdHJ9PC9oNT5cbiAgICAgICAgPHNlbGVjdCBuYW1lPVwiZHJvcGRvd25CdXllclR5cGVzXCIgY2xhc3M9XCJkcm9wZG93bkJ1eWVyVHlwZXNcIj48L3NlbGVjdD5cbiAgICA8L2Rpdj5gKTtcbn1cblxuLy8gdG9kbzogZ2VuZXJhbGl6ZSBkcm9wZG93biBmaWxsIG9wdGlvbnNcbmZ1bmN0aW9uIGFkZERyb3Bkb3duQnV5ZXJUeXBlT3B0aW9ucyhpbkJ1eWVyVHlwZXM6IEkuVHlwZUJ1eWVyVHlwZSwgaW5TZWxlY3Rvcjogc3RyaW5nKSB7XG4gICAgaWYgKCFpbkJ1eWVyVHlwZXMpXG4gICAgICAgIHJldHVybjtcblxuICAgIGluQnV5ZXJUeXBlcy5mb3JFYWNoKGFyciA9PiB7ICAgICAgICBcbiAgICAgICAgaWYgKGFyclswXSlcbiAgICAgICAgICAgIGFwcGVuZE9wdGlvbihpblNlbGVjdG9yLCBhcnIpXG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGFwcGVuZE9wdGlvbihpblNlbGVjdG9yOiBzdHJpbmcsIGluQXJyOiBJLlR5cGVCdXllclR5cGVBcnIpOiB2b2lkIHtcbiAgICBjb25zdCBkcm9wZG93bkJ1eWVyVHlwZXM6IEhUTUxFbGVtZW50ID0galF1ZXJ5KGluU2VsZWN0b3IpLmdldCgwKTtcbiAgICBsZXQgb3B0OiBIVE1MT3B0aW9uRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ29wdGlvbicpO1xuICAgIG9wdC52YWx1ZSA9IDxzdHJpbmc+aW5BcnJbMF07XG4gICAgb3B0LmlubmVySFRNTCA9IGAke2luQXJyWzJdfSDigqwke2luQXJyWzFdfWA7XG4gICAgZHJvcGRvd25CdXllclR5cGVzLmFwcGVuZENoaWxkKG9wdCk7XG59XG5cbmZ1bmN0aW9uIHN1bVNlYXRQcmljZXMoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNBcnIubWFwKGdldFNlYXRQcmljZSlcbiAgICAgICAgLnJlZHVjZSgocHJldiwgY3VycikgPT4gcHJldiArIGN1cnIpXG4gICAgICAgIC50b0ZpeGVkKDIpO1xufVxuXG5mdW5jdGlvbiBnZXRTZWF0UHJpY2UoYXJyOiBzdHJpbmdbXSkge1xuICAgIGNvbnN0IHNlYXRJRDogc3RyaW5nID0gYXJyWzBdO1xuICAgICAgICBjb25zdCBidXllcnR5cGVJRDogc3RyaW5nID0gYXJyWzFdO1xuICAgICAgICBjb25zdCBzZWxlY3RlZFNlYXQ6IEkuSlNDU2VsZWN0ZWRTZWF0ID0gY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNPYmpbc2VhdElEXTtcbiAgICAgICAgY29uc3QgcHJpY2VzY2FsZUlEOiBzdHJpbmcgPSBzZWxlY3RlZFNlYXQuZGF0YS5zZWF0c09iai5pZFswXTtcbiAgICAgICAgY29uc3QgcHJpY2VzY2FsZU9iajogSS5QcmljZXNjYWxlNSB8IHVuZGVmaW5lZCA9IFhNTEhlbHBlci5nZXRWZW51ZVByaWNlU3RydWN0dXJlUHJvcGVydHlCeVByaWNlc2NhbGVJRChwcmljZXNjYWxlSUQpO1xuXG4gICAgICAgIGlmIChwcmljZXNjYWxlT2JqKSB7XG4gICAgICAgICAgICBjb25zdCBzZWF0UHJpY2U6IG51bWJlciB8IHVuZGVmaW5lZCA9IFhNTEhlbHBlci5nZXRQcmljZUJ5QnV5ZXJUeXBlSUQoYnV5ZXJ0eXBlSUQsIHByaWNlc2NhbGVPYmopO1xuXG4gICAgICAgICAgICBpZiAoc2VhdFByaWNlKVxuICAgICAgICAgICAgICAgIHJldHVybiBzZWF0UHJpY2U7ICAgXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gMDtcbn0iLCJpbXBvcnQgeyBjb25maWcgfSBmcm9tIFwiLi9jb25maWdcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldEJ0bkNhcnRUZXh0KCk6IHZvaWQge1xuICAgIGpRdWVyeShcIiNtb2RhbENhcnQgLnVhYmItYnV0dG9uLXRleHRcIilbMF0uaW5uZXJUZXh0ID0gY3JlYXRlQ2FydEJ0blRleHQoKTtcbiAgICBqUXVlcnkoXCIjbW9kYWxDYXJ0U3VtIC51YWJiLWhlYWRpbmctdGV4dFwiKVswXS50ZXh0Q29udGVudCA9IGNyZWF0ZU1vZGFsQ2FydEJ0blRleHQoKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2FydEJ0blRleHQoKTogc3RyaW5nIHtcbiAgICBjb25zdCBudW1UaWNrZXRzOiBudW1iZXIgPSBjb25maWcuc3RhdGUuc2VsZWN0ZWRTZWF0c0Fyci5sZW5ndGg7XG5cbiAgICBpZiAoY29uZmlnLnN0YXRlLnByaWNlT3ZlcmFsbCAhPT0gXCJcIilcbiAgICAgICAgcmV0dXJuIG51bVRpY2tldHMgPT09IDEgPyBgJHtudW1UaWNrZXRzfSBUaWNrZXQgZsO8ciDigqwke2NvbmZpZy5zdGF0ZS5wcmljZU92ZXJhbGx9YCA6IGAke251bVRpY2tldHN9IFRpY2tldHMgZsO8ciDigqwke2NvbmZpZy5zdGF0ZS5wcmljZU92ZXJhbGx9YDtcbiAgICBlbHNlIFxuICAgICAgICByZXR1cm4gXCIwIFRpY2tldHMgZsO8ciDigqwwLjAwXCI7ICAgIFxufVxuXG5mdW5jdGlvbiBjcmVhdGVNb2RhbENhcnRCdG5UZXh0KCk6IHN0cmluZyB7XG4gICAgY29uc3QgbnVtVGlja2V0czogbnVtYmVyID0gY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNBcnIubGVuZ3RoO1xuXG4gICAgaWYgKGNvbmZpZy5zdGF0ZS5wcmljZU92ZXJhbGwgIT09IFwiXCIpXG4gICAgICAgIHJldHVybiBgU3VtbWUgKCR7bnVtVGlja2V0c30gUGzDpHR6ZSkg4oKsJHtjb25maWcuc3RhdGUucHJpY2VPdmVyYWxsfWA7XG4gICAgZWxzZVxuICAgICAgICByZXR1cm4gYFN1bW1lICgwIFBsw6R0emUpIOKCrDAsMDBgO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2hvd0hpZGVCdG5DYXJ0TG9hZGluZyhpblN3aXRjaDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKGluU3dpdGNoID09PSBcInNob3dcIikge1xuICAgICAgICBqUXVlcnkoXCIjbW9kYWxDYXJ0IC51YWJiLWJ1dHRvblwiKS5jc3MoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICAgIGpRdWVyeShcIiNtb2RhbENhcnQgaVwiKS5oaWRlKCk7XG4gICAgICAgIGpRdWVyeShcIiNtb2RhbENhcnQgLnVhYmItYnV0dG9uLXRleHRcIikuYWRkQ2xhc3MoXCJkb3QtcHVsc2VcIik7XG4gICAgfVxuICAgIGVsc2UgaWYgKGluU3dpdGNoID09PSBcImhpZGVcIikge1xuICAgICAgICBqUXVlcnkoXCIjbW9kYWxDYXJ0IGlcIikuc2hvdygpO1xuICAgICAgICBqUXVlcnkoXCIjbW9kYWxDYXJ0IC51YWJiLWJ1dHRvbi10ZXh0XCIpLnJlbW92ZUNsYXNzKFwiZG90LXB1bHNlXCIpO1xuICAgICAgICBqUXVlcnkoXCIjbW9kYWxDYXJ0IC51YWJiLWJ1dHRvblwiKS5jc3MoXCJwb2ludGVyLWV2ZW50c1wiLCBcImFsbFwiKTtcbiAgICB9XG59IiwiaW1wb3J0ICogYXMgQ29tbXVuaWNhdGlvbiBmcm9tIFwiLi9jb21tdW5pY2F0aW9uXCI7XG5pbXBvcnQgKiBhcyBVSSBmcm9tIFwiLi91aVwiO1xuaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgVXRpbHMgZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCAqIGFzIFBhcnNlciBmcm9tICcuL3BhcnNlcic7XG5pbXBvcnQgKiBhcyBJIGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0ICogYXMgSlNDIGZyb20gXCIuL2pzY1wiO1xuaW1wb3J0ICogYXMgTGVnZW5kIGZyb20gXCIuL2xlZ2VuZFwiO1xuaW1wb3J0ICogYXMgRXZlbnRzIGZyb20gXCIuL2V2ZW50c1wiO1xuaW1wb3J0ICogYXMgVHJpbXMgZnJvbSBcIi4vdHJpbXNcIjtcbmltcG9ydCAqIGFzIFhNTEhlbHBlciBmcm9tIFwiLi94bWxoZWxwZXJcIjtcbmltcG9ydCAqIGFzIFBhbnpvb20gZnJvbSBcIi4vcGFuem9vbVwiO1xuaW1wb3J0ICogYXMgakJveEhlbHBlciBmcm9tIFwiLi9qQm94SGVscGVyXCI7XG5pbXBvcnQgKiBhcyBDYXJ0IGZyb20gXCIuL2NhcnRcIjtcbmltcG9ydCAqIGFzIENhcnRCdXR0b25zIGZyb20gXCIuL2NhcnRCdXR0b25zXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0VmVudWUoKSB7XG4gICAgVUkuY29udHJvbExvZnRsb2FkZXIoXCJzaG93XCIpO1xuICAgIENvbW11bmljYXRpb24uc2VuZEV2ZW50VG9QYXJlbnQoXCJjaGlsZF9pbml0X25lZWRJbnB1dHNXaXRoVmFsdWVcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0U2VuZFZlbnVlWE1MKGluRTogYW55KSB7XG4gICAgY29uc3QgZGF0YTogSS5NZXNzYWdlID0gSlNPTi5wYXJzZShpbkUuZGF0YSk7XG4gICAgY29uZmlnLnN0YXRlLmluVmVudWVYTUwgPSBkYXRhLm1lc3NhZ2UubWFwX3Jlc3BvbnNlO1xuICAgIGNvbnN0IHZlbnVlWE1MID0gY29uZmlnLnN0YXRlLmluVmVudWVYTUwhO1xuXG4gICAgLy8gR2VuZXJhdGUgcHJpY2VzY2FsZSBjc3MgY2xhc3Nlc1xuICAgIGNvbnN0IGNzcyA9IFVJLmdlbmVyYXRlUHJpY2VzY2FsZUNTUygpO1xuICAgIFV0aWxzLmluamVjdChjc3MsIFwiY3NzQ3VzdG9tXCIsIFwiYm9keVwiKTtcblxuICAgIC8vIEZpbGwgZXZlbnQgaW5mb1xuICAgIGNvbnN0IGV2ZW50SW5mbyA9IFBhcnNlci5nZXRFdmVudEluZm8oKTtcbiAgICBVSS5zZXRFdmVudEluZm8oZXZlbnRJbmZvKTtcblxuICAgIC8vIEZpbGwgc2VsZWN0IGRyb3Bkb3duXG4gICAgY29uc3Qgc2VhdG1hcExpc3Rpbmc6IEkuU2VhdG1hcFtdID0gdmVudWVYTUwuc2VhdG1hcF9jb25maWdbMF0uc2VhdG1hcDtcbiAgICBVSS5zZXRPcHRpb25TZWxlY3Qoc2VhdG1hcExpc3RpbmcsIFwiZHJvcGRvd25TZWF0bWFwXCIpO1xuXG4gICAgLy8gRGlzcGxheSBmaXJzdCBzZWF0bWFwWE1MXG4gICAgY29uc3QgaWQ6IHN0cmluZyA9IHNlYXRtYXBMaXN0aW5nWzBdLmlkWzBdO1xuICAgIGpRdWVyeShcIiNkcm9wZG93blNlYXRtYXBcIikudmFsKGlkKTtcbiAgICBDb21tdW5pY2F0aW9uLm5lZWRTZWF0bWFwWE1MKGlkKTtcblxuICAgIGNvbnNvbGUubG9nKGNzcyk7XG4gICAgY29uc29sZS5sb2coc2VhdG1hcExpc3RpbmcpO1xuXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0U2VuZElucHV0c1dpdGhWYWx1ZShpbkU6IGFueSkge1xuICAgIGNvbnN0IGRhdGE6IEkuTWVzc2FnZSA9IEpTT04ucGFyc2UoaW5FLmRhdGEpO1xuICAgIGNvbmZpZy5zdGF0ZS5pbnB1dHNXaXRoVmFsdWUgPSBkYXRhLm1lc3NhZ2U7XG4gICAgVUkuY2hhbmdlVmVudWVJbWFnZSgpO1xuICAgIENvbW11bmljYXRpb24uc2VuZEV2ZW50VG9QYXJlbnQoXCJjaGlsZF9pbml0X25lZWRWZW51ZVhNTFwiKTtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gc2VuZFNlYXRtYXBYTUwoaW5FOiBhbnkpIHtcbiAgICBjb25zdCBkYXRhOiBJLk1lc3NhZ2UgPSBKU09OLnBhcnNlKGluRS5kYXRhKTtcbiAgICBjb25maWcuc3RhdGUuc2VhdG1hcFhNTCA9IGRhdGEubWVzc2FnZS5tYXBfcmVzcG9uc2U7XG4gICAgY29uc3QgbWFwOiBzdHJpbmdbXSA9IEpTQy5nZW5lcmF0ZU1hcCgpO1xuICAgIGNvbnN0IHJvd3NOYW1pbmc6IHN0cmluZ1tdID0gSlNDLmdldFJvd3NOYW1pbmcoKTtcbiAgICBjb25zdCBzZWF0czogSS5KU0NTZWF0cyA9IEpTQy5nZXRTZWF0cygpO1xuICAgIGNvbnN0IGxlZ2VuZDogSS5KU0NMZWdlbmQgPSBKU0MuZ2VuZXJhdGVMZWdlbmQoXCIjSlNDTGVnZW5kSW5uZXJcIik7XG5cbiAgICBKU0MuYWRkU2VhdG1hcChcIiNjb250YWluZXJTZWF0bWFwSW5uZXJcIiwgbWFwLCByb3dzTmFtaW5nLCBzZWF0cywgbGVnZW5kKTtcbiAgICBKU0Muc2V0VW5hdmFpbGFibGVTZWF0cygpO1xuICAgIEpTQy5zZWxlY3RTZWF0c0luQ2FydCgpO1xuICAgIExlZ2VuZC5jb252ZXJ0TGVnZW5kVG9Ecm9wZG93bihcImRyb3Bkb3duTGVnZW5kXCIpO1xuICAgIEV2ZW50cy5kcm9wZG93bkxlZ2VuZE9uQ2hhbmdlKFwiI2Ryb3Bkb3duTGVnZW5kXCIpO1xuICAgIFRyaW1zLmFkZFRyaW1zKCk7XG4gICAgWE1MSGVscGVyLnByb2Nlc3NTTUFQKCk7XG4gICAgY29uZmlnLnN0YXRlLnBhbnpvb20gPSBQYW56b29tLmFkZFBhbnpvb20oXCIjY29udGFpbmVyU2VhdG1hcElubmVyXCIsIFwiLnBhbnpvb21ab29tSW5cIiwgXCIucGFuem9vbVpvb21PdXRcIiwgXCIjcGFuem9vbVJlc2V0Wm9vbVwiKTtcbiAgICBVSS5jb250cm9sTG9mdGxvYWRlcihcImhpZGVcIik7XG4gICAgakJveEhlbHBlci5jcmVhdGVTZWF0VG9vbHRpcHMoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNlbmRDaGVja291dFJlc3BvbnNlKGluRTogYW55KSB7XG4gICAgY29uc3QgZGF0YTogSS5NZXNzYWdlID0gSlNPTi5wYXJzZShpbkUuZGF0YSk7XG4gICAgY29uZmlnLnN0YXRlLmlzVmFsaWRTZWF0U2VsZWN0aW9uID0gZGF0YS5tZXNzYWdlLmlzVmFsaWRTZWF0U2VsZWN0aW9uO1xuXG4gICAgY29uc29sZS5sb2coZGF0YS5tZXNzYWdlKTtcblxuICAgIGlmICghY29uZmlnLnN0YXRlLmlzVmFsaWRTZWF0U2VsZWN0aW9uKSB7XG4gICAgICAgIGpCb3hIZWxwZXIuc2hvd0pCb3hOb3RpY2UoYEF1c3dhaGwgbmljaHQgbcO2Z2xpY2g6IEJpdHRlIGxhc3NlbiBTaWUga2VpbmVuIGVpbnplbG5lbiBQbGF0eiBmcmVpLmApO1xuICAgICAgICBDYXJ0QnV0dG9ucy5zaG93SGlkZUJ0bkNhcnRMb2FkaW5nKFwiaGlkZVwiKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIENhcnQucmVtb3ZlQ2FydEl0ZW1zKCk7XG4gICAgICAgIENhcnQuZ2VuZXJhdGVDYXJ0SXRlbXMoKTtcbiAgICAgICAgY29uc3QgdXJsID0gQ2FydC5nZW5lcmF0ZUNoZWNrb3V0VXJsKCk7XG4gICAgICAgIEV2ZW50cy5hZGRSZWRpcmVjdENoZWNrb3V0KHVybCk7XG4gICAgICAgIFVJLmZhZGVJbkNhcnRNb2RhbCgpO1xuICAgICAgICBDYXJ0QnV0dG9ucy5zaG93SGlkZUJ0bkNhcnRMb2FkaW5nKFwiaGlkZVwiKTtcbiAgICB9XG5cbiAgICBjb25maWcuc3RhdGUuY2FydENoYW5nZWQgPSBmYWxzZTtcbn1cbiIsImltcG9ydCAqIGFzIEkgZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgYXhpb3MsIHsgQXhpb3NSZXNwb25zZSB9IGZyb20gJ2F4aW9zJztcbmNvbnN0IHhtbDJqc1BhcnNlciA9IHJlcXVpcmUoJ3htbDJqcycpLnBhcnNlU3RyaW5nO1xuaW1wb3J0ICogYXMgVUkgZnJvbSBcIi4vdWlcIjtcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gXCIuL2NvbmZpZ1wiO1xuaW1wb3J0ICogYXMgQ2FydCBmcm9tIFwiLi9jYXJ0XCI7XG5cbi8vIHJld29yayB0cnkvY2F0Y2ggP1xuZXhwb3J0IGZ1bmN0aW9uIHNlbmRNZXNzYWdlKGluRGF0YTogSS5NZXNzYWdlLCBpblRvOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoaW5UbyA9PT0gXCJwYXJlbnRcIilcbiAgICAgICAgd2luZG93LnBhcmVudC5wb3N0TWVzc2FnZShKU09OLnN0cmluZ2lmeShpbkRhdGEpLCAnKicpO1xuICAgIGVsc2Uge1xuICAgICAgICBjb25zdCBjaGlsZDogYW55ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaW5Ubyk7XG5cbiAgICAgICAgaWYgKGNoaWxkICE9PSBudWxsICYmIGNoaWxkLmNvbnRlbnRXaW5kb3cgIT09IG51bGwpXG4gICAgICAgICAgICBjaGlsZC5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKEpTT04uc3RyaW5naWZ5KGluRGF0YSksIFwiKlwiKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgY29uc29sZS5sb2coYEVsZW1lbnQgd2l0aCBJRCAke2luVG99IGRvZXMgbm90IGV4aXN0YCk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbGlzdGVuVG9NZXNzYWdlcyhpbkhhbmRsZXI6IENhbGxhYmxlRnVuY3Rpb24pOiB2b2lkIHtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIChlOiBhbnkpOiB2b2lkID0+IHtcbiAgICAgICAgaW5IYW5kbGVyKGUpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2VuZFhNTChpblVybDogc3RyaW5nLCBpblRvOiBzdHJpbmcsIGluRXZlbnQ6IHN0cmluZywgaW5Gcm9tOiBzdHJpbmcsIGluRGF0ZTogbnVtYmVyID0gRGF0ZS5ub3coKSk6IHZvaWQge1xuICAgIGdldFhNTFByb21pc2UoaW5VcmwpLnRoZW4oKHJlc3VsdDogdW5rbm93bik6IHZvaWQgPT4ge1xuICAgICAgICBjb25zdCBtZXNzYWdlOiBJLk1lc3NhZ2UgPSB7XG4gICAgICAgICAgICBkYXRlOiBpbkRhdGUsXG4gICAgICAgICAgICBmcm9tOiBpbkZyb20sXG4gICAgICAgICAgICBtZXNzYWdlOiByZXN1bHQsXG4gICAgICAgICAgICBldmVudDogaW5FdmVudFxuICAgICAgICB9XG4gICAgICAgIHNlbmRNZXNzYWdlKG1lc3NhZ2UsIGluVG8pO1xuICAgIH0pXG4gICAgICAgIC5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2VuZEV2ZW50VG9DaGlsZChpbkV2ZW50OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBtZXNzYWdlOiBJLk1lc3NhZ2UgPSB7XG4gICAgICAgIG1lc3NhZ2U6IG51bGwsXG4gICAgICAgIGZyb206IFwicGFyZW50XCIsXG4gICAgICAgIGV2ZW50OiBpbkV2ZW50LFxuICAgICAgICBkYXRlOiBEYXRlLm5vdygpXG4gICAgfTtcbiAgICBzZW5kTWVzc2FnZShtZXNzYWdlLCBcImlmcmFtZVNlYXRtYXBcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZW5kRXZlbnRUb1BhcmVudChpbkV2ZW50OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBtZXNzYWdlOiBJLk1lc3NhZ2UgPSB7XG4gICAgICAgIG1lc3NhZ2U6IG51bGwsXG4gICAgICAgIGZyb206IFwiY2hpbGRcIixcbiAgICAgICAgZXZlbnQ6IGluRXZlbnQsXG4gICAgICAgIGRhdGU6IERhdGUubm93KClcbiAgICB9O1xuICAgIHNlbmRNZXNzYWdlKG1lc3NhZ2UsIFwicGFyZW50XCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbmVlZFNlYXRtYXBYTUwoaW5JRDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgbWVzc2FnZTogSS5NZXNzYWdlID0ge1xuICAgICAgICBtZXNzYWdlOiBpbklELFxuICAgICAgICBmcm9tOiBcImNoaWxkXCIsXG4gICAgICAgIGV2ZW50OiBcImNoaWxkX25lZWRTZWF0bWFwWE1MXCIsXG4gICAgICAgIGRhdGU6IERhdGUubm93KClcbiAgICB9O1xuICAgIHNlbmRNZXNzYWdlKG1lc3NhZ2UsIFwicGFyZW50XCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FuY2VsQ2hlY2tvdXQoaW5Vcmw6IHN0cmluZyk6IHZvaWQge1xuICAgIC8vIHVzZSBmZXRjaCBpbnN0ZWFkIG9mIGF4aW9zIGJlY2F1c2Ugb2YgMzAyIHJlZGlyZWN0XG4gICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9heGlvcy9heGlvcy9pc3N1ZXMvOTMyXG4gICAgZmV0Y2goaW5VcmwsIHtcbiAgICAgICAgcmVkaXJlY3Q6IFwibWFudWFsXCJcbiAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiBjb25zb2xlLmxvZyhgJHtpblVybH0gY2FuY2VsZWRgKSlcbiAgICAgICAgLmNhdGNoKGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJlcnJvclwiKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkU2VhdFNlbGVjdGlvbigpOiB2b2lkIHtcbiAgICBqUXVlcnkoXCIjbW9kYWxDYXJ0LW92ZXJsYXlcIikuaGlkZSgpO1xuXG4gICAgaWYgKCFjb25maWcuc3RhdGUuc2VsZWN0ZWRTZWF0c0Fyci5sZW5ndGgpXG4gICAgICAgIHJldHVybjtcblxuICAgIFVJLmFkanVzdFVJVG9Mb2FkaW5nKCk7XG4gICAgY29uc3QgdXJsOiBzdHJpbmcgfCB1bmRlZmluZWQgPSBDYXJ0LmdlbmVyYXRlQ2hlY2tvdXRVcmwoKTtcblxuICAgIGNvbnN0IG1lc3NhZ2U6IEkuTWVzc2FnZSA9IHtcbiAgICAgICAgbWVzc2FnZToge1xuICAgICAgICAgICAgdXJsOiB1cmwsXG4gICAgICAgIH0sXG4gICAgICAgIGZyb206IFwiY2hpbGRcIixcbiAgICAgICAgZXZlbnQ6IFwiY2hpbGRfbmVlZENoZWNrb3V0UmVzcG9uc2VcIixcbiAgICAgICAgZGF0ZTogRGF0ZS5ub3coKVxuICAgIH07XG5cbiAgICBzZW5kTWVzc2FnZShtZXNzYWdlLCBcInBhcmVudFwiKTtcbn1cblxuZnVuY3Rpb24gZ2V0WE1MUHJvbWlzZShpblVybDogc3RyaW5nKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgcmV0dXJuIGF4aW9zLmdldChpblVybClcbiAgICAgICAgLnRoZW4oKHJlc3BvbnNlOiB2b2lkIHwgQXhpb3NSZXNwb25zZTxhbnk+KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmU6IGFueSwgcmVqZWN0OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBBeGlvc1Jlc3BvbnNlID0gPEF4aW9zUmVzcG9uc2U+cmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgaWYgKEF4aW9zUmVzcG9uc2Uuc3RhdHVzID09PSAyMDAgJiYgQXhpb3NSZXNwb25zZS5oZWFkZXJzW1wiY29udGVudC10eXBlXCJdID09PSBcInRleHQveG1sO2NoYXJzZXQ9dXRmLThcIikge1xuICAgICAgICAgICAgICAgICAgICB4bWwyanNQYXJzZXIoQXhpb3NSZXNwb25zZS5kYXRhLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBub3JtYWxpemVUYWdzOiB0cnVlLCBub3JtYWxpemU6IHRydWUsIG1lcmdlQXR0cnM6IHRydWUgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIChlcnI6IGFueSwgcmVzdWx0OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICAgIH0pO1xufSIsImltcG9ydCAqIGFzIEkgZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5cbmV4cG9ydCBjb25zdCBjb25maWc6IEkuQ29uZmlnID0ge1xuICAgIGRlYnVnOiB0cnVlLFxuICAgIGJyYW5jaDogXCJzdGFnaW5nXCIsXG4gICAgdXJsU2VhdG1hcFN0YWdpbmc6IFwiaHR0cHM6Ly9zdGFnaW5nLnRpY2tldHMuemlub21lZGlhLmRlXCIsXG4gICAgdXJsU2VhdG1hcE1hc3RlcjogXCJodHRwczovL3RpY2tldHMuemlub21lZGlhLmRlXCIsXG4gICAgdXJsQ1NTQ2hpbGRNYXN0ZXI6IFwiaHR0cHM6Ly90aWNrZXRzLnppbm9tZWRpYS5kZS9kaXN0L3N0eWxlQ2hpbGQuY3NzXCIsXG4gICAgdXJsQ1NTQ2hpbGRTdGFnaW5nOiBcImh0dHBzOi8vc3RhZ2luZy50aWNrZXRzLnppbm9tZWRpYS5kZS9kaXN0L3N0eWxlQ2hpbGQuY3NzXCIsXG4gICAgdXJsQ1NTUGFyZW50TWFzdGVyOiBcImh0dHBzOi8vdGlja2V0cy56aW5vbWVkaWEuZGUvZGlzdC9zdHlsZVBhcmVudC5jc3NcIixcbiAgICB1cmxDU1NQYXJlbnRTdGFnaW5nOiBcImh0dHBzOi8vc3RhZ2luZy50aWNrZXRzLnppbm9tZWRpYS5kZS9kaXN0L3N0eWxlUGFyZW50LmNzc1wiLFxuICAgIHVybEpTQ1N0YWdpbmc6IFwiaHR0cHM6Ly9zdGFnaW5nLnRpY2tldHMuemlub21lZGlhLmRlL2xpYnMvalF1ZXJ5LVNlYXQtQ2hhcnRzL2pxdWVyeS5zZWF0LWNoYXJ0cy5taW4uanNcIixcbiAgICB1cmxKU0NNYXN0ZXI6IFwiaHR0cHM6Ly90aWNrZXRzLnppbm9tZWRpYS5kZS9saWJzL2pRdWVyeS1TZWF0LUNoYXJ0cy9qcXVlcnkuc2VhdC1jaGFydHMubWluLmpzXCIsXG4gICAgdXJsQ1NTSlNDU3RhZ2luZzogXCJodHRwczovL3N0YWdpbmcudGlja2V0cy56aW5vbWVkaWEuZGUvbGlicy9qUXVlcnktU2VhdC1DaGFydHMvanF1ZXJ5LnNlYXQtY2hhcnRzLmNzc1wiLFxuICAgIHVybENTU0pTQ01hc3RlcjogXCJodHRwczovL3RpY2tldHMuemlub21lZGlhLmRlL2xpYnMvalF1ZXJ5LVNlYXQtQ2hhcnRzL2pxdWVyeS5zZWF0LWNoYXJ0cy5jc3NcIixcbiAgICB1cmxDU1NqUXVlcnlVSTogXCJodHRwczovL2NvZGUuanF1ZXJ5LmNvbS91aS8xLjEyLjEvdGhlbWVzL2Jhc2UvanF1ZXJ5LXVpLmNzc1wiLFxuICAgIGNoaWxkSGFzVmVudWVYTUw6IGZhbHNlLFxuICAgIG1heFNlbGVjdGVkU2VhdHM6IDEwLFxuICAgIHN0YXRlOiB7XG4gICAgICAgIHByaWNlT3ZlcmFsbDogXCJcIixcbiAgICAgICAgY2FydENoYW5nZWQ6IGZhbHNlLFxuICAgICAgICBzZWxlY3RlZFNlYXRzQXJyOiBbXSxcbiAgICAgICAgc2VsZWN0ZWRTZWF0c09iajoge30sXG4gICAgICAgIGxheW91dFJvd3M6IHt9LFxuICAgICAgICBpc1ZhbGlkU2VhdFNlbGVjdGlvbjogZmFsc2UsXG4gICAgICAgIGlucHV0c1dpdGhWYWx1ZTogdW5kZWZpbmVkLFxuICAgICAgICBzZWF0bWFwOiB1bmRlZmluZWQsXG4gICAgICAgIHBhbnpvb206IHVuZGVmaW5lZCxcbiAgICAgICAgaW5WZW51ZVhNTDogdW5kZWZpbmVkLFxuICAgICAgICBzZWF0bWFwWE1MOiB1bmRlZmluZWQsXG4gICAgfVxufSIsImltcG9ydCAqIGFzIENvbW11bmljYXRpb24gZnJvbSBcIi4vY29tbXVuaWNhdGlvblwiO1xuaW1wb3J0ICogYXMgVUkgZnJvbSBcIi4vdWlcIjtcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gXCIuL2NvbmZpZ1wiO1xuaW1wb3J0ICogYXMgSSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCAqIGFzIEpTQyBmcm9tIFwiLi9qc2NcIjtcbmltcG9ydCAqIGFzIENhcnQgZnJvbSBcIi4vY2FydFwiO1xuaW1wb3J0ICogYXMgTGVnZW5kIGZyb20gXCIuL2xlZ2VuZFwiO1xuaW1wb3J0ICogYXMgakJveEhlbHBlciBmcm9tIFwiLi9qQm94SGVscGVyXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDbG9zZU1vZGFsKCk6IHZvaWQge1xuICAgIGNvbnN0IGJ0bkNsb3NlTW9kYWw6IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkID0galF1ZXJ5KFwiI2J0bkNsb3NlTW9kYWxcIikuZ2V0KDApO1xuICAgIGlmIChidG5DbG9zZU1vZGFsKVxuICAgICAgICBidG5DbG9zZU1vZGFsLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoKSA9PiBDb21tdW5pY2F0aW9uLnNlbmRFdmVudFRvUGFyZW50KFwiY2hpbGRfY2xvc2VEaWFsb2dcIikpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkRHJvcGRvd25TZWF0bWFwKCk6IHZvaWQge1xuICAgIGNvbnN0IGRyb3Bkb3duU2VhdG1hcDogSFRNTEVsZW1lbnQgfCBudWxsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJkcm9wZG93blNlYXRtYXBcIik7XG5cbiAgICBpZiAoZHJvcGRvd25TZWF0bWFwKSB7XG4gICAgICAgIGRyb3Bkb3duU2VhdG1hcC5hZGRFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsIGZ1bmN0aW9uICh0aGlzOiBIVE1MU2VsZWN0RWxlbWVudCkge1xuICAgICAgICAgICAgVUkuY29udHJvbExvZnRsb2FkZXIoXCJzaG93XCIpOyAvLyB0b2RvOiByZXdyaXRlP1xuICAgICAgICAgICAgVUkuZGVzdHJveUN1cnJlbnRTZWF0bWFwKFwiI2NvbnRhaW5lclNlYXRtYXBJbm5lclwiKTtcbiAgICAgICAgICAgIENvbW11bmljYXRpb24ubmVlZFNlYXRtYXBYTUwodGhpcy52YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZE1vZGFsQ2FydCgpOiB2b2lkIHtcbiAgICBjb25zdCBidG5DYXJ0OiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCA9IGpRdWVyeShcIiNtb2RhbENhcnQgLnVhYmItYnV0dG9uXCIpLmdldCgwKTtcblxuICAgIGlmIChidG5DYXJ0KSB7XG4gICAgICAgIGJ0bkNhcnQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+IHtcbiAgICAgICAgICAgIGlmICghY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNBcnIubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGpCb3hIZWxwZXIuc2hvd0pCb3hOb3RpY2UoYFNpZSBoYWJlbiBiaXNsYW5nIGtlaW5lbiBQbGF0eiBhdXNnZXfDpGhsdC5gKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKGNvbmZpZy5zdGF0ZS5jYXJ0Q2hhbmdlZClcbiAgICAgICAgICAgICAgICBDb21tdW5pY2F0aW9uLmlzVmFsaWRTZWF0U2VsZWN0aW9uKCk7XG4gICAgICAgICAgICBlbHNlIGlmICghY29uZmlnLnN0YXRlLmNhcnRDaGFuZ2VkICYmIGNvbmZpZy5zdGF0ZS5pc1ZhbGlkU2VhdFNlbGVjdGlvbilcbiAgICAgICAgICAgICAgICBVSS5mYWRlSW5DYXJ0TW9kYWwoKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKCFjb25maWcuc3RhdGUuY2FydENoYW5nZWQgJiYgIWNvbmZpZy5zdGF0ZS5pc1ZhbGlkU2VhdFNlbGVjdGlvbilcbiAgICAgICAgICAgICAgICBqQm94SGVscGVyLnNob3dKQm94Tm90aWNlKGBBdXN3YWhsIG5pY2h0IG3DtmdsaWNoOiBCaXR0ZSBsYXNzZW4gU2llIGtlaW5lbiBlaW56ZWxuZW4gUGxhdHogZnJlaS5gKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkUmVkaXJlY3RDaGVja291dChpblVybDogc3RyaW5nIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gICAgaWYgKCFpblVybClcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgY29uc3QgYnRuQ2hlY2tvdXQgPSBqUXVlcnkoXCIjbW9kYWxDYXJ0LW92ZXJsYXkgI2NoZWNrb3V0IC5mbC1idXR0b25cIikuZ2V0KDApO1xuICAgIGlmIChidG5DaGVja291dCkge1xuICAgICAgICBidG5DaGVja291dC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZTogSS5NZXNzYWdlID0ge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IHtcbiAgICAgICAgICAgICAgICAgICAgdXJsOiBpblVybCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGZyb206IFwiY2hpbGRcIixcbiAgICAgICAgICAgICAgICBldmVudDogXCJjaGlsZF9jbGlja19jaGVja291dFwiLFxuICAgICAgICAgICAgICAgIGRhdGU6IERhdGUubm93KClcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBDb21tdW5pY2F0aW9uLnNlbmRNZXNzYWdlKG1lc3NhZ2UsIFwicGFyZW50XCIpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDYXJ0Q2xvc2UoKTogdm9pZCB7XG4gICAgY29uc3QgYnRuQ2xvc2U6IEhUTUxFbGVtZW50ID0galF1ZXJ5KFwiI21vZGFsQ2FydC1vdmVybGF5IC51YWJiLWNsb3NlLWljb25cIikuZ2V0KDApO1xuICAgIGlmIChidG5DbG9zZSlcbiAgICAgICAgYnRuQ2xvc2UuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+IENvbW11bmljYXRpb24uc2VuZEV2ZW50VG9QYXJlbnQoXCJjaGlsZF9zaG93X2RpYWxvZ190aXRsZWJhclwiKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDYXJ0QmFjaygpOiB2b2lkIHtcbiAgICBjb25zdCBidG5CYWNrOiBIVE1MRWxlbWVudCA9IGpRdWVyeShcIiNtb2RhbENhcnQtb3ZlcmxheSAjZ29CYWNrIC5mbC1idXR0b25cIikuZ2V0KDApO1xuICAgIGlmIChidG5CYWNrKVxuICAgICAgICBidG5CYWNrLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoKSA9PiBqUXVlcnkoXCIjbW9kYWxDYXJ0LW92ZXJsYXkgLnVhYmItY2xvc2UtaWNvblwiKS50cmlnZ2VyKFwiY2xpY2tcIikpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZHJvcGRvd25MZWdlbmRPbkNoYW5nZShpblNlbGVjdG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzZWF0bWFwOiBhbnkgPSBjb25maWcuc3RhdGUuc2VhdG1hcDtcbiAgICBjb25zdCBkcm9wZG93bkxlZ2VuZDogSFRNTEVsZW1lbnQgPSBqUXVlcnkoaW5TZWxlY3RvcikuZ2V0KDApO1xuXG4gICAgZHJvcGRvd25MZWdlbmQuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLCBmdW5jdGlvbiAodGhpczogSFRNTFNlbGVjdEVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgdmFsdWU6IHN0cmluZyA9IHRoaXMudmFsdWU7XG4gICAgICAgIGNvbnN0IGNsYXNzTmFtZTogc3RyaW5nID0gYC5fJHt2YWx1ZX1gO1xuXG4gICAgICAgIExlZ2VuZC5jaGFuZ2VEcm9wZG93bkxlZ2VuZEJHQ29sb3IoaW5TZWxlY3RvciwgdmFsdWUsIGNsYXNzTmFtZSk7XG5cbiAgICAgICAgaWYgKHZhbHVlID09PSBcImFsbFwiKSB7XG4gICAgICAgICAgICBzZWF0bWFwLmZpbmQoJ3VuYXZhaWxhYmxlJykuc3RhdHVzKCdhdmFpbGFibGUnKTtcbiAgICAgICAgICAgIEpTQy5zZXRVbmF2YWlsYWJsZVNlYXRzKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzZWF0bWFwLmZpbmQoJ2F2YWlsYWJsZScpLnN0YXR1cygndW5hdmFpbGFibGUnKTtcbiAgICAgICAgICAgIEpTQy5hY3RpdmF0ZVNlYXRzQnlTZWN0aW9uSUQodmFsdWUpO1xuICAgICAgICAgICAgSlNDLnNldFVuYXZhaWxhYmxlU2VhdHMoKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkQ2FydERyb3Bkb3duQnV5ZXJUeXBlcyhpblNlbGVjdG9yOiBzdHJpbmcsIGluU2VhdE9iajogSS5KU0NTZWxlY3RlZFNlYXQpOiB2b2lkIHtcbiAgICAvLyB0b2RvOiB3aGljaCB2YXJpYW50IGlzIG5vdCBkZXByZWNhdGVkP1xuICAgIGpRdWVyeShpblNlbGVjdG9yKS5vbignY2hhbmdlJywgZnVuY3Rpb24gKHRoaXM6IEhUTUxTZWxlY3RFbGVtZW50KSB7XG4gICAgICAgIENhcnQuY2hhbmdlZERyb3Bkb3duQnV5ZXJUeXBlKHRoaXMsIGluU2VhdE9iaik7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRPcGVuU2VhdG1hcCgpIHtcbiAgICBqUXVlcnkoXCIjb3BlblNlYXRtYXBcIikub24oXCJjbGlja1wiLCAoKSA9PiB7XG4gICAgICAgIGlmICghY29uZmlnLmNoaWxkSGFzVmVudWVYTUwpXG4gICAgICAgICAgICBDb21tdW5pY2F0aW9uLnNlbmRFdmVudFRvQ2hpbGQoXCJwYXJlbnRfaW5pdF92ZW51ZVwiKTtcblxuICAgICAgICBqUXVlcnkoJ2h0bWwsIGJvZHknKS5jc3MoJ292ZXJmbG93JywgJ2hpZGRlbicpO1xuICAgICAgICBqUXVlcnkoXCIjZGlhbG9nU2VhdG1hcFwiKS5kaWFsb2coJ29wZW4nKTtcbiAgICB9KTtcbn0iLCJpbXBvcnQgakJveCBmcm9tIFwiamJveFwiO1xuaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgKiBhcyBYTUxIZWxwZXIgZnJvbSBcIi4veG1saGVscGVyXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBzaG93SkJveE5vdGljZShpbkNvbnRlbnQ6IHN0cmluZywgaW5BdXRvQ2xvc2U6IG51bWJlciB8IGJvb2xlYW4gfCB1bmRlZmluZWQgPSA1MDAwKTogdm9pZCB7XG4gICAgbmV3IGpCb3g8XCJOb3RpY2VcIj4gKCdOb3RpY2UnLCB7XG4gICAgICAgIHBvc2l0aW9uOiB7IHg6ICdjZW50ZXInLCB5OiAndG9wJyB9LFxuICAgICAgICBvZmZzZXQ6IHsgeDogMCwgeTogMzIwIH0sXG4gICAgICAgIGNvbnRlbnQ6IGluQ29udGVudCxcbiAgICAgICAgYXV0b0Nsb3NlOiBpbkF1dG9DbG9zZSxcbiAgICAgICAgYW5pbWF0aW9uOiB7IG9wZW46IFwiem9vbUluXCIsIGNsb3NlOiBcInpvb21PdXRcIiB9LFxuICAgICAgICBjbG9zZU9uRXNjOiBmYWxzZSxcbiAgICAgICAgY2xvc2VCdXR0b246IHRydWUsXG4gICAgICAgIGNsb3NlT25Nb3VzZWxlYXZlOiBmYWxzZSxcbiAgICAgICAgY2xvc2VPbkNsaWNrOiBmYWxzZSxcbiAgICAgICAgZHJhZ2dhYmxlOiBmYWxzZSxcbiAgICAgICAgY29sb3I6IFwicmVkXCIsXG4gICAgICAgIHN0YWNrOiB0cnVlLFxuICAgICAgICBzaG93Q291bnRkb3duOiB0cnVlLFxuICAgICAgICByZXBvc2l0aW9uOiB0cnVlLFxuICAgICAgICByZXNwb25zaXZlV2lkdGg6IHRydWUsXG4gICAgICAgIHJlc3BvbnNpdmVIZWlnaHQ6IHRydWUsXG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTZWF0VG9vbHRpcHMoKTogdm9pZCB7XG4gICAgbmV3IGpCb3g8XCJUb29sdGlwXCI+IChcIlRvb2x0aXBcIiwge1xuICAgICAgICBhdHRhY2g6IGpRdWVyeShcIi5zZWF0Q2hhcnRzLXNlYXRcIiksXG4gICAgICAgIG9uT3BlbjogZnVuY3Rpb24gKHRoaXM6IGFueSkge1xuICAgICAgICAgICAgc2hvd1NlYXRUb29sdGlwKHRoaXMpO1xuICAgICAgICB9LFxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBzaG93U2VhdFRvb2x0aXAoakJveDogYW55KTogdm9pZCB7XG4gICAgY29uc3Qgc2VhdElEOiBzdHJpbmcgPSBqQm94LnNvdXJjZVswXS5pZDtcbiAgICBjb25zdCBzZWF0OiBzdHJpbmcgPSBjb25maWcuc3RhdGUubGF5b3V0Um93c1tzZWF0SURdWzVdO1xuICAgIGNvbnN0IHJvdzogc3RyaW5nID0gY29uZmlnLnN0YXRlLmxheW91dFJvd3Nbc2VhdElEXVs0XTtcbiAgICBjb25zdCBzZWN0aW9uSUQ6IHN0cmluZyA9IGNvbmZpZy5zdGF0ZS5sYXlvdXRSb3dzW3NlYXRJRF1bM107XG4gICAgY29uc3Qgc2VjdGlvbkRlc2M6IHN0cmluZyB8IHVuZGVmaW5lZCA9IFhNTEhlbHBlci5nZXRTZWN0aW9uRGVzY0J5U2VjdGlvbklEKHNlY3Rpb25JRCk7XG4gICAgY29uc3QgdG9vbHRpcENvbnRlbnQ6IHN0cmluZyA9IGAke3NlY3Rpb25EZXNjfTxici8+UmVpaGUgJHtyb3d9IFBsYXR6ICR7c2VhdH1gO1xuXG4gICAgakJveC5zZXRDb250ZW50KHRvb2x0aXBDb250ZW50KTtcbn0iLCJpbXBvcnQgKiBhcyBJIGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgKiBhcyBTdGF0ZSBmcm9tIFwiLi9zdGF0ZVwiO1xuaW1wb3J0ICogYXMgQ2FydCBmcm9tIFwiLi9jYXJ0XCI7XG5pbXBvcnQgKiBhcyBDYXJ0QnV0dG9ucyBmcm9tIFwiLi9jYXJ0QnV0dG9uc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VhdHMoKTogSS5KU0NTZWF0cyB7XG4gICAgY29uc3Qgc2VhdG1hcFhNTDogYW55ID0gY29uZmlnLnN0YXRlLnNlYXRtYXBYTUw7XG4gICAgY29uc3QgcHJpY2VzY2FsZUFycjogSS5TZWF0bWFwUHJpY2VzY2FsZVtdID0gc2VhdG1hcFhNTC5zZWF0bWFwWzBdLnByaWNlc2NhbGVfY29uZmlnWzBdLnByaWNlc2NhbGU7XG4gICAgbGV0IHNlYXRtYXBJbml0U2VhdHM6IEkuSlNDU2VhdHMgPSB7fTtcblxuICAgIGZvciAobGV0IGtleSBpbiBwcmljZXNjYWxlQXJyKSB7XG4gICAgICAgIGNvbnN0IHNlYXRzT2JqOiBJLkpTQ1NlYXRzMiA9IHtcbiAgICAgICAgICAgIFwiY2xhc3Nlc1wiOiBgXyR7cHJpY2VzY2FsZUFycltrZXldLmlkWzBdfWAsXG4gICAgICAgICAgICBcInNlYXRzT2JqXCI6IHByaWNlc2NhbGVBcnJba2V5XVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNlYXRzS2V5OiBzdHJpbmcgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDk3ICsgcGFyc2VJbnQoa2V5KSkudG9Mb2NhbGVVcHBlckNhc2UoKTtcbiAgICAgICAgc2VhdG1hcEluaXRTZWF0c1tzZWF0c0tleV0gPSBzZWF0c09iajtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VhdG1hcEluaXRTZWF0cztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFjdGl2YXRlU2VhdHNCeVNlY3Rpb25JRChpblZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzZWF0bWFwWE1MOiBhbnkgPSBjb25maWcuc3RhdGUuc2VhdG1hcFhNTDtcbiAgICBjb25zdCBzZWF0bWFwOiBhbnkgPSBjb25maWcuc3RhdGUuc2VhdG1hcDtcbiAgICBjb25zdCBwcmljZXNjYWxlQXJyOiBJLlNlYXRtYXBQcmljZXNjYWxlW10gPSBzZWF0bWFwWE1MLnNlYXRtYXBbMF0ucHJpY2VzY2FsZV9jb25maWdbMF0ucHJpY2VzY2FsZTtcblxuICAgIGNvbnN0IHNlYXRzQXJyOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCA9IHByaWNlc2NhbGVBcnIuZmluZChhcnIgPT4ge1xuICAgICAgICByZXR1cm4gYXJyLmlkWzBdID09PSBpblZhbHVlO1xuICAgIH0pPy5tYXNrWzBdLnNwbGl0KFwiLFwiKTtcblxuICAgIHNlYXRtYXAuc3RhdHVzKHNlYXRzQXJyLCBcImF2YWlsYWJsZVwiKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvd3NOYW1pbmcoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHNlYXRtYXBYTUw6IGFueSA9IGNvbmZpZy5zdGF0ZS5zZWF0bWFwWE1MO1xuICAgIGNvbnN0IGxheW91dDogSS5TZWF0bWFwTGF5b3V0ID0gc2VhdG1hcFhNTC5zZWF0bWFwWzBdLmxheW91dHNbMF0ubGF5b3V0WzBdO1xuICAgIGNvbnN0IGhlaWdodDogbnVtYmVyID0gcGFyc2VJbnQobGF5b3V0LmhlaWdodFswXSk7XG4gICAgY29uc3QgbmFtaW5nQXJyOiBzdHJpbmdbXSA9IEFycmF5LmZyb20oeyBsZW5ndGg6IGhlaWdodCB9LCAoXykgPT4gXCJcIik7XG4gICAgY29uc3Qgcm93c0FycjogSS5MYXlvdXRSb3cyW10gPSBsYXlvdXQucm93c1swXS5yb3c7XG5cbiAgICByb3dzQXJyLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICAgIGNvbnN0IGluZGV4OiBudW1iZXIgPSBwYXJzZUludChlbGVtZW50LnlfY2VsbF9jb29yZFswXSk7XG4gICAgICAgIGNvbnN0IHNlYXRzQXJyOiBzdHJpbmdbXSA9IGVsZW1lbnQuc2VhdHNbMF0uc3BsaXQoXCJ8XCIpO1xuICAgICAgICBjb25zdCBzZWF0QXJyOiBzdHJpbmdbXSA9IHNwbGl0U2VhdFN0cihzZWF0c0FyclswXSk7XG4gICAgICAgIGNvbnN0IHJvdzogc3RyaW5nID0gc2VhdEFycls0XTtcbiAgICAgICAgbmFtaW5nQXJyW2luZGV4XSA9IHJvdztcbiAgICB9KTtcblxuICAgIHJldHVybiBuYW1pbmdBcnI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZU1hcCgpOiBzdHJpbmdbXSB7XG4gICAgY29uc3Qgc2VhdG1hcFhNTDogYW55ID0gY29uZmlnLnN0YXRlLnNlYXRtYXBYTUw7XG4gICAgY29uc3QgbGF5b3V0OiBJLlNlYXRtYXBMYXlvdXQgPSBzZWF0bWFwWE1MLnNlYXRtYXBbMF0ubGF5b3V0c1swXS5sYXlvdXRbMF07XG4gICAgY29uc3Qgcm93czogSS5MYXlvdXRSb3cyW10gPSBsYXlvdXQucm93c1swXS5yb3c7XG4gICAgY29uc3QgcHJpY2VzY2FsZUFycjogSS5TZWF0bWFwUHJpY2VzY2FsZVtdID0gc2VhdG1hcFhNTC5zZWF0bWFwWzBdLnByaWNlc2NhbGVfY29uZmlnWzBdLnByaWNlc2NhbGU7XG4gICAgY29uc3QgYXZhaWxhYmlsaXR5QXJyOiBJLkpTQ0F2YWlsYWJpbGl0eSA9IHNlYXRtYXBYTUwuc2VhdG1hcFswXS52aWV3X21vZGVzWzBdLnZpZXdfbW9kZVswXS5hdmFpbGFiaWxpdHlbMF07XG5cbiAgICAvLyBGb3JtOiBhcnJNYXRyaXhbWV1bWF1cbiAgICBsZXQgYXJyTWF0cml4OiBzdHJpbmdbXVtdID0gY3JlYXRlQXJyTWF0cml4KFxuICAgICAgICBwYXJzZUludChsYXlvdXQuaGVpZ2h0WzBdKSxcbiAgICAgICAgcGFyc2VJbnQobGF5b3V0LndpZHRoWzBdKSxcbiAgICAgICAgXCJfXCJcbiAgICApO1xuXG4gICAgYXJyTWF0cml4ID0gZW50ZXJTZWF0c0luTWF0cml4KHJvd3MsIGFyck1hdHJpeCwgcHJpY2VzY2FsZUFyciwgYXZhaWxhYmlsaXR5QXJyKTtcbiAgICByZXR1cm4gYXJyTWF0cml4Lm1hcChlbGVtZW50ID0+IGVsZW1lbnQuam9pbihcIlwiKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUxlZ2VuZChpbk5vZGU6IHN0cmluZyk6IEkuSlNDTGVnZW5kIHtcbiAgICBjb25zdCBzZWF0bWFwWE1MOiBhbnkgPSBjb25maWcuc3RhdGUuc2VhdG1hcFhNTDtcbiAgICBjb25zdCB2ZW51ZVhNTDogSS5WZW51ZVhNTCA9IGNvbmZpZy5zdGF0ZS5pblZlbnVlWE1MITtcbiAgICBjb25zdCBwcmljZXNjYWxlQXJyOiBJLlNlYXRtYXBQcmljZXNjYWxlW10gPSBzZWF0bWFwWE1MLnNlYXRtYXBbMF0ucHJpY2VzY2FsZV9jb25maWdbMF0ucHJpY2VzY2FsZTtcbiAgICBjb25zdCB2ZW51ZVByaWNlc2NhbGVBcnI6IEkuUHJpY2VzY2FsZTJbXSA9IHZlbnVlWE1MLnZlbnVlWzBdLnByaWNlc2NhbGVzWzBdLnByaWNlc2NhbGU7XG5cbiAgICByZXR1cm4gPEkuSlNDTGVnZW5kPntcbiAgICAgICAgbm9kZTogalF1ZXJ5KGluTm9kZSksXG4gICAgICAgIGl0ZW1zOiBjcmVhdGVMZWdlbmRJdGVtcyhwcmljZXNjYWxlQXJyLCB2ZW51ZVByaWNlc2NhbGVBcnIpXG4gICAgfVxufVxuXG5cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFVuYXZhaWxhYmxlU2VhdHMoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VhdG1hcFhNTDogYW55ID0gY29uZmlnLnN0YXRlLnNlYXRtYXBYTUw7XG4gICAgY29uc3Qgc2VhdG1hcDogYW55ID0gY29uZmlnLnN0YXRlLnNlYXRtYXA7XG4gICAgY29uc3QgYXZhaWxhYmlsaXR5QXJyOiBJLkpTQ0F2YWlsYWJpbGl0eSA9IHNlYXRtYXBYTUwuc2VhdG1hcFswXS52aWV3X21vZGVzWzBdLnZpZXdfbW9kZVswXS5hdmFpbGFiaWxpdHlbMF07XG5cbiAgICBpZiAoYXZhaWxhYmlsaXR5QXJyLnVuYXZhaWxhYmxlX3Vuc2VsZWN0YWJsZV9tYXNrWzBdICE9PSBcIlwiKSB7XG4gICAgICAgIGNvbnN0IHVuYXZhaWxhYmxlQXJyOiBzdHJpbmdbXSA9IGF2YWlsYWJpbGl0eUFyci51bmF2YWlsYWJsZV91bnNlbGVjdGFibGVfbWFza1swXS5zcGxpdChcIixcIik7XG4gICAgICAgIHNlYXRtYXAuc3RhdHVzKHVuYXZhaWxhYmxlQXJyLCBcInVuYXZhaWxhYmxlXCIpO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNlYXRzS2V5KGluU2VhdElEOiBzdHJpbmcsIGluUHJpY2VzY2FsZUFycjogSS5TZWF0bWFwUHJpY2VzY2FsZVtdKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBmb3IgKGxldCBrZXkgaW4gaW5QcmljZXNjYWxlQXJyKSB7XG4gICAgICAgIGlmIChpblByaWNlc2NhbGVBcnJba2V5XS5tYXNrWzBdLmluY2x1ZGVzKGluU2VhdElEKSlcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDk3ICsgcGFyc2VJbnQoa2V5KSkudG9Mb2NhbGVVcHBlckNhc2UoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3BsaXRTZWF0U3RyKGluU2VhdFN0cjogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBpblNlYXRTdHIuc3BsaXQoXCIsXCIpLm1hcCgoaXRlbSkgPT4gaXRlbS50cmltKCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXJyTWF0cml4KGluTnVtcm93czogbnVtYmVyLCBpbk51bWNvbHM6IG51bWJlciwgaW5DaGFyYWN0ZXI6IHN0cmluZyk6IHN0cmluZ1tdW10ge1xuICAgIHJldHVybiBBcnJheShpbk51bXJvd3MpLmZpbGwobnVsbCkubWFwKCgpID0+IEFycmF5KGluTnVtY29scykuZmlsbChpbkNoYXJhY3RlcikpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2VsZWN0U2VhdHNJbkNhcnQoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VhdG1hcDogYW55ID0gY29uZmlnLnN0YXRlLnNlYXRtYXA7XG4gICAgY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNBcnIuZm9yRWFjaChhcnIgPT4ge1xuICAgICAgICBjb25zdCBzZWF0SUQ6IHN0cmluZyA9IGFyclswXTtcblxuICAgICAgICBpZiAoc2VhdG1hcC5nZXQoc2VhdElEKSlcbiAgICAgICAgICAgIHNlYXRtYXAuc3RhdHVzKHNlYXRJRCwgXCJzZWxlY3RlZFwiKTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFNlYXRtYXAoaW5TZWxlY3Rvcjogc3RyaW5nLCBpbk1hcDogc3RyaW5nW10sIGluUm93c05hbWluZzogc3RyaW5nW10sIGluU2VhdHM6IEkuSlNDU2VhdHMsIGluTGVnZW5kOiBJLkpTQ0xlZ2VuZCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbnRhaW5lclNlYXRtYXA6IGFueSA9ICg8YW55PndpbmRvdykualF1ZXJ5KGluU2VsZWN0b3IpO1xuXG4gICAgLy8gY29uc29sZS5sb2coaW5TZWF0bWFwSW5pdE1hcCk7XG4gICAgLy8gY29uc29sZS5sb2coaW5TZWF0cyk7XG4gICAgLy8gY29uc29sZS5sb2coaW5MZWdlbmQpO1xuXG4gICAgY29uZmlnLnN0YXRlLnNlYXRtYXAgPSBjb250YWluZXJTZWF0bWFwLnNlYXRDaGFydHMoe1xuICAgICAgICBuYW1pbmc6IHtcbiAgICAgICAgICAgIHRvcDogZmFsc2UsXG4gICAgICAgICAgICBsZWZ0OiBmYWxzZSxcbiAgICAgICAgICAgIHJvd3M6IGluUm93c05hbWluZyxcbiAgICAgICAgfSxcbiAgICAgICAgbWFwOiBpbk1hcCxcbiAgICAgICAgc2VhdHM6IGluU2VhdHMsXG4gICAgICAgIGxlZ2VuZDogaW5MZWdlbmQsXG4gICAgICAgIGNsaWNrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gY2xpY2tlZFNlYXQodGhpcyk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlTGVnZW5kSXRlbXMocHJpY2VzY2FsZUFycjogSS5TZWF0bWFwUHJpY2VzY2FsZVtdLCB2ZW51ZVByaWNlc2NhbGVBcnI6IEkuUHJpY2VzY2FsZTJbXSk6IHN0cmluZ1tdW10ge1xuICAgIHJldHVybiBwcmljZXNjYWxlQXJyLm1hcCgoYXJyLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IGlkOiBzdHJpbmcgPSBhcnIuaWRbMF07XG4gICAgICAgIGNvbnN0IHNlYXRzS2V5OiBzdHJpbmcgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDk3ICsgaW5kZXgpLnRvTG9jYWxlVXBwZXJDYXNlKCk7XG4gICAgICAgIGNvbnN0IGRlc2M6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHZlbnVlUHJpY2VzY2FsZUFyci5maW5kKG9iaiA9PiBvYmouaWRbMF0gPT09IGlkKT8uZGVzY1swXTtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRpb246IHN0cmluZyA9IGAke2Rlc2N9IOKCrCR7cHJpY2VzY2FsZUFycltpbmRleF0ucmVmX3ByaWNlWzBdfWA7XG4gICAgICAgIHJldHVybiBbc2VhdHNLZXksIFwiYXZhaWxhYmxlXCIsIGRlc2NyaXB0aW9uXTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gZW50ZXJTZWF0c0luTWF0cml4KGluUm93czogSS5MYXlvdXRSb3cyW10sIGluQXJyTWF0cml4OiBzdHJpbmdbXVtdLCBpblByaWNlc2NhbGVBcnI6IEkuU2VhdG1hcFByaWNlc2NhbGVbXSwgaW5BdmFpbGFiaWxpdHlBcnI6IEkuSlNDQXZhaWxhYmlsaXR5KTogc3RyaW5nW11bXSB7XG4gICAgY29uc3QgYXZhaWxhYmxlQXJyOiBzdHJpbmdbXSA9IGluQXZhaWxhYmlsaXR5QXJyLmF2YWlsYWJsZV9zZWxlY3RhYmxlX21hc2tbMF0uc3BsaXQoXCIsXCIpO1xuICAgIGNvbnN0IHVuYXZhaWxhYmxlQXJyOiBzdHJpbmdbXSA9IGluQXZhaWxhYmlsaXR5QXJyLnVuYXZhaWxhYmxlX3Vuc2VsZWN0YWJsZV9tYXNrWzBdLnNwbGl0KFwiLFwiKTtcblxuICAgIGluUm93cy5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgICBjb25zdCByb3c6IEkuTGF5b3V0Um93MiA9IGVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IFk6IG51bWJlciA9IHBhcnNlSW50KHJvdy55X2NlbGxfY29vcmRbMF0pIC0gMTtcbiAgICAgICAgY29uc3Qgc2VhdHNBcnI6IHN0cmluZ1tdID0gcm93LnNlYXRzWzBdLnNwbGl0KFwifFwiKTtcblxuICAgICAgICBzZWF0c0Fyci5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc2VhdFN0cjogc3RyaW5nID0gZWxlbWVudDtcbiAgICAgICAgICAgIC8vIEZvcm06XG4gICAgICAgICAgICAvLyBcIjU2ODQyMCw1Njg0MjAsMTUsNzAyNCwxMyAsMVwiXG5cbiAgICAgICAgICAgIGNvbnN0IHNlYXRBcnI6IHN0cmluZ1tdID0gc3BsaXRTZWF0U3RyKHNlYXRTdHIpO1xuICAgICAgICAgICAgLy8gRm9ybTpcbiAgICAgICAgICAgIC8vIDA6IFwiNTY4NTI4XCIgLT4gSURcbiAgICAgICAgICAgIC8vIDE6IFwiNTY4NTI4XCIgLT4gSURcbiAgICAgICAgICAgIC8vIDI6IFwiMjFcIiAtPiBYLUNvb3JkIGJlbnV0emVuXG4gICAgICAgICAgICAvLyAzOiBcIjcwMjRcIiAtPiBzZWN0aW9uIElEXG4gICAgICAgICAgICAvLyA0OiBcIjEzXCIgLT4gUmVpaGVuYmV6ZWljaG51bmdcbiAgICAgICAgICAgIC8vIDU6IFwiNFwiIC0+IFBsYXR6bnVtbWVyXG5cbiAgICAgICAgICAgIC8vIHNraXAgYmxhY2tlZCBvdXQgc2VhdHMgICAgICAgICAgICBcbiAgICAgICAgICAgIGlmICghYXZhaWxhYmxlQXJyLmluY2x1ZGVzKHNlYXRBcnJbMF0pICYmICF1bmF2YWlsYWJsZUFyci5pbmNsdWRlcyhzZWF0QXJyWzBdKSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgICAgIC8vIGNvbnN0IFg6IG51bWJlciA9IHBhcnNlSW50KHNlYXRBcnJbNV0pO1xuICAgICAgICAgICAgY29uc3QgWDogbnVtYmVyID0gcGFyc2VJbnQoc2VhdEFyclsyXSkgLSAxO1xuICAgICAgICAgICAgY29uc3Qgc2VhdHNLZXk6IHN0cmluZyB8IHVuZGVmaW5lZCA9IGdldFNlYXRzS2V5KHNlYXRBcnJbMF0sIGluUHJpY2VzY2FsZUFycik7XG5cbiAgICAgICAgICAgIGlmIChzZWF0c0tleSlcbiAgICAgICAgICAgICAgICBpbkFyck1hdHJpeFtZXVtYXSA9IGAke3NlYXRzS2V5fVske3NlYXRBcnJbMF19LCBdYDtcblxuXG4gICAgICAgICAgICAvLyBzYXZlIHNlYXRBcnIgaW4gc3RhdGUgd2l0aCBzZWF0SUQgYXMga2V5XG4gICAgICAgICAgICBjb25maWcuc3RhdGUubGF5b3V0Um93c1tzZWF0QXJyWzBdXSA9IHNlYXRBcnI7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGluQXJyTWF0cml4O1xufVxuXG5mdW5jdGlvbiBjbGlja2VkU2VhdChpblNlYXRtYXA6IGFueSkge1xuICAgIGlmIChpblNlYXRtYXAuc3RhdHVzKCkgPT0gJ2F2YWlsYWJsZScpIHtcbiAgICAgICAgcmV0dXJuIGNsaWNrQXZhaWxhYmxlU2VhdChpblNlYXRtYXApO1xuICAgIH1cbiAgICBlbHNlIGlmIChpblNlYXRtYXAuc3RhdHVzKCkgPT09IFwic2VsZWN0ZWRcIikge1xuICAgICAgICByZXR1cm4gY2xpY2tlZFNlbGVjdGVkU2VhdChpblNlYXRtYXApO1xuICAgIH1cbiAgICBlbHNlIGlmIChpblNlYXRtYXAuc3RhdHVzKCkgPT0gJ3VuYXZhaWxhYmxlJykge1xuICAgICAgICByZXR1cm4gXCJ1bmF2YWlsYWJsZVwiO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGluU2VhdG1hcC5zdHlsZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY2xpY2tBdmFpbGFibGVTZWF0KGluU2VhdG1hcDogYW55KSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRTZWF0OiBJLkpTQ1NlbGVjdGVkU2VhdCA9IGluU2VhdG1hcC5zZXR0aW5ncztcbiAgICBjb25zb2xlLmxvZyhzZWxlY3RlZFNlYXQpO1xuXG4gICAgaWYgKFN0YXRlLm1heGltdW1TZWxlY3RlZFNlYXRzUmVhY2hlZChzZWxlY3RlZFNlYXQpKVxuICAgICAgICByZXR1cm4gXCJhdmFpbGFibGVcIjtcblxuICAgIFN0YXRlLmFkZFNlYXRUb1N0YXRlKHNlbGVjdGVkU2VhdCk7XG4gICAgQ2FydC5jYWxjT3ZlcmFsbFByaWNlKCk7XG4gICAgQ2FydEJ1dHRvbnMuc2V0QnRuQ2FydFRleHQoKTtcblxuICAgIHJldHVybiBcInNlbGVjdGVkXCI7XG59XG5cbmZ1bmN0aW9uIGNsaWNrZWRTZWxlY3RlZFNlYXQoaW5TZWF0bWFwOiBhbnkpIHtcbiAgICBjb25zdCBzZWxlY3RlZFNlYXQ6IEkuSlNDU2VsZWN0ZWRTZWF0ID0gaW5TZWF0bWFwLnNldHRpbmdzO1xuICAgIFN0YXRlLnJlbW92ZVNlYXRGcm9tU3RhdGUoc2VsZWN0ZWRTZWF0KTtcbiAgICBDYXJ0LmNhbGNPdmVyYWxsUHJpY2UoKTtcbiAgICBDYXJ0QnV0dG9ucy5zZXRCdG5DYXJ0VGV4dCgpO1xuXG4gICAgcmV0dXJuIFwiYXZhaWxhYmxlXCI7XG59IiwiZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRMZWdlbmRUb0Ryb3Bkb3duKGluSUQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGpRdWVyeSgndWwuc2VhdENoYXJ0cy1sZWdlbmRMaXN0JykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBzZWxlY3Q6IEpRdWVyeTxIVE1MU2VsZWN0RWxlbWVudD4gPSBqUXVlcnkoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2VsZWN0JykpXG4gICAgICAgICAgICAuaW5zZXJ0QmVmb3JlKFxuICAgICAgICAgICAgICAgIGpRdWVyeSh0aGlzKS5oaWRlKClcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgc2VsZWN0LmF0dHIoeyBpZDogaW5JRCB9KTtcbiAgICAgICAgYXBwZW5kRmlyc3RMZWdlbmRPcHRpb24oc2VsZWN0KTtcbiAgICAgICAgYXBwZW5kTGVnZW5kT3B0aW9ucyh0aGlzLCBzZWxlY3QpOyAgICAgICAgXG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGFwcGVuZExlZ2VuZE9wdGlvbnMoZWxlbWVudDogSFRNTEVsZW1lbnQsIGluU2VsZWN0OiBKUXVlcnk8SFRNTFNlbGVjdEVsZW1lbnQ+KSB7XG4gICAgalF1ZXJ5KCc+bGknLCBlbGVtZW50KS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY2xhc3NOYW1lOiBzdHJpbmcgPSBqUXVlcnkodGhpcylbMF0uY2hpbGRyZW5bMF0uY2xhc3NMaXN0WzNdO1xuICAgICAgICBjb25zdCB2YWw6IHN0cmluZyA9IGNsYXNzTmFtZS5zdWJzdHJpbmcoMSk7XG4gICAgICAgIGNvbnN0IHRleHQ6IHN0cmluZyA9ICg8SFRNTEVsZW1lbnQ+alF1ZXJ5KHRoaXMpWzBdLmNoaWxkcmVuWzFdKS5pbm5lclRleHQ7XG5cbiAgICAgICAgYXBwZW5kTGVnZW5kT3B0aW9uKGluU2VsZWN0LCBjbGFzc05hbWUsIHZhbCwgdGV4dCk7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGFwcGVuZExlZ2VuZE9wdGlvbihpblNlbGVjdDogSlF1ZXJ5PEhUTUxTZWxlY3RFbGVtZW50PiwgY2xhc3NOYW1lOiBzdHJpbmcsIHZhbDogc3RyaW5nLCB0ZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBsZXQgb3B0aW9uOiBKUXVlcnk8SFRNTE9wdGlvbkVsZW1lbnQ+ID0galF1ZXJ5KCc8b3B0aW9uLz4nKTtcbiAgICBvcHRpb24uYXR0cih7ICd2YWx1ZSc6IHZhbCwgJ2NsYXNzJzogY2xhc3NOYW1lIH0pLnRleHQodGV4dCk7XG4gICAgaW5TZWxlY3QuYXBwZW5kKG9wdGlvbik7XG59XG5cbmZ1bmN0aW9uIGFwcGVuZEZpcnN0TGVnZW5kT3B0aW9uKGluU2VsZWN0OiBKUXVlcnk8SFRNTFNlbGVjdEVsZW1lbnQ+KTogdm9pZCB7XG4gICAgbGV0IG9wdGlvbjogSlF1ZXJ5PEhUTUxPcHRpb25FbGVtZW50PiA9IGpRdWVyeSgnPG9wdGlvbi8+Jyk7XG4gICAgb3B0aW9uLmF0dHIoeyAndmFsdWUnOiAnYWxsJyB9KS50ZXh0KCdBbGxlIFByZWlza2F0ZWdvcmllbicpO1xuICAgIG9wdGlvbi5jc3MoXCJjb2xvclwiLCBcIiM1YzVjNWNcIik7XG4gICAgaW5TZWxlY3QuYXBwZW5kKG9wdGlvbik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjaGFuZ2VEcm9wZG93bkxlZ2VuZEJHQ29sb3IoaW5TZWxlY3Rvcjogc3RyaW5nLCBpblZhbHVlOiBzdHJpbmcsIGluQ2xhc3NOYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBsZXQgYmdDb2xvcjogc3RyaW5nID0gXCIjZmFmYWZhXCI7XG4gICAgbGV0IGNvbG9yOiBzdHJpbmcgPSBcIiM1YzVjNWNcIjtcblxuICAgIGlmIChpblZhbHVlICE9PSBcImFsbFwiKSB7XG4gICAgICAgIGNvbG9yID0gXCJ3aGl0ZVwiO1xuICAgICAgICBiZ0NvbG9yID0galF1ZXJ5KGluQ2xhc3NOYW1lKS5jc3MoXCJiYWNrZ3JvdW5kLWNvbG9yXCIpO1xuICAgIH1cblxuICAgIGpRdWVyeShpblNlbGVjdG9yKS5jc3MoXCJjb2xvclwiLCBjb2xvcik7XG4gICAgalF1ZXJ5KGluU2VsZWN0b3IpLmNzcyhcImJhY2tncm91bmQtY29sb3JcIiwgYmdDb2xvcik7XG4gICAgalF1ZXJ5KGAke2luU2VsZWN0b3J9IG9wdGlvblt2YWx1ZT1cImFsbFwiXWApLmNzcyhcImNvbG9yXCIsIGNvbG9yKTtcbn0iLCJpbXBvcnQgUGFuem9vbSBmcm9tICdAcGFuem9vbS9wYW56b29tJztcbmltcG9ydCB7IFBhbnpvb21PYmplY3QgfSBmcm9tIFwiQHBhbnpvb20vcGFuem9vbS9kaXN0L3NyYy90eXBlc1wiO1xuaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRQYW56b29tKGluU2VsZWN0b3I6IHN0cmluZywgaW5CdG5ab29tSW46IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZCwgaW5CdG5ab29tT3V0OiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsIGluQnRuUmVzZXRab29tOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQpOiBQYW56b29tT2JqZWN0IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBjb250YWluZXI6IEhUTUxFbGVtZW50ID0galF1ZXJ5KGluU2VsZWN0b3IpLmdldCgwKTtcblxuICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgICAgY29uc3QgcGFuem9vbTogUGFuem9vbU9iamVjdCA9IFBhbnpvb20oY29udGFpbmVyLCB7XG4gICAgICAgICAgICBtYXhTY2FsZTogNSxcbiAgICAgICAgICAgIGFuaW1hdGU6IGZhbHNlLFxuICAgICAgICAgICAgb3ZlcmZsb3c6IFwiaGlkZGVuXCIsXG4gICAgICAgICAgICBzdGFydFNjYWxlOiBcIjAuNjZcIlxuICAgICAgICB9KTtcblxuICAgICAgICBhZGRQYW56b29tRXZlbnRzKGluQnRuWm9vbUluLCBpbkJ0blpvb21PdXQsIGluQnRuUmVzZXRab29tLCBjb250YWluZXIucGFyZW50RWxlbWVudCEsIHBhbnpvb20pO1xuICAgICAgICByZXR1cm4gcGFuem9vbTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBhZGRQYW56b29tRXZlbnRzKGluQnRuWm9vbUluOiBzdHJpbmcgfCB1bmRlZmluZWQsIGluQnRuWm9vbU91dDogc3RyaW5nIHwgdW5kZWZpbmVkLCBpbkJ0blJlc2V0Wm9vbTogc3RyaW5nIHwgdW5kZWZpbmVkLCBjb250YWluZXJQYXJlbnQ6IEhUTUxFbGVtZW50LCBwYW56b29tOiBQYW56b29tT2JqZWN0KTogdm9pZCB7XG4gICAgY29uc3QgZXZlbnRNYXBwaW5nID0gW1xuICAgICAgICB7IFNlbGVjdG9yOiBpbkJ0blpvb21JbiwgUGFuem9vbUZ1bmN0aW9uOiBwYW56b29tLnpvb21JbiwgVHlwZTogXCJDbGlja1wiIH0sXG4gICAgICAgIHsgU2VsZWN0b3I6IGluQnRuWm9vbU91dCwgUGFuem9vbUZ1bmN0aW9uOiBwYW56b29tLnpvb21PdXQsIFR5cGU6IFwiQ2xpY2tcIiB9LFxuICAgICAgICB7IFNlbGVjdG9yOiBpbkJ0blJlc2V0Wm9vbSwgUGFuem9vbUZ1bmN0aW9uOiBwYW56b29tLnJlc2V0LCBUeXBlOiBcIkNsaWNrXCIgfSxcbiAgICAgICAgeyBIVE1MRWxlbWVudDogY29udGFpbmVyUGFyZW50LCBQYW56b29tRnVuY3Rpb246IHBhbnpvb20uem9vbVdpdGhXaGVlbCwgVHlwZTogXCJ3aGVlbFwiIH1cbiAgICBdO1xuXG4gICAgZXZlbnRNYXBwaW5nLm1hcChldmVudCA9PiB7XG4gICAgICAgIGlmIChldmVudC5TZWxlY3Rvcikge1xuICAgICAgICAgICAgY29uc3QgYnRuOiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCA9IGpRdWVyeShldmVudC5TZWxlY3RvcikuZ2V0KDApO1xuICAgICAgICAgICAgaWYgKGJ0bilcbiAgICAgICAgICAgICAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcihldmVudC5UeXBlLCBldmVudC5QYW56b29tRnVuY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2ZW50LkhUTUxFbGVtZW50KSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuVHlwZSA9PT0gXCJ3aGVlbFwiKVxuICAgICAgICAgICAgICAgIGV2ZW50LkhUTUxFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQuVHlwZSwgZXZlbnQuUGFuem9vbUZ1bmN0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1bmJpbmRQYW56b29tRXZlbnRzKGluU2VsZWN0b3I6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGNvbnRhaW5lcjogSFRNTEVsZW1lbnQgPSBqUXVlcnkoaW5TZWxlY3RvcikuZ2V0KDApO1xuICAgIGNvbnRhaW5lci5wYXJlbnRFbGVtZW50Py5yZW1vdmVFdmVudExpc3RlbmVyKCd3aGVlbCcsIGNvbmZpZy5zdGF0ZS5wYW56b29tIS56b29tV2l0aFdoZWVsKTtcbn0iLCJpbXBvcnQgKiBhcyBJIGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcIi4vY29uZmlnXCI7XG52YXIgalF1ZXJ5ID0gcmVxdWlyZShcImpxdWVyeVwiKTtcbmltcG9ydCBVdGlscyBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZlbnVlTG9jYXRpb24oKTogc3RyaW5nIHtcbiAgICBsZXQgc3BhbkFycjogc3RyaW5nW10gPSBbXTtcbiAgICBqUXVlcnkoXCIudmVudWUgc3BhblwiKS5lYWNoKGZ1bmN0aW9uICh0aGlzOiBhbnkpIHtcbiAgICAgICAgc3BhbkFyci5wdXNoKGpRdWVyeSh0aGlzKS50ZXh0KCkpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHNwYW5BcnIuam9pbihcIiwgXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW5wdXRzKGluQ29udGVudDogc3RyaW5nKTogSS5JbnB1dHMgIHtcbiAgICBjb25zdCBwYXJzZWRIVE1MOiBOb2RlW10gPSBqUXVlcnkucGFyc2VIVE1MKGluQ29udGVudCk7XG4gICAgbGV0IGlucHV0czogSS5JbnB1dHMgPSB7fTtcblxuICAgIGpRdWVyeShwYXJzZWRIVE1MKS5maW5kKCdpbnB1dCcpLmVhY2goZnVuY3Rpb24gKHRoaXM6IGFueSkge1xuICAgICAgICBjb25zdCBuYW1lOiBzdHJpbmcgPSB0aGlzLm5hbWU7XG4gICAgICAgIGNvbnN0IHZhbHVlOiBzdHJpbmcgPSB0aGlzLnZhbHVlO1xuXG4gICAgICAgIGlmICh2YWx1ZSAhPT0gJycpXG4gICAgICAgICAgICBpbnB1dHNbbmFtZV0gPSB2YWx1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiBpbnB1dHM7XG59XG5cbi8vIHRvZG86IGNoZWNrIHdpdGggZGlmZmVyZW50IHZlbnVlc1xuZXhwb3J0IGZ1bmN0aW9uIGdldEltcG9ydGFudE5vdGUoKTogSS5JbXBvcnRhbnROb3RlIHwgdW5kZWZpbmVkICB7XG4gICAgaWYgKGpRdWVyeShcIi5pbXBvcnRhbnRfbm90ZVwiKS5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgaW1wb3J0YW50Tm90ZTogc3RyaW5nIHwgbnVsbCA9IGpRdWVyeShcIi5pbXBvcnRhbnRfbm90ZVwiKVswXS50ZXh0Q29udGVudDtcblxuICAgICAgICBpZiAoaW1wb3J0YW50Tm90ZT8udHJpbSgpLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgaW1wb3J0YW50Tm90ZUVuY29kZWQ6IHN0cmluZyA9IGVuY29kZVVSSUNvbXBvbmVudChpbXBvcnRhbnROb3RlKTtcbiAgICAgICAgICAgIHJldHVybiA8SS5JbXBvcnRhbnROb3RlPiB7XG4gICAgICAgICAgICAgICAgXCJpbXBvcnRhbnROb3RlXCI6IGltcG9ydGFudE5vdGUsXG4gICAgICAgICAgICAgICAgXCJpbXBvcnRhbnROb3RlRW5jb2RlZFwiOiBpbXBvcnRhbnROb3RlRW5jb2RlZFxuICAgICAgICAgICAgfSAgICAgICAgXG4gICAgICAgIH1cbiAgICB9ICAgXG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWRkaXRpb25hbElucHV0cyhpbkNvbnRlbnQ6IHN0cmluZyk6IEkuSW5wdXRzIHtcbiAgICBjb25zdCBldmVudCA9IGluQ29udGVudC5tYXRjaCgvZXZlbnQ6XCIoLis/KVwiLykhWzFdO1xuICAgIGNvbnN0IGhvbGRjb2RlID0gaW5Db250ZW50Lm1hdGNoKC9ob2xkY29kZTpcIiguKz8pXCIvKSFbMV07XG4gICAgY29uc3QgcG9zdHVybFJhdyA9IGluQ29udGVudC5tYXRjaCgvcG9zdHVybDpcIiguKz8pXCIvKSFbMV07XG4gICAgY29uc3QgcG9zdHVybFJhd0RlY29kZWQgPSBkZWNvZGVVUklDb21wb25lbnQocG9zdHVybFJhdyk7XG4gICAgY29uc3QgcG9zdHVybCA9IGRlY29kZVVSSUNvbXBvbmVudChgJHtwb3N0dXJsUmF3fSZldmVudD0ke2V2ZW50fSZob2xkY29kZT0ke2hvbGRjb2RlfSZub2NhY2hlPTAmaW5jbHBrZz1ZJmluY2xvZmZlcj1ZJmluY2xjYXJ0ZGV0YWlscz1ZJmluY2xDYXJ0PVkmaW5jbHZlbnVlPVlgKTtcbiAgICBjb25zdCB2ZW51ZUxvY2F0aW9uID0gZ2V0VmVudWVMb2NhdGlvbigpO1xuICAgIGNvbnN0IHRpY2tldFB1cmNoYXNlVXJsID0gYCR7cG9zdHVybFJhd0RlY29kZWQuc3BsaXQoXCI/XCIpWzBdLnNwbGl0KCcvJykuc2xpY2UoMCwtMSkuam9pbignLycpfS9UaWNrZXRQdXJjaGFzZWA7XG5cbiAgICByZXR1cm4gPEkuSW5wdXRzPiB7XG4gICAgICAgIFwiZXZlbnRcIjogZXZlbnQsXG4gICAgICAgIFwiaG9sZGNvZGVcIjogaG9sZGNvZGUsXG4gICAgICAgIFwicG9zdHVybFJhd1wiOiBwb3N0dXJsUmF3LFxuICAgICAgICBcInBvc3R1cmxSYXdEZWNvZGVkXCI6IHBvc3R1cmxSYXdEZWNvZGVkLFxuICAgICAgICBcInBvc3R1cmxcIjogcG9zdHVybCxcbiAgICAgICAgXCJ2ZW51ZUxvY2F0aW9uXCI6IHZlbnVlTG9jYXRpb24sXG4gICAgICAgIFwidGlja2V0UHVyY2hhc2VVcmxcIjogdGlja2V0UHVyY2hhc2VVcmxcbiAgICB9ICAgIFxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmVudWVJbWFnZSgpOiBJLlZlbnVlSW1hZ2UgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGltZzogSFRNTEltYWdlRWxlbWVudCA9IGpRdWVyeShcIiNzdGF0aWNfdmVudWVfbWFwIGltZ1wiKS5nZXQoMCk7XG5cbiAgICBpZiAoaW1nKSB7XG4gICAgICAgIHJldHVybiA8SS5WZW51ZUltYWdlPiB7XG4gICAgICAgICAgICB2ZW51ZUltYWdlU3JjOiBpbWcuc3JjLFxuICAgICAgICAgICAgdmVudWVJbWFnZUhlaWdodDogaW1nLmhlaWdodCxcbiAgICAgICAgICAgIHZlbnVlSW1hZ2VXaWR0aDogaW1nLndpZHRoXG4gICAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNNQVAoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWpRdWVyeShcIiNzZWF0aW5nX21hcF91cmxcIikubGVuZ3RoKVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgY29uc3Qgc3RyOiBzdHJpbmcgPSBqUXVlcnkoXCIjc2VhdGluZ19tYXBfdXJsIGFcIikuYXR0cihcIm9uY2xpY2tcIik7XG4gICAgY29uc3QgcmUgPSAvb3Blbk5ld1dpbmRvd1xcKFxcJyhcXGQrKVxcJy87XG4gICAgY29uc3QgZm91bmQ6IFJlZ0V4cE1hdGNoQXJyYXkgfCBudWxsID0gc3RyLm1hdGNoKHJlKTtcbiBcbiAgICByZXR1cm4gZm91bmQgPyBmb3VuZFsxXSA6IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEV2ZW50SW5mbygpOiBJLkV2ZW50SW5mbyB7XG4gICAgY29uc3QgdmVudWVYTUw6IEkuVmVudWVYTUwgPSBjb25maWcuc3RhdGUuaW5WZW51ZVhNTCE7XG4gICAgY29uc3Qgc2VjdGlvbkFycjogSS5TZWN0aW9uMltdID0gdmVudWVYTUwubWFzdGVyX2NvbmZpZ1swXS5zZWN0aW9uX2ludmVudG9yeVswXS5zZWN0aW9uO1xuICAgIGNvbnN0IGV2ZW50T2JqOiBJLkV2ZW50ID0gdmVudWVYTUwuZXZlbnRbMF07XG4gICAgY29uc3QgZXZlbnQ6IEkuRXZlbnQgPSB2ZW51ZVhNTC5ldmVudFswXTtcbiAgICBjb25zdCB2ZW51ZV9jb25maWc6IEkuVmVudWVDb25maWcgPSB2ZW51ZVhNTC52ZW51ZV9jb25maWdbMF07XG4gICAgY29uc3QgZGF0ZU9iajogRGF0ZSA9IG5ldyBEYXRlKHBhcnNlSW50KGV2ZW50LnllYXJbMF0pLCBwYXJzZUludChldmVudC5tb250aFswXSkgLSAxLCBwYXJzZUludChldmVudC5kYXlbMF0pLCBwYXJzZUludChldmVudC5ob3VyWzBdKSwgcGFyc2VJbnQoZXZlbnQubWludXRlWzBdKSk7XG4gICAgY29uc3Qgc3RhcnQ6IHN0cmluZ1tdID0gW2RhdGVPYmoudG9Mb2NhbGVTdHJpbmcoW1wiZGUtREVcIl0sIHsgd2Vla2RheTogXCJsb25nXCIsIGRheTogXCIyLWRpZ2l0XCIsIG1vbnRoOiBcIjItZGlnaXRcIiwgeWVhcjogXCJudW1lcmljXCIsIGhvdXI6IFwiMi1kaWdpdFwiLCBtaW51dGU6IFwiMi1kaWdpdFwiLCB0aW1lWm9uZU5hbWU6IFwic2hvcnRcIiB9KV07XG4gICAgY29uc3Qgd2Vla2RheTogc3RyaW5nW10gPSBbVXRpbHMuZ2V0RGF5TmFtZShkYXRlT2JqLCBcImRlLURFXCIpXTtcbiAgICBjb25zdCBzZWF0c19hdmFpbGFibGUgPSBzZWN0aW9uQXJyLm1hcChpdGVtID0+IHBhcnNlSW50KGl0ZW0uYXZhaWxhYmxlWzBdKSkucmVkdWNlKChwcmV2LCBjdXJyKSA9PiBwcmV2ICsgY3Vycik7XG5cbiAgICBjb25zdCBldmVudEV4dGVuZDogSS5FdmVudEV4dGVuZCA9IHtcbiAgICAgICAgdmVudWVfY29uZmlnX2NhcGFjaXR5OiB2ZW51ZV9jb25maWcuY2FwYWNpdHksXG4gICAgICAgIHZlbnVlX2NvbmZpZ19jb2RlOiB2ZW51ZV9jb25maWcuY29kZSxcbiAgICAgICAgdmVudWVfY29uZmlnX2Rlc2M6IHZlbnVlX2NvbmZpZy5kZXNjLFxuICAgICAgICB2ZW51ZV9jb25maWdfaWQ6IHZlbnVlX2NvbmZpZy5pZCxcbiAgICAgICAgdmVudWVfY29uZmlnX25hdl9pbWFnZTogdmVudWVfY29uZmlnLm5hdl9pbWFnZSxcbiAgICAgICAgdmVudWVfY29uZmlnX25hdl9pbWFnZV9oZWlnaHQ6IHZlbnVlX2NvbmZpZy5uYXZfaW1hZ2VfaGVpZ2h0LFxuICAgICAgICB2ZW51ZV9jb25maWdfbmF2X2ltYWdlX3dpZHRoOiB2ZW51ZV9jb25maWcubmF2X2ltYWdlX3dpZHRoLFxuICAgICAgICBzdGFydDogc3RhcnQsXG4gICAgICAgIHdlZWtkYXk6IHdlZWtkYXksXG4gICAgICAgIHNlYXRzX2F2YWlsYWJsZTogc2VhdHNfYXZhaWxhYmxlLFxuICAgIH07XG5cbiAgICByZXR1cm4gPEkuRXZlbnRJbmZvPnsgLi4uZXZlbnRPYmosIC4uLmV2ZW50RXh0ZW5kIH07XG59IiwiaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgKiBhcyBJIGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0ICogYXMgWE1MSGVscGVyIGZyb20gXCIuL3htbGhlbHBlclwiO1xuaW1wb3J0ICogYXMgakJveEhlbHBlciBmcm9tIFwiLi9qQm94SGVscGVyXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRTZWF0VG9TdGF0ZShpblNlbGVjdGVkU2VhdDogSS5KU0NTZWxlY3RlZFNlYXQpOiB2b2lkIHtcbiAgICBhZGRTZWF0T2JqVG9TdGF0ZShpblNlbGVjdGVkU2VhdCk7XG4gICAgY29uc3QgcHJpY2VzY2FsZUlEOiBzdHJpbmcgPSBjb25maWcuc3RhdGUuc2VsZWN0ZWRTZWF0c09ialtpblNlbGVjdGVkU2VhdC5pZF0uZGF0YS5zZWF0c09iai5pZFswXTtcbiAgICBjb25zdCBwcmljZXNjYWxlT2JqOiBJLlByaWNlc2NhbGU1IHwgdW5kZWZpbmVkID0gWE1MSGVscGVyLmdldFZlbnVlUHJpY2VTdHJ1Y3R1cmVQcm9wZXJ0eUJ5UHJpY2VzY2FsZUlEKHByaWNlc2NhbGVJRCk7XG5cbiAgICBpZiAocHJpY2VzY2FsZU9iaikge1xuICAgICAgICBjb25zdCBmaXJzdEJ1eWVyVHlwZUlEOiBzdHJpbmcgPSBwcmljZXNjYWxlT2JqLmJ1eWVyX3R5cGVbMF0uaWRbMF07XG4gICAgICAgIGNvbnN0IGJ1eWVyVHlwZUNvZGU6IHN0cmluZyB8IHVuZGVmaW5lZCA9IFhNTEhlbHBlci5nZXRCdXllclR5cGVDb2RlQnlCdXllclR5cGVJRChmaXJzdEJ1eWVyVHlwZUlEKTtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRTZWF0c0Fyckl0ZW06IChzdHJpbmcgfCB1bmRlZmluZWQpW10gPSBbaW5TZWxlY3RlZFNlYXQuaWQsIGZpcnN0QnV5ZXJUeXBlSUQsIGJ1eWVyVHlwZUNvZGVdO1xuICAgICAgICBhZGRTZWF0c0l0ZW1Ub1N0YXRlKHNlbGVjdGVkU2VhdHNBcnJJdGVtKTtcbiAgICB9XG4gICAgZWxzZVxuICAgICAgICBjb25zb2xlLndhcm4oYENhbm5vdCBmaW5kIGNvcnJlc3BvbmRpbmcgdmVudWVYTUwgcHJpY2VzY2FsZU9iaiBmb3IgcHJpY2VzY2FsZSB3aXRoIElEICR7cHJpY2VzY2FsZUlEfWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlU2VhdEZyb21TdGF0ZShpblNlbGVjdGVkU2VhdDogSS5KU0NTZWxlY3RlZFNlYXQpOiB2b2lkIHtcbiAgICBkZWxldGUgY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNPYmpbaW5TZWxlY3RlZFNlYXQuaWRdO1xuXG4gICAgY29uc3QgaW5kZXg6IG51bWJlciA9IGNvbmZpZy5zdGF0ZS5zZWxlY3RlZFNlYXRzQXJyLmZpbmRJbmRleChhcnIgPT4gYXJyWzBdID09PSBpblNlbGVjdGVkU2VhdC5pZCk7XG4gICAgY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNBcnIuc3BsaWNlKGluZGV4LCAxKTtcblxuICAgIGNvbmZpZy5zdGF0ZS5jYXJ0Q2hhbmdlZCA9IHRydWU7XG5cbiAgICBpZiAoIWNvbmZpZy5zdGF0ZS5zZWxlY3RlZFNlYXRzQXJyLmxlbmd0aClcbiAgICAgICAgalF1ZXJ5KFwiI21vZGFsQ2FydC1vdmVybGF5XCIpLmhpZGUoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1heGltdW1TZWxlY3RlZFNlYXRzUmVhY2hlZChpblNlYXRPYmo6IEkuSlNDU2VsZWN0ZWRTZWF0KTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc2VhdG1hcDogYW55ID0gY29uZmlnLnN0YXRlLnNlYXRtYXA7XG5cbiAgICBpZiAoY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNBcnIubGVuZ3RoID49IGNvbmZpZy5tYXhTZWxlY3RlZFNlYXRzKSB7XG4gICAgICAgIGpCb3hIZWxwZXIuc2hvd0pCb3hOb3RpY2UoYFNpZSBrw7ZubmVuIG1heGltYWwgJHtjb25maWcubWF4U2VsZWN0ZWRTZWF0c30gUGzDpHR6ZSBhdXN3w6RobGVuLmApO1xuICAgICAgICBzZWF0bWFwLnN0YXR1cyhpblNlYXRPYmouaWQsIFwiYXZhaWxhYmxlXCIpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGFkZFNlYXRzSXRlbVRvU3RhdGUoaW5JdGVtOiAoc3RyaW5nIHwgdW5kZWZpbmVkKVtdKTogdm9pZCB7XG4gICAgaWYgKGluSXRlbS5ldmVyeSh2ID0+IHYgIT09IChcIlwiIHx8IHVuZGVmaW5lZCB8fCBudWxsKSkpIHtcbiAgICAgICAgY29uZmlnLnN0YXRlLnNlbGVjdGVkU2VhdHNBcnIucHVzaCg8c3RyaW5nW10+aW5JdGVtKTtcbiAgICAgICAgY29uZmlnLnN0YXRlLmNhcnRDaGFuZ2VkID0gdHJ1ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGFkZFNlYXRPYmpUb1N0YXRlKGluU2VsZWN0ZWRTZWF0OiBJLkpTQ1NlbGVjdGVkU2VhdCk6IHZvaWQge1xuICAgIGNvbnN0IHNlYXRJRDogc3RyaW5nID0gaW5TZWxlY3RlZFNlYXQuaWQ7XG4gICAgY29uc3Qgc2VhdE9iajogSS5TdGF0ZUpTQ1NlbGVjdGVkU2VhdHMgPSB7XG4gICAgICAgIFtzZWF0SURdOiBpblNlbGVjdGVkU2VhdFxuICAgIH1cblxuICAgIGNvbmZpZy5zdGF0ZS5zZWxlY3RlZFNlYXRzT2JqID0geyAuLi5jb25maWcuc3RhdGUuc2VsZWN0ZWRTZWF0c09iaiwgLi4uc2VhdE9iaiB9XG59IiwiaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgKiBhcyBJIGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkVHJpbXMoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VhdG1hcFhNTDogYW55ID0gY29uZmlnLnN0YXRlLnNlYXRtYXBYTUw7XG4gICAgY29uc3QgdHJpbUFycjogSS5UcmltW10gPSBzZWF0bWFwWE1MLnNlYXRtYXBbMF0udHJpbXNbMF0udHJpbTtcblxuICAgIHRyaW1BcnIuZm9yRWFjaChhcnIgPT4ge1xuICAgICAgICBjb25zdCBbeFRyaW0sIHlUcmltXSA9IGFyci5jb29yZFswXS5zcGxpdChcIixcIikubWFwKE51bWJlcik7XG4gICAgICAgIGNvbnN0IHRleHRBcnI6IHN0cmluZ1tdID0gYXJyLnRleHRbMF0uc3BsaXQoXCI7XCIpLmZpbHRlcihCb29sZWFuKTtcbiAgICAgICAgY29uc3QgeDogbnVtYmVyID0geFRyaW0gLyAyMDtcbiAgICAgICAgY29uc3QgeTogbnVtYmVyID0gTWF0aC5yb3VuZCh5VHJpbSAvIDIxLjI1KTsgICAgICAgIFxuXG4gICAgICAgIGRlY29kZVRyaW0odGV4dEFyciwgeCwgeSk7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGRlY29kZVRyaW0odGV4dEFycjogc3RyaW5nW10sIHg6IG51bWJlciwgeTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgc3BlY2lhbENoYXI6IE1hcDxzdHJpbmcsIHN0cmluZz4gPSBuZXcgTWFwKFtcbiAgICAgICAgW1wiJiN4OGVcIiwgXCLDhFwiXSxcbiAgICAgICAgW1wiJiN4OTlcIiwgXCLDllwiXSxcbiAgICAgICAgW1wiJiN4OWFcIiwgXCLDnFwiXSxcbiAgICAgICAgW1wiJiN4ODRcIiwgXCLDpFwiXSxcbiAgICAgICAgW1wiJiN4OTRcIiwgXCLDtlwiXSxcbiAgICAgICAgW1wiJiN4ODFcIiwgXCLDvFwiXSxcbiAgICAgICAgW1wiJiN4ZTFcIiwgXCLDn1wiXVxuICAgIF0pO1xuXG4gICAgdGV4dEFyci5tYXAoKGVsZW1lbnQsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGNoYXJhY3Rlcjogc3RyaW5nIHwgdW5kZWZpbmVkID0gc3BlY2lhbENoYXIuaGFzKGVsZW1lbnQpID8gc3BlY2lhbENoYXIuZ2V0KGVsZW1lbnQpIDogZGVjb2RlTm9ybWFsVHJpbShlbGVtZW50KTtcblxuICAgICAgICBpZiAoY2hhcmFjdGVyKSB7XG4gICAgICAgICAgICBjb25zdCB0cmltUG9zOiBJLlRyaW1Qb3MgPSBnZXRKU0NUcmltUG9zKHgsIHksIGluZGV4KTtcbiAgICAgICAgICAgIGFwcGx5VHJpbShjaGFyYWN0ZXIsIHRyaW1Qb3MpO1xuICAgICAgICB9ICAgICAgICAgICAgXG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGRlY29kZU5vcm1hbFRyaW0oZWxlbWVudDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBjaGFyQ29kZTogc3RyaW5nID0gZWxlbWVudC5yZXBsYWNlKC9eXFwmXFwjLywgXCIwXCIpO1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGNoYXJDb2RlLCAxNikpO1xufVxuXG5mdW5jdGlvbiBhcHBseVRyaW0oaW5DaGFyYWN0ZXI6IHN0cmluZywgaW5UcmltUG9zOiBJLlRyaW1Qb3MpOiB2b2lkIHtcbiAgICBjb25zdCByZWdleDogUmVnRXhwID0gL1teYS16QS1aMC05w6TDtsO8w4TDlsOcw58kXS87XG4gICAgXG4gICAgaWYgKCFyZWdleC50ZXN0KGluQ2hhcmFjdGVyKSkge1xuICAgICAgICBjb25zb2xlLmxvZyhgJHtpbkNoYXJhY3Rlcn0gLT4gJHtpblRyaW1Qb3MueEpTQ30gJHtpblRyaW1Qb3MueUpTQ31gKTtcbiAgICAgICAgalF1ZXJ5KFwiLnNlYXRDaGFydHMtcm93XCIpW2luVHJpbVBvcy55SlNDXS5jaGlsZHJlbltpblRyaW1Qb3MueEpTQ10uaW5uZXJIVE1MID0gYDxzcGFuIGNsYXNzPVwidHJpbUNoYXJcIj4ke2luQ2hhcmFjdGVyfTwvc3Bhbj5gXG4gICAgfVxufVxuXG5mdW5jdGlvbiBnZXRKU0NUcmltUG9zKGluWDogbnVtYmVyLCBpblk6IG51bWJlciwgaW5kZXg6IG51bWJlcik6IEkuVHJpbVBvcyB7XG4gICAgcmV0dXJuIDxJLlRyaW1Qb3M+IHtcbiAgICAgICAgeDogaW5YLFxuICAgICAgICB5OiBpblksXG4gICAgICAgIHhKU0M6IChpblggLSAxKSArIGluZGV4LFxuICAgICAgICB5SlNDOiBpblkgLSAxXG4gICAgfVxufSIsImltcG9ydCAqIGFzIEkgZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgKiBhcyBDb21tdW5pY2F0aW9uIGZyb20gXCIuL2NvbW11bmljYXRpb25cIjtcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gXCIuL2NvbmZpZ1wiO1xuaW1wb3J0ICogYXMgRXZlbnRzIGZyb20gXCIuL2V2ZW50c1wiO1xuaW1wb3J0ICogYXMgUGFuem9vbSBmcm9tIFwiLi9wYW56b29tXCI7XG5pbXBvcnQgKiBhcyBDYXJ0QnV0dG9ucyBmcm9tIFwiLi9jYXJ0QnV0dG9uc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0T3B0aW9uU2VsZWN0KGluU2VhdG1hcExpc3Rpbmc6IEkuU2VhdG1hcFtdLCBpbklkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzZWF0bWFwRHJvcGRvd246IEhUTUxFbGVtZW50IHwgbnVsbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGluSWQpO1xuXG4gICAgaWYgKHNlYXRtYXBEcm9wZG93bikge1xuICAgICAgICBmb3IgKGxldCBzZWF0bWFwT2JqIG9mIGluU2VhdG1hcExpc3RpbmcpIHtcbiAgICAgICAgICAgIHZhciBvcHQ6IEhUTUxPcHRpb25FbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb3B0aW9uJyk7XG4gICAgICAgICAgICBvcHQudmFsdWUgPSBzZWF0bWFwT2JqLmlkWzBdO1xuICAgICAgICAgICAgb3B0LmlubmVySFRNTCA9IHNlYXRtYXBPYmouZGVzY1swXTtcbiAgICAgICAgICAgIHNlYXRtYXBEcm9wZG93bi5hcHBlbmRDaGlsZChvcHQpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0RXZlbnRJbmZvKGluRXZlbnRJbmZvOiBJLkV2ZW50SW5mbyk6IHZvaWQge1xuICAgIGNvbnN0IGlucHV0c1dpdGhWYWx1ZSA9IGNvbmZpZy5zdGF0ZS5pbnB1dHNXaXRoVmFsdWUhO1xuXG4gICAgalF1ZXJ5KFwiI2V2ZW50SW5mb0Rlc2Mgc3Bhbi5mbC1oZWFkaW5nLXRleHRcIilbMF0uY2hpbGROb2Rlc1swXS50ZXh0Q29udGVudCA9IGluRXZlbnRJbmZvLmRlc2NbMF07XG4gICAgalF1ZXJ5KFwiI2V2ZW50SW5mb0RhdGUgcFwiKVswXS5jaGlsZE5vZGVzWzBdLnRleHRDb250ZW50ID0gaW5FdmVudEluZm8uc3RhcnRbMF07XG4gICAgalF1ZXJ5KFwiI2V2ZW50SW5mb0xvY2F0aW9uIHBcIilbMF0uY2hpbGROb2Rlc1swXS50ZXh0Q29udGVudCA9IGlucHV0c1dpdGhWYWx1ZS52ZW51ZUxvY2F0aW9uO1xuICAgIGpRdWVyeShcIiNldmVudEluZm9DYXBhY2l0eSBwXCIpWzBdLmNoaWxkTm9kZXNbMF0udGV4dENvbnRlbnQgPSBgVmVyZsO8Z2JhcmUgUGzDpHR6ZTogJHtpbkV2ZW50SW5mby5zZWF0c19hdmFpbGFibGV9IHZvbiAke2luRXZlbnRJbmZvLnZlbnVlX2NvbmZpZ19jYXBhY2l0eVswXX1gO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRGlhbG9nKCk6IHZvaWQge1xuICAgIGNvbnN0IGlmcmFtZUhUTUw6IHN0cmluZyA9IFwiPGlmcmFtZSBpZD0naWZyYW1lU2VhdG1hcCcgc2Nyb2xsaW5nPSdubycgZnJhbWVib3JkZXI9JzAnIG1hcmdpbndpZHRoPScwJyBtYXJnaW5oZWlnaHQ9JzAnIGFsbG93ZnVsbHNjcmVlbiB3aWR0aD0nMTAwJScgLz5cIjtcbiAgICBjb25zdCBzcmM6IHN0cmluZyA9IGNvbmZpZy5icmFuY2ggPT09IFwic3RhZ2luZ1wiID8gY29uZmlnLnVybFNlYXRtYXBTdGFnaW5nIDogY29uZmlnLnVybFNlYXRtYXBNYXN0ZXI7XG5cbiAgICBqUXVlcnkoXCIjZGlhbG9nU2VhdG1hcFwiKS5hcHBlbmQoXG4gICAgICAgIGpRdWVyeShpZnJhbWVIVE1MKVxuICAgICAgICAgICAgLmF0dHIoXCJzcmNcIiwgc3JjKSlcbiAgICAgICAgLmRpYWxvZyh7XG4gICAgICAgICAgICBtb2RhbDogdHJ1ZSxcbiAgICAgICAgICAgIGF1dG9PcGVuOiBmYWxzZSxcbiAgICAgICAgICAgIGNsb3NlT25Fc2NhcGU6IHRydWUsXG4gICAgICAgICAgICBkcmFnZ2FibGU6IGZhbHNlLFxuICAgICAgICAgICAgaGlkZTogdHJ1ZSxcbiAgICAgICAgICAgIHNob3c6IHRydWUsXG4gICAgICAgICAgICByZXNpemFibGU6IGZhbHNlLFxuICAgICAgICAgICAgdGl0bGU6IFwiXCIsXG4gICAgICAgICAgICB3aWR0aDogXCIxMDAlXCIsXG4gICAgICAgICAgICBoZWlnaHQ6IFwiYXV0b1wiLFxuICAgICAgICAgICAgY2xvc2U6ICgpID0+IGpRdWVyeShcImh0bWwsIGJvZHlcIikuY3NzKFwib3ZlcmZsb3dcIiwgXCJhdXRvXCIpLFxuICAgICAgICB9KTtcblxuICAgIEV2ZW50cy5hZGRPcGVuU2VhdG1hcCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVzdHJveUN1cnJlbnRTZWF0bWFwKGluU2VsZWN0b3I6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmIChjb25maWcuc3RhdGUucGFuem9vbSlcbiAgICAgICAgUGFuem9vbS51bmJpbmRQYW56b29tRXZlbnRzKGluU2VsZWN0b3IpO1xuXG4gICAgalF1ZXJ5KFwiI2NvbnRhaW5lclNlYXRtYXBJbm5lclwiKS5yZW1vdmUoKTtcbiAgICBqUXVlcnkoXCIjaHRtbFNlYXRtYXBJbm5lciAuZmwtaHRtbFwiKS5yZW1vdmVBdHRyKFwic3R5bGVcIik7XG4gICAgalF1ZXJ5KFwiI2h0bWxTZWF0bWFwSW5uZXIgLmZsLWh0bWxcIikuYXBwZW5kKCc8ZGl2IGlkPVwiY29udGFpbmVyU2VhdG1hcElubmVyXCI+PC9kaXY+Jyk7XG4gICAgalF1ZXJ5KFwiI0pTQ0xlZ2VuZElubmVyXCIpLnJlbW92ZSgpO1xuICAgIGpRdWVyeShcIiNKU0NMZWdlbmQgLmZsLWh0bWxcIikuYXBwZW5kKCc8ZGl2IGlkPVwiSlNDTGVnZW5kSW5uZXJcIj48L2Rpdj4nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnRyb2xMb2Z0bG9hZGVyKGluU3dpdGNoOiBzdHJpbmcpIHtcbiAgICBpZiAoaW5Td2l0Y2ggPT09IFwic2hvd1wiKVxuICAgICAgICBqUXVlcnkoXCJib2R5XCIpLnJlbW92ZUNsYXNzKFwibG9hZGVkIGxvZnRsb2FkZXItbG9hZGVkXCIpO1xuICAgIGVsc2UgaWYgKGluU3dpdGNoID09PSBcImhpZGVcIilcbiAgICAgICAgalF1ZXJ5KFwiYm9keVwiKS5hZGRDbGFzcyhcImxvYWRlZCBsb2Z0bG9hZGVyLWxvYWRlZFwiKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNoYW5nZVZlbnVlSW1hZ2UoKTogdm9pZCB7XG4gICAgY29uc3QgaW5wdXRzV2l0aFZhbHVlOiBJLklucHV0c1dpdGhWYWx1ZSA9IGNvbmZpZy5zdGF0ZS5pbnB1dHNXaXRoVmFsdWUhO1xuXG4gICAgaWYgKGlucHV0c1dpdGhWYWx1ZS52ZW51ZUltYWdlU3JjICE9PSB1bmRlZmluZWQpXG4gICAgICAgIGpRdWVyeShcIiN2ZW51ZUltYWdlIGltZ1wiKS5hdHRyKFwic3JjXCIsIGlucHV0c1dpdGhWYWx1ZS52ZW51ZUltYWdlU3JjKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZhZGVJbkNhcnRNb2RhbCgpOiB2b2lkIHtcbiAgICBqUXVlcnkoXCIjbW9kYWxDYXJ0LW92ZXJsYXlcIikuZmFkZUluKDMwMCk7XG4gICAgQ29tbXVuaWNhdGlvbi5zZW5kRXZlbnRUb1BhcmVudChcImNoaWxkX2hpZGVfZGlhbG9nX3RpdGxlYmFyXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVQcmljZXNjYWxlQ1NTKCk6IHN0cmluZyB7XG4gICAgY29uc3QgdmVudWVYTUw6IEkuVmVudWVYTUwgPSBjb25maWcuc3RhdGUuaW5WZW51ZVhNTCE7XG4gICAgY29uc3QgdmVudWVQcmljZXNjYWxlc0FycjogSS5QcmljZXNjYWxlMltdID0gdmVudWVYTUwudmVudWVbMF0ucHJpY2VzY2FsZXNbMF0ucHJpY2VzY2FsZTtcblxuICAgIHJldHVybiB2ZW51ZVByaWNlc2NhbGVzQXJyLm1hcChhcnIgPT4ge1xuICAgICAgICBjb25zdCBJRDogc3RyaW5nID0gYXJyLmlkWzBdO1xuICAgICAgICBsZXQgY29sb3I6IHN0cmluZyA9IGAjJHthcnIuY29sb3JbMF19ICFpbXBvcnRhbnRgOyAgLy8gVXBkYXRlOiBDb2xvcnMgYXJlIGFsd2F5cyBkZWZpbmVkOiBmYWxsYmFjayBjb2xvcnMgZXhpc3QgaW4gc3lzdGVtIHNvIGV2ZXJ5IFhNTCBwcm92aWRlcyB0aGVtXG4gICAgICAgIHJldHVybiBgLl8ke0lEfSB7IGJhY2tncm91bmQtY29sb3I6ICR7Y29sb3J9OyB9YDtcbiAgICB9KS5qb2luKFwiXFxyXFxuXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRqdXN0VUlUb0xvYWRpbmcoKTogdm9pZCB7XG4gICAgQ2FydEJ1dHRvbnMuc2hvd0hpZGVCdG5DYXJ0TG9hZGluZyhcInNob3dcIik7XG4gICAgalF1ZXJ5KFwiI21vZGFsQ2FydCBpXCIpLmhpZGUoKTtcbiAgICBqUXVlcnkoXCIjbW9kYWxDYXJ0IC51YWJiLWJ1dHRvbi10ZXh0XCIpLmFkZENsYXNzKFwiZG90LXB1bHNlXCIpO1xufSIsImltcG9ydCAqIGFzIEkgZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFV0aWxzIHtcblxuICAgIHN0YXRpYyB3YWl0Rm9yRWxlbWVudChpblNlbGVjdG9yOiBzdHJpbmcgfCBDYWxsYWJsZUZ1bmN0aW9uLCBpbkNhbGxiYWNrOiBGdW5jdGlvbiwgaW5Td2l0Y2g6IEkuVHlwZVdhaXRGb3JFbGVtZW50U3dpdGNoID0gXCJzZWxlY3RvclwiLCBpbkNoZWNrSW50ZXJ2YWxJbk1zOiBudW1iZXIgPSAxMDAwLCBpblRpbWVvdXRJbk1zOiBudW1iZXIgPSAxMDAwMCk6IHZvaWQge1xuICAgICAgICBjb25zdCBzdGFydFRpbWVJbk1zOiBudW1iZXIgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIChmdW5jdGlvbiBsb29wU2VhcmNoKCk6IHZvaWQge1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudDogYm9vbGVhbiB8IEhUTUxFbGVtZW50ID0gaW5Td2l0Y2ggPT09IFwic2VsZWN0b3JcIiA/IGpRdWVyeSg8c3RyaW5nPmluU2VsZWN0b3IpLmdldCgwKSA6IFV0aWxzLmdldFNlYXRtYXBFbGVtZW50KCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJyZWFkeVwiKTtcbiAgICAgICAgICAgICAgICBpbkNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9ICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFJlcGVhdGluZyBmb3IgJHtpblN3aXRjaH1gKTtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluVGltZW91dEluTXMgJiYgRGF0ZS5ub3coKSAtIHN0YXJ0VGltZUluTXMgPiBpblRpbWVvdXRJbk1zKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgICAgICAgICAgICAgIGxvb3BTZWFyY2goKTtcbiAgICAgICAgICAgICAgICB9LCBpbkNoZWNrSW50ZXJ2YWxJbk1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgZ2V0U2VhdG1hcEVsZW1lbnQoKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHNlYXRDaGFydHM6IENhbGxhYmxlRnVuY3Rpb24gPSAoPGFueT53aW5kb3cpLmpRdWVyeShcIiNjb250YWluZXJTZWF0bWFwXCIpLnNlYXRDaGFydHM7XG4gICAgICAgIHJldHVybiBVdGlscy5pc0Z1bmN0aW9uKHNlYXRDaGFydHMpO1xuICAgIH1cblxuICAgIHN0YXRpYyB3YWl0Rm9yU2VhdG1hcChpbkNhbGxiYWNrOiBGdW5jdGlvbik6IHZvaWQge1xuICAgICAgICBjb25zdCBzZWF0Q2hhcnRzOiBDYWxsYWJsZUZ1bmN0aW9uID0gKDxhbnk+d2luZG93KS5qUXVlcnkoXCIjY29udGFpbmVyU2VhdG1hcFwiKS5zZWF0Q2hhcnRzO1xuICAgICAgICB0aGlzLndhaXRGb3JFbGVtZW50KHNlYXRDaGFydHMsIGluQ2FsbGJhY2ssIFwic2VhdG1hcFwiKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgcXVlcnlTZWxlY3RvcihzZWxlY3Rvcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKSAhPSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBzdGF0aWMgaXNGdW5jdGlvbihpblNlbGVjdG9yOiBDYWxsYWJsZUZ1bmN0aW9uKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgaW5TZWxlY3RvciA9PT0gXCJmdW5jdGlvblwiID8gdHJ1ZSA6IGZhbHNlO1xuICAgIH1cblxuICAgIHN0YXRpYyBpbmplY3QoaW5Db250ZW50OiBzdHJpbmcsIGluVHlwZTogc3RyaW5nID0gXCJqc1wiLCBpbkxvYzogc3RyaW5nID0gXCJoZWFkXCIpOiB2b2lkIHtcbiAgICAgICAgdmFyIHNjcmlwdDogSS5UeXBlSW5qZWN0U2NyaXB0IHwgdW5kZWZpbmVkO1xuXG4gICAgICAgIHN3aXRjaCAoaW5UeXBlKSB7XG4gICAgICAgICAgICBjYXNlIFwianNcIjpcbiAgICAgICAgICAgICAgICBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcbiAgICAgICAgICAgICAgICBzY3JpcHQudHlwZSA9ICd0ZXh0L2phdmFzY3JpcHQnO1xuICAgICAgICAgICAgICAgIHNjcmlwdC5zcmMgPSBpbkNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgXCJjc3NcIjpcbiAgICAgICAgICAgICAgICBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaW5rJyk7XG4gICAgICAgICAgICAgICAgc2NyaXB0LnR5cGUgPSAndGV4dC9jc3MnO1xuICAgICAgICAgICAgICAgICg8SFRNTExpbmtFbGVtZW50PnNjcmlwdCkucmVsID0gXCJzdHlsZXNoZWV0XCI7XG4gICAgICAgICAgICAgICAgKDxIVE1MTGlua0VsZW1lbnQ+c2NyaXB0KS5ocmVmID0gaW5Db250ZW50O1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIFwiY3NzQ3VzdG9tXCI6XG4gICAgICAgICAgICAgICAgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICAgICAgICAgICAgICBzY3JpcHQudHlwZSA9ICd0ZXh0L2Nzcyc7XG4gICAgICAgICAgICAgICAgc2NyaXB0LmlubmVySFRNTCA9IGluQ29udGVudDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY2FzZSBcInNjcmlwdFwiOlxuICAgICAgICAgICAgICAgIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICAgICAgICAgIHNjcmlwdC50eXBlID0gJ3RleHQvamF2YXNjcmlwdCc7XG4gICAgICAgICAgICAgICAgc2NyaXB0LmlubmVySFRNTCA9IGluQ29udGVudDtcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBzY3JpcHQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7ICAgICAgICAgICAgICAgIFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjcmlwdClcbiAgICAgICAgICAgIFV0aWxzLmFwcGVuZFNjcmlwdChzY3JpcHQsIGluTG9jKTsgICAgICAgIFxuICAgIH1cblxuICAgIHN0YXRpYyBhcHBlbmRTY3JpcHQoaW5TY3JpcHQ6IEkuVHlwZUluamVjdFNjcmlwdCwgaW5Mb2M6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBpZiAoaW5Mb2MgPT09IFwiYm9keVwiKVxuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChpblNjcmlwdCk7XG4gICAgICAgIGVsc2UgaWYgKGluTG9jID09PSBcImhlYWRcIilcbiAgICAgICAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoaW5TY3JpcHQpO1xuICAgIH1cblxuICAgIHN0YXRpYyBnZXREYXlOYW1lKGluRGF0ZTogRGF0ZSwgaW5Mb2NhbGU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBpbkRhdGUudG9Mb2NhbGVEYXRlU3RyaW5nKGluTG9jYWxlLCB7IHdlZWtkYXk6ICdsb25nJyB9KTtcbiAgICB9ICAgIFxufSIsIlxuaW1wb3J0ICogYXMgSSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gXCIuL2NvbmZpZ1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gcHJvY2Vzc1NNQVAoKTogdm9pZCB7XG4gICAgY29uc3QgaW5wdXRzV2l0aFZhbHVlID0gY29uZmlnLnN0YXRlLmlucHV0c1dpdGhWYWx1ZSE7XG5cbiAgICBpZiAoIWlucHV0c1dpdGhWYWx1ZS5zbWFwKVxuICAgICAgICByZXR1cm47XG5cbiAgICBjb25zdCBzbWFwQXJyOiBudW1iZXJbXSA9IGlucHV0c1dpdGhWYWx1ZS5zbWFwLnNwbGl0KFwiXCIpLm1hcChOdW1iZXIpO1xuXG4gICAgaWYgKCFzbWFwQXJyWzBdKVxuICAgICAgICBqUXVlcnkoXCIjZXZlbnRJbmZvQ2FwYWNpdHlcIikuaGlkZSgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VjdGlvbkRlc2NCeVNlY3Rpb25JRChpblNlY3Rpb25JRDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB2ZW51ZVhNTDogSS5WZW51ZVhNTCA9IGNvbmZpZy5zdGF0ZS5pblZlbnVlWE1MITtcbiAgICBjb25zdCBzZWN0aW9uQXJyOiBJLlNlY3Rpb25bXSA9IHZlbnVlWE1MLm1hc3Rlcl9jb25maWdbMF0uc2VjdGlvbl9jb25maWdbMF0uc2VjdGlvbjtcblxuICAgIHJldHVybiBzZWN0aW9uQXJyLmZpbmQoYXJyID0+IGluU2VjdGlvbklEID09PSBhcnIuaWRbMF0pPy5kZXNjWzBdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmVudWVQcmljZXNjYWxlUHJvcGVydHlCeVByaWNlc2NhbGVJRChpblByb3BlcnR5OiBJLlByaWNlc2NhbGUyUHJvcGVydGllcywgaW5QcmljZXNjYWxlSUQ6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdmVudWVYTUw6IEkuVmVudWVYTUwgPSBjb25maWcuc3RhdGUuaW5WZW51ZVhNTCE7XG4gICAgY29uc3QgdmVudWVQcmljZXNjYWxlQXJyOiBJLlByaWNlc2NhbGUyW10gPSB2ZW51ZVhNTC52ZW51ZVswXS5wcmljZXNjYWxlc1swXS5wcmljZXNjYWxlO1xuXG4gICAgcmV0dXJuIHZlbnVlUHJpY2VzY2FsZUFyci5maW5kKG9iaiA9PiBvYmouaWRbMF0gPT09IGluUHJpY2VzY2FsZUlEID8gb2JqIDogdW5kZWZpbmVkKT8uW2luUHJvcGVydHldWzBdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QnV5ZXJUeXBlQ29kZUJ5QnV5ZXJUeXBlSUQoaW5CdXllclR5cGVJRDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB2ZW51ZVhNTDogSS5WZW51ZVhNTCA9IGNvbmZpZy5zdGF0ZS5pblZlbnVlWE1MITtcbiAgICBjb25zdCB2ZW51ZUJ1eWVyVHlwZUFycjogSS5CdXllclR5cGUyW10gPSB2ZW51ZVhNTC52ZW51ZVswXS5idXllcl90eXBlc1swXS5idXllcl90eXBlO1xuXG4gICAgcmV0dXJuIHZlbnVlQnV5ZXJUeXBlQXJyLmZpbmQoYXJyID0+IGluQnV5ZXJUeXBlSUQgPT09IGFyci5pZFswXSk/LmNvZGVbMF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcmljZUJ5QnV5ZXJUeXBlSUQoaW5CdXllcnR5cGVJRDogc3RyaW5nLCBpblByaWNlc2NhbGVPYmo6IEkuUHJpY2VzY2FsZTUpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHByaWNlID0gaW5QcmljZXNjYWxlT2JqPy5idXllcl90eXBlLmZpbmQoYXJyID0+IGFyci5pZFswXSA9PT0gaW5CdXllcnR5cGVJRCk/LnByaWNlWzBdO1xuICAgIHJldHVybiBwcmljZSA/IHBhcnNlRmxvYXQocHJpY2UpIDogdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmVudWVQcmljZVN0cnVjdHVyZVByb3BlcnR5QnlQcmljZXNjYWxlSUQoaW5JRDogc3RyaW5nKTogSS5QcmljZXNjYWxlNSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdmVudWVYTUw6IEkuVmVudWVYTUwgPSBjb25maWcuc3RhdGUuaW5WZW51ZVhNTCE7XG4gICAgY29uc3QgdmVudWVQcmljZXNjYWxlQXJyOiBJLlByaWNlc2NhbGU1W10gPSB2ZW51ZVhNTC5wcmljZV9zdHJ1Y3R1cmVbMF0ucHJpY2VzY2FsZTtcbiAgICByZXR1cm4gdmVudWVQcmljZXNjYWxlQXJyLmZpbmQob2JqID0+IG9iai5pZFswXSA9PT0gaW5JRCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCdXllclR5cGVzQnlQcmljZXNjYWxlSUQoaW5QcmljZXNjYWxlSUQ6IHN0cmluZyk6IEkuVHlwZUJ1eWVyVHlwZUFycltdIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBidXllclR5cGVzQXJyOiBJLkJ1eWVyVHlwZTNbXSB8IHVuZGVmaW5lZCA9IGZpbmRCdXllclR5cGVzQXJyQnlQcmljZXNjYWxlSUQoaW5QcmljZXNjYWxlSUQpO1xuICAgIHJldHVybiBidXllclR5cGVzQXJyID8gYnV5ZXJUeXBlc0Fyci5tYXAoYXJyID0+IFthcnIuaWRbMF0sIGFyci5wcmljZVswXSwgZ2V0QnV5ZXJUeXBlRGVzYyhhcnIpXSkgOiB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVNlbGVjdGVkU2VhdEluZGV4ZXMoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gKGNvbmZpZy5zdGF0ZS5zZWxlY3RlZFNlYXRzQXJyLm1hcChhcnIgPT4gYXJyLmpvaW4oXCIsXCIpKSkuam9pbihcInxcIik7XG59XG5cbmZ1bmN0aW9uIGZpbmRCdXllclR5cGVzQXJyQnlQcmljZXNjYWxlSUQoaW5QcmljZXNjYWxlSUQ6IHN0cmluZyk6IEkuQnV5ZXJUeXBlM1tdIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB2ZW51ZVhNTDogSS5WZW51ZVhNTCA9IGNvbmZpZy5zdGF0ZS5pblZlbnVlWE1MITtcbiAgICBjb25zdCB2ZW51ZVByaWNlc2NhbGVBcnI6IEkuUHJpY2VzY2FsZTVbXSA9IHZlbnVlWE1MLnByaWNlX3N0cnVjdHVyZVswXS5wcmljZXNjYWxlO1xuXG4gICAgcmV0dXJuIHZlbnVlUHJpY2VzY2FsZUFyci5maW5kKG9iaiA9PiBvYmouaWRbMF0gPT09IGluUHJpY2VzY2FsZUlEKT8uYnV5ZXJfdHlwZTtcbn1cblxuZnVuY3Rpb24gZ2V0QnV5ZXJUeXBlRGVzYyhpbkFycjogSS5CdXllclR5cGUzKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB2ZW51ZVhNTDogSS5WZW51ZVhNTCA9IGNvbmZpZy5zdGF0ZS5pblZlbnVlWE1MITtcbiAgICBjb25zdCBidXllclR5cGVBcnI6IEkuQnV5ZXJUeXBlMltdID0gdmVudWVYTUwudmVudWVbMF0uYnV5ZXJfdHlwZXNbMF0uYnV5ZXJfdHlwZTtcblxuICAgIHJldHVybiBidXllclR5cGVBcnIuZmluZChvYmogPT4gb2JqLmlkWzBdID09PSBpbkFyci5pZFswXSA/IG9iai5kZXNjWzBdIDogdW5kZWZpbmVkKT8uZGVzY1swXTtcbn0iLCJpbXBvcnQgalF1ZXJ5ID0gcmVxdWlyZShcImpxdWVyeVwiKTtcbmltcG9ydCAqIGFzIENvbW11bmljYXRpb24gZnJvbSBcIi4vbW9kdWxlcy9jb21tdW5pY2F0aW9uXCI7XG5pbXBvcnQgKiBhcyBJIGZyb20gXCIuL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBjb25maWcgfSBmcm9tIFwiLi9tb2R1bGVzL2NvbmZpZ1wiO1xuaW1wb3J0IFV0aWxzIGZyb20gXCIuL21vZHVsZXMvdXRpbHNcIjtcbmltcG9ydCAqIGFzIEV2ZW50cyBmcm9tIFwiLi9tb2R1bGVzL2V2ZW50c1wiO1xucmVxdWlyZShcImpib3gvZGlzdC9qQm94LmFsbC5jc3NcIik7XG5pbXBvcnQgKiBhcyBDYXJ0IGZyb20gXCIuL21vZHVsZXMvY2FydFwiO1xuaW1wb3J0ICogYXMgQm9va2luZ0J0biBmcm9tIFwiLi9tb2R1bGVzL2Jvb2tpbmdCdXR0b25cIjtcbmltcG9ydCAqIGFzIENoaWxkIGZyb20gJy4vbW9kdWxlcy9jaGlsZCc7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgKCkgPT4ge1xuICAgIC8vIEluamVjdCBKU0MgKGpRdWVyeSBTZWF0IENoYXJ0cylcbiAgICAvLyBJbmplY3QgQ1NTIGZvciBKU0MsIGNoaWxkIGFuZCBqUXVlcnkgZGlhbG9nXG4gICAgVXRpbHMuaW5qZWN0KGNvbmZpZy51cmxKU0NTdGFnaW5nLCBcImpzXCIsIFwiaGVhZFwiKTtcbiAgICBVdGlscy5pbmplY3QoY29uZmlnLnVybENTU0pTQ1N0YWdpbmcsIFwiY3NzXCIsIFwiYm9keVwiKTtcbiAgICBVdGlscy5pbmplY3QoY29uZmlnLnVybENTU0NoaWxkU3RhZ2luZywgXCJjc3NcIiwgXCJib2R5XCIpO1xuICAgIFV0aWxzLmluamVjdChjb25maWcudXJsQ1NTalF1ZXJ5VUksIFwiY3NzXCIsIFwiYm9keVwiKTtcblxuICAgIC8vIFN0YXJ0IG1lc3NhZ2UgaGFuZGxlciB0byBiZSBhYmxlIHRvIHJlY2VpdmUgbWVzc2FnZXMgZnJvbSBwYXJlbnRcbiAgICBDb21tdW5pY2F0aW9uLmxpc3RlblRvTWVzc2FnZXMobWVzc2FnZUhhbmRsZXIpO1xuXG4gICAgLy8gRGl2IHdpdGggSUQgXCJjb250YWluZXJTZWF0bWFwXCIgaXMgbm90IHlldCByZWFkeSwgd2FpdCBmb3IgaXQsIHRoZW4gZGlzcGxheSBzZWF0bWFwIGJ1dHRvbiBvbiB0cnhzdGF0ZSAyMFxuICAgIFV0aWxzLndhaXRGb3JTZWF0bWFwKEJvb2tpbmdCdG4uc2hvd1NlYXRtYXBCdG5QYXJlbnQpO1xuXG4gICAgLy8gTW9kYWwgb3ZlcmxheSBmb3IgY2FydCBpcyBub3QgeWV0IHJlYWR5LCB3YWl0IGZvciBpdCwgdGhlbiBpbml0aWFsaXplXG4gICAgVXRpbHMud2FpdEZvckVsZW1lbnQoXCIjbW9kYWxDYXJ0LW92ZXJsYXlcIiwgQ2FydC5pbml0TW9kYWxDYXJ0KTtcblxuICAgIC8vIEFkZCBldmVudCBsaXN0ZW5lcnNcbiAgICBFdmVudHMuYWRkQ2xvc2VNb2RhbCgpO1xuICAgIEV2ZW50cy5hZGRNb2RhbENhcnQoKTtcbiAgICBFdmVudHMuYWRkRHJvcGRvd25TZWF0bWFwKCk7XG5cbn0pO1xuXG4vLyBIaWRlIGhlYWRlciB3aGVuIGhlaWdodCBvZiB3aW5kb3cgaXMgc21hbGxlciB0aGFuIC4uLlxuLy8gTm90ZTogQ2Fubm90IGRldGVybWluZSB3aWR0aCBvZiBpbm5lciBpZnJhbWUsIHRoZXJlZm9yZSBuZWVkIHRvIHVzZSB3aW5kb3cuaW5uZXJIZWlnaHRcbndpbmRvdy5vbnJlc2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBwYW56b29tID0gY29uZmlnLnN0YXRlLnBhbnpvb207XG4gICAgY29uc3QgaW5uZXJIZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XG5cbiAgICBpZiAoaW5uZXJIZWlnaHQgPCA1NzYpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJzbWFsbFwiKTtcbiAgICAgICAgalF1ZXJ5KFwiI2NvbnRhaW5lckV2ZW50SW5mb1Jvd1wiKS5oaWRlKCk7XG4gICAgICAgIHBhbnpvb20/LnJlc2V0KCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGlubmVySGVpZ2h0ID49IDU3Nikge1xuICAgICAgICBqUXVlcnkoXCIjY29udGFpbmVyRXZlbnRJbmZvUm93XCIpLnNob3coKTtcbiAgICAgICAgcGFuem9vbT8ucmVzZXQoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIG1lc3NhZ2VIYW5kbGVyKGluRTogYW55KSB7XG4gICAgaWYgKHR5cGVvZiAoaW5FLmRhdGEpICE9PSAnc3RyaW5nJylcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgY29uc3QgZGF0YTogSS5NZXNzYWdlID0gSlNPTi5wYXJzZShpbkUuZGF0YSk7XG5cbiAgICBjb25zb2xlLmxvZyhgY2hpbGQ6IHJlY2VpdmVkIGZyb20gJHtkYXRhLmZyb219YCk7XG4gICAgY29uc29sZS5sb2coZGF0YSk7XG5cbiAgICBzd2l0Y2ggKGRhdGEuZXZlbnQpIHtcbiAgICAgICAgY2FzZSBcInBhcmVudF9pbml0X3ZlbnVlXCI6IHtcbiAgICAgICAgICAgIENoaWxkLmluaXRWZW51ZSgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBcInBhcmVudF9pbml0X3NlbmRWZW51ZVhNTFwiOiB7XG4gICAgICAgICAgICBDaGlsZC5pbml0U2VuZFZlbnVlWE1MKGluRSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIFwicGFyZW50X2luaXRfc2VuZElucHV0c1dpdGhWYWx1ZVwiOiB7XG4gICAgICAgICAgICBDaGlsZC5pbml0U2VuZElucHV0c1dpdGhWYWx1ZShpbkUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBcInBhcmVudF9zZW5kU2VhdG1hcFhNTFwiOiB7XG4gICAgICAgICAgICBDaGlsZC5zZW5kU2VhdG1hcFhNTChpbkUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBcInBhcmVudF9zZW5kQ2hlY2tvdXRSZXNwb25zZVwiOiB7ICAgICAgICAgXG4gICAgICAgICAgICBDaGlsZC5zZW5kQ2hlY2tvdXRSZXNwb25zZShpbkUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cbn0iXX0=
|