diff --git a/docs/exampleJSON/remote.json b/docs/exampleJSON/remote.json index 9c9fd20..a0aa28d 100644 --- a/docs/exampleJSON/remote.json +++ b/docs/exampleJSON/remote.json @@ -1,7 +1 @@ -{ - "code":80141, - "command":{ - "type":"play", - "url":"xxx" - } -} +"{'code':55414, "command":{"action":"next"}}" diff --git a/mstream.js b/mstream.js index ae374b6..dab5e35 100755 --- a/mstream.js +++ b/mstream.js @@ -26,11 +26,11 @@ mstream.use(bodyParser.urlencoded({ extended: true })); // support encoded bodie // Setup WebApp if(program.userinterface){ - mstream.use( express.static(fe.join(__dirname, program.userinterface) )); + mstream.use( '/public', express.static(fe.join(__dirname, program.userinterface) )); // Serve the webapp mstream.get('/', function (req, res) { - res.sendFile( fe.join(program.userinterface, 'mstream.html'), { root: __dirname }); + res.sendFile( fe.join('public', 'mstream.html'), { root: __dirname }); }); } @@ -251,10 +251,10 @@ var sharedTokenMap = { }; -mstream.use( '/public-shared', express.static(fe.join(__dirname, 'public-shared') )); +// mstream.use( '/public-shared', express.static(fe.join(__dirname, 'public-shared') )); // Serve the webapp mstream.all('/shared/*', function (req, res) { - res.sendFile( fe.join('public-shared', 'mstream.html'), { root: __dirname }); + res.sendFile( fe.join('public', 'shared.html'), { root: __dirname }); }); // Setup shared diff --git a/public-shared/img/struckaxiom.png b/public-shared/img/struckaxiom.png deleted file mode 100644 index e3c4f4c..0000000 Binary files a/public-shared/img/struckaxiom.png and /dev/null differ diff --git a/public-shared/img/struckaxiom_@2X.png b/public-shared/img/struckaxiom_@2X.png deleted file mode 100644 index 6fa2d86..0000000 Binary files a/public-shared/img/struckaxiom_@2X.png and /dev/null differ diff --git a/public-shared/js/aurora.js b/public-shared/js/aurora.js deleted file mode 100644 index 49bee2c..0000000 --- a/public-shared/js/aurora.js +++ /dev/null @@ -1,4003 +0,0 @@ -(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.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; - }; - - 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){ -// Generated by CoffeeScript 1.7.1 -(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 (_error) {} - 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){ -// Generated by CoffeeScript 1.7.1 -(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.7.1 -(function() { - var Base, EventEmitter, - __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; }, - __slice = [].slice; - - Base = require('./base'); - - EventEmitter = (function(_super) { - __extends(EventEmitter, _super); - - 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.7.1 -(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(list) { - this.list = list; - 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, _i, _j, _ref; - if (littleEndian == null) { - littleEndian = false; - } - if (littleEndian === nativeEndian) { - for (i = _i = 0; _i < bytes; i = _i += 1) { - uint8[i] = this.readUInt8(); - } - } else { - for (i = _j = _ref = bytes - 1; _j >= 0; i = _j += -1) { - uint8[i] = this.readUInt8(); - } - } - }; - - Stream.prototype.peek = function(bytes, offset, littleEndian) { - var i, _i, _j; - if (littleEndian == null) { - littleEndian = false; - } - if (littleEndian === nativeEndian) { - for (i = _i = 0; _i < bytes; i = _i += 1) { - uint8[i] = this.peekUInt8(offset + i); - } - } else { - for (i = _j = 0; _j < bytes; i = _j += 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, result, to, _i; - result = AVBuffer.allocate(length); - to = result.data; - for (i = _i = 0; _i < length; i = _i += 1) { - to[i] = this.readUInt8(); - } - return result; - }; - - Stream.prototype.peekBuffer = function(offset, length) { - var i, result, to, _i; - if (offset == null) { - offset = 0; - } - result = AVBuffer.allocate(length); - to = result.data; - for (i = _i = 0; _i < length; i = _i += 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.7.1 -(function() { - var UnderflowError, - __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; }; - - UnderflowError = (function(_super) { - __extends(UnderflowError, _super); - - 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.7.1 -(function() { - var Bitstream, BufferList, Decoder, EventEmitter, Stream, UnderflowError, - __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'); - - BufferList = require('./core/bufferlist'); - - Stream = require('./core/stream'); - - Bitstream = require('./core/bitstream'); - - UnderflowError = require('./core/underflow'); - - Decoder = (function(_super) { - var codecs; - - __extends(Decoder, _super); - - 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; - try { - return _this.setCookie(cookie); - } catch (_error) { - error = _error; - 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, offset, packet; - this.waiting = !this.receivedFinalBuffer; - offset = this.bitstream.offset(); - try { - packet = this.readChunk(); - } catch (_error) { - error = _error; - 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.7.1 -(function() { - var Decoder, LPCMDecoder, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }; - - Decoder = require('../decoder'); - - LPCMDecoder = (function(_super) { - __extends(LPCMDecoder, _super); - - 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, littleEndian, output, samples, stream, _i, _j, _k, _l, _m, _n; - 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 = _i = 0; _i < samples; i = _i += 1) { - output[i] = stream.readFloat32(littleEndian); - } - break; - case 64: - output = new Float64Array(samples); - for (i = _j = 0; _j < samples; i = _j += 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 = _k = 0; _k < samples; i = _k += 1) { - output[i] = stream.readInt8(); - } - break; - case 16: - output = new Int16Array(samples); - for (i = _l = 0; _l < samples; i = _l += 1) { - output[i] = stream.readInt16(littleEndian); - } - break; - case 24: - output = new Int32Array(samples); - for (i = _m = 0; _m < samples; i = _m += 1) { - output[i] = stream.readInt24(littleEndian); - } - break; - case 32: - output = new Int32Array(samples); - for (i = _n = 0; _n < samples; i = _n += 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.7.1 -(function() { - var Decoder, XLAWDecoder, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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; }; - - Decoder = require('../decoder'); - - XLAWDecoder = (function(_super) { - var BIAS, QUANT_MASK, SEG_MASK, SEG_SHIFT, SIGN_BIT; - - __extends(XLAWDecoder, _super); - - 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, seg, t, table, val, _i, _j; - this.format.bitsPerChannel = 16; - this.table = table = new Int16Array(256); - if (this.format.formatID === 'ulaw') { - for (i = _i = 0; _i < 256; i = ++_i) { - 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 = _j = 0; _j < 256; i = ++_j) { - 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, output, samples, stream, table, _i; - stream = this.stream, table = this.table; - samples = Math.min(4096, this.stream.remainingBytes()); - if (samples === 0) { - return; - } - output = new Int16Array(samples); - for (i = _i = 0; _i < samples; i = _i += 1) { - output[i] = table[stream.readUInt8()]; - } - return output; - }; - - return XLAWDecoder; - - })(Decoder); - -}).call(this); - -},{"../decoder":11}],14:[function(require,module,exports){ -// Generated by CoffeeScript 1.7.1 -(function() { - var BufferList, Demuxer, EventEmitter, Stream, - __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'); - - BufferList = require('./core/bufferlist'); - - Stream = require('./core/stream'); - - Demuxer = (function(_super) { - var formats; - - __extends(Demuxer, _super); - - 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; - 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, format, offset, stream, _i, _len; - 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.7.1 -(function() { - var AIFFDemuxer, Demuxer, - __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; }; - - Demuxer = require('../demuxer'); - - AIFFDemuxer = (function(_super) { - __extends(AIFFDemuxer, _super); - - 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.7.1 -(function() { - var AUDemuxer, Demuxer, - __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; }; - - Demuxer = require('../demuxer'); - - AUDemuxer = (function(_super) { - var bps, formats; - - __extends(AUDemuxer, _super); - - 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.7.1 -(function() { - var CAFDemuxer, Demuxer, M4ADemuxer, - __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; }; - - Demuxer = require('../demuxer'); - - M4ADemuxer = require('./m4a'); - - CAFDemuxer = (function(_super) { - __extends(CAFDemuxer, _super); - - 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, key, metadata, offset, sampleOffset, value, _i, _j, _ref; - 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 ') { - 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 = _i = 0, _ref = this.numPackets; _i < _ref; i = _i += 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 = _j = 0; 0 <= entries ? _j < entries : _j > entries; i = 0 <= entries ? ++_j : --_j) { - 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.7.1 -(function() { - var Demuxer, M4ADemuxer, - __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; }, - __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(_super) { - var BITS_PER_CHANNEL, TYPES, after, atom, atoms, bool, containers, diskTrack, genres, meta, string; - - __extends(M4ADemuxer, _super); - - 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, _i, _len, _ref; - c = []; - _ref = name.split('.').slice(0, -1); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - container = _ref[_i]; - 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, version, _ref, _ref1; - 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, _i; - this.stream.advance(4); - entries = this.stream.readUInt32(); - this.track.stts = []; - for (i = _i = 0; _i < entries; i = _i += 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, _i; - this.stream.advance(4); - entries = this.stream.readUInt32(); - this.track.stsc = []; - for (i = _i = 0; _i < entries; i = _i += 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, _i; - 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 = _i = 0; _i < entries; i = _i += 1) { - this.track.sampleSizes[i] = this.stream.readUInt32(); - } - } - return this.setupSeekPoints(); - }); - - atom('moov.trak.mdia.minf.stbl.stco', function() { - var entries, i, _i; - this.stream.advance(4); - entries = this.stream.readUInt32(); - this.track.chunkOffsets = []; - for (i = _i = 0; _i < entries; i = _i += 1) { - this.track.chunkOffsets[i] = this.stream.readUInt32(); - } - return this.setupSeekPoints(); - }); - - atom('moov.trak.tref.chap', function() { - var entries, i, _i; - entries = this.len >> 2; - this.track.chapterTracks = []; - for (i = _i = 0; _i < entries; i = _i += 1) { - this.track.chapterTracks[i] = this.stream.readUInt32(); - } - }); - - M4ADemuxer.prototype.setupSeekPoints = function() { - var i, j, offset, position, sampleIndex, size, stscIndex, sttsIndex, sttsSample, timestamp, _i, _j, _len, _ref, _ref1, _results; - 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 = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { - position = _ref[i]; - for (j = _j = 0, _ref1 = this.track.stsc[stscIndex].count; _j < _ref1; j = _j += 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 track, _i, _len, _ref; - if (this.mdatOffset != null) { - this.stream.seek(this.mdatOffset - 8); - } - _ref = this.tracks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - track = _ref[_i]; - 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, length, numSamples, offset, sample, size, _i; - 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 = _i = 0; _i < numSamples; sample = _i += 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, len, nextTimestamp, point, title, track, _i, _len, _ref, _ref1, _ref2, _ref3; - if (!(((_ref = this.track.chapterTracks) != null ? _ref.length : void 0) > 0)) { - return true; - } - id = this.track.chapterTracks[0]; - _ref1 = this.tracks; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - track = _ref1[_i]; - 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.7.1 -(function() { - var Demuxer, WAVEDemuxer, - __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; }; - - Demuxer = require('../demuxer'); - - WAVEDemuxer = (function(_super) { - var formats; - - __extends(WAVEDemuxer, _super); - - 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.7.1 -(function() { - var AudioDevice, EventEmitter, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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'); - - AudioDevice = (function(_super) { - var devices; - - __extends(AudioDevice, _super); - - function AudioDevice(sampleRate, channels) { - this.sampleRate = sampleRate; - this.channels = channels; - 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.7.1 -(function() { - var AVBuffer, AudioDevice, EventEmitter, MozillaAudioDevice, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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'); - - AudioDevice = require('../device'); - - AVBuffer = require('../core/buffer'); - - MozillaAudioDevice = (function(_super) { - var createTimer, destroyTimer; - - __extends(MozillaAudioDevice, _super); - - 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); - } - - 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.7.1 -(function() { - var AudioDevice, EventEmitter, Resampler, WebAudioDevice, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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'); - - AudioDevice = require('../device'); - - Resampler = require('./resampler'); - - WebAudioDevice = (function(_super) { - var AudioContext, createProcessor, sharedContext; - - __extends(WebAudioDevice, _super); - - AudioDevice.register(WebAudioDevice); - - AudioContext = global.AudioContext || global.webkitAudioContext; - - WebAudioDevice.supported = AudioContext && (typeof AudioContext.prototype[createProcessor = 'createScriptProcessor'] === 'function' || typeof AudioContext.prototype[createProcessor = 'createJavaScriptNode'] === 'function'); - - sharedContext = null; - - function WebAudioDevice(sampleRate, channels) { - this.sampleRate = sampleRate; - this.channels = channels; - 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, n, outputBuffer, _i, _j, _k, _ref; - outputBuffer = event.outputBuffer; - channelCount = outputBuffer.numberOfChannels; - channels = new Array(channelCount); - for (i = _i = 0; _i < channelCount; i = _i += 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 = _j = 0, _ref = outputBuffer.length; _j < _ref; i = _j += 1) { - for (n = _k = 0; _k < channelCount; n = _k += 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.7.1 -(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.7.1 -(function() { - var BalanceFilter, Filter, - __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; }; - - Filter = require('../filter'); - - BalanceFilter = (function(_super) { - __extends(BalanceFilter, _super); - - function BalanceFilter() { - return BalanceFilter.__super__.constructor.apply(this, arguments); - } - - BalanceFilter.prototype.process = function(buffer) { - var i, pan, _i, _ref; - if (this.value === 0) { - return; - } - pan = Math.max(-50, Math.min(50, this.value)); - for (i = _i = 0, _ref = buffer.length; _i < _ref; i = _i += 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.7.1 -(function() { - var Filter, VolumeFilter, - __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; }; - - Filter = require('../filter'); - - VolumeFilter = (function(_super) { - __extends(VolumeFilter, _super); - - function VolumeFilter() { - return VolumeFilter.__super__.constructor.apply(this, arguments); - } - - VolumeFilter.prototype.process = function(buffer) { - var i, vol, _i, _ref; - if (this.value >= 100) { - return; - } - vol = Math.max(0, Math.min(100, this.value)) / 100; - for (i = _i = 0, _ref = buffer.length; _i < _ref; i = _i += 1) { - buffer[i] *= vol; - } - }; - - return VolumeFilter; - - })(Filter); - - module.exports = VolumeFilter; - -}).call(this); - -},{"../filter":24}],27:[function(require,module,exports){ -// Generated by CoffeeScript 1.7.1 -(function() { - var Asset, AudioDevice, BalanceFilter, EventEmitter, Player, Queue, VolumeFilter, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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'); - - Asset = require('./asset'); - - VolumeFilter = require('./filters/volume'); - - BalanceFilter = require('./filters/balance'); - - Queue = require('./queue'); - - AudioDevice = require('./device'); - - Player = (function(_super) { - __extends(Player, _super); - - function Player(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)); - } - - Player.fromURL = function(url, opts) { - return new Player(Asset.fromURL(url, opts)); - }; - - 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); - }; - - Player.prototype.play = function() { - var _ref; - if (this.playing) { - return; - } - if (!this.startedPreloading) { - this.preload(); - } - 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, max, _i, _j, _len, _ref; - 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 = _i = 0; _i < max; i = _i += 1) { - buffer[bufferOffset++] = frame[frameOffset++]; - } - if (frameOffset === frame.length) { - frame = _this.queue.read(); - frameOffset = 0; - } - } - _ref = _this.filters; - for (_j = 0, _len = _ref.length; _j < _len; _j++) { - filter = _ref[_j]; - 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.7.1 -(function() { - var EventEmitter, Queue, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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'); - - Queue = (function(_super) { - __extends(Queue, _super); - - 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; - 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); - 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.7.1 -(function() { - var AVBuffer, BufferList, BufferSource, EventEmitter, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __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'); - - BufferList = require('../core/bufferlist'); - - AVBuffer = require('../core/buffer'); - - BufferSource = (function(_super) { - var clearImmediate, setImmediate; - - __extends(BufferSource, _super); - - 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYXNzZXQuanMiLCJzcmMvYXVyb3JhLmpzIiwic3JjL2F1cm9yYV9iYXNlLmpzIiwic3JjL2NvcmUvYmFzZS5qcyIsInNyYy9jb3JlL2JpdHN0cmVhbS5qcyIsInNyYy9jb3JlL2J1ZmZlci5qcyIsInNyYy9jb3JlL2J1ZmZlcmxpc3QuanMiLCJzcmMvY29yZS9ldmVudHMuanMiLCJzcmMvY29yZS9zdHJlYW0uanMiLCJzcmMvY29yZS91bmRlcmZsb3cuanMiLCJzcmMvZGVjb2Rlci5qcyIsInNyYy9kZWNvZGVycy9scGNtLmpzIiwic3JjL2RlY29kZXJzL3hsYXcuanMiLCJzcmMvZGVtdXhlci5qcyIsInNyYy9kZW11eGVycy9haWZmLmpzIiwic3JjL2RlbXV4ZXJzL2F1LmpzIiwic3JjL2RlbXV4ZXJzL2NhZi5qcyIsInNyYy9kZW11eGVycy9tNGEuanMiLCJzcmMvZGVtdXhlcnMvd2F2ZS5qcyIsInNyYy9kZXZpY2UuanMiLCJzcmMvZGV2aWNlcy9tb3ppbGxhLmpzIiwic3JjL2RldmljZXMvcmVzYW1wbGVyLmpzIiwic3JjL2RldmljZXMvd2ViYXVkaW8uanMiLCJzcmMvZmlsdGVyLmpzIiwic3JjL2ZpbHRlcnMvYmFsYW5jZS5qcyIsInNyYy9maWx0ZXJzL3ZvbHVtZS5qcyIsInNyYy9wbGF5ZXIuanMiLCJzcmMvcXVldWUuanMiLCIvVXNlcnMvcHNvcmkvRG9jdW1lbnRzL0NvZGUvYXVyb3JhLmpzL3NyYy9zb3VyY2VzL2Jyb3dzZXIvZmlsZS5jb2ZmZWUiLCIvVXNlcnMvcHNvcmkvRG9jdW1lbnRzL0NvZGUvYXVyb3JhLmpzL3NyYy9zb3VyY2VzL2Jyb3dzZXIvaHR0cC5jb2ZmZWUiLCJzcmMvc291cmNlcy9idWZmZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbk9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeG5CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEVBLElBQUEsa0NBQUE7RUFBQTtpU0FBQTs7QUFBQSxZQUFBLEdBQWUsT0FBQSxDQUFRLG1CQUFSLENBQWYsQ0FBQTs7QUFBQSxRQUNBLEdBQVcsT0FBQSxDQUFRLG1CQUFSLENBRFgsQ0FBQTs7QUFBQTtBQUlJLCtCQUFBLENBQUE7O0FBQWEsRUFBQSxvQkFBRSxJQUFGLEdBQUE7QUFDVCxJQURVLElBQUMsQ0FBQSxPQUFBLElBQ1gsQ0FBQTtBQUFBLElBQUEsSUFBTyx3REFBUDtBQUNJLGFBQU8sSUFBQyxDQUFBLElBQUQsQ0FBTSxPQUFOLEVBQWUsZ0RBQWYsQ0FBUCxDQURKO0tBQUE7QUFBQSxJQUdBLElBQUMsQ0FBQSxNQUFELEdBQVUsQ0FIVixDQUFBO0FBQUEsSUFJQSxJQUFDLENBQUEsTUFBRCxHQUFVLElBQUMsQ0FBQSxJQUFJLENBQUMsSUFKaEIsQ0FBQTtBQUFBLElBS0EsSUFBQyxDQUFBLFNBQUQsR0FBYSxDQUFBLElBQUssRUFMbEIsQ0FBQTtBQUFBLElBTUEsSUFBQyxDQUFBLElBQUssQ0FBQSxJQUFDLENBQUEsS0FBRCxHQUFTLE9BQVQsQ0FBTixJQUEyQixJQUFDLENBQUEsSUFBSyxDQUFBLElBQUMsQ0FBQSxLQUFELEdBQVMsYUFBVCxDQUFqQyxJQUE0RCxJQUFDLENBQUEsSUFBSyxDQUFBLElBQUMsQ0FBQSxLQUFELEdBQVMsVUFBVCxDQU5sRSxDQURTO0VBQUEsQ0FBYjs7QUFBQSx1QkFTQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsSUFBQSxJQUFHLElBQUMsQ0FBQSxNQUFKO0FBQ0ksTUFBQSxJQUFBLENBQUEsSUFBdUIsQ0FBQSxNQUF2QjtBQUFBLGVBQU8sSUFBQyxDQUFBLElBQUQsQ0FBQSxDQUFQLENBQUE7T0FESjtLQUFBO0FBQUEsSUFHQSxJQUFDLENBQUEsTUFBRCxHQUFVLEdBQUEsQ0FBQSxVQUhWLENBQUE7QUFBQSxJQUlBLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFKVixDQUFBO0FBQUEsSUFNQSxJQUFDLENBQUEsTUFBTSxDQUFDLE1BQVIsR0FBaUIsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsQ0FBRCxHQUFBO0FBQ2IsWUFBQSxHQUFBO0FBQUEsUUFBQSxHQUFBLEdBQVUsSUFBQSxRQUFBLENBQWEsSUFBQSxVQUFBLENBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFwQixDQUFiLENBQVYsQ0FBQTtBQUFBLFFBQ0EsS0FBQyxDQUFBLE1BQUQsSUFBVyxHQUFHLENBQUMsTUFEZixDQUFBO0FBQUEsUUFHQSxLQUFDLENBQUEsSUFBRCxDQUFNLE1BQU4sRUFBYyxHQUFkLENBSEEsQ0FBQTtBQUFBLFFBSUEsS0FBQyxDQUFBLE1BQUQsR0FBVSxLQUpWLENBQUE7QUFLQSxRQUFBLElBQVcsS0FBQyxDQUFBLE1BQUQsR0FBVSxLQUFDLENBQUEsTUFBdEI7aUJBQUEsS0FBQyxDQUFBLElBQUQsQ0FBQSxFQUFBO1NBTmE7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQU5qQixDQUFBO0FBQUEsSUFjQSxJQUFDLENBQUEsTUFBTSxDQUFDLFNBQVIsR0FBb0IsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUEsR0FBQTtBQUNoQixRQUFBLElBQUcsS0FBQyxDQUFBLE1BQUQsS0FBVyxLQUFDLENBQUEsTUFBZjtBQUNJLFVBQUEsS0FBQyxDQUFBLElBQUQsQ0FBTSxLQUFOLENBQUEsQ0FBQTtpQkFDQSxLQUFDLENBQUEsTUFBRCxHQUFVLEtBRmQ7U0FEZ0I7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQWRwQixDQUFBO0FBQUEsSUFtQkEsSUFBQyxDQUFBLE1BQU0sQ0FBQyxPQUFSLEdBQWtCLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLENBQUQsR0FBQTtlQUNkLEtBQUMsQ0FBQSxJQUFELENBQU0sT0FBTixFQUFlLENBQWYsRUFEYztNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBbkJsQixDQUFBO0FBQUEsSUFzQkEsSUFBQyxDQUFBLE1BQU0sQ0FBQyxVQUFSLEdBQXFCLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLENBQUQsR0FBQTtlQUNqQixLQUFDLENBQUEsSUFBRCxDQUFNLFVBQU4sRUFBa0IsQ0FBQyxLQUFDLENBQUEsTUFBRCxHQUFVLENBQUMsQ0FBQyxNQUFiLENBQUEsR0FBdUIsS0FBQyxDQUFBLE1BQXhCLEdBQWlDLEdBQW5ELEVBRGlCO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0F0QnJCLENBQUE7V0F5QkEsSUFBQyxDQUFBLElBQUQsQ0FBQSxFQTFCRztFQUFBLENBVFAsQ0FBQTs7QUFBQSx1QkFxQ0EsSUFBQSxHQUFNLFNBQUEsR0FBQTtBQUNGLFFBQUEsWUFBQTtBQUFBLElBQUEsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUFWLENBQUE7QUFBQSxJQUNBLE1BQUEsR0FBUyxJQUFJLENBQUMsR0FBTCxDQUFTLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFBQyxDQUFBLFNBQXBCLEVBQStCLElBQUMsQ0FBQSxNQUFoQyxDQURULENBQUE7QUFBQSxJQUdBLElBQUEsR0FBTyxJQUFDLENBQUEsSUFBSyxDQUFBLElBQUMsQ0FBQSxLQUFELENBQU4sQ0FBYyxJQUFDLENBQUEsTUFBZixFQUF1QixNQUF2QixDQUhQLENBQUE7V0FJQSxJQUFDLENBQUEsTUFBTSxDQUFDLGlCQUFSLENBQTBCLElBQTFCLEVBTEU7RUFBQSxDQXJDTixDQUFBOztBQUFBLHVCQTRDQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsUUFBQSxJQUFBO0FBQUEsSUFBQSxJQUFDLENBQUEsTUFBRCxHQUFVLEtBQVYsQ0FBQTtBQUNBO2dEQUNTLENBQUUsS0FBVCxDQUFBLFdBREY7S0FBQSxrQkFGRztFQUFBLENBNUNQLENBQUE7O0FBQUEsdUJBaURBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxJQUFBLElBQUMsQ0FBQSxLQUFELENBQUEsQ0FBQSxDQUFBO1dBQ0EsSUFBQyxDQUFBLE1BQUQsR0FBVSxFQUZQO0VBQUEsQ0FqRFAsQ0FBQTs7b0JBQUE7O0dBRHFCLGFBSHpCLENBQUE7O0FBQUEsTUF5RE0sQ0FBQyxPQUFQLEdBQWlCLFVBekRqQixDQUFBOzs7QUNBQSxJQUFBLGtDQUFBO0VBQUE7aVNBQUE7O0FBQUEsWUFBQSxHQUFlLE9BQUEsQ0FBUSxtQkFBUixDQUFmLENBQUE7O0FBQUEsUUFDQSxHQUFXLE9BQUEsQ0FBUSxtQkFBUixDQURYLENBQUE7O0FBQUE7QUFJSSwrQkFBQSxDQUFBOztBQUFhLEVBQUEsb0JBQUUsR0FBRixFQUFRLElBQVIsR0FBQTtBQUNULElBRFUsSUFBQyxDQUFBLE1BQUEsR0FDWCxDQUFBO0FBQUEsSUFEZ0IsSUFBQyxDQUFBLHNCQUFBLE9BQU8sRUFDeEIsQ0FBQTtBQUFBLElBQUEsSUFBQyxDQUFBLFNBQUQsR0FBYSxDQUFBLElBQUssRUFBbEIsQ0FBQTtBQUFBLElBQ0EsSUFBQyxDQUFBLFFBQUQsR0FBWSxLQURaLENBQUE7QUFFQSxJQUFBLElBQUcsSUFBQyxDQUFBLElBQUksQ0FBQyxNQUFUO0FBQ0ksTUFBQSxJQUFDLENBQUEsTUFBRCxHQUFVLElBQUMsQ0FBQSxJQUFJLENBQUMsTUFBaEIsQ0FESjtLQUZBO0FBQUEsSUFJQSxJQUFDLENBQUEsS0FBRCxDQUFBLENBSkEsQ0FEUztFQUFBLENBQWI7O0FBQUEsdUJBT0EsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILElBQUEsSUFBRyxJQUFDLENBQUEsTUFBSjtBQUNJLE1BQUEsSUFBQSxDQUFBLElBQXVCLENBQUEsUUFBdkI7QUFBQSxlQUFPLElBQUMsQ0FBQSxJQUFELENBQUEsQ0FBUCxDQUFBO09BREo7S0FBQTtBQUFBLElBR0EsSUFBQyxDQUFBLFFBQUQsR0FBWSxJQUhaLENBQUE7QUFBQSxJQUlBLElBQUMsQ0FBQSxHQUFELEdBQVcsSUFBQSxjQUFBLENBQUEsQ0FKWCxDQUFBO0FBQUEsSUFNQSxJQUFDLENBQUEsR0FBRyxDQUFDLE1BQUwsR0FBYyxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxLQUFELEdBQUE7QUFDVixRQUFBLEtBQUMsQ0FBQSxNQUFELEdBQVUsUUFBQSxDQUFTLEtBQUMsQ0FBQSxHQUFHLENBQUMsaUJBQUwsQ0FBdUIsZ0JBQXZCLENBQVQsQ0FBVixDQUFBO0FBQUEsUUFDQSxLQUFDLENBQUEsUUFBRCxHQUFZLEtBRFosQ0FBQTtlQUVBLEtBQUMsQ0FBQSxJQUFELENBQUEsRUFIVTtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBTmQsQ0FBQTtBQUFBLElBV0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxPQUFMLEdBQWUsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsR0FBRCxHQUFBO0FBQ1gsUUFBQSxLQUFDLENBQUEsS0FBRCxDQUFBLENBQUEsQ0FBQTtlQUNBLEtBQUMsQ0FBQSxJQUFELENBQU0sT0FBTixFQUFlLEdBQWYsRUFGVztNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBWGYsQ0FBQTtBQUFBLElBZUEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxPQUFMLEdBQWUsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsS0FBRCxHQUFBO2VBQ1gsS0FBQyxDQUFBLFFBQUQsR0FBWSxNQUREO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FmZixDQUFBO0FBQUEsSUFrQkEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxJQUFMLENBQVUsTUFBVixFQUFrQixJQUFDLENBQUEsR0FBbkIsRUFBd0IsSUFBeEIsQ0FsQkEsQ0FBQTtXQW1CQSxJQUFDLENBQUEsR0FBRyxDQUFDLElBQUwsQ0FBVSxJQUFWLEVBcEJHO0VBQUEsQ0FQUCxDQUFBOztBQUFBLHVCQTZCQSxJQUFBLEdBQU0sU0FBQSxHQUFBO0FBQ0YsUUFBQSxNQUFBO0FBQUEsSUFBQSxJQUFHLElBQUMsQ0FBQSxRQUFELElBQWEsQ0FBQSxJQUFLLENBQUEsTUFBckI7QUFDSSxhQUFPLElBQUMsQ0FBQSxJQUFELENBQU0sT0FBTixFQUFlLHVDQUFmLENBQVAsQ0FESjtLQUFBO0FBQUEsSUFHQSxJQUFDLENBQUEsUUFBRCxHQUFZLElBSFosQ0FBQTtBQUFBLElBSUEsSUFBQyxDQUFBLEdBQUQsR0FBVyxJQUFBLGNBQUEsQ0FBQSxDQUpYLENBQUE7QUFBQSxJQU1BLElBQUMsQ0FBQSxHQUFHLENBQUMsTUFBTCxHQUFjLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEtBQUQsR0FBQTtBQUNWLFlBQUEsNkJBQUE7QUFBQSxRQUFBLElBQUcsS0FBQyxDQUFBLEdBQUcsQ0FBQyxRQUFSO0FBQ0ksVUFBQSxHQUFBLEdBQVUsSUFBQSxVQUFBLENBQVcsS0FBQyxDQUFBLEdBQUcsQ0FBQyxRQUFoQixDQUFWLENBREo7U0FBQSxNQUFBO0FBR0ksVUFBQSxHQUFBLEdBQU0sS0FBQyxDQUFBLEdBQUcsQ0FBQyxZQUFYLENBQUE7QUFBQSxVQUNBLEdBQUEsR0FBVSxJQUFBLFVBQUEsQ0FBVyxHQUFHLENBQUMsTUFBZixDQURWLENBQUE7QUFFQSxlQUFTLDZGQUFULEdBQUE7QUFDSSxZQUFBLEdBQUksQ0FBQSxDQUFBLENBQUosR0FBUyxHQUFHLENBQUMsVUFBSixDQUFlLENBQWYsQ0FBQSxHQUFvQixJQUE3QixDQURKO0FBQUEsV0FMSjtTQUFBO0FBQUEsUUFRQSxNQUFBLEdBQWEsSUFBQSxRQUFBLENBQVMsR0FBVCxDQVJiLENBQUE7QUFBQSxRQVNBLEtBQUMsQ0FBQSxNQUFELElBQVcsTUFBTSxDQUFDLE1BVGxCLENBQUE7QUFBQSxRQVdBLEtBQUMsQ0FBQSxJQUFELENBQU0sTUFBTixFQUFjLE1BQWQsQ0FYQSxDQUFBO0FBWUEsUUFBQSxJQUFlLEtBQUMsQ0FBQSxNQUFELElBQVcsS0FBQyxDQUFBLE1BQTNCO0FBQUEsVUFBQSxLQUFDLENBQUEsSUFBRCxDQUFNLEtBQU4sQ0FBQSxDQUFBO1NBWkE7QUFBQSxRQWNBLEtBQUMsQ0FBQSxRQUFELEdBQVksS0FkWixDQUFBO0FBZUEsUUFBQSxJQUFBLENBQUEsQ0FBZSxLQUFDLENBQUEsTUFBRCxJQUFXLEtBQUMsQ0FBQSxNQUEzQixDQUFBO2lCQUFBLEtBQUMsQ0FBQSxJQUFELENBQUEsRUFBQTtTQWhCVTtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBTmQsQ0FBQTtBQUFBLElBd0JBLElBQUMsQ0FBQSxHQUFHLENBQUMsVUFBTCxHQUFrQixDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxLQUFELEdBQUE7ZUFDZCxLQUFDLENBQUEsSUFBRCxDQUFNLFVBQU4sRUFBa0IsQ0FBQyxLQUFDLENBQUEsTUFBRCxHQUFVLEtBQUssQ0FBQyxNQUFqQixDQUFBLEdBQTJCLEtBQUMsQ0FBQSxNQUE1QixHQUFxQyxHQUF2RCxFQURjO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0F4QmxCLENBQUE7QUFBQSxJQTJCQSxJQUFDLENBQUEsR0FBRyxDQUFDLE9BQUwsR0FBZSxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxHQUFELEdBQUE7QUFDWCxRQUFBLEtBQUMsQ0FBQSxJQUFELENBQU0sT0FBTixFQUFlLEdBQWYsQ0FBQSxDQUFBO2VBQ0EsS0FBQyxDQUFBLEtBQUQsQ0FBQSxFQUZXO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0EzQmYsQ0FBQTtBQUFBLElBK0JBLElBQUMsQ0FBQSxHQUFHLENBQUMsT0FBTCxHQUFlLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEtBQUQsR0FBQTtlQUNYLEtBQUMsQ0FBQSxRQUFELEdBQVksTUFERDtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBL0JmLENBQUE7QUFBQSxJQWtDQSxJQUFDLENBQUEsR0FBRyxDQUFDLElBQUwsQ0FBVSxLQUFWLEVBQWlCLElBQUMsQ0FBQSxHQUFsQixFQUF1QixJQUF2QixDQWxDQSxDQUFBO0FBQUEsSUFtQ0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxZQUFMLEdBQW9CLGFBbkNwQixDQUFBO0FBQUEsSUFxQ0EsTUFBQSxHQUFTLElBQUksQ0FBQyxHQUFMLENBQVMsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUFDLENBQUEsU0FBcEIsRUFBK0IsSUFBQyxDQUFBLE1BQUQsR0FBVSxDQUF6QyxDQXJDVCxDQUFBO0FBQUEsSUFzQ0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxnQkFBTCxDQUFzQixlQUF0QixFQUF1QyxpQkFBdkMsQ0F0Q0EsQ0FBQTtBQUFBLElBdUNBLElBQUMsQ0FBQSxHQUFHLENBQUMsZ0JBQUwsQ0FBc0IsT0FBdEIsRUFBZ0MsUUFBQSxHQUFPLElBQUMsQ0FBQSxNQUFSLEdBQWdCLEdBQWhCLEdBQWtCLE1BQWxELENBdkNBLENBQUE7QUFBQSxJQXdDQSxJQUFDLENBQUEsR0FBRyxDQUFDLGdCQUFMLENBQXNCLG9DQUF0QixDQXhDQSxDQUFBO1dBeUNBLElBQUMsQ0FBQSxHQUFHLENBQUMsSUFBTCxDQUFVLElBQVYsRUExQ0U7RUFBQSxDQTdCTixDQUFBOztBQUFBLHVCQXlFQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsUUFBQSxJQUFBO0FBQUEsSUFBQSxJQUFDLENBQUEsUUFBRCxHQUFZLEtBQVosQ0FBQTsyQ0FDSSxDQUFFLEtBQU4sQ0FBQSxXQUZHO0VBQUEsQ0F6RVAsQ0FBQTs7QUFBQSx1QkE2RUEsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILElBQUEsSUFBQyxDQUFBLEtBQUQsQ0FBQSxDQUFBLENBQUE7V0FDQSxJQUFDLENBQUEsTUFBRCxHQUFVLEVBRlA7RUFBQSxDQTdFUCxDQUFBOztvQkFBQTs7R0FEcUIsYUFIekIsQ0FBQTs7QUFBQSxNQXFGTSxDQUFDLE9BQVAsR0FBaUIsVUFyRmpCLENBQUE7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBc3NldCwgQnVmZmVyU291cmNlLCBEZWNvZGVyLCBEZW11eGVyLCBFdmVudEVtaXR0ZXIsIEZpbGVTb3VyY2UsIEhUVFBTb3VyY2UsXG4gICAgX19iaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgSFRUUFNvdXJjZSA9IHJlcXVpcmUoJy4vc291cmNlcy9ub2RlL2h0dHAnKTtcblxuICBGaWxlU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvZmlsZScpO1xuXG4gIEJ1ZmZlclNvdXJjZSA9IHJlcXVpcmUoJy4vc291cmNlcy9idWZmZXInKTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi9kZW11eGVyJyk7XG5cbiAgRGVjb2RlciA9IHJlcXVpcmUoJy4vZGVjb2RlcicpO1xuXG4gIEFzc2V0ID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhBc3NldCwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIEFzc2V0KHNvdXJjZSkge1xuICAgICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7XG4gICAgICB0aGlzLl9kZWNvZGUgPSBfX2JpbmQodGhpcy5fZGVjb2RlLCB0aGlzKTtcbiAgICAgIHRoaXMuZmluZERlY29kZXIgPSBfX2JpbmQodGhpcy5maW5kRGVjb2RlciwgdGhpcyk7XG4gICAgICB0aGlzLnByb2JlID0gX19iaW5kKHRoaXMucHJvYmUsIHRoaXMpO1xuICAgICAgdGhpcy5idWZmZXJlZCA9IDA7XG4gICAgICB0aGlzLmR1cmF0aW9uID0gbnVsbDtcbiAgICAgIHRoaXMuZm9ybWF0ID0gbnVsbDtcbiAgICAgIHRoaXMubWV0YWRhdGEgPSBudWxsO1xuICAgICAgdGhpcy5hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuZGVtdXhlciA9IG51bGw7XG4gICAgICB0aGlzLmRlY29kZXIgPSBudWxsO1xuICAgICAgdGhpcy5zb3VyY2Uub25jZSgnZGF0YScsIHRoaXMucHJvYmUpO1xuICAgICAgdGhpcy5zb3VyY2Uub24oJ2Vycm9yJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgICBfdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLnN0b3AoKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuc291cmNlLm9uKCdwcm9ncmVzcycsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyZWQpIHtcbiAgICAgICAgICBfdGhpcy5idWZmZXJlZCA9IGJ1ZmZlcmVkO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdidWZmZXInLCBfdGhpcy5idWZmZXJlZCk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgfVxuXG4gICAgQXNzZXQuZnJvbVVSTCA9IGZ1bmN0aW9uKHVybCwgb3B0cykge1xuICAgICAgcmV0dXJuIG5ldyBBc3NldChuZXcgSFRUUFNvdXJjZSh1cmwsIG9wdHMpKTtcbiAgICB9O1xuXG4gICAgQXNzZXQuZnJvbUZpbGUgPSBmdW5jdGlvbihmaWxlKSB7XG4gICAgICByZXR1cm4gbmV3IEFzc2V0KG5ldyBGaWxlU291cmNlKGZpbGUpKTtcbiAgICB9O1xuXG4gICAgQXNzZXQuZnJvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgcmV0dXJuIG5ldyBBc3NldChuZXcgQnVmZmVyU291cmNlKGJ1ZmZlcikpO1xuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihkZWNvZGUpIHtcbiAgICAgIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoZGVjb2RlICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5zaG91bGREZWNvZGUgPSBkZWNvZGU7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5zaG91bGREZWNvZGUgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLnNob3VsZERlY29kZSA9IHRydWU7XG4gICAgICB9XG4gICAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG4gICAgICB0aGlzLnNvdXJjZS5zdGFydCgpO1xuICAgICAgaWYgKHRoaXMuZGVjb2RlciAmJiB0aGlzLnNob3VsZERlY29kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjb2RlKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIXRoaXMuYWN0aXZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gICAgICByZXR1cm4gdGhpcy5zb3VyY2UucGF1c2UoKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGV2ZW50LCBjYWxsYmFjaykge1xuICAgICAgaWYgKGV2ZW50ICE9PSAnZm9ybWF0JyAmJiBldmVudCAhPT0gJ2R1cmF0aW9uJyAmJiBldmVudCAhPT0gJ21ldGFkYXRhJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAodGhpc1tldmVudF0gIT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2sodGhpc1tldmVudF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbmNlKGV2ZW50LCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIF90aGlzLnN0b3AoKTtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayh2YWx1ZSk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSkodGhpcykpO1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFydCgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZGVjb2RlUGFja2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGVyLmRlY29kZSgpO1xuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZGVjb2RlVG9CdWZmZXIgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgICAgdmFyIGNodW5rcywgZGF0YUhhbmRsZXIsIGxlbmd0aDtcbiAgICAgIGxlbmd0aCA9IDA7XG4gICAgICBjaHVua3MgPSBbXTtcbiAgICAgIHRoaXMub24oJ2RhdGEnLCBkYXRhSGFuZGxlciA9IGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgICAgIGxlbmd0aCArPSBjaHVuay5sZW5ndGg7XG4gICAgICAgIHJldHVybiBjaHVua3MucHVzaChjaHVuayk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMub25jZSgnZW5kJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBidWYsIGNodW5rLCBvZmZzZXQsIF9pLCBfbGVuO1xuICAgICAgICBidWYgPSBuZXcgRmxvYXQzMkFycmF5KGxlbmd0aCk7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gY2h1bmtzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgICAgY2h1bmsgPSBjaHVua3NbX2ldO1xuICAgICAgICAgIGJ1Zi5zZXQoY2h1bmssIG9mZnNldCk7XG4gICAgICAgICAgb2Zmc2V0ICs9IGNodW5rLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9mZignZGF0YScsIGRhdGFIYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGJ1Zik7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB0aGlzLnN0YXJ0KCk7XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5wcm9iZSA9IGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgICB2YXIgZGVtdXhlcjtcbiAgICAgIGlmICghdGhpcy5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZGVtdXhlciA9IERlbXV4ZXIuZmluZChjaHVuayk7XG4gICAgICBpZiAoIWRlbXV4ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnQSBkZW11eGVyIGZvciB0aGlzIGNvbnRhaW5lciB3YXMgbm90IGZvdW5kLicpO1xuICAgICAgfVxuICAgICAgdGhpcy5kZW11eGVyID0gbmV3IGRlbXV4ZXIodGhpcy5zb3VyY2UsIGNodW5rKTtcbiAgICAgIHRoaXMuZGVtdXhlci5vbignZm9ybWF0JywgdGhpcy5maW5kRGVjb2Rlcik7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ2R1cmF0aW9uJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihkdXJhdGlvbikge1xuICAgICAgICAgIF90aGlzLmR1cmF0aW9uID0gZHVyYXRpb247XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2R1cmF0aW9uJywgX3RoaXMuZHVyYXRpb24pO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdtZXRhZGF0YScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24obWV0YWRhdGEpIHtcbiAgICAgICAgICBfdGhpcy5tZXRhZGF0YSA9IG1ldGFkYXRhO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdtZXRhZGF0YScsIF90aGlzLm1ldGFkYXRhKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHJldHVybiB0aGlzLmRlbXV4ZXIub24oJ2Vycm9yJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgICBfdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLnN0b3AoKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmZpbmREZWNvZGVyID0gZnVuY3Rpb24oZm9ybWF0KSB7XG4gICAgICB2YXIgZGVjb2RlciwgZGl2O1xuICAgICAgdGhpcy5mb3JtYXQgPSBmb3JtYXQ7XG4gICAgICBpZiAoIXRoaXMuYWN0aXZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy5mb3JtYXQpO1xuICAgICAgZGVjb2RlciA9IERlY29kZXIuZmluZCh0aGlzLmZvcm1hdC5mb3JtYXRJRCk7XG4gICAgICBpZiAoIWRlY29kZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIkEgZGVjb2RlciBmb3IgXCIgKyB0aGlzLmZvcm1hdC5mb3JtYXRJRCArIFwiIHdhcyBub3QgZm91bmQuXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5kZWNvZGVyID0gbmV3IGRlY29kZXIodGhpcy5kZW11eGVyLCB0aGlzLmZvcm1hdCk7XG4gICAgICBpZiAodGhpcy5mb3JtYXQuZmxvYXRpbmdQb2ludCkge1xuICAgICAgICB0aGlzLmRlY29kZXIub24oJ2RhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZGF0YScsIGJ1ZmZlcik7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSkodGhpcykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGl2ID0gTWF0aC5wb3coMiwgdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLSAxKTtcbiAgICAgICAgdGhpcy5kZWNvZGVyLm9uKCdkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgICAgICAgdmFyIGJ1ZiwgaSwgc2FtcGxlLCBfaSwgX2xlbjtcbiAgICAgICAgICAgIGJ1ZiA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKGkgPSBfaSA9IDAsIF9sZW4gPSBidWZmZXIubGVuZ3RoOyBfaSA8IF9sZW47IGkgPSArK19pKSB7XG4gICAgICAgICAgICAgIHNhbXBsZSA9IGJ1ZmZlcltpXTtcbiAgICAgICAgICAgICAgYnVmW2ldID0gc2FtcGxlIC8gZGl2O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2RhdGEnLCBidWYpO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pKHRoaXMpKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZGVjb2Rlci5vbignZXJyb3InLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuc3RvcCgpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5kZWNvZGVyLm9uKCdlbmQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuZW1pdCgnZGVjb2RlU3RhcnQnKTtcbiAgICAgIGlmICh0aGlzLnNob3VsZERlY29kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjb2RlKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5fZGVjb2RlID0gZnVuY3Rpb24oKSB7XG4gICAgICB3aGlsZSAodGhpcy5kZWNvZGVyLmRlY29kZSgpICYmIHRoaXMuYWN0aXZlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuYWN0aXZlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZXIub25jZSgnZGF0YScsIHRoaXMuX2RlY29kZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX3JlZiwgX3JlZjEsIF9yZWYyO1xuICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICBpZiAoKF9yZWYgPSB0aGlzLmRlbXV4ZXIpICE9IG51bGwpIHtcbiAgICAgICAgX3JlZi5vZmYoKTtcbiAgICAgIH1cbiAgICAgIGlmICgoX3JlZjEgPSB0aGlzLmRlY29kZXIpICE9IG51bGwpIHtcbiAgICAgICAgX3JlZjEub2ZmKCk7XG4gICAgICB9XG4gICAgICBpZiAoKF9yZWYyID0gdGhpcy5zb3VyY2UpICE9IG51bGwpIHtcbiAgICAgICAgX3JlZjIub2ZmKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5vZmYoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEFzc2V0O1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBBc3NldDtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIGtleSwgdmFsLCBfcmVmO1xuXG4gIF9yZWYgPSByZXF1aXJlKCcuL2F1cm9yYV9iYXNlJyk7XG4gIGZvciAoa2V5IGluIF9yZWYpIHtcbiAgICB2YWwgPSBfcmVmW2tleV07XG4gICAgZXhwb3J0c1trZXldID0gdmFsO1xuICB9XG5cbiAgcmVxdWlyZSgnLi9kZW11eGVycy9jYWYnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL200YScpO1xuXG4gIHJlcXVpcmUoJy4vZGVtdXhlcnMvYWlmZicpO1xuXG4gIHJlcXVpcmUoJy4vZGVtdXhlcnMvd2F2ZScpO1xuXG4gIHJlcXVpcmUoJy4vZGVtdXhlcnMvYXUnKTtcblxuICByZXF1aXJlKCcuL2RlY29kZXJzL2xwY20nKTtcblxuICByZXF1aXJlKCcuL2RlY29kZXJzL3hsYXcnKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgZXhwb3J0cy5CYXNlID0gcmVxdWlyZSgnLi9jb3JlL2Jhc2UnKTtcblxuICBleHBvcnRzLkJ1ZmZlciA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXInKTtcblxuICBleHBvcnRzLkJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2NvcmUvYnVmZmVybGlzdCcpO1xuXG4gIGV4cG9ydHMuU3RyZWFtID0gcmVxdWlyZSgnLi9jb3JlL3N0cmVhbScpO1xuXG4gIGV4cG9ydHMuQml0c3RyZWFtID0gcmVxdWlyZSgnLi9jb3JlL2JpdHN0cmVhbScpO1xuXG4gIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIGV4cG9ydHMuVW5kZXJmbG93RXJyb3IgPSByZXF1aXJlKCcuL2NvcmUvdW5kZXJmbG93Jyk7XG5cbiAgZXhwb3J0cy5IVFRQU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvaHR0cCcpO1xuXG4gIGV4cG9ydHMuRmlsZVNvdXJjZSA9IHJlcXVpcmUoJy4vc291cmNlcy9ub2RlL2ZpbGUnKTtcblxuICBleHBvcnRzLkJ1ZmZlclNvdXJjZSA9IHJlcXVpcmUoJy4vc291cmNlcy9idWZmZXInKTtcblxuICBleHBvcnRzLkRlbXV4ZXIgPSByZXF1aXJlKCcuL2RlbXV4ZXInKTtcblxuICBleHBvcnRzLkRlY29kZXIgPSByZXF1aXJlKCcuL2RlY29kZXInKTtcblxuICBleHBvcnRzLkF1ZGlvRGV2aWNlID0gcmVxdWlyZSgnLi9kZXZpY2UnKTtcblxuICBleHBvcnRzLkFzc2V0ID0gcmVxdWlyZSgnLi9hc3NldCcpO1xuXG4gIGV4cG9ydHMuUGxheWVyID0gcmVxdWlyZSgnLi9wbGF5ZXInKTtcblxuICBleHBvcnRzLkZpbHRlciA9IHJlcXVpcmUoJy4vZmlsdGVyJyk7XG5cbiAgZXhwb3J0cy5Wb2x1bWVGaWx0ZXIgPSByZXF1aXJlKCcuL2ZpbHRlcnMvdm9sdW1lJyk7XG5cbiAgZXhwb3J0cy5CYWxhbmNlRmlsdGVyID0gcmVxdWlyZSgnLi9maWx0ZXJzL2JhbGFuY2UnKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJhc2UsXG4gICAgX19oYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgX19leHRlbmRzID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChfX2hhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgX19pbmRleE9mID0gW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH07XG5cbiAgQmFzZSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgZm5UZXN0O1xuXG4gICAgZnVuY3Rpb24gQmFzZSgpIHt9XG5cbiAgICBmblRlc3QgPSAvXFxiX3N1cGVyXFxiLztcblxuICAgIEJhc2UuZXh0ZW5kID0gZnVuY3Rpb24ocHJvcCkge1xuICAgICAgdmFyIENsYXNzLCBmbiwga2V5LCBrZXlzLCBfcmVmLCBfc3VwZXI7XG4gICAgICBDbGFzcyA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICAgICAgX19leHRlbmRzKENsYXNzLCBfc3VwZXIpO1xuXG4gICAgICAgIGZ1bmN0aW9uIENsYXNzKCkge1xuICAgICAgICAgIHJldHVybiBDbGFzcy5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDbGFzcztcblxuICAgICAgfSkodGhpcyk7XG4gICAgICBpZiAodHlwZW9mIHByb3AgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAga2V5cyA9IE9iamVjdC5rZXlzKENsYXNzLnByb3RvdHlwZSk7XG4gICAgICAgIHByb3AuY2FsbChDbGFzcywgQ2xhc3MpO1xuICAgICAgICBwcm9wID0ge307XG4gICAgICAgIF9yZWYgPSBDbGFzcy5wcm90b3R5cGU7XG4gICAgICAgIGZvciAoa2V5IGluIF9yZWYpIHtcbiAgICAgICAgICBmbiA9IF9yZWZba2V5XTtcbiAgICAgICAgICBpZiAoX19pbmRleE9mLmNhbGwoa2V5cywga2V5KSA8IDApIHtcbiAgICAgICAgICAgIHByb3Bba2V5XSA9IGZuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgX3N1cGVyID0gQ2xhc3MuX19zdXBlcl9fO1xuICAgICAgZm9yIChrZXkgaW4gcHJvcCkge1xuICAgICAgICBmbiA9IHByb3Bba2V5XTtcbiAgICAgICAgaWYgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJyAmJiBmblRlc3QudGVzdChmbikpIHtcbiAgICAgICAgICAoZnVuY3Rpb24oa2V5LCBmbikge1xuICAgICAgICAgICAgcmV0dXJuIENsYXNzLnByb3RvdHlwZVtrZXldID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHZhciByZXQsIHRtcDtcbiAgICAgICAgICAgICAgdG1wID0gdGhpcy5fc3VwZXI7XG4gICAgICAgICAgICAgIHRoaXMuX3N1cGVyID0gX3N1cGVyW2tleV07XG4gICAgICAgICAgICAgIHJldCA9IGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgIHRoaXMuX3N1cGVyID0gdG1wO1xuICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KShrZXksIGZuKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBDbGFzcy5wcm90b3R5cGVba2V5XSA9IGZuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gQ2xhc3M7XG4gICAgfTtcblxuICAgIHJldHVybiBCYXNlO1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBCYXNlO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQml0c3RyZWFtO1xuXG4gIEJpdHN0cmVhbSA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBCaXRzdHJlYW0oc3RyZWFtKSB7XG4gICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgIHRoaXMuYml0UG9zaXRpb24gPSAwO1xuICAgIH1cblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBCaXRzdHJlYW0odGhpcy5zdHJlYW0uY29weSgpKTtcbiAgICAgIHJlc3VsdC5iaXRQb3NpdGlvbiA9IHRoaXMuYml0UG9zaXRpb247XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLm9mZnNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIDggKiB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmF2YWlsYWJsZSA9IGZ1bmN0aW9uKGJpdHMpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoKGJpdHMgKyA4IC0gdGhpcy5iaXRQb3NpdGlvbikgLyA4KTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5hZHZhbmNlID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gKyBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZShwb3MgPj4gMyk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmV3aW5kID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gLSBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0ucmV3aW5kKE1hdGguYWJzKHBvcyA+PiAzKSk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgdmFyIGN1ck9mZnNldDtcbiAgICAgIGN1ck9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XG4gICAgICBpZiAob2Zmc2V0ID4gY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkdmFuY2Uob2Zmc2V0IC0gY3VyT2Zmc2V0KTtcbiAgICAgIH0gZWxzZSBpZiAob2Zmc2V0IDwgY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJld2luZChjdXJPZmZzZXQgLSBvZmZzZXQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmFsaWduID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5iaXRQb3NpdGlvbiAhPT0gMCkge1xuICAgICAgICB0aGlzLmJpdFBvc2l0aW9uID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKGJpdHMsIHNpZ25lZCkge1xuICAgICAgdmFyIGEsIGEwLCBhMSwgYTIsIGEzLCBhNCwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIG1CaXRzID0gYml0cyArIHRoaXMuYml0UG9zaXRpb247XG4gICAgICBpZiAobUJpdHMgPD0gOCkge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDgoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmYpID4+PiAoOCAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSAxNikge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDE2KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmZmYpID4+PiAoMTYgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMjQpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQyNCgpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmZmYpID4+PiAoMjQgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMzIpIHtcbiAgICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDMyKCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgPj4+ICgzMiAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSA0MCkge1xuICAgICAgICBhMCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgwKSAqIDB4MDEwMDAwMDAwMDtcbiAgICAgICAgYTEgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkgPDwgMjQgPj4+IDA7XG4gICAgICAgIGEyID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDIpIDw8IDE2O1xuICAgICAgICBhMyA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgzKSA8PCA4O1xuICAgICAgICBhNCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KTtcbiAgICAgICAgYSA9IGEwICsgYTEgKyBhMiArIGEzICsgYTQ7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgNDAgLSB0aGlzLmJpdFBvc2l0aW9uKTtcbiAgICAgICAgYSA9IE1hdGguZmxvb3IoYSAvIE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbiAtIGJpdHMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRvbyBtYW55IGJpdHMhXCIpO1xuICAgICAgfVxuICAgICAgaWYgKHNpZ25lZCkge1xuICAgICAgICBpZiAobUJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChhID4+PiAoYml0cyAtIDEpKSB7XG4gICAgICAgICAgICBhID0gKCgxIDw8IGJpdHMgPj4+IDApIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGEgLyBNYXRoLnBvdygyLCBiaXRzIC0gMSkgfCAwKSB7XG4gICAgICAgICAgICBhID0gKE1hdGgucG93KDIsIGJpdHMpIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuYWR2YW5jZShiaXRzKTtcbiAgICAgIHJldHVybiBhO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLnBlZWsgPSBmdW5jdGlvbihiaXRzLCBzaWduZWQpIHtcbiAgICAgIHZhciBhLCBhMCwgYTEsIGEyLCBhMywgYTQsIG1CaXRzO1xuICAgICAgaWYgKGJpdHMgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzIDw9IDgpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQ4KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmKSA+Pj4gKDggLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMTYpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQxNigpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmKSA+Pj4gKDE2IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDI0KSB7XG4gICAgICAgIGEgPSAoKHRoaXMuc3RyZWFtLnBlZWtVSW50MjQoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmZmZmZmKSA+Pj4gKDI0IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDMyKSB7XG4gICAgICAgIGEgPSAodGhpcy5zdHJlYW0ucGVla1VJbnQzMigpIDw8IHRoaXMuYml0UG9zaXRpb24pID4+PiAoMzIgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gNDApIHtcbiAgICAgICAgYTAgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkgKiAweDAxMDAwMDAwMDA7XG4gICAgICAgIGExID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDEpIDw8IDI0ID4+PiAwO1xuICAgICAgICBhMiA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgyKSA8PCAxNjtcbiAgICAgICAgYTMgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMykgPDwgODtcbiAgICAgICAgYTQgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoNCk7XG4gICAgICAgIGEgPSBhMCArIGExICsgYTIgKyBhMyArIGE0O1xuICAgICAgICBhICU9IE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICAgIGEgPSBNYXRoLmZsb29yKGEgLyBNYXRoLnBvdygyLCA0MCAtIHRoaXMuYml0UG9zaXRpb24gLSBiaXRzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUb28gbWFueSBiaXRzIVwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5yZWFkTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmFkdmFuY2UoYml0cyk7XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5wZWVrTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJpdHN0cmVhbTtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQml0c3RyZWFtO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQVZCdWZmZXI7XG5cbiAgQVZCdWZmZXIgPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIEJsb2JCdWlsZGVyLCBVUkw7XG5cbiAgICBmdW5jdGlvbiBBVkJ1ZmZlcihpbnB1dCkge1xuICAgICAgdmFyIF9yZWY7XG4gICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGlucHV0O1xuICAgICAgfSBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IEFycmF5LmlzQXJyYXkoaW5wdXQpIHx8IHR5cGVvZiBpbnB1dCA9PT0gJ251bWJlcicgfHwgKChfcmVmID0gZ2xvYmFsLkJ1ZmZlcikgIT0gbnVsbCA/IF9yZWYuaXNCdWZmZXIoaW5wdXQpIDogdm9pZCAwKSkge1xuICAgICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShpbnB1dCk7XG4gICAgICB9IGVsc2UgaWYgKGlucHV0LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGlucHV0LmJ1ZmZlciwgaW5wdXQuYnl0ZU9mZnNldCwgaW5wdXQubGVuZ3RoICogaW5wdXQuQllURVNfUEVSX0VMRU1FTlQpO1xuICAgICAgfSBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIEFWQnVmZmVyKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGlucHV0LmRhdGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb25zdHJ1Y3RpbmcgYnVmZmVyIHdpdGggdW5rbm93biB0eXBlLlwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubGVuZ3RoID0gdGhpcy5kYXRhLmxlbmd0aDtcbiAgICAgIHRoaXMubmV4dCA9IG51bGw7XG4gICAgICB0aGlzLnByZXYgPSBudWxsO1xuICAgIH1cblxuICAgIEFWQnVmZmVyLmFsbG9jYXRlID0gZnVuY3Rpb24oc2l6ZSkge1xuICAgICAgcmV0dXJuIG5ldyBBVkJ1ZmZlcihzaXplKTtcbiAgICB9O1xuXG4gICAgQVZCdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIobmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhKSk7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKHBvc2l0aW9uLCBsZW5ndGgpIHtcbiAgICAgIGlmIChsZW5ndGggPT0gbnVsbCkge1xuICAgICAgICBsZW5ndGggPSB0aGlzLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGlmIChwb3NpdGlvbiA9PT0gMCAmJiBsZW5ndGggPj0gdGhpcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBVkJ1ZmZlcih0aGlzLmRhdGEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBVkJ1ZmZlcih0aGlzLmRhdGEuc3ViYXJyYXkocG9zaXRpb24sIHBvc2l0aW9uICsgbGVuZ3RoKSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJsb2JCdWlsZGVyID0gZ2xvYmFsLkJsb2JCdWlsZGVyIHx8IGdsb2JhbC5Nb3pCbG9iQnVpbGRlciB8fCBnbG9iYWwuV2ViS2l0QmxvYkJ1aWxkZXI7XG5cbiAgICBVUkwgPSBnbG9iYWwuVVJMIHx8IGdsb2JhbC53ZWJraXRVUkwgfHwgZ2xvYmFsLm1velVSTDtcblxuICAgIEFWQnVmZmVyLm1ha2VCbG9iID0gZnVuY3Rpb24oZGF0YSwgdHlwZSkge1xuICAgICAgdmFyIGJiO1xuICAgICAgaWYgKHR5cGUgPT0gbnVsbCkge1xuICAgICAgICB0eXBlID0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSc7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbmV3IEJsb2IoW2RhdGFdLCB7XG4gICAgICAgICAgdHlwZTogdHlwZVxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKF9lcnJvcikge31cbiAgICAgIGlmIChCbG9iQnVpbGRlciAhPSBudWxsKSB7XG4gICAgICAgIGJiID0gbmV3IEJsb2JCdWlsZGVyO1xuICAgICAgICBiYi5hcHBlbmQoZGF0YSk7XG4gICAgICAgIHJldHVybiBiYi5nZXRCbG9iKHR5cGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLm1ha2VCbG9iVVJMID0gZnVuY3Rpb24oZGF0YSwgdHlwZSkge1xuICAgICAgcmV0dXJuIFVSTCAhPSBudWxsID8gVVJMLmNyZWF0ZU9iamVjdFVSTCh0aGlzLm1ha2VCbG9iKGRhdGEsIHR5cGUpKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgQVZCdWZmZXIucmV2b2tlQmxvYlVSTCA9IGZ1bmN0aW9uKHVybCkge1xuICAgICAgcmV0dXJuIFVSTCAhPSBudWxsID8gVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5wcm90b3R5cGUudG9CbG9iID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gQVZCdWZmZXIubWFrZUJsb2IodGhpcy5kYXRhLmJ1ZmZlcik7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnByb3RvdHlwZS50b0Jsb2JVUkwgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBBVkJ1ZmZlci5tYWtlQmxvYlVSTCh0aGlzLmRhdGEuYnVmZmVyKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEFWQnVmZmVyO1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBBVkJ1ZmZlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJ1ZmZlckxpc3Q7XG5cbiAgQnVmZmVyTGlzdCA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBCdWZmZXJMaXN0KCkge1xuICAgICAgdGhpcy5maXJzdCA9IG51bGw7XG4gICAgICB0aGlzLmxhc3QgPSBudWxsO1xuICAgICAgdGhpcy5udW1CdWZmZXJzID0gMDtcbiAgICAgIHRoaXMuYXZhaWxhYmxlQnl0ZXMgPSAwO1xuICAgICAgdGhpcy5hdmFpbGFibGVCdWZmZXJzID0gMDtcbiAgICB9XG5cbiAgICBCdWZmZXJMaXN0LnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgcmVzdWx0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICByZXN1bHQuZmlyc3QgPSB0aGlzLmZpcnN0O1xuICAgICAgcmVzdWx0Lmxhc3QgPSB0aGlzLmxhc3Q7XG4gICAgICByZXN1bHQubnVtQnVmZmVycyA9IHRoaXMubnVtQnVmZmVycztcbiAgICAgIHJlc3VsdC5hdmFpbGFibGVCeXRlcyA9IHRoaXMuYXZhaWxhYmxlQnl0ZXM7XG4gICAgICByZXN1bHQuYXZhaWxhYmxlQnVmZmVycyA9IHRoaXMuYXZhaWxhYmxlQnVmZmVycztcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIEJ1ZmZlckxpc3QucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIF9yZWY7XG4gICAgICBidWZmZXIucHJldiA9IHRoaXMubGFzdDtcbiAgICAgIGlmICgoX3JlZiA9IHRoaXMubGFzdCkgIT0gbnVsbCkge1xuICAgICAgICBfcmVmLm5leHQgPSBidWZmZXI7XG4gICAgICB9XG4gICAgICB0aGlzLmxhc3QgPSBidWZmZXI7XG4gICAgICBpZiAodGhpcy5maXJzdCA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuZmlyc3QgPSBidWZmZXI7XG4gICAgICB9XG4gICAgICB0aGlzLmF2YWlsYWJsZUJ5dGVzICs9IGJ1ZmZlci5sZW5ndGg7XG4gICAgICB0aGlzLmF2YWlsYWJsZUJ1ZmZlcnMrKztcbiAgICAgIHJldHVybiB0aGlzLm51bUJ1ZmZlcnMrKztcbiAgICB9O1xuXG4gICAgQnVmZmVyTGlzdC5wcm90b3R5cGUuYWR2YW5jZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuZmlyc3QpIHtcbiAgICAgICAgdGhpcy5hdmFpbGFibGVCeXRlcyAtPSB0aGlzLmZpcnN0Lmxlbmd0aDtcbiAgICAgICAgdGhpcy5hdmFpbGFibGVCdWZmZXJzLS07XG4gICAgICAgIHRoaXMuZmlyc3QgPSB0aGlzLmZpcnN0Lm5leHQ7XG4gICAgICAgIHJldHVybiB0aGlzLmZpcnN0ICE9IG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIEJ1ZmZlckxpc3QucHJvdG90eXBlLnJld2luZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIF9yZWY7XG4gICAgICBpZiAodGhpcy5maXJzdCAmJiAhdGhpcy5maXJzdC5wcmV2KSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZmlyc3QgPSAoKF9yZWYgPSB0aGlzLmZpcnN0KSAhPSBudWxsID8gX3JlZi5wcmV2IDogdm9pZCAwKSB8fCB0aGlzLmxhc3Q7XG4gICAgICBpZiAodGhpcy5maXJzdCkge1xuICAgICAgICB0aGlzLmF2YWlsYWJsZUJ5dGVzICs9IHRoaXMuZmlyc3QubGVuZ3RoO1xuICAgICAgICB0aGlzLmF2YWlsYWJsZUJ1ZmZlcnMrKztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmZpcnN0ICE9IG51bGw7XG4gICAgfTtcblxuICAgIEJ1ZmZlckxpc3QucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX3Jlc3VsdHM7XG4gICAgICBfcmVzdWx0cyA9IFtdO1xuICAgICAgd2hpbGUgKHRoaXMucmV3aW5kKCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gX3Jlc3VsdHM7XG4gICAgfTtcblxuICAgIHJldHVybiBCdWZmZXJMaXN0O1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBCdWZmZXJMaXN0O1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQmFzZSwgRXZlbnRFbWl0dGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIF9fc2xpY2UgPSBbXS5zbGljZTtcblxuICBCYXNlID0gcmVxdWlyZSgnLi9iYXNlJyk7XG5cbiAgRXZlbnRFbWl0dGVyID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhFdmVudEVtaXR0ZXIsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gICAgICByZXR1cm4gRXZlbnRFbWl0dGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIEV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBmdW5jdGlvbihldmVudCwgZm4pIHtcbiAgICAgIHZhciBfYmFzZTtcbiAgICAgIGlmICh0aGlzLmV2ZW50cyA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuZXZlbnRzID0ge307XG4gICAgICB9XG4gICAgICBpZiAoKF9iYXNlID0gdGhpcy5ldmVudHMpW2V2ZW50XSA9PSBudWxsKSB7XG4gICAgICAgIF9iYXNlW2V2ZW50XSA9IFtdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzW2V2ZW50XS5wdXNoKGZuKTtcbiAgICB9O1xuXG4gICAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbihldmVudCwgZm4pIHtcbiAgICAgIHZhciBldmVudHMsIGluZGV4LCBfcmVmO1xuICAgICAgaWYgKHRoaXMuZXZlbnRzID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKChfcmVmID0gdGhpcy5ldmVudHMpICE9IG51bGwgPyBfcmVmW2V2ZW50XSA6IHZvaWQgMCkge1xuICAgICAgICBpZiAoZm4gIT0gbnVsbCkge1xuICAgICAgICAgIGluZGV4ID0gdGhpcy5ldmVudHNbZXZlbnRdLmluZGV4T2YoZm4pO1xuICAgICAgICAgIGlmICh+aW5kZXgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50c1tldmVudF0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzW2V2ZW50XTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChldmVudCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBldmVudHMgPSB7fTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKSB7XG4gICAgICB2YXIgY2I7XG4gICAgICByZXR1cm4gdGhpcy5vbihldmVudCwgY2IgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy5vZmYoZXZlbnQsIGNiKTtcbiAgICAgICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYXJncywgZXZlbnQsIGZuLCBfaSwgX2xlbiwgX3JlZiwgX3JlZjE7XG4gICAgICBldmVudCA9IGFyZ3VtZW50c1swXSwgYXJncyA9IDIgPD0gYXJndW1lbnRzLmxlbmd0aCA/IF9fc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpIDogW107XG4gICAgICBpZiAoISgoX3JlZiA9IHRoaXMuZXZlbnRzKSAhPSBudWxsID8gX3JlZltldmVudF0gOiB2b2lkIDApKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIF9yZWYxID0gdGhpcy5ldmVudHNbZXZlbnRdLnNsaWNlKCk7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYxLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGZuID0gX3JlZjFbX2ldO1xuICAgICAgICBmbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcblxuICB9KShCYXNlKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyLCBCdWZmZXJMaXN0LCBTdHJlYW0sIFVuZGVyZmxvd0Vycm9yO1xuXG4gIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2J1ZmZlcmxpc3QnKTtcblxuICBBVkJ1ZmZlciA9IHJlcXVpcmUoJy4vYnVmZmVyJyk7XG5cbiAgVW5kZXJmbG93RXJyb3IgPSByZXF1aXJlKCcuL3VuZGVyZmxvdycpO1xuXG4gIFN0cmVhbSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgYnVmLCBkZWNvZGVTdHJpbmcsIGZsb2F0MzIsIGZsb2F0NjQsIGZsb2F0NjRGYWxsYmFjaywgZmxvYXQ4MCwgaW50MTYsIGludDMyLCBpbnQ4LCBuYXRpdmVFbmRpYW4sIHVpbnQxNiwgdWludDMyLCB1aW50ODtcblxuICAgIGJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcigxNik7XG5cbiAgICB1aW50OCA9IG5ldyBVaW50OEFycmF5KGJ1Zik7XG5cbiAgICBpbnQ4ID0gbmV3IEludDhBcnJheShidWYpO1xuXG4gICAgdWludDE2ID0gbmV3IFVpbnQxNkFycmF5KGJ1Zik7XG5cbiAgICBpbnQxNiA9IG5ldyBJbnQxNkFycmF5KGJ1Zik7XG5cbiAgICB1aW50MzIgPSBuZXcgVWludDMyQXJyYXkoYnVmKTtcblxuICAgIGludDMyID0gbmV3IEludDMyQXJyYXkoYnVmKTtcblxuICAgIGZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1Zik7XG5cbiAgICBpZiAodHlwZW9mIEZsb2F0NjRBcnJheSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBGbG9hdDY0QXJyYXkgIT09IG51bGwpIHtcbiAgICAgIGZsb2F0NjQgPSBuZXcgRmxvYXQ2NEFycmF5KGJ1Zik7XG4gICAgfVxuXG4gICAgbmF0aXZlRW5kaWFuID0gbmV3IFVpbnQxNkFycmF5KG5ldyBVaW50OEFycmF5KFsweDEyLCAweDM0XSkuYnVmZmVyKVswXSA9PT0gMHgzNDEyO1xuXG4gICAgZnVuY3Rpb24gU3RyZWFtKGxpc3QpIHtcbiAgICAgIHRoaXMubGlzdCA9IGxpc3Q7XG4gICAgICB0aGlzLmxvY2FsT2Zmc2V0ID0gMDtcbiAgICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICB9XG5cbiAgICBTdHJlYW0uZnJvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIGxpc3Q7XG4gICAgICBsaXN0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICBsaXN0LmFwcGVuZChidWZmZXIpO1xuICAgICAgcmV0dXJuIG5ldyBTdHJlYW0obGlzdCk7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBTdHJlYW0odGhpcy5saXN0LmNvcHkoKSk7XG4gICAgICByZXN1bHQubG9jYWxPZmZzZXQgPSB0aGlzLmxvY2FsT2Zmc2V0O1xuICAgICAgcmVzdWx0Lm9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5hdmFpbGFibGUgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgcmV0dXJuIGJ5dGVzIDw9IHRoaXMubGlzdC5hdmFpbGFibGVCeXRlcyAtIHRoaXMubG9jYWxPZmZzZXQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVtYWluaW5nQnl0ZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmxpc3QuYXZhaWxhYmxlQnl0ZXMgLSB0aGlzLmxvY2FsT2Zmc2V0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLmFkdmFuY2UgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZShieXRlcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuZGVyZmxvd0Vycm9yKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmxvY2FsT2Zmc2V0ICs9IGJ5dGVzO1xuICAgICAgdGhpcy5vZmZzZXQgKz0gYnl0ZXM7XG4gICAgICB3aGlsZSAodGhpcy5saXN0LmZpcnN0ICYmIHRoaXMubG9jYWxPZmZzZXQgPj0gdGhpcy5saXN0LmZpcnN0Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmxvY2FsT2Zmc2V0IC09IHRoaXMubGlzdC5maXJzdC5sZW5ndGg7XG4gICAgICAgIHRoaXMubGlzdC5hZHZhbmNlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZXdpbmQgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgaWYgKGJ5dGVzID4gdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuZGVyZmxvd0Vycm9yKCk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMubGlzdC5maXJzdCkge1xuICAgICAgICB0aGlzLmxpc3QucmV3aW5kKCk7XG4gICAgICAgIHRoaXMubG9jYWxPZmZzZXQgPSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2NhbE9mZnNldCAtPSBieXRlcztcbiAgICAgIHRoaXMub2Zmc2V0IC09IGJ5dGVzO1xuICAgICAgd2hpbGUgKHRoaXMubGlzdC5maXJzdC5wcmV2ICYmIHRoaXMubG9jYWxPZmZzZXQgPCAwKSB7XG4gICAgICAgIHRoaXMubGlzdC5yZXdpbmQoKTtcbiAgICAgICAgdGhpcy5sb2NhbE9mZnNldCArPSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHBvc2l0aW9uKSB7XG4gICAgICBpZiAocG9zaXRpb24gPiB0aGlzLm9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hZHZhbmNlKHBvc2l0aW9uIC0gdGhpcy5vZmZzZXQpO1xuICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbiA8IHRoaXMub2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJld2luZCh0aGlzLm9mZnNldCAtIHBvc2l0aW9uKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhO1xuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIGEgPSB0aGlzLmxpc3QuZmlyc3QuZGF0YVt0aGlzLmxvY2FsT2Zmc2V0XTtcbiAgICAgIHRoaXMubG9jYWxPZmZzZXQgKz0gMTtcbiAgICAgIHRoaXMub2Zmc2V0ICs9IDE7XG4gICAgICBpZiAodGhpcy5sb2NhbE9mZnNldCA9PT0gdGhpcy5saXN0LmZpcnN0Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmxvY2FsT2Zmc2V0ID0gMDtcbiAgICAgICAgdGhpcy5saXN0LmFkdmFuY2UoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtVSW50OCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgdmFyIGJ1ZmZlcjtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZShvZmZzZXQgKyAxKSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIG9mZnNldCA9IHRoaXMubG9jYWxPZmZzZXQgKyBvZmZzZXQ7XG4gICAgICBidWZmZXIgPSB0aGlzLmxpc3QuZmlyc3Q7XG4gICAgICB3aGlsZSAoYnVmZmVyKSB7XG4gICAgICAgIGlmIChidWZmZXIubGVuZ3RoID4gb2Zmc2V0KSB7XG4gICAgICAgICAgcmV0dXJuIGJ1ZmZlci5kYXRhW29mZnNldF07XG4gICAgICAgIH1cbiAgICAgICAgb2Zmc2V0IC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgIGJ1ZmZlciA9IGJ1ZmZlci5uZXh0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIDA7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzLCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHZhciBpLCBfaSwgX2osIF9yZWY7XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09IG51bGwpIHtcbiAgICAgICAgbGl0dGxlRW5kaWFuID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09PSBuYXRpdmVFbmRpYW4pIHtcbiAgICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IGJ5dGVzOyBpID0gX2kgKz0gMSkge1xuICAgICAgICAgIHVpbnQ4W2ldID0gdGhpcy5yZWFkVUludDgoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChpID0gX2ogPSBfcmVmID0gYnl0ZXMgLSAxOyBfaiA+PSAwOyBpID0gX2ogKz0gLTEpIHtcbiAgICAgICAgICB1aW50OFtpXSA9IHRoaXMucmVhZFVJbnQ4KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrID0gZnVuY3Rpb24oYnl0ZXMsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICB2YXIgaSwgX2ksIF9qO1xuICAgICAgaWYgKGxpdHRsZUVuZGlhbiA9PSBudWxsKSB7XG4gICAgICAgIGxpdHRsZUVuZGlhbiA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKGxpdHRsZUVuZGlhbiA9PT0gbmF0aXZlRW5kaWFuKSB7XG4gICAgICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCBieXRlczsgaSA9IF9pICs9IDEpIHtcbiAgICAgICAgICB1aW50OFtpXSA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCArIGkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgPSBfaiA9IDA7IF9qIDwgYnl0ZXM7IGkgPSBfaiArPSAxKSB7XG4gICAgICAgICAgdWludDhbYnl0ZXMgLSBpIC0gMV0gPSB0aGlzLnBlZWtVSW50OChvZmZzZXQgKyBpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnJlYWQoMSk7XG4gICAgICByZXR1cm4gaW50OFswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrSW50OCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoMSwgb2Zmc2V0KTtcbiAgICAgIHJldHVybiBpbnQ4WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRVSW50MTYgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCgyLCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIHVpbnQxNlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrVUludDE2ID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDIsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiB1aW50MTZbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEludDE2ID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoMiwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBpbnQxNlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrSW50MTYgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoMiwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGludDE2WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRVSW50MjQgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChsaXR0bGVFbmRpYW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZFVJbnQxNih0cnVlKSArICh0aGlzLnJlYWRVSW50OCgpIDw8IDE2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAodGhpcy5yZWFkVUludDE2KCkgPDwgOCkgKyB0aGlzLnJlYWRVSW50OCgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtVSW50MjQgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBlZWtVSW50MTYob2Zmc2V0LCB0cnVlKSArICh0aGlzLnBlZWtVSW50OChvZmZzZXQgKyAyKSA8PCAxNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gKHRoaXMucGVla1VJbnQxNihvZmZzZXQpIDw8IDgpICsgdGhpcy5wZWVrVUludDgob2Zmc2V0ICsgMik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEludDI0ID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRVSW50MTYodHJ1ZSkgKyAodGhpcy5yZWFkSW50OCgpIDw8IDE2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAodGhpcy5yZWFkSW50MTYoKSA8PCA4KSArIHRoaXMucmVhZFVJbnQ4KCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0ludDI0ID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgICAgICByZXR1cm4gdGhpcy5wZWVrVUludDE2KG9mZnNldCwgdHJ1ZSkgKyAodGhpcy5wZWVrSW50OChvZmZzZXQgKyAyKSA8PCAxNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gKHRoaXMucGVla0ludDE2KG9mZnNldCkgPDwgOCkgKyB0aGlzLnBlZWtVSW50OChvZmZzZXQgKyAyKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkVUludDMyID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoNCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiB1aW50MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1VJbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlayg0LCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gdWludDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRJbnQzMiA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gaW50MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0ludDMyID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDQsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBpbnQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkRmxvYXQzMiA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gZmxvYXQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrRmxvYXQzMiA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlayg0LCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gZmxvYXQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkRmxvYXQ2NCA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDgsIGxpdHRsZUVuZGlhbik7XG4gICAgICBpZiAoZmxvYXQ2NCkge1xuICAgICAgICByZXR1cm4gZmxvYXQ2NFswXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmbG9hdDY0RmFsbGJhY2soKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZmxvYXQ2NEZhbGxiYWNrID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZXhwLCBmcmFjLCBoaWdoLCBsb3csIG91dCwgc2lnbjtcbiAgICAgIGxvdyA9IHVpbnQzMlswXSwgaGlnaCA9IHVpbnQzMlsxXTtcbiAgICAgIGlmICghaGlnaCB8fCBoaWdoID09PSAweDgwMDAwMDAwKSB7XG4gICAgICAgIHJldHVybiAwLjA7XG4gICAgICB9XG4gICAgICBzaWduID0gMSAtIChoaWdoID4+PiAzMSkgKiAyO1xuICAgICAgZXhwID0gKGhpZ2ggPj4+IDIwKSAmIDB4N2ZmO1xuICAgICAgZnJhYyA9IGhpZ2ggJiAweGZmZmZmO1xuICAgICAgaWYgKGV4cCA9PT0gMHg3ZmYpIHtcbiAgICAgICAgaWYgKGZyYWMpIHtcbiAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzaWduICogSW5maW5pdHk7XG4gICAgICB9XG4gICAgICBleHAgLT0gMTAyMztcbiAgICAgIG91dCA9IChmcmFjIHwgMHgxMDAwMDApICogTWF0aC5wb3coMiwgZXhwIC0gMjApO1xuICAgICAgb3V0ICs9IGxvdyAqIE1hdGgucG93KDIsIGV4cCAtIDUyKTtcbiAgICAgIHJldHVybiBzaWduICogb3V0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtGbG9hdDY0ID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDgsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIGlmIChmbG9hdDY0KSB7XG4gICAgICAgIHJldHVybiBmbG9hdDY0WzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZsb2F0NjRGYWxsYmFjaygpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRGbG9hdDgwID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoMTAsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gZmxvYXQ4MCgpO1xuICAgIH07XG5cbiAgICBmbG9hdDgwID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYTAsIGExLCBleHAsIGhpZ2gsIGxvdywgb3V0LCBzaWduO1xuICAgICAgaGlnaCA9IHVpbnQzMlswXSwgbG93ID0gdWludDMyWzFdO1xuICAgICAgYTAgPSB1aW50OFs5XTtcbiAgICAgIGExID0gdWludDhbOF07XG4gICAgICBzaWduID0gMSAtIChhMCA+Pj4gNykgKiAyO1xuICAgICAgZXhwID0gKChhMCAmIDB4N0YpIDw8IDgpIHwgYTE7XG4gICAgICBpZiAoZXhwID09PSAwICYmIGxvdyA9PT0gMCAmJiBoaWdoID09PSAwKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgICAgaWYgKGV4cCA9PT0gMHg3ZmZmKSB7XG4gICAgICAgIGlmIChsb3cgPT09IDAgJiYgaGlnaCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBzaWduICogSW5maW5pdHk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE5hTjtcbiAgICAgIH1cbiAgICAgIGV4cCAtPSAxNjM4MztcbiAgICAgIG91dCA9IGxvdyAqIE1hdGgucG93KDIsIGV4cCAtIDMxKTtcbiAgICAgIG91dCArPSBoaWdoICogTWF0aC5wb3coMiwgZXhwIC0gNjMpO1xuICAgICAgcmV0dXJuIHNpZ24gKiBvdXQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0Zsb2F0ODAgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoMTAsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBmbG9hdDgwKCk7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEJ1ZmZlciA9IGZ1bmN0aW9uKGxlbmd0aCkge1xuICAgICAgdmFyIGksIHJlc3VsdCwgdG8sIF9pO1xuICAgICAgcmVzdWx0ID0gQVZCdWZmZXIuYWxsb2NhdGUobGVuZ3RoKTtcbiAgICAgIHRvID0gcmVzdWx0LmRhdGE7XG4gICAgICBmb3IgKGkgPSBfaSA9IDA7IF9pIDwgbGVuZ3RoOyBpID0gX2kgKz0gMSkge1xuICAgICAgICB0b1tpXSA9IHRoaXMucmVhZFVJbnQ4KCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtCdWZmZXIgPSBmdW5jdGlvbihvZmZzZXQsIGxlbmd0aCkge1xuICAgICAgdmFyIGksIHJlc3VsdCwgdG8sIF9pO1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBBVkJ1ZmZlci5hbGxvY2F0ZShsZW5ndGgpO1xuICAgICAgdG8gPSByZXN1bHQuZGF0YTtcbiAgICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCBsZW5ndGg7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgIHRvW2ldID0gdGhpcy5wZWVrVUludDgob2Zmc2V0ICsgaSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRTaW5nbGVCdWZmZXIgPSBmdW5jdGlvbihsZW5ndGgpIHtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICByZXN1bHQgPSB0aGlzLmxpc3QuZmlyc3Quc2xpY2UodGhpcy5sb2NhbE9mZnNldCwgbGVuZ3RoKTtcbiAgICAgIHRoaXMuYWR2YW5jZShyZXN1bHQubGVuZ3RoKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1NpbmdsZUJ1ZmZlciA9IGZ1bmN0aW9uKG9mZnNldCwgbGVuZ3RoKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgcmVzdWx0ID0gdGhpcy5saXN0LmZpcnN0LnNsaWNlKHRoaXMubG9jYWxPZmZzZXQgKyBvZmZzZXQsIGxlbmd0aCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRTdHJpbmcgPSBmdW5jdGlvbihsZW5ndGgsIGVuY29kaW5nKSB7XG4gICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkge1xuICAgICAgICBlbmNvZGluZyA9ICdhc2NpaSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGVjb2RlU3RyaW5nLmNhbGwodGhpcywgMCwgbGVuZ3RoLCBlbmNvZGluZywgdHJ1ZSk7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1N0cmluZyA9IGZ1bmN0aW9uKG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkge1xuICAgICAgICBlbmNvZGluZyA9ICdhc2NpaSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGVjb2RlU3RyaW5nLmNhbGwodGhpcywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nLCBmYWxzZSk7XG4gICAgfTtcblxuICAgIGRlY29kZVN0cmluZyA9IGZ1bmN0aW9uKG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZywgYWR2YW5jZSkge1xuICAgICAgdmFyIGIxLCBiMiwgYjMsIGI0LCBib20sIGMsIGVuZCwgbGl0dGxlRW5kaWFuLCBudWxsRW5kLCBwdCwgcmVzdWx0LCB3MSwgdzI7XG4gICAgICBlbmNvZGluZyA9IGVuY29kaW5nLnRvTG93ZXJDYXNlKCk7XG4gICAgICBudWxsRW5kID0gbGVuZ3RoID09PSBudWxsID8gMCA6IC0xO1xuICAgICAgaWYgKGxlbmd0aCA9PSBudWxsKSB7XG4gICAgICAgIGxlbmd0aCA9IEluZmluaXR5O1xuICAgICAgfVxuICAgICAgZW5kID0gb2Zmc2V0ICsgbGVuZ3RoO1xuICAgICAgcmVzdWx0ID0gJyc7XG4gICAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgZW5kICYmIChjID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspKSAhPT0gbnVsbEVuZCkge1xuICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd1dGY4JzpcbiAgICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICAgIHdoaWxlIChvZmZzZXQgPCBlbmQgJiYgKGIxID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspKSAhPT0gbnVsbEVuZCkge1xuICAgICAgICAgICAgaWYgKChiMSAmIDB4ODApID09PSAwKSB7XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGIxKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGIxICYgMHhlMCkgPT09IDB4YzApIHtcbiAgICAgICAgICAgICAgYjIgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGIxICYgMHgxZikgPDwgNikgfCBiMik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChiMSAmIDB4ZjApID09PSAweGUwKSB7XG4gICAgICAgICAgICAgIGIyID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgYjMgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGIxICYgMHgwZikgPDwgMTIpIHwgKGIyIDw8IDYpIHwgYjMpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoYjEgJiAweGY4KSA9PT0gMHhmMCkge1xuICAgICAgICAgICAgICBiMiA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIGIzID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgYjQgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICBwdCA9ICgoKGIxICYgMHgwZikgPDwgMTgpIHwgKGIyIDw8IDEyKSB8IChiMyA8PCA2KSB8IGI0KSAtIDB4MTAwMDA7XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ZDgwMCArIChwdCA+PiAxMCksIDB4ZGMwMCArIChwdCAmIDB4M2ZmKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd1dGYxNi1iZSc6XG4gICAgICAgIGNhc2UgJ3V0ZjE2YmUnOlxuICAgICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgICAgY2FzZSAndXRmMTYtbGUnOlxuICAgICAgICBjYXNlICd1dGYxNmJvbSc6XG4gICAgICAgIGNhc2UgJ3V0ZjE2LWJvbSc6XG4gICAgICAgICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgICAgICAgY2FzZSAndXRmMTZiZSc6XG4gICAgICAgICAgICBjYXNlICd1dGYxNi1iZSc6XG4gICAgICAgICAgICAgIGxpdHRsZUVuZGlhbiA9IGZhbHNlO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgICAgICAgY2FzZSAndXRmMTYtbGUnOlxuICAgICAgICAgICAgICBsaXR0bGVFbmRpYW4gPSB0cnVlO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2Ym9tJzpcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2LWJvbSc6XG4gICAgICAgICAgICAgIGlmIChsZW5ndGggPCAyIHx8IChib20gPSB0aGlzLnBlZWtVSW50MTYob2Zmc2V0KSkgPT09IG51bGxFbmQpIHtcbiAgICAgICAgICAgICAgICBpZiAoYWR2YW5jZSkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5hZHZhbmNlKG9mZnNldCArPSAyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsaXR0bGVFbmRpYW4gPSBib20gPT09IDB4ZmZmZTtcbiAgICAgICAgICAgICAgb2Zmc2V0ICs9IDI7XG4gICAgICAgICAgfVxuICAgICAgICAgIHdoaWxlIChvZmZzZXQgPCBlbmQgJiYgKHcxID0gdGhpcy5wZWVrVUludDE2KG9mZnNldCwgbGl0dGxlRW5kaWFuKSkgIT09IG51bGxFbmQpIHtcbiAgICAgICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICAgICAgaWYgKHcxIDwgMHhkODAwIHx8IHcxID4gMHhkZmZmKSB7XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHcxKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICh3MSA+IDB4ZGJmZikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdXRmMTYgc2VxdWVuY2UuXCIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHcyID0gdGhpcy5wZWVrVUludDE2KG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgICAgaWYgKHcyIDwgMHhkYzAwIHx8IHcyID4gMHhkZmZmKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB1dGYxNiBzZXF1ZW5jZS5cIik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodzEsIHcyKTtcbiAgICAgICAgICAgICAgb2Zmc2V0ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh3MSA9PT0gbnVsbEVuZCkge1xuICAgICAgICAgICAgb2Zmc2V0ICs9IDI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiICsgZW5jb2RpbmcpO1xuICAgICAgfVxuICAgICAgaWYgKGFkdmFuY2UpIHtcbiAgICAgICAgdGhpcy5hZHZhbmNlKG9mZnNldCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICByZXR1cm4gU3RyZWFtO1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBVbmRlcmZsb3dFcnJvcixcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBVbmRlcmZsb3dFcnJvciA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVW5kZXJmbG93RXJyb3IsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBVbmRlcmZsb3dFcnJvcigpIHtcbiAgICAgIFVuZGVyZmxvd0Vycm9yLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgdGhpcy5uYW1lID0gJ1VuZGVyZmxvd0Vycm9yJztcbiAgICAgIHRoaXMuc3RhY2sgPSBuZXcgRXJyb3IoKS5zdGFjaztcbiAgICB9XG5cbiAgICByZXR1cm4gVW5kZXJmbG93RXJyb3I7XG5cbiAgfSkoRXJyb3IpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gVW5kZXJmbG93RXJyb3I7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBCaXRzdHJlYW0sIEJ1ZmZlckxpc3QsIERlY29kZXIsIEV2ZW50RW1pdHRlciwgU3RyZWFtLCBVbmRlcmZsb3dFcnJvcixcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgU3RyZWFtID0gcmVxdWlyZSgnLi9jb3JlL3N0cmVhbScpO1xuXG4gIEJpdHN0cmVhbSA9IHJlcXVpcmUoJy4vY29yZS9iaXRzdHJlYW0nKTtcblxuICBVbmRlcmZsb3dFcnJvciA9IHJlcXVpcmUoJy4vY29yZS91bmRlcmZsb3cnKTtcblxuICBEZWNvZGVyID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIHZhciBjb2RlY3M7XG5cbiAgICBfX2V4dGVuZHMoRGVjb2RlciwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIERlY29kZXIoZGVtdXhlciwgZm9ybWF0KSB7XG4gICAgICB2YXIgbGlzdDtcbiAgICAgIHRoaXMuZGVtdXhlciA9IGRlbXV4ZXI7XG4gICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICAgIGxpc3QgPSBuZXcgQnVmZmVyTGlzdDtcbiAgICAgIHRoaXMuc3RyZWFtID0gbmV3IFN0cmVhbShsaXN0KTtcbiAgICAgIHRoaXMuYml0c3RyZWFtID0gbmV3IEJpdHN0cmVhbSh0aGlzLnN0cmVhbSk7XG4gICAgICB0aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIgPSBmYWxzZTtcbiAgICAgIHRoaXMud2FpdGluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdjb29raWUnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvb2tpZSkge1xuICAgICAgICAgIHZhciBlcnJvcjtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLnNldENvb2tpZShjb29raWUpO1xuICAgICAgICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBfZXJyb3I7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihjaHVuaykge1xuICAgICAgICAgIGxpc3QuYXBwZW5kKGNodW5rKTtcbiAgICAgICAgICBpZiAoX3RoaXMud2FpdGluZykge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmRlY29kZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuZGVtdXhlci5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBfdGhpcy5yZWNlaXZlZEZpbmFsQnVmZmVyID0gdHJ1ZTtcbiAgICAgICAgICBpZiAoX3RoaXMud2FpdGluZykge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmRlY29kZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cblxuICAgIERlY29kZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHt9O1xuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUuc2V0Q29va2llID0gZnVuY3Rpb24oY29va2llKSB7fTtcblxuICAgIERlY29kZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge307XG5cbiAgICBEZWNvZGVyLnByb3RvdHlwZS5kZWNvZGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBlcnJvciwgb2Zmc2V0LCBwYWNrZXQ7XG4gICAgICB0aGlzLndhaXRpbmcgPSAhdGhpcy5yZWNlaXZlZEZpbmFsQnVmZmVyO1xuICAgICAgb2Zmc2V0ID0gdGhpcy5iaXRzdHJlYW0ub2Zmc2V0KCk7XG4gICAgICB0cnkge1xuICAgICAgICBwYWNrZXQgPSB0aGlzLnJlYWRDaHVuaygpO1xuICAgICAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgICAgIGVycm9yID0gX2Vycm9yO1xuICAgICAgICBpZiAoIShlcnJvciBpbnN0YW5jZW9mIFVuZGVyZmxvd0Vycm9yKSkge1xuICAgICAgICAgIHRoaXMuZW1pdCgnZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAocGFja2V0KSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIHBhY2tldCk7XG4gICAgICAgIGlmICh0aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIpIHtcbiAgICAgICAgICB0aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIGlmICghdGhpcy5yZWNlaXZlZEZpbmFsQnVmZmVyKSB7XG4gICAgICAgIHRoaXMuYml0c3RyZWFtLnNlZWsob2Zmc2V0KTtcbiAgICAgICAgdGhpcy53YWl0aW5nID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZW5kJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIERlY29kZXIucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbih0aW1lc3RhbXApIHtcbiAgICAgIHZhciBzZWVrUG9pbnQ7XG4gICAgICBzZWVrUG9pbnQgPSB0aGlzLmRlbXV4ZXIuc2Vlayh0aW1lc3RhbXApO1xuICAgICAgdGhpcy5zdHJlYW0uc2VlayhzZWVrUG9pbnQub2Zmc2V0KTtcbiAgICAgIHJldHVybiBzZWVrUG9pbnQudGltZXN0YW1wO1xuICAgIH07XG5cbiAgICBjb2RlY3MgPSB7fTtcblxuICAgIERlY29kZXIucmVnaXN0ZXIgPSBmdW5jdGlvbihpZCwgZGVjb2Rlcikge1xuICAgICAgcmV0dXJuIGNvZGVjc1tpZF0gPSBkZWNvZGVyO1xuICAgIH07XG5cbiAgICBEZWNvZGVyLmZpbmQgPSBmdW5jdGlvbihpZCkge1xuICAgICAgcmV0dXJuIGNvZGVjc1tpZF0gfHwgbnVsbDtcbiAgICB9O1xuXG4gICAgcmV0dXJuIERlY29kZXI7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IERlY29kZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZWNvZGVyLCBMUENNRGVjb2RlcixcbiAgICBfX2JpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIERlY29kZXIgPSByZXF1aXJlKCcuLi9kZWNvZGVyJyk7XG5cbiAgTFBDTURlY29kZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKExQQ01EZWNvZGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gTFBDTURlY29kZXIoKSB7XG4gICAgICB0aGlzLnJlYWRDaHVuayA9IF9fYmluZCh0aGlzLnJlYWRDaHVuaywgdGhpcyk7XG4gICAgICByZXR1cm4gTFBDTURlY29kZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5yZWdpc3RlcignbHBjbScsIExQQ01EZWNvZGVyKTtcblxuICAgIExQQ01EZWNvZGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjaHVua1NpemUsIGksIGxpdHRsZUVuZGlhbiwgb3V0cHV0LCBzYW1wbGVzLCBzdHJlYW0sIF9pLCBfaiwgX2ssIF9sLCBfbSwgX247XG4gICAgICBzdHJlYW0gPSB0aGlzLnN0cmVhbTtcbiAgICAgIGxpdHRsZUVuZGlhbiA9IHRoaXMuZm9ybWF0LmxpdHRsZUVuZGlhbjtcbiAgICAgIGNodW5rU2l6ZSA9IE1hdGgubWluKDQwOTYsIHN0cmVhbS5yZW1haW5pbmdCeXRlcygpKTtcbiAgICAgIHNhbXBsZXMgPSBjaHVua1NpemUgLyAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4KSB8IDA7XG4gICAgICBpZiAoY2h1bmtTaXplIDwgdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuZm9ybWF0LmZsb2F0aW5nUG9pbnQpIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCkge1xuICAgICAgICAgIGNhc2UgMzI6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgRmxvYXQzMkFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IHNhbXBsZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkRmxvYXQzMihsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSA2NDpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBGbG9hdDY0QXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBfaiA9IDA7IF9qIDwgc2FtcGxlczsgaSA9IF9qICs9IDEpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W2ldID0gc3RyZWFtLnJlYWRGbG9hdDY0KGxpdHRsZUVuZGlhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBiaXQgZGVwdGguJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwpIHtcbiAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgSW50OEFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gX2sgPSAwOyBfayA8IHNhbXBsZXM7IGkgPSBfayArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkSW50OCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAxNjpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBJbnQxNkFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gX2wgPSAwOyBfbCA8IHNhbXBsZXM7IGkgPSBfbCArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkSW50MTYobGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgMjQ6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgSW50MzJBcnJheShzYW1wbGVzKTtcbiAgICAgICAgICAgIGZvciAoaSA9IF9tID0gMDsgX20gPCBzYW1wbGVzOyBpID0gX20gKz0gMSkge1xuICAgICAgICAgICAgICBvdXRwdXRbaV0gPSBzdHJlYW0ucmVhZEludDI0KGxpdHRsZUVuZGlhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIDMyOlxuICAgICAgICAgICAgb3V0cHV0ID0gbmV3IEludDMyQXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBfbiA9IDA7IF9uIDwgc2FtcGxlczsgaSA9IF9uICs9IDEpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W2ldID0gc3RyZWFtLnJlYWRJbnQzMihsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgYml0IGRlcHRoLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG5cbiAgICByZXR1cm4gTFBDTURlY29kZXI7XG5cbiAgfSkoRGVjb2Rlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZWNvZGVyLCBYTEFXRGVjb2RlcixcbiAgICBfX2JpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIERlY29kZXIgPSByZXF1aXJlKCcuLi9kZWNvZGVyJyk7XG5cbiAgWExBV0RlY29kZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgdmFyIEJJQVMsIFFVQU5UX01BU0ssIFNFR19NQVNLLCBTRUdfU0hJRlQsIFNJR05fQklUO1xuXG4gICAgX19leHRlbmRzKFhMQVdEZWNvZGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gWExBV0RlY29kZXIoKSB7XG4gICAgICB0aGlzLnJlYWRDaHVuayA9IF9fYmluZCh0aGlzLnJlYWRDaHVuaywgdGhpcyk7XG4gICAgICByZXR1cm4gWExBV0RlY29kZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5yZWdpc3RlcigndWxhdycsIFhMQVdEZWNvZGVyKTtcblxuICAgIERlY29kZXIucmVnaXN0ZXIoJ2FsYXcnLCBYTEFXRGVjb2Rlcik7XG5cbiAgICBTSUdOX0JJVCA9IDB4ODA7XG5cbiAgICBRVUFOVF9NQVNLID0gMHhmO1xuXG4gICAgU0VHX1NISUZUID0gNDtcblxuICAgIFNFR19NQVNLID0gMHg3MDtcblxuICAgIEJJQVMgPSAweDg0O1xuXG4gICAgWExBV0RlY29kZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBpLCBzZWcsIHQsIHRhYmxlLCB2YWwsIF9pLCBfajtcbiAgICAgIHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gMTY7XG4gICAgICB0aGlzLnRhYmxlID0gdGFibGUgPSBuZXcgSW50MTZBcnJheSgyNTYpO1xuICAgICAgaWYgKHRoaXMuZm9ybWF0LmZvcm1hdElEID09PSAndWxhdycpIHtcbiAgICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IDI1NjsgaSA9ICsrX2kpIHtcbiAgICAgICAgICB2YWwgPSB+aTtcbiAgICAgICAgICB0ID0gKCh2YWwgJiBRVUFOVF9NQVNLKSA8PCAzKSArIEJJQVM7XG4gICAgICAgICAgdCA8PD0gKHZhbCAmIFNFR19NQVNLKSA+Pj4gU0VHX1NISUZUO1xuICAgICAgICAgIHRhYmxlW2ldID0gdmFsICYgU0lHTl9CSVQgPyBCSUFTIC0gdCA6IHQgLSBCSUFTO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgPSBfaiA9IDA7IF9qIDwgMjU2OyBpID0gKytfaikge1xuICAgICAgICAgIHZhbCA9IGkgXiAweDU1O1xuICAgICAgICAgIHQgPSB2YWwgJiBRVUFOVF9NQVNLO1xuICAgICAgICAgIHNlZyA9ICh2YWwgJiBTRUdfTUFTSykgPj4+IFNFR19TSElGVDtcbiAgICAgICAgICBpZiAoc2VnKSB7XG4gICAgICAgICAgICB0ID0gKHQgKyB0ICsgMSArIDMyKSA8PCAoc2VnICsgMik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHQgPSAodCArIHQgKyAxKSA8PCAzO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0YWJsZVtpXSA9IHZhbCAmIFNJR05fQklUID8gdCA6IC10O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIFhMQVdEZWNvZGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBpLCBvdXRwdXQsIHNhbXBsZXMsIHN0cmVhbSwgdGFibGUsIF9pO1xuICAgICAgc3RyZWFtID0gdGhpcy5zdHJlYW0sIHRhYmxlID0gdGhpcy50YWJsZTtcbiAgICAgIHNhbXBsZXMgPSBNYXRoLm1pbig0MDk2LCB0aGlzLnN0cmVhbS5yZW1haW5pbmdCeXRlcygpKTtcbiAgICAgIGlmIChzYW1wbGVzID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIG91dHB1dCA9IG5ldyBJbnQxNkFycmF5KHNhbXBsZXMpO1xuICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IHNhbXBsZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgIG91dHB1dFtpXSA9IHRhYmxlW3N0cmVhbS5yZWFkVUludDgoKV07XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG5cbiAgICByZXR1cm4gWExBV0RlY29kZXI7XG5cbiAgfSkoRGVjb2Rlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBCdWZmZXJMaXN0LCBEZW11eGVyLCBFdmVudEVtaXR0ZXIsIFN0cmVhbSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgU3RyZWFtID0gcmVxdWlyZSgnLi9jb3JlL3N0cmVhbScpO1xuXG4gIERlbXV4ZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgdmFyIGZvcm1hdHM7XG5cbiAgICBfX2V4dGVuZHMoRGVtdXhlciwgX3N1cGVyKTtcblxuICAgIERlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gRGVtdXhlcihzb3VyY2UsIGNodW5rKSB7XG4gICAgICB2YXIgbGlzdCwgcmVjZWl2ZWQ7XG4gICAgICBsaXN0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICBsaXN0LmFwcGVuZChjaHVuayk7XG4gICAgICB0aGlzLnN0cmVhbSA9IG5ldyBTdHJlYW0obGlzdCk7XG4gICAgICByZWNlaXZlZCA9IGZhbHNlO1xuICAgICAgc291cmNlLm9uKCdkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihjaHVuaykge1xuICAgICAgICAgIHZhciBlO1xuICAgICAgICAgIHJlY2VpdmVkID0gdHJ1ZTtcbiAgICAgICAgICBsaXN0LmFwcGVuZChjaHVuayk7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5yZWFkQ2h1bmsoY2h1bmspO1xuICAgICAgICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgICAgICAgZSA9IF9lcnJvcjtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlcnJvcicsIGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHNvdXJjZS5vbignZXJyb3InLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICBzb3VyY2Uub24oJ2VuZCcsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKCFyZWNlaXZlZCkge1xuICAgICAgICAgICAgX3RoaXMucmVhZENodW5rKGNodW5rKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5zZWVrUG9pbnRzID0gW107XG4gICAgICB0aGlzLmluaXQoKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24oKSB7fTtcblxuICAgIERlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKGNodW5rKSB7fTtcblxuICAgIERlbXV4ZXIucHJvdG90eXBlLmFkZFNlZWtQb2ludCA9IGZ1bmN0aW9uKG9mZnNldCwgdGltZXN0YW1wKSB7XG4gICAgICB2YXIgaW5kZXg7XG4gICAgICBpbmRleCA9IHRoaXMuc2VhcmNoVGltZXN0YW1wKHRpbWVzdGFtcCk7XG4gICAgICByZXR1cm4gdGhpcy5zZWVrUG9pbnRzLnNwbGljZShpbmRleCwgMCwge1xuICAgICAgICBvZmZzZXQ6IG9mZnNldCxcbiAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXBcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBEZW11eGVyLnByb3RvdHlwZS5zZWFyY2hUaW1lc3RhbXAgPSBmdW5jdGlvbih0aW1lc3RhbXAsIGJhY2t3YXJkKSB7XG4gICAgICB2YXIgaGlnaCwgbG93LCBtaWQsIHRpbWU7XG4gICAgICBsb3cgPSAwO1xuICAgICAgaGlnaCA9IHRoaXMuc2Vla1BvaW50cy5sZW5ndGg7XG4gICAgICBpZiAoaGlnaCA+IDAgJiYgdGhpcy5zZWVrUG9pbnRzW2hpZ2ggLSAxXS50aW1lc3RhbXAgPCB0aW1lc3RhbXApIHtcbiAgICAgICAgcmV0dXJuIGhpZ2g7XG4gICAgICB9XG4gICAgICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgICAgICBtaWQgPSAobG93ICsgaGlnaCkgPj4gMTtcbiAgICAgICAgdGltZSA9IHRoaXMuc2Vla1BvaW50c1ttaWRdLnRpbWVzdGFtcDtcbiAgICAgICAgaWYgKHRpbWUgPCB0aW1lc3RhbXApIHtcbiAgICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgICB9IGVsc2UgaWYgKHRpbWUgPj0gdGltZXN0YW1wKSB7XG4gICAgICAgICAgaGlnaCA9IG1pZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGhpZ2ggPiB0aGlzLnNlZWtQb2ludHMubGVuZ3RoKSB7XG4gICAgICAgIGhpZ2ggPSB0aGlzLnNlZWtQb2ludHMubGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhpZ2g7XG4gICAgfTtcblxuICAgIERlbXV4ZXIucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbih0aW1lc3RhbXApIHtcbiAgICAgIHZhciBpbmRleCwgc2Vla1BvaW50O1xuICAgICAgaWYgKHRoaXMuZm9ybWF0ICYmIHRoaXMuZm9ybWF0LmZyYW1lc1BlclBhY2tldCA+IDAgJiYgdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgPiAwKSB7XG4gICAgICAgIHNlZWtQb2ludCA9IHtcbiAgICAgICAgICB0aW1lc3RhbXA6IHRpbWVzdGFtcCxcbiAgICAgICAgICBvZmZzZXQ6IHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ICogdGltZXN0YW1wIC8gdGhpcy5mb3JtYXQuZnJhbWVzUGVyUGFja2V0XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBzZWVrUG9pbnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbmRleCA9IHRoaXMuc2VhcmNoVGltZXN0YW1wKHRpbWVzdGFtcCk7XG4gICAgICAgIHJldHVybiB0aGlzLnNlZWtQb2ludHNbaW5kZXhdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3JtYXRzID0gW107XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyID0gZnVuY3Rpb24oZGVtdXhlcikge1xuICAgICAgcmV0dXJuIGZvcm1hdHMucHVzaChkZW11eGVyKTtcbiAgICB9O1xuXG4gICAgRGVtdXhlci5maW5kID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgZSwgZm9ybWF0LCBvZmZzZXQsIHN0cmVhbSwgX2ksIF9sZW47XG4gICAgICBzdHJlYW0gPSBTdHJlYW0uZnJvbUJ1ZmZlcihidWZmZXIpO1xuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBmb3JtYXRzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGZvcm1hdCA9IGZvcm1hdHNbX2ldO1xuICAgICAgICBvZmZzZXQgPSBzdHJlYW0ub2Zmc2V0O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChmb3JtYXQucHJvYmUoc3RyZWFtKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgICAgIGUgPSBfZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgc3RyZWFtLnNlZWsob2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICByZXR1cm4gRGVtdXhlcjtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gRGVtdXhlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFJRkZEZW11eGVyLCBEZW11eGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgQUlGRkRlbXV4ZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKEFJRkZEZW11eGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gQUlGRkRlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gQUlGRkRlbXV4ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVtdXhlci5yZWdpc3RlcihBSUZGRGVtdXhlcik7XG5cbiAgICBBSUZGRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIF9yZWY7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoMCwgNCkgPT09ICdGT1JNJyAmJiAoKF9yZWYgPSBidWZmZXIucGVla1N0cmluZyg4LCA0KSkgPT09ICdBSUZGJyB8fCBfcmVmID09PSAnQUlGQycpO1xuICAgIH07XG5cbiAgICBBSUZGRGVtdXhlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYnVmZmVyLCBmb3JtYXQsIG9mZnNldCwgX3JlZjtcbiAgICAgIGlmICghdGhpcy5yZWFkU3RhcnQgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEyKSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ0ZPUk0nKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBSUZGLicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlsZVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZmlsZVR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICB0aGlzLnJlYWRTdGFydCA9IHRydWU7XG4gICAgICAgIGlmICgoX3JlZiA9IHRoaXMuZmlsZVR5cGUpICE9PSAnQUlGRicgJiYgX3JlZiAhPT0gJ0FJRkMnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBSUZGLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIGlmICghdGhpcy5yZWFkSGVhZGVycyAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgIHRoaXMubGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICAgICAgY2FzZSAnQ09NTSc6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgICAgIGZvcm1hdElEOiAnbHBjbScsXG4gICAgICAgICAgICAgIGNoYW5uZWxzUGVyRnJhbWU6IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSxcbiAgICAgICAgICAgICAgc2FtcGxlQ291bnQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICAgICAgYml0c1BlckNoYW5uZWw6IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSxcbiAgICAgICAgICAgICAgc2FtcGxlUmF0ZTogdGhpcy5zdHJlYW0ucmVhZEZsb2F0ODAoKSxcbiAgICAgICAgICAgICAgZnJhbWVzUGVyUGFja2V0OiAxLFxuICAgICAgICAgICAgICBsaXR0bGVFbmRpYW46IGZhbHNlLFxuICAgICAgICAgICAgICBmbG9hdGluZ1BvaW50OiBmYWxzZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ID0gKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkgKiB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lO1xuICAgICAgICAgICAgaWYgKHRoaXMuZmlsZVR5cGUgPT09ICdBSUZDJykge1xuICAgICAgICAgICAgICBmb3JtYXQgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgICAgICB0aGlzLmZvcm1hdC5saXR0bGVFbmRpYW4gPSBmb3JtYXQgPT09ICdzb3d0JyAmJiB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA+IDg7XG4gICAgICAgICAgICAgIHRoaXMuZm9ybWF0LmZsb2F0aW5nUG9pbnQgPSBmb3JtYXQgPT09ICdmbDMyJyB8fCBmb3JtYXQgPT09ICdmbDY0JztcbiAgICAgICAgICAgICAgaWYgKGZvcm1hdCA9PT0gJ3R3b3MnIHx8IGZvcm1hdCA9PT0gJ3Nvd3QnIHx8IGZvcm1hdCA9PT0gJ2ZsMzInIHx8IGZvcm1hdCA9PT0gJ2ZsNjQnIHx8IGZvcm1hdCA9PT0gJ05PTkUnKSB7XG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gJ2xwY20nO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMuZm9ybWF0LmZvcm1hdElEID0gZm9ybWF0O1xuICAgICAgICAgICAgICB0aGlzLmxlbiAtPSA0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDE4KTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy5mb3JtYXQpO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMuZm9ybWF0LnNhbXBsZUNvdW50IC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ1NTTkQnOlxuICAgICAgICAgICAgaWYgKCEodGhpcy5yZWFkU1NOREhlYWRlciAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoNCkpKSB7XG4gICAgICAgICAgICAgIG9mZnNldCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZShvZmZzZXQpO1xuICAgICAgICAgICAgICB0aGlzLnJlYWRTU05ESGVhZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJ1ZmZlciA9IHRoaXMuc3RyZWFtLnJlYWRTaW5nbGVCdWZmZXIodGhpcy5sZW4pO1xuICAgICAgICAgICAgdGhpcy5sZW4gLT0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSB0aGlzLmxlbiA+IDA7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBidWZmZXIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMubGVuKSkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy50eXBlICE9PSAnU1NORCcpIHtcbiAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIEFJRkZEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQVVEZW11eGVyLCBEZW11eGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgQVVEZW11eGVyID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIHZhciBicHMsIGZvcm1hdHM7XG5cbiAgICBfX2V4dGVuZHMoQVVEZW11eGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gQVVEZW11eGVyKCkge1xuICAgICAgcmV0dXJuIEFVRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKEFVRGVtdXhlcik7XG5cbiAgICBBVURlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBidWZmZXIucGVla1N0cmluZygwLCA0KSA9PT0gJy5zbmQnO1xuICAgIH07XG5cbiAgICBicHMgPSBbOCwgOCwgMTYsIDI0LCAzMiwgMzIsIDY0XTtcblxuICAgIGJwc1syNl0gPSA4O1xuXG4gICAgZm9ybWF0cyA9IHtcbiAgICAgIDE6ICd1bGF3JyxcbiAgICAgIDI3OiAnYWxhdydcbiAgICB9O1xuXG4gICAgQVVEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBieXRlcywgZGF0YVNpemUsIGVuY29kaW5nLCBzaXplO1xuICAgICAgaWYgKCF0aGlzLnJlYWRIZWFkZXIgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDI0KSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJy5zbmQnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBVSBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICAgIHNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIGRhdGFTaXplID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICBlbmNvZGluZyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgZm9ybWF0SUQ6IGZvcm1hdHNbZW5jb2RpbmddIHx8ICdscGNtJyxcbiAgICAgICAgICBsaXR0bGVFbmRpYW46IGZhbHNlLFxuICAgICAgICAgIGZsb2F0aW5nUG9pbnQ6IGVuY29kaW5nID09PSA2IHx8IGVuY29kaW5nID09PSA3LFxuICAgICAgICAgIGJpdHNQZXJDaGFubmVsOiBicHNbZW5jb2RpbmcgLSAxXSxcbiAgICAgICAgICBzYW1wbGVSYXRlOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgY2hhbm5lbHNQZXJGcmFtZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpLFxuICAgICAgICAgIGZyYW1lc1BlclBhY2tldDogMVxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ1Vuc3VwcG9ydGVkIGVuY29kaW5nIGluIEFVIGZpbGUuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgPSAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4KSAqIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWU7XG4gICAgICAgIGlmIChkYXRhU2l6ZSAhPT0gMHhmZmZmZmZmZikge1xuICAgICAgICAgIGJ5dGVzID0gdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4O1xuICAgICAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCBkYXRhU2l6ZSAvIGJ5dGVzIC8gdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZSAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICAgIHRoaXMucmVhZEhlYWRlciA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5yZWFkSGVhZGVyKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5hdmFpbGFibGUoMSkpIHtcbiAgICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMuc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCkpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQVVEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQ0FGRGVtdXhlciwgRGVtdXhlciwgTTRBRGVtdXhlcixcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi4vZGVtdXhlcicpO1xuXG4gIE00QURlbXV4ZXIgPSByZXF1aXJlKCcuL200YScpO1xuXG4gIENBRkRlbXV4ZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKENBRkRlbXV4ZXIsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBDQUZEZW11eGVyKCkge1xuICAgICAgcmV0dXJuIENBRkRlbXV4ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVtdXhlci5yZWdpc3RlcihDQUZEZW11eGVyKTtcblxuICAgIENBRkRlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBidWZmZXIucGVla1N0cmluZygwLCA0KSA9PT0gJ2NhZmYnO1xuICAgIH07XG5cbiAgICBDQUZEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBidWZmZXIsIGJ5dGVPZmZzZXQsIGNvb2tpZSwgZW50cmllcywgZmxhZ3MsIGksIGtleSwgbWV0YWRhdGEsIG9mZnNldCwgc2FtcGxlT2Zmc2V0LCB2YWx1ZSwgX2ksIF9qLCBfcmVmO1xuICAgICAgaWYgKCF0aGlzLmZvcm1hdCAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoNjQpKSB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnY2FmZicpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiSW52YWxpZCBDQUYsIGRvZXMgbm90IGJlZ2luIHdpdGggJ2NhZmYnXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnZGVzYycpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiSW52YWxpZCBDQUYsICdjYWZmJyBpcyBub3QgZm9sbG93ZWQgYnkgJ2Rlc2MnXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghKHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSA9PT0gMCAmJiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgPT09IDMyKSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgXCJJbnZhbGlkICdkZXNjJyBzaXplLCBzaG91bGQgYmUgMzJcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb3JtYXQgPSB7fTtcbiAgICAgICAgdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSA9IHRoaXMuc3RyZWFtLnJlYWRGbG9hdDY0KCk7XG4gICAgICAgIHRoaXMuZm9ybWF0LmZvcm1hdElEID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgICAgZmxhZ3MgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIGlmICh0aGlzLmZvcm1hdC5mb3JtYXRJRCA9PT0gJ2xwY20nKSB7XG4gICAgICAgICAgdGhpcy5mb3JtYXQuZmxvYXRpbmdQb2ludCA9IEJvb2xlYW4oZmxhZ3MgJiAxKTtcbiAgICAgICAgICB0aGlzLmZvcm1hdC5saXR0bGVFbmRpYW4gPSBCb29sZWFuKGZsYWdzICYgMik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZm9ybWF0LmZyYW1lc1BlclBhY2tldCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy5mb3JtYXQpO1xuICAgICAgfVxuICAgICAgd2hpbGUgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICBpZiAoIXRoaXMuaGVhZGVyQ2FjaGUpIHtcbiAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0ge1xuICAgICAgICAgICAgdHlwZTogdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSxcbiAgICAgICAgICAgIG92ZXJzaXplOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgIT09IDAsXG4gICAgICAgICAgICBzaXplOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKClcbiAgICAgICAgICB9O1xuICAgICAgICAgIGlmICh0aGlzLmhlYWRlckNhY2hlLm92ZXJzaXplKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiSG9seSBTaGl0LCBhbiBvdmVyc2l6ZWQgZmlsZSwgbm90IHN1cHBvcnRlZCBpbiBKU1wiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoICh0aGlzLmhlYWRlckNhY2hlLnR5cGUpIHtcbiAgICAgICAgICBjYXNlICdrdWtpJzpcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5oZWFkZXJDYWNoZS5zaXplKSkge1xuICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtYXQuZm9ybWF0SUQgPT09ICdhYWMgJykge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IHRoaXMuc3RyZWFtLm9mZnNldCArIHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZTtcbiAgICAgICAgICAgICAgICBpZiAoY29va2llID0gTTRBRGVtdXhlci5yZWFkRXNkcyh0aGlzLnN0cmVhbSkpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgnY29va2llJywgY29va2llKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2VlayhvZmZzZXQpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJ1ZmZlciA9IHRoaXMuc3RyZWFtLnJlYWRCdWZmZXIodGhpcy5oZWFkZXJDYWNoZS5zaXplKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2Nvb2tpZScsIGJ1ZmZlcik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdwYWt0JzpcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5oZWFkZXJDYWNoZS5zaXplKSkge1xuICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnU2l6ZXMgZ3JlYXRlciB0aGFuIDMyIGJpdHMgYXJlIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5udW1QYWNrZXRzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnU2l6ZXMgZ3JlYXRlciB0aGFuIDMyIGJpdHMgYXJlIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5udW1GcmFtZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICAgIHRoaXMucHJpbWluZ0ZyYW1lcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgdGhpcy5yZW1haW5kZXJGcmFtZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCB0aGlzLm51bUZyYW1lcyAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMCk7XG4gICAgICAgICAgICAgIHRoaXMuc2VudER1cmF0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnl0ZU9mZnNldCA9IDA7XG4gICAgICAgICAgICAgIHNhbXBsZU9mZnNldCA9IDA7XG4gICAgICAgICAgICAgIGZvciAoaSA9IF9pID0gMCwgX3JlZiA9IHRoaXMubnVtUGFja2V0czsgX2kgPCBfcmVmOyBpID0gX2kgKz0gMSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkU2Vla1BvaW50KGJ5dGVPZmZzZXQsIHNhbXBsZU9mZnNldCk7XG4gICAgICAgICAgICAgICAgYnl0ZU9mZnNldCArPSB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCB8fCBNNEFEZW11eGVyLnJlYWREZXNjckxlbih0aGlzLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgc2FtcGxlT2Zmc2V0ICs9IHRoaXMuZm9ybWF0LmZyYW1lc1BlclBhY2tldCB8fCBNNEFEZW11eGVyLnJlYWREZXNjckxlbih0aGlzLnN0cmVhbSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdpbmZvJzpcbiAgICAgICAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICBtZXRhZGF0YSA9IHt9O1xuICAgICAgICAgICAgZm9yIChpID0gX2ogPSAwOyAwIDw9IGVudHJpZXMgPyBfaiA8IGVudHJpZXMgOiBfaiA+IGVudHJpZXM7IGkgPSAwIDw9IGVudHJpZXMgPyArK19qIDogLS1faikge1xuICAgICAgICAgICAgICBrZXkgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKG51bGwpO1xuICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcobnVsbCk7XG4gICAgICAgICAgICAgIG1ldGFkYXRhW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZW1pdCgnbWV0YWRhdGEnLCBtZXRhZGF0YSk7XG4gICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0gbnVsbDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2RhdGEnOlxuICAgICAgICAgICAgaWYgKCF0aGlzLnNlbnRGaXJzdERhdGFDaHVuaykge1xuICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlLnNpemUgLT0gNDtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ICE9PSAwICYmICF0aGlzLnNlbnREdXJhdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMubnVtRnJhbWVzID0gdGhpcy5oZWFkZXJDYWNoZS5zaXplIC8gdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMubnVtRnJhbWVzIC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLnNlbnRGaXJzdERhdGFDaHVuayA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidWZmZXIgPSB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSk7XG4gICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlLnNpemUgLT0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIGJ1ZmZlcik7XG4gICAgICAgICAgICBpZiAodGhpcy5oZWFkZXJDYWNoZS5zaXplIDw9IDApIHtcbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmhlYWRlckNhY2hlLnNpemUpKSB7XG4gICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5oZWFkZXJDYWNoZS5zaXplKTtcbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIENBRkRlbXV4ZXI7XG5cbiAgfSkoRGVtdXhlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZW11eGVyLCBNNEFEZW11eGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIF9faW5kZXhPZiA9IFtdLmluZGV4T2YgfHwgZnVuY3Rpb24oaXRlbSkgeyBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7IGlmIChpIGluIHRoaXMgJiYgdGhpc1tpXSA9PT0gaXRlbSkgcmV0dXJuIGk7IH0gcmV0dXJuIC0xOyB9O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgTTRBRGVtdXhlciA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICB2YXIgQklUU19QRVJfQ0hBTk5FTCwgVFlQRVMsIGFmdGVyLCBhdG9tLCBhdG9tcywgYm9vbCwgY29udGFpbmVycywgZGlza1RyYWNrLCBnZW5yZXMsIG1ldGEsIHN0cmluZztcblxuICAgIF9fZXh0ZW5kcyhNNEFEZW11eGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gTTRBRGVtdXhlcigpIHtcbiAgICAgIHJldHVybiBNNEFEZW11eGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucmVnaXN0ZXIoTTRBRGVtdXhlcik7XG5cbiAgICBUWVBFUyA9IFsnTTRBICcsICdNNFAgJywgJ000QiAnLCAnTTRWICcsICdpc29tJywgJ21wNDInLCAncXQgICddO1xuXG4gICAgTTRBRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIF9yZWY7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoNCwgNCkgPT09ICdmdHlwJyAmJiAoX3JlZiA9IGJ1ZmZlci5wZWVrU3RyaW5nKDgsIDQpLCBfX2luZGV4T2YuY2FsbChUWVBFUywgX3JlZikgPj0gMCk7XG4gICAgfTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuYXRvbXMgPSBbXTtcbiAgICAgIHRoaXMub2Zmc2V0cyA9IFtdO1xuICAgICAgdGhpcy50cmFjayA9IG51bGw7XG4gICAgICByZXR1cm4gdGhpcy50cmFja3MgPSBbXTtcbiAgICB9O1xuXG4gICAgYXRvbXMgPSB7fTtcblxuICAgIGNvbnRhaW5lcnMgPSB7fTtcblxuICAgIGF0b20gPSBmdW5jdGlvbihuYW1lLCBmbikge1xuICAgICAgdmFyIGMsIGNvbnRhaW5lciwgX2ksIF9sZW4sIF9yZWY7XG4gICAgICBjID0gW107XG4gICAgICBfcmVmID0gbmFtZS5zcGxpdCgnLicpLnNsaWNlKDAsIC0xKTtcbiAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gX3JlZi5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgICBjb250YWluZXIgPSBfcmVmW19pXTtcbiAgICAgICAgYy5wdXNoKGNvbnRhaW5lcik7XG4gICAgICAgIGNvbnRhaW5lcnNbYy5qb2luKCcuJyldID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChhdG9tc1tuYW1lXSA9PSBudWxsKSB7XG4gICAgICAgIGF0b21zW25hbWVdID0ge307XG4gICAgICB9XG4gICAgICByZXR1cm4gYXRvbXNbbmFtZV0uZm4gPSBmbjtcbiAgICB9O1xuXG4gICAgYWZ0ZXIgPSBmdW5jdGlvbihuYW1lLCBmbikge1xuICAgICAgaWYgKGF0b21zW25hbWVdID09IG51bGwpIHtcbiAgICAgICAgYXRvbXNbbmFtZV0gPSB7fTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdG9tc1tuYW1lXS5hZnRlciA9IGZuO1xuICAgIH07XG5cbiAgICBNNEFEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBoYW5kbGVyLCBwYXRoLCB0eXBlO1xuICAgICAgdGhpc1tcImJyZWFrXCJdID0gZmFsc2U7XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpICYmICF0aGlzW1wiYnJlYWtcIl0pIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlYWRIZWFkZXJzKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5sZW4gPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgLSA4O1xuICAgICAgICAgIHRoaXMudHlwZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCk7XG4gICAgICAgICAgaWYgKHRoaXMubGVuID09PSAwKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5hdG9tcy5wdXNoKHRoaXMudHlwZSk7XG4gICAgICAgICAgdGhpcy5vZmZzZXRzLnB1c2godGhpcy5zdHJlYW0ub2Zmc2V0ICsgdGhpcy5sZW4pO1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHBhdGggPSB0aGlzLmF0b21zLmpvaW4oJy4nKTtcbiAgICAgICAgaGFuZGxlciA9IGF0b21zW3BhdGhdO1xuICAgICAgICBpZiAoaGFuZGxlciAhPSBudWxsID8gaGFuZGxlci5mbiA6IHZvaWQgMCkge1xuICAgICAgICAgIGlmICghKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikgfHwgcGF0aCA9PT0gJ21kYXQnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBoYW5kbGVyLmZuLmNhbGwodGhpcyk7XG4gICAgICAgICAgaWYgKHBhdGggaW4gY29udGFpbmVycykge1xuICAgICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChwYXRoIGluIGNvbnRhaW5lcnMpIHtcbiAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5sZW4pKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4pO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5vZmZzZXQgPj0gdGhpcy5vZmZzZXRzW3RoaXMub2Zmc2V0cy5sZW5ndGggLSAxXSkge1xuICAgICAgICAgIGhhbmRsZXIgPSBhdG9tc1t0aGlzLmF0b21zLmpvaW4oJy4nKV07XG4gICAgICAgICAgaWYgKGhhbmRsZXIgIT0gbnVsbCA/IGhhbmRsZXIuYWZ0ZXIgOiB2b2lkIDApIHtcbiAgICAgICAgICAgIGhhbmRsZXIuYWZ0ZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdHlwZSA9IHRoaXMuYXRvbXMucG9wKCk7XG4gICAgICAgICAgdGhpcy5vZmZzZXRzLnBvcCgpO1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBhdG9tKCdmdHlwJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX3JlZjtcbiAgICAgIGlmIChfcmVmID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSwgX19pbmRleE9mLmNhbGwoVFlQRVMsIF9yZWYpIDwgMCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdOb3QgYSB2YWxpZCBNNEEgZmlsZS4nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gNCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMudHJhY2sgPSB7fTtcbiAgICAgIHJldHVybiB0aGlzLnRyYWNrcy5wdXNoKHRoaXMudHJhY2spO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLnRraGQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDgpO1xuICAgICAgdGhpcy50cmFjay5pZCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gMTYpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEuaGRscicsIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnRyYWNrLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgxMik7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDI0KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1kaGQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDgpO1xuICAgICAgdGhpcy50cmFjay50aW1lU2NhbGUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB0aGlzLnRyYWNrLmR1cmF0aW9uID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgfSk7XG5cbiAgICBCSVRTX1BFUl9DSEFOTkVMID0ge1xuICAgICAgdWxhdzogOCxcbiAgICAgIGFsYXc6IDgsXG4gICAgICBpbjI0OiAyNCxcbiAgICAgIGluMzI6IDMyLFxuICAgICAgZmwzMjogMzIsXG4gICAgICBmbDY0OiA2NFxuICAgIH07XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGZvcm1hdCwgbnVtRW50cmllcywgdmVyc2lvbiwgX3JlZiwgX3JlZjE7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgbnVtRW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIGlmICh0aGlzLnRyYWNrLnR5cGUgIT09ICdzb3VuJykge1xuICAgICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDgpO1xuICAgICAgfVxuICAgICAgaWYgKG51bUVudHJpZXMgIT09IDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIk9ubHkgZXhwZWN0aW5nIG9uZSBlbnRyeSBpbiBzYW1wbGUgZGVzY3JpcHRpb24gYXRvbSFcIik7XG4gICAgICB9XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgZm9ybWF0ID0gdGhpcy50cmFjay5mb3JtYXQgPSB7fTtcbiAgICAgIGZvcm1hdC5mb3JtYXRJRCA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDYpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgIHZlcnNpb24gPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDYpO1xuICAgICAgZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICBmb3JtYXQuYml0c1BlckNoYW5uZWwgPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgZm9ybWF0LnNhbXBsZVJhdGUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgaWYgKHZlcnNpb24gPT09IDEpIHtcbiAgICAgICAgZm9ybWF0LmZyYW1lc1BlclBhY2tldCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgZm9ybWF0LmJ5dGVzUGVyRnJhbWUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB9IGVsc2UgaWYgKHZlcnNpb24gIT09IDApIHtcbiAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsICdVbmtub3duIHZlcnNpb24gaW4gc3RzZCBhdG9tJyk7XG4gICAgICB9XG4gICAgICBpZiAoQklUU19QRVJfQ0hBTk5FTFtmb3JtYXQuZm9ybWF0SURdICE9IG51bGwpIHtcbiAgICAgICAgZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gQklUU19QRVJfQ0hBTk5FTFtmb3JtYXQuZm9ybWF0SURdO1xuICAgICAgfVxuICAgICAgZm9ybWF0LmZsb2F0aW5nUG9pbnQgPSAoX3JlZiA9IGZvcm1hdC5mb3JtYXRJRCkgPT09ICdmbDMyJyB8fCBfcmVmID09PSAnZmw2NCc7XG4gICAgICBmb3JtYXQubGl0dGxlRW5kaWFuID0gZm9ybWF0LmZvcm1hdElEID09PSAnc293dCcgJiYgZm9ybWF0LmJpdHNQZXJDaGFubmVsID4gODtcbiAgICAgIGlmICgoX3JlZjEgPSBmb3JtYXQuZm9ybWF0SUQpID09PSAndHdvcycgfHwgX3JlZjEgPT09ICdzb3d0JyB8fCBfcmVmMSA9PT0gJ2luMjQnIHx8IF9yZWYxID09PSAnaW4zMicgfHwgX3JlZjEgPT09ICdmbDMyJyB8fCBfcmVmMSA9PT0gJ2ZsNjQnIHx8IF9yZWYxID09PSAncmF3ICcgfHwgX3JlZjEgPT09ICdOT05FJykge1xuICAgICAgICByZXR1cm4gZm9ybWF0LmZvcm1hdElEID0gJ2xwY20nO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c2QuYWxhYycsIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHJldHVybiB0aGlzLnRyYWNrLmNvb2tpZSA9IHRoaXMuc3RyZWFtLnJlYWRCdWZmZXIodGhpcy5sZW4gLSA0KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNkLmVzZHMnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBvZmZzZXQ7XG4gICAgICBvZmZzZXQgPSB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmxlbjtcbiAgICAgIHRoaXMudHJhY2suY29va2llID0gTTRBRGVtdXhlci5yZWFkRXNkcyh0aGlzLnN0cmVhbSk7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uc2VlayhvZmZzZXQpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c2Qud2F2ZS5lbmRhJywgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50cmFjay5mb3JtYXQubGl0dGxlRW5kaWFuID0gISF0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgfSk7XG5cbiAgICBNNEFEZW11eGVyLnJlYWREZXNjckxlbiA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgdmFyIGMsIGNvdW50LCBsZW47XG4gICAgICBsZW4gPSAwO1xuICAgICAgY291bnQgPSA0O1xuICAgICAgd2hpbGUgKGNvdW50LS0pIHtcbiAgICAgICAgYyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgICAgbGVuID0gKGxlbiA8PCA3KSB8IChjICYgMHg3Zik7XG4gICAgICAgIGlmICghKGMgJiAweDgwKSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbGVuO1xuICAgIH07XG5cbiAgICBNNEFEZW11eGVyLnJlYWRFc2RzID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICB2YXIgY29kZWNfaWQsIGZsYWdzLCBsZW4sIHRhZztcbiAgICAgIHN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGFnID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgbGVuID0gTTRBRGVtdXhlci5yZWFkRGVzY3JMZW4oc3RyZWFtKTtcbiAgICAgIGlmICh0YWcgPT09IDB4MDMpIHtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICAgIGZsYWdzID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBpZiAoZmxhZ3MgJiAweDgwKSB7XG4gICAgICAgICAgc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZsYWdzICYgMHg0MCkge1xuICAgICAgICAgIHN0cmVhbS5hZHZhbmNlKHN0cmVhbS5yZWFkVUludDgoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZsYWdzICYgMHgyMCkge1xuICAgICAgICAgIHN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgIH1cbiAgICAgIHRhZyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgIGxlbiA9IE00QURlbXV4ZXIucmVhZERlc2NyTGVuKHN0cmVhbSk7XG4gICAgICBpZiAodGFnID09PSAweDA0KSB7XG4gICAgICAgIGNvZGVjX2lkID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSgxKTtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMyk7XG4gICAgICAgIHN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgdGFnID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBsZW4gPSBNNEFEZW11eGVyLnJlYWREZXNjckxlbihzdHJlYW0pO1xuICAgICAgICBpZiAodGFnID09PSAweDA1KSB7XG4gICAgICAgICAgcmV0dXJuIHN0cmVhbS5yZWFkQnVmZmVyKGxlbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3R0cycsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIF9pO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB0aGlzLnRyYWNrLnN0dHMgPSBbXTtcbiAgICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCBlbnRyaWVzOyBpID0gX2kgKz0gMSkge1xuICAgICAgICB0aGlzLnRyYWNrLnN0dHNbaV0gPSB7XG4gICAgICAgICAgY291bnQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICBkdXJhdGlvbjogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5zZXR1cFNlZWtQb2ludHMoKTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNjJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZW50cmllcywgaSwgX2k7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgZW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHRoaXMudHJhY2suc3RzYyA9IFtdO1xuICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IGVudHJpZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suc3RzY1tpXSA9IHtcbiAgICAgICAgICBmaXJzdDogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpLFxuICAgICAgICAgIGNvdW50OiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgaWQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzeicsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIF9pO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHRoaXMudHJhY2suc2FtcGxlU2l6ZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICBpZiAodGhpcy50cmFjay5zYW1wbGVTaXplID09PSAwICYmIGVudHJpZXMgPiAwKSB7XG4gICAgICAgIHRoaXMudHJhY2suc2FtcGxlU2l6ZXMgPSBbXTtcbiAgICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IGVudHJpZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgICAgdGhpcy50cmFjay5zYW1wbGVTaXplc1tpXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RjbycsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIF9pO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0cyA9IFtdO1xuICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IGVudHJpZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suY2h1bmtPZmZzZXRzW2ldID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsudHJlZi5jaGFwJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZW50cmllcywgaSwgX2k7XG4gICAgICBlbnRyaWVzID0gdGhpcy5sZW4gPj4gMjtcbiAgICAgIHRoaXMudHJhY2suY2hhcHRlclRyYWNrcyA9IFtdO1xuICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IGVudHJpZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suY2hhcHRlclRyYWNrc1tpXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLnNldHVwU2Vla1BvaW50cyA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGksIGosIG9mZnNldCwgcG9zaXRpb24sIHNhbXBsZUluZGV4LCBzaXplLCBzdHNjSW5kZXgsIHN0dHNJbmRleCwgc3R0c1NhbXBsZSwgdGltZXN0YW1wLCBfaSwgX2osIF9sZW4sIF9yZWYsIF9yZWYxLCBfcmVzdWx0cztcbiAgICAgIGlmICghKCh0aGlzLnRyYWNrLmNodW5rT2Zmc2V0cyAhPSBudWxsKSAmJiAodGhpcy50cmFjay5zdHNjICE9IG51bGwpICYmICh0aGlzLnRyYWNrLnNhbXBsZVNpemUgIT0gbnVsbCkgJiYgKHRoaXMudHJhY2suc3R0cyAhPSBudWxsKSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc3RzY0luZGV4ID0gMDtcbiAgICAgIHN0dHNJbmRleCA9IDA7XG4gICAgICBzdHRzSW5kZXggPSAwO1xuICAgICAgc3R0c1NhbXBsZSA9IDA7XG4gICAgICBzYW1wbGVJbmRleCA9IDA7XG4gICAgICBvZmZzZXQgPSAwO1xuICAgICAgdGltZXN0YW1wID0gMDtcbiAgICAgIHRoaXMudHJhY2suc2Vla1BvaW50cyA9IFtdO1xuICAgICAgX3JlZiA9IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzO1xuICAgICAgX3Jlc3VsdHMgPSBbXTtcbiAgICAgIGZvciAoaSA9IF9pID0gMCwgX2xlbiA9IF9yZWYubGVuZ3RoOyBfaSA8IF9sZW47IGkgPSArK19pKSB7XG4gICAgICAgIHBvc2l0aW9uID0gX3JlZltpXTtcbiAgICAgICAgZm9yIChqID0gX2ogPSAwLCBfcmVmMSA9IHRoaXMudHJhY2suc3RzY1tzdHNjSW5kZXhdLmNvdW50OyBfaiA8IF9yZWYxOyBqID0gX2ogKz0gMSkge1xuICAgICAgICAgIHRoaXMudHJhY2suc2Vla1BvaW50cy5wdXNoKHtcbiAgICAgICAgICAgIG9mZnNldDogb2Zmc2V0LFxuICAgICAgICAgICAgcG9zaXRpb246IHBvc2l0aW9uLFxuICAgICAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXBcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzaXplID0gdGhpcy50cmFjay5zYW1wbGVTaXplIHx8IHRoaXMudHJhY2suc2FtcGxlU2l6ZXNbc2FtcGxlSW5kZXgrK107XG4gICAgICAgICAgb2Zmc2V0ICs9IHNpemU7XG4gICAgICAgICAgcG9zaXRpb24gKz0gc2l6ZTtcbiAgICAgICAgICB0aW1lc3RhbXAgKz0gdGhpcy50cmFjay5zdHRzW3N0dHNJbmRleF0uZHVyYXRpb247XG4gICAgICAgICAgaWYgKHN0dHNJbmRleCArIDEgPCB0aGlzLnRyYWNrLnN0dHMubGVuZ3RoICYmICsrc3R0c1NhbXBsZSA9PT0gdGhpcy50cmFjay5zdHRzW3N0dHNJbmRleF0uY291bnQpIHtcbiAgICAgICAgICAgIHN0dHNTYW1wbGUgPSAwO1xuICAgICAgICAgICAgc3R0c0luZGV4Kys7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzdHNjSW5kZXggKyAxIDwgdGhpcy50cmFjay5zdHNjLmxlbmd0aCAmJiBpICsgMSA9PT0gdGhpcy50cmFjay5zdHNjW3N0c2NJbmRleCArIDFdLmZpcnN0KSB7XG4gICAgICAgICAgX3Jlc3VsdHMucHVzaChzdHNjSW5kZXgrKyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgX3Jlc3VsdHMucHVzaCh2b2lkIDApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gX3Jlc3VsdHM7XG4gICAgfTtcblxuICAgIGFmdGVyKCdtb292JywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgdHJhY2ssIF9pLCBfbGVuLCBfcmVmO1xuICAgICAgaWYgKHRoaXMubWRhdE9mZnNldCAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtLnNlZWsodGhpcy5tZGF0T2Zmc2V0IC0gOCk7XG4gICAgICB9XG4gICAgICBfcmVmID0gdGhpcy50cmFja3M7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgdHJhY2sgPSBfcmVmW19pXTtcbiAgICAgICAgaWYgKCEodHJhY2sudHlwZSA9PT0gJ3NvdW4nKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudHJhY2sgPSB0cmFjaztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy50cmFjay50eXBlICE9PSAnc291bicpIHtcbiAgICAgICAgdGhpcy50cmFjayA9IG51bGw7XG4gICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ05vIGF1ZGlvIHRyYWNrcyBpbiBtNGEgZmlsZS4nKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy50cmFjay5mb3JtYXQpO1xuICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMudHJhY2suZHVyYXRpb24gLyB0aGlzLnRyYWNrLnRpbWVTY2FsZSAqIDEwMDAgfCAwKTtcbiAgICAgIGlmICh0aGlzLnRyYWNrLmNvb2tpZSkge1xuICAgICAgICB0aGlzLmVtaXQoJ2Nvb2tpZScsIHRoaXMudHJhY2suY29va2llKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnNlZWtQb2ludHMgPSB0aGlzLnRyYWNrLnNlZWtQb2ludHM7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtZGF0JywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYnl0ZXMsIGNodW5rU2l6ZSwgbGVuZ3RoLCBudW1TYW1wbGVzLCBvZmZzZXQsIHNhbXBsZSwgc2l6ZSwgX2k7XG4gICAgICBpZiAoIXRoaXMuc3RhcnRlZERhdGEpIHtcbiAgICAgICAgaWYgKHRoaXMubWRhdE9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5tZGF0T2Zmc2V0ID0gdGhpcy5zdHJlYW0ub2Zmc2V0O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnRyYWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBieXRlcyA9IE1hdGgubWluKHRoaXMuc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCksIHRoaXMubGVuKTtcbiAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKGJ5dGVzKTtcbiAgICAgICAgICB0aGlzLmxlbiAtPSBieXRlcztcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaHVua0luZGV4ID0gMDtcbiAgICAgICAgdGhpcy5zdHNjSW5kZXggPSAwO1xuICAgICAgICB0aGlzLnNhbXBsZUluZGV4ID0gMDtcbiAgICAgICAgdGhpcy50YWlsT2Zmc2V0ID0gMDtcbiAgICAgICAgdGhpcy50YWlsU2FtcGxlcyA9IDA7XG4gICAgICAgIHRoaXMuc3RhcnRlZERhdGEgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLnJlYWRDaGFwdGVycykge1xuICAgICAgICB0aGlzLnJlYWRDaGFwdGVycyA9IHRoaXMucGFyc2VDaGFwdGVycygpO1xuICAgICAgICBpZiAodGhpc1tcImJyZWFrXCJdID0gIXRoaXMucmVhZENoYXB0ZXJzKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyZWFtLnNlZWsodGhpcy5tZGF0T2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIG9mZnNldCA9IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzW3RoaXMuY2h1bmtJbmRleF0gKyB0aGlzLnRhaWxPZmZzZXQ7XG4gICAgICBsZW5ndGggPSAwO1xuICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUob2Zmc2V0IC0gdGhpcy5zdHJlYW0ub2Zmc2V0KSkge1xuICAgICAgICB0aGlzW1wiYnJlYWtcIl0gPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnN0cmVhbS5zZWVrKG9mZnNldCk7XG4gICAgICB3aGlsZSAodGhpcy5jaHVua0luZGV4IDwgdGhpcy50cmFjay5jaHVua09mZnNldHMubGVuZ3RoKSB7XG4gICAgICAgIG51bVNhbXBsZXMgPSB0aGlzLnRyYWNrLnN0c2NbdGhpcy5zdHNjSW5kZXhdLmNvdW50IC0gdGhpcy50YWlsU2FtcGxlcztcbiAgICAgICAgY2h1bmtTaXplID0gMDtcbiAgICAgICAgZm9yIChzYW1wbGUgPSBfaSA9IDA7IF9pIDwgbnVtU2FtcGxlczsgc2FtcGxlID0gX2kgKz0gMSkge1xuICAgICAgICAgIHNpemUgPSB0aGlzLnRyYWNrLnNhbXBsZVNpemUgfHwgdGhpcy50cmFjay5zYW1wbGVTaXplc1t0aGlzLnNhbXBsZUluZGV4XTtcbiAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZShsZW5ndGggKyBzaXplKSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxlbmd0aCArPSBzaXplO1xuICAgICAgICAgIGNodW5rU2l6ZSArPSBzaXplO1xuICAgICAgICAgIHRoaXMuc2FtcGxlSW5kZXgrKztcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2FtcGxlIDwgbnVtU2FtcGxlcykge1xuICAgICAgICAgIHRoaXMudGFpbE9mZnNldCArPSBjaHVua1NpemU7XG4gICAgICAgICAgdGhpcy50YWlsU2FtcGxlcyArPSBzYW1wbGU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5jaHVua0luZGV4Kys7XG4gICAgICAgICAgdGhpcy50YWlsT2Zmc2V0ID0gMDtcbiAgICAgICAgICB0aGlzLnRhaWxTYW1wbGVzID0gMDtcbiAgICAgICAgICBpZiAodGhpcy5zdHNjSW5kZXggKyAxIDwgdGhpcy50cmFjay5zdHNjLmxlbmd0aCAmJiB0aGlzLmNodW5rSW5kZXggKyAxID09PSB0aGlzLnRyYWNrLnN0c2NbdGhpcy5zdHNjSW5kZXggKyAxXS5maXJzdCkge1xuICAgICAgICAgICAgdGhpcy5zdHNjSW5kZXgrKztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG9mZnNldCArIGxlbmd0aCAhPT0gdGhpcy50cmFjay5jaHVua09mZnNldHNbdGhpcy5jaHVua0luZGV4XSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCB0aGlzLnN0cmVhbS5yZWFkQnVmZmVyKGxlbmd0aCkpO1xuICAgICAgICByZXR1cm4gdGhpc1tcImJyZWFrXCJdID0gdGhpcy5jaHVua0luZGV4ID09PSB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0cy5sZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpc1tcImJyZWFrXCJdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLnBhcnNlQ2hhcHRlcnMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBib20sIGlkLCBsZW4sIG5leHRUaW1lc3RhbXAsIHBvaW50LCB0aXRsZSwgdHJhY2ssIF9pLCBfbGVuLCBfcmVmLCBfcmVmMSwgX3JlZjIsIF9yZWYzO1xuICAgICAgaWYgKCEoKChfcmVmID0gdGhpcy50cmFjay5jaGFwdGVyVHJhY2tzKSAhPSBudWxsID8gX3JlZi5sZW5ndGggOiB2b2lkIDApID4gMCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZCA9IHRoaXMudHJhY2suY2hhcHRlclRyYWNrc1swXTtcbiAgICAgIF9yZWYxID0gdGhpcy50cmFja3M7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYxLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIHRyYWNrID0gX3JlZjFbX2ldO1xuICAgICAgICBpZiAodHJhY2suaWQgPT09IGlkKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0cmFjay5pZCAhPT0gaWQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsICdDaGFwdGVyIHRyYWNrIGRvZXMgbm90IGV4aXN0LicpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuY2hhcHRlcnMgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmNoYXB0ZXJzID0gW107XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5jaGFwdGVycy5sZW5ndGggPCB0cmFjay5zZWVrUG9pbnRzLmxlbmd0aCkge1xuICAgICAgICBwb2ludCA9IHRyYWNrLnNlZWtQb2ludHNbdGhpcy5jaGFwdGVycy5sZW5ndGhdO1xuICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZShwb2ludC5wb3NpdGlvbiAtIHRoaXMuc3RyZWFtLm9mZnNldCArIDMyKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0cmVhbS5zZWVrKHBvaW50LnBvc2l0aW9uKTtcbiAgICAgICAgbGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgICB0aXRsZSA9IG51bGw7XG4gICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKGxlbikpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxlbiA+IDIpIHtcbiAgICAgICAgICBib20gPSB0aGlzLnN0cmVhbS5wZWVrVUludDE2KCk7XG4gICAgICAgICAgaWYgKGJvbSA9PT0gMHhmZWZmIHx8IGJvbSA9PT0gMHhmZmZlKSB7XG4gICAgICAgICAgICB0aXRsZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcobGVuLCAndXRmMTYtYm9tJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aXRsZSA9PSBudWxsKSB7XG4gICAgICAgICAgdGl0bGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKGxlbiwgJ3V0ZjgnKTtcbiAgICAgICAgfVxuICAgICAgICBuZXh0VGltZXN0YW1wID0gKF9yZWYyID0gKF9yZWYzID0gdHJhY2suc2Vla1BvaW50c1t0aGlzLmNoYXB0ZXJzLmxlbmd0aCArIDFdKSAhPSBudWxsID8gX3JlZjMudGltZXN0YW1wIDogdm9pZCAwKSAhPSBudWxsID8gX3JlZjIgOiB0cmFjay5kdXJhdGlvbjtcbiAgICAgICAgdGhpcy5jaGFwdGVycy5wdXNoKHtcbiAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgdGltZXN0YW1wOiBwb2ludC50aW1lc3RhbXAgLyB0cmFjay50aW1lU2NhbGUgKiAxMDAwIHwgMCxcbiAgICAgICAgICBkdXJhdGlvbjogKG5leHRUaW1lc3RhbXAgLSBwb2ludC50aW1lc3RhbXApIC8gdHJhY2sudGltZVNjYWxlICogMTAwMCB8IDBcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0aGlzLmVtaXQoJ2NoYXB0ZXJzJywgdGhpcy5jaGFwdGVycyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgYXRvbSgnbW9vdi51ZHRhLm1ldGEnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMubWV0YWRhdGEgPSB7fTtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXIoJ21vb3YudWR0YS5tZXRhJywgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbWl0KCdtZXRhZGF0YScsIHRoaXMubWV0YWRhdGEpO1xuICAgIH0pO1xuXG4gICAgbWV0YSA9IGZ1bmN0aW9uKGZpZWxkLCBuYW1lLCBmbikge1xuICAgICAgcmV0dXJuIGF0b20oXCJtb292LnVkdGEubWV0YS5pbHN0LlwiICsgZmllbGQgKyBcIi5kYXRhXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDgpO1xuICAgICAgICB0aGlzLmxlbiAtPSA4O1xuICAgICAgICByZXR1cm4gZm4uY2FsbCh0aGlzLCBuYW1lKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBzdHJpbmcgPSBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyh0aGlzLmxlbiwgJ3V0ZjgnKTtcbiAgICB9O1xuXG4gICAgbWV0YSgnwqlhbGInLCAnYWxidW0nLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlhcmcnLCAnYXJyYW5nZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlhcnQnLCAnYXJ0aXN0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpQVJUJywgJ2FydGlzdCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdhQVJUJywgJ2FsYnVtQXJ0aXN0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2NhdGcnLCAnY2F0ZWdvcnknLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqljb20nLCAnY29tcG9zZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqljcHknLCAnY29weXJpZ2h0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2NwcnQnLCAnY29weXJpZ2h0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpY210JywgJ2NvbW1lbnRzJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpZGF5JywgJ3JlbGVhc2VEYXRlJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2Rlc2MnLCAnZGVzY3JpcHRpb24nLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlnZW4nLCAnZ2VucmUnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlncnAnLCAnZ3JvdXBpbmcnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlpc3InLCAnSVNSQycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdrZXl3JywgJ2tleXdvcmRzJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpbGFiJywgJ3JlY29yZExhYmVsJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2xkZXMnLCAnbG9uZ0Rlc2NyaXB0aW9uJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpbHlyJywgJ2x5cmljcycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqW5hbScsICd0aXRsZScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXBoZycsICdyZWNvcmRpbmdDb3B5cmlnaHQnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlwcmQnLCAncHJvZHVjZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlwcmYnLCAncGVyZm9ybWVycycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdwdXJkJywgJ3B1cmNoYXNlRGF0ZScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdwdXJsJywgJ3BvZGNhc3RVUkwnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlzd2YnLCAnc29uZ3dyaXRlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXRvbycsICdlbmNvZGVyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8Kpd3J0JywgJ2NvbXBvc2VyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2NvdnInLCAnY292ZXJBcnQnLCBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gdGhpcy5zdHJlYW0ucmVhZEJ1ZmZlcih0aGlzLmxlbik7XG4gICAgfSk7XG5cbiAgICBnZW5yZXMgPSBbXCJCbHVlc1wiLCBcIkNsYXNzaWMgUm9ja1wiLCBcIkNvdW50cnlcIiwgXCJEYW5jZVwiLCBcIkRpc2NvXCIsIFwiRnVua1wiLCBcIkdydW5nZVwiLCBcIkhpcC1Ib3BcIiwgXCJKYXp6XCIsIFwiTWV0YWxcIiwgXCJOZXcgQWdlXCIsIFwiT2xkaWVzXCIsIFwiT3RoZXJcIiwgXCJQb3BcIiwgXCJSJkJcIiwgXCJSYXBcIiwgXCJSZWdnYWVcIiwgXCJSb2NrXCIsIFwiVGVjaG5vXCIsIFwiSW5kdXN0cmlhbFwiLCBcIkFsdGVybmF0aXZlXCIsIFwiU2thXCIsIFwiRGVhdGggTWV0YWxcIiwgXCJQcmFua3NcIiwgXCJTb3VuZHRyYWNrXCIsIFwiRXVyby1UZWNobm9cIiwgXCJBbWJpZW50XCIsIFwiVHJpcC1Ib3BcIiwgXCJWb2NhbFwiLCBcIkphenorRnVua1wiLCBcIkZ1c2lvblwiLCBcIlRyYW5jZVwiLCBcIkNsYXNzaWNhbFwiLCBcIkluc3RydW1lbnRhbFwiLCBcIkFjaWRcIiwgXCJIb3VzZVwiLCBcIkdhbWVcIiwgXCJTb3VuZCBDbGlwXCIsIFwiR29zcGVsXCIsIFwiTm9pc2VcIiwgXCJBbHRlcm5Sb2NrXCIsIFwiQmFzc1wiLCBcIlNvdWxcIiwgXCJQdW5rXCIsIFwiU3BhY2VcIiwgXCJNZWRpdGF0aXZlXCIsIFwiSW5zdHJ1bWVudGFsIFBvcFwiLCBcIkluc3RydW1lbnRhbCBSb2NrXCIsIFwiRXRobmljXCIsIFwiR290aGljXCIsIFwiRGFya3dhdmVcIiwgXCJUZWNobm8tSW5kdXN0cmlhbFwiLCBcIkVsZWN0cm9uaWNcIiwgXCJQb3AtRm9sa1wiLCBcIkV1cm9kYW5jZVwiLCBcIkRyZWFtXCIsIFwiU291dGhlcm4gUm9ja1wiLCBcIkNvbWVkeVwiLCBcIkN1bHRcIiwgXCJHYW5nc3RhXCIsIFwiVG9wIDQwXCIsIFwiQ2hyaXN0aWFuIFJhcFwiLCBcIlBvcC9GdW5rXCIsIFwiSnVuZ2xlXCIsIFwiTmF0aXZlIEFtZXJpY2FuXCIsIFwiQ2FiYXJldFwiLCBcIk5ldyBXYXZlXCIsIFwiUHN5Y2hhZGVsaWNcIiwgXCJSYXZlXCIsIFwiU2hvd3R1bmVzXCIsIFwiVHJhaWxlclwiLCBcIkxvLUZpXCIsIFwiVHJpYmFsXCIsIFwiQWNpZCBQdW5rXCIsIFwiQWNpZCBKYXp6XCIsIFwiUG9sa2FcIiwgXCJSZXRyb1wiLCBcIk11c2ljYWxcIiwgXCJSb2NrICYgUm9sbFwiLCBcIkhhcmQgUm9ja1wiLCBcIkZvbGtcIiwgXCJGb2xrL1JvY2tcIiwgXCJOYXRpb25hbCBGb2xrXCIsIFwiU3dpbmdcIiwgXCJGYXN0IEZ1c2lvblwiLCBcIkJlYm9iXCIsIFwiTGF0aW5cIiwgXCJSZXZpdmFsXCIsIFwiQ2VsdGljXCIsIFwiQmx1ZWdyYXNzXCIsIFwiQXZhbnRnYXJkZVwiLCBcIkdvdGhpYyBSb2NrXCIsIFwiUHJvZ3Jlc3NpdmUgUm9ja1wiLCBcIlBzeWNoZWRlbGljIFJvY2tcIiwgXCJTeW1waG9uaWMgUm9ja1wiLCBcIlNsb3cgUm9ja1wiLCBcIkJpZyBCYW5kXCIsIFwiQ2hvcnVzXCIsIFwiRWFzeSBMaXN0ZW5pbmdcIiwgXCJBY291c3RpY1wiLCBcIkh1bW91clwiLCBcIlNwZWVjaFwiLCBcIkNoYW5zb25cIiwgXCJPcGVyYVwiLCBcIkNoYW1iZXIgTXVzaWNcIiwgXCJTb25hdGFcIiwgXCJTeW1waG9ueVwiLCBcIkJvb3R5IEJhc3NcIiwgXCJQcmltdXNcIiwgXCJQb3JuIEdyb292ZVwiLCBcIlNhdGlyZVwiLCBcIlNsb3cgSmFtXCIsIFwiQ2x1YlwiLCBcIlRhbmdvXCIsIFwiU2FtYmFcIiwgXCJGb2xrbG9yZVwiLCBcIkJhbGxhZFwiLCBcIlBvd2VyIEJhbGxhZFwiLCBcIlJoeXRobWljIFNvdWxcIiwgXCJGcmVlc3R5bGVcIiwgXCJEdWV0XCIsIFwiUHVuayBSb2NrXCIsIFwiRHJ1bSBTb2xvXCIsIFwiQSBDYXBlbGxhXCIsIFwiRXVyby1Ib3VzZVwiLCBcIkRhbmNlIEhhbGxcIl07XG5cbiAgICBtZXRhKCdnbnJlJywgJ2dlbnJlJywgZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IGdlbnJlc1t0aGlzLnN0cmVhbS5yZWFkVUludDE2KCkgLSAxXTtcbiAgICB9KTtcblxuICAgIG1ldGEoJ3RtcG8nLCAndGVtcG8nLCBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgIH0pO1xuXG4gICAgbWV0YSgncnRuZycsICdyYXRpbmcnLCBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgdmFyIHJhdGluZztcbiAgICAgIHJhdGluZyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gcmF0aW5nID09PSAyID8gJ0NsZWFuJyA6IHJhdGluZyAhPT0gMCA/ICdFeHBsaWNpdCcgOiAnTm9uZSc7XG4gICAgfSk7XG5cbiAgICBkaXNrVHJhY2sgPSBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgIHRoaXMubWV0YWRhdGFbZmllbGRdID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpICsgJyBvZiAnICsgdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4gLSA2KTtcbiAgICB9O1xuXG4gICAgbWV0YSgnZGlzaycsICdkaXNrTnVtYmVyJywgZGlza1RyYWNrKTtcblxuICAgIG1ldGEoJ3Rya24nLCAndHJhY2tOdW1iZXInLCBkaXNrVHJhY2spO1xuXG4gICAgYm9vbCA9IGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSB0aGlzLnN0cmVhbS5yZWFkVUludDgoKSA9PT0gMTtcbiAgICB9O1xuXG4gICAgbWV0YSgnY3BpbCcsICdjb21waWxhdGlvbicsIGJvb2wpO1xuXG4gICAgbWV0YSgncGNzdCcsICdwb2RjYXN0JywgYm9vbCk7XG5cbiAgICBtZXRhKCdwZ2FwJywgJ2dhcGxlc3MnLCBib29sKTtcblxuICAgIHJldHVybiBNNEFEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gTTRBRGVtdXhlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIERlbXV4ZXIsIFdBVkVEZW11eGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgV0FWRURlbXV4ZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgdmFyIGZvcm1hdHM7XG5cbiAgICBfX2V4dGVuZHMoV0FWRURlbXV4ZXIsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBXQVZFRGVtdXhlcigpIHtcbiAgICAgIHJldHVybiBXQVZFRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKFdBVkVEZW11eGVyKTtcblxuICAgIFdBVkVEZW11eGVyLnByb2JlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoMCwgNCkgPT09ICdSSUZGJyAmJiBidWZmZXIucGVla1N0cmluZyg4LCA0KSA9PT0gJ1dBVkUnO1xuICAgIH07XG5cbiAgICBmb3JtYXRzID0ge1xuICAgICAgMHgwMDAxOiAnbHBjbScsXG4gICAgICAweDAwMDM6ICdscGNtJyxcbiAgICAgIDB4MDAwNjogJ2FsYXcnLFxuICAgICAgMHgwMDA3OiAndWxhdydcbiAgICB9O1xuXG4gICAgV0FWRURlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ1ZmZlciwgYnl0ZXMsIGVuY29kaW5nO1xuICAgICAgaWYgKCF0aGlzLnJlYWRTdGFydCAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoMTIpKSB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnUklGRicpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIFdBViBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlsZVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKHRydWUpO1xuICAgICAgICB0aGlzLnJlYWRTdGFydCA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnV0FWRScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIFdBViBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIGlmICghdGhpcy5yZWFkSGVhZGVycyAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgIHRoaXMubGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMih0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ2ZtdCAnOlxuICAgICAgICAgICAgZW5jb2RpbmcgPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KHRydWUpO1xuICAgICAgICAgICAgaWYgKCEoZW5jb2RpbmcgaW4gZm9ybWF0cykpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnVW5zdXBwb3J0ZWQgZm9ybWF0IGluIFdBViBmaWxlLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgICAgIGZvcm1hdElEOiBmb3JtYXRzW2VuY29kaW5nXSxcbiAgICAgICAgICAgICAgZmxvYXRpbmdQb2ludDogZW5jb2RpbmcgPT09IDB4MDAwMyxcbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuOiBmb3JtYXRzW2VuY29kaW5nXSA9PT0gJ2xwY20nLFxuICAgICAgICAgICAgICBjaGFubmVsc1BlckZyYW1lOiB0aGlzLnN0cmVhbS5yZWFkVUludDE2KHRydWUpLFxuICAgICAgICAgICAgICBzYW1wbGVSYXRlOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKHRydWUpLFxuICAgICAgICAgICAgICBmcmFtZXNQZXJQYWNrZXQ6IDFcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNih0cnVlKTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ID0gKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkgKiB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gMTYpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZGF0YSc6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2VudER1cmF0aW9uKSB7XG4gICAgICAgICAgICAgIGJ5dGVzID0gdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4O1xuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2R1cmF0aW9uJywgdGhpcy5sZW4gLyBieXRlcyAvIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWUgLyB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlICogMTAwMCB8IDApO1xuICAgICAgICAgICAgICB0aGlzLnNlbnREdXJhdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidWZmZXIgPSB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMubGVuKTtcbiAgICAgICAgICAgIHRoaXMubGVuIC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gdGhpcy5sZW4gPiAwO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gJ2RhdGEnKSB7XG4gICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBXQVZFRGVtdXhlcjtcblxuICB9KShEZW11eGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEF1ZGlvRGV2aWNlLCBFdmVudEVtaXR0ZXIsXG4gICAgX19iaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgQXVkaW9EZXZpY2UgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgdmFyIGRldmljZXM7XG5cbiAgICBfX2V4dGVuZHMoQXVkaW9EZXZpY2UsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBBdWRpb0RldmljZShzYW1wbGVSYXRlLCBjaGFubmVscykge1xuICAgICAgdGhpcy5zYW1wbGVSYXRlID0gc2FtcGxlUmF0ZTtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVscztcbiAgICAgIHRoaXMudXBkYXRlVGltZSA9IF9fYmluZCh0aGlzLnVwZGF0ZVRpbWUsIHRoaXMpO1xuICAgICAgdGhpcy5wbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gMDtcbiAgICAgIHRoaXMuX2xhc3RUaW1lID0gMDtcbiAgICB9XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gdHJ1ZTtcbiAgICAgIGlmICh0aGlzLmRldmljZSA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuZGV2aWNlID0gQXVkaW9EZXZpY2UuY3JlYXRlKHRoaXMuc2FtcGxlUmF0ZSwgdGhpcy5jaGFubmVscyk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuZGV2aWNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHN1cHBvcnRlZCBhdWRpbyBkZXZpY2UgZm91bmQuXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5fbGFzdFRpbWUgPSB0aGlzLmRldmljZS5nZXREZXZpY2VUaW1lKCk7XG4gICAgICB0aGlzLl90aW1lciA9IHNldEludGVydmFsKHRoaXMudXBkYXRlVGltZSwgMjAwKTtcbiAgICAgIHJldHVybiB0aGlzLmRldmljZS5vbigncmVmaWxsJywgdGhpcy5yZWZpbGwgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdyZWZpbGwnLCBidWZmZXIpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmRldmljZS5vZmYoJ3JlZmlsbCcsIHRoaXMucmVmaWxsKTtcbiAgICAgIHJldHVybiBjbGVhckludGVydmFsKHRoaXMuX3RpbWVyKTtcbiAgICB9O1xuXG4gICAgQXVkaW9EZXZpY2UucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBfcmVmO1xuICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICByZXR1cm4gKF9yZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCA/IF9yZWYuZGVzdHJveSgpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKGN1cnJlbnRUaW1lKSB7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICBpZiAodGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHRoaXMuX2xhc3RUaW1lID0gdGhpcy5kZXZpY2UuZ2V0RGV2aWNlVGltZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgndGltZVVwZGF0ZScsIHRoaXMuY3VycmVudFRpbWUpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUudXBkYXRlVGltZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHRpbWU7XG4gICAgICB0aW1lID0gdGhpcy5kZXZpY2UuZ2V0RGV2aWNlVGltZSgpO1xuICAgICAgdGhpcy5jdXJyZW50VGltZSArPSAodGltZSAtIHRoaXMuX2xhc3RUaW1lKSAvIHRoaXMuZGV2aWNlLnNhbXBsZVJhdGUgKiAxMDAwIHwgMDtcbiAgICAgIHRoaXMuX2xhc3RUaW1lID0gdGltZTtcbiAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3RpbWVVcGRhdGUnLCB0aGlzLmN1cnJlbnRUaW1lKTtcbiAgICB9O1xuXG4gICAgZGV2aWNlcyA9IFtdO1xuXG4gICAgQXVkaW9EZXZpY2UucmVnaXN0ZXIgPSBmdW5jdGlvbihkZXZpY2UpIHtcbiAgICAgIHJldHVybiBkZXZpY2VzLnB1c2goZGV2aWNlKTtcbiAgICB9O1xuXG4gICAgQXVkaW9EZXZpY2UuY3JlYXRlID0gZnVuY3Rpb24oc2FtcGxlUmF0ZSwgY2hhbm5lbHMpIHtcbiAgICAgIHZhciBkZXZpY2UsIF9pLCBfbGVuO1xuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBkZXZpY2VzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGRldmljZSA9IGRldmljZXNbX2ldO1xuICAgICAgICBpZiAoZGV2aWNlLnN1cHBvcnRlZCkge1xuICAgICAgICAgIHJldHVybiBuZXcgZGV2aWNlKHNhbXBsZVJhdGUsIGNoYW5uZWxzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIHJldHVybiBBdWRpb0RldmljZTtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQXVkaW9EZXZpY2U7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBVkJ1ZmZlciwgQXVkaW9EZXZpY2UsIEV2ZW50RW1pdHRlciwgTW96aWxsYUF1ZGlvRGV2aWNlLFxuICAgIF9fYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgX19oYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgX19leHRlbmRzID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChfX2hhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH07XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi4vY29yZS9ldmVudHMnKTtcblxuICBBdWRpb0RldmljZSA9IHJlcXVpcmUoJy4uL2RldmljZScpO1xuXG4gIEFWQnVmZmVyID0gcmVxdWlyZSgnLi4vY29yZS9idWZmZXInKTtcblxuICBNb3ppbGxhQXVkaW9EZXZpY2UgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgdmFyIGNyZWF0ZVRpbWVyLCBkZXN0cm95VGltZXI7XG5cbiAgICBfX2V4dGVuZHMoTW96aWxsYUF1ZGlvRGV2aWNlLCBfc3VwZXIpO1xuXG4gICAgQXVkaW9EZXZpY2UucmVnaXN0ZXIoTW96aWxsYUF1ZGlvRGV2aWNlKTtcblxuICAgIE1vemlsbGFBdWRpb0RldmljZS5zdXBwb3J0ZWQgPSAodHlwZW9mIEF1ZGlvICE9PSBcInVuZGVmaW5lZFwiICYmIEF1ZGlvICE9PSBudWxsKSAmJiAnbW96V3JpdGVBdWRpbycgaW4gbmV3IEF1ZGlvO1xuXG4gICAgZnVuY3Rpb24gTW96aWxsYUF1ZGlvRGV2aWNlKHNhbXBsZVJhdGUsIGNoYW5uZWxzKSB7XG4gICAgICB0aGlzLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlO1xuICAgICAgdGhpcy5jaGFubmVscyA9IGNoYW5uZWxzO1xuICAgICAgdGhpcy5yZWZpbGwgPSBfX2JpbmQodGhpcy5yZWZpbGwsIHRoaXMpO1xuICAgICAgdGhpcy5hdWRpbyA9IG5ldyBBdWRpbztcbiAgICAgIHRoaXMuYXVkaW8ubW96U2V0dXAodGhpcy5jaGFubmVscywgdGhpcy5zYW1wbGVSYXRlKTtcbiAgICAgIHRoaXMud3JpdGVQb3NpdGlvbiA9IDA7XG4gICAgICB0aGlzLnByZWJ1ZmZlclNpemUgPSB0aGlzLnNhbXBsZVJhdGUgLyAyO1xuICAgICAgdGhpcy50YWlsID0gbnVsbDtcbiAgICAgIHRoaXMudGltZXIgPSBjcmVhdGVUaW1lcih0aGlzLnJlZmlsbCwgMTAwKTtcbiAgICB9XG5cbiAgICBNb3ppbGxhQXVkaW9EZXZpY2UucHJvdG90eXBlLnJlZmlsbCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGF2YWlsYWJsZSwgYnVmZmVyLCBjdXJyZW50UG9zaXRpb24sIHdyaXR0ZW47XG4gICAgICBpZiAodGhpcy50YWlsKSB7XG4gICAgICAgIHdyaXR0ZW4gPSB0aGlzLmF1ZGlvLm1veldyaXRlQXVkaW8odGhpcy50YWlsKTtcbiAgICAgICAgdGhpcy53cml0ZVBvc2l0aW9uICs9IHdyaXR0ZW47XG4gICAgICAgIGlmICh0aGlzLndyaXRlUG9zaXRpb24gPCB0aGlzLnRhaWwubGVuZ3RoKSB7XG4gICAgICAgICAgdGhpcy50YWlsID0gdGhpcy50YWlsLnN1YmFycmF5KHdyaXR0ZW4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMudGFpbCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGN1cnJlbnRQb3NpdGlvbiA9IHRoaXMuYXVkaW8ubW96Q3VycmVudFNhbXBsZU9mZnNldCgpO1xuICAgICAgYXZhaWxhYmxlID0gY3VycmVudFBvc2l0aW9uICsgdGhpcy5wcmVidWZmZXJTaXplIC0gdGhpcy53cml0ZVBvc2l0aW9uO1xuICAgICAgaWYgKGF2YWlsYWJsZSA+IDApIHtcbiAgICAgICAgYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShhdmFpbGFibGUpO1xuICAgICAgICB0aGlzLmVtaXQoJ3JlZmlsbCcsIGJ1ZmZlcik7XG4gICAgICAgIHdyaXR0ZW4gPSB0aGlzLmF1ZGlvLm1veldyaXRlQXVkaW8oYnVmZmVyKTtcbiAgICAgICAgaWYgKHdyaXR0ZW4gPCBidWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgdGhpcy50YWlsID0gYnVmZmVyLnN1YmFycmF5KHdyaXR0ZW4pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud3JpdGVQb3NpdGlvbiArPSB3cml0dGVuO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBNb3ppbGxhQXVkaW9EZXZpY2UucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkZXN0cm95VGltZXIodGhpcy50aW1lcik7XG4gICAgfTtcblxuICAgIE1vemlsbGFBdWRpb0RldmljZS5wcm90b3R5cGUuZ2V0RGV2aWNlVGltZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuYXVkaW8ubW96Q3VycmVudFNhbXBsZU9mZnNldCgpIC8gdGhpcy5jaGFubmVscztcbiAgICB9O1xuXG4gICAgY3JlYXRlVGltZXIgPSBmdW5jdGlvbihmbiwgaW50ZXJ2YWwpIHtcbiAgICAgIHZhciB1cmwsIHdvcmtlcjtcbiAgICAgIHVybCA9IEFWQnVmZmVyLm1ha2VCbG9iVVJMKFwic2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7IHBvc3RNZXNzYWdlKCdwaW5nJyk7IH0sIFwiICsgaW50ZXJ2YWwgKyBcIik7XCIpO1xuICAgICAgaWYgKHVybCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBzZXRJbnRlcnZhbChmbiwgaW50ZXJ2YWwpO1xuICAgICAgfVxuICAgICAgd29ya2VyID0gbmV3IFdvcmtlcih1cmwpO1xuICAgICAgd29ya2VyLm9ubWVzc2FnZSA9IGZuO1xuICAgICAgd29ya2VyLnVybCA9IHVybDtcbiAgICAgIHJldHVybiB3b3JrZXI7XG4gICAgfTtcblxuICAgIGRlc3Ryb3lUaW1lciA9IGZ1bmN0aW9uKHRpbWVyKSB7XG4gICAgICBpZiAodGltZXIudGVybWluYXRlKSB7XG4gICAgICAgIHRpbWVyLnRlcm1pbmF0ZSgpO1xuICAgICAgICByZXR1cm4gVVJMLnJldm9rZU9iamVjdFVSTCh0aW1lci51cmwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGNsZWFySW50ZXJ2YWwodGltZXIpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gTW96aWxsYUF1ZGlvRGV2aWNlO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvL0phdmFTY3JpcHQgQXVkaW8gUmVzYW1wbGVyXG4vL0NvcHlyaWdodCAoQykgMjAxMS0yMDE1IEdyYW50IEdhbGl0elxuLy9SZWxlYXNlZCB0byBQdWJsaWMgRG9tYWluXG5mdW5jdGlvbiBSZXNhbXBsZXIoZnJvbVNhbXBsZVJhdGUsIHRvU2FtcGxlUmF0ZSwgY2hhbm5lbHMsIGlucHV0QnVmZmVyTGVuZ3RoKSB7XG4gIHRoaXMuZnJvbVNhbXBsZVJhdGUgPSArZnJvbVNhbXBsZVJhdGU7XG4gIHRoaXMudG9TYW1wbGVSYXRlID0gK3RvU2FtcGxlUmF0ZTtcbiAgdGhpcy5jaGFubmVscyA9IGNoYW5uZWxzIHwgMDtcbiAgdGhpcy5pbnB1dEJ1ZmZlckxlbmd0aCA9IGlucHV0QnVmZmVyTGVuZ3RoO1xuICB0aGlzLmluaXRpYWxpemUoKTtcbn1cblxuUmVzYW1wbGVyLnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24gKCkge1xuICAvL1BlcmZvcm0gc29tZSBjaGVja3M6XG4gIGlmICh0aGlzLmZyb21TYW1wbGVSYXRlID4gMCAmJiB0aGlzLnRvU2FtcGxlUmF0ZSA+IDAgJiYgdGhpcy5jaGFubmVscyA+IDApIHtcbiAgICBpZiAodGhpcy5mcm9tU2FtcGxlUmF0ZSA9PSB0aGlzLnRvU2FtcGxlUmF0ZSkge1xuICAgICAgLy9TZXR1cCBhIHJlc2FtcGxlciBieXBhc3M6XG4gICAgICB0aGlzLnJlc2FtcGxlciA9IHRoaXMuYnlwYXNzUmVzYW1wbGVyOyAgICAvL1Jlc2FtcGxlciBqdXN0IHJldHVybnMgd2hhdCB3YXMgcGFzc2VkIHRocm91Z2guXG4gICAgICB0aGlzLnJhdGlvV2VpZ2h0ID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yYXRpb1dlaWdodCA9IHRoaXMuZnJvbVNhbXBsZVJhdGUgLyB0aGlzLnRvU2FtcGxlUmF0ZTtcbiAgICAgIGlmICh0aGlzLmZyb21TYW1wbGVSYXRlIDwgdGhpcy50b1NhbXBsZVJhdGUpIHtcbiAgICAgICAgLypcbiAgICAgICAgICBVc2UgZ2VuZXJpYyBsaW5lYXIgaW50ZXJwb2xhdGlvbiBpZiB1cHNhbXBsaW5nLFxuICAgICAgICAgIGFzIGxpbmVhciBpbnRlcnBvbGF0aW9uIHByb2R1Y2VzIGEgZ3JhZGllbnQgdGhhdCB3ZSB3YW50XG4gICAgICAgICAgYW5kIHdvcmtzIGZpbmUgd2l0aCB0d28gaW5wdXQgc2FtcGxlIHBvaW50cyBwZXIgb3V0cHV0IGluIHRoaXMgY2FzZS5cbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jb21waWxlTGluZWFySW50ZXJwb2xhdGlvbkZ1bmN0aW9uKCk7XG4gICAgICAgIHRoaXMubGFzdFdlaWdodCA9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvKlxuICAgICAgICAgIEN1c3RvbSByZXNhbXBsZXIgSSB3cm90ZSB0aGF0IGRvZXNuJ3Qgc2tpcCBzYW1wbGVzXG4gICAgICAgICAgbGlrZSBzdGFuZGFyZCBsaW5lYXIgaW50ZXJwb2xhdGlvbiBpbiBoaWdoIGRvd25zYW1wbGluZy5cbiAgICAgICAgICBUaGlzIGlzIG1vcmUgYWNjdXJhdGUgdGhhbiBsaW5lYXIgaW50ZXJwb2xhdGlvbiBvbiBkb3duc2FtcGxpbmcuXG4gICAgICAgICovXG4gICAgICAgIHRoaXMuY29tcGlsZU11bHRpVGFwRnVuY3Rpb24oKTtcbiAgICAgICAgdGhpcy50YWlsRXhpc3RzID0gZmFsc2U7XG4gICAgICAgIHRoaXMubGFzdFdlaWdodCA9IDA7XG4gICAgICB9XG4gICAgICBcbiAgICAgIHZhciBvdXRwdXRCdWZmZXJTaXplID0gKE1hdGguY2VpbCh0aGlzLmlucHV0QnVmZmVyTGVuZ3RoICogdGhpcy50b1NhbXBsZVJhdGUgLyB0aGlzLmZyb21TYW1wbGVSYXRlIC8gdGhpcy5jaGFubmVscyAqIDEuMDEpICogdGhpcy5jaGFubmVscykgKyB0aGlzLmNoYW5uZWxzO1xuICAgICAgdGhpcy5vdXRwdXRCdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KG91dHB1dEJ1ZmZlclNpemUpO1xuICAgICAgdGhpcy5sYXN0T3V0cHV0ID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmNoYW5uZWxzKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cobmV3IEVycm9yKFwiSW52YWxpZCBzZXR0aW5ncyBzcGVjaWZpZWQgZm9yIHRoZSByZXNhbXBsZXIuXCIpKTtcbiAgfVxufTtcblxuUmVzYW1wbGVyLnByb3RvdHlwZS5jb21waWxlTGluZWFySW50ZXJwb2xhdGlvbkZ1bmN0aW9uID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdG9Db21waWxlID0gXCJ2YXIgb3V0cHV0T2Zmc2V0ID0gMDtcXFxuICAgIHZhciBidWZmZXJMZW5ndGggPSBidWZmZXIubGVuZ3RoO1xcXG4gICAgaWYgKGJ1ZmZlckxlbmd0aCA+IDApIHtcXFxuICAgICAgdmFyIHdlaWdodCA9IHRoaXMubGFzdFdlaWdodDtcXFxuICAgICAgdmFyIGZpcnN0V2VpZ2h0ID0gMDtcXFxuICAgICAgdmFyIHNlY29uZFdlaWdodCA9IDA7XFxcbiAgICAgIHZhciBzb3VyY2VPZmZzZXQgPSAwO1xcXG4gICAgICB2YXIgb3V0cHV0T2Zmc2V0ID0gMDtcXFxuICAgICAgdmFyIG91dHB1dEJ1ZmZlciA9IHRoaXMub3V0cHV0QnVmZmVyO1xcXG4gICAgICBmb3IgKDsgd2VpZ2h0IDwgMTsgd2VpZ2h0ICs9IFwiICsgdGhpcy5yYXRpb1dlaWdodCArIFwiKSB7XFxcbiAgICAgICAgc2Vjb25kV2VpZ2h0ID0gd2VpZ2h0ICUgMTtcXFxuICAgICAgICBmaXJzdFdlaWdodCA9IDEgLSBzZWNvbmRXZWlnaHQ7XCI7XG4gICAgICAgIGZvciAodmFyIGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0QnVmZmVyW291dHB1dE9mZnNldCsrXSA9ICh0aGlzLmxhc3RPdXRwdXRbXCIgKyBjaGFubmVsICsgXCJdICogZmlyc3RXZWlnaHQpICsgKGJ1ZmZlcltcIiArIGNoYW5uZWwgKyBcIl0gKiBzZWNvbmRXZWlnaHQpO1wiO1xuICAgICAgICB9XG4gICAgICB0b0NvbXBpbGUgKz0gXCJ9XFxcbiAgICAgIHdlaWdodCAtPSAxO1xcXG4gICAgICBmb3IgKGJ1ZmZlckxlbmd0aCAtPSBcIiArIHRoaXMuY2hhbm5lbHMgKyBcIiwgc291cmNlT2Zmc2V0ID0gTWF0aC5mbG9vcih3ZWlnaHQpICogXCIgKyB0aGlzLmNoYW5uZWxzICsgXCI7IHNvdXJjZU9mZnNldCA8IGJ1ZmZlckxlbmd0aDspIHtcXFxuICAgICAgICBzZWNvbmRXZWlnaHQgPSB3ZWlnaHQgJSAxO1xcXG4gICAgICAgIGZpcnN0V2VpZ2h0ID0gMSAtIHNlY29uZFdlaWdodDtcIjtcbiAgICAgICAgZm9yICh2YXIgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRCdWZmZXJbb3V0cHV0T2Zmc2V0KytdID0gKGJ1ZmZlcltzb3VyY2VPZmZzZXRcIiArICgoY2hhbm5lbCA+IDApID8gKFwiICsgXCIgKyBjaGFubmVsKSA6IFwiXCIpICsgXCJdICogZmlyc3RXZWlnaHQpICsgKGJ1ZmZlcltzb3VyY2VPZmZzZXQgKyBcIiArICh0aGlzLmNoYW5uZWxzICsgY2hhbm5lbCkgKyBcIl0gKiBzZWNvbmRXZWlnaHQpO1wiO1xuICAgICAgICB9XG4gICAgICAgIHRvQ29tcGlsZSArPSBcIndlaWdodCArPSBcIiArIHRoaXMucmF0aW9XZWlnaHQgKyBcIjtcXFxuICAgICAgICBzb3VyY2VPZmZzZXQgPSBNYXRoLmZsb29yKHdlaWdodCkgKiBcIiArIHRoaXMuY2hhbm5lbHMgKyBcIjtcXFxuICAgICAgfVwiO1xuICAgICAgZm9yICh2YXIgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgdG9Db21waWxlICs9IFwidGhpcy5sYXN0T3V0cHV0W1wiICsgY2hhbm5lbCArIFwiXSA9IGJ1ZmZlcltzb3VyY2VPZmZzZXQrK107XCI7XG4gICAgICB9XG4gICAgICB0b0NvbXBpbGUgKz0gXCJ0aGlzLmxhc3RXZWlnaHQgPSB3ZWlnaHQgJSAxO1xcXG4gICAgfVxcXG4gICAgcmV0dXJuIHRoaXMub3V0cHV0QnVmZmVyO1wiO1xuICAgIFxuICB0aGlzLnJlc2FtcGxlciA9IEZ1bmN0aW9uKFwiYnVmZmVyXCIsIHRvQ29tcGlsZSk7XG59O1xuXG5SZXNhbXBsZXIucHJvdG90eXBlLmNvbXBpbGVNdWx0aVRhcEZ1bmN0aW9uID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdG9Db21waWxlID0gXCJ2YXIgb3V0cHV0T2Zmc2V0ID0gMDtcXFxuICAgIHZhciBidWZmZXJMZW5ndGggPSBidWZmZXIubGVuZ3RoO1xcXG4gICAgaWYgKGJ1ZmZlckxlbmd0aCA+IDApIHtcXFxuICAgICAgdmFyIHdlaWdodCA9IDA7XCI7XG4gICAgICBmb3IgKHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICB0b0NvbXBpbGUgKz0gXCJ2YXIgb3V0cHV0XCIgKyBjaGFubmVsICsgXCIgPSAwO1wiXG4gICAgICB9XG4gICAgICB0b0NvbXBpbGUgKz0gXCJ2YXIgYWN0dWFsUG9zaXRpb24gPSAwO1xcXG4gICAgICB2YXIgYW1vdW50VG9OZXh0ID0gMDtcXFxuICAgICAgdmFyIGFscmVhZHlQcm9jZXNzZWRUYWlsID0gIXRoaXMudGFpbEV4aXN0cztcXFxuICAgICAgdGhpcy50YWlsRXhpc3RzID0gZmFsc2U7XFxcbiAgICAgIHZhciBvdXRwdXRCdWZmZXIgPSB0aGlzLm91dHB1dEJ1ZmZlcjtcXFxuICAgICAgdmFyIGN1cnJlbnRQb3NpdGlvbiA9IDA7XFxcbiAgICAgIGRvIHtcXFxuICAgICAgICBpZiAoYWxyZWFkeVByb2Nlc3NlZFRhaWwpIHtcXFxuICAgICAgICAgIHdlaWdodCA9IFwiICsgdGhpcy5yYXRpb1dlaWdodCArIFwiO1wiO1xuICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dFwiICsgY2hhbm5lbCArIFwiID0gMDtcIlxuICAgICAgICAgIH1cbiAgICAgICAgdG9Db21waWxlICs9IFwifVxcXG4gICAgICAgIGVsc2Uge1xcXG4gICAgICAgICAgd2VpZ2h0ID0gdGhpcy5sYXN0V2VpZ2h0O1wiO1xuICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dFwiICsgY2hhbm5lbCArIFwiID0gdGhpcy5sYXN0T3V0cHV0W1wiICsgY2hhbm5lbCArIFwiXTtcIlxuICAgICAgICAgIH1cbiAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJhbHJlYWR5UHJvY2Vzc2VkVGFpbCA9IHRydWU7XFxcbiAgICAgICAgfVxcXG4gICAgICAgIHdoaWxlICh3ZWlnaHQgPiAwICYmIGFjdHVhbFBvc2l0aW9uIDwgYnVmZmVyTGVuZ3RoKSB7XFxcbiAgICAgICAgICBhbW91bnRUb05leHQgPSAxICsgYWN0dWFsUG9zaXRpb24gLSBjdXJyZW50UG9zaXRpb247XFxcbiAgICAgICAgICBpZiAod2VpZ2h0ID49IGFtb3VudFRvTmV4dCkge1wiO1xuICAgICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiArPSBidWZmZXJbYWN0dWFsUG9zaXRpb24rK10gKiBhbW91bnRUb05leHQ7XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcImN1cnJlbnRQb3NpdGlvbiA9IGFjdHVhbFBvc2l0aW9uO1xcXG4gICAgICAgICAgICB3ZWlnaHQgLT0gYW1vdW50VG9OZXh0O1xcXG4gICAgICAgICAgfVxcXG4gICAgICAgICAgZWxzZSB7XCI7XG4gICAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dFwiICsgY2hhbm5lbCArIFwiICs9IGJ1ZmZlclthY3R1YWxQb3NpdGlvblwiICsgKChjaGFubmVsID4gMCkgPyAoXCIgKyBcIiArIGNoYW5uZWwpIDogXCJcIikgKyBcIl0gKiB3ZWlnaHQ7XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcImN1cnJlbnRQb3NpdGlvbiArPSB3ZWlnaHQ7XFxcbiAgICAgICAgICAgIHdlaWdodCA9IDA7XFxcbiAgICAgICAgICAgIGJyZWFrO1xcXG4gICAgICAgICAgfVxcXG4gICAgICAgIH1cXFxuICAgICAgICBpZiAod2VpZ2h0IDw9IDApIHtcIjtcbiAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRCdWZmZXJbb3V0cHV0T2Zmc2V0KytdID0gb3V0cHV0XCIgKyBjaGFubmVsICsgXCIgLyBcIiArIHRoaXMucmF0aW9XZWlnaHQgKyBcIjtcIlxuICAgICAgICAgIH1cbiAgICAgICAgdG9Db21waWxlICs9IFwifVxcXG4gICAgICAgIGVsc2Uge1xcXG4gICAgICAgICAgdGhpcy5sYXN0V2VpZ2h0ID0gd2VpZ2h0O1wiO1xuICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcInRoaXMubGFzdE91dHB1dFtcIiArIGNoYW5uZWwgKyBcIl0gPSBvdXRwdXRcIiArIGNoYW5uZWwgKyBcIjtcIlxuICAgICAgICAgIH1cbiAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJ0aGlzLnRhaWxFeGlzdHMgPSB0cnVlO1xcXG4gICAgICAgICAgYnJlYWs7XFxcbiAgICAgICAgfVxcXG4gICAgICB9IHdoaWxlIChhY3R1YWxQb3NpdGlvbiA8IGJ1ZmZlckxlbmd0aCk7XFxcbiAgICB9XFxcbiAgICByZXR1cm4gdGhpcy5vdXRwdXRCdWZmZXI7XCI7XG4gIFxuICB0aGlzLnJlc2FtcGxlciA9IEZ1bmN0aW9uKFwiYnVmZmVyXCIsIHRvQ29tcGlsZSk7XG59O1xuXG5SZXNhbXBsZXIucHJvdG90eXBlLmJ5cGFzc1Jlc2FtcGxlciA9IGZ1bmN0aW9uIChpbnB1dEJ1ZmZlcikge1xuICByZXR1cm4gaW5wdXRCdWZmZXI7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlc2FtcGxlcjtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEF1ZGlvRGV2aWNlLCBFdmVudEVtaXR0ZXIsIFJlc2FtcGxlciwgV2ViQXVkaW9EZXZpY2UsXG4gICAgX19iaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuLi9jb3JlL2V2ZW50cycpO1xuXG4gIEF1ZGlvRGV2aWNlID0gcmVxdWlyZSgnLi4vZGV2aWNlJyk7XG5cbiAgUmVzYW1wbGVyID0gcmVxdWlyZSgnLi9yZXNhbXBsZXInKTtcblxuICBXZWJBdWRpb0RldmljZSA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICB2YXIgQXVkaW9Db250ZXh0LCBjcmVhdGVQcm9jZXNzb3IsIHNoYXJlZENvbnRleHQ7XG5cbiAgICBfX2V4dGVuZHMoV2ViQXVkaW9EZXZpY2UsIF9zdXBlcik7XG5cbiAgICBBdWRpb0RldmljZS5yZWdpc3RlcihXZWJBdWRpb0RldmljZSk7XG5cbiAgICBBdWRpb0NvbnRleHQgPSBnbG9iYWwuQXVkaW9Db250ZXh0IHx8IGdsb2JhbC53ZWJraXRBdWRpb0NvbnRleHQ7XG5cbiAgICBXZWJBdWRpb0RldmljZS5zdXBwb3J0ZWQgPSBBdWRpb0NvbnRleHQgJiYgKHR5cGVvZiBBdWRpb0NvbnRleHQucHJvdG90eXBlW2NyZWF0ZVByb2Nlc3NvciA9ICdjcmVhdGVTY3JpcHRQcm9jZXNzb3InXSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgQXVkaW9Db250ZXh0LnByb3RvdHlwZVtjcmVhdGVQcm9jZXNzb3IgPSAnY3JlYXRlSmF2YVNjcmlwdE5vZGUnXSA9PT0gJ2Z1bmN0aW9uJyk7XG5cbiAgICBzaGFyZWRDb250ZXh0ID0gbnVsbDtcblxuICAgIGZ1bmN0aW9uIFdlYkF1ZGlvRGV2aWNlKHNhbXBsZVJhdGUsIGNoYW5uZWxzKSB7XG4gICAgICB0aGlzLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlO1xuICAgICAgdGhpcy5jaGFubmVscyA9IGNoYW5uZWxzO1xuICAgICAgdGhpcy5yZWZpbGwgPSBfX2JpbmQodGhpcy5yZWZpbGwsIHRoaXMpO1xuICAgICAgdGhpcy5jb250ZXh0ID0gc2hhcmVkQ29udGV4dCAhPSBudWxsID8gc2hhcmVkQ29udGV4dCA6IHNoYXJlZENvbnRleHQgPSBuZXcgQXVkaW9Db250ZXh0O1xuICAgICAgdGhpcy5kZXZpY2VTYW1wbGVSYXRlID0gdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICB0aGlzLmJ1ZmZlclNpemUgPSBNYXRoLmNlaWwoNDA5NiAvICh0aGlzLmRldmljZVNhbXBsZVJhdGUgLyB0aGlzLnNhbXBsZVJhdGUpICogdGhpcy5jaGFubmVscyk7XG4gICAgICB0aGlzLmJ1ZmZlclNpemUgKz0gdGhpcy5idWZmZXJTaXplICUgdGhpcy5jaGFubmVscztcbiAgICAgIGlmICh0aGlzLmRldmljZVNhbXBsZVJhdGUgIT09IHRoaXMuc2FtcGxlUmF0ZSkge1xuICAgICAgICB0aGlzLnJlc2FtcGxlciA9IG5ldyBSZXNhbXBsZXIodGhpcy5zYW1wbGVSYXRlLCB0aGlzLmRldmljZVNhbXBsZVJhdGUsIHRoaXMuY2hhbm5lbHMsIHRoaXMuYnVmZmVyU2l6ZSk7XG4gICAgICB9XG4gICAgICB0aGlzLm5vZGUgPSB0aGlzLmNvbnRleHRbY3JlYXRlUHJvY2Vzc29yXSg0MDk2LCB0aGlzLmNoYW5uZWxzLCB0aGlzLmNoYW5uZWxzKTtcbiAgICAgIHRoaXMubm9kZS5vbmF1ZGlvcHJvY2VzcyA9IHRoaXMucmVmaWxsO1xuICAgICAgdGhpcy5ub2RlLmNvbm5lY3QodGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICB9XG5cbiAgICBXZWJBdWRpb0RldmljZS5wcm90b3R5cGUucmVmaWxsID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgIHZhciBjaGFubmVsQ291bnQsIGNoYW5uZWxzLCBkYXRhLCBpLCBuLCBvdXRwdXRCdWZmZXIsIF9pLCBfaiwgX2ssIF9yZWY7XG4gICAgICBvdXRwdXRCdWZmZXIgPSBldmVudC5vdXRwdXRCdWZmZXI7XG4gICAgICBjaGFubmVsQ291bnQgPSBvdXRwdXRCdWZmZXIubnVtYmVyT2ZDaGFubmVscztcbiAgICAgIGNoYW5uZWxzID0gbmV3IEFycmF5KGNoYW5uZWxDb3VudCk7XG4gICAgICBmb3IgKGkgPSBfaSA9IDA7IF9pIDwgY2hhbm5lbENvdW50OyBpID0gX2kgKz0gMSkge1xuICAgICAgICBjaGFubmVsc1tpXSA9IG91dHB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgIH1cbiAgICAgIGRhdGEgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYnVmZmVyU2l6ZSk7XG4gICAgICB0aGlzLmVtaXQoJ3JlZmlsbCcsIGRhdGEpO1xuICAgICAgaWYgKHRoaXMucmVzYW1wbGVyKSB7XG4gICAgICAgIGRhdGEgPSB0aGlzLnJlc2FtcGxlci5yZXNhbXBsZXIoZGF0YSk7XG4gICAgICB9XG4gICAgICBmb3IgKGkgPSBfaiA9IDAsIF9yZWYgPSBvdXRwdXRCdWZmZXIubGVuZ3RoOyBfaiA8IF9yZWY7IGkgPSBfaiArPSAxKSB7XG4gICAgICAgIGZvciAobiA9IF9rID0gMDsgX2sgPCBjaGFubmVsQ291bnQ7IG4gPSBfayArPSAxKSB7XG4gICAgICAgICAgY2hhbm5lbHNbbl1baV0gPSBkYXRhW2kgKiBjaGFubmVsQ291bnQgKyBuXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBXZWJBdWRpb0RldmljZS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMubm9kZS5kaXNjb25uZWN0KDApO1xuICAgIH07XG5cbiAgICBXZWJBdWRpb0RldmljZS5wcm90b3R5cGUuZ2V0RGV2aWNlVGltZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSAqIHRoaXMuc2FtcGxlUmF0ZTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFdlYkF1ZGlvRGV2aWNlO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBGaWx0ZXI7XG5cbiAgRmlsdGVyID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIEZpbHRlcihjb250ZXh0LCBrZXkpIHtcbiAgICAgIGlmIChjb250ZXh0ICYmIGtleSkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3ZhbHVlJywge1xuICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dFtrZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgRmlsdGVyLnByb3RvdHlwZS5wcm9jZXNzID0gZnVuY3Rpb24oYnVmZmVyKSB7fTtcblxuICAgIHJldHVybiBGaWx0ZXI7XG5cbiAgfSkoKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEZpbHRlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJhbGFuY2VGaWx0ZXIsIEZpbHRlcixcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBGaWx0ZXIgPSByZXF1aXJlKCcuLi9maWx0ZXInKTtcblxuICBCYWxhbmNlRmlsdGVyID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhCYWxhbmNlRmlsdGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gQmFsYW5jZUZpbHRlcigpIHtcbiAgICAgIHJldHVybiBCYWxhbmNlRmlsdGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIEJhbGFuY2VGaWx0ZXIucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciBpLCBwYW4sIF9pLCBfcmVmO1xuICAgICAgaWYgKHRoaXMudmFsdWUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcGFuID0gTWF0aC5tYXgoLTUwLCBNYXRoLm1pbig1MCwgdGhpcy52YWx1ZSkpO1xuICAgICAgZm9yIChpID0gX2kgPSAwLCBfcmVmID0gYnVmZmVyLmxlbmd0aDsgX2kgPCBfcmVmOyBpID0gX2kgKz0gMikge1xuICAgICAgICBidWZmZXJbaV0gKj0gTWF0aC5taW4oMSwgKDUwIC0gcGFuKSAvIDUwKTtcbiAgICAgICAgYnVmZmVyW2kgKyAxXSAqPSBNYXRoLm1pbigxLCAoNTAgKyBwYW4pIC8gNTApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQmFsYW5jZUZpbHRlcjtcblxuICB9KShGaWx0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQmFsYW5jZUZpbHRlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEZpbHRlciwgVm9sdW1lRmlsdGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIEZpbHRlciA9IHJlcXVpcmUoJy4uL2ZpbHRlcicpO1xuXG4gIFZvbHVtZUZpbHRlciA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVm9sdW1lRmlsdGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gVm9sdW1lRmlsdGVyKCkge1xuICAgICAgcmV0dXJuIFZvbHVtZUZpbHRlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBWb2x1bWVGaWx0ZXIucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciBpLCB2b2wsIF9pLCBfcmVmO1xuICAgICAgaWYgKHRoaXMudmFsdWUgPj0gMTAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZvbCA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEwMCwgdGhpcy52YWx1ZSkpIC8gMTAwO1xuICAgICAgZm9yIChpID0gX2kgPSAwLCBfcmVmID0gYnVmZmVyLmxlbmd0aDsgX2kgPCBfcmVmOyBpID0gX2kgKz0gMSkge1xuICAgICAgICBidWZmZXJbaV0gKj0gdm9sO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gVm9sdW1lRmlsdGVyO1xuXG4gIH0pKEZpbHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBWb2x1bWVGaWx0ZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBc3NldCwgQXVkaW9EZXZpY2UsIEJhbGFuY2VGaWx0ZXIsIEV2ZW50RW1pdHRlciwgUGxheWVyLCBRdWV1ZSwgVm9sdW1lRmlsdGVyLFxuICAgIF9fYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgX19oYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgX19leHRlbmRzID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChfX2hhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH07XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIEFzc2V0ID0gcmVxdWlyZSgnLi9hc3NldCcpO1xuXG4gIFZvbHVtZUZpbHRlciA9IHJlcXVpcmUoJy4vZmlsdGVycy92b2x1bWUnKTtcblxuICBCYWxhbmNlRmlsdGVyID0gcmVxdWlyZSgnLi9maWx0ZXJzL2JhbGFuY2UnKTtcblxuICBRdWV1ZSA9IHJlcXVpcmUoJy4vcXVldWUnKTtcblxuICBBdWRpb0RldmljZSA9IHJlcXVpcmUoJy4vZGV2aWNlJyk7XG5cbiAgUGxheWVyID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhQbGF5ZXIsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBQbGF5ZXIoYXNzZXQpIHtcbiAgICAgIHRoaXMuYXNzZXQgPSBhc3NldDtcbiAgICAgIHRoaXMuc3RhcnRQbGF5aW5nID0gX19iaW5kKHRoaXMuc3RhcnRQbGF5aW5nLCB0aGlzKTtcbiAgICAgIHRoaXMucGxheWluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5idWZmZXJlZCA9IDA7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gMDtcbiAgICAgIHRoaXMuZHVyYXRpb24gPSAwO1xuICAgICAgdGhpcy52b2x1bWUgPSAxMDA7XG4gICAgICB0aGlzLnBhbiA9IDA7XG4gICAgICB0aGlzLm1ldGFkYXRhID0ge307XG4gICAgICB0aGlzLmZpbHRlcnMgPSBbbmV3IFZvbHVtZUZpbHRlcih0aGlzLCAndm9sdW1lJyksIG5ldyBCYWxhbmNlRmlsdGVyKHRoaXMsICdwYW4nKV07XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdidWZmZXInLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcmVkKSB7XG4gICAgICAgICAgX3RoaXMuYnVmZmVyZWQgPSBidWZmZXJlZDtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnYnVmZmVyJywgX3RoaXMuYnVmZmVyZWQpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5vbignZGVjb2RlU3RhcnQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIF90aGlzLnF1ZXVlID0gbmV3IFF1ZXVlKF90aGlzLmFzc2V0KTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMucXVldWUub25jZSgncmVhZHknLCBfdGhpcy5zdGFydFBsYXlpbmcpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5vbignZm9ybWF0JywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgICAgICBfdGhpcy5mb3JtYXQgPSBmb3JtYXQ7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Zvcm1hdCcsIF90aGlzLmZvcm1hdCk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdtZXRhZGF0YScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24obWV0YWRhdGEpIHtcbiAgICAgICAgICBfdGhpcy5tZXRhZGF0YSA9IG1ldGFkYXRhO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdtZXRhZGF0YScsIF90aGlzLm1ldGFkYXRhKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ2R1cmF0aW9uJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihkdXJhdGlvbikge1xuICAgICAgICAgIF90aGlzLmR1cmF0aW9uID0gZHVyYXRpb247XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2R1cmF0aW9uJywgX3RoaXMuZHVyYXRpb24pO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5vbignZXJyb3InLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyb3IpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH1cblxuICAgIFBsYXllci5mcm9tVVJMID0gZnVuY3Rpb24odXJsLCBvcHRzKSB7XG4gICAgICByZXR1cm4gbmV3IFBsYXllcihBc3NldC5mcm9tVVJMKHVybCwgb3B0cykpO1xuICAgIH07XG5cbiAgICBQbGF5ZXIuZnJvbUZpbGUgPSBmdW5jdGlvbihmaWxlKSB7XG4gICAgICByZXR1cm4gbmV3IFBsYXllcihBc3NldC5mcm9tRmlsZShmaWxlKSk7XG4gICAgfTtcblxuICAgIFBsYXllci5mcm9tQnVmZmVyID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICByZXR1cm4gbmV3IFBsYXllcihBc3NldC5mcm9tQnVmZmVyKGJ1ZmZlcikpO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnByZWxvYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghdGhpcy5hc3NldCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnN0YXJ0ZWRQcmVsb2FkaW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzLmFzc2V0LnN0YXJ0KGZhbHNlKTtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5wbGF5ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX3JlZjtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLnN0YXJ0ZWRQcmVsb2FkaW5nKSB7XG4gICAgICAgIHRoaXMucHJlbG9hZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiAoX3JlZiA9IHRoaXMuZGV2aWNlKSAhPSBudWxsID8gX3JlZi5zdGFydCgpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX3JlZjtcbiAgICAgIGlmICghdGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMucGxheWluZyA9IGZhbHNlO1xuICAgICAgcmV0dXJuIChfcmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwgPyBfcmVmLnN0b3AoKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS50b2dnbGVQbGF5YmFjayA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMucGxheWluZykge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXVzZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGxheSgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBfcmVmO1xuICAgICAgdGhpcy5wYXVzZSgpO1xuICAgICAgdGhpcy5hc3NldC5zdG9wKCk7XG4gICAgICByZXR1cm4gKF9yZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCA/IF9yZWYuZGVzdHJveSgpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbih0aW1lc3RhbXApIHtcbiAgICAgIHZhciBfcmVmO1xuICAgICAgaWYgKChfcmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwpIHtcbiAgICAgICAgX3JlZi5zdG9wKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnF1ZXVlLm9uY2UoJ3JlYWR5JywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgX3JlZjEsIF9yZWYyO1xuICAgICAgICAgIGlmICgoX3JlZjEgPSBfdGhpcy5kZXZpY2UpICE9IG51bGwpIHtcbiAgICAgICAgICAgIF9yZWYxLnNlZWsoX3RoaXMuY3VycmVudFRpbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoX3RoaXMucGxheWluZykge1xuICAgICAgICAgICAgcmV0dXJuIChfcmVmMiA9IF90aGlzLmRldmljZSkgIT0gbnVsbCA/IF9yZWYyLnN0YXJ0KCkgOiB2b2lkIDA7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGltZXN0YW1wID0gKHRpbWVzdGFtcCAvIDEwMDApICogdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZTtcbiAgICAgIHRpbWVzdGFtcCA9IHRoaXMuYXNzZXQuZGVjb2Rlci5zZWVrKHRpbWVzdGFtcCk7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gdGltZXN0YW1wIC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwO1xuICAgICAgdGhpcy5xdWV1ZS5yZXNldCgpO1xuICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFRpbWU7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUuc3RhcnRQbGF5aW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZnJhbWUsIGZyYW1lT2Zmc2V0O1xuICAgICAgZnJhbWUgPSB0aGlzLnF1ZXVlLnJlYWQoKTtcbiAgICAgIGZyYW1lT2Zmc2V0ID0gMDtcbiAgICAgIHRoaXMuZGV2aWNlID0gbmV3IEF1ZGlvRGV2aWNlKHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUsIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWUpO1xuICAgICAgdGhpcy5kZXZpY2Uub24oJ3RpbWVVcGRhdGUnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGN1cnJlbnRUaW1lKSB7XG4gICAgICAgICAgX3RoaXMuY3VycmVudFRpbWUgPSBjdXJyZW50VGltZTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgncHJvZ3Jlc3MnLCBfdGhpcy5jdXJyZW50VGltZSk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLnJlZmlsbCA9IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICAgICAgdmFyIGJ1ZmZlck9mZnNldCwgZmlsdGVyLCBpLCBtYXgsIF9pLCBfaiwgX2xlbiwgX3JlZjtcbiAgICAgICAgICBpZiAoIV90aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFmcmFtZSkge1xuICAgICAgICAgICAgZnJhbWUgPSBfdGhpcy5xdWV1ZS5yZWFkKCk7XG4gICAgICAgICAgICBmcmFtZU9mZnNldCA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJ1ZmZlck9mZnNldCA9IDA7XG4gICAgICAgICAgd2hpbGUgKGZyYW1lICYmIGJ1ZmZlck9mZnNldCA8IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgIG1heCA9IE1hdGgubWluKGZyYW1lLmxlbmd0aCAtIGZyYW1lT2Zmc2V0LCBidWZmZXIubGVuZ3RoIC0gYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCBtYXg7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgICAgICAgIGJ1ZmZlcltidWZmZXJPZmZzZXQrK10gPSBmcmFtZVtmcmFtZU9mZnNldCsrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmcmFtZU9mZnNldCA9PT0gZnJhbWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGZyYW1lID0gX3RoaXMucXVldWUucmVhZCgpO1xuICAgICAgICAgICAgICBmcmFtZU9mZnNldCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIF9yZWYgPSBfdGhpcy5maWx0ZXJzO1xuICAgICAgICAgIGZvciAoX2ogPSAwLCBfbGVuID0gX3JlZi5sZW5ndGg7IF9qIDwgX2xlbjsgX2orKykge1xuICAgICAgICAgICAgZmlsdGVyID0gX3JlZltfal07XG4gICAgICAgICAgICBmaWx0ZXIucHJvY2VzcyhidWZmZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWZyYW1lKSB7XG4gICAgICAgICAgICBpZiAoX3RoaXMucXVldWUuZW5kZWQpIHtcbiAgICAgICAgICAgICAgX3RoaXMuY3VycmVudFRpbWUgPSBfdGhpcy5kdXJhdGlvbjtcbiAgICAgICAgICAgICAgX3RoaXMuZW1pdCgncHJvZ3Jlc3MnLCBfdGhpcy5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgIF90aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgICAgICAgICBfdGhpcy5zdG9wKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBfdGhpcy5kZXZpY2Uuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpO1xuICAgICAgdGhpcy5kZXZpY2Uub24oJ3JlZmlsbCcsIHRoaXMucmVmaWxsKTtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgdGhpcy5kZXZpY2Uuc3RhcnQoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIF9yZWYsIF9yZWYxO1xuICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICBpZiAoKF9yZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCkge1xuICAgICAgICBfcmVmLm9mZigpO1xuICAgICAgfVxuICAgICAgaWYgKChfcmVmMSA9IHRoaXMuYXNzZXQpICE9IG51bGwpIHtcbiAgICAgICAgX3JlZjEuZGVzdHJveSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMub2ZmKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBQbGF5ZXI7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFBsYXllcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEV2ZW50RW1pdHRlciwgUXVldWUsXG4gICAgX19iaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgUXVldWUgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFF1ZXVlLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gUXVldWUoYXNzZXQpIHtcbiAgICAgIHRoaXMuYXNzZXQgPSBhc3NldDtcbiAgICAgIHRoaXMud3JpdGUgPSBfX2JpbmQodGhpcy53cml0ZSwgdGhpcyk7XG4gICAgICB0aGlzLnJlYWR5TWFyayA9IDY0O1xuICAgICAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5idWZmZXJpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5idWZmZXJzID0gW107XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdkYXRhJywgdGhpcy53cml0ZSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdlbmQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbmRlZCA9IHRydWU7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0LmRlY29kZVBhY2tldCgpO1xuICAgIH1cblxuICAgIFF1ZXVlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgaWYgKGJ1ZmZlcikge1xuICAgICAgICB0aGlzLmJ1ZmZlcnMucHVzaChidWZmZXIpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuYnVmZmVyaW5nKSB7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlcnMubGVuZ3RoID49IHRoaXMucmVhZHlNYXJrIHx8IHRoaXMuZW5kZWQpIHtcbiAgICAgICAgICB0aGlzLmJ1ZmZlcmluZyA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuYXNzZXQuZGVjb2RlUGFja2V0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgUXVldWUucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmJ1ZmZlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgdGhpcy5hc3NldC5kZWNvZGVQYWNrZXQoKTtcbiAgICAgIHJldHVybiB0aGlzLmJ1ZmZlcnMuc2hpZnQoKTtcbiAgICB9O1xuXG4gICAgUXVldWUucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmJ1ZmZlcnMubGVuZ3RoID0gMDtcbiAgICAgIHRoaXMuYnVmZmVyaW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzLmFzc2V0LmRlY29kZVBhY2tldCgpO1xuICAgIH07XG5cbiAgICByZXR1cm4gUXVldWU7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFF1ZXVlO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiRXZlbnRFbWl0dGVyID0gcmVxdWlyZSAnLi4vLi4vY29yZS9ldmVudHMnXG5BVkJ1ZmZlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvYnVmZmVyJ1xuXG5jbGFzcyBGaWxlU291cmNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyXG4gICAgY29uc3RydWN0b3I6IChAZmlsZSkgLT5cbiAgICAgICAgaWYgbm90IEZpbGVSZWFkZXI/XG4gICAgICAgICAgICByZXR1cm4gQGVtaXQgJ2Vycm9yJywgJ1RoaXMgYnJvd3NlciBkb2VzIG5vdCBoYXZlIEZpbGVSZWFkZXIgc3VwcG9ydC4nXG4gICAgICAgIFxuICAgICAgICBAb2Zmc2V0ID0gMFxuICAgICAgICBAbGVuZ3RoID0gQGZpbGUuc2l6ZVxuICAgICAgICBAY2h1bmtTaXplID0gMSA8PCAyMFxuICAgICAgICBAZmlsZVtAc2xpY2UgPSAnc2xpY2UnXSBvciBAZmlsZVtAc2xpY2UgPSAnd2Via2l0U2xpY2UnXSBvciBAZmlsZVtAc2xpY2UgPSAnbW96U2xpY2UnXVxuICAgICAgICAgICAgXG4gICAgc3RhcnQ6IC0+XG4gICAgICAgIGlmIEByZWFkZXJcbiAgICAgICAgICAgIHJldHVybiBAbG9vcCgpIHVubGVzcyBAYWN0aXZlXG4gICAgICAgIFxuICAgICAgICBAcmVhZGVyID0gbmV3IEZpbGVSZWFkZXJcbiAgICAgICAgQGFjdGl2ZSA9IHRydWVcbiAgICAgICAgXG4gICAgICAgIEByZWFkZXIub25sb2FkID0gKGUpID0+XG4gICAgICAgICAgICBidWYgPSBuZXcgQVZCdWZmZXIobmV3IFVpbnQ4QXJyYXkoZS50YXJnZXQucmVzdWx0KSlcbiAgICAgICAgICAgIEBvZmZzZXQgKz0gYnVmLmxlbmd0aFxuICAgICAgICBcbiAgICAgICAgICAgIEBlbWl0ICdkYXRhJywgYnVmICAgXG4gICAgICAgICAgICBAYWN0aXZlID0gZmFsc2UgICAgIFxuICAgICAgICAgICAgQGxvb3AoKSBpZiBAb2Zmc2V0IDwgQGxlbmd0aFxuICAgICAgICBcbiAgICAgICAgQHJlYWRlci5vbmxvYWRlbmQgPSA9PlxuICAgICAgICAgICAgaWYgQG9mZnNldCBpcyBAbGVuZ3RoXG4gICAgICAgICAgICAgICAgQGVtaXQgJ2VuZCdcbiAgICAgICAgICAgICAgICBAcmVhZGVyID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgQHJlYWRlci5vbmVycm9yID0gKGUpID0+XG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlXG4gICAgICAgIFxuICAgICAgICBAcmVhZGVyLm9ucHJvZ3Jlc3MgPSAoZSkgPT5cbiAgICAgICAgICAgIEBlbWl0ICdwcm9ncmVzcycsIChAb2Zmc2V0ICsgZS5sb2FkZWQpIC8gQGxlbmd0aCAqIDEwMFxuICAgICAgICBcbiAgICAgICAgQGxvb3AoKVxuICAgICAgICBcbiAgICBsb29wOiAtPlxuICAgICAgICBAYWN0aXZlID0gdHJ1ZVxuICAgICAgICBlbmRQb3MgPSBNYXRoLm1pbihAb2Zmc2V0ICsgQGNodW5rU2l6ZSwgQGxlbmd0aClcbiAgICAgICAgXG4gICAgICAgIGJsb2IgPSBAZmlsZVtAc2xpY2VdKEBvZmZzZXQsIGVuZFBvcylcbiAgICAgICAgQHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihibG9iKVxuICAgICAgICBcbiAgICBwYXVzZTogLT5cbiAgICAgICAgQGFjdGl2ZSA9IGZhbHNlXG4gICAgICAgIHRyeVxuICAgICAgICAgIEByZWFkZXI/LmFib3J0KClcbiAgICAgICAgXG4gICAgcmVzZXQ6IC0+XG4gICAgICAgIEBwYXVzZSgpXG4gICAgICAgIEBvZmZzZXQgPSAwXG5cbm1vZHVsZS5leHBvcnRzID0gRmlsZVNvdXJjZVxuIiwiRXZlbnRFbWl0dGVyID0gcmVxdWlyZSAnLi4vLi4vY29yZS9ldmVudHMnXG5BVkJ1ZmZlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvYnVmZmVyJ1xuXG5jbGFzcyBIVFRQU291cmNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyXG4gICAgY29uc3RydWN0b3I6IChAdXJsLCBAb3B0cyA9IHt9KSAtPlxuICAgICAgICBAY2h1bmtTaXplID0gMSA8PCAyMFxuICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICBpZiBAb3B0cy5sZW5ndGhcbiAgICAgICAgICAgIEBsZW5ndGggPSBAb3B0cy5sZW5ndGhcbiAgICAgICAgQHJlc2V0KClcbiAgICAgICAgXG4gICAgc3RhcnQ6IC0+XG4gICAgICAgIGlmIEBsZW5ndGhcbiAgICAgICAgICAgIHJldHVybiBAbG9vcCgpIHVubGVzcyBAaW5mbGlnaHRcbiAgICAgICAgXG4gICAgICAgIEBpbmZsaWdodCA9IHRydWVcbiAgICAgICAgQHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpXG4gICAgICAgIFxuICAgICAgICBAeGhyLm9ubG9hZCA9IChldmVudCkgPT5cbiAgICAgICAgICAgIEBsZW5ndGggPSBwYXJzZUludCBAeGhyLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1MZW5ndGhcIikgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICAgICAgQGxvb3AoKVxuICAgICAgICBcbiAgICAgICAgQHhoci5vbmVycm9yID0gKGVycikgPT5cbiAgICAgICAgICAgIEBwYXVzZSgpXG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlcnJcbiAgICAgICAgICAgIFxuICAgICAgICBAeGhyLm9uYWJvcnQgPSAoZXZlbnQpID0+XG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICBcbiAgICAgICAgQHhoci5vcGVuKFwiSEVBRFwiLCBAdXJsLCB0cnVlKVxuICAgICAgICBAeGhyLnNlbmQobnVsbClcbiAgICAgICAgXG4gICAgbG9vcDogLT5cbiAgICAgICAgaWYgQGluZmxpZ2h0IG9yIG5vdCBAbGVuZ3RoXG4gICAgICAgICAgICByZXR1cm4gQGVtaXQgJ2Vycm9yJywgJ1NvbWV0aGluZyBpcyB3cm9uZyBpbiBIVFRQU291cmNlLmxvb3AnXG4gICAgICAgICAgICBcbiAgICAgICAgQGluZmxpZ2h0ID0gdHJ1ZVxuICAgICAgICBAeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KClcbiAgICAgICAgXG4gICAgICAgIEB4aHIub25sb2FkID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgaWYgQHhoci5yZXNwb25zZVxuICAgICAgICAgICAgICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KEB4aHIucmVzcG9uc2UpXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdHh0ID0gQHhoci5yZXNwb25zZVRleHRcbiAgICAgICAgICAgICAgICBidWYgPSBuZXcgVWludDhBcnJheSh0eHQubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciBpIGluIFswLi4udHh0Lmxlbmd0aF1cbiAgICAgICAgICAgICAgICAgICAgYnVmW2ldID0gdHh0LmNoYXJDb2RlQXQoaSkgJiAweGZmXG5cbiAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBBVkJ1ZmZlcihidWYpXG4gICAgICAgICAgICBAb2Zmc2V0ICs9IGJ1ZmZlci5sZW5ndGhcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgQGVtaXQgJ2RhdGEnLCBidWZmZXJcbiAgICAgICAgICAgIEBlbWl0ICdlbmQnIGlmIEBvZmZzZXQgPj0gQGxlbmd0aFxuXG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICAgICAgQGxvb3AoKSB1bmxlc3MgQG9mZnNldCA+PSBAbGVuZ3RoXG4gICAgICAgICAgICBcbiAgICAgICAgQHhoci5vbnByb2dyZXNzID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgQGVtaXQgJ3Byb2dyZXNzJywgKEBvZmZzZXQgKyBldmVudC5sb2FkZWQpIC8gQGxlbmd0aCAqIDEwMFxuXG4gICAgICAgIEB4aHIub25lcnJvciA9IChlcnIpID0+XG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlcnJcbiAgICAgICAgICAgIEBwYXVzZSgpXG5cbiAgICAgICAgQHhoci5vbmFib3J0ID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcblxuICAgICAgICBAeGhyLm9wZW4oXCJHRVRcIiwgQHVybCwgdHJ1ZSlcbiAgICAgICAgQHhoci5yZXNwb25zZVR5cGUgPSBcImFycmF5YnVmZmVyXCJcblxuICAgICAgICBlbmRQb3MgPSBNYXRoLm1pbihAb2Zmc2V0ICsgQGNodW5rU2l6ZSwgQGxlbmd0aCAtIDEpXG4gICAgICAgIEB4aHIuc2V0UmVxdWVzdEhlYWRlcihcIklmLU5vbmUtTWF0Y2hcIiwgXCJ3ZWJraXQtbm8tY2FjaGVcIilcbiAgICAgICAgQHhoci5zZXRSZXF1ZXN0SGVhZGVyKFwiUmFuZ2VcIiwgXCJieXRlcz0je0BvZmZzZXR9LSN7ZW5kUG9zfVwiKVxuICAgICAgICBAeGhyLm92ZXJyaWRlTWltZVR5cGUoJ3RleHQvcGxhaW47IGNoYXJzZXQ9eC11c2VyLWRlZmluZWQnKVxuICAgICAgICBAeGhyLnNlbmQobnVsbClcbiAgICAgICAgXG4gICAgcGF1c2U6IC0+XG4gICAgICAgIEBpbmZsaWdodCA9IGZhbHNlXG4gICAgICAgIEB4aHI/LmFib3J0KClcbiAgICAgICAgXG4gICAgcmVzZXQ6IC0+XG4gICAgICAgIEBwYXVzZSgpXG4gICAgICAgIEBvZmZzZXQgPSAwXG4gICAgICAgIFxubW9kdWxlLmV4cG9ydHMgPSBIVFRQU291cmNlXG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBVkJ1ZmZlciwgQnVmZmVyTGlzdCwgQnVmZmVyU291cmNlLCBFdmVudEVtaXR0ZXIsXG4gICAgX19iaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuLi9jb3JlL2V2ZW50cycpO1xuXG4gIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuLi9jb3JlL2J1ZmZlcmxpc3QnKTtcblxuICBBVkJ1ZmZlciA9IHJlcXVpcmUoJy4uL2NvcmUvYnVmZmVyJyk7XG5cbiAgQnVmZmVyU291cmNlID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIHZhciBjbGVhckltbWVkaWF0ZSwgc2V0SW1tZWRpYXRlO1xuXG4gICAgX19leHRlbmRzKEJ1ZmZlclNvdXJjZSwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIEJ1ZmZlclNvdXJjZShpbnB1dCkge1xuICAgICAgdGhpcy5sb29wID0gX19iaW5kKHRoaXMubG9vcCwgdGhpcyk7XG4gICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBCdWZmZXJMaXN0KSB7XG4gICAgICAgIHRoaXMubGlzdCA9IGlucHV0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5saXN0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICAgIHRoaXMubGlzdC5hcHBlbmQobmV3IEFWQnVmZmVyKGlucHV0KSk7XG4gICAgICB9XG4gICAgICB0aGlzLnBhdXNlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgc2V0SW1tZWRpYXRlID0gZ2xvYmFsLnNldEltbWVkaWF0ZSB8fCBmdW5jdGlvbihmbikge1xuICAgICAgcmV0dXJuIGdsb2JhbC5zZXRUaW1lb3V0KGZuLCAwKTtcbiAgICB9O1xuXG4gICAgY2xlYXJJbW1lZGlhdGUgPSBnbG9iYWwuY2xlYXJJbW1lZGlhdGUgfHwgZnVuY3Rpb24odGltZXIpIHtcbiAgICAgIHJldHVybiBnbG9iYWwuY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICB9O1xuXG4gICAgQnVmZmVyU291cmNlLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5wYXVzZWQgPSBmYWxzZTtcbiAgICAgIHJldHVybiB0aGlzLl90aW1lciA9IHNldEltbWVkaWF0ZSh0aGlzLmxvb3ApO1xuICAgIH07XG5cbiAgICBCdWZmZXJTb3VyY2UucHJvdG90eXBlLmxvb3AgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuZW1pdCgncHJvZ3Jlc3MnLCAodGhpcy5saXN0Lm51bUJ1ZmZlcnMgLSB0aGlzLmxpc3QuYXZhaWxhYmxlQnVmZmVycyArIDEpIC8gdGhpcy5saXN0Lm51bUJ1ZmZlcnMgKiAxMDAgfCAwKTtcbiAgICAgIHRoaXMuZW1pdCgnZGF0YScsIHRoaXMubGlzdC5maXJzdCk7XG4gICAgICBpZiAodGhpcy5saXN0LmFkdmFuY2UoKSkge1xuICAgICAgICByZXR1cm4gc2V0SW1tZWRpYXRlKHRoaXMubG9vcCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQnVmZmVyU291cmNlLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgY2xlYXJJbW1lZGlhdGUodGhpcy5fdGltZXIpO1xuICAgICAgcmV0dXJuIHRoaXMucGF1c2VkID0gdHJ1ZTtcbiAgICB9O1xuXG4gICAgQnVmZmVyU291cmNlLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5wYXVzZSgpO1xuICAgICAgcmV0dXJuIHRoaXMubGlzdC5yZXdpbmQoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJ1ZmZlclNvdXJjZTtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQnVmZmVyU291cmNlO1xuXG59KS5jYWxsKHRoaXMpO1xuIl19 diff --git a/public-shared/js/flac.js b/public-shared/js/flac.js deleted file mode 100644 index 6a35ecf..0000000 --- a/public-shared/js/flac.js +++ /dev/null @@ -1,799 +0,0 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1; ones--) { - stream.advance(2); // == 2 - frame_or_sample_num = (frame_or_sample_num << 6) | stream.read(6); - } - - // block size - if (bsCode === 0) - throw new Error('Reserved blocksize code'); - else if (bsCode === 6) - this.blockSize = stream.read(8) + 1; - else if (bsCode === 7) - this.blockSize = stream.read(16) + 1; - else - this.blockSize = BLOCK_SIZES[bsCode]; - - // sample rate - var sampleRate; - if (srCode < 12) - sampleRate = SAMPLE_RATES[srCode]; - else if (srCode === 12) - sampleRate = stream.read(8) * 1000; - else if (srCode === 13) - sampleRate = stream.read(16); - else if (srCode === 14) - sampleRate = stream.read(16) * 10; - else - throw new Error('Invalid sample rate code'); - - stream.advance(8); // skip CRC check - - // subframes - for (var i = 0; i < channels; i++) - this.decodeSubframe(i); - - stream.align(); - stream.advance(16); // skip CRC frame footer - - var is32 = this.bps > 16, - output = new ArrayBuffer(this.blockSize * channels * (is32 ? 4 : 2)), - buf = is32 ? new Int32Array(output) : new Int16Array(output), - blockSize = this.blockSize, - decoded = this.decoded, - j = 0; - - switch (this.chMode) { - case CHMODE_INDEPENDENT: - for (var k = 0; k < blockSize; k++) { - for (var i = 0; i < channels; i++) { - buf[j++] = decoded[i][k]; - } - } - break; - - case CHMODE_LEFT_SIDE: - for (var i = 0; i < blockSize; i++) { - var left = decoded[0][i], - right = decoded[1][i]; - - buf[j++] = left; - buf[j++] = (left - right); - } - break; - - case CHMODE_RIGHT_SIDE: - for (var i = 0; i < blockSize; i++) { - var left = decoded[0][i], - right = decoded[1][i]; - - buf[j++] = (left + right); - buf[j++] = right; - } - break; - - case CHMODE_MID_SIDE: - for (var i = 0; i < blockSize; i++) { - var left = decoded[0][i], - right = decoded[1][i]; - - left -= right >> 1; - buf[j++] = (left + right); - buf[j++] = left; - } - break; - } - - return buf; - }; - - this.prototype.decodeSubframe = function(channel) { - var wasted = 0, - stream = this.bitstream, - blockSize = this.blockSize, - decoded = this.decoded; - - this.curr_bps = this.bps; - if (channel === 0) { - if (this.chMode === CHMODE_RIGHT_SIDE) - this.curr_bps++; - } else { - if (this.chMode === CHMODE_LEFT_SIDE || this.chMode === CHMODE_MID_SIDE) - this.curr_bps++; - } - - if (stream.read(1)) - throw new Error("Invalid subframe padding"); - - var type = stream.read(6); - - if (stream.read(1)) { - wasted = 1; - while (!stream.read(1)) - wasted++; - - this.curr_bps -= wasted; - } - - if (this.curr_bps > 32) - throw new Error("decorrelated bit depth > 32 (" + this.curr_bps + ")"); - - if (type === 0) { - var tmp = stream.read(this.curr_bps, true); - for (var i = 0; i < blockSize; i++) - decoded[channel][i] = tmp; - - } else if (type === 1) { - var bps = this.curr_bps; - for (var i = 0; i < blockSize; i++) - decoded[channel][i] = stream.read(bps, true); - - } else if ((type >= 8) && (type <= 12)) { - this.decode_subframe_fixed(channel, type & ~0x8); - - } else if (type >= 32) { - this.decode_subframe_lpc(channel, (type & ~0x20) + 1); - - } else { - throw new Error("Invalid coding type"); - } - - if (wasted) { - for (var i = 0; i < blockSize; i++) - decoded[channel][i] <<= wasted; - } - }; - - this.prototype.decode_subframe_fixed = function(channel, predictor_order) { - var decoded = this.decoded[channel], - stream = this.bitstream, - bps = this.curr_bps; - - // warm up samples - for (var i = 0; i < predictor_order; i++) - decoded[i] = stream.read(bps, true); - - this.decode_residuals(channel, predictor_order); - - var a = 0, b = 0, c = 0, d = 0; - - if (predictor_order > 0) - a = decoded[predictor_order - 1]; - - if (predictor_order > 1) - b = a - decoded[predictor_order - 2]; - - if (predictor_order > 2) - c = b - decoded[predictor_order - 2] + decoded[predictor_order - 3]; - - if (predictor_order > 3) - d = c - decoded[predictor_order - 2] + 2 * decoded[predictor_order - 3] - decoded[predictor_order - 4]; - - switch (predictor_order) { - case 0: - break; - - case 1: - case 2: - case 3: - case 4: - var abcd = new Int32Array([a, b, c, d]), - blockSize = this.blockSize; - - for (var i = predictor_order; i < blockSize; i++) { - abcd[predictor_order - 1] += decoded[i]; - - for (var j = predictor_order - 2; j >= 0; j--) { - abcd[j] += abcd[j + 1]; - } - - decoded[i] = abcd[0]; - } - - break; - - default: - throw new Error("Invalid Predictor Order " + predictor_order); - } - }; - - this.prototype.decode_subframe_lpc = function(channel, predictor_order) { - var stream = this.bitstream, - decoded = this.decoded[channel], - bps = this.curr_bps, - blockSize = this.blockSize; - - // warm up samples - for (var i = 0; i < predictor_order; i++) { - decoded[i] = stream.read(bps, true); - } - - var coeff_prec = stream.read(4) + 1; - if (coeff_prec === 16) - throw new Error("Invalid coefficient precision"); - - var qlevel = stream.read(5, true); - if (qlevel < 0) - throw new Error("Negative qlevel, maybe buggy stream"); - - var coeffs = new Int32Array(32); - for (var i = 0; i < predictor_order; i++) { - coeffs[i] = stream.read(coeff_prec, true); - } - - this.decode_residuals(channel, predictor_order); - - if (this.bps <= 16) { - for (var i = predictor_order; i < blockSize - 1; i += 2) { - var d = decoded[i - predictor_order], - s0 = 0, s1 = 0, c = 0; - - for (var j = predictor_order - 1; j > 0; j--) { - c = coeffs[j]; - s0 += c * d; - d = decoded[i - j]; - s1 += c * d; - } - - c = coeffs[0]; - s0 += c * d; - d = decoded[i] += (s0 >> qlevel); - s1 += c * d; - decoded[i + 1] += (s1 >> qlevel); - } - - if (i < blockSize) { - var sum = 0; - for (var j = 0; j < predictor_order; j++) - sum += coeffs[j] * decoded[i - j - 1]; - - decoded[i] += (sum >> qlevel); - } - } else { - // simulate 64 bit integer using an array of two 32 bit ints - var total = this.lpc_total; - for (var i = predictor_order; i < blockSize; i++) { - // reset total to 0 - total[0] = 0; - total[1] = 0; - - for (j = 0; j < predictor_order; j++) { - // simulate `total += coeffs[j] * decoded[i - j - 1]` - multiply_add(total, coeffs[j], decoded[i - j - 1]); - } - - // simulate `decoded[i] += total >> qlevel` - // we know that qlevel < 32 since it is a 5 bit field (see above) - decoded[i] += (total[0] >>> qlevel) | (total[1] << (32 - qlevel)); - } - } - }; - - const TWO_PWR_32_DBL = Math.pow(2, 32); - - // performs `total += a * b` on a simulated 64 bit int - // total is an Int32Array(2) - // a and b are JS numbers (32 bit ints) - function multiply_add(total, a, b) { - // multiply a * b (we can use normal JS multiplication for this) - var r = a * b; - var n = r < 0; - if (n) - r = -r; - - var r_low = (r % TWO_PWR_32_DBL) | 0; - var r_high = (r / TWO_PWR_32_DBL) | 0; - if (n) { - r_low = ~r_low + 1; - r_high = ~r_high; - } - - // add result to total - var a48 = total[1] >>> 16; - var a32 = total[1] & 0xFFFF; - var a16 = total[0] >>> 16; - var a00 = total[0] & 0xFFFF; - - var b48 = r_high >>> 16; - var b32 = r_high & 0xFFFF; - var b16 = r_low >>> 16; - var b00 = r_low & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - - // store result back in total - total[0] = (c16 << 16) | c00; - total[1] = (c48 << 16) | c32; - } - - const INT_MAX = 32767; - - this.prototype.decode_residuals = function(channel, predictor_order) { - var stream = this.bitstream, - method_type = stream.read(2); - - if (method_type > 1) - throw new Error('Illegal residual coding method ' + method_type); - - var rice_order = stream.read(4), - samples = (this.blockSize >>> rice_order); - - if (predictor_order > samples) - throw new Error('Invalid predictor order ' + predictor_order + ' > ' + samples); - - var decoded = this.decoded[channel], - sample = predictor_order, - i = predictor_order; - - for (var partition = 0; partition < (1 << rice_order); partition++) { - var tmp = stream.read(method_type === 0 ? 4 : 5); - - if (tmp === (method_type === 0 ? 15 : 31)) { - tmp = stream.read(5); - for (; i < samples; i++) - decoded[sample++] = stream.read(tmp, true); - - } else { - for (; i < samples; i++) - decoded[sample++] = this.golomb(tmp, INT_MAX, 0); - } - - i = 0; - } - }; - - const MIN_CACHE_BITS = 25; - - this.prototype.golomb = function(k, limit, esc_len) { - var data = this.bitstream, - offset = data.bitPosition, - buf = data.peek(32 - offset) << offset, - v = 0; - - var log = 31 - clz(buf | 1); // log2(buf) - - if (log - k >= 32 - MIN_CACHE_BITS && 32 - log < limit) { - buf >>>= log - k; - buf += (30 - log) << k; - - data.advance(32 + k - log); - v = buf; - - } else { - for (var i = 0; data.read(1) === 0; i++) - buf = data.peek(32 - offset) << offset; - - if (i < limit - 1) { - if (k) - buf = data.read(k); - else - buf = 0; - - v = buf + (i << k); - - } else if (i === limit - 1) { - buf = data.read(esc_len); - v = buf + 1; - - } else { - v = -1; - } - } - - return (v >> 1) ^ -(v & 1); - }; - - // Should be in the damned standard library... - function clz(input) { - var output = 0, - curbyte = 0; - - while(true) { // emulate goto in JS using the break statement :D - curbyte = input >>> 24; - if (curbyte) break; - output += 8; - - curbyte = input >>> 16; - if (curbyte & 0xff) break; - output += 8; - - curbyte = input >>> 8; - if (curbyte & 0xff) break; - output += 8; - - curbyte = input; - if (curbyte & 0xff) break; - output += 8; - - return output; - } - - if (!(curbyte & 0xf0)) - output += 4; - else - curbyte >>>= 4; - - if (curbyte & 0x8) - return output; - - if (curbyte & 0x4) - return output + 1; - - if (curbyte & 0x2) - return output + 2; - - if (curbyte & 0x1) - return output + 3; - - // shouldn't get here - return output + 4; - } -}); - -module.exports = FLACDecoder; - -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],3:[function(require,module,exports){ -(function (global){ -/* - * FLAC.js - Free Lossless Audio Codec decoder in JavaScript - * By Devon Govett and Jens Nockert of Official.fm Labs - * - * FLAC.js is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FLAC.js is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - */ - -var AV = (typeof window !== "undefined" ? window['AV'] : typeof global !== "undefined" ? global['AV'] : null); - -var FLACDemuxer = AV.Demuxer.extend(function() { - AV.Demuxer.register(this); - - this.probe = function(buffer) { - return buffer.peekString(0, 4) === 'fLaC'; - } - - const STREAMINFO = 0, - PADDING = 1, - APPLICATION = 2, - SEEKTABLE = 3, - VORBIS_COMMENT = 4, - CUESHEET = 5, - PICTURE = 6, - INVALID = 127, - STREAMINFO_SIZE = 34; - - this.prototype.readChunk = function() { - var stream = this.stream; - - if (!this.readHeader && stream.available(4)) { - if (stream.readString(4) !== 'fLaC') - return this.emit('error', 'Invalid FLAC file.'); - - this.readHeader = true; - } - - while (stream.available(1) && !this.last) { - if (!this.readBlockHeaders) { - var tmp = stream.readUInt8(); - this.last = (tmp & 0x80) === 0x80, - this.type = tmp & 0x7F, - this.size = stream.readUInt24(); - } - - if (!this.foundStreamInfo && this.type !== STREAMINFO) - return this.emit('error', 'STREAMINFO must be the first block'); - - if (!stream.available(this.size)) - return; - - switch (this.type) { - case STREAMINFO: - if (this.foundStreamInfo) - return this.emit('error', 'STREAMINFO can only occur once.'); - - if (this.size !== STREAMINFO_SIZE) - return this.emit('error', 'STREAMINFO size is wrong.'); - - this.foundStreamInfo = true; - var bitstream = new AV.Bitstream(stream); - - var cookie = { - minBlockSize: bitstream.read(16), - maxBlockSize: bitstream.read(16), - minFrameSize: bitstream.read(24), - maxFrameSize: bitstream.read(24) - }; - - this.format = { - formatID: 'flac', - sampleRate: bitstream.read(20), - channelsPerFrame: bitstream.read(3) + 1, - bitsPerChannel: bitstream.read(5) + 1 - }; - - this.emit('format', this.format); - this.emit('cookie', cookie); - - var sampleCount = bitstream.read(36); - this.emit('duration', sampleCount / this.format.sampleRate * 1000 | 0); - - stream.advance(16); // skip MD5 hashes - this.readBlockHeaders = false; - break; - - /* - I am only looking at the least significant 32 bits of sample number and offset data - This is more than sufficient for the longest flac file I have (~50 mins 2-channel 16-bit 44.1k which uses about 7.5% of the UInt32 space for the largest offset) - Can certainly be improved by storing sample numbers and offests as doubles, but would require additional overriding of the searchTimestamp and seek functions (possibly more?) - Also the flac faq suggests it would be possible to find frame lengths and thus create seek points on the fly via decoding but I assume this would be slow - I may look into these thigns though as my project progresses - */ - case SEEKTABLE: - for(var s=0; s 0) - { - this.emit('error', 'Seek points with sample number >UInt32 not supported'); - } - var samplenum = stream.readUInt32(); - if(stream.readUInt32() > 0) - { - this.emit('error', 'Seek points with stream offset >UInt32 not supported'); - } - var offset = stream.readUInt32(); - - stream.advance(2); - - this.addSeekPoint(offset, samplenum); - } - } - break; - - case VORBIS_COMMENT: - // see http://www.xiph.org/vorbis/doc/v-comment.html - this.metadata || (this.metadata = {}); - var len = stream.readUInt32(true); - - this.metadata.vendor = stream.readString(len); - var length = stream.readUInt32(true); - - for (var i = 0; i < length; i++) { - len = stream.readUInt32(true); - var str = stream.readString(len, 'utf8'), - idx = str.indexOf('='); - - this.metadata[str.slice(0, idx).toLowerCase()] = str.slice(idx + 1); - } - - // TODO: standardize field names across formats - break; - - case PICTURE: - var type = stream.readUInt32(); - if (type !== 3) { // make sure this is album art (type 3) - stream.advance(this.size - 4); - } else { - var mimeLen = stream.readUInt32(), - mime = stream.readString(mimeLen), - descLen = stream.readUInt32(), - description = stream.readString(descLen), - width = stream.readUInt32(), - height = stream.readUInt32(), - depth = stream.readUInt32(), - colors = stream.readUInt32(), - length = stream.readUInt32(), - picture = stream.readBuffer(length); - - this.metadata || (this.metadata = {}); - this.metadata.coverArt = picture; - } - - // does anyone want the rest of the info? - break; - - default: - stream.advance(this.size); - this.readBlockHeaders = false; - } - - if (this.last && this.metadata) - this.emit('metadata', this.metadata); - } - - while (stream.available(1) && this.last) { - var buffer = stream.readSingleBuffer(stream.remainingBytes()); - this.emit('data', buffer); - } - } - -}); - -module.exports = FLACDemuxer; - -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],4:[function(require,module,exports){ -(function (global){ -var AV = (typeof window !== "undefined" ? window['AV'] : typeof global !== "undefined" ? global['AV'] : null); - -// if ogg.js exists, register a plugin -try { - var OggDemuxer = (typeof window !== "undefined" ? window['AV']['OggDemuxer'] : typeof global !== "undefined" ? global['AV']['OggDemuxer'] : null); -} catch (e) {}; -if (!OggDemuxer) return; - -OggDemuxer.plugins.push({ - magic: "\177FLAC", - - init: function() { - this.list = new AV.BufferList(); - this.stream = new AV.Stream(this.list); - }, - - readHeaders: function(packet) { - var stream = this.stream; - this.list.append(new AV.Buffer(packet)); - - stream.advance(5); // magic - if (stream.readUInt8() != 1) - throw new Error('Unsupported FLAC version'); - - stream.advance(3); - if (stream.peekString(0, 4) != 'fLaC') - throw new Error('Not flac'); - - this.flac = AV.Demuxer.find(stream.peekSingleBuffer(0, stream.remainingBytes())); - if (!this.flac) - throw new Error('Flac demuxer not found'); - - this.flac.prototype.readChunk.call(this); - return true; - }, - - readPacket: function(packet) { - this.list.append(new AV.Buffer(packet)); - this.flac.prototype.readChunk.call(this); - } -}); - -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}]},{},[1]) - - -//# sourceMappingURL=flac.js.map \ No newline at end of file diff --git a/public-shared/css/shared.css b/public/css/shared.css similarity index 100% rename from public-shared/css/shared.css rename to public/css/shared.css diff --git a/public-shared/img/mstream-logo.svg b/public/img/mstream-logo.svg similarity index 100% rename from public-shared/img/mstream-logo.svg rename to public/img/mstream-logo.svg diff --git a/public-shared/img/mstream-logo.svgz b/public/img/mstream-logo.svgz similarity index 100% rename from public-shared/img/mstream-logo.svgz rename to public/img/mstream-logo.svgz diff --git a/public-shared/img/next-white.svg b/public/img/next-white.svg similarity index 100% rename from public-shared/img/next-white.svg rename to public/img/next-white.svg diff --git a/public-shared/img/pause-white.svg b/public/img/pause-white.svg similarity index 100% rename from public-shared/img/pause-white.svg rename to public/img/pause-white.svg diff --git a/public-shared/img/play-white.svg b/public/img/play-white.svg similarity index 100% rename from public-shared/img/play-white.svg rename to public/img/play-white.svg diff --git a/public-shared/img/previous-white.svg b/public/img/previous-white.svg similarity index 100% rename from public-shared/img/previous-white.svg rename to public/img/previous-white.svg diff --git a/public-shared/js/howler.core.min.js b/public/js/howler.core.min.js old mode 100755 new mode 100644 similarity index 100% rename from public-shared/js/howler.core.min.js rename to public/js/howler.core.min.js diff --git a/public/js/mstream-old-functions.js b/public/js/mstream-old-functions.js deleted file mode 100644 index 63d5842..0000000 --- a/public/js/mstream-old-functions.js +++ /dev/null @@ -1,86 +0,0 @@ -// ///////////////////////////// Database Management - -// // The Manage DB panel -// $('#manage_database').on('click', function(){ -// // Hide the directory bar -// $('.directoryTitle').hide(); -// // Change the panel name -// $('.panel_one_name').html('Database Management'); -// //clear the list -// $('#filelist').empty(); - -// // Make an ajax request to get the current state of the db -// var request = $.ajax({ -// url: "db_scripts/check_db_status.php", -// type: "GET", -// dataType: "json" -// }); - -// request.done(function( msg ) { - -// // If there is an error -// if(msg.error){ -// $('#filelist').html('

The database returned the following error:

' + msg.error + '

'); - -// return; -// } - -// // if the DB is locked -// if(msg.locked){ -// // -// $('#filelist').html('

The database is currently being built

'); -// return; -// } - -// // If the db is empty -// if(msg.status == 'The database has not been created yet'){ -// $('#filelist').html('

The database has not been set up yet. Clicking the button will scan your library and create a database

'); -// return; -// } - -// // If you got this far the db is made and working -// $('#filelist').html('

Your DB currently stores ' + msg.file_count + ' files

'); -// }); - -// }); - - -// // Build the database -// $('body').on('click', '#build_database', function(){ -// $(this).prop("disabled", true); - -// // Send out AJAX request to start building the DB -// $.ajax({ -// url: "make_db.php", -// type: "GET", -// }); - -// // Append the check db button so the user can start checking right away -// $('#filelist').append(''); -// }); - -// // Check DB build progress -// $('body').on('click', '#check_db_progress', function(){ -// var request = $.ajax({ -// url: "db_scripts/db_file_counts.php", -// type: "GET", -// dataType: "json" -// }); - -// request.done( function(msg){ -// // remove a

tage with the id of "db_progress_report" -// $( "#db_progress_report" ).remove(); - -// // if file_count is 0, report that the the build script is not done counting files -// if(msg.file_count == 0){ -// $('#filelist').append('

The create database script is still counting the files in the music collection. This operation can take some time. Try again in a bit

'); -// return; -// } - -// // Append new

tag with id of "db_progress_report" -// $('#filelist').append('

Progress: '+ msg.files_in_db +'/'+ msg.file_count +'

'); -// }); - -// }); - - diff --git a/public-shared/js/mstream.api.js b/public/js/mstream.api.js similarity index 100% rename from public-shared/js/mstream.api.js rename to public/js/mstream.api.js diff --git a/public-shared/js/mstream.js b/public/js/mstream.player.js similarity index 100% rename from public-shared/js/mstream.js rename to public/js/mstream.player.js diff --git a/public-shared/js/shared.js b/public/js/shared.js similarity index 100% rename from public-shared/js/shared.js rename to public/js/shared.js diff --git a/public/js/sortable.js b/public/js/sortable.js deleted file mode 100755 index 09d69b2..0000000 --- a/public/js/sortable.js +++ /dev/null @@ -1,85 +0,0 @@ -/* - * HTML5 Sortable jQuery Plugin - * http://farhadi.ir/projects/html5sortable - * - * Copyright 2012, Ali Farhadi - * Released under the MIT license. - */ -(function($) { -var dragging, placeholders = $(); -$.fn.sortable = function(options) { - var method = String(options); - options = $.extend({ - connectWith: false - }, options); - return this.each(function() { - if (/^enable|disable|destroy$/.test(method)) { - var items = $(this).children($(this).data('items')).attr('draggable', method == 'enable'); - if (method == 'destroy') { - items.add(this).removeData('connectWith items') - .off('dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s'); - } - return; - } - var isHandle, index, items = $(this).children(options.items); - var placeholder = $('<' + (/^ul|ol$/i.test(this.tagName) ? 'li' : 'div') + ' class="sortable-placeholder">'); - items.find(options.handle).mousedown(function() { - isHandle = true; - }).mouseup(function() { - isHandle = false; - }); - $(this).data('items', options.items) - placeholders = placeholders.add(placeholder); - if (options.connectWith) { - $(options.connectWith).add(this).data('connectWith', options.connectWith); - } - items.attr('draggable', 'true').on('dragstart.h5s', function(e) { - if (options.handle && !isHandle) { - return false; - } - isHandle = false; - var dt = e.originalEvent.dataTransfer; - dt.effectAllowed = 'move'; - dt.setData('Text', 'dummy'); - index = (dragging = $(this)).addClass('sortable-dragging').index(); - }).on('dragend.h5s', function() { - if (!dragging) { - return; - } - dragging.removeClass('sortable-dragging').show(); - placeholders.detach(); - if (index != dragging.index()) { - dragging.parent().trigger('sortupdate', {item: dragging}); - } - dragging = null; - }).not('a[href], img').on('selectstart.h5s', function() { - this.dragDrop && this.dragDrop(); - return false; - }).end().add([this, placeholder]).on('dragover.h5s dragenter.h5s drop.h5s', function(e) { - if (!items.is(dragging) && options.connectWith !== $(dragging).parent().data('connectWith')) { - return true; - } - if (e.type == 'drop') { - e.stopPropagation(); - placeholders.filter(':visible').after(dragging); - dragging.trigger('dragend.h5s'); - return false; - } - e.preventDefault(); - e.originalEvent.dataTransfer.dropEffect = 'move'; - if (items.is(this)) { - if (options.forcePlaceholderSize) { - placeholder.height(dragging.outerHeight()); - } - dragging.hide(); - $(this)[placeholder.index() < $(this).index() ? 'after' : 'before'](placeholder); - placeholders.not(placeholder).detach(); - } else if (!placeholders.is(this) && !$(this).children(options.items).length) { - placeholders.detach(); - $(this).append(placeholder); - } - return false; - }); - }); -}; -})(jQuery); \ No newline at end of file diff --git a/public-shared/js/vue-sortable.js b/public/js/vue-sortable.js similarity index 100% rename from public-shared/js/vue-sortable.js rename to public/js/vue-sortable.js diff --git a/public/mstream.html b/public/mstream.html index 9a6fd17..d21df99 100755 --- a/public/mstream.html +++ b/public/mstream.html @@ -8,27 +8,26 @@ - - - - - - + + + + + + mStream Media Player - All your media. Everywhere you go. - - - + + + - + - - + @@ -38,7 +37,7 @@ - + @@ -47,28 +46,18 @@ DO NOT Change to order these are loaded in You do not need to worry about how these work --> - - - - - - - - - - + + + + + - + @@ -140,7 +129,7 @@ }, computed: { imgsrc: function () { - return "/public-shared/img/"+(this.status.playing ? 'pause' : 'play')+"-white.svg"; + return "/public/img/"+(this.status.playing ? 'pause' : 'play')+"-white.svg"; } } }); @@ -268,36 +257,6 @@ - - - - - - - - - @@ -309,7 +268,7 @@

-