UNPKG

es51922

Version:

Streaming Cyrustek ES51922 DMM data protocol implementation over serial

659 lines (561 loc) 79 kB
import { take, tap, mapTo, concatMap, map } from 'rxjs/operators'; import { using, fromEvent, iif, of } from 'rxjs'; import { streamToRx, rxToStream } from 'rxjs-stream'; import ByteLength from '@serialport/parser-byte-length'; import KaitaiStream from 'kaitai-struct/KaitaiStream'; import { KaitaiStream as KaitaiStream$1 } from 'kaitai-struct'; import SerialPort from 'serialport'; import { config } from 'dotenv'; import createDebugger from 'debug'; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { keys.push.apply(keys, Object.getOwnPropertySymbols(object)); } if (enumerableOnly) keys = keys.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var es51922 = createCommonjsModule(function (module) { // This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild (function (root, factory) { if ( module.exports) { module.exports = factory(KaitaiStream); } else { root.Es51922 = factory(root.KaitaiStream); } })(commonjsGlobal, function (KaitaiStream) { var Es51922 = function () { Es51922.AdpRanges = Object.freeze({ ADP0: 0, ADP1: 1, ADP2: 2, ADP3: 3, ADP4: 4, 0: "ADP0", 1: "ADP1", 2: "ADP2", 3: "ADP3", 4: "ADP4" }); Es51922.Functions = Object.freeze({ CURRENT_22A: 0, DIODE: 1, FREQ: 2, RESISTANCE: 3, TEMPERATURE: 4, CONTINUITY: 5, CAPACITANCE: 6, CURRENT_MANUAL: 9, VOLTAGE: 11, CURRENT_MICROAMP: 13, ADP: 14, CURRENT_MILLIAMP: 15, 0: "CURRENT_22A", 1: "DIODE", 2: "FREQ", 3: "RESISTANCE", 4: "TEMPERATURE", 5: "CONTINUITY", 6: "CAPACITANCE", 9: "CURRENT_MANUAL", 11: "VOLTAGE", 13: "CURRENT_MICROAMP", 14: "ADP", 15: "CURRENT_MILLIAMP" }); function Es51922(_io, _parent, _root) { this._io = _io; this._parent = _parent; this._root = _root || this; this._read(); } Es51922.prototype._read = function () { this.rawRange = this._io.readU1(); this.rawDigit0 = this._io.readU1(); this.rawDigit1 = this._io.readU1(); this.rawDigit2 = this._io.readU1(); this.rawDigit3 = this._io.readU1(); this.rawDigit4 = this._io.readU1(); this.rawFunc = this._io.readU1(); this.rawStatus = this._io.readU1(); this.rawOption0 = this._io.readU1(); this.rawOption1 = this._io.readU1(); this.rawOption2 = this._io.readU1(); this.rawOption3 = this._io.readU1(); this.eom = this._io.ensureFixedContents([13, 10]); }; var Options = Es51922.Options = function () { function Options(_io, _parent, _root) { this._io = _io; this._parent = _parent; this._root = _root || this; this._read(); } Options.prototype._read = function () {}; Object.defineProperty(Options.prototype, 'hold', { get: function () { if (this._m_hold !== undefined) return this._m_hold; this._m_hold = (this._parent.rawOption3 ^ 48 & 1) == 1; return this._m_hold; } }); Object.defineProperty(Options.prototype, 'maximum', { get: function () { if (this._m_maximum !== undefined) return this._m_maximum; this._m_maximum = (this._parent.rawOption0 ^ 48 & 3) == 1; return this._m_maximum; } }); Object.defineProperty(Options.prototype, 'auto', { get: function () { if (this._m_auto !== undefined) return this._m_auto; this._m_auto = (this._parent.rawOption2 ^ 48 & 1) == 1; return this._m_auto; } }); Object.defineProperty(Options.prototype, 'peakMaximum', { get: function () { if (this._m_peakMaximum !== undefined) return this._m_peakMaximum; this._m_peakMaximum = (this._parent.rawOption1 ^ 48 & 2) == 1; return this._m_peakMaximum; } }); Object.defineProperty(Options.prototype, 'currentValue', { get: function () { if (this._m_currentValue !== undefined) return this._m_currentValue; this._m_currentValue = (this._parent.rawOption0 ^ 48 & 0) == 1; return this._m_currentValue; } }); Object.defineProperty(Options.prototype, 'vahz', { get: function () { if (this._m_vahz !== undefined) return this._m_vahz; this._m_vahz = (this._parent.rawOption2 ^ 48 & 0) == 1; return this._m_vahz; } }); Object.defineProperty(Options.prototype, 'lpf', { get: function () { if (this._m_lpf !== undefined) return this._m_lpf; this._m_lpf = (this._parent.rawOption3 ^ 48 & 0) == 1; return this._m_lpf; } }); Object.defineProperty(Options.prototype, 'minimum', { get: function () { if (this._m_minimum !== undefined) return this._m_minimum; this._m_minimum = (this._parent.rawOption0 ^ 48 & 2) == 1; return this._m_minimum; } }); Object.defineProperty(Options.prototype, 'acMode', { get: function () { if (this._m_acMode !== undefined) return this._m_acMode; this._m_acMode = (this._parent.rawOption2 ^ 48 & 2) == 1 ? "current" : "voltage"; return this._m_acMode; } }); Object.defineProperty(Options.prototype, 'peakMinimum', { get: function () { if (this._m_peakMinimum !== undefined) return this._m_peakMinimum; this._m_peakMinimum = (this._parent.rawOption1 ^ 48 & 1) == 1; return this._m_peakMinimum; } }); Object.defineProperty(Options.prototype, 'dcMode', { get: function () { if (this._m_dcMode !== undefined) return this._m_dcMode; this._m_dcMode = (this._parent.rawOption2 ^ 48 & 3) == 1 ? "current" : "voltage"; return this._m_dcMode; } }); Object.defineProperty(Options.prototype, 'relative', { get: function () { if (this._m_relative !== undefined) return this._m_relative; this._m_relative = (this._parent.rawOption0 ^ 48 & 1) == 1; return this._m_relative; } }); Object.defineProperty(Options.prototype, 'vbar', { get: function () { if (this._m_vbar !== undefined) return this._m_vbar; this._m_vbar = (this._parent.rawOption3 ^ 48 & 2) == 1; return this._m_vbar; } }); return Options; }(); var BaseAdpRange = Es51922.BaseAdpRange = function () { function BaseAdpRange(_io, _parent, _root, adpMode) { this._io = _io; this._parent = _parent; this._root = _root || this; this.adpMode = adpMode; this._read(); } BaseAdpRange.prototype._read = function () {}; return BaseAdpRange; }(); var BaseFunc = Es51922.BaseFunc = function () { function BaseFunc(_io, _parent, _root, baseUnit, baseRange, mode) { this._io = _io; this._parent = _parent; this._root = _root || this; this.baseUnit = baseUnit; this.baseRange = baseRange; this.mode = mode; this._read(); } BaseFunc.prototype._read = function () {}; return BaseFunc; }(); var BaseRange = Es51922.BaseRange = function () { function BaseRange(_io, _parent, _root, unit, multiplier, precision, mode) { this._io = _io; this._parent = _parent; this._root = _root || this; this.unit = unit; this.multiplier = multiplier; this.precision = precision; this.mode = mode; this._read(); } BaseRange.prototype._read = function () {}; return BaseRange; }(); var Status = Es51922.Status = function () { function Status(_io, _parent, _root) { this._io = _io; this._parent = _parent; this._root = _root || this; this._read(); } Status.prototype._read = function () {}; Object.defineProperty(Status.prototype, 'signMultiplier', { get: function () { if (this._m_signMultiplier !== undefined) return this._m_signMultiplier; this._m_signMultiplier = (this._parent.rawStatus ^ 48 & 2) == 1 ? -1 : 1; return this._m_signMultiplier; } }); Object.defineProperty(Status.prototype, 'batteryLow', { get: function () { if (this._m_batteryLow !== undefined) return this._m_batteryLow; this._m_batteryLow = (this._parent.rawStatus ^ 48 & 1) == 1; return this._m_batteryLow; } }); Object.defineProperty(Status.prototype, 'underload', { get: function () { if (this._m_underload !== undefined) return this._m_underload; this._m_underload = (this._parent.rawOption1 ^ 48 & 2) == 1; return this._m_underload; } }); Object.defineProperty(Status.prototype, 'degrees', { get: function () { if (this._m_degrees !== undefined) return this._m_degrees; this._m_degrees = (this._parent.rawStatus ^ 48 & 3) == 1 ? "C" : "F"; return this._m_degrees; } }); Object.defineProperty(Status.prototype, 'overload', { get: function () { if (this._m_overload !== undefined) return this._m_overload; this._m_overload = (this._parent.rawStatus ^ 48 & 0) == 1; return this._m_overload; } }); Object.defineProperty(Status.prototype, 'operation', { get: function () { if (this._m_operation !== undefined) return this._m_operation; this._m_operation = this.overload ? "overload" : this.underload ? "underload" : "normal"; return this._m_operation; } }); return Status; }(); Object.defineProperty(Es51922.prototype, 'status', { get: function () { if (this._m_status !== undefined) return this._m_status; this._m_status = new Status(this._io, this, this._root); return this._m_status; } }); Object.defineProperty(Es51922.prototype, 'func', { get: function () { if (this._m_func !== undefined) return this._m_func; this._m_func = this.rawFunc ^ 48; return this._m_func; } }); Object.defineProperty(Es51922.prototype, 'digits', { get: function () { if (this._m_digits !== undefined) return this._m_digits; var _pos = this._io.pos; this._io.seek(1); this._raw__m_digits = this._io.readBytes(5); this._m_digits = KaitaiStream.processXorOne(this._raw__m_digits, 48); this._io.seek(_pos); return this._m_digits; } }); Object.defineProperty(Es51922.prototype, 'options', { get: function () { if (this._m_options !== undefined) return this._m_options; this._m_options = new Options(this._io, this, this._root); return this._m_options; } }); Object.defineProperty(Es51922.prototype, 'range', { get: function () { if (this._m_range !== undefined) return this._m_range; switch (this.rawRange ^ 48 | (this.rawFunc ^ 48) << 4) { case 177: this._m_range = new BaseRange(this._io, this, this._root, "V", 1.0, 3, "voltage"); break; case 0: this._m_range = new BaseRange(this._io, this, this._root, "A", 1.0, 3, "current"); break; case 146: this._m_range = new BaseRange(this._io, this, this._root, "A", 1.0, 2, "current"); break; case 224: this._m_range = new BaseAdpRange(this._io, this, this._root, Es51922.AdpRanges.ADP0); break; case 35: this._m_range = new BaseRange(this._io, this, this._root, "kHz", 1000.0, 2, "frequency"); break; case 32: this._m_range = new BaseRange(this._io, this, this._root, "Hz", 1.0, 2, "frequency"); break; case 96: this._m_range = new BaseRange(this._io, this, this._root, "nF", 1E-9, 3, "capacitance"); break; case 209: this._m_range = new BaseRange(this._io, this, this._root, "\xb5A", 0.000001, 1, "current"); break; case 97: this._m_range = new BaseRange(this._io, this, this._root, "nF", 1E-9, 2, "capacitance"); break; case 145: this._m_range = new BaseRange(this._io, this, this._root, "A", 1.0, 3, "current"); break; case 52: this._m_range = new BaseRange(this._io, this, this._root, "M\u03a9", 1000000.0, 4, "resistance"); break; case 101: this._m_range = new BaseRange(this._io, this, this._root, "mF", 0.001, 4, "capacitance"); break; case 144: this._m_range = new BaseRange(this._io, this, this._root, "A", 1.0, 4, "current"); break; case 100: this._m_range = new BaseRange(this._io, this, this._root, "\xb5F", 0.000001, 2, "capacitance"); break; case 98: this._m_range = new BaseRange(this._io, this, this._root, "\xb5F", 0.000001, 4, "capacitance"); break; case 208: this._m_range = new BaseRange(this._io, this, this._root, "\xb5A", 0.000001, 2, "current"); break; case 33: this._m_range = new BaseRange(this._io, this, this._root, "Hz", 1.0, 1, "frequency"); break; case 103: this._m_range = new BaseRange(this._io, this, this._root, "mF", 0.001, 2, "capacitance"); break; case 99: this._m_range = new BaseRange(this._io, this, this._root, "\xb5F", 0.000001, 3, "capacitance"); break; case 180: this._m_range = new BaseRange(this._io, this, this._root, "mV", 0.001, 2, "voltage"); break; case 51: this._m_range = new BaseRange(this._io, this, this._root, "k\u03a9", 1000.0, 2, "resistance"); break; case 227: this._m_range = new BaseAdpRange(this._io, this, this._root, Es51922.AdpRanges.ADP3); break; case 48: this._m_range = new BaseRange(this._io, this, this._root, "\u03a9", 1.0, 2, "resistance"); break; case 178: this._m_range = new BaseRange(this._io, this, this._root, "V", 1.0, 2, "voltage"); break; case 53: this._m_range = new BaseRange(this._io, this, this._root, "M\u03a9", 1000000.0, 3, "resistance"); break; case 176: this._m_range = new BaseRange(this._io, this, this._root, "V", 1.0, 4, "voltage"); break; case 38: this._m_range = new BaseRange(this._io, this, this._root, "MHz", 1000000.0, 2, "frequency"); break; case 148: this._m_range = new BaseRange(this._io, this, this._root, "A", 1.0, 0, "current"); break; case 241: this._m_range = new BaseRange(this._io, this, this._root, "mA", 0.001, 2, "current"); break; case 226: this._m_range = new BaseAdpRange(this._io, this, this._root, Es51922.AdpRanges.ADP2); break; case 179: this._m_range = new BaseRange(this._io, this, this._root, "V", 1.0, 1, "voltage"); break; case 240: this._m_range = new BaseRange(this._io, this, this._root, "mA", 0.001, 3, "current"); break; case 225: this._m_range = new BaseAdpRange(this._io, this, this._root, Es51922.AdpRanges.ADP1); break; case 37: this._m_range = new BaseRange(this._io, this, this._root, "MHz", 1000000.0, 3, "frequency"); break; case 36: this._m_range = new BaseRange(this._io, this, this._root, "MHz", 1000000.0, 4, "frequency"); break; case 16: this._m_range = new BaseRange(this._io, this, this._root, "V", 1.0, 4, "diode"); break; case 147: this._m_range = new BaseRange(this._io, this, this._root, "A", 1.0, 1, "current"); break; case 80: this._m_range = new BaseRange(this._io, this, this._root, "\u03a9", 1.0, 2, "continuity"); break; case 102: this._m_range = new BaseRange(this._io, this, this._root, "mF", 0.001, 3, "capacitance"); break; case 49: this._m_range = new BaseRange(this._io, this, this._root, "k\u03a9", 1000.0, 4, "resistance"); break; case 34: this._m_range = new BaseRange(this._io, this, this._root, "kHz", 1000.0, 3, "frequency"); break; case 54: this._m_range = new BaseRange(this._io, this, this._root, "M\u03a9", 1000000.0, 2, "resistance"); break; case 228: this._m_range = new BaseAdpRange(this._io, this, this._root, Es51922.AdpRanges.ADP4); break; case 50: this._m_range = new BaseRange(this._io, this, this._root, "k\u03a9", 1000.0, 3, "resistance"); break; } return this._m_range; } }); Object.defineProperty(Es51922.prototype, 'precision', { get: function () { if (this._m_precision !== undefined) return this._m_precision; this._m_precision = this.range.precision == 0 ? 1.0 : this.range.precision == 1 ? 0.1 : this.range.precision == 2 ? 0.01 : this.range.precision == 3 ? 0.001 : 0.0001; return this._m_precision; } }); Object.defineProperty(Es51922.prototype, 'value', { get: function () { if (this._m_value !== undefined) return this._m_value; if (this.func != Es51922.Functions.TEMPERATURE && this.func != Es51922.Functions.ADP) { this._m_value = ((this.rawDigit0 ^ 48) * 10000 + (this.rawDigit1 ^ 48) * 1000 + (this.rawDigit2 ^ 48) * 100 + (this.rawDigit3 ^ 48) * 10 + (this.rawDigit4 ^ 48)) * this.range.multiplier * this.precision * this.status.signMultiplier; } return this._m_value; } }); return Es51922; }(); return Es51922; }); }); config(); const debug = createDebugger('es51922'); const DEFAULT_PORT = '/dev/ttyUSB0'; const fromEventOnce = (...args) => fromEvent(...args).pipe(take(1)); const createProtocolStream = buf => new es51922(new KaitaiStream$1(buf)); const createFixedPrecisionProxy = protocolStream => new Proxy(protocolStream, { get(target, prop, receiver) { const value = Reflect.get(target, prop, receiver); return prop === 'value' ? parseFloat(value.toFixed(target.range.precision)) : value; } }); const parse = () => observable => observable.pipe(tap(buf => debug(`received Buffer`, buf)), map(buf => createFixedPrecisionProxy(createProtocolStream(buf)))); const createSerialPortSubscriber = serialPort => { const unsubscribe = () => { debug(`request received to close port at ${serialPort.path}`); if (serialPort.isOpen) { serialPort.close(); } else { debug(`port at ${serialPort.path} was already closed`); } }; return new Proxy(serialPort, { get: (target, prop, receiver) => { return prop === 'unsubscribe' ? unsubscribe : Reflect.get(target, prop, receiver); } }); }; const fromSerialPort = (port = process.env.ES51922_PORT || DEFAULT_PORT, opts = {}) => using(() => { const serialPort = createSerialPortSubscriber(new SerialPort(port, _objectSpread2({ baudRate: 19200, dataBits: 7, parity: 'odd' }, opts, { autoOpen: false }))); debug(`instantiated SerialPort at path ${port}`); return serialPort; }, serialPort => { debug(`opening port at path ${port}`); serialPort.open(); return fromEventOnce(serialPort, 'open').pipe(tap(() => { debug(`port at ${serialPort.path} open`); serialPort.set({ rts: false }); }), mapTo(serialPort)); }); const fromES51922 = (port = process.env.ES51922_PORT || DEFAULT_PORT) => iif(() => typeof port === 'string', fromSerialPort(port), of(port)).pipe(concatMap(serialPort => streamToRx(serialPort.pipe(new ByteLength({ length: 14 })))), parse()); const readES51922Stream = (...args) => rxToStream(fromES51922(...args), { objectMode: true }); export { DEFAULT_PORT, fromES51922, fromSerialPort, readES51922Stream }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXM1MTkyMi5lc20uanMiLCJzb3VyY2VzIjpbIi4uL3ZlbmRvci9lczUxOTIyLmpzIiwiLi4vc3JjL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgaXMgYSBnZW5lcmF0ZWQgZmlsZSEgUGxlYXNlIGVkaXQgc291cmNlIC5rc3kgZmlsZSBhbmQgdXNlIGthaXRhaS1zdHJ1Y3QtY29tcGlsZXIgdG8gcmVidWlsZFxuXG4oZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgIGRlZmluZShbJ2thaXRhaS1zdHJ1Y3QvS2FpdGFpU3RyZWFtJ10sIGZhY3RvcnkpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoJ2thaXRhaS1zdHJ1Y3QvS2FpdGFpU3RyZWFtJykpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuRXM1MTkyMiA9IGZhY3Rvcnkocm9vdC5LYWl0YWlTdHJlYW0pO1xuICB9XG59KHRoaXMsIGZ1bmN0aW9uIChLYWl0YWlTdHJlYW0pIHtcbnZhciBFczUxOTIyID0gKGZ1bmN0aW9uKCkge1xuICBFczUxOTIyLkFkcFJhbmdlcyA9IE9iamVjdC5mcmVlemUoe1xuICAgIEFEUDA6IDAsXG4gICAgQURQMTogMSxcbiAgICBBRFAyOiAyLFxuICAgIEFEUDM6IDMsXG4gICAgQURQNDogNCxcblxuICAgIDA6IFwiQURQMFwiLFxuICAgIDE6IFwiQURQMVwiLFxuICAgIDI6IFwiQURQMlwiLFxuICAgIDM6IFwiQURQM1wiLFxuICAgIDQ6IFwiQURQNFwiLFxuICB9KTtcblxuICBFczUxOTIyLkZ1bmN0aW9ucyA9IE9iamVjdC5mcmVlemUoe1xuICAgIENVUlJFTlRfMjJBOiAwLFxuICAgIERJT0RFOiAxLFxuICAgIEZSRVE6IDIsXG4gICAgUkVTSVNUQU5DRTogMyxcbiAgICBURU1QRVJBVFVSRTogNCxcbiAgICBDT05USU5VSVRZOiA1LFxuICAgIENBUEFDSVRBTkNFOiA2LFxuICAgIENVUlJFTlRfTUFOVUFMOiA5LFxuICAgIFZPTFRBR0U6IDExLFxuICAgIENVUlJFTlRfTUlDUk9BTVA6IDEzLFxuICAgIEFEUDogMTQsXG4gICAgQ1VSUkVOVF9NSUxMSUFNUDogMTUsXG5cbiAgICAwOiBcIkNVUlJFTlRfMjJBXCIsXG4gICAgMTogXCJESU9ERVwiLFxuICAgIDI6IFwiRlJFUVwiLFxuICAgIDM6IFwiUkVTSVNUQU5DRVwiLFxuICAgIDQ6IFwiVEVNUEVSQVRVUkVcIixcbiAgICA1OiBcIkNPTlRJTlVJVFlcIixcbiAgICA2OiBcIkNBUEFDSVRBTkNFXCIsXG4gICAgOTogXCJDVVJSRU5UX01BTlVBTFwiLFxuICAgIDExOiBcIlZPTFRBR0VcIixcbiAgICAxMzogXCJDVVJSRU5UX01JQ1JPQU1QXCIsXG4gICAgMTQ6IFwiQURQXCIsXG4gICAgMTU6IFwiQ1VSUkVOVF9NSUxMSUFNUFwiLFxuICB9KTtcblxuICBmdW5jdGlvbiBFczUxOTIyKF9pbywgX3BhcmVudCwgX3Jvb3QpIHtcbiAgICB0aGlzLl9pbyA9IF9pbztcbiAgICB0aGlzLl9wYXJlbnQgPSBfcGFyZW50O1xuICAgIHRoaXMuX3Jvb3QgPSBfcm9vdCB8fCB0aGlzO1xuXG4gICAgdGhpcy5fcmVhZCgpO1xuICB9XG4gIEVzNTE5MjIucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5yYXdSYW5nZSA9IHRoaXMuX2lvLnJlYWRVMSgpO1xuICAgIHRoaXMucmF3RGlnaXQwID0gdGhpcy5faW8ucmVhZFUxKCk7XG4gICAgdGhpcy5yYXdEaWdpdDEgPSB0aGlzLl9pby5yZWFkVTEoKTtcbiAgICB0aGlzLnJhd0RpZ2l0MiA9IHRoaXMuX2lvLnJlYWRVMSgpO1xuICAgIHRoaXMucmF3RGlnaXQzID0gdGhpcy5faW8ucmVhZFUxKCk7XG4gICAgdGhpcy5yYXdEaWdpdDQgPSB0aGlzLl9pby5yZWFkVTEoKTtcbiAgICB0aGlzLnJhd0Z1bmMgPSB0aGlzLl9pby5yZWFkVTEoKTtcbiAgICB0aGlzLnJhd1N0YXR1cyA9IHRoaXMuX2lvLnJlYWRVMSgpO1xuICAgIHRoaXMucmF3T3B0aW9uMCA9IHRoaXMuX2lvLnJlYWRVMSgpO1xuICAgIHRoaXMucmF3T3B0aW9uMSA9IHRoaXMuX2lvLnJlYWRVMSgpO1xuICAgIHRoaXMucmF3T3B0aW9uMiA9IHRoaXMuX2lvLnJlYWRVMSgpO1xuICAgIHRoaXMucmF3T3B0aW9uMyA9IHRoaXMuX2lvLnJlYWRVMSgpO1xuICAgIHRoaXMuZW9tID0gdGhpcy5faW8uZW5zdXJlRml4ZWRDb250ZW50cyhbMTMsIDEwXSk7XG4gIH1cblxuICB2YXIgT3B0aW9ucyA9IEVzNTE5MjIuT3B0aW9ucyA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBPcHRpb25zKF9pbywgX3BhcmVudCwgX3Jvb3QpIHtcbiAgICAgIHRoaXMuX2lvID0gX2lvO1xuICAgICAgdGhpcy5fcGFyZW50ID0gX3BhcmVudDtcbiAgICAgIHRoaXMuX3Jvb3QgPSBfcm9vdCB8fCB0aGlzO1xuXG4gICAgICB0aGlzLl9yZWFkKCk7XG4gICAgfVxuICAgIE9wdGlvbnMucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24oKSB7XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPcHRpb25zLnByb3RvdHlwZSwgJ2hvbGQnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5fbV9ob2xkICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgcmV0dXJuIHRoaXMuX21faG9sZDtcbiAgICAgICAgdGhpcy5fbV9ob2xkID0gKHRoaXMuX3BhcmVudC5yYXdPcHRpb24zIF4gKDQ4ICYgMSkpID09IDE7XG4gICAgICAgIHJldHVybiB0aGlzLl9tX2hvbGQ7XG4gICAgICB9XG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE9wdGlvbnMucHJvdG90eXBlLCAnbWF4aW11bScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl9tX21heGltdW0gIT09IHVuZGVmaW5lZClcbiAgICAgICAgICByZXR1cm4gdGhpcy5fbV9tYXhpbXVtO1xuICAgICAgICB0aGlzLl9tX21heGltdW0gPSAodGhpcy5fcGFyZW50LnJhd09wdGlvbjAgXiAoNDggJiAzKSkgPT0gMTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21fbWF4aW11bTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoT3B0aW9ucy5wcm90b3R5cGUsICdhdXRvJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX21fYXV0byAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHJldHVybiB0aGlzLl9tX2F1dG87XG4gICAgICAgIHRoaXMuX21fYXV0byA9ICh0aGlzLl9wYXJlbnQucmF3T3B0aW9uMiBeICg0OCAmIDEpKSA9PSAxO1xuICAgICAgICByZXR1cm4gdGhpcy5fbV9hdXRvO1xuICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPcHRpb25zLnByb3RvdHlwZSwgJ3BlYWtNYXhpbXVtJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX21fcGVha01heGltdW0gIT09IHVuZGVmaW5lZClcbiAgICAgICAgICByZXR1cm4gdGhpcy5fbV9wZWFrTWF4aW11bTtcbiAgICAgICAgdGhpcy5fbV9wZWFrTWF4aW11bSA9ICh0aGlzLl9wYXJlbnQucmF3T3B0aW9uMSBeICg0OCAmIDIpKSA9PSAxO1xuICAgICAgICByZXR1cm4gdGhpcy5fbV9wZWFrTWF4aW11bTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoT3B0aW9ucy5wcm90b3R5cGUsICdjdXJyZW50VmFsdWUnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5fbV9jdXJyZW50VmFsdWUgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICByZXR1cm4gdGhpcy5fbV9jdXJyZW50VmFsdWU7XG4gICAgICAgIHRoaXMuX21fY3VycmVudFZhbHVlID0gKHRoaXMuX3BhcmVudC5yYXdPcHRpb24wIF4gKDQ4ICYgMCkpID09IDE7XG4gICAgICAgIHJldHVybiB0aGlzLl9tX2N1cnJlbnRWYWx1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoT3B0aW9ucy5wcm90b3R5cGUsICd2YWh6Jywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX21fdmFoeiAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHJldHVybiB0aGlzLl9tX3ZhaHo7XG4gICAgICAgIHRoaXMuX21fdmFoeiA9ICh0aGlzLl9wYXJlbnQucmF3T3B0aW9uMiBeICg0OCAmIDApKSA9PSAxO1xuICAgICAgICByZXR1cm4gdGhpcy5fbV92YWh6O1xuICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPcHRpb25zLnByb3RvdHlwZSwgJ2xwZicsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl9tX2xwZiAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHJldHVybiB0aGlzLl9tX2xwZjtcbiAgICAgICAgdGhpcy5fbV9scGYgPSAodGhpcy5fcGFyZW50LnJhd09wdGlvbjMgXiAoNDggJiAwKSkgPT0gMTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21fbHBmO1xuICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPcHRpb25zLnByb3RvdHlwZSwgJ21pbmltdW0nLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5fbV9taW5pbXVtICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgcmV0dXJuIHRoaXMuX21fbWluaW11bTtcbiAgICAgICAgdGhpcy5fbV9taW5pbXVtID0gKHRoaXMuX3BhcmVudC5yYXdPcHRpb24wIF4gKDQ4ICYgMikpID09IDE7XG4gICAgICAgIHJldHVybiB0aGlzLl9tX21pbmltdW07XG4gICAgICB9XG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE9wdGlvbnMucHJvdG90eXBlLCAnYWNNb2RlJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX21fYWNNb2RlICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgcmV0dXJuIHRoaXMuX21fYWNNb2RlO1xuICAgICAgICB0aGlzLl9tX2FjTW9kZSA9ICgodGhpcy5fcGFyZW50LnJhd09wdGlvbjIgXiAoNDggJiAyKSkgPT0gMSA/IFwiY3VycmVudFwiIDogXCJ2b2x0YWdlXCIpO1xuICAgICAgICByZXR1cm4gdGhpcy5fbV9hY01vZGU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE9wdGlvbnMucHJvdG90eXBlLCAncGVha01pbmltdW0nLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5fbV9wZWFrTWluaW11bSAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHJldHVybiB0aGlzLl9tX3BlYWtNaW5pbXVtO1xuICAgICAgICB0aGlzLl9tX3BlYWtNaW5pbXVtID0gKHRoaXMuX3BhcmVudC5yYXdPcHRpb24xIF4gKDQ4ICYgMSkpID09IDE7XG4gICAgICAgIHJldHVybiB0aGlzLl9tX3BlYWtNaW5pbXVtO1xuICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPcHRpb25zLnByb3RvdHlwZSwgJ2RjTW9kZScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl9tX2RjTW9kZSAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHJldHVybiB0aGlzLl9tX2RjTW9kZTtcbiAgICAgICAgdGhpcy5fbV9kY01vZGUgPSAoKHRoaXMuX3BhcmVudC5yYXdPcHRpb24yIF4gKDQ4ICYgMykpID09IDEgPyBcImN1cnJlbnRcIiA6IFwidm9sdGFnZVwiKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21fZGNNb2RlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPcHRpb25zLnByb3RvdHlwZSwgJ3JlbGF0aXZlJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX21fcmVsYXRpdmUgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICByZXR1cm4gdGhpcy5fbV9yZWxhdGl2ZTtcbiAgICAgICAgdGhpcy5fbV9yZWxhdGl2ZSA9ICh0aGlzLl9wYXJlbnQucmF3T3B0aW9uMCBeICg0OCAmIDEpKSA9PSAxO1xuICAgICAgICByZXR1cm4gdGhpcy5fbV9yZWxhdGl2ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoT3B0aW9ucy5wcm90b3R5cGUsICd2YmFyJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX21fdmJhciAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHJldHVybiB0aGlzLl9tX3ZiYXI7XG4gICAgICAgIHRoaXMuX21fdmJhciA9ICh0aGlzLl9wYXJlbnQucmF3T3B0aW9uMyBeICg0OCAmIDIpKSA9PSAxO1xuICAgICAgICByZXR1cm4gdGhpcy5fbV92YmFyO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIE9wdGlvbnM7XG4gIH0pKCk7XG5cbiAgdmFyIEJhc2VBZHBSYW5nZSA9IEVzNTE5MjIuQmFzZUFkcFJhbmdlID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIEJhc2VBZHBSYW5nZShfaW8sIF9wYXJlbnQsIF9yb290LCBhZHBNb2RlKSB7XG4gICAgICB0aGlzLl9pbyA9IF9pbztcbiAgICAgIHRoaXMuX3BhcmVudCA9IF9wYXJlbnQ7XG4gICAgICB0aGlzLl9yb290ID0gX3Jvb3QgfHwgdGhpcztcbiAgICAgIHRoaXMuYWRwTW9kZSA9IGFkcE1vZGU7XG5cbiAgICAgIHRoaXMuX3JlYWQoKTtcbiAgICB9XG4gICAgQmFzZUFkcFJhbmdlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uKCkge1xuICAgIH1cblxuICAgIHJldHVybiBCYXNlQWRwUmFuZ2U7XG4gIH0pKCk7XG5cbiAgdmFyIEJhc2VGdW5jID0gRXM1MTkyMi5CYXNlRnVuYyA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBCYXNlRnVuYyhfaW8sIF9wYXJlbnQsIF9yb290LCBiYXNlVW5pdCwgYmFzZVJhbmdlLCBtb2RlKSB7XG4gICAgICB0aGlzLl9pbyA9IF9pbztcbiAgICAgIHRoaXMuX3BhcmVudCA9IF9wYXJlbnQ7XG4gICAgICB0aGlzLl9yb290ID0gX3Jvb3QgfHwgdGhpcztcbiAgICAgIHRoaXMuYmFzZVVuaXQgPSBiYXNlVW5pdDtcbiAgICAgIHRoaXMuYmFzZVJhbmdlID0gYmFzZVJhbmdlO1xuICAgICAgdGhpcy5tb2RlID0gbW9kZTtcblxuICAgICAgdGhpcy5fcmVhZCgpO1xuICAgIH1cbiAgICBCYXNlRnVuYy5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbigpIHtcbiAgICB9XG5cbiAgICByZXR1cm4gQmFzZUZ1bmM7XG4gIH0pKCk7XG5cbiAgdmFyIEJhc2VSYW5nZSA9IEVzNTE5MjIuQmFzZVJhbmdlID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIEJhc2VSYW5nZShfaW8sIF9wYXJlbnQsIF9yb290LCB1bml0LCBtdWx0aXBsaWVyLCBwcmVjaXNpb24sIG1vZGUpIHtcbiAgICAgIHRoaXMuX2lvID0gX2lvO1xuICAgICAgdGhpcy5fcGFyZW50ID0gX3BhcmVudDtcbiAgICAgIHRoaXMuX3Jvb3QgPSBfcm9vdCB8fCB0aGlzO1xuICAgICAgdGhpcy51bml0ID0gdW5pdDtcbiAgICAgIHRoaXMubXVsdGlwbGllciA9IG11bHRpcGxpZXI7XG4gICAgICB0aGlzLnByZWNpc2lvbiA9IHByZWNpc2lvbjtcbiAgICAgIHRoaXMubW9kZSA9IG1vZGU7XG5cbiAgICAgIHRoaXMuX3JlYWQoKTtcbiAgICB9XG4gICAgQmFzZVJhbmdlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uKCkge1xuICAgIH1cblxuICAgIHJldHVybiBCYXNlUmFuZ2U7XG4gIH0pKCk7XG5cbiAgdmFyIFN0YXR1cyA9IEVzNTE5MjIuU3RhdHVzID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIFN0YXR1cyhfaW8sIF9wYXJlbnQsIF9yb290KSB7XG4gICAgICB0aGlzLl9pbyA9IF9pbztcbiAgICAgIHRoaXMuX3BhcmVudCA9IF9wYXJlbnQ7XG4gICAgICB0aGlzLl9yb290ID0gX3Jvb3QgfHwgdGhpcztcblxuICAgICAgdGhpcy5fcmVhZCgpO1xuICAgIH1cbiAgICBTdGF0dXMucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24oKSB7XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTdGF0dXMucHJvdG90eXBlLCAnc2lnbk11bHRpcGxpZXInLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5fbV9zaWduTXVsdGlwbGllciAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHJldHVybiB0aGlzLl9tX3NpZ25NdWx0aXBsaWVyO1xuICAgICAgICB0aGlzLl9tX3NpZ25NdWx0aXBsaWVyID0gKCh0aGlzLl9wYXJlbnQucmF3U3RhdHVzIF4gKDQ4ICYgMikpID09IDEgPyAtMSA6IDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5fbV9zaWduTXVsdGlwbGllcjtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoU3RhdHVzLnByb3RvdHlwZSwgJ2JhdHRlcnlMb3cnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5fbV9iYXR0ZXJ5TG93ICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgcmV0dXJuIHRoaXMuX21fYmF0dGVyeUxvdztcbiAgICAgICAgdGhpcy5fbV9iYXR0ZXJ5TG93ID0gKHRoaXMuX3BhcmVudC5yYXdTdGF0dXMgXiAoNDggJiAxKSkgPT0gMTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21fYmF0dGVyeUxvdztcbiAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoU3RhdHVzLnByb3RvdHlwZSwgJ3VuZGVybG9hZCcsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl9tX3VuZGVybG9hZCAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHJldHVybiB0aGlzLl9tX3VuZGVybG9hZDtcbiAgICAgICAgdGhpcy5fbV91bmRlcmxvYWQgPSAodGhpcy5fcGFyZW50LnJhd09wdGlvbjEgXiAoNDggJiAyKSkgPT0gMTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21fdW5kZXJsb2FkO1xuICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTdGF0dXMucHJvdG90eXBlLCAnZGVncmVlcycsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl9tX2RlZ3JlZXMgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICByZXR1cm4gdGhpcy5fbV9kZWdyZWVzO1xuICAgICAgICB0aGlzLl9tX2RlZ3JlZXMgPSAoKHRoaXMuX3BhcmVudC5yYXdTdGF0dXMgXiAoNDggJiAzKSkgPT0gMSA/IFwiQ1wiIDogXCJGXCIpO1xuICAgICAgICByZXR1cm4gdGhpcy5fbV9kZWdyZWVzO1xuICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTdGF0dXMucHJvdG90eXBlLCAnb3ZlcmxvYWQnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5fbV9vdmVybG9hZCAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHJldHVybiB0aGlzLl9tX292ZXJsb2FkO1xuICAgICAgICB0aGlzLl9tX292ZXJsb2FkID0gKHRoaXMuX3BhcmVudC5yYXdTdGF0dXMgXiAoNDggJiAwKSkgPT0gMTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21fb3ZlcmxvYWQ7XG4gICAgICB9XG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFN0YXR1cy5wcm90b3R5cGUsICdvcGVyYXRpb24nLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5fbV9vcGVyYXRpb24gIT09IHVuZGVmaW5lZClcbiAgICAgICAgICByZXR1cm4gdGhpcy5fbV9vcGVyYXRpb247XG4gICAgICAgIHRoaXMuX21fb3BlcmF0aW9uID0gKHRoaXMub3ZlcmxvYWQgPyBcIm92ZXJsb2FkXCIgOiAodGhpcy51bmRlcmxvYWQgPyBcInVuZGVybG9hZFwiIDogXCJub3JtYWxcIikpO1xuICAgICAgICByZXR1cm4gdGhpcy5fbV9vcGVyYXRpb247XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gU3RhdHVzO1xuICB9KSgpO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRXM1MTkyMi5wcm90b3R5cGUsICdzdGF0dXMnLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLl9tX3N0YXR1cyAhPT0gdW5kZWZpbmVkKVxuICAgICAgICByZXR1cm4gdGhpcy5fbV9zdGF0dXM7XG4gICAgICB0aGlzLl9tX3N0YXR1cyA9IG5ldyBTdGF0dXModGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QpO1xuICAgICAgcmV0dXJuIHRoaXMuX21fc3RhdHVzO1xuICAgIH1cbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFczUxOTIyLnByb3RvdHlwZSwgJ2Z1bmMnLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLl9tX2Z1bmMgIT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXMuX21fZnVuYztcbiAgICAgIHRoaXMuX21fZnVuYyA9ICh0aGlzLnJhd0Z1bmMgXiA0OCk7XG4gICAgICByZXR1cm4gdGhpcy5fbV9mdW5jO1xuICAgIH1cbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFczUxOTIyLnByb3RvdHlwZSwgJ2RpZ2l0cycsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuX21fZGlnaXRzICE9PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzLl9tX2RpZ2l0cztcbiAgICAgIHZhciBfcG9zID0gdGhpcy5faW8ucG9zO1xuICAgICAgdGhpcy5faW8uc2VlaygxKTtcbiAgICAgIHRoaXMuX3Jhd19fbV9kaWdpdHMgPSB0aGlzLl9pby5yZWFkQnl0ZXMoNSk7XG4gICAgICB0aGlzLl9tX2RpZ2l0cyA9IEthaXRhaVN0cmVhbS5wcm9jZXNzWG9yT25lKHRoaXMuX3Jhd19fbV9kaWdpdHMsIDQ4KTtcbiAgICAgIHRoaXMuX2lvLnNlZWsoX3Bvcyk7XG4gICAgICByZXR1cm4gdGhpcy5fbV9kaWdpdHM7XG4gICAgfVxuICB9KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEVzNTE5MjIucHJvdG90eXBlLCAnb3B0aW9ucycsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuX21fb3B0aW9ucyAhPT0gdW5kZWZpbmVkKVxuICAgICAgICByZXR1cm4gdGhpcy5fbV9vcHRpb25zO1xuICAgICAgdGhpcy5fbV9vcHRpb25zID0gbmV3IE9wdGlvbnModGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QpO1xuICAgICAgcmV0dXJuIHRoaXMuX21fb3B0aW9ucztcbiAgICB9XG4gIH0pO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRXM1MTkyMi5wcm90b3R5cGUsICdyYW5nZScsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuX21fcmFuZ2UgIT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXMuX21fcmFuZ2U7XG4gICAgICBzd2l0Y2ggKCgodGhpcy5yYXdSYW5nZSBeIDQ4KSB8ICgodGhpcy5yYXdGdW5jIF4gNDgpIDw8IDQpKSkge1xuICAgICAgY2FzZSAxNzc6XG4gICAgICAgIHRoaXMuX21fcmFuZ2UgPSBuZXcgQmFzZVJhbmdlKHRoaXMuX2lvLCB0aGlzLCB0aGlzLl9yb290LCBcIlZcIiwgMS4wLCAzLCBcInZvbHRhZ2VcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAwOlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJBXCIsIDEuMCwgMywgXCJjdXJyZW50XCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTQ2OlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJBXCIsIDEuMCwgMiwgXCJjdXJyZW50XCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjI0OlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VBZHBSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgRXM1MTkyMi5BZHBSYW5nZXMuQURQMCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzNTpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwia0h6XCIsIDEwMDAuMCwgMiwgXCJmcmVxdWVuY3lcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzMjpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiSHpcIiwgMS4wLCAyLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDk2OlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJuRlwiLCAxRS05LCAzLCBcImNhcGFjaXRhbmNlXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjA5OlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJcXHhiNUFcIiwgMC4wMDAwMDEsIDEsIFwiY3VycmVudFwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDk3OlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJuRlwiLCAxRS05LCAyLCBcImNhcGFjaXRhbmNlXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTQ1OlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJBXCIsIDEuMCwgMywgXCJjdXJyZW50XCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNTI6XG4gICAgICAgIHRoaXMuX21fcmFuZ2UgPSBuZXcgQmFzZVJhbmdlKHRoaXMuX2lvLCB0aGlzLCB0aGlzLl9yb290LCBcIk1cXHUwM2E5XCIsIDEwMDAwMDAuMCwgNCwgXCJyZXNpc3RhbmNlXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTAxOlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJtRlwiLCAwLjAwMSwgNCwgXCJjYXBhY2l0YW5jZVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDE0NDpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiQVwiLCAxLjAsIDQsIFwiY3VycmVudFwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEwMDpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiXFx4YjVGXCIsIDAuMDAwMDAxLCAyLCBcImNhcGFjaXRhbmNlXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgOTg6XG4gICAgICAgIHRoaXMuX21fcmFuZ2UgPSBuZXcgQmFzZVJhbmdlKHRoaXMuX2lvLCB0aGlzLCB0aGlzLl9yb290LCBcIlxceGI1RlwiLCAwLjAwMDAwMSwgNCwgXCJjYXBhY2l0YW5jZVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDIwODpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiXFx4YjVBXCIsIDAuMDAwMDAxLCAyLCBcImN1cnJlbnRcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzMzpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiSHpcIiwgMS4wLCAxLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEwMzpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwibUZcIiwgMC4wMDEsIDIsIFwiY2FwYWNpdGFuY2VcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA5OTpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiXFx4YjVGXCIsIDAuMDAwMDAxLCAzLCBcImNhcGFjaXRhbmNlXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTgwOlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJtVlwiLCAwLjAwMSwgMiwgXCJ2b2x0YWdlXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNTE6XG4gICAgICAgIHRoaXMuX21fcmFuZ2UgPSBuZXcgQmFzZVJhbmdlKHRoaXMuX2lvLCB0aGlzLCB0aGlzLl9yb290LCBcImtcXHUwM2E5XCIsIDEwMDAuMCwgMiwgXCJyZXNpc3RhbmNlXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjI3OlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VBZHBSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgRXM1MTkyMi5BZHBSYW5nZXMuQURQMyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA0ODpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiXFx1MDNhOVwiLCAxLjAsIDIsIFwicmVzaXN0YW5jZVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDE3ODpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiVlwiLCAxLjAsIDIsIFwidm9sdGFnZVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDUzOlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJNXFx1MDNhOVwiLCAxMDAwMDAwLjAsIDMsIFwicmVzaXN0YW5jZVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDE3NjpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiVlwiLCAxLjAsIDQsIFwidm9sdGFnZVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM4OlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJNSHpcIiwgMTAwMDAwMC4wLCAyLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDE0ODpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiQVwiLCAxLjAsIDAsIFwiY3VycmVudFwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI0MTpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwibUFcIiwgMC4wMDEsIDIsIFwiY3VycmVudFwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDIyNjpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlQWRwUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIEVzNTE5MjIuQWRwUmFuZ2VzLkFEUDIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTc5OlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJWXCIsIDEuMCwgMSwgXCJ2b2x0YWdlXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjQwOlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJtQVwiLCAwLjAwMSwgMywgXCJjdXJyZW50XCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjI1OlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VBZHBSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgRXM1MTkyMi5BZHBSYW5nZXMuQURQMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzNzpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiTUh6XCIsIDEwMDAwMDAuMCwgMywgXCJmcmVxdWVuY3lcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzNjpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiTUh6XCIsIDEwMDAwMDAuMCwgNCwgXCJmcmVxdWVuY3lcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxNjpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiVlwiLCAxLjAsIDQsIFwiZGlvZGVcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxNDc6XG4gICAgICAgIHRoaXMuX21fcmFuZ2UgPSBuZXcgQmFzZVJhbmdlKHRoaXMuX2lvLCB0aGlzLCB0aGlzLl9yb290LCBcIkFcIiwgMS4wLCAxLCBcImN1cnJlbnRcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MDpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiXFx1MDNhOVwiLCAxLjAsIDIsIFwiY29udGludWl0eVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEwMjpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwibUZcIiwgMC4wMDEsIDMsIFwiY2FwYWNpdGFuY2VcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA0OTpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwia1xcdTAzYTlcIiwgMTAwMC4wLCA0LCBcInJlc2lzdGFuY2VcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzNDpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwia0h6XCIsIDEwMDAuMCwgMywgXCJmcmVxdWVuY3lcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA1NDpcbiAgICAgICAgdGhpcy5fbV9yYW5nZSA9IG5ldyBCYXNlUmFuZ2UodGhpcy5faW8sIHRoaXMsIHRoaXMuX3Jvb3QsIFwiTVxcdTAzYTlcIiwgMTAwMDAwMC4wLCAyLCBcInJlc2lzdGFuY2VcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyMjg6XG4gICAgICAgIHRoaXMuX21fcmFuZ2UgPSBuZXcgQmFzZUFkcFJhbmdlKHRoaXMuX2lvLCB0aGlzLCB0aGlzLl9yb290LCBFczUxOTIyLkFkcFJhbmdlcy5BRFA0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDUwOlxuICAgICAgICB0aGlzLl9tX3JhbmdlID0gbmV3IEJhc2VSYW5nZSh0aGlzLl9pbywgdGhpcywgdGhpcy5fcm9vdCwgXCJrXFx1MDNhOVwiLCAxMDAwLjAsIDMsIFwicmVzaXN0YW5jZVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5fbV9yYW5nZTtcbiAgICB9XG4gIH0pO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRXM1MTkyMi5wcm90b3R5cGUsICdwcmVjaXNpb24nLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLl9tX3ByZWNpc2lvbiAhPT0gdW5kZWZpbmVkKVxuICAgICAgICByZXR1cm4gdGhpcy5fbV9wcmVjaXNpb247XG4gICAgICB0aGlzLl9tX3ByZWNpc2lvbiA9ICh0aGlzLnJhbmdlLnByZWNpc2lvbiA9PSAwID8gMS4wIDogKHRoaXMucmFuZ2UucHJlY2lzaW9uID09IDEgPyAwLjEgOiAodGhpcy5yYW5nZS5wcmVjaXNpb24gPT0gMiA/IDAuMDEgOiAodGhpcy5yYW5nZS5wcmVjaXNpb24gPT0gMyA/IDAuMDAxIDogMC4wMDAxKSkpKTtcbiAgICAgIHJldHVybiB0aGlzLl9tX3ByZWNpc2lvbjtcbiAgICB9XG4gIH0pO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRXM1MTkyMi5wcm90b3R5cGUsICd2YWx1ZScsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuX21fdmFsdWUgIT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXMuX21fdmFsdWU7XG4gICAgICBpZiAoICgodGhpcy5mdW5jICE9IEVzNTE5MjIuRnVuY3Rpb25zLlRFTVBFUkFUVVJFKSAmJiAodGhpcy5mdW5jICE9IEVzNTE5MjIuRnVuY3Rpb25zLkFEUCkpICkge1xuICAgICAgICB0aGlzLl9tX3ZhbHVlID0gKCgoKCgoKCgodGhpcy5yYXdEaWdpdDAgXiA0OCkgKiAxMDAwMCkgKyAoKHRoaXMucmF3RGlnaXQxIF4gNDgpICogMTAwMCkpICsgKCh0aGlzLnJhd0RpZ2l0MiBeIDQ4KSAqIDEwMCkpICsgKCh0aGlzLnJhd0RpZ2l0MyBeIDQ4KSAqIDEwKSkgKyAodGhpcy5yYXdEaWdpdDQgXiA0OCkpICogdGhpcy5yYW5nZS5tdWx0aXBsaWVyKSAqIHRoaXMucHJlY2lzaW9uKSAqIHRoaXMuc3RhdHVzLnNpZ25NdWx0aXBsaWVyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLl9tX3ZhbHVlO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIEVzNTE5MjI7XG59KSgpO1xucmV0dXJuIEVzNTE5MjI7XG59KSk7XG4iLCJpbXBvcnQge2NvbmNhdE1hcCwgbWFwLCBtYXBUbywgdGFrZSwgdGFwfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge2Zyb21FdmVudCwgdXNpbmcsIG9mLCBpaWZ9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtyeFRvU3RyZWFtLCBzdHJlYW1Ub1J4fSBmcm9tICdyeGpzLXN0cmVhbSc7XG5cbmltcG9ydCBCeXRlTGVuZ3RoIGZyb20gJ0BzZXJpYWxwb3J0L3BhcnNlci1ieXRlLWxlbmd0aCc7XG5pbXBvcnQgRVM1MTkyMiBmcm9tICcuLi92ZW5kb3IvZXM1MTkyMi5qcyc7XG5pbXBvcnQge0thaXRhaVN0cmVhbX0gZnJvbSAna2FpdGFpLXN0cnVjdCc7XG5pbXBvcnQgU2VyaWFsUG9ydCBmcm9tICdzZXJpYWxwb3J0JztcbmltcG9ydCB7Y29uZmlnIGFzIGRvdGVudkNvbmZpZ30gZnJvbSAnZG90ZW52JztcbmltcG9ydCBjcmVhdGVEZWJ1Z2dlciBmcm9tICdkZWJ1Zyc7XG5cbmRvdGVudkNvbmZpZygpO1xuXG5jb25zdCBkZWJ1ZyA9IGNyZWF0ZURlYnVnZ2VyKCdlczUxOTIyJyk7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1BPUlQgPSAnL2Rldi90dHlVU0IwJztcblxuY29uc3QgZnJvbUV2ZW50T25jZSA9ICguLi5hcmdzKSA9PiBmcm9tRXZlbnQoLi4uYXJncykucGlwZSh0YWtlKDEpKTtcblxuY29uc3QgY3JlYXRlUHJvdG9jb2xTdHJlYW0gPSBidWYgPT4gbmV3IEVTNTE5MjIobmV3IEthaXRhaVN0cmVhbShidWYpKTtcblxuY29uc3QgY3JlYXRlRml4ZWRQcmVjaXNpb25Qcm94eSA9IHByb3RvY29sU3RyZWFtID0+XG4gIG5ldyBQcm94eShwcm90b2NvbFN0cmVhbSwge1xuICAgIGdldCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IFJlZmxlY3QuZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpO1xuICAgICAgcmV0dXJuIHByb3AgPT09ICd2YWx1ZSdcbiAgICAgICAgPyBwYXJzZUZsb2F0KHZhbHVlLnRvRml4ZWQodGFyZ2V0LnJhbmdlLnByZWNpc2lvbikpXG4gICAgICAgIDogdmFsdWU7XG4gICAgfVxuICB9KTtcblxuY29uc3QgcGFyc2UgPSAoKSA9PiBvYnNlcnZhYmxlID0+XG4gIG9ic2VydmFibGUucGlwZShcbiAgICB0YXAoYnVmID0+IGRlYnVnKGByZWNlaXZlZCBCdWZmZXJgLCBidWYpKSxcbiAgICBtYXAoYnVmID0+IGNyZWF0ZUZpeGVkUHJlY2lzaW9uUHJveHkoY3JlYXRlUHJvdG9jb2xTdHJlYW0oYnVmKSkpXG4gICk7XG5cbmNvbnN0IGNyZWF0ZVNlcmlhbFBvcnRTdWJzY3JpYmVyID0gc2VyaWFsUG9ydCA9PiB7XG4gIGNvbnN0IHVuc3Vic2NyaWJlID0gKCkgPT4ge1xuICAgIGRlYnVnKGByZXF1ZXN0IHJlY2VpdmVkIHRvIGNsb3NlIHBvcnQgYXQgJHtzZXJpYWxQb3J0LnBhdGh9YCk7XG4gICAgaWYgKHNlcmlhbFBvcnQuaXNPcGVuKSB7XG4gICAgICBzZXJpYWxQb3J0LmNsb3NlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnKGBwb3J0IGF0ICR7c2VyaWFsUG9ydC5wYXRofSB3YXMgYWxyZWFkeSBjbG9zZWRgKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiBuZXcgUHJveHkoc2VyaWFsUG9ydCwge1xuICAgIGdldDogKHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpID0+IHtcbiAgICAgIHJldHVybiBwcm9wID09PSAndW5zdWJzY3JpYmUnXG4gICAgICAgID8gdW5zdWJzY3JpYmVcbiAgICAgICAgOiBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKTtcbiAgICB9XG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGZyb21TZXJpYWxQb3J0ID0gKFxuICBwb3J0ID0gcHJvY2Vzcy5lbnYuRVM1MTkyMl9QT1JUIHx8IERFRkFVTFRfUE9SVCxcbiAgb3B0cyA9IHt9XG4pID0+XG4gIHVzaW5nKFxuICAgICgpID0+IHtcbiAgICAgIGNvbnN0IHNlcmlhbFBvcnQgPSBjcmVhdGVTZXJpYWxQb3J0U3Vic2NyaWJlcihcbiAgICAgICAgbmV3IFNlcmlhbFBvcnQocG9ydCwge1xuICAgICAgICAgIGJhdWRSYXRlOiAxOTIwMCxcbiAgICAgICAgICBkYXRhQml0czogNyxcbiAgICAgICAgICBwYXJpdHk6ICdvZGQnLFxuICAgICAgICAgIC4uLm9wdHMsXG4gICAgICAgICAgYXV0b09wZW46IGZhbHNlXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgZGVidWcoYGluc3RhbnRpYXRlZCBTZXJpYWxQb3J0IGF0IHBhdGggJHtwb3J0fWApO1xuICAgICAgcmV0dXJuIHNlcmlhbFBvcnQ7XG4gICAgfSxcbiAgICBzZXJpYWxQb3J0ID0+IHtcbiAgICAgIGRlYnVnKGBvcGVuaW5nIHBvcnQgYXQgcGF0aCAke3BvcnR9YCk7XG4gICAgICBzZXJpYWxQb3J0Lm9wZW4oKTtcbiAgICAgIHJldHVybiBmcm9tRXZlbnRPbmNlKHNlcmlhbFBvcnQsICdvcGVuJykucGlwZShcbiAgICAgICAgdGFwKCgpID0+IHtcbiAgICAgICAgICBkZWJ1ZyhgcG9ydCBhdCAke3NlcmlhbFBvcnQucGF0aH0gb3BlbmApO1xuICAgICAgICAgIHNlcmlhbFBvcnQuc2V0KHtydHM6