tedious
Version:
A TDS driver, for connecting to MS SQLServer databases.
213 lines (200 loc) • 27.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _token = require("./token");
var _colinfoTokenParser = _interopRequireDefault(require("./colinfo-token-parser"));
var _colmetadataTokenParser = require("./colmetadata-token-parser");
var _doneTokenParser = require("./done-token-parser");
var _envChangeTokenParser = _interopRequireDefault(require("./env-change-token-parser"));
var _infoerrorTokenParser = require("./infoerror-token-parser");
var _fedauthInfoParser = _interopRequireDefault(require("./fedauth-info-parser"));
var _featureExtAckParser = _interopRequireDefault(require("./feature-ext-ack-parser"));
var _loginackTokenParser = _interopRequireDefault(require("./loginack-token-parser"));
var _orderTokenParser = _interopRequireDefault(require("./order-token-parser"));
var _returnstatusTokenParser = _interopRequireDefault(require("./returnstatus-token-parser"));
var _returnvalueTokenParser = require("./returnvalue-token-parser");
var _rowTokenParser = require("./row-token-parser");
var _nbcrowTokenParser = require("./nbcrow-token-parser");
var _sspiTokenParser = _interopRequireDefault(require("./sspi-token-parser"));
var _tabnameTokenParser = _interopRequireDefault(require("./tabname-token-parser"));
var _helpers = require("./helpers");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Parses a token that is short enough to simply be parsed again from its
* start if it is not fully available yet.
*/
/**
* Parses a token that can grow arbitrarily large, and thus needs to be parsed
* incrementally.
*
* The reader starts parsing right after the token's type byte and keeps its
* progress across calls: if `read` throws a `NotEnoughDataError`, it is
* called again once more data has arrived.
*/
/**
* A push-based parser for the tokens contained in a TDS token stream.
*
* Data is pushed into the parser as it arrives via `write`, and parsed tokens
* are pulled out via `read`. Tokens are parsed lazily, one at a time, so any
* effects of handling a token (e.g. the TDS version negotiated via the
* `LOGINACK` token) apply to the parsing of all tokens that follow it.
*/
class Parser {
// The data that is currently being parsed, and the position of the first
// byte in it that has not been consumed yet.
// Chunks that were written, but not yet appended to `buffer`.
// The number of unconsumed bytes required for parsing to make progress.
//
// Incomplete data is not appended to `buffer` until at least this many
// bytes are available, so that a large token arriving across many chunks is
// not parsed again (and copied again) for every chunk.
// The reader of an incrementally parsed token that is not complete yet.
constructor(options, colMetadata = []) {
this.options = options;
this.colMetadata = colMetadata;
this.buffer = Buffer.alloc(0);
this.position = 0;
this.pending = [];
this.pendingLength = 0;
this.bytesNeeded = 1;
this.tokenReader = undefined;
}
/**
* Parse all tokens from the given chunks of data.
*/
static async *parseTokens(iterable, options, colMetadata) {
const parser = new Parser(options, colMetadata);
for await (const chunk of iterable) {
parser.write(chunk);
let token;
while ((token = parser.read()) !== undefined) {
yield token;
}
}
parser.end();
}
/**
* Add a chunk of data to be parsed.
*/
write(chunk) {
this.pending.push(chunk);
this.pendingLength += chunk.length;
}
/**
* Parse the next token, or return `undefined` if more data needs to be
* written first.
*/
read() {
while (true) {
if (this.buffer.length - this.position < this.bytesNeeded && !this.appendPending()) {
return undefined;
}
let token;
try {
token = this.tokenReader !== undefined ? this.tokenReader.read(this) : this.readToken();
} catch (err) {
if (err instanceof _helpers.NotEnoughDataError) {
// Always wait for at least one more byte, so parsing never retries
// without new data.
this.bytesNeeded = Math.max(err.byteCount, this.buffer.length + 1) - this.position;
continue;
}
throw err;
}
this.tokenReader = undefined;
this.bytesNeeded = 1;
// Some tokens (e.g. unknown `ENVCHANGE` types) are skipped.
if (token !== undefined) {
return token;
}
}
}
/**
* Signal that all data was written.
*
* Throws if the data ended in the middle of a token.
*/
end() {
if (this.tokenReader !== undefined || this.position < this.buffer.length || this.pendingLength > 0) {
throw new Error('unexpected end of data');
}
}
/**
* Append the pending chunks to the unconsumed data, if that makes enough
* data available for parsing to make progress.
*/
appendPending() {
const remaining = this.buffer.length - this.position;
if (remaining + this.pendingLength < this.bytesNeeded) {
return false;
}
if (remaining === 0 && this.pending.length === 1) {
this.buffer = this.pending[0];
} else {
this.pending.unshift(this.buffer.subarray(this.position));
this.buffer = Buffer.concat(this.pending, remaining + this.pendingLength);
}
this.position = 0;
this.pending = [];
this.pendingLength = 0;
return true;
}
readToken() {
const type = this.buffer[this.position];
switch (type) {
case _token.TYPE.DONE:
return this.parseToken(_doneTokenParser.doneParser);
case _token.TYPE.DONEPROC:
return this.parseToken(_doneTokenParser.doneProcParser);
case _token.TYPE.DONEINPROC:
return this.parseToken(_doneTokenParser.doneInProcParser);
case _token.TYPE.ERROR:
return this.parseToken(_infoerrorTokenParser.errorParser);
case _token.TYPE.INFO:
return this.parseToken(_infoerrorTokenParser.infoParser);
case _token.TYPE.ENVCHANGE:
return this.parseToken(_envChangeTokenParser.default);
case _token.TYPE.LOGINACK:
return this.parseToken(_loginackTokenParser.default);
case _token.TYPE.RETURNSTATUS:
return this.parseToken(_returnstatusTokenParser.default);
case _token.TYPE.ORDER:
return this.parseToken(_orderTokenParser.default);
case _token.TYPE.FEDAUTHINFO:
return this.parseToken(_fedauthInfoParser.default);
case _token.TYPE.SSPI:
return this.parseToken(_sspiTokenParser.default);
case _token.TYPE.FEATUREEXTACK:
return this.parseToken(_featureExtAckParser.default);
case _token.TYPE.TABNAME:
return this.parseToken(_tabnameTokenParser.default);
case _token.TYPE.COLINFO:
return this.parseToken(_colinfoTokenParser.default);
case _token.TYPE.COLMETADATA:
return this.startTokenReader(new _colmetadataTokenParser.ColMetadataTokenReader());
case _token.TYPE.RETURNVALUE:
return this.startTokenReader(new _returnvalueTokenParser.ReturnValueTokenReader());
case _token.TYPE.ROW:
return this.startTokenReader(new _rowTokenParser.RowTokenReader());
case _token.TYPE.NBCROW:
return this.startTokenReader(new _nbcrowTokenParser.NBCRowTokenReader());
default:
throw new Error('Unknown type: ' + type);
}
}
parseToken(parser) {
const result = parser(this.buffer, this.position + 1, this.options);
this.position = result.offset;
return result.value;
}
startTokenReader(reader) {
this.position += 1;
this.tokenReader = reader;
return reader.read(this);
}
}
var _default = exports.default = Parser;
module.exports = Parser;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdG9rZW4iLCJyZXF1aXJlIiwiX2NvbGluZm9Ub2tlblBhcnNlciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfY29sbWV0YWRhdGFUb2tlblBhcnNlciIsIl9kb25lVG9rZW5QYXJzZXIiLCJfZW52Q2hhbmdlVG9rZW5QYXJzZXIiLCJfaW5mb2Vycm9yVG9rZW5QYXJzZXIiLCJfZmVkYXV0aEluZm9QYXJzZXIiLCJfZmVhdHVyZUV4dEFja1BhcnNlciIsIl9sb2dpbmFja1Rva2VuUGFyc2VyIiwiX29yZGVyVG9rZW5QYXJzZXIiLCJfcmV0dXJuc3RhdHVzVG9rZW5QYXJzZXIiLCJfcmV0dXJudmFsdWVUb2tlblBhcnNlciIsIl9yb3dUb2tlblBhcnNlciIsIl9uYmNyb3dUb2tlblBhcnNlciIsIl9zc3BpVG9rZW5QYXJzZXIiLCJfdGFibmFtZVRva2VuUGFyc2VyIiwiX2hlbHBlcnMiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJQYXJzZXIiLCJjb25zdHJ1Y3RvciIsIm9wdGlvbnMiLCJjb2xNZXRhZGF0YSIsImJ1ZmZlciIsIkJ1ZmZlciIsImFsbG9jIiwicG9zaXRpb24iLCJwZW5kaW5nIiwicGVuZGluZ0xlbmd0aCIsImJ5dGVzTmVlZGVkIiwidG9rZW5SZWFkZXIiLCJ1bmRlZmluZWQiLCJwYXJzZVRva2VucyIsIml0ZXJhYmxlIiwicGFyc2VyIiwiY2h1bmsiLCJ3cml0ZSIsInRva2VuIiwicmVhZCIsImVuZCIsInB1c2giLCJsZW5ndGgiLCJhcHBlbmRQZW5kaW5nIiwicmVhZFRva2VuIiwiZXJyIiwiTm90RW5vdWdoRGF0YUVycm9yIiwiTWF0aCIsIm1heCIsImJ5dGVDb3VudCIsIkVycm9yIiwicmVtYWluaW5nIiwidW5zaGlmdCIsInN1YmFycmF5IiwiY29uY2F0IiwidHlwZSIsIlRZUEUiLCJET05FIiwicGFyc2VUb2tlbiIsImRvbmVQYXJzZXIiLCJET05FUFJPQyIsImRvbmVQcm9jUGFyc2VyIiwiRE9ORUlOUFJPQyIsImRvbmVJblByb2NQYXJzZXIiLCJFUlJPUiIsImVycm9yUGFyc2VyIiwiSU5GTyIsImluZm9QYXJzZXIiLCJFTlZDSEFOR0UiLCJlbnZDaGFuZ2VQYXJzZXIiLCJMT0dJTkFDSyIsImxvZ2luQWNrUGFyc2VyIiwiUkVUVVJOU1RBVFVTIiwicmV0dXJuU3RhdHVzUGFyc2VyIiwiT1JERVIiLCJvcmRlclBhcnNlciIsIkZFREFVVEhJTkZPIiwiZmVkQXV0aEluZm9QYXJzZXIiLCJTU1BJIiwic3NwaVBhcnNlciIsIkZFQVRVUkVFWFRBQ0siLCJmZWF0dXJlRXh0QWNrUGFyc2VyIiwiVEFCTkFNRSIsInRhYk5hbWVQYXJzZXIiLCJDT0xJTkZPIiwiY29sSW5mb1BhcnNlciIsIkNPTE1FVEFEQVRBIiwic3RhcnRUb2tlblJlYWRlciIsIkNvbE1ldGFkYXRhVG9rZW5SZWFkZXIiLCJSRVRVUk5WQUxVRSIsIlJldHVyblZhbHVlVG9rZW5SZWFkZXIiLCJST1ciLCJSb3dUb2tlblJlYWRlciIsIk5CQ1JPVyIsIk5CQ1Jvd1Rva2VuUmVhZGVyIiwicmVzdWx0Iiwib2Zmc2V0IiwidmFsdWUiLCJyZWFkZXIiLCJfZGVmYXVsdCIsImV4cG9ydHMiLCJtb2R1bGUiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdG9rZW4vc3RyZWFtLXBhcnNlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0eXBlIEludGVybmFsQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9jb25uZWN0aW9uJztcblxuaW1wb3J0IHsgVFlQRSwgdHlwZSBUb2tlbiB9IGZyb20gJy4vdG9rZW4nO1xuXG5pbXBvcnQgY29sSW5mb1BhcnNlciBmcm9tICcuL2NvbGluZm8tdG9rZW4tcGFyc2VyJztcbmltcG9ydCB7IENvbE1ldGFkYXRhVG9rZW5SZWFkZXIsIHR5cGUgQ29sdW1uTWV0YWRhdGEgfSBmcm9tICcuL2NvbG1ldGFkYXRhLXRva2VuLXBhcnNlcic7XG5pbXBvcnQgeyBkb25lUGFyc2VyLCBkb25lSW5Qcm9jUGFyc2VyLCBkb25lUHJvY1BhcnNlciB9IGZyb20gJy4vZG9uZS10b2tlbi1wYXJzZXInO1xuaW1wb3J0IGVudkNoYW5nZVBhcnNlciBmcm9tICcuL2Vudi1jaGFuZ2UtdG9rZW4tcGFyc2VyJztcbmltcG9ydCB7IGVycm9yUGFyc2VyLCBpbmZvUGFyc2VyIH0gZnJvbSAnLi9pbmZvZXJyb3ItdG9rZW4tcGFyc2VyJztcbmltcG9ydCBmZWRBdXRoSW5mb1BhcnNlciBmcm9tICcuL2ZlZGF1dGgtaW5mby1wYXJzZXInO1xuaW1wb3J0IGZlYXR1cmVFeHRBY2tQYXJzZXIgZnJvbSAnLi9mZWF0dXJlLWV4dC1hY2stcGFyc2VyJztcbmltcG9ydCBsb2dpbkFja1BhcnNlciBmcm9tICcuL2xvZ2luYWNrLXRva2VuLXBhcnNlcic7XG5pbXBvcnQgb3JkZXJQYXJzZXIgZnJvbSAnLi9vcmRlci10b2tlbi1wYXJzZXInO1xuaW1wb3J0IHJldHVyblN0YXR1c1BhcnNlciBmcm9tICcuL3JldHVybnN0YXR1cy10b2tlbi1wYXJzZXInO1xuaW1wb3J0IHsgUmV0dXJuVmFsdWVUb2tlblJlYWRlciB9IGZyb20gJy4vcmV0dXJudmFsdWUtdG9rZW4tcGFyc2VyJztcbmltcG9ydCB7IFJvd1Rva2VuUmVhZGVyIH0gZnJvbSAnLi9yb3ctdG9rZW4tcGFyc2VyJztcbmltcG9ydCB7IE5CQ1Jvd1Rva2VuUmVhZGVyIH0gZnJvbSAnLi9uYmNyb3ctdG9rZW4tcGFyc2VyJztcbmltcG9ydCBzc3BpUGFyc2VyIGZyb20gJy4vc3NwaS10b2tlbi1wYXJzZXInO1xuaW1wb3J0IHRhYk5hbWVQYXJzZXIgZnJvbSAnLi90YWJuYW1lLXRva2VuLXBhcnNlcic7XG5pbXBvcnQgeyBOb3RFbm91Z2hEYXRhRXJyb3IsIHR5cGUgUmVzdWx0IH0gZnJvbSAnLi9oZWxwZXJzJztcblxuZXhwb3J0IHR5cGUgUGFyc2VyT3B0aW9ucyA9IFBpY2s8SW50ZXJuYWxDb25uZWN0aW9uT3B0aW9ucywgJ3VzZVVUQycgfCAnbG93ZXJDYXNlR3VpZHMnIHwgJ3Rkc1ZlcnNpb24nIHwgJ3VzZUNvbHVtbk5hbWVzJyB8ICdjb2x1bW5OYW1lUmVwbGFjZXInIHwgJ2NhbWVsQ2FzZUNvbHVtbnMnPjtcblxuLyoqXG4gKiBQYXJzZXMgYSB0b2tlbiB0aGF0IGlzIHNob3J0IGVub3VnaCB0byBzaW1wbHkgYmUgcGFyc2VkIGFnYWluIGZyb20gaXRzXG4gKiBzdGFydCBpZiBpdCBpcyBub3QgZnVsbHkgYXZhaWxhYmxlIHlldC5cbiAqL1xudHlwZSBUb2tlblBhcnNlciA9IChidWY6IEJ1ZmZlciwgb2Zmc2V0OiBudW1iZXIsIG9wdGlvbnM6IFBhcnNlck9wdGlvbnMpID0+IFJlc3VsdDxUb2tlbiB8IHVuZGVmaW5lZD47XG5cbi8qKlxuICogUGFyc2VzIGEgdG9rZW4gdGhhdCBjYW4gZ3JvdyBhcmJpdHJhcmlseSBsYXJnZSwgYW5kIHRodXMgbmVlZHMgdG8gYmUgcGFyc2VkXG4gKiBpbmNyZW1lbnRhbGx5LlxuICpcbiAqIFRoZSByZWFkZXIgc3RhcnRzIHBhcnNpbmcgcmlnaHQgYWZ0ZXIgdGhlIHRva2VuJ3MgdHlwZSBieXRlIGFuZCBrZWVwcyBpdHNcbiAqIHByb2dyZXNzIGFjcm9zcyBjYWxsczogaWYgYHJlYWRgIHRocm93cyBhIGBOb3RFbm91Z2hEYXRhRXJyb3JgLCBpdCBpc1xuICogY2FsbGVkIGFnYWluIG9uY2UgbW9yZSBkYXRhIGhhcyBhcnJpdmVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRva2VuUmVhZGVyIHtcbiAgcmVhZChwYXJzZXI6IFBhcnNlcik6IFRva2VuO1xufVxuXG4vKipcbiAqIEEgcHVzaC1iYXNlZCBwYXJzZXIgZm9yIHRoZSB0b2tlbnMgY29udGFpbmVkIGluIGEgVERTIHRva2VuIHN0cmVhbS5cbiAqXG4gKiBEYXRhIGlzIHB1c2hlZCBpbnRvIHRoZSBwYXJzZXIgYXMgaXQgYXJyaXZlcyB2aWEgYHdyaXRlYCwgYW5kIHBhcnNlZCB0b2tlbnNcbiAqIGFyZSBwdWxsZWQgb3V0IHZpYSBgcmVhZGAuIFRva2VucyBhcmUgcGFyc2VkIGxhemlseSwgb25lIGF0IGEgdGltZSwgc28gYW55XG4gKiBlZmZlY3RzIG9mIGhhbmRsaW5nIGEgdG9rZW4gKGUuZy4gdGhlIFREUyB2ZXJzaW9uIG5lZ290aWF0ZWQgdmlhIHRoZVxuICogYExPR0lOQUNLYCB0b2tlbikgYXBwbHkgdG8gdGhlIHBhcnNpbmcgb2YgYWxsIHRva2VucyB0aGF0IGZvbGxvdyBpdC5cbiAqL1xuY2xhc3MgUGFyc2VyIHtcbiAgZGVjbGFyZSBvcHRpb25zOiBQYXJzZXJPcHRpb25zO1xuICBkZWNsYXJlIGNvbE1ldGFkYXRhOiBDb2x1bW5NZXRhZGF0YVtdO1xuXG4gIC8vIFRoZSBkYXRhIHRoYXQgaXMgY3VycmVudGx5IGJlaW5nIHBhcnNlZCwgYW5kIHRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3RcbiAgLy8gYnl0ZSBpbiBpdCB0aGF0IGhhcyBub3QgYmVlbiBjb25zdW1lZCB5ZXQuXG4gIGRlY2xhcmUgYnVmZmVyOiBCdWZmZXI7XG4gIGRlY2xhcmUgcG9zaXRpb246IG51bWJlcjtcblxuICAvLyBDaHVua3MgdGhhdCB3ZXJlIHdyaXR0ZW4sIGJ1dCBub3QgeWV0IGFwcGVuZGVkIHRvIGBidWZmZXJgLlxuICBkZWNsYXJlIHBlbmRpbmc6IEJ1ZmZlcltdO1xuICBkZWNsYXJlIHBlbmRpbmdMZW5ndGg6IG51bWJlcjtcblxuICAvLyBUaGUgbnVtYmVyIG9mIHVuY29uc3VtZWQgYnl0ZXMgcmVxdWlyZWQgZm9yIHBhcnNpbmcgdG8gbWFrZSBwcm9ncmVzcy5cbiAgLy9cbiAgLy8gSW5jb21wbGV0ZSBkYXRhIGlzIG5vdCBhcHBlbmRlZCB0byBgYnVmZmVyYCB1bnRpbCBhdCBsZWFzdCB0aGlzIG1hbnlcbiAgLy8gYnl0ZXMgYXJlIGF2YWlsYWJsZSwgc28gdGhhdCBhIGxhcmdlIHRva2VuIGFycml2aW5nIGFjcm9zcyBtYW55IGNodW5rcyBpc1xuICAvLyBub3QgcGFyc2VkIGFnYWluIChhbmQgY29waWVkIGFnYWluKSBmb3IgZXZlcnkgY2h1bmsuXG4gIGRlY2xhcmUgYnl0ZXNOZWVkZWQ6IG51bWJlcjtcblxuICAvLyBUaGUgcmVhZGVyIG9mIGFuIGluY3JlbWVudGFsbHkgcGFyc2VkIHRva2VuIHRoYXQgaXMgbm90IGNvbXBsZXRlIHlldC5cbiAgZGVjbGFyZSB0b2tlblJlYWRlcjogVG9rZW5SZWFkZXIgfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogUGFyc2VyT3B0aW9ucywgY29sTWV0YWRhdGE6IENvbHVtbk1ldGFkYXRhW10gPSBbXSkge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgdGhpcy5jb2xNZXRhZGF0YSA9IGNvbE1ldGFkYXRhO1xuXG4gICAgdGhpcy5idWZmZXIgPSBCdWZmZXIuYWxsb2MoMCk7XG4gICAgdGhpcy5wb3NpdGlvbiA9IDA7XG5cbiAgICB0aGlzLnBlbmRpbmcgPSBbXTtcbiAgICB0aGlzLnBlbmRpbmdMZW5ndGggPSAwO1xuXG4gICAgdGhpcy5ieXRlc05lZWRlZCA9IDE7XG4gICAgdGhpcy50b2tlblJlYWRlciA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSBhbGwgdG9rZW5zIGZyb20gdGhlIGdpdmVuIGNodW5rcyBvZiBkYXRhLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jICpwYXJzZVRva2VucyhpdGVyYWJsZTogQXN5bmNJdGVyYWJsZTxCdWZmZXI+IHwgSXRlcmFibGU8QnVmZmVyPiwgb3B0aW9uczogUGFyc2VyT3B0aW9ucywgY29sTWV0YWRhdGE/OiBDb2x1bW5NZXRhZGF0YVtdKTogQXN5bmNHZW5lcmF0b3I8VG9rZW4sIHZvaWQsIHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IHBhcnNlciA9IG5ldyBQYXJzZXIob3B0aW9ucywgY29sTWV0YWRhdGEpO1xuXG4gICAgZm9yIGF3YWl0IChjb25zdCBjaHVuayBvZiBpdGVyYWJsZSkge1xuICAgICAgcGFyc2VyLndyaXRlKGNodW5rKTtcblxuICAgICAgbGV0IHRva2VuO1xuICAgICAgd2hpbGUgKCh0b2tlbiA9IHBhcnNlci5yZWFkKCkpICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgeWllbGQgdG9rZW47XG4gICAgICB9XG4gICAgfVxuXG4gICAgcGFyc2VyLmVuZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIGNodW5rIG9mIGRhdGEgdG8gYmUgcGFyc2VkLlxuICAgKi9cbiAgd3JpdGUoY2h1bms6IEJ1ZmZlcikge1xuICAgIHRoaXMucGVuZGluZy5wdXNoKGNodW5rKTtcbiAgICB0aGlzLnBlbmRpbmdMZW5ndGggKz0gY2h1bmsubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIHRoZSBuZXh0IHRva2VuLCBvciByZXR1cm4gYHVuZGVmaW5lZGAgaWYgbW9yZSBkYXRhIG5lZWRzIHRvIGJlXG4gICAqIHdyaXR0ZW4gZmlyc3QuXG4gICAqL1xuICByZWFkKCk6IFRva2VuIHwgdW5kZWZpbmVkIHtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKHRoaXMuYnVmZmVyLmxlbmd0aCAtIHRoaXMucG9zaXRpb24gPCB0aGlzLmJ5dGVzTmVlZGVkICYmICF0aGlzLmFwcGVuZFBlbmRpbmcoKSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBsZXQgdG9rZW47XG4gICAgICB0cnkge1xuICAgICAgICB0b2tlbiA9IHRoaXMudG9rZW5SZWFkZXIgIT09IHVuZGVmaW5lZCA/IHRoaXMudG9rZW5SZWFkZXIucmVhZCh0aGlzKSA6IHRoaXMucmVhZFRva2VuKCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIE5vdEVub3VnaERhdGFFcnJvcikge1xuICAgICAgICAgIC8vIEFsd2F5cyB3YWl0IGZvciBhdCBsZWFzdCBvbmUgbW9yZSBieXRlLCBzbyBwYXJzaW5nIG5ldmVyIHJldHJpZXNcbiAgICAgICAgICAvLyB3aXRob3V0IG5ldyBkYXRhLlxuICAgICAgICAgIHRoaXMuYnl0ZXNOZWVkZWQgPSBNYXRoLm1heChlcnIuYnl0ZUNvdW50LCB0aGlzLmJ1ZmZlci5sZW5ndGggKyAxKSAtIHRoaXMucG9zaXRpb247XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG5cbiAgICAgIHRoaXMudG9rZW5SZWFkZXIgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmJ5dGVzTmVlZGVkID0gMTtcblxuICAgICAgLy8gU29tZSB0b2tlbnMgKGUuZy4gdW5rbm93biBgRU5WQ0hBTkdFYCB0eXBlcykgYXJlIHNraXBwZWQuXG4gICAgICBpZiAodG9rZW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdG9rZW47XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNpZ25hbCB0aGF0IGFsbCBkYXRhIHdhcyB3cml0dGVuLlxuICAgKlxuICAgKiBUaHJvd3MgaWYgdGhlIGRhdGEgZW5kZWQgaW4gdGhlIG1pZGRsZSBvZiBhIHRva2VuLlxuICAgKi9cbiAgZW5kKCkge1xuICAgIGlmICh0aGlzLnRva2VuUmVhZGVyICE9PSB1bmRlZmluZWQgfHwgdGhpcy5wb3NpdGlvbiA8IHRoaXMuYnVmZmVyLmxlbmd0aCB8fCB0aGlzLnBlbmRpbmdMZW5ndGggPiAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VuZXhwZWN0ZWQgZW5kIG9mIGRhdGEnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQXBwZW5kIHRoZSBwZW5kaW5nIGNodW5rcyB0byB0aGUgdW5jb25zdW1lZCBkYXRhLCBpZiB0aGF0IG1ha2VzIGVub3VnaFxuICAgKiBkYXRhIGF2YWlsYWJsZSBmb3IgcGFyc2luZyB0byBtYWtlIHByb2dyZXNzLlxuICAgKi9cbiAgYXBwZW5kUGVuZGluZygpOiBib29sZWFuIHtcbiAgICBjb25zdCByZW1haW5pbmcgPSB0aGlzLmJ1ZmZlci5sZW5ndGggLSB0aGlzLnBvc2l0aW9uO1xuICAgIGlmIChyZW1haW5pbmcgKyB0aGlzLnBlbmRpbmdMZW5ndGggPCB0aGlzLmJ5dGVzTmVlZGVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHJlbWFpbmluZyA9PT0gMCAmJiB0aGlzLnBlbmRpbmcubGVuZ3RoID09PSAxKSB7XG4gICAgICB0aGlzLmJ1ZmZlciA9IHRoaXMucGVuZGluZ1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wZW5kaW5nLnVuc2hpZnQodGhpcy5idWZmZXIuc3ViYXJyYXkodGhpcy5wb3NpdGlvbikpO1xuICAgICAgdGhpcy5idWZmZXIgPSBCdWZmZXIuY29uY2F0KHRoaXMucGVuZGluZywgcmVtYWluaW5nICsgdGhpcy5wZW5kaW5nTGVuZ3RoKTtcbiAgICB9XG5cbiAgICB0aGlzLnBvc2l0aW9uID0gMDtcbiAgICB0aGlzLnBlbmRpbmcgPSBbXTtcbiAgICB0aGlzLnBlbmRpbmdMZW5ndGggPSAwO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZWFkVG9rZW4oKTogVG9rZW4gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHR5cGUgPSB0aGlzLmJ1ZmZlclt0aGlzLnBvc2l0aW9uXTtcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBUWVBFLkRPTkU6XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlVG9rZW4oZG9uZVBhcnNlcik7XG5cbiAgICAgIGNhc2UgVFlQRS5ET05FUFJPQzpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VUb2tlbihkb25lUHJvY1BhcnNlcik7XG5cbiAgICAgIGNhc2UgVFlQRS5ET05FSU5QUk9DOlxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZVRva2VuKGRvbmVJblByb2NQYXJzZXIpO1xuXG4gICAgICBjYXNlIFRZUEUuRVJST1I6XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlVG9rZW4oZXJyb3JQYXJzZXIpO1xuXG4gICAgICBjYXNlIFRZUEUuSU5GTzpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VUb2tlbihpbmZvUGFyc2VyKTtcblxuICAgICAgY2FzZSBUWVBFLkVOVkNIQU5HRTpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VUb2tlbihlbnZDaGFuZ2VQYXJzZXIpO1xuXG4gICAgICBjYXNlIFRZUEUuTE9HSU5BQ0s6XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlVG9rZW4obG9naW5BY2tQYXJzZXIpO1xuXG4gICAgICBjYXNlIFRZUEUuUkVUVVJOU1RBVFVTOlxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZVRva2VuKHJldHVyblN0YXR1c1BhcnNlcik7XG5cbiAgICAgIGNhc2UgVFlQRS5PUkRFUjpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VUb2tlbihvcmRlclBhcnNlcik7XG5cbiAgICAgIGNhc2UgVFlQRS5GRURBVVRISU5GTzpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VUb2tlbihmZWRBdXRoSW5mb1BhcnNlcik7XG5cbiAgICAgIGNhc2UgVFlQRS5TU1BJOlxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZVRva2VuKHNzcGlQYXJzZXIpO1xuXG4gICAgICBjYXNlIFRZUEUuRkVBVFVSRUVYVEFDSzpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VUb2tlbihmZWF0dXJlRXh0QWNrUGFyc2VyKTtcblxuICAgICAgY2FzZSBUWVBFLlRBQk5BTUU6XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlVG9rZW4odGFiTmFtZVBhcnNlcik7XG5cbiAgICAgIGNhc2UgVFlQRS5DT0xJTkZPOlxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZVRva2VuKGNvbEluZm9QYXJzZXIpO1xuXG4gICAgICBjYXNlIFRZUEUuQ09MTUVUQURBVEE6XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXJ0VG9rZW5SZWFkZXIobmV3IENvbE1ldGFkYXRhVG9rZW5SZWFkZXIoKSk7XG5cbiAgICAgIGNhc2UgVFlQRS5SRVRVUk5WQUxVRTpcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnRUb2tlblJlYWRlcihuZXcgUmV0dXJuVmFsdWVUb2tlblJlYWRlcigpKTtcblxuICAgICAgY2FzZSBUWVBFLlJPVzpcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnRUb2tlblJlYWRlcihuZXcgUm93VG9rZW5SZWFkZXIoKSk7XG5cbiAgICAgIGNhc2UgVFlQRS5OQkNST1c6XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXJ0VG9rZW5SZWFkZXIobmV3IE5CQ1Jvd1Rva2VuUmVhZGVyKCkpO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gdHlwZTogJyArIHR5cGUpO1xuICAgIH1cbiAgfVxuXG4gIHBhcnNlVG9rZW4ocGFyc2VyOiBUb2tlblBhcnNlcik6IFRva2VuIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCByZXN1bHQgPSBwYXJzZXIodGhpcy5idWZmZXIsIHRoaXMucG9zaXRpb24gKyAxLCB0aGlzLm9wdGlvbnMpO1xuICAgIHRoaXMucG9zaXRpb24gPSByZXN1bHQub2Zmc2V0O1xuICAgIHJldHVybiByZXN1bHQudmFsdWU7XG4gIH1cblxuICBzdGFydFRva2VuUmVhZGVyKHJlYWRlcjogVG9rZW5SZWFkZXIpOiBUb2tlbiB7XG4gICAgdGhpcy5wb3NpdGlvbiArPSAxO1xuICAgIHRoaXMudG9rZW5SZWFkZXIgPSByZWFkZXI7XG4gICAgcmV0dXJuIHJlYWRlci5yZWFkKHRoaXMpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBhcnNlcjtcbm1vZHVsZS5leHBvcnRzID0gUGFyc2VyO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFFQSxJQUFBQSxNQUFBLEdBQUFDLE9BQUE7QUFFQSxJQUFBQyxtQkFBQSxHQUFBQyxzQkFBQSxDQUFBRixPQUFBO0FBQ0EsSUFBQUcsdUJBQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLGdCQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxxQkFBQSxHQUFBSCxzQkFBQSxDQUFBRixPQUFBO0FBQ0EsSUFBQU0scUJBQUEsR0FBQU4sT0FBQTtBQUNBLElBQUFPLGtCQUFBLEdBQUFMLHNC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