UNPKG

request-monitor

Version:
437 lines (395 loc) 40.1 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["requestMonitor"] = factory(); else root["requestMonitor"] = factory(); })(window, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./src/index.js"); /******/ }) /************************************************************************/ /******/ ({ /***/ "./src/index.js": /*!**********************!*\ !*** ./src/index.js ***! \**********************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /** * * @param {*} listener * http Info: { __type: "fetch", // 使用底层库类型,有 fetch 和 xhr url: "", method: "", timeout: 0, // 超时时间 params: {}, // 请求参数 responseStatus: 200, // 如果是 -1 ,代表网络异常 responseStatusText: "ok", responseJson: {"code": 0}, responseText: "{"code": 0}", requestTime: 100, 请求时间,单位为 ms } */ var listeners = {}; var id = 1; function getId() { return id++; } function handleEndTime(info) { var endTime = new Date().getTime(); info.requestTime = endTime - info.startTime; info.endTime = endTime; } function handleDefaultApi(emit) { if (window._requestMonitorIsLoad) return null; window._requestMonitorIsLoad = true; handleXhr(emit); handleFetch(emit); return true; } function handleHeader(xhr) { try { var headers = xhr.getAllResponseHeaders(); if (!headers) return; if ((typeof headers === 'undefined' ? 'undefined' : _typeof(headers)) === 'object') { return headers; } var newHeaders = {}, headers = headers.split(/[\r\n]/).forEach(function (header) { var index = header.indexOf(":"); var name = header.substr(0, index); var value = header.substr(index + 2); if (name) { newHeaders[name] = value; } }); return newHeaders; } catch (e) { return {}; } } function handleXhr(emit) { var _open = XMLHttpRequest.prototype.open; var _send = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.open = function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var method = args[0]; var url = args[1]; this._monitor = { __type: 'xhr' }; _open.apply(this, args); Object.assign(this._monitor, { method: method, url: url }); }; XMLHttpRequest.prototype.send = function () { var _this = this; for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } _send.apply(this, args); this._monitor.startTime = new Date().getTime(); this._monitor.timeout = this.timeout || 0; try { if (args.length > 0 && typeof args[0] === 'string') { this._monitor.params = args[0]; } } catch (err) {} this.addEventListener('load', function () { var contentType = this.getResponseHeader('Content-Type'); contentType = contentType || ''; contentType = contentType.toLowerCase(); var ignores = ['blob', 'arraybuffer', 'moz-chunked-arraybuffer', "ms-stream"]; if (this.responseType && ignores.indexOf(this.responseType) > -1) { return; // ignore blob type } if (contentType.indexOf('application/json') !== -1) { this._monitor.responseText = this.responseText; try { this._monitor.responseJson = JSON.parse(this.responseText); } catch (e) {} } else if (contentType.indexOf('text/plain') !== -1) { this._monitor.responseText = this.responseText; } this._monitor.responseHeaders = handleHeader(this); this._monitor.responseStatus = this.status; this._monitor.responseStatusText = this.statusText; emit(this._monitor); }, false); this.addEventListener('error', function () { _this._monitor.responseStatusText = 'Xhr Network request exception'; _this._monitor.responseStatus = -1; emit(_this._monitor); }); this.addEventListener('timeout', function () { emit(_this._monitor); }); }; } function getParams(options) { var params = void 0; try { if (options.body && typeof options.body === 'string') { params = options.body; } } catch (er) {} return params; } function handleFetch(emit) { if (window.fetch) { var getHeaders = function getHeaders(response) { try { var headers = response.headers.entries(); var result = {}; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = headers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var pair = _step.value; result[pair[0]] = pair[1]; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return result; } catch (e) { console.warn(e); return {}; } }; var monitorFetch = function monitorFetch(url) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var params = getParams(options); var _monitor = { __type: 'fetch', url: url, method: options.method || 'GET', params: params, startTime: new Date().getTime(), timeout: options.timeout || 0 }; var fetchRequest = // _Promise // .race ([ // new _Promise ((resolve, reject) => { // setTimeout (() => { // let err = new Error ('前端fetch Network request timeout: ' + options.timeout); // err.status = 504; // reject (err); // }, timeout); // }), // ]) _fetch(url, options).then(function (response) { var _text = response.text; _monitor.responseStatus = response.status; _monitor.responseHeaders = getHeaders(response); _monitor.responseStatusText = response.statusText; response.json = function () { return new _Promise(function (resolve, reject) { _text.call(response).then(function (text) { try { var json = JSON.parse(text); _monitor.responseText = text; _monitor.responseJson = json; emit(_monitor); resolve(json); } catch (e) { e.type = 'invalid-json'; _monitor.responseText = text; emit(_monitor); reject(e); } }).catch(function (err) { reject(err); }); }); }; response.text = function () { return new _Promise(function (resolve, reject) { _text.call(response).then(function (text) { _monitor.responseText = text; emit(_monitor); resolve(text); }).catch(function (err) { reject(err); }); }); }; return response; }); return new _Promise(function (resolve, reject) { fetchRequest.then(function (data) { resolve(data); }).catch(function (err) { _monitor.responseStatus = err.status || -1; _monitor.responseText = err.message || 'Fetch Network request exception'; emit(_monitor); reject(err); }); return fetchRequest; }); }; var _Promise = window.fetch.Promise || Promise; var _fetch = window.fetch; monitorFetch.Promise = _Promise; Object.defineProperty(monitorFetch, 'Promise', { set: function set(value) { // monitorFetch.Promise = value; _fetch.Promise = value; }, get: function get() { return _fetch.Promise; } }); window.fetch = monitorFetch; } } function emit(info) { handleEndTime(info); try { Object.keys(info).forEach(function (key) { if (typeof info[key] === 'undefined') { delete info[key]; } }); Object.keys(listeners).forEach(function (key) { setTimeout(function () { try { listeners[key](info); } catch (err) { console.error(err); } }); }); } catch (e) { console.error(e); } } module.exports = requestMonitor; function requestMonitor(listener) { listener = listener || function (httpInfo) { return httpInfo; }; if (typeof listener !== 'function') { throw new Error('The listener Type must be function'); } var _id = getId(); listeners[_id] = listener; handleDefaultApi(emit); return { cancel: function cancel() { delete listeners[_id]; } }; } requestMonitor.handleDefaultApi = handleDefaultApi; /***/ }) /******/ }); }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZXF1ZXN0TW9uaXRvci93ZWJwYWNrL3VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24iLCJ3ZWJwYWNrOi8vcmVxdWVzdE1vbml0b3Ivd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vcmVxdWVzdE1vbml0b3IvLi9zcmMvaW5kZXguanMiXSwibmFtZXMiOlsibGlzdGVuZXJzIiwiaWQiLCJnZXRJZCIsImhhbmRsZUVuZFRpbWUiLCJpbmZvIiwiZW5kVGltZSIsIkRhdGUiLCJnZXRUaW1lIiwicmVxdWVzdFRpbWUiLCJzdGFydFRpbWUiLCJoYW5kbGVEZWZhdWx0QXBpIiwiZW1pdCIsIndpbmRvdyIsIl9yZXF1ZXN0TW9uaXRvcklzTG9hZCIsImhhbmRsZVhociIsImhhbmRsZUZldGNoIiwiaGFuZGxlSGVhZGVyIiwieGhyIiwiaGVhZGVycyIsImdldEFsbFJlc3BvbnNlSGVhZGVycyIsIm5ld0hlYWRlcnMiLCJzcGxpdCIsImZvckVhY2giLCJoZWFkZXIiLCJpbmRleCIsImluZGV4T2YiLCJuYW1lIiwic3Vic3RyIiwidmFsdWUiLCJlIiwiX29wZW4iLCJYTUxIdHRwUmVxdWVzdCIsInByb3RvdHlwZSIsIm9wZW4iLCJfc2VuZCIsInNlbmQiLCJhcmdzIiwibWV0aG9kIiwidXJsIiwiX21vbml0b3IiLCJfX3R5cGUiLCJhcHBseSIsIk9iamVjdCIsImFzc2lnbiIsInRpbWVvdXQiLCJsZW5ndGgiLCJwYXJhbXMiLCJlcnIiLCJhZGRFdmVudExpc3RlbmVyIiwiY29udGVudFR5cGUiLCJnZXRSZXNwb25zZUhlYWRlciIsInRvTG93ZXJDYXNlIiwiaWdub3JlcyIsInJlc3BvbnNlVHlwZSIsInJlc3BvbnNlVGV4dCIsInJlc3BvbnNlSnNvbiIsIkpTT04iLCJwYXJzZSIsInJlc3BvbnNlSGVhZGVycyIsInJlc3BvbnNlU3RhdHVzIiwic3RhdHVzIiwicmVzcG9uc2VTdGF0dXNUZXh0Iiwic3RhdHVzVGV4dCIsImdldFBhcmFtcyIsIm9wdGlvbnMiLCJib2R5IiwiZXIiLCJmZXRjaCIsImdldEhlYWRlcnMiLCJyZXNwb25zZSIsImVudHJpZXMiLCJyZXN1bHQiLCJwYWlyIiwiY29uc29sZSIsIndhcm4iLCJtb25pdG9yRmV0Y2giLCJmZXRjaFJlcXVlc3QiLCJfZmV0Y2giLCJ0aGVuIiwiX3RleHQiLCJ0ZXh0IiwianNvbiIsIl9Qcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImNhbGwiLCJ0eXBlIiwiY2F0Y2giLCJkYXRhIiwibWVzc2FnZSIsIlByb21pc2UiLCJkZWZpbmVQcm9wZXJ0eSIsInNldCIsImdldCIsImtleXMiLCJrZXkiLCJzZXRUaW1lb3V0IiwiZXJyb3IiLCJtb2R1bGUiLCJleHBvcnRzIiwicmVxdWVzdE1vbml0b3IiLCJsaXN0ZW5lciIsImh0dHBJbmZvIiwiRXJyb3IiLCJfaWQiLCJjYW5jZWwiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRCxPO0FDVkE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrREFBMEMsZ0NBQWdDO0FBQzFFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0VBQXdELGtCQUFrQjtBQUMxRTtBQUNBLHlEQUFpRCxjQUFjO0FBQy9EOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBeUMsaUNBQWlDO0FBQzFFLHdIQUFnSCxtQkFBbUIsRUFBRTtBQUNySTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1DQUEyQiwwQkFBMEIsRUFBRTtBQUN2RCx5Q0FBaUMsZUFBZTtBQUNoRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw4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Q0FlQyxPQUFNbEIsQ0FBTixFQUFRO0FBQ1A0QyxZQUFRd0IsS0FBUixDQUFjcEUsQ0FBZDtBQUNEO0FBQ0Y7O0FBRURxRSxPQUFPQyxPQUFQLEdBQWlCQyxjQUFqQjs7QUFFQSxTQUFTQSxjQUFULENBQXlCQyxRQUF6QixFQUFtQztBQUNqQ0EsYUFBV0EsWUFBYTtBQUFBLFdBQVlDLFFBQVo7QUFBQSxHQUF4Qjs7QUFFQSxNQUFJLE9BQU9ELFFBQVAsS0FBb0IsVUFBeEIsRUFBb0M7QUFDbEMsVUFBTSxJQUFJRSxLQUFKLHNDQUFOO0FBQ0Q7O0FBRUQsTUFBSUMsTUFBTXRHLE9BQVY7QUFDQUYsWUFBVXdHLEdBQVYsSUFBaUJILFFBQWpCO0FBQ0EzRixtQkFBa0JDLElBQWxCOztBQUVBLFNBQU87QUFDTDhGLFlBQVEsa0JBQU07QUFDWixhQUFPekcsVUFBVXdHLEdBQVYsQ0FBUDtBQUNEO0FBSEksR0FBUDtBQUtEOztBQUVESixlQUFlMUYsZ0JBQWYsR0FBa0NBLGdCQUFsQyxDIiwiZmlsZSI6InJlcXVlc3QtbW9uaXRvci5qcyIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcInJlcXVlc3RNb25pdG9yXCJdID0gZmFjdG9yeSgpO1xuXHRlbHNlXG5cdFx0cm9vdFtcInJlcXVlc3RNb25pdG9yXCJdID0gZmFjdG9yeSgpO1xufSkod2luZG93LCBmdW5jdGlvbigpIHtcbnJldHVybiAiLCIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gXCIuL3NyYy9pbmRleC5qc1wiKTtcbiIsIi8qKlxuICogXG4gKiBAcGFyYW0geyp9IGxpc3RlbmVyIFxuICogXG5odHRwIEluZm86IHtcbiAgIF9fdHlwZTogXCJmZXRjaFwiLCAgLy8g5L2/55So5bqV5bGC5bqT57G75Z6L77yM5pyJIGZldGNoIOWSjCB4aHJcbiAgIHVybDogXCJcIixcbiAgIG1ldGhvZDogXCJcIixcbiAgIHRpbWVvdXQ6IDAsIC8vIOi2heaXtuaXtumXtFxuICAgcGFyYW1zOiB7fSwgLy8g6K+35rGC5Y+C5pWwXG4gICByZXNwb25zZVN0YXR1czogMjAwLCAgLy8g5aaC5p6c5pivIC0xIO+8jOS7o+ihqOe9kee7nOW8guW4uFxuICAgcmVzcG9uc2VTdGF0dXNUZXh0OiBcIm9rXCIsXG4gICByZXNwb25zZUpzb246IHtcImNvZGVcIjogMH0sXG4gICByZXNwb25zZVRleHQ6IFwie1wiY29kZVwiOiAwfVwiLFxuICAgcmVxdWVzdFRpbWU6IDEwMCwgIOivt+axguaXtumXtO+8jOWNleS9jeS4uiBtc1xufVxuICovXG5cbmNvbnN0IGxpc3RlbmVycyA9IHt9O1xubGV0IGlkID0gMTtcblxuZnVuY3Rpb24gZ2V0SWQgKCkge1xuICByZXR1cm4gaWQrKztcbn1cblxuZnVuY3Rpb24gaGFuZGxlRW5kVGltZShpbmZvKXtcbiAgbGV0IGVuZFRpbWUgPSBuZXcgRGF0ZSAoKS5nZXRUaW1lICgpO1xuICBpbmZvLnJlcXVlc3RUaW1lID0gZW5kVGltZSAtIGluZm8uc3RhcnRUaW1lO1xuICBpbmZvLmVuZFRpbWUgPSBlbmRUaW1lO1xufVxuXG5cbmZ1bmN0aW9uIGhhbmRsZURlZmF1bHRBcGkgKGVtaXQpIHtcbiAgaWYgKHdpbmRvdy5fcmVxdWVzdE1vbml0b3JJc0xvYWQpIHJldHVybiBudWxsO1xuICB3aW5kb3cuX3JlcXVlc3RNb25pdG9ySXNMb2FkID0gdHJ1ZTtcbiAgaGFuZGxlWGhyIChlbWl0KTtcbiAgaGFuZGxlRmV0Y2ggKGVtaXQpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaGFuZGxlSGVhZGVyKHhocikge1xuICB0cnl7XG4gICAgdmFyIGhlYWRlcnMgPSB4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCk7XG4gICAgaWYgKCFoZWFkZXJzKSByZXR1cm47XG4gICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaGVhZGVycztcbiAgICB9XG4gICAgdmFyIG5ld0hlYWRlcnMgPSB7fSwgaGVhZGVycyA9IGhlYWRlcnMuc3BsaXQoL1tcXHJcXG5dLykuZm9yRWFjaChmdW5jdGlvbiAoaGVhZGVyKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGhlYWRlci5pbmRleE9mKFwiOlwiKTtcbiAgICAgICAgdmFyIG5hbWUgPSBoZWFkZXIuc3Vic3RyKDAsIGluZGV4KTtcbiAgICAgICAgdmFyIHZhbHVlID0gaGVhZGVyLnN1YnN0cihpbmRleCArIDIpO1xuICAgICAgICBpZiAobmFtZSkge1xuICAgICAgICAgICAgbmV3SGVhZGVyc1tuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9XG5cbiAgICB9KVxuICAgIHJldHVybiBuZXdIZWFkZXJzO1xuICB9Y2F0Y2goZSl7XG4gICAgcmV0dXJuIHt9XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFuZGxlWGhyIChlbWl0KSB7XG4gIGxldCBfb3BlbiA9IFhNTEh0dHBSZXF1ZXN0LnByb3RvdHlwZS5vcGVuO1xuICBsZXQgX3NlbmQgPSBYTUxIdHRwUmVxdWVzdC5wcm90b3R5cGUuc2VuZDtcbiAgWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgIGNvbnN0IG1ldGhvZCA9IGFyZ3NbMF07XG4gICAgY29uc3QgdXJsID0gYXJnc1sxXTtcbiAgICB0aGlzLl9tb25pdG9yID0ge1xuICAgICAgX190eXBlOiAneGhyJyxcbiAgICB9O1xuICAgIF9vcGVuLmFwcGx5ICh0aGlzLCBhcmdzKTtcbiAgICBPYmplY3QuYXNzaWduICh0aGlzLl9tb25pdG9yLCB7XG4gICAgICBtZXRob2QsXG4gICAgICB1cmwsXG4gICAgfSk7XG4gIH07XG5cbiAgWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgIF9zZW5kLmFwcGx5ICh0aGlzLCBhcmdzKTtcbiAgICB0aGlzLl9tb25pdG9yLnN0YXJ0VGltZSA9IG5ldyBEYXRlICgpLmdldFRpbWUgKCk7XG4gICAgdGhpcy5fbW9uaXRvci50aW1lb3V0ID0gdGhpcy50aW1lb3V0IHx8IDA7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChhcmdzLmxlbmd0aCA+IDAgJiYgdHlwZW9mIGFyZ3NbMF0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMuX21vbml0b3IucGFyYW1zID0gYXJnc1swXTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHt9XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyIChcbiAgICAgICdsb2FkJyxcbiAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IGNvbnRlbnRUeXBlID0gdGhpcy5nZXRSZXNwb25zZUhlYWRlciAoXG4gICAgICAgICAgJ0NvbnRlbnQtVHlwZSdcbiAgICAgICAgKTtcbiAgICAgICAgY29udGVudFR5cGUgPSBjb250ZW50VHlwZSB8fCAnJztcbiAgICAgICAgY29udGVudFR5cGUgPSBjb250ZW50VHlwZS50b0xvd2VyQ2FzZSAoKTtcbiAgICAgICAgY29uc3QgaWdub3JlcyA9IFsnYmxvYicsICdhcnJheWJ1ZmZlcicsICdtb3otY2h1bmtlZC1hcnJheWJ1ZmZlcicsIFwibXMtc3RyZWFtXCJdO1xuICAgICAgICBpZih0aGlzLnJlc3BvbnNlVHlwZSAmJiBpZ25vcmVzLmluZGV4T2YodGhpcy5yZXNwb25zZVR5cGUpID4gLTEpe1xuICAgICAgICAgIHJldHVybjsgLy8gaWdub3JlIGJsb2IgdHlwZVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb250ZW50VHlwZS5pbmRleE9mICgnYXBwbGljYXRpb24vanNvbicpICE9PSAtMSkge1xuICAgICAgICAgIHRoaXMuX21vbml0b3IucmVzcG9uc2VUZXh0ID0gdGhpcy5yZXNwb25zZVRleHQ7XG4gICAgICAgICAgdHJ5e1xuICAgICAgICAgICAgdGhpcy5fbW9uaXRvci5yZXNwb25zZUpzb24gPSBKU09OLnBhcnNlICh0aGlzLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgfWNhdGNoKGUpe31cbiAgICAgICAgICBcbiAgICAgICAgfSBlbHNlIGlmIChjb250ZW50VHlwZS5pbmRleE9mICgndGV4dC9wbGFpbicpICE9PSAtMSkge1xuICAgICAgICAgIHRoaXMuX21vbml0b3IucmVzcG9uc2VUZXh0ID0gdGhpcy5yZXNwb25zZVRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbW9uaXRvci5yZXNwb25zZUhlYWRlcnMgPSBoYW5kbGVIZWFkZXIodGhpcyk7XG4gICAgICAgIHRoaXMuX21vbml0b3IucmVzcG9uc2VTdGF0dXMgPSB0aGlzLnN0YXR1cztcbiAgICAgICAgdGhpcy5fbW9uaXRvci5yZXNwb25zZVN0YXR1c1RleHQgPSB0aGlzLnN0YXR1c1RleHQ7XG4gICAgICAgIGVtaXQgKHRoaXMuX21vbml0b3IpO1xuICAgICAgfSxcbiAgICAgIGZhbHNlXG4gICAgKTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIgKCdlcnJvcicsICgpID0+IHtcbiAgICAgIHRoaXMuX21vbml0b3IucmVzcG9uc2VTdGF0dXNUZXh0ID0gJ1hociBOZXR3b3JrIHJlcXVlc3QgZXhjZXB0aW9uJztcbiAgICAgIHRoaXMuX21vbml0b3IucmVzcG9uc2VTdGF0dXMgPSAtMTtcbiAgICAgIGVtaXQgKHRoaXMuX21vbml0b3IpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyICgndGltZW91dCcsICgpID0+IHtcbiAgICAgIGVtaXQgKHRoaXMuX21vbml0b3IpO1xuICAgIH0pO1xuXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldFBhcmFtcyAob3B0aW9ucykge1xuICBsZXQgcGFyYW1zO1xuICB0cnkge1xuICAgIGlmIChvcHRpb25zLmJvZHkgJiYgdHlwZW9mIG9wdGlvbnMuYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHBhcmFtcyA9IG9wdGlvbnMuYm9keTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVyKSB7fVxuICByZXR1cm4gcGFyYW1zO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVGZXRjaCAoZW1pdCkge1xuICBpZiAod2luZG93LmZldGNoKSB7XG4gICAgY29uc3QgX1Byb21pc2UgPSB3aW5kb3cuZmV0Y2guUHJvbWlzZSB8fCBQcm9taXNlO1xuICAgIGNvbnN0IF9mZXRjaCA9IHdpbmRvdy5mZXRjaDtcblxuICAgIGZ1bmN0aW9uIGdldEhlYWRlcnMocmVzcG9uc2Upe1xuICAgICAgdHJ5e1xuICAgICAgICBsZXQgaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnMuZW50cmllcygpO1xuICAgICAgICBsZXQgcmVzdWx0ID0ge307XG4gICAgICAgIGZvciAodmFyIHBhaXIgb2YgaGVhZGVycykge1xuICAgICAgICAgIHJlc3VsdFtwYWlyWzBdXSA9IHBhaXJbMV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1jYXRjaChlKXtcbiAgICAgICAgY29uc29sZS53YXJuKGUpO1xuICAgICAgICByZXR1cm4ge307XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbW9uaXRvckZldGNoICh1cmwsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgY29uc3QgcGFyYW1zID0gZ2V0UGFyYW1zIChvcHRpb25zKTtcblxuICAgICAgY29uc3QgX21vbml0b3IgPSB7XG4gICAgICAgIF9fdHlwZTogJ2ZldGNoJyxcbiAgICAgICAgdXJsLFxuICAgICAgICBtZXRob2Q6IG9wdGlvbnMubWV0aG9kIHx8ICdHRVQnLFxuICAgICAgICBwYXJhbXMsXG4gICAgICAgIHN0YXJ0VGltZTogbmV3IERhdGUgKCkuZ2V0VGltZSAoKSxcbiAgICAgICAgdGltZW91dDogb3B0aW9ucy50aW1lb3V0IHx8IDBcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGZldGNoUmVxdWVzdCA9IFxuICAgICAgICAvLyBfUHJvbWlzZVxuICAgICAgICAvLyAucmFjZSAoW1xuICAgICAgICAgIFxuICAgICAgICAvLyAgIG5ldyBfUHJvbWlzZSAoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAvLyAgICAgc2V0VGltZW91dCAoKCkgPT4ge1xuICAgICAgICAvLyAgICAgICBsZXQgZXJyID0gbmV3IEVycm9yICgn5YmN56uvZmV0Y2ggTmV0d29yayByZXF1ZXN0IHRpbWVvdXQ6ICcgKyBvcHRpb25zLnRpbWVvdXQpO1xuICAgICAgICAvLyAgICAgICBlcnIuc3RhdHVzID0gNTA0O1xuICAgICAgICAvLyAgICAgICByZWplY3QgKGVycik7XG4gICAgICAgIC8vICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgLy8gICB9KSxcbiAgICAgICAgLy8gXSlcbiAgICAgICAgX2ZldGNoICh1cmwsIG9wdGlvbnMpXG4gICAgICAgIC50aGVuIChyZXNwb25zZSA9PiB7XG4gICAgICAgICAgbGV0IF90ZXh0ID0gcmVzcG9uc2UudGV4dDtcbiAgICAgICAgICBfbW9uaXRvci5yZXNwb25zZVN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cztcbiAgICAgICAgICBfbW9uaXRvci5yZXNwb25zZUhlYWRlcnMgPSBnZXRIZWFkZXJzKHJlc3BvbnNlKVxuICAgICAgICAgIF9tb25pdG9yLnJlc3BvbnNlU3RhdHVzVGV4dCA9IHJlc3BvbnNlLnN0YXR1c1RleHQ7XG4gICAgICAgICAgcmVzcG9uc2UuanNvbiA9ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgX1Byb21pc2UgKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgX3RleHRcbiAgICAgICAgICAgICAgICAuY2FsbCAocmVzcG9uc2UpXG4gICAgICAgICAgICAgICAgLnRoZW4gKHRleHQgPT4ge1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlICh0ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgX21vbml0b3IucmVzcG9uc2VUZXh0ID0gdGV4dDtcbiAgICAgICAgICAgICAgICAgICAgX21vbml0b3IucmVzcG9uc2VKc29uID0ganNvbjtcbiAgICAgICAgICAgICAgICAgICAgZW1pdCAoX21vbml0b3IpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlIChqc29uKTtcbiAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZS50eXBlID0gJ2ludmFsaWQtanNvbic7XG4gICAgICAgICAgICAgICAgICAgIF9tb25pdG9yLnJlc3BvbnNlVGV4dCA9IHRleHQ7XG4gICAgICAgICAgICAgICAgICAgIGVtaXQoX21vbml0b3IpO1xuICAgICAgICAgICAgICAgICAgICByZWplY3QgKGUpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoIChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgcmVqZWN0IChlcnIpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHJlc3BvbnNlLnRleHQgPSAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IF9Qcm9taXNlICgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgIF90ZXh0XG4gICAgICAgICAgICAgICAgLmNhbGwgKHJlc3BvbnNlKVxuICAgICAgICAgICAgICAgIC50aGVuICh0ZXh0ID0+IHtcbiAgICAgICAgICAgICAgICAgIF9tb25pdG9yLnJlc3BvbnNlVGV4dCA9IHRleHQ7XG4gICAgICAgICAgICAgICAgICBlbWl0IChfbW9uaXRvcik7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlICh0ZXh0KTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCAoZXJyID0+IHtcbiAgICAgICAgICAgICAgICAgIHJlamVjdCAoZXJyKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbmV3IF9Qcm9taXNlICgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGZldGNoUmVxdWVzdFxuICAgICAgICAgIC50aGVuIChkYXRhID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUgKGRhdGEpO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmNhdGNoIChlcnIgPT4ge1xuICAgICAgICAgICAgX21vbml0b3IucmVzcG9uc2VTdGF0dXMgPSBlcnIuc3RhdHVzIHx8IC0xO1xuICAgICAgICAgICAgX21vbml0b3IucmVzcG9uc2VUZXh0ID0gZXJyLm1lc3NhZ2UgfHwgJ0ZldGNoIE5ldHdvcmsgcmVxdWVzdCBleGNlcHRpb24nO1xuICAgICAgICAgICAgZW1pdCAoX21vbml0b3IpO1xuICAgICAgICAgICAgcmVqZWN0IChlcnIpO1xuICAgICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZmV0Y2hSZXF1ZXN0O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbW9uaXRvckZldGNoLlByb21pc2UgPSBfUHJvbWlzZTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSAobW9uaXRvckZldGNoLCAnUHJvbWlzZScsIHtcbiAgICAgIHNldCAodmFsdWUpIHtcbiAgICAgICAgLy8gbW9uaXRvckZldGNoLlByb21pc2UgPSB2YWx1ZTtcbiAgICAgICAgX2ZldGNoLlByb21pc2UgPSB2YWx1ZTtcbiAgICAgIH0sXG4gICAgICBnZXQgKCkge1xuICAgICAgICByZXR1cm4gX2ZldGNoLlByb21pc2U7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgd2luZG93LmZldGNoID0gbW9uaXRvckZldGNoO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXQgKGluZm8pIHtcbiAgaGFuZGxlRW5kVGltZShpbmZvKVxuICB0cnl7XG4gICAgT2JqZWN0LmtleXMgKGluZm8pLmZvckVhY2ggKGtleSA9PiB7XG4gICAgICBpZiAodHlwZW9mIGluZm9ba2V5XSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgZGVsZXRlIGluZm9ba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3Qua2V5cyAobGlzdGVuZXJzKS5mb3JFYWNoIChrZXkgPT4ge1xuICAgICAgc2V0VGltZW91dCgoKT0+IHtcbiAgICAgICAgdHJ5e1xuICAgICAgICAgIGxpc3RlbmVyc1trZXldIChpbmZvKVxuICAgICAgICB9Y2F0Y2goZXJyKXtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycilcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9KTtcbiAgfWNhdGNoKGUpe1xuICAgIGNvbnNvbGUuZXJyb3IoZSlcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVlc3RNb25pdG9yO1xuXG5mdW5jdGlvbiByZXF1ZXN0TW9uaXRvciAobGlzdGVuZXIpIHtcbiAgbGlzdGVuZXIgPSBsaXN0ZW5lciB8fCAoaHR0cEluZm8gPT4gaHR0cEluZm8pO1xuXG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IgKGBUaGUgbGlzdGVuZXIgVHlwZSBtdXN0IGJlIGZ1bmN0aW9uYCk7XG4gIH1cblxuICBsZXQgX2lkID0gZ2V0SWQgKCk7XG4gIGxpc3RlbmVyc1tfaWRdID0gbGlzdGVuZXI7XG4gIGhhbmRsZURlZmF1bHRBcGkgKGVtaXQpO1xuXG4gIHJldHVybiB7XG4gICAgY2FuY2VsOiAoKSA9PiB7XG4gICAgICBkZWxldGUgbGlzdGVuZXJzW19pZF07XG4gICAgfSxcbiAgfTtcbn1cblxucmVxdWVzdE1vbml0b3IuaGFuZGxlRGVmYXVsdEFwaSA9IGhhbmRsZURlZmF1bHRBcGk7XG4iXSwic291cmNlUm9vdCI6IiJ9