UNPKG

tedious

Version:

A TDS driver, for connecting to MS SQLServer databases.

213 lines (200 loc) • 27.9 kB
"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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