//请了解比特流 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.AV = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 3); return this.bitPosition = pos & 7; }; Bitstream.prototype.rewind = function(bits) { var pos; pos = this.bitPosition - bits; this.stream.rewind(Math.abs(pos >> 3)); return this.bitPosition = pos & 7; }; Bitstream.prototype.seek = function(offset) { var curOffset; curOffset = this.offset(); if (offset > curOffset) { return this.advance(offset - curOffset); } else if (offset < curOffset) { return this.rewind(curOffset - offset); } }; Bitstream.prototype.align = function() { if (this.bitPosition !== 0) { this.bitPosition = 0; return this.stream.advance(1); } }; //Bitstream原型读取 Bitstream.prototype.read = function(bits, signed) { var a, a0, a1, a2, a3, a4, mBits; if (bits === 0) { return 0; } mBits = bits + this.bitPosition; if (mBits <= 8) { a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits); } else if (mBits <= 16) { a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits); } else if (mBits <= 24) { a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits); } else if (mBits <= 32) { a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits); } else if (mBits <= 40) { a0 = this.stream.peekUInt8(0) * 0x0100000000; a1 = this.stream.peekUInt8(1) << 24 >>> 0; a2 = this.stream.peekUInt8(2) << 16; a3 = this.stream.peekUInt8(3) << 8; a4 = this.stream.peekUInt8(4); a = a0 + a1 + a2 + a3 + a4; a %= Math.pow(2, 40 - this.bitPosition); a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits)); } else { throw new Error("Too many bits!"); } if (signed) { if (mBits < 32) { if (a >>> (bits - 1)) { a = ((1 << bits >>> 0) - a) * -1; } } else { if (a / Math.pow(2, bits - 1) | 0) { a = (Math.pow(2, bits) - a) * -1; } } } this.advance(bits); return a; }; // 每一段的查 Bitstream.prototype.peek = function(bits, signed) { var a, a0, a1, a2, a3, a4, mBits; if (bits === 0) { return 0; } mBits = bits + this.bitPosition; if (mBits <= 8) { a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits); } else if (mBits <= 16) { a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits); } else if (mBits <= 24) { a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits); } else if (mBits <= 32) { a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits); } else if (mBits <= 40) { a0 = this.stream.peekUInt8(0) * 0x0100000000; a1 = this.stream.peekUInt8(1) << 24 >>> 0; a2 = this.stream.peekUInt8(2) << 16; a3 = this.stream.peekUInt8(3) << 8; a4 = this.stream.peekUInt8(4); a = a0 + a1 + a2 + a3 + a4; a %= Math.pow(2, 40 - this.bitPosition); a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits)); } else { throw new Error("Too many bits!"); } if (signed) { if (mBits < 32) { if (a >>> (bits - 1)) { a = ((1 << bits >>> 0) - a) * -1; } } else { if (a / Math.pow(2, bits - 1) | 0) { a = (Math.pow(2, bits) - a) * -1; } } } return a; }; //读LSB 8 16 24 32 等 Bitstream.prototype.readLSB = function(bits, signed) { var a, mBits; if (bits === 0) { return 0; } if (bits > 40) { throw new Error("Too many bits!"); } mBits = bits + this.bitPosition; a = (this.stream.peekUInt8(0)) >>> this.bitPosition; if (mBits > 8) { a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition); } if (mBits > 16) { a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition); } if (mBits > 24) { a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0; } if (mBits > 32) { a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition); } if (mBits >= 32) { a %= Math.pow(2, bits); } else { a &= (1 << bits) - 1; } if (signed) { if (mBits < 32) { if (a >>> (bits - 1)) { a = ((1 << bits >>> 0) - a) * -1; } } else { if (a / Math.pow(2, bits - 1) | 0) { a = (Math.pow(2, bits) - a) * -1; } } } this.advance(bits); return a; }; Bitstream.prototype.peekLSB = function(bits, signed) { var a, mBits; if (bits === 0) { return 0; } if (bits > 40) { throw new Error("Too many bits!"); } mBits = bits + this.bitPosition; a = (this.stream.peekUInt8(0)) >>> this.bitPosition; if (mBits > 8) { a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition); } if (mBits > 16) { a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition); } if (mBits > 24) { a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0; } if (mBits > 32) { a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition); } if (mBits >= 32) { a %= Math.pow(2, bits); } else { a &= (1 << bits) - 1; } if (signed) { if (mBits < 32) { if (a >>> (bits - 1)) { a = ((1 << bits >>> 0) - a) * -1; } } else { if (a / Math.pow(2, bits - 1) | 0) { a = (Math.pow(2, bits) - a) * -1; } } } return a; }; return Bitstream; })(); module.exports = Bitstream; }).call(this); },{}],6:[function(require,module,exports){ (function (global){ (function() { var AVBuffer; AVBuffer = (function() { var BlobBuilder, URL; function AVBuffer(input) { var ref; if (input instanceof Uint8Array) { this.data = input; } else if (input instanceof ArrayBuffer || Array.isArray(input) || typeof input === 'number' || ((ref = global.Buffer) != null ? ref.isBuffer(input) : void 0)) { this.data = new Uint8Array(input); } else if (input.buffer instanceof ArrayBuffer) { this.data = new Uint8Array(input.buffer, input.byteOffset, input.length * input.BYTES_PER_ELEMENT); } else if (input instanceof AVBuffer) { this.data = input.data; } else { throw new Error("Constructing buffer with unknown type.构造未知类型的缓冲区"); } this.length = this.data.length; this.next = null; this.prev = null; } AVBuffer.allocate = function(size) { return new AVBuffer(size); }; AVBuffer.prototype.copy = function() { return new AVBuffer(new Uint8Array(this.data)); }; AVBuffer.prototype.slice = function(position, length) { if (length == null) { length = this.length; } if (position === 0 && length >= this.length) { return new AVBuffer(this.data); } else { return new AVBuffer(this.data.subarray(position, position + length)); } }; BlobBuilder = global.BlobBuilder || global.MozBlobBuilder || global.WebKitBlobBuilder; URL = global.URL || global.webkitURL || global.mozURL; AVBuffer.makeBlob = function(data, type) { var bb; if (type == null) { type = 'application/octet-stream'; } try { return new Blob([data], { type: type }); } catch (undefined) {} if (BlobBuilder != null) { bb = new BlobBuilder; bb.append(data); return bb.getBlob(type); } return null; }; AVBuffer.makeBlobURL = function(data, type) { return URL != null ? URL.createObjectURL(this.makeBlob(data, type)) : void 0; }; AVBuffer.revokeBlobURL = function(url) { return URL != null ? URL.revokeObjectURL(url) : void 0; }; AVBuffer.prototype.toBlob = function() { return AVBuffer.makeBlob(this.data.buffer); }; AVBuffer.prototype.toBlobURL = function() { return AVBuffer.makeBlobURL(this.data.buffer); }; return AVBuffer; })(); module.exports = AVBuffer; }).call(this); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],7:[function(require,module,exports){ (function() { var BufferList; BufferList = (function() { function BufferList() { this.first = null; this.last = null; this.numBuffers = 0; this.availableBytes = 0; this.availableBuffers = 0; } BufferList.prototype.copy = function() { var result; result = new BufferList; result.first = this.first; result.last = this.last; result.numBuffers = this.numBuffers; result.availableBytes = this.availableBytes; result.availableBuffers = this.availableBuffers; return result; }; BufferList.prototype.append = function(buffer) { var ref; buffer.prev = this.last; if ((ref = this.last) != null) { ref.next = buffer; } this.last = buffer; if (this.first == null) { this.first = buffer; } this.availableBytes += buffer.length; this.availableBuffers++; return this.numBuffers++; }; BufferList.prototype.advance = function() { if (this.first) { this.availableBytes -= this.first.length; this.availableBuffers--; this.first = this.first.next; return this.first != null; } return false; }; BufferList.prototype.rewind = function() { var ref; if (this.first && !this.first.prev) { return false; } this.first = ((ref = this.first) != null ? ref.prev : void 0) || this.last; if (this.first) { this.availableBytes += this.first.length; this.availableBuffers++; } return this.first != null; }; BufferList.prototype.reset = function() { var results; results = []; while (this.rewind()) { continue; } return results; }; return BufferList; })(); module.exports = BufferList; }).call(this); },{}],8:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var Base, EventEmitter, 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, slice = [].slice; Base = require('./base'); EventEmitter = (function(superClass) { extend(EventEmitter, superClass); function EventEmitter() { return EventEmitter.__super__.constructor.apply(this, arguments); } EventEmitter.prototype.on = function(event, fn) { var base; if (this.events == null) { this.events = {}; } if ((base = this.events)[event] == null) { base[event] = []; } return this.events[event].push(fn); }; EventEmitter.prototype.off = function(event, fn) { var events, index, ref; if (this.events == null) { return; } if ((ref = this.events) != null ? ref[event] : void 0) { if (fn != null) { index = this.events[event].indexOf(fn); if (~index) { return this.events[event].splice(index, 1); } } else { return this.events[event]; } } else if (event == null) { return events = {}; } }; EventEmitter.prototype.once = function(event, fn) { var cb; return this.on(event, cb = function() { this.off(event, cb); return fn.apply(this, arguments); }); }; EventEmitter.prototype.emit = function() { var args, event, fn, i, len, ref, ref1; event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; if (!((ref = this.events) != null ? ref[event] : void 0)) { return; } ref1 = this.events[event].slice(); for (i = 0, len = ref1.length; i < len; i++) { fn = ref1[i]; fn.apply(this, args); } }; return EventEmitter; })(Base); module.exports = EventEmitter; }).call(this); },{"./base":4}],9:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var AVBuffer, BufferList, Stream, UnderflowError; BufferList = require('./bufferlist'); AVBuffer = require('./buffer'); UnderflowError = require('./underflow'); Stream = (function() { var buf, decodeString, float32, float64, float64Fallback, float80, int16, int32, int8, nativeEndian, uint16, uint32, uint8; buf = new ArrayBuffer(16); uint8 = new Uint8Array(buf); int8 = new Int8Array(buf); uint16 = new Uint16Array(buf); int16 = new Int16Array(buf); uint32 = new Uint32Array(buf); int32 = new Int32Array(buf); float32 = new Float32Array(buf); if (typeof Float64Array !== "undefined" && Float64Array !== null) { float64 = new Float64Array(buf); } nativeEndian = new Uint16Array(new Uint8Array([0x12, 0x34]).buffer)[0] === 0x3412; function Stream(list1) { this.list = list1; this.localOffset = 0; this.offset = 0; } Stream.fromBuffer = function(buffer) { var list; list = new BufferList; list.append(buffer); return new Stream(list); }; Stream.prototype.copy = function() { var result; result = new Stream(this.list.copy()); result.localOffset = this.localOffset; result.offset = this.offset; return result; }; Stream.prototype.available = function(bytes) { return bytes <= this.list.availableBytes - this.localOffset; }; Stream.prototype.remainingBytes = function() { return this.list.availableBytes - this.localOffset; }; Stream.prototype.advance = function(bytes) { if (!this.available(bytes)) { throw new UnderflowError(); } this.localOffset += bytes; this.offset += bytes; while (this.list.first && this.localOffset >= this.list.first.length) { this.localOffset -= this.list.first.length; this.list.advance(); } return this; }; Stream.prototype.rewind = function(bytes) { if (bytes > this.offset) { throw new UnderflowError(); } if (!this.list.first) { this.list.rewind(); this.localOffset = this.list.first.length; } this.localOffset -= bytes; this.offset -= bytes; while (this.list.first.prev && this.localOffset < 0) { this.list.rewind(); this.localOffset += this.list.first.length; } return this; }; Stream.prototype.seek = function(position) { if (position > this.offset) { return this.advance(position - this.offset); } else if (position < this.offset) { return this.rewind(this.offset - position); } }; Stream.prototype.readUInt8 = function() { var a; if (!this.available(1)) { throw new UnderflowError(); } a = this.list.first.data[this.localOffset]; this.localOffset += 1; this.offset += 1; if (this.localOffset === this.list.first.length) { this.localOffset = 0; this.list.advance(); } return a; }; Stream.prototype.peekUInt8 = function(offset) { var buffer; if (offset == null) { offset = 0; } if (!this.available(offset + 1)) { throw new UnderflowError(); } offset = this.localOffset + offset; buffer = this.list.first; while (buffer) { if (buffer.length > offset) { return buffer.data[offset]; } offset -= buffer.length; buffer = buffer.next; } return 0; }; Stream.prototype.read = function(bytes, littleEndian) { var i, j, k, ref, ref1; if (littleEndian == null) { littleEndian = false; } if (littleEndian === nativeEndian) { for (i = j = 0, ref = bytes; j < ref; i = j += 1) { uint8[i] = this.readUInt8(); } } else { for (i = k = ref1 = bytes - 1; k >= 0; i = k += -1) { uint8[i] = this.readUInt8(); } } }; Stream.prototype.peek = function(bytes, offset, littleEndian) { var i, j, k, ref, ref1; if (littleEndian == null) { littleEndian = false; } if (littleEndian === nativeEndian) { for (i = j = 0, ref = bytes; j < ref; i = j += 1) { uint8[i] = this.peekUInt8(offset + i); } } else { for (i = k = 0, ref1 = bytes; k < ref1; i = k += 1) { uint8[bytes - i - 1] = this.peekUInt8(offset + i); } } }; Stream.prototype.readInt8 = function() { this.read(1); return int8[0]; }; Stream.prototype.peekInt8 = function(offset) { if (offset == null) { offset = 0; } this.peek(1, offset); return int8[0]; }; Stream.prototype.readUInt16 = function(littleEndian) { this.read(2, littleEndian); return uint16[0]; }; Stream.prototype.peekUInt16 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(2, offset, littleEndian); return uint16[0]; }; Stream.prototype.readInt16 = function(littleEndian) { this.read(2, littleEndian); return int16[0]; }; Stream.prototype.peekInt16 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(2, offset, littleEndian); return int16[0]; }; Stream.prototype.readUInt24 = function(littleEndian) { if (littleEndian) { return this.readUInt16(true) + (this.readUInt8() << 16); } else { return (this.readUInt16() << 8) + this.readUInt8(); } }; Stream.prototype.peekUInt24 = function(offset, littleEndian) { if (offset == null) { offset = 0; } if (littleEndian) { return this.peekUInt16(offset, true) + (this.peekUInt8(offset + 2) << 16); } else { return (this.peekUInt16(offset) << 8) + this.peekUInt8(offset + 2); } }; Stream.prototype.readInt24 = function(littleEndian) { if (littleEndian) { return this.readUInt16(true) + (this.readInt8() << 16); } else { return (this.readInt16() << 8) + this.readUInt8(); } }; Stream.prototype.peekInt24 = function(offset, littleEndian) { if (offset == null) { offset = 0; } if (littleEndian) { return this.peekUInt16(offset, true) + (this.peekInt8(offset + 2) << 16); } else { return (this.peekInt16(offset) << 8) + this.peekUInt8(offset + 2); } }; Stream.prototype.readUInt32 = function(littleEndian) { this.read(4, littleEndian); return uint32[0]; }; Stream.prototype.peekUInt32 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(4, offset, littleEndian); return uint32[0]; }; Stream.prototype.readInt32 = function(littleEndian) { this.read(4, littleEndian); return int32[0]; }; Stream.prototype.peekInt32 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(4, offset, littleEndian); return int32[0]; }; Stream.prototype.readFloat32 = function(littleEndian) { this.read(4, littleEndian); return float32[0]; }; Stream.prototype.peekFloat32 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(4, offset, littleEndian); return float32[0]; }; Stream.prototype.readFloat64 = function(littleEndian) { this.read(8, littleEndian); if (float64) { return float64[0]; } else { return float64Fallback(); } }; float64Fallback = function() { var exp, frac, high, low, out, sign; low = uint32[0], high = uint32[1]; if (!high || high === 0x80000000) { return 0.0; } sign = 1 - (high >>> 31) * 2; exp = (high >>> 20) & 0x7ff; frac = high & 0xfffff; if (exp === 0x7ff) { if (frac) { return NaN; } return sign * Infinity; } exp -= 1023; out = (frac | 0x100000) * Math.pow(2, exp - 20); out += low * Math.pow(2, exp - 52); return sign * out; }; Stream.prototype.peekFloat64 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(8, offset, littleEndian); if (float64) { return float64[0]; } else { return float64Fallback(); } }; Stream.prototype.readFloat80 = function(littleEndian) { this.read(10, littleEndian); return float80(); }; float80 = function() { var a0, a1, exp, high, low, out, sign; high = uint32[0], low = uint32[1]; a0 = uint8[9]; a1 = uint8[8]; sign = 1 - (a0 >>> 7) * 2; exp = ((a0 & 0x7F) << 8) | a1; if (exp === 0 && low === 0 && high === 0) { return 0; } if (exp === 0x7fff) { if (low === 0 && high === 0) { return sign * Infinity; } return NaN; } exp -= 16383; out = low * Math.pow(2, exp - 31); out += high * Math.pow(2, exp - 63); return sign * out; }; Stream.prototype.peekFloat80 = function(offset, littleEndian) { if (offset == null) { offset = 0; } this.peek(10, offset, littleEndian); return float80(); }; Stream.prototype.readBuffer = function(length) { var i, j, ref, result, to; result = AVBuffer.allocate(length); to = result.data; for (i = j = 0, ref = length; j < ref; i = j += 1) { to[i] = this.readUInt8(); } return result; }; Stream.prototype.peekBuffer = function(offset, length) { var i, j, ref, result, to; if (offset == null) { offset = 0; } result = AVBuffer.allocate(length); to = result.data; for (i = j = 0, ref = length; j < ref; i = j += 1) { to[i] = this.peekUInt8(offset + i); } return result; }; Stream.prototype.readSingleBuffer = function(length) { var result; result = this.list.first.slice(this.localOffset, length); this.advance(result.length); return result; }; Stream.prototype.peekSingleBuffer = function(offset, length) { var result; result = this.list.first.slice(this.localOffset + offset, length); return result; }; Stream.prototype.readString = function(length, encoding) { if (encoding == null) { encoding = 'ascii'; } return decodeString.call(this, 0, length, encoding, true); }; Stream.prototype.peekString = function(offset, length, encoding) { if (offset == null) { offset = 0; } if (encoding == null) { encoding = 'ascii'; } return decodeString.call(this, offset, length, encoding, false); }; decodeString = function(offset, length, encoding, advance) { var b1, b2, b3, b4, bom, c, end, littleEndian, nullEnd, pt, result, w1, w2; encoding = encoding.toLowerCase(); nullEnd = length === null ? 0 : -1; if (length == null) { length = Infinity; } end = offset + length; result = ''; switch (encoding) { case 'ascii': case 'latin1': while (offset < end && (c = this.peekUInt8(offset++)) !== nullEnd) { result += String.fromCharCode(c); } break; case 'utf8': case 'utf-8': while (offset < end && (b1 = this.peekUInt8(offset++)) !== nullEnd) { if ((b1 & 0x80) === 0) { result += String.fromCharCode(b1); } else if ((b1 & 0xe0) === 0xc0) { b2 = this.peekUInt8(offset++) & 0x3f; result += String.fromCharCode(((b1 & 0x1f) << 6) | b2); } else if ((b1 & 0xf0) === 0xe0) { b2 = this.peekUInt8(offset++) & 0x3f; b3 = this.peekUInt8(offset++) & 0x3f; result += String.fromCharCode(((b1 & 0x0f) << 12) | (b2 << 6) | b3); } else if ((b1 & 0xf8) === 0xf0) { b2 = this.peekUInt8(offset++) & 0x3f; b3 = this.peekUInt8(offset++) & 0x3f; b4 = this.peekUInt8(offset++) & 0x3f; pt = (((b1 & 0x0f) << 18) | (b2 << 12) | (b3 << 6) | b4) - 0x10000; result += String.fromCharCode(0xd800 + (pt >> 10), 0xdc00 + (pt & 0x3ff)); } } break; case 'utf16-be': case 'utf16be': case 'utf16le': case 'utf16-le': case 'utf16bom': case 'utf16-bom': switch (encoding) { case 'utf16be': case 'utf16-be': littleEndian = false; break; case 'utf16le': case 'utf16-le': littleEndian = true; break; case 'utf16bom': case 'utf16-bom': if (length < 2 || (bom = this.peekUInt16(offset)) === nullEnd) { if (advance) { this.advance(offset += 2); } return result; } littleEndian = bom === 0xfffe; offset += 2; } while (offset < end && (w1 = this.peekUInt16(offset, littleEndian)) !== nullEnd) { offset += 2; if (w1 < 0xd800 || w1 > 0xdfff) { result += String.fromCharCode(w1); } else { if (w1 > 0xdbff) { throw new Error("Invalid utf16 sequence."); } w2 = this.peekUInt16(offset, littleEndian); if (w2 < 0xdc00 || w2 > 0xdfff) { throw new Error("Invalid utf16 sequence."); } result += String.fromCharCode(w1, w2); offset += 2; } } if (w1 === nullEnd) { offset += 2; } break; default: throw new Error("Unknown encoding: " + encoding); } if (advance) { this.advance(offset); } return result; }; return Stream; })(); module.exports = Stream; }).call(this); },{"./buffer":6,"./bufferlist":7,"./underflow":10}],10:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var UnderflowError, 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; UnderflowError = (function(superClass) { extend(UnderflowError, superClass); function UnderflowError() { UnderflowError.__super__.constructor.apply(this, arguments); this.name = 'UnderflowError'; this.stack = new Error().stack; } return UnderflowError; })(Error); module.exports = UnderflowError; }).call(this); },{}],11:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var Bitstream, BufferList, Decoder, EventEmitter, Stream, UnderflowError, 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; EventEmitter = require('./core/events'); BufferList = require('./core/bufferlist'); Stream = require('./core/stream'); Bitstream = require('./core/bitstream'); UnderflowError = require('./core/underflow'); Decoder = (function(superClass) { var codecs; extend(Decoder, superClass); function Decoder(demuxer, format) { var list; this.demuxer = demuxer; this.format = format; list = new BufferList; this.stream = new Stream(list); this.bitstream = new Bitstream(this.stream); this.receivedFinalBuffer = false; this.waiting = false; this.demuxer.on('cookie', (function(_this) { return function(cookie) { var error, error1; try { return _this.setCookie(cookie); } catch (error1) { error = error1; return _this.emit('error', error); } }; })(this)); this.demuxer.on('data', (function(_this) { return function(chunk) { list.append(chunk); if (_this.waiting) { return _this.decode(); } }; })(this)); this.demuxer.on('end', (function(_this) { return function() { _this.receivedFinalBuffer = true; if (_this.waiting) { return _this.decode(); } }; })(this)); this.init(); } Decoder.prototype.init = function() {}; Decoder.prototype.setCookie = function(cookie) {}; Decoder.prototype.readChunk = function() {}; Decoder.prototype.decode = function() { var error, error1, offset, packet; this.waiting = !this.receivedFinalBuffer; offset = this.bitstream.offset(); try { packet = this.readChunk(); } catch (error1) { error = error1; if (!(error instanceof UnderflowError)) { this.emit('error', error); return false; } } if (packet) { this.emit('data', packet); if (this.receivedFinalBuffer) { this.emit('end'); } return true; } else if (!this.receivedFinalBuffer) { this.bitstream.seek(offset); this.waiting = true; } else { this.emit('end'); } return false; }; Decoder.prototype.seek = function(timestamp) { var seekPoint; seekPoint = this.demuxer.seek(timestamp); this.stream.seek(seekPoint.offset); return seekPoint.timestamp; }; codecs = {}; Decoder.register = function(id, decoder) { return codecs[id] = decoder; }; Decoder.find = function(id) { return codecs[id] || null; }; return Decoder; })(EventEmitter); module.exports = Decoder; }).call(this); },{"./core/bitstream":5,"./core/bufferlist":7,"./core/events":8,"./core/stream":9,"./core/underflow":10}],12:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var Decoder, LPCMDecoder, 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; Decoder = require('../decoder'); LPCMDecoder = (function(superClass) { extend(LPCMDecoder, superClass); function LPCMDecoder() { this.readChunk = bind(this.readChunk, this); return LPCMDecoder.__super__.constructor.apply(this, arguments); } Decoder.register('lpcm', LPCMDecoder); LPCMDecoder.prototype.readChunk = function() { var chunkSize, i, j, k, l, littleEndian, m, n, o, output, ref, ref1, ref2, ref3, ref4, ref5, samples, stream; stream = this.stream; littleEndian = this.format.littleEndian; chunkSize = Math.min(4096, stream.remainingBytes()); samples = chunkSize / (this.format.bitsPerChannel / 8) | 0; if (chunkSize < this.format.bitsPerChannel / 8) { return null; } if (this.format.floatingPoint) { switch (this.format.bitsPerChannel) { case 32: output = new Float32Array(samples); for (i = j = 0, ref = samples; j < ref; i = j += 1) { output[i] = stream.readFloat32(littleEndian); } break; case 64: output = new Float64Array(samples); for (i = k = 0, ref1 = samples; k < ref1; i = k += 1) { output[i] = stream.readFloat64(littleEndian); } break; default: throw new Error('Unsupported bit depth.不支持的位深度'); } } else { switch (this.format.bitsPerChannel) { case 8: output = new Int8Array(samples); for (i = l = 0, ref2 = samples; l < ref2; i = l += 1) { output[i] = stream.readInt8(); } break; case 16: output = new Int16Array(samples); for (i = m = 0, ref3 = samples; m < ref3; i = m += 1) { output[i] = stream.readInt16(littleEndian); } break; case 24: output = new Int32Array(samples); for (i = n = 0, ref4 = samples; n < ref4; i = n += 1) { output[i] = stream.readInt24(littleEndian); } break; case 32: output = new Int32Array(samples); for (i = o = 0, ref5 = samples; o < ref5; i = o += 1) { output[i] = stream.readInt32(littleEndian); } break; default: throw new Error('Unsupported bit depth.'); } } return output; }; return LPCMDecoder; })(Decoder); }).call(this); },{"../decoder":11}],13:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var Decoder, XLAWDecoder, 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; Decoder = require('../decoder'); XLAWDecoder = (function(superClass) { var BIAS, QUANT_MASK, SEG_MASK, SEG_SHIFT, SIGN_BIT; extend(XLAWDecoder, superClass); function XLAWDecoder() { this.readChunk = bind(this.readChunk, this); return XLAWDecoder.__super__.constructor.apply(this, arguments); } Decoder.register('ulaw', XLAWDecoder); Decoder.register('alaw', XLAWDecoder); SIGN_BIT = 0x80; QUANT_MASK = 0xf; SEG_SHIFT = 4; SEG_MASK = 0x70; BIAS = 0x84; XLAWDecoder.prototype.init = function() { var i, j, k, seg, t, table, val; this.format.bitsPerChannel = 16; this.table = table = new Int16Array(256); if (this.format.formatID === 'ulaw') { for (i = j = 0; j < 256; i = ++j) { val = ~i; t = ((val & QUANT_MASK) << 3) + BIAS; t <<= (val & SEG_MASK) >>> SEG_SHIFT; table[i] = val & SIGN_BIT ? BIAS - t : t - BIAS; } } else { for (i = k = 0; k < 256; i = ++k) { val = i ^ 0x55; t = val & QUANT_MASK; seg = (val & SEG_MASK) >>> SEG_SHIFT; if (seg) { t = (t + t + 1 + 32) << (seg + 2); } else { t = (t + t + 1) << 3; } table[i] = val & SIGN_BIT ? t : -t; } } }; XLAWDecoder.prototype.readChunk = function() { var i, j, output, ref, samples, stream, table; stream = this.stream, table = this.table; samples = Math.min(4096, this.stream.remainingBytes()); if (samples === 0) { return; } output = new Int16Array(samples); for (i = j = 0, ref = samples; j < ref; i = j += 1) { output[i] = table[stream.readUInt8()]; } return output; }; return XLAWDecoder; })(Decoder); }).call(this); },{"../decoder":11}],14:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var BufferList, Demuxer, EventEmitter, Stream, 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; EventEmitter = require('./core/events'); BufferList = require('./core/bufferlist'); Stream = require('./core/stream'); Demuxer = (function(superClass) { var formats; extend(Demuxer, superClass); Demuxer.probe = function(buffer) { return false; }; function Demuxer(source, chunk) { var list, received; list = new BufferList; list.append(chunk); this.stream = new Stream(list); received = false; source.on('data', (function(_this) { return function(chunk) { var e, error; received = true; list.append(chunk); try { return _this.readChunk(chunk); } catch (error) { e = error; return _this.emit('error', e); } }; })(this)); source.on('error', (function(_this) { return function(err) { return _this.emit('error', err); }; })(this)); source.on('end', (function(_this) { return function() { if (!received) { _this.readChunk(chunk); } return _this.emit('end'); }; })(this)); this.seekPoints = []; this.init(); } Demuxer.prototype.init = function() {}; Demuxer.prototype.readChunk = function(chunk) {}; Demuxer.prototype.addSeekPoint = function(offset, timestamp) { var index; index = this.searchTimestamp(timestamp); return this.seekPoints.splice(index, 0, { offset: offset, timestamp: timestamp }); }; Demuxer.prototype.searchTimestamp = function(timestamp, backward) { var high, low, mid, time; low = 0; high = this.seekPoints.length; if (high > 0 && this.seekPoints[high - 1].timestamp < timestamp) { return high; } while (low < high) { mid = (low + high) >> 1; time = this.seekPoints[mid].timestamp; if (time < timestamp) { low = mid + 1; } else if (time >= timestamp) { high = mid; } } if (high > this.seekPoints.length) { high = this.seekPoints.length; } return high; }; Demuxer.prototype.seek = function(timestamp) { var index, seekPoint; if (this.format && this.format.framesPerPacket > 0 && this.format.bytesPerPacket > 0) { seekPoint = { timestamp: timestamp, offset: this.format.bytesPerPacket * timestamp / this.format.framesPerPacket }; return seekPoint; } else { index = this.searchTimestamp(timestamp); return this.seekPoints[index]; } }; formats = []; Demuxer.register = function(demuxer) { return formats.push(demuxer); }; Demuxer.find = function(buffer) { var e, error, format, i, len, offset, stream; stream = Stream.fromBuffer(buffer); for (i = 0, len = formats.length; i < len; i++) { format = formats[i]; offset = stream.offset; try { if (format.probe(stream)) { return format; } } catch (error) { e = error; } stream.seek(offset); } return null; }; return Demuxer; })(EventEmitter); module.exports = Demuxer; }).call(this); },{"./core/bufferlist":7,"./core/events":8,"./core/stream":9}],15:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var AIFFDemuxer, Demuxer, 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; Demuxer = require('../demuxer'); AIFFDemuxer = (function(superClass) { extend(AIFFDemuxer, superClass); function AIFFDemuxer() { return AIFFDemuxer.__super__.constructor.apply(this, arguments); } Demuxer.register(AIFFDemuxer); AIFFDemuxer.probe = function(buffer) { var ref; return buffer.peekString(0, 4) === 'FORM' && ((ref = buffer.peekString(8, 4)) === 'AIFF' || ref === 'AIFC'); }; AIFFDemuxer.prototype.readChunk = function() { var buffer, format, offset, ref; if (!this.readStart && this.stream.available(12)) { if (this.stream.readString(4) !== 'FORM') { return this.emit('error', 'Invalid AIFF.'); } this.fileSize = this.stream.readUInt32(); this.fileType = this.stream.readString(4); this.readStart = true; if ((ref = this.fileType) !== 'AIFF' && ref !== 'AIFC') { return this.emit('error', 'Invalid AIFF.'); } } while (this.stream.available(1)) { if (!this.readHeaders && this.stream.available(8)) { this.type = this.stream.readString(4); this.len = this.stream.readUInt32(); } switch (this.type) { case 'COMM': if (!this.stream.available(this.len)) { return; } this.format = { formatID: 'lpcm', channelsPerFrame: this.stream.readUInt16(), sampleCount: this.stream.readUInt32(), bitsPerChannel: this.stream.readUInt16(), sampleRate: this.stream.readFloat80(), framesPerPacket: 1, littleEndian: false, floatingPoint: false }; this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame; if (this.fileType === 'AIFC') { format = this.stream.readString(4); this.format.littleEndian = format === 'sowt' && this.format.bitsPerChannel > 8; this.format.floatingPoint = format === 'fl32' || format === 'fl64'; if (format === 'twos' || format === 'sowt' || format === 'fl32' || format === 'fl64' || format === 'NONE') { format = 'lpcm'; } this.format.formatID = format; this.len -= 4; } this.stream.advance(this.len - 18); this.emit('format', this.format); this.emit('duration', this.format.sampleCount / this.format.sampleRate * 1000 | 0); break; case 'SSND': if (!(this.readSSNDHeader && this.stream.available(4))) { offset = this.stream.readUInt32(); this.stream.advance(4); this.stream.advance(offset); this.readSSNDHeader = true; } buffer = this.stream.readSingleBuffer(this.len); this.len -= buffer.length; this.readHeaders = this.len > 0; this.emit('data', buffer); break; default: if (!this.stream.available(this.len)) { return; } this.stream.advance(this.len); } if (this.type !== 'SSND') { this.readHeaders = false; } } }; return AIFFDemuxer; })(Demuxer); }).call(this); },{"../demuxer":14}],16:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var AUDemuxer, Demuxer, 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; Demuxer = require('../demuxer'); AUDemuxer = (function(superClass) { var bps, formats; extend(AUDemuxer, superClass); function AUDemuxer() { return AUDemuxer.__super__.constructor.apply(this, arguments); } Demuxer.register(AUDemuxer); AUDemuxer.probe = function(buffer) { return buffer.peekString(0, 4) === '.snd'; }; bps = [8, 8, 16, 24, 32, 32, 64]; bps[26] = 8; formats = { 1: 'ulaw', 27: 'alaw' }; AUDemuxer.prototype.readChunk = function() { var bytes, dataSize, encoding, size; if (!this.readHeader && this.stream.available(24)) { if (this.stream.readString(4) !== '.snd') { return this.emit('error', 'Invalid AU file.'); } size = this.stream.readUInt32(); dataSize = this.stream.readUInt32(); encoding = this.stream.readUInt32(); this.format = { formatID: formats[encoding] || 'lpcm', littleEndian: false, floatingPoint: encoding === 6 || encoding === 7, bitsPerChannel: bps[encoding - 1], sampleRate: this.stream.readUInt32(), channelsPerFrame: this.stream.readUInt32(), framesPerPacket: 1 }; if (this.format.bitsPerChannel == null) { return this.emit('error', 'Unsupported encoding in AU file.'); } this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame; if (dataSize !== 0xffffffff) { bytes = this.format.bitsPerChannel / 8; this.emit('duration', dataSize / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0); } this.emit('format', this.format); this.readHeader = true; } if (this.readHeader) { while (this.stream.available(1)) { this.emit('data', this.stream.readSingleBuffer(this.stream.remainingBytes())); } } }; return AUDemuxer; })(Demuxer); }).call(this); },{"../demuxer":14}],17:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var CAFDemuxer, Demuxer, M4ADemuxer, 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; Demuxer = require('../demuxer'); M4ADemuxer = require('./m4a'); CAFDemuxer = (function(superClass) { extend(CAFDemuxer, superClass); function CAFDemuxer() { return CAFDemuxer.__super__.constructor.apply(this, arguments); } Demuxer.register(CAFDemuxer); CAFDemuxer.probe = function(buffer) { return buffer.peekString(0, 4) === 'caff'; }; CAFDemuxer.prototype.readChunk = function() { var buffer, byteOffset, cookie, entries, flags, i, j, k, key, metadata, offset, ref, ref1, sampleOffset, value; if (!this.format && this.stream.available(64)) { if (this.stream.readString(4) !== 'caff') { return this.emit('error', "Invalid CAF, does not begin with 'caff'"); } this.stream.advance(4); if (this.stream.readString(4) !== 'desc') { return this.emit('error', "Invalid CAF, 'caff' is not followed by 'desc'"); } if (!(this.stream.readUInt32() === 0 && this.stream.readUInt32() === 32)) { return this.emit('error', "Invalid 'desc' size, should be 32"); } this.format = {}; this.format.sampleRate = this.stream.readFloat64(); this.format.formatID = this.stream.readString(4); flags = this.stream.readUInt32(); if (this.format.formatID === 'lpcm') { this.format.floatingPoint = Boolean(flags & 1); this.format.littleEndian = Boolean(flags & 2); } this.format.bytesPerPacket = this.stream.readUInt32(); this.format.framesPerPacket = this.stream.readUInt32(); this.format.channelsPerFrame = this.stream.readUInt32(); this.format.bitsPerChannel = this.stream.readUInt32(); this.emit('format', this.format); } while (this.stream.available(1)) { if (!this.headerCache) { this.headerCache = { type: this.stream.readString(4), oversize: this.stream.readUInt32() !== 0, size: this.stream.readUInt32() }; if (this.headerCache.oversize) { return this.emit('error', "Holy Shit, an oversized file, not supported in JS"); } } switch (this.headerCache.type) { case 'kuki': if (this.stream.available(this.headerCache.size)) { if (this.format.formatID === 'aac ') { console.log('aac') offset = this.stream.offset + this.headerCache.size; if (cookie = M4ADemuxer.readEsds(this.stream)) { this.emit('cookie', cookie); } this.stream.seek(offset); } else { buffer = this.stream.readBuffer(this.headerCache.size); this.emit('cookie', buffer); } this.headerCache = null; } break; case 'pakt': if (this.stream.available(this.headerCache.size)) { if (this.stream.readUInt32() !== 0) { return this.emit('error', 'Sizes greater than 32 bits are not supported.'); } this.numPackets = this.stream.readUInt32(); if (this.stream.readUInt32() !== 0) { return this.emit('error', 'Sizes greater than 32 bits are not supported.'); } this.numFrames = this.stream.readUInt32(); this.primingFrames = this.stream.readUInt32(); this.remainderFrames = this.stream.readUInt32(); this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0); this.sentDuration = true; byteOffset = 0; sampleOffset = 0; for (i = j = 0, ref = this.numPackets; j < ref; i = j += 1) { this.addSeekPoint(byteOffset, sampleOffset); byteOffset += this.format.bytesPerPacket || M4ADemuxer.readDescrLen(this.stream); sampleOffset += this.format.framesPerPacket || M4ADemuxer.readDescrLen(this.stream); } this.headerCache = null; } break; case 'info': entries = this.stream.readUInt32(); metadata = {}; for (i = k = 0, ref1 = entries; 0 <= ref1 ? k < ref1 : k > ref1; i = 0 <= ref1 ? ++k : --k) { key = this.stream.readString(null); value = this.stream.readString(null); metadata[key] = value; } this.emit('metadata', metadata); this.headerCache = null; break; case 'data': if (!this.sentFirstDataChunk) { this.stream.advance(4); this.headerCache.size -= 4; if (this.format.bytesPerPacket !== 0 && !this.sentDuration) { this.numFrames = this.headerCache.size / this.format.bytesPerPacket; this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0); } this.sentFirstDataChunk = true; } buffer = this.stream.readSingleBuffer(this.headerCache.size); this.headerCache.size -= buffer.length; this.emit('data', buffer); if (this.headerCache.size <= 0) { this.headerCache = null; } break; default: if (this.stream.available(this.headerCache.size)) { this.stream.advance(this.headerCache.size); this.headerCache = null; } } } }; return CAFDemuxer; })(Demuxer); }).call(this); },{"../demuxer":14,"./m4a":18}],18:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var Demuxer, M4ADemuxer, 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, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; Demuxer = require('../demuxer'); M4ADemuxer = (function(superClass) { var BITS_PER_CHANNEL, TYPES, after, atom, atoms, bool, containers, diskTrack, genres, meta, string; extend(M4ADemuxer, superClass); function M4ADemuxer() { return M4ADemuxer.__super__.constructor.apply(this, arguments); } Demuxer.register(M4ADemuxer); TYPES = ['M4A ', 'M4P ', 'M4B ', 'M4V ', 'isom', 'mp42', 'qt ']; M4ADemuxer.probe = function(buffer) { var ref; return buffer.peekString(4, 4) === 'ftyp' && (ref = buffer.peekString(8, 4), indexOf.call(TYPES, ref) >= 0); }; M4ADemuxer.prototype.init = function() { this.atoms = []; this.offsets = []; this.track = null; return this.tracks = []; }; atoms = {}; containers = {}; atom = function(name, fn) { var c, container, k, len1, ref; c = []; ref = name.split('.').slice(0, -1); for (k = 0, len1 = ref.length; k < len1; k++) { container = ref[k]; c.push(container); containers[c.join('.')] = true; } if (atoms[name] == null) { atoms[name] = {}; } return atoms[name].fn = fn; }; after = function(name, fn) { if (atoms[name] == null) { atoms[name] = {}; } return atoms[name].after = fn; }; M4ADemuxer.prototype.readChunk = function() { var handler, path, type; this["break"] = false; while (this.stream.available(1) && !this["break"]) { if (!this.readHeaders) { if (!this.stream.available(8)) { return; } this.len = this.stream.readUInt32() - 8; this.type = this.stream.readString(4); if (this.len === 0) { continue; } this.atoms.push(this.type); this.offsets.push(this.stream.offset + this.len); this.readHeaders = true; } path = this.atoms.join('.'); handler = atoms[path]; if (handler != null ? handler.fn : void 0) { if (!(this.stream.available(this.len) || path === 'mdat')) { return; } handler.fn.call(this); if (path in containers) { this.readHeaders = false; } } else if (path in containers) { this.readHeaders = false; } else { if (!this.stream.available(this.len)) { return; } this.stream.advance(this.len); } while (this.stream.offset >= this.offsets[this.offsets.length - 1]) { handler = atoms[this.atoms.join('.')]; if (handler != null ? handler.after : void 0) { handler.after.call(this); } type = this.atoms.pop(); this.offsets.pop(); this.readHeaders = false; } } }; atom('ftyp', function() { var ref; if (ref = this.stream.readString(4), indexOf.call(TYPES, ref) < 0) { return this.emit('error', 'Not a valid M4A file.'); } return this.stream.advance(this.len - 4); }); atom('moov.trak', function() { this.track = {}; return this.tracks.push(this.track); }); atom('moov.trak.tkhd', function() { this.stream.advance(4); this.stream.advance(8); this.track.id = this.stream.readUInt32(); return this.stream.advance(this.len - 16); }); atom('moov.trak.mdia.hdlr', function() { this.stream.advance(4); this.stream.advance(4); this.track.type = this.stream.readString(4); this.stream.advance(12); return this.stream.advance(this.len - 24); }); atom('moov.trak.mdia.mdhd', function() { this.stream.advance(4); this.stream.advance(8); this.track.timeScale = this.stream.readUInt32(); this.track.duration = this.stream.readUInt32(); return this.stream.advance(4); }); BITS_PER_CHANNEL = { ulaw: 8, alaw: 8, in24: 24, in32: 32, fl32: 32, fl64: 64 }; atom('moov.trak.mdia.minf.stbl.stsd', function() { var format, numEntries, ref, ref1, version; this.stream.advance(4); numEntries = this.stream.readUInt32(); if (this.track.type !== 'soun') { return this.stream.advance(this.len - 8); } if (numEntries !== 1) { return this.emit('error', "Only expecting one entry in sample description atom!"); } this.stream.advance(4); format = this.track.format = {}; format.formatID = this.stream.readString(4); this.stream.advance(6); this.stream.advance(2); version = this.stream.readUInt16(); this.stream.advance(6); format.channelsPerFrame = this.stream.readUInt16(); format.bitsPerChannel = this.stream.readUInt16(); this.stream.advance(4); format.sampleRate = this.stream.readUInt16(); this.stream.advance(2); if (version === 1) { format.framesPerPacket = this.stream.readUInt32(); this.stream.advance(4); format.bytesPerFrame = this.stream.readUInt32(); this.stream.advance(4); } else if (version !== 0) { this.emit('error', 'Unknown version in stsd atom'); } if (BITS_PER_CHANNEL[format.formatID] != null) { format.bitsPerChannel = BITS_PER_CHANNEL[format.formatID]; } format.floatingPoint = (ref = format.formatID) === 'fl32' || ref === 'fl64'; format.littleEndian = format.formatID === 'sowt' && format.bitsPerChannel > 8; if ((ref1 = format.formatID) === 'twos' || ref1 === 'sowt' || ref1 === 'in24' || ref1 === 'in32' || ref1 === 'fl32' || ref1 === 'fl64' || ref1 === 'raw ' || ref1 === 'NONE') { return format.formatID = 'lpcm'; } }); atom('moov.trak.mdia.minf.stbl.stsd.alac', function() { this.stream.advance(4); return this.track.cookie = this.stream.readBuffer(this.len - 4); }); atom('moov.trak.mdia.minf.stbl.stsd.esds', function() { var offset; offset = this.stream.offset + this.len; this.track.cookie = M4ADemuxer.readEsds(this.stream); return this.stream.seek(offset); }); atom('moov.trak.mdia.minf.stbl.stsd.wave.enda', function() { return this.track.format.littleEndian = !!this.stream.readUInt16(); }); M4ADemuxer.readDescrLen = function(stream) { var c, count, len; len = 0; count = 4; while (count--) { c = stream.readUInt8(); len = (len << 7) | (c & 0x7f); if (!(c & 0x80)) { break; } } return len; }; M4ADemuxer.readEsds = function(stream) { var codec_id, flags, len, tag; stream.advance(4); tag = stream.readUInt8(); len = M4ADemuxer.readDescrLen(stream); if (tag === 0x03) { stream.advance(2); flags = stream.readUInt8(); if (flags & 0x80) { stream.advance(2); } if (flags & 0x40) { stream.advance(stream.readUInt8()); } if (flags & 0x20) { stream.advance(2); } } else { stream.advance(2); } tag = stream.readUInt8(); len = M4ADemuxer.readDescrLen(stream); if (tag === 0x04) { codec_id = stream.readUInt8(); stream.advance(1); stream.advance(3); stream.advance(4); stream.advance(4); tag = stream.readUInt8(); len = M4ADemuxer.readDescrLen(stream); if (tag === 0x05) { return stream.readBuffer(len); } } return null; }; atom('moov.trak.mdia.minf.stbl.stts', function() { var entries, i, k, ref; this.stream.advance(4); entries = this.stream.readUInt32(); this.track.stts = []; for (i = k = 0, ref = entries; k < ref; i = k += 1) { this.track.stts[i] = { count: this.stream.readUInt32(), duration: this.stream.readUInt32() }; } return this.setupSeekPoints(); }); atom('moov.trak.mdia.minf.stbl.stsc', function() { var entries, i, k, ref; this.stream.advance(4); entries = this.stream.readUInt32(); this.track.stsc = []; for (i = k = 0, ref = entries; k < ref; i = k += 1) { this.track.stsc[i] = { first: this.stream.readUInt32(), count: this.stream.readUInt32(), id: this.stream.readUInt32() }; } return this.setupSeekPoints(); }); atom('moov.trak.mdia.minf.stbl.stsz', function() { var entries, i, k, ref; this.stream.advance(4); this.track.sampleSize = this.stream.readUInt32(); entries = this.stream.readUInt32(); if (this.track.sampleSize === 0 && entries > 0) { this.track.sampleSizes = []; for (i = k = 0, ref = entries; k < ref; i = k += 1) { this.track.sampleSizes[i] = this.stream.readUInt32(); } } return this.setupSeekPoints(); }); atom('moov.trak.mdia.minf.stbl.stco', function() { var entries, i, k, ref; this.stream.advance(4); entries = this.stream.readUInt32(); this.track.chunkOffsets = []; for (i = k = 0, ref = entries; k < ref; i = k += 1) { this.track.chunkOffsets[i] = this.stream.readUInt32(); } return this.setupSeekPoints(); }); atom('moov.trak.tref.chap', function() { var entries, i, k, ref; entries = this.len >> 2; this.track.chapterTracks = []; for (i = k = 0, ref = entries; k < ref; i = k += 1) { this.track.chapterTracks[i] = this.stream.readUInt32(); } }); M4ADemuxer.prototype.setupSeekPoints = function() { var i, j, k, l, len1, offset, position, ref, ref1, results, sampleIndex, size, stscIndex, sttsIndex, sttsSample, timestamp; if (!((this.track.chunkOffsets != null) && (this.track.stsc != null) && (this.track.sampleSize != null) && (this.track.stts != null))) { return; } stscIndex = 0; sttsIndex = 0; sttsIndex = 0; sttsSample = 0; sampleIndex = 0; offset = 0; timestamp = 0; this.track.seekPoints = []; ref = this.track.chunkOffsets; results = []; for (i = k = 0, len1 = ref.length; k < len1; i = ++k) { position = ref[i]; for (j = l = 0, ref1 = this.track.stsc[stscIndex].count; l < ref1; j = l += 1) { this.track.seekPoints.push({ offset: offset, position: position, timestamp: timestamp }); size = this.track.sampleSize || this.track.sampleSizes[sampleIndex++]; offset += size; position += size; timestamp += this.track.stts[sttsIndex].duration; if (sttsIndex + 1 < this.track.stts.length && ++sttsSample === this.track.stts[sttsIndex].count) { sttsSample = 0; sttsIndex++; } } if (stscIndex + 1 < this.track.stsc.length && i + 1 === this.track.stsc[stscIndex + 1].first) { results.push(stscIndex++); } else { results.push(void 0); } } return results; }; after('moov', function() { var k, len1, ref, track; if (this.mdatOffset != null) { this.stream.seek(this.mdatOffset - 8); } ref = this.tracks; for (k = 0, len1 = ref.length; k < len1; k++) { track = ref[k]; if (!(track.type === 'soun')) { continue; } this.track = track; break; } if (this.track.type !== 'soun') { this.track = null; return this.emit('error', 'No audio tracks in m4a file.'); } this.emit('format', this.track.format); this.emit('duration', this.track.duration / this.track.timeScale * 1000 | 0); if (this.track.cookie) { this.emit('cookie', this.track.cookie); } return this.seekPoints = this.track.seekPoints; }); atom('mdat', function() { var bytes, chunkSize, k, length, numSamples, offset, ref, sample, size; if (!this.startedData) { if (this.mdatOffset == null) { this.mdatOffset = this.stream.offset; } if (this.tracks.length === 0) { bytes = Math.min(this.stream.remainingBytes(), this.len); this.stream.advance(bytes); this.len -= bytes; return; } this.chunkIndex = 0; this.stscIndex = 0; this.sampleIndex = 0; this.tailOffset = 0; this.tailSamples = 0; this.startedData = true; } if (!this.readChapters) { this.readChapters = this.parseChapters(); if (this["break"] = !this.readChapters) { return; } this.stream.seek(this.mdatOffset); } offset = this.track.chunkOffsets[this.chunkIndex] + this.tailOffset; length = 0; if (!this.stream.available(offset - this.stream.offset)) { this["break"] = true; return; } this.stream.seek(offset); while (this.chunkIndex < this.track.chunkOffsets.length) { numSamples = this.track.stsc[this.stscIndex].count - this.tailSamples; chunkSize = 0; for (sample = k = 0, ref = numSamples; k < ref; sample = k += 1) { size = this.track.sampleSize || this.track.sampleSizes[this.sampleIndex]; if (!this.stream.available(length + size)) { break; } length += size; chunkSize += size; this.sampleIndex++; } if (sample < numSamples) { this.tailOffset += chunkSize; this.tailSamples += sample; break; } else { this.chunkIndex++; this.tailOffset = 0; this.tailSamples = 0; if (this.stscIndex + 1 < this.track.stsc.length && this.chunkIndex + 1 === this.track.stsc[this.stscIndex + 1].first) { this.stscIndex++; } if (offset + length !== this.track.chunkOffsets[this.chunkIndex]) { break; } } } if (length > 0) { this.emit('data', this.stream.readBuffer(length)); return this["break"] = this.chunkIndex === this.track.chunkOffsets.length; } else { return this["break"] = true; } }); M4ADemuxer.prototype.parseChapters = function() { var bom, id, k, len, len1, nextTimestamp, point, ref, ref1, ref2, ref3, title, track; if (!(((ref = this.track.chapterTracks) != null ? ref.length : void 0) > 0)) { return true; } id = this.track.chapterTracks[0]; ref1 = this.tracks; for (k = 0, len1 = ref1.length; k < len1; k++) { track = ref1[k]; if (track.id === id) { break; } } if (track.id !== id) { this.emit('error', 'Chapter track does not exist.'); } if (this.chapters == null) { this.chapters = []; } while (this.chapters.length < track.seekPoints.length) { point = track.seekPoints[this.chapters.length]; if (!this.stream.available(point.position - this.stream.offset + 32)) { return false; } this.stream.seek(point.position); len = this.stream.readUInt16(); title = null; if (!this.stream.available(len)) { return false; } if (len > 2) { bom = this.stream.peekUInt16(); if (bom === 0xfeff || bom === 0xfffe) { title = this.stream.readString(len, 'utf16-bom'); } } if (title == null) { title = this.stream.readString(len, 'utf8'); } nextTimestamp = (ref2 = (ref3 = track.seekPoints[this.chapters.length + 1]) != null ? ref3.timestamp : void 0) != null ? ref2 : track.duration; this.chapters.push({ title: title, timestamp: point.timestamp / track.timeScale * 1000 | 0, duration: (nextTimestamp - point.timestamp) / track.timeScale * 1000 | 0 }); } this.emit('chapters', this.chapters); return true; }; atom('moov.udta.meta', function() { this.metadata = {}; return this.stream.advance(4); }); after('moov.udta.meta', function() { return this.emit('metadata', this.metadata); }); meta = function(field, name, fn) { return atom("moov.udta.meta.ilst." + field + ".data", function() { this.stream.advance(8); this.len -= 8; return fn.call(this, name); }); }; string = function(field) { return this.metadata[field] = this.stream.readString(this.len, 'utf8'); }; meta('©alb', 'album', string); meta('©arg', 'arranger', string); meta('©art', 'artist', string); meta('©ART', 'artist', string); meta('aART', 'albumArtist', string); meta('catg', 'category', string); meta('©com', 'composer', string); meta('©cpy', 'copyright', string); meta('cprt', 'copyright', string); meta('©cmt', 'comments', string); meta('©day', 'releaseDate', string); meta('desc', 'description', string); meta('©gen', 'genre', string); meta('©grp', 'grouping', string); meta('©isr', 'ISRC', string); meta('keyw', 'keywords', string); meta('©lab', 'recordLabel', string); meta('ldes', 'longDescription', string); meta('©lyr', 'lyrics', string); meta('©nam', 'title', string); meta('©phg', 'recordingCopyright', string); meta('©prd', 'producer', string); meta('©prf', 'performers', string); meta('purd', 'purchaseDate', string); meta('purl', 'podcastURL', string); meta('©swf', 'songwriter', string); meta('©too', 'encoder', string); meta('©wrt', 'composer', string); meta('covr', 'coverArt', function(field) { return this.metadata[field] = this.stream.readBuffer(this.len); }); genres = ["Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Capella", "Euro-House", "Dance Hall"]; meta('gnre', 'genre', function(field) { return this.metadata[field] = genres[this.stream.readUInt16() - 1]; }); meta('tmpo', 'tempo', function(field) { return this.metadata[field] = this.stream.readUInt16(); }); meta('rtng', 'rating', function(field) { var rating; rating = this.stream.readUInt8(); return this.metadata[field] = rating === 2 ? 'Clean' : rating !== 0 ? 'Explicit' : 'None'; }); diskTrack = function(field) { this.stream.advance(2); this.metadata[field] = this.stream.readUInt16() + ' of ' + this.stream.readUInt16(); return this.stream.advance(this.len - 6); }; meta('disk', 'diskNumber', diskTrack); meta('trkn', 'trackNumber', diskTrack); bool = function(field) { return this.metadata[field] = this.stream.readUInt8() === 1; }; meta('cpil', 'compilation', bool); meta('pcst', 'podcast', bool); meta('pgap', 'gapless', bool); return M4ADemuxer; })(Demuxer); module.exports = M4ADemuxer; }).call(this); },{"../demuxer":14}],19:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var Demuxer, WAVEDemuxer, 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; Demuxer = require('../demuxer'); WAVEDemuxer = (function(superClass) { var formats; extend(WAVEDemuxer, superClass); function WAVEDemuxer() { return WAVEDemuxer.__super__.constructor.apply(this, arguments); } Demuxer.register(WAVEDemuxer); WAVEDemuxer.probe = function(buffer) { return buffer.peekString(0, 4) === 'RIFF' && buffer.peekString(8, 4) === 'WAVE'; }; formats = { 0x0001: 'lpcm', 0x0003: 'lpcm', 0x0006: 'alaw', 0x0007: 'ulaw' }; WAVEDemuxer.prototype.readChunk = function() { var buffer, bytes, encoding; if (!this.readStart && this.stream.available(12)) { if (this.stream.readString(4) !== 'RIFF') { return this.emit('error', 'Invalid WAV file.'); } this.fileSize = this.stream.readUInt32(true); this.readStart = true; if (this.stream.readString(4) !== 'WAVE') { return this.emit('error', 'Invalid WAV file.'); } } while (this.stream.available(1)) { if (!this.readHeaders && this.stream.available(8)) { this.type = this.stream.readString(4); this.len = this.stream.readUInt32(true); } switch (this.type) { case 'fmt ': encoding = this.stream.readUInt16(true); if (!(encoding in formats)) { return this.emit('error', 'Unsupported format in WAV file.'); } this.format = { formatID: formats[encoding], floatingPoint: encoding === 0x0003, littleEndian: formats[encoding] === 'lpcm', channelsPerFrame: this.stream.readUInt16(true), sampleRate: this.stream.readUInt32(true), framesPerPacket: 1 }; this.stream.advance(4); this.stream.advance(2); this.format.bitsPerChannel = this.stream.readUInt16(true); this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame; this.emit('format', this.format); this.stream.advance(this.len - 16); break; case 'data': if (!this.sentDuration) { bytes = this.format.bitsPerChannel / 8; this.emit('duration', this.len / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0); this.sentDuration = true; } buffer = this.stream.readSingleBuffer(this.len); this.len -= buffer.length; this.readHeaders = this.len > 0; this.emit('data', buffer); break; default: if (!this.stream.available(this.len)) { return; } this.stream.advance(this.len); } if (this.type !== 'data') { this.readHeaders = false; } } }; return WAVEDemuxer; })(Demuxer); }).call(this); },{"../demuxer":14}],20:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var AudioDevice, EventEmitter, 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; EventEmitter = require('./core/events'); AudioDevice = (function(superClass) { var devices; extend(AudioDevice, superClass); function AudioDevice(sampleRate1, channels1) { this.sampleRate = sampleRate1; this.channels = channels1; this.updateTime = bind(this.updateTime, this); this.playing = false; this.currentTime = 0; this._lastTime = 0; } AudioDevice.prototype.start = function() { if (this.playing) { return; } this.playing = true; if (this.device == null) { this.device = AudioDevice.create(this.sampleRate, this.channels); } if (!this.device) { throw new Error("No supported audio device found."); } this._lastTime = this.device.getDeviceTime(); this._timer = setInterval(this.updateTime, 200); return this.device.on('refill', this.refill = (function(_this) { return function(buffer) { return _this.emit('refill', buffer); }; })(this)); }; AudioDevice.prototype.stop = function() { if (!this.playing) { return; } this.playing = false; this.device.off('refill', this.refill); return clearInterval(this._timer); }; AudioDevice.prototype.destroy = function() { var ref; this.stop(); return (ref = this.device) != null ? ref.destroy() : void 0; }; AudioDevice.prototype.seek = function(currentTime) { this.currentTime = currentTime; if (this.playing) { this._lastTime = this.device.getDeviceTime(); } return this.emit('timeUpdate', this.currentTime); }; AudioDevice.prototype.updateTime = function() { var time; time = this.device.getDeviceTime(); this.currentTime += (time - this._lastTime) / this.device.sampleRate * 1000 | 0; this._lastTime = time; return this.emit('timeUpdate', this.currentTime); }; devices = []; AudioDevice.register = function(device) { return devices.push(device); }; AudioDevice.create = function(sampleRate, channels) { var device, i, len; for (i = 0, len = devices.length; i < len; i++) { device = devices[i]; if (device.supported) { return new device(sampleRate, channels); } } return null; }; return AudioDevice; })(EventEmitter); module.exports = AudioDevice; }).call(this); },{"./core/events":8}],21:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var AVBuffer, AudioDevice, EventEmitter, MozillaAudioDevice, 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; EventEmitter = require('../core/events'); AudioDevice = require('../device'); AVBuffer = require('../core/buffer'); MozillaAudioDevice = (function(superClass) { var createTimer, destroyTimer; extend(MozillaAudioDevice, superClass); AudioDevice.register(MozillaAudioDevice); MozillaAudioDevice.supported = (typeof Audio !== "undefined" && Audio !== null) && 'mozWriteAudio' in new Audio; function MozillaAudioDevice(sampleRate, channels) { this.sampleRate = sampleRate; this.channels = channels; this.refill = bind(this.refill, this); this.audio = new Audio; this.audio.mozSetup(this.channels, this.sampleRate); this.writePosition = 0; this.prebufferSize = this.sampleRate / 2; this.tail = null; this.timer = createTimer(this.refill, 100); console.log('createTimer>>>',createTimer) } MozillaAudioDevice.prototype.refill = function() { var available, buffer, currentPosition, written; if (this.tail) { written = this.audio.mozWriteAudio(this.tail); this.writePosition += written; if (this.writePosition < this.tail.length) { this.tail = this.tail.subarray(written); } else { this.tail = null; } } currentPosition = this.audio.mozCurrentSampleOffset(); available = currentPosition + this.prebufferSize - this.writePosition; if (available > 0) { buffer = new Float32Array(available); this.emit('refill', buffer); written = this.audio.mozWriteAudio(buffer); if (written < buffer.length) { this.tail = buffer.subarray(written); } this.writePosition += written; } }; MozillaAudioDevice.prototype.destroy = function() { return destroyTimer(this.timer); }; MozillaAudioDevice.prototype.getDeviceTime = function() { return this.audio.mozCurrentSampleOffset() / this.channels; }; createTimer = function(fn, interval) { var url, worker; url = AVBuffer.makeBlobURL("setInterval(function() { postMessage('ping'); }, " + interval + ");"); if (url == null) { return setInterval(fn, interval); } worker = new Worker(url); worker.onmessage = fn; worker.url = url; return worker; }; destroyTimer = function(timer) { if (timer.terminate) { timer.terminate(); return URL.revokeObjectURL(timer.url); } else { return clearInterval(timer); } }; return MozillaAudioDevice; })(EventEmitter); }).call(this); },{"../core/buffer":6,"../core/events":8,"../device":20}],22:[function(require,module,exports){ //JavaScript Audio Resampler //Copyright (C) 2011-2015 Grant Galitz //Released to Public Domain function Resampler(fromSampleRate, toSampleRate, channels, inputBufferLength) { this.fromSampleRate = +fromSampleRate; this.toSampleRate = +toSampleRate; this.channels = channels | 0; this.inputBufferLength = inputBufferLength; this.initialize(); } Resampler.prototype.initialize = function () { //Perform some checks: if (this.fromSampleRate > 0 && this.toSampleRate > 0 && this.channels > 0) { if (this.fromSampleRate == this.toSampleRate) { //Setup a resampler bypass: this.resampler = this.bypassResampler; //Resampler just returns what was passed through. this.ratioWeight = 1; } else { this.ratioWeight = this.fromSampleRate / this.toSampleRate; if (this.fromSampleRate < this.toSampleRate) { /* Use generic linear interpolation if upsampling, as linear interpolation produces a gradient that we want and works fine with two input sample points per output in this case. */ this.compileLinearInterpolationFunction(); this.lastWeight = 1; } else { /* Custom resampler I wrote that doesn't skip samples like standard linear interpolation in high downsampling. This is more accurate than linear interpolation on downsampling. */ this.compileMultiTapFunction(); this.tailExists = false; this.lastWeight = 0; } var outputBufferSize = (Math.ceil(this.inputBufferLength * this.toSampleRate / this.fromSampleRate / this.channels * 1.01) * this.channels) + this.channels; this.outputBuffer = new Float32Array(outputBufferSize); this.lastOutput = new Float32Array(this.channels); } } else { throw(new Error("Invalid settings specified for the resampler.")); } }; Resampler.prototype.compileLinearInterpolationFunction = function () { var toCompile = "var outputOffset = 0;\ var bufferLength = buffer.length;\ if (bufferLength > 0) {\ var weight = this.lastWeight;\ var firstWeight = 0;\ var secondWeight = 0;\ var sourceOffset = 0;\ var outputOffset = 0;\ var outputBuffer = this.outputBuffer;\ for (; weight < 1; weight += " + this.ratioWeight + ") {\ secondWeight = weight % 1;\ firstWeight = 1 - secondWeight;"; for (var channel = 0; channel < this.channels; ++channel) { toCompile += "outputBuffer[outputOffset++] = (this.lastOutput[" + channel + "] * firstWeight) + (buffer[" + channel + "] * secondWeight);"; } toCompile += "}\ weight -= 1;\ for (bufferLength -= " + this.channels + ", sourceOffset = Math.floor(weight) * " + this.channels + "; sourceOffset < bufferLength;) {\ secondWeight = weight % 1;\ firstWeight = 1 - secondWeight;"; for (var channel = 0; channel < this.channels; ++channel) { toCompile += "outputBuffer[outputOffset++] = (buffer[sourceOffset" + ((channel > 0) ? (" + " + channel) : "") + "] * firstWeight) + (buffer[sourceOffset + " + (this.channels + channel) + "] * secondWeight);"; } toCompile += "weight += " + this.ratioWeight + ";\ sourceOffset = Math.floor(weight) * " + this.channels + ";\ }"; for (var channel = 0; channel < this.channels; ++channel) { toCompile += "this.lastOutput[" + channel + "] = buffer[sourceOffset++];"; } toCompile += "this.lastWeight = weight % 1;\ }\ return this.outputBuffer;"; this.resampler = Function("buffer", toCompile); }; Resampler.prototype.compileMultiTapFunction = function () { var toCompile = "var outputOffset = 0;\ var bufferLength = buffer.length;\ if (bufferLength > 0) {\ var weight = 0;"; for (var channel = 0; channel < this.channels; ++channel) { toCompile += "var output" + channel + " = 0;" } toCompile += "var actualPosition = 0;\ var amountToNext = 0;\ var alreadyProcessedTail = !this.tailExists;\ this.tailExists = false;\ var outputBuffer = this.outputBuffer;\ var currentPosition = 0;\ do {\ if (alreadyProcessedTail) {\ weight = " + this.ratioWeight + ";"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "output" + channel + " = 0;" } toCompile += "}\ else {\ weight = this.lastWeight;"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "output" + channel + " = this.lastOutput[" + channel + "];" } toCompile += "alreadyProcessedTail = true;\ }\ while (weight > 0 && actualPosition < bufferLength) {\ amountToNext = 1 + actualPosition - currentPosition;\ if (weight >= amountToNext) {"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "output" + channel + " += buffer[actualPosition++] * amountToNext;" } toCompile += "currentPosition = actualPosition;\ weight -= amountToNext;\ }\ else {"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "output" + channel + " += buffer[actualPosition" + ((channel > 0) ? (" + " + channel) : "") + "] * weight;" } toCompile += "currentPosition += weight;\ weight = 0;\ break;\ }\ }\ if (weight <= 0) {"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "outputBuffer[outputOffset++] = output" + channel + " / " + this.ratioWeight + ";" } toCompile += "}\ else {\ this.lastWeight = weight;"; for (channel = 0; channel < this.channels; ++channel) { toCompile += "this.lastOutput[" + channel + "] = output" + channel + ";" } toCompile += "this.tailExists = true;\ break;\ }\ } while (actualPosition < bufferLength);\ }\ return this.outputBuffer;"; this.resampler = Function("buffer", toCompile); }; Resampler.prototype.bypassResampler = function (inputBuffer) { return inputBuffer; }; module.exports = Resampler; },{}],23:[function(require,module,exports){ (function (global){ // Generated by CoffeeScript 1.10.0 (function() { var AudioDevice, EventEmitter, Resampler, WebAudioDevice, 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; EventEmitter = require('../core/events'); AudioDevice = require('../device'); Resampler = require('./resampler'); WebAudioDevice = (function(superClass) { var AudioContext, createProcessor, sharedContext; extend(WebAudioDevice, superClass); AudioDevice.register(WebAudioDevice); // TEED 生成音频上下文 AudioContext = global.AudioContext || global.webkitAudioContext; console.log("AudioContext>>>>>",AudioContext) WebAudioDevice.supported = AudioContext && (typeof AudioContext.prototype[createProcessor = 'createScriptProcessor'] === 'function' || typeof AudioContext.prototype[createProcessor = 'createJavaScriptNode'] === 'function'); sharedContext = null; // 网络音频设备 function WebAudioDevice(sampleRate, channels1) { this.sampleRate = sampleRate; this.channels = channels1; this.refill = bind(this.refill, this); this.context = sharedContext != null ? sharedContext : sharedContext = new AudioContext; this.deviceSampleRate = this.context.sampleRate; this.bufferSize = Math.ceil(4096 / (this.deviceSampleRate / this.sampleRate) * this.channels); this.bufferSize += this.bufferSize % this.channels; if (this.deviceSampleRate !== this.sampleRate) { this.resampler = new Resampler(this.sampleRate, this.deviceSampleRate, this.channels, this.bufferSize); } this.node = this.context[createProcessor](4096, this.channels, this.channels); this.node.onaudioprocess = this.refill; this.node.connect(this.context.destination); } WebAudioDevice.prototype.refill = function(event) { var channelCount, channels, data, i, j, k, l, n, outputBuffer, ref, ref1, ref2; outputBuffer = event.outputBuffer; channelCount = outputBuffer.numberOfChannels; channels = new Array(channelCount); for (i = j = 0, ref = channelCount; j < ref; i = j += 1) { channels[i] = outputBuffer.getChannelData(i); } data = new Float32Array(this.bufferSize); this.emit('refill', data); if (this.resampler) { data = this.resampler.resampler(data); } for (i = k = 0, ref1 = outputBuffer.length; k < ref1; i = k += 1) { for (n = l = 0, ref2 = channelCount; l < ref2; n = l += 1) { channels[n][i] = data[i * channelCount + n]; } } }; WebAudioDevice.prototype.destroy = function() { return this.node.disconnect(0); }; WebAudioDevice.prototype.getDeviceTime = function() { return this.context.currentTime * this.sampleRate; }; return WebAudioDevice; })(EventEmitter); }).call(this); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../core/events":8,"../device":20,"./resampler":22}],24:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var Filter; Filter = (function() { function Filter(context, key) { if (context && key) { Object.defineProperty(this, 'value', { get: function() { return context[key]; } }); } } Filter.prototype.process = function(buffer) {}; return Filter; })(); module.exports = Filter; }).call(this); },{}],25:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var BalanceFilter, Filter, 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; Filter = require('../filter'); BalanceFilter = (function(superClass) { extend(BalanceFilter, superClass); function BalanceFilter() { return BalanceFilter.__super__.constructor.apply(this, arguments); } BalanceFilter.prototype.process = function(buffer) { var i, j, pan, ref; if (this.value === 0) { return; } pan = Math.max(-50, Math.min(50, this.value)); for (i = j = 0, ref = buffer.length; j < ref; i = j += 2) { buffer[i] *= Math.min(1, (50 - pan) / 50); buffer[i + 1] *= Math.min(1, (50 + pan) / 50); } }; return BalanceFilter; })(Filter); module.exports = BalanceFilter; }).call(this); },{"../filter":24}],26:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var Filter, VolumeFilter, 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; Filter = require('../filter'); VolumeFilter = (function(superClass) { extend(VolumeFilter, superClass); function VolumeFilter() { return VolumeFilter.__super__.constructor.apply(this, arguments); } VolumeFilter.prototype.process = function(buffer) { var i, j, ref, vol; if (this.value >= 100) { return; } vol = Math.max(0, Math.min(100, this.value)) / 100; for (i = j = 0, ref = buffer.length; j < ref; i = j += 1) { buffer[i] *= vol; } }; return VolumeFilter; })(Filter); module.exports = VolumeFilter; }).call(this); },{"../filter":24}],27:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var Asset, AudioDevice, BalanceFilter, EventEmitter, Player, Queue, VolumeFilter, 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; EventEmitter = require('./core/events'); Asset = require('./asset'); VolumeFilter = require('./filters/volume'); BalanceFilter = require('./filters/balance'); Queue = require('./queue'); AudioDevice = require('./device'); Player = (function(superClass) { extend(Player, superClass); // 请看音频上下文的文档 了解 这个作用是 播放音频 TDDE function Player(asset) { console.log("asset",asset); this.asset = asset; this.startPlaying = bind(this.startPlaying, this); this.playing = false; this.buffered = 0; this.currentTime = 0; this.duration = 0; this.volume = 100; this.pan = 0; this.metadata = {}; this.filters = [new VolumeFilter(this, 'volume'), new BalanceFilter(this, 'pan')]; this.asset.on('buffer', (function(_this) { return function(buffered) { _this.buffered = buffered; return _this.emit('buffer', _this.buffered); }; })(this)); this.asset.on('decodeStart', (function(_this) { return function() { _this.queue = new Queue(_this.asset); return _this.queue.once('ready', _this.startPlaying); }; })(this)); this.asset.on('format', (function(_this) { return function(format) { _this.format = format; return _this.emit('format', _this.format); }; })(this)); this.asset.on('metadata', (function(_this) { return function(metadata) { _this.metadata = metadata; return _this.emit('metadata', _this.metadata); }; })(this)); this.asset.on('duration', (function(_this) { return function(duration) { _this.duration = duration; return _this.emit('duration', _this.duration); }; })(this)); this.asset.on('error', (function(_this) { return function(error) { return _this.emit('error', error); }; })(this)); } //来自URL Player.fromURL = function(url, opts) { return new Player(Asset.fromURL(url, opts)); }; //来自文件 封装 可以读取 aac 本地文件 Player.fromFile = function(file) { return new Player(Asset.fromFile(file)); }; //每一块 Player.fromBuffer = function(buffer) { return new Player(Asset.fromBuffer(buffer)); }; //预载 Player.prototype.preload = function() { if (!this.asset) { return; } this.startedPreloading = true; return this.asset.start(false); console.log("!this.asset==========",!this.asset,this.asset); }; Player.prototype.play = function() { var ref; if (this.playing) { return; } if (!this.startedPreloading) { this.preload(); console.log("!this.startedPreloading",!this.startedPreloading); } // this.playing = true; return (ref = this.device) != null ? ref.start() : void 0; }; Player.prototype.pause = function() { var ref; if (!this.playing) { return; } this.playing = false; return (ref = this.device) != null ? ref.stop() : void 0; }; Player.prototype.togglePlayback = function() { if (this.playing) { return this.pause(); } else { return this.play(); } }; Player.prototype.stop = function() { var ref; this.pause(); this.asset.stop(); return (ref = this.device) != null ? ref.destroy() : void 0; }; Player.prototype.seek = function(timestamp) { var ref; if ((ref = this.device) != null) { ref.stop(); } this.queue.once('ready', (function(_this) { return function() { var ref1, ref2; if ((ref1 = _this.device) != null) { ref1.seek(_this.currentTime); } if (_this.playing) { return (ref2 = _this.device) != null ? ref2.start() : void 0; } }; })(this)); timestamp = (timestamp / 1000) * this.format.sampleRate; timestamp = this.asset.decoder.seek(timestamp); this.currentTime = timestamp / this.format.sampleRate * 1000 | 0; this.queue.reset(); return this.currentTime; }; Player.prototype.startPlaying = function() { var frame, frameOffset; frame = this.queue.read(); frameOffset = 0; this.device = new AudioDevice(this.format.sampleRate, this.format.channelsPerFrame); this.device.on('timeUpdate', (function(_this) { return function(currentTime) { _this.currentTime = currentTime; return _this.emit('progress', _this.currentTime); }; })(this)); this.refill = (function(_this) { return function(buffer) { var bufferOffset, filter, i, j, k, len, max, ref, ref1; if (!_this.playing) { return; } if (!frame) { frame = _this.queue.read(); frameOffset = 0; } bufferOffset = 0; while (frame && bufferOffset < buffer.length) { max = Math.min(frame.length - frameOffset, buffer.length - bufferOffset); for (i = j = 0, ref = max; j < ref; i = j += 1) { buffer[bufferOffset++] = frame[frameOffset++]; } if (frameOffset === frame.length) { frame = _this.queue.read(); frameOffset = 0; } } ref1 = _this.filters; for (k = 0, len = ref1.length; k < len; k++) { filter = ref1[k]; filter.process(buffer); } if (!frame) { if (_this.queue.ended) { _this.currentTime = _this.duration; _this.emit('progress', _this.currentTime); _this.emit('end'); _this.stop(); } else { _this.device.stop(); } } }; })(this); this.device.on('refill', this.refill); if (this.playing) { this.device.start(); } return this.emit('ready'); }; Player.prototype.destroy = function() { var ref, ref1; this.stop(); if ((ref = this.device) != null) { ref.off(); } if ((ref1 = this.asset) != null) { ref1.destroy(); } return this.off(); }; return Player; })(EventEmitter); module.exports = Player; }).call(this); },{"./asset":1,"./core/events":8,"./device":20,"./filters/balance":25,"./filters/volume":26,"./queue":28}],28:[function(require,module,exports){ // Generated by CoffeeScript 1.10.0 (function() { var EventEmitter, Queue, 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; EventEmitter = require('./core/events'); Queue = (function(superClass) { extend(Queue, superClass); function Queue(asset) { this.asset = asset; this.write = bind(this.write, this); this.readyMark = 64; this.finished = false; this.buffering = true; this.ended = false; this.buffers = []; this.asset.on('data', this.write); this.asset.on('end', (function(_this) { return function() { return _this.ended = true; }; })(this)); this.asset.decodePacket(); } Queue.prototype.write = function(buffer) { if (buffer) { this.buffers.push(buffer); } if (this.buffering) { if (this.buffers.length >= this.readyMark || this.ended) { this.buffering = false; return this.emit('ready'); } else { return this.asset.decodePacket(); } } }; Queue.prototype.read = function() { if (this.buffers.length === 0) { return null; } this.asset.decodePacket(); return this.buffers.shift(); }; Queue.prototype.reset = function() { this.buffers.length = 0; this.buffering = true; return this.asset.decodePacket(); }; return Queue; })(EventEmitter); module.exports = Queue; }).call(this); },{"./core/events":8}],29:[function(require,module,exports){ var AVBuffer, EventEmitter, FileSource, __hasProp = {}.hasOwnProperty, __extends = 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; }; EventEmitter = require('../../core/events'); AVBuffer = require('../../core/buffer'); FileSource = (function(_super) { __extends(FileSource, _super); function FileSource(file) { this.file = file; if (typeof FileReader === "undefined" || FileReader === null) { return this.emit('error', 'This browser does not have FileReader support.'); } this.offset = 0; this.length = this.file.size; this.chunkSize = 1 << 20; this.file[this.slice = 'slice'] || this.file[this.slice = 'webkitSlice'] || this.file[this.slice = 'mozSlice']; } FileSource.prototype.start = function() { if (this.reader) { if (!this.active) { return this.loop(); } } this.reader = new FileReader; this.active = true; this.reader.onload = (function(_this) { return function(e) { var buf; buf = new AVBuffer(new Uint8Array(e.target.result)); _this.offset += buf.length; _this.emit('data', buf); _this.active = false; if (_this.offset < _this.length) { return _this.loop(); } }; })(this); this.reader.onloadend = (function(_this) { return function() { if (_this.offset === _this.length) { _this.emit('end'); return _this.reader = null; } }; })(this); this.reader.onerror = (function(_this) { return function(e) { return _this.emit('error', e); }; })(this); this.reader.onprogress = (function(_this) { return function(e) { return _this.emit('progress', (_this.offset + e.loaded) / _this.length * 100); }; })(this); return this.loop(); }; FileSource.prototype.loop = function() { var blob, endPos; this.active = true; endPos = Math.min(this.offset + this.chunkSize, this.length); blob = this.file[this.slice](this.offset, endPos); return this.reader.readAsArrayBuffer(blob); }; FileSource.prototype.pause = function() { var _ref; this.active = false; try { return (_ref = this.reader) != null ? _ref.abort() : void 0; } catch (_error) {} }; FileSource.prototype.reset = function() { this.pause(); return this.offset = 0; }; return FileSource; })(EventEmitter); module.exports = FileSource; },{"../../core/buffer":6,"../../core/events":8}],30:[function(require,module,exports){ var AVBuffer, EventEmitter, HTTPSource, __hasProp = {}.hasOwnProperty, __extends = 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; }; EventEmitter = require('../../core/events'); AVBuffer = require('../../core/buffer'); HTTPSource = (function(_super) { __extends(HTTPSource, _super); function HTTPSource(url, opts) { this.url = url; console.log('url>>>',url) this.opts = opts != null ? opts : {}; this.chunkSize = 1 << 20; this.inflight = false; if (this.opts.length) { this.length = this.opts.length; } this.reset(); } HTTPSource.prototype.start = function() { if (this.length) { if (!this.inflight) { return this.loop(); } } this.inflight = true; this.xhr = new XMLHttpRequest(); this.xhr.onload = (function(_this) { return function(event) { _this.length = parseInt(_this.xhr.getResponseHeader("Content-Length")); _this.inflight = false; return _this.loop(); }; })(this); this.xhr.onerror = (function(_this) { return function(err) { _this.pause(); return _this.emit('error', err); }; })(this); this.xhr.onabort = (function(_this) { return function(event) { return _this.inflight = false; }; })(this); this.xhr.open("HEAD", this.url, true); return this.xhr.send(null); }; HTTPSource.prototype.loop = function() { var endPos; if (this.inflight || !this.length) { return this.emit('error', 'Something is wrong in HTTPSource.loop'); } this.inflight = true; this.xhr = new XMLHttpRequest(); this.xhr.onload = (function(_this) { return function(event) { var buf, buffer, i, txt, _i, _ref; if (_this.xhr.response) { buf = new Uint8Array(_this.xhr.response); } else { txt = _this.xhr.responseText; buf = new Uint8Array(txt.length); for (i = _i = 0, _ref = txt.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { buf[i] = txt.charCodeAt(i) & 0xff; } } buffer = new AVBuffer(buf); _this.offset += buffer.length; _this.emit('data', buffer); if (_this.offset >= _this.length) { _this.emit('end'); } _this.inflight = false; if (!(_this.offset >= _this.length)) { return _this.loop(); } }; })(this); this.xhr.onprogress = (function(_this) { return function(event) { return _this.emit('progress', (_this.offset + event.loaded) / _this.length * 100); }; })(this); this.xhr.onerror = (function(_this) { return function(err) { _this.emit('error', err); return _this.pause(); }; })(this); this.xhr.onabort = (function(_this) { return function(event) { return _this.inflight = false; }; })(this); alert(this.url) this.xhr.open("GET", this.url, true); this.xhr.responseType = "arraybuffer"; endPos = Math.min(this.offset + this.chunkSize, this.length - 1); this.xhr.setRequestHeader("If-None-Match", "webkit-no-cache"); this.xhr.setRequestHeader("Range", "bytes=" + this.offset + "-" + endPos); this.xhr.overrideMimeType('text/plain; charset=x-user-defined'); return this.xhr.send(null); }; HTTPSource.prototype.pause = function() { var _ref; this.inflight = false; return (_ref = this.xhr) != null ? _ref.abort() : void 0; }; HTTPSource.prototype.reset = function() { this.pause(); return this.offset = 0; }; return HTTPSource; })(EventEmitter); module.exports = HTTPSource; },{"../../core/buffer":6,"../../core/events":8}],31:[function(require,module,exports){ (function (global){ // Generated by CoffeeScript 1.10.0 (function() { var AVBuffer, BufferList, BufferSource, EventEmitter, 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; EventEmitter = require('../core/events'); BufferList = require('../core/bufferlist'); AVBuffer = require('../core/buffer'); BufferSource = (function(superClass) { var clearImmediate, setImmediate; extend(BufferSource, superClass); function BufferSource(input) { this.loop = bind(this.loop, this); if (input instanceof BufferList) { this.list = input; } else { this.list = new BufferList; this.list.append(new AVBuffer(input)); } this.paused = true; } setImmediate = global.setImmediate || function(fn) { return global.setTimeout(fn, 0); }; clearImmediate = global.clearImmediate || function(timer) { return global.clearTimeout(timer); }; BufferSource.prototype.start = function() { this.paused = false; return this._timer = setImmediate(this.loop); }; BufferSource.prototype.loop = function() { this.emit('progress', (this.list.numBuffers - this.list.availableBuffers + 1) / this.list.numBuffers * 100 | 0); this.emit('data', this.list.first); if (this.list.advance()) { return setImmediate(this.loop); } else { return this.emit('end'); } }; BufferSource.prototype.pause = function() { clearImmediate(this._timer); return this.paused = true; }; BufferSource.prototype.reset = function() { this.pause(); return this.list.rewind(); }; return BufferSource; })(EventEmitter); module.exports = BufferSource; }).call(this); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../core/buffer":6,"../core/bufferlist":7,"../core/events":8}],32:[function(require,module,exports){ var key, val, _ref; _ref = require('./src/aurora'); for (key in _ref) { val = _ref[key]; exports[key] = val; } require('./src/devices/webaudio'); require('./src/devices/mozilla'); },{"./src/aurora":2,"./src/devices/mozilla":21,"./src/devices/webaudio":23}]},{},[32])(32) }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYXNzZXQuanMiLCJzcmMvYXVyb3JhLmpzIiwic3JjL2F1cm9yYV9iYXNlLmpzIiwic3JjL2NvcmUvYmFzZS5qcyIsInNyYy9jb3JlL2JpdHN0cmVhbS5qcyIsInNyYy9jb3JlL2J1ZmZlci5qcyIsInNyYy9jb3JlL2J1ZmZlcmxpc3QuanMiLCJzcmMvY29yZS9ldmVudHMuanMiLCJzcmMvY29yZS9zdHJlYW0uanMiLCJzcmMvY29yZS91bmRlcmZsb3cuanMiLCJzcmMvZGVjb2Rlci5qcyIsInNyYy9kZWNvZGVycy9scGNtLmpzIiwic3JjL2RlY29kZXJzL3hsYXcuanMiLCJzcmMvZGVtdXhlci5qcyIsInNyYy9kZW11eGVycy9haWZmLmpzIiwic3JjL2RlbXV4ZXJzL2F1LmpzIiwic3JjL2RlbXV4ZXJzL2NhZi5qcyIsInNyYy9kZW11eGVycy9tNGEuanMiLCJzcmMvZGVtdXhlcnMvd2F2ZS5qcyIsInNyYy9kZXZpY2UuanMiLCJzcmMvZGV2aWNlcy9tb3ppbGxhLmpzIiwic3JjL2RldmljZXMvcmVzYW1wbGVyLmpzIiwic3JjL2RldmljZXMvd2ViYXVkaW8uanMiLCJzcmMvZmlsdGVyLmpzIiwic3JjL2ZpbHRlcnMvYmFsYW5jZS5qcyIsInNyYy9maWx0ZXJzL3ZvbHVtZS5qcyIsInNyYy9wbGF5ZXIuanMiLCJzcmMvcXVldWUuanMiLCIvaG9tZS9kaW0vY29kZS9hdXJvcmEuanMvc3JjL3NvdXJjZXMvYnJvd3Nlci9maWxlLmNvZmZlZSIsIi9ob21lL2RpbS9jb2RlL2F1cm9yYS5qcy9zcmMvc291cmNlcy9icm93c2VyL2h0dHAuY29mZmVlIiwic3JjL3NvdXJjZXMvYnVmZmVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ25PQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsZ0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3huQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDNUpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hFQSxJQUFBLGtDQUFBO0VBQUE7aVNBQUE7O0FBQUEsWUFBQSxHQUFlLE9BQUEsQ0FBUSxtQkFBUixDQUFmLENBQUE7O0FBQUEsUUFDQSxHQUFXLE9BQUEsQ0FBUSxtQkFBUixDQURYLENBQUE7O0FBQUE7QUFJSSwrQkFBQSxDQUFBOztBQUFhLEVBQUEsb0JBQUUsSUFBRixHQUFBO0FBQ1QsSUFEVSxJQUFDLENBQUEsT0FBQSxJQUNYLENBQUE7QUFBQSxJQUFBLElBQU8sd0RBQVA7QUFDSSxhQUFPLElBQUMsQ0FBQSxJQUFELENBQU0sT0FBTixFQUFlLGdEQUFmLENBQVAsQ0FESjtLQUFBO0FBQUEsSUFHQSxJQUFDLENBQUEsTUFBRCxHQUFVLENBSFYsQ0FBQTtBQUFBLElBSUEsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUFDLENBQUEsSUFBSSxDQUFDLElBSmhCLENBQUE7QUFBQSxJQUtBLElBQUMsQ0FBQSxTQUFELEdBQWEsQ0FBQSxJQUFLLEVBTGxCLENBQUE7QUFBQSxJQU1BLElBQUMsQ0FBQSxJQUFLLENBQUEsSUFBQyxDQUFBLEtBQUQsR0FBUyxPQUFULENBQU4sSUFBMkIsSUFBQyxDQUFBLElBQUssQ0FBQSxJQUFDLENBQUEsS0FBRCxHQUFTLGFBQVQsQ0FBakMsSUFBNEQsSUFBQyxDQUFBLElBQUssQ0FBQSxJQUFDLENBQUEsS0FBRCxHQUFTLFVBQVQsQ0FObEUsQ0FEUztFQUFBLENBQWI7O0FBQUEsdUJBU0EsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILElBQUEsSUFBRyxJQUFDLENBQUEsTUFBSjtBQUNJLE1BQUEsSUFBQSxDQUFBLElBQXVCLENBQUEsTUFBdkI7QUFBQSxlQUFPLElBQUMsQ0FBQSxJQUFELENBQUEsQ0FBUCxDQUFBO09BREo7S0FBQTtBQUFBLElBR0EsSUFBQyxDQUFBLE1BQUQsR0FBVSxHQUFBLENBQUEsVUFIVixDQUFBO0FBQUEsSUFJQSxJQUFDLENBQUEsTUFBRCxHQUFVLElBSlYsQ0FBQTtBQUFBLElBTUEsSUFBQyxDQUFBLE1BQU0sQ0FBQyxNQUFSLEdBQWlCLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLENBQUQsR0FBQTtBQUNiLFlBQUEsR0FBQTtBQUFBLFFBQUEsR0FBQSxHQUFVLElBQUEsUUFBQSxDQUFhLElBQUEsVUFBQSxDQUFXLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBcEIsQ0FBYixDQUFWLENBQUE7QUFBQSxRQUNBLEtBQUMsQ0FBQSxNQUFELElBQVcsR0FBRyxDQUFDLE1BRGYsQ0FBQTtBQUFBLFFBR0EsS0FBQyxDQUFBLElBQUQsQ0FBTSxNQUFOLEVBQWMsR0FBZCxDQUhBLENBQUE7QUFBQSxRQUlBLEtBQUMsQ0FBQSxNQUFELEdBQVUsS0FKVixDQUFBO0FBS0EsUUFBQSxJQUFXLEtBQUMsQ0FBQSxNQUFELEdBQVUsS0FBQyxDQUFBLE1BQXRCO2lCQUFBLEtBQUMsQ0FBQSxJQUFELENBQUEsRUFBQTtTQU5hO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FOakIsQ0FBQTtBQUFBLElBY0EsSUFBQyxDQUFBLE1BQU0sQ0FBQyxTQUFSLEdBQW9CLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFBLEdBQUE7QUFDaEIsUUFBQSxJQUFHLEtBQUMsQ0FBQSxNQUFELEtBQVcsS0FBQyxDQUFBLE1BQWY7QUFDSSxVQUFBLEtBQUMsQ0FBQSxJQUFELENBQU0sS0FBTixDQUFBLENBQUE7aUJBQ0EsS0FBQyxDQUFBLE1BQUQsR0FBVSxLQUZkO1NBRGdCO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FkcEIsQ0FBQTtBQUFBLElBbUJBLElBQUMsQ0FBQSxNQUFNLENBQUMsT0FBUixHQUFrQixDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxDQUFELEdBQUE7ZUFDZCxLQUFDLENBQUEsSUFBRCxDQUFNLE9BQU4sRUFBZSxDQUFmLEVBRGM7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQW5CbEIsQ0FBQTtBQUFBLElBc0JBLElBQUMsQ0FBQSxNQUFNLENBQUMsVUFBUixHQUFxQixDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxDQUFELEdBQUE7ZUFDakIsS0FBQyxDQUFBLElBQUQsQ0FBTSxVQUFOLEVBQWtCLENBQUMsS0FBQyxDQUFBLE1BQUQsR0FBVSxDQUFDLENBQUMsTUFBYixDQUFBLEdBQXVCLEtBQUMsQ0FBQSxNQUF4QixHQUFpQyxHQUFuRCxFQURpQjtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBdEJyQixDQUFBO1dBeUJBLElBQUMsQ0FBQSxJQUFELENBQUEsRUExQkc7RUFBQSxDQVRQLENBQUE7O0FBQUEsdUJBcUNBLElBQUEsR0FBTSxTQUFBLEdBQUE7QUFDRixRQUFBLFlBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFBVixDQUFBO0FBQUEsSUFDQSxNQUFBLEdBQVMsSUFBSSxDQUFDLEdBQUwsQ0FBUyxJQUFDLENBQUEsTUFBRCxHQUFVLElBQUMsQ0FBQSxTQUFwQixFQUErQixJQUFDLENBQUEsTUFBaEMsQ0FEVCxDQUFBO0FBQUEsSUFHQSxJQUFBLEdBQU8sSUFBQyxDQUFBLElBQUssQ0FBQSxJQUFDLENBQUEsS0FBRCxDQUFOLENBQWMsSUFBQyxDQUFBLE1BQWYsRUFBdUIsTUFBdkIsQ0FIUCxDQUFBO1dBSUEsSUFBQyxDQUFBLE1BQU0sQ0FBQyxpQkFBUixDQUEwQixJQUExQixFQUxFO0VBQUEsQ0FyQ04sQ0FBQTs7QUFBQSx1QkE0Q0EsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILFFBQUEsSUFBQTtBQUFBLElBQUEsSUFBQyxDQUFBLE1BQUQsR0FBVSxLQUFWLENBQUE7QUFDQTtnREFDUyxDQUFFLEtBQVQsQ0FBQSxXQURGO0tBQUEsa0JBRkc7RUFBQSxDQTVDUCxDQUFBOztBQUFBLHVCQWlEQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsSUFBQSxJQUFDLENBQUEsS0FBRCxDQUFBLENBQUEsQ0FBQTtXQUNBLElBQUMsQ0FBQSxNQUFELEdBQVUsRUFGUDtFQUFBLENBakRQLENBQUE7O29CQUFBOztHQURxQixhQUh6QixDQUFBOztBQUFBLE1BeURNLENBQUMsT0FBUCxHQUFpQixVQXpEakIsQ0FBQTs7O0FDQUEsSUFBQSxrQ0FBQTtFQUFBO2lTQUFBOztBQUFBLFlBQUEsR0FBZSxPQUFBLENBQVEsbUJBQVIsQ0FBZixDQUFBOztBQUFBLFFBQ0EsR0FBVyxPQUFBLENBQVEsbUJBQVIsQ0FEWCxDQUFBOztBQUFBO0FBSUksK0JBQUEsQ0FBQTs7QUFBYSxFQUFBLG9CQUFFLEdBQUYsRUFBUSxJQUFSLEdBQUE7QUFDVCxJQURVLElBQUMsQ0FBQSxNQUFBLEdBQ1gsQ0FBQTtBQUFBLElBRGdCLElBQUMsQ0FBQSxzQkFBQSxPQUFPLEVBQ3hCLENBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxTQUFELEdBQWEsQ0FBQSxJQUFLLEVBQWxCLENBQUE7QUFBQSxJQUNBLElBQUMsQ0FBQSxRQUFELEdBQVksS0FEWixDQUFBO0FBRUEsSUFBQSxJQUFHLElBQUMsQ0FBQSxJQUFJLENBQUMsTUFBVDtBQUNJLE1BQUEsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUFDLENBQUEsSUFBSSxDQUFDLE1BQWhCLENBREo7S0FGQTtBQUFBLElBSUEsSUFBQyxDQUFBLEtBQUQsQ0FBQSxDQUpBLENBRFM7RUFBQSxDQUFiOztBQUFBLHVCQU9BLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxJQUFBLElBQUcsSUFBQyxDQUFBLE1BQUo7QUFDSSxNQUFBLElBQUEsQ0FBQSxJQUF1QixDQUFBLFFBQXZCO0FBQUEsZUFBTyxJQUFDLENBQUEsSUFBRCxDQUFBLENBQVAsQ0FBQTtPQURKO0tBQUE7QUFBQSxJQUdBLElBQUMsQ0FBQSxRQUFELEdBQVksSUFIWixDQUFBO0FBQUEsSUFJQSxJQUFDLENBQUEsR0FBRCxHQUFXLElBQUEsY0FBQSxDQUFBLENBSlgsQ0FBQTtBQUFBLElBTUEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxNQUFMLEdBQWMsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsS0FBRCxHQUFBO0FBQ1YsUUFBQSxLQUFDLENBQUEsTUFBRCxHQUFVLFFBQUEsQ0FBUyxLQUFDLENBQUEsR0FBRyxDQUFDLGlCQUFMLENBQXVCLGdCQUF2QixDQUFULENBQVYsQ0FBQTtBQUFBLFFBQ0EsS0FBQyxDQUFBLFFBQUQsR0FBWSxLQURaLENBQUE7ZUFFQSxLQUFDLENBQUEsSUFBRCxDQUFBLEVBSFU7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQU5kLENBQUE7QUFBQSxJQVdBLElBQUMsQ0FBQSxHQUFHLENBQUMsT0FBTCxHQUFlLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEdBQUQsR0FBQTtBQUNYLFFBQUEsS0FBQyxDQUFBLEtBQUQsQ0FBQSxDQUFBLENBQUE7ZUFDQSxLQUFDLENBQUEsSUFBRCxDQUFNLE9BQU4sRUFBZSxHQUFmLEVBRlc7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQVhmLENBQUE7QUFBQSxJQWVBLElBQUMsQ0FBQSxHQUFHLENBQUMsT0FBTCxHQUFlLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEtBQUQsR0FBQTtlQUNYLEtBQUMsQ0FBQSxRQUFELEdBQVksTUFERDtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBZmYsQ0FBQTtBQUFBLElBa0JBLElBQUMsQ0FBQSxHQUFHLENBQUMsSUFBTCxDQUFVLE1BQVYsRUFBa0IsSUFBQyxDQUFBLEdBQW5CLEVBQXdCLElBQXhCLENBbEJBLENBQUE7V0FtQkEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxJQUFMLENBQVUsSUFBVixFQXBCRztFQUFBLENBUFAsQ0FBQTs7QUFBQSx1QkE2QkEsSUFBQSxHQUFNLFNBQUEsR0FBQTtBQUNGLFFBQUEsTUFBQTtBQUFBLElBQUEsSUFBRyxJQUFDLENBQUEsUUFBRCxJQUFhLENBQUEsSUFBSyxDQUFBLE1BQXJCO0FBQ0ksYUFBTyxJQUFDLENBQUEsSUFBRCxDQUFNLE9BQU4sRUFBZSx1Q0FBZixDQUFQLENBREo7S0FBQTtBQUFBLElBR0EsSUFBQyxDQUFBLFFBQUQsR0FBWSxJQUhaLENBQUE7QUFBQSxJQUlBLElBQUMsQ0FBQSxHQUFELEdBQVcsSUFBQSxjQUFBLENBQUEsQ0FKWCxDQUFBO0FBQUEsSUFNQSxJQUFDLENBQUEsR0FBRyxDQUFDLE1BQUwsR0FBYyxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxLQUFELEdBQUE7QUFDVixZQUFBLDZCQUFBO0FBQUEsUUFBQSxJQUFHLEtBQUMsQ0FBQSxHQUFHLENBQUMsUUFBUjtBQUNJLFVBQUEsR0FBQSxHQUFVLElBQUEsVUFBQSxDQUFXLEtBQUMsQ0FBQSxHQUFHLENBQUMsUUFBaEIsQ0FBVixDQURKO1NBQUEsTUFBQTtBQUdJLFVBQUEsR0FBQSxHQUFNLEtBQUMsQ0FBQSxHQUFHLENBQUMsWUFBWCxDQUFBO0FBQUEsVUFDQSxHQUFBLEdBQVUsSUFBQSxVQUFBLENBQVcsR0FBRyxDQUFDLE1BQWYsQ0FEVixDQUFBO0FBRUEsZUFBUyw2RkFBVCxHQUFBO0FBQ0ksWUFBQSxHQUFJLENBQUEsQ0FBQSxDQUFKLEdBQVMsR0FBRyxDQUFDLFVBQUosQ0FBZSxDQUFmLENBQUEsR0FBb0IsSUFBN0IsQ0FESjtBQUFBLFdBTEo7U0FBQTtBQUFBLFFBUUEsTUFBQSxHQUFhLElBQUEsUUFBQSxDQUFTLEdBQVQsQ0FSYixDQUFBO0FBQUEsUUFTQSxLQUFDLENBQUEsTUFBRCxJQUFXLE1BQU0sQ0FBQyxNQVRsQixDQUFBO0FBQUEsUUFXQSxLQUFDLENBQUEsSUFBRCxDQUFNLE1BQU4sRUFBYyxNQUFkLENBWEEsQ0FBQTtBQVlBLFFBQUEsSUFBZSxLQUFDLENBQUEsTUFBRCxJQUFXLEtBQUMsQ0FBQSxNQUEzQjtBQUFBLFVBQUEsS0FBQyxDQUFBLElBQUQsQ0FBTSxLQUFOLENBQUEsQ0FBQTtTQVpBO0FBQUEsUUFjQSxLQUFDLENBQUEsUUFBRCxHQUFZLEtBZFosQ0FBQTtBQWVBLFFBQUEsSUFBQSxDQUFBLENBQWUsS0FBQyxDQUFBLE1BQUQsSUFBVyxLQUFDLENBQUEsTUFBM0IsQ0FBQTtpQkFBQSxLQUFDLENBQUEsSUFBRCxDQUFBLEVBQUE7U0FoQlU7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQU5kLENBQUE7QUFBQSxJQXdCQSxJQUFDLENBQUEsR0FBRyxDQUFDLFVBQUwsR0FBa0IsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsS0FBRCxHQUFBO2VBQ2QsS0FBQyxDQUFBLElBQUQsQ0FBTSxVQUFOLEVBQWtCLENBQUMsS0FBQyxDQUFBLE1BQUQsR0FBVSxLQUFLLENBQUMsTUFBakIsQ0FBQSxHQUEyQixLQUFDLENBQUEsTUFBNUIsR0FBcUMsR0FBdkQsRUFEYztNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBeEJsQixDQUFBO0FBQUEsSUEyQkEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxPQUFMLEdBQWUsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsR0FBRCxHQUFBO0FBQ1gsUUFBQSxLQUFDLENBQUEsSUFBRCxDQUFNLE9BQU4sRUFBZSxHQUFmLENBQUEsQ0FBQTtlQUNBLEtBQUMsQ0FBQSxLQUFELENBQUEsRUFGVztNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBM0JmLENBQUE7QUFBQSxJQStCQSxJQUFDLENBQUEsR0FBRyxDQUFDLE9BQUwsR0FBZSxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxLQUFELEdBQUE7ZUFDWCxLQUFDLENBQUEsUUFBRCxHQUFZLE1BREQ7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQS9CZixDQUFBO0FBQUEsSUFrQ0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxJQUFMLENBQVUsS0FBVixFQUFpQixJQUFDLENBQUEsR0FBbEIsRUFBdUIsSUFBdkIsQ0FsQ0EsQ0FBQTtBQUFBLElBbUNBLElBQUMsQ0FBQSxHQUFHLENBQUMsWUFBTCxHQUFvQixhQW5DcEIsQ0FBQTtBQUFBLElBcUNBLE1BQUEsR0FBUyxJQUFJLENBQUMsR0FBTCxDQUFTLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFBQyxDQUFBLFNBQXBCLEVBQStCLElBQUMsQ0FBQSxNQUFELEdBQVUsQ0FBekMsQ0FyQ1QsQ0FBQTtBQUFBLElBc0NBLElBQUMsQ0FBQSxHQUFHLENBQUMsZ0JBQUwsQ0FBc0IsZUFBdEIsRUFBdUMsaUJBQXZDLENBdENBLENBQUE7QUFBQSxJQXVDQSxJQUFDLENBQUEsR0FBRyxDQUFDLGdCQUFMLENBQXNCLE9BQXRCLEVBQWdDLFFBQUEsR0FBTyxJQUFDLENBQUEsTUFBUixHQUFnQixHQUFoQixHQUFrQixNQUFsRCxDQXZDQSxDQUFBO0FBQUEsSUF3Q0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxnQkFBTCxDQUFzQixvQ0FBdEIsQ0F4Q0EsQ0FBQTtXQXlDQSxJQUFDLENBQUEsR0FBRyxDQUFDLElBQUwsQ0FBVSxJQUFWLEVBMUNFO0VBQUEsQ0E3Qk4sQ0FBQTs7QUFBQSx1QkF5RUEsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILFFBQUEsSUFBQTtBQUFBLElBQUEsSUFBQyxDQUFBLFFBQUQsR0FBWSxLQUFaLENBQUE7MkNBQ0ksQ0FBRSxLQUFOLENBQUEsV0FGRztFQUFBLENBekVQLENBQUE7O0FBQUEsdUJBNkVBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxJQUFBLElBQUMsQ0FBQSxLQUFELENBQUEsQ0FBQSxDQUFBO1dBQ0EsSUFBQyxDQUFBLE1BQUQsR0FBVSxFQUZQO0VBQUEsQ0E3RVAsQ0FBQTs7b0JBQUE7O0dBRHFCLGFBSHpCLENBQUE7O0FBQUEsTUFxRk0sQ0FBQyxPQUFQLEdBQWlCLFVBckZqQixDQUFBOzs7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFzc2V0LCBCdWZmZXJTb3VyY2UsIERlY29kZXIsIERlbXV4ZXIsIEV2ZW50RW1pdHRlciwgRmlsZVNvdXJjZSwgSFRUUFNvdXJjZSxcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vY29yZS9ldmVudHMnKTtcblxuICBIVFRQU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvaHR0cCcpO1xuXG4gIEZpbGVTb3VyY2UgPSByZXF1aXJlKCcuL3NvdXJjZXMvbm9kZS9maWxlJyk7XG5cbiAgQnVmZmVyU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL2J1ZmZlcicpO1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuL2RlbXV4ZXInKTtcblxuICBEZWNvZGVyID0gcmVxdWlyZSgnLi9kZWNvZGVyJyk7XG5cbiAgQXNzZXQgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChBc3NldCwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBBc3NldChzb3VyY2UpIHtcbiAgICAgIHRoaXMuc291cmNlID0gc291cmNlO1xuICAgICAgdGhpcy5fZGVjb2RlID0gYmluZCh0aGlzLl9kZWNvZGUsIHRoaXMpO1xuICAgICAgdGhpcy5maW5kRGVjb2RlciA9IGJpbmQodGhpcy5maW5kRGVjb2RlciwgdGhpcyk7XG4gICAgICB0aGlzLnByb2JlID0gYmluZCh0aGlzLnByb2JlLCB0aGlzKTtcbiAgICAgIHRoaXMuYnVmZmVyZWQgPSAwO1xuICAgICAgdGhpcy5kdXJhdGlvbiA9IG51bGw7XG4gICAgICB0aGlzLmZvcm1hdCA9IG51bGw7XG4gICAgICB0aGlzLm1ldGFkYXRhID0gbnVsbDtcbiAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gICAgICB0aGlzLmRlbXV4ZXIgPSBudWxsO1xuICAgICAgdGhpcy5kZWNvZGVyID0gbnVsbDtcbiAgICAgIHRoaXMuc291cmNlLm9uY2UoJ2RhdGEnLCB0aGlzLnByb2JlKTtcbiAgICAgIHRoaXMuc291cmNlLm9uKCdlcnJvcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgX3RoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5zdG9wKCk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLnNvdXJjZS5vbigncHJvZ3Jlc3MnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcmVkKSB7XG4gICAgICAgICAgX3RoaXMuYnVmZmVyZWQgPSBidWZmZXJlZDtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnYnVmZmVyJywgX3RoaXMuYnVmZmVyZWQpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH1cblxuICAgIEFzc2V0LmZyb21VUkwgPSBmdW5jdGlvbih1cmwsIG9wdHMpIHtcbiAgICAgIHJldHVybiBuZXcgQXNzZXQobmV3IEhUVFBTb3VyY2UodXJsLCBvcHRzKSk7XG4gICAgfTtcblxuICAgIEFzc2V0LmZyb21GaWxlID0gZnVuY3Rpb24oZmlsZSkge1xuICAgICAgcmV0dXJuIG5ldyBBc3NldChuZXcgRmlsZVNvdXJjZShmaWxlKSk7XG4gICAgfTtcblxuICAgIEFzc2V0LmZyb21CdWZmZXIgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBuZXcgQXNzZXQobmV3IEJ1ZmZlclNvdXJjZShidWZmZXIpKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oZGVjb2RlKSB7XG4gICAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGRlY29kZSAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc2hvdWxkRGVjb2RlID0gZGVjb2RlO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuc2hvdWxkRGVjb2RlID09IG51bGwpIHtcbiAgICAgICAgdGhpcy5zaG91bGREZWNvZGUgPSB0cnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5hY3RpdmUgPSB0cnVlO1xuICAgICAgdGhpcy5zb3VyY2Uuc3RhcnQoKTtcbiAgICAgIGlmICh0aGlzLmRlY29kZXIgJiYgdGhpcy5zaG91bGREZWNvZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY29kZSgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICAgICAgcmV0dXJuIHRoaXMuc291cmNlLnBhdXNlKCk7XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihldmVudCwgY2FsbGJhY2spIHtcbiAgICAgIGlmIChldmVudCAhPT0gJ2Zvcm1hdCcgJiYgZXZlbnQgIT09ICdkdXJhdGlvbicgJiYgZXZlbnQgIT09ICdtZXRhZGF0YScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXNbZXZlbnRdICE9IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHRoaXNbZXZlbnRdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub25jZShldmVudCwgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBfdGhpcy5zdG9wKCk7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sodmFsdWUpO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pKHRoaXMpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnQoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmRlY29kZVBhY2tldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2Rlci5kZWNvZGUoKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmRlY29kZVRvQnVmZmVyID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICAgIHZhciBjaHVua3MsIGRhdGFIYW5kbGVyLCBsZW5ndGg7XG4gICAgICBsZW5ndGggPSAwO1xuICAgICAgY2h1bmtzID0gW107XG4gICAgICB0aGlzLm9uKCdkYXRhJywgZGF0YUhhbmRsZXIgPSBmdW5jdGlvbihjaHVuaykge1xuICAgICAgICBsZW5ndGggKz0gY2h1bmsubGVuZ3RoO1xuICAgICAgICByZXR1cm4gY2h1bmtzLnB1c2goY2h1bmspO1xuICAgICAgfSk7XG4gICAgICB0aGlzLm9uY2UoJ2VuZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYnVmLCBjaHVuaywgaiwgbGVuLCBvZmZzZXQ7XG4gICAgICAgIGJ1ZiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgICAgZm9yIChqID0gMCwgbGVuID0gY2h1bmtzLmxlbmd0aDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgY2h1bmsgPSBjaHVua3Nbal07XG4gICAgICAgICAgYnVmLnNldChjaHVuaywgb2Zmc2V0KTtcbiAgICAgICAgICBvZmZzZXQgKz0gY2h1bmsubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2ZmKCdkYXRhJywgZGF0YUhhbmRsZXIpO1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soYnVmKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRoaXMuc3RhcnQoKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLnByb2JlID0gZnVuY3Rpb24oY2h1bmspIHtcbiAgICAgIHZhciBkZW11eGVyO1xuICAgICAgaWYgKCF0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBkZW11eGVyID0gRGVtdXhlci5maW5kKGNodW5rKTtcbiAgICAgIGlmICghZGVtdXhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdBIGRlbXV4ZXIgZm9yIHRoaXMgY29udGFpbmVyIHdhcyBub3QgZm91bmQuJyk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlbXV4ZXIgPSBuZXcgZGVtdXhlcih0aGlzLnNvdXJjZSwgY2h1bmspO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdmb3JtYXQnLCB0aGlzLmZpbmREZWNvZGVyKTtcbiAgICAgIHRoaXMuZGVtdXhlci5vbignZHVyYXRpb24nLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGR1cmF0aW9uKSB7XG4gICAgICAgICAgX3RoaXMuZHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZHVyYXRpb24nLCBfdGhpcy5kdXJhdGlvbik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ21ldGFkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihtZXRhZGF0YSkge1xuICAgICAgICAgIF90aGlzLm1ldGFkYXRhID0gbWV0YWRhdGE7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ21ldGFkYXRhJywgX3RoaXMubWV0YWRhdGEpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVtdXhlci5vbignZXJyb3InLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuc3RvcCgpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZmluZERlY29kZXIgPSBmdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgIHZhciBkZWNvZGVyLCBkaXY7XG4gICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICAgIGlmICghdGhpcy5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICBkZWNvZGVyID0gRGVjb2Rlci5maW5kKHRoaXMuZm9ybWF0LmZvcm1hdElEKTtcbiAgICAgIGlmICghZGVjb2Rlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiQSBkZWNvZGVyIGZvciBcIiArIHRoaXMuZm9ybWF0LmZvcm1hdElEICsgXCIgd2FzIG5vdCBmb3VuZC5cIik7XG4gICAgICB9XG4gICAgICB0aGlzLmRlY29kZXIgPSBuZXcgZGVjb2Rlcih0aGlzLmRlbXV4ZXIsIHRoaXMuZm9ybWF0KTtcbiAgICAgIGlmICh0aGlzLmZvcm1hdC5mbG9hdGluZ1BvaW50KSB7XG4gICAgICAgIHRoaXMuZGVjb2Rlci5vbignZGF0YScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaXYgPSBNYXRoLnBvdygyLCB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAtIDEpO1xuICAgICAgICB0aGlzLmRlY29kZXIub24oJ2RhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICAgICAgICB2YXIgYnVmLCBpLCBqLCBsZW4sIHNhbXBsZTtcbiAgICAgICAgICAgIGJ1ZiA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgbGVuID0gYnVmZmVyLmxlbmd0aDsgaiA8IGxlbjsgaSA9ICsraikge1xuICAgICAgICAgICAgICBzYW1wbGUgPSBidWZmZXJbaV07XG4gICAgICAgICAgICAgIGJ1ZltpXSA9IHNhbXBsZSAvIGRpdjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdkYXRhJywgYnVmKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlY29kZXIub24oJ2Vycm9yJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgICBfdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLnN0b3AoKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuZGVjb2Rlci5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmVtaXQoJ2RlY29kZVN0YXJ0Jyk7XG4gICAgICBpZiAodGhpcy5zaG91bGREZWNvZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY29kZSgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuX2RlY29kZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgd2hpbGUgKHRoaXMuZGVjb2Rlci5kZWNvZGUoKSAmJiB0aGlzLmFjdGl2ZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGVyLm9uY2UoJ2RhdGEnLCB0aGlzLl9kZWNvZGUpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZiwgcmVmMSwgcmVmMjtcbiAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgaWYgKChyZWYgPSB0aGlzLmRlbXV4ZXIpICE9IG51bGwpIHtcbiAgICAgICAgcmVmLm9mZigpO1xuICAgICAgfVxuICAgICAgaWYgKChyZWYxID0gdGhpcy5kZWNvZGVyKSAhPSBudWxsKSB7XG4gICAgICAgIHJlZjEub2ZmKCk7XG4gICAgICB9XG4gICAgICBpZiAoKHJlZjIgPSB0aGlzLnNvdXJjZSkgIT0gbnVsbCkge1xuICAgICAgICByZWYyLm9mZigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMub2ZmKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBBc3NldDtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQXNzZXQ7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIga2V5LCByZWYsIHZhbDtcblxuICByZWYgPSByZXF1aXJlKCcuL2F1cm9yYV9iYXNlJyk7XG4gIGZvciAoa2V5IGluIHJlZikge1xuICAgIHZhbCA9IHJlZltrZXldO1xuICAgIGV4cG9ydHNba2V5XSA9IHZhbDtcbiAgfVxuXG4gIHJlcXVpcmUoJy4vZGVtdXhlcnMvY2FmJyk7XG5cbiAgcmVxdWlyZSgnLi9kZW11eGVycy9tNGEnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL2FpZmYnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL3dhdmUnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL2F1Jyk7XG5cbiAgcmVxdWlyZSgnLi9kZWNvZGVycy9scGNtJyk7XG5cbiAgcmVxdWlyZSgnLi9kZWNvZGVycy94bGF3Jyk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICBleHBvcnRzLkJhc2UgPSByZXF1aXJlKCcuL2NvcmUvYmFzZScpO1xuXG4gIGV4cG9ydHMuQnVmZmVyID0gcmVxdWlyZSgnLi9jb3JlL2J1ZmZlcicpO1xuXG4gIGV4cG9ydHMuQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgZXhwb3J0cy5TdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvc3RyZWFtJyk7XG5cbiAgZXhwb3J0cy5CaXRzdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvYml0c3RyZWFtJyk7XG5cbiAgZXhwb3J0cy5FdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgZXhwb3J0cy5VbmRlcmZsb3dFcnJvciA9IHJlcXVpcmUoJy4vY29yZS91bmRlcmZsb3cnKTtcblxuICBleHBvcnRzLkhUVFBTb3VyY2UgPSByZXF1aXJlKCcuL3NvdXJjZXMvbm9kZS9odHRwJyk7XG5cbiAgZXhwb3J0cy5GaWxlU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvZmlsZScpO1xuXG4gIGV4cG9ydHMuQnVmZmVyU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL2J1ZmZlcicpO1xuXG4gIGV4cG9ydHMuRGVtdXhlciA9IHJlcXVpcmUoJy4vZGVtdXhlcicpO1xuXG4gIGV4cG9ydHMuRGVjb2RlciA9IHJlcXVpcmUoJy4vZGVjb2RlcicpO1xuXG4gIGV4cG9ydHMuQXVkaW9EZXZpY2UgPSByZXF1aXJlKCcuL2RldmljZScpO1xuXG4gIGV4cG9ydHMuQXNzZXQgPSByZXF1aXJlKCcuL2Fzc2V0Jyk7XG5cbiAgZXhwb3J0cy5QbGF5ZXIgPSByZXF1aXJlKCcuL3BsYXllcicpO1xuXG4gIGV4cG9ydHMuRmlsdGVyID0gcmVxdWlyZSgnLi9maWx0ZXInKTtcblxuICBleHBvcnRzLlZvbHVtZUZpbHRlciA9IHJlcXVpcmUoJy4vZmlsdGVycy92b2x1bWUnKTtcblxuICBleHBvcnRzLkJhbGFuY2VGaWx0ZXIgPSByZXF1aXJlKCcuL2ZpbHRlcnMvYmFsYW5jZScpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJhc2UsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBpbmRleE9mID0gW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH07XG5cbiAgQmFzZSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgZm5UZXN0O1xuXG4gICAgZnVuY3Rpb24gQmFzZSgpIHt9XG5cbiAgICBmblRlc3QgPSAvXFxiX3N1cGVyXFxiLztcblxuICAgIEJhc2UuZXh0ZW5kID0gZnVuY3Rpb24ocHJvcCkge1xuICAgICAgdmFyIENsYXNzLCBfc3VwZXIsIGZuLCBrZXksIGtleXMsIHJlZjtcbiAgICAgIENsYXNzID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICAgICAgZXh0ZW5kKENsYXNzLCBzdXBlckNsYXNzKTtcblxuICAgICAgICBmdW5jdGlvbiBDbGFzcygpIHtcbiAgICAgICAgICByZXR1cm4gQ2xhc3MuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gQ2xhc3M7XG5cbiAgICAgIH0pKHRoaXMpO1xuICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGtleXMgPSBPYmplY3Qua2V5cyhDbGFzcy5wcm90b3R5cGUpO1xuICAgICAgICBwcm9wLmNhbGwoQ2xhc3MsIENsYXNzKTtcbiAgICAgICAgcHJvcCA9IHt9O1xuICAgICAgICByZWYgPSBDbGFzcy5wcm90b3R5cGU7XG4gICAgICAgIGZvciAoa2V5IGluIHJlZikge1xuICAgICAgICAgIGZuID0gcmVmW2tleV07XG4gICAgICAgICAgaWYgKGluZGV4T2YuY2FsbChrZXlzLCBrZXkpIDwgMCkge1xuICAgICAgICAgICAgcHJvcFtrZXldID0gZm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBfc3VwZXIgPSBDbGFzcy5fX3N1cGVyX187XG4gICAgICBmb3IgKGtleSBpbiBwcm9wKSB7XG4gICAgICAgIGZuID0gcHJvcFtrZXldO1xuICAgICAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nICYmIGZuVGVzdC50ZXN0KGZuKSkge1xuICAgICAgICAgIChmdW5jdGlvbihrZXksIGZuKSB7XG4gICAgICAgICAgICByZXR1cm4gQ2xhc3MucHJvdG90eXBlW2tleV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgdmFyIHJldCwgdG1wO1xuICAgICAgICAgICAgICB0bXAgPSB0aGlzLl9zdXBlcjtcbiAgICAgICAgICAgICAgdGhpcy5fc3VwZXIgPSBfc3VwZXJba2V5XTtcbiAgICAgICAgICAgICAgcmV0ID0gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgdGhpcy5fc3VwZXIgPSB0bXA7XG4gICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKGtleSwgZm4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIENsYXNzLnByb3RvdHlwZVtrZXldID0gZm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBDbGFzcztcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJhc2U7XG5cbiAgfSkoKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEJhc2U7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQml0c3RyZWFtO1xuXG4gIEJpdHN0cmVhbSA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBCaXRzdHJlYW0oc3RyZWFtKSB7XG4gICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgIHRoaXMuYml0UG9zaXRpb24gPSAwO1xuICAgIH1cblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBCaXRzdHJlYW0odGhpcy5zdHJlYW0uY29weSgpKTtcbiAgICAgIHJlc3VsdC5iaXRQb3NpdGlvbiA9IHRoaXMuYml0UG9zaXRpb247XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLm9mZnNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIDggKiB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmF2YWlsYWJsZSA9IGZ1bmN0aW9uKGJpdHMpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoKGJpdHMgKyA4IC0gdGhpcy5iaXRQb3NpdGlvbikgLyA4KTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5hZHZhbmNlID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gKyBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZShwb3MgPj4gMyk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmV3aW5kID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gLSBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0ucmV3aW5kKE1hdGguYWJzKHBvcyA+PiAzKSk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgdmFyIGN1ck9mZnNldDtcbiAgICAgIGN1ck9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XG4gICAgICBpZiAob2Zmc2V0ID4gY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkdmFuY2Uob2Zmc2V0IC0gY3VyT2Zmc2V0KTtcbiAgICAgIH0gZWxzZSBpZiAob2Zmc2V0IDwgY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJld2luZChjdXJPZmZzZXQgLSBvZmZzZXQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmFsaWduID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5iaXRQb3NpdGlvbiAhPT0gMCkge1xuICAgICAgICB0aGlzLmJpdFBvc2l0aW9uID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKGJpdHMsIHNpZ25lZCkge1xuICAgICAgdmFyIGEsIGEwLCBhMSwgYTIsIGEzLCBhNCwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIG1CaXRzID0gYml0cyArIHRoaXMuYml0UG9zaXRpb247XG4gICAgICBpZiAobUJpdHMgPD0gOCkge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDgoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmYpID4+PiAoOCAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSAxNikge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDE2KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmZmYpID4+PiAoMTYgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMjQpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQyNCgpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmZmYpID4+PiAoMjQgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMzIpIHtcbiAgICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDMyKCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgPj4+ICgzMiAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSA0MCkge1xuICAgICAgICBhMCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgwKSAqIDB4MDEwMDAwMDAwMDtcbiAgICAgICAgYTEgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkgPDwgMjQgPj4+IDA7XG4gICAgICAgIGEyID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDIpIDw8IDE2O1xuICAgICAgICBhMyA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgzKSA8PCA4O1xuICAgICAgICBhNCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KTtcbiAgICAgICAgYSA9IGEwICsgYTEgKyBhMiArIGEzICsgYTQ7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgNDAgLSB0aGlzLmJpdFBvc2l0aW9uKTtcbiAgICAgICAgYSA9IE1hdGguZmxvb3IoYSAvIE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbiAtIGJpdHMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRvbyBtYW55IGJpdHMhXCIpO1xuICAgICAgfVxuICAgICAgaWYgKHNpZ25lZCkge1xuICAgICAgICBpZiAobUJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChhID4+PiAoYml0cyAtIDEpKSB7XG4gICAgICAgICAgICBhID0gKCgxIDw8IGJpdHMgPj4+IDApIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGEgLyBNYXRoLnBvdygyLCBiaXRzIC0gMSkgfCAwKSB7XG4gICAgICAgICAgICBhID0gKE1hdGgucG93KDIsIGJpdHMpIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuYWR2YW5jZShiaXRzKTtcbiAgICAgIHJldHVybiBhO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLnBlZWsgPSBmdW5jdGlvbihiaXRzLCBzaWduZWQpIHtcbiAgICAgIHZhciBhLCBhMCwgYTEsIGEyLCBhMywgYTQsIG1CaXRzO1xuICAgICAgaWYgKGJpdHMgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzIDw9IDgpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQ4KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmKSA+Pj4gKDggLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMTYpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQxNigpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmKSA+Pj4gKDE2IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDI0KSB7XG4gICAgICAgIGEgPSAoKHRoaXMuc3RyZWFtLnBlZWtVSW50MjQoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmZmZmZmKSA+Pj4gKDI0IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDMyKSB7XG4gICAgICAgIGEgPSAodGhpcy5zdHJlYW0ucGVla1VJbnQzMigpIDw8IHRoaXMuYml0UG9zaXRpb24pID4+PiAoMzIgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gNDApIHtcbiAgICAgICAgYTAgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkgKiAweDAxMDAwMDAwMDA7XG4gICAgICAgIGExID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDEpIDw8IDI0ID4+PiAwO1xuICAgICAgICBhMiA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgyKSA8PCAxNjtcbiAgICAgICAgYTMgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMykgPDwgODtcbiAgICAgICAgYTQgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoNCk7XG4gICAgICAgIGEgPSBhMCArIGExICsgYTIgKyBhMyArIGE0O1xuICAgICAgICBhICU9IE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICAgIGEgPSBNYXRoLmZsb29yKGEgLyBNYXRoLnBvdygyLCA0MCAtIHRoaXMuYml0UG9zaXRpb24gLSBiaXRzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUb28gbWFueSBiaXRzIVwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5yZWFkTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmFkdmFuY2UoYml0cyk7XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5wZWVrTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJpdHN0cmVhbTtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQml0c3RyZWFtO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyO1xuXG4gIEFWQnVmZmVyID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBCbG9iQnVpbGRlciwgVVJMO1xuXG4gICAgZnVuY3Rpb24gQVZCdWZmZXIoaW5wdXQpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGlucHV0O1xuICAgICAgfSBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IEFycmF5LmlzQXJyYXkoaW5wdXQpIHx8IHR5cGVvZiBpbnB1dCA9PT0gJ251bWJlcicgfHwgKChyZWYgPSBnbG9iYWwuQnVmZmVyKSAhPSBudWxsID8gcmVmLmlzQnVmZmVyKGlucHV0KSA6IHZvaWQgMCkpIHtcbiAgICAgICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoaW5wdXQpO1xuICAgICAgfSBlbHNlIGlmIChpbnB1dC5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShpbnB1dC5idWZmZXIsIGlucHV0LmJ5dGVPZmZzZXQsIGlucHV0Lmxlbmd0aCAqIGlucHV0LkJZVEVTX1BFUl9FTEVNRU5UKTtcbiAgICAgIH0gZWxzZSBpZiAoaW5wdXQgaW5zdGFuY2VvZiBBVkJ1ZmZlcikge1xuICAgICAgICB0aGlzLmRhdGEgPSBpbnB1dC5kYXRhO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29uc3RydWN0aW5nIGJ1ZmZlciB3aXRoIHVua25vd24gdHlwZS5cIik7XG4gICAgICB9XG4gICAgICB0aGlzLmxlbmd0aCA9IHRoaXMuZGF0YS5sZW5ndGg7XG4gICAgICB0aGlzLm5leHQgPSBudWxsO1xuICAgICAgdGhpcy5wcmV2ID0gbnVsbDtcbiAgICB9XG5cbiAgICBBVkJ1ZmZlci5hbGxvY2F0ZSA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIoc2l6ZSk7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IEFWQnVmZmVyKG5ldyBVaW50OEFycmF5KHRoaXMuZGF0YSkpO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbihwb3NpdGlvbiwgbGVuZ3RoKSB7XG4gICAgICBpZiAobGVuZ3RoID09IG51bGwpIHtcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgICB9XG4gICAgICBpZiAocG9zaXRpb24gPT09IDAgJiYgbGVuZ3RoID49IHRoaXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIodGhpcy5kYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIodGhpcy5kYXRhLnN1YmFycmF5KHBvc2l0aW9uLCBwb3NpdGlvbiArIGxlbmd0aCkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCbG9iQnVpbGRlciA9IGdsb2JhbC5CbG9iQnVpbGRlciB8fCBnbG9iYWwuTW96QmxvYkJ1aWxkZXIgfHwgZ2xvYmFsLldlYktpdEJsb2JCdWlsZGVyO1xuXG4gICAgVVJMID0gZ2xvYmFsLlVSTCB8fCBnbG9iYWwud2Via2l0VVJMIHx8IGdsb2JhbC5tb3pVUkw7XG5cbiAgICBBVkJ1ZmZlci5tYWtlQmxvYiA9IGZ1bmN0aW9uKGRhdGEsIHR5cGUpIHtcbiAgICAgIHZhciBiYjtcbiAgICAgIGlmICh0eXBlID09IG51bGwpIHtcbiAgICAgICAgdHlwZSA9ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBCbG9iKFtkYXRhXSwge1xuICAgICAgICAgIHR5cGU6IHR5cGVcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoICh1bmRlZmluZWQpIHt9XG4gICAgICBpZiAoQmxvYkJ1aWxkZXIgIT0gbnVsbCkge1xuICAgICAgICBiYiA9IG5ldyBCbG9iQnVpbGRlcjtcbiAgICAgICAgYmIuYXBwZW5kKGRhdGEpO1xuICAgICAgICByZXR1cm4gYmIuZ2V0QmxvYih0eXBlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5tYWtlQmxvYlVSTCA9IGZ1bmN0aW9uKGRhdGEsIHR5cGUpIHtcbiAgICAgIHJldHVybiBVUkwgIT0gbnVsbCA/IFVSTC5jcmVhdGVPYmplY3RVUkwodGhpcy5tYWtlQmxvYihkYXRhLCB0eXBlKSkgOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnJldm9rZUJsb2JVUkwgPSBmdW5jdGlvbih1cmwpIHtcbiAgICAgIHJldHVybiBVUkwgIT0gbnVsbCA/IFVSTC5yZXZva2VPYmplY3RVUkwodXJsKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgQVZCdWZmZXIucHJvdG90eXBlLnRvQmxvYiA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIEFWQnVmZmVyLm1ha2VCbG9iKHRoaXMuZGF0YS5idWZmZXIpO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5wcm90b3R5cGUudG9CbG9iVVJMID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gQVZCdWZmZXIubWFrZUJsb2JVUkwodGhpcy5kYXRhLmJ1ZmZlcik7XG4gICAgfTtcblxuICAgIHJldHVybiBBVkJ1ZmZlcjtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQVZCdWZmZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQnVmZmVyTGlzdDtcblxuICBCdWZmZXJMaXN0ID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIEJ1ZmZlckxpc3QoKSB7XG4gICAgICB0aGlzLmZpcnN0ID0gbnVsbDtcbiAgICAgIHRoaXMubGFzdCA9IG51bGw7XG4gICAgICB0aGlzLm51bUJ1ZmZlcnMgPSAwO1xuICAgICAgdGhpcy5hdmFpbGFibGVCeXRlcyA9IDA7XG4gICAgICB0aGlzLmF2YWlsYWJsZUJ1ZmZlcnMgPSAwO1xuICAgIH1cblxuICAgIEJ1ZmZlckxpc3QucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICByZXN1bHQgPSBuZXcgQnVmZmVyTGlzdDtcbiAgICAgIHJlc3VsdC5maXJzdCA9IHRoaXMuZmlyc3Q7XG4gICAgICByZXN1bHQubGFzdCA9IHRoaXMubGFzdDtcbiAgICAgIHJlc3VsdC5udW1CdWZmZXJzID0gdGhpcy5udW1CdWZmZXJzO1xuICAgICAgcmVzdWx0LmF2YWlsYWJsZUJ5dGVzID0gdGhpcy5hdmFpbGFibGVCeXRlcztcbiAgICAgIHJlc3VsdC5hdmFpbGFibGVCdWZmZXJzID0gdGhpcy5hdmFpbGFibGVCdWZmZXJzO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgQnVmZmVyTGlzdC5wcm90b3R5cGUuYXBwZW5kID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgYnVmZmVyLnByZXYgPSB0aGlzLmxhc3Q7XG4gICAgICBpZiAoKHJlZiA9IHRoaXMubGFzdCkgIT0gbnVsbCkge1xuICAgICAgICByZWYubmV4dCA9IGJ1ZmZlcjtcbiAgICAgIH1cbiAgICAgIHRoaXMubGFzdCA9IGJ1ZmZlcjtcbiAgICAgIGlmICh0aGlzLmZpcnN0ID09IG51bGwpIHtcbiAgICAgICAgdGhpcy5maXJzdCA9IGJ1ZmZlcjtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXZhaWxhYmxlQnl0ZXMgKz0gYnVmZmVyLmxlbmd0aDtcbiAgICAgIHRoaXMuYXZhaWxhYmxlQnVmZmVycysrO1xuICAgICAgcmV0dXJuIHRoaXMubnVtQnVmZmVycysrO1xuICAgIH07XG5cbiAgICBCdWZmZXJMaXN0LnByb3RvdHlwZS5hZHZhbmNlID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5maXJzdCkge1xuICAgICAgICB0aGlzLmF2YWlsYWJsZUJ5dGVzIC09IHRoaXMuZmlyc3QubGVuZ3RoO1xuICAgICAgICB0aGlzLmF2YWlsYWJsZUJ1ZmZlcnMtLTtcbiAgICAgICAgdGhpcy5maXJzdCA9IHRoaXMuZmlyc3QubmV4dDtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmlyc3QgIT0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgQnVmZmVyTGlzdC5wcm90b3R5cGUucmV3aW5kID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgaWYgKHRoaXMuZmlyc3QgJiYgIXRoaXMuZmlyc3QucHJldikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB0aGlzLmZpcnN0ID0gKChyZWYgPSB0aGlzLmZpcnN0KSAhPSBudWxsID8gcmVmLnByZXYgOiB2b2lkIDApIHx8IHRoaXMubGFzdDtcbiAgICAgIGlmICh0aGlzLmZpcnN0KSB7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlQnl0ZXMgKz0gdGhpcy5maXJzdC5sZW5ndGg7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlQnVmZmVycysrO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZmlyc3QgIT0gbnVsbDtcbiAgICB9O1xuXG4gICAgQnVmZmVyTGlzdC5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZXN1bHRzO1xuICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgd2hpbGUgKHRoaXMucmV3aW5kKCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJ1ZmZlckxpc3Q7XG5cbiAgfSkoKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEJ1ZmZlckxpc3Q7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQmFzZSwgRXZlbnRFbWl0dGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgc2xpY2UgPSBbXS5zbGljZTtcblxuICBCYXNlID0gcmVxdWlyZSgnLi9iYXNlJyk7XG5cbiAgRXZlbnRFbWl0dGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoRXZlbnRFbWl0dGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgICAgIHJldHVybiBFdmVudEVtaXR0ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uKGV2ZW50LCBmbikge1xuICAgICAgdmFyIGJhc2U7XG4gICAgICBpZiAodGhpcy5ldmVudHMgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmV2ZW50cyA9IHt9O1xuICAgICAgfVxuICAgICAgaWYgKChiYXNlID0gdGhpcy5ldmVudHMpW2V2ZW50XSA9PSBudWxsKSB7XG4gICAgICAgIGJhc2VbZXZlbnRdID0gW107XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5ldmVudHNbZXZlbnRdLnB1c2goZm4pO1xuICAgIH07XG5cbiAgICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uKGV2ZW50LCBmbikge1xuICAgICAgdmFyIGV2ZW50cywgaW5kZXgsIHJlZjtcbiAgICAgIGlmICh0aGlzLmV2ZW50cyA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICgocmVmID0gdGhpcy5ldmVudHMpICE9IG51bGwgPyByZWZbZXZlbnRdIDogdm9pZCAwKSB7XG4gICAgICAgIGlmIChmbiAhPSBudWxsKSB7XG4gICAgICAgICAgaW5kZXggPSB0aGlzLmV2ZW50c1tldmVudF0uaW5kZXhPZihmbik7XG4gICAgICAgICAgaWYgKH5pbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzW2V2ZW50XS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHNbZXZlbnRdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGV2ZW50cyA9IHt9O1xuICAgICAgfVxuICAgIH07XG5cbiAgICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pIHtcbiAgICAgIHZhciBjYjtcbiAgICAgIHJldHVybiB0aGlzLm9uKGV2ZW50LCBjYiA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLm9mZihldmVudCwgY2IpO1xuICAgICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhcmdzLCBldmVudCwgZm4sIGksIGxlbiwgcmVmLCByZWYxO1xuICAgICAgZXZlbnQgPSBhcmd1bWVudHNbMF0sIGFyZ3MgPSAyIDw9IGFyZ3VtZW50cy5sZW5ndGggPyBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkgOiBbXTtcbiAgICAgIGlmICghKChyZWYgPSB0aGlzLmV2ZW50cykgIT0gbnVsbCA/IHJlZltldmVudF0gOiB2b2lkIDApKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJlZjEgPSB0aGlzLmV2ZW50c1tldmVudF0uc2xpY2UoKTtcbiAgICAgIGZvciAoaSA9IDAsIGxlbiA9IHJlZjEubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgZm4gPSByZWYxW2ldO1xuICAgICAgICBmbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcblxuICB9KShCYXNlKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBVkJ1ZmZlciwgQnVmZmVyTGlzdCwgU3RyZWFtLCBVbmRlcmZsb3dFcnJvcjtcblxuICBCdWZmZXJMaXN0ID0gcmVxdWlyZSgnLi9idWZmZXJsaXN0Jyk7XG5cbiAgQVZCdWZmZXIgPSByZXF1aXJlKCcuL2J1ZmZlcicpO1xuXG4gIFVuZGVyZmxvd0Vycm9yID0gcmVxdWlyZSgnLi91bmRlcmZsb3cnKTtcblxuICBTdHJlYW0gPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ1ZiwgZGVjb2RlU3RyaW5nLCBmbG9hdDMyLCBmbG9hdDY0LCBmbG9hdDY0RmFsbGJhY2ssIGZsb2F0ODAsIGludDE2LCBpbnQzMiwgaW50OCwgbmF0aXZlRW5kaWFuLCB1aW50MTYsIHVpbnQzMiwgdWludDg7XG5cbiAgICBidWYgPSBuZXcgQXJyYXlCdWZmZXIoMTYpO1xuXG4gICAgdWludDggPSBuZXcgVWludDhBcnJheShidWYpO1xuXG4gICAgaW50OCA9IG5ldyBJbnQ4QXJyYXkoYnVmKTtcblxuICAgIHVpbnQxNiA9IG5ldyBVaW50MTZBcnJheShidWYpO1xuXG4gICAgaW50MTYgPSBuZXcgSW50MTZBcnJheShidWYpO1xuXG4gICAgdWludDMyID0gbmV3IFVpbnQzMkFycmF5KGJ1Zik7XG5cbiAgICBpbnQzMiA9IG5ldyBJbnQzMkFycmF5KGJ1Zik7XG5cbiAgICBmbG9hdDMyID0gbmV3IEZsb2F0MzJBcnJheShidWYpO1xuXG4gICAgaWYgKHR5cGVvZiBGbG9hdDY0QXJyYXkgIT09IFwidW5kZWZpbmVkXCIgJiYgRmxvYXQ2NEFycmF5ICE9PSBudWxsKSB7XG4gICAgICBmbG9hdDY0ID0gbmV3IEZsb2F0NjRBcnJheShidWYpO1xuICAgIH1cblxuICAgIG5hdGl2ZUVuZGlhbiA9IG5ldyBVaW50MTZBcnJheShuZXcgVWludDhBcnJheShbMHgxMiwgMHgzNF0pLmJ1ZmZlcilbMF0gPT09IDB4MzQxMjtcblxuICAgIGZ1bmN0aW9uIFN0cmVhbShsaXN0MSkge1xuICAgICAgdGhpcy5saXN0ID0gbGlzdDE7XG4gICAgICB0aGlzLmxvY2FsT2Zmc2V0ID0gMDtcbiAgICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICB9XG5cbiAgICBTdHJlYW0uZnJvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIGxpc3Q7XG4gICAgICBsaXN0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICBsaXN0LmFwcGVuZChidWZmZXIpO1xuICAgICAgcmV0dXJuIG5ldyBTdHJlYW0obGlzdCk7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBTdHJlYW0odGhpcy5saXN0LmNvcHkoKSk7XG4gICAgICByZXN1bHQubG9jYWxPZmZzZXQgPSB0aGlzLmxvY2FsT2Zmc2V0O1xuICAgICAgcmVzdWx0Lm9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5hdmFpbGFibGUgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgcmV0dXJuIGJ5dGVzIDw9IHRoaXMubGlzdC5hdmFpbGFibGVCeXRlcyAtIHRoaXMubG9jYWxPZmZzZXQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVtYWluaW5nQnl0ZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmxpc3QuYXZhaWxhYmxlQnl0ZXMgLSB0aGlzLmxvY2FsT2Zmc2V0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLmFkdmFuY2UgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZShieXRlcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuZGVyZmxvd0Vycm9yKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmxvY2FsT2Zmc2V0ICs9IGJ5dGVzO1xuICAgICAgdGhpcy5vZmZzZXQgKz0gYnl0ZXM7XG4gICAgICB3aGlsZSAodGhpcy5saXN0LmZpcnN0ICYmIHRoaXMubG9jYWxPZmZzZXQgPj0gdGhpcy5saXN0LmZpcnN0Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmxvY2FsT2Zmc2V0IC09IHRoaXMubGlzdC5maXJzdC5sZW5ndGg7XG4gICAgICAgIHRoaXMubGlzdC5hZHZhbmNlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZXdpbmQgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgaWYgKGJ5dGVzID4gdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuZGVyZmxvd0Vycm9yKCk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMubGlzdC5maXJzdCkge1xuICAgICAgICB0aGlzLmxpc3QucmV3aW5kKCk7XG4gICAgICAgIHRoaXMubG9jYWxPZmZzZXQgPSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2NhbE9mZnNldCAtPSBieXRlcztcbiAgICAgIHRoaXMub2Zmc2V0IC09IGJ5dGVzO1xuICAgICAgd2hpbGUgKHRoaXMubGlzdC5maXJzdC5wcmV2ICYmIHRoaXMubG9jYWxPZmZzZXQgPCAwKSB7XG4gICAgICAgIHRoaXMubGlzdC5yZXdpbmQoKTtcbiAgICAgICAgdGhpcy5sb2NhbE9mZnNldCArPSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHBvc2l0aW9uKSB7XG4gICAgICBpZiAocG9zaXRpb24gPiB0aGlzLm9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hZHZhbmNlKHBvc2l0aW9uIC0gdGhpcy5vZmZzZXQpO1xuICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbiA8IHRoaXMub2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJld2luZCh0aGlzLm9mZnNldCAtIHBvc2l0aW9uKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhO1xuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIGEgPSB0aGlzLmxpc3QuZmlyc3QuZGF0YVt0aGlzLmxvY2FsT2Zmc2V0XTtcbiAgICAgIHRoaXMubG9jYWxPZmZzZXQgKz0gMTtcbiAgICAgIHRoaXMub2Zmc2V0ICs9IDE7XG4gICAgICBpZiAodGhpcy5sb2NhbE9mZnNldCA9PT0gdGhpcy5saXN0LmZpcnN0Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmxvY2FsT2Zmc2V0ID0gMDtcbiAgICAgICAgdGhpcy5saXN0LmFkdmFuY2UoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtVSW50OCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgdmFyIGJ1ZmZlcjtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZShvZmZzZXQgKyAxKSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIG9mZnNldCA9IHRoaXMubG9jYWxPZmZzZXQgKyBvZmZzZXQ7XG4gICAgICBidWZmZXIgPSB0aGlzLmxpc3QuZmlyc3Q7XG4gICAgICB3aGlsZSAoYnVmZmVyKSB7XG4gICAgICAgIGlmIChidWZmZXIubGVuZ3RoID4gb2Zmc2V0KSB7XG4gICAgICAgICAgcmV0dXJuIGJ1ZmZlci5kYXRhW29mZnNldF07XG4gICAgICAgIH1cbiAgICAgICAgb2Zmc2V0IC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgIGJ1ZmZlciA9IGJ1ZmZlci5uZXh0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIDA7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzLCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHZhciBpLCBqLCBrLCByZWYsIHJlZjE7XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09IG51bGwpIHtcbiAgICAgICAgbGl0dGxlRW5kaWFuID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09PSBuYXRpdmVFbmRpYW4pIHtcbiAgICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IGJ5dGVzOyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgICAgdWludDhbaV0gPSB0aGlzLnJlYWRVSW50OCgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgPSBrID0gcmVmMSA9IGJ5dGVzIC0gMTsgayA+PSAwOyBpID0gayArPSAtMSkge1xuICAgICAgICAgIHVpbnQ4W2ldID0gdGhpcy5yZWFkVUludDgoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWsgPSBmdW5jdGlvbihieXRlcywgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHZhciBpLCBqLCBrLCByZWYsIHJlZjE7XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09IG51bGwpIHtcbiAgICAgICAgbGl0dGxlRW5kaWFuID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09PSBuYXRpdmVFbmRpYW4pIHtcbiAgICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IGJ5dGVzOyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgICAgdWludDhbaV0gPSB0aGlzLnBlZWtVSW50OChvZmZzZXQgKyBpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChpID0gayA9IDAsIHJlZjEgPSBieXRlczsgayA8IHJlZjE7IGkgPSBrICs9IDEpIHtcbiAgICAgICAgICB1aW50OFtieXRlcyAtIGkgLSAxXSA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCArIGkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMucmVhZCgxKTtcbiAgICAgIHJldHVybiBpbnQ4WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtJbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlaygxLCBvZmZzZXQpO1xuICAgICAgcmV0dXJuIGludDhbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZFVJbnQxNiA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDIsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gdWludDE2WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtVSW50MTYgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoMiwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIHVpbnQxNlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkSW50MTYgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCgyLCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGludDE2WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtJbnQxNiA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlaygyLCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gaW50MTZbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZFVJbnQyNCA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkVUludDE2KHRydWUpICsgKHRoaXMucmVhZFVJbnQ4KCkgPDwgMTYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnJlYWRVSW50MTYoKSA8PCA4KSArIHRoaXMucmVhZFVJbnQ4KCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1VJbnQyNCA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIGlmIChsaXR0bGVFbmRpYW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGVla1VJbnQxNihvZmZzZXQsIHRydWUpICsgKHRoaXMucGVla1VJbnQ4KG9mZnNldCArIDIpIDw8IDE2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAodGhpcy5wZWVrVUludDE2KG9mZnNldCkgPDwgOCkgKyB0aGlzLnBlZWtVSW50OChvZmZzZXQgKyAyKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkSW50MjQgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChsaXR0bGVFbmRpYW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZFVJbnQxNih0cnVlKSArICh0aGlzLnJlYWRJbnQ4KCkgPDwgMTYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnJlYWRJbnQxNigpIDw8IDgpICsgdGhpcy5yZWFkVUludDgoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrSW50MjQgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBlZWtVSW50MTYob2Zmc2V0LCB0cnVlKSArICh0aGlzLnBlZWtJbnQ4KG9mZnNldCArIDIpIDw8IDE2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAodGhpcy5wZWVrSW50MTYob2Zmc2V0KSA8PCA4KSArIHRoaXMucGVla1VJbnQ4KG9mZnNldCArIDIpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRVSW50MzIgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCg0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIHVpbnQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrVUludDMyID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDQsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiB1aW50MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEludDMyID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoNCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBpbnQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrSW50MzIgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoNCwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGludDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRGbG9hdDMyID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoNCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBmbG9hdDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtGbG9hdDMyID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDQsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBmbG9hdDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRGbG9hdDY0ID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoOCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIGlmIChmbG9hdDY0KSB7XG4gICAgICAgIHJldHVybiBmbG9hdDY0WzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZsb2F0NjRGYWxsYmFjaygpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBmbG9hdDY0RmFsbGJhY2sgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBleHAsIGZyYWMsIGhpZ2gsIGxvdywgb3V0LCBzaWduO1xuICAgICAgbG93ID0gdWludDMyWzBdLCBoaWdoID0gdWludDMyWzFdO1xuICAgICAgaWYgKCFoaWdoIHx8IGhpZ2ggPT09IDB4ODAwMDAwMDApIHtcbiAgICAgICAgcmV0dXJuIDAuMDtcbiAgICAgIH1cbiAgICAgIHNpZ24gPSAxIC0gKGhpZ2ggPj4+IDMxKSAqIDI7XG4gICAgICBleHAgPSAoaGlnaCA+Pj4gMjApICYgMHg3ZmY7XG4gICAgICBmcmFjID0gaGlnaCAmIDB4ZmZmZmY7XG4gICAgICBpZiAoZXhwID09PSAweDdmZikge1xuICAgICAgICBpZiAoZnJhYykge1xuICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNpZ24gKiBJbmZpbml0eTtcbiAgICAgIH1cbiAgICAgIGV4cCAtPSAxMDIzO1xuICAgICAgb3V0ID0gKGZyYWMgfCAweDEwMDAwMCkgKiBNYXRoLnBvdygyLCBleHAgLSAyMCk7XG4gICAgICBvdXQgKz0gbG93ICogTWF0aC5wb3coMiwgZXhwIC0gNTIpO1xuICAgICAgcmV0dXJuIHNpZ24gKiBvdXQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0Zsb2F0NjQgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoOCwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgaWYgKGZsb2F0NjQpIHtcbiAgICAgICAgcmV0dXJuIGZsb2F0NjRbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmxvYXQ2NEZhbGxiYWNrKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEZsb2F0ODAgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCgxMCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBmbG9hdDgwKCk7XG4gICAgfTtcblxuICAgIGZsb2F0ODAgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhMCwgYTEsIGV4cCwgaGlnaCwgbG93LCBvdXQsIHNpZ247XG4gICAgICBoaWdoID0gdWludDMyWzBdLCBsb3cgPSB1aW50MzJbMV07XG4gICAgICBhMCA9IHVpbnQ4WzldO1xuICAgICAgYTEgPSB1aW50OFs4XTtcbiAgICAgIHNpZ24gPSAxIC0gKGEwID4+PiA3KSAqIDI7XG4gICAgICBleHAgPSAoKGEwICYgMHg3RikgPDwgOCkgfCBhMTtcbiAgICAgIGlmIChleHAgPT09IDAgJiYgbG93ID09PSAwICYmIGhpZ2ggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBpZiAoZXhwID09PSAweDdmZmYpIHtcbiAgICAgICAgaWYgKGxvdyA9PT0gMCAmJiBoaWdoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHNpZ24gKiBJbmZpbml0eTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgfVxuICAgICAgZXhwIC09IDE2MzgzO1xuICAgICAgb3V0ID0gbG93ICogTWF0aC5wb3coMiwgZXhwIC0gMzEpO1xuICAgICAgb3V0ICs9IGhpZ2ggKiBNYXRoLnBvdygyLCBleHAgLSA2Myk7XG4gICAgICByZXR1cm4gc2lnbiAqIG91dDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrRmxvYXQ4MCA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlaygxMCwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGZsb2F0ODAoKTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkQnVmZmVyID0gZnVuY3Rpb24obGVuZ3RoKSB7XG4gICAgICB2YXIgaSwgaiwgcmVmLCByZXN1bHQsIHRvO1xuICAgICAgcmVzdWx0ID0gQVZCdWZmZXIuYWxsb2NhdGUobGVuZ3RoKTtcbiAgICAgIHRvID0gcmVzdWx0LmRhdGE7XG4gICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gbGVuZ3RoOyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgIHRvW2ldID0gdGhpcy5yZWFkVUludDgoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0J1ZmZlciA9IGZ1bmN0aW9uKG9mZnNldCwgbGVuZ3RoKSB7XG4gICAgICB2YXIgaSwgaiwgcmVmLCByZXN1bHQsIHRvO1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBBVkJ1ZmZlci5hbGxvY2F0ZShsZW5ndGgpO1xuICAgICAgdG8gPSByZXN1bHQuZGF0YTtcbiAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBsZW5ndGg7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgdG9baV0gPSB0aGlzLnBlZWtVSW50OChvZmZzZXQgKyBpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZFNpbmdsZUJ1ZmZlciA9IGZ1bmN0aW9uKGxlbmd0aCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IHRoaXMubGlzdC5maXJzdC5zbGljZSh0aGlzLmxvY2FsT2Zmc2V0LCBsZW5ndGgpO1xuICAgICAgdGhpcy5hZHZhbmNlKHJlc3VsdC5sZW5ndGgpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrU2luZ2xlQnVmZmVyID0gZnVuY3Rpb24ob2Zmc2V0LCBsZW5ndGgpIHtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICByZXN1bHQgPSB0aGlzLmxpc3QuZmlyc3Quc2xpY2UodGhpcy5sb2NhbE9mZnNldCArIG9mZnNldCwgbGVuZ3RoKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZFN0cmluZyA9IGZ1bmN0aW9uKGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7XG4gICAgICAgIGVuY29kaW5nID0gJ2FzY2lpJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZWNvZGVTdHJpbmcuY2FsbCh0aGlzLCAwLCBsZW5ndGgsIGVuY29kaW5nLCB0cnVlKTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrU3RyaW5nID0gZnVuY3Rpb24ob2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7XG4gICAgICAgIGVuY29kaW5nID0gJ2FzY2lpJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZWNvZGVTdHJpbmcuY2FsbCh0aGlzLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcsIGZhbHNlKTtcbiAgICB9O1xuXG4gICAgZGVjb2RlU3RyaW5nID0gZnVuY3Rpb24ob2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nLCBhZHZhbmNlKSB7XG4gICAgICB2YXIgYjEsIGIyLCBiMywgYjQsIGJvbSwgYywgZW5kLCBsaXR0bGVFbmRpYW4sIG51bGxFbmQsIHB0LCByZXN1bHQsIHcxLCB3MjtcbiAgICAgIGVuY29kaW5nID0gZW5jb2RpbmcudG9Mb3dlckNhc2UoKTtcbiAgICAgIG51bGxFbmQgPSBsZW5ndGggPT09IG51bGwgPyAwIDogLTE7XG4gICAgICBpZiAobGVuZ3RoID09IG51bGwpIHtcbiAgICAgICAgbGVuZ3RoID0gSW5maW5pdHk7XG4gICAgICB9XG4gICAgICBlbmQgPSBvZmZzZXQgKyBsZW5ndGg7XG4gICAgICByZXN1bHQgPSAnJztcbiAgICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgICAgIHdoaWxlIChvZmZzZXQgPCBlbmQgJiYgKGMgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykpICE9PSBudWxsRW5kKSB7XG4gICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgICAgd2hpbGUgKG9mZnNldCA8IGVuZCAmJiAoYjEgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykpICE9PSBudWxsRW5kKSB7XG4gICAgICAgICAgICBpZiAoKGIxICYgMHg4MCkgPT09IDApIHtcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYjEpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoYjEgJiAweGUwKSA9PT0gMHhjMCkge1xuICAgICAgICAgICAgICBiMiA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYjEgJiAweDFmKSA8PCA2KSB8IGIyKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGIxICYgMHhmMCkgPT09IDB4ZTApIHtcbiAgICAgICAgICAgICAgYjIgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICBiMyA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYjEgJiAweDBmKSA8PCAxMikgfCAoYjIgPDwgNikgfCBiMyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChiMSAmIDB4ZjgpID09PSAweGYwKSB7XG4gICAgICAgICAgICAgIGIyID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgYjMgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICBiNCA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIHB0ID0gKCgoYjEgJiAweDBmKSA8PCAxOCkgfCAoYjIgPDwgMTIpIHwgKGIzIDw8IDYpIHwgYjQpIC0gMHgxMDAwMDtcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHhkODAwICsgKHB0ID4+IDEwKSwgMHhkYzAwICsgKHB0ICYgMHgzZmYpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3V0ZjE2LWJlJzpcbiAgICAgICAgY2FzZSAndXRmMTZiZSc6XG4gICAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgICBjYXNlICd1dGYxNi1sZSc6XG4gICAgICAgIGNhc2UgJ3V0ZjE2Ym9tJzpcbiAgICAgICAgY2FzZSAndXRmMTYtYm9tJzpcbiAgICAgICAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICAgICAgICBjYXNlICd1dGYxNmJlJzpcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2LWJlJzpcbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gZmFsc2U7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICAgICAgICBjYXNlICd1dGYxNi1sZSc6XG4gICAgICAgICAgICAgIGxpdHRsZUVuZGlhbiA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndXRmMTZib20nOlxuICAgICAgICAgICAgY2FzZSAndXRmMTYtYm9tJzpcbiAgICAgICAgICAgICAgaWYgKGxlbmd0aCA8IDIgfHwgKGJvbSA9IHRoaXMucGVla1VJbnQxNihvZmZzZXQpKSA9PT0gbnVsbEVuZCkge1xuICAgICAgICAgICAgICAgIGlmIChhZHZhbmNlKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmFkdmFuY2Uob2Zmc2V0ICs9IDIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGxpdHRsZUVuZGlhbiA9IGJvbSA9PT0gMHhmZmZlO1xuICAgICAgICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgICB9XG4gICAgICAgICAgd2hpbGUgKG9mZnNldCA8IGVuZCAmJiAodzEgPSB0aGlzLnBlZWtVSW50MTYob2Zmc2V0LCBsaXR0bGVFbmRpYW4pKSAhPT0gbnVsbEVuZCkge1xuICAgICAgICAgICAgb2Zmc2V0ICs9IDI7XG4gICAgICAgICAgICBpZiAodzEgPCAweGQ4MDAgfHwgdzEgPiAweGRmZmYpIHtcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodzEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKHcxID4gMHhkYmZmKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB1dGYxNiBzZXF1ZW5jZS5cIik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdzIgPSB0aGlzLnBlZWtVSW50MTYob2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgICBpZiAodzIgPCAweGRjMDAgfHwgdzIgPiAweGRmZmYpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHV0ZjE2IHNlcXVlbmNlLlwiKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh3MSwgdzIpO1xuICAgICAgICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHcxID09PSBudWxsRW5kKSB7XG4gICAgICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBlbmNvZGluZzogXCIgKyBlbmNvZGluZyk7XG4gICAgICB9XG4gICAgICBpZiAoYWR2YW5jZSkge1xuICAgICAgICB0aGlzLmFkdmFuY2Uob2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIHJldHVybiBTdHJlYW07XG5cbiAgfSkoKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFN0cmVhbTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBVbmRlcmZsb3dFcnJvcixcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIFVuZGVyZmxvd0Vycm9yID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoVW5kZXJmbG93RXJyb3IsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gVW5kZXJmbG93RXJyb3IoKSB7XG4gICAgICBVbmRlcmZsb3dFcnJvci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHRoaXMubmFtZSA9ICdVbmRlcmZsb3dFcnJvcic7XG4gICAgICB0aGlzLnN0YWNrID0gbmV3IEVycm9yKCkuc3RhY2s7XG4gICAgfVxuXG4gICAgcmV0dXJuIFVuZGVyZmxvd0Vycm9yO1xuXG4gIH0pKEVycm9yKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFVuZGVyZmxvd0Vycm9yO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJpdHN0cmVhbSwgQnVmZmVyTGlzdCwgRGVjb2RlciwgRXZlbnRFbWl0dGVyLCBTdHJlYW0sIFVuZGVyZmxvd0Vycm9yLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2NvcmUvYnVmZmVybGlzdCcpO1xuXG4gIFN0cmVhbSA9IHJlcXVpcmUoJy4vY29yZS9zdHJlYW0nKTtcblxuICBCaXRzdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvYml0c3RyZWFtJyk7XG5cbiAgVW5kZXJmbG93RXJyb3IgPSByZXF1aXJlKCcuL2NvcmUvdW5kZXJmbG93Jyk7XG5cbiAgRGVjb2RlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGNvZGVjcztcblxuICAgIGV4dGVuZChEZWNvZGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIERlY29kZXIoZGVtdXhlciwgZm9ybWF0KSB7XG4gICAgICB2YXIgbGlzdDtcbiAgICAgIHRoaXMuZGVtdXhlciA9IGRlbXV4ZXI7XG4gICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICAgIGxpc3QgPSBuZXcgQnVmZmVyTGlzdDtcbiAgICAgIHRoaXMuc3RyZWFtID0gbmV3IFN0cmVhbShsaXN0KTtcbiAgICAgIHRoaXMuYml0c3RyZWFtID0gbmV3IEJpdHN0cmVhbSh0aGlzLnN0cmVhbSk7XG4gICAgICB0aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIgPSBmYWxzZTtcbiAgICAgIHRoaXMud2FpdGluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdjb29raWUnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvb2tpZSkge1xuICAgICAgICAgIHZhciBlcnJvciwgZXJyb3IxO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuc2V0Q29va2llKGNvb2tpZSk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IxKSB7XG4gICAgICAgICAgICBlcnJvciA9IGVycm9yMTtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ2RhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgICAgICAgbGlzdC5hcHBlbmQoY2h1bmspO1xuICAgICAgICAgIGlmIChfdGhpcy53YWl0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZGVjb2RlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdlbmQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIF90aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIgPSB0cnVlO1xuICAgICAgICAgIGlmIChfdGhpcy53YWl0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZGVjb2RlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge307XG5cbiAgICBEZWNvZGVyLnByb3RvdHlwZS5zZXRDb29raWUgPSBmdW5jdGlvbihjb29raWUpIHt9O1xuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7fTtcblxuICAgIERlY29kZXIucHJvdG90eXBlLmRlY29kZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVycm9yLCBlcnJvcjEsIG9mZnNldCwgcGFja2V0O1xuICAgICAgdGhpcy53YWl0aW5nID0gIXRoaXMucmVjZWl2ZWRGaW5hbEJ1ZmZlcjtcbiAgICAgIG9mZnNldCA9IHRoaXMuYml0c3RyZWFtLm9mZnNldCgpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcGFja2V0ID0gdGhpcy5yZWFkQ2h1bmsoKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yMSkge1xuICAgICAgICBlcnJvciA9IGVycm9yMTtcbiAgICAgICAgaWYgKCEoZXJyb3IgaW5zdGFuY2VvZiBVbmRlcmZsb3dFcnJvcikpIHtcbiAgICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyb3IpO1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHBhY2tldCkge1xuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBwYWNrZXQpO1xuICAgICAgICBpZiAodGhpcy5yZWNlaXZlZEZpbmFsQnVmZmVyKSB7XG4gICAgICAgICAgdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMucmVjZWl2ZWRGaW5hbEJ1ZmZlcikge1xuICAgICAgICB0aGlzLmJpdHN0cmVhbS5zZWVrKG9mZnNldCk7XG4gICAgICAgIHRoaXMud2FpdGluZyA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICBEZWNvZGVyLnByb3RvdHlwZS5zZWVrID0gZnVuY3Rpb24odGltZXN0YW1wKSB7XG4gICAgICB2YXIgc2Vla1BvaW50O1xuICAgICAgc2Vla1BvaW50ID0gdGhpcy5kZW11eGVyLnNlZWsodGltZXN0YW1wKTtcbiAgICAgIHRoaXMuc3RyZWFtLnNlZWsoc2Vla1BvaW50Lm9mZnNldCk7XG4gICAgICByZXR1cm4gc2Vla1BvaW50LnRpbWVzdGFtcDtcbiAgICB9O1xuXG4gICAgY29kZWNzID0ge307XG5cbiAgICBEZWNvZGVyLnJlZ2lzdGVyID0gZnVuY3Rpb24oaWQsIGRlY29kZXIpIHtcbiAgICAgIHJldHVybiBjb2RlY3NbaWRdID0gZGVjb2RlcjtcbiAgICB9O1xuXG4gICAgRGVjb2Rlci5maW5kID0gZnVuY3Rpb24oaWQpIHtcbiAgICAgIHJldHVybiBjb2RlY3NbaWRdIHx8IG51bGw7XG4gICAgfTtcblxuICAgIHJldHVybiBEZWNvZGVyO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBEZWNvZGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIERlY29kZXIsIExQQ01EZWNvZGVyLFxuICAgIGJpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRGVjb2RlciA9IHJlcXVpcmUoJy4uL2RlY29kZXInKTtcblxuICBMUENNRGVjb2RlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKExQQ01EZWNvZGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIExQQ01EZWNvZGVyKCkge1xuICAgICAgdGhpcy5yZWFkQ2h1bmsgPSBiaW5kKHRoaXMucmVhZENodW5rLCB0aGlzKTtcbiAgICAgIHJldHVybiBMUENNRGVjb2Rlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZWNvZGVyLnJlZ2lzdGVyKCdscGNtJywgTFBDTURlY29kZXIpO1xuXG4gICAgTFBDTURlY29kZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGNodW5rU2l6ZSwgaSwgaiwgaywgbCwgbGl0dGxlRW5kaWFuLCBtLCBuLCBvLCBvdXRwdXQsIHJlZiwgcmVmMSwgcmVmMiwgcmVmMywgcmVmNCwgcmVmNSwgc2FtcGxlcywgc3RyZWFtO1xuICAgICAgc3RyZWFtID0gdGhpcy5zdHJlYW07XG4gICAgICBsaXR0bGVFbmRpYW4gPSB0aGlzLmZvcm1hdC5saXR0bGVFbmRpYW47XG4gICAgICBjaHVua1NpemUgPSBNYXRoLm1pbig0MDk2LCBzdHJlYW0ucmVtYWluaW5nQnl0ZXMoKSk7XG4gICAgICBzYW1wbGVzID0gY2h1bmtTaXplIC8gKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkgfCAwO1xuICAgICAgaWYgKGNodW5rU2l6ZSA8IHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmZvcm1hdC5mbG9hdGluZ1BvaW50KSB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwpIHtcbiAgICAgICAgICBjYXNlIDMyOlxuICAgICAgICAgICAgb3V0cHV0ID0gbmV3IEZsb2F0MzJBcnJheShzYW1wbGVzKTtcbiAgICAgICAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBzYW1wbGVzOyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkRmxvYXQzMihsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSA2NDpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBGbG9hdDY0QXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBrID0gMCwgcmVmMSA9IHNhbXBsZXM7IGsgPCByZWYxOyBpID0gayArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkRmxvYXQ2NChsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgYml0IGRlcHRoLicpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsKSB7XG4gICAgICAgICAgY2FzZSA4OlxuICAgICAgICAgICAgb3V0cHV0ID0gbmV3IEludDhBcnJheShzYW1wbGVzKTtcbiAgICAgICAgICAgIGZvciAoaSA9IGwgPSAwLCByZWYyID0gc2FtcGxlczsgbCA8IHJlZjI7IGkgPSBsICs9IDEpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W2ldID0gc3RyZWFtLnJlYWRJbnQ4KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIDE2OlxuICAgICAgICAgICAgb3V0cHV0ID0gbmV3IEludDE2QXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBtID0gMCwgcmVmMyA9IHNhbXBsZXM7IG0gPCByZWYzOyBpID0gbSArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkSW50MTYobGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgMjQ6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgSW50MzJBcnJheShzYW1wbGVzKTtcbiAgICAgICAgICAgIGZvciAoaSA9IG4gPSAwLCByZWY0ID0gc2FtcGxlczsgbiA8IHJlZjQ7IGkgPSBuICs9IDEpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W2ldID0gc3RyZWFtLnJlYWRJbnQyNChsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAzMjpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBJbnQzMkFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gbyA9IDAsIHJlZjUgPSBzYW1wbGVzOyBvIDwgcmVmNTsgaSA9IG8gKz0gMSkge1xuICAgICAgICAgICAgICBvdXRwdXRbaV0gPSBzdHJlYW0ucmVhZEludDMyKGxpdHRsZUVuZGlhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBiaXQgZGVwdGguJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfTtcblxuICAgIHJldHVybiBMUENNRGVjb2RlcjtcblxuICB9KShEZWNvZGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZWNvZGVyLCBYTEFXRGVjb2RlcixcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIERlY29kZXIgPSByZXF1aXJlKCcuLi9kZWNvZGVyJyk7XG5cbiAgWExBV0RlY29kZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIHZhciBCSUFTLCBRVUFOVF9NQVNLLCBTRUdfTUFTSywgU0VHX1NISUZULCBTSUdOX0JJVDtcblxuICAgIGV4dGVuZChYTEFXRGVjb2Rlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBYTEFXRGVjb2RlcigpIHtcbiAgICAgIHRoaXMucmVhZENodW5rID0gYmluZCh0aGlzLnJlYWRDaHVuaywgdGhpcyk7XG4gICAgICByZXR1cm4gWExBV0RlY29kZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5yZWdpc3RlcigndWxhdycsIFhMQVdEZWNvZGVyKTtcblxuICAgIERlY29kZXIucmVnaXN0ZXIoJ2FsYXcnLCBYTEFXRGVjb2Rlcik7XG5cbiAgICBTSUdOX0JJVCA9IDB4ODA7XG5cbiAgICBRVUFOVF9NQVNLID0gMHhmO1xuXG4gICAgU0VHX1NISUZUID0gNDtcblxuICAgIFNFR19NQVNLID0gMHg3MDtcblxuICAgIEJJQVMgPSAweDg0O1xuXG4gICAgWExBV0RlY29kZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBpLCBqLCBrLCBzZWcsIHQsIHRhYmxlLCB2YWw7XG4gICAgICB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9IDE2O1xuICAgICAgdGhpcy50YWJsZSA9IHRhYmxlID0gbmV3IEludDE2QXJyYXkoMjU2KTtcbiAgICAgIGlmICh0aGlzLmZvcm1hdC5mb3JtYXRJRCA9PT0gJ3VsYXcnKSB7XG4gICAgICAgIGZvciAoaSA9IGogPSAwOyBqIDwgMjU2OyBpID0gKytqKSB7XG4gICAgICAgICAgdmFsID0gfmk7XG4gICAgICAgICAgdCA9ICgodmFsICYgUVVBTlRfTUFTSykgPDwgMykgKyBCSUFTO1xuICAgICAgICAgIHQgPDw9ICh2YWwgJiBTRUdfTUFTSykgPj4+IFNFR19TSElGVDtcbiAgICAgICAgICB0YWJsZVtpXSA9IHZhbCAmIFNJR05fQklUID8gQklBUyAtIHQgOiB0IC0gQklBUztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChpID0gayA9IDA7IGsgPCAyNTY7IGkgPSArK2spIHtcbiAgICAgICAgICB2YWwgPSBpIF4gMHg1NTtcbiAgICAgICAgICB0ID0gdmFsICYgUVVBTlRfTUFTSztcbiAgICAgICAgICBzZWcgPSAodmFsICYgU0VHX01BU0spID4+PiBTRUdfU0hJRlQ7XG4gICAgICAgICAgaWYgKHNlZykge1xuICAgICAgICAgICAgdCA9ICh0ICsgdCArIDEgKyAzMikgPDwgKHNlZyArIDIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0ID0gKHQgKyB0ICsgMSkgPDwgMztcbiAgICAgICAgICB9XG4gICAgICAgICAgdGFibGVbaV0gPSB2YWwgJiBTSUdOX0JJVCA/IHQgOiAtdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBYTEFXRGVjb2Rlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaSwgaiwgb3V0cHV0LCByZWYsIHNhbXBsZXMsIHN0cmVhbSwgdGFibGU7XG4gICAgICBzdHJlYW0gPSB0aGlzLnN0cmVhbSwgdGFibGUgPSB0aGlzLnRhYmxlO1xuICAgICAgc2FtcGxlcyA9IE1hdGgubWluKDQwOTYsIHRoaXMuc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCkpO1xuICAgICAgaWYgKHNhbXBsZXMgPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgb3V0cHV0ID0gbmV3IEludDE2QXJyYXkoc2FtcGxlcyk7XG4gICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gc2FtcGxlczsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICBvdXRwdXRbaV0gPSB0YWJsZVtzdHJlYW0ucmVhZFVJbnQ4KCldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhMQVdEZWNvZGVyO1xuXG4gIH0pKERlY29kZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJ1ZmZlckxpc3QsIERlbXV4ZXIsIEV2ZW50RW1pdHRlciwgU3RyZWFtLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2NvcmUvYnVmZmVybGlzdCcpO1xuXG4gIFN0cmVhbSA9IHJlcXVpcmUoJy4vY29yZS9zdHJlYW0nKTtcblxuICBEZW11eGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgZm9ybWF0cztcblxuICAgIGV4dGVuZChEZW11eGVyLCBzdXBlckNsYXNzKTtcblxuICAgIERlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gRGVtdXhlcihzb3VyY2UsIGNodW5rKSB7XG4gICAgICB2YXIgbGlzdCwgcmVjZWl2ZWQ7XG4gICAgICBsaXN0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICBsaXN0LmFwcGVuZChjaHVuayk7XG4gICAgICB0aGlzLnN0cmVhbSA9IG5ldyBTdHJlYW0obGlzdCk7XG4gICAgICByZWNlaXZlZCA9IGZhbHNlO1xuICAgICAgc291cmNlLm9uKCdkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihjaHVuaykge1xuICAgICAgICAgIHZhciBlLCBlcnJvcjtcbiAgICAgICAgICByZWNlaXZlZCA9IHRydWU7XG4gICAgICAgICAgbGlzdC5hcHBlbmQoY2h1bmspO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMucmVhZENodW5rKGNodW5rKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgZSA9IGVycm9yO1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgc291cmNlLm9uKCdlcnJvcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHNvdXJjZS5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAoIXJlY2VpdmVkKSB7XG4gICAgICAgICAgICBfdGhpcy5yZWFkQ2h1bmsoY2h1bmspO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLnNlZWtQb2ludHMgPSBbXTtcbiAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHt9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oY2h1bmspIHt9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUuYWRkU2Vla1BvaW50ID0gZnVuY3Rpb24ob2Zmc2V0LCB0aW1lc3RhbXApIHtcbiAgICAgIHZhciBpbmRleDtcbiAgICAgIGluZGV4ID0gdGhpcy5zZWFyY2hUaW1lc3RhbXAodGltZXN0YW1wKTtcbiAgICAgIHJldHVybiB0aGlzLnNlZWtQb2ludHMuc3BsaWNlKGluZGV4LCAwLCB7XG4gICAgICAgIG9mZnNldDogb2Zmc2V0LFxuICAgICAgICB0aW1lc3RhbXA6IHRpbWVzdGFtcFxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIERlbXV4ZXIucHJvdG90eXBlLnNlYXJjaFRpbWVzdGFtcCA9IGZ1bmN0aW9uKHRpbWVzdGFtcCwgYmFja3dhcmQpIHtcbiAgICAgIHZhciBoaWdoLCBsb3csIG1pZCwgdGltZTtcbiAgICAgIGxvdyA9IDA7XG4gICAgICBoaWdoID0gdGhpcy5zZWVrUG9pbnRzLmxlbmd0aDtcbiAgICAgIGlmIChoaWdoID4gMCAmJiB0aGlzLnNlZWtQb2ludHNbaGlnaCAtIDFdLnRpbWVzdGFtcCA8IHRpbWVzdGFtcCkge1xuICAgICAgICByZXR1cm4gaGlnaDtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICAgIG1pZCA9IChsb3cgKyBoaWdoKSA+PiAxO1xuICAgICAgICB0aW1lID0gdGhpcy5zZWVrUG9pbnRzW21pZF0udGltZXN0YW1wO1xuICAgICAgICBpZiAodGltZSA8IHRpbWVzdGFtcCkge1xuICAgICAgICAgIGxvdyA9IG1pZCArIDE7XG4gICAgICAgIH0gZWxzZSBpZiAodGltZSA+PSB0aW1lc3RhbXApIHtcbiAgICAgICAgICBoaWdoID0gbWlkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaGlnaCA+IHRoaXMuc2Vla1BvaW50cy5sZW5ndGgpIHtcbiAgICAgICAgaGlnaCA9IHRoaXMuc2Vla1BvaW50cy5sZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGlnaDtcbiAgICB9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHRpbWVzdGFtcCkge1xuICAgICAgdmFyIGluZGV4LCBzZWVrUG9pbnQ7XG4gICAgICBpZiAodGhpcy5mb3JtYXQgJiYgdGhpcy5mb3JtYXQuZnJhbWVzUGVyUGFja2V0ID4gMCAmJiB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA+IDApIHtcbiAgICAgICAgc2Vla1BvaW50ID0ge1xuICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wLFxuICAgICAgICAgIG9mZnNldDogdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgKiB0aW1lc3RhbXAgLyB0aGlzLmZvcm1hdC5mcmFtZXNQZXJQYWNrZXRcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHNlZWtQb2ludDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZGV4ID0gdGhpcy5zZWFyY2hUaW1lc3RhbXAodGltZXN0YW1wKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vla1BvaW50c1tpbmRleF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZvcm1hdHMgPSBbXTtcblxuICAgIERlbXV4ZXIucmVnaXN0ZXIgPSBmdW5jdGlvbihkZW11eGVyKSB7XG4gICAgICByZXR1cm4gZm9ybWF0cy5wdXNoKGRlbXV4ZXIpO1xuICAgIH07XG5cbiAgICBEZW11eGVyLmZpbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciBlLCBlcnJvciwgZm9ybWF0LCBpLCBsZW4sIG9mZnNldCwgc3RyZWFtO1xuICAgICAgc3RyZWFtID0gU3RyZWFtLmZyb21CdWZmZXIoYnVmZmVyKTtcbiAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGZvcm1hdHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgZm9ybWF0ID0gZm9ybWF0c1tpXTtcbiAgICAgICAgb2Zmc2V0ID0gc3RyZWFtLm9mZnNldDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAoZm9ybWF0LnByb2JlKHN0cmVhbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGUgPSBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBzdHJlYW0uc2VlayhvZmZzZXQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIHJldHVybiBEZW11eGVyO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBEZW11eGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFJRkZEZW11eGVyLCBEZW11eGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRGVtdXhlciA9IHJlcXVpcmUoJy4uL2RlbXV4ZXInKTtcblxuICBBSUZGRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKEFJRkZEZW11eGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIEFJRkZEZW11eGVyKCkge1xuICAgICAgcmV0dXJuIEFJRkZEZW11eGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucmVnaXN0ZXIoQUlGRkRlbXV4ZXIpO1xuXG4gICAgQUlGRkRlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoMCwgNCkgPT09ICdGT1JNJyAmJiAoKHJlZiA9IGJ1ZmZlci5wZWVrU3RyaW5nKDgsIDQpKSA9PT0gJ0FJRkYnIHx8IHJlZiA9PT0gJ0FJRkMnKTtcbiAgICB9O1xuXG4gICAgQUlGRkRlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ1ZmZlciwgZm9ybWF0LCBvZmZzZXQsIHJlZjtcbiAgICAgIGlmICghdGhpcy5yZWFkU3RhcnQgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEyKSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ0ZPUk0nKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBSUZGLicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlsZVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZmlsZVR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICB0aGlzLnJlYWRTdGFydCA9IHRydWU7XG4gICAgICAgIGlmICgocmVmID0gdGhpcy5maWxlVHlwZSkgIT09ICdBSUZGJyAmJiByZWYgIT09ICdBSUZDJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ0ludmFsaWQgQUlGRi4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgd2hpbGUgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICBpZiAoIXRoaXMucmVhZEhlYWRlcnMgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDgpKSB7XG4gICAgICAgICAgdGhpcy50eXBlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgICAgICB0aGlzLmxlbiA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ0NPTU0nOlxuICAgICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5sZW4pKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZm9ybWF0ID0ge1xuICAgICAgICAgICAgICBmb3JtYXRJRDogJ2xwY20nLFxuICAgICAgICAgICAgICBjaGFubmVsc1BlckZyYW1lOiB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCksXG4gICAgICAgICAgICAgIHNhbXBsZUNvdW50OiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgICAgIGJpdHNQZXJDaGFubmVsOiB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCksXG4gICAgICAgICAgICAgIHNhbXBsZVJhdGU6IHRoaXMuc3RyZWFtLnJlYWRGbG9hdDgwKCksXG4gICAgICAgICAgICAgIGZyYW1lc1BlclBhY2tldDogMSxcbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuOiBmYWxzZSxcbiAgICAgICAgICAgICAgZmxvYXRpbmdQb2ludDogZmFsc2VcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA9ICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDgpICogdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZTtcbiAgICAgICAgICAgIGlmICh0aGlzLmZpbGVUeXBlID09PSAnQUlGQycpIHtcbiAgICAgICAgICAgICAgZm9ybWF0ID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgICAgICAgICAgdGhpcy5mb3JtYXQubGl0dGxlRW5kaWFuID0gZm9ybWF0ID09PSAnc293dCcgJiYgdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgPiA4O1xuICAgICAgICAgICAgICB0aGlzLmZvcm1hdC5mbG9hdGluZ1BvaW50ID0gZm9ybWF0ID09PSAnZmwzMicgfHwgZm9ybWF0ID09PSAnZmw2NCc7XG4gICAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICd0d29zJyB8fCBmb3JtYXQgPT09ICdzb3d0JyB8fCBmb3JtYXQgPT09ICdmbDMyJyB8fCBmb3JtYXQgPT09ICdmbDY0JyB8fCBmb3JtYXQgPT09ICdOT05FJykge1xuICAgICAgICAgICAgICAgIGZvcm1hdCA9ICdscGNtJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLmZvcm1hdC5mb3JtYXRJRCA9IGZvcm1hdDtcbiAgICAgICAgICAgICAgdGhpcy5sZW4gLT0gNDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4gLSAxOCk7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2Zvcm1hdCcsIHRoaXMuZm9ybWF0KTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCB0aGlzLmZvcm1hdC5zYW1wbGVDb3VudCAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdTU05EJzpcbiAgICAgICAgICAgIGlmICghKHRoaXMucmVhZFNTTkRIZWFkZXIgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDQpKSkge1xuICAgICAgICAgICAgICBvZmZzZXQgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2Uob2Zmc2V0KTtcbiAgICAgICAgICAgICAgdGhpcy5yZWFkU1NOREhlYWRlciA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidWZmZXIgPSB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMubGVuKTtcbiAgICAgICAgICAgIHRoaXMubGVuIC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gdGhpcy5sZW4gPiAwO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gJ1NTTkQnKSB7XG4gICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBBSUZGRGVtdXhlcjtcblxuICB9KShEZW11eGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBVURlbXV4ZXIsIERlbXV4ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi4vZGVtdXhlcicpO1xuXG4gIEFVRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGJwcywgZm9ybWF0cztcblxuICAgIGV4dGVuZChBVURlbXV4ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gQVVEZW11eGVyKCkge1xuICAgICAgcmV0dXJuIEFVRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKEFVRGVtdXhlcik7XG5cbiAgICBBVURlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBidWZmZXIucGVla1N0cmluZygwLCA0KSA9PT0gJy5zbmQnO1xuICAgIH07XG5cbiAgICBicHMgPSBbOCwgOCwgMTYsIDI0LCAzMiwgMzIsIDY0XTtcblxuICAgIGJwc1syNl0gPSA4O1xuXG4gICAgZm9ybWF0cyA9IHtcbiAgICAgIDE6ICd1bGF3JyxcbiAgICAgIDI3OiAnYWxhdydcbiAgICB9O1xuXG4gICAgQVVEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBieXRlcywgZGF0YVNpemUsIGVuY29kaW5nLCBzaXplO1xuICAgICAgaWYgKCF0aGlzLnJlYWRIZWFkZXIgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDI0KSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJy5zbmQnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBVSBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICAgIHNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIGRhdGFTaXplID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICBlbmNvZGluZyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgZm9ybWF0SUQ6IGZvcm1hdHNbZW5jb2RpbmddIHx8ICdscGNtJyxcbiAgICAgICAgICBsaXR0bGVFbmRpYW46IGZhbHNlLFxuICAgICAgICAgIGZsb2F0aW5nUG9pbnQ6IGVuY29kaW5nID09PSA2IHx8IGVuY29kaW5nID09PSA3LFxuICAgICAgICAgIGJpdHNQZXJDaGFubmVsOiBicHNbZW5jb2RpbmcgLSAxXSxcbiAgICAgICAgICBzYW1wbGVSYXRlOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgY2hhbm5lbHNQZXJGcmFtZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpLFxuICAgICAgICAgIGZyYW1lc1BlclBhY2tldDogMVxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ1Vuc3VwcG9ydGVkIGVuY29kaW5nIGluIEFVIGZpbGUuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgPSAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4KSAqIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWU7XG4gICAgICAgIGlmIChkYXRhU2l6ZSAhPT0gMHhmZmZmZmZmZikge1xuICAgICAgICAgIGJ5dGVzID0gdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4O1xuICAgICAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCBkYXRhU2l6ZSAvIGJ5dGVzIC8gdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZSAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICAgIHRoaXMucmVhZEhlYWRlciA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5yZWFkSGVhZGVyKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5hdmFpbGFibGUoMSkpIHtcbiAgICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMuc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCkpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQVVEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIENBRkRlbXV4ZXIsIERlbXV4ZXIsIE00QURlbXV4ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi4vZGVtdXhlcicpO1xuXG4gIE00QURlbXV4ZXIgPSByZXF1aXJlKCcuL200YScpO1xuXG4gIENBRkRlbXV4ZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChDQUZEZW11eGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIENBRkRlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gQ0FGRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKENBRkRlbXV4ZXIpO1xuXG4gICAgQ0FGRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgcmV0dXJuIGJ1ZmZlci5wZWVrU3RyaW5nKDAsIDQpID09PSAnY2FmZic7XG4gICAgfTtcblxuICAgIENBRkRlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ1ZmZlciwgYnl0ZU9mZnNldCwgY29va2llLCBlbnRyaWVzLCBmbGFncywgaSwgaiwgaywga2V5LCBtZXRhZGF0YSwgb2Zmc2V0LCByZWYsIHJlZjEsIHNhbXBsZU9mZnNldCwgdmFsdWU7XG4gICAgICBpZiAoIXRoaXMuZm9ybWF0ICYmIHRoaXMuc3RyZWFtLmF2YWlsYWJsZSg2NCkpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCkgIT09ICdjYWZmJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgXCJJbnZhbGlkIENBRiwgZG9lcyBub3QgYmVnaW4gd2l0aCAnY2FmZidcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCkgIT09ICdkZXNjJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgXCJJbnZhbGlkIENBRiwgJ2NhZmYnIGlzIG5vdCBmb2xsb3dlZCBieSAnZGVzYydcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEodGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpID09PSAwICYmIHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSA9PT0gMzIpKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIkludmFsaWQgJ2Rlc2MnIHNpemUsIHNob3VsZCBiZSAzMlwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZvcm1hdCA9IHt9O1xuICAgICAgICB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlID0gdGhpcy5zdHJlYW0ucmVhZEZsb2F0NjQoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQuZm9ybWF0SUQgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICBmbGFncyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgaWYgKHRoaXMuZm9ybWF0LmZvcm1hdElEID09PSAnbHBjbScpIHtcbiAgICAgICAgICB0aGlzLmZvcm1hdC5mbG9hdGluZ1BvaW50ID0gQm9vbGVhbihmbGFncyAmIDEpO1xuICAgICAgICAgIHRoaXMuZm9ybWF0LmxpdHRsZUVuZGlhbiA9IEJvb2xlYW4oZmxhZ3MgJiAyKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQuZnJhbWVzUGVyUGFja2V0ID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIGlmICghdGhpcy5oZWFkZXJDYWNoZSkge1xuICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUgPSB7XG4gICAgICAgICAgICB0eXBlOiB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpLFxuICAgICAgICAgICAgb3ZlcnNpemU6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSAhPT0gMCxcbiAgICAgICAgICAgIHNpemU6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKVxuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKHRoaXMuaGVhZGVyQ2FjaGUub3ZlcnNpemUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgXCJIb2x5IFNoaXQsIGFuIG92ZXJzaXplZCBmaWxlLCBub3Qgc3VwcG9ydGVkIGluIEpTXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHRoaXMuaGVhZGVyQ2FjaGUudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ2t1a2knOlxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmhlYWRlckNhY2hlLnNpemUpKSB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmZvcm1hdC5mb3JtYXRJRCA9PT0gJ2FhYyAnKSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gdGhpcy5zdHJlYW0ub2Zmc2V0ICsgdGhpcy5oZWFkZXJDYWNoZS5zaXplO1xuICAgICAgICAgICAgICAgIGlmIChjb29raWUgPSBNNEFEZW11eGVyLnJlYWRFc2RzKHRoaXMuc3RyZWFtKSkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdjb29raWUnLCBjb29raWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZWVrKG9mZnNldCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYnVmZmVyID0gdGhpcy5zdHJlYW0ucmVhZEJ1ZmZlcih0aGlzLmhlYWRlckNhY2hlLnNpemUpO1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgnY29va2llJywgYnVmZmVyKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3Bha3QnOlxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmhlYWRlckNhY2hlLnNpemUpKSB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgIT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdTaXplcyBncmVhdGVyIHRoYW4gMzIgYml0cyBhcmUgbm90IHN1cHBvcnRlZC4nKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLm51bVBhY2tldHMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgIT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdTaXplcyBncmVhdGVyIHRoYW4gMzIgYml0cyBhcmUgbm90IHN1cHBvcnRlZC4nKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLm51bUZyYW1lcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgdGhpcy5wcmltaW5nRnJhbWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICAgICAgICB0aGlzLnJlbWFpbmRlckZyYW1lcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMubnVtRnJhbWVzIC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgICAgICAgdGhpcy5zZW50RHVyYXRpb24gPSB0cnVlO1xuICAgICAgICAgICAgICBieXRlT2Zmc2V0ID0gMDtcbiAgICAgICAgICAgICAgc2FtcGxlT2Zmc2V0ID0gMDtcbiAgICAgICAgICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IHRoaXMubnVtUGFja2V0czsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkU2Vla1BvaW50KGJ5dGVPZmZzZXQsIHNhbXBsZU9mZnNldCk7XG4gICAgICAgICAgICAgICAgYnl0ZU9mZnNldCArPSB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCB8fCBNNEFEZW11eGVyLnJlYWREZXNjckxlbih0aGlzLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgc2FtcGxlT2Zmc2V0ICs9IHRoaXMuZm9ybWF0LmZyYW1lc1BlclBhY2tldCB8fCBNNEFEZW11eGVyLnJlYWREZXNjckxlbih0aGlzLnN0cmVhbSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdpbmZvJzpcbiAgICAgICAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICBtZXRhZGF0YSA9IHt9O1xuICAgICAgICAgICAgZm9yIChpID0gayA9IDAsIHJlZjEgPSBlbnRyaWVzOyAwIDw9IHJlZjEgPyBrIDwgcmVmMSA6IGsgPiByZWYxOyBpID0gMCA8PSByZWYxID8gKytrIDogLS1rKSB7XG4gICAgICAgICAgICAgIGtleSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcobnVsbCk7XG4gICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyhudWxsKTtcbiAgICAgICAgICAgICAgbWV0YWRhdGFba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdtZXRhZGF0YScsIG1ldGFkYXRhKTtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUgPSBudWxsO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZGF0YSc6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2VudEZpcnN0RGF0YUNodW5rKSB7XG4gICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSAtPSA0O1xuICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgIT09IDAgJiYgIXRoaXMuc2VudER1cmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5udW1GcmFtZXMgPSB0aGlzLmhlYWRlckNhY2hlLnNpemUgLyB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldDtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2R1cmF0aW9uJywgdGhpcy5udW1GcmFtZXMgLyB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlICogMTAwMCB8IDApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMuc2VudEZpcnN0RGF0YUNodW5rID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJ1ZmZlciA9IHRoaXMuc3RyZWFtLnJlYWRTaW5nbGVCdWZmZXIodGhpcy5oZWFkZXJDYWNoZS5zaXplKTtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSAtPSBidWZmZXIubGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmhlYWRlckNhY2hlLnNpemUgPD0gMCkge1xuICAgICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSkpIHtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmhlYWRlckNhY2hlLnNpemUpO1xuICAgICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQ0FGRGVtdXhlcjtcblxuICB9KShEZW11eGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZW11eGVyLCBNNEFEZW11eGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgaW5kZXhPZiA9IFtdLmluZGV4T2YgfHwgZnVuY3Rpb24oaXRlbSkgeyBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7IGlmIChpIGluIHRoaXMgJiYgdGhpc1tpXSA9PT0gaXRlbSkgcmV0dXJuIGk7IH0gcmV0dXJuIC0xOyB9O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgTTRBRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIEJJVFNfUEVSX0NIQU5ORUwsIFRZUEVTLCBhZnRlciwgYXRvbSwgYXRvbXMsIGJvb2wsIGNvbnRhaW5lcnMsIGRpc2tUcmFjaywgZ2VucmVzLCBtZXRhLCBzdHJpbmc7XG5cbiAgICBleHRlbmQoTTRBRGVtdXhlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBNNEFEZW11eGVyKCkge1xuICAgICAgcmV0dXJuIE00QURlbXV4ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVtdXhlci5yZWdpc3RlcihNNEFEZW11eGVyKTtcblxuICAgIFRZUEVTID0gWydNNEEgJywgJ000UCAnLCAnTTRCICcsICdNNFYgJywgJ2lzb20nLCAnbXA0MicsICdxdCAgJ107XG5cbiAgICBNNEFEZW11eGVyLnByb2JlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgcmV0dXJuIGJ1ZmZlci5wZWVrU3RyaW5nKDQsIDQpID09PSAnZnR5cCcgJiYgKHJlZiA9IGJ1ZmZlci5wZWVrU3RyaW5nKDgsIDQpLCBpbmRleE9mLmNhbGwoVFlQRVMsIHJlZikgPj0gMCk7XG4gICAgfTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuYXRvbXMgPSBbXTtcbiAgICAgIHRoaXMub2Zmc2V0cyA9IFtdO1xuICAgICAgdGhpcy50cmFjayA9IG51bGw7XG4gICAgICByZXR1cm4gdGhpcy50cmFja3MgPSBbXTtcbiAgICB9O1xuXG4gICAgYXRvbXMgPSB7fTtcblxuICAgIGNvbnRhaW5lcnMgPSB7fTtcblxuICAgIGF0b20gPSBmdW5jdGlvbihuYW1lLCBmbikge1xuICAgICAgdmFyIGMsIGNvbnRhaW5lciwgaywgbGVuMSwgcmVmO1xuICAgICAgYyA9IFtdO1xuICAgICAgcmVmID0gbmFtZS5zcGxpdCgnLicpLnNsaWNlKDAsIC0xKTtcbiAgICAgIGZvciAoayA9IDAsIGxlbjEgPSByZWYubGVuZ3RoOyBrIDwgbGVuMTsgaysrKSB7XG4gICAgICAgIGNvbnRhaW5lciA9IHJlZltrXTtcbiAgICAgICAgYy5wdXNoKGNvbnRhaW5lcik7XG4gICAgICAgIGNvbnRhaW5lcnNbYy5qb2luKCcuJyldID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChhdG9tc1tuYW1lXSA9PSBudWxsKSB7XG4gICAgICAgIGF0b21zW25hbWVdID0ge307XG4gICAgICB9XG4gICAgICByZXR1cm4gYXRvbXNbbmFtZV0uZm4gPSBmbjtcbiAgICB9O1xuXG4gICAgYWZ0ZXIgPSBmdW5jdGlvbihuYW1lLCBmbikge1xuICAgICAgaWYgKGF0b21zW25hbWVdID09IG51bGwpIHtcbiAgICAgICAgYXRvbXNbbmFtZV0gPSB7fTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdG9tc1tuYW1lXS5hZnRlciA9IGZuO1xuICAgIH07XG5cbiAgICBNNEFEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBoYW5kbGVyLCBwYXRoLCB0eXBlO1xuICAgICAgdGhpc1tcImJyZWFrXCJdID0gZmFsc2U7XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpICYmICF0aGlzW1wiYnJlYWtcIl0pIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlYWRIZWFkZXJzKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5sZW4gPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgLSA4O1xuICAgICAgICAgIHRoaXMudHlwZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCk7XG4gICAgICAgICAgaWYgKHRoaXMubGVuID09PSAwKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5hdG9tcy5wdXNoKHRoaXMudHlwZSk7XG4gICAgICAgICAgdGhpcy5vZmZzZXRzLnB1c2godGhpcy5zdHJlYW0ub2Zmc2V0ICsgdGhpcy5sZW4pO1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHBhdGggPSB0aGlzLmF0b21zLmpvaW4oJy4nKTtcbiAgICAgICAgaGFuZGxlciA9IGF0b21zW3BhdGhdO1xuICAgICAgICBpZiAoaGFuZGxlciAhPSBudWxsID8gaGFuZGxlci5mbiA6IHZvaWQgMCkge1xuICAgICAgICAgIGlmICghKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikgfHwgcGF0aCA9PT0gJ21kYXQnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBoYW5kbGVyLmZuLmNhbGwodGhpcyk7XG4gICAgICAgICAgaWYgKHBhdGggaW4gY29udGFpbmVycykge1xuICAgICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChwYXRoIGluIGNvbnRhaW5lcnMpIHtcbiAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5sZW4pKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4pO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5vZmZzZXQgPj0gdGhpcy5vZmZzZXRzW3RoaXMub2Zmc2V0cy5sZW5ndGggLSAxXSkge1xuICAgICAgICAgIGhhbmRsZXIgPSBhdG9tc1t0aGlzLmF0b21zLmpvaW4oJy4nKV07XG4gICAgICAgICAgaWYgKGhhbmRsZXIgIT0gbnVsbCA/IGhhbmRsZXIuYWZ0ZXIgOiB2b2lkIDApIHtcbiAgICAgICAgICAgIGhhbmRsZXIuYWZ0ZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdHlwZSA9IHRoaXMuYXRvbXMucG9wKCk7XG4gICAgICAgICAgdGhpcy5vZmZzZXRzLnBvcCgpO1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBhdG9tKCdmdHlwJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgaWYgKHJlZiA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCksIGluZGV4T2YuY2FsbChUWVBFUywgcmVmKSA8IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnTm90IGEgdmFsaWQgTTRBIGZpbGUuJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDQpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrJywgZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnRyYWNrID0ge307XG4gICAgICByZXR1cm4gdGhpcy50cmFja3MucHVzaCh0aGlzLnRyYWNrKTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay50a2hkJywgZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg4KTtcbiAgICAgIHRoaXMudHJhY2suaWQgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDE2KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLmhkbHInLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGhpcy50cmFjay50eXBlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoMTIpO1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4gLSAyNCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5tZGhkJywgZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg4KTtcbiAgICAgIHRoaXMudHJhY2sudGltZVNjYWxlID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgdGhpcy50cmFjay5kdXJhdGlvbiA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgIH0pO1xuXG4gICAgQklUU19QRVJfQ0hBTk5FTCA9IHtcbiAgICAgIHVsYXc6IDgsXG4gICAgICBhbGF3OiA4LFxuICAgICAgaW4yNDogMjQsXG4gICAgICBpbjMyOiAzMixcbiAgICAgIGZsMzI6IDMyLFxuICAgICAgZmw2NDogNjRcbiAgICB9O1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c2QnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBmb3JtYXQsIG51bUVudHJpZXMsIHJlZiwgcmVmMSwgdmVyc2lvbjtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBudW1FbnRyaWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgaWYgKHRoaXMudHJhY2sudHlwZSAhPT0gJ3NvdW4nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gOCk7XG4gICAgICB9XG4gICAgICBpZiAobnVtRW50cmllcyAhPT0gMSkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiT25seSBleHBlY3Rpbmcgb25lIGVudHJ5IGluIHNhbXBsZSBkZXNjcmlwdGlvbiBhdG9tIVwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBmb3JtYXQgPSB0aGlzLnRyYWNrLmZvcm1hdCA9IHt9O1xuICAgICAgZm9ybWF0LmZvcm1hdElEID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNik7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgdmVyc2lvbiA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNik7XG4gICAgICBmb3JtYXQuY2hhbm5lbHNQZXJGcmFtZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICAgIGZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBmb3JtYXQuc2FtcGxlUmF0ZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICBpZiAodmVyc2lvbiA9PT0gMSkge1xuICAgICAgICBmb3JtYXQuZnJhbWVzUGVyUGFja2V0ID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICBmb3JtYXQuYnl0ZXNQZXJGcmFtZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIH0gZWxzZSBpZiAodmVyc2lvbiAhPT0gMCkge1xuICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgJ1Vua25vd24gdmVyc2lvbiBpbiBzdHNkIGF0b20nKTtcbiAgICAgIH1cbiAgICAgIGlmIChCSVRTX1BFUl9DSEFOTkVMW2Zvcm1hdC5mb3JtYXRJRF0gIT0gbnVsbCkge1xuICAgICAgICBmb3JtYXQuYml0c1BlckNoYW5uZWwgPSBCSVRTX1BFUl9DSEFOTkVMW2Zvcm1hdC5mb3JtYXRJRF07XG4gICAgICB9XG4gICAgICBmb3JtYXQuZmxvYXRpbmdQb2ludCA9IChyZWYgPSBmb3JtYXQuZm9ybWF0SUQpID09PSAnZmwzMicgfHwgcmVmID09PSAnZmw2NCc7XG4gICAgICBmb3JtYXQubGl0dGxlRW5kaWFuID0gZm9ybWF0LmZvcm1hdElEID09PSAnc293dCcgJiYgZm9ybWF0LmJpdHNQZXJDaGFubmVsID4gODtcbiAgICAgIGlmICgocmVmMSA9IGZvcm1hdC5mb3JtYXRJRCkgPT09ICd0d29zJyB8fCByZWYxID09PSAnc293dCcgfHwgcmVmMSA9PT0gJ2luMjQnIHx8IHJlZjEgPT09ICdpbjMyJyB8fCByZWYxID09PSAnZmwzMicgfHwgcmVmMSA9PT0gJ2ZsNjQnIHx8IHJlZjEgPT09ICdyYXcgJyB8fCByZWYxID09PSAnTk9ORScpIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdC5mb3JtYXRJRCA9ICdscGNtJztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNkLmFsYWMnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICByZXR1cm4gdGhpcy50cmFjay5jb29raWUgPSB0aGlzLnN0cmVhbS5yZWFkQnVmZmVyKHRoaXMubGVuIC0gNCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzZC5lc2RzJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgb2Zmc2V0O1xuICAgICAgb2Zmc2V0ID0gdGhpcy5zdHJlYW0ub2Zmc2V0ICsgdGhpcy5sZW47XG4gICAgICB0aGlzLnRyYWNrLmNvb2tpZSA9IE00QURlbXV4ZXIucmVhZEVzZHModGhpcy5zdHJlYW0pO1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLnNlZWsob2Zmc2V0KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNkLndhdmUuZW5kYScsIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudHJhY2suZm9ybWF0LmxpdHRsZUVuZGlhbiA9ICEhdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgIH0pO1xuXG4gICAgTTRBRGVtdXhlci5yZWFkRGVzY3JMZW4gPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgIHZhciBjLCBjb3VudCwgbGVuO1xuICAgICAgbGVuID0gMDtcbiAgICAgIGNvdW50ID0gNDtcbiAgICAgIHdoaWxlIChjb3VudC0tKSB7XG4gICAgICAgIGMgPSBzdHJlYW0ucmVhZFVJbnQ4KCk7XG4gICAgICAgIGxlbiA9IChsZW4gPDwgNykgfCAoYyAmIDB4N2YpO1xuICAgICAgICBpZiAoIShjICYgMHg4MCkpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGxlbjtcbiAgICB9O1xuXG4gICAgTTRBRGVtdXhlci5yZWFkRXNkcyA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgdmFyIGNvZGVjX2lkLCBmbGFncywgbGVuLCB0YWc7XG4gICAgICBzdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHRhZyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgIGxlbiA9IE00QURlbXV4ZXIucmVhZERlc2NyTGVuKHN0cmVhbSk7XG4gICAgICBpZiAodGFnID09PSAweDAzKSB7XG4gICAgICAgIHN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgICBmbGFncyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgICAgaWYgKGZsYWdzICYgMHg4MCkge1xuICAgICAgICAgIHN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmbGFncyAmIDB4NDApIHtcbiAgICAgICAgICBzdHJlYW0uYWR2YW5jZShzdHJlYW0ucmVhZFVJbnQ4KCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmbGFncyAmIDB4MjApIHtcbiAgICAgICAgICBzdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICB9XG4gICAgICB0YWcgPSBzdHJlYW0ucmVhZFVJbnQ4KCk7XG4gICAgICBsZW4gPSBNNEFEZW11eGVyLnJlYWREZXNjckxlbihzdHJlYW0pO1xuICAgICAgaWYgKHRhZyA9PT0gMHgwNCkge1xuICAgICAgICBjb2RlY19pZCA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMSk7XG4gICAgICAgIHN0cmVhbS5hZHZhbmNlKDMpO1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICAgIHRhZyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgICAgbGVuID0gTTRBRGVtdXhlci5yZWFkRGVzY3JMZW4oc3RyZWFtKTtcbiAgICAgICAgaWYgKHRhZyA9PT0gMHgwNSkge1xuICAgICAgICAgIHJldHVybiBzdHJlYW0ucmVhZEJ1ZmZlcihsZW4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0dHMnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBlbnRyaWVzLCBpLCBrLCByZWY7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgZW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHRoaXMudHJhY2suc3R0cyA9IFtdO1xuICAgICAgZm9yIChpID0gayA9IDAsIHJlZiA9IGVudHJpZXM7IGsgPCByZWY7IGkgPSBrICs9IDEpIHtcbiAgICAgICAgdGhpcy50cmFjay5zdHRzW2ldID0ge1xuICAgICAgICAgIGNvdW50OiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgZHVyYXRpb246IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzYycsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIGssIHJlZjtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBlbnRyaWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgdGhpcy50cmFjay5zdHNjID0gW107XG4gICAgICBmb3IgKGkgPSBrID0gMCwgcmVmID0gZW50cmllczsgayA8IHJlZjsgaSA9IGsgKz0gMSkge1xuICAgICAgICB0aGlzLnRyYWNrLnN0c2NbaV0gPSB7XG4gICAgICAgICAgZmlyc3Q6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICBjb3VudDogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpLFxuICAgICAgICAgIGlkOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKClcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnNldHVwU2Vla1BvaW50cygpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c3onLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBlbnRyaWVzLCBpLCBrLCByZWY7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGhpcy50cmFjay5zYW1wbGVTaXplID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgZW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIGlmICh0aGlzLnRyYWNrLnNhbXBsZVNpemUgPT09IDAgJiYgZW50cmllcyA+IDApIHtcbiAgICAgICAgdGhpcy50cmFjay5zYW1wbGVTaXplcyA9IFtdO1xuICAgICAgICBmb3IgKGkgPSBrID0gMCwgcmVmID0gZW50cmllczsgayA8IHJlZjsgaSA9IGsgKz0gMSkge1xuICAgICAgICAgIHRoaXMudHJhY2suc2FtcGxlU2l6ZXNbaV0gPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnNldHVwU2Vla1BvaW50cygpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0Y28nLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBlbnRyaWVzLCBpLCBrLCByZWY7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgZW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHRoaXMudHJhY2suY2h1bmtPZmZzZXRzID0gW107XG4gICAgICBmb3IgKGkgPSBrID0gMCwgcmVmID0gZW50cmllczsgayA8IHJlZjsgaSA9IGsgKz0gMSkge1xuICAgICAgICB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0c1tpXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnNldHVwU2Vla1BvaW50cygpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLnRyZWYuY2hhcCcsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIGssIHJlZjtcbiAgICAgIGVudHJpZXMgPSB0aGlzLmxlbiA+PiAyO1xuICAgICAgdGhpcy50cmFjay5jaGFwdGVyVHJhY2tzID0gW107XG4gICAgICBmb3IgKGkgPSBrID0gMCwgcmVmID0gZW50cmllczsgayA8IHJlZjsgaSA9IGsgKz0gMSkge1xuICAgICAgICB0aGlzLnRyYWNrLmNoYXB0ZXJUcmFja3NbaV0gPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBNNEFEZW11eGVyLnByb3RvdHlwZS5zZXR1cFNlZWtQb2ludHMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBpLCBqLCBrLCBsLCBsZW4xLCBvZmZzZXQsIHBvc2l0aW9uLCByZWYsIHJlZjEsIHJlc3VsdHMsIHNhbXBsZUluZGV4LCBzaXplLCBzdHNjSW5kZXgsIHN0dHNJbmRleCwgc3R0c1NhbXBsZSwgdGltZXN0YW1wO1xuICAgICAgaWYgKCEoKHRoaXMudHJhY2suY2h1bmtPZmZzZXRzICE9IG51bGwpICYmICh0aGlzLnRyYWNrLnN0c2MgIT0gbnVsbCkgJiYgKHRoaXMudHJhY2suc2FtcGxlU2l6ZSAhPSBudWxsKSAmJiAodGhpcy50cmFjay5zdHRzICE9IG51bGwpKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzdHNjSW5kZXggPSAwO1xuICAgICAgc3R0c0luZGV4ID0gMDtcbiAgICAgIHN0dHNJbmRleCA9IDA7XG4gICAgICBzdHRzU2FtcGxlID0gMDtcbiAgICAgIHNhbXBsZUluZGV4ID0gMDtcbiAgICAgIG9mZnNldCA9IDA7XG4gICAgICB0aW1lc3RhbXAgPSAwO1xuICAgICAgdGhpcy50cmFjay5zZWVrUG9pbnRzID0gW107XG4gICAgICByZWYgPSB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0cztcbiAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgIGZvciAoaSA9IGsgPSAwLCBsZW4xID0gcmVmLmxlbmd0aDsgayA8IGxlbjE7IGkgPSArK2spIHtcbiAgICAgICAgcG9zaXRpb24gPSByZWZbaV07XG4gICAgICAgIGZvciAoaiA9IGwgPSAwLCByZWYxID0gdGhpcy50cmFjay5zdHNjW3N0c2NJbmRleF0uY291bnQ7IGwgPCByZWYxOyBqID0gbCArPSAxKSB7XG4gICAgICAgICAgdGhpcy50cmFjay5zZWVrUG9pbnRzLnB1c2goe1xuICAgICAgICAgICAgb2Zmc2V0OiBvZmZzZXQsXG4gICAgICAgICAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgICAgICAgICB0aW1lc3RhbXA6IHRpbWVzdGFtcFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHNpemUgPSB0aGlzLnRyYWNrLnNhbXBsZVNpemUgfHwgdGhpcy50cmFjay5zYW1wbGVTaXplc1tzYW1wbGVJbmRleCsrXTtcbiAgICAgICAgICBvZmZzZXQgKz0gc2l6ZTtcbiAgICAgICAgICBwb3NpdGlvbiArPSBzaXplO1xuICAgICAgICAgIHRpbWVzdGFtcCArPSB0aGlzLnRyYWNrLnN0dHNbc3R0c0luZGV4XS5kdXJhdGlvbjtcbiAgICAgICAgICBpZiAoc3R0c0luZGV4ICsgMSA8IHRoaXMudHJhY2suc3R0cy5sZW5ndGggJiYgKytzdHRzU2FtcGxlID09PSB0aGlzLnRyYWNrLnN0dHNbc3R0c0luZGV4XS5jb3VudCkge1xuICAgICAgICAgICAgc3R0c1NhbXBsZSA9IDA7XG4gICAgICAgICAgICBzdHRzSW5kZXgrKztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0c2NJbmRleCArIDEgPCB0aGlzLnRyYWNrLnN0c2MubGVuZ3RoICYmIGkgKyAxID09PSB0aGlzLnRyYWNrLnN0c2Nbc3RzY0luZGV4ICsgMV0uZmlyc3QpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2goc3RzY0luZGV4KyspO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdHMucHVzaCh2b2lkIDApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9O1xuXG4gICAgYWZ0ZXIoJ21vb3YnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBrLCBsZW4xLCByZWYsIHRyYWNrO1xuICAgICAgaWYgKHRoaXMubWRhdE9mZnNldCAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtLnNlZWsodGhpcy5tZGF0T2Zmc2V0IC0gOCk7XG4gICAgICB9XG4gICAgICByZWYgPSB0aGlzLnRyYWNrcztcbiAgICAgIGZvciAoayA9IDAsIGxlbjEgPSByZWYubGVuZ3RoOyBrIDwgbGVuMTsgaysrKSB7XG4gICAgICAgIHRyYWNrID0gcmVmW2tdO1xuICAgICAgICBpZiAoISh0cmFjay50eXBlID09PSAnc291bicpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50cmFjayA9IHRyYWNrO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnRyYWNrLnR5cGUgIT09ICdzb3VuJykge1xuICAgICAgICB0aGlzLnRyYWNrID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnTm8gYXVkaW8gdHJhY2tzIGluIG00YSBmaWxlLicpO1xuICAgICAgfVxuICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLnRyYWNrLmZvcm1hdCk7XG4gICAgICB0aGlzLmVtaXQoJ2R1cmF0aW9uJywgdGhpcy50cmFjay5kdXJhdGlvbiAvIHRoaXMudHJhY2sudGltZVNjYWxlICogMTAwMCB8IDApO1xuICAgICAgaWYgKHRoaXMudHJhY2suY29va2llKSB7XG4gICAgICAgIHRoaXMuZW1pdCgnY29va2llJywgdGhpcy50cmFjay5jb29raWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2Vla1BvaW50cyA9IHRoaXMudHJhY2suc2Vla1BvaW50cztcbiAgICB9KTtcblxuICAgIGF0b20oJ21kYXQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBieXRlcywgY2h1bmtTaXplLCBrLCBsZW5ndGgsIG51bVNhbXBsZXMsIG9mZnNldCwgcmVmLCBzYW1wbGUsIHNpemU7XG4gICAgICBpZiAoIXRoaXMuc3RhcnRlZERhdGEpIHtcbiAgICAgICAgaWYgKHRoaXMubWRhdE9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5tZGF0T2Zmc2V0ID0gdGhpcy5zdHJlYW0ub2Zmc2V0O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnRyYWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBieXRlcyA9IE1hdGgubWluKHRoaXMuc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCksIHRoaXMubGVuKTtcbiAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKGJ5dGVzKTtcbiAgICAgICAgICB0aGlzLmxlbiAtPSBieXRlcztcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaHVua0luZGV4ID0gMDtcbiAgICAgICAgdGhpcy5zdHNjSW5kZXggPSAwO1xuICAgICAgICB0aGlzLnNhbXBsZUluZGV4ID0gMDtcbiAgICAgICAgdGhpcy50YWlsT2Zmc2V0ID0gMDtcbiAgICAgICAgdGhpcy50YWlsU2FtcGxlcyA9IDA7XG4gICAgICAgIHRoaXMuc3RhcnRlZERhdGEgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLnJlYWRDaGFwdGVycykge1xuICAgICAgICB0aGlzLnJlYWRDaGFwdGVycyA9IHRoaXMucGFyc2VDaGFwdGVycygpO1xuICAgICAgICBpZiAodGhpc1tcImJyZWFrXCJdID0gIXRoaXMucmVhZENoYXB0ZXJzKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyZWFtLnNlZWsodGhpcy5tZGF0T2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIG9mZnNldCA9IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzW3RoaXMuY2h1bmtJbmRleF0gKyB0aGlzLnRhaWxPZmZzZXQ7XG4gICAgICBsZW5ndGggPSAwO1xuICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUob2Zmc2V0IC0gdGhpcy5zdHJlYW0ub2Zmc2V0KSkge1xuICAgICAgICB0aGlzW1wiYnJlYWtcIl0gPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnN0cmVhbS5zZWVrKG9mZnNldCk7XG4gICAgICB3aGlsZSAodGhpcy5jaHVua0luZGV4IDwgdGhpcy50cmFjay5jaHVua09mZnNldHMubGVuZ3RoKSB7XG4gICAgICAgIG51bVNhbXBsZXMgPSB0aGlzLnRyYWNrLnN0c2NbdGhpcy5zdHNjSW5kZXhdLmNvdW50IC0gdGhpcy50YWlsU2FtcGxlcztcbiAgICAgICAgY2h1bmtTaXplID0gMDtcbiAgICAgICAgZm9yIChzYW1wbGUgPSBrID0gMCwgcmVmID0gbnVtU2FtcGxlczsgayA8IHJlZjsgc2FtcGxlID0gayArPSAxKSB7XG4gICAgICAgICAgc2l6ZSA9IHRoaXMudHJhY2suc2FtcGxlU2l6ZSB8fCB0aGlzLnRyYWNrLnNhbXBsZVNpemVzW3RoaXMuc2FtcGxlSW5kZXhdO1xuICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKGxlbmd0aCArIHNpemUpKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgbGVuZ3RoICs9IHNpemU7XG4gICAgICAgICAgY2h1bmtTaXplICs9IHNpemU7XG4gICAgICAgICAgdGhpcy5zYW1wbGVJbmRleCsrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzYW1wbGUgPCBudW1TYW1wbGVzKSB7XG4gICAgICAgICAgdGhpcy50YWlsT2Zmc2V0ICs9IGNodW5rU2l6ZTtcbiAgICAgICAgICB0aGlzLnRhaWxTYW1wbGVzICs9IHNhbXBsZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNodW5rSW5kZXgrKztcbiAgICAgICAgICB0aGlzLnRhaWxPZmZzZXQgPSAwO1xuICAgICAgICAgIHRoaXMudGFpbFNhbXBsZXMgPSAwO1xuICAgICAgICAgIGlmICh0aGlzLnN0c2NJbmRleCArIDEgPCB0aGlzLnRyYWNrLnN0c2MubGVuZ3RoICYmIHRoaXMuY2h1bmtJbmRleCArIDEgPT09IHRoaXMudHJhY2suc3RzY1t0aGlzLnN0c2NJbmRleCArIDFdLmZpcnN0KSB7XG4gICAgICAgICAgICB0aGlzLnN0c2NJbmRleCsrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAob2Zmc2V0ICsgbGVuZ3RoICE9PSB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0c1t0aGlzLmNodW5rSW5kZXhdKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChsZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIHRoaXMuc3RyZWFtLnJlYWRCdWZmZXIobGVuZ3RoKSk7XG4gICAgICAgIHJldHVybiB0aGlzW1wiYnJlYWtcIl0gPSB0aGlzLmNodW5rSW5kZXggPT09IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzLmxlbmd0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzW1wiYnJlYWtcIl0gPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgTTRBRGVtdXhlci5wcm90b3R5cGUucGFyc2VDaGFwdGVycyA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJvbSwgaWQsIGssIGxlbiwgbGVuMSwgbmV4dFRpbWVzdGFtcCwgcG9pbnQsIHJlZiwgcmVmMSwgcmVmMiwgcmVmMywgdGl0bGUsIHRyYWNrO1xuICAgICAgaWYgKCEoKChyZWYgPSB0aGlzLnRyYWNrLmNoYXB0ZXJUcmFja3MpICE9IG51bGwgPyByZWYubGVuZ3RoIDogdm9pZCAwKSA+IDApKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgaWQgPSB0aGlzLnRyYWNrLmNoYXB0ZXJUcmFja3NbMF07XG4gICAgICByZWYxID0gdGhpcy50cmFja3M7XG4gICAgICBmb3IgKGsgPSAwLCBsZW4xID0gcmVmMS5sZW5ndGg7IGsgPCBsZW4xOyBrKyspIHtcbiAgICAgICAgdHJhY2sgPSByZWYxW2tdO1xuICAgICAgICBpZiAodHJhY2suaWQgPT09IGlkKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0cmFjay5pZCAhPT0gaWQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsICdDaGFwdGVyIHRyYWNrIGRvZXMgbm90IGV4aXN0LicpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuY2hhcHRlcnMgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmNoYXB0ZXJzID0gW107XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5jaGFwdGVycy5sZW5ndGggPCB0cmFjay5zZWVrUG9pbnRzLmxlbmd0aCkge1xuICAgICAgICBwb2ludCA9IHRyYWNrLnNlZWtQb2ludHNbdGhpcy5jaGFwdGVycy5sZW5ndGhdO1xuICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZShwb2ludC5wb3NpdGlvbiAtIHRoaXMuc3RyZWFtLm9mZnNldCArIDMyKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0cmVhbS5zZWVrKHBvaW50LnBvc2l0aW9uKTtcbiAgICAgICAgbGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgICB0aXRsZSA9IG51bGw7XG4gICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKGxlbikpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxlbiA+IDIpIHtcbiAgICAgICAgICBib20gPSB0aGlzLnN0cmVhbS5wZWVrVUludDE2KCk7XG4gICAgICAgICAgaWYgKGJvbSA9PT0gMHhmZWZmIHx8IGJvbSA9PT0gMHhmZmZlKSB7XG4gICAgICAgICAgICB0aXRsZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcobGVuLCAndXRmMTYtYm9tJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aXRsZSA9PSBudWxsKSB7XG4gICAgICAgICAgdGl0bGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKGxlbiwgJ3V0ZjgnKTtcbiAgICAgICAgfVxuICAgICAgICBuZXh0VGltZXN0YW1wID0gKHJlZjIgPSAocmVmMyA9IHRyYWNrLnNlZWtQb2ludHNbdGhpcy5jaGFwdGVycy5sZW5ndGggKyAxXSkgIT0gbnVsbCA/IHJlZjMudGltZXN0YW1wIDogdm9pZCAwKSAhPSBudWxsID8gcmVmMiA6IHRyYWNrLmR1cmF0aW9uO1xuICAgICAgICB0aGlzLmNoYXB0ZXJzLnB1c2goe1xuICAgICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgICAgICB0aW1lc3RhbXA6IHBvaW50LnRpbWVzdGFtcCAvIHRyYWNrLnRpbWVTY2FsZSAqIDEwMDAgfCAwLFxuICAgICAgICAgIGR1cmF0aW9uOiAobmV4dFRpbWVzdGFtcCAtIHBvaW50LnRpbWVzdGFtcCkgLyB0cmFjay50aW1lU2NhbGUgKiAxMDAwIHwgMFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZW1pdCgnY2hhcHRlcnMnLCB0aGlzLmNoYXB0ZXJzKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG5cbiAgICBhdG9tKCdtb292LnVkdGEubWV0YScsIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5tZXRhZGF0YSA9IHt9O1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgfSk7XG5cbiAgICBhZnRlcignbW9vdi51ZHRhLm1ldGEnLCBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmVtaXQoJ21ldGFkYXRhJywgdGhpcy5tZXRhZGF0YSk7XG4gICAgfSk7XG5cbiAgICBtZXRhID0gZnVuY3Rpb24oZmllbGQsIG5hbWUsIGZuKSB7XG4gICAgICByZXR1cm4gYXRvbShcIm1vb3YudWR0YS5tZXRhLmlsc3QuXCIgKyBmaWVsZCArIFwiLmRhdGFcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoOCk7XG4gICAgICAgIHRoaXMubGVuIC09IDg7XG4gICAgICAgIHJldHVybiBmbi5jYWxsKHRoaXMsIG5hbWUpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIHN0cmluZyA9IGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKHRoaXMubGVuLCAndXRmOCcpO1xuICAgIH07XG5cbiAgICBtZXRhKCfCqWFsYicsICdhbGJ1bScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWFyZycsICdhcnJhbmdlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWFydCcsICdhcnRpc3QnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlBUlQnLCAnYXJ0aXN0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2FBUlQnLCAnYWxidW1BcnRpc3QnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnY2F0ZycsICdjYXRlZ29yeScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWNvbScsICdjb21wb3NlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWNweScsICdjb3B5cmlnaHQnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnY3BydCcsICdjb3B5cmlnaHQnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqljbXQnLCAnY29tbWVudHMnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlkYXknLCAncmVsZWFzZURhdGUnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnZGVzYycsICdkZXNjcmlwdGlvbicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWdlbicsICdnZW5yZScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWdycCcsICdncm91cGluZycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWlzcicsICdJU1JDJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2tleXcnLCAna2V5d29yZHMnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlsYWInLCAncmVjb3JkTGFiZWwnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnbGRlcycsICdsb25nRGVzY3JpcHRpb24nLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlseXInLCAnbHlyaWNzJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpbmFtJywgJ3RpdGxlJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpcGhnJywgJ3JlY29yZGluZ0NvcHlyaWdodCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXByZCcsICdwcm9kdWNlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXByZicsICdwZXJmb3JtZXJzJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ3B1cmQnLCAncHVyY2hhc2VEYXRlJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ3B1cmwnLCAncG9kY2FzdFVSTCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXN3ZicsICdzb25nd3JpdGVyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpdG9vJywgJ2VuY29kZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwql3cnQnLCAnY29tcG9zZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnY292cicsICdjb3ZlckFydCcsIGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSB0aGlzLnN0cmVhbS5yZWFkQnVmZmVyKHRoaXMubGVuKTtcbiAgICB9KTtcblxuICAgIGdlbnJlcyA9IFtcIkJsdWVzXCIsIFwiQ2xhc3NpYyBSb2NrXCIsIFwiQ291bnRyeVwiLCBcIkRhbmNlXCIsIFwiRGlzY29cIiwgXCJGdW5rXCIsIFwiR3J1bmdlXCIsIFwiSGlwLUhvcFwiLCBcIkphenpcIiwgXCJNZXRhbFwiLCBcIk5ldyBBZ2VcIiwgXCJPbGRpZXNcIiwgXCJPdGhlclwiLCBcIlBvcFwiLCBcIlImQlwiLCBcIlJhcFwiLCBcIlJlZ2dhZVwiLCBcIlJvY2tcIiwgXCJUZWNobm9cIiwgXCJJbmR1c3RyaWFsXCIsIFwiQWx0ZXJuYXRpdmVcIiwgXCJTa2FcIiwgXCJEZWF0aCBNZXRhbFwiLCBcIlByYW5rc1wiLCBcIlNvdW5kdHJhY2tcIiwgXCJFdXJvLVRlY2hub1wiLCBcIkFtYmllbnRcIiwgXCJUcmlwLUhvcFwiLCBcIlZvY2FsXCIsIFwiSmF6eitGdW5rXCIsIFwiRnVzaW9uXCIsIFwiVHJhbmNlXCIsIFwiQ2xhc3NpY2FsXCIsIFwiSW5zdHJ1bWVudGFsXCIsIFwiQWNpZFwiLCBcIkhvdXNlXCIsIFwiR2FtZVwiLCBcIlNvdW5kIENsaXBcIiwgXCJHb3NwZWxcIiwgXCJOb2lzZVwiLCBcIkFsdGVyblJvY2tcIiwgXCJCYXNzXCIsIFwiU291bFwiLCBcIlB1bmtcIiwgXCJTcGFjZVwiLCBcIk1lZGl0YXRpdmVcIiwgXCJJbnN0cnVtZW50YWwgUG9wXCIsIFwiSW5zdHJ1bWVudGFsIFJvY2tcIiwgXCJFdGhuaWNcIiwgXCJHb3RoaWNcIiwgXCJEYXJrd2F2ZVwiLCBcIlRlY2huby1JbmR1c3RyaWFsXCIsIFwiRWxlY3Ryb25pY1wiLCBcIlBvcC1Gb2xrXCIsIFwiRXVyb2RhbmNlXCIsIFwiRHJlYW1cIiwgXCJTb3V0aGVybiBSb2NrXCIsIFwiQ29tZWR5XCIsIFwiQ3VsdFwiLCBcIkdhbmdzdGFcIiwgXCJUb3AgNDBcIiwgXCJDaHJpc3RpYW4gUmFwXCIsIFwiUG9wL0Z1bmtcIiwgXCJKdW5nbGVcIiwgXCJOYXRpdmUgQW1lcmljYW5cIiwgXCJDYWJhcmV0XCIsIFwiTmV3IFdhdmVcIiwgXCJQc3ljaGFkZWxpY1wiLCBcIlJhdmVcIiwgXCJTaG93dHVuZXNcIiwgXCJUcmFpbGVyXCIsIFwiTG8tRmlcIiwgXCJUcmliYWxcIiwgXCJBY2lkIFB1bmtcIiwgXCJBY2lkIEphenpcIiwgXCJQb2xrYVwiLCBcIlJldHJvXCIsIFwiTXVzaWNhbFwiLCBcIlJvY2sgJiBSb2xsXCIsIFwiSGFyZCBSb2NrXCIsIFwiRm9sa1wiLCBcIkZvbGsvUm9ja1wiLCBcIk5hdGlvbmFsIEZvbGtcIiwgXCJTd2luZ1wiLCBcIkZhc3QgRnVzaW9uXCIsIFwiQmVib2JcIiwgXCJMYXRpblwiLCBcIlJldml2YWxcIiwgXCJDZWx0aWNcIiwgXCJCbHVlZ3Jhc3NcIiwgXCJBdmFudGdhcmRlXCIsIFwiR290aGljIFJvY2tcIiwgXCJQcm9ncmVzc2l2ZSBSb2NrXCIsIFwiUHN5Y2hlZGVsaWMgUm9ja1wiLCBcIlN5bXBob25pYyBSb2NrXCIsIFwiU2xvdyBSb2NrXCIsIFwiQmlnIEJhbmRcIiwgXCJDaG9ydXNcIiwgXCJFYXN5IExpc3RlbmluZ1wiLCBcIkFjb3VzdGljXCIsIFwiSHVtb3VyXCIsIFwiU3BlZWNoXCIsIFwiQ2hhbnNvblwiLCBcIk9wZXJhXCIsIFwiQ2hhbWJlciBNdXNpY1wiLCBcIlNvbmF0YVwiLCBcIlN5bXBob255XCIsIFwiQm9vdHkgQmFzc1wiLCBcIlByaW11c1wiLCBcIlBvcm4gR3Jvb3ZlXCIsIFwiU2F0aXJlXCIsIFwiU2xvdyBKYW1cIiwgXCJDbHViXCIsIFwiVGFuZ29cIiwgXCJTYW1iYVwiLCBcIkZvbGtsb3JlXCIsIFwiQmFsbGFkXCIsIFwiUG93ZXIgQmFsbGFkXCIsIFwiUmh5dGhtaWMgU291bFwiLCBcIkZyZWVzdHlsZVwiLCBcIkR1ZXRcIiwgXCJQdW5rIFJvY2tcIiwgXCJEcnVtIFNvbG9cIiwgXCJBIENhcGVsbGFcIiwgXCJFdXJvLUhvdXNlXCIsIFwiRGFuY2UgSGFsbFwiXTtcblxuICAgIG1ldGEoJ2ducmUnLCAnZ2VucmUnLCBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gZ2VucmVzW3RoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSAtIDFdO1xuICAgIH0pO1xuXG4gICAgbWV0YSgndG1wbycsICd0ZW1wbycsIGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgfSk7XG5cbiAgICBtZXRhKCdydG5nJywgJ3JhdGluZycsIGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICB2YXIgcmF0aW5nO1xuICAgICAgcmF0aW5nID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQ4KCk7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSByYXRpbmcgPT09IDIgPyAnQ2xlYW4nIDogcmF0aW5nICE9PSAwID8gJ0V4cGxpY2l0JyA6ICdOb25lJztcbiAgICB9KTtcblxuICAgIGRpc2tUcmFjayA9IGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCkgKyAnIG9mICcgKyB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDYpO1xuICAgIH07XG5cbiAgICBtZXRhKCdkaXNrJywgJ2Rpc2tOdW1iZXInLCBkaXNrVHJhY2spO1xuXG4gICAgbWV0YSgndHJrbicsICd0cmFja051bWJlcicsIGRpc2tUcmFjayk7XG5cbiAgICBib29sID0gZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50OCgpID09PSAxO1xuICAgIH07XG5cbiAgICBtZXRhKCdjcGlsJywgJ2NvbXBpbGF0aW9uJywgYm9vbCk7XG5cbiAgICBtZXRhKCdwY3N0JywgJ3BvZGNhc3QnLCBib29sKTtcblxuICAgIG1ldGEoJ3BnYXAnLCAnZ2FwbGVzcycsIGJvb2wpO1xuXG4gICAgcmV0dXJuIE00QURlbXV4ZXI7XG5cbiAgfSkoRGVtdXhlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBNNEFEZW11eGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIERlbXV4ZXIsIFdBVkVEZW11eGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRGVtdXhlciA9IHJlcXVpcmUoJy4uL2RlbXV4ZXInKTtcblxuICBXQVZFRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGZvcm1hdHM7XG5cbiAgICBleHRlbmQoV0FWRURlbXV4ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gV0FWRURlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gV0FWRURlbXV4ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVtdXhlci5yZWdpc3RlcihXQVZFRGVtdXhlcik7XG5cbiAgICBXQVZFRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgcmV0dXJuIGJ1ZmZlci5wZWVrU3RyaW5nKDAsIDQpID09PSAnUklGRicgJiYgYnVmZmVyLnBlZWtTdHJpbmcoOCwgNCkgPT09ICdXQVZFJztcbiAgICB9O1xuXG4gICAgZm9ybWF0cyA9IHtcbiAgICAgIDB4MDAwMTogJ2xwY20nLFxuICAgICAgMHgwMDAzOiAnbHBjbScsXG4gICAgICAweDAwMDY6ICdhbGF3JyxcbiAgICAgIDB4MDAwNzogJ3VsYXcnXG4gICAgfTtcblxuICAgIFdBVkVEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBidWZmZXIsIGJ5dGVzLCBlbmNvZGluZztcbiAgICAgIGlmICghdGhpcy5yZWFkU3RhcnQgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEyKSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ1JJRkYnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBXQVYgZmlsZS4nKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZpbGVTaXplID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMih0cnVlKTtcbiAgICAgICAgdGhpcy5yZWFkU3RhcnQgPSB0cnVlO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ1dBVkUnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBXQVYgZmlsZS4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgd2hpbGUgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICBpZiAoIXRoaXMucmVhZEhlYWRlcnMgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDgpKSB7XG4gICAgICAgICAgdGhpcy50eXBlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgICAgICB0aGlzLmxlbiA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIodHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgICAgICBjYXNlICdmbXQgJzpcbiAgICAgICAgICAgIGVuY29kaW5nID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNih0cnVlKTtcbiAgICAgICAgICAgIGlmICghKGVuY29kaW5nIGluIGZvcm1hdHMpKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ1Vuc3VwcG9ydGVkIGZvcm1hdCBpbiBXQVYgZmlsZS4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZm9ybWF0ID0ge1xuICAgICAgICAgICAgICBmb3JtYXRJRDogZm9ybWF0c1tlbmNvZGluZ10sXG4gICAgICAgICAgICAgIGZsb2F0aW5nUG9pbnQ6IGVuY29kaW5nID09PSAweDAwMDMsXG4gICAgICAgICAgICAgIGxpdHRsZUVuZGlhbjogZm9ybWF0c1tlbmNvZGluZ10gPT09ICdscGNtJyxcbiAgICAgICAgICAgICAgY2hhbm5lbHNQZXJGcmFtZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQxNih0cnVlKSxcbiAgICAgICAgICAgICAgc2FtcGxlUmF0ZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMih0cnVlKSxcbiAgICAgICAgICAgICAgZnJhbWVzUGVyUGFja2V0OiAxXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICAgICAgICB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA9ICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDgpICogdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy5mb3JtYXQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDE2KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2RhdGEnOlxuICAgICAgICAgICAgaWYgKCF0aGlzLnNlbnREdXJhdGlvbikge1xuICAgICAgICAgICAgICBieXRlcyA9IHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gODtcbiAgICAgICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMubGVuIC8gYnl0ZXMgLyB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lIC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgICAgICAgdGhpcy5zZW50RHVyYXRpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnVmZmVyID0gdGhpcy5zdHJlYW0ucmVhZFNpbmdsZUJ1ZmZlcih0aGlzLmxlbik7XG4gICAgICAgICAgICB0aGlzLmxlbiAtPSBidWZmZXIubGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IHRoaXMubGVuID4gMDtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIGJ1ZmZlcik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5sZW4pKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnR5cGUgIT09ICdkYXRhJykge1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gV0FWRURlbXV4ZXI7XG5cbiAgfSkoRGVtdXhlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQXVkaW9EZXZpY2UsIEV2ZW50RW1pdHRlcixcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vY29yZS9ldmVudHMnKTtcblxuICBBdWRpb0RldmljZSA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGRldmljZXM7XG5cbiAgICBleHRlbmQoQXVkaW9EZXZpY2UsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gQXVkaW9EZXZpY2Uoc2FtcGxlUmF0ZTEsIGNoYW5uZWxzMSkge1xuICAgICAgdGhpcy5zYW1wbGVSYXRlID0gc2FtcGxlUmF0ZTE7XG4gICAgICB0aGlzLmNoYW5uZWxzID0gY2hhbm5lbHMxO1xuICAgICAgdGhpcy51cGRhdGVUaW1lID0gYmluZCh0aGlzLnVwZGF0ZVRpbWUsIHRoaXMpO1xuICAgICAgdGhpcy5wbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gMDtcbiAgICAgIHRoaXMuX2xhc3RUaW1lID0gMDtcbiAgICB9XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gdHJ1ZTtcbiAgICAgIGlmICh0aGlzLmRldmljZSA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuZGV2aWNlID0gQXVkaW9EZXZpY2UuY3JlYXRlKHRoaXMuc2FtcGxlUmF0ZSwgdGhpcy5jaGFubmVscyk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuZGV2aWNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHN1cHBvcnRlZCBhdWRpbyBkZXZpY2UgZm91bmQuXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5fbGFzdFRpbWUgPSB0aGlzLmRldmljZS5nZXREZXZpY2VUaW1lKCk7XG4gICAgICB0aGlzLl90aW1lciA9IHNldEludGVydmFsKHRoaXMudXBkYXRlVGltZSwgMjAwKTtcbiAgICAgIHJldHVybiB0aGlzLmRldmljZS5vbigncmVmaWxsJywgdGhpcy5yZWZpbGwgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdyZWZpbGwnLCBidWZmZXIpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmRldmljZS5vZmYoJ3JlZmlsbCcsIHRoaXMucmVmaWxsKTtcbiAgICAgIHJldHVybiBjbGVhckludGVydmFsKHRoaXMuX3RpbWVyKTtcbiAgICB9O1xuXG4gICAgQXVkaW9EZXZpY2UucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICB0aGlzLnN0b3AoKTtcbiAgICAgIHJldHVybiAocmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwgPyByZWYuZGVzdHJveSgpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKGN1cnJlbnRUaW1lKSB7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICBpZiAodGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHRoaXMuX2xhc3RUaW1lID0gdGhpcy5kZXZpY2UuZ2V0RGV2aWNlVGltZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgndGltZVVwZGF0ZScsIHRoaXMuY3VycmVudFRpbWUpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUudXBkYXRlVGltZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHRpbWU7XG4gICAgICB0aW1lID0gdGhpcy5kZXZpY2UuZ2V0RGV2aWNlVGltZSgpO1xuICAgICAgdGhpcy5jdXJyZW50VGltZSArPSAodGltZSAtIHRoaXMuX2xhc3RUaW1lKSAvIHRoaXMuZGV2aWNlLnNhbXBsZVJhdGUgKiAxMDAwIHwgMDtcbiAgICAgIHRoaXMuX2xhc3RUaW1lID0gdGltZTtcbiAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3RpbWVVcGRhdGUnLCB0aGlzLmN1cnJlbnRUaW1lKTtcbiAgICB9O1xuXG4gICAgZGV2aWNlcyA9IFtdO1xuXG4gICAgQXVkaW9EZXZpY2UucmVnaXN0ZXIgPSBmdW5jdGlvbihkZXZpY2UpIHtcbiAgICAgIHJldHVybiBkZXZpY2VzLnB1c2goZGV2aWNlKTtcbiAgICB9O1xuXG4gICAgQXVkaW9EZXZpY2UuY3JlYXRlID0gZnVuY3Rpb24oc2FtcGxlUmF0ZSwgY2hhbm5lbHMpIHtcbiAgICAgIHZhciBkZXZpY2UsIGksIGxlbjtcbiAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGRldmljZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgZGV2aWNlID0gZGV2aWNlc1tpXTtcbiAgICAgICAgaWYgKGRldmljZS5zdXBwb3J0ZWQpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IGRldmljZShzYW1wbGVSYXRlLCBjaGFubmVscyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICByZXR1cm4gQXVkaW9EZXZpY2U7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEF1ZGlvRGV2aWNlO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyLCBBdWRpb0RldmljZSwgRXZlbnRFbWl0dGVyLCBNb3ppbGxhQXVkaW9EZXZpY2UsXG4gICAgYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuLi9jb3JlL2V2ZW50cycpO1xuXG4gIEF1ZGlvRGV2aWNlID0gcmVxdWlyZSgnLi4vZGV2aWNlJyk7XG5cbiAgQVZCdWZmZXIgPSByZXF1aXJlKCcuLi9jb3JlL2J1ZmZlcicpO1xuXG4gIE1vemlsbGFBdWRpb0RldmljZSA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGNyZWF0ZVRpbWVyLCBkZXN0cm95VGltZXI7XG5cbiAgICBleHRlbmQoTW96aWxsYUF1ZGlvRGV2aWNlLCBzdXBlckNsYXNzKTtcblxuICAgIEF1ZGlvRGV2aWNlLnJlZ2lzdGVyKE1vemlsbGFBdWRpb0RldmljZSk7XG5cbiAgICBNb3ppbGxhQXVkaW9EZXZpY2Uuc3VwcG9ydGVkID0gKHR5cGVvZiBBdWRpbyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBBdWRpbyAhPT0gbnVsbCkgJiYgJ21veldyaXRlQXVkaW8nIGluIG5ldyBBdWRpbztcblxuICAgIGZ1bmN0aW9uIE1vemlsbGFBdWRpb0RldmljZShzYW1wbGVSYXRlLCBjaGFubmVscykge1xuICAgICAgdGhpcy5zYW1wbGVSYXRlID0gc2FtcGxlUmF0ZTtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVscztcbiAgICAgIHRoaXMucmVmaWxsID0gYmluZCh0aGlzLnJlZmlsbCwgdGhpcyk7XG4gICAgICB0aGlzLmF1ZGlvID0gbmV3IEF1ZGlvO1xuICAgICAgdGhpcy5hdWRpby5tb3pTZXR1cCh0aGlzLmNoYW5uZWxzLCB0aGlzLnNhbXBsZVJhdGUpO1xuICAgICAgdGhpcy53cml0ZVBvc2l0aW9uID0gMDtcbiAgICAgIHRoaXMucHJlYnVmZmVyU2l6ZSA9IHRoaXMuc2FtcGxlUmF0ZSAvIDI7XG4gICAgICB0aGlzLnRhaWwgPSBudWxsO1xuICAgICAgdGhpcy50aW1lciA9IGNyZWF0ZVRpbWVyKHRoaXMucmVmaWxsLCAxMDApO1xuICAgIH1cblxuICAgIE1vemlsbGFBdWRpb0RldmljZS5wcm90b3R5cGUucmVmaWxsID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYXZhaWxhYmxlLCBidWZmZXIsIGN1cnJlbnRQb3NpdGlvbiwgd3JpdHRlbjtcbiAgICAgIGlmICh0aGlzLnRhaWwpIHtcbiAgICAgICAgd3JpdHRlbiA9IHRoaXMuYXVkaW8ubW96V3JpdGVBdWRpbyh0aGlzLnRhaWwpO1xuICAgICAgICB0aGlzLndyaXRlUG9zaXRpb24gKz0gd3JpdHRlbjtcbiAgICAgICAgaWYgKHRoaXMud3JpdGVQb3NpdGlvbiA8IHRoaXMudGFpbC5sZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLnRhaWwgPSB0aGlzLnRhaWwuc3ViYXJyYXkod3JpdHRlbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy50YWlsID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY3VycmVudFBvc2l0aW9uID0gdGhpcy5hdWRpby5tb3pDdXJyZW50U2FtcGxlT2Zmc2V0KCk7XG4gICAgICBhdmFpbGFibGUgPSBjdXJyZW50UG9zaXRpb24gKyB0aGlzLnByZWJ1ZmZlclNpemUgLSB0aGlzLndyaXRlUG9zaXRpb247XG4gICAgICBpZiAoYXZhaWxhYmxlID4gMCkge1xuICAgICAgICBidWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGF2YWlsYWJsZSk7XG4gICAgICAgIHRoaXMuZW1pdCgncmVmaWxsJywgYnVmZmVyKTtcbiAgICAgICAgd3JpdHRlbiA9IHRoaXMuYXVkaW8ubW96V3JpdGVBdWRpbyhidWZmZXIpO1xuICAgICAgICBpZiAod3JpdHRlbiA8IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLnRhaWwgPSBidWZmZXIuc3ViYXJyYXkod3JpdHRlbik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy53cml0ZVBvc2l0aW9uICs9IHdyaXR0ZW47XG4gICAgICB9XG4gICAgfTtcblxuICAgIE1vemlsbGFBdWRpb0RldmljZS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGRlc3Ryb3lUaW1lcih0aGlzLnRpbWVyKTtcbiAgICB9O1xuXG4gICAgTW96aWxsYUF1ZGlvRGV2aWNlLnByb3RvdHlwZS5nZXREZXZpY2VUaW1lID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5hdWRpby5tb3pDdXJyZW50U2FtcGxlT2Zmc2V0KCkgLyB0aGlzLmNoYW5uZWxzO1xuICAgIH07XG5cbiAgICBjcmVhdGVUaW1lciA9IGZ1bmN0aW9uKGZuLCBpbnRlcnZhbCkge1xuICAgICAgdmFyIHVybCwgd29ya2VyO1xuICAgICAgdXJsID0gQVZCdWZmZXIubWFrZUJsb2JVUkwoXCJzZXRJbnRlcnZhbChmdW5jdGlvbigpIHsgcG9zdE1lc3NhZ2UoJ3BpbmcnKTsgfSwgXCIgKyBpbnRlcnZhbCArIFwiKTtcIik7XG4gICAgICBpZiAodXJsID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHNldEludGVydmFsKGZuLCBpbnRlcnZhbCk7XG4gICAgICB9XG4gICAgICB3b3JrZXIgPSBuZXcgV29ya2VyKHVybCk7XG4gICAgICB3b3JrZXIub25tZXNzYWdlID0gZm47XG4gICAgICB3b3JrZXIudXJsID0gdXJsO1xuICAgICAgcmV0dXJuIHdvcmtlcjtcbiAgICB9O1xuXG4gICAgZGVzdHJveVRpbWVyID0gZnVuY3Rpb24odGltZXIpIHtcbiAgICAgIGlmICh0aW1lci50ZXJtaW5hdGUpIHtcbiAgICAgICAgdGltZXIudGVybWluYXRlKCk7XG4gICAgICAgIHJldHVybiBVUkwucmV2b2tlT2JqZWN0VVJMKHRpbWVyLnVybCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gY2xlYXJJbnRlcnZhbCh0aW1lcik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBNb3ppbGxhQXVkaW9EZXZpY2U7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vSmF2YVNjcmlwdCBBdWRpbyBSZXNhbXBsZXJcbi8vQ29weXJpZ2h0IChDKSAyMDExLTIwMTUgR3JhbnQgR2FsaXR6XG4vL1JlbGVhc2VkIHRvIFB1YmxpYyBEb21haW5cbmZ1bmN0aW9uIFJlc2FtcGxlcihmcm9tU2FtcGxlUmF0ZSwgdG9TYW1wbGVSYXRlLCBjaGFubmVscywgaW5wdXRCdWZmZXJMZW5ndGgpIHtcbiAgdGhpcy5mcm9tU2FtcGxlUmF0ZSA9ICtmcm9tU2FtcGxlUmF0ZTtcbiAgdGhpcy50b1NhbXBsZVJhdGUgPSArdG9TYW1wbGVSYXRlO1xuICB0aGlzLmNoYW5uZWxzID0gY2hhbm5lbHMgfCAwO1xuICB0aGlzLmlucHV0QnVmZmVyTGVuZ3RoID0gaW5wdXRCdWZmZXJMZW5ndGg7XG4gIHRoaXMuaW5pdGlhbGl6ZSgpO1xufVxuXG5SZXNhbXBsZXIucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbiAoKSB7XG4gIC8vUGVyZm9ybSBzb21lIGNoZWNrczpcbiAgaWYgKHRoaXMuZnJvbVNhbXBsZVJhdGUgPiAwICYmIHRoaXMudG9TYW1wbGVSYXRlID4gMCAmJiB0aGlzLmNoYW5uZWxzID4gMCkge1xuICAgIGlmICh0aGlzLmZyb21TYW1wbGVSYXRlID09IHRoaXMudG9TYW1wbGVSYXRlKSB7XG4gICAgICAvL1NldHVwIGEgcmVzYW1wbGVyIGJ5cGFzczpcbiAgICAgIHRoaXMucmVzYW1wbGVyID0gdGhpcy5ieXBhc3NSZXNhbXBsZXI7ICAgIC8vUmVzYW1wbGVyIGp1c3QgcmV0dXJucyB3aGF0IHdhcyBwYXNzZWQgdGhyb3VnaC5cbiAgICAgIHRoaXMucmF0aW9XZWlnaHQgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJhdGlvV2VpZ2h0ID0gdGhpcy5mcm9tU2FtcGxlUmF0ZSAvIHRoaXMudG9TYW1wbGVSYXRlO1xuICAgICAgaWYgKHRoaXMuZnJvbVNhbXBsZVJhdGUgPCB0aGlzLnRvU2FtcGxlUmF0ZSkge1xuICAgICAgICAvKlxuICAgICAgICAgIFVzZSBnZW5lcmljIGxpbmVhciBpbnRlcnBvbGF0aW9uIGlmIHVwc2FtcGxpbmcsXG4gICAgICAgICAgYXMgbGluZWFyIGludGVycG9sYXRpb24gcHJvZHVjZXMgYSBncmFkaWVudCB0aGF0IHdlIHdhbnRcbiAgICAgICAgICBhbmQgd29ya3MgZmluZSB3aXRoIHR3byBpbnB1dCBzYW1wbGUgcG9pbnRzIHBlciBvdXRwdXQgaW4gdGhpcyBjYXNlLlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLmNvbXBpbGVMaW5lYXJJbnRlcnBvbGF0aW9uRnVuY3Rpb24oKTtcbiAgICAgICAgdGhpcy5sYXN0V2VpZ2h0ID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8qXG4gICAgICAgICAgQ3VzdG9tIHJlc2FtcGxlciBJIHdyb3RlIHRoYXQgZG9lc24ndCBza2lwIHNhbXBsZXNcbiAgICAgICAgICBsaWtlIHN0YW5kYXJkIGxpbmVhciBpbnRlcnBvbGF0aW9uIGluIGhpZ2ggZG93bnNhbXBsaW5nLlxuICAgICAgICAgIFRoaXMgaXMgbW9yZSBhY2N1cmF0ZSB0aGFuIGxpbmVhciBpbnRlcnBvbGF0aW9uIG9uIGRvd25zYW1wbGluZy5cbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jb21waWxlTXVsdGlUYXBGdW5jdGlvbigpO1xuICAgICAgICB0aGlzLnRhaWxFeGlzdHMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5sYXN0V2VpZ2h0ID0gMDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgdmFyIG91dHB1dEJ1ZmZlclNpemUgPSAoTWF0aC5jZWlsKHRoaXMuaW5wdXRCdWZmZXJMZW5ndGggKiB0aGlzLnRvU2FtcGxlUmF0ZSAvIHRoaXMuZnJvbVNhbXBsZVJhdGUgLyB0aGlzLmNoYW5uZWxzICogMS4wMSkgKiB0aGlzLmNoYW5uZWxzKSArIHRoaXMuY2hhbm5lbHM7XG4gICAgICB0aGlzLm91dHB1dEJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkob3V0cHV0QnVmZmVyU2l6ZSk7XG4gICAgICB0aGlzLmxhc3RPdXRwdXQgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuY2hhbm5lbHMpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyhuZXcgRXJyb3IoXCJJbnZhbGlkIHNldHRpbmdzIHNwZWNpZmllZCBmb3IgdGhlIHJlc2FtcGxlci5cIikpO1xuICB9XG59O1xuXG5SZXNhbXBsZXIucHJvdG90eXBlLmNvbXBpbGVMaW5lYXJJbnRlcnBvbGF0aW9uRnVuY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB0b0NvbXBpbGUgPSBcInZhciBvdXRwdXRPZmZzZXQgPSAwO1xcXG4gICAgdmFyIGJ1ZmZlckxlbmd0aCA9IGJ1ZmZlci5sZW5ndGg7XFxcbiAgICBpZiAoYnVmZmVyTGVuZ3RoID4gMCkge1xcXG4gICAgICB2YXIgd2VpZ2h0ID0gdGhpcy5sYXN0V2VpZ2h0O1xcXG4gICAgICB2YXIgZmlyc3RXZWlnaHQgPSAwO1xcXG4gICAgICB2YXIgc2Vjb25kV2VpZ2h0ID0gMDtcXFxuICAgICAgdmFyIHNvdXJjZU9mZnNldCA9IDA7XFxcbiAgICAgIHZhciBvdXRwdXRPZmZzZXQgPSAwO1xcXG4gICAgICB2YXIgb3V0cHV0QnVmZmVyID0gdGhpcy5vdXRwdXRCdWZmZXI7XFxcbiAgICAgIGZvciAoOyB3ZWlnaHQgPCAxOyB3ZWlnaHQgKz0gXCIgKyB0aGlzLnJhdGlvV2VpZ2h0ICsgXCIpIHtcXFxuICAgICAgICBzZWNvbmRXZWlnaHQgPSB3ZWlnaHQgJSAxO1xcXG4gICAgICAgIGZpcnN0V2VpZ2h0ID0gMSAtIHNlY29uZFdlaWdodDtcIjtcbiAgICAgICAgZm9yICh2YXIgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRCdWZmZXJbb3V0cHV0T2Zmc2V0KytdID0gKHRoaXMubGFzdE91dHB1dFtcIiArIGNoYW5uZWwgKyBcIl0gKiBmaXJzdFdlaWdodCkgKyAoYnVmZmVyW1wiICsgY2hhbm5lbCArIFwiXSAqIHNlY29uZFdlaWdodCk7XCI7XG4gICAgICAgIH1cbiAgICAgIHRvQ29tcGlsZSArPSBcIn1cXFxuICAgICAgd2VpZ2h0IC09IDE7XFxcbiAgICAgIGZvciAoYnVmZmVyTGVuZ3RoIC09IFwiICsgdGhpcy5jaGFubmVscyArIFwiLCBzb3VyY2VPZmZzZXQgPSBNYXRoLmZsb29yKHdlaWdodCkgKiBcIiArIHRoaXMuY2hhbm5lbHMgKyBcIjsgc291cmNlT2Zmc2V0IDwgYnVmZmVyTGVuZ3RoOykge1xcXG4gICAgICAgIHNlY29uZFdlaWdodCA9IHdlaWdodCAlIDE7XFxcbiAgICAgICAgZmlyc3RXZWlnaHQgPSAxIC0gc2Vjb25kV2VpZ2h0O1wiO1xuICAgICAgICBmb3IgKHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dEJ1ZmZlcltvdXRwdXRPZmZzZXQrK10gPSAoYnVmZmVyW3NvdXJjZU9mZnNldFwiICsgKChjaGFubmVsID4gMCkgPyAoXCIgKyBcIiArIGNoYW5uZWwpIDogXCJcIikgKyBcIl0gKiBmaXJzdFdlaWdodCkgKyAoYnVmZmVyW3NvdXJjZU9mZnNldCArIFwiICsgKHRoaXMuY2hhbm5lbHMgKyBjaGFubmVsKSArIFwiXSAqIHNlY29uZFdlaWdodCk7XCI7XG4gICAgICAgIH1cbiAgICAgICAgdG9Db21waWxlICs9IFwid2VpZ2h0ICs9IFwiICsgdGhpcy5yYXRpb1dlaWdodCArIFwiO1xcXG4gICAgICAgIHNvdXJjZU9mZnNldCA9IE1hdGguZmxvb3Iod2VpZ2h0KSAqIFwiICsgdGhpcy5jaGFubmVscyArIFwiO1xcXG4gICAgICB9XCI7XG4gICAgICBmb3IgKHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICB0b0NvbXBpbGUgKz0gXCJ0aGlzLmxhc3RPdXRwdXRbXCIgKyBjaGFubmVsICsgXCJdID0gYnVmZmVyW3NvdXJjZU9mZnNldCsrXTtcIjtcbiAgICAgIH1cbiAgICAgIHRvQ29tcGlsZSArPSBcInRoaXMubGFzdFdlaWdodCA9IHdlaWdodCAlIDE7XFxcbiAgICB9XFxcbiAgICByZXR1cm4gdGhpcy5vdXRwdXRCdWZmZXI7XCI7XG4gICAgXG4gIHRoaXMucmVzYW1wbGVyID0gRnVuY3Rpb24oXCJidWZmZXJcIiwgdG9Db21waWxlKTtcbn07XG5cblJlc2FtcGxlci5wcm90b3R5cGUuY29tcGlsZU11bHRpVGFwRnVuY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB0b0NvbXBpbGUgPSBcInZhciBvdXRwdXRPZmZzZXQgPSAwO1xcXG4gICAgdmFyIGJ1ZmZlckxlbmd0aCA9IGJ1ZmZlci5sZW5ndGg7XFxcbiAgICBpZiAoYnVmZmVyTGVuZ3RoID4gMCkge1xcXG4gICAgICB2YXIgd2VpZ2h0ID0gMDtcIjtcbiAgICAgIGZvciAodmFyIGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgIHRvQ29tcGlsZSArPSBcInZhciBvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiA9IDA7XCJcbiAgICAgIH1cbiAgICAgIHRvQ29tcGlsZSArPSBcInZhciBhY3R1YWxQb3NpdGlvbiA9IDA7XFxcbiAgICAgIHZhciBhbW91bnRUb05leHQgPSAwO1xcXG4gICAgICB2YXIgYWxyZWFkeVByb2Nlc3NlZFRhaWwgPSAhdGhpcy50YWlsRXhpc3RzO1xcXG4gICAgICB0aGlzLnRhaWxFeGlzdHMgPSBmYWxzZTtcXFxuICAgICAgdmFyIG91dHB1dEJ1ZmZlciA9IHRoaXMub3V0cHV0QnVmZmVyO1xcXG4gICAgICB2YXIgY3VycmVudFBvc2l0aW9uID0gMDtcXFxuICAgICAgZG8ge1xcXG4gICAgICAgIGlmIChhbHJlYWR5UHJvY2Vzc2VkVGFpbCkge1xcXG4gICAgICAgICAgd2VpZ2h0ID0gXCIgKyB0aGlzLnJhdGlvV2VpZ2h0ICsgXCI7XCI7XG4gICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0XCIgKyBjaGFubmVsICsgXCIgPSAwO1wiXG4gICAgICAgICAgfVxuICAgICAgICB0b0NvbXBpbGUgKz0gXCJ9XFxcbiAgICAgICAgZWxzZSB7XFxcbiAgICAgICAgICB3ZWlnaHQgPSB0aGlzLmxhc3RXZWlnaHQ7XCI7XG4gICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0XCIgKyBjaGFubmVsICsgXCIgPSB0aGlzLmxhc3RPdXRwdXRbXCIgKyBjaGFubmVsICsgXCJdO1wiXG4gICAgICAgICAgfVxuICAgICAgICAgIHRvQ29tcGlsZSArPSBcImFscmVhZHlQcm9jZXNzZWRUYWlsID0gdHJ1ZTtcXFxuICAgICAgICB9XFxcbiAgICAgICAgd2hpbGUgKHdlaWdodCA+IDAgJiYgYWN0dWFsUG9zaXRpb24gPCBidWZmZXJMZW5ndGgpIHtcXFxuICAgICAgICAgIGFtb3VudFRvTmV4dCA9IDEgKyBhY3R1YWxQb3NpdGlvbiAtIGN1cnJlbnRQb3NpdGlvbjtcXFxuICAgICAgICAgIGlmICh3ZWlnaHQgPj0gYW1vdW50VG9OZXh0KSB7XCI7XG4gICAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dFwiICsgY2hhbm5lbCArIFwiICs9IGJ1ZmZlclthY3R1YWxQb3NpdGlvbisrXSAqIGFtb3VudFRvTmV4dDtcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9Db21waWxlICs9IFwiY3VycmVudFBvc2l0aW9uID0gYWN0dWFsUG9zaXRpb247XFxcbiAgICAgICAgICAgIHdlaWdodCAtPSBhbW91bnRUb05leHQ7XFxcbiAgICAgICAgICB9XFxcbiAgICAgICAgICBlbHNlIHtcIjtcbiAgICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0XCIgKyBjaGFubmVsICsgXCIgKz0gYnVmZmVyW2FjdHVhbFBvc2l0aW9uXCIgKyAoKGNoYW5uZWwgPiAwKSA/IChcIiArIFwiICsgY2hhbm5lbCkgOiBcIlwiKSArIFwiXSAqIHdlaWdodDtcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9Db21waWxlICs9IFwiY3VycmVudFBvc2l0aW9uICs9IHdlaWdodDtcXFxuICAgICAgICAgICAgd2VpZ2h0ID0gMDtcXFxuICAgICAgICAgICAgYnJlYWs7XFxcbiAgICAgICAgICB9XFxcbiAgICAgICAgfVxcXG4gICAgICAgIGlmICh3ZWlnaHQgPD0gMCkge1wiO1xuICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dEJ1ZmZlcltvdXRwdXRPZmZzZXQrK10gPSBvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiAvIFwiICsgdGhpcy5yYXRpb1dlaWdodCArIFwiO1wiXG4gICAgICAgICAgfVxuICAgICAgICB0b0NvbXBpbGUgKz0gXCJ9XFxcbiAgICAgICAgZWxzZSB7XFxcbiAgICAgICAgICB0aGlzLmxhc3RXZWlnaHQgPSB3ZWlnaHQ7XCI7XG4gICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgdG9Db21waWxlICs9IFwidGhpcy5sYXN0T3V0cHV0W1wiICsgY2hhbm5lbCArIFwiXSA9IG91dHB1dFwiICsgY2hhbm5lbCArIFwiO1wiXG4gICAgICAgICAgfVxuICAgICAgICAgIHRvQ29tcGlsZSArPSBcInRoaXMudGFpbEV4aXN0cyA9IHRydWU7XFxcbiAgICAgICAgICBicmVhaztcXFxuICAgICAgICB9XFxcbiAgICAgIH0gd2hpbGUgKGFjdHVhbFBvc2l0aW9uIDwgYnVmZmVyTGVuZ3RoKTtcXFxuICAgIH1cXFxuICAgIHJldHVybiB0aGlzLm91dHB1dEJ1ZmZlcjtcIjtcbiAgXG4gIHRoaXMucmVzYW1wbGVyID0gRnVuY3Rpb24oXCJidWZmZXJcIiwgdG9Db21waWxlKTtcbn07XG5cblJlc2FtcGxlci5wcm90b3R5cGUuYnlwYXNzUmVzYW1wbGVyID0gZnVuY3Rpb24gKGlucHV0QnVmZmVyKSB7XG4gIHJldHVybiBpbnB1dEJ1ZmZlcjtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVzYW1wbGVyO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEF1ZGlvRGV2aWNlLCBFdmVudEVtaXR0ZXIsIFJlc2FtcGxlciwgV2ViQXVkaW9EZXZpY2UsXG4gICAgYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuLi9jb3JlL2V2ZW50cycpO1xuXG4gIEF1ZGlvRGV2aWNlID0gcmVxdWlyZSgnLi4vZGV2aWNlJyk7XG5cbiAgUmVzYW1wbGVyID0gcmVxdWlyZSgnLi9yZXNhbXBsZXInKTtcblxuICBXZWJBdWRpb0RldmljZSA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIEF1ZGlvQ29udGV4dCwgY3JlYXRlUHJvY2Vzc29yLCBzaGFyZWRDb250ZXh0O1xuXG4gICAgZXh0ZW5kKFdlYkF1ZGlvRGV2aWNlLCBzdXBlckNsYXNzKTtcblxuICAgIEF1ZGlvRGV2aWNlLnJlZ2lzdGVyKFdlYkF1ZGlvRGV2aWNlKTtcblxuICAgIEF1ZGlvQ29udGV4dCA9IGdsb2JhbC5BdWRpb0NvbnRleHQgfHwgZ2xvYmFsLndlYmtpdEF1ZGlvQ29udGV4dDtcblxuICAgIFdlYkF1ZGlvRGV2aWNlLnN1cHBvcnRlZCA9IEF1ZGlvQ29udGV4dCAmJiAodHlwZW9mIEF1ZGlvQ29udGV4dC5wcm90b3R5cGVbY3JlYXRlUHJvY2Vzc29yID0gJ2NyZWF0ZVNjcmlwdFByb2Nlc3NvciddID09PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBBdWRpb0NvbnRleHQucHJvdG90eXBlW2NyZWF0ZVByb2Nlc3NvciA9ICdjcmVhdGVKYXZhU2NyaXB0Tm9kZSddID09PSAnZnVuY3Rpb24nKTtcblxuICAgIHNoYXJlZENvbnRleHQgPSBudWxsO1xuXG4gICAgZnVuY3Rpb24gV2ViQXVkaW9EZXZpY2Uoc2FtcGxlUmF0ZSwgY2hhbm5lbHMxKSB7XG4gICAgICB0aGlzLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlO1xuICAgICAgdGhpcy5jaGFubmVscyA9IGNoYW5uZWxzMTtcbiAgICAgIHRoaXMucmVmaWxsID0gYmluZCh0aGlzLnJlZmlsbCwgdGhpcyk7XG4gICAgICB0aGlzLmNvbnRleHQgPSBzaGFyZWRDb250ZXh0ICE9IG51bGwgPyBzaGFyZWRDb250ZXh0IDogc2hhcmVkQ29udGV4dCA9IG5ldyBBdWRpb0NvbnRleHQ7XG4gICAgICB0aGlzLmRldmljZVNhbXBsZVJhdGUgPSB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgIHRoaXMuYnVmZmVyU2l6ZSA9IE1hdGguY2VpbCg0MDk2IC8gKHRoaXMuZGV2aWNlU2FtcGxlUmF0ZSAvIHRoaXMuc2FtcGxlUmF0ZSkgKiB0aGlzLmNoYW5uZWxzKTtcbiAgICAgIHRoaXMuYnVmZmVyU2l6ZSArPSB0aGlzLmJ1ZmZlclNpemUgJSB0aGlzLmNoYW5uZWxzO1xuICAgICAgaWYgKHRoaXMuZGV2aWNlU2FtcGxlUmF0ZSAhPT0gdGhpcy5zYW1wbGVSYXRlKSB7XG4gICAgICAgIHRoaXMucmVzYW1wbGVyID0gbmV3IFJlc2FtcGxlcih0aGlzLnNhbXBsZVJhdGUsIHRoaXMuZGV2aWNlU2FtcGxlUmF0ZSwgdGhpcy5jaGFubmVscywgdGhpcy5idWZmZXJTaXplKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubm9kZSA9IHRoaXMuY29udGV4dFtjcmVhdGVQcm9jZXNzb3JdKDQwOTYsIHRoaXMuY2hhbm5lbHMsIHRoaXMuY2hhbm5lbHMpO1xuICAgICAgdGhpcy5ub2RlLm9uYXVkaW9wcm9jZXNzID0gdGhpcy5yZWZpbGw7XG4gICAgICB0aGlzLm5vZGUuY29ubmVjdCh0aGlzLmNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgIH1cblxuICAgIFdlYkF1ZGlvRGV2aWNlLnByb3RvdHlwZS5yZWZpbGwgPSBmdW5jdGlvbihldmVudCkge1xuICAgICAgdmFyIGNoYW5uZWxDb3VudCwgY2hhbm5lbHMsIGRhdGEsIGksIGosIGssIGwsIG4sIG91dHB1dEJ1ZmZlciwgcmVmLCByZWYxLCByZWYyO1xuICAgICAgb3V0cHV0QnVmZmVyID0gZXZlbnQub3V0cHV0QnVmZmVyO1xuICAgICAgY2hhbm5lbENvdW50ID0gb3V0cHV0QnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7XG4gICAgICBjaGFubmVscyA9IG5ldyBBcnJheShjaGFubmVsQ291bnQpO1xuICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IGNoYW5uZWxDb3VudDsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICBjaGFubmVsc1tpXSA9IG91dHB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgIH1cbiAgICAgIGRhdGEgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYnVmZmVyU2l6ZSk7XG4gICAgICB0aGlzLmVtaXQoJ3JlZmlsbCcsIGRhdGEpO1xuICAgICAgaWYgKHRoaXMucmVzYW1wbGVyKSB7XG4gICAgICAgIGRhdGEgPSB0aGlzLnJlc2FtcGxlci5yZXNhbXBsZXIoZGF0YSk7XG4gICAgICB9XG4gICAgICBmb3IgKGkgPSBrID0gMCwgcmVmMSA9IG91dHB1dEJ1ZmZlci5sZW5ndGg7IGsgPCByZWYxOyBpID0gayArPSAxKSB7XG4gICAgICAgIGZvciAobiA9IGwgPSAwLCByZWYyID0gY2hhbm5lbENvdW50OyBsIDwgcmVmMjsgbiA9IGwgKz0gMSkge1xuICAgICAgICAgIGNoYW5uZWxzW25dW2ldID0gZGF0YVtpICogY2hhbm5lbENvdW50ICsgbl07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgV2ViQXVkaW9EZXZpY2UucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLm5vZGUuZGlzY29ubmVjdCgwKTtcbiAgICB9O1xuXG4gICAgV2ViQXVkaW9EZXZpY2UucHJvdG90eXBlLmdldERldmljZVRpbWUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUgKiB0aGlzLnNhbXBsZVJhdGU7XG4gICAgfTtcblxuICAgIHJldHVybiBXZWJBdWRpb0RldmljZTtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEZpbHRlcjtcblxuICBGaWx0ZXIgPSAoZnVuY3Rpb24oKSB7XG4gICAgZnVuY3Rpb24gRmlsdGVyKGNvbnRleHQsIGtleSkge1xuICAgICAgaWYgKGNvbnRleHQgJiYga2V5KSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndmFsdWUnLCB7XG4gICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0W2tleV07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBGaWx0ZXIucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbihidWZmZXIpIHt9O1xuXG4gICAgcmV0dXJuIEZpbHRlcjtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gRmlsdGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJhbGFuY2VGaWx0ZXIsIEZpbHRlcixcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEZpbHRlciA9IHJlcXVpcmUoJy4uL2ZpbHRlcicpO1xuXG4gIEJhbGFuY2VGaWx0ZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChCYWxhbmNlRmlsdGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIEJhbGFuY2VGaWx0ZXIoKSB7XG4gICAgICByZXR1cm4gQmFsYW5jZUZpbHRlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBCYWxhbmNlRmlsdGVyLnByb3RvdHlwZS5wcm9jZXNzID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgaSwgaiwgcGFuLCByZWY7XG4gICAgICBpZiAodGhpcy52YWx1ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBwYW4gPSBNYXRoLm1heCgtNTAsIE1hdGgubWluKDUwLCB0aGlzLnZhbHVlKSk7XG4gICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gYnVmZmVyLmxlbmd0aDsgaiA8IHJlZjsgaSA9IGogKz0gMikge1xuICAgICAgICBidWZmZXJbaV0gKj0gTWF0aC5taW4oMSwgKDUwIC0gcGFuKSAvIDUwKTtcbiAgICAgICAgYnVmZmVyW2kgKyAxXSAqPSBNYXRoLm1pbigxLCAoNTAgKyBwYW4pIC8gNTApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQmFsYW5jZUZpbHRlcjtcblxuICB9KShGaWx0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQmFsYW5jZUZpbHRlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBGaWx0ZXIsIFZvbHVtZUZpbHRlcixcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEZpbHRlciA9IHJlcXVpcmUoJy4uL2ZpbHRlcicpO1xuXG4gIFZvbHVtZUZpbHRlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFZvbHVtZUZpbHRlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBWb2x1bWVGaWx0ZXIoKSB7XG4gICAgICByZXR1cm4gVm9sdW1lRmlsdGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIFZvbHVtZUZpbHRlci5wcm90b3R5cGUucHJvY2VzcyA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIGksIGosIHJlZiwgdm9sO1xuICAgICAgaWYgKHRoaXMudmFsdWUgPj0gMTAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZvbCA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEwMCwgdGhpcy52YWx1ZSkpIC8gMTAwO1xuICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IGJ1ZmZlci5sZW5ndGg7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgYnVmZmVyW2ldICo9IHZvbDtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIFZvbHVtZUZpbHRlcjtcblxuICB9KShGaWx0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gVm9sdW1lRmlsdGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFzc2V0LCBBdWRpb0RldmljZSwgQmFsYW5jZUZpbHRlciwgRXZlbnRFbWl0dGVyLCBQbGF5ZXIsIFF1ZXVlLCBWb2x1bWVGaWx0ZXIsXG4gICAgYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgQXNzZXQgPSByZXF1aXJlKCcuL2Fzc2V0Jyk7XG5cbiAgVm9sdW1lRmlsdGVyID0gcmVxdWlyZSgnLi9maWx0ZXJzL3ZvbHVtZScpO1xuXG4gIEJhbGFuY2VGaWx0ZXIgPSByZXF1aXJlKCcuL2ZpbHRlcnMvYmFsYW5jZScpO1xuXG4gIFF1ZXVlID0gcmVxdWlyZSgnLi9xdWV1ZScpO1xuXG4gIEF1ZGlvRGV2aWNlID0gcmVxdWlyZSgnLi9kZXZpY2UnKTtcblxuICBQbGF5ZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChQbGF5ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gUGxheWVyKGFzc2V0KSB7XG4gICAgICB0aGlzLmFzc2V0ID0gYXNzZXQ7XG4gICAgICB0aGlzLnN0YXJ0UGxheWluZyA9IGJpbmQodGhpcy5zdGFydFBsYXlpbmcsIHRoaXMpO1xuICAgICAgdGhpcy5wbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmJ1ZmZlcmVkID0gMDtcbiAgICAgIHRoaXMuY3VycmVudFRpbWUgPSAwO1xuICAgICAgdGhpcy5kdXJhdGlvbiA9IDA7XG4gICAgICB0aGlzLnZvbHVtZSA9IDEwMDtcbiAgICAgIHRoaXMucGFuID0gMDtcbiAgICAgIHRoaXMubWV0YWRhdGEgPSB7fTtcbiAgICAgIHRoaXMuZmlsdGVycyA9IFtuZXcgVm9sdW1lRmlsdGVyKHRoaXMsICd2b2x1bWUnKSwgbmV3IEJhbGFuY2VGaWx0ZXIodGhpcywgJ3BhbicpXTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ2J1ZmZlcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyZWQpIHtcbiAgICAgICAgICBfdGhpcy5idWZmZXJlZCA9IGJ1ZmZlcmVkO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdidWZmZXInLCBfdGhpcy5idWZmZXJlZCk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdkZWNvZGVTdGFydCcsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgX3RoaXMucXVldWUgPSBuZXcgUXVldWUoX3RoaXMuYXNzZXQpO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5xdWV1ZS5vbmNlKCdyZWFkeScsIF90aGlzLnN0YXJ0UGxheWluZyk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdmb3JtYXQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGZvcm1hdCkge1xuICAgICAgICAgIF90aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZm9ybWF0JywgX3RoaXMuZm9ybWF0KTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ21ldGFkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihtZXRhZGF0YSkge1xuICAgICAgICAgIF90aGlzLm1ldGFkYXRhID0gbWV0YWRhdGE7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ21ldGFkYXRhJywgX3RoaXMubWV0YWRhdGEpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5vbignZHVyYXRpb24nLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGR1cmF0aW9uKSB7XG4gICAgICAgICAgX3RoaXMuZHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZHVyYXRpb24nLCBfdGhpcy5kdXJhdGlvbik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdlcnJvcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZXJyb3InLCBlcnJvcik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgfVxuXG4gICAgUGxheWVyLmZyb21VUkwgPSBmdW5jdGlvbih1cmwsIG9wdHMpIHtcbiAgICAgIHJldHVybiBuZXcgUGxheWVyKEFzc2V0LmZyb21VUkwodXJsLCBvcHRzKSk7XG4gICAgfTtcblxuICAgIFBsYXllci5mcm9tRmlsZSA9IGZ1bmN0aW9uKGZpbGUpIHtcbiAgICAgIHJldHVybiBuZXcgUGxheWVyKEFzc2V0LmZyb21GaWxlKGZpbGUpKTtcbiAgICB9O1xuXG4gICAgUGxheWVyLmZyb21CdWZmZXIgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBuZXcgUGxheWVyKEFzc2V0LmZyb21CdWZmZXIoYnVmZmVyKSk7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUucHJlbG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLmFzc2V0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RhcnRlZFByZWxvYWRpbmcgPSB0cnVlO1xuICAgICAgcmV0dXJuIHRoaXMuYXNzZXQuc3RhcnQoZmFsc2UpO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnBsYXkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAodGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5zdGFydGVkUHJlbG9hZGluZykge1xuICAgICAgICB0aGlzLnByZWxvYWQoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucGxheWluZyA9IHRydWU7XG4gICAgICByZXR1cm4gKHJlZiA9IHRoaXMuZGV2aWNlKSAhPSBudWxsID8gcmVmLnN0YXJ0KCkgOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAoIXRoaXMucGxheWluZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnBsYXlpbmcgPSBmYWxzZTtcbiAgICAgIHJldHVybiAocmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwgPyByZWYuc3RvcCgpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnRvZ2dsZVBsYXliYWNrID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhdXNlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5wbGF5KCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIHRoaXMucGF1c2UoKTtcbiAgICAgIHRoaXMuYXNzZXQuc3RvcCgpO1xuICAgICAgcmV0dXJuIChyZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCA/IHJlZi5kZXN0cm95KCkgOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHRpbWVzdGFtcCkge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIGlmICgocmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwpIHtcbiAgICAgICAgcmVmLnN0b3AoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucXVldWUub25jZSgncmVhZHknLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciByZWYxLCByZWYyO1xuICAgICAgICAgIGlmICgocmVmMSA9IF90aGlzLmRldmljZSkgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmVmMS5zZWVrKF90aGlzLmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKF90aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiAocmVmMiA9IF90aGlzLmRldmljZSkgIT0gbnVsbCA/IHJlZjIuc3RhcnQoKSA6IHZvaWQgMDtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aW1lc3RhbXAgPSAodGltZXN0YW1wIC8gMTAwMCkgKiB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlO1xuICAgICAgdGltZXN0YW1wID0gdGhpcy5hc3NldC5kZWNvZGVyLnNlZWsodGltZXN0YW1wKTtcbiAgICAgIHRoaXMuY3VycmVudFRpbWUgPSB0aW1lc3RhbXAgLyB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlICogMTAwMCB8IDA7XG4gICAgICB0aGlzLnF1ZXVlLnJlc2V0KCk7XG4gICAgICByZXR1cm4gdGhpcy5jdXJyZW50VGltZTtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5zdGFydFBsYXlpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBmcmFtZSwgZnJhbWVPZmZzZXQ7XG4gICAgICBmcmFtZSA9IHRoaXMucXVldWUucmVhZCgpO1xuICAgICAgZnJhbWVPZmZzZXQgPSAwO1xuICAgICAgdGhpcy5kZXZpY2UgPSBuZXcgQXVkaW9EZXZpY2UodGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSwgdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZSk7XG4gICAgICB0aGlzLmRldmljZS5vbigndGltZVVwZGF0ZScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oY3VycmVudFRpbWUpIHtcbiAgICAgICAgICBfdGhpcy5jdXJyZW50VGltZSA9IGN1cnJlbnRUaW1lO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdwcm9ncmVzcycsIF90aGlzLmN1cnJlbnRUaW1lKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMucmVmaWxsID0gKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgICAgICB2YXIgYnVmZmVyT2Zmc2V0LCBmaWx0ZXIsIGksIGosIGssIGxlbiwgbWF4LCByZWYsIHJlZjE7XG4gICAgICAgICAgaWYgKCFfdGhpcy5wbGF5aW5nKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghZnJhbWUpIHtcbiAgICAgICAgICAgIGZyYW1lID0gX3RoaXMucXVldWUucmVhZCgpO1xuICAgICAgICAgICAgZnJhbWVPZmZzZXQgPSAwO1xuICAgICAgICAgIH1cbiAgICAgICAgICBidWZmZXJPZmZzZXQgPSAwO1xuICAgICAgICAgIHdoaWxlIChmcmFtZSAmJiBidWZmZXJPZmZzZXQgPCBidWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICBtYXggPSBNYXRoLm1pbihmcmFtZS5sZW5ndGggLSBmcmFtZU9mZnNldCwgYnVmZmVyLmxlbmd0aCAtIGJ1ZmZlck9mZnNldCk7XG4gICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gbWF4OyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgICAgICAgIGJ1ZmZlcltidWZmZXJPZmZzZXQrK10gPSBmcmFtZVtmcmFtZU9mZnNldCsrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmcmFtZU9mZnNldCA9PT0gZnJhbWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGZyYW1lID0gX3RoaXMucXVldWUucmVhZCgpO1xuICAgICAgICAgICAgICBmcmFtZU9mZnNldCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlZjEgPSBfdGhpcy5maWx0ZXJzO1xuICAgICAgICAgIGZvciAoayA9IDAsIGxlbiA9IHJlZjEubGVuZ3RoOyBrIDwgbGVuOyBrKyspIHtcbiAgICAgICAgICAgIGZpbHRlciA9IHJlZjFba107XG4gICAgICAgICAgICBmaWx0ZXIucHJvY2VzcyhidWZmZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWZyYW1lKSB7XG4gICAgICAgICAgICBpZiAoX3RoaXMucXVldWUuZW5kZWQpIHtcbiAgICAgICAgICAgICAgX3RoaXMuY3VycmVudFRpbWUgPSBfdGhpcy5kdXJhdGlvbjtcbiAgICAgICAgICAgICAgX3RoaXMuZW1pdCgncHJvZ3Jlc3MnLCBfdGhpcy5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgIF90aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgICAgICAgICBfdGhpcy5zdG9wKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBfdGhpcy5kZXZpY2Uuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpO1xuICAgICAgdGhpcy5kZXZpY2Uub24oJ3JlZmlsbCcsIHRoaXMucmVmaWxsKTtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgdGhpcy5kZXZpY2Uuc3RhcnQoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZiwgcmVmMTtcbiAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgaWYgKChyZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCkge1xuICAgICAgICByZWYub2ZmKCk7XG4gICAgICB9XG4gICAgICBpZiAoKHJlZjEgPSB0aGlzLmFzc2V0KSAhPSBudWxsKSB7XG4gICAgICAgIHJlZjEuZGVzdHJveSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMub2ZmKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBQbGF5ZXI7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFBsYXllcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBFdmVudEVtaXR0ZXIsIFF1ZXVlLFxuICAgIGJpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIFF1ZXVlID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoUXVldWUsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gUXVldWUoYXNzZXQpIHtcbiAgICAgIHRoaXMuYXNzZXQgPSBhc3NldDtcbiAgICAgIHRoaXMud3JpdGUgPSBiaW5kKHRoaXMud3JpdGUsIHRoaXMpO1xuICAgICAgdGhpcy5yZWFkeU1hcmsgPSA2NDtcbiAgICAgIHRoaXMuZmluaXNoZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuYnVmZmVyaW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuYnVmZmVycyA9IFtdO1xuICAgICAgdGhpcy5hc3NldC5vbignZGF0YScsIHRoaXMud3JpdGUpO1xuICAgICAgdGhpcy5hc3NldC5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW5kZWQgPSB0cnVlO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5kZWNvZGVQYWNrZXQoKTtcbiAgICB9XG5cbiAgICBRdWV1ZS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIGlmIChidWZmZXIpIHtcbiAgICAgICAgdGhpcy5idWZmZXJzLnB1c2goYnVmZmVyKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmJ1ZmZlcmluZykge1xuICAgICAgICBpZiAodGhpcy5idWZmZXJzLmxlbmd0aCA+PSB0aGlzLnJlYWR5TWFyayB8fCB0aGlzLmVuZGVkKSB7XG4gICAgICAgICAgdGhpcy5idWZmZXJpbmcgPSBmYWxzZTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdyZWFkeScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmFzc2V0LmRlY29kZVBhY2tldCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIFF1ZXVlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5idWZmZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXNzZXQuZGVjb2RlUGFja2V0KCk7XG4gICAgICByZXR1cm4gdGhpcy5idWZmZXJzLnNoaWZ0KCk7XG4gICAgfTtcblxuICAgIFF1ZXVlLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5idWZmZXJzLmxlbmd0aCA9IDA7XG4gICAgICB0aGlzLmJ1ZmZlcmluZyA9IHRydWU7XG4gICAgICByZXR1cm4gdGhpcy5hc3NldC5kZWNvZGVQYWNrZXQoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFF1ZXVlO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBRdWV1ZTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIkV2ZW50RW1pdHRlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvZXZlbnRzJ1xuQVZCdWZmZXIgPSByZXF1aXJlICcuLi8uLi9jb3JlL2J1ZmZlcidcblxuY2xhc3MgRmlsZVNvdXJjZSBleHRlbmRzIEV2ZW50RW1pdHRlclxuICAgIGNvbnN0cnVjdG9yOiAoQGZpbGUpIC0+XG4gICAgICAgIGlmIG5vdCBGaWxlUmVhZGVyP1xuICAgICAgICAgICAgcmV0dXJuIEBlbWl0ICdlcnJvcicsICdUaGlzIGJyb3dzZXIgZG9lcyBub3QgaGF2ZSBGaWxlUmVhZGVyIHN1cHBvcnQuJ1xuICAgICAgICBcbiAgICAgICAgQG9mZnNldCA9IDBcbiAgICAgICAgQGxlbmd0aCA9IEBmaWxlLnNpemVcbiAgICAgICAgQGNodW5rU2l6ZSA9IDEgPDwgMjBcbiAgICAgICAgQGZpbGVbQHNsaWNlID0gJ3NsaWNlJ10gb3IgQGZpbGVbQHNsaWNlID0gJ3dlYmtpdFNsaWNlJ10gb3IgQGZpbGVbQHNsaWNlID0gJ21velNsaWNlJ11cbiAgICAgICAgICAgIFxuICAgIHN0YXJ0OiAtPlxuICAgICAgICBpZiBAcmVhZGVyXG4gICAgICAgICAgICByZXR1cm4gQGxvb3AoKSB1bmxlc3MgQGFjdGl2ZVxuICAgICAgICBcbiAgICAgICAgQHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyXG4gICAgICAgIEBhY3RpdmUgPSB0cnVlXG4gICAgICAgIFxuICAgICAgICBAcmVhZGVyLm9ubG9hZCA9IChlKSA9PlxuICAgICAgICAgICAgYnVmID0gbmV3IEFWQnVmZmVyKG5ldyBVaW50OEFycmF5KGUudGFyZ2V0LnJlc3VsdCkpXG4gICAgICAgICAgICBAb2Zmc2V0ICs9IGJ1Zi5sZW5ndGhcbiAgICAgICAgXG4gICAgICAgICAgICBAZW1pdCAnZGF0YScsIGJ1ZiAgIFxuICAgICAgICAgICAgQGFjdGl2ZSA9IGZhbHNlICAgICBcbiAgICAgICAgICAgIEBsb29wKCkgaWYgQG9mZnNldCA8IEBsZW5ndGhcbiAgICAgICAgXG4gICAgICAgIEByZWFkZXIub25sb2FkZW5kID0gPT5cbiAgICAgICAgICAgIGlmIEBvZmZzZXQgaXMgQGxlbmd0aFxuICAgICAgICAgICAgICAgIEBlbWl0ICdlbmQnXG4gICAgICAgICAgICAgICAgQHJlYWRlciA9IG51bGxcbiAgICAgICAgXG4gICAgICAgIEByZWFkZXIub25lcnJvciA9IChlKSA9PlxuICAgICAgICAgICAgQGVtaXQgJ2Vycm9yJywgZVxuICAgICAgICBcbiAgICAgICAgQHJlYWRlci5vbnByb2dyZXNzID0gKGUpID0+XG4gICAgICAgICAgICBAZW1pdCAncHJvZ3Jlc3MnLCAoQG9mZnNldCArIGUubG9hZGVkKSAvIEBsZW5ndGggKiAxMDBcbiAgICAgICAgXG4gICAgICAgIEBsb29wKClcbiAgICAgICAgXG4gICAgbG9vcDogLT5cbiAgICAgICAgQGFjdGl2ZSA9IHRydWVcbiAgICAgICAgZW5kUG9zID0gTWF0aC5taW4oQG9mZnNldCArIEBjaHVua1NpemUsIEBsZW5ndGgpXG4gICAgICAgIFxuICAgICAgICBibG9iID0gQGZpbGVbQHNsaWNlXShAb2Zmc2V0LCBlbmRQb3MpXG4gICAgICAgIEByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoYmxvYilcbiAgICAgICAgXG4gICAgcGF1c2U6IC0+XG4gICAgICAgIEBhY3RpdmUgPSBmYWxzZVxuICAgICAgICB0cnlcbiAgICAgICAgICBAcmVhZGVyPy5hYm9ydCgpXG4gICAgICAgIFxuICAgIHJlc2V0OiAtPlxuICAgICAgICBAcGF1c2UoKVxuICAgICAgICBAb2Zmc2V0ID0gMFxuXG5tb2R1bGUuZXhwb3J0cyA9IEZpbGVTb3VyY2VcbiIsIkV2ZW50RW1pdHRlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvZXZlbnRzJ1xuQVZCdWZmZXIgPSByZXF1aXJlICcuLi8uLi9jb3JlL2J1ZmZlcidcblxuY2xhc3MgSFRUUFNvdXJjZSBleHRlbmRzIEV2ZW50RW1pdHRlclxuICAgIGNvbnN0cnVjdG9yOiAoQHVybCwgQG9wdHMgPSB7fSkgLT5cbiAgICAgICAgQGNodW5rU2l6ZSA9IDEgPDwgMjBcbiAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcbiAgICAgICAgaWYgQG9wdHMubGVuZ3RoXG4gICAgICAgICAgICBAbGVuZ3RoID0gQG9wdHMubGVuZ3RoXG4gICAgICAgIEByZXNldCgpXG4gICAgICAgIFxuICAgIHN0YXJ0OiAtPlxuICAgICAgICBpZiBAbGVuZ3RoXG4gICAgICAgICAgICByZXR1cm4gQGxvb3AoKSB1bmxlc3MgQGluZmxpZ2h0XG4gICAgICAgIFxuICAgICAgICBAaW5mbGlnaHQgPSB0cnVlXG4gICAgICAgIEB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKVxuICAgICAgICBcbiAgICAgICAgQHhoci5vbmxvYWQgPSAoZXZlbnQpID0+XG4gICAgICAgICAgICBAbGVuZ3RoID0gcGFyc2VJbnQgQHhoci5nZXRSZXNwb25zZUhlYWRlcihcIkNvbnRlbnQtTGVuZ3RoXCIpICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcbiAgICAgICAgICAgIEBsb29wKClcbiAgICAgICAgXG4gICAgICAgIEB4aHIub25lcnJvciA9IChlcnIpID0+XG4gICAgICAgICAgICBAcGF1c2UoKVxuICAgICAgICAgICAgQGVtaXQgJ2Vycm9yJywgZXJyXG4gICAgICAgICAgICBcbiAgICAgICAgQHhoci5vbmFib3J0ID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcbiAgICAgICAgXG4gICAgICAgIEB4aHIub3BlbihcIkhFQURcIiwgQHVybCwgdHJ1ZSlcbiAgICAgICAgQHhoci5zZW5kKG51bGwpXG4gICAgICAgIFxuICAgIGxvb3A6IC0+XG4gICAgICAgIGlmIEBpbmZsaWdodCBvciBub3QgQGxlbmd0aFxuICAgICAgICAgICAgcmV0dXJuIEBlbWl0ICdlcnJvcicsICdTb21ldGhpbmcgaXMgd3JvbmcgaW4gSFRUUFNvdXJjZS5sb29wJ1xuICAgICAgICAgICAgXG4gICAgICAgIEBpbmZsaWdodCA9IHRydWVcbiAgICAgICAgQHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpXG4gICAgICAgIFxuICAgICAgICBAeGhyLm9ubG9hZCA9IChldmVudCkgPT5cbiAgICAgICAgICAgIGlmIEB4aHIucmVzcG9uc2VcbiAgICAgICAgICAgICAgICBidWYgPSBuZXcgVWludDhBcnJheShAeGhyLnJlc3BvbnNlKVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHR4dCA9IEB4aHIucmVzcG9uc2VUZXh0XG4gICAgICAgICAgICAgICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkodHh0Lmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgaSBpbiBbMC4uLnR4dC5sZW5ndGhdXG4gICAgICAgICAgICAgICAgICAgIGJ1ZltpXSA9IHR4dC5jaGFyQ29kZUF0KGkpICYgMHhmZlxuXG4gICAgICAgICAgICBidWZmZXIgPSBuZXcgQVZCdWZmZXIoYnVmKVxuICAgICAgICAgICAgQG9mZnNldCArPSBidWZmZXIubGVuZ3RoXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIEBlbWl0ICdkYXRhJywgYnVmZmVyXG4gICAgICAgICAgICBAZW1pdCAnZW5kJyBpZiBAb2Zmc2V0ID49IEBsZW5ndGhcblxuICAgICAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcbiAgICAgICAgICAgIEBsb29wKCkgdW5sZXNzIEBvZmZzZXQgPj0gQGxlbmd0aFxuICAgICAgICAgICAgXG4gICAgICAgIEB4aHIub25wcm9ncmVzcyA9IChldmVudCkgPT5cbiAgICAgICAgICAgIEBlbWl0ICdwcm9ncmVzcycsIChAb2Zmc2V0ICsgZXZlbnQubG9hZGVkKSAvIEBsZW5ndGggKiAxMDBcblxuICAgICAgICBAeGhyLm9uZXJyb3IgPSAoZXJyKSA9PlxuICAgICAgICAgICAgQGVtaXQgJ2Vycm9yJywgZXJyXG4gICAgICAgICAgICBAcGF1c2UoKVxuXG4gICAgICAgIEB4aHIub25hYm9ydCA9IChldmVudCkgPT5cbiAgICAgICAgICAgIEBpbmZsaWdodCA9IGZhbHNlXG5cbiAgICAgICAgQHhoci5vcGVuKFwiR0VUXCIsIEB1cmwsIHRydWUpXG4gICAgICAgIEB4aHIucmVzcG9uc2VUeXBlID0gXCJhcnJheWJ1ZmZlclwiXG5cbiAgICAgICAgZW5kUG9zID0gTWF0aC5taW4oQG9mZnNldCArIEBjaHVua1NpemUsIEBsZW5ndGggLSAxKVxuICAgICAgICBAeGhyLnNldFJlcXVlc3RIZWFkZXIoXCJJZi1Ob25lLU1hdGNoXCIsIFwid2Via2l0LW5vLWNhY2hlXCIpXG4gICAgICAgIEB4aHIuc2V0UmVxdWVzdEhlYWRlcihcIlJhbmdlXCIsIFwiYnl0ZXM9I3tAb2Zmc2V0fS0je2VuZFBvc31cIilcbiAgICAgICAgQHhoci5vdmVycmlkZU1pbWVUeXBlKCd0ZXh0L3BsYWluOyBjaGFyc2V0PXgtdXNlci1kZWZpbmVkJylcbiAgICAgICAgQHhoci5zZW5kKG51bGwpXG4gICAgICAgIFxuICAgIHBhdXNlOiAtPlxuICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICBAeGhyPy5hYm9ydCgpXG4gICAgICAgIFxuICAgIHJlc2V0OiAtPlxuICAgICAgICBAcGF1c2UoKVxuICAgICAgICBAb2Zmc2V0ID0gMFxuICAgICAgICBcbm1vZHVsZS5leHBvcnRzID0gSFRUUFNvdXJjZVxuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyLCBCdWZmZXJMaXN0LCBCdWZmZXJTb3VyY2UsIEV2ZW50RW1pdHRlcixcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4uL2NvcmUvZXZlbnRzJyk7XG5cbiAgQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4uL2NvcmUvYnVmZmVybGlzdCcpO1xuXG4gIEFWQnVmZmVyID0gcmVxdWlyZSgnLi4vY29yZS9idWZmZXInKTtcblxuICBCdWZmZXJTb3VyY2UgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIHZhciBjbGVhckltbWVkaWF0ZSwgc2V0SW1tZWRpYXRlO1xuXG4gICAgZXh0ZW5kKEJ1ZmZlclNvdXJjZSwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBCdWZmZXJTb3VyY2UoaW5wdXQpIHtcbiAgICAgIHRoaXMubG9vcCA9IGJpbmQodGhpcy5sb29wLCB0aGlzKTtcbiAgICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIEJ1ZmZlckxpc3QpIHtcbiAgICAgICAgdGhpcy5saXN0ID0gaW5wdXQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxpc3QgPSBuZXcgQnVmZmVyTGlzdDtcbiAgICAgICAgdGhpcy5saXN0LmFwcGVuZChuZXcgQVZCdWZmZXIoaW5wdXQpKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucGF1c2VkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBzZXRJbW1lZGlhdGUgPSBnbG9iYWwuc2V0SW1tZWRpYXRlIHx8IGZ1bmN0aW9uKGZuKSB7XG4gICAgICByZXR1cm4gZ2xvYmFsLnNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG5cbiAgICBjbGVhckltbWVkaWF0ZSA9IGdsb2JhbC5jbGVhckltbWVkaWF0ZSB8fCBmdW5jdGlvbih0aW1lcikge1xuICAgICAgcmV0dXJuIGdsb2JhbC5jbGVhclRpbWVvdXQodGltZXIpO1xuICAgIH07XG5cbiAgICBCdWZmZXJTb3VyY2UucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnBhdXNlZCA9IGZhbHNlO1xuICAgICAgcmV0dXJuIHRoaXMuX3RpbWVyID0gc2V0SW1tZWRpYXRlKHRoaXMubG9vcCk7XG4gICAgfTtcblxuICAgIEJ1ZmZlclNvdXJjZS5wcm90b3R5cGUubG9vcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5lbWl0KCdwcm9ncmVzcycsICh0aGlzLmxpc3QubnVtQnVmZmVycyAtIHRoaXMubGlzdC5hdmFpbGFibGVCdWZmZXJzICsgMSkgLyB0aGlzLmxpc3QubnVtQnVmZmVycyAqIDEwMCB8IDApO1xuICAgICAgdGhpcy5lbWl0KCdkYXRhJywgdGhpcy5saXN0LmZpcnN0KTtcbiAgICAgIGlmICh0aGlzLmxpc3QuYWR2YW5jZSgpKSB7XG4gICAgICAgIHJldHVybiBzZXRJbW1lZGlhdGUodGhpcy5sb29wKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCdWZmZXJTb3VyY2UucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gICAgICBjbGVhckltbWVkaWF0ZSh0aGlzLl90aW1lcik7XG4gICAgICByZXR1cm4gdGhpcy5wYXVzZWQgPSB0cnVlO1xuICAgIH07XG5cbiAgICBCdWZmZXJTb3VyY2UucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnBhdXNlKCk7XG4gICAgICByZXR1cm4gdGhpcy5saXN0LnJld2luZCgpO1xuICAgIH07XG5cbiAgICByZXR1cm4gQnVmZmVyU291cmNlO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBCdWZmZXJTb3VyY2U7XG5cbn0pLmNhbGwodGhpcyk7XG4iXX0=