tedious
Version:
A TDS driver, for connecting to MS SQLServer databases.
493 lines • 64.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.tds71DeprecationWarning = exports.UnexpectedTokenError = exports.TokenHandler = exports.RequestTokenHandler = exports.Login7TokenHandler = exports.InitialSqlTokenHandler = exports.AttentionTokenHandler = void 0;
var _request = _interopRequireDefault(require("../request"));
var _errors = require("../errors");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
class UnexpectedTokenError extends Error {
constructor(handler, token) {
super('Unexpected token `' + token.name + '` in `' + handler.constructor.name + '`');
}
}
/**
* Emits a warning (once per process) when a connection is established
* using TDS 7.1.
*
* @private
*/
exports.UnexpectedTokenError = UnexpectedTokenError;
const tds71DeprecationWarning = exports.tds71DeprecationWarning = {
emitted: false,
emit() {
if (this.emitted) {
return;
}
this.emitted = true;
process.emitWarning('Support for TDS 7.1 (used by SQL Server 2000) is deprecated and will be removed in a future version of `tedious`.', {
type: 'DeprecationWarning',
code: 'TEDIOUS_DEP_TDS71'
});
}
};
class TokenHandler {
onInfoMessage(token) {
throw new UnexpectedTokenError(this, token);
}
onErrorMessage(token) {
throw new UnexpectedTokenError(this, token);
}
onSSPI(token) {
throw new UnexpectedTokenError(this, token);
}
onDatabaseChange(token) {
throw new UnexpectedTokenError(this, token);
}
onLanguageChange(token) {
throw new UnexpectedTokenError(this, token);
}
onCharsetChange(token) {
throw new UnexpectedTokenError(this, token);
}
onSqlCollationChange(token) {
throw new UnexpectedTokenError(this, token);
}
onRoutingChange(token) {
throw new UnexpectedTokenError(this, token);
}
onPacketSizeChange(token) {
throw new UnexpectedTokenError(this, token);
}
onResetConnection(token) {
throw new UnexpectedTokenError(this, token);
}
onBeginTransaction(token) {
throw new UnexpectedTokenError(this, token);
}
onCommitTransaction(token) {
throw new UnexpectedTokenError(this, token);
}
onRollbackTransaction(token) {
throw new UnexpectedTokenError(this, token);
}
onFedAuthInfo(token) {
throw new UnexpectedTokenError(this, token);
}
onFeatureExtAck(token) {
throw new UnexpectedTokenError(this, token);
}
onLoginAck(token) {
throw new UnexpectedTokenError(this, token);
}
onColMetadata(token) {
throw new UnexpectedTokenError(this, token);
}
onTabName(token) {
throw new UnexpectedTokenError(this, token);
}
onColInfo(token) {
throw new UnexpectedTokenError(this, token);
}
onOrder(token) {
throw new UnexpectedTokenError(this, token);
}
onRow(token) {
throw new UnexpectedTokenError(this, token);
}
onReturnStatus(token) {
throw new UnexpectedTokenError(this, token);
}
onReturnValue(token) {
throw new UnexpectedTokenError(this, token);
}
onDoneProc(token) {
throw new UnexpectedTokenError(this, token);
}
onDoneInProc(token) {
throw new UnexpectedTokenError(this, token);
}
onDone(token) {
throw new UnexpectedTokenError(this, token);
}
onDatabaseMirroringPartner(token) {
throw new UnexpectedTokenError(this, token);
}
}
/**
* A handler for tokens received in the response message to the initial SQL Batch request
* that sets up different connection settings.
*/
exports.TokenHandler = TokenHandler;
class InitialSqlTokenHandler extends TokenHandler {
constructor(connection) {
super();
this.connection = connection;
}
onInfoMessage(token) {
this.connection.emit('infoMessage', token);
}
onErrorMessage(token) {
this.connection.emit('errorMessage', token);
}
onDatabaseChange(token) {
this.connection.emit('databaseChange', token.newValue);
}
onLanguageChange(token) {
this.connection.emit('languageChange', token.newValue);
}
onCharsetChange(token) {
this.connection.emit('charsetChange', token.newValue);
}
onSqlCollationChange(token) {
this.connection.databaseCollation = token.newValue;
}
onPacketSizeChange(token) {
this.connection.messageIo.packetSize(token.newValue);
}
onBeginTransaction(token) {
this.connection.transactionDescriptors.push(token.newValue);
this.connection.inTransaction = true;
}
onCommitTransaction(token) {
this.connection.transactionDescriptors.length = 1;
this.connection.inTransaction = false;
}
onRollbackTransaction(token) {
this.connection.transactionDescriptors.length = 1;
// An outermost transaction was rolled back. Reset the transaction counter
this.connection.inTransaction = false;
this.connection.emit('rollbackTransaction');
}
onColMetadata(token) {
this.connection.emit('error', new Error("Received 'columnMetadata' when no sqlRequest is in progress"));
this.connection.close();
}
onOrder(token) {
this.connection.emit('error', new Error("Received 'order' when no sqlRequest is in progress"));
this.connection.close();
}
onRow(token) {
this.connection.emit('error', new Error("Received 'row' when no sqlRequest is in progress"));
this.connection.close();
}
onReturnStatus(token) {
// Do nothing
}
onReturnValue(token) {
// Do nothing
}
onDoneProc(token) {
// Do nothing
}
onDoneInProc(token) {
// Do nothing
}
onDone(token) {
// Do nothing
}
onResetConnection(token) {
this.connection.emit('resetConnection');
}
}
/**
* A handler for tokens received in the response message to a Login7 message.
*/
exports.InitialSqlTokenHandler = InitialSqlTokenHandler;
class Login7TokenHandler extends TokenHandler {
constructor(connection) {
super();
this.loginAckReceived = false;
this.connection = connection;
this.loginError = undefined;
}
onInfoMessage(token) {
this.connection.emit('infoMessage', token);
}
onErrorMessage(token) {
this.connection.emit('errorMessage', token);
const error = new _errors.ConnectionError(token.message, 'ELOGIN');
const isLoginErrorTransient = this.connection.transientErrorLookup.isTransientError(token.number);
if (isLoginErrorTransient && this.connection.curTransientRetryCount !== this.connection.config.options.maxRetriesOnTransientErrors) {
error.isTransient = true;
}
this.loginError = error;
}
onSSPI(token) {
if (token.ntlmpacket) {
this.connection.ntlmpacket = token.ntlmpacket;
this.connection.ntlmpacketBuffer = token.ntlmpacketBuffer;
}
}
onDatabaseChange(token) {
this.connection.emit('databaseChange', token.newValue);
}
onDatabaseMirroringPartner(token) {
this.connection.emit('databaseMirroringPartner', token.newValue);
}
onLanguageChange(token) {
this.connection.emit('languageChange', token.newValue);
}
onCharsetChange(token) {
this.connection.emit('charsetChange', token.newValue);
}
onSqlCollationChange(token) {
this.connection.databaseCollation = token.newValue;
}
onFedAuthInfo(token) {
this.fedAuthInfoToken = token;
}
onFeatureExtAck(token) {
const {
authentication
} = this.connection.config;
if (authentication.type === 'azure-active-directory-password' || authentication.type === 'azure-active-directory-access-token' || authentication.type === 'azure-active-directory-msi-vm' || authentication.type === 'azure-active-directory-msi-app-service' || authentication.type === 'azure-active-directory-service-principal-secret' || authentication.type === 'azure-active-directory-default') {
if (token.fedAuth === undefined) {
this.loginError = new _errors.ConnectionError('Did not receive Active Directory authentication acknowledgement');
} else if (token.fedAuth.length !== 0) {
this.loginError = new _errors.ConnectionError(`Active Directory authentication acknowledgment for ${authentication.type} authentication method includes extra data`);
}
} else if (token.fedAuth === undefined && token.utf8Support === undefined) {
this.loginError = new _errors.ConnectionError('Received acknowledgement for unknown feature');
} else if (token.fedAuth) {
this.loginError = new _errors.ConnectionError('Did not request Active Directory authentication, but received the acknowledgment');
}
}
onLoginAck(token) {
if (!token.tdsVersion) {
// unsupported TDS version
this.loginError = new _errors.ConnectionError('Server responded with unknown TDS version.', 'ETDS');
return;
}
if (!token.interface) {
// unsupported interface
this.loginError = new _errors.ConnectionError('Server responded with unsupported interface.', 'EINTERFACENOTSUPP');
return;
}
// use negotiated version
this.connection.config.options.tdsVersion = token.tdsVersion;
if (token.tdsVersion < '7_2') {
tds71DeprecationWarning.emit();
}
this.loginAckReceived = true;
}
onRoutingChange(token) {
// Splits instance name attached to the redirect url. E.g., redirect.db.net\instance1 --> [redirect.db.net, instance1]
const [server, instance] = token.newValue.server.split('\\');
this.routingData = {
server,
port: token.newValue.port,
instance
};
}
onDoneInProc(token) {
// Do nothing
}
onDone(token) {
// Do nothing
}
onPacketSizeChange(token) {
this.connection.messageIo.packetSize(token.newValue);
}
}
/**
* A handler for tokens received in the response message to a RPC Request,
* a SQL Batch Request, a Bulk Load BCP Request or a Transaction Manager Request.
*/
exports.Login7TokenHandler = Login7TokenHandler;
class RequestTokenHandler extends TokenHandler {
constructor(connection, request) {
super();
this.connection = connection;
this.request = request;
this.errors = [];
}
onInfoMessage(token) {
this.connection.emit('infoMessage', token);
}
onErrorMessage(token) {
this.connection.emit('errorMessage', token);
if (!this.request.canceled) {
const error = new _errors.RequestError(token.message, 'EREQUEST');
error.number = token.number;
error.state = token.state;
error.class = token.class;
error.serverName = token.serverName;
error.procName = token.procName;
error.lineNumber = token.lineNumber;
this.errors.push(error);
this.request.error = error;
if (this.request instanceof _request.default && this.errors.length > 1) {
this.request.error = new AggregateError(this.errors);
}
}
}
onDatabaseChange(token) {
this.connection.emit('databaseChange', token.newValue);
}
onLanguageChange(token) {
this.connection.emit('languageChange', token.newValue);
}
onCharsetChange(token) {
this.connection.emit('charsetChange', token.newValue);
}
onSqlCollationChange(token) {
this.connection.databaseCollation = token.newValue;
}
onPacketSizeChange(token) {
this.connection.messageIo.packetSize(token.newValue);
}
onBeginTransaction(token) {
this.connection.transactionDescriptors.push(token.newValue);
this.connection.inTransaction = true;
}
onCommitTransaction(token) {
this.connection.transactionDescriptors.length = 1;
this.connection.inTransaction = false;
}
onRollbackTransaction(token) {
this.connection.transactionDescriptors.length = 1;
// An outermost transaction was rolled back. Reset the transaction counter
this.connection.inTransaction = false;
this.connection.emit('rollbackTransaction');
}
onColMetadata(token) {
if (!this.request.canceled) {
if (this.connection.config.options.useColumnNames) {
const columns = Object.create(null);
for (let j = 0, len = token.columns.length; j < len; j++) {
const col = token.columns[j];
if (columns[col.colName] == null) {
columns[col.colName] = col;
}
}
this.request.emit('columnMetadata', columns);
} else {
this.request.emit('columnMetadata', token.columns);
}
}
}
onTabName(token) {
if (!this.request.canceled) {
this.request.emit('tabName', token.tableNames);
}
}
onColInfo(token) {
if (!this.request.canceled) {
this.request.emit('colInfo', token.columns);
}
}
onOrder(token) {
if (!this.request.canceled) {
this.request.emit('order', token.orderColumns);
}
}
onRow(token) {
if (!this.request.canceled) {
if (this.connection.config.options.rowCollectionOnRequestCompletion) {
this.request.rows.push(token.columns);
}
if (this.connection.config.options.rowCollectionOnDone) {
this.request.rst.push(token.columns);
}
this.request.emit('row', token.columns);
}
}
onReturnStatus(token) {
if (!this.request.canceled) {
// Keep value for passing in 'doneProc' event.
this.connection.procReturnStatusValue = token.value;
}
}
onReturnValue(token) {
if (!this.request.canceled) {
// The response to `sp_prepare` returns the prepared statement's handle.
if (this.request instanceof _request.default && this.request.preparing) {
if (token.paramName === 'handle') {
this.request.handle = token.value;
} else {
this.request.error = new _errors.RequestError(`Tedious > Unexpected output parameter ${token.paramName} from sp_prepare`);
}
}
this.request.emit('returnValue', token.paramName, token.value, token.metadata);
}
}
onDoneProc(token) {
if (!this.request.canceled) {
if (token.sqlError && !this.request.error) {
// check if the DONE_ERROR flags was set, but an ERROR token was not sent.
this.request.error = new _errors.RequestError('An unknown error has occurred.', 'UNKNOWN');
}
this.request.emit('doneProc', token.rowCount, token.more, this.connection.procReturnStatusValue, this.request.rst);
this.connection.procReturnStatusValue = undefined;
if (token.rowCount !== undefined) {
this.request.rowCount += token.rowCount;
}
if (this.connection.config.options.rowCollectionOnDone) {
this.request.rst = [];
}
}
}
onDoneInProc(token) {
if (!this.request.canceled) {
this.request.emit('doneInProc', token.rowCount, token.more, this.request.rst);
if (token.rowCount !== undefined) {
this.request.rowCount += token.rowCount;
}
if (this.connection.config.options.rowCollectionOnDone) {
this.request.rst = [];
}
}
}
onDone(token) {
if (!this.request.canceled) {
if (token.sqlError && !this.request.error) {
// check if the DONE_ERROR flags was set, but an ERROR token was not sent.
this.request.error = new _errors.RequestError('An unknown error has occurred.', 'UNKNOWN');
}
this.request.emit('done', token.rowCount, token.more, this.request.rst);
if (token.rowCount !== undefined) {
this.request.rowCount += token.rowCount;
}
if (this.connection.config.options.rowCollectionOnDone) {
this.request.rst = [];
}
}
}
onResetConnection(token) {
this.connection.emit('resetConnection');
}
}
/**
* A handler for the attention acknowledgement message.
*
* This message only contains a `DONE` token that acknowledges
* that the attention message was received by the server.
*/
exports.RequestTokenHandler = RequestTokenHandler;
class AttentionTokenHandler extends TokenHandler {
/**
* Returns whether an attention acknowledgement was received.
*/
constructor(connection, request) {
super();
this.connection = connection;
this.request = request;
this.attentionReceived = false;
}
onDone(token) {
if (token.attention) {
this.attentionReceived = true;
}
}
}
exports.AttentionTokenHandler = AttentionTokenHandler;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVxdWVzdCIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX2Vycm9ycyIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsIlVuZXhwZWN0ZWRUb2tlbkVycm9yIiwiRXJyb3IiLCJjb25zdHJ1Y3RvciIsImhhbmRsZXIiLCJ0b2tlbiIsIm5hbWUiLCJleHBvcnRzIiwidGRzNzFEZXByZWNhdGlvbldhcm5pbmciLCJlbWl0dGVkIiwiZW1pdCIsInByb2Nlc3MiLCJlbWl0V2FybmluZyIsInR5cGUiLCJjb2RlIiwiVG9rZW5IYW5kbGVyIiwib25JbmZvTWVzc2FnZSIsIm9uRXJyb3JNZXNzYWdlIiwib25TU1BJIiwib25EYXRhYmFzZUNoYW5nZSIsIm9uTGFuZ3VhZ2VDaGFuZ2UiLCJvbkNoYXJzZXRDaGFuZ2UiLCJvblNxbENvbGxhdGlvbkNoYW5nZSIsIm9uUm91dGluZ0NoYW5nZSIsIm9uUGFja2V0U2l6ZUNoYW5nZSIsIm9uUmVzZXRDb25uZWN0aW9uIiwib25CZWdpblRyYW5zYWN0aW9uIiwib25Db21taXRUcmFuc2FjdGlvbiIsIm9uUm9sbGJhY2tUcmFuc2FjdGlvbiIsIm9uRmVkQXV0aEluZm8iLCJvbkZlYXR1cmVFeHRBY2siLCJvbkxvZ2luQWNrIiwib25Db2xNZXRhZGF0YSIsIm9uVGFiTmFtZSIsIm9uQ29sSW5mbyIsIm9uT3JkZXIiLCJvblJvdyIsIm9uUmV0dXJuU3RhdHVzIiwib25SZXR1cm5WYWx1ZSIsIm9uRG9uZVByb2MiLCJvbkRvbmVJblByb2MiLCJvbkRvbmUiLCJvbkRhdGFiYXNlTWlycm9yaW5nUGFydG5lciIsIkluaXRpYWxTcWxUb2tlbkhhbmRsZXIiLCJjb25uZWN0aW9uIiwibmV3VmFsdWUiLCJkYXRhYmFzZUNvbGxhdGlvbiIsIm1lc3NhZ2VJbyIsInBhY2tldFNpemUiLCJ0cmFuc2FjdGlvbkRlc2NyaXB0b3JzIiwicHVzaCIsImluVHJhbnNhY3Rpb24iLCJsZW5ndGgiLCJjbG9zZSIsIkxvZ2luN1Rva2VuSGFuZGxlciIsImxvZ2luQWNrUmVjZWl2ZWQiLCJsb2dpbkVycm9yIiwidW5kZWZpbmVkIiwiZXJyb3IiLCJDb25uZWN0aW9uRXJyb3IiLCJtZXNzYWdlIiwiaXNMb2dpbkVycm9yVHJhbnNpZW50IiwidHJhbnNpZW50RXJyb3JMb29rdXAiLCJpc1RyYW5zaWVudEVycm9yIiwibnVtYmVyIiwiY3VyVHJhbnNpZW50UmV0cnlDb3VudCIsImNvbmZpZyIsIm9wdGlvbnMiLCJtYXhSZXRyaWVzT25UcmFuc2llbnRFcnJvcnMiLCJpc1RyYW5zaWVudCIsIm50bG1wYWNrZXQiLCJudGxtcGFja2V0QnVmZmVyIiwiZmVkQXV0aEluZm9Ub2tlbiIsImF1dGhlbnRpY2F0aW9uIiwiZmVkQXV0aCIsInV0ZjhTdXBwb3J0IiwidGRzVmVyc2lvbiIsImludGVyZmFjZSIsInNlcnZlciIsImluc3RhbmNlIiwic3BsaXQiLCJyb3V0aW5nRGF0YSIsInBvcnQiLCJSZXF1ZXN0VG9rZW5IYW5kbGVyIiwicmVxdWVzdCIsImVycm9ycyIsImNhbmNlbGVkIiwiUmVxdWVzdEVycm9yIiwic3RhdGUiLCJjbGFzcyIsInNlcnZlck5hbWUiLCJwcm9jTmFtZSIsImxpbmVOdW1iZXIiLCJSZXF1ZXN0IiwiQWdncmVnYXRlRXJyb3IiLCJ1c2VDb2x1bW5OYW1lcyIsImNvbHVtbnMiLCJPYmplY3QiLCJjcmVhdGUiLCJqIiwibGVuIiwiY29sIiwiY29sTmFtZSIsInRhYmxlTmFtZXMiLCJvcmRlckNvbHVtbnMiLCJyb3dDb2xsZWN0aW9uT25SZXF1ZXN0Q29tcGxldGlvbiIsInJvd3MiLCJyb3dDb2xsZWN0aW9uT25Eb25lIiwicnN0IiwicHJvY1JldHVyblN0YXR1c1ZhbHVlIiwidmFsdWUiLCJwcmVwYXJpbmciLCJwYXJhbU5hbWUiLCJoYW5kbGUiLCJtZXRhZGF0YSIsInNxbEVycm9yIiwicm93Q291bnQiLCJtb3JlIiwiQXR0ZW50aW9uVG9rZW5IYW5kbGVyIiwiYXR0ZW50aW9uUmVjZWl2ZWQiLCJhdHRlbnRpb24iXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdG9rZW4vaGFuZGxlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ29ubmVjdGlvbiBmcm9tICcuLi9jb25uZWN0aW9uJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4uL3JlcXVlc3QnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbkVycm9yLCBSZXF1ZXN0RXJyb3IgfSBmcm9tICcuLi9lcnJvcnMnO1xuaW1wb3J0IHsgdHlwZSBDb2x1bW5NZXRhZGF0YSB9IGZyb20gJy4vY29sbWV0YWRhdGEtdG9rZW4tcGFyc2VyJztcbmltcG9ydCB7XG4gIEJlZ2luVHJhbnNhY3Rpb25FbnZDaGFuZ2VUb2tlbixcbiAgQ2hhcnNldEVudkNoYW5nZVRva2VuLFxuICBDb2xJbmZvVG9rZW4sXG4gIENvbGxhdGlvbkNoYW5nZVRva2VuLFxuICBDb2xNZXRhZGF0YVRva2VuLFxuICBDb21taXRUcmFuc2FjdGlvbkVudkNoYW5nZVRva2VuLFxuICBEYXRhYmFzZUVudkNoYW5nZVRva2VuLFxuICBEYXRhYmFzZU1pcnJvcmluZ1BhcnRuZXJFbnZDaGFuZ2VUb2tlbixcbiAgRG9uZUluUHJvY1Rva2VuLFxuICBEb25lUHJvY1Rva2VuLFxuICBEb25lVG9rZW4sXG4gIEVycm9yTWVzc2FnZVRva2VuLFxuICBGZWF0dXJlRXh0QWNrVG9rZW4sXG4gIEZlZEF1dGhJbmZvVG9rZW4sXG4gIEluZm9NZXNzYWdlVG9rZW4sXG4gIExhbmd1YWdlRW52Q2hhbmdlVG9rZW4sXG4gIExvZ2luQWNrVG9rZW4sXG4gIE5CQ1Jvd1Rva2VuLFxuICBPcmRlclRva2VuLFxuICBQYWNrZXRTaXplRW52Q2hhbmdlVG9rZW4sXG4gIFJlc2V0Q29ubmVjdGlvbkVudkNoYW5nZVRva2VuLFxuICBSZXR1cm5TdGF0dXNUb2tlbixcbiAgUmV0dXJuVmFsdWVUb2tlbixcbiAgUm9sbGJhY2tUcmFuc2FjdGlvbkVudkNoYW5nZVRva2VuLFxuICBSb3V0aW5nRW52Q2hhbmdlVG9rZW4sXG4gIFJvd1Rva2VuLFxuICBTU1BJVG9rZW4sXG4gIFRhYk5hbWVUb2tlbixcbiAgVG9rZW5cbn0gZnJvbSAnLi90b2tlbic7XG5pbXBvcnQgQnVsa0xvYWQgZnJvbSAnLi4vYnVsay1sb2FkJztcblxuZXhwb3J0IGNsYXNzIFVuZXhwZWN0ZWRUb2tlbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihoYW5kbGVyOiBUb2tlbkhhbmRsZXIsIHRva2VuOiBUb2tlbikge1xuICAgIHN1cGVyKCdVbmV4cGVjdGVkIHRva2VuIGAnICsgdG9rZW4ubmFtZSArICdgIGluIGAnICsgaGFuZGxlci5jb25zdHJ1Y3Rvci5uYW1lICsgJ2AnKTtcbiAgfVxufVxuXG4vKipcbiAqIEVtaXRzIGEgd2FybmluZyAob25jZSBwZXIgcHJvY2Vzcykgd2hlbiBhIGNvbm5lY3Rpb24gaXMgZXN0YWJsaXNoZWRcbiAqIHVzaW5nIFREUyA3LjEuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IHRkczcxRGVwcmVjYXRpb25XYXJuaW5nID0ge1xuICBlbWl0dGVkOiBmYWxzZSxcblxuICBlbWl0KCkge1xuICAgIGlmICh0aGlzLmVtaXR0ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5lbWl0dGVkID0gdHJ1ZTtcblxuICAgIHByb2Nlc3MuZW1pdFdhcm5pbmcoXG4gICAgICAnU3VwcG9ydCBmb3IgVERTIDcuMSAodXNlZCBieSBTUUwgU2VydmVyIDIwMDApIGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uIG9mIGB0ZWRpb3VzYC4nLFxuICAgICAgeyB0eXBlOiAnRGVwcmVjYXRpb25XYXJuaW5nJywgY29kZTogJ1RFRElPVVNfREVQX1REUzcxJyB9XG4gICAgKTtcbiAgfVxufTtcblxuZXhwb3J0IGNsYXNzIFRva2VuSGFuZGxlciB7XG4gIG9uSW5mb01lc3NhZ2UodG9rZW46IEluZm9NZXNzYWdlVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IodGhpcywgdG9rZW4pO1xuICB9XG5cbiAgb25FcnJvck1lc3NhZ2UodG9rZW46IEVycm9yTWVzc2FnZVRva2VuKSB7XG4gICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRUb2tlbkVycm9yKHRoaXMsIHRva2VuKTtcbiAgfVxuXG4gIG9uU1NQSSh0b2tlbjogU1NQSVRva2VuKSB7XG4gICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRUb2tlbkVycm9yKHRoaXMsIHRva2VuKTtcbiAgfVxuXG4gIG9uRGF0YWJhc2VDaGFuZ2UodG9rZW46IERhdGFiYXNlRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IodGhpcywgdG9rZW4pO1xuICB9XG5cbiAgb25MYW5ndWFnZUNoYW5nZSh0b2tlbjogTGFuZ3VhZ2VFbnZDaGFuZ2VUb2tlbikge1xuICAgIHRocm93IG5ldyBVbmV4cGVjdGVkVG9rZW5FcnJvcih0aGlzLCB0b2tlbik7XG4gIH1cblxuICBvbkNoYXJzZXRDaGFuZ2UodG9rZW46IENoYXJzZXRFbnZDaGFuZ2VUb2tlbikge1xuICAgIHRocm93IG5ldyBVbmV4cGVjdGVkVG9rZW5FcnJvcih0aGlzLCB0b2tlbik7XG4gIH1cblxuICBvblNxbENvbGxhdGlvbkNoYW5nZSh0b2tlbjogQ29sbGF0aW9uQ2hhbmdlVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IodGhpcywgdG9rZW4pO1xuICB9XG5cbiAgb25Sb3V0aW5nQ2hhbmdlKHRva2VuOiBSb3V0aW5nRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IodGhpcywgdG9rZW4pO1xuICB9XG5cbiAgb25QYWNrZXRTaXplQ2hhbmdlKHRva2VuOiBQYWNrZXRTaXplRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IodGhpcywgdG9rZW4pO1xuICB9XG5cbiAgb25SZXNldENvbm5lY3Rpb24odG9rZW46IFJlc2V0Q29ubmVjdGlvbkVudkNoYW5nZVRva2VuKSB7XG4gICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRUb2tlbkVycm9yKHRoaXMsIHRva2VuKTtcbiAgfVxuXG4gIG9uQmVnaW5UcmFuc2FjdGlvbih0b2tlbjogQmVnaW5UcmFuc2FjdGlvbkVudkNoYW5nZVRva2VuKSB7XG4gICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRUb2tlbkVycm9yKHRoaXMsIHRva2VuKTtcbiAgfVxuXG4gIG9uQ29tbWl0VHJhbnNhY3Rpb24odG9rZW46IENvbW1pdFRyYW5zYWN0aW9uRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IodGhpcywgdG9rZW4pO1xuICB9XG5cbiAgb25Sb2xsYmFja1RyYW5zYWN0aW9uKHRva2VuOiBSb2xsYmFja1RyYW5zYWN0aW9uRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IodGhpcywgdG9rZW4pO1xuICB9XG5cbiAgb25GZWRBdXRoSW5mbyh0b2tlbjogRmVkQXV0aEluZm9Ub2tlbikge1xuICAgIHRocm93IG5ldyBVbmV4cGVjdGVkVG9rZW5FcnJvcih0aGlzLCB0b2tlbik7XG4gIH1cblxuICBvbkZlYXR1cmVFeHRBY2sodG9rZW46IEZlYXR1cmVFeHRBY2tUb2tlbikge1xuICAgIHRocm93IG5ldyBVbmV4cGVjdGVkVG9rZW5FcnJvcih0aGlzLCB0b2tlbik7XG4gIH1cblxuICBvbkxvZ2luQWNrKHRva2VuOiBMb2dpbkFja1Rva2VuKSB7XG4gICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRUb2tlbkVycm9yKHRoaXMsIHRva2VuKTtcbiAgfVxuXG4gIG9uQ29sTWV0YWRhdGEodG9rZW46IENvbE1ldGFkYXRhVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IodGhpcywgdG9rZW4pO1xuICB9XG5cbiAgb25UYWJOYW1lKHRva2VuOiBUYWJOYW1lVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IodGhpcywgdG9rZW4pO1xuICB9XG5cbiAgb25Db2xJbmZvKHRva2VuOiBDb2xJbmZvVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IodGhpcywgdG9rZW4pO1xuICB9XG5cbiAgb25PcmRlcih0b2tlbjogT3JkZXJUb2tlbikge1xuICAgIHRocm93IG5ldyBVbmV4cGVjdGVkVG9rZW5FcnJvcih0aGlzLCB0b2tlbik7XG4gIH1cblxuICBvblJvdyh0b2tlbjogUm93VG9rZW4gfCBOQkNSb3dUb2tlbikge1xuICAgIHRocm93IG5ldyBVbmV4cGVjdGVkVG9rZW5FcnJvcih0aGlzLCB0b2tlbik7XG4gIH1cblxuICBvblJldHVyblN0YXR1cyh0b2tlbjogUmV0dXJuU3RhdHVzVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IodGhpcywgdG9rZW4pO1xuICB9XG5cbiAgb25SZXR1cm5WYWx1ZSh0b2tlbjogUmV0dXJuVmFsdWVUb2tlbikge1xuICAgIHRocm93IG5ldyBVbmV4cGVjdGVkVG9rZW5FcnJvcih0aGlzLCB0b2tlbik7XG4gIH1cblxuICBvbkRvbmVQcm9jKHRva2VuOiBEb25lUHJvY1Rva2VuKSB7XG4gICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRUb2tlbkVycm9yKHRoaXMsIHRva2VuKTtcbiAgfVxuXG4gIG9uRG9uZUluUHJvYyh0b2tlbjogRG9uZUluUHJvY1Rva2VuKSB7XG4gICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRUb2tlbkVycm9yKHRoaXMsIHRva2VuKTtcbiAgfVxuXG4gIG9uRG9uZSh0b2tlbjogRG9uZVRva2VuKSB7XG4gICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRUb2tlbkVycm9yKHRoaXMsIHRva2VuKTtcbiAgfVxuXG4gIG9uRGF0YWJhc2VNaXJyb3JpbmdQYXJ0bmVyKHRva2VuOiBEYXRhYmFzZU1pcnJvcmluZ1BhcnRuZXJFbnZDaGFuZ2VUb2tlbikge1xuICAgIHRocm93IG5ldyBVbmV4cGVjdGVkVG9rZW5FcnJvcih0aGlzLCB0b2tlbik7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGhhbmRsZXIgZm9yIHRva2VucyByZWNlaXZlZCBpbiB0aGUgcmVzcG9uc2UgbWVzc2FnZSB0byB0aGUgaW5pdGlhbCBTUUwgQmF0Y2ggcmVxdWVzdFxuICogdGhhdCBzZXRzIHVwIGRpZmZlcmVudCBjb25uZWN0aW9uIHNldHRpbmdzLlxuICovXG5leHBvcnQgY2xhc3MgSW5pdGlhbFNxbFRva2VuSGFuZGxlciBleHRlbmRzIFRva2VuSGFuZGxlciB7XG4gIGRlY2xhcmUgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICBjb25zdHJ1Y3Rvcihjb25uZWN0aW9uOiBDb25uZWN0aW9uKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gIH1cblxuICBvbkluZm9NZXNzYWdlKHRva2VuOiBJbmZvTWVzc2FnZVRva2VuKSB7XG4gICAgdGhpcy5jb25uZWN0aW9uLmVtaXQoJ2luZm9NZXNzYWdlJywgdG9rZW4pO1xuICB9XG5cbiAgb25FcnJvck1lc3NhZ2UodG9rZW46IEVycm9yTWVzc2FnZVRva2VuKSB7XG4gICAgdGhpcy5jb25uZWN0aW9uLmVtaXQoJ2Vycm9yTWVzc2FnZScsIHRva2VuKTtcbiAgfVxuXG4gIG9uRGF0YWJhc2VDaGFuZ2UodG9rZW46IERhdGFiYXNlRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24uZW1pdCgnZGF0YWJhc2VDaGFuZ2UnLCB0b2tlbi5uZXdWYWx1ZSk7XG4gIH1cblxuICBvbkxhbmd1YWdlQ2hhbmdlKHRva2VuOiBMYW5ndWFnZUVudkNoYW5nZVRva2VuKSB7XG4gICAgdGhpcy5jb25uZWN0aW9uLmVtaXQoJ2xhbmd1YWdlQ2hhbmdlJywgdG9rZW4ubmV3VmFsdWUpO1xuICB9XG5cbiAgb25DaGFyc2V0Q2hhbmdlKHRva2VuOiBDaGFyc2V0RW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24uZW1pdCgnY2hhcnNldENoYW5nZScsIHRva2VuLm5ld1ZhbHVlKTtcbiAgfVxuXG4gIG9uU3FsQ29sbGF0aW9uQ2hhbmdlKHRva2VuOiBDb2xsYXRpb25DaGFuZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5kYXRhYmFzZUNvbGxhdGlvbiA9IHRva2VuLm5ld1ZhbHVlO1xuICB9XG5cbiAgb25QYWNrZXRTaXplQ2hhbmdlKHRva2VuOiBQYWNrZXRTaXplRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24ubWVzc2FnZUlvLnBhY2tldFNpemUodG9rZW4ubmV3VmFsdWUpO1xuICB9XG5cbiAgb25CZWdpblRyYW5zYWN0aW9uKHRva2VuOiBCZWdpblRyYW5zYWN0aW9uRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24udHJhbnNhY3Rpb25EZXNjcmlwdG9ycy5wdXNoKHRva2VuLm5ld1ZhbHVlKTtcbiAgICB0aGlzLmNvbm5lY3Rpb24uaW5UcmFuc2FjdGlvbiA9IHRydWU7XG4gIH1cblxuICBvbkNvbW1pdFRyYW5zYWN0aW9uKHRva2VuOiBDb21taXRUcmFuc2FjdGlvbkVudkNoYW5nZVRva2VuKSB7XG4gICAgdGhpcy5jb25uZWN0aW9uLnRyYW5zYWN0aW9uRGVzY3JpcHRvcnMubGVuZ3RoID0gMTtcbiAgICB0aGlzLmNvbm5lY3Rpb24uaW5UcmFuc2FjdGlvbiA9IGZhbHNlO1xuICB9XG5cbiAgb25Sb2xsYmFja1RyYW5zYWN0aW9uKHRva2VuOiBSb2xsYmFja1RyYW5zYWN0aW9uRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24udHJhbnNhY3Rpb25EZXNjcmlwdG9ycy5sZW5ndGggPSAxO1xuICAgIC8vIEFuIG91dGVybW9zdCB0cmFuc2FjdGlvbiB3YXMgcm9sbGVkIGJhY2suIFJlc2V0IHRoZSB0cmFuc2FjdGlvbiBjb3VudGVyXG4gICAgdGhpcy5jb25uZWN0aW9uLmluVHJhbnNhY3Rpb24gPSBmYWxzZTtcbiAgICB0aGlzLmNvbm5lY3Rpb24uZW1pdCgncm9sbGJhY2tUcmFuc2FjdGlvbicpO1xuICB9XG5cbiAgb25Db2xNZXRhZGF0YSh0b2tlbjogQ29sTWV0YWRhdGFUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcihcIlJlY2VpdmVkICdjb2x1bW5NZXRhZGF0YScgd2hlbiBubyBzcWxSZXF1ZXN0IGlzIGluIHByb2dyZXNzXCIpKTtcbiAgICB0aGlzLmNvbm5lY3Rpb24uY2xvc2UoKTtcbiAgfVxuXG4gIG9uT3JkZXIodG9rZW46IE9yZGVyVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24uZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoXCJSZWNlaXZlZCAnb3JkZXInIHdoZW4gbm8gc3FsUmVxdWVzdCBpcyBpbiBwcm9ncmVzc1wiKSk7XG4gICAgdGhpcy5jb25uZWN0aW9uLmNsb3NlKCk7XG4gIH1cblxuICBvblJvdyh0b2tlbjogUm93VG9rZW4gfCBOQkNSb3dUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcihcIlJlY2VpdmVkICdyb3cnIHdoZW4gbm8gc3FsUmVxdWVzdCBpcyBpbiBwcm9ncmVzc1wiKSk7XG4gICAgdGhpcy5jb25uZWN0aW9uLmNsb3NlKCk7XG4gIH1cblxuICBvblJldHVyblN0YXR1cyh0b2tlbjogUmV0dXJuU3RhdHVzVG9rZW4pIHtcbiAgICAvLyBEbyBub3RoaW5nXG4gIH1cblxuICBvblJldHVyblZhbHVlKHRva2VuOiBSZXR1cm5WYWx1ZVRva2VuKSB7XG4gICAgLy8gRG8gbm90aGluZ1xuICB9XG5cbiAgb25Eb25lUHJvYyh0b2tlbjogRG9uZVByb2NUb2tlbikge1xuICAgIC8vIERvIG5vdGhpbmdcbiAgfVxuXG4gIG9uRG9uZUluUHJvYyh0b2tlbjogRG9uZUluUHJvY1Rva2VuKSB7XG4gICAgLy8gRG8gbm90aGluZ1xuICB9XG5cbiAgb25Eb25lKHRva2VuOiBEb25lVG9rZW4pIHtcbiAgICAvLyBEbyBub3RoaW5nXG4gIH1cblxuICBvblJlc2V0Q29ubmVjdGlvbih0b2tlbjogUmVzZXRDb25uZWN0aW9uRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24uZW1pdCgncmVzZXRDb25uZWN0aW9uJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGhhbmRsZXIgZm9yIHRva2VucyByZWNlaXZlZCBpbiB0aGUgcmVzcG9uc2UgbWVzc2FnZSB0byBhIExvZ2luNyBtZXNzYWdlLlxuICovXG5leHBvcnQgY2xhc3MgTG9naW43VG9rZW5IYW5kbGVyIGV4dGVuZHMgVG9rZW5IYW5kbGVyIHtcbiAgZGVjbGFyZSBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gIGRlY2xhcmUgZmVkQXV0aEluZm9Ub2tlbjogRmVkQXV0aEluZm9Ub2tlbiB8IHVuZGVmaW5lZDtcbiAgZGVjbGFyZSByb3V0aW5nRGF0YTogeyBzZXJ2ZXI6IHN0cmluZywgcG9ydDogbnVtYmVyLCBpbnN0YW5jZTogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG5cbiAgZGVjbGFyZSBsb2dpbkFja1JlY2VpdmVkOiBib29sZWFuO1xuXG4gIGRlY2xhcmUgbG9naW5FcnJvcjogQ29ubmVjdGlvbkVycm9yIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMubG9naW5BY2tSZWNlaXZlZCA9IGZhbHNlO1xuICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgdGhpcy5sb2dpbkVycm9yID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgb25JbmZvTWVzc2FnZSh0b2tlbjogSW5mb01lc3NhZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5lbWl0KCdpbmZvTWVzc2FnZScsIHRva2VuKTtcbiAgfVxuXG4gIG9uRXJyb3JNZXNzYWdlKHRva2VuOiBFcnJvck1lc3NhZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5lbWl0KCdlcnJvck1lc3NhZ2UnLCB0b2tlbik7XG5cbiAgICBjb25zdCBlcnJvciA9IG5ldyBDb25uZWN0aW9uRXJyb3IodG9rZW4ubWVzc2FnZSwgJ0VMT0dJTicpO1xuXG4gICAgY29uc3QgaXNMb2dpbkVycm9yVHJhbnNpZW50ID0gdGhpcy5jb25uZWN0aW9uLnRyYW5zaWVudEVycm9yTG9va3VwLmlzVHJhbnNpZW50RXJyb3IodG9rZW4ubnVtYmVyKTtcbiAgICBpZiAoaXNMb2dpbkVycm9yVHJhbnNpZW50ICYmIHRoaXMuY29ubmVjdGlvbi5jdXJUcmFuc2llbnRSZXRyeUNvdW50ICE9PSB0aGlzLmNvbm5lY3Rpb24uY29uZmlnLm9wdGlvbnMubWF4UmV0cmllc09uVHJhbnNpZW50RXJyb3JzKSB7XG4gICAgICBlcnJvci5pc1RyYW5zaWVudCA9IHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy5sb2dpbkVycm9yID0gZXJyb3I7XG4gIH1cblxuICBvblNTUEkodG9rZW46IFNTUElUb2tlbikge1xuICAgIGlmICh0b2tlbi5udGxtcGFja2V0KSB7XG4gICAgICB0aGlzLmNvbm5lY3Rpb24ubnRsbXBhY2tldCA9IHRva2VuLm50bG1wYWNrZXQ7XG4gICAgICB0aGlzLmNvbm5lY3Rpb24ubnRsbXBhY2tldEJ1ZmZlciA9IHRva2VuLm50bG1wYWNrZXRCdWZmZXI7XG4gICAgfVxuICB9XG5cbiAgb25EYXRhYmFzZUNoYW5nZSh0b2tlbjogRGF0YWJhc2VFbnZDaGFuZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5lbWl0KCdkYXRhYmFzZUNoYW5nZScsIHRva2VuLm5ld1ZhbHVlKTtcbiAgfVxuXG4gIG9uRGF0YWJhc2VNaXJyb3JpbmdQYXJ0bmVyKHRva2VuOiBEYXRhYmFzZU1pcnJvcmluZ1BhcnRuZXJFbnZDaGFuZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5lbWl0KCdkYXRhYmFzZU1pcnJvcmluZ1BhcnRuZXInLCB0b2tlbi5uZXdWYWx1ZSk7XG4gIH1cblxuICBvbkxhbmd1YWdlQ2hhbmdlKHRva2VuOiBMYW5ndWFnZUVudkNoYW5nZVRva2VuKSB7XG4gICAgdGhpcy5jb25uZWN0aW9uLmVtaXQoJ2xhbmd1YWdlQ2hhbmdlJywgdG9rZW4ubmV3VmFsdWUpO1xuICB9XG5cbiAgb25DaGFyc2V0Q2hhbmdlKHRva2VuOiBDaGFyc2V0RW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24uZW1pdCgnY2hhcnNldENoYW5nZScsIHRva2VuLm5ld1ZhbHVlKTtcbiAgfVxuXG4gIG9uU3FsQ29sbGF0aW9uQ2hhbmdlKHRva2VuOiBDb2xsYXRpb25DaGFuZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5kYXRhYmFzZUNvbGxhdGlvbiA9IHRva2VuLm5ld1ZhbHVlO1xuICB9XG5cbiAgb25GZWRBdXRoSW5mbyh0b2tlbjogRmVkQXV0aEluZm9Ub2tlbikge1xuICAgIHRoaXMuZmVkQXV0aEluZm9Ub2tlbiA9IHRva2VuO1xuICB9XG5cbiAgb25GZWF0dXJlRXh0QWNrKHRva2VuOiBGZWF0dXJlRXh0QWNrVG9rZW4pIHtcbiAgICBjb25zdCB7IGF1dGhlbnRpY2F0aW9uIH0gPSB0aGlzLmNvbm5lY3Rpb24uY29uZmlnO1xuXG4gICAgaWYgKGF1dGhlbnRpY2F0aW9uLnR5cGUgPT09ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LXBhc3N3b3JkJyB8fCBhdXRoZW50aWNhdGlvbi50eXBlID09PSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1hY2Nlc3MtdG9rZW4nIHx8IGF1dGhlbnRpY2F0aW9uLnR5cGUgPT09ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LW1zaS12bScgfHwgYXV0aGVudGljYXRpb24udHlwZSA9PT0gJ2F6dXJlLWFjdGl2ZS1kaXJlY3RvcnktbXNpLWFwcC1zZXJ2aWNlJyB8fCBhdXRoZW50aWNhdGlvbi50eXBlID09PSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1zZXJ2aWNlLXByaW5jaXBhbC1zZWNyZXQnIHx8IGF1dGhlbnRpY2F0aW9uLnR5cGUgPT09ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LWRlZmF1bHQnKSB7XG4gICAgICBpZiAodG9rZW4uZmVkQXV0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMubG9naW5FcnJvciA9IG5ldyBDb25uZWN0aW9uRXJyb3IoJ0RpZCBub3QgcmVjZWl2ZSBBY3RpdmUgRGlyZWN0b3J5IGF1dGhlbnRpY2F0aW9uIGFja25vd2xlZGdlbWVudCcpO1xuICAgICAgfSBlbHNlIGlmICh0b2tlbi5mZWRBdXRoLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICB0aGlzLmxvZ2luRXJyb3IgPSBuZXcgQ29ubmVjdGlvbkVycm9yKGBBY3RpdmUgRGlyZWN0b3J5IGF1dGhlbnRpY2F0aW9uIGFja25vd2xlZGdtZW50IGZvciAke2F1dGhlbnRpY2F0aW9uLnR5cGV9IGF1dGhlbnRpY2F0aW9uIG1ldGhvZCBpbmNsdWRlcyBleHRyYSBkYXRhYCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0b2tlbi5mZWRBdXRoID09PSB1bmRlZmluZWQgJiYgdG9rZW4udXRmOFN1cHBvcnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2dpbkVycm9yID0gbmV3IENvbm5lY3Rpb25FcnJvcignUmVjZWl2ZWQgYWNrbm93bGVkZ2VtZW50IGZvciB1bmtub3duIGZlYXR1cmUnKTtcbiAgICB9IGVsc2UgaWYgKHRva2VuLmZlZEF1dGgpIHtcbiAgICAgIHRoaXMubG9naW5FcnJvciA9IG5ldyBDb25uZWN0aW9uRXJyb3IoJ0RpZCBub3QgcmVxdWVzdCBBY3RpdmUgRGlyZWN0b3J5IGF1dGhlbnRpY2F0aW9uLCBidXQgcmVjZWl2ZWQgdGhlIGFja25vd2xlZGdtZW50Jyk7XG4gICAgfVxuICB9XG5cbiAgb25Mb2dpbkFjayh0b2tlbjogTG9naW5BY2tUb2tlbikge1xuICAgIGlmICghdG9rZW4udGRzVmVyc2lvbikge1xuICAgICAgLy8gdW5zdXBwb3J0ZWQgVERTIHZlcnNpb25cbiAgICAgIHRoaXMubG9naW5FcnJvciA9IG5ldyBDb25uZWN0aW9uRXJyb3IoJ1NlcnZlciByZXNwb25kZWQgd2l0aCB1bmtub3duIFREUyB2ZXJzaW9uLicsICdFVERTJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCF0b2tlbi5pbnRlcmZhY2UpIHtcbiAgICAgIC8vIHVuc3VwcG9ydGVkIGludGVyZmFjZVxuICAgICAgdGhpcy5sb2dpbkVycm9yID0gbmV3IENvbm5lY3Rpb25FcnJvcignU2VydmVyIHJlc3BvbmRlZCB3aXRoIHVuc3VwcG9ydGVkIGludGVyZmFjZS4nLCAnRUlOVEVSRkFDRU5PVFNVUFAnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB1c2UgbmVnb3RpYXRlZCB2ZXJzaW9uXG4gICAgdGhpcy5jb25uZWN0aW9uLmNvbmZpZy5vcHRpb25zLnRkc1ZlcnNpb24gPSB0b2tlbi50ZHNWZXJzaW9uO1xuXG4gICAgaWYgKHRva2VuLnRkc1ZlcnNpb24gPCAnN18yJykge1xuICAgICAgdGRzNzFEZXByZWNhdGlvbldhcm5pbmcuZW1pdCgpO1xuICAgIH1cblxuICAgIHRoaXMubG9naW5BY2tSZWNlaXZlZCA9IHRydWU7XG4gIH1cblxuICBvblJvdXRpbmdDaGFuZ2UodG9rZW46IFJvdXRpbmdFbnZDaGFuZ2VUb2tlbikge1xuICAgIC8vIFNwbGl0cyBpbnN0YW5jZSBuYW1lIGF0dGFjaGVkIHRvIHRoZSByZWRpcmVjdCB1cmwuIEUuZy4sIHJlZGlyZWN0LmRiLm5ldFxcaW5zdGFuY2UxIC0tPiBbcmVkaXJlY3QuZGIubmV0LCBpbnN0YW5jZTFdXG4gICAgY29uc3QgWyBzZXJ2ZXIsIGluc3RhbmNlIF0gPSB0b2tlbi5uZXdWYWx1ZS5zZXJ2ZXIuc3BsaXQoJ1xcXFwnKTtcblxuICAgIHRoaXMucm91dGluZ0RhdGEgPSB7XG4gICAgICBzZXJ2ZXIsIHBvcnQ6IHRva2VuLm5ld1ZhbHVlLnBvcnQsIGluc3RhbmNlXG4gICAgfTtcbiAgfVxuXG4gIG9uRG9uZUluUHJvYyh0b2tlbjogRG9uZUluUHJvY1Rva2VuKSB7XG4gICAgLy8gRG8gbm90aGluZ1xuICB9XG5cbiAgb25Eb25lKHRva2VuOiBEb25lVG9rZW4pIHtcbiAgICAvLyBEbyBub3RoaW5nXG4gIH1cblxuICBvblBhY2tldFNpemVDaGFuZ2UodG9rZW46IFBhY2tldFNpemVFbnZDaGFuZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5tZXNzYWdlSW8ucGFja2V0U2l6ZSh0b2tlbi5uZXdWYWx1ZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGhhbmRsZXIgZm9yIHRva2VucyByZWNlaXZlZCBpbiB0aGUgcmVzcG9uc2UgbWVzc2FnZSB0byBhIFJQQyBSZXF1ZXN0LFxuICogYSBTUUwgQmF0Y2ggUmVxdWVzdCwgYSBCdWxrIExvYWQgQkNQIFJlcXVlc3Qgb3IgYSBUcmFuc2FjdGlvbiBNYW5hZ2VyIFJlcXVlc3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXF1ZXN0VG9rZW5IYW5kbGVyIGV4dGVuZHMgVG9rZW5IYW5kbGVyIHtcbiAgZGVjbGFyZSBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICBkZWNsYXJlIHJlcXVlc3Q6IFJlcXVlc3QgfCBCdWxrTG9hZDtcbiAgZGVjbGFyZSBlcnJvcnM6IFJlcXVlc3RFcnJvcltdO1xuXG4gIGNvbnN0cnVjdG9yKGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHJlcXVlc3Q6IFJlcXVlc3QgfCBCdWxrTG9hZCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgdGhpcy5lcnJvcnMgPSBbXTtcbiAgfVxuXG4gIG9uSW5mb01lc3NhZ2UodG9rZW46IEluZm9NZXNzYWdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24uZW1pdCgnaW5mb01lc3NhZ2UnLCB0b2tlbik7XG4gIH1cblxuICBvbkVycm9yTWVzc2FnZSh0b2tlbjogRXJyb3JNZXNzYWdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24uZW1pdCgnZXJyb3JNZXNzYWdlJywgdG9rZW4pO1xuXG4gICAgaWYgKCF0aGlzLnJlcXVlc3QuY2FuY2VsZWQpIHtcbiAgICAgIGNvbnN0IGVycm9yID0gbmV3IFJlcXVlc3RFcnJvcih0b2tlbi5tZXNzYWdlLCAnRVJFUVVFU1QnKTtcblxuICAgICAgZXJyb3IubnVtYmVyID0gdG9rZW4ubnVtYmVyO1xuICAgICAgZXJyb3Iuc3RhdGUgPSB0b2tlbi5zdGF0ZTtcbiAgICAgIGVycm9yLmNsYXNzID0gdG9rZW4uY2xhc3M7XG4gICAgICBlcnJvci5zZXJ2ZXJOYW1lID0gdG9rZW4uc2VydmVyTmFtZTtcbiAgICAgIGVycm9yLnByb2NOYW1lID0gdG9rZW4ucHJvY05hbWU7XG4gICAgICBlcnJvci5saW5lTnVtYmVyID0gdG9rZW4ubGluZU51bWJlcjtcbiAgICAgIHRoaXMuZXJyb3JzLnB1c2goZXJyb3IpO1xuICAgICAgdGhpcy5yZXF1ZXN0LmVycm9yID0gZXJyb3I7XG4gICAgICBpZiAodGhpcy5yZXF1ZXN0IGluc3RhbmNlb2YgUmVxdWVzdCAmJiB0aGlzLmVycm9ycy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHRoaXMucmVxdWVzdC5lcnJvciA9IG5ldyBBZ2dyZWdhdGVFcnJvcih0aGlzLmVycm9ycyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25EYXRhYmFzZUNoYW5nZSh0b2tlbjogRGF0YWJhc2VFbnZDaGFuZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5lbWl0KCdkYXRhYmFzZUNoYW5nZScsIHRva2VuLm5ld1ZhbHVlKTtcbiAgfVxuXG4gIG9uTGFuZ3VhZ2VDaGFuZ2UodG9rZW46IExhbmd1YWdlRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24uZW1pdCgnbGFuZ3VhZ2VDaGFuZ2UnLCB0b2tlbi5uZXdWYWx1ZSk7XG4gIH1cblxuICBvbkNoYXJzZXRDaGFuZ2UodG9rZW46IENoYXJzZXRFbnZDaGFuZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5lbWl0KCdjaGFyc2V0Q2hhbmdlJywgdG9rZW4ubmV3VmFsdWUpO1xuICB9XG5cbiAgb25TcWxDb2xsYXRpb25DaGFuZ2UodG9rZW46IENvbGxhdGlvbkNoYW5nZVRva2VuKSB7XG4gICAgdGhpcy5jb25uZWN0aW9uLmRhdGFiYXNlQ29sbGF0aW9uID0gdG9rZW4ubmV3VmFsdWU7XG4gIH1cblxuICBvblBhY2tldFNpemVDaGFuZ2UodG9rZW46IFBhY2tldFNpemVFbnZDaGFuZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi5tZXNzYWdlSW8ucGFja2V0U2l6ZSh0b2tlbi5uZXdWYWx1ZSk7XG4gIH1cblxuICBvbkJlZ2luVHJhbnNhY3Rpb24odG9rZW46IEJlZ2luVHJhbnNhY3Rpb25FbnZDaGFuZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi50cmFuc2FjdGlvbkRlc2NyaXB0b3JzLnB1c2godG9rZW4ubmV3VmFsdWUpO1xuICAgIHRoaXMuY29ubmVjdGlvbi5pblRyYW5zYWN0aW9uID0gdHJ1ZTtcbiAgfVxuXG4gIG9uQ29tbWl0VHJhbnNhY3Rpb24odG9rZW46IENvbW1pdFRyYW5zYWN0aW9uRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24udHJhbnNhY3Rpb25EZXNjcmlwdG9ycy5sZW5ndGggPSAxO1xuICAgIHRoaXMuY29ubmVjdGlvbi5pblRyYW5zYWN0aW9uID0gZmFsc2U7XG4gIH1cblxuICBvblJvbGxiYWNrVHJhbnNhY3Rpb24odG9rZW46IFJvbGxiYWNrVHJhbnNhY3Rpb25FbnZDaGFuZ2VUb2tlbikge1xuICAgIHRoaXMuY29ubmVjdGlvbi50cmFuc2FjdGlvbkRlc2NyaXB0b3JzLmxlbmd0aCA9IDE7XG4gICAgLy8gQW4gb3V0ZXJtb3N0IHRyYW5zYWN0aW9uIHdhcyByb2xsZWQgYmFjay4gUmVzZXQgdGhlIHRyYW5zYWN0aW9uIGNvdW50ZXJcbiAgICB0aGlzLmNvbm5lY3Rpb24uaW5UcmFuc2FjdGlvbiA9IGZhbHNlO1xuICAgIHRoaXMuY29ubmVjdGlvbi5lbWl0KCdyb2xsYmFja1RyYW5zYWN0aW9uJyk7XG4gIH1cblxuICBvbkNvbE1ldGFkYXRhKHRva2VuOiBDb2xNZXRhZGF0YVRva2VuKSB7XG4gICAgaWYgKCF0aGlzLnJlcXVlc3QuY2FuY2VsZWQpIHtcbiAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb24uY29uZmlnLm9wdGlvbnMudXNlQ29sdW1uTmFtZXMpIHtcbiAgICAgICAgY29uc3QgY29sdW1uczogeyBba2V5OiBzdHJpbmddOiBDb2x1bW5NZXRhZGF0YSB9ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAgICAgICBmb3IgKGxldCBqID0gMCwgbGVuID0gdG9rZW4uY29sdW1ucy5sZW5ndGg7IGogPCBsZW47IGorKykge1xuICAgICAgICAgIGNvbnN0IGNvbCA9IHRva2VuLmNvbHVtbnNbal07XG4gICAgICAgICAgaWYgKGNvbHVtbnNbY29sLmNvbE5hbWVdID09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbHVtbnNbY29sLmNvbE5hbWVdID0gY29sO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVxdWVzdC5lbWl0KCdjb2x1bW5NZXRhZGF0YScsIGNvbHVtbnMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZXF1ZXN0LmVtaXQoJ2NvbHVtbk1ldGFkYXRhJywgdG9rZW4uY29sdW1ucyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25UYWJOYW1lKHRva2VuOiBUYWJOYW1lVG9rZW4pIHtcbiAgICBpZiAoIXRoaXMucmVxdWVzdC5jYW5jZWxlZCkge1xuICAgICAgdGhpcy5yZXF1ZXN0LmVtaXQoJ3RhYk5hbWUnLCB0b2tlbi50YWJsZU5hbWVzKTtcbiAgICB9XG4gIH1cblxuICBvbkNvbEluZm8odG9rZW46IENvbEluZm9Ub2tlbikge1xuICAgIGlmICghdGhpcy5yZXF1ZXN0LmNhbmNlbGVkKSB7XG4gICAgICB0aGlzLnJlcXVlc3QuZW1pdCgnY29sSW5mbycsIHRva2VuLmNvbHVtbnMpO1xuICAgIH1cbiAgfVxuXG4gIG9uT3JkZXIodG9rZW46IE9yZGVyVG9rZW4pIHtcbiAgICBpZiAoIXRoaXMucmVxdWVzdC5jYW5jZWxlZCkge1xuICAgICAgdGhpcy5yZXF1ZXN0LmVtaXQoJ29yZGVyJywgdG9rZW4ub3JkZXJDb2x1bW5zKTtcbiAgICB9XG4gIH1cblxuICBvblJvdyh0b2tlbjogUm93VG9rZW4gfCBOQkNSb3dUb2tlbikge1xuICAgIGlmICghdGhpcy5yZXF1ZXN0LmNhbmNlbGVkKSB7XG4gICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbmZpZy5vcHRpb25zLnJvd0NvbGxlY3Rpb25PblJlcXVlc3RDb21wbGV0aW9uKSB7XG4gICAgICAgIHRoaXMucmVxdWVzdC5yb3dzIS5wdXNoKHRva2VuLmNvbHVtbnMpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbmZpZy5vcHRpb25zLnJvd0NvbGxlY3Rpb25PbkRvbmUpIHtcbiAgICAgICAgdGhpcy5yZXF1ZXN0LnJzdCEucHVzaCh0b2tlbi5jb2x1bW5zKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5yZXF1ZXN0LmVtaXQoJ3JvdycsIHRva2VuLmNvbHVtbnMpO1xuICAgIH1cbiAgfVxuXG4gIG9uUmV0dXJuU3RhdHVzKHRva2VuOiBSZXR1cm5TdGF0dXNUb2tlbikge1xuICAgIGlmICghdGhpcy5yZXF1ZXN0LmNhbmNlbGVkKSB7XG4gICAgICAvLyBLZWVwIHZhbHVlIGZvciBwYXNzaW5nIGluICdkb25lUHJvYycgZXZlbnQuXG4gICAgICB0aGlzLmNvbm5lY3Rpb24ucHJvY1JldHVyblN0YXR1c1ZhbHVlID0gdG9rZW4udmFsdWU7XG4gICAgfVxuICB9XG5cbiAgb25SZXR1cm5WYWx1ZSh0b2tlbjogUmV0dXJuVmFsdWVUb2tlbikge1xuICAgIGlmICghdGhpcy5yZXF1ZXN0LmNhbmNlbGVkKSB7XG4gICAgICAvLyBUaGUgcmVzcG9uc2UgdG8gYHNwX3ByZXBhcmVgIHJldHVybnMgdGhlIHByZXBhcmVkIHN0YXRlbWVudCdzIGhhbmRsZS5cbiAgICAgIGlmICh0aGlzLnJlcXVlc3QgaW5zdGFuY2VvZiBSZXF1ZXN0ICYmIHRoaXMucmVxdWVzdC5wcmVwYXJpbmcpIHtcbiAgICAgICAgaWYgKHRva2VuLnBhcmFtTmFtZSA9PT0gJ2hhbmRsZScpIHtcbiAgICAgICAgICB0aGlzLnJlcXVlc3QuaGFuZGxlID0gdG9rZW4udmFsdWUgYXMgbnVtYmVyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucmVxdWVzdC5lcnJvciA9IG5ldyBSZXF1ZXN0RXJyb3IoYFRlZGlvdXMgPiBVbmV4cGVjdGVkIG91dHB1dCBwYXJhbWV0ZXIgJHt0b2tlbi5wYXJhbU5hbWV9IGZyb20gc3BfcHJlcGFyZWApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMucmVxdWVzdC5lbWl0KCdyZXR1cm5WYWx1ZScsIHRva2VuLnBhcmFtTmFtZSwgdG9rZW4udmFsdWUsIHRva2VuLm1ldGFkYXRhKTtcbiAgICB9XG4gIH1cblxuICBvbkRvbmVQcm9jKHRva2VuOiBEb25lUHJvY1Rva2VuKSB7XG4gICAgaWYgKCF0aGlzLnJlcXVlc3QuY2FuY2VsZWQpIHtcbiAgICAgIGlmICh0b2tlbi5zcWxFcnJvciAmJiAhdGhpcy5yZXF1ZXN0LmVycm9yKSB7XG4gICAgICAgIC8vIGNoZWNrIGlmIHRoZSBET05FX0VSUk9SIGZsYWdzIHdhcyBzZXQsIGJ1dCBhbiBFUlJPUiB0b2tlbiB3YXMgbm90IHNlbnQuXG4gICAgICAgIHRoaXMucmVxdWVzdC5lcnJvciA9IG5ldyBSZXF1ZXN0RXJyb3IoJ0FuIHVua25vd24gZXJyb3IgaGFzIG9jY3VycmVkLicsICdVTktOT1dOJyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMucmVxdWVzdC5lbWl0KCdkb25lUHJvYycsIHRva2VuLnJvd0NvdW50LCB0b2tlbi5tb3JlLCB0aGlzLmNvbm5lY3Rpb24ucHJvY1JldHVyblN0YXR1c1ZhbHVlLCB0aGlzLnJlcXVlc3QucnN0KTtcblxuICAgICAgdGhpcy5jb25uZWN0aW9uLnByb2NSZXR1cm5TdGF0dXNWYWx1ZSA9IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKHRva2VuLnJvd0NvdW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5yZXF1ZXN0LnJvd0NvdW50ISArPSB0b2tlbi5yb3dDb3VudDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuY29ubmVjdGlvbi5jb25maWcub3B0aW9ucy5yb3dDb2xsZWN0aW9uT25Eb25lKSB7XG4gICAgICAgIHRoaXMucmVxdWVzdC5yc3QgPSBbXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvbkRvbmVJblByb2ModG9rZW46IERvbmVJblByb2NUb2tlbikge1xuICAgIGlmICghdGhpcy5yZXF1ZXN0LmNhbmNlbGVkKSB7XG4gICAgICB0aGlzLnJlcXVlc3QuZW1pdCgnZG9uZUluUHJvYycsIHRva2VuLnJvd0NvdW50LCB0b2tlbi5tb3JlLCB0aGlzLnJlcXVlc3QucnN0KTtcblxuICAgICAgaWYgKHRva2VuLnJvd0NvdW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5yZXF1ZXN0LnJvd0NvdW50ISArPSB0b2tlbi5yb3dDb3VudDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuY29ubmVjdGlvbi5jb25maWcub3B0aW9ucy5yb3dDb2xsZWN0aW9uT25Eb25lKSB7XG4gICAgICAgIHRoaXMucmVxdWVzdC5yc3QgPSBbXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvbkRvbmUodG9rZW46IERvbmVUb2tlbikge1xuICAgIGlmICghdGhpcy5yZXF1ZXN0LmNhbmNlbGVkKSB7XG4gICAgICBpZiAodG9rZW4uc3FsRXJyb3IgJiYgIXRoaXMucmVxdWVzdC5lcnJvcikge1xuICAgICAgICAvLyBjaGVjayBpZiB0aGUgRE9ORV9FUlJPUiBmbGFncyB3YXMgc2V0LCBidXQgYW4gRVJST1IgdG9rZW4gd2FzIG5vdCBzZW50LlxuICAgICAgICB0aGlzLnJlcXVlc3QuZXJyb3IgPSBuZXcgUmVxdWVzdEVycm9yKCdBbiB1bmtub3duIGVycm9yIGhhcyBvY2N1cnJlZC4nLCAnVU5LTk9XTicpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnJlcXVlc3QuZW1pdCgnZG9uZScsIHRva2VuLnJvd0NvdW50LCB0b2tlbi5tb3JlLCB0aGlzLnJlcXVlc3QucnN0KTtcblxuICAgICAgaWYgKHRva2VuLnJvd0NvdW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5yZXF1ZXN0LnJvd0NvdW50ISArPSB0b2tlbi5yb3dDb3VudDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuY29ubmVjdGlvbi5jb25maWcub3B0aW9ucy5yb3dDb2xsZWN0aW9uT25Eb25lKSB7XG4gICAgICAgIHRoaXMucmVxdWVzdC5yc3QgPSBbXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvblJlc2V0Q29ubmVjdGlvbih0b2tlbjogUmVzZXRDb25uZWN0aW9uRW52Q2hhbmdlVG9rZW4pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24uZW1pdCgncmVzZXRDb25uZWN0aW9uJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGhhbmRsZXIgZm9yIHRoZSBhdHRlbnRpb24gYWNrbm93bGVkZ2VtZW50IG1lc3NhZ2UuXG4gKlxuICogVGhpcyBtZXNzYWdlIG9ubHkgY29udGFpbnMgYSBgRE9ORWAgdG9rZW4gdGhhdCBhY2tub3dsZWRnZXNcbiAqIHRoYXQgdGhlIGF0dGVudGlvbiBtZXNzYWdlIHdhcyByZWNlaXZlZCBieSB0aGUgc2VydmVyLlxuICovXG5leHBvcnQgY2xhc3MgQXR0ZW50aW9uVG9rZW5IYW5kbGVyIGV4dGVuZHMgVG9rZW5IYW5kbGVyIHtcbiAgZGVjbGFyZSBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICBkZWNsYXJlIHJlcXVlc3Q6IFJlcXVlc3QgfCBCdWxrTG9hZDtcblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyIGFuIGF0dGVudGlvbiBhY2tub3dsZWRnZW1lbnQgd2FzIHJlY2VpdmVkLlxuICAgKi9cbiAgZGVjbGFyZSBhdHRlbnRpb25SZWNlaXZlZDogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3Rvcihjb25uZWN0aW9uOiBDb25uZWN0aW9uLCByZXF1ZXN0OiBSZXF1ZXN0IHwgQnVsa0xvYWQpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuXG4gICAgdGhpcy5hdHRlbnRpb25SZWNlaXZlZCA9IGZhbHNlO1xuICB9XG5cbiAgb25Eb25lKHRva2VuOiBEb25lVG9rZW4pIHtcbiAgICBpZiAodG9rZW4uYXR0ZW50aW9uKSB7XG4gICAgICB0aGlzLmF0dGVudGlvblJlY2VpdmVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQ0EsSUFBQUEsUUFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsT0FBQSxHQUFBRCxPQUFBO0FBQTBELFNBQUFELHVCQUFBRyxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBbUNuRCxNQUFNRyxvQkFBb0IsU0FBU0MsS0FBSyxDQUFDO0VBQzlDQyxXQUFXQSxDQUFDQyxPQUFxQixFQUFFQyxLQUFZLEVBQUU7SUFDL0MsS0FBSyxDQUFDLG9CQUFvQixHQUFHQSxLQUFLLENBQUNDLElBQUksR0FBRyxRQUFRLEdBQUdGLE9BQU8sQ0FBQ0QsV0FBVyxDQUFDRyxJQUFJLEdBQUcsR0FBRyxDQUFDO0VBQ3RGO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEFDLE9BQUEsQ0FBQU4sb0JBQUEsR0FBQUEsb0JBQUE7QUFNTyxNQUFNTyx1QkFBdUIsR0FBQUQsT0FBQSxDQUFBQyx1QkFBQSxHQUFHO0VBQ3JDQyxPQUFP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