public/lib/modules/aurora.js/aurora.js
(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(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var Asset, BufferSource, Decoder, Demuxer, EventEmitter, FileSource, HTTPSource,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('./core/events');
HTTPSource = require('./sources/node/http');
FileSource = require('./sources/node/file');
BufferSource = require('./sources/buffer');
Demuxer = require('./demuxer');
Decoder = require('./decoder');
Asset = (function(superClass) {
extend(Asset, superClass);
function Asset(source) {
this.source = source;
this._decode = bind(this._decode, this);
this.findDecoder = bind(this.findDecoder, this);
this.probe = bind(this.probe, this);
this.buffered = 0;
this.duration = null;
this.format = null;
this.metadata = null;
this.active = false;
this.demuxer = null;
this.decoder = null;
this.source.once('data', this.probe);
this.source.on('error', (function(_this) {
return function(err) {
_this.emit('error', err);
return _this.stop();
};
})(this));
this.source.on('progress', (function(_this) {
return function(buffered) {
_this.buffered = buffered;
return _this.emit('buffer', _this.buffered);
};
})(this));
}
Asset.fromURL = function(url, opts) {
return new Asset(new HTTPSource(url, opts));
};
Asset.fromFile = function(file) {
return new Asset(new FileSource(file));
};
Asset.fromBuffer = function(buffer) {
return new Asset(new BufferSource(buffer));
};
Asset.prototype.start = function(decode) {
if (this.active) {
return;
}
if (decode != null) {
this.shouldDecode = decode;
}
if (this.shouldDecode == null) {
this.shouldDecode = true;
}
this.active = true;
this.source.start();
if (this.decoder && this.shouldDecode) {
return this._decode();
}
};
Asset.prototype.stop = function() {
if (!this.active) {
return;
}
this.active = false;
return this.source.pause();
};
Asset.prototype.get = function(event, callback) {
if (event !== 'format' && event !== 'duration' && event !== 'metadata') {
return;
}
if (this[event] != null) {
return callback(this[event]);
} else {
this.once(event, (function(_this) {
return function(value) {
_this.stop();
return callback(value);
};
})(this));
return this.start();
}
};
Asset.prototype.decodePacket = function() {
return this.decoder.decode();
};
Asset.prototype.decodeToBuffer = function(callback) {
var chunks, dataHandler, length;
length = 0;
chunks = [];
this.on('data', dataHandler = function(chunk) {
length += chunk.length;
return chunks.push(chunk);
});
this.once('end', function() {
var buf, chunk, j, len, offset;
buf = new Float32Array(length);
offset = 0;
for (j = 0, len = chunks.length; j < len; j++) {
chunk = chunks[j];
buf.set(chunk, offset);
offset += chunk.length;
}
this.off('data', dataHandler);
return callback(buf);
});
return this.start();
};
Asset.prototype.probe = function(chunk) {
var demuxer;
if (!this.active) {
return;
}
demuxer = Demuxer.find(chunk);
if (!demuxer) {
return this.emit('error', 'A demuxer for this container was not found.');
}
this.demuxer = new demuxer(this.source, chunk);
this.demuxer.on('format', this.findDecoder);
this.demuxer.on('duration', (function(_this) {
return function(duration) {
_this.duration = duration;
return _this.emit('duration', _this.duration);
};
})(this));
this.demuxer.on('metadata', (function(_this) {
return function(metadata) {
_this.metadata = metadata;
return _this.emit('metadata', _this.metadata);
};
})(this));
return this.demuxer.on('error', (function(_this) {
return function(err) {
_this.emit('error', err);
return _this.stop();
};
})(this));
};
Asset.prototype.findDecoder = function(format) {
var decoder, div;
this.format = format;
if (!this.active) {
return;
}
this.emit('format', this.format);
decoder = Decoder.find(this.format.formatID);
if (!decoder) {
return this.emit('error', "A decoder for " + this.format.formatID + " was not found.");
}
this.decoder = new decoder(this.demuxer, this.format);
if (this.format.floatingPoint) {
this.decoder.on('data', (function(_this) {
return function(buffer) {
return _this.emit('data', buffer);
};
})(this));
} else {
div = Math.pow(2, this.format.bitsPerChannel - 1);
this.decoder.on('data', (function(_this) {
return function(buffer) {
var buf, i, j, len, sample;
buf = new Float32Array(buffer.length);
for (i = j = 0, len = buffer.length; j < len; i = ++j) {
sample = buffer[i];
buf[i] = sample / div;
}
return _this.emit('data', buf);
};
})(this));
}
this.decoder.on('error', (function(_this) {
return function(err) {
_this.emit('error', err);
return _this.stop();
};
})(this));
this.decoder.on('end', (function(_this) {
return function() {
return _this.emit('end');
};
})(this));
this.emit('decodeStart');
if (this.shouldDecode) {
return this._decode();
}
};
Asset.prototype._decode = function() {
while (this.decoder.decode() && this.active) {
continue;
}
if (this.active) {
return this.decoder.once('data', this._decode);
}
};
Asset.prototype.destroy = function() {
var ref, ref1, ref2;
this.stop();
if ((ref = this.demuxer) != null) {
ref.off();
}
if ((ref1 = this.decoder) != null) {
ref1.off();
}
if ((ref2 = this.source) != null) {
ref2.off();
}
return this.off();
};
return Asset;
})(EventEmitter);
module.exports = Asset;
}).call(this);
},{"./core/events":8,"./decoder":11,"./demuxer":14,"./sources/buffer":31,"./sources/node/file":29,"./sources/node/http":30}],2:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var key, ref, val;
ref = require('./aurora_base');
for (key in ref) {
val = ref[key];
exports[key] = val;
}
require('./demuxers/caf');
require('./demuxers/m4a');
require('./demuxers/aiff');
require('./demuxers/wave');
require('./demuxers/au');
require('./decoders/lpcm');
require('./decoders/xlaw');
}).call(this);
},{"./aurora_base":3,"./decoders/lpcm":12,"./decoders/xlaw":13,"./demuxers/aiff":15,"./demuxers/au":16,"./demuxers/caf":17,"./demuxers/m4a":18,"./demuxers/wave":19}],3:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
exports.Base = require('./core/base');
exports.Buffer = require('./core/buffer');
exports.BufferList = require('./core/bufferlist');
exports.Stream = require('./core/stream');
exports.Bitstream = require('./core/bitstream');
exports.EventEmitter = require('./core/events');
exports.UnderflowError = require('./core/underflow');
exports.HTTPSource = require('./sources/node/http');
exports.FileSource = require('./sources/node/file');
exports.BufferSource = require('./sources/buffer');
exports.Demuxer = require('./demuxer');
exports.Decoder = require('./decoder');
exports.AudioDevice = require('./device');
exports.Asset = require('./asset');
exports.Player = require('./player');
exports.Filter = require('./filter');
exports.VolumeFilter = require('./filters/volume');
exports.BalanceFilter = require('./filters/balance');
}).call(this);
},{"./asset":1,"./core/base":4,"./core/bitstream":5,"./core/buffer":6,"./core/bufferlist":7,"./core/events":8,"./core/stream":9,"./core/underflow":10,"./decoder":11,"./demuxer":14,"./device":20,"./filter":24,"./filters/balance":25,"./filters/volume":26,"./player":27,"./sources/buffer":31,"./sources/node/file":29,"./sources/node/http":30}],4:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var Base,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
Base = (function() {
var fnTest;
function Base() {}
fnTest = /\b_super\b/;
Base.extend = function(prop) {
var Class, _super, fn, key, keys, ref;
Class = (function(superClass) {
extend(Class, superClass);
function Class() {
return Class.__super__.constructor.apply(this, arguments);
}
return Class;
})(this);
if (typeof prop === 'function') {
keys = Object.keys(Class.prototype);
prop.call(Class, Class);
prop = {};
ref = Class.prototype;
for (key in ref) {
fn = ref[key];
if (indexOf.call(keys, key) < 0) {
prop[key] = fn;
}
}
}
_super = Class.__super__;
for (key in prop) {
fn = prop[key];
if (typeof fn === 'function' && fnTest.test(fn)) {
(function(key, fn) {
return Class.prototype[key] = function() {
var ret, tmp;
tmp = this._super;
this._super = _super[key];
ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(key, fn);
} else {
Class.prototype[key] = fn;
}
}
return Class;
};
return Base;
})();
module.exports = Base;
}).call(this);
},{}],5:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var Bitstream;
Bitstream = (function() {
function Bitstream(stream) {
this.stream = stream;
this.bitPosition = 0;
}
Bitstream.prototype.copy = function() {
var result;
result = new Bitstream(this.stream.copy());
result.bitPosition = this.bitPosition;
return result;
};
Bitstream.prototype.offset = function() {
return 8 * this.stream.offset + this.bitPosition;
};
Bitstream.prototype.available = function(bits) {
return this.stream.available((bits + 8 - this.bitPosition) / 8);
};
Bitstream.prototype.advance = function(bits) {
var pos;
pos = this.bitPosition + bits;
this.stream.advance(pos >> 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){(function (){
// Generated by CoffeeScript 1.12.7
(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)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],7:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(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.12.7
(function() {
var Base, EventEmitter,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty,
slice = [].slice;
Base = require('./base');
EventEmitter = (function(superClass) {
extend(EventEmitter, superClass);
function EventEmitter() {
return EventEmitter.__super__.constructor.apply(this, arguments);
}
EventEmitter.prototype.on = function(event, fn) {
var base;
if (this.events == null) {
this.events = {};
}
if ((base = this.events)[event] == null) {
base[event] = [];
}
return this.events[event].push(fn);
};
EventEmitter.prototype.off = function(event, fn) {
var events, index, ref;
if (this.events == null) {
return;
}
if ((ref = this.events) != null ? ref[event] : void 0) {
if (fn != null) {
index = this.events[event].indexOf(fn);
if (~index) {
return this.events[event].splice(index, 1);
}
} else {
return this.events[event];
}
} else if (event == null) {
return events = {};
}
};
EventEmitter.prototype.once = function(event, fn) {
var cb;
return this.on(event, cb = function() {
this.off(event, cb);
return fn.apply(this, arguments);
});
};
EventEmitter.prototype.emit = function() {
var args, event, fn, i, len, ref, ref1;
event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
if (!((ref = this.events) != null ? ref[event] : void 0)) {
return;
}
ref1 = this.events[event].slice();
for (i = 0, len = ref1.length; i < len; i++) {
fn = ref1[i];
fn.apply(this, args);
}
};
return EventEmitter;
})(Base);
module.exports = EventEmitter;
}).call(this);
},{"./base":4}],9:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var AVBuffer, BufferList, Stream, UnderflowError;
BufferList = require('./bufferlist');
AVBuffer = require('./buffer');
UnderflowError = require('./underflow');
Stream = (function() {
var buf, decodeString, float32, float64, float64Fallback, float80, int16, int32, int8, nativeEndian, uint16, uint32, uint8;
buf = new ArrayBuffer(16);
uint8 = new Uint8Array(buf);
int8 = new Int8Array(buf);
uint16 = new Uint16Array(buf);
int16 = new Int16Array(buf);
uint32 = new Uint32Array(buf);
int32 = new Int32Array(buf);
float32 = new Float32Array(buf);
if (typeof Float64Array !== "undefined" && Float64Array !== null) {
float64 = new Float64Array(buf);
}
nativeEndian = new Uint16Array(new Uint8Array([0x12, 0x34]).buffer)[0] === 0x3412;
function Stream(list1) {
this.list = list1;
this.localOffset = 0;
this.offset = 0;
}
Stream.fromBuffer = function(buffer) {
var list;
list = new BufferList;
list.append(buffer);
return new Stream(list);
};
Stream.prototype.copy = function() {
var result;
result = new Stream(this.list.copy());
result.localOffset = this.localOffset;
result.offset = this.offset;
return result;
};
Stream.prototype.available = function(bytes) {
return bytes <= this.list.availableBytes - this.localOffset;
};
Stream.prototype.remainingBytes = function() {
return this.list.availableBytes - this.localOffset;
};
Stream.prototype.advance = function(bytes) {
if (!this.available(bytes)) {
throw new UnderflowError();
}
this.localOffset += bytes;
this.offset += bytes;
while (this.list.first && this.localOffset >= this.list.first.length) {
this.localOffset -= this.list.first.length;
this.list.advance();
}
return this;
};
Stream.prototype.rewind = function(bytes) {
if (bytes > this.offset) {
throw new UnderflowError();
}
if (!this.list.first) {
this.list.rewind();
this.localOffset = this.list.first.length;
}
this.localOffset -= bytes;
this.offset -= bytes;
while (this.list.first.prev && this.localOffset < 0) {
this.list.rewind();
this.localOffset += this.list.first.length;
}
return this;
};
Stream.prototype.seek = function(position) {
if (position > this.offset) {
return this.advance(position - this.offset);
} else if (position < this.offset) {
return this.rewind(this.offset - position);
}
};
Stream.prototype.readUInt8 = function() {
var a;
if (!this.available(1)) {
throw new UnderflowError();
}
a = this.list.first.data[this.localOffset];
this.localOffset += 1;
this.offset += 1;
if (this.localOffset === this.list.first.length) {
this.localOffset = 0;
this.list.advance();
}
return a;
};
Stream.prototype.peekUInt8 = function(offset) {
var buffer;
if (offset == null) {
offset = 0;
}
if (!this.available(offset + 1)) {
throw new UnderflowError();
}
offset = this.localOffset + offset;
buffer = this.list.first;
while (buffer) {
if (buffer.length > offset) {
return buffer.data[offset];
}
offset -= buffer.length;
buffer = buffer.next;
}
return 0;
};
Stream.prototype.read = function(bytes, littleEndian) {
var i, j, k, ref, ref1;
if (littleEndian == null) {
littleEndian = false;
}
if (littleEndian === nativeEndian) {
for (i = j = 0, ref = bytes; j < ref; i = j += 1) {
uint8[i] = this.readUInt8();
}
} else {
for (i = k = ref1 = bytes - 1; k >= 0; i = k += -1) {
uint8[i] = this.readUInt8();
}
}
};
Stream.prototype.peek = function(bytes, offset, littleEndian) {
var i, j, k, ref, ref1;
if (littleEndian == null) {
littleEndian = false;
}
if (littleEndian === nativeEndian) {
for (i = j = 0, ref = bytes; j < ref; i = j += 1) {
uint8[i] = this.peekUInt8(offset + i);
}
} else {
for (i = k = 0, ref1 = bytes; k < ref1; i = k += 1) {
uint8[bytes - i - 1] = this.peekUInt8(offset + i);
}
}
};
Stream.prototype.readInt8 = function() {
this.read(1);
return int8[0];
};
Stream.prototype.peekInt8 = function(offset) {
if (offset == null) {
offset = 0;
}
this.peek(1, offset);
return int8[0];
};
Stream.prototype.readUInt16 = function(littleEndian) {
this.read(2, littleEndian);
return uint16[0];
};
Stream.prototype.peekUInt16 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(2, offset, littleEndian);
return uint16[0];
};
Stream.prototype.readInt16 = function(littleEndian) {
this.read(2, littleEndian);
return int16[0];
};
Stream.prototype.peekInt16 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(2, offset, littleEndian);
return int16[0];
};
Stream.prototype.readUInt24 = function(littleEndian) {
if (littleEndian) {
return this.readUInt16(true) + (this.readUInt8() << 16);
} else {
return (this.readUInt16() << 8) + this.readUInt8();
}
};
Stream.prototype.peekUInt24 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
if (littleEndian) {
return this.peekUInt16(offset, true) + (this.peekUInt8(offset + 2) << 16);
} else {
return (this.peekUInt16(offset) << 8) + this.peekUInt8(offset + 2);
}
};
Stream.prototype.readInt24 = function(littleEndian) {
if (littleEndian) {
return this.readUInt16(true) + (this.readInt8() << 16);
} else {
return (this.readInt16() << 8) + this.readUInt8();
}
};
Stream.prototype.peekInt24 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
if (littleEndian) {
return this.peekUInt16(offset, true) + (this.peekInt8(offset + 2) << 16);
} else {
return (this.peekInt16(offset) << 8) + this.peekUInt8(offset + 2);
}
};
Stream.prototype.readUInt32 = function(littleEndian) {
this.read(4, littleEndian);
return uint32[0];
};
Stream.prototype.peekUInt32 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(4, offset, littleEndian);
return uint32[0];
};
Stream.prototype.readInt32 = function(littleEndian) {
this.read(4, littleEndian);
return int32[0];
};
Stream.prototype.peekInt32 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(4, offset, littleEndian);
return int32[0];
};
Stream.prototype.readFloat32 = function(littleEndian) {
this.read(4, littleEndian);
return float32[0];
};
Stream.prototype.peekFloat32 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(4, offset, littleEndian);
return float32[0];
};
Stream.prototype.readFloat64 = function(littleEndian) {
this.read(8, littleEndian);
if (float64) {
return float64[0];
} else {
return float64Fallback();
}
};
float64Fallback = function() {
var exp, frac, high, low, out, sign;
low = uint32[0], high = uint32[1];
if (!high || high === 0x80000000) {
return 0.0;
}
sign = 1 - (high >>> 31) * 2;
exp = (high >>> 20) & 0x7ff;
frac = high & 0xfffff;
if (exp === 0x7ff) {
if (frac) {
return 0/0;
}
return sign * 2e308;
}
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 * 2e308;
}
return 0/0;
}
exp -= 16383;
out = low * Math.pow(2, exp - 31);
out += high * Math.pow(2, exp - 63);
return sign * out;
};
Stream.prototype.peekFloat80 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(10, offset, littleEndian);
return float80();
};
Stream.prototype.readBuffer = function(length) {
var i, j, ref, result, to;
result = AVBuffer.allocate(length);
to = result.data;
for (i = j = 0, ref = length; j < ref; i = j += 1) {
to[i] = this.readUInt8();
}
return result;
};
Stream.prototype.peekBuffer = function(offset, length) {
var i, j, ref, result, to;
if (offset == null) {
offset = 0;
}
result = AVBuffer.allocate(length);
to = result.data;
for (i = j = 0, ref = length; j < ref; i = j += 1) {
to[i] = this.peekUInt8(offset + i);
}
return result;
};
Stream.prototype.readSingleBuffer = function(length) {
var result;
result = this.list.first.slice(this.localOffset, length);
this.advance(result.length);
return result;
};
Stream.prototype.peekSingleBuffer = function(offset, length) {
var result;
result = this.list.first.slice(this.localOffset + offset, length);
return result;
};
Stream.prototype.readString = function(length, encoding) {
if (encoding == null) {
encoding = 'ascii';
}
return decodeString.call(this, 0, length, encoding, true);
};
Stream.prototype.peekString = function(offset, length, encoding) {
if (offset == null) {
offset = 0;
}
if (encoding == null) {
encoding = 'ascii';
}
return decodeString.call(this, offset, length, encoding, false);
};
decodeString = function(offset, length, encoding, advance) {
var b1, b2, b3, b4, bom, c, end, littleEndian, nullEnd, pt, result, w1, w2;
encoding = encoding.toLowerCase();
nullEnd = length === null ? 0 : -1;
if (length == null) {
length = 2e308;
}
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.12.7
(function() {
var UnderflowError,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
UnderflowError = (function(superClass) {
extend(UnderflowError, superClass);
function UnderflowError() {
UnderflowError.__super__.constructor.apply(this, arguments);
this.name = 'UnderflowError';
this.stack = new Error().stack;
}
return UnderflowError;
})(Error);
module.exports = UnderflowError;
}).call(this);
},{}],11:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var Bitstream, BufferList, Decoder, EventEmitter, Stream, UnderflowError,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('./core/events');
BufferList = require('./core/bufferlist');
Stream = require('./core/stream');
Bitstream = require('./core/bitstream');
UnderflowError = require('./core/underflow');
Decoder = (function(superClass) {
var codecs;
extend(Decoder, superClass);
function Decoder(demuxer, format) {
var list;
this.demuxer = demuxer;
this.format = format;
list = new BufferList;
this.stream = new Stream(list);
this.bitstream = new Bitstream(this.stream);
this.receivedFinalBuffer = false;
this.waiting = false;
this.demuxer.on('cookie', (function(_this) {
return function(cookie) {
var error;
try {
return _this.setCookie(cookie);
} catch (error1) {
error = error1;
return _this.emit('error', error);
}
};
})(this));
this.demuxer.on('data', (function(_this) {
return function(chunk) {
list.append(chunk);
if (_this.waiting) {
return _this.decode();
}
};
})(this));
this.demuxer.on('end', (function(_this) {
return function() {
_this.receivedFinalBuffer = true;
if (_this.waiting) {
return _this.decode();
}
};
})(this));
this.init();
}
Decoder.prototype.init = function() {};
Decoder.prototype.setCookie = function(cookie) {};
Decoder.prototype.readChunk = function() {};
Decoder.prototype.decode = function() {
var error, offset, packet;
this.waiting = !this.receivedFinalBuffer;
offset = this.bitstream.offset();
try {
packet = this.readChunk();
} catch (error1) {
error = error1;
if (!(error instanceof UnderflowError)) {
this.emit('error', error);
return false;
}
}
if (packet) {
this.emit('data', packet);
if (this.receivedFinalBuffer) {
this.emit('end');
}
return true;
} else if (!this.receivedFinalBuffer) {
this.bitstream.seek(offset);
this.waiting = true;
} else {
this.emit('end');
}
return false;
};
Decoder.prototype.seek = function(timestamp) {
var seekPoint;
seekPoint = this.demuxer.seek(timestamp);
this.stream.seek(seekPoint.offset);
return seekPoint.timestamp;
};
codecs = {};
Decoder.register = function(id, decoder) {
return codecs[id] = decoder;
};
Decoder.find = function(id) {
return codecs[id] || null;
};
return Decoder;
})(EventEmitter);
module.exports = Decoder;
}).call(this);
},{"./core/bitstream":5,"./core/bufferlist":7,"./core/events":8,"./core/stream":9,"./core/underflow":10}],12:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var Decoder, LPCMDecoder,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Decoder = require('../decoder');
LPCMDecoder = (function(superClass) {
extend(LPCMDecoder, superClass);
function LPCMDecoder() {
this.readChunk = bind(this.readChunk, this);
return LPCMDecoder.__super__.constructor.apply(this, arguments);
}
Decoder.register('lpcm', LPCMDecoder);
LPCMDecoder.prototype.readChunk = function() {
var chunkSize, i, j, k, l, littleEndian, m, n, o, output, ref, ref1, ref2, ref3, ref4, ref5, samples, stream;
stream = this.stream;
littleEndian = this.format.littleEndian;
chunkSize = Math.min(4096, stream.remainingBytes());
samples = chunkSize / (this.format.bitsPerChannel / 8) | 0;
if (chunkSize < this.format.bitsPerChannel / 8) {
return null;
}
if (this.format.floatingPoint) {
switch (this.format.bitsPerChannel) {
case 32:
output = new Float32Array(samples);
for (i = j = 0, ref = samples; j < ref; i = j += 1) {
output[i] = stream.readFloat32(littleEndian);
}
break;
case 64:
output = new Float64Array(samples);
for (i = k = 0, ref1 = samples; k < ref1; i = k += 1) {
output[i] = stream.readFloat64(littleEndian);
}
break;
default:
throw new Error('Unsupported bit depth.');
}
} else {
switch (this.format.bitsPerChannel) {
case 8:
output = new Int8Array(samples);
for (i = l = 0, ref2 = samples; l < ref2; i = l += 1) {
output[i] = stream.readInt8();
}
break;
case 16:
output = new Int16Array(samples);
for (i = m = 0, ref3 = samples; m < ref3; i = m += 1) {
output[i] = stream.readInt16(littleEndian);
}
break;
case 24:
output = new Int32Array(samples);
for (i = n = 0, ref4 = samples; n < ref4; i = n += 1) {
output[i] = stream.readInt24(littleEndian);
}
break;
case 32:
output = new Int32Array(samples);
for (i = o = 0, ref5 = samples; o < ref5; i = o += 1) {
output[i] = stream.readInt32(littleEndian);
}
break;
default:
throw new Error('Unsupported bit depth.');
}
}
return output;
};
return LPCMDecoder;
})(Decoder);
}).call(this);
},{"../decoder":11}],13:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var Decoder, XLAWDecoder,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Decoder = require('../decoder');
XLAWDecoder = (function(superClass) {
var BIAS, QUANT_MASK, SEG_MASK, SEG_SHIFT, SIGN_BIT;
extend(XLAWDecoder, superClass);
function XLAWDecoder() {
this.readChunk = bind(this.readChunk, this);
return XLAWDecoder.__super__.constructor.apply(this, arguments);
}
Decoder.register('ulaw', XLAWDecoder);
Decoder.register('alaw', XLAWDecoder);
SIGN_BIT = 0x80;
QUANT_MASK = 0xf;
SEG_SHIFT = 4;
SEG_MASK = 0x70;
BIAS = 0x84;
XLAWDecoder.prototype.init = function() {
var i, j, k, seg, t, table, val;
this.format.bitsPerChannel = 16;
this.table = table = new Int16Array(256);
if (this.format.formatID === 'ulaw') {
for (i = j = 0; j < 256; i = ++j) {
val = ~i;
t = ((val & QUANT_MASK) << 3) + BIAS;
t <<= (val & SEG_MASK) >>> SEG_SHIFT;
table[i] = val & SIGN_BIT ? BIAS - t : t - BIAS;
}
} else {
for (i = k = 0; k < 256; i = ++k) {
val = i ^ 0x55;
t = val & QUANT_MASK;
seg = (val & SEG_MASK) >>> SEG_SHIFT;
if (seg) {
t = (t + t + 1 + 32) << (seg + 2);
} else {
t = (t + t + 1) << 3;
}
table[i] = val & SIGN_BIT ? t : -t;
}
}
};
XLAWDecoder.prototype.readChunk = function() {
var i, j, output, ref, ref1, samples, stream, table;
ref = this, stream = ref.stream, table = ref.table;
samples = Math.min(4096, this.stream.remainingBytes());
if (samples === 0) {
return;
}
output = new Int16Array(samples);
for (i = j = 0, ref1 = samples; j < ref1; i = j += 1) {
output[i] = table[stream.readUInt8()];
}
return output;
};
return XLAWDecoder;
})(Decoder);
}).call(this);
},{"../decoder":11}],14:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var BufferList, Demuxer, EventEmitter, Stream,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('./core/events');
BufferList = require('./core/bufferlist');
Stream = require('./core/stream');
Demuxer = (function(superClass) {
var formats;
extend(Demuxer, superClass);
Demuxer.probe = function(buffer) {
return false;
};
function Demuxer(source, chunk) {
var list, received;
list = new BufferList;
list.append(chunk);
this.stream = new Stream(list);
received = false;
source.on('data', (function(_this) {
return function(chunk) {
var e;
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, i, len, offset, stream;
stream = Stream.fromBuffer(buffer);
for (i = 0, len = formats.length; i < len; i++) {
format = formats[i];
offset = stream.offset;
try {
if (format.probe(stream)) {
return format;
}
} catch (error) {
e = error;
}
stream.seek(offset);
}
return null;
};
return Demuxer;
})(EventEmitter);
module.exports = Demuxer;
}).call(this);
},{"./core/bufferlist":7,"./core/events":8,"./core/stream":9}],15:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var AIFFDemuxer, Demuxer,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Demuxer = require('../demuxer');
AIFFDemuxer = (function(superClass) {
extend(AIFFDemuxer, superClass);
function AIFFDemuxer() {
return AIFFDemuxer.__super__.constructor.apply(this, arguments);
}
Demuxer.register(AIFFDemuxer);
AIFFDemuxer.probe = function(buffer) {
var ref;
return buffer.peekString(0, 4) === 'FORM' && ((ref = buffer.peekString(8, 4)) === 'AIFF' || ref === 'AIFC');
};
AIFFDemuxer.prototype.readChunk = function() {
var buffer, format, offset, ref;
if (!this.readStart && this.stream.available(12)) {
if (this.stream.readString(4) !== 'FORM') {
return this.emit('error', 'Invalid AIFF.');
}
this.fileSize = this.stream.readUInt32();
this.fileType = this.stream.readString(4);
this.readStart = true;
if ((ref = this.fileType) !== 'AIFF' && ref !== 'AIFC') {
return this.emit('error', 'Invalid AIFF.');
}
}
while (this.stream.available(1)) {
if (!this.readHeaders && this.stream.available(8)) {
this.type = this.stream.readString(4);
this.len = this.stream.readUInt32();
}
switch (this.type) {
case 'COMM':
if (!this.stream.available(this.len)) {
return;
}
this.format = {
formatID: 'lpcm',
channelsPerFrame: this.stream.readUInt16(),
sampleCount: this.stream.readUInt32(),
bitsPerChannel: this.stream.readUInt16(),
sampleRate: this.stream.readFloat80(),
framesPerPacket: 1,
littleEndian: false,
floatingPoint: false
};
this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
if (this.fileType === 'AIFC') {
format = this.stream.readString(4);
this.format.littleEndian = format === 'sowt' && this.format.bitsPerChannel > 8;
this.format.floatingPoint = format === 'fl32' || format === 'fl64';
if (format === 'twos' || format === 'sowt' || format === 'fl32' || format === 'fl64' || format === 'NONE') {
format = 'lpcm';
}
this.format.formatID = format;
this.len -= 4;
}
this.stream.advance(this.len - 18);
this.emit('format', this.format);
this.emit('duration', this.format.sampleCount / this.format.sampleRate * 1000 | 0);
break;
case 'SSND':
if (!(this.readSSNDHeader && this.stream.available(4))) {
offset = this.stream.readUInt32();
this.stream.advance(4);
this.stream.advance(offset);
this.readSSNDHeader = true;
}
buffer = this.stream.readSingleBuffer(this.len);
this.len -= buffer.length;
this.readHeaders = this.len > 0;
this.emit('data', buffer);
break;
default:
if (!this.stream.available(this.len)) {
return;
}
this.stream.advance(this.len);
}
if (this.type !== 'SSND') {
this.readHeaders = false;
}
}
};
return AIFFDemuxer;
})(Demuxer);
}).call(this);
},{"../demuxer":14}],16:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var AUDemuxer, Demuxer,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Demuxer = require('../demuxer');
AUDemuxer = (function(superClass) {
var bps, formats;
extend(AUDemuxer, superClass);
function AUDemuxer() {
return AUDemuxer.__super__.constructor.apply(this, arguments);
}
Demuxer.register(AUDemuxer);
AUDemuxer.probe = function(buffer) {
return buffer.peekString(0, 4) === '.snd';
};
bps = [8, 8, 16, 24, 32, 32, 64];
bps[26] = 8;
formats = {
1: 'ulaw',
27: 'alaw'
};
AUDemuxer.prototype.readChunk = function() {
var bytes, dataSize, encoding, size;
if (!this.readHeader && this.stream.available(24)) {
if (this.stream.readString(4) !== '.snd') {
return this.emit('error', 'Invalid AU file.');
}
size = this.stream.readUInt32();
dataSize = this.stream.readUInt32();
encoding = this.stream.readUInt32();
this.format = {
formatID: formats[encoding] || 'lpcm',
littleEndian: false,
floatingPoint: encoding === 6 || encoding === 7,
bitsPerChannel: bps[encoding - 1],
sampleRate: this.stream.readUInt32(),
channelsPerFrame: this.stream.readUInt32(),
framesPerPacket: 1
};
if (this.format.bitsPerChannel == null) {
return this.emit('error', 'Unsupported encoding in AU file.');
}
this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
if (dataSize !== 0xffffffff) {
bytes = this.format.bitsPerChannel / 8;
this.emit('duration', dataSize / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0);
}
this.emit('format', this.format);
this.readHeader = true;
}
if (this.readHeader) {
while (this.stream.available(1)) {
this.emit('data', this.stream.readSingleBuffer(this.stream.remainingBytes()));
}
}
};
return AUDemuxer;
})(Demuxer);
}).call(this);
},{"../demuxer":14}],17:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var CAFDemuxer, Demuxer, M4ADemuxer,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Demuxer = require('../demuxer');
M4ADemuxer = require('./m4a');
CAFDemuxer = (function(superClass) {
extend(CAFDemuxer, superClass);
function CAFDemuxer() {
return CAFDemuxer.__super__.constructor.apply(this, arguments);
}
Demuxer.register(CAFDemuxer);
CAFDemuxer.probe = function(buffer) {
return buffer.peekString(0, 4) === 'caff';
};
CAFDemuxer.prototype.readChunk = function() {
var buffer, byteOffset, cookie, entries, flags, i, j, k, key, metadata, offset, ref, ref1, sampleOffset, value;
if (!this.format && this.stream.available(64)) {
if (this.stream.readString(4) !== 'caff') {
return this.emit('error', "Invalid CAF, does not begin with 'caff'");
}
this.stream.advance(4);
if (this.stream.readString(4) !== 'desc') {
return this.emit('error', "Invalid CAF, 'caff' is not followed by 'desc'");
}
if (!(this.stream.readUInt32() === 0 && this.stream.readUInt32() === 32)) {
return this.emit('error', "Invalid 'desc' size, should be 32");
}
this.format = {};
this.format.sampleRate = this.stream.readFloat64();
this.format.formatID = this.stream.readString(4);
flags = this.stream.readUInt32();
if (this.format.formatID === 'lpcm') {
this.format.floatingPoint = Boolean(flags & 1);
this.format.littleEndian = Boolean(flags & 2);
}
this.format.bytesPerPacket = this.stream.readUInt32();
this.format.framesPerPacket = this.stream.readUInt32();
this.format.channelsPerFrame = this.stream.readUInt32();
this.format.bitsPerChannel = this.stream.readUInt32();
this.emit('format', this.format);
}
while (this.stream.available(1)) {
if (!this.headerCache) {
this.headerCache = {
type: this.stream.readString(4),
oversize: this.stream.readUInt32() !== 0,
size: this.stream.readUInt32()
};
if (this.headerCache.oversize) {
return this.emit('error', "Holy Shit, an oversized file, not supported in JS");
}
}
switch (this.headerCache.type) {
case 'kuki':
if (this.stream.available(this.headerCache.size)) {
if (this.format.formatID === 'aac ') {
offset = this.stream.offset + this.headerCache.size;
if (cookie = M4ADemuxer.readEsds(this.stream)) {
this.emit('cookie', cookie);
}
this.stream.seek(offset);
} else {
buffer = this.stream.readBuffer(this.headerCache.size);
this.emit('cookie', buffer);
}
this.headerCache = null;
}
break;
case 'pakt':
if (this.stream.available(this.headerCache.size)) {
if (this.stream.readUInt32() !== 0) {
return this.emit('error', 'Sizes greater than 32 bits are not supported.');
}
this.numPackets = this.stream.readUInt32();
if (this.stream.readUInt32() !== 0) {
return this.emit('error', 'Sizes greater than 32 bits are not supported.');
}
this.numFrames = this.stream.readUInt32();
this.primingFrames = this.stream.readUInt32();
this.remainderFrames = this.stream.readUInt32();
this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0);
this.sentDuration = true;
byteOffset = 0;
sampleOffset = 0;
for (i = j = 0, ref = this.numPackets; j < ref; i = j += 1) {
this.addSeekPoint(byteOffset, sampleOffset);
byteOffset += this.format.bytesPerPacket || M4ADemuxer.readDescrLen(this.stream);
sampleOffset += this.format.framesPerPacket || M4ADemuxer.readDescrLen(this.stream);
}
this.headerCache = null;
}
break;
case 'info':
entries = this.stream.readUInt32();
metadata = {};
for (i = k = 0, ref1 = entries; 0 <= ref1 ? k < ref1 : k > ref1; i = 0 <= ref1 ? ++k : --k) {
key = this.stream.readString(null);
value = this.stream.readString(null);
metadata[key] = value;
}
this.emit('metadata', metadata);
this.headerCache = null;
break;
case 'data':
if (!this.sentFirstDataChunk) {
this.stream.advance(4);
this.headerCache.size -= 4;
if (this.format.bytesPerPacket !== 0 && !this.sentDuration) {
this.numFrames = this.headerCache.size / this.format.bytesPerPacket;
this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0);
}
this.sentFirstDataChunk = true;
}
buffer = this.stream.readSingleBuffer(this.headerCache.size);
this.headerCache.size -= buffer.length;
this.emit('data', buffer);
if (this.headerCache.size <= 0) {
this.headerCache = null;
}
break;
default:
if (this.stream.available(this.headerCache.size)) {
this.stream.advance(this.headerCache.size);
this.headerCache = null;
}
}
}
};
return CAFDemuxer;
})(Demuxer);
}).call(this);
},{"../demuxer":14,"./m4a":18}],18:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var Demuxer, M4ADemuxer,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
Demuxer = require('../demuxer');
M4ADemuxer = (function(superClass) {
var BITS_PER_CHANNEL, TYPES, after, atom, atoms, bool, containers, diskTrack, genres, meta, string;
extend(M4ADemuxer, superClass);
function M4ADemuxer() {
return M4ADemuxer.__super__.constructor.apply(this, arguments);
}
Demuxer.register(M4ADemuxer);
TYPES = ['M4A ', 'M4P ', 'M4B ', 'M4V ', 'isom', 'mp42', 'qt '];
M4ADemuxer.probe = function(buffer) {
var ref;
return buffer.peekString(4, 4) === 'ftyp' && (ref = buffer.peekString(8, 4), indexOf.call(TYPES, ref) >= 0);
};
M4ADemuxer.prototype.init = function() {
this.atoms = [];
this.offsets = [];
this.track = null;
return this.tracks = [];
};
atoms = {};
containers = {};
atom = function(name, fn) {
var c, container, k, len1, ref;
c = [];
ref = name.split('.').slice(0, -1);
for (k = 0, len1 = ref.length; k < len1; k++) {
container = ref[k];
c.push(container);
containers[c.join('.')] = true;
}
if (atoms[name] == null) {
atoms[name] = {};
}
return atoms[name].fn = fn;
};
after = function(name, fn) {
if (atoms[name] == null) {
atoms[name] = {};
}
return atoms[name].after = fn;
};
M4ADemuxer.prototype.readChunk = function() {
var handler, path, type;
this["break"] = false;
while (this.stream.available(1) && !this["break"]) {
if (!this.readHeaders) {
if (!this.stream.available(8)) {
return;
}
this.len = this.stream.readUInt32() - 8;
this.type = this.stream.readString(4);
if (this.len === 0) {
continue;
}
this.atoms.push(this.type);
this.offsets.push(this.stream.offset + this.len);
this.readHeaders = true;
}
path = this.atoms.join('.');
handler = atoms[path];
if (handler != null ? handler.fn : void 0) {
if (!(this.stream.available(this.len) || path === 'mdat')) {
return;
}
handler.fn.call(this);
if (path in containers) {
this.readHeaders = false;
}
} else if (path in containers) {
this.readHeaders = false;
} else {
if (!this.stream.available(this.len)) {
return;
}
this.stream.advance(this.len);
}
while (this.stream.offset >= this.offsets[this.offsets.length - 1]) {
handler = atoms[this.atoms.join('.')];
if (handler != null ? handler.after : void 0) {
handler.after.call(this);
}
type = this.atoms.pop();
this.offsets.pop();
this.readHeaders = false;
}
}
};
atom('ftyp', function() {
var ref;
if (ref = this.stream.readString(4), indexOf.call(TYPES, ref) < 0) {
return this.emit('error', 'Not a valid M4A file.');
}
return this.stream.advance(this.len - 4);
});
atom('moov.trak', function() {
this.track = {};
return this.tracks.push(this.track);
});
atom('moov.trak.tkhd', function() {
this.stream.advance(4);
this.stream.advance(8);
this.track.id = this.stream.readUInt32();
return this.stream.advance(this.len - 16);
});
atom('moov.trak.mdia.hdlr', function() {
this.stream.advance(4);
this.stream.advance(4);
this.track.type = this.stream.readString(4);
this.stream.advance(12);
return this.stream.advance(this.len - 24);
});
atom('moov.trak.mdia.mdhd', function() {
this.stream.advance(4);
this.stream.advance(8);
this.track.timeScale = this.stream.readUInt32();
this.track.duration = this.stream.readUInt32();
return this.stream.advance(4);
});
BITS_PER_CHANNEL = {
ulaw: 8,
alaw: 8,
in24: 24,
in32: 32,
fl32: 32,
fl64: 64
};
atom('moov.trak.mdia.minf.stbl.stsd', function() {
var format, numEntries, ref, ref1, version;
this.stream.advance(4);
numEntries = this.stream.readUInt32();
if (this.track.type !== 'soun') {
return this.stream.advance(this.len - 8);
}
if (numEntries !== 1) {
return this.emit('error', "Only expecting one entry in sample description atom!");
}
this.stream.advance(4);
format = this.track.format = {};
format.formatID = this.stream.readString(4);
this.stream.advance(6);
this.stream.advance(2);
version = this.stream.readUInt16();
this.stream.advance(6);
format.channelsPerFrame = this.stream.readUInt16();
format.bitsPerChannel = this.stream.readUInt16();
this.stream.advance(4);
format.sampleRate = this.stream.readUInt16();
this.stream.advance(2);
if (version === 1) {
format.framesPerPacket = this.stream.readUInt32();
this.stream.advance(4);
format.bytesPerFrame = this.stream.readUInt32();
this.stream.advance(4);
} else if (version !== 0) {
this.emit('error', 'Unknown version in stsd atom');
}
if (BITS_PER_CHANNEL[format.formatID] != null) {
format.bitsPerChannel = BITS_PER_CHANNEL[format.formatID];
}
format.floatingPoint = (ref = format.formatID) === 'fl32' || ref === 'fl64';
format.littleEndian = format.formatID === 'sowt' && format.bitsPerChannel > 8;
if ((ref1 = format.formatID) === 'twos' || ref1 === 'sowt' || ref1 === 'in24' || ref1 === 'in32' || ref1 === 'fl32' || ref1 === 'fl64' || ref1 === 'raw ' || ref1 === 'NONE') {
return format.formatID = 'lpcm';
}
});
atom('moov.trak.mdia.minf.stbl.stsd.alac', function() {
this.stream.advance(4);
return this.track.cookie = this.stream.readBuffer(this.len - 4);
});
atom('moov.trak.mdia.minf.stbl.stsd.esds', function() {
var offset;
offset = this.stream.offset + this.len;
this.track.cookie = M4ADemuxer.readEsds(this.stream);
return this.stream.seek(offset);
});
atom('moov.trak.mdia.minf.stbl.stsd.wave.enda', function() {
return this.track.format.littleEndian = !!this.stream.readUInt16();
});
M4ADemuxer.readDescrLen = function(stream) {
var c, count, len;
len = 0;
count = 4;
while (count--) {
c = stream.readUInt8();
len = (len << 7) | (c & 0x7f);
if (!(c & 0x80)) {
break;
}
}
return len;
};
M4ADemuxer.readEsds = function(stream) {
var codec_id, flags, len, tag;
stream.advance(4);
tag = stream.readUInt8();
len = M4ADemuxer.readDescrLen(stream);
if (tag === 0x03) {
stream.advance(2);
flags = stream.readUInt8();
if (flags & 0x80) {
stream.advance(2);
}
if (flags & 0x40) {
stream.advance(stream.readUInt8());
}
if (flags & 0x20) {
stream.advance(2);
}
} else {
stream.advance(2);
}
tag = stream.readUInt8();
len = M4ADemuxer.readDescrLen(stream);
if (tag === 0x04) {
codec_id = stream.readUInt8();
stream.advance(1);
stream.advance(3);
stream.advance(4);
stream.advance(4);
tag = stream.readUInt8();
len = M4ADemuxer.readDescrLen(stream);
if (tag === 0x05) {
return stream.readBuffer(len);
}
}
return null;
};
atom('moov.trak.mdia.minf.stbl.stts', function() {
var entries, i, k, ref;
this.stream.advance(4);
entries = this.stream.readUInt32();
this.track.stts = [];
for (i = k = 0, ref = entries; k < ref; i = k += 1) {
this.track.stts[i] = {
count: this.stream.readUInt32(),
duration: this.stream.readUInt32()
};
}
return this.setupSeekPoints();
});
atom('moov.trak.mdia.minf.stbl.stsc', function() {
var entries, i, k, ref;
this.stream.advance(4);
entries = this.stream.readUInt32();
this.track.stsc = [];
for (i = k = 0, ref = entries; k < ref; i = k += 1) {
this.track.stsc[i] = {
first: this.stream.readUInt32(),
count: this.stream.readUInt32(),
id: this.stream.readUInt32()
};
}
return this.setupSeekPoints();
});
atom('moov.trak.mdia.minf.stbl.stsz', function() {
var entries, i, k, ref;
this.stream.advance(4);
this.track.sampleSize = this.stream.readUInt32();
entries = this.stream.readUInt32();
if (this.track.sampleSize === 0 && entries > 0) {
this.track.sampleSizes = [];
for (i = k = 0, ref = entries; k < ref; i = k += 1) {
this.track.sampleSizes[i] = this.stream.readUInt32();
}
}
return this.setupSeekPoints();
});
atom('moov.trak.mdia.minf.stbl.stco', function() {
var entries, i, k, ref;
this.stream.advance(4);
entries = this.stream.readUInt32();
this.track.chunkOffsets = [];
for (i = k = 0, ref = entries; k < ref; i = k += 1) {
this.track.chunkOffsets[i] = this.stream.readUInt32();
}
return this.setupSeekPoints();
});
atom('moov.trak.tref.chap', function() {
var entries, i, k, ref;
entries = this.len >> 2;
this.track.chapterTracks = [];
for (i = k = 0, ref = entries; k < ref; i = k += 1) {
this.track.chapterTracks[i] = this.stream.readUInt32();
}
});
M4ADemuxer.prototype.setupSeekPoints = function() {
var i, j, k, l, len1, offset, position, ref, ref1, results, sampleIndex, size, stscIndex, sttsIndex, sttsSample, timestamp;
if (!((this.track.chunkOffsets != null) && (this.track.stsc != null) && (this.track.sampleSize != null) && (this.track.stts != null))) {
return;
}
stscIndex = 0;
sttsIndex = 0;
sttsIndex = 0;
sttsSample = 0;
sampleIndex = 0;
offset = 0;
timestamp = 0;
this.track.seekPoints = [];
ref = this.track.chunkOffsets;
results = [];
for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
position = ref[i];
for (j = l = 0, ref1 = this.track.stsc[stscIndex].count; l < ref1; j = l += 1) {
this.track.seekPoints.push({
offset: offset,
position: position,
timestamp: timestamp
});
size = this.track.sampleSize || this.track.sampleSizes[sampleIndex++];
offset += size;
position += size;
timestamp += this.track.stts[sttsIndex].duration;
if (sttsIndex + 1 < this.track.stts.length && ++sttsSample === this.track.stts[sttsIndex].count) {
sttsSample = 0;
sttsIndex++;
}
}
if (stscIndex + 1 < this.track.stsc.length && i + 1 === this.track.stsc[stscIndex + 1].first) {
results.push(stscIndex++);
} else {
results.push(void 0);
}
}
return results;
};
after('moov', function() {
var k, len1, ref, track;
if (this.mdatOffset != null) {
this.stream.seek(this.mdatOffset - 8);
}
ref = this.tracks;
for (k = 0, len1 = ref.length; k < len1; k++) {
track = ref[k];
if (!(track.type === 'soun')) {
continue;
}
this.track = track;
break;
}
if (this.track.type !== 'soun') {
this.track = null;
return this.emit('error', 'No audio tracks in m4a file.');
}
this.emit('format', this.track.format);
this.emit('duration', this.track.duration / this.track.timeScale * 1000 | 0);
if (this.track.cookie) {
this.emit('cookie', this.track.cookie);
}
return this.seekPoints = this.track.seekPoints;
});
atom('mdat', function() {
var bytes, chunkSize, k, length, numSamples, offset, ref, sample, size;
if (!this.startedData) {
if (this.mdatOffset == null) {
this.mdatOffset = this.stream.offset;
}
if (this.tracks.length === 0) {
bytes = Math.min(this.stream.remainingBytes(), this.len);
this.stream.advance(bytes);
this.len -= bytes;
return;
}
this.chunkIndex = 0;
this.stscIndex = 0;
this.sampleIndex = 0;
this.tailOffset = 0;
this.tailSamples = 0;
this.startedData = true;
}
if (!this.readChapters) {
this.readChapters = this.parseChapters();
if (this["break"] = !this.readChapters) {
return;
}
this.stream.seek(this.mdatOffset);
}
offset = this.track.chunkOffsets[this.chunkIndex] + this.tailOffset;
length = 0;
if (!this.stream.available(offset - this.stream.offset)) {
this["break"] = true;
return;
}
this.stream.seek(offset);
while (this.chunkIndex < this.track.chunkOffsets.length) {
numSamples = this.track.stsc[this.stscIndex].count - this.tailSamples;
chunkSize = 0;
for (sample = k = 0, ref = numSamples; k < ref; sample = k += 1) {
size = this.track.sampleSize || this.track.sampleSizes[this.sampleIndex];
if (!this.stream.available(length + size)) {
break;
}
length += size;
chunkSize += size;
this.sampleIndex++;
}
if (sample < numSamples) {
this.tailOffset += chunkSize;
this.tailSamples += sample;
break;
} else {
this.chunkIndex++;
this.tailOffset = 0;
this.tailSamples = 0;
if (this.stscIndex + 1 < this.track.stsc.length && this.chunkIndex + 1 === this.track.stsc[this.stscIndex + 1].first) {
this.stscIndex++;
}
if (offset + length !== this.track.chunkOffsets[this.chunkIndex]) {
break;
}
}
}
if (length > 0) {
this.emit('data', this.stream.readBuffer(length));
return this["break"] = this.chunkIndex === this.track.chunkOffsets.length;
} else {
return this["break"] = true;
}
});
M4ADemuxer.prototype.parseChapters = function() {
var bom, id, k, len, len1, nextTimestamp, point, ref, ref1, ref2, ref3, title, track;
if (!(((ref = this.track.chapterTracks) != null ? ref.length : void 0) > 0)) {
return true;
}
id = this.track.chapterTracks[0];
ref1 = this.tracks;
for (k = 0, len1 = ref1.length; k < len1; k++) {
track = ref1[k];
if (track.id === id) {
break;
}
}
if (track.id !== id) {
this.emit('error', 'Chapter track does not exist.');
}
if (this.chapters == null) {
this.chapters = [];
}
while (this.chapters.length < track.seekPoints.length) {
point = track.seekPoints[this.chapters.length];
if (!this.stream.available(point.position - this.stream.offset + 32)) {
return false;
}
this.stream.seek(point.position);
len = this.stream.readUInt16();
title = null;
if (!this.stream.available(len)) {
return false;
}
if (len > 2) {
bom = this.stream.peekUInt16();
if (bom === 0xfeff || bom === 0xfffe) {
title = this.stream.readString(len, 'utf16-bom');
}
}
if (title == null) {
title = this.stream.readString(len, 'utf8');
}
nextTimestamp = (ref2 = (ref3 = track.seekPoints[this.chapters.length + 1]) != null ? ref3.timestamp : void 0) != null ? ref2 : track.duration;
this.chapters.push({
title: title,
timestamp: point.timestamp / track.timeScale * 1000 | 0,
duration: (nextTimestamp - point.timestamp) / track.timeScale * 1000 | 0
});
}
this.emit('chapters', this.chapters);
return true;
};
atom('moov.udta.meta', function() {
this.metadata = {};
return this.stream.advance(4);
});
after('moov.udta.meta', function() {
return this.emit('metadata', this.metadata);
});
meta = function(field, name, fn) {
return atom("moov.udta.meta.ilst." + field + ".data", function() {
this.stream.advance(8);
this.len -= 8;
return fn.call(this, name);
});
};
string = function(field) {
return this.metadata[field] = this.stream.readString(this.len, 'utf8');
};
meta('©alb', 'album', string);
meta('©arg', 'arranger', string);
meta('©art', 'artist', string);
meta('©ART', 'artist', string);
meta('aART', 'albumArtist', string);
meta('catg', 'category', string);
meta('©com', 'composer', string);
meta('©cpy', 'copyright', string);
meta('cprt', 'copyright', string);
meta('©cmt', 'comments', string);
meta('©day', 'releaseDate', string);
meta('desc', 'description', string);
meta('©gen', 'genre', string);
meta('©grp', 'grouping', string);
meta('©isr', 'ISRC', string);
meta('keyw', 'keywords', string);
meta('©lab', 'recordLabel', string);
meta('ldes', 'longDescription', string);
meta('©lyr', 'lyrics', string);
meta('©nam', 'title', string);
meta('©phg', 'recordingCopyright', string);
meta('©prd', 'producer', string);
meta('©prf', 'performers', string);
meta('purd', 'purchaseDate', string);
meta('purl', 'podcastURL', string);
meta('©swf', 'songwriter', string);
meta('©too', 'encoder', string);
meta('©wrt', 'composer', string);
meta('covr', 'coverArt', function(field) {
return this.metadata[field] = this.stream.readBuffer(this.len);
});
genres = ["Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Capella", "Euro-House", "Dance Hall"];
meta('gnre', 'genre', function(field) {
return this.metadata[field] = genres[this.stream.readUInt16() - 1];
});
meta('tmpo', 'tempo', function(field) {
return this.metadata[field] = this.stream.readUInt16();
});
meta('rtng', 'rating', function(field) {
var rating;
rating = this.stream.readUInt8();
return this.metadata[field] = rating === 2 ? 'Clean' : rating !== 0 ? 'Explicit' : 'None';
});
diskTrack = function(field) {
this.stream.advance(2);
this.metadata[field] = this.stream.readUInt16() + ' of ' + this.stream.readUInt16();
return this.stream.advance(this.len - 6);
};
meta('disk', 'diskNumber', diskTrack);
meta('trkn', 'trackNumber', diskTrack);
bool = function(field) {
return this.metadata[field] = this.stream.readUInt8() === 1;
};
meta('cpil', 'compilation', bool);
meta('pcst', 'podcast', bool);
meta('pgap', 'gapless', bool);
return M4ADemuxer;
})(Demuxer);
module.exports = M4ADemuxer;
}).call(this);
},{"../demuxer":14}],19:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var Demuxer, WAVEDemuxer,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Demuxer = require('../demuxer');
WAVEDemuxer = (function(superClass) {
var formats;
extend(WAVEDemuxer, superClass);
function WAVEDemuxer() {
return WAVEDemuxer.__super__.constructor.apply(this, arguments);
}
Demuxer.register(WAVEDemuxer);
WAVEDemuxer.probe = function(buffer) {
return buffer.peekString(0, 4) === 'RIFF' && buffer.peekString(8, 4) === 'WAVE';
};
formats = {
0x0001: 'lpcm',
0x0003: 'lpcm',
0x0006: 'alaw',
0x0007: 'ulaw'
};
WAVEDemuxer.prototype.readChunk = function() {
var buffer, bytes, encoding;
if (!this.readStart && this.stream.available(12)) {
if (this.stream.readString(4) !== 'RIFF') {
return this.emit('error', 'Invalid WAV file.');
}
this.fileSize = this.stream.readUInt32(true);
this.readStart = true;
if (this.stream.readString(4) !== 'WAVE') {
return this.emit('error', 'Invalid WAV file.');
}
}
while (this.stream.available(1)) {
if (!this.readHeaders && this.stream.available(8)) {
this.type = this.stream.readString(4);
this.len = this.stream.readUInt32(true);
}
switch (this.type) {
case 'fmt ':
encoding = this.stream.readUInt16(true);
if (!(encoding in formats)) {
return this.emit('error', 'Unsupported format in WAV file.');
}
this.format = {
formatID: formats[encoding],
floatingPoint: encoding === 0x0003,
littleEndian: formats[encoding] === 'lpcm',
channelsPerFrame: this.stream.readUInt16(true),
sampleRate: this.stream.readUInt32(true),
framesPerPacket: 1
};
this.stream.advance(4);
this.stream.advance(2);
this.format.bitsPerChannel = this.stream.readUInt16(true);
this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
this.emit('format', this.format);
this.stream.advance(this.len - 16);
break;
case 'data':
if (!this.sentDuration) {
bytes = this.format.bitsPerChannel / 8;
this.emit('duration', this.len / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0);
this.sentDuration = true;
}
buffer = this.stream.readSingleBuffer(this.len);
this.len -= buffer.length;
this.readHeaders = this.len > 0;
this.emit('data', buffer);
break;
default:
if (!this.stream.available(this.len)) {
return;
}
this.stream.advance(this.len);
}
if (this.type !== 'data') {
this.readHeaders = false;
}
}
};
return WAVEDemuxer;
})(Demuxer);
}).call(this);
},{"../demuxer":14}],20:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var AudioDevice, EventEmitter,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('./core/events');
AudioDevice = (function(superClass) {
var devices;
extend(AudioDevice, superClass);
function AudioDevice(sampleRate1, channels1) {
this.sampleRate = sampleRate1;
this.channels = channels1;
this.updateTime = bind(this.updateTime, this);
this.playing = false;
this.currentTime = 0;
this._lastTime = 0;
}
AudioDevice.prototype.start = function() {
if (this.playing) {
return;
}
this.playing = true;
if (this.device == null) {
this.device = AudioDevice.create(this.sampleRate, this.channels);
}
if (!this.device) {
throw new Error("No supported audio device found.");
}
this._lastTime = this.device.getDeviceTime();
this._timer = setInterval(this.updateTime, 200);
return this.device.on('refill', this.refill = (function(_this) {
return function(buffer) {
return _this.emit('refill', buffer);
};
})(this));
};
AudioDevice.prototype.stop = function() {
if (!this.playing) {
return;
}
this.playing = false;
this.device.off('refill', this.refill);
return clearInterval(this._timer);
};
AudioDevice.prototype.destroy = function() {
var ref;
this.stop();
return (ref = this.device) != null ? ref.destroy() : void 0;
};
AudioDevice.prototype.seek = function(currentTime) {
this.currentTime = currentTime;
if (this.playing) {
this._lastTime = this.device.getDeviceTime();
}
return this.emit('timeUpdate', this.currentTime);
};
AudioDevice.prototype.updateTime = function() {
var time;
time = this.device.getDeviceTime();
this.currentTime += (time - this._lastTime) / this.device.sampleRate * 1000 | 0;
this._lastTime = time;
return this.emit('timeUpdate', this.currentTime);
};
devices = [];
AudioDevice.register = function(device) {
return devices.push(device);
};
AudioDevice.create = function(sampleRate, channels) {
var device, i, len;
for (i = 0, len = devices.length; i < len; i++) {
device = devices[i];
if (device.supported) {
return new device(sampleRate, channels);
}
}
return null;
};
return AudioDevice;
})(EventEmitter);
module.exports = AudioDevice;
}).call(this);
},{"./core/events":8}],21:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var AVBuffer, AudioDevice, EventEmitter, MozillaAudioDevice,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('../core/events');
AudioDevice = require('../device');
AVBuffer = require('../core/buffer');
MozillaAudioDevice = (function(superClass) {
var createTimer, destroyTimer;
extend(MozillaAudioDevice, superClass);
AudioDevice.register(MozillaAudioDevice);
MozillaAudioDevice.supported = (typeof Audio !== "undefined" && Audio !== null) && 'mozWriteAudio' in new Audio;
function MozillaAudioDevice(sampleRate, channels) {
this.sampleRate = sampleRate;
this.channels = channels;
this.refill = bind(this.refill, this);
this.audio = new Audio;
this.audio.mozSetup(this.channels, this.sampleRate);
this.writePosition = 0;
this.prebufferSize = this.sampleRate / 2;
this.tail = null;
this.timer = createTimer(this.refill, 100);
}
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){(function (){
// Generated by CoffeeScript 1.12.7
(function() {
var AudioDevice, EventEmitter, Resampler, WebAudioDevice,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('../core/events');
AudioDevice = require('../device');
Resampler = require('./resampler');
WebAudioDevice = (function(superClass) {
var AudioContext, createProcessor, sharedContext;
extend(WebAudioDevice, superClass);
AudioDevice.register(WebAudioDevice);
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, channels1) {
this.sampleRate = sampleRate;
this.channels = channels1;
this.refill = bind(this.refill, this);
this.context = sharedContext != null ? sharedContext : sharedContext = new AudioContext;
this.deviceSampleRate = this.context.sampleRate;
this.bufferSize = Math.ceil(4096 / (this.deviceSampleRate / this.sampleRate) * this.channels);
this.bufferSize += this.bufferSize % this.channels;
if (this.deviceSampleRate !== this.sampleRate) {
this.resampler = new Resampler(this.sampleRate, this.deviceSampleRate, this.channels, this.bufferSize);
}
this.node = this.context[createProcessor](4096, this.channels, this.channels);
this.node.onaudioprocess = this.refill;
this.node.connect(this.context.destination);
}
WebAudioDevice.prototype.refill = function(event) {
var channelCount, channels, data, i, j, k, l, n, outputBuffer, ref, ref1, ref2;
outputBuffer = event.outputBuffer;
channelCount = outputBuffer.numberOfChannels;
channels = new Array(channelCount);
for (i = j = 0, ref = channelCount; j < ref; i = j += 1) {
channels[i] = outputBuffer.getChannelData(i);
}
data = new Float32Array(this.bufferSize);
this.emit('refill', data);
if (this.resampler) {
data = this.resampler.resampler(data);
}
for (i = k = 0, ref1 = outputBuffer.length; k < ref1; i = k += 1) {
for (n = l = 0, ref2 = channelCount; l < ref2; n = l += 1) {
channels[n][i] = data[i * channelCount + n];
}
}
};
WebAudioDevice.prototype.destroy = function() {
return this.node.disconnect(0);
};
WebAudioDevice.prototype.getDeviceTime = function() {
return this.context.currentTime * this.sampleRate;
};
return WebAudioDevice;
})(EventEmitter);
}).call(this);
}).call(this)}).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.12.7
(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.12.7
(function() {
var BalanceFilter, Filter,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Filter = require('../filter');
BalanceFilter = (function(superClass) {
extend(BalanceFilter, superClass);
function BalanceFilter() {
return BalanceFilter.__super__.constructor.apply(this, arguments);
}
BalanceFilter.prototype.process = function(buffer) {
var i, j, pan, ref;
if (this.value === 0) {
return;
}
pan = Math.max(-50, Math.min(50, this.value));
for (i = j = 0, ref = buffer.length; j < ref; i = j += 2) {
buffer[i] *= Math.min(1, (50 - pan) / 50);
buffer[i + 1] *= Math.min(1, (50 + pan) / 50);
}
};
return BalanceFilter;
})(Filter);
module.exports = BalanceFilter;
}).call(this);
},{"../filter":24}],26:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var Filter, VolumeFilter,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Filter = require('../filter');
VolumeFilter = (function(superClass) {
extend(VolumeFilter, superClass);
function VolumeFilter() {
return VolumeFilter.__super__.constructor.apply(this, arguments);
}
VolumeFilter.prototype.process = function(buffer) {
var i, j, ref, vol;
if (this.value >= 100) {
return;
}
vol = Math.max(0, Math.min(100, this.value)) / 100;
for (i = j = 0, ref = buffer.length; j < ref; i = j += 1) {
buffer[i] *= vol;
}
};
return VolumeFilter;
})(Filter);
module.exports = VolumeFilter;
}).call(this);
},{"../filter":24}],27:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var Asset, AudioDevice, BalanceFilter, EventEmitter, Player, Queue, VolumeFilter,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('./core/events');
Asset = require('./asset');
VolumeFilter = require('./filters/volume');
BalanceFilter = require('./filters/balance');
Queue = require('./queue');
AudioDevice = require('./device');
Player = (function(superClass) {
extend(Player, superClass);
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, j, k, len, max, ref, ref1;
if (!_this.playing) {
return;
}
if (!frame) {
frame = _this.queue.read();
frameOffset = 0;
}
bufferOffset = 0;
while (frame && bufferOffset < buffer.length) {
max = Math.min(frame.length - frameOffset, buffer.length - bufferOffset);
for (i = j = 0, ref = max; j < ref; i = j += 1) {
buffer[bufferOffset++] = frame[frameOffset++];
}
if (frameOffset === frame.length) {
frame = _this.queue.read();
frameOffset = 0;
}
}
ref1 = _this.filters;
for (k = 0, len = ref1.length; k < len; k++) {
filter = ref1[k];
filter.process(buffer);
}
if (!frame) {
if (_this.queue.ended) {
_this.currentTime = _this.duration;
_this.emit('progress', _this.currentTime);
_this.emit('end');
_this.stop();
} else {
_this.device.stop();
}
}
};
})(this);
this.device.on('refill', this.refill);
if (this.playing) {
this.device.start();
}
return this.emit('ready');
};
Player.prototype.destroy = function() {
var ref, ref1;
this.stop();
if ((ref = this.device) != null) {
ref.off();
}
if ((ref1 = this.asset) != null) {
ref1.destroy();
}
return this.off();
};
return Player;
})(EventEmitter);
module.exports = Player;
}).call(this);
},{"./asset":1,"./core/events":8,"./device":20,"./filters/balance":25,"./filters/volume":26,"./queue":28}],28:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
var EventEmitter, Queue,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('./core/events');
Queue = (function(superClass) {
extend(Queue, superClass);
function Queue(asset) {
this.asset = asset;
this.write = bind(this.write, this);
this.readyMark = 64;
this.finished = false;
this.buffering = true;
this.ended = false;
this.buffers = [];
this.asset.on('data', this.write);
this.asset.on('end', (function(_this) {
return function() {
return _this.ended = true;
};
})(this));
this.asset.decodePacket();
}
Queue.prototype.write = function(buffer) {
if (buffer) {
this.buffers.push(buffer);
}
if (this.buffering) {
if (this.buffers.length >= this.readyMark || this.ended) {
this.buffering = false;
return this.emit('ready');
} else {
return this.asset.decodePacket();
}
}
};
Queue.prototype.read = function() {
if (this.buffers.length === 0) {
return null;
}
this.asset.decodePacket();
return this.buffers.shift();
};
Queue.prototype.reset = function() {
this.buffers.length = 0;
this.buffering = true;
return this.asset.decodePacket();
};
return Queue;
})(EventEmitter);
module.exports = Queue;
}).call(this);
},{"./core/events":8}],29:[function(require,module,exports){
var AVBuffer, EventEmitter, FileSource,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('../../core/events');
AVBuffer = require('../../core/buffer');
FileSource = (function(_super) {
__extends(FileSource, _super);
function FileSource(file) {
this.file = file;
if (typeof FileReader === "undefined" || FileReader === null) {
return this.emit('error', 'This browser does not have FileReader support.');
}
this.offset = 0;
this.length = this.file.size;
this.chunkSize = 1 << 20;
this.file[this.slice = 'slice'] || this.file[this.slice = 'webkitSlice'] || this.file[this.slice = 'mozSlice'];
}
FileSource.prototype.start = function() {
if (this.reader) {
if (!this.active) {
return this.loop();
}
}
this.reader = new FileReader;
this.active = true;
this.reader.onload = (function(_this) {
return function(e) {
var buf;
buf = new AVBuffer(new Uint8Array(e.target.result));
_this.offset += buf.length;
_this.emit('data', buf);
_this.active = false;
if (_this.offset < _this.length) {
return _this.loop();
}
};
})(this);
this.reader.onloadend = (function(_this) {
return function() {
if (_this.offset === _this.length) {
_this.emit('end');
return _this.reader = null;
}
};
})(this);
this.reader.onerror = (function(_this) {
return function(e) {
return _this.emit('error', e);
};
})(this);
this.reader.onprogress = (function(_this) {
return function(e) {
return _this.emit('progress', (_this.offset + e.loaded) / _this.length * 100);
};
})(this);
return this.loop();
};
FileSource.prototype.loop = function() {
var blob, endPos;
this.active = true;
endPos = Math.min(this.offset + this.chunkSize, this.length);
blob = this.file[this.slice](this.offset, endPos);
return this.reader.readAsArrayBuffer(blob);
};
FileSource.prototype.pause = function() {
var _ref;
this.active = false;
try {
return (_ref = this.reader) != null ? _ref.abort() : void 0;
} catch (_error) {}
};
FileSource.prototype.reset = function() {
this.pause();
return this.offset = 0;
};
return FileSource;
})(EventEmitter);
module.exports = FileSource;
},{"../../core/buffer":6,"../../core/events":8}],30:[function(require,module,exports){
var AVBuffer, EventEmitter, HTTPSource,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('../../core/events');
AVBuffer = require('../../core/buffer');
HTTPSource = (function(_super) {
__extends(HTTPSource, _super);
function HTTPSource(url, opts) {
this.url = url;
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){(function (){
// Generated by CoffeeScript 1.12.7
(function() {
var AVBuffer, BufferList, BufferSource, EventEmitter,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('../core/events');
BufferList = require('../core/bufferlist');
AVBuffer = require('../core/buffer');
BufferSource = (function(superClass) {
var clearImmediate, setImmediate;
extend(BufferSource, superClass);
function BufferSource(input) {
this.loop = bind(this.loop, this);
if (input instanceof BufferList) {
this.list = input;
} else {
this.list = new BufferList;
this.list.append(new AVBuffer(input));
}
this.paused = true;
}
setImmediate = global.setImmediate || function(fn) {
return global.setTimeout(fn, 0);
};
clearImmediate = global.clearImmediate || function(timer) {
return global.clearTimeout(timer);
};
BufferSource.prototype.start = function() {
this.paused = false;
return this._timer = setImmediate(this.loop);
};
BufferSource.prototype.loop = function() {
this.emit('progress', (this.list.numBuffers - this.list.availableBuffers + 1) / this.list.numBuffers * 100 | 0);
this.emit('data', this.list.first);
if (this.list.advance()) {
return setImmediate(this.loop);
} else {
return this.emit('end');
}
};
BufferSource.prototype.pause = function() {
clearImmediate(this._timer);
return this.paused = true;
};
BufferSource.prototype.reset = function() {
this.pause();
return this.list.rewind();
};
return BufferSource;
})(EventEmitter);
module.exports = BufferSource;
}).call(this);
}).call(this)}).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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYXNzZXQuanMiLCJzcmMvYXVyb3JhLmpzIiwic3JjL2F1cm9yYV9iYXNlLmpzIiwic3JjL2NvcmUvYmFzZS5qcyIsInNyYy9jb3JlL2JpdHN0cmVhbS5qcyIsInNyYy9jb3JlL2J1ZmZlci5qcyIsInNyYy9jb3JlL2J1ZmZlcmxpc3QuanMiLCJzcmMvY29yZS9ldmVudHMuanMiLCJzcmMvY29yZS9zdHJlYW0uanMiLCJzcmMvY29yZS91bmRlcmZsb3cuanMiLCJzcmMvZGVjb2Rlci5qcyIsInNyYy9kZWNvZGVycy9scGNtLmpzIiwic3JjL2RlY29kZXJzL3hsYXcuanMiLCJzcmMvZGVtdXhlci5qcyIsInNyYy9kZW11eGVycy9haWZmLmpzIiwic3JjL2RlbXV4ZXJzL2F1LmpzIiwic3JjL2RlbXV4ZXJzL2NhZi5qcyIsInNyYy9kZW11eGVycy9tNGEuanMiLCJzcmMvZGVtdXhlcnMvd2F2ZS5qcyIsInNyYy9kZXZpY2UuanMiLCJzcmMvZGV2aWNlcy9tb3ppbGxhLmpzIiwic3JjL2RldmljZXMvcmVzYW1wbGVyLmpzIiwic3JjL2RldmljZXMvd2ViYXVkaW8uanMiLCJzcmMvZmlsdGVyLmpzIiwic3JjL2ZpbHRlcnMvYmFsYW5jZS5qcyIsInNyYy9maWx0ZXJzL3ZvbHVtZS5qcyIsInNyYy9wbGF5ZXIuanMiLCJzcmMvcXVldWUuanMiLCIvaG9tZS91c2VyL2F1cm9yYS5qcy0wLjQuOS9zcmMvc291cmNlcy9icm93c2VyL2ZpbGUuY29mZmVlIiwiL2hvbWUvdXNlci9hdXJvcmEuanMtMC40Ljkvc3JjL3NvdXJjZXMvYnJvd3Nlci9odHRwLmNvZmZlZSIsInNyYy9zb3VyY2VzL2J1ZmZlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDalBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNuT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDekZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbGdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4bkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzVKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoRUEsSUFBQSxrQ0FBQTtFQUFBO2lTQUFBOztBQUFBLFlBQUEsR0FBZSxPQUFBLENBQVEsbUJBQVIsQ0FBZixDQUFBOztBQUFBLFFBQ0EsR0FBVyxPQUFBLENBQVEsbUJBQVIsQ0FEWCxDQUFBOztBQUFBO0FBSUksK0JBQUEsQ0FBQTs7QUFBYSxFQUFBLG9CQUFFLElBQUYsR0FBQTtBQUNULElBRFUsSUFBQyxDQUFBLE9BQUEsSUFDWCxDQUFBO0FBQUEsSUFBQSxJQUFPLHdEQUFQO0FBQ0ksYUFBTyxJQUFDLENBQUEsSUFBRCxDQUFNLE9BQU4sRUFBZSxnREFBZixDQUFQLENBREo7S0FBQTtBQUFBLElBR0EsSUFBQyxDQUFBLE1BQUQsR0FBVSxDQUhWLENBQUE7QUFBQSxJQUlBLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFBQyxDQUFBLElBQUksQ0FBQyxJQUpoQixDQUFBO0FBQUEsSUFLQSxJQUFDLENBQUEsU0FBRCxHQUFhLENBQUEsSUFBSyxFQUxsQixDQUFBO0FBQUEsSUFNQSxJQUFDLENBQUEsSUFBSyxDQUFBLElBQUMsQ0FBQSxLQUFELEdBQVMsT0FBVCxDQUFOLElBQTJCLElBQUMsQ0FBQSxJQUFLLENBQUEsSUFBQyxDQUFBLEtBQUQsR0FBUyxhQUFULENBQWpDLElBQTRELElBQUMsQ0FBQSxJQUFLLENBQUEsSUFBQyxDQUFBLEtBQUQsR0FBUyxVQUFULENBTmxFLENBRFM7RUFBQSxDQUFiOztBQUFBLHVCQVNBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxJQUFBLElBQUcsSUFBQyxDQUFBLE1BQUo7QUFDSSxNQUFBLElBQUEsQ0FBQSxJQUF1QixDQUFBLE1BQXZCO0FBQUEsZUFBTyxJQUFDLENBQUEsSUFBRCxDQUFBLENBQVAsQ0FBQTtPQURKO0tBQUE7QUFBQSxJQUdBLElBQUMsQ0FBQSxNQUFELEdBQVUsR0FBQSxDQUFBLFVBSFYsQ0FBQTtBQUFBLElBSUEsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUpWLENBQUE7QUFBQSxJQU1BLElBQUMsQ0FBQSxNQUFNLENBQUMsTUFBUixHQUFpQixDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxDQUFELEdBQUE7QUFDYixZQUFBLEdBQUE7QUFBQSxRQUFBLEdBQUEsR0FBVSxJQUFBLFFBQUEsQ0FBYSxJQUFBLFVBQUEsQ0FBVyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQXBCLENBQWIsQ0FBVixDQUFBO0FBQUEsUUFDQSxLQUFDLENBQUEsTUFBRCxJQUFXLEdBQUcsQ0FBQyxNQURmLENBQUE7QUFBQSxRQUdBLEtBQUMsQ0FBQSxJQUFELENBQU0sTUFBTixFQUFjLEdBQWQsQ0FIQSxDQUFBO0FBQUEsUUFJQSxLQUFDLENBQUEsTUFBRCxHQUFVLEtBSlYsQ0FBQTtBQUtBLFFBQUEsSUFBVyxLQUFDLENBQUEsTUFBRCxHQUFVLEtBQUMsQ0FBQSxNQUF0QjtpQkFBQSxLQUFDLENBQUEsSUFBRCxDQUFBLEVBQUE7U0FOYTtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBTmpCLENBQUE7QUFBQSxJQWNBLElBQUMsQ0FBQSxNQUFNLENBQUMsU0FBUixHQUFvQixDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQSxHQUFBO0FBQ2hCLFFBQUEsSUFBRyxLQUFDLENBQUEsTUFBRCxLQUFXLEtBQUMsQ0FBQSxNQUFmO0FBQ0ksVUFBQSxLQUFDLENBQUEsSUFBRCxDQUFNLEtBQU4sQ0FBQSxDQUFBO2lCQUNBLEtBQUMsQ0FBQSxNQUFELEdBQVUsS0FGZDtTQURnQjtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBZHBCLENBQUE7QUFBQSxJQW1CQSxJQUFDLENBQUEsTUFBTSxDQUFDLE9BQVIsR0FBa0IsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsQ0FBRCxHQUFBO2VBQ2QsS0FBQyxDQUFBLElBQUQsQ0FBTSxPQUFOLEVBQWUsQ0FBZixFQURjO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FuQmxCLENBQUE7QUFBQSxJQXNCQSxJQUFDLENBQUEsTUFBTSxDQUFDLFVBQVIsR0FBcUIsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsQ0FBRCxHQUFBO2VBQ2pCLEtBQUMsQ0FBQSxJQUFELENBQU0sVUFBTixFQUFrQixDQUFDLEtBQUMsQ0FBQSxNQUFELEdBQVUsQ0FBQyxDQUFDLE1BQWIsQ0FBQSxHQUF1QixLQUFDLENBQUEsTUFBeEIsR0FBaUMsR0FBbkQsRUFEaUI7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQXRCckIsQ0FBQTtXQXlCQSxJQUFDLENBQUEsSUFBRCxDQUFBLEVBMUJHO0VBQUEsQ0FUUCxDQUFBOztBQUFBLHVCQXFDQSxJQUFBLEdBQU0sU0FBQSxHQUFBO0FBQ0YsUUFBQSxZQUFBO0FBQUEsSUFBQSxJQUFDLENBQUEsTUFBRCxHQUFVLElBQVYsQ0FBQTtBQUFBLElBQ0EsTUFBQSxHQUFTLElBQUksQ0FBQyxHQUFMLENBQVMsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUFDLENBQUEsU0FBcEIsRUFBK0IsSUFBQyxDQUFBLE1BQWhDLENBRFQsQ0FBQTtBQUFBLElBR0EsSUFBQSxHQUFPLElBQUMsQ0FBQSxJQUFLLENBQUEsSUFBQyxDQUFBLEtBQUQsQ0FBTixDQUFjLElBQUMsQ0FBQSxNQUFmLEVBQXVCLE1BQXZCLENBSFAsQ0FBQTtXQUlBLElBQUMsQ0FBQSxNQUFNLENBQUMsaUJBQVIsQ0FBMEIsSUFBMUIsRUFMRTtFQUFBLENBckNOLENBQUE7O0FBQUEsdUJBNENBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxRQUFBLElBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxNQUFELEdBQVUsS0FBVixDQUFBO0FBQ0E7Z0RBQ1MsQ0FBRSxLQUFULENBQUEsV0FERjtLQUFBLGtCQUZHO0VBQUEsQ0E1Q1AsQ0FBQTs7QUFBQSx1QkFpREEsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILElBQUEsSUFBQyxDQUFBLEtBQUQsQ0FBQSxDQUFBLENBQUE7V0FDQSxJQUFDLENBQUEsTUFBRCxHQUFVLEVBRlA7RUFBQSxDQWpEUCxDQUFBOztvQkFBQTs7R0FEcUIsYUFIekIsQ0FBQTs7QUFBQSxNQXlETSxDQUFDLE9BQVAsR0FBaUIsVUF6RGpCLENBQUE7OztBQ0FBLElBQUEsa0NBQUE7RUFBQTtpU0FBQTs7QUFBQSxZQUFBLEdBQWUsT0FBQSxDQUFRLG1CQUFSLENBQWYsQ0FBQTs7QUFBQSxRQUNBLEdBQVcsT0FBQSxDQUFRLG1CQUFSLENBRFgsQ0FBQTs7QUFBQTtBQUlJLCtCQUFBLENBQUE7O0FBQWEsRUFBQSxvQkFBRSxHQUFGLEVBQVEsSUFBUixHQUFBO0FBQ1QsSUFEVSxJQUFDLENBQUEsTUFBQSxHQUNYLENBQUE7QUFBQSxJQURnQixJQUFDLENBQUEsc0JBQUEsT0FBTyxFQUN4QixDQUFBO0FBQUEsSUFBQSxJQUFDLENBQUEsU0FBRCxHQUFhLENBQUEsSUFBSyxFQUFsQixDQUFBO0FBQUEsSUFDQSxJQUFDLENBQUEsUUFBRCxHQUFZLEtBRFosQ0FBQTtBQUVBLElBQUEsSUFBRyxJQUFDLENBQUEsSUFBSSxDQUFDLE1BQVQ7QUFDSSxNQUFBLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFBQyxDQUFBLElBQUksQ0FBQyxNQUFoQixDQURKO0tBRkE7QUFBQSxJQUlBLElBQUMsQ0FBQSxLQUFELENBQUEsQ0FKQSxDQURTO0VBQUEsQ0FBYjs7QUFBQSx1QkFPQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsSUFBQSxJQUFHLElBQUMsQ0FBQSxNQUFKO0FBQ0ksTUFBQSxJQUFBLENBQUEsSUFBdUIsQ0FBQSxRQUF2QjtBQUFBLGVBQU8sSUFBQyxDQUFBLElBQUQsQ0FBQSxDQUFQLENBQUE7T0FESjtLQUFBO0FBQUEsSUFHQSxJQUFDLENBQUEsUUFBRCxHQUFZLElBSFosQ0FBQTtBQUFBLElBSUEsSUFBQyxDQUFBLEdBQUQsR0FBVyxJQUFBLGNBQUEsQ0FBQSxDQUpYLENBQUE7QUFBQSxJQU1BLElBQUMsQ0FBQSxHQUFHLENBQUMsTUFBTCxHQUFjLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEtBQUQsR0FBQTtBQUNWLFFBQUEsS0FBQyxDQUFBLE1BQUQsR0FBVSxRQUFBLENBQVMsS0FBQyxDQUFBLEdBQUcsQ0FBQyxpQkFBTCxDQUF1QixnQkFBdkIsQ0FBVCxDQUFWLENBQUE7QUFBQSxRQUNBLEtBQUMsQ0FBQSxRQUFELEdBQVksS0FEWixDQUFBO2VBRUEsS0FBQyxDQUFBLElBQUQsQ0FBQSxFQUhVO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FOZCxDQUFBO0FBQUEsSUFXQSxJQUFDLENBQUEsR0FBRyxDQUFDLE9BQUwsR0FBZSxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxHQUFELEdBQUE7QUFDWCxRQUFBLEtBQUMsQ0FBQSxLQUFELENBQUEsQ0FBQSxDQUFBO2VBQ0EsS0FBQyxDQUFBLElBQUQsQ0FBTSxPQUFOLEVBQWUsR0FBZixFQUZXO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FYZixDQUFBO0FBQUEsSUFlQSxJQUFDLENBQUEsR0FBRyxDQUFDLE9BQUwsR0FBZSxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxLQUFELEdBQUE7ZUFDWCxLQUFDLENBQUEsUUFBRCxHQUFZLE1BREQ7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQWZmLENBQUE7QUFBQSxJQWtCQSxJQUFDLENBQUEsR0FBRyxDQUFDLElBQUwsQ0FBVSxNQUFWLEVBQWtCLElBQUMsQ0FBQSxHQUFuQixFQUF3QixJQUF4QixDQWxCQSxDQUFBO1dBbUJBLElBQUMsQ0FBQSxHQUFHLENBQUMsSUFBTCxDQUFVLElBQVYsRUFwQkc7RUFBQSxDQVBQLENBQUE7O0FBQUEsdUJBNkJBLElBQUEsR0FBTSxTQUFBLEdBQUE7QUFDRixRQUFBLE1BQUE7QUFBQSxJQUFBLElBQUcsSUFBQyxDQUFBLFFBQUQsSUFBYSxDQUFBLElBQUssQ0FBQSxNQUFyQjtBQUNJLGFBQU8sSUFBQyxDQUFBLElBQUQsQ0FBTSxPQUFOLEVBQWUsdUNBQWYsQ0FBUCxDQURKO0tBQUE7QUFBQSxJQUdBLElBQUMsQ0FBQSxRQUFELEdBQVksSUFIWixDQUFBO0FBQUEsSUFJQSxJQUFDLENBQUEsR0FBRCxHQUFXLElBQUEsY0FBQSxDQUFBLENBSlgsQ0FBQTtBQUFBLElBTUEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxNQUFMLEdBQWMsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsS0FBRCxHQUFBO0FBQ1YsWUFBQSw2QkFBQTtBQUFBLFFBQUEsSUFBRyxLQUFDLENBQUEsR0FBRyxDQUFDLFFBQVI7QUFDSSxVQUFBLEdBQUEsR0FBVSxJQUFBLFVBQUEsQ0FBVyxLQUFDLENBQUEsR0FBRyxDQUFDLFFBQWhCLENBQVYsQ0FESjtTQUFBLE1BQUE7QUFHSSxVQUFBLEdBQUEsR0FBTSxLQUFDLENBQUEsR0FBRyxDQUFDLFlBQVgsQ0FBQTtBQUFBLFVBQ0EsR0FBQSxHQUFVLElBQUEsVUFBQSxDQUFXLEdBQUcsQ0FBQyxNQUFmLENBRFYsQ0FBQTtBQUVBLGVBQVMsNkZBQVQsR0FBQTtBQUNJLFlBQUEsR0FBSSxDQUFBLENBQUEsQ0FBSixHQUFTLEdBQUcsQ0FBQyxVQUFKLENBQWUsQ0FBZixDQUFBLEdBQW9CLElBQTdCLENBREo7QUFBQSxXQUxKO1NBQUE7QUFBQSxRQVFBLE1BQUEsR0FBYSxJQUFBLFFBQUEsQ0FBUyxHQUFULENBUmIsQ0FBQTtBQUFBLFFBU0EsS0FBQyxDQUFBLE1BQUQsSUFBVyxNQUFNLENBQUMsTUFUbEIsQ0FBQTtBQUFBLFFBV0EsS0FBQyxDQUFBLElBQUQsQ0FBTSxNQUFOLEVBQWMsTUFBZCxDQVhBLENBQUE7QUFZQSxRQUFBLElBQWUsS0FBQyxDQUFBLE1BQUQsSUFBVyxLQUFDLENBQUEsTUFBM0I7QUFBQSxVQUFBLEtBQUMsQ0FBQSxJQUFELENBQU0sS0FBTixDQUFBLENBQUE7U0FaQTtBQUFBLFFBY0EsS0FBQyxDQUFBLFFBQUQsR0FBWSxLQWRaLENBQUE7QUFlQSxRQUFBLElBQUEsQ0FBQSxDQUFlLEtBQUMsQ0FBQSxNQUFELElBQVcsS0FBQyxDQUFBLE1BQTNCLENBQUE7aUJBQUEsS0FBQyxDQUFBLElBQUQsQ0FBQSxFQUFBO1NBaEJVO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FOZCxDQUFBO0FBQUEsSUF3QkEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxVQUFMLEdBQWtCLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEtBQUQsR0FBQTtlQUNkLEtBQUMsQ0FBQSxJQUFELENBQU0sVUFBTixFQUFrQixDQUFDLEtBQUMsQ0FBQSxNQUFELEdBQVUsS0FBSyxDQUFDLE1BQWpCLENBQUEsR0FBMkIsS0FBQyxDQUFBLE1BQTVCLEdBQXFDLEdBQXZELEVBRGM7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQXhCbEIsQ0FBQTtBQUFBLElBMkJBLElBQUMsQ0FBQSxHQUFHLENBQUMsT0FBTCxHQUFlLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEdBQUQsR0FBQTtBQUNYLFFBQUEsS0FBQyxDQUFBLElBQUQsQ0FBTSxPQUFOLEVBQWUsR0FBZixDQUFBLENBQUE7ZUFDQSxLQUFDLENBQUEsS0FBRCxDQUFBLEVBRlc7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQTNCZixDQUFBO0FBQUEsSUErQkEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxPQUFMLEdBQWUsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsS0FBRCxHQUFBO2VBQ1gsS0FBQyxDQUFBLFFBQUQsR0FBWSxNQUREO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0EvQmYsQ0FBQTtBQUFBLElBa0NBLElBQUMsQ0FBQSxHQUFHLENBQUMsSUFBTCxDQUFVLEtBQVYsRUFBaUIsSUFBQyxDQUFBLEdBQWxCLEVBQXVCLElBQXZCLENBbENBLENBQUE7QUFBQSxJQW1DQSxJQUFDLENBQUEsR0FBRyxDQUFDLFlBQUwsR0FBb0IsYUFuQ3BCLENBQUE7QUFBQSxJQXFDQSxNQUFBLEdBQVMsSUFBSSxDQUFDLEdBQUwsQ0FBUyxJQUFDLENBQUEsTUFBRCxHQUFVLElBQUMsQ0FBQSxTQUFwQixFQUErQixJQUFDLENBQUEsTUFBRCxHQUFVLENBQXpDLENBckNULENBQUE7QUFBQSxJQXNDQSxJQUFDLENBQUEsR0FBRyxDQUFDLGdCQUFMLENBQXNCLGVBQXRCLEVBQXVDLGlCQUF2QyxDQXRDQSxDQUFBO0FBQUEsSUF1Q0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxnQkFBTCxDQUFzQixPQUF0QixFQUFnQyxRQUFBLEdBQU8sSUFBQyxDQUFBLE1BQVIsR0FBZ0IsR0FBaEIsR0FBa0IsTUFBbEQsQ0F2Q0EsQ0FBQTtBQUFBLElBd0NBLElBQUMsQ0FBQSxHQUFHLENBQUMsZ0JBQUwsQ0FBc0Isb0NBQXRCLENBeENBLENBQUE7V0F5Q0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxJQUFMLENBQVUsSUFBVixFQTFDRTtFQUFBLENBN0JOLENBQUE7O0FBQUEsdUJBeUVBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxRQUFBLElBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxRQUFELEdBQVksS0FBWixDQUFBOzJDQUNJLENBQUUsS0FBTixDQUFBLFdBRkc7RUFBQSxDQXpFUCxDQUFBOztBQUFBLHVCQTZFQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsSUFBQSxJQUFDLENBQUEsS0FBRCxDQUFBLENBQUEsQ0FBQTtXQUNBLElBQUMsQ0FBQSxNQUFELEdBQVUsRUFGUDtFQUFBLENBN0VQLENBQUE7O29CQUFBOztHQURxQixhQUh6QixDQUFBOztBQUFBLE1BcUZNLENBQUMsT0FBUCxHQUFpQixVQXJGakIsQ0FBQTs7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFzc2V0LCBCdWZmZXJTb3VyY2UsIERlY29kZXIsIERlbXV4ZXIsIEV2ZW50RW1pdHRlciwgRmlsZVNvdXJjZSwgSFRUUFNvdXJjZSxcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vY29yZS9ldmVudHMnKTtcblxuICBIVFRQU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvaHR0cCcpO1xuXG4gIEZpbGVTb3VyY2UgPSByZXF1aXJlKCcuL3NvdXJjZXMvbm9kZS9maWxlJyk7XG5cbiAgQnVmZmVyU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL2J1ZmZlcicpO1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuL2RlbXV4ZXInKTtcblxuICBEZWNvZGVyID0gcmVxdWlyZSgnLi9kZWNvZGVyJyk7XG5cbiAgQXNzZXQgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChBc3NldCwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBBc3NldChzb3VyY2UpIHtcbiAgICAgIHRoaXMuc291cmNlID0gc291cmNlO1xuICAgICAgdGhpcy5fZGVjb2RlID0gYmluZCh0aGlzLl9kZWNvZGUsIHRoaXMpO1xuICAgICAgdGhpcy5maW5kRGVjb2RlciA9IGJpbmQodGhpcy5maW5kRGVjb2RlciwgdGhpcyk7XG4gICAgICB0aGlzLnByb2JlID0gYmluZCh0aGlzLnByb2JlLCB0aGlzKTtcbiAgICAgIHRoaXMuYnVmZmVyZWQgPSAwO1xuICAgICAgdGhpcy5kdXJhdGlvbiA9IG51bGw7XG4gICAgICB0aGlzLmZvcm1hdCA9IG51bGw7XG4gICAgICB0aGlzLm1ldGFkYXRhID0gbnVsbDtcbiAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gICAgICB0aGlzLmRlbXV4ZXIgPSBudWxsO1xuICAgICAgdGhpcy5kZWNvZGVyID0gbnVsbDtcbiAgICAgIHRoaXMuc291cmNlLm9uY2UoJ2RhdGEnLCB0aGlzLnByb2JlKTtcbiAgICAgIHRoaXMuc291cmNlLm9uKCdlcnJvcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgX3RoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5zdG9wKCk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLnNvdXJjZS5vbigncHJvZ3Jlc3MnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcmVkKSB7XG4gICAgICAgICAgX3RoaXMuYnVmZmVyZWQgPSBidWZmZXJlZDtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnYnVmZmVyJywgX3RoaXMuYnVmZmVyZWQpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH1cblxuICAgIEFzc2V0LmZyb21VUkwgPSBmdW5jdGlvbih1cmwsIG9wdHMpIHtcbiAgICAgIHJldHVybiBuZXcgQXNzZXQobmV3IEhUVFBTb3VyY2UodXJsLCBvcHRzKSk7XG4gICAgfTtcblxuICAgIEFzc2V0LmZyb21GaWxlID0gZnVuY3Rpb24oZmlsZSkge1xuICAgICAgcmV0dXJuIG5ldyBBc3NldChuZXcgRmlsZVNvdXJjZShmaWxlKSk7XG4gICAgfTtcblxuICAgIEFzc2V0LmZyb21CdWZmZXIgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBuZXcgQXNzZXQobmV3IEJ1ZmZlclNvdXJjZShidWZmZXIpKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oZGVjb2RlKSB7XG4gICAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGRlY29kZSAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc2hvdWxkRGVjb2RlID0gZGVjb2RlO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuc2hvdWxkRGVjb2RlID09IG51bGwpIHtcbiAgICAgICAgdGhpcy5zaG91bGREZWNvZGUgPSB0cnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5hY3RpdmUgPSB0cnVlO1xuICAgICAgdGhpcy5zb3VyY2Uuc3RhcnQoKTtcbiAgICAgIGlmICh0aGlzLmRlY29kZXIgJiYgdGhpcy5zaG91bGREZWNvZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY29kZSgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICAgICAgcmV0dXJuIHRoaXMuc291cmNlLnBhdXNlKCk7XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihldmVudCwgY2FsbGJhY2spIHtcbiAgICAgIGlmIChldmVudCAhPT0gJ2Zvcm1hdCcgJiYgZXZlbnQgIT09ICdkdXJhdGlvbicgJiYgZXZlbnQgIT09ICdtZXRhZGF0YScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXNbZXZlbnRdICE9IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHRoaXNbZXZlbnRdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub25jZShldmVudCwgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBfdGhpcy5zdG9wKCk7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sodmFsdWUpO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pKHRoaXMpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnQoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmRlY29kZVBhY2tldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2Rlci5kZWNvZGUoKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmRlY29kZVRvQnVmZmVyID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICAgIHZhciBjaHVua3MsIGRhdGFIYW5kbGVyLCBsZW5ndGg7XG4gICAgICBsZW5ndGggPSAwO1xuICAgICAgY2h1bmtzID0gW107XG4gICAgICB0aGlzLm9uKCdkYXRhJywgZGF0YUhhbmRsZXIgPSBmdW5jdGlvbihjaHVuaykge1xuICAgICAgICBsZW5ndGggKz0gY2h1bmsubGVuZ3RoO1xuICAgICAgICByZXR1cm4gY2h1bmtzLnB1c2goY2h1bmspO1xuICAgICAgfSk7XG4gICAgICB0aGlzLm9uY2UoJ2VuZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYnVmLCBjaHVuaywgaiwgbGVuLCBvZmZzZXQ7XG4gICAgICAgIGJ1ZiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgICAgZm9yIChqID0gMCwgbGVuID0gY2h1bmtzLmxlbmd0aDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgY2h1bmsgPSBjaHVua3Nbal07XG4gICAgICAgICAgYnVmLnNldChjaHVuaywgb2Zmc2V0KTtcbiAgICAgICAgICBvZmZzZXQgKz0gY2h1bmsubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2ZmKCdkYXRhJywgZGF0YUhhbmRsZXIpO1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soYnVmKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRoaXMuc3RhcnQoKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLnByb2JlID0gZnVuY3Rpb24oY2h1bmspIHtcbiAgICAgIHZhciBkZW11eGVyO1xuICAgICAgaWYgKCF0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBkZW11eGVyID0gRGVtdXhlci5maW5kKGNodW5rKTtcbiAgICAgIGlmICghZGVtdXhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdBIGRlbXV4ZXIgZm9yIHRoaXMgY29udGFpbmVyIHdhcyBub3QgZm91bmQuJyk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlbXV4ZXIgPSBuZXcgZGVtdXhlcih0aGlzLnNvdXJjZSwgY2h1bmspO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdmb3JtYXQnLCB0aGlzLmZpbmREZWNvZGVyKTtcbiAgICAgIHRoaXMuZGVtdXhlci5vbignZHVyYXRpb24nLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGR1cmF0aW9uKSB7XG4gICAgICAgICAgX3RoaXMuZHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZHVyYXRpb24nLCBfdGhpcy5kdXJhdGlvbik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ21ldGFkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihtZXRhZGF0YSkge1xuICAgICAgICAgIF90aGlzLm1ldGFkYXRhID0gbWV0YWRhdGE7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ21ldGFkYXRhJywgX3RoaXMubWV0YWRhdGEpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVtdXhlci5vbignZXJyb3InLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuc3RvcCgpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZmluZERlY29kZXIgPSBmdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgIHZhciBkZWNvZGVyLCBkaXY7XG4gICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICAgIGlmICghdGhpcy5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICBkZWNvZGVyID0gRGVjb2Rlci5maW5kKHRoaXMuZm9ybWF0LmZvcm1hdElEKTtcbiAgICAgIGlmICghZGVjb2Rlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiQSBkZWNvZGVyIGZvciBcIiArIHRoaXMuZm9ybWF0LmZvcm1hdElEICsgXCIgd2FzIG5vdCBmb3VuZC5cIik7XG4gICAgICB9XG4gICAgICB0aGlzLmRlY29kZXIgPSBuZXcgZGVjb2Rlcih0aGlzLmRlbXV4ZXIsIHRoaXMuZm9ybWF0KTtcbiAgICAgIGlmICh0aGlzLmZvcm1hdC5mbG9hdGluZ1BvaW50KSB7XG4gICAgICAgIHRoaXMuZGVjb2Rlci5vbignZGF0YScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaXYgPSBNYXRoLnBvdygyLCB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAtIDEpO1xuICAgICAgICB0aGlzLmRlY29kZXIub24oJ2RhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICAgICAgICB2YXIgYnVmLCBpLCBqLCBsZW4sIHNhbXBsZTtcbiAgICAgICAgICAgIGJ1ZiA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgbGVuID0gYnVmZmVyLmxlbmd0aDsgaiA8IGxlbjsgaSA9ICsraikge1xuICAgICAgICAgICAgICBzYW1wbGUgPSBidWZmZXJbaV07XG4gICAgICAgICAgICAgIGJ1ZltpXSA9IHNhbXBsZSAvIGRpdjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdkYXRhJywgYnVmKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlY29kZXIub24oJ2Vycm9yJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgICBfdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLnN0b3AoKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuZGVjb2Rlci5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmVtaXQoJ2RlY29kZVN0YXJ0Jyk7XG4gICAgICBpZiAodGhpcy5zaG91bGREZWNvZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY29kZSgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuX2RlY29kZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgd2hpbGUgKHRoaXMuZGVjb2Rlci5kZWNvZGUoKSAmJiB0aGlzLmFjdGl2ZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGVyLm9uY2UoJ2RhdGEnLCB0aGlzLl9kZWNvZGUpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZiwgcmVmMSwgcmVmMjtcbiAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgaWYgKChyZWYgPSB0aGlzLmRlbXV4ZXIpICE9IG51bGwpIHtcbiAgICAgICAgcmVmLm9mZigpO1xuICAgICAgfVxuICAgICAgaWYgKChyZWYxID0gdGhpcy5kZWNvZGVyKSAhPSBudWxsKSB7XG4gICAgICAgIHJlZjEub2ZmKCk7XG4gICAgICB9XG4gICAgICBpZiAoKHJlZjIgPSB0aGlzLnNvdXJjZSkgIT0gbnVsbCkge1xuICAgICAgICByZWYyLm9mZigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMub2ZmKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBBc3NldDtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQXNzZXQ7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIga2V5LCByZWYsIHZhbDtcblxuICByZWYgPSByZXF1aXJlKCcuL2F1cm9yYV9iYXNlJyk7XG4gIGZvciAoa2V5IGluIHJlZikge1xuICAgIHZhbCA9IHJlZltrZXldO1xuICAgIGV4cG9ydHNba2V5XSA9IHZhbDtcbiAgfVxuXG4gIHJlcXVpcmUoJy4vZGVtdXhlcnMvY2FmJyk7XG5cbiAgcmVxdWlyZSgnLi9kZW11eGVycy9tNGEnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL2FpZmYnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL3dhdmUnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL2F1Jyk7XG5cbiAgcmVxdWlyZSgnLi9kZWNvZGVycy9scGNtJyk7XG5cbiAgcmVxdWlyZSgnLi9kZWNvZGVycy94bGF3Jyk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICBleHBvcnRzLkJhc2UgPSByZXF1aXJlKCcuL2NvcmUvYmFzZScpO1xuXG4gIGV4cG9ydHMuQnVmZmVyID0gcmVxdWlyZSgnLi9jb3JlL2J1ZmZlcicpO1xuXG4gIGV4cG9ydHMuQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgZXhwb3J0cy5TdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvc3RyZWFtJyk7XG5cbiAgZXhwb3J0cy5CaXRzdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvYml0c3RyZWFtJyk7XG5cbiAgZXhwb3J0cy5FdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgZXhwb3J0cy5VbmRlcmZsb3dFcnJvciA9IHJlcXVpcmUoJy4vY29yZS91bmRlcmZsb3cnKTtcblxuICBleHBvcnRzLkhUVFBTb3VyY2UgPSByZXF1aXJlKCcuL3NvdXJjZXMvbm9kZS9odHRwJyk7XG5cbiAgZXhwb3J0cy5GaWxlU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvZmlsZScpO1xuXG4gIGV4cG9ydHMuQnVmZmVyU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL2J1ZmZlcicpO1xuXG4gIGV4cG9ydHMuRGVtdXhlciA9IHJlcXVpcmUoJy4vZGVtdXhlcicpO1xuXG4gIGV4cG9ydHMuRGVjb2RlciA9IHJlcXVpcmUoJy4vZGVjb2RlcicpO1xuXG4gIGV4cG9ydHMuQXVkaW9EZXZpY2UgPSByZXF1aXJlKCcuL2RldmljZScpO1xuXG4gIGV4cG9ydHMuQXNzZXQgPSByZXF1aXJlKCcuL2Fzc2V0Jyk7XG5cbiAgZXhwb3J0cy5QbGF5ZXIgPSByZXF1aXJlKCcuL3BsYXllcicpO1xuXG4gIGV4cG9ydHMuRmlsdGVyID0gcmVxdWlyZSgnLi9maWx0ZXInKTtcblxuICBleHBvcnRzLlZvbHVtZUZpbHRlciA9IHJlcXVpcmUoJy4vZmlsdGVycy92b2x1bWUnKTtcblxuICBleHBvcnRzLkJhbGFuY2VGaWx0ZXIgPSByZXF1aXJlKCcuL2ZpbHRlcnMvYmFsYW5jZScpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJhc2UsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBpbmRleE9mID0gW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH07XG5cbiAgQmFzZSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgZm5UZXN0O1xuXG4gICAgZnVuY3Rpb24gQmFzZSgpIHt9XG5cbiAgICBmblRlc3QgPSAvXFxiX3N1cGVyXFxiLztcblxuICAgIEJhc2UuZXh0ZW5kID0gZnVuY3Rpb24ocHJvcCkge1xuICAgICAgdmFyIENsYXNzLCBfc3VwZXIsIGZuLCBrZXksIGtleXMsIHJlZjtcbiAgICAgIENsYXNzID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICAgICAgZXh0ZW5kKENsYXNzLCBzdXBlckNsYXNzKTtcblxuICAgICAgICBmdW5jdGlvbiBDbGFzcygpIHtcbiAgICAgICAgICByZXR1cm4gQ2xhc3MuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gQ2xhc3M7XG5cbiAgICAgIH0pKHRoaXMpO1xuICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGtleXMgPSBPYmplY3Qua2V5cyhDbGFzcy5wcm90b3R5cGUpO1xuICAgICAgICBwcm9wLmNhbGwoQ2xhc3MsIENsYXNzKTtcbiAgICAgICAgcHJvcCA9IHt9O1xuICAgICAgICByZWYgPSBDbGFzcy5wcm90b3R5cGU7XG4gICAgICAgIGZvciAoa2V5IGluIHJlZikge1xuICAgICAgICAgIGZuID0gcmVmW2tleV07XG4gICAgICAgICAgaWYgKGluZGV4T2YuY2FsbChrZXlzLCBrZXkpIDwgMCkge1xuICAgICAgICAgICAgcHJvcFtrZXldID0gZm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBfc3VwZXIgPSBDbGFzcy5fX3N1cGVyX187XG4gICAgICBmb3IgKGtleSBpbiBwcm9wKSB7XG4gICAgICAgIGZuID0gcHJvcFtrZXldO1xuICAgICAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nICYmIGZuVGVzdC50ZXN0KGZuKSkge1xuICAgICAgICAgIChmdW5jdGlvbihrZXksIGZuKSB7XG4gICAgICAgICAgICByZXR1cm4gQ2xhc3MucHJvdG90eXBlW2tleV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgdmFyIHJldCwgdG1wO1xuICAgICAgICAgICAgICB0bXAgPSB0aGlzLl9zdXBlcjtcbiAgICAgICAgICAgICAgdGhpcy5fc3VwZXIgPSBfc3VwZXJba2V5XTtcbiAgICAgICAgICAgICAgcmV0ID0gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgdGhpcy5fc3VwZXIgPSB0bXA7XG4gICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKGtleSwgZm4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIENsYXNzLnByb3RvdHlwZVtrZXldID0gZm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBDbGFzcztcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJhc2U7XG5cbiAgfSkoKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEJhc2U7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQml0c3RyZWFtO1xuXG4gIEJpdHN0cmVhbSA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBCaXRzdHJlYW0oc3RyZWFtKSB7XG4gICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgIHRoaXMuYml0UG9zaXRpb24gPSAwO1xuICAgIH1cblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBCaXRzdHJlYW0odGhpcy5zdHJlYW0uY29weSgpKTtcbiAgICAgIHJlc3VsdC5iaXRQb3NpdGlvbiA9IHRoaXMuYml0UG9zaXRpb247XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLm9mZnNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIDggKiB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmF2YWlsYWJsZSA9IGZ1bmN0aW9uKGJpdHMpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoKGJpdHMgKyA4IC0gdGhpcy5iaXRQb3NpdGlvbikgLyA4KTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5hZHZhbmNlID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gKyBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZShwb3MgPj4gMyk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmV3aW5kID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gLSBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0ucmV3aW5kKE1hdGguYWJzKHBvcyA+PiAzKSk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgdmFyIGN1ck9mZnNldDtcbiAgICAgIGN1ck9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XG4gICAgICBpZiAob2Zmc2V0ID4gY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkdmFuY2Uob2Zmc2V0IC0gY3VyT2Zmc2V0KTtcbiAgICAgIH0gZWxzZSBpZiAob2Zmc2V0IDwgY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJld2luZChjdXJPZmZzZXQgLSBvZmZzZXQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmFsaWduID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5iaXRQb3NpdGlvbiAhPT0gMCkge1xuICAgICAgICB0aGlzLmJpdFBvc2l0aW9uID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKGJpdHMsIHNpZ25lZCkge1xuICAgICAgdmFyIGEsIGEwLCBhMSwgYTIsIGEzLCBhNCwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIG1CaXRzID0gYml0cyArIHRoaXMuYml0UG9zaXRpb247XG4gICAgICBpZiAobUJpdHMgPD0gOCkge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDgoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmYpID4+PiAoOCAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSAxNikge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDE2KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmZmYpID4+PiAoMTYgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMjQpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQyNCgpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmZmYpID4+PiAoMjQgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMzIpIHtcbiAgICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDMyKCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgPj4+ICgzMiAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSA0MCkge1xuICAgICAgICBhMCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgwKSAqIDB4MDEwMDAwMDAwMDtcbiAgICAgICAgYTEgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkgPDwgMjQgPj4+IDA7XG4gICAgICAgIGEyID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDIpIDw8IDE2O1xuICAgICAgICBhMyA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgzKSA8PCA4O1xuICAgICAgICBhNCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KTtcbiAgICAgICAgYSA9IGEwICsgYTEgKyBhMiArIGEzICsgYTQ7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgNDAgLSB0aGlzLmJpdFBvc2l0aW9uKTtcbiAgICAgICAgYSA9IE1hdGguZmxvb3IoYSAvIE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbiAtIGJpdHMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRvbyBtYW55IGJpdHMhXCIpO1xuICAgICAgfVxuICAgICAgaWYgKHNpZ25lZCkge1xuICAgICAgICBpZiAobUJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChhID4+PiAoYml0cyAtIDEpKSB7XG4gICAgICAgICAgICBhID0gKCgxIDw8IGJpdHMgPj4+IDApIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGEgLyBNYXRoLnBvdygyLCBiaXRzIC0gMSkgfCAwKSB7XG4gICAgICAgICAgICBhID0gKE1hdGgucG93KDIsIGJpdHMpIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuYWR2YW5jZShiaXRzKTtcbiAgICAgIHJldHVybiBhO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLnBlZWsgPSBmdW5jdGlvbihiaXRzLCBzaWduZWQpIHtcbiAgICAgIHZhciBhLCBhMCwgYTEsIGEyLCBhMywgYTQsIG1CaXRzO1xuICAgICAgaWYgKGJpdHMgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzIDw9IDgpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQ4KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmKSA+Pj4gKDggLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMTYpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQxNigpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmKSA+Pj4gKDE2IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDI0KSB7XG4gICAgICAgIGEgPSAoKHRoaXMuc3RyZWFtLnBlZWtVSW50MjQoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmZmZmZmKSA+Pj4gKDI0IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDMyKSB7XG4gICAgICAgIGEgPSAodGhpcy5zdHJlYW0ucGVla1VJbnQzMigpIDw8IHRoaXMuYml0UG9zaXRpb24pID4+PiAoMzIgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gNDApIHtcbiAgICAgICAgYTAgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkgKiAweDAxMDAwMDAwMDA7XG4gICAgICAgIGExID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDEpIDw8IDI0ID4+PiAwO1xuICAgICAgICBhMiA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgyKSA8PCAxNjtcbiAgICAgICAgYTMgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMykgPDwgODtcbiAgICAgICAgYTQgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoNCk7XG4gICAgICAgIGEgPSBhMCArIGExICsgYTIgKyBhMyArIGE0O1xuICAgICAgICBhICU9IE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICAgIGEgPSBNYXRoLmZsb29yKGEgLyBNYXRoLnBvdygyLCA0MCAtIHRoaXMuYml0UG9zaXRpb24gLSBiaXRzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUb28gbWFueSBiaXRzIVwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5yZWFkTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmFkdmFuY2UoYml0cyk7XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5wZWVrTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJpdHN0cmVhbTtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQml0c3RyZWFtO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyO1xuXG4gIEFWQnVmZmVyID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBCbG9iQnVpbGRlciwgVVJMO1xuXG4gICAgZnVuY3Rpb24gQVZCdWZmZXIoaW5wdXQpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGlucHV0O1xuICAgICAgfSBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IEFycmF5LmlzQXJyYXkoaW5wdXQpIHx8IHR5cGVvZiBpbnB1dCA9PT0gJ251bWJlcicgfHwgKChyZWYgPSBnbG9iYWwuQnVmZmVyKSAhPSBudWxsID8gcmVmLmlzQnVmZmVyKGlucHV0KSA6IHZvaWQgMCkpIHtcbiAgICAgICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoaW5wdXQpO1xuICAgICAgfSBlbHNlIGlmIChpbnB1dC5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShpbnB1dC5idWZmZXIsIGlucHV0LmJ5dGVPZmZzZXQsIGlucHV0Lmxlbmd0aCAqIGlucHV0LkJZVEVTX1BFUl9FTEVNRU5UKTtcbiAgICAgIH0gZWxzZSBpZiAoaW5wdXQgaW5zdGFuY2VvZiBBVkJ1ZmZlcikge1xuICAgICAgICB0aGlzLmRhdGEgPSBpbnB1dC5kYXRhO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29uc3RydWN0aW5nIGJ1ZmZlciB3aXRoIHVua25vd24gdHlwZS5cIik7XG4gICAgICB9XG4gICAgICB0aGlzLmxlbmd0aCA9IHRoaXMuZGF0YS5sZW5ndGg7XG4gICAgICB0aGlzLm5leHQgPSBudWxsO1xuICAgICAgdGhpcy5wcmV2ID0gbnVsbDtcbiAgICB9XG5cbiAgICBBVkJ1ZmZlci5hbGxvY2F0ZSA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIoc2l6ZSk7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IEFWQnVmZmVyKG5ldyBVaW50OEFycmF5KHRoaXMuZGF0YSkpO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbihwb3NpdGlvbiwgbGVuZ3RoKSB7XG4gICAgICBpZiAobGVuZ3RoID09IG51bGwpIHtcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgICB9XG4gICAgICBpZiAocG9zaXRpb24gPT09IDAgJiYgbGVuZ3RoID49IHRoaXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIodGhpcy5kYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIodGhpcy5kYXRhLnN1YmFycmF5KHBvc2l0aW9uLCBwb3NpdGlvbiArIGxlbmd0aCkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCbG9iQnVpbGRlciA9IGdsb2JhbC5CbG9iQnVpbGRlciB8fCBnbG9iYWwuTW96QmxvYkJ1aWxkZXIgfHwgZ2xvYmFsLldlYktpdEJsb2JCdWlsZGVyO1xuXG4gICAgVVJMID0gZ2xvYmFsLlVSTCB8fCBnbG9iYWwud2Via2l0VVJMIHx8IGdsb2JhbC5tb3pVUkw7XG5cbiAgICBBVkJ1ZmZlci5tYWtlQmxvYiA9IGZ1bmN0aW9uKGRhdGEsIHR5cGUpIHtcbiAgICAgIHZhciBiYjtcbiAgICAgIGlmICh0eXBlID09IG51bGwpIHtcbiAgICAgICAgdHlwZSA9ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBCbG9iKFtkYXRhXSwge1xuICAgICAgICAgIHR5cGU6IHR5cGVcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge31cbiAgICAgIGlmIChCbG9iQnVpbGRlciAhPSBudWxsKSB7XG4gICAgICAgIGJiID0gbmV3IEJsb2JCdWlsZGVyO1xuICAgICAgICBiYi5hcHBlbmQoZGF0YSk7XG4gICAgICAgIHJldHVybiBiYi5nZXRCbG9iKHR5cGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLm1ha2VCbG9iVVJMID0gZnVuY3Rpb24oZGF0YSwgdHlwZSkge1xuICAgICAgcmV0dXJuIFVSTCAhPSBudWxsID8gVVJMLmNyZWF0ZU9iamVjdFVSTCh0aGlzLm1ha2VCbG9iKGRhdGEsIHR5cGUpKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgQVZCdWZmZXIucmV2b2tlQmxvYlVSTCA9IGZ1bmN0aW9uKHVybCkge1xuICAgICAgcmV0dXJuIFVSTCAhPSBudWxsID8gVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5wcm90b3R5cGUudG9CbG9iID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gQVZCdWZmZXIubWFrZUJsb2IodGhpcy5kYXRhLmJ1ZmZlcik7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnByb3RvdHlwZS50b0Jsb2JVUkwgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBBVkJ1ZmZlci5tYWtlQmxvYlVSTCh0aGlzLmRhdGEuYnVmZmVyKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEFWQnVmZmVyO1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBBVkJ1ZmZlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBCdWZmZXJMaXN0O1xuXG4gIEJ1ZmZlckxpc3QgPSAoZnVuY3Rpb24oKSB7XG4gICAgZnVuY3Rpb24gQnVmZmVyTGlzdCgpIHtcbiAgICAgIHRoaXMuZmlyc3QgPSBudWxsO1xuICAgICAgdGhpcy5sYXN0ID0gbnVsbDtcbiAgICAgIHRoaXMubnVtQnVmZmVycyA9IDA7XG4gICAgICB0aGlzLmF2YWlsYWJsZUJ5dGVzID0gMDtcbiAgICAgIHRoaXMuYXZhaWxhYmxlQnVmZmVycyA9IDA7XG4gICAgfVxuXG4gICAgQnVmZmVyTGlzdC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBCdWZmZXJMaXN0O1xuICAgICAgcmVzdWx0LmZpcnN0ID0gdGhpcy5maXJzdDtcbiAgICAgIHJlc3VsdC5sYXN0ID0gdGhpcy5sYXN0O1xuICAgICAgcmVzdWx0Lm51bUJ1ZmZlcnMgPSB0aGlzLm51bUJ1ZmZlcnM7XG4gICAgICByZXN1bHQuYXZhaWxhYmxlQnl0ZXMgPSB0aGlzLmF2YWlsYWJsZUJ5dGVzO1xuICAgICAgcmVzdWx0LmF2YWlsYWJsZUJ1ZmZlcnMgPSB0aGlzLmF2YWlsYWJsZUJ1ZmZlcnM7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBCdWZmZXJMaXN0LnByb3RvdHlwZS5hcHBlbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBidWZmZXIucHJldiA9IHRoaXMubGFzdDtcbiAgICAgIGlmICgocmVmID0gdGhpcy5sYXN0KSAhPSBudWxsKSB7XG4gICAgICAgIHJlZi5uZXh0ID0gYnVmZmVyO1xuICAgICAgfVxuICAgICAgdGhpcy5sYXN0ID0gYnVmZmVyO1xuICAgICAgaWYgKHRoaXMuZmlyc3QgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmZpcnN0ID0gYnVmZmVyO1xuICAgICAgfVxuICAgICAgdGhpcy5hdmFpbGFibGVCeXRlcyArPSBidWZmZXIubGVuZ3RoO1xuICAgICAgdGhpcy5hdmFpbGFibGVCdWZmZXJzKys7XG4gICAgICByZXR1cm4gdGhpcy5udW1CdWZmZXJzKys7XG4gICAgfTtcblxuICAgIEJ1ZmZlckxpc3QucHJvdG90eXBlLmFkdmFuY2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmZpcnN0KSB7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlQnl0ZXMgLT0gdGhpcy5maXJzdC5sZW5ndGg7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlQnVmZmVycy0tO1xuICAgICAgICB0aGlzLmZpcnN0ID0gdGhpcy5maXJzdC5uZXh0O1xuICAgICAgICByZXR1cm4gdGhpcy5maXJzdCAhPSBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICBCdWZmZXJMaXN0LnByb3RvdHlwZS5yZXdpbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAodGhpcy5maXJzdCAmJiAhdGhpcy5maXJzdC5wcmV2KSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZmlyc3QgPSAoKHJlZiA9IHRoaXMuZmlyc3QpICE9IG51bGwgPyByZWYucHJldiA6IHZvaWQgMCkgfHwgdGhpcy5sYXN0O1xuICAgICAgaWYgKHRoaXMuZmlyc3QpIHtcbiAgICAgICAgdGhpcy5hdmFpbGFibGVCeXRlcyArPSB0aGlzLmZpcnN0Lmxlbmd0aDtcbiAgICAgICAgdGhpcy5hdmFpbGFibGVCdWZmZXJzKys7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5maXJzdCAhPSBudWxsO1xuICAgIH07XG5cbiAgICBCdWZmZXJMaXN0LnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdHM7XG4gICAgICByZXN1bHRzID0gW107XG4gICAgICB3aGlsZSAodGhpcy5yZXdpbmQoKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHRzO1xuICAgIH07XG5cbiAgICByZXR1cm4gQnVmZmVyTGlzdDtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQnVmZmVyTGlzdDtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBCYXNlLCBFdmVudEVtaXR0ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBzbGljZSA9IFtdLnNsaWNlO1xuXG4gIEJhc2UgPSByZXF1aXJlKCcuL2Jhc2UnKTtcblxuICBFdmVudEVtaXR0ZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChFdmVudEVtaXR0ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gZnVuY3Rpb24oZXZlbnQsIGZuKSB7XG4gICAgICB2YXIgYmFzZTtcbiAgICAgIGlmICh0aGlzLmV2ZW50cyA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuZXZlbnRzID0ge307XG4gICAgICB9XG4gICAgICBpZiAoKGJhc2UgPSB0aGlzLmV2ZW50cylbZXZlbnRdID09IG51bGwpIHtcbiAgICAgICAgYmFzZVtldmVudF0gPSBbXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmV2ZW50c1tldmVudF0ucHVzaChmbik7XG4gICAgfTtcblxuICAgIEV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24oZXZlbnQsIGZuKSB7XG4gICAgICB2YXIgZXZlbnRzLCBpbmRleCwgcmVmO1xuICAgICAgaWYgKHRoaXMuZXZlbnRzID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKChyZWYgPSB0aGlzLmV2ZW50cykgIT0gbnVsbCA/IHJlZltldmVudF0gOiB2b2lkIDApIHtcbiAgICAgICAgaWYgKGZuICE9IG51bGwpIHtcbiAgICAgICAgICBpbmRleCA9IHRoaXMuZXZlbnRzW2V2ZW50XS5pbmRleE9mKGZuKTtcbiAgICAgICAgICBpZiAofmluZGV4KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHNbZXZlbnRdLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50c1tldmVudF07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZXZlbnRzID0ge307XG4gICAgICB9XG4gICAgfTtcblxuICAgIEV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKGV2ZW50LCBmbikge1xuICAgICAgdmFyIGNiO1xuICAgICAgcmV0dXJuIHRoaXMub24oZXZlbnQsIGNiID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMub2ZmKGV2ZW50LCBjYik7XG4gICAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIEV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGFyZ3MsIGV2ZW50LCBmbiwgaSwgbGVuLCByZWYsIHJlZjE7XG4gICAgICBldmVudCA9IGFyZ3VtZW50c1swXSwgYXJncyA9IDIgPD0gYXJndW1lbnRzLmxlbmd0aCA/IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSA6IFtdO1xuICAgICAgaWYgKCEoKHJlZiA9IHRoaXMuZXZlbnRzKSAhPSBudWxsID8gcmVmW2V2ZW50XSA6IHZvaWQgMCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmVmMSA9IHRoaXMuZXZlbnRzW2V2ZW50XS5zbGljZSgpO1xuICAgICAgZm9yIChpID0gMCwgbGVuID0gcmVmMS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBmbiA9IHJlZjFbaV07XG4gICAgICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuXG4gIH0pKEJhc2UpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyLCBCdWZmZXJMaXN0LCBTdHJlYW0sIFVuZGVyZmxvd0Vycm9yO1xuXG4gIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2J1ZmZlcmxpc3QnKTtcblxuICBBVkJ1ZmZlciA9IHJlcXVpcmUoJy4vYnVmZmVyJyk7XG5cbiAgVW5kZXJmbG93RXJyb3IgPSByZXF1aXJlKCcuL3VuZGVyZmxvdycpO1xuXG4gIFN0cmVhbSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgYnVmLCBkZWNvZGVTdHJpbmcsIGZsb2F0MzIsIGZsb2F0NjQsIGZsb2F0NjRGYWxsYmFjaywgZmxvYXQ4MCwgaW50MTYsIGludDMyLCBpbnQ4LCBuYXRpdmVFbmRpYW4sIHVpbnQxNiwgdWludDMyLCB1aW50ODtcblxuICAgIGJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcigxNik7XG5cbiAgICB1aW50OCA9IG5ldyBVaW50OEFycmF5KGJ1Zik7XG5cbiAgICBpbnQ4ID0gbmV3IEludDhBcnJheShidWYpO1xuXG4gICAgdWludDE2ID0gbmV3IFVpbnQxNkFycmF5KGJ1Zik7XG5cbiAgICBpbnQxNiA9IG5ldyBJbnQxNkFycmF5KGJ1Zik7XG5cbiAgICB1aW50MzIgPSBuZXcgVWludDMyQXJyYXkoYnVmKTtcblxuICAgIGludDMyID0gbmV3IEludDMyQXJyYXkoYnVmKTtcblxuICAgIGZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1Zik7XG5cbiAgICBpZiAodHlwZW9mIEZsb2F0NjRBcnJheSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBGbG9hdDY0QXJyYXkgIT09IG51bGwpIHtcbiAgICAgIGZsb2F0NjQgPSBuZXcgRmxvYXQ2NEFycmF5KGJ1Zik7XG4gICAgfVxuXG4gICAgbmF0aXZlRW5kaWFuID0gbmV3IFVpbnQxNkFycmF5KG5ldyBVaW50OEFycmF5KFsweDEyLCAweDM0XSkuYnVmZmVyKVswXSA9PT0gMHgzNDEyO1xuXG4gICAgZnVuY3Rpb24gU3RyZWFtKGxpc3QxKSB7XG4gICAgICB0aGlzLmxpc3QgPSBsaXN0MTtcbiAgICAgIHRoaXMubG9jYWxPZmZzZXQgPSAwO1xuICAgICAgdGhpcy5vZmZzZXQgPSAwO1xuICAgIH1cblxuICAgIFN0cmVhbS5mcm9tQnVmZmVyID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgbGlzdDtcbiAgICAgIGxpc3QgPSBuZXcgQnVmZmVyTGlzdDtcbiAgICAgIGxpc3QuYXBwZW5kKGJ1ZmZlcik7XG4gICAgICByZXR1cm4gbmV3IFN0cmVhbShsaXN0KTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgcmVzdWx0ID0gbmV3IFN0cmVhbSh0aGlzLmxpc3QuY29weSgpKTtcbiAgICAgIHJlc3VsdC5sb2NhbE9mZnNldCA9IHRoaXMubG9jYWxPZmZzZXQ7XG4gICAgICByZXN1bHQub2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLmF2YWlsYWJsZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgICByZXR1cm4gYnl0ZXMgPD0gdGhpcy5saXN0LmF2YWlsYWJsZUJ5dGVzIC0gdGhpcy5sb2NhbE9mZnNldDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZW1haW5pbmdCeXRlcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMubGlzdC5hdmFpbGFibGVCeXRlcyAtIHRoaXMubG9jYWxPZmZzZXQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUuYWR2YW5jZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgICBpZiAoIXRoaXMuYXZhaWxhYmxlKGJ5dGVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9jYWxPZmZzZXQgKz0gYnl0ZXM7XG4gICAgICB0aGlzLm9mZnNldCArPSBieXRlcztcbiAgICAgIHdoaWxlICh0aGlzLmxpc3QuZmlyc3QgJiYgdGhpcy5sb2NhbE9mZnNldCA+PSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMubG9jYWxPZmZzZXQgLT0gdGhpcy5saXN0LmZpcnN0Lmxlbmd0aDtcbiAgICAgICAgdGhpcy5saXN0LmFkdmFuY2UoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJld2luZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgICBpZiAoYnl0ZXMgPiB0aGlzLm9mZnNldCkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5saXN0LmZpcnN0KSB7XG4gICAgICAgIHRoaXMubGlzdC5yZXdpbmQoKTtcbiAgICAgICAgdGhpcy5sb2NhbE9mZnNldCA9IHRoaXMubGlzdC5maXJzdC5sZW5ndGg7XG4gICAgICB9XG4gICAgICB0aGlzLmxvY2FsT2Zmc2V0IC09IGJ5dGVzO1xuICAgICAgdGhpcy5vZmZzZXQgLT0gYnl0ZXM7XG4gICAgICB3aGlsZSAodGhpcy5saXN0LmZpcnN0LnByZXYgJiYgdGhpcy5sb2NhbE9mZnNldCA8IDApIHtcbiAgICAgICAgdGhpcy5saXN0LnJld2luZCgpO1xuICAgICAgICB0aGlzLmxvY2FsT2Zmc2V0ICs9IHRoaXMubGlzdC5maXJzdC5sZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5zZWVrID0gZnVuY3Rpb24ocG9zaXRpb24pIHtcbiAgICAgIGlmIChwb3NpdGlvbiA+IHRoaXMub2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkdmFuY2UocG9zaXRpb24gLSB0aGlzLm9mZnNldCk7XG4gICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uIDwgdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmV3aW5kKHRoaXMub2Zmc2V0IC0gcG9zaXRpb24pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGE7XG4gICAgICBpZiAoIXRoaXMuYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIHRocm93IG5ldyBVbmRlcmZsb3dFcnJvcigpO1xuICAgICAgfVxuICAgICAgYSA9IHRoaXMubGlzdC5maXJzdC5kYXRhW3RoaXMubG9jYWxPZmZzZXRdO1xuICAgICAgdGhpcy5sb2NhbE9mZnNldCArPSAxO1xuICAgICAgdGhpcy5vZmZzZXQgKz0gMTtcbiAgICAgIGlmICh0aGlzLmxvY2FsT2Zmc2V0ID09PSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMubG9jYWxPZmZzZXQgPSAwO1xuICAgICAgICB0aGlzLmxpc3QuYWR2YW5jZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGE7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1VJbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gICAgICB2YXIgYnVmZmVyO1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuYXZhaWxhYmxlKG9mZnNldCArIDEpKSB7XG4gICAgICAgIHRocm93IG5ldyBVbmRlcmZsb3dFcnJvcigpO1xuICAgICAgfVxuICAgICAgb2Zmc2V0ID0gdGhpcy5sb2NhbE9mZnNldCArIG9mZnNldDtcbiAgICAgIGJ1ZmZlciA9IHRoaXMubGlzdC5maXJzdDtcbiAgICAgIHdoaWxlIChidWZmZXIpIHtcbiAgICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPiBvZmZzZXQpIHtcbiAgICAgICAgICByZXR1cm4gYnVmZmVyLmRhdGFbb2Zmc2V0XTtcbiAgICAgICAgfVxuICAgICAgICBvZmZzZXQgLT0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgYnVmZmVyID0gYnVmZmVyLm5leHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gMDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24oYnl0ZXMsIGxpdHRsZUVuZGlhbikge1xuICAgICAgdmFyIGksIGosIGssIHJlZiwgcmVmMTtcbiAgICAgIGlmIChsaXR0bGVFbmRpYW4gPT0gbnVsbCkge1xuICAgICAgICBsaXR0bGVFbmRpYW4gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChsaXR0bGVFbmRpYW4gPT09IG5hdGl2ZUVuZGlhbikge1xuICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gYnl0ZXM7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgICB1aW50OFtpXSA9IHRoaXMucmVhZFVJbnQ4KCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoaSA9IGsgPSByZWYxID0gYnl0ZXMgLSAxOyBrID49IDA7IGkgPSBrICs9IC0xKSB7XG4gICAgICAgICAgdWludDhbaV0gPSB0aGlzLnJlYWRVSW50OCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVlayA9IGZ1bmN0aW9uKGJ5dGVzLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgdmFyIGksIGosIGssIHJlZiwgcmVmMTtcbiAgICAgIGlmIChsaXR0bGVFbmRpYW4gPT0gbnVsbCkge1xuICAgICAgICBsaXR0bGVFbmRpYW4gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChsaXR0bGVFbmRpYW4gPT09IG5hdGl2ZUVuZGlhbikge1xuICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gYnl0ZXM7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgICB1aW50OFtpXSA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCArIGkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgPSBrID0gMCwgcmVmMSA9IGJ5dGVzOyBrIDwgcmVmMTsgaSA9IGsgKz0gMSkge1xuICAgICAgICAgIHVpbnQ4W2J5dGVzIC0gaSAtIDFdID0gdGhpcy5wZWVrVUludDgob2Zmc2V0ICsgaSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5yZWFkKDEpO1xuICAgICAgcmV0dXJuIGludDhbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0ludDggPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDEsIG9mZnNldCk7XG4gICAgICByZXR1cm4gaW50OFswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkVUludDE2ID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoMiwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiB1aW50MTZbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1VJbnQxNiA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlaygyLCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gdWludDE2WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRJbnQxNiA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDIsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gaW50MTZbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0ludDE2ID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDIsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBpbnQxNlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkVUludDI0ID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRVSW50MTYodHJ1ZSkgKyAodGhpcy5yZWFkVUludDgoKSA8PCAxNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gKHRoaXMucmVhZFVJbnQxNigpIDw8IDgpICsgdGhpcy5yZWFkVUludDgoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrVUludDI0ID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgICAgICByZXR1cm4gdGhpcy5wZWVrVUludDE2KG9mZnNldCwgdHJ1ZSkgKyAodGhpcy5wZWVrVUludDgob2Zmc2V0ICsgMikgPDwgMTYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnBlZWtVSW50MTYob2Zmc2V0KSA8PCA4KSArIHRoaXMucGVla1VJbnQ4KG9mZnNldCArIDIpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRJbnQyNCA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkVUludDE2KHRydWUpICsgKHRoaXMucmVhZEludDgoKSA8PCAxNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gKHRoaXMucmVhZEludDE2KCkgPDwgOCkgKyB0aGlzLnJlYWRVSW50OCgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtJbnQyNCA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIGlmIChsaXR0bGVFbmRpYW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGVla1VJbnQxNihvZmZzZXQsIHRydWUpICsgKHRoaXMucGVla0ludDgob2Zmc2V0ICsgMikgPDwgMTYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnBlZWtJbnQxNihvZmZzZXQpIDw8IDgpICsgdGhpcy5wZWVrVUludDgob2Zmc2V0ICsgMik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZFVJbnQzMiA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gdWludDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtVSW50MzIgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoNCwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIHVpbnQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkSW50MzIgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCg0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGludDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtJbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlayg0LCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gaW50MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEZsb2F0MzIgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCg0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGZsb2F0MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0Zsb2F0MzIgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoNCwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGZsb2F0MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEZsb2F0NjQgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCg4LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgaWYgKGZsb2F0NjQpIHtcbiAgICAgICAgcmV0dXJuIGZsb2F0NjRbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmxvYXQ2NEZhbGxiYWNrKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZsb2F0NjRGYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGV4cCwgZnJhYywgaGlnaCwgbG93LCBvdXQsIHNpZ247XG4gICAgICBsb3cgPSB1aW50MzJbMF0sIGhpZ2ggPSB1aW50MzJbMV07XG4gICAgICBpZiAoIWhpZ2ggfHwgaGlnaCA9PT0gMHg4MDAwMDAwMCkge1xuICAgICAgICByZXR1cm4gMC4wO1xuICAgICAgfVxuICAgICAgc2lnbiA9IDEgLSAoaGlnaCA+Pj4gMzEpICogMjtcbiAgICAgIGV4cCA9IChoaWdoID4+PiAyMCkgJiAweDdmZjtcbiAgICAgIGZyYWMgPSBoaWdoICYgMHhmZmZmZjtcbiAgICAgIGlmIChleHAgPT09IDB4N2ZmKSB7XG4gICAgICAgIGlmIChmcmFjKSB7XG4gICAgICAgICAgcmV0dXJuIDAvMDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2lnbiAqIDJlMzA4O1xuICAgICAgfVxuICAgICAgZXhwIC09IDEwMjM7XG4gICAgICBvdXQgPSAoZnJhYyB8IDB4MTAwMDAwKSAqIE1hdGgucG93KDIsIGV4cCAtIDIwKTtcbiAgICAgIG91dCArPSBsb3cgKiBNYXRoLnBvdygyLCBleHAgLSA1Mik7XG4gICAgICByZXR1cm4gc2lnbiAqIG91dDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrRmxvYXQ2NCA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlayg4LCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICBpZiAoZmxvYXQ2NCkge1xuICAgICAgICByZXR1cm4gZmxvYXQ2NFswXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmbG9hdDY0RmFsbGJhY2soKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkRmxvYXQ4MCA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDEwLCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGZsb2F0ODAoKTtcbiAgICB9O1xuXG4gICAgZmxvYXQ4MCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGEwLCBhMSwgZXhwLCBoaWdoLCBsb3csIG91dCwgc2lnbjtcbiAgICAgIGhpZ2ggPSB1aW50MzJbMF0sIGxvdyA9IHVpbnQzMlsxXTtcbiAgICAgIGEwID0gdWludDhbOV07XG4gICAgICBhMSA9IHVpbnQ4WzhdO1xuICAgICAgc2lnbiA9IDEgLSAoYTAgPj4+IDcpICogMjtcbiAgICAgIGV4cCA9ICgoYTAgJiAweDdGKSA8PCA4KSB8IGExO1xuICAgICAgaWYgKGV4cCA9PT0gMCAmJiBsb3cgPT09IDAgJiYgaGlnaCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChleHAgPT09IDB4N2ZmZikge1xuICAgICAgICBpZiAobG93ID09PSAwICYmIGhpZ2ggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gc2lnbiAqIDJlMzA4O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAwLzA7XG4gICAgICB9XG4gICAgICBleHAgLT0gMTYzODM7XG4gICAgICBvdXQgPSBsb3cgKiBNYXRoLnBvdygyLCBleHAgLSAzMSk7XG4gICAgICBvdXQgKz0gaGlnaCAqIE1hdGgucG93KDIsIGV4cCAtIDYzKTtcbiAgICAgIHJldHVybiBzaWduICogb3V0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtGbG9hdDgwID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDEwLCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gZmxvYXQ4MCgpO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRCdWZmZXIgPSBmdW5jdGlvbihsZW5ndGgpIHtcbiAgICAgIHZhciBpLCBqLCByZWYsIHJlc3VsdCwgdG87XG4gICAgICByZXN1bHQgPSBBVkJ1ZmZlci5hbGxvY2F0ZShsZW5ndGgpO1xuICAgICAgdG8gPSByZXN1bHQuZGF0YTtcbiAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBsZW5ndGg7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgdG9baV0gPSB0aGlzLnJlYWRVSW50OCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrQnVmZmVyID0gZnVuY3Rpb24ob2Zmc2V0LCBsZW5ndGgpIHtcbiAgICAgIHZhciBpLCBqLCByZWYsIHJlc3VsdCwgdG87XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHJlc3VsdCA9IEFWQnVmZmVyLmFsbG9jYXRlKGxlbmd0aCk7XG4gICAgICB0byA9IHJlc3VsdC5kYXRhO1xuICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IGxlbmd0aDsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICB0b1tpXSA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCArIGkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkU2luZ2xlQnVmZmVyID0gZnVuY3Rpb24obGVuZ3RoKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgcmVzdWx0ID0gdGhpcy5saXN0LmZpcnN0LnNsaWNlKHRoaXMubG9jYWxPZmZzZXQsIGxlbmd0aCk7XG4gICAgICB0aGlzLmFkdmFuY2UocmVzdWx0Lmxlbmd0aCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtTaW5nbGVCdWZmZXIgPSBmdW5jdGlvbihvZmZzZXQsIGxlbmd0aCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IHRoaXMubGlzdC5maXJzdC5zbGljZSh0aGlzLmxvY2FsT2Zmc2V0ICsgb2Zmc2V0LCBsZW5ndGgpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkU3RyaW5nID0gZnVuY3Rpb24obGVuZ3RoLCBlbmNvZGluZykge1xuICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHtcbiAgICAgICAgZW5jb2RpbmcgPSAnYXNjaWknO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRlY29kZVN0cmluZy5jYWxsKHRoaXMsIDAsIGxlbmd0aCwgZW5jb2RpbmcsIHRydWUpO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtTdHJpbmcgPSBmdW5jdGlvbihvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHtcbiAgICAgICAgZW5jb2RpbmcgPSAnYXNjaWknO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRlY29kZVN0cmluZy5jYWxsKHRoaXMsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZywgZmFsc2UpO1xuICAgIH07XG5cbiAgICBkZWNvZGVTdHJpbmcgPSBmdW5jdGlvbihvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcsIGFkdmFuY2UpIHtcbiAgICAgIHZhciBiMSwgYjIsIGIzLCBiNCwgYm9tLCBjLCBlbmQsIGxpdHRsZUVuZGlhbiwgbnVsbEVuZCwgcHQsIHJlc3VsdCwgdzEsIHcyO1xuICAgICAgZW5jb2RpbmcgPSBlbmNvZGluZy50b0xvd2VyQ2FzZSgpO1xuICAgICAgbnVsbEVuZCA9IGxlbmd0aCA9PT0gbnVsbCA/IDAgOiAtMTtcbiAgICAgIGlmIChsZW5ndGggPT0gbnVsbCkge1xuICAgICAgICBsZW5ndGggPSAyZTMwODtcbiAgICAgIH1cbiAgICAgIGVuZCA9IG9mZnNldCArIGxlbmd0aDtcbiAgICAgIHJlc3VsdCA9ICcnO1xuICAgICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICAgICAgd2hpbGUgKG9mZnNldCA8IGVuZCAmJiAoYyA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSkgIT09IG51bGxFbmQpIHtcbiAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndXRmOCc6XG4gICAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgZW5kICYmIChiMSA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSkgIT09IG51bGxFbmQpIHtcbiAgICAgICAgICAgIGlmICgoYjEgJiAweDgwKSA9PT0gMCkge1xuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShiMSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChiMSAmIDB4ZTApID09PSAweGMwKSB7XG4gICAgICAgICAgICAgIGIyID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChiMSAmIDB4MWYpIDw8IDYpIHwgYjIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoYjEgJiAweGYwKSA9PT0gMHhlMCkge1xuICAgICAgICAgICAgICBiMiA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIGIzID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChiMSAmIDB4MGYpIDw8IDEyKSB8IChiMiA8PCA2KSB8IGIzKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGIxICYgMHhmOCkgPT09IDB4ZjApIHtcbiAgICAgICAgICAgICAgYjIgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICBiMyA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIGI0ID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgcHQgPSAoKChiMSAmIDB4MGYpIDw8IDE4KSB8IChiMiA8PCAxMikgfCAoYjMgPDwgNikgfCBiNCkgLSAweDEwMDAwO1xuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweGQ4MDAgKyAocHQgPj4gMTApLCAweGRjMDAgKyAocHQgJiAweDNmZikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndXRmMTYtYmUnOlxuICAgICAgICBjYXNlICd1dGYxNmJlJzpcbiAgICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICAgIGNhc2UgJ3V0ZjE2LWxlJzpcbiAgICAgICAgY2FzZSAndXRmMTZib20nOlxuICAgICAgICBjYXNlICd1dGYxNi1ib20nOlxuICAgICAgICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2YmUnOlxuICAgICAgICAgICAgY2FzZSAndXRmMTYtYmUnOlxuICAgICAgICAgICAgICBsaXR0bGVFbmRpYW4gPSBmYWxzZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2LWxlJzpcbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd1dGYxNmJvbSc6XG4gICAgICAgICAgICBjYXNlICd1dGYxNi1ib20nOlxuICAgICAgICAgICAgICBpZiAobGVuZ3RoIDwgMiB8fCAoYm9tID0gdGhpcy5wZWVrVUludDE2KG9mZnNldCkpID09PSBudWxsRW5kKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFkdmFuY2UpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuYWR2YW5jZShvZmZzZXQgKz0gMik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gYm9tID09PSAweGZmZmU7XG4gICAgICAgICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICAgIH1cbiAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgZW5kICYmICh3MSA9IHRoaXMucGVla1VJbnQxNihvZmZzZXQsIGxpdHRsZUVuZGlhbikpICE9PSBudWxsRW5kKSB7XG4gICAgICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgICAgIGlmICh3MSA8IDB4ZDgwMCB8fCB3MSA+IDB4ZGZmZikge1xuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh3MSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAodzEgPiAweGRiZmYpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHV0ZjE2IHNlcXVlbmNlLlwiKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB3MiA9IHRoaXMucGVla1VJbnQxNihvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICAgICAgICAgIGlmICh3MiA8IDB4ZGMwMCB8fCB3MiA+IDB4ZGZmZikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdXRmMTYgc2VxdWVuY2UuXCIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHcxLCB3Mik7XG4gICAgICAgICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodzEgPT09IG51bGxFbmQpIHtcbiAgICAgICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIGVuY29kaW5nOiBcIiArIGVuY29kaW5nKTtcbiAgICAgIH1cbiAgICAgIGlmIChhZHZhbmNlKSB7XG4gICAgICAgIHRoaXMuYWR2YW5jZShvZmZzZXQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFN0cmVhbTtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gU3RyZWFtO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIFVuZGVyZmxvd0Vycm9yLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgVW5kZXJmbG93RXJyb3IgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChVbmRlcmZsb3dFcnJvciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBVbmRlcmZsb3dFcnJvcigpIHtcbiAgICAgIFVuZGVyZmxvd0Vycm9yLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgdGhpcy5uYW1lID0gJ1VuZGVyZmxvd0Vycm9yJztcbiAgICAgIHRoaXMuc3RhY2sgPSBuZXcgRXJyb3IoKS5zdGFjaztcbiAgICB9XG5cbiAgICByZXR1cm4gVW5kZXJmbG93RXJyb3I7XG5cbiAgfSkoRXJyb3IpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gVW5kZXJmbG93RXJyb3I7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQml0c3RyZWFtLCBCdWZmZXJMaXN0LCBEZWNvZGVyLCBFdmVudEVtaXR0ZXIsIFN0cmVhbSwgVW5kZXJmbG93RXJyb3IsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgU3RyZWFtID0gcmVxdWlyZSgnLi9jb3JlL3N0cmVhbScpO1xuXG4gIEJpdHN0cmVhbSA9IHJlcXVpcmUoJy4vY29yZS9iaXRzdHJlYW0nKTtcblxuICBVbmRlcmZsb3dFcnJvciA9IHJlcXVpcmUoJy4vY29yZS91bmRlcmZsb3cnKTtcblxuICBEZWNvZGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgY29kZWNzO1xuXG4gICAgZXh0ZW5kKERlY29kZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gRGVjb2RlcihkZW11eGVyLCBmb3JtYXQpIHtcbiAgICAgIHZhciBsaXN0O1xuICAgICAgdGhpcy5kZW11eGVyID0gZGVtdXhlcjtcbiAgICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0O1xuICAgICAgbGlzdCA9IG5ldyBCdWZmZXJMaXN0O1xuICAgICAgdGhpcy5zdHJlYW0gPSBuZXcgU3RyZWFtKGxpc3QpO1xuICAgICAgdGhpcy5iaXRzdHJlYW0gPSBuZXcgQml0c3RyZWFtKHRoaXMuc3RyZWFtKTtcbiAgICAgIHRoaXMucmVjZWl2ZWRGaW5hbEJ1ZmZlciA9IGZhbHNlO1xuICAgICAgdGhpcy53YWl0aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ2Nvb2tpZScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oY29va2llKSB7XG4gICAgICAgICAgdmFyIGVycm9yO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuc2V0Q29va2llKGNvb2tpZSk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IxKSB7XG4gICAgICAgICAgICBlcnJvciA9IGVycm9yMTtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ2RhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgICAgICAgbGlzdC5hcHBlbmQoY2h1bmspO1xuICAgICAgICAgIGlmIChfdGhpcy53YWl0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZGVjb2RlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdlbmQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIF90aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIgPSB0cnVlO1xuICAgICAgICAgIGlmIChfdGhpcy53YWl0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZGVjb2RlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge307XG5cbiAgICBEZWNvZGVyLnByb3RvdHlwZS5zZXRDb29raWUgPSBmdW5jdGlvbihjb29raWUpIHt9O1xuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7fTtcblxuICAgIERlY29kZXIucHJvdG90eXBlLmRlY29kZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVycm9yLCBvZmZzZXQsIHBhY2tldDtcbiAgICAgIHRoaXMud2FpdGluZyA9ICF0aGlzLnJlY2VpdmVkRmluYWxCdWZmZXI7XG4gICAgICBvZmZzZXQgPSB0aGlzLmJpdHN0cmVhbS5vZmZzZXQoKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHBhY2tldCA9IHRoaXMucmVhZENodW5rKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcjEpIHtcbiAgICAgICAgZXJyb3IgPSBlcnJvcjE7XG4gICAgICAgIGlmICghKGVycm9yIGluc3RhbmNlb2YgVW5kZXJmbG93RXJyb3IpKSB7XG4gICAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChwYWNrZXQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgcGFja2V0KTtcbiAgICAgICAgaWYgKHRoaXMucmVjZWl2ZWRGaW5hbEJ1ZmZlcikge1xuICAgICAgICAgIHRoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIpIHtcbiAgICAgICAgdGhpcy5iaXRzdHJlYW0uc2VlayhvZmZzZXQpO1xuICAgICAgICB0aGlzLndhaXRpbmcgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHRpbWVzdGFtcCkge1xuICAgICAgdmFyIHNlZWtQb2ludDtcbiAgICAgIHNlZWtQb2ludCA9IHRoaXMuZGVtdXhlci5zZWVrKHRpbWVzdGFtcCk7XG4gICAgICB0aGlzLnN0cmVhbS5zZWVrKHNlZWtQb2ludC5vZmZzZXQpO1xuICAgICAgcmV0dXJuIHNlZWtQb2ludC50aW1lc3RhbXA7XG4gICAgfTtcblxuICAgIGNvZGVjcyA9IHt9O1xuXG4gICAgRGVjb2Rlci5yZWdpc3RlciA9IGZ1bmN0aW9uKGlkLCBkZWNvZGVyKSB7XG4gICAgICByZXR1cm4gY29kZWNzW2lkXSA9IGRlY29kZXI7XG4gICAgfTtcblxuICAgIERlY29kZXIuZmluZCA9IGZ1bmN0aW9uKGlkKSB7XG4gICAgICByZXR1cm4gY29kZWNzW2lkXSB8fCBudWxsO1xuICAgIH07XG5cbiAgICByZXR1cm4gRGVjb2RlcjtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gRGVjb2RlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZWNvZGVyLCBMUENNRGVjb2RlcixcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIERlY29kZXIgPSByZXF1aXJlKCcuLi9kZWNvZGVyJyk7XG5cbiAgTFBDTURlY29kZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChMUENNRGVjb2Rlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBMUENNRGVjb2RlcigpIHtcbiAgICAgIHRoaXMucmVhZENodW5rID0gYmluZCh0aGlzLnJlYWRDaHVuaywgdGhpcyk7XG4gICAgICByZXR1cm4gTFBDTURlY29kZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5yZWdpc3RlcignbHBjbScsIExQQ01EZWNvZGVyKTtcblxuICAgIExQQ01EZWNvZGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjaHVua1NpemUsIGksIGosIGssIGwsIGxpdHRsZUVuZGlhbiwgbSwgbiwgbywgb3V0cHV0LCByZWYsIHJlZjEsIHJlZjIsIHJlZjMsIHJlZjQsIHJlZjUsIHNhbXBsZXMsIHN0cmVhbTtcbiAgICAgIHN0cmVhbSA9IHRoaXMuc3RyZWFtO1xuICAgICAgbGl0dGxlRW5kaWFuID0gdGhpcy5mb3JtYXQubGl0dGxlRW5kaWFuO1xuICAgICAgY2h1bmtTaXplID0gTWF0aC5taW4oNDA5Niwgc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCkpO1xuICAgICAgc2FtcGxlcyA9IGNodW5rU2l6ZSAvICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDgpIHwgMDtcbiAgICAgIGlmIChjaHVua1NpemUgPCB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDgpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5mb3JtYXQuZmxvYXRpbmdQb2ludCkge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsKSB7XG4gICAgICAgICAgY2FzZSAzMjpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBGbG9hdDMyQXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gc2FtcGxlczsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICAgICAgICBvdXRwdXRbaV0gPSBzdHJlYW0ucmVhZEZsb2F0MzIobGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgNjQ6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgRmxvYXQ2NEFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gayA9IDAsIHJlZjEgPSBzYW1wbGVzOyBrIDwgcmVmMTsgaSA9IGsgKz0gMSkge1xuICAgICAgICAgICAgICBvdXRwdXRbaV0gPSBzdHJlYW0ucmVhZEZsb2F0NjQobGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGJpdCBkZXB0aC4nKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCkge1xuICAgICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBJbnQ4QXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBsID0gMCwgcmVmMiA9IHNhbXBsZXM7IGwgPCByZWYyOyBpID0gbCArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkSW50OCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAxNjpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBJbnQxNkFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gbSA9IDAsIHJlZjMgPSBzYW1wbGVzOyBtIDwgcmVmMzsgaSA9IG0gKz0gMSkge1xuICAgICAgICAgICAgICBvdXRwdXRbaV0gPSBzdHJlYW0ucmVhZEludDE2KGxpdHRsZUVuZGlhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIDI0OlxuICAgICAgICAgICAgb3V0cHV0ID0gbmV3IEludDMyQXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBuID0gMCwgcmVmNCA9IHNhbXBsZXM7IG4gPCByZWY0OyBpID0gbiArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkSW50MjQobGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgMzI6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgSW50MzJBcnJheShzYW1wbGVzKTtcbiAgICAgICAgICAgIGZvciAoaSA9IG8gPSAwLCByZWY1ID0gc2FtcGxlczsgbyA8IHJlZjU7IGkgPSBvICs9IDEpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W2ldID0gc3RyZWFtLnJlYWRJbnQzMihsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgYml0IGRlcHRoLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG5cbiAgICByZXR1cm4gTFBDTURlY29kZXI7XG5cbiAgfSkoRGVjb2Rlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgRGVjb2RlciwgWExBV0RlY29kZXIsXG4gICAgYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBEZWNvZGVyID0gcmVxdWlyZSgnLi4vZGVjb2RlcicpO1xuXG4gIFhMQVdEZWNvZGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgQklBUywgUVVBTlRfTUFTSywgU0VHX01BU0ssIFNFR19TSElGVCwgU0lHTl9CSVQ7XG5cbiAgICBleHRlbmQoWExBV0RlY29kZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gWExBV0RlY29kZXIoKSB7XG4gICAgICB0aGlzLnJlYWRDaHVuayA9IGJpbmQodGhpcy5yZWFkQ2h1bmssIHRoaXMpO1xuICAgICAgcmV0dXJuIFhMQVdEZWNvZGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIERlY29kZXIucmVnaXN0ZXIoJ3VsYXcnLCBYTEFXRGVjb2Rlcik7XG5cbiAgICBEZWNvZGVyLnJlZ2lzdGVyKCdhbGF3JywgWExBV0RlY29kZXIpO1xuXG4gICAgU0lHTl9CSVQgPSAweDgwO1xuXG4gICAgUVVBTlRfTUFTSyA9IDB4ZjtcblxuICAgIFNFR19TSElGVCA9IDQ7XG5cbiAgICBTRUdfTUFTSyA9IDB4NzA7XG5cbiAgICBCSUFTID0gMHg4NDtcblxuICAgIFhMQVdEZWNvZGVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaSwgaiwgaywgc2VnLCB0LCB0YWJsZSwgdmFsO1xuICAgICAgdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgPSAxNjtcbiAgICAgIHRoaXMudGFibGUgPSB0YWJsZSA9IG5ldyBJbnQxNkFycmF5KDI1Nik7XG4gICAgICBpZiAodGhpcy5mb3JtYXQuZm9ybWF0SUQgPT09ICd1bGF3Jykge1xuICAgICAgICBmb3IgKGkgPSBqID0gMDsgaiA8IDI1NjsgaSA9ICsraikge1xuICAgICAgICAgIHZhbCA9IH5pO1xuICAgICAgICAgIHQgPSAoKHZhbCAmIFFVQU5UX01BU0spIDw8IDMpICsgQklBUztcbiAgICAgICAgICB0IDw8PSAodmFsICYgU0VHX01BU0spID4+PiBTRUdfU0hJRlQ7XG4gICAgICAgICAgdGFibGVbaV0gPSB2YWwgJiBTSUdOX0JJVCA/IEJJQVMgLSB0IDogdCAtIEJJQVM7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoaSA9IGsgPSAwOyBrIDwgMjU2OyBpID0gKytrKSB7XG4gICAgICAgICAgdmFsID0gaSBeIDB4NTU7XG4gICAgICAgICAgdCA9IHZhbCAmIFFVQU5UX01BU0s7XG4gICAgICAgICAgc2VnID0gKHZhbCAmIFNFR19NQVNLKSA+Pj4gU0VHX1NISUZUO1xuICAgICAgICAgIGlmIChzZWcpIHtcbiAgICAgICAgICAgIHQgPSAodCArIHQgKyAxICsgMzIpIDw8IChzZWcgKyAyKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdCA9ICh0ICsgdCArIDEpIDw8IDM7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRhYmxlW2ldID0gdmFsICYgU0lHTl9CSVQgPyB0IDogLXQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgWExBV0RlY29kZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGksIGosIG91dHB1dCwgcmVmLCByZWYxLCBzYW1wbGVzLCBzdHJlYW0sIHRhYmxlO1xuICAgICAgcmVmID0gdGhpcywgc3RyZWFtID0gcmVmLnN0cmVhbSwgdGFibGUgPSByZWYudGFibGU7XG4gICAgICBzYW1wbGVzID0gTWF0aC5taW4oNDA5NiwgdGhpcy5zdHJlYW0ucmVtYWluaW5nQnl0ZXMoKSk7XG4gICAgICBpZiAoc2FtcGxlcyA9PT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBvdXRwdXQgPSBuZXcgSW50MTZBcnJheShzYW1wbGVzKTtcbiAgICAgIGZvciAoaSA9IGogPSAwLCByZWYxID0gc2FtcGxlczsgaiA8IHJlZjE7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgb3V0cHV0W2ldID0gdGFibGVbc3RyZWFtLnJlYWRVSW50OCgpXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfTtcblxuICAgIHJldHVybiBYTEFXRGVjb2RlcjtcblxuICB9KShEZWNvZGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBCdWZmZXJMaXN0LCBEZW11eGVyLCBFdmVudEVtaXR0ZXIsIFN0cmVhbSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vY29yZS9ldmVudHMnKTtcblxuICBCdWZmZXJMaXN0ID0gcmVxdWlyZSgnLi9jb3JlL2J1ZmZlcmxpc3QnKTtcblxuICBTdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvc3RyZWFtJyk7XG5cbiAgRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGZvcm1hdHM7XG5cbiAgICBleHRlbmQoRGVtdXhlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBEZW11eGVyLnByb2JlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIERlbXV4ZXIoc291cmNlLCBjaHVuaykge1xuICAgICAgdmFyIGxpc3QsIHJlY2VpdmVkO1xuICAgICAgbGlzdCA9IG5ldyBCdWZmZXJMaXN0O1xuICAgICAgbGlzdC5hcHBlbmQoY2h1bmspO1xuICAgICAgdGhpcy5zdHJlYW0gPSBuZXcgU3RyZWFtKGxpc3QpO1xuICAgICAgcmVjZWl2ZWQgPSBmYWxzZTtcbiAgICAgIHNvdXJjZS5vbignZGF0YScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oY2h1bmspIHtcbiAgICAgICAgICB2YXIgZTtcbiAgICAgICAgICByZWNlaXZlZCA9IHRydWU7XG4gICAgICAgICAgbGlzdC5hcHBlbmQoY2h1bmspO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMucmVhZENodW5rKGNodW5rKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgZSA9IGVycm9yO1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgc291cmNlLm9uKCdlcnJvcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHNvdXJjZS5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAoIXJlY2VpdmVkKSB7XG4gICAgICAgICAgICBfdGhpcy5yZWFkQ2h1bmsoY2h1bmspO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLnNlZWtQb2ludHMgPSBbXTtcbiAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHt9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oY2h1bmspIHt9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUuYWRkU2Vla1BvaW50ID0gZnVuY3Rpb24ob2Zmc2V0LCB0aW1lc3RhbXApIHtcbiAgICAgIHZhciBpbmRleDtcbiAgICAgIGluZGV4ID0gdGhpcy5zZWFyY2hUaW1lc3RhbXAodGltZXN0YW1wKTtcbiAgICAgIHJldHVybiB0aGlzLnNlZWtQb2ludHMuc3BsaWNlKGluZGV4LCAwLCB7XG4gICAgICAgIG9mZnNldDogb2Zmc2V0LFxuICAgICAgICB0aW1lc3RhbXA6IHRpbWVzdGFtcFxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIERlbXV4ZXIucHJvdG90eXBlLnNlYXJjaFRpbWVzdGFtcCA9IGZ1bmN0aW9uKHRpbWVzdGFtcCwgYmFja3dhcmQpIHtcbiAgICAgIHZhciBoaWdoLCBsb3csIG1pZCwgdGltZTtcbiAgICAgIGxvdyA9IDA7XG4gICAgICBoaWdoID0gdGhpcy5zZWVrUG9pbnRzLmxlbmd0aDtcbiAgICAgIGlmIChoaWdoID4gMCAmJiB0aGlzLnNlZWtQb2ludHNbaGlnaCAtIDFdLnRpbWVzdGFtcCA8IHRpbWVzdGFtcCkge1xuICAgICAgICByZXR1cm4gaGlnaDtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICAgIG1pZCA9IChsb3cgKyBoaWdoKSA+PiAxO1xuICAgICAgICB0aW1lID0gdGhpcy5zZWVrUG9pbnRzW21pZF0udGltZXN0YW1wO1xuICAgICAgICBpZiAodGltZSA8IHRpbWVzdGFtcCkge1xuICAgICAgICAgIGxvdyA9IG1pZCArIDE7XG4gICAgICAgIH0gZWxzZSBpZiAodGltZSA+PSB0aW1lc3RhbXApIHtcbiAgICAgICAgICBoaWdoID0gbWlkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaGlnaCA+IHRoaXMuc2Vla1BvaW50cy5sZW5ndGgpIHtcbiAgICAgICAgaGlnaCA9IHRoaXMuc2Vla1BvaW50cy5sZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGlnaDtcbiAgICB9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHRpbWVzdGFtcCkge1xuICAgICAgdmFyIGluZGV4LCBzZWVrUG9pbnQ7XG4gICAgICBpZiAodGhpcy5mb3JtYXQgJiYgdGhpcy5mb3JtYXQuZnJhbWVzUGVyUGFja2V0ID4gMCAmJiB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA+IDApIHtcbiAgICAgICAgc2Vla1BvaW50ID0ge1xuICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wLFxuICAgICAgICAgIG9mZnNldDogdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgKiB0aW1lc3RhbXAgLyB0aGlzLmZvcm1hdC5mcmFtZXNQZXJQYWNrZXRcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHNlZWtQb2ludDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZGV4ID0gdGhpcy5zZWFyY2hUaW1lc3RhbXAodGltZXN0YW1wKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vla1BvaW50c1tpbmRleF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZvcm1hdHMgPSBbXTtcblxuICAgIERlbXV4ZXIucmVnaXN0ZXIgPSBmdW5jdGlvbihkZW11eGVyKSB7XG4gICAgICByZXR1cm4gZm9ybWF0cy5wdXNoKGRlbXV4ZXIpO1xuICAgIH07XG5cbiAgICBEZW11eGVyLmZpbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciBlLCBmb3JtYXQsIGksIGxlbiwgb2Zmc2V0LCBzdHJlYW07XG4gICAgICBzdHJlYW0gPSBTdHJlYW0uZnJvbUJ1ZmZlcihidWZmZXIpO1xuICAgICAgZm9yIChpID0gMCwgbGVuID0gZm9ybWF0cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBmb3JtYXQgPSBmb3JtYXRzW2ldO1xuICAgICAgICBvZmZzZXQgPSBzdHJlYW0ub2Zmc2V0O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChmb3JtYXQucHJvYmUoc3RyZWFtKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgZSA9IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHN0cmVhbS5zZWVrKG9mZnNldCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgcmV0dXJuIERlbXV4ZXI7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IERlbXV4ZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQUlGRkRlbXV4ZXIsIERlbXV4ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi4vZGVtdXhlcicpO1xuXG4gIEFJRkZEZW11eGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoQUlGRkRlbXV4ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gQUlGRkRlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gQUlGRkRlbXV4ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVtdXhlci5yZWdpc3RlcihBSUZGRGVtdXhlcik7XG5cbiAgICBBSUZGRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIHJldHVybiBidWZmZXIucGVla1N0cmluZygwLCA0KSA9PT0gJ0ZPUk0nICYmICgocmVmID0gYnVmZmVyLnBlZWtTdHJpbmcoOCwgNCkpID09PSAnQUlGRicgfHwgcmVmID09PSAnQUlGQycpO1xuICAgIH07XG5cbiAgICBBSUZGRGVtdXhlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYnVmZmVyLCBmb3JtYXQsIG9mZnNldCwgcmVmO1xuICAgICAgaWYgKCF0aGlzLnJlYWRTdGFydCAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoMTIpKSB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnRk9STScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIEFJRkYuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5maWxlU2l6ZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5maWxlVHlwZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCk7XG4gICAgICAgIHRoaXMucmVhZFN0YXJ0ID0gdHJ1ZTtcbiAgICAgICAgaWYgKChyZWYgPSB0aGlzLmZpbGVUeXBlKSAhPT0gJ0FJRkYnICYmIHJlZiAhPT0gJ0FJRkMnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBSUZGLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIGlmICghdGhpcy5yZWFkSGVhZGVycyAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgIHRoaXMubGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICAgICAgY2FzZSAnQ09NTSc6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgICAgIGZvcm1hdElEOiAnbHBjbScsXG4gICAgICAgICAgICAgIGNoYW5uZWxzUGVyRnJhbWU6IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSxcbiAgICAgICAgICAgICAgc2FtcGxlQ291bnQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICAgICAgYml0c1BlckNoYW5uZWw6IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSxcbiAgICAgICAgICAgICAgc2FtcGxlUmF0ZTogdGhpcy5zdHJlYW0ucmVhZEZsb2F0ODAoKSxcbiAgICAgICAgICAgICAgZnJhbWVzUGVyUGFja2V0OiAxLFxuICAgICAgICAgICAgICBsaXR0bGVFbmRpYW46IGZhbHNlLFxuICAgICAgICAgICAgICBmbG9hdGluZ1BvaW50OiBmYWxzZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ID0gKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkgKiB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lO1xuICAgICAgICAgICAgaWYgKHRoaXMuZmlsZVR5cGUgPT09ICdBSUZDJykge1xuICAgICAgICAgICAgICBmb3JtYXQgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgICAgICB0aGlzLmZvcm1hdC5saXR0bGVFbmRpYW4gPSBmb3JtYXQgPT09ICdzb3d0JyAmJiB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA+IDg7XG4gICAgICAgICAgICAgIHRoaXMuZm9ybWF0LmZsb2F0aW5nUG9pbnQgPSBmb3JtYXQgPT09ICdmbDMyJyB8fCBmb3JtYXQgPT09ICdmbDY0JztcbiAgICAgICAgICAgICAgaWYgKGZvcm1hdCA9PT0gJ3R3b3MnIHx8IGZvcm1hdCA9PT0gJ3Nvd3QnIHx8IGZvcm1hdCA9PT0gJ2ZsMzInIHx8IGZvcm1hdCA9PT0gJ2ZsNjQnIHx8IGZvcm1hdCA9PT0gJ05PTkUnKSB7XG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gJ2xwY20nO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMuZm9ybWF0LmZvcm1hdElEID0gZm9ybWF0O1xuICAgICAgICAgICAgICB0aGlzLmxlbiAtPSA0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDE4KTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy5mb3JtYXQpO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMuZm9ybWF0LnNhbXBsZUNvdW50IC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ1NTTkQnOlxuICAgICAgICAgICAgaWYgKCEodGhpcy5yZWFkU1NOREhlYWRlciAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoNCkpKSB7XG4gICAgICAgICAgICAgIG9mZnNldCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZShvZmZzZXQpO1xuICAgICAgICAgICAgICB0aGlzLnJlYWRTU05ESGVhZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJ1ZmZlciA9IHRoaXMuc3RyZWFtLnJlYWRTaW5nbGVCdWZmZXIodGhpcy5sZW4pO1xuICAgICAgICAgICAgdGhpcy5sZW4gLT0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSB0aGlzLmxlbiA+IDA7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBidWZmZXIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMubGVuKSkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy50eXBlICE9PSAnU1NORCcpIHtcbiAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIEFJRkZEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFVRGVtdXhlciwgRGVtdXhlcixcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgQVVEZW11eGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgYnBzLCBmb3JtYXRzO1xuXG4gICAgZXh0ZW5kKEFVRGVtdXhlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBBVURlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gQVVEZW11eGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucmVnaXN0ZXIoQVVEZW11eGVyKTtcblxuICAgIEFVRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgcmV0dXJuIGJ1ZmZlci5wZWVrU3RyaW5nKDAsIDQpID09PSAnLnNuZCc7XG4gICAgfTtcblxuICAgIGJwcyA9IFs4LCA4LCAxNiwgMjQsIDMyLCAzMiwgNjRdO1xuXG4gICAgYnBzWzI2XSA9IDg7XG5cbiAgICBmb3JtYXRzID0ge1xuICAgICAgMTogJ3VsYXcnLFxuICAgICAgMjc6ICdhbGF3J1xuICAgIH07XG5cbiAgICBBVURlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ5dGVzLCBkYXRhU2l6ZSwgZW5jb2RpbmcsIHNpemU7XG4gICAgICBpZiAoIXRoaXMucmVhZEhlYWRlciAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoMjQpKSB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnLnNuZCcpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIEFVIGZpbGUuJyk7XG4gICAgICAgIH1cbiAgICAgICAgc2l6ZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgZGF0YVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIGVuY29kaW5nID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLmZvcm1hdCA9IHtcbiAgICAgICAgICBmb3JtYXRJRDogZm9ybWF0c1tlbmNvZGluZ10gfHwgJ2xwY20nLFxuICAgICAgICAgIGxpdHRsZUVuZGlhbjogZmFsc2UsXG4gICAgICAgICAgZmxvYXRpbmdQb2ludDogZW5jb2RpbmcgPT09IDYgfHwgZW5jb2RpbmcgPT09IDcsXG4gICAgICAgICAgYml0c1BlckNoYW5uZWw6IGJwc1tlbmNvZGluZyAtIDFdLFxuICAgICAgICAgIHNhbXBsZVJhdGU6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICBjaGFubmVsc1BlckZyYW1lOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgZnJhbWVzUGVyUGFja2V0OiAxXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnVW5zdXBwb3J0ZWQgZW5jb2RpbmcgaW4gQVUgZmlsZS4nKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA9ICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDgpICogdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZTtcbiAgICAgICAgaWYgKGRhdGFTaXplICE9PSAweGZmZmZmZmZmKSB7XG4gICAgICAgICAgYnl0ZXMgPSB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDg7XG4gICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIGRhdGFTaXplIC8gYnl0ZXMgLyB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lIC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVtaXQoJ2Zvcm1hdCcsIHRoaXMuZm9ybWF0KTtcbiAgICAgICAgdGhpcy5yZWFkSGVhZGVyID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnJlYWRIZWFkZXIpIHtcbiAgICAgICAgd2hpbGUgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIHRoaXMuc3RyZWFtLnJlYWRTaW5nbGVCdWZmZXIodGhpcy5zdHJlYW0ucmVtYWluaW5nQnl0ZXMoKSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBBVURlbXV4ZXI7XG5cbiAgfSkoRGVtdXhlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQ0FGRGVtdXhlciwgRGVtdXhlciwgTTRBRGVtdXhlcixcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgTTRBRGVtdXhlciA9IHJlcXVpcmUoJy4vbTRhJyk7XG5cbiAgQ0FGRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKENBRkRlbXV4ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gQ0FGRGVtdXhlcigpIHtcbiAgICAgIHJldHVybiBDQUZEZW11eGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucmVnaXN0ZXIoQ0FGRGVtdXhlcik7XG5cbiAgICBDQUZEZW11eGVyLnByb2JlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoMCwgNCkgPT09ICdjYWZmJztcbiAgICB9O1xuXG4gICAgQ0FGRGVtdXhlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYnVmZmVyLCBieXRlT2Zmc2V0LCBjb29raWUsIGVudHJpZXMsIGZsYWdzLCBpLCBqLCBrLCBrZXksIG1ldGFkYXRhLCBvZmZzZXQsIHJlZiwgcmVmMSwgc2FtcGxlT2Zmc2V0LCB2YWx1ZTtcbiAgICAgIGlmICghdGhpcy5mb3JtYXQgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDY0KSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ2NhZmYnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIkludmFsaWQgQ0FGLCBkb2VzIG5vdCBiZWdpbiB3aXRoICdjYWZmJ1wiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ2Rlc2MnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIkludmFsaWQgQ0FGLCAnY2FmZicgaXMgbm90IGZvbGxvd2VkIGJ5ICdkZXNjJ1wiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISh0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgPT09IDAgJiYgdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpID09PSAzMikpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiSW52YWxpZCAnZGVzYycgc2l6ZSwgc2hvdWxkIGJlIDMyXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZm9ybWF0ID0ge307XG4gICAgICAgIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgPSB0aGlzLnN0cmVhbS5yZWFkRmxvYXQ2NCgpO1xuICAgICAgICB0aGlzLmZvcm1hdC5mb3JtYXRJRCA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCk7XG4gICAgICAgIGZsYWdzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICBpZiAodGhpcy5mb3JtYXQuZm9ybWF0SUQgPT09ICdscGNtJykge1xuICAgICAgICAgIHRoaXMuZm9ybWF0LmZsb2F0aW5nUG9pbnQgPSBCb29sZWFuKGZsYWdzICYgMSk7XG4gICAgICAgICAgdGhpcy5mb3JtYXQubGl0dGxlRW5kaWFuID0gQm9vbGVhbihmbGFncyAmIDIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLmZvcm1hdC5mcmFtZXNQZXJQYWNrZXQgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLmVtaXQoJ2Zvcm1hdCcsIHRoaXMuZm9ybWF0KTtcbiAgICAgIH1cbiAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5hdmFpbGFibGUoMSkpIHtcbiAgICAgICAgaWYgKCF0aGlzLmhlYWRlckNhY2hlKSB7XG4gICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IHtcbiAgICAgICAgICAgIHR5cGU6IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCksXG4gICAgICAgICAgICBvdmVyc2l6ZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpICE9PSAwLFxuICAgICAgICAgICAgc2l6ZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAodGhpcy5oZWFkZXJDYWNoZS5vdmVyc2l6ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIkhvbHkgU2hpdCwgYW4gb3ZlcnNpemVkIGZpbGUsIG5vdCBzdXBwb3J0ZWQgaW4gSlNcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAodGhpcy5oZWFkZXJDYWNoZS50eXBlKSB7XG4gICAgICAgICAgY2FzZSAna3VraSc6XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSkpIHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuZm9ybWF0LmZvcm1hdElEID09PSAnYWFjICcpIHtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmhlYWRlckNhY2hlLnNpemU7XG4gICAgICAgICAgICAgICAgaWYgKGNvb2tpZSA9IE00QURlbXV4ZXIucmVhZEVzZHModGhpcy5zdHJlYW0pKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2Nvb2tpZScsIGNvb2tpZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlZWsob2Zmc2V0KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBidWZmZXIgPSB0aGlzLnN0cmVhbS5yZWFkQnVmZmVyKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdjb29raWUnLCBidWZmZXIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAncGFrdCc6XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSkpIHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ1NpemVzIGdyZWF0ZXIgdGhhbiAzMiBiaXRzIGFyZSBub3Qgc3VwcG9ydGVkLicpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMubnVtUGFja2V0cyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ1NpemVzIGdyZWF0ZXIgdGhhbiAzMiBiaXRzIGFyZSBub3Qgc3VwcG9ydGVkLicpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMubnVtRnJhbWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICAgICAgICB0aGlzLnByaW1pbmdGcmFtZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICAgIHRoaXMucmVtYWluZGVyRnJhbWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2R1cmF0aW9uJywgdGhpcy5udW1GcmFtZXMgLyB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlICogMTAwMCB8IDApO1xuICAgICAgICAgICAgICB0aGlzLnNlbnREdXJhdGlvbiA9IHRydWU7XG4gICAgICAgICAgICAgIGJ5dGVPZmZzZXQgPSAwO1xuICAgICAgICAgICAgICBzYW1wbGVPZmZzZXQgPSAwO1xuICAgICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gdGhpcy5udW1QYWNrZXRzOyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRTZWVrUG9pbnQoYnl0ZU9mZnNldCwgc2FtcGxlT2Zmc2V0KTtcbiAgICAgICAgICAgICAgICBieXRlT2Zmc2V0ICs9IHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0IHx8IE00QURlbXV4ZXIucmVhZERlc2NyTGVuKHRoaXMuc3RyZWFtKTtcbiAgICAgICAgICAgICAgICBzYW1wbGVPZmZzZXQgKz0gdGhpcy5mb3JtYXQuZnJhbWVzUGVyUGFja2V0IHx8IE00QURlbXV4ZXIucmVhZERlc2NyTGVuKHRoaXMuc3RyZWFtKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2luZm8nOlxuICAgICAgICAgICAgZW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgIG1ldGFkYXRhID0ge307XG4gICAgICAgICAgICBmb3IgKGkgPSBrID0gMCwgcmVmMSA9IGVudHJpZXM7IDAgPD0gcmVmMSA/IGsgPCByZWYxIDogayA+IHJlZjE7IGkgPSAwIDw9IHJlZjEgPyArK2sgOiAtLWspIHtcbiAgICAgICAgICAgICAga2V5ID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyhudWxsKTtcbiAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKG51bGwpO1xuICAgICAgICAgICAgICBtZXRhZGF0YVtrZXldID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ21ldGFkYXRhJywgbWV0YWRhdGEpO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdkYXRhJzpcbiAgICAgICAgICAgIGlmICghdGhpcy5zZW50Rmlyc3REYXRhQ2h1bmspIHtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZS5zaXplIC09IDQ7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCAhPT0gMCAmJiAhdGhpcy5zZW50RHVyYXRpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLm51bUZyYW1lcyA9IHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSAvIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCB0aGlzLm51bUZyYW1lcyAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5zZW50Rmlyc3REYXRhQ2h1bmsgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnVmZmVyID0gdGhpcy5zdHJlYW0ucmVhZFNpbmdsZUJ1ZmZlcih0aGlzLmhlYWRlckNhY2hlLnNpemUpO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZS5zaXplIC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBidWZmZXIpO1xuICAgICAgICAgICAgaWYgKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSA8PSAwKSB7XG4gICAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5oZWFkZXJDYWNoZS5zaXplKSkge1xuICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSk7XG4gICAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBDQUZEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIERlbXV4ZXIsIE00QURlbXV4ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBpbmRleE9mID0gW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH07XG5cbiAgRGVtdXhlciA9IHJlcXVpcmUoJy4uL2RlbXV4ZXInKTtcblxuICBNNEFEZW11eGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgQklUU19QRVJfQ0hBTk5FTCwgVFlQRVMsIGFmdGVyLCBhdG9tLCBhdG9tcywgYm9vbCwgY29udGFpbmVycywgZGlza1RyYWNrLCBnZW5yZXMsIG1ldGEsIHN0cmluZztcblxuICAgIGV4dGVuZChNNEFEZW11eGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIE00QURlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gTTRBRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKE00QURlbXV4ZXIpO1xuXG4gICAgVFlQRVMgPSBbJ000QSAnLCAnTTRQICcsICdNNEIgJywgJ000ViAnLCAnaXNvbScsICdtcDQyJywgJ3F0ICAnXTtcblxuICAgIE00QURlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoNCwgNCkgPT09ICdmdHlwJyAmJiAocmVmID0gYnVmZmVyLnBlZWtTdHJpbmcoOCwgNCksIGluZGV4T2YuY2FsbChUWVBFUywgcmVmKSA+PSAwKTtcbiAgICB9O1xuXG4gICAgTTRBRGVtdXhlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5hdG9tcyA9IFtdO1xuICAgICAgdGhpcy5vZmZzZXRzID0gW107XG4gICAgICB0aGlzLnRyYWNrID0gbnVsbDtcbiAgICAgIHJldHVybiB0aGlzLnRyYWNrcyA9IFtdO1xuICAgIH07XG5cbiAgICBhdG9tcyA9IHt9O1xuXG4gICAgY29udGFpbmVycyA9IHt9O1xuXG4gICAgYXRvbSA9IGZ1bmN0aW9uKG5hbWUsIGZuKSB7XG4gICAgICB2YXIgYywgY29udGFpbmVyLCBrLCBsZW4xLCByZWY7XG4gICAgICBjID0gW107XG4gICAgICByZWYgPSBuYW1lLnNwbGl0KCcuJykuc2xpY2UoMCwgLTEpO1xuICAgICAgZm9yIChrID0gMCwgbGVuMSA9IHJlZi5sZW5ndGg7IGsgPCBsZW4xOyBrKyspIHtcbiAgICAgICAgY29udGFpbmVyID0gcmVmW2tdO1xuICAgICAgICBjLnB1c2goY29udGFpbmVyKTtcbiAgICAgICAgY29udGFpbmVyc1tjLmpvaW4oJy4nKV0gPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKGF0b21zW25hbWVdID09IG51bGwpIHtcbiAgICAgICAgYXRvbXNbbmFtZV0gPSB7fTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdG9tc1tuYW1lXS5mbiA9IGZuO1xuICAgIH07XG5cbiAgICBhZnRlciA9IGZ1bmN0aW9uKG5hbWUsIGZuKSB7XG4gICAgICBpZiAoYXRvbXNbbmFtZV0gPT0gbnVsbCkge1xuICAgICAgICBhdG9tc1tuYW1lXSA9IHt9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGF0b21zW25hbWVdLmFmdGVyID0gZm47XG4gICAgfTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGhhbmRsZXIsIHBhdGgsIHR5cGU7XG4gICAgICB0aGlzW1wiYnJlYWtcIl0gPSBmYWxzZTtcbiAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5hdmFpbGFibGUoMSkgJiYgIXRoaXNbXCJicmVha1wiXSkge1xuICAgICAgICBpZiAoIXRoaXMucmVhZEhlYWRlcnMpIHtcbiAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSg4KSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmxlbiA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSAtIDg7XG4gICAgICAgICAgdGhpcy50eXBlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgICAgICBpZiAodGhpcy5sZW4gPT09IDApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmF0b21zLnB1c2godGhpcy50eXBlKTtcbiAgICAgICAgICB0aGlzLm9mZnNldHMucHVzaCh0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmxlbik7XG4gICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcGF0aCA9IHRoaXMuYXRvbXMuam9pbignLicpO1xuICAgICAgICBoYW5kbGVyID0gYXRvbXNbcGF0aF07XG4gICAgICAgIGlmIChoYW5kbGVyICE9IG51bGwgPyBoYW5kbGVyLmZuIDogdm9pZCAwKSB7XG4gICAgICAgICAgaWYgKCEodGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMubGVuKSB8fCBwYXRoID09PSAnbWRhdCcpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGhhbmRsZXIuZm4uY2FsbCh0aGlzKTtcbiAgICAgICAgICBpZiAocGF0aCBpbiBjb250YWluZXJzKSB7XG4gICAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHBhdGggaW4gY29udGFpbmVycykge1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbik7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHRoaXMuc3RyZWFtLm9mZnNldCA+PSB0aGlzLm9mZnNldHNbdGhpcy5vZmZzZXRzLmxlbmd0aCAtIDFdKSB7XG4gICAgICAgICAgaGFuZGxlciA9IGF0b21zW3RoaXMuYXRvbXMuam9pbignLicpXTtcbiAgICAgICAgICBpZiAoaGFuZGxlciAhPSBudWxsID8gaGFuZGxlci5hZnRlciA6IHZvaWQgMCkge1xuICAgICAgICAgICAgaGFuZGxlci5hZnRlci5jYWxsKHRoaXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0eXBlID0gdGhpcy5hdG9tcy5wb3AoKTtcbiAgICAgICAgICB0aGlzLm9mZnNldHMucG9wKCk7XG4gICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGF0b20oJ2Z0eXAnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAocmVmID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSwgaW5kZXhPZi5jYWxsKFRZUEVTLCByZWYpIDwgMCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdOb3QgYSB2YWxpZCBNNEEgZmlsZS4nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gNCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMudHJhY2sgPSB7fTtcbiAgICAgIHJldHVybiB0aGlzLnRyYWNrcy5wdXNoKHRoaXMudHJhY2spO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLnRraGQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDgpO1xuICAgICAgdGhpcy50cmFjay5pZCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gMTYpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEuaGRscicsIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnRyYWNrLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgxMik7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDI0KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1kaGQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDgpO1xuICAgICAgdGhpcy50cmFjay50aW1lU2NhbGUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB0aGlzLnRyYWNrLmR1cmF0aW9uID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgfSk7XG5cbiAgICBCSVRTX1BFUl9DSEFOTkVMID0ge1xuICAgICAgdWxhdzogOCxcbiAgICAgIGFsYXc6IDgsXG4gICAgICBpbjI0OiAyNCxcbiAgICAgIGluMzI6IDMyLFxuICAgICAgZmwzMjogMzIsXG4gICAgICBmbDY0OiA2NFxuICAgIH07XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGZvcm1hdCwgbnVtRW50cmllcywgcmVmLCByZWYxLCB2ZXJzaW9uO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIG51bUVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICBpZiAodGhpcy50cmFjay50eXBlICE9PSAnc291bicpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4gLSA4KTtcbiAgICAgIH1cbiAgICAgIGlmIChudW1FbnRyaWVzICE9PSAxKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgXCJPbmx5IGV4cGVjdGluZyBvbmUgZW50cnkgaW4gc2FtcGxlIGRlc2NyaXB0aW9uIGF0b20hXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIGZvcm1hdCA9IHRoaXMudHJhY2suZm9ybWF0ID0ge307XG4gICAgICBmb3JtYXQuZm9ybWF0SUQgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg2KTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICB2ZXJzaW9uID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg2KTtcbiAgICAgIGZvcm1hdC5jaGFubmVsc1BlckZyYW1lID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIGZvcm1hdC5zYW1wbGVSYXRlID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgIGlmICh2ZXJzaW9uID09PSAxKSB7XG4gICAgICAgIGZvcm1hdC5mcmFtZXNQZXJQYWNrZXQgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICAgIGZvcm1hdC5ieXRlc1BlckZyYW1lID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgfSBlbHNlIGlmICh2ZXJzaW9uICE9PSAwKSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZXJyb3InLCAnVW5rbm93biB2ZXJzaW9uIGluIHN0c2QgYXRvbScpO1xuICAgICAgfVxuICAgICAgaWYgKEJJVFNfUEVSX0NIQU5ORUxbZm9ybWF0LmZvcm1hdElEXSAhPSBudWxsKSB7XG4gICAgICAgIGZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9IEJJVFNfUEVSX0NIQU5ORUxbZm9ybWF0LmZvcm1hdElEXTtcbiAgICAgIH1cbiAgICAgIGZvcm1hdC5mbG9hdGluZ1BvaW50ID0gKHJlZiA9IGZvcm1hdC5mb3JtYXRJRCkgPT09ICdmbDMyJyB8fCByZWYgPT09ICdmbDY0JztcbiAgICAgIGZvcm1hdC5saXR0bGVFbmRpYW4gPSBmb3JtYXQuZm9ybWF0SUQgPT09ICdzb3d0JyAmJiBmb3JtYXQuYml0c1BlckNoYW5uZWwgPiA4O1xuICAgICAgaWYgKChyZWYxID0gZm9ybWF0LmZvcm1hdElEKSA9PT0gJ3R3b3MnIHx8IHJlZjEgPT09ICdzb3d0JyB8fCByZWYxID09PSAnaW4yNCcgfHwgcmVmMSA9PT0gJ2luMzInIHx8IHJlZjEgPT09ICdmbDMyJyB8fCByZWYxID09PSAnZmw2NCcgfHwgcmVmMSA9PT0gJ3JhdyAnIHx8IHJlZjEgPT09ICdOT05FJykge1xuICAgICAgICByZXR1cm4gZm9ybWF0LmZvcm1hdElEID0gJ2xwY20nO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c2QuYWxhYycsIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHJldHVybiB0aGlzLnRyYWNrLmNvb2tpZSA9IHRoaXMuc3RyZWFtLnJlYWRCdWZmZXIodGhpcy5sZW4gLSA0KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNkLmVzZHMnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBvZmZzZXQ7XG4gICAgICBvZmZzZXQgPSB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmxlbjtcbiAgICAgIHRoaXMudHJhY2suY29va2llID0gTTRBRGVtdXhlci5yZWFkRXNkcyh0aGlzLnN0cmVhbSk7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uc2VlayhvZmZzZXQpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c2Qud2F2ZS5lbmRhJywgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50cmFjay5mb3JtYXQubGl0dGxlRW5kaWFuID0gISF0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgfSk7XG5cbiAgICBNNEFEZW11eGVyLnJlYWREZXNjckxlbiA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgdmFyIGMsIGNvdW50LCBsZW47XG4gICAgICBsZW4gPSAwO1xuICAgICAgY291bnQgPSA0O1xuICAgICAgd2hpbGUgKGNvdW50LS0pIHtcbiAgICAgICAgYyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgICAgbGVuID0gKGxlbiA8PCA3KSB8IChjICYgMHg3Zik7XG4gICAgICAgIGlmICghKGMgJiAweDgwKSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbGVuO1xuICAgIH07XG5cbiAgICBNNEFEZW11eGVyLnJlYWRFc2RzID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICB2YXIgY29kZWNfaWQsIGZsYWdzLCBsZW4sIHRhZztcbiAgICAgIHN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGFnID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgbGVuID0gTTRBRGVtdXhlci5yZWFkRGVzY3JMZW4oc3RyZWFtKTtcbiAgICAgIGlmICh0YWcgPT09IDB4MDMpIHtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICAgIGZsYWdzID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBpZiAoZmxhZ3MgJiAweDgwKSB7XG4gICAgICAgICAgc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZsYWdzICYgMHg0MCkge1xuICAgICAgICAgIHN0cmVhbS5hZHZhbmNlKHN0cmVhbS5yZWFkVUludDgoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZsYWdzICYgMHgyMCkge1xuICAgICAgICAgIHN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgIH1cbiAgICAgIHRhZyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgIGxlbiA9IE00QURlbXV4ZXIucmVhZERlc2NyTGVuKHN0cmVhbSk7XG4gICAgICBpZiAodGFnID09PSAweDA0KSB7XG4gICAgICAgIGNvZGVjX2lkID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSgxKTtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMyk7XG4gICAgICAgIHN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgdGFnID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBsZW4gPSBNNEFEZW11eGVyLnJlYWREZXNjckxlbihzdHJlYW0pO1xuICAgICAgICBpZiAodGFnID09PSAweDA1KSB7XG4gICAgICAgICAgcmV0dXJuIHN0cmVhbS5yZWFkQnVmZmVyKGxlbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3R0cycsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIGssIHJlZjtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBlbnRyaWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgdGhpcy50cmFjay5zdHRzID0gW107XG4gICAgICBmb3IgKGkgPSBrID0gMCwgcmVmID0gZW50cmllczsgayA8IHJlZjsgaSA9IGsgKz0gMSkge1xuICAgICAgICB0aGlzLnRyYWNrLnN0dHNbaV0gPSB7XG4gICAgICAgICAgY291bnQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICBkdXJhdGlvbjogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5zZXR1cFNlZWtQb2ludHMoKTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNjJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZW50cmllcywgaSwgaywgcmVmO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB0aGlzLnRyYWNrLnN0c2MgPSBbXTtcbiAgICAgIGZvciAoaSA9IGsgPSAwLCByZWYgPSBlbnRyaWVzOyBrIDwgcmVmOyBpID0gayArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suc3RzY1tpXSA9IHtcbiAgICAgICAgICBmaXJzdDogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpLFxuICAgICAgICAgIGNvdW50OiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgaWQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzeicsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIGssIHJlZjtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnRyYWNrLnNhbXBsZVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICBlbnRyaWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgaWYgKHRoaXMudHJhY2suc2FtcGxlU2l6ZSA9PT0gMCAmJiBlbnRyaWVzID4gMCkge1xuICAgICAgICB0aGlzLnRyYWNrLnNhbXBsZVNpemVzID0gW107XG4gICAgICAgIGZvciAoaSA9IGsgPSAwLCByZWYgPSBlbnRyaWVzOyBrIDwgcmVmOyBpID0gayArPSAxKSB7XG4gICAgICAgICAgdGhpcy50cmFjay5zYW1wbGVTaXplc1tpXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RjbycsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIGssIHJlZjtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBlbnRyaWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgdGhpcy50cmFjay5jaHVua09mZnNldHMgPSBbXTtcbiAgICAgIGZvciAoaSA9IGsgPSAwLCByZWYgPSBlbnRyaWVzOyBrIDwgcmVmOyBpID0gayArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suY2h1bmtPZmZzZXRzW2ldID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsudHJlZi5jaGFwJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZW50cmllcywgaSwgaywgcmVmO1xuICAgICAgZW50cmllcyA9IHRoaXMubGVuID4+IDI7XG4gICAgICB0aGlzLnRyYWNrLmNoYXB0ZXJUcmFja3MgPSBbXTtcbiAgICAgIGZvciAoaSA9IGsgPSAwLCByZWYgPSBlbnRyaWVzOyBrIDwgcmVmOyBpID0gayArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suY2hhcHRlclRyYWNrc1tpXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLnNldHVwU2Vla1BvaW50cyA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGksIGosIGssIGwsIGxlbjEsIG9mZnNldCwgcG9zaXRpb24sIHJlZiwgcmVmMSwgcmVzdWx0cywgc2FtcGxlSW5kZXgsIHNpemUsIHN0c2NJbmRleCwgc3R0c0luZGV4LCBzdHRzU2FtcGxlLCB0aW1lc3RhbXA7XG4gICAgICBpZiAoISgodGhpcy50cmFjay5jaHVua09mZnNldHMgIT0gbnVsbCkgJiYgKHRoaXMudHJhY2suc3RzYyAhPSBudWxsKSAmJiAodGhpcy50cmFjay5zYW1wbGVTaXplICE9IG51bGwpICYmICh0aGlzLnRyYWNrLnN0dHMgIT0gbnVsbCkpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHN0c2NJbmRleCA9IDA7XG4gICAgICBzdHRzSW5kZXggPSAwO1xuICAgICAgc3R0c0luZGV4ID0gMDtcbiAgICAgIHN0dHNTYW1wbGUgPSAwO1xuICAgICAgc2FtcGxlSW5kZXggPSAwO1xuICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIHRpbWVzdGFtcCA9IDA7XG4gICAgICB0aGlzLnRyYWNrLnNlZWtQb2ludHMgPSBbXTtcbiAgICAgIHJlZiA9IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzO1xuICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgZm9yIChpID0gayA9IDAsIGxlbjEgPSByZWYubGVuZ3RoOyBrIDwgbGVuMTsgaSA9ICsraykge1xuICAgICAgICBwb3NpdGlvbiA9IHJlZltpXTtcbiAgICAgICAgZm9yIChqID0gbCA9IDAsIHJlZjEgPSB0aGlzLnRyYWNrLnN0c2Nbc3RzY0luZGV4XS5jb3VudDsgbCA8IHJlZjE7IGogPSBsICs9IDEpIHtcbiAgICAgICAgICB0aGlzLnRyYWNrLnNlZWtQb2ludHMucHVzaCh7XG4gICAgICAgICAgICBvZmZzZXQ6IG9mZnNldCxcbiAgICAgICAgICAgIHBvc2l0aW9uOiBwb3NpdGlvbixcbiAgICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgc2l6ZSA9IHRoaXMudHJhY2suc2FtcGxlU2l6ZSB8fCB0aGlzLnRyYWNrLnNhbXBsZVNpemVzW3NhbXBsZUluZGV4KytdO1xuICAgICAgICAgIG9mZnNldCArPSBzaXplO1xuICAgICAgICAgIHBvc2l0aW9uICs9IHNpemU7XG4gICAgICAgICAgdGltZXN0YW1wICs9IHRoaXMudHJhY2suc3R0c1tzdHRzSW5kZXhdLmR1cmF0aW9uO1xuICAgICAgICAgIGlmIChzdHRzSW5kZXggKyAxIDwgdGhpcy50cmFjay5zdHRzLmxlbmd0aCAmJiArK3N0dHNTYW1wbGUgPT09IHRoaXMudHJhY2suc3R0c1tzdHRzSW5kZXhdLmNvdW50KSB7XG4gICAgICAgICAgICBzdHRzU2FtcGxlID0gMDtcbiAgICAgICAgICAgIHN0dHNJbmRleCsrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RzY0luZGV4ICsgMSA8IHRoaXMudHJhY2suc3RzYy5sZW5ndGggJiYgaSArIDEgPT09IHRoaXMudHJhY2suc3RzY1tzdHNjSW5kZXggKyAxXS5maXJzdCkge1xuICAgICAgICAgIHJlc3VsdHMucHVzaChzdHNjSW5kZXgrKyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKHZvaWQgMCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHRzO1xuICAgIH07XG5cbiAgICBhZnRlcignbW9vdicsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGssIGxlbjEsIHJlZiwgdHJhY2s7XG4gICAgICBpZiAodGhpcy5tZGF0T2Zmc2V0ICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5zdHJlYW0uc2Vlayh0aGlzLm1kYXRPZmZzZXQgLSA4KTtcbiAgICAgIH1cbiAgICAgIHJlZiA9IHRoaXMudHJhY2tzO1xuICAgICAgZm9yIChrID0gMCwgbGVuMSA9IHJlZi5sZW5ndGg7IGsgPCBsZW4xOyBrKyspIHtcbiAgICAgICAgdHJhY2sgPSByZWZba107XG4gICAgICAgIGlmICghKHRyYWNrLnR5cGUgPT09ICdzb3VuJykpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRyYWNrID0gdHJhY2s7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMudHJhY2sudHlwZSAhPT0gJ3NvdW4nKSB7XG4gICAgICAgIHRoaXMudHJhY2sgPSBudWxsO1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdObyBhdWRpbyB0cmFja3MgaW4gbTRhIGZpbGUuJyk7XG4gICAgICB9XG4gICAgICB0aGlzLmVtaXQoJ2Zvcm1hdCcsIHRoaXMudHJhY2suZm9ybWF0KTtcbiAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCB0aGlzLnRyYWNrLmR1cmF0aW9uIC8gdGhpcy50cmFjay50aW1lU2NhbGUgKiAxMDAwIHwgMCk7XG4gICAgICBpZiAodGhpcy50cmFjay5jb29raWUpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjb29raWUnLCB0aGlzLnRyYWNrLmNvb2tpZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5zZWVrUG9pbnRzID0gdGhpcy50cmFjay5zZWVrUG9pbnRzO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbWRhdCcsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ5dGVzLCBjaHVua1NpemUsIGssIGxlbmd0aCwgbnVtU2FtcGxlcywgb2Zmc2V0LCByZWYsIHNhbXBsZSwgc2l6ZTtcbiAgICAgIGlmICghdGhpcy5zdGFydGVkRGF0YSkge1xuICAgICAgICBpZiAodGhpcy5tZGF0T2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLm1kYXRPZmZzZXQgPSB0aGlzLnN0cmVhbS5vZmZzZXQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHJhY2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGJ5dGVzID0gTWF0aC5taW4odGhpcy5zdHJlYW0ucmVtYWluaW5nQnl0ZXMoKSwgdGhpcy5sZW4pO1xuICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoYnl0ZXMpO1xuICAgICAgICAgIHRoaXMubGVuIC09IGJ5dGVzO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNodW5rSW5kZXggPSAwO1xuICAgICAgICB0aGlzLnN0c2NJbmRleCA9IDA7XG4gICAgICAgIHRoaXMuc2FtcGxlSW5kZXggPSAwO1xuICAgICAgICB0aGlzLnRhaWxPZmZzZXQgPSAwO1xuICAgICAgICB0aGlzLnRhaWxTYW1wbGVzID0gMDtcbiAgICAgICAgdGhpcy5zdGFydGVkRGF0YSA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMucmVhZENoYXB0ZXJzKSB7XG4gICAgICAgIHRoaXMucmVhZENoYXB0ZXJzID0gdGhpcy5wYXJzZUNoYXB0ZXJzKCk7XG4gICAgICAgIGlmICh0aGlzW1wiYnJlYWtcIl0gPSAhdGhpcy5yZWFkQ2hhcHRlcnMpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdHJlYW0uc2Vlayh0aGlzLm1kYXRPZmZzZXQpO1xuICAgICAgfVxuICAgICAgb2Zmc2V0ID0gdGhpcy50cmFjay5jaHVua09mZnNldHNbdGhpcy5jaHVua0luZGV4XSArIHRoaXMudGFpbE9mZnNldDtcbiAgICAgIGxlbmd0aCA9IDA7XG4gICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZShvZmZzZXQgLSB0aGlzLnN0cmVhbS5vZmZzZXQpKSB7XG4gICAgICAgIHRoaXNbXCJicmVha1wiXSA9IHRydWU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RyZWFtLnNlZWsob2Zmc2V0KTtcbiAgICAgIHdoaWxlICh0aGlzLmNodW5rSW5kZXggPCB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0cy5sZW5ndGgpIHtcbiAgICAgICAgbnVtU2FtcGxlcyA9IHRoaXMudHJhY2suc3RzY1t0aGlzLnN0c2NJbmRleF0uY291bnQgLSB0aGlzLnRhaWxTYW1wbGVzO1xuICAgICAgICBjaHVua1NpemUgPSAwO1xuICAgICAgICBmb3IgKHNhbXBsZSA9IGsgPSAwLCByZWYgPSBudW1TYW1wbGVzOyBrIDwgcmVmOyBzYW1wbGUgPSBrICs9IDEpIHtcbiAgICAgICAgICBzaXplID0gdGhpcy50cmFjay5zYW1wbGVTaXplIHx8IHRoaXMudHJhY2suc2FtcGxlU2l6ZXNbdGhpcy5zYW1wbGVJbmRleF07XG4gICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUobGVuZ3RoICsgc2l6ZSkpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsZW5ndGggKz0gc2l6ZTtcbiAgICAgICAgICBjaHVua1NpemUgKz0gc2l6ZTtcbiAgICAgICAgICB0aGlzLnNhbXBsZUluZGV4Kys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNhbXBsZSA8IG51bVNhbXBsZXMpIHtcbiAgICAgICAgICB0aGlzLnRhaWxPZmZzZXQgKz0gY2h1bmtTaXplO1xuICAgICAgICAgIHRoaXMudGFpbFNhbXBsZXMgKz0gc2FtcGxlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuY2h1bmtJbmRleCsrO1xuICAgICAgICAgIHRoaXMudGFpbE9mZnNldCA9IDA7XG4gICAgICAgICAgdGhpcy50YWlsU2FtcGxlcyA9IDA7XG4gICAgICAgICAgaWYgKHRoaXMuc3RzY0luZGV4ICsgMSA8IHRoaXMudHJhY2suc3RzYy5sZW5ndGggJiYgdGhpcy5jaHVua0luZGV4ICsgMSA9PT0gdGhpcy50cmFjay5zdHNjW3RoaXMuc3RzY0luZGV4ICsgMV0uZmlyc3QpIHtcbiAgICAgICAgICAgIHRoaXMuc3RzY0luZGV4Kys7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChvZmZzZXQgKyBsZW5ndGggIT09IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzW3RoaXMuY2h1bmtJbmRleF0pIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgdGhpcy5zdHJlYW0ucmVhZEJ1ZmZlcihsZW5ndGgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXNbXCJicmVha1wiXSA9IHRoaXMuY2h1bmtJbmRleCA9PT0gdGhpcy50cmFjay5jaHVua09mZnNldHMubGVuZ3RoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbXCJicmVha1wiXSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBNNEFEZW11eGVyLnByb3RvdHlwZS5wYXJzZUNoYXB0ZXJzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYm9tLCBpZCwgaywgbGVuLCBsZW4xLCBuZXh0VGltZXN0YW1wLCBwb2ludCwgcmVmLCByZWYxLCByZWYyLCByZWYzLCB0aXRsZSwgdHJhY2s7XG4gICAgICBpZiAoISgoKHJlZiA9IHRoaXMudHJhY2suY2hhcHRlclRyYWNrcykgIT0gbnVsbCA/IHJlZi5sZW5ndGggOiB2b2lkIDApID4gMCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZCA9IHRoaXMudHJhY2suY2hhcHRlclRyYWNrc1swXTtcbiAgICAgIHJlZjEgPSB0aGlzLnRyYWNrcztcbiAgICAgIGZvciAoayA9IDAsIGxlbjEgPSByZWYxLmxlbmd0aDsgayA8IGxlbjE7IGsrKykge1xuICAgICAgICB0cmFjayA9IHJlZjFba107XG4gICAgICAgIGlmICh0cmFjay5pZCA9PT0gaWQpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRyYWNrLmlkICE9PSBpZCkge1xuICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgJ0NoYXB0ZXIgdHJhY2sgZG9lcyBub3QgZXhpc3QuJyk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5jaGFwdGVycyA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuY2hhcHRlcnMgPSBbXTtcbiAgICAgIH1cbiAgICAgIHdoaWxlICh0aGlzLmNoYXB0ZXJzLmxlbmd0aCA8IHRyYWNrLnNlZWtQb2ludHMubGVuZ3RoKSB7XG4gICAgICAgIHBvaW50ID0gdHJhY2suc2Vla1BvaW50c1t0aGlzLmNoYXB0ZXJzLmxlbmd0aF07XG4gICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKHBvaW50LnBvc2l0aW9uIC0gdGhpcy5zdHJlYW0ub2Zmc2V0ICsgMzIpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyZWFtLnNlZWsocG9pbnQucG9zaXRpb24pO1xuICAgICAgICBsZW4gPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICAgIHRpdGxlID0gbnVsbDtcbiAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUobGVuKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGVuID4gMikge1xuICAgICAgICAgIGJvbSA9IHRoaXMuc3RyZWFtLnBlZWtVSW50MTYoKTtcbiAgICAgICAgICBpZiAoYm9tID09PSAweGZlZmYgfHwgYm9tID09PSAweGZmZmUpIHtcbiAgICAgICAgICAgIHRpdGxlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyhsZW4sICd1dGYxNi1ib20nKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRpdGxlID09IG51bGwpIHtcbiAgICAgICAgICB0aXRsZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcobGVuLCAndXRmOCcpO1xuICAgICAgICB9XG4gICAgICAgIG5leHRUaW1lc3RhbXAgPSAocmVmMiA9IChyZWYzID0gdHJhY2suc2Vla1BvaW50c1t0aGlzLmNoYXB0ZXJzLmxlbmd0aCArIDFdKSAhPSBudWxsID8gcmVmMy50aW1lc3RhbXAgOiB2b2lkIDApICE9IG51bGwgPyByZWYyIDogdHJhY2suZHVyYXRpb247XG4gICAgICAgIHRoaXMuY2hhcHRlcnMucHVzaCh7XG4gICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgIHRpbWVzdGFtcDogcG9pbnQudGltZXN0YW1wIC8gdHJhY2sudGltZVNjYWxlICogMTAwMCB8IDAsXG4gICAgICAgICAgZHVyYXRpb246IChuZXh0VGltZXN0YW1wIC0gcG9pbnQudGltZXN0YW1wKSAvIHRyYWNrLnRpbWVTY2FsZSAqIDEwMDAgfCAwXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgdGhpcy5lbWl0KCdjaGFwdGVycycsIHRoaXMuY2hhcHRlcnMpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIGF0b20oJ21vb3YudWR0YS5tZXRhJywgZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLm1ldGFkYXRhID0ge307XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICB9KTtcblxuICAgIGFmdGVyKCdtb292LnVkdGEubWV0YScsIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnbWV0YWRhdGEnLCB0aGlzLm1ldGFkYXRhKTtcbiAgICB9KTtcblxuICAgIG1ldGEgPSBmdW5jdGlvbihmaWVsZCwgbmFtZSwgZm4pIHtcbiAgICAgIHJldHVybiBhdG9tKFwibW9vdi51ZHRhLm1ldGEuaWxzdC5cIiArIGZpZWxkICsgXCIuZGF0YVwiLCBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg4KTtcbiAgICAgICAgdGhpcy5sZW4gLT0gODtcbiAgICAgICAgcmV0dXJuIGZuLmNhbGwodGhpcywgbmFtZSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgc3RyaW5nID0gZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcodGhpcy5sZW4sICd1dGY4Jyk7XG4gICAgfTtcblxuICAgIG1ldGEoJ8KpYWxiJywgJ2FsYnVtJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpYXJnJywgJ2FycmFuZ2VyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpYXJ0JywgJ2FydGlzdCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqUFSVCcsICdhcnRpc3QnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnYUFSVCcsICdhbGJ1bUFydGlzdCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdjYXRnJywgJ2NhdGVnb3J5Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpY29tJywgJ2NvbXBvc2VyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpY3B5JywgJ2NvcHlyaWdodCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdjcHJ0JywgJ2NvcHlyaWdodCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWNtdCcsICdjb21tZW50cycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWRheScsICdyZWxlYXNlRGF0ZScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdkZXNjJywgJ2Rlc2NyaXB0aW9uJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpZ2VuJywgJ2dlbnJlJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpZ3JwJywgJ2dyb3VwaW5nJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpaXNyJywgJ0lTUkMnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgna2V5dycsICdrZXl3b3JkcycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWxhYicsICdyZWNvcmRMYWJlbCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdsZGVzJywgJ2xvbmdEZXNjcmlwdGlvbicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWx5cicsICdseXJpY3MnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqluYW0nLCAndGl0bGUnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlwaGcnLCAncmVjb3JkaW5nQ29weXJpZ2h0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpcHJkJywgJ3Byb2R1Y2VyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpcHJmJywgJ3BlcmZvcm1lcnMnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgncHVyZCcsICdwdXJjaGFzZURhdGUnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgncHVybCcsICdwb2RjYXN0VVJMJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8Kpc3dmJywgJ3Nvbmd3cml0ZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwql0b28nLCAnZW5jb2RlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXdydCcsICdjb21wb3NlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdjb3ZyJywgJ2NvdmVyQXJ0JywgZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHRoaXMuc3RyZWFtLnJlYWRCdWZmZXIodGhpcy5sZW4pO1xuICAgIH0pO1xuXG4gICAgZ2VucmVzID0gW1wiQmx1ZXNcIiwgXCJDbGFzc2ljIFJvY2tcIiwgXCJDb3VudHJ5XCIsIFwiRGFuY2VcIiwgXCJEaXNjb1wiLCBcIkZ1bmtcIiwgXCJHcnVuZ2VcIiwgXCJIaXAtSG9wXCIsIFwiSmF6elwiLCBcIk1ldGFsXCIsIFwiTmV3IEFnZVwiLCBcIk9sZGllc1wiLCBcIk90aGVyXCIsIFwiUG9wXCIsIFwiUiZCXCIsIFwiUmFwXCIsIFwiUmVnZ2FlXCIsIFwiUm9ja1wiLCBcIlRlY2hub1wiLCBcIkluZHVzdHJpYWxcIiwgXCJBbHRlcm5hdGl2ZVwiLCBcIlNrYVwiLCBcIkRlYXRoIE1ldGFsXCIsIFwiUHJhbmtzXCIsIFwiU291bmR0cmFja1wiLCBcIkV1cm8tVGVjaG5vXCIsIFwiQW1iaWVudFwiLCBcIlRyaXAtSG9wXCIsIFwiVm9jYWxcIiwgXCJKYXp6K0Z1bmtcIiwgXCJGdXNpb25cIiwgXCJUcmFuY2VcIiwgXCJDbGFzc2ljYWxcIiwgXCJJbnN0cnVtZW50YWxcIiwgXCJBY2lkXCIsIFwiSG91c2VcIiwgXCJHYW1lXCIsIFwiU291bmQgQ2xpcFwiLCBcIkdvc3BlbFwiLCBcIk5vaXNlXCIsIFwiQWx0ZXJuUm9ja1wiLCBcIkJhc3NcIiwgXCJTb3VsXCIsIFwiUHVua1wiLCBcIlNwYWNlXCIsIFwiTWVkaXRhdGl2ZVwiLCBcIkluc3RydW1lbnRhbCBQb3BcIiwgXCJJbnN0cnVtZW50YWwgUm9ja1wiLCBcIkV0aG5pY1wiLCBcIkdvdGhpY1wiLCBcIkRhcmt3YXZlXCIsIFwiVGVjaG5vLUluZHVzdHJpYWxcIiwgXCJFbGVjdHJvbmljXCIsIFwiUG9wLUZvbGtcIiwgXCJFdXJvZGFuY2VcIiwgXCJEcmVhbVwiLCBcIlNvdXRoZXJuIFJvY2tcIiwgXCJDb21lZHlcIiwgXCJDdWx0XCIsIFwiR2FuZ3N0YVwiLCBcIlRvcCA0MFwiLCBcIkNocmlzdGlhbiBSYXBcIiwgXCJQb3AvRnVua1wiLCBcIkp1bmdsZVwiLCBcIk5hdGl2ZSBBbWVyaWNhblwiLCBcIkNhYmFyZXRcIiwgXCJOZXcgV2F2ZVwiLCBcIlBzeWNoYWRlbGljXCIsIFwiUmF2ZVwiLCBcIlNob3d0dW5lc1wiLCBcIlRyYWlsZXJcIiwgXCJMby1GaVwiLCBcIlRyaWJhbFwiLCBcIkFjaWQgUHVua1wiLCBcIkFjaWQgSmF6elwiLCBcIlBvbGthXCIsIFwiUmV0cm9cIiwgXCJNdXNpY2FsXCIsIFwiUm9jayAmIFJvbGxcIiwgXCJIYXJkIFJvY2tcIiwgXCJGb2xrXCIsIFwiRm9say9Sb2NrXCIsIFwiTmF0aW9uYWwgRm9sa1wiLCBcIlN3aW5nXCIsIFwiRmFzdCBGdXNpb25cIiwgXCJCZWJvYlwiLCBcIkxhdGluXCIsIFwiUmV2aXZhbFwiLCBcIkNlbHRpY1wiLCBcIkJsdWVncmFzc1wiLCBcIkF2YW50Z2FyZGVcIiwgXCJHb3RoaWMgUm9ja1wiLCBcIlByb2dyZXNzaXZlIFJvY2tcIiwgXCJQc3ljaGVkZWxpYyBSb2NrXCIsIFwiU3ltcGhvbmljIFJvY2tcIiwgXCJTbG93IFJvY2tcIiwgXCJCaWcgQmFuZFwiLCBcIkNob3J1c1wiLCBcIkVhc3kgTGlzdGVuaW5nXCIsIFwiQWNvdXN0aWNcIiwgXCJIdW1vdXJcIiwgXCJTcGVlY2hcIiwgXCJDaGFuc29uXCIsIFwiT3BlcmFcIiwgXCJDaGFtYmVyIE11c2ljXCIsIFwiU29uYXRhXCIsIFwiU3ltcGhvbnlcIiwgXCJCb290eSBCYXNzXCIsIFwiUHJpbXVzXCIsIFwiUG9ybiBHcm9vdmVcIiwgXCJTYXRpcmVcIiwgXCJTbG93IEphbVwiLCBcIkNsdWJcIiwgXCJUYW5nb1wiLCBcIlNhbWJhXCIsIFwiRm9sa2xvcmVcIiwgXCJCYWxsYWRcIiwgXCJQb3dlciBCYWxsYWRcIiwgXCJSaHl0aG1pYyBTb3VsXCIsIFwiRnJlZXN0eWxlXCIsIFwiRHVldFwiLCBcIlB1bmsgUm9ja1wiLCBcIkRydW0gU29sb1wiLCBcIkEgQ2FwZWxsYVwiLCBcIkV1cm8tSG91c2VcIiwgXCJEYW5jZSBIYWxsXCJdO1xuXG4gICAgbWV0YSgnZ25yZScsICdnZW5yZScsIGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSBnZW5yZXNbdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpIC0gMV07XG4gICAgfSk7XG5cbiAgICBtZXRhKCd0bXBvJywgJ3RlbXBvJywgZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICB9KTtcblxuICAgIG1ldGEoJ3J0bmcnLCAncmF0aW5nJywgZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHZhciByYXRpbmc7XG4gICAgICByYXRpbmcgPSB0aGlzLnN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHJhdGluZyA9PT0gMiA/ICdDbGVhbicgOiByYXRpbmcgIT09IDAgPyAnRXhwbGljaXQnIDogJ05vbmUnO1xuICAgIH0pO1xuXG4gICAgZGlza1RyYWNrID0gZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSArICcgb2YgJyArIHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gNik7XG4gICAgfTtcblxuICAgIG1ldGEoJ2Rpc2snLCAnZGlza051bWJlcicsIGRpc2tUcmFjayk7XG5cbiAgICBtZXRhKCd0cmtuJywgJ3RyYWNrTnVtYmVyJywgZGlza1RyYWNrKTtcblxuICAgIGJvb2wgPSBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQ4KCkgPT09IDE7XG4gICAgfTtcblxuICAgIG1ldGEoJ2NwaWwnLCAnY29tcGlsYXRpb24nLCBib29sKTtcblxuICAgIG1ldGEoJ3Bjc3QnLCAncG9kY2FzdCcsIGJvb2wpO1xuXG4gICAgbWV0YSgncGdhcCcsICdnYXBsZXNzJywgYm9vbCk7XG5cbiAgICByZXR1cm4gTTRBRGVtdXhlcjtcblxuICB9KShEZW11eGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IE00QURlbXV4ZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgRGVtdXhlciwgV0FWRURlbXV4ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi4vZGVtdXhlcicpO1xuXG4gIFdBVkVEZW11eGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgZm9ybWF0cztcblxuICAgIGV4dGVuZChXQVZFRGVtdXhlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBXQVZFRGVtdXhlcigpIHtcbiAgICAgIHJldHVybiBXQVZFRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKFdBVkVEZW11eGVyKTtcblxuICAgIFdBVkVEZW11eGVyLnByb2JlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoMCwgNCkgPT09ICdSSUZGJyAmJiBidWZmZXIucGVla1N0cmluZyg4LCA0KSA9PT0gJ1dBVkUnO1xuICAgIH07XG5cbiAgICBmb3JtYXRzID0ge1xuICAgICAgMHgwMDAxOiAnbHBjbScsXG4gICAgICAweDAwMDM6ICdscGNtJyxcbiAgICAgIDB4MDAwNjogJ2FsYXcnLFxuICAgICAgMHgwMDA3OiAndWxhdydcbiAgICB9O1xuXG4gICAgV0FWRURlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ1ZmZlciwgYnl0ZXMsIGVuY29kaW5nO1xuICAgICAgaWYgKCF0aGlzLnJlYWRTdGFydCAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoMTIpKSB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnUklGRicpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIFdBViBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlsZVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKHRydWUpO1xuICAgICAgICB0aGlzLnJlYWRTdGFydCA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnV0FWRScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIFdBViBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIGlmICghdGhpcy5yZWFkSGVhZGVycyAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgIHRoaXMubGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMih0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ2ZtdCAnOlxuICAgICAgICAgICAgZW5jb2RpbmcgPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KHRydWUpO1xuICAgICAgICAgICAgaWYgKCEoZW5jb2RpbmcgaW4gZm9ybWF0cykpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnVW5zdXBwb3J0ZWQgZm9ybWF0IGluIFdBViBmaWxlLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgICAgIGZvcm1hdElEOiBmb3JtYXRzW2VuY29kaW5nXSxcbiAgICAgICAgICAgICAgZmxvYXRpbmdQb2ludDogZW5jb2RpbmcgPT09IDB4MDAwMyxcbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuOiBmb3JtYXRzW2VuY29kaW5nXSA9PT0gJ2xwY20nLFxuICAgICAgICAgICAgICBjaGFubmVsc1BlckZyYW1lOiB0aGlzLnN0cmVhbS5yZWFkVUludDE2KHRydWUpLFxuICAgICAgICAgICAgICBzYW1wbGVSYXRlOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKHRydWUpLFxuICAgICAgICAgICAgICBmcmFtZXNQZXJQYWNrZXQ6IDFcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNih0cnVlKTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ID0gKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkgKiB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gMTYpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZGF0YSc6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2VudER1cmF0aW9uKSB7XG4gICAgICAgICAgICAgIGJ5dGVzID0gdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4O1xuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2R1cmF0aW9uJywgdGhpcy5sZW4gLyBieXRlcyAvIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWUgLyB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlICogMTAwMCB8IDApO1xuICAgICAgICAgICAgICB0aGlzLnNlbnREdXJhdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidWZmZXIgPSB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMubGVuKTtcbiAgICAgICAgICAgIHRoaXMubGVuIC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gdGhpcy5sZW4gPiAwO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gJ2RhdGEnKSB7XG4gICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBXQVZFRGVtdXhlcjtcblxuICB9KShEZW11eGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBdWRpb0RldmljZSwgRXZlbnRFbWl0dGVyLFxuICAgIGJpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIEF1ZGlvRGV2aWNlID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgZGV2aWNlcztcblxuICAgIGV4dGVuZChBdWRpb0RldmljZSwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBBdWRpb0RldmljZShzYW1wbGVSYXRlMSwgY2hhbm5lbHMxKSB7XG4gICAgICB0aGlzLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlMTtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVsczE7XG4gICAgICB0aGlzLnVwZGF0ZVRpbWUgPSBiaW5kKHRoaXMudXBkYXRlVGltZSwgdGhpcyk7XG4gICAgICB0aGlzLnBsYXlpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY3VycmVudFRpbWUgPSAwO1xuICAgICAgdGhpcy5fbGFzdFRpbWUgPSAwO1xuICAgIH1cblxuICAgIEF1ZGlvRGV2aWNlLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMucGxheWluZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnBsYXlpbmcgPSB0cnVlO1xuICAgICAgaWYgKHRoaXMuZGV2aWNlID09IG51bGwpIHtcbiAgICAgICAgdGhpcy5kZXZpY2UgPSBBdWRpb0RldmljZS5jcmVhdGUodGhpcy5zYW1wbGVSYXRlLCB0aGlzLmNoYW5uZWxzKTtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5kZXZpY2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gc3VwcG9ydGVkIGF1ZGlvIGRldmljZSBmb3VuZC5cIik7XG4gICAgICB9XG4gICAgICB0aGlzLl9sYXN0VGltZSA9IHRoaXMuZGV2aWNlLmdldERldmljZVRpbWUoKTtcbiAgICAgIHRoaXMuX3RpbWVyID0gc2V0SW50ZXJ2YWwodGhpcy51cGRhdGVUaW1lLCAyMDApO1xuICAgICAgcmV0dXJuIHRoaXMuZGV2aWNlLm9uKCdyZWZpbGwnLCB0aGlzLnJlZmlsbCA9IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ3JlZmlsbCcsIGJ1ZmZlcik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgfTtcblxuICAgIEF1ZGlvRGV2aWNlLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIXRoaXMucGxheWluZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnBsYXlpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuZGV2aWNlLm9mZigncmVmaWxsJywgdGhpcy5yZWZpbGwpO1xuICAgICAgcmV0dXJuIGNsZWFySW50ZXJ2YWwodGhpcy5fdGltZXIpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgcmV0dXJuIChyZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCA/IHJlZi5kZXN0cm95KCkgOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIEF1ZGlvRGV2aWNlLnByb3RvdHlwZS5zZWVrID0gZnVuY3Rpb24oY3VycmVudFRpbWUpIHtcbiAgICAgIHRoaXMuY3VycmVudFRpbWUgPSBjdXJyZW50VGltZTtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgdGhpcy5fbGFzdFRpbWUgPSB0aGlzLmRldmljZS5nZXREZXZpY2VUaW1lKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5lbWl0KCd0aW1lVXBkYXRlJywgdGhpcy5jdXJyZW50VGltZSk7XG4gICAgfTtcblxuICAgIEF1ZGlvRGV2aWNlLnByb3RvdHlwZS51cGRhdGVUaW1lID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgdGltZTtcbiAgICAgIHRpbWUgPSB0aGlzLmRldmljZS5nZXREZXZpY2VUaW1lKCk7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lICs9ICh0aW1lIC0gdGhpcy5fbGFzdFRpbWUpIC8gdGhpcy5kZXZpY2Uuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwO1xuICAgICAgdGhpcy5fbGFzdFRpbWUgPSB0aW1lO1xuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgndGltZVVwZGF0ZScsIHRoaXMuY3VycmVudFRpbWUpO1xuICAgIH07XG5cbiAgICBkZXZpY2VzID0gW107XG5cbiAgICBBdWRpb0RldmljZS5yZWdpc3RlciA9IGZ1bmN0aW9uKGRldmljZSkge1xuICAgICAgcmV0dXJuIGRldmljZXMucHVzaChkZXZpY2UpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5jcmVhdGUgPSBmdW5jdGlvbihzYW1wbGVSYXRlLCBjaGFubmVscykge1xuICAgICAgdmFyIGRldmljZSwgaSwgbGVuO1xuICAgICAgZm9yIChpID0gMCwgbGVuID0gZGV2aWNlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBkZXZpY2UgPSBkZXZpY2VzW2ldO1xuICAgICAgICBpZiAoZGV2aWNlLnN1cHBvcnRlZCkge1xuICAgICAgICAgIHJldHVybiBuZXcgZGV2aWNlKHNhbXBsZVJhdGUsIGNoYW5uZWxzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIHJldHVybiBBdWRpb0RldmljZTtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQXVkaW9EZXZpY2U7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQVZCdWZmZXIsIEF1ZGlvRGV2aWNlLCBFdmVudEVtaXR0ZXIsIE1vemlsbGFBdWRpb0RldmljZSxcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4uL2NvcmUvZXZlbnRzJyk7XG5cbiAgQXVkaW9EZXZpY2UgPSByZXF1aXJlKCcuLi9kZXZpY2UnKTtcblxuICBBVkJ1ZmZlciA9IHJlcXVpcmUoJy4uL2NvcmUvYnVmZmVyJyk7XG5cbiAgTW96aWxsYUF1ZGlvRGV2aWNlID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgY3JlYXRlVGltZXIsIGRlc3Ryb3lUaW1lcjtcblxuICAgIGV4dGVuZChNb3ppbGxhQXVkaW9EZXZpY2UsIHN1cGVyQ2xhc3MpO1xuXG4gICAgQXVkaW9EZXZpY2UucmVnaXN0ZXIoTW96aWxsYUF1ZGlvRGV2aWNlKTtcblxuICAgIE1vemlsbGFBdWRpb0RldmljZS5zdXBwb3J0ZWQgPSAodHlwZW9mIEF1ZGlvICE9PSBcInVuZGVmaW5lZFwiICYmIEF1ZGlvICE9PSBudWxsKSAmJiAnbW96V3JpdGVBdWRpbycgaW4gbmV3IEF1ZGlvO1xuXG4gICAgZnVuY3Rpb24gTW96aWxsYUF1ZGlvRGV2aWNlKHNhbXBsZVJhdGUsIGNoYW5uZWxzKSB7XG4gICAgICB0aGlzLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlO1xuICAgICAgdGhpcy5jaGFubmVscyA9IGNoYW5uZWxzO1xuICAgICAgdGhpcy5yZWZpbGwgPSBiaW5kKHRoaXMucmVmaWxsLCB0aGlzKTtcbiAgICAgIHRoaXMuYXVkaW8gPSBuZXcgQXVkaW87XG4gICAgICB0aGlzLmF1ZGlvLm1velNldHVwKHRoaXMuY2hhbm5lbHMsIHRoaXMuc2FtcGxlUmF0ZSk7XG4gICAgICB0aGlzLndyaXRlUG9zaXRpb24gPSAwO1xuICAgICAgdGhpcy5wcmVidWZmZXJTaXplID0gdGhpcy5zYW1wbGVSYXRlIC8gMjtcbiAgICAgIHRoaXMudGFpbCA9IG51bGw7XG4gICAgICB0aGlzLnRpbWVyID0gY3JlYXRlVGltZXIodGhpcy5yZWZpbGwsIDEwMCk7XG4gICAgfVxuXG4gICAgTW96aWxsYUF1ZGlvRGV2aWNlLnByb3RvdHlwZS5yZWZpbGwgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhdmFpbGFibGUsIGJ1ZmZlciwgY3VycmVudFBvc2l0aW9uLCB3cml0dGVuO1xuICAgICAgaWYgKHRoaXMudGFpbCkge1xuICAgICAgICB3cml0dGVuID0gdGhpcy5hdWRpby5tb3pXcml0ZUF1ZGlvKHRoaXMudGFpbCk7XG4gICAgICAgIHRoaXMud3JpdGVQb3NpdGlvbiArPSB3cml0dGVuO1xuICAgICAgICBpZiAodGhpcy53cml0ZVBvc2l0aW9uIDwgdGhpcy50YWlsLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMudGFpbCA9IHRoaXMudGFpbC5zdWJhcnJheSh3cml0dGVuKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnRhaWwgPSBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjdXJyZW50UG9zaXRpb24gPSB0aGlzLmF1ZGlvLm1vekN1cnJlbnRTYW1wbGVPZmZzZXQoKTtcbiAgICAgIGF2YWlsYWJsZSA9IGN1cnJlbnRQb3NpdGlvbiArIHRoaXMucHJlYnVmZmVyU2l6ZSAtIHRoaXMud3JpdGVQb3NpdGlvbjtcbiAgICAgIGlmIChhdmFpbGFibGUgPiAwKSB7XG4gICAgICAgIGJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYXZhaWxhYmxlKTtcbiAgICAgICAgdGhpcy5lbWl0KCdyZWZpbGwnLCBidWZmZXIpO1xuICAgICAgICB3cml0dGVuID0gdGhpcy5hdWRpby5tb3pXcml0ZUF1ZGlvKGJ1ZmZlcik7XG4gICAgICAgIGlmICh3cml0dGVuIDwgYnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMudGFpbCA9IGJ1ZmZlci5zdWJhcnJheSh3cml0dGVuKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLndyaXRlUG9zaXRpb24gKz0gd3JpdHRlbjtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgTW96aWxsYUF1ZGlvRGV2aWNlLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZGVzdHJveVRpbWVyKHRoaXMudGltZXIpO1xuICAgIH07XG5cbiAgICBNb3ppbGxhQXVkaW9EZXZpY2UucHJvdG90eXBlLmdldERldmljZVRpbWUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmF1ZGlvLm1vekN1cnJlbnRTYW1wbGVPZmZzZXQoKSAvIHRoaXMuY2hhbm5lbHM7XG4gICAgfTtcblxuICAgIGNyZWF0ZVRpbWVyID0gZnVuY3Rpb24oZm4sIGludGVydmFsKSB7XG4gICAgICB2YXIgdXJsLCB3b3JrZXI7XG4gICAgICB1cmwgPSBBVkJ1ZmZlci5tYWtlQmxvYlVSTChcInNldEludGVydmFsKGZ1bmN0aW9uKCkgeyBwb3N0TWVzc2FnZSgncGluZycpOyB9LCBcIiArIGludGVydmFsICsgXCIpO1wiKTtcbiAgICAgIGlmICh1cmwgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gc2V0SW50ZXJ2YWwoZm4sIGludGVydmFsKTtcbiAgICAgIH1cbiAgICAgIHdvcmtlciA9IG5ldyBXb3JrZXIodXJsKTtcbiAgICAgIHdvcmtlci5vbm1lc3NhZ2UgPSBmbjtcbiAgICAgIHdvcmtlci51cmwgPSB1cmw7XG4gICAgICByZXR1cm4gd29ya2VyO1xuICAgIH07XG5cbiAgICBkZXN0cm95VGltZXIgPSBmdW5jdGlvbih0aW1lcikge1xuICAgICAgaWYgKHRpbWVyLnRlcm1pbmF0ZSkge1xuICAgICAgICB0aW1lci50ZXJtaW5hdGUoKTtcbiAgICAgICAgcmV0dXJuIFVSTC5yZXZva2VPYmplY3RVUkwodGltZXIudXJsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBjbGVhckludGVydmFsKHRpbWVyKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIE1vemlsbGFBdWRpb0RldmljZTtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy9KYXZhU2NyaXB0IEF1ZGlvIFJlc2FtcGxlclxuLy9Db3B5cmlnaHQgKEMpIDIwMTEtMjAxNSBHcmFudCBHYWxpdHpcbi8vUmVsZWFzZWQgdG8gUHVibGljIERvbWFpblxuZnVuY3Rpb24gUmVzYW1wbGVyKGZyb21TYW1wbGVSYXRlLCB0b1NhbXBsZVJhdGUsIGNoYW5uZWxzLCBpbnB1dEJ1ZmZlckxlbmd0aCkge1xuICB0aGlzLmZyb21TYW1wbGVSYXRlID0gK2Zyb21TYW1wbGVSYXRlO1xuICB0aGlzLnRvU2FtcGxlUmF0ZSA9ICt0b1NhbXBsZVJhdGU7XG4gIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVscyB8IDA7XG4gIHRoaXMuaW5wdXRCdWZmZXJMZW5ndGggPSBpbnB1dEJ1ZmZlckxlbmd0aDtcbiAgdGhpcy5pbml0aWFsaXplKCk7XG59XG5cblJlc2FtcGxlci5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgLy9QZXJmb3JtIHNvbWUgY2hlY2tzOlxuICBpZiAodGhpcy5mcm9tU2FtcGxlUmF0ZSA+IDAgJiYgdGhpcy50b1NhbXBsZVJhdGUgPiAwICYmIHRoaXMuY2hhbm5lbHMgPiAwKSB7XG4gICAgaWYgKHRoaXMuZnJvbVNhbXBsZVJhdGUgPT0gdGhpcy50b1NhbXBsZVJhdGUpIHtcbiAgICAgIC8vU2V0dXAgYSByZXNhbXBsZXIgYnlwYXNzOlxuICAgICAgdGhpcy5yZXNhbXBsZXIgPSB0aGlzLmJ5cGFzc1Jlc2FtcGxlcjsgICAgLy9SZXNhbXBsZXIganVzdCByZXR1cm5zIHdoYXQgd2FzIHBhc3NlZCB0aHJvdWdoLlxuICAgICAgdGhpcy5yYXRpb1dlaWdodCA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmF0aW9XZWlnaHQgPSB0aGlzLmZyb21TYW1wbGVSYXRlIC8gdGhpcy50b1NhbXBsZVJhdGU7XG4gICAgICBpZiAodGhpcy5mcm9tU2FtcGxlUmF0ZSA8IHRoaXMudG9TYW1wbGVSYXRlKSB7XG4gICAgICAgIC8qXG4gICAgICAgICAgVXNlIGdlbmVyaWMgbGluZWFyIGludGVycG9sYXRpb24gaWYgdXBzYW1wbGluZyxcbiAgICAgICAgICBhcyBsaW5lYXIgaW50ZXJwb2xhdGlvbiBwcm9kdWNlcyBhIGdyYWRpZW50IHRoYXQgd2Ugd2FudFxuICAgICAgICAgIGFuZCB3b3JrcyBmaW5lIHdpdGggdHdvIGlucHV0IHNhbXBsZSBwb2ludHMgcGVyIG91dHB1dCBpbiB0aGlzIGNhc2UuXG4gICAgICAgICovXG4gICAgICAgIHRoaXMuY29tcGlsZUxpbmVhckludGVycG9sYXRpb25GdW5jdGlvbigpO1xuICAgICAgICB0aGlzLmxhc3RXZWlnaHQgPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLypcbiAgICAgICAgICBDdXN0b20gcmVzYW1wbGVyIEkgd3JvdGUgdGhhdCBkb2Vzbid0IHNraXAgc2FtcGxlc1xuICAgICAgICAgIGxpa2Ugc3RhbmRhcmQgbGluZWFyIGludGVycG9sYXRpb24gaW4gaGlnaCBkb3duc2FtcGxpbmcuXG4gICAgICAgICAgVGhpcyBpcyBtb3JlIGFjY3VyYXRlIHRoYW4gbGluZWFyIGludGVycG9sYXRpb24gb24gZG93bnNhbXBsaW5nLlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLmNvbXBpbGVNdWx0aVRhcEZ1bmN0aW9uKCk7XG4gICAgICAgIHRoaXMudGFpbEV4aXN0cyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmxhc3RXZWlnaHQgPSAwO1xuICAgICAgfVxuICAgICAgXG4gICAgICB2YXIgb3V0cHV0QnVmZmVyU2l6ZSA9IChNYXRoLmNlaWwodGhpcy5pbnB1dEJ1ZmZlckxlbmd0aCAqIHRoaXMudG9TYW1wbGVSYXRlIC8gdGhpcy5mcm9tU2FtcGxlUmF0ZSAvIHRoaXMuY2hhbm5lbHMgKiAxLjAxKSAqIHRoaXMuY2hhbm5lbHMpICsgdGhpcy5jaGFubmVscztcbiAgICAgIHRoaXMub3V0cHV0QnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShvdXRwdXRCdWZmZXJTaXplKTtcbiAgICAgIHRoaXMubGFzdE91dHB1dCA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5jaGFubmVscyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93KG5ldyBFcnJvcihcIkludmFsaWQgc2V0dGluZ3Mgc3BlY2lmaWVkIGZvciB0aGUgcmVzYW1wbGVyLlwiKSk7XG4gIH1cbn07XG5cblJlc2FtcGxlci5wcm90b3R5cGUuY29tcGlsZUxpbmVhckludGVycG9sYXRpb25GdW5jdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRvQ29tcGlsZSA9IFwidmFyIG91dHB1dE9mZnNldCA9IDA7XFxcbiAgICB2YXIgYnVmZmVyTGVuZ3RoID0gYnVmZmVyLmxlbmd0aDtcXFxuICAgIGlmIChidWZmZXJMZW5ndGggPiAwKSB7XFxcbiAgICAgIHZhciB3ZWlnaHQgPSB0aGlzLmxhc3RXZWlnaHQ7XFxcbiAgICAgIHZhciBmaXJzdFdlaWdodCA9IDA7XFxcbiAgICAgIHZhciBzZWNvbmRXZWlnaHQgPSAwO1xcXG4gICAgICB2YXIgc291cmNlT2Zmc2V0ID0gMDtcXFxuICAgICAgdmFyIG91dHB1dE9mZnNldCA9IDA7XFxcbiAgICAgIHZhciBvdXRwdXRCdWZmZXIgPSB0aGlzLm91dHB1dEJ1ZmZlcjtcXFxuICAgICAgZm9yICg7IHdlaWdodCA8IDE7IHdlaWdodCArPSBcIiArIHRoaXMucmF0aW9XZWlnaHQgKyBcIikge1xcXG4gICAgICAgIHNlY29uZFdlaWdodCA9IHdlaWdodCAlIDE7XFxcbiAgICAgICAgZmlyc3RXZWlnaHQgPSAxIC0gc2Vjb25kV2VpZ2h0O1wiO1xuICAgICAgICBmb3IgKHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dEJ1ZmZlcltvdXRwdXRPZmZzZXQrK10gPSAodGhpcy5sYXN0T3V0cHV0W1wiICsgY2hhbm5lbCArIFwiXSAqIGZpcnN0V2VpZ2h0KSArIChidWZmZXJbXCIgKyBjaGFubmVsICsgXCJdICogc2Vjb25kV2VpZ2h0KTtcIjtcbiAgICAgICAgfVxuICAgICAgdG9Db21waWxlICs9IFwifVxcXG4gICAgICB3ZWlnaHQgLT0gMTtcXFxuICAgICAgZm9yIChidWZmZXJMZW5ndGggLT0gXCIgKyB0aGlzLmNoYW5uZWxzICsgXCIsIHNvdXJjZU9mZnNldCA9IE1hdGguZmxvb3Iod2VpZ2h0KSAqIFwiICsgdGhpcy5jaGFubmVscyArIFwiOyBzb3VyY2VPZmZzZXQgPCBidWZmZXJMZW5ndGg7KSB7XFxcbiAgICAgICAgc2Vjb25kV2VpZ2h0ID0gd2VpZ2h0ICUgMTtcXFxuICAgICAgICBmaXJzdFdlaWdodCA9IDEgLSBzZWNvbmRXZWlnaHQ7XCI7XG4gICAgICAgIGZvciAodmFyIGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0QnVmZmVyW291dHB1dE9mZnNldCsrXSA9IChidWZmZXJbc291cmNlT2Zmc2V0XCIgKyAoKGNoYW5uZWwgPiAwKSA/IChcIiArIFwiICsgY2hhbm5lbCkgOiBcIlwiKSArIFwiXSAqIGZpcnN0V2VpZ2h0KSArIChidWZmZXJbc291cmNlT2Zmc2V0ICsgXCIgKyAodGhpcy5jaGFubmVscyArIGNoYW5uZWwpICsgXCJdICogc2Vjb25kV2VpZ2h0KTtcIjtcbiAgICAgICAgfVxuICAgICAgICB0b0NvbXBpbGUgKz0gXCJ3ZWlnaHQgKz0gXCIgKyB0aGlzLnJhdGlvV2VpZ2h0ICsgXCI7XFxcbiAgICAgICAgc291cmNlT2Zmc2V0ID0gTWF0aC5mbG9vcih3ZWlnaHQpICogXCIgKyB0aGlzLmNoYW5uZWxzICsgXCI7XFxcbiAgICAgIH1cIjtcbiAgICAgIGZvciAodmFyIGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgIHRvQ29tcGlsZSArPSBcInRoaXMubGFzdE91dHB1dFtcIiArIGNoYW5uZWwgKyBcIl0gPSBidWZmZXJbc291cmNlT2Zmc2V0KytdO1wiO1xuICAgICAgfVxuICAgICAgdG9Db21waWxlICs9IFwidGhpcy5sYXN0V2VpZ2h0ID0gd2VpZ2h0ICUgMTtcXFxuICAgIH1cXFxuICAgIHJldHVybiB0aGlzLm91dHB1dEJ1ZmZlcjtcIjtcbiAgICBcbiAgdGhpcy5yZXNhbXBsZXIgPSBGdW5jdGlvbihcImJ1ZmZlclwiLCB0b0NvbXBpbGUpO1xufTtcblxuUmVzYW1wbGVyLnByb3RvdHlwZS5jb21waWxlTXVsdGlUYXBGdW5jdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRvQ29tcGlsZSA9IFwidmFyIG91dHB1dE9mZnNldCA9IDA7XFxcbiAgICB2YXIgYnVmZmVyTGVuZ3RoID0gYnVmZmVyLmxlbmd0aDtcXFxuICAgIGlmIChidWZmZXJMZW5ndGggPiAwKSB7XFxcbiAgICAgIHZhciB3ZWlnaHQgPSAwO1wiO1xuICAgICAgZm9yICh2YXIgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgdG9Db21waWxlICs9IFwidmFyIG91dHB1dFwiICsgY2hhbm5lbCArIFwiID0gMDtcIlxuICAgICAgfVxuICAgICAgdG9Db21waWxlICs9IFwidmFyIGFjdHVhbFBvc2l0aW9uID0gMDtcXFxuICAgICAgdmFyIGFtb3VudFRvTmV4dCA9IDA7XFxcbiAgICAgIHZhciBhbHJlYWR5UHJvY2Vzc2VkVGFpbCA9ICF0aGlzLnRhaWxFeGlzdHM7XFxcbiAgICAgIHRoaXMudGFpbEV4aXN0cyA9IGZhbHNlO1xcXG4gICAgICB2YXIgb3V0cHV0QnVmZmVyID0gdGhpcy5vdXRwdXRCdWZmZXI7XFxcbiAgICAgIHZhciBjdXJyZW50UG9zaXRpb24gPSAwO1xcXG4gICAgICBkbyB7XFxcbiAgICAgICAgaWYgKGFscmVhZHlQcm9jZXNzZWRUYWlsKSB7XFxcbiAgICAgICAgICB3ZWlnaHQgPSBcIiArIHRoaXMucmF0aW9XZWlnaHQgKyBcIjtcIjtcbiAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiA9IDA7XCJcbiAgICAgICAgICB9XG4gICAgICAgIHRvQ29tcGlsZSArPSBcIn1cXFxuICAgICAgICBlbHNlIHtcXFxuICAgICAgICAgIHdlaWdodCA9IHRoaXMubGFzdFdlaWdodDtcIjtcbiAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiA9IHRoaXMubGFzdE91dHB1dFtcIiArIGNoYW5uZWwgKyBcIl07XCJcbiAgICAgICAgICB9XG4gICAgICAgICAgdG9Db21waWxlICs9IFwiYWxyZWFkeVByb2Nlc3NlZFRhaWwgPSB0cnVlO1xcXG4gICAgICAgIH1cXFxuICAgICAgICB3aGlsZSAod2VpZ2h0ID4gMCAmJiBhY3R1YWxQb3NpdGlvbiA8IGJ1ZmZlckxlbmd0aCkge1xcXG4gICAgICAgICAgYW1vdW50VG9OZXh0ID0gMSArIGFjdHVhbFBvc2l0aW9uIC0gY3VycmVudFBvc2l0aW9uO1xcXG4gICAgICAgICAgaWYgKHdlaWdodCA+PSBhbW91bnRUb05leHQpIHtcIjtcbiAgICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0XCIgKyBjaGFubmVsICsgXCIgKz0gYnVmZmVyW2FjdHVhbFBvc2l0aW9uKytdICogYW1vdW50VG9OZXh0O1wiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJjdXJyZW50UG9zaXRpb24gPSBhY3R1YWxQb3NpdGlvbjtcXFxuICAgICAgICAgICAgd2VpZ2h0IC09IGFtb3VudFRvTmV4dDtcXFxuICAgICAgICAgIH1cXFxuICAgICAgICAgIGVsc2Uge1wiO1xuICAgICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiArPSBidWZmZXJbYWN0dWFsUG9zaXRpb25cIiArICgoY2hhbm5lbCA+IDApID8gKFwiICsgXCIgKyBjaGFubmVsKSA6IFwiXCIpICsgXCJdICogd2VpZ2h0O1wiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJjdXJyZW50UG9zaXRpb24gKz0gd2VpZ2h0O1xcXG4gICAgICAgICAgICB3ZWlnaHQgPSAwO1xcXG4gICAgICAgICAgICBicmVhaztcXFxuICAgICAgICAgIH1cXFxuICAgICAgICB9XFxcbiAgICAgICAgaWYgKHdlaWdodCA8PSAwKSB7XCI7XG4gICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0QnVmZmVyW291dHB1dE9mZnNldCsrXSA9IG91dHB1dFwiICsgY2hhbm5lbCArIFwiIC8gXCIgKyB0aGlzLnJhdGlvV2VpZ2h0ICsgXCI7XCJcbiAgICAgICAgICB9XG4gICAgICAgIHRvQ29tcGlsZSArPSBcIn1cXFxuICAgICAgICBlbHNlIHtcXFxuICAgICAgICAgIHRoaXMubGFzdFdlaWdodCA9IHdlaWdodDtcIjtcbiAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJ0aGlzLmxhc3RPdXRwdXRbXCIgKyBjaGFubmVsICsgXCJdID0gb3V0cHV0XCIgKyBjaGFubmVsICsgXCI7XCJcbiAgICAgICAgICB9XG4gICAgICAgICAgdG9Db21waWxlICs9IFwidGhpcy50YWlsRXhpc3RzID0gdHJ1ZTtcXFxuICAgICAgICAgIGJyZWFrO1xcXG4gICAgICAgIH1cXFxuICAgICAgfSB3aGlsZSAoYWN0dWFsUG9zaXRpb24gPCBidWZmZXJMZW5ndGgpO1xcXG4gICAgfVxcXG4gICAgcmV0dXJuIHRoaXMub3V0cHV0QnVmZmVyO1wiO1xuICBcbiAgdGhpcy5yZXNhbXBsZXIgPSBGdW5jdGlvbihcImJ1ZmZlclwiLCB0b0NvbXBpbGUpO1xufTtcblxuUmVzYW1wbGVyLnByb3RvdHlwZS5ieXBhc3NSZXNhbXBsZXIgPSBmdW5jdGlvbiAoaW5wdXRCdWZmZXIpIHtcbiAgcmV0dXJuIGlucHV0QnVmZmVyO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZXNhbXBsZXI7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQXVkaW9EZXZpY2UsIEV2ZW50RW1pdHRlciwgUmVzYW1wbGVyLCBXZWJBdWRpb0RldmljZSxcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4uL2NvcmUvZXZlbnRzJyk7XG5cbiAgQXVkaW9EZXZpY2UgPSByZXF1aXJlKCcuLi9kZXZpY2UnKTtcblxuICBSZXNhbXBsZXIgPSByZXF1aXJlKCcuL3Jlc2FtcGxlcicpO1xuXG4gIFdlYkF1ZGlvRGV2aWNlID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgQXVkaW9Db250ZXh0LCBjcmVhdGVQcm9jZXNzb3IsIHNoYXJlZENvbnRleHQ7XG5cbiAgICBleHRlbmQoV2ViQXVkaW9EZXZpY2UsIHN1cGVyQ2xhc3MpO1xuXG4gICAgQXVkaW9EZXZpY2UucmVnaXN0ZXIoV2ViQXVkaW9EZXZpY2UpO1xuXG4gICAgQXVkaW9Db250ZXh0ID0gZ2xvYmFsLkF1ZGlvQ29udGV4dCB8fCBnbG9iYWwud2Via2l0QXVkaW9Db250ZXh0O1xuXG4gICAgV2ViQXVkaW9EZXZpY2Uuc3VwcG9ydGVkID0gQXVkaW9Db250ZXh0ICYmICh0eXBlb2YgQXVkaW9Db250ZXh0LnByb3RvdHlwZVtjcmVhdGVQcm9jZXNzb3IgPSAnY3JlYXRlU2NyaXB0UHJvY2Vzc29yJ10gPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIEF1ZGlvQ29udGV4dC5wcm90b3R5cGVbY3JlYXRlUHJvY2Vzc29yID0gJ2NyZWF0ZUphdmFTY3JpcHROb2RlJ10gPT09ICdmdW5jdGlvbicpO1xuXG4gICAgc2hhcmVkQ29udGV4dCA9IG51bGw7XG5cbiAgICBmdW5jdGlvbiBXZWJBdWRpb0RldmljZShzYW1wbGVSYXRlLCBjaGFubmVsczEpIHtcbiAgICAgIHRoaXMuc2FtcGxlUmF0ZSA9IHNhbXBsZVJhdGU7XG4gICAgICB0aGlzLmNoYW5uZWxzID0gY2hhbm5lbHMxO1xuICAgICAgdGhpcy5yZWZpbGwgPSBiaW5kKHRoaXMucmVmaWxsLCB0aGlzKTtcbiAgICAgIHRoaXMuY29udGV4dCA9IHNoYXJlZENvbnRleHQgIT0gbnVsbCA/IHNoYXJlZENvbnRleHQgOiBzaGFyZWRDb250ZXh0ID0gbmV3IEF1ZGlvQ29udGV4dDtcbiAgICAgIHRoaXMuZGV2aWNlU2FtcGxlUmF0ZSA9IHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgdGhpcy5idWZmZXJTaXplID0gTWF0aC5jZWlsKDQwOTYgLyAodGhpcy5kZXZpY2VTYW1wbGVSYXRlIC8gdGhpcy5zYW1wbGVSYXRlKSAqIHRoaXMuY2hhbm5lbHMpO1xuICAgICAgdGhpcy5idWZmZXJTaXplICs9IHRoaXMuYnVmZmVyU2l6ZSAlIHRoaXMuY2hhbm5lbHM7XG4gICAgICBpZiAodGhpcy5kZXZpY2VTYW1wbGVSYXRlICE9PSB0aGlzLnNhbXBsZVJhdGUpIHtcbiAgICAgICAgdGhpcy5yZXNhbXBsZXIgPSBuZXcgUmVzYW1wbGVyKHRoaXMuc2FtcGxlUmF0ZSwgdGhpcy5kZXZpY2VTYW1wbGVSYXRlLCB0aGlzLmNoYW5uZWxzLCB0aGlzLmJ1ZmZlclNpemUpO1xuICAgICAgfVxuICAgICAgdGhpcy5ub2RlID0gdGhpcy5jb250ZXh0W2NyZWF0ZVByb2Nlc3Nvcl0oNDA5NiwgdGhpcy5jaGFubmVscywgdGhpcy5jaGFubmVscyk7XG4gICAgICB0aGlzLm5vZGUub25hdWRpb3Byb2Nlc3MgPSB0aGlzLnJlZmlsbDtcbiAgICAgIHRoaXMubm9kZS5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgfVxuXG4gICAgV2ViQXVkaW9EZXZpY2UucHJvdG90eXBlLnJlZmlsbCA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICB2YXIgY2hhbm5lbENvdW50LCBjaGFubmVscywgZGF0YSwgaSwgaiwgaywgbCwgbiwgb3V0cHV0QnVmZmVyLCByZWYsIHJlZjEsIHJlZjI7XG4gICAgICBvdXRwdXRCdWZmZXIgPSBldmVudC5vdXRwdXRCdWZmZXI7XG4gICAgICBjaGFubmVsQ291bnQgPSBvdXRwdXRCdWZmZXIubnVtYmVyT2ZDaGFubmVscztcbiAgICAgIGNoYW5uZWxzID0gbmV3IEFycmF5KGNoYW5uZWxDb3VudCk7XG4gICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gY2hhbm5lbENvdW50OyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgIGNoYW5uZWxzW2ldID0gb3V0cHV0QnVmZmVyLmdldENoYW5uZWxEYXRhKGkpO1xuICAgICAgfVxuICAgICAgZGF0YSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5idWZmZXJTaXplKTtcbiAgICAgIHRoaXMuZW1pdCgncmVmaWxsJywgZGF0YSk7XG4gICAgICBpZiAodGhpcy5yZXNhbXBsZXIpIHtcbiAgICAgICAgZGF0YSA9IHRoaXMucmVzYW1wbGVyLnJlc2FtcGxlcihkYXRhKTtcbiAgICAgIH1cbiAgICAgIGZvciAoaSA9IGsgPSAwLCByZWYxID0gb3V0cHV0QnVmZmVyLmxlbmd0aDsgayA8IHJlZjE7IGkgPSBrICs9IDEpIHtcbiAgICAgICAgZm9yIChuID0gbCA9IDAsIHJlZjIgPSBjaGFubmVsQ291bnQ7IGwgPCByZWYyOyBuID0gbCArPSAxKSB7XG4gICAgICAgICAgY2hhbm5lbHNbbl1baV0gPSBkYXRhW2kgKiBjaGFubmVsQ291bnQgKyBuXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBXZWJBdWRpb0RldmljZS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMubm9kZS5kaXNjb25uZWN0KDApO1xuICAgIH07XG5cbiAgICBXZWJBdWRpb0RldmljZS5wcm90b3R5cGUuZ2V0RGV2aWNlVGltZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSAqIHRoaXMuc2FtcGxlUmF0ZTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFdlYkF1ZGlvRGV2aWNlO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgRmlsdGVyO1xuXG4gIEZpbHRlciA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBGaWx0ZXIoY29udGV4dCwga2V5KSB7XG4gICAgICBpZiAoY29udGV4dCAmJiBrZXkpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd2YWx1ZScsIHtcbiAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHRba2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIEZpbHRlci5wcm90b3R5cGUucHJvY2VzcyA9IGZ1bmN0aW9uKGJ1ZmZlcikge307XG5cbiAgICByZXR1cm4gRmlsdGVyO1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBGaWx0ZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQmFsYW5jZUZpbHRlciwgRmlsdGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRmlsdGVyID0gcmVxdWlyZSgnLi4vZmlsdGVyJyk7XG5cbiAgQmFsYW5jZUZpbHRlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKEJhbGFuY2VGaWx0ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gQmFsYW5jZUZpbHRlcigpIHtcbiAgICAgIHJldHVybiBCYWxhbmNlRmlsdGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIEJhbGFuY2VGaWx0ZXIucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciBpLCBqLCBwYW4sIHJlZjtcbiAgICAgIGlmICh0aGlzLnZhbHVlID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHBhbiA9IE1hdGgubWF4KC01MCwgTWF0aC5taW4oNTAsIHRoaXMudmFsdWUpKTtcbiAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBidWZmZXIubGVuZ3RoOyBqIDwgcmVmOyBpID0gaiArPSAyKSB7XG4gICAgICAgIGJ1ZmZlcltpXSAqPSBNYXRoLm1pbigxLCAoNTAgLSBwYW4pIC8gNTApO1xuICAgICAgICBidWZmZXJbaSArIDFdICo9IE1hdGgubWluKDEsICg1MCArIHBhbikgLyA1MCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBCYWxhbmNlRmlsdGVyO1xuXG4gIH0pKEZpbHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBCYWxhbmNlRmlsdGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEZpbHRlciwgVm9sdW1lRmlsdGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRmlsdGVyID0gcmVxdWlyZSgnLi4vZmlsdGVyJyk7XG5cbiAgVm9sdW1lRmlsdGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoVm9sdW1lRmlsdGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIFZvbHVtZUZpbHRlcigpIHtcbiAgICAgIHJldHVybiBWb2x1bWVGaWx0ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgVm9sdW1lRmlsdGVyLnByb3RvdHlwZS5wcm9jZXNzID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgaSwgaiwgcmVmLCB2b2w7XG4gICAgICBpZiAodGhpcy52YWx1ZSA+PSAxMDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdm9sID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMTAwLCB0aGlzLnZhbHVlKSkgLyAxMDA7XG4gICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gYnVmZmVyLmxlbmd0aDsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICBidWZmZXJbaV0gKj0gdm9sO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gVm9sdW1lRmlsdGVyO1xuXG4gIH0pKEZpbHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBWb2x1bWVGaWx0ZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQXNzZXQsIEF1ZGlvRGV2aWNlLCBCYWxhbmNlRmlsdGVyLCBFdmVudEVtaXR0ZXIsIFBsYXllciwgUXVldWUsIFZvbHVtZUZpbHRlcixcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vY29yZS9ldmVudHMnKTtcblxuICBBc3NldCA9IHJlcXVpcmUoJy4vYXNzZXQnKTtcblxuICBWb2x1bWVGaWx0ZXIgPSByZXF1aXJlKCcuL2ZpbHRlcnMvdm9sdW1lJyk7XG5cbiAgQmFsYW5jZUZpbHRlciA9IHJlcXVpcmUoJy4vZmlsdGVycy9iYWxhbmNlJyk7XG5cbiAgUXVldWUgPSByZXF1aXJlKCcuL3F1ZXVlJyk7XG5cbiAgQXVkaW9EZXZpY2UgPSByZXF1aXJlKCcuL2RldmljZScpO1xuXG4gIFBsYXllciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFBsYXllciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBQbGF5ZXIoYXNzZXQpIHtcbiAgICAgIHRoaXMuYXNzZXQgPSBhc3NldDtcbiAgICAgIHRoaXMuc3RhcnRQbGF5aW5nID0gYmluZCh0aGlzLnN0YXJ0UGxheWluZywgdGhpcyk7XG4gICAgICB0aGlzLnBsYXlpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuYnVmZmVyZWQgPSAwO1xuICAgICAgdGhpcy5jdXJyZW50VGltZSA9IDA7XG4gICAgICB0aGlzLmR1cmF0aW9uID0gMDtcbiAgICAgIHRoaXMudm9sdW1lID0gMTAwO1xuICAgICAgdGhpcy5wYW4gPSAwO1xuICAgICAgdGhpcy5tZXRhZGF0YSA9IHt9O1xuICAgICAgdGhpcy5maWx0ZXJzID0gW25ldyBWb2x1bWVGaWx0ZXIodGhpcywgJ3ZvbHVtZScpLCBuZXcgQmFsYW5jZUZpbHRlcih0aGlzLCAncGFuJyldO1xuICAgICAgdGhpcy5hc3NldC5vbignYnVmZmVyJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihidWZmZXJlZCkge1xuICAgICAgICAgIF90aGlzLmJ1ZmZlcmVkID0gYnVmZmVyZWQ7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2J1ZmZlcicsIF90aGlzLmJ1ZmZlcmVkKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ2RlY29kZVN0YXJ0JywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBfdGhpcy5xdWV1ZSA9IG5ldyBRdWV1ZShfdGhpcy5hc3NldCk7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLnF1ZXVlLm9uY2UoJ3JlYWR5JywgX3RoaXMuc3RhcnRQbGF5aW5nKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ2Zvcm1hdCcsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZm9ybWF0KSB7XG4gICAgICAgICAgX3RoaXMuZm9ybWF0ID0gZm9ybWF0O1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdmb3JtYXQnLCBfdGhpcy5mb3JtYXQpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5vbignbWV0YWRhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKG1ldGFkYXRhKSB7XG4gICAgICAgICAgX3RoaXMubWV0YWRhdGEgPSBtZXRhZGF0YTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnbWV0YWRhdGEnLCBfdGhpcy5tZXRhZGF0YSk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdkdXJhdGlvbicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZHVyYXRpb24pIHtcbiAgICAgICAgICBfdGhpcy5kdXJhdGlvbiA9IGR1cmF0aW9uO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdkdXJhdGlvbicsIF90aGlzLmR1cmF0aW9uKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ2Vycm9yJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihlcnJvcikge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICB9XG5cbiAgICBQbGF5ZXIuZnJvbVVSTCA9IGZ1bmN0aW9uKHVybCwgb3B0cykge1xuICAgICAgcmV0dXJuIG5ldyBQbGF5ZXIoQXNzZXQuZnJvbVVSTCh1cmwsIG9wdHMpKTtcbiAgICB9O1xuXG4gICAgUGxheWVyLmZyb21GaWxlID0gZnVuY3Rpb24oZmlsZSkge1xuICAgICAgcmV0dXJuIG5ldyBQbGF5ZXIoQXNzZXQuZnJvbUZpbGUoZmlsZSkpO1xuICAgIH07XG5cbiAgICBQbGF5ZXIuZnJvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgcmV0dXJuIG5ldyBQbGF5ZXIoQXNzZXQuZnJvbUJ1ZmZlcihidWZmZXIpKTtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5wcmVsb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIXRoaXMuYXNzZXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5zdGFydGVkUHJlbG9hZGluZyA9IHRydWU7XG4gICAgICByZXR1cm4gdGhpcy5hc3NldC5zdGFydChmYWxzZSk7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUucGxheSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLnN0YXJ0ZWRQcmVsb2FkaW5nKSB7XG4gICAgICAgIHRoaXMucHJlbG9hZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiAocmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwgPyByZWYuc3RhcnQoKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIGlmICghdGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMucGxheWluZyA9IGZhbHNlO1xuICAgICAgcmV0dXJuIChyZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCA/IHJlZi5zdG9wKCkgOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUudG9nZ2xlUGxheWJhY2sgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGF1c2UoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBsYXkoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgdGhpcy5wYXVzZSgpO1xuICAgICAgdGhpcy5hc3NldC5zdG9wKCk7XG4gICAgICByZXR1cm4gKHJlZiA9IHRoaXMuZGV2aWNlKSAhPSBudWxsID8gcmVmLmRlc3Ryb3koKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5zZWVrID0gZnVuY3Rpb24odGltZXN0YW1wKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgaWYgKChyZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCkge1xuICAgICAgICByZWYuc3RvcCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5xdWV1ZS5vbmNlKCdyZWFkeScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdmFyIHJlZjEsIHJlZjI7XG4gICAgICAgICAgaWYgKChyZWYxID0gX3RoaXMuZGV2aWNlKSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZWYxLnNlZWsoX3RoaXMuY3VycmVudFRpbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoX3RoaXMucGxheWluZykge1xuICAgICAgICAgICAgcmV0dXJuIChyZWYyID0gX3RoaXMuZGV2aWNlKSAhPSBudWxsID8gcmVmMi5zdGFydCgpIDogdm9pZCAwO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRpbWVzdGFtcCA9ICh0aW1lc3RhbXAgLyAxMDAwKSAqIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGU7XG4gICAgICB0aW1lc3RhbXAgPSB0aGlzLmFzc2V0LmRlY29kZXIuc2Vlayh0aW1lc3RhbXApO1xuICAgICAgdGhpcy5jdXJyZW50VGltZSA9IHRpbWVzdGFtcCAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMDtcbiAgICAgIHRoaXMucXVldWUucmVzZXQoKTtcbiAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRUaW1lO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnN0YXJ0UGxheWluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGZyYW1lLCBmcmFtZU9mZnNldDtcbiAgICAgIGZyYW1lID0gdGhpcy5xdWV1ZS5yZWFkKCk7XG4gICAgICBmcmFtZU9mZnNldCA9IDA7XG4gICAgICB0aGlzLmRldmljZSA9IG5ldyBBdWRpb0RldmljZSh0aGlzLmZvcm1hdC5zYW1wbGVSYXRlLCB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lKTtcbiAgICAgIHRoaXMuZGV2aWNlLm9uKCd0aW1lVXBkYXRlJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihjdXJyZW50VGltZSkge1xuICAgICAgICAgIF90aGlzLmN1cnJlbnRUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ3Byb2dyZXNzJywgX3RoaXMuY3VycmVudFRpbWUpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5yZWZpbGwgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgICAgIHZhciBidWZmZXJPZmZzZXQsIGZpbHRlciwgaSwgaiwgaywgbGVuLCBtYXgsIHJlZiwgcmVmMTtcbiAgICAgICAgICBpZiAoIV90aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFmcmFtZSkge1xuICAgICAgICAgICAgZnJhbWUgPSBfdGhpcy5xdWV1ZS5yZWFkKCk7XG4gICAgICAgICAgICBmcmFtZU9mZnNldCA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJ1ZmZlck9mZnNldCA9IDA7XG4gICAgICAgICAgd2hpbGUgKGZyYW1lICYmIGJ1ZmZlck9mZnNldCA8IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgIG1heCA9IE1hdGgubWluKGZyYW1lLmxlbmd0aCAtIGZyYW1lT2Zmc2V0LCBidWZmZXIubGVuZ3RoIC0gYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBtYXg7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgICAgICAgYnVmZmVyW2J1ZmZlck9mZnNldCsrXSA9IGZyYW1lW2ZyYW1lT2Zmc2V0KytdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZyYW1lT2Zmc2V0ID09PSBmcmFtZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgZnJhbWUgPSBfdGhpcy5xdWV1ZS5yZWFkKCk7XG4gICAgICAgICAgICAgIGZyYW1lT2Zmc2V0ID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmVmMSA9IF90aGlzLmZpbHRlcnM7XG4gICAgICAgICAgZm9yIChrID0gMCwgbGVuID0gcmVmMS5sZW5ndGg7IGsgPCBsZW47IGsrKykge1xuICAgICAgICAgICAgZmlsdGVyID0gcmVmMVtrXTtcbiAgICAgICAgICAgIGZpbHRlci5wcm9jZXNzKGJ1ZmZlcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghZnJhbWUpIHtcbiAgICAgICAgICAgIGlmIChfdGhpcy5xdWV1ZS5lbmRlZCkge1xuICAgICAgICAgICAgICBfdGhpcy5jdXJyZW50VGltZSA9IF90aGlzLmR1cmF0aW9uO1xuICAgICAgICAgICAgICBfdGhpcy5lbWl0KCdwcm9ncmVzcycsIF90aGlzLmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgICAgICAgIF90aGlzLnN0b3AoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIF90aGlzLmRldmljZS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcyk7XG4gICAgICB0aGlzLmRldmljZS5vbigncmVmaWxsJywgdGhpcy5yZWZpbGwpO1xuICAgICAgaWYgKHRoaXMucGxheWluZykge1xuICAgICAgICB0aGlzLmRldmljZS5zdGFydCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgncmVhZHknKTtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVmLCByZWYxO1xuICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICBpZiAoKHJlZiA9IHRoaXMuZGV2aWNlKSAhPSBudWxsKSB7XG4gICAgICAgIHJlZi5vZmYoKTtcbiAgICAgIH1cbiAgICAgIGlmICgocmVmMSA9IHRoaXMuYXNzZXQpICE9IG51bGwpIHtcbiAgICAgICAgcmVmMS5kZXN0cm95KCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5vZmYoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFBsYXllcjtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gUGxheWVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEV2ZW50RW1pdHRlciwgUXVldWUsXG4gICAgYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgUXVldWUgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChRdWV1ZSwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBRdWV1ZShhc3NldCkge1xuICAgICAgdGhpcy5hc3NldCA9IGFzc2V0O1xuICAgICAgdGhpcy53cml0ZSA9IGJpbmQodGhpcy53cml0ZSwgdGhpcyk7XG4gICAgICB0aGlzLnJlYWR5TWFyayA9IDY0O1xuICAgICAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5idWZmZXJpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5idWZmZXJzID0gW107XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdkYXRhJywgdGhpcy53cml0ZSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdlbmQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbmRlZCA9IHRydWU7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0LmRlY29kZVBhY2tldCgpO1xuICAgIH1cblxuICAgIFF1ZXVlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgaWYgKGJ1ZmZlcikge1xuICAgICAgICB0aGlzLmJ1ZmZlcnMucHVzaChidWZmZXIpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuYnVmZmVyaW5nKSB7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlcnMubGVuZ3RoID49IHRoaXMucmVhZHlNYXJrIHx8IHRoaXMuZW5kZWQpIHtcbiAgICAgICAgICB0aGlzLmJ1ZmZlcmluZyA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuYXNzZXQuZGVjb2RlUGFja2V0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgUXVldWUucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmJ1ZmZlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgdGhpcy5hc3NldC5kZWNvZGVQYWNrZXQoKTtcbiAgICAgIHJldHVybiB0aGlzLmJ1ZmZlcnMuc2hpZnQoKTtcbiAgICB9O1xuXG4gICAgUXVldWUucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmJ1ZmZlcnMubGVuZ3RoID0gMDtcbiAgICAgIHRoaXMuYnVmZmVyaW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzLmFzc2V0LmRlY29kZVBhY2tldCgpO1xuICAgIH07XG5cbiAgICByZXR1cm4gUXVldWU7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFF1ZXVlO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiRXZlbnRFbWl0dGVyID0gcmVxdWlyZSAnLi4vLi4vY29yZS9ldmVudHMnXG5BVkJ1ZmZlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvYnVmZmVyJ1xuXG5jbGFzcyBGaWxlU291cmNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyXG4gICAgY29uc3RydWN0b3I6IChAZmlsZSkgLT5cbiAgICAgICAgaWYgbm90IEZpbGVSZWFkZXI/XG4gICAgICAgICAgICByZXR1cm4gQGVtaXQgJ2Vycm9yJywgJ1RoaXMgYnJvd3NlciBkb2VzIG5vdCBoYXZlIEZpbGVSZWFkZXIgc3VwcG9ydC4nXG4gICAgICAgIFxuICAgICAgICBAb2Zmc2V0ID0gMFxuICAgICAgICBAbGVuZ3RoID0gQGZpbGUuc2l6ZVxuICAgICAgICBAY2h1bmtTaXplID0gMSA8PCAyMFxuICAgICAgICBAZmlsZVtAc2xpY2UgPSAnc2xpY2UnXSBvciBAZmlsZVtAc2xpY2UgPSAnd2Via2l0U2xpY2UnXSBvciBAZmlsZVtAc2xpY2UgPSAnbW96U2xpY2UnXVxuICAgICAgICAgICAgXG4gICAgc3RhcnQ6IC0+XG4gICAgICAgIGlmIEByZWFkZXJcbiAgICAgICAgICAgIHJldHVybiBAbG9vcCgpIHVubGVzcyBAYWN0aXZlXG4gICAgICAgIFxuICAgICAgICBAcmVhZGVyID0gbmV3IEZpbGVSZWFkZXJcbiAgICAgICAgQGFjdGl2ZSA9IHRydWVcbiAgICAgICAgXG4gICAgICAgIEByZWFkZXIub25sb2FkID0gKGUpID0+XG4gICAgICAgICAgICBidWYgPSBuZXcgQVZCdWZmZXIobmV3IFVpbnQ4QXJyYXkoZS50YXJnZXQucmVzdWx0KSlcbiAgICAgICAgICAgIEBvZmZzZXQgKz0gYnVmLmxlbmd0aFxuICAgICAgICBcbiAgICAgICAgICAgIEBlbWl0ICdkYXRhJywgYnVmICAgXG4gICAgICAgICAgICBAYWN0aXZlID0gZmFsc2UgICAgIFxuICAgICAgICAgICAgQGxvb3AoKSBpZiBAb2Zmc2V0IDwgQGxlbmd0aFxuICAgICAgICBcbiAgICAgICAgQHJlYWRlci5vbmxvYWRlbmQgPSA9PlxuICAgICAgICAgICAgaWYgQG9mZnNldCBpcyBAbGVuZ3RoXG4gICAgICAgICAgICAgICAgQGVtaXQgJ2VuZCdcbiAgICAgICAgICAgICAgICBAcmVhZGVyID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgQHJlYWRlci5vbmVycm9yID0gKGUpID0+XG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlXG4gICAgICAgIFxuICAgICAgICBAcmVhZGVyLm9ucHJvZ3Jlc3MgPSAoZSkgPT5cbiAgICAgICAgICAgIEBlbWl0ICdwcm9ncmVzcycsIChAb2Zmc2V0ICsgZS5sb2FkZWQpIC8gQGxlbmd0aCAqIDEwMFxuICAgICAgICBcbiAgICAgICAgQGxvb3AoKVxuICAgICAgICBcbiAgICBsb29wOiAtPlxuICAgICAgICBAYWN0aXZlID0gdHJ1ZVxuICAgICAgICBlbmRQb3MgPSBNYXRoLm1pbihAb2Zmc2V0ICsgQGNodW5rU2l6ZSwgQGxlbmd0aClcbiAgICAgICAgXG4gICAgICAgIGJsb2IgPSBAZmlsZVtAc2xpY2VdKEBvZmZzZXQsIGVuZFBvcylcbiAgICAgICAgQHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihibG9iKVxuICAgICAgICBcbiAgICBwYXVzZTogLT5cbiAgICAgICAgQGFjdGl2ZSA9IGZhbHNlXG4gICAgICAgIHRyeVxuICAgICAgICAgIEByZWFkZXI/LmFib3J0KClcbiAgICAgICAgXG4gICAgcmVzZXQ6IC0+XG4gICAgICAgIEBwYXVzZSgpXG4gICAgICAgIEBvZmZzZXQgPSAwXG5cbm1vZHVsZS5leHBvcnRzID0gRmlsZVNvdXJjZVxuIiwiRXZlbnRFbWl0dGVyID0gcmVxdWlyZSAnLi4vLi4vY29yZS9ldmVudHMnXG5BVkJ1ZmZlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvYnVmZmVyJ1xuXG5jbGFzcyBIVFRQU291cmNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyXG4gICAgY29uc3RydWN0b3I6IChAdXJsLCBAb3B0cyA9IHt9KSAtPlxuICAgICAgICBAY2h1bmtTaXplID0gMSA8PCAyMFxuICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICBpZiBAb3B0cy5sZW5ndGhcbiAgICAgICAgICAgIEBsZW5ndGggPSBAb3B0cy5sZW5ndGhcbiAgICAgICAgQHJlc2V0KClcbiAgICAgICAgXG4gICAgc3RhcnQ6IC0+XG4gICAgICAgIGlmIEBsZW5ndGhcbiAgICAgICAgICAgIHJldHVybiBAbG9vcCgpIHVubGVzcyBAaW5mbGlnaHRcbiAgICAgICAgXG4gICAgICAgIEBpbmZsaWdodCA9IHRydWVcbiAgICAgICAgQHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpXG4gICAgICAgIFxuICAgICAgICBAeGhyLm9ubG9hZCA9IChldmVudCkgPT5cbiAgICAgICAgICAgIEBsZW5ndGggPSBwYXJzZUludCBAeGhyLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1MZW5ndGhcIikgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICAgICAgQGxvb3AoKVxuICAgICAgICBcbiAgICAgICAgQHhoci5vbmVycm9yID0gKGVycikgPT5cbiAgICAgICAgICAgIEBwYXVzZSgpXG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlcnJcbiAgICAgICAgICAgIFxuICAgICAgICBAeGhyLm9uYWJvcnQgPSAoZXZlbnQpID0+XG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICBcbiAgICAgICAgQHhoci5vcGVuKFwiSEVBRFwiLCBAdXJsLCB0cnVlKVxuICAgICAgICBAeGhyLnNlbmQobnVsbClcbiAgICAgICAgXG4gICAgbG9vcDogLT5cbiAgICAgICAgaWYgQGluZmxpZ2h0IG9yIG5vdCBAbGVuZ3RoXG4gICAgICAgICAgICByZXR1cm4gQGVtaXQgJ2Vycm9yJywgJ1NvbWV0aGluZyBpcyB3cm9uZyBpbiBIVFRQU291cmNlLmxvb3AnXG4gICAgICAgICAgICBcbiAgICAgICAgQGluZmxpZ2h0ID0gdHJ1ZVxuICAgICAgICBAeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KClcbiAgICAgICAgXG4gICAgICAgIEB4aHIub25sb2FkID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgaWYgQHhoci5yZXNwb25zZVxuICAgICAgICAgICAgICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KEB4aHIucmVzcG9uc2UpXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdHh0ID0gQHhoci5yZXNwb25zZVRleHRcbiAgICAgICAgICAgICAgICBidWYgPSBuZXcgVWludDhBcnJheSh0eHQubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciBpIGluIFswLi4udHh0Lmxlbmd0aF1cbiAgICAgICAgICAgICAgICAgICAgYnVmW2ldID0gdHh0LmNoYXJDb2RlQXQoaSkgJiAweGZmXG5cbiAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBBVkJ1ZmZlcihidWYpXG4gICAgICAgICAgICBAb2Zmc2V0ICs9IGJ1ZmZlci5sZW5ndGhcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgQGVtaXQgJ2RhdGEnLCBidWZmZXJcbiAgICAgICAgICAgIEBlbWl0ICdlbmQnIGlmIEBvZmZzZXQgPj0gQGxlbmd0aFxuXG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICAgICAgQGxvb3AoKSB1bmxlc3MgQG9mZnNldCA+PSBAbGVuZ3RoXG4gICAgICAgICAgICBcbiAgICAgICAgQHhoci5vbnByb2dyZXNzID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgQGVtaXQgJ3Byb2dyZXNzJywgKEBvZmZzZXQgKyBldmVudC5sb2FkZWQpIC8gQGxlbmd0aCAqIDEwMFxuXG4gICAgICAgIEB4aHIub25lcnJvciA9IChlcnIpID0+XG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlcnJcbiAgICAgICAgICAgIEBwYXVzZSgpXG5cbiAgICAgICAgQHhoci5vbmFib3J0ID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcblxuICAgICAgICBAeGhyLm9wZW4oXCJHRVRcIiwgQHVybCwgdHJ1ZSlcbiAgICAgICAgQHhoci5yZXNwb25zZVR5cGUgPSBcImFycmF5YnVmZmVyXCJcblxuICAgICAgICBlbmRQb3MgPSBNYXRoLm1pbihAb2Zmc2V0ICsgQGNodW5rU2l6ZSwgQGxlbmd0aCAtIDEpXG4gICAgICAgIEB4aHIuc2V0UmVxdWVzdEhlYWRlcihcIklmLU5vbmUtTWF0Y2hcIiwgXCJ3ZWJraXQtbm8tY2FjaGVcIilcbiAgICAgICAgQHhoci5zZXRSZXF1ZXN0SGVhZGVyKFwiUmFuZ2VcIiwgXCJieXRlcz0je0BvZmZzZXR9LSN7ZW5kUG9zfVwiKVxuICAgICAgICBAeGhyLm92ZXJyaWRlTWltZVR5cGUoJ3RleHQvcGxhaW47IGNoYXJzZXQ9eC11c2VyLWRlZmluZWQnKVxuICAgICAgICBAeGhyLnNlbmQobnVsbClcbiAgICAgICAgXG4gICAgcGF1c2U6IC0+XG4gICAgICAgIEBpbmZsaWdodCA9IGZhbHNlXG4gICAgICAgIEB4aHI/LmFib3J0KClcbiAgICAgICAgXG4gICAgcmVzZXQ6IC0+XG4gICAgICAgIEBwYXVzZSgpXG4gICAgICAgIEBvZmZzZXQgPSAwXG4gICAgICAgIFxubW9kdWxlLmV4cG9ydHMgPSBIVFRQU291cmNlXG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQVZCdWZmZXIsIEJ1ZmZlckxpc3QsIEJ1ZmZlclNvdXJjZSwgRXZlbnRFbWl0dGVyLFxuICAgIGJpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi4vY29yZS9ldmVudHMnKTtcblxuICBCdWZmZXJMaXN0ID0gcmVxdWlyZSgnLi4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgQVZCdWZmZXIgPSByZXF1aXJlKCcuLi9jb3JlL2J1ZmZlcicpO1xuXG4gIEJ1ZmZlclNvdXJjZSA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGNsZWFySW1tZWRpYXRlLCBzZXRJbW1lZGlhdGU7XG5cbiAgICBleHRlbmQoQnVmZmVyU291cmNlLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIEJ1ZmZlclNvdXJjZShpbnB1dCkge1xuICAgICAgdGhpcy5sb29wID0gYmluZCh0aGlzLmxvb3AsIHRoaXMpO1xuICAgICAgaWYgKGlucHV0IGluc3RhbmNlb2YgQnVmZmVyTGlzdCkge1xuICAgICAgICB0aGlzLmxpc3QgPSBpbnB1dDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubGlzdCA9IG5ldyBCdWZmZXJMaXN0O1xuICAgICAgICB0aGlzLmxpc3QuYXBwZW5kKG5ldyBBVkJ1ZmZlcihpbnB1dCkpO1xuICAgICAgfVxuICAgICAgdGhpcy5wYXVzZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHNldEltbWVkaWF0ZSA9IGdsb2JhbC5zZXRJbW1lZGlhdGUgfHwgZnVuY3Rpb24oZm4pIHtcbiAgICAgIHJldHVybiBnbG9iYWwuc2V0VGltZW91dChmbiwgMCk7XG4gICAgfTtcblxuICAgIGNsZWFySW1tZWRpYXRlID0gZ2xvYmFsLmNsZWFySW1tZWRpYXRlIHx8IGZ1bmN0aW9uKHRpbWVyKSB7XG4gICAgICByZXR1cm4gZ2xvYmFsLmNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgfTtcblxuICAgIEJ1ZmZlclNvdXJjZS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMucGF1c2VkID0gZmFsc2U7XG4gICAgICByZXR1cm4gdGhpcy5fdGltZXIgPSBzZXRJbW1lZGlhdGUodGhpcy5sb29wKTtcbiAgICB9O1xuXG4gICAgQnVmZmVyU291cmNlLnByb3RvdHlwZS5sb29wID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmVtaXQoJ3Byb2dyZXNzJywgKHRoaXMubGlzdC5udW1CdWZmZXJzIC0gdGhpcy5saXN0LmF2YWlsYWJsZUJ1ZmZlcnMgKyAxKSAvIHRoaXMubGlzdC5udW1CdWZmZXJzICogMTAwIHwgMCk7XG4gICAgICB0aGlzLmVtaXQoJ2RhdGEnLCB0aGlzLmxpc3QuZmlyc3QpO1xuICAgICAgaWYgKHRoaXMubGlzdC5hZHZhbmNlKCkpIHtcbiAgICAgICAgcmV0dXJuIHNldEltbWVkaWF0ZSh0aGlzLmxvb3ApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZW5kJyk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJ1ZmZlclNvdXJjZS5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIGNsZWFySW1tZWRpYXRlKHRoaXMuX3RpbWVyKTtcbiAgICAgIHJldHVybiB0aGlzLnBhdXNlZCA9IHRydWU7XG4gICAgfTtcblxuICAgIEJ1ZmZlclNvdXJjZS5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMucGF1c2UoKTtcbiAgICAgIHJldHVybiB0aGlzLmxpc3QucmV3aW5kKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBCdWZmZXJTb3VyY2U7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEJ1ZmZlclNvdXJjZTtcblxufSkuY2FsbCh0aGlzKTtcbiJdfQ==