UNPKG

tedious

Version:

A TDS driver, for connecting to MS SQLServer databases.

245 lines (244 loc) • 31 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _errors = require("./errors"); var _formatHex = require("./format-hex"); var _writableTrackingBuffer = _interopRequireDefault(require("./tracking-buffer/writable-tracking-buffer")); var _crypto = require("crypto"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } 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.5 */ 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(); 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(); 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(); buffer.writeUInt8(0x00); return { token: TOKEN.INSTOPT, data: buffer.data }; } createThreadIdOption() { const buffer = new _writableTrackingBuffer.default(); buffer.writeUInt32BE(0x00); return { token: TOKEN.THREADID, data: buffer.data }; } createMarsOption() { const buffer = new _writableTrackingBuffer.default(); buffer.writeUInt8(MARS.OFF); return { token: TOKEN.MARS, data: buffer.data }; } createTraceIdOption() { const buffer = new _writableTrackingBuffer.default(); // 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(); buffer.writeUInt8(0x01); return { token: TOKEN.FEDAUTHREQUIRED, data: buffer.data }; } extractOptions() { let offset = 0; let encryptionOffset; 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: if (encryptionOffset !== undefined) { throw new _errors.ConnectionError('Duplicate ENCRYPTION option in PRELOGIN response', 'EENCRYPT'); } if (dataLength !== 1 || dataOffset >= this.data.length) { throw new _errors.ConnectionError('Malformed ENCRYPTION option in PRELOGIN response', 'EENCRYPT'); } encryptionOffset = dataOffset; 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; } if (encryptionOffset !== undefined && encryptionOffset <= offset) { throw new _errors.ConnectionError('Malformed ENCRYPTION option in PRELOGIN response', 'EENCRYPT'); } } 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, offset + traceIdSize); } extractFedAuth(offset) { this.fedAuthRequired = this.data.readUInt8(offset); } toString(indent = '') { const { major, minor, build, subbuild } = this.version; return indent + 'PreLogin - ' + `version:${major}.${minor}.${build}.${subbuild}, ` + `encryption:0x${(0, _formatHex.formatHex)(this.encryption ? this.encryption : 0, 2)}(${this.encryptionString ? this.encryptionString : ''}), ` + `instopt:0x${(0, _formatHex.formatHex)(this.instance ? this.instance : 0, 2)}, ` + `threadId:0x${(0, _formatHex.formatHex)(this.threadId ? this.threadId : 0, 8)}, ` + `mars:0x${(0, _formatHex.formatHex)(this.mars ? this.mars : 0, 2)}(${this.marsString ? this.marsString : ''}), ` + `traceId:${this.traceId ? this.traceId.toString('hex') : ''}`; } } var _default = exports.default = PreloginPayload; module.exports = PreloginPayload; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZXJyb3JzIiwicmVxdWlyZSIsIl9mb3JtYXRIZXgiLCJfd3JpdGFibGVUcmFja2luZ0J1ZmZlciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfY3J5cHRvIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwidHJhY2VJZFNpemUiLCJUT0tFTiIsIlZFUlNJT04iLCJFTkNSWVBUSU9OIiwiSU5TVE9QVCIsIlRIUkVBRElEIiwiTUFSUyIsIlRSQUNFSUQiLCJGRURBVVRIUkVRVUlSRUQiLCJURVJNSU5BVE9SIiwiRU5DUllQVCIsIk9GRiIsIk9OIiwiTk9UX1NVUCIsIlJFUSIsImVuY3J5cHRCeVZhbHVlIiwibmFtZSIsInZhbHVlIiwibWFyc0J5VmFsdWUiLCJQcmVsb2dpblBheWxvYWQiLCJjb25zdHJ1Y3RvciIsImJ1ZmZlck9yT3B0aW9ucyIsImVuY3J5cHQiLCJ2ZXJzaW9uIiwibWFqb3IiLCJtaW5vciIsImJ1aWxkIiwic3ViYnVpbGQiLCJCdWZmZXIiLCJkYXRhIiwib3B0aW9ucyIsImNyZWF0ZU9wdGlvbnMiLCJleHRyYWN0T3B0aW9ucyIsImNyZWF0ZVZlcnNpb25PcHRpb24iLCJjcmVhdGVFbmNyeXB0aW9uT3B0aW9uIiwiY3JlYXRlSW5zdGFuY2VPcHRpb24iLCJjcmVhdGVUaHJlYWRJZE9wdGlvbiIsImNyZWF0ZU1hcnNPcHRpb24iLCJjcmVhdGVUcmFjZUlkT3B0aW9uIiwiY3JlYXRlRmVkQXV0aE9wdGlvbiIsImxlbmd0aCIsImkiLCJsZW4iLCJvcHRpb24iLCJhbGxvYyIsIm9wdGlvbk9mZnNldCIsIm9wdGlvbkRhdGFPZmZzZXQiLCJqIiwid3JpdGVVSW50OCIsInRva2VuIiwid3JpdGVVSW50MTZCRSIsImNvcHkiLCJidWZmZXIiLCJXcml0YWJsZVRyYWNraW5nQnVmZmVyIiwid3JpdGVVSW50MzJCRSIsIndyaXRlQnVmZmVyIiwicmFuZG9tQnl0ZXMiLCJvZmZzZXQiLCJlbmNyeXB0aW9uT2Zmc2V0IiwiZGF0YU9mZnNldCIsInJlYWRVSW50MTZCRSIsImRhdGFMZW5ndGgiLCJleHRyYWN0VmVyc2lvbiIsInVuZGVmaW5lZCIsIkNvbm5lY3Rpb25FcnJvciIsImV4dHJhY3RFbmNyeXB0aW9uIiwiZXh0cmFjdEluc3RhbmNlIiwiZXh0cmFjdFRocmVhZElkIiwiZXh0cmFjdE1hcnMiLCJleHRyYWN0VHJhY2VJZCIsImV4dHJhY3RGZWRBdXRoIiwicmVhZFVJbnQ4IiwiZW5jcnlwdGlvbiIsImVuY3J5cHRpb25TdHJpbmciLCJpbnN0YW5jZSIsInRocmVhZElkIiwicmVhZFVJbnQzMkJFIiwibWFycyIsIm1hcnNTdHJpbmciLCJ0cmFjZUlkIiwic3ViYXJyYXkiLCJmZWRBdXRoUmVxdWlyZWQiLCJ0b1N0cmluZyIsImluZGVudCIsImZvcm1hdEhleCIsIl9kZWZhdWx0IiwiZXhwb3J0cyIsIm1vZHVsZSJdLCJzb3VyY2VzIjpbIi4uL3NyYy9wcmVsb2dpbi1wYXlsb2FkLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbm5lY3Rpb25FcnJvciB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IGZvcm1hdEhleCB9IGZyb20gJy4vZm9ybWF0LWhleCc7XG5cbmltcG9ydCBXcml0YWJsZVRyYWNraW5nQnVmZmVyIGZyb20gJy4vdHJhY2tpbmctYnVmZmVyL3dyaXRhYmxlLXRyYWNraW5nLWJ1ZmZlcic7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5cbmNvbnN0IHRyYWNlSWRTaXplID0gMzY7XG5cbmNvbnN0IFRPS0VOID0ge1xuICBWRVJTSU9OOiAweDAwLFxuICBFTkNSWVBUSU9OOiAweDAxLFxuICBJTlNUT1BUOiAweDAyLFxuICBUSFJFQURJRDogMHgwMyxcbiAgTUFSUzogMHgwNCxcbiAgVFJBQ0VJRDogMHgwNSxcbiAgRkVEQVVUSFJFUVVJUkVEOiAweDA2LFxuICBURVJNSU5BVE9SOiAweEZGXG59O1xuXG5jb25zdCBFTkNSWVBUOiB7IFtrZXk6IHN0cmluZ106IG51bWJlciB9ID0ge1xuICBPRkY6IDB4MDAsXG4gIE9OOiAweDAxLFxuICBOT1RfU1VQOiAweDAyLFxuICBSRVE6IDB4MDNcbn07XG5cbmNvbnN0IGVuY3J5cHRCeVZhbHVlOiB7IFtrZXk6IG51bWJlcl06IHN0cmluZyB9ID0ge307XG5cbmZvciAoY29uc3QgbmFtZSBpbiBFTkNSWVBUKSB7XG4gIGNvbnN0IHZhbHVlID0gRU5DUllQVFtuYW1lXTtcbiAgZW5jcnlwdEJ5VmFsdWVbdmFsdWVdID0gbmFtZTtcbn1cblxuY29uc3QgTUFSUzogeyBba2V5OiBzdHJpbmddOiBudW1iZXIgfSA9IHtcbiAgT0ZGOiAweDAwLFxuICBPTjogMHgwMVxufTtcblxuY29uc3QgbWFyc0J5VmFsdWU6IHsgW2tleTogbnVtYmVyXTogc3RyaW5nIH0gPSB7fTtcblxuZm9yIChjb25zdCBuYW1lIGluIE1BUlMpIHtcbiAgY29uc3QgdmFsdWUgPSBNQVJTW25hbWVdO1xuICBtYXJzQnlWYWx1ZVt2YWx1ZV0gPSBuYW1lO1xufVxuXG5pbnRlcmZhY2UgT3B0aW9ucyB7XG4gIGVuY3J5cHQ6IGJvb2xlYW47XG4gIHZlcnNpb246IHtcbiAgICBtYWpvcjogbnVtYmVyO1xuICAgIG1pbm9yOiBudW1iZXI7XG4gICAgYnVpbGQ6IG51bWJlcjtcbiAgICBzdWJidWlsZDogbnVtYmVyO1xuICB9O1xufVxuXG4vKlxuICBzMi4yLjYuNVxuICovXG5jbGFzcyBQcmVsb2dpblBheWxvYWQge1xuICBkZWNsYXJlIGRhdGE6IEJ1ZmZlcjtcbiAgZGVjbGFyZSBvcHRpb25zOiBPcHRpb25zO1xuXG4gIGRlY2xhcmUgdmVyc2lvbjoge1xuICAgIG1ham9yOiBudW1iZXI7XG4gICAgbWlub3I6IG51bWJlcjtcbiAgICBidWlsZDogbnVtYmVyO1xuICAgIHN1YmJ1aWxkOiBudW1iZXI7XG4gIH07XG5cbiAgZGVjbGFyZSBlbmNyeXB0aW9uOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGRlY2xhcmUgZW5jcnlwdGlvblN0cmluZzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIGRlY2xhcmUgaW5zdGFuY2U6IG51bWJlcjtcblxuICBkZWNsYXJlIHRocmVhZElkOiBudW1iZXI7XG5cbiAgZGVjbGFyZSBtYXJzOiBudW1iZXI7XG4gIGRlY2xhcmUgbWFyc1N0cmluZzogc3RyaW5nO1xuICBkZWNsYXJlIHRyYWNlSWQ6IEJ1ZmZlcjtcbiAgZGVjbGFyZSBmZWRBdXRoUmVxdWlyZWQ6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihidWZmZXJPck9wdGlvbnM6IEJ1ZmZlciB8IE9wdGlvbnMgPSB7IGVuY3J5cHQ6IGZhbHNlLCB2ZXJzaW9uOiB7IG1ham9yOiAwLCBtaW5vcjogMCwgYnVpbGQ6IDAsIHN1YmJ1aWxkOiAwIH0gfSkge1xuICAgIGlmIChidWZmZXJPck9wdGlvbnMgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIHRoaXMuZGF0YSA9IGJ1ZmZlck9yT3B0aW9ucztcbiAgICAgIHRoaXMub3B0aW9ucyA9IHsgZW5jcnlwdDogZmFsc2UsIHZlcnNpb246IHsgbWFqb3I6IDAsIG1pbm9yOiAwLCBidWlsZDogMCwgc3ViYnVpbGQ6IDAgfSB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9wdGlvbnMgPSBidWZmZXJPck9wdGlvbnMgYXMgT3B0aW9ucztcbiAgICAgIHRoaXMuY3JlYXRlT3B0aW9ucygpO1xuICAgIH1cbiAgICB0aGlzLmV4dHJhY3RPcHRpb25zKCk7XG4gIH1cblxuICBjcmVhdGVPcHRpb25zKCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBbXG4gICAgICB0aGlzLmNyZWF0ZVZlcnNpb25PcHRpb24oKSxcbiAgICAgIHRoaXMuY3JlYXRlRW5jcnlwdGlvbk9wdGlvbigpLFxuICAgICAgdGhpcy5jcmVhdGVJbnN0YW5jZU9wdGlvbigpLFxuICAgICAgdGhpcy5jcmVhdGVUaHJlYWRJZE9wdGlvbigpLFxuICAgICAgdGhpcy5jcmVhdGVNYXJzT3B0aW9uKCksXG4gICAgICB0aGlzLmNyZWF0ZVRyYWNlSWRPcHRpb24oKSxcbiAgICAgIHRoaXMuY3JlYXRlRmVkQXV0aE9wdGlvbigpXG4gICAgXTtcblxuICAgIGxldCBsZW5ndGggPSAwO1xuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBvcHRpb25zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBjb25zdCBvcHRpb24gPSBvcHRpb25zW2ldO1xuICAgICAgbGVuZ3RoICs9IDUgKyBvcHRpb24uZGF0YS5sZW5ndGg7XG4gICAgfVxuICAgIGxlbmd0aCsrOyAvLyB0ZXJtaW5hdG9yXG4gICAgdGhpcy5kYXRhID0gQnVmZmVyLmFsbG9jKGxlbmd0aCwgMCk7XG4gICAgbGV0IG9wdGlvbk9mZnNldCA9IDA7XG4gICAgbGV0IG9wdGlvbkRhdGFPZmZzZXQgPSA1ICogb3B0aW9ucy5sZW5ndGggKyAxO1xuXG4gICAgZm9yIChsZXQgaiA9IDAsIGxlbiA9IG9wdGlvbnMubGVuZ3RoOyBqIDwgbGVuOyBqKyspIHtcbiAgICAgIGNvbnN0IG9wdGlvbiA9IG9wdGlvbnNbal07XG4gICAgICB0aGlzLmRhdGEud3JpdGVVSW50OChvcHRpb24udG9rZW4sIG9wdGlvbk9mZnNldCArIDApO1xuICAgICAgdGhpcy5kYXRhLndyaXRlVUludDE2QkUob3B0aW9uRGF0YU9mZnNldCwgb3B0aW9uT2Zmc2V0ICsgMSk7XG4gICAgICB0aGlzLmRhdGEud3JpdGVVSW50MTZCRShvcHRpb24uZGF0YS5sZW5ndGgsIG9wdGlvbk9mZnNldCArIDMpO1xuICAgICAgb3B0aW9uT2Zmc2V0ICs9IDU7XG4gICAgICBvcHRpb24uZGF0YS5jb3B5KHRoaXMuZGF0YSwgb3B0aW9uRGF0YU9mZnNldCk7XG4gICAgICBvcHRpb25EYXRhT2Zmc2V0ICs9IG9wdGlvbi5kYXRhLmxlbmd0aDtcbiAgICB9XG5cbiAgICB0aGlzLmRhdGEud3JpdGVVSW50OChUT0tFTi5URVJNSU5BVE9SLCBvcHRpb25PZmZzZXQpO1xuICB9XG5cbiAgY3JlYXRlVmVyc2lvbk9wdGlvbigpIHtcbiAgICBjb25zdCBidWZmZXIgPSBuZXcgV3JpdGFibGVUcmFja2luZ0J1ZmZlcigpO1xuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KHRoaXMub3B0aW9ucy52ZXJzaW9uLm1ham9yKTtcbiAgICBidWZmZXIud3JpdGVVSW50OCh0aGlzLm9wdGlvbnMudmVyc2lvbi5taW5vcik7XG4gICAgYnVmZmVyLndyaXRlVUludDE2QkUodGhpcy5vcHRpb25zLnZlcnNpb24uYnVpbGQpO1xuICAgIGJ1ZmZlci53cml0ZVVJbnQxNkJFKHRoaXMub3B0aW9ucy52ZXJzaW9uLnN1YmJ1aWxkKTtcbiAgICByZXR1cm4ge1xuICAgICAgdG9rZW46IFRPS0VOLlZFUlNJT04sXG4gICAgICBkYXRhOiBidWZmZXIuZGF0YVxuICAgIH07XG4gIH1cblxuICBjcmVhdGVFbmNyeXB0aW9uT3B0aW9uKCkge1xuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBXcml0YWJsZVRyYWNraW5nQnVmZmVyKCk7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5lbmNyeXB0KSB7XG4gICAgICBidWZmZXIud3JpdGVVSW50OChFTkNSWVBULk9OKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmZmVyLndyaXRlVUludDgoRU5DUllQVC5OT1RfU1VQKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHRva2VuOiBUT0tFTi5FTkNSWVBUSU9OLFxuICAgICAgZGF0YTogYnVmZmVyLmRhdGFcbiAgICB9O1xuICB9XG5cbiAgY3JlYXRlSW5zdGFuY2VPcHRpb24oKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIoKTtcbiAgICBidWZmZXIud3JpdGVVSW50OCgweDAwKTtcbiAgICByZXR1cm4ge1xuICAgICAgdG9rZW46IFRPS0VOLklOU1RPUFQsXG4gICAgICBkYXRhOiBidWZmZXIuZGF0YVxuICAgIH07XG4gIH1cblxuICBjcmVhdGVUaHJlYWRJZE9wdGlvbigpIHtcbiAgICBjb25zdCBidWZmZXIgPSBuZXcgV3JpdGFibGVUcmFja2luZ0J1ZmZlcigpO1xuICAgIGJ1ZmZlci53cml0ZVVJbnQzMkJFKDB4MDApO1xuICAgIHJldHVybiB7XG4gICAgICB0b2tlbjogVE9LRU4uVEhSRUFESUQsXG4gICAgICBkYXRhOiBidWZmZXIuZGF0YVxuICAgIH07XG4gIH1cblxuICBjcmVhdGVNYXJzT3B0aW9uKCkge1xuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBXcml0YWJsZVRyYWNraW5nQnVmZmVyKCk7XG4gICAgYnVmZmVyLndyaXRlVUludDgoTUFSUy5PRkYpO1xuICAgIHJldHVybiB7XG4gICAgICB0b2tlbjogVE9LRU4uTUFSUyxcbiAgICAgIGRhdGE6IGJ1ZmZlci5kYXRhXG4gICAgfTtcbiAgfVxuXG4gIGNyZWF0ZVRyYWNlSWRPcHRpb24oKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIoKTtcbiAgICAvLyBHZW5lcmF0ZSBhIHJhbmRvbSBzZXJpZXMgb2YgYnl0ZXMgdG8gdXNlIGFzIHRoZSBUcmFjZUlELlxuICAgIC8vIFVzZWQgZm9yIGRlYnVnZ2luZyBwdXJwb3Nlcy5cbiAgICBidWZmZXIud3JpdGVCdWZmZXIocmFuZG9tQnl0ZXModHJhY2VJZFNpemUpKTtcbiAgICByZXR1cm4ge1xuICAgICAgdG9rZW46IFRPS0VOLlRSQUNFSUQsXG4gICAgICBkYXRhOiBidWZmZXIuZGF0YVxuICAgIH07XG4gIH1cblxuICBjcmVhdGVGZWRBdXRoT3B0aW9uKCkge1xuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBXcml0YWJsZVRyYWNraW5nQnVmZmVyKCk7XG4gICAgYnVmZmVyLndyaXRlVUludDgoMHgwMSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRva2VuOiBUT0tFTi5GRURBVVRIUkVRVUlSRUQsXG4gICAgICBkYXRhOiBidWZmZXIuZGF0YVxuICAgIH07XG4gIH1cblxuICBleHRyYWN0T3B0aW9ucygpIHtcbiAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICBsZXQgZW5jcnlwdGlvbk9mZnNldDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIHdoaWxlICh0aGlzLmRhdGFbb2Zmc2V0XSAhPT0gVE9LRU4uVEVSTUlOQVRPUikge1xuICAgICAgbGV0IGRhdGFPZmZzZXQgPSB0aGlzLmRhdGEucmVhZFVJbnQxNkJFKG9mZnNldCArIDEpO1xuICAgICAgY29uc3QgZGF0YUxlbmd0aCA9IHRoaXMuZGF0YS5yZWFkVUludDE2QkUob2Zmc2V0ICsgMyk7XG4gICAgICBzd2l0Y2ggKHRoaXMuZGF0YVtvZmZzZXRdKSB7XG4gICAgICAgIGNhc2UgVE9LRU4uVkVSU0lPTjpcbiAgICAgICAgICB0aGlzLmV4dHJhY3RWZXJzaW9uKGRhdGFPZmZzZXQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFRPS0VOLkVOQ1JZUFRJT046XG4gICAgICAgICAgaWYgKGVuY3J5cHRpb25PZmZzZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IENvbm5lY3Rpb25FcnJvcignRHVwbGljYXRlIEVOQ1JZUFRJT04gb3B0aW9uIGluIFBSRUxPR0lOIHJlc3BvbnNlJywgJ0VFTkNSWVBUJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkYXRhTGVuZ3RoICE9PSAxIHx8IGRhdGFPZmZzZXQgPj0gdGhpcy5kYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IENvbm5lY3Rpb25FcnJvcignTWFsZm9ybWVkIEVOQ1JZUFRJT04gb3B0aW9uIGluIFBSRUxPR0lOIHJlc3BvbnNlJywgJ0VFTkNSWVBUJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVuY3J5cHRpb25PZmZzZXQgPSBkYXRhT2Zmc2V0O1xuICAgICAgICAgIHRoaXMuZXh0cmFjdEVuY3J5cHRpb24oZGF0YU9mZnNldCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgVE9LRU4uSU5TVE9QVDpcbiAgICAgICAgICB0aGlzLmV4dHJhY3RJbnN0YW5jZShkYXRhT2Zmc2V0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBUT0tFTi5USFJFQURJRDpcbiAgICAgICAgICBpZiAoZGF0YUxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuZXh0cmFjdFRocmVhZElkKGRhdGFPZmZzZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBUT0tFTi5NQVJTOlxuICAgICAgICAgIHRoaXMuZXh0cmFjdE1hcnMoZGF0YU9mZnNldCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgVE9LRU4uVFJBQ0VJRDpcbiAgICAgICAgICB0aGlzLmV4dHJhY3RUcmFjZUlkKGRhdGFPZmZzZXQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFRPS0VOLkZFREFVVEhSRVFVSVJFRDpcbiAgICAgICAgICB0aGlzLmV4dHJhY3RGZWRBdXRoKGRhdGFPZmZzZXQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgb2Zmc2V0ICs9IDU7XG4gICAgICBkYXRhT2Zmc2V0ICs9IGRhdGFMZW5ndGg7XG4gICAgfVxuICAgIGlmIChlbmNyeXB0aW9uT2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgZW5jcnlwdGlvbk9mZnNldCA8PSBvZmZzZXQpIHtcbiAgICAgIHRocm93IG5ldyBDb25uZWN0aW9uRXJyb3IoJ01hbGZvcm1lZCBFTkNSWVBUSU9OIG9wdGlvbiBpbiBQUkVMT0dJTiByZXNwb25zZScsICdFRU5DUllQVCcpO1xuICAgIH1cbiAgfVxuXG4gIGV4dHJhY3RWZXJzaW9uKG9mZnNldDogbnVtYmVyKSB7XG4gICAgdGhpcy52ZXJzaW9uID0ge1xuICAgICAgbWFqb3I6IHRoaXMuZGF0YS5yZWFkVUludDgob2Zmc2V0ICsgMCksXG4gICAgICBtaW5vcjogdGhpcy5kYXRhLnJlYWRVSW50OChvZmZzZXQgKyAxKSxcbiAgICAgIGJ1aWxkOiB0aGlzLmRhdGEucmVhZFVJbnQxNkJFKG9mZnNldCArIDIpLFxuICAgICAgc3ViYnVpbGQ6IHRoaXMuZGF0YS5yZWFkVUludDE2QkUob2Zmc2V0ICsgNClcbiAgICB9O1xuICB9XG5cbiAgZXh0cmFjdEVuY3J5cHRpb24ob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLmVuY3J5cHRpb24gPSB0aGlzLmRhdGEucmVhZFVJbnQ4KG9mZnNldCk7XG4gICAgdGhpcy5lbmNyeXB0aW9uU3RyaW5nID0gZW5jcnlwdEJ5VmFsdWVbdGhpcy5lbmNyeXB0aW9uXTtcbiAgfVxuXG4gIGV4dHJhY3RJbnN0YW5jZShvZmZzZXQ6IG51bWJlcikge1xuICAgIHRoaXMuaW5zdGFuY2UgPSB0aGlzLmRhdGEucmVhZFVJbnQ4KG9mZnNldCk7XG4gIH1cblxuICBleHRyYWN0VGhyZWFkSWQob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLnRocmVhZElkID0gdGhpcy5kYXRhLnJlYWRVSW50MzJCRShvZmZzZXQpO1xuICB9XG5cbiAgZXh0cmFjdE1hcnMob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLm1hcnMgPSB0aGlzLmRhdGEucmVhZFVJbnQ4KG9mZnNldCk7XG4gICAgdGhpcy5tYXJzU3RyaW5nID0gbWFyc0J5VmFsdWVbdGhpcy5tYXJzXTtcbiAgfVxuXG4gIGV4dHJhY3RUcmFjZUlkKG9mZnNldDogbnVtYmVyKSB7XG4gICAgdGhpcy50cmFjZUlkID0gdGhpcy5kYXRhLnN1YmFycmF5KG9mZnNldCwgb2Zmc2V0ICsgdHJhY2VJZFNpemUpO1xuICB9XG5cbiAgZXh0cmFjdEZlZEF1dGgob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLmZlZEF1dGhSZXF1aXJlZCA9IHRoaXMuZGF0YS5yZWFkVUludDgob2Zmc2V0KTtcbiAgfVxuXG4gIHRvU3RyaW5nKGluZGVudCA9ICcnKSB7XG4gICAgY29uc3QgeyBtYWpvciwgbWlub3IsIGJ1aWxkLCBzdWJidWlsZCB9ID0gdGhpcy52ZXJzaW9uO1xuICAgIHJldHVybiBpbmRlbnQgKyAnUHJlTG9naW4gLSAnICtcbiAgICAgIGB2ZXJzaW9uOiR7bWFqb3J9LiR7bWlub3J9LiR7YnVpbGR9LiR7c3ViYnVpbGR9LCBgICtcbiAgICAgIGBlbmNyeXB0aW9uOjB4JHtmb3JtYXRIZXgodGhpcy5lbmNyeXB0aW9uID8gdGhpcy5lbmNyeXB0aW9uIDogMCwgMil9KCR7dGhpcy5lbmNyeXB0aW9uU3RyaW5nID8gdGhpcy5lbmNyeXB0aW9uU3RyaW5nIDogJyd9KSwgYCArXG4gICAgICBgaW5zdG9wdDoweCR7Zm9ybWF0SGV4KHRoaXMuaW5zdGFuY2UgPyB0aGlzLmluc3RhbmNlIDogMCwgMil9LCBgICtcbiAgICAgIGB0aHJlYWRJZDoweCR7Zm9ybWF0SGV4KHRoaXMudGhyZWFkSWQgPyB0aGlzLnRocmVhZElkIDogMCwgOCl9LCBgICtcbiAgICAgIGBtYXJzOjB4JHtmb3JtYXRIZXgodGhpcy5tYXJzID8gdGhpcy5tYXJzIDogMCwgMil9KCR7dGhpcy5tYXJzU3RyaW5nID8gdGhpcy5tYXJzU3RyaW5nIDogJyd9KSwgYCArXG4gICAgICBgdHJhY2VJZDoke3RoaXMudHJhY2VJZCA/IHRoaXMudHJhY2VJZC50b1N0cmluZygnaGV4JykgOiAnJ31gO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFByZWxvZ2luUGF5bG9hZDtcbm1vZHVsZS5leHBvcnRzID0gUHJlbG9naW5QYXlsb2FkO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxVQUFBLEdBQUFELE9BQUE7QUFFQSxJQUFBRSx1QkFBQSxHQUFBQyxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQUksT0FBQSxHQUFBSixPQUFBO0FBQXFDLFNBQUFHLHVCQUFBRSxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBRXJDLE1BQU1HLFdBQVcsR0FBRyxFQUFFO0FBRXRCLE1BQU1DLEtBQUssR0FBRztFQUNaQyxPQUFPLEVBQUUsSUFBSTtFQUNiQyxVQUFVLEVBQUUsSUFBSTtFQUNoQkMsT0FBTyxFQUFFLElBQUk7RUFDYkMsUUFBUSxFQUFF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