import _Reflect$construct from "@babel/runtime-corejs3/core-js-stable/reflect/construct"; import _wrapNativeSuper from "@babel/runtime-corejs3/helpers/wrapNativeSuper"; import _typeof from "@babel/runtime-corejs3/helpers/typeof"; import _classCallCheck from "@babel/runtime-corejs3/helpers/classCallCheck"; import _createClass from "@babel/runtime-corejs3/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime-corejs3/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime-corejs3/helpers/getPrototypeOf"; import _inherits from "@babel/runtime-corejs3/helpers/inherits"; import _defineProperty from "@babel/runtime-corejs3/helpers/defineProperty"; import _asyncToGenerator from "@babel/runtime-corejs3/helpers/asyncToGenerator"; import _regeneratorRuntime from "@babel/runtime-corejs3/regenerator"; import _concatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/concat"; import _Date$now from "@babel/runtime-corejs3/core-js-stable/date/now"; import _Object$keys2 from "@babel/runtime-corejs3/core-js-stable/object/keys"; import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes"; import _globalThis from "@babel/runtime-corejs3/core-js/global-this"; import _Array$isArray from "@babel/runtime-corejs3/core-js-stable/array/is-array"; function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } import "core-js/modules/es.error.cause.js"; import "core-js/modules/es.array.join.js"; import "core-js/modules/es.array.push.js"; import "core-js/modules/es.function.name.js"; import "core-js/modules/es.object.keys.js"; import "core-js/modules/es.regexp.exec.js"; import "core-js/modules/es.regexp.test.js"; import "core-js/modules/web.self.js"; /** * */ import { EventEmitter } from 'events'; import xml2js from 'xml2js'; import { getLogger } from './util/logger'; import { StreamPromise } from './util/promise'; import { parseCSV } from './csv'; import { createLazyStream } from './util/stream'; import { getBodySize } from './util/get-body-size'; /** @private */ function parseJSON(str) { return JSON.parse(str); } /** @private */ function parseXML(_x) { return _parseXML.apply(this, arguments); } /** @private */ function _parseXML() { _parseXML = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5(str) { return _regeneratorRuntime.wrap(function _callee5$(_context11) { while (1) switch (_context11.prev = _context11.next) { case 0: return _context11.abrupt("return", xml2js.parseStringPromise(str, { explicitArray: false })); case 1: case "end": return _context11.stop(); } }, _callee5); })); return _parseXML.apply(this, arguments); } function parseText(str) { return str; } /** * HTTP based API class with authorization hook */ export var HttpApi = /*#__PURE__*/function (_EventEmitter) { function HttpApi(conn, options) { var _this; _classCallCheck(this, HttpApi); _this = _callSuper(this, HttpApi); _this._conn = conn; _this._logger = conn._logLevel ? HttpApi._logger.createInstance(conn._logLevel) : HttpApi._logger; _this._responseType = options.responseType; _this._transport = options.transport || conn._transport; _this._noContentResponse = options.noContentResponse; _this._options = options; return _this; } /** * Callout to API endpoint using http */ _inherits(HttpApi, _EventEmitter); return _createClass(HttpApi, [{ key: "request", value: function request(_request) { var _this2 = this; return StreamPromise.create(function () { var _createLazyStream = createLazyStream(), stream = _createLazyStream.stream, setStream = _createLazyStream.setStream; var promise = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() { var _context, _context2; var refreshDelegate, bodyPromise, _body2, requestTime, requestPromise, response, responseTime, err, body; return _regeneratorRuntime.wrap(function _callee$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: refreshDelegate = _this2.getRefreshDelegate(); /* TODO decide remove or not this section */ /* // remember previous instance url in case it changes after a refresh const lastInstanceUrl = conn.instanceUrl; // check to see if the token refresh has changed the instance url if(lastInstanceUrl !== conn.instanceUrl){ // if the instance url has changed // then replace the current request urls instance url fragment // with the updated instance url request.url = request.url.replace(lastInstanceUrl,conn.instanceUrl); } */ if (!(refreshDelegate && refreshDelegate.isRefreshing())) { _context3.next = 10; break; } _context3.next = 4; return refreshDelegate.waitRefresh(); case 4: bodyPromise = _this2.request(_request); setStream(bodyPromise.stream()); _context3.next = 8; return bodyPromise; case 8: _body2 = _context3.sent; return _context3.abrupt("return", _body2); case 10: // hook before sending _this2.beforeSend(_request); _this2.emit('request', _request); _this2._logger.debug(_concatInstanceProperty(_context = " method=".concat(_request.method, ", url=")).call(_context, _request.url)); requestTime = _Date$now(); requestPromise = _this2._transport.httpRequest(_request, _this2._options); setStream(requestPromise.stream()); _context3.prev = 16; _context3.next = 19; return requestPromise; case 19: response = _context3.sent; _context3.next = 26; break; case 22: _context3.prev = 22; _context3.t0 = _context3["catch"](16); _this2._logger.error(_context3.t0); throw _context3.t0; case 26: _context3.prev = 26; responseTime = _Date$now(); _this2._logger.debug("elapsed time: ".concat(responseTime - requestTime, " msec")); return _context3.finish(26); case 30: if (response) { _context3.next = 32; break; } return _context3.abrupt("return"); case 32: _this2._logger.debug(_concatInstanceProperty(_context2 = " status=".concat(String(response.statusCode), ", url=")).call(_context2, _request.url)); _this2.emit('response', response); // Refresh token if session has been expired and requires authentication // when session refresh delegate is available if (!(_this2.isSessionExpired(response) && refreshDelegate)) { _context3.next = 39; break; } _context3.next = 37; return refreshDelegate.refresh(requestTime); case 37: /* remove the `content-length` header after token refresh * * SOAP requests include the access token their the body, * if the first req had an invalid token and jsforce successfully * refreshed it we need to remove the `content-length` header * so that it get's re-calculated again with the new body. * * REST request aren't affected by this because the access token * is sent via HTTP headers * * `_message` is only present in SOAP requests */ if ('_message' in _request && _request.headers && 'content-length' in _request.headers) { delete _request.headers['content-length']; } return _context3.abrupt("return", _this2.request(_request)); case 39: if (!_this2.isErrorResponse(response)) { _context3.next = 44; break; } _context3.next = 42; return _this2.getError(response); case 42: err = _context3.sent; throw err; case 44: _context3.next = 46; return _this2.getResponseBody(response); case 46: body = _context3.sent; return _context3.abrupt("return", body); case 48: case "end": return _context3.stop(); } }, _callee, null, [[16, 22, 26, 30]]); }))(); return { stream: stream, promise: promise }; }); } /** * @protected */ }, { key: "getRefreshDelegate", value: function getRefreshDelegate() { return this._conn._refreshDelegate; } /** * @protected */ }, { key: "beforeSend", value: function beforeSend(request) { var _context5; /* eslint-disable no-param-reassign */ var headers = request.headers || {}; if (this._conn.accessToken) { headers.Authorization = "Bearer ".concat(this._conn.accessToken); } if (this._conn._callOptions) { var callOptions = []; for (var _i = 0, _Object$keys = _Object$keys2(this._conn._callOptions); _i < _Object$keys.length; _i++) { var _context4; var name = _Object$keys[_i]; callOptions.push(_concatInstanceProperty(_context4 = "".concat(name, "=")).call(_context4, this._conn._callOptions[name])); } headers['Sforce-Call-Options'] = callOptions.join(', '); } var bodySize = getBodySize(request.body, headers); var cannotHaveBody = _includesInstanceProperty(_context5 = ['GET', 'HEAD', 'OPTIONS']).call(_context5, request.method); // Don't set content-length in browsers as it's not allowed var isBrowser = 'window' in _globalThis || 'self' in _globalThis; if (!isBrowser && // Don't set content-length in browsers as it's not allowed !cannotHaveBody && !!request.body && !('transfer-encoding' in headers) && !('content-length' in headers) && !!bodySize) { this._logger.debug("missing 'content-length' header, setting it to: ".concat(bodySize)); headers['content-length'] = String(bodySize); } request.headers = headers; } /** * Detect response content mime-type * @protected */ }, { key: "getResponseContentType", value: function getResponseContentType(response) { return this._responseType || response.headers && response.headers['content-type']; } /** * @private */ // eslint-disable-next-line @typescript-eslint/require-await }, { key: "parseResponseBody", value: (function () { var _parseResponseBody = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(response) { var contentType, parseBody, _context6; return _regeneratorRuntime.wrap(function _callee2$(_context7) { while (1) switch (_context7.prev = _context7.next) { case 0: contentType = this.getResponseContentType(response) || ''; parseBody = /^(text|application)\/xml(;|$)/.test(contentType) ? parseXML : /^application\/json(;|$)/.test(contentType) ? parseJSON : /^text\/csv(;|$)/.test(contentType) ? parseCSV : parseText; _context7.prev = 2; return _context7.abrupt("return", parseBody(response.body)); case 6: _context7.prev = 6; _context7.t0 = _context7["catch"](2); // TODO(next major): we could throw a new "invalid response body" error instead. this._logger.debug(_concatInstanceProperty(_context6 = "Failed to parse body of content-type: ".concat(contentType, ". Error: ")).call(_context6, _context7.t0.message)); return _context7.abrupt("return", response.body); case 10: case "end": return _context7.stop(); } }, _callee2, this, [[2, 6]]); })); function parseResponseBody(_x2) { return _parseResponseBody.apply(this, arguments); } return parseResponseBody; }() /** * Get response body * @protected */ ) }, { key: "getResponseBody", value: (function () { var _getResponseBody = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(response) { var body, err; return _regeneratorRuntime.wrap(function _callee3$(_context8) { while (1) switch (_context8.prev = _context8.next) { case 0: if (!(response.statusCode === 204)) { _context8.next = 2; break; } return _context8.abrupt("return", this._noContentResponse); case 2: _context8.next = 4; return this.parseResponseBody(response); case 4: body = _context8.sent; if (!this.hasErrorInResponseBody(body)) { _context8.next = 10; break; } _context8.next = 8; return this.getError(response, body); case 8: err = _context8.sent; throw err; case 10: if (!(response.statusCode === 300)) { _context8.next = 12; break; } throw new HttpApiError('Multiple records found', 'MULTIPLE_CHOICES', body); case 12: return _context8.abrupt("return", body); case 13: case "end": return _context8.stop(); } }, _callee3, this); })); function getResponseBody(_x3) { return _getResponseBody.apply(this, arguments); } return getResponseBody; }() /** * Detect session expiry * @protected */ ) }, { key: "isSessionExpired", value: function isSessionExpired(response) { var _context9; // TODO: // The connected app msg only applies to Agent API requests, we should move this to a separate SFAP/Agent API class later. return response.statusCode === 401 && !_includesInstanceProperty(_context9 = response.body).call(_context9, 'Connected app is not attached to Agent'); } /** * Detect error response * @protected */ }, { key: "isErrorResponse", value: function isErrorResponse(response) { return response.statusCode >= 400; } /** * Detect error in response body * @protected */ }, { key: "hasErrorInResponseBody", value: function hasErrorInResponseBody(_body) { return false; } /** * Parsing error message in response * @protected */ }, { key: "parseError", value: function parseError(body) { var errors = body; // XML response if (errors.Errors) { return errors.Errors.Error; } return errors; } /** * Get error message in response * @protected */ }, { key: "getError", value: (function () { var _getError = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(response, body) { var error; return _regeneratorRuntime.wrap(function _callee4$(_context10) { while (1) switch (_context10.prev = _context10.next) { case 0: _context10.prev = 0; _context10.t0 = this; _context10.t1 = body; if (_context10.t1) { _context10.next = 7; break; } _context10.next = 6; return this.parseResponseBody(response); case 6: _context10.t1 = _context10.sent; case 7: _context10.t2 = _context10.t1; error = _context10.t0.parseError.call(_context10.t0, _context10.t2); _context10.next = 13; break; case 11: _context10.prev = 11; _context10.t3 = _context10["catch"](0); case 13: if (!_Array$isArray(error)) { _context10.next = 19; break; } if (!(error.length === 1)) { _context10.next = 18; break; } error = error[0]; _context10.next = 19; break; case 18: return _context10.abrupt("return", new HttpApiError("Multiple errors returned.\n Check `error.data` for the error details", 'MULTIPLE_API_ERRORS', error)); case 19: error = _typeof(error) === 'object' && error !== null && typeof error.message === 'string' ? error : { errorCode: "ERROR_HTTP_".concat(response.statusCode), message: response.body }; if (!(response.headers['content-type'] === 'text/html')) { _context10.next = 23; break; } this._logger.debug("html response.body: ".concat(response.body)); return _context10.abrupt("return", new HttpApiError("HTTP response contains html content.\nCheck that the org exists and can be reached.\nSee `error.data` for the full html response.", error.errorCode, error.message)); case 23: return _context10.abrupt("return", error instanceof HttpApiError ? error : new HttpApiError(error.message, error.errorCode, error)); case 24: case "end": return _context10.stop(); } }, _callee4, this, [[0, 11]]); })); function getError(_x4, _x5) { return _getError.apply(this, arguments); } return getError; }()) }]); }(EventEmitter); /** * */ _defineProperty(HttpApi, "_logger", getLogger('http-api')); var HttpApiError = /*#__PURE__*/function (_Error) { /** * This contains error-specific details, usually returned from the API. */ function HttpApiError(message, errorCode, data) { var _this3; _classCallCheck(this, HttpApiError); _this3 = _callSuper(this, HttpApiError, [message]); _this3.name = errorCode || _this3.name; _this3.errorCode = _this3.name; _this3.data = data; return _this3; } /** * This will be removed in the next major (v4) * * @deprecated use `error.data` instead */ _inherits(HttpApiError, _Error); return _createClass(HttpApiError, [{ key: "content", get: function get() { return this.data; } }]); }(/*#__PURE__*/_wrapNativeSuper(Error)); export default HttpApi; export var isBrowser = 'window' in _globalThis || 'self' in _globalThis; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJFdmVudEVtaXR0ZXIiLCJ4bWwyanMiLCJnZXRMb2dnZXIiLCJTdHJlYW1Qcm9taXNlIiwicGFyc2VDU1YiLCJjcmVhdGVMYXp5U3RyZWFtIiwiZ2V0Qm9keVNpemUiLCJwYXJzZUpTT04iLCJzdHIiLCJKU09OIiwicGFyc2UiLCJwYXJzZVhNTCIsIl94IiwiX3BhcnNlWE1MIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJfYXN5bmNUb0dlbmVyYXRvciIsIl9yZWdlbmVyYXRvclJ1bnRpbWUiLCJtYXJrIiwiX2NhbGxlZTUiLCJ3cmFwIiwiX2NhbGxlZTUkIiwiX2NvbnRleHQxMSIsInByZXYiLCJuZXh0IiwiYWJydXB0IiwicGFyc2VTdHJpbmdQcm9taXNlIiwiZXhwbGljaXRBcnJheSIsInN0b3AiLCJwYXJzZVRleHQiLCJIdHRwQXBpIiwiX0V2ZW50RW1pdHRlciIsImNvbm4iLCJvcHRpb25zIiwiX3RoaXMiLCJfY2xhc3NDYWxsQ2hlY2siLCJfY2FsbFN1cGVyIiwiX2Nvbm4iLCJfbG9nZ2VyIiwiX2xvZ0xldmVsIiwiY3JlYXRlSW5zdGFuY2UiLCJfcmVzcG9uc2VUeXBlIiwicmVzcG9uc2VUeXBlIiwiX3RyYW5zcG9ydCIsInRyYW5zcG9ydCIsIl9ub0NvbnRlbnRSZXNwb25zZSIsIm5vQ29udGVudFJlc3BvbnNlIiwiX29wdGlvbnMiLCJfaW5oZXJpdHMiLCJfY3JlYXRlQ2xhc3MiLCJrZXkiLCJ2YWx1ZSIsInJlcXVlc3QiLCJfdGhpczIiLCJjcmVhdGUiLCJfY3JlYXRlTGF6eVN0cmVhbSIsInN0cmVhbSIsInNldFN0cmVhbSIsInByb21pc2UiLCJfY2FsbGVlIiwiX2NvbnRleHQiLCJfY29udGV4dDIiLCJyZWZyZXNoRGVsZWdhdGUiLCJib2R5UHJvbWlzZSIsIl9ib2R5MiIsInJlcXVlc3RUaW1lIiwicmVxdWVzdFByb21pc2UiLCJyZXNwb25zZSIsInJlc3BvbnNlVGltZSIsImVyciIsImJvZHkiLCJfY2FsbGVlJCIsIl9jb250ZXh0MyIsImdldFJlZnJlc2hEZWxlZ2F0ZSIsImlzUmVmcmVzaGluZyIsIndhaXRSZWZyZXNoIiwic2VudCIsImJlZm9yZVNlbmQiLCJlbWl0IiwiZGVidWciLCJfY29uY2F0SW5zdGFuY2VQcm9wZXJ0eSIsImNvbmNhdCIsIm1ldGhvZCIsImNhbGwiLCJ1cmwiLCJfRGF0ZSRub3ciLCJodHRwUmVxdWVzdCIsInQwIiwiZXJyb3IiLCJmaW5pc2giLCJTdHJpbmciLCJzdGF0dXNDb2RlIiwiaXNTZXNzaW9uRXhwaXJlZCIsInJlZnJlc2giLCJoZWFkZXJzIiwiaXNFcnJvclJlc3BvbnNlIiwiZ2V0RXJyb3IiLCJnZXRSZXNwb25zZUJvZHkiLCJfcmVmcmVzaERlbGVnYXRlIiwiX2NvbnRleHQ1IiwiYWNjZXNzVG9rZW4iLCJBdXRob3JpemF0aW9uIiwiX2NhbGxPcHRpb25zIiwiY2FsbE9wdGlvbnMiLCJfaSIsIl9PYmplY3Qka2V5cyIsIl9PYmplY3Qka2V5czIiLCJsZW5ndGgiLCJfY29udGV4dDQiLCJuYW1lIiwicHVzaCIsImpvaW4iLCJib2R5U2l6ZSIsImNhbm5vdEhhdmVCb2R5IiwiX2luY2x1ZGVzSW5zdGFuY2VQcm9wZXJ0eSIsImlzQnJvd3NlciIsIl9nbG9iYWxUaGlzIiwiZ2V0UmVzcG9uc2VDb250ZW50VHlwZSIsIl9wYXJzZVJlc3BvbnNlQm9keSIsIl9jYWxsZWUyIiwiY29udGVudFR5cGUiLCJwYXJzZUJvZHkiLCJfY29udGV4dDYiLCJfY2FsbGVlMiQiLCJfY29udGV4dDciLCJ0ZXN0IiwibWVzc2FnZSIsInBhcnNlUmVzcG9uc2VCb2R5IiwiX3gyIiwiX2dldFJlc3BvbnNlQm9keSIsIl9jYWxsZWUzIiwiX2NhbGxlZTMkIiwiX2NvbnRleHQ4IiwiaGFzRXJyb3JJblJlc3BvbnNlQm9keSIsIkh0dHBBcGlFcnJvciIsIl94MyIsIl9jb250ZXh0OSIsIl9ib2R5IiwicGFyc2VFcnJvciIsImVycm9ycyIsIkVycm9ycyIsIkVycm9yIiwiX2dldEVycm9yIiwiX2NhbGxlZTQiLCJfY2FsbGVlNCQiLCJfY29udGV4dDEwIiwidDEiLCJ0MiIsInQzIiwiX0FycmF5JGlzQXJyYXkiLCJfdHlwZW9mIiwiZXJyb3JDb2RlIiwiX3g0IiwiX3g1IiwiX2RlZmluZVByb3BlcnR5IiwiX0Vycm9yIiwiZGF0YSIsIl90aGlzMyIsImdldCIsIl93cmFwTmF0aXZlU3VwZXIiXSwic291cmNlcyI6WyIuLi9zcmMvaHR0cC1hcGkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKlxuICovXG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdldmVudHMnO1xuaW1wb3J0IHhtbDJqcyBmcm9tICd4bWwyanMnO1xuaW1wb3J0IHsgTG9nZ2VyLCBnZXRMb2dnZXIgfSBmcm9tICcuL3V0aWwvbG9nZ2VyJztcbmltcG9ydCB7IFN0cmVhbVByb21pc2UgfSBmcm9tICcuL3V0aWwvcHJvbWlzZSc7XG5pbXBvcnQgQ29ubmVjdGlvbiBmcm9tICcuL2Nvbm5lY3Rpb24nO1xuaW1wb3J0IFRyYW5zcG9ydCBmcm9tICcuL3RyYW5zcG9ydCc7XG5pbXBvcnQgeyBwYXJzZUNTViB9IGZyb20gJy4vY3N2JztcbmltcG9ydCB7XG4gIEh0dHBSZXF1ZXN0LFxuICBIdHRwUmVxdWVzdE9wdGlvbnMsXG4gIEh0dHBSZXNwb25zZSxcbiAgT3B0aW9uYWwsXG4gIFNjaGVtYSxcbn0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBjcmVhdGVMYXp5U3RyZWFtIH0gZnJvbSAnLi91dGlsL3N0cmVhbSc7XG5pbXBvcnQgeyBnZXRCb2R5U2l6ZSB9IGZyb20gJy4vdXRpbC9nZXQtYm9keS1zaXplJztcblxuLyoqIEBwcml2YXRlICovXG5mdW5jdGlvbiBwYXJzZUpTT04oc3RyOiBzdHJpbmcpIHtcbiAgcmV0dXJuIEpTT04ucGFyc2Uoc3RyKTtcbn1cblxuLyoqIEBwcml2YXRlICovXG5hc3luYyBmdW5jdGlvbiBwYXJzZVhNTChzdHI6IHN0cmluZykge1xuICByZXR1cm4geG1sMmpzLnBhcnNlU3RyaW5nUHJvbWlzZShzdHIsIHsgZXhwbGljaXRBcnJheTogZmFsc2UgfSk7XG59XG5cbi8qKiBAcHJpdmF0ZSAqL1xuZnVuY3Rpb24gcGFyc2VUZXh0KHN0cjogc3RyaW5nKSB7XG4gIHJldHVybiBzdHI7XG59XG5cbi8qKlxuICogSFRUUCBiYXNlZCBBUEkgY2xhc3Mgd2l0aCBhdXRob3JpemF0aW9uIGhvb2tcbiAqL1xuZXhwb3J0IGNsYXNzIEh0dHBBcGk8UyBleHRlbmRzIFNjaGVtYT4gZXh0ZW5kcyBFdmVudEVtaXR0ZXIge1xuICBzdGF0aWMgX2xvZ2dlciA9IGdldExvZ2dlcignaHR0cC1hcGknKTtcblxuICBfY29ubjogQ29ubmVjdGlvbjxTPjtcbiAgX2xvZ2dlcjogTG9nZ2VyO1xuICBfdHJhbnNwb3J0OiBUcmFuc3BvcnQ7XG4gIF9yZXNwb25zZVR5cGU6IHN0cmluZyB8IHZvaWQ7XG4gIF9ub0NvbnRlbnRSZXNwb25zZTogc3RyaW5nIHwgdm9pZDtcbiAgX29wdGlvbnM6IEh0dHBSZXF1ZXN0T3B0aW9ucztcblxuICBjb25zdHJ1Y3Rvcihjb25uOiBDb25uZWN0aW9uPFM+LCBvcHRpb25zOiBhbnkpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2Nvbm4gPSBjb25uO1xuICAgIHRoaXMuX2xvZ2dlciA9IGNvbm4uX2xvZ0xldmVsXG4gICAgICA/IEh0dHBBcGkuX2xvZ2dlci5jcmVhdGVJbnN0YW5jZShjb25uLl9sb2dMZXZlbClcbiAgICAgIDogSHR0cEFwaS5fbG9nZ2VyO1xuICAgIHRoaXMuX3Jlc3BvbnNlVHlwZSA9IG9wdGlvbnMucmVzcG9uc2VUeXBlO1xuICAgIHRoaXMuX3RyYW5zcG9ydCA9IG9wdGlvbnMudHJhbnNwb3J0IHx8IGNvbm4uX3RyYW5zcG9ydDtcbiAgICB0aGlzLl9ub0NvbnRlbnRSZXNwb25zZSA9IG9wdGlvbnMubm9Db250ZW50UmVzcG9uc2U7XG4gICAgdGhpcy5fb3B0aW9ucyA9IG9wdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogQ2FsbG91dCB0byBBUEkgZW5kcG9pbnQgdXNpbmcgaHR0cFxuICAgKi9cbiAgcmVxdWVzdDxSID0gdW5rbm93bj4ocmVxdWVzdDogSHR0cFJlcXVlc3QpOiBTdHJlYW1Qcm9taXNlPFI+IHtcbiAgICByZXR1cm4gU3RyZWFtUHJvbWlzZS5jcmVhdGU8Uj4oKCkgPT4ge1xuICAgICAgY29uc3QgeyBzdHJlYW0sIHNldFN0cmVhbSB9ID0gY3JlYXRlTGF6eVN0cmVhbSgpO1xuICAgICAgY29uc3QgcHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlZnJlc2hEZWxlZ2F0ZSA9IHRoaXMuZ2V0UmVmcmVzaERlbGVnYXRlKCk7XG4gICAgICAgIC8qIFRPRE8gZGVjaWRlIHJlbW92ZSBvciBub3QgdGhpcyBzZWN0aW9uICovXG4gICAgICAgIC8qXG4gICAgICAgIC8vIHJlbWVtYmVyIHByZXZpb3VzIGluc3RhbmNlIHVybCBpbiBjYXNlIGl0IGNoYW5nZXMgYWZ0ZXIgYSByZWZyZXNoXG4gICAgICAgIGNvbnN0IGxhc3RJbnN0YW5jZVVybCA9IGNvbm4uaW5zdGFuY2VVcmw7XG5cbiAgICAgICAgLy8gY2hlY2sgdG8gc2VlIGlmIHRoZSB0b2tlbiByZWZyZXNoIGhhcyBjaGFuZ2VkIHRoZSBpbnN0YW5jZSB1cmxcbiAgICAgICAgaWYobGFzdEluc3RhbmNlVXJsICE9PSBjb25uLmluc3RhbmNlVXJsKXtcbiAgICAgICAgICAvLyBpZiB0aGUgaW5zdGFuY2UgdXJsIGhhcyBjaGFuZ2VkXG4gICAgICAgICAgLy8gdGhlbiByZXBsYWNlIHRoZSBjdXJyZW50IHJlcXVlc3QgdXJscyBpbnN0YW5jZSB1cmwgZnJhZ21lbnRcbiAgICAgICAgICAvLyB3aXRoIHRoZSB1cGRhdGVkIGluc3RhbmNlIHVybFxuICAgICAgICAgIHJlcXVlc3QudXJsID0gcmVxdWVzdC51cmwucmVwbGFjZShsYXN0SW5zdGFuY2VVcmwsY29ubi5pbnN0YW5jZVVybCk7XG4gICAgICAgIH1cbiAgICAgICAgKi9cbiAgICAgICAgaWYgKHJlZnJlc2hEZWxlZ2F0ZSAmJiByZWZyZXNoRGVsZWdhdGUuaXNSZWZyZXNoaW5nKCkpIHtcbiAgICAgICAgICBhd2FpdCByZWZyZXNoRGVsZWdhdGUud2FpdFJlZnJlc2goKTtcbiAgICAgICAgICBjb25zdCBib2R5UHJvbWlzZSA9IHRoaXMucmVxdWVzdChyZXF1ZXN0KTtcbiAgICAgICAgICBzZXRTdHJlYW0oYm9keVByb21pc2Uuc3RyZWFtKCkpO1xuICAgICAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCBib2R5UHJvbWlzZTtcbiAgICAgICAgICByZXR1cm4gYm9keTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGhvb2sgYmVmb3JlIHNlbmRpbmdcbiAgICAgICAgdGhpcy5iZWZvcmVTZW5kKHJlcXVlc3QpO1xuXG4gICAgICAgIHRoaXMuZW1pdCgncmVxdWVzdCcsIHJlcXVlc3QpO1xuICAgICAgICB0aGlzLl9sb2dnZXIuZGVidWcoXG4gICAgICAgICAgYDxyZXF1ZXN0PiBtZXRob2Q9JHtyZXF1ZXN0Lm1ldGhvZH0sIHVybD0ke3JlcXVlc3QudXJsfWAsXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHJlcXVlc3RUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgY29uc3QgcmVxdWVzdFByb21pc2UgPSB0aGlzLl90cmFuc3BvcnQuaHR0cFJlcXVlc3QoXG4gICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICB0aGlzLl9vcHRpb25zLFxuICAgICAgICApO1xuXG4gICAgICAgIHNldFN0cmVhbShyZXF1ZXN0UHJvbWlzZS5zdHJlYW0oKSk7XG5cbiAgICAgICAgbGV0IHJlc3BvbnNlOiBIdHRwUmVzcG9uc2UgfCB2b2lkO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFByb21pc2U7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBjb25zdCByZXNwb25zZVRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgIGBlbGFwc2VkIHRpbWU6ICR7cmVzcG9uc2VUaW1lIC0gcmVxdWVzdFRpbWV9IG1zZWNgLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9sb2dnZXIuZGVidWcoXG4gICAgICAgICAgYDxyZXNwb25zZT4gc3RhdHVzPSR7U3RyaW5nKHJlc3BvbnNlLnN0YXR1c0NvZGUpfSwgdXJsPSR7XG4gICAgICAgICAgICByZXF1ZXN0LnVybFxuICAgICAgICAgIH1gLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmVtaXQoJ3Jlc3BvbnNlJywgcmVzcG9uc2UpO1xuICAgICAgICAvLyBSZWZyZXNoIHRva2VuIGlmIHNlc3Npb24gaGFzIGJlZW4gZXhwaXJlZCBhbmQgcmVxdWlyZXMgYXV0aGVudGljYXRpb25cbiAgICAgICAgLy8gd2hlbiBzZXNzaW9uIHJlZnJlc2ggZGVsZWdhdGUgaXMgYXZhaWxhYmxlXG4gICAgICAgIGlmICh0aGlzLmlzU2Vzc2lvbkV4cGlyZWQocmVzcG9uc2UpICYmIHJlZnJlc2hEZWxlZ2F0ZSkge1xuICAgICAgICAgIGF3YWl0IHJlZnJlc2hEZWxlZ2F0ZS5yZWZyZXNoKHJlcXVlc3RUaW1lKTtcbiAgICAgICAgICAvKiByZW1vdmUgdGhlIGBjb250ZW50LWxlbmd0aGAgaGVhZGVyIGFmdGVyIHRva2VuIHJlZnJlc2hcbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIFNPQVAgcmVxdWVzdHMgaW5jbHVkZSB0aGUgYWNjZXNzIHRva2VuIHRoZWlyIHRoZSBib2R5LFxuICAgICAgICAgICAqIGlmIHRoZSBmaXJzdCByZXEgaGFkIGFuIGludmFsaWQgdG9rZW4gYW5kIGpzZm9yY2Ugc3VjY2Vzc2Z1bGx5XG4gICAgICAgICAgICogcmVmcmVzaGVkIGl0IHdlIG5lZWQgdG8gcmVtb3ZlIHRoZSBgY29udGVudC1sZW5ndGhgIGhlYWRlclxuICAgICAgICAgICAqIHNvIHRoYXQgaXQgZ2V0J3MgcmUtY2FsY3VsYXRlZCBhZ2FpbiB3aXRoIHRoZSBuZXcgYm9keS5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIFJFU1QgcmVxdWVzdCBhcmVuJ3QgYWZmZWN0ZWQgYnkgdGhpcyBiZWNhdXNlIHRoZSBhY2Nlc3MgdG9rZW5cbiAgICAgICAgICAgKiBpcyBzZW50IHZpYSBIVFRQIGhlYWRlcnNcbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIGBfbWVzc2FnZWAgaXMgb25seSBwcmVzZW50IGluIFNPQVAgcmVxdWVzdHNcbiAgICAgICAgICAgKi9cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAnX21lc3NhZ2UnIGluIHJlcXVlc3QgJiZcbiAgICAgICAgICAgIHJlcXVlc3QuaGVhZGVycyAmJlxuICAgICAgICAgICAgJ2NvbnRlbnQtbGVuZ3RoJyBpbiByZXF1ZXN0LmhlYWRlcnNcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGRlbGV0ZSByZXF1ZXN0LmhlYWRlcnNbJ2NvbnRlbnQtbGVuZ3RoJ107XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QocmVxdWVzdCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaXNFcnJvclJlc3BvbnNlKHJlc3BvbnNlKSkge1xuICAgICAgICAgIGNvbnN0IGVyciA9IGF3YWl0IHRoaXMuZ2V0RXJyb3IocmVzcG9uc2UpO1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBib2R5ID0gYXdhaXQgdGhpcy5nZXRSZXNwb25zZUJvZHkocmVzcG9uc2UpO1xuICAgICAgICByZXR1cm4gYm9keTtcbiAgICAgIH0pKCk7XG4gICAgICByZXR1cm4geyBzdHJlYW0sIHByb21pc2UgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBnZXRSZWZyZXNoRGVsZWdhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Nvbm4uX3JlZnJlc2hEZWxlZ2F0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBiZWZvcmVTZW5kKHJlcXVlc3Q6IEh0dHBSZXF1ZXN0KSB7XG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tcGFyYW0tcmVhc3NpZ24gKi9cbiAgICBjb25zdCBoZWFkZXJzID0gcmVxdWVzdC5oZWFkZXJzIHx8IHt9O1xuICAgIGlmICh0aGlzLl9jb25uLmFjY2Vzc1Rva2VuKSB7XG4gICAgICBoZWFkZXJzLkF1dGhvcml6YXRpb24gPSBgQmVhcmVyICR7dGhpcy5fY29ubi5hY2Nlc3NUb2tlbn1gO1xuICAgIH1cbiAgICBpZiAodGhpcy5fY29ubi5fY2FsbE9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IGNhbGxPcHRpb25zID0gW107XG4gICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgT2JqZWN0LmtleXModGhpcy5fY29ubi5fY2FsbE9wdGlvbnMpKSB7XG4gICAgICAgIGNhbGxPcHRpb25zLnB1c2goYCR7bmFtZX09JHt0aGlzLl9jb25uLl9jYWxsT3B0aW9uc1tuYW1lXX1gKTtcbiAgICAgIH1cbiAgICAgIGhlYWRlcnNbJ1Nmb3JjZS1DYWxsLU9wdGlvbnMnXSA9IGNhbGxPcHRpb25zLmpvaW4oJywgJyk7XG4gICAgfVxuXG4gICAgY29uc3QgYm9keVNpemUgPSBnZXRCb2R5U2l6ZShyZXF1ZXN0LmJvZHksIGhlYWRlcnMpO1xuXG4gICAgY29uc3QgY2Fubm90SGF2ZUJvZHkgPSBbJ0dFVCcsICdIRUFEJywgJ09QVElPTlMnXS5pbmNsdWRlcyhyZXF1ZXN0Lm1ldGhvZCk7XG5cbiAgICAvLyBEb24ndCBzZXQgY29udGVudC1sZW5ndGggaW4gYnJvd3NlcnMgYXMgaXQncyBub3QgYWxsb3dlZFxuICAgIGNvbnN0IGlzQnJvd3NlciA9ICd3aW5kb3cnIGluIGdsb2JhbFRoaXMgfHwgJ3NlbGYnIGluIGdsb2JhbFRoaXM7XG5cbiAgICBpZiAoXG4gICAgICAhaXNCcm93c2VyICYmIC8vIERvbid0IHNldCBjb250ZW50LWxlbmd0aCBpbiBicm93c2VycyBhcyBpdCdzIG5vdCBhbGxvd2VkXG4gICAgICAhY2Fubm90SGF2ZUJvZHkgJiZcbiAgICAgICEhcmVxdWVzdC5ib2R5ICYmXG4gICAgICAhKCd0cmFuc2Zlci1lbmNvZGluZycgaW4gaGVhZGVycykgJiZcbiAgICAgICEoJ2NvbnRlbnQtbGVuZ3RoJyBpbiBoZWFkZXJzKSAmJlxuICAgICAgISFib2R5U2l6ZVxuICAgICkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgbWlzc2luZyAnY29udGVudC1sZW5ndGgnIGhlYWRlciwgc2V0dGluZyBpdCB0bzogJHtib2R5U2l6ZX1gLFxuICAgICAgKTtcbiAgICAgIGhlYWRlcnNbJ2NvbnRlbnQtbGVuZ3RoJ10gPSBTdHJpbmcoYm9keVNpemUpO1xuICAgIH1cbiAgICByZXF1ZXN0LmhlYWRlcnMgPSBoZWFkZXJzO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVjdCByZXNwb25zZSBjb250ZW50IG1pbWUtdHlwZVxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBnZXRSZXNwb25zZUNvbnRlbnRUeXBlKHJlc3BvbnNlOiBIdHRwUmVzcG9uc2UpOiBPcHRpb25hbDxzdHJpbmc+IHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5fcmVzcG9uc2VUeXBlIHx8XG4gICAgICAocmVzcG9uc2UuaGVhZGVycyAmJiByZXNwb25zZS5oZWFkZXJzWydjb250ZW50LXR5cGUnXSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3JlcXVpcmUtYXdhaXRcbiAgYXN5bmMgcGFyc2VSZXNwb25zZUJvZHkocmVzcG9uc2U6IEh0dHBSZXNwb25zZSkge1xuICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gdGhpcy5nZXRSZXNwb25zZUNvbnRlbnRUeXBlKHJlc3BvbnNlKSB8fCAnJztcbiAgICBjb25zdCBwYXJzZUJvZHkgPSAvXih0ZXh0fGFwcGxpY2F0aW9uKVxcL3htbCg7fCQpLy50ZXN0KGNvbnRlbnRUeXBlKVxuICAgICAgPyBwYXJzZVhNTFxuICAgICAgOiAvXmFwcGxpY2F0aW9uXFwvanNvbig7fCQpLy50ZXN0KGNvbnRlbnRUeXBlKVxuICAgICAgPyBwYXJzZUpTT05cbiAgICAgIDogL150ZXh0XFwvY3N2KDt8JCkvLnRlc3QoY29udGVudFR5cGUpXG4gICAgICA/IHBhcnNlQ1NWXG4gICAgICA6IHBhcnNlVGV4dDtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHBhcnNlQm9keShyZXNwb25zZS5ib2R5KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBUT0RPKG5leHQgbWFqb3IpOiB3ZSBjb3VsZCB0aHJvdyBhIG5ldyBcImludmFsaWQgcmVzcG9uc2UgYm9keVwiIGVycm9yIGluc3RlYWQuXG4gICAgICB0aGlzLl9sb2dnZXIuZGVidWcoXG4gICAgICAgIGBGYWlsZWQgdG8gcGFyc2UgYm9keSBvZiBjb250ZW50LXR5cGU6ICR7Y29udGVudFR5cGV9LiBFcnJvcjogJHtcbiAgICAgICAgICAoZSBhcyBFcnJvcikubWVzc2FnZVxuICAgICAgICB9YCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gcmVzcG9uc2UuYm9keTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IHJlc3BvbnNlIGJvZHlcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgYXN5bmMgZ2V0UmVzcG9uc2VCb2R5KHJlc3BvbnNlOiBIdHRwUmVzcG9uc2UpIHtcbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSA9PT0gMjA0KSB7XG4gICAgICAvLyBObyBDb250ZW50XG4gICAgICByZXR1cm4gdGhpcy5fbm9Db250ZW50UmVzcG9uc2U7XG4gICAgfVxuICAgIGNvbnN0IGJvZHkgPSBhd2FpdCB0aGlzLnBhcnNlUmVzcG9uc2VCb2R5KHJlc3BvbnNlKTtcbiAgICBsZXQgZXJyO1xuICAgIGlmICh0aGlzLmhhc0Vycm9ySW5SZXNwb25zZUJvZHkoYm9keSkpIHtcbiAgICAgIGVyciA9IGF3YWl0IHRoaXMuZ2V0RXJyb3IocmVzcG9uc2UsIGJvZHkpO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSA9PT0gMzAwKSB7XG4gICAgICAvLyBNdWx0aXBsZSBDaG9pY2VzXG4gICAgICB0aHJvdyBuZXcgSHR0cEFwaUVycm9yKFxuICAgICAgICAnTXVsdGlwbGUgcmVjb3JkcyBmb3VuZCcsXG4gICAgICAgICdNVUxUSVBMRV9DSE9JQ0VTJyxcbiAgICAgICAgYm9keSxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBib2R5O1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVjdCBzZXNzaW9uIGV4cGlyeVxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBpc1Nlc3Npb25FeHBpcmVkKHJlc3BvbnNlOiBIdHRwUmVzcG9uc2UpIHtcbiAgICAvLyBUT0RPOlxuICAgIC8vIFRoZSBjb25uZWN0ZWQgYXBwIG1zZyBvbmx5IGFwcGxpZXMgdG8gQWdlbnQgQVBJIHJlcXVlc3RzLCB3ZSBzaG91bGQgbW92ZSB0aGlzIHRvIGEgc2VwYXJhdGUgU0ZBUC9BZ2VudCBBUEkgY2xhc3MgbGF0ZXIuXG4gICAgcmV0dXJuIChcbiAgICAgIHJlc3BvbnNlLnN0YXR1c0NvZGUgPT09IDQwMSAmJlxuICAgICAgIXJlc3BvbnNlLmJvZHkuaW5jbHVkZXMoJ0Nvbm5lY3RlZCBhcHAgaXMgbm90IGF0dGFjaGVkIHRvIEFnZW50JylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVjdCBlcnJvciByZXNwb25zZVxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBpc0Vycm9yUmVzcG9uc2UocmVzcG9uc2U6IEh0dHBSZXNwb25zZSkge1xuICAgIHJldHVybiByZXNwb25zZS5zdGF0dXNDb2RlID49IDQwMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlY3QgZXJyb3IgaW4gcmVzcG9uc2UgYm9keVxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBoYXNFcnJvckluUmVzcG9uc2VCb2R5KF9ib2R5OiBPcHRpb25hbDxzdHJpbmc+KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZXJyb3IgbWVzc2FnZSBpbiByZXNwb25zZVxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBwYXJzZUVycm9yKGJvZHk6IGFueSkge1xuICAgIGNvbnN0IGVycm9ycyA9IGJvZHk7XG5cbiAgICAvLyBYTUwgcmVzcG9uc2VcbiAgICBpZiAoZXJyb3JzLkVycm9ycykge1xuICAgICAgcmV0dXJuIGVycm9ycy5FcnJvcnMuRXJyb3I7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9ycztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZXJyb3IgbWVzc2FnZSBpbiByZXNwb25zZVxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBhc3luYyBnZXRFcnJvcihyZXNwb25zZTogSHR0cFJlc3BvbnNlLCBib2R5PzogYW55KTogUHJvbWlzZTxFcnJvcj4ge1xuICAgIGxldCBlcnJvcjtcbiAgICB0cnkge1xuICAgICAgZXJyb3IgPSB0aGlzLnBhcnNlRXJyb3IoYm9keSB8fCAoYXdhaXQgdGhpcy5wYXJzZVJlc3BvbnNlQm9keShyZXNwb25zZSkpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZSBuby1lbXB0eVxuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KGVycm9yKSkge1xuICAgICAgaWYgKGVycm9yLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBlcnJvciA9IGVycm9yWzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBIdHRwQXBpRXJyb3IoXG4gICAgICAgICAgYE11bHRpcGxlIGVycm9ycyByZXR1cm5lZC5cbiAgQ2hlY2sgXFxgZXJyb3IuZGF0YVxcYCBmb3IgdGhlIGVycm9yIGRldGFpbHNgLFxuICAgICAgICAgICdNVUxUSVBMRV9BUElfRVJST1JTJyxcbiAgICAgICAgICBlcnJvcixcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBlcnJvciA9XG4gICAgICB0eXBlb2YgZXJyb3IgPT09ICdvYmplY3QnICYmXG4gICAgICBlcnJvciAhPT0gbnVsbCAmJlxuICAgICAgdHlwZW9mIGVycm9yLm1lc3NhZ2UgPT09ICdzdHJpbmcnXG4gICAgICAgID8gZXJyb3JcbiAgICAgICAgOiB7XG4gICAgICAgICAgICBlcnJvckNvZGU6IGBFUlJPUl9IVFRQXyR7cmVzcG9uc2Uuc3RhdHVzQ29kZX1gLFxuICAgICAgICAgICAgbWVzc2FnZTogcmVzcG9uc2UuYm9keSxcbiAgICAgICAgICB9O1xuXG4gICAgaWYgKHJlc3BvbnNlLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddID09PSAndGV4dC9odG1sJykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmRlYnVnKGBodG1sIHJlc3BvbnNlLmJvZHk6ICR7cmVzcG9uc2UuYm9keX1gKTtcbiAgICAgIHJldHVybiBuZXcgSHR0cEFwaUVycm9yKFxuICAgICAgICBgSFRUUCByZXNwb25zZSBjb250YWlucyBodG1sIGNvbnRlbnQuXG5DaGVjayB0aGF0IHRoZSBvcmcgZXhpc3RzIGFuZCBjYW4gYmUgcmVhY2hlZC5cblNlZSBcXGBlcnJvci5kYXRhXFxgIGZvciB0aGUgZnVsbCBodG1sIHJlc3BvbnNlLmAsXG4gICAgICAgIGVycm9yLmVycm9yQ29kZSxcbiAgICAgICAgZXJyb3IubWVzc2FnZSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9yIGluc3RhbmNlb2YgSHR0cEFwaUVycm9yXG4gICAgICA/IGVycm9yXG4gICAgICA6IG5ldyBIdHRwQXBpRXJyb3IoZXJyb3IubWVzc2FnZSwgZXJyb3IuZXJyb3JDb2RlLCBlcnJvcik7XG4gIH1cbn1cblxuLyoqXG4gKlxuICovXG5jbGFzcyBIdHRwQXBpRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIC8qKlxuICAgKiBUaGlzIGNvbnRhaW5zIGVycm9yLXNwZWNpZmljIGRldGFpbHMsIHVzdWFsbHkgcmV0dXJuZWQgZnJvbSB0aGUgQVBJLlxuICAgKi9cbiAgZGF0YTogYW55O1xuICBlcnJvckNvZGU6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcsIGVycm9yQ29kZT86IHN0cmluZyB8IHVuZGVmaW5lZCwgZGF0YT86IGFueSkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IGVycm9yQ29kZSB8fCB0aGlzLm5hbWU7XG4gICAgdGhpcy5lcnJvckNvZGUgPSB0aGlzLm5hbWU7XG4gICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgbmV4dCBtYWpvciAodjQpXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIHVzZSBgZXJyb3IuZGF0YWAgaW5zdGVhZFxuICAgKi9cbiAgZ2V0IGNvbnRlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBIdHRwQXBpO1xuZXhwb3J0IGNvbnN0IGlzQnJvd3NlciA9ICd3aW5kb3cnIGluIGdsb2JhbFRoaXMgfHwgJ3NlbGYnIGluIGdsb2JhbFRoaXM7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBLFNBQVNBLFlBQVksUUFBUSxRQUFRO0FBQ3JDLE9BQU9DLE1BQU0sTUFBTSxRQUFRO0FBQzNCLFNBQWlCQyxTQUFTLFFBQVEsZUFBZTtBQUNqRCxTQUFTQyxhQUFhLFFBQVEsZ0JBQWdCO0FBRzlDLFNBQVNDLFFBQVEsUUFBUSxPQUFPO0FBUWhDLFNBQVNDLGdCQUFnQixRQUFRLGVBQWU7QUFDaEQs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