@statsig/tedious
Version:
A fork of tedious that supports Fabric OBO auth user impersonation
228 lines (227 loc) • 28.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _sprintfJs = require("sprintf-js");
var _writableTrackingBuffer = _interopRequireDefault(require("./tracking-buffer/writable-tracking-buffer"));
var _crypto = require("crypto");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const optionBufferSize = 20;
const traceIdSize = 36;
const TOKEN = {
VERSION: 0x00,
ENCRYPTION: 0x01,
INSTOPT: 0x02,
THREADID: 0x03,
MARS: 0x04,
TRACEID: 0x05,
FEDAUTHREQUIRED: 0x06,
TERMINATOR: 0xFF
};
const ENCRYPT = {
OFF: 0x00,
ON: 0x01,
NOT_SUP: 0x02,
REQ: 0x03
};
const encryptByValue = {};
for (const name in ENCRYPT) {
const value = ENCRYPT[name];
encryptByValue[value] = name;
}
const MARS = {
OFF: 0x00,
ON: 0x01
};
const marsByValue = {};
for (const name in MARS) {
const value = MARS[name];
marsByValue[value] = name;
}
/*
s2.2.6.4
*/
class PreloginPayload {
constructor(bufferOrOptions = {
encrypt: false,
version: {
major: 0,
minor: 0,
build: 0,
subbuild: 0
}
}) {
if (bufferOrOptions instanceof Buffer) {
this.data = bufferOrOptions;
this.options = {
encrypt: false,
version: {
major: 0,
minor: 0,
build: 0,
subbuild: 0
}
};
} else {
this.options = bufferOrOptions;
this.createOptions();
}
this.extractOptions();
}
createOptions() {
const options = [this.createVersionOption(), this.createEncryptionOption(), this.createInstanceOption(), this.createThreadIdOption(), this.createMarsOption(), this.createTraceIdOption(), this.createFedAuthOption()];
let length = 0;
for (let i = 0, len = options.length; i < len; i++) {
const option = options[i];
length += 5 + option.data.length;
}
length++; // terminator
this.data = Buffer.alloc(length, 0);
let optionOffset = 0;
let optionDataOffset = 5 * options.length + 1;
for (let j = 0, len = options.length; j < len; j++) {
const option = options[j];
this.data.writeUInt8(option.token, optionOffset + 0);
this.data.writeUInt16BE(optionDataOffset, optionOffset + 1);
this.data.writeUInt16BE(option.data.length, optionOffset + 3);
optionOffset += 5;
option.data.copy(this.data, optionDataOffset);
optionDataOffset += option.data.length;
}
this.data.writeUInt8(TOKEN.TERMINATOR, optionOffset);
}
createVersionOption() {
const buffer = new _writableTrackingBuffer.default(optionBufferSize);
buffer.writeUInt8(this.options.version.major);
buffer.writeUInt8(this.options.version.minor);
buffer.writeUInt16BE(this.options.version.build);
buffer.writeUInt16BE(this.options.version.subbuild);
return {
token: TOKEN.VERSION,
data: buffer.data
};
}
createEncryptionOption() {
const buffer = new _writableTrackingBuffer.default(optionBufferSize);
if (this.options.encrypt) {
buffer.writeUInt8(ENCRYPT.ON);
} else {
buffer.writeUInt8(ENCRYPT.NOT_SUP);
}
return {
token: TOKEN.ENCRYPTION,
data: buffer.data
};
}
createInstanceOption() {
const buffer = new _writableTrackingBuffer.default(optionBufferSize);
buffer.writeUInt8(0x00);
return {
token: TOKEN.INSTOPT,
data: buffer.data
};
}
createThreadIdOption() {
const buffer = new _writableTrackingBuffer.default(optionBufferSize);
buffer.writeUInt32BE(0x00);
return {
token: TOKEN.THREADID,
data: buffer.data
};
}
createMarsOption() {
const buffer = new _writableTrackingBuffer.default(optionBufferSize);
buffer.writeUInt8(MARS.OFF);
return {
token: TOKEN.MARS,
data: buffer.data
};
}
createTraceIdOption() {
const buffer = new _writableTrackingBuffer.default(traceIdSize);
// generate a random series of bytes to use as the TraceID
// used for debugging purposes
buffer.writeBuffer((0, _crypto.randomBytes)(traceIdSize));
return {
token: TOKEN.TRACEID,
data: buffer.data
};
}
createFedAuthOption() {
const buffer = new _writableTrackingBuffer.default(optionBufferSize);
buffer.writeUInt8(0x01);
return {
token: TOKEN.FEDAUTHREQUIRED,
data: buffer.data
};
}
extractOptions() {
let offset = 0;
while (this.data[offset] !== TOKEN.TERMINATOR) {
let dataOffset = this.data.readUInt16BE(offset + 1);
const dataLength = this.data.readUInt16BE(offset + 3);
switch (this.data[offset]) {
case TOKEN.VERSION:
this.extractVersion(dataOffset);
break;
case TOKEN.ENCRYPTION:
this.extractEncryption(dataOffset);
break;
case TOKEN.INSTOPT:
this.extractInstance(dataOffset);
break;
case TOKEN.THREADID:
if (dataLength > 0) {
this.extractThreadId(dataOffset);
}
break;
case TOKEN.MARS:
this.extractMars(dataOffset);
break;
case TOKEN.TRACEID:
this.extractTraceId(dataOffset);
break;
case TOKEN.FEDAUTHREQUIRED:
this.extractFedAuth(dataOffset);
break;
}
offset += 5;
dataOffset += dataLength;
}
}
extractVersion(offset) {
this.version = {
major: this.data.readUInt8(offset + 0),
minor: this.data.readUInt8(offset + 1),
build: this.data.readUInt16BE(offset + 2),
subbuild: this.data.readUInt16BE(offset + 4)
};
}
extractEncryption(offset) {
this.encryption = this.data.readUInt8(offset);
this.encryptionString = encryptByValue[this.encryption];
}
extractInstance(offset) {
this.instance = this.data.readUInt8(offset);
}
extractThreadId(offset) {
this.threadId = this.data.readUInt32BE(offset);
}
extractMars(offset) {
this.mars = this.data.readUInt8(offset);
this.marsString = marsByValue[this.mars];
}
extractTraceId(offset) {
this.traceId = this.data.subarray(offset, traceIdSize);
}
extractFedAuth(offset) {
this.fedAuthRequired = this.data.readUInt8(offset);
}
toString(indent = '') {
return indent + 'PreLogin - ' + (0, _sprintfJs.sprintf)('version:%d.%d.%d.%d, encryption:0x%02X(%s), instopt:0x%02X, threadId:0x%08X, mars:0x%02X(%s), traceId:%s', this.version.major, this.version.minor, this.version.build, this.version.subbuild, this.encryption ? this.encryption : 0, this.encryptionString ? this.encryptionString : '', this.instance ? this.instance : 0, this.threadId ? this.threadId : 0, this.mars ? this.mars : 0, this.marsString ? this.marsString : '', this.traceId ? this.traceId.toString('hex') : '');
}
}
var _default = exports.default = PreloginPayload;
module.exports = PreloginPayload;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfc3ByaW50ZkpzIiwicmVxdWlyZSIsIl93cml0YWJsZVRyYWNraW5nQnVmZmVyIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9jcnlwdG8iLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJvcHRpb25CdWZmZXJTaXplIiwidHJhY2VJZFNpemUiLCJUT0tFTiIsIlZFUlNJT04iLCJFTkNSWVBUSU9OIiwiSU5TVE9QVCIsIlRIUkVBRElEIiwiTUFSUyIsIlRSQUNFSUQiLCJGRURBVVRIUkVRVUlSRUQiLCJURVJNSU5BVE9SIiwiRU5DUllQVCIsIk9GRiIsIk9OIiwiTk9UX1NVUCIsIlJFUSIsImVuY3J5cHRCeVZhbHVlIiwibmFtZSIsInZhbHVlIiwibWFyc0J5VmFsdWUiLCJQcmVsb2dpblBheWxvYWQiLCJjb25zdHJ1Y3RvciIsImJ1ZmZlck9yT3B0aW9ucyIsImVuY3J5cHQiLCJ2ZXJzaW9uIiwibWFqb3IiLCJtaW5vciIsImJ1aWxkIiwic3ViYnVpbGQiLCJCdWZmZXIiLCJkYXRhIiwib3B0aW9ucyIsImNyZWF0ZU9wdGlvbnMiLCJleHRyYWN0T3B0aW9ucyIsImNyZWF0ZVZlcnNpb25PcHRpb24iLCJjcmVhdGVFbmNyeXB0aW9uT3B0aW9uIiwiY3JlYXRlSW5zdGFuY2VPcHRpb24iLCJjcmVhdGVUaHJlYWRJZE9wdGlvbiIsImNyZWF0ZU1hcnNPcHRpb24iLCJjcmVhdGVUcmFjZUlkT3B0aW9uIiwiY3JlYXRlRmVkQXV0aE9wdGlvbiIsImxlbmd0aCIsImkiLCJsZW4iLCJvcHRpb24iLCJhbGxvYyIsIm9wdGlvbk9mZnNldCIsIm9wdGlvbkRhdGFPZmZzZXQiLCJqIiwid3JpdGVVSW50OCIsInRva2VuIiwid3JpdGVVSW50MTZCRSIsImNvcHkiLCJidWZmZXIiLCJXcml0YWJsZVRyYWNraW5nQnVmZmVyIiwid3JpdGVVSW50MzJCRSIsIndyaXRlQnVmZmVyIiwicmFuZG9tQnl0ZXMiLCJvZmZzZXQiLCJkYXRhT2Zmc2V0IiwicmVhZFVJbnQxNkJFIiwiZGF0YUxlbmd0aCIsImV4dHJhY3RWZXJzaW9uIiwiZXh0cmFjdEVuY3J5cHRpb24iLCJleHRyYWN0SW5zdGFuY2UiLCJleHRyYWN0VGhyZWFkSWQiLCJleHRyYWN0TWFycyIsImV4dHJhY3RUcmFjZUlkIiwiZXh0cmFjdEZlZEF1dGgiLCJyZWFkVUludDgiLCJlbmNyeXB0aW9uIiwiZW5jcnlwdGlvblN0cmluZyIsImluc3RhbmNlIiwidGhyZWFkSWQiLCJyZWFkVUludDMyQkUiLCJtYXJzIiwibWFyc1N0cmluZyIsInRyYWNlSWQiLCJzdWJhcnJheSIsImZlZEF1dGhSZXF1aXJlZCIsInRvU3RyaW5nIiwiaW5kZW50Iiwic3ByaW50ZiIsIl9kZWZhdWx0IiwiZXhwb3J0cyIsIm1vZHVsZSJdLCJzb3VyY2VzIjpbIi4uL3NyYy9wcmVsb2dpbi1wYXlsb2FkLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNwcmludGYgfSBmcm9tICdzcHJpbnRmLWpzJztcblxuaW1wb3J0IFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIgZnJvbSAnLi90cmFja2luZy1idWZmZXIvd3JpdGFibGUtdHJhY2tpbmctYnVmZmVyJztcbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcblxuY29uc3Qgb3B0aW9uQnVmZmVyU2l6ZSA9IDIwO1xuY29uc3QgdHJhY2VJZFNpemUgPSAzNjtcblxuY29uc3QgVE9LRU4gPSB7XG4gIFZFUlNJT046IDB4MDAsXG4gIEVOQ1JZUFRJT046IDB4MDEsXG4gIElOU1RPUFQ6IDB4MDIsXG4gIFRIUkVBRElEOiAweDAzLFxuICBNQVJTOiAweDA0LFxuICBUUkFDRUlEOiAweDA1LFxuICBGRURBVVRIUkVRVUlSRUQ6IDB4MDYsXG4gIFRFUk1JTkFUT1I6IDB4RkZcbn07XG5cbmNvbnN0IEVOQ1JZUFQ6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH0gPSB7XG4gIE9GRjogMHgwMCxcbiAgT046IDB4MDEsXG4gIE5PVF9TVVA6IDB4MDIsXG4gIFJFUTogMHgwM1xufTtcblxuY29uc3QgZW5jcnlwdEJ5VmFsdWU6IHsgW2tleTogbnVtYmVyXTogc3RyaW5nIH0gPSB7fTtcblxuZm9yIChjb25zdCBuYW1lIGluIEVOQ1JZUFQpIHtcbiAgY29uc3QgdmFsdWUgPSBFTkNSWVBUW25hbWVdO1xuICBlbmNyeXB0QnlWYWx1ZVt2YWx1ZV0gPSBuYW1lO1xufVxuXG5jb25zdCBNQVJTOiB7IFtrZXk6IHN0cmluZ106IG51bWJlciB9ID0ge1xuICBPRkY6IDB4MDAsXG4gIE9OOiAweDAxXG59O1xuXG5jb25zdCBtYXJzQnlWYWx1ZTogeyBba2V5OiBudW1iZXJdOiBzdHJpbmcgfSA9IHt9O1xuXG5mb3IgKGNvbnN0IG5hbWUgaW4gTUFSUykge1xuICBjb25zdCB2YWx1ZSA9IE1BUlNbbmFtZV07XG4gIG1hcnNCeVZhbHVlW3ZhbHVlXSA9IG5hbWU7XG59XG5cbmludGVyZmFjZSBPcHRpb25zIHtcbiAgZW5jcnlwdDogYm9vbGVhbjtcbiAgdmVyc2lvbjoge1xuICAgIG1ham9yOiBudW1iZXI7XG4gICAgbWlub3I6IG51bWJlcjtcbiAgICBidWlsZDogbnVtYmVyO1xuICAgIHN1YmJ1aWxkOiBudW1iZXI7XG4gIH07XG59XG5cbi8qXG4gIHMyLjIuNi40XG4gKi9cbmNsYXNzIFByZWxvZ2luUGF5bG9hZCB7XG4gIGRlY2xhcmUgZGF0YTogQnVmZmVyO1xuICBkZWNsYXJlIG9wdGlvbnM6IE9wdGlvbnM7XG5cbiAgZGVjbGFyZSB2ZXJzaW9uOiB7XG4gICAgbWFqb3I6IG51bWJlcjtcbiAgICBtaW5vcjogbnVtYmVyO1xuICAgIGJ1aWxkOiBudW1iZXI7XG4gICAgc3ViYnVpbGQ6IG51bWJlcjtcbiAgfTtcblxuICBkZWNsYXJlIGVuY3J5cHRpb246IG51bWJlcjtcbiAgZGVjbGFyZSBlbmNyeXB0aW9uU3RyaW5nOiBzdHJpbmc7XG5cbiAgZGVjbGFyZSBpbnN0YW5jZTogbnVtYmVyO1xuXG4gIGRlY2xhcmUgdGhyZWFkSWQ6IG51bWJlcjtcblxuICBkZWNsYXJlIG1hcnM6IG51bWJlcjtcbiAgZGVjbGFyZSBtYXJzU3RyaW5nOiBzdHJpbmc7XG5cbiAgZGVjbGFyZSB0cmFjZUlkOiBCdWZmZXI7XG5cbiAgZGVjbGFyZSBmZWRBdXRoUmVxdWlyZWQ6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihidWZmZXJPck9wdGlvbnM6IEJ1ZmZlciB8IE9wdGlvbnMgPSB7IGVuY3J5cHQ6IGZhbHNlLCB2ZXJzaW9uOiB7IG1ham9yOiAwLCBtaW5vcjogMCwgYnVpbGQ6IDAsIHN1YmJ1aWxkOiAwIH0gfSkge1xuICAgIGlmIChidWZmZXJPck9wdGlvbnMgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIHRoaXMuZGF0YSA9IGJ1ZmZlck9yT3B0aW9ucztcbiAgICAgIHRoaXMub3B0aW9ucyA9IHsgZW5jcnlwdDogZmFsc2UsIHZlcnNpb246IHsgbWFqb3I6IDAsIG1pbm9yOiAwLCBidWlsZDogMCwgc3ViYnVpbGQ6IDAgfSB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9wdGlvbnMgPSBidWZmZXJPck9wdGlvbnM7XG4gICAgICB0aGlzLmNyZWF0ZU9wdGlvbnMoKTtcbiAgICB9XG4gICAgdGhpcy5leHRyYWN0T3B0aW9ucygpO1xuICB9XG5cbiAgY3JlYXRlT3B0aW9ucygpIHtcbiAgICBjb25zdCBvcHRpb25zID0gW1xuICAgICAgdGhpcy5jcmVhdGVWZXJzaW9uT3B0aW9uKCksXG4gICAgICB0aGlzLmNyZWF0ZUVuY3J5cHRpb25PcHRpb24oKSxcbiAgICAgIHRoaXMuY3JlYXRlSW5zdGFuY2VPcHRpb24oKSxcbiAgICAgIHRoaXMuY3JlYXRlVGhyZWFkSWRPcHRpb24oKSxcbiAgICAgIHRoaXMuY3JlYXRlTWFyc09wdGlvbigpLFxuICAgICAgdGhpcy5jcmVhdGVUcmFjZUlkT3B0aW9uKCksXG4gICAgICB0aGlzLmNyZWF0ZUZlZEF1dGhPcHRpb24oKVxuICAgIF07XG5cbiAgICBsZXQgbGVuZ3RoID0gMDtcbiAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gb3B0aW9ucy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgY29uc3Qgb3B0aW9uID0gb3B0aW9uc1tpXTtcbiAgICAgIGxlbmd0aCArPSA1ICsgb3B0aW9uLmRhdGEubGVuZ3RoO1xuICAgIH1cbiAgICBsZW5ndGgrKzsgLy8gdGVybWluYXRvclxuICAgIHRoaXMuZGF0YSA9IEJ1ZmZlci5hbGxvYyhsZW5ndGgsIDApO1xuICAgIGxldCBvcHRpb25PZmZzZXQgPSAwO1xuICAgIGxldCBvcHRpb25EYXRhT2Zmc2V0ID0gNSAqIG9wdGlvbnMubGVuZ3RoICsgMTtcblxuICAgIGZvciAobGV0IGogPSAwLCBsZW4gPSBvcHRpb25zLmxlbmd0aDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICBjb25zdCBvcHRpb24gPSBvcHRpb25zW2pdO1xuICAgICAgdGhpcy5kYXRhLndyaXRlVUludDgob3B0aW9uLnRva2VuLCBvcHRpb25PZmZzZXQgKyAwKTtcbiAgICAgIHRoaXMuZGF0YS53cml0ZVVJbnQxNkJFKG9wdGlvbkRhdGFPZmZzZXQsIG9wdGlvbk9mZnNldCArIDEpO1xuICAgICAgdGhpcy5kYXRhLndyaXRlVUludDE2QkUob3B0aW9uLmRhdGEubGVuZ3RoLCBvcHRpb25PZmZzZXQgKyAzKTtcbiAgICAgIG9wdGlvbk9mZnNldCArPSA1O1xuICAgICAgb3B0aW9uLmRhdGEuY29weSh0aGlzLmRhdGEsIG9wdGlvbkRhdGFPZmZzZXQpO1xuICAgICAgb3B0aW9uRGF0YU9mZnNldCArPSBvcHRpb24uZGF0YS5sZW5ndGg7XG4gICAgfVxuXG4gICAgdGhpcy5kYXRhLndyaXRlVUludDgoVE9LRU4uVEVSTUlOQVRPUiwgb3B0aW9uT2Zmc2V0KTtcbiAgfVxuXG4gIGNyZWF0ZVZlcnNpb25PcHRpb24oKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIob3B0aW9uQnVmZmVyU2l6ZSk7XG4gICAgYnVmZmVyLndyaXRlVUludDgodGhpcy5vcHRpb25zLnZlcnNpb24ubWFqb3IpO1xuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KHRoaXMub3B0aW9ucy52ZXJzaW9uLm1pbm9yKTtcbiAgICBidWZmZXIud3JpdGVVSW50MTZCRSh0aGlzLm9wdGlvbnMudmVyc2lvbi5idWlsZCk7XG4gICAgYnVmZmVyLndyaXRlVUludDE2QkUodGhpcy5vcHRpb25zLnZlcnNpb24uc3ViYnVpbGQpO1xuICAgIHJldHVybiB7XG4gICAgICB0b2tlbjogVE9LRU4uVkVSU0lPTixcbiAgICAgIGRhdGE6IGJ1ZmZlci5kYXRhXG4gICAgfTtcbiAgfVxuXG4gIGNyZWF0ZUVuY3J5cHRpb25PcHRpb24oKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIob3B0aW9uQnVmZmVyU2l6ZSk7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5lbmNyeXB0KSB7XG4gICAgICBidWZmZXIud3JpdGVVSW50OChFTkNSWVBULk9OKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmZmVyLndyaXRlVUludDgoRU5DUllQVC5OT1RfU1VQKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHRva2VuOiBUT0tFTi5FTkNSWVBUSU9OLFxuICAgICAgZGF0YTogYnVmZmVyLmRhdGFcbiAgICB9O1xuICB9XG5cbiAgY3JlYXRlSW5zdGFuY2VPcHRpb24oKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIob3B0aW9uQnVmZmVyU2l6ZSk7XG4gICAgYnVmZmVyLndyaXRlVUludDgoMHgwMCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRva2VuOiBUT0tFTi5JTlNUT1BULFxuICAgICAgZGF0YTogYnVmZmVyLmRhdGFcbiAgICB9O1xuICB9XG5cbiAgY3JlYXRlVGhyZWFkSWRPcHRpb24oKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIob3B0aW9uQnVmZmVyU2l6ZSk7XG4gICAgYnVmZmVyLndyaXRlVUludDMyQkUoMHgwMCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRva2VuOiBUT0tFTi5USFJFQURJRCxcbiAgICAgIGRhdGE6IGJ1ZmZlci5kYXRhXG4gICAgfTtcbiAgfVxuXG4gIGNyZWF0ZU1hcnNPcHRpb24oKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIob3B0aW9uQnVmZmVyU2l6ZSk7XG4gICAgYnVmZmVyLndyaXRlVUludDgoTUFSUy5PRkYpO1xuICAgIHJldHVybiB7XG4gICAgICB0b2tlbjogVE9LRU4uTUFSUyxcbiAgICAgIGRhdGE6IGJ1ZmZlci5kYXRhXG4gICAgfTtcbiAgfVxuXG4gIGNyZWF0ZVRyYWNlSWRPcHRpb24oKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIodHJhY2VJZFNpemUpO1xuICAgIC8vIGdlbmVyYXRlIGEgcmFuZG9tIHNlcmllcyBvZiBieXRlcyB0byB1c2UgYXMgdGhlIFRyYWNlSURcbiAgICAvLyB1c2VkIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXNcbiAgICBidWZmZXIud3JpdGVCdWZmZXIocmFuZG9tQnl0ZXModHJhY2VJZFNpemUpKTtcbiAgICByZXR1cm4ge1xuICAgICAgdG9rZW46IFRPS0VOLlRSQUNFSUQsXG4gICAgICBkYXRhOiBidWZmZXIuZGF0YVxuICAgIH07XG4gIH1cblxuICBjcmVhdGVGZWRBdXRoT3B0aW9uKCkge1xuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBXcml0YWJsZVRyYWNraW5nQnVmZmVyKG9wdGlvbkJ1ZmZlclNpemUpO1xuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KDB4MDEpO1xuICAgIHJldHVybiB7XG4gICAgICB0b2tlbjogVE9LRU4uRkVEQVVUSFJFUVVJUkVELFxuICAgICAgZGF0YTogYnVmZmVyLmRhdGFcbiAgICB9O1xuICB9XG5cbiAgZXh0cmFjdE9wdGlvbnMoKSB7XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgd2hpbGUgKHRoaXMuZGF0YVtvZmZzZXRdICE9PSBUT0tFTi5URVJNSU5BVE9SKSB7XG4gICAgICBsZXQgZGF0YU9mZnNldCA9IHRoaXMuZGF0YS5yZWFkVUludDE2QkUob2Zmc2V0ICsgMSk7XG4gICAgICBjb25zdCBkYXRhTGVuZ3RoID0gdGhpcy5kYXRhLnJlYWRVSW50MTZCRShvZmZzZXQgKyAzKTtcbiAgICAgIHN3aXRjaCAodGhpcy5kYXRhW29mZnNldF0pIHtcbiAgICAgICAgY2FzZSBUT0tFTi5WRVJTSU9OOlxuICAgICAgICAgIHRoaXMuZXh0cmFjdFZlcnNpb24oZGF0YU9mZnNldCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgVE9LRU4uRU5DUllQVElPTjpcbiAgICAgICAgICB0aGlzLmV4dHJhY3RFbmNyeXB0aW9uKGRhdGFPZmZzZXQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFRPS0VOLklOU1RPUFQ6XG4gICAgICAgICAgdGhpcy5leHRyYWN0SW5zdGFuY2UoZGF0YU9mZnNldCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgVE9LRU4uVEhSRUFESUQ6XG4gICAgICAgICAgaWYgKGRhdGFMZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmV4dHJhY3RUaHJlYWRJZChkYXRhT2Zmc2V0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgVE9LRU4uTUFSUzpcbiAgICAgICAgICB0aGlzLmV4dHJhY3RNYXJzKGRhdGFPZmZzZXQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFRPS0VOLlRSQUNFSUQ6XG4gICAgICAgICAgdGhpcy5leHRyYWN0VHJhY2VJZChkYXRhT2Zmc2V0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBUT0tFTi5GRURBVVRIUkVRVUlSRUQ6XG4gICAgICAgICAgdGhpcy5leHRyYWN0RmVkQXV0aChkYXRhT2Zmc2V0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIG9mZnNldCArPSA1O1xuICAgICAgZGF0YU9mZnNldCArPSBkYXRhTGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIGV4dHJhY3RWZXJzaW9uKG9mZnNldDogbnVtYmVyKSB7XG4gICAgdGhpcy52ZXJzaW9uID0ge1xuICAgICAgbWFqb3I6IHRoaXMuZGF0YS5yZWFkVUludDgob2Zmc2V0ICsgMCksXG4gICAgICBtaW5vcjogdGhpcy5kYXRhLnJlYWRVSW50OChvZmZzZXQgKyAxKSxcbiAgICAgIGJ1aWxkOiB0aGlzLmRhdGEucmVhZFVJbnQxNkJFKG9mZnNldCArIDIpLFxuICAgICAgc3ViYnVpbGQ6IHRoaXMuZGF0YS5yZWFkVUludDE2QkUob2Zmc2V0ICsgNClcbiAgICB9O1xuICB9XG5cbiAgZXh0cmFjdEVuY3J5cHRpb24ob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLmVuY3J5cHRpb24gPSB0aGlzLmRhdGEucmVhZFVJbnQ4KG9mZnNldCk7XG4gICAgdGhpcy5lbmNyeXB0aW9uU3RyaW5nID0gZW5jcnlwdEJ5VmFsdWVbdGhpcy5lbmNyeXB0aW9uXTtcbiAgfVxuXG4gIGV4dHJhY3RJbnN0YW5jZShvZmZzZXQ6IG51bWJlcikge1xuICAgIHRoaXMuaW5zdGFuY2UgPSB0aGlzLmRhdGEucmVhZFVJbnQ4KG9mZnNldCk7XG4gIH1cblxuICBleHRyYWN0VGhyZWFkSWQob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLnRocmVhZElkID0gdGhpcy5kYXRhLnJlYWRVSW50MzJCRShvZmZzZXQpO1xuICB9XG5cbiAgZXh0cmFjdE1hcnMob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLm1hcnMgPSB0aGlzLmRhdGEucmVhZFVJbnQ4KG9mZnNldCk7XG4gICAgdGhpcy5tYXJzU3RyaW5nID0gbWFyc0J5VmFsdWVbdGhpcy5tYXJzXTtcbiAgfVxuXG4gIGV4dHJhY3RUcmFjZUlkKG9mZnNldDogbnVtYmVyKSB7XG4gICAgdGhpcy50cmFjZUlkID0gdGhpcy5kYXRhLnN1YmFycmF5KG9mZnNldCwgdHJhY2VJZFNpemUpO1xuICB9XG5cbiAgZXh0cmFjdEZlZEF1dGgob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLmZlZEF1dGhSZXF1aXJlZCA9IHRoaXMuZGF0YS5yZWFkVUludDgob2Zmc2V0KTtcbiAgfVxuXG4gIHRvU3RyaW5nKGluZGVudCA9ICcnKSB7XG4gICAgcmV0dXJuIGluZGVudCArICdQcmVMb2dpbiAtICcgKyBzcHJpbnRmKFxuICAgICAgJ3ZlcnNpb246JWQuJWQuJWQuJWQsIGVuY3J5cHRpb246MHglMDJYKCVzKSwgaW5zdG9wdDoweCUwMlgsIHRocmVhZElkOjB4JTA4WCwgbWFyczoweCUwMlgoJXMpLCB0cmFjZUlkOiVzJyxcbiAgICAgIHRoaXMudmVyc2lvbi5tYWpvciwgdGhpcy52ZXJzaW9uLm1pbm9yLCB0aGlzLnZlcnNpb24uYnVpbGQsIHRoaXMudmVyc2lvbi5zdWJidWlsZCxcbiAgICAgIHRoaXMuZW5jcnlwdGlvbiA/IHRoaXMuZW5jcnlwdGlvbiA6IDAsXG4gICAgICB0aGlzLmVuY3J5cHRpb25TdHJpbmcgPyB0aGlzLmVuY3J5cHRpb25TdHJpbmcgOiAnJyxcbiAgICAgIHRoaXMuaW5zdGFuY2UgPyB0aGlzLmluc3RhbmNlIDogMCxcbiAgICAgIHRoaXMudGhyZWFkSWQgPyB0aGlzLnRocmVhZElkIDogMCxcbiAgICAgIHRoaXMubWFycyA/IHRoaXMubWFycyA6IDAsXG4gICAgICB0aGlzLm1hcnNTdHJpbmcgPyB0aGlzLm1hcnNTdHJpbmcgOiAnJyxcbiAgICAgIHRoaXMudHJhY2VJZCA/IHRoaXMudHJhY2VJZC50b1N0cmluZygnaGV4JykgOiAnJyxcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFByZWxvZ2luUGF5bG9hZDtcbm1vZHVsZS5leHBvcnRzID0gUHJlbG9naW5QYXlsb2FkO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFBQSxVQUFBLEdBQUFDLE9BQUE7QUFFQSxJQUFBQyx1QkFBQSxHQUFBQyxzQkFBQSxDQUFBRixPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFB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