UNPKG

@crawly/superagent

Version:

elegant & feature rich browser / node HTTP with a fluent API

769 lines (645 loc) 61 kB
"use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } /** * Module of mixed-in functions shared between node and client code */ var isObject = require('./is-object'); /** * Expose `RequestBase`. */ module.exports = RequestBase; /** * Initialize a new `RequestBase`. * * @api public */ function RequestBase(obj) { if (obj) return mixin(obj); } /** * Mixin the prototype properties. * * @param {Object} obj * @return {Object} * @api private */ function mixin(obj) { for (var key in RequestBase.prototype) { if (Object.prototype.hasOwnProperty.call(RequestBase.prototype, key)) obj[key] = RequestBase.prototype[key]; } return obj; } /** * Clear previous timeout. * * @return {Request} for chaining * @api public */ RequestBase.prototype.clearTimeout = function () { clearTimeout(this._timer); clearTimeout(this._responseTimeoutTimer); clearTimeout(this._uploadTimeoutTimer); delete this._timer; delete this._responseTimeoutTimer; delete this._uploadTimeoutTimer; return this; }; /** * Override default response body parser * * This function will be called to convert incoming data into request.body * * @param {Function} * @api public */ RequestBase.prototype.parse = function (fn) { this._parser = fn; return this; }; /** * Set format of binary response body. * In browser valid formats are 'blob' and 'arraybuffer', * which return Blob and ArrayBuffer, respectively. * * In Node all values result in Buffer. * * Examples: * * req.get('/') * .responseType('blob') * .end(callback); * * @param {String} val * @return {Request} for chaining * @api public */ RequestBase.prototype.responseType = function (val) { this._responseType = val; return this; }; /** * Override default request body serializer * * This function will be called to convert data set via .send or .attach into payload to send * * @param {Function} * @api public */ RequestBase.prototype.serialize = function (fn) { this._serializer = fn; return this; }; /** * Set timeouts. * * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time. * - deadline is the time from start of the request to receiving response body in full. If the deadline is too short large files may not load at all on slow connections. * - upload is the time since last bit of data was sent or received. This timeout works only if deadline timeout is off * * Value of 0 or false means no timeout. * * @param {Number|Object} ms or {response, deadline} * @return {Request} for chaining * @api public */ RequestBase.prototype.timeout = function (options) { if (!options || _typeof(options) !== 'object') { this._timeout = options; this._responseTimeout = 0; this._uploadTimeout = 0; return this; } for (var option in options) { if (Object.prototype.hasOwnProperty.call(options, option)) { switch (option) { case 'deadline': this._timeout = options.deadline; break; case 'response': this._responseTimeout = options.response; break; case 'upload': this._uploadTimeout = options.upload; break; default: console.warn('Unknown timeout option', option); } } } return this; }; /** * Set number of retry attempts on error. * * Failed requests will be retried 'count' times if timeout or err.code >= 500. * * @param {Number} count * @param {Function} [fn] * @return {Request} for chaining * @api public */ RequestBase.prototype.retry = function (count, fn) { // Default to 1 if no count passed or true if (arguments.length === 0 || count === true) count = 1; if (count <= 0) count = 0; this._maxRetries = count; this._retries = 0; this._retryCallback = fn; return this; }; var ERROR_CODES = ['ECONNRESET', 'ETIMEDOUT', 'EADDRINFO', 'ESOCKETTIMEDOUT']; /** * Determine if a request should be retried. * (Borrowed from segmentio/superagent-retry) * * @param {Error} err an error * @param {Response} [res] response * @returns {Boolean} if segment should be retried */ RequestBase.prototype._shouldRetry = function (err, res) { var _this = this; return new Promise(function (resolve) { if (!_this._maxRetries || _this._retries++ >= _this._maxRetries) { return resolve(false); } if (_this._retryCallback) { try { _this._retryCallback(err, res).then(function (override) { resolve(override); }); return; } catch (err_) { console.error(err_); } } if (res && res.status && res.status >= 500 && res.status !== 501) return resolve(true); if (err) { if (err.code && ERROR_CODES.includes(err.code)) return resolve(true); // Superagent timeout if (err.timeout && err.code === 'ECONNABORTED') return resolve(true); if (err.crossDomain) return resolve(true); } return resolve(false); }); }; /** * Retry request * * @return {Request} for chaining * @api private */ RequestBase.prototype._retry = function () { var _this2 = this; return new Promise(function (resolve, reject) { _this2.clearTimeout(); // node if (_this2.req) { _this2.req = null; _this2.req = _this2.request(); } _this2._aborted = false; _this2.timedout = false; _this2.timedoutError = null; resolve(_this2._end()); }); }; /** * Promise support * * @param {Function} resolve * @param {Function} [reject] * @return {Request} */ RequestBase.prototype.then = function (resolve, reject) { var _this3 = this; if (!this._fullfilledPromise) { var self = this; if (this._endCalled) { console.warn('Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises'); } this._fullfilledPromise = new Promise(function (resolve, reject) { self.on('abort', function () { if (_this3._maxRetries && _this3._maxRetries > _this3._retries) { return; } if (_this3.timedout && _this3.timedoutError) { reject(_this3.timedoutError); return; } var err = new Error('Aborted'); err.code = 'ABORTED'; err.status = _this3.status; err.method = _this3.method; err.url = _this3.url; err.req = _this3.req; reject(err); }); self.end(function (err, res) { if (err) reject(err);else resolve(res); }); }); } return this._fullfilledPromise.then(resolve, reject); }; RequestBase.prototype.catch = function (cb) { return this.then(undefined, cb); }; /** * Allow for extension */ RequestBase.prototype.use = function (fn) { fn(this); return this; }; RequestBase.prototype.ok = function (cb) { if (typeof cb !== 'function') throw new Error('Callback required'); this._okCallback = cb; return this; }; RequestBase.prototype._isResponseOK = function (res) { if (!res) { return false; } if (this._okCallback) { return this._okCallback(res); } return res.status >= 200 && res.status < 300; }; /** * Get request header `field`. * Case-insensitive. * * @param {String} field * @return {String} * @api public */ RequestBase.prototype.get = function (field) { return this._header[field.toLowerCase()]; }; /** * Get case-insensitive header `field` value. * This is a deprecated internal API. Use `.get(field)` instead. * * (getHeader is no longer used internally by the superagent code base) * * @param {String} field * @return {String} * @api private * @deprecated */ RequestBase.prototype.getHeader = RequestBase.prototype.get; /** * Set header `field` to `val`, or multiple fields with one object. * Case-insensitive. * * Examples: * * req.get('/') * .set('Accept', 'application/json') * .set('X-API-Key', 'foobar') * .end(callback); * * req.get('/') * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) * .end(callback); * * @param {String|Object} field * @param {String} val * @return {Request} for chaining * @api public */ RequestBase.prototype.set = function (field, val) { if (isObject(field)) { for (var key in field) { if (Object.prototype.hasOwnProperty.call(field, key)) this.set(key, field[key]); } return this; } this._header[field.toLowerCase()] = val; this.header[field] = val; return this; }; /** * Remove header `field`. * Case-insensitive. * * Example: * * req.get('/') * .unset('User-Agent') * .end(callback); * * @param {String} field field name */ RequestBase.prototype.unset = function (field) { delete this._header[field.toLowerCase()]; delete this.header[field]; return this; }; /** * Write the field `name` and `val`, or multiple fields with one object * for "multipart/form-data" request bodies. * * ``` js * request.post('/upload') * .field('foo', 'bar') * .end(callback); * * request.post('/upload') * .field({ foo: 'bar', baz: 'qux' }) * .end(callback); * ``` * * @param {String|Object} name name of field * @param {String|Blob|File|Buffer|fs.ReadStream} val value of field * @return {Request} for chaining * @api public */ RequestBase.prototype.field = function (name, val) { // name should be either a string or an object. if (name === null || undefined === name) { throw new Error('.field(name, val) name can not be empty'); } if (this._data) { throw new Error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()"); } if (isObject(name)) { for (var key in name) { if (Object.prototype.hasOwnProperty.call(name, key)) this.field(key, name[key]); } return this; } if (Array.isArray(val)) { for (var i in val) { if (Object.prototype.hasOwnProperty.call(val, i)) this.field(name, val[i]); } return this; } // val should be defined now if (val === null || undefined === val) { throw new Error('.field(name, val) val can not be empty'); } if (typeof val === 'boolean') { val = String(val); } this._getFormData().append(name, val); return this; }; /** * Abort the request, and clear potential timeout. * * @return {Request} request * @api public */ RequestBase.prototype.abort = function () { if (this._aborted) { return this; } this._aborted = true; if (this.xhr) this.xhr.abort(); // browser if (this.req) this.req.abort(); // node this.clearTimeout(); this.emit('abort'); return this; }; RequestBase.prototype._auth = function (user, pass, options, base64Encoder) { switch (options.type) { case 'basic': this.set('Authorization', "Basic ".concat(base64Encoder("".concat(user, ":").concat(pass)))); break; case 'auto': this.username = user; this.password = pass; break; case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' }) this.set('Authorization', "Bearer ".concat(user)); break; default: break; } return this; }; /** * Enable transmission of cookies with x-domain requests. * * Note that for this to work the origin must not be * using "Access-Control-Allow-Origin" with a wildcard, * and also must set "Access-Control-Allow-Credentials" * to "true". * * @api public */ RequestBase.prototype.withCredentials = function (on) { // This is browser-only functionality. Node side is no-op. if (on === undefined) on = true; this._withCredentials = on; return this; }; /** * Set the max redirects to `n`. Does nothing in browser XHR implementation. * * @param {Number} n * @return {Request} for chaining * @api public */ RequestBase.prototype.redirects = function (n) { this._maxRedirects = n; return this; }; /** * Maximum size of buffered response body, in bytes. Counts uncompressed size. * Default 200MB. * * @param {Number} n number of bytes * @return {Request} for chaining */ RequestBase.prototype.maxResponseSize = function (n) { if (typeof n !== 'number') { throw new TypeError('Invalid argument'); } this._maxResponseSize = n; return this; }; /** * Convert to a plain javascript object (not JSON string) of scalar properties. * Note as this method is designed to return a useful non-this value, * it cannot be chained. * * @return {Object} describing method, url, and data of this request * @api public */ RequestBase.prototype.toJSON = function () { return { method: this.method, url: this.url, data: this._data, headers: this._header }; }; /** * Send `data` as the request body, defaulting the `.type()` to "json" when * an object is given. * * Examples: * * // manual json * request.post('/user') * .type('json') * .send('{"name":"tj"}') * .end(callback) * * // auto json * request.post('/user') * .send({ name: 'tj' }) * .end(callback) * * // manual x-www-form-urlencoded * request.post('/user') * .type('form') * .send('name=tj') * .end(callback) * * // auto x-www-form-urlencoded * request.post('/user') * .type('form') * .send({ name: 'tj' }) * .end(callback) * * // defaults to x-www-form-urlencoded * request.post('/user') * .send('name=tobi') * .send('species=ferret') * .end(callback) * * @param {String|Object} data * @return {Request} for chaining * @api public */ // eslint-disable-next-line complexity RequestBase.prototype.send = function (data) { var isObj = isObject(data); var type = this._header['content-type']; if (this._formData) { throw new Error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()"); } if (isObj && !this._data) { if (Array.isArray(data)) { this._data = []; } else if (!this._isHost(data)) { this._data = {}; } } else if (data && this._data && this._isHost(this._data)) { throw new Error("Can't merge these send calls"); } // merge if (isObj && isObject(this._data)) { for (var key in data) { if (Object.prototype.hasOwnProperty.call(data, key)) this._data[key] = data[key]; } } else if (typeof data === 'string') { // default to x-www-form-urlencoded if (!type) this.type('form'); type = this._header['content-type']; if (type === 'application/x-www-form-urlencoded') { this._data = this._data ? "".concat(this._data, "&").concat(data) : data; } else { this._data = (this._data || '') + data; } } else { this._data = data; } if (!isObj || this._isHost(data)) { return this; } // default to json if (!type) this.type('json'); return this; }; /** * Sort `querystring` by the sort function * * * Examples: * * // default order * request.get('/user') * .query('name=Nick') * .query('search=Manny') * .sortQuery() * .end(callback) * * // customized sort function * request.get('/user') * .query('name=Nick') * .query('search=Manny') * .sortQuery(function(a, b){ * return a.length - b.length; * }) * .end(callback) * * * @param {Function} sort * @return {Request} for chaining * @api public */ RequestBase.prototype.sortQuery = function (sort) { // _sort default to true but otherwise can be a function or boolean this._sort = typeof sort === 'undefined' ? true : sort; return this; }; /** * Compose querystring to append to req.url * * @api private */ RequestBase.prototype._finalizeQueryString = function () { var query = this._query.join('&'); if (query) { this.url += (this.url.includes('?') ? '&' : '?') + query; } this._query.length = 0; // Makes the call idempotent if (this._sort) { var index = this.url.indexOf('?'); if (index >= 0) { var queryArr = this.url.slice(index + 1).split('&'); if (typeof this._sort === 'function') { queryArr.sort(this._sort); } else { queryArr.sort(); } this.url = this.url.slice(0, index) + '?' + queryArr.join('&'); } } }; // For backwards compat only RequestBase.prototype._appendQueryString = function () { console.warn('Unsupported'); }; /** * Invoke callback with timeout error. * * @api private */ RequestBase.prototype._timeoutError = function (reason, timeout, errno) { if (this._aborted) { return; } var err = new Error("".concat(reason + timeout, "ms exceeded")); err.timeout = timeout; err.code = 'ECONNABORTED'; err.errno = errno; err.req = this.req; this.timedout = true; this.timedoutError = err; this.abort(); this.callback(err); }; RequestBase.prototype._setTimeouts = function () { var self = this; // deadline if (this._timeout && !this._timer) { this._timer = setTimeout(function () { self._timeoutError('Timeout of ', self._timeout, 'ETIME'); }, this._timeout); } // response timeout if (this._responseTimeout && !this._responseTimeoutTimer) { this._responseTimeoutTimer = setTimeout(function () { self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT'); }, this._responseTimeout); } }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1ZXN0LWJhc2UuanMiXSwibmFtZXMiOlsiaXNPYmplY3QiLCJyZXF1aXJlIiwibW9kdWxlIiwiZXhwb3J0cyIsIlJlcXVlc3RCYXNlIiwib2JqIiwibWl4aW4iLCJrZXkiLCJwcm90b3R5cGUiLCJPYmplY3QiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJjbGVhclRpbWVvdXQiLCJfdGltZXIiLCJfcmVzcG9uc2VUaW1lb3V0VGltZXIiLCJfdXBsb2FkVGltZW91dFRpbWVyIiwicGFyc2UiLCJmbiIsIl9wYXJzZXIiLCJyZXNwb25zZVR5cGUiLCJ2YWwiLCJfcmVzcG9uc2VUeXBlIiwic2VyaWFsaXplIiwiX3NlcmlhbGl6ZXIiLCJ0aW1lb3V0Iiwib3B0aW9ucyIsIl90aW1lb3V0IiwiX3Jlc3BvbnNlVGltZW91dCIsIl91cGxvYWRUaW1lb3V0Iiwib3B0aW9uIiwiZGVhZGxpbmUiLCJyZXNwb25zZSIsInVwbG9hZCIsImNvbnNvbGUiLCJ3YXJuIiwicmV0cnkiLCJjb3VudCIsImFyZ3VtZW50cyIsImxlbmd0aCIsIl9tYXhSZXRyaWVzIiwiX3JldHJpZXMiLCJfcmV0cnlDYWxsYmFjayIsIkVSUk9SX0NPREVTIiwiX3Nob3VsZFJldHJ5IiwiZXJyIiwicmVzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0aGVuIiwib3ZlcnJpZGUiLCJlcnJfIiwiZXJyb3IiLCJzdGF0dXMiLCJjb2RlIiwiaW5jbHVkZXMiLCJjcm9zc0RvbWFpbiIsIl9yZXRyeSIsInJlamVjdCIsInJlcSIsInJlcXVlc3QiLCJfYWJvcnRlZCIsInRpbWVkb3V0IiwidGltZWRvdXRFcnJvciIsIl9lbmQiLCJfZnVsbGZpbGxlZFByb21pc2UiLCJzZWxmIiwiX2VuZENhbGxlZCIsIm9uIiwiRXJyb3IiLCJtZXRob2QiLCJ1cmwiLCJlbmQiLCJjYXRjaCIsImNiIiwidW5kZWZpbmVkIiwidXNlIiwib2siLCJfb2tDYWxsYmFjayIsIl9pc1Jlc3BvbnNlT0siLCJnZXQiLCJmaWVsZCIsIl9oZWFkZXIiLCJ0b0xvd2VyQ2FzZSIsImdldEhlYWRlciIsInNldCIsImhlYWRlciIsInVuc2V0IiwibmFtZSIsIl9kYXRhIiwiQXJyYXkiLCJpc0FycmF5IiwiaSIsIlN0cmluZyIsIl9nZXRGb3JtRGF0YSIsImFwcGVuZCIsImFib3J0IiwieGhyIiwiZW1pdCIsIl9hdXRoIiwidXNlciIsInBhc3MiLCJiYXNlNjRFbmNvZGVyIiwidHlwZSIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJ3aXRoQ3JlZGVudGlhbHMiLCJfd2l0aENyZWRlbnRpYWxzIiwicmVkaXJlY3RzIiwibiIsIl9tYXhSZWRpcmVjdHMiLCJtYXhSZXNwb25zZVNpemUiLCJUeXBlRXJyb3IiLCJfbWF4UmVzcG9uc2VTaXplIiwidG9KU09OIiwiZGF0YSIsImhlYWRlcnMiLCJzZW5kIiwiaXNPYmoiLCJfZm9ybURhdGEiLCJfaXNIb3N0Iiwic29ydFF1ZXJ5Iiwic29ydCIsIl9zb3J0IiwiX2ZpbmFsaXplUXVlcnlTdHJpbmciLCJxdWVyeSIsIl9xdWVyeSIsImpvaW4iLCJpbmRleCIsImluZGV4T2YiLCJxdWVyeUFyciIsInNsaWNlIiwic3BsaXQiLCJfYXBwZW5kUXVlcnlTdHJpbmciLCJfdGltZW91dEVycm9yIiwicmVhc29uIiwiZXJybm8iLCJjYWxsYmFjayIsIl9zZXRUaW1lb3V0cyIsInNldFRpbWVvdXQiXSwibWFwcGluZ3MiOiI7Ozs7QUFBQTs7O0FBR0EsSUFBTUEsUUFBUSxHQUFHQyxPQUFPLENBQUMsYUFBRCxDQUF4QjtBQUVBOzs7OztBQUlBQyxNQUFNLENBQUNDLE9BQVAsR0FBaUJDLFdBQWpCO0FBRUE7Ozs7OztBQU1BLFNBQVNBLFdBQVQsQ0FBcUJDLEdBQXJCLEVBQTBCO0FBQ3hCLE1BQUlBLEdBQUosRUFBUyxPQUFPQyxLQUFLLENBQUNELEdBQUQsQ0FBWjtBQUNWO0FBRUQ7Ozs7Ozs7OztBQVFBLFNBQVNDLEtBQVQsQ0FBZUQsR0FBZixFQUFvQjtBQUNsQixPQUFLLElBQU1FLEdBQVgsSUFBa0JI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QUNBM0YsRUFBQUEsR0FBRyxDQUFDYyxHQUFKLEdBQVUsS0FBS0EsR0FBZjtBQUVBLE9BQUtHLFFBQUwsR0FBZ0IsSUFBaEI7QUFDQSxPQUFLQyxhQUFMLEdBQXFCbEIsR0FBckI7QUFDQSxPQUFLbUQsS0FBTDtBQUNBLE9BQUt5QyxRQUFMLENBQWM1RixHQUFkO0FBQ0QsQ0FmRDs7QUFpQkF4QyxXQUFXLENBQUNJLFNBQVosQ0FBc0JpSSxZQUF0QixHQUFxQyxZQUFZO0FBQy9DLE1BQU14RSxJQUFJLEdBQUcsSUFBYixDQUQrQyxDQUcvQzs7QUFDQSxNQUFJLEtBQUt2QyxRQUFMLElBQWlCLENBQUMsS0FBS2IsTUFBM0IsRUFBbUM7QUFDakMsU0FBS0EsTUFBTCxHQUFjNkgsVUFBVSxDQUFDLFlBQU07QUFDN0J6RSxNQUFBQSxJQUFJLENBQUNvRSxhQUFMLENBQW1CLGFBQW5CLEVBQWtDcEUsSUFBSSxDQUFDdkMsUUFBdkMsRUFBaUQsT0FBakQ7QUFDRCxLQUZ1QixFQUVyQixLQUFLQSxRQUZnQixDQUF4QjtBQUdELEdBUjhDLENBVS9DOzs7QUFDQSxNQUFJLEtBQUtDLGdCQUFMLElBQXlCLENBQUMsS0FBS2IscUJBQW5DLEVBQTBEO0FBQ3hELFNBQUtBLHFCQUFMLEdBQTZCNEgsVUFBVSxDQUFDLFlBQU07QUFDNUN6RSxNQUFBQSxJQUFJLENBQUNvRSxhQUFMLENBQ0Usc0JBREYsRUFFRXBFLElBQUksQ0FBQ3RDLGdCQUZQLEVBR0UsV0FIRjtBQUtELEtBTnNDLEVBTXBDLEtBQUtBLGdCQU4rQixDQUF2QztBQU9EO0FBQ0YsQ0FwQkQiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1vZHVsZSBvZiBtaXhlZC1pbiBmdW5jdGlvbnMgc2hhcmVkIGJldHdlZW4gbm9kZSBhbmQgY2xpZW50IGNvZGVcbiAqL1xuY29uc3QgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzLW9iamVjdCcpO1xuXG4vKipcbiAqIEV4cG9zZSBgUmVxdWVzdEJhc2VgLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gUmVxdWVzdEJhc2U7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgUmVxdWVzdEJhc2VgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gUmVxdWVzdEJhc2Uob2JqKSB7XG4gIGlmIChvYmopIHJldHVybiBtaXhpbihvYmopO1xufVxuXG4vKipcbiAqIE1peGluIHRoZSBwcm90b3R5cGUgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBtaXhpbihvYmopIHtcbiAgZm9yIChjb25zdCBrZXkgaW4gUmVxdWVzdEJhc2UucHJvdG90eXBlKSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChSZXF1ZXN0QmFzZS5wcm90b3R5cGUsIGtleSkpXG4gICAgICBvYmpba2V5XSA9IFJlcXVlc3RCYXNlLnByb3RvdHlwZVtrZXldO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBDbGVhciBwcmV2aW91cyB0aW1lb3V0LlxuICpcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUuY2xlYXJUaW1lb3V0ID0gZnVuY3Rpb24gKCkge1xuICBjbGVhclRpbWVvdXQodGhpcy5fdGltZXIpO1xuICBjbGVhclRpbWVvdXQodGhpcy5fcmVzcG9uc2VUaW1lb3V0VGltZXIpO1xuICBjbGVhclRpbWVvdXQodGhpcy5fdXBsb2FkVGltZW91dFRpbWVyKTtcbiAgZGVsZXRlIHRoaXMuX3RpbWVyO1xuICBkZWxldGUgdGhpcy5fcmVzcG9uc2VUaW1lb3V0VGltZXI7XG4gIGRlbGV0ZSB0aGlzLl91cGxvYWRUaW1lb3V0VGltZXI7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBPdmVycmlkZSBkZWZhdWx0IHJlc3BvbnNlIGJvZHkgcGFyc2VyXG4gKlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCB0byBjb252ZXJ0IGluY29taW5nIGRhdGEgaW50byByZXF1ZXN0LmJvZHlcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiAoZm4pIHtcbiAgdGhpcy5fcGFyc2VyID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgZm9ybWF0IG9mIGJpbmFyeSByZXNwb25zZSBib2R5LlxuICogSW4gYnJvd3NlciB2YWxpZCBmb3JtYXRzIGFyZSAnYmxvYicgYW5kICdhcnJheWJ1ZmZlcicsXG4gKiB3aGljaCByZXR1cm4gQmxvYiBhbmQgQXJyYXlCdWZmZXIsIHJlc3BlY3RpdmVseS5cbiAqXG4gKiBJbiBOb2RlIGFsbCB2YWx1ZXMgcmVzdWx0IGluIEJ1ZmZlci5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC5yZXNwb25zZVR5cGUoJ2Jsb2InKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWxcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUucmVzcG9uc2VUeXBlID0gZnVuY3Rpb24gKHZhbCkge1xuICB0aGlzLl9yZXNwb25zZVR5cGUgPSB2YWw7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBPdmVycmlkZSBkZWZhdWx0IHJlcXVlc3QgYm9keSBzZXJpYWxpemVyXG4gKlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCB0byBjb252ZXJ0IGRhdGEgc2V0IHZpYSAuc2VuZCBvciAuYXR0YWNoIGludG8gcGF5bG9hZCB0byBzZW5kXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLnNlcmlhbGl6ZSA9IGZ1bmN0aW9uIChmbikge1xuICB0aGlzLl9zZXJpYWxpemVyID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgdGltZW91dHMuXG4gKlxuICogLSByZXNwb25zZSB0aW1lb3V0IGlzIHRpbWUgYmV0d2VlbiBzZW5kaW5nIHJlcXVlc3QgYW5kIHJlY2VpdmluZyB0aGUgZmlyc3QgYnl0ZSBvZiB0aGUgcmVzcG9uc2UuIEluY2x1ZGVzIEROUyBhbmQgY29ubmVjdGlvbiB0aW1lLlxuICogLSBkZWFkbGluZSBpcyB0aGUgdGltZSBmcm9tIHN0YXJ0IG9mIHRoZSByZXF1ZXN0IHRvIHJlY2VpdmluZyByZXNwb25zZSBib2R5IGluIGZ1bGwuIElmIHRoZSBkZWFkbGluZSBpcyB0b28gc2hvcnQgbGFyZ2UgZmlsZXMgbWF5IG5vdCBsb2FkIGF0IGFsbCBvbiBzbG93IGNvbm5lY3Rpb25zLlxuICogLSB1cGxvYWQgaXMgdGhlIHRpbWUgIHNpbmNlIGxhc3QgYml0IG9mIGRhdGEgd2FzIHNlbnQgb3IgcmVjZWl2ZWQuIFRoaXMgdGltZW91dCB3b3JrcyBvbmx5IGlmIGRlYWRsaW5lIHRpbWVvdXQgaXMgb2ZmXG4gKlxuICogVmFsdWUgb2YgMCBvciBmYWxzZSBtZWFucyBubyB0aW1lb3V0LlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfE9iamVjdH0gbXMgb3Ige3Jlc3BvbnNlLCBkZWFkbGluZX1cbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUudGltZW91dCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICB0aGlzLl90aW1lb3V0ID0gb3B0aW9ucztcbiAgICB0aGlzLl9yZXNwb25zZVRpbWVvdXQgPSAwO1xuICAgIHRoaXMuX3VwbG9hZFRpbWVvdXQgPSAwO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZm9yIChjb25zdCBvcHRpb24gaW4gb3B0aW9ucykge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywgb3B0aW9uKSkge1xuICAgICAgc3dpdGNoIChvcHRpb24pIHtcbiAgICAgICAgY2FzZSAnZGVhZGxpbmUnOlxuICAgICAgICAgIHRoaXMuX3RpbWVvdXQgPSBvcHRpb25zLmRlYWRsaW5lO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdyZXNwb25zZSc6XG4gICAgICAgICAgdGhpcy5fcmVzcG9uc2VUaW1lb3V0ID0gb3B0aW9ucy5yZXNwb25zZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndXBsb2FkJzpcbiAgICAgICAgICB0aGlzLl91cGxvYWRUaW1lb3V0ID0gb3B0aW9ucy51cGxvYWQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgY29uc29sZS53YXJuKCdVbmtub3duIHRpbWVvdXQgb3B0aW9uJywgb3B0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IG51bWJlciBvZiByZXRyeSBhdHRlbXB0cyBvbiBlcnJvci5cbiAqXG4gKiBGYWlsZWQgcmVxdWVzdHMgd2lsbCBiZSByZXRyaWVkICdjb3VudCcgdGltZXMgaWYgdGltZW91dCBvciBlcnIuY29kZSA+PSA1MDAuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGNvdW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLnJldHJ5ID0gZnVuY3Rpb24gKGNvdW50LCBmbikge1xuICAvLyBEZWZhdWx0IHRvIDEgaWYgbm8gY291bnQgcGFzc2VkIG9yIHRydWVcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDAgfHwgY291bnQgPT09IHRydWUpIGNvdW50ID0gMTtcbiAgaWYgKGNvdW50IDw9IDApIGNvdW50ID0gMDtcbiAgdGhpcy5fbWF4UmV0cmllcyA9IGNvdW50O1xuICB0aGlzLl9yZXRyaWVzID0gMDtcbiAgdGhpcy5fcmV0cnlDYWxsYmFjayA9IGZuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmNvbnN0IEVSUk9SX0NPREVTID0gWydFQ09OTlJFU0VUJywgJ0VUSU1FRE9VVCcsICdFQUREUklORk8nLCAnRVNPQ0tFVFRJTUVET1VUJ107XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgcmVxdWVzdCBzaG91bGQgYmUgcmV0cmllZC5cbiAqIChCb3Jyb3dlZCBmcm9tIHNlZ21lbnRpby9zdXBlcmFnZW50LXJldHJ5KVxuICpcbiAqIEBwYXJhbSB7RXJyb3J9IGVyciBhbiBlcnJvclxuICogQHBhcmFtIHtSZXNwb25zZX0gW3Jlc10gcmVzcG9uc2VcbiAqIEByZXR1cm5zIHtCb29sZWFufSBpZiBzZWdtZW50IHNob3VsZCBiZSByZXRyaWVkXG4gKi9cblJlcXVlc3RCYXNlLnByb3RvdHlwZS5fc2hvdWxkUmV0cnkgPSBmdW5jdGlvbiAoZXJyLCByZXMpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgIGlmICghdGhpcy5fbWF4UmV0cmllcyB8fCB0aGlzLl9yZXRyaWVzKysgPj0gdGhpcy5fbWF4UmV0cmllcykge1xuICAgICAgcmV0dXJuIHJlc29sdmUoZmFsc2UpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9yZXRyeUNhbGxiYWNrKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLl9yZXRyeUNhbGxiYWNrKGVyciwgcmVzKS50aGVuKChvdmVycmlkZSkgPT4ge1xuICAgICAgICAgIHJlc29sdmUob3ZlcnJpZGUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZXJyXykge1xuICAgICAgICBjb25zb2xlLmVycm9yKGVycl8pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyZXMgJiYgcmVzLnN0YXR1cyAmJiByZXMuc3RhdHVzID49IDUwMCAmJiByZXMuc3RhdHVzICE9PSA1MDEpXG4gICAgICByZXR1cm4gcmVzb2x2ZSh0cnVlKTtcblxuICAgIGlmIChlcnIpIHtcbiAgICAgIGlmIChlcnIuY29kZSAmJiBFUlJPUl9DT0RFUy5pbmNsdWRlcyhlcnIuY29kZSkpIHJldHVybiByZXNvbHZlKHRydWUpO1xuICAgICAgLy8gU3VwZXJhZ2VudCB0aW1lb3V0XG4gICAgICBpZiAoZXJyLnRpbWVvdXQgJiYgZXJyLmNvZGUgPT09ICdFQ09OTkFCT1JURUQnKSByZXR1cm4gcmVzb2x2ZSh0cnVlKTtcbiAgICAgIGlmIChlcnIuY3Jvc3NEb21haW4pIHJldHVybiByZXNvbHZlKHRydWUpO1xuICAgIH1cblxuICAgIHJldHVybiByZXNvbHZlKGZhbHNlKTtcbiAgfSk7XG5cbn07XG5cbi8qKlxuICogUmV0cnkgcmVxdWVzdFxuICpcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLl9yZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICB0aGlzLmNsZWFyVGltZW91dCgpO1xuXG4gICAgLy8gbm9kZVxuICAgIGlmICh0aGlzLnJlcSkge1xuICAgICAgdGhpcy5yZXEgPSBudWxsO1xuICAgICAgdGhpcy5yZXEgPSB0aGlzLnJlcXVlc3QoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9hYm9ydGVkID0gZmFsc2U7XG4gICAgdGhpcy50aW1lZG91dCA9IGZhbHNlO1xuICAgIHRoaXMudGltZWRvdXRFcnJvciA9IG51bGw7XG5cbiAgICByZXNvbHZlKHRoaXMuX2VuZCgpKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIFByb21pc2Ugc3VwcG9ydFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHJlc29sdmVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtyZWplY3RdXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICovXG5cblJlcXVlc3RCYXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICBpZiAoIXRoaXMuX2Z1bGxmaWxsZWRQcm9taXNlKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgaWYgKHRoaXMuX2VuZENhbGxlZCkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAnV2FybmluZzogc3VwZXJhZ2VudCByZXF1ZXN0IHdhcyBzZW50IHR3aWNlLCBiZWNhdXNlIGJvdGggLmVuZCgpIGFuZCAudGhlbigpIHdlcmUgY2FsbGVkLiBOZXZlciBjYWxsIC5lbmQoKSBpZiB5b3UgdXNlIHByb21pc2VzJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLl9mdWxsZmlsbGVkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHNlbGYub24oJ2Fib3J0JywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5fbWF4UmV0cmllcyAmJiB0aGlzLl9tYXhSZXRyaWVzID4gdGhpcy5fcmV0cmllcykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnRpbWVkb3V0ICYmIHRoaXMudGltZWRvdXRFcnJvcikge1xuICAgICAgICAgIHJlamVjdCh0aGlzLnRpbWVkb3V0RXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVyciA9IG5ldyBFcnJvcignQWJvcnRlZCcpO1xuICAgICAgICBlcnIuY29kZSA9ICdBQk9SVEVEJztcbiAgICAgICAgZXJyLnN0YXR1cyA9IHRoaXMuc3RhdHVzO1xuICAgICAgICBlcnIubWV0aG9kID0gdGhpcy5tZXRob2Q7XG4gICAgICAgIGVyci51cmwgPSB0aGlzLnVybDtcbiAgICAgICAgZXJyLnJlcSA9IHRoaXMucmVxO1xuXG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfSk7XG4gICAgICBzZWxmLmVuZCgoZXJyLCByZXMpID0+IHtcbiAgICAgICAgaWYgKGVycikgcmVqZWN0KGVycik7XG4gICAgICAgIGVsc2UgcmVzb2x2ZShyZXMpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fZnVsbGZpbGxlZFByb21pc2UudGhlbihyZXNvbHZlLCByZWplY3QpO1xufTtcblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLmNhdGNoID0gZnVuY3Rpb24gKGNiKSB7XG4gIHJldHVybiB0aGlzLnRoZW4odW5kZWZpbmVkLCBjYik7XG59O1xuXG4vKipcbiAqIEFsbG93IGZvciBleHRlbnNpb25cbiAqL1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUudXNlID0gZnVuY3Rpb24gKGZuKSB7XG4gIGZuKHRoaXMpO1xuICByZXR1cm4gdGhpcztcbn07XG5cblJlcXVlc3RCYXNlLnByb3RvdHlwZS5vayA9IGZ1bmN0aW9uIChjYikge1xuICBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgRXJyb3IoJ0NhbGxiYWNrIHJlcXVpcmVkJyk7XG4gIHRoaXMuX29rQ2FsbGJhY2sgPSBjYjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUuX2lzUmVzcG9uc2VPSyA9IGZ1bmN0aW9uIChyZXMpIHtcbiAgaWYgKCFyZXMpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAodGhpcy5fb2tDYWxsYmFjaykge1xuICAgIHJldHVybiB0aGlzLl9va0NhbGxiYWNrKHJlcyk7XG4gIH1cblxuICByZXR1cm4gcmVzLnN0YXR1cyA+PSAyMDAgJiYgcmVzLnN0YXR1cyA8IDMwMDtcbn07XG5cbi8qKlxuICogR2V0IHJlcXVlc3QgaGVhZGVyIGBmaWVsZGAuXG4gKiBDYXNlLWluc2Vuc2l0aXZlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGZpZWxkKSB7XG4gIHJldHVybiB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV07XG59O1xuXG4vKipcbiAqIEdldCBjYXNlLWluc2Vuc2l0aXZlIGhlYWRlciBgZmllbGRgIHZhbHVlLlxuICogVGhpcyBpcyBhIGRlcHJlY2F0ZWQgaW50ZXJuYWwgQVBJLiBVc2UgYC5nZXQoZmllbGQpYCBpbnN0ZWFkLlxuICpcbiAqIChnZXRIZWFkZXIgaXMgbm8gbG9uZ2VyIHVzZWQgaW50ZXJuYWxseSBieSB0aGUgc3VwZXJhZ2VudCBjb2RlIGJhc2UpXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqIEBkZXByZWNhdGVkXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLmdldEhlYWRlciA9IFJlcXVlc3RCYXNlLnByb3RvdHlwZS5nZXQ7XG5cbi8qKlxuICogU2V0IGhlYWRlciBgZmllbGRgIHRvIGB2YWxgLCBvciBtdWx0aXBsZSBmaWVsZHMgd2l0aCBvbmUgb2JqZWN0LlxuICogQ2FzZS1pbnNlbnNpdGl2ZS5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC5zZXQoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJylcbiAqICAgICAgICAuc2V0KCdYLUFQSS1LZXknLCAnZm9vYmFyJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC5zZXQoeyBBY2NlcHQ6ICdhcHBsaWNhdGlvbi9qc29uJywgJ1gtQVBJLUtleSc6ICdmb29iYXInIH0pXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBmaWVsZFxuICogQHBhcmFtIHtTdHJpbmd9IHZhbFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3RCYXNlLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoZmllbGQsIHZhbCkge1xuICBpZiAoaXNPYmplY3QoZmllbGQpKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gZmllbGQpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZmllbGQsIGtleSkpXG4gICAgICAgIHRoaXMuc2V0KGtleSwgZmllbGRba2V5XSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV0gPSB2YWw7XG4gIHRoaXMuaGVhZGVyW2ZpZWxkXSA9IHZhbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBoZWFkZXIgYGZpZWxkYC5cbiAqIENhc2UtaW5zZW5zaXRpdmUuXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC51bnNldCgnVXNlci1BZ2VudCcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkIGZpZWxkIG5hbWVcbiAqL1xuUmVxdWVzdEJhc2UucHJvdG90eXBlLnVuc2V0ID0gZnVuY3Rpb24gKGZpZWxkKSB7XG4gIGRlbGV0ZSB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV07XG4gIGRlbGV0ZSB0aGlzLmhlYWRlcltmaWVsZF07XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBXcml0ZSB0aGUgZmllbGQgYG5hbWVgIGFuZCBgdmFsYCwgb3IgbXVsdGlwbGUgZmllbGRzIHdpdGggb25lIG9iamVjdFxuICogZm9yIFwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiIHJlcXVlc3QgYm9kaWVzLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmZpZWxkKCdmb28nLCAnYmFyJylcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmZpZWxkKHsgZm9vOiAnYmFyJywgYmF6OiAncXV4JyB9KVxuICogICAuZW5kKGNhbGxiYWNrKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdH0gbmFtZSBuYW1lIG9mIGZpZWxkXG4gKiBAcGFyYW0ge1N0cmluZ3xCbG9ifEZpbGV8QnVmZmVyfGZzLlJlYWRTdHJlYW19IHZhbCB2YWx1ZSBvZiBmaWVsZFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUuZmllbGQgPSBmdW5jdGlvbiAobmFtZSwgdmFsKSB7XG4gIC8vIG5hbWUgc2hvdWxkIGJlIGVpdGhlciBhIHN0cmluZyBvciBhbiBvYmplY3QuXG4gIGlmIChuYW1lID09PSBudWxsIHx8IHVuZGVmaW5lZCA9PT0gbmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignLmZpZWxkKG5hbWUsIHZhbCkgbmFtZSBjYW4gbm90IGJlIGVtcHR5Jyk7XG4gIH1cblxuICBpZiAodGhpcy5fZGF0Y