superagent
Version:
elegant & feature rich browser / node HTTP with a fluent API
1,521 lines • 151 kB
JavaScript
"use strict";
/**
* Module dependencies.
*/
const {
format
} = require('node:url');
const Stream = require('node:stream');
const https = require('node:https');
const http = require('node:http');
const fs = require('node:fs');
const zlib = require('node:zlib');
const util = require('node:util');
const qs = require('qs');
const mime = require('mime');
let methods = require('methods');
const FormData = require('form-data');
const formidable = require('formidable');
const debug = require('debug')('superagent');
const CookieJar = require('cookiejar');
const safeStringify = require('fast-safe-stringify');
const utils = require('../utils');
const RequestBase = require('../request-base');
const http2 = require('./http2wrapper');
const {
decompress
} = require('./unzip');
const Response = require('./response');
const {
mixin,
hasOwn,
isBrotliEncoding,
isGzipOrDeflateEncoding
} = utils;
const {
chooseDecompresser
} = require('./decompress');
function request(method, url) {
// callback
if (typeof url === 'function') {
return new exports.Request('GET', method).end(url);
}
// url first
if (arguments.length === 1) {
return new exports.Request('GET', method);
}
return new exports.Request(method, url);
}
module.exports = request;
exports = module.exports;
/**
* Expose `Request`.
*/
exports.Request = Request;
/**
* Expose the agent function
*/
exports.agent = require('./agent');
/**
* Noop.
*/
function noop() {}
/**
* Close an underlying Node request/session created during setup.
*
* Used when header application or later request-path work throws after
* `http.request()` / `http2.connect()` has already allocated a socket.
*
* @param {Request} request_
* @api private
*/
function disposeNodeRequest(request_) {
const {
req
} = request_;
if (!req || request_._requestDisposed) {
return;
}
request_._requestDisposed = true;
try {
// HTTP/2 wrapper keeps a session open as soon as request() is called.
// Prefer destroying that session so we never call abort() → getFrame()
// with invalid headers (which would emit a late protocol error).
if (req.session && typeof req.session.destroy === 'function') {
req.session.destroy();
}
if (req.socket && typeof req.socket.destroy === 'function') {
req.socket.destroy();
}
if (typeof req.destroy === 'function') {
req.destroy();
return;
}
if (typeof req.abort === 'function') {
req.abort();
return;
}
if (typeof req.end === 'function') {
req.end();
}
} catch (err) {
debug('error disposing request after setup failure', err);
}
}
/**
* Preserve dot-only path segments that WHATWG URL normalizes away.
*
* @param {String} urlString
* @returns {{urlString: String, restorePath: Function}}
* @api private
*/
function preserveDotSegments(urlString) {
const parts = urlString.match(/^([a-z][a-z\d+.-]*:\/\/[^/?#]*)([^?#]*)(.*)$/i);
if (!parts) {
return {
urlString,
restorePath(path) {
return path;
}
};
}
const segments = [];
const prefix = '__superagent_dot_segment_';
const path = parts[2].replace(/\/((?:\.|%2e){1,2})(?=\/|$)/gi, (_, segment) => {
const marker = `${prefix}${segments.length}__`;
segments.push(segment);
return `/${marker}`;
});
return {
urlString: `${parts[1]}${path}${parts[3]}`,
restorePath(requestPath) {
let restoredPath = requestPath;
for (const [index, segment] of segments.entries()) {
restoredPath = restoredPath.replace(`${prefix}${index}__`, segment);
}
return restoredPath;
}
};
}
/**
* Expose `Response`.
*/
exports.Response = Response;
/**
* Define "form" mime type.
*/
mime.define({
'application/x-www-form-urlencoded': ['form', 'urlencoded', 'form-data']
}, true);
/**
* Protocol map.
*/
exports.protocols = {
'http:': http,
'https:': https,
'http2:': http2
};
/**
* Default serialization map.
*
* superagent.serialize['application/xml'] = function(obj){
* return 'generated xml here';
* };
*
*/
exports.serialize = {
'application/x-www-form-urlencoded'(object) {
return qs.stringify(object, {
indices: false,
strictNullHandling: true
});
},
'application/json': safeStringify,
// CSP reports carry JSON bodies but use a distinct registered media type.
'application/csp-report': safeStringify
};
/**
* Default parsers.
*
* superagent.parse['application/xml'] = function(res, fn){
* fn(null, res);
* };
*
*/
exports.parse = require('./parsers');
/**
* Default buffering map. Can be used to set certain
* response types to buffer/not buffer.
*
* superagent.buffer['application/xml'] = true;
*/
exports.buffer = {};
/**
* Initialize internal header tracking properties on a request instance.
*
* @param {Object} req the instance
* @api private
*/
function _initHeaders(request_) {
request_._header = {
// coerces header names to lowercase
};
request_.header = {
// preserves header name case
};
}
/**
* Initialize a new `Request` with the given `method` and `url`.
*
* @param {String} method
* @param {String|Object} url
* @api public
*/
function Request(method, url) {
Stream.call(this);
if (typeof url !== 'string') url = format(url);
this._enableHttp2 = Boolean(process.env.HTTP2_TEST); // internal only
this._agent = false;
this._formData = null;
this.method = method;
this.url = url;
_initHeaders(this);
this.writable = true;
this._redirects = 0;
this.redirects(method === 'HEAD' ? 0 : 5);
this.cookies = '';
this.qs = {};
this._query = [];
this.qsRaw = this._query; // Unused, for backwards compatibility only
this._redirectList = [];
this._streamRequest = false;
this._lookup = undefined;
this.once('end', this.clearTimeout.bind(this));
}
/**
* Inherit from `Stream` (which inherits from `EventEmitter`).
* Mixin `RequestBase`.
*/
util.inherits(Request, Stream);
mixin(Request.prototype, RequestBase.prototype);
/**
* Enable or Disable http2.
*
* Enable http2.
*
* ``` js
* request.get('http://localhost/')
* .http2()
* .end(callback);
*
* request.get('http://localhost/')
* .http2(true)
* .end(callback);
* ```
*
* Disable http2.
*
* ``` js
* request = request.http2();
* request.get('http://localhost/')
* .http2(false)
* .end(callback);
* ```
*
* @param {Boolean} enable
* @return {Request} for chaining
* @api public
*/
Request.prototype.http2 = function (bool) {
if (exports.protocols['http2:'] === undefined) {
throw new Error('superagent: this version of Node.js does not support http2');
}
this._enableHttp2 = bool === undefined ? true : bool;
return this;
};
/**
* Queue the given `file` as an attachment to the specified `field`,
* with optional `options` (or filename).
*
* ``` js
* request.post('http://localhost/upload')
* .attach('field', Buffer.from('<b>Hello world</b>'), 'hello.html')
* .end(callback);
* ```
*
* A filename may also be used:
*
* ``` js
* request.post('http://localhost/upload')
* .attach('files', 'image.jpg')
* .end(callback);
* ```
*
* @param {String} field
* @param {String|fs.ReadStream|Buffer} file
* @param {String|Object} options
* @return {Request} for chaining
* @api public
*/
Request.prototype.attach = function (field, file, options) {
if (file) {
if (this._data) {
throw new Error("superagent can't mix .send() and .attach()");
}
let o = options || {};
if (typeof options === 'string') {
o = {
filename: options
};
}
if (typeof file === 'string') {
if (!o.filename) o.filename = file;
debug('creating `fs.ReadStream` instance for file: %s', file);
file = fs.createReadStream(file);
file.on('error', error => {
const formData = this._getFormData();
formData.emit('error', error);
});
} else if (!o.filename && file.path) {
o.filename = file.path;
}
this._getFormData().append(field, file, o);
}
return this;
};
Request.prototype._getFormData = function () {
if (!this._formData) {
this._formData = new FormData();
this._formData.on('error', error => {
debug('FormData error', error);
if (this.called) {
// The request has already finished and the callback was called.
// Silently ignore the error.
return;
}
this.callback(error);
this.abort();
});
}
return this._formData;
};
/**
* Gets/sets the `Agent` to use for this HTTP request. The default (if this
* function is not called) is to opt out of connection pooling (`agent: false`).
*
* @param {http.Agent} agent
* @return {http.Agent}
* @api public
*/
Request.prototype.agent = function (agent) {
if (arguments.length > 0 && agent && typeof agent === 'object' && typeof agent.addRequest !== 'function') {
throw new TypeError('.agent() expects an http(s).Agent-compatible object. Did you mean to use .cert() and .key()?');
}
if (arguments.length === 0) return this._agent;
this._agent = agent;
return this;
};
/**
* Gets/sets the `lookup` function to use custom DNS resolver.
*
* @param {Function} lookup
* @return {Function}
* @api public
*/
Request.prototype.lookup = function (lookup) {
if (arguments.length === 0) return this._lookup;
this._lookup = lookup;
return this;
};
/**
* Set _Content-Type_ response header passed through `mime.getType()`.
*
* Examples:
*
* request.post('/')
* .type('xml')
* .send(xmlstring)
* .end(callback);
*
* request.post('/')
* .type('json')
* .send(jsonstring)
* .end(callback);
*
* request.post('/')
* .type('application/json')
* .send(jsonstring)
* .end(callback);
*
* @param {String} type
* @return {Request} for chaining
* @api public
*/
Request.prototype.type = function (type) {
return this.set('Content-Type', type.includes('/') ? type : mime.getType(type));
};
/**
* Set _Accept_ response header passed through `mime.getType()`.
*
* Examples:
*
* superagent.types.json = 'application/json';
*
* request.get('/agent')
* .accept('json')
* .end(callback);
*
* request.get('/agent')
* .accept('application/json')
* .end(callback);
*
* @param {String} accept
* @return {Request} for chaining
* @api public
*/
Request.prototype.accept = function (type) {
return this.set('Accept', type.includes('/') ? type : mime.getType(type));
};
/**
* Add query-string `val`.
*
* Examples:
*
* request.get('/shoes')
* .query('size=10')
* .query({ color: 'blue' })
*
* @param {Object|String} val
* @return {Request} for chaining
* @api public
*/
Request.prototype.query = function (value) {
if (typeof value === 'string') {
this._query.push(value);
} else {
Object.assign(this.qs, value);
}
return this;
};
/**
* Write raw `data` / `encoding` to the socket.
*
* @param {Buffer|String} data
* @param {String} encoding
* @return {Boolean}
* @api public
*/
Request.prototype.write = function (data, encoding) {
const request_ = this.request();
if (!this._streamRequest) {
this._streamRequest = true;
}
return request_.write(data, encoding);
};
/**
* Pipe the request body to `stream`.
*
* @param {Stream} stream
* @param {Object} options
* @return {Stream}
* @api public
*/
Request.prototype.pipe = function (stream, options) {
this.piped = true; // HACK...
this.buffer(false);
this.end();
return this._pipeContinue(stream, options);
};
Request.prototype._pipeContinue = function (stream, options) {
this.req.once('response', res => {
// redirect
if (isRedirect(res.statusCode) && this._redirects++ !== this._maxRedirects) {
return this._redirect(res) === this ? this._pipeContinue(stream, options) : undefined;
}
this.res = res;
this._emitResponse();
if (this._aborted) return;
if (this._shouldDecompress(res)) {
const decompresser = chooseDecompresser(res);
decompresser.on('error', error => {
if (error && error.code === 'Z_BUF_ERROR') {
// unexpected end of file is ignored by browsers and curl
stream.emit('end');
return;
}
stream.emit('error', error);
});
res.pipe(decompresser).pipe(stream, options);
// don't emit 'end' until decompresser has completed writing all its data.
decompresser.once('end', () => this.emit('end'));
} else {
res.pipe(stream, options);
res.once('end', () => this.emit('end'));
}
});
return stream;
};
/**
* Enable / disable buffering.
*
* @return {Boolean} [val]
* @return {Request} for chaining
* @api public
*/
Request.prototype.buffer = function (value) {
this._buffer = value !== false;
return this;
};
/**
* Redirect to `url
*
* @param {IncomingMessage} res
* @return {Request} for chaining
* @api private
*/
Request.prototype._redirect = function (res) {
let url = res.headers.location;
if (!url) {
return this.callback(new Error('No location header for redirect'), res);
}
debug('redirect %s -> %s', this.url, url);
// location
url = new URL(url, this.url).href;
// ensure the response is being consumed
// this is required for Node v0.10+
res.resume();
this._emitPreRedirect(res);
let headers = this.req.getHeaders ? this.req.getHeaders() : this.req._headers;
const changesOrigin = new URL(url).origin !== new URL(this.url).origin;
// implementation of 302 following defacto standard
if (res.statusCode === 301 || res.statusCode === 302) {
// strip Content-* related fields
// in case of POST etc
headers = utils.cleanHeader(headers, changesOrigin);
// force GET
this.method = this.method === 'HEAD' ? 'HEAD' : 'GET';
// clear data
this._data = null;
}
// 303 is always GET
if (res.statusCode === 303) {
// strip Content-* related fields
// in case of POST etc
headers = utils.cleanHeader(headers, changesOrigin);
// force method
this.method = 'GET';
// clear data
this._data = null;
}
// 307 preserves method
// 308 preserves method
if ((res.statusCode === 307 || res.statusCode === 308) && changesOrigin) {
delete headers.authorization;
delete headers.cookie;
}
delete headers.host;
delete this.req;
delete this._formData;
// remove all add header except User-Agent
_initHeaders(this);
// redirect
this.res = res;
this._endCalled = false;
this.url = url;
this.qs = {};
this._query.length = 0;
this.set(headers);
this._emitRedirect();
this._redirectList.push(this.url);
this.end(this._callback);
return this;
};
/**
* Set Authorization field value with `user` and `pass`.
*
* Examples:
*
* .auth('tobi', 'learnboost')
* .auth('tobi:learnboost')
* .auth('tobi')
* .auth(accessToken, { type: 'bearer' })
*
* @param {String} user
* @param {String} [pass]
* @param {Object} [options] options with authorization type 'basic' or 'bearer' ('basic' is default)
* @return {Request} for chaining
* @api public
*/
Request.prototype.auth = function (user, pass, options) {
if (arguments.length === 1) pass = '';
if (typeof pass === 'object' && pass !== null) {
// pass is optional and can be replaced with options
options = pass;
pass = '';
}
if (!options) {
options = {
type: 'basic'
};
}
const encoder = string => Buffer.from(string).toString('base64');
return this._auth(user, pass, options, encoder);
};
/**
* Set the certificate authority option for https request.
*
* @param {Buffer | Array} cert
* @return {Request} for chaining
* @api public
*/
Request.prototype.ca = function (cert) {
this._ca = cert;
return this;
};
/**
* Set the client certificate key option for https request.
*
* @param {Buffer | String} cert
* @return {Request} for chaining
* @api public
*/
Request.prototype.key = function (cert) {
this._key = cert;
return this;
};
/**
* Set the key, certificate, and CA certs of the client in PFX or PKCS12 format.
*
* @param {Buffer | String} cert
* @return {Request} for chaining
* @api public
*/
Request.prototype.pfx = function (cert) {
if (typeof cert === 'object' && !Buffer.isBuffer(cert)) {
this._pfx = cert.pfx;
this._passphrase = cert.passphrase;
} else {
this._pfx = cert;
}
return this;
};
/**
* Set the client certificate option for https request.
*
* @param {Buffer | String} cert
* @return {Request} for chaining
* @api public
*/
Request.prototype.cert = function (cert) {
this._cert = cert;
return this;
};
/**
* Do not reject expired or invalid TLS certs.
* sets `rejectUnauthorized=true`. Be warned that this allows MITM attacks.
*
* @return {Request} for chaining
* @api public
*/
Request.prototype.disableTLSCerts = function () {
this._disableTLSCerts = true;
return this;
};
/**
* Return an http[s] request.
*
* @return {OutgoingMessage}
* @api private
*/
// eslint-disable-next-line complexity
Request.prototype.request = function () {
if (this.req) return this.req;
const options = {};
try {
const query = qs.stringify(this.qs, {
indices: false,
strictNullHandling: true
});
if (query) {
this.qs = {};
this._query.push(query);
}
this._finalizeQueryString();
} catch (err) {
return this.emit('error', err);
}
let {
url: urlString
} = this;
const retries = this._retries;
// default to http://
if (urlString.indexOf('http') !== 0) urlString = `http://${urlString}`;
const protectedUrl = preserveDotSegments(urlString);
const url = new URL(protectedUrl.urlString);
let {
protocol
} = url;
const path = protectedUrl.restorePath(`${url.pathname}${url.search}`);
// support unix sockets
if (/^https?\+unix:/.test(protocol) === true) {
// get the protocol
protocol = `${protocol.split('+')[0]}:`;
if (!url.hostname) {
throw new Error('Invalid unix socket URL: percent-encode the socket path by replacing "/" with "%2F".');
}
// get the socket path
options.socketPath = url.hostname.replace(/%2F/g, '/');
url.host = '';
url.hostname = '';
}
// Override IP address of a hostname
if (this._connectOverride) {
const {
hostname
} = url;
const match = hostname in this._connectOverride ? this._connectOverride[hostname] : this._connectOverride['*'];
if (match) {
// backup the real host
if (!this._header.host) {
this.set('host', url.host);
}
let newHost;
let newPort;
if (typeof match === 'object') {
newHost = match.host;
newPort = match.port;
} else {
newHost = match;
newPort = url.port;
}
// wrap [ipv6]
url.host = /:/.test(newHost) ? `[${newHost}]` : newHost;
if (newPort) {
url.host += `:${newPort}`;
url.port = newPort;
}
url.hostname = newHost;
}
}
// options
options.method = this.method;
options.port = url.port;
options.path = path;
options.host = utils.normalizeHostname(url.hostname); // ex: [::1] -> ::1
// Apply user headers before connecting so invalid values (e.g. undefined)
// throw without allocating a TCP handle. See #1827.
// HTTP/2's wrapper forwards leftover options to http2.connect(), so only
// do this on HTTP/1.
if (!this._enableHttp2) {
options.headers = {
...this.header
};
}
options.ca = this._ca;
options.key = this._key;
options.pfx = this._pfx;
options.cert = this._cert;
options.passphrase = this._passphrase;
options.agent = this._agent;
options.lookup = this._lookup;
options.rejectUnauthorized = typeof this._disableTLSCerts === 'boolean' ? !this._disableTLSCerts : process.env.NODE_TLS_REJECT_UNAUTHORIZED !== '0';
// Allows request.get('https://1.2.3.4/').set('Host', 'example.com')
if (this._header.host) {
options.servername = this._header.host.replace(/:\d+$/, '');
}
if (this._trustLocalhost && /^(?:localhost|127\.0\.0\.\d+|(0*:)+:0*1)$/.test(url.hostname)) {
options.rejectUnauthorized = false;
}
// initiate request
const module_ = this._enableHttp2 ? exports.protocols['http2:'].setProtocol(protocol) : exports.protocols[protocol];
// request
this.req = module_.request(options);
const {
req
} = this;
// Attach this before header setup so destroy() during a setup exception
// cannot emit an unhandled 'error' (or a second callback).
req.on('error', error => {
// flag abortion here for out timeouts
// because node will emit a faux-error "socket hang up"
// when request is aborted before a connection is made
if (this._aborted || this._requestDisposed) return;
// if not the same, we are in the **old** (cancelled) request,
// so need to continue (same as for above)
if (this._retries !== retries) return;
// if we've received a response then we don't want to let
// an error in the request blow up the response
if (this.response) return;
this.callback(error);
});
try {
// set tcp no delay
req.setNoDelay(true);
if (options.method !== 'HEAD') {
req.setHeader('Accept-Encoding', 'gzip, deflate');
}
this.protocol = protocol;
this.host = url.host;
// expose events
const emitDrain = () => {
this.emit('drain');
};
req.on('drain', emitDrain);
req.once('close', () => {
req.removeListener('drain', emitDrain);
});
// auth
if (url.username || url.password) {
this.auth(url.username, url.password);
}
if (this.username && this.password) {
this.auth(this.username, this.password);
}
for (const key in this.header) {
if (hasOwn(this.header, key)) req.setHeader(key, this.header[key]);
}
// add cookies
if (this.cookies) {
if (hasOwn(this._header, 'cookie')) {
// merge
const temporaryJar = new CookieJar.CookieJar();
temporaryJar.setCookies(this._header.cookie.split('; '));
temporaryJar.setCookies(this.cookies.split('; '));
req.setHeader('Cookie', temporaryJar.getCookies(CookieJar.CookieAccessInfo.All).toValueString());
} else {
req.setHeader('Cookie', this.cookies);
}
}
return req;
} catch (err) {
disposeNodeRequest(this);
throw err;
}
};
/**
* Abort/end the Node request if it was created.
*
* @api private
*/
Request.prototype._disposeRequest = function () {
disposeNodeRequest(this);
};
/**
* Report a setup/request-path error without leaving the socket open.
*
* @param {Error} error
* @api private
*/
Request.prototype._failRequest = function (error) {
this._disposeRequest();
if (typeof this._callback === 'function' && this._callback !== noop) {
this.callback(error);
return;
}
throw error;
};
/**
* Invoke the callback with `err` and `res`
* and handle arity check.
*
* @param {Error} err
* @param {Response} res
* @api private
*/
Request.prototype.callback = function (error, res) {
if (this._shouldRetry(error, res)) {
return this._retry();
}
// Avoid the error which is emitted from 'socket hang up' to cause the fn undefined error on JS runtime.
const fn = this._callback || noop;
this.clearTimeout();
if (this.called) {
if (this.timedout) return;
return console.warn('superagent: double callback bug');
}
this.called = true;
if (!error) {
try {
if (!this._isResponseOK(res)) {
let message = 'Unsuccessful HTTP response';
if (res) {
message = http.STATUS_CODES[res.status] || message;
}
error = new Error(message);
error.status = res ? res.status : undefined;
}
} catch (err) {
error = err;
error.status = error.status || (res ? res.status : undefined);
}
}
// It's important that the callback is called outside try/catch
// to avoid double callback
if (!error) {
return fn(null, res);
}
error.response = res;
if (this._maxRetries) error.retries = this._retries - 1;
// only emit error event if there is a listener
// otherwise we assume the callback to `.end()` will get the error
if (error && this.listeners('error').length > 0) {
this.emit('error', error);
}
fn(error, res);
};
/**
* Check if `obj` is a host object,
*
* @param {Object} obj host object
* @return {Boolean} is a host object
* @api private
*/
Request.prototype._isHost = function (object) {
return Buffer.isBuffer(object) || object instanceof Stream || object instanceof FormData;
};
/**
* Initiate request, invoking callback `fn(err, res)`
* with an instanceof `Response`.
*
* @param {Function} fn
* @return {Request} for chaining
* @api public
*/
Request.prototype._emitResponse = function (body, files) {
const response = new Response(this);
this.response = response;
response.redirects = this._redirectList;
if (undefined !== body) {
response.body = body;
}
response.files = files;
if (this._endCalled) {
response.pipe = function () {
throw new Error("end() has already been called, so it's too late to start piping");
};
}
this.emit('response', response);
return response;
};
/**
* Emit `redirect` event, passing an instanceof `Response`.
*
* @api private
*/
Request.prototype._emitRedirect = function () {
const response = new Response(this);
response.redirects = this._redirectList;
this.emit('redirect', response);
};
/**
* Emit a redirect response before the request URL is changed.
*
* @param {IncomingMessage} res
* @api private
*/
Request.prototype._emitPreRedirect = function (res) {
this.res = res;
const response = new Response(this);
response.redirects = this._redirectList;
this.emit('pre-redirect', response);
};
Request.prototype.end = function (fn) {
try {
this.request();
} catch (err) {
this._endCalled = true;
if (typeof fn === 'function') {
this._callback = fn;
this.callback(err);
return;
}
throw err;
}
debug('%s %s', this.method, this.url);
if (this._endCalled) {
throw new Error('.end() was called twice. This is not supported in superagent');
}
this._endCalled = true;
// store callback
this._callback = fn || noop;
this._end();
};
Request.prototype._end = function () {
if (this._aborted) return this.callback(new Error('The request has been aborted even before .end() was called'));
let data = this._data;
const {
req
} = this;
const {
method
} = this;
this._setTimeouts();
// body
if (method !== 'HEAD' && !req._headerSent) {
try {
// serialize stuff
if (typeof data !== 'string') {
let contentType = req.getHeader('Content-Type');
// Parse out just the content type from the header (ignore the charset)
if (contentType) contentType = contentType.split(';')[0];
let serialize = this._serializer || exports.serialize[contentType];
if (!serialize && isJSON(contentType)) {
serialize = exports.serialize['application/json'];
}
if (serialize) data = serialize(data);
}
// content-length
if (data && !req.getHeader('Content-Length')) {
req.setHeader('Content-Length', Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data));
}
} catch (err) {
return this._failRequest(err);
}
}
// response
// eslint-disable-next-line complexity
req.once('response', res => {
debug('%s %s -> %s', this.method, this.url, res.statusCode);
if (this._responseTimeoutTimer) {
clearTimeout(this._responseTimeoutTimer);
}
if (this.piped) {
return;
}
const max = this._maxRedirects;
const mime = utils.type(res.headers['content-type'] || '') || 'text/plain';
let type = mime.split('/')[0];
if (type) type = type.toLowerCase().trim();
const multipart = type === 'multipart';
const redirect = isRedirect(res.statusCode);
const responseType = this._responseType;
this.res = res;
// redirect
if (redirect && this._redirects++ !== max) {
return this._redirect(res);
}
if (this.method === 'HEAD') {
this.emit('end');
this.callback(null, this._emitResponse());
return;
}
// zlib support
if (this._shouldDecompress(res)) {
decompress(req, res);
}
let buffer = this._buffer;
if (buffer === undefined && mime in exports.buffer) {
buffer = Boolean(exports.buffer[mime]);
}
let parser = this._parser;
if (undefined === buffer && parser) {
console.warn("A custom superagent parser has been set, but buffering strategy for the parser hasn't been configured. Call `req.buffer(true or false)` or set `superagent.buffer[mime] = true or false`");
buffer = true;
}
if (!parser) {
if (responseType) {
parser = exports.parse.image; // It's actually a generic Buffer
buffer = true;
} else if (multipart) {
const form = formidable.formidable();
parser = (res, callback) => {
// Create a PassThrough stream that acts as a proper HTTP request
const bridgeStream = new Stream.PassThrough();
// Add HTTP request properties from the current request context
bridgeStream.method = this.method || 'POST';
bridgeStream.url = this.url || '/';
bridgeStream.httpVersion = res.httpVersion || '1.1';
bridgeStream.headers = res.headers || {};
bridgeStream.socket = res.socket || {
readable: true
};
// Pipe the response data through the bridge stream
res.pipe(bridgeStream);
form.parse(bridgeStream, (err, fields, files) => {
if (err) return callback(err);
// Formidable v3 always returns arrays, but SuperAgent expects single values
// Flatten single-item arrays to maintain backward compatibility
const flattenedFields = {};
if (fields) {
for (const key in fields) {
if (!Object.prototype.hasOwnProperty.call(fields, key)) continue;
const value = fields[key];
flattenedFields[key] = Array.isArray(value) && value.length === 1 ? value[0] : value;
}
}
const flattenedFiles = {};
if (files) {
for (const key in files) {
if (!Object.prototype.hasOwnProperty.call(files, key)) continue;
const value = files[key];
flattenedFiles[key] = Array.isArray(value) && value.length === 1 ? value[0] : value;
}
}
// Return flattened fields as the object parameter to match SuperAgent's expected format
callback(null, flattenedFields, flattenedFiles);
});
};
buffer = true;
} else if (isBinary(mime)) {
parser = exports.parse.image;
buffer = buffer !== false; // For backwards-compatibility buffering default is ad-hoc MIME-dependent
} else if (exports.parse[mime]) {
parser = exports.parse[mime];
} else if (type === 'text') {
parser = exports.parse.text;
buffer = buffer !== false;
// everyone wants their own white-labeled json
} else if (isJSON(mime)) {
parser = exports.parse['application/json'];
buffer = buffer !== false;
} else if (buffer) {
parser = exports.parse.text;
} else if (undefined === buffer) {
parser = exports.parse.image; // It's actually a generic Buffer
buffer = true;
}
}
// by default only buffer text/*, json and messed up thing from hell
if (undefined === buffer && isText(mime) || isJSON(mime)) {
buffer = true;
}
this._resBuffered = buffer;
let parserHandlesEnd = false;
if (buffer) {
// Protectiona against zip bombs and other nuisance
let responseBytesLeft = this._maxResponseSize || 200000000;
res.on('data', buf => {
responseBytesLeft -= buf.byteLength || buf.length > 0 ? buf.length : 0;
if (responseBytesLeft < 0) {
const error = new Error('Maximum response size reached');
error.code = 'ETOOLARGE';
// Parsers aren't required to observe error event,
// so would incorrectly report success
parserHandlesEnd = false;
// Destroy without an error: IncomingMessage.destroy(err) emits
// 'error', and the parser may also fail, each of which would
// call callback() again ("superagent: double callback bug").
res.destroy();
this.callback(error, null);
}
});
}
if (parser) {
try {
// Unbuffered parsers are supposed to emit response early,
// which is weird BTW, because response.body won't be there.
parserHandlesEnd = buffer;
parser(res, (error, object, files) => {
if (this.timedout || this.called) {
// Timeout or maxResponseSize has already handled all callbacks
return;
}
// Intentional (non-timeout) abort is supposed to preserve partial response,
// even if it doesn't parse.
if (error && !this._aborted) {
return this.callback(error);
}
if (parserHandlesEnd) {
this.emit('end');
this.callback(null, this._emitResponse(object, files));
}
});
} catch (err) {
this.callback(err);
return;
}
}
this.res = res;
// unbuffered
if (!buffer) {
debug('unbuffered %s %s', this.method, this.url);
this.callback(null, this._emitResponse());
if (multipart) return; // allow multipart to handle end event
res.once('end', () => {
debug('end %s %s', this.method, this.url);
this.emit('end');
});
return;
}
const completeAbortedResponse = () => {
if (!this._aborted) {
return false;
}
parserHandlesEnd = false;
if (!this.called) {
this.emit('end');
const response = this._emitResponse();
response.on('error', noop);
this.callback(null, response);
}
return true;
};
// terminating events
res.once('error', error => {
if (completeAbortedResponse()) return;
parserHandlesEnd = false;
this.callback(error, null);
});
res.once('aborted', completeAbortedResponse);
res.once('close', completeAbortedResponse);
if (!parserHandlesEnd) res.once('end', () => {
debug('end %s %s', this.method, this.url);
// TODO: unless buffering emit earlier to stream
this.emit('end');
this.callback(null, this._emitResponse());
});
});
this.emit('request', this);
const getProgressMonitor = () => {
const lengthComputable = true;
const total = req.getHeader('Content-Length');
let loaded = 0;
const progress = new Stream.Transform();
progress._transform = (chunk, encoding, callback) => {
loaded += chunk.length;
this.emit('progress', {
direction: 'upload',
lengthComputable,
loaded,
total
});
callback(null, chunk);
};
return progress;
};
const bufferToChunks = buffer => {
const chunkSize = 16 * 1024; // default highWaterMark value
const chunking = new Stream.Readable();
const totalLength = buffer.length;
const remainder = totalLength % chunkSize;
const cutoff = totalLength - remainder;
for (let i = 0; i < cutoff; i += chunkSize) {
const chunk = buffer.slice(i, i + chunkSize);
chunking.push(chunk);
}
if (remainder > 0) {
const remainderBuffer = buffer.slice(-remainder);
chunking.push(remainderBuffer);
}
chunking.push(null); // no more data
return chunking;
};
try {
// if a FormData instance got created, then we send that as the request body
const formData = this._formData;
if (formData) {
// set headers
const headers = formData.getHeaders();
for (const i in headers) {
if (hasOwn(headers, i)) {
debug('setting FormData header: "%s: %s"', i, headers[i]);
req.setHeader(i, headers[i]);
}
}
// attempt to get "Content-Length" header
formData.getLength((error, length) => {
// TODO: Add chunked encoding when no length (if err)
if (error) debug('formData.getLength had error', error, length);
debug('got FormData Content-Length: %s', length);
if (typeof length === 'number') {
req.setHeader('Content-Length', length);
}
formData.pipe(getProgressMonitor()).pipe(req);
});
} else if (Buffer.isBuffer(data)) {
bufferToChunks(data).pipe(getProgressMonitor()).pipe(req);
} else {
req.end(data);
}
} catch (err) {
this._failRequest(err);
}
};
// Check whether response has a non-0-sized gzip-encoded body
Request.prototype._shouldDecompress = res => {
return hasNonEmptyResponseContent(res) && (isGzipOrDeflateEncoding(res) || isBrotliEncoding(res));
};
/**
* Overrides DNS for selected hostnames. Takes object mapping hostnames to IP addresses.
*
* When making a request to a URL with a hostname exactly matching a key in the object,
* use the given IP address to connect, instead of using DNS to resolve the hostname.
*
* A special host `*` matches every hostname (keep redirects in mind!)
*
* request.connect({
* 'test.example.com': '127.0.0.1',
* 'ipv6.example.com': '::1',
* })
*/
Request.prototype.connect = function (connectOverride) {
if (typeof connectOverride === 'string') {
this._connectOverride = {
'*': connectOverride
};
} else if (typeof connectOverride === 'object') {
this._connectOverride = connectOverride;
} else {
this._connectOverride = undefined;
}
return this;
};
Request.prototype.trustLocalhost = function (toggle) {
this._trustLocalhost = toggle === undefined ? true : toggle;
return this;
};
// generate HTTP verb methods
if (!methods.includes('del')) {
// create a copy so we don't cause conflicts with
// other packages using the methods package and
// npm 3.x
methods = [...methods];
methods.push('del');
}
for (let method of methods) {
const name = method;
method = method === 'del' ? 'delete' : method;
method = method.toUpperCase();
request[name] = (url, data, fn) => {
const request_ = request(method, url);
if (typeof data === 'function') {
fn = data;
data = null;
}
if (data) {
if (method === 'GET' || method === 'HEAD') {
request_.query(data);
} else {
request_.send(data);
}
}
if (fn) request_.end(fn);
return request_;
};
}
/**
* Check if `mime` is text and should be buffered.
*
* @param {String} mime
* @return {Boolean}
* @api public
*/
function isText(mime) {
const parts = mime.split('/');
let type = parts[0];
if (type) type = type.toLowerCase().trim();
let subtype = parts[1];
if (subtype) subtype = subtype.toLowerCase().trim();
return type === 'text' || subtype === 'x-www-form-urlencoded';
}
// This is not a catchall, but a start. It might be useful
// in the long run to have file that includes all binary
// content types from https://www.iana.org/assignments/media-types/media-types.xhtml
function isBinary(mime) {
let [registry, name] = mime.split('/');
if (registry) registry = registry.toLowerCase().trim();
if (name) name = name.toLowerCase().trim();
return ['audio', 'font', 'image', 'video'].includes(registry) || ['gz', 'gzip'].includes(name);
}
/**
* Check if `mime` is json or has +json structured syntax suffix.
*
* @param {String} mime
* @return {Boolean}
* @api private
*/
function isJSON(mime) {
// should match /json or +json
// but not /json-seq
return /[/+]json($|[^-\w])/i.test(mime);
}
/**
* Check if we should follow the redirect `code`.
*
* @param {Number} code
* @return {Boolean}
* @api private
*/
function isRedirect(code) {
return [301, 302, 303, 305, 307, 308].includes(code);
}
function hasNonEmptyResponseContent(res) {
if (res.statusCode === 204 || res.statusCode === 304) {
// These aren't supposed to have any body
return false;
}
// header content is a string, and distinction between 0 and no information is crucial
if (res.headers['content-length'] === '0') {
// We know that the body is empty (unfortunately, this check does not cover chunked encoding)
return false;
}
return true;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmb3JtYXQiLCJyZXF1aXJlIiwiU3RyZWFtIiwiaHR0cHMiLCJodHRwIiwiZnMiLCJ6bGliIiwidXRpbCIsInFzIiwibWltZSIsIm1ldGhvZHMiLCJGb3JtRGF0YSIsImZvcm1pZGFibGUiLCJkZWJ1ZyIsIkNvb2tpZUphciIsInNhZmVTdHJpbmdpZnkiLCJ1dGlscyIsIlJlcXVlc3RCYXNlIiwiaHR0cDIiLCJkZWNvbXByZXNzIiwiUmVzcG9uc2UiLCJtaXhpbiIsImhhc093biIsImlzQnJvdGxpRW5jb2RpbmciLCJpc0d6aXBPckRlZmxhdGVFbmNvZGluZyIsImNob29zZURlY29tcHJlc3NlciIsInJlcXVlc3QiLCJtZXRob2QiLCJ1cmwiLCJleHBvcnRzIiwiUmVxdWVzdCIsImVuZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsIm1vZHVsZSIsImFnZW50Iiwibm9vcCIsImRpc3Bvc2VOb2RlUmVxdWVzdCIsInJlcXVlc3RfIiwicmVxIiwiX3JlcXVlc3REaXNwb3NlZCIsInNlc3Npb24iLCJkZXN0cm95Iiwic29ja2V0IiwiYWJvcnQiLCJlcnIiLCJwcmVzZXJ2ZURvdFNlZ21lbnRzIiwidXJsU3RyaW5nIiwicGFydHMiLCJtYXRjaCIsInJlc3RvcmVQYXRoIiwicGF0aCIsInNlZ21lbnRzIiwicHJlZml4IiwicmVwbGFjZSIsIl8iLCJzZWdtZW50IiwibWFya2VyIiwicHVzaCIsInJlcXVlc3RQYXRoIiwicmVzdG9yZWRQYXRoIiwiaW5kZXgiLCJlbnRyaWVzIiwiZGVmaW5lIiwicHJvdG9jb2xzIiwic2VyaWFsaXplIiwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIiwib2JqZWN0Iiwic3RyaW5naWZ5IiwiaW5kaWNlcyIsInN0cmljdE51bGxIYW5kbGluZyIsInBhcnNlIiwiYnVmZmVyIiwiX2luaXRIZWFkZXJzIiwiX2hlYWRlciIsImhlYWRlciIsImNhbGwiLCJfZW5hYmxlSHR0cDIiLCJCb29sZWFuIiwicHJvY2VzcyIsImVudiIsIkhUVFAyX1RFU1QiLCJfYWdlbnQiLCJfZm9ybURhdGEiLCJ3cml0YWJsZSIsIl9yZWRpcmVjdHMiLCJyZWRpcmVjdHMiLCJjb29raWVzIiwiX3F1ZXJ5IiwicXNSYXciLCJfcmVkaXJlY3RMaXN0IiwiX3N0cmVhbVJlcXVlc3QiLCJfbG9va3VwIiwidW5kZWZpbmVkIiwib25jZSIsImNsZWFyVGltZW91dCIsImJpbmQiLCJpbmhlcml0cyIsInByb3RvdHlwZSIsImJvb2wiLCJFcnJvciIsImF0dGFjaCIsImZpZWxkIiwiZmlsZSIsIm9wdGlvbnMiLCJfZGF0YSIsIm8iLCJmaWxlbmFtZSIsImNyZWF0ZVJlYWRTdHJlYW0iLCJvbiIsImVycm9yIiwiZm9ybURhdGEiLCJfZ2V0Rm9ybURhdGEiLCJlbWl0IiwiYXBwZW5kIiwiY2FsbGVkIiwiY2FsbGJhY2siLCJhZGRSZXF1ZXN0IiwiVHlwZUVycm9yIiwibG9va3VwIiwidHlwZSIsInNldCIsImluY2x1ZGVzIiwiZ2V0VHlwZSIsImFjY2VwdCIsInF1ZXJ5IiwidmFsdWUiLCJPYmplY3QiLCJhc3NpZ24iLCJ3cml0ZSIsImRhdGEiLCJlbmNvZGluZyIsInBpcGUiLCJzdHJlYW0iLCJwaXBlZCIsIl9waXBlQ29udGludWUiLCJyZXMiLCJpc1JlZGlyZWN0Iiwic3RhdHVzQ29kZSIsIl9tYXhSZWRpcmVjdHMiLCJfcmVkaXJlY3QiLCJfZW1pdFJlc3BvbnNlIiwiX2Fib3J0ZWQiLCJfc2hvdWxkRGVjb21wcmVzcyIsImRlY29tcHJlc3NlciIsImNvZGUiLCJfYnVmZmVyIiwiaGVhZGVycyIsImxvY2F0aW9uIiwiVVJMIiwiaHJlZiIsInJlc3VtZSIsIl9lbWl0UHJlUmVkaXJlY3QiLCJnZXRIZWFkZXJzIiwiX2hlYWRlcnMiLCJjaGFuZ2VzT3JpZ2luIiwib3JpZ2luIiwiY2xlYW5IZWFkZXIiLCJhdXRob3JpemF0aW9uIiwiY29va2llIiwiaG9zdCIsIl9lbmRDYWxsZWQiLCJfZW1pdFJlZGlyZWN0IiwiX2NhbGxiYWNrIiwiYXV0aCIsInVzZXIiLCJwYXNzIiwiZW5jb2RlciIsInN0cmluZyIsIkJ1ZmZlciIsImZyb20iLCJ0b1N0cmluZyIsIl9hdXRoIiwiY2EiLCJjZXJ0IiwiX2NhIiwia2V5IiwiX2tleSIsInBmeCIsImlzQnVmZmVyIiwiX3BmeCIsIl9wYXNzcGhyYXNlIiwicGFzc3BocmFzZSIsIl9jZXJ0IiwiZGlzYWJsZVRMU0NlcnRzIiwiX2Rpc2FibGVUTFNDZXJ0cyIsIl9maW5hbGl6ZVF1ZXJ5U3RyaW5nIiwicmV0cmllcyIsIl9yZXRyaWVzIiwiaW5kZXhPZiIsInByb3RlY3RlZFVybCIsInByb3RvY29sIiwicGF0aG5hbWUiLCJzZWFyY2giLCJ0ZXN0Iiwic3BsaXQiLCJob3N0bmFtZSIsInNvY2tldFBhdGgiLCJfY29ubmVjdE92ZXJyaWRlIiwibmV3SG9zdCIsIm5ld1BvcnQiLCJwb3J0Iiwibm9ybWFsaXplSG9zdG5hbWUiLCJyZWplY3RVbmF1dGhvcml6ZWQiLCJOT0RFX1RMU19SRUpFQ1RfVU5BVVRIT1JJWkVEIiwic2VydmVybmFtZSIsIl90cnVzdExvY2FsaG9zdCIsIm1vZHVsZV8iLCJzZXRQcm90b2NvbCIsInJlc3BvbnNlIiwic2V0Tm9EZWxheSIsInNldEhlYWRlciIsImVtaXREcmFpbiIsInJlbW92ZUxpc3RlbmVyIiwidXNlcm5hbWUiLCJwYXNzd29yZCIsInRlbXBvcmFyeUphciIsInNldENvb2tpZXMiLCJnZXRDb29raWVzIiwiQ29va2llQWNjZXNzSW5mbyIsIkFsbCIsInRvVmFsdWVTdHJpbmciLCJfZGlzcG9zZVJlcXVlc3QiLCJfZmFpbFJlcXVlc3QiLCJfc2hvdWxkUmV0cnkiLCJfcmV0cnkiLCJmbiIsInRpbWVkb3V0IiwiY29uc29sZSIsIndhcm4iLCJfaXNSZXNwb25zZU9LIiwibWVzc2FnZSIsIlNUQVRVU19DT0RFUyIsInN0YXR1cyIsIl9tYXhSZXRyaWVzIiwibGlzdGVuZXJzIiwiX2lzSG9zdCIsImJvZHkiLCJmaWxlcyIsIl9lbmQiLCJfc2V0VGltZW91dHMiLCJfaGVhZGVyU2VudCIsImNvbnRlbnRUeXBlIiwiZ2V0SGVhZGVyIiwiX3NlcmlhbGl6ZXIiLCJpc0pTT04iLCJieXRlTGVuZ3RoIiwiX3Jlc3BvbnNlVGltZW91dFRpbWVyIiwibWF4IiwidG9Mb3dlckNhc2UiLCJ0cmltIiwibXVsdGlwYXJ0IiwicmVkaXJlY3QiLCJyZXNwb25zZVR5cGUiLCJfcmVzcG9uc2VUeXBlIiwicGFyc2VyIiwiX3BhcnNlciIsImltYWdlIiwiZm9ybSIsImJyaWRnZVN0cmVhbSIsIlBhc3NUaHJvdWdoIiwiaHR0cFZlcnNpb24iLCJyZWFkYWJsZSIsImZpZWxkcyIsImZsYXR0ZW5lZEZpZWxkcyIsImhhc093blByb3BlcnR5IiwiQXJyYXkiLCJpc0FycmF5IiwiZmxhdHRlbmVkRmlsZXMiLCJpc0JpbmFyeSIsInRleHQiLCJpc1RleHQiLCJfcmVzQnVmZmVyZWQiLCJwYXJzZXJIYW5kbGVzRW5kIiwicmVzcG9uc2VCeXRlc0xlZnQiLCJfbWF4UmVzcG9uc2VTaXplIiwiYnVmIiwiY29tcGxldGVBYm9ydGVkUmVzcG9uc2UiLCJnZXRQcm9ncmVzc01vbml0b3IiLCJsZW5ndGhDb21wdXRhYmxlIiwidG90YWwiLCJsb2FkZWQiLCJwcm9ncmVzcyIsIlRyYW5zZm9ybSIsIl90cmFuc2Zvcm0iLCJjaHVuayIsImRpcmVjdGlvbiIsImJ1ZmZlclRvQ2h1bmtzIiwiY2h1bmtTaXplIiwiY2h1bmtpbmciLCJSZWFkYWJsZSIsInRvdGFsTGVuZ3RoIiwicmVtYWluZGVyIiwiY3V0b2ZmIiwiaSIsInNsaWNlIiwicmVtYWluZGVyQnVmZmVyIiwiZ2V0TGVuZ3RoIiwiaGFzTm9uRW1wdHlSZXNwb25zZUNvbnRlbnQiLCJjb25uZWN0IiwiY29ubmVjdE92ZXJyaWRlIiwidHJ1c3RMb2NhbGhvc3QiLCJ0b2dnbGUiLCJuYW1lIiwidG9VcHBlckNhc2UiLCJzZW5kIiwic3VidHlwZSIsInJlZ2lzdHJ5Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL25vZGUvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbmNvbnN0IHsgZm9ybWF0IH0gPSByZXF1aXJlKCdub2RlOnVybCcpO1xuY29uc3QgU3RyZWFtID0gcmVxdWlyZSgnbm9kZTpzdHJlYW0nKTtcbmNvbnN0IGh0dHBzID0gcmVxdWlyZSgnbm9kZTpodHRwcycpO1xuY29uc3QgaHR0cCA9IHJlcXVpcmUoJ25vZGU6aHR0cCcpO1xuY29uc3QgZnMgPSByZXF1aXJlKCdub2RlOmZzJyk7XG5jb25zdCB6bGliID0gcmVxdWlyZSgnbm9kZTp6bGliJyk7XG5jb25zdCB1dGlsID0gcmVxdWlyZSgnbm9kZTp1dGlsJyk7XG5jb25zdCBxcyA9IHJlcXVpcmUoJ3FzJyk7XG5jb25zdCBtaW1lID0gcmVxdWlyZSgnbWltZScpO1xubGV0IG1ldGhvZHMgPSByZXF1aXJlKCdtZXRob2RzJyk7XG5jb25zdCBGb3JtRGF0YSA9IHJlcXVpcmUoJ2Zvcm0tZGF0YScpO1xuY29uc3QgZm9ybWlkYWJsZSA9IHJlcXVpcmUoJ2Zvcm1pZGFibGUnKTtcbmNvbnN0IGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnc3VwZXJhZ2VudCcpO1xuY29uc3QgQ29va2llSmFyID0gcmVxdWlyZSgnY29va2llamFyJyk7XG5jb25zdCBzYWZlU3RyaW5naWZ5ID0gcmVxdWlyZSgnZmFzdC1zYWZlLXN0cmluZ2lmeScpO1xuXG5jb25zdCB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5jb25zdCBSZXF1ZXN0QmFzZSA9IHJlcXVpcmUoJy4uL3JlcXVlc3QtYmFzZScpO1xuY29uc3QgaHR0cDIgPSByZXF1aXJlKCcuL2h0dHAyd3JhcHBlcicpO1xuY29uc3QgeyBkZWNvbXByZXNzIH0gPSByZXF1aXJlKCcuL3VuemlwJyk7XG5jb25zdCBSZXNwb25zZSA9IHJlcXVpcmUoJy4vcmVzcG9uc2UnKTtcblxuY29uc3QgeyBtaXhpbiwgaGFzT3duLCBpc0Jyb3RsaUVuY29kaW5nLCBpc0d6aXBPckRlZmxhdGVFbmNvZGluZyB9ID0gdXRpbHM7XG5jb25zdCB7IGNob29zZURlY29tcHJlc3NlciB9ID0gcmVxdWlyZSgnLi9kZWNvbXByZXNzJyk7XG5cbmZ1bmN0aW9uIHJlcXVlc3QobWV0aG9kLCB1cmwpIHtcbiAgLy8gY2FsbGJhY2tcbiAgaWYgKHR5cGVvZiB1cmwgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gbmV3IGV4cG9ydHMuUmVxdWVzdCgnR0VUJywgbWV0aG9kKS5lbmQodXJsKTtcbiAgfVxuXG4gIC8vIHVybCBmaXJzdFxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiBuZXcgZXhwb3J0cy5SZXF1ZXN0KCdHRVQnLCBtZXRob2QpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBleHBvcnRzLlJlcXVlc3QobWV0aG9kLCB1cmwpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVlc3Q7XG5leHBvcnRzID0gbW9kdWxlLmV4cG9ydHM7XG5cbi8qKlxuICogRXhwb3NlIGBSZXF1ZXN0YC5cbiAqL1xuXG5leHBvcnRzLlJlcXVlc3QgPSBSZXF1ZXN0O1xuXG4vKipcbiAqIEV4cG9zZSB0aGUgYWdlbnQgZnVuY3Rpb25cbiAqL1xuXG5leHBvcnRzLmFnZW50ID0gcmVxdWlyZSgnLi9hZ2VudCcpO1xuXG4vKipcbiAqIE5vb3AuXG4gKi9cblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbi8qKlxuICogQ2xvc2UgYW4gdW5kZXJseWluZyBOb2RlIHJlcXVlc3Qvc2Vzc2lvbiBjcmVhdGVkIGR1cmluZyBzZXR1cC5cbiAqXG4gKiBVc2VkIHdoZW4gaGVhZGVyIGFwcGxpY2F0aW9uIG9yIGxhdGVyIHJlcXVlc3QtcGF0aCB3b3JrIHRocm93cyBhZnRlclxuICogYGh0dHAucmVxdWVzdCgpYCAvIGBodHRwMi5jb25uZWN0KClgIGhhcyBhbHJlYWR5IGFsbG9jYXRlZCBhIHNvY2tldC5cbiAqXG4gKiBAcGFyYW0ge1JlcXVlc3R9IHJlcXVlc3RfXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGlzcG9zZU5vZGVSZXF1ZXN0KHJlcXVlc3RfKSB7XG4gIGNvbnN0IHsgcmVxIH0gPSByZXF1ZXN0XztcbiAgaWYgKCFyZXEgfHwgcmVxdWVzdF8uX3JlcXVlc3REaXNwb3NlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJlcXVlc3RfLl9yZXF1ZXN0RGlzcG9zZWQgPSB0cnVlO1xuXG4gIHRyeSB7XG4gICAgLy8gSFRUUC8yIHdyYXBwZXIga2VlcHMgYSBzZXNzaW9uIG9wZW4gYXMgc29vbiBhcyByZXF1ZXN0KCkgaXMgY2FsbGVkLlxuICAgIC8vIFByZWZlciBkZXN0cm95aW5nIHRoYXQgc2Vzc2lvbiBzbyB3ZSBuZXZlciBjYWxsIGFib3J0KCkg4oaSIGdldEZyYW1lKClcbiAgICAvLyB3aXRoIGludmFsaWQgaGVhZGVycyAod2hpY2ggd291bGQgZW1pdCBhIGxhdGUgcHJvdG9jb2wgZXJyb3IpLlxuICAgIGlmIChyZXEuc2Vzc2lvbiAmJiB0eXBlb2YgcmVxLnNlc3Npb24uZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmVxLnNlc3Npb24uZGVzdHJveSgpO1xuICAgIH1cblxuICAgIGlmIChyZXEuc29ja2V0ICYmIHR5cGVvZiByZXEuc29ja2V0LmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJlcS5zb2NrZXQuZGVzdHJveSgpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcmVxLmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJlcS5kZXN0cm95KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiByZXEuYWJvcnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJlcS5hYm9ydCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcmVxLmVuZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmVxLmVuZCgpO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZGVidWcoJ2Vycm9yIGRpc3Bvc2luZyByZXF1ZXN0IGFmdGVyIHNldHVwIGZhaWx1cmUnLCBlcnIpO1xuICB9XG59XG5cbi8qKlxuICogUHJlc2VydmUgZG90LW9ubHkgcGF0aCBzZWdtZW50cyB0aGF0IFdIQVRXRyBVUkwgbm9ybWFsaXplcyBhd2F5LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxTdHJpbmdcbiAqIEByZXR1cm5zIHt7dXJsU3RyaW5nOiBTdHJpbmcsIHJlc3RvcmVQYXRoOiBGdW5jdGlvbn19XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcHJlc2VydmVEb3RTZWdtZW50cyh1cmxTdHJpbmcpIHtcbiAgY29uc3QgcGFydHMgPSB1cmxTdHJpbmcubWF0Y2goXG4gICAgL14oW2Etel1bYS16XFxkKy4tXSo6XFwvXFwvW14vPyNdKikoW14/I10qKSguKikkL2lcbiAgKTtcbiAgaWYgKCFwYXJ0cykge1xuICAgIHJldHVybiB7XG4gICAgICB1cmxTdHJpbmcsXG4gICAgICByZXN0b3JlUGF0aChwYXRoKSB7XG4gICAgICAgIHJldHVybiBwYXRoO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBjb25zdCBzZWdtZW50cyA9IFtdO1xuICBjb25zdCBwcmVmaXggPSAnX19zdXBlcmFnZW50X2RvdF9zZWdtZW50Xyc7XG4gIGNvbnN0IHBhdGggPSBwYXJ0c1syXS5yZXBsYWNlKFxuICAgIC9cXC8oKD86XFwufCUyZSl7MSwyfSkoPz1cXC98JCkvZ2ksXG4gICAgKF8sIHNlZ21lbnQpID0+IHtcbiAgICAgIGNvbnN0IG1hcmtlciA9IGAke3ByZWZpeH0ke3NlZ21lbnRzLmxlbmd0aH1fX2A7XG4gICAgICBzZWdtZW50cy5wdXNoKHNlZ21lbnQpO1xuICAgICAgcmV0dXJuIGAvJHttYXJrZXJ9YDtcbiAgICB9XG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICB1cmxTdHJpbmc6IGAke3BhcnRzWzFdfSR7cGF0aH0ke3BhcnRzWzNdfWAsXG4gICAgcmVzdG9yZVBhdGgocmVxdWVzdFBhdGgpIHtcbiAgICAgIGxldCByZXN0b3JlZFBhdGggPSByZXF1ZXN0UGF0aDtcbiAgICAgIGZvciAoY29uc3QgW2luZGV4LCBzZWdtZW50XSBvZiBzZWdtZW50cy5lbnRyaWVzKCkpIHtcbiAgICAgICAgcmVzdG9yZWRQYXRoID0gcmVzdG9yZWRQYXRoLnJlcGxhY2UoYCR7cHJlZml4fSR7aW5kZXh9X19gLCBzZWdtZW50KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3RvcmVkUGF0aDtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogRXhwb3NlIGBSZXNwb25zZWAuXG4gKi9cblxuZXhwb3J0cy5SZXNwb25zZSA9IFJlc3BvbnNlO1xuXG4vKipcbiAqIERlZmluZSBcImZvcm1cIiBtaW1lIHR5cGUuXG4gKi9cblxubWltZS5kZWZpbmUoXG4gIHtcbiAgICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogWydmb3JtJywgJ3VybGVuY29kZWQnLCAnZm9ybS1kYXRhJ11cbiAgfSxcbiAgdHJ1ZVxuKTtcblxuLyoqXG4gKiBQcm90b2NvbCBtYXAuXG4gKi9cblxuZXhwb3J0cy5wcm90b2NvbHMgPSB7XG4gICdodHRwOic6IGh0dHAsXG4gICdodHRwczonOiBodHRwcyxcbiAgJ2h0dHAyOic6IGh0dHAyXG59O1xuXG4vKipcbiAqIERlZmF1bHQgc2VyaWFsaXphdGlvbiBtYXAuXG4gKlxuICogICAgIHN1cGVyYWdlbnQuc2VyaWFsaXplWydhcHBsaWNhdGlvbi94bWwnXSA9IGZ1bmN0aW9uKG9iail7XG4gKiAgICAgICByZXR1cm4gJ2dlbmVyYXRlZCB4bWwgaGVyZSc7XG4gKiAgICAgfTtcbiAqXG4gKi9cblxuZXhwb3J0cy5zZXJpYWxpemUgPSB7XG4gICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKG9iamVjdCkge1xuICAgIHJldHVybiBxcy5zdHJpbmdpZnkob2JqZWN0LCB7IGluZGljZXM6IGZhbHNlLCBzdHJpY3ROdWxsSGFuZGxpbmc6IHRydWUgfSk7XG4gIH0sXG4gICdhcHBsaWNhdGlvbi9qc29uJzogc2FmZVN0cmluZ2lmeSxcbiAgLy8gQ1NQIHJlcG9ydHMgY2FycnkgSlNPTiBib2RpZXMgYnV0IHVzZSBhIGRpc3RpbmN0IHJlZ2lzdGVyZWQgbWVkaWEgdHlwZS5cbiAgJ2FwcGxpY2F0aW9uL2NzcC1yZXBvcnQnOiBzYWZlU3RyaW5naWZ5XG59O1xuXG4vKipcbiAqIERlZmF1bHQgcGFyc2Vycy5cbiAqXG4gKiAgICAgc3VwZXJhZ2VudC5wYXJzZVsnYXBwbGljYXRpb24veG1sJ10gPSBmdW5jdGlvbihyZXMsIGZuKXtcbiAqICAgICAgIGZuKG51bGwsIHJlcyk7XG4gKiAgICAgfTtcbiAqXG4gKi9cblxuZXhwb3J0cy5wYXJzZSA9IHJlcXVpcmUoJy4vcGFyc2VycycpO1xuXG4vKipcbiAqIERlZmF1bHQgYnVmZmVyaW5nIG1hcC4gQ2FuIGJlIHVzZWQgdG8gc2V0IGNlcnRhaW5cbiAqIHJlc3BvbnNlIHR5cGVzIHRvIGJ1ZmZlci9ub3QgYnVmZmVyLlxuICpcbiAqICAgICBzdXBlcmFnZW50LmJ1ZmZlclsnYXBwbGljYXRpb24veG1sJ10gPSB0cnVlO1xuICovXG5leHBvcnRzLmJ1ZmZlciA9IHt9O1xuXG4vKipcbiAqIEluaXRpYWxpemUgaW50ZXJuYWwgaGVhZGVyIHRyYWNraW5nIHByb3BlcnRpZXMgb24gYSByZXF1ZXN0IGluc3RhbmNlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSByZXEgdGhlIGluc3RhbmNlXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gX2luaXRIZWFkZXJzKHJlcXVlc3RfKSB7XG4gIHJlcXVlc3RfLl9oZWFkZXIgPSB7XG4gICAgLy8gY29lcmNlcyBoZWFkZXIgbmFtZXMgdG8gbG93ZXJjYXNlXG4gIH07XG4gIHJlcXVlc3RfLmhlYWRlciA9IHtcbiAgICAvLyBwcmVzZXJ2ZXMgaGVhZGVyIG5hbWUgY2FzZVxuICB9O1xufVxuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYFJlcXVlc3RgIHdpdGggdGhlIGdpdmVuIGBtZXRob2RgIGFuZCBgdXJsYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IHVybFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0KG1ldGhvZCwgdXJsKSB7XG4gIFN0cmVhbS5jYWxsKHRoaXMpO1xuICBpZiAodHlwZW9mIHVybCAhPT0gJ3N0cmluZycpIHVybCA9IGZvcm1hdCh1cmwpO1xuICB0aGlzLl9lbmFibGVIdHRwMiA9IEJvb2xlYW4ocHJvY2Vzcy5lbnYuSFRUUDJfVEVTVCk7IC8vIGludGVybmFsIG9ubHlcbiAgdGhpcy5fYWdlbnQgPSBmYWxzZTtcbiAgdGhpcy5fZm9ybURhdGEgPSBudWxsO1xuICB0aGlzLm1ldGhvZCA9IG1ldGhvZDtcbiAgdGhpcy51cmwgPSB1cmw7XG4gIF9pbml0SGVhZGVycyh0aGlzKTtcbiAgdGhpcy53cml0YWJsZSA9IHRydWU7XG4gIHRoaXMuX3JlZGlyZWN0cyA9IDA7XG4gIHRoaXMucmVkaXJlY3RzKG1ldGhvZCA9PT0gJ0hFQUQnID8gMCA6IDUpO1xuICB0aGlzLmNvb2tpZXMgPSAnJztcbiAgdGhpcy5xcyA9IHt9O1xuICB0aGlzLl9xdWVyeSA9IFtdO1xuICB0aGlzLnFzUmF3ID0gdGhpcy5fcXVlcnk7IC8vIFVudXNlZCwgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IG9ubHlcbiAgdGhpcy5fcmVkaXJlY3RMaXN0ID0gW107XG4gIHRoaXMuX3N0cmVhbVJlcXVlc3QgPSBmYWxzZTtcbiAgdGhpcy5fbG9va3VwID0gdW5kZWZpbmVkO1xuICB0aGlzLm9uY2UoJ2VuZCcsIHRoaXMuY2xlYXJUaW1lb3V0LmJpbmQodGhpcykpO1xufVxuXG4vKipcbiAqIEluaGVyaXQgZnJvbSBgU3RyZWFtYCAod2hpY2ggaW5oZXJpdHMgZnJvbSBgRXZlbnRFbWl0dGVyYCkuXG4gKiBNaXhpbiBgUmVxdWVzdEJhc2VgLlxuICovXG51dGlsLmluaGVyaXRzKFJlcXVlc3QsIFN0cmVhbSk7XG5cbm1peGluKFJlcXVlc3QucHJvdG90eXBlLCBSZXF1ZXN0QmFzZS5wcm90b3R5cGUpO1xuXG4vKipcbiAqIEVuYWJsZSBvciBEaXNhYmxlIGh0dHAyLlxuICpcbiAqIEVuYWJsZSBodHRwMi5cbiAqXG4gKiBgYGAganNcbiAqIHJlcXVlc3QuZ2V0KCdodHRwOi8vbG9jYWxob3N0LycpXG4gKiAgIC5odHRwMigpXG4gKiAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIHJlcXVlc3QuZ2V0KCdodHRwOi8vbG9jYWxob3N0LycpXG4gKiAgIC5odHRwMih0cnVlKVxuICogICAuZW5kKGNhbGxiYWNrKTtcbiAqIGBgYFxuICpcbiAqIERpc2FibGUgaHR0cDIuXG4gKlxuICogYGBgIGpzXG4gKiByZXF1ZXN0ID0gcmVxdWVzdC5odHRwMigpO1xuICogcmVxdWVzdC5nZXQoJ2h0dHA6Ly9sb2NhbGhvc3QvJylcbiAqICAgLmh0dHAyKGZhbHNlKVxuICogICAuZW5kKGNhbGxiYWNrKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5hYmxlXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuaHR0cDIgPSBmdW5jdGlvbiAoYm9vbCkge1xuICBpZiAoZXhwb3J0cy5wcm90b2NvbHNbJ2h0dHAyOiddID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnc3VwZXJhZ2VudDogdGhpcyB2ZXJzaW9uIG9mIE5vZGUuanMgZG9lcyBub3Qgc3VwcG9ydCBodHRwMidcbiAgICApO1xuICB9XG5cbiAgdGhpcy5fZW5hYmxlSHR0cDIgPSBib29sID09PSB1bmRlZmluZWQgPyB0cnVlIDogYm9vbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFF1ZXVlIHRoZSBnaXZlbiBgZmlsZWAgYXMgYW4gYXR0YWNobWVudCB0byB0aGUgc3BlY2lmaWVkIGBmaWVsZGAsXG4gKiB3aXRoIG9wdGlvbmFsIGBvcHRpb25zYCAob3IgZmlsZW5hbWUpLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCdodHRwOi8vbG9jYWxob3N0L3VwbG9hZCcpXG4gKiAgIC5hdHRhY2goJ2ZpZWxkJywgQnVmZmVyLmZyb20oJzxiPkhlbGxvIHdvcmxkPC9iPicpLCAnaGVsbG8uaHRtbCcpXG4gKiAgIC5lbmQoY2FsbGJhY2spO1xuICogYGBgXG4gKlxuICogQSBmaWxlbmFtZSBtYXkgYWxzbyBiZSB1c2VkOlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCdodHRwOi8vbG9jYWxob3N0L3VwbG9hZCcpXG4gKiAgIC5hdHRhY2goJ2ZpbGVzJywgJ2ltYWdlLmpwZycpXG4gKiAgIC5lbmQoY2FsbGJhY2spO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKiBAcGFyYW0ge1N0cmluZ3xmcy5SZWFkU3RyZWFtfEJ1ZmZlcn0gZmlsZVxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYXR0YWNoID0gZnVuY3Rpb24gKGZpZWxkLCBmaWxlLCBvcHRpb25zKSB7XG4gIGlmIChmaWxlKSB7XG4gICAgaWYgKHRoaXMuX2RhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInN1cGVyYWdlbnQgY2FuJ3QgbWl4IC5zZW5kKCkgYW5kIC5hdHRhY2goKVwiKTtcbiAgICB9XG5cbiAgICBsZXQgbyA9IG9wdGlvbnMgfHwge307XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykge1xuICAgICAgbyA9IHsgZmlsZW5hbWU6IG9wdGlvbnMgfTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGZpbGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAoIW8uZmlsZW5hbWUpIG8uZmlsZW5hbWUgPSBmaWxlO1xuICAgICAgZGVidWcoJ2NyZWF0aW5nIGBmcy5SZWFkU3RyZWFtYCBpbnN0YW5jZSBmb3IgZmlsZTogJXMnLCBmaWxlKTtcbiAgICAgIGZpbGUgPSBmcy5jcmVhdGVSZWFkU3RyZWFtKGZpbGUpO1xuICAgICAgZmlsZS5vbignZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc3QgZm9ybURhdGEgPSB0aGlzLl9nZXRGb3JtRGF0YSgpO1xuICAgICAgICBmb3JtRGF0YS5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoIW8uZmlsZW5hbWUgJiYgZmlsZS5wYXRoKSB7XG4gICAgICBvLmZpbGVuYW1lID0gZmlsZS5wYXRoO1xuICAgIH1cblxuICAgIHRoaXMuX2dldEZvcm1EYXRhKCkuYXBwZW5kKGZpZWxkLCBmaWxlLCBvKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuUmVxdWVzdC5wcm90b3R5cGUuX2dldEZvcm1EYXRhID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuX2Zvcm1EYXRhKSB7XG4gICAgdGhpcy5fZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcbiAgICB0aGlzLl9mb3JtRGF0YS5vbignZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICAgIGRlYnVnKCdGb3JtRGF0YSBlcnJvcicsIGVycm9yKTtcbiAgICAgIGlmICh0aGlzLmNhbGxlZCkge1xuICAgICAgICAvLyBUaGUgcmVxdWVzdCBoYXMgYWxyZWFkeSBmaW5pc2hlZCBhbmQgdGhlIGNhbGxiYWNrIHdhcyBjYWxsZWQuXG4gICAgICAgIC8vIFNpbGVudGx5IGlnbm9yZSB0aGUgZXJyb3IuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jYWxsYmFjayhlcnJvcik7XG4gICAgICB0aGlzLmFib3J0KCk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fZm9ybURhdGE7XG59O1xuXG4vKipcbiAqIEdldHMvc2V0cyB0aGUgYEFnZW50YCB0byB1c2UgZm9yIHRoaXMgSFRUUCByZXF1ZXN0LiBUaGUgZGVmYXVsdCAoaWYgdGhpc1xuICogZnVuY3Rpb24gaXMgbm90IGNhbGxlZCkgaXMgdG8gb3B0IG91dCBvZiBjb25uZWN0aW9uIHBvb2xpbmcgKGBhZ2VudDogZmFsc2VgKS5cbiAqXG4gKiBAcGFyYW0ge2h0dHAuQWdlbnR9IGFnZW50XG4gKiBAcmV0dXJuIHtodHRwLkFnZW50fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hZ2VudCA9IGZ1bmN0aW9uIChhZ2VudCkge1xuICBpZiAoXG4gICAgYXJndW1lbnRzLmxlbmd0aCA+IDAgJiZcbiAgICBhZ2VudCAmJlxuICAgIHR5cGVvZiBhZ2VudCA9PT0gJ29iamVjdCcgJiZcbiAgICB0eXBlb2YgYWdlbnQuYWRkUmVxdWVzdCAhPT0gJ2Z1bmN0aW9uJ1xuICApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJy5hZ2VudCgpIGV4cGVjdHMgYW4gaHR0cChzKS5BZ2VudC1jb21wYXRpYmxlIG9iamVjdC4gRGlkIHlvdSBtZWFuIHRvIHVzZSAuY2VydCgpIGFuZCAua2V5KCk/J1xuICAgICk7XG4gIH1cblxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHRoaXMuX2FnZW50O1xuICB0aGlzLl9hZ2VudCA9IGFnZW50O1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogR2V0cy9zZXRzIHRoZSBgbG9va3VwYCBmdW5jdGlvbiB0byB1c2UgY3VzdG9tIEROUyByZXNvbHZlci5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBsb29rdXBcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5sb29rdXAgPSBmdW5jdGlvbiAobG9va3VwKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdGhpcy5fbG9va3VwO1xuICB0aGlzLl9sb29rdXAgPSBsb29rdXA7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgX0NvbnRlbnQtVHlwZV8gcmVzcG9uc2UgaGVhZGVyIHBhc3NlZCB0aHJvdWdoIGBtaW1lLmdldFR5cGUoKWAuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICByZXF1ZXN0LnBvc3QoJy8nKVxuICogICAgICAgIC50eXBlKCd4bWwnKVxuICogICAgICAgIC5zZW5kKHhtbHN0cmluZylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiAgICAgIHJlcXVlc3QucG9zdCgnLycpXG4gKiAgICAgICAgLnR5cGUoJ2pzb24nKVxuICogICAgICAgIC5zZW5kKGpzb25zdHJpbmcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogICAgICByZXF1ZXN0LnBvc3QoJy8nKVxuICogICAgICAgIC50eXBlKCdhcHBsaWNhdGlvbi9qc29uJylcbiAqICAgICAgICAuc2VuZChqc29uc3RyaW5nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUudHlwZSA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIHJldHVybiB0aGlzLnNldChcbiAgICAnQ29udGVudC1UeXBlJyxcbiAgICB0eXBlLmluY2x1ZGVzKCcvJykgPyB0eXBlIDogbWltZS5nZXRUeXBlKHR5cGUpXG4gICk7XG59O1xuXG4vKipcbiAqIFNldCBfQWNjZXB0XyByZXNwb25zZSBoZWFkZXIgcGFzc2VkIHRocm91Z2ggYG1pbWUuZ2V0VHlwZSgpYC5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHN1cGVyYWdlbnQudHlwZXMuanNvbiA9ICdhcHBsaWNhdGlvbi9qc29uJztcbiAqXG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvYWdlbnQnKVxuICogICAgICAgIC5hY2NlcHQoJ2pzb24nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqICAgICAgcmVxdWVzdC5nZXQoJy9hZ2VudCcpXG4gKiAgICAgICAgLmFjY2VwdCgnYXBwbGljYXRpb24vanNvbicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGFjY2VwdFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIHJldHVybiB0aGlzLnNldCgnQWNjZXB0JywgdHlwZS5pbmNsdWRlcygnLycpID8gdHlwZSA6IG1pbWUuZ2V0VHlwZSh0eXBlKSk7XG59O1xuXG4vKipcbiAqIEFkZCBxdWVyeS1zdHJpbmcgYHZhbGAuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICByZXF1ZXN0LmdldCgnL3Nob2VzJylcbiAqICAgICAucXVlcnkoJ3NpemU9MTAnKVxuICogICAgIC5xdWVyeSh7IGNvbG9yOiAnYmx1ZScgfSlcbiAqXG4gKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IHZhbFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnF1ZXJ5ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhpcy5fcXVlcnkucHVzaCh2YWx1ZSk7XG4gIH0gZWxzZSB7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLnFzLCB2YWx1ZSk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogV3JpdGUgcmF3IGBkYXRhYCAvIGBlbmNvZGluZ2AgdG8gdGhlIHNvY2tldC5cbiAqXG4gKiBAcGFyYW0ge0J1ZmZlcnxTdHJpbmd9IGRhdGFcbiAqIEBwYXJhbSB7U3RyaW5nfSBlbmNvZGluZ1xuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoZGF0YSwgZW5jb2RpbmcpIHtcbiAgY29uc3QgcmVxdWVzdF8gPSB0aGlzLnJlcXVlc3QoKTtcbiAgaWYgKCF0aGlzLl9zdHJlYW1SZXF1ZXN0KSB7XG4gICAgdGhpcy5fc3RyZWFtUmVxdWVzdCA9IHRydWU7XG4gIH1cblxuICByZXR1cm4gcmVxdWVzdF8ud3JpdGUoZGF0YSwgZW5jb2RpbmcpO1xufTtcblxuLyoqXG4gKiBQaXBlIHRoZSByZXF1ZXN0IGJvZHkgdG8gYHN0cmVhbWAuXG4gKlxuICogQHBhcmFtIHtTdHJlYW19IHN0cmVhbVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmVhbX1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uIChzdHJlYW0sIG9wdGlvbnMpIHtcbiAgdGhpcy5waXBlZCA9IHRydWU7IC8vIEhBQ0suLi5cbiAgdGhpcy5idWZmZXIoZmFsc2UpO1xuICB0aGlzLmVuZCgpO1xuICByZXR1cm4gdGhpcy5fcGlwZUNvbnRpbnVlKHN0cmVhbSwgb3B0aW9ucyk7XG59O1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5fcGlwZUNvbnRpbnVlID0gZnVuY3Rpb24gKHN0cmVhbSwgb3B0aW9ucykge1xuICB0aGlzLnJlcS5vbmNlKCdyZXNwb25zZScsIChyZXMpID0+IHtcbiAgICAvLyByZWRpcmVjdFxuICAgIGlmIChcbiAgICAgIGlzUmVkaXJlY3QocmVzLnN0YXR1c0NvZGUpICYmXG4gICAgICB0aGlzLl9yZWRpcmVjdHMrKyAhPT0gdGhpcy5fbWF4UmVkaXJlY3RzXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5fcmVkaXJlY3QocmVzKSA9PT0gdGhpc1xuICAgICAgICA/IHRoaXMuX3BpcGVDb250aW51ZShzdHJlYW0sIG9wdGlvbnMpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHRoaXMucmVzID0gcmVzO1xuICAgIHRoaXMuX2VtaXRSZXNwb25zZSgpO1xuICAgIGlmICh0aGlzLl9hYm9ydGVkKSByZXR1cm47XG5cbiAgICBpZiAodGhpcy5fc2hvdWxkRGVjb21wcmVzcyhyZXMpKSB7XG4gICAgICBjb25zdCBkZWNvbXByZXNzZXIgPSBjaG9vc2VEZWNvbXByZXNzZXIocmVzKTtcblxuICAgICAgZGVjb21wcmVzc2VyLm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgJiYgZXJyb3IuY29kZSA9PT0gJ1pfQlVGX0VSUk9SJykge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgZW5kIG9mIGZpbGUgaXMgaWdub3JlZCBieSBicm93c2VycyBhbmQgY3VybFxuICAgICAgICAgIHN0cmVhbS5lbWl0KCdlbmQnKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcnJvcik7XG4gICAgICB9KTtcbiAgICAgIHJlcy5waXBlKGRlY29tcHJlc3NlcikucGlwZShzdHJlYW0sIG9wdGlvbnMpO1xuICAgICAgLy8gZG9uJ3QgZW1pdCAnZW5kJyB1bnRpbCBkZWNvbXByZXNzZXIgaGFzIGNvbXBsZXRlZCB3cml0aW5nIGFsbCBpdHMgZGF0YS5cbiAgICAgIGRlY29tcHJlc3Nlci5vbmNlKCdlbmQnLCAoKSA9PiB0aGlzLmVtaXQoJ2VuZCcpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzLnBpcGUoc3RyZWFtLCBvcHRpb25zKTtcbiAgICAgIHJlcy5vbmNlKCdlbmQnLCAoKSA9PiB0aGlzLmVtaXQoJ2VuZCcpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gc3RyZWFtO1xufTtcblxuLyoqXG4gKiBFbmFibGUgLyBkaXNhYmxlIGJ1ZmZlcmluZy5cbiAqXG4gKiBAcmV0dXJuIHtCb29sZWFufSBbdmFsXVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmJ1ZmZlciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB0aGlzLl9idWZmZXIgPSB2YWx1ZSAhPT0gZmFsc2U7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZWRpcmVjdCB0byBgdXJsXG4gKlxuICogQHBhcmFtIHtJbmNvbWluZ01lc3NhZ2V9IHJlc1xuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5fcmVkaXJlY3QgPSBmdW5jdGlvbiAocmVzKSB7XG4gIGxldCB1cmwgPSByZXMuaGVhZGVycy5sb2NhdGlvbjtcbiAgaWYgKCF1cmwpIHtcbiAgICByZXR1cm4gdGhpcy5jYWxsYmFjayhuZXcgRXJyb3IoJ05vIGxvY2F0aW9uIGhlYWRlciBmb3IgcmVkaXJlY3QnKSwgcmVzKTtcbiAgfVxuXG4gIGRlYnVnKCdyZWRpcmVjdCAlcyAtPiAlcycsIHRoaXMudXJsLCB1cmwpO1xuXG4gIC8vIGxvY2F0aW9uXG4gIHVybCA9IG5ldyBVUkwodXJsLCB0aGlzLnVybCkuaHJlZjtcblxuICAvLyBlbnN1cmUgdGhlIHJlc3BvbnNlIGlzIGJlaW5nIGNvbnN1bWVkXG4gIC8vIHRoaXMgaXMgcmVxdWlyZWQgZm9yIE5vZGUgdjAuMTArXG4gIHJlcy5yZXN1bWUoKTtcblxuICB0aGlzLl9lbWl0UHJlUmVkaXJlY3QocmVzKTtcblxuICBsZXQgaGVhZGVycyA9IHRoaXMucmVxLmdldEhlYWRlcnMgPyB0aGlzLnJlcS5nZXRIZWFkZXJzKCkgOiB0aGlzLnJlcS5faGVhZGVycztcblxuICBjb25zdCBjaGFuZ2VzT3JpZ2luID0gbmV3IFVSTCh1cmwpLm9yaWdpbiAhPT0gbmV3IFVSTCh0aGlzLnVybCkub3JpZ2luO1xuXG4gIC8vIGltcGxlbWVudGF0aW9uIG9mIDMwMiBmb2xsb3dpbmcgZGVmYWN0byBzdGFuZGFyZFxuICBpZiAocmVzLnN0YXR1c0NvZGUgPT09IDMwMSB8fCByZXMuc3RhdHVzQ29kZSA9PT0gMzAyKSB7XG4gICAgLy8gc3RyaXAgQ29udGVudC0qIHJlbGF0ZWQgZmllbGRzXG4gICAgLy8gaW4gY2FzZSBvZiBQT1NUIGV0Y1xuICAgIGhlYWRlcnMgPSB1dGlscy5jbGVhbkhlYWRlcihoZWFkZXJzLCBjaGFuZ2VzT3JpZ2luKTtcblxuICAgIC8vIGZvcmNlIEdFVFxuICAgIHRoaXMubWV0aG9kID0gdGhpcy5tZXRob2QgPT09ICdIRUFEJyA/ICdIRUFEJyA6ICdHRVQnO1xuXG4gICAgLy8gY2xlYXIgZGF0YVxuICAgIHRoaXMuX2RhdGEgPSBudWxsO1xuICB9XG5cbiAgLy8gMzAzIGlzIGFsd2F5cyBHRVRcbiAgaWYgKHJlcy5zdGF0dXNDb2RlID09PSAzMDMpIHtcbiAgICAvLyBzdHJpcCBDb250ZW50LSogcmVsYXRlZCBmaWVsZHNcbiAgICAvLyBpbiBjYXNlIG9mIFBPU1QgZXRjXG4gICAgaGVhZGVycyA9IHV0aWxzLmNsZWFuSGVhZGVyKGhlYWRlcnMsIGNoYW5nZXNPcmlnaW4pO1xuXG4gICAgLy8gZm9yY2UgbWV0aG9kXG4gICAgdGhpcy5tZXRob2QgPSAnR0VUJztcblxuICAgIC8vIGNsZWFyIGRhdGFcbiAgICB0aGlzLl9kYXRhID0gbnVsbDtcbiAgfVxuXG4gIC8vIDMwNyBwcmVzZXJ2ZXMgbWV0aG9kXG4gIC8vIDMwOCBwcmVzZXJ2ZXMgbWV0aG9kXG4gIGlmICgocmVzLnN0YXR1c0NvZGUgPT09IDMwNyB8fCByZXMuc3RhdHVzQ29kZSA9PT0gMzA4KSAmJiBjaGFuZ2VzT3JpZ2luKSB7XG4gICAgZGVsZXRlIGhlYWRlcnMuYXV0aG9yaXphdGlvbjtcbiAgICBkZWxldGUgaGVhZGVycy5jb29raWU7XG4gIH1cblxuICBkZWxldGUgaGVhZGVycy5ob3N0O1xuXG4gIGRlbGV0ZSB0aGlzLnJlcTtcbiAgZGVsZXRlIHRoaXMuX2Zvcm1EYXRhO1xuXG4gIC8vIHJlbW92ZSBhbGwgYWRkIGhlYWRlciBleGNlcHQgVXNlci1BZ2VudFxuICBfaW5pdEhlYWRlcnModGhpcyk7XG5cbiAgLy8gcmVkaXJlY3RcbiAgdGhpcy5yZXMgPSByZXM7XG4gIHRoaXMuX2VuZENhbGxlZCA9IGZhbHNlO1xuICB0aGlzLnVybCA9IHVybDtcbiAgdGhpcy5xcyA9IHt9O1xuICB0aGlzLl9xdWVyeS5sZW5ndGggPSAwO1xuICB0aGlzLnNldChoZWFkZXJzKTtcbiAgdGhpcy5fZW1pdFJlZGlyZWN0KCk7XG4gIHRoaXMuX3JlZGlyZWN0TGlzdC5wdXNoKHRoaXMudXJsKTtcbiAgdGhpcy5lbmQodGhpcy5fY2FsbGJhY2spO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IEF1dGhvcml6YXRpb24gZmllbGQgdmFsdWUgd2l0aCBgdXNlcmAgYW5kIGBwYXNzYC5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgIC5hdXRoKCd0b2JpJywgJ2xlYXJuYm9vc3QnKVxuICogICAuYXV0aCgndG9iaTpsZWFybmJvb3N0JylcbiAqICAgLmF1dGgoJ3RvYmknKVxuICogICAuYXV0aChhY2Nlc3NUb2tlbiwgeyB0eXBlOiAnYmVhcmVyJyB9KVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1c2VyXG4gKiBAcGFyYW0ge1N0cmluZ30gW3Bhc3NdXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIG9wdGlvbnMgd2l0aCBhdXRob3JpemF0aW9uIHR5cGUgJ2Jhc2ljJyBvciAnYmVhcmVyJyAoJ2Jhc2ljJyBpcyBkZWZhdWx0KVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmF1dGggPSBmdW5jdGlvbiAodXNlciwgcGFzcywgb3B0aW9ucykge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkgcGFzcyA9ICcnO1xuICBpZiAodHlwZW9mIHBhc3MgPT09ICdvYmplY3QnICYmIHBhc3MgIT09IG51bGwpIHtcbiAgICAvLyBwYXNzIGlzIG9wdGlvbmFsIGFuZCBjYW4gYmUgcmVwbGFjZWQgd2l0aCBvcHRpb25zXG4gICAgb3B0aW9ucyA9IHBhc3M7XG4gICAgcGFzcyA9ICcnO1xuICB9XG5cbiAgaWYgKCFvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHsgdHlwZTogJ2Jhc2ljJyB9O1xuICB9XG5cbiAgY29uc3QgZW5jb2RlciA9IChzdHJpbmcpID0+IEJ1ZmZlci5mcm9tKHN0cmluZykudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuXG4gIHJldHVybiB0aGlzLl9hdXRoKHVzZXIsIHBhc3MsIG9wdGlvbnMsIGVuY29kZXIpO1xufTtcblxuLyoqXG4gKiBTZXQgdGhlIGNlcnRpZmljYXRlIGF1dGhvcml0eSBvcHRpb24gZm9yIGh0dHBzIHJlcXVlc3QuXG4gKlxuICogQHBhcmFtIHtCdWZmZXIgfCBBcnJheX0gY2VydFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNhID0gZnVuY3Rpb24gKGNlcnQpIHtcbiAgdGhpcy5fY2EgPSBjZXJ0O1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHRoZSBjbGllbnQgY2VydGlmaWNhdGUga2V5IG9wdGlvbiBmb3IgaHR0cHMgcmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0ge0J1ZmZlciB8IFN0cmluZ30gY2VydFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmtleSA9IGZ1bmN0aW9uIChjZXJ0KSB7XG4gIHRoaXMuX2tleSA9IGNlcnQ7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgdGhlIGtleSwgY2VydGlmaWNhdGUsIGFuZCBDQSBjZXJ0cyBvZiB0aGUgY2xpZW50IGluIFBGWCBvciBQS0NTMTIgZm9ybWF0LlxuICpcbiAqIEBwYXJhbSB7QnVmZmVyIHwgU3RyaW5nfSBjZXJ0XG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUucGZ4ID0gZnVuY3Rpb24gKGNlcnQpIHtcbiAgaWYgKHR5cGVvZiBjZXJ0ID09PSAnb2JqZWN0JyAmJiAhQnVmZmVyLmlzQnVmZmVyKGNlcnQpKSB7XG4gICAgdGhpcy5fcGZ4ID0gY2VydC5wZng7XG4gICAgdGhpcy5fcGFzc3BocmFzZSA9IGNlcnQucGFzc3BocmFzZTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9wZnggPSBjZXJ0O1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCB0aGUgY2xpZW50IGNlcnRpZmljYXRlIG9wdGlvbiBmb3IgaHR0cHMgcmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0ge0J1ZmZlciB8IFN0cmluZ30gY2VydFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNlcnQgPSBmdW5jdGlvbiAoY2VydCkge1xuICB0aGlzLl9jZXJ0ID0gY2VydDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIERvIG5vdCByZWplY3QgZXhwaXJlZCBvciBpbnZhbGlkIFRMUyBjZXJ0cy5cbiAqIHNldHMgYHJlamVjdFVuYXV0aG9yaXplZD10cnVlYC4gQmUgd2FybmVkIHRoYXQgdGhpcyBhbGxvd3MgTUlUTSBhdHRhY2tzLlxuICpcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5kaXNhYmxlVExTQ2VydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2Rpc2FibGVUTFNDZXJ0cyA9IHRydWU7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYW4gaHR0cFtzXSByZXF1ZXN0LlxuICpcbiAqIEByZXR1cm4ge091dGdvaW5nTWVzc2FnZX1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5XG5SZXF1ZXN0LnByb3RvdHlwZS5yZXF1ZXN0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5yZXEpIHJldHVybiB0aGlzLnJlcTtcblxuICBjb25zdCBvcHRpb25zID0ge307XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBxdWVyeSA9IHFzLnN0cmluZ2lmeSh0aGlzLnFzLCB7XG4gICAgICBpbmRpY2VzOiBmYWxzZSxcbiAgICAgIHN0cmljdE51bGxIYW5kbGluZzogdHJ1ZVxuICAgIH0pO1xuICAgIGlmIChxdWVyeSkge1xuICAgICAgdGhpcy5xcyA9IHt9O1xuICAgICAgdGhpcy5fcXVlcnkucHVzaChxdWVyeSk7XG4gICAgfVxuXG4gICAgdGhpcy5fZmluYWxpemVRdWVyeVN0cmluZygpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gIH1cblxuICBsZXQgeyB1cmw6IHVybFN0cmluZyB9ID0gdGhpcztcbiAgY29uc3QgcmV0cmllcyA9IHRoaXMuX3JldHJpZXM7XG5cbiAgLy8gZGVmYXVsdCB0byBodHRwOi8vXG4gIGlmICh1cmxTdHJpbmcuaW5kZXhPZignaHR0cCcpICE9PSAwKSB1cmxTdHJpbmcgPSBgaHR0cDovLyR7dXJsU3RyaW5nfWA7XG4gIGNvbnN0IHByb3RlY3RlZFVybCA9IHByZXNlcnZlRG90U2VnbWVudHModXJsU3RyaW5nKTtcbiAgY29uc3QgdXJsID0gbmV3IFVSTChwcm90ZWN0ZWRVcmwudXJsU3RyaW5nKTtcbiAgbGV0IHsgcHJvdG9jb2wgfSA9IHVybDtcbiAgY29uc3QgcGF0aCA9IHByb3RlY3RlZFVybC5yZXN0b3JlUGF0aChgJHt1cmwucGF0aG5hbWV9JHt1cmwuc2VhcmNofWApO1xuXG4gIC8vIHN1cHBvcnQgdW5peCBzb2NrZXRzXG4gIGlmICgvXmh0dHBzP1xcK3VuaXg6Ly50ZXN0KHByb3RvY29sKSA9PT0gdHJ1ZSkge1xuICAgIC8vIGdldCB0aGUgcHJvdG9jb2xcbiAgICBwcm90b2NvbCA9IGAke3Byb3RvY29sLnNwbGl0KCcrJylbMF19OmA7XG5cbiAgICBpZiAoIXVybC5ob3N0bmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnSW52YWxpZCB1bml4IHNvY2tldCBVUkw6IHBlcmNlbnQtZW5jb2RlIHRoZSBzb2NrZXQgcGF0aCBieSByZXBsYWNpbmcgXCIvXCIgd2l0aCBcIiUyRlwiLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gZ2V0IHRoZSBzb2NrZXQgcGF0aFxuICAgIG9wdGlvbnMuc29ja2V0UGF0aCA9IHVybC5ob3N0bmFtZS5yZXBsYWNlKC8lMkYvZywgJy8nKTtcbiAgICB1cmwuaG9zdCA9ICcnO1xuICAgIHVybC5ob3N0bmFtZSA9ICcnO1xuICB9XG5cbiAgLy8gT3ZlcnJpZGUgSVAgYWRkcmVzcyBvZiBhIGhvc3RuYW1lXG4gIGlmICh0aGlzLl9jb25uZWN0T3ZlcnJpZGUpIHtcbiAgICBjb25zdCB7IGhvc3RuYW1lIH0gPSB1cmw7XG4gICAgY29uc3QgbWF0Y2ggPVxuICAgICAgaG9zdG5hbWUgaW4gdGhpcy5fY29ubmVjdE92ZXJyaWRlXG4gICAgICAgID8gdGhpcy5fY29ubmVjdE92ZXJyaWRlW2hvc3RuYW1lXVxuICAgICAgICA6IHRoaXMuX2Nvbm5lY3RPdmVycmlkZVsnKiddO1xuICAgIGlmIChtYXRjaCkge1xuICAgICAgLy8gYmFja3VwIHRoZSByZWFsIGhvc3RcbiAgICAgIGlmICghdGhpcy5faGVhZGVyLmhvc3QpIHtcbiAgICAgICAgdGhpcy5zZXQoJ2hvc3QnLCB1cmwuaG9zdCk7XG4gICAgICB9XG5cbiAgICAgIGxldCBuZXdIb3N0O1xuICAgICAgbGV0IG5ld1BvcnQ7XG5cbiAgICAgIGlmICh0eXBlb2YgbWF0Y2ggPT09ICdvYmplY3QnKSB7XG4gICAgICAgIG5ld0hvc3QgPSBtYXRjaC5ob3N0O1xuICAgICAgICBuZXdQb3J0ID0gbWF0Y2gucG9ydDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld0hvc3QgPSBtYXRjaDtcbiAgICAgICAgbmV3UG9ydCA9IHVybC5wb3J0O1xuICAgICAgfVxuXG4gICAgICAvLyB3cmFwIFtpcHY2XVxuICAgICAgdXJsLmhvc3QgPSAvOi8udGVzdChuZXdIb3N0KSA/IGBbJHtuZXdIb3N0fV1gIDogbmV3SG9zdDtcbiAgICAgIGlmIChuZXdQb3J0KSB7XG4gICAgICAgIHVybC5ob3N0ICs9IGA6JHtuZXdQb3J0fWA7XG4gICAgICAgIHVybC5wb3J0ID0gbmV3UG9ydDtcbiAgICAgIH1cblxuICAgICAgdXJsLmhvc3RuYW1lID0gbmV3SG9zdDtcbiAgICB9XG4gIH1cblxuICAvLyBvcHRpb25zXG4gIG9wdGlvbnMubWV0aG9kID0gdGhpcy5tZXRob2Q7XG4gIG9wdGlvbnMucG9ydCA9IHVybC5wb3J0O1xuICBvcHRpb25zLnBhdGggPSBwYXRoO1xuICBvcHRpb25zLmhvc3QgPSB1dGlscy5ub3JtYWxpemVIb3N0bmFtZSh1cmwuaG9zdG5hbWUpOyAvLyBleDogWzo6MV0gLT4gOjoxXG4gIC8vIEFwcGx5IHVzZXIgaGVhZGVycyBiZWZvcmUgY29ubmVjdGluZyBzbyBpbnZhbGlkIHZhbHVlcyAoZS5nLiB1bmRlZmluZWQpXG4gIC8vIHRocm93IHdpdGhvdXQgYWxsb2NhdGluZyBhIFRDUCBoYW5kbGUuIFNlZSAjMTgyNy5cbiAgLy8gSFRUUC8yJ3Mgd3JhcHBlciBmb3J3YXJkcyBsZWZ0b3ZlciBvcHRpb25zIHRvIGh0dHAyLmNvbm5lY3QoKSwgc28gb25seVxuICAvLyBkbyB0aGlzIG9uIEhUVFAvMS5cbiAgaWYgKCF0aGlzLl9lbmFibGVIdHRwMikge1xuICAgIG9wdGlvbnMuaGVhZGVycyA9IHsgLi4udGhpcy5oZWFkZXIgfTtcbiAgfVxuXG4gIG9wdGlvbnMuY2EgPSB0aGlzLl9jYTtcbiAgb3B0aW9ucy5rZXkgPSB0aGlzLl9rZXk7XG4gIG9wdGlvbnMucGZ4ID0gdGhpcy5fcGZ4O1xuICBvcHRpb25zLmNlcnQgPSB0aGlzLl9jZXJ0O1xuICBvcHRpb25zLnBhc3NwaHJhc2UgPSB0aGlzLl9wYXNzcGhyYXNlO1xuICBvcHRpb25zLmFnZW50ID0gdGhpcy5fYWdlbnQ7XG4gIG9wdGlvbnMubG9va3VwID0gdGhpcy5fbG9va3VwO1xuICBvcHRpb25zLnJlamVjdFVuYXV0aG9yaXplZCA9XG4gICAgdHlwZW9mIHRoaXMuX2Rpc2FibGVUTFNDZXJ0cyA9PT0gJ2Jvb2xlYW4nXG4gICAgICA/ICF0aGlzLl9kaXNhYmxlVExTQ2VydHNcbiAgICAgIDogcHJvY2Vzcy5lbnYuTk9ERV9UTFNfUkVKRUNUX1VOQVVUSE9SSVpFRCAhPT0gJzAnO1xuXG4gIC8vIEFsbG93cyByZXF1ZXN0LmdldCgnaHR0cHM6Ly8xLjIuMy40LycpLnNldCgnSG9zdCcsICdleGFtcGxlLmNvbScpXG4gIGlmICh0aGlzLl9oZWFkZXIuaG9zdCkge1xuICAgIG9wdGlvbnMuc2VydmVybmFtZSA9IHRoaXMuX2hlYWRlci5ob3N0LnJlcGxhY2UoLzpcXGQrJC8sICcnKTtcbiAgfVxuXG4gIGlmIChcbiAgICB0aGlzLl90cnVzdExvY2FsaG9zdCAmJlxuICAgIC9eKD86bG9jYWxob3N0fDEyN1xcLjBcXC4wXFwuXFxkK3woMCo6KSs6MCoxKSQvLnRlc3QodXJsLmhvc3RuYW1lKVxuICApIHtcbiAgICBvcHRpb25zLnJlamVjdFVuYXV0aG9yaXplZCA9IGZhbHNlO1xuICB9XG5cbiAgLy8gaW5pdGlhdGUgcmVxdWVzdFxuICBjb25zdCBtb2R1bGVfID0gdGhpcy5fZW5hYmxlSHR0cDJcbiAgICA/IGV4cG9ydHMucHJvdG9jb2xzWydodHRwMjonXS5zZXRQcm90b2NvbChwcm90b2NvbClcbiAgICA6IGV4cG9ydHMucHJvdG9jb2xzW3Byb3RvY29sXTtcblxuICAvLyByZXF1ZXN0XG4gIHRoaXMucmVxID0gbW9kdWxlXy5yZXF1ZXN0KG9wdGlvbnMpO1xuICBjb25zdCB7IHJlcSB9ID0gdGhpcztcblxuICAvLyBBdHRhY2ggdGhpcyBiZWZvcmUgaGVhZGVyIHNldHVwIHNvIGRlc3Ryb3koKSBkdXJpbmcgYSBzZXR1cCBleGNlcHRpb25cbiAgLy8gY2Fubm90IGVtaXQgYW4gdW5oYW5kbGVkICdlcnJvcicgKG9yIGEgc2Vjb25kIGNhbGxiYWNrKS5cbiAgcmVxLm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgIC8vIGZsYWcgYWJvcnRpb24gaGVyZSBmb3Igb3V0IHRpbWVvdXRzXG4gICAgLy8gYmVjYXVzZSBub2RlIHdpbGwgZW1pdCBhIGZhdXgtZXJyb3IgXCJzb2NrZXQgaGFuZyB1cFwiXG4gICAgLy8gd2hlbiByZXF1ZXN0IGlzIGFib3J0ZWQgYmVmb3JlIGEgY29ubmVjdGlvbiBpcyBtYWRlXG4gICAgaWYgKHRoaXMuX2Fib3J0ZWQgfHwgdGhpcy5fcmVxdWVzdERpc3Bvc2VkKSByZXR1cm47XG4gICAgLy8gaWYgbm90IHRoZSBzYW1lLCB3ZSBhcmUgaW4gdGhlICoqb2xkKiogKGNhbmNlbGxlZCkgcmVxdWVzdCxcbiAgICAvLyBzbyBuZWVkIHRvIGNvbnRpbnVlIChzYW1lIGFzIGZvciBhYm92ZSlcbiAgICBpZiAodGhpcy5fcmV0cmllcyAhPT0gcmV0cmllcykgcmV0dXJuO1xuICAgIC8vIGlmIHdlJ3ZlIHJlY2VpdmVkIGEgcmVzcG9uc2UgdGhlbiB3ZSBkb24ndCB3YW50IHRvIGxldFxuICAgIC8vIGFuIGVycm9yIGluIHRoZSByZXF1ZXN0IGJsb3cgdXAgdGhlIHJlc3BvbnNlXG4gICAgaWYgKHRoaXMucmVzcG9uc2UpIHJldHVybjtcbiAgICB0aGlzLmNhbGxiYWNrKGVycm9yKTtcbiAgfSk7XG5cbiAgdHJ5IHtcbiAgICAvLyBzZXQgdGNwIG5vIGRlbGF5XG4gICAgcmVxLnNldE5vRGVsYXkodHJ1ZSk7XG5cbiAgICBpZiAob3B0aW9ucy5tZXRob2QgIT09ICdIRUFEJykge1xuICAgICAgcmVxLnNldEhlYWRlcignQWNjZXB0LUVuY29kaW5nJywgJ2d6aXAsIGRlZmxhdGUnKTtcbiAgICB9XG5cbiAgICB0aGlzLnByb3RvY29sID0gcHJvdG9jb2w7XG4gICAgdGhpcy5ob3N0ID0gdXJsLmhvc3Q7XG5cbiAgICAvLyBleHBvc2UgZXZlbnRzXG4gICAgY29uc3QgZW1pdERyYWluID0gKCkgPT4ge1xuICAgICAgdGhpcy5lbWl0KCdkcmFpbicpO1xuICAgIH07XG5cbiAgICByZXEub24oJ2RyYWluJywgZW1pdERyYWluKTtcbiAgICByZXEub25jZSgnY2xvc2UnLCAoKSA9PiB7XG4gICAgICByZXEucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgZW1pdERyYWluKTtcbiAgICB9KTtcblxuICAgIC8vIGF1dGhcbiAgICBpZiAodXJsLnVzZXJuYW1lIHx8IHVybC5wYXNzd29yZCkge1xuICAgICAgdGhpcy5hdXRoKHVybC51c2VybmFtZSwgdXJsLnBhc3N3b3JkKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy51c2VybmFtZSAmJiB0aGlzLnBhc3N3b3JkKSB7XG4gICAgICB0aGlzLmF1dGgodGhpcy51c2VybmFtZSwgdGhpcy5wYXNzd29yZCk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5oZWFkZXIpIHtcbiAgICAgIGlmIChoYXNPd24odGhpcy5oZWFkZXIsIGtleSkpIHJlcS5zZXRIZWFkZXIoa2V5LCB0aGlzLmhlYWRlcltrZXldKTtcbiAgICB9XG5cbiAgICAvLyBhZGQgY29va2llc1xuICAgIGlmICh0aGlzLmNvb2tpZXMpIHtcbiAgICAgIGlmIChoYXNPd24odGhpcy5faGVhZGVyLCAnY29va2llJykpIHtcbiAgICAgICAgLy8gbWVyZ2VcbiAgICAgICAgY29uc3QgdGVtcG9yYXJ5SmFyID0gbmV3IENvb2tpZUphci5Db29raWVKYXIoKTtcbiAgICAgICAgdGVtcG9yYXJ5SmFyLnNldENvb2tpZXModGhpcy5faGVhZGVyLmNvb2tpZS5zcGxpdCgnOyAnKSk7XG4gICAgICAgIHRlbXBvcmFyeUphci5zZXRDb29raWVzKHRoaXMuY29va2llcy5zcGxpdCgnOyAnKSk7XG4gICAgICAgIHJlcS5zZXRIZWFkZXIoXG4gICAgICAgICAgJ0Nvb2tpZScsXG4gICAgICAgICAgdGVtcG9yYXJ5SmFyXG4gICAgICAgICAgICAuZ2V0Q29va2llcyhDb29raWVKYXIuQ29va2llQWNjZXNzSW5mby5BbGwpXG4gICAgICAgICAgICAudG9WYWx1ZVN0cmluZygpXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXEuc2V0SGVhZGVyKCdDb29raWUnLCB0aGlzLmNvb2tpZXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXE7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGRpc3Bvc2VOb2RlUmVxdWVzdCh0aGlzKTtcbiAgICB0aHJvdyBlcnI7XG4gIH1cbn07XG5cbi8qKlxuICogQWJvcnQvZW5kIHRoZSBOb2RlIHJlcXVlc3QgaWYgaXQgd2FzIGNyZWF0ZWQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblJlcXVlc3QucHJvdG90eXBlLl9kaXNwb3NlUmVxdWVzdCA9IGZ1bmN0aW9uICgpIHtcbiAgZGlzcG9zZU5vZGVSZXF1ZXN0KHRoaXMpO1xufTtcblxuLyoqXG4gKiBSZXBvcnQgYSBzZXR1cC9yZXF1ZXN0LXBhdGggZXJyb3Igd2l0aG91dCBsZWF2aW5nIHRoZSBzb2NrZXQgb3Blbi5cbiAqXG4gKiBAcGFyYW0ge0Vycm9yfSBlcnJvclxuICogQGFwaSBwcml2YXRlXG4gKi9cblJlcXVlc3QucHJvdG90eXBlLl9mYWlsUmVxdWVzdCA9IGZ1bmN0aW9uIChlcnJvcikge1xuICB0aGlzLl9kaXNwb3NlUmVxdWVzdCgpO1xuICBpZiAodHlwZW9mIHRoaXMuX2NhbGxiYWNrID09PSAnZnVuY3Rpb24nICYmIHRoaXMuX2NhbGxiYWNrICE9PSBub29wKSB7XG4gICAgdGhpcy5jYWxsYmFjayhlcnJvcik7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhyb3cgZXJyb3I7XG59O1xuXG4vKipcbiAqIEludm9rZSB0aGUgY2FsbGJhY2sgd2l0aCBgZXJyYCBhbmQgYHJlc2BcbiAqIGFuZCBoYW5kbGUgYXJpdHkgY2hlY2suXG4gKlxuICogQHBhcmFtIHtFcnJvcn0gZXJyXG4gKiBAcGFyYW0ge1Jlc3BvbnNlfSByZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNhbGxiYWNrID0gZnVuY3Rpb24gKGVycm9yLCByZXMpIHtcbiAgaWYgKHRoaXMuX3Nob3VsZFJldHJ5KGVycm9yLCByZXMpKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JldHJ5KCk7XG4gIH1cblxuICAvLyBBdm9pZCB0aGUgZXJyb3Igd2hpY2ggaXMgZW1pdHRlZCBmcm9tICdzb2NrZXQgaGFuZyB1cCcgdG8gY2F1c2UgdGhlIGZuIHVuZGVmaW5lZCBlcnJvciBvbiBKUyBydW50aW1lLlxuICBjb25zdCBmbiA9IHRoaXMuX2NhbGxiYWNrIHx8IG5vb3A7XG4gIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG4gIGlmICh0aGlzLmNhbGxlZCkge1xuICAgIGlmICh0aGlzLnRpbWVkb3V0KSByZXR1cm47XG4gICAgcmV0dXJuIGNvbnNvbGUud2Fybignc3VwZXJhZ2VudDogZG91YmxlIGNhbGxiYWNrIGJ1ZycpO1xuICB9XG5cbiAgdGhpcy5jYWxsZWQgPSB0cnVlO1xuXG4gIGlmICghZXJyb3IpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKCF0aGlzLl9pc1Jlc3BvbnNlT0socmVzKSkge1xuICAgICAgICBsZXQgbWVzc2FnZSA9ICdVbnN1Y2Nlc3NmdWwgSFRUUCByZXNwb25zZSc7XG4gICAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgICBtZXNzYWdlID0gaHR0cC5TVEFUVVNfQ09ERVNbcmVzLnN0YXR1c10gfHwgbWVzc2FnZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVycm9yID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgICBlcnJvci5zdGF0dXMgPSByZXMgPyByZXMuc3RhdHVzIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgZXJyb3IgPSBlcnI7XG4gICAgICBlcnJvci5zdGF0dXMgPSBlcnJvci5zdGF0dXMgfHwgKHJlcyA/IHJlcy5zdGF0dXMgOiB1bmRlZmluZWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEl0J3MgaW1wb3J0YW50IHRoYXQgdGhlIGNhbGxiYWNrIGlzIGNhbGxlZCBvdXRzaWRlIHRyeS9jYXRjaFxuICAvLyB0byBhdm9pZCBkb3VibGUgY2FsbGJhY2tcbiAgaWYgKCFlcnJvcikge1xuICAgIHJldHVybiBmbihudWxsLCByZXMpO1xuICB9XG5cbiAgZXJyb3IucmVzcG9uc2UgPSByZXM7XG4gIGlmICh0aGlzLl9tYXhSZXRyaWVzKSBlcnJvci5yZXRyaWVzID0gdGhpcy5fcmV0cmllcyAtIDE7XG5cbiAgLy8gb25seSBlbWl0IGVycm9yIGV2ZW50IGlmIHRoZXJlIGlzIGEgbGlzdGVuZXJcbiAgLy8gb3RoZXJ3aXNlIHdlIGFzc3VtZSB0aGUgY2FsbGJhY2sgdG8gYC5lbmQoKWAgd2lsbCBnZXQgdGhlIGVycm9yXG4gIGlmIChlcnJvciAmJiB0aGlzLmxpc3RlbmVycygnZXJyb3InKS5sZW5ndGggPiAwKSB7XG4gICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgfVxuXG4gIGZuKGVycm9yLCByZXMpO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIGhvc3Qgb2JqZWN0LFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogaG9zdCBvYmplY3RcbiAqIEByZXR1cm4ge0Jvb2xlYW59IGlzIGEgaG9zdCBvYmplY3RcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5SZXF1ZXN0LnByb3RvdHlwZS5faXNIb3N0ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICByZXR1cm4gKFxuICAgIEJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpIHx8XG4gICAgb2JqZWN0IGluc3RhbmNlb2YgU3RyZWFtIHx8XG4gICAgb2JqZWN0IGluc3RhbmNlb2YgRm9ybURhdGFcbiAgKTtcbn07XG5cbi8qKlxuICogSW5pdGlhdGUgcmVxdWVzdCwgaW52b2tpbmcgY2FsbGJhY2sgYGZuKGVyciwgcmVzKWBcbiAqIHdpdGggYW4gaW5zdGFuY2VvZiBgUmVzcG9uc2VgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuX2VtaXRSZXNwb25zZSA9IGZ1bmN0aW9uIChib2R5LCBmaWxlcykge1xuICBjb25zdCByZXNwb25zZSA9IG5ldyBSZXNwb25zZSh0aGlzKTtcbiAgdGhpcy5yZXNwb25zZSA9IHJlc3BvbnNlO1xuICByZXNwb25zZS5yZWRpcmVjdHMgPSB0aGlzLl9yZWRpcmVjdExpc3Q7XG4gIGlmICh1bmRlZmluZWQgIT09IGJvZHkpIHtcbiAgICByZXNwb25zZS5ib2R5ID0gYm9keTtcbiAgfVxuXG4gIHJlc3BvbnNlLmZpbGVzID0gZmlsZXM7XG4gIGlmICh0aGlzLl9lbmRDYWxsZWQpIHtcbiAgICByZXNwb25zZS5waXBlID0gZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcImVuZCgpIGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkLCBzbyBpdCdzIHRvbyBsYXRlIHRvIHN0YXJ0IHBpcGluZ1wiXG4gICAgICApO1xuICAgIH07XG4gIH1cblxuICB0aGlzLmVtaXQoJ3Jlc3BvbnNlJywgcmVzcG9uc2UpO1xuICByZXR1cm4gcmVzcG9uc2U7XG59O1xuXG4vKipcbiAqIEVtaXQgYHJlZGlyZWN0YCBldmVudCwgcGFzc2luZyBhbiBpbnN0YW5jZW9mIGBSZXNwb25zZWAuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuX2VtaXRSZWRpcmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgcmVzcG9uc2UgPSBuZXcgUmVzcG9uc2UodGhpcyk7XG4gIHJlc3BvbnNlLnJlZGlyZWN0cyA9IHRoaXMuX3JlZGlyZWN0TGlzdDtcbiAgdGhpcy5lbWl0KCdyZWRpcmVjdCcsIHJlc3BvbnNlKTtcbn07XG5cbi8qKlxuICogRW1pdCBhIHJlZGlyZWN0IHJlc3BvbnNlIGJlZm9yZSB0aGUgcmVxdWVzdCBVUkwgaXMgY2hhbmdlZC5cbiAqXG4gKiBAcGFyYW0ge0luY29taW5nTWVzc2FnZX0gcmVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5fZW1pdFByZVJlZGlyZWN0ID0gZnVuY3Rpb24gKHJlcykge1xuICB0aGlzLnJlcyA9IHJlcztcbiAgY29uc3QgcmVzcG9uc2UgPSBuZXcgUmVzcG9uc2UodGhpcyk7XG4gIHJlc3BvbnNlLnJlZGlyZWN0cyA9IHRoaXMuX3JlZGlyZWN0TGlzdDtcbiAgdGhpcy5lbWl0KCdwcmUtcmVkaXJlY3QnLCByZXNwb25zZSk7XG59O1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAoZm4pIHtcbiAgdHJ5IHtcbiAgICB0aGlzLnJlcXVlc3QoKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhpcy5fZW5kQ2FsbGVkID0gdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLl9jYWxsYmFjayA9IGZuO1xuICAgICAgdGhpcy5jYWxsYmFjayhlcnIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRocm93IGVycjtcbiAgfVxuXG4gIGRlYnVnKCclcyAlcycsIHRoaXMubWV0aG9kLCB0aGlzLnVybCk7XG5cbiAgaWYgKHRoaXMuX2VuZENhbGxlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICcuZW5kKCkgd2FzIGNhbGxlZCB0d2ljZS4gVGhpcyBpcyBub3Qgc3VwcG9ydGVkIGluIHN1cGVyYWdlbnQnXG4gICAgKTtcbiAgfVxuXG4gIHRoaXMuX2VuZENhbGxlZCA9IHRydWU7XG5cbiAgLy8gc3RvcmUgY2FsbGJhY2tcbiAgdGhpcy5fY2FsbGJhY2sgPSBmbiB8fCBub29wO1xuXG4gIHRoaXMuX2VuZCgpO1xufTtcblxuUmVxdWVzdC5wcm90b3R5cGUuX2VuZCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuX2Fib3J0ZWQpXG4gICAgcmV0dXJuIHRoaXMuY2FsbGJhY2soXG4gICAgICBuZXcgRXJyb3IoJ1RoZSByZXF1ZXN0IGhhcyBiZWVuIGFib3J0ZWQgZXZlbiBiZWZvcmUgLmVuZCgpIHdhcyBjYWxsZWQnKVxuICAgICk7XG5cbiAgbGV0IGRhdGEgPSB0aGlzLl9kYXRhO1xuICBjb25zdCB7IHJlcSB9ID0gdGhpcztcbiAgY29uc3QgeyBtZXRob2QgfSA9IHRoaXM7XG5cbiAgdGhpcy5fc2V0VGltZW91dHMoKTtcblxuICAvLyBib2R5XG4gIGlmIChtZXRob2QgIT09ICdIRUFEJyAmJiAhcmVxLl9oZWFkZXJTZW50KSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIHNlcmlhbGl6ZSBzdHVmZlxuICAgICAgaWYgKHR5cGVvZiBkYXRhICE9PSAnc3RyaW5nJykge1xuICAgICAgICBsZXQgY29udGVudFR5cGUgPSByZXEuZ2V0SGVhZGVyKCdDb250ZW50LVR5cGUnKTtcbiAgICAgICAgLy8gUGFyc2Ugb3V0IGp1c3QgdGhlIGNvbnRlbnQgdHlwZSBmcm9tIHRoZSBoZWFkZXIgKGlnbm9yZSB0aGUgY2hhcnNldClcbiAgICAgICAgaWYgKGNvbnRlbnRUeXBlKSBjb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlLnNwbGl0KCc7JylbMF07XG4gICAgICAgIGxldCBzZXJpYWxpemUgPSB0aGlzLl9zZXJpYWxpemVyIHx8IGV4cG9ydHMuc2VyaWFsaXplW2NvbnRlbnRUeXBlXTtcbiAgICAgICAgaWYgKCFzZXJpYWxpemUgJiYgaXNKU09OKGNvbnRlbnRUeXBlKSkge1xuICAgICAgICAgIHNlcmlhbGl6ZSA9IGV4cG9ydHMuc2VyaWFsaXplWydhcHBsaWNhdGlvbi9qc29uJ107XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2VyaWFsaXplKSBkYXRhID0gc2VyaWFsaXplKGRhdGEpO1xuICAgICAgfVxuXG4gICAgICAvLyBjb250ZW50LWxlbmd0aFxuICAgICAgaWYgKGRhdGEgJiYgIXJlcS5nZXRIZWFkZXIoJ0NvbnRlbnQtTGVuZ3RoJykpIHtcbiAgICAgICAgcmVxLnNldEhlYWRlcihcbiAgICAgICAgICAnQ29udGVudC1MZW5ndGgnLFxuICAgICAgICAgIEJ1ZmZlci5pc0J1ZmZlcihkYXRhKSA/IGRhdGEubGVuZ3RoIDogQnVmZmVyLmJ5dGVMZW5ndGgoZGF0YSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLl9mYWlsUmVxdWVzdChlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHJlc3BvbnNlXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5XG4gIHJlcS5vbmNlKCdyZXNwb25zZScsIChyZXMpID0+IHtcbiAgICBkZWJ1ZygnJXMgJXMgLT4gJXMnLCB0aGlzLm1ldGhvZCwgdGhpcy51cmwsIHJlcy5zdGF0dXNDb2RlKTtcblxuICAgIGlmICh0aGlzLl9yZXNwb25zZVRpbWVvdXRUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3Jlc3BvbnNlVGltZW91dFRpbWVyKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5waXBlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG1heCA9IHRoaXMuX21heFJlZGlyZWN0cztcbiAgICBjb25zdCBtaW1lID0gdXRpbHMudHlwZShyZXMuaGVhZGVyc1snY29udGVudC10eXBlJ10gfHwgJycpIHx8ICd0ZXh0L3BsYWluJztcbiAgICBsZXQgdHlwZSA9IG1pbWUuc3BsaXQoJy8nKVswXTtcbiAgICBpZiAodHlwZSkgdHlwZSA9IHR5cGUudG9Mb3dlckNhc2UoKS50cmltKCk7XG4gICAgY29uc3QgbXVsdGlwYXJ0ID0gdHlwZSA9PT0gJ211bHRpcGFydCc7XG4gICAgY29uc3QgcmVkaXJlY3QgPSBpc1JlZGlyZWN0KHJlcy5zdGF0dXNDb2RlKTtcbiAgICBjb25zdCByZXNwb25zZVR5cGUgPSB0aGlzLl9yZXNwb25zZVR5cGU7XG5cbiAgICB0aGlzLnJlcyA9IHJlcztcblxuICAgIC8vIHJlZGlyZWN0XG4gICAgaWYgKHJlZGlyZWN0ICYmIHRoaXMuX3JlZGlyZWN0cysrICE9PSBtYXgpIHtcbiAgICAgIHJldHVybiB0aGlzLl9yZWRpcmVjdChyZXMpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1ldGhvZCA9PT0gJ0hFQUQnKSB7XG4gICAgICB0aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgdGhpcy5jYWxsYmFjayhudWxsLCB0aGlzLl9lbWl0UmVzcG9uc2UoKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gemxpYiBzdXBwb3J0XG4gICAgaWYgKHRoaXMuX3Nob3VsZERlY29tcHJlc3MocmVzKSkge1xuICAgICAgZGVjb21wcmVzcyhyZXEsIHJlcyk7XG4gICAgfVxuXG4gICAgbGV0IGJ1ZmZlciA9IHRoaXMuX2J1ZmZlcjtcbiAgICBpZiAoYnVmZmVyID09PSB1bmRlZmluZWQgJiYgbWltZSBpbiBleHBvcnRzLmJ1ZmZlcikge1xuICAgICAgYnVmZmVyID0gQm9vbGVhbihleHBvcnRzLmJ1ZmZlclttaW1lXSk7XG4gICAgfVxuXG4gICAgbGV0IHBhcnNlciA9IHRoaXMuX3BhcnNlcjtcbiAgICBpZiAodW5kZWZpbmVkID09PSBidWZmZXIgJiYgcGFyc2VyKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIFwiQSBjdXN0b20gc3VwZXJhZ2VudCBwYXJzZXIgaGFzIGJlZW4gc2V0LCBidXQgYnVmZmVyaW5nIHN0cmF0ZWd5IGZvciB0aGUgcGFyc2VyIGhhc24ndCBiZWVuIGNvbmZpZ3VyZWQuIENhbGwgYHJlcS5idWZmZXIodHJ1ZSBvciBmYWxzZSlgIG9yIHNldCBgc3VwZXJhZ2VudC5idWZmZXJbbWltZV0gPSB0cnVlIG9yIGZhbHNlYFwiXG4gICAgICApO1xuICAgICAgYnVmZmVyID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcnNlcikge1xuICAgICAgaWYgKHJlc3BvbnNlVHlwZSkge1xuICAgICAgICBwYXJzZXIgPSBleHBvcnRzLnBhcnNlLmltYWdlOyAvLyBJdCdzIGFjdHVhbGx5IGEgZ2VuZXJpYyBCdWZmZXJcbiAgICAgICAgYnVmZmVyID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSBpZiAobXVsdGlwYXJ0KSB7XG4gICAgICAgIGNvbnN0IGZvcm0gPSBmb3JtaWRhYmxlLmZvcm1pZGFibGUoKTtcbiAgICAgICAgcGFyc2VyID0gKHJlcywgY2FsbGJhY2spID0+IHtcbiAgICAgICAgICAvLyBDcmVhdGUgYSBQYXNzVGhyb3VnaCBzdHJlYW0gdGhhdCBhY3RzIGFzIGEgcHJvcGVyIEhUVFAgcmVxdWVzdFxuICAgICAgICAgIGNvbnN0IGJyaWRnZVN0cmVhbSA9IG5ldyBTdHJlYW0uUGFzc1Rocm91Z2goKTtcblxuICAgICAgICAgIC8vIEFkZCBIVFRQIHJlcXVlc3QgcHJvcGVydGllcyBmcm9tIHRoZSBjdXJyZW50IHJlcXVlc3QgY29udGV4dFxuICAgICAgICAgIGJyaWRnZVN0cmVhbS5tZXRob2QgPSB0aGlzLm1ldGhvZCB8fCAnUE9TVCc7XG4gICAgICAgICAgYnJpZGdlU3RyZWFtLnVybCA9IHRoaXMudXJsIHx8ICcvJztcbiAgICAgICAgICBicmlkZ2VTdHJlYW0uaHR0cFZlcnNpb24gPSByZXMuaHR0cFZlcnNpb24gfHwgJzEuMSc7XG4gICAgICAgICAgYnJpZGdlU3RyZWFtLmhlYWRlcnMgPSByZXMuaGVhZGVycyB8fCB7fTtcbiAgICAgICAgICBicmlkZ2VTdHJlYW0uc29ja2V0ID0gcmVzLnNvY2tldCB8fCB7IHJlYWRhYmxlOiB0cnVlIH07XG5cbiAgICAgICAgICAvLyBQaXBlIHRoZSByZXNwb25zZSBkYXRhIHRocm91Z2ggdGhlIGJyaWRnZSBzdHJlYW1cbiAgICAgICAgICByZXMucGlwZShicmlkZ2VTdHJlYW0pO1xuXG4gICAgICAgICAgZm9ybS5wYXJzZShicmlkZ2VTdHJlYW0sIChlcnIsIGZpZWxkcywgZmlsZXMpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgICAgICAvLyBGb3JtaWRhYmxlIHYzIGFsd2F5cyByZXR1cm5zIGFycmF5cywgYnV0IFN1cGVyQWdlbnQgZXhwZWN0cyBzaW5nbGUgdmFsdWVzXG4gICAgICAgICAgICAvLyBGbGF0dGVuIHNpbmdsZS1pdGVtIGFycmF5cyB0byBtYWludGFpbiBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG4gICAgICAgICAgICBjb25zdCBmbGF0dGVuZWRGaWVsZHMgPSB7fTtcbiAgICAgICAgICAgIGlmIChmaWVsZHMpIHtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZmllbGRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZmllbGRzLCBrZXkpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGZpZWxkc1trZXldO1xuICAgICAgICAgICAgICAgIGZsYXR0ZW5lZEZpZWxkc1trZXldID1cbiAgICAgICAgICAgICAgICAgIEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA9PT0gMSA/IHZhbHVlWzBdIDogdmFsdWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZmxhdHRlbmVkRmlsZXMgPSB7fTtcbiAgICAgICAgICAgIGlmIChmaWxlcykge1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBmaWxlcykge1xuICAgICAgICAgICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGZpbGVzLCBrZXkpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGZpbGVzW2tleV07XG4gICAgICAgICAgICAgICAgZmxhdHRlbmVkRmlsZXNba2V5XSA9XG4gICAgICAgICAgICAgICAgICBBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPT09IDEgPyB2YWx1ZVswXSA6IHZhbHVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJldHVybiBmbGF0dGVuZWQgZmllbGRzIGFzIHRoZSBvYmplY3QgcGFyYW1ldGVyIHRvIG1hdGNoIFN1cGVyQWdlbnQncyBleHBlY3RlZCBmb3JtYXRcbiAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGZsYXR0ZW5lZEZpZWxkcywgZmxhdHRlbmVkRmlsZXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGJ1ZmZlciA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKGlzQmluYXJ5KG1pbWUpKSB7XG4gICAgICAgIHBhcnNlciA9IGV4cG9ydHMucGFyc2UuaW1hZ2U7XG4gICAgICAgIGJ1ZmZlciA9IGJ1ZmZlciAhPT0gZmFsc2U7IC8vIEZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSBidWZmZXJpbmcgZGVmYXVsdCBpcyBhZC1ob2MgTUlNRS1kZXBlbmRlbnRcbiAgICAgIH0gZWxzZSBpZiAoZXhwb3J0cy5wYXJzZVttaW1lXSkge1xuICAgICAgICBwYXJzZXIgPSBleHBvcnRzLnBhcnNlW21pbWVdO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAndGV4dCcpIHtcbiAgICAgICAgcGFyc2VyID0gZXhwb3J0cy5wYXJzZS50ZXh0O1xuICAgICAgICBidWZmZXIgPSBidWZmZXIgIT09IGZhbHNlO1xuICAgICAgICAvLyBldmVyeW9uZSB3YW50cyB0aGVpciBvd24gd2hpdGUtbGFiZWxlZCBqc29uXG4gICAgICB9IGVsc2UgaWYgKGlzSlNPTihtaW1lKSkge1xuICAgICAgICBwYXJzZXIgPSBleHBvcnRzLnBhcnNlWydhcHBsaWNhdGlvbi9qc29uJ107XG4gICAgICAgIGJ1ZmZlciA9IGJ1ZmZlciAhPT0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKGJ1ZmZlcikge1xuICAgICAgICBwYXJzZXIgPSBleHBvcnRzLnBhcnNlLnRleHQ7XG4gICAgICB9IGVsc2UgaWYgKHVuZGVmaW5lZCA9PT0gYnVmZmVyKSB7XG4gICAgICAgIHBhcnNlciA9IGV4cG9ydHMucGFyc2UuaW1hZ2U7IC8vIEl0J3MgYWN0dWFsbHkgYSBnZW5lcmljIEJ1ZmZlclxuICAgICAgICBidWZmZXIgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGJ5IGRlZmF1bHQgb25seSBidWZmZXIgdGV4dC8qLCBqc29uIGFuZCBtZXNzZWQgdXAgdGhpbmcgZnJvbSBoZWxsXG4gICAgaWYgKCh1bmRlZmluZWQgPT09IGJ1ZmZlciAmJiBpc1RleHQobWltZSkpIHx8IGlzSlNPTihtaW1lKSkge1xuICAgICAgYnVmZmVyID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLl9yZXNCdWZmZXJlZCA9IGJ1ZmZlcjtcbiAgICBsZXQgcGFyc2VySGFuZGxlc0VuZCA9IGZhbHNlO1xuICAgIGlmIChidWZmZXIpIHtcbiAgICAgIC8vIFByb3RlY3Rpb25hIGFnYWluc3QgemlwIGJvbWJzIGFuZCBvdGhlciBudWlzYW5jZVxuICAgICAgbGV0IHJlc3BvbnNlQnl0ZXNMZWZ0ID0gdGhpcy5fbWF4UmVzcG9uc2VTaXplIHx8IDIwMDAwMDAwMDtcbiAgICAgIHJlcy5vbignZGF0YScsIChidWYpID0+IHtcbiAgICAgICAgcmVzcG9uc2VCeXRlc0xlZnQgLT0gYnVmLmJ5dGVMZW5ndGggfHwgYnVmLmxlbmd0aCA+IDAgPyBidWYubGVuZ3RoIDogMDtcbiAgICAgICAgaWYgKHJlc3BvbnNlQnl0ZXNMZWZ0IDwgMCkge1xuICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCdNYXhpbXVtIHJlc3BvbnNlIHNpemUgcmVhY2hlZCcpO1xuICAgICAgICAgIGVycm9yLmNvZGUgPSAnRVRPT0xBUkdFJztcbiAgICAgICAgICAvLyBQYXJzZXJzIGFyZW4ndCByZXF1aXJlZCB0byBvYnNlcnZlIGVycm9yIGV2ZW50LFxuICAgICAgICAgIC8vIHNvIHdvdWxkIGluY29ycmVjdGx5IHJlcG9ydCBzdWNjZXNzXG4gICAgICAgICAgcGFyc2VySGFuZGxlc0VuZCA9IGZhbHNlO1xuICAgICAgICAgIC8vIERlc3Ryb3kgd2l0aG91dCBhbiBlcnJvcjogSW5jb21pbmdNZXNzYWdlLmRlc3Ryb3koZXJyKSBlbWl0c1xuICAgICAgICAgIC8vICdlcnJvcicsIGFuZCB0aGUgcGFyc2VyIG1heSBhbHNvIGZhaWwsIGVhY2ggb2Ygd2hpY2ggd291bGRcbiAgICAgICAgICAvLyBjYWxsIGNhbGxiYWNrKCkgYWdhaW4gKFwic3VwZXJhZ2VudDogZG91YmxlIGNhbGxiYWNrIGJ1Z1wiKS5cbiAgICAgICAgICByZXMuZGVzdHJveSgpO1xuICAgICAgICAgIHRoaXMuY2FsbGJhY2soZXJyb3IsIG51bGwpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAocGFyc2VyKSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBVbmJ1ZmZlcmVkIHBhcnNlcnMgYXJlIHN1cHBvc2VkIHRvIGVtaXQgcmVzcG9uc2UgZWFybHksXG4gICAgICAgIC8vIHdoaWNoIGlzIHdlaXJkIEJUVywgYmVjYXVzZSByZXNwb25zZS5ib2R5IHdvbid0IGJlIHRoZXJlLlxuICAgICAgICBwYXJzZXJIYW5kbGVzRW5kID0gYnVmZmVyO1xuXG4gICAgICAgIHBhcnNlcihyZXMsIChlcnJvciwgb2JqZWN0LCBmaWxlcykgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLnRpbWVkb3V0IHx8IHRoaXMuY2FsbGVkKSB7XG4gICAgICAgICAgICAvLyBUaW1lb3V0IG9yIG1heFJlc3BvbnNlU2l6ZSBoYXMgYWxyZWFkeSBoYW5kbGVkIGFsbCBjYWxsYmFja3NcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBJbnRlbnRpb25hbCAobm9uLXRpbWVvdXQpIGFib3J0IGlzIHN1cHBvc2VkIHRvIHByZXNlcnZlIHBhcnRpYWwgcmVzcG9uc2UsXG4gICAgICAgICAgLy8gZXZlbiBpZiBpdCBkb2Vzbid0IHBhcnNlLlxuICAgICAgICAgIGlmIChlcnJvciAmJiAhdGhpcy5fYWJvcnRlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwYXJzZXJIYW5kbGVzRW5kKSB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayhudWxsLCB0aGlzLl9lbWl0UmVzcG9uc2Uob2JqZWN0LCBmaWxlcykpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFjayhlcnIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5yZXMgPSByZXM7XG5cbiAgICAvLyB1bmJ1ZmZlcmVkXG4gICAgaWYgKCFidWZmZXIpIHtcbiAgICAgIGRlYnVnKCd1bmJ1ZmZlcmVkICVzICVzJywgdGhpcy5tZXRob2QsIHRoaXMudXJsKTtcbiAgICAgIHRoaXMuY2FsbGJhY2sobnVsbCwgdGhpcy5fZW1pdFJlc3BvbnNlKCkpO1xuICAgICAgaWYgKG11bHRpcGFydCkgcmV0dXJuOyAvLyBhbGxvdyBtdWx0aXBhcnQgdG8gaGFuZGxlIGVuZCBldmVudFxuICAgICAgcmVzLm9uY2UoJ2VuZCcsICgpID0+IHtcbiAgICAgICAgZGVidWcoJ2VuZCAlcyAlcycsIHRoaXMubWV0aG9kLCB0aGlzLnVybCk7XG4gICAgICAgIHRoaXMuZW1pdCgnZW5kJyk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjb21wbGV0ZUFib3J0ZWRSZXNwb25zZSA9ICgpID0+IHtcbiAgICAgIGlmICghdGhpcy5fYWJvcnRlZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHBhcnNlckhhbmRsZXNFbmQgPSBmYWxzZTtcbiAgICAgIGlmICghdGhpcy5jYWxsZWQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLl9lbWl0UmVzcG9uc2UoKTtcbiAgICAgICAgcmVzcG9uc2Uub24oJ2Vycm9yJywgbm9vcCk7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sobnVsbCwgcmVzcG9uc2UpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgLy8gdGVybWluYXRpbmcgZXZlbnRzXG4gICAgcmVzLm9uY2UoJ2Vycm9yJywgKGVycm9yKSA9PiB7XG4gICAgICBpZiAoY29tcGxldGVBYm9ydGVkUmVzcG9uc2UoKSkgcmV0dXJuO1xuICAgICAgcGFyc2VySGFuZGxlc0VuZCA9IGZhbHNlO1xuICAgICAgdGhpcy5jYWxsYmFjayhlcnJvciwgbnVsbCk7XG4gICAgfSk7XG4gICAgcmVzLm9uY2UoJ2Fib3J0ZWQnLCBjb21wbGV0ZUFib3J0ZWRSZXNwb25zZSk7XG4gICAgcmVzLm9uY2UoJ2Nsb3NlJywgY29tcGxldGVBYm9ydGVkUmVzcG9uc2UpO1xuICAgIGlmICghcGFyc2VySGFuZGxlc0VuZClcbiAgICAgIHJlcy5vbmNlKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgIGRlYnVnKCdlbmQgJXMgJXMnLCB0aGlzLm1ldGhvZCwgdGhpcy51cmwpO1xuICAgICAgICAvLyBUT0RPOiB1bmxlc3MgYnVmZmVyaW5nIGVtaXQgZWFybGllciB0byBzdHJlYW1cbiAgICAgICAgdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayhudWxsLCB0aGlzLl9lbWl0UmVzcG9uc2UoKSk7XG4gICAgICB9KTtcbiAgfSk7XG5cbiAgdGhpcy5lbWl0KCdyZXF1ZXN0JywgdGhpcyk7XG5cbiAgY29uc3QgZ2V0UHJvZ3Jlc3NNb25pdG9yID0gKCkgPT4ge1xuICAgIGNvbnN0IGxlbmd0aENvbXB1dGFibGUgPSB0cnVlO1xuICAgIGNvbnN0IHRvdGFsID0gcmVxLmdldEhlYWRlcignQ29udGVudC1MZW5ndGgnKTtcbiAgICBsZXQgbG9hZGVkID0gMDtcblxuICAgIGNvbnN0IHByb2dyZXNzID0gbmV3IFN0cmVhbS5UcmFuc2Zvcm0oKTtcbiAgICBwcm9ncmVzcy5fdHJhbnNmb3JtID0gKGNodW5rLCBlbmNvZGluZywgY2FsbGJhY2spID0+IHtcbiAgICAgIGxvYWRlZCArPSBjaHVuay5sZW5ndGg7XG4gICAgICB0aGlzLmVtaXQoJ3Byb2dyZXNzJywge1xuICAgICAgICBkaXJlY3Rpb246ICd1cGxvYWQnLFxuICAgICAgICBsZW5ndGhDb21wdXRhYmxlLFxuICAgICAgICBsb2FkZWQsXG4gICAgICAgIHRvdGFsXG4gICAgICB9KTtcbiAgICAgIGNhbGxiYWNrKG51bGwsIGNodW5rKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIHByb2dyZXNzO1xuICB9O1xuXG4gIGNvbnN0IGJ1ZmZlclRvQ2h1bmtzID0gKGJ1ZmZlcikgPT4ge1xuICAgIGNvbnN0IGNodW5rU2l6ZSA9IDE2ICogMTAyNDsgLy8gZGVmYXVsdCBoaWdoV2F0ZXJNYXJrIHZhbHVlXG4gICAgY29uc3QgY2h1bmtpbmcgPSBuZXcgU3RyZWFtLlJlYWRhYmxlKCk7XG4gICAgY29uc3QgdG90YWxMZW5ndGggPSBidWZmZXIubGVuZ3RoO1xuICAgIGNvbnN0IHJlbWFpbmRlciA9IHRvdGFsTGVuZ3RoICUgY2h1bmtTaXplO1xuICAgIGNvbnN0IGN1dG9mZiA9IHRvdGFsTGVuZ3RoIC0gcmVtYWluZGVyO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjdXRvZmY7IGkgKz0gY2h1bmtTaXplKSB7XG4gICAgICBjb25zdCBjaHVuayA9IGJ1ZmZlci5zbGljZShpLCBpICsgY2h1bmtTaXplKTtcbiAgICAgIGNodW5raW5nLnB1c2goY2h1bmspO1xuICAgIH1cblxuICAgIGlmIChyZW1haW5kZXIgPiAwKSB7XG4gICAgICBjb25zdCByZW1haW5kZXJCdWZmZXIgPSBidWZmZXIuc2xpY2UoLXJlbWFpbmRlcik7XG4gICAgICBjaHVua2luZy5wdXNoKHJlbWFpbmRlckJ1ZmZlcik7XG4gICAgfVxuXG4gICAgY2h1bmtpbmcucHVzaChudWxsKTsgLy8gbm8gbW9yZSBkYXRhXG5cbiAgICByZXR1cm4gY2h1bmtpbmc7XG4gIH07XG5cbiAgdHJ5IHtcbiAgICAvLyBpZiBhIEZvcm1EYXRhIGluc3RhbmNlIGdvdCBjcmVhdGVkLCB0aGVuIHdlIHNlbmQgdGhhdCBhcyB0aGUgcmVxdWVzdCBib2R5XG4gICAgY29uc3QgZm9ybURhdGEgPSB0aGlzLl9mb3JtRGF0YTtcbiAgICBpZiAoZm9ybURhdGEpIHtcbiAgICAgIC8vIHNldCBoZWFkZXJzXG4gICAgICBjb25zdCBoZWFkZXJzID0gZm9ybURhdGEuZ2V0SGVhZGVycygpO1xuICAgICAgZm9yIChjb25zdCBpIGluIGhlYWRlcnMpIHtcbiAgICAgICAgaWYgKGhhc093bihoZWFkZXJzLCBpKSkge1xuICAgICAgICAgIGRlYnVnKCdzZXR0aW5nIEZvcm1EYXRhIGhlYWRlcjogXCIlczogJXNcIicsIGksIGhlYWRlcnNbaV0pO1xuICAgICAgICAgIHJlcS5zZXRIZWFkZXIoaSwgaGVhZGVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gYXR0ZW1wdCB0byBnZXQgXCJDb250ZW50LUxlbmd0aFwiIGhlYWRlclxuICAgICAgZm9ybURhdGEuZ2V0TGVuZ3RoKChlcnJvciwgbGVuZ3RoKSA9PiB7XG4gICAgICAgIC8vIFRPRE86IEFkZCBjaHVua2VkIGVuY29kaW5nIHdoZW4gbm8gbGVuZ3RoIChpZiBlcnIpXG4gICAgICAgIGlmIChlcnJvcikgZGVidWcoJ2Zvcm1EYXRhLmdldExlbmd0aCBoYWQgZXJyb3InLCBlcnJvciwgbGVuZ3RoKTtcblxuICAgICAgICBkZWJ1ZygnZ290IEZvcm1EYXRhIENvbnRlbnQtTGVuZ3RoOiAlcycsIGxlbmd0aCk7XG4gICAgICAgIGlmICh0eXBlb2YgbGVuZ3RoID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHJlcS5zZXRIZWFkZXIoJ0NvbnRlbnQtTGVuZ3RoJywgbGVuZ3RoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvcm1EYXRhLnBpcGUoZ2V0UHJvZ3Jlc3NNb25pdG9yKCkpLnBpcGUocmVxKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKGRhdGEpKSB7XG4gICAgICBidWZmZXJUb0NodW5rcyhkYXRhKS5waXBlKGdldFByb2dyZXNzTW9uaXRvcigpKS5waXBlKHJlcSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcS5lbmQoZGF0YSk7XG4gICAgfVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aGlzLl9mYWlsUmVxdWVzdChlcnIpO1xuICB9XG59O1xuXG4vLyBDaGVjayB3aGV0aGVyIHJlc3BvbnNlIGhhcyBhIG5vbi0wLXNpemVkIGd6aXAtZW5jb2RlZCBib2R5XG5SZXF1ZXN0LnByb3RvdHlwZS5fc2hvdWxkRGVjb21wcmVzcyA9IChyZXMpID0+IHtcbiAgcmV0dXJuIChcbiAgICBoYXNOb25FbXB0eVJlc3BvbnNlQ29udGVudChyZXMpICYmXG4gICAgKGlzR3ppcE9yRGVmbGF0ZUVuY29kaW5nKHJlcykgfHwgaXNCcm90bGlFbmNvZGluZyhyZXMpKVxuICApO1xufTtcblxuLyoqXG4gKiBPdmVycmlkZXMgRE5TIGZvciBzZWxlY3RlZCBob3N0bmFtZXMuIFRha2VzIG9iamVjdCBtYXBwaW5nIGhvc3RuYW1lcyB0byBJUCBhZGRyZXNzZXMuXG4gKlxuICogV2hlbiBtYWtpbmcgYSByZXF1ZXN0IHRvIGEgVVJMIHdpdGggYSBob3N0bmFtZSBleGFjdGx5IG1hdGNoaW5nIGEga2V5IGluIHRoZSBvYmplY3QsXG4gKiB1c2UgdGhlIGdpdmVuIElQIGFkZHJlc3MgdG8gY29ubmVjdCwgaW5zdGVhZCBvZiB1c2luZyBETlMgdG8gcmVzb2x2ZSB0aGUgaG9zdG5hbWUuXG4gKlxuICogQSBzcGVjaWFsIGhvc3QgYCpgIG1hdGNoZXMgZXZlcnkgaG9zdG5hbWUgKGtlZXAgcmVkaXJlY3RzIGluIG1pbmQhKVxuICpcbiAqICAgICAgcmVxdWVzdC5jb25uZWN0KHtcbiAqICAgICAgICAndGVzdC5leGFtcGxlLmNvbSc6ICcxMjcuMC4wLjEnLFxuICogICAgICAgICdpcHY2LmV4YW1wbGUuY29tJzogJzo6MScsXG4gKiAgICAgIH0pXG4gKi9cblJlcXVlc3QucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbiAoY29ubmVjdE92ZXJyaWRlKSB7XG4gIGlmICh0eXBlb2YgY29ubmVjdE92ZXJyaWRlID09PSAnc3RyaW5nJykge1xuICAgIHRoaXMuX2Nvbm5lY3RPdmVycmlkZSA9IHsgJyonOiBjb25uZWN0T3ZlcnJpZGUgfTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgY29ubmVjdE92ZXJyaWRlID09PSAnb2JqZWN0Jykge1xuICAgIHRoaXMuX2Nvbm5lY3RPdmVycmlkZSA9IGNvbm5lY3RPdmVycmlkZTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9jb25uZWN0T3ZlcnJpZGUgPSB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cblJlcXVlc3QucHJvdG90eXBlLnRydXN0TG9jYWxob3N0ID0gZnVuY3Rpb24gKHRvZ2dsZSkge1xuICB0aGlzLl90cnVzdExvY2FsaG9zdCA9IHRvZ2dsZSA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IHRvZ2dsZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBnZW5lcmF0ZSBIVFRQIHZlcmIgbWV0aG9kc1xuaWYgKCFtZXRob2RzLmluY2x1ZGVzKCdkZWwnKSkge1xuICAvLyBjcmVhdGUgYSBjb3B5IHNvIHdlIGRvbid0IGNhdXNlIGNvbmZsaWN0cyB3aXRoXG4gIC8vIG90aGVyIHBhY2thZ2VzIHVzaW5nIHRoZSBtZXRob2RzIHBhY2thZ2UgYW5kXG4gIC8vIG5wbSAzLnhcbiAgbWV0aG9kcyA9IFsuLi5tZXRob2RzXTtcbiAgbWV0aG9kcy5wdXNoKCdkZWwnKTtcbn1cblxuZm9yIChsZXQgbWV0aG9kIG9mIG1ldGhvZHMpIHtcbiAgY29uc3QgbmFtZSA9IG1ldGhvZDtcbiAgbWV0aG9kID0gbWV0aG9kID09PSAnZGVsJyA/ICdkZWxldGUnIDogbWV0aG9kO1xuXG4gIG1ldGhvZCA9IG1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuICByZXF1ZXN0W25hbWVdID0gKHVybCwgZGF0YSwgZm4pID0+IHtcbiAgICBjb25zdCByZXF1ZXN0XyA9IHJlcXVlc3QobWV0aG9kLCB1cmwpO1xuICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZm4gPSBkYXRhO1xuICAgICAgZGF0YSA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGRhdGEpIHtcbiAgICAgIGlmIChtZXRob2QgPT09ICdHRVQnIHx8IG1ldGhvZCA9PT0gJ0hFQUQnKSB7XG4gICAgICAgIHJlcXVlc3RfLnF1ZXJ5KGRhdGEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVxdWVzdF8uc2VuZChkYXRhKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZm4pIHJlcXVlc3RfLmVuZChmbik7XG4gICAgcmV0dXJuIHJlcXVlc3RfO1xuICB9O1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGBtaW1lYCBpcyB0ZXh0IGFuZCBzaG91bGQgYmUgYnVmZmVyZWQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1pbWVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGlzVGV4dChtaW1lKSB7XG4gIGNvbnN0IHBhcnRzID0gbWltZS5zcGxpdCgnLycpO1xuICBsZXQgdHlwZSA9IHBhcnRzWzBdO1xuICBpZiAodHlwZSkgdHlwZSA9IHR5cGUudG9Mb3dlckNhc2UoKS50cmltKCk7XG4gIGxldCBzdWJ0eXBlID0gcGFydHNbMV07XG4gIGlmIChzdWJ0eXBlKSBzdWJ0eXBlID0gc3VidHlwZS50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcblxuICByZXR1cm4gdHlwZSA9PT0gJ3RleHQnIHx8IHN1YnR5cGUgPT09ICd4LXd3dy1mb3JtLXVybGVuY29kZWQnO1xufVxuXG4vLyBUaGlzIGlzIG5vdCBhIGNhdGNoYWxsLCBidXQgYSBzdGFydC4gSXQgbWlnaHQgYmUgdXNlZnVsXG4vLyBpbiB0aGUgbG9uZyBydW4gdG8gaGF2ZSBmaWxlIHRoYXQgaW5jbHVkZXMgYWxsIGJpbmFyeVxuLy8gY29udGVudCB0eXBlcyBmcm9tIGh0dHBzOi8vd3d3LmlhbmEub3JnL2Fzc2lnbm1lbnRzL21lZGlhLXR5cGVzL21lZGlhLXR5cGVzLnhodG1sXG5mdW5jdGlvbiBpc0JpbmFyeShtaW1lKSB7XG4gIGxldCBbcmVnaXN0cnksIG5hbWVdID0gbWltZS5zcGxpdCgnLycpO1xuICBpZiAocmVnaXN0cnkpIHJlZ2lzdHJ5ID0gcmVnaXN0cnkudG9Mb3dlckNhc2UoKS50cmltKCk7XG4gIGlmIChuYW1lKSBuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcbiAgcmV0dXJuIChcbiAgICBbJ2F1ZGlvJywgJ2ZvbnQnLCAnaW1hZ2UnLCAndmlkZW8nXS5pbmNsdWRlcyhyZWdpc3RyeSkgfHxcbiAgICBbJ2d6JywgJ2d6aXAnXS5pbmNsdWRlcyhuYW1lKVxuICApO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGBtaW1lYCBpcyBqc29uIG9yIGhhcyAranNvbiBzdHJ1Y3R1cmVkIHN5bnRheCBzdWZmaXguXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1pbWVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0pTT04obWltZSkge1xuICAvLyBzaG91bGQgbWF0Y2ggL2pzb24gb3IgK2pzb25cbiAgLy8gYnV0IG5vdCAvanNvbi1zZXFcbiAgcmV0dXJuIC9bLytdanNvbigkfFteLVxcd10pL2kudGVzdChtaW1lKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBzaG91bGQgZm9sbG93IHRoZSByZWRpcmVjdCBgY29kZWAuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGNvZGVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc1JlZGlyZWN0KGNvZGUpIHtcbiAgcmV0dXJuIFszMDEsIDMwMiwgMzAzLCAzMDUsIDMwNywgMzA4XS5pbmNsdWRlcyhjb2RlKTtcbn1cblxuZnVuY3Rpb24gaGFzTm9uRW1wdHlSZXNwb25zZUNvbnRlbnQocmVzKSB7XG4gIGlmIChyZXMuc3RhdHVzQ29kZSA9PT0gMjA0IHx8IHJlcy5zdGF0dXNDb2RlID09PSAzMDQpIHtcbiAgICAvLyBUaGVzZSBhcmVuJ3Qgc3VwcG9zZWQgdG8gaGF2ZSBhbnkgYm9keVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGhlYWRlciBjb250ZW50IGlzIGEgc3RyaW5nLCBhbmQgZGlzdGluY3Rpb24gYmV0d2VlbiAwIGFuZCBubyBpbmZvcm1hdGlvbiBpcyBjcnVjaWFsXG4gIGlmIChyZXMuaGVhZGVyc1snY29udGVudC1sZW5ndGgnXSA9PT0gJzAnKSB7XG4gICAgLy8gV2Uga25vdyB0aGF0IHRoZSBib2R5IGlzIGVtcHR5ICh1bmZvcnR1bmF0ZWx5LCB0aGlzIGNoZWNrIGRvZXMgbm90IGNvdmVyIGNodW5rZWQgZW5jb2RpbmcpXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBOztBQUVBLE1BQU07RUFBRUE7QUFBTyxDQUFDLEdBQUdDLE9BQU8sQ0FBQyxVQUFVLENBQUM7QUFDdEMsTUFBTUMsTUFBTSxHQUFHRCxPQUFPLENBQUMsYUFBYSxDQUFDO0FBQ3JDLE1BQU1FLEtBQUssR0FBR0YsT0FBTyxDQUFDLFlBQVksQ0FBQztBQUNuQyxNQUFNRyxJQUFJLEdBQUdILE9BQU8sQ0FBQyxXQUFXLENBQUM7QUFDakMsTUFBTUksRUFBRSxHQUFHSixPQUFPLENBQUMsU0FBUyxDQUFDO0FBQzdCLE1B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