platform.wyscout.com Open in urlscan Pro
52.30.223.195  Public Scan

URL: http://platform.wyscout.com/app/platform.engine/ui/js/lib/video-metrics.js?_=1639336379443
Submission: On December 12 via manual from DK — Scanned from DE

Form analysis 0 forms found in the DOM

Text Content

var WyMetrics = (function (exports, _, os, React, PropTypes) {
    'use strict';

    _ = _ && _.hasOwnProperty('default') ? _['default'] : _;
    os = os && os.hasOwnProperty('default') ? os['default'] : os;
    var React__default = 'default' in React ? React['default'] : React;
    PropTypes = PropTypes && PropTypes.hasOwnProperty('default') ? PropTypes['default'] : PropTypes;

    var decodedFrameCount = function decodedFrameCount(video) {
      return video.webkitDecodedFrameCount;
    };

    var decodedVideoByteCount = function decodedVideoByteCount(video) {
      return video.webkitVideoDecodedByteCount;
    };

    var decodedAudioByteCount = function decodedAudioByteCount(video) {
      return video.webkitAudioDecodedByteCount;
    };

    var displayIsFullscreen = function displayIsFullscreen(video) {
      return video.webkitDisplayingFullscreen;
    };

    var displaySupportFullScreen = function displaySupportFullScreen(video) {
      return video.webkitSupportsFullscreen;
    };

    var droppedFrameCount = function droppedFrameCount(video) {
      return video.webkitDroppedFrameCount;
    };

    var duration = function duration(video) {
      return video.duration;
    };

    var paused = function paused(video) {
      return video.paused;
    };

    var currentSrc = function currentSrc(video) {
      return video.currentSrc;
    };

    var networkState = function networkState(video) {
      return video.networkState;
    };

    var currentTime = function currentTime(video) {
      return video.currentTime;
    };

    // import WyAnalytics from '@wyscout/analytics';

    var initAnalytics = function initAnalytics(userId) {
    };

    var restApiBaseName = null;

    var env = process.env.REACT_APP_ENV || process.env.NODE_ENV;

    switch (env) {
        case 'rc':
        case 'release':
            restApiBaseName = 'https://restrc.wyscout.com/';
            break;
        case 'preview':
            restApiBaseName = 'https://restpreview.wyscout.com/';
            break;
        case 'production':
            restApiBaseName = 'https://rest.wyscout.com/';
            break;
        default:
            restApiBaseName = 'https://restbeta.wyscout.com/';
            break;
    }

    var API_HOSTNAME = restApiBaseName;

    var API_SERVER = 'http://5b9249cb4c818e001456e8f5.mockapi.io/video-metrics/v1/';

    var MAX_SEEKING_VIDEO_TAG = 10;

    var MAX_PAUSED_SECONDS = 20;

    var ENABLING_STATUS_MILLISECONDS = 1000 * 60 * 10; // 10 minutes

    var TRANSMISSION_TYPE = {
        REST: 'rest',
        LOGSTASH: 'logstash'
    };

    var NETWORK_STATE = {
        EMPTY: 0,
        IDLE: 1,
        LOADING: 2,
        NO_SOURCE: 3
    };

    var ANALYTICS_APP_SOURCE = 'Video Player';
    var ANALYTICS_DETAILED_SOURCE = {
        VIDEO_START: 'Video Player Auto Start',
        VIDEO_COMPLETED: 'Video Player Completed'
    };

    var PLAYER_TYPE = {
        PLATFORM: 'AEVideo',
        APPS: 'VP2018'
    };

    var WYSCOUT_HOSTNAMES_SUFFIX = {
        DEFAULT: 'wyscout.com',
        RU: 'platform-ru.wyscout.com',
        CN: 'wyscout.cn'
    };

    var bind = function bind(fn, thisArg) {
      return function wrap() {
        var args = new Array(arguments.length);
        for (var i = 0; i < args.length; i++) {
          args[i] = arguments[i];
        }
        return fn.apply(thisArg, args);
      };
    };

    /*!
     * Determine if an object is a Buffer
     *
     * @author   Feross Aboukhadijeh <https://feross.org>
     * @license  MIT
     */

    // The _isBuffer check is for Safari 5-7 support, because it's missing
    // Object.prototype.constructor. Remove this eventually
    var isBuffer_1 = function (obj) {
      return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
    };

    function isBuffer (obj) {
      return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
    }

    // For Node v0.10 support. Remove this eventually.
    function isSlowBuffer (obj) {
      return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
    }

    /*global toString:true*/

    // utils is a library of generic helper functions non-specific to axios

    var toString = Object.prototype.toString;

    /**
     * Determine if a value is an Array
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is an Array, otherwise false
     */
    function isArray(val) {
      return toString.call(val) === '[object Array]';
    }

    /**
     * Determine if a value is an ArrayBuffer
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is an ArrayBuffer, otherwise false
     */
    function isArrayBuffer(val) {
      return toString.call(val) === '[object ArrayBuffer]';
    }

    /**
     * Determine if a value is a FormData
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is an FormData, otherwise false
     */
    function isFormData(val) {
      return (typeof FormData !== 'undefined') && (val instanceof FormData);
    }

    /**
     * Determine if a value is a view on an ArrayBuffer
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
     */
    function isArrayBufferView(val) {
      var result;
      if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {
        result = ArrayBuffer.isView(val);
      } else {
        result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);
      }
      return result;
    }

    /**
     * Determine if a value is a String
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a String, otherwise false
     */
    function isString(val) {
      return typeof val === 'string';
    }

    /**
     * Determine if a value is a Number
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a Number, otherwise false
     */
    function isNumber(val) {
      return typeof val === 'number';
    }

    /**
     * Determine if a value is undefined
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if the value is undefined, otherwise false
     */
    function isUndefined(val) {
      return typeof val === 'undefined';
    }

    /**
     * Determine if a value is an Object
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is an Object, otherwise false
     */
    function isObject(val) {
      return val !== null && typeof val === 'object';
    }

    /**
     * Determine if a value is a Date
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a Date, otherwise false
     */
    function isDate(val) {
      return toString.call(val) === '[object Date]';
    }

    /**
     * Determine if a value is a File
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a File, otherwise false
     */
    function isFile(val) {
      return toString.call(val) === '[object File]';
    }

    /**
     * Determine if a value is a Blob
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a Blob, otherwise false
     */
    function isBlob(val) {
      return toString.call(val) === '[object Blob]';
    }

    /**
     * Determine if a value is a Function
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a Function, otherwise false
     */
    function isFunction(val) {
      return toString.call(val) === '[object Function]';
    }

    /**
     * Determine if a value is a Stream
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a Stream, otherwise false
     */
    function isStream(val) {
      return isObject(val) && isFunction(val.pipe);
    }

    /**
     * Determine if a value is a URLSearchParams object
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a URLSearchParams object, otherwise false
     */
    function isURLSearchParams(val) {
      return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
    }

    /**
     * Trim excess whitespace off the beginning and end of a string
     *
     * @param {String} str The String to trim
     * @returns {String} The String freed of excess whitespace
     */
    function trim(str) {
      return str.replace(/^\s*/, '').replace(/\s*$/, '');
    }

    /**
     * Determine if we're running in a standard browser environment
     *
     * This allows axios to run in a web worker, and react-native.
     * Both environments support XMLHttpRequest, but not fully standard globals.
     *
     * web workers:
     *  typeof window -> undefined
     *  typeof document -> undefined
     *
     * react-native:
     *  navigator.product -> 'ReactNative'
     */
    function isStandardBrowserEnv() {
      if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
        return false;
      }
      return (
        typeof window !== 'undefined' &&
        typeof document !== 'undefined'
      );
    }

    /**
     * Iterate over an Array or an Object invoking a function for each item.
     *
     * If `obj` is an Array callback will be called passing
     * the value, index, and complete array for each item.
     *
     * If 'obj' is an Object callback will be called passing
     * the value, key, and complete object for each property.
     *
     * @param {Object|Array} obj The object to iterate
     * @param {Function} fn The callback to invoke for each item
     */
    function forEach(obj, fn) {
      // Don't bother if no value provided
      if (obj === null || typeof obj === 'undefined') {
        return;
      }

      // Force an array if not already something iterable
      if (typeof obj !== 'object') {
        /*eslint no-param-reassign:0*/
        obj = [obj];
      }

      if (isArray(obj)) {
        // Iterate over array values
        for (var i = 0, l = obj.length; i < l; i++) {
          fn.call(null, obj[i], i, obj);
        }
      } else {
        // Iterate over object keys
        for (var key in obj) {
          if (Object.prototype.hasOwnProperty.call(obj, key)) {
            fn.call(null, obj[key], key, obj);
          }
        }
      }
    }

    /**
     * Accepts varargs expecting each argument to be an object, then
     * immutably merges the properties of each object and returns result.
     *
     * When multiple objects contain the same key the later object in
     * the arguments list will take precedence.
     *
     * Example:
     *
     * ```js
     * var result = merge({foo: 123}, {foo: 456});
     * console.log(result.foo); // outputs 456
     * ```
     *
     * @param {Object} obj1 Object to merge
     * @returns {Object} Result of all merge properties
     */
    function merge(/* obj1, obj2, obj3, ... */) {
      var result = {};
      function assignValue(val, key) {
        if (typeof result[key] === 'object' && typeof val === 'object') {
          result[key] = merge(result[key], val);
        } else {
          result[key] = val;
        }
      }

      for (var i = 0, l = arguments.length; i < l; i++) {
        forEach(arguments[i], assignValue);
      }
      return result;
    }

    /**
     * Extends object a by mutably adding to it the properties of object b.
     *
     * @param {Object} a The object to be extended
     * @param {Object} b The object to copy properties from
     * @param {Object} thisArg The object to bind function to
     * @return {Object} The resulting value of object a
     */
    function extend(a, b, thisArg) {
      forEach(b, function assignValue(val, key) {
        if (thisArg && typeof val === 'function') {
          a[key] = bind(val, thisArg);
        } else {
          a[key] = val;
        }
      });
      return a;
    }

    var utils = {
      isArray: isArray,
      isArrayBuffer: isArrayBuffer,
      isBuffer: isBuffer_1,
      isFormData: isFormData,
      isArrayBufferView: isArrayBufferView,
      isString: isString,
      isNumber: isNumber,
      isObject: isObject,
      isUndefined: isUndefined,
      isDate: isDate,
      isFile: isFile,
      isBlob: isBlob,
      isFunction: isFunction,
      isStream: isStream,
      isURLSearchParams: isURLSearchParams,
      isStandardBrowserEnv: isStandardBrowserEnv,
      forEach: forEach,
      merge: merge,
      extend: extend,
      trim: trim
    };

    var normalizeHeaderName = function normalizeHeaderName(headers, normalizedName) {
      utils.forEach(headers, function processHeader(value, name) {
        if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
          headers[normalizedName] = value;
          delete headers[name];
        }
      });
    };

    /**
     * Update an Error with the specified config, error code, and response.
     *
     * @param {Error} error The error to update.
     * @param {Object} config The config.
     * @param {string} [code] The error code (for example, 'ECONNABORTED').
     * @param {Object} [request] The request.
     * @param {Object} [response] The response.
     * @returns {Error} The error.
     */
    var enhanceError = function enhanceError(error, config, code, request, response) {
      error.config = config;
      if (code) {
        error.code = code;
      }
      error.request = request;
      error.response = response;
      return error;
    };

    /**
     * Create an Error with the specified message, config, error code, request and response.
     *
     * @param {string} message The error message.
     * @param {Object} config The config.
     * @param {string} [code] The error code (for example, 'ECONNABORTED').
     * @param {Object} [request] The request.
     * @param {Object} [response] The response.
     * @returns {Error} The created error.
     */
    var createError = function createError(message, config, code, request, response) {
      var error = new Error(message);
      return enhanceError(error, config, code, request, response);
    };

    /**
     * Resolve or reject a Promise based on response status.
     *
     * @param {Function} resolve A function that resolves the promise.
     * @param {Function} reject A function that rejects the promise.
     * @param {object} response The response.
     */
    var settle = function settle(resolve, reject, response) {
      var validateStatus = response.config.validateStatus;
      // Note: status is not exposed by XDomainRequest
      if (!response.status || !validateStatus || validateStatus(response.status)) {
        resolve(response);
      } else {
        reject(createError(
          'Request failed with status code ' + response.status,
          response.config,
          null,
          response.request,
          response
        ));
      }
    };

    function encode(val) {
      return encodeURIComponent(val).
        replace(/%40/gi, '@').
        replace(/%3A/gi, ':').
        replace(/%24/g, '$').
        replace(/%2C/gi, ',').
        replace(/%20/g, '+').
        replace(/%5B/gi, '[').
        replace(/%5D/gi, ']');
    }

    /**
     * Build a URL by appending params to the end
     *
     * @param {string} url The base of the url (e.g., http://www.google.com)
     * @param {object} [params] The params to be appended
     * @returns {string} The formatted url
     */
    var buildURL = function buildURL(url, params, paramsSerializer) {
      /*eslint no-param-reassign:0*/
      if (!params) {
        return url;
      }

      var serializedParams;
      if (paramsSerializer) {
        serializedParams = paramsSerializer(params);
      } else if (utils.isURLSearchParams(params)) {
        serializedParams = params.toString();
      } else {
        var parts = [];

        utils.forEach(params, function serialize(val, key) {
          if (val === null || typeof val === 'undefined') {
            return;
          }

          if (utils.isArray(val)) {
            key = key + '[]';
          } else {
            val = [val];
          }

          utils.forEach(val, function parseValue(v) {
            if (utils.isDate(v)) {
              v = v.toISOString();
            } else if (utils.isObject(v)) {
              v = JSON.stringify(v);
            }
            parts.push(encode(key) + '=' + encode(v));
          });
        });

        serializedParams = parts.join('&');
      }

      if (serializedParams) {
        url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
      }

      return url;
    };

    // Headers whose duplicates are ignored by node
    // c.f. https://nodejs.org/api/http.html#http_message_headers
    var ignoreDuplicateOf = [
      'age', 'authorization', 'content-length', 'content-type', 'etag',
      'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
      'last-modified', 'location', 'max-forwards', 'proxy-authorization',
      'referer', 'retry-after', 'user-agent'
    ];

    /**
     * Parse headers into an object
     *
     * ```
     * Date: Wed, 27 Aug 2014 08:58:49 GMT
     * Content-Type: application/json
     * Connection: keep-alive
     * Transfer-Encoding: chunked
     * ```
     *
     * @param {String} headers Headers needing to be parsed
     * @returns {Object} Headers parsed into an object
     */
    var parseHeaders = function parseHeaders(headers) {
      var parsed = {};
      var key;
      var val;
      var i;

      if (!headers) { return parsed; }

      utils.forEach(headers.split('\n'), function parser(line) {
        i = line.indexOf(':');
        key = utils.trim(line.substr(0, i)).toLowerCase();
        val = utils.trim(line.substr(i + 1));

        if (key) {
          if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
            return;
          }
          if (key === 'set-cookie') {
            parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
          } else {
            parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
          }
        }
      });

      return parsed;
    };

    var isURLSameOrigin = (
      utils.isStandardBrowserEnv() ?

      // Standard browser envs have full support of the APIs needed to test
      // whether the request URL is of the same origin as current location.
      (function standardBrowserEnv() {
        var msie = /(msie|trident)/i.test(navigator.userAgent);
        var urlParsingNode = document.createElement('a');
        var originURL;

        /**
        * Parse a URL to discover it's components
        *
        * @param {String} url The URL to be parsed
        * @returns {Object}
        */
        function resolveURL(url) {
          var href = url;

          if (msie) {
            // IE needs attribute set twice to normalize properties
            urlParsingNode.setAttribute('href', href);
            href = urlParsingNode.href;
          }

          urlParsingNode.setAttribute('href', href);

          // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
          return {
            href: urlParsingNode.href,
            protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
            host: urlParsingNode.host,
            search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
            hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
            hostname: urlParsingNode.hostname,
            port: urlParsingNode.port,
            pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
                      urlParsingNode.pathname :
                      '/' + urlParsingNode.pathname
          };
        }

        originURL = resolveURL(window.location.href);

        /**
        * Determine if a URL shares the same origin as the current location
        *
        * @param {String} requestURL The URL to test
        * @returns {boolean} True if URL shares the same origin, otherwise false
        */
        return function isURLSameOrigin(requestURL) {
          var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
          return (parsed.protocol === originURL.protocol &&
                parsed.host === originURL.host);
        };
      })() :

      // Non standard browser envs (web workers, react-native) lack needed support.
      (function nonStandardBrowserEnv() {
        return function isURLSameOrigin() {
          return true;
        };
      })()
    );

    // btoa polyfill for IE<10 courtesy https://github.com/davidchambers/Base64.js

    var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

    function E() {
      this.message = 'String contains an invalid character';
    }
    E.prototype = new Error;
    E.prototype.code = 5;
    E.prototype.name = 'InvalidCharacterError';

    function btoa(input) {
      var str = String(input);
      var output = '';
      for (
        // initialize result and counter
        var block, charCode, idx = 0, map = chars;
        // if the next str index does not exist:
        //   change the mapping table to "="
        //   check if d has no fractional digits
        str.charAt(idx | 0) || (map = '=', idx % 1);
        // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
        output += map.charAt(63 & block >> 8 - idx % 1 * 8)
      ) {
        charCode = str.charCodeAt(idx += 3 / 4);
        if (charCode > 0xFF) {
          throw new E();
        }
        block = block << 8 | charCode;
      }
      return output;
    }

    var btoa_1 = btoa;

    var cookies = (
      utils.isStandardBrowserEnv() ?

      // Standard browser envs support document.cookie
      (function standardBrowserEnv() {
        return {
          write: function write(name, value, expires, path, domain, secure) {
            var cookie = [];
            cookie.push(name + '=' + encodeURIComponent(value));

            if (utils.isNumber(expires)) {
              cookie.push('expires=' + new Date(expires).toGMTString());
            }

            if (utils.isString(path)) {
              cookie.push('path=' + path);
            }

            if (utils.isString(domain)) {
              cookie.push('domain=' + domain);
            }

            if (secure === true) {
              cookie.push('secure');
            }

            document.cookie = cookie.join('; ');
          },

          read: function read(name) {
            var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
            return (match ? decodeURIComponent(match[3]) : null);
          },

          remove: function remove(name) {
            this.write(name, '', Date.now() - 86400000);
          }
        };
      })() :

      // Non standard browser env (web workers, react-native) lack needed support.
      (function nonStandardBrowserEnv() {
        return {
          write: function write() {},
          read: function read() { return null; },
          remove: function remove() {}
        };
      })()
    );

    var btoa$1 = (typeof window !== 'undefined' && window.btoa && window.btoa.bind(window)) || btoa_1;

    var xhr = function xhrAdapter(config) {
      return new Promise(function dispatchXhrRequest(resolve, reject) {
        var requestData = config.data;
        var requestHeaders = config.headers;

        if (utils.isFormData(requestData)) {
          delete requestHeaders['Content-Type']; // Let the browser set it
        }

        var request = new XMLHttpRequest();
        var loadEvent = 'onreadystatechange';
        var xDomain = false;

        // For IE 8/9 CORS support
        // Only supports POST and GET calls and doesn't returns the response headers.
        // DON'T do this for testing b/c XMLHttpRequest is mocked, not XDomainRequest.
        if (process.env.NODE_ENV !== 'test' &&
            typeof window !== 'undefined' &&
            window.XDomainRequest && !('withCredentials' in request) &&
            !isURLSameOrigin(config.url)) {
          request = new window.XDomainRequest();
          loadEvent = 'onload';
          xDomain = true;
          request.onprogress = function handleProgress() {};
          request.ontimeout = function handleTimeout() {};
        }

        // HTTP basic authentication
        if (config.auth) {
          var username = config.auth.username || '';
          var password = config.auth.password || '';
          requestHeaders.Authorization = 'Basic ' + btoa$1(username + ':' + password);
        }

        request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true);

        // Set the request timeout in MS
        request.timeout = config.timeout;

        // Listen for ready state
        request[loadEvent] = function handleLoad() {
          if (!request || (request.readyState !== 4 && !xDomain)) {
            return;
          }

          // The request errored out and we didn't get a response, this will be
          // handled by onerror instead
          // With one exception: request that using file: protocol, most browsers
          // will return status as 0 even though it's a successful request
          if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
            return;
          }

          // Prepare the response
          var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;
          var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
          var response = {
            data: responseData,
            // IE sends 1223 instead of 204 (https://github.com/axios/axios/issues/201)
            status: request.status === 1223 ? 204 : request.status,
            statusText: request.status === 1223 ? 'No Content' : request.statusText,
            headers: responseHeaders,
            config: config,
            request: request
          };

          settle(resolve, reject, response);

          // Clean up request
          request = null;
        };

        // Handle low level network errors
        request.onerror = function handleError() {
          // Real errors are hidden from us by the browser
          // onerror should only fire if it's a network error
          reject(createError('Network Error', config, null, request));

          // Clean up request
          request = null;
        };

        // Handle timeout
        request.ontimeout = function handleTimeout() {
          reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',
            request));

          // Clean up request
          request = null;
        };

        // Add xsrf header
        // This is only done if running in a standard browser environment.
        // Specifically not if we're in a web worker, or react-native.
        if (utils.isStandardBrowserEnv()) {
          var cookies$$1 = cookies;

          // Add xsrf header
          var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?
              cookies$$1.read(config.xsrfCookieName) :
              undefined;

          if (xsrfValue) {
            requestHeaders[config.xsrfHeaderName] = xsrfValue;
          }
        }

        // Add headers to the request
        if ('setRequestHeader' in request) {
          utils.forEach(requestHeaders, function setRequestHeader(val, key) {
            if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
              // Remove Content-Type if data is undefined
              delete requestHeaders[key];
            } else {
              // Otherwise add header to the request
              request.setRequestHeader(key, val);
            }
          });
        }

        // Add withCredentials to request if needed
        if (config.withCredentials) {
          request.withCredentials = true;
        }

        // Add responseType to request if needed
        if (config.responseType) {
          try {
            request.responseType = config.responseType;
          } catch (e) {
            // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.
            // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.
            if (config.responseType !== 'json') {
              throw e;
            }
          }
        }

        // Handle progress if needed
        if (typeof config.onDownloadProgress === 'function') {
          request.addEventListener('progress', config.onDownloadProgress);
        }

        // Not all browsers support upload events
        if (typeof config.onUploadProgress === 'function' && request.upload) {
          request.upload.addEventListener('progress', config.onUploadProgress);
        }

        if (config.cancelToken) {
          // Handle cancellation
          config.cancelToken.promise.then(function onCanceled(cancel) {
            if (!request) {
              return;
            }

            request.abort();
            reject(cancel);
            // Clean up request
            request = null;
          });
        }

        if (requestData === undefined) {
          requestData = null;
        }

        // Send the request
        request.send(requestData);
      });
    };

    var DEFAULT_CONTENT_TYPE = {
      'Content-Type': 'application/x-www-form-urlencoded'
    };

    function setContentTypeIfUnset(headers, value) {
      if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {
        headers['Content-Type'] = value;
      }
    }

    function getDefaultAdapter() {
      var adapter;
      if (typeof XMLHttpRequest !== 'undefined') {
        // For browsers use XHR adapter
        adapter = xhr;
      } else if (typeof process !== 'undefined') {
        // For node use HTTP adapter
        adapter = xhr;
      }
      return adapter;
    }

    var defaults = {
      adapter: getDefaultAdapter(),

      transformRequest: [function transformRequest(data, headers) {
        normalizeHeaderName(headers, 'Content-Type');
        if (utils.isFormData(data) ||
          utils.isArrayBuffer(data) ||
          utils.isBuffer(data) ||
          utils.isStream(data) ||
          utils.isFile(data) ||
          utils.isBlob(data)
        ) {
          return data;
        }
        if (utils.isArrayBufferView(data)) {
          return data.buffer;
        }
        if (utils.isURLSearchParams(data)) {
          setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
          return data.toString();
        }
        if (utils.isObject(data)) {
          setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
          return JSON.stringify(data);
        }
        return data;
      }],

      transformResponse: [function transformResponse(data) {
        /*eslint no-param-reassign:0*/
        if (typeof data === 'string') {
          try {
            data = JSON.parse(data);
          } catch (e) { /* Ignore */ }
        }
        return data;
      }],

      /**
       * A timeout in milliseconds to abort a request. If set to 0 (default) a
       * timeout is not created.
       */
      timeout: 0,

      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',

      maxContentLength: -1,

      validateStatus: function validateStatus(status) {
        return status >= 200 && status < 300;
      }
    };

    defaults.headers = {
      common: {
        'Accept': 'application/json, text/plain, */*'
      }
    };

    utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {
      defaults.headers[method] = {};
    });

    utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
      defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
    });

    var defaults_1 = defaults;

    function InterceptorManager() {
      this.handlers = [];
    }

    /**
     * Add a new interceptor to the stack
     *
     * @param {Function} fulfilled The function to handle `then` for a `Promise`
     * @param {Function} rejected The function to handle `reject` for a `Promise`
     *
     * @return {Number} An ID used to remove interceptor later
     */
    InterceptorManager.prototype.use = function use(fulfilled, rejected) {
      this.handlers.push({
        fulfilled: fulfilled,
        rejected: rejected
      });
      return this.handlers.length - 1;
    };

    /**
     * Remove an interceptor from the stack
     *
     * @param {Number} id The ID that was returned by `use`
     */
    InterceptorManager.prototype.eject = function eject(id) {
      if (this.handlers[id]) {
        this.handlers[id] = null;
      }
    };

    /**
     * Iterate over all the registered interceptors
     *
     * This method is particularly useful for skipping over any
     * interceptors that may have become `null` calling `eject`.
     *
     * @param {Function} fn The function to call for each interceptor
     */
    InterceptorManager.prototype.forEach = function forEach(fn) {
      utils.forEach(this.handlers, function forEachHandler(h) {
        if (h !== null) {
          fn(h);
        }
      });
    };

    var InterceptorManager_1 = InterceptorManager;

    /**
     * Transform the data for a request or a response
     *
     * @param {Object|String} data The data to be transformed
     * @param {Array} headers The headers for the request or response
     * @param {Array|Function} fns A single function or Array of functions
     * @returns {*} The resulting transformed data
     */
    var transformData = function transformData(data, headers, fns) {
      /*eslint no-param-reassign:0*/
      utils.forEach(fns, function transform(fn) {
        data = fn(data, headers);
      });

      return data;
    };

    var isCancel = function isCancel(value) {
      return !!(value && value.__CANCEL__);
    };

    /**
     * Determines whether the specified URL is absolute
     *
     * @param {string} url The URL to test
     * @returns {boolean} True if the specified URL is absolute, otherwise false
     */
    var isAbsoluteURL = function isAbsoluteURL(url) {
      // A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
      // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
      // by any combination of letters, digits, plus, period, or hyphen.
      return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
    };

    /**
     * Creates a new URL by combining the specified URLs
     *
     * @param {string} baseURL The base URL
     * @param {string} relativeURL The relative URL
     * @returns {string} The combined URL
     */
    var combineURLs = function combineURLs(baseURL, relativeURL) {
      return relativeURL
        ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
        : baseURL;
    };

    /**
     * Throws a `Cancel` if cancellation has been requested.
     */
    function throwIfCancellationRequested(config) {
      if (config.cancelToken) {
        config.cancelToken.throwIfRequested();
      }
    }

    /**
     * Dispatch a request to the server using the configured adapter.
     *
     * @param {object} config The config that is to be used for the request
     * @returns {Promise} The Promise to be fulfilled
     */
    var dispatchRequest = function dispatchRequest(config) {
      throwIfCancellationRequested(config);

      // Support baseURL config
      if (config.baseURL && !isAbsoluteURL(config.url)) {
        config.url = combineURLs(config.baseURL, config.url);
      }

      // Ensure headers exist
      config.headers = config.headers || {};

      // Transform request data
      config.data = transformData(
        config.data,
        config.headers,
        config.transformRequest
      );

      // Flatten headers
      config.headers = utils.merge(
        config.headers.common || {},
        config.headers[config.method] || {},
        config.headers || {}
      );

      utils.forEach(
        ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
        function cleanHeaderConfig(method) {
          delete config.headers[method];
        }
      );

      var adapter = config.adapter || defaults_1.adapter;

      return adapter(config).then(function onAdapterResolution(response) {
        throwIfCancellationRequested(config);

        // Transform response data
        response.data = transformData(
          response.data,
          response.headers,
          config.transformResponse
        );

        return response;
      }, function onAdapterRejection(reason) {
        if (!isCancel(reason)) {
          throwIfCancellationRequested(config);

          // Transform response data
          if (reason && reason.response) {
            reason.response.data = transformData(
              reason.response.data,
              reason.response.headers,
              config.transformResponse
            );
          }
        }

        return Promise.reject(reason);
      });
    };

    /**
     * Create a new instance of Axios
     *
     * @param {Object} instanceConfig The default config for the instance
     */
    function Axios(instanceConfig) {
      this.defaults = instanceConfig;
      this.interceptors = {
        request: new InterceptorManager_1(),
        response: new InterceptorManager_1()
      };
    }

    /**
     * Dispatch a request
     *
     * @param {Object} config The config specific for this request (merged with this.defaults)
     */
    Axios.prototype.request = function request(config) {
      /*eslint no-param-reassign:0*/
      // Allow for axios('example/url'[, config]) a la fetch API
      if (typeof config === 'string') {
        config = utils.merge({
          url: arguments[0]
        }, arguments[1]);
      }

      config = utils.merge(defaults_1, {method: 'get'}, this.defaults, config);
      config.method = config.method.toLowerCase();

      // Hook up interceptors middleware
      var chain = [dispatchRequest, undefined];
      var promise = Promise.resolve(config);

      this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
        chain.unshift(interceptor.fulfilled, interceptor.rejected);
      });

      this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
        chain.push(interceptor.fulfilled, interceptor.rejected);
      });

      while (chain.length) {
        promise = promise.then(chain.shift(), chain.shift());
      }

      return promise;
    };

    // Provide aliases for supported request methods
    utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
      /*eslint func-names:0*/
      Axios.prototype[method] = function(url, config) {
        return this.request(utils.merge(config || {}, {
          method: method,
          url: url
        }));
      };
    });

    utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
      /*eslint func-names:0*/
      Axios.prototype[method] = function(url, data, config) {
        return this.request(utils.merge(config || {}, {
          method: method,
          url: url,
          data: data
        }));
      };
    });

    var Axios_1 = Axios;

    /**
     * A `Cancel` is an object that is thrown when an operation is canceled.
     *
     * @class
     * @param {string=} message The message.
     */
    function Cancel(message) {
      this.message = message;
    }

    Cancel.prototype.toString = function toString() {
      return 'Cancel' + (this.message ? ': ' + this.message : '');
    };

    Cancel.prototype.__CANCEL__ = true;

    var Cancel_1 = Cancel;

    /**
     * A `CancelToken` is an object that can be used to request cancellation of an operation.
     *
     * @class
     * @param {Function} executor The executor function.
     */
    function CancelToken(executor) {
      if (typeof executor !== 'function') {
        throw new TypeError('executor must be a function.');
      }

      var resolvePromise;
      this.promise = new Promise(function promiseExecutor(resolve) {
        resolvePromise = resolve;
      });

      var token = this;
      executor(function cancel(message) {
        if (token.reason) {
          // Cancellation has already been requested
          return;
        }

        token.reason = new Cancel_1(message);
        resolvePromise(token.reason);
      });
    }

    /**
     * Throws a `Cancel` if cancellation has been requested.
     */
    CancelToken.prototype.throwIfRequested = function throwIfRequested() {
      if (this.reason) {
        throw this.reason;
      }
    };

    /**
     * Returns an object that contains a new `CancelToken` and a function that, when called,
     * cancels the `CancelToken`.
     */
    CancelToken.source = function source() {
      var cancel;
      var token = new CancelToken(function executor(c) {
        cancel = c;
      });
      return {
        token: token,
        cancel: cancel
      };
    };

    var CancelToken_1 = CancelToken;

    /**
     * Syntactic sugar for invoking a function and expanding an array for arguments.
     *
     * Common use case would be to use `Function.prototype.apply`.
     *
     *  ```js
     *  function f(x, y, z) {}
     *  var args = [1, 2, 3];
     *  f.apply(null, args);
     *  ```
     *
     * With `spread` this example can be re-written.
     *
     *  ```js
     *  spread(function(x, y, z) {})([1, 2, 3]);
     *  ```
     *
     * @param {Function} callback
     * @returns {Function}
     */
    var spread = function spread(callback) {
      return function wrap(arr) {
        return callback.apply(null, arr);
      };
    };

    /**
     * Create an instance of Axios
     *
     * @param {Object} defaultConfig The default config for the instance
     * @return {Axios} A new instance of Axios
     */
    function createInstance(defaultConfig) {
      var context = new Axios_1(defaultConfig);
      var instance = bind(Axios_1.prototype.request, context);

      // Copy axios.prototype to instance
      utils.extend(instance, Axios_1.prototype, context);

      // Copy context to instance
      utils.extend(instance, context);

      return instance;
    }

    // Create the default instance to be exported
    var axios = createInstance(defaults_1);

    // Expose Axios class to allow class inheritance
    axios.Axios = Axios_1;

    // Factory for creating new instances
    axios.create = function create(instanceConfig) {
      return createInstance(utils.merge(defaults_1, instanceConfig));
    };

    // Expose Cancel & CancelToken
    axios.Cancel = Cancel_1;
    axios.CancelToken = CancelToken_1;
    axios.isCancel = isCancel;

    // Expose all/spread
    axios.all = function all(promises) {
      return Promise.all(promises);
    };
    axios.spread = spread;

    var axios_1 = axios;

    // Allow use of default import syntax in TypeScript
    var default_1 = axios;
    axios_1.default = default_1;

    var axios$1 = axios_1;

    var bind$1 = function bind(fn, thisArg) {
      return function wrap() {
        var args = new Array(arguments.length);
        for (var i = 0; i < args.length; i++) {
          args[i] = arguments[i];
        }
        return fn.apply(thisArg, args);
      };
    };

    /*global toString:true*/

    // utils is a library of generic helper functions non-specific to axios

    var toString$1 = Object.prototype.toString;

    /**
     * Determine if a value is an Array
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is an Array, otherwise false
     */
    function isArray$1(val) {
      return toString$1.call(val) === '[object Array]';
    }

    /**
     * Determine if a value is an ArrayBuffer
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is an ArrayBuffer, otherwise false
     */
    function isArrayBuffer$1(val) {
      return toString$1.call(val) === '[object ArrayBuffer]';
    }

    /**
     * Determine if a value is a FormData
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is an FormData, otherwise false
     */
    function isFormData$1(val) {
      return (typeof FormData !== 'undefined') && (val instanceof FormData);
    }

    /**
     * Determine if a value is a view on an ArrayBuffer
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
     */
    function isArrayBufferView$1(val) {
      var result;
      if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {
        result = ArrayBuffer.isView(val);
      } else {
        result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);
      }
      return result;
    }

    /**
     * Determine if a value is a String
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a String, otherwise false
     */
    function isString$1(val) {
      return typeof val === 'string';
    }

    /**
     * Determine if a value is a Number
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a Number, otherwise false
     */
    function isNumber$1(val) {
      return typeof val === 'number';
    }

    /**
     * Determine if a value is undefined
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if the value is undefined, otherwise false
     */
    function isUndefined$1(val) {
      return typeof val === 'undefined';
    }

    /**
     * Determine if a value is an Object
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is an Object, otherwise false
     */
    function isObject$1(val) {
      return val !== null && typeof val === 'object';
    }

    /**
     * Determine if a value is a Date
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a Date, otherwise false
     */
    function isDate$1(val) {
      return toString$1.call(val) === '[object Date]';
    }

    /**
     * Determine if a value is a File
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a File, otherwise false
     */
    function isFile$1(val) {
      return toString$1.call(val) === '[object File]';
    }

    /**
     * Determine if a value is a Blob
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a Blob, otherwise false
     */
    function isBlob$1(val) {
      return toString$1.call(val) === '[object Blob]';
    }

    /**
     * Determine if a value is a Function
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a Function, otherwise false
     */
    function isFunction$1(val) {
      return toString$1.call(val) === '[object Function]';
    }

    /**
     * Determine if a value is a Stream
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a Stream, otherwise false
     */
    function isStream$1(val) {
      return isObject$1(val) && isFunction$1(val.pipe);
    }

    /**
     * Determine if a value is a URLSearchParams object
     *
     * @param {Object} val The value to test
     * @returns {boolean} True if value is a URLSearchParams object, otherwise false
     */
    function isURLSearchParams$1(val) {
      return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
    }

    /**
     * Trim excess whitespace off the beginning and end of a string
     *
     * @param {String} str The String to trim
     * @returns {String} The String freed of excess whitespace
     */
    function trim$1(str) {
      return str.replace(/^\s*/, '').replace(/\s*$/, '');
    }

    /**
     * Determine if we're running in a standard browser environment
     *
     * This allows axios to run in a web worker, and react-native.
     * Both environments support XMLHttpRequest, but not fully standard globals.
     *
     * web workers:
     *  typeof window -> undefined
     *  typeof document -> undefined
     *
     * react-native:
     *  navigator.product -> 'ReactNative'
     */
    function isStandardBrowserEnv$1() {
      if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
        return false;
      }
      return (
        typeof window !== 'undefined' &&
        typeof document !== 'undefined'
      );
    }

    /**
     * Iterate over an Array or an Object invoking a function for each item.
     *
     * If `obj` is an Array callback will be called passing
     * the value, index, and complete array for each item.
     *
     * If 'obj' is an Object callback will be called passing
     * the value, key, and complete object for each property.
     *
     * @param {Object|Array} obj The object to iterate
     * @param {Function} fn The callback to invoke for each item
     */
    function forEach$1(obj, fn) {
      // Don't bother if no value provided
      if (obj === null || typeof obj === 'undefined') {
        return;
      }

      // Force an array if not already something iterable
      if (typeof obj !== 'object') {
        /*eslint no-param-reassign:0*/
        obj = [obj];
      }

      if (isArray$1(obj)) {
        // Iterate over array values
        for (var i = 0, l = obj.length; i < l; i++) {
          fn.call(null, obj[i], i, obj);
        }
      } else {
        // Iterate over object keys
        for (var key in obj) {
          if (Object.prototype.hasOwnProperty.call(obj, key)) {
            fn.call(null, obj[key], key, obj);
          }
        }
      }
    }

    /**
     * Accepts varargs expecting each argument to be an object, then
     * immutably merges the properties of each object and returns result.
     *
     * When multiple objects contain the same key the later object in
     * the arguments list will take precedence.
     *
     * Example:
     *
     * ```js
     * var result = merge({foo: 123}, {foo: 456});
     * console.log(result.foo); // outputs 456
     * ```
     *
     * @param {Object} obj1 Object to merge
     * @returns {Object} Result of all merge properties
     */
    function merge$1(/* obj1, obj2, obj3, ... */) {
      var result = {};
      function assignValue(val, key) {
        if (typeof result[key] === 'object' && typeof val === 'object') {
          result[key] = merge$1(result[key], val);
        } else {
          result[key] = val;
        }
      }

      for (var i = 0, l = arguments.length; i < l; i++) {
        forEach$1(arguments[i], assignValue);
      }
      return result;
    }

    /**
     * Extends object a by mutably adding to it the properties of object b.
     *
     * @param {Object} a The object to be extended
     * @param {Object} b The object to copy properties from
     * @param {Object} thisArg The object to bind function to
     * @return {Object} The resulting value of object a
     */
    function extend$1(a, b, thisArg) {
      forEach$1(b, function assignValue(val, key) {
        if (thisArg && typeof val === 'function') {
          a[key] = bind$1(val, thisArg);
        } else {
          a[key] = val;
        }
      });
      return a;
    }

    var utils$1 = {
      isArray: isArray$1,
      isArrayBuffer: isArrayBuffer$1,
      isBuffer: isBuffer_1,
      isFormData: isFormData$1,
      isArrayBufferView: isArrayBufferView$1,
      isString: isString$1,
      isNumber: isNumber$1,
      isObject: isObject$1,
      isUndefined: isUndefined$1,
      isDate: isDate$1,
      isFile: isFile$1,
      isBlob: isBlob$1,
      isFunction: isFunction$1,
      isStream: isStream$1,
      isURLSearchParams: isURLSearchParams$1,
      isStandardBrowserEnv: isStandardBrowserEnv$1,
      forEach: forEach$1,
      merge: merge$1,
      extend: extend$1,
      trim: trim$1
    };

    var normalizeHeaderName$1 = function normalizeHeaderName(headers, normalizedName) {
      utils$1.forEach(headers, function processHeader(value, name) {
        if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
          headers[normalizedName] = value;
          delete headers[name];
        }
      });
    };

    /**
     * Update an Error with the specified config, error code, and response.
     *
     * @param {Error} error The error to update.
     * @param {Object} config The config.
     * @param {string} [code] The error code (for example, 'ECONNABORTED').
     * @param {Object} [request] The request.
     * @param {Object} [response] The response.
     * @returns {Error} The error.
     */
    var enhanceError$1 = function enhanceError(error, config, code, request, response) {
      error.config = config;
      if (code) {
        error.code = code;
      }
      error.request = request;
      error.response = response;
      return error;
    };

    /**
     * Create an Error with the specified message, config, error code, request and response.
     *
     * @param {string} message The error message.
     * @param {Object} config The config.
     * @param {string} [code] The error code (for example, 'ECONNABORTED').
     * @param {Object} [request] The request.
     * @param {Object} [response] The response.
     * @returns {Error} The created error.
     */
    var createError$1 = function createError(message, config, code, request, response) {
      var error = new Error(message);
      return enhanceError$1(error, config, code, request, response);
    };

    /**
     * Resolve or reject a Promise based on response status.
     *
     * @param {Function} resolve A function that resolves the promise.
     * @param {Function} reject A function that rejects the promise.
     * @param {object} response The response.
     */
    var settle$1 = function settle(resolve, reject, response) {
      var validateStatus = response.config.validateStatus;
      // Note: status is not exposed by XDomainRequest
      if (!response.status || !validateStatus || validateStatus(response.status)) {
        resolve(response);
      } else {
        reject(createError$1(
          'Request failed with status code ' + response.status,
          response.config,
          null,
          response.request,
          response
        ));
      }
    };

    function encode$1(val) {
      return encodeURIComponent(val).
        replace(/%40/gi, '@').
        replace(/%3A/gi, ':').
        replace(/%24/g, '$').
        replace(/%2C/gi, ',').
        replace(/%20/g, '+').
        replace(/%5B/gi, '[').
        replace(/%5D/gi, ']');
    }

    /**
     * Build a URL by appending params to the end
     *
     * @param {string} url The base of the url (e.g., http://www.google.com)
     * @param {object} [params] The params to be appended
     * @returns {string} The formatted url
     */
    var buildURL$1 = function buildURL(url, params, paramsSerializer) {
      /*eslint no-param-reassign:0*/
      if (!params) {
        return url;
      }

      var serializedParams;
      if (paramsSerializer) {
        serializedParams = paramsSerializer(params);
      } else if (utils$1.isURLSearchParams(params)) {
        serializedParams = params.toString();
      } else {
        var parts = [];

        utils$1.forEach(params, function serialize(val, key) {
          if (val === null || typeof val === 'undefined') {
            return;
          }

          if (utils$1.isArray(val)) {
            key = key + '[]';
          }

          if (!utils$1.isArray(val)) {
            val = [val];
          }

          utils$1.forEach(val, function parseValue(v) {
            if (utils$1.isDate(v)) {
              v = v.toISOString();
            } else if (utils$1.isObject(v)) {
              v = JSON.stringify(v);
            }
            parts.push(encode$1(key) + '=' + encode$1(v));
          });
        });

        serializedParams = parts.join('&');
      }

      if (serializedParams) {
        url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
      }

      return url;
    };

    // Headers whose duplicates are ignored by node
    // c.f. https://nodejs.org/api/http.html#http_message_headers
    var ignoreDuplicateOf$1 = [
      'age', 'authorization', 'content-length', 'content-type', 'etag',
      'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
      'last-modified', 'location', 'max-forwards', 'proxy-authorization',
      'referer', 'retry-after', 'user-agent'
    ];

    /**
     * Parse headers into an object
     *
     * ```
     * Date: Wed, 27 Aug 2014 08:58:49 GMT
     * Content-Type: application/json
     * Connection: keep-alive
     * Transfer-Encoding: chunked
     * ```
     *
     * @param {String} headers Headers needing to be parsed
     * @returns {Object} Headers parsed into an object
     */
    var parseHeaders$1 = function parseHeaders(headers) {
      var parsed = {};
      var key;
      var val;
      var i;

      if (!headers) { return parsed; }

      utils$1.forEach(headers.split('\n'), function parser(line) {
        i = line.indexOf(':');
        key = utils$1.trim(line.substr(0, i)).toLowerCase();
        val = utils$1.trim(line.substr(i + 1));

        if (key) {
          if (parsed[key] && ignoreDuplicateOf$1.indexOf(key) >= 0) {
            return;
          }
          if (key === 'set-cookie') {
            parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
          } else {
            parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
          }
        }
      });

      return parsed;
    };

    var isURLSameOrigin$1 = (
      utils$1.isStandardBrowserEnv() ?

      // Standard browser envs have full support of the APIs needed to test
      // whether the request URL is of the same origin as current location.
      (function standardBrowserEnv() {
        var msie = /(msie|trident)/i.test(navigator.userAgent);
        var urlParsingNode = document.createElement('a');
        var originURL;

        /**
        * Parse a URL to discover it's components
        *
        * @param {String} url The URL to be parsed
        * @returns {Object}
        */
        function resolveURL(url) {
          var href = url;

          if (msie) {
            // IE needs attribute set twice to normalize properties
            urlParsingNode.setAttribute('href', href);
            href = urlParsingNode.href;
          }

          urlParsingNode.setAttribute('href', href);

          // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
          return {
            href: urlParsingNode.href,
            protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
            host: urlParsingNode.host,
            search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
            hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
            hostname: urlParsingNode.hostname,
            port: urlParsingNode.port,
            pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
                      urlParsingNode.pathname :
                      '/' + urlParsingNode.pathname
          };
        }

        originURL = resolveURL(window.location.href);

        /**
        * Determine if a URL shares the same origin as the current location
        *
        * @param {String} requestURL The URL to test
        * @returns {boolean} True if URL shares the same origin, otherwise false
        */
        return function isURLSameOrigin(requestURL) {
          var parsed = (utils$1.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
          return (parsed.protocol === originURL.protocol &&
                parsed.host === originURL.host);
        };
      })() :

      // Non standard browser envs (web workers, react-native) lack needed support.
      (function nonStandardBrowserEnv() {
        return function isURLSameOrigin() {
          return true;
        };
      })()
    );

    // btoa polyfill for IE<10 courtesy https://github.com/davidchambers/Base64.js

    var chars$1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

    function E$1() {
      this.message = 'String contains an invalid character';
    }
    E$1.prototype = new Error;
    E$1.prototype.code = 5;
    E$1.prototype.name = 'InvalidCharacterError';

    function btoa$2(input) {
      var str = String(input);
      var output = '';
      for (
        // initialize result and counter
        var block, charCode, idx = 0, map = chars$1;
        // if the next str index does not exist:
        //   change the mapping table to "="
        //   check if d has no fractional digits
        str.charAt(idx | 0) || (map = '=', idx % 1);
        // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
        output += map.charAt(63 & block >> 8 - idx % 1 * 8)
      ) {
        charCode = str.charCodeAt(idx += 3 / 4);
        if (charCode > 0xFF) {
          throw new E$1();
        }
        block = block << 8 | charCode;
      }
      return output;
    }

    var btoa_1$1 = btoa$2;

    var cookies$1 = (
      utils$1.isStandardBrowserEnv() ?

      // Standard browser envs support document.cookie
      (function standardBrowserEnv() {
        return {
          write: function write(name, value, expires, path, domain, secure) {
            var cookie = [];
            cookie.push(name + '=' + encodeURIComponent(value));

            if (utils$1.isNumber(expires)) {
              cookie.push('expires=' + new Date(expires).toGMTString());
            }

            if (utils$1.isString(path)) {
              cookie.push('path=' + path);
            }

            if (utils$1.isString(domain)) {
              cookie.push('domain=' + domain);
            }

            if (secure === true) {
              cookie.push('secure');
            }

            document.cookie = cookie.join('; ');
          },

          read: function read(name) {
            var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
            return (match ? decodeURIComponent(match[3]) : null);
          },

          remove: function remove(name) {
            this.write(name, '', Date.now() - 86400000);
          }
        };
      })() :

      // Non standard browser env (web workers, react-native) lack needed support.
      (function nonStandardBrowserEnv() {
        return {
          write: function write() {},
          read: function read() { return null; },
          remove: function remove() {}
        };
      })()
    );

    var btoa$3 = (typeof window !== 'undefined' && window.btoa && window.btoa.bind(window)) || btoa_1$1;

    var xhr$1 = function xhrAdapter(config) {
      return new Promise(function dispatchXhrRequest(resolve, reject) {
        var requestData = config.data;
        var requestHeaders = config.headers;

        if (utils$1.isFormData(requestData)) {
          delete requestHeaders['Content-Type']; // Let the browser set it
        }

        var request = new XMLHttpRequest();
        var loadEvent = 'onreadystatechange';
        var xDomain = false;

        // For IE 8/9 CORS support
        // Only supports POST and GET calls and doesn't returns the response headers.
        // DON'T do this for testing b/c XMLHttpRequest is mocked, not XDomainRequest.
        if (process.env.NODE_ENV !== 'test' &&
            typeof window !== 'undefined' &&
            window.XDomainRequest && !('withCredentials' in request) &&
            !isURLSameOrigin$1(config.url)) {
          request = new window.XDomainRequest();
          loadEvent = 'onload';
          xDomain = true;
          request.onprogress = function handleProgress() {};
          request.ontimeout = function handleTimeout() {};
        }

        // HTTP basic authentication
        if (config.auth) {
          var username = config.auth.username || '';
          var password = config.auth.password || '';
          requestHeaders.Authorization = 'Basic ' + btoa$3(username + ':' + password);
        }

        request.open(config.method.toUpperCase(), buildURL$1(config.url, config.params, config.paramsSerializer), true);

        // Set the request timeout in MS
        request.timeout = config.timeout;

        // Listen for ready state
        request[loadEvent] = function handleLoad() {
          if (!request || (request.readyState !== 4 && !xDomain)) {
            return;
          }

          // The request errored out and we didn't get a response, this will be
          // handled by onerror instead
          // With one exception: request that using file: protocol, most browsers
          // will return status as 0 even though it's a successful request
          if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
            return;
          }

          // Prepare the response
          var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders$1(request.getAllResponseHeaders()) : null;
          var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
          var response = {
            data: responseData,
            // IE sends 1223 instead of 204 (https://github.com/axios/axios/issues/201)
            status: request.status === 1223 ? 204 : request.status,
            statusText: request.status === 1223 ? 'No Content' : request.statusText,
            headers: responseHeaders,
            config: config,
            request: request
          };

          settle$1(resolve, reject, response);

          // Clean up request
          request = null;
        };

        // Handle low level network errors
        request.onerror = function handleError() {
          // Real errors are hidden from us by the browser
          // onerror should only fire if it's a network error
          reject(createError$1('Network Error', config, null, request));

          // Clean up request
          request = null;
        };

        // Handle timeout
        request.ontimeout = function handleTimeout() {
          reject(createError$1('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',
            request));

          // Clean up request
          request = null;
        };

        // Add xsrf header
        // This is only done if running in a standard browser environment.
        // Specifically not if we're in a web worker, or react-native.
        if (utils$1.isStandardBrowserEnv()) {
          var cookies = cookies$1;

          // Add xsrf header
          var xsrfValue = (config.withCredentials || isURLSameOrigin$1(config.url)) && config.xsrfCookieName ?
              cookies.read(config.xsrfCookieName) :
              undefined;

          if (xsrfValue) {
            requestHeaders[config.xsrfHeaderName] = xsrfValue;
          }
        }

        // Add headers to the request
        if ('setRequestHeader' in request) {
          utils$1.forEach(requestHeaders, function setRequestHeader(val, key) {
            if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
              // Remove Content-Type if data is undefined
              delete requestHeaders[key];
            } else {
              // Otherwise add header to the request
              request.setRequestHeader(key, val);
            }
          });
        }

        // Add withCredentials to request if needed
        if (config.withCredentials) {
          request.withCredentials = true;
        }

        // Add responseType to request if needed
        if (config.responseType) {
          try {
            request.responseType = config.responseType;
          } catch (e) {
            // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.
            // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.
            if (config.responseType !== 'json') {
              throw e;
            }
          }
        }

        // Handle progress if needed
        if (typeof config.onDownloadProgress === 'function') {
          request.addEventListener('progress', config.onDownloadProgress);
        }

        // Not all browsers support upload events
        if (typeof config.onUploadProgress === 'function' && request.upload) {
          request.upload.addEventListener('progress', config.onUploadProgress);
        }

        if (config.cancelToken) {
          // Handle cancellation
          config.cancelToken.promise.then(function onCanceled(cancel) {
            if (!request) {
              return;
            }

            request.abort();
            reject(cancel);
            // Clean up request
            request = null;
          });
        }

        if (requestData === undefined) {
          requestData = null;
        }

        // Send the request
        request.send(requestData);
      });
    };

    var DEFAULT_CONTENT_TYPE$1 = {
      'Content-Type': 'application/x-www-form-urlencoded'
    };

    function setContentTypeIfUnset$1(headers, value) {
      if (!utils$1.isUndefined(headers) && utils$1.isUndefined(headers['Content-Type'])) {
        headers['Content-Type'] = value;
      }
    }

    function getDefaultAdapter$1() {
      var adapter;
      if (typeof XMLHttpRequest !== 'undefined') {
        // For browsers use XHR adapter
        adapter = xhr$1;
      } else if (typeof process !== 'undefined') {
        // For node use HTTP adapter
        adapter = xhr$1;
      }
      return adapter;
    }

    var defaults$1 = {
      adapter: getDefaultAdapter$1(),

      transformRequest: [function transformRequest(data, headers) {
        normalizeHeaderName$1(headers, 'Content-Type');
        if (utils$1.isFormData(data) ||
          utils$1.isArrayBuffer(data) ||
          utils$1.isBuffer(data) ||
          utils$1.isStream(data) ||
          utils$1.isFile(data) ||
          utils$1.isBlob(data)
        ) {
          return data;
        }
        if (utils$1.isArrayBufferView(data)) {
          return data.buffer;
        }
        if (utils$1.isURLSearchParams(data)) {
          setContentTypeIfUnset$1(headers, 'application/x-www-form-urlencoded;charset=utf-8');
          return data.toString();
        }
        if (utils$1.isObject(data)) {
          setContentTypeIfUnset$1(headers, 'application/json;charset=utf-8');
          return JSON.stringify(data);
        }
        return data;
      }],

      transformResponse: [function transformResponse(data) {
        /*eslint no-param-reassign:0*/
        if (typeof data === 'string') {
          try {
            data = JSON.parse(data);
          } catch (e) { /* Ignore */ }
        }
        return data;
      }],

      timeout: 0,

      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',

      maxContentLength: -1,

      validateStatus: function validateStatus(status) {
        return status >= 200 && status < 300;
      }
    };

    defaults$1.headers = {
      common: {
        'Accept': 'application/json, text/plain, */*'
      }
    };

    utils$1.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {
      defaults$1.headers[method] = {};
    });

    utils$1.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
      defaults$1.headers[method] = utils$1.merge(DEFAULT_CONTENT_TYPE$1);
    });

    var defaults_1$1 = defaults$1;

    function InterceptorManager$1() {
      this.handlers = [];
    }

    /**
     * Add a new interceptor to the stack
     *
     * @param {Function} fulfilled The function to handle `then` for a `Promise`
     * @param {Function} rejected The function to handle `reject` for a `Promise`
     *
     * @return {Number} An ID used to remove interceptor later
     */
    InterceptorManager$1.prototype.use = function use(fulfilled, rejected) {
      this.handlers.push({
        fulfilled: fulfilled,
        rejected: rejected
      });
      return this.handlers.length - 1;
    };

    /**
     * Remove an interceptor from the stack
     *
     * @param {Number} id The ID that was returned by `use`
     */
    InterceptorManager$1.prototype.eject = function eject(id) {
      if (this.handlers[id]) {
        this.handlers[id] = null;
      }
    };

    /**
     * Iterate over all the registered interceptors
     *
     * This method is particularly useful for skipping over any
     * interceptors that may have become `null` calling `eject`.
     *
     * @param {Function} fn The function to call for each interceptor
     */
    InterceptorManager$1.prototype.forEach = function forEach(fn) {
      utils$1.forEach(this.handlers, function forEachHandler(h) {
        if (h !== null) {
          fn(h);
        }
      });
    };

    var InterceptorManager_1$1 = InterceptorManager$1;

    /**
     * Transform the data for a request or a response
     *
     * @param {Object|String} data The data to be transformed
     * @param {Array} headers The headers for the request or response
     * @param {Array|Function} fns A single function or Array of functions
     * @returns {*} The resulting transformed data
     */
    var transformData$1 = function transformData(data, headers, fns) {
      /*eslint no-param-reassign:0*/
      utils$1.forEach(fns, function transform(fn) {
        data = fn(data, headers);
      });

      return data;
    };

    var isCancel$1 = function isCancel(value) {
      return !!(value && value.__CANCEL__);
    };

    /**
     * Determines whether the specified URL is absolute
     *
     * @param {string} url The URL to test
     * @returns {boolean} True if the specified URL is absolute, otherwise false
     */
    var isAbsoluteURL$1 = function isAbsoluteURL(url) {
      // A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
      // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
      // by any combination of letters, digits, plus, period, or hyphen.
      return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
    };

    /**
     * Creates a new URL by combining the specified URLs
     *
     * @param {string} baseURL The base URL
     * @param {string} relativeURL The relative URL
     * @returns {string} The combined URL
     */
    var combineURLs$1 = function combineURLs(baseURL, relativeURL) {
      return relativeURL
        ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
        : baseURL;
    };

    /**
     * Throws a `Cancel` if cancellation has been requested.
     */
    function throwIfCancellationRequested$1(config) {
      if (config.cancelToken) {
        config.cancelToken.throwIfRequested();
      }
    }

    /**
     * Dispatch a request to the server using the configured adapter.
     *
     * @param {object} config The config that is to be used for the request
     * @returns {Promise} The Promise to be fulfilled
     */
    var dispatchRequest$1 = function dispatchRequest(config) {
      throwIfCancellationRequested$1(config);

      // Support baseURL config
      if (config.baseURL && !isAbsoluteURL$1(config.url)) {
        config.url = combineURLs$1(config.baseURL, config.url);
      }

      // Ensure headers exist
      config.headers = config.headers || {};

      // Transform request data
      config.data = transformData$1(
        config.data,
        config.headers,
        config.transformRequest
      );

      // Flatten headers
      config.headers = utils$1.merge(
        config.headers.common || {},
        config.headers[config.method] || {},
        config.headers || {}
      );

      utils$1.forEach(
        ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
        function cleanHeaderConfig(method) {
          delete config.headers[method];
        }
      );

      var adapter = config.adapter || defaults_1$1.adapter;

      return adapter(config).then(function onAdapterResolution(response) {
        throwIfCancellationRequested$1(config);

        // Transform response data
        response.data = transformData$1(
          response.data,
          response.headers,
          config.transformResponse
        );

        return response;
      }, function onAdapterRejection(reason) {
        if (!isCancel$1(reason)) {
          throwIfCancellationRequested$1(config);

          // Transform response data
          if (reason && reason.response) {
            reason.response.data = transformData$1(
              reason.response.data,
              reason.response.headers,
              config.transformResponse
            );
          }
        }

        return Promise.reject(reason);
      });
    };

    /**
     * Create a new instance of Axios
     *
     * @param {Object} instanceConfig The default config for the instance
     */
    function Axios$1(instanceConfig) {
      this.defaults = instanceConfig;
      this.interceptors = {
        request: new InterceptorManager_1$1(),
        response: new InterceptorManager_1$1()
      };
    }

    /**
     * Dispatch a request
     *
     * @param {Object} config The config specific for this request (merged with this.defaults)
     */
    Axios$1.prototype.request = function request(config) {
      /*eslint no-param-reassign:0*/
      // Allow for axios('example/url'[, config]) a la fetch API
      if (typeof config === 'string') {
        config = utils$1.merge({
          url: arguments[0]
        }, arguments[1]);
      }

      config = utils$1.merge(defaults_1$1, this.defaults, { method: 'get' }, config);
      config.method = config.method.toLowerCase();

      // Hook up interceptors middleware
      var chain = [dispatchRequest$1, undefined];
      var promise = Promise.resolve(config);

      this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
        chain.unshift(interceptor.fulfilled, interceptor.rejected);
      });

      this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
        chain.push(interceptor.fulfilled, interceptor.rejected);
      });

      while (chain.length) {
        promise = promise.then(chain.shift(), chain.shift());
      }

      return promise;
    };

    // Provide aliases for supported request methods
    utils$1.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
      /*eslint func-names:0*/
      Axios$1.prototype[method] = function(url, config) {
        return this.request(utils$1.merge(config || {}, {
          method: method,
          url: url
        }));
      };
    });

    utils$1.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
      /*eslint func-names:0*/
      Axios$1.prototype[method] = function(url, data, config) {
        return this.request(utils$1.merge(config || {}, {
          method: method,
          url: url,
          data: data
        }));
      };
    });

    var Axios_1$1 = Axios$1;

    /**
     * A `Cancel` is an object that is thrown when an operation is canceled.
     *
     * @class
     * @param {string=} message The message.
     */
    function Cancel$1(message) {
      this.message = message;
    }

    Cancel$1.prototype.toString = function toString() {
      return 'Cancel' + (this.message ? ': ' + this.message : '');
    };

    Cancel$1.prototype.__CANCEL__ = true;

    var Cancel_1$1 = Cancel$1;

    /**
     * A `CancelToken` is an object that can be used to request cancellation of an operation.
     *
     * @class
     * @param {Function} executor The executor function.
     */
    function CancelToken$1(executor) {
      if (typeof executor !== 'function') {
        throw new TypeError('executor must be a function.');
      }

      var resolvePromise;
      this.promise = new Promise(function promiseExecutor(resolve) {
        resolvePromise = resolve;
      });

      var token = this;
      executor(function cancel(message) {
        if (token.reason) {
          // Cancellation has already been requested
          return;
        }

        token.reason = new Cancel_1$1(message);
        resolvePromise(token.reason);
      });
    }

    /**
     * Throws a `Cancel` if cancellation has been requested.
     */
    CancelToken$1.prototype.throwIfRequested = function throwIfRequested() {
      if (this.reason) {
        throw this.reason;
      }
    };

    /**
     * Returns an object that contains a new `CancelToken` and a function that, when called,
     * cancels the `CancelToken`.
     */
    CancelToken$1.source = function source() {
      var cancel;
      var token = new CancelToken$1(function executor(c) {
        cancel = c;
      });
      return {
        token: token,
        cancel: cancel
      };
    };

    var CancelToken_1$1 = CancelToken$1;

    /**
     * Syntactic sugar for invoking a function and expanding an array for arguments.
     *
     * Common use case would be to use `Function.prototype.apply`.
     *
     *  ```js
     *  function f(x, y, z) {}
     *  var args = [1, 2, 3];
     *  f.apply(null, args);
     *  ```
     *
     * With `spread` this example can be re-written.
     *
     *  ```js
     *  spread(function(x, y, z) {})([1, 2, 3]);
     *  ```
     *
     * @param {Function} callback
     * @returns {Function}
     */
    var spread$1 = function spread(callback) {
      return function wrap(arr) {
        return callback.apply(null, arr);
      };
    };

    /**
     * Create an instance of Axios
     *
     * @param {Object} defaultConfig The default config for the instance
     * @return {Axios} A new instance of Axios
     */
    function createInstance$1(defaultConfig) {
      var context = new Axios_1$1(defaultConfig);
      var instance = bind$1(Axios_1$1.prototype.request, context);

      // Copy axios.prototype to instance
      utils$1.extend(instance, Axios_1$1.prototype, context);

      // Copy context to instance
      utils$1.extend(instance, context);

      return instance;
    }

    // Create the default instance to be exported
    var axios$2 = createInstance$1(defaults_1$1);

    // Expose Axios class to allow class inheritance
    axios$2.Axios = Axios_1$1;

    // Factory for creating new instances
    axios$2.create = function create(instanceConfig) {
      return createInstance$1(utils$1.merge(defaults_1$1, instanceConfig));
    };

    // Expose Cancel & CancelToken
    axios$2.Cancel = Cancel_1$1;
    axios$2.CancelToken = CancelToken_1$1;
    axios$2.isCancel = isCancel$1;

    // Expose all/spread
    axios$2.all = function all(promises) {
      return Promise.all(promises);
    };
    axios$2.spread = spread$1;

    var axios_1$1 = axios$2;

    // Allow use of default import syntax in TypeScript
    var default_1$1 = axios$2;
    axios_1$1.default = default_1$1;

    var axios$3 = axios_1$1;

    function create(url, tags, level) {
      var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};

      return new Logstash(url, tags, level, options);
    }

    function Logstash(url) {
      var tags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
      var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "info";
      var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};

      if (!url) {
        throw new TypeError("Invalid URL");
      }

      this.url = url;
      this.tags = tags;
      this.level = level;
      this.sendDelay = options.sendDelay || 100;
      this.retryDelay = options.retryDelay || 2000;
      this.muteConsole = options.muteConsole === true || false;
      this.isSending = false;
      this.queue = [];
    }

    Logstash.prototype._trySendEvent = function _trySendEvent() {
      var _this = this;

      if (!this.queue.length || this.isSending) {
        return;
      }

      this.isSending = true;
      var event = this.queue.shift();

      var request = {
        url: this.url,
        method: 'post',
        headers: { 'Content-Type': 'application/json' },
        data: event
      };

      // HTTP request
      return axios$3(request).then(function () {
        _this.isSending = false;
        _this._trySendEvent();
      }).catch(function (err) {
        console.error(err);

        // If we could not send the event,
        // put it back into queue
        _this.queue.unshift(event);

        _this.isSending = false;
        setTimeout(_this._trySendEvent.bind(_this), _this.retryDelay);
      });
    };

    Logstash.prototype.log = function log(level, message, fields) {
      var event = { level: level, fields: fields, message: message };

      event['@timestamp'] = new Date().toISOString();
      event['@tags'] = this.tags;

      // Navigator metadata
      if (typeof navigator !== 'undefined') {
        event.navigator = {
          cookieEnabled: navigator.cookieEnabled,
          geoLocation: navigator.geoLocation,
          language: navigator.language,
          languages: navigator.languages,
          online: navigator.online,
          userAgent: navigator.userAgent,
          platform: navigator.platform,
          vendor: navigator.vendor
        };
      }

      // Location metadata
      if (typeof location !== 'undefined') {
        event.location = {
          search: location.search,
          pathname: location.pathname,
          hostname: location.hostname,
          protocol: location.protocol,
          port: location.port,
          hash: location.hash,
          href: location.href
        };
      }

      this.queue.push(event);
      this._trySendEvent();

      if (this.muteConsole) {
        return;
      }

      var fieldsStr = fields ? " - " + JSON.stringify(fields) : '';

      switch (level) {
        case "error":
          console.error("" + message + fieldsStr);
          break;
        case "warn":
          console.warn("" + message + fieldsStr);
          break;
        default:
          console.info("" + message + fieldsStr);
      }
    };

    Logstash.prototype.debug = function debug(message, fields) {
      this.log('debug', message, fields);
    };

    Logstash.prototype.info = function info(message, fields) {
      this.log('info', message, fields);
    };

    Logstash.prototype.warn = function warn(message, fields) {
      this.log('warn', message, fields);
    };

    Logstash.prototype.error = function error(err, fields) {
      if (err instanceof Error) {
        this.log('error', err.message, Object.assign({ stack: err.stack }, fields));
      } else {
        this.log('error', err, fields);
      }
    };

    var dist = create;

    var classCallCheck = function (instance, Constructor) {
      if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
      }
    };

    var createClass = function () {
      function defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
          var descriptor = props[i];
          descriptor.enumerable = descriptor.enumerable || false;
          descriptor.configurable = true;
          if ("value" in descriptor) descriptor.writable = true;
          Object.defineProperty(target, descriptor.key, descriptor);
        }
      }

      return function (Constructor, protoProps, staticProps) {
        if (protoProps) defineProperties(Constructor.prototype, protoProps);
        if (staticProps) defineProperties(Constructor, staticProps);
        return Constructor;
      };
    }();

    var _extends = Object.assign || function (target) {
      for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i];

        for (var key in source) {
          if (Object.prototype.hasOwnProperty.call(source, key)) {
            target[key] = source[key];
          }
        }
      }

      return target;
    };

    var inherits = function (subClass, superClass) {
      if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
      }

      subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: {
          value: subClass,
          enumerable: false,
          writable: true,
          configurable: true
        }
      });
      if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
    };

    var possibleConstructorReturn = function (self, call) {
      if (!self) {
        throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
      }

      return call && (typeof call === "object" || typeof call === "function") ? call : self;
    };

    var formatUserSettings = function formatUserSettings(userSettings) {
        return _extends({}, userSettings, {
            userId: userSettings.userId ? userSettings.userId.toString() : '',
            subgroupId: userSettings.subgroupId ? userSettings.subgroupId.toString() : '',
            groupId: userSettings.groupId ? userSettings.groupId.toString() : ''
        });
    };

    var LogStash = function LogStash(model, label) {
        return new Promise(function (resolve, reject) {
            try {
                var firstDomainLevel = getFirstLevelDomain();
                var url = 'https://videometrics.wyscout' + firstDomainLevel + ':8080';
                // optional
                var tags = ['video', 'metrics'];
                var level = 'info';
                model.userSettings = formatUserSettings(model.userSettings);
                var options = {
                    muteConsole: true
                };
                // Create logger instance
                var logger = dist(url, tags, level, options);

                logger.info(label, model);
                resolve(logger);
            } catch (err) {
                reject(err);
            }
        });
    };

    var RestApi = function RestApi(model) {
        return axios$1({
            method: model.id ? 'PUT' : 'POST',
            url: model.id ? API_SERVER + ('metrics/' + model.id) : API_SERVER + 'metrics',
            data: model
        });
    };

    var getIpAddress = function getIpAddress() {
        return axios$1({
            method: 'GET',
            url: 'https://opsapi.wyscout.com/v0.2/get_my_ip'
        });
    };

    var Caller = function Caller(model, label) {
        var transmission = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : TRANSMISSION_TYPE.LOGSTASH;

        return transmission === TRANSMISSION_TYPE.LOGSTASH ? LogStash(model, label) : RestApi(model, label);
    };

    var getGlobalSwitchStatus = function getGlobalSwitchStatus(accessToken, apiHostname) {
        return axios$1({
            method: 'GET',
            url: apiHostname + 'media/videometricsconfig/',
            params: {
                access_token: accessToken
            }
        });
    };

    var formatBufferedRanges = function formatBufferedRanges(video) {
        var formattedRanges = [];
        for (var i = 0; i < video.buffered.length; i++) {
            formattedRanges.push({
                start: video.buffered.start(i),
                end: video.buffered.end(i)
            });
        }
        return formattedRanges;
    };

    var formatSeekableRanges = function formatSeekableRanges(video) {
        var formattedSeekableRanges = [];
        for (var i = 0; i < video.seekable.length; i++) {
            formattedSeekableRanges.push({
                start: video.seekable.start(i),
                end: video.seekable.end(i)
            });
        }
        return formattedSeekableRanges;
    };

    var formatPlayedRanges = function formatPlayedRanges(video) {
        var formattedPlayedRanges = [];
        for (var i = 0; i < video.played.length; i++) {
            formattedPlayedRanges.push({
                start: video.played.start(i),
                end: video.played.end(i)
            });
        }
        return formattedPlayedRanges;
    };

    var getUrlParams = function getUrlParams(url) {
        var finalUrl = url;
        if (!finalUrl.includes('?')) {
            return {
                userId: 123456,
                groupId: 123,
                subgroupId: 123,
                userName: 'Tester User'
            };
        }

        finalUrl = finalUrl.split('?')[1].split('&');
        finalUrl = finalUrl.reduce(function (acc, cur) {
            var key = cur.split('=')[0];
            var val = cur.split('=')[1];
            acc[key] = val;
            return acc;
        }, {});
        return finalUrl;
    };

    var getUserParams = function getUserParams() {
        var result = null;
        if (window.location.hostname.includes('.wyscout.')) {
            result = getUrlParams(window.location.href);
        } else {
            result = {
                userId: 123456,
                groupId: 123,
                subgroupId: 123,
                userName: 'Tester User'
            };
        }
        return result;
    };

    var checkIsEnabledStatus = function checkIsEnabledStatus(accessToken, apiHostname) {
        var promise = new Promise(function (resolve, reject) {
            getGlobalSwitchStatus(accessToken, apiHostname).then(function (response) {
                if (!response.data.isEnabled) return reject(false);
                return resolve(true);
            }).catch(function () {
                return reject(new Error(false));
            });
        });

        return promise;
    };

    var findHTML5Video = function findHTML5Video(userSettings, apiHostname) {
        var promise = new Promise(function (resolve, reject) {
            checkIsEnabledStatus(userSettings.accessToken, apiHostname).then(function () {
                var counter = 0;
                var seeking = setInterval(function () {
                    var video = document.querySelector('video');
                    if (video) {
                        clearInterval(seeking);
                        return resolve(video);
                    } else if (counter >= MAX_SEEKING_VIDEO_TAG) {
                        clearInterval(seeking);
                        return reject(new Error('HTML tag video not found'));
                    }
                    counter++;
                }, 500);
            }).catch(function () {
                return reject(new Error('find html5 Video checking problem'));
            });
        });

        return promise;
    };

    var getFirstLevelDomain = function getFirstLevelDomain() {
        if (typeof location !== 'undefined') {
            if (location.hostname.includes(WYSCOUT_HOSTNAMES_SUFFIX.CN)) {
                return '.cn';
            }
        }

        return '.com';
    };

    var createAnalyticsObject = function createAnalyticsObject(video, detailedAppSource) {
        return {
            appSource: ANALYTICS_APP_SOURCE,
            detailedAppSource: detailedAppSource,
            actionValue: 1,
            sessionId: video.sessionId,
            position: detailedAppSource === ANALYTICS_DETAILED_SOURCE.VIDEO_COMPLETED ? video.duration : video.currentTime, // sometimes on video end, cursor return to position 0
            totalLength: video.duration,
            player: video.playerType || PLAYER_TYPE.APPS,
            isMuted: video.muted,
            fullScreen: video.webkitDisplayingFullscreen,
            isPlaylist: _isPlaylist(video.currentSrc)
        };
    };

    var _isPlaylist = function _isPlaylist() {
        var src = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'sometext?vbegin=0';

        var params = getUrlParams(src);
        return params.vbegin && !Number.isNaN(params.vbegin) && params.vbegin > 0;
    };

    var calculateAverageBitRate = function calculateAverageBitRate(snapshots) {
        return _.meanBy(snapshots, function (p) {
            return p.decodedBytes;
        });
    };

    var calculateAverageFrameRate = function calculateAverageFrameRate(snapshots) {
        return _.meanBy(snapshots, function (p) {
            return p.decodedFrames;
        });
    };

    var dateStartTimestamp = 0;
    var canPlayTimeStamp = 0;
    var totalWaitingSeconds = 0;
    var startWaitingSeconds = 0;
    var rebufferingEventsNum = 0;

    var loadStart = function loadStart(event) {
        // console.log('loadStart --> ', event);
        dateStartTimestamp = new Date().getTime();
    };

    var durationchange = function durationchange(event) {
        // console.log('durationchange --> ', event);
    };

    var loadedmetadata = function loadedmetadata(event) {
        // console.log('loadedmetadata --> ', event);
    };

    var ended = function ended(event, session) {
        // right now we may not have anymore video properties (Es. video is regenerated by client), so we have to use session info.
        var analyticObj = createAnalyticsObject(event.target, ANALYTICS_DETAILED_SOURCE.VIDEO_COMPLETED);
        analyticObj.bitrate = calculateAverageBitRate(session.snapshots).toFixed(1);
        analyticObj.framerate = calculateAverageFrameRate(session.snapshots).toFixed(0);
        analyticObj.position = session.duration;
        analyticObj.totalLength = session.duration;
    };

    var loadeddata = function loadeddata(event) {
        // console.log('loadeddata --> ', event);
        /*
        * canplay and others events are also fired  after video is completed. So, in order to track on segment
        * we assume that video is started when video player has loaded all data. This event that's not good in order to track video-metrics
        */
        var analyticObj = createAnalyticsObject(event.target, ANALYTICS_DETAILED_SOURCE.VIDEO_START);
    };

    var progress = function progress(event) {
        var currentTime = new Date().getTime();
        // console.log('progress --> ', event);
        if (startWaitingSeconds > 0) {
            totalWaitingSeconds += currentTime - startWaitingSeconds;
            startWaitingSeconds = 0;
        }
    };

    var canplay = function canplay(event) {
        // console.log('canplay --> ', event);
        canPlayTimeStamp = new Date().getTime();
    };

    var pause = function pause(event) {
        if (event.target.networkState === NETWORK_STATE.NO_SOURCE) {
            var analyticObj = createAnalyticsObject(event.target, 'no audio/video source found');
            // track(ANALYTICS_EVENTS.PLAY_INTERRUPTED, analyticObj);
        }
    };

    var canplaythrough = function canplaythrough(event) {
        // console.log('canplaythrough --> ', event);
    };

    var waiting = function waiting(event) {
        // console.log('waiting --> ', event);
        startWaitingSeconds = new Date().getTime();
        rebufferingEventsNum++;
    };

    var getJoinedTime = function getJoinedTime() {
        return canPlayTimeStamp && dateStartTimestamp ? canPlayTimeStamp - dateStartTimestamp : 0;
    };

    var getTotalRebufferingTime = function getTotalRebufferingTime() {
        return totalWaitingSeconds;
    };

    var getTotalRebufferingEventsNum = function getTotalRebufferingEventsNum() {
        return rebufferingEventsNum;
    };

    var convertBytesToBits = function convertBytesToBits(bytes) {
      return bytes * 8;
    };

    var composeMetric = function composeMetric(startTime, video) {
        return {
            startTime: startTime ? startTime : new Date(),
            decodedFrames: decodedFrameCount(video),
            droppedFrames: droppedFrameCount(video),
            decodedBytes: decodedVideoByteCount(video),
            decodedAudioBytes: decodedAudioByteCount(video),
            displaySupportFullscreen: displaySupportFullScreen(video),
            src: currentSrc(video),
            duration: duration(video),
            bufferedRanges: formatBufferedRanges(video),
            playedRanges: formatPlayedRanges(video),
            seekableRanges: formatSeekableRanges(video)
        };
    };

    var Report = function Report() {
        var _this = this;

        classCallCheck(this, Report);

        this.setReportProperties = function (report) {
            var decodedFrames = report.decodedFrames,
                droppedFrames = report.droppedFrames,
                decodedBytes = report.decodedBytes,
                decodedAudioBytes = report.decodedAudioBytes,
                src = report.src,
                duration = report.duration,
                bufferedRanges = report.bufferedRanges,
                playedRanges = report.playedRanges,
                seekableRanges = report.seekableRanges,
                startTime = report.startTime;

            _this.startTime = startTime;
            _this.decodedFrames = decodedFrames;
            _this.droppedFrames = droppedFrames;
            _this.decodedBytes = decodedBytes;
            _this.decodedAudioBytes = decodedAudioBytes;
            _this.src = src;
            _this.duration = duration;
            _this.bufferedRanges = bufferedRanges;
            _this.playedRanges = playedRanges;
            _this.seekableRanges = seekableRanges;
        };

        this.setSnapshots = function (snapshots) {
            _this.snapshots = snapshots;
        };

        this.setSessionId = function (sessionId) {
            _this.sessionId = sessionId;
        };

        this.setUserSettings = function (userSettings) {
            _this.userSettings = userSettings;
        };

        this.clearSnapshots = function () {
            return _this.snapshots = [];
        };

        this.setJoinedTime = function (joinedTime) {
            return _this.joinedTime = joinedTime;
        };

        this.setRebufferingTime = function (rebufferingTime) {
            return _this.rebufferingTime = rebufferingTime;
        };

        this.setRebufferingEvents = function (rebufferingEvents) {
            return _this.rebufferingEvents = rebufferingEvents;
        };

        this.setIpAddress = function (ipAddress) {
            return _this.ipAddress = ipAddress;
        };

        this.setEndTime = function (endTime) {
            return _this.endTime = endTime;
        };

        this.setAverageBitrate = function (averageBitrate) {
            return _this.averageBitrate = averageBitrate;
        };
    };

    var Session = function Session() {
        var _this = this;

        classCallCheck(this, Session);

        this.addSnapshot = function (snapshot) {
            _this.snapshots.push(snapshot);
        };

        this.clearSnapshots = function () {
            _this.snapshots = [];
        };

        this.setSessionProperties = function (sessionId, duration, currentSrc) {
            _this.sessionId = sessionId;
            _this.duration = duration;
            _this.currentSrc = currentSrc;
        };

        this.snapshots = [];
        this.sessionId = null;
        this.duration = 0;
    };

    function createCommonjsModule(fn, module) {
    	return module = { exports: {} }, fn(module, module.exports), module.exports;
    }

    var uniqid = createCommonjsModule(function (module) {
    /* 
    (The MIT License)
    Copyright (c) 2014 Halász Ádám <mail@adamhalasz.com>
    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    */

    //  Unique Hexatridecimal ID Generator
    // ================================================

    //  Dependencies
    // ================================================
    var pid = process && process.pid ? process.pid.toString(36) : '' ;
    var address = '';
    if(typeof __webpack_require__ !== 'function'){
        var mac = '', networkInterfaces = os.networkInterfaces();
        for(interface_key in networkInterfaces){
            const networkInterface = networkInterfaces[interface_key];
            const length = networkInterface.length;
            for(var i = 0; i < length; i++){
                if(networkInterface[i].mac && networkInterface[i].mac != '00:00:00:00:00:00'){
                    mac = networkInterface[i].mac; break;
                }
            }
        }
        address = mac ? parseInt(mac.replace(/\:|\D+/gi, '')).toString(36) : '' ;
    } 

    //  Exports
    // ================================================
    module.exports = module.exports.default = function(prefix){ return (prefix || '') + address + pid + now().toString(36); };
    module.exports.process = function(prefix){ return (prefix || '') + pid + now().toString(36); };
    module.exports.time    = function(prefix){ return (prefix || '') + now().toString(36); };

    //  Helpers
    // ================================================
    function now(){
        var time = Date.now();
        var last = now.last || time;
        return now.last = time > last ? time : last + 1;
    }
    });
    var uniqid_1 = uniqid.time;

    var lastDecodedFrames = 0;
    var lastDroppedFrames = 0;
    var lastDecodedBytes = 0;
    var lastDecodedAudioBytes = 0;
    var lastAudioBitRate = 0;
    var lastVideoBitRate = 0;
    var totalAudioBitRate = 0;
    var totalVideoBitRate = 0;
    var requestAnimationId = 0;
    var _timer = void 0;
    var sessionTransmission = null;
    var report = new Report();
    var session = new Session();
    var lastTime = null;
    var currentTime$1 = null;
    var video = null;

    var resetParams = function resetParams(totalReport) {
        lastDecodedFrames = totalReport.decodedFrames;
        lastDroppedFrames = totalReport.droppedFrames;
        lastDecodedBytes = totalReport.decodedBytes;
        lastDecodedAudioBytes = totalReport.decodedAudioBytes;
        lastAudioBitRate = totalAudioBitRate;
        lastVideoBitRate = totalVideoBitRate;
    };

    var resetWithCurrentVideoValues = function resetWithCurrentVideoValues(currentVideo) {
        lastDecodedFrames = decodedFrameCount(currentVideo);
        lastDroppedFrames = droppedFrameCount(currentVideo);
        lastDecodedBytes = decodedVideoByteCount(currentVideo);
        lastDecodedAudioBytes = decodedAudioByteCount(currentVideo);
        lastAudioBitRate = convertBytesToBits(lastDecodedAudioBytes);
        lastVideoBitRate = convertBytesToBits(lastDecodedBytes);
    };

    var resetAll = function resetAll() {
        lastDecodedFrames = 0;
        lastDroppedFrames = 0;
        lastDecodedBytes = 0;
        lastDecodedAudioBytes = 0;
        lastAudioBitRate = 0;
        lastVideoBitRate = 0;
        totalAudioBitRate = 0;
        totalVideoBitRate = 0;
    };

    var requestAnimFrame = function () {
        return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
            window.setTimeout(callback, 1000 / 60);
        };
    }();

    var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;

    var closeSession = function closeSession() {
        report.setJoinedTime(getJoinedTime());
        report.setRebufferingTime(getTotalRebufferingTime());
        report.setRebufferingEvents(getTotalRebufferingEventsNum());
        report.setEndTime(new Date());
        Caller(report, 'session', sessionTransmission);
    };

    var startWork = function startWork() {
        var withReset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

        if (withReset) {
            resetWithCurrentVideoValues(video);
            currentTime$1 = new Date().getTime();
            lastTime = currentTime$1;
        }
        if (!requestAnimationId) _timer();else console.log('Profiler is already running');

        session = new Session();
    };

    var stopWork = function stopWork() {
        var withCloseSession = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

        cancelAnimationFrame(requestAnimationId);
        requestAnimationId = 0;
        if (withCloseSession) closeSession();
    };

    var onVideoEnded = function onVideoEnded(event) {
        ended(event, session); // track into analytics
        stopWork(true); // stopping sniffing
        resetAll(); // reset all values in order to play the next video
    };

    var onTabVisibilitychange = function onTabVisibilitychange(event) {
        if (document.visibilityState === 'hidden') stopWork();else startWork(true);
    };

    var onVideoPlaying = function onVideoPlaying(event) {
        startWork();
    };

    var stopSniffingVideoMetrics = function stopSniffingVideoMetrics() {
        console.log('Profiler is going to stop work');
        document.removeEventListener('visibilitychange', onTabVisibilitychange);
        video.removeEventListener('loadstart', loadStart, false);
        video.removeEventListener('durationchange', durationchange, false);
        video.removeEventListener('loadedmetadata', loadedmetadata, false);
        video.removeEventListener('loadeddata', loadeddata, false);
        video.removeEventListener('progress', progress, false);
        video.removeEventListener('canplay', canplay, false);
        video.removeEventListener('canplaythrough', canplaythrough, false);
        video.removeEventListener('waiting', waiting, false);
        video.removeEventListener('pause', pause, false);
        video.removeEventListener('ended', onVideoEnded, false);
        video.removeEventListener('playing', onVideoPlaying, false);
        stopWork();
    };

    var checkStatusInterval = function checkStatusInterval(accessToken, apiHostname) {
        var interval = setInterval(function () {
            checkIsEnabledStatus(accessToken, apiHostname).then(function (response) {
                if (!response) {
                    stopSniffingVideoMetrics();
                    clearInterval(interval);
                }
                if (response && !requestAnimationId) startWork();
            }).catch(function () {
                stopSniffingVideoMetrics();
                clearInterval(interval);
            });
        }, ENABLING_STATUS_MILLISECONDS);
    };

    var startSniffingVideoMetrics = function startSniffingVideoMetrics(userSettings, playerType) {
        var transmission = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : TRANSMISSION_TYPE.LOGSTASH;
        var apiHostname = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : API_HOSTNAME;

        findHTML5Video(userSettings, apiHostname).then(function (foundVideo) {
            video = foundVideo;
            var sessionId = uniqid();
            var profile = !userSettings ? getUserParams() : userSettings;
            sessionTransmission = transmission;
            initAnalytics(profile.userId);
            video.sessionId = sessionId;
            report.setSessionId(sessionId);

            document.addEventListener('visibilitychange', onTabVisibilitychange);
            video.playerType = playerType || PLAYER_TYPE.PLATFROM;
            video.addEventListener('loadstart', loadStart, false);
            video.addEventListener('durationchange', durationchange, false);
            video.addEventListener('loadedmetadata', loadedmetadata, false);
            video.addEventListener('loadeddata', loadeddata, false);
            video.addEventListener('progress', progress, false);
            video.addEventListener('canplay', canplay, false);
            video.addEventListener('canplaythrough', canplaythrough, false);
            video.addEventListener('waiting', waiting, false);
            video.addEventListener('pause', pause, false);
            video.addEventListener('ended', onVideoEnded, false);
            video.addEventListener('playing', onVideoPlaying, false);

            report.setUserSettings(profile);

            getIpAddress().then(function (call) {
                if (call && call.data && call.data.response) {
                    report.setIpAddress(call.data.response);
                }
            });

            lastTime = new Date().getTime();
            var numPausedSeconds = 0;
            currentTime$1 = 0;

            checkStatusInterval(profile.accessToken, apiHostname);

            _timer = function timer() {
                requestAnimationId = requestAnimFrame(_timer);
                session.setSessionProperties(sessionId, video.duration, video.currentSrc);
                currentTime$1 = new Date().getTime();

                if (currentTime$1 - lastTime >= 1000) {
                    // è passato un secondo
                    lastTime = currentTime$1;

                    if (paused(video)) {
                        numPausedSeconds++;
                        if (numPausedSeconds > MAX_PAUSED_SECONDS) stopWork(true);
                        return;
                    }
                    numPausedSeconds = 0;

                    var metric = composeMetric(report.startTime, video);

                    totalVideoBitRate = convertBytesToBits(metric.decodedBytes);
                    totalAudioBitRate = convertBytesToBits(metric.decodedAudioBytes);
                    report.setReportProperties(metric);

                    var snapshot = {
                        effectiveTime: new Date(),
                        decodedFrames: report.decodedFrames - lastDecodedFrames,
                        droppedFrames: report.droppedFrames - lastDroppedFrames,
                        decodedBytes: report.decodedBytes - lastDecodedBytes,
                        decodedAudioBytes: report.decodedAudioBytes - lastDecodedAudioBytes,
                        displayIsFullscreen: displayIsFullscreen(video),
                        videoBitRate: totalVideoBitRate - lastVideoBitRate,
                        audioBitRate: totalAudioBitRate - lastAudioBitRate,
                        currentTime: currentTime(video).toFixed(2),
                        networkState: networkState(video),
                        sessionId: report.sessionId,
                        userSettings: profile
                    };
                    session.addSnapshot(snapshot);

                    resetParams(report);
                    Caller(snapshot, 'snapshot', sessionTransmission);
                }
            };
        }).catch(function () {
            // console.error(err);
        });
    };

    var WyMetricProfiler = function (_Component) {
        inherits(WyMetricProfiler, _Component);

        function WyMetricProfiler() {
            classCallCheck(this, WyMetricProfiler);

            var _this = possibleConstructorReturn(this, (WyMetricProfiler.__proto__ || Object.getPrototypeOf(WyMetricProfiler)).call(this));

            _this.componentDidMount = function () {
                var _this$props = _this.props,
                    startOnMount = _this$props.startOnMount,
                    userSettings = _this$props.userSettings,
                    playerType = _this$props.playerType,
                    transmitter = _this$props.transmitter,
                    apiHostname = _this$props.apiHostname;

                if (startOnMount) {
                    startSniffingVideoMetrics(userSettings, playerType, transmitter, apiHostname);
                }
            };

            _this.state = {
                running: false,
                startOnMount: true
            };
            return _this;
        }

        createClass(WyMetricProfiler, [{
            key: 'render',
            value: function render() {
                return React__default.createElement(
                    'div',
                    null,
                    this.props.children
                );
            }
        }], [{
            key: 'getDerivedStateFromProps',
            value: function getDerivedStateFromProps(props, state) {
                var userSettings = props.userSettings,
                    playerType = props.playerType,
                    transmitter = props.transmitter,
                    running = props.running,
                    apiHostname = props.apiHostname;


                if (running && !state.running) {
                    startSniffingVideoMetrics(userSettings, playerType, transmitter, apiHostname);
                } else if (!running && state.running) {
                    stopSniffingVideoMetrics();
                }

                return {
                    running: props.running
                };
            }
        }]);
        return WyMetricProfiler;
    }(React.Component);
    WyMetricProfiler.propTypes = {
        running: PropTypes.bool.isRequired,
        startOnMount: PropTypes.bool,
        userSettings: PropTypes.shape({
            userId: PropTypes.number,
            userName: PropTypes.string,
            groupId: PropTypes.number,
            subgroupId: PropTypes.number,
            accessToken: PropTypes.string
        }).isRequired,
        transmitter: PropTypes.oneOf([TRANSMISSION_TYPE.LOGSTASH, TRANSMISSION_TYPE.REST]),
        playerType: PropTypes.oneOf([PLAYER_TYPE.PLATFORM, PLAYER_TYPE.APPS]),
        children: PropTypes.node.isRequired,
        apiHostname: PropTypes.string
    };
    WyMetricProfiler.defaultProps = {
        startOnMount: true,
        transmitter: TRANSMISSION_TYPE.LOGSTASH,
        playerType: PLAYER_TYPE.PLATFORM,
        apiHostname: API_HOSTNAME
    };

    exports.startSniffingVideoMetrics = startSniffingVideoMetrics;
    exports.stopSniffingVideoMetrics = stopSniffingVideoMetrics;
    exports.WyMetricProfiler = WyMetricProfiler;
    exports.TRANSMISSION_TYPE = TRANSMISSION_TYPE;
    exports.PLAYER_TYPE = PLAYER_TYPE;

    return exports;

}({}, _, os, React, PropTypes));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlkZW8tbWV0cmljcy5qcyIsInNvdXJjZXMiOlsiLi4vc3JjL2NvcmUvSFRNTDVWaWRlb1Byb3BlcnRpZXMuanMiLCIuLi9zcmMvYW5hbHl0aWNzL2FuYWx5dGljc01hbmFnZXIuanMiLCIuLi9zcmMvY29uZmlnL2NvbmZpZy5qcyIsIi4uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9iaW5kLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2lzLWJ1ZmZlci9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvdXRpbHMuanMiLCIuLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvbm9ybWFsaXplSGVhZGVyTmFtZS5qcyIsIi4uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvY29yZS9lbmhhbmNlRXJyb3IuanMiLCIuLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvY3JlYXRlRXJyb3IuanMiLCIuLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvc2V0dGxlLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL2J1aWxkVVJMLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL3BhcnNlSGVhZGVycy5qcyIsIi4uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9pc1VSTFNhbWVPcmlnaW4uanMiLCIuLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvYnRvYS5qcyIsIi4uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9jb29raWVzLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9hZGFwdGVycy94aHIuanMiLCIuLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2RlZmF1bHRzLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9jb3JlL0ludGVyY2VwdG9yTWFuYWdlci5qcyIsIi4uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvY29yZS90cmFuc2Zvcm1EYXRhLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9jYW5jZWwvaXNDYW5jZWwuanMiLCIuLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvaXNBYnNvbHV0ZVVSTC5qcyIsIi4uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9jb21iaW5lVVJMcy5qcyIsIi4uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvY29yZS9kaXNwYXRjaFJlcXVlc3QuanMiLCIuLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvQXhpb3MuanMiLCIuLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NhbmNlbC9DYW5jZWwuanMiLCIuLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NhbmNlbC9DYW5jZWxUb2tlbi5qcyIsIi4uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9zcHJlYWQuanMiLCIuLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2F4aW9zLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2F4aW9zL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL0B3eXNjb3V0L2xvZ3N0YXNoL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9iaW5kLmpzIiwiLi4vbm9kZV9tb2R1bGVzL0B3eXNjb3V0L2xvZ3N0YXNoL25vZGVfbW9kdWxlcy9heGlvcy9saWIvdXRpbHMuanMiLCIuLi9ub2RlX21vZHVsZXMvQHd5c2NvdXQvbG9nc3Rhc2gvbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL25vcm1hbGl6ZUhlYWRlck5hbWUuanMiLCIuLi9ub2RlX21vZHVsZXMvQHd5c2NvdXQvbG9nc3Rhc2gvbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9jb3JlL2VuaGFuY2VFcnJvci5qcyIsIi4uL25vZGVfbW9kdWxlcy9Ad3lzY291dC9sb2dzdGFzaC9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvY3JlYXRlRXJyb3IuanMiLCIuLi9ub2RlX21vZHVsZXMvQHd5c2NvdXQvbG9nc3Rhc2gvbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9jb3JlL3NldHRsZS5qcyIsIi4uL25vZGVfbW9kdWxlcy9Ad3lzY291dC9sb2dzdGFzaC9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvYnVpbGRVUkwuanMiLCIuLi9ub2RlX21vZHVsZXMvQHd5c2NvdXQvbG9nc3Rhc2gvbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL3BhcnNlSGVhZGVycy5qcyIsIi4uL25vZGVfbW9kdWxlcy9Ad3lzY291dC9sb2dzdGFzaC9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvaXNVUkxTYW1lT3JpZ2luLmpzIiwiLi4vbm9kZV9tb2R1bGVzL0B3eXNjb3V0L2xvZ3N0YXNoL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9idG9hLmpzIiwiLi4vbm9kZV9tb2R1bGVzL0B3eXNjb3V0L2xvZ3N0YXNoL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9jb29raWVzLmpzIiwiLi4vbm9kZV9tb2R1bGVzL0B3eXNjb3V0L2xvZ3N0YXNoL25vZGVfbW9kdWxlcy9heGlvcy9saWIvYWRhcHRlcnMveGhyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL0B3eXNjb3V0L2xvZ3N0YXNoL25vZGVfbW9kdWxlcy9heGlvcy9saWIvZGVmYXVsdHMuanMiLCIuLi9ub2RlX21vZHVsZXMvQHd5c2NvdXQvbG9nc3Rhc2gvbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9jb3JlL0ludGVyY2VwdG9yTWFuYWdlci5qcyIsIi4uL25vZGVfbW9kdWxlcy9Ad3lzY291dC9sb2dzdGFzaC9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvdHJhbnNmb3JtRGF0YS5qcyIsIi4uL25vZGVfbW9kdWxlcy9Ad3lzY291dC9sb2dzdGFzaC9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NhbmNlbC9pc0NhbmNlbC5qcyIsIi4uL25vZGVfbW9kdWxlcy9Ad3lzY291dC9sb2dzdGFzaC9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvaXNBYnNvbHV0ZVVSTC5qcyIsIi4uL25vZGVfbW9kdWxlcy9Ad3lzY291dC9sb2dzdGFzaC9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvY29tYmluZVVSTHMuanMiLCIuLi9ub2RlX21vZHVsZXMvQHd5c2NvdXQvbG9nc3Rhc2gvbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9jb3JlL2Rpc3BhdGNoUmVxdWVzdC5qcyIsIi4uL25vZGVfbW9kdWxlcy9Ad3lzY291dC9sb2dzdGFzaC9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvQXhpb3MuanMiLCIuLi9ub2RlX21vZHVsZXMvQHd5c2NvdXQvbG9nc3Rhc2gvbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9jYW5jZWwvQ2FuY2VsLmpzIiwiLi4vbm9kZV9tb2R1bGVzL0B3eXNjb3V0L2xvZ3N0YXNoL25vZGVfbW9kdWxlcy9heGlvcy9saWIvY2FuY2VsL0NhbmNlbFRva2VuLmpzIiwiLi4vbm9kZV9tb2R1bGVzL0B3eXNjb3V0L2xvZ3N0YXNoL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9zcHJlYWQuanMiLCIuLi9ub2RlX21vZHVsZXMvQHd5c2NvdXQvbG9nc3Rhc2gvbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9heGlvcy5qcyIsIi4uL25vZGVfbW9kdWxlcy9Ad3lzY291dC9sb2dzdGFzaC9ub2RlX21vZHVsZXMvYXhpb3MvaW5kZXguanMiLCIuLi9ub2RlX21vZHVsZXMvQHd5c2NvdXQvbG9nc3Rhc2gvZGlzdC9pbmRleC5qcyIsIi4uL3NyYy90cmFuc21pdHRlci9Mb2dTdGFzaC5qcyIsIi4uL3NyYy90cmFuc21pdHRlci9SZXN0QXBpLmpzIiwiLi4vc3JjL2NvcmUvQ2FsbGVyLmpzIiwiLi4vc3JjL3V0aWxpdGllcy91dGlscy5qcyIsIi4uL3NyYy9hbmFseXRpY3MvdXRpbHMuanMiLCIuLi9zcmMvdXRpbGl0aWVzL3N0YXRzLmpzIiwiLi4vc3JjL2NvcmUvRXZlbnRzTWFuYWdlci5qcyIsIi4uL3NyYy91dGlsaXRpZXMvY29udmVydGVyLmpzIiwiLi4vc3JjL3V0aWxpdGllcy92aWRlb1V0aWxzLmpzIiwiLi4vc3JjL21vZGVsL1JlcG9ydC5qcyIsIi4uL3NyYy9tb2RlbC9TZXNzaW9uLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3VuaXFpZC9pbmRleC5qcyIsIi4uL3NyYy9tZXRyaWNzTWFuYWdlci5qcyIsIi4uL3NyYy9tZXRyaWNzTWFuYWdlcldyYXBwZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IGRlY29kZWRGcmFtZUNvdW50ID0gdmlkZW8gPT4gdmlkZW8ud2Via2l0RGVjb2RlZEZyYW1lQ291bnQ7XG5cbmV4cG9ydCBjb25zdCBkZWNvZGVkVmlkZW9CeXRlQ291bnQgPSB2aWRlbyA9PiB2aWRlby53ZWJraXRWaWRlb0RlY29kZWRCeXRlQ291bnQ7XG5cbmV4cG9ydCBjb25zdCBkZWNvZGVkQXVkaW9CeXRlQ291bnQgPSB2aWRlbyA9PiB2aWRlby53ZWJraXRBdWRpb0RlY29kZWRCeXRlQ291bnQ7XG5cbmV4cG9ydCBjb25zdCBkaXNwbGF5SXNGdWxsc2NyZWVuID0gdmlkZW8gPT4gdmlkZW8ud2Via2l0RGlzcGxheWluZ0Z1bGxzY3JlZW47XG5cbmV4cG9ydCBjb25zdCBkaXNwbGF5U3VwcG9ydEZ1bGxTY3JlZW4gPSB2aWRlbyA9PiB2aWRlby53ZWJraXRTdXBwb3J0c0Z1bGxzY3JlZW47XG5cbmV4cG9ydCBjb25zdCBkcm9wcGVkRnJhbWVDb3VudCA9IHZpZGVvID0+IHZpZGVvLndlYmtpdERyb3BwZWRGcmFtZUNvdW50O1xuXG5leHBvcnQgY29uc3QgZHVyYXRpb24gPSB2aWRlbyA9PiB2aWRlby5kdXJhdGlvbjtcblxuZXhwb3J0IGNvbnN0IHBhdXNlZCA9IHZpZGVvID0+IHZpZGVvLnBhdXNlZDtcblxuZXhwb3J0IGNvbnN0IHNyYyA9IHZpZGVvID0+IHZpZGVvLnNyYztcblxuZXhwb3J0IGNvbnN0IGN1cnJlbnRTcmMgPSB2aWRlbyA9PiB2aWRlby5jdXJyZW50U3JjO1xuXG5leHBvcnQgY29uc3QgbmV0d29ya1N0YXRlID0gdmlkZW8gPT4gdmlkZW8ubmV0d29ya1N0YXRlO1xuXG5leHBvcnQgY29uc3QgY3VycmVudFRpbWUgPSB2aWRlbyA9PiB2aWRlby5jdXJyZW50VGltZTtcbiIsIi8vIGltcG9ydCBXeUFuYWx5dGljcyBmcm9tICdAd3lzY291dC9hbmFseXRpY3MnO1xuXG5sZXQgYW5hbHl0aWNzID0gbnVsbDtcblxuXG5leHBvcnQgY29uc3QgaW5pdEFuYWx5dGljcyA9ICh1c2VySWQsIHByb2Nlc3NFbnYgPSAnZGV2ZWxvcG1lbnQnKSA9PiB7XG4gICAgLy8gYW5hbHl0aWNzID0gbmV3IFd5QW5hbHl0aWNzKHByb2Nlc3NFbnYsIHVzZXJJZCk7XG4gICAgLy8gYW5hbHl0aWNzLmlkZW50aWZ5KCk7XG59O1xuXG5cbmV4cG9ydCBjb25zdCB0cmFjayA9IChldmVudE5hbWUsIG1vZGVsID0ge2FwcFNvdXJjZTogJ3ZpZGVvLW1ldHJpY3MnLCBhcHBEZXRhaWxlZFNvdXJjZTogJ0RlZmF1bHQgRXZlbnQnfSkgPT4ge1xuICAgIC8vIGFuYWx5dGljcy50cmFjayhldmVudE5hbWUsIG1vZGVsKTtcbn07XG4iLCJsZXQgcmVzdEFwaUJhc2VOYW1lID0gbnVsbDtcblxuY29uc3QgZW52ID0gcHJvY2Vzcy5lbnYuUkVBQ1RfQVBQX0VOViB8fCBwcm9jZXNzLmVudi5OT0RFX0VOVjtcblxuc3dpdGNoIChlbnYpIHtcbiAgICBjYXNlICdyYyc6XG4gICAgY2FzZSAncmVsZWFzZSc6XG4gICAgICAgIHJlc3RBcGlCYXNlTmFtZSA9ICdodHRwczovL3Jlc3RyYy53eXNjb3V0LmNvbS8nO1xuICAgICAgICBicmVhaztcbiAgICBjYXNlICdwcmV2aWV3JzpcbiAgICAgICAgcmVzdEFwaUJhc2VOYW1lID0gJ2h0dHBzOi8vcmVzdHByZXZpZXcud3lzY291dC5jb20vJztcbiAgICAgICAgYnJlYWs7XG4gICAgY2FzZSAncHJvZHVjdGlvbic6XG4gICAgICAgIHJlc3RBcGlCYXNlTmFtZSA9ICdodHRwczovL3Jlc3Qud3lzY291dC5jb20vJztcbiAgICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgICAgcmVzdEFwaUJhc2VOYW1lID0gJ2h0dHBzOi8vcmVzdGJldGEud3lzY291dC5jb20vJztcbiAgICAgICAgYnJlYWs7XG59XG5cbmV4cG9ydCBjb25zdCBBUElfSE9TVE5BTUUgPSByZXN0QXBpQmFzZU5hbWU7XG5cbmV4cG9ydCBjb25zdCBBUElfU0VSVklDRVMgPSB7XG4gICAgdmlkZW9tZXRyaWNzQ29uZmlnOiBgJHtyZXN0QXBpQmFzZU5hbWV9L21lZGlhL3ZpZGVvbWV0cmljc2NvbmZpZy9gLFxufTtcblxuZXhwb3J0IGNvbnN0IEFQSV9TRVJWRVIgPVxuICAgICdodHRwOi8vNWI5MjQ5Y2I0YzgxOGUwMDE0NTZlOGY1Lm1vY2thcGkuaW8vdmlkZW8tbWV0cmljcy92MS8nO1xuXG5leHBvcnQgY29uc3QgTUFYX1NOSUZGSU5HX1NFU1NJT04gPSA2MDtcblxuZXhwb3J0IGNvbnN0IE1BWF9NRVRSSUNTX0NBQ0hFRCA9IDIwO1xuXG5leHBvcnQgY29uc3QgTUFYX1NFRUtJTkdfVklERU9fVEFHID0gMTA7XG5cbmV4cG9ydCBjb25zdCBNQVhfUEFVU0VEX1NFQ09ORFMgPSAyMDtcblxuZXhwb3J0IGNvbnN0IEVOQUJMSU5HX1NUQVRVU19NSUxMSVNFQ09ORFMgPSAxMDAwICogNjAgKiAxMDsgLy8gMTAgbWludXRlc1xuXG5leHBvcnQgY29uc3QgVFJBTlNNSVNTSU9OX1RZUEUgPSB7XG4gICAgUkVTVDogJ3Jlc3QnLFxuICAgIExPR1NUQVNIOiAnbG9nc3Rhc2gnLFxufTtcblxuZXhwb3J0IGNvbnN0IE5FVFdPUktfU1RBVEUgPSB7XG4gICAgRU1QVFk6IDAsXG4gICAgSURMRTogMSxcbiAgICBMT0FESU5HOiAyLFxuICAgIE5PX1NPVVJDRTogMyxcbn07XG5cbmV4cG9ydCBjb25zdCBBTkFMWVRJQ1NfRVZFTlRTID0ge1xuICAgIEJVRkZFUl9TVEFSVEVEOiAnVmlkZW8gUGxheWJhY2sgQnVmZmVyIFN0YXJ0ZWQnLFxuICAgIEJVRkZFUl9DT01QTEVURUQ6ICdWaWRlbyBQbGF5YmFjayBCdWZmZXIgQ29tcGxldGVkJyxcbiAgICBQTEFZX1NUQVJURUQ6ICdWaWRlbyBQbGF5YmFjayBTdGFydGVkJyxcbiAgICBQTEFZX0NPTVBMRVRFRDogJ1ZpZGVvIFBsYXliYWNrIENvbXBsZXRlZCcsXG4gICAgUExBWV9QQVVTRUQ6ICdWaWRlbyBQbGF5YmFjayBQYXVzZWQnLFxuICAgIFBMQVlfSU5URVJSVVBURUQ6ICdWaWRlbyBQbGF5YmFjayBJbnRlcnJ1cHRlZCcsXG59O1xuXG5leHBvcnQgY29uc3QgQU5BTFlUSUNTX0FQUF9TT1VSQ0UgPSAnVmlkZW8gUGxheWVyJztcbmV4cG9ydCBjb25zdCBBTkFMWVRJQ1NfREVUQUlMRURfU09VUkNFID0ge1xuICAgIFZJREVPX1NUQVJUOiAnVmlkZW8gUGxheWVyIEF1dG8gU3RhcnQnLFxuICAgIFZJREVPX0NPTVBMRVRFRDogJ1ZpZGVvIFBsYXllciBDb21wbGV0ZWQnLFxufTtcblxuZXhwb3J0IGNvbnN0IFBMQVlFUl9UWVBFID0ge1xuICAgIFBMQVRGT1JNOiAnQUVWaWRlbycsXG4gICAgQVBQUzogJ1ZQMjAxOCcsXG59O1xuXG5leHBvcnQgY29uc3QgV1lTQ09VVF9IT1NUTkFNRVNfU1VGRklYID0ge1xuICAgIERFRkFVTFQ6ICd3eXNjb3V0LmNvbScsXG4gICAgUlU6ICdwbGF0Zm9ybS1ydS53eXNjb3V0LmNvbScsXG4gICAgQ046ICd3eXNjb3V0LmNuJyxcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYmluZChmbiwgdGhpc0FyZykge1xuICByZXR1cm4gZnVuY3Rpb24gd3JhcCgpIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGFyZ3NbaV0gPSBhcmd1bWVudHNbaV07XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbiAgfTtcbn07XG4iLCIvKiFcbiAqIERldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBCdWZmZXJcbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbi8vIFRoZSBfaXNCdWZmZXIgY2hlY2sgaXMgZm9yIFNhZmFyaSA1LTcgc3VwcG9ydCwgYmVjYXVzZSBpdCdzIG1pc3Npbmdcbi8vIE9iamVjdC5wcm90b3R5cGUuY29uc3RydWN0b3IuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHlcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaikge1xuICByZXR1cm4gb2JqICE9IG51bGwgJiYgKGlzQnVmZmVyKG9iaikgfHwgaXNTbG93QnVmZmVyKG9iaikgfHwgISFvYmouX2lzQnVmZmVyKVxufVxuXG5mdW5jdGlvbiBpc0J1ZmZlciAob2JqKSB7XG4gIHJldHVybiAhIW9iai5jb25zdHJ1Y3RvciAmJiB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyID09PSAnZnVuY3Rpb24nICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopXG59XG5cbi8vIEZvciBOb2RlIHYwLjEwIHN1cHBvcnQuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHkuXG5mdW5jdGlvbiBpc1Nsb3dCdWZmZXIgKG9iaikge1xuICByZXR1cm4gdHlwZW9mIG9iai5yZWFkRmxvYXRMRSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2Ygb2JqLnNsaWNlID09PSAnZnVuY3Rpb24nICYmIGlzQnVmZmVyKG9iai5zbGljZSgwLCAwKSlcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGJpbmQgPSByZXF1aXJlKCcuL2hlbHBlcnMvYmluZCcpO1xudmFyIGlzQnVmZmVyID0gcmVxdWlyZSgnaXMtYnVmZmVyJyk7XG5cbi8qZ2xvYmFsIHRvU3RyaW5nOnRydWUqL1xuXG4vLyB1dGlscyBpcyBhIGxpYnJhcnkgb2YgZ2VuZXJpYyBoZWxwZXIgZnVuY3Rpb25zIG5vbi1zcGVjaWZpYyB0byBheGlvc1xuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIEFycmF5XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYW4gQXJyYXksIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0FycmF5KHZhbCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWwpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIEFycmF5QnVmZmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYW4gQXJyYXlCdWZmZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0FycmF5QnVmZmVyKHZhbCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWwpID09PSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRm9ybURhdGFcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhbiBGb3JtRGF0YSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRm9ybURhdGEodmFsKSB7XG4gIHJldHVybiAodHlwZW9mIEZvcm1EYXRhICE9PSAndW5kZWZpbmVkJykgJiYgKHZhbCBpbnN0YW5jZW9mIEZvcm1EYXRhKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIHZpZXcgb24gYW4gQXJyYXlCdWZmZXJcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIHZpZXcgb24gYW4gQXJyYXlCdWZmZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0FycmF5QnVmZmVyVmlldyh2YWwpIHtcbiAgdmFyIHJlc3VsdDtcbiAgaWYgKCh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnKSAmJiAoQXJyYXlCdWZmZXIuaXNWaWV3KSkge1xuICAgIHJlc3VsdCA9IEFycmF5QnVmZmVyLmlzVmlldyh2YWwpO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdCA9ICh2YWwpICYmICh2YWwuYnVmZmVyKSAmJiAodmFsLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgU3RyaW5nXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBTdHJpbmcsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1N0cmluZyh2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgTnVtYmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBOdW1iZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc051bWJlcih2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdudW1iZXInO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIHVuZGVmaW5lZFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyB1bmRlZmluZWQsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICd1bmRlZmluZWQnO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIE9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGFuIE9iamVjdCwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbCkge1xuICByZXR1cm4gdmFsICE9PSBudWxsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRGF0ZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRGF0ZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRGF0ZSh2YWwpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRmlsZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRmlsZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRmlsZSh2YWwpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsKSA9PT0gJ1tvYmplY3QgRmlsZV0nO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgQmxvYlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgQmxvYiwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQmxvYih2YWwpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsKSA9PT0gJ1tvYmplY3QgQmxvYl0nO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRnVuY3Rpb25cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIEZ1bmN0aW9uLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWwpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIFN0cmVhbVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgU3RyZWFtLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTdHJlYW0odmFsKSB7XG4gIHJldHVybiBpc09iamVjdCh2YWwpICYmIGlzRnVuY3Rpb24odmFsLnBpcGUpO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgVVJMU2VhcmNoUGFyYW1zIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgVVJMU2VhcmNoUGFyYW1zIG9iamVjdCwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzVVJMU2VhcmNoUGFyYW1zKHZhbCkge1xuICByZXR1cm4gdHlwZW9mIFVSTFNlYXJjaFBhcmFtcyAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsIGluc3RhbmNlb2YgVVJMU2VhcmNoUGFyYW1zO1xufVxuXG4vKipcbiAqIFRyaW0gZXhjZXNzIHdoaXRlc3BhY2Ugb2ZmIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiBhIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgVGhlIFN0cmluZyB0byB0cmltXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgU3RyaW5nIGZyZWVkIG9mIGV4Y2VzcyB3aGl0ZXNwYWNlXG4gKi9cbmZ1bmN0aW9uIHRyaW0oc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyovLCAnJykucmVwbGFjZSgvXFxzKiQvLCAnJyk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIHdlJ3JlIHJ1bm5pbmcgaW4gYSBzdGFuZGFyZCBicm93c2VyIGVudmlyb25tZW50XG4gKlxuICogVGhpcyBhbGxvd3MgYXhpb3MgdG8gcnVuIGluIGEgd2ViIHdvcmtlciwgYW5kIHJlYWN0LW5hdGl2ZS5cbiAqIEJvdGggZW52aXJvbm1lbnRzIHN1cHBvcnQgWE1MSHR0cFJlcXVlc3QsIGJ1dCBub3QgZnVsbHkgc3RhbmRhcmQgZ2xvYmFscy5cbiAqXG4gKiB3ZWIgd29ya2VyczpcbiAqICB0eXBlb2Ygd2luZG93IC0+IHVuZGVmaW5lZFxuICogIHR5cGVvZiBkb2N1bWVudCAtPiB1bmRlZmluZWRcbiAqXG4gKiByZWFjdC1uYXRpdmU6XG4gKiAgbmF2aWdhdG9yLnByb2R1Y3QgLT4gJ1JlYWN0TmF0aXZlJ1xuICovXG5mdW5jdGlvbiBpc1N0YW5kYXJkQnJvd3NlckVudigpIHtcbiAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmIG5hdmlnYXRvci5wcm9kdWN0ID09PSAnUmVhY3ROYXRpdmUnKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnXG4gICk7XG59XG5cbi8qKlxuICogSXRlcmF0ZSBvdmVyIGFuIEFycmF5IG9yIGFuIE9iamVjdCBpbnZva2luZyBhIGZ1bmN0aW9uIGZvciBlYWNoIGl0ZW0uXG4gKlxuICogSWYgYG9iamAgaXMgYW4gQXJyYXkgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgcGFzc2luZ1xuICogdGhlIHZhbHVlLCBpbmRleCwgYW5kIGNvbXBsZXRlIGFycmF5IGZvciBlYWNoIGl0ZW0uXG4gKlxuICogSWYgJ29iaicgaXMgYW4gT2JqZWN0IGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHBhc3NpbmdcbiAqIHRoZSB2YWx1ZSwga2V5LCBhbmQgY29tcGxldGUgb2JqZWN0IGZvciBlYWNoIHByb3BlcnR5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBvYmogVGhlIG9iamVjdCB0byBpdGVyYXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIGZvciBlYWNoIGl0ZW1cbiAqL1xuZnVuY3Rpb24gZm9yRWFjaChvYmosIGZuKSB7XG4gIC8vIERvbid0IGJvdGhlciBpZiBubyB2YWx1ZSBwcm92aWRlZFxuICBpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRm9yY2UgYW4gYXJyYXkgaWYgbm90IGFscmVhZHkgc29tZXRoaW5nIGl0ZXJhYmxlXG4gIGlmICh0eXBlb2Ygb2JqICE9PSAnb2JqZWN0Jykge1xuICAgIC8qZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOjAqL1xuICAgIG9iaiA9IFtvYmpdO1xuICB9XG5cbiAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgIC8vIEl0ZXJhdGUgb3ZlciBhcnJheSB2YWx1ZXNcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IG9iai5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgb2JqW2ldLCBpLCBvYmopO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBJdGVyYXRlIG92ZXIgb2JqZWN0IGtleXNcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICBmbi5jYWxsKG51bGwsIG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQWNjZXB0cyB2YXJhcmdzIGV4cGVjdGluZyBlYWNoIGFyZ3VtZW50IHRvIGJlIGFuIG9iamVjdCwgdGhlblxuICogaW1tdXRhYmx5IG1lcmdlcyB0aGUgcHJvcGVydGllcyBvZiBlYWNoIG9iamVjdCBhbmQgcmV0dXJucyByZXN1bHQuXG4gKlxuICogV2hlbiBtdWx0aXBsZSBvYmplY3RzIGNvbnRhaW4gdGhlIHNhbWUga2V5IHRoZSBsYXRlciBvYmplY3QgaW5cbiAqIHRoZSBhcmd1bWVudHMgbGlzdCB3aWxsIHRha2UgcHJlY2VkZW5jZS5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqIGBgYGpzXG4gKiB2YXIgcmVzdWx0ID0gbWVyZ2Uoe2ZvbzogMTIzfSwge2ZvbzogNDU2fSk7XG4gKiBjb25zb2xlLmxvZyhyZXN1bHQuZm9vKTsgLy8gb3V0cHV0cyA0NTZcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmoxIE9iamVjdCB0byBtZXJnZVxuICogQHJldHVybnMge09iamVjdH0gUmVzdWx0IG9mIGFsbCBtZXJnZSBwcm9wZXJ0aWVzXG4gKi9cbmZ1bmN0aW9uIG1lcmdlKC8qIG9iajEsIG9iajIsIG9iajMsIC4uLiAqLykge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIGZ1bmN0aW9uIGFzc2lnblZhbHVlKHZhbCwga2V5KSB7XG4gICAgaWYgKHR5cGVvZiByZXN1bHRba2V5XSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJlc3VsdFtrZXldID0gbWVyZ2UocmVzdWx0W2tleV0sIHZhbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdFtrZXldID0gdmFsO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGZvckVhY2goYXJndW1lbnRzW2ldLCBhc3NpZ25WYWx1ZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBFeHRlbmRzIG9iamVjdCBhIGJ5IG11dGFibHkgYWRkaW5nIHRvIGl0IHRoZSBwcm9wZXJ0aWVzIG9mIG9iamVjdCBiLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBhIFRoZSBvYmplY3QgdG8gYmUgZXh0ZW5kZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBiIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIGZyb21cbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGlzQXJnIFRoZSBvYmplY3QgdG8gYmluZCBmdW5jdGlvbiB0b1xuICogQHJldHVybiB7T2JqZWN0fSBUaGUgcmVzdWx0aW5nIHZhbHVlIG9mIG9iamVjdCBhXG4gKi9cbmZ1bmN0aW9uIGV4dGVuZChhLCBiLCB0aGlzQXJnKSB7XG4gIGZvckVhY2goYiwgZnVuY3Rpb24gYXNzaWduVmFsdWUodmFsLCBrZXkpIHtcbiAgICBpZiAodGhpc0FyZyAmJiB0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBhW2tleV0gPSBiaW5kKHZhbCwgdGhpc0FyZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFba2V5XSA9IHZhbDtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gYTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGlzQXJyYXk6IGlzQXJyYXksXG4gIGlzQXJyYXlCdWZmZXI6IGlzQXJyYXlCdWZmZXIsXG4gIGlzQnVmZmVyOiBpc0J1ZmZlcixcbiAgaXNGb3JtRGF0YTogaXNGb3JtRGF0YSxcbiAgaXNBcnJheUJ1ZmZlclZpZXc6IGlzQXJyYXlCdWZmZXJWaWV3LFxuICBpc1N0cmluZzogaXNTdHJpbmcsXG4gIGlzTnVtYmVyOiBpc051bWJlcixcbiAgaXNPYmplY3Q6IGlzT2JqZWN0LFxuICBpc1VuZGVmaW5lZDogaXNVbmRlZmluZWQsXG4gIGlzRGF0ZTogaXNEYXRlLFxuICBpc0ZpbGU6IGlzRmlsZSxcbiAgaXNCbG9iOiBpc0Jsb2IsXG4gIGlzRnVuY3Rpb246IGlzRnVuY3Rpb24sXG4gIGlzU3RyZWFtOiBpc1N0cmVhbSxcbiAgaXNVUkxTZWFyY2hQYXJhbXM6IGlzVVJMU2VhcmNoUGFyYW1zLFxuICBpc1N0YW5kYXJkQnJvd3NlckVudjogaXNTdGFuZGFyZEJyb3dzZXJFbnYsXG4gIGZvckVhY2g6IGZvckVhY2gsXG4gIG1lcmdlOiBtZXJnZSxcbiAgZXh0ZW5kOiBleHRlbmQsXG4gIHRyaW06IHRyaW1cbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbm9ybWFsaXplSGVhZGVyTmFtZShoZWFkZXJzLCBub3JtYWxpemVkTmFtZSkge1xuICB1dGlscy5mb3JFYWNoKGhlYWRlcnMsIGZ1bmN0aW9uIHByb2Nlc3NIZWFkZXIodmFsdWUsIG5hbWUpIHtcbiAgICBpZiAobmFtZSAhPT0gbm9ybWFsaXplZE5hbWUgJiYgbmFtZS50b1VwcGVyQ2FzZSgpID09PSBub3JtYWxpemVkTmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICBoZWFkZXJzW25vcm1hbGl6ZWROYW1lXSA9IHZhbHVlO1xuICAgICAgZGVsZXRlIGhlYWRlcnNbbmFtZV07XG4gICAgfVxuICB9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogVXBkYXRlIGFuIEVycm9yIHdpdGggdGhlIHNwZWNpZmllZCBjb25maWcsIGVycm9yIGNvZGUsIGFuZCByZXNwb25zZS5cbiAqXG4gKiBAcGFyYW0ge0Vycm9yfSBlcnJvciBUaGUgZXJyb3IgdG8gdXBkYXRlLlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyBUaGUgY29uZmlnLlxuICogQHBhcmFtIHtzdHJpbmd9IFtjb2RlXSBUaGUgZXJyb3IgY29kZSAoZm9yIGV4YW1wbGUsICdFQ09OTkFCT1JURUQnKS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVxdWVzdF0gVGhlIHJlcXVlc3QuXG4gKiBAcGFyYW0ge09iamVjdH0gW3Jlc3BvbnNlXSBUaGUgcmVzcG9uc2UuXG4gKiBAcmV0dXJucyB7RXJyb3J9IFRoZSBlcnJvci5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBlbmhhbmNlRXJyb3IoZXJyb3IsIGNvbmZpZywgY29kZSwgcmVxdWVzdCwgcmVzcG9uc2UpIHtcbiAgZXJyb3IuY29uZmlnID0gY29uZmlnO1xuICBpZiAoY29kZSkge1xuICAgIGVycm9yLmNvZGUgPSBjb2RlO1xuICB9XG4gIGVycm9yLnJlcXVlc3QgPSByZXF1ZXN0O1xuICBlcnJvci5yZXNwb25zZSA9IHJlc3BvbnNlO1xuICByZXR1cm4gZXJyb3I7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZW5oYW5jZUVycm9yID0gcmVxdWlyZSgnLi9lbmhhbmNlRXJyb3InKTtcblxuLyoqXG4gKiBDcmVhdGUgYW4gRXJyb3Igd2l0aCB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UsIGNvbmZpZywgZXJyb3IgY29kZSwgcmVxdWVzdCBhbmQgcmVzcG9uc2UuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgVGhlIGVycm9yIG1lc3NhZ2UuXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIFRoZSBjb25maWcuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2NvZGVdIFRoZSBlcnJvciBjb2RlIChmb3IgZXhhbXBsZSwgJ0VDT05OQUJPUlRFRCcpLlxuICogQHBhcmFtIHtPYmplY3R9IFtyZXF1ZXN0XSBUaGUgcmVxdWVzdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVzcG9uc2VdIFRoZSByZXNwb25zZS5cbiAqIEByZXR1cm5zIHtFcnJvcn0gVGhlIGNyZWF0ZWQgZXJyb3IuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlRXJyb3IobWVzc2FnZSwgY29uZmlnLCBjb2RlLCByZXF1ZXN0LCByZXNwb25zZSkge1xuICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSk7XG4gIHJldHVybiBlbmhhbmNlRXJyb3IoZXJyb3IsIGNvbmZpZywgY29kZSwgcmVxdWVzdCwgcmVzcG9uc2UpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNyZWF0ZUVycm9yID0gcmVxdWlyZSgnLi9jcmVhdGVFcnJvcicpO1xuXG4vKipcbiAqIFJlc29sdmUgb3IgcmVqZWN0IGEgUHJvbWlzZSBiYXNlZCBvbiByZXNwb25zZSBzdGF0dXMuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVzb2x2ZSBBIGZ1bmN0aW9uIHRoYXQgcmVzb2x2ZXMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3QgQSBmdW5jdGlvbiB0aGF0IHJlamVjdHMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge29iamVjdH0gcmVzcG9uc2UgVGhlIHJlc3BvbnNlLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlKSB7XG4gIHZhciB2YWxpZGF0ZVN0YXR1cyA9IHJlc3BvbnNlLmNvbmZpZy52YWxpZGF0ZVN0YXR1cztcbiAgLy8gTm90ZTogc3RhdHVzIGlzIG5vdCBleHBvc2VkIGJ5IFhEb21haW5SZXF1ZXN0XG4gIGlmICghcmVzcG9uc2Uuc3RhdHVzIHx8ICF2YWxpZGF0ZVN0YXR1cyB8fCB2YWxpZGF0ZVN0YXR1cyhyZXNwb25zZS5zdGF0dXMpKSB7XG4gICAgcmVzb2x2ZShyZXNwb25zZSk7XG4gIH0gZWxzZSB7XG4gICAgcmVqZWN0KGNyZWF0ZUVycm9yKFxuICAgICAgJ1JlcXVlc3QgZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgJyArIHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIHJlc3BvbnNlLmNvbmZpZyxcbiAgICAgIG51bGwsXG4gICAgICByZXNwb25zZS5yZXF1ZXN0LFxuICAgICAgcmVzcG9uc2VcbiAgICApKTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi8uLi91dGlscycpO1xuXG5mdW5jdGlvbiBlbmNvZGUodmFsKSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQodmFsKS5cbiAgICByZXBsYWNlKC8lNDAvZ2ksICdAJykuXG4gICAgcmVwbGFjZSgvJTNBL2dpLCAnOicpLlxuICAgIHJlcGxhY2UoLyUyNC9nLCAnJCcpLlxuICAgIHJlcGxhY2UoLyUyQy9naSwgJywnKS5cbiAgICByZXBsYWNlKC8lMjAvZywgJysnKS5cbiAgICByZXBsYWNlKC8lNUIvZ2ksICdbJykuXG4gICAgcmVwbGFjZSgvJTVEL2dpLCAnXScpO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgVVJMIGJ5IGFwcGVuZGluZyBwYXJhbXMgdG8gdGhlIGVuZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIGJhc2Ugb2YgdGhlIHVybCAoZS5nLiwgaHR0cDovL3d3dy5nb29nbGUuY29tKVxuICogQHBhcmFtIHtvYmplY3R9IFtwYXJhbXNdIFRoZSBwYXJhbXMgdG8gYmUgYXBwZW5kZWRcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBmb3JtYXR0ZWQgdXJsXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYnVpbGRVUkwodXJsLCBwYXJhbXMsIHBhcmFtc1NlcmlhbGl6ZXIpIHtcbiAgLyplc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246MCovXG4gIGlmICghcGFyYW1zKSB7XG4gICAgcmV0dXJuIHVybDtcbiAgfVxuXG4gIHZhciBzZXJpYWxpemVkUGFyYW1zO1xuICBpZiAocGFyYW1zU2VyaWFsaXplcikge1xuICAgIHNlcmlhbGl6ZWRQYXJhbXMgPSBwYXJhbXNTZXJpYWxpemVyKHBhcmFtcyk7XG4gIH0gZWxzZSBpZiAodXRpbHMuaXNVUkxTZWFyY2hQYXJhbXMocGFyYW1zKSkge1xuICAgIHNlcmlhbGl6ZWRQYXJhbXMgPSBwYXJhbXMudG9TdHJpbmcoKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgcGFydHMgPSBbXTtcblxuICAgIHV0aWxzLmZvckVhY2gocGFyYW1zLCBmdW5jdGlvbiBzZXJpYWxpemUodmFsLCBrZXkpIHtcbiAgICAgIGlmICh2YWwgPT09IG51bGwgfHwgdHlwZW9mIHZhbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodXRpbHMuaXNBcnJheSh2YWwpKSB7XG4gICAgICAgIGtleSA9IGtleSArICdbXSc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWwgPSBbdmFsXTtcbiAgICAgIH1cblxuICAgICAgdXRpbHMuZm9yRWFjaCh2YWwsIGZ1bmN0aW9uIHBhcnNlVmFsdWUodikge1xuICAgICAgICBpZiAodXRpbHMuaXNEYXRlKHYpKSB7XG4gICAgICAgICAgdiA9IHYudG9JU09TdHJpbmcoKTtcbiAgICAgICAgfSBlbHNlIGlmICh1dGlscy5pc09iamVjdCh2KSkge1xuICAgICAgICAgIHYgPSBKU09OLnN0cmluZ2lmeSh2KTtcbiAgICAgICAgfVxuICAgICAgICBwYXJ0cy5wdXNoKGVuY29kZShrZXkpICsgJz0nICsgZW5jb2RlKHYpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgc2VyaWFsaXplZFBhcmFtcyA9IHBhcnRzLmpvaW4oJyYnKTtcbiAgfVxuXG4gIGlmIChzZXJpYWxpemVkUGFyYW1zKSB7XG4gICAgdXJsICs9ICh1cmwuaW5kZXhPZignPycpID09PSAtMSA/ICc/JyA6ICcmJykgKyBzZXJpYWxpemVkUGFyYW1zO1xuICB9XG5cbiAgcmV0dXJuIHVybDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcblxuLy8gSGVhZGVycyB3aG9zZSBkdXBsaWNhdGVzIGFyZSBpZ25vcmVkIGJ5IG5vZGVcbi8vIGMuZi4gaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9odHRwLmh0bWwjaHR0cF9tZXNzYWdlX2hlYWRlcnNcbnZhciBpZ25vcmVEdXBsaWNhdGVPZiA9IFtcbiAgJ2FnZScsICdhdXRob3JpemF0aW9uJywgJ2NvbnRlbnQtbGVuZ3RoJywgJ2NvbnRlbnQtdHlwZScsICdldGFnJyxcbiAgJ2V4cGlyZXMnLCAnZnJvbScsICdob3N0JywgJ2lmLW1vZGlmaWVkLXNpbmNlJywgJ2lmLXVubW9kaWZpZWQtc2luY2UnLFxuICAnbGFzdC1tb2RpZmllZCcsICdsb2NhdGlvbicsICdtYXgtZm9yd2FyZHMnLCAncHJveHktYXV0aG9yaXphdGlvbicsXG4gICdyZWZlcmVyJywgJ3JldHJ5LWFmdGVyJywgJ3VzZXItYWdlbnQnXG5dO1xuXG4vKipcbiAqIFBhcnNlIGhlYWRlcnMgaW50byBhbiBvYmplY3RcbiAqXG4gKiBgYGBcbiAqIERhdGU6IFdlZCwgMjcgQXVnIDIwMTQgMDg6NTg6NDkgR01UXG4gKiBDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL2pzb25cbiAqIENvbm5lY3Rpb246IGtlZXAtYWxpdmVcbiAqIFRyYW5zZmVyLUVuY29kaW5nOiBjaHVua2VkXG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gaGVhZGVycyBIZWFkZXJzIG5lZWRpbmcgdG8gYmUgcGFyc2VkXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBIZWFkZXJzIHBhcnNlZCBpbnRvIGFuIG9iamVjdFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhcnNlSGVhZGVycyhoZWFkZXJzKSB7XG4gIHZhciBwYXJzZWQgPSB7fTtcbiAgdmFyIGtleTtcbiAgdmFyIHZhbDtcbiAgdmFyIGk7XG5cbiAgaWYgKCFoZWFkZXJzKSB7IHJldHVybiBwYXJzZWQ7IH1cblxuICB1dGlscy5mb3JFYWNoKGhlYWRlcnMuc3BsaXQoJ1xcbicpLCBmdW5jdGlvbiBwYXJzZXIobGluZSkge1xuICAgIGkgPSBsaW5lLmluZGV4T2YoJzonKTtcbiAgICBrZXkgPSB1dGlscy50cmltKGxpbmUuc3Vic3RyKDAsIGkpKS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhbCA9IHV0aWxzLnRyaW0obGluZS5zdWJzdHIoaSArIDEpKTtcblxuICAgIGlmIChrZXkpIHtcbiAgICAgIGlmIChwYXJzZWRba2V5XSAmJiBpZ25vcmVEdXBsaWNhdGVPZi5pbmRleE9mKGtleSkgPj0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoa2V5ID09PSAnc2V0LWNvb2tpZScpIHtcbiAgICAgICAgcGFyc2VkW2tleV0gPSAocGFyc2VkW2tleV0gPyBwYXJzZWRba2V5XSA6IFtdKS5jb25jYXQoW3ZhbF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFyc2VkW2tleV0gPSBwYXJzZWRba2V5XSA/IHBhcnNlZFtrZXldICsgJywgJyArIHZhbCA6IHZhbDtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBwYXJzZWQ7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKFxuICB1dGlscy5pc1N0YW5kYXJkQnJvd3NlckVudigpID9cblxuICAvLyBTdGFuZGFyZCBicm93c2VyIGVudnMgaGF2ZSBmdWxsIHN1cHBvcnQgb2YgdGhlIEFQSXMgbmVlZGVkIHRvIHRlc3RcbiAgLy8gd2hldGhlciB0aGUgcmVxdWVzdCBVUkwgaXMgb2YgdGhlIHNhbWUgb3JpZ2luIGFzIGN1cnJlbnQgbG9jYXRpb24uXG4gIChmdW5jdGlvbiBzdGFuZGFyZEJyb3dzZXJFbnYoKSB7XG4gICAgdmFyIG1zaWUgPSAvKG1zaWV8dHJpZGVudCkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICAgIHZhciB1cmxQYXJzaW5nTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICB2YXIgb3JpZ2luVVJMO1xuXG4gICAgLyoqXG4gICAgKiBQYXJzZSBhIFVSTCB0byBkaXNjb3ZlciBpdCdzIGNvbXBvbmVudHNcbiAgICAqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gdXJsIFRoZSBVUkwgdG8gYmUgcGFyc2VkXG4gICAgKiBAcmV0dXJucyB7T2JqZWN0fVxuICAgICovXG4gICAgZnVuY3Rpb24gcmVzb2x2ZVVSTCh1cmwpIHtcbiAgICAgIHZhciBocmVmID0gdXJsO1xuXG4gICAgICBpZiAobXNpZSkge1xuICAgICAgICAvLyBJRSBuZWVkcyBhdHRyaWJ1dGUgc2V0IHR3aWNlIHRvIG5vcm1hbGl6ZSBwcm9wZXJ0aWVzXG4gICAgICAgIHVybFBhcnNpbmdOb2RlLnNldEF0dHJpYnV0ZSgnaHJlZicsIGhyZWYpO1xuICAgICAgICBocmVmID0gdXJsUGFyc2luZ05vZGUuaHJlZjtcbiAgICAgIH1cblxuICAgICAgdXJsUGFyc2luZ05vZGUuc2V0QXR0cmlidXRlKCdocmVmJywgaHJlZik7XG5cbiAgICAgIC8vIHVybFBhcnNpbmdOb2RlIHByb3ZpZGVzIHRoZSBVcmxVdGlscyBpbnRlcmZhY2UgLSBodHRwOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jdXJsdXRpbHNcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGhyZWY6IHVybFBhcnNpbmdOb2RlLmhyZWYsXG4gICAgICAgIHByb3RvY29sOiB1cmxQYXJzaW5nTm9kZS5wcm90b2NvbCA/IHVybFBhcnNpbmdOb2RlLnByb3RvY29sLnJlcGxhY2UoLzokLywgJycpIDogJycsXG4gICAgICAgIGhvc3Q6IHVybFBhcnNpbmdOb2RlLmhvc3QsXG4gICAgICAgIHNlYXJjaDogdXJsUGFyc2luZ05vZGUuc2VhcmNoID8gdXJsUGFyc2luZ05vZGUuc2VhcmNoLnJlcGxhY2UoL15cXD8vLCAnJykgOiAnJyxcbiAgICAgICAgaGFzaDogdXJsUGFyc2luZ05vZGUuaGFzaCA/IHVybFBhcnNpbmdOb2RlLmhhc2gucmVwbGFjZSgvXiMvLCAnJykgOiAnJyxcbiAgICAgICAgaG9zdG5hbWU6IHVybFBhcnNpbmdOb2RlLmhvc3RuYW1lLFxuICAgICAgICBwb3J0OiB1cmxQYXJzaW5nTm9kZS5wb3J0LFxuICAgICAgICBwYXRobmFtZTogKHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nKSA/XG4gICAgICAgICAgICAgICAgICB1cmxQYXJzaW5nTm9kZS5wYXRobmFtZSA6XG4gICAgICAgICAgICAgICAgICAnLycgKyB1cmxQYXJzaW5nTm9kZS5wYXRobmFtZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBvcmlnaW5VUkwgPSByZXNvbHZlVVJMKHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcblxuICAgIC8qKlxuICAgICogRGV0ZXJtaW5lIGlmIGEgVVJMIHNoYXJlcyB0aGUgc2FtZSBvcmlnaW4gYXMgdGhlIGN1cnJlbnQgbG9jYXRpb25cbiAgICAqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gcmVxdWVzdFVSTCBUaGUgVVJMIHRvIHRlc3RcbiAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIFVSTCBzaGFyZXMgdGhlIHNhbWUgb3JpZ2luLCBvdGhlcndpc2UgZmFsc2VcbiAgICAqL1xuICAgIHJldHVybiBmdW5jdGlvbiBpc1VSTFNhbWVPcmlnaW4ocmVxdWVzdFVSTCkge1xuICAgICAgdmFyIHBhcnNlZCA9ICh1dGlscy5pc1N0cmluZyhyZXF1ZXN0VVJMKSkgPyByZXNvbHZlVVJMKHJlcXVlc3RVUkwpIDogcmVxdWVzdFVSTDtcbiAgICAgIHJldHVybiAocGFyc2VkLnByb3RvY29sID09PSBvcmlnaW5VUkwucHJvdG9jb2wgJiZcbiAgICAgICAgICAgIHBhcnNlZC5ob3N0ID09PSBvcmlnaW5VUkwuaG9zdCk7XG4gICAgfTtcbiAgfSkoKSA6XG5cbiAgLy8gTm9uIHN0YW5kYXJkIGJyb3dzZXIgZW52cyAod2ViIHdvcmtlcnMsIHJlYWN0LW5hdGl2ZSkgbGFjayBuZWVkZWQgc3VwcG9ydC5cbiAgKGZ1bmN0aW9uIG5vblN0YW5kYXJkQnJvd3NlckVudigpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gaXNVUkxTYW1lT3JpZ2luKCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgfSkoKVxuKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gYnRvYSBwb2x5ZmlsbCBmb3IgSUU8MTAgY291cnRlc3kgaHR0cHM6Ly9naXRodWIuY29tL2RhdmlkY2hhbWJlcnMvQmFzZTY0LmpzXG5cbnZhciBjaGFycyA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPSc7XG5cbmZ1bmN0aW9uIEUoKSB7XG4gIHRoaXMubWVzc2FnZSA9ICdTdHJpbmcgY29udGFpbnMgYW4gaW52YWxpZCBjaGFyYWN0ZXInO1xufVxuRS5wcm90b3R5cGUgPSBuZXcgRXJyb3I7XG5FLnByb3RvdHlwZS5jb2RlID0gNTtcbkUucHJvdG90eXBlLm5hbWUgPSAnSW52YWxpZENoYXJhY3RlckVycm9yJztcblxuZnVuY3Rpb24gYnRvYShpbnB1dCkge1xuICB2YXIgc3RyID0gU3RyaW5nKGlucHV0KTtcbiAgdmFyIG91dHB1dCA9ICcnO1xuICBmb3IgKFxuICAgIC8vIGluaXRpYWxpemUgcmVzdWx0IGFuZCBjb3VudGVyXG4gICAgdmFyIGJsb2NrLCBjaGFyQ29kZSwgaWR4ID0gMCwgbWFwID0gY2hhcnM7XG4gICAgLy8gaWYgdGhlIG5leHQgc3RyIGluZGV4IGRvZXMgbm90IGV4aXN0OlxuICAgIC8vICAgY2hhbmdlIHRoZSBtYXBwaW5nIHRhYmxlIHRvIFwiPVwiXG4gICAgLy8gICBjaGVjayBpZiBkIGhhcyBubyBmcmFjdGlvbmFsIGRpZ2l0c1xuICAgIHN0ci5jaGFyQXQoaWR4IHwgMCkgfHwgKG1hcCA9ICc9JywgaWR4ICUgMSk7XG4gICAgLy8gXCI4IC0gaWR4ICUgMSAqIDhcIiBnZW5lcmF0ZXMgdGhlIHNlcXVlbmNlIDIsIDQsIDYsIDhcbiAgICBvdXRwdXQgKz0gbWFwLmNoYXJBdCg2MyAmIGJsb2NrID4+IDggLSBpZHggJSAxICogOClcbiAgKSB7XG4gICAgY2hhckNvZGUgPSBzdHIuY2hhckNvZGVBdChpZHggKz0gMyAvIDQpO1xuICAgIGlmIChjaGFyQ29kZSA+IDB4RkYpIHtcbiAgICAgIHRocm93IG5ldyBFKCk7XG4gICAgfVxuICAgIGJsb2NrID0gYmxvY2sgPDwgOCB8IGNoYXJDb2RlO1xuICB9XG4gIHJldHVybiBvdXRwdXQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnRvYTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi8uLi91dGlscycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChcbiAgdXRpbHMuaXNTdGFuZGFyZEJyb3dzZXJFbnYoKSA/XG5cbiAgLy8gU3RhbmRhcmQgYnJvd3NlciBlbnZzIHN1cHBvcnQgZG9jdW1lbnQuY29va2llXG4gIChmdW5jdGlvbiBzdGFuZGFyZEJyb3dzZXJFbnYoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHdyaXRlOiBmdW5jdGlvbiB3cml0ZShuYW1lLCB2YWx1ZSwgZXhwaXJlcywgcGF0aCwgZG9tYWluLCBzZWN1cmUpIHtcbiAgICAgICAgdmFyIGNvb2tpZSA9IFtdO1xuICAgICAgICBjb29raWUucHVzaChuYW1lICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKSk7XG5cbiAgICAgICAgaWYgKHV0aWxzLmlzTnVtYmVyKGV4cGlyZXMpKSB7XG4gICAgICAgICAgY29va2llLnB1c2goJ2V4cGlyZXM9JyArIG5ldyBEYXRlKGV4cGlyZXMpLnRvR01UU3RyaW5nKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHV0aWxzLmlzU3RyaW5nKHBhdGgpKSB7XG4gICAgICAgICAgY29va2llLnB1c2goJ3BhdGg9JyArIHBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHV0aWxzLmlzU3RyaW5nKGRvbWFpbikpIHtcbiAgICAgICAgICBjb29raWUucHVzaCgnZG9tYWluPScgKyBkb21haW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNlY3VyZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgIGNvb2tpZS5wdXNoKCdzZWN1cmUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRvY3VtZW50LmNvb2tpZSA9IGNvb2tpZS5qb2luKCc7ICcpO1xuICAgICAgfSxcblxuICAgICAgcmVhZDogZnVuY3Rpb24gcmVhZChuYW1lKSB7XG4gICAgICAgIHZhciBtYXRjaCA9IGRvY3VtZW50LmNvb2tpZS5tYXRjaChuZXcgUmVnRXhwKCcoXnw7XFxcXHMqKSgnICsgbmFtZSArICcpPShbXjtdKiknKSk7XG4gICAgICAgIHJldHVybiAobWF0Y2ggPyBkZWNvZGVVUklDb21wb25lbnQobWF0Y2hbM10pIDogbnVsbCk7XG4gICAgICB9LFxuXG4gICAgICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZShuYW1lKSB7XG4gICAgICAgIHRoaXMud3JpdGUobmFtZSwgJycsIERhdGUubm93KCkgLSA4NjQwMDAwMCk7XG4gICAgICB9XG4gICAgfTtcbiAgfSkoKSA6XG5cbiAgLy8gTm9uIHN0YW5kYXJkIGJyb3dzZXIgZW52ICh3ZWIgd29ya2VycywgcmVhY3QtbmF0aXZlKSBsYWNrIG5lZWRlZCBzdXBwb3J0LlxuICAoZnVuY3Rpb24gbm9uU3RhbmRhcmRCcm93c2VyRW52KCkge1xuICAgIHJldHVybiB7XG4gICAgICB3cml0ZTogZnVuY3Rpb24gd3JpdGUoKSB7fSxcbiAgICAgIHJlYWQ6IGZ1bmN0aW9uIHJlYWQoKSB7IHJldHVybiBudWxsOyB9LFxuICAgICAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUoKSB7fVxuICAgIH07XG4gIH0pKClcbik7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcbnZhciBzZXR0bGUgPSByZXF1aXJlKCcuLy4uL2NvcmUvc2V0dGxlJyk7XG52YXIgYnVpbGRVUkwgPSByZXF1aXJlKCcuLy4uL2hlbHBlcnMvYnVpbGRVUkwnKTtcbnZhciBwYXJzZUhlYWRlcnMgPSByZXF1aXJlKCcuLy4uL2hlbHBlcnMvcGFyc2VIZWFkZXJzJyk7XG52YXIgaXNVUkxTYW1lT3JpZ2luID0gcmVxdWlyZSgnLi8uLi9oZWxwZXJzL2lzVVJMU2FtZU9yaWdpbicpO1xudmFyIGNyZWF0ZUVycm9yID0gcmVxdWlyZSgnLi4vY29yZS9jcmVhdGVFcnJvcicpO1xudmFyIGJ0b2EgPSAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmJ0b2EgJiYgd2luZG93LmJ0b2EuYmluZCh3aW5kb3cpKSB8fCByZXF1aXJlKCcuLy4uL2hlbHBlcnMvYnRvYScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHhockFkYXB0ZXIoY29uZmlnKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiBkaXNwYXRjaFhoclJlcXVlc3QocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgdmFyIHJlcXVlc3REYXRhID0gY29uZmlnLmRhdGE7XG4gICAgdmFyIHJlcXVlc3RIZWFkZXJzID0gY29uZmlnLmhlYWRlcnM7XG5cbiAgICBpZiAodXRpbHMuaXNGb3JtRGF0YShyZXF1ZXN0RGF0YSkpIHtcbiAgICAgIGRlbGV0ZSByZXF1ZXN0SGVhZGVyc1snQ29udGVudC1UeXBlJ107IC8vIExldCB0aGUgYnJvd3NlciBzZXQgaXRcbiAgICB9XG5cbiAgICB2YXIgcmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIHZhciBsb2FkRXZlbnQgPSAnb25yZWFkeXN0YXRlY2hhbmdlJztcbiAgICB2YXIgeERvbWFpbiA9IGZhbHNlO1xuXG4gICAgLy8gRm9yIElFIDgvOSBDT1JTIHN1cHBvcnRcbiAgICAvLyBPbmx5IHN1cHBvcnRzIFBPU1QgYW5kIEdFVCBjYWxscyBhbmQgZG9lc24ndCByZXR1cm5zIHRoZSByZXNwb25zZSBoZWFkZXJzLlxuICAgIC8vIERPTidUIGRvIHRoaXMgZm9yIHRlc3RpbmcgYi9jIFhNTEh0dHBSZXF1ZXN0IGlzIG1vY2tlZCwgbm90IFhEb21haW5SZXF1ZXN0LlxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnICYmXG4gICAgICAgIHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIHdpbmRvdy5YRG9tYWluUmVxdWVzdCAmJiAhKCd3aXRoQ3JlZGVudGlhbHMnIGluIHJlcXVlc3QpICYmXG4gICAgICAgICFpc1VSTFNhbWVPcmlnaW4oY29uZmlnLnVybCkpIHtcbiAgICAgIHJlcXVlc3QgPSBuZXcgd2luZG93LlhEb21haW5SZXF1ZXN0KCk7XG4gICAgICBsb2FkRXZlbnQgPSAnb25sb2FkJztcbiAgICAgIHhEb21haW4gPSB0cnVlO1xuICAgICAgcmVxdWVzdC5vbnByb2dyZXNzID0gZnVuY3Rpb24gaGFuZGxlUHJvZ3Jlc3MoKSB7fTtcbiAgICAgIHJlcXVlc3Qub250aW1lb3V0ID0gZnVuY3Rpb24gaGFuZGxlVGltZW91dCgpIHt9O1xuICAgIH1cblxuICAgIC8vIEhUVFAgYmFzaWMgYXV0aGVudGljYXRpb25cbiAgICBpZiAoY29uZmlnLmF1dGgpIHtcbiAgICAgIHZhciB1c2VybmFtZSA9IGNvbmZpZy5hdXRoLnVzZXJuYW1lIHx8ICcnO1xuICAgICAgdmFyIHBhc3N3b3JkID0gY29uZmlnLmF1dGgucGFzc3dvcmQgfHwgJyc7XG4gICAgICByZXF1ZXN0SGVhZGVycy5BdXRob3JpemF0aW9uID0gJ0Jhc2ljICcgKyBidG9hKHVzZXJuYW1lICsgJzonICsgcGFzc3dvcmQpO1xuICAgIH1cblxuICAgIHJlcXVlc3Qub3Blbihjb25maWcubWV0aG9kLnRvVXBwZXJDYXNlKCksIGJ1aWxkVVJMKGNvbmZpZy51cmwsIGNvbmZpZy5wYXJhbXMsIGNvbmZpZy5wYXJhbXNTZXJpYWxpemVyKSwgdHJ1ZSk7XG5cbiAgICAvLyBTZXQgdGhlIHJlcXVlc3QgdGltZW91dCBpbiBNU1xuICAgIHJlcXVlc3QudGltZW91dCA9IGNvbmZpZy50aW1lb3V0O1xuXG4gICAgLy8gTGlzdGVuIGZvciByZWFkeSBzdGF0ZVxuICAgIHJlcXVlc3RbbG9hZEV2ZW50XSA9IGZ1bmN0aW9uIGhhbmRsZUxvYWQoKSB7XG4gICAgICBpZiAoIXJlcXVlc3QgfHwgKHJlcXVlc3QucmVhZHlTdGF0ZSAhPT0gNCAmJiAheERvbWFpbikpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBUaGUgcmVxdWVzdCBlcnJvcmVkIG91dCBhbmQgd2UgZGlkbid0IGdldCBhIHJlc3BvbnNlLCB0aGlzIHdpbGwgYmVcbiAgICAgIC8vIGhhbmRsZWQgYnkgb25lcnJvciBpbnN0ZWFkXG4gICAgICAvLyBXaXRoIG9uZSBleGNlcHRpb246IHJlcXVlc3QgdGhhdCB1c2luZyBmaWxlOiBwcm90b2NvbCwgbW9zdCBicm93c2Vyc1xuICAgICAgLy8gd2lsbCByZXR1cm4gc3RhdHVzIGFzIDAgZXZlbiB0aG91Z2ggaXQncyBhIHN1Y2Nlc3NmdWwgcmVxdWVzdFxuICAgICAgaWYgKHJlcXVlc3Quc3RhdHVzID09PSAwICYmICEocmVxdWVzdC5yZXNwb25zZVVSTCAmJiByZXF1ZXN0LnJlc3BvbnNlVVJMLmluZGV4T2YoJ2ZpbGU6JykgPT09IDApKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gUHJlcGFyZSB0aGUgcmVzcG9uc2VcbiAgICAgIHZhciByZXNwb25zZUhlYWRlcnMgPSAnZ2V0QWxsUmVzcG9uc2VIZWFkZXJzJyBpbiByZXF1ZXN0ID8gcGFyc2VIZWFkZXJzKHJlcXVlc3QuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpIDogbnVsbDtcbiAgICAgIHZhciByZXNwb25zZURhdGEgPSAhY29uZmlnLnJlc3BvbnNlVHlwZSB8fCBjb25maWcucmVzcG9uc2VUeXBlID09PSAndGV4dCcgPyByZXF1ZXN0LnJlc3BvbnNlVGV4dCA6IHJlcXVlc3QucmVzcG9uc2U7XG4gICAgICB2YXIgcmVzcG9uc2UgPSB7XG4gICAgICAgIGRhdGE6IHJlc3BvbnNlRGF0YSxcbiAgICAgICAgLy8gSUUgc2VuZHMgMTIyMyBpbnN0ZWFkIG9mIDIwNCAoaHR0cHM6Ly9naXRodWIuY29tL2F4aW9zL2F4aW9zL2lzc3Vlcy8yMDEpXG4gICAgICAgIHN0YXR1czogcmVxdWVzdC5zdGF0dXMgPT09IDEyMjMgPyAyMDQgOiByZXF1ZXN0LnN0YXR1cyxcbiAgICAgICAgc3RhdHVzVGV4dDogcmVxdWVzdC5zdGF0dXMgPT09IDEyMjMgPyAnTm8gQ29udGVudCcgOiByZXF1ZXN0LnN0YXR1c1RleHQsXG4gICAgICAgIGhlYWRlcnM6IHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgY29uZmlnOiBjb25maWcsXG4gICAgICAgIHJlcXVlc3Q6IHJlcXVlc3RcbiAgICAgIH07XG5cbiAgICAgIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdFxuICAgICAgcmVxdWVzdCA9IG51bGw7XG4gICAgfTtcblxuICAgIC8vIEhhbmRsZSBsb3cgbGV2ZWwgbmV0d29yayBlcnJvcnNcbiAgICByZXF1ZXN0Lm9uZXJyb3IgPSBmdW5jdGlvbiBoYW5kbGVFcnJvcigpIHtcbiAgICAgIC8vIFJlYWwgZXJyb3JzIGFyZSBoaWRkZW4gZnJvbSB1cyBieSB0aGUgYnJvd3NlclxuICAgICAgLy8gb25lcnJvciBzaG91bGQgb25seSBmaXJlIGlmIGl0J3MgYSBuZXR3b3JrIGVycm9yXG4gICAgICByZWplY3QoY3JlYXRlRXJyb3IoJ05ldHdvcmsgRXJyb3InLCBjb25maWcsIG51bGwsIHJlcXVlc3QpKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdFxuICAgICAgcmVxdWVzdCA9IG51bGw7XG4gICAgfTtcblxuICAgIC8vIEhhbmRsZSB0aW1lb3V0XG4gICAgcmVxdWVzdC5vbnRpbWVvdXQgPSBmdW5jdGlvbiBoYW5kbGVUaW1lb3V0KCkge1xuICAgICAgcmVqZWN0KGNyZWF0ZUVycm9yKCd0aW1lb3V0IG9mICcgKyBjb25maWcudGltZW91dCArICdtcyBleGNlZWRlZCcsIGNvbmZpZywgJ0VDT05OQUJPUlRFRCcsXG4gICAgICAgIHJlcXVlc3QpKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdFxuICAgICAgcmVxdWVzdCA9IG51bGw7XG4gICAgfTtcblxuICAgIC8vIEFkZCB4c3JmIGhlYWRlclxuICAgIC8vIFRoaXMgaXMgb25seSBkb25lIGlmIHJ1bm5pbmcgaW4gYSBzdGFuZGFyZCBicm93c2VyIGVudmlyb25tZW50LlxuICAgIC8vIFNwZWNpZmljYWxseSBub3QgaWYgd2UncmUgaW4gYSB3ZWIgd29ya2VyLCBvciByZWFjdC1uYXRpdmUuXG4gICAgaWYgKHV0aWxzLmlzU3RhbmRhcmRCcm93c2VyRW52KCkpIHtcbiAgICAgIHZhciBjb29raWVzID0gcmVxdWlyZSgnLi8uLi9oZWxwZXJzL2Nvb2tpZXMnKTtcblxuICAgICAgLy8gQWRkIHhzcmYgaGVhZGVyXG4gICAgICB2YXIgeHNyZlZhbHVlID0gKGNvbmZpZy53aXRoQ3JlZGVudGlhbHMgfHwgaXNVUkxTYW1lT3JpZ2luKGNvbmZpZy51cmwpKSAmJiBjb25maWcueHNyZkNvb2tpZU5hbWUgP1xuICAgICAgICAgIGNvb2tpZXMucmVhZChjb25maWcueHNyZkNvb2tpZU5hbWUpIDpcbiAgICAgICAgICB1bmRlZmluZWQ7XG5cbiAgICAgIGlmICh4c3JmVmFsdWUpIHtcbiAgICAgICAgcmVxdWVzdEhlYWRlcnNbY29uZmlnLnhzcmZIZWFkZXJOYW1lXSA9IHhzcmZWYWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBZGQgaGVhZGVycyB0byB0aGUgcmVxdWVzdFxuICAgIGlmICgnc2V0UmVxdWVzdEhlYWRlcicgaW4gcmVxdWVzdCkge1xuICAgICAgdXRpbHMuZm9yRWFjaChyZXF1ZXN0SGVhZGVycywgZnVuY3Rpb24gc2V0UmVxdWVzdEhlYWRlcih2YWwsIGtleSkge1xuICAgICAgICBpZiAodHlwZW9mIHJlcXVlc3REYXRhID09PSAndW5kZWZpbmVkJyAmJiBrZXkudG9Mb3dlckNhc2UoKSA9PT0gJ2NvbnRlbnQtdHlwZScpIHtcbiAgICAgICAgICAvLyBSZW1vdmUgQ29udGVudC1UeXBlIGlmIGRhdGEgaXMgdW5kZWZpbmVkXG4gICAgICAgICAgZGVsZXRlIHJlcXVlc3RIZWFkZXJzW2tleV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gT3RoZXJ3aXNlIGFkZCBoZWFkZXIgdG8gdGhlIHJlcXVlc3RcbiAgICAgICAgICByZXF1ZXN0LnNldFJlcXVlc3RIZWFkZXIoa2V5LCB2YWwpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBBZGQgd2l0aENyZWRlbnRpYWxzIHRvIHJlcXVlc3QgaWYgbmVlZGVkXG4gICAgaWYgKGNvbmZpZy53aXRoQ3JlZGVudGlhbHMpIHtcbiAgICAgIHJlcXVlc3Qud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBBZGQgcmVzcG9uc2VUeXBlIHRvIHJlcXVlc3QgaWYgbmVlZGVkXG4gICAgaWYgKGNvbmZpZy5yZXNwb25zZVR5cGUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlcXVlc3QucmVzcG9uc2VUeXBlID0gY29uZmlnLnJlc3BvbnNlVHlwZTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gRXhwZWN0ZWQgRE9NRXhjZXB0aW9uIHRocm93biBieSBicm93c2VycyBub3QgY29tcGF0aWJsZSBYTUxIdHRwUmVxdWVzdCBMZXZlbCAyLlxuICAgICAgICAvLyBCdXQsIHRoaXMgY2FuIGJlIHN1cHByZXNzZWQgZm9yICdqc29uJyB0eXBlIGFzIGl0IGNhbiBiZSBwYXJzZWQgYnkgZGVmYXVsdCAndHJhbnNmb3JtUmVzcG9uc2UnIGZ1bmN0aW9uLlxuICAgICAgICBpZiAoY29uZmlnLnJlc3BvbnNlVHlwZSAhPT0gJ2pzb24nKSB7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBwcm9ncmVzcyBpZiBuZWVkZWRcbiAgICBpZiAodHlwZW9mIGNvbmZpZy5vbkRvd25sb2FkUHJvZ3Jlc3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigncHJvZ3Jlc3MnLCBjb25maWcub25Eb3dubG9hZFByb2dyZXNzKTtcbiAgICB9XG5cbiAgICAvLyBOb3QgYWxsIGJyb3dzZXJzIHN1cHBvcnQgdXBsb2FkIGV2ZW50c1xuICAgIGlmICh0eXBlb2YgY29uZmlnLm9uVXBsb2FkUHJvZ3Jlc3MgPT09ICdmdW5jdGlvbicgJiYgcmVxdWVzdC51cGxvYWQpIHtcbiAgICAgIHJlcXVlc3QudXBsb2FkLmFkZEV2ZW50TGlzdGVuZXIoJ3Byb2dyZXNzJywgY29uZmlnLm9uVXBsb2FkUHJvZ3Jlc3MpO1xuICAgIH1cblxuICAgIGlmIChjb25maWcuY2FuY2VsVG9rZW4pIHtcbiAgICAgIC8vIEhhbmRsZSBjYW5jZWxsYXRpb25cbiAgICAgIGNvbmZpZy5jYW5jZWxUb2tlbi5wcm9taXNlLnRoZW4oZnVuY3Rpb24gb25DYW5jZWxlZChjYW5jZWwpIHtcbiAgICAgICAgaWYgKCFyZXF1ZXN0KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVxdWVzdC5hYm9ydCgpO1xuICAgICAgICByZWplY3QoY2FuY2VsKTtcbiAgICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdFxuICAgICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChyZXF1ZXN0RGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXF1ZXN0RGF0YSA9IG51bGw7XG4gICAgfVxuXG4gICAgLy8gU2VuZCB0aGUgcmVxdWVzdFxuICAgIHJlcXVlc3Quc2VuZChyZXF1ZXN0RGF0YSk7XG4gIH0pO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIG5vcm1hbGl6ZUhlYWRlck5hbWUgPSByZXF1aXJlKCcuL2hlbHBlcnMvbm9ybWFsaXplSGVhZGVyTmFtZScpO1xuXG52YXIgREVGQVVMVF9DT05URU5UX1RZUEUgPSB7XG4gICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJ1xufTtcblxuZnVuY3Rpb24gc2V0Q29udGVudFR5cGVJZlVuc2V0KGhlYWRlcnMsIHZhbHVlKSB7XG4gIGlmICghdXRpbHMuaXNVbmRlZmluZWQoaGVhZGVycykgJiYgdXRpbHMuaXNVbmRlZmluZWQoaGVhZGVyc1snQ29udGVudC1UeXBlJ10pKSB7XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSB2YWx1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXREZWZhdWx0QWRhcHRlcigpIHtcbiAgdmFyIGFkYXB0ZXI7XG4gIGlmICh0eXBlb2YgWE1MSHR0cFJlcXVlc3QgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gRm9yIGJyb3dzZXJzIHVzZSBYSFIgYWRhcHRlclxuICAgIGFkYXB0ZXIgPSByZXF1aXJlKCcuL2FkYXB0ZXJzL3hocicpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJykge1xuICAgIC8vIEZvciBub2RlIHVzZSBIVFRQIGFkYXB0ZXJcbiAgICBhZGFwdGVyID0gcmVxdWlyZSgnLi9hZGFwdGVycy9odHRwJyk7XG4gIH1cbiAgcmV0dXJuIGFkYXB0ZXI7XG59XG5cbnZhciBkZWZhdWx0cyA9IHtcbiAgYWRhcHRlcjogZ2V0RGVmYXVsdEFkYXB0ZXIoKSxcblxuICB0cmFuc2Zvcm1SZXF1ZXN0OiBbZnVuY3Rpb24gdHJhbnNmb3JtUmVxdWVzdChkYXRhLCBoZWFkZXJzKSB7XG4gICAgbm9ybWFsaXplSGVhZGVyTmFtZShoZWFkZXJzLCAnQ29udGVudC1UeXBlJyk7XG4gICAgaWYgKHV0aWxzLmlzRm9ybURhdGEoZGF0YSkgfHxcbiAgICAgIHV0aWxzLmlzQXJyYXlCdWZmZXIoZGF0YSkgfHxcbiAgICAgIHV0aWxzLmlzQnVmZmVyKGRhdGEpIHx8XG4gICAgICB1dGlscy5pc1N0cmVhbShkYXRhKSB8fFxuICAgICAgdXRpbHMuaXNGaWxlKGRhdGEpIHx8XG4gICAgICB1dGlscy5pc0Jsb2IoZGF0YSlcbiAgICApIHtcbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICBpZiAodXRpbHMuaXNBcnJheUJ1ZmZlclZpZXcoZGF0YSkpIHtcbiAgICAgIHJldHVybiBkYXRhLmJ1ZmZlcjtcbiAgICB9XG4gICAgaWYgKHV0aWxzLmlzVVJMU2VhcmNoUGFyYW1zKGRhdGEpKSB7XG4gICAgICBzZXRDb250ZW50VHlwZUlmVW5zZXQoaGVhZGVycywgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDtjaGFyc2V0PXV0Zi04Jyk7XG4gICAgICByZXR1cm4gZGF0YS50b1N0cmluZygpO1xuICAgIH1cbiAgICBpZiAodXRpbHMuaXNPYmplY3QoZGF0YSkpIHtcbiAgICAgIHNldENvbnRlbnRUeXBlSWZVbnNldChoZWFkZXJzLCAnYXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04Jyk7XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XSxcblxuICB0cmFuc2Zvcm1SZXNwb25zZTogW2Z1bmN0aW9uIHRyYW5zZm9ybVJlc3BvbnNlKGRhdGEpIHtcbiAgICAvKmVzbGludCBuby1wYXJhbS1yZWFzc2lnbjowKi9cbiAgICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHsgLyogSWdub3JlICovIH1cbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1dLFxuXG4gIC8qKlxuICAgKiBBIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIHRvIGFib3J0IGEgcmVxdWVzdC4gSWYgc2V0IHRvIDAgKGRlZmF1bHQpIGFcbiAgICogdGltZW91dCBpcyBub3QgY3JlYXRlZC5cbiAgICovXG4gIHRpbWVvdXQ6IDAsXG5cbiAgeHNyZkNvb2tpZU5hbWU6ICdYU1JGLVRPS0VOJyxcbiAgeHNyZkhlYWRlck5hbWU6ICdYLVhTUkYtVE9LRU4nLFxuXG4gIG1heENvbnRlbnRMZW5ndGg6IC0xLFxuXG4gIHZhbGlkYXRlU3RhdHVzOiBmdW5jdGlvbiB2YWxpZGF0ZVN0YXR1cyhzdGF0dXMpIHtcbiAgICByZXR1cm4gc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDA7XG4gIH1cbn07XG5cbmRlZmF1bHRzLmhlYWRlcnMgPSB7XG4gIGNvbW1vbjoge1xuICAgICdBY2NlcHQnOiAnYXBwbGljYXRpb24vanNvbiwgdGV4dC9wbGFpbiwgKi8qJ1xuICB9XG59O1xuXG51dGlscy5mb3JFYWNoKFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJ10sIGZ1bmN0aW9uIGZvckVhY2hNZXRob2ROb0RhdGEobWV0aG9kKSB7XG4gIGRlZmF1bHRzLmhlYWRlcnNbbWV0aG9kXSA9IHt9O1xufSk7XG5cbnV0aWxzLmZvckVhY2goWydwb3N0JywgJ3B1dCcsICdwYXRjaCddLCBmdW5jdGlvbiBmb3JFYWNoTWV0aG9kV2l0aERhdGEobWV0aG9kKSB7XG4gIGRlZmF1bHRzLmhlYWRlcnNbbWV0aG9kXSA9IHV0aWxzLm1lcmdlKERFRkFVTFRfQ09OVEVOVF9UWVBFKTtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlZmF1bHRzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG5cbmZ1bmN0aW9uIEludGVyY2VwdG9yTWFuYWdlcigpIHtcbiAgdGhpcy5oYW5kbGVycyA9IFtdO1xufVxuXG4vKipcbiAqIEFkZCBhIG5ldyBpbnRlcmNlcHRvciB0byB0aGUgc3RhY2tcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdWxmaWxsZWQgVGhlIGZ1bmN0aW9uIHRvIGhhbmRsZSBgdGhlbmAgZm9yIGEgYFByb21pc2VgXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3RlZCBUaGUgZnVuY3Rpb24gdG8gaGFuZGxlIGByZWplY3RgIGZvciBhIGBQcm9taXNlYFxuICpcbiAqIEByZXR1cm4ge051bWJlcn0gQW4gSUQgdXNlZCB0byByZW1vdmUgaW50ZXJjZXB0b3IgbGF0ZXJcbiAqL1xuSW50ZXJjZXB0b3JNYW5hZ2VyLnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbiB1c2UoZnVsZmlsbGVkLCByZWplY3RlZCkge1xuICB0aGlzLmhhbmRsZXJzLnB1c2goe1xuICAgIGZ1bGZpbGxlZDogZnVsZmlsbGVkLFxuICAgIHJlamVjdGVkOiByZWplY3RlZFxuICB9KTtcbiAgcmV0dXJuIHRoaXMuaGFuZGxlcnMubGVuZ3RoIC0gMTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIGFuIGludGVyY2VwdG9yIGZyb20gdGhlIHN0YWNrXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGlkIFRoZSBJRCB0aGF0IHdhcyByZXR1cm5lZCBieSBgdXNlYFxuICovXG5JbnRlcmNlcHRvck1hbmFnZXIucHJvdG90eXBlLmVqZWN0ID0gZnVuY3Rpb24gZWplY3QoaWQpIHtcbiAgaWYgKHRoaXMuaGFuZGxlcnNbaWRdKSB7XG4gICAgdGhpcy5oYW5kbGVyc1tpZF0gPSBudWxsO1xuICB9XG59O1xuXG4vKipcbiAqIEl0ZXJhdGUgb3ZlciBhbGwgdGhlIHJlZ2lzdGVyZWQgaW50ZXJjZXB0b3JzXG4gKlxuICogVGhpcyBtZXRob2QgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCBmb3Igc2tpcHBpbmcgb3ZlciBhbnlcbiAqIGludGVyY2VwdG9ycyB0aGF0IG1heSBoYXZlIGJlY29tZSBgbnVsbGAgY2FsbGluZyBgZWplY3RgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGludGVyY2VwdG9yXG4gKi9cbkludGVyY2VwdG9yTWFuYWdlci5wcm90b3R5cGUuZm9yRWFjaCA9IGZ1bmN0aW9uIGZvckVhY2goZm4pIHtcbiAgdXRpbHMuZm9yRWFjaCh0aGlzLmhhbmRsZXJzLCBmdW5jdGlvbiBmb3JFYWNoSGFuZGxlcihoKSB7XG4gICAgaWYgKGggIT09IG51bGwpIHtcbiAgICAgIGZuKGgpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEludGVyY2VwdG9yTWFuYWdlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi8uLi91dGlscycpO1xuXG4vKipcbiAqIFRyYW5zZm9ybSB0aGUgZGF0YSBmb3IgYSByZXF1ZXN0IG9yIGEgcmVzcG9uc2VcbiAqXG4gKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IGRhdGEgVGhlIGRhdGEgdG8gYmUgdHJhbnNmb3JtZWRcbiAqIEBwYXJhbSB7QXJyYXl9IGhlYWRlcnMgVGhlIGhlYWRlcnMgZm9yIHRoZSByZXF1ZXN0IG9yIHJlc3BvbnNlXG4gKiBAcGFyYW0ge0FycmF5fEZ1bmN0aW9ufSBmbnMgQSBzaW5nbGUgZnVuY3Rpb24gb3IgQXJyYXkgb2YgZnVuY3Rpb25zXG4gKiBAcmV0dXJucyB7Kn0gVGhlIHJlc3VsdGluZyB0cmFuc2Zvcm1lZCBkYXRhXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gdHJhbnNmb3JtRGF0YShkYXRhLCBoZWFkZXJzLCBmbnMpIHtcbiAgLyplc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246MCovXG4gIHV0aWxzLmZvckVhY2goZm5zLCBmdW5jdGlvbiB0cmFuc2Zvcm0oZm4pIHtcbiAgICBkYXRhID0gZm4oZGF0YSwgaGVhZGVycyk7XG4gIH0pO1xuXG4gIHJldHVybiBkYXRhO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0NhbmNlbCh2YWx1ZSkge1xuICByZXR1cm4gISEodmFsdWUgJiYgdmFsdWUuX19DQU5DRUxfXyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciB0aGUgc3BlY2lmaWVkIFVSTCBpcyBhYnNvbHV0ZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIFVSTCB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIFVSTCBpcyBhYnNvbHV0ZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBYnNvbHV0ZVVSTCh1cmwpIHtcbiAgLy8gQSBVUkwgaXMgY29uc2lkZXJlZCBhYnNvbHV0ZSBpZiBpdCBiZWdpbnMgd2l0aCBcIjxzY2hlbWU+Oi8vXCIgb3IgXCIvL1wiIChwcm90b2NvbC1yZWxhdGl2ZSBVUkwpLlxuICAvLyBSRkMgMzk4NiBkZWZpbmVzIHNjaGVtZSBuYW1lIGFzIGEgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyBiZWdpbm5pbmcgd2l0aCBhIGxldHRlciBhbmQgZm9sbG93ZWRcbiAgLy8gYnkgYW55IGNvbWJpbmF0aW9uIG9mIGxldHRlcnMsIGRpZ2l0cywgcGx1cywgcGVyaW9kLCBvciBoeXBoZW4uXG4gIHJldHVybiAvXihbYS16XVthLXpcXGRcXCtcXC1cXC5dKjopP1xcL1xcLy9pLnRlc3QodXJsKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBVUkwgYnkgY29tYmluaW5nIHRoZSBzcGVjaWZpZWQgVVJMc1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlVVJMIFRoZSBiYXNlIFVSTFxuICogQHBhcmFtIHtzdHJpbmd9IHJlbGF0aXZlVVJMIFRoZSByZWxhdGl2ZSBVUkxcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb21iaW5lZCBVUkxcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjb21iaW5lVVJMcyhiYXNlVVJMLCByZWxhdGl2ZVVSTCkge1xuICByZXR1cm4gcmVsYXRpdmVVUkxcbiAgICA/IGJhc2VVUkwucmVwbGFjZSgvXFwvKyQvLCAnJykgKyAnLycgKyByZWxhdGl2ZVVSTC5yZXBsYWNlKC9eXFwvKy8sICcnKVxuICAgIDogYmFzZVVSTDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcbnZhciB0cmFuc2Zvcm1EYXRhID0gcmVxdWlyZSgnLi90cmFuc2Zvcm1EYXRhJyk7XG52YXIgaXNDYW5jZWwgPSByZXF1aXJlKCcuLi9jYW5jZWwvaXNDYW5jZWwnKTtcbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2RlZmF1bHRzJyk7XG52YXIgaXNBYnNvbHV0ZVVSTCA9IHJlcXVpcmUoJy4vLi4vaGVscGVycy9pc0Fic29sdXRlVVJMJyk7XG52YXIgY29tYmluZVVSTHMgPSByZXF1aXJlKCcuLy4uL2hlbHBlcnMvY29tYmluZVVSTHMnKTtcblxuLyoqXG4gKiBUaHJvd3MgYSBgQ2FuY2VsYCBpZiBjYW5jZWxsYXRpb24gaGFzIGJlZW4gcmVxdWVzdGVkLlxuICovXG5mdW5jdGlvbiB0aHJvd0lmQ2FuY2VsbGF0aW9uUmVxdWVzdGVkKGNvbmZpZykge1xuICBpZiAoY29uZmlnLmNhbmNlbFRva2VuKSB7XG4gICAgY29uZmlnLmNhbmNlbFRva2VuLnRocm93SWZSZXF1ZXN0ZWQoKTtcbiAgfVxufVxuXG4vKipcbiAqIERpc3BhdGNoIGEgcmVxdWVzdCB0byB0aGUgc2VydmVyIHVzaW5nIHRoZSBjb25maWd1cmVkIGFkYXB0ZXIuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZyBUaGUgY29uZmlnIHRoYXQgaXMgdG8gYmUgdXNlZCBmb3IgdGhlIHJlcXVlc3RcbiAqIEByZXR1cm5zIHtQcm9taXNlfSBUaGUgUHJvbWlzZSB0byBiZSBmdWxmaWxsZWRcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBkaXNwYXRjaFJlcXVlc3QoY29uZmlnKSB7XG4gIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKTtcblxuICAvLyBTdXBwb3J0IGJhc2VVUkwgY29uZmlnXG4gIGlmIChjb25maWcuYmFzZVVSTCAmJiAhaXNBYnNvbHV0ZVVSTChjb25maWcudXJsKSkge1xuICAgIGNvbmZpZy51cmwgPSBjb21iaW5lVVJMcyhjb25maWcuYmFzZVVSTCwgY29uZmlnLnVybCk7XG4gIH1cblxuICAvLyBFbnN1cmUgaGVhZGVycyBleGlzdFxuICBjb25maWcuaGVhZGVycyA9IGNvbmZpZy5oZWFkZXJzIHx8IHt9O1xuXG4gIC8vIFRyYW5zZm9ybSByZXF1ZXN0IGRhdGFcbiAgY29uZmlnLmRhdGEgPSB0cmFuc2Zvcm1EYXRhKFxuICAgIGNvbmZpZy5kYXRhLFxuICAgIGNvbmZpZy5oZWFkZXJzLFxuICAgIGNvbmZpZy50cmFuc2Zvcm1SZXF1ZXN0XG4gICk7XG5cbiAgLy8gRmxhdHRlbiBoZWFkZXJzXG4gIGNvbmZpZy5oZWFkZXJzID0gdXRpbHMubWVyZ2UoXG4gICAgY29uZmlnLmhlYWRlcnMuY29tbW9uIHx8IHt9LFxuICAgIGNvbmZpZy5oZWFkZXJzW2NvbmZpZy5tZXRob2RdIHx8IHt9LFxuICAgIGNvbmZpZy5oZWFkZXJzIHx8IHt9XG4gICk7XG5cbiAgdXRpbHMuZm9yRWFjaChcbiAgICBbJ2RlbGV0ZScsICdnZXQnLCAnaGVhZCcsICdwb3N0JywgJ3B1dCcsICdwYXRjaCcsICdjb21tb24nXSxcbiAgICBmdW5jdGlvbiBjbGVhbkhlYWRlckNvbmZpZyhtZXRob2QpIHtcbiAgICAgIGRlbGV0ZSBjb25maWcuaGVhZGVyc1ttZXRob2RdO1xuICAgIH1cbiAgKTtcblxuICB2YXIgYWRhcHRlciA9IGNvbmZpZy5hZGFwdGVyIHx8IGRlZmF1bHRzLmFkYXB0ZXI7XG5cbiAgcmV0dXJuIGFkYXB0ZXIoY29uZmlnKS50aGVuKGZ1bmN0aW9uIG9uQWRhcHRlclJlc29sdXRpb24ocmVzcG9uc2UpIHtcbiAgICB0aHJvd0lmQ2FuY2VsbGF0aW9uUmVxdWVzdGVkKGNvbmZpZyk7XG5cbiAgICAvLyBUcmFuc2Zvcm0gcmVzcG9uc2UgZGF0YVxuICAgIHJlc3BvbnNlLmRhdGEgPSB0cmFuc2Zvcm1EYXRhKFxuICAgICAgcmVzcG9uc2UuZGF0YSxcbiAgICAgIHJlc3BvbnNlLmhlYWRlcnMsXG4gICAgICBjb25maWcudHJhbnNmb3JtUmVzcG9uc2VcbiAgICApO1xuXG4gICAgcmV0dXJuIHJlc3BvbnNlO1xuICB9LCBmdW5jdGlvbiBvbkFkYXB0ZXJSZWplY3Rpb24ocmVhc29uKSB7XG4gICAgaWYgKCFpc0NhbmNlbChyZWFzb24pKSB7XG4gICAgICB0aHJvd0lmQ2FuY2VsbGF0aW9uUmVxdWVzdGVkKGNvbmZpZyk7XG5cbiAgICAgIC8vIFRyYW5zZm9ybSByZXNwb25zZSBkYXRhXG4gICAgICBpZiAocmVhc29uICYmIHJlYXNvbi5yZXNwb25zZSkge1xuICAgICAgICByZWFzb24ucmVzcG9uc2UuZGF0YSA9IHRyYW5zZm9ybURhdGEoXG4gICAgICAgICAgcmVhc29uLnJlc3BvbnNlLmRhdGEsXG4gICAgICAgICAgcmVhc29uLnJlc3BvbnNlLmhlYWRlcnMsXG4gICAgICAgICAgY29uZmlnLnRyYW5zZm9ybVJlc3BvbnNlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHJlYXNvbik7XG4gIH0pO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmF1bHRzID0gcmVxdWlyZSgnLi8uLi9kZWZhdWx0cycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi8uLi91dGlscycpO1xudmFyIEludGVyY2VwdG9yTWFuYWdlciA9IHJlcXVpcmUoJy4vSW50ZXJjZXB0b3JNYW5hZ2VyJyk7XG52YXIgZGlzcGF0Y2hSZXF1ZXN0ID0gcmVxdWlyZSgnLi9kaXNwYXRjaFJlcXVlc3QnKTtcblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgQXhpb3NcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gaW5zdGFuY2VDb25maWcgVGhlIGRlZmF1bHQgY29uZmlnIGZvciB0aGUgaW5zdGFuY2VcbiAqL1xuZnVuY3Rpb24gQXhpb3MoaW5zdGFuY2VDb25maWcpIHtcbiAgdGhpcy5kZWZhdWx0cyA9IGluc3RhbmNlQ29uZmlnO1xuICB0aGlzLmludGVyY2VwdG9ycyA9IHtcbiAgICByZXF1ZXN0OiBuZXcgSW50ZXJjZXB0b3JNYW5hZ2VyKCksXG4gICAgcmVzcG9uc2U6IG5ldyBJbnRlcmNlcHRvck1hbmFnZXIoKVxuICB9O1xufVxuXG4vKipcbiAqIERpc3BhdGNoIGEgcmVxdWVzdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgVGhlIGNvbmZpZyBzcGVjaWZpYyBmb3IgdGhpcyByZXF1ZXN0IChtZXJnZWQgd2l0aCB0aGlzLmRlZmF1bHRzKVxuICovXG5BeGlvcy5wcm90b3R5cGUucmVxdWVzdCA9IGZ1bmN0aW9uIHJlcXVlc3QoY29uZmlnKSB7XG4gIC8qZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOjAqL1xuICAvLyBBbGxvdyBmb3IgYXhpb3MoJ2V4YW1wbGUvdXJsJ1ssIGNvbmZpZ10pIGEgbGEgZmV0Y2ggQVBJXG4gIGlmICh0eXBlb2YgY29uZmlnID09PSAnc3RyaW5nJykge1xuICAgIGNvbmZpZyA9IHV0aWxzLm1lcmdlKHtcbiAgICAgIHVybDogYXJndW1lbnRzWzBdXG4gICAgfSwgYXJndW1lbnRzWzFdKTtcbiAgfVxuXG4gIGNvbmZpZyA9IHV0aWxzLm1lcmdlKGRlZmF1bHRzLCB7bWV0aG9kOiAnZ2V0J30sIHRoaXMuZGVmYXVsdHMsIGNvbmZpZyk7XG4gIGNvbmZpZy5tZXRob2QgPSBjb25maWcubWV0aG9kLnRvTG93ZXJDYXNlKCk7XG5cbiAgLy8gSG9vayB1cCBpbnRlcmNlcHRvcnMgbWlkZGxld2FyZVxuICB2YXIgY2hhaW4gPSBbZGlzcGF0Y2hSZXF1ZXN0LCB1bmRlZmluZWRdO1xuICB2YXIgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShjb25maWcpO1xuXG4gIHRoaXMuaW50ZXJjZXB0b3JzLnJlcXVlc3QuZm9yRWFjaChmdW5jdGlvbiB1bnNoaWZ0UmVxdWVzdEludGVyY2VwdG9ycyhpbnRlcmNlcHRvcikge1xuICAgIGNoYWluLnVuc2hpZnQoaW50ZXJjZXB0b3IuZnVsZmlsbGVkLCBpbnRlcmNlcHRvci5yZWplY3RlZCk7XG4gIH0pO1xuXG4gIHRoaXMuaW50ZXJjZXB0b3JzLnJlc3BvbnNlLmZvckVhY2goZnVuY3Rpb24gcHVzaFJlc3BvbnNlSW50ZXJjZXB0b3JzKGludGVyY2VwdG9yKSB7XG4gICAgY2hhaW4ucHVzaChpbnRlcmNlcHRvci5mdWxmaWxsZWQsIGludGVyY2VwdG9yLnJlamVjdGVkKTtcbiAgfSk7XG5cbiAgd2hpbGUgKGNoYWluLmxlbmd0aCkge1xuICAgIHByb21pc2UgPSBwcm9taXNlLnRoZW4oY2hhaW4uc2hpZnQoKSwgY2hhaW4uc2hpZnQoKSk7XG4gIH1cblxuICByZXR1cm4gcHJvbWlzZTtcbn07XG5cbi8vIFByb3ZpZGUgYWxpYXNlcyBmb3Igc3VwcG9ydGVkIHJlcXVlc3QgbWV0aG9kc1xudXRpbHMuZm9yRWFjaChbJ2RlbGV0ZScsICdnZXQnLCAnaGVhZCcsICdvcHRpb25zJ10sIGZ1bmN0aW9uIGZvckVhY2hNZXRob2ROb0RhdGEobWV0aG9kKSB7XG4gIC8qZXNsaW50IGZ1bmMtbmFtZXM6MCovXG4gIEF4aW9zLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24odXJsLCBjb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KHV0aWxzLm1lcmdlKGNvbmZpZyB8fCB7fSwge1xuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICB1cmw6IHVybFxuICAgIH0pKTtcbiAgfTtcbn0pO1xuXG51dGlscy5mb3JFYWNoKFsncG9zdCcsICdwdXQnLCAncGF0Y2gnXSwgZnVuY3Rpb24gZm9yRWFjaE1ldGhvZFdpdGhEYXRhKG1ldGhvZCkge1xuICAvKmVzbGludCBmdW5jLW5hbWVzOjAqL1xuICBBeGlvcy5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdCh1dGlscy5tZXJnZShjb25maWcgfHwge30sIHtcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgdXJsOiB1cmwsXG4gICAgICBkYXRhOiBkYXRhXG4gICAgfSkpO1xuICB9O1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gQXhpb3M7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogQSBgQ2FuY2VsYCBpcyBhbiBvYmplY3QgdGhhdCBpcyB0aHJvd24gd2hlbiBhbiBvcGVyYXRpb24gaXMgY2FuY2VsZWQuXG4gKlxuICogQGNsYXNzXG4gKiBAcGFyYW0ge3N0cmluZz19IG1lc3NhZ2UgVGhlIG1lc3NhZ2UuXG4gKi9cbmZ1bmN0aW9uIENhbmNlbChtZXNzYWdlKSB7XG4gIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG59XG5cbkNhbmNlbC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgcmV0dXJuICdDYW5jZWwnICsgKHRoaXMubWVzc2FnZSA/ICc6ICcgKyB0aGlzLm1lc3NhZ2UgOiAnJyk7XG59O1xuXG5DYW5jZWwucHJvdG90eXBlLl9fQ0FOQ0VMX18gPSB0cnVlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IENhbmNlbDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENhbmNlbCA9IHJlcXVpcmUoJy4vQ2FuY2VsJyk7XG5cbi8qKlxuICogQSBgQ2FuY2VsVG9rZW5gIGlzIGFuIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIHJlcXVlc3QgY2FuY2VsbGF0aW9uIG9mIGFuIG9wZXJhdGlvbi5cbiAqXG4gKiBAY2xhc3NcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGV4ZWN1dG9yIFRoZSBleGVjdXRvciBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2FuY2VsVG9rZW4oZXhlY3V0b3IpIHtcbiAgaWYgKHR5cGVvZiBleGVjdXRvciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2V4ZWN1dG9yIG11c3QgYmUgYSBmdW5jdGlvbi4nKTtcbiAgfVxuXG4gIHZhciByZXNvbHZlUHJvbWlzZTtcbiAgdGhpcy5wcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24gcHJvbWlzZUV4ZWN1dG9yKHJlc29sdmUpIHtcbiAgICByZXNvbHZlUHJvbWlzZSA9IHJlc29sdmU7XG4gIH0pO1xuXG4gIHZhciB0b2tlbiA9IHRoaXM7XG4gIGV4ZWN1dG9yKGZ1bmN0aW9uIGNhbmNlbChtZXNzYWdlKSB7XG4gICAgaWYgKHRva2VuLnJlYXNvbikge1xuICAgICAgLy8gQ2FuY2VsbGF0aW9uIGhhcyBhbHJlYWR5IGJlZW4gcmVxdWVzdGVkXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdG9rZW4ucmVhc29uID0gbmV3IENhbmNlbChtZXNzYWdlKTtcbiAgICByZXNvbHZlUHJvbWlzZSh0b2tlbi5yZWFzb24pO1xuICB9KTtcbn1cblxuLyoqXG4gKiBUaHJvd3MgYSBgQ2FuY2VsYCBpZiBjYW5jZWxsYXRpb24gaGFzIGJlZW4gcmVxdWVzdGVkLlxuICovXG5DYW5jZWxUb2tlbi5wcm90b3R5cGUudGhyb3dJZlJlcXVlc3RlZCA9IGZ1bmN0aW9uIHRocm93SWZSZXF1ZXN0ZWQoKSB7XG4gIGlmICh0aGlzLnJlYXNvbikge1xuICAgIHRocm93IHRoaXMucmVhc29uO1xuICB9XG59O1xuXG4vKipcbiAqIFJldHVybnMgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYSBuZXcgYENhbmNlbFRva2VuYCBhbmQgYSBmdW5jdGlvbiB0aGF0LCB3aGVuIGNhbGxlZCxcbiAqIGNhbmNlbHMgdGhlIGBDYW5jZWxUb2tlbmAuXG4gKi9cbkNhbmNlbFRva2VuLnNvdXJjZSA9IGZ1bmN0aW9uIHNvdXJjZSgpIHtcbiAgdmFyIGNhbmNlbDtcbiAgdmFyIHRva2VuID0gbmV3IENhbmNlbFRva2VuKGZ1bmN0aW9uIGV4ZWN1dG9yKGMpIHtcbiAgICBjYW5jZWwgPSBjO1xuICB9KTtcbiAgcmV0dXJuIHtcbiAgICB0b2tlbjogdG9rZW4sXG4gICAgY2FuY2VsOiBjYW5jZWxcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQ2FuY2VsVG9rZW47XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogU3ludGFjdGljIHN1Z2FyIGZvciBpbnZva2luZyBhIGZ1bmN0aW9uIGFuZCBleHBhbmRpbmcgYW4gYXJyYXkgZm9yIGFyZ3VtZW50cy5cbiAqXG4gKiBDb21tb24gdXNlIGNhc2Ugd291bGQgYmUgdG8gdXNlIGBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHlgLlxuICpcbiAqICBgYGBqc1xuICogIGZ1bmN0aW9uIGYoeCwgeSwgeikge31cbiAqICB2YXIgYXJncyA9IFsxLCAyLCAzXTtcbiAqICBmLmFwcGx5KG51bGwsIGFyZ3MpO1xuICogIGBgYFxuICpcbiAqIFdpdGggYHNwcmVhZGAgdGhpcyBleGFtcGxlIGNhbiBiZSByZS13cml0dGVuLlxuICpcbiAqICBgYGBqc1xuICogIHNwcmVhZChmdW5jdGlvbih4LCB5LCB6KSB7fSkoWzEsIDIsIDNdKTtcbiAqICBgYGBcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHJldHVybnMge0Z1bmN0aW9ufVxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHNwcmVhZChjYWxsYmFjaykge1xuICByZXR1cm4gZnVuY3Rpb24gd3JhcChhcnIpIHtcbiAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkobnVsbCwgYXJyKTtcbiAgfTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBiaW5kID0gcmVxdWlyZSgnLi9oZWxwZXJzL2JpbmQnKTtcbnZhciBBeGlvcyA9IHJlcXVpcmUoJy4vY29yZS9BeGlvcycpO1xudmFyIGRlZmF1bHRzID0gcmVxdWlyZSgnLi9kZWZhdWx0cycpO1xuXG4vKipcbiAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBBeGlvc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBkZWZhdWx0Q29uZmlnIFRoZSBkZWZhdWx0IGNvbmZpZyBmb3IgdGhlIGluc3RhbmNlXG4gKiBAcmV0dXJuIHtBeGlvc30gQSBuZXcgaW5zdGFuY2Ugb2YgQXhpb3NcbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5zdGFuY2UoZGVmYXVsdENvbmZpZykge1xuICB2YXIgY29udGV4dCA9IG5ldyBBeGlvcyhkZWZhdWx0Q29uZmlnKTtcbiAgdmFyIGluc3RhbmNlID0gYmluZChBeGlvcy5wcm90b3R5cGUucmVxdWVzdCwgY29udGV4dCk7XG5cbiAgLy8gQ29weSBheGlvcy5wcm90b3R5cGUgdG8gaW5zdGFuY2VcbiAgdXRpbHMuZXh0ZW5kKGluc3RhbmNlLCBBeGlvcy5wcm90b3R5cGUsIGNvbnRleHQpO1xuXG4gIC8vIENvcHkgY29udGV4dCB0byBpbnN0YW5jZVxuICB1dGlscy5leHRlbmQoaW5zdGFuY2UsIGNvbnRleHQpO1xuXG4gIHJldHVybiBpbnN0YW5jZTtcbn1cblxuLy8gQ3JlYXRlIHRoZSBkZWZhdWx0IGluc3RhbmNlIHRvIGJlIGV4cG9ydGVkXG52YXIgYXhpb3MgPSBjcmVhdGVJbnN0YW5jZShkZWZhdWx0cyk7XG5cbi8vIEV4cG9zZSBBeGlvcyBjbGFzcyB0byBhbGxvdyBjbGFzcyBpbmhlcml0YW5jZVxuYXhpb3MuQXhpb3MgPSBBeGlvcztcblxuLy8gRmFjdG9yeSBmb3IgY3JlYXRpbmcgbmV3IGluc3RhbmNlc1xuYXhpb3MuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKGluc3RhbmNlQ29uZmlnKSB7XG4gIHJldHVybiBjcmVhdGVJbnN0YW5jZSh1dGlscy5tZXJnZShkZWZhdWx0cywgaW5zdGFuY2VDb25maWcpKTtcbn07XG5cbi8vIEV4cG9zZSBDYW5jZWwgJiBDYW5jZWxUb2tlblxuYXhpb3MuQ2FuY2VsID0gcmVxdWlyZSgnLi9jYW5jZWwvQ2FuY2VsJyk7XG5heGlvcy5DYW5jZWxUb2tlbiA9IHJlcXVpcmUoJy4vY2FuY2VsL0NhbmNlbFRva2VuJyk7XG5heGlvcy5pc0NhbmNlbCA9IHJlcXVpcmUoJy4vY2FuY2VsL2lzQ2FuY2VsJyk7XG5cbi8vIEV4cG9zZSBhbGwvc3ByZWFkXG5heGlvcy5hbGwgPSBmdW5jdGlvbiBhbGwocHJvbWlzZXMpIHtcbiAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKTtcbn07XG5heGlvcy5zcHJlYWQgPSByZXF1aXJlKCcuL2hlbHBlcnMvc3ByZWFkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gYXhpb3M7XG5cbi8vIEFsbG93IHVzZSBvZiBkZWZhdWx0IGltcG9ydCBzeW50YXggaW4gVHlwZVNjcmlwdFxubW9kdWxlLmV4cG9ydHMuZGVmYXVsdCA9IGF4aW9zO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9heGlvcycpOyIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKGZuLCB0aGlzQXJnKSB7XG4gIHJldHVybiBmdW5jdGlvbiB3cmFwKCkge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXNBcmcsIGFyZ3MpO1xuICB9O1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGJpbmQgPSByZXF1aXJlKCcuL2hlbHBlcnMvYmluZCcpO1xudmFyIGlzQnVmZmVyID0gcmVxdWlyZSgnaXMtYnVmZmVyJyk7XG5cbi8qZ2xvYmFsIHRvU3RyaW5nOnRydWUqL1xuXG4vLyB1dGlscyBpcyBhIGxpYnJhcnkgb2YgZ2VuZXJpYyBoZWxwZXIgZnVuY3Rpb25zIG5vbi1zcGVjaWZpYyB0byBheGlvc1xuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIEFycmF5XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYW4gQXJyYXksIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0FycmF5KHZhbCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWwpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIEFycmF5QnVmZmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYW4gQXJyYXlCdWZmZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0FycmF5QnVmZmVyKHZhbCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWwpID09PSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRm9ybURhdGFcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhbiBGb3JtRGF0YSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRm9ybURhdGEodmFsKSB7XG4gIHJldHVybiAodHlwZW9mIEZvcm1EYXRhICE9PSAndW5kZWZpbmVkJykgJiYgKHZhbCBpbnN0YW5jZW9mIEZvcm1EYXRhKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIHZpZXcgb24gYW4gQXJyYXlCdWZmZXJcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIHZpZXcgb24gYW4gQXJyYXlCdWZmZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0FycmF5QnVmZmVyVmlldyh2YWwpIHtcbiAgdmFyIHJlc3VsdDtcbiAgaWYgKCh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnKSAmJiAoQXJyYXlCdWZmZXIuaXNWaWV3KSkge1xuICAgIHJlc3VsdCA9IEFycmF5QnVmZmVyLmlzVmlldyh2YWwpO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdCA9ICh2YWwpICYmICh2YWwuYnVmZmVyKSAmJiAodmFsLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgU3RyaW5nXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBTdHJpbmcsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1N0cmluZyh2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgTnVtYmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBOdW1iZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc051bWJlcih2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdudW1iZXInO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIHVuZGVmaW5lZFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyB1bmRlZmluZWQsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICd1bmRlZmluZWQnO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIE9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGFuIE9iamVjdCwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbCkge1xuICByZXR1cm4gdmFsICE9PSBudWxsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRGF0ZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRGF0ZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRGF0ZSh2YWwpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRmlsZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRmlsZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRmlsZSh2YWwpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsKSA9PT0gJ1tvYmplY3QgRmlsZV0nO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgQmxvYlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgQmxvYiwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQmxvYih2YWwpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsKSA9PT0gJ1tvYmplY3QgQmxvYl0nO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRnVuY3Rpb25cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIEZ1bmN0aW9uLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWwpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIFN0cmVhbVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgU3RyZWFtLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTdHJlYW0odmFsKSB7XG4gIHJldHVybiBpc09iamVjdCh2YWwpICYmIGlzRnVuY3Rpb24odmFsLnBpcGUpO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgVVJMU2VhcmNoUGFyYW1zIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgVVJMU2VhcmNoUGFyYW1zIG9iamVjdCwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzVVJMU2VhcmNoUGFyYW1zKHZhbCkge1xuICByZXR1cm4gdHlwZW9mIFVSTFNlYXJjaFBhcmFtcyAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsIGluc3RhbmNlb2YgVVJMU2VhcmNoUGFyYW1zO1xufVxuXG4vKipcbiAqIFRyaW0gZXhjZXNzIHdoaXRlc3BhY2Ugb2ZmIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiBhIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgVGhlIFN0cmluZyB0byB0cmltXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgU3RyaW5nIGZyZWVkIG9mIGV4Y2VzcyB3aGl0ZXNwYWNlXG4gKi9cbmZ1bmN0aW9uIHRyaW0oc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyovLCAnJykucmVwbGFjZSgvXFxzKiQvLCAnJyk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIHdlJ3JlIHJ1bm5pbmcgaW4gYSBzdGFuZGFyZCBicm93c2VyIGVudmlyb25tZW50XG4gKlxuICogVGhpcyBhbGxvd3MgYXhpb3MgdG8gcnVuIGluIGEgd2ViIHdvcmtlciwgYW5kIHJlYWN0LW5hdGl2ZS5cbiAqIEJvdGggZW52aXJvbm1lbnRzIHN1cHBvcnQgWE1MSHR0cFJlcXVlc3QsIGJ1dCBub3QgZnVsbHkgc3RhbmRhcmQgZ2xvYmFscy5cbiAqXG4gKiB3ZWIgd29ya2VyczpcbiAqICB0eXBlb2Ygd2luZG93IC0+IHVuZGVmaW5lZFxuICogIHR5cGVvZiBkb2N1bWVudCAtPiB1bmRlZmluZWRcbiAqXG4gKiByZWFjdC1uYXRpdmU6XG4gKiAgbmF2aWdhdG9yLnByb2R1Y3QgLT4gJ1JlYWN0TmF0aXZlJ1xuICovXG5mdW5jdGlvbiBpc1N0YW5kYXJkQnJvd3NlckVudigpIHtcbiAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmIG5hdmlnYXRvci5wcm9kdWN0ID09PSAnUmVhY3ROYXRpdmUnKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnXG4gICk7XG59XG5cbi8qKlxuICogSXRlcmF0ZSBvdmVyIGFuIEFycmF5IG9yIGFuIE9iamVjdCBpbnZva2luZyBhIGZ1bmN0aW9uIGZvciBlYWNoIGl0ZW0uXG4gKlxuICogSWYgYG9iamAgaXMgYW4gQXJyYXkgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgcGFzc2luZ1xuICogdGhlIHZhbHVlLCBpbmRleCwgYW5kIGNvbXBsZXRlIGFycmF5IGZvciBlYWNoIGl0ZW0uXG4gKlxuICogSWYgJ29iaicgaXMgYW4gT2JqZWN0IGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHBhc3NpbmdcbiAqIHRoZSB2YWx1ZSwga2V5LCBhbmQgY29tcGxldGUgb2JqZWN0IGZvciBlYWNoIHByb3BlcnR5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBvYmogVGhlIG9iamVjdCB0byBpdGVyYXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIGZvciBlYWNoIGl0ZW1cbiAqL1xuZnVuY3Rpb24gZm9yRWFjaChvYmosIGZuKSB7XG4gIC8vIERvbid0IGJvdGhlciBpZiBubyB2YWx1ZSBwcm92aWRlZFxuICBpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRm9yY2UgYW4gYXJyYXkgaWYgbm90IGFscmVhZHkgc29tZXRoaW5nIGl0ZXJhYmxlXG4gIGlmICh0eXBlb2Ygb2JqICE9PSAnb2JqZWN0Jykge1xuICAgIC8qZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOjAqL1xuICAgIG9iaiA9IFtvYmpdO1xuICB9XG5cbiAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgIC8vIEl0ZXJhdGUgb3ZlciBhcnJheSB2YWx1ZXNcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IG9iai5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgb2JqW2ldLCBpLCBvYmopO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBJdGVyYXRlIG92ZXIgb2JqZWN0IGtleXNcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICBmbi5jYWxsKG51bGwsIG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQWNjZXB0cyB2YXJhcmdzIGV4cGVjdGluZyBlYWNoIGFyZ3VtZW50IHRvIGJlIGFuIG9iamVjdCwgdGhlblxuICogaW1tdXRhYmx5IG1lcmdlcyB0aGUgcHJvcGVydGllcyBvZiBlYWNoIG9iamVjdCBhbmQgcmV0dXJucyByZXN1bHQuXG4gKlxuICogV2hlbiBtdWx0aXBsZSBvYmplY3RzIGNvbnRhaW4gdGhlIHNhbWUga2V5IHRoZSBsYXRlciBvYmplY3QgaW5cbiAqIHRoZSBhcmd1bWVudHMgbGlzdCB3aWxsIHRha2UgcHJlY2VkZW5jZS5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqIGBgYGpzXG4gKiB2YXIgcmVzdWx0ID0gbWVyZ2Uoe2ZvbzogMTIzfSwge2ZvbzogNDU2fSk7XG4gKiBjb25zb2xlLmxvZyhyZXN1bHQuZm9vKTsgLy8gb3V0cHV0cyA0NTZcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmoxIE9iamVjdCB0byBtZXJnZVxuICogQHJldHVybnMge09iamVjdH0gUmVzdWx0IG9mIGFsbCBtZXJnZSBwcm9wZXJ0aWVzXG4gKi9cbmZ1bmN0aW9uIG1lcmdlKC8qIG9iajEsIG9iajIsIG9iajMsIC4uLiAqLykge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIGZ1bmN0aW9uIGFzc2lnblZhbHVlKHZhbCwga2V5KSB7XG4gICAgaWYgKHR5cGVvZiByZXN1bHRba2V5XSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJlc3VsdFtrZXldID0gbWVyZ2UocmVzdWx0W2tleV0sIHZhbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdFtrZXldID0gdmFsO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGZvckVhY2goYXJndW1lbnRzW2ldLCBhc3NpZ25WYWx1ZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBFeHRlbmRzIG9iamVjdCBhIGJ5IG11dGFibHkgYWRkaW5nIHRvIGl0IHRoZSBwcm9wZXJ0aWVzIG9mIG9iamVjdCBiLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBhIFRoZSBvYmplY3QgdG8gYmUgZXh0ZW5kZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBiIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIGZyb21cbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGlzQXJnIFRoZSBvYmplY3QgdG8gYmluZCBmdW5jdGlvbiB0b1xuICogQHJldHVybiB7T2JqZWN0fSBUaGUgcmVzdWx0aW5nIHZhbHVlIG9mIG9iamVjdCBhXG4gKi9cbmZ1bmN0aW9uIGV4dGVuZChhLCBiLCB0aGlzQXJnKSB7XG4gIGZvckVhY2goYiwgZnVuY3Rpb24gYXNzaWduVmFsdWUodmFsLCBrZXkpIHtcbiAgICBpZiAodGhpc0FyZyAmJiB0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBhW2tleV0gPSBiaW5kKHZhbCwgdGhpc0FyZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFba2V5XSA9IHZhbDtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gYTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGlzQXJyYXk6IGlzQXJyYXksXG4gIGlzQXJyYXlCdWZmZXI6IGlzQXJyYXlCdWZmZXIsXG4gIGlzQnVmZmVyOiBpc0J1ZmZlcixcbiAgaXNGb3JtRGF0YTogaXNGb3JtRGF0YSxcbiAgaXNBcnJheUJ1ZmZlclZpZXc6IGlzQXJyYXlCdWZmZXJWaWV3LFxuICBpc1N0cmluZzogaXNTdHJpbmcsXG4gIGlzTnVtYmVyOiBpc051bWJlcixcbiAgaXNPYmplY3Q6IGlzT2JqZWN0LFxuICBpc1VuZGVmaW5lZDogaXNVbmRlZmluZWQsXG4gIGlzRGF0ZTogaXNEYXRlLFxuICBpc0ZpbGU6IGlzRmlsZSxcbiAgaXNCbG9iOiBpc0Jsb2IsXG4gIGlzRnVuY3Rpb246IGlzRnVuY3Rpb24sXG4gIGlzU3RyZWFtOiBpc1N0cmVhbSxcbiAgaXNVUkxTZWFyY2hQYXJhbXM6IGlzVVJMU2VhcmNoUGFyYW1zLFxuICBpc1N0YW5kYXJkQnJvd3NlckVudjogaXNTdGFuZGFyZEJyb3dzZXJFbnYsXG4gIGZvckVhY2g6IGZvckVhY2gsXG4gIG1lcmdlOiBtZXJnZSxcbiAgZXh0ZW5kOiBleHRlbmQsXG4gIHRyaW06IHRyaW1cbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbm9ybWFsaXplSGVhZGVyTmFtZShoZWFkZXJzLCBub3JtYWxpemVkTmFtZSkge1xuICB1dGlscy5mb3JFYWNoKGhlYWRlcnMsIGZ1bmN0aW9uIHByb2Nlc3NIZWFkZXIodmFsdWUsIG5hbWUpIHtcbiAgICBpZiAobmFtZSAhPT0gbm9ybWFsaXplZE5hbWUgJiYgbmFtZS50b1VwcGVyQ2FzZSgpID09PSBub3JtYWxpemVkTmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICBoZWFkZXJzW25vcm1hbGl6ZWROYW1lXSA9IHZhbHVlO1xuICAgICAgZGVsZXRlIGhlYWRlcnNbbmFtZV07XG4gICAgfVxuICB9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogVXBkYXRlIGFuIEVycm9yIHdpdGggdGhlIHNwZWNpZmllZCBjb25maWcsIGVycm9yIGNvZGUsIGFuZCByZXNwb25zZS5cbiAqXG4gKiBAcGFyYW0ge0Vycm9yfSBlcnJvciBUaGUgZXJyb3IgdG8gdXBkYXRlLlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyBUaGUgY29uZmlnLlxuICogQHBhcmFtIHtzdHJpbmd9IFtjb2RlXSBUaGUgZXJyb3IgY29kZSAoZm9yIGV4YW1wbGUsICdFQ09OTkFCT1JURUQnKS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVxdWVzdF0gVGhlIHJlcXVlc3QuXG4gKiBAcGFyYW0ge09iamVjdH0gW3Jlc3BvbnNlXSBUaGUgcmVzcG9uc2UuXG4gKiBAcmV0dXJucyB7RXJyb3J9IFRoZSBlcnJvci5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBlbmhhbmNlRXJyb3IoZXJyb3IsIGNvbmZpZywgY29kZSwgcmVxdWVzdCwgcmVzcG9uc2UpIHtcbiAgZXJyb3IuY29uZmlnID0gY29uZmlnO1xuICBpZiAoY29kZSkge1xuICAgIGVycm9yLmNvZGUgPSBjb2RlO1xuICB9XG4gIGVycm9yLnJlcXVlc3QgPSByZXF1ZXN0O1xuICBlcnJvci5yZXNwb25zZSA9IHJlc3BvbnNlO1xuICByZXR1cm4gZXJyb3I7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZW5oYW5jZUVycm9yID0gcmVxdWlyZSgnLi9lbmhhbmNlRXJyb3InKTtcblxuLyoqXG4gKiBDcmVhdGUgYW4gRXJyb3Igd2l0aCB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UsIGNvbmZpZywgZXJyb3IgY29kZSwgcmVxdWVzdCBhbmQgcmVzcG9uc2UuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgVGhlIGVycm9yIG1lc3NhZ2UuXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIFRoZSBjb25maWcuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2NvZGVdIFRoZSBlcnJvciBjb2RlIChmb3IgZXhhbXBsZSwgJ0VDT05OQUJPUlRFRCcpLlxuICogQHBhcmFtIHtPYmplY3R9IFtyZXF1ZXN0XSBUaGUgcmVxdWVzdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVzcG9uc2VdIFRoZSByZXNwb25zZS5cbiAqIEByZXR1cm5zIHtFcnJvcn0gVGhlIGNyZWF0ZWQgZXJyb3IuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlRXJyb3IobWVzc2FnZSwgY29uZmlnLCBjb2RlLCByZXF1ZXN0LCByZXNwb25zZSkge1xuICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSk7XG4gIHJldHVybiBlbmhhbmNlRXJyb3IoZXJyb3IsIGNvbmZpZywgY29kZSwgcmVxdWVzdCwgcmVzcG9uc2UpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNyZWF0ZUVycm9yID0gcmVxdWlyZSgnLi9jcmVhdGVFcnJvcicpO1xuXG4vKipcbiAqIFJlc29sdmUgb3IgcmVqZWN0IGEgUHJvbWlzZSBiYXNlZCBvbiByZXNwb25zZSBzdGF0dXMuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVzb2x2ZSBBIGZ1bmN0aW9uIHRoYXQgcmVzb2x2ZXMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3QgQSBmdW5jdGlvbiB0aGF0IHJlamVjdHMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge29iamVjdH0gcmVzcG9uc2UgVGhlIHJlc3BvbnNlLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlKSB7XG4gIHZhciB2YWxpZGF0ZVN0YXR1cyA9IHJlc3BvbnNlLmNvbmZpZy52YWxpZGF0ZVN0YXR1cztcbiAgLy8gTm90ZTogc3RhdHVzIGlzIG5vdCBleHBvc2VkIGJ5IFhEb21haW5SZXF1ZXN0XG4gIGlmICghcmVzcG9uc2Uuc3RhdHVzIHx8ICF2YWxpZGF0ZVN0YXR1cyB8fCB2YWxpZGF0ZVN0YXR1cyhyZXNwb25zZS5zdGF0dXMpKSB7XG4gICAgcmVzb2x2ZShyZXNwb25zZSk7XG4gIH0gZWxzZSB7XG4gICAgcmVqZWN0KGNyZWF0ZUVycm9yKFxuICAgICAgJ1JlcXVlc3QgZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgJyArIHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIHJlc3BvbnNlLmNvbmZpZyxcbiAgICAgIG51bGwsXG4gICAgICByZXNwb25zZS5yZXF1ZXN0LFxuICAgICAgcmVzcG9uc2VcbiAgICApKTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi8uLi91dGlscycpO1xuXG5mdW5jdGlvbiBlbmNvZGUodmFsKSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQodmFsKS5cbiAgICByZXBsYWNlKC8lNDAvZ2ksICdAJykuXG4gICAgcmVwbGFjZSgvJTNBL2dpLCAnOicpLlxuICAgIHJlcGxhY2UoLyUyNC9nLCAnJCcpLlxuICAgIHJlcGxhY2UoLyUyQy9naSwgJywnKS5cbiAgICByZXBsYWNlKC8lMjAvZywgJysnKS5cbiAgICByZXBsYWNlKC8lNUIvZ2ksICdbJykuXG4gICAgcmVwbGFjZSgvJTVEL2dpLCAnXScpO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgVVJMIGJ5IGFwcGVuZGluZyBwYXJhbXMgdG8gdGhlIGVuZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIGJhc2Ugb2YgdGhlIHVybCAoZS5nLiwgaHR0cDovL3d3dy5nb29nbGUuY29tKVxuICogQHBhcmFtIHtvYmplY3R9IFtwYXJhbXNdIFRoZSBwYXJhbXMgdG8gYmUgYXBwZW5kZWRcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBmb3JtYXR0ZWQgdXJsXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYnVpbGRVUkwodXJsLCBwYXJhbXMsIHBhcmFtc1NlcmlhbGl6ZXIpIHtcbiAgLyplc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246MCovXG4gIGlmICghcGFyYW1zKSB7XG4gICAgcmV0dXJuIHVybDtcbiAgfVxuXG4gIHZhciBzZXJpYWxpemVkUGFyYW1zO1xuICBpZiAocGFyYW1zU2VyaWFsaXplcikge1xuICAgIHNlcmlhbGl6ZWRQYXJhbXMgPSBwYXJhbXNTZXJpYWxpemVyKHBhcmFtcyk7XG4gIH0gZWxzZSBpZiAodXRpbHMuaXNVUkxTZWFyY2hQYXJhbXMocGFyYW1zKSkge1xuICAgIHNlcmlhbGl6ZWRQYXJhbXMgPSBwYXJhbXMudG9TdHJpbmcoKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgcGFydHMgPSBbXTtcblxuICAgIHV0aWxzLmZvckVhY2gocGFyYW1zLCBmdW5jdGlvbiBzZXJpYWxpemUodmFsLCBrZXkpIHtcbiAgICAgIGlmICh2YWwgPT09IG51bGwgfHwgdHlwZW9mIHZhbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodXRpbHMuaXNBcnJheSh2YWwpKSB7XG4gICAgICAgIGtleSA9IGtleSArICdbXSc7XG4gICAgICB9XG5cbiAgICAgIGlmICghdXRpbHMuaXNBcnJheSh2YWwpKSB7XG4gICAgICAgIHZhbCA9IFt2YWxdO1xuICAgICAgfVxuXG4gICAgICB1dGlscy5mb3JFYWNoKHZhbCwgZnVuY3Rpb24gcGFyc2VWYWx1ZSh2KSB7XG4gICAgICAgIGlmICh1dGlscy5pc0RhdGUodikpIHtcbiAgICAgICAgICB2ID0gdi50b0lTT1N0cmluZygpO1xuICAgICAgICB9IGVsc2UgaWYgKHV0aWxzLmlzT2JqZWN0KHYpKSB7XG4gICAgICAgICAgdiA9IEpTT04uc3RyaW5naWZ5KHYpO1xuICAgICAgICB9XG4gICAgICAgIHBhcnRzLnB1c2goZW5jb2RlKGtleSkgKyAnPScgKyBlbmNvZGUodikpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBzZXJpYWxpemVkUGFyYW1zID0gcGFydHMuam9pbignJicpO1xuICB9XG5cbiAgaWYgKHNlcmlhbGl6ZWRQYXJhbXMpIHtcbiAgICB1cmwgKz0gKHVybC5pbmRleE9mKCc/JykgPT09IC0xID8gJz8nIDogJyYnKSArIHNlcmlhbGl6ZWRQYXJhbXM7XG4gIH1cblxuICByZXR1cm4gdXJsO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi8uLi91dGlscycpO1xuXG4vLyBIZWFkZXJzIHdob3NlIGR1cGxpY2F0ZXMgYXJlIGlnbm9yZWQgYnkgbm9kZVxuLy8gYy5mLiBodHRwczovL25vZGVqcy5vcmcvYXBpL2h0dHAuaHRtbCNodHRwX21lc3NhZ2VfaGVhZGVyc1xudmFyIGlnbm9yZUR1cGxpY2F0ZU9mID0gW1xuICAnYWdlJywgJ2F1dGhvcml6YXRpb24nLCAnY29udGVudC1sZW5ndGgnLCAnY29udGVudC10eXBlJywgJ2V0YWcnLFxuICAnZXhwaXJlcycsICdmcm9tJywgJ2hvc3QnLCAnaWYtbW9kaWZpZWQtc2luY2UnLCAnaWYtdW5tb2RpZmllZC1zaW5jZScsXG4gICdsYXN0LW1vZGlmaWVkJywgJ2xvY2F0aW9uJywgJ21heC1mb3J3YXJkcycsICdwcm94eS1hdXRob3JpemF0aW9uJyxcbiAgJ3JlZmVyZXInLCAncmV0cnktYWZ0ZXInLCAndXNlci1hZ2VudCdcbl07XG5cbi8qKlxuICogUGFyc2UgaGVhZGVycyBpbnRvIGFuIG9iamVjdFxuICpcbiAqIGBgYFxuICogRGF0ZTogV2VkLCAyNyBBdWcgMjAxNCAwODo1ODo0OSBHTVRcbiAqIENvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vanNvblxuICogQ29ubmVjdGlvbjoga2VlcC1hbGl2ZVxuICogVHJhbnNmZXItRW5jb2Rpbmc6IGNodW5rZWRcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBoZWFkZXJzIEhlYWRlcnMgbmVlZGluZyB0byBiZSBwYXJzZWRcbiAqIEByZXR1cm5zIHtPYmplY3R9IEhlYWRlcnMgcGFyc2VkIGludG8gYW4gb2JqZWN0XG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFyc2VIZWFkZXJzKGhlYWRlcnMpIHtcbiAgdmFyIHBhcnNlZCA9IHt9O1xuICB2YXIga2V5O1xuICB2YXIgdmFsO1xuICB2YXIgaTtcblxuICBpZiAoIWhlYWRlcnMpIHsgcmV0dXJuIHBhcnNlZDsgfVxuXG4gIHV0aWxzLmZvckVhY2goaGVhZGVycy5zcGxpdCgnXFxuJyksIGZ1bmN0aW9uIHBhcnNlcihsaW5lKSB7XG4gICAgaSA9IGxpbmUuaW5kZXhPZignOicpO1xuICAgIGtleSA9IHV0aWxzLnRyaW0obGluZS5zdWJzdHIoMCwgaSkpLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFsID0gdXRpbHMudHJpbShsaW5lLnN1YnN0cihpICsgMSkpO1xuXG4gICAgaWYgKGtleSkge1xuICAgICAgaWYgKHBhcnNlZFtrZXldICYmIGlnbm9yZUR1cGxpY2F0ZU9mLmluZGV4T2Yoa2V5KSA+PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChrZXkgPT09ICdzZXQtY29va2llJykge1xuICAgICAgICBwYXJzZWRba2V5XSA9IChwYXJzZWRba2V5XSA/IHBhcnNlZFtrZXldIDogW10pLmNvbmNhdChbdmFsXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXJzZWRba2V5XSA9IHBhcnNlZFtrZXldID8gcGFyc2VkW2tleV0gKyAnLCAnICsgdmFsIDogdmFsO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHBhcnNlZDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAoXG4gIHV0aWxzLmlzU3RhbmRhcmRCcm93c2VyRW52KCkgP1xuXG4gIC8vIFN0YW5kYXJkIGJyb3dzZXIgZW52cyBoYXZlIGZ1bGwgc3VwcG9ydCBvZiB0aGUgQVBJcyBuZWVkZWQgdG8gdGVzdFxuICAvLyB3aGV0aGVyIHRoZSByZXF1ZXN0IFVSTCBpcyBvZiB0aGUgc2FtZSBvcmlnaW4gYXMgY3VycmVudCBsb2NhdGlvbi5cbiAgKGZ1bmN0aW9uIHN0YW5kYXJkQnJvd3NlckVudigpIHtcbiAgICB2YXIgbXNpZSA9IC8obXNpZXx0cmlkZW50KS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gICAgdmFyIHVybFBhcnNpbmdOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgIHZhciBvcmlnaW5VUkw7XG5cbiAgICAvKipcbiAgICAqIFBhcnNlIGEgVVJMIHRvIGRpc2NvdmVyIGl0J3MgY29tcG9uZW50c1xuICAgICpcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSB1cmwgVGhlIFVSTCB0byBiZSBwYXJzZWRcbiAgICAqIEByZXR1cm5zIHtPYmplY3R9XG4gICAgKi9cbiAgICBmdW5jdGlvbiByZXNvbHZlVVJMKHVybCkge1xuICAgICAgdmFyIGhyZWYgPSB1cmw7XG5cbiAgICAgIGlmIChtc2llKSB7XG4gICAgICAgIC8vIElFIG5lZWRzIGF0dHJpYnV0ZSBzZXQgdHdpY2UgdG8gbm9ybWFsaXplIHByb3BlcnRpZXNcbiAgICAgICAgdXJsUGFyc2luZ05vZGUuc2V0QXR0cmlidXRlKCdocmVmJywgaHJlZik7XG4gICAgICAgIGhyZWYgPSB1cmxQYXJzaW5nTm9kZS5ocmVmO1xuICAgICAgfVxuXG4gICAgICB1cmxQYXJzaW5nTm9kZS5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBocmVmKTtcblxuICAgICAgLy8gdXJsUGFyc2luZ05vZGUgcHJvdmlkZXMgdGhlIFVybFV0aWxzIGludGVyZmFjZSAtIGh0dHA6Ly91cmwuc3BlYy53aGF0d2cub3JnLyN1cmx1dGlsc1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaHJlZjogdXJsUGFyc2luZ05vZGUuaHJlZixcbiAgICAgICAgcHJvdG9jb2w6IHVybFBhcnNpbmdOb2RlLnByb3RvY29sID8gdXJsUGFyc2luZ05vZGUucHJvdG9jb2wucmVwbGFjZSgvOiQvLCAnJykgOiAnJyxcbiAgICAgICAgaG9zdDogdXJsUGFyc2luZ05vZGUuaG9zdCxcbiAgICAgICAgc2VhcmNoOiB1cmxQYXJzaW5nTm9kZS5zZWFyY2ggPyB1cmxQYXJzaW5nTm9kZS5zZWFyY2gucmVwbGFjZSgvXlxcPy8sICcnKSA6ICcnLFxuICAgICAgICBoYXNoOiB1cmxQYXJzaW5nTm9kZS5oYXNoID8gdXJsUGFyc2luZ05vZGUuaGFzaC5yZXBsYWNlKC9eIy8sICcnKSA6ICcnLFxuICAgICAgICBob3N0bmFtZTogdXJsUGFyc2luZ05vZGUuaG9zdG5hbWUsXG4gICAgICAgIHBvcnQ6IHVybFBhcnNpbmdOb2RlLnBvcnQsXG4gICAgICAgIHBhdGhuYW1lOiAodXJsUGFyc2luZ05vZGUucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycpID9cbiAgICAgICAgICAgICAgICAgIHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lIDpcbiAgICAgICAgICAgICAgICAgICcvJyArIHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lXG4gICAgICB9O1xuICAgIH1cblxuICAgIG9yaWdpblVSTCA9IHJlc29sdmVVUkwod2luZG93LmxvY2F0aW9uLmhyZWYpO1xuXG4gICAgLyoqXG4gICAgKiBEZXRlcm1pbmUgaWYgYSBVUkwgc2hhcmVzIHRoZSBzYW1lIG9yaWdpbiBhcyB0aGUgY3VycmVudCBsb2NhdGlvblxuICAgICpcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSByZXF1ZXN0VVJMIFRoZSBVUkwgdG8gdGVzdFxuICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgVVJMIHNoYXJlcyB0aGUgc2FtZSBvcmlnaW4sIG90aGVyd2lzZSBmYWxzZVxuICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uIGlzVVJMU2FtZU9yaWdpbihyZXF1ZXN0VVJMKSB7XG4gICAgICB2YXIgcGFyc2VkID0gKHV0aWxzLmlzU3RyaW5nKHJlcXVlc3RVUkwpKSA/IHJlc29sdmVVUkwocmVxdWVzdFVSTCkgOiByZXF1ZXN0VVJMO1xuICAgICAgcmV0dXJuIChwYXJzZWQucHJvdG9jb2wgPT09IG9yaWdpblVSTC5wcm90b2NvbCAmJlxuICAgICAgICAgICAgcGFyc2VkLmhvc3QgPT09IG9yaWdpblVSTC5ob3N0KTtcbiAgICB9O1xuICB9KSgpIDpcblxuICAvLyBOb24gc3RhbmRhcmQgYnJvd3NlciBlbnZzICh3ZWIgd29ya2VycywgcmVhY3QtbmF0aXZlKSBsYWNrIG5lZWRlZCBzdXBwb3J0LlxuICAoZnVuY3Rpb24gbm9uU3RhbmRhcmRCcm93c2VyRW52KCkge1xuICAgIHJldHVybiBmdW5jdGlvbiBpc1VSTFNhbWVPcmlnaW4oKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuICB9KSgpXG4pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBidG9hIHBvbHlmaWxsIGZvciBJRTwxMCBjb3VydGVzeSBodHRwczovL2dpdGh1Yi5jb20vZGF2aWRjaGFtYmVycy9CYXNlNjQuanNcblxudmFyIGNoYXJzID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89JztcblxuZnVuY3Rpb24gRSgpIHtcbiAgdGhpcy5tZXNzYWdlID0gJ1N0cmluZyBjb250YWlucyBhbiBpbnZhbGlkIGNoYXJhY3Rlcic7XG59XG5FLnByb3RvdHlwZSA9IG5ldyBFcnJvcjtcbkUucHJvdG90eXBlLmNvZGUgPSA1O1xuRS5wcm90b3R5cGUubmFtZSA9ICdJbnZhbGlkQ2hhcmFjdGVyRXJyb3InO1xuXG5mdW5jdGlvbiBidG9hKGlucHV0KSB7XG4gIHZhciBzdHIgPSBTdHJpbmcoaW5wdXQpO1xuICB2YXIgb3V0cHV0ID0gJyc7XG4gIGZvciAoXG4gICAgLy8gaW5pdGlhbGl6ZSByZXN1bHQgYW5kIGNvdW50ZXJcbiAgICB2YXIgYmxvY2ssIGNoYXJDb2RlLCBpZHggPSAwLCBtYXAgPSBjaGFycztcbiAgICAvLyBpZiB0aGUgbmV4dCBzdHIgaW5kZXggZG9lcyBub3QgZXhpc3Q6XG4gICAgLy8gICBjaGFuZ2UgdGhlIG1hcHBpbmcgdGFibGUgdG8gXCI9XCJcbiAgICAvLyAgIGNoZWNrIGlmIGQgaGFzIG5vIGZyYWN0aW9uYWwgZGlnaXRzXG4gICAgc3RyLmNoYXJBdChpZHggfCAwKSB8fCAobWFwID0gJz0nLCBpZHggJSAxKTtcbiAgICAvLyBcIjggLSBpZHggJSAxICogOFwiIGdlbmVyYXRlcyB0aGUgc2VxdWVuY2UgMiwgNCwgNiwgOFxuICAgIG91dHB1dCArPSBtYXAuY2hhckF0KDYzICYgYmxvY2sgPj4gOCAtIGlkeCAlIDEgKiA4KVxuICApIHtcbiAgICBjaGFyQ29kZSA9IHN0ci5jaGFyQ29kZUF0KGlkeCArPSAzIC8gNCk7XG4gICAgaWYgKGNoYXJDb2RlID4gMHhGRikge1xuICAgICAgdGhyb3cgbmV3IEUoKTtcbiAgICB9XG4gICAgYmxvY2sgPSBibG9jayA8PCA4IHwgY2hhckNvZGU7XG4gIH1cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBidG9hO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKFxuICB1dGlscy5pc1N0YW5kYXJkQnJvd3NlckVudigpID9cblxuICAvLyBTdGFuZGFyZCBicm93c2VyIGVudnMgc3VwcG9ydCBkb2N1bWVudC5jb29raWVcbiAgKGZ1bmN0aW9uIHN0YW5kYXJkQnJvd3NlckVudigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgd3JpdGU6IGZ1bmN0aW9uIHdyaXRlKG5hbWUsIHZhbHVlLCBleHBpcmVzLCBwYXRoLCBkb21haW4sIHNlY3VyZSkge1xuICAgICAgICB2YXIgY29va2llID0gW107XG4gICAgICAgIGNvb2tpZS5wdXNoKG5hbWUgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpKTtcblxuICAgICAgICBpZiAodXRpbHMuaXNOdW1iZXIoZXhwaXJlcykpIHtcbiAgICAgICAgICBjb29raWUucHVzaCgnZXhwaXJlcz0nICsgbmV3IERhdGUoZXhwaXJlcykudG9HTVRTdHJpbmcoKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodXRpbHMuaXNTdHJpbmcocGF0aCkpIHtcbiAgICAgICAgICBjb29raWUucHVzaCgncGF0aD0nICsgcGF0aCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodXRpbHMuaXNTdHJpbmcoZG9tYWluKSkge1xuICAgICAgICAgIGNvb2tpZS5wdXNoKCdkb21haW49JyArIGRvbWFpbik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2VjdXJlID09PSB0cnVlKSB7XG4gICAgICAgICAgY29va2llLnB1c2goJ3NlY3VyZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgZG9jdW1lbnQuY29va2llID0gY29va2llLmpvaW4oJzsgJyk7XG4gICAgICB9LFxuXG4gICAgICByZWFkOiBmdW5jdGlvbiByZWFkKG5hbWUpIHtcbiAgICAgICAgdmFyIG1hdGNoID0gZG9jdW1lbnQuY29va2llLm1hdGNoKG5ldyBSZWdFeHAoJyhefDtcXFxccyopKCcgKyBuYW1lICsgJyk9KFteO10qKScpKTtcbiAgICAgICAgcmV0dXJuIChtYXRjaCA/IGRlY29kZVVSSUNvbXBvbmVudChtYXRjaFszXSkgOiBudWxsKTtcbiAgICAgIH0sXG5cbiAgICAgIHJlbW92ZTogZnVuY3Rpb24gcmVtb3ZlKG5hbWUpIHtcbiAgICAgICAgdGhpcy53cml0ZShuYW1lLCAnJywgRGF0ZS5ub3coKSAtIDg2NDAwMDAwKTtcbiAgICAgIH1cbiAgICB9O1xuICB9KSgpIDpcblxuICAvLyBOb24gc3RhbmRhcmQgYnJvd3NlciBlbnYgKHdlYiB3b3JrZXJzLCByZWFjdC1uYXRpdmUpIGxhY2sgbmVlZGVkIHN1cHBvcnQuXG4gIChmdW5jdGlvbiBub25TdGFuZGFyZEJyb3dzZXJFbnYoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHdyaXRlOiBmdW5jdGlvbiB3cml0ZSgpIHt9LFxuICAgICAgcmVhZDogZnVuY3Rpb24gcmVhZCgpIHsgcmV0dXJuIG51bGw7IH0sXG4gICAgICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZSgpIHt9XG4gICAgfTtcbiAgfSkoKVxuKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi8uLi91dGlscycpO1xudmFyIHNldHRsZSA9IHJlcXVpcmUoJy4vLi4vY29yZS9zZXR0bGUnKTtcbnZhciBidWlsZFVSTCA9IHJlcXVpcmUoJy4vLi4vaGVscGVycy9idWlsZFVSTCcpO1xudmFyIHBhcnNlSGVhZGVycyA9IHJlcXVpcmUoJy4vLi4vaGVscGVycy9wYXJzZUhlYWRlcnMnKTtcbnZhciBpc1VSTFNhbWVPcmlnaW4gPSByZXF1aXJlKCcuLy4uL2hlbHBlcnMvaXNVUkxTYW1lT3JpZ2luJyk7XG52YXIgY3JlYXRlRXJyb3IgPSByZXF1aXJlKCcuLi9jb3JlL2NyZWF0ZUVycm9yJyk7XG52YXIgYnRvYSA9ICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuYnRvYSAmJiB3aW5kb3cuYnRvYS5iaW5kKHdpbmRvdykpIHx8IHJlcXVpcmUoJy4vLi4vaGVscGVycy9idG9hJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24geGhyQWRhcHRlcihjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIGRpc3BhdGNoWGhyUmVxdWVzdChyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgcmVxdWVzdERhdGEgPSBjb25maWcuZGF0YTtcbiAgICB2YXIgcmVxdWVzdEhlYWRlcnMgPSBjb25maWcuaGVhZGVycztcblxuICAgIGlmICh1dGlscy5pc0Zvcm1EYXRhKHJlcXVlc3REYXRhKSkge1xuICAgICAgZGVsZXRlIHJlcXVlc3RIZWFkZXJzWydDb250ZW50LVR5cGUnXTsgLy8gTGV0IHRoZSBicm93c2VyIHNldCBpdFxuICAgIH1cblxuICAgIHZhciByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgdmFyIGxvYWRFdmVudCA9ICdvbnJlYWR5c3RhdGVjaGFuZ2UnO1xuICAgIHZhciB4RG9tYWluID0gZmFsc2U7XG5cbiAgICAvLyBGb3IgSUUgOC85IENPUlMgc3VwcG9ydFxuICAgIC8vIE9ubHkgc3VwcG9ydHMgUE9TVCBhbmQgR0VUIGNhbGxzIGFuZCBkb2Vzbid0IHJldHVybnMgdGhlIHJlc3BvbnNlIGhlYWRlcnMuXG4gICAgLy8gRE9OJ1QgZG8gdGhpcyBmb3IgdGVzdGluZyBiL2MgWE1MSHR0cFJlcXVlc3QgaXMgbW9ja2VkLCBub3QgWERvbWFpblJlcXVlc3QuXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAndGVzdCcgJiZcbiAgICAgICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgd2luZG93LlhEb21haW5SZXF1ZXN0ICYmICEoJ3dpdGhDcmVkZW50aWFscycgaW4gcmVxdWVzdCkgJiZcbiAgICAgICAgIWlzVVJMU2FtZU9yaWdpbihjb25maWcudXJsKSkge1xuICAgICAgcmVxdWVzdCA9IG5ldyB3aW5kb3cuWERvbWFpblJlcXVlc3QoKTtcbiAgICAgIGxvYWRFdmVudCA9ICdvbmxvYWQnO1xuICAgICAgeERvbWFpbiA9IHRydWU7XG4gICAgICByZXF1ZXN0Lm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbiBoYW5kbGVQcm9ncmVzcygpIHt9O1xuICAgICAgcmVxdWVzdC5vbnRpbWVvdXQgPSBmdW5jdGlvbiBoYW5kbGVUaW1lb3V0KCkge307XG4gICAgfVxuXG4gICAgLy8gSFRUUCBiYXNpYyBhdXRoZW50aWNhdGlvblxuICAgIGlmIChjb25maWcuYXV0aCkge1xuICAgICAgdmFyIHVzZXJuYW1lID0gY29uZmlnLmF1dGgudXNlcm5hbWUgfHwgJyc7XG4gICAgICB2YXIgcGFzc3dvcmQgPSBjb25maWcuYXV0aC5wYXNzd29yZCB8fCAnJztcbiAgICAgIHJlcXVlc3RIZWFkZXJzLkF1dGhvcml6YXRpb24gPSAnQmFzaWMgJyArIGJ0b2EodXNlcm5hbWUgKyAnOicgKyBwYXNzd29yZCk7XG4gICAgfVxuXG4gICAgcmVxdWVzdC5vcGVuKGNvbmZpZy5tZXRob2QudG9VcHBlckNhc2UoKSwgYnVpbGRVUkwoY29uZmlnLnVybCwgY29uZmlnLnBhcmFtcywgY29uZmlnLnBhcmFtc1NlcmlhbGl6ZXIpLCB0cnVlKTtcblxuICAgIC8vIFNldCB0aGUgcmVxdWVzdCB0aW1lb3V0IGluIE1TXG4gICAgcmVxdWVzdC50aW1lb3V0ID0gY29uZmlnLnRpbWVvdXQ7XG5cbiAgICAvLyBMaXN0ZW4gZm9yIHJlYWR5IHN0YXRlXG4gICAgcmVxdWVzdFtsb2FkRXZlbnRdID0gZnVuY3Rpb24gaGFuZGxlTG9hZCgpIHtcbiAgICAgIGlmICghcmVxdWVzdCB8fCAocmVxdWVzdC5yZWFkeVN0YXRlICE9PSA0ICYmICF4RG9tYWluKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFRoZSByZXF1ZXN0IGVycm9yZWQgb3V0IGFuZCB3ZSBkaWRuJ3QgZ2V0IGEgcmVzcG9uc2UsIHRoaXMgd2lsbCBiZVxuICAgICAgLy8gaGFuZGxlZCBieSBvbmVycm9yIGluc3RlYWRcbiAgICAgIC8vIFdpdGggb25lIGV4Y2VwdGlvbjogcmVxdWVzdCB0aGF0IHVzaW5nIGZpbGU6IHByb3RvY29sLCBtb3N0IGJyb3dzZXJzXG4gICAgICAvLyB3aWxsIHJldHVybiBzdGF0dXMgYXMgMCBldmVuIHRob3VnaCBpdCdzIGEgc3VjY2Vzc2Z1bCByZXF1ZXN0XG4gICAgICBpZiAocmVxdWVzdC5zdGF0dXMgPT09IDAgJiYgIShyZXF1ZXN0LnJlc3BvbnNlVVJMICYmIHJlcXVlc3QucmVzcG9uc2VVUkwuaW5kZXhPZignZmlsZTonKSA9PT0gMCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBQcmVwYXJlIHRoZSByZXNwb25zZVxuICAgICAgdmFyIHJlc3BvbnNlSGVhZGVycyA9ICdnZXRBbGxSZXNwb25zZUhlYWRlcnMnIGluIHJlcXVlc3QgPyBwYXJzZUhlYWRlcnMocmVxdWVzdC5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSkgOiBudWxsO1xuICAgICAgdmFyIHJlc3BvbnNlRGF0YSA9ICFjb25maWcucmVzcG9uc2VUeXBlIHx8IGNvbmZpZy5yZXNwb25zZVR5cGUgPT09ICd0ZXh0JyA/IHJlcXVlc3QucmVzcG9uc2VUZXh0IDogcmVxdWVzdC5yZXNwb25zZTtcbiAgICAgIHZhciByZXNwb25zZSA9IHtcbiAgICAgICAgZGF0YTogcmVzcG9uc2VEYXRhLFxuICAgICAgICAvLyBJRSBzZW5kcyAxMjIzIGluc3RlYWQgb2YgMjA0IChodHRwczovL2dpdGh1Yi5jb20vYXhpb3MvYXhpb3MvaXNzdWVzLzIwMSlcbiAgICAgICAgc3RhdHVzOiByZXF1ZXN0LnN0YXR1cyA9PT0gMTIyMyA/IDIwNCA6IHJlcXVlc3Quc3RhdHVzLFxuICAgICAgICBzdGF0dXNUZXh0OiByZXF1ZXN0LnN0YXR1cyA9PT0gMTIyMyA/ICdObyBDb250ZW50JyA6IHJlcXVlc3Quc3RhdHVzVGV4dCxcbiAgICAgICAgaGVhZGVyczogcmVzcG9uc2VIZWFkZXJzLFxuICAgICAgICBjb25maWc6IGNvbmZpZyxcbiAgICAgICAgcmVxdWVzdDogcmVxdWVzdFxuICAgICAgfTtcblxuICAgICAgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgcmVzcG9uc2UpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIGxvdyBsZXZlbCBuZXR3b3JrIGVycm9yc1xuICAgIHJlcXVlc3Qub25lcnJvciA9IGZ1bmN0aW9uIGhhbmRsZUVycm9yKCkge1xuICAgICAgLy8gUmVhbCBlcnJvcnMgYXJlIGhpZGRlbiBmcm9tIHVzIGJ5IHRoZSBicm93c2VyXG4gICAgICAvLyBvbmVycm9yIHNob3VsZCBvbmx5IGZpcmUgaWYgaXQncyBhIG5ldHdvcmsgZXJyb3JcbiAgICAgIHJlamVjdChjcmVhdGVFcnJvcignTmV0d29yayBFcnJvcicsIGNvbmZpZywgbnVsbCwgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIHRpbWVvdXRcbiAgICByZXF1ZXN0Lm9udGltZW91dCA9IGZ1bmN0aW9uIGhhbmRsZVRpbWVvdXQoKSB7XG4gICAgICByZWplY3QoY3JlYXRlRXJyb3IoJ3RpbWVvdXQgb2YgJyArIGNvbmZpZy50aW1lb3V0ICsgJ21zIGV4Y2VlZGVkJywgY29uZmlnLCAnRUNPTk5BQk9SVEVEJyxcbiAgICAgICAgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gQWRkIHhzcmYgaGVhZGVyXG4gICAgLy8gVGhpcyBpcyBvbmx5IGRvbmUgaWYgcnVubmluZyBpbiBhIHN0YW5kYXJkIGJyb3dzZXIgZW52aXJvbm1lbnQuXG4gICAgLy8gU3BlY2lmaWNhbGx5IG5vdCBpZiB3ZSdyZSBpbiBhIHdlYiB3b3JrZXIsIG9yIHJlYWN0LW5hdGl2ZS5cbiAgICBpZiAodXRpbHMuaXNTdGFuZGFyZEJyb3dzZXJFbnYoKSkge1xuICAgICAgdmFyIGNvb2tpZXMgPSByZXF1aXJlKCcuLy4uL2hlbHBlcnMvY29va2llcycpO1xuXG4gICAgICAvLyBBZGQgeHNyZiBoZWFkZXJcbiAgICAgIHZhciB4c3JmVmFsdWUgPSAoY29uZmlnLndpdGhDcmVkZW50aWFscyB8fCBpc1VSTFNhbWVPcmlnaW4oY29uZmlnLnVybCkpICYmIGNvbmZpZy54c3JmQ29va2llTmFtZSA/XG4gICAgICAgICAgY29va2llcy5yZWFkKGNvbmZpZy54c3JmQ29va2llTmFtZSkgOlxuICAgICAgICAgIHVuZGVmaW5lZDtcblxuICAgICAgaWYgKHhzcmZWYWx1ZSkge1xuICAgICAgICByZXF1ZXN0SGVhZGVyc1tjb25maWcueHNyZkhlYWRlck5hbWVdID0geHNyZlZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFkZCBoZWFkZXJzIHRvIHRoZSByZXF1ZXN0XG4gICAgaWYgKCdzZXRSZXF1ZXN0SGVhZGVyJyBpbiByZXF1ZXN0KSB7XG4gICAgICB1dGlscy5mb3JFYWNoKHJlcXVlc3RIZWFkZXJzLCBmdW5jdGlvbiBzZXRSZXF1ZXN0SGVhZGVyKHZhbCwga2V5KSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVxdWVzdERhdGEgPT09ICd1bmRlZmluZWQnICYmIGtleS50b0xvd2VyQ2FzZSgpID09PSAnY29udGVudC10eXBlJykge1xuICAgICAgICAgIC8vIFJlbW92ZSBDb250ZW50LVR5cGUgaWYgZGF0YSBpcyB1bmRlZmluZWRcbiAgICAgICAgICBkZWxldGUgcmVxdWVzdEhlYWRlcnNba2V5XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBPdGhlcndpc2UgYWRkIGhlYWRlciB0byB0aGUgcmVxdWVzdFxuICAgICAgICAgIHJlcXVlc3Quc2V0UmVxdWVzdEhlYWRlcihrZXksIHZhbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEFkZCB3aXRoQ3JlZGVudGlhbHMgdG8gcmVxdWVzdCBpZiBuZWVkZWRcbiAgICBpZiAoY29uZmlnLndpdGhDcmVkZW50aWFscykge1xuICAgICAgcmVxdWVzdC53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIEFkZCByZXNwb25zZVR5cGUgdG8gcmVxdWVzdCBpZiBuZWVkZWRcbiAgICBpZiAoY29uZmlnLnJlc3BvbnNlVHlwZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVxdWVzdC5yZXNwb25zZVR5cGUgPSBjb25maWcucmVzcG9uc2VUeXBlO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBFeHBlY3RlZCBET01FeGNlcHRpb24gdGhyb3duIGJ5IGJyb3dzZXJzIG5vdCBjb21wYXRpYmxlIFhNTEh0dHBSZXF1ZXN0IExldmVsIDIuXG4gICAgICAgIC8vIEJ1dCwgdGhpcyBjYW4gYmUgc3VwcHJlc3NlZCBmb3IgJ2pzb24nIHR5cGUgYXMgaXQgY2FuIGJlIHBhcnNlZCBieSBkZWZhdWx0ICd0cmFuc2Zvcm1SZXNwb25zZScgZnVuY3Rpb24uXG4gICAgICAgIGlmIChjb25maWcucmVzcG9uc2VUeXBlICE9PSAnanNvbicpIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHByb2dyZXNzIGlmIG5lZWRlZFxuICAgIGlmICh0eXBlb2YgY29uZmlnLm9uRG93bmxvYWRQcm9ncmVzcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCdwcm9ncmVzcycsIGNvbmZpZy5vbkRvd25sb2FkUHJvZ3Jlc3MpO1xuICAgIH1cblxuICAgIC8vIE5vdCBhbGwgYnJvd3NlcnMgc3VwcG9ydCB1cGxvYWQgZXZlbnRzXG4gICAgaWYgKHR5cGVvZiBjb25maWcub25VcGxvYWRQcm9ncmVzcyA9PT0gJ2Z1bmN0aW9uJyAmJiByZXF1ZXN0LnVwbG9hZCkge1xuICAgICAgcmVxdWVzdC51cGxvYWQuYWRkRXZlbnRMaXN0ZW5lcigncHJvZ3Jlc3MnLCBjb25maWcub25VcGxvYWRQcm9ncmVzcyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5jYW5jZWxUb2tlbikge1xuICAgICAgLy8gSGFuZGxlIGNhbmNlbGxhdGlvblxuICAgICAgY29uZmlnLmNhbmNlbFRva2VuLnByb21pc2UudGhlbihmdW5jdGlvbiBvbkNhbmNlbGVkKGNhbmNlbCkge1xuICAgICAgICBpZiAoIXJlcXVlc3QpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0LmFib3J0KCk7XG4gICAgICAgIHJlamVjdChjYW5jZWwpO1xuICAgICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICAgIHJlcXVlc3QgPSBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHJlcXVlc3REYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJlcXVlc3REYXRhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBTZW5kIHRoZSByZXF1ZXN0XG4gICAgcmVxdWVzdC5zZW5kKHJlcXVlc3REYXRhKTtcbiAgfSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgbm9ybWFsaXplSGVhZGVyTmFtZSA9IHJlcXVpcmUoJy4vaGVscGVycy9ub3JtYWxpemVIZWFkZXJOYW1lJyk7XG5cbnZhciBERUZBVUxUX0NPTlRFTlRfVFlQRSA9IHtcbiAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXG59O1xuXG5mdW5jdGlvbiBzZXRDb250ZW50VHlwZUlmVW5zZXQoaGVhZGVycywgdmFsdWUpIHtcbiAgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChoZWFkZXJzKSAmJiB1dGlscy5pc1VuZGVmaW5lZChoZWFkZXJzWydDb250ZW50LVR5cGUnXSkpIHtcbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IHZhbHVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldERlZmF1bHRBZGFwdGVyKCkge1xuICB2YXIgYWRhcHRlcjtcbiAgaWYgKHR5cGVvZiBYTUxIdHRwUmVxdWVzdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAvLyBGb3IgYnJvd3NlcnMgdXNlIFhIUiBhZGFwdGVyXG4gICAgYWRhcHRlciA9IHJlcXVpcmUoJy4vYWRhcHRlcnMveGhyJyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gRm9yIG5vZGUgdXNlIEhUVFAgYWRhcHRlclxuICAgIGFkYXB0ZXIgPSByZXF1aXJlKCcuL2FkYXB0ZXJzL2h0dHAnKTtcbiAgfVxuICByZXR1cm4gYWRhcHRlcjtcbn1cblxudmFyIGRlZmF1bHRzID0ge1xuICBhZGFwdGVyOiBnZXREZWZhdWx0QWRhcHRlcigpLFxuXG4gIHRyYW5zZm9ybVJlcXVlc3Q6IFtmdW5jdGlvbiB0cmFuc2Zvcm1SZXF1ZXN0KGRhdGEsIGhlYWRlcnMpIHtcbiAgICBub3JtYWxpemVIZWFkZXJOYW1lKGhlYWRlcnMsICdDb250ZW50LVR5cGUnKTtcbiAgICBpZiAodXRpbHMuaXNGb3JtRGF0YShkYXRhKSB8fFxuICAgICAgdXRpbHMuaXNBcnJheUJ1ZmZlcihkYXRhKSB8fFxuICAgICAgdXRpbHMuaXNCdWZmZXIoZGF0YSkgfHxcbiAgICAgIHV0aWxzLmlzU3RyZWFtKGRhdGEpIHx8XG4gICAgICB1dGlscy5pc0ZpbGUoZGF0YSkgfHxcbiAgICAgIHV0aWxzLmlzQmxvYihkYXRhKVxuICAgICkge1xuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuICAgIGlmICh1dGlscy5pc0FycmF5QnVmZmVyVmlldyhkYXRhKSkge1xuICAgICAgcmV0dXJuIGRhdGEuYnVmZmVyO1xuICAgIH1cbiAgICBpZiAodXRpbHMuaXNVUkxTZWFyY2hQYXJhbXMoZGF0YSkpIHtcbiAgICAgIHNldENvbnRlbnRUeXBlSWZVbnNldChoZWFkZXJzLCAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkO2NoYXJzZXQ9dXRmLTgnKTtcbiAgICAgIHJldHVybiBkYXRhLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIGlmICh1dGlscy5pc09iamVjdChkYXRhKSkge1xuICAgICAgc2V0Q29udGVudFR5cGVJZlVuc2V0KGhlYWRlcnMsICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTgnKTtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShkYXRhKTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1dLFxuXG4gIHRyYW5zZm9ybVJlc3BvbnNlOiBbZnVuY3Rpb24gdHJhbnNmb3JtUmVzcG9uc2UoZGF0YSkge1xuICAgIC8qZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOjAqL1xuICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGRhdGEgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgfSBjYXRjaCAoZSkgeyAvKiBJZ25vcmUgKi8gfVxuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfV0sXG5cbiAgdGltZW91dDogMCxcblxuICB4c3JmQ29va2llTmFtZTogJ1hTUkYtVE9LRU4nLFxuICB4c3JmSGVhZGVyTmFtZTogJ1gtWFNSRi1UT0tFTicsXG5cbiAgbWF4Q29udGVudExlbmd0aDogLTEsXG5cbiAgdmFsaWRhdGVTdGF0dXM6IGZ1bmN0aW9uIHZhbGlkYXRlU3RhdHVzKHN0YXR1cykge1xuICAgIHJldHVybiBzdGF0dXMgPj0gMjAwICYmIHN0YXR1cyA8IDMwMDtcbiAgfVxufTtcblxuZGVmYXVsdHMuaGVhZGVycyA9IHtcbiAgY29tbW9uOiB7XG4gICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L3BsYWluLCAqLyonXG4gIH1cbn07XG5cbnV0aWxzLmZvckVhY2goWydkZWxldGUnLCAnZ2V0JywgJ2hlYWQnXSwgZnVuY3Rpb24gZm9yRWFjaE1ldGhvZE5vRGF0YShtZXRob2QpIHtcbiAgZGVmYXVsdHMuaGVhZGVyc1ttZXRob2RdID0ge307XG59KTtcblxudXRpbHMuZm9yRWFjaChbJ3Bvc3QnLCAncHV0JywgJ3BhdGNoJ10sIGZ1bmN0aW9uIGZvckVhY2hNZXRob2RXaXRoRGF0YShtZXRob2QpIHtcbiAgZGVmYXVsdHMuaGVhZGVyc1ttZXRob2RdID0gdXRpbHMubWVyZ2UoREVGQVVMVF9DT05URU5UX1RZUEUpO1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmYXVsdHM7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcblxuZnVuY3Rpb24gSW50ZXJjZXB0b3JNYW5hZ2VyKCkge1xuICB0aGlzLmhhbmRsZXJzID0gW107XG59XG5cbi8qKlxuICogQWRkIGEgbmV3IGludGVyY2VwdG9yIHRvIHRoZSBzdGFja1xuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bGZpbGxlZCBUaGUgZnVuY3Rpb24gdG8gaGFuZGxlIGB0aGVuYCBmb3IgYSBgUHJvbWlzZWBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHJlamVjdGVkIFRoZSBmdW5jdGlvbiB0byBoYW5kbGUgYHJlamVjdGAgZm9yIGEgYFByb21pc2VgXG4gKlxuICogQHJldHVybiB7TnVtYmVyfSBBbiBJRCB1c2VkIHRvIHJlbW92ZSBpbnRlcmNlcHRvciBsYXRlclxuICovXG5JbnRlcmNlcHRvck1hbmFnZXIucHJvdG90eXBlLnVzZSA9IGZ1bmN0aW9uIHVzZShmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gIHRoaXMuaGFuZGxlcnMucHVzaCh7XG4gICAgZnVsZmlsbGVkOiBmdWxmaWxsZWQsXG4gICAgcmVqZWN0ZWQ6IHJlamVjdGVkXG4gIH0pO1xuICByZXR1cm4gdGhpcy5oYW5kbGVycy5sZW5ndGggLSAxO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgYW4gaW50ZXJjZXB0b3IgZnJvbSB0aGUgc3RhY2tcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gaWQgVGhlIElEIHRoYXQgd2FzIHJldHVybmVkIGJ5IGB1c2VgXG4gKi9cbkludGVyY2VwdG9yTWFuYWdlci5wcm90b3R5cGUuZWplY3QgPSBmdW5jdGlvbiBlamVjdChpZCkge1xuICBpZiAodGhpcy5oYW5kbGVyc1tpZF0pIHtcbiAgICB0aGlzLmhhbmRsZXJzW2lkXSA9IG51bGw7XG4gIH1cbn07XG5cbi8qKlxuICogSXRlcmF0ZSBvdmVyIGFsbCB0aGUgcmVnaXN0ZXJlZCBpbnRlcmNlcHRvcnNcbiAqXG4gKiBUaGlzIG1ldGhvZCBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIGZvciBza2lwcGluZyBvdmVyIGFueVxuICogaW50ZXJjZXB0b3JzIHRoYXQgbWF5IGhhdmUgYmVjb21lIGBudWxsYCBjYWxsaW5nIGBlamVjdGAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggaW50ZXJjZXB0b3JcbiAqL1xuSW50ZXJjZXB0b3JNYW5hZ2VyLnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24gZm9yRWFjaChmbikge1xuICB1dGlscy5mb3JFYWNoKHRoaXMuaGFuZGxlcnMsIGZ1bmN0aW9uIGZvckVhY2hIYW5kbGVyKGgpIHtcbiAgICBpZiAoaCAhPT0gbnVsbCkge1xuICAgICAgZm4oaCk7XG4gICAgfVxuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gSW50ZXJjZXB0b3JNYW5hZ2VyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG5cbi8qKlxuICogVHJhbnNmb3JtIHRoZSBkYXRhIGZvciBhIHJlcXVlc3Qgb3IgYSByZXNwb25zZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fFN0cmluZ30gZGF0YSBUaGUgZGF0YSB0byBiZSB0cmFuc2Zvcm1lZFxuICogQHBhcmFtIHtBcnJheX0gaGVhZGVycyBUaGUgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3Qgb3IgcmVzcG9uc2VcbiAqIEBwYXJhbSB7QXJyYXl8RnVuY3Rpb259IGZucyBBIHNpbmdsZSBmdW5jdGlvbiBvciBBcnJheSBvZiBmdW5jdGlvbnNcbiAqIEByZXR1cm5zIHsqfSBUaGUgcmVzdWx0aW5nIHRyYW5zZm9ybWVkIGRhdGFcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB0cmFuc2Zvcm1EYXRhKGRhdGEsIGhlYWRlcnMsIGZucykge1xuICAvKmVzbGludCBuby1wYXJhbS1yZWFzc2lnbjowKi9cbiAgdXRpbHMuZm9yRWFjaChmbnMsIGZ1bmN0aW9uIHRyYW5zZm9ybShmbikge1xuICAgIGRhdGEgPSBmbihkYXRhLCBoZWFkZXJzKTtcbiAgfSk7XG5cbiAgcmV0dXJuIGRhdGE7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzQ2FuY2VsKHZhbHVlKSB7XG4gIHJldHVybiAhISh2YWx1ZSAmJiB2YWx1ZS5fX0NBTkNFTF9fKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgVVJMIGlzIGFic29sdXRlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHVybCBUaGUgVVJMIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBzcGVjaWZpZWQgVVJMIGlzIGFic29sdXRlLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0Fic29sdXRlVVJMKHVybCkge1xuICAvLyBBIFVSTCBpcyBjb25zaWRlcmVkIGFic29sdXRlIGlmIGl0IGJlZ2lucyB3aXRoIFwiPHNjaGVtZT46Ly9cIiBvciBcIi8vXCIgKHByb3RvY29sLXJlbGF0aXZlIFVSTCkuXG4gIC8vIFJGQyAzOTg2IGRlZmluZXMgc2NoZW1lIG5hbWUgYXMgYSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGJlZ2lubmluZyB3aXRoIGEgbGV0dGVyIGFuZCBmb2xsb3dlZFxuICAvLyBieSBhbnkgY29tYmluYXRpb24gb2YgbGV0dGVycywgZGlnaXRzLCBwbHVzLCBwZXJpb2QsIG9yIGh5cGhlbi5cbiAgcmV0dXJuIC9eKFthLXpdW2EtelxcZFxcK1xcLVxcLl0qOik/XFwvXFwvL2kudGVzdCh1cmwpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IFVSTCBieSBjb21iaW5pbmcgdGhlIHNwZWNpZmllZCBVUkxzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2VVUkwgVGhlIGJhc2UgVVJMXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVsYXRpdmVVUkwgVGhlIHJlbGF0aXZlIFVSTFxuICogQHJldHVybnMge3N0cmluZ30gVGhlIGNvbWJpbmVkIFVSTFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNvbWJpbmVVUkxzKGJhc2VVUkwsIHJlbGF0aXZlVVJMKSB7XG4gIHJldHVybiByZWxhdGl2ZVVSTFxuICAgID8gYmFzZVVSTC5yZXBsYWNlKC9cXC8rJC8sICcnKSArICcvJyArIHJlbGF0aXZlVVJMLnJlcGxhY2UoL15cXC8rLywgJycpXG4gICAgOiBiYXNlVVJMO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi8uLi91dGlscycpO1xudmFyIHRyYW5zZm9ybURhdGEgPSByZXF1aXJlKCcuL3RyYW5zZm9ybURhdGEnKTtcbnZhciBpc0NhbmNlbCA9IHJlcXVpcmUoJy4uL2NhbmNlbC9pc0NhbmNlbCcpO1xudmFyIGRlZmF1bHRzID0gcmVxdWlyZSgnLi4vZGVmYXVsdHMnKTtcbnZhciBpc0Fic29sdXRlVVJMID0gcmVxdWlyZSgnLi8uLi9oZWxwZXJzL2lzQWJzb2x1dGVVUkwnKTtcbnZhciBjb21iaW5lVVJMcyA9IHJlcXVpcmUoJy4vLi4vaGVscGVycy9jb21iaW5lVVJMcycpO1xuXG4vKipcbiAqIFRocm93cyBhIGBDYW5jZWxgIGlmIGNhbmNlbGxhdGlvbiBoYXMgYmVlbiByZXF1ZXN0ZWQuXG4gKi9cbmZ1bmN0aW9uIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKSB7XG4gIGlmIChjb25maWcuY2FuY2VsVG9rZW4pIHtcbiAgICBjb25maWcuY2FuY2VsVG9rZW4udGhyb3dJZlJlcXVlc3RlZCgpO1xuICB9XG59XG5cbi8qKlxuICogRGlzcGF0Y2ggYSByZXF1ZXN0IHRvIHRoZSBzZXJ2ZXIgdXNpbmcgdGhlIGNvbmZpZ3VyZWQgYWRhcHRlci5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gY29uZmlnIFRoZSBjb25maWcgdGhhdCBpcyB0byBiZSB1c2VkIGZvciB0aGUgcmVxdWVzdFxuICogQHJldHVybnMge1Byb21pc2V9IFRoZSBQcm9taXNlIHRvIGJlIGZ1bGZpbGxlZFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGRpc3BhdGNoUmVxdWVzdChjb25maWcpIHtcbiAgdGhyb3dJZkNhbmNlbGxhdGlvblJlcXVlc3RlZChjb25maWcpO1xuXG4gIC8vIFN1cHBvcnQgYmFzZVVSTCBjb25maWdcbiAgaWYgKGNvbmZpZy5iYXNlVVJMICYmICFpc0Fic29sdXRlVVJMKGNvbmZpZy51cmwpKSB7XG4gICAgY29uZmlnLnVybCA9IGNvbWJpbmVVUkxzKGNvbmZpZy5iYXNlVVJMLCBjb25maWcudXJsKTtcbiAgfVxuXG4gIC8vIEVuc3VyZSBoZWFkZXJzIGV4aXN0XG4gIGNvbmZpZy5oZWFkZXJzID0gY29uZmlnLmhlYWRlcnMgfHwge307XG5cbiAgLy8gVHJhbnNmb3JtIHJlcXVlc3QgZGF0YVxuICBjb25maWcuZGF0YSA9IHRyYW5zZm9ybURhdGEoXG4gICAgY29uZmlnLmRhdGEsXG4gICAgY29uZmlnLmhlYWRlcnMsXG4gICAgY29uZmlnLnRyYW5zZm9ybVJlcXVlc3RcbiAgKTtcblxuICAvLyBGbGF0dGVuIGhlYWRlcnNcbiAgY29uZmlnLmhlYWRlcnMgPSB1dGlscy5tZXJnZShcbiAgICBjb25maWcuaGVhZGVycy5jb21tb24gfHwge30sXG4gICAgY29uZmlnLmhlYWRlcnNbY29uZmlnLm1ldGhvZF0gfHwge30sXG4gICAgY29uZmlnLmhlYWRlcnMgfHwge31cbiAgKTtcblxuICB1dGlscy5mb3JFYWNoKFxuICAgIFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ3Bvc3QnLCAncHV0JywgJ3BhdGNoJywgJ2NvbW1vbiddLFxuICAgIGZ1bmN0aW9uIGNsZWFuSGVhZGVyQ29uZmlnKG1ldGhvZCkge1xuICAgICAgZGVsZXRlIGNvbmZpZy5oZWFkZXJzW21ldGhvZF07XG4gICAgfVxuICApO1xuXG4gIHZhciBhZGFwdGVyID0gY29uZmlnLmFkYXB0ZXIgfHwgZGVmYXVsdHMuYWRhcHRlcjtcblxuICByZXR1cm4gYWRhcHRlcihjb25maWcpLnRoZW4oZnVuY3Rpb24gb25BZGFwdGVyUmVzb2x1dGlvbihyZXNwb25zZSkge1xuICAgIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKTtcblxuICAgIC8vIFRyYW5zZm9ybSByZXNwb25zZSBkYXRhXG4gICAgcmVzcG9uc2UuZGF0YSA9IHRyYW5zZm9ybURhdGEoXG4gICAgICByZXNwb25zZS5kYXRhLFxuICAgICAgcmVzcG9uc2UuaGVhZGVycyxcbiAgICAgIGNvbmZpZy50cmFuc2Zvcm1SZXNwb25zZVxuICAgICk7XG5cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH0sIGZ1bmN0aW9uIG9uQWRhcHRlclJlamVjdGlvbihyZWFzb24pIHtcbiAgICBpZiAoIWlzQ2FuY2VsKHJlYXNvbikpIHtcbiAgICAgIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKTtcblxuICAgICAgLy8gVHJhbnNmb3JtIHJlc3BvbnNlIGRhdGFcbiAgICAgIGlmIChyZWFzb24gJiYgcmVhc29uLnJlc3BvbnNlKSB7XG4gICAgICAgIHJlYXNvbi5yZXNwb25zZS5kYXRhID0gdHJhbnNmb3JtRGF0YShcbiAgICAgICAgICByZWFzb24ucmVzcG9uc2UuZGF0YSxcbiAgICAgICAgICByZWFzb24ucmVzcG9uc2UuaGVhZGVycyxcbiAgICAgICAgICBjb25maWcudHJhbnNmb3JtUmVzcG9uc2VcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QocmVhc29uKTtcbiAgfSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuLy4uL2RlZmF1bHRzJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG52YXIgSW50ZXJjZXB0b3JNYW5hZ2VyID0gcmVxdWlyZSgnLi9JbnRlcmNlcHRvck1hbmFnZXInKTtcbnZhciBkaXNwYXRjaFJlcXVlc3QgPSByZXF1aXJlKCcuL2Rpc3BhdGNoUmVxdWVzdCcpO1xuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBBeGlvc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBpbnN0YW5jZUNvbmZpZyBUaGUgZGVmYXVsdCBjb25maWcgZm9yIHRoZSBpbnN0YW5jZVxuICovXG5mdW5jdGlvbiBBeGlvcyhpbnN0YW5jZUNvbmZpZykge1xuICB0aGlzLmRlZmF1bHRzID0gaW5zdGFuY2VDb25maWc7XG4gIHRoaXMuaW50ZXJjZXB0b3JzID0ge1xuICAgIHJlcXVlc3Q6IG5ldyBJbnRlcmNlcHRvck1hbmFnZXIoKSxcbiAgICByZXNwb25zZTogbmV3IEludGVyY2VwdG9yTWFuYWdlcigpXG4gIH07XG59XG5cbi8qKlxuICogRGlzcGF0Y2ggYSByZXF1ZXN0XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyBUaGUgY29uZmlnIHNwZWNpZmljIGZvciB0aGlzIHJlcXVlc3QgKG1lcmdlZCB3aXRoIHRoaXMuZGVmYXVsdHMpXG4gKi9cbkF4aW9zLnByb3RvdHlwZS5yZXF1ZXN0ID0gZnVuY3Rpb24gcmVxdWVzdChjb25maWcpIHtcbiAgLyplc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246MCovXG4gIC8vIEFsbG93IGZvciBheGlvcygnZXhhbXBsZS91cmwnWywgY29uZmlnXSkgYSBsYSBmZXRjaCBBUElcbiAgaWYgKHR5cGVvZiBjb25maWcgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uZmlnID0gdXRpbHMubWVyZ2Uoe1xuICAgICAgdXJsOiBhcmd1bWVudHNbMF1cbiAgICB9LCBhcmd1bWVudHNbMV0pO1xuICB9XG5cbiAgY29uZmlnID0gdXRpbHMubWVyZ2UoZGVmYXVsdHMsIHRoaXMuZGVmYXVsdHMsIHsgbWV0aG9kOiAnZ2V0JyB9LCBjb25maWcpO1xuICBjb25maWcubWV0aG9kID0gY29uZmlnLm1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuXG4gIC8vIEhvb2sgdXAgaW50ZXJjZXB0b3JzIG1pZGRsZXdhcmVcbiAgdmFyIGNoYWluID0gW2Rpc3BhdGNoUmVxdWVzdCwgdW5kZWZpbmVkXTtcbiAgdmFyIHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoY29uZmlnKTtcblxuICB0aGlzLmludGVyY2VwdG9ycy5yZXF1ZXN0LmZvckVhY2goZnVuY3Rpb24gdW5zaGlmdFJlcXVlc3RJbnRlcmNlcHRvcnMoaW50ZXJjZXB0b3IpIHtcbiAgICBjaGFpbi51bnNoaWZ0KGludGVyY2VwdG9yLmZ1bGZpbGxlZCwgaW50ZXJjZXB0b3IucmVqZWN0ZWQpO1xuICB9KTtcblxuICB0aGlzLmludGVyY2VwdG9ycy5yZXNwb25zZS5mb3JFYWNoKGZ1bmN0aW9uIHB1c2hSZXNwb25zZUludGVyY2VwdG9ycyhpbnRlcmNlcHRvcikge1xuICAgIGNoYWluLnB1c2goaW50ZXJjZXB0b3IuZnVsZmlsbGVkLCBpbnRlcmNlcHRvci5yZWplY3RlZCk7XG4gIH0pO1xuXG4gIHdoaWxlIChjaGFpbi5sZW5ndGgpIHtcbiAgICBwcm9taXNlID0gcHJvbWlzZS50aGVuKGNoYWluLnNoaWZ0KCksIGNoYWluLnNoaWZ0KCkpO1xuICB9XG5cbiAgcmV0dXJuIHByb21pc2U7XG59O1xuXG4vLyBQcm92aWRlIGFsaWFzZXMgZm9yIHN1cHBvcnRlZCByZXF1ZXN0IG1ldGhvZHNcbnV0aWxzLmZvckVhY2goWydkZWxldGUnLCAnZ2V0JywgJ2hlYWQnLCAnb3B0aW9ucyddLCBmdW5jdGlvbiBmb3JFYWNoTWV0aG9kTm9EYXRhKG1ldGhvZCkge1xuICAvKmVzbGludCBmdW5jLW5hbWVzOjAqL1xuICBBeGlvcy5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKHVybCwgY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdCh1dGlscy5tZXJnZShjb25maWcgfHwge30sIHtcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgdXJsOiB1cmxcbiAgICB9KSk7XG4gIH07XG59KTtcblxudXRpbHMuZm9yRWFjaChbJ3Bvc3QnLCAncHV0JywgJ3BhdGNoJ10sIGZ1bmN0aW9uIGZvckVhY2hNZXRob2RXaXRoRGF0YShtZXRob2QpIHtcbiAgLyplc2xpbnQgZnVuYy1uYW1lczowKi9cbiAgQXhpb3MucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbih1cmwsIGRhdGEsIGNvbmZpZykge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QodXRpbHMubWVyZ2UoY29uZmlnIHx8IHt9LCB7XG4gICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgIHVybDogdXJsLFxuICAgICAgZGF0YTogZGF0YVxuICAgIH0pKTtcbiAgfTtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEF4aW9zO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEEgYENhbmNlbGAgaXMgYW4gb2JqZWN0IHRoYXQgaXMgdGhyb3duIHdoZW4gYW4gb3BlcmF0aW9uIGlzIGNhbmNlbGVkLlxuICpcbiAqIEBjbGFzc1xuICogQHBhcmFtIHtzdHJpbmc9fSBtZXNzYWdlIFRoZSBtZXNzYWdlLlxuICovXG5mdW5jdGlvbiBDYW5jZWwobWVzc2FnZSkge1xuICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xufVxuXG5DYW5jZWwucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gIHJldHVybiAnQ2FuY2VsJyArICh0aGlzLm1lc3NhZ2UgPyAnOiAnICsgdGhpcy5tZXNzYWdlIDogJycpO1xufTtcblxuQ2FuY2VsLnByb3RvdHlwZS5fX0NBTkNFTF9fID0gdHJ1ZTtcblxubW9kdWxlLmV4cG9ydHMgPSBDYW5jZWw7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDYW5jZWwgPSByZXF1aXJlKCcuL0NhbmNlbCcpO1xuXG4vKipcbiAqIEEgYENhbmNlbFRva2VuYCBpcyBhbiBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byByZXF1ZXN0IGNhbmNlbGxhdGlvbiBvZiBhbiBvcGVyYXRpb24uXG4gKlxuICogQGNsYXNzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBleGVjdXRvciBUaGUgZXhlY3V0b3IgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIENhbmNlbFRva2VuKGV4ZWN1dG9yKSB7XG4gIGlmICh0eXBlb2YgZXhlY3V0b3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdleGVjdXRvciBtdXN0IGJlIGEgZnVuY3Rpb24uJyk7XG4gIH1cblxuICB2YXIgcmVzb2x2ZVByb21pc2U7XG4gIHRoaXMucHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIHByb21pc2VFeGVjdXRvcihyZXNvbHZlKSB7XG4gICAgcmVzb2x2ZVByb21pc2UgPSByZXNvbHZlO1xuICB9KTtcblxuICB2YXIgdG9rZW4gPSB0aGlzO1xuICBleGVjdXRvcihmdW5jdGlvbiBjYW5jZWwobWVzc2FnZSkge1xuICAgIGlmICh0b2tlbi5yZWFzb24pIHtcbiAgICAgIC8vIENhbmNlbGxhdGlvbiBoYXMgYWxyZWFkeSBiZWVuIHJlcXVlc3RlZFxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRva2VuLnJlYXNvbiA9IG5ldyBDYW5jZWwobWVzc2FnZSk7XG4gICAgcmVzb2x2ZVByb21pc2UodG9rZW4ucmVhc29uKTtcbiAgfSk7XG59XG5cbi8qKlxuICogVGhyb3dzIGEgYENhbmNlbGAgaWYgY2FuY2VsbGF0aW9uIGhhcyBiZWVuIHJlcXVlc3RlZC5cbiAqL1xuQ2FuY2VsVG9rZW4ucHJvdG90eXBlLnRocm93SWZSZXF1ZXN0ZWQgPSBmdW5jdGlvbiB0aHJvd0lmUmVxdWVzdGVkKCkge1xuICBpZiAodGhpcy5yZWFzb24pIHtcbiAgICB0aHJvdyB0aGlzLnJlYXNvbjtcbiAgfVxufTtcblxuLyoqXG4gKiBSZXR1cm5zIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGEgbmV3IGBDYW5jZWxUb2tlbmAgYW5kIGEgZnVuY3Rpb24gdGhhdCwgd2hlbiBjYWxsZWQsXG4gKiBjYW5jZWxzIHRoZSBgQ2FuY2VsVG9rZW5gLlxuICovXG5DYW5jZWxUb2tlbi5zb3VyY2UgPSBmdW5jdGlvbiBzb3VyY2UoKSB7XG4gIHZhciBjYW5jZWw7XG4gIHZhciB0b2tlbiA9IG5ldyBDYW5jZWxUb2tlbihmdW5jdGlvbiBleGVjdXRvcihjKSB7XG4gICAgY2FuY2VsID0gYztcbiAgfSk7XG4gIHJldHVybiB7XG4gICAgdG9rZW46IHRva2VuLFxuICAgIGNhbmNlbDogY2FuY2VsXG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IENhbmNlbFRva2VuO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFN5bnRhY3RpYyBzdWdhciBmb3IgaW52b2tpbmcgYSBmdW5jdGlvbiBhbmQgZXhwYW5kaW5nIGFuIGFycmF5IGZvciBhcmd1bWVudHMuXG4gKlxuICogQ29tbW9uIHVzZSBjYXNlIHdvdWxkIGJlIHRvIHVzZSBgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5YC5cbiAqXG4gKiAgYGBganNcbiAqICBmdW5jdGlvbiBmKHgsIHksIHopIHt9XG4gKiAgdmFyIGFyZ3MgPSBbMSwgMiwgM107XG4gKiAgZi5hcHBseShudWxsLCBhcmdzKTtcbiAqICBgYGBcbiAqXG4gKiBXaXRoIGBzcHJlYWRgIHRoaXMgZXhhbXBsZSBjYW4gYmUgcmUtd3JpdHRlbi5cbiAqXG4gKiAgYGBganNcbiAqICBzcHJlYWQoZnVuY3Rpb24oeCwgeSwgeikge30pKFsxLCAyLCAzXSk7XG4gKiAgYGBgXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm5zIHtGdW5jdGlvbn1cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzcHJlYWQoY2FsbGJhY2spIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHdyYXAoYXJyKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KG51bGwsIGFycik7XG4gIH07XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgYmluZCA9IHJlcXVpcmUoJy4vaGVscGVycy9iaW5kJyk7XG52YXIgQXhpb3MgPSByZXF1aXJlKCcuL2NvcmUvQXhpb3MnKTtcbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4vZGVmYXVsdHMnKTtcblxuLyoqXG4gKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgQXhpb3NcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZGVmYXVsdENvbmZpZyBUaGUgZGVmYXVsdCBjb25maWcgZm9yIHRoZSBpbnN0YW5jZVxuICogQHJldHVybiB7QXhpb3N9IEEgbmV3IGluc3RhbmNlIG9mIEF4aW9zXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUluc3RhbmNlKGRlZmF1bHRDb25maWcpIHtcbiAgdmFyIGNvbnRleHQgPSBuZXcgQXhpb3MoZGVmYXVsdENvbmZpZyk7XG4gIHZhciBpbnN0YW5jZSA9IGJpbmQoQXhpb3MucHJvdG90eXBlLnJlcXVlc3QsIGNvbnRleHQpO1xuXG4gIC8vIENvcHkgYXhpb3MucHJvdG90eXBlIHRvIGluc3RhbmNlXG4gIHV0aWxzLmV4dGVuZChpbnN0YW5jZSwgQXhpb3MucHJvdG90eXBlLCBjb250ZXh0KTtcblxuICAvLyBDb3B5IGNvbnRleHQgdG8gaW5zdGFuY2VcbiAgdXRpbHMuZXh0ZW5kKGluc3RhbmNlLCBjb250ZXh0KTtcblxuICByZXR1cm4gaW5zdGFuY2U7XG59XG5cbi8vIENyZWF0ZSB0aGUgZGVmYXVsdCBpbnN0YW5jZSB0byBiZSBleHBvcnRlZFxudmFyIGF4aW9zID0gY3JlYXRlSW5zdGFuY2UoZGVmYXVsdHMpO1xuXG4vLyBFeHBvc2UgQXhpb3MgY2xhc3MgdG8gYWxsb3cgY2xhc3MgaW5oZXJpdGFuY2VcbmF4aW9zLkF4aW9zID0gQXhpb3M7XG5cbi8vIEZhY3RvcnkgZm9yIGNyZWF0aW5nIG5ldyBpbnN0YW5jZXNcbmF4aW9zLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShpbnN0YW5jZUNvbmZpZykge1xuICByZXR1cm4gY3JlYXRlSW5zdGFuY2UodXRpbHMubWVyZ2UoZGVmYXVsdHMsIGluc3RhbmNlQ29uZmlnKSk7XG59O1xuXG4vLyBFeHBvc2UgQ2FuY2VsICYgQ2FuY2VsVG9rZW5cbmF4aW9zLkNhbmNlbCA9IHJlcXVpcmUoJy4vY2FuY2VsL0NhbmNlbCcpO1xuYXhpb3MuQ2FuY2VsVG9rZW4gPSByZXF1aXJlKCcuL2NhbmNlbC9DYW5jZWxUb2tlbicpO1xuYXhpb3MuaXNDYW5jZWwgPSByZXF1aXJlKCcuL2NhbmNlbC9pc0NhbmNlbCcpO1xuXG4vLyBFeHBvc2UgYWxsL3NwcmVhZFxuYXhpb3MuYWxsID0gZnVuY3Rpb24gYWxsKHByb21pc2VzKSB7XG4gIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG59O1xuYXhpb3Muc3ByZWFkID0gcmVxdWlyZSgnLi9oZWxwZXJzL3NwcmVhZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGF4aW9zO1xuXG4vLyBBbGxvdyB1c2Ugb2YgZGVmYXVsdCBpbXBvcnQgc3ludGF4IGluIFR5cGVTY3JpcHRcbm1vZHVsZS5leHBvcnRzLmRlZmF1bHQgPSBheGlvcztcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvYXhpb3MnKTsiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIGF4aW9zID0gcmVxdWlyZSgnYXhpb3MnKTtcbnZhciBsb2dnZXJzID0gW107XG5cbmZ1bmN0aW9uIGNyZWF0ZSh1cmwsIHRhZ3MsIGxldmVsKSB7XG4gIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiB7fTtcblxuICByZXR1cm4gbmV3IExvZ3N0YXNoKHVybCwgdGFncywgbGV2ZWwsIG9wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBMb2dzdGFzaCh1cmwpIHtcbiAgdmFyIHRhZ3MgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IFtdO1xuICB2YXIgbGV2ZWwgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IFwiaW5mb1wiO1xuICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDoge307XG5cbiAgaWYgKCF1cmwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBVUkxcIik7XG4gIH1cblxuICB0aGlzLnVybCA9IHVybDtcbiAgdGhpcy50YWdzID0gdGFncztcbiAgdGhpcy5sZXZlbCA9IGxldmVsO1xuICB0aGlzLnNlbmREZWxheSA9IG9wdGlvbnMuc2VuZERlbGF5IHx8IDEwMDtcbiAgdGhpcy5yZXRyeURlbGF5ID0gb3B0aW9ucy5yZXRyeURlbGF5IHx8IDIwMDA7XG4gIHRoaXMubXV0ZUNvbnNvbGUgPSBvcHRpb25zLm11dGVDb25zb2xlID09PSB0cnVlIHx8IGZhbHNlO1xuICB0aGlzLmlzU2VuZGluZyA9IGZhbHNlO1xuICB0aGlzLnF1ZXVlID0gW107XG59XG5cbkxvZ3N0YXNoLnByb3RvdHlwZS5fdHJ5U2VuZEV2ZW50ID0gZnVuY3Rpb24gX3RyeVNlbmRFdmVudCgpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICBpZiAoIXRoaXMucXVldWUubGVuZ3RoIHx8IHRoaXMuaXNTZW5kaW5nKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5pc1NlbmRpbmcgPSB0cnVlO1xuICB2YXIgZXZlbnQgPSB0aGlzLnF1ZXVlLnNoaWZ0KCk7XG5cbiAgdmFyIHJlcXVlc3QgPSB7XG4gICAgdXJsOiB0aGlzLnVybCxcbiAgICBtZXRob2Q6ICdwb3N0JyxcbiAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICBkYXRhOiBldmVudFxuICB9O1xuXG4gIC8vIEhUVFAgcmVxdWVzdFxuICByZXR1cm4gYXhpb3MocmVxdWVzdCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgX3RoaXMuaXNTZW5kaW5nID0gZmFsc2U7XG4gICAgX3RoaXMuX3RyeVNlbmRFdmVudCgpO1xuICB9KS5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG4gICAgY29uc29sZS5lcnJvcihlcnIpO1xuXG4gICAgLy8gSWYgd2UgY291bGQgbm90IHNlbmQgdGhlIGV2ZW50LFxuICAgIC8vIHB1dCBpdCBiYWNrIGludG8gcXVldWVcbiAgICBfdGhpcy5xdWV1ZS51bnNoaWZ0KGV2ZW50KTtcblxuICAgIF90aGlzLmlzU2VuZGluZyA9IGZhbHNlO1xuICAgIHNldFRpbWVvdXQoX3RoaXMuX3RyeVNlbmRFdmVudC5iaW5kKF90aGlzKSwgX3RoaXMucmV0cnlEZWxheSk7XG4gIH0pO1xufTtcblxuTG9nc3Rhc2gucHJvdG90eXBlLmxvZyA9IGZ1bmN0aW9uIGxvZyhsZXZlbCwgbWVzc2FnZSwgZmllbGRzKSB7XG4gIHZhciBldmVudCA9IHsgbGV2ZWw6IGxldmVsLCBmaWVsZHM6IGZpZWxkcywgbWVzc2FnZTogbWVzc2FnZSB9O1xuXG4gIGV2ZW50WydAdGltZXN0YW1wJ10gPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gIGV2ZW50WydAdGFncyddID0gdGhpcy50YWdzO1xuXG4gIC8vIE5hdmlnYXRvciBtZXRhZGF0YVxuICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBldmVudC5uYXZpZ2F0b3IgPSB7XG4gICAgICBjb29raWVFbmFibGVkOiBuYXZpZ2F0b3IuY29va2llRW5hYmxlZCxcbiAgICAgIGdlb0xvY2F0aW9uOiBuYXZpZ2F0b3IuZ2VvTG9jYXRpb24sXG4gICAgICBsYW5ndWFnZTogbmF2aWdhdG9yLmxhbmd1YWdlLFxuICAgICAgbGFuZ3VhZ2VzOiBuYXZpZ2F0b3IubGFuZ3VhZ2VzLFxuICAgICAgb25saW5lOiBuYXZpZ2F0b3Iub25saW5lLFxuICAgICAgdXNlckFnZW50OiBuYXZpZ2F0b3IudXNlckFnZW50LFxuICAgICAgcGxhdGZvcm06IG5hdmlnYXRvci5wbGF0Zm9ybSxcbiAgICAgIHZlbmRvcjogbmF2aWdhdG9yLnZlbmRvclxuICAgIH07XG4gIH1cblxuICAvLyBMb2NhdGlvbiBtZXRhZGF0YVxuICBpZiAodHlwZW9mIGxvY2F0aW9uICE9PSAndW5kZWZpbmVkJykge1xuICAgIGV2ZW50LmxvY2F0aW9uID0ge1xuICAgICAgc2VhcmNoOiBsb2NhdGlvbi5zZWFyY2gsXG4gICAgICBwYXRobmFtZTogbG9jYXRpb24ucGF0aG5hbWUsXG4gICAgICBob3N0bmFtZTogbG9jYXRpb24uaG9zdG5hbWUsXG4gICAgICBwcm90b2NvbDogbG9jYXRpb24ucHJvdG9jb2wsXG4gICAgICBwb3J0OiBsb2NhdGlvbi5wb3J0LFxuICAgICAgaGFzaDogbG9jYXRpb24uaGFzaCxcbiAgICAgIGhyZWY6IGxvY2F0aW9uLmhyZWZcbiAgICB9O1xuICB9XG5cbiAgdGhpcy5xdWV1ZS5wdXNoKGV2ZW50KTtcbiAgdGhpcy5fdHJ5U2VuZEV2ZW50KCk7XG5cbiAgaWYgKHRoaXMubXV0ZUNvbnNvbGUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZmllbGRzU3RyID0gZmllbGRzID8gXCIgLSBcIiArIEpTT04uc3RyaW5naWZ5KGZpZWxkcykgOiAnJztcblxuICBzd2l0Y2ggKGxldmVsKSB7XG4gICAgY2FzZSBcImVycm9yXCI6XG4gICAgICBjb25zb2xlLmVycm9yKFwiXCIgKyBtZXNzYWdlICsgZmllbGRzU3RyKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJ3YXJuXCI6XG4gICAgICBjb25zb2xlLndhcm4oXCJcIiArIG1lc3NhZ2UgKyBmaWVsZHNTdHIpO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGNvbnNvbGUuaW5mbyhcIlwiICsgbWVzc2FnZSArIGZpZWxkc1N0cik7XG4gIH1cbn07XG5cbkxvZ3N0YXNoLnByb3RvdHlwZS5kZWJ1ZyA9IGZ1bmN0aW9uIGRlYnVnKG1lc3NhZ2UsIGZpZWxkcykge1xuICB0aGlzLmxvZygnZGVidWcnLCBtZXNzYWdlLCBmaWVsZHMpO1xufTtcblxuTG9nc3Rhc2gucHJvdG90eXBlLmluZm8gPSBmdW5jdGlvbiBpbmZvKG1lc3NhZ2UsIGZpZWxkcykge1xuICB0aGlzLmxvZygnaW5mbycsIG1lc3NhZ2UsIGZpZWxkcyk7XG59O1xuXG5Mb2dzdGFzaC5wcm90b3R5cGUud2FybiA9IGZ1bmN0aW9uIHdhcm4obWVzc2FnZSwgZmllbGRzKSB7XG4gIHRoaXMubG9nKCd3YXJuJywgbWVzc2FnZSwgZmllbGRzKTtcbn07XG5cbkxvZ3N0YXNoLnByb3RvdHlwZS5lcnJvciA9IGZ1bmN0aW9uIGVycm9yKGVyciwgZmllbGRzKSB7XG4gIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgIHRoaXMubG9nKCdlcnJvcicsIGVyci5tZXNzYWdlLCBPYmplY3QuYXNzaWduKHsgc3RhY2s6IGVyci5zdGFjayB9LCBmaWVsZHMpKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmxvZygnZXJyb3InLCBlcnIsIGZpZWxkcyk7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlOyIsImltcG9ydCBjcmVhdGUgZnJvbSAnQHd5c2NvdXQvbG9nc3Rhc2gnO1xuaW1wb3J0IHsgZ2V0Rmlyc3RMZXZlbERvbWFpbiB9IGZyb20gJy4uL3V0aWxpdGllcy91dGlscyc7XG5cbmNvbnN0IGZvcm1hdFVzZXJTZXR0aW5ncyA9ICh1c2VyU2V0dGluZ3MpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgICAuLi51c2VyU2V0dGluZ3MsXG4gICAgICAgIHVzZXJJZDogdXNlclNldHRpbmdzLnVzZXJJZCA/IHVzZXJTZXR0aW5ncy51c2VySWQudG9TdHJpbmcoKSA6ICcnLFxuICAgICAgICBzdWJncm91cElkOiB1c2VyU2V0dGluZ3Muc3ViZ3JvdXBJZCA/IHVzZXJTZXR0aW5ncy5zdWJncm91cElkLnRvU3RyaW5nKCkgOiAnJyxcbiAgICAgICAgZ3JvdXBJZDogdXNlclNldHRpbmdzLmdyb3VwSWQgPyB1c2VyU2V0dGluZ3MuZ3JvdXBJZC50b1N0cmluZygpIDogJycsXG4gICAgfTtcbn07XG5cbmNvbnN0IExvZ1N0YXNoID0gKG1vZGVsLCBsYWJlbCkgPT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaXJzdERvbWFpbkxldmVsID0gZ2V0Rmlyc3RMZXZlbERvbWFpbigpO1xuICAgICAgICAgICAgY29uc3QgdXJsID0gYGh0dHBzOi8vdmlkZW9tZXRyaWNzLnd5c2NvdXQke2ZpcnN0RG9tYWluTGV2ZWx9OjgwODBgO1xuICAgICAgICAgICAgLy8gb3B0aW9uYWxcbiAgICAgICAgICAgIGNvbnN0IHRhZ3MgPSBbJ3ZpZGVvJywgJ21ldHJpY3MnXTtcbiAgICAgICAgICAgIGNvbnN0IGxldmVsID0gJ2luZm8nO1xuICAgICAgICAgICAgbW9kZWwudXNlclNldHRpbmdzID0gZm9ybWF0VXNlclNldHRpbmdzKG1vZGVsLnVzZXJTZXR0aW5ncyk7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIG11dGVDb25zb2xlOiB0cnVlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIENyZWF0ZSBsb2dnZXIgaW5zdGFuY2VcbiAgICAgICAgICAgIGNvbnN0IGxvZ2dlciA9IGNyZWF0ZSh1cmwsIHRhZ3MsIGxldmVsLCBvcHRpb25zKTtcblxuICAgICAgICAgICAgbG9nZ2VyLmluZm8obGFiZWwsIG1vZGVsKTtcbiAgICAgICAgICAgIHJlc29sdmUobG9nZ2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgIH0pO1xufTtcblxuXG5leHBvcnQgZGVmYXVsdCBMb2dTdGFzaDtcbiIsImltcG9ydCBheGlvcyBmcm9tICdheGlvcyc7XG5pbXBvcnQgeyBBUElfU0VSVkVSIH0gZnJvbSAnLi4vY29uZmlnL2NvbmZpZy5qcyc7XG5cbmNvbnN0IFJlc3RBcGkgPSAobW9kZWwpID0+IHtcbiAgICByZXR1cm4gYXhpb3Moe1xuICAgICAgICBtZXRob2Q6IG1vZGVsLmlkID8gJ1BVVCcgOiAnUE9TVCcsXG4gICAgICAgIHVybDogbW9kZWwuaWRcbiAgICAgICAgICAgID8gQVBJX1NFUlZFUiArIGBtZXRyaWNzLyR7bW9kZWwuaWR9YFxuICAgICAgICAgICAgOiBBUElfU0VSVkVSICsgJ21ldHJpY3MnLFxuICAgICAgICBkYXRhOiBtb2RlbCxcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFJlc3RBcGk7XG4iLCJpbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHsgVFJBTlNNSVNTSU9OX1RZUEUgfSBmcm9tICcuLi9jb25maWcvY29uZmlnLmpzJztcbmltcG9ydCBMb2dTdGFzaCBmcm9tICcuLi90cmFuc21pdHRlci9Mb2dTdGFzaCc7XG5pbXBvcnQgUmVzdEFwaSBmcm9tICcuLi90cmFuc21pdHRlci9SZXN0QXBpJztcblxuZXhwb3J0IGNvbnN0IGdldElwQWRkcmVzcyA9ICgpID0+IHtcbiAgICByZXR1cm4gYXhpb3Moe1xuICAgICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgICB1cmw6ICdodHRwczovL29wc2FwaS53eXNjb3V0LmNvbS92MC4yL2dldF9teV9pcCcsXG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgQ2FsbGVyID0gKG1vZGVsLCBsYWJlbCwgdHJhbnNtaXNzaW9uID0gVFJBTlNNSVNTSU9OX1RZUEUuTE9HU1RBU0gpID0+IHtcbiAgICByZXR1cm4gdHJhbnNtaXNzaW9uID09PSBUUkFOU01JU1NJT05fVFlQRS5MT0dTVEFTSCA/IExvZ1N0YXNoKG1vZGVsLCBsYWJlbCkgOiBSZXN0QXBpKG1vZGVsLCBsYWJlbCk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0R2xvYmFsU3dpdGNoU3RhdHVzID0gKGFjY2Vzc1Rva2VuLCBhcGlIb3N0bmFtZSkgPT4ge1xuICAgIHJldHVybiBheGlvcyh7XG4gICAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICAgIHVybDogYXBpSG9zdG5hbWUgKyAnbWVkaWEvdmlkZW9tZXRyaWNzY29uZmlnLycsXG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgYWNjZXNzX3Rva2VuOiBhY2Nlc3NUb2tlbixcbiAgICAgICAgfSxcbiAgICB9KTtcbn07XG4iLCJpbXBvcnQgeyBnZXRHbG9iYWxTd2l0Y2hTdGF0dXMgfSBmcm9tICcuLi9jb3JlL0NhbGxlcic7XG5pbXBvcnQgeyBNQVhfU0VFS0lOR19WSURFT19UQUcsIFdZU0NPVVRfSE9TVE5BTUVTX1NVRkZJWCB9IGZyb20gJy4uL2NvbmZpZy9jb25maWcnO1xuXG5cbmV4cG9ydCBjb25zdCBmb3JtYXRCdWZmZXJlZFJhbmdlcyA9IHZpZGVvID0+IHtcbiAgICBsZXQgZm9ybWF0dGVkUmFuZ2VzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2aWRlby5idWZmZXJlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICBmb3JtYXR0ZWRSYW5nZXMucHVzaCh7XG4gICAgICAgICAgICBzdGFydDogdmlkZW8uYnVmZmVyZWQuc3RhcnQoaSksXG4gICAgICAgICAgICBlbmQ6IHZpZGVvLmJ1ZmZlcmVkLmVuZChpKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBmb3JtYXR0ZWRSYW5nZXM7XG59O1xuXG5leHBvcnQgY29uc3QgZm9ybWF0U2Vla2FibGVSYW5nZXMgPSB2aWRlbyA9PiB7XG4gICAgbGV0IGZvcm1hdHRlZFNlZWthYmxlUmFuZ2VzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2aWRlby5zZWVrYWJsZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBmb3JtYXR0ZWRTZWVrYWJsZVJhbmdlcy5wdXNoKHtcbiAgICAgICAgICAgIHN0YXJ0OiB2aWRlby5zZWVrYWJsZS5zdGFydChpKSxcbiAgICAgICAgICAgIGVuZDogdmlkZW8uc2Vla2FibGUuZW5kKGkpLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGZvcm1hdHRlZFNlZWthYmxlUmFuZ2VzO1xufTtcblxuZXhwb3J0IGNvbnN0IGZvcm1hdFBsYXllZFJhbmdlcyA9IHZpZGVvID0+IHtcbiAgICBsZXQgZm9ybWF0dGVkUGxheWVkUmFuZ2VzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2aWRlby5wbGF5ZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZm9ybWF0dGVkUGxheWVkUmFuZ2VzLnB1c2goe1xuICAgICAgICAgICAgc3RhcnQ6IHZpZGVvLnBsYXllZC5zdGFydChpKSxcbiAgICAgICAgICAgIGVuZDogdmlkZW8ucGxheWVkLmVuZChpKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBmb3JtYXR0ZWRQbGF5ZWRSYW5nZXM7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXJsUGFyYW1zID0gdXJsID0+IHtcbiAgICBsZXQgZmluYWxVcmwgPSB1cmw7XG4gICAgaWYgKCFmaW5hbFVybC5pbmNsdWRlcygnPycpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB1c2VySWQ6IDEyMzQ1NixcbiAgICAgICAgICAgIGdyb3VwSWQ6IDEyMyxcbiAgICAgICAgICAgIHN1Ymdyb3VwSWQ6IDEyMyxcbiAgICAgICAgICAgIHVzZXJOYW1lOiAnVGVzdGVyIFVzZXInLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZpbmFsVXJsID0gZmluYWxVcmwuc3BsaXQoJz8nKVsxXS5zcGxpdCgnJicpO1xuICAgIGZpbmFsVXJsID0gZmluYWxVcmwucmVkdWNlKChhY2MsIGN1cikgPT4ge1xuICAgICAgICBsZXQga2V5ID0gY3VyLnNwbGl0KCc9JylbMF07XG4gICAgICAgIGxldCB2YWwgPSBjdXIuc3BsaXQoJz0nKVsxXTtcbiAgICAgICAgYWNjW2tleV0gPSB2YWw7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pO1xuICAgIHJldHVybiBmaW5hbFVybDtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRVc2VyUGFyYW1zID0gKCkgPT4ge1xuICAgIGxldCByZXN1bHQgPSBudWxsO1xuICAgIGlmICh3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUuaW5jbHVkZXMoJy53eXNjb3V0LicpKSB7XG4gICAgICAgIHJlc3VsdCA9IGdldFVybFBhcmFtcyh3aW5kb3cubG9jYXRpb24uaHJlZik7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0ge1xuICAgICAgICAgICAgdXNlcklkOiAxMjM0NTYsXG4gICAgICAgICAgICBncm91cElkOiAxMjMsXG4gICAgICAgICAgICBzdWJncm91cElkOiAxMjMsXG4gICAgICAgICAgICB1c2VyTmFtZTogJ1Rlc3RlciBVc2VyJyxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbmV4cG9ydCBjb25zdCBjaGVja0lzRW5hYmxlZFN0YXR1cyA9IChhY2Nlc3NUb2tlbiwgYXBpSG9zdG5hbWUpID0+IHtcbiAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBnZXRHbG9iYWxTd2l0Y2hTdGF0dXMoYWNjZXNzVG9rZW4sIGFwaUhvc3RuYW1lKS50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5kYXRhLmlzRW5hYmxlZCkgcmV0dXJuIHJlamVjdChmYWxzZSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgfSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoZmFsc2UpKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcHJvbWlzZTtcbn07XG5cbmV4cG9ydCBjb25zdCBmaW5kSFRNTDVWaWRlbyA9ICh1c2VyU2V0dGluZ3MsIGFwaUhvc3RuYW1lKSA9PiB7XG4gICAgY29uc3QgcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY2hlY2tJc0VuYWJsZWRTdGF0dXModXNlclNldHRpbmdzLmFjY2Vzc1Rva2VuLCBhcGlIb3N0bmFtZSkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBsZXQgY291bnRlciA9IDA7XG4gICAgICAgICAgICBsZXQgc2Vla2luZyA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgdmlkZW8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCd2aWRlbycpO1xuICAgICAgICAgICAgICAgIGlmICh2aWRlbykge1xuICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHNlZWtpbmcpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSh2aWRlbyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb3VudGVyID49IE1BWF9TRUVLSU5HX1ZJREVPX1RBRykge1xuICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHNlZWtpbmcpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignSFRNTCB0YWcgdmlkZW8gbm90IGZvdW5kJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb3VudGVyKys7XG4gICAgICAgICAgICB9LCA1MDApO1xuICAgICAgICB9KS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignZmluZCBodG1sNSBWaWRlbyBjaGVja2luZyBwcm9ibGVtJykpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBwcm9taXNlO1xufTtcblxuXG5leHBvcnQgY29uc3QgZ2V0Rmlyc3RMZXZlbERvbWFpbiA9ICgpID0+IHtcbiAgICBpZiAodHlwZW9mIGxvY2F0aW9uICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAobG9jYXRpb24uaG9zdG5hbWUuaW5jbHVkZXMoV1lTQ09VVF9IT1NUTkFNRVNfU1VGRklYLkNOKSkge1xuICAgICAgICAgICAgcmV0dXJuICcuY24nO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICcuY29tJztcbn07XG4iLCJpbXBvcnQgeyBBTkFMWVRJQ1NfQVBQX1NPVVJDRSwgQU5BTFlUSUNTX0RFVEFJTEVEX1NPVVJDRSwgUExBWUVSX1RZUEUgfSBmcm9tICcuLi9jb25maWcvY29uZmlnJztcbmltcG9ydCB7IGdldFVybFBhcmFtcyB9IGZyb20gJy4uL3V0aWxpdGllcy91dGlscyc7XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVBbmFseXRpY3NPYmplY3QgPSAodmlkZW8sIGRldGFpbGVkQXBwU291cmNlKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYXBwU291cmNlOiBBTkFMWVRJQ1NfQVBQX1NPVVJDRSxcbiAgICAgICAgZGV0YWlsZWRBcHBTb3VyY2U6IGRldGFpbGVkQXBwU291cmNlLFxuICAgICAgICBhY3Rpb25WYWx1ZTogMSxcbiAgICAgICAgc2Vzc2lvbklkOiB2aWRlby5zZXNzaW9uSWQsXG4gICAgICAgIHBvc2l0aW9uOiBkZXRhaWxlZEFwcFNvdXJjZSA9PT0gQU5BTFlUSUNTX0RFVEFJTEVEX1NPVVJDRS5WSURFT19DT01QTEVURUQgPyB2aWRlby5kdXJhdGlvbiA6IHZpZGVvLmN1cnJlbnRUaW1lLCAvLyBzb21ldGltZXMgb24gdmlkZW8gZW5kLCBjdXJzb3IgcmV0dXJuIHRvIHBvc2l0aW9uIDBcbiAgICAgICAgdG90YWxMZW5ndGg6IHZpZGVvLmR1cmF0aW9uLFxuICAgICAgICBwbGF5ZXI6IHZpZGVvLnBsYXllclR5cGUgfHwgUExBWUVSX1RZUEUuQVBQUyxcbiAgICAgICAgaXNNdXRlZDogdmlkZW8ubXV0ZWQsXG4gICAgICAgIGZ1bGxTY3JlZW46IHZpZGVvLndlYmtpdERpc3BsYXlpbmdGdWxsc2NyZWVuLFxuICAgICAgICBpc1BsYXlsaXN0OiBfaXNQbGF5bGlzdCh2aWRlby5jdXJyZW50U3JjKSxcbiAgICB9O1xufTtcblxuXG5jb25zdCBfaXNQbGF5bGlzdCA9IChzcmMgPSAnc29tZXRleHQ/dmJlZ2luPTAnKSA9PiB7XG4gICAgY29uc3QgcGFyYW1zID0gZ2V0VXJsUGFyYW1zKHNyYyk7XG4gICAgcmV0dXJuIHBhcmFtcy52YmVnaW4gJiYgIU51bWJlci5pc05hTihwYXJhbXMudmJlZ2luKSAmJiBwYXJhbXMudmJlZ2luID4gMDtcbn07XG4iLCJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuXG5leHBvcnQgY29uc3QgY2FsY3VsYXRlQXZlcmFnZUJpdFJhdGUgPSBzbmFwc2hvdHMgPT4ge1xuICAgIHJldHVybiBfLm1lYW5CeShzbmFwc2hvdHMsIHAgPT4gcC5kZWNvZGVkQnl0ZXMpO1xufTtcblxuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZUF2ZXJhZ2VGcmFtZVJhdGUgPSBzbmFwc2hvdHMgPT4ge1xuICAgIHJldHVybiBfLm1lYW5CeShzbmFwc2hvdHMsIHAgPT4gcC5kZWNvZGVkRnJhbWVzKTtcbn07XG4iLCJpbXBvcnQgeyB0cmFjayB9IGZyb20gJy4uL2FuYWx5dGljcy9hbmFseXRpY3NNYW5hZ2VyJztcbmltcG9ydCB7IGNyZWF0ZUFuYWx5dGljc09iamVjdCB9IGZyb20gJy4uL2FuYWx5dGljcy91dGlscyc7XG5pbXBvcnQgeyBBTkFMWVRJQ1NfRVZFTlRTLCBORVRXT1JLX1NUQVRFLCBBTkFMWVRJQ1NfREVUQUlMRURfU09VUkNFIH0gZnJvbSAnLi4vY29uZmlnL2NvbmZpZyc7XG5pbXBvcnQgeyBjYWxjdWxhdGVBdmVyYWdlQml0UmF0ZSwgY2FsY3VsYXRlQXZlcmFnZUZyYW1lUmF0ZSB9IGZyb20gJy4uL3V0aWxpdGllcy9zdGF0cyc7XG5cbmxldCBkYXRlU3RhcnRUaW1lc3RhbXAgPSAwO1xubGV0IGNhblBsYXlUaW1lU3RhbXAgPSAwO1xubGV0IHRvdGFsV2FpdGluZ1NlY29uZHMgPSAwO1xubGV0IHN0YXJ0V2FpdGluZ1NlY29uZHMgPSAwO1xubGV0IHJlYnVmZmVyaW5nRXZlbnRzTnVtID0gMDtcblxuZXhwb3J0IGNvbnN0IGxvYWRTdGFydCA9IChldmVudCkgPT4ge1xuICAgIC8vIGNvbnNvbGUubG9nKCdsb2FkU3RhcnQgLS0+ICcsIGV2ZW50KTtcbiAgICBkYXRlU3RhcnRUaW1lc3RhbXAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbn07XG5cbmV4cG9ydCBjb25zdCBkdXJhdGlvbmNoYW5nZSA9IChldmVudCkgPT4ge1xuICAgIC8vIGNvbnNvbGUubG9nKCdkdXJhdGlvbmNoYW5nZSAtLT4gJywgZXZlbnQpO1xufTtcblxuZXhwb3J0IGNvbnN0IGxvYWRlZG1ldGFkYXRhID0gKGV2ZW50KSA9PiB7XG4gICAgLy8gY29uc29sZS5sb2coJ2xvYWRlZG1ldGFkYXRhIC0tPiAnLCBldmVudCk7XG59O1xuXG5leHBvcnQgY29uc3QgZW5kZWQgPSAoZXZlbnQsIHNlc3Npb24pID0+IHtcbiAgICAvLyByaWdodCBub3cgd2UgbWF5IG5vdCBoYXZlIGFueW1vcmUgdmlkZW8gcHJvcGVydGllcyAoRXMuIHZpZGVvIGlzIHJlZ2VuZXJhdGVkIGJ5IGNsaWVudCksIHNvIHdlIGhhdmUgdG8gdXNlIHNlc3Npb24gaW5mby5cbiAgICBsZXQgYW5hbHl0aWNPYmogPSBjcmVhdGVBbmFseXRpY3NPYmplY3QoZXZlbnQudGFyZ2V0LCBBTkFMWVRJQ1NfREVUQUlMRURfU09VUkNFLlZJREVPX0NPTVBMRVRFRCk7XG4gICAgYW5hbHl0aWNPYmouYml0cmF0ZSA9IGNhbGN1bGF0ZUF2ZXJhZ2VCaXRSYXRlKHNlc3Npb24uc25hcHNob3RzKS50b0ZpeGVkKDEpO1xuICAgIGFuYWx5dGljT2JqLmZyYW1lcmF0ZSA9IGNhbGN1bGF0ZUF2ZXJhZ2VGcmFtZVJhdGUoc2Vzc2lvbi5zbmFwc2hvdHMpLnRvRml4ZWQoMCk7XG4gICAgYW5hbHl0aWNPYmoucG9zaXRpb24gPSBzZXNzaW9uLmR1cmF0aW9uO1xuICAgIGFuYWx5dGljT2JqLnRvdGFsTGVuZ3RoID0gc2Vzc2lvbi5kdXJhdGlvbjtcbiAgICB0cmFjayhBTkFMWVRJQ1NfRVZFTlRTLlBMQVlfQ09NUExFVEVELCBhbmFseXRpY09iaik7XG59O1xuXG5leHBvcnQgY29uc3QgbG9hZGVkZGF0YSA9IChldmVudCkgPT4ge1xuICAgIC8vIGNvbnNvbGUubG9nKCdsb2FkZWRkYXRhIC0tPiAnLCBldmVudCk7XG4gICAgLypcbiAgICAqIGNhbnBsYXkgYW5kIG90aGVycyBldmVudHMgYXJlIGFsc28gZmlyZWQgIGFmdGVyIHZpZGVvIGlzIGNvbXBsZXRlZC4gU28sIGluIG9yZGVyIHRvIHRyYWNrIG9uIHNlZ21lbnRcbiAgICAqIHdlIGFzc3VtZSB0aGF0IHZpZGVvIGlzIHN0YXJ0ZWQgd2hlbiB2aWRlbyBwbGF5ZXIgaGFzIGxvYWRlZCBhbGwgZGF0YS4gVGhpcyBldmVudCB0aGF0J3Mgbm90IGdvb2QgaW4gb3JkZXIgdG8gdHJhY2sgdmlkZW8tbWV0cmljc1xuICAgICovXG4gICAgY29uc3QgYW5hbHl0aWNPYmogPSBjcmVhdGVBbmFseXRpY3NPYmplY3QoZXZlbnQudGFyZ2V0LCBBTkFMWVRJQ1NfREVUQUlMRURfU09VUkNFLlZJREVPX1NUQVJUKTtcbiAgICB0cmFjayhBTkFMWVRJQ1NfRVZFTlRTLlBMQVlfU1RBUlRFRCwgYW5hbHl0aWNPYmopO1xufTtcblxuZXhwb3J0IGNvbnN0IHByb2dyZXNzID0gKGV2ZW50KSA9PiB7XG4gICAgY29uc3QgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAvLyBjb25zb2xlLmxvZygncHJvZ3Jlc3MgLS0+ICcsIGV2ZW50KTtcbiAgICBpZiAoc3RhcnRXYWl0aW5nU2Vjb25kcyA+IDApIHtcbiAgICAgICAgdG90YWxXYWl0aW5nU2Vjb25kcyArPSBjdXJyZW50VGltZSAtIHN0YXJ0V2FpdGluZ1NlY29uZHM7XG4gICAgICAgIHN0YXJ0V2FpdGluZ1NlY29uZHMgPSAwO1xuICAgIH1cbn07XG5cbmV4cG9ydCBjb25zdCBjYW5wbGF5ID0gKGV2ZW50KSA9PiB7XG4gICAgLy8gY29uc29sZS5sb2coJ2NhbnBsYXkgLS0+ICcsIGV2ZW50KTtcbiAgICBjYW5QbGF5VGltZVN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG59O1xuXG5leHBvcnQgY29uc3QgcGF1c2UgPSAoZXZlbnQpID0+IHtcbiAgICBpZiAoZXZlbnQudGFyZ2V0Lm5ldHdvcmtTdGF0ZSA9PT0gTkVUV09SS19TVEFURS5OT19TT1VSQ0UpIHtcbiAgICAgICAgY29uc3QgYW5hbHl0aWNPYmogPSBjcmVhdGVBbmFseXRpY3NPYmplY3QoZXZlbnQudGFyZ2V0LCAnbm8gYXVkaW8vdmlkZW8gc291cmNlIGZvdW5kJyk7XG4gICAgICAgIC8vIHRyYWNrKEFOQUxZVElDU19FVkVOVFMuUExBWV9JTlRFUlJVUFRFRCwgYW5hbHl0aWNPYmopO1xuICAgIH1cbn07XG5cbmV4cG9ydCBjb25zdCBjYW5wbGF5dGhyb3VnaCA9IChldmVudCkgPT4ge1xuICAgIC8vIGNvbnNvbGUubG9nKCdjYW5wbGF5dGhyb3VnaCAtLT4gJywgZXZlbnQpO1xufTtcblxuZXhwb3J0IGNvbnN0IHdhaXRpbmcgPSAoZXZlbnQpID0+IHtcbiAgICAvLyBjb25zb2xlLmxvZygnd2FpdGluZyAtLT4gJywgZXZlbnQpO1xuICAgIHN0YXJ0V2FpdGluZ1NlY29uZHMgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICByZWJ1ZmZlcmluZ0V2ZW50c051bSsrO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEpvaW5lZFRpbWUgPSAoKSA9PiB7XG4gICAgcmV0dXJuIGNhblBsYXlUaW1lU3RhbXAgJiYgZGF0ZVN0YXJ0VGltZXN0YW1wXG4gICAgICAgID8gY2FuUGxheVRpbWVTdGFtcCAtIGRhdGVTdGFydFRpbWVzdGFtcFxuICAgICAgICA6IDA7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VG90YWxSZWJ1ZmZlcmluZ1RpbWUgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHRvdGFsV2FpdGluZ1NlY29uZHM7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VG90YWxSZWJ1ZmZlcmluZ0V2ZW50c051bSA9ICgpID0+IHtcbiAgICByZXR1cm4gcmVidWZmZXJpbmdFdmVudHNOdW07XG59O1xuIiwiZXhwb3J0IGNvbnN0IGNvbnZlcnRCeXRlc1RvQml0cyA9IGJ5dGVzID0+IGJ5dGVzICogODtcbiIsImltcG9ydCB7XG4gICAgZGVjb2RlZEZyYW1lQ291bnQsXG4gICAgZGVjb2RlZFZpZGVvQnl0ZUNvdW50LFxuICAgIGRlY29kZWRBdWRpb0J5dGVDb3VudCxcbiAgICBkaXNwbGF5U3VwcG9ydEZ1bGxTY3JlZW4sXG4gICAgZHJvcHBlZEZyYW1lQ291bnQsXG4gICAgZHVyYXRpb24sXG4gICAgY3VycmVudFNyYyxcbn0gZnJvbSAnLi4vY29yZS9IVE1MNVZpZGVvUHJvcGVydGllcyc7XG5cbmltcG9ydCB7XG4gICAgZm9ybWF0QnVmZmVyZWRSYW5nZXMsXG4gICAgZm9ybWF0U2Vla2FibGVSYW5nZXMsXG4gICAgZm9ybWF0UGxheWVkUmFuZ2VzLFxufSBmcm9tICcuLi91dGlsaXRpZXMvdXRpbHMuanMnO1xuXG5leHBvcnQgY29uc3QgY29tcG9zZU1ldHJpYyA9IChzdGFydFRpbWUsIHZpZGVvKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnRUaW1lOiBzdGFydFRpbWUgPyBzdGFydFRpbWUgOiBuZXcgRGF0ZSgpLFxuICAgICAgICBkZWNvZGVkRnJhbWVzOiBkZWNvZGVkRnJhbWVDb3VudCh2aWRlbyksXG4gICAgICAgIGRyb3BwZWRGcmFtZXM6IGRyb3BwZWRGcmFtZUNvdW50KHZpZGVvKSxcbiAgICAgICAgZGVjb2RlZEJ5dGVzOiBkZWNvZGVkVmlkZW9CeXRlQ291bnQodmlkZW8pLFxuICAgICAgICBkZWNvZGVkQXVkaW9CeXRlczogZGVjb2RlZEF1ZGlvQnl0ZUNvdW50KHZpZGVvKSxcbiAgICAgICAgZGlzcGxheVN1cHBvcnRGdWxsc2NyZWVuOiBkaXNwbGF5U3VwcG9ydEZ1bGxTY3JlZW4odmlkZW8pLFxuICAgICAgICBzcmM6IGN1cnJlbnRTcmModmlkZW8pLFxuICAgICAgICBkdXJhdGlvbjogZHVyYXRpb24odmlkZW8pLFxuICAgICAgICBidWZmZXJlZFJhbmdlczogZm9ybWF0QnVmZmVyZWRSYW5nZXModmlkZW8pLFxuICAgICAgICBwbGF5ZWRSYW5nZXM6IGZvcm1hdFBsYXllZFJhbmdlcyh2aWRlbyksXG4gICAgICAgIHNlZWthYmxlUmFuZ2VzOiBmb3JtYXRTZWVrYWJsZVJhbmdlcyh2aWRlbyksXG4gICAgfTtcbn07XG4iLCJleHBvcnQgZGVmYXVsdCBjbGFzcyBSZXBvcnQge1xuICAgIHNldFJlcG9ydFByb3BlcnRpZXMgPSByZXBvcnQgPT4ge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICBkZWNvZGVkRnJhbWVzLFxuICAgICAgICAgICAgZHJvcHBlZEZyYW1lcyxcbiAgICAgICAgICAgIGRlY29kZWRCeXRlcyxcbiAgICAgICAgICAgIGRlY29kZWRBdWRpb0J5dGVzLFxuICAgICAgICAgICAgc3JjLFxuICAgICAgICAgICAgZHVyYXRpb24sXG4gICAgICAgICAgICBidWZmZXJlZFJhbmdlcyxcbiAgICAgICAgICAgIHBsYXllZFJhbmdlcyxcbiAgICAgICAgICAgIHNlZWthYmxlUmFuZ2VzLFxuICAgICAgICAgICAgc3RhcnRUaW1lLFxuICAgICAgICB9ID0gcmVwb3J0O1xuICAgICAgICB0aGlzLnN0YXJ0VGltZSA9IHN0YXJ0VGltZTtcbiAgICAgICAgdGhpcy5kZWNvZGVkRnJhbWVzID0gZGVjb2RlZEZyYW1lcztcbiAgICAgICAgdGhpcy5kcm9wcGVkRnJhbWVzID0gZHJvcHBlZEZyYW1lcztcbiAgICAgICAgdGhpcy5kZWNvZGVkQnl0ZXMgPSBkZWNvZGVkQnl0ZXM7XG4gICAgICAgIHRoaXMuZGVjb2RlZEF1ZGlvQnl0ZXMgPSBkZWNvZGVkQXVkaW9CeXRlcztcbiAgICAgICAgdGhpcy5zcmMgPSBzcmM7XG4gICAgICAgIHRoaXMuZHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgdGhpcy5idWZmZXJlZFJhbmdlcyA9IGJ1ZmZlcmVkUmFuZ2VzO1xuICAgICAgICB0aGlzLnBsYXllZFJhbmdlcyA9IHBsYXllZFJhbmdlcztcbiAgICAgICAgdGhpcy5zZWVrYWJsZVJhbmdlcyA9IHNlZWthYmxlUmFuZ2VzO1xuICAgIH07XG5cbiAgICBzZXRTbmFwc2hvdHMgPSBzbmFwc2hvdHMgPT4ge1xuICAgICAgICB0aGlzLnNuYXBzaG90cyA9IHNuYXBzaG90cztcbiAgICB9O1xuXG4gICAgc2V0U2Vzc2lvbklkID0gc2Vzc2lvbklkID0+IHtcbiAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSBzZXNzaW9uSWQ7XG4gICAgfTtcblxuICAgIHNldFVzZXJTZXR0aW5ncyA9IHVzZXJTZXR0aW5ncyA9PiB7XG4gICAgICAgIHRoaXMudXNlclNldHRpbmdzID0gdXNlclNldHRpbmdzO1xuICAgIH07XG5cbiAgICBjbGVhclNuYXBzaG90cyA9ICgpID0+ICh0aGlzLnNuYXBzaG90cyA9IFtdKTtcblxuICAgIHNldEpvaW5lZFRpbWUgPSBqb2luZWRUaW1lID0+ICh0aGlzLmpvaW5lZFRpbWUgPSBqb2luZWRUaW1lKTtcblxuICAgIHNldFJlYnVmZmVyaW5nVGltZSA9IHJlYnVmZmVyaW5nVGltZSA9PlxuICAgICAgICAodGhpcy5yZWJ1ZmZlcmluZ1RpbWUgPSByZWJ1ZmZlcmluZ1RpbWUpO1xuXG4gICAgc2V0UmVidWZmZXJpbmdFdmVudHMgPSByZWJ1ZmZlcmluZ0V2ZW50cyA9PlxuICAgICAgICAodGhpcy5yZWJ1ZmZlcmluZ0V2ZW50cyA9IHJlYnVmZmVyaW5nRXZlbnRzKTtcblxuICAgIHNldElwQWRkcmVzcyA9IGlwQWRkcmVzcyA9PiAodGhpcy5pcEFkZHJlc3MgPSBpcEFkZHJlc3MpO1xuXG4gICAgc2V0RW5kVGltZSA9IGVuZFRpbWUgPT4gKHRoaXMuZW5kVGltZSA9IGVuZFRpbWUpO1xuXG4gICAgc2V0QXZlcmFnZUJpdHJhdGUgPSBhdmVyYWdlQml0cmF0ZSA9PlxuICAgICAgICAodGhpcy5hdmVyYWdlQml0cmF0ZSA9IGF2ZXJhZ2VCaXRyYXRlKTtcbn1cbiIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlc3Npb24ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnNuYXBzaG90cyA9IFtdO1xuICAgICAgICB0aGlzLnNlc3Npb25JZCA9IG51bGw7XG4gICAgICAgIHRoaXMuZHVyYXRpb24gPSAwO1xuICAgIH1cblxuICAgIGFkZFNuYXBzaG90ID0gKHNuYXBzaG90KSA9PiB7XG4gICAgICAgIHRoaXMuc25hcHNob3RzLnB1c2goc25hcHNob3QpO1xuICAgIH1cblxuICAgIGNsZWFyU25hcHNob3RzID0gKCkgPT4ge1xuICAgICAgICB0aGlzLnNuYXBzaG90cyA9IFtdO1xuICAgIH1cblxuICAgIHNldFNlc3Npb25Qcm9wZXJ0aWVzID0gKHNlc3Npb25JZCwgZHVyYXRpb24sIGN1cnJlbnRTcmMpID0+IHtcbiAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSBzZXNzaW9uSWQ7XG4gICAgICAgIHRoaXMuZHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgdGhpcy5jdXJyZW50U3JjID0gY3VycmVudFNyYztcbiAgICB9XG59XG4iLCIvKiBcbihUaGUgTUlUIExpY2Vuc2UpXG5Db3B5cmlnaHQgKGMpIDIwMTQgSGFsw6FzeiDDgWTDoW0gPG1haWxAYWRhbWhhbGFzei5jb20+XG5QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cbiovXG5cbi8vICBVbmlxdWUgSGV4YXRyaWRlY2ltYWwgSUQgR2VuZXJhdG9yXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLy8gIERlcGVuZGVuY2llc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG52YXIgcGlkID0gcHJvY2VzcyAmJiBwcm9jZXNzLnBpZCA/IHByb2Nlc3MucGlkLnRvU3RyaW5nKDM2KSA6ICcnIDtcbnZhciBhZGRyZXNzID0gJyc7XG5pZih0eXBlb2YgX193ZWJwYWNrX3JlcXVpcmVfXyAhPT0gJ2Z1bmN0aW9uJyl7XG4gICAgdmFyIG1hYyA9ICcnLCBuZXR3b3JrSW50ZXJmYWNlcyA9IHJlcXVpcmUoJ29zJykubmV0d29ya0ludGVyZmFjZXMoKTtcbiAgICBmb3IoaW50ZXJmYWNlX2tleSBpbiBuZXR3b3JrSW50ZXJmYWNlcyl7XG4gICAgICAgIGNvbnN0IG5ldHdvcmtJbnRlcmZhY2UgPSBuZXR3b3JrSW50ZXJmYWNlc1tpbnRlcmZhY2Vfa2V5XTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gbmV0d29ya0ludGVyZmFjZS5sZW5ndGg7XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICBpZihuZXR3b3JrSW50ZXJmYWNlW2ldLm1hYyAmJiBuZXR3b3JrSW50ZXJmYWNlW2ldLm1hYyAhPSAnMDA6MDA6MDA6MDA6MDA6MDAnKXtcbiAgICAgICAgICAgICAgICBtYWMgPSBuZXR3b3JrSW50ZXJmYWNlW2ldLm1hYzsgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkcmVzcyA9IG1hYyA/IHBhcnNlSW50KG1hYy5yZXBsYWNlKC9cXDp8XFxEKy9naSwgJycpKS50b1N0cmluZygzNikgOiAnJyA7XG59IFxuXG4vLyAgRXhwb3J0c1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5tb2R1bGUuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzLmRlZmF1bHQgPSBmdW5jdGlvbihwcmVmaXgpeyByZXR1cm4gKHByZWZpeCB8fCAnJykgKyBhZGRyZXNzICsgcGlkICsgbm93KCkudG9TdHJpbmcoMzYpOyB9XG5tb2R1bGUuZXhwb3J0cy5wcm9jZXNzID0gZnVuY3Rpb24ocHJlZml4KXsgcmV0dXJuIChwcmVmaXggfHwgJycpICsgcGlkICsgbm93KCkudG9TdHJpbmcoMzYpOyB9XG5tb2R1bGUuZXhwb3J0cy50aW1lICAgID0gZnVuY3Rpb24ocHJlZml4KXsgcmV0dXJuIChwcmVmaXggfHwgJycpICsgbm93KCkudG9TdHJpbmcoMzYpOyB9XG5cbi8vICBIZWxwZXJzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmZ1bmN0aW9uIG5vdygpe1xuICAgIHZhciB0aW1lID0gRGF0ZS5ub3coKTtcbiAgICB2YXIgbGFzdCA9IG5vdy5sYXN0IHx8IHRpbWU7XG4gICAgcmV0dXJuIG5vdy5sYXN0ID0gdGltZSA+IGxhc3QgPyB0aW1lIDogbGFzdCArIDE7XG59XG4iLCJpbXBvcnQge1xuICAgIGRlY29kZWRGcmFtZUNvdW50LFxuICAgIGRlY29kZWRWaWRlb0J5dGVDb3VudCxcbiAgICBkZWNvZGVkQXVkaW9CeXRlQ291bnQsXG4gICAgZGlzcGxheUlzRnVsbHNjcmVlbixcbiAgICBkcm9wcGVkRnJhbWVDb3VudCxcbiAgICBwYXVzZWQsXG4gICAgbmV0d29ya1N0YXRlLFxuICAgIGN1cnJlbnRUaW1lIGFzIGN1cnJlbnRWaWRlb1RpbWUsXG59IGZyb20gJy4vY29yZS9IVE1MNVZpZGVvUHJvcGVydGllcyc7XG5cbmltcG9ydCB7XG4gICAgbG9hZFN0YXJ0LFxuICAgIGR1cmF0aW9uY2hhbmdlLFxuICAgIGxvYWRlZG1ldGFkYXRhLFxuICAgIGxvYWRlZGRhdGEsXG4gICAgcHJvZ3Jlc3MsXG4gICAgY2FucGxheSxcbiAgICBjYW5wbGF5dGhyb3VnaCxcbiAgICB3YWl0aW5nLFxuICAgIGdldEpvaW5lZFRpbWUsXG4gICAgZ2V0VG90YWxSZWJ1ZmZlcmluZ1RpbWUsXG4gICAgZ2V0VG90YWxSZWJ1ZmZlcmluZ0V2ZW50c051bSxcbiAgICBwYXVzZSxcbiAgICBlbmRlZCxcbn0gZnJvbSAnLi9jb3JlL0V2ZW50c01hbmFnZXInO1xuXG5pbXBvcnQge1xuICAgIGdldFVzZXJQYXJhbXMsXG4gICAgZmluZEhUTUw1VmlkZW8sXG4gICAgY29udmVydEJ5dGVzVG9CaXRzLFxuICAgIGNvbXBvc2VNZXRyaWMsXG4gICAgY2hlY2tJc0VuYWJsZWRTdGF0dXMsXG59IGZyb20gJy4vdXRpbGl0aWVzJztcblxuaW1wb3J0IHsgQ2FsbGVyLCBnZXRJcEFkZHJlc3MgfSBmcm9tICcuL2NvcmUvQ2FsbGVyJztcblxuaW1wb3J0IHtcbiAgICBNQVhfUEFVU0VEX1NFQ09ORFMsXG4gICAgVFJBTlNNSVNTSU9OX1RZUEUsXG4gICAgUExBWUVSX1RZUEUsXG4gICAgQVBJX0hPU1ROQU1FLFxuICAgIEVOQUJMSU5HX1NUQVRVU19NSUxMSVNFQ09ORFMsXG59IGZyb20gJy4vY29uZmlnL2NvbmZpZyc7XG5cbmltcG9ydCBSZXBvcnQgZnJvbSAnLi9tb2RlbC9SZXBvcnQnO1xuaW1wb3J0IFNlc3Npb24gZnJvbSAnLi9tb2RlbC9TZXNzaW9uJztcbmltcG9ydCB1bmlxaWQgZnJvbSAndW5pcWlkJztcbmltcG9ydCB7IGluaXRBbmFseXRpY3MgfSBmcm9tICcuL2FuYWx5dGljcy9hbmFseXRpY3NNYW5hZ2VyJztcblxubGV0IGxhc3REZWNvZGVkRnJhbWVzID0gMDtcbmxldCBsYXN0RHJvcHBlZEZyYW1lcyA9IDA7XG5sZXQgbGFzdERlY29kZWRCeXRlcyA9IDA7XG5sZXQgbGFzdERlY29kZWRBdWRpb0J5dGVzID0gMDtcbmxldCBsYXN0QXVkaW9CaXRSYXRlID0gMDtcbmxldCBsYXN0VmlkZW9CaXRSYXRlID0gMDtcbmxldCB0b3RhbEF1ZGlvQml0UmF0ZSA9IDA7XG5sZXQgdG90YWxWaWRlb0JpdFJhdGUgPSAwO1xubGV0IHJlcXVlc3RBbmltYXRpb25JZCA9IDA7XG5sZXQgdGltZXI7XG5sZXQgc2Vzc2lvblRyYW5zbWlzc2lvbiA9IG51bGw7XG5sZXQgcmVwb3J0ID0gbmV3IFJlcG9ydCgpO1xubGV0IHNlc3Npb24gPSBuZXcgU2Vzc2lvbigpO1xubGV0IGxhc3RUaW1lID0gbnVsbDtcbmxldCBjdXJyZW50VGltZSA9IG51bGw7XG5sZXQgdmlkZW8gPSBudWxsO1xuXG5jb25zdCByZXNldFBhcmFtcyA9ICh0b3RhbFJlcG9ydCkgPT4ge1xuICAgIGxhc3REZWNvZGVkRnJhbWVzID0gdG90YWxSZXBvcnQuZGVjb2RlZEZyYW1lcztcbiAgICBsYXN0RHJvcHBlZEZyYW1lcyA9IHRvdGFsUmVwb3J0LmRyb3BwZWRGcmFtZXM7XG4gICAgbGFzdERlY29kZWRCeXRlcyA9IHRvdGFsUmVwb3J0LmRlY29kZWRCeXRlcztcbiAgICBsYXN0RGVjb2RlZEF1ZGlvQnl0ZXMgPSB0b3RhbFJlcG9ydC5kZWNvZGVkQXVkaW9CeXRlcztcbiAgICBsYXN0QXVkaW9CaXRSYXRlID0gdG90YWxBdWRpb0JpdFJhdGU7XG4gICAgbGFzdFZpZGVvQml0UmF0ZSA9IHRvdGFsVmlkZW9CaXRSYXRlO1xufTtcblxuY29uc3QgcmVzZXRXaXRoQ3VycmVudFZpZGVvVmFsdWVzID0gKGN1cnJlbnRWaWRlbykgPT4ge1xuICAgIGxhc3REZWNvZGVkRnJhbWVzID0gZGVjb2RlZEZyYW1lQ291bnQoY3VycmVudFZpZGVvKTtcbiAgICBsYXN0RHJvcHBlZEZyYW1lcyA9IGRyb3BwZWRGcmFtZUNvdW50KGN1cnJlbnRWaWRlbyk7XG4gICAgbGFzdERlY29kZWRCeXRlcyA9IGRlY29kZWRWaWRlb0J5dGVDb3VudChjdXJyZW50VmlkZW8pO1xuICAgIGxhc3REZWNvZGVkQXVkaW9CeXRlcyA9IGRlY29kZWRBdWRpb0J5dGVDb3VudChjdXJyZW50VmlkZW8pO1xuICAgIGxhc3RBdWRpb0JpdFJhdGUgPSBjb252ZXJ0Qnl0ZXNUb0JpdHMobGFzdERlY29kZWRBdWRpb0J5dGVzKTtcbiAgICBsYXN0VmlkZW9CaXRSYXRlID0gY29udmVydEJ5dGVzVG9CaXRzKGxhc3REZWNvZGVkQnl0ZXMpO1xufTtcblxuY29uc3QgcmVzZXRBbGwgPSAoKSA9PiB7XG4gICAgbGFzdERlY29kZWRGcmFtZXMgPSAwO1xuICAgIGxhc3REcm9wcGVkRnJhbWVzID0gMDtcbiAgICBsYXN0RGVjb2RlZEJ5dGVzID0gMDtcbiAgICBsYXN0RGVjb2RlZEF1ZGlvQnl0ZXMgPSAwO1xuICAgIGxhc3RBdWRpb0JpdFJhdGUgPSAwO1xuICAgIGxhc3RWaWRlb0JpdFJhdGUgPSAwO1xuICAgIHRvdGFsQXVkaW9CaXRSYXRlID0gMDtcbiAgICB0b3RhbFZpZGVvQml0UmF0ZSA9IDA7XG59O1xuXG5jb25zdCByZXF1ZXN0QW5pbUZyYW1lID0gKCgpID0+IHtcbiAgICByZXR1cm4gKFxuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgICAgIHdpbmRvdy53ZWJraXRSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICAgICAgd2luZG93Lm1velJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgICAgICBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoY2FsbGJhY2ssIDEwMDAgLyA2MCk7XG4gICAgICAgIH1cbiAgICApO1xufSkoKTtcblxuY29uc3QgY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgfHwgd2luZG93Lm1vekNhbmNlbEFuaW1hdGlvbkZyYW1lO1xuXG5jb25zdCBjbG9zZVNlc3Npb24gPSAoKSA9PiB7XG4gICAgcmVwb3J0LnNldEpvaW5lZFRpbWUoZ2V0Sm9pbmVkVGltZSgpKTtcbiAgICByZXBvcnQuc2V0UmVidWZmZXJpbmdUaW1lKGdldFRvdGFsUmVidWZmZXJpbmdUaW1lKCkpO1xuICAgIHJlcG9ydC5zZXRSZWJ1ZmZlcmluZ0V2ZW50cyhnZXRUb3RhbFJlYnVmZmVyaW5nRXZlbnRzTnVtKCkpO1xuICAgIHJlcG9ydC5zZXRFbmRUaW1lKG5ldyBEYXRlKCkpO1xuICAgIENhbGxlcihyZXBvcnQsICdzZXNzaW9uJywgc2Vzc2lvblRyYW5zbWlzc2lvbik7XG59O1xuXG5jb25zdCBzdGFydFdvcmsgPSAod2l0aFJlc2V0ID0gZmFsc2UpID0+IHtcbiAgICBpZiAod2l0aFJlc2V0KSB7XG4gICAgICAgIHJlc2V0V2l0aEN1cnJlbnRWaWRlb1ZhbHVlcyh2aWRlbyk7XG4gICAgICAgIGN1cnJlbnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIGxhc3RUaW1lID0gY3VycmVudFRpbWU7XG4gICAgfVxuICAgIGlmICghcmVxdWVzdEFuaW1hdGlvbklkKSB0aW1lcigpO1xuICAgIGVsc2UgY29uc29sZS5sb2coJ1Byb2ZpbGVyIGlzIGFscmVhZHkgcnVubmluZycpO1xuXG4gICAgc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKCk7XG59O1xuXG5jb25zdCBzdG9wV29yayA9ICh3aXRoQ2xvc2VTZXNzaW9uID0gZmFsc2UpID0+IHtcbiAgICBjYW5jZWxBbmltYXRpb25GcmFtZShyZXF1ZXN0QW5pbWF0aW9uSWQpO1xuICAgIHJlcXVlc3RBbmltYXRpb25JZCA9IDA7XG4gICAgaWYgKHdpdGhDbG9zZVNlc3Npb24pIGNsb3NlU2Vzc2lvbigpO1xufTtcblxuY29uc3Qgb25WaWRlb0VuZGVkID0gKGV2ZW50KSA9PiB7XG4gICAgZW5kZWQoZXZlbnQsIHNlc3Npb24pOyAvLyB0cmFjayBpbnRvIGFuYWx5dGljc1xuICAgIHN0b3BXb3JrKHRydWUpOyAvLyBzdG9wcGluZyBzbmlmZmluZ1xuICAgIHJlc2V0QWxsKCk7IC8vIHJlc2V0IGFsbCB2YWx1ZXMgaW4gb3JkZXIgdG8gcGxheSB0aGUgbmV4dCB2aWRlb1xufTtcblxuY29uc3Qgb25UYWJWaXNpYmlsaXR5Y2hhbmdlID0gZXZlbnQgPT4ge1xuICAgIGlmIChkb2N1bWVudC52aXNpYmlsaXR5U3RhdGUgPT09ICdoaWRkZW4nKSBzdG9wV29yaygpO1xuICAgIGVsc2Ugc3RhcnRXb3JrKHRydWUpO1xufTtcblxuY29uc3Qgb25WaWRlb1BsYXlpbmcgPSBldmVudCA9PiB7XG4gICAgc3RhcnRXb3JrKCk7XG59O1xuXG5leHBvcnQgY29uc3Qgc3RvcFNuaWZmaW5nVmlkZW9NZXRyaWNzID0gKCkgPT4ge1xuICAgIGNvbnNvbGUubG9nKCdQcm9maWxlciBpcyBnb2luZyB0byBzdG9wIHdvcmsnKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd2aXNpYmlsaXR5Y2hhbmdlJywgb25UYWJWaXNpYmlsaXR5Y2hhbmdlKTtcbiAgICB2aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdsb2Fkc3RhcnQnLCBsb2FkU3RhcnQsIGZhbHNlKTtcbiAgICB2aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdkdXJhdGlvbmNoYW5nZScsIGR1cmF0aW9uY2hhbmdlLCBmYWxzZSk7XG4gICAgdmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignbG9hZGVkbWV0YWRhdGEnLCBsb2FkZWRtZXRhZGF0YSwgZmFsc2UpO1xuICAgIHZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2xvYWRlZGRhdGEnLCBsb2FkZWRkYXRhLCBmYWxzZSk7XG4gICAgdmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcigncHJvZ3Jlc3MnLCBwcm9ncmVzcywgZmFsc2UpO1xuICAgIHZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCBjYW5wbGF5LCBmYWxzZSk7XG4gICAgdmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2FucGxheXRocm91Z2gnLCBjYW5wbGF5dGhyb3VnaCwgZmFsc2UpO1xuICAgIHZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3dhaXRpbmcnLCB3YWl0aW5nLCBmYWxzZSk7XG4gICAgdmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcigncGF1c2UnLCBwYXVzZSwgZmFsc2UpO1xuICAgIHZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgb25WaWRlb0VuZGVkLCBmYWxzZSk7XG4gICAgdmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcigncGxheWluZycsIG9uVmlkZW9QbGF5aW5nLCBmYWxzZSk7XG4gICAgc3RvcFdvcmsoKTtcbn07XG5cbmNvbnN0IGNoZWNrU3RhdHVzSW50ZXJ2YWwgPSAoYWNjZXNzVG9rZW4sIGFwaUhvc3RuYW1lKSA9PiB7XG4gICAgbGV0IGludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICBjaGVja0lzRW5hYmxlZFN0YXR1cyhhY2Nlc3NUb2tlbiwgYXBpSG9zdG5hbWUpLnRoZW4oKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgc3RvcFNuaWZmaW5nVmlkZW9NZXRyaWNzKCk7XG4gICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzcG9uc2UgJiYgIXJlcXVlc3RBbmltYXRpb25JZCkgc3RhcnRXb3JrKCk7XG4gICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgIHN0b3BTbmlmZmluZ1ZpZGVvTWV0cmljcygpO1xuICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICAgICAgfSk7XG4gICAgfSwgRU5BQkxJTkdfU1RBVFVTX01JTExJU0VDT05EUyk7XG59O1xuXG5leHBvcnQgY29uc3Qgc3RhcnRTbmlmZmluZ1ZpZGVvTWV0cmljcyA9ICh1c2VyU2V0dGluZ3MsIHBsYXllclR5cGUsIHRyYW5zbWlzc2lvbiA9IFRSQU5TTUlTU0lPTl9UWVBFLkxPR1NUQVNILCBhcGlIb3N0bmFtZSA9IEFQSV9IT1NUTkFNRSkgPT4ge1xuICAgIGZpbmRIVE1MNVZpZGVvKHVzZXJTZXR0aW5ncywgYXBpSG9zdG5hbWUpXG4gICAgICAgIC50aGVuKGZvdW5kVmlkZW8gPT4ge1xuICAgICAgICAgICAgdmlkZW8gPSBmb3VuZFZpZGVvO1xuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gdW5pcWlkKCk7XG4gICAgICAgICAgICBjb25zdCBwcm9maWxlID0gIXVzZXJTZXR0aW5ncyA/IGdldFVzZXJQYXJhbXMoKSA6IHVzZXJTZXR0aW5ncztcbiAgICAgICAgICAgIHNlc3Npb25UcmFuc21pc3Npb24gPSB0cmFuc21pc3Npb247XG4gICAgICAgICAgICBpbml0QW5hbHl0aWNzKHByb2ZpbGUudXNlcklkKTtcbiAgICAgICAgICAgIHZpZGVvLnNlc3Npb25JZCA9IHNlc3Npb25JZDtcbiAgICAgICAgICAgIHJlcG9ydC5zZXRTZXNzaW9uSWQoc2Vzc2lvbklkKTtcblxuICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndmlzaWJpbGl0eWNoYW5nZScsIG9uVGFiVmlzaWJpbGl0eWNoYW5nZSk7XG4gICAgICAgICAgICB2aWRlby5wbGF5ZXJUeXBlID0gcGxheWVyVHlwZSB8fCBQTEFZRVJfVFlQRS5QTEFURlJPTTtcbiAgICAgICAgICAgIHZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRzdGFydCcsIGxvYWRTdGFydCwgZmFsc2UpO1xuICAgICAgICAgICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignZHVyYXRpb25jaGFuZ2UnLCBkdXJhdGlvbmNoYW5nZSwgZmFsc2UpO1xuICAgICAgICAgICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignbG9hZGVkbWV0YWRhdGEnLCBsb2FkZWRtZXRhZGF0YSwgZmFsc2UpO1xuICAgICAgICAgICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignbG9hZGVkZGF0YScsIGxvYWRlZGRhdGEsIGZhbHNlKTtcbiAgICAgICAgICAgIHZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoJ3Byb2dyZXNzJywgcHJvZ3Jlc3MsIGZhbHNlKTtcbiAgICAgICAgICAgIHZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCBjYW5wbGF5LCBmYWxzZSk7XG4gICAgICAgICAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5dGhyb3VnaCcsIGNhbnBsYXl0aHJvdWdoLCBmYWxzZSk7XG4gICAgICAgICAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCd3YWl0aW5nJywgd2FpdGluZywgZmFsc2UpO1xuICAgICAgICAgICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcigncGF1c2UnLCBwYXVzZSwgZmFsc2UpO1xuICAgICAgICAgICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBvblZpZGVvRW5kZWQsIGZhbHNlKTtcbiAgICAgICAgICAgIHZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoJ3BsYXlpbmcnLCBvblZpZGVvUGxheWluZywgZmFsc2UpO1xuXG4gICAgICAgICAgICByZXBvcnQuc2V0VXNlclNldHRpbmdzKHByb2ZpbGUpO1xuXG4gICAgICAgICAgICBnZXRJcEFkZHJlc3MoKS50aGVuKGNhbGwgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjYWxsICYmIGNhbGwuZGF0YSAmJiBjYWxsLmRhdGEucmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0LnNldElwQWRkcmVzcyhjYWxsLmRhdGEucmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBsYXN0VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICAgICAgbGV0IG51bVBhdXNlZFNlY29uZHMgPSAwO1xuICAgICAgICAgICAgY3VycmVudFRpbWUgPSAwO1xuXG4gICAgICAgICAgICBjaGVja1N0YXR1c0ludGVydmFsKHByb2ZpbGUuYWNjZXNzVG9rZW4sIGFwaUhvc3RuYW1lKTtcblxuICAgICAgICAgICAgdGltZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbklkID0gcmVxdWVzdEFuaW1GcmFtZSh0aW1lcik7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5zZXRTZXNzaW9uUHJvcGVydGllcyhzZXNzaW9uSWQsIHZpZGVvLmR1cmF0aW9uLCB2aWRlby5jdXJyZW50U3JjKTtcbiAgICAgICAgICAgICAgICBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRUaW1lIC0gbGFzdFRpbWUgPj0gMTAwMCkge1xuICAgICAgICAgICAgICAgICAgICAvLyDDqCBwYXNzYXRvIHVuIHNlY29uZG9cbiAgICAgICAgICAgICAgICAgICAgbGFzdFRpbWUgPSBjdXJyZW50VGltZTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocGF1c2VkKHZpZGVvKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbnVtUGF1c2VkU2Vjb25kcysrO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG51bVBhdXNlZFNlY29uZHMgPiBNQVhfUEFVU0VEX1NFQ09ORFMpIHN0b3BXb3JrKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG51bVBhdXNlZFNlY29uZHMgPSAwO1xuXG4gICAgICAgICAgICAgICAgICAgIGxldCBtZXRyaWMgPSBjb21wb3NlTWV0cmljKHJlcG9ydC5zdGFydFRpbWUsIHZpZGVvKTtcblxuICAgICAgICAgICAgICAgICAgICB0b3RhbFZpZGVvQml0UmF0ZSA9IGNvbnZlcnRCeXRlc1RvQml0cyhtZXRyaWMuZGVjb2RlZEJ5dGVzKTtcbiAgICAgICAgICAgICAgICAgICAgdG90YWxBdWRpb0JpdFJhdGUgPSBjb252ZXJ0Qnl0ZXNUb0JpdHMoXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWMuZGVjb2RlZEF1ZGlvQnl0ZXMsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHJlcG9ydC5zZXRSZXBvcnRQcm9wZXJ0aWVzKG1ldHJpYyk7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IHNuYXBzaG90ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0aXZlVGltZTogbmV3IERhdGUoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlY29kZWRGcmFtZXM6IHJlcG9ydC5kZWNvZGVkRnJhbWVzIC0gbGFzdERlY29kZWRGcmFtZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBkcm9wcGVkRnJhbWVzOiByZXBvcnQuZHJvcHBlZEZyYW1lcyAtIGxhc3REcm9wcGVkRnJhbWVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVjb2RlZEJ5dGVzOiByZXBvcnQuZGVjb2RlZEJ5dGVzIC0gbGFzdERlY29kZWRCeXRlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlY29kZWRBdWRpb0J5dGVzOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydC5kZWNvZGVkQXVkaW9CeXRlcyAtIGxhc3REZWNvZGVkQXVkaW9CeXRlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXlJc0Z1bGxzY3JlZW46IGRpc3BsYXlJc0Z1bGxzY3JlZW4odmlkZW8pLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9CaXRSYXRlOiB0b3RhbFZpZGVvQml0UmF0ZSAtIGxhc3RWaWRlb0JpdFJhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBhdWRpb0JpdFJhdGU6IHRvdGFsQXVkaW9CaXRSYXRlIC0gbGFzdEF1ZGlvQml0UmF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRUaW1lOiBjdXJyZW50VmlkZW9UaW1lKHZpZGVvKS50b0ZpeGVkKDIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV0d29ya1N0YXRlOiBuZXR3b3JrU3RhdGUodmlkZW8pLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkOiByZXBvcnQuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlclNldHRpbmdzOiBwcm9maWxlLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmFkZFNuYXBzaG90KHNuYXBzaG90KTtcblxuICAgICAgICAgICAgICAgICAgICByZXNldFBhcmFtcyhyZXBvcnQpO1xuICAgICAgICAgICAgICAgICAgICBDYWxsZXIoc25hcHNob3QsICdzbmFwc2hvdCcsIHNlc3Npb25UcmFuc21pc3Npb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgIH0pO1xufTtcbiIsImltcG9ydCBSZWFjdCwgeyBDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQge1xuICAgIHN0YXJ0U25pZmZpbmdWaWRlb01ldHJpY3MsXG4gICAgc3RvcFNuaWZmaW5nVmlkZW9NZXRyaWNzLFxufSBmcm9tICcuL21ldHJpY3NNYW5hZ2VyJztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgeyBUUkFOU01JU1NJT05fVFlQRSwgUExBWUVSX1RZUEUsIEFQSV9IT1NUTkFNRSB9IGZyb20gJy4vY29uZmlnL2NvbmZpZyc7XG5cbmV4cG9ydCBjbGFzcyBXeU1ldHJpY1Byb2ZpbGVyIGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIHJ1bm5pbmc6IGZhbHNlLFxuICAgICAgICAgICAgc3RhcnRPbk1vdW50OiB0cnVlLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHN0YXRpYyBwcm9wVHlwZXMgPSB7XG4gICAgICAgIHJ1bm5pbmc6IFByb3BUeXBlcy5ib29sLmlzUmVxdWlyZWQsXG4gICAgICAgIHN0YXJ0T25Nb3VudDogUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIHVzZXJTZXR0aW5nczogUHJvcFR5cGVzLnNoYXBlKHtcbiAgICAgICAgICAgIHVzZXJJZDogUHJvcFR5cGVzLm51bWJlcixcbiAgICAgICAgICAgIHVzZXJOYW1lOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICAgICAgZ3JvdXBJZDogUHJvcFR5cGVzLm51bWJlcixcbiAgICAgICAgICAgIHN1Ymdyb3VwSWQ6IFByb3BUeXBlcy5udW1iZXIsXG4gICAgICAgICAgICBhY2Nlc3NUb2tlbjogUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgfSkuaXNSZXF1aXJlZCxcbiAgICAgICAgdHJhbnNtaXR0ZXI6IFByb3BUeXBlcy5vbmVPZihbVFJBTlNNSVNTSU9OX1RZUEUuTE9HU1RBU0gsIFRSQU5TTUlTU0lPTl9UWVBFLlJFU1RdKSxcbiAgICAgICAgcGxheWVyVHlwZTogUHJvcFR5cGVzLm9uZU9mKFtQTEFZRVJfVFlQRS5QTEFURk9STSwgUExBWUVSX1RZUEUuQVBQU10pLFxuICAgICAgICBjaGlsZHJlbjogUHJvcFR5cGVzLm5vZGUuaXNSZXF1aXJlZCxcbiAgICAgICAgYXBpSG9zdG5hbWU6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgfTtcblxuICAgIHN0YXRpYyBkZWZhdWx0UHJvcHMgPSB7XG4gICAgICAgIHN0YXJ0T25Nb3VudDogdHJ1ZSxcbiAgICAgICAgdHJhbnNtaXR0ZXI6IFRSQU5TTUlTU0lPTl9UWVBFLkxPR1NUQVNILFxuICAgICAgICBwbGF5ZXJUeXBlOiBQTEFZRVJfVFlQRS5QTEFURk9STSxcbiAgICAgICAgYXBpSG9zdG5hbWU6IEFQSV9IT1NUTkFNRSxcbiAgICB9O1xuXG4gICAgY29tcG9uZW50RGlkTW91bnQgPSAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgc3RhcnRPbk1vdW50LCB1c2VyU2V0dGluZ3MsIHBsYXllclR5cGUsIHRyYW5zbWl0dGVyLCBhcGlIb3N0bmFtZSB9ID0gdGhpcy5wcm9wcztcbiAgICAgICAgaWYgKHN0YXJ0T25Nb3VudCkge1xuICAgICAgICAgICAgc3RhcnRTbmlmZmluZ1ZpZGVvTWV0cmljcyh1c2VyU2V0dGluZ3MsIHBsYXllclR5cGUsIHRyYW5zbWl0dGVyLCBhcGlIb3N0bmFtZSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgc3RhdGljIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyhwcm9wcywgc3RhdGUpIHtcbiAgICAgICAgY29uc3QgeyB1c2VyU2V0dGluZ3MsIHBsYXllclR5cGUsIHRyYW5zbWl0dGVyLCBydW5uaW5nLCBhcGlIb3N0bmFtZSB9ID0gcHJvcHM7XG5cbiAgICAgICAgaWYgKHJ1bm5pbmcgJiYgIXN0YXRlLnJ1bm5pbmcpIHtcbiAgICAgICAgICAgIHN0YXJ0U25pZmZpbmdWaWRlb01ldHJpY3ModXNlclNldHRpbmdzLCBwbGF5ZXJUeXBlLCB0cmFuc21pdHRlciwgYXBpSG9zdG5hbWUpO1xuICAgICAgICB9IGVsc2UgaWYgKCFydW5uaW5nICYmIHN0YXRlLnJ1bm5pbmcpIHtcbiAgICAgICAgICAgIHN0b3BTbmlmZmluZ1ZpZGVvTWV0cmljcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJ1bm5pbmc6IHByb3BzLnJ1bm5pbmcsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gPGRpdj57dGhpcy5wcm9wcy5jaGlsZHJlbn08L2Rpdj47XG4gICAgfVxufVxuIl0sIm5hbWVzIjpbImRlY29kZWRGcmFtZUNvdW50IiwidmlkZW8iLCJ3ZWJraXREZWNvZGVkRnJhbWVDb3VudCIsImRlY29kZWRWaWRlb0J5dGVDb3VudCIsIndlYmtpdFZpZGVvRGVjb2RlZEJ5dGVDb3VudCIsImRlY29kZWRBdWRpb0J5dGVDb3VudCIsIndlYmtpdEF1ZGlvRGVjb2RlZEJ5dGVDb3VudCIsImRpc3BsYXlJc0Z1bGxzY3JlZW4iLCJ3ZWJraXREaXNwbGF5aW5nRnVsbHNjcmVlbiIsImRpc3BsYXlTdXBwb3J0RnVsbFNjcmVlbiIsIndlYmtpdFN1cHBvcnRzRnVsbHNjcmVlbiIsImRyb3BwZWRGcmFtZUNvdW50Iiwid2Via2l0RHJvcHBlZEZyYW1lQ291bnQiLCJkdXJhdGlvbiIsInBhdXNlZCIsImN1cnJlbnRTcmMiLCJuZXR3b3JrU3RhdGUiLCJjdXJyZW50VGltZSIsImluaXRBbmFseXRpY3MiLCJ1c2VySWQiLCJyZXN0QXBpQmFzZU5hbWUiLCJlbnYiLCJwcm9jZXNzIiwiUkVBQ1RfQVBQX0VOViIsIk5PREVfRU5WIiwiQVBJX0hPU1ROQU1FIiwiQVBJX1NFUlZFUiIsIk1BWF9TRUVLSU5HX1ZJREVPX1RBRyIsIk1BWF9QQVVTRURfU0VDT05EUyIsIkVOQUJMSU5HX1NUQVRVU19NSUxMSVNFQ09ORFMiLCJUUkFOU01JU1NJT05fVFlQRSIsIlJFU1QiLCJMT0dTVEFTSCIsIk5FVFdPUktfU1RBVEUiLCJFTVBUWSIsIklETEUiLCJMT0FESU5HIiwiTk9fU09VUkNFIiwiQU5BTFlUSUNTX0FQUF9TT1VSQ0UiLCJBTkFMWVRJQ1NfREVUQUlMRURfU09VUkNFIiwiVklERU9fU1RBUlQiLCJWSURFT19DT01QTEVURUQiLCJQTEFZRVJfVFlQRSIsIlBMQVRGT1JNIiwiQVBQUyIsIldZU0NPVVRfSE9TVE5BTUVTX1NVRkZJWCIsIkRFRkFVTFQiLCJSVSIsIkNOIiwiaXNCdWZmZXIiLCJidG9hIiwicmVxdWlyZSQkMCIsImNvb2tpZXMiLCJyZXF1aXJlJCQxIiwiZGVmYXVsdHMiLCJJbnRlcmNlcHRvck1hbmFnZXIiLCJDYW5jZWwiLCJBeGlvcyIsInJlcXVpcmUkJDIiLCJyZXF1aXJlJCQzIiwidG9TdHJpbmciLCJpc0FycmF5IiwiaXNBcnJheUJ1ZmZlciIsImlzRm9ybURhdGEiLCJpc0FycmF5QnVmZmVyVmlldyIsImlzU3RyaW5nIiwiaXNOdW1iZXIiLCJpc1VuZGVmaW5lZCIsImlzT2JqZWN0IiwiaXNEYXRlIiwiaXNGaWxlIiwiaXNCbG9iIiwiaXNGdW5jdGlvbiIsImlzU3RyZWFtIiwiaXNVUkxTZWFyY2hQYXJhbXMiLCJ0cmltIiwiaXNTdGFuZGFyZEJyb3dzZXJFbnYiLCJmb3JFYWNoIiwibWVyZ2UiLCJleHRlbmQiLCJiaW5kIiwidXRpbHMiLCJlbmhhbmNlRXJyb3IiLCJjcmVhdGVFcnJvciIsImVuY29kZSIsImlnbm9yZUR1cGxpY2F0ZU9mIiwiY2hhcnMiLCJFIiwiaXNVUkxTYW1lT3JpZ2luIiwiYnVpbGRVUkwiLCJwYXJzZUhlYWRlcnMiLCJzZXR0bGUiLCJERUZBVUxUX0NPTlRFTlRfVFlQRSIsInNldENvbnRlbnRUeXBlSWZVbnNldCIsImdldERlZmF1bHRBZGFwdGVyIiwibm9ybWFsaXplSGVhZGVyTmFtZSIsInRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQiLCJpc0Fic29sdXRlVVJMIiwiY29tYmluZVVSTHMiLCJ0cmFuc2Zvcm1EYXRhIiwiaXNDYW5jZWwiLCJkaXNwYXRjaFJlcXVlc3QiLCJDYW5jZWxUb2tlbiIsImNyZWF0ZUluc3RhbmNlIiwiYXhpb3MiLCJmb3JtYXRVc2VyU2V0dGluZ3MiLCJ1c2VyU2V0dGluZ3MiLCJzdWJncm91cElkIiwiZ3JvdXBJZCIsIkxvZ1N0YXNoIiwibW9kZWwiLCJsYWJlbCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZmlyc3REb21haW5MZXZlbCIsImdldEZpcnN0TGV2ZWxEb21haW4iLCJ1cmwiLCJ0YWdzIiwibGV2ZWwiLCJvcHRpb25zIiwibXV0ZUNvbnNvbGUiLCJsb2dnZXIiLCJjcmVhdGUiLCJpbmZvIiwiZXJyIiwiUmVzdEFwaSIsIm1ldGhvZCIsImlkIiwiZGF0YSIsImdldElwQWRkcmVzcyIsIkNhbGxlciIsInRyYW5zbWlzc2lvbiIsImdldEdsb2JhbFN3aXRjaFN0YXR1cyIsImFjY2Vzc1Rva2VuIiwiYXBpSG9zdG5hbWUiLCJwYXJhbXMiLCJhY2Nlc3NfdG9rZW4iLCJmb3JtYXRCdWZmZXJlZFJhbmdlcyIsImZvcm1hdHRlZFJhbmdlcyIsImkiLCJidWZmZXJlZCIsImxlbmd0aCIsInB1c2giLCJzdGFydCIsImVuZCIsImZvcm1hdFNlZWthYmxlUmFuZ2VzIiwiZm9ybWF0dGVkU2Vla2FibGVSYW5nZXMiLCJzZWVrYWJsZSIsImZvcm1hdFBsYXllZFJhbmdlcyIsImZvcm1hdHRlZFBsYXllZFJhbmdlcyIsInBsYXllZCIsImdldFVybFBhcmFtcyIsImZpbmFsVXJsIiwiaW5jbHVkZXMiLCJ1c2VyTmFtZSIsInNwbGl0IiwicmVkdWNlIiwiYWNjIiwiY3VyIiwia2V5IiwidmFsIiwiZ2V0VXNlclBhcmFtcyIsInJlc3VsdCIsIndpbmRvdyIsImxvY2F0aW9uIiwiaG9zdG5hbWUiLCJocmVmIiwiY2hlY2tJc0VuYWJsZWRTdGF0dXMiLCJwcm9taXNlIiwidGhlbiIsInJlc3BvbnNlIiwiaXNFbmFibGVkIiwiY2F0Y2giLCJFcnJvciIsImZpbmRIVE1MNVZpZGVvIiwiY291bnRlciIsInNlZWtpbmciLCJzZXRJbnRlcnZhbCIsImRvY3VtZW50IiwicXVlcnlTZWxlY3RvciIsImNsZWFySW50ZXJ2YWwiLCJjcmVhdGVBbmFseXRpY3NPYmplY3QiLCJkZXRhaWxlZEFwcFNvdXJjZSIsImFwcFNvdXJjZSIsImFjdGlvblZhbHVlIiwic2Vzc2lvbklkIiwicG9zaXRpb24iLCJ0b3RhbExlbmd0aCIsInBsYXllciIsInBsYXllclR5cGUiLCJpc011dGVkIiwibXV0ZWQiLCJmdWxsU2NyZWVuIiwiaXNQbGF5bGlzdCIsIl9pc1BsYXlsaXN0Iiwic3JjIiwidmJlZ2luIiwiTnVtYmVyIiwiaXNOYU4iLCJjYWxjdWxhdGVBdmVyYWdlQml0UmF0ZSIsIl8iLCJtZWFuQnkiLCJzbmFwc2hvdHMiLCJwIiwiZGVjb2RlZEJ5dGVzIiwiY2FsY3VsYXRlQXZlcmFnZUZyYW1lUmF0ZSIsImRlY29kZWRGcmFtZXMiLCJkYXRlU3RhcnRUaW1lc3RhbXAiLCJjYW5QbGF5VGltZVN0YW1wIiwidG90YWxXYWl0aW5nU2Vjb25kcyIsInN0YXJ0V2FpdGluZ1NlY29uZHMiLCJyZWJ1ZmZlcmluZ0V2ZW50c051bSIsImxvYWRTdGFydCIsImV2ZW50IiwiRGF0ZSIsImdldFRpbWUiLCJkdXJhdGlvbmNoYW5nZSIsImxvYWRlZG1ldGFkYXRhIiwiZW5kZWQiLCJzZXNzaW9uIiwiYW5hbHl0aWNPYmoiLCJ0YXJnZXQiLCJiaXRyYXRlIiwidG9GaXhlZCIsImZyYW1lcmF0ZSIsInRyYWNrIiwibG9hZGVkZGF0YSIsInByb2dyZXNzIiwiY2FucGxheSIsInBhdXNlIiwiY2FucGxheXRocm91Z2giLCJ3YWl0aW5nIiwiZ2V0Sm9pbmVkVGltZSIsImdldFRvdGFsUmVidWZmZXJpbmdUaW1lIiwiZ2V0VG90YWxSZWJ1ZmZlcmluZ0V2ZW50c051bSIsImNvbnZlcnRCeXRlc1RvQml0cyIsImJ5dGVzIiwiY29tcG9zZU1ldHJpYyIsInN0YXJ0VGltZSIsImRyb3BwZWRGcmFtZXMiLCJkZWNvZGVkQXVkaW9CeXRlcyIsImRpc3BsYXlTdXBwb3J0RnVsbHNjcmVlbiIsImJ1ZmZlcmVkUmFuZ2VzIiwicGxheWVkUmFuZ2VzIiwic2Vla2FibGVSYW5nZXMiLCJSZXBvcnQiLCJzZXRSZXBvcnRQcm9wZXJ0aWVzIiwicmVwb3J0Iiwic2V0U25hcHNob3RzIiwic2V0U2Vzc2lvbklkIiwic2V0VXNlclNldHRpbmdzIiwiY2xlYXJTbmFwc2hvdHMiLCJzZXRKb2luZWRUaW1lIiwiam9pbmVkVGltZSIsInNldFJlYnVmZmVyaW5nVGltZSIsInJlYnVmZmVyaW5nVGltZSIsInNldFJlYnVmZmVyaW5nRXZlbnRzIiwicmVidWZmZXJpbmdFdmVudHMiLCJzZXRJcEFkZHJlc3MiLCJpcEFkZHJlc3MiLCJzZXRFbmRUaW1lIiwiZW5kVGltZSIsInNldEF2ZXJhZ2VCaXRyYXRlIiwiYXZlcmFnZUJpdHJhdGUiLCJTZXNzaW9uIiwiYWRkU25hcHNob3QiLCJzbmFwc2hvdCIsInNldFNlc3Npb25Qcm9wZXJ0aWVzIiwibGFzdERlY29kZWRGcmFtZXMiLCJsYXN0RHJvcHBlZEZyYW1lcyIsImxhc3REZWNvZGVkQnl0ZXMiLCJsYXN0RGVjb2RlZEF1ZGlvQnl0ZXMiLCJsYXN0QXVkaW9CaXRSYXRlIiwibGFzdFZpZGVvQml0UmF0ZSIsInRvdGFsQXVkaW9CaXRSYXRlIiwidG90YWxWaWRlb0JpdFJhdGUiLCJyZXF1ZXN0QW5pbWF0aW9uSWQiLCJ0aW1lciIsInNlc3Npb25UcmFuc21pc3Npb24iLCJsYXN0VGltZSIsInJlc2V0UGFyYW1zIiwidG90YWxSZXBvcnQiLCJyZXNldFdpdGhDdXJyZW50VmlkZW9WYWx1ZXMiLCJjdXJyZW50VmlkZW8iLCJyZXNldEFsbCIsInJlcXVlc3RBbmltRnJhbWUiLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJ3ZWJraXRSZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJtb3pSZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJjYWxsYmFjayIsInNldFRpbWVvdXQiLCJjYW5jZWxBbmltYXRpb25GcmFtZSIsIm1vekNhbmNlbEFuaW1hdGlvbkZyYW1lIiwiY2xvc2VTZXNzaW9uIiwic3RhcnRXb3JrIiwid2l0aFJlc2V0IiwiY29uc29sZSIsImxvZyIsInN0b3BXb3JrIiwid2l0aENsb3NlU2Vzc2lvbiIsIm9uVmlkZW9FbmRlZCIsIm9uVGFiVmlzaWJpbGl0eWNoYW5nZSIsInZpc2liaWxpdHlTdGF0ZSIsIm9uVmlkZW9QbGF5aW5nIiwic3RvcFNuaWZmaW5nVmlkZW9NZXRyaWNzIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsImNoZWNrU3RhdHVzSW50ZXJ2YWwiLCJpbnRlcnZhbCIsInN0YXJ0U25pZmZpbmdWaWRlb01ldHJpY3MiLCJmb3VuZFZpZGVvIiwidW5pcWlkIiwicHJvZmlsZSIsImFkZEV2ZW50TGlzdGVuZXIiLCJQTEFURlJPTSIsImNhbGwiLCJudW1QYXVzZWRTZWNvbmRzIiwibWV0cmljIiwiZWZmZWN0aXZlVGltZSIsInZpZGVvQml0UmF0ZSIsImF1ZGlvQml0UmF0ZSIsImN1cnJlbnRWaWRlb1RpbWUiLCJXeU1ldHJpY1Byb2ZpbGVyIiwiY29tcG9uZW50RGlkTW91bnQiLCJwcm9wcyIsInN0YXJ0T25Nb3VudCIsInRyYW5zbWl0dGVyIiwic3RhdGUiLCJydW5uaW5nIiwiUmVhY3QiLCJjaGlsZHJlbiIsIkNvbXBvbmVudCIsInByb3BUeXBlcyIsIlByb3BUeXBlcyIsImJvb2wiLCJpc1JlcXVpcmVkIiwic2hhcGUiLCJudW1iZXIiLCJzdHJpbmciLCJvbmVPZiIsIm5vZGUiLCJkZWZhdWx0UHJvcHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0lBQU8sSUFBTUEsb0JBQW9CLFNBQXBCQSxpQkFBb0I7SUFBQSxTQUFTQyxNQUFNQyx1QkFBZjtJQUFBLENBQTFCOztBQUVQLElBQU8sSUFBTUMsd0JBQXdCLFNBQXhCQSxxQkFBd0I7SUFBQSxTQUFTRixNQUFNRywyQkFBZjtJQUFBLENBQTlCOztBQUVQLElBQU8sSUFBTUMsd0JBQXdCLFNBQXhCQSxxQkFBd0I7SUFBQSxTQUFTSixNQUFNSywyQkFBZjtJQUFBLENBQTlCOztBQUVQLElBQU8sSUFBTUMsc0JBQXNCLFNBQXRCQSxtQkFBc0I7SUFBQSxTQUFTTixNQUFNTywwQkFBZjtJQUFBLENBQTVCOztBQUVQLElBQU8sSUFBTUMsMkJBQTJCLFNBQTNCQSx3QkFBMkI7SUFBQSxTQUFT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