diff --git a/dist/client.js b/dist/client.js index b942e5a..81d63b8 100644 --- a/dist/client.js +++ b/dist/client.js @@ -14,16 +14,6 @@ var _emailjsTcpSocket2 = _interopRequireDefault(_emailjsTcpSocket); var _textEncoding = require('text-encoding'); -var _parser = require('./parser'); - -var _parser2 = _interopRequireDefault(_parser); - -var _logger = require('./logger'); - -var _logger2 = _interopRequireDefault(_logger); - -var _common = require('./common'); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -62,6 +52,7 @@ var SmtpClient = function () { * @param {Object} [options.auth] Authentication options. Depends on the preferred authentication method. Usually {user, pass} * @param {String} [options.authMethod] Force specific authentication method * @param {Boolean} [options.disableEscaping] If set to true, do not escape dots on the beginning of the lines + * @param {Boolean} [options.logger] A winston-compatible logger */ function SmtpClient(host, port) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; @@ -91,20 +82,25 @@ var SmtpClient = function () { // Private properties - this._parser = new _parser2.default(); // SMTP response parser object. All data coming from the downstream server is feeded to this parser this._authenticatedAs = null; // If authenticated successfully, stores the username this._supportedAuth = []; // A list of authentication mechanisms detected from the EHLO response and which are compatible with this library this._dataMode = false; // If true, accepts data from the upstream to be passed directly to the downstream socket. Used after the DATA command this._lastDataBytes = ''; // Keep track of the last bytes to see how the terminating dot should be placed this._envelope = null; // Envelope object for tracking who is sending mail to whom this._currentAction = null; // Stores the function that should be run after a response has been received from the server + this._maxAllowedSize = 0; // Stores the max message size supported by the server as reported in the greeting this._secureMode = !!this.options.useSecureTransport; // Indicates if the connection is secured or plaintext this._socketTimeoutTimer = false; // Timer waiting to declare the socket dead starting from the last write this._socketTimeoutStart = false; // Start time of sending the first packet in data mode this._socketTimeoutPeriod = false; // Timeout for sending in data mode, gets extended with every send() - // Activate logging - this.createLogger(); + this._parseBlock = { data: [], statusCode: null }; + this._parseRemainder = ''; // If the complete line is not received yet, contains the beginning of it + + var dummyLogger = ['error', 'warning', 'info', 'debug'].reduce(function (o, l) { + o[l] = function () {};return o; + }, {}); + this.logger = options.logger || dummyLogger; // Event placeholders this.onerror = function (e) {}; // Will be run when an error occurs. The `onclose` event will fire subsequently. @@ -142,31 +138,6 @@ var SmtpClient = function () { this.socket.onopen = this._onOpen.bind(this); } - /** - * Pauses `data` events from the downstream SMTP server - */ - - }, { - key: 'suspend', - value: function suspend() { - if (this.socket && this.socket.readyState === 'open') { - this.socket.suspend(); - } - } - - /** - * Resumes `data` events from the downstream SMTP server. Be careful of not - * resuming something that is not suspended - an error is thrown in this case - */ - - }, { - key: 'resume', - value: function resume() { - if (this.socket && this.socket.readyState === 'open') { - this.socket.resume(); - } - } - /** * Sends QUIT */ @@ -179,21 +150,6 @@ var SmtpClient = function () { this._currentAction = this.close; } - /** - * Reset authentication - * - * @param {Object} [auth] Use this if you want to authenticate as another user - */ - - }, { - key: 'reset', - value: function reset(auth) { - this.options.auth = auth || this.options.auth; - this.logger.debug(DEBUG_TAG, 'Sending RSET...'); - this._sendCommand('RSET'); - this._currentAction = this._actionRSET; - } - /** * Closes the connection to the server */ @@ -303,6 +259,66 @@ var SmtpClient = function () { // PRIVATE METHODS + /** + * Queue some data from the server for parsing. + * + * @param {String} chunk Chunk of data received from the server + */ + + }, { + key: '_parse', + value: function _parse(chunk) { + // Lines should always end with but you never know, might be only as well + var lines = (this._parseRemainder + (chunk || '')).split(/\r?\n/); + this._parseRemainder = lines.pop(); // not sure if the line has completely arrived yet + + for (var i = 0, len = lines.length; i < len; i++) { + if (!lines[i].trim()) { + // nothing to check, empty line + continue; + } + + // possible input strings for the regex: + // 250-MULTILINE REPLY + // 250 LAST LINE OF REPLY + // 250 1.2.3 MESSAGE + + var match = lines[i].match(/^(\d{3})([- ])(?:(\d+\.\d+\.\d+)(?: ))?(.*)/); + + if (match) { + this._parseBlock.data.push(match[4]); + + if (match[2] === '-') { + // this is a multiline reply + this._parseBlock.statusCode = this._parseBlock.statusCode || Number(match[1]); + } else { + var statusCode = Number(match[1]) || 0; + var response = { + statusCode: statusCode, + data: this._parseBlock.data.join('\n'), + success: statusCode >= 200 && statusCode < 300 + }; + + this._onCommand(response); + this._parseBlock = { + data: [], + statusCode: null + }; + } + } else { + this._onCommand({ + success: false, + statusCode: this._parseBlock.statusCode || null, + data: [lines[i]].join('\n') + }); + this._parseBlock = { + data: [], + statusCode: null + }; + } + } + } + // EVENT HANDLERS FOR THE SOCKET /** @@ -325,8 +341,6 @@ var SmtpClient = function () { this.socket.onclose = this._onClose.bind(this); this.socket.ondrain = this._onDrain.bind(this); - this._parser.ondata = this._onCommand.bind(this); - this._currentAction = this._actionGreeting; } @@ -343,7 +357,7 @@ var SmtpClient = function () { clearTimeout(this._socketTimeoutTimer); var stringPayload = new _textEncoding.TextDecoder('UTF-8').decode(new Uint8Array(evt.data)); this.logger.debug(DEBUG_TAG, 'SERVER: ' + stringPayload); - this._parser.send(stringPayload); + this._parse(stringPayload); } /** @@ -578,7 +592,7 @@ var SmtpClient = function () { /** * Initial response from the server, must have a status 220 * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { @@ -605,7 +619,7 @@ var SmtpClient = function () { /** * Response to LHLO * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { @@ -624,7 +638,7 @@ var SmtpClient = function () { /** * Response to EHLO. If the response is an error, try HELO instead * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { @@ -641,39 +655,40 @@ var SmtpClient = function () { } // Try HELO instead - this.logger.warn(DEBUG_TAG, 'EHLO not successful, trying HELO ' + this.options.name); + this.logger.warning(DEBUG_TAG, 'EHLO not successful, trying HELO ' + this.options.name); this._currentAction = this._actionHELO; this._sendCommand('HELO ' + this.options.name); return; } // Detect if the server supports PLAIN auth - if (command.line.match(/AUTH(?:\s+[^\n]*\s+|\s+)PLAIN/i)) { + if (command.data.match(/AUTH(?:\s+[^\n]*\s+|\s+)PLAIN/i)) { this.logger.debug(DEBUG_TAG, 'Server supports AUTH PLAIN'); this._supportedAuth.push('PLAIN'); } // Detect if the server supports LOGIN auth - if (command.line.match(/AUTH(?:\s+[^\n]*\s+|\s+)LOGIN/i)) { + if (command.data.match(/AUTH(?:\s+[^\n]*\s+|\s+)LOGIN/i)) { this.logger.debug(DEBUG_TAG, 'Server supports AUTH LOGIN'); this._supportedAuth.push('LOGIN'); } // Detect if the server supports XOAUTH2 auth - if (command.line.match(/AUTH(?:\s+[^\n]*\s+|\s+)XOAUTH2/i)) { + if (command.data.match(/AUTH(?:\s+[^\n]*\s+|\s+)XOAUTH2/i)) { this.logger.debug(DEBUG_TAG, 'Server supports AUTH XOAUTH2'); this._supportedAuth.push('XOAUTH2'); } // Detect maximum allowed message size - if ((match = command.line.match(/SIZE (\d+)/i)) && Number(match[1])) { + if ((match = command.data.match(/SIZE (\d+)/i)) && Number(match[1])) { var maxAllowedSize = Number(match[1]); - this.logger.debug(DEBUG_TAG, 'Maximum allowd message size: ' + maxAllowedSize); + this._maxAllowedSize = maxAllowedSize; + this.logger.debug(DEBUG_TAG, 'Maximum allowed message size: ' + maxAllowedSize); } // Detect if the server supports STARTTLS if (!this._secureMode) { - if (command.line.match(/[ -]STARTTLS\s?$/mi) && !this.options.ignoreTLS || !!this.options.requireTLS) { + if (command.data.match(/STARTTLS\s?$/mi) && !this.options.ignoreTLS || !!this.options.requireTLS) { this._currentAction = this._actionSTARTTLS; this.logger.debug(DEBUG_TAG, 'Sending STARTTLS'); this._sendCommand('STARTTLS'); @@ -712,7 +727,7 @@ var SmtpClient = function () { /** * Response to HELO * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { @@ -729,7 +744,7 @@ var SmtpClient = function () { /** * Response to AUTH LOGIN, if successful expects base64 encoded username * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { @@ -748,7 +763,7 @@ var SmtpClient = function () { /** * Response to AUTH LOGIN username, if successful expects base64 encoded password * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { @@ -767,14 +782,14 @@ var SmtpClient = function () { /** * Response to AUTH XOAUTH2 token, if error occurs send empty response * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { key: '_actionAUTH_XOAUTH2', value: function _actionAUTH_XOAUTH2(command) { if (!command.success) { - this.logger.warn(DEBUG_TAG, 'Error during AUTH XOAUTH2, sending empty response'); + this.logger.warning(DEBUG_TAG, 'Error during AUTH XOAUTH2, sending empty response'); this._sendCommand(''); this._currentAction = this._actionAUTHComplete; } else { @@ -786,7 +801,7 @@ var SmtpClient = function () { * Checks if authentication succeeded or not. If successfully authenticated * emit `idle` to indicate that an e-mail can be sent using this connection * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { @@ -809,14 +824,14 @@ var SmtpClient = function () { /** * Used when the connection is idle and the server emits timeout * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { key: '_actionIdle', value: function _actionIdle(command) { if (command.statusCode > 300) { - this._onError(new Error(command.line)); + this._onError(new Error(command.data)); return; } @@ -826,7 +841,7 @@ var SmtpClient = function () { /** * Response to MAIL FROM command. Proceed to defining RCPT TO list if successful * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { @@ -854,14 +869,14 @@ var SmtpClient = function () { * as this might be related only to the current recipient, not a global error, so * the following recipients might still be valid * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { key: '_actionRCPT', value: function _actionRCPT(command) { if (!command.success) { - this.logger.warn(DEBUG_TAG, 'RCPT TO failed for: ' + this._envelope.curRecipient); + this.logger.warning(DEBUG_TAG, 'RCPT TO failed for: ' + this._envelope.curRecipient); // this is a soft error this._envelope.rcptFailed.push(this._envelope.curRecipient); } else { @@ -885,30 +900,10 @@ var SmtpClient = function () { } } - /** - * Response to the RSET command. If successful, clear the current authentication - * information and reauthenticate. - * - * @param {Object} command Parsed command from the server {statusCode, data, line} - */ - - }, { - key: '_actionRSET', - value: function _actionRSET(command) { - if (!command.success) { - this.logger.error(DEBUG_TAG, 'RSET unsuccessful ' + command.data); - this._onError(new Error(command.data)); - return; - } - - this._authenticatedAs = null; - this._authenticateUser(); - } - /** * Response to the DATA command. Server is now waiting for a message, so emit `onready` * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { @@ -931,7 +926,7 @@ var SmtpClient = function () { * Response from the server, once the message stream has ended with . * Emits `ondone`. * - * @param {Object} command Parsed command from the server {statusCode, data, line} + * @param {Object} command Parsed command from the server {statusCode, data} */ }, { @@ -995,58 +990,10 @@ var SmtpClient = function () { // base64("user={User}\x00auth=Bearer {Token}\x00\x00") return (0, _emailjsBase.encode)(authData.join('\x01')); } - }, { - key: 'createLogger', - value: function createLogger() { - var _this = this; - - var creator = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _logger2.default; - - var logger = creator((this.options.auth || {}).user || '', this.host); - this.logLevel = this.LOG_LEVEL_ALL; - this.logger = { - debug: function debug() { - for (var _len = arguments.length, msgs = Array(_len), _key = 0; _key < _len; _key++) { - msgs[_key] = arguments[_key]; - } - - if (_common.LOG_LEVEL_DEBUG >= _this.logLevel) { - logger.debug(msgs); - } - }, - info: function info() { - for (var _len2 = arguments.length, msgs = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - msgs[_key2] = arguments[_key2]; - } - - if (_common.LOG_LEVEL_INFO >= _this.logLevel) { - logger.info(msgs); - } - }, - warn: function warn() { - for (var _len3 = arguments.length, msgs = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { - msgs[_key3] = arguments[_key3]; - } - - if (_common.LOG_LEVEL_WARN >= _this.logLevel) { - logger.warn(msgs); - } - }, - error: function error() { - for (var _len4 = arguments.length, msgs = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { - msgs[_key4] = arguments[_key4]; - } - - if (_common.LOG_LEVEL_ERROR >= _this.logLevel) { - logger.error(msgs); - } - } - }; - } }]); return SmtpClient; }(); exports.default = SmtpClient; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jbGllbnQuanMiXSwibmFtZXMiOlsiREVCVUdfVEFHIiwiVElNRU9VVF9TT0NLRVRfTE9XRVJfQk9VTkQiLCJUSU1FT1VUX1NPQ0tFVF9NVUxUSVBMSUVSIiwiU210cENsaWVudCIsImhvc3QiLCJwb3J0Iiwib3B0aW9ucyIsInRpbWVvdXRTb2NrZXRMb3dlckJvdW5kIiwidGltZW91dFNvY2tldE11bHRpcGxpZXIiLCJ1c2VTZWN1cmVUcmFuc3BvcnQiLCJhdXRoIiwibmFtZSIsInNvY2tldCIsImRlc3Ryb3llZCIsIndhaXREcmFpbiIsIl9wYXJzZXIiLCJTbXRwQ2xpZW50UmVzcG9uc2VQYXJzZXIiLCJfYXV0aGVudGljYXRlZEFzIiwiX3N1cHBvcnRlZEF1dGgiLCJfZGF0YU1vZGUiLCJfbGFzdERhdGFCeXRlcyIsIl9lbnZlbG9wZSIsIl9jdXJyZW50QWN0aW9uIiwiX3NlY3VyZU1vZGUiLCJfc29ja2V0VGltZW91dFRpbWVyIiwiX3NvY2tldFRpbWVvdXRTdGFydCIsIl9zb2NrZXRUaW1lb3V0UGVyaW9kIiwiY3JlYXRlTG9nZ2VyIiwib25lcnJvciIsImUiLCJvbmRyYWluIiwib25jbG9zZSIsIm9uaWRsZSIsIm9ucmVhZHkiLCJmYWlsZWRSZWNpcGllbnRzIiwib25kb25lIiwic3VjY2VzcyIsIlNvY2tldENvbnRydWN0b3IiLCJUQ1BTb2NrZXQiLCJvcGVuIiwiYmluYXJ5VHlwZSIsImNhIiwidGxzV29ya2VyUGF0aCIsIndzIiwib25jZXJ0IiwiRSIsIl9vbkVycm9yIiwiYmluZCIsIm9ub3BlbiIsIl9vbk9wZW4iLCJyZWFkeVN0YXRlIiwic3VzcGVuZCIsInJlc3VtZSIsImxvZ2dlciIsImRlYnVnIiwiX3NlbmRDb21tYW5kIiwiY2xvc2UiLCJfYWN0aW9uUlNFVCIsIl9kZXN0cm95IiwiZW52ZWxvcGUiLCJmcm9tIiwiY29uY2F0IiwidG8iLCJyY3B0UXVldWUiLCJyY3B0RmFpbGVkIiwicmVzcG9uc2VRdWV1ZSIsIl9hY3Rpb25NQUlMIiwiY2h1bmsiLCJfc2VuZFN0cmluZyIsImxlbmd0aCIsInNlbmQiLCJfYWN0aW9uU3RyZWFtIiwiX3NlbmQiLCJVaW50OEFycmF5IiwiYnVmZmVyIiwic3Vic3RyIiwiZXZlbnQiLCJkYXRhIiwicHJveHlIb3N0bmFtZSIsIm9uZGF0YSIsIl9vbkRhdGEiLCJfb25DbG9zZSIsIl9vbkRyYWluIiwiX29uQ29tbWFuZCIsIl9hY3Rpb25HcmVldGluZyIsImV2dCIsImNsZWFyVGltZW91dCIsInN0cmluZ1BheWxvYWQiLCJUZXh0RGVjb2RlciIsImRlY29kZSIsIkVycm9yIiwibWVzc2FnZSIsImVycm9yIiwiY29tbWFuZCIsImRpc2FibGVFc2NhcGluZyIsInJlcGxhY2UiLCJjaGFyQXQiLCJUZXh0RW5jb2RlciIsImVuY29kZSIsInN0ciIsIl9zZXRUaW1lb3V0IiwiYnl0ZUxlbmd0aCIsInByb2xvbmdQZXJpb2QiLCJNYXRoIiwiZmxvb3IiLCJ0aW1lb3V0Iiwibm93IiwiRGF0ZSIsInNldFRpbWVvdXQiLCJfb25UaW1lb3V0IiwiX2FjdGlvbklkbGUiLCJhdXRoTWV0aG9kIiwieG9hdXRoMiIsInRvVXBwZXJDYXNlIiwidHJpbSIsIl9hY3Rpb25BVVRIX0xPR0lOX1VTRVIiLCJfYWN0aW9uQVVUSENvbXBsZXRlIiwidXNlciIsInBhc3MiLCJfYWN0aW9uQVVUSF9YT0FVVEgyIiwiX2J1aWxkWE9BdXRoMlRva2VuIiwic3RhdHVzQ29kZSIsImxtdHAiLCJfYWN0aW9uTEhMTyIsIl9hY3Rpb25FSExPIiwibWF0Y2giLCJyZXF1aXJlVExTIiwiZXJyTXNnIiwid2FybiIsIl9hY3Rpb25IRUxPIiwibGluZSIsInB1c2giLCJOdW1iZXIiLCJtYXhBbGxvd2VkU2l6ZSIsImlnbm9yZVRMUyIsIl9hY3Rpb25TVEFSVFRMUyIsIl9hdXRoZW50aWNhdGVVc2VyIiwidXBncmFkZVRvU2VjdXJlIiwiX2FjdGlvbkFVVEhfTE9HSU5fUEFTUyIsImN1clJlY2lwaWVudCIsInNoaWZ0IiwiX2FjdGlvblJDUFQiLCJfYWN0aW9uREFUQSIsImluZGV4T2YiLCJyY3B0IiwidG9rZW4iLCJhdXRoRGF0YSIsImpvaW4iLCJjcmVhdG9yIiwiY3JlYXRlRGVmYXVsdExvZ2dlciIsImxvZ0xldmVsIiwiTE9HX0xFVkVMX0FMTCIsIm1zZ3MiLCJMT0dfTEVWRUxfREVCVUciLCJpbmZvIiwiTE9HX0xFVkVMX0lORk8iLCJMT0dfTEVWRUxfV0FSTiIsIkxPR19MRVZFTF9FUlJPUiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O3FqQkFBQTs7QUFFQTs7QUFDQTs7OztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7O0FBT0EsSUFBSUEsWUFBWSxhQUFoQjs7QUFFQTs7O0FBR0EsSUFBTUMsNkJBQTZCLEtBQW5DOztBQUVBOzs7Ozs7O0FBT0EsSUFBTUMsNEJBQTRCLEdBQWxDOztJQUVNQyxVO0FBQ0o7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWtCQSxzQkFBYUMsSUFBYixFQUFtQkMsSUFBbkIsRUFBdUM7QUFBQSxRQUFkQyxPQUFjLHVFQUFKLEVBQUk7O0FBQUE7O0FBQ3JDLFNBQUtBLE9BQUwsR0FBZUEsT0FBZjs7QUFFQSxTQUFLQyx1QkFBTCxHQUErQk4sMEJBQS9CO0FBQ0EsU0FBS08sdUJBQUwsR0FBK0JOLHlCQUEvQjs7QUFFQSxTQUFLRyxJQUFMLEdBQVlBLFNBQVMsS0FBS0MsT0FBTCxDQUFhRyxrQkFBYixHQUFrQyxHQUFsQyxHQUF3QyxFQUFqRCxDQUFaO0FBQ0EsU0FBS0wsSUFBTCxHQUFZQSxRQUFRLFdBQXBCOztBQUVBOzs7OztBQUtBLFNBQUtFLE9BQUwsQ0FBYUcsa0JBQWIsR0FBa0Msd0JBQXdCLEtBQUtILE9BQTdCLEdBQXVDLENBQUMsQ0FBQyxLQUFLQSxPQUFMLENBQWFHLGtCQUF0RCxHQUEyRSxLQUFLSixJQUFMLEtBQWMsR0FBM0g7O0FBRUEsU0FBS0MsT0FBTCxDQUFhSSxJQUFiLEdBQW9CLEtBQUtKLE9BQUwsQ0FBYUksSUFBYixJQUFxQixLQUF6QyxDQWhCcUMsQ0FnQlU7QUFDL0MsU0FBS0osT0FBTCxDQUFhSyxJQUFiLEdBQW9CLEtBQUtMLE9BQUwsQ0FBYUssSUFBYixJQUFxQixXQUF6QyxDQWpCcUMsQ0FpQmdCO0FBQ3JELFNBQUtDLE1BQUwsR0FBYyxLQUFkLENBbEJxQyxDQWtCakI7QUFDcEIsU0FBS0MsU0FBTCxHQUFpQixLQUFqQixDQW5CcUMsQ0FtQmQ7QUFDdkIsU0FBS0MsU0FBTCxHQUFpQixLQUFqQixDQXBCcUMsQ0FvQmQ7O0FBRXZCOztBQUVBLFNBQUtDLE9BQUwsR0FBZSxJQUFJQyxnQkFBSixFQUFmLENBeEJxQyxDQXdCUztBQUM5QyxTQUFLQyxnQkFBTCxHQUF3QixJQUF4QixDQXpCcUMsQ0F5QlI7QUFDN0IsU0FBS0MsY0FBTCxHQUFzQixFQUF0QixDQTFCcUMsQ0EwQlo7QUFDekIsU0FBS0MsU0FBTCxHQUFpQixLQUFqQixDQTNCcUMsQ0EyQmQ7QUFDdkIsU0FBS0MsY0FBTCxHQUFzQixFQUF0QixDQTVCcUMsQ0E0Qlo7QUFDekIsU0FBS0MsU0FBTCxHQUFpQixJQUFqQixDQTdCcUMsQ0E2QmY7QUFDdEIsU0FBS0MsY0FBTCxHQUFzQixJQUF0QixDQTlCcUMsQ0E4QlY7QUFDM0IsU0FBS0MsV0FBTCxHQUFtQixDQUFDLENBQUMsS0FBS2pCLE9BQUwsQ0FBYUcsa0JBQWxDLENBL0JxQyxDQStCZ0I7QUFDckQsU0FBS2UsbUJBQUwsR0FBMkIsS0FBM0IsQ0FoQ3FDLENBZ0NKO0FBQ2pDLFNBQUtDLG1CQUFMLEdBQTJCLEtBQTNCLENBakNxQyxDQWlDSjtBQUNqQyxTQUFLQyxvQkFBTCxHQUE0QixLQUE1QixDQWxDcUMsQ0FrQ0g7O0FBRWxDO0FBQ0EsU0FBS0MsWUFBTDs7QUFFQTtBQUNBLFNBQUtDLE9BQUwsR0FBZSxVQUFDQyxDQUFELEVBQU8sQ0FBRyxDQUF6QixDQXhDcUMsQ0F3Q1g7QUFDMUIsU0FBS0MsT0FBTCxHQUFlLFlBQU0sQ0FBRyxDQUF4QixDQXpDcUMsQ0F5Q1o7QUFDekIsU0FBS0MsT0FBTCxHQUFlLFlBQU0sQ0FBRyxDQUF4QixDQTFDcUMsQ0EwQ1o7QUFDekIsU0FBS0MsTUFBTCxHQUFjLFlBQU0sQ0FBRyxDQUF2QixDQTNDcUMsQ0EyQ2I7QUFDeEIsU0FBS0MsT0FBTCxHQUFlLFVBQUNDLGdCQUFELEVBQXNCLENBQUcsQ0FBeEMsQ0E1Q3FDLENBNENJO0FBQ3pDLFNBQUtDLE1BQUwsR0FBYyxVQUFDQyxPQUFELEVBQWEsQ0FBRyxDQUE5QixDQTdDcUMsQ0E2Q047QUFDaEM7O0FBRUQ7Ozs7Ozs7OEJBR3VDO0FBQUEsVUFBOUJDLGdCQUE4Qix1RUFBWEMsMEJBQVc7O0FBQ3JDLFdBQUsxQixNQUFMLEdBQWN5QixpQkFBaUJFLElBQWpCLENBQXNCLEtBQUtuQyxJQUEzQixFQUFpQyxLQUFLQyxJQUF0QyxFQUE0QztBQUN4RG1DLG9CQUFZLGFBRDRDO0FBRXhEL0IsNEJBQW9CLEtBQUtjLFdBRitCO0FBR3hEa0IsWUFBSSxLQUFLbkMsT0FBTCxDQUFhbUMsRUFIdUM7QUFJeERDLHVCQUFlLEtBQUtwQyxPQUFMLENBQWFvQyxhQUo0QjtBQUt4REMsWUFBSSxLQUFLckMsT0FBTCxDQUFhcUM7QUFMdUMsT0FBNUMsQ0FBZDs7QUFRQTtBQUNBO0FBQ0EsVUFBSTtBQUNGLGFBQUsvQixNQUFMLENBQVlnQyxNQUFaLEdBQXFCLEtBQUtBLE1BQTFCO0FBQ0QsT0FGRCxDQUVFLE9BQU9DLENBQVAsRUFBVSxDQUFHO0FBQ2YsV0FBS2pDLE1BQUwsQ0FBWWdCLE9BQVosR0FBc0IsS0FBS2tCLFFBQUwsQ0FBY0MsSUFBZCxDQUFtQixJQUFuQixDQUF0QjtBQUNBLFdBQUtuQyxNQUFMLENBQVlvQyxNQUFaLEdBQXFCLEtBQUtDLE9BQUwsQ0FBYUYsSUFBYixDQUFrQixJQUFsQixDQUFyQjtBQUNEOztBQUVEOzs7Ozs7OEJBR1c7QUFDVCxVQUFJLEtBQUtuQyxNQUFMLElBQWUsS0FBS0EsTUFBTCxDQUFZc0MsVUFBWixLQUEyQixNQUE5QyxFQUFzRDtBQUNwRCxhQUFLdEMsTUFBTCxDQUFZdUMsT0FBWjtBQUNEO0FBQ0Y7O0FBRUQ7Ozs7Ozs7NkJBSVU7QUFDUixVQUFJLEtBQUt2QyxNQUFMLElBQWUsS0FBS0EsTUFBTCxDQUFZc0MsVUFBWixLQUEyQixNQUE5QyxFQUFzRDtBQUNwRCxhQUFLdEMsTUFBTCxDQUFZd0MsTUFBWjtBQUNEO0FBQ0Y7O0FBRUQ7Ozs7OzsyQkFHUTtBQUNOLFdBQUtDLE1BQUwsQ0FBWUMsS0FBWixDQUFrQnRELFNBQWxCLEVBQTZCLGlCQUE3QjtBQUNBLFdBQUt1RCxZQUFMLENBQWtCLE1BQWxCO0FBQ0EsV0FBS2pDLGNBQUwsR0FBc0IsS0FBS2tDLEtBQTNCO0FBQ0Q7O0FBRUQ7Ozs7Ozs7OzBCQUtPOUMsSSxFQUFNO0FBQ1gsV0FBS0osT0FBTCxDQUFhSSxJQUFiLEdBQW9CQSxRQUFRLEtBQUtKLE9BQUwsQ0FBYUksSUFBekM7QUFDQSxXQUFLMkMsTUFBTCxDQUFZQyxLQUFaLENBQWtCdEQsU0FBbEIsRUFBNkIsaUJBQTdCO0FBQ0EsV0FBS3VELFlBQUwsQ0FBa0IsTUFBbEI7QUFDQSxXQUFLakMsY0FBTCxHQUFzQixLQUFLbUMsV0FBM0I7QUFDRDs7QUFFRDs7Ozs7OzRCQUdTO0FBQ1AsV0FBS0osTUFBTCxDQUFZQyxLQUFaLENBQWtCdEQsU0FBbEIsRUFBNkIsdUJBQTdCO0FBQ0EsVUFBSSxLQUFLWSxNQUFMLElBQWUsS0FBS0EsTUFBTCxDQUFZc0MsVUFBWixLQUEyQixNQUE5QyxFQUFzRDtBQUNwRCxhQUFLdEMsTUFBTCxDQUFZNEMsS0FBWjtBQUNELE9BRkQsTUFFTztBQUNMLGFBQUtFLFFBQUw7QUFDRDtBQUNGOztBQUVEOztBQUVBOzs7Ozs7Ozs7Z0NBTWFDLFEsRUFBVTtBQUNyQixXQUFLdEMsU0FBTCxHQUFpQnNDLFlBQVksRUFBN0I7QUFDQSxXQUFLdEMsU0FBTCxDQUFldUMsSUFBZixHQUFzQixHQUFHQyxNQUFILENBQVUsS0FBS3hDLFNBQUwsQ0FBZXVDLElBQWYsSUFBd0IsZUFBZSxLQUFLdEQsT0FBTCxDQUFhSyxJQUE5RCxFQUFxRSxDQUFyRSxDQUF0QjtBQUNBLFdBQUtVLFNBQUwsQ0FBZXlDLEVBQWYsR0FBb0IsR0FBR0QsTUFBSCxDQUFVLEtBQUt4QyxTQUFMLENBQWV5QyxFQUFmLElBQXFCLEVBQS9CLENBQXBCOztBQUVBO0FBQ0EsV0FBS3pDLFNBQUwsQ0FBZTBDLFNBQWYsR0FBMkIsR0FBR0YsTUFBSCxDQUFVLEtBQUt4QyxTQUFMLENBQWV5QyxFQUF6QixDQUEzQjtBQUNBLFdBQUt6QyxTQUFMLENBQWUyQyxVQUFmLEdBQTRCLEVBQTVCO0FBQ0EsV0FBSzNDLFNBQUwsQ0FBZTRDLGFBQWYsR0FBK0IsRUFBL0I7O0FBRUEsV0FBSzNDLGNBQUwsR0FBc0IsS0FBSzRDLFdBQTNCO0FBQ0EsV0FBS2IsTUFBTCxDQUFZQyxLQUFaLENBQWtCdEQsU0FBbEIsRUFBNkIsc0JBQTdCO0FBQ0EsV0FBS3VELFlBQUwsQ0FBa0IsZ0JBQWlCLEtBQUtsQyxTQUFMLENBQWV1QyxJQUFoQyxHQUF3QyxHQUExRDtBQUNEOztBQUVEOzs7Ozs7Ozs7O3lCQU9NTyxLLEVBQU87QUFDWDtBQUNBLFVBQUksQ0FBQyxLQUFLaEQsU0FBVixFQUFxQjtBQUNuQjtBQUNBO0FBQ0EsZUFBTyxJQUFQO0FBQ0Q7O0FBRUQ7QUFDQSxhQUFPLEtBQUtpRCxXQUFMLENBQWlCRCxLQUFqQixDQUFQO0FBQ0Q7O0FBRUQ7Ozs7Ozs7Ozs7O3dCQVFLQSxLLEVBQU87QUFDVjtBQUNBLFVBQUksQ0FBQyxLQUFLaEQsU0FBVixFQUFxQjtBQUNuQjtBQUNBO0FBQ0EsZUFBTyxJQUFQO0FBQ0Q7O0FBRUQsVUFBSWdELFNBQVNBLE1BQU1FLE1BQW5CLEVBQTJCO0FBQ3pCLGFBQUtDLElBQUwsQ0FBVUgsS0FBVjtBQUNEOztBQUVEO0FBQ0EsV0FBSzdDLGNBQUwsR0FBc0IsS0FBS2lELGFBQTNCOztBQUVBO0FBQ0E7QUFDQSxVQUFJLEtBQUtuRCxjQUFMLEtBQXdCLE1BQTVCLEVBQW9DO0FBQ2xDLGFBQUtOLFNBQUwsR0FBaUIsS0FBSzBELEtBQUwsQ0FBVyxJQUFJQyxVQUFKLENBQWUsQ0FBQyxJQUFELEVBQU8sSUFBUCxFQUFhLElBQWIsQ0FBZixFQUFtQ0MsTUFBOUMsQ0FBakIsQ0FEa0MsQ0FDcUM7QUFDeEUsT0FGRCxNQUVPLElBQUksS0FBS3RELGNBQUwsQ0FBb0J1RCxNQUFwQixDQUEyQixDQUFDLENBQTVCLE1BQW1DLElBQXZDLEVBQTZDO0FBQ2xELGFBQUs3RCxTQUFMLEdBQWlCLEtBQUswRCxLQUFMLENBQVcsSUFBSUMsVUFBSixDQUFlLENBQUMsSUFBRCxFQUFPLElBQVAsRUFBYSxJQUFiLEVBQW1CLElBQW5CLENBQWYsRUFBeUNDLE1BQXBELENBQWpCLENBRGtELENBQzJCO0FBQzlFLE9BRk0sTUFFQTtBQUNMLGFBQUs1RCxTQUFMLEdBQWlCLEtBQUswRCxLQUFMLENBQVcsSUFBSUMsVUFBSixDQUFlLENBQUMsSUFBRCxFQUFPLElBQVAsRUFBYSxJQUFiLEVBQW1CLElBQW5CLEVBQXlCLElBQXpCLENBQWYsRUFBK0NDLE1BQTFELENBQWpCLENBREssQ0FDOEU7QUFDcEY7O0FBRUQ7QUFDQSxXQUFLdkQsU0FBTCxHQUFpQixLQUFqQjtBQUNBLFdBQUtNLG1CQUFMLEdBQTJCLEtBQTNCO0FBQ0EsV0FBS0Msb0JBQUwsR0FBNEIsS0FBNUI7O0FBRUEsYUFBTyxLQUFLWixTQUFaO0FBQ0Q7O0FBRUQ7O0FBRUE7O0FBRUE7Ozs7Ozs7Ozs7NEJBT1M4RCxLLEVBQU87QUFDZCxVQUFJQSxTQUFTQSxNQUFNQyxJQUFmLElBQXVCRCxNQUFNQyxJQUFOLENBQVdDLGFBQXRDLEVBQXFEO0FBQ25ELGFBQUt4RSxPQUFMLENBQWFLLElBQWIsR0FBb0JpRSxNQUFNQyxJQUFOLENBQVdDLGFBQS9CO0FBQ0Q7O0FBRUQsV0FBS2xFLE1BQUwsQ0FBWW1FLE1BQVosR0FBcUIsS0FBS0MsT0FBTCxDQUFhakMsSUFBYixDQUFrQixJQUFsQixDQUFyQjs7QUFFQSxXQUFLbkMsTUFBTCxDQUFZbUIsT0FBWixHQUFzQixLQUFLa0QsUUFBTCxDQUFjbEMsSUFBZCxDQUFtQixJQUFuQixDQUF0QjtBQUNBLFdBQUtuQyxNQUFMLENBQVlrQixPQUFaLEdBQXNCLEtBQUtvRCxRQUFMLENBQWNuQyxJQUFkLENBQW1CLElBQW5CLENBQXRCOztBQUVBLFdBQUtoQyxPQUFMLENBQWFnRSxNQUFiLEdBQXNCLEtBQUtJLFVBQUwsQ0FBZ0JwQyxJQUFoQixDQUFxQixJQUFyQixDQUF0Qjs7QUFFQSxXQUFLekIsY0FBTCxHQUFzQixLQUFLOEQsZUFBM0I7QUFDRDs7QUFFRDs7Ozs7Ozs7OzRCQU1TQyxHLEVBQUs7QUFDWkMsbUJBQWEsS0FBSzlELG1CQUFsQjtBQUNBLFVBQUkrRCxnQkFBZ0IsSUFBSUMseUJBQUosQ0FBZ0IsT0FBaEIsRUFBeUJDLE1BQXpCLENBQWdDLElBQUloQixVQUFKLENBQWVZLElBQUlSLElBQW5CLENBQWhDLENBQXBCO0FBQ0EsV0FBS3hCLE1BQUwsQ0FBWUMsS0FBWixDQUFrQnRELFNBQWxCLEVBQTZCLGFBQWF1RixhQUExQztBQUNBLFdBQUt4RSxPQUFMLENBQWF1RCxJQUFiLENBQWtCaUIsYUFBbEI7QUFDRDs7QUFFRDs7Ozs7Ozs7OytCQU1ZO0FBQ1YsV0FBS3pFLFNBQUwsR0FBaUIsS0FBakI7QUFDQSxXQUFLZ0IsT0FBTDtBQUNEOztBQUVEOzs7Ozs7Ozs7NkJBTVV1RCxHLEVBQUs7QUFDYixVQUFJQSxlQUFlSyxLQUFmLElBQXdCTCxJQUFJTSxPQUFoQyxFQUF5QztBQUN2QyxhQUFLdEMsTUFBTCxDQUFZdUMsS0FBWixDQUFrQjVGLFNBQWxCLEVBQTZCcUYsR0FBN0I7QUFDQSxhQUFLekQsT0FBTCxDQUFheUQsR0FBYjtBQUNELE9BSEQsTUFHTyxJQUFJQSxPQUFPQSxJQUFJUixJQUFKLFlBQW9CYSxLQUEvQixFQUFzQztBQUMzQyxhQUFLckMsTUFBTCxDQUFZdUMsS0FBWixDQUFrQjVGLFNBQWxCLEVBQTZCcUYsSUFBSVIsSUFBakM7QUFDQSxhQUFLakQsT0FBTCxDQUFheUQsSUFBSVIsSUFBakI7QUFDRCxPQUhNLE1BR0E7QUFDTCxhQUFLeEIsTUFBTCxDQUFZdUMsS0FBWixDQUFrQjVGLFNBQWxCLEVBQTZCLElBQUkwRixLQUFKLENBQVdMLE9BQU9BLElBQUlSLElBQVgsSUFBbUJRLElBQUlSLElBQUosQ0FBU2MsT0FBN0IsSUFBeUNOLElBQUlSLElBQTdDLElBQXFEUSxHQUFyRCxJQUE0RCxPQUF0RSxDQUE3QjtBQUNBLGFBQUt6RCxPQUFMLENBQWEsSUFBSThELEtBQUosQ0FBV0wsT0FBT0EsSUFBSVIsSUFBWCxJQUFtQlEsSUFBSVIsSUFBSixDQUFTYyxPQUE3QixJQUF5Q04sSUFBSVIsSUFBN0MsSUFBcURRLEdBQXJELElBQTRELE9BQXRFLENBQWI7QUFDRDs7QUFFRCxXQUFLN0IsS0FBTDtBQUNEOztBQUVEOzs7Ozs7Ozs7K0JBTVk7QUFDVixXQUFLSCxNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2QixnQkFBN0I7QUFDQSxXQUFLMEQsUUFBTDtBQUNEOztBQUVEOzs7Ozs7Ozs7OytCQU9ZbUMsTyxFQUFTO0FBQ25CLFVBQUksT0FBTyxLQUFLdkUsY0FBWixLQUErQixVQUFuQyxFQUErQztBQUM3QyxhQUFLQSxjQUFMLENBQW9CdUUsT0FBcEI7QUFDRDtBQUNGOzs7aUNBRWE7QUFDWjtBQUNBLFVBQUlELFFBQVEsSUFBSUYsS0FBSixDQUFVLG1CQUFWLENBQVo7QUFDQSxXQUFLNUMsUUFBTCxDQUFjOEMsS0FBZDtBQUNEOztBQUVEOzs7Ozs7K0JBR1k7QUFDVk4sbUJBQWEsS0FBSzlELG1CQUFsQjs7QUFFQSxVQUFJLENBQUMsS0FBS1gsU0FBVixFQUFxQjtBQUNuQixhQUFLQSxTQUFMLEdBQWlCLElBQWpCO0FBQ0EsYUFBS2tCLE9BQUw7QUFDRDtBQUNGOztBQUVEOzs7Ozs7Ozs7Z0NBTWFvQyxLLEVBQU87QUFDbEI7QUFDQSxVQUFJLENBQUMsS0FBSzdELE9BQUwsQ0FBYXdGLGVBQWxCLEVBQW1DO0FBQ2pDM0IsZ0JBQVFBLE1BQU00QixPQUFOLENBQWMsT0FBZCxFQUF1QixNQUF2QixDQUFSO0FBQ0EsWUFBSSxDQUFDLEtBQUszRSxjQUFMLENBQW9CdUQsTUFBcEIsQ0FBMkIsQ0FBQyxDQUE1QixNQUFtQyxJQUFuQyxJQUEyQyxDQUFDLEtBQUt2RCxjQUFsRCxLQUFxRStDLE1BQU02QixNQUFOLENBQWEsQ0FBYixNQUFvQixHQUE3RixFQUFrRztBQUNoRzdCLGtCQUFRLE1BQU1BLEtBQWQ7QUFDRDtBQUNGOztBQUVEO0FBQ0E7QUFDQSxVQUFJQSxNQUFNRSxNQUFOLEdBQWUsQ0FBbkIsRUFBc0I7QUFDcEIsYUFBS2pELGNBQUwsR0FBc0IrQyxNQUFNUSxNQUFOLENBQWEsQ0FBQyxDQUFkLENBQXRCO0FBQ0QsT0FGRCxNQUVPLElBQUlSLE1BQU1FLE1BQU4sS0FBaUIsQ0FBckIsRUFBd0I7QUFDN0IsYUFBS2pELGNBQUwsR0FBc0IsS0FBS0EsY0FBTCxDQUFvQnVELE1BQXBCLENBQTJCLENBQUMsQ0FBNUIsSUFBaUNSLEtBQXZEO0FBQ0Q7O0FBRUQsV0FBS2QsTUFBTCxDQUFZQyxLQUFaLENBQWtCdEQsU0FBbEIsRUFBNkIsYUFBYW1FLE1BQU1FLE1BQW5CLEdBQTRCLG1CQUF6RDs7QUFFQTtBQUNBLFdBQUt2RCxTQUFMLEdBQWlCLEtBQUswRCxLQUFMLENBQVcsSUFBSXlCLHlCQUFKLENBQWdCLE9BQWhCLEVBQXlCQyxNQUF6QixDQUFnQy9CLEtBQWhDLEVBQXVDTyxNQUFsRCxDQUFqQjtBQUNBLGFBQU8sS0FBSzVELFNBQVo7QUFDRDs7QUFFRDs7Ozs7Ozs7aUNBS2NxRixHLEVBQUs7QUFDakIsV0FBS3JGLFNBQUwsR0FBaUIsS0FBSzBELEtBQUwsQ0FBVyxJQUFJeUIseUJBQUosQ0FBZ0IsT0FBaEIsRUFBeUJDLE1BQXpCLENBQWdDQyxPQUFPQSxJQUFJeEIsTUFBSixDQUFXLENBQUMsQ0FBWixNQUFtQixNQUFuQixHQUE0QixNQUE1QixHQUFxQyxFQUE1QyxDQUFoQyxFQUFpRkQsTUFBNUYsQ0FBakI7QUFDRDs7OzBCQUVNQSxNLEVBQVE7QUFDYixXQUFLMEIsV0FBTCxDQUFpQjFCLE9BQU8yQixVQUF4QjtBQUNBLGFBQU8sS0FBS3pGLE1BQUwsQ0FBWTBELElBQVosQ0FBaUJJLE1BQWpCLENBQVA7QUFDRDs7O2dDQUVZMkIsVSxFQUFZO0FBQ3ZCLFVBQUlDLGdCQUFnQkMsS0FBS0MsS0FBTCxDQUFXSCxhQUFhLEtBQUs3Rix1QkFBN0IsQ0FBcEI7QUFDQSxVQUFJaUcsT0FBSjs7QUFFQSxVQUFJLEtBQUt0RixTQUFULEVBQW9CO0FBQ2xCO0FBQ0EsWUFBSXVGLE1BQU1DLEtBQUtELEdBQUwsRUFBVjs7QUFFQTtBQUNBLGFBQUtqRixtQkFBTCxHQUEyQixLQUFLQSxtQkFBTCxJQUE0QmlGLEdBQXZEOztBQUVBO0FBQ0EsYUFBS2hGLG9CQUFMLEdBQTRCLENBQUMsS0FBS0Esb0JBQUwsSUFBNkIsS0FBS25CLHVCQUFuQyxJQUE4RCtGLGFBQTFGOztBQUVBO0FBQ0FHLGtCQUFVLEtBQUtoRixtQkFBTCxHQUEyQixLQUFLQyxvQkFBaEMsR0FBdURnRixHQUFqRTtBQUNELE9BWkQsTUFZTztBQUNMO0FBQ0FELGtCQUFVLEtBQUtsRyx1QkFBTCxHQUErQitGLGFBQXpDO0FBQ0Q7O0FBRURoQixtQkFBYSxLQUFLOUQsbUJBQWxCLEVBckJ1QixDQXFCZ0I7QUFDdkMsV0FBS0EsbUJBQUwsR0FBMkJvRixXQUFXLEtBQUtDLFVBQUwsQ0FBZ0I5RCxJQUFoQixDQUFxQixJQUFyQixDQUFYLEVBQXVDMEQsT0FBdkMsQ0FBM0IsQ0F0QnVCLENBc0JvRDtBQUM1RTs7QUFFRDs7Ozs7O3dDQUdxQjtBQUNuQixVQUFJLENBQUMsS0FBS25HLE9BQUwsQ0FBYUksSUFBbEIsRUFBd0I7QUFDdEI7QUFDQSxhQUFLWSxjQUFMLEdBQXNCLEtBQUt3RixXQUEzQjtBQUNBLGFBQUs5RSxNQUFMLEdBSHNCLENBR1I7QUFDZDtBQUNEOztBQUVELFVBQUl0QixJQUFKOztBQUVBLFVBQUksQ0FBQyxLQUFLSixPQUFMLENBQWF5RyxVQUFkLElBQTRCLEtBQUt6RyxPQUFMLENBQWFJLElBQWIsQ0FBa0JzRyxPQUFsRCxFQUEyRDtBQUN6RCxhQUFLMUcsT0FBTCxDQUFheUcsVUFBYixHQUEwQixTQUExQjtBQUNEOztBQUVELFVBQUksS0FBS3pHLE9BQUwsQ0FBYXlHLFVBQWpCLEVBQTZCO0FBQzNCckcsZUFBTyxLQUFLSixPQUFMLENBQWF5RyxVQUFiLENBQXdCRSxXQUF4QixHQUFzQ0MsSUFBdEMsRUFBUDtBQUNELE9BRkQsTUFFTztBQUNMO0FBQ0F4RyxlQUFPLENBQUMsS0FBS1EsY0FBTCxDQUFvQixDQUFwQixLQUEwQixPQUEzQixFQUFvQytGLFdBQXBDLEdBQWtEQyxJQUFsRCxFQUFQO0FBQ0Q7O0FBRUQsY0FBUXhHLElBQVI7QUFDRSxhQUFLLE9BQUw7QUFDRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQUsyQyxNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2QiwrQkFBN0I7QUFDQSxlQUFLc0IsY0FBTCxHQUFzQixLQUFLNkYsc0JBQTNCO0FBQ0EsZUFBSzVELFlBQUwsQ0FBa0IsWUFBbEI7QUFDQTtBQUNGLGFBQUssT0FBTDtBQUNFO0FBQ0E7QUFDQSxlQUFLRixNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2QiwrQkFBN0I7QUFDQSxlQUFLc0IsY0FBTCxHQUFzQixLQUFLOEYsbUJBQTNCO0FBQ0EsZUFBSzdELFlBQUw7QUFDRTtBQUNBLDBCQUNBO0FBQ0U7QUFDQSxpQkFBVztBQUNYLGVBQUtqRCxPQUFMLENBQWFJLElBQWIsQ0FBa0IyRyxJQURsQixHQUN5QixJQUR6QixHQUVBLEtBQUsvRyxPQUFMLENBQWFJLElBQWIsQ0FBa0I0RyxJQUpwQixDQUhGO0FBU0E7QUFDRixhQUFLLFNBQUw7QUFDRTtBQUNBLGVBQUtqRSxNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2QixpQ0FBN0I7QUFDQSxlQUFLc0IsY0FBTCxHQUFzQixLQUFLaUcsbUJBQTNCO0FBQ0EsZUFBS2hFLFlBQUwsQ0FBa0Isa0JBQWtCLEtBQUtpRSxrQkFBTCxDQUF3QixLQUFLbEgsT0FBTCxDQUFhSSxJQUFiLENBQWtCMkcsSUFBMUMsRUFBZ0QsS0FBSy9HLE9BQUwsQ0FBYUksSUFBYixDQUFrQnNHLE9BQWxFLENBQXBDO0FBQ0E7QUE5Qko7O0FBaUNBLFdBQUtsRSxRQUFMLENBQWMsSUFBSTRDLEtBQUosQ0FBVSxtQ0FBbUNoRixJQUE3QyxDQUFkO0FBQ0Q7O0FBRUQ7O0FBRUE7Ozs7Ozs7O29DQUtpQm1GLE8sRUFBUztBQUN4QixVQUFJQSxRQUFRNEIsVUFBUixLQUF1QixHQUEzQixFQUFnQztBQUM5QixhQUFLM0UsUUFBTCxDQUFjLElBQUk0QyxLQUFKLENBQVUsdUJBQXVCRyxRQUFRaEIsSUFBekMsQ0FBZDtBQUNBO0FBQ0Q7O0FBRUQsVUFBSSxLQUFLdkUsT0FBTCxDQUFhb0gsSUFBakIsRUFBdUI7QUFDckIsYUFBS3JFLE1BQUwsQ0FBWUMsS0FBWixDQUFrQnRELFNBQWxCLEVBQTZCLGtCQUFrQixLQUFLTSxPQUFMLENBQWFLLElBQTVEOztBQUVBLGFBQUtXLGNBQUwsR0FBc0IsS0FBS3FHLFdBQTNCO0FBQ0EsYUFBS3BFLFlBQUwsQ0FBa0IsVUFBVSxLQUFLakQsT0FBTCxDQUFhSyxJQUF6QztBQUNELE9BTEQsTUFLTztBQUNMLGFBQUswQyxNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2QixrQkFBa0IsS0FBS00sT0FBTCxDQUFhSyxJQUE1RDs7QUFFQSxhQUFLVyxjQUFMLEdBQXNCLEtBQUtzRyxXQUEzQjtBQUNBLGFBQUtyRSxZQUFMLENBQWtCLFVBQVUsS0FBS2pELE9BQUwsQ0FBYUssSUFBekM7QUFDRDtBQUNGOztBQUVEOzs7Ozs7OztnQ0FLYWtGLE8sRUFBUztBQUNwQixVQUFJLENBQUNBLFFBQVF6RCxPQUFiLEVBQXNCO0FBQ3BCLGFBQUtpQixNQUFMLENBQVl1QyxLQUFaLENBQWtCNUYsU0FBbEIsRUFBNkIscUJBQTdCO0FBQ0EsYUFBSzhDLFFBQUwsQ0FBYyxJQUFJNEMsS0FBSixDQUFVRyxRQUFRaEIsSUFBbEIsQ0FBZDtBQUNBO0FBQ0Q7O0FBRUQ7QUFDQSxXQUFLK0MsV0FBTCxDQUFpQi9CLE9BQWpCO0FBQ0Q7O0FBRUQ7Ozs7Ozs7O2dDQUthQSxPLEVBQVM7QUFDcEIsVUFBSWdDLEtBQUo7O0FBRUEsVUFBSSxDQUFDaEMsUUFBUXpELE9BQWIsRUFBc0I7QUFDcEIsWUFBSSxDQUFDLEtBQUtiLFdBQU4sSUFBcUIsS0FBS2pCLE9BQUwsQ0FBYXdILFVBQXRDLEVBQWtEO0FBQ2hELGNBQUlDLFNBQVMscUNBQWI7QUFDQSxlQUFLMUUsTUFBTCxDQUFZdUMsS0FBWixDQUFrQjVGLFNBQWxCLEVBQTZCK0gsTUFBN0I7QUFDQSxlQUFLakYsUUFBTCxDQUFjLElBQUk0QyxLQUFKLENBQVVxQyxNQUFWLENBQWQ7QUFDQTtBQUNEOztBQUVEO0FBQ0EsYUFBSzFFLE1BQUwsQ0FBWTJFLElBQVosQ0FBaUJoSSxTQUFqQixFQUE0QixzQ0FBc0MsS0FBS00sT0FBTCxDQUFhSyxJQUEvRTtBQUNBLGFBQUtXLGNBQUwsR0FBc0IsS0FBSzJHLFdBQTNCO0FBQ0EsYUFBSzFFLFlBQUwsQ0FBa0IsVUFBVSxLQUFLakQsT0FBTCxDQUFhSyxJQUF6QztBQUNBO0FBQ0Q7O0FBRUQ7QUFDQSxVQUFJa0YsUUFBUXFDLElBQVIsQ0FBYUwsS0FBYixDQUFtQixnQ0FBbkIsQ0FBSixFQUEwRDtBQUN4RCxhQUFLeEUsTUFBTCxDQUFZQyxLQUFaLENBQWtCdEQsU0FBbEIsRUFBNkIsNEJBQTdCO0FBQ0EsYUFBS2tCLGNBQUwsQ0FBb0JpSCxJQUFwQixDQUF5QixPQUF6QjtBQUNEOztBQUVEO0FBQ0EsVUFBSXRDLFFBQVFxQyxJQUFSLENBQWFMLEtBQWIsQ0FBbUIsZ0NBQW5CLENBQUosRUFBMEQ7QUFDeEQsYUFBS3hFLE1BQUwsQ0FBWUMsS0FBWixDQUFrQnRELFNBQWxCLEVBQTZCLDRCQUE3QjtBQUNBLGFBQUtrQixjQUFMLENBQW9CaUgsSUFBcEIsQ0FBeUIsT0FBekI7QUFDRDs7QUFFRDtBQUNBLFVBQUl0QyxRQUFRcUMsSUFBUixDQUFhTCxLQUFiLENBQW1CLGtDQUFuQixDQUFKLEVBQTREO0FBQzFELGFBQUt4RSxNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2Qiw4QkFBN0I7QUFDQSxhQUFLa0IsY0FBTCxDQUFvQmlILElBQXBCLENBQXlCLFNBQXpCO0FBQ0Q7O0FBRUQ7QUFDQSxVQUFJLENBQUNOLFFBQVFoQyxRQUFRcUMsSUFBUixDQUFhTCxLQUFiLENBQW1CLGFBQW5CLENBQVQsS0FBK0NPLE9BQU9QLE1BQU0sQ0FBTixDQUFQLENBQW5ELEVBQXFFO0FBQ25FLFlBQU1RLGlCQUFpQkQsT0FBT1AsTUFBTSxDQUFOLENBQVAsQ0FBdkI7QUFDQSxhQUFLeEUsTUFBTCxDQUFZQyxLQUFaLENBQWtCdEQsU0FBbEIsRUFBNkIsa0NBQWtDcUksY0FBL0Q7QUFDRDs7QUFFRDtBQUNBLFVBQUksQ0FBQyxLQUFLOUcsV0FBVixFQUF1QjtBQUNyQixZQUFLc0UsUUFBUXFDLElBQVIsQ0FBYUwsS0FBYixDQUFtQixvQkFBbkIsS0FBNEMsQ0FBQyxLQUFLdkgsT0FBTCxDQUFhZ0ksU0FBM0QsSUFBeUUsQ0FBQyxDQUFDLEtBQUtoSSxPQUFMLENBQWF3SCxVQUE1RixFQUF3RztBQUN0RyxlQUFLeEcsY0FBTCxHQUFzQixLQUFLaUgsZUFBM0I7QUFDQSxlQUFLbEYsTUFBTCxDQUFZQyxLQUFaLENBQWtCdEQsU0FBbEIsRUFBNkIsa0JBQTdCO0FBQ0EsZUFBS3VELFlBQUwsQ0FBa0IsVUFBbEI7QUFDQTtBQUNEO0FBQ0Y7O0FBRUQsV0FBS2lGLGlCQUFMO0FBQ0Q7O0FBRUQ7Ozs7Ozs7Ozs7b0NBT2lCM0MsTyxFQUFTO0FBQ3hCLFVBQUksQ0FBQ0EsUUFBUXpELE9BQWIsRUFBc0I7QUFDcEIsYUFBS2lCLE1BQUwsQ0FBWXVDLEtBQVosQ0FBa0I1RixTQUFsQixFQUE2Qix5QkFBN0I7QUFDQSxhQUFLOEMsUUFBTCxDQUFjLElBQUk0QyxLQUFKLENBQVVHLFFBQVFoQixJQUFsQixDQUFkO0FBQ0E7QUFDRDs7QUFFRCxXQUFLdEQsV0FBTCxHQUFtQixJQUFuQjtBQUNBLFdBQUtYLE1BQUwsQ0FBWTZILGVBQVo7O0FBRUE7QUFDQSxXQUFLbkgsY0FBTCxHQUFzQixLQUFLc0csV0FBM0I7QUFDQSxXQUFLckUsWUFBTCxDQUFrQixVQUFVLEtBQUtqRCxPQUFMLENBQWFLLElBQXpDO0FBQ0Q7O0FBRUQ7Ozs7Ozs7O2dDQUtha0YsTyxFQUFTO0FBQ3BCLFVBQUksQ0FBQ0EsUUFBUXpELE9BQWIsRUFBc0I7QUFDcEIsYUFBS2lCLE1BQUwsQ0FBWXVDLEtBQVosQ0FBa0I1RixTQUFsQixFQUE2QixxQkFBN0I7QUFDQSxhQUFLOEMsUUFBTCxDQUFjLElBQUk0QyxLQUFKLENBQVVHLFFBQVFoQixJQUFsQixDQUFkO0FBQ0E7QUFDRDtBQUNELFdBQUsyRCxpQkFBTDtBQUNEOztBQUVEOzs7Ozs7OzsyQ0FLd0IzQyxPLEVBQVM7QUFDL0IsVUFBSUEsUUFBUTRCLFVBQVIsS0FBdUIsR0FBdkIsSUFBOEI1QixRQUFRaEIsSUFBUixLQUFpQixjQUFuRCxFQUFtRTtBQUNqRSxhQUFLeEIsTUFBTCxDQUFZdUMsS0FBWixDQUFrQjVGLFNBQWxCLEVBQTZCLHFDQUFxQzZGLFFBQVFoQixJQUExRTtBQUNBLGFBQUsvQixRQUFMLENBQWMsSUFBSTRDLEtBQUosQ0FBVSxtRUFBbUVHLFFBQVFoQixJQUFyRixDQUFkO0FBQ0E7QUFDRDtBQUNELFdBQUt4QixNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2Qiw0QkFBN0I7QUFDQSxXQUFLc0IsY0FBTCxHQUFzQixLQUFLb0gsc0JBQTNCO0FBQ0EsV0FBS25GLFlBQUwsQ0FBa0IseUJBQU8sS0FBS2pELE9BQUwsQ0FBYUksSUFBYixDQUFrQjJHLElBQXpCLENBQWxCO0FBQ0Q7O0FBRUQ7Ozs7Ozs7OzJDQUt3QnhCLE8sRUFBUztBQUMvQixVQUFJQSxRQUFRNEIsVUFBUixLQUF1QixHQUF2QixJQUE4QjVCLFFBQVFoQixJQUFSLEtBQWlCLGNBQW5ELEVBQW1FO0FBQ2pFLGFBQUt4QixNQUFMLENBQVl1QyxLQUFaLENBQWtCNUYsU0FBbEIsRUFBNkIscUNBQXFDNkYsUUFBUWhCLElBQTFFO0FBQ0EsYUFBSy9CLFFBQUwsQ0FBYyxJQUFJNEMsS0FBSixDQUFVLG1FQUFtRUcsUUFBUWhCLElBQXJGLENBQWQ7QUFDQTtBQUNEO0FBQ0QsV0FBS3hCLE1BQUwsQ0FBWUMsS0FBWixDQUFrQnRELFNBQWxCLEVBQTZCLDRCQUE3QjtBQUNBLFdBQUtzQixjQUFMLEdBQXNCLEtBQUs4RixtQkFBM0I7QUFDQSxXQUFLN0QsWUFBTCxDQUFrQix5QkFBTyxLQUFLakQsT0FBTCxDQUFhSSxJQUFiLENBQWtCNEcsSUFBekIsQ0FBbEI7QUFDRDs7QUFFRDs7Ozs7Ozs7d0NBS3FCekIsTyxFQUFTO0FBQzVCLFVBQUksQ0FBQ0EsUUFBUXpELE9BQWIsRUFBc0I7QUFDcEIsYUFBS2lCLE1BQUwsQ0FBWTJFLElBQVosQ0FBaUJoSSxTQUFqQixFQUE0QixtREFBNUI7QUFDQSxhQUFLdUQsWUFBTCxDQUFrQixFQUFsQjtBQUNBLGFBQUtqQyxjQUFMLEdBQXNCLEtBQUs4RixtQkFBM0I7QUFDRCxPQUpELE1BSU87QUFDTCxhQUFLQSxtQkFBTCxDQUF5QnZCLE9BQXpCO0FBQ0Q7QUFDRjs7QUFFRDs7Ozs7Ozs7O3dDQU1xQkEsTyxFQUFTO0FBQzVCLFVBQUksQ0FBQ0EsUUFBUXpELE9BQWIsRUFBc0I7QUFDcEIsYUFBS2lCLE1BQUwsQ0FBWUMsS0FBWixDQUFrQnRELFNBQWxCLEVBQTZCLDRCQUE0QjZGLFFBQVFoQixJQUFqRTtBQUNBLGFBQUsvQixRQUFMLENBQWMsSUFBSTRDLEtBQUosQ0FBVUcsUUFBUWhCLElBQWxCLENBQWQ7QUFDQTtBQUNEOztBQUVELFdBQUt4QixNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2Qiw0QkFBN0I7O0FBRUEsV0FBS2lCLGdCQUFMLEdBQXdCLEtBQUtYLE9BQUwsQ0FBYUksSUFBYixDQUFrQjJHLElBQTFDOztBQUVBLFdBQUsvRixjQUFMLEdBQXNCLEtBQUt3RixXQUEzQjtBQUNBLFdBQUs5RSxNQUFMLEdBWjRCLENBWWQ7QUFDZjs7QUFFRDs7Ozs7Ozs7Z0NBS2E2RCxPLEVBQVM7QUFDcEIsVUFBSUEsUUFBUTRCLFVBQVIsR0FBcUIsR0FBekIsRUFBOEI7QUFDNUIsYUFBSzNFLFFBQUwsQ0FBYyxJQUFJNEMsS0FBSixDQUFVRyxRQUFRcUMsSUFBbEIsQ0FBZDtBQUNBO0FBQ0Q7O0FBRUQsV0FBS3BGLFFBQUwsQ0FBYyxJQUFJNEMsS0FBSixDQUFVRyxRQUFRaEIsSUFBbEIsQ0FBZDtBQUNEOztBQUVEOzs7Ozs7OztnQ0FLYWdCLE8sRUFBUztBQUNwQixVQUFJLENBQUNBLFFBQVF6RCxPQUFiLEVBQXNCO0FBQ3BCLGFBQUtpQixNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2Qiw2QkFBNkI2RixRQUFRaEIsSUFBbEU7QUFDQSxhQUFLL0IsUUFBTCxDQUFjLElBQUk0QyxLQUFKLENBQVVHLFFBQVFoQixJQUFsQixDQUFkO0FBQ0E7QUFDRDs7QUFFRCxVQUFJLENBQUMsS0FBS3hELFNBQUwsQ0FBZTBDLFNBQWYsQ0FBeUJNLE1BQTlCLEVBQXNDO0FBQ3BDLGFBQUt2QixRQUFMLENBQWMsSUFBSTRDLEtBQUosQ0FBVSwwQ0FBVixDQUFkO0FBQ0QsT0FGRCxNQUVPO0FBQ0wsYUFBS3JDLE1BQUwsQ0FBWUMsS0FBWixDQUFrQnRELFNBQWxCLEVBQTZCLDJDQUEyQyxLQUFLcUIsU0FBTCxDQUFlMEMsU0FBZixDQUF5Qk0sTUFBcEUsR0FBNkUsYUFBMUc7QUFDQSxhQUFLaEIsTUFBTCxDQUFZQyxLQUFaLENBQWtCdEQsU0FBbEIsRUFBNkIscUJBQTdCO0FBQ0EsYUFBS3FCLFNBQUwsQ0FBZXNILFlBQWYsR0FBOEIsS0FBS3RILFNBQUwsQ0FBZTBDLFNBQWYsQ0FBeUI2RSxLQUF6QixFQUE5QjtBQUNBLGFBQUt0SCxjQUFMLEdBQXNCLEtBQUt1SCxXQUEzQjtBQUNBLGFBQUt0RixZQUFMLENBQWtCLGNBQWMsS0FBS2xDLFNBQUwsQ0FBZXNILFlBQTdCLEdBQTRDLEdBQTlEO0FBQ0Q7QUFDRjs7QUFFRDs7Ozs7Ozs7OztnQ0FPYTlDLE8sRUFBUztBQUNwQixVQUFJLENBQUNBLFFBQVF6RCxPQUFiLEVBQXNCO0FBQ3BCLGFBQUtpQixNQUFMLENBQVkyRSxJQUFaLENBQWlCaEksU0FBakIsRUFBNEIseUJBQXlCLEtBQUtxQixTQUFMLENBQWVzSCxZQUFwRTtBQUNBO0FBQ0EsYUFBS3RILFNBQUwsQ0FBZTJDLFVBQWYsQ0FBMEJtRSxJQUExQixDQUErQixLQUFLOUcsU0FBTCxDQUFlc0gsWUFBOUM7QUFDRCxPQUpELE1BSU87QUFDTCxhQUFLdEgsU0FBTCxDQUFlNEMsYUFBZixDQUE2QmtFLElBQTdCLENBQWtDLEtBQUs5RyxTQUFMLENBQWVzSCxZQUFqRDtBQUNEOztBQUVELFVBQUksQ0FBQyxLQUFLdEgsU0FBTCxDQUFlMEMsU0FBZixDQUF5Qk0sTUFBOUIsRUFBc0M7QUFDcEMsWUFBSSxLQUFLaEQsU0FBTCxDQUFlMkMsVUFBZixDQUEwQkssTUFBMUIsR0FBbUMsS0FBS2hELFNBQUwsQ0FBZXlDLEVBQWYsQ0FBa0JPLE1BQXpELEVBQWlFO0FBQy9ELGVBQUsvQyxjQUFMLEdBQXNCLEtBQUt3SCxXQUEzQjtBQUNBLGVBQUt6RixNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2Qix1Q0FBN0I7QUFDQSxlQUFLdUQsWUFBTCxDQUFrQixNQUFsQjtBQUNELFNBSkQsTUFJTztBQUNMLGVBQUtULFFBQUwsQ0FBYyxJQUFJNEMsS0FBSixDQUFVLGlEQUFWLENBQWQ7QUFDQSxlQUFLcEUsY0FBTCxHQUFzQixLQUFLd0YsV0FBM0I7QUFDRDtBQUNGLE9BVEQsTUFTTztBQUNMLGFBQUt6RCxNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2QixxQkFBN0I7QUFDQSxhQUFLcUIsU0FBTCxDQUFlc0gsWUFBZixHQUE4QixLQUFLdEgsU0FBTCxDQUFlMEMsU0FBZixDQUF5QjZFLEtBQXpCLEVBQTlCO0FBQ0EsYUFBS3RILGNBQUwsR0FBc0IsS0FBS3VILFdBQTNCO0FBQ0EsYUFBS3RGLFlBQUwsQ0FBa0IsY0FBYyxLQUFLbEMsU0FBTCxDQUFlc0gsWUFBN0IsR0FBNEMsR0FBOUQ7QUFDRDtBQUNGOztBQUVEOzs7Ozs7Ozs7Z0NBTWE5QyxPLEVBQVM7QUFDcEIsVUFBSSxDQUFDQSxRQUFRekQsT0FBYixFQUFzQjtBQUNwQixhQUFLaUIsTUFBTCxDQUFZdUMsS0FBWixDQUFrQjVGLFNBQWxCLEVBQTZCLHVCQUF1QjZGLFFBQVFoQixJQUE1RDtBQUNBLGFBQUsvQixRQUFMLENBQWMsSUFBSTRDLEtBQUosQ0FBVUcsUUFBUWhCLElBQWxCLENBQWQ7QUFDQTtBQUNEOztBQUVELFdBQUs1RCxnQkFBTCxHQUF3QixJQUF4QjtBQUNBLFdBQUt1SCxpQkFBTDtBQUNEOztBQUVEOzs7Ozs7OztnQ0FLYTNDLE8sRUFBUztBQUNwQjtBQUNBO0FBQ0EsVUFBSSxDQUFDLEdBQUQsRUFBTSxHQUFOLEVBQVdrRCxPQUFYLENBQW1CbEQsUUFBUTRCLFVBQTNCLElBQXlDLENBQTdDLEVBQWdEO0FBQzlDLGFBQUtwRSxNQUFMLENBQVl1QyxLQUFaLENBQWtCNUYsU0FBbEIsRUFBNkIsdUJBQXVCNkYsUUFBUWhCLElBQTVEO0FBQ0EsYUFBSy9CLFFBQUwsQ0FBYyxJQUFJNEMsS0FBSixDQUFVRyxRQUFRaEIsSUFBbEIsQ0FBZDtBQUNBO0FBQ0Q7O0FBRUQsV0FBSzFELFNBQUwsR0FBaUIsSUFBakI7QUFDQSxXQUFLRyxjQUFMLEdBQXNCLEtBQUt3RixXQUEzQjtBQUNBLFdBQUs3RSxPQUFMLENBQWEsS0FBS1osU0FBTCxDQUFlMkMsVUFBNUI7QUFDRDs7QUFFRDs7Ozs7Ozs7O2tDQU1lNkIsTyxFQUFTO0FBQ3RCLFVBQUltRCxJQUFKOztBQUVBLFVBQUksS0FBSzFJLE9BQUwsQ0FBYW9ILElBQWpCLEVBQXVCO0FBQ3JCO0FBQ0E7O0FBRUFzQixlQUFPLEtBQUszSCxTQUFMLENBQWU0QyxhQUFmLENBQTZCMkUsS0FBN0IsRUFBUDtBQUNBLFlBQUksQ0FBQy9DLFFBQVF6RCxPQUFiLEVBQXNCO0FBQ3BCLGVBQUtpQixNQUFMLENBQVl1QyxLQUFaLENBQWtCNUYsU0FBbEIsRUFBNkIsdUJBQXVCZ0osSUFBdkIsR0FBOEIsVUFBM0Q7QUFDQSxlQUFLM0gsU0FBTCxDQUFlMkMsVUFBZixDQUEwQm1FLElBQTFCLENBQStCYSxJQUEvQjtBQUNELFNBSEQsTUFHTztBQUNMLGVBQUszRixNQUFMLENBQVl1QyxLQUFaLENBQWtCNUYsU0FBbEIsRUFBNkIsdUJBQXVCZ0osSUFBdkIsR0FBOEIsYUFBM0Q7QUFDRDs7QUFFRCxZQUFJLEtBQUszSCxTQUFMLENBQWU0QyxhQUFmLENBQTZCSSxNQUFqQyxFQUF5QztBQUN2QyxlQUFLL0MsY0FBTCxHQUFzQixLQUFLaUQsYUFBM0I7QUFDQTtBQUNEOztBQUVELGFBQUtqRCxjQUFMLEdBQXNCLEtBQUt3RixXQUEzQjtBQUNBLGFBQUszRSxNQUFMLENBQVksSUFBWjtBQUNELE9BbkJELE1BbUJPO0FBQ0w7QUFDQTs7QUFFQSxZQUFJLENBQUMwRCxRQUFRekQsT0FBYixFQUFzQjtBQUNwQixlQUFLaUIsTUFBTCxDQUFZdUMsS0FBWixDQUFrQjVGLFNBQWxCLEVBQTZCLHlCQUE3QjtBQUNELFNBRkQsTUFFTztBQUNMLGVBQUtxRCxNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2Qiw0QkFBN0I7QUFDRDs7QUFFRCxhQUFLc0IsY0FBTCxHQUFzQixLQUFLd0YsV0FBM0I7QUFDQSxhQUFLM0UsTUFBTCxDQUFZLENBQUMsQ0FBQzBELFFBQVF6RCxPQUF0QjtBQUNEOztBQUVEO0FBQ0EsVUFBSSxLQUFLZCxjQUFMLEtBQXdCLEtBQUt3RixXQUFqQyxFQUE4QztBQUM1QztBQUNBLGFBQUt6RCxNQUFMLENBQVlDLEtBQVosQ0FBa0J0RCxTQUFsQixFQUE2Qiw2Q0FBN0I7QUFDQSxhQUFLZ0MsTUFBTDtBQUNEO0FBQ0Y7O0FBRUQ7Ozs7Ozs7Ozs7dUNBT29CcUYsSSxFQUFNNEIsSyxFQUFPO0FBQy9CLFVBQUlDLFdBQVcsQ0FDYixXQUFXN0IsUUFBUSxFQUFuQixDQURhLEVBRWIsaUJBQWlCNEIsS0FGSixFQUdiLEVBSGEsRUFJYixFQUphLENBQWY7QUFNQTtBQUNBLGFBQU8seUJBQU9DLFNBQVNDLElBQVQsQ0FBYyxNQUFkLENBQVAsQ0FBUDtBQUNEOzs7bUNBRTRDO0FBQUE7O0FBQUEsVUFBL0JDLE9BQStCLHVFQUFyQkMsZ0JBQXFCOztBQUMzQyxVQUFNaEcsU0FBUytGLFFBQVEsQ0FBQyxLQUFLOUksT0FBTCxDQUFhSSxJQUFiLElBQXFCLEVBQXRCLEVBQTBCMkcsSUFBMUIsSUFBa0MsRUFBMUMsRUFBOEMsS0FBS2pILElBQW5ELENBQWY7QUFDQSxXQUFLa0osUUFBTCxHQUFnQixLQUFLQyxhQUFyQjtBQUNBLFdBQUtsRyxNQUFMLEdBQWM7QUFDWkMsZUFBTyxpQkFBYTtBQUFBLDRDQUFUa0csSUFBUztBQUFUQSxnQkFBUztBQUFBOztBQUFFLGNBQUlDLDJCQUFtQixNQUFLSCxRQUE1QixFQUFzQztBQUFFakcsbUJBQU9DLEtBQVAsQ0FBYWtHLElBQWI7QUFBb0I7QUFBRSxTQUR4RTtBQUVaRSxjQUFNLGdCQUFhO0FBQUEsNkNBQVRGLElBQVM7QUFBVEEsZ0JBQVM7QUFBQTs7QUFBRSxjQUFJRywwQkFBa0IsTUFBS0wsUUFBM0IsRUFBcUM7QUFBRWpHLG1CQUFPcUcsSUFBUCxDQUFZRixJQUFaO0FBQW1CO0FBQUUsU0FGckU7QUFHWnhCLGNBQU0sZ0JBQWE7QUFBQSw2Q0FBVHdCLElBQVM7QUFBVEEsZ0JBQVM7QUFBQTs7QUFBRSxjQUFJSSwwQkFBa0IsTUFBS04sUUFBM0IsRUFBcUM7QUFBRWpHLG1CQUFPMkUsSUFBUCxDQUFZd0IsSUFBWjtBQUFtQjtBQUFFLFNBSHJFO0FBSVo1RCxlQUFPLGlCQUFhO0FBQUEsNkNBQVQ0RCxJQUFTO0FBQVRBLGdCQUFTO0FBQUE7O0FBQUUsY0FBSUssMkJBQW1CLE1BQUtQLFFBQTVCLEVBQXNDO0FBQUVqRyxtQkFBT3VDLEtBQVAsQ0FBYTRELElBQWI7QUFBb0I7QUFBRTtBQUp4RSxPQUFkO0FBTUQ7Ozs7OztrQkFHWXJKLFUiLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG5cbmltcG9ydCB7IGVuY29kZSB9IGZyb20gJ2VtYWlsanMtYmFzZTY0J1xuaW1wb3J0IFRDUFNvY2tldCBmcm9tICdlbWFpbGpzLXRjcC1zb2NrZXQnXG5pbXBvcnQgeyBUZXh0RGVjb2RlciwgVGV4dEVuY29kZXIgfSBmcm9tICd0ZXh0LWVuY29kaW5nJ1xuaW1wb3J0IFNtdHBDbGllbnRSZXNwb25zZVBhcnNlciBmcm9tICcuL3BhcnNlcidcbmltcG9ydCBjcmVhdGVEZWZhdWx0TG9nZ2VyIGZyb20gJy4vbG9nZ2VyJ1xuaW1wb3J0IHtcbiAgTE9HX0xFVkVMX0VSUk9SLFxuICBMT0dfTEVWRUxfV0FSTixcbiAgTE9HX0xFVkVMX0lORk8sXG4gIExPR19MRVZFTF9ERUJVR1xufSBmcm9tICcuL2NvbW1vbidcblxudmFyIERFQlVHX1RBRyA9ICdTTVRQIENsaWVudCdcblxuLyoqXG4gKiBMb3dlciBCb3VuZCBmb3Igc29ja2V0IHRpbWVvdXQgdG8gd2FpdCBzaW5jZSB0aGUgbGFzdCBkYXRhIHdhcyB3cml0dGVuIHRvIGEgc29ja2V0XG4gKi9cbmNvbnN0IFRJTUVPVVRfU09DS0VUX0xPV0VSX0JPVU5EID0gMTAwMDBcblxuLyoqXG4gKiBNdWx0aXBsaWVyIGZvciBzb2NrZXQgdGltZW91dDpcbiAqXG4gKiBXZSBhc3N1bWUgYXQgbGVhc3QgYSBHUFJTIGNvbm5lY3Rpb24gd2l0aCAxMTUga2IvcyA9IDE0LDM3NSBrQi9zIHRvcHMsIHNvIDEwIEtCL3MgdG8gYmUgb25cbiAqIHRoZSBzYWZlIHNpZGUuIFdlIGNhbiB0aW1lb3V0IGFmdGVyIGEgbG93ZXIgYm91bmQgb2YgMTBzICsgKG4gS0IgLyAxMCBLQi9zKS4gQSAxIE1CIG1lc3NhZ2VcbiAqIHVwbG9hZCB3b3VsZCBiZSAxMTAgc2Vjb25kcyB0byB3YWl0IGZvciB0aGUgdGltZW91dC4gMTAgS0IvcyA9PT0gMC4xIHMvQlxuICovXG5jb25zdCBUSU1FT1VUX1NPQ0tFVF9NVUxUSVBMSUVSID0gMC4xXG5cbmNsYXNzIFNtdHBDbGllbnQge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIGNvbm5lY3Rpb24gb2JqZWN0IHRvIGEgU01UUCBzZXJ2ZXIgYW5kIGFsbG93cyB0byBzZW5kIG1haWwgdGhyb3VnaCBpdC5cbiAgICogQ2FsbCBgY29ubmVjdGAgbWV0aG9kIHRvIGluaXRpdGF0ZSB0aGUgYWN0dWFsIGNvbm5lY3Rpb24sIHRoZSBjb25zdHJ1Y3RvciBvbmx5XG4gICAqIGRlZmluZXMgdGhlIHByb3BlcnRpZXMgYnV0IGRvZXMgbm90IGFjdHVhbGx5IGNvbm5lY3QuXG4gICAqXG4gICAqIE5CISBUaGUgcGFyYW1ldGVyIG9yZGVyIChob3N0LCBwb3J0KSBkaWZmZXJzIGZyb20gbm9kZS5qcyBcIndheVwiIChwb3J0LCBob3N0KVxuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IFtob3N0PVwibG9jYWxob3N0XCJdIEhvc3RuYW1lIHRvIGNvbmVuY3QgdG9cbiAgICogQHBhcmFtIHtOdW1iZXJ9IFtwb3J0PTI1XSBQb3J0IG51bWJlciB0byBjb25uZWN0IHRvXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gT3B0aW9uYWwgb3B0aW9ucyBvYmplY3RcbiAgICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy51c2VTZWN1cmVUcmFuc3BvcnRdIFNldCB0byB0cnVlLCB0byB1c2UgZW5jcnlwdGVkIGNvbm5lY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLm5hbWVdIENsaWVudCBob3N0bmFtZSBmb3IgaW50cm9kdWNpbmcgaXRzZWxmIHRvIHRoZSBzZXJ2ZXJcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmF1dGhdIEF1dGhlbnRpY2F0aW9uIG9wdGlvbnMuIERlcGVuZHMgb24gdGhlIHByZWZlcnJlZCBhdXRoZW50aWNhdGlvbiBtZXRob2QuIFVzdWFsbHkge3VzZXIsIHBhc3N9XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hdXRoTWV0aG9kXSBGb3JjZSBzcGVjaWZpYyBhdXRoZW50aWNhdGlvbiBtZXRob2RcbiAgICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5kaXNhYmxlRXNjYXBpbmddIElmIHNldCB0byB0cnVlLCBkbyBub3QgZXNjYXBlIGRvdHMgb24gdGhlIGJlZ2lubmluZyBvZiB0aGUgbGluZXNcbiAgICovXG4gIGNvbnN0cnVjdG9yIChob3N0LCBwb3J0LCBvcHRpb25zID0ge30pIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG5cbiAgICB0aGlzLnRpbWVvdXRTb2NrZXRMb3dlckJvdW5kID0gVElNRU9VVF9TT0NLRVRfTE9XRVJfQk9VTkRcbiAgICB0aGlzLnRpbWVvdXRTb2NrZXRNdWx0aXBsaWVyID0gVElNRU9VVF9TT0NLRVRfTVVMVElQTElFUlxuXG4gICAgdGhpcy5wb3J0ID0gcG9ydCB8fCAodGhpcy5vcHRpb25zLnVzZVNlY3VyZVRyYW5zcG9ydCA/IDQ2NSA6IDI1KVxuICAgIHRoaXMuaG9zdCA9IGhvc3QgfHwgJ2xvY2FsaG9zdCdcblxuICAgIC8qKlxuICAgICAqIElmIHNldCB0byB0cnVlLCBzdGFydCBhbiBlbmNyeXB0ZWQgY29ubmVjdGlvbiBpbnN0ZWFkIG9mIHRoZSBwbGFpbnRleHQgb25lXG4gICAgICogKHJlY29tbWVuZGVkIGlmIGFwcGxpY2FibGUpLiBJZiB1c2VTZWN1cmVUcmFuc3BvcnQgaXMgbm90IHNldCBidXQgdGhlIHBvcnQgdXNlZCBpcyA0NjUsXG4gICAgICogdGhlbiBlY3J5cHRpb24gaXMgdXNlZCBieSBkZWZhdWx0LlxuICAgICAqL1xuICAgIHRoaXMub3B0aW9ucy51c2VTZWN1cmVUcmFuc3BvcnQgPSAndXNlU2VjdXJlVHJhbnNwb3J0JyBpbiB0aGlzLm9wdGlvbnMgPyAhIXRoaXMub3B0aW9ucy51c2VTZWN1cmVUcmFuc3BvcnQgOiB0aGlzLnBvcnQgPT09IDQ2NVxuXG4gICAgdGhpcy5vcHRpb25zLmF1dGggPSB0aGlzLm9wdGlvbnMuYXV0aCB8fCBmYWxzZSAvLyBBdXRoZW50aWNhdGlvbiBvYmplY3QuIElmIG5vdCBzZXQsIGF1dGhlbnRpY2F0aW9uIHN0ZXAgd2lsbCBiZSBza2lwcGVkLlxuICAgIHRoaXMub3B0aW9ucy5uYW1lID0gdGhpcy5vcHRpb25zLm5hbWUgfHwgJ2xvY2FsaG9zdCcgLy8gSG9zdG5hbWUgb2YgdGhlIGNsaWVudCwgdGhpcyB3aWxsIGJlIHVzZWQgZm9yIGludHJvZHVjaW5nIHRvIHRoZSBzZXJ2ZXJcbiAgICB0aGlzLnNvY2tldCA9IGZhbHNlIC8vIERvd25zdHJlYW0gVENQIHNvY2tldCB0byB0aGUgU01UUCBzZXJ2ZXIsIGNyZWF0ZWQgd2l0aCBtb3pUQ1BTb2NrZXRcbiAgICB0aGlzLmRlc3Ryb3llZCA9IGZhbHNlIC8vIEluZGljYXRlcyBpZiB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBjbG9zZWQgYW5kIGNhbid0IGJlIHVzZWQgYW55bW9yZVxuICAgIHRoaXMud2FpdERyYWluID0gZmFsc2UgLy8gS2VlcHMgdHJhY2sgaWYgdGhlIGRvd25zdHJlYW0gc29ja2V0IGlzIGN1cnJlbnRseSBmdWxsIGFuZCBhIGRyYWluIGV2ZW50IHNob3VsZCBiZSB3YWl0ZWQgZm9yIG9yIG5vdFxuXG4gICAgLy8gUHJpdmF0ZSBwcm9wZXJ0aWVzXG5cbiAgICB0aGlzLl9wYXJzZXIgPSBuZXcgU210cENsaWVudFJlc3BvbnNlUGFyc2VyKCkgLy8gU01UUCByZXNwb25zZSBwYXJzZXIgb2JqZWN0LiBBbGwgZGF0YSBjb21pbmcgZnJvbSB0aGUgZG93bnN0cmVhbSBzZXJ2ZXIgaXMgZmVlZGVkIHRvIHRoaXMgcGFyc2VyXG4gICAgdGhpcy5fYXV0aGVudGljYXRlZEFzID0gbnVsbCAvLyBJZiBhdXRoZW50aWNhdGVkIHN1Y2Nlc3NmdWxseSwgc3RvcmVzIHRoZSB1c2VybmFtZVxuICAgIHRoaXMuX3N1cHBvcnRlZEF1dGggPSBbXSAvLyBBIGxpc3Qgb2YgYXV0aGVudGljYXRpb24gbWVjaGFuaXNtcyBkZXRlY3RlZCBmcm9tIHRoZSBFSExPIHJlc3BvbnNlIGFuZCB3aGljaCBhcmUgY29tcGF0aWJsZSB3aXRoIHRoaXMgbGlicmFyeVxuICAgIHRoaXMuX2RhdGFNb2RlID0gZmFsc2UgLy8gSWYgdHJ1ZSwgYWNjZXB0cyBkYXRhIGZyb20gdGhlIHVwc3RyZWFtIHRvIGJlIHBhc3NlZCBkaXJlY3RseSB0byB0aGUgZG93bnN0cmVhbSBzb2NrZXQuIFVzZWQgYWZ0ZXIgdGhlIERBVEEgY29tbWFuZFxuICAgIHRoaXMuX2xhc3REYXRhQnl0ZXMgPSAnJyAvLyBLZWVwIHRyYWNrIG9mIHRoZSBsYXN0IGJ5dGVzIHRvIHNlZSBob3cgdGhlIHRlcm1pbmF0aW5nIGRvdCBzaG91bGQgYmUgcGxhY2VkXG4gICAgdGhpcy5fZW52ZWxvcGUgPSBudWxsIC8vIEVudmVsb3BlIG9iamVjdCBmb3IgdHJhY2tpbmcgd2hvIGlzIHNlbmRpbmcgbWFpbCB0byB3aG9tXG4gICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IG51bGwgLy8gU3RvcmVzIHRoZSBmdW5jdGlvbiB0aGF0IHNob3VsZCBiZSBydW4gYWZ0ZXIgYSByZXNwb25zZSBoYXMgYmVlbiByZWNlaXZlZCBmcm9tIHRoZSBzZXJ2ZXJcbiAgICB0aGlzLl9zZWN1cmVNb2RlID0gISF0aGlzLm9wdGlvbnMudXNlU2VjdXJlVHJhbnNwb3J0IC8vIEluZGljYXRlcyBpZiB0aGUgY29ubmVjdGlvbiBpcyBzZWN1cmVkIG9yIHBsYWludGV4dFxuICAgIHRoaXMuX3NvY2tldFRpbWVvdXRUaW1lciA9IGZhbHNlIC8vIFRpbWVyIHdhaXRpbmcgdG8gZGVjbGFyZSB0aGUgc29ja2V0IGRlYWQgc3RhcnRpbmcgZnJvbSB0aGUgbGFzdCB3cml0ZVxuICAgIHRoaXMuX3NvY2tldFRpbWVvdXRTdGFydCA9IGZhbHNlIC8vIFN0YXJ0IHRpbWUgb2Ygc2VuZGluZyB0aGUgZmlyc3QgcGFja2V0IGluIGRhdGEgbW9kZVxuICAgIHRoaXMuX3NvY2tldFRpbWVvdXRQZXJpb2QgPSBmYWxzZSAvLyBUaW1lb3V0IGZvciBzZW5kaW5nIGluIGRhdGEgbW9kZSwgZ2V0cyBleHRlbmRlZCB3aXRoIGV2ZXJ5IHNlbmQoKVxuXG4gICAgLy8gQWN0aXZhdGUgbG9nZ2luZ1xuICAgIHRoaXMuY3JlYXRlTG9nZ2VyKClcblxuICAgIC8vIEV2ZW50IHBsYWNlaG9sZGVyc1xuICAgIHRoaXMub25lcnJvciA9IChlKSA9PiB7IH0gLy8gV2lsbCBiZSBydW4gd2hlbiBhbiBlcnJvciBvY2N1cnMuIFRoZSBgb25jbG9zZWAgZXZlbnQgd2lsbCBmaXJlIHN1YnNlcXVlbnRseS5cbiAgICB0aGlzLm9uZHJhaW4gPSAoKSA9PiB7IH0gLy8gTW9yZSBkYXRhIGNhbiBiZSBidWZmZXJlZCBpbiB0aGUgc29ja2V0LlxuICAgIHRoaXMub25jbG9zZSA9ICgpID0+IHsgfSAvLyBUaGUgY29ubmVjdGlvbiB0byB0aGUgc2VydmVyIGhhcyBiZWVuIGNsb3NlZFxuICAgIHRoaXMub25pZGxlID0gKCkgPT4geyB9IC8vIFRoZSBjb25uZWN0aW9uIGlzIGVzdGFibGlzaGVkIGFuZCBpZGxlLCB5b3UgY2FuIHNlbmQgbWFpbCBub3dcbiAgICB0aGlzLm9ucmVhZHkgPSAoZmFpbGVkUmVjaXBpZW50cykgPT4geyB9IC8vIFdhaXRpbmcgZm9yIG1haWwgYm9keSwgbGlzdHMgYWRkcmVzc2VzIHRoYXQgd2VyZSBub3QgYWNjZXB0ZWQgYXMgcmVjaXBpZW50c1xuICAgIHRoaXMub25kb25lID0gKHN1Y2Nlc3MpID0+IHsgfSAvLyBUaGUgbWFpbCBoYXMgYmVlbiBzZW50LiBXYWl0IGZvciBgb25pZGxlYCBuZXh0LiBJbmRpY2F0ZXMgaWYgdGhlIG1lc3NhZ2Ugd2FzIHF1ZXVlZCBieSB0aGUgc2VydmVyLlxuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYXRlIGEgY29ubmVjdGlvbiB0byB0aGUgc2VydmVyXG4gICAqL1xuICBjb25uZWN0IChTb2NrZXRDb250cnVjdG9yID0gVENQU29ja2V0KSB7XG4gICAgdGhpcy5zb2NrZXQgPSBTb2NrZXRDb250cnVjdG9yLm9wZW4odGhpcy5ob3N0LCB0aGlzLnBvcnQsIHtcbiAgICAgIGJpbmFyeVR5cGU6ICdhcnJheWJ1ZmZlcicsXG4gICAgICB1c2VTZWN1cmVUcmFuc3BvcnQ6IHRoaXMuX3NlY3VyZU1vZGUsXG4gICAgICBjYTogdGhpcy5vcHRpb25zLmNhLFxuICAgICAgdGxzV29ya2VyUGF0aDogdGhpcy5vcHRpb25zLnRsc1dvcmtlclBhdGgsXG4gICAgICB3czogdGhpcy5vcHRpb25zLndzXG4gICAgfSlcblxuICAgIC8vIGFsbG93cyBjZXJ0aWZpY2F0ZSBoYW5kbGluZyBmb3IgcGxhdGZvcm0gdy9vIG5hdGl2ZSB0bHMgc3VwcG9ydFxuICAgIC8vIG9uY2VydCBpcyBub24gc3RhbmRhcmQgc28gc2V0dGluZyBpdCBtaWdodCB0aHJvdyBpZiB0aGUgc29ja2V0IG9iamVjdCBpcyBpbW11dGFibGVcbiAgICB0cnkge1xuICAgICAgdGhpcy5zb2NrZXQub25jZXJ0ID0gdGhpcy5vbmNlcnRcbiAgICB9IGNhdGNoIChFKSB7IH1cbiAgICB0aGlzLnNvY2tldC5vbmVycm9yID0gdGhpcy5fb25FcnJvci5iaW5kKHRoaXMpXG4gICAgdGhpcy5zb2NrZXQub25vcGVuID0gdGhpcy5fb25PcGVuLmJpbmQodGhpcylcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXVzZXMgYGRhdGFgIGV2ZW50cyBmcm9tIHRoZSBkb3duc3RyZWFtIFNNVFAgc2VydmVyXG4gICAqL1xuICBzdXNwZW5kICgpIHtcbiAgICBpZiAodGhpcy5zb2NrZXQgJiYgdGhpcy5zb2NrZXQucmVhZHlTdGF0ZSA9PT0gJ29wZW4nKSB7XG4gICAgICB0aGlzLnNvY2tldC5zdXNwZW5kKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzdW1lcyBgZGF0YWAgZXZlbnRzIGZyb20gdGhlIGRvd25zdHJlYW0gU01UUCBzZXJ2ZXIuIEJlIGNhcmVmdWwgb2Ygbm90XG4gICAqIHJlc3VtaW5nIHNvbWV0aGluZyB0aGF0IGlzIG5vdCBzdXNwZW5kZWQgLSBhbiBlcnJvciBpcyB0aHJvd24gaW4gdGhpcyBjYXNlXG4gICAqL1xuICByZXN1bWUgKCkge1xuICAgIGlmICh0aGlzLnNvY2tldCAmJiB0aGlzLnNvY2tldC5yZWFkeVN0YXRlID09PSAnb3BlbicpIHtcbiAgICAgIHRoaXMuc29ja2V0LnJlc3VtZSgpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNlbmRzIFFVSVRcbiAgICovXG4gIHF1aXQgKCkge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ1NlbmRpbmcgUVVJVC4uLicpXG4gICAgdGhpcy5fc2VuZENvbW1hbmQoJ1FVSVQnKVxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLmNsb3NlXG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgYXV0aGVudGljYXRpb25cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IFthdXRoXSBVc2UgdGhpcyBpZiB5b3Ugd2FudCB0byBhdXRoZW50aWNhdGUgYXMgYW5vdGhlciB1c2VyXG4gICAqL1xuICByZXNldCAoYXV0aCkge1xuICAgIHRoaXMub3B0aW9ucy5hdXRoID0gYXV0aCB8fCB0aGlzLm9wdGlvbnMuYXV0aFxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ1NlbmRpbmcgUlNFVC4uLicpXG4gICAgdGhpcy5fc2VuZENvbW1hbmQoJ1JTRVQnKVxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25SU0VUXG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBzZXJ2ZXJcbiAgICovXG4gIGNsb3NlICgpIHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdDbG9zaW5nIGNvbm5lY3Rpb24uLi4nKVxuICAgIGlmICh0aGlzLnNvY2tldCAmJiB0aGlzLnNvY2tldC5yZWFkeVN0YXRlID09PSAnb3BlbicpIHtcbiAgICAgIHRoaXMuc29ja2V0LmNsb3NlKClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZGVzdHJveSgpXG4gICAgfVxuICB9XG5cbiAgLy8gTWFpbCByZWxhdGVkIG1ldGhvZHNcblxuICAvKipcbiAgICogSW5pdGlhdGVzIGEgbmV3IG1lc3NhZ2UgYnkgc3VibWl0dGluZyBlbnZlbG9wZSBkYXRhLCBzdGFydGluZyB3aXRoXG4gICAqIGBNQUlMIEZST006YCBjb21tYW5kLiBVc2UgYWZ0ZXIgYG9uaWRsZWAgZXZlbnRcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGVudmVsb3BlIEVudmVsb3BlIG9iamVjdCBpbiB0aGUgZm9ybSBvZiB7ZnJvbTpcIi4uLlwiLCB0bzpbXCIuLi5cIl19XG4gICAqL1xuICB1c2VFbnZlbG9wZSAoZW52ZWxvcGUpIHtcbiAgICB0aGlzLl9lbnZlbG9wZSA9IGVudmVsb3BlIHx8IHt9XG4gICAgdGhpcy5fZW52ZWxvcGUuZnJvbSA9IFtdLmNvbmNhdCh0aGlzLl9lbnZlbG9wZS5mcm9tIHx8ICgnYW5vbnltb3VzQCcgKyB0aGlzLm9wdGlvbnMubmFtZSkpWzBdXG4gICAgdGhpcy5fZW52ZWxvcGUudG8gPSBbXS5jb25jYXQodGhpcy5fZW52ZWxvcGUudG8gfHwgW10pXG5cbiAgICAvLyBjbG9uZSB0aGUgcmVjaXBpZW50cyBhcnJheSBmb3IgbGF0dGVyIG1hbmlwdWxhdGlvblxuICAgIHRoaXMuX2VudmVsb3BlLnJjcHRRdWV1ZSA9IFtdLmNvbmNhdCh0aGlzLl9lbnZlbG9wZS50bylcbiAgICB0aGlzLl9lbnZlbG9wZS5yY3B0RmFpbGVkID0gW11cbiAgICB0aGlzLl9lbnZlbG9wZS5yZXNwb25zZVF1ZXVlID0gW11cblxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25NQUlMXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnU2VuZGluZyBNQUlMIEZST00uLi4nKVxuICAgIHRoaXMuX3NlbmRDb21tYW5kKCdNQUlMIEZST006PCcgKyAodGhpcy5fZW52ZWxvcGUuZnJvbSkgKyAnPicpXG4gIH1cblxuICAvKipcbiAgICogU2VuZCBBU0NJSSBkYXRhIHRvIHRoZSBzZXJ2ZXIuIFdvcmtzIG9ubHkgaW4gZGF0YSBtb2RlIChhZnRlciBgb25yZWFkeWAgZXZlbnQpLCBpZ25vcmVkXG4gICAqIG90aGVyd2lzZVxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2h1bmsgQVNDSUkgc3RyaW5nIChxdW90ZWQtcHJpbnRhYmxlLCBiYXNlNjQgZXRjLikgdG8gYmUgc2VudCB0byB0aGUgc2VydmVyXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IElmIHRydWUsIGl0IGlzIHNhZmUgdG8gc2VuZCBtb3JlIGRhdGEsIGlmIGZhbHNlLCB5b3UgKnNob3VsZCogd2FpdCBmb3IgdGhlIG9uZHJhaW4gZXZlbnQgYmVmb3JlIHNlbmRpbmcgbW9yZVxuICAgKi9cbiAgc2VuZCAoY2h1bmspIHtcbiAgICAvLyB3b3JrcyBvbmx5IGluIGRhdGEgbW9kZVxuICAgIGlmICghdGhpcy5fZGF0YU1vZGUpIHtcbiAgICAgIC8vIHRoaXMgbGluZSBzaG91bGQgbmV2ZXIgYmUgcmVhY2hlZCBidXQgaWYgaXQgZG9lcyxcbiAgICAgIC8vIGFjdCBsaWtlIGV2ZXJ5dGhpbmcncyBub3JtYWwuXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIC8vIFRPRE86IGlmIHRoZSBjaHVuayBpcyBhbiBhcnJheWJ1ZmZlciwgdXNlIGEgc2VwYXJhdGUgZnVuY3Rpb24gdG8gc2VuZCB0aGUgZGF0YVxuICAgIHJldHVybiB0aGlzLl9zZW5kU3RyaW5nKGNodW5rKVxuICB9XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGF0IGEgZGF0YSBzdHJlYW0gZm9yIHRoZSBzb2NrZXQgaXMgZW5kZWQuIFdvcmtzIG9ubHkgaW4gZGF0YVxuICAgKiBtb2RlIChhZnRlciBgb25yZWFkeWAgZXZlbnQpLCBpZ25vcmVkIG90aGVyd2lzZS4gVXNlIGl0IHdoZW4geW91IGFyZSBkb25lXG4gICAqIHdpdGggc2VuZGluZyB0aGUgbWFpbC4gVGhpcyBtZXRob2QgZG9lcyBub3QgY2xvc2UgdGhlIHNvY2tldC4gT25jZSB0aGUgbWFpbFxuICAgKiBoYXMgYmVlbiBxdWV1ZWQgYnkgdGhlIHNlcnZlciwgYG9uZG9uZWAgYW5kIGBvbmlkbGVgIGFyZSBlbWl0dGVkLlxuICAgKlxuICAgKiBAcGFyYW0ge0J1ZmZlcn0gW2NodW5rXSBDaHVuayBvZiBkYXRhIHRvIGJlIHNlbnQgdG8gdGhlIHNlcnZlclxuICAgKi9cbiAgZW5kIChjaHVuaykge1xuICAgIC8vIHdvcmtzIG9ubHkgaW4gZGF0YSBtb2RlXG4gICAgaWYgKCF0aGlzLl9kYXRhTW9kZSkge1xuICAgICAgLy8gdGhpcyBsaW5lIHNob3VsZCBuZXZlciBiZSByZWFjaGVkIGJ1dCBpZiBpdCBkb2VzLFxuICAgICAgLy8gYWN0IGxpa2UgZXZlcnl0aGluZydzIG5vcm1hbC5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkge1xuICAgICAgdGhpcy5zZW5kKGNodW5rKVxuICAgIH1cblxuICAgIC8vIHJlZGlyZWN0IG91dHB1dCBmcm9tIHRoZSBzZXJ2ZXIgdG8gX2FjdGlvblN0cmVhbVxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25TdHJlYW1cblxuICAgIC8vIGluZGljYXRlIHRoYXQgdGhlIHN0cmVhbSBoYXMgZW5kZWQgYnkgc2VuZGluZyBhIHNpbmdsZSBkb3Qgb24gaXRzIG93biBsaW5lXG4gICAgLy8gaWYgdGhlIGNsaWVudCBhbHJlYWR5IGNsb3NlZCB0aGUgZGF0YSB3aXRoIFxcclxcbiBubyBuZWVkIHRvIGRvIGl0IGFnYWluXG4gICAgaWYgKHRoaXMuX2xhc3REYXRhQnl0ZXMgPT09ICdcXHJcXG4nKSB7XG4gICAgICB0aGlzLndhaXREcmFpbiA9IHRoaXMuX3NlbmQobmV3IFVpbnQ4QXJyYXkoWzB4MkUsIDB4MEQsIDB4MEFdKS5idWZmZXIpIC8vIC5cXHJcXG5cbiAgICB9IGVsc2UgaWYgKHRoaXMuX2xhc3REYXRhQnl0ZXMuc3Vic3RyKC0xKSA9PT0gJ1xccicpIHtcbiAgICAgIHRoaXMud2FpdERyYWluID0gdGhpcy5fc2VuZChuZXcgVWludDhBcnJheShbMHgwQSwgMHgyRSwgMHgwRCwgMHgwQV0pLmJ1ZmZlcikgLy8gXFxuLlxcclxcblxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLndhaXREcmFpbiA9IHRoaXMuX3NlbmQobmV3IFVpbnQ4QXJyYXkoWzB4MEQsIDB4MEEsIDB4MkUsIDB4MEQsIDB4MEFdKS5idWZmZXIpIC8vIFxcclxcbi5cXHJcXG5cbiAgICB9XG5cbiAgICAvLyBlbmQgZGF0YSBtb2RlLCByZXNldCB0aGUgdmFyaWFibGVzIGZvciBleHRlbmRpbmcgdGhlIHRpbWVvdXQgaW4gZGF0YSBtb2RlXG4gICAgdGhpcy5fZGF0YU1vZGUgPSBmYWxzZVxuICAgIHRoaXMuX3NvY2tldFRpbWVvdXRTdGFydCA9IGZhbHNlXG4gICAgdGhpcy5fc29ja2V0VGltZW91dFBlcmlvZCA9IGZhbHNlXG5cbiAgICByZXR1cm4gdGhpcy53YWl0RHJhaW5cbiAgfVxuXG4gIC8vIFBSSVZBVEUgTUVUSE9EU1xuXG4gIC8vIEVWRU5UIEhBTkRMRVJTIEZPUiBUSEUgU09DS0VUXG5cbiAgLyoqXG4gICAqIENvbm5lY3Rpb24gbGlzdGVuZXIgdGhhdCBpcyBydW4gd2hlbiB0aGUgY29ubmVjdGlvbiB0byB0aGUgc2VydmVyIGlzIG9wZW5lZC5cbiAgICogU2V0cyB1cCBkaWZmZXJlbnQgZXZlbnQgaGFuZGxlcnMgZm9yIHRoZSBvcGVuZWQgc29ja2V0XG4gICAqXG4gICAqIEBldmVudFxuICAgKiBAcGFyYW0ge0V2ZW50fSBldnQgRXZlbnQgb2JqZWN0LiBOb3QgdXNlZFxuICAgKi9cbiAgX29uT3BlbiAoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQgJiYgZXZlbnQuZGF0YSAmJiBldmVudC5kYXRhLnByb3h5SG9zdG5hbWUpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5uYW1lID0gZXZlbnQuZGF0YS5wcm94eUhvc3RuYW1lXG4gICAgfVxuXG4gICAgdGhpcy5zb2NrZXQub25kYXRhID0gdGhpcy5fb25EYXRhLmJpbmQodGhpcylcblxuICAgIHRoaXMuc29ja2V0Lm9uY2xvc2UgPSB0aGlzLl9vbkNsb3NlLmJpbmQodGhpcylcbiAgICB0aGlzLnNvY2tldC5vbmRyYWluID0gdGhpcy5fb25EcmFpbi5iaW5kKHRoaXMpXG5cbiAgICB0aGlzLl9wYXJzZXIub25kYXRhID0gdGhpcy5fb25Db21tYW5kLmJpbmQodGhpcylcblxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25HcmVldGluZ1xuICB9XG5cbiAgLyoqXG4gICAqIERhdGEgbGlzdGVuZXIgZm9yIGNodW5rcyBvZiBkYXRhIGVtaXR0ZWQgYnkgdGhlIHNlcnZlclxuICAgKlxuICAgKiBAZXZlbnRcbiAgICogQHBhcmFtIHtFdmVudH0gZXZ0IEV2ZW50IG9iamVjdC4gU2VlIGBldnQuZGF0YWAgZm9yIHRoZSBjaHVuayByZWNlaXZlZFxuICAgKi9cbiAgX29uRGF0YSAoZXZ0KSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuX3NvY2tldFRpbWVvdXRUaW1lcilcbiAgICB2YXIgc3RyaW5nUGF5bG9hZCA9IG5ldyBUZXh0RGVjb2RlcignVVRGLTgnKS5kZWNvZGUobmV3IFVpbnQ4QXJyYXkoZXZ0LmRhdGEpKVxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ1NFUlZFUjogJyArIHN0cmluZ1BheWxvYWQpXG4gICAgdGhpcy5fcGFyc2VyLnNlbmQoc3RyaW5nUGF5bG9hZClcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3JlIGRhdGEgY2FuIGJlIGJ1ZmZlcmVkIGluIHRoZSBzb2NrZXQsIGB3YWl0RHJhaW5gIGlzIHJlc2V0IHRvIGZhbHNlXG4gICAqXG4gICAqIEBldmVudFxuICAgKiBAcGFyYW0ge0V2ZW50fSBldnQgRXZlbnQgb2JqZWN0LiBOb3QgdXNlZFxuICAgKi9cbiAgX29uRHJhaW4gKCkge1xuICAgIHRoaXMud2FpdERyYWluID0gZmFsc2VcbiAgICB0aGlzLm9uZHJhaW4oKVxuICB9XG5cbiAgLyoqXG4gICAqIEVycm9yIGhhbmRsZXIgZm9yIHRoZSBzb2NrZXRcbiAgICpcbiAgICogQGV2ZW50XG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2dCBFdmVudCBvYmplY3QuIFNlZSBldnQuZGF0YSBmb3IgdGhlIGVycm9yXG4gICAqL1xuICBfb25FcnJvciAoZXZ0KSB7XG4gICAgaWYgKGV2dCBpbnN0YW5jZW9mIEVycm9yICYmIGV2dC5tZXNzYWdlKSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihERUJVR19UQUcsIGV2dClcbiAgICAgIHRoaXMub25lcnJvcihldnQpXG4gICAgfSBlbHNlIGlmIChldnQgJiYgZXZ0LmRhdGEgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoREVCVUdfVEFHLCBldnQuZGF0YSlcbiAgICAgIHRoaXMub25lcnJvcihldnQuZGF0YSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoREVCVUdfVEFHLCBuZXcgRXJyb3IoKGV2dCAmJiBldnQuZGF0YSAmJiBldnQuZGF0YS5tZXNzYWdlKSB8fCBldnQuZGF0YSB8fCBldnQgfHwgJ0Vycm9yJykpXG4gICAgICB0aGlzLm9uZXJyb3IobmV3IEVycm9yKChldnQgJiYgZXZ0LmRhdGEgJiYgZXZ0LmRhdGEubWVzc2FnZSkgfHwgZXZ0LmRhdGEgfHwgZXZ0IHx8ICdFcnJvcicpKVxuICAgIH1cblxuICAgIHRoaXMuY2xvc2UoKVxuICB9XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGF0IHRoZSBzb2NrZXQgaGFzIGJlZW4gY2xvc2VkXG4gICAqXG4gICAqIEBldmVudFxuICAgKiBAcGFyYW0ge0V2ZW50fSBldnQgRXZlbnQgb2JqZWN0LiBOb3QgdXNlZFxuICAgKi9cbiAgX29uQ2xvc2UgKCkge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ1NvY2tldCBjbG9zZWQuJylcbiAgICB0aGlzLl9kZXN0cm95KClcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGlzIG5vdCBhIHNvY2tldCBkYXRhIGhhbmRsZXIgYnV0IHRoZSBoYW5kbGVyIGZvciBkYXRhIGVtaXR0ZWQgYnkgdGhlIHBhcnNlcixcbiAgICogc28gdGhpcyBkYXRhIGlzIHNhZmUgdG8gdXNlIGFzIGl0IGlzIGFsd2F5cyBjb21wbGV0ZSAoc2VydmVyIG1pZ2h0IHNlbmQgcGFydGlhbCBjaHVua3MpXG4gICAqXG4gICAqIEBldmVudFxuICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCBQYXJzZWQgZGF0YVxuICAgKi9cbiAgX29uQ29tbWFuZCAoY29tbWFuZCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fY3VycmVudEFjdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5fY3VycmVudEFjdGlvbihjb21tYW5kKVxuICAgIH1cbiAgfVxuXG4gIF9vblRpbWVvdXQgKCkge1xuICAgIC8vIGluZm9ybSBhYm91dCB0aGUgdGltZW91dCBhbmQgc2h1dCBkb3duXG4gICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdTb2NrZXQgdGltZWQgb3V0IScpXG4gICAgdGhpcy5fb25FcnJvcihlcnJvcilcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIHRoYXQgdGhlIGNvbm5lY3Rpb24gaXMgY2xvc2VkIGFuZCBzdWNoXG4gICAqL1xuICBfZGVzdHJveSAoKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuX3NvY2tldFRpbWVvdXRUaW1lcilcblxuICAgIGlmICghdGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZVxuICAgICAgdGhpcy5vbmNsb3NlKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2VuZHMgYSBzdHJpbmcgdG8gdGhlIHNvY2tldC5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGNodW5rIEFTQ0lJIHN0cmluZyAocXVvdGVkLXByaW50YWJsZSwgYmFzZTY0IGV0Yy4pIHRvIGJlIHNlbnQgdG8gdGhlIHNlcnZlclxuICAgKiBAcmV0dXJuIHtCb29sZWFufSBJZiB0cnVlLCBpdCBpcyBzYWZlIHRvIHNlbmQgbW9yZSBkYXRhLCBpZiBmYWxzZSwgeW91ICpzaG91bGQqIHdhaXQgZm9yIHRoZSBvbmRyYWluIGV2ZW50IGJlZm9yZSBzZW5kaW5nIG1vcmVcbiAgICovXG4gIF9zZW5kU3RyaW5nIChjaHVuaykge1xuICAgIC8vIGVzY2FwZSBkb3RzXG4gICAgaWYgKCF0aGlzLm9wdGlvbnMuZGlzYWJsZUVzY2FwaW5nKSB7XG4gICAgICBjaHVuayA9IGNodW5rLnJlcGxhY2UoL1xcblxcLi9nLCAnXFxuLi4nKVxuICAgICAgaWYgKCh0aGlzLl9sYXN0RGF0YUJ5dGVzLnN1YnN0cigtMSkgPT09ICdcXG4nIHx8ICF0aGlzLl9sYXN0RGF0YUJ5dGVzKSAmJiBjaHVuay5jaGFyQXQoMCkgPT09ICcuJykge1xuICAgICAgICBjaHVuayA9ICcuJyArIGNodW5rXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gS2VlcGluZyBleWUgb24gdGhlIGxhc3QgYnl0ZXMgc2VudCwgdG8gc2VlIGlmIHRoZXJlIGlzIGEgPENSPjxMRj4gc2VxdWVuY2VcbiAgICAvLyBhdCB0aGUgZW5kIHdoaWNoIGlzIG5lZWRlZCB0byBlbmQgdGhlIGRhdGEgc3RyZWFtXG4gICAgaWYgKGNodW5rLmxlbmd0aCA+IDIpIHtcbiAgICAgIHRoaXMuX2xhc3REYXRhQnl0ZXMgPSBjaHVuay5zdWJzdHIoLTIpXG4gICAgfSBlbHNlIGlmIChjaHVuay5sZW5ndGggPT09IDEpIHtcbiAgICAgIHRoaXMuX2xhc3REYXRhQnl0ZXMgPSB0aGlzLl9sYXN0RGF0YUJ5dGVzLnN1YnN0cigtMSkgKyBjaHVua1xuICAgIH1cblxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ1NlbmRpbmcgJyArIGNodW5rLmxlbmd0aCArICcgYnl0ZXMgb2YgcGF5bG9hZCcpXG5cbiAgICAvLyBwYXNzIHRoZSBjaHVuayB0byB0aGUgc29ja2V0XG4gICAgdGhpcy53YWl0RHJhaW4gPSB0aGlzLl9zZW5kKG5ldyBUZXh0RW5jb2RlcignVVRGLTgnKS5lbmNvZGUoY2h1bmspLmJ1ZmZlcilcbiAgICByZXR1cm4gdGhpcy53YWl0RHJhaW5cbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kIGEgc3RyaW5nIGNvbW1hbmQgdG8gdGhlIHNlcnZlciwgYWxzbyBhcHBlbmQgXFxyXFxuIGlmIG5lZWRlZFxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBiZSBzZW50IHRvIHRoZSBzZXJ2ZXJcbiAgICovXG4gIF9zZW5kQ29tbWFuZCAoc3RyKSB7XG4gICAgdGhpcy53YWl0RHJhaW4gPSB0aGlzLl9zZW5kKG5ldyBUZXh0RW5jb2RlcignVVRGLTgnKS5lbmNvZGUoc3RyICsgKHN0ci5zdWJzdHIoLTIpICE9PSAnXFxyXFxuJyA/ICdcXHJcXG4nIDogJycpKS5idWZmZXIpXG4gIH1cblxuICBfc2VuZCAoYnVmZmVyKSB7XG4gICAgdGhpcy5fc2V0VGltZW91dChidWZmZXIuYnl0ZUxlbmd0aClcbiAgICByZXR1cm4gdGhpcy5zb2NrZXQuc2VuZChidWZmZXIpXG4gIH1cblxuICBfc2V0VGltZW91dCAoYnl0ZUxlbmd0aCkge1xuICAgIHZhciBwcm9sb25nUGVyaW9kID0gTWF0aC5mbG9vcihieXRlTGVuZ3RoICogdGhpcy50aW1lb3V0U29ja2V0TXVsdGlwbGllcilcbiAgICB2YXIgdGltZW91dFxuXG4gICAgaWYgKHRoaXMuX2RhdGFNb2RlKSB7XG4gICAgICAvLyB3ZSdyZSBpbiBkYXRhIG1vZGUsIHNvIHdlIGNvdW50IG9ubHkgb25lIHRpbWVvdXQgdGhhdCBnZXQgZXh0ZW5kZWQgZm9yIGV2ZXJ5IHNlbmQoKS5cbiAgICAgIHZhciBub3cgPSBEYXRlLm5vdygpXG5cbiAgICAgIC8vIHRoZSBvbGQgdGltZW91dCBzdGFydCB0aW1lXG4gICAgICB0aGlzLl9zb2NrZXRUaW1lb3V0U3RhcnQgPSB0aGlzLl9zb2NrZXRUaW1lb3V0U3RhcnQgfHwgbm93XG5cbiAgICAgIC8vIHRoZSBvbGQgdGltZW91dCBwZXJpb2QsIG5vcm1hbGl6ZWQgdG8gYSBtaW5pbXVtIG9mIFRJTUVPVVRfU09DS0VUX0xPV0VSX0JPVU5EXG4gICAgICB0aGlzLl9zb2NrZXRUaW1lb3V0UGVyaW9kID0gKHRoaXMuX3NvY2tldFRpbWVvdXRQZXJpb2QgfHwgdGhpcy50aW1lb3V0U29ja2V0TG93ZXJCb3VuZCkgKyBwcm9sb25nUGVyaW9kXG5cbiAgICAgIC8vIHRoZSBuZXcgdGltZW91dCBpcyB0aGUgZGVsdGEgYmV0d2VlbiB0aGUgbmV3IGZpcmluZyB0aW1lICg9IHRpbWVvdXQgcGVyaW9kICsgdGltZW91dCBzdGFydCB0aW1lKSBhbmQgbm93XG4gICAgICB0aW1lb3V0ID0gdGhpcy5fc29ja2V0VGltZW91dFN0YXJ0ICsgdGhpcy5fc29ja2V0VGltZW91dFBlcmlvZCAtIG5vd1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBzZXQgbmV3IHRpbW91dFxuICAgICAgdGltZW91dCA9IHRoaXMudGltZW91dFNvY2tldExvd2VyQm91bmQgKyBwcm9sb25nUGVyaW9kXG4gICAgfVxuXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuX3NvY2tldFRpbWVvdXRUaW1lcikgLy8gY2xlYXIgcGVuZGluZyB0aW1lb3V0c1xuICAgIHRoaXMuX3NvY2tldFRpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQodGhpcy5fb25UaW1lb3V0LmJpbmQodGhpcyksIHRpbWVvdXQpIC8vIGFybSB0aGUgbmV4dCB0aW1lb3V0XG4gIH1cblxuICAvKipcbiAgICogSW50aXRpYXRlIGF1dGhlbnRpY2F0aW9uIHNlcXVlbmNlIGlmIG5lZWRlZFxuICAgKi9cbiAgX2F1dGhlbnRpY2F0ZVVzZXIgKCkge1xuICAgIGlmICghdGhpcy5vcHRpb25zLmF1dGgpIHtcbiAgICAgIC8vIG5vIG5lZWQgdG8gYXV0aGVudGljYXRlLCBhdCBsZWFzdCBubyBkYXRhIGdpdmVuXG4gICAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gdGhpcy5fYWN0aW9uSWRsZVxuICAgICAgdGhpcy5vbmlkbGUoKSAvLyByZWFkeSB0byB0YWtlIG9yZGVyc1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdmFyIGF1dGhcblxuICAgIGlmICghdGhpcy5vcHRpb25zLmF1dGhNZXRob2QgJiYgdGhpcy5vcHRpb25zLmF1dGgueG9hdXRoMikge1xuICAgICAgdGhpcy5vcHRpb25zLmF1dGhNZXRob2QgPSAnWE9BVVRIMidcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmF1dGhNZXRob2QpIHtcbiAgICAgIGF1dGggPSB0aGlzLm9wdGlvbnMuYXV0aE1ldGhvZC50b1VwcGVyQ2FzZSgpLnRyaW0oKVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyB1c2UgZmlyc3Qgc3VwcG9ydGVkXG4gICAgICBhdXRoID0gKHRoaXMuX3N1cHBvcnRlZEF1dGhbMF0gfHwgJ1BMQUlOJykudG9VcHBlckNhc2UoKS50cmltKClcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGF1dGgpIHtcbiAgICAgIGNhc2UgJ0xPR0lOJzpcbiAgICAgICAgLy8gTE9HSU4gaXMgYSAzIHN0ZXAgYXV0aGVudGljYXRpb24gcHJvY2Vzc1xuICAgICAgICAvLyBDOiBBVVRIIExPR0lOXG4gICAgICAgIC8vIEM6IEJBU0U2NChVU0VSKVxuICAgICAgICAvLyBDOiBCQVNFNjQoUEFTUylcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnQXV0aGVudGljYXRpb24gdmlhIEFVVEggTE9HSU4nKVxuICAgICAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gdGhpcy5fYWN0aW9uQVVUSF9MT0dJTl9VU0VSXG4gICAgICAgIHRoaXMuX3NlbmRDb21tYW5kKCdBVVRIIExPR0lOJylcbiAgICAgICAgcmV0dXJuXG4gICAgICBjYXNlICdQTEFJTic6XG4gICAgICAgIC8vIEFVVEggUExBSU4gaXMgYSAxIHN0ZXAgYXV0aGVudGljYXRpb24gcHJvY2Vzc1xuICAgICAgICAvLyBDOiBBVVRIIFBMQUlOIEJBU0U2NChcXDAgVVNFUiBcXDAgUEFTUylcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnQXV0aGVudGljYXRpb24gdmlhIEFVVEggUExBSU4nKVxuICAgICAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gdGhpcy5fYWN0aW9uQVVUSENvbXBsZXRlXG4gICAgICAgIHRoaXMuX3NlbmRDb21tYW5kKFxuICAgICAgICAgIC8vIGNvbnZlcnQgdG8gQkFTRTY0XG4gICAgICAgICAgJ0FVVEggUExBSU4gJyArXG4gICAgICAgICAgZW5jb2RlKFxuICAgICAgICAgICAgLy8gdGhpcy5vcHRpb25zLmF1dGgudXNlcisnXFx1MDAwMCcrXG4gICAgICAgICAgICAnXFx1MDAwMCcgKyAvLyBza2lwIGF1dGhvcml6YXRpb24gaWRlbnRpdHkgYXMgaXQgY2F1c2VzIHByb2JsZW1zIHdpdGggc29tZSBzZXJ2ZXJzXG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMuYXV0aC51c2VyICsgJ1xcdTAwMDAnICtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5hdXRoLnBhc3MpXG4gICAgICAgIClcbiAgICAgICAgcmV0dXJuXG4gICAgICBjYXNlICdYT0FVVEgyJzpcbiAgICAgICAgLy8gU2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2dtYWlsL3hvYXV0aDJfcHJvdG9jb2wjc210cF9wcm90b2NvbF9leGNoYW5nZVxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdBdXRoZW50aWNhdGlvbiB2aWEgQVVUSCBYT0FVVEgyJylcbiAgICAgICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvbkFVVEhfWE9BVVRIMlxuICAgICAgICB0aGlzLl9zZW5kQ29tbWFuZCgnQVVUSCBYT0FVVEgyICcgKyB0aGlzLl9idWlsZFhPQXV0aDJUb2tlbih0aGlzLm9wdGlvbnMuYXV0aC51c2VyLCB0aGlzLm9wdGlvbnMuYXV0aC54b2F1dGgyKSlcbiAgICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fb25FcnJvcihuZXcgRXJyb3IoJ1Vua25vd24gYXV0aGVudGljYXRpb24gbWV0aG9kICcgKyBhdXRoKSlcbiAgfVxuXG4gIC8vIEFDVElPTlMgRk9SIFJFU1BPTlNFUyBGUk9NIFRIRSBTTVRQIFNFUlZFUlxuXG4gIC8qKlxuICAgKiBJbml0aWFsIHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlciwgbXVzdCBoYXZlIGEgc3RhdHVzIDIyMFxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCBQYXJzZWQgY29tbWFuZCBmcm9tIHRoZSBzZXJ2ZXIge3N0YXR1c0NvZGUsIGRhdGEsIGxpbmV9XG4gICAqL1xuICBfYWN0aW9uR3JlZXRpbmcgKGNvbW1hbmQpIHtcbiAgICBpZiAoY29tbWFuZC5zdGF0dXNDb2RlICE9PSAyMjApIHtcbiAgICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKCdJbnZhbGlkIGdyZWV0aW5nOiAnICsgY29tbWFuZC5kYXRhKSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMubG10cCkge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnU2VuZGluZyBMSExPICcgKyB0aGlzLm9wdGlvbnMubmFtZSlcblxuICAgICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvbkxITE9cbiAgICAgIHRoaXMuX3NlbmRDb21tYW5kKCdMSExPICcgKyB0aGlzLm9wdGlvbnMubmFtZSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnU2VuZGluZyBFSExPICcgKyB0aGlzLm9wdGlvbnMubmFtZSlcblxuICAgICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvbkVITE9cbiAgICAgIHRoaXMuX3NlbmRDb21tYW5kKCdFSExPICcgKyB0aGlzLm9wdGlvbnMubmFtZSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzcG9uc2UgdG8gTEhMT1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCBQYXJzZWQgY29tbWFuZCBmcm9tIHRoZSBzZXJ2ZXIge3N0YXR1c0NvZGUsIGRhdGEsIGxpbmV9XG4gICAqL1xuICBfYWN0aW9uTEhMTyAoY29tbWFuZCkge1xuICAgIGlmICghY29tbWFuZC5zdWNjZXNzKSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihERUJVR19UQUcsICdMSExPIG5vdCBzdWNjZXNzZnVsJylcbiAgICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKGNvbW1hbmQuZGF0YSkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBQcm9jZXNzIGFzIEVITE8gcmVzcG9uc2VcbiAgICB0aGlzLl9hY3Rpb25FSExPKGNvbW1hbmQpXG4gIH1cblxuICAvKipcbiAgICogUmVzcG9uc2UgdG8gRUhMTy4gSWYgdGhlIHJlc3BvbnNlIGlzIGFuIGVycm9yLCB0cnkgSEVMTyBpbnN0ZWFkXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIFBhcnNlZCBjb21tYW5kIGZyb20gdGhlIHNlcnZlciB7c3RhdHVzQ29kZSwgZGF0YSwgbGluZX1cbiAgICovXG4gIF9hY3Rpb25FSExPIChjb21tYW5kKSB7XG4gICAgdmFyIG1hdGNoXG5cbiAgICBpZiAoIWNvbW1hbmQuc3VjY2Vzcykge1xuICAgICAgaWYgKCF0aGlzLl9zZWN1cmVNb2RlICYmIHRoaXMub3B0aW9ucy5yZXF1aXJlVExTKSB7XG4gICAgICAgIHZhciBlcnJNc2cgPSAnU1RBUlRUTFMgbm90IHN1cHBvcnRlZCB3aXRob3V0IEVITE8nXG4gICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKERFQlVHX1RBRywgZXJyTXNnKVxuICAgICAgICB0aGlzLl9vbkVycm9yKG5ldyBFcnJvcihlcnJNc2cpKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgLy8gVHJ5IEhFTE8gaW5zdGVhZFxuICAgICAgdGhpcy5sb2dnZXIud2FybihERUJVR19UQUcsICdFSExPIG5vdCBzdWNjZXNzZnVsLCB0cnlpbmcgSEVMTyAnICsgdGhpcy5vcHRpb25zLm5hbWUpXG4gICAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gdGhpcy5fYWN0aW9uSEVMT1xuICAgICAgdGhpcy5fc2VuZENvbW1hbmQoJ0hFTE8gJyArIHRoaXMub3B0aW9ucy5uYW1lKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gRGV0ZWN0IGlmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgUExBSU4gYXV0aFxuICAgIGlmIChjb21tYW5kLmxpbmUubWF0Y2goL0FVVEgoPzpcXHMrW15cXG5dKlxccyt8XFxzKylQTEFJTi9pKSkge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnU2VydmVyIHN1cHBvcnRzIEFVVEggUExBSU4nKVxuICAgICAgdGhpcy5fc3VwcG9ydGVkQXV0aC5wdXNoKCdQTEFJTicpXG4gICAgfVxuXG4gICAgLy8gRGV0ZWN0IGlmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgTE9HSU4gYXV0aFxuICAgIGlmIChjb21tYW5kLmxpbmUubWF0Y2goL0FVVEgoPzpcXHMrW15cXG5dKlxccyt8XFxzKylMT0dJTi9pKSkge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnU2VydmVyIHN1cHBvcnRzIEFVVEggTE9HSU4nKVxuICAgICAgdGhpcy5fc3VwcG9ydGVkQXV0aC5wdXNoKCdMT0dJTicpXG4gICAgfVxuXG4gICAgLy8gRGV0ZWN0IGlmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgWE9BVVRIMiBhdXRoXG4gICAgaWYgKGNvbW1hbmQubGluZS5tYXRjaCgvQVVUSCg/OlxccytbXlxcbl0qXFxzK3xcXHMrKVhPQVVUSDIvaSkpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ1NlcnZlciBzdXBwb3J0cyBBVVRIIFhPQVVUSDInKVxuICAgICAgdGhpcy5fc3VwcG9ydGVkQXV0aC5wdXNoKCdYT0FVVEgyJylcbiAgICB9XG5cbiAgICAvLyBEZXRlY3QgbWF4aW11bSBhbGxvd2VkIG1lc3NhZ2Ugc2l6ZVxuICAgIGlmICgobWF0Y2ggPSBjb21tYW5kLmxpbmUubWF0Y2goL1NJWkUgKFxcZCspL2kpKSAmJiBOdW1iZXIobWF0Y2hbMV0pKSB7XG4gICAgICBjb25zdCBtYXhBbGxvd2VkU2l6ZSA9IE51bWJlcihtYXRjaFsxXSlcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ01heGltdW0gYWxsb3dkIG1lc3NhZ2Ugc2l6ZTogJyArIG1heEFsbG93ZWRTaXplKVxuICAgIH1cblxuICAgIC8vIERldGVjdCBpZiB0aGUgc2VydmVyIHN1cHBvcnRzIFNUQVJUVExTXG4gICAgaWYgKCF0aGlzLl9zZWN1cmVNb2RlKSB7XG4gICAgICBpZiAoKGNvbW1hbmQubGluZS5tYXRjaCgvWyAtXVNUQVJUVExTXFxzPyQvbWkpICYmICF0aGlzLm9wdGlvbnMuaWdub3JlVExTKSB8fCAhIXRoaXMub3B0aW9ucy5yZXF1aXJlVExTKSB7XG4gICAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25TVEFSVFRMU1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdTZW5kaW5nIFNUQVJUVExTJylcbiAgICAgICAgdGhpcy5fc2VuZENvbW1hbmQoJ1NUQVJUVExTJylcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fYXV0aGVudGljYXRlVXNlcigpXG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyBzZXJ2ZXIgcmVzcG9uc2UgZm9yIFNUQVJUVExTIGNvbW1hbmQuIElmIHRoZXJlJ3MgYW4gZXJyb3JcbiAgICogdHJ5IEhFTE8gaW5zdGVhZCwgb3RoZXJ3aXNlIGluaXRpYXRlIFRMUyB1cGdyYWRlLiBJZiB0aGUgdXBncmFkZVxuICAgKiBzdWNjZWVkZXMgcmVzdGFydCB0aGUgRUhMT1xuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIE1lc3NhZ2UgZnJvbSB0aGUgc2VydmVyXG4gICAqL1xuICBfYWN0aW9uU1RBUlRUTFMgKGNvbW1hbmQpIHtcbiAgICBpZiAoIWNvbW1hbmQuc3VjY2Vzcykge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoREVCVUdfVEFHLCAnU1RBUlRUTFMgbm90IHN1Y2Nlc3NmdWwnKVxuICAgICAgdGhpcy5fb25FcnJvcihuZXcgRXJyb3IoY29tbWFuZC5kYXRhKSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuX3NlY3VyZU1vZGUgPSB0cnVlXG4gICAgdGhpcy5zb2NrZXQudXBncmFkZVRvU2VjdXJlKClcblxuICAgIC8vIHJlc3RhcnQgcHJvdG9jb2wgZmxvd1xuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25FSExPXG4gICAgdGhpcy5fc2VuZENvbW1hbmQoJ0VITE8gJyArIHRoaXMub3B0aW9ucy5uYW1lKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc3BvbnNlIHRvIEhFTE9cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbW1hbmQgUGFyc2VkIGNvbW1hbmQgZnJvbSB0aGUgc2VydmVyIHtzdGF0dXNDb2RlLCBkYXRhLCBsaW5lfVxuICAgKi9cbiAgX2FjdGlvbkhFTE8gKGNvbW1hbmQpIHtcbiAgICBpZiAoIWNvbW1hbmQuc3VjY2Vzcykge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoREVCVUdfVEFHLCAnSEVMTyBub3Qgc3VjY2Vzc2Z1bCcpXG4gICAgICB0aGlzLl9vbkVycm9yKG5ldyBFcnJvcihjb21tYW5kLmRhdGEpKVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHRoaXMuX2F1dGhlbnRpY2F0ZVVzZXIoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc3BvbnNlIHRvIEFVVEggTE9HSU4sIGlmIHN1Y2Nlc3NmdWwgZXhwZWN0cyBiYXNlNjQgZW5jb2RlZCB1c2VybmFtZVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCBQYXJzZWQgY29tbWFuZCBmcm9tIHRoZSBzZXJ2ZXIge3N0YXR1c0NvZGUsIGRhdGEsIGxpbmV9XG4gICAqL1xuICBfYWN0aW9uQVVUSF9MT0dJTl9VU0VSIChjb21tYW5kKSB7XG4gICAgaWYgKGNvbW1hbmQuc3RhdHVzQ29kZSAhPT0gMzM0IHx8IGNvbW1hbmQuZGF0YSAhPT0gJ1ZYTmxjbTVoYldVNicpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKERFQlVHX1RBRywgJ0FVVEggTE9HSU4gVVNFUiBub3Qgc3VjY2Vzc2Z1bDogJyArIGNvbW1hbmQuZGF0YSlcbiAgICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKCdJbnZhbGlkIGxvZ2luIHNlcXVlbmNlIHdoaWxlIHdhaXRpbmcgZm9yIFwiMzM0IFZYTmxjbTVoYldVNiBcIjogJyArIGNvbW1hbmQuZGF0YSkpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnQVVUSCBMT0dJTiBVU0VSIHN1Y2Nlc3NmdWwnKVxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25BVVRIX0xPR0lOX1BBU1NcbiAgICB0aGlzLl9zZW5kQ29tbWFuZChlbmNvZGUodGhpcy5vcHRpb25zLmF1dGgudXNlcikpXG4gIH1cblxuICAvKipcbiAgICogUmVzcG9uc2UgdG8gQVVUSCBMT0dJTiB1c2VybmFtZSwgaWYgc3VjY2Vzc2Z1bCBleHBlY3RzIGJhc2U2NCBlbmNvZGVkIHBhc3N3b3JkXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIFBhcnNlZCBjb21tYW5kIGZyb20gdGhlIHNlcnZlciB7c3RhdHVzQ29kZSwgZGF0YSwgbGluZX1cbiAgICovXG4gIF9hY3Rpb25BVVRIX0xPR0lOX1BBU1MgKGNvbW1hbmQpIHtcbiAgICBpZiAoY29tbWFuZC5zdGF0dXNDb2RlICE9PSAzMzQgfHwgY29tbWFuZC5kYXRhICE9PSAnVUdGemMzZHZjbVE2Jykge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoREVCVUdfVEFHLCAnQVVUSCBMT0dJTiBQQVNTIG5vdCBzdWNjZXNzZnVsOiAnICsgY29tbWFuZC5kYXRhKVxuICAgICAgdGhpcy5fb25FcnJvcihuZXcgRXJyb3IoJ0ludmFsaWQgbG9naW4gc2VxdWVuY2Ugd2hpbGUgd2FpdGluZyBmb3IgXCIzMzQgVUdGemMzZHZjbVE2IFwiOiAnICsgY29tbWFuZC5kYXRhKSlcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdBVVRIIExPR0lOIFBBU1Mgc3VjY2Vzc2Z1bCcpXG4gICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvbkFVVEhDb21wbGV0ZVxuICAgIHRoaXMuX3NlbmRDb21tYW5kKGVuY29kZSh0aGlzLm9wdGlvbnMuYXV0aC5wYXNzKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNwb25zZSB0byBBVVRIIFhPQVVUSDIgdG9rZW4sIGlmIGVycm9yIG9jY3VycyBzZW5kIGVtcHR5IHJlc3BvbnNlXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIFBhcnNlZCBjb21tYW5kIGZyb20gdGhlIHNlcnZlciB7c3RhdHVzQ29kZSwgZGF0YSwgbGluZX1cbiAgICovXG4gIF9hY3Rpb25BVVRIX1hPQVVUSDIgKGNvbW1hbmQpIHtcbiAgICBpZiAoIWNvbW1hbmQuc3VjY2Vzcykge1xuICAgICAgdGhpcy5sb2dnZXIud2FybihERUJVR19UQUcsICdFcnJvciBkdXJpbmcgQVVUSCBYT0FVVEgyLCBzZW5kaW5nIGVtcHR5IHJlc3BvbnNlJylcbiAgICAgIHRoaXMuX3NlbmRDb21tYW5kKCcnKVxuICAgICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvbkFVVEhDb21wbGV0ZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9hY3Rpb25BVVRIQ29tcGxldGUoY29tbWFuZClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGF1dGhlbnRpY2F0aW9uIHN1Y2NlZWRlZCBvciBub3QuIElmIHN1Y2Nlc3NmdWxseSBhdXRoZW50aWNhdGVkXG4gICAqIGVtaXQgYGlkbGVgIHRvIGluZGljYXRlIHRoYXQgYW4gZS1tYWlsIGNhbiBiZSBzZW50IHVzaW5nIHRoaXMgY29ubmVjdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCBQYXJzZWQgY29tbWFuZCBmcm9tIHRoZSBzZXJ2ZXIge3N0YXR1c0NvZGUsIGRhdGEsIGxpbmV9XG4gICAqL1xuICBfYWN0aW9uQVVUSENvbXBsZXRlIChjb21tYW5kKSB7XG4gICAgaWYgKCFjb21tYW5kLnN1Y2Nlc3MpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZDogJyArIGNvbW1hbmQuZGF0YSlcbiAgICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKGNvbW1hbmQuZGF0YSkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdBdXRoZW50aWNhdGlvbiBzdWNjZXNzZnVsLicpXG5cbiAgICB0aGlzLl9hdXRoZW50aWNhdGVkQXMgPSB0aGlzLm9wdGlvbnMuYXV0aC51c2VyXG5cbiAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gdGhpcy5fYWN0aW9uSWRsZVxuICAgIHRoaXMub25pZGxlKCkgLy8gcmVhZHkgdG8gdGFrZSBvcmRlcnNcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgaWRsZSBhbmQgdGhlIHNlcnZlciBlbWl0cyB0aW1lb3V0XG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIFBhcnNlZCBjb21tYW5kIGZyb20gdGhlIHNlcnZlciB7c3RhdHVzQ29kZSwgZGF0YSwgbGluZX1cbiAgICovXG4gIF9hY3Rpb25JZGxlIChjb21tYW5kKSB7XG4gICAgaWYgKGNvbW1hbmQuc3RhdHVzQ29kZSA+IDMwMCkge1xuICAgICAgdGhpcy5fb25FcnJvcihuZXcgRXJyb3IoY29tbWFuZC5saW5lKSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKGNvbW1hbmQuZGF0YSkpXG4gIH1cblxuICAvKipcbiAgICogUmVzcG9uc2UgdG8gTUFJTCBGUk9NIGNvbW1hbmQuIFByb2NlZWQgdG8gZGVmaW5pbmcgUkNQVCBUTyBsaXN0IGlmIHN1Y2Nlc3NmdWxcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbW1hbmQgUGFyc2VkIGNvbW1hbmQgZnJvbSB0aGUgc2VydmVyIHtzdGF0dXNDb2RlLCBkYXRhLCBsaW5lfVxuICAgKi9cbiAgX2FjdGlvbk1BSUwgKGNvbW1hbmQpIHtcbiAgICBpZiAoIWNvbW1hbmQuc3VjY2Vzcykge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnTUFJTCBGUk9NIHVuc3VjY2Vzc2Z1bDogJyArIGNvbW1hbmQuZGF0YSlcbiAgICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKGNvbW1hbmQuZGF0YSkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX2VudmVsb3BlLnJjcHRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKCdDYW5cXCd0IHNlbmQgbWFpbCAtIG5vIHJlY2lwaWVudHMgZGVmaW5lZCcpKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdNQUlMIEZST00gc3VjY2Vzc2Z1bCwgcHJvY2VlZGluZyB3aXRoICcgKyB0aGlzLl9lbnZlbG9wZS5yY3B0UXVldWUubGVuZ3RoICsgJyByZWNpcGllbnRzJylcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ0FkZGluZyByZWNpcGllbnQuLi4nKVxuICAgICAgdGhpcy5fZW52ZWxvcGUuY3VyUmVjaXBpZW50ID0gdGhpcy5fZW52ZWxvcGUucmNwdFF1ZXVlLnNoaWZ0KClcbiAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25SQ1BUXG4gICAgICB0aGlzLl9zZW5kQ29tbWFuZCgnUkNQVCBUTzo8JyArIHRoaXMuX2VudmVsb3BlLmN1clJlY2lwaWVudCArICc+JylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzcG9uc2UgdG8gYSBSQ1BUIFRPIGNvbW1hbmQuIElmIHRoZSBjb21tYW5kIGlzIHVuc3VjY2Vzc2Z1bCwgdHJ5IHRoZSBuZXh0IG9uZSxcbiAgICogYXMgdGhpcyBtaWdodCBiZSByZWxhdGVkIG9ubHkgdG8gdGhlIGN1cnJlbnQgcmVjaXBpZW50LCBub3QgYSBnbG9iYWwgZXJyb3IsIHNvXG4gICAqIHRoZSBmb2xsb3dpbmcgcmVjaXBpZW50cyBtaWdodCBzdGlsbCBiZSB2YWxpZFxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCBQYXJzZWQgY29tbWFuZCBmcm9tIHRoZSBzZXJ2ZXIge3N0YXR1c0NvZGUsIGRhdGEsIGxpbmV9XG4gICAqL1xuICBfYWN0aW9uUkNQVCAoY29tbWFuZCkge1xuICAgIGlmICghY29tbWFuZC5zdWNjZXNzKSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKERFQlVHX1RBRywgJ1JDUFQgVE8gZmFpbGVkIGZvcjogJyArIHRoaXMuX2VudmVsb3BlLmN1clJlY2lwaWVudClcbiAgICAgIC8vIHRoaXMgaXMgYSBzb2Z0IGVycm9yXG4gICAgICB0aGlzLl9lbnZlbG9wZS5yY3B0RmFpbGVkLnB1c2godGhpcy5fZW52ZWxvcGUuY3VyUmVjaXBpZW50KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9lbnZlbG9wZS5yZXNwb25zZVF1ZXVlLnB1c2godGhpcy5fZW52ZWxvcGUuY3VyUmVjaXBpZW50KVxuICAgIH1cblxuICAgIGlmICghdGhpcy5fZW52ZWxvcGUucmNwdFF1ZXVlLmxlbmd0aCkge1xuICAgICAgaWYgKHRoaXMuX2VudmVsb3BlLnJjcHRGYWlsZWQubGVuZ3RoIDwgdGhpcy5fZW52ZWxvcGUudG8ubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25EQVRBXG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ1JDUFQgVE8gZG9uZSwgcHJvY2VlZGluZyB3aXRoIHBheWxvYWQnKVxuICAgICAgICB0aGlzLl9zZW5kQ29tbWFuZCgnREFUQScpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9vbkVycm9yKG5ldyBFcnJvcignQ2FuXFwndCBzZW5kIG1haWwgLSBhbGwgcmVjaXBpZW50cyB3ZXJlIHJlamVjdGVkJykpXG4gICAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25JZGxlXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ0FkZGluZyByZWNpcGllbnQuLi4nKVxuICAgICAgdGhpcy5fZW52ZWxvcGUuY3VyUmVjaXBpZW50ID0gdGhpcy5fZW52ZWxvcGUucmNwdFF1ZXVlLnNoaWZ0KClcbiAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25SQ1BUXG4gICAgICB0aGlzLl9zZW5kQ29tbWFuZCgnUkNQVCBUTzo8JyArIHRoaXMuX2VudmVsb3BlLmN1clJlY2lwaWVudCArICc+JylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzcG9uc2UgdG8gdGhlIFJTRVQgY29tbWFuZC4gSWYgc3VjY2Vzc2Z1bCwgY2xlYXIgdGhlIGN1cnJlbnQgYXV0aGVudGljYXRpb25cbiAgICogaW5mb3JtYXRpb24gYW5kIHJlYXV0aGVudGljYXRlLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCBQYXJzZWQgY29tbWFuZCBmcm9tIHRoZSBzZXJ2ZXIge3N0YXR1c0NvZGUsIGRhdGEsIGxpbmV9XG4gICAqL1xuICBfYWN0aW9uUlNFVCAoY29tbWFuZCkge1xuICAgIGlmICghY29tbWFuZC5zdWNjZXNzKSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihERUJVR19UQUcsICdSU0VUIHVuc3VjY2Vzc2Z1bCAnICsgY29tbWFuZC5kYXRhKVxuICAgICAgdGhpcy5fb25FcnJvcihuZXcgRXJyb3IoY29tbWFuZC5kYXRhKSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuX2F1dGhlbnRpY2F0ZWRBcyA9IG51bGxcbiAgICB0aGlzLl9hdXRoZW50aWNhdGVVc2VyKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNwb25zZSB0byB0aGUgREFUQSBjb21tYW5kLiBTZXJ2ZXIgaXMgbm93IHdhaXRpbmcgZm9yIGEgbWVzc2FnZSwgc28gZW1pdCBgb25yZWFkeWBcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbW1hbmQgUGFyc2VkIGNvbW1hbmQgZnJvbSB0aGUgc2VydmVyIHtzdGF0dXNDb2RlLCBkYXRhLCBsaW5lfVxuICAgKi9cbiAgX2FjdGlvbkRBVEEgKGNvbW1hbmQpIHtcbiAgICAvLyByZXNwb25zZSBzaG91bGQgYmUgMzU0IGJ1dCBhY2NvcmRpbmcgdG8gdGhpcyBpc3N1ZSBodHRwczovL2dpdGh1Yi5jb20vZWxlaXRoL2VtYWlsanMvaXNzdWVzLzI0XG4gICAgLy8gc29tZSBzZXJ2ZXJzIG1pZ2h0IHVzZSAyNTAgaW5zdGVhZFxuICAgIGlmIChbMjUwLCAzNTRdLmluZGV4T2YoY29tbWFuZC5zdGF0dXNDb2RlKSA8IDApIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKERFQlVHX1RBRywgJ0RBVEEgdW5zdWNjZXNzZnVsICcgKyBjb21tYW5kLmRhdGEpXG4gICAgICB0aGlzLl9vbkVycm9yKG5ldyBFcnJvcihjb21tYW5kLmRhdGEpKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fZGF0YU1vZGUgPSB0cnVlXG4gICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvbklkbGVcbiAgICB0aGlzLm9ucmVhZHkodGhpcy5fZW52ZWxvcGUucmNwdEZhaWxlZClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNwb25zZSBmcm9tIHRoZSBzZXJ2ZXIsIG9uY2UgdGhlIG1lc3NhZ2Ugc3RyZWFtIGhhcyBlbmRlZCB3aXRoIDxDUj48TEY+LjxDUj48TEY+XG4gICAqIEVtaXRzIGBvbmRvbmVgLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCBQYXJzZWQgY29tbWFuZCBmcm9tIHRoZSBzZXJ2ZXIge3N0YXR1c0NvZGUsIGRhdGEsIGxpbmV9XG4gICAqL1xuICBfYWN0aW9uU3RyZWFtIChjb21tYW5kKSB7XG4gICAgdmFyIHJjcHRcblxuICAgIGlmICh0aGlzLm9wdGlvbnMubG10cCkge1xuICAgICAgLy8gTE1UUCByZXR1cm5zIGEgcmVzcG9uc2UgY29kZSBmb3IgKmV2ZXJ5KiBzdWNjZXNzZnVsbHkgc2V0IHJlY2lwaWVudFxuICAgICAgLy8gRm9yIGV2ZXJ5IHJlY2lwaWVudCB0aGUgbWVzc2FnZSBtaWdodCBzdWNjZWVkIG9yIGZhaWwgaW5kaXZpZHVhbGx5XG5cbiAgICAgIHJjcHQgPSB0aGlzLl9lbnZlbG9wZS5yZXNwb25zZVF1ZXVlLnNoaWZ0KClcbiAgICAgIGlmICghY29tbWFuZC5zdWNjZXNzKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKERFQlVHX1RBRywgJ0xvY2FsIGRlbGl2ZXJ5IHRvICcgKyByY3B0ICsgJyBmYWlsZWQuJylcbiAgICAgICAgdGhpcy5fZW52ZWxvcGUucmNwdEZhaWxlZC5wdXNoKHJjcHQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihERUJVR19UQUcsICdMb2NhbCBkZWxpdmVyeSB0byAnICsgcmNwdCArICcgc3VjY2VlZGVkLicpXG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9lbnZlbG9wZS5yZXNwb25zZVF1ZXVlLmxlbmd0aCkge1xuICAgICAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gdGhpcy5fYWN0aW9uU3RyZWFtXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gdGhpcy5fYWN0aW9uSWRsZVxuICAgICAgdGhpcy5vbmRvbmUodHJ1ZSlcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRm9yIFNNVFAgdGhlIG1lc3NhZ2UgZWl0aGVyIGZhaWxzIG9yIHN1Y2NlZWRzLCB0aGVyZSBpcyBubyBpbmZvcm1hdGlvblxuICAgICAgLy8gYWJvdXQgaW5kaXZpZHVhbCByZWNpcGllbnRzXG5cbiAgICAgIGlmICghY29tbWFuZC5zdWNjZXNzKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKERFQlVHX1RBRywgJ01lc3NhZ2Ugc2VuZGluZyBmYWlsZWQuJylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ01lc3NhZ2Ugc2VudCBzdWNjZXNzZnVsbHkuJylcbiAgICAgIH1cblxuICAgICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvbklkbGVcbiAgICAgIHRoaXMub25kb25lKCEhY29tbWFuZC5zdWNjZXNzKVxuICAgIH1cblxuICAgIC8vIElmIHRoZSBjbGllbnQgd2FudGVkIHRvIGRvIHNvbWV0aGluZyBlbHNlIChlZy4gdG8gcXVpdCksIGRvIG5vdCBmb3JjZSBpZGxlXG4gICAgaWYgKHRoaXMuX2N1cnJlbnRBY3Rpb24gPT09IHRoaXMuX2FjdGlvbklkbGUpIHtcbiAgICAgIC8vIFdhaXRpbmcgZm9yIG5ldyBjb25uZWN0aW9uc1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnSWRsaW5nIHdoaWxlIHdhaXRpbmcgZm9yIG5ldyBjb25uZWN0aW9ucy4uLicpXG4gICAgICB0aGlzLm9uaWRsZSgpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIGxvZ2luIHRva2VuIGZvciBYT0FVVEgyIGF1dGhlbnRpY2F0aW9uIGNvbW1hbmRcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IHVzZXIgRS1tYWlsIGFkZHJlc3Mgb2YgdGhlIHVzZXJcbiAgICogQHBhcmFtIHtTdHJpbmd9IHRva2VuIFZhbGlkIGFjY2VzcyB0b2tlbiBmb3IgdGhlIHVzZXJcbiAgICogQHJldHVybiB7U3RyaW5nfSBCYXNlNjQgZm9ybWF0dGVkIGxvZ2luIHRva2VuXG4gICAqL1xuICBfYnVpbGRYT0F1dGgyVG9rZW4gKHVzZXIsIHRva2VuKSB7XG4gICAgdmFyIGF1dGhEYXRhID0gW1xuICAgICAgJ3VzZXI9JyArICh1c2VyIHx8ICcnKSxcbiAgICAgICdhdXRoPUJlYXJlciAnICsgdG9rZW4sXG4gICAgICAnJyxcbiAgICAgICcnXG4gICAgXVxuICAgIC8vIGJhc2U2NChcInVzZXI9e1VzZXJ9XFx4MDBhdXRoPUJlYXJlciB7VG9rZW59XFx4MDBcXHgwMFwiKVxuICAgIHJldHVybiBlbmNvZGUoYXV0aERhdGEuam9pbignXFx4MDEnKSlcbiAgfVxuXG4gIGNyZWF0ZUxvZ2dlciAoY3JlYXRvciA9IGNyZWF0ZURlZmF1bHRMb2dnZXIpIHtcbiAgICBjb25zdCBsb2dnZXIgPSBjcmVhdG9yKCh0aGlzLm9wdGlvbnMuYXV0aCB8fCB7fSkudXNlciB8fCAnJywgdGhpcy5ob3N0KVxuICAgIHRoaXMubG9nTGV2ZWwgPSB0aGlzLkxPR19MRVZFTF9BTExcbiAgICB0aGlzLmxvZ2dlciA9IHtcbiAgICAgIGRlYnVnOiAoLi4ubXNncykgPT4geyBpZiAoTE9HX0xFVkVMX0RFQlVHID49IHRoaXMubG9nTGV2ZWwpIHsgbG9nZ2VyLmRlYnVnKG1zZ3MpIH0gfSxcbiAgICAgIGluZm86ICguLi5tc2dzKSA9PiB7IGlmIChMT0dfTEVWRUxfSU5GTyA+PSB0aGlzLmxvZ0xldmVsKSB7IGxvZ2dlci5pbmZvKG1zZ3MpIH0gfSxcbiAgICAgIHdhcm46ICguLi5tc2dzKSA9PiB7IGlmIChMT0dfTEVWRUxfV0FSTiA+PSB0aGlzLmxvZ0xldmVsKSB7IGxvZ2dlci53YXJuKG1zZ3MpIH0gfSxcbiAgICAgIGVycm9yOiAoLi4ubXNncykgPT4geyBpZiAoTE9HX0xFVkVMX0VSUk9SID49IHRoaXMubG9nTGV2ZWwpIHsgbG9nZ2VyLmVycm9yKG1zZ3MpIH0gfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTbXRwQ2xpZW50XG4iXX0= \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jbGllbnQuanMiXSwibmFtZXMiOlsiREVCVUdfVEFHIiwiVElNRU9VVF9TT0NLRVRfTE9XRVJfQk9VTkQiLCJUSU1FT1VUX1NPQ0tFVF9NVUxUSVBMSUVSIiwiU210cENsaWVudCIsImhvc3QiLCJwb3J0Iiwib3B0aW9ucyIsInRpbWVvdXRTb2NrZXRMb3dlckJvdW5kIiwidGltZW91dFNvY2tldE11bHRpcGxpZXIiLCJ1c2VTZWN1cmVUcmFuc3BvcnQiLCJhdXRoIiwibmFtZSIsInNvY2tldCIsImRlc3Ryb3llZCIsIndhaXREcmFpbiIsIl9hdXRoZW50aWNhdGVkQXMiLCJfc3VwcG9ydGVkQXV0aCIsIl9kYXRhTW9kZSIsIl9sYXN0RGF0YUJ5dGVzIiwiX2VudmVsb3BlIiwiX2N1cnJlbnRBY3Rpb24iLCJfbWF4QWxsb3dlZFNpemUiLCJfc2VjdXJlTW9kZSIsIl9zb2NrZXRUaW1lb3V0VGltZXIiLCJfc29ja2V0VGltZW91dFN0YXJ0IiwiX3NvY2tldFRpbWVvdXRQZXJpb2QiLCJfcGFyc2VCbG9jayIsImRhdGEiLCJzdGF0dXNDb2RlIiwiX3BhcnNlUmVtYWluZGVyIiwiZHVtbXlMb2dnZXIiLCJyZWR1Y2UiLCJvIiwibCIsImxvZ2dlciIsIm9uZXJyb3IiLCJlIiwib25kcmFpbiIsIm9uY2xvc2UiLCJvbmlkbGUiLCJvbnJlYWR5IiwiZmFpbGVkUmVjaXBpZW50cyIsIm9uZG9uZSIsInN1Y2Nlc3MiLCJTb2NrZXRDb250cnVjdG9yIiwiVENQU29ja2V0Iiwib3BlbiIsImJpbmFyeVR5cGUiLCJjYSIsInRsc1dvcmtlclBhdGgiLCJ3cyIsIm9uY2VydCIsIkUiLCJfb25FcnJvciIsImJpbmQiLCJvbm9wZW4iLCJfb25PcGVuIiwiZGVidWciLCJfc2VuZENvbW1hbmQiLCJjbG9zZSIsInJlYWR5U3RhdGUiLCJfZGVzdHJveSIsImVudmVsb3BlIiwiZnJvbSIsImNvbmNhdCIsInRvIiwicmNwdFF1ZXVlIiwicmNwdEZhaWxlZCIsInJlc3BvbnNlUXVldWUiLCJfYWN0aW9uTUFJTCIsImNodW5rIiwiX3NlbmRTdHJpbmciLCJsZW5ndGgiLCJzZW5kIiwiX2FjdGlvblN0cmVhbSIsIl9zZW5kIiwiVWludDhBcnJheSIsImJ1ZmZlciIsInN1YnN0ciIsImxpbmVzIiwic3BsaXQiLCJwb3AiLCJpIiwibGVuIiwidHJpbSIsIm1hdGNoIiwicHVzaCIsIk51bWJlciIsInJlc3BvbnNlIiwiam9pbiIsIl9vbkNvbW1hbmQiLCJldmVudCIsInByb3h5SG9zdG5hbWUiLCJvbmRhdGEiLCJfb25EYXRhIiwiX29uQ2xvc2UiLCJfb25EcmFpbiIsIl9hY3Rpb25HcmVldGluZyIsImV2dCIsImNsZWFyVGltZW91dCIsInN0cmluZ1BheWxvYWQiLCJUZXh0RGVjb2RlciIsImRlY29kZSIsIl9wYXJzZSIsIkVycm9yIiwibWVzc2FnZSIsImVycm9yIiwiY29tbWFuZCIsImRpc2FibGVFc2NhcGluZyIsInJlcGxhY2UiLCJjaGFyQXQiLCJUZXh0RW5jb2RlciIsImVuY29kZSIsInN0ciIsIl9zZXRUaW1lb3V0IiwiYnl0ZUxlbmd0aCIsInByb2xvbmdQZXJpb2QiLCJNYXRoIiwiZmxvb3IiLCJ0aW1lb3V0Iiwibm93IiwiRGF0ZSIsInNldFRpbWVvdXQiLCJfb25UaW1lb3V0IiwiX2FjdGlvbklkbGUiLCJhdXRoTWV0aG9kIiwieG9hdXRoMiIsInRvVXBwZXJDYXNlIiwiX2FjdGlvbkFVVEhfTE9HSU5fVVNFUiIsIl9hY3Rpb25BVVRIQ29tcGxldGUiLCJ1c2VyIiwicGFzcyIsIl9hY3Rpb25BVVRIX1hPQVVUSDIiLCJfYnVpbGRYT0F1dGgyVG9rZW4iLCJsbXRwIiwiX2FjdGlvbkxITE8iLCJfYWN0aW9uRUhMTyIsInJlcXVpcmVUTFMiLCJlcnJNc2ciLCJ3YXJuaW5nIiwiX2FjdGlvbkhFTE8iLCJtYXhBbGxvd2VkU2l6ZSIsImlnbm9yZVRMUyIsIl9hY3Rpb25TVEFSVFRMUyIsIl9hdXRoZW50aWNhdGVVc2VyIiwidXBncmFkZVRvU2VjdXJlIiwiX2FjdGlvbkFVVEhfTE9HSU5fUEFTUyIsImN1clJlY2lwaWVudCIsInNoaWZ0IiwiX2FjdGlvblJDUFQiLCJfYWN0aW9uREFUQSIsImluZGV4T2YiLCJyY3B0IiwidG9rZW4iLCJhdXRoRGF0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O3FqQkFBQTs7QUFFQTs7QUFDQTs7OztBQUNBOzs7Ozs7QUFFQSxJQUFJQSxZQUFZLGFBQWhCOztBQUVBOzs7QUFHQSxJQUFNQyw2QkFBNkIsS0FBbkM7O0FBRUE7Ozs7Ozs7QUFPQSxJQUFNQyw0QkFBNEIsR0FBbEM7O0lBRU1DLFU7QUFDSjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1CQSxzQkFBYUMsSUFBYixFQUFtQkMsSUFBbkIsRUFBdUM7QUFBQSxRQUFkQyxPQUFjLHVFQUFKLEVBQUk7O0FBQUE7O0FBQ3JDLFNBQUtBLE9BQUwsR0FBZUEsT0FBZjs7QUFFQSxTQUFLQyx1QkFBTCxHQUErQk4sMEJBQS9CO0FBQ0EsU0FBS08sdUJBQUwsR0FBK0JOLHlCQUEvQjs7QUFFQSxTQUFLRyxJQUFMLEdBQVlBLFNBQVMsS0FBS0MsT0FBTCxDQUFhRyxrQkFBYixHQUFrQyxHQUFsQyxHQUF3QyxFQUFqRCxDQUFaO0FBQ0EsU0FBS0wsSUFBTCxHQUFZQSxRQUFRLFdBQXBCOztBQUVBOzs7OztBQUtBLFNBQUtFLE9BQUwsQ0FBYUcsa0JBQWIsR0FBa0Msd0JBQXdCLEtBQUtILE9BQTdCLEdBQXVDLENBQUMsQ0FBQyxLQUFLQSxPQUFMLENBQWFHLGtCQUF0RCxHQUEyRSxLQUFLSixJQUFMLEtBQWMsR0FBM0g7O0FBRUEsU0FBS0MsT0FBTCxDQUFhSSxJQUFiLEdBQW9CLEtBQUtKLE9BQUwsQ0FBYUksSUFBYixJQUFxQixLQUF6QyxDQWhCcUMsQ0FnQlU7QUFDL0MsU0FBS0osT0FBTCxDQUFhSyxJQUFiLEdBQW9CLEtBQUtMLE9BQUwsQ0FBYUssSUFBYixJQUFxQixXQUF6QyxDQWpCcUMsQ0FpQmdCO0FBQ3JELFNBQUtDLE1BQUwsR0FBYyxLQUFkLENBbEJxQyxDQWtCakI7QUFDcEIsU0FBS0Ms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TUFBTCxDQUFZLElBQVo7QUFDRCxPQW5CRCxNQW1CTztBQUNMO0FBQ0E7O0FBRUEsWUFBSSxDQUFDaUUsUUFBUWhFLE9BQWIsRUFBc0I7QUFDcEIsZUFBS1QsTUFBTCxDQUFZd0UsS0FBWixDQUFrQjFHLFNBQWxCLEVBQTZCLHlCQUE3QjtBQUNELFNBRkQsTUFFTztBQUNMLGVBQUtrQyxNQUFMLENBQVl1QixLQUFaLENBQWtCekQsU0FBbEIsRUFBNkIsNEJBQTdCO0FBQ0Q7O0FBRUQsYUFBS29CLGNBQUwsR0FBc0IsS0FBS3dHLFdBQTNCO0FBQ0EsYUFBS2xGLE1BQUwsQ0FBWSxDQUFDLENBQUNpRSxRQUFRaEUsT0FBdEI7QUFDRDs7QUFFRDtBQUNBLFVBQUksS0FBS3ZCLGNBQUwsS0FBd0IsS0FBS3dHLFdBQWpDLEVBQThDO0FBQzVDO0FBQ0EsYUFBSzFGLE1BQUwsQ0FBWXVCLEtBQVosQ0FBa0J6RCxTQUFsQixFQUE2Qiw2Q0FBN0I7QUFDQSxhQUFLdUMsTUFBTDtBQUNEO0FBQ0Y7O0FBRUQ7Ozs7Ozs7Ozs7dUNBT29CMkYsSSxFQUFNdUIsSyxFQUFPO0FBQy9CLFVBQUlDLFdBQVcsQ0FDYixXQUFXeEIsUUFBUSxFQUFuQixDQURhLEVBRWIsaUJBQWlCdUIsS0FGSixFQUdiLEVBSGEsRUFJYixFQUphLENBQWY7QUFNQTtBQUNBLGFBQU8seUJBQU9DLFNBQVNqRSxJQUFULENBQWMsTUFBZCxDQUFQLENBQVA7QUFDRDs7Ozs7O2tCQUdZdEYsVSIsImZpbGUiOiJjbGllbnQuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cblxuaW1wb3J0IHsgZW5jb2RlIH0gZnJvbSAnZW1haWxqcy1iYXNlNjQnXG5pbXBvcnQgVENQU29ja2V0IGZyb20gJ2VtYWlsanMtdGNwLXNvY2tldCdcbmltcG9ydCB7IFRleHREZWNvZGVyLCBUZXh0RW5jb2RlciB9IGZyb20gJ3RleHQtZW5jb2RpbmcnXG5cbnZhciBERUJVR19UQUcgPSAnU01UUCBDbGllbnQnXG5cbi8qKlxuICogTG93ZXIgQm91bmQgZm9yIHNvY2tldCB0aW1lb3V0IHRvIHdhaXQgc2luY2UgdGhlIGxhc3QgZGF0YSB3YXMgd3JpdHRlbiB0byBhIHNvY2tldFxuICovXG5jb25zdCBUSU1FT1VUX1NPQ0tFVF9MT1dFUl9CT1VORCA9IDEwMDAwXG5cbi8qKlxuICogTXVsdGlwbGllciBmb3Igc29ja2V0IHRpbWVvdXQ6XG4gKlxuICogV2UgYXNzdW1lIGF0IGxlYXN0IGEgR1BSUyBjb25uZWN0aW9uIHdpdGggMTE1IGtiL3MgPSAxNCwzNzUga0IvcyB0b3BzLCBzbyAxMCBLQi9zIHRvIGJlIG9uXG4gKiB0aGUgc2FmZSBzaWRlLiBXZSBjYW4gdGltZW91dCBhZnRlciBhIGxvd2VyIGJvdW5kIG9mIDEwcyArIChuIEtCIC8gMTAgS0IvcykuIEEgMSBNQiBtZXNzYWdlXG4gKiB1cGxvYWQgd291bGQgYmUgMTEwIHNlY29uZHMgdG8gd2FpdCBmb3IgdGhlIHRpbWVvdXQuIDEwIEtCL3MgPT09IDAuMSBzL0JcbiAqL1xuY29uc3QgVElNRU9VVF9TT0NLRVRfTVVMVElQTElFUiA9IDAuMVxuXG5jbGFzcyBTbXRwQ2xpZW50IHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBjb25uZWN0aW9uIG9iamVjdCB0byBhIFNNVFAgc2VydmVyIGFuZCBhbGxvd3MgdG8gc2VuZCBtYWlsIHRocm91Z2ggaXQuXG4gICAqIENhbGwgYGNvbm5lY3RgIG1ldGhvZCB0byBpbml0aXRhdGUgdGhlIGFjdHVhbCBjb25uZWN0aW9uLCB0aGUgY29uc3RydWN0b3Igb25seVxuICAgKiBkZWZpbmVzIHRoZSBwcm9wZXJ0aWVzIGJ1dCBkb2VzIG5vdCBhY3R1YWxseSBjb25uZWN0LlxuICAgKlxuICAgKiBOQiEgVGhlIHBhcmFtZXRlciBvcmRlciAoaG9zdCwgcG9ydCkgZGlmZmVycyBmcm9tIG5vZGUuanMgXCJ3YXlcIiAocG9ydCwgaG9zdClcbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbaG9zdD1cImxvY2FsaG9zdFwiXSBIb3N0bmFtZSB0byBjb25lbmN0IHRvXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBbcG9ydD0yNV0gUG9ydCBudW1iZXIgdG8gY29ubmVjdCB0b1xuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0XG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMudXNlU2VjdXJlVHJhbnNwb3J0XSBTZXQgdG8gdHJ1ZSwgdG8gdXNlIGVuY3J5cHRlZCBjb25uZWN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5uYW1lXSBDbGllbnQgaG9zdG5hbWUgZm9yIGludHJvZHVjaW5nIGl0c2VsZiB0byB0aGUgc2VydmVyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5hdXRoXSBBdXRoZW50aWNhdGlvbiBvcHRpb25zLiBEZXBlbmRzIG9uIHRoZSBwcmVmZXJyZWQgYXV0aGVudGljYXRpb24gbWV0aG9kLiBVc3VhbGx5IHt1c2VyLCBwYXNzfVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYXV0aE1ldGhvZF0gRm9yY2Ugc3BlY2lmaWMgYXV0aGVudGljYXRpb24gbWV0aG9kXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuZGlzYWJsZUVzY2FwaW5nXSBJZiBzZXQgdG8gdHJ1ZSwgZG8gbm90IGVzY2FwZSBkb3RzIG9uIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpbmVzXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMubG9nZ2VyXSBBIHdpbnN0b24tY29tcGF0aWJsZSBsb2dnZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yIChob3N0LCBwb3J0LCBvcHRpb25zID0ge30pIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG5cbiAgICB0aGlzLnRpbWVvdXRTb2NrZXRMb3dlckJvdW5kID0gVElNRU9VVF9TT0NLRVRfTE9XRVJfQk9VTkRcbiAgICB0aGlzLnRpbWVvdXRTb2NrZXRNdWx0aXBsaWVyID0gVElNRU9VVF9TT0NLRVRfTVVMVElQTElFUlxuXG4gICAgdGhpcy5wb3J0ID0gcG9ydCB8fCAodGhpcy5vcHRpb25zLnVzZVNlY3VyZVRyYW5zcG9ydCA/IDQ2NSA6IDI1KVxuICAgIHRoaXMuaG9zdCA9IGhvc3QgfHwgJ2xvY2FsaG9zdCdcblxuICAgIC8qKlxuICAgICAqIElmIHNldCB0byB0cnVlLCBzdGFydCBhbiBlbmNyeXB0ZWQgY29ubmVjdGlvbiBpbnN0ZWFkIG9mIHRoZSBwbGFpbnRleHQgb25lXG4gICAgICogKHJlY29tbWVuZGVkIGlmIGFwcGxpY2FibGUpLiBJZiB1c2VTZWN1cmVUcmFuc3BvcnQgaXMgbm90IHNldCBidXQgdGhlIHBvcnQgdXNlZCBpcyA0NjUsXG4gICAgICogdGhlbiBlY3J5cHRpb24gaXMgdXNlZCBieSBkZWZhdWx0LlxuICAgICAqL1xuICAgIHRoaXMub3B0aW9ucy51c2VTZWN1cmVUcmFuc3BvcnQgPSAndXNlU2VjdXJlVHJhbnNwb3J0JyBpbiB0aGlzLm9wdGlvbnMgPyAhIXRoaXMub3B0aW9ucy51c2VTZWN1cmVUcmFuc3BvcnQgOiB0aGlzLnBvcnQgPT09IDQ2NVxuXG4gICAgdGhpcy5vcHRpb25zLmF1dGggPSB0aGlzLm9wdGlvbnMuYXV0aCB8fCBmYWxzZSAvLyBBdXRoZW50aWNhdGlvbiBvYmplY3QuIElmIG5vdCBzZXQsIGF1dGhlbnRpY2F0aW9uIHN0ZXAgd2lsbCBiZSBza2lwcGVkLlxuICAgIHRoaXMub3B0aW9ucy5uYW1lID0gdGhpcy5vcHRpb25zLm5hbWUgfHwgJ2xvY2FsaG9zdCcgLy8gSG9zdG5hbWUgb2YgdGhlIGNsaWVudCwgdGhpcyB3aWxsIGJlIHVzZWQgZm9yIGludHJvZHVjaW5nIHRvIHRoZSBzZXJ2ZXJcbiAgICB0aGlzLnNvY2tldCA9IGZhbHNlIC8vIERvd25zdHJlYW0gVENQIHNvY2tldCB0byB0aGUgU01UUCBzZXJ2ZXIsIGNyZWF0ZWQgd2l0aCBtb3pUQ1BTb2NrZXRcbiAgICB0aGlzLmRlc3Ryb3llZCA9IGZhbHNlIC8vIEluZGljYXRlcyBpZiB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBjbG9zZWQgYW5kIGNhbid0IGJlIHVzZWQgYW55bW9yZVxuICAgIHRoaXMud2FpdERyYWluID0gZmFsc2UgLy8gS2VlcHMgdHJhY2sgaWYgdGhlIGRvd25zdHJlYW0gc29ja2V0IGlzIGN1cnJlbnRseSBmdWxsIGFuZCBhIGRyYWluIGV2ZW50IHNob3VsZCBiZSB3YWl0ZWQgZm9yIG9yIG5vdFxuXG4gICAgLy8gUHJpdmF0ZSBwcm9wZXJ0aWVzXG5cbiAgICB0aGlzLl9hdXRoZW50aWNhdGVkQXMgPSBudWxsIC8vIElmIGF1dGhlbnRpY2F0ZWQgc3VjY2Vzc2Z1bGx5LCBzdG9yZXMgdGhlIHVzZXJuYW1lXG4gICAgdGhpcy5fc3VwcG9ydGVkQXV0aCA9IFtdIC8vIEEgbGlzdCBvZiBhdXRoZW50aWNhdGlvbiBtZWNoYW5pc21zIGRldGVjdGVkIGZyb20gdGhlIEVITE8gcmVzcG9uc2UgYW5kIHdoaWNoIGFyZSBjb21wYXRpYmxlIHdpdGggdGhpcyBsaWJyYXJ5XG4gICAgdGhpcy5fZGF0YU1vZGUgPSBmYWxzZSAvLyBJZiB0cnVlLCBhY2NlcHRzIGRhdGEgZnJvbSB0aGUgdXBzdHJlYW0gdG8gYmUgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSBkb3duc3RyZWFtIHNvY2tldC4gVXNlZCBhZnRlciB0aGUgREFUQSBjb21tYW5kXG4gICAgdGhpcy5fbGFzdERhdGFCeXRlcyA9ICcnIC8vIEtlZXAgdHJhY2sgb2YgdGhlIGxhc3QgYnl0ZXMgdG8gc2VlIGhvdyB0aGUgdGVybWluYXRpbmcgZG90IHNob3VsZCBiZSBwbGFjZWRcbiAgICB0aGlzLl9lbnZlbG9wZSA9IG51bGwgLy8gRW52ZWxvcGUgb2JqZWN0IGZvciB0cmFja2luZyB3aG8gaXMgc2VuZGluZyBtYWlsIHRvIHdob21cbiAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gbnVsbCAvLyBTdG9yZXMgdGhlIGZ1bmN0aW9uIHRoYXQgc2hvdWxkIGJlIHJ1biBhZnRlciBhIHJlc3BvbnNlIGhhcyBiZWVuIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlclxuICAgIHRoaXMuX21heEFsbG93ZWRTaXplID0gMDsgLy8gU3RvcmVzIHRoZSBtYXggbWVzc2FnZSBzaXplIHN1cHBvcnRlZCBieSB0aGUgc2VydmVyIGFzIHJlcG9ydGVkIGluIHRoZSBncmVldGluZ1xuICAgIHRoaXMuX3NlY3VyZU1vZGUgPSAhIXRoaXMub3B0aW9ucy51c2VTZWN1cmVUcmFuc3BvcnQgLy8gSW5kaWNhdGVzIGlmIHRoZSBjb25uZWN0aW9uIGlzIHNlY3VyZWQgb3IgcGxhaW50ZXh0XG4gICAgdGhpcy5fc29ja2V0VGltZW91dFRpbWVyID0gZmFsc2UgLy8gVGltZXIgd2FpdGluZyB0byBkZWNsYXJlIHRoZSBzb2NrZXQgZGVhZCBzdGFydGluZyBmcm9tIHRoZSBsYXN0IHdyaXRlXG4gICAgdGhpcy5fc29ja2V0VGltZW91dFN0YXJ0ID0gZmFsc2UgLy8gU3RhcnQgdGltZSBvZiBzZW5kaW5nIHRoZSBmaXJzdCBwYWNrZXQgaW4gZGF0YSBtb2RlXG4gICAgdGhpcy5fc29ja2V0VGltZW91dFBlcmlvZCA9IGZhbHNlIC8vIFRpbWVvdXQgZm9yIHNlbmRpbmcgaW4gZGF0YSBtb2RlLCBnZXRzIGV4dGVuZGVkIHdpdGggZXZlcnkgc2VuZCgpXG5cbiAgICB0aGlzLl9wYXJzZUJsb2NrID0geyBkYXRhOiBbXSwgc3RhdHVzQ29kZTogbnVsbCB9XG4gICAgdGhpcy5fcGFyc2VSZW1haW5kZXIgPSAnJyAvLyBJZiB0aGUgY29tcGxldGUgbGluZSBpcyBub3QgcmVjZWl2ZWQgeWV0LCBjb250YWlucyB0aGUgYmVnaW5uaW5nIG9mIGl0XG5cbiAgICBjb25zdCBkdW1teUxvZ2dlciA9IFsnZXJyb3InLCAnd2FybmluZycsICdpbmZvJywgJ2RlYnVnJ10ucmVkdWNlKChvLCBsKSA9PiB7IG9bbF0gPSAoKSA9PiB7fTsgcmV0dXJuIG8gfSwge30pXG4gICAgdGhpcy5sb2dnZXIgPSBvcHRpb25zLmxvZ2dlciB8fCBkdW1teUxvZ2dlclxuXG4gICAgLy8gRXZlbnQgcGxhY2Vob2xkZXJzXG4gICAgdGhpcy5vbmVycm9yID0gKGUpID0+IHsgfSAvLyBXaWxsIGJlIHJ1biB3aGVuIGFuIGVycm9yIG9jY3Vycy4gVGhlIGBvbmNsb3NlYCBldmVudCB3aWxsIGZpcmUgc3Vic2VxdWVudGx5LlxuICAgIHRoaXMub25kcmFpbiA9ICgpID0+IHsgfSAvLyBNb3JlIGRhdGEgY2FuIGJlIGJ1ZmZlcmVkIGluIHRoZSBzb2NrZXQuXG4gICAgdGhpcy5vbmNsb3NlID0gKCkgPT4geyB9IC8vIFRoZSBjb25uZWN0aW9uIHRvIHRoZSBzZXJ2ZXIgaGFzIGJlZW4gY2xvc2VkXG4gICAgdGhpcy5vbmlkbGUgPSAoKSA9PiB7IH0gLy8gVGhlIGNvbm5lY3Rpb24gaXMgZXN0YWJsaXNoZWQgYW5kIGlkbGUsIHlvdSBjYW4gc2VuZCBtYWlsIG5vd1xuICAgIHRoaXMub25yZWFkeSA9IChmYWlsZWRSZWNpcGllbnRzKSA9PiB7IH0gLy8gV2FpdGluZyBmb3IgbWFpbCBib2R5LCBsaXN0cyBhZGRyZXNzZXMgdGhhdCB3ZXJlIG5vdCBhY2NlcHRlZCBhcyByZWNpcGllbnRzXG4gICAgdGhpcy5vbmRvbmUgPSAoc3VjY2VzcykgPT4geyB9IC8vIFRoZSBtYWlsIGhhcyBiZWVuIHNlbnQuIFdhaXQgZm9yIGBvbmlkbGVgIG5leHQuIEluZGljYXRlcyBpZiB0aGUgbWVzc2FnZSB3YXMgcXVldWVkIGJ5IHRoZSBzZXJ2ZXIuXG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhdGUgYSBjb25uZWN0aW9uIHRvIHRoZSBzZXJ2ZXJcbiAgICovXG4gIGNvbm5lY3QgKFNvY2tldENvbnRydWN0b3IgPSBUQ1BTb2NrZXQpIHtcbiAgICB0aGlzLnNvY2tldCA9IFNvY2tldENvbnRydWN0b3Iub3Blbih0aGlzLmhvc3QsIHRoaXMucG9ydCwge1xuICAgICAgYmluYXJ5VHlwZTogJ2FycmF5YnVmZmVyJyxcbiAgICAgIHVzZVNlY3VyZVRyYW5zcG9ydDogdGhpcy5fc2VjdXJlTW9kZSxcbiAgICAgIGNhOiB0aGlzLm9wdGlvbnMuY2EsXG4gICAgICB0bHNXb3JrZXJQYXRoOiB0aGlzLm9wdGlvbnMudGxzV29ya2VyUGF0aCxcbiAgICAgIHdzOiB0aGlzLm9wdGlvbnMud3NcbiAgICB9KVxuXG4gICAgLy8gYWxsb3dzIGNlcnRpZmljYXRlIGhhbmRsaW5nIGZvciBwbGF0Zm9ybSB3L28gbmF0aXZlIHRscyBzdXBwb3J0XG4gICAgLy8gb25jZXJ0IGlzIG5vbiBzdGFuZGFyZCBzbyBzZXR0aW5nIGl0IG1pZ2h0IHRocm93IGlmIHRoZSBzb2NrZXQgb2JqZWN0IGlzIGltbXV0YWJsZVxuICAgIHRyeSB7XG4gICAgICB0aGlzLnNvY2tldC5vbmNlcnQgPSB0aGlzLm9uY2VydFxuICAgIH0gY2F0Y2ggKEUpIHsgfVxuICAgIHRoaXMuc29ja2V0Lm9uZXJyb3IgPSB0aGlzLl9vbkVycm9yLmJpbmQodGhpcylcbiAgICB0aGlzLnNvY2tldC5vbm9wZW4gPSB0aGlzLl9vbk9wZW4uYmluZCh0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIFNlbmRzIFFVSVRcbiAgICovXG4gIHF1aXQgKCkge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ1NlbmRpbmcgUVVJVC4uLicpXG4gICAgdGhpcy5fc2VuZENvbW1hbmQoJ1FVSVQnKVxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLmNsb3NlXG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBzZXJ2ZXJcbiAgICovXG4gIGNsb3NlICgpIHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdDbG9zaW5nIGNvbm5lY3Rpb24uLi4nKVxuICAgIGlmICh0aGlzLnNvY2tldCAmJiB0aGlzLnNvY2tldC5yZWFkeVN0YXRlID09PSAnb3BlbicpIHtcbiAgICAgIHRoaXMuc29ja2V0LmNsb3NlKClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZGVzdHJveSgpXG4gICAgfVxuICB9XG5cbiAgLy8gTWFpbCByZWxhdGVkIG1ldGhvZHNcblxuICAvKipcbiAgICogSW5pdGlhdGVzIGEgbmV3IG1lc3NhZ2UgYnkgc3VibWl0dGluZyBlbnZlbG9wZSBkYXRhLCBzdGFydGluZyB3aXRoXG4gICAqIGBNQUlMIEZST006YCBjb21tYW5kLiBVc2UgYWZ0ZXIgYG9uaWRsZWAgZXZlbnRcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGVudmVsb3BlIEVudmVsb3BlIG9iamVjdCBpbiB0aGUgZm9ybSBvZiB7ZnJvbTpcIi4uLlwiLCB0bzpbXCIuLi5cIl19XG4gICAqL1xuICB1c2VFbnZlbG9wZSAoZW52ZWxvcGUpIHtcbiAgICB0aGlzLl9lbnZlbG9wZSA9IGVudmVsb3BlIHx8IHt9XG4gICAgdGhpcy5fZW52ZWxvcGUuZnJvbSA9IFtdLmNvbmNhdCh0aGlzLl9lbnZlbG9wZS5mcm9tIHx8ICgnYW5vbnltb3VzQCcgKyB0aGlzLm9wdGlvbnMubmFtZSkpWzBdXG4gICAgdGhpcy5fZW52ZWxvcGUudG8gPSBbXS5jb25jYXQodGhpcy5fZW52ZWxvcGUudG8gfHwgW10pXG5cbiAgICAvLyBjbG9uZSB0aGUgcmVjaXBpZW50cyBhcnJheSBmb3IgbGF0dGVyIG1hbmlwdWxhdGlvblxuICAgIHRoaXMuX2VudmVsb3BlLnJjcHRRdWV1ZSA9IFtdLmNvbmNhdCh0aGlzLl9lbnZlbG9wZS50bylcbiAgICB0aGlzLl9lbnZlbG9wZS5yY3B0RmFpbGVkID0gW11cbiAgICB0aGlzLl9lbnZlbG9wZS5yZXNwb25zZVF1ZXVlID0gW11cblxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25NQUlMXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnU2VuZGluZyBNQUlMIEZST00uLi4nKVxuICAgIHRoaXMuX3NlbmRDb21tYW5kKCdNQUlMIEZST006PCcgKyAodGhpcy5fZW52ZWxvcGUuZnJvbSkgKyAnPicpXG4gIH1cblxuICAvKipcbiAgICogU2VuZCBBU0NJSSBkYXRhIHRvIHRoZSBzZXJ2ZXIuIFdvcmtzIG9ubHkgaW4gZGF0YSBtb2RlIChhZnRlciBgb25yZWFkeWAgZXZlbnQpLCBpZ25vcmVkXG4gICAqIG90aGVyd2lzZVxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2h1bmsgQVNDSUkgc3RyaW5nIChxdW90ZWQtcHJpbnRhYmxlLCBiYXNlNjQgZXRjLikgdG8gYmUgc2VudCB0byB0aGUgc2VydmVyXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IElmIHRydWUsIGl0IGlzIHNhZmUgdG8gc2VuZCBtb3JlIGRhdGEsIGlmIGZhbHNlLCB5b3UgKnNob3VsZCogd2FpdCBmb3IgdGhlIG9uZHJhaW4gZXZlbnQgYmVmb3JlIHNlbmRpbmcgbW9yZVxuICAgKi9cbiAgc2VuZCAoY2h1bmspIHtcbiAgICAvLyB3b3JrcyBvbmx5IGluIGRhdGEgbW9kZVxuICAgIGlmICghdGhpcy5fZGF0YU1vZGUpIHtcbiAgICAgIC8vIHRoaXMgbGluZSBzaG91bGQgbmV2ZXIgYmUgcmVhY2hlZCBidXQgaWYgaXQgZG9lcyxcbiAgICAgIC8vIGFjdCBsaWtlIGV2ZXJ5dGhpbmcncyBub3JtYWwuXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIC8vIFRPRE86IGlmIHRoZSBjaHVuayBpcyBhbiBhcnJheWJ1ZmZlciwgdXNlIGEgc2VwYXJhdGUgZnVuY3Rpb24gdG8gc2VuZCB0aGUgZGF0YVxuICAgIHJldHVybiB0aGlzLl9zZW5kU3RyaW5nKGNodW5rKVxuICB9XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGF0IGEgZGF0YSBzdHJlYW0gZm9yIHRoZSBzb2NrZXQgaXMgZW5kZWQuIFdvcmtzIG9ubHkgaW4gZGF0YVxuICAgKiBtb2RlIChhZnRlciBgb25yZWFkeWAgZXZlbnQpLCBpZ25vcmVkIG90aGVyd2lzZS4gVXNlIGl0IHdoZW4geW91IGFyZSBkb25lXG4gICAqIHdpdGggc2VuZGluZyB0aGUgbWFpbC4gVGhpcyBtZXRob2QgZG9lcyBub3QgY2xvc2UgdGhlIHNvY2tldC4gT25jZSB0aGUgbWFpbFxuICAgKiBoYXMgYmVlbiBxdWV1ZWQgYnkgdGhlIHNlcnZlciwgYG9uZG9uZWAgYW5kIGBvbmlkbGVgIGFyZSBlbWl0dGVkLlxuICAgKlxuICAgKiBAcGFyYW0ge0J1ZmZlcn0gW2NodW5rXSBDaHVuayBvZiBkYXRhIHRvIGJlIHNlbnQgdG8gdGhlIHNlcnZlclxuICAgKi9cbiAgZW5kIChjaHVuaykge1xuICAgIC8vIHdvcmtzIG9ubHkgaW4gZGF0YSBtb2RlXG4gICAgaWYgKCF0aGlzLl9kYXRhTW9kZSkge1xuICAgICAgLy8gdGhpcyBsaW5lIHNob3VsZCBuZXZlciBiZSByZWFjaGVkIGJ1dCBpZiBpdCBkb2VzLFxuICAgICAgLy8gYWN0IGxpa2UgZXZlcnl0aGluZydzIG5vcm1hbC5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkge1xuICAgICAgdGhpcy5zZW5kKGNodW5rKVxuICAgIH1cblxuICAgIC8vIHJlZGlyZWN0IG91dHB1dCBmcm9tIHRoZSBzZXJ2ZXIgdG8gX2FjdGlvblN0cmVhbVxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25TdHJlYW1cblxuICAgIC8vIGluZGljYXRlIHRoYXQgdGhlIHN0cmVhbSBoYXMgZW5kZWQgYnkgc2VuZGluZyBhIHNpbmdsZSBkb3Qgb24gaXRzIG93biBsaW5lXG4gICAgLy8gaWYgdGhlIGNsaWVudCBhbHJlYWR5IGNsb3NlZCB0aGUgZGF0YSB3aXRoIFxcclxcbiBubyBuZWVkIHRvIGRvIGl0IGFnYWluXG4gICAgaWYgKHRoaXMuX2xhc3REYXRhQnl0ZXMgPT09ICdcXHJcXG4nKSB7XG4gICAgICB0aGlzLndhaXREcmFpbiA9IHRoaXMuX3NlbmQobmV3IFVpbnQ4QXJyYXkoWzB4MkUsIDB4MEQsIDB4MEFdKS5idWZmZXIpIC8vIC5cXHJcXG5cbiAgICB9IGVsc2UgaWYgKHRoaXMuX2xhc3REYXRhQnl0ZXMuc3Vic3RyKC0xKSA9PT0gJ1xccicpIHtcbiAgICAgIHRoaXMud2FpdERyYWluID0gdGhpcy5fc2VuZChuZXcgVWludDhBcnJheShbMHgwQSwgMHgyRSwgMHgwRCwgMHgwQV0pLmJ1ZmZlcikgLy8gXFxuLlxcclxcblxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLndhaXREcmFpbiA9IHRoaXMuX3NlbmQobmV3IFVpbnQ4QXJyYXkoWzB4MEQsIDB4MEEsIDB4MkUsIDB4MEQsIDB4MEFdKS5idWZmZXIpIC8vIFxcclxcbi5cXHJcXG5cbiAgICB9XG5cbiAgICAvLyBlbmQgZGF0YSBtb2RlLCByZXNldCB0aGUgdmFyaWFibGVzIGZvciBleHRlbmRpbmcgdGhlIHRpbWVvdXQgaW4gZGF0YSBtb2RlXG4gICAgdGhpcy5fZGF0YU1vZGUgPSBmYWxzZVxuICAgIHRoaXMuX3NvY2tldFRpbWVvdXRTdGFydCA9IGZhbHNlXG4gICAgdGhpcy5fc29ja2V0VGltZW91dFBlcmlvZCA9IGZhbHNlXG5cbiAgICByZXR1cm4gdGhpcy53YWl0RHJhaW5cbiAgfVxuXG4gIC8vIFBSSVZBVEUgTUVUSE9EU1xuXG4gIC8qKlxuICAgKiBRdWV1ZSBzb21lIGRhdGEgZnJvbSB0aGUgc2VydmVyIGZvciBwYXJzaW5nLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2h1bmsgQ2h1bmsgb2YgZGF0YSByZWNlaXZlZCBmcm9tIHRoZSBzZXJ2ZXJcbiAgICovXG4gIF9wYXJzZSAoY2h1bmspIHtcbiAgICAvLyBMaW5lcyBzaG91bGQgYWx3YXlzIGVuZCB3aXRoIDxDUj48TEY+IGJ1dCB5b3UgbmV2ZXIga25vdywgbWlnaHQgYmUgb25seSA8TEY+IGFzIHdlbGxcbiAgICB2YXIgbGluZXMgPSAodGhpcy5fcGFyc2VSZW1haW5kZXIgKyAoY2h1bmsgfHwgJycpKS5zcGxpdCgvXFxyP1xcbi8pXG4gICAgdGhpcy5fcGFyc2VSZW1haW5kZXIgPSBsaW5lcy5wb3AoKSAvLyBub3Qgc3VyZSBpZiB0aGUgbGluZSBoYXMgY29tcGxldGVseSBhcnJpdmVkIHlldFxuXG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxpbmVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBpZiAoIWxpbmVzW2ldLnRyaW0oKSkge1xuICAgICAgICAvLyBub3RoaW5nIHRvIGNoZWNrLCBlbXB0eSBsaW5lXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHBvc3NpYmxlIGlucHV0IHN0cmluZ3MgZm9yIHRoZSByZWdleDpcbiAgICAgIC8vIDI1MC1NVUxUSUxJTkUgUkVQTFlcbiAgICAgIC8vIDI1MCBMQVNUIExJTkUgT0YgUkVQTFlcbiAgICAgIC8vIDI1MCAxLjIuMyBNRVNTQUdFXG5cbiAgICAgIGNvbnN0IG1hdGNoID0gbGluZXNbaV0ubWF0Y2goL14oXFxkezN9KShbLSBdKSg/OihcXGQrXFwuXFxkK1xcLlxcZCspKD86ICkpPyguKikvKVxuXG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgdGhpcy5fcGFyc2VCbG9jay5kYXRhLnB1c2gobWF0Y2hbNF0pXG5cbiAgICAgICAgaWYgKG1hdGNoWzJdID09PSAnLScpIHtcbiAgICAgICAgICAvLyB0aGlzIGlzIGEgbXVsdGlsaW5lIHJlcGx5XG4gICAgICAgICAgdGhpcy5fcGFyc2VCbG9jay5zdGF0dXNDb2RlID0gdGhpcy5fcGFyc2VCbG9jay5zdGF0dXNDb2RlIHx8IE51bWJlcihtYXRjaFsxXSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBzdGF0dXNDb2RlID0gTnVtYmVyKG1hdGNoWzFdKSB8fCAwXG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlLFxuICAgICAgICAgICAgZGF0YTogdGhpcy5fcGFyc2VCbG9jay5kYXRhLmpvaW4oJ1xcbicpLFxuICAgICAgICAgICAgc3VjY2Vzczogc3RhdHVzQ29kZSA+PSAyMDAgJiYgc3RhdHVzQ29kZSA8IDMwMFxuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX29uQ29tbWFuZChyZXNwb25zZSlcbiAgICAgICAgICB0aGlzLl9wYXJzZUJsb2NrID0ge1xuICAgICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgICBzdGF0dXNDb2RlOiBudWxsXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9vbkNvbW1hbmQoe1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IHRoaXMuX3BhcnNlQmxvY2suc3RhdHVzQ29kZSB8fCBudWxsLFxuICAgICAgICAgIGRhdGE6IFtsaW5lc1tpXV0uam9pbignXFxuJylcbiAgICAgICAgfSlcbiAgICAgICAgdGhpcy5fcGFyc2VCbG9jayA9IHtcbiAgICAgICAgICBkYXRhOiBbXSxcbiAgICAgICAgICBzdGF0dXNDb2RlOiBudWxsXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBFVkVOVCBIQU5ETEVSUyBGT1IgVEhFIFNPQ0tFVFxuXG4gIC8qKlxuICAgKiBDb25uZWN0aW9uIGxpc3RlbmVyIHRoYXQgaXMgcnVuIHdoZW4gdGhlIGNvbm5lY3Rpb24gdG8gdGhlIHNlcnZlciBpcyBvcGVuZWQuXG4gICAqIFNldHMgdXAgZGlmZmVyZW50IGV2ZW50IGhhbmRsZXJzIGZvciB0aGUgb3BlbmVkIHNvY2tldFxuICAgKlxuICAgKiBAZXZlbnRcbiAgICogQHBhcmFtIHtFdmVudH0gZXZ0IEV2ZW50IG9iamVjdC4gTm90IHVzZWRcbiAgICovXG4gIF9vbk9wZW4gKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50ICYmIGV2ZW50LmRhdGEgJiYgZXZlbnQuZGF0YS5wcm94eUhvc3RuYW1lKSB7XG4gICAgICB0aGlzLm9wdGlvbnMubmFtZSA9IGV2ZW50LmRhdGEucHJveHlIb3N0bmFtZVxuICAgIH1cblxuICAgIHRoaXMuc29ja2V0Lm9uZGF0YSA9IHRoaXMuX29uRGF0YS5iaW5kKHRoaXMpXG5cbiAgICB0aGlzLnNvY2tldC5vbmNsb3NlID0gdGhpcy5fb25DbG9zZS5iaW5kKHRoaXMpXG4gICAgdGhpcy5zb2NrZXQub25kcmFpbiA9IHRoaXMuX29uRHJhaW4uYmluZCh0aGlzKVxuXG4gICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvbkdyZWV0aW5nXG4gIH1cblxuICAvKipcbiAgICogRGF0YSBsaXN0ZW5lciBmb3IgY2h1bmtzIG9mIGRhdGEgZW1pdHRlZCBieSB0aGUgc2VydmVyXG4gICAqXG4gICAqIEBldmVudFxuICAgKiBAcGFyYW0ge0V2ZW50fSBldnQgRXZlbnQgb2JqZWN0LiBTZWUgYGV2dC5kYXRhYCBmb3IgdGhlIGNodW5rIHJlY2VpdmVkXG4gICAqL1xuICBfb25EYXRhIChldnQpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5fc29ja2V0VGltZW91dFRpbWVyKVxuICAgIHZhciBzdHJpbmdQYXlsb2FkID0gbmV3IFRleHREZWNvZGVyKCdVVEYtOCcpLmRlY29kZShuZXcgVWludDhBcnJheShldnQuZGF0YSkpXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnU0VSVkVSOiAnICsgc3RyaW5nUGF5bG9hZClcbiAgICB0aGlzLl9wYXJzZShzdHJpbmdQYXlsb2FkKVxuICB9XG5cbiAgLyoqXG4gICAqIE1vcmUgZGF0YSBjYW4gYmUgYnVmZmVyZWQgaW4gdGhlIHNvY2tldCwgYHdhaXREcmFpbmAgaXMgcmVzZXQgdG8gZmFsc2VcbiAgICpcbiAgICogQGV2ZW50XG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2dCBFdmVudCBvYmplY3QuIE5vdCB1c2VkXG4gICAqL1xuICBfb25EcmFpbiAoKSB7XG4gICAgdGhpcy53YWl0RHJhaW4gPSBmYWxzZVxuICAgIHRoaXMub25kcmFpbigpXG4gIH1cblxuICAvKipcbiAgICogRXJyb3IgaGFuZGxlciBmb3IgdGhlIHNvY2tldFxuICAgKlxuICAgKiBAZXZlbnRcbiAgICogQHBhcmFtIHtFdmVudH0gZXZ0IEV2ZW50IG9iamVjdC4gU2VlIGV2dC5kYXRhIGZvciB0aGUgZXJyb3JcbiAgICovXG4gIF9vbkVycm9yIChldnQpIHtcbiAgICBpZiAoZXZ0IGluc3RhbmNlb2YgRXJyb3IgJiYgZXZ0Lm1lc3NhZ2UpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKERFQlVHX1RBRywgZXZ0KVxuICAgICAgdGhpcy5vbmVycm9yKGV2dClcbiAgICB9IGVsc2UgaWYgKGV2dCAmJiBldnQuZGF0YSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihERUJVR19UQUcsIGV2dC5kYXRhKVxuICAgICAgdGhpcy5vbmVycm9yKGV2dC5kYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihERUJVR19UQUcsIG5ldyBFcnJvcigoZXZ0ICYmIGV2dC5kYXRhICYmIGV2dC5kYXRhLm1lc3NhZ2UpIHx8IGV2dC5kYXRhIHx8IGV2dCB8fCAnRXJyb3InKSlcbiAgICAgIHRoaXMub25lcnJvcihuZXcgRXJyb3IoKGV2dCAmJiBldnQuZGF0YSAmJiBldnQuZGF0YS5tZXNzYWdlKSB8fCBldnQuZGF0YSB8fCBldnQgfHwgJ0Vycm9yJykpXG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSgpXG4gIH1cblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgdGhlIHNvY2tldCBoYXMgYmVlbiBjbG9zZWRcbiAgICpcbiAgICogQGV2ZW50XG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2dCBFdmVudCBvYmplY3QuIE5vdCB1c2VkXG4gICAqL1xuICBfb25DbG9zZSAoKSB7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnU29ja2V0IGNsb3NlZC4nKVxuICAgIHRoaXMuX2Rlc3Ryb3koKVxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgaXMgbm90IGEgc29ja2V0IGRhdGEgaGFuZGxlciBidXQgdGhlIGhhbmRsZXIgZm9yIGRhdGEgZW1pdHRlZCBieSB0aGUgcGFyc2VyLFxuICAgKiBzbyB0aGlzIGRhdGEgaXMgc2FmZSB0byB1c2UgYXMgaXQgaXMgYWx3YXlzIGNvbXBsZXRlIChzZXJ2ZXIgbWlnaHQgc2VuZCBwYXJ0aWFsIGNodW5rcylcbiAgICpcbiAgICogQGV2ZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIFBhcnNlZCBkYXRhXG4gICAqL1xuICBfb25Db21tYW5kIChjb21tYW5kKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9jdXJyZW50QWN0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QWN0aW9uKGNvbW1hbmQpXG4gICAgfVxuICB9XG5cbiAgX29uVGltZW91dCAoKSB7XG4gICAgLy8gaW5mb3JtIGFib3V0IHRoZSB0aW1lb3V0IGFuZCBzaHV0IGRvd25cbiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1NvY2tldCB0aW1lZCBvdXQhJylcbiAgICB0aGlzLl9vbkVycm9yKGVycm9yKVxuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgdGhhdCB0aGUgY29ubmVjdGlvbiBpcyBjbG9zZWQgYW5kIHN1Y2hcbiAgICovXG4gIF9kZXN0cm95ICgpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5fc29ja2V0VGltZW91dFRpbWVyKVxuXG4gICAgaWYgKCF0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlXG4gICAgICB0aGlzLm9uY2xvc2UoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBhIHN0cmluZyB0byB0aGUgc29ja2V0LlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2h1bmsgQVNDSUkgc3RyaW5nIChxdW90ZWQtcHJpbnRhYmxlLCBiYXNlNjQgZXRjLikgdG8gYmUgc2VudCB0byB0aGUgc2VydmVyXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IElmIHRydWUsIGl0IGlzIHNhZmUgdG8gc2VuZCBtb3JlIGRhdGEsIGlmIGZhbHNlLCB5b3UgKnNob3VsZCogd2FpdCBmb3IgdGhlIG9uZHJhaW4gZXZlbnQgYmVmb3JlIHNlbmRpbmcgbW9yZVxuICAgKi9cbiAgX3NlbmRTdHJpbmcgKGNodW5rKSB7XG4gICAgLy8gZXNjYXBlIGRvdHNcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5kaXNhYmxlRXNjYXBpbmcpIHtcbiAgICAgIGNodW5rID0gY2h1bmsucmVwbGFjZSgvXFxuXFwuL2csICdcXG4uLicpXG4gICAgICBpZiAoKHRoaXMuX2xhc3REYXRhQnl0ZXMuc3Vic3RyKC0xKSA9PT0gJ1xcbicgfHwgIXRoaXMuX2xhc3REYXRhQnl0ZXMpICYmIGNodW5rLmNoYXJBdCgwKSA9PT0gJy4nKSB7XG4gICAgICAgIGNodW5rID0gJy4nICsgY2h1bmtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBLZWVwaW5nIGV5ZSBvbiB0aGUgbGFzdCBieXRlcyBzZW50LCB0byBzZWUgaWYgdGhlcmUgaXMgYSA8Q1I+PExGPiBzZXF1ZW5jZVxuICAgIC8vIGF0IHRoZSBlbmQgd2hpY2ggaXMgbmVlZGVkIHRvIGVuZCB0aGUgZGF0YSBzdHJlYW1cbiAgICBpZiAoY2h1bmsubGVuZ3RoID4gMikge1xuICAgICAgdGhpcy5fbGFzdERhdGFCeXRlcyA9IGNodW5rLnN1YnN0cigtMilcbiAgICB9IGVsc2UgaWYgKGNodW5rLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdGhpcy5fbGFzdERhdGFCeXRlcyA9IHRoaXMuX2xhc3REYXRhQnl0ZXMuc3Vic3RyKC0xKSArIGNodW5rXG4gICAgfVxuXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnU2VuZGluZyAnICsgY2h1bmsubGVuZ3RoICsgJyBieXRlcyBvZiBwYXlsb2FkJylcblxuICAgIC8vIHBhc3MgdGhlIGNodW5rIHRvIHRoZSBzb2NrZXRcbiAgICB0aGlzLndhaXREcmFpbiA9IHRoaXMuX3NlbmQobmV3IFRleHRFbmNvZGVyKCdVVEYtOCcpLmVuY29kZShjaHVuaykuYnVmZmVyKVxuICAgIHJldHVybiB0aGlzLndhaXREcmFpblxuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgYSBzdHJpbmcgY29tbWFuZCB0byB0aGUgc2VydmVyLCBhbHNvIGFwcGVuZCBcXHJcXG4gaWYgbmVlZGVkXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGJlIHNlbnQgdG8gdGhlIHNlcnZlclxuICAgKi9cbiAgX3NlbmRDb21tYW5kIChzdHIpIHtcbiAgICB0aGlzLndhaXREcmFpbiA9IHRoaXMuX3NlbmQobmV3IFRleHRFbmNvZGVyKCdVVEYtOCcpLmVuY29kZShzdHIgKyAoc3RyLnN1YnN0cigtMikgIT09ICdcXHJcXG4nID8gJ1xcclxcbicgOiAnJykpLmJ1ZmZlcilcbiAgfVxuXG4gIF9zZW5kIChidWZmZXIpIHtcbiAgICB0aGlzLl9zZXRUaW1lb3V0KGJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgIHJldHVybiB0aGlzLnNvY2tldC5zZW5kKGJ1ZmZlcilcbiAgfVxuXG4gIF9zZXRUaW1lb3V0IChieXRlTGVuZ3RoKSB7XG4gICAgdmFyIHByb2xvbmdQZXJpb2QgPSBNYXRoLmZsb29yKGJ5dGVMZW5ndGggKiB0aGlzLnRpbWVvdXRTb2NrZXRNdWx0aXBsaWVyKVxuICAgIHZhciB0aW1lb3V0XG5cbiAgICBpZiAodGhpcy5fZGF0YU1vZGUpIHtcbiAgICAgIC8vIHdlJ3JlIGluIGRhdGEgbW9kZSwgc28gd2UgY291bnQgb25seSBvbmUgdGltZW91dCB0aGF0IGdldCBleHRlbmRlZCBmb3IgZXZlcnkgc2VuZCgpLlxuICAgICAgdmFyIG5vdyA9IERhdGUubm93KClcblxuICAgICAgLy8gdGhlIG9sZCB0aW1lb3V0IHN0YXJ0IHRpbWVcbiAgICAgIHRoaXMuX3NvY2tldFRpbWVvdXRTdGFydCA9IHRoaXMuX3NvY2tldFRpbWVvdXRTdGFydCB8fCBub3dcblxuICAgICAgLy8gdGhlIG9sZCB0aW1lb3V0IHBlcmlvZCwgbm9ybWFsaXplZCB0byBhIG1pbmltdW0gb2YgVElNRU9VVF9TT0NLRVRfTE9XRVJfQk9VTkRcbiAgICAgIHRoaXMuX3NvY2tldFRpbWVvdXRQZXJpb2QgPSAodGhpcy5fc29ja2V0VGltZW91dFBlcmlvZCB8fCB0aGlzLnRpbWVvdXRTb2NrZXRMb3dlckJvdW5kKSArIHByb2xvbmdQZXJpb2RcblxuICAgICAgLy8gdGhlIG5ldyB0aW1lb3V0IGlzIHRoZSBkZWx0YSBiZXR3ZWVuIHRoZSBuZXcgZmlyaW5nIHRpbWUgKD0gdGltZW91dCBwZXJpb2QgKyB0aW1lb3V0IHN0YXJ0IHRpbWUpIGFuZCBub3dcbiAgICAgIHRpbWVvdXQgPSB0aGlzLl9zb2NrZXRUaW1lb3V0U3RhcnQgKyB0aGlzLl9zb2NrZXRUaW1lb3V0UGVyaW9kIC0gbm93XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHNldCBuZXcgdGltb3V0XG4gICAgICB0aW1lb3V0ID0gdGhpcy50aW1lb3V0U29ja2V0TG93ZXJCb3VuZCArIHByb2xvbmdQZXJpb2RcbiAgICB9XG5cbiAgICBjbGVhclRpbWVvdXQodGhpcy5fc29ja2V0VGltZW91dFRpbWVyKSAvLyBjbGVhciBwZW5kaW5nIHRpbWVvdXRzXG4gICAgdGhpcy5fc29ja2V0VGltZW91dFRpbWVyID0gc2V0VGltZW91dCh0aGlzLl9vblRpbWVvdXQuYmluZCh0aGlzKSwgdGltZW91dCkgLy8gYXJtIHRoZSBuZXh0IHRpbWVvdXRcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnRpdGlhdGUgYXV0aGVudGljYXRpb24gc2VxdWVuY2UgaWYgbmVlZGVkXG4gICAqL1xuICBfYXV0aGVudGljYXRlVXNlciAoKSB7XG4gICAgaWYgKCF0aGlzLm9wdGlvbnMuYXV0aCkge1xuICAgICAgLy8gbm8gbmVlZCB0byBhdXRoZW50aWNhdGUsIGF0IGxlYXN0IG5vIGRhdGEgZ2l2ZW5cbiAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25JZGxlXG4gICAgICB0aGlzLm9uaWRsZSgpIC8vIHJlYWR5IHRvIHRha2Ugb3JkZXJzXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB2YXIgYXV0aFxuXG4gICAgaWYgKCF0aGlzLm9wdGlvbnMuYXV0aE1ldGhvZCAmJiB0aGlzLm9wdGlvbnMuYXV0aC54b2F1dGgyKSB7XG4gICAgICB0aGlzLm9wdGlvbnMuYXV0aE1ldGhvZCA9ICdYT0FVVEgyJ1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMuYXV0aE1ldGhvZCkge1xuICAgICAgYXV0aCA9IHRoaXMub3B0aW9ucy5hdXRoTWV0aG9kLnRvVXBwZXJDYXNlKCkudHJpbSgpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHVzZSBmaXJzdCBzdXBwb3J0ZWRcbiAgICAgIGF1dGggPSAodGhpcy5fc3VwcG9ydGVkQXV0aFswXSB8fCAnUExBSU4nKS50b1VwcGVyQ2FzZSgpLnRyaW0oKVxuICAgIH1cblxuICAgIHN3aXRjaCAoYXV0aCkge1xuICAgICAgY2FzZSAnTE9HSU4nOlxuICAgICAgICAvLyBMT0dJTiBpcyBhIDMgc3RlcCBhdXRoZW50aWNhdGlvbiBwcm9jZXNzXG4gICAgICAgIC8vIEM6IEFVVEggTE9HSU5cbiAgICAgICAgLy8gQzogQkFTRTY0KFVTRVIpXG4gICAgICAgIC8vIEM6IEJBU0U2NChQQVNTKVxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdBdXRoZW50aWNhdGlvbiB2aWEgQVVUSCBMT0dJTicpXG4gICAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25BVVRIX0xPR0lOX1VTRVJcbiAgICAgICAgdGhpcy5fc2VuZENvbW1hbmQoJ0FVVEggTE9HSU4nKVxuICAgICAgICByZXR1cm5cbiAgICAgIGNhc2UgJ1BMQUlOJzpcbiAgICAgICAgLy8gQVVUSCBQTEFJTiBpcyBhIDEgc3RlcCBhdXRoZW50aWNhdGlvbiBwcm9jZXNzXG4gICAgICAgIC8vIEM6IEFVVEggUExBSU4gQkFTRTY0KFxcMCBVU0VSIFxcMCBQQVNTKVxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdBdXRoZW50aWNhdGlvbiB2aWEgQVVUSCBQTEFJTicpXG4gICAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25BVVRIQ29tcGxldGVcbiAgICAgICAgdGhpcy5fc2VuZENvbW1hbmQoXG4gICAgICAgICAgLy8gY29udmVydCB0byBCQVNFNjRcbiAgICAgICAgICAnQVVUSCBQTEFJTiAnICtcbiAgICAgICAgICBlbmNvZGUoXG4gICAgICAgICAgICAvLyB0aGlzLm9wdGlvbnMuYXV0aC51c2VyKydcXHUwMDAwJytcbiAgICAgICAgICAgICdcXHUwMDAwJyArIC8vIHNraXAgYXV0aG9yaXphdGlvbiBpZGVudGl0eSBhcyBpdCBjYXVzZXMgcHJvYmxlbXMgd2l0aCBzb21lIHNlcnZlcnNcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5hdXRoLnVzZXIgKyAnXFx1MDAwMCcgK1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zLmF1dGgucGFzcylcbiAgICAgICAgKVxuICAgICAgICByZXR1cm5cbiAgICAgIGNhc2UgJ1hPQVVUSDInOlxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vZ21haWwveG9hdXRoMl9wcm90b2NvbCNzbXRwX3Byb3RvY29sX2V4Y2hhbmdlXG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ0F1dGhlbnRpY2F0aW9uIHZpYSBBVVRIIFhPQVVUSDInKVxuICAgICAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gdGhpcy5fYWN0aW9uQVVUSF9YT0FVVEgyXG4gICAgICAgIHRoaXMuX3NlbmRDb21tYW5kKCdBVVRIIFhPQVVUSDIgJyArIHRoaXMuX2J1aWxkWE9BdXRoMlRva2VuKHRoaXMub3B0aW9ucy5hdXRoLnVzZXIsIHRoaXMub3B0aW9ucy5hdXRoLnhvYXV0aDIpKVxuICAgICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLl9vbkVycm9yKG5ldyBFcnJvcignVW5rbm93biBhdXRoZW50aWNhdGlvbiBtZXRob2QgJyArIGF1dGgpKVxuICB9XG5cbiAgLy8gQUNUSU9OUyBGT1IgUkVTUE9OU0VTIEZST00gVEhFIFNNVFAgU0VSVkVSXG5cbiAgLyoqXG4gICAqIEluaXRpYWwgcmVzcG9uc2UgZnJvbSB0aGUgc2VydmVyLCBtdXN0IGhhdmUgYSBzdGF0dXMgMjIwXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIFBhcnNlZCBjb21tYW5kIGZyb20gdGhlIHNlcnZlciB7c3RhdHVzQ29kZSwgZGF0YX1cbiAgICovXG4gIF9hY3Rpb25HcmVldGluZyAoY29tbWFuZCkge1xuICAgIGlmIChjb21tYW5kLnN0YXR1c0NvZGUgIT09IDIyMCkge1xuICAgICAgdGhpcy5fb25FcnJvcihuZXcgRXJyb3IoJ0ludmFsaWQgZ3JlZXRpbmc6ICcgKyBjb21tYW5kLmRhdGEpKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5sbXRwKSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdTZW5kaW5nIExITE8gJyArIHRoaXMub3B0aW9ucy5uYW1lKVxuXG4gICAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gdGhpcy5fYWN0aW9uTEhMT1xuICAgICAgdGhpcy5fc2VuZENvbW1hbmQoJ0xITE8gJyArIHRoaXMub3B0aW9ucy5uYW1lKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdTZW5kaW5nIEVITE8gJyArIHRoaXMub3B0aW9ucy5uYW1lKVxuXG4gICAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gdGhpcy5fYWN0aW9uRUhMT1xuICAgICAgdGhpcy5fc2VuZENvbW1hbmQoJ0VITE8gJyArIHRoaXMub3B0aW9ucy5uYW1lKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNwb25zZSB0byBMSExPXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIFBhcnNlZCBjb21tYW5kIGZyb20gdGhlIHNlcnZlciB7c3RhdHVzQ29kZSwgZGF0YX1cbiAgICovXG4gIF9hY3Rpb25MSExPIChjb21tYW5kKSB7XG4gICAgaWYgKCFjb21tYW5kLnN1Y2Nlc3MpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKERFQlVHX1RBRywgJ0xITE8gbm90IHN1Y2Nlc3NmdWwnKVxuICAgICAgdGhpcy5fb25FcnJvcihuZXcgRXJyb3IoY29tbWFuZC5kYXRhKSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIFByb2Nlc3MgYXMgRUhMTyByZXNwb25zZVxuICAgIHRoaXMuX2FjdGlvbkVITE8oY29tbWFuZClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNwb25zZSB0byBFSExPLiBJZiB0aGUgcmVzcG9uc2UgaXMgYW4gZXJyb3IsIHRyeSBIRUxPIGluc3RlYWRcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbW1hbmQgUGFyc2VkIGNvbW1hbmQgZnJvbSB0aGUgc2VydmVyIHtzdGF0dXNDb2RlLCBkYXRhfVxuICAgKi9cbiAgX2FjdGlvbkVITE8gKGNvbW1hbmQpIHtcbiAgICB2YXIgbWF0Y2hcblxuICAgIGlmICghY29tbWFuZC5zdWNjZXNzKSB7XG4gICAgICBpZiAoIXRoaXMuX3NlY3VyZU1vZGUgJiYgdGhpcy5vcHRpb25zLnJlcXVpcmVUTFMpIHtcbiAgICAgICAgdmFyIGVyck1zZyA9ICdTVEFSVFRMUyBub3Qgc3VwcG9ydGVkIHdpdGhvdXQgRUhMTydcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoREVCVUdfVEFHLCBlcnJNc2cpXG4gICAgICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKGVyck1zZykpXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICAvLyBUcnkgSEVMTyBpbnN0ZWFkXG4gICAgICB0aGlzLmxvZ2dlci53YXJuaW5nKERFQlVHX1RBRywgJ0VITE8gbm90IHN1Y2Nlc3NmdWwsIHRyeWluZyBIRUxPICcgKyB0aGlzLm9wdGlvbnMubmFtZSlcbiAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25IRUxPXG4gICAgICB0aGlzLl9zZW5kQ29tbWFuZCgnSEVMTyAnICsgdGhpcy5vcHRpb25zLm5hbWUpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBEZXRlY3QgaWYgdGhlIHNlcnZlciBzdXBwb3J0cyBQTEFJTiBhdXRoXG4gICAgaWYgKGNvbW1hbmQuZGF0YS5tYXRjaCgvQVVUSCg/OlxccytbXlxcbl0qXFxzK3xcXHMrKVBMQUlOL2kpKSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdTZXJ2ZXIgc3VwcG9ydHMgQVVUSCBQTEFJTicpXG4gICAgICB0aGlzLl9zdXBwb3J0ZWRBdXRoLnB1c2goJ1BMQUlOJylcbiAgICB9XG5cbiAgICAvLyBEZXRlY3QgaWYgdGhlIHNlcnZlciBzdXBwb3J0cyBMT0dJTiBhdXRoXG4gICAgaWYgKGNvbW1hbmQuZGF0YS5tYXRjaCgvQVVUSCg/OlxccytbXlxcbl0qXFxzK3xcXHMrKUxPR0lOL2kpKSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdTZXJ2ZXIgc3VwcG9ydHMgQVVUSCBMT0dJTicpXG4gICAgICB0aGlzLl9zdXBwb3J0ZWRBdXRoLnB1c2goJ0xPR0lOJylcbiAgICB9XG5cbiAgICAvLyBEZXRlY3QgaWYgdGhlIHNlcnZlciBzdXBwb3J0cyBYT0FVVEgyIGF1dGhcbiAgICBpZiAoY29tbWFuZC5kYXRhLm1hdGNoKC9BVVRIKD86XFxzK1teXFxuXSpcXHMrfFxccyspWE9BVVRIMi9pKSkge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnU2VydmVyIHN1cHBvcnRzIEFVVEggWE9BVVRIMicpXG4gICAgICB0aGlzLl9zdXBwb3J0ZWRBdXRoLnB1c2goJ1hPQVVUSDInKVxuICAgIH1cblxuICAgIC8vIERldGVjdCBtYXhpbXVtIGFsbG93ZWQgbWVzc2FnZSBzaXplXG4gICAgaWYgKChtYXRjaCA9IGNvbW1hbmQuZGF0YS5tYXRjaCgvU0laRSAoXFxkKykvaSkpICYmIE51bWJlcihtYXRjaFsxXSkpIHtcbiAgICAgIGNvbnN0IG1heEFsbG93ZWRTaXplID0gTnVtYmVyKG1hdGNoWzFdKVxuICAgICAgdGhpcy5fbWF4QWxsb3dlZFNpemUgPSBtYXhBbGxvd2VkU2l6ZTtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ01heGltdW0gYWxsb3dlZCBtZXNzYWdlIHNpemU6ICcgKyBtYXhBbGxvd2VkU2l6ZSlcbiAgICB9XG5cbiAgICAvLyBEZXRlY3QgaWYgdGhlIHNlcnZlciBzdXBwb3J0cyBTVEFSVFRMU1xuICAgIGlmICghdGhpcy5fc2VjdXJlTW9kZSkge1xuICAgICAgaWYgKChjb21tYW5kLmRhdGEubWF0Y2goL1NUQVJUVExTXFxzPyQvbWkpICYmICF0aGlzLm9wdGlvbnMuaWdub3JlVExTKSB8fCAhIXRoaXMub3B0aW9ucy5yZXF1aXJlVExTKSB7XG4gICAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25TVEFSVFRMU1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdTZW5kaW5nIFNUQVJUVExTJylcbiAgICAgICAgdGhpcy5fc2VuZENvbW1hbmQoJ1NUQVJUVExTJylcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fYXV0aGVudGljYXRlVXNlcigpXG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyBzZXJ2ZXIgcmVzcG9uc2UgZm9yIFNUQVJUVExTIGNvbW1hbmQuIElmIHRoZXJlJ3MgYW4gZXJyb3JcbiAgICogdHJ5IEhFTE8gaW5zdGVhZCwgb3RoZXJ3aXNlIGluaXRpYXRlIFRMUyB1cGdyYWRlLiBJZiB0aGUgdXBncmFkZVxuICAgKiBzdWNjZWVkZXMgcmVzdGFydCB0aGUgRUhMT1xuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIE1lc3NhZ2UgZnJvbSB0aGUgc2VydmVyXG4gICAqL1xuICBfYWN0aW9uU1RBUlRUTFMgKGNvbW1hbmQpIHtcbiAgICBpZiAoIWNvbW1hbmQuc3VjY2Vzcykge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoREVCVUdfVEFHLCAnU1RBUlRUTFMgbm90IHN1Y2Nlc3NmdWwnKVxuICAgICAgdGhpcy5fb25FcnJvcihuZXcgRXJyb3IoY29tbWFuZC5kYXRhKSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuX3NlY3VyZU1vZGUgPSB0cnVlXG4gICAgdGhpcy5zb2NrZXQudXBncmFkZVRvU2VjdXJlKClcblxuICAgIC8vIHJlc3RhcnQgcHJvdG9jb2wgZmxvd1xuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25FSExPXG4gICAgdGhpcy5fc2VuZENvbW1hbmQoJ0VITE8gJyArIHRoaXMub3B0aW9ucy5uYW1lKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc3BvbnNlIHRvIEhFTE9cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbW1hbmQgUGFyc2VkIGNvbW1hbmQgZnJvbSB0aGUgc2VydmVyIHtzdGF0dXNDb2RlLCBkYXRhfVxuICAgKi9cbiAgX2FjdGlvbkhFTE8gKGNvbW1hbmQpIHtcbiAgICBpZiAoIWNvbW1hbmQuc3VjY2Vzcykge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoREVCVUdfVEFHLCAnSEVMTyBub3Qgc3VjY2Vzc2Z1bCcpXG4gICAgICB0aGlzLl9vbkVycm9yKG5ldyBFcnJvcihjb21tYW5kLmRhdGEpKVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHRoaXMuX2F1dGhlbnRpY2F0ZVVzZXIoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc3BvbnNlIHRvIEFVVEggTE9HSU4sIGlmIHN1Y2Nlc3NmdWwgZXhwZWN0cyBiYXNlNjQgZW5jb2RlZCB1c2VybmFtZVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCBQYXJzZWQgY29tbWFuZCBmcm9tIHRoZSBzZXJ2ZXIge3N0YXR1c0NvZGUsIGRhdGF9XG4gICAqL1xuICBfYWN0aW9uQVVUSF9MT0dJTl9VU0VSIChjb21tYW5kKSB7XG4gICAgaWYgKGNvbW1hbmQuc3RhdHVzQ29kZSAhPT0gMzM0IHx8IGNvbW1hbmQuZGF0YSAhPT0gJ1ZYTmxjbTVoYldVNicpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKERFQlVHX1RBRywgJ0FVVEggTE9HSU4gVVNFUiBub3Qgc3VjY2Vzc2Z1bDogJyArIGNvbW1hbmQuZGF0YSlcbiAgICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKCdJbnZhbGlkIGxvZ2luIHNlcXVlbmNlIHdoaWxlIHdhaXRpbmcgZm9yIFwiMzM0IFZYTmxjbTVoYldVNiBcIjogJyArIGNvbW1hbmQuZGF0YSkpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnQVVUSCBMT0dJTiBVU0VSIHN1Y2Nlc3NmdWwnKVxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25BVVRIX0xPR0lOX1BBU1NcbiAgICB0aGlzLl9zZW5kQ29tbWFuZChlbmNvZGUodGhpcy5vcHRpb25zLmF1dGgudXNlcikpXG4gIH1cblxuICAvKipcbiAgICogUmVzcG9uc2UgdG8gQVVUSCBMT0dJTiB1c2VybmFtZSwgaWYgc3VjY2Vzc2Z1bCBleHBlY3RzIGJhc2U2NCBlbmNvZGVkIHBhc3N3b3JkXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIFBhcnNlZCBjb21tYW5kIGZyb20gdGhlIHNlcnZlciB7c3RhdHVzQ29kZSwgZGF0YX1cbiAgICovXG4gIF9hY3Rpb25BVVRIX0xPR0lOX1BBU1MgKGNvbW1hbmQpIHtcbiAgICBpZiAoY29tbWFuZC5zdGF0dXNDb2RlICE9PSAzMzQgfHwgY29tbWFuZC5kYXRhICE9PSAnVUdGemMzZHZjbVE2Jykge1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoREVCVUdfVEFHLCAnQVVUSCBMT0dJTiBQQVNTIG5vdCBzdWNjZXNzZnVsOiAnICsgY29tbWFuZC5kYXRhKVxuICAgICAgdGhpcy5fb25FcnJvcihuZXcgRXJyb3IoJ0ludmFsaWQgbG9naW4gc2VxdWVuY2Ugd2hpbGUgd2FpdGluZyBmb3IgXCIzMzQgVUdGemMzZHZjbVE2IFwiOiAnICsgY29tbWFuZC5kYXRhKSlcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdBVVRIIExPR0lOIFBBU1Mgc3VjY2Vzc2Z1bCcpXG4gICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvbkFVVEhDb21wbGV0ZVxuICAgIHRoaXMuX3NlbmRDb21tYW5kKGVuY29kZSh0aGlzLm9wdGlvbnMuYXV0aC5wYXNzKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNwb25zZSB0byBBVVRIIFhPQVVUSDIgdG9rZW4sIGlmIGVycm9yIG9jY3VycyBzZW5kIGVtcHR5IHJlc3BvbnNlXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIFBhcnNlZCBjb21tYW5kIGZyb20gdGhlIHNlcnZlciB7c3RhdHVzQ29kZSwgZGF0YX1cbiAgICovXG4gIF9hY3Rpb25BVVRIX1hPQVVUSDIgKGNvbW1hbmQpIHtcbiAgICBpZiAoIWNvbW1hbmQuc3VjY2Vzcykge1xuICAgICAgdGhpcy5sb2dnZXIud2FybmluZyhERUJVR19UQUcsICdFcnJvciBkdXJpbmcgQVVUSCBYT0FVVEgyLCBzZW5kaW5nIGVtcHR5IHJlc3BvbnNlJylcbiAgICAgIHRoaXMuX3NlbmRDb21tYW5kKCcnKVxuICAgICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvbkFVVEhDb21wbGV0ZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9hY3Rpb25BVVRIQ29tcGxldGUoY29tbWFuZClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGF1dGhlbnRpY2F0aW9uIHN1Y2NlZWRlZCBvciBub3QuIElmIHN1Y2Nlc3NmdWxseSBhdXRoZW50aWNhdGVkXG4gICAqIGVtaXQgYGlkbGVgIHRvIGluZGljYXRlIHRoYXQgYW4gZS1tYWlsIGNhbiBiZSBzZW50IHVzaW5nIHRoaXMgY29ubmVjdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCBQYXJzZWQgY29tbWFuZCBmcm9tIHRoZSBzZXJ2ZXIge3N0YXR1c0NvZGUsIGRhdGF9XG4gICAqL1xuICBfYWN0aW9uQVVUSENvbXBsZXRlIChjb21tYW5kKSB7XG4gICAgaWYgKCFjb21tYW5kLnN1Y2Nlc3MpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZDogJyArIGNvbW1hbmQuZGF0YSlcbiAgICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKGNvbW1hbmQuZGF0YSkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdBdXRoZW50aWNhdGlvbiBzdWNjZXNzZnVsLicpXG5cbiAgICB0aGlzLl9hdXRoZW50aWNhdGVkQXMgPSB0aGlzLm9wdGlvbnMuYXV0aC51c2VyXG5cbiAgICB0aGlzLl9jdXJyZW50QWN0aW9uID0gdGhpcy5fYWN0aW9uSWRsZVxuICAgIHRoaXMub25pZGxlKCkgLy8gcmVhZHkgdG8gdGFrZSBvcmRlcnNcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgaWRsZSBhbmQgdGhlIHNlcnZlciBlbWl0cyB0aW1lb3V0XG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIFBhcnNlZCBjb21tYW5kIGZyb20gdGhlIHNlcnZlciB7c3RhdHVzQ29kZSwgZGF0YX1cbiAgICovXG4gIF9hY3Rpb25JZGxlIChjb21tYW5kKSB7XG4gICAgaWYgKGNvbW1hbmQuc3RhdHVzQ29kZSA+IDMwMCkge1xuICAgICAgdGhpcy5fb25FcnJvcihuZXcgRXJyb3IoY29tbWFuZC5kYXRhKSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKGNvbW1hbmQuZGF0YSkpXG4gIH1cblxuICAvKipcbiAgICogUmVzcG9uc2UgdG8gTUFJTCBGUk9NIGNvbW1hbmQuIFByb2NlZWQgdG8gZGVmaW5pbmcgUkNQVCBUTyBsaXN0IGlmIHN1Y2Nlc3NmdWxcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbW1hbmQgUGFyc2VkIGNvbW1hbmQgZnJvbSB0aGUgc2VydmVyIHtzdGF0dXNDb2RlLCBkYXRhfVxuICAgKi9cbiAgX2FjdGlvbk1BSUwgKGNvbW1hbmQpIHtcbiAgICBpZiAoIWNvbW1hbmQuc3VjY2Vzcykge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoREVCVUdfVEFHLCAnTUFJTCBGUk9NIHVuc3VjY2Vzc2Z1bDogJyArIGNvbW1hbmQuZGF0YSlcbiAgICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKGNvbW1hbmQuZGF0YSkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX2VudmVsb3BlLnJjcHRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX29uRXJyb3IobmV3IEVycm9yKCdDYW5cXCd0IHNlbmQgbWFpbCAtIG5vIHJlY2lwaWVudHMgZGVmaW5lZCcpKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdNQUlMIEZST00gc3VjY2Vzc2Z1bCwgcHJvY2VlZGluZyB3aXRoICcgKyB0aGlzLl9lbnZlbG9wZS5yY3B0UXVldWUubGVuZ3RoICsgJyByZWNpcGllbnRzJylcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ0FkZGluZyByZWNpcGllbnQuLi4nKVxuICAgICAgdGhpcy5fZW52ZWxvcGUuY3VyUmVjaXBpZW50ID0gdGhpcy5fZW52ZWxvcGUucmNwdFF1ZXVlLnNoaWZ0KClcbiAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25SQ1BUXG4gICAgICB0aGlzLl9zZW5kQ29tbWFuZCgnUkNQVCBUTzo8JyArIHRoaXMuX2VudmVsb3BlLmN1clJlY2lwaWVudCArICc+JylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzcG9uc2UgdG8gYSBSQ1BUIFRPIGNvbW1hbmQuIElmIHRoZSBjb21tYW5kIGlzIHVuc3VjY2Vzc2Z1bCwgdHJ5IHRoZSBuZXh0IG9uZSxcbiAgICogYXMgdGhpcyBtaWdodCBiZSByZWxhdGVkIG9ubHkgdG8gdGhlIGN1cnJlbnQgcmVjaXBpZW50LCBub3QgYSBnbG9iYWwgZXJyb3IsIHNvXG4gICAqIHRoZSBmb2xsb3dpbmcgcmVjaXBpZW50cyBtaWdodCBzdGlsbCBiZSB2YWxpZFxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29tbWFuZCBQYXJzZWQgY29tbWFuZCBmcm9tIHRoZSBzZXJ2ZXIge3N0YXR1c0NvZGUsIGRhdGF9XG4gICAqL1xuICBfYWN0aW9uUkNQVCAoY29tbWFuZCkge1xuICAgIGlmICghY29tbWFuZC5zdWNjZXNzKSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuaW5nKERFQlVHX1RBRywgJ1JDUFQgVE8gZmFpbGVkIGZvcjogJyArIHRoaXMuX2VudmVsb3BlLmN1clJlY2lwaWVudClcbiAgICAgIC8vIHRoaXMgaXMgYSBzb2Z0IGVycm9yXG4gICAgICB0aGlzLl9lbnZlbG9wZS5yY3B0RmFpbGVkLnB1c2godGhpcy5fZW52ZWxvcGUuY3VyUmVjaXBpZW50KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9lbnZlbG9wZS5yZXNwb25zZVF1ZXVlLnB1c2godGhpcy5fZW52ZWxvcGUuY3VyUmVjaXBpZW50KVxuICAgIH1cblxuICAgIGlmICghdGhpcy5fZW52ZWxvcGUucmNwdFF1ZXVlLmxlbmd0aCkge1xuICAgICAgaWYgKHRoaXMuX2VudmVsb3BlLnJjcHRGYWlsZWQubGVuZ3RoIDwgdGhpcy5fZW52ZWxvcGUudG8ubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25EQVRBXG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ1JDUFQgVE8gZG9uZSwgcHJvY2VlZGluZyB3aXRoIHBheWxvYWQnKVxuICAgICAgICB0aGlzLl9zZW5kQ29tbWFuZCgnREFUQScpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9vbkVycm9yKG5ldyBFcnJvcignQ2FuXFwndCBzZW5kIG1haWwgLSBhbGwgcmVjaXBpZW50cyB3ZXJlIHJlamVjdGVkJykpXG4gICAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25JZGxlXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ0FkZGluZyByZWNpcGllbnQuLi4nKVxuICAgICAgdGhpcy5fZW52ZWxvcGUuY3VyUmVjaXBpZW50ID0gdGhpcy5fZW52ZWxvcGUucmNwdFF1ZXVlLnNoaWZ0KClcbiAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25SQ1BUXG4gICAgICB0aGlzLl9zZW5kQ29tbWFuZCgnUkNQVCBUTzo8JyArIHRoaXMuX2VudmVsb3BlLmN1clJlY2lwaWVudCArICc+JylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzcG9uc2UgdG8gdGhlIERBVEEgY29tbWFuZC4gU2VydmVyIGlzIG5vdyB3YWl0aW5nIGZvciBhIG1lc3NhZ2UsIHNvIGVtaXQgYG9ucmVhZHlgXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21tYW5kIFBhcnNlZCBjb21tYW5kIGZyb20gdGhlIHNlcnZlciB7c3RhdHVzQ29kZSwgZGF0YX1cbiAgICovXG4gIF9hY3Rpb25EQVRBIChjb21tYW5kKSB7XG4gICAgLy8gcmVzcG9uc2Ugc2hvdWxkIGJlIDM1NCBidXQgYWNjb3JkaW5nIHRvIHRoaXMgaXNzdWUgaHR0cHM6Ly9naXRodWIuY29tL2VsZWl0aC9lbWFpbGpzL2lzc3Vlcy8yNFxuICAgIC8vIHNvbWUgc2VydmVycyBtaWdodCB1c2UgMjUwIGluc3RlYWRcbiAgICBpZiAoWzI1MCwgMzU0XS5pbmRleE9mKGNvbW1hbmQuc3RhdHVzQ29kZSkgPCAwKSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihERUJVR19UQUcsICdEQVRBIHVuc3VjY2Vzc2Z1bCAnICsgY29tbWFuZC5kYXRhKVxuICAgICAgdGhpcy5fb25FcnJvcihuZXcgRXJyb3IoY29tbWFuZC5kYXRhKSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuX2RhdGFNb2RlID0gdHJ1ZVxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25JZGxlXG4gICAgdGhpcy5vbnJlYWR5KHRoaXMuX2VudmVsb3BlLnJjcHRGYWlsZWQpXG4gIH1cblxuICAvKipcbiAgICogUmVzcG9uc2UgZnJvbSB0aGUgc2VydmVyLCBvbmNlIHRoZSBtZXNzYWdlIHN0cmVhbSBoYXMgZW5kZWQgd2l0aCA8Q1I+PExGPi48Q1I+PExGPlxuICAgKiBFbWl0cyBgb25kb25lYC5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbW1hbmQgUGFyc2VkIGNvbW1hbmQgZnJvbSB0aGUgc2VydmVyIHtzdGF0dXNDb2RlLCBkYXRhfVxuICAgKi9cbiAgX2FjdGlvblN0cmVhbSAoY29tbWFuZCkge1xuICAgIHZhciByY3B0XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmxtdHApIHtcbiAgICAgIC8vIExNVFAgcmV0dXJucyBhIHJlc3BvbnNlIGNvZGUgZm9yICpldmVyeSogc3VjY2Vzc2Z1bGx5IHNldCByZWNpcGllbnRcbiAgICAgIC8vIEZvciBldmVyeSByZWNpcGllbnQgdGhlIG1lc3NhZ2UgbWlnaHQgc3VjY2VlZCBvciBmYWlsIGluZGl2aWR1YWxseVxuXG4gICAgICByY3B0ID0gdGhpcy5fZW52ZWxvcGUucmVzcG9uc2VRdWV1ZS5zaGlmdCgpXG4gICAgICBpZiAoIWNvbW1hbmQuc3VjY2Vzcykge1xuICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihERUJVR19UQUcsICdMb2NhbCBkZWxpdmVyeSB0byAnICsgcmNwdCArICcgZmFpbGVkLicpXG4gICAgICAgIHRoaXMuX2VudmVsb3BlLnJjcHRGYWlsZWQucHVzaChyY3B0KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoREVCVUdfVEFHLCAnTG9jYWwgZGVsaXZlcnkgdG8gJyArIHJjcHQgKyAnIHN1Y2NlZWRlZC4nKVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fZW52ZWxvcGUucmVzcG9uc2VRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvblN0cmVhbVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgdGhpcy5fY3VycmVudEFjdGlvbiA9IHRoaXMuX2FjdGlvbklkbGVcbiAgICAgIHRoaXMub25kb25lKHRydWUpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZvciBTTVRQIHRoZSBtZXNzYWdlIGVpdGhlciBmYWlscyBvciBzdWNjZWVkcywgdGhlcmUgaXMgbm8gaW5mb3JtYXRpb25cbiAgICAgIC8vIGFib3V0IGluZGl2aWR1YWwgcmVjaXBpZW50c1xuXG4gICAgICBpZiAoIWNvbW1hbmQuc3VjY2Vzcykge1xuICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihERUJVR19UQUcsICdNZXNzYWdlIHNlbmRpbmcgZmFpbGVkLicpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhERUJVR19UQUcsICdNZXNzYWdlIHNlbnQgc3VjY2Vzc2Z1bGx5LicpXG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2N1cnJlbnRBY3Rpb24gPSB0aGlzLl9hY3Rpb25JZGxlXG4gICAgICB0aGlzLm9uZG9uZSghIWNvbW1hbmQuc3VjY2VzcylcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgY2xpZW50IHdhbnRlZCB0byBkbyBzb21ldGhpbmcgZWxzZSAoZWcuIHRvIHF1aXQpLCBkbyBub3QgZm9yY2UgaWRsZVxuICAgIGlmICh0aGlzLl9jdXJyZW50QWN0aW9uID09PSB0aGlzLl9hY3Rpb25JZGxlKSB7XG4gICAgICAvLyBXYWl0aW5nIGZvciBuZXcgY29ubmVjdGlvbnNcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKERFQlVHX1RBRywgJ0lkbGluZyB3aGlsZSB3YWl0aW5nIGZvciBuZXcgY29ubmVjdGlvbnMuLi4nKVxuICAgICAgdGhpcy5vbmlkbGUoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBsb2dpbiB0b2tlbiBmb3IgWE9BVVRIMiBhdXRoZW50aWNhdGlvbiBjb21tYW5kXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB1c2VyIEUtbWFpbCBhZGRyZXNzIG9mIHRoZSB1c2VyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0b2tlbiBWYWxpZCBhY2Nlc3MgdG9rZW4gZm9yIHRoZSB1c2VyXG4gICAqIEByZXR1cm4ge1N0cmluZ30gQmFzZTY0IGZvcm1hdHRlZCBsb2dpbiB0b2tlblxuICAgKi9cbiAgX2J1aWxkWE9BdXRoMlRva2VuICh1c2VyLCB0b2tlbikge1xuICAgIHZhciBhdXRoRGF0YSA9IFtcbiAgICAgICd1c2VyPScgKyAodXNlciB8fCAnJyksXG4gICAgICAnYXV0aD1CZWFyZXIgJyArIHRva2VuLFxuICAgICAgJycsXG4gICAgICAnJ1xuICAgIF1cbiAgICAvLyBiYXNlNjQoXCJ1c2VyPXtVc2VyfVxceDAwYXV0aD1CZWFyZXIge1Rva2VufVxceDAwXFx4MDBcIilcbiAgICByZXR1cm4gZW5jb2RlKGF1dGhEYXRhLmpvaW4oJ1xceDAxJykpXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgU210cENsaWVudFxuIl19 \ No newline at end of file diff --git a/dist/common.js b/dist/common.js deleted file mode 100644 index 8c68a97..0000000 --- a/dist/common.js +++ /dev/null @@ -1,12 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var LOG_LEVEL_NONE = exports.LOG_LEVEL_NONE = 1000; -var LOG_LEVEL_ERROR = exports.LOG_LEVEL_ERROR = 40; -var LOG_LEVEL_WARN = exports.LOG_LEVEL_WARN = 30; -var LOG_LEVEL_INFO = exports.LOG_LEVEL_INFO = 20; -var LOG_LEVEL_DEBUG = exports.LOG_LEVEL_DEBUG = 10; -var LOG_LEVEL_ALL = exports.LOG_LEVEL_ALL = 0; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tb24uanMiXSwibmFtZXMiOlsiTE9HX0xFVkVMX05PTkUiLCJMT0dfTEVWRUxfRVJST1IiLCJMT0dfTEVWRUxfV0FSTiIsIkxPR19MRVZFTF9JTkZPIiwiTE9HX0xFVkVMX0RFQlVHIiwiTE9HX0xFVkVMX0FMTCJdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBTyxJQUFNQSwwQ0FBaUIsSUFBdkI7QUFDQSxJQUFNQyw0Q0FBa0IsRUFBeEI7QUFDQSxJQUFNQywwQ0FBaUIsRUFBdkI7QUFDQSxJQUFNQywwQ0FBaUIsRUFBdkI7QUFDQSxJQUFNQyw0Q0FBa0IsRUFBeEI7QUFDQSxJQUFNQyx3Q0FBZ0IsQ0FBdEIiLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IExPR19MRVZFTF9OT05FID0gMTAwMFxuZXhwb3J0IGNvbnN0IExPR19MRVZFTF9FUlJPUiA9IDQwXG5leHBvcnQgY29uc3QgTE9HX0xFVkVMX1dBUk4gPSAzMFxuZXhwb3J0IGNvbnN0IExPR19MRVZFTF9JTkZPID0gMjBcbmV4cG9ydCBjb25zdCBMT0dfTEVWRUxfREVCVUcgPSAxMFxuZXhwb3J0IGNvbnN0IExPR19MRVZFTF9BTEwgPSAwXG4iXX0= \ No newline at end of file diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index e4e45b6..0000000 --- a/dist/index.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.LOG_LEVEL_ALL = exports.LOG_LEVEL_DEBUG = exports.LOG_LEVEL_INFO = exports.LOG_LEVEL_WARN = exports.LOG_LEVEL_ERROR = exports.LOG_LEVEL_NONE = undefined; - -var _common = require('./common'); - -Object.defineProperty(exports, 'LOG_LEVEL_NONE', { - enumerable: true, - get: function get() { - return _common.LOG_LEVEL_NONE; - } -}); -Object.defineProperty(exports, 'LOG_LEVEL_ERROR', { - enumerable: true, - get: function get() { - return _common.LOG_LEVEL_ERROR; - } -}); -Object.defineProperty(exports, 'LOG_LEVEL_WARN', { - enumerable: true, - get: function get() { - return _common.LOG_LEVEL_WARN; - } -}); -Object.defineProperty(exports, 'LOG_LEVEL_INFO', { - enumerable: true, - get: function get() { - return _common.LOG_LEVEL_INFO; - } -}); -Object.defineProperty(exports, 'LOG_LEVEL_DEBUG', { - enumerable: true, - get: function get() { - return _common.LOG_LEVEL_DEBUG; - } -}); -Object.defineProperty(exports, 'LOG_LEVEL_ALL', { - enumerable: true, - get: function get() { - return _common.LOG_LEVEL_ALL; - } -}); - -var _client = require('./client'); - -var _client2 = _interopRequireDefault(_client); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.default = _client2.default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJMT0dfTEVWRUxfTk9ORSIsIkxPR19MRVZFTF9FUlJPUiIsIkxPR19MRVZFTF9XQVJOIiwiTE9HX0xFVkVMX0lORk8iLCJMT0dfTEVWRUxfREVCVUciLCJMT0dfTEVWRUxfQUxMIiwiU210cENsaWVudCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O21CQUdFQSxjOzs7Ozs7bUJBQ0FDLGU7Ozs7OzttQkFDQUMsYzs7Ozs7O21CQUNBQyxjOzs7Ozs7bUJBQ0FDLGU7Ozs7OzttQkFDQUMsYTs7OztBQVJGOzs7Ozs7a0JBV2VDLGdCIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFNtdHBDbGllbnQgZnJvbSAnLi9jbGllbnQnXG5cbmV4cG9ydCB7XG4gIExPR19MRVZFTF9OT05FLFxuICBMT0dfTEVWRUxfRVJST1IsXG4gIExPR19MRVZFTF9XQVJOLFxuICBMT0dfTEVWRUxfSU5GTyxcbiAgTE9HX0xFVkVMX0RFQlVHLFxuICBMT0dfTEVWRUxfQUxMXG59IGZyb20gJy4vY29tbW9uJ1xuXG5leHBvcnQgZGVmYXVsdCBTbXRwQ2xpZW50XG4iXX0= \ No newline at end of file diff --git a/dist/logger.js b/dist/logger.js deleted file mode 100644 index 74e87f2..0000000 --- a/dist/logger.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = createDefaultLogger; - -var _common = require('./common'); - -var SESSIONCOUNTER = 0; - -function createDefaultLogger(username, hostname) { - var session = ++SESSIONCOUNTER; - var log = function log(level, messages) { - messages = messages.map(function (msg) { - return typeof msg === 'function' ? msg() : msg; - }); - var date = new Date().toISOString(); - var logMessage = '[' + date + '][' + session + '][' + username + '][' + hostname + '] ' + messages.join(' '); - if (level === _common.LOG_LEVEL_DEBUG) { - console.log('[DEBUG]' + logMessage); - } else if (level === _common.LOG_LEVEL_INFO) { - console.info('[INFO]' + logMessage); - } else if (level === _common.LOG_LEVEL_WARN) { - console.warn('[WARN]' + logMessage); - } else if (level === _common.LOG_LEVEL_ERROR) { - console.error('[ERROR]' + logMessage); - } - }; - - return { - debug: function debug(msgs) { - return log(_common.LOG_LEVEL_DEBUG, msgs); - }, - info: function info(msgs) { - return log(_common.LOG_LEVEL_INFO, msgs); - }, - warn: function warn(msgs) { - return log(_common.LOG_LEVEL_WARN, msgs); - }, - error: function error(msgs) { - return log(_common.LOG_LEVEL_ERROR, msgs); - } - }; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9sb2dnZXIuanMiXSwibmFtZXMiOlsiY3JlYXRlRGVmYXVsdExvZ2dlciIsIlNFU1NJT05DT1VOVEVSIiwidXNlcm5hbWUiLCJob3N0bmFtZSIsInNlc3Npb24iLCJsb2ciLCJsZXZlbCIsIm1lc3NhZ2VzIiwibWFwIiwibXNnIiwiZGF0ZSIsIkRhdGUiLCJ0b0lTT1N0cmluZyIsImxvZ01lc3NhZ2UiLCJqb2luIiwiTE9HX0xFVkVMX0RFQlVHIiwiY29uc29sZSIsIkxPR19MRVZFTF9JTkZPIiwiaW5mbyIsIkxPR19MRVZFTF9XQVJOIiwid2FybiIsIkxPR19MRVZFTF9FUlJPUiIsImVycm9yIiwiZGVidWciLCJtc2dzIl0sIm1hcHBpbmdzIjoiOzs7OztrQkFTd0JBLG1COztBQVR4Qjs7QUFPQSxJQUFJQyxpQkFBaUIsQ0FBckI7O0FBRWUsU0FBU0QsbUJBQVQsQ0FBOEJFLFFBQTlCLEVBQXdDQyxRQUF4QyxFQUFrRDtBQUMvRCxNQUFNQyxVQUFVLEVBQUVILGNBQWxCO0FBQ0EsTUFBSUksTUFBTSxTQUFOQSxHQUFNLENBQUNDLEtBQUQsRUFBUUMsUUFBUixFQUFxQjtBQUM3QkEsZUFBV0EsU0FBU0MsR0FBVCxDQUFhO0FBQUEsYUFBTyxPQUFPQyxHQUFQLEtBQWUsVUFBZixHQUE0QkEsS0FBNUIsR0FBb0NBLEdBQTNDO0FBQUEsS0FBYixDQUFYO0FBQ0EsUUFBTUMsT0FBTyxJQUFJQyxJQUFKLEdBQVdDLFdBQVgsRUFBYjtBQUNBLFFBQUlDLG1CQUFpQkgsSUFBakIsVUFBMEJOLE9BQTFCLFVBQXNDRixRQUF0QyxVQUFtREMsUUFBbkQsVUFBZ0VJLFNBQVNPLElBQVQsQ0FBYyxHQUFkLENBQXBFO0FBQ0EsUUFBSVIsVUFBVVMsdUJBQWQsRUFBK0I7QUFDN0JDLGNBQVFYLEdBQVIsQ0FBWSxZQUFZUSxVQUF4QjtBQUNELEtBRkQsTUFFTyxJQUFJUCxVQUFVVyxzQkFBZCxFQUE4QjtBQUNuQ0QsY0FBUUUsSUFBUixDQUFhLFdBQVdMLFVBQXhCO0FBQ0QsS0FGTSxNQUVBLElBQUlQLFVBQVVhLHNCQUFkLEVBQThCO0FBQ25DSCxjQUFRSSxJQUFSLENBQWEsV0FBV1AsVUFBeEI7QUFDRCxLQUZNLE1BRUEsSUFBSVAsVUFBVWUsdUJBQWQsRUFBK0I7QUFDcENMLGNBQVFNLEtBQVIsQ0FBYyxZQUFZVCxVQUExQjtBQUNEO0FBQ0YsR0FiRDs7QUFlQSxTQUFPO0FBQ0xVLFdBQU87QUFBQSxhQUFRbEIsSUFBSVUsdUJBQUosRUFBcUJTLElBQXJCLENBQVI7QUFBQSxLQURGO0FBRUxOLFVBQU07QUFBQSxhQUFRYixJQUFJWSxzQkFBSixFQUFvQk8sSUFBcEIsQ0FBUjtBQUFBLEtBRkQ7QUFHTEosVUFBTTtBQUFBLGFBQVFmLElBQUljLHNCQUFKLEVBQW9CSyxJQUFwQixDQUFSO0FBQUEsS0FIRDtBQUlMRixXQUFPO0FBQUEsYUFBUWpCLElBQUlnQix1QkFBSixFQUFxQkcsSUFBckIsQ0FBUjtBQUFBO0FBSkYsR0FBUDtBQU1EIiwiZmlsZSI6ImxvZ2dlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIExPR19MRVZFTF9FUlJPUixcbiAgTE9HX0xFVkVMX1dBUk4sXG4gIExPR19MRVZFTF9JTkZPLFxuICBMT0dfTEVWRUxfREVCVUdcbn0gZnJvbSAnLi9jb21tb24nXG5cbmxldCBTRVNTSU9OQ09VTlRFUiA9IDBcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY3JlYXRlRGVmYXVsdExvZ2dlciAodXNlcm5hbWUsIGhvc3RuYW1lKSB7XG4gIGNvbnN0IHNlc3Npb24gPSArK1NFU1NJT05DT1VOVEVSXG4gIGxldCBsb2cgPSAobGV2ZWwsIG1lc3NhZ2VzKSA9PiB7XG4gICAgbWVzc2FnZXMgPSBtZXNzYWdlcy5tYXAobXNnID0+IHR5cGVvZiBtc2cgPT09ICdmdW5jdGlvbicgPyBtc2coKSA6IG1zZylcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgbGV0IGxvZ01lc3NhZ2UgPSBgWyR7ZGF0ZX1dWyR7c2Vzc2lvbn1dWyR7dXNlcm5hbWV9XVske2hvc3RuYW1lfV0gJHttZXNzYWdlcy5qb2luKCcgJyl9YFxuICAgIGlmIChsZXZlbCA9PT0gTE9HX0xFVkVMX0RFQlVHKSB7XG4gICAgICBjb25zb2xlLmxvZygnW0RFQlVHXScgKyBsb2dNZXNzYWdlKVxuICAgIH0gZWxzZSBpZiAobGV2ZWwgPT09IExPR19MRVZFTF9JTkZPKSB7XG4gICAgICBjb25zb2xlLmluZm8oJ1tJTkZPXScgKyBsb2dNZXNzYWdlKVxuICAgIH0gZWxzZSBpZiAobGV2ZWwgPT09IExPR19MRVZFTF9XQVJOKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tXQVJOXScgKyBsb2dNZXNzYWdlKVxuICAgIH0gZWxzZSBpZiAobGV2ZWwgPT09IExPR19MRVZFTF9FUlJPUikge1xuICAgICAgY29uc29sZS5lcnJvcignW0VSUk9SXScgKyBsb2dNZXNzYWdlKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZGVidWc6IG1zZ3MgPT4gbG9nKExPR19MRVZFTF9ERUJVRywgbXNncyksXG4gICAgaW5mbzogbXNncyA9PiBsb2coTE9HX0xFVkVMX0lORk8sIG1zZ3MpLFxuICAgIHdhcm46IG1zZ3MgPT4gbG9nKExPR19MRVZFTF9XQVJOLCBtc2dzKSxcbiAgICBlcnJvcjogbXNncyA9PiBsb2coTE9HX0xFVkVMX0VSUk9SLCBtc2dzKVxuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/dist/parser.js b/dist/parser.js deleted file mode 100644 index 28929d4..0000000 --- a/dist/parser.js +++ /dev/null @@ -1,152 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var SmtpResponseParser = function () { - /** - * Generates a parser object for data coming from a SMTP server - */ - function SmtpResponseParser() { - _classCallCheck(this, SmtpResponseParser); - - this.destroyed = false; // If set to true, do not accept any more input - - // Event placeholders - // NB! Errors do not block, the parsing and data emitting continues despite of the errors - this.onerror = function () {}; - this.ondata = function () {}; - this.onend = function () {}; - - this._block = { data: [], lines: [], statusCode: null // If the response is a list, contains previous not yet emitted lines - };this._remainder = ''; // If the complete line is not received yet, contains the beginning of it - } - - /** - * Queue some data from the server for parsing. Only allowed, if 'end' has not been called yet - * - * @param {String} chunk Chunk of data received from the server - */ - - - _createClass(SmtpResponseParser, [{ - key: 'send', - value: function send(chunk) { - if (this.destroyed) { - return this.onerror(new Error('This parser has already been closed, "write" is prohibited')); - } - - // Lines should always end with but you never know, might be only as well - var lines = (this._remainder + (chunk || '')).split(/\r?\n/); - this._remainder = lines.pop(); // not sure if the line has completely arrived yet - - for (var i = 0, len = lines.length; i < len; i++) { - this._processLine(lines[i]); - } - } - - /** - * Indicate that all the data from the server has been received. Can be called only once. - * - * @param {String} [chunk] Chunk of data received from the server - */ - - }, { - key: 'end', - value: function end(chunk) { - if (this.destroyed) { - return this.onerror(new Error('This parser has already been closed, "end" is prohibited')); - } - - if (chunk) { - this.send(chunk); - } - - if (this._remainder) { - this._processLine(this._remainder); - } - - this.destroyed = true; - this.onend(); - } - - // Private API - - /** - * Processes a single and complete line. If it is a continous one (slash after status code), - * queue it to this._block - * - * @param {String} line Complete line of data from the server - */ - - }, { - key: '_processLine', - value: function _processLine(line) { - var match, response; - - // possible input strings for the regex: - // 250-MESSAGE - // 250 MESSAGE - // 250 1.2.3 MESSAGE - - if (!line.trim()) { - // nothing to check, empty line - return; - } - - this._block.lines.push(line); - - if (match = line.match(/^(\d{3})([- ])(?:(\d+\.\d+\.\d+)(?: ))?(.*)/)) { - this._block.data.push(match[4]); - - if (match[2] === '-') { - if (this._block.statusCode && this._block.statusCode !== Number(match[1])) { - this.onerror('Invalid status code ' + match[1] + ' for multi line response (' + this._block.statusCode + ' expected)'); - } else if (!this._block.statusCode) { - this._block.statusCode = Number(match[1]); - } - } else { - response = { - statusCode: Number(match[1]) || 0, - enhancedStatus: match[3] || null, - data: this._block.data.join('\n'), - line: this._block.lines.join('\n') - }; - response.success = response.statusCode >= 200 && response.statusCode < 300; - - this.ondata(response); - this._block = { - data: [], - lines: [], - statusCode: null - }; - this._block.statusCode = null; - } - } else { - this.onerror(new Error('Invalid SMTP response "' + line + '"')); - this.ondata({ - success: false, - statusCode: this._block.statusCode || null, - enhancedStatus: null, - data: [line].join('\n'), - line: this._block.lines.join('\n') - }); - this._block = { - data: [], - lines: [], - statusCode: null - }; - } - } - }]); - - return SmtpResponseParser; -}(); - -exports.default = SmtpResponseParser; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9wYXJzZXIuanMiXSwibmFtZXMiOlsiU210cFJlc3BvbnNlUGFyc2VyIiwiZGVzdHJveWVkIiwib25lcnJvciIsIm9uZGF0YSIsIm9uZW5kIiwiX2Jsb2NrIiwiZGF0YSIsImxpbmVzIiwic3RhdHVzQ29kZSIsIl9yZW1haW5kZXIiLCJjaHVuayIsIkVycm9yIiwic3BsaXQiLCJwb3AiLCJpIiwibGVuIiwibGVuZ3RoIiwiX3Byb2Nlc3NMaW5lIiwic2VuZCIsImxpbmUiLCJtYXRjaCIsInJlc3BvbnNlIiwidHJpbSIsInB1c2giLCJOdW1iZXIiLCJlbmhhbmNlZFN0YXR1cyIsImpvaW4iLCJzdWNjZXNzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0lBQU1BLGtCO0FBQ0o7OztBQUdBLGdDQUFlO0FBQUE7O0FBQ2IsU0FBS0MsU0FBTCxHQUFpQixLQUFqQixDQURhLENBQ1U7O0FBRXZCO0FBQ0E7QUFDQSxTQUFLQyxPQUFMLEdBQWUsWUFBTSxDQUFHLENBQXhCO0FBQ0EsU0FBS0MsTUFBTCxHQUFjLFlBQU0sQ0FBRyxDQUF2QjtBQUNBLFNBQUtDLEtBQUwsR0FBYSxZQUFNLENBQUcsQ0FBdEI7O0FBRUEsU0FBS0MsTUFBTCxHQUFjLEVBQUVDLE1BQU0sRUFBUixFQUFZQyxPQUFPLEVBQW5CLEVBQXVCQyxZQUFZLElBQW5DLENBQTBDO0FBQTFDLEtBQWQsQ0FDQSxLQUFLQyxVQUFMLEdBQWtCLEVBQWxCLENBVmEsQ0FVUTtBQUN0Qjs7QUFFRDs7Ozs7Ozs7O3lCQUtNQyxLLEVBQU87QUFDWCxVQUFJLEtBQUtULFNBQVQsRUFBb0I7QUFDbEIsZUFBTyxLQUFLQyxPQUFMLENBQWEsSUFBSVMsS0FBSixDQUFVLDREQUFWLENBQWIsQ0FBUDtBQUNEOztBQUVEO0FBQ0EsVUFBSUosUUFBUSxDQUFDLEtBQUtFLFVBQUwsSUFBbUJDLFNBQVMsRUFBNUIsQ0FBRCxFQUFrQ0UsS0FBbEMsQ0FBd0MsT0FBeEMsQ0FBWjtBQUNBLFdBQUtILFVBQUwsR0FBa0JG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QUlWbkIsZ0JBQU0sQ0FBQ2EsSUFBRCxFQUFPTyxJQUFQLENBQVksSUFBWixDQUpJO0FBS1ZQLGdCQUFNLEtBQUtkLE1BQUwsQ0FBWUUsS0FBWixDQUFrQm1CLElBQWxCLENBQXVCLElBQXZCO0FBTEksU0FBWjtBQU9BLGFBQUtyQixNQUFMLEdBQWM7QUFDWkMsZ0JBQU0sRUFETTtBQUVaQyxpQkFBTyxFQUZLO0FBR1pDLHNCQUFZO0FBSEEsU0FBZDtBQUtEO0FBQ0Y7Ozs7OztrQkFHWVIsa0IiLCJmaWxlIjoicGFyc2VyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgU210cFJlc3BvbnNlUGFyc2VyIHtcbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBhIHBhcnNlciBvYmplY3QgZm9yIGRhdGEgY29taW5nIGZyb20gYSBTTVRQIHNlcnZlclxuICAgKi9cbiAgY29uc3RydWN0b3IgKCkge1xuICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2UgLy8gSWYgc2V0IHRvIHRydWUsIGRvIG5vdCBhY2NlcHQgYW55IG1vcmUgaW5wdXRcblxuICAgIC8vIEV2ZW50IHBsYWNlaG9sZGVyc1xuICAgIC8vIE5CISBFcnJvcnMgZG8gbm90IGJsb2NrLCB0aGUgcGFyc2luZyBhbmQgZGF0YSBlbWl0dGluZyBjb250aW51ZXMgZGVzcGl0ZSBvZiB0aGUgZXJyb3JzXG4gICAgdGhpcy5vbmVycm9yID0gKCkgPT4geyB9XG4gICAgdGhpcy5vbmRhdGEgPSAoKSA9PiB7IH1cbiAgICB0aGlzLm9uZW5kID0gKCkgPT4geyB9XG5cbiAgICB0aGlzLl9ibG9jayA9IHsgZGF0YTogW10sIGxpbmVzOiBbXSwgc3RhdHVzQ29kZTogbnVsbCB9IC8vIElmIHRoZSByZXNwb25zZSBpcyBhIGxpc3QsIGNvbnRhaW5zIHByZXZpb3VzIG5vdCB5ZXQgZW1pdHRlZCBsaW5lc1xuICAgIHRoaXMuX3JlbWFpbmRlciA9ICcnIC8vIElmIHRoZSBjb21wbGV0ZSBsaW5lIGlzIG5vdCByZWNlaXZlZCB5ZXQsIGNvbnRhaW5zIHRoZSBiZWdpbm5pbmcgb2YgaXRcbiAgfVxuXG4gIC8qKlxuICAgKiBRdWV1ZSBzb21lIGRhdGEgZnJvbSB0aGUgc2VydmVyIGZvciBwYXJzaW5nLiBPbmx5IGFsbG93ZWQsIGlmICdlbmQnIGhhcyBub3QgYmVlbiBjYWxsZWQgeWV0XG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjaHVuayBDaHVuayBvZiBkYXRhIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlclxuICAgKi9cbiAgc2VuZCAoY2h1bmspIHtcbiAgICBpZiAodGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLm9uZXJyb3IobmV3IEVycm9yKCdUaGlzIHBhcnNlciBoYXMgYWxyZWFkeSBiZWVuIGNsb3NlZCwgXCJ3cml0ZVwiIGlzIHByb2hpYml0ZWQnKSlcbiAgICB9XG5cbiAgICAvLyBMaW5lcyBzaG91bGQgYWx3YXlzIGVuZCB3aXRoIDxDUj48TEY+IGJ1dCB5b3UgbmV2ZXIga25vdywgbWlnaHQgYmUgb25seSA8TEY+IGFzIHdlbGxcbiAgICB2YXIgbGluZXMgPSAodGhpcy5fcmVtYWluZGVyICsgKGNodW5rIHx8ICcnKSkuc3BsaXQoL1xccj9cXG4vKVxuICAgIHRoaXMuX3JlbWFpbmRlciA9IGxpbmVzLnBvcCgpIC8vIG5vdCBzdXJlIGlmIHRoZSBsaW5lIGhhcyBjb21wbGV0ZWx5IGFycml2ZWQgeWV0XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGluZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHRoaXMuX3Byb2Nlc3NMaW5lKGxpbmVzW2ldKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZSB0aGF0IGFsbCB0aGUgZGF0YSBmcm9tIHRoZSBzZXJ2ZXIgaGFzIGJlZW4gcmVjZWl2ZWQuIENhbiBiZSBjYWxsZWQgb25seSBvbmNlLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gW2NodW5rXSBDaHVuayBvZiBkYXRhIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlclxuICAgKi9cbiAgZW5kIChjaHVuaykge1xuICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgcmV0dXJuIHRoaXMub25lcnJvcihuZXcgRXJyb3IoJ1RoaXMgcGFyc2VyIGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkLCBcImVuZFwiIGlzIHByb2hpYml0ZWQnKSlcbiAgICB9XG5cbiAgICBpZiAoY2h1bmspIHtcbiAgICAgIHRoaXMuc2VuZChjaHVuaylcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcmVtYWluZGVyKSB7XG4gICAgICB0aGlzLl9wcm9jZXNzTGluZSh0aGlzLl9yZW1haW5kZXIpXG4gICAgfVxuXG4gICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlXG4gICAgdGhpcy5vbmVuZCgpXG4gIH1cblxuICAvLyBQcml2YXRlIEFQSVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzZXMgYSBzaW5nbGUgYW5kIGNvbXBsZXRlIGxpbmUuIElmIGl0IGlzIGEgY29udGlub3VzIG9uZSAoc2xhc2ggYWZ0ZXIgc3RhdHVzIGNvZGUpLFxuICAgKiBxdWV1ZSBpdCB0byB0aGlzLl9ibG9ja1xuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbGluZSBDb21wbGV0ZSBsaW5lIG9mIGRhdGEgZnJvbSB0aGUgc2VydmVyXG4gICAqL1xuICBfcHJvY2Vzc0xpbmUgKGxpbmUpIHtcbiAgICB2YXIgbWF0Y2gsIHJlc3BvbnNlXG5cbiAgICAvLyBwb3NzaWJsZSBpbnB1dCBzdHJpbmdzIGZvciB0aGUgcmVnZXg6XG4gICAgLy8gMjUwLU1FU1NBR0VcbiAgICAvLyAyNTAgTUVTU0FHRVxuICAgIC8vIDI1MCAxLjIuMyBNRVNTQUdFXG5cbiAgICBpZiAoIWxpbmUudHJpbSgpKSB7XG4gICAgICAvLyBub3RoaW5nIHRvIGNoZWNrLCBlbXB0eSBsaW5lXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLl9ibG9jay5saW5lcy5wdXNoKGxpbmUpXG5cbiAgICBpZiAoKG1hdGNoID0gbGluZS5tYXRjaCgvXihcXGR7M30pKFstIF0pKD86KFxcZCtcXC5cXGQrXFwuXFxkKykoPzogKSk/KC4qKS8pKSkge1xuICAgICAgdGhpcy5fYmxvY2suZGF0YS5wdXNoKG1hdGNoWzRdKVxuXG4gICAgICBpZiAobWF0Y2hbMl0gPT09ICctJykge1xuICAgICAgICBpZiAodGhpcy5fYmxvY2suc3RhdHVzQ29kZSAmJiB0aGlzLl9ibG9jay5zdGF0dXNDb2RlICE9PSBOdW1iZXIobWF0Y2hbMV0pKSB7XG4gICAgICAgICAgdGhpcy5vbmVycm9yKCdJbnZhbGlkIHN0YXR1cyBjb2RlICcgKyBtYXRjaFsxXSArXG4gICAgICAgICAgICAnIGZvciBtdWx0aSBsaW5lIHJlc3BvbnNlICgnICsgdGhpcy5fYmxvY2suc3RhdHVzQ29kZSArICcgZXhwZWN0ZWQpJylcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5fYmxvY2suc3RhdHVzQ29kZSkge1xuICAgICAgICAgIHRoaXMuX2Jsb2NrLnN0YXR1c0NvZGUgPSBOdW1iZXIobWF0Y2hbMV0pXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3BvbnNlID0ge1xuICAgICAgICAgIHN0YXR1c0NvZGU6IE51bWJlcihtYXRjaFsxXSkgfHwgMCxcbiAgICAgICAgICBlbmhhbmNlZFN0YXR1czogbWF0Y2hbM10gfHwgbnVsbCxcbiAgICAgICAgICBkYXRhOiB0aGlzLl9ibG9jay5kYXRhLmpvaW4oJ1xcbicpLFxuICAgICAgICAgIGxpbmU6IHRoaXMuX2Jsb2NrLmxpbmVzLmpvaW4oJ1xcbicpXG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2Uuc3VjY2VzcyA9IHJlc3BvbnNlLnN0YXR1c0NvZGUgPj0gMjAwICYmIHJlc3BvbnNlLnN0YXR1c0NvZGUgPCAzMDBcblxuICAgICAgICB0aGlzLm9uZGF0YShyZXNwb25zZSlcbiAgICAgICAgdGhpcy5fYmxvY2sgPSB7XG4gICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgbGluZXM6IFtdLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IG51bGxcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9ibG9jay5zdGF0dXNDb2RlID0gbnVsbFxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9uZXJyb3IobmV3IEVycm9yKCdJbnZhbGlkIFNNVFAgcmVzcG9uc2UgXCInICsgbGluZSArICdcIicpKVxuICAgICAgdGhpcy5vbmRhdGEoe1xuICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgc3RhdHVzQ29kZTogdGhpcy5fYmxvY2suc3RhdHVzQ29kZSB8fCBudWxsLFxuICAgICAgICBlbmhhbmNlZFN0YXR1czogbnVsbCxcbiAgICAgICAgZGF0YTogW2xpbmVdLmpvaW4oJ1xcbicpLFxuICAgICAgICBsaW5lOiB0aGlzLl9ibG9jay5saW5lcy5qb2luKCdcXG4nKVxuICAgICAgfSlcbiAgICAgIHRoaXMuX2Jsb2NrID0ge1xuICAgICAgICBkYXRhOiBbXSxcbiAgICAgICAgbGluZXM6IFtdLFxuICAgICAgICBzdGF0dXNDb2RlOiBudWxsXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNtdHBSZXNwb25zZVBhcnNlclxuIl19 \ No newline at end of file diff --git a/src/client.js b/src/client.js index 6ce50a6..22d94ff 100644 --- a/src/client.js +++ b/src/client.js @@ -61,6 +61,7 @@ class SmtpClient { this.socket = false // Downstream TCP socket to the SMTP server, created with mozTCPSocket this.destroyed = false // Indicates if the connection has been closed and can't be used anymore this.waitDrain = false // Keeps track if the downstream socket is currently full and a drain event should be waited for or not + this.maxAllowedSize = 0 // Stores the max message size supported by the server as reported in the greeting // Private properties @@ -597,8 +598,8 @@ class SmtpClient { // Detect maximum allowed message size if ((match = command.data.match(/SIZE (\d+)/i)) && Number(match[1])) { - const maxAllowedSize = Number(match[1]) - this.logger.debug(DEBUG_TAG, 'Maximum allowd message size: ' + maxAllowedSize) + this.maxAllowedSize = Number(match[1]) + this.logger.debug(DEBUG_TAG, 'Maximum allowed message size: ' + this.maxAllowedSize) } // Detect if the server supports STARTTLS