var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/biquad/Coefficients.ts var FilterType = { SinglePoleLowPassApprox: 0, SinglePoleLowPass: 1, LowPass: 2, HighPass: 3, BandPass: 4, Notch: 5, AllPass: 6, LowShelf: 7, HighShelf: 8, PeakingEQ: 9 }; var Q_BUTTERWORTH = Math.SQRT1_2; var _Coefficients = class _Coefficients { constructor(data) { // Denominator coefficients __publicField(this, "a1", 0); __publicField(this, "a2", 0); // Nominator coefficients __publicField(this, "b0", 0); __publicField(this, "b1", 0); __publicField(this, "b2", 0); if (data) { this.a1 = data.a1; this.a2 = data.a2; this.b0 = data.b0; this.b1 = data.b1; this.b2 = data.b2; } } static from(filter, samplingFreq, cutoffFreq, Q, dbGain = -10) { if (2 * cutoffFreq > samplingFreq) { throw new Error(`Cutoff frequency is too big!`); } if (Q < 0) { throw new Error(`Q may not be negative`); } const omega = 2 * Math.PI * cutoffFreq / samplingFreq; const bqf = typeof filter === "string" ? FilterType[filter] : filter; switch (bqf) { case FilterType.SinglePoleLowPassApprox: { const alpha = omega / (omega + 1); return new _Coefficients({ a1: alpha - 1, a2: 0, b0: alpha, b1: 0, b2: 0 }); } case FilterType.SinglePoleLowPass: { const omega_t = Math.tan(omega / 2); const a0 = 1 + omega_t; return new _Coefficients({ a1: (omega_t - 1) / a0, a2: 0, b0: omega_t / a0, b1: omega_t / a0, b2: 0 }); } case FilterType.LowPass: { const omega_s = Math.sin(omega); const omega_c = Math.cos(omega); const alpha = omega_s / (2 * Q); const b0 = (1 - omega_c) * 0.5; const b1 = 1 - omega_c; const b2 = (1 - omega_c) * 0.5; const a0 = 1 + alpha; const a1 = -2 * omega_c; const a2 = 1 - alpha; const div = 1 / a0; return new _Coefficients({ a1: a1 * div, a2: a2 * div, b0: b0 * div, b1: b1 * div, b2: b2 * div }); } case FilterType.HighPass: { const omega_s = Math.sin(omega); const omega_c = Math.cos(omega); const alpha = omega_s / (2 * Q); const b0 = (1 + omega_c) * 0.5; const b1 = -(1 + omega_c); const b2 = (1 + omega_c) * 0.5; const a0 = 1 + alpha; const a1 = -2 * omega_c; const a2 = 1 - alpha; const div = 1 / a0; return new _Coefficients({ a1: a1 * div, a2: a2 * div, b0: b0 * div, b1: b1 * div, b2: b2 * div }); } case FilterType.Notch: { const omega_s = Math.sin(omega); const omega_c = Math.cos(omega); const alpha = omega_s / (2 * Q); const b0 = 1; const b1 = -2 * omega_c; const b2 = 1; const a0 = 1 + alpha; const a1 = -2 * omega_c; const a2 = 1 - alpha; const div = 1 / a0; return new _Coefficients({ a1: a1 * div, a2: a2 * div, b0: b0 * div, b1: b1 * div, b2: b2 * div }); } case FilterType.BandPass: { const omega_s = Math.sin(omega); const omega_c = Math.cos(omega); const alpha = omega_s / (2 * Q); const b0 = omega_s / 2; const b1 = 0; const b2 = -(omega_s / 2); const a0 = 1 + alpha; const a1 = -2 * omega_c; const a2 = 1 - alpha; const div = 1 / a0; return new _Coefficients({ a1: a1 * div, a2: a2 * div, b0: b0 * div, b1: b1 * div, b2: b2 * div }); } case FilterType.AllPass: { const omega_s = Math.sin(omega); const omega_c = Math.cos(omega); const alpha = omega_s / (2 * Q); const b0 = 1 - alpha; const b1 = -2 * omega_c; const b2 = 1 + alpha; const a0 = 1 + alpha; const a1 = -2 * omega_c; const a2 = 1 - alpha; return new _Coefficients({ a1: a1 / a0, a2: a2 / a0, b0: b0 / a0, b1: b1 / a0, b2: b2 / a0 }); } case FilterType.LowShelf: { const a = Math.pow(10, dbGain / 40); const omega_s = Math.sin(omega); const omega_c = Math.cos(omega); const alpha = omega_s / (2 * Q); const b0 = a * (a + 1 - (a - 1) * omega_c + 2 * alpha * Math.sqrt(a)); const b1 = 2 * a * (a - 1 - (a + 1) * omega_c); const b2 = a * (a + 1 - (a - 1) * omega_c - 2 * alpha * Math.sqrt(a)); const a0 = a + 1 + (a - 1) * omega_c + 2 * alpha * Math.sqrt(a); const a1 = -2 * (a - 1 + (a + 1) * omega_c); const a2 = a + 1 + (a - 1) * omega_c - 2 * alpha * Math.sqrt(a); return new _Coefficients({ a1: a1 / a0, a2: a2 / a0, b0: b0 / a0, b1: b1 / a0, b2: b2 / a0 }); } case FilterType.HighShelf: { const a = Math.pow(10, dbGain / 40); const omega_s = Math.sin(omega); const omega_c = Math.cos(omega); const alpha = omega_s / (2 * Q); const b0 = a * (a + 1 + (a - 1) * omega_c + 2 * alpha * Math.sqrt(a)); const b1 = -2 * a * (a - 1 + (a + 1) * omega_c); const b2 = a * (a + 1 + (a - 1) * omega_c - 2 * alpha * Math.sqrt(a)); const a0 = a + 1 - (a - 1) * omega_c + 2 * alpha * Math.sqrt(a); const a1 = 2 * (a - 1 - (a + 1) * omega_c); const a2 = a + 1 - (a - 1) * omega_c - 2 * alpha * Math.sqrt(a); return new _Coefficients({ a1: a1 / a0, a2: a2 / a0, b0: b0 / a0, b1: b1 / a0, b2: b2 / a0 }); } case FilterType.PeakingEQ: { const a = Math.pow(10, dbGain / 40); const omega_s = Math.sin(omega); const omega_c = Math.cos(omega); const alpha = omega_s / (2 * Q); const b0 = 1 + alpha * a; const b1 = -2 * omega_c; const b2 = 1 - alpha * a; const a0 = 1 + alpha / a; const a1 = -2 * omega_c; const a2 = 1 - alpha / a; return new _Coefficients({ a1: a1 / a0, a2: a2 / a0, b0: b0 / a0, b1: b1 / a0, b2: b2 / a0 }); } default: throw new TypeError(`Invalid filter type "${filter}"`); } } }; __name(_Coefficients, "Coefficients"); var Coefficients = _Coefficients; // src/biquad/Biquad.ts var _BiquadFilter = class _BiquadFilter { constructor(coefficients) { this.coefficients = coefficients; __publicField(this, "x1", 0); __publicField(this, "x2", 0); __publicField(this, "y1", 0); __publicField(this, "y2", 0); __publicField(this, "s1", 0); __publicField(this, "s2", 0); } setFilter(filter, options) { const coefficients = Coefficients.from( filter, options.fs, options.f0, options.Q, options.gain ); this.update(coefficients); } update(coefficients) { this.coefficients = coefficients; } replace(coefficients) { this.coefficients = coefficients; } reset() { this.x1 = 0; this.x2 = 0; this.y1 = 0; this.y2 = 0; this.s1 = 0; this.s2 = 0; } run(input) { const { a1, a2, b0, b1, b2 } = this.coefficients; const out = b0 * input + b1 * this.x1 + b2 * this.x2 - a1 * this.y1 - a2 * this.y2; this.x2 = this.x1; this.x1 = input; this.y2 = this.y1; this.y1 = out; return out; } runTransposed(input) { const { a1, a2, b0, b1, b2 } = this.coefficients; const out = this.s1 + b0 * input; this.s1 = this.s2 + b1 * input - a1 * out; this.s2 = b2 * input - a2 * out; return out; } }; __name(_BiquadFilter, "BiquadFilter"); var BiquadFilter = _BiquadFilter; // src/utils/Frequency.ts var _Frequency = class _Frequency { constructor(__val) { this.__val = __val; if (typeof __val !== "number" || isNaN(__val) || __val === Infinity) throw new TypeError("Frequency value must be a number"); if (this.__val < 0) throw new Error(`Frequency value cannot be negative (${__val})`); } khz() { return this.__val * 1e3; } mhz() { return this.__val * 1e6; } hz() { return this.__val; } dt() { return 1 / this.__val; } valueOf() { return this.__val; } toString() { return `${this.__val}Hz`; } toJSON() { return this.toString(); } }; __name(_Frequency, "Frequency"); var Frequency = _Frequency; // src/utils/PCMTransformer.ts import { Transform } from "stream"; var _PCMTransformer = class _PCMTransformer extends Transform { constructor(options = {}) { super(options); __publicField(this, "type", "s16le"); __publicField(this, "bits"); __publicField(this, "bytes"); __publicField(this, "extremum"); __publicField(this, "disabled", false); __publicField(this, "sampleRate", 48e3); __publicField(this, "onUpdate", /* @__PURE__ */ __name(() => { }, "onUpdate")); options.type ?? (options.type = "s16le"); this.disabled = !!options.disabled; if (typeof options.sampleRate === "number" && options.sampleRate > 0) { this.sampleRate = options.sampleRate; } switch (options.type) { case "s16be": case "s16le": this.type = options.type; this.bits = 16; break; case "s32be": case "s32le": this.type = options.type; this.bits = 32; break; default: throw new TypeError( `Expected type to be one of ${["s16be", "s16le", "s32be", "s32le"].join(", ")}, got "${options.type}"` ); } this.bytes = this.bits / 8; this.extremum = Math.pow(2, this.bits - 1); } disable() { this.disabled = true; } enable() { this.disabled = false; } toggle() { this.disabled = !this.disabled; return this.disabled; } _readInt(buffer, index) { const method = `readInt${this.type.substring(1).toUpperCase()}`; return buffer[method](index); } _writeInt(buffer, int, index) { const method = `writeInt${this.type.substring(1).toUpperCase()}`; return buffer[method](int, index); } clamp(val, max = this.extremum - 1, min = -this.extremum) { return Math.min(max, Math.max(min, val)); } setSampleRate(rate) { this.sampleRate = rate; return; } }; __name(_PCMTransformer, "PCMTransformer"); var PCMTransformer = _PCMTransformer; // src/biquad/BiquadStream.ts var _BiquadStream = class _BiquadStream extends PCMTransformer { constructor(options = {}) { super(options); __publicField(this, "biquad"); __publicField(this, "cutoff", 80); __publicField(this, "gain", 0); __publicField(this, "biquadFilter"); __publicField(this, "Q", Q_BUTTERWORTH); if ("cutoff" in options) this.cutoff = options.cutoff; if ("gain" in options) this.gain = options.gain; if ("Q" in options) this.Q = options.Q; if ("biquadFilter" in options) { if (typeof options.biquadFilter === "string" || typeof options.biquadFilter === "number") this.biquadFilter = options.filter; if (this.biquadFilter != null) { this.biquad = new BiquadFilter( Coefficients.from( this.biquadFilter, this.sampleRate, this.cutoff, this.Q, this.gain ) ); } } } get filters() { return this.biquadFilter; } set filters(f) { if (f == null || typeof f === "string" || typeof f === "number") { this.update({ filter: f }); } else { throw new TypeError(`Invalid biquad filter type "${f}"`); } } getFilterName() { if (this.biquadFilter == null) return null; if (typeof this.biquadFilter === "string") return this.biquadFilter; return Object.entries(FilterType).find( (r) => r[1] === this.biquadFilter )?.[0]; } update(options) { if ("cutoff" in options) this.cutoff = options.cutoff; if ("gain" in options) this.gain = options.gain; if ("Q" in options) this.Q = options.Q; if ("filter" in options) this.biquadFilter = options.filter; if (this.biquadFilter != null) { this.biquad = new BiquadFilter( Coefficients.from( this.biquadFilter, this.sampleRate, this.cutoff, this.Q, this.gain ) ); } this.onUpdate?.(); } setFilter(filter) { this.update({ filter }); } setQ(Q) { this.update({ Q }); } setCutoff(f0) { this.update({ cutoff: f0 }); } setGain(dB) { this.update({ gain: dB }); } _transform(chunk, encoding, callback) { if (this.disabled || !this.biquad) { this.push(chunk); return callback(); } const endIndex = Math.floor(chunk.length / 2) * 2; const { bytes } = this; for (let sampleIndex = 0; sampleIndex < endIndex; sampleIndex += bytes) { const int = this._readInt(chunk, sampleIndex); const result = this.biquad.run(int); this._writeInt(chunk, this.clamp(result), sampleIndex); } this.push(chunk); return callback(); } }; __name(_BiquadStream, "BiquadStream"); var BiquadStream = _BiquadStream; // src/equalizer/ChannelProcessor.ts var _ChannelProcessor = class _ChannelProcessor { constructor(bandMultipliers) { __publicField(this, "history"); __publicField(this, "bandMultipliers"); __publicField(this, "current"); __publicField(this, "m1"); __publicField(this, "m2"); this.history = new Array(Equalizer.BAND_COUNT * 6).fill(0); this.bandMultipliers = bandMultipliers; this.current = 0; this.m1 = 2; this.m2 = 1; } processInt(int) { let result = int * 0.25; for (let bandIndex = 0; bandIndex < Equalizer.BAND_COUNT; bandIndex++) { const x = bandIndex * 6; const y = x + 3; const coefficients = Equalizer.Coefficients48000[bandIndex]; const bandResult = coefficients.alpha * (int - this.history[x + this.m2]) + coefficients.gamma * this.history[y + this.m1] - coefficients.beta * this.history[y + this.m2]; this.history[x + this.current] = int; this.history[y + this.current] = bandResult; result += bandResult * this.bandMultipliers[bandIndex]; } const val = result * 4; return val; } process(samples, extremum = 131072, bytes = 2, readInt, writeInt) { const endIndex = Math.floor(samples.length / 2) * 2; for (let sampleIndex = 0; sampleIndex < endIndex; sampleIndex += bytes) { const sample = readInt?.(samples, sampleIndex) ?? samples.readInt16LE(sampleIndex); const result = this.processInt(sample); const val = Math.min(extremum - 1, Math.max(-extremum, result)); writeInt?.(samples, val, sampleIndex) ?? samples.writeInt16LE(val, sampleIndex); this.step(); } return samples; } step() { if (++this.current === 3) { this.current = 0; } if (++this.m1 === 3) { this.m1 = 0; } if (++this.m2 === 3) { this.m2 = 0; } } reset() { this.history.fill(0); } }; __name(_ChannelProcessor, "ChannelProcessor"); var ChannelProcessor = _ChannelProcessor; // src/equalizer/Coefficients.ts var _EqualizerCoefficients = class _EqualizerCoefficients { constructor(beta, alpha, gamma) { this.beta = beta; this.alpha = alpha; this.gamma = gamma; } setBeta(v) { this.beta = v; } setAlpha(v) { this.alpha = v; } setGamma(v) { this.gamma = v; } toJSON() { const { alpha, beta, gamma } = this; return { alpha, beta, gamma }; } }; __name(_EqualizerCoefficients, "EqualizerCoefficients"); var EqualizerCoefficients = _EqualizerCoefficients; // src/equalizer/EqualizerConfiguration.ts var _EqualizerConfiguration = class _EqualizerConfiguration { constructor(bandMultipliers) { this.bandMultipliers = bandMultipliers; } setGain(band, value) { if (this.isValidBand(band)) { this.bandMultipliers[band] = Math.max(Math.min(value, 1), -0.25); } } getGain(band) { if (this.isValidBand(band)) { return this.bandMultipliers[band]; } else { return 0; } } isValidBand(band) { return band >= 0 && band < this.bandMultipliers.length; } }; __name(_EqualizerConfiguration, "EqualizerConfiguration"); var EqualizerConfiguration = _EqualizerConfiguration; // src/equalizer/Equalizer.ts var _Equalizer = class _Equalizer extends EqualizerConfiguration { constructor(channelCount, bandMultipliers) { super(bandMultipliers); __publicField(this, "channels", []); __publicField(this, "channelCount"); this.channelCount = channelCount; this.channels = this.createChannelProcessor(); } createChannelProcessor() { return Array.from({ length: this.channelCount }, () => { return new ChannelProcessor(this.bandMultipliers); }); } process(input) { return this.channels.map((c, i) => { const { data, extremum, readInt, writeInt, bytes } = input[i]; return c.process(data, extremum, bytes, readInt, writeInt); }); } }; __name(_Equalizer, "Equalizer"); __publicField(_Equalizer, "BAND_COUNT", 15); __publicField(_Equalizer, "SAMPLE_RATE", 48e3); __publicField(_Equalizer, "Coefficients48000", [ new EqualizerCoefficients(0.99847546664, 76226668143e-14, 1.9984647656), new EqualizerCoefficients(0.99756184654, 0.0012190767289, 1.9975344645), new EqualizerCoefficients(0.99616261379, 0.0019186931041, 1.9960947369), new EqualizerCoefficients(0.99391578543, 0.0030421072865, 1.9937449618), new EqualizerCoefficients(0.99028307215, 0.0048584639242, 1.9898465702), new EqualizerCoefficients(0.98485897264, 0.0075705136795, 1.9837962543), new EqualizerCoefficients(0.97588512657, 0.012057436715, 1.9731772447), new EqualizerCoefficients(0.96228521814, 0.018857390928, 1.9556164694), new EqualizerCoefficients(0.94080933132, 0.029595334338, 1.9242054384), new EqualizerCoefficients(0.90702059196, 0.046489704022, 1.8653476166), new EqualizerCoefficients(0.85868004289, 0.070659978553, 1.7600401337), new EqualizerCoefficients(0.78409610788, 0.10795194606, 1.5450725522), new EqualizerCoefficients(0.68332861002, 0.15833569499, 1.1426447155), new EqualizerCoefficients( 0.55267518228, 0.22366240886, 0.40186190803 ), new EqualizerCoefficients( 0.41811888447, 0.29094055777, -0.70905944223 ) ]); var Equalizer = _Equalizer; // src/equalizer/EqualizerStream.ts var _EqualizerStream = class _EqualizerStream extends PCMTransformer { constructor(options) { super(options); __publicField(this, "bandMultipliers", new Array(Equalizer.BAND_COUNT).fill(0)); __publicField(this, "equalizer"); options = Object.assign( {}, { bandMultiplier: [], channels: 1 }, options || {} ); this.equalizer = new Equalizer(options.channels || 1, this.bandMultipliers); if (Array.isArray(options.bandMultiplier)) this._processBands(options.bandMultiplier); } _processBands(multiplier) { for (const mul of multiplier) { if (mul.band > Equalizer.BAND_COUNT - 1 || mul.band < 0) throw new RangeError( `Band value out of range. Expected >0 & <${Equalizer.BAND_COUNT - 1}, received "${mul.band}"` ); this.equalizer.setGain(mul.band, mul.gain); } this.onUpdate?.(); } _transform(chunk, encoding, callback) { if (this.disabled) { this.push(chunk); return callback(); } this.equalizer.process( [ { data: chunk, extremum: this.extremum, readInt: /* @__PURE__ */ __name((b, idx) => this._readInt(b, idx), "readInt"), writeInt: /* @__PURE__ */ __name((b, i, idx) => this._writeInt(b, i, idx), "writeInt"), bytes: this.bytes } ] ); this.push(chunk); return callback(); } getEQ() { return this.bandMultipliers.map((m, i) => ({ band: i, gain: m })); } setEQ(bands) { this._processBands(bands); } resetEQ() { this._processBands( Array.from( { length: Equalizer.BAND_COUNT }, (_, i) => ({ band: i, gain: 0 }) ) ); } }; __name(_EqualizerStream, "EqualizerStream"); var EqualizerStream = _EqualizerStream; // src/audio/MonoStereoTransformer.ts var _MonoStereoTransformer = class _MonoStereoTransformer extends PCMTransformer { constructor(options) { super(options); __publicField(this, "strategy"); if (!["m2s", "s2m"].includes(options?.strategy)) { throw new TypeError(`Strategy must be "m2s" or "s2m"`); } this.strategy = options.strategy; } setStrategy(strategy) { this.strategy = strategy; } _transform(chunk, encoding, callback) { if (this.disabled) { this.push(chunk); return callback(); } const len = Math.floor(chunk.length / 2) * 2; if (this.strategy === "m2s") { this.push(this.toStereo(chunk, len)); } else { this.push(this.toMono(chunk, len)); } return callback(); } toStereo(sample, len) { const bytes = this.bytes; const stereoBuffer = Buffer.alloc(len * 2); for (let i = 0; i < len; i += bytes) { stereoBuffer[i * 2 + 0] = sample[i]; stereoBuffer[i * 2 + 1] = sample[i + 1]; stereoBuffer[i * 2 + 2] = sample[i]; stereoBuffer[i * 2 + 3] = sample[i + 1]; } return stereoBuffer; } toMono(sample, len) { const bytes = this.bytes; const monoBuffer = Buffer.alloc(Math.floor(len / 2)); for (let i = 0; i < len; i += bytes) { monoBuffer[i] = sample[i * 2 + 0]; monoBuffer[i + 1] = sample[i * 2 + 1]; } return monoBuffer; } }; __name(_MonoStereoTransformer, "MonoStereoTransformer"); var MonoStereoTransformer = _MonoStereoTransformer; // src/audio/transformers/index.ts var transformers_exports = {}; __export(transformers_exports, { applyBiquad: () => applyBiquad, applyEqualization: () => applyEqualization, applyPulsator: () => applyPulsator, applyTremolo: () => applyTremolo, applyVibrato: () => applyVibrato, applyVolume: () => applyVolume }); // src/audio/transformers/biquad.ts function applyBiquad(filterer, int) { return filterer.run(int); } __name(applyBiquad, "applyBiquad"); // src/audio/transformers/dsp.ts function applyPulsator(config, int, channel) { const sin = Math.sin(config.x); const currentChannelVal = channel === 0 ? sin : -sin; const res = int * (currentChannelVal + 1) / 2; config.x += config.dI; return res; } __name(applyPulsator, "applyPulsator"); function applyTremolo(config, int, sampleRate) { const fOffset = 1 - config.depth; const modSignal = fOffset + config.depth * Math.sin(config.phase); config.phase += 2 * Math.PI / sampleRate * config.frequency; return modSignal * int; } __name(applyTremolo, "applyTremolo"); function applyVibrato(config, int, sampleRate) { const fOffset = 1 - config.depth; const modSignal = fOffset + config.depth * Math.sin(2 * Math.PI * config.phase); config.phase += 2 * Math.PI / sampleRate * config.frequency; return modSignal * int; } __name(applyVibrato, "applyVibrato"); function applyVolume(vol, int) { return vol * int; } __name(applyVolume, "applyVolume"); // src/audio/transformers/equalizer.ts function applyEqualization(eq, int) { const processor = eq.channels[0]; const result = processor.processInt(int); processor.step(); return result; } __name(applyEqualization, "applyEqualization"); // src/audio/AudioFilter.ts var AudioFilters = { "8D": "8D", Tremolo: "Tremolo", Vibrato: "Vibrato" }; var AF_NIGHTCORE_RATE = 1.3; var AF_VAPORWAVE_RATE = 0.8; var BASS_EQ_BANDS = Array.from( { length: 3 }, (_, i) => ({ band: i, gain: 0.25 }) ); var _AudioFilter = class _AudioFilter extends PCMTransformer { constructor(options) { super(options); __publicField(this, "filters", []); __publicField(this, "targetSampleRate", this.sampleRate); __publicField(this, "pulsatorConfig", { hz: 0.02, x: 0, dI: 3926990816987241e-21 }); __publicField(this, "tremoloConfig", { phase: 0, depth: 0.5, frequency: 5 }); __publicField(this, "vibratoConfig", { phase: 0, depth: 0.5, frequency: 5 }); if (options && Array.isArray(options.filters)) { this.setFilters(options.filters); } this.onUpdate?.(); } setTargetSampleRate(rate) { this.targetSampleRate = rate || this.sampleRate; return; } setPulsator(hz) { hz /= 4; this.pulsatorConfig.hz = hz; const samplesPerCycle = this.targetSampleRate / (hz * 2 * Math.PI); this.pulsatorConfig.dI = hz === 0 ? 0 : 1 / samplesPerCycle; this.onUpdate?.(); } get pulsator() { return this.pulsatorConfig.hz; } setTremolo({ depth = this.tremoloConfig.depth, frequency = this.tremoloConfig.frequency, phase = this.tremoloConfig.phase }) { if (typeof depth === "number") this.tremoloConfig.depth = depth; if (typeof frequency === "number") this.tremoloConfig.frequency = frequency; if (typeof phase === "number") this.tremoloConfig.phase = phase; this.onUpdate?.(); } setVibrato({ depth = this.vibratoConfig.depth, frequency = this.vibratoConfig.frequency, phase = this.vibratoConfig.phase }) { if (typeof depth === "number") this.vibratoConfig.depth = depth; if (typeof frequency === "number") this.vibratoConfig.frequency = frequency; if (typeof phase === "number") this.vibratoConfig.phase = phase; this.onUpdate?.(); } get tremolo() { return this.tremoloConfig; } setFilters(filters) { if (!Array.isArray(filters) || !filters.every((r) => r in AudioFilters)) { return false; } this.filters = filters; this.onUpdate?.(); return true; } _transform(chunk, encoding, callback) { if (this.disabled || !this.filters.length) { return callback(null, chunk); } const len = Math.floor(chunk.length / 2) * 2; const { bytes } = this; let L = false; for (let i = 0; i < len; i += bytes) { const int = this._readInt(chunk, i); const value = this.applyFilters(int, +(L = !L)); this._writeInt(chunk, this.clamp(value), i); } this.push(chunk); return callback(); } get currentSampleRate() { return this.targetSampleRate || this.sampleRate; } applyFilters(byte, channel) { if (this.filters.length) { for (const filter of this.filters) { if (filter === "8D") { byte = applyPulsator(this.pulsatorConfig, byte, channel); } if (filter === "Tremolo") { byte = applyTremolo(this.tremoloConfig, byte, this.currentSampleRate); } if (filter === "Vibrato") { byte = applyVibrato(this.vibratoConfig, byte, this.currentSampleRate); } } } return byte; } }; __name(_AudioFilter, "AudioFilter"); var AudioFilter = _AudioFilter; // src/audio/PCMResampler.ts var _PCMResampler = class _PCMResampler extends PCMTransformer { constructor(options) { super(options); __publicField(this, "inputSampleRate"); __publicField(this, "channels"); __publicField(this, "buffer"); __publicField(this, "currentFilter", null); this.inputSampleRate = options?.inputSampleRate ?? 48e3; this.channels = options?.channels ?? 2; this.buffer = Buffer.alloc(0); if (this.inputSampleRate < 1) { this.inputSampleRate = 48e3; } if (options?.targetSampleRate) { this.setSampleRate(options?.targetSampleRate); } } setFilter(filter) { if (this.currentFilter === filter) return; switch (filter) { case "nightcore": this.setSampleRate(this.inputSampleRate * 1.25); break; case "vaporwave": this.setSampleRate(this.inputSampleRate * 0.8); break; default: this.setSampleRate(this.inputSampleRate); break; } this.currentFilter = filter; } getParameters() { return { currentFilter: this.currentFilter, inputSampleRate: this.inputSampleRate, channels: this.channels, sampleRate: this.sampleRate }; } toggleFilter(filter) { const same = this.currentFilter === filter; this.setFilter(same ? null : filter); return !same; } getRatio() { if (this.inputSampleRate === 0) return 1; return this.sampleRate / this.inputSampleRate; } resample(input) { const bytesPerFrame = this.bytes * this.channels; const inputFrames = Math.floor(input.length / bytesPerFrame); const outputFrames = Math.floor( inputFrames * this.inputSampleRate / this.sampleRate ); const output = Buffer.alloc(outputFrames * bytesPerFrame); for (let outFrame = 0; outFrame < outputFrames; outFrame++) { const inPos = outFrame * this.sampleRate / this.inputSampleRate; const inFrame = Math.floor(inPos); if (inFrame >= inputFrames - 1 || (inFrame + 1) * bytesPerFrame + (this.channels - 1) * this.bytes > input.length) { break; } const fraction = inPos - inFrame; for (let channel = 0; channel < this.channels; channel++) { const pos1 = inFrame * bytesPerFrame + channel * this.bytes; const pos2 = (inFrame + 1) * bytesPerFrame + channel * this.bytes; if (pos1 + this.bytes > input.length || pos2 + this.bytes > input.length) { continue; } const sample1 = this._readInt(input, pos1); const sample2 = this._readInt(input, pos2); const interpolated = sample1 + fraction * (sample2 - sample1); const clamped = this.clamp(Math.round(interpolated)); const outPos = outFrame * bytesPerFrame + channel * this.bytes; this._writeInt(output, clamped, outPos); } } return output; } _transform(chunk, encoding, callback) { if (this.disabled || this.sampleRate === this.inputSampleRate) { this.push(chunk); callback(); return; } this.buffer = Buffer.concat([this.buffer, chunk]); const bytesPerFrame = this.bytes * this.channels; const minFramesNeeded = Math.ceil( bytesPerFrame * (this.inputSampleRate / this.sampleRate) ); const completeFrames = Math.floor(this.buffer.length / bytesPerFrame) - 1; if (completeFrames >= minFramesNeeded) { const processSize = completeFrames * bytesPerFrame; const toProcess = this.buffer.slice(0, processSize); this.buffer = this.buffer.slice(processSize); const resampled = this.resample(toProcess); this.push(resampled); } callback(); } _flush(callback) { if (this.disabled) { callback(); return; } if (this.buffer.length > 0) { const resampled = this.resample(this.buffer); this.push(resampled); } callback(); } setSampleRate(rate) { if (rate === this.sampleRate) return; if (rate < 1) { throw new RangeError("Sample rate must be greater than 0"); } super.setSampleRate(rate); this.onUpdate(); } }; __name(_PCMResampler, "PCMResampler"); var PCMResampler = _PCMResampler; // src/audio/VolumeTransformer.ts var _VolumeTransformer = class _VolumeTransformer extends PCMTransformer { constructor(options) { super(options); __publicField(this, "_volume", 1); if (typeof options?.volume === "number") { this.setVolume(options.volume); } } get volumeApprox() { return this._volume * 100; } get volume() { return Math.floor(this.volumeApprox); } set volume(volume) { this.setVolume(volume); } setVolume(volume) { if (typeof volume !== "number" || isNaN(volume)) throw new Error( `Expected volume amount to be a number, received ${typeof volume}!` ); if (volume < 0) volume = 0; if (!isFinite(volume)) volume = 100; this._volume = volume / 100; this.onUpdate?.(); return true; } _transform(chunk, encoding, callback) { if (this.disabled || this._volume === 1) { this.push(chunk); return callback(); } const len = Math.floor(chunk.length / 2) * 2; const { bytes } = this; for (let i = 0; i < len; i += bytes) { const int = this._readInt(chunk, i); const amp = this.clamp(int * this._volume); this._writeInt(chunk, amp, i); } this.push(chunk); return callback(); } toString() { return `${this.volume}%`; } }; __name(_VolumeTransformer, "VolumeTransformer"); var VolumeTransformer = _VolumeTransformer; // src/audio/CompressorTransformer.ts var _CompressorTransformer = class _CompressorTransformer extends PCMTransformer { constructor(options = {}) { super(options); __publicField(this, "threshold"); __publicField(this, "ratio"); __publicField(this, "attack"); __publicField(this, "release"); __publicField(this, "makeupGain"); __publicField(this, "kneeWidth"); __publicField(this, "envelope", 0); __publicField(this, "gainReduction", 1); __publicField(this, "previousGainReduction", 1); this.threshold = options.threshold ?? -20; this.ratio = options.ratio ?? 4; this.attack = options.attack ?? 20; this.release = options.release ?? 100; this.makeupGain = options.makeupGain ?? 0; this.kneeWidth = options.kneeWidth ?? 6; this.attack = Math.exp(-1 / (this.sampleRate * this.attack / 1e3)); this.release = Math.exp(-1 / (this.sampleRate * this.release / 1e3)); } linearToDb(linear) { const val = 20 * Math.log10(Math.max(linear, 1e-6)); return val; } dbToLinear(db) { const val = Math.pow(10, db / 20); return val; } setThreshold(db) { this.threshold = Math.max(-100, Math.min(0, db)); this.onUpdate(); } setRatio(ratio) { this.ratio = Math.max(1, ratio); this.onUpdate(); } setAttack(ms) { this.attack = Math.exp(-1 / (this.sampleRate * Math.max(0.1, ms) / 1e3)); this.onUpdate(); } setRelease(ms) { this.release = Math.exp( -1 / (this.sampleRate * Math.max(0.1, ms) / 1e3) ); this.onUpdate(); } setMakeupGain(db) { this.makeupGain = Math.max(-20, Math.min(20, db)); this.onUpdate(); } setKneeWidth(db) { this.kneeWidth = Math.max(0, Math.min(20, db)); this.onUpdate(); } setCompressor(options) { if (typeof options.threshold === "number") { this.setThreshold(options.threshold); } if (typeof options.ratio === "number") { this.setRatio(options.ratio); } if (typeof options.attack === "number") { this.setAttack(options.attack); } if (typeof options.release === "number") { this.setRelease(options.release); } if (typeof options.makeupGain === "number") { this.setMakeupGain(options.makeupGain); } if (typeof options.kneeWidth === "number") { this.setKneeWidth(options.kneeWidth); } this.onUpdate(); return this.getParameters(); } getParameters() { return { threshold: this.threshold, ratio: this.ratio, attack: this.attack, release: this.release, makeupGain: this.makeupGain, kneeWidth: this.kneeWidth }; } computeGainReduction(inputLevel) { const inputDb = this.linearToDb(inputLevel); let gainReductionDb = 0; if (2 * (inputDb - this.threshold) < -this.kneeWidth) { gainReductionDb = 0; } else if (2 * Math.abs(inputDb - this.threshold) <= this.kneeWidth) { const x = inputDb - this.threshold + this.kneeWidth / 2; gainReductionDb = (1 / this.ratio - 1) * Math.pow(x, 2) / (2 * this.kneeWidth); } else { gainReductionDb = (inputDb - this.threshold) * (1 - 1 / this.ratio); } return this.dbToLinear(-gainReductionDb + this.makeupGain); } processSample(input) { if (this.disabled) return input; const inputFloat = input / this.extremum; const inputLevel = Math.abs(inputFloat); const coeff = inputLevel > this.envelope ? this.attack : this.release; this.envelope = coeff * this.envelope + (1 - coeff) * inputLevel; const targetGainReduction = this.computeGainReduction(this.envelope); this.gainReduction = Math.min( this.previousGainReduction * this.attack + targetGainReduction * (1 - this.attack), targetGainReduction ); this.previousGainReduction = this.gainReduction; const outputFloat = inputFloat * this.gainReduction; return this.clamp(Math.floor(outputFloat * this.extremum)); } _transform(chunk, encoding, callback) { if (this.disabled) { callback(null, chunk); return; } const output = Buffer.alloc(chunk.length); for (let i = 0; i < chunk.length; i += this.bytes) { const sample = this._readInt(chunk, i); const processed = this.processSample(sample); this._writeInt(output, processed, i); } callback(null, output); } }; __name(_CompressorTransformer, "CompressorTransformer"); var CompressorTransformer = _CompressorTransformer; // src/audio/PCMSeekerTransformer.ts import { EventEmitter } from "events"; var _PCMSeekerTransformer = class _PCMSeekerTransformer extends PCMTransformer { constructor(options = { channels: 2, totalDuration: 0 }) { super(options); __publicField(this, "totalDuration"); __publicField(this, "channels"); __publicField(this, "bytesPerFrame"); __publicField(this, "currentPosition", 0); __publicField(this, "seekTarget", null); __publicField(this, "buffer", Buffer.alloc(0)); __publicField(this, "events", new EventEmitter()); if (options.totalDuration == null || options.totalDuration < 0) { throw new Error("totalDuration must be a positive number"); } if (!options.channels || options.channels <= 0) { throw new Error("channels must be a positive number"); } this.totalDuration = options.totalDuration; this.channels = options.channels; if (typeof options.seekTarget === "number" && options.seekTarget > 0) { this.seekTarget = options.seekTarget; } this.updateDependentValues(); } getParameters() { return { currentPosition: this.currentPosition, seekTarget: this.seekTarget, totalDuration: this.totalDuration }; } updateDependentValues() { this.bytesPerFrame = this.bytes * this.channels; if (this.currentPosition > 0) { const currentMs = this.currentPosition / (this.sampleRate / 1e3); this.currentPosition = Math.floor(currentMs / 1e3 * this.sampleRate); } if (this.seekTarget !== null) { const seekMs = this.seekTarget / (this.sampleRate / 1e3); this.seekTarget = Math.floor(seekMs / 1e3 * this.sampleRate); } } /** * Calculate byte position from sample position * @param samplePosition Position in samples * @returns Position in bytes */ sampleToBytePosition(samplePosition) { return samplePosition * this.bytesPerFrame; } setTotalDuration(duration) { if (duration <= 0) { throw new Error("totalDuration must be a positive number"); } this.totalDuration = duration; this.updateDependentValues(); this.onUpdate(); } setSampleRate(rate) { super.setSampleRate(rate); this.updateDependentValues(); this.onUpdate(); } /** * Seek to a specific position in milliseconds * @param ms Position in milliseconds (negative values seek from end) * @returns Actual position in milliseconds after seeking */ seek(ms) { if (this.totalDuration === 0) return 0; if (ms < 0) { ms = Math.max(0, this.totalDuration + ms); } ms = Math.max(0, Math.min(this.totalDuration, ms)); const targetSample = Math.floor(ms / 1e3 * this.sampleRate); if (targetSample < this.currentPosition) { this.buffer = Buffer.alloc(0); const bytePosition = this.sampleToBytePosition(targetSample); this.events.emit("seek", { position: ms, sample: targetSample, bytePosition }); } this.seekTarget = targetSample; return targetSample / this.sampleRate * 1e3; } getPosition() { return this.currentPosition / this.sampleRate * 1e3; } handleSeek(chunk) { if (this.seekTarget === null) return chunk; const chunkStartSample = this.currentPosition; const chunkSamples = Math.floor(chunk.length / this.bytesPerFrame); const chunkEndSample = chunkStartSample + chunkSamples; if (this.seekTarget >= chunkEndSample) { this.currentPosition += chunkSamples; return Buffer.alloc(0); } if (this.seekTarget >= chunkStartSample) { const offsetSamples = this.seekTarget - chunkStartSample; const offsetBytes = offsetSamples * this.bytesPerFrame; this.currentPosition = this.seekTarget; this.seekTarget = null; return chunk.subarray(offsetBytes); } this.currentPosition = this.seekTarget; this.seekTarget = null; return chunk; } _transform(chunk, encoding, callback) { try { if (this.disabled || this.totalDuration === 0) { callback(null, chunk); return; } const combinedBuffer = Buffer.concat([this.buffer, chunk]); const frameCount = Math.floor(combinedBuffer.length / this.bytesPerFrame); const processableBytes = frameCount * this.bytesPerFrame; this.buffer = combinedBuffer.subarray(processableBytes); let processBuffer = combinedBuffer.subarray(0, processableBytes); if (this.seekTarget !== null) { processBuffer = this.handleSeek(processBuffer); } else { this.currentPosition += frameCount; } callback(null, processBuffer); } catch (error) { callback(error); } } _flush(callback) { if (this.buffer.length >= this.bytesPerFrame) { const frameCount = Math.floor(this.buffer.length / this.bytesPerFrame); const processableBytes = frameCount * this.bytesPerFrame; callback(null, this.buffer.subarray(0, processableBytes)); } callback(); } }; __name(_PCMSeekerTransformer, "PCMSeekerTransformer"); var PCMSeekerTransformer = _PCMSeekerTransformer; // src/audio/ReverbTransformer.ts var _ReverbTransformer = class _ReverbTransformer extends PCMTransformer { constructor(options = {}) { super(options); __publicField(this, "roomSize"); __publicField(this, "damping"); __publicField(this, "wetLevel"); __publicField(this, "dryLevel"); __publicField(this, "delayLines"); __publicField(this, "delayLineLength"); __publicField(this, "delayIndices"); __publicField(this, "numDelayLines", 8); __publicField(this, "feedback", 0.84); this.roomSize = options.roomSize ?? 0.5; this.damping = options.damping ?? 0.5; this.wetLevel = options.wetLevel ?? 0.3; this.dryLevel = options.dryLevel ?? 0.7; this.delayLineLength = Math.floor(this.sampleRate * 0.05); this.delayLines = Array.from( { length: this.numDelayLines }, () => new Float32Array(this.delayLineLength) ); this.delayIndices = Array(this.numDelayLines).fill(0); } setRoomSize(size) { this.roomSize = Math.max(0, Math.min(1, size)); this.onUpdate(); } setDamping(damping) { this.damping = Math.max(0, Math.min(1, damping)); this.onUpdate(); } setWetLevel(level) { this.wetLevel = Math.max(0, Math.min(1, level)); this.onUpdate(); } setDryLevel(level) { this.dryLevel = Math.max(0, Math.min(1, level)); this.onUpdate(); } setReverb(options) { if (typeof options.roomSize === "number") { this.setRoomSize(options.roomSize); } if (typeof options.damping === "number") { this.setDamping(options.damping); } if (typeof options.wetLevel === "number") { this.setWetLevel(options.wetLevel); } if (typeof options.dryLevel === "number") { this.setDryLevel(options.dryLevel); } this.onUpdate(); return this.getParameters(); } getParameters() { return { roomSize: this.roomSize, damping: this.damping, wetLevel: this.wetLevel, dryLevel: this.dryLevel }; } processSample(input) { if (this.disabled) return input; const inputFloat = input / this.extremum; let wet = 0; for (let i = 0; i < this.numDelayLines; i++) { const delayLine = this.delayLines[i]; const delayIndex = this.delayIndices[i]; const delayed = delayLine[delayIndex]; const processed = delayed * this.roomSize * (1 - this.damping); delayLine[delayIndex] = inputFloat + processed * this.feedback; this.delayIndices[i] = (delayIndex + 1) % this.delayLineLength; wet += processed; } const output = inputFloat * this.dryLevel + wet * this.wetLevel / this.numDelayLines; return this.clamp(Math.floor(output * this.extremum)); } _transform(chunk, encoding, callback) { if (this.disabled) { callback(null, chunk); return; } const output = Buffer.alloc(chunk.length); for (let i = 0; i < chunk.length; i += this.bytes) { const sample = this._readInt(chunk, i); const processed = this.processSample(sample); this._writeInt(output, processed, i); } callback(null, output); } }; __name(_ReverbTransformer, "ReverbTransformer"); var ReverbTransformer = _ReverbTransformer; // src/FiltersChainBuilder.ts import { pipeline } from "stream"; var _FiltersChain = class _FiltersChain { constructor(presets = {}) { this.presets = presets; __publicField(this, "equalizer", null); __publicField(this, "filters", null); __publicField(this, "biquad", null); __publicField(this, "volume", null); __publicField(this, "resampler", null); __publicField(this, "compressor", null); __publicField(this, "seeker", null); __publicField(this, "reverb", null); __publicField(this, "destination", null); __publicField(this, "source", null); __publicField(this, "onUpdate", /* @__PURE__ */ __name(() => null, "onUpdate")); __publicField(this, "onError", /* @__PURE__ */ __name(() => null, "onError")); } create(src, presets = this.presets) { this.destroy(); this.source = src; const resampler = !presets.resampler?.disabled ? new PCMResampler(presets.resampler) : null; const equalizerStream = !presets.equalizer?.disabled ? new EqualizerStream(presets.equalizer) : null; const dspStream = !presets.dsp?.disabled ? new AudioFilter(presets.dsp) : null; const biquadStream = !presets.biquad?.disabled ? new BiquadStream(presets.biquad) : null; const volumeTransformer = !presets.volume?.disabled ? new VolumeTransformer(presets.volume) : null; const compressor = !presets.compressor?.disabled ? new CompressorTransformer(presets.compressor) : null; const seeker = !presets.seeker?.disabled ? new PCMSeekerTransformer(presets.seeker) : null; const reverb = !presets.reverb?.disabled ? new ReverbTransformer(presets.reverb) : null; this.resampler = resampler; this.equalizer = equalizerStream; this.filters = dspStream; this.biquad = biquadStream; this.volume = volumeTransformer; this.compressor = compressor; this.seeker = seeker; this.reverb = reverb; if (resampler) resampler.onUpdate = this.onUpdate; if (equalizerStream) equalizerStream.onUpdate = this.onUpdate; if (dspStream) dspStream.onUpdate = this.onUpdate; if (biquadStream) biquadStream.onUpdate = this.onUpdate; if (volumeTransformer) volumeTransformer.onUpdate = this.onUpdate; if (compressor) compressor.onUpdate = this.onUpdate; if (seeker) seeker.onUpdate = this.onUpdate; if (reverb) reverb.onUpdate = this.onUpdate; const chains = [ src, resampler, equalizerStream, reverb, dspStream, biquadStream, compressor, volumeTransformer, seeker ].filter(Boolean); if (!chains.length) return src; this.destination = pipeline(...chains, (err) => { if (err) { this.destroy(); if (!err.message.includes("ERR_STREAM_PREMATURE_CLOSE")) this.onError(err); } }); this.destination.once("close", this.destroy.bind(this)); return this.destination; } destroy() { this.resampler?.destroy(); this.equalizer?.destroy(); this.biquad?.destroy(); this.filters?.destroy(); this.volume?.destroy(); this.compressor?.destroy(); this.seeker?.destroy(); this.reverb?.destroy(); this.destination?.destroy(); this.source?.destroy(); this.resampler?.removeAllListeners(); this.equalizer?.removeAllListeners(); this.biquad?.removeAllListeners(); this.filters?.removeAllListeners(); this.volume?.removeAllListeners(); this.compressor?.removeAllListeners(); this.seeker?.removeAllListeners(); this.reverb?.removeAllListeners(); this.destination?.removeAllListeners(); this.source?.removeAllListeners(); this.resampler = null; this.equalizer = null; this.biquad = null; this.filters = null; this.volume = null; this.compressor = null; this.seeker = null; this.reverb = null; this.destination = null; this.source = null; } }; __name(_FiltersChain, "FiltersChain"); var FiltersChain = _FiltersChain; // src/version.ts var version = ( /* @__MACRO__ getVersion */ "7.2.0" ); export { AF_NIGHTCORE_RATE, AF_VAPORWAVE_RATE, AudioFilter, AudioFilters, BASS_EQ_BANDS, BiquadFilter, BiquadStream, ChannelProcessor, Coefficients, CompressorTransformer, Equalizer, EqualizerCoefficients, EqualizerConfiguration, EqualizerStream, FilterType, FiltersChain, Frequency, MonoStereoTransformer, transformers_exports as PCMAudioTransformer, PCMResampler, PCMSeekerTransformer, PCMTransformer, Q_BUTTERWORTH, ReverbTransformer, VolumeTransformer, version }; //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2JpcXVhZC9Db2VmZmljaWVudHMudHMiLCAiLi4vc3JjL2JpcXVhZC9CaXF1YWQudHMiLCAiLi4vc3JjL3V0aWxzL0ZyZXF1ZW5jeS50cyIsICIuLi9zcmMvdXRpbHMvUENNVHJhbnNmb3JtZXIudHMiLCAiLi4vc3JjL2JpcXVhZC9CaXF1YWRTdHJlYW0udHMiLCAiLi4vc3JjL2VxdWFsaXplci9DaGFubmVsUHJvY2Vzc29yLnRzIiwgIi4uL3NyYy9lcXVhbGl6ZXIvQ29lZmZpY2llbnRzLnRzIiwgIi4uL3NyYy9lcXVhbGl6ZXIvRXF1YWxpemVyQ29uZmlndXJhdGlvbi50cyIsICIuLi9zcmMvZXF1YWxpemVyL0VxdWFsaXplci50cyIsICIuLi9zcmMvZXF1YWxpemVyL0VxdWFsaXplclN0cmVhbS50cyIsICIuLi9zcmMvYXVkaW8vTW9ub1N0ZXJlb1RyYW5zZm9ybWVyLnRzIiwgIi4uL3NyYy9hdWRpby90cmFuc2Zvcm1lcnMvaW5kZXgudHMiLCAiLi4vc3JjL2F1ZGlvL3RyYW5zZm9ybWVycy9iaXF1YWQudHMiLCAiLi4vc3JjL2F1ZGlvL3RyYW5zZm9ybWVycy9kc3AudHMiLCAiLi4vc3JjL2F1ZGlvL3RyYW5zZm9ybWVycy9lcXVhbGl6ZXIudHMiLCAiLi4vc3JjL2F1ZGlvL0F1ZGlvRmlsdGVyLnRzIiwgIi4uL3NyYy9hdWRpby9QQ01SZXNhbXBsZXIudHMiLCAiLi4vc3JjL2F1ZGlvL1ZvbHVtZVRyYW5zZm9ybWVyLnRzIiwgIi4uL3NyYy9hdWRpby9Db21wcmVzc29yVHJhbnNmb3JtZXIudHMiLCAiLi4vc3JjL2F1ZGlvL1BDTVNlZWtlclRyYW5zZm9ybWVyLnRzIiwgIi4uL3NyYy9hdWRpby9SZXZlcmJUcmFuc2Zvcm1lci50cyIsICIuLi9zcmMvRmlsdGVyc0NoYWluQnVpbGRlci50cyIsICIuLi9zcmMvdmVyc2lvbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiZXhwb3J0IGNvbnN0IEZpbHRlclR5cGUgPSB7XG4gIFNpbmdsZVBvbGVMb3dQYXNzQXBwcm94OiAwLFxuICBTaW5nbGVQb2xlTG93UGFzczogMSxcbiAgTG93UGFzczogMixcbiAgSGlnaFBhc3M6IDMsXG4gIEJhbmRQYXNzOiA0LFxuICBOb3RjaDogNSxcbiAgQWxsUGFzczogNixcbiAgTG93U2hlbGY6IDcsXG4gIEhpZ2hTaGVsZjogOCxcbiAgUGVha2luZ0VROiA5XG59IGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBCaXF1YWRGaWx0ZXJzID1cbmtleW9mIHR5cGVvZiBGaWx0ZXJUeXBlIHxcbih0eXBlb2YgRmlsdGVyVHlwZSlba2V5b2YgdHlwZW9mIEZpbHRlclR5cGVdO1xuXG5pbnRlcmZhY2UgQ29lZmZpY2llbnRzSW5pdCB7XG4gIGExOiBudW1iZXI7XG4gIGEyOiBudW1iZXI7XG4gIGIwOiBudW1iZXI7XG4gIGIxOiBudW1iZXI7XG4gIGIyOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBRX0JVVFRFUldPUlRIID0gTWF0aC5TUVJUMV8yO1xuXG5leHBvcnQgY2xhc3MgQ29lZmZpY2llbnRzIHtcbiAgLy8gRGVub21pbmF0b3IgY29lZmZpY2llbnRzXG4gIHB1YmxpYyBhMSA9IDA7XG4gIHB1YmxpYyBhMiA9IDA7XG5cbiAgLy8gTm9taW5hdG9yIGNvZWZmaWNpZW50c1xuICBwdWJsaWMgYjAgPSAwO1xuICBwdWJsaWMgYjEgPSAwO1xuICBwdWJsaWMgYjIgPSAwO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihkYXRhPzogQ29lZmZpY2llbnRzSW5pdCkge1xuICAgIGlmIChkYXRhKSB7XG4gICAgICB0aGlzLmExID0gZGF0YS5hMTtcbiAgICAgIHRoaXMuYTIgPSBkYXRhLmEyO1xuICAgICAgdGhpcy5iMCA9IGRhdGEuYjA7XG4gICAgICB0aGlzLmIxID0gZGF0YS5iMTtcbiAgICAgIHRoaXMuYjIgPSBkYXRhLmIyO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgZnJvbShcbiAgZmlsdGVyOiBCaXF1YWRGaWx0ZXJzLFxuICBzYW1wbGluZ0ZyZXE6IG51bWJlcixcbiAgY3V0b2ZmRnJlcTogbnVtYmVyLFxuICBROiBudW1iZXIsXG4gIGRiR2FpbiA9IC0xMClcbiAge1xuICAgIGlmICgyLjAgKiBjdXRvZmZGcmVxID4gc2FtcGxpbmdGcmVxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEN1dG9mZiBmcmVxdWVuY3kgaXMgdG9vIGJpZyFgKTtcbiAgICB9XG5cbiAgICBpZiAoUSA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUSBtYXkgbm90IGJlIG5lZ2F0aXZlYCk7XG4gICAgfVxuXG4gICAgY29uc3Qgb21lZ2EgPSAyLjAgKiBNYXRoLlBJICogY3V0b2ZmRnJlcSAvIHNhbXBsaW5nRnJlcTtcblxuICAgIGNvbnN0IGJxZiA9IHR5cGVvZiBmaWx0ZXIgPT09ICdzdHJpbmcnID8gRmlsdGVyVHlwZVtmaWx0ZXJdIDogZmlsdGVyO1xuXG4gICAgc3dpdGNoIChicWYpIHtcbiAgICAgIGNhc2UgRmlsdGVyVHlwZS5TaW5nbGVQb2xlTG93UGFzc0FwcHJveDp7XG4gICAgICAgICAgY29uc3QgYWxwaGEgPSBvbWVnYSAvIChvbWVnYSArIDEuMCk7XG5cbiAgICAgICAgICByZXR1cm4gbmV3IENvZWZmaWNpZW50cyh7XG4gICAgICAgICAgICBhMTogYWxwaGEgLSAxLjAsXG4gICAgICAgICAgICBhMjogMC4wLFxuICAgICAgICAgICAgYjA6IGFscGhhLFxuICAgICAgICAgICAgYjE6IDAuMCxcbiAgICAgICAgICAgIGIyOiAwLjBcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgY2FzZSBGaWx0ZXJUeXBlLlNpbmdsZVBvbGVMb3dQYXNzOntcbiAgICAgICAgICBjb25zdCBvbWVnYV90ID0gTWF0aC50YW4ob21lZ2EgLyAyLjApO1xuICAgICAgICAgIGNvbnN0IGEwID0gMS4wICsgb21lZ2FfdDtcblxuICAgICAgICAgIHJldHVybiBuZXcgQ29lZmZpY2llbnRzKHtcbiAgICAgICAgICAgIGExOiAob21lZ2FfdCAtIDEuMCkgLyBhMCxcbiAgICAgICAgICAgIGEyOiAwLjAsXG4gICAgICAgICAgICBiMDogb21lZ2FfdCAvIGEwLFxuICAgICAgICAgICAgYjE6IG9tZWdhX3QgLyBhMCxcbiAgICAgICAgICAgIGIyOiAwLjBcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgY2FzZSBGaWx0ZXJUeXBlLkxvd1Bhc3M6e1xuICAgICAgICAgIGNvbnN0IG9tZWdhX3MgPSBNYXRoLnNpbihvbWVnYSk7XG4gICAgICAgICAgY29uc3Qgb21lZ2FfYyA9IE1hdGguY29zKG9tZWdhKTtcbiAgICAgICAgICBjb25zdCBhbHBoYSA9IG9tZWdhX3MgLyAoMi4wICogUSk7XG5cbiAgICAgICAgICBjb25zdCBiMCA9ICgxLjAgLSBvbWVnYV9jKSAqIDAuNTtcbiAgICAgICAgICBjb25zdCBiMSA9IDEuMCAtIG9tZWdhX2M7XG4gICAgICAgICAgY29uc3QgYjIgPSAoMS4wIC0gb21lZ2FfYykgKiAwLjU7XG4gICAgICAgICAgY29uc3QgYTAgPSAxLjAgKyBhbHBoYTtcbiAgICAgICAgICBjb25zdCBhMSA9IC0yLjAgKiBvbWVnYV9jO1xuICAgICAgICAgIGNvbnN0IGEyID0gMS4wIC0gYWxwaGE7XG5cbiAgICAgICAgICBjb25zdCBkaXYgPSAxLjAgLyBhMDtcblxuICAgICAgICAgIHJldHVybiBuZXcgQ29lZmZpY2llbnRzKHtcbiAgICAgICAgICAgIGExOiBhMSAqIGRpdixcbiAgICAgICAgICAgIGEyOiBhMiAqIGRpdixcbiAgICAgICAgICAgIGIwOiBiMCAqIGRpdixcbiAgICAgICAgICAgIGIxOiBiMSAqIGRpdixcbiAgICAgICAgICAgIGIyOiBiMiAqIGRpdlxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICBjYXNlIEZpbHRlclR5cGUuSGlnaFBhc3M6e1xuICAgICAgICAgIGNvbnN0IG9tZWdhX3MgPSBNYXRoLnNpbihvbWVnYSk7XG4gICAgICAgICAgY29uc3Qgb21lZ2FfYyA9IE1hdGguY29zKG9tZWdhKTtcbiAgICAgICAgICBjb25zdCBhbHBoYSA9IG9tZWdhX3MgLyAoMi4wICogUSk7XG5cbiAgICAgICAgICBjb25zdCBiMCA9ICgxLjAgKyBvbWVnYV9jKSAqIDAuNTtcbiAgICAgICAgICBjb25zdCBiMSA9IC0oMS4wICsgb21lZ2FfYyk7XG4gICAgICAgICAgY29uc3QgYjIgPSAoMS4wICsgb21lZ2FfYykgKiAwLjU7XG4gICAgICAgICAgY29uc3QgYTAgPSAxLjAgKyBhbHBoYTtcbiAgICAgICAgICBjb25zdCBhMSA9IC0yLjAgKiBvbWVnYV9jO1xuICAgICAgICAgIGNvbnN0IGEyID0gMS4wIC0gYWxwaGE7XG5cbiAgICAgICAgICBjb25zdCBkaXYgPSAxLjAgLyBhMDtcblxuICAgICAgICAgIHJldHVybiBuZXcgQ29lZmZpY2llbnRzKHtcbiAgICAgICAgICAgIGExOiBhMSAqIGRpdixcbiAgICAgICAgICAgIGEyOiBhMiAqIGRpdixcbiAgICAgICAgICAgIGIwOiBiMCAqIGRpdixcbiAgICAgICAgICAgIGIxOiBiMSAqIGRpdixcbiAgICAgICAgICAgIGIyOiBiMiAqIGRpdlxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICBjYXNlIEZpbHRlclR5cGUuTm90Y2g6e1xuICAgICAgICAgIGNvbnN0IG9tZWdhX3MgPSBNYXRoLnNpbihvbWVnYSk7XG4gICAgICAgICAgY29uc3Qgb21lZ2FfYyA9IE1hdGguY29zKG9tZWdhKTtcbiAgICAgICAgICBjb25zdCBhbHBoYSA9IG9tZWdhX3MgLyAoMi4wICogUSk7XG5cbiAgICAgICAgICBjb25zdCBiMCA9IDEuMDtcbiAgICAgICAgICBjb25zdCBiMSA9IC0yLjAgKiBvbWVnYV9jO1xuICAgICAgICAgIGNvbnN0IGIyID0gMS4wO1xuICAgICAgICAgIGNvbnN0IGEwID0gMS4wICsgYWxwaGE7XG4gICAgICAgICAgY29uc3QgYTEgPSAtMi4wICogb21lZ2FfYztcbiAgICAgICAgICBjb25zdCBhMiA9IDEuMCAtIGFscGhhO1xuXG4gICAgICAgICAgY29uc3QgZGl2ID0gMS4wIC8gYTA7XG5cbiAgICAgICAgICByZXR1cm4gbmV3IENvZWZmaWNpZW50cyh7XG4gICAgICAgICAgICBhMTogYTEgKiBkaXYsXG4gICAgICAgICAgICBhMjogYTIgKiBkaXYsXG4gICAgICAgICAgICBiMDogYjAgKiBkaXYsXG4gICAgICAgICAgICBiMTogYjEgKiBkaXYsXG4gICAgICAgICAgICBiMjogYjIgKiBkaXZcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgY2FzZSBGaWx0ZXJUeXBlLkJhbmRQYXNzOntcbiAgICAgICAgICBjb25zdCBvbWVnYV9zID0gTWF0aC5zaW4ob21lZ2EpO1xuICAgICAgICAgIGNvbnN0IG9tZWdhX2MgPSBNYXRoLmNvcyhvbWVnYSk7XG4gICAgICAgICAgY29uc3QgYWxwaGEgPSBvbWVnYV9zIC8gKDIuMCAqIFEpO1xuXG4gICAgICAgICAgY29uc3QgYjAgPSBvbWVnYV9zIC8gMi4wO1xuICAgICAgICAgIGNvbnN0IGIxID0gMDtcbiAgICAgICAgICBjb25zdCBiMiA9IC0ob21lZ2FfcyAvIDIuMCk7XG4gICAgICAgICAgY29uc3QgYTAgPSAxLjAgKyBhbHBoYTtcbiAgICAgICAgICBjb25zdCBhMSA9IC0yLjAgKiBvbWVnYV9jO1xuICAgICAgICAgIGNvbnN0IGEyID0gMS4wIC0gYWxwaGE7XG5cbiAgICAgICAgICBjb25zdCBkaXYgPSAxLjAgLyBhMDtcblxuICAgICAgICAgIHJldHVybiBuZXcgQ29lZmZpY2llbnRzKHtcbiAgICAgICAgICAgIGExOiBhMSAqIGRpdixcbiAgICAgICAgICAgIGEyOiBhMiAqIGRpdixcbiAgICAgICAgICAgIGIwOiBiMCAqIGRpdixcbiAgICAgICAgICAgIGIxOiBiMSAqIGRpdixcbiAgICAgICAgICAgIGIyOiBiMiAqIGRpdlxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICBjYXNlIEZpbHRlclR5cGUuQWxsUGFzczp7XG4gICAgICAgICAgY29uc3Qgb21lZ2FfcyA9IE1hdGguc2luKG9tZWdhKTtcbiAgICAgICAgICBjb25zdCBvbWVnYV9jID0gTWF0aC5jb3Mob21lZ2EpO1xuICAgICAgICAgIGNvbnN0IGFscGhhID0gb21lZ2FfcyAvICgyLjAgKiBRKTtcblxuICAgICAgICAgIGNvbnN0IGIwID0gMS4wIC0gYWxwaGE7XG4gICAgICAgICAgY29uc3QgYjEgPSAtMi4wICogb21lZ2FfYztcbiAgICAgICAgICBjb25zdCBiMiA9IDEuMCArIGFscGhhO1xuICAgICAgICAgIGNvbnN0IGEwID0gMS4wICsgYWxwaGE7XG4gICAgICAgICAgY29uc3QgYTEgPSAtMi4wICogb21lZ2FfYztcbiAgICAgICAgICBjb25zdCBhMiA9IDEuMCAtIGFscGhhO1xuXG4gICAgICAgICAgcmV0dXJuIG5ldyBDb2VmZmljaWVudHMoe1xuICAgICAgICAgICAgYTE6IGExIC8gYTAsXG4gICAgICAgICAgICBhMjogYTIgLyBhMCxcbiAgICAgICAgICAgIGIwOiBiMCAvIGEwLFxuICAgICAgICAgICAgYjE6IGIxIC8gYTAsXG4gICAgICAgICAgICBiMjogYjIgLyBhMFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICBjYXNlIEZpbHRlclR5cGUuTG93U2hlbGY6e1xuICAgICAgICAgIGNvbnN0IGEgPSBNYXRoLnBvdygxMC4wLCBkYkdhaW4gLyA0MC4wKTtcbiAgICAgICAgICBjb25zdCBvbWVnYV9zID0gTWF0aC5zaW4ob21lZ2EpO1xuICAgICAgICAgIGNvbnN0IG9tZWdhX2MgPSBNYXRoLmNvcyhvbWVnYSk7XG4gICAgICAgICAgY29uc3QgYWxwaGEgPSBvbWVnYV9zIC8gKDIuMCAqIFEpO1xuXG4gICAgICAgICAgY29uc3QgYjAgPVxuICAgICAgICAgIGEgKiAoYSArIDEuMCAtIChhIC0gMS4wKSAqIG9tZWdhX2MgKyAyLjAgKiBhbHBoYSAqIE1hdGguc3FydChhKSk7XG4gICAgICAgICAgY29uc3QgYjEgPSAyLjAgKiBhICogKGEgLSAxLjAgLSAoYSArIDEuMCkgKiBvbWVnYV9jKTtcbiAgICAgICAgICBjb25zdCBiMiA9XG4gICAgICAgICAgYSAqIChhICsgMS4wIC0gKGEgLSAxLjApICogb21lZ2FfYyAtIDIuMCAqIGFscGhhICogTWF0aC5zcXJ0KGEpKTtcbiAgICAgICAgICBjb25zdCBhMCA9IGEgKyAxLjAgKyAoYSAtIDEuMCkgKiBvbWVnYV9jICsgMi4wICogYWxwaGEgKiBNYXRoLnNxcnQoYSk7XG4gICAgICAgICAgY29uc3QgYTEgPSAtMi4wICogKGEgLSAxLjAgKyAoYSArIDEuMCkgKiBvbWVnYV9jKTtcbiAgICAgICAgICBjb25zdCBhMiA9IGEgKyAxLjAgKyAoYSAtIDEuMCkgKiBvbWVnYV9jIC0gMi4wICogYWxwaGEgKiBNYXRoLnNxcnQoYSk7XG5cbiAgICAgICAgICByZXR1cm4gbmV3IENvZWZmaWNpZW50cyh7XG4gICAgICAgICAgICBhMTogYTEgLyBhMCxcbiAgICAgICAgICAgIGEyOiBhMiAvIGEwLFxuICAgICAgICAgICAgYjA6IGIwIC8gYTAsXG4gICAgICAgICAgICBiMTogYjEgLyBhMCxcbiAgICAgICAgICAgIGIyOiBiMiAvIGEwXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgRmlsdGVyVHlwZS5IaWdoU2hlbGY6e1xuICAgICAgICAgIGNvbnN0IGEgPSBNYXRoLnBvdygxMC4wLCBkYkdhaW4gLyA0MC4wKTtcbiAgICAgICAgICBjb25zdCBvbWVnYV9zID0gTWF0aC5zaW4ob21lZ2EpO1xuICAgICAgICAgIGNvbnN0IG9tZWdhX2MgPSBNYXRoLmNvcyhvbWVnYSk7XG4gICAgICAgICAgY29uc3QgYWxwaGEgPSBvbWVnYV9zIC8gKDIuMCAqIFEpO1xuXG4gICAgICAgICAgY29uc3QgYjAgPVxuICAgICAgICAgIGEgKiAoYSArIDEuMCArIChhIC0gMS4wKSAqIG9tZWdhX2MgKyAyLjAgKiBhbHBoYSAqIE1hdGguc3FydChhKSk7XG4gICAgICAgICAgY29uc3QgYjEgPSAtMi4wICogYSAqIChhIC0gMS4wICsgKGEgKyAxLjApICogb21lZ2FfYyk7XG4gICAgICAgICAgY29uc3QgYjIgPVxuICAgICAgICAgIGEgKiAoYSArIDEuMCArIChhIC0gMS4wKSAqIG9tZWdhX2MgLSAyLjAgKiBhbHBoYSAqIE1hdGguc3FydChhKSk7XG4gICAgICAgICAgY29uc3QgYTAgPSBhICsgMS4wIC0gKGEgLSAxLjApICogb21lZ2FfYyArIDIuMCAqIGFscGhhICogTWF0aC5zcXJ0KGEpO1xuICAgICAgICAgIGNvbnN0IGExID0gMi4wICogKGEgLSAxLjAgLSAoYSArIDEuMCkgKiBvbWVnYV9jKTtcbiAgICAgICAgICBjb25zdCBhMiA9IGEgKyAxLjAgLSAoYSAtIDEuMCkgKiBvbWVnYV9jIC0gMi4wICogYWxwaGEgKiBNYXRoLnNxcnQoYSk7XG5cbiAgICAgICAgICByZXR1cm4gbmV3IENvZWZmaWNpZW50cyh7XG4gICAgICAgICAgICBhMTogYTEgLyBhMCxcbiAgICAgICAgICAgIGEyOiBhMiAvIGEwLFxuICAgICAgICAgICAgYjA6IGIwIC8gYTAsXG4gICAgICAgICAgICBiMTogYjEgLyBhMCxcbiAgICAgICAgICAgIGIyOiBiMiAvIGEwXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgRmlsdGVyVHlwZS5QZWFraW5nRVE6e1xuICAgICAgICAgIGNvbnN0IGEgPSBNYXRoLnBvdygxMC4wLCBkYkdhaW4gLyA0MC4wKTtcbiAgICAgICAgICBjb25zdCBvbWVnYV9zID0gTWF0aC5zaW4ob21lZ2EpO1xuICAgICAgICAgIGNvbnN0IG9tZWdhX2MgPSBNYXRoLmNvcyhvbWVnYSk7XG4gICAgICAgICAgY29uc3QgYWxwaGEgPSBvbWVnYV9zIC8gKDIuMCAqIFEpO1xuXG4gICAgICAgICAgY29uc3QgYjAgPSAxLjAgKyBhbHBoYSAqIGE7XG4gICAgICAgICAgY29uc3QgYjEgPSAtMi4wICogb21lZ2FfYztcbiAgICAgICAgICBjb25zdCBiMiA9IDEuMCAtIGFscGhhICogYTtcbiAgICAgICAgICBjb25zdCBhMCA9IDEuMCArIGFscGhhIC8gYTtcbiAgICAgICAgICBjb25zdCBhMSA9IC0yLjAgKiBvbWVnYV9jO1xuICAgICAgICAgIGNvbnN0IGEyID0gMS4wIC0gYWxwaGEgLyBhO1xuXG4gICAgICAgICAgcmV0dXJuIG5ldyBDb2VmZmljaWVudHMoe1xuICAgICAgICAgICAgYTE6IGExIC8gYTAsXG4gICAgICAgICAgICBhMjogYTIgLyBhMCxcbiAgICAgICAgICAgIGIwOiBiMCAvIGEwLFxuICAgICAgICAgICAgYjE6IGIxIC8gYTAsXG4gICAgICAgICAgICBiMjogYjIgLyBhMFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIGZpbHRlciB0eXBlIFwiJHtmaWx0ZXJ9XCJgKTtcbiAgICB9XG4gIH1cbn0iLCAiaW1wb3J0IHsgQmlxdWFkRmlsdGVycywgQ29lZmZpY2llbnRzIH0gZnJvbSAnLi9Db2VmZmljaWVudHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJpcXVhZFNldEZpbHRlclByb3BzIHtcbiAgZjA6IG51bWJlcjtcbiAgZnM6IG51bWJlcjtcbiAgUTogbnVtYmVyO1xuICBnYWluPzogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgQmlxdWFkRmlsdGVyIHtcbiAgcHVibGljIHgxID0gMC4wO1xuICBwdWJsaWMgeDIgPSAwLjA7XG4gIHB1YmxpYyB5MSA9IDAuMDtcbiAgcHVibGljIHkyID0gMC4wO1xuICBwdWJsaWMgczEgPSAwLjA7XG4gIHB1YmxpYyBzMiA9IDAuMDtcblxuICBwdWJsaWMgY29uc3RydWN0b3IocHVibGljIGNvZWZmaWNpZW50czogQ29lZmZpY2llbnRzKSB7fVxuXG4gIHB1YmxpYyBzZXRGaWx0ZXIoZmlsdGVyOiBCaXF1YWRGaWx0ZXJzLCBvcHRpb25zOiBCaXF1YWRTZXRGaWx0ZXJQcm9wcykge1xuICAgIGNvbnN0IGNvZWZmaWNpZW50cyA9IENvZWZmaWNpZW50cy5mcm9tKFxuICAgICAgZmlsdGVyLFxuICAgICAgb3B0aW9ucy5mcyxcbiAgICAgIG9wdGlvbnMuZjAsXG4gICAgICBvcHRpb25zLlEsXG4gICAgICBvcHRpb25zLmdhaW5cbiAgICApO1xuXG4gICAgdGhpcy51cGRhdGUoY29lZmZpY2llbnRzKTtcbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGUoY29lZmZpY2llbnRzOiBDb2VmZmljaWVudHMpIHtcbiAgICB0aGlzLmNvZWZmaWNpZW50cyA9IGNvZWZmaWNpZW50cztcbiAgfVxuXG4gIHB1YmxpYyByZXBsYWNlKGNvZWZmaWNpZW50czogQ29lZmZpY2llbnRzKSB7XG4gICAgdGhpcy5jb2VmZmljaWVudHMgPSBjb2VmZmljaWVudHM7XG4gIH1cblxuICBwdWJsaWMgcmVzZXQoKSB7XG4gICAgdGhpcy54MSA9IDAuMDtcbiAgICB0aGlzLngyID0gMC4wO1xuICAgIHRoaXMueTEgPSAwLjA7XG4gICAgdGhpcy55MiA9IDAuMDtcbiAgICB0aGlzLnMxID0gMC4wO1xuICAgIHRoaXMuczIgPSAwLjA7XG4gIH1cblxuICBwdWJsaWMgcnVuKGlucHV0OiBudW1iZXIpIHtcbiAgICBjb25zdCB7IGExLCBhMiwgYjAsIGIxLCBiMiB9ID0gdGhpcy5jb2VmZmljaWVudHM7XG5cbiAgICBjb25zdCBvdXQgPVxuICAgIGIwICogaW5wdXQgKyBiMSAqIHRoaXMueDEgKyBiMiAqIHRoaXMueDIgLSBhMSAqIHRoaXMueTEgLSBhMiAqIHRoaXMueTI7XG5cbiAgICB0aGlzLngyID0gdGhpcy54MTtcbiAgICB0aGlzLngxID0gaW5wdXQ7XG4gICAgdGhpcy55MiA9IHRoaXMueTE7XG4gICAgdGhpcy55MSA9IG91dDtcblxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICBwdWJsaWMgcnVuVHJhbnNwb3NlZChpbnB1dDogbnVtYmVyKSB7XG4gICAgY29uc3QgeyBhMSwgYTIsIGIwLCBiMSwgYjIgfSA9IHRoaXMuY29lZmZpY2llbnRzO1xuXG4gICAgY29uc3Qgb3V0ID0gdGhpcy5zMSArIGIwICogaW5wdXQ7XG5cbiAgICB0aGlzLnMxID0gdGhpcy5zMiArIGIxICogaW5wdXQgLSBhMSAqIG91dDtcbiAgICB0aGlzLnMyID0gYjIgKiBpbnB1dCAtIGEyICogb3V0O1xuXG4gICAgcmV0dXJuIG91dDtcbiAgfVxufSIsICJleHBvcnQgY2xhc3MgRnJlcXVlbmN5IHtcbiAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgX192YWw6IG51bWJlcikge1xuICAgIGlmICh0eXBlb2YgX192YWwgIT09ICdudW1iZXInIHx8IGlzTmFOKF9fdmFsKSB8fCBfX3ZhbCA9PT0gSW5maW5pdHkpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRnJlcXVlbmN5IHZhbHVlIG11c3QgYmUgYSBudW1iZXInKTtcbiAgICBpZiAodGhpcy5fX3ZhbCA8IDApXG4gICAgdGhyb3cgbmV3IEVycm9yKGBGcmVxdWVuY3kgdmFsdWUgY2Fubm90IGJlIG5lZ2F0aXZlICgke19fdmFsfSlgKTtcbiAgfVxuXG4gIHB1YmxpYyBraHooKSB7XG4gICAgcmV0dXJuIHRoaXMuX192YWwgKiAxMDAwLjA7XG4gIH1cblxuICBwdWJsaWMgbWh6KCkge1xuICAgIHJldHVybiB0aGlzLl9fdmFsICogMV8wMDBfMDAwLjA7XG4gIH1cblxuICBwdWJsaWMgaHooKSB7XG4gICAgcmV0dXJuIHRoaXMuX192YWw7XG4gIH1cblxuICBwdWJsaWMgZHQoKSB7XG4gICAgcmV0dXJuIDEuMCAvIHRoaXMuX192YWw7XG4gIH1cblxuICBwdWJsaWMgdmFsdWVPZigpIHtcbiAgICByZXR1cm4gdGhpcy5fX3ZhbDtcbiAgfVxuXG4gIHB1YmxpYyB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gYCR7dGhpcy5fX3ZhbH1IemA7XG4gIH1cblxuICBwdWJsaWMgdG9KU09OKCkge1xuICAgIHJldHVybiB0aGlzLnRvU3RyaW5nKCk7XG4gIH1cbn0iLCAiaW1wb3J0IHsgVHJhbnNmb3JtLCBUcmFuc2Zvcm1PcHRpb25zIH0gZnJvbSAnc3RyZWFtJztcblxuZXhwb3J0IHR5cGUgUENNVHlwZSA9IGBzJHsxNiB8IDMyfSR7J2wnIHwgJ2InfWVgO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBDTVRyYW5zZm9ybWVyT3B0aW9ucyBleHRlbmRzIFRyYW5zZm9ybU9wdGlvbnMge1xuICB0eXBlPzogUENNVHlwZTtcbiAgZGlzYWJsZWQ/OiBib29sZWFuO1xuICBzYW1wbGVSYXRlPzogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgUENNVHJhbnNmb3JtZXIgZXh0ZW5kcyBUcmFuc2Zvcm0ge1xuICBwdWJsaWMgcmVhZG9ubHkgdHlwZTogUENNVHlwZSA9ICdzMTZsZSc7XG4gIHB1YmxpYyBiaXRzOiBudW1iZXI7XG4gIHB1YmxpYyBieXRlczogbnVtYmVyO1xuICBwdWJsaWMgZXh0cmVtdW06IG51bWJlcjtcbiAgcHVibGljIGRpc2FibGVkID0gZmFsc2U7XG4gIHB1YmxpYyBzYW1wbGVSYXRlID0gNDgwMDA7XG4gIHB1YmxpYyBvblVwZGF0ZSA9ICgpOiB2b2lkID0+IHtcblxuICAgIC8qIG5vb3AgKi99O1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zOiBQQ01UcmFuc2Zvcm1lck9wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuXG4gICAgb3B0aW9ucy50eXBlID8/PSAnczE2bGUnO1xuICAgIHRoaXMuZGlzYWJsZWQgPSAhIW9wdGlvbnMuZGlzYWJsZWQ7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnNhbXBsZVJhdGUgPT09ICdudW1iZXInICYmIG9wdGlvbnMuc2FtcGxlUmF0ZSA+IDApIHtcbiAgICAgIHRoaXMuc2FtcGxlUmF0ZSA9IG9wdGlvbnMuc2FtcGxlUmF0ZTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKG9wdGlvbnMudHlwZSkge1xuICAgICAgY2FzZSAnczE2YmUnOlxuICAgICAgY2FzZSAnczE2bGUnOlxuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuYml0cyA9IDE2O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3MzMmJlJzpcbiAgICAgIGNhc2UgJ3MzMmxlJzpcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLmJpdHMgPSAzMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgIGBFeHBlY3RlZCB0eXBlIHRvIGJlIG9uZSBvZiAkeyhcbiAgICAgICAgICBbJ3MxNmJlJywgJ3MxNmxlJywgJ3MzMmJlJywgJ3MzMmxlJ10gYXMgUENNVHlwZVtdKS5cbiAgICAgICAgICBqb2luKCcsICcpfSwgZ290IFwiJHtvcHRpb25zLnR5cGV9XCJgXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5ieXRlcyA9IHRoaXMuYml0cyAvIDg7XG4gICAgdGhpcy5leHRyZW11bSA9IE1hdGgucG93KDIsIHRoaXMuYml0cyAtIDEpO1xuICB9XG5cbiAgcHVibGljIGRpc2FibGUoKSB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IHRydWU7XG4gIH1cblxuICBwdWJsaWMgZW5hYmxlKCkge1xuICAgIHRoaXMuZGlzYWJsZWQgPSBmYWxzZTtcbiAgfVxuXG4gIHB1YmxpYyB0b2dnbGUoKSB7XG4gICAgdGhpcy5kaXNhYmxlZCA9ICF0aGlzLmRpc2FibGVkO1xuXG4gICAgcmV0dXJuIHRoaXMuZGlzYWJsZWQ7XG4gIH1cblxuICBwdWJsaWMgX3JlYWRJbnQoYnVmZmVyOiBCdWZmZXIsIGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBtZXRob2QgPSBgcmVhZEludCR7dGhpcy50eXBlLlxuICAgIHN1YnN0cmluZygxKS5cbiAgICB0b1VwcGVyQ2FzZSgpfWAgYXMgYHJlYWRJbnQkezE2IHwgMzJ9JHsnTCcgfCAnQid9RWA7XG4gICAgcmV0dXJuIGJ1ZmZlclttZXRob2RdKGluZGV4KTtcbiAgfVxuXG4gIHB1YmxpYyBfd3JpdGVJbnQoYnVmZmVyOiBCdWZmZXIsIGludDogbnVtYmVyLCBpbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgbWV0aG9kID0gYHdyaXRlSW50JHt0aGlzLnR5cGUuXG4gICAgc3Vic3RyaW5nKDEpLlxuICAgIHRvVXBwZXJDYXNlKCl9YCBhcyBgd3JpdGVJbnQkezE2IHwgMzJ9JHsnTCcgfCAnQid9RWA7XG4gICAgcmV0dXJuIGJ1ZmZlclttZXRob2RdKGludCwgaW5kZXgpO1xuICB9XG5cbiAgcHVibGljIGNsYW1wKHZhbDogbnVtYmVyLCBtYXggPSB0aGlzLmV4dHJlbXVtIC0gMSwgbWluID0gLXRoaXMuZXh0cmVtdW0pIHtcbiAgICByZXR1cm4gTWF0aC5taW4obWF4LCBNYXRoLm1heChtaW4sIHZhbCkpO1xuICB9XG5cbiAgcHVibGljIHNldFNhbXBsZVJhdGUocmF0ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5zYW1wbGVSYXRlID0gcmF0ZTtcbiAgICByZXR1cm47XG4gIH1cbn0iLCAiaW1wb3J0IHsgVHJhbnNmb3JtQ2FsbGJhY2sgfSBmcm9tICdzdHJlYW0nO1xuaW1wb3J0IHsgUENNVHJhbnNmb3JtZXIsIFBDTVRyYW5zZm9ybWVyT3B0aW9ucyB9IGZyb20gJy4uL3V0aWxzJztcbmltcG9ydCB7IEJpcXVhZEZpbHRlciB9IGZyb20gJy4vQmlxdWFkJztcbmltcG9ydCB7XG4gIEJpcXVhZEZpbHRlcnMsXG4gIENvZWZmaWNpZW50cyxcbiAgRmlsdGVyVHlwZSxcbiAgUV9CVVRURVJXT1JUSCB9IGZyb21cbicuL0NvZWZmaWNpZW50cyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmlxdWFkU3RyZWFtT3B0aW9ucyBleHRlbmRzIFBDTVRyYW5zZm9ybWVyT3B0aW9ucyB7XG4gIGZpbHRlcj86IEJpcXVhZEZpbHRlcnM7XG4gIFE/OiBudW1iZXI7XG4gIGN1dG9mZj86IG51bWJlcjtcbiAgZ2Fpbj86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCaXF1YWRGaWx0ZXJVcGRhdGVEYXRhIHtcbiAgZmlsdGVyPzogQmlxdWFkRmlsdGVycztcbiAgUT86IG51bWJlcjtcbiAgY3V0b2ZmPzogbnVtYmVyO1xuICBnYWluPzogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgQmlxdWFkU3RyZWFtIGV4dGVuZHMgUENNVHJhbnNmb3JtZXIge1xuICBwdWJsaWMgYmlxdWFkITogQmlxdWFkRmlsdGVyO1xuICBwdWJsaWMgY3V0b2ZmID0gODA7XG4gIHB1YmxpYyBnYWluID0gMDtcbiAgcHVibGljIGJpcXVhZEZpbHRlciE6IEJpcXVhZEZpbHRlcnM7XG4gIHB1YmxpYyBRID0gUV9CVVRURVJXT1JUSDtcbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEJpcXVhZFN0cmVhbU9wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuXG4gICAgaWYgKCdjdXRvZmYnIGluIG9wdGlvbnMpIHRoaXMuY3V0b2ZmID0gb3B0aW9ucy5jdXRvZmYhO1xuICAgIGlmICgnZ2FpbicgaW4gb3B0aW9ucykgdGhpcy5nYWluID0gb3B0aW9ucy5nYWluITtcbiAgICBpZiAoJ1EnIGluIG9wdGlvbnMpIHRoaXMuUSA9IG9wdGlvbnMuUSE7XG4gICAgaWYgKCdiaXF1YWRGaWx0ZXInIGluIG9wdGlvbnMpIHtcbiAgICAgIGlmIChcbiAgICAgIHR5cGVvZiBvcHRpb25zLmJpcXVhZEZpbHRlciA9PT0gJ3N0cmluZycgfHxcbiAgICAgIHR5cGVvZiBvcHRpb25zLmJpcXVhZEZpbHRlciA9PT0gJ251bWJlcicpXG5cbiAgICAgIHRoaXMuYmlxdWFkRmlsdGVyID0gb3B0aW9ucy5maWx0ZXIhO1xuICAgICAgaWYgKHRoaXMuYmlxdWFkRmlsdGVyICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5iaXF1YWQgPSBuZXcgQmlxdWFkRmlsdGVyKFxuICAgICAgICAgIENvZWZmaWNpZW50cy5mcm9tKFxuICAgICAgICAgICAgdGhpcy5iaXF1YWRGaWx0ZXIsXG4gICAgICAgICAgICB0aGlzLnNhbXBsZVJhdGUsXG4gICAgICAgICAgICB0aGlzLmN1dG9mZixcbiAgICAgICAgICAgIHRoaXMuUSxcbiAgICAgICAgICAgIHRoaXMuZ2FpblxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0IGZpbHRlcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuYmlxdWFkRmlsdGVyO1xuICB9XG5cbiAgcHVibGljIHNldCBmaWx0ZXJzKGY6IEJpcXVhZEZpbHRlcnMpIHtcbiAgICBpZiAoZiA9PSBudWxsIHx8IHR5cGVvZiBmID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgZiA9PT0gJ251bWJlcicpIHtcbiAgICAgIHRoaXMudXBkYXRlKHsgZmlsdGVyOiBmIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIGJpcXVhZCBmaWx0ZXIgdHlwZSBcIiR7Zn1cImApO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXRGaWx0ZXJOYW1lKCkge1xuICAgIGlmICh0aGlzLmJpcXVhZEZpbHRlciA9PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICBpZiAodHlwZW9mIHRoaXMuYmlxdWFkRmlsdGVyID09PSAnc3RyaW5nJykgcmV0dXJuIHRoaXMuYmlxdWFkRmlsdGVyO1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhGaWx0ZXJUeXBlKS5maW5kKFxuICAgICAgKHIpID0+IHJbMV0gPT09IHRoaXMuYmlxdWFkRmlsdGVyXG4gICAgKT8uWzBdIGFzIEJpcXVhZEZpbHRlcnM7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlKG9wdGlvbnM6IEJpcXVhZEZpbHRlclVwZGF0ZURhdGEpIHtcbiAgICBpZiAoJ2N1dG9mZicgaW4gb3B0aW9ucykgdGhpcy5jdXRvZmYgPSBvcHRpb25zLmN1dG9mZiE7XG4gICAgaWYgKCdnYWluJyBpbiBvcHRpb25zKSB0aGlzLmdhaW4gPSBvcHRpb25zLmdhaW4hO1xuICAgIGlmICgnUScgaW4gb3B0aW9ucykgdGhpcy5RID0gb3B0aW9ucy5RITtcbiAgICBpZiAoJ2ZpbHRlcicgaW4gb3B0aW9ucykgdGhpcy5iaXF1YWRGaWx0ZXIgPSBvcHRpb25zLmZpbHRlciE7XG5cbiAgICBpZiAodGhpcy5iaXF1YWRGaWx0ZXIgIT0gbnVsbCkge1xuICAgICAgdGhpcy5iaXF1YWQgPSBuZXcgQmlxdWFkRmlsdGVyKFxuICAgICAgICBDb2VmZmljaWVudHMuZnJvbShcbiAgICAgICAgICB0aGlzLmJpcXVhZEZpbHRlcixcbiAgICAgICAgICB0aGlzLnNhbXBsZVJhdGUsXG4gICAgICAgICAgdGhpcy5jdXRvZmYsXG4gICAgICAgICAgdGhpcy5RLFxuICAgICAgICAgIHRoaXMuZ2FpblxuICAgICAgICApXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMub25VcGRhdGU/LigpO1xuICB9XG5cbiAgcHVibGljIHNldEZpbHRlcihmaWx0ZXI6IEJpcXVhZEZpbHRlcnMpIHtcbiAgICB0aGlzLnVwZGF0ZSh7IGZpbHRlciB9KTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRRKFE6IG51bWJlcikge1xuICAgIHRoaXMudXBkYXRlKHsgUSB9KTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRDdXRvZmYoZjA6IG51bWJlcikge1xuICAgIHRoaXMudXBkYXRlKHsgY3V0b2ZmOiBmMCB9KTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRHYWluKGRCOiBudW1iZXIpIHtcbiAgICB0aGlzLnVwZGF0ZSh7IGdhaW46IGRCIH0pO1xuICB9XG5cbiAgcHVibGljIF90cmFuc2Zvcm0oXG4gIGNodW5rOiBCdWZmZXIsXG4gIGVuY29kaW5nOiBCdWZmZXJFbmNvZGluZyxcbiAgY2FsbGJhY2s6IFRyYW5zZm9ybUNhbGxiYWNrKVxuICB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQgfHwgIXRoaXMuYmlxdWFkKSB7XG4gICAgICB0aGlzLnB1c2goY2h1bmspO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgY29uc3QgZW5kSW5kZXggPSBNYXRoLmZsb29yKGNodW5rLmxlbmd0aCAvIDIpICogMjtcbiAgICBjb25zdCB7IGJ5dGVzIH0gPSB0aGlzO1xuXG4gICAgZm9yIChsZXQgc2FtcGxlSW5kZXggPSAwOyBzYW1wbGVJbmRleCA8IGVuZEluZGV4OyBzYW1wbGVJbmRleCArPSBieXRlcykge1xuICAgICAgY29uc3QgaW50ID0gdGhpcy5fcmVhZEludChjaHVuaywgc2FtcGxlSW5kZXgpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5iaXF1YWQucnVuKGludCk7XG4gICAgICB0aGlzLl93cml0ZUludChjaHVuaywgdGhpcy5jbGFtcChyZXN1bHQpLCBzYW1wbGVJbmRleCk7XG4gICAgfVxuXG4gICAgdGhpcy5wdXNoKGNodW5rKTtcbiAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgfVxufSIsICJpbXBvcnQgeyBFcXVhbGl6ZXIgfSBmcm9tICcuL0VxdWFsaXplcic7XG5cbmV4cG9ydCB0eXBlIFJlYWRJbnRDYWxsYmFjayA9IChidWZmZXI6IEJ1ZmZlciwgaW5kZXg6IG51bWJlcikgPT4gbnVtYmVyO1xuZXhwb3J0IHR5cGUgV3JpdGVJbnRDYWxsYmFjayA9IChcbmJ1ZmZlcjogQnVmZmVyLFxuaW50OiBudW1iZXIsXG5pbmRleDogbnVtYmVyKVxuPT4gbnVtYmVyO1xuXG5leHBvcnQgY2xhc3MgQ2hhbm5lbFByb2Nlc3NvciB7XG4gIHB1YmxpYyBoaXN0b3J5OiBudW1iZXJbXTtcbiAgcHVibGljIGJhbmRNdWx0aXBsaWVyczogbnVtYmVyW107XG4gIHB1YmxpYyBjdXJyZW50OiBudW1iZXI7XG4gIHB1YmxpYyBtMTogbnVtYmVyO1xuICBwdWJsaWMgbTI6IG51bWJlcjtcblxuICBwdWJsaWMgY29uc3RydWN0b3IoYmFuZE11bHRpcGxpZXJzOiBudW1iZXJbXSkge1xuICAgIHRoaXMuaGlzdG9yeSA9IG5ldyBBcnJheShFcXVhbGl6ZXIuQkFORF9DT1VOVCAqIDYpLmZpbGwoMCk7XG4gICAgdGhpcy5iYW5kTXVsdGlwbGllcnMgPSBiYW5kTXVsdGlwbGllcnM7XG4gICAgdGhpcy5jdXJyZW50ID0gMDtcbiAgICB0aGlzLm0xID0gMjtcbiAgICB0aGlzLm0yID0gMTtcbiAgfVxuXG4gIHB1YmxpYyBwcm9jZXNzSW50KGludDogbnVtYmVyKSB7XG4gICAgbGV0IHJlc3VsdCA9IGludCAqIDAuMjU7XG5cbiAgICBmb3IgKGxldCBiYW5kSW5kZXggPSAwOyBiYW5kSW5kZXggPCBFcXVhbGl6ZXIuQkFORF9DT1VOVDsgYmFuZEluZGV4KyspIHtcbiAgICAgIGNvbnN0IHggPSBiYW5kSW5kZXggKiA2O1xuICAgICAgY29uc3QgeSA9IHggKyAzO1xuXG4gICAgICBjb25zdCBjb2VmZmljaWVudHMgPSBFcXVhbGl6ZXIuQ29lZmZpY2llbnRzNDgwMDBbYmFuZEluZGV4XTtcblxuICAgICAgY29uc3QgYmFuZFJlc3VsdCA9XG4gICAgICBjb2VmZmljaWVudHMuYWxwaGEgKiAoaW50IC0gdGhpcy5oaXN0b3J5W3ggKyB0aGlzLm0yXSkgK1xuICAgICAgY29lZmZpY2llbnRzLmdhbW1hICogdGhpcy5oaXN0b3J5W3kgKyB0aGlzLm0xXSAtXG4gICAgICBjb2VmZmljaWVudHMuYmV0YSAqIHRoaXMuaGlzdG9yeVt5ICsgdGhpcy5tMl07XG5cbiAgICAgIHRoaXMuaGlzdG9yeVt4ICsgdGhpcy5jdXJyZW50XSA9IGludDtcbiAgICAgIHRoaXMuaGlzdG9yeVt5ICsgdGhpcy5jdXJyZW50XSA9IGJhbmRSZXN1bHQ7XG5cbiAgICAgIHJlc3VsdCArPSBiYW5kUmVzdWx0ICogdGhpcy5iYW5kTXVsdGlwbGllcnNbYmFuZEluZGV4XTtcbiAgICB9XG5cbiAgICBjb25zdCB2YWwgPSByZXN1bHQgKiA0LjA7XG5cbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgcHVibGljIHByb2Nlc3MoXG4gIHNhbXBsZXM6IEJ1ZmZlcixcbiAgZXh0cmVtdW0gPSAxMzEwNzIsXG4gIGJ5dGVzID0gMixcbiAgcmVhZEludD86IFJlYWRJbnRDYWxsYmFjayxcbiAgd3JpdGVJbnQ/OiBXcml0ZUludENhbGxiYWNrKVxuICB7XG4gICAgY29uc3QgZW5kSW5kZXggPSBNYXRoLmZsb29yKHNhbXBsZXMubGVuZ3RoIC8gMikgKiAyO1xuICAgIGZvciAobGV0IHNhbXBsZUluZGV4ID0gMDsgc2FtcGxlSW5kZXggPCBlbmRJbmRleDsgc2FtcGxlSW5kZXggKz0gYnl0ZXMpIHtcbiAgICAgIGNvbnN0IHNhbXBsZSA9XG4gICAgICByZWFkSW50Py4oc2FtcGxlcywgc2FtcGxlSW5kZXgpID8/IHNhbXBsZXMucmVhZEludDE2TEUoc2FtcGxlSW5kZXgpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5wcm9jZXNzSW50KHNhbXBsZSk7XG5cbiAgICAgIGNvbnN0IHZhbCA9IE1hdGgubWluKGV4dHJlbXVtIC0gMSwgTWF0aC5tYXgoLWV4dHJlbXVtLCByZXN1bHQpKTtcbiAgICAgIHdyaXRlSW50Py4oc2FtcGxlcywgdmFsLCBzYW1wbGVJbmRleCkgPz9cbiAgICAgIHNhbXBsZXMud3JpdGVJbnQxNkxFKHZhbCwgc2FtcGxlSW5kZXgpO1xuXG4gICAgICB0aGlzLnN0ZXAoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2FtcGxlcztcbiAgfVxuXG4gIHB1YmxpYyBzdGVwKCkge1xuICAgIGlmICgrK3RoaXMuY3VycmVudCA9PT0gMykge1xuICAgICAgdGhpcy5jdXJyZW50ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoKyt0aGlzLm0xID09PSAzKSB7XG4gICAgICB0aGlzLm0xID0gMDtcbiAgICB9XG5cbiAgICBpZiAoKyt0aGlzLm0yID09PSAzKSB7XG4gICAgICB0aGlzLm0yID0gMDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcmVzZXQoKSB7XG4gICAgdGhpcy5oaXN0b3J5LmZpbGwoMC4wKTtcbiAgfVxufSIsICJleHBvcnQgY2xhc3MgRXF1YWxpemVyQ29lZmZpY2llbnRzIHtcbiAgcHVibGljIGNvbnN0cnVjdG9yKFxuICBwdWJsaWMgYmV0YTogbnVtYmVyLFxuICBwdWJsaWMgYWxwaGE6IG51bWJlcixcbiAgcHVibGljIGdhbW1hOiBudW1iZXIpXG4gIHt9XG5cbiAgcHVibGljIHNldEJldGEodjogbnVtYmVyKSB7XG4gICAgdGhpcy5iZXRhID0gdjtcbiAgfVxuXG4gIHB1YmxpYyBzZXRBbHBoYSh2OiBudW1iZXIpIHtcbiAgICB0aGlzLmFscGhhID0gdjtcbiAgfVxuXG4gIHB1YmxpYyBzZXRHYW1tYSh2OiBudW1iZXIpIHtcbiAgICB0aGlzLmdhbW1hID0gdjtcbiAgfVxuXG4gIHB1YmxpYyB0b0pTT04oKSB7XG4gICAgY29uc3QgeyBhbHBoYSwgYmV0YSwgZ2FtbWEgfSA9IHRoaXM7XG5cbiAgICByZXR1cm4geyBhbHBoYSwgYmV0YSwgZ2FtbWEgfTtcbiAgfVxufSIsICJleHBvcnQgY2xhc3MgRXF1YWxpemVyQ29uZmlndXJhdGlvbiB7XG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihwdWJsaWMgYmFuZE11bHRpcGxpZXJzOiBudW1iZXJbXSkge31cblxuICBwdWJsaWMgc2V0R2FpbihiYW5kOiBudW1iZXIsIHZhbHVlOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5pc1ZhbGlkQmFuZChiYW5kKSkge1xuICAgICAgdGhpcy5iYW5kTXVsdGlwbGllcnNbYmFuZF0gPSBNYXRoLm1heChNYXRoLm1pbih2YWx1ZSwgMS4wKSwgLTAuMjUpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXRHYWluKGJhbmQ6IG51bWJlcikge1xuICAgIGlmICh0aGlzLmlzVmFsaWRCYW5kKGJhbmQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5iYW5kTXVsdGlwbGllcnNbYmFuZF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAwLjA7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGlzVmFsaWRCYW5kKGJhbmQ6IG51bWJlcikge1xuICAgIHJldHVybiBiYW5kID49IDAgJiYgYmFuZCA8IHRoaXMuYmFuZE11bHRpcGxpZXJzLmxlbmd0aDtcbiAgfVxufSIsICJpbXBvcnQge1xuICBDaGFubmVsUHJvY2Vzc29yLFxuICBSZWFkSW50Q2FsbGJhY2ssXG4gIFdyaXRlSW50Q2FsbGJhY2sgfSBmcm9tXG4nLi9DaGFubmVsUHJvY2Vzc29yJztcbmltcG9ydCB7IEVxdWFsaXplckNvZWZmaWNpZW50cyB9IGZyb20gJy4vQ29lZmZpY2llbnRzJztcbmltcG9ydCB7IEVxdWFsaXplckNvbmZpZ3VyYXRpb24gfSBmcm9tICcuL0VxdWFsaXplckNvbmZpZ3VyYXRpb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIENoYW5uZWxQcm9jZXNzb3JJbnB1dCB7XG4gIGRhdGE6IEJ1ZmZlcjtcbiAgcmVhZEludD86IFJlYWRJbnRDYWxsYmFjaztcbiAgd3JpdGVJbnQ/OiBXcml0ZUludENhbGxiYWNrO1xuICBleHRyZW11bT86IG51bWJlcjtcbiAgYnl0ZXM/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBFcXVhbGl6ZXIgZXh0ZW5kcyBFcXVhbGl6ZXJDb25maWd1cmF0aW9uIHtcbiAgcHVibGljIHN0YXRpYyBCQU5EX0NPVU5UID0gMTUgYXMgY29uc3Q7XG4gIHB1YmxpYyBzdGF0aWMgU0FNUExFX1JBVEUgPSA0ODAwMCBhcyBjb25zdDtcbiAgcHVibGljIHN0YXRpYyBDb2VmZmljaWVudHM0ODAwMCA9IFtcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg5Ljk4NDc1NDY2NjRlLTEsIDcuNjIyNjY2ODE0M2UtNCwgMS45OTg0NjQ3NjU2KSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg5Ljk3NTYxODQ2NTRlLTEsIDEuMjE5MDc2NzI4OWUtMywgMS45OTc1MzQ0NjQ1KSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg5Ljk2MTYyNjEzNzllLTEsIDEuOTE4NjkzMTA0MWUtMywgMS45OTYwOTQ3MzY5KSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg5LjkzOTE1Nzg1NDNlLTEsIDMuMDQyMTA3Mjg2NWUtMywgMS45OTM3NDQ5NjE4KSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg5LjkwMjgzMDcyMTVlLTEsIDQuODU4NDYzOTI0MmUtMywgMS45ODk4NDY1NzAyKSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg5Ljg0ODU4OTcyNjRlLTEsIDcuNTcwNTEzNjc5NWUtMywgMS45ODM3OTYyNTQzKSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg5Ljc1ODg1MTI2NTdlLTEsIDEuMjA1NzQzNjcxNWUtMiwgMS45NzMxNzcyNDQ3KSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg5LjYyMjg1MjE4MTRlLTEsIDEuODg1NzM5MDkyOGUtMiwgMS45NTU2MTY0Njk0KSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg5LjQwODA5MzMxMzJlLTEsIDIuOTU5NTMzNDMzOGUtMiwgMS45MjQyMDU0Mzg0KSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg5LjA3MDIwNTkxOTZlLTEsIDQuNjQ4OTcwNDAyMmUtMiwgMS44NjUzNDc2MTY2KSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg4LjU4NjgwMDQyODllLTEsIDcuMDY1OTk3ODU1M2UtMiwgMS43NjAwNDAxMzM3KSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg3Ljg0MDk2MTA3ODhlLTEsIDEuMDc5NTE5NDYwNmUtMSwgMS41NDUwNzI1NTIyKSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyg2LjgzMzI4NjEwMDJlLTEsIDEuNTgzMzU2OTQ5OWUtMSwgMS4xNDI2NDQ3MTU1KSxcbiAgbmV3IEVxdWFsaXplckNvZWZmaWNpZW50cyhcbiAgICA1LjUyNjc1MTgyMjhlLTEsXG4gICAgMi4yMzY2MjQwODg2ZS0xLFxuICAgIDQuMDE4NjE5MDgwM2UtMVxuICApLFxuICBuZXcgRXF1YWxpemVyQ29lZmZpY2llbnRzKFxuICAgIDQuMTgxMTg4ODQ0N2UtMSxcbiAgICAyLjkwOTQwNTU3NzdlLTEsXG4gICAgLTcuMDkwNTk0NDIyM2UtMVxuICApXTtcblxuICBwdWJsaWMgY2hhbm5lbHM6IENoYW5uZWxQcm9jZXNzb3JbXSA9IFtdO1xuICBwdWJsaWMgY2hhbm5lbENvdW50OiBudW1iZXI7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKGNoYW5uZWxDb3VudDogbnVtYmVyLCBiYW5kTXVsdGlwbGllcnM6IG51bWJlcltdKSB7XG4gICAgc3VwZXIoYmFuZE11bHRpcGxpZXJzKTtcbiAgICB0aGlzLmNoYW5uZWxDb3VudCA9IGNoYW5uZWxDb3VudDtcbiAgICB0aGlzLmNoYW5uZWxzID0gdGhpcy5jcmVhdGVDaGFubmVsUHJvY2Vzc29yKCk7XG4gIH1cblxuICBwdWJsaWMgY3JlYXRlQ2hhbm5lbFByb2Nlc3NvcigpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh7IGxlbmd0aDogdGhpcy5jaGFubmVsQ291bnQgfSwgKCkgPT4ge1xuICAgICAgcmV0dXJuIG5ldyBDaGFubmVsUHJvY2Vzc29yKHRoaXMuYmFuZE11bHRpcGxpZXJzKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBwcm9jZXNzKGlucHV0OiBDaGFubmVsUHJvY2Vzc29ySW5wdXRbXSkge1xuICAgIHJldHVybiB0aGlzLmNoYW5uZWxzLm1hcCgoYywgaSkgPT4ge1xuICAgICAgY29uc3QgeyBkYXRhLCBleHRyZW11bSwgcmVhZEludCwgd3JpdGVJbnQsIGJ5dGVzIH0gPSBpbnB1dFtpXTtcblxuICAgICAgcmV0dXJuIGMucHJvY2VzcyhkYXRhLCBleHRyZW11bSwgYnl0ZXMsIHJlYWRJbnQsIHdyaXRlSW50KTtcbiAgICB9KTtcbiAgfVxufSIsICJpbXBvcnQgeyBUcmFuc2Zvcm1DYWxsYmFjayB9IGZyb20gJ3N0cmVhbSc7XG5pbXBvcnQgeyBQQ01UcmFuc2Zvcm1lciwgUENNVHJhbnNmb3JtZXJPcHRpb25zIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHsgRXF1YWxpemVyIH0gZnJvbSAnLi9FcXVhbGl6ZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIEVxdWFsaXplclN0cmVhbU9wdGlvbnMgZXh0ZW5kcyBQQ01UcmFuc2Zvcm1lck9wdGlvbnMge1xuICBiYW5kTXVsdGlwbGllcj86IEVxdWFsaXplckJhbmRbXTtcbiAgY2hhbm5lbHM/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXF1YWxpemVyQmFuZCB7XG4gIGJhbmQ6IG51bWJlcjtcbiAgZ2FpbjogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgRXF1YWxpemVyU3RyZWFtIGV4dGVuZHMgUENNVHJhbnNmb3JtZXIge1xuICBwdWJsaWMgYmFuZE11bHRpcGxpZXJzOiBudW1iZXJbXSA9IG5ldyBBcnJheShFcXVhbGl6ZXIuQkFORF9DT1VOVCkuZmlsbCgwKTtcbiAgcHVibGljIGVxdWFsaXplcjogRXF1YWxpemVyO1xuICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9ucz86IEVxdWFsaXplclN0cmVhbU9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcblxuICAgIG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKFxuICAgICAge30sXG4gICAgICB7XG4gICAgICAgIGJhbmRNdWx0aXBsaWVyOiBbXSxcbiAgICAgICAgY2hhbm5lbHM6IDFcbiAgICAgIH0sXG4gICAgICBvcHRpb25zIHx8IHt9XG4gICAgKTtcblxuICAgIHRoaXMuZXF1YWxpemVyID0gbmV3IEVxdWFsaXplcihvcHRpb25zLmNoYW5uZWxzIHx8IDEsIHRoaXMuYmFuZE11bHRpcGxpZXJzKTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRpb25zLmJhbmRNdWx0aXBsaWVyKSlcbiAgICB0aGlzLl9wcm9jZXNzQmFuZHMob3B0aW9ucy5iYW5kTXVsdGlwbGllcik7XG4gIH1cblxuICBwdWJsaWMgX3Byb2Nlc3NCYW5kcyhtdWx0aXBsaWVyOiBFcXVhbGl6ZXJCYW5kW10pIHtcbiAgICBmb3IgKGNvbnN0IG11bCBvZiBtdWx0aXBsaWVyKSB7XG4gICAgICBpZiAobXVsLmJhbmQgPiBFcXVhbGl6ZXIuQkFORF9DT1VOVCAtIDEgfHwgbXVsLmJhbmQgPCAwKVxuICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXG4gICAgICAgIGBCYW5kIHZhbHVlIG91dCBvZiByYW5nZS4gRXhwZWN0ZWQgPjAgJiA8JHtcbiAgICAgICAgRXF1YWxpemVyLkJBTkRfQ09VTlQgLSAxfSwgcmVjZWl2ZWQgXCIke1xuICAgICAgICBtdWwuYmFuZH1cImBcbiAgICAgICk7XG4gICAgICB0aGlzLmVxdWFsaXplci5zZXRHYWluKG11bC5iYW5kLCBtdWwuZ2Fpbik7XG4gICAgfVxuXG4gICAgdGhpcy5vblVwZGF0ZT8uKCk7XG4gIH1cblxuICBwdWJsaWMgX3RyYW5zZm9ybShcbiAgY2h1bms6IEJ1ZmZlcixcbiAgZW5jb2Rpbmc6IEJ1ZmZlckVuY29kaW5nLFxuICBjYWxsYmFjazogVHJhbnNmb3JtQ2FsbGJhY2spXG4gIDogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIHRoaXMucHVzaChjaHVuayk7XG4gICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB9XG5cbiAgICB0aGlzLmVxdWFsaXplci5wcm9jZXNzKFtcbiAgICB7XG4gICAgICBkYXRhOiBjaHVuayxcbiAgICAgIGV4dHJlbXVtOiB0aGlzLmV4dHJlbXVtLFxuICAgICAgcmVhZEludDogKGIsIGlkeCkgPT4gdGhpcy5fcmVhZEludChiLCBpZHgpLFxuICAgICAgd3JpdGVJbnQ6IChiLCBpLCBpZHgpID0+IHRoaXMuX3dyaXRlSW50KGIsIGksIGlkeCksXG4gICAgICBieXRlczogdGhpcy5ieXRlc1xuICAgIH1dXG4gICAgKTtcblxuICAgIHRoaXMucHVzaChjaHVuayk7XG5cbiAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRFUSgpIHtcbiAgICByZXR1cm4gdGhpcy5iYW5kTXVsdGlwbGllcnMubWFwKChtLCBpKSA9PiAoe1xuICAgICAgYmFuZDogaSxcbiAgICAgIGdhaW46IG1cbiAgICB9KSkgYXMgRXF1YWxpemVyQmFuZFtdO1xuICB9XG5cbiAgcHVibGljIHNldEVRKGJhbmRzOiBFcXVhbGl6ZXJCYW5kW10pIHtcbiAgICB0aGlzLl9wcm9jZXNzQmFuZHMoYmFuZHMpO1xuICB9XG5cbiAgcHVibGljIHJlc2V0RVEoKSB7XG4gICAgdGhpcy5fcHJvY2Vzc0JhbmRzKFxuICAgICAgQXJyYXkuZnJvbShcbiAgICAgICAge1xuICAgICAgICAgIGxlbmd0aDogRXF1YWxpemVyLkJBTkRfQ09VTlRcbiAgICAgICAgfSxcbiAgICAgICAgKF8sIGkpID0+ICh7XG4gICAgICAgICAgYmFuZDogaSxcbiAgICAgICAgICBnYWluOiAwXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgKTtcbiAgfVxufSIsICJpbXBvcnQgeyBUcmFuc2Zvcm1DYWxsYmFjayB9IGZyb20gJ3N0cmVhbSc7XG5pbXBvcnQgeyBQQ01UcmFuc2Zvcm1lciwgUENNVHJhbnNmb3JtZXJPcHRpb25zIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG4vKlxuTW9ubzogWzAsIDEsIDIsIDMsIDQsIDVdXG5TdGVyZW86IFswLCAxLCAwLCAxLCAyLCAzLCAyLCAzLCA0LCA1LCA0LCA1XVxuKi9cblxuZXhwb3J0IHR5cGUgTVNUU3RyYXRlZ3kgPSAnbTJzJyB8ICdzMm0nO1xuXG5leHBvcnQgaW50ZXJmYWNlIE1vbm9TdGVyZW9UcmFuc2Zvcm1lck9wdGlvbnMgZXh0ZW5kcyBQQ01UcmFuc2Zvcm1lck9wdGlvbnMge1xuICBzdHJhdGVneTogTVNUU3RyYXRlZ3k7XG59XG5cbmV4cG9ydCBjbGFzcyBNb25vU3RlcmVvVHJhbnNmb3JtZXIgZXh0ZW5kcyBQQ01UcmFuc2Zvcm1lciB7XG4gIHB1YmxpYyBzdHJhdGVneTogTVNUU3RyYXRlZ3k7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM/OiBNb25vU3RlcmVvVHJhbnNmb3JtZXJPcHRpb25zKSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gICAgaWYgKCFbJ20ycycsICdzMm0nXS5pbmNsdWRlcyhvcHRpb25zPy5zdHJhdGVneSBhcyBNU1RTdHJhdGVneSkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFN0cmF0ZWd5IG11c3QgYmUgXCJtMnNcIiBvciBcInMybVwiYCk7XG4gICAgfVxuXG4gICAgdGhpcy5zdHJhdGVneSA9IG9wdGlvbnMhLnN0cmF0ZWd5O1xuICB9XG5cbiAgcHVibGljIHNldFN0cmF0ZWd5KHN0cmF0ZWd5OiBNU1RTdHJhdGVneSkge1xuICAgIHRoaXMuc3RyYXRlZ3kgPSBzdHJhdGVneTtcbiAgfVxuXG4gIHB1YmxpYyBfdHJhbnNmb3JtKFxuICBjaHVuazogQnVmZmVyLFxuICBlbmNvZGluZzogQnVmZmVyRW5jb2RpbmcsXG4gIGNhbGxiYWNrOiBUcmFuc2Zvcm1DYWxsYmFjaylcbiAgOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgdGhpcy5wdXNoKGNodW5rKTtcbiAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgIH1cblxuICAgIGNvbnN0IGxlbiA9IE1hdGguZmxvb3IoY2h1bmsubGVuZ3RoIC8gMikgKiAyO1xuXG4gICAgaWYgKHRoaXMuc3RyYXRlZ3kgPT09ICdtMnMnKSB7XG4gICAgICB0aGlzLnB1c2godGhpcy50b1N0ZXJlbyhjaHVuaywgbGVuKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHVzaCh0aGlzLnRvTW9ubyhjaHVuaywgbGVuKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gIH1cblxuICBwdWJsaWMgdG9TdGVyZW8oc2FtcGxlOiBCdWZmZXIsIGxlbjogbnVtYmVyKSB7XG4gICAgY29uc3QgYnl0ZXMgPSB0aGlzLmJ5dGVzO1xuICAgIGNvbnN0IHN0ZXJlb0J1ZmZlciA9IEJ1ZmZlci5hbGxvYyhsZW4gKiAyKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpICs9IGJ5dGVzKSB7XG4gICAgICBzdGVyZW9CdWZmZXJbaSAqIDIgKyAwXSA9IHNhbXBsZVtpXTtcbiAgICAgIHN0ZXJlb0J1ZmZlcltpICogMiArIDFdID0gc2FtcGxlW2kgKyAxXTtcbiAgICAgIHN0ZXJlb0J1ZmZlcltpICogMiArIDJdID0gc2FtcGxlW2ldO1xuICAgICAgc3RlcmVvQnVmZmVyW2kgKiAyICsgM10gPSBzYW1wbGVbaSArIDFdO1xuICAgIH1cblxuICAgIHJldHVybiBzdGVyZW9CdWZmZXI7XG4gIH1cblxuICBwdWJsaWMgdG9Nb25vKHNhbXBsZTogQnVmZmVyLCBsZW46IG51bWJlcikge1xuICAgIGNvbnN0IGJ5dGVzID0gdGhpcy5ieXRlcztcbiAgICBjb25zdCBtb25vQnVmZmVyID0gQnVmZmVyLmFsbG9jKE1hdGguZmxvb3IobGVuIC8gMikpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkgKz0gYnl0ZXMpIHtcbiAgICAgIG1vbm9CdWZmZXJbaV0gPSBzYW1wbGVbaSAqIDIgKyAwXTtcbiAgICAgIG1vbm9CdWZmZXJbaSArIDFdID0gc2FtcGxlW2kgKiAyICsgMV07XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vbm9CdWZmZXI7XG4gIH1cbn0iLCAiZXhwb3J0ICogZnJvbSAnLi9iaXF1YWQnO1xuZXhwb3J0ICogZnJvbSAnLi9kc3AnO1xuZXhwb3J0ICogZnJvbSAnLi9lcXVhbGl6ZXInOyIsICJpbXBvcnQgeyBCaXF1YWRGaWx0ZXIsIEJpcXVhZEZpbHRlcnMsIENvZWZmaWNpZW50cyB9IGZyb20gJy4uLy4uL2JpcXVhZCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQUZCaXF1YWRDb25maWcge1xuICBiaXF1YWQ6IEJpcXVhZEZpbHRlcjtcbiAgc2FtcGxlOiBudW1iZXI7XG4gIGN1dG9mZjogbnVtYmVyO1xuICBnYWluOiBudW1iZXI7XG4gIGZpbHRlcjogQmlxdWFkRmlsdGVycztcbiAgY29lZmZpY2llbnQ6IENvZWZmaWNpZW50cztcbiAgUTogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlCaXF1YWQoZmlsdGVyZXI6IEJpcXVhZEZpbHRlciwgaW50OiBudW1iZXIpIHtcbiAgcmV0dXJuIGZpbHRlcmVyLnJ1bihpbnQpO1xufSIsICJleHBvcnQgaW50ZXJmYWNlIEFGUHVsc2F0b3JDb25maWcge1xuICBoejogbnVtYmVyO1xuICB4OiBudW1iZXI7XG4gIGRJOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQUZUcmVtb2xvQ29uZmlnIHtcbiAgcGhhc2U6IG51bWJlcjtcbiAgZGVwdGg6IG51bWJlcjtcbiAgZnJlcXVlbmN5OiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIEFGVmlicmF0b0NvbmZpZyA9IEFGVHJlbW9sb0NvbmZpZztcblxuZXhwb3J0IHR5cGUgTFIgPSAwIHwgMTtcblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5UHVsc2F0b3IoXG5jb25maWc6IEFGUHVsc2F0b3JDb25maWcsXG5pbnQ6IG51bWJlcixcbmNoYW5uZWw6IExSKVxue1xuICBjb25zdCBzaW4gPSBNYXRoLnNpbihjb25maWcueCk7XG4gIGNvbnN0IGN1cnJlbnRDaGFubmVsVmFsID0gY2hhbm5lbCA9PT0gMCA/IHNpbiA6IC1zaW47XG4gIGNvbnN0IHJlcyA9IGludCAqIChjdXJyZW50Q2hhbm5lbFZhbCArIDEuMCkgLyAyLjA7XG5cbiAgY29uZmlnLnggKz0gY29uZmlnLmRJO1xuXG4gIHJldHVybiByZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVRyZW1vbG8oXG5jb25maWc6IEFGVHJlbW9sb0NvbmZpZyxcbmludDogbnVtYmVyLFxuc2FtcGxlUmF0ZTogbnVtYmVyKVxue1xuICBjb25zdCBmT2Zmc2V0ID0gMS4wIC0gY29uZmlnLmRlcHRoO1xuICBjb25zdCBtb2RTaWduYWwgPSBmT2Zmc2V0ICsgY29uZmlnLmRlcHRoICogTWF0aC5zaW4oY29uZmlnLnBoYXNlKTtcbiAgY29uZmlnLnBoYXNlICs9IDIgKiBNYXRoLlBJIC8gc2FtcGxlUmF0ZSAqIGNvbmZpZy5mcmVxdWVuY3k7XG4gIHJldHVybiBtb2RTaWduYWwgKiBpbnQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVZpYnJhdG8oXG5jb25maWc6IEFGVmlicmF0b0NvbmZpZyxcbmludDogbnVtYmVyLFxuc2FtcGxlUmF0ZTogbnVtYmVyKVxue1xuICBjb25zdCBmT2Zmc2V0ID0gMS4wIC0gY29uZmlnLmRlcHRoO1xuICBjb25zdCBtb2RTaWduYWwgPVxuICBmT2Zmc2V0ICsgY29uZmlnLmRlcHRoICogTWF0aC5zaW4oMiAqIE1hdGguUEkgKiBjb25maWcucGhhc2UpO1xuICBjb25maWcucGhhc2UgKz0gMiAqIE1hdGguUEkgLyBzYW1wbGVSYXRlICogY29uZmlnLmZyZXF1ZW5jeTtcbiAgcmV0dXJuIG1vZFNpZ25hbCAqIGludDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5Vm9sdW1lKHZvbDogbnVtYmVyLCBpbnQ6IG51bWJlcikge1xuICByZXR1cm4gdm9sICogaW50O1xufSIsICJpbXBvcnQgeyBFcXVhbGl6ZXIgfSBmcm9tICcuLi8uLi9lcXVhbGl6ZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlFcXVhbGl6YXRpb24oZXE6IEVxdWFsaXplciwgaW50OiBudW1iZXIpIHtcbiAgY29uc3QgcHJvY2Vzc29yID0gZXEuY2hhbm5lbHNbMF07XG4gIGNvbnN0IHJlc3VsdCA9IHByb2Nlc3Nvci5wcm9jZXNzSW50KGludCk7XG4gIHByb2Nlc3Nvci5zdGVwKCk7XG4gIHJldHVybiByZXN1bHQ7XG59IiwgImltcG9ydCB7IFRyYW5zZm9ybUNhbGxiYWNrIH0gZnJvbSAnc3RyZWFtJztcbmltcG9ydCB7IFBDTVRyYW5zZm9ybWVyLCBQQ01UcmFuc2Zvcm1lck9wdGlvbnMgfSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQge1xuICBBRlB1bHNhdG9yQ29uZmlnLFxuICBBRlRyZW1vbG9Db25maWcsXG4gIEFGVmlicmF0b0NvbmZpZyxcbiAgTFIsXG4gIGFwcGx5UHVsc2F0b3IsXG4gIGFwcGx5VHJlbW9sbyxcbiAgYXBwbHlWaWJyYXRvIH0gZnJvbVxuJy4vdHJhbnNmb3JtZXJzJztcbmltcG9ydCB7IEVxdWFsaXplckJhbmQgfSBmcm9tICcuLi9lcXVhbGl6ZXInO1xuXG5leHBvcnQgY29uc3QgQXVkaW9GaWx0ZXJzID0ge1xuICAnOEQnOiAnOEQnLFxuICBUcmVtb2xvOiAnVHJlbW9sbycsXG4gIFZpYnJhdG86ICdWaWJyYXRvJ1xufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgUENNRmlsdGVycyA9IGtleW9mIHR5cGVvZiBBdWRpb0ZpbHRlcnM7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUENNRmlsdGVyZXJPcHRpb25zIGV4dGVuZHMgUENNVHJhbnNmb3JtZXJPcHRpb25zIHtcbiAgZmlsdGVycz86IFBDTUZpbHRlcnNbXTtcbn1cblxuZXhwb3J0IGNvbnN0IEFGX05JR0hUQ09SRV9SQVRFID0gMS4zIGFzIGNvbnN0O1xuZXhwb3J0IGNvbnN0IEFGX1ZBUE9SV0FWRV9SQVRFID0gMC44IGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgQkFTU19FUV9CQU5EUzogRXF1YWxpemVyQmFuZFtdID0gQXJyYXkuZnJvbShcbiAgeyBsZW5ndGg6IDMgfSxcbiAgKF8sIGkpID0+ICh7XG4gICAgYmFuZDogaSxcbiAgICBnYWluOiAwLjI1XG4gIH0pXG4pO1xuXG4vLyBiYXNlZCBvbiBsYXZhZHNwXG5leHBvcnQgY2xhc3MgQXVkaW9GaWx0ZXIgZXh0ZW5kcyBQQ01UcmFuc2Zvcm1lciB7XG4gIHB1YmxpYyBmaWx0ZXJzOiBQQ01GaWx0ZXJzW10gPSBbXTtcbiAgcHVibGljIHRhcmdldFNhbXBsZVJhdGUgPSB0aGlzLnNhbXBsZVJhdGU7XG5cbiAgcHVibGljIHB1bHNhdG9yQ29uZmlnOiBBRlB1bHNhdG9yQ29uZmlnID0ge1xuICAgIGh6OiAwLjAyLFxuICAgIHg6IDAsXG4gICAgZEk6IDAuMDAwMDAzOTI2OTkwODE2OTg3MjQxXG4gIH07XG5cbiAgcHVibGljIHRyZW1vbG9Db25maWc6IEFGVHJlbW9sb0NvbmZpZyA9IHtcbiAgICBwaGFzZTogMCxcbiAgICBkZXB0aDogMC41LFxuICAgIGZyZXF1ZW5jeTogNS4wXG4gIH07XG5cbiAgcHVibGljIHZpYnJhdG9Db25maWc6IEFGVmlicmF0b0NvbmZpZyA9IHtcbiAgICBwaGFzZTogMCxcbiAgICBkZXB0aDogMC41LFxuICAgIGZyZXF1ZW5jeTogNS4wXG4gIH07XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM/OiBQQ01GaWx0ZXJlck9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcblxuICAgIGlmIChvcHRpb25zICYmIEFycmF5LmlzQXJyYXkob3B0aW9ucy5maWx0ZXJzKSkge1xuICAgICAgdGhpcy5zZXRGaWx0ZXJzKG9wdGlvbnMuZmlsdGVycyk7XG4gICAgfVxuXG4gICAgdGhpcy5vblVwZGF0ZT8uKCk7XG4gIH1cblxuICBwdWJsaWMgc2V0VGFyZ2V0U2FtcGxlUmF0ZShyYXRlOiBudW1iZXIpIHtcbiAgICB0aGlzLnRhcmdldFNhbXBsZVJhdGUgPSByYXRlIHx8IHRoaXMuc2FtcGxlUmF0ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICBwdWJsaWMgc2V0UHVsc2F0b3IoaHo6IG51bWJlcikge1xuICAgIGh6IC89IDQ7IC8vIG1hdGNoIGZmbXBlZ1xuICAgIHRoaXMucHVsc2F0b3JDb25maWcuaHogPSBoejtcbiAgICBjb25zdCBzYW1wbGVzUGVyQ3ljbGUgPSB0aGlzLnRhcmdldFNhbXBsZVJhdGUgLyAoaHogKiAyICogTWF0aC5QSSk7XG4gICAgdGhpcy5wdWxzYXRvckNvbmZpZy5kSSA9IGh6ID09PSAwID8gMCA6IDEgLyBzYW1wbGVzUGVyQ3ljbGU7XG5cbiAgICB0aGlzLm9uVXBkYXRlPy4oKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgcHVsc2F0b3IoKSB7XG4gICAgcmV0dXJuIHRoaXMucHVsc2F0b3JDb25maWcuaHo7XG4gIH1cblxuICBwdWJsaWMgc2V0VHJlbW9sbyh7XG4gICAgZGVwdGggPSB0aGlzLnRyZW1vbG9Db25maWcuZGVwdGgsXG4gICAgZnJlcXVlbmN5ID0gdGhpcy50cmVtb2xvQ29uZmlnLmZyZXF1ZW5jeSxcbiAgICBwaGFzZSA9IHRoaXMudHJlbW9sb0NvbmZpZy5waGFzZVxuICB9OiBQYXJ0aWFsPEFGVHJlbW9sb0NvbmZpZz4pIHtcbiAgICBpZiAodHlwZW9mIGRlcHRoID09PSAnbnVtYmVyJykgdGhpcy50cmVtb2xvQ29uZmlnLmRlcHRoID0gZGVwdGg7XG4gICAgaWYgKHR5cGVvZiBmcmVxdWVuY3kgPT09ICdudW1iZXInKSB0aGlzLnRyZW1vbG9Db25maWcuZnJlcXVlbmN5ID0gZnJlcXVlbmN5O1xuICAgIGlmICh0eXBlb2YgcGhhc2UgPT09ICdudW1iZXInKSB0aGlzLnRyZW1vbG9Db25maWcucGhhc2UgPSBwaGFzZTtcblxuICAgIHRoaXMub25VcGRhdGU/LigpO1xuICB9XG5cbiAgcHVibGljIHNldFZpYnJhdG8oe1xuICAgIGRlcHRoID0gdGhpcy52aWJyYXRvQ29uZmlnLmRlcHRoLFxuICAgIGZyZXF1ZW5jeSA9IHRoaXMudmlicmF0b0NvbmZpZy5mcmVxdWVuY3ksXG4gICAgcGhhc2UgPSB0aGlzLnZpYnJhdG9Db25maWcucGhhc2VcbiAgfTogUGFydGlhbDxBRlZpYnJhdG9Db25maWc+KSB7XG4gICAgaWYgKHR5cGVvZiBkZXB0aCA9PT0gJ251bWJlcicpIHRoaXMudmlicmF0b0NvbmZpZy5kZXB0aCA9IGRlcHRoO1xuICAgIGlmICh0eXBlb2YgZnJlcXVlbmN5ID09PSAnbnVtYmVyJykgdGhpcy52aWJyYXRvQ29uZmlnLmZyZXF1ZW5jeSA9IGZyZXF1ZW5jeTtcbiAgICBpZiAodHlwZW9mIHBoYXNlID09PSAnbnVtYmVyJykgdGhpcy52aWJyYXRvQ29uZmlnLnBoYXNlID0gcGhhc2U7XG5cbiAgICB0aGlzLm9uVXBkYXRlPy4oKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdHJlbW9sbygpIHtcbiAgICByZXR1cm4gdGhpcy50cmVtb2xvQ29uZmlnO1xuICB9XG5cbiAgcHVibGljIHNldEZpbHRlcnMoZmlsdGVyczogUENNRmlsdGVyc1tdKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGZpbHRlcnMpIHx8ICFmaWx0ZXJzLmV2ZXJ5KChyKSA9PiByIGluIEF1ZGlvRmlsdGVycykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmZpbHRlcnMgPSBmaWx0ZXJzO1xuXG4gICAgdGhpcy5vblVwZGF0ZT8uKCk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBfdHJhbnNmb3JtKFxuICBjaHVuazogQnVmZmVyLFxuICBlbmNvZGluZzogQnVmZmVyRW5jb2RpbmcsXG4gIGNhbGxiYWNrOiBUcmFuc2Zvcm1DYWxsYmFjaylcbiAgOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCB8fCAhdGhpcy5maWx0ZXJzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGNodW5rKTtcbiAgICB9XG5cbiAgICBjb25zdCBsZW4gPSBNYXRoLmZsb29yKGNodW5rLmxlbmd0aCAvIDIpICogMjtcbiAgICBjb25zdCB7IGJ5dGVzIH0gPSB0aGlzO1xuXG4gICAgLy8gbGVmdC1yaWdodCBjaGFubmVsXG4gICAgbGV0IEwgPSBmYWxzZTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpICs9IGJ5dGVzKSB7XG4gICAgICBjb25zdCBpbnQgPSB0aGlzLl9yZWFkSW50KGNodW5rLCBpKTtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5hcHBseUZpbHRlcnMoaW50LCArKEwgPSAhTCkgYXMgTFIpO1xuICAgICAgdGhpcy5fd3JpdGVJbnQoY2h1bmssIHRoaXMuY2xhbXAodmFsdWUpLCBpKTtcbiAgICB9XG5cbiAgICB0aGlzLnB1c2goY2h1bmspO1xuXG4gICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGN1cnJlbnRTYW1wbGVSYXRlKCkge1xuICAgIHJldHVybiB0aGlzLnRhcmdldFNhbXBsZVJhdGUgfHwgdGhpcy5zYW1wbGVSYXRlO1xuICB9XG5cbiAgcHVibGljIGFwcGx5RmlsdGVycyhieXRlOiBudW1iZXIsIGNoYW5uZWw6IExSKSB7XG4gICAgaWYgKHRoaXMuZmlsdGVycy5sZW5ndGgpIHtcbiAgICAgIGZvciAoY29uc3QgZmlsdGVyIG9mIHRoaXMuZmlsdGVycykge1xuICAgICAgICBpZiAoZmlsdGVyID09PSAnOEQnKSB7XG4gICAgICAgICAgYnl0ZSA9IGFwcGx5UHVsc2F0b3IodGhpcy5wdWxzYXRvckNvbmZpZywgYnl0ZSwgY2hhbm5lbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmlsdGVyID09PSAnVHJlbW9sbycpIHtcbiAgICAgICAgICBieXRlID0gYXBwbHlUcmVtb2xvKHRoaXMudHJlbW9sb0NvbmZpZywgYnl0ZSwgdGhpcy5jdXJyZW50U2FtcGxlUmF0ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmlsdGVyID09PSAnVmlicmF0bycpIHtcbiAgICAgICAgICBieXRlID0gYXBwbHlWaWJyYXRvKHRoaXMudmlicmF0b0NvbmZpZywgYnl0ZSwgdGhpcy5jdXJyZW50U2FtcGxlUmF0ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYnl0ZTtcbiAgfVxufSIsICJpbXBvcnQgeyBQQ01UcmFuc2Zvcm1lciwgUENNVHJhbnNmb3JtZXJPcHRpb25zIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBDTVJlc2FtcGxlck9wdGlvbnMgZXh0ZW5kcyBQQ01UcmFuc2Zvcm1lck9wdGlvbnMge1xuICBpbnB1dFNhbXBsZVJhdGU6IG51bWJlcjtcbiAgdGFyZ2V0U2FtcGxlUmF0ZTogbnVtYmVyO1xuICBjaGFubmVscz86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXNhbXBsZVBhcmFtZXRlcnMge1xuICBjdXJyZW50RmlsdGVyOiBDb21tb25SZXNhbXBsZXJGaWx0ZXJQcmVzZXQgfCBudWxsO1xuICBpbnB1dFNhbXBsZVJhdGU6IG51bWJlcjtcbiAgY2hhbm5lbHM6IG51bWJlcjtcbiAgc2FtcGxlUmF0ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgdHlwZSBDb21tb25SZXNhbXBsZXJGaWx0ZXJQcmVzZXQgPSAnbmlnaHRjb3JlJyB8ICd2YXBvcndhdmUnO1xuXG5leHBvcnQgY2xhc3MgUENNUmVzYW1wbGVyIGV4dGVuZHMgUENNVHJhbnNmb3JtZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGlucHV0U2FtcGxlUmF0ZTogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGNoYW5uZWxzOiBudW1iZXI7XG4gIHByaXZhdGUgYnVmZmVyOiBCdWZmZXI7XG4gIHB1YmxpYyBjdXJyZW50RmlsdGVyOiBDb21tb25SZXNhbXBsZXJGaWx0ZXJQcmVzZXQgfCBudWxsID0gbnVsbDtcblxuICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9ucz86IFBDTVJlc2FtcGxlck9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcblxuICAgIHRoaXMuaW5wdXRTYW1wbGVSYXRlID0gb3B0aW9ucz8uaW5wdXRTYW1wbGVSYXRlID8/IDQ4MDAwO1xuICAgIHRoaXMuY2hhbm5lbHMgPSBvcHRpb25zPy5jaGFubmVscyA/PyAyO1xuICAgIHRoaXMuYnVmZmVyID0gQnVmZmVyLmFsbG9jKDApO1xuXG4gICAgaWYgKHRoaXMuaW5wdXRTYW1wbGVSYXRlIDwgMSkge1xuICAgICAgdGhpcy5pbnB1dFNhbXBsZVJhdGUgPSA0ODAwMDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucz8udGFyZ2V0U2FtcGxlUmF0ZSkge1xuICAgICAgdGhpcy5zZXRTYW1wbGVSYXRlKG9wdGlvbnM/LnRhcmdldFNhbXBsZVJhdGUpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZXRGaWx0ZXIoZmlsdGVyOiBDb21tb25SZXNhbXBsZXJGaWx0ZXJQcmVzZXQgfCBudWxsKSB7XG4gICAgaWYgKHRoaXMuY3VycmVudEZpbHRlciA9PT0gZmlsdGVyKSByZXR1cm47XG5cbiAgICBzd2l0Y2ggKGZpbHRlcikge1xuICAgICAgY2FzZSAnbmlnaHRjb3JlJzpcbiAgICAgICAgdGhpcy5zZXRTYW1wbGVSYXRlKHRoaXMuaW5wdXRTYW1wbGVSYXRlICogMS4yNSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndmFwb3J3YXZlJzpcbiAgICAgICAgdGhpcy5zZXRTYW1wbGVSYXRlKHRoaXMuaW5wdXRTYW1wbGVSYXRlICogMC44KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aGlzLnNldFNhbXBsZVJhdGUodGhpcy5pbnB1dFNhbXBsZVJhdGUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLmN1cnJlbnRGaWx0ZXIgPSBmaWx0ZXI7XG4gIH1cblxuICBwdWJsaWMgZ2V0UGFyYW1ldGVycygpOiBSZXNhbXBsZVBhcmFtZXRlcnMge1xuICAgIHJldHVybiB7XG4gICAgICBjdXJyZW50RmlsdGVyOiB0aGlzLmN1cnJlbnRGaWx0ZXIsXG4gICAgICBpbnB1dFNhbXBsZVJhdGU6IHRoaXMuaW5wdXRTYW1wbGVSYXRlLFxuICAgICAgY2hhbm5lbHM6IHRoaXMuY2hhbm5lbHMsXG4gICAgICBzYW1wbGVSYXRlOiB0aGlzLnNhbXBsZVJhdGVcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZUZpbHRlcihmaWx0ZXI6IENvbW1vblJlc2FtcGxlckZpbHRlclByZXNldCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHNhbWUgPSB0aGlzLmN1cnJlbnRGaWx0ZXIgPT09IGZpbHRlcjtcbiAgICB0aGlzLnNldEZpbHRlcihzYW1lID8gbnVsbCA6IGZpbHRlcik7XG5cbiAgICByZXR1cm4gIXNhbWU7XG4gIH1cblxuICBwdWJsaWMgZ2V0UmF0aW8oKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5pbnB1dFNhbXBsZVJhdGUgPT09IDApIHJldHVybiAxO1xuXG4gICAgcmV0dXJuIHRoaXMuc2FtcGxlUmF0ZSAvIHRoaXMuaW5wdXRTYW1wbGVSYXRlO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNhbXBsZShpbnB1dDogQnVmZmVyKTogQnVmZmVyIHtcbiAgICBjb25zdCBieXRlc1BlckZyYW1lID0gdGhpcy5ieXRlcyAqIHRoaXMuY2hhbm5lbHM7XG4gICAgY29uc3QgaW5wdXRGcmFtZXMgPSBNYXRoLmZsb29yKGlucHV0Lmxlbmd0aCAvIGJ5dGVzUGVyRnJhbWUpO1xuICAgIGNvbnN0IG91dHB1dEZyYW1lcyA9IE1hdGguZmxvb3IoXG4gICAgICBpbnB1dEZyYW1lcyAqIHRoaXMuaW5wdXRTYW1wbGVSYXRlIC8gdGhpcy5zYW1wbGVSYXRlXG4gICAgKTtcbiAgICBjb25zdCBvdXRwdXQgPSBCdWZmZXIuYWxsb2Mob3V0cHV0RnJhbWVzICogYnl0ZXNQZXJGcmFtZSk7XG5cbiAgICBmb3IgKGxldCBvdXRGcmFtZSA9IDA7IG91dEZyYW1lIDwgb3V0cHV0RnJhbWVzOyBvdXRGcmFtZSsrKSB7XG4gICAgICBjb25zdCBpblBvcyA9IG91dEZyYW1lICogdGhpcy5zYW1wbGVSYXRlIC8gdGhpcy5pbnB1dFNhbXBsZVJhdGU7XG4gICAgICBjb25zdCBpbkZyYW1lID0gTWF0aC5mbG9vcihpblBvcyk7XG5cbiAgICAgIGlmIChcbiAgICAgIGluRnJhbWUgPj0gaW5wdXRGcmFtZXMgLSAxIHx8XG4gICAgICAoaW5GcmFtZSArIDEpICogYnl0ZXNQZXJGcmFtZSArICh0aGlzLmNoYW5uZWxzIC0gMSkgKiB0aGlzLmJ5dGVzID5cbiAgICAgIGlucHV0Lmxlbmd0aClcbiAgICAgIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZyYWN0aW9uID0gaW5Qb3MgLSBpbkZyYW1lO1xuXG4gICAgICBmb3IgKGxldCBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7IGNoYW5uZWwrKykge1xuICAgICAgICBjb25zdCBwb3MxID0gaW5GcmFtZSAqIGJ5dGVzUGVyRnJhbWUgKyBjaGFubmVsICogdGhpcy5ieXRlcztcbiAgICAgICAgY29uc3QgcG9zMiA9IChpbkZyYW1lICsgMSkgKiBieXRlc1BlckZyYW1lICsgY2hhbm5lbCAqIHRoaXMuYnl0ZXM7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICBwb3MxICsgdGhpcy5ieXRlcyA+IGlucHV0Lmxlbmd0aCB8fFxuICAgICAgICBwb3MyICsgdGhpcy5ieXRlcyA+IGlucHV0Lmxlbmd0aClcbiAgICAgICAge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2FtcGxlMSA9IHRoaXMuX3JlYWRJbnQoaW5wdXQsIHBvczEpO1xuICAgICAgICBjb25zdCBzYW1wbGUyID0gdGhpcy5fcmVhZEludChpbnB1dCwgcG9zMik7XG5cbiAgICAgICAgY29uc3QgaW50ZXJwb2xhdGVkID0gc2FtcGxlMSArIGZyYWN0aW9uICogKHNhbXBsZTIgLSBzYW1wbGUxKTtcbiAgICAgICAgY29uc3QgY2xhbXBlZCA9IHRoaXMuY2xhbXAoTWF0aC5yb3VuZChpbnRlcnBvbGF0ZWQpKTtcblxuICAgICAgICBjb25zdCBvdXRQb3MgPSBvdXRGcmFtZSAqIGJ5dGVzUGVyRnJhbWUgKyBjaGFubmVsICogdGhpcy5ieXRlcztcbiAgICAgICAgdGhpcy5fd3JpdGVJbnQob3V0cHV0LCBjbGFtcGVkLCBvdXRQb3MpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cblxuICBwdWJsaWMgb3ZlcnJpZGUgX3RyYW5zZm9ybShcbiAgY2h1bms6IEJ1ZmZlcixcbiAgZW5jb2Rpbmc6IEJ1ZmZlckVuY29kaW5nLFxuICBjYWxsYmFjazogKGVycm9yPzogRXJyb3IgfCBudWxsLCBkYXRhPzogQnVmZmVyKSA9PiB2b2lkKVxuICA6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkIHx8IHRoaXMuc2FtcGxlUmF0ZSA9PT0gdGhpcy5pbnB1dFNhbXBsZVJhdGUpIHtcbiAgICAgIHRoaXMucHVzaChjaHVuayk7XG4gICAgICBjYWxsYmFjaygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYnVmZmVyID0gQnVmZmVyLmNvbmNhdChbdGhpcy5idWZmZXIsIGNodW5rXSk7XG5cbiAgICBjb25zdCBieXRlc1BlckZyYW1lID0gdGhpcy5ieXRlcyAqIHRoaXMuY2hhbm5lbHM7XG4gICAgY29uc3QgbWluRnJhbWVzTmVlZGVkID0gTWF0aC5jZWlsKFxuICAgICAgYnl0ZXNQZXJGcmFtZSAqICh0aGlzLmlucHV0U2FtcGxlUmF0ZSAvIHRoaXMuc2FtcGxlUmF0ZSlcbiAgICApO1xuICAgIGNvbnN0IGNvbXBsZXRlRnJhbWVzID0gTWF0aC5mbG9vcih0aGlzLmJ1ZmZlci5sZW5ndGggLyBieXRlc1BlckZyYW1lKSAtIDE7XG5cbiAgICBpZiAoY29tcGxldGVGcmFtZXMgPj0gbWluRnJhbWVzTmVlZGVkKSB7XG4gICAgICBjb25zdCBwcm9jZXNzU2l6ZSA9IGNvbXBsZXRlRnJhbWVzICogYnl0ZXNQZXJGcmFtZTtcbiAgICAgIGNvbnN0IHRvUHJvY2VzcyA9IHRoaXMuYnVmZmVyLnNsaWNlKDAsIHByb2Nlc3NTaXplKTtcbiAgICAgIHRoaXMuYnVmZmVyID0gdGhpcy5idWZmZXIuc2xpY2UocHJvY2Vzc1NpemUpO1xuXG4gICAgICBjb25zdCByZXNhbXBsZWQgPSB0aGlzLnJlc2FtcGxlKHRvUHJvY2Vzcyk7XG4gICAgICB0aGlzLnB1c2gocmVzYW1wbGVkKTtcbiAgICB9XG5cbiAgICBjYWxsYmFjaygpO1xuICB9XG5cbiAgcHVibGljIG92ZXJyaWRlIF9mbHVzaChcbiAgY2FsbGJhY2s6IChlcnJvcj86IEVycm9yIHwgbnVsbCwgZGF0YT86IEJ1ZmZlcikgPT4gdm9pZClcbiAgOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgY2FsbGJhY2soKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5idWZmZXIubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgcmVzYW1wbGVkID0gdGhpcy5yZXNhbXBsZSh0aGlzLmJ1ZmZlcik7XG4gICAgICB0aGlzLnB1c2gocmVzYW1wbGVkKTtcbiAgICB9XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIHB1YmxpYyBvdmVycmlkZSBzZXRTYW1wbGVSYXRlKHJhdGU6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChyYXRlID09PSB0aGlzLnNhbXBsZVJhdGUpIHJldHVybjtcblxuICAgIGlmIChyYXRlIDwgMSkge1xuICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1NhbXBsZSByYXRlIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgICB9XG5cbiAgICBzdXBlci5zZXRTYW1wbGVSYXRlKHJhdGUpO1xuICAgIHRoaXMub25VcGRhdGUoKTtcbiAgfVxufSIsICJpbXBvcnQgeyBUcmFuc2Zvcm1DYWxsYmFjayB9IGZyb20gJ3N0cmVhbSc7XG5pbXBvcnQgeyBQQ01UcmFuc2Zvcm1lciwgUENNVHJhbnNmb3JtZXJPcHRpb25zIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZvbHVtZVRyYW5zZm9ybWVyT3B0aW9ucyBleHRlbmRzIFBDTVRyYW5zZm9ybWVyT3B0aW9ucyB7XG4gIHZvbHVtZT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGNsYXNzIFZvbHVtZVRyYW5zZm9ybWVyIGV4dGVuZHMgUENNVHJhbnNmb3JtZXIge1xuICBwcml2YXRlIF92b2x1bWUgPSAxO1xuICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9ucz86IFZvbHVtZVRyYW5zZm9ybWVyT3B0aW9ucykge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zPy52b2x1bWUgPT09ICdudW1iZXInKSB7XG4gICAgICB0aGlzLnNldFZvbHVtZShvcHRpb25zLnZvbHVtZSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldCB2b2x1bWVBcHByb3goKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZvbHVtZSAqIDEwMDtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdm9sdW1lKCkge1xuICAgIHJldHVybiBNYXRoLmZsb29yKHRoaXMudm9sdW1lQXBwcm94KTtcbiAgfVxuXG4gIHB1YmxpYyBzZXQgdm9sdW1lKHZvbHVtZTogbnVtYmVyKSB7XG4gICAgdGhpcy5zZXRWb2x1bWUodm9sdW1lKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRWb2x1bWUodm9sdW1lOiBudW1iZXIpIHtcbiAgICBpZiAodHlwZW9mIHZvbHVtZSAhPT0gJ251bWJlcicgfHwgaXNOYU4odm9sdW1lKSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRXhwZWN0ZWQgdm9sdW1lIGFtb3VudCB0byBiZSBhIG51bWJlciwgcmVjZWl2ZWQgJHt0eXBlb2Ygdm9sdW1lfSFgXG4gICAgKTtcbiAgICBpZiAodm9sdW1lIDwgMCkgdm9sdW1lID0gMDtcbiAgICBpZiAoIWlzRmluaXRlKHZvbHVtZSkpIHZvbHVtZSA9IDEwMDtcblxuICAgIHRoaXMuX3ZvbHVtZSA9IHZvbHVtZSAvIDEwMDtcblxuICAgIHRoaXMub25VcGRhdGU/LigpO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwdWJsaWMgX3RyYW5zZm9ybShcbiAgY2h1bms6IEJ1ZmZlcixcbiAgZW5jb2Rpbmc6IEJ1ZmZlckVuY29kaW5nLFxuICBjYWxsYmFjazogVHJhbnNmb3JtQ2FsbGJhY2spXG4gIDogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQgfHwgdGhpcy5fdm9sdW1lID09PSAxKSB7XG4gICAgICB0aGlzLnB1c2goY2h1bmspO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgY29uc3QgbGVuID0gTWF0aC5mbG9vcihjaHVuay5sZW5ndGggLyAyKSAqIDI7XG4gICAgY29uc3QgeyBieXRlcyB9ID0gdGhpcztcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpICs9IGJ5dGVzKSB7XG4gICAgICBjb25zdCBpbnQgPSB0aGlzLl9yZWFkSW50KGNodW5rLCBpKTtcbiAgICAgIGNvbnN0IGFtcCA9IHRoaXMuY2xhbXAoaW50ICogdGhpcy5fdm9sdW1lKTtcbiAgICAgIHRoaXMuX3dyaXRlSW50KGNodW5rLCBhbXAsIGkpO1xuICAgIH1cblxuICAgIHRoaXMucHVzaChjaHVuayk7XG5cbiAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgfVxuXG4gIHB1YmxpYyB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gYCR7dGhpcy52b2x1bWV9JWA7XG4gIH1cbn0iLCAiaW1wb3J0IHsgUENNVHJhbnNmb3JtZXIsIFBDTVRyYW5zZm9ybWVyT3B0aW9ucyB9IGZyb20gJy4uL3V0aWxzL1BDTVRyYW5zZm9ybWVyJztcblxuZXhwb3J0IGludGVyZmFjZSBDb21wcmVzc29yT3B0aW9ucyBleHRlbmRzIFBDTVRyYW5zZm9ybWVyT3B0aW9ucyB7XG4gIHRocmVzaG9sZD86IG51bWJlcjtcbiAgcmF0aW8/OiBudW1iZXI7XG4gIGF0dGFjaz86IG51bWJlcjtcbiAgcmVsZWFzZT86IG51bWJlcjtcbiAgbWFrZXVwR2Fpbj86IG51bWJlcjtcbiAga25lZVdpZHRoPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbXByZXNzb3JQYXJhbWV0ZXJzIHtcbiAgdGhyZXNob2xkOiBudW1iZXI7XG4gIHJhdGlvOiBudW1iZXI7XG4gIGF0dGFjazogbnVtYmVyO1xuICByZWxlYXNlOiBudW1iZXI7XG4gIG1ha2V1cEdhaW46IG51bWJlcjtcbiAga25lZVdpZHRoOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBDb21wcmVzc29yVHJhbnNmb3JtZXIgZXh0ZW5kcyBQQ01UcmFuc2Zvcm1lciB7XG4gIHByaXZhdGUgdGhyZXNob2xkOiBudW1iZXI7XG4gIHByaXZhdGUgcmF0aW86IG51bWJlcjtcbiAgcHJpdmF0ZSBhdHRhY2s6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWxlYXNlOiBudW1iZXI7XG4gIHByaXZhdGUgbWFrZXVwR2FpbjogbnVtYmVyO1xuICBwcml2YXRlIGtuZWVXaWR0aDogbnVtYmVyO1xuICBwcml2YXRlIGVudmVsb3BlOiBudW1iZXIgPSAwO1xuICBwcml2YXRlIGdhaW5SZWR1Y3Rpb246IG51bWJlciA9IDE7XG4gIHByaXZhdGUgcHJldmlvdXNHYWluUmVkdWN0aW9uOiBudW1iZXIgPSAxO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IENvbXByZXNzb3JPcHRpb25zID0ge30pIHtcbiAgICBzdXBlcihvcHRpb25zKTtcblxuICAgIHRoaXMudGhyZXNob2xkID0gb3B0aW9ucy50aHJlc2hvbGQgPz8gLTIwO1xuICAgIHRoaXMucmF0aW8gPSBvcHRpb25zLnJhdGlvID8/IDQ7XG4gICAgdGhpcy5hdHRhY2sgPSBvcHRpb25zLmF0dGFjayA/PyAyMDtcbiAgICB0aGlzLnJlbGVhc2UgPSBvcHRpb25zLnJlbGVhc2UgPz8gMTAwO1xuICAgIHRoaXMubWFrZXVwR2FpbiA9IG9wdGlvbnMubWFrZXVwR2FpbiA/PyAwO1xuICAgIHRoaXMua25lZVdpZHRoID0gb3B0aW9ucy5rbmVlV2lkdGggPz8gNjtcbiAgICB0aGlzLmF0dGFjayA9IE1hdGguZXhwKC0xIC8gKHRoaXMuc2FtcGxlUmF0ZSAqIHRoaXMuYXR0YWNrIC8gMTAwMCkpO1xuICAgIHRoaXMucmVsZWFzZSA9IE1hdGguZXhwKC0xIC8gKHRoaXMuc2FtcGxlUmF0ZSAqIHRoaXMucmVsZWFzZSAvIDEwMDApKTtcbiAgfVxuXG4gIHByaXZhdGUgbGluZWFyVG9EYihsaW5lYXI6IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3QgdmFsID0gMjAgKiBNYXRoLmxvZzEwKE1hdGgubWF4KGxpbmVhciwgMWUtNikpO1xuICAgIHJldHVybiB2YWw7XG4gIH1cblxuICBwcml2YXRlIGRiVG9MaW5lYXIoZGI6IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3QgdmFsID0gTWF0aC5wb3coMTAsIGRiIC8gMjApO1xuICAgIHJldHVybiB2YWw7XG4gIH1cblxuICBwdWJsaWMgc2V0VGhyZXNob2xkKGRiOiBudW1iZXIpIHtcbiAgICB0aGlzLnRocmVzaG9sZCA9IE1hdGgubWF4KC0xMDAsIE1hdGgubWluKDAsIGRiKSk7XG4gICAgdGhpcy5vblVwZGF0ZSgpO1xuICB9XG5cbiAgcHVibGljIHNldFJhdGlvKHJhdGlvOiBudW1iZXIpIHtcbiAgICB0aGlzLnJhdGlvID0gTWF0aC5tYXgoMSwgcmF0aW8pO1xuICAgIHRoaXMub25VcGRhdGUoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRBdHRhY2sobXM6IG51bWJlcikge1xuICAgIHRoaXMuYXR0YWNrID0gTWF0aC5leHAoLTEgLyAodGhpcy5zYW1wbGVSYXRlICogTWF0aC5tYXgoMC4xLCBtcykgLyAxMDAwKSk7XG4gICAgdGhpcy5vblVwZGF0ZSgpO1xuICB9XG5cbiAgcHVibGljIHNldFJlbGVhc2UobXM6IG51bWJlcikge1xuICAgIHRoaXMucmVsZWFzZSA9IE1hdGguZXhwKFxuICAgICAgLTEgLyAodGhpcy5zYW1wbGVSYXRlICogTWF0aC5tYXgoMC4xLCBtcykgLyAxMDAwKVxuICAgICk7XG4gICAgdGhpcy5vblVwZGF0ZSgpO1xuICB9XG5cbiAgcHVibGljIHNldE1ha2V1cEdhaW4oZGI6IG51bWJlcikge1xuICAgIHRoaXMubWFrZXVwR2FpbiA9IE1hdGgubWF4KC0yMCwgTWF0aC5taW4oMjAsIGRiKSk7XG4gICAgdGhpcy5vblVwZGF0ZSgpO1xuICB9XG5cbiAgcHVibGljIHNldEtuZWVXaWR0aChkYjogbnVtYmVyKSB7XG4gICAgdGhpcy5rbmVlV2lkdGggPSBNYXRoLm1heCgwLCBNYXRoLm1pbigyMCwgZGIpKTtcbiAgICB0aGlzLm9uVXBkYXRlKCk7XG4gIH1cblxuICBwdWJsaWMgc2V0Q29tcHJlc3NvcihvcHRpb25zOiBQYXJ0aWFsPENvbXByZXNzb3JQYXJhbWV0ZXJzPikge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy50aHJlc2hvbGQgPT09ICdudW1iZXInKSB7XG4gICAgICB0aGlzLnNldFRocmVzaG9sZChvcHRpb25zLnRocmVzaG9sZCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnJhdGlvID09PSAnbnVtYmVyJykge1xuICAgICAgdGhpcy5zZXRSYXRpbyhvcHRpb25zLnJhdGlvKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuYXR0YWNrID09PSAnbnVtYmVyJykge1xuICAgICAgdGhpcy5zZXRBdHRhY2sob3B0aW9ucy5hdHRhY2spO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5yZWxlYXNlID09PSAnbnVtYmVyJykge1xuICAgICAgdGhpcy5zZXRSZWxlYXNlKG9wdGlvbnMucmVsZWFzZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLm1ha2V1cEdhaW4gPT09ICdudW1iZXInKSB7XG4gICAgICB0aGlzLnNldE1ha2V1cEdhaW4ob3B0aW9ucy5tYWtldXBHYWluKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMua25lZVdpZHRoID09PSAnbnVtYmVyJykge1xuICAgICAgdGhpcy5zZXRLbmVlV2lkdGgob3B0aW9ucy5rbmVlV2lkdGgpO1xuICAgIH1cblxuICAgIHRoaXMub25VcGRhdGUoKTtcblxuICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcnMoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRQYXJhbWV0ZXJzKCk6IENvbXByZXNzb3JQYXJhbWV0ZXJzIHtcbiAgICByZXR1cm4ge1xuICAgICAgdGhyZXNob2xkOiB0aGlzLnRocmVzaG9sZCxcbiAgICAgIHJhdGlvOiB0aGlzLnJhdGlvLFxuICAgICAgYXR0YWNrOiB0aGlzLmF0dGFjayxcbiAgICAgIHJlbGVhc2U6IHRoaXMucmVsZWFzZSxcbiAgICAgIG1ha2V1cEdhaW46IHRoaXMubWFrZXVwR2FpbixcbiAgICAgIGtuZWVXaWR0aDogdGhpcy5rbmVlV2lkdGhcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlR2FpblJlZHVjdGlvbihpbnB1dExldmVsOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IGlucHV0RGIgPSB0aGlzLmxpbmVhclRvRGIoaW5wdXRMZXZlbCk7XG5cbiAgICBsZXQgZ2FpblJlZHVjdGlvbkRiID0gMDtcblxuICAgIGlmICgyICogKGlucHV0RGIgLSB0aGlzLnRocmVzaG9sZCkgPCAtdGhpcy5rbmVlV2lkdGgpIHtcbiAgICAgIGdhaW5SZWR1Y3Rpb25EYiA9IDA7XG4gICAgfSBlbHNlIGlmICgyICogTWF0aC5hYnMoaW5wdXREYiAtIHRoaXMudGhyZXNob2xkKSA8PSB0aGlzLmtuZWVXaWR0aCkge1xuICAgICAgY29uc3QgeCA9IGlucHV0RGIgLSB0aGlzLnRocmVzaG9sZCArIHRoaXMua25lZVdpZHRoIC8gMjtcbiAgICAgIGdhaW5SZWR1Y3Rpb25EYiA9XG4gICAgICAoMSAvIHRoaXMucmF0aW8gLSAxKSAqIE1hdGgucG93KHgsIDIpIC8gKDIgKiB0aGlzLmtuZWVXaWR0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdhaW5SZWR1Y3Rpb25EYiA9IChpbnB1dERiIC0gdGhpcy50aHJlc2hvbGQpICogKDEgLSAxIC8gdGhpcy5yYXRpbyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZGJUb0xpbmVhcigtZ2FpblJlZHVjdGlvbkRiICsgdGhpcy5tYWtldXBHYWluKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc1NhbXBsZShpbnB1dDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkgcmV0dXJuIGlucHV0O1xuXG4gICAgY29uc3QgaW5wdXRGbG9hdCA9IGlucHV0IC8gdGhpcy5leHRyZW11bTtcblxuICAgIGNvbnN0IGlucHV0TGV2ZWwgPSBNYXRoLmFicyhpbnB1dEZsb2F0KTtcbiAgICBjb25zdCBjb2VmZiA9IGlucHV0TGV2ZWwgPiB0aGlzLmVudmVsb3BlID8gdGhpcy5hdHRhY2sgOiB0aGlzLnJlbGVhc2U7XG4gICAgdGhpcy5lbnZlbG9wZSA9IGNvZWZmICogdGhpcy5lbnZlbG9wZSArICgxIC0gY29lZmYpICogaW5wdXRMZXZlbDtcblxuICAgIGNvbnN0IHRhcmdldEdhaW5SZWR1Y3Rpb24gPSB0aGlzLmNvbXB1dGVHYWluUmVkdWN0aW9uKHRoaXMuZW52ZWxvcGUpO1xuXG4gICAgdGhpcy5nYWluUmVkdWN0aW9uID0gTWF0aC5taW4oXG4gICAgICB0aGlzLnByZXZpb3VzR2FpblJlZHVjdGlvbiAqIHRoaXMuYXR0YWNrICtcbiAgICAgIHRhcmdldEdhaW5SZWR1Y3Rpb24gKiAoMSAtIHRoaXMuYXR0YWNrKSxcbiAgICAgIHRhcmdldEdhaW5SZWR1Y3Rpb25cbiAgICApO1xuICAgIHRoaXMucHJldmlvdXNHYWluUmVkdWN0aW9uID0gdGhpcy5nYWluUmVkdWN0aW9uO1xuXG4gICAgY29uc3Qgb3V0cHV0RmxvYXQgPSBpbnB1dEZsb2F0ICogdGhpcy5nYWluUmVkdWN0aW9uO1xuXG4gICAgcmV0dXJuIHRoaXMuY2xhbXAoTWF0aC5mbG9vcihvdXRwdXRGbG9hdCAqIHRoaXMuZXh0cmVtdW0pKTtcbiAgfVxuXG4gIHB1YmxpYyBvdmVycmlkZSBfdHJhbnNmb3JtKFxuICBjaHVuazogQnVmZmVyLFxuICBlbmNvZGluZzogQnVmZmVyRW5jb2RpbmcsXG4gIGNhbGxiYWNrOiAoZXJyb3I/OiBFcnJvciB8IG51bGwsIGRhdGE/OiBCdWZmZXIpID0+IHZvaWQpXG4gIDogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIGNhbGxiYWNrKG51bGwsIGNodW5rKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBvdXRwdXQgPSBCdWZmZXIuYWxsb2MoY2h1bmsubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2h1bmsubGVuZ3RoOyBpICs9IHRoaXMuYnl0ZXMpIHtcbiAgICAgIGNvbnN0IHNhbXBsZSA9IHRoaXMuX3JlYWRJbnQoY2h1bmssIGkpO1xuICAgICAgY29uc3QgcHJvY2Vzc2VkID0gdGhpcy5wcm9jZXNzU2FtcGxlKHNhbXBsZSk7XG4gICAgICB0aGlzLl93cml0ZUludChvdXRwdXQsIHByb2Nlc3NlZCwgaSk7XG4gICAgfVxuXG4gICAgY2FsbGJhY2sobnVsbCwgb3V0cHV0KTtcbiAgfVxufSIsICJpbXBvcnQgeyBQQ01UcmFuc2Zvcm1lciwgUENNVHJhbnNmb3JtZXJPcHRpb25zIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRzJztcblxuZXhwb3J0IGludGVyZmFjZSBQQ01TZWVrZXJPcHRpb25zIGV4dGVuZHMgUENNVHJhbnNmb3JtZXJPcHRpb25zIHtcbiAgdG90YWxEdXJhdGlvbjogbnVtYmVyO1xuICBjaGFubmVsczogbnVtYmVyO1xuICBzZWVrVGFyZ2V0PzogbnVtYmVyIHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZWVrZXJQYXJhbWV0ZXJzIHtcbiAgY3VycmVudFBvc2l0aW9uOiBudW1iZXI7XG4gIHNlZWtUYXJnZXQ6IG51bWJlciB8IG51bGw7XG4gIHRvdGFsRHVyYXRpb246IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZWVrRXZlbnQge1xuICBwb3NpdGlvbjogbnVtYmVyO1xuICBzYW1wbGU6IG51bWJlcjtcbiAgYnl0ZVBvc2l0aW9uOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBQQ01TZWVrZXJUcmFuc2Zvcm1lciBleHRlbmRzIFBDTVRyYW5zZm9ybWVyIHtcbiAgcHJpdmF0ZSB0b3RhbER1cmF0aW9uOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2hhbm5lbHM6IG51bWJlcjtcbiAgcHJpdmF0ZSBieXRlc1BlckZyYW1lITogbnVtYmVyO1xuICBwcml2YXRlIGN1cnJlbnRQb3NpdGlvbiA9IDA7XG4gIHByaXZhdGUgc2Vla1RhcmdldDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgYnVmZmVyOiBCdWZmZXIgPSBCdWZmZXIuYWxsb2MoMCk7XG4gIHB1YmxpYyByZWFkb25seSBldmVudHMgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKFxuICBvcHRpb25zOiBQQ01TZWVrZXJPcHRpb25zID0ge1xuICAgIGNoYW5uZWxzOiAyLFxuICAgIHRvdGFsRHVyYXRpb246IDBcbiAgfSlcbiAge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuXG4gICAgaWYgKG9wdGlvbnMudG90YWxEdXJhdGlvbiA9PSBudWxsIHx8IG9wdGlvbnMudG90YWxEdXJhdGlvbiA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndG90YWxEdXJhdGlvbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLmNoYW5uZWxzIHx8IG9wdGlvbnMuY2hhbm5lbHMgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjaGFubmVscyBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgdGhpcy50b3RhbER1cmF0aW9uID0gb3B0aW9ucy50b3RhbER1cmF0aW9uO1xuICAgIHRoaXMuY2hhbm5lbHMgPSBvcHRpb25zLmNoYW5uZWxzO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnNlZWtUYXJnZXQgPT09ICdudW1iZXInICYmIG9wdGlvbnMuc2Vla1RhcmdldCA+IDApIHtcbiAgICAgIHRoaXMuc2Vla1RhcmdldCA9IG9wdGlvbnMuc2Vla1RhcmdldDtcbiAgICB9XG5cbiAgICB0aGlzLnVwZGF0ZURlcGVuZGVudFZhbHVlcygpO1xuICB9XG5cbiAgcHVibGljIGdldFBhcmFtZXRlcnMoKTogU2Vla2VyUGFyYW1ldGVycyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGN1cnJlbnRQb3NpdGlvbjogdGhpcy5jdXJyZW50UG9zaXRpb24sXG4gICAgICBzZWVrVGFyZ2V0OiB0aGlzLnNlZWtUYXJnZXQsXG4gICAgICB0b3RhbER1cmF0aW9uOiB0aGlzLnRvdGFsRHVyYXRpb25cbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVEZXBlbmRlbnRWYWx1ZXMoKTogdm9pZCB7XG4gICAgdGhpcy5ieXRlc1BlckZyYW1lID0gdGhpcy5ieXRlcyAqIHRoaXMuY2hhbm5lbHM7XG5cbiAgICBpZiAodGhpcy5jdXJyZW50UG9zaXRpb24gPiAwKSB7XG4gICAgICBjb25zdCBjdXJyZW50TXMgPSB0aGlzLmN1cnJlbnRQb3NpdGlvbiAvICh0aGlzLnNhbXBsZVJhdGUgLyAxMDAwKTtcbiAgICAgIHRoaXMuY3VycmVudFBvc2l0aW9uID0gTWF0aC5mbG9vcihjdXJyZW50TXMgLyAxMDAwICogdGhpcy5zYW1wbGVSYXRlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zZWVrVGFyZ2V0ICE9PSBudWxsKSB7XG4gICAgICBjb25zdCBzZWVrTXMgPSB0aGlzLnNlZWtUYXJnZXQgLyAodGhpcy5zYW1wbGVSYXRlIC8gMTAwMCk7XG4gICAgICB0aGlzLnNlZWtUYXJnZXQgPSBNYXRoLmZsb29yKHNlZWtNcyAvIDEwMDAgKiB0aGlzLnNhbXBsZVJhdGUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgYnl0ZSBwb3NpdGlvbiBmcm9tIHNhbXBsZSBwb3NpdGlvblxuICAgKiBAcGFyYW0gc2FtcGxlUG9zaXRpb24gUG9zaXRpb24gaW4gc2FtcGxlc1xuICAgKiBAcmV0dXJucyBQb3NpdGlvbiBpbiBieXRlc1xuICAgKi9cbiAgcHJpdmF0ZSBzYW1wbGVUb0J5dGVQb3NpdGlvbihzYW1wbGVQb3NpdGlvbjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gc2FtcGxlUG9zaXRpb24gKiB0aGlzLmJ5dGVzUGVyRnJhbWU7XG4gIH1cblxuICBwdWJsaWMgc2V0VG90YWxEdXJhdGlvbihkdXJhdGlvbjogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKGR1cmF0aW9uIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndG90YWxEdXJhdGlvbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgdGhpcy50b3RhbER1cmF0aW9uID0gZHVyYXRpb247XG4gICAgdGhpcy51cGRhdGVEZXBlbmRlbnRWYWx1ZXMoKTtcbiAgICB0aGlzLm9uVXBkYXRlKCk7XG4gIH1cblxuICBwdWJsaWMgb3ZlcnJpZGUgc2V0U2FtcGxlUmF0ZShyYXRlOiBudW1iZXIpOiB2b2lkIHtcbiAgICBzdXBlci5zZXRTYW1wbGVSYXRlKHJhdGUpO1xuICAgIHRoaXMudXBkYXRlRGVwZW5kZW50VmFsdWVzKCk7XG4gICAgdGhpcy5vblVwZGF0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlZWsgdG8gYSBzcGVjaWZpYyBwb3NpdGlvbiBpbiBtaWxsaXNlY29uZHNcbiAgICogQHBhcmFtIG1zIFBvc2l0aW9uIGluIG1pbGxpc2Vjb25kcyAobmVnYXRpdmUgdmFsdWVzIHNlZWsgZnJvbSBlbmQpXG4gICAqIEByZXR1cm5zIEFjdHVhbCBwb3NpdGlvbiBpbiBtaWxsaXNlY29uZHMgYWZ0ZXIgc2Vla2luZ1xuICAgKi9cbiAgcHVibGljIHNlZWsobXM6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKHRoaXMudG90YWxEdXJhdGlvbiA9PT0gMCkgcmV0dXJuIDA7XG5cbiAgICBpZiAobXMgPCAwKSB7XG4gICAgICBtcyA9IE1hdGgubWF4KDAsIHRoaXMudG90YWxEdXJhdGlvbiArIG1zKTtcbiAgICB9XG5cbiAgICBtcyA9IE1hdGgubWF4KDAsIE1hdGgubWluKHRoaXMudG90YWxEdXJhdGlvbiwgbXMpKTtcbiAgICBjb25zdCB0YXJnZXRTYW1wbGUgPSBNYXRoLmZsb29yKG1zIC8gMTAwMCAqIHRoaXMuc2FtcGxlUmF0ZSk7XG5cbiAgICBpZiAodGFyZ2V0U2FtcGxlIDwgdGhpcy5jdXJyZW50UG9zaXRpb24pIHtcbiAgICAgIHRoaXMuYnVmZmVyID0gQnVmZmVyLmFsbG9jKDApO1xuXG4gICAgICBjb25zdCBieXRlUG9zaXRpb24gPSB0aGlzLnNhbXBsZVRvQnl0ZVBvc2l0aW9uKHRhcmdldFNhbXBsZSk7XG5cbiAgICAgIHRoaXMuZXZlbnRzLmVtaXQoJ3NlZWsnLCB7XG4gICAgICAgIHBvc2l0aW9uOiBtcyxcbiAgICAgICAgc2FtcGxlOiB0YXJnZXRTYW1wbGUsXG4gICAgICAgIGJ5dGVQb3NpdGlvbjogYnl0ZVBvc2l0aW9uXG4gICAgICB9IGFzIFNlZWtFdmVudCk7XG4gICAgfVxuXG4gICAgdGhpcy5zZWVrVGFyZ2V0ID0gdGFyZ2V0U2FtcGxlO1xuICAgIHJldHVybiB0YXJnZXRTYW1wbGUgLyB0aGlzLnNhbXBsZVJhdGUgKiAxMDAwO1xuICB9XG5cbiAgcHVibGljIGdldFBvc2l0aW9uKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuY3VycmVudFBvc2l0aW9uIC8gdGhpcy5zYW1wbGVSYXRlICogMTAwMDtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlU2VlayhjaHVuazogQnVmZmVyKTogQnVmZmVyIHtcbiAgICBpZiAodGhpcy5zZWVrVGFyZ2V0ID09PSBudWxsKSByZXR1cm4gY2h1bms7XG5cbiAgICBjb25zdCBjaHVua1N0YXJ0U2FtcGxlID0gdGhpcy5jdXJyZW50UG9zaXRpb247XG4gICAgY29uc3QgY2h1bmtTYW1wbGVzID0gTWF0aC5mbG9vcihjaHVuay5sZW5ndGggLyB0aGlzLmJ5dGVzUGVyRnJhbWUpO1xuICAgIGNvbnN0IGNodW5rRW5kU2FtcGxlID0gY2h1bmtTdGFydFNhbXBsZSArIGNodW5rU2FtcGxlcztcblxuICAgIGlmICh0aGlzLnNlZWtUYXJnZXQgPj0gY2h1bmtFbmRTYW1wbGUpIHtcbiAgICAgIHRoaXMuY3VycmVudFBvc2l0aW9uICs9IGNodW5rU2FtcGxlcztcbiAgICAgIHJldHVybiBCdWZmZXIuYWxsb2MoMCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2Vla1RhcmdldCA+PSBjaHVua1N0YXJ0U2FtcGxlKSB7XG4gICAgICBjb25zdCBvZmZzZXRTYW1wbGVzID0gdGhpcy5zZWVrVGFyZ2V0IC0gY2h1bmtTdGFydFNhbXBsZTtcbiAgICAgIGNvbnN0IG9mZnNldEJ5dGVzID0gb2Zmc2V0U2FtcGxlcyAqIHRoaXMuYnl0ZXNQZXJGcmFtZTtcbiAgICAgIHRoaXMuY3VycmVudFBvc2l0aW9uID0gdGhpcy5zZWVrVGFyZ2V0O1xuICAgICAgdGhpcy5zZWVrVGFyZ2V0ID0gbnVsbDtcbiAgICAgIHJldHVybiBjaHVuay5zdWJhcnJheShvZmZzZXRCeXRlcyk7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyZW50UG9zaXRpb24gPSB0aGlzLnNlZWtUYXJnZXQ7XG4gICAgdGhpcy5zZWVrVGFyZ2V0ID0gbnVsbDtcbiAgICByZXR1cm4gY2h1bms7XG4gIH1cblxuICBwdWJsaWMgb3ZlcnJpZGUgX3RyYW5zZm9ybShcbiAgY2h1bms6IEJ1ZmZlcixcbiAgZW5jb2Rpbmc6IEJ1ZmZlckVuY29kaW5nLFxuICBjYWxsYmFjazogKGVycm9yPzogRXJyb3IgfCBudWxsLCBkYXRhPzogQnVmZmVyKSA9PiB2b2lkKVxuICA6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBpZiAodGhpcy5kaXNhYmxlZCB8fCB0aGlzLnRvdGFsRHVyYXRpb24gPT09IDApIHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgY2h1bmspO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNvbWJpbmVkQnVmZmVyID0gQnVmZmVyLmNvbmNhdChbdGhpcy5idWZmZXIsIGNodW5rXSk7XG4gICAgICBjb25zdCBmcmFtZUNvdW50ID0gTWF0aC5mbG9vcihjb21iaW5lZEJ1ZmZlci5sZW5ndGggLyB0aGlzLmJ5dGVzUGVyRnJhbWUpO1xuICAgICAgY29uc3QgcHJvY2Vzc2FibGVCeXRlcyA9IGZyYW1lQ291bnQgKiB0aGlzLmJ5dGVzUGVyRnJhbWU7XG5cbiAgICAgIHRoaXMuYnVmZmVyID0gY29tYmluZWRCdWZmZXIuc3ViYXJyYXkocHJvY2Vzc2FibGVCeXRlcyk7XG5cbiAgICAgIGxldCBwcm9jZXNzQnVmZmVyID0gY29tYmluZWRCdWZmZXIuc3ViYXJyYXkoMCwgcHJvY2Vzc2FibGVCeXRlcyk7XG5cbiAgICAgIGlmICh0aGlzLnNlZWtUYXJnZXQgIT09IG51bGwpIHtcbiAgICAgICAgcHJvY2Vzc0J1ZmZlciA9IHRoaXMuaGFuZGxlU2Vlayhwcm9jZXNzQnVmZmVyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY3VycmVudFBvc2l0aW9uICs9IGZyYW1lQ291bnQ7XG4gICAgICB9XG5cbiAgICAgIGNhbGxiYWNrKG51bGwsIHByb2Nlc3NCdWZmZXIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjYWxsYmFjayhlcnJvciBhcyBFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG92ZXJyaWRlIF9mbHVzaChcbiAgY2FsbGJhY2s6IChlcnJvcj86IEVycm9yIHwgbnVsbCwgZGF0YT86IEJ1ZmZlcikgPT4gdm9pZClcbiAgOiB2b2lkIHtcbiAgICBpZiAodGhpcy5idWZmZXIubGVuZ3RoID49IHRoaXMuYnl0ZXNQZXJGcmFtZSkge1xuICAgICAgY29uc3QgZnJhbWVDb3VudCA9IE1hdGguZmxvb3IodGhpcy5idWZmZXIubGVuZ3RoIC8gdGhpcy5ieXRlc1BlckZyYW1lKTtcbiAgICAgIGNvbnN0IHByb2Nlc3NhYmxlQnl0ZXMgPSBmcmFtZUNvdW50ICogdGhpcy5ieXRlc1BlckZyYW1lO1xuICAgICAgY2FsbGJhY2sobnVsbCwgdGhpcy5idWZmZXIuc3ViYXJyYXkoMCwgcHJvY2Vzc2FibGVCeXRlcykpO1xuICAgIH1cblxuICAgIGNhbGxiYWNrKCk7XG4gIH1cbn0iLCAiaW1wb3J0IHsgUENNVHJhbnNmb3JtZXIsIFBDTVRyYW5zZm9ybWVyT3B0aW9ucyB9IGZyb20gJy4uL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBSZXZlcmJPcHRpb25zIGV4dGVuZHMgUENNVHJhbnNmb3JtZXJPcHRpb25zIHtcbiAgcm9vbVNpemU/OiBudW1iZXI7XG4gIGRhbXBpbmc/OiBudW1iZXI7XG4gIHdldExldmVsPzogbnVtYmVyO1xuICBkcnlMZXZlbD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXZlcmJQYXJhbWV0ZXJzIHtcbiAgcm9vbVNpemU6IG51bWJlcjtcbiAgZGFtcGluZzogbnVtYmVyO1xuICB3ZXRMZXZlbDogbnVtYmVyO1xuICBkcnlMZXZlbDogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgUmV2ZXJiVHJhbnNmb3JtZXIgZXh0ZW5kcyBQQ01UcmFuc2Zvcm1lciB7XG4gIHByaXZhdGUgcm9vbVNpemU6IG51bWJlcjtcbiAgcHJpdmF0ZSBkYW1waW5nOiBudW1iZXI7XG4gIHByaXZhdGUgd2V0TGV2ZWw6IG51bWJlcjtcbiAgcHJpdmF0ZSBkcnlMZXZlbDogbnVtYmVyO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVsYXlMaW5lczogRmxvYXQzMkFycmF5W107XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVsYXlMaW5lTGVuZ3RoOiBudW1iZXI7XG4gIHByaXZhdGUgZGVsYXlJbmRpY2VzOiBudW1iZXJbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBudW1EZWxheUxpbmVzID0gODtcbiAgcHJpdmF0ZSByZWFkb25seSBmZWVkYmFjazogbnVtYmVyID0gMC44NDtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBSZXZlcmJPcHRpb25zID0ge30pIHtcbiAgICBzdXBlcihvcHRpb25zKTtcblxuICAgIHRoaXMucm9vbVNpemUgPSBvcHRpb25zLnJvb21TaXplID8/IDAuNTtcbiAgICB0aGlzLmRhbXBpbmcgPSBvcHRpb25zLmRhbXBpbmcgPz8gMC41O1xuICAgIHRoaXMud2V0TGV2ZWwgPSBvcHRpb25zLndldExldmVsID8/IDAuMztcbiAgICB0aGlzLmRyeUxldmVsID0gb3B0aW9ucy5kcnlMZXZlbCA/PyAwLjc7XG5cbiAgICB0aGlzLmRlbGF5TGluZUxlbmd0aCA9IE1hdGguZmxvb3IodGhpcy5zYW1wbGVSYXRlICogMC4wNSk7XG4gICAgdGhpcy5kZWxheUxpbmVzID0gQXJyYXkuZnJvbShcbiAgICAgIHsgbGVuZ3RoOiB0aGlzLm51bURlbGF5TGluZXMgfSxcbiAgICAgICgpID0+IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5kZWxheUxpbmVMZW5ndGgpXG4gICAgKTtcbiAgICB0aGlzLmRlbGF5SW5kaWNlcyA9IEFycmF5KHRoaXMubnVtRGVsYXlMaW5lcykuZmlsbCgwKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRSb29tU2l6ZShzaXplOiBudW1iZXIpIHtcbiAgICB0aGlzLnJvb21TaXplID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgc2l6ZSkpO1xuICAgIHRoaXMub25VcGRhdGUoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXREYW1waW5nKGRhbXBpbmc6IG51bWJlcikge1xuICAgIHRoaXMuZGFtcGluZyA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIGRhbXBpbmcpKTtcbiAgICB0aGlzLm9uVXBkYXRlKCk7XG4gIH1cblxuICBwdWJsaWMgc2V0V2V0TGV2ZWwobGV2ZWw6IG51bWJlcikge1xuICAgIHRoaXMud2V0TGV2ZWwgPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBsZXZlbCkpO1xuICAgIHRoaXMub25VcGRhdGUoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXREcnlMZXZlbChsZXZlbDogbnVtYmVyKSB7XG4gICAgdGhpcy5kcnlMZXZlbCA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIGxldmVsKSk7XG4gICAgdGhpcy5vblVwZGF0ZSgpO1xuICB9XG5cbiAgcHVibGljIHNldFJldmVyYihvcHRpb25zOiBQYXJ0aWFsPFJldmVyYlBhcmFtZXRlcnM+KSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnJvb21TaXplID09PSAnbnVtYmVyJykge1xuICAgICAgdGhpcy5zZXRSb29tU2l6ZShvcHRpb25zLnJvb21TaXplKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZGFtcGluZyA9PT0gJ251bWJlcicpIHtcbiAgICAgIHRoaXMuc2V0RGFtcGluZyhvcHRpb25zLmRhbXBpbmcpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy53ZXRMZXZlbCA9PT0gJ251bWJlcicpIHtcbiAgICAgIHRoaXMuc2V0V2V0TGV2ZWwob3B0aW9ucy53ZXRMZXZlbCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmRyeUxldmVsID09PSAnbnVtYmVyJykge1xuICAgICAgdGhpcy5zZXREcnlMZXZlbChvcHRpb25zLmRyeUxldmVsKTtcbiAgICB9XG5cbiAgICB0aGlzLm9uVXBkYXRlKCk7XG5cbiAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXJzKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0UGFyYW1ldGVycygpOiBSZXZlcmJQYXJhbWV0ZXJzIHtcbiAgICByZXR1cm4ge1xuICAgICAgcm9vbVNpemU6IHRoaXMucm9vbVNpemUsXG4gICAgICBkYW1waW5nOiB0aGlzLmRhbXBpbmcsXG4gICAgICB3ZXRMZXZlbDogdGhpcy53ZXRMZXZlbCxcbiAgICAgIGRyeUxldmVsOiB0aGlzLmRyeUxldmVsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc1NhbXBsZShpbnB1dDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkgcmV0dXJuIGlucHV0O1xuXG4gICAgY29uc3QgaW5wdXRGbG9hdCA9IGlucHV0IC8gdGhpcy5leHRyZW11bTtcbiAgICBsZXQgd2V0ID0gMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5udW1EZWxheUxpbmVzOyBpKyspIHtcbiAgICAgIGNvbnN0IGRlbGF5TGluZSA9IHRoaXMuZGVsYXlMaW5lc1tpXTtcbiAgICAgIGNvbnN0IGRlbGF5SW5kZXggPSB0aGlzLmRlbGF5SW5kaWNlc1tpXTtcblxuICAgICAgY29uc3QgZGVsYXllZCA9IGRlbGF5TGluZVtkZWxheUluZGV4XTtcblxuICAgICAgY29uc3QgcHJvY2Vzc2VkID0gZGVsYXllZCAqIHRoaXMucm9vbVNpemUgKiAoMSAtIHRoaXMuZGFtcGluZyk7XG5cbiAgICAgIGRlbGF5TGluZVtkZWxheUluZGV4XSA9IGlucHV0RmxvYXQgKyBwcm9jZXNzZWQgKiB0aGlzLmZlZWRiYWNrO1xuXG4gICAgICB0aGlzLmRlbGF5SW5kaWNlc1tpXSA9IChkZWxheUluZGV4ICsgMSkgJSB0aGlzLmRlbGF5TGluZUxlbmd0aDtcblxuICAgICAgd2V0ICs9IHByb2Nlc3NlZDtcbiAgICB9XG5cbiAgICBjb25zdCBvdXRwdXQgPVxuICAgIGlucHV0RmxvYXQgKiB0aGlzLmRyeUxldmVsICsgd2V0ICogdGhpcy53ZXRMZXZlbCAvIHRoaXMubnVtRGVsYXlMaW5lcztcblxuICAgIHJldHVybiB0aGlzLmNsYW1wKE1hdGguZmxvb3Iob3V0cHV0ICogdGhpcy5leHRyZW11bSkpO1xuICB9XG5cbiAgcHVibGljIG92ZXJyaWRlIF90cmFuc2Zvcm0oXG4gIGNodW5rOiBCdWZmZXIsXG4gIGVuY29kaW5nOiBCdWZmZXJFbmNvZGluZyxcbiAgY2FsbGJhY2s6IChlcnJvcj86IEVycm9yIHwgbnVsbCwgZGF0YT86IEJ1ZmZlcikgPT4gdm9pZClcbiAgOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgY2FsbGJhY2sobnVsbCwgY2h1bmspO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG91dHB1dCA9IEJ1ZmZlci5hbGxvYyhjaHVuay5sZW5ndGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaHVuay5sZW5ndGg7IGkgKz0gdGhpcy5ieXRlcykge1xuICAgICAgY29uc3Qgc2FtcGxlID0gdGhpcy5fcmVhZEludChjaHVuaywgaSk7XG4gICAgICBjb25zdCBwcm9jZXNzZWQgPSB0aGlzLnByb2Nlc3NTYW1wbGUoc2FtcGxlKTtcbiAgICAgIHRoaXMuX3dyaXRlSW50KG91dHB1dCwgcHJvY2Vzc2VkLCBpKTtcbiAgICB9XG5cbiAgICBjYWxsYmFjayhudWxsLCBvdXRwdXQpO1xuICB9XG59IiwgImltcG9ydCB7IHR5cGUgUmVhZGFibGUsIHBpcGVsaW5lIH0gZnJvbSAnc3RyZWFtJztcbmltcG9ydCB7IEVxdWFsaXplclN0cmVhbSwgRXF1YWxpemVyU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4vZXF1YWxpemVyJztcbmltcG9ydCB7XG4gIEF1ZGlvRmlsdGVyLFxuICBDb21wcmVzc29yT3B0aW9ucyxcbiAgQ29tcHJlc3NvclRyYW5zZm9ybWVyLFxuICBQQ01GaWx0ZXJlck9wdGlvbnMsXG4gIFBDTVJlc2FtcGxlcixcbiAgUENNUmVzYW1wbGVyT3B0aW9ucyxcbiAgUENNU2Vla2VyT3B0aW9ucyxcbiAgUENNU2Vla2VyVHJhbnNmb3JtZXIsXG4gIFJldmVyYk9wdGlvbnMsXG4gIFJldmVyYlRyYW5zZm9ybWVyIH0gZnJvbVxuJy4vYXVkaW8nO1xuaW1wb3J0IHsgQmlxdWFkU3RyZWFtLCBCaXF1YWRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi9iaXF1YWQnO1xuaW1wb3J0IHtcbiAgVm9sdW1lVHJhbnNmb3JtZXIsXG4gIFZvbHVtZVRyYW5zZm9ybWVyT3B0aW9ucyB9IGZyb21cbicuL2F1ZGlvL1ZvbHVtZVRyYW5zZm9ybWVyJztcblxuZXhwb3J0IGludGVyZmFjZSBEU1BGaWx0ZXJzUHJlc2V0IHtcbiAgZXF1YWxpemVyPzogRXF1YWxpemVyU3RyZWFtT3B0aW9ucztcbiAgZHNwPzogUENNRmlsdGVyZXJPcHRpb25zO1xuICBiaXF1YWQ/OiBCaXF1YWRTdHJlYW1PcHRpb25zO1xuICB2b2x1bWU/OiBWb2x1bWVUcmFuc2Zvcm1lck9wdGlvbnM7XG4gIHJlc2FtcGxlcj86IFBDTVJlc2FtcGxlck9wdGlvbnM7XG4gIGNvbXByZXNzb3I/OiBDb21wcmVzc29yT3B0aW9ucztcbiAgc2Vla2VyPzogUENNU2Vla2VyT3B0aW9ucztcbiAgcmV2ZXJiPzogUmV2ZXJiT3B0aW9ucztcbn1cblxuZXhwb3J0IGNsYXNzIEZpbHRlcnNDaGFpbiB7XG4gIHB1YmxpYyBlcXVhbGl6ZXI6IEVxdWFsaXplclN0cmVhbSB8IG51bGwgPSBudWxsO1xuICBwdWJsaWMgZmlsdGVyczogQXVkaW9GaWx0ZXIgfCBudWxsID0gbnVsbDtcbiAgcHVibGljIGJpcXVhZDogQmlxdWFkU3RyZWFtIHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyB2b2x1bWU6IFZvbHVtZVRyYW5zZm9ybWVyIHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyByZXNhbXBsZXI6IFBDTVJlc2FtcGxlciB8IG51bGwgPSBudWxsO1xuICBwdWJsaWMgY29tcHJlc3NvcjogQ29tcHJlc3NvclRyYW5zZm9ybWVyIHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyBzZWVrZXI6IFBDTVNlZWtlclRyYW5zZm9ybWVyIHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyByZXZlcmI6IFJldmVyYlRyYW5zZm9ybWVyIHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyBkZXN0aW5hdGlvbjogUmVhZGFibGUgfCBudWxsID0gbnVsbDtcbiAgcHVibGljIHNvdXJjZTogUmVhZGFibGUgfCBudWxsID0gbnVsbDtcbiAgcHVibGljIG9uVXBkYXRlOiAoKSA9PiB1bmtub3duID0gKCkgPT4gbnVsbDtcbiAgcHVibGljIG9uRXJyb3I6IChlcnI6IEVycm9yKSA9PiB1bmtub3duID0gKCkgPT4gbnVsbDtcblxuICBwdWJsaWMgY29uc3RydWN0b3IocHVibGljIHByZXNldHM6IERTUEZpbHRlcnNQcmVzZXQgPSB7fSkge31cblxuICBwdWJsaWMgY3JlYXRlKHNyYzogUmVhZGFibGUsIHByZXNldHM6IERTUEZpbHRlcnNQcmVzZXQgPSB0aGlzLnByZXNldHMpIHtcbiAgICB0aGlzLmRlc3Ryb3koKTtcblxuICAgIHRoaXMuc291cmNlID0gc3JjO1xuXG4gICAgY29uc3QgcmVzYW1wbGVyID0gIXByZXNldHMucmVzYW1wbGVyPy5kaXNhYmxlZCA/XG4gICAgbmV3IFBDTVJlc2FtcGxlcihwcmVzZXRzLnJlc2FtcGxlcikgOlxuICAgIG51bGw7XG5cbiAgICBjb25zdCBlcXVhbGl6ZXJTdHJlYW0gPSAhcHJlc2V0cy5lcXVhbGl6ZXI/LmRpc2FibGVkID9cbiAgICBuZXcgRXF1YWxpemVyU3RyZWFtKHByZXNldHMuZXF1YWxpemVyKSA6XG4gICAgbnVsbDtcblxuICAgIGNvbnN0IGRzcFN0cmVhbSA9ICFwcmVzZXRzLmRzcD8uZGlzYWJsZWQgP1xuICAgIG5ldyBBdWRpb0ZpbHRlcihwcmVzZXRzLmRzcCkgOlxuICAgIG51bGw7XG5cbiAgICBjb25zdCBiaXF1YWRTdHJlYW0gPSAhcHJlc2V0cy5iaXF1YWQ/LmRpc2FibGVkID9cbiAgICBuZXcgQmlxdWFkU3RyZWFtKHByZXNldHMuYmlxdWFkKSA6XG4gICAgbnVsbDtcblxuICAgIGNvbnN0IHZvbHVtZVRyYW5zZm9ybWVyID0gIXByZXNldHMudm9sdW1lPy5kaXNhYmxlZCA/XG4gICAgbmV3IFZvbHVtZVRyYW5zZm9ybWVyKHByZXNldHMudm9sdW1lKSA6XG4gICAgbnVsbDtcblxuICAgIGNvbnN0IGNvbXByZXNzb3IgPSAhcHJlc2V0cy5jb21wcmVzc29yPy5kaXNhYmxlZCA/XG4gICAgbmV3IENvbXByZXNzb3JUcmFuc2Zvcm1lcihwcmVzZXRzLmNvbXByZXNzb3IpIDpcbiAgICBudWxsO1xuXG4gICAgY29uc3Qgc2Vla2VyID0gIXByZXNldHMuc2Vla2VyPy5kaXNhYmxlZCA/XG4gICAgbmV3IFBDTVNlZWtlclRyYW5zZm9ybWVyKHByZXNldHMuc2Vla2VyKSA6XG4gICAgbnVsbDtcblxuICAgIGNvbnN0IHJldmVyYiA9ICFwcmVzZXRzLnJldmVyYj8uZGlzYWJsZWQgP1xuICAgIG5ldyBSZXZlcmJUcmFuc2Zvcm1lcihwcmVzZXRzLnJldmVyYikgOlxuICAgIG51bGw7XG5cbiAgICB0aGlzLnJlc2FtcGxlciA9IHJlc2FtcGxlcjtcbiAgICB0aGlzLmVxdWFsaXplciA9IGVxdWFsaXplclN0cmVhbTtcbiAgICB0aGlzLmZpbHRlcnMgPSBkc3BTdHJlYW07XG4gICAgdGhpcy5iaXF1YWQgPSBiaXF1YWRTdHJlYW07XG4gICAgdGhpcy52b2x1bWUgPSB2b2x1bWVUcmFuc2Zvcm1lcjtcbiAgICB0aGlzLmNvbXByZXNzb3IgPSBjb21wcmVzc29yO1xuICAgIHRoaXMuc2Vla2VyID0gc2Vla2VyO1xuICAgIHRoaXMucmV2ZXJiID0gcmV2ZXJiO1xuXG4gICAgLy8gdXBkYXRlIGxpc3RlbmVyc1xuICAgIGlmIChyZXNhbXBsZXIpIHJlc2FtcGxlci5vblVwZGF0ZSA9IHRoaXMub25VcGRhdGU7XG4gICAgaWYgKGVxdWFsaXplclN0cmVhbSkgZXF1YWxpemVyU3RyZWFtLm9uVXBkYXRlID0gdGhpcy5vblVwZGF0ZTtcbiAgICBpZiAoZHNwU3RyZWFtKSBkc3BTdHJlYW0ub25VcGRhdGUgPSB0aGlzLm9uVXBkYXRlO1xuICAgIGlmIChiaXF1YWRTdHJlYW0pIGJpcXVhZFN0cmVhbS5vblVwZGF0ZSA9IHRoaXMub25VcGRhdGU7XG4gICAgaWYgKHZvbHVtZVRyYW5zZm9ybWVyKSB2b2x1bWVUcmFuc2Zvcm1lci5vblVwZGF0ZSA9IHRoaXMub25VcGRhdGU7XG4gICAgaWYgKGNvbXByZXNzb3IpIGNvbXByZXNzb3Iub25VcGRhdGUgPSB0aGlzLm9uVXBkYXRlO1xuICAgIGlmIChzZWVrZXIpIHNlZWtlci5vblVwZGF0ZSA9IHRoaXMub25VcGRhdGU7XG4gICAgaWYgKHJldmVyYikgcmV2ZXJiLm9uVXBkYXRlID0gdGhpcy5vblVwZGF0ZTtcblxuICAgIGNvbnN0IGNoYWlucyA9IFtcbiAgICBzcmMsXG4gICAgcmVzYW1wbGVyLFxuICAgIGVxdWFsaXplclN0cmVhbSxcbiAgICByZXZlcmIsXG4gICAgZHNwU3RyZWFtLFxuICAgIGJpcXVhZFN0cmVhbSxcbiAgICBjb21wcmVzc29yLFxuICAgIHZvbHVtZVRyYW5zZm9ybWVyLFxuICAgIHNlZWtlcl0uXG4gICAgZmlsdGVyKEJvb2xlYW4pIGFzIFJlYWRvbmx5PFJlYWRhYmxlW10+O1xuXG4gICAgaWYgKCFjaGFpbnMubGVuZ3RoKSByZXR1cm4gc3JjO1xuXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHRoaXMuZGVzdGluYXRpb24gPSBwaXBlbGluZSguLi5jaGFpbnMsIChlcnI6IEVycm9yIHwgbnVsbCkgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICB0aGlzLmRlc3Ryb3koKTtcbiAgICAgICAgaWYgKCFlcnIubWVzc2FnZS5pbmNsdWRlcygnRVJSX1NUUkVBTV9QUkVNQVRVUkVfQ0xPU0UnKSlcbiAgICAgICAgdGhpcy5vbkVycm9yKGVycik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmRlc3RpbmF0aW9uIS5vbmNlKCdjbG9zZScsIHRoaXMuZGVzdHJveS5iaW5kKHRoaXMpKTtcblxuICAgIHJldHVybiB0aGlzLmRlc3RpbmF0aW9uIGFzIFJlYWRhYmxlO1xuICB9XG5cbiAgcHVibGljIGRlc3Ryb3koKSB7XG4gICAgLy8gY2xlYW51cFxuICAgIHRoaXMucmVzYW1wbGVyPy5kZXN0cm95KCk7XG4gICAgdGhpcy5lcXVhbGl6ZXI/LmRlc3Ryb3koKTtcbiAgICB0aGlzLmJpcXVhZD8uZGVzdHJveSgpO1xuICAgIHRoaXMuZmlsdGVycz8uZGVzdHJveSgpO1xuICAgIHRoaXMudm9sdW1lPy5kZXN0cm95KCk7XG4gICAgdGhpcy5jb21wcmVzc29yPy5kZXN0cm95KCk7XG4gICAgdGhpcy5zZWVrZXI/LmRlc3Ryb3koKTtcbiAgICB0aGlzLnJldmVyYj8uZGVzdHJveSgpO1xuICAgIHRoaXMuZGVzdGluYXRpb24/LmRlc3Ryb3koKTtcbiAgICB0aGlzLnNvdXJjZT8uZGVzdHJveSgpO1xuXG4gICAgLy8gcmVtb3ZlIGV2ZW50c1xuICAgIHRoaXMucmVzYW1wbGVyPy5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLmVxdWFsaXplcj8ucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gICAgdGhpcy5iaXF1YWQ/LnJlbW92ZUFsbExpc3RlbmVycygpO1xuICAgIHRoaXMuZmlsdGVycz8ucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gICAgdGhpcy52b2x1bWU/LnJlbW92ZUFsbExpc3RlbmVycygpO1xuICAgIHRoaXMuY29tcHJlc3Nvcj8ucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gICAgdGhpcy5zZWVrZXI/LnJlbW92ZUFsbExpc3RlbmVycygpO1xuICAgIHRoaXMucmV2ZXJiPy5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLmRlc3RpbmF0aW9uPy5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLnNvdXJjZT8ucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG5cbiAgICAvLyB1bnJlZlxuICAgIHRoaXMucmVzYW1wbGVyID0gbnVsbDtcbiAgICB0aGlzLmVxdWFsaXplciA9IG51bGw7XG4gICAgdGhpcy5iaXF1YWQgPSBudWxsO1xuICAgIHRoaXMuZmlsdGVycyA9IG51bGw7XG4gICAgdGhpcy52b2x1bWUgPSBudWxsO1xuICAgIHRoaXMuY29tcHJlc3NvciA9IG51bGw7XG4gICAgdGhpcy5zZWVrZXIgPSBudWxsO1xuICAgIHRoaXMucmV2ZXJiID0gbnVsbDtcbiAgICB0aGlzLmRlc3RpbmF0aW9uID0gbnVsbDtcbiAgICB0aGlzLnNvdXJjZSA9IG51bGw7XG4gIH1cbn0iLCAiXG5cblxuXG5cblxuZXhwb3J0IGNvbnN0IHZlcnNpb24gPSAvKiBAX19NQUNST19fIGdldFZlcnNpb24gKi9cIjcuMi4wXCI7Il0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7OztBQUFPLElBQU0sYUFBYTtBQUFBLEVBQ3hCLHlCQUF5QjtBQUFBLEVBQ3pCLG1CQUFtQjtBQUFBLEVBQ25CLFNBQVM7QUFBQSxFQUNULFVBQVU7QUFBQSxFQUNWLFVBQVU7QUFBQSxFQUNWLE9BQU87QUFBQSxFQUNQLFNBQVM7QUFBQSxFQUNULFVBQVU7QUFBQSxFQUNWLFdBQVc7QUFBQSxFQUNYLFdBQVc7QUFDYjtBQWNPLElBQU0sZ0JBQWdCLEtBQUs7QUFFM0IsSUFBTSxnQkFBTixNQUFNLGNBQWE7QUFBQSxFQVVqQixZQUFZLE1BQXlCO0FBUjVDO0FBQUEsd0JBQU8sTUFBSztBQUNaLHdCQUFPLE1BQUs7QUFHWjtBQUFBLHdCQUFPLE1BQUs7QUFDWix3QkFBTyxNQUFLO0FBQ1osd0JBQU8sTUFBSztBQUdWLFFBQUksTUFBTTtBQUNSLFdBQUssS0FBSyxLQUFLO0FBQ2YsV0FBSyxLQUFLLEtBQUs7QUFDZixXQUFLLEtBQUssS0FBSztBQUNmLFdBQUssS0FBSyxLQUFLO0FBQ2YsV0FBSyxLQUFLLEtBQUs7QUFBQSxJQUNqQjtBQUFBLEVBQ0Y7QUFBQSxFQUVBLE9BQWMsS0FDZCxRQUNBLGNBQ0EsWUFDQSxHQUNBLFNBQVMsS0FDVDtBQUNFLFFBQUksSUFBTSxhQUFhLGNBQWM7QUFDbkMsWUFBTSxJ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