UNPKG

superagent

Version:

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

1,521 lines 151 kB
"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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