From c5c800077c308a297c7efc39b19f393867fd3a25 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Sat, 28 Feb 2026 13:38:48 -0800 Subject: [PATCH] feat(web): add routine preview timeline in editor - Visual horizontal bar chart showing step durations proportionally - Color-coded segments with golden-angle hue distribution - Time markers (start/end) and step legend - Updates live as steps are added, removed, or reordered --- web/public/sw.js | 220 --------------------------- web/src/components/RoutineEditor.tsx | 80 ++++++++++ 2 files changed, 80 insertions(+), 220 deletions(-) diff --git a/web/public/sw.js b/web/public/sw.js index 5888d43..e69de29 100644 --- a/web/public/sw.js +++ b/web/public/sw.js @@ -1,220 +0,0 @@ -/* - * ATTENTION: An "eval-source-map" devtool has been used. - * This devtool is neither made for production nor for readable output files. - * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. - * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) - * or disable the default devtool with "devtool: false". - * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). - */ -/******/ (() => { // webpackBootstrap -/******/ "use strict"; -/******/ var __webpack_modules__ = ({ - -/***/ "./node_modules/@serwist/next/dist/index.worker.js": -/*!*********************************************************!*\ - !*** ./node_modules/@serwist/next/dist/index.worker.js ***! - \*********************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ PAGES_CACHE_NAME: () => (/* binding */ PAGES_CACHE_NAME),\n/* harmony export */ defaultCache: () => (/* binding */ defaultCache)\n/* harmony export */ });\n/* harmony import */ var serwist__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! serwist */ \"./node_modules/serwist/dist/index.js\");\n\n\nconst PAGES_CACHE_NAME = {\n rscPrefetch: \"pages-rsc-prefetch\",\n rsc: \"pages-rsc\",\n html: \"pages\"\n};\nconst defaultCache = true ? [\n {\n matcher: /.*/i,\n handler: new serwist__WEBPACK_IMPORTED_MODULE_0__.NetworkOnly()\n }\n] : 0;\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQHNlcndpc3QvbmV4dC9kaXN0L2luZGV4Lndvcmtlci5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7QUFBNkg7O0FBRTdIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsS0FBcUM7QUFDMUQ7QUFDQTtBQUNBLHFCQUFxQixnREFBVztBQUNoQztBQUNBLElBQUksQ0FzUEg7O0FBRXlDIiwic291cmNlcyI6WyIvVXNlcnMvc2Q5MjM1L2NvZGUvbXlnaC9sZWFybmluZ19haV9jbG9jay93ZWIvbm9kZV9tb2R1bGVzL0BzZXJ3aXN0L25leHQvZGlzdC9pbmRleC53b3JrZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmV0d29ya09ubHksIENhY2hlRmlyc3QsIFN0YWxlV2hpbGVSZXZhbGlkYXRlLCBOZXR3b3JrRmlyc3QsIEV4cGlyYXRpb25QbHVnaW4sIFJhbmdlUmVxdWVzdHNQbHVnaW4gfSBmcm9tICdzZXJ3aXN0JztcblxuY29uc3QgUEFHRVNfQ0FDSEVfTkFNRSA9IHtcbiAgICByc2NQcmVmZXRjaDogXCJwYWdlcy1yc2MtcHJlZmV0Y2hcIixcbiAgICByc2M6IFwicGFnZXMtcnNjXCIsXG4gICAgaHRtbDogXCJwYWdlc1wiXG59O1xuY29uc3QgZGVmYXVsdENhY2hlID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiID8gW1xuICAgIHtcbiAgICAgICAgbWF0Y2hlcjogLy4qL2ksXG4gICAgICAgIGhhbmRsZXI6IG5ldyBOZXR3b3JrT25seSgpXG4gICAgfVxuXSA6IFtcbiAgICB7XG4gICAgICAgIG1hdGNoZXI6IC9eaHR0cHM6XFwvXFwvZm9udHNcXC4oPzpnc3RhdGljKVxcLmNvbVxcLy4qL2ksXG4gICAgICAgIGhhbmRsZXI6IG5ldyBDYWNoZUZpcnN0KHtcbiAgICAgICAgICAgIGNhY2hlTmFtZTogXCJnb29nbGUtZm9udHMtd2ViZm9udHNcIixcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDQsXG4gICAgICAgICAgICAgICAgICAgIG1heEFnZVNlY29uZHM6IDM2NSAqIDI0ICogNjAgKiA2MCxcbiAgICAgICAgICAgICAgICAgICAgbWF4QWdlRnJvbTogXCJsYXN0LXVzZWRcIlxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pXG4gICAgfSxcbiAgICB7XG4gICAgICAgIG1hdGNoZXI6IC9eaHR0cHM6XFwvXFwvZm9udHNcXC4oPzpnb29nbGVhcGlzKVxcLmNvbVxcLy4qL2ksXG4gICAgICAgIGhhbmRsZXI6IG5ldyBTdGFsZVdoaWxlUmV2YWxpZGF0ZSh7XG4gICAgICAgICAgICBjYWNoZU5hbWU6IFwiZ29vZ2xlLWZvbnRzLXN0eWxlc2hlZXRzXCIsXG4gICAgICAgICAgICBwbHVnaW5zOiBbXG4gICAgICAgICAgICAgICAgbmV3IEV4cGlyYXRpb25QbHVnaW4oe1xuICAgICAgICAgICAgICAgICAgICBtYXhFbnRyaWVzOiA0LFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzOiA3ICogMjQgKiA2MCAqIDYwLFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VGcm9tOiBcImxhc3QtdXNlZFwiXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIF1cbiAgICAgICAgfSlcbiAgICB9LFxuICAgIHtcbiAgICAgICAgbWF0Y2hlcjogL1xcLig/OmVvdHxvdGZ8dHRjfHR0Znx3b2ZmfHdvZmYyfGZvbnQuY3NzKSQvaSxcbiAgICAgICAgaGFuZGxlcjogbmV3IFN0YWxlV2hpbGVSZXZhbGlkYXRlKHtcbiAgICAgICAgICAgIGNhY2hlTmFtZTogXCJzdGF0aWMtZm9udC1hc3NldHNcIixcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDQsXG4gICAgICAgICAgICAgICAgICAgIG1heEFnZVNlY29uZHM6IDcgKiAyNCAqIDYwICogNjAsXG4gICAgICAgICAgICAgICAgICAgIG1heEFnZUZyb206IFwibGFzdC11c2VkXCJcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXVxuICAgICAgICB9KVxuICAgIH0sXG4gICAge1xuICAgICAgICBtYXRjaGVyOiAvXFwuKD86anBnfGpwZWd8Z2lmfHBuZ3xzdmd8aWNvfHdlYnApJC9pLFxuICAgICAgICBoYW5kbGVyOiBuZXcgU3RhbGVXaGlsZVJldmFsaWRhdGUoe1xuICAgICAgICAgICAgY2FjaGVOYW1lOiBcInN0YXRpYy1pbWFnZS1hc3NldHNcIixcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDY0LFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzOiAzMCAqIDI0ICogNjAgKiA2MCxcbiAgICAgICAgICAgICAgICAgICAgbWF4QWdlRnJvbTogXCJsYXN0LXVzZWRcIlxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pXG4gICAgfSxcbiAgICB7XG4gICAgICAgIG1hdGNoZXI6IC9cXC9fbmV4dFxcL3N0YXRpYy4rXFwuanMkL2ksXG4gICAgICAgIGhhbmRsZXI6IG5ldyBDYWNoZUZpcnN0KHtcbiAgICAgICAgICAgIGNhY2hlTmFtZTogXCJuZXh0LXN0YXRpYy1qcy1hc3NldHNcIixcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDY0LFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzOiAyNCAqIDYwICogNjAsXG4gICAgICAgICAgICAgICAgICAgIG1heEFnZUZyb206IFwibGFzdC11c2VkXCJcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXVxuICAgICAgICB9KVxuICAgIH0sXG4gICAge1xuICAgICAgICBtYXRjaGVyOiAvXFwvX25leHRcXC9pbWFnZVxcP3VybD0uKyQvaSxcbiAgICAgICAgaGFuZGxlcjogbmV3IFN0YWxlV2hpbGVSZXZhbGlkYXRlKHtcbiAgICAgICAgICAgIGNhY2hlTmFtZTogXCJuZXh0LWltYWdlXCIsXG4gICAgICAgICAgICBwbHVnaW5zOiBbXG4gICAgICAgICAgICAgICAgbmV3IEV4cGlyYXRpb25QbHVnaW4oe1xuICAgICAgICAgICAgICAgICAgICBtYXhFbnRyaWVzOiA2NCxcbiAgICAgICAgICAgICAgICAgICAgbWF4QWdlU2Vjb25kczogMjQgKiA2MCAqIDYwLFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VGcm9tOiBcImxhc3QtdXNlZFwiXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIF1cbiAgICAgICAgfSlcbiAgICB9LFxuICAgIHtcbiAgICAgICAgbWF0Y2hlcjogL1xcLig/Om1wM3x3YXZ8b2dnKSQvaSxcbiAgICAgICAgaGFuZGxlcjogbmV3IENhY2hlRmlyc3Qoe1xuICAgICAgICAgICAgY2FjaGVOYW1lOiBcInN0YXRpYy1hdWRpby1hc3NldHNcIixcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDMyLFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzOiAyNCAqIDYwICogNjAsXG4gICAgICAgICAgICAgICAgICAgIG1heEFnZUZyb206IFwibGFzdC11c2VkXCJcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBuZXcgUmFuZ2VSZXF1ZXN0c1BsdWdpbigpXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pXG4gICAgfSxcbiAgICB7XG4gICAgICAgIG1hdGNoZXI6IC9cXC4oPzptcDR8d2VibSkkL2ksXG4gICAgICAgIGhhbmRsZXI6IG5ldyBDYWNoZUZpcnN0KHtcbiAgICAgICAgICAgIGNhY2hlTmFtZTogXCJzdGF0aWMtdmlkZW8tYXNzZXRzXCIsXG4gICAgICAgICAgICBwbHVnaW5zOiBbXG4gICAgICAgICAgICAgICAgbmV3IEV4cGlyYXRpb25QbHVnaW4oe1xuICAgICAgICAgICAgICAgICAgICBtYXhFbnRyaWVzOiAzMixcbiAgICAgICAgICAgICAgICAgICAgbWF4QWdlU2Vjb25kczogMjQgKiA2MCAqIDYwLFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VGcm9tOiBcImxhc3QtdXNlZFwiXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgbmV3IFJhbmdlUmVxdWVzdHNQbHVnaW4oKVxuICAgICAgICAgICAgXVxuICAgICAgICB9KVxuICAgIH0sXG4gICAge1xuICAgICAgICBtYXRjaGVyOiAvXFwuKD86anMpJC9pLFxuICAgICAgICBoYW5kbGVyOiBuZXcgU3RhbGVXaGlsZVJldmFsaWRhdGUoe1xuICAgICAgICAgICAgY2FjaGVOYW1lOiBcInN0YXRpYy1qcy1hc3NldHNcIixcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDQ4LFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzOiAyNCAqIDYwICogNjAsXG4gICAgICAgICAgICAgICAgICAgIG1heEFnZUZyb206IFwibGFzdC11c2VkXCJcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXVxuICAgICAgICB9KVxuICAgIH0sXG4gICAge1xuICAgICAgICBtYXRjaGVyOiAvXFwuKD86Y3NzfGxlc3MpJC9pLFxuICAgICAgICBoYW5kbGVyOiBuZXcgU3RhbGVXaGlsZVJldmFsaWRhdGUoe1xuICAgICAgICAgICAgY2FjaGVOYW1lOiBcInN0YXRpYy1zdHlsZS1hc3NldHNcIixcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDMyLFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzOiAyNCAqIDYwICogNjAsXG4gICAgICAgICAgICAgICAgICAgIG1heEFnZUZyb206IFwibGFzdC11c2VkXCJcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXVxuICAgICAgICB9KVxuICAgIH0sXG4gICAge1xuICAgICAgICBtYXRjaGVyOiAvXFwvX25leHRcXC9kYXRhXFwvLitcXC8uK1xcLmpzb24kL2ksXG4gICAgICAgIGhhbmRsZXI6IG5ldyBOZXR3b3JrRmlyc3Qoe1xuICAgICAgICAgICAgY2FjaGVOYW1lOiBcIm5leHQtZGF0YVwiLFxuICAgICAgICAgICAgcGx1Z2luczogW1xuICAgICAgICAgICAgICAgIG5ldyBFeHBpcmF0aW9uUGx1Z2luKHtcbiAgICAgICAgICAgICAgICAgICAgbWF4RW50cmllczogMzIsXG4gICAgICAgICAgICAgICAgICAgIG1heEFnZVNlY29uZHM6IDI0ICogNjAgKiA2MCxcbiAgICAgICAgICAgICAgICAgICAgbWF4QWdlRnJvbTogXCJsYXN0LXVzZWRcIlxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pXG4gICAgfSxcbiAgICB7XG4gICAgICAgIG1hdGNoZXI6IC9cXC4oPzpqc29ufHhtbHxjc3YpJC9pLFxuICAgICAgICBoYW5kbGVyOiBuZXcgTmV0d29ya0ZpcnN0KHtcbiAgICAgICAgICAgIGNhY2hlTmFtZTogXCJzdGF0aWMtZGF0YS1hc3NldHNcIixcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDMyLFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzOiAyNCAqIDYwICogNjAsXG4gICAgICAgICAgICAgICAgICAgIG1heEFnZUZyb206IFwibGFzdC11c2VkXCJcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXVxuICAgICAgICB9KVxuICAgIH0sXG4gICAge1xuICAgICAgICBtYXRjaGVyOiAvXFwvYXBpXFwvYXV0aFxcLy4qLyxcbiAgICAgICAgaGFuZGxlcjogbmV3IE5ldHdvcmtPbmx5KHtcbiAgICAgICAgICAgIG5ldHdvcmtUaW1lb3V0U2Vjb25kczogMTBcbiAgICAgICAgfSlcbiAgICB9LFxuICAgIHtcbiAgICAgICAgbWF0Y2hlcjogKHsgc2FtZU9yaWdpbiwgdXJsOiB7IHBhdGhuYW1lIH0gfSk9PnNhbWVPcmlnaW4gJiYgcGF0aG5hbWUuc3RhcnRzV2l0aChcIi9hcGkvXCIpLFxuICAgICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICAgIGhhbmRsZXI6IG5ldyBOZXR3b3JrRmlyc3Qoe1xuICAgICAgICAgICAgY2FjaGVOYW1lOiBcImFwaXNcIixcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDE2LFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzOiAyNCAqIDYwICogNjAsXG4gICAgICAgICAgICAgICAgICAgIG1heEFnZUZyb206IFwibGFzdC11c2VkXCJcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIG5ldHdvcmtUaW1lb3V0U2Vjb25kczogMTBcbiAgICAgICAgfSlcbiAgICB9LFxuICAgIHtcbiAgICAgICAgbWF0Y2hlcjogKHsgcmVxdWVzdCwgdXJsOiB7IHBhdGhuYW1lIH0sIHNhbWVPcmlnaW4gfSk9PnJlcXVlc3QuaGVhZGVycy5nZXQoXCJSU0NcIikgPT09IFwiMVwiICYmIHJlcXVlc3QuaGVhZGVycy5nZXQoXCJOZXh0LVJvdXRlci1QcmVmZXRjaFwiKSA9PT0gXCIxXCIgJiYgc2FtZU9yaWdpbiAmJiAhcGF0aG5hbWUuc3RhcnRzV2l0aChcIi9hcGkvXCIpLFxuICAgICAgICBoYW5kbGVyOiBuZXcgTmV0d29ya0ZpcnN0KHtcbiAgICAgICAgICAgIGNhY2hlTmFtZTogUEFHRVNfQ0FDSEVfTkFNRS5yc2NQcmVmZXRjaCxcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDMyLFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzOiAyNCAqIDYwICogNjBcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXVxuICAgICAgICB9KVxuICAgIH0sXG4gICAge1xuICAgICAgICBtYXRjaGVyOiAoeyByZXF1ZXN0LCB1cmw6IHsgcGF0aG5hbWUgfSwgc2FtZU9yaWdpbiB9KT0+cmVxdWVzdC5oZWFkZXJzLmdldChcIlJTQ1wiKSA9PT0gXCIxXCIgJiYgc2FtZU9yaWdpbiAmJiAhcGF0aG5hbWUuc3RhcnRzV2l0aChcIi9hcGkvXCIpLFxuICAgICAgICBoYW5kbGVyOiBuZXcgTmV0d29ya0ZpcnN0KHtcbiAgICAgICAgICAgIGNhY2hlTmFtZTogUEFHRVNfQ0FDSEVfTkFNRS5yc2MsXG4gICAgICAgICAgICBwbHVnaW5zOiBbXG4gICAgICAgICAgICAgICAgbmV3IEV4cGlyYXRpb25QbHVnaW4oe1xuICAgICAgICAgICAgICAgICAgICBtYXhFbnRyaWVzOiAzMixcbiAgICAgICAgICAgICAgICAgICAgbWF4QWdlU2Vjb25kczogMjQgKiA2MCAqIDYwXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIF1cbiAgICAgICAgfSlcbiAgICB9LFxuICAgIHtcbiAgICAgICAgbWF0Y2hlcjogKHsgcmVxdWVzdCwgdXJsOiB7IHBhdGhuYW1lIH0sIHNhbWVPcmlnaW4gfSk9PnJlcXVlc3QuaGVhZGVycy5nZXQoXCJDb250ZW50LVR5cGVcIik/LmluY2x1ZGVzKFwidGV4dC9odG1sXCIpICYmIHNhbWVPcmlnaW4gJiYgIXBhdGhuYW1lLnN0YXJ0c1dpdGgoXCIvYXBpL1wiKSxcbiAgICAgICAgaGFuZGxlcjogbmV3IE5ldHdvcmtGaXJzdCh7XG4gICAgICAgICAgICBjYWNoZU5hbWU6IFBBR0VTX0NBQ0hFX05BTUUuaHRtbCxcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDMyLFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzOiAyNCAqIDYwICogNjBcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXVxuICAgICAgICB9KVxuICAgIH0sXG4gICAge1xuICAgICAgICBtYXRjaGVyOiAoeyB1cmw6IHsgcGF0aG5hbWUgfSwgc2FtZU9yaWdpbiB9KT0+c2FtZU9yaWdpbiAmJiAhcGF0aG5hbWUuc3RhcnRzV2l0aChcIi9hcGkvXCIpLFxuICAgICAgICBoYW5kbGVyOiBuZXcgTmV0d29ya0ZpcnN0KHtcbiAgICAgICAgICAgIGNhY2hlTmFtZTogXCJvdGhlcnNcIixcbiAgICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgICAgICBuZXcgRXhwaXJhdGlvblBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIG1heEVudHJpZXM6IDMyLFxuICAgICAgICAgICAgICAgICAgICBtYXhBZ2VTZWNvbmRzOiAyNCAqIDYwICogNjBcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXVxuICAgICAgICB9KVxuICAgIH0sXG4gICAge1xuICAgICAgICBtYXRjaGVyOiAoeyBzYW1lT3JpZ2luIH0pPT4hc2FtZU9yaWdpbixcbiAgICAgICAgaGFuZGxlcjogbmV3IE5ldHdvcmtGaXJzdCh7XG4gICAgICAgICAgICBjYWNoZU5hbWU6IFwiY3Jvc3Mtb3JpZ2luXCIsXG4gICAgICAgICAgICBwbHVnaW5zOiBbXG4gICAgICAgICAgICAgICAgbmV3IEV4cGlyYXRpb25QbHVnaW4oe1xuICAgICAgICAgICAgICAgICAgICBtYXhFbnRyaWVzOiAzMixcbiAgICAgICAgICAgICAgICAgICAgbWF4QWdlU2Vjb25kczogNjAgKiA2MFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgbmV0d29ya1RpbWVvdXRTZWNvbmRzOiAxMFxuICAgICAgICB9KVxuICAgIH0sXG4gICAge1xuICAgICAgICBtYXRjaGVyOiAvLiovaSxcbiAgICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgICBoYW5kbGVyOiBuZXcgTmV0d29ya09ubHkoKVxuICAgIH1cbl07XG5cbmV4cG9ydCB7IFBBR0VTX0NBQ0hFX05BTUUsIGRlZmF1bHRDYWNoZSB9O1xuIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6WzBdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/@serwist/next/dist/index.worker.js\n")); - -/***/ }), - -/***/ "./node_modules/@serwist/utils/dist/index.js": -/*!***************************************************!*\ - !*** ./node_modules/@serwist/utils/dist/index.js ***! - \***************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SUPPORTED_ESBUILD_TARGETS: () => (/* binding */ SUPPORTED_ESBUILD_TARGETS),\n/* harmony export */ UNSUPPORTED_BROWSERLIST_TARGETS: () => (/* binding */ UNSUPPORTED_BROWSERLIST_TARGETS),\n/* harmony export */ browserslistToEsbuild: () => (/* binding */ browserslistToEsbuild),\n/* harmony export */ compare: () => (/* binding */ compare),\n/* harmony export */ compareSemver: () => (/* binding */ compareSemver),\n/* harmony export */ nonNullable: () => (/* binding */ nonNullable),\n/* harmony export */ parallel: () => (/* binding */ parallel),\n/* harmony export */ toUnix: () => (/* binding */ toUnix)\n/* harmony export */ });\nconst nonNullable = (value)=>value !== null && value !== undefined;\n\nconst parallel = async (limit, array, func)=>{\n const work = array.map((item, index)=>({\n index,\n item\n }));\n const processor = async (res)=>{\n const results = [];\n while(true){\n const next = work.pop();\n if (!next) {\n return res(results);\n }\n const result = await func(next.item);\n results.push({\n result: result,\n index: next.index\n });\n }\n };\n const queues = Array.from({\n length: limit\n }, ()=>new Promise(processor));\n const results = (await Promise.all(queues)).flat().sort((a, b)=>a.index < b.index ? -1 : 1).map((res)=>res.result);\n return results;\n};\n\nconst toUnix = (p)=>p.replace(/\\\\/g, \"/\").replace(/(?{\n if (a < b) return -1;\n if (a > b) return 1;\n return 0;\n};\n\nconst SUPPORTED_ESBUILD_TARGETS = [\n \"chrome\",\n \"deno\",\n \"edge\",\n \"firefox\",\n \"hermes\",\n \"ie\",\n \"ios\",\n \"node\",\n \"opera\",\n \"rhino\",\n \"safari\"\n];\nconst UNSUPPORTED_BROWSERLIST_TARGETS = [\n \"android 4\",\n \"android 3\",\n \"android 2\"\n];\n\nconst compareSemver = (a, b)=>{\n return compare(Number.parseInt(a[0], 10), Number.parseInt(b[0], 10)) || compare(Number.parseInt(a[1] || \"0\", 10), Number.parseInt(b[1] || \"0\", 10)) || compare(Number.parseInt(a[2] || \"0\", 10), Number.parseInt(b[2] || \"0\", 10));\n};\n\nconst browserslistToEsbuild = (browserslist, cwd, defaultBrowserslist)=>{\n const browserslistConfig = browserslist.loadConfig({\n path: cwd\n }) ?? defaultBrowserslist;\n return browserslist(browserslistConfig).filter((query)=>!UNSUPPORTED_BROWSERLIST_TARGETS.some((target)=>query.startsWith(target))).map((query)=>{\n const modified = query === \"safari TP\" ? browserslist(\"last 1 safari version\")[0] : query;\n const split = modified.split(\" \");\n if (split[0] === \"android\" || split[0] === \"and_chr\") {\n split[0] = \"chrome\";\n }\n if (split[0] === \"and_ff\") {\n split[0] = \"firefox\";\n }\n if (split[0] === \"ios_saf\" || split[0] === \"ios\") {\n split[0] = \"safari\";\n }\n if (split[1].includes(\"-\")) {\n split[1] = split[1].slice(0, split[1].indexOf(\"-\"));\n }\n if (split[1].endsWith(\".0\")) {\n split[1] = split[1].slice(0, -2);\n }\n return split;\n }).filter((split)=>SUPPORTED_ESBUILD_TARGETS.includes(split[0]) && /^\\d+(\\.\\d+)*$/.test(split[1])).sort((a, b)=>{\n if (a[0] === b[0]) {\n return compareSemver(b[1].split(\".\"), a[1].split(\".\"));\n } else {\n return compare(a[0], b[0]);\n }\n }).reduce((acc, browser)=>{\n const existingIndex = acc.findIndex((br)=>br[0] === browser[0]);\n if (existingIndex !== -1) {\n acc[existingIndex][1] = browser[1];\n } else {\n acc.push(browser);\n }\n return acc;\n }, []).map((split)=>split.join(\"\"));\n};\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQHNlcndpc3QvdXRpbHMvZGlzdC9pbmRleC5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRW9KIiwic291cmNlcyI6WyIvVXNlcnMvc2Q5MjM1L2NvZGUvbXlnaC9sZWFybmluZ19haV9jbG9jay93ZWIvbm9kZV9tb2R1bGVzL0BzZXJ3aXN0L3V0aWxzL2Rpc3QvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3Qgbm9uTnVsbGFibGUgPSAodmFsdWUpPT52YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkO1xuXG5jb25zdCBwYXJhbGxlbCA9IGFzeW5jIChsaW1pdCwgYXJyYXksIGZ1bmMpPT57XG4gICAgY29uc3Qgd29yayA9IGFycmF5Lm1hcCgoaXRlbSwgaW5kZXgpPT4oe1xuICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICBpdGVtXG4gICAgICAgIH0pKTtcbiAgICBjb25zdCBwcm9jZXNzb3IgPSBhc3luYyAocmVzKT0+e1xuICAgICAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgICAgIHdoaWxlKHRydWUpe1xuICAgICAgICAgICAgY29uc3QgbmV4dCA9IHdvcmsucG9wKCk7XG4gICAgICAgICAgICBpZiAoIW5leHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzKHJlc3VsdHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZnVuYyhuZXh0Lml0ZW0pO1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHtcbiAgICAgICAgICAgICAgICByZXN1bHQ6IHJlc3VsdCxcbiAgICAgICAgICAgICAgICBpbmRleDogbmV4dC5pbmRleFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IHF1ZXVlcyA9IEFycmF5LmZyb20oe1xuICAgICAgICBsZW5ndGg6IGxpbWl0XG4gICAgfSwgKCk9Pm5ldyBQcm9taXNlKHByb2Nlc3NvcikpO1xuICAgIGNvbnN0IHJlc3VsdHMgPSAoYXdhaXQgUHJvbWlzZS5hbGwocXVldWVzKSkuZmxhdCgpLnNvcnQoKGEsIGIpPT5hLmluZGV4IDwgYi5pbmRleCA/IC0xIDogMSkubWFwKChyZXMpPT5yZXMucmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbn07XG5cbmNvbnN0IHRvVW5peCA9IChwKT0+cC5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKS5yZXBsYWNlKC8oPzwhXilcXC8rL2csIFwiL1wiKTtcblxuY29uc3QgY29tcGFyZSA9IChhLCBiKT0+e1xuICAgIGlmIChhIDwgYikgcmV0dXJuIC0xO1xuICAgIGlmIChhID4gYikgcmV0dXJuIDE7XG4gICAgcmV0dXJuIDA7XG59O1xuXG5jb25zdCBTVVBQT1JURURfRVNCVUlMRF9UQVJHRVRTID0gW1xuICAgIFwiY2hyb21lXCIsXG4gICAgXCJkZW5vXCIsXG4gICAgXCJlZGdlXCIsXG4gICAgXCJmaXJlZm94XCIsXG4gICAgXCJoZXJtZXNcIixcbiAgICBcImllXCIsXG4gICAgXCJpb3NcIixcbiAgICBcIm5vZGVcIixcbiAgICBcIm9wZXJhXCIsXG4gICAgXCJyaGlub1wiLFxuICAgIFwic2FmYXJpXCJcbl07XG5jb25zdCBVTlNVUFBPUlRFRF9CUk9XU0VSTElTVF9UQVJHRVRTID0gW1xuICAgIFwiYW5kcm9pZCA0XCIsXG4gICAgXCJhbmRyb2lkIDNcIixcbiAgICBcImFuZHJvaWQgMlwiXG5dO1xuXG5jb25zdCBjb21wYXJlU2VtdmVyID0gKGEsIGIpPT57XG4gICAgcmV0dXJuIGNvbXBhcmUoTnVtYmVyLnBhcnNlSW50KGFbMF0sIDEwKSwgTnVtYmVyLnBhcnNlSW50KGJbMF0sIDEwKSkgfHwgY29tcGFyZShOdW1iZXIucGFyc2VJbnQoYVsxXSB8fCBcIjBcIiwgMTApLCBOdW1iZXIucGFyc2VJbnQoYlsxXSB8fCBcIjBcIiwgMTApKSB8fCBjb21wYXJlKE51bWJlci5wYXJzZUludChhWzJdIHx8IFwiMFwiLCAxMCksIE51bWJlci5wYXJzZUludChiWzJdIHx8IFwiMFwiLCAxMCkpO1xufTtcblxuY29uc3QgYnJvd3NlcnNsaXN0VG9Fc2J1aWxkID0gKGJyb3dzZXJzbGlzdCwgY3dkLCBkZWZhdWx0QnJvd3NlcnNsaXN0KT0+e1xuICAgIGNvbnN0IGJyb3dzZXJzbGlzdENvbmZpZyA9IGJyb3dzZXJzbGlzdC5sb2FkQ29uZmlnKHtcbiAgICAgICAgcGF0aDogY3dkXG4gICAgfSkgPz8gZGVmYXVsdEJyb3dzZXJzbGlzdDtcbiAgICByZXR1cm4gYnJvd3NlcnNsaXN0KGJyb3dzZXJzbGlzdENvbmZpZykuZmlsdGVyKChxdWVyeSk9PiFVTlNVUFBPUlRFRF9CUk9XU0VSTElTVF9UQVJHRVRTLnNvbWUoKHRhcmdldCk9PnF1ZXJ5LnN0YXJ0c1dpdGgodGFyZ2V0KSkpLm1hcCgocXVlcnkpPT57XG4gICAgICAgIGNvbnN0IG1vZGlmaWVkID0gcXVlcnkgPT09IFwic2FmYXJpIFRQXCIgPyBicm93c2Vyc2xpc3QoXCJsYXN0IDEgc2FmYXJpIHZlcnNpb25cIilbMF0gOiBxdWVyeTtcbiAgICAgICAgY29uc3Qgc3BsaXQgPSBtb2RpZmllZC5zcGxpdChcIiBcIik7XG4gICAgICAgIGlmIChzcGxpdFswXSA9PT0gXCJhbmRyb2lkXCIgfHwgc3BsaXRbMF0gPT09IFwiYW5kX2NoclwiKSB7XG4gICAgICAgICAgICBzcGxpdFswXSA9IFwiY2hyb21lXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNwbGl0WzBdID09PSBcImFuZF9mZlwiKSB7XG4gICAgICAgICAgICBzcGxpdFswXSA9IFwiZmlyZWZveFwiO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzcGxpdFswXSA9PT0gXCJpb3Nfc2FmXCIgfHwgc3BsaXRbMF0gPT09IFwiaW9zXCIpIHtcbiAgICAgICAgICAgIHNwbGl0WzBdID0gXCJzYWZhcmlcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3BsaXRbMV0uaW5jbHVkZXMoXCItXCIpKSB7XG4gICAgICAgICAgICBzcGxpdFsxXSA9IHNwbGl0WzFdLnNsaWNlKDAsIHNwbGl0WzFdLmluZGV4T2YoXCItXCIpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3BsaXRbMV0uZW5kc1dpdGgoXCIuMFwiKSkge1xuICAgICAgICAgICAgc3BsaXRbMV0gPSBzcGxpdFsxXS5zbGljZSgwLCAtMik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNwbGl0O1xuICAgIH0pLmZpbHRlcigoc3BsaXQpPT5TVVBQT1JURURfRVNCVUlMRF9UQVJHRVRTLmluY2x1ZGVzKHNwbGl0WzBdKSAmJiAvXlxcZCsoXFwuXFxkKykqJC8udGVzdChzcGxpdFsxXSkpLnNvcnQoKGEsIGIpPT57XG4gICAgICAgIGlmIChhWzBdID09PSBiWzBdKSB7XG4gICAgICAgICAgICByZXR1cm4gY29tcGFyZVNlbXZlcihiWzFdLnNwbGl0KFwiLlwiKSwgYVsxXS5zcGxpdChcIi5cIikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmUoYVswXSwgYlswXSk7XG4gICAgICAgIH1cbiAgICB9KS5yZWR1Y2UoKGFjYywgYnJvd3Nlcik9PntcbiAgICAgICAgY29uc3QgZXhpc3RpbmdJbmRleCA9IGFjYy5maW5kSW5kZXgoKGJyKT0+YnJbMF0gPT09IGJyb3dzZXJbMF0pO1xuICAgICAgICBpZiAoZXhpc3RpbmdJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGFjY1tleGlzdGluZ0luZGV4XVsxXSA9IGJyb3dzZXJbMV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhY2MucHVzaChicm93c2VyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIFtdKS5tYXAoKHNwbGl0KT0+c3BsaXQuam9pbihcIlwiKSk7XG59O1xuXG5leHBvcnQgeyBTVVBQT1JURURfRVNCVUlMRF9UQVJHRVRTLCBVTlNVUFBPUlRFRF9CUk9XU0VSTElTVF9UQVJHRVRTLCBicm93c2Vyc2xpc3RUb0VzYnVpbGQsIGNvbXBhcmUsIGNvbXBhcmVTZW12ZXIsIG5vbk51bGxhYmxlLCBwYXJhbGxlbCwgdG9Vbml4IH07XG4iXSwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbMF0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/@serwist/utils/dist/index.js\n")); - -/***/ }), - -/***/ "./node_modules/idb/build/index.js": -/*!*****************************************!*\ - !*** ./node_modules/idb/build/index.js ***! - \*****************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ deleteDB: () => (/* binding */ deleteDB),\n/* harmony export */ openDB: () => (/* binding */ openDB),\n/* harmony export */ unwrap: () => (/* binding */ unwrap),\n/* harmony export */ wrap: () => (/* binding */ wrap)\n/* harmony export */ });\nconst instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n return (idbProxyableTypes ||\n (idbProxyableTypes = [\n IDBDatabase,\n IDBObjectStore,\n IDBIndex,\n IDBCursor,\n IDBTransaction,\n ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n return (cursorAdvanceMethods ||\n (cursorAdvanceMethods = [\n IDBCursor.prototype.advance,\n IDBCursor.prototype.continue,\n IDBCursor.prototype.continuePrimaryKey,\n ]));\n}\nconst transactionDoneMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n const promise = new Promise((resolve, reject) => {\n const unlisten = () => {\n request.removeEventListener('success', success);\n request.removeEventListener('error', error);\n };\n const success = () => {\n resolve(wrap(request.result));\n unlisten();\n };\n const error = () => {\n reject(request.error);\n unlisten();\n };\n request.addEventListener('success', success);\n request.addEventListener('error', error);\n });\n // This mapping exists in reverseTransformCache but doesn't exist in transformCache. This\n // is because we create many promises from a single IDBRequest.\n reverseTransformCache.set(promise, request);\n return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n // Early bail if we've already created a done promise for this transaction.\n if (transactionDoneMap.has(tx))\n return;\n const done = new Promise((resolve, reject) => {\n const unlisten = () => {\n tx.removeEventListener('complete', complete);\n tx.removeEventListener('error', error);\n tx.removeEventListener('abort', error);\n };\n const complete = () => {\n resolve();\n unlisten();\n };\n const error = () => {\n reject(tx.error || new DOMException('AbortError', 'AbortError'));\n unlisten();\n };\n tx.addEventListener('complete', complete);\n tx.addEventListener('error', error);\n tx.addEventListener('abort', error);\n });\n // Cache it for later retrieval.\n transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n get(target, prop, receiver) {\n if (target instanceof IDBTransaction) {\n // Special handling for transaction.done.\n if (prop === 'done')\n return transactionDoneMap.get(target);\n // Make tx.store return the only store in the transaction, or undefined if there are many.\n if (prop === 'store') {\n return receiver.objectStoreNames[1]\n ? undefined\n : receiver.objectStore(receiver.objectStoreNames[0]);\n }\n }\n // Else transform whatever we get back.\n return wrap(target[prop]);\n },\n set(target, prop, value) {\n target[prop] = value;\n return true;\n },\n has(target, prop) {\n if (target instanceof IDBTransaction &&\n (prop === 'done' || prop === 'store')) {\n return true;\n }\n return prop in target;\n },\n};\nfunction replaceTraps(callback) {\n idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n // Due to expected object equality (which is enforced by the caching in `wrap`), we\n // only create one new func per func.\n // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n // with real promises, so each advance methods returns a new promise for the cursor object, or\n // undefined if the end of the cursor has been reached.\n if (getCursorAdvanceMethods().includes(func)) {\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n func.apply(unwrap(this), args);\n return wrap(this.request);\n };\n }\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n return wrap(func.apply(unwrap(this), args));\n };\n}\nfunction transformCachableValue(value) {\n if (typeof value === 'function')\n return wrapFunction(value);\n // This doesn't return, it just creates a 'done' promise for the transaction,\n // which is later returned for transaction.done (see idbObjectHandler).\n if (value instanceof IDBTransaction)\n cacheDonePromiseForTransaction(value);\n if (instanceOfAny(value, getIdbProxyableTypes()))\n return new Proxy(value, idbProxyTraps);\n // Return the same value back if we're not going to transform it.\n return value;\n}\nfunction wrap(value) {\n // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n if (value instanceof IDBRequest)\n return promisifyRequest(value);\n // If we've already transformed this value before, reuse the transformed value.\n // This is faster, but it also provides object equality.\n if (transformCache.has(value))\n return transformCache.get(value);\n const newValue = transformCachableValue(value);\n // Not all types are transformed.\n // These may be primitive types, so they can't be WeakMap keys.\n if (newValue !== value) {\n transformCache.set(value, newValue);\n reverseTransformCache.set(newValue, value);\n }\n return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\n/**\n * Open a database.\n *\n * @param name Name of the database.\n * @param version Schema version.\n * @param callbacks Additional callbacks.\n */\nfunction openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {\n const request = indexedDB.open(name, version);\n const openPromise = wrap(request);\n if (upgrade) {\n request.addEventListener('upgradeneeded', (event) => {\n upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);\n });\n }\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event.newVersion, event));\n }\n openPromise\n .then((db) => {\n if (terminated)\n db.addEventListener('close', () => terminated());\n if (blocking) {\n db.addEventListener('versionchange', (event) => blocking(event.oldVersion, event.newVersion, event));\n }\n })\n .catch(() => { });\n return openPromise;\n}\n/**\n * Delete a database.\n *\n * @param name Name of the database.\n */\nfunction deleteDB(name, { blocked } = {}) {\n const request = indexedDB.deleteDatabase(name);\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event));\n }\n return wrap(request).then(() => undefined);\n}\n\nconst readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];\nconst writeMethods = ['put', 'add', 'delete', 'clear'];\nconst cachedMethods = new Map();\nfunction getMethod(target, prop) {\n if (!(target instanceof IDBDatabase &&\n !(prop in target) &&\n typeof prop === 'string')) {\n return;\n }\n if (cachedMethods.get(prop))\n return cachedMethods.get(prop);\n const targetFuncName = prop.replace(/FromIndex$/, '');\n const useIndex = prop !== targetFuncName;\n const isWrite = writeMethods.includes(targetFuncName);\n if (\n // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.\n !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||\n !(isWrite || readMethods.includes(targetFuncName))) {\n return;\n }\n const method = async function (storeName, ...args) {\n // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(\n const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');\n let target = tx.store;\n if (useIndex)\n target = target.index(args.shift());\n // Must reject if op rejects.\n // If it's a write operation, must reject if tx.done rejects.\n // Must reject with op rejection first.\n // Must resolve with op value.\n // Must handle both promises (no unhandled rejections)\n return (await Promise.all([\n target[targetFuncName](...args),\n isWrite && tx.done,\n ]))[0];\n };\n cachedMethods.set(prop, method);\n return method;\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),\n has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),\n}));\n\nconst advanceMethodProps = ['continue', 'continuePrimaryKey', 'advance'];\nconst methodMap = {};\nconst advanceResults = new WeakMap();\nconst ittrProxiedCursorToOriginalProxy = new WeakMap();\nconst cursorIteratorTraps = {\n get(target, prop) {\n if (!advanceMethodProps.includes(prop))\n return target[prop];\n let cachedFunc = methodMap[prop];\n if (!cachedFunc) {\n cachedFunc = methodMap[prop] = function (...args) {\n advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));\n };\n }\n return cachedFunc;\n },\n};\nasync function* iterate(...args) {\n // tslint:disable-next-line:no-this-assignment\n let cursor = this;\n if (!(cursor instanceof IDBCursor)) {\n cursor = await cursor.openCursor(...args);\n }\n if (!cursor)\n return;\n cursor = cursor;\n const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);\n ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);\n // Map this double-proxy back to the original, so other cursor methods work.\n reverseTransformCache.set(proxiedCursor, unwrap(cursor));\n while (cursor) {\n yield proxiedCursor;\n // If one of the advancing methods was not called, call continue().\n cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());\n advanceResults.delete(proxiedCursor);\n }\n}\nfunction isIteratorProp(target, prop) {\n return ((prop === Symbol.asyncIterator &&\n instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor])) ||\n (prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore])));\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get(target, prop, receiver) {\n if (isIteratorProp(target, prop))\n return iterate;\n return oldTraps.get(target, prop, receiver);\n },\n has(target, prop) {\n return isIteratorProp(target, prop) || oldTraps.has(target, prop);\n },\n}));\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvaWRiL2J1aWxkL2luZGV4LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLHlDQUF5QyxJQUFJO0FBQzlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLFVBQVUsSUFBSTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMLENBQUM7O0FBRXlDIiwic291cmNlcyI6WyIvVXNlcnMvc2Q5MjM1L2NvZGUvbXlnaC9sZWFybmluZ19haV9jbG9jay93ZWIvbm9kZV9tb2R1bGVzL2lkYi9idWlsZC9pbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBpbnN0YW5jZU9mQW55ID0gKG9iamVjdCwgY29uc3RydWN0b3JzKSA9PiBjb25zdHJ1Y3RvcnMuc29tZSgoYykgPT4gb2JqZWN0IGluc3RhbmNlb2YgYyk7XG5cbmxldCBpZGJQcm94eWFibGVUeXBlcztcbmxldCBjdXJzb3JBZHZhbmNlTWV0aG9kcztcbi8vIFRoaXMgaXMgYSBmdW5jdGlvbiB0byBwcmV2ZW50IGl0IHRocm93aW5nIHVwIGluIG5vZGUgZW52aXJvbm1lbnRzLlxuZnVuY3Rpb24gZ2V0SWRiUHJveHlhYmxlVHlwZXMoKSB7XG4gICAgcmV0dXJuIChpZGJQcm94eWFibGVUeXBlcyB8fFxuICAgICAgICAoaWRiUHJveHlhYmxlVHlwZXMgPSBbXG4gICAgICAgICAgICBJREJEYXRhYmFzZSxcbiAgICAgICAgICAgIElEQk9iamVjdFN0b3JlLFxuICAgICAgICAgICAgSURCSW5kZXgsXG4gICAgICAgICAgICBJREJDdXJzb3IsXG4gICAgICAgICAgICBJREJUcmFuc2FjdGlvbixcbiAgICAgICAgXSkpO1xufVxuLy8gVGhpcyBpcyBhIGZ1bmN0aW9uIHRvIHByZXZlbnQgaXQgdGhyb3dpbmcgdXAgaW4gbm9kZSBlbnZpcm9ubWVudHMuXG5mdW5jdGlvbiBnZXRDdXJzb3JBZHZhbmNlTWV0aG9kcygpIHtcbiAgICByZXR1cm4gKGN1cnNvckFkdmFuY2VNZXRob2RzIHx8XG4gICAgICAgIChjdXJzb3JBZHZhbmNlTWV0aG9kcyA9IFtcbiAgICAgICAgICAgIElEQkN1cnNvci5wcm90b3R5cGUuYWR2YW5jZSxcbiAgICAgICAgICAgIElEQkN1cnNvci5wcm90b3R5cGUuY29udGludWUsXG4gICAgICAgICAgICBJREJDdXJzb3IucHJvdG90eXBlLmNvbnRpbnVlUHJpbWFyeUtleSxcbiAgICAgICAgXSkpO1xufVxuY29uc3QgdHJhbnNhY3Rpb25Eb25lTWFwID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IHRyYW5zZm9ybUNhY2hlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IHJldmVyc2VUcmFuc2Zvcm1DYWNoZSA9IG5ldyBXZWFrTWFwKCk7XG5mdW5jdGlvbiBwcm9taXNpZnlSZXF1ZXN0KHJlcXVlc3QpIHtcbiAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCB1bmxpc3RlbiA9ICgpID0+IHtcbiAgICAgICAgICAgIHJlcXVlc3QucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3VjY2VzcycsIHN1Y2Nlc3MpO1xuICAgICAgICAgICAgcmVxdWVzdC5yZW1vdmVFdmVudExpc3RlbmVyKCdlcnJvcicsIGVycm9yKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUod3JhcChyZXF1ZXN0LnJlc3VsdCkpO1xuICAgICAgICAgICAgdW5saXN0ZW4oKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICByZWplY3QocmVxdWVzdC5lcnJvcik7XG4gICAgICAgICAgICB1bmxpc3RlbigpO1xuICAgICAgICB9O1xuICAgICAgICByZXF1ZXN0LmFkZEV2ZW50TGlzdGVuZXIoJ3N1Y2Nlc3MnLCBzdWNjZXNzKTtcbiAgICAgICAgcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIGVycm9yKTtcbiAgICB9KTtcbiAgICAvLyBUaGlzIG1hcHBpbmcgZXhpc3RzIGluIHJldmVyc2VUcmFuc2Zvcm1DYWNoZSBidXQgZG9lc24ndCBleGlzdCBpbiB0cmFuc2Zvcm1DYWNoZS4gVGhpc1xuICAgIC8vIGlzIGJlY2F1c2Ugd2UgY3JlYXRlIG1hbnkgcHJvbWlzZXMgZnJvbSBhIHNpbmdsZSBJREJSZXF1ZXN0LlxuICAgIHJldmVyc2VUcmFuc2Zvcm1DYWNoZS5zZXQocHJvbWlzZSwgcmVxdWVzdCk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5mdW5jdGlvbiBjYWNoZURvbmVQcm9taXNlRm9yVHJhbnNhY3Rpb24odHgpIHtcbiAgICAvLyBFYXJseSBiYWlsIGlmIHdlJ3ZlIGFscmVhZHkgY3JlYXRlZCBhIGRvbmUgcHJvbWlzZSBmb3IgdGhpcyB0cmFuc2FjdGlvbi5cbiAgICBpZiAodHJhbnNhY3Rpb25Eb25lTWFwLmhhcyh0eCkpXG4gICAgICAgIHJldHVybjtcbiAgICBjb25zdCBkb25lID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCB1bmxpc3RlbiA9ICgpID0+IHtcbiAgICAgICAgICAgIHR4LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NvbXBsZXRlJywgY29tcGxldGUpO1xuICAgICAgICAgICAgdHgucmVtb3ZlRXZlbnRMaXN0ZW5lcignZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICB0eC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIGVycm9yKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY29tcGxldGUgPSAoKSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB1bmxpc3RlbigpO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBlcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgIHJlamVjdCh0eC5lcnJvciB8fCBuZXcgRE9NRXhjZXB0aW9uKCdBYm9ydEVycm9yJywgJ0Fib3J0RXJyb3InKSk7XG4gICAgICAgICAgICB1bmxpc3RlbigpO1xuICAgICAgICB9O1xuICAgICAgICB0eC5hZGRFdmVudExpc3RlbmVyKCdjb21wbGV0ZScsIGNvbXBsZXRlKTtcbiAgICAgICAgdHguYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCBlcnJvcik7XG4gICAgICAgIHR4LmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgZXJyb3IpO1xuICAgIH0pO1xuICAgIC8vIENhY2hlIGl0IGZvciBsYXRlciByZXRyaWV2YWwuXG4gICAgdHJhbnNhY3Rpb25Eb25lTWFwLnNldCh0eCwgZG9uZSk7XG59XG5sZXQgaWRiUHJveHlUcmFwcyA9IHtcbiAgICBnZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcikge1xuICAgICAgICBpZiAodGFyZ2V0IGluc3RhbmNlb2YgSURCVHJhbnNhY3Rpb24pIHtcbiAgICAgICAgICAgIC8vIFNwZWNpYWwgaGFuZGxpbmcgZm9yIHRyYW5zYWN0aW9uLmRvbmUuXG4gICAgICAgICAgICBpZiAocHJvcCA9PT0gJ2RvbmUnKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cmFuc2FjdGlvbkRvbmVNYXAuZ2V0KHRhcmdldCk7XG4gICAgICAgICAgICAvLyBNYWtlIHR4LnN0b3JlIHJldHVybiB0aGUgb25seSBzdG9yZSBpbiB0aGUgdHJhbnNhY3Rpb24sIG9yIHVuZGVmaW5lZCBpZiB0aGVyZSBhcmUgbWFueS5cbiAgICAgICAgICAgIGlmIChwcm9wID09PSAnc3RvcmUnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlY2VpdmVyLm9iamVjdFN0b3JlTmFtZXNbMV1cbiAgICAgICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgOiByZWNlaXZlci5vYmplY3RTdG9yZShyZWNlaXZlci5vYmplY3RTdG9yZU5hbWVzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBFbHNlIHRyYW5zZm9ybSB3aGF0ZXZlciB3ZSBnZXQgYmFjay5cbiAgICAgICAgcmV0dXJuIHdyYXAodGFyZ2V0W3Byb3BdKTtcbiAgICB9LFxuICAgIHNldCh0YXJnZXQsIHByb3AsIHZhbHVlKSB7XG4gICAgICAgIHRhcmdldFtwcm9wXSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuICAgIGhhcyh0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIElEQlRyYW5zYWN0aW9uICYmXG4gICAgICAgICAgICAocHJvcCA9PT0gJ2RvbmUnIHx8IHByb3AgPT09ICdzdG9yZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcCBpbiB0YXJnZXQ7XG4gICAgfSxcbn07XG5mdW5jdGlvbiByZXBsYWNlVHJhcHMoY2FsbGJhY2spIHtcbiAgICBpZGJQcm94eVRyYXBzID0gY2FsbGJhY2soaWRiUHJveHlUcmFwcyk7XG59XG5mdW5jdGlvbiB3cmFwRnVuY3Rpb24oZnVuYykge1xuICAgIC8vIER1ZSB0byBleHBlY3RlZCBvYmplY3QgZXF1YWxpdHkgKHdoaWNoIGlzIGVuZm9yY2VkIGJ5IHRoZSBjYWNoaW5nIGluIGB3cmFwYCksIHdlXG4gICAgLy8gb25seSBjcmVhdGUgb25lIG5ldyBmdW5jIHBlciBmdW5jLlxuICAgIC8vIEN1cnNvciBtZXRob2RzIGFyZSBzcGVjaWFsLCBhcyB0aGUgYmVoYXZpb3VyIGlzIGEgbGl0dGxlIG1vcmUgZGlmZmVyZW50IHRvIHN0YW5kYXJkIElEQi4gSW5cbiAgICAvLyBJREIsIHlvdSBhZHZhbmNlIHRoZSBjdXJzb3IgYW5kIHdhaXQgZm9yIGEgbmV3ICdzdWNjZXNzJyBvbiB0aGUgSURCUmVxdWVzdCB0aGF0IGdhdmUgeW91IHRoZVxuICAgIC8vIGN1cnNvci4gSXQncyBraW5kYSBsaWtlIGEgcHJvbWlzZSB0aGF0IGNhbiByZXNvbHZlIHdpdGggbWFueSB2YWx1ZXMuIFRoYXQgZG9lc24ndCBtYWtlIHNlbnNlXG4gICAgLy8gd2l0aCByZWFsIHByb21pc2VzLCBzbyBlYWNoIGFkdmFuY2UgbWV0aG9kcyByZXR1cm5zIGEgbmV3IHByb21pc2UgZm9yIHRoZSBjdXJzb3Igb2JqZWN0LCBvclxuICAgIC8vIHVuZGVmaW5lZCBpZiB0aGUgZW5kIG9mIHRoZSBjdXJzb3IgaGFzIGJlZW4gcmVhY2hlZC5cbiAgICBpZiAoZ2V0Q3Vyc29yQWR2YW5jZU1ldGhvZHMoKS5pbmNsdWRlcyhmdW5jKSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgIC8vIENhbGxpbmcgdGhlIG9yaWdpbmFsIGZ1bmN0aW9uIHdpdGggdGhlIHByb3h5IGFzICd0aGlzJyBjYXVzZXMgSUxMRUdBTCBJTlZPQ0FUSU9OLCBzbyB3ZSB1c2VcbiAgICAgICAgICAgIC8vIHRoZSBvcmlnaW5hbCBvYmplY3QuXG4gICAgICAgICAgICBmdW5jLmFwcGx5KHVud3JhcCh0aGlzKSwgYXJncyk7XG4gICAgICAgICAgICByZXR1cm4gd3JhcCh0aGlzLnJlcXVlc3QpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgLy8gQ2FsbGluZyB0aGUgb3JpZ2luYWwgZnVuY3Rpb24gd2l0aCB0aGUgcHJveHkgYXMgJ3RoaXMnIGNhdXNlcyBJTExFR0FMIElOVk9DQVRJT04sIHNvIHdlIHVzZVxuICAgICAgICAvLyB0aGUgb3JpZ2luYWwgb2JqZWN0LlxuICAgICAgICByZXR1cm4gd3JhcChmdW5jLmFwcGx5KHVud3JhcCh0aGlzKSwgYXJncykpO1xuICAgIH07XG59XG5mdW5jdGlvbiB0cmFuc2Zvcm1DYWNoYWJsZVZhbHVlKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgcmV0dXJuIHdyYXBGdW5jdGlvbih2YWx1ZSk7XG4gICAgLy8gVGhpcyBkb2Vzbid0IHJldHVybiwgaXQganVzdCBjcmVhdGVzIGEgJ2RvbmUnIHByb21pc2UgZm9yIHRoZSB0cmFuc2FjdGlvbixcbiAgICAvLyB3aGljaCBpcyBsYXRlciByZXR1cm5lZCBmb3IgdHJhbnNhY3Rpb24uZG9uZSAoc2VlIGlkYk9iamVjdEhhbmRsZXIpLlxuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIElEQlRyYW5zYWN0aW9uKVxuICAgICAgICBjYWNoZURvbmVQcm9taXNlRm9yVHJhbnNhY3Rpb24odmFsdWUpO1xuICAgIGlmIChpbnN0YW5jZU9mQW55KHZhbHVlLCBnZXRJZGJQcm94eWFibGVUeXBlcygpKSlcbiAgICAgICAgcmV0dXJuIG5ldyBQcm94eSh2YWx1ZSwgaWRiUHJveHlUcmFwcyk7XG4gICAgLy8gUmV0dXJuIHRoZSBzYW1lIHZhbHVlIGJhY2sgaWYgd2UncmUgbm90IGdvaW5nIHRvIHRyYW5zZm9ybSBpdC5cbiAgICByZXR1cm4gdmFsdWU7XG59XG5mdW5jdGlvbiB3cmFwKHZhbHVlKSB7XG4gICAgLy8gV2Ugc29tZXRpbWVzIGdlbmVyYXRlIG11bHRpcGxlIHByb21pc2VzIGZyb20gYSBzaW5nbGUgSURCUmVxdWVzdCAoZWcgd2hlbiBjdXJzb3JpbmcpLCBiZWNhdXNlXG4gICAgLy8gSURCIGlzIHdlaXJkIGFuZCBhIHNpbmdsZSBJREJSZXF1ZXN0IGNhbiB5aWVsZCBtYW55IHJlc3BvbnNlcywgc28gdGhlc2UgY2FuJ3QgYmUgY2FjaGVkLlxuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIElEQlJlcXVlc3QpXG4gICAgICAgIHJldHVybiBwcm9taXNpZnlSZXF1ZXN0KHZhbHVlKTtcbiAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IHRyYW5zZm9ybWVkIHRoaXMgdmFsdWUgYmVmb3JlLCByZXVzZSB0aGUgdHJhbnNmb3JtZWQgdmFsdWUuXG4gICAgLy8gVGhpcyBpcyBmYXN0ZXIsIGJ1dCBpdCBhbHNvIHByb3ZpZGVzIG9iamVjdCBlcXVhbGl0eS5cbiAgICBpZiAodHJhbnNmb3JtQ2FjaGUuaGFzKHZhbHVlKSlcbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybUNhY2hlLmdldCh2YWx1ZSk7XG4gICAgY29uc3QgbmV3VmFsdWUgPSB0cmFuc2Zvcm1DYWNoYWJsZVZhbHVlKHZhbHVlKTtcbiAgICAvLyBOb3QgYWxsIHR5cGVzIGFyZSB0cmFuc2Zvcm1lZC5cbiAgICAvLyBUaGVzZSBtYXkgYmUgcHJpbWl0aXZlIHR5cGVzLCBzbyB0aGV5IGNhbid0IGJlIFdlYWtNYXAga2V5cy5cbiAgICBpZiAobmV3VmFsdWUgIT09IHZhbHVlKSB7XG4gICAgICAgIHRyYW5zZm9ybUNhY2hlLnNldCh2YWx1ZSwgbmV3VmFsdWUpO1xuICAgICAgICByZXZlcnNlVHJhbnNmb3JtQ2FjaGUuc2V0KG5ld1ZhbHVlLCB2YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiBuZXdWYWx1ZTtcbn1cbmNvbnN0IHVud3JhcCA9ICh2YWx1ZSkgPT4gcmV2ZXJzZVRyYW5zZm9ybUNhY2hlLmdldCh2YWx1ZSk7XG5cbi8qKlxuICogT3BlbiBhIGRhdGFiYXNlLlxuICpcbiAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgdGhlIGRhdGFiYXNlLlxuICogQHBhcmFtIHZlcnNpb24gU2NoZW1hIHZlcnNpb24uXG4gKiBAcGFyYW0gY2FsbGJhY2tzIEFkZGl0aW9uYWwgY2FsbGJhY2tzLlxuICovXG5mdW5jdGlvbiBvcGVuREIobmFtZSwgdmVyc2lvbiwgeyBibG9ja2VkLCB1cGdyYWRlLCBibG9ja2luZywgdGVybWluYXRlZCB9ID0ge30pIHtcbiAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXhlZERCLm9wZW4obmFtZSwgdmVyc2lvbik7XG4gICAgY29uc3Qgb3BlblByb21pc2UgPSB3cmFwKHJlcXVlc3QpO1xuICAgIGlmICh1cGdyYWRlKSB7XG4gICAgICAgIHJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigndXBncmFkZW5lZWRlZCcsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgdXBncmFkZSh3cmFwKHJlcXVlc3QucmVzdWx0KSwgZXZlbnQub2xkVmVyc2lvbiwgZXZlbnQubmV3VmVyc2lvbiwgd3JhcChyZXF1ZXN0LnRyYW5zYWN0aW9uKSwgZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKGJsb2NrZWQpIHtcbiAgICAgICAgcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCdibG9ja2VkJywgKGV2ZW50KSA9PiBibG9ja2VkKFxuICAgICAgICAvLyBDYXN0aW5nIGR1ZSB0byBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L1R5cGVTY3JpcHQtRE9NLWxpYi1nZW5lcmF0b3IvcHVsbC8xNDA1XG4gICAgICAgIGV2ZW50Lm9sZFZlcnNpb24sIGV2ZW50Lm5ld1ZlcnNpb24sIGV2ZW50KSk7XG4gICAgfVxuICAgIG9wZW5Qcm9taXNlXG4gICAgICAgIC50aGVuKChkYikgPT4ge1xuICAgICAgICBpZiAodGVybWluYXRlZClcbiAgICAgICAgICAgIGRiLmFkZEV2ZW50TGlzdGVuZXIoJ2Nsb3NlJywgKCkgPT4gdGVybWluYXRlZCgpKTtcbiAgICAgICAgaWYgKGJsb2NraW5nKSB7XG4gICAgICAgICAgICBkYi5hZGRFdmVudExpc3RlbmVyKCd2ZXJzaW9uY2hhbmdlJywgKGV2ZW50KSA9PiBibG9ja2luZyhldmVudC5vbGRWZXJzaW9uLCBldmVudC5uZXdWZXJzaW9uLCBldmVudCkpO1xuICAgICAgICB9XG4gICAgfSlcbiAgICAgICAgLmNhdGNoKCgpID0+IHsgfSk7XG4gICAgcmV0dXJuIG9wZW5Qcm9taXNlO1xufVxuLyoqXG4gKiBEZWxldGUgYSBkYXRhYmFzZS5cbiAqXG4gKiBAcGFyYW0gbmFtZSBOYW1lIG9mIHRoZSBkYXRhYmFzZS5cbiAqL1xuZnVuY3Rpb24gZGVsZXRlREIobmFtZSwgeyBibG9ja2VkIH0gPSB7fSkge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBpbmRleGVkREIuZGVsZXRlRGF0YWJhc2UobmFtZSk7XG4gICAgaWYgKGJsb2NrZWQpIHtcbiAgICAgICAgcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCdibG9ja2VkJywgKGV2ZW50KSA9PiBibG9ja2VkKFxuICAgICAgICAvLyBDYXN0aW5nIGR1ZSB0byBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L1R5cGVTY3JpcHQtRE9NLWxpYi1nZW5lcmF0b3IvcHVsbC8xNDA1XG4gICAgICAgIGV2ZW50Lm9sZFZlcnNpb24sIGV2ZW50KSk7XG4gICAgfVxuICAgIHJldHVybiB3cmFwKHJlcXVlc3QpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbn1cblxuY29uc3QgcmVhZE1ldGhvZHMgPSBbJ2dldCcsICdnZXRLZXknLCAnZ2V0QWxsJywgJ2dldEFsbEtleXMnLCAnY291bnQnXTtcbmNvbnN0IHdyaXRlTWV0aG9kcyA9IFsncHV0JywgJ2FkZCcsICdkZWxldGUnLCAnY2xlYXInXTtcbmNvbnN0IGNhY2hlZE1ldGhvZHMgPSBuZXcgTWFwKCk7XG5mdW5jdGlvbiBnZXRNZXRob2QodGFyZ2V0LCBwcm9wKSB7XG4gICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSURCRGF0YWJhc2UgJiZcbiAgICAgICAgIShwcm9wIGluIHRhcmdldCkgJiZcbiAgICAgICAgdHlwZW9mIHByb3AgPT09ICdzdHJpbmcnKSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjYWNoZWRNZXRob2RzLmdldChwcm9wKSlcbiAgICAgICAgcmV0dXJuIGNhY2hlZE1ldGhvZHMuZ2V0KHByb3ApO1xuICAgIGNvbnN0IHRhcmdldEZ1bmNOYW1lID0gcHJvcC5yZXBsYWNlKC9Gcm9tSW5kZXgkLywgJycpO1xuICAgIGNvbnN0IHVzZUluZGV4ID0gcHJvcCAhPT0gdGFyZ2V0RnVuY05hbWU7XG4gICAgY29uc3QgaXNXcml0ZSA9IHdyaXRlTWV0aG9kcy5pbmNsdWRlcyh0YXJnZXRGdW5jTmFtZSk7XG4gICAgaWYgKFxuICAgIC8vIEJhaWwgaWYgdGhlIHRhcmdldCBkb2Vzbid0IGV4aXN0IG9uIHRoZSB0YXJnZXQuIEVnLCBnZXRBbGwgaXNuJ3QgaW4gRWRnZS5cbiAgICAhKHRhcmdldEZ1bmNOYW1lIGluICh1c2VJbmRleCA/IElEQkluZGV4IDogSURCT2JqZWN0U3RvcmUpLnByb3RvdHlwZSkgfHxcbiAgICAgICAgIShpc1dyaXRlIHx8IHJlYWRNZXRob2RzLmluY2x1ZGVzKHRhcmdldEZ1bmNOYW1lKSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtZXRob2QgPSBhc3luYyBmdW5jdGlvbiAoc3RvcmVOYW1lLCAuLi5hcmdzKSB7XG4gICAgICAgIC8vIGlzV3JpdGUgPyAncmVhZHdyaXRlJyA6IHVuZGVmaW5lZCBnemlwcHMgYmV0dGVyLCBidXQgZmFpbHMgaW4gRWRnZSA6KFxuICAgICAgICBjb25zdCB0eCA9IHRoaXMudHJhbnNhY3Rpb24oc3RvcmVOYW1lLCBpc1dyaXRlID8gJ3JlYWR3cml0ZScgOiAncmVhZG9ubHknKTtcbiAgICAgICAgbGV0IHRhcmdldCA9IHR4LnN0b3JlO1xuICAgICAgICBpZiAodXNlSW5kZXgpXG4gICAgICAgICAgICB0YXJnZXQgPSB0YXJnZXQuaW5kZXgoYXJncy5zaGlmdCgpKTtcbiAgICAgICAgLy8gTXVzdCByZWplY3QgaWYgb3AgcmVqZWN0cy5cbiAgICAgICAgLy8gSWYgaXQncyBhIHdyaXRlIG9wZXJhdGlvbiwgbXVzdCByZWplY3QgaWYgdHguZG9uZSByZWplY3RzLlxuICAgICAgICAvLyBNdXN0IHJlamVjdCB3aXRoIG9wIHJlamVjdGlvbiBmaXJzdC5cbiAgICAgICAgLy8gTXVzdCByZXNvbHZlIHdpdGggb3AgdmFsdWUuXG4gICAgICAgIC8vIE11c3QgaGFuZGxlIGJvdGggcHJvbWlzZXMgKG5vIHVuaGFuZGxlZCByZWplY3Rpb25zKVxuICAgICAgICByZXR1cm4gKGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgIHRhcmdldFt0YXJnZXRGdW5jTmFtZV0oLi4uYXJncyksXG4gICAgICAgICAgICBpc1dyaXRlICYmIHR4LmRvbmUsXG4gICAgICAgIF0pKVswXTtcbiAgICB9O1xuICAgIGNhY2hlZE1ldGhvZHMuc2V0KHByb3AsIG1ldGhvZCk7XG4gICAgcmV0dXJuIG1ldGhvZDtcbn1cbnJlcGxhY2VUcmFwcygob2xkVHJhcHMpID0+ICh7XG4gICAgLi4ub2xkVHJhcHMsXG4gICAgZ2V0OiAodGFyZ2V0LCBwcm9wLCByZWNlaXZlcikgPT4gZ2V0TWV0aG9kKHRhcmdldCwgcHJvcCkgfHwgb2xkVHJhcHMuZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpLFxuICAgIGhhczogKHRhcmdldCwgcHJvcCkgPT4gISFnZXRNZXRob2QodGFyZ2V0LCBwcm9wKSB8fCBvbGRUcmFwcy5oYXModGFyZ2V0LCBwcm9wKSxcbn0pKTtcblxuY29uc3QgYWR2YW5jZU1ldGhvZFByb3BzID0gWydjb250aW51ZScsICdjb250aW51ZVByaW1hcnlLZXknLCAnYWR2YW5jZSddO1xuY29uc3QgbWV0aG9kTWFwID0ge307XG5jb25zdCBhZHZhbmNlUmVzdWx0cyA9IG5ldyBXZWFrTWFwKCk7XG5jb25zdCBpdHRyUHJveGllZEN1cnNvclRvT3JpZ2luYWxQcm94eSA9IG5ldyBXZWFrTWFwKCk7XG5jb25zdCBjdXJzb3JJdGVyYXRvclRyYXBzID0ge1xuICAgIGdldCh0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgaWYgKCFhZHZhbmNlTWV0aG9kUHJvcHMuaW5jbHVkZXMocHJvcCkpXG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0W3Byb3BdO1xuICAgICAgICBsZXQgY2FjaGVkRnVuYyA9IG1ldGhvZE1hcFtwcm9wXTtcbiAgICAgICAgaWYgKCFjYWNoZWRGdW5jKSB7XG4gICAgICAgICAgICBjYWNoZWRGdW5jID0gbWV0aG9kTWFwW3Byb3BdID0gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICBhZHZhbmNlUmVzdWx0cy5zZXQodGhpcywgaXR0clByb3hpZWRDdXJzb3JUb09yaWdpbmFsUHJveHkuZ2V0KHRoaXMpW3Byb3BdKC4uLmFyZ3MpKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhY2hlZEZ1bmM7XG4gICAgfSxcbn07XG5hc3luYyBmdW5jdGlvbiogaXRlcmF0ZSguLi5hcmdzKSB7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXRoaXMtYXNzaWdubWVudFxuICAgIGxldCBjdXJzb3IgPSB0aGlzO1xuICAgIGlmICghKGN1cnNvciBpbnN0YW5jZW9mIElEQkN1cnNvcikpIHtcbiAgICAgICAgY3Vyc29yID0gYXdhaXQgY3Vyc29yLm9wZW5DdXJzb3IoLi4uYXJncyk7XG4gICAgfVxuICAgIGlmICghY3Vyc29yKVxuICAgICAgICByZXR1cm47XG4gICAgY3Vyc29yID0gY3Vyc29yO1xuICAgIGNvbnN0IHByb3hpZWRDdXJzb3IgPSBuZXcgUHJveHkoY3Vyc29yLCBjdXJzb3JJdGVyYXRvclRyYXBzKTtcbiAgICBpdHRyUHJveGllZEN1cnNvclRvT3JpZ2luYWxQcm94eS5zZXQocHJveGllZEN1cnNvciwgY3Vyc29yKTtcbiAgICAvLyBNYXAgdGhpcyBkb3VibGUtcHJveHkgYmFjayB0byB0aGUgb3JpZ2luYWwsIHNvIG90aGVyIGN1cnNvciBtZXRob2RzIHdvcmsuXG4gICAgcmV2ZXJzZVRyYW5zZm9ybUNhY2hlLnNldChwcm94aWVkQ3Vyc29yLCB1bndyYXAoY3Vyc29yKSk7XG4gICAgd2hpbGUgKGN1cnNvcikge1xuICAgICAgICB5aWVsZCBwcm94aWVkQ3Vyc29yO1xuICAgICAgICAvLyBJZiBvbmUgb2YgdGhlIGFkdmFuY2luZyBtZXRob2RzIHdhcyBub3QgY2FsbGVkLCBjYWxsIGNvbnRpbnVlKCkuXG4gICAgICAgIGN1cnNvciA9IGF3YWl0IChhZHZhbmNlUmVzdWx0cy5nZXQocHJveGllZEN1cnNvcikgfHwgY3Vyc29yLmNvbnRpbnVlKCkpO1xuICAgICAgICBhZHZhbmNlUmVzdWx0cy5kZWxldGUocHJveGllZEN1cnNvcik7XG4gICAgfVxufVxuZnVuY3Rpb24gaXNJdGVyYXRvclByb3AodGFyZ2V0LCBwcm9wKSB7XG4gICAgcmV0dXJuICgocHJvcCA9PT0gU3ltYm9sLmFzeW5jSXRlcmF0b3IgJiZcbiAgICAgICAgaW5zdGFuY2VPZkFueSh0YXJnZXQsIFtJREJJbmRleCwgSURCT2JqZWN0U3RvcmUsIElEQkN1cnNvcl0pKSB8fFxuICAgICAgICAocHJvcCA9PT0gJ2l0ZXJhdGUnICYmIGluc3RhbmNlT2ZBbnkodGFyZ2V0LCBbSURCSW5kZXgsIElEQk9iamVjdFN0b3JlXSkpKTtcbn1cbnJlcGxhY2VUcmFwcygob2xkVHJhcHMpID0+ICh7XG4gICAgLi4ub2xkVHJhcHMsXG4gICAgZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpIHtcbiAgICAgICAgaWYgKGlzSXRlcmF0b3JQcm9wKHRhcmdldCwgcHJvcCkpXG4gICAgICAgICAgICByZXR1cm4gaXRlcmF0ZTtcbiAgICAgICAgcmV0dXJuIG9sZFRyYXBzLmdldCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKTtcbiAgICB9LFxuICAgIGhhcyh0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgcmV0dXJuIGlzSXRlcmF0b3JQcm9wKHRhcmdldCwgcHJvcCkgfHwgb2xkVHJhcHMuaGFzKHRhcmdldCwgcHJvcCk7XG4gICAgfSxcbn0pKTtcblxuZXhwb3J0IHsgZGVsZXRlREIsIG9wZW5EQiwgdW53cmFwLCB3cmFwIH07XG4iXSwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbMF0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/idb/build/index.js\n")); - -/***/ }), - -/***/ "./node_modules/serwist/dist/chunks/printInstallDetails.js": -/*!*****************************************************************!*\ - !*** ./node_modules/serwist/dist/chunks/printInstallDetails.js ***! - \*****************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ B: () => (/* binding */ BackgroundSyncPlugin),\n/* harmony export */ N: () => (/* binding */ NetworkFirst),\n/* harmony export */ P: () => (/* binding */ PrecacheStrategy),\n/* harmony export */ R: () => (/* binding */ Route),\n/* harmony export */ S: () => (/* binding */ Strategy),\n/* harmony export */ a: () => (/* binding */ NetworkOnly),\n/* harmony export */ b: () => (/* binding */ NavigationRoute),\n/* harmony export */ c: () => (/* binding */ cacheOkAndOpaquePlugin),\n/* harmony export */ d: () => (/* binding */ disableDevLogs),\n/* harmony export */ e: () => (/* binding */ enableNavigationPreload),\n/* harmony export */ f: () => (/* binding */ createCacheKey),\n/* harmony export */ g: () => (/* binding */ generateURLVariations),\n/* harmony export */ h: () => (/* binding */ defaultMethod),\n/* harmony export */ i: () => (/* binding */ PrecacheInstallReportPlugin),\n/* harmony export */ j: () => (/* binding */ printInstallDetails),\n/* harmony export */ k: () => (/* binding */ printCleanupDetails),\n/* harmony export */ l: () => (/* binding */ BackgroundSyncQueue),\n/* harmony export */ m: () => (/* binding */ messages),\n/* harmony export */ n: () => (/* binding */ normalizeHandler),\n/* harmony export */ o: () => (/* binding */ BackgroundSyncQueueStore),\n/* harmony export */ p: () => (/* binding */ parseRoute),\n/* harmony export */ q: () => (/* binding */ RegExpRoute),\n/* harmony export */ r: () => (/* binding */ StorableRequest),\n/* harmony export */ s: () => (/* binding */ setCacheNameDetails),\n/* harmony export */ t: () => (/* binding */ StrategyHandler),\n/* harmony export */ u: () => (/* binding */ copyResponse),\n/* harmony export */ v: () => (/* binding */ disableNavigationPreload),\n/* harmony export */ w: () => (/* binding */ isNavigationPreloadSupported)\n/* harmony export */ });\n/* harmony import */ var _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./waitUntil.js */ \"./node_modules/serwist/dist/chunks/waitUntil.js\");\n/* harmony import */ var idb__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! idb */ \"./node_modules/idb/build/index.js\");\n\n\n\nconst copyResponse = async (response, modifier)=>{\n let origin = null;\n if (response.url) {\n const responseURL = new URL(response.url);\n origin = responseURL.origin;\n }\n if (origin !== self.location.origin) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"cross-origin-copy-response\", {\n origin\n });\n }\n const clonedResponse = response.clone();\n const responseInit = {\n headers: new Headers(clonedResponse.headers),\n status: clonedResponse.status,\n statusText: clonedResponse.statusText\n };\n const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit;\n const body = (0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.d)() ? clonedResponse.body : await clonedResponse.blob();\n return new Response(body, modifiedResponseInit);\n};\n\nconst disableDevLogs = ()=>{\n self.__WB_DISABLE_DEV_LOGS = true;\n};\n\nconst BACKGROUND_SYNC_DB_VERSION = 3;\nconst BACKGROUND_SYNC_DB_NAME = \"serwist-background-sync\";\nconst REQUEST_OBJECT_STORE_NAME = \"requests\";\nconst QUEUE_NAME_INDEX = \"queueName\";\nclass BackgroundSyncQueueDb {\n _db = null;\n async addEntry(entry) {\n const db = await this.getDb();\n const tx = db.transaction(REQUEST_OBJECT_STORE_NAME, \"readwrite\", {\n durability: \"relaxed\"\n });\n await tx.store.add(entry);\n await tx.done;\n }\n async getFirstEntryId() {\n const db = await this.getDb();\n const cursor = await db.transaction(REQUEST_OBJECT_STORE_NAME).store.openCursor();\n return cursor?.value.id;\n }\n async getAllEntriesByQueueName(queueName) {\n const db = await this.getDb();\n const results = await db.getAllFromIndex(REQUEST_OBJECT_STORE_NAME, QUEUE_NAME_INDEX, IDBKeyRange.only(queueName));\n return results ? results : [];\n }\n async getEntryCountByQueueName(queueName) {\n const db = await this.getDb();\n return db.countFromIndex(REQUEST_OBJECT_STORE_NAME, QUEUE_NAME_INDEX, IDBKeyRange.only(queueName));\n }\n async deleteEntry(id) {\n const db = await this.getDb();\n await db.delete(REQUEST_OBJECT_STORE_NAME, id);\n }\n async getFirstEntryByQueueName(queueName) {\n return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), \"next\");\n }\n async getLastEntryByQueueName(queueName) {\n return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), \"prev\");\n }\n async getEndEntryFromIndex(query, direction) {\n const db = await this.getDb();\n const cursor = await db.transaction(REQUEST_OBJECT_STORE_NAME).store.index(QUEUE_NAME_INDEX).openCursor(query, direction);\n return cursor?.value;\n }\n async getDb() {\n if (!this._db) {\n this._db = await (0,idb__WEBPACK_IMPORTED_MODULE_1__.openDB)(BACKGROUND_SYNC_DB_NAME, BACKGROUND_SYNC_DB_VERSION, {\n upgrade: this._upgradeDb\n });\n }\n return this._db;\n }\n _upgradeDb(db, oldVersion) {\n if (oldVersion > 0 && oldVersion < BACKGROUND_SYNC_DB_VERSION) {\n if (db.objectStoreNames.contains(REQUEST_OBJECT_STORE_NAME)) {\n db.deleteObjectStore(REQUEST_OBJECT_STORE_NAME);\n }\n }\n const objStore = db.createObjectStore(REQUEST_OBJECT_STORE_NAME, {\n autoIncrement: true,\n keyPath: \"id\"\n });\n objStore.createIndex(QUEUE_NAME_INDEX, QUEUE_NAME_INDEX, {\n unique: false\n });\n }\n}\n\nclass BackgroundSyncQueueStore {\n _queueName;\n _queueDb;\n constructor(queueName){\n this._queueName = queueName;\n this._queueDb = new BackgroundSyncQueueDb();\n }\n async pushEntry(entry) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(entry, \"object\", {\n moduleName: \"serwist\",\n className: \"BackgroundSyncQueueStore\",\n funcName: \"pushEntry\",\n paramName: \"entry\"\n });\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(entry.requestData, \"object\", {\n moduleName: \"serwist\",\n className: \"BackgroundSyncQueueStore\",\n funcName: \"pushEntry\",\n paramName: \"entry.requestData\"\n });\n }\n delete entry.id;\n entry.queueName = this._queueName;\n await this._queueDb.addEntry(entry);\n }\n async unshiftEntry(entry) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(entry, \"object\", {\n moduleName: \"serwist\",\n className: \"BackgroundSyncQueueStore\",\n funcName: \"unshiftEntry\",\n paramName: \"entry\"\n });\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(entry.requestData, \"object\", {\n moduleName: \"serwist\",\n className: \"BackgroundSyncQueueStore\",\n funcName: \"unshiftEntry\",\n paramName: \"entry.requestData\"\n });\n }\n const firstId = await this._queueDb.getFirstEntryId();\n if (firstId) {\n entry.id = firstId - 1;\n } else {\n delete entry.id;\n }\n entry.queueName = this._queueName;\n await this._queueDb.addEntry(entry);\n }\n async popEntry() {\n return this._removeEntry(await this._queueDb.getLastEntryByQueueName(this._queueName));\n }\n async shiftEntry() {\n return this._removeEntry(await this._queueDb.getFirstEntryByQueueName(this._queueName));\n }\n async getAll() {\n return await this._queueDb.getAllEntriesByQueueName(this._queueName);\n }\n async size() {\n return await this._queueDb.getEntryCountByQueueName(this._queueName);\n }\n async deleteEntry(id) {\n await this._queueDb.deleteEntry(id);\n }\n async _removeEntry(entry) {\n if (entry) {\n await this.deleteEntry(entry.id);\n }\n return entry;\n }\n}\n\nconst serializableProperties = [\n \"method\",\n \"referrer\",\n \"referrerPolicy\",\n \"mode\",\n \"credentials\",\n \"cache\",\n \"redirect\",\n \"integrity\",\n \"keepalive\"\n];\nclass StorableRequest {\n _requestData;\n static async fromRequest(request) {\n const requestData = {\n url: request.url,\n headers: {}\n };\n if (request.method !== \"GET\") {\n requestData.body = await request.clone().arrayBuffer();\n }\n request.headers.forEach((value, key)=>{\n requestData.headers[key] = value;\n });\n for (const prop of serializableProperties){\n if (request[prop] !== undefined) {\n requestData[prop] = request[prop];\n }\n }\n return new StorableRequest(requestData);\n }\n constructor(requestData){\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(requestData, \"object\", {\n moduleName: \"serwist\",\n className: \"StorableRequest\",\n funcName: \"constructor\",\n paramName: \"requestData\"\n });\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(requestData.url, \"string\", {\n moduleName: \"serwist\",\n className: \"StorableRequest\",\n funcName: \"constructor\",\n paramName: \"requestData.url\"\n });\n }\n if (requestData.mode === \"navigate\") {\n requestData.mode = \"same-origin\";\n }\n this._requestData = requestData;\n }\n toObject() {\n const requestData = Object.assign({}, this._requestData);\n requestData.headers = Object.assign({}, this._requestData.headers);\n if (requestData.body) {\n requestData.body = requestData.body.slice(0);\n }\n return requestData;\n }\n toRequest() {\n return new Request(this._requestData.url, this._requestData);\n }\n clone() {\n return new StorableRequest(this.toObject());\n }\n}\n\nconst TAG_PREFIX = \"serwist-background-sync\";\nconst MAX_RETENTION_TIME = 60 * 24 * 7;\nconst queueNames = new Set();\nconst convertEntry = (queueStoreEntry)=>{\n const queueEntry = {\n request: new StorableRequest(queueStoreEntry.requestData).toRequest(),\n timestamp: queueStoreEntry.timestamp\n };\n if (queueStoreEntry.metadata) {\n queueEntry.metadata = queueStoreEntry.metadata;\n }\n return queueEntry;\n};\nclass BackgroundSyncQueue {\n _name;\n _onSync;\n _maxRetentionTime;\n _queueStore;\n _forceSyncFallback;\n _syncInProgress = false;\n _requestsAddedDuringSync = false;\n constructor(name, { forceSyncFallback, onSync, maxRetentionTime } = {}){\n if (queueNames.has(name)) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"duplicate-queue-name\", {\n name\n });\n }\n queueNames.add(name);\n this._name = name;\n this._onSync = onSync || this.replayRequests;\n this._maxRetentionTime = maxRetentionTime || MAX_RETENTION_TIME;\n this._forceSyncFallback = Boolean(forceSyncFallback);\n this._queueStore = new BackgroundSyncQueueStore(this._name);\n this._addSyncListener();\n }\n get name() {\n return this._name;\n }\n async pushRequest(entry) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(entry, \"object\", {\n moduleName: \"serwist\",\n className: \"BackgroundSyncQueue\",\n funcName: \"pushRequest\",\n paramName: \"entry\"\n });\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(entry.request, Request, {\n moduleName: \"serwist\",\n className: \"BackgroundSyncQueue\",\n funcName: \"pushRequest\",\n paramName: \"entry.request\"\n });\n }\n await this._addRequest(entry, \"push\");\n }\n async unshiftRequest(entry) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(entry, \"object\", {\n moduleName: \"serwist\",\n className: \"BackgroundSyncQueue\",\n funcName: \"unshiftRequest\",\n paramName: \"entry\"\n });\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(entry.request, Request, {\n moduleName: \"serwist\",\n className: \"BackgroundSyncQueue\",\n funcName: \"unshiftRequest\",\n paramName: \"entry.request\"\n });\n }\n await this._addRequest(entry, \"unshift\");\n }\n async popRequest() {\n return this._removeRequest(\"pop\");\n }\n async shiftRequest() {\n return this._removeRequest(\"shift\");\n }\n async getAll() {\n const allEntries = await this._queueStore.getAll();\n const now = Date.now();\n const unexpiredEntries = [];\n for (const entry of allEntries){\n const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n if (now - entry.timestamp > maxRetentionTimeInMs) {\n await this._queueStore.deleteEntry(entry.id);\n } else {\n unexpiredEntries.push(convertEntry(entry));\n }\n }\n return unexpiredEntries;\n }\n async size() {\n return await this._queueStore.size();\n }\n async _addRequest({ request, metadata, timestamp = Date.now() }, operation) {\n const storableRequest = await StorableRequest.fromRequest(request.clone());\n const entry = {\n requestData: storableRequest.toObject(),\n timestamp\n };\n if (metadata) {\n entry.metadata = metadata;\n }\n switch(operation){\n case \"push\":\n await this._queueStore.pushEntry(entry);\n break;\n case \"unshift\":\n await this._queueStore.unshiftEntry(entry);\n break;\n }\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Request for '${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(request.url)}' has ` + `been added to background sync queue '${this._name}'.`);\n }\n if (this._syncInProgress) {\n this._requestsAddedDuringSync = true;\n } else {\n await this.registerSync();\n }\n }\n async _removeRequest(operation) {\n const now = Date.now();\n let entry;\n switch(operation){\n case \"pop\":\n entry = await this._queueStore.popEntry();\n break;\n case \"shift\":\n entry = await this._queueStore.shiftEntry();\n break;\n }\n if (entry) {\n const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n if (now - entry.timestamp > maxRetentionTimeInMs) {\n return this._removeRequest(operation);\n }\n return convertEntry(entry);\n }\n return undefined;\n }\n async replayRequests() {\n let entry;\n while(entry = await this.shiftRequest()){\n try {\n await fetch(entry.request.clone());\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Request for '${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(entry.request.url)}' ` + `has been replayed in queue '${this._name}'`);\n }\n } catch {\n await this.unshiftRequest(entry);\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Request for '${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(entry.request.url)}' ` + `failed to replay, putting it back in queue '${this._name}'`);\n }\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"queue-replay-failed\", {\n name: this._name\n });\n }\n }\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`All requests in queue '${this.name}' have successfully replayed; the queue is now empty!`);\n }\n }\n async registerSync() {\n if (\"sync\" in self.registration && !this._forceSyncFallback) {\n try {\n await self.registration.sync.register(`${TAG_PREFIX}:${this._name}`);\n } catch (err) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.warn(`Unable to register sync event for '${this._name}'.`, err);\n }\n }\n }\n }\n _addSyncListener() {\n if (\"sync\" in self.registration && !this._forceSyncFallback) {\n self.addEventListener(\"sync\", (event)=>{\n if (event.tag === `${TAG_PREFIX}:${this._name}`) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Background sync for tag '${event.tag}' has been received`);\n }\n const syncComplete = async ()=>{\n this._syncInProgress = true;\n let syncError;\n try {\n await this._onSync({\n queue: this\n });\n } catch (error) {\n if (error instanceof Error) {\n syncError = error;\n throw syncError;\n }\n } finally{\n if (this._requestsAddedDuringSync && !(syncError && !event.lastChance)) {\n await this.registerSync();\n }\n this._syncInProgress = false;\n this._requestsAddedDuringSync = false;\n }\n };\n event.waitUntil(syncComplete());\n }\n });\n } else {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(\"Background sync replaying without background sync event\");\n }\n void this._onSync({\n queue: this\n });\n }\n }\n static get _queueNames() {\n return queueNames;\n }\n}\n\nclass BackgroundSyncPlugin {\n _queue;\n constructor(name, options){\n this._queue = new BackgroundSyncQueue(name, options);\n }\n async fetchDidFail({ request }) {\n await this._queue.pushRequest({\n request\n });\n }\n}\n\nconst cacheOkAndOpaquePlugin = {\n cacheWillUpdate: async ({ response })=>{\n if (response.status === 200 || response.status === 0) {\n return response;\n }\n return null;\n }\n};\n\nfunction toRequest(input) {\n return typeof input === \"string\" ? new Request(input) : input;\n}\nclass StrategyHandler {\n event;\n request;\n url;\n params;\n _cacheKeys = {};\n _strategy;\n _handlerDeferred;\n _extendLifetimePromises;\n _plugins;\n _pluginStateMap;\n constructor(strategy, options){\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(options.event, ExtendableEvent, {\n moduleName: \"serwist\",\n className: \"StrategyHandler\",\n funcName: \"constructor\",\n paramName: \"options.event\"\n });\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(options.request, Request, {\n moduleName: \"serwist\",\n className: \"StrategyHandler\",\n funcName: \"constructor\",\n paramName: \"options.request\"\n });\n }\n this.event = options.event;\n this.request = options.request;\n if (options.url) {\n this.url = options.url;\n this.params = options.params;\n }\n this._strategy = strategy;\n this._handlerDeferred = new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.D();\n this._extendLifetimePromises = [];\n this._plugins = [\n ...strategy.plugins\n ];\n this._pluginStateMap = new Map();\n for (const plugin of this._plugins){\n this._pluginStateMap.set(plugin, {});\n }\n this.event.waitUntil(this._handlerDeferred.promise);\n }\n async fetch(input) {\n const { event } = this;\n let request = toRequest(input);\n const preloadResponse = await this.getPreloadResponse();\n if (preloadResponse) {\n return preloadResponse;\n }\n const originalRequest = this.hasCallback(\"fetchDidFail\") ? request.clone() : null;\n try {\n for (const cb of this.iterateCallbacks(\"requestWillFetch\")){\n request = await cb({\n request: request.clone(),\n event\n });\n }\n } catch (err) {\n if (err instanceof Error) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"plugin-error-request-will-fetch\", {\n thrownErrorMessage: err.message\n });\n }\n }\n const pluginFilteredRequest = request.clone();\n try {\n let fetchResponse;\n fetchResponse = await fetch(request, request.mode === \"navigate\" ? undefined : this._strategy.fetchOptions);\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`Network request for '${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(request.url)}' returned a response with status '${fetchResponse.status}'.`);\n }\n for (const callback of this.iterateCallbacks(\"fetchDidSucceed\")){\n fetchResponse = await callback({\n event,\n request: pluginFilteredRequest,\n response: fetchResponse\n });\n }\n return fetchResponse;\n } catch (error) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Network request for '${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(request.url)}' threw an error.`, error);\n }\n if (originalRequest) {\n await this.runCallbacks(\"fetchDidFail\", {\n error: error,\n event,\n originalRequest: originalRequest.clone(),\n request: pluginFilteredRequest.clone()\n });\n }\n throw error;\n }\n }\n async fetchAndCachePut(input) {\n const response = await this.fetch(input);\n const responseClone = response.clone();\n void this.waitUntil(this.cachePut(input, responseClone));\n return response;\n }\n async cacheMatch(key) {\n const request = toRequest(key);\n let cachedResponse;\n const { cacheName, matchOptions } = this._strategy;\n const effectiveRequest = await this.getCacheKey(request, \"read\");\n const multiMatchOptions = {\n ...matchOptions,\n ...{\n cacheName\n }\n };\n cachedResponse = await caches.match(effectiveRequest, multiMatchOptions);\n if (true) {\n if (cachedResponse) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`Found a cached response in '${cacheName}'.`);\n } else {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`No cached response found in '${cacheName}'.`);\n }\n }\n for (const callback of this.iterateCallbacks(\"cachedResponseWillBeUsed\")){\n cachedResponse = await callback({\n cacheName,\n matchOptions,\n cachedResponse,\n request: effectiveRequest,\n event: this.event\n }) || undefined;\n }\n return cachedResponse;\n }\n async cachePut(key, response) {\n const request = toRequest(key);\n await (0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.t)(0);\n const effectiveRequest = await this.getCacheKey(request, \"write\");\n if (true) {\n if (effectiveRequest.method && effectiveRequest.method !== \"GET\") {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"attempt-to-cache-non-get-request\", {\n url: (0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(effectiveRequest.url),\n method: effectiveRequest.method\n });\n }\n }\n if (!response) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.error(`Cannot cache non-existent response for '${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(effectiveRequest.url)}'.`);\n }\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"cache-put-with-no-response\", {\n url: (0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(effectiveRequest.url)\n });\n }\n const responseToCache = await this._ensureResponseSafeToCache(response);\n if (!responseToCache) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`Response '${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(effectiveRequest.url)}' will not be cached.`, responseToCache);\n }\n return false;\n }\n const { cacheName, matchOptions } = this._strategy;\n const cache = await self.caches.open(cacheName);\n if (true) {\n const vary = response.headers.get(\"Vary\");\n if (vary && matchOptions?.ignoreVary !== true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`The response for ${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(effectiveRequest.url)} has a 'Vary: ${vary}' header. Consider setting the {ignoreVary: true} option on your strategy to ensure cache matching and deletion works as expected.`);\n }\n }\n const hasCacheUpdateCallback = this.hasCallback(\"cacheDidUpdate\");\n const oldResponse = hasCacheUpdateCallback ? await (0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.e)(cache, effectiveRequest.clone(), [\n \"__WB_REVISION__\"\n ], matchOptions) : null;\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`Updating the '${cacheName}' cache with a new Response for ${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(effectiveRequest.url)}.`);\n }\n try {\n await cache.put(effectiveRequest, hasCacheUpdateCallback ? responseToCache.clone() : responseToCache);\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === \"QuotaExceededError\") {\n await (0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.h)();\n }\n throw error;\n }\n }\n for (const callback of this.iterateCallbacks(\"cacheDidUpdate\")){\n await callback({\n cacheName,\n oldResponse,\n newResponse: responseToCache.clone(),\n request: effectiveRequest,\n event: this.event\n });\n }\n return true;\n }\n async getCacheKey(request, mode) {\n const key = `${request.url} | ${mode}`;\n if (!this._cacheKeys[key]) {\n let effectiveRequest = request;\n for (const callback of this.iterateCallbacks(\"cacheKeyWillBeUsed\")){\n effectiveRequest = toRequest(await callback({\n mode,\n request: effectiveRequest,\n event: this.event,\n params: this.params\n }));\n }\n this._cacheKeys[key] = effectiveRequest;\n }\n return this._cacheKeys[key];\n }\n hasCallback(name) {\n for (const plugin of this._strategy.plugins){\n if (name in plugin) {\n return true;\n }\n }\n return false;\n }\n async runCallbacks(name, param) {\n for (const callback of this.iterateCallbacks(name)){\n await callback(param);\n }\n }\n *iterateCallbacks(name) {\n for (const plugin of this._strategy.plugins){\n if (typeof plugin[name] === \"function\") {\n const state = this._pluginStateMap.get(plugin);\n const statefulCallback = (param)=>{\n const statefulParam = {\n ...param,\n state\n };\n return plugin[name](statefulParam);\n };\n yield statefulCallback;\n }\n }\n }\n waitUntil(promise) {\n this._extendLifetimePromises.push(promise);\n return promise;\n }\n async doneWaiting() {\n let promise;\n while(promise = this._extendLifetimePromises.shift()){\n await promise;\n }\n }\n destroy() {\n this._handlerDeferred.resolve(null);\n }\n async getPreloadResponse() {\n if (this.event instanceof FetchEvent && this.event.request.mode === \"navigate\" && \"preloadResponse\" in this.event) {\n try {\n const possiblePreloadResponse = await this.event.preloadResponse;\n if (possiblePreloadResponse) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Using a preloaded navigation response for '${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(this.event.request.url)}'`);\n }\n return possiblePreloadResponse;\n }\n } catch (error) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.error(error);\n }\n return undefined;\n }\n }\n return undefined;\n }\n async _ensureResponseSafeToCache(response) {\n let responseToCache = response;\n let pluginsUsed = false;\n for (const callback of this.iterateCallbacks(\"cacheWillUpdate\")){\n responseToCache = await callback({\n request: this.request,\n response: responseToCache,\n event: this.event\n }) || undefined;\n pluginsUsed = true;\n if (!responseToCache) {\n break;\n }\n }\n if (!pluginsUsed) {\n if (responseToCache && responseToCache.status !== 200) {\n if (true) {\n if (responseToCache.status === 0) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.warn(`The response for '${this.request.url}' is an opaque response. The caching strategy that you're using will not cache opaque responses by default.`);\n } else {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`The response for '${this.request.url}' returned a status code of '${response.status}' and won't be cached as a result.`);\n }\n }\n responseToCache = undefined;\n }\n }\n return responseToCache;\n }\n}\n\nclass Strategy {\n cacheName;\n plugins;\n fetchOptions;\n matchOptions;\n constructor(options = {}){\n this.cacheName = _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.c.getRuntimeName(options.cacheName);\n this.plugins = options.plugins || [];\n this.fetchOptions = options.fetchOptions;\n this.matchOptions = options.matchOptions;\n }\n handle(options) {\n const [responseDone] = this.handleAll(options);\n return responseDone;\n }\n handleAll(options) {\n if (options instanceof FetchEvent) {\n options = {\n event: options,\n request: options.request\n };\n }\n const event = options.event;\n const request = typeof options.request === \"string\" ? new Request(options.request) : options.request;\n const handler = new StrategyHandler(this, options.url ? {\n event,\n request,\n url: options.url,\n params: options.params\n } : {\n event,\n request\n });\n const responseDone = this._getResponse(handler, request, event);\n const handlerDone = this._awaitComplete(responseDone, handler, request, event);\n return [\n responseDone,\n handlerDone\n ];\n }\n async _getResponse(handler, request, event) {\n await handler.runCallbacks(\"handlerWillStart\", {\n event,\n request\n });\n let response;\n try {\n response = await this._handle(request, handler);\n if (response === undefined || response.type === \"error\") {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"no-response\", {\n url: request.url\n });\n }\n } catch (error) {\n if (error instanceof Error) {\n for (const callback of handler.iterateCallbacks(\"handlerDidError\")){\n response = await callback({\n error,\n event,\n request\n });\n if (response !== undefined) {\n break;\n }\n }\n }\n if (!response) {\n throw error;\n }\n if (true) {\n throw _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`While responding to '${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(request.url)}', an ${error instanceof Error ? error.toString() : \"\"} error occurred. Using a fallback response provided by a handlerDidError plugin.`);\n }\n }\n for (const callback of handler.iterateCallbacks(\"handlerWillRespond\")){\n response = await callback({\n event,\n request,\n response\n });\n }\n return response;\n }\n async _awaitComplete(responseDone, handler, request, event) {\n let response;\n let error;\n try {\n response = await responseDone;\n } catch {}\n try {\n await handler.runCallbacks(\"handlerDidRespond\", {\n event,\n request,\n response\n });\n await handler.doneWaiting();\n } catch (waitUntilError) {\n if (waitUntilError instanceof Error) {\n error = waitUntilError;\n }\n }\n await handler.runCallbacks(\"handlerDidComplete\", {\n event,\n request,\n response,\n error\n });\n handler.destroy();\n if (error) {\n throw error;\n }\n }\n}\n\nconst messages = {\n strategyStart: (strategyName, request)=>`Using ${strategyName} to respond to '${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(request.url)}'`,\n printFinalResponse: (response)=>{\n if (response) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(\"View the final response here.\");\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(response || \"[No response returned]\");\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n }\n};\n\nclass NetworkFirst extends Strategy {\n _networkTimeoutSeconds;\n constructor(options = {}){\n super(options);\n if (!this.plugins.some((p)=>\"cacheWillUpdate\" in p)) {\n this.plugins.unshift(cacheOkAndOpaquePlugin);\n }\n this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0;\n if (true) {\n if (this._networkTimeoutSeconds) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(this._networkTimeoutSeconds, \"number\", {\n moduleName: \"serwist\",\n className: this.constructor.name,\n funcName: \"constructor\",\n paramName: \"networkTimeoutSeconds\"\n });\n }\n }\n }\n async _handle(request, handler) {\n const logs = [];\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(request, Request, {\n moduleName: \"serwist\",\n className: this.constructor.name,\n funcName: \"handle\",\n paramName: \"makeRequest\"\n });\n }\n const promises = [];\n let timeoutId;\n if (this._networkTimeoutSeconds) {\n const { id, promise } = this._getTimeoutPromise({\n request,\n logs,\n handler\n });\n timeoutId = id;\n promises.push(promise);\n }\n const networkPromise = this._getNetworkPromise({\n timeoutId,\n request,\n logs,\n handler\n });\n promises.push(networkPromise);\n const response = await handler.waitUntil((async ()=>{\n return await handler.waitUntil(Promise.race(promises)) || await networkPromise;\n })());\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(messages.strategyStart(this.constructor.name, request));\n for (const log of logs){\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(log);\n }\n messages.printFinalResponse(response);\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n if (!response) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"no-response\", {\n url: request.url\n });\n }\n return response;\n }\n _getTimeoutPromise({ request, logs, handler }) {\n let timeoutId;\n const timeoutPromise = new Promise((resolve)=>{\n const onNetworkTimeout = async ()=>{\n if (true) {\n logs.push(`Timing out the network response at ${this._networkTimeoutSeconds} seconds.`);\n }\n resolve(await handler.cacheMatch(request));\n };\n timeoutId = setTimeout(onNetworkTimeout, this._networkTimeoutSeconds * 1000);\n });\n return {\n promise: timeoutPromise,\n id: timeoutId\n };\n }\n async _getNetworkPromise({ timeoutId, request, logs, handler }) {\n let error;\n let response;\n try {\n response = await handler.fetchAndCachePut(request);\n } catch (fetchError) {\n if (fetchError instanceof Error) {\n error = fetchError;\n }\n }\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n if (true) {\n if (response) {\n logs.push(\"Got response from network.\");\n } else {\n logs.push(\"Unable to get a response from the network. Will respond \" + \"with a cached response.\");\n }\n }\n if (error || !response) {\n response = await handler.cacheMatch(request);\n if (true) {\n if (response) {\n logs.push(`Found a cached response in the '${this.cacheName}' cache.`);\n } else {\n logs.push(`No response found in the '${this.cacheName}' cache.`);\n }\n }\n }\n return response;\n }\n}\n\nclass NetworkOnly extends Strategy {\n _networkTimeoutSeconds;\n constructor(options = {}){\n super(options);\n this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0;\n }\n async _handle(request, handler) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(request, Request, {\n moduleName: \"serwist\",\n className: this.constructor.name,\n funcName: \"_handle\",\n paramName: \"request\"\n });\n }\n let error;\n let response;\n try {\n const promises = [\n handler.fetch(request)\n ];\n if (this._networkTimeoutSeconds) {\n const timeoutPromise = (0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.t)(this._networkTimeoutSeconds * 1000);\n promises.push(timeoutPromise);\n }\n response = await Promise.race(promises);\n if (!response) {\n throw new Error(`Timed out the network response after ${this._networkTimeoutSeconds} seconds.`);\n }\n } catch (err) {\n if (err instanceof Error) {\n error = err;\n }\n }\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(messages.strategyStart(this.constructor.name, request));\n if (response) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(\"Got response from network.\");\n } else {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(\"Unable to get a response from the network.\");\n }\n messages.printFinalResponse(response);\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n if (!response) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"no-response\", {\n url: request.url,\n error\n });\n }\n return response;\n }\n}\n\nconst defaultMethod = \"GET\";\nconst validMethods = [\n \"DELETE\",\n \"GET\",\n \"HEAD\",\n \"PATCH\",\n \"POST\",\n \"PUT\"\n];\n\nconst normalizeHandler = (handler)=>{\n if (handler && typeof handler === \"object\") {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.hasMethod(handler, \"handle\", {\n moduleName: \"serwist\",\n className: \"Route\",\n funcName: \"constructor\",\n paramName: \"handler\"\n });\n }\n return handler;\n }\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(handler, \"function\", {\n moduleName: \"serwist\",\n className: \"Route\",\n funcName: \"constructor\",\n paramName: \"handler\"\n });\n }\n return {\n handle: handler\n };\n};\n\nclass Route {\n handler;\n match;\n method;\n catchHandler;\n constructor(match, handler, method = defaultMethod){\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(match, \"function\", {\n moduleName: \"serwist\",\n className: \"Route\",\n funcName: \"constructor\",\n paramName: \"match\"\n });\n if (method) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isOneOf(method, validMethods, {\n paramName: \"method\"\n });\n }\n }\n this.handler = normalizeHandler(handler);\n this.match = match;\n this.method = method;\n }\n setCatchHandler(handler) {\n this.catchHandler = normalizeHandler(handler);\n }\n}\n\nclass PrecacheStrategy extends Strategy {\n _fallbackToNetwork;\n static defaultPrecacheCacheabilityPlugin = {\n async cacheWillUpdate ({ response }) {\n if (!response || response.status >= 400) {\n return null;\n }\n return response;\n }\n };\n static copyRedirectedCacheableResponsesPlugin = {\n async cacheWillUpdate ({ response }) {\n return response.redirected ? await copyResponse(response) : response;\n }\n };\n constructor(options = {}){\n options.cacheName = _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.c.getPrecacheName(options.cacheName);\n super(options);\n this._fallbackToNetwork = options.fallbackToNetwork !== false;\n this.plugins.push(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin);\n }\n async _handle(request, handler) {\n const preloadResponse = await handler.getPreloadResponse();\n if (preloadResponse) {\n return preloadResponse;\n }\n const response = await handler.cacheMatch(request);\n if (response) {\n return response;\n }\n if (handler.event && handler.event.type === \"install\") {\n return await this._handleInstall(request, handler);\n }\n return await this._handleFetch(request, handler);\n }\n async _handleFetch(request, handler) {\n let response;\n const params = handler.params || {};\n if (this._fallbackToNetwork) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.warn(`The precached response for ${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(request.url)} in ${this.cacheName} was not found. Falling back to the network.`);\n }\n const integrityInManifest = params.integrity;\n const integrityInRequest = request.integrity;\n const noIntegrityConflict = !integrityInRequest || integrityInRequest === integrityInManifest;\n response = await handler.fetch(new Request(request, {\n integrity: request.mode !== \"no-cors\" ? integrityInRequest || integrityInManifest : undefined\n }));\n if (integrityInManifest && noIntegrityConflict && request.mode !== \"no-cors\") {\n this._useDefaultCacheabilityPluginIfNeeded();\n const wasCached = await handler.cachePut(request, response.clone());\n if (true) {\n if (wasCached) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`A response for ${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(request.url)} was used to \"repair\" the precache.`);\n }\n }\n }\n } else {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"missing-precache-entry\", {\n cacheName: this.cacheName,\n url: request.url\n });\n }\n if (true) {\n const cacheKey = params.cacheKey || await handler.getCacheKey(request, \"read\");\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(`Precaching is responding to: ${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(request.url)}`);\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Serving the precached url: ${(0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(cacheKey instanceof Request ? cacheKey.url : cacheKey)}`);\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(\"View request details here.\");\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(request);\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(\"View response details here.\");\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(response);\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n return response;\n }\n async _handleInstall(request, handler) {\n this._useDefaultCacheabilityPluginIfNeeded();\n const response = await handler.fetch(request);\n const wasCached = await handler.cachePut(request, response.clone());\n if (!wasCached) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"bad-precaching-response\", {\n url: request.url,\n status: response.status\n });\n }\n return response;\n }\n _useDefaultCacheabilityPluginIfNeeded() {\n let defaultPluginIndex = null;\n let cacheWillUpdatePluginCount = 0;\n for (const [index, plugin] of this.plugins.entries()){\n if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) {\n continue;\n }\n if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) {\n defaultPluginIndex = index;\n }\n if (plugin.cacheWillUpdate) {\n cacheWillUpdatePluginCount++;\n }\n }\n if (cacheWillUpdatePluginCount === 0) {\n this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin);\n } else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) {\n this.plugins.splice(defaultPluginIndex, 1);\n }\n }\n}\n\nclass NavigationRoute extends Route {\n _allowlist;\n _denylist;\n constructor(handler, { allowlist = [\n /./\n ], denylist = [] } = {}){\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isArrayOfClass(allowlist, RegExp, {\n moduleName: \"serwist\",\n className: \"NavigationRoute\",\n funcName: \"constructor\",\n paramName: \"options.allowlist\"\n });\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isArrayOfClass(denylist, RegExp, {\n moduleName: \"serwist\",\n className: \"NavigationRoute\",\n funcName: \"constructor\",\n paramName: \"options.denylist\"\n });\n }\n super((options)=>this._match(options), handler);\n this._allowlist = allowlist;\n this._denylist = denylist;\n }\n _match({ url, request }) {\n if (request && request.mode !== \"navigate\") {\n return false;\n }\n const pathnameAndSearch = url.pathname + url.search;\n for (const regExp of this._denylist){\n if (regExp.test(pathnameAndSearch)) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`The navigation route ${pathnameAndSearch} is not being used, since the URL matches this denylist pattern: ${regExp.toString()}`);\n }\n return false;\n }\n }\n if (this._allowlist.some((regExp)=>regExp.test(pathnameAndSearch))) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`The navigation route ${pathnameAndSearch} is being used.`);\n }\n return true;\n }\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`The navigation route ${pathnameAndSearch} is not being used, since the URL being navigated to doesn't match the allowlist.`);\n }\n return false;\n }\n}\n\nconst isNavigationPreloadSupported = ()=>{\n return Boolean(self.registration?.navigationPreload);\n};\nconst enableNavigationPreload = (headerValue)=>{\n if (isNavigationPreloadSupported()) {\n self.addEventListener(\"activate\", (event)=>{\n event.waitUntil(self.registration.navigationPreload.enable().then(()=>{\n if (headerValue) {\n void self.registration.navigationPreload.setHeaderValue(headerValue);\n }\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(\"Navigation preloading is enabled.\");\n }\n }));\n });\n } else {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(\"Navigation preloading is not supported in this browser.\");\n }\n }\n};\nconst disableNavigationPreload = ()=>{\n if (isNavigationPreloadSupported()) {\n self.addEventListener(\"activate\", (event)=>{\n event.waitUntil(self.registration.navigationPreload.disable().then(()=>{\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(\"Navigation preloading is disabled.\");\n }\n }));\n });\n } else {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(\"Navigation preloading is not supported in this browser.\");\n }\n }\n};\n\nconst removeIgnoredSearchParams = (urlObject, ignoreURLParametersMatching = [])=>{\n for (const paramName of [\n ...urlObject.searchParams.keys()\n ]){\n if (ignoreURLParametersMatching.some((regExp)=>regExp.test(paramName))) {\n urlObject.searchParams.delete(paramName);\n }\n }\n return urlObject;\n};\n\nfunction* generateURLVariations(url, { directoryIndex = \"index.html\", ignoreURLParametersMatching = [\n /^utm_/,\n /^fbclid$/\n], cleanURLs = true, urlManipulation } = {}) {\n const urlObject = new URL(url, location.href);\n urlObject.hash = \"\";\n yield urlObject.href;\n const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching);\n yield urlWithoutIgnoredParams.href;\n if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith(\"/\")) {\n const directoryURL = new URL(urlWithoutIgnoredParams.href);\n directoryURL.pathname += directoryIndex;\n yield directoryURL.href;\n }\n if (cleanURLs) {\n const cleanURL = new URL(urlWithoutIgnoredParams.href);\n cleanURL.pathname += \".html\";\n yield cleanURL.href;\n }\n if (urlManipulation) {\n const additionalURLs = urlManipulation({\n url: urlObject\n });\n for (const urlToAttempt of additionalURLs){\n yield urlToAttempt.href;\n }\n }\n}\n\nclass RegExpRoute extends Route {\n constructor(regExp, handler, method){\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(regExp, RegExp, {\n moduleName: \"serwist\",\n className: \"RegExpRoute\",\n funcName: \"constructor\",\n paramName: \"pattern\"\n });\n }\n const match = ({ url })=>{\n const result = regExp.exec(url.href);\n if (!result) {\n return;\n }\n if (url.origin !== location.origin && result.index !== 0) {\n if (true) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`The regular expression '${regExp.toString()}' only partially matched against the cross-origin URL '${url.toString()}'. RegExpRoute's will only handle cross-origin requests if they match the entire URL.`);\n }\n return;\n }\n return result.slice(1);\n };\n super(match, handler, method);\n }\n}\n\nconst setCacheNameDetails = (details)=>{\n if (true) {\n for (const key of Object.keys(details)){\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(details[key], \"string\", {\n moduleName: \"@serwist/core\",\n funcName: \"setCacheNameDetails\",\n paramName: `details.${key}`\n });\n }\n if (details.precache?.length === 0) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"invalid-cache-name\", {\n cacheNameId: \"precache\",\n value: details.precache\n });\n }\n if (details.runtime?.length === 0) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"invalid-cache-name\", {\n cacheNameId: \"runtime\",\n value: details.runtime\n });\n }\n if (details.googleAnalytics?.length === 0) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"invalid-cache-name\", {\n cacheNameId: \"googleAnalytics\",\n value: details.googleAnalytics\n });\n }\n }\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.c.updateDetails(details);\n};\n\nconst REVISION_SEARCH_PARAM = \"__WB_REVISION__\";\nconst createCacheKey = (entry)=>{\n if (!entry) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"add-to-cache-list-unexpected-type\", {\n entry\n });\n }\n if (typeof entry === \"string\") {\n const urlObject = new URL(entry, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href\n };\n }\n const { revision, url } = entry;\n if (!url) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"add-to-cache-list-unexpected-type\", {\n entry\n });\n }\n if (!revision) {\n const urlObject = new URL(url, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href\n };\n }\n const cacheKeyURL = new URL(url, location.href);\n const originalURL = new URL(url, location.href);\n cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);\n return {\n cacheKey: cacheKeyURL.href,\n url: originalURL.href\n };\n};\n\nclass PrecacheInstallReportPlugin {\n updatedURLs = [];\n notUpdatedURLs = [];\n handlerWillStart = async ({ request, state })=>{\n if (state) {\n state.originalRequest = request;\n }\n };\n cachedResponseWillBeUsed = async ({ event, state, cachedResponse })=>{\n if (event.type === \"install\") {\n if (state?.originalRequest && state.originalRequest instanceof Request) {\n const url = state.originalRequest.url;\n if (cachedResponse) {\n this.notUpdatedURLs.push(url);\n } else {\n this.updatedURLs.push(url);\n }\n }\n }\n return cachedResponse;\n };\n}\n\nconst parseRoute = (capture, handler, method)=>{\n if (typeof capture === \"string\") {\n const captureUrl = new URL(capture, location.href);\n if (true) {\n if (!(capture.startsWith(\"/\") || capture.startsWith(\"http\"))) {\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"invalid-string\", {\n moduleName: \"serwist\",\n funcName: \"parseRoute\",\n paramName: \"capture\"\n });\n }\n const valueToCheck = capture.startsWith(\"http\") ? captureUrl.pathname : capture;\n const wildcards = \"[*:?+]\";\n if (new RegExp(`${wildcards}`).exec(valueToCheck)) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`The '$capture' parameter contains an Express-style wildcard character (${wildcards}). Strings are now always interpreted as exact matches; use a RegExp for partial or wildcard matches.`);\n }\n }\n const matchCallback = ({ url })=>{\n if (true) {\n if (url.pathname === captureUrl.pathname && url.origin !== captureUrl.origin) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`${capture} only partially matches the cross-origin URL ${url.toString()}. This route will only handle cross-origin requests if they match the entire URL.`);\n }\n }\n return url.href === captureUrl.href;\n };\n return new Route(matchCallback, handler, method);\n }\n if (capture instanceof RegExp) {\n return new RegExpRoute(capture, handler, method);\n }\n if (typeof capture === \"function\") {\n return new Route(capture, handler, method);\n }\n if (capture instanceof Route) {\n return capture;\n }\n throw new _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"unsupported-route-type\", {\n moduleName: \"serwist\",\n funcName: \"parseRoute\",\n paramName: \"capture\"\n });\n};\n\nconst logGroup = (groupTitle, deletedURLs)=>{\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(groupTitle);\n for (const url of deletedURLs){\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(url);\n }\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n};\nconst printCleanupDetails = (deletedURLs)=>{\n const deletionCount = deletedURLs.length;\n if (deletionCount > 0) {\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(`During precaching cleanup, ${deletionCount} cached request${deletionCount === 1 ? \" was\" : \"s were\"} deleted.`);\n logGroup(\"Deleted Cache Requests\", deletedURLs);\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n};\n\nfunction _nestedGroup(groupTitle, urls) {\n if (urls.length === 0) {\n return;\n }\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(groupTitle);\n for (const url of urls){\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(url);\n }\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n}\nconst printInstallDetails = (urlsToPrecache, urlsAlreadyPrecached)=>{\n const precachedCount = urlsToPrecache.length;\n const alreadyPrecachedCount = urlsAlreadyPrecached.length;\n if (precachedCount || alreadyPrecachedCount) {\n let message = `Precaching ${precachedCount} file${precachedCount === 1 ? \"\" : \"s\"}.`;\n if (alreadyPrecachedCount > 0) {\n message += ` ${alreadyPrecachedCount} ` + `file${alreadyPrecachedCount === 1 ? \" is\" : \"s are\"} already cached.`;\n }\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(message);\n _nestedGroup(\"View newly precached URLs.\", urlsToPrecache);\n _nestedGroup(\"View previously precached URLs.\", urlsAlreadyPrecached);\n _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n};\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvc2Vyd2lzdC9kaXN0L2NodW5rcy9wcmludEluc3RhbGxEZXRhaWxzLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFtUTtBQUN0Tzs7QUFFN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsNENBQVk7QUFDOUI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixnREFBa0M7QUFDbkQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsMkNBQU07QUFDbkM7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxJQUFxQztBQUNqRCxZQUFZLDRDQUFrQjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixZQUFZLDRDQUFrQjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLElBQXFDO0FBQ2pELFlBQVksNENBQWtCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FB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QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLGdCQUFnQixNQUFNLGdDQUFnQztBQUMxRjtBQUNBLDJCQUEyQix1QkFBdUIsV0FBVywrQ0FBK0M7QUFDNUc7QUFDQSxRQUFRLDRDQUFNO0FBQ2Q7QUFDQTtBQUNBLFFBQVEsNENBQU07QUFDZDtBQUNBOztBQUUwcEIiLCJzb3VyY2VzIjpbIi9Vc2Vycy9zZDkyMzUvY29kZS9teWdoL2xlYXJuaW5nX2FpX2Nsb2NrL3dlYi9ub2RlX21vZHVsZXMvc2Vyd2lzdC9kaXN0L2NodW5rcy9wcmludEluc3RhbGxEZXRhaWxzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFMgYXMgU2Vyd2lzdEVycm9yLCBkIGFzIGNhbkNvbnN0cnVjdFJlc3BvbnNlRnJvbUJvZHlTdHJlYW0sIGYgYXMgZmluYWxBc3NlcnRFeHBvcnRzLCBsIGFzIGxvZ2dlciwgZyBhcyBnZXRGcmllbmRseVVSTCwgRCBhcyBEZWZlcnJlZCwgdCBhcyB0aW1lb3V0LCBlIGFzIGNhY2hlTWF0Y2hJZ25vcmVQYXJhbXMsIGggYXMgZXhlY3V0ZVF1b3RhRXJyb3JDYWxsYmFja3MsIGMgYXMgY2FjaGVOYW1lcyB9IGZyb20gJy4vd2FpdFVudGlsLmpzJztcbmltcG9ydCB7IG9wZW5EQiB9IGZyb20gJ2lkYic7XG5cbmNvbnN0IGNvcHlSZXNwb25zZSA9IGFzeW5jIChyZXNwb25zZSwgbW9kaWZpZXIpPT57XG4gICAgbGV0IG9yaWdpbiA9IG51bGw7XG4gICAgaWYgKHJlc3BvbnNlLnVybCkge1xuICAgICAgICBjb25zdCByZXNwb25zZVVSTCA9IG5ldyBVUkwocmVzcG9uc2UudXJsKTtcbiAgICAgICAgb3JpZ2luID0gcmVzcG9uc2VVUkwub3JpZ2luO1xuICAgIH1cbiAgICBpZiAob3JpZ2luICE9PSBzZWxmLmxvY2F0aW9uLm9yaWdpbikge1xuICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiY3Jvc3Mtb3JpZ2luLWNvcHktcmVzcG9uc2VcIiwge1xuICAgICAgICAgICAgb3JpZ2luXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zdCBjbG9uZWRSZXNwb25zZSA9IHJlc3BvbnNlLmNsb25lKCk7XG4gICAgY29uc3QgcmVzcG9uc2VJbml0ID0ge1xuICAgICAgICBoZWFkZXJzOiBuZXcgSGVhZGVycyhjbG9uZWRSZXNwb25zZS5oZWFkZXJzKSxcbiAgICAgICAgc3RhdHVzOiBjbG9uZWRSZXNwb25zZS5zdGF0dXMsXG4gICAgICAgIHN0YXR1c1RleHQ6IGNsb25lZFJlc3BvbnNlLnN0YXR1c1RleHRcbiAgICB9O1xuICAgIGNvbnN0IG1vZGlmaWVkUmVzcG9uc2VJbml0ID0gbW9kaWZpZXIgPyBtb2RpZmllcihyZXNwb25zZUluaXQpIDogcmVzcG9uc2VJbml0O1xuICAgIGNvbnN0IGJvZHkgPSBjYW5Db25zdHJ1Y3RSZXNwb25zZUZyb21Cb2R5U3RyZWFtKCkgPyBjbG9uZWRSZXNwb25zZS5ib2R5IDogYXdhaXQgY2xvbmVkUmVzcG9uc2UuYmxvYigpO1xuICAgIHJldHVybiBuZXcgUmVzcG9uc2UoYm9keSwgbW9kaWZpZWRSZXNwb25zZUluaXQpO1xufTtcblxuY29uc3QgZGlzYWJsZURldkxvZ3MgPSAoKT0+e1xuICAgIHNlbGYuX19XQl9ESVNBQkxFX0RFVl9MT0dTID0gdHJ1ZTtcbn07XG5cbmNvbnN0IEJBQ0tHUk9VTkRfU1lOQ19EQl9WRVJTSU9OID0gMztcbmNvbnN0IEJBQ0tHUk9VTkRfU1lOQ19EQl9OQU1FID0gXCJzZXJ3aXN0LWJhY2tncm91bmQtc3luY1wiO1xuY29uc3QgUkVRVUVTVF9PQkpFQ1RfU1RPUkVfTkFNRSA9IFwicmVxdWVzdHNcIjtcbmNvbnN0IFFVRVVFX05BTUVfSU5ERVggPSBcInF1ZXVlTmFtZVwiO1xuY2xhc3MgQmFja2dyb3VuZFN5bmNRdWV1ZURiIHtcbiAgICBfZGIgPSBudWxsO1xuICAgIGFzeW5jIGFkZEVudHJ5KGVudHJ5KSB7XG4gICAgICAgIGNvbnN0IGRiID0gYXdhaXQgdGhpcy5nZXREYigpO1xuICAgICAgICBjb25zdCB0eCA9IGRiLnRyYW5zYWN0aW9uKFJFUVVFU1RfT0JKRUNUX1NUT1JFX05BTUUsIFwicmVhZHdyaXRlXCIsIHtcbiAgICAgICAgICAgIGR1cmFiaWxpdHk6IFwicmVsYXhlZFwiXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCB0eC5zdG9yZS5hZGQoZW50cnkpO1xuICAgICAgICBhd2FpdCB0eC5kb25lO1xuICAgIH1cbiAgICBhc3luYyBnZXRGaXJzdEVudHJ5SWQoKSB7XG4gICAgICAgIGNvbnN0IGRiID0gYXdhaXQgdGhpcy5nZXREYigpO1xuICAgICAgICBjb25zdCBjdXJzb3IgPSBhd2FpdCBkYi50cmFuc2FjdGlvbihSRVFVRVNUX09CSkVDVF9TVE9SRV9OQU1FKS5zdG9yZS5vcGVuQ3Vyc29yKCk7XG4gICAgICAgIHJldHVybiBjdXJzb3I/LnZhbHVlLmlkO1xuICAgIH1cbiAgICBhc3luYyBnZXRBbGxFbnRyaWVzQnlRdWV1ZU5hbWUocXVldWVOYW1lKSB7XG4gICAgICAgIGNvbnN0IGRiID0gYXdhaXQgdGhpcy5nZXREYigpO1xuICAgICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgZGIuZ2V0QWxsRnJvbUluZGV4KFJFUVVFU1RfT0JKRUNUX1NUT1JFX05BTUUsIFFVRVVFX05BTUVfSU5ERVgsIElEQktleVJhbmdlLm9ubHkocXVldWVOYW1lKSk7XG4gICAgICAgIHJldHVybiByZXN1bHRzID8gcmVzdWx0cyA6IFtdO1xuICAgIH1cbiAgICBhc3luYyBnZXRFbnRyeUNvdW50QnlRdWV1ZU5hbWUocXVldWVOYW1lKSB7XG4gICAgICAgIGNvbnN0IGRiID0gYXdhaXQgdGhpcy5nZXREYigpO1xuICAgICAgICByZXR1cm4gZGIuY291bnRGcm9tSW5kZXgoUkVRVUVTVF9PQkpFQ1RfU1RPUkVfTkFNRSwgUVVFVUVfTkFNRV9JTkRFWCwgSURCS2V5UmFuZ2Uub25seShxdWV1ZU5hbWUpKTtcbiAgICB9XG4gICAgYXN5bmMgZGVsZXRlRW50cnkoaWQpIHtcbiAgICAgICAgY29uc3QgZGIgPSBhd2FpdCB0aGlzLmdldERiKCk7XG4gICAgICAgIGF3YWl0IGRiLmRlbGV0ZShSRVFVRVNUX09CSkVDVF9TVE9SRV9OQU1FLCBpZCk7XG4gICAgfVxuICAgIGFzeW5jIGdldEZpcnN0RW50cnlCeVF1ZXVlTmFtZShxdWV1ZU5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0RW5kRW50cnlGcm9tSW5kZXgoSURCS2V5UmFuZ2Uub25seShxdWV1ZU5hbWUpLCBcIm5leHRcIik7XG4gICAgfVxuICAgIGFzeW5jIGdldExhc3RFbnRyeUJ5UXVldWVOYW1lKHF1ZXVlTmFtZSkge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5nZXRFbmRFbnRyeUZyb21JbmRleChJREJLZXlSYW5nZS5vbmx5KHF1ZXVlTmFtZSksIFwicHJldlwiKTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0RW5kRW50cnlGcm9tSW5kZXgocXVlcnksIGRpcmVjdGlvbikge1xuICAgICAgICBjb25zdCBkYiA9IGF3YWl0IHRoaXMuZ2V0RGIoKTtcbiAgICAgICAgY29uc3QgY3Vyc29yID0gYXdhaXQgZGIudHJhbnNhY3Rpb24oUkVRVUVTVF9PQkpFQ1RfU1RPUkVfTkFNRSkuc3RvcmUuaW5kZXgoUVVFVUVfTkFNRV9JTkRFWCkub3BlbkN1cnNvcihxdWVyeSwgZGlyZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIGN1cnNvcj8udmFsdWU7XG4gICAgfVxuICAgIGFzeW5jIGdldERiKCkge1xuICAgICAgICBpZiAoIXRoaXMuX2RiKSB7XG4gICAgICAgICAgICB0aGlzLl9kYiA9IGF3YWl0IG9wZW5EQihCQUNLR1JPVU5EX1NZTkNfREJfTkFNRSwgQkFDS0dST1VORF9TWU5DX0RCX1ZFUlNJT04sIHtcbiAgICAgICAgICAgICAgICB1cGdyYWRlOiB0aGlzLl91cGdyYWRlRGJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9kYjtcbiAgICB9XG4gICAgX3VwZ3JhZGVEYihkYiwgb2xkVmVyc2lvbikge1xuICAgICAgICBpZiAob2xkVmVyc2lvbiA+IDAgJiYgb2xkVmVyc2lvbiA8IEJBQ0tHUk9VTkRfU1lOQ19EQl9WRVJTSU9OKSB7XG4gICAgICAgICAgICBpZiAoZGIub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhSRVFVRVNUX09CSkVDVF9TVE9SRV9OQU1FKSkge1xuICAgICAgICAgICAgICAgIGRiLmRlbGV0ZU9iamVjdFN0b3JlKFJFUVVFU1RfT0JKRUNUX1NUT1JFX05BTUUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9ialN0b3JlID0gZGIuY3JlYXRlT2JqZWN0U3RvcmUoUkVRVUVTVF9PQkpFQ1RfU1RPUkVfTkFNRSwge1xuICAgICAgICAgICAgYXV0b0luY3JlbWVudDogdHJ1ZSxcbiAgICAgICAgICAgIGtleVBhdGg6IFwiaWRcIlxuICAgICAgICB9KTtcbiAgICAgICAgb2JqU3RvcmUuY3JlYXRlSW5kZXgoUVVFVUVfTkFNRV9JTkRFWCwgUVVFVUVfTkFNRV9JTkRFWCwge1xuICAgICAgICAgICAgdW5pcXVlOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICB9XG59XG5cbmNsYXNzIEJhY2tncm91bmRTeW5jUXVldWVTdG9yZSB7XG4gICAgX3F1ZXVlTmFtZTtcbiAgICBfcXVldWVEYjtcbiAgICBjb25zdHJ1Y3RvcihxdWV1ZU5hbWUpe1xuICAgICAgICB0aGlzLl9xdWV1ZU5hbWUgPSBxdWV1ZU5hbWU7XG4gICAgICAgIHRoaXMuX3F1ZXVlRGIgPSBuZXcgQmFja2dyb3VuZFN5bmNRdWV1ZURiKCk7XG4gICAgfVxuICAgIGFzeW5jIHB1c2hFbnRyeShlbnRyeSkge1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNUeXBlKGVudHJ5LCBcIm9iamVjdFwiLCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIkJhY2tncm91bmRTeW5jUXVldWVTdG9yZVwiLFxuICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcInB1c2hFbnRyeVwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJlbnRyeVwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc1R5cGUoZW50cnkucmVxdWVzdERhdGEsIFwib2JqZWN0XCIsIHtcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiQmFja2dyb3VuZFN5bmNRdWV1ZVN0b3JlXCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwicHVzaEVudHJ5XCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcImVudHJ5LnJlcXVlc3REYXRhXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGRlbGV0ZSBlbnRyeS5pZDtcbiAgICAgICAgZW50cnkucXVldWVOYW1lID0gdGhpcy5fcXVldWVOYW1lO1xuICAgICAgICBhd2FpdCB0aGlzLl9xdWV1ZURiLmFkZEVudHJ5KGVudHJ5KTtcbiAgICB9XG4gICAgYXN5bmMgdW5zaGlmdEVudHJ5KGVudHJ5KSB7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc1R5cGUoZW50cnksIFwib2JqZWN0XCIsIHtcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiQmFja2dyb3VuZFN5bmNRdWV1ZVN0b3JlXCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwidW5zaGlmdEVudHJ5XCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcImVudHJ5XCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzVHlwZShlbnRyeS5yZXF1ZXN0RGF0YSwgXCJvYmplY3RcIiwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJCYWNrZ3JvdW5kU3luY1F1ZXVlU3RvcmVcIixcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJ1bnNoaWZ0RW50cnlcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwiZW50cnkucmVxdWVzdERhdGFcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmlyc3RJZCA9IGF3YWl0IHRoaXMuX3F1ZXVlRGIuZ2V0Rmlyc3RFbnRyeUlkKCk7XG4gICAgICAgIGlmIChmaXJzdElkKSB7XG4gICAgICAgICAgICBlbnRyeS5pZCA9IGZpcnN0SWQgLSAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsZXRlIGVudHJ5LmlkO1xuICAgICAgICB9XG4gICAgICAgIGVudHJ5LnF1ZXVlTmFtZSA9IHRoaXMuX3F1ZXVlTmFtZTtcbiAgICAgICAgYXdhaXQgdGhpcy5fcXVldWVEYi5hZGRFbnRyeShlbnRyeSk7XG4gICAgfVxuICAgIGFzeW5jIHBvcEVudHJ5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVtb3ZlRW50cnkoYXdhaXQgdGhpcy5fcXVldWVEYi5nZXRMYXN0RW50cnlCeVF1ZXVlTmFtZSh0aGlzLl9xdWV1ZU5hbWUpKTtcbiAgICB9XG4gICAgYXN5bmMgc2hpZnRFbnRyeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlbW92ZUVudHJ5KGF3YWl0IHRoaXMuX3F1ZXVlRGIuZ2V0Rmlyc3RFbnRyeUJ5UXVldWVOYW1lKHRoaXMuX3F1ZXVlTmFtZSkpO1xuICAgIH1cbiAgICBhc3luYyBnZXRBbGwoKSB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9xdWV1ZURiLmdldEFsbEVudHJpZXNCeVF1ZXVlTmFtZSh0aGlzLl9xdWV1ZU5hbWUpO1xuICAgIH1cbiAgICBhc3luYyBzaXplKCkge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fcXVldWVEYi5nZXRFbnRyeUNvdW50QnlRdWV1ZU5hbWUodGhpcy5fcXVldWVOYW1lKTtcbiAgICB9XG4gICAgYXN5bmMgZGVsZXRlRW50cnkoaWQpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5fcXVldWVEYi5kZWxldGVFbnRyeShpZCk7XG4gICAgfVxuICAgIGFzeW5jIF9yZW1vdmVFbnRyeShlbnRyeSkge1xuICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZGVsZXRlRW50cnkoZW50cnkuaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbnRyeTtcbiAgICB9XG59XG5cbmNvbnN0IHNlcmlhbGl6YWJsZVByb3BlcnRpZXMgPSBbXG4gICAgXCJtZXRob2RcIixcbiAgICBcInJlZmVycmVyXCIsXG4gICAgXCJyZWZlcnJlclBvbGljeVwiLFxuICAgIFwibW9kZVwiLFxuICAgIFwiY3JlZGVudGlhbHNcIixcbiAgICBcImNhY2hlXCIsXG4gICAgXCJyZWRpcmVjdFwiLFxuICAgIFwiaW50ZWdyaXR5XCIsXG4gICAgXCJrZWVwYWxpdmVcIlxuXTtcbmNsYXNzIFN0b3JhYmxlUmVxdWVzdCB7XG4gICAgX3JlcXVlc3REYXRhO1xuICAgIHN0YXRpYyBhc3luYyBmcm9tUmVxdWVzdChyZXF1ZXN0KSB7XG4gICAgICAgIGNvbnN0IHJlcXVlc3REYXRhID0ge1xuICAgICAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgICAgIGhlYWRlcnM6IHt9XG4gICAgICAgIH07XG4gICAgICAgIGlmIChyZXF1ZXN0Lm1ldGhvZCAhPT0gXCJHRVRcIikge1xuICAgICAgICAgICAgcmVxdWVzdERhdGEuYm9keSA9IGF3YWl0IHJlcXVlc3QuY2xvbmUoKS5hcnJheUJ1ZmZlcigpO1xuICAgICAgICB9XG4gICAgICAgIHJlcXVlc3QuaGVhZGVycy5mb3JFYWNoKCh2YWx1ZSwga2V5KT0+e1xuICAgICAgICAgICAgcmVxdWVzdERhdGEuaGVhZGVyc1trZXldID0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgICBmb3IgKGNvbnN0IHByb3Agb2Ygc2VyaWFsaXphYmxlUHJvcGVydGllcyl7XG4gICAgICAgICAgICBpZiAocmVxdWVzdFtwcm9wXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmVxdWVzdERhdGFbcHJvcF0gPSByZXF1ZXN0W3Byb3BdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgU3RvcmFibGVSZXF1ZXN0KHJlcXVlc3REYXRhKTtcbiAgICB9XG4gICAgY29uc3RydWN0b3IocmVxdWVzdERhdGEpe1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNUeXBlKHJlcXVlc3REYXRhLCBcIm9iamVjdFwiLCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIlN0b3JhYmxlUmVxdWVzdFwiLFxuICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNvbnN0cnVjdG9yXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcInJlcXVlc3REYXRhXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzVHlwZShyZXF1ZXN0RGF0YS51cmwsIFwic3RyaW5nXCIsIHtcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiU3RvcmFibGVSZXF1ZXN0XCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiY29uc3RydWN0b3JcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwicmVxdWVzdERhdGEudXJsXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXF1ZXN0RGF0YS5tb2RlID09PSBcIm5hdmlnYXRlXCIpIHtcbiAgICAgICAgICAgIHJlcXVlc3REYXRhLm1vZGUgPSBcInNhbWUtb3JpZ2luXCI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcmVxdWVzdERhdGEgPSByZXF1ZXN0RGF0YTtcbiAgICB9XG4gICAgdG9PYmplY3QoKSB7XG4gICAgICAgIGNvbnN0IHJlcXVlc3REYXRhID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5fcmVxdWVzdERhdGEpO1xuICAgICAgICByZXF1ZXN0RGF0YS5oZWFkZXJzID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5fcmVxdWVzdERhdGEuaGVhZGVycyk7XG4gICAgICAgIGlmIChyZXF1ZXN0RGF0YS5ib2R5KSB7XG4gICAgICAgICAgICByZXF1ZXN0RGF0YS5ib2R5ID0gcmVxdWVzdERhdGEuYm9keS5zbGljZSgwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVxdWVzdERhdGE7XG4gICAgfVxuICAgIHRvUmVxdWVzdCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXF1ZXN0KHRoaXMuX3JlcXVlc3REYXRhLnVybCwgdGhpcy5fcmVxdWVzdERhdGEpO1xuICAgIH1cbiAgICBjbG9uZSgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdG9yYWJsZVJlcXVlc3QodGhpcy50b09iamVjdCgpKTtcbiAgICB9XG59XG5cbmNvbnN0IFRBR19QUkVGSVggPSBcInNlcndpc3QtYmFja2dyb3VuZC1zeW5jXCI7XG5jb25zdCBNQVhfUkVURU5USU9OX1RJTUUgPSA2MCAqIDI0ICogNztcbmNvbnN0IHF1ZXVlTmFtZXMgPSBuZXcgU2V0KCk7XG5jb25zdCBjb252ZXJ0RW50cnkgPSAocXVldWVTdG9yZUVudHJ5KT0+e1xuICAgIGNvbnN0IHF1ZXVlRW50cnkgPSB7XG4gICAgICAgIHJlcXVlc3Q6IG5ldyBTdG9yYWJsZVJlcXVlc3QocXVldWVTdG9yZUVudHJ5LnJlcXVlc3REYXRhKS50b1JlcXVlc3QoKSxcbiAgICAgICAgdGltZXN0YW1wOiBxdWV1ZVN0b3JlRW50cnkudGltZXN0YW1wXG4gICAgfTtcbiAgICBpZiAocXVldWVTdG9yZUVudHJ5Lm1ldGFkYXRhKSB7XG4gICAgICAgIHF1ZXVlRW50cnkubWV0YWRhdGEgPSBxdWV1ZVN0b3JlRW50cnkubWV0YWRhdGE7XG4gICAgfVxuICAgIHJldHVybiBxdWV1ZUVudHJ5O1xufTtcbmNsYXNzIEJhY2tncm91bmRTeW5jUXVldWUge1xuICAgIF9uYW1lO1xuICAgIF9vblN5bmM7XG4gICAgX21heFJldGVudGlvblRpbWU7XG4gICAgX3F1ZXVlU3RvcmU7XG4gICAgX2ZvcmNlU3luY0ZhbGxiYWNrO1xuICAgIF9zeW5jSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgIF9yZXF1ZXN0c0FkZGVkRHVyaW5nU3luYyA9IGZhbHNlO1xuICAgIGNvbnN0cnVjdG9yKG5hbWUsIHsgZm9yY2VTeW5jRmFsbGJhY2ssIG9uU3luYywgbWF4UmV0ZW50aW9uVGltZSB9ID0ge30pe1xuICAgICAgICBpZiAocXVldWVOYW1lcy5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJkdXBsaWNhdGUtcXVldWUtbmFtZVwiLCB7XG4gICAgICAgICAgICAgICAgbmFtZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVOYW1lcy5hZGQobmFtZSk7XG4gICAgICAgIHRoaXMuX25hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLl9vblN5bmMgPSBvblN5bmMgfHwgdGhpcy5yZXBsYXlSZXF1ZXN0cztcbiAgICAgICAgdGhpcy5fbWF4UmV0ZW50aW9uVGltZSA9IG1heFJldGVudGlvblRpbWUgfHwgTUFYX1JFVEVOVElPTl9USU1FO1xuICAgICAgICB0aGlzLl9mb3JjZVN5bmNGYWxsYmFjayA9IEJvb2xlYW4oZm9yY2VTeW5jRmFsbGJhY2spO1xuICAgICAgICB0aGlzLl9xdWV1ZVN0b3JlID0gbmV3IEJhY2tncm91bmRTeW5jUXVldWVTdG9yZSh0aGlzLl9uYW1lKTtcbiAgICAgICAgdGhpcy5fYWRkU3luY0xpc3RlbmVyKCk7XG4gICAgfVxuICAgIGdldCBuYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbmFtZTtcbiAgICB9XG4gICAgYXN5bmMgcHVzaFJlcXVlc3QoZW50cnkpIHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzVHlwZShlbnRyeSwgXCJvYmplY3RcIiwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJCYWNrZ3JvdW5kU3luY1F1ZXVlXCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwicHVzaFJlcXVlc3RcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwiZW50cnlcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNJbnN0YW5jZShlbnRyeS5yZXF1ZXN0LCBSZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIkJhY2tncm91bmRTeW5jUXVldWVcIixcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJwdXNoUmVxdWVzdFwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJlbnRyeS5yZXF1ZXN0XCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuX2FkZFJlcXVlc3QoZW50cnksIFwicHVzaFwiKTtcbiAgICB9XG4gICAgYXN5bmMgdW5zaGlmdFJlcXVlc3QoZW50cnkpIHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzVHlwZShlbnRyeSwgXCJvYmplY3RcIiwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJCYWNrZ3JvdW5kU3luY1F1ZXVlXCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwidW5zaGlmdFJlcXVlc3RcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwiZW50cnlcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNJbnN0YW5jZShlbnRyeS5yZXF1ZXN0LCBSZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIkJhY2tncm91bmRTeW5jUXVldWVcIixcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJ1bnNoaWZ0UmVxdWVzdFwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJlbnRyeS5yZXF1ZXN0XCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuX2FkZFJlcXVlc3QoZW50cnksIFwidW5zaGlmdFwiKTtcbiAgICB9XG4gICAgYXN5bmMgcG9wUmVxdWVzdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlbW92ZVJlcXVlc3QoXCJwb3BcIik7XG4gICAgfVxuICAgIGFzeW5jIHNoaWZ0UmVxdWVzdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlbW92ZVJlcXVlc3QoXCJzaGlmdFwiKTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0QWxsKCkge1xuICAgICAgICBjb25zdCBhbGxFbnRyaWVzID0gYXdhaXQgdGhpcy5fcXVldWVTdG9yZS5nZXRBbGwoKTtcbiAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgY29uc3QgdW5leHBpcmVkRW50cmllcyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGFsbEVudHJpZXMpe1xuICAgICAgICAgICAgY29uc3QgbWF4UmV0ZW50aW9uVGltZUluTXMgPSB0aGlzLl9tYXhSZXRlbnRpb25UaW1lICogNjAgKiAxMDAwO1xuICAgICAgICAgICAgaWYgKG5vdyAtIGVudHJ5LnRpbWVzdGFtcCA+IG1heFJldGVudGlvblRpbWVJbk1zKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5fcXVldWVTdG9yZS5kZWxldGVFbnRyeShlbnRyeS5pZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHVuZXhwaXJlZEVudHJpZXMucHVzaChjb252ZXJ0RW50cnkoZW50cnkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5leHBpcmVkRW50cmllcztcbiAgICB9XG4gICAgYXN5bmMgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX3F1ZXVlU3RvcmUuc2l6ZSgpO1xuICAgIH1cbiAgICBhc3luYyBfYWRkUmVxdWVzdCh7IHJlcXVlc3QsIG1ldGFkYXRhLCB0aW1lc3RhbXAgPSBEYXRlLm5vdygpIH0sIG9wZXJhdGlvbikge1xuICAgICAgICBjb25zdCBzdG9yYWJsZVJlcXVlc3QgPSBhd2FpdCBTdG9yYWJsZVJlcXVlc3QuZnJvbVJlcXVlc3QocmVxdWVzdC5jbG9uZSgpKTtcbiAgICAgICAgY29uc3QgZW50cnkgPSB7XG4gICAgICAgICAgICByZXF1ZXN0RGF0YTogc3RvcmFibGVSZXF1ZXN0LnRvT2JqZWN0KCksXG4gICAgICAgICAgICB0aW1lc3RhbXBcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKG1ldGFkYXRhKSB7XG4gICAgICAgICAgICBlbnRyeS5tZXRhZGF0YSA9IG1ldGFkYXRhO1xuICAgICAgICB9XG4gICAgICAgIHN3aXRjaChvcGVyYXRpb24pe1xuICAgICAgICAgICAgY2FzZSBcInB1c2hcIjpcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLl9xdWV1ZVN0b3JlLnB1c2hFbnRyeShlbnRyeSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwidW5zaGlmdFwiOlxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuX3F1ZXVlU3RvcmUudW5zaGlmdEVudHJ5KGVudHJ5KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBsb2dnZXIubG9nKGBSZXF1ZXN0IGZvciAnJHtnZXRGcmllbmRseVVSTChyZXF1ZXN0LnVybCl9JyBoYXMgYCArIGBiZWVuIGFkZGVkIHRvIGJhY2tncm91bmQgc3luYyBxdWV1ZSAnJHt0aGlzLl9uYW1lfScuYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3N5bmNJblByb2dyZXNzKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXF1ZXN0c0FkZGVkRHVyaW5nU3luYyA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyU3luYygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIF9yZW1vdmVSZXF1ZXN0KG9wZXJhdGlvbikge1xuICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICBsZXQgZW50cnk7XG4gICAgICAgIHN3aXRjaChvcGVyYXRpb24pe1xuICAgICAgICAgICAgY2FzZSBcInBvcFwiOlxuICAgICAgICAgICAgICAgIGVudHJ5ID0gYXdhaXQgdGhpcy5fcXVldWVTdG9yZS5wb3BFbnRyeSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcInNoaWZ0XCI6XG4gICAgICAgICAgICAgICAgZW50cnkgPSBhd2FpdCB0aGlzLl9xdWV1ZVN0b3JlLnNoaWZ0RW50cnkoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICAgIGNvbnN0IG1heFJldGVudGlvblRpbWVJbk1zID0gdGhpcy5fbWF4UmV0ZW50aW9uVGltZSAqIDYwICogMTAwMDtcbiAgICAgICAgICAgIGlmIChub3cgLSBlbnRyeS50aW1lc3RhbXAgPiBtYXhSZXRlbnRpb25UaW1lSW5Ncykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZW1vdmVSZXF1ZXN0KG9wZXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY29udmVydEVudHJ5KGVudHJ5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBhc3luYyByZXBsYXlSZXF1ZXN0cygpIHtcbiAgICAgICAgbGV0IGVudHJ5O1xuICAgICAgICB3aGlsZShlbnRyeSA9IGF3YWl0IHRoaXMuc2hpZnRSZXF1ZXN0KCkpe1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBmZXRjaChlbnRyeS5yZXF1ZXN0LmNsb25lKCkpO1xuICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhgUmVxdWVzdCBmb3IgJyR7Z2V0RnJpZW5kbHlVUkwoZW50cnkucmVxdWVzdC51cmwpfScgYCArIGBoYXMgYmVlbiByZXBsYXllZCBpbiBxdWV1ZSAnJHt0aGlzLl9uYW1lfSdgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoICB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy51bnNoaWZ0UmVxdWVzdChlbnRyeSk7XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKGBSZXF1ZXN0IGZvciAnJHtnZXRGcmllbmRseVVSTChlbnRyeS5yZXF1ZXN0LnVybCl9JyBgICsgYGZhaWxlZCB0byByZXBsYXksIHB1dHRpbmcgaXQgYmFjayBpbiBxdWV1ZSAnJHt0aGlzLl9uYW1lfSdgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNlcndpc3RFcnJvcihcInF1ZXVlLXJlcGxheS1mYWlsZWRcIiwge1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiB0aGlzLl9uYW1lXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgbG9nZ2VyLmxvZyhgQWxsIHJlcXVlc3RzIGluIHF1ZXVlICcke3RoaXMubmFtZX0nIGhhdmUgc3VjY2Vzc2Z1bGx5IHJlcGxheWVkOyB0aGUgcXVldWUgaXMgbm93IGVtcHR5IWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIHJlZ2lzdGVyU3luYygpIHtcbiAgICAgICAgaWYgKFwic3luY1wiIGluIHNlbGYucmVnaXN0cmF0aW9uICYmICF0aGlzLl9mb3JjZVN5bmNGYWxsYmFjaykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBzZWxmLnJlZ2lzdHJhdGlvbi5zeW5jLnJlZ2lzdGVyKGAke1RBR19QUkVGSVh9OiR7dGhpcy5fbmFtZX1gKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oYFVuYWJsZSB0byByZWdpc3RlciBzeW5jIGV2ZW50IGZvciAnJHt0aGlzLl9uYW1lfScuYCwgZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgX2FkZFN5bmNMaXN0ZW5lcigpIHtcbiAgICAgICAgaWYgKFwic3luY1wiIGluIHNlbGYucmVnaXN0cmF0aW9uICYmICF0aGlzLl9mb3JjZVN5bmNGYWxsYmFjaykge1xuICAgICAgICAgICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKFwic3luY1wiLCAoZXZlbnQpPT57XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LnRhZyA9PT0gYCR7VEFHX1BSRUZJWH06JHt0aGlzLl9uYW1lfWApIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhgQmFja2dyb3VuZCBzeW5jIGZvciB0YWcgJyR7ZXZlbnQudGFnfScgaGFzIGJlZW4gcmVjZWl2ZWRgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzeW5jQ29tcGxldGUgPSBhc3luYyAoKT0+e1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3luY0luUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHN5bmNFcnJvcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5fb25TeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVldWU6IHRoaXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3luY0Vycm9yID0gZXJyb3I7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IHN5bmNFcnJvcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHl7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3JlcXVlc3RzQWRkZWREdXJpbmdTeW5jICYmICEoc3luY0Vycm9yICYmICFldmVudC5sYXN0Q2hhbmNlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyU3luYygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zeW5jSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlcXVlc3RzQWRkZWREdXJpbmdTeW5jID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LndhaXRVbnRpbChzeW5jQ29tcGxldGUoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhcIkJhY2tncm91bmQgc3luYyByZXBsYXlpbmcgd2l0aG91dCBiYWNrZ3JvdW5kIHN5bmMgZXZlbnRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2b2lkIHRoaXMuX29uU3luYyh7XG4gICAgICAgICAgICAgICAgcXVldWU6IHRoaXNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBnZXQgX3F1ZXVlTmFtZXMoKSB7XG4gICAgICAgIHJldHVybiBxdWV1ZU5hbWVzO1xuICAgIH1cbn1cblxuY2xhc3MgQmFja2dyb3VuZFN5bmNQbHVnaW4ge1xuICAgIF9xdWV1ZTtcbiAgICBjb25zdHJ1Y3RvcihuYW1lLCBvcHRpb25zKXtcbiAgICAgICAgdGhpcy5fcXVldWUgPSBuZXcgQmFja2dyb3VuZFN5bmNRdWV1ZShuYW1lLCBvcHRpb25zKTtcbiAgICB9XG4gICAgYXN5bmMgZmV0Y2hEaWRGYWlsKHsgcmVxdWVzdCB9KSB7XG4gICAgICAgIGF3YWl0IHRoaXMuX3F1ZXVlLnB1c2hSZXF1ZXN0KHtcbiAgICAgICAgICAgIHJlcXVlc3RcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5jb25zdCBjYWNoZU9rQW5kT3BhcXVlUGx1Z2luID0ge1xuICAgIGNhY2hlV2lsbFVwZGF0ZTogYXN5bmMgKHsgcmVzcG9uc2UgfSk9PntcbiAgICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gMjAwIHx8IHJlc3BvbnNlLnN0YXR1cyA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIHRvUmVxdWVzdChpbnB1dCkge1xuICAgIHJldHVybiB0eXBlb2YgaW5wdXQgPT09IFwic3RyaW5nXCIgPyBuZXcgUmVxdWVzdChpbnB1dCkgOiBpbnB1dDtcbn1cbmNsYXNzIFN0cmF0ZWd5SGFuZGxlciB7XG4gICAgZXZlbnQ7XG4gICAgcmVxdWVzdDtcbiAgICB1cmw7XG4gICAgcGFyYW1zO1xuICAgIF9jYWNoZUtleXMgPSB7fTtcbiAgICBfc3RyYXRlZ3k7XG4gICAgX2hhbmRsZXJEZWZlcnJlZDtcbiAgICBfZXh0ZW5kTGlmZXRpbWVQcm9taXNlcztcbiAgICBfcGx1Z2lucztcbiAgICBfcGx1Z2luU3RhdGVNYXA7XG4gICAgY29uc3RydWN0b3Ioc3RyYXRlZ3ksIG9wdGlvbnMpe1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNJbnN0YW5jZShvcHRpb25zLmV2ZW50LCBFeHRlbmRhYmxlRXZlbnQsIHtcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiU3RyYXRlZ3lIYW5kbGVyXCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiY29uc3RydWN0b3JcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwib3B0aW9ucy5ldmVudFwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc0luc3RhbmNlKG9wdGlvbnMucmVxdWVzdCwgUmVxdWVzdCwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJTdHJhdGVneUhhbmRsZXJcIixcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJjb25zdHJ1Y3RvclwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJvcHRpb25zLnJlcXVlc3RcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ldmVudCA9IG9wdGlvbnMuZXZlbnQ7XG4gICAgICAgIHRoaXMucmVxdWVzdCA9IG9wdGlvbnMucmVxdWVzdDtcbiAgICAgICAgaWYgKG9wdGlvbnMudXJsKSB7XG4gICAgICAgICAgICB0aGlzLnVybCA9IG9wdGlvbnMudXJsO1xuICAgICAgICAgICAgdGhpcy5wYXJhbXMgPSBvcHRpb25zLnBhcmFtcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zdHJhdGVneSA9IHN0cmF0ZWd5O1xuICAgICAgICB0aGlzLl9oYW5kbGVyRGVmZXJyZWQgPSBuZXcgRGVmZXJyZWQoKTtcbiAgICAgICAgdGhpcy5fZXh0ZW5kTGlmZXRpbWVQcm9taXNlcyA9IFtdO1xuICAgICAgICB0aGlzLl9wbHVnaW5zID0gW1xuICAgICAgICAgICAgLi4uc3RyYXRlZ3kucGx1Z2luc1xuICAgICAgICBdO1xuICAgICAgICB0aGlzLl9wbHVnaW5TdGF0ZU1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgZm9yIChjb25zdCBwbHVnaW4gb2YgdGhpcy5fcGx1Z2lucyl7XG4gICAgICAgICAgICB0aGlzLl9wbHVnaW5TdGF0ZU1hcC5zZXQocGx1Z2luLCB7fSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ldmVudC53YWl0VW50aWwodGhpcy5faGFuZGxlckRlZmVycmVkLnByb21pc2UpO1xuICAgIH1cbiAgICBhc3luYyBmZXRjaChpbnB1dCkge1xuICAgICAgICBjb25zdCB7IGV2ZW50IH0gPSB0aGlzO1xuICAgICAgICBsZXQgcmVxdWVzdCA9IHRvUmVxdWVzdChpbnB1dCk7XG4gICAgICAgIGNvbnN0IHByZWxvYWRSZXNwb25zZSA9IGF3YWl0IHRoaXMuZ2V0UHJlbG9hZFJlc3BvbnNlKCk7XG4gICAgICAgIGlmIChwcmVsb2FkUmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHJldHVybiBwcmVsb2FkUmVzcG9uc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3JpZ2luYWxSZXF1ZXN0ID0gdGhpcy5oYXNDYWxsYmFjayhcImZldGNoRGlkRmFpbFwiKSA/IHJlcXVlc3QuY2xvbmUoKSA6IG51bGw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNiIG9mIHRoaXMuaXRlcmF0ZUNhbGxiYWNrcyhcInJlcXVlc3RXaWxsRmV0Y2hcIikpe1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSBhd2FpdCBjYih7XG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3Q6IHJlcXVlc3QuY2xvbmUoKSxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwicGx1Z2luLWVycm9yLXJlcXVlc3Qtd2lsbC1mZXRjaFwiLCB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93bkVycm9yTWVzc2FnZTogZXJyLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwbHVnaW5GaWx0ZXJlZFJlcXVlc3QgPSByZXF1ZXN0LmNsb25lKCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgZmV0Y2hSZXNwb25zZTtcbiAgICAgICAgICAgIGZldGNoUmVzcG9uc2UgPSBhd2FpdCBmZXRjaChyZXF1ZXN0LCByZXF1ZXN0Lm1vZGUgPT09IFwibmF2aWdhdGVcIiA/IHVuZGVmaW5lZCA6IHRoaXMuX3N0cmF0ZWd5LmZldGNoT3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBOZXR3b3JrIHJlcXVlc3QgZm9yICcke2dldEZyaWVuZGx5VVJMKHJlcXVlc3QudXJsKX0nIHJldHVybmVkIGEgcmVzcG9uc2Ugd2l0aCBzdGF0dXMgJyR7ZmV0Y2hSZXNwb25zZS5zdGF0dXN9Jy5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoY29uc3QgY2FsbGJhY2sgb2YgdGhpcy5pdGVyYXRlQ2FsbGJhY2tzKFwiZmV0Y2hEaWRTdWNjZWVkXCIpKXtcbiAgICAgICAgICAgICAgICBmZXRjaFJlc3BvbnNlID0gYXdhaXQgY2FsbGJhY2soe1xuICAgICAgICAgICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdDogcGx1Z2luRmlsdGVyZWRSZXF1ZXN0LFxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZTogZmV0Y2hSZXNwb25zZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZldGNoUmVzcG9uc2U7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhgTmV0d29yayByZXF1ZXN0IGZvciAnJHtnZXRGcmllbmRseVVSTChyZXF1ZXN0LnVybCl9JyB0aHJldyBhbiBlcnJvci5gLCBlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3JpZ2luYWxSZXF1ZXN0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5ydW5DYWxsYmFja3MoXCJmZXRjaERpZEZhaWxcIiwge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbFJlcXVlc3Q6IG9yaWdpbmFsUmVxdWVzdC5jbG9uZSgpLFxuICAgICAgICAgICAgICAgICAgICByZXF1ZXN0OiBwbHVnaW5GaWx0ZXJlZFJlcXVlc3QuY2xvbmUoKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgZmV0Y2hBbmRDYWNoZVB1dChpbnB1dCkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZmV0Y2goaW5wdXQpO1xuICAgICAgICBjb25zdCByZXNwb25zZUNsb25lID0gcmVzcG9uc2UuY2xvbmUoKTtcbiAgICAgICAgdm9pZCB0aGlzLndhaXRVbnRpbCh0aGlzLmNhY2hlUHV0KGlucHV0LCByZXNwb25zZUNsb25lKSk7XG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG4gICAgYXN5bmMgY2FjaGVNYXRjaChrZXkpIHtcbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IHRvUmVxdWVzdChrZXkpO1xuICAgICAgICBsZXQgY2FjaGVkUmVzcG9uc2U7XG4gICAgICAgIGNvbnN0IHsgY2FjaGVOYW1lLCBtYXRjaE9wdGlvbnMgfSA9IHRoaXMuX3N0cmF0ZWd5O1xuICAgICAgICBjb25zdCBlZmZlY3RpdmVSZXF1ZXN0ID0gYXdhaXQgdGhpcy5nZXRDYWNoZUtleShyZXF1ZXN0LCBcInJlYWRcIik7XG4gICAgICAgIGNvbnN0IG11bHRpTWF0Y2hPcHRpb25zID0ge1xuICAgICAgICAgICAgLi4ubWF0Y2hPcHRpb25zLFxuICAgICAgICAgICAgLi4ue1xuICAgICAgICAgICAgICAgIGNhY2hlTmFtZVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjYWNoZWRSZXNwb25zZSA9IGF3YWl0IGNhY2hlcy5tYXRjaChlZmZlY3RpdmVSZXF1ZXN0LCBtdWx0aU1hdGNoT3B0aW9ucyk7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGlmIChjYWNoZWRSZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgYSBjYWNoZWQgcmVzcG9uc2UgaW4gJyR7Y2FjaGVOYW1lfScuYCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgTm8gY2FjaGVkIHJlc3BvbnNlIGZvdW5kIGluICcke2NhY2hlTmFtZX0nLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgY2FsbGJhY2sgb2YgdGhpcy5pdGVyYXRlQ2FsbGJhY2tzKFwiY2FjaGVkUmVzcG9uc2VXaWxsQmVVc2VkXCIpKXtcbiAgICAgICAgICAgIGNhY2hlZFJlc3BvbnNlID0gYXdhaXQgY2FsbGJhY2soe1xuICAgICAgICAgICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgICAgICAgICBtYXRjaE9wdGlvbnMsXG4gICAgICAgICAgICAgICAgY2FjaGVkUmVzcG9uc2UsXG4gICAgICAgICAgICAgICAgcmVxdWVzdDogZWZmZWN0aXZlUmVxdWVzdCxcbiAgICAgICAgICAgICAgICBldmVudDogdGhpcy5ldmVudFxuICAgICAgICAgICAgfSkgfHwgdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWNoZWRSZXNwb25zZTtcbiAgICB9XG4gICAgYXN5bmMgY2FjaGVQdXQoa2V5LCByZXNwb25zZSkge1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gdG9SZXF1ZXN0KGtleSk7XG4gICAgICAgIGF3YWl0IHRpbWVvdXQoMCk7XG4gICAgICAgIGNvbnN0IGVmZmVjdGl2ZVJlcXVlc3QgPSBhd2FpdCB0aGlzLmdldENhY2hlS2V5KHJlcXVlc3QsIFwid3JpdGVcIik7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGlmIChlZmZlY3RpdmVSZXF1ZXN0Lm1ldGhvZCAmJiBlZmZlY3RpdmVSZXF1ZXN0Lm1ldGhvZCAhPT0gXCJHRVRcIikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJhdHRlbXB0LXRvLWNhY2hlLW5vbi1nZXQtcmVxdWVzdFwiLCB7XG4gICAgICAgICAgICAgICAgICAgIHVybDogZ2V0RnJpZW5kbHlVUkwoZWZmZWN0aXZlUmVxdWVzdC51cmwpLFxuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6IGVmZmVjdGl2ZVJlcXVlc3QubWV0aG9kXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgQ2Fubm90IGNhY2hlIG5vbi1leGlzdGVudCByZXNwb25zZSBmb3IgJyR7Z2V0RnJpZW5kbHlVUkwoZWZmZWN0aXZlUmVxdWVzdC51cmwpfScuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiY2FjaGUtcHV0LXdpdGgtbm8tcmVzcG9uc2VcIiwge1xuICAgICAgICAgICAgICAgIHVybDogZ2V0RnJpZW5kbHlVUkwoZWZmZWN0aXZlUmVxdWVzdC51cmwpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXNwb25zZVRvQ2FjaGUgPSBhd2FpdCB0aGlzLl9lbnN1cmVSZXNwb25zZVNhZmVUb0NhY2hlKHJlc3BvbnNlKTtcbiAgICAgICAgaWYgKCFyZXNwb25zZVRvQ2FjaGUpIHtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYFJlc3BvbnNlICcke2dldEZyaWVuZGx5VVJMKGVmZmVjdGl2ZVJlcXVlc3QudXJsKX0nIHdpbGwgbm90IGJlIGNhY2hlZC5gLCByZXNwb25zZVRvQ2FjaGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgY2FjaGVOYW1lLCBtYXRjaE9wdGlvbnMgfSA9IHRoaXMuX3N0cmF0ZWd5O1xuICAgICAgICBjb25zdCBjYWNoZSA9IGF3YWl0IHNlbGYuY2FjaGVzLm9wZW4oY2FjaGVOYW1lKTtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgY29uc3QgdmFyeSA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiVmFyeVwiKTtcbiAgICAgICAgICAgIGlmICh2YXJ5ICYmIG1hdGNoT3B0aW9ucz8uaWdub3JlVmFyeSAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgVGhlIHJlc3BvbnNlIGZvciAke2dldEZyaWVuZGx5VVJMKGVmZmVjdGl2ZVJlcXVlc3QudXJsKX0gaGFzIGEgJ1Zhcnk6ICR7dmFyeX0nIGhlYWRlci4gQ29uc2lkZXIgc2V0dGluZyB0aGUge2lnbm9yZVZhcnk6IHRydWV9IG9wdGlvbiBvbiB5b3VyIHN0cmF0ZWd5IHRvIGVuc3VyZSBjYWNoZSBtYXRjaGluZyBhbmQgZGVsZXRpb24gd29ya3MgYXMgZXhwZWN0ZWQuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGFzQ2FjaGVVcGRhdGVDYWxsYmFjayA9IHRoaXMuaGFzQ2FsbGJhY2soXCJjYWNoZURpZFVwZGF0ZVwiKTtcbiAgICAgICAgY29uc3Qgb2xkUmVzcG9uc2UgPSBoYXNDYWNoZVVwZGF0ZUNhbGxiYWNrID8gYXdhaXQgY2FjaGVNYXRjaElnbm9yZVBhcmFtcyhjYWNoZSwgZWZmZWN0aXZlUmVxdWVzdC5jbG9uZSgpLCBbXG4gICAgICAgICAgICBcIl9fV0JfUkVWSVNJT05fX1wiXG4gICAgICAgIF0sIG1hdGNoT3B0aW9ucykgOiBudWxsO1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYFVwZGF0aW5nIHRoZSAnJHtjYWNoZU5hbWV9JyBjYWNoZSB3aXRoIGEgbmV3IFJlc3BvbnNlIGZvciAke2dldEZyaWVuZGx5VVJMKGVmZmVjdGl2ZVJlcXVlc3QudXJsKX0uYCk7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGNhY2hlLnB1dChlZmZlY3RpdmVSZXF1ZXN0LCBoYXNDYWNoZVVwZGF0ZUNhbGxiYWNrID8gcmVzcG9uc2VUb0NhY2hlLmNsb25lKCkgOiByZXNwb25zZVRvQ2FjaGUpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gXCJRdW90YUV4Y2VlZGVkRXJyb3JcIikge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBleGVjdXRlUXVvdGFFcnJvckNhbGxiYWNrcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGNhbGxiYWNrIG9mIHRoaXMuaXRlcmF0ZUNhbGxiYWNrcyhcImNhY2hlRGlkVXBkYXRlXCIpKXtcbiAgICAgICAgICAgIGF3YWl0IGNhbGxiYWNrKHtcbiAgICAgICAgICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgICAgICAgICAgb2xkUmVzcG9uc2UsXG4gICAgICAgICAgICAgICAgbmV3UmVzcG9uc2U6IHJlc3BvbnNlVG9DYWNoZS5jbG9uZSgpLFxuICAgICAgICAgICAgICAgIHJlcXVlc3Q6IGVmZmVjdGl2ZVJlcXVlc3QsXG4gICAgICAgICAgICAgICAgZXZlbnQ6IHRoaXMuZXZlbnRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBhc3luYyBnZXRDYWNoZUtleShyZXF1ZXN0LCBtb2RlKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGAke3JlcXVlc3QudXJsfSB8ICR7bW9kZX1gO1xuICAgICAgICBpZiAoIXRoaXMuX2NhY2hlS2V5c1trZXldKSB7XG4gICAgICAgICAgICBsZXQgZWZmZWN0aXZlUmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNhbGxiYWNrIG9mIHRoaXMuaXRlcmF0ZUNhbGxiYWNrcyhcImNhY2hlS2V5V2lsbEJlVXNlZFwiKSl7XG4gICAgICAgICAgICAgICAgZWZmZWN0aXZlUmVxdWVzdCA9IHRvUmVxdWVzdChhd2FpdCBjYWxsYmFjayh7XG4gICAgICAgICAgICAgICAgICAgIG1vZGUsXG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3Q6IGVmZmVjdGl2ZVJlcXVlc3QsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50OiB0aGlzLmV2ZW50LFxuICAgICAgICAgICAgICAgICAgICBwYXJhbXM6IHRoaXMucGFyYW1zXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fY2FjaGVLZXlzW2tleV0gPSBlZmZlY3RpdmVSZXF1ZXN0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jYWNoZUtleXNba2V5XTtcbiAgICB9XG4gICAgaGFzQ2FsbGJhY2sobmFtZSkge1xuICAgICAgICBmb3IgKGNvbnN0IHBsdWdpbiBvZiB0aGlzLl9zdHJhdGVneS5wbHVnaW5zKXtcbiAgICAgICAgICAgIGlmIChuYW1lIGluIHBsdWdpbikge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgYXN5bmMgcnVuQ2FsbGJhY2tzKG5hbWUsIHBhcmFtKSB7XG4gICAgICAgIGZvciAoY29uc3QgY2FsbGJhY2sgb2YgdGhpcy5pdGVyYXRlQ2FsbGJhY2tzKG5hbWUpKXtcbiAgICAgICAgICAgIGF3YWl0IGNhbGxiYWNrKHBhcmFtKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAqaXRlcmF0ZUNhbGxiYWNrcyhuYW1lKSB7XG4gICAgICAgIGZvciAoY29uc3QgcGx1Z2luIG9mIHRoaXMuX3N0cmF0ZWd5LnBsdWdpbnMpe1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBwbHVnaW5bbmFtZV0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5fcGx1Z2luU3RhdGVNYXAuZ2V0KHBsdWdpbik7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhdGVmdWxDYWxsYmFjayA9IChwYXJhbSk9PntcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdGVmdWxQYXJhbSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBsdWdpbltuYW1lXShzdGF0ZWZ1bFBhcmFtKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHlpZWxkIHN0YXRlZnVsQ2FsbGJhY2s7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgd2FpdFVudGlsKHByb21pc2UpIHtcbiAgICAgICAgdGhpcy5fZXh0ZW5kTGlmZXRpbWVQcm9taXNlcy5wdXNoKHByb21pc2UpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG4gICAgYXN5bmMgZG9uZVdhaXRpbmcoKSB7XG4gICAgICAgIGxldCBwcm9taXNlO1xuICAgICAgICB3aGlsZShwcm9taXNlID0gdGhpcy5fZXh0ZW5kTGlmZXRpbWVQcm9taXNlcy5zaGlmdCgpKXtcbiAgICAgICAgICAgIGF3YWl0IHByb21pc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5faGFuZGxlckRlZmVycmVkLnJlc29sdmUobnVsbCk7XG4gICAgfVxuICAgIGFzeW5jIGdldFByZWxvYWRSZXNwb25zZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuZXZlbnQgaW5zdGFuY2VvZiBGZXRjaEV2ZW50ICYmIHRoaXMuZXZlbnQucmVxdWVzdC5tb2RlID09PSBcIm5hdmlnYXRlXCIgJiYgXCJwcmVsb2FkUmVzcG9uc2VcIiBpbiB0aGlzLmV2ZW50KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBvc3NpYmxlUHJlbG9hZFJlc3BvbnNlID0gYXdhaXQgdGhpcy5ldmVudC5wcmVsb2FkUmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgaWYgKHBvc3NpYmxlUHJlbG9hZFJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coYFVzaW5nIGEgcHJlbG9hZGVkIG5hdmlnYXRpb24gcmVzcG9uc2UgZm9yICcke2dldEZyaWVuZGx5VVJMKHRoaXMuZXZlbnQucmVxdWVzdC51cmwpfSdgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcG9zc2libGVQcmVsb2FkUmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgYXN5bmMgX2Vuc3VyZVJlc3BvbnNlU2FmZVRvQ2FjaGUocmVzcG9uc2UpIHtcbiAgICAgICAgbGV0IHJlc3BvbnNlVG9DYWNoZSA9IHJlc3BvbnNlO1xuICAgICAgICBsZXQgcGx1Z2luc1VzZWQgPSBmYWxzZTtcbiAgICAgICAgZm9yIChjb25zdCBjYWxsYmFjayBvZiB0aGlzLml0ZXJhdGVDYWxsYmFja3MoXCJjYWNoZVdpbGxVcGRhdGVcIikpe1xuICAgICAgICAgICAgcmVzcG9uc2VUb0NhY2hlID0gYXdhaXQgY2FsbGJhY2soe1xuICAgICAgICAgICAgICAgIHJlcXVlc3Q6IHRoaXMucmVxdWVzdCxcbiAgICAgICAgICAgICAgICByZXNwb25zZTogcmVzcG9uc2VUb0NhY2hlLFxuICAgICAgICAgICAgICAgIGV2ZW50OiB0aGlzLmV2ZW50XG4gICAgICAgICAgICB9KSB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICBwbHVnaW5zVXNlZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlVG9DYWNoZSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghcGx1Z2luc1VzZWQpIHtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZVRvQ2FjaGUgJiYgcmVzcG9uc2VUb0NhY2hlLnN0YXR1cyAhPT0gMjAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2VUb0NhY2hlLnN0YXR1cyA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oYFRoZSByZXNwb25zZSBmb3IgJyR7dGhpcy5yZXF1ZXN0LnVybH0nIGlzIGFuIG9wYXF1ZSByZXNwb25zZS4gVGhlIGNhY2hpbmcgc3RyYXRlZ3kgdGhhdCB5b3UncmUgdXNpbmcgd2lsbCBub3QgY2FjaGUgb3BhcXVlIHJlc3BvbnNlcyBieSBkZWZhdWx0LmApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBUaGUgcmVzcG9uc2UgZm9yICcke3RoaXMucmVxdWVzdC51cmx9JyByZXR1cm5lZCBhIHN0YXR1cyBjb2RlIG9mICcke3Jlc3BvbnNlLnN0YXR1c30nIGFuZCB3b24ndCBiZSBjYWNoZWQgYXMgYSByZXN1bHQuYCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzcG9uc2VUb0NhY2hlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNwb25zZVRvQ2FjaGU7XG4gICAgfVxufVxuXG5jbGFzcyBTdHJhdGVneSB7XG4gICAgY2FjaGVOYW1lO1xuICAgIHBsdWdpbnM7XG4gICAgZmV0Y2hPcHRpb25zO1xuICAgIG1hdGNoT3B0aW9ucztcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pe1xuICAgICAgICB0aGlzLmNhY2hlTmFtZSA9IGNhY2hlTmFtZXMuZ2V0UnVudGltZU5hbWUob3B0aW9ucy5jYWNoZU5hbWUpO1xuICAgICAgICB0aGlzLnBsdWdpbnMgPSBvcHRpb25zLnBsdWdpbnMgfHwgW107XG4gICAgICAgIHRoaXMuZmV0Y2hPcHRpb25zID0gb3B0aW9ucy5mZXRjaE9wdGlvbnM7XG4gICAgICAgIHRoaXMubWF0Y2hPcHRpb25zID0gb3B0aW9ucy5tYXRjaE9wdGlvbnM7XG4gICAgfVxuICAgIGhhbmRsZShvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IFtyZXNwb25zZURvbmVdID0gdGhpcy5oYW5kbGVBbGwob3B0aW9ucyk7XG4gICAgICAgIHJldHVybiByZXNwb25zZURvbmU7XG4gICAgfVxuICAgIGhhbmRsZUFsbChvcHRpb25zKSB7XG4gICAgICAgIGlmIChvcHRpb25zIGluc3RhbmNlb2YgRmV0Y2hFdmVudCkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBldmVudDogb3B0aW9ucyxcbiAgICAgICAgICAgICAgICByZXF1ZXN0OiBvcHRpb25zLnJlcXVlc3RcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZXZlbnQgPSBvcHRpb25zLmV2ZW50O1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gdHlwZW9mIG9wdGlvbnMucmVxdWVzdCA9PT0gXCJzdHJpbmdcIiA/IG5ldyBSZXF1ZXN0KG9wdGlvbnMucmVxdWVzdCkgOiBvcHRpb25zLnJlcXVlc3Q7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSBuZXcgU3RyYXRlZ3lIYW5kbGVyKHRoaXMsIG9wdGlvbnMudXJsID8ge1xuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgdXJsOiBvcHRpb25zLnVybCxcbiAgICAgICAgICAgIHBhcmFtczogb3B0aW9ucy5wYXJhbXNcbiAgICAgICAgfSA6IHtcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgcmVxdWVzdFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2VEb25lID0gdGhpcy5fZ2V0UmVzcG9uc2UoaGFuZGxlciwgcmVxdWVzdCwgZXZlbnQpO1xuICAgICAgICBjb25zdCBoYW5kbGVyRG9uZSA9IHRoaXMuX2F3YWl0Q29tcGxldGUocmVzcG9uc2VEb25lLCBoYW5kbGVyLCByZXF1ZXN0LCBldmVudCk7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICByZXNwb25zZURvbmUsXG4gICAgICAgICAgICBoYW5kbGVyRG9uZVxuICAgICAgICBdO1xuICAgIH1cbiAgICBhc3luYyBfZ2V0UmVzcG9uc2UoaGFuZGxlciwgcmVxdWVzdCwgZXZlbnQpIHtcbiAgICAgICAgYXdhaXQgaGFuZGxlci5ydW5DYWxsYmFja3MoXCJoYW5kbGVyV2lsbFN0YXJ0XCIsIHtcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgcmVxdWVzdFxuICAgICAgICB9KTtcbiAgICAgICAgbGV0IHJlc3BvbnNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9oYW5kbGUocmVxdWVzdCwgaGFuZGxlcik7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IHVuZGVmaW5lZCB8fCByZXNwb25zZS50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwibm8tcmVzcG9uc2VcIiwge1xuICAgICAgICAgICAgICAgICAgICB1cmw6IHJlcXVlc3QudXJsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY2FsbGJhY2sgb2YgaGFuZGxlci5pdGVyYXRlQ2FsbGJhY2tzKFwiaGFuZGxlckRpZEVycm9yXCIpKXtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCBjYWxsYmFjayh7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgIHRocm93IGxvZ2dlci5sb2coYFdoaWxlIHJlc3BvbmRpbmcgdG8gJyR7Z2V0RnJpZW5kbHlVUkwocmVxdWVzdC51cmwpfScsIGFuICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLnRvU3RyaW5nKCkgOiBcIlwifSBlcnJvciBvY2N1cnJlZC4gVXNpbmcgYSBmYWxsYmFjayByZXNwb25zZSBwcm92aWRlZCBieSBhIGhhbmRsZXJEaWRFcnJvciBwbHVnaW4uYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBjYWxsYmFjayBvZiBoYW5kbGVyLml0ZXJhdGVDYWxsYmFja3MoXCJoYW5kbGVyV2lsbFJlc3BvbmRcIikpe1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCBjYWxsYmFjayh7XG4gICAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgICAgICByZXNwb25zZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cbiAgICBhc3luYyBfYXdhaXRDb21wbGV0ZShyZXNwb25zZURvbmUsIGhhbmRsZXIsIHJlcXVlc3QsIGV2ZW50KSB7XG4gICAgICAgIGxldCByZXNwb25zZTtcbiAgICAgICAgbGV0IGVycm9yO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCByZXNwb25zZURvbmU7XG4gICAgICAgIH0gY2F0Y2ggIHt9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBoYW5kbGVyLnJ1bkNhbGxiYWNrcyhcImhhbmRsZXJEaWRSZXNwb25kXCIsIHtcbiAgICAgICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgICAgIHJlc3BvbnNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGF3YWl0IGhhbmRsZXIuZG9uZVdhaXRpbmcoKTtcbiAgICAgICAgfSBjYXRjaCAod2FpdFVudGlsRXJyb3IpIHtcbiAgICAgICAgICAgIGlmICh3YWl0VW50aWxFcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICAgICAgZXJyb3IgPSB3YWl0VW50aWxFcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBoYW5kbGVyLnJ1bkNhbGxiYWNrcyhcImhhbmRsZXJEaWRDb21wbGV0ZVwiLCB7XG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgICAgIGVycm9yXG4gICAgICAgIH0pO1xuICAgICAgICBoYW5kbGVyLmRlc3Ryb3koKTtcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY29uc3QgbWVzc2FnZXMgPSB7XG4gICAgc3RyYXRlZ3lTdGFydDogKHN0cmF0ZWd5TmFtZSwgcmVxdWVzdCk9PmBVc2luZyAke3N0cmF0ZWd5TmFtZX0gdG8gcmVzcG9uZCB0byAnJHtnZXRGcmllbmRseVVSTChyZXF1ZXN0LnVybCl9J2AsXG4gICAgcHJpbnRGaW5hbFJlc3BvbnNlOiAocmVzcG9uc2UpPT57XG4gICAgICAgIGlmIChyZXNwb25zZSkge1xuICAgICAgICAgICAgbG9nZ2VyLmdyb3VwQ29sbGFwc2VkKFwiVmlldyB0aGUgZmluYWwgcmVzcG9uc2UgaGVyZS5cIik7XG4gICAgICAgICAgICBsb2dnZXIubG9nKHJlc3BvbnNlIHx8IFwiW05vIHJlc3BvbnNlIHJldHVybmVkXVwiKTtcbiAgICAgICAgICAgIGxvZ2dlci5ncm91cEVuZCgpO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuY2xhc3MgTmV0d29ya0ZpcnN0IGV4dGVuZHMgU3RyYXRlZ3kge1xuICAgIF9uZXR3b3JrVGltZW91dFNlY29uZHM7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KXtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIGlmICghdGhpcy5wbHVnaW5zLnNvbWUoKHApPT5cImNhY2hlV2lsbFVwZGF0ZVwiIGluIHApKSB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMudW5zaGlmdChjYWNoZU9rQW5kT3BhcXVlUGx1Z2luKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9uZXR3b3JrVGltZW91dFNlY29uZHMgPSBvcHRpb25zLm5ldHdvcmtUaW1lb3V0U2Vjb25kcyB8fCAwO1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fbmV0d29ya1RpbWVvdXRTZWNvbmRzKSB7XG4gICAgICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzVHlwZSh0aGlzLl9uZXR3b3JrVGltZW91dFNlY29uZHMsIFwibnVtYmVyXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogdGhpcy5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgICAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJjb25zdHJ1Y3RvclwiLFxuICAgICAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwibmV0d29ya1RpbWVvdXRTZWNvbmRzXCJcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBfaGFuZGxlKHJlcXVlc3QsIGhhbmRsZXIpIHtcbiAgICAgICAgY29uc3QgbG9ncyA9IFtdO1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNJbnN0YW5jZShyZXF1ZXN0LCBSZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiaGFuZGxlXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcIm1ha2VSZXF1ZXN0XCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gW107XG4gICAgICAgIGxldCB0aW1lb3V0SWQ7XG4gICAgICAgIGlmICh0aGlzLl9uZXR3b3JrVGltZW91dFNlY29uZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgaWQsIHByb21pc2UgfSA9IHRoaXMuX2dldFRpbWVvdXRQcm9taXNlKHtcbiAgICAgICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgICAgIGxvZ3MsXG4gICAgICAgICAgICAgICAgaGFuZGxlclxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aW1lb3V0SWQgPSBpZDtcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2gocHJvbWlzZSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV0d29ya1Byb21pc2UgPSB0aGlzLl9nZXROZXR3b3JrUHJvbWlzZSh7XG4gICAgICAgICAgICB0aW1lb3V0SWQsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgbG9ncyxcbiAgICAgICAgICAgIGhhbmRsZXJcbiAgICAgICAgfSk7XG4gICAgICAgIHByb21pc2VzLnB1c2gobmV0d29ya1Byb21pc2UpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGhhbmRsZXIud2FpdFVudGlsKChhc3luYyAoKT0+e1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGhhbmRsZXIud2FpdFVudGlsKFByb21pc2UucmFjZShwcm9taXNlcykpIHx8IGF3YWl0IG5ldHdvcmtQcm9taXNlO1xuICAgICAgICB9KSgpKTtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgbG9nZ2VyLmdyb3VwQ29sbGFwc2VkKG1lc3NhZ2VzLnN0cmF0ZWd5U3RhcnQodGhpcy5jb25zdHJ1Y3Rvci5uYW1lLCByZXF1ZXN0KSk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGxvZyBvZiBsb2dzKXtcbiAgICAgICAgICAgICAgICBsb2dnZXIubG9nKGxvZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtZXNzYWdlcy5wcmludEZpbmFsUmVzcG9uc2UocmVzcG9uc2UpO1xuICAgICAgICAgICAgbG9nZ2VyLmdyb3VwRW5kKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFNlcndpc3RFcnJvcihcIm5vLXJlc3BvbnNlXCIsIHtcbiAgICAgICAgICAgICAgICB1cmw6IHJlcXVlc3QudXJsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuICAgIF9nZXRUaW1lb3V0UHJvbWlzZSh7IHJlcXVlc3QsIGxvZ3MsIGhhbmRsZXIgfSkge1xuICAgICAgICBsZXQgdGltZW91dElkO1xuICAgICAgICBjb25zdCB0aW1lb3V0UHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKT0+e1xuICAgICAgICAgICAgY29uc3Qgb25OZXR3b3JrVGltZW91dCA9IGFzeW5jICgpPT57XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBsb2dzLnB1c2goYFRpbWluZyBvdXQgdGhlIG5ldHdvcmsgcmVzcG9uc2UgYXQgJHt0aGlzLl9uZXR3b3JrVGltZW91dFNlY29uZHN9IHNlY29uZHMuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoYXdhaXQgaGFuZGxlci5jYWNoZU1hdGNoKHJlcXVlc3QpKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KG9uTmV0d29ya1RpbWVvdXQsIHRoaXMuX25ldHdvcmtUaW1lb3V0U2Vjb25kcyAqIDEwMDApO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHByb21pc2U6IHRpbWVvdXRQcm9taXNlLFxuICAgICAgICAgICAgaWQ6IHRpbWVvdXRJZFxuICAgICAgICB9O1xuICAgIH1cbiAgICBhc3luYyBfZ2V0TmV0d29ya1Byb21pc2UoeyB0aW1lb3V0SWQsIHJlcXVlc3QsIGxvZ3MsIGhhbmRsZXIgfSkge1xuICAgICAgICBsZXQgZXJyb3I7XG4gICAgICAgIGxldCByZXNwb25zZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgaGFuZGxlci5mZXRjaEFuZENhY2hlUHV0KHJlcXVlc3QpO1xuICAgICAgICB9IGNhdGNoIChmZXRjaEVycm9yKSB7XG4gICAgICAgICAgICBpZiAoZmV0Y2hFcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICAgICAgZXJyb3IgPSBmZXRjaEVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aW1lb3V0SWQpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGxvZ3MucHVzaChcIkdvdCByZXNwb25zZSBmcm9tIG5ldHdvcmsuXCIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2dzLnB1c2goXCJVbmFibGUgdG8gZ2V0IGEgcmVzcG9uc2UgZnJvbSB0aGUgbmV0d29yay4gV2lsbCByZXNwb25kIFwiICsgXCJ3aXRoIGEgY2FjaGVkIHJlc3BvbnNlLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZXJyb3IgfHwgIXJlc3BvbnNlKSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IGF3YWl0IGhhbmRsZXIuY2FjaGVNYXRjaChyZXF1ZXN0KTtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9ncy5wdXNoKGBGb3VuZCBhIGNhY2hlZCByZXNwb25zZSBpbiB0aGUgJyR7dGhpcy5jYWNoZU5hbWV9JyBjYWNoZS5gKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsb2dzLnB1c2goYE5vIHJlc3BvbnNlIGZvdW5kIGluIHRoZSAnJHt0aGlzLmNhY2hlTmFtZX0nIGNhY2hlLmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxufVxuXG5jbGFzcyBOZXR3b3JrT25seSBleHRlbmRzIFN0cmF0ZWd5IHtcbiAgICBfbmV0d29ya1RpbWVvdXRTZWNvbmRzO1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMgPSB7fSl7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLl9uZXR3b3JrVGltZW91dFNlY29uZHMgPSBvcHRpb25zLm5ldHdvcmtUaW1lb3V0U2Vjb25kcyB8fCAwO1xuICAgIH1cbiAgICBhc3luYyBfaGFuZGxlKHJlcXVlc3QsIGhhbmRsZXIpIHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzSW5zdGFuY2UocmVxdWVzdCwgUmVxdWVzdCwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogdGhpcy5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcIl9oYW5kbGVcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwicmVxdWVzdFwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZXJyb3I7XG4gICAgICAgIGxldCByZXNwb25zZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gW1xuICAgICAgICAgICAgICAgIGhhbmRsZXIuZmV0Y2gocmVxdWVzdClcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBpZiAodGhpcy5fbmV0d29ya1RpbWVvdXRTZWNvbmRzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGltZW91dFByb21pc2UgPSB0aW1lb3V0KHRoaXMuX25ldHdvcmtUaW1lb3V0U2Vjb25kcyAqIDEwMDApO1xuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2godGltZW91dFByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCBQcm9taXNlLnJhY2UocHJvbWlzZXMpO1xuICAgICAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVGltZWQgb3V0IHRoZSBuZXR3b3JrIHJlc3BvbnNlIGFmdGVyICR7dGhpcy5fbmV0d29ya1RpbWVvdXRTZWNvbmRzfSBzZWNvbmRzLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgICAgIGVycm9yID0gZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGxvZ2dlci5ncm91cENvbGxhcHNlZChtZXNzYWdlcy5zdHJhdGVneVN0YXJ0KHRoaXMuY29uc3RydWN0b3IubmFtZSwgcmVxdWVzdCkpO1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhcIkdvdCByZXNwb25zZSBmcm9tIG5ldHdvcmsuXCIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIubG9nKFwiVW5hYmxlIHRvIGdldCBhIHJlc3BvbnNlIGZyb20gdGhlIG5ldHdvcmsuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWVzc2FnZXMucHJpbnRGaW5hbFJlc3BvbnNlKHJlc3BvbnNlKTtcbiAgICAgICAgICAgIGxvZ2dlci5ncm91cEVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJuby1yZXNwb25zZVwiLCB7XG4gICAgICAgICAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cbn1cblxuY29uc3QgZGVmYXVsdE1ldGhvZCA9IFwiR0VUXCI7XG5jb25zdCB2YWxpZE1ldGhvZHMgPSBbXG4gICAgXCJERUxFVEVcIixcbiAgICBcIkdFVFwiLFxuICAgIFwiSEVBRFwiLFxuICAgIFwiUEFUQ0hcIixcbiAgICBcIlBPU1RcIixcbiAgICBcIlBVVFwiXG5dO1xuXG5jb25zdCBub3JtYWxpemVIYW5kbGVyID0gKGhhbmRsZXIpPT57XG4gICAgaWYgKGhhbmRsZXIgJiYgdHlwZW9mIGhhbmRsZXIgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmhhc01ldGhvZChoYW5kbGVyLCBcImhhbmRsZVwiLCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIlJvdXRlXCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiY29uc3RydWN0b3JcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwiaGFuZGxlclwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaGFuZGxlcjtcbiAgICB9XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNUeXBlKGhhbmRsZXIsIFwiZnVuY3Rpb25cIiwge1xuICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICBjbGFzc05hbWU6IFwiUm91dGVcIixcbiAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNvbnN0cnVjdG9yXCIsXG4gICAgICAgICAgICBwYXJhbU5hbWU6IFwiaGFuZGxlclwiXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBoYW5kbGU6IGhhbmRsZXJcbiAgICB9O1xufTtcblxuY2xhc3MgUm91dGUge1xuICAgIGhhbmRsZXI7XG4gICAgbWF0Y2g7XG4gICAgbWV0aG9kO1xuICAgIGNhdGNoSGFuZGxlcjtcbiAgICBjb25zdHJ1Y3RvcihtYXRjaCwgaGFuZGxlciwgbWV0aG9kID0gZGVmYXVsdE1ldGhvZCl7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc1R5cGUobWF0Y2gsIFwiZnVuY3Rpb25cIiwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJSb3V0ZVwiLFxuICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNvbnN0cnVjdG9yXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcIm1hdGNoXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKG1ldGhvZCkge1xuICAgICAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc09uZU9mKG1ldGhvZCwgdmFsaWRNZXRob2RzLCB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJtZXRob2RcIlxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuaGFuZGxlciA9IG5vcm1hbGl6ZUhhbmRsZXIoaGFuZGxlcik7XG4gICAgICAgIHRoaXMubWF0Y2ggPSBtYXRjaDtcbiAgICAgICAgdGhpcy5tZXRob2QgPSBtZXRob2Q7XG4gICAgfVxuICAgIHNldENhdGNoSGFuZGxlcihoYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuY2F0Y2hIYW5kbGVyID0gbm9ybWFsaXplSGFuZGxlcihoYW5kbGVyKTtcbiAgICB9XG59XG5cbmNsYXNzIFByZWNhY2hlU3RyYXRlZ3kgZXh0ZW5kcyBTdHJhdGVneSB7XG4gICAgX2ZhbGxiYWNrVG9OZXR3b3JrO1xuICAgIHN0YXRpYyBkZWZhdWx0UHJlY2FjaGVDYWNoZWFiaWxpdHlQbHVnaW4gPSB7XG4gICAgICAgIGFzeW5jIGNhY2hlV2lsbFVwZGF0ZSAoeyByZXNwb25zZSB9KSB7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlIHx8IHJlc3BvbnNlLnN0YXR1cyA+PSA0MDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgc3RhdGljIGNvcHlSZWRpcmVjdGVkQ2FjaGVhYmxlUmVzcG9uc2VzUGx1Z2luID0ge1xuICAgICAgICBhc3luYyBjYWNoZVdpbGxVcGRhdGUgKHsgcmVzcG9uc2UgfSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnJlZGlyZWN0ZWQgPyBhd2FpdCBjb3B5UmVzcG9uc2UocmVzcG9uc2UpIDogcmVzcG9uc2U7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMgPSB7fSl7XG4gICAgICAgIG9wdGlvbnMuY2FjaGVOYW1lID0gY2FjaGVOYW1lcy5nZXRQcmVjYWNoZU5hbWUob3B0aW9ucy5jYWNoZU5hbWUpO1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5fZmFsbGJhY2tUb05ldHdvcmsgPSBvcHRpb25zLmZhbGxiYWNrVG9OZXR3b3JrICE9PSBmYWxzZTtcbiAgICAgICAgdGhpcy5wbHVnaW5zLnB1c2goUHJlY2FjaGVTdHJhdGVneS5jb3B5UmVkaXJlY3RlZENhY2hlYWJsZVJlc3BvbnNlc1BsdWdpbik7XG4gICAgfVxuICAgIGFzeW5jIF9oYW5kbGUocmVxdWVzdCwgaGFuZGxlcikge1xuICAgICAgICBjb25zdCBwcmVsb2FkUmVzcG9uc2UgPSBhd2FpdCBoYW5kbGVyLmdldFByZWxvYWRSZXNwb25zZSgpO1xuICAgICAgICBpZiAocHJlbG9hZFJlc3BvbnNlKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJlbG9hZFJlc3BvbnNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgaGFuZGxlci5jYWNoZU1hdGNoKHJlcXVlc3QpO1xuICAgICAgICBpZiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGFuZGxlci5ldmVudCAmJiBoYW5kbGVyLmV2ZW50LnR5cGUgPT09IFwiaW5zdGFsbFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5faGFuZGxlSW5zdGFsbChyZXF1ZXN0LCBoYW5kbGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5faGFuZGxlRmV0Y2gocmVxdWVzdCwgaGFuZGxlcik7XG4gICAgfVxuICAgIGFzeW5jIF9oYW5kbGVGZXRjaChyZXF1ZXN0LCBoYW5kbGVyKSB7XG4gICAgICAgIGxldCByZXNwb25zZTtcbiAgICAgICAgY29uc3QgcGFyYW1zID0gaGFuZGxlci5wYXJhbXMgfHwge307XG4gICAgICAgIGlmICh0aGlzLl9mYWxsYmFja1RvTmV0d29yaykge1xuICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKGBUaGUgcHJlY2FjaGVkIHJlc3BvbnNlIGZvciAke2dldEZyaWVuZGx5VVJMKHJlcXVlc3QudXJsKX0gaW4gJHt0aGlzLmNhY2hlTmFtZX0gd2FzIG5vdCBmb3VuZC4gRmFsbGluZyBiYWNrIHRvIHRoZSBuZXR3b3JrLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaW50ZWdyaXR5SW5NYW5pZmVzdCA9IHBhcmFtcy5pbnRlZ3JpdHk7XG4gICAgICAgICAgICBjb25zdCBpbnRlZ3JpdHlJblJlcXVlc3QgPSByZXF1ZXN0LmludGVncml0eTtcbiAgICAgICAgICAgIGNvbnN0IG5vSW50ZWdyaXR5Q29uZmxpY3QgPSAhaW50ZWdyaXR5SW5SZXF1ZXN0IHx8IGludGVncml0eUluUmVxdWVzdCA9PT0gaW50ZWdyaXR5SW5NYW5pZmVzdDtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgaGFuZGxlci5mZXRjaChuZXcgUmVxdWVzdChyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgaW50ZWdyaXR5OiByZXF1ZXN0Lm1vZGUgIT09IFwibm8tY29yc1wiID8gaW50ZWdyaXR5SW5SZXF1ZXN0IHx8IGludGVncml0eUluTWFuaWZlc3QgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGlmIChpbnRlZ3JpdHlJbk1hbmlmZXN0ICYmIG5vSW50ZWdyaXR5Q29uZmxpY3QgJiYgcmVxdWVzdC5tb2RlICE9PSBcIm5vLWNvcnNcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3VzZURlZmF1bHRDYWNoZWFiaWxpdHlQbHVnaW5JZk5lZWRlZCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHdhc0NhY2hlZCA9IGF3YWl0IGhhbmRsZXIuY2FjaGVQdXQocmVxdWVzdCwgcmVzcG9uc2UuY2xvbmUoKSk7XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBpZiAod2FzQ2FjaGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKGBBIHJlc3BvbnNlIGZvciAke2dldEZyaWVuZGx5VVJMKHJlcXVlc3QudXJsKX0gd2FzIHVzZWQgdG8gXCJyZXBhaXJcIiB0aGUgcHJlY2FjaGUuYCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwibWlzc2luZy1wcmVjYWNoZS1lbnRyeVwiLCB7XG4gICAgICAgICAgICAgICAgY2FjaGVOYW1lOiB0aGlzLmNhY2hlTmFtZSxcbiAgICAgICAgICAgICAgICB1cmw6IHJlcXVlc3QudXJsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBjb25zdCBjYWNoZUtleSA9IHBhcmFtcy5jYWNoZUtleSB8fCBhd2FpdCBoYW5kbGVyLmdldENhY2hlS2V5KHJlcXVlc3QsIFwicmVhZFwiKTtcbiAgICAgICAgICAgIGxvZ2dlci5ncm91cENvbGxhcHNlZChgUHJlY2FjaGluZyBpcyByZXNwb25kaW5nIHRvOiAke2dldEZyaWVuZGx5VVJMKHJlcXVlc3QudXJsKX1gKTtcbiAgICAgICAgICAgIGxvZ2dlci5sb2coYFNlcnZpbmcgdGhlIHByZWNhY2hlZCB1cmw6ICR7Z2V0RnJpZW5kbHlVUkwoY2FjaGVLZXkgaW5zdGFuY2VvZiBSZXF1ZXN0ID8gY2FjaGVLZXkudXJsIDogY2FjaGVLZXkpfWApO1xuICAgICAgICAgICAgbG9nZ2VyLmdyb3VwQ29sbGFwc2VkKFwiVmlldyByZXF1ZXN0IGRldGFpbHMgaGVyZS5cIik7XG4gICAgICAgICAgICBsb2dnZXIubG9nKHJlcXVlc3QpO1xuICAgICAgICAgICAgbG9nZ2VyLmdyb3VwRW5kKCk7XG4gICAgICAgICAgICBsb2dnZXIuZ3JvdXBDb2xsYXBzZWQoXCJWaWV3IHJlc3BvbnNlIGRldGFpbHMgaGVyZS5cIik7XG4gICAgICAgICAgICBsb2dnZXIubG9nKHJlc3BvbnNlKTtcbiAgICAgICAgICAgIGxvZ2dlci5ncm91cEVuZCgpO1xuICAgICAgICAgICAgbG9nZ2VyLmdyb3VwRW5kKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cbiAgICBhc3luYyBfaGFuZGxlSW5zdGFsbChyZXF1ZXN0LCBoYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuX3VzZURlZmF1bHRDYWNoZWFiaWxpdHlQbHVnaW5JZk5lZWRlZCgpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGhhbmRsZXIuZmV0Y2gocmVxdWVzdCk7XG4gICAgICAgIGNvbnN0IHdhc0NhY2hlZCA9IGF3YWl0IGhhbmRsZXIuY2FjaGVQdXQocmVxdWVzdCwgcmVzcG9uc2UuY2xvbmUoKSk7XG4gICAgICAgIGlmICghd2FzQ2FjaGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiYmFkLXByZWNhY2hpbmctcmVzcG9uc2VcIiwge1xuICAgICAgICAgICAgICAgIHVybDogcmVxdWVzdC51cmwsXG4gICAgICAgICAgICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG4gICAgX3VzZURlZmF1bHRDYWNoZWFiaWxpdHlQbHVnaW5JZk5lZWRlZCgpIHtcbiAgICAgICAgbGV0IGRlZmF1bHRQbHVnaW5JbmRleCA9IG51bGw7XG4gICAgICAgIGxldCBjYWNoZVdpbGxVcGRhdGVQbHVnaW5Db3VudCA9IDA7XG4gICAgICAgIGZvciAoY29uc3QgW2luZGV4LCBwbHVnaW5dIG9mIHRoaXMucGx1Z2lucy5lbnRyaWVzKCkpe1xuICAgICAgICAgICAgaWYgKHBsdWdpbiA9PT0gUHJlY2FjaGVTdHJhdGVneS5jb3B5UmVkaXJlY3RlZENhY2hlYWJsZVJlc3BvbnNlc1BsdWdpbikge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBsdWdpbiA9PT0gUHJlY2FjaGVTdHJhdGVneS5kZWZhdWx0UHJlY2FjaGVDYWNoZWFiaWxpdHlQbHVnaW4pIHtcbiAgICAgICAgICAgICAgICBkZWZhdWx0UGx1Z2luSW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwbHVnaW4uY2FjaGVXaWxsVXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgY2FjaGVXaWxsVXBkYXRlUGx1Z2luQ291bnQrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoY2FjaGVXaWxsVXBkYXRlUGx1Z2luQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5wdXNoKFByZWNhY2hlU3RyYXRlZ3kuZGVmYXVsdFByZWNhY2hlQ2FjaGVhYmlsaXR5UGx1Z2luKTtcbiAgICAgICAgfSBlbHNlIGlmIChjYWNoZVdpbGxVcGRhdGVQbHVnaW5Db3VudCA+IDEgJiYgZGVmYXVsdFBsdWdpbkluZGV4ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMuc3BsaWNlKGRlZmF1bHRQbHVnaW5JbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIE5hdmlnYXRpb25Sb3V0ZSBleHRlbmRzIFJvdXRlIHtcbiAgICBfYWxsb3dsaXN0O1xuICAgIF9kZW55bGlzdDtcbiAgICBjb25zdHJ1Y3RvcihoYW5kbGVyLCB7IGFsbG93bGlzdCA9IFtcbiAgICAgICAgLy4vXG4gICAgXSwgZGVueWxpc3QgPSBbXSB9ID0ge30pe1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNBcnJheU9mQ2xhc3MoYWxsb3dsaXN0LCBSZWdFeHAsIHtcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiTmF2aWdhdGlvblJvdXRlXCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiY29uc3RydWN0b3JcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwib3B0aW9ucy5hbGxvd2xpc3RcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNBcnJheU9mQ2xhc3MoZGVueWxpc3QsIFJlZ0V4cCwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJOYXZpZ2F0aW9uUm91dGVcIixcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJjb25zdHJ1Y3RvclwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJvcHRpb25zLmRlbnlsaXN0XCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHN1cGVyKChvcHRpb25zKT0+dGhpcy5fbWF0Y2gob3B0aW9ucyksIGhhbmRsZXIpO1xuICAgICAgICB0aGlzLl9hbGxvd2xpc3QgPSBhbGxvd2xpc3Q7XG4gICAgICAgIHRoaXMuX2RlbnlsaXN0ID0gZGVueWxpc3Q7XG4gICAgfVxuICAgIF9tYXRjaCh7IHVybCwgcmVxdWVzdCB9KSB7XG4gICAgICAgIGlmIChyZXF1ZXN0ICYmIHJlcXVlc3QubW9kZSAhPT0gXCJuYXZpZ2F0ZVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGF0aG5hbWVBbmRTZWFyY2ggPSB1cmwucGF0aG5hbWUgKyB1cmwuc2VhcmNoO1xuICAgICAgICBmb3IgKGNvbnN0IHJlZ0V4cCBvZiB0aGlzLl9kZW55bGlzdCl7XG4gICAgICAgICAgICBpZiAocmVnRXhwLnRlc3QocGF0aG5hbWVBbmRTZWFyY2gpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKGBUaGUgbmF2aWdhdGlvbiByb3V0ZSAke3BhdGhuYW1lQW5kU2VhcmNofSBpcyBub3QgYmVpbmcgdXNlZCwgc2luY2UgdGhlIFVSTCBtYXRjaGVzIHRoaXMgZGVueWxpc3QgcGF0dGVybjogJHtyZWdFeHAudG9TdHJpbmcoKX1gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9hbGxvd2xpc3Quc29tZSgocmVnRXhwKT0+cmVnRXhwLnRlc3QocGF0aG5hbWVBbmRTZWFyY2gpKSkge1xuICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgVGhlIG5hdmlnYXRpb24gcm91dGUgJHtwYXRobmFtZUFuZFNlYXJjaH0gaXMgYmVpbmcgdXNlZC5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGxvZ2dlci5sb2coYFRoZSBuYXZpZ2F0aW9uIHJvdXRlICR7cGF0aG5hbWVBbmRTZWFyY2h9IGlzIG5vdCBiZWluZyB1c2VkLCBzaW5jZSB0aGUgVVJMIGJlaW5nIG5hdmlnYXRlZCB0byBkb2Vzbid0IG1hdGNoIHRoZSBhbGxvd2xpc3QuYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuY29uc3QgaXNOYXZpZ2F0aW9uUHJlbG9hZFN1cHBvcnRlZCA9ICgpPT57XG4gICAgcmV0dXJuIEJvb2xlYW4oc2VsZi5yZWdpc3RyYXRpb24/Lm5hdmlnYXRpb25QcmVsb2FkKTtcbn07XG5jb25zdCBlbmFibGVOYXZpZ2F0aW9uUHJlbG9hZCA9IChoZWFkZXJWYWx1ZSk9PntcbiAgICBpZiAoaXNOYXZpZ2F0aW9uUHJlbG9hZFN1cHBvcnRlZCgpKSB7XG4gICAgICAgIHNlbGYuYWRkRXZlbnRMaXN0ZW5lcihcImFjdGl2YXRlXCIsIChldmVudCk9PntcbiAgICAgICAgICAgIGV2ZW50LndhaXRVbnRpbChzZWxmLnJlZ2lzdHJhdGlvbi5uYXZpZ2F0aW9uUHJlbG9hZC5lbmFibGUoKS50aGVuKCgpPT57XG4gICAgICAgICAgICAgICAgaWYgKGhlYWRlclZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZvaWQgc2VsZi5yZWdpc3RyYXRpb24ubmF2aWdhdGlvblByZWxvYWQuc2V0SGVhZGVyVmFsdWUoaGVhZGVyVmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXCJOYXZpZ2F0aW9uIHByZWxvYWRpbmcgaXMgZW5hYmxlZC5cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBsb2dnZXIubG9nKFwiTmF2aWdhdGlvbiBwcmVsb2FkaW5nIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyLlwiKTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5jb25zdCBkaXNhYmxlTmF2aWdhdGlvblByZWxvYWQgPSAoKT0+e1xuICAgIGlmIChpc05hdmlnYXRpb25QcmVsb2FkU3VwcG9ydGVkKCkpIHtcbiAgICAgICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKFwiYWN0aXZhdGVcIiwgKGV2ZW50KT0+e1xuICAgICAgICAgICAgZXZlbnQud2FpdFVudGlsKHNlbGYucmVnaXN0cmF0aW9uLm5hdmlnYXRpb25QcmVsb2FkLmRpc2FibGUoKS50aGVuKCgpPT57XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKFwiTmF2aWdhdGlvbiBwcmVsb2FkaW5nIGlzIGRpc2FibGVkLlwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGxvZ2dlci5sb2coXCJOYXZpZ2F0aW9uIHByZWxvYWRpbmcgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXIuXCIpO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuY29uc3QgcmVtb3ZlSWdub3JlZFNlYXJjaFBhcmFtcyA9ICh1cmxPYmplY3QsIGlnbm9yZVVSTFBhcmFtZXRlcnNNYXRjaGluZyA9IFtdKT0+e1xuICAgIGZvciAoY29uc3QgcGFyYW1OYW1lIG9mIFtcbiAgICAgICAgLi4udXJsT2JqZWN0LnNlYXJjaFBhcmFtcy5rZXlzKClcbiAgICBdKXtcbiAgICAgICAgaWYgKGlnbm9yZVVSTFBhcmFtZXRlcnNNYXRjaGluZy5zb21lKChyZWdFeHApPT5yZWdFeHAudGVzdChwYXJhbU5hbWUpKSkge1xuICAgICAgICAgICAgdXJsT2JqZWN0LnNlYXJjaFBhcmFtcy5kZWxldGUocGFyYW1OYW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdXJsT2JqZWN0O1xufTtcblxuZnVuY3Rpb24qIGdlbmVyYXRlVVJMVmFyaWF0aW9ucyh1cmwsIHsgZGlyZWN0b3J5SW5kZXggPSBcImluZGV4Lmh0bWxcIiwgaWdub3JlVVJMUGFyYW1ldGVyc01hdGNoaW5nID0gW1xuICAgIC9edXRtXy8sXG4gICAgL15mYmNsaWQkL1xuXSwgY2xlYW5VUkxzID0gdHJ1ZSwgdXJsTWFuaXB1bGF0aW9uIH0gPSB7fSkge1xuICAgIGNvbnN0IHVybE9iamVjdCA9IG5ldyBVUkwodXJsLCBsb2NhdGlvbi5ocmVmKTtcbiAgICB1cmxPYmplY3QuaGFzaCA9IFwiXCI7XG4gICAgeWllbGQgdXJsT2JqZWN0LmhyZWY7XG4gICAgY29uc3QgdXJsV2l0aG91dElnbm9yZWRQYXJhbXMgPSByZW1vdmVJZ25vcmVkU2VhcmNoUGFyYW1zKHVybE9iamVjdCwgaWdub3JlVVJMUGFyYW1ldGVyc01hdGNoaW5nKTtcbiAgICB5aWVsZCB1cmxXaXRob3V0SWdub3JlZFBhcmFtcy5ocmVmO1xuICAgIGlmIChkaXJlY3RvcnlJbmRleCAmJiB1cmxXaXRob3V0SWdub3JlZFBhcmFtcy5wYXRobmFtZS5lbmRzV2l0aChcIi9cIikpIHtcbiAgICAgICAgY29uc3QgZGlyZWN0b3J5VVJMID0gbmV3IFVSTCh1cmxXaXRob3V0SWdub3JlZFBhcmFtcy5ocmVmKTtcbiAgICAgICAgZGlyZWN0b3J5VVJMLnBhdGhuYW1lICs9IGRpcmVjdG9yeUluZGV4O1xuICAgICAgICB5aWVsZCBkaXJlY3RvcnlVUkwuaHJlZjtcbiAgICB9XG4gICAgaWYgKGNsZWFuVVJMcykge1xuICAgICAgICBjb25zdCBjbGVhblVSTCA9IG5ldyBVUkwodXJsV2l0aG91dElnbm9yZWRQYXJhbXMuaHJlZik7XG4gICAgICAgIGNsZWFuVVJMLnBhdGhuYW1lICs9IFwiLmh0bWxcIjtcbiAgICAgICAgeWllbGQgY2xlYW5VUkwuaHJlZjtcbiAgICB9XG4gICAgaWYgKHVybE1hbmlwdWxhdGlvbikge1xuICAgICAgICBjb25zdCBhZGRpdGlvbmFsVVJMcyA9IHVybE1hbmlwdWxhdGlvbih7XG4gICAgICAgICAgICB1cmw6IHVybE9iamVjdFxuICAgICAgICB9KTtcbiAgICAgICAgZm9yIChjb25zdCB1cmxUb0F0dGVtcHQgb2YgYWRkaXRpb25hbFVSTHMpe1xuICAgICAgICAgICAgeWllbGQgdXJsVG9BdHRlbXB0LmhyZWY7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIFJlZ0V4cFJvdXRlIGV4dGVuZHMgUm91dGUge1xuICAgIGNvbnN0cnVjdG9yKHJlZ0V4cCwgaGFuZGxlciwgbWV0aG9kKXtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzSW5zdGFuY2UocmVnRXhwLCBSZWdFeHAsIHtcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiUmVnRXhwUm91dGVcIixcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJjb25zdHJ1Y3RvclwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJwYXR0ZXJuXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1hdGNoID0gKHsgdXJsIH0pPT57XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSByZWdFeHAuZXhlYyh1cmwuaHJlZik7XG4gICAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh1cmwub3JpZ2luICE9PSBsb2NhdGlvbi5vcmlnaW4gJiYgcmVzdWx0LmluZGV4ICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYFRoZSByZWd1bGFyIGV4cHJlc3Npb24gJyR7cmVnRXhwLnRvU3RyaW5nKCl9JyBvbmx5IHBhcnRpYWxseSBtYXRjaGVkIGFnYWluc3QgdGhlIGNyb3NzLW9yaWdpbiBVUkwgJyR7dXJsLnRvU3RyaW5nKCl9Jy4gUmVnRXhwUm91dGUncyB3aWxsIG9ubHkgaGFuZGxlIGNyb3NzLW9yaWdpbiByZXF1ZXN0cyBpZiB0aGV5IG1hdGNoIHRoZSBlbnRpcmUgVVJMLmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0LnNsaWNlKDEpO1xuICAgICAgICB9O1xuICAgICAgICBzdXBlcihtYXRjaCwgaGFuZGxlciwgbWV0aG9kKTtcbiAgICB9XG59XG5cbmNvbnN0IHNldENhY2hlTmFtZURldGFpbHMgPSAoZGV0YWlscyk9PntcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGRldGFpbHMpKXtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc1R5cGUoZGV0YWlsc1trZXldLCBcInN0cmluZ1wiLCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJAc2Vyd2lzdC9jb3JlXCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwic2V0Q2FjaGVOYW1lRGV0YWlsc1wiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogYGRldGFpbHMuJHtrZXl9YFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRldGFpbHMucHJlY2FjaGU/Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFNlcndpc3RFcnJvcihcImludmFsaWQtY2FjaGUtbmFtZVwiLCB7XG4gICAgICAgICAgICAgICAgY2FjaGVOYW1lSWQ6IFwicHJlY2FjaGVcIixcbiAgICAgICAgICAgICAgICB2YWx1ZTogZGV0YWlscy5wcmVjYWNoZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRldGFpbHMucnVudGltZT8ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiaW52YWxpZC1jYWNoZS1uYW1lXCIsIHtcbiAgICAgICAgICAgICAgICBjYWNoZU5hbWVJZDogXCJydW50aW1lXCIsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGRldGFpbHMucnVudGltZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRldGFpbHMuZ29vZ2xlQW5hbHl0aWNzPy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJpbnZhbGlkLWNhY2hlLW5hbWVcIiwge1xuICAgICAgICAgICAgICAgIGNhY2hlTmFtZUlkOiBcImdvb2dsZUFuYWx5dGljc1wiLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBkZXRhaWxzLmdvb2dsZUFuYWx5dGljc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2FjaGVOYW1lcy51cGRhdGVEZXRhaWxzKGRldGFpbHMpO1xufTtcblxuY29uc3QgUkVWSVNJT05fU0VBUkNIX1BBUkFNID0gXCJfX1dCX1JFVklTSU9OX19cIjtcbmNvbnN0IGNyZWF0ZUNhY2hlS2V5ID0gKGVudHJ5KT0+e1xuICAgIGlmICghZW50cnkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFNlcndpc3RFcnJvcihcImFkZC10by1jYWNoZS1saXN0LXVuZXhwZWN0ZWQtdHlwZVwiLCB7XG4gICAgICAgICAgICBlbnRyeVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbnRyeSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICBjb25zdCB1cmxPYmplY3QgPSBuZXcgVVJMKGVudHJ5LCBsb2NhdGlvbi5ocmVmKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNhY2hlS2V5OiB1cmxPYmplY3QuaHJlZixcbiAgICAgICAgICAgIHVybDogdXJsT2JqZWN0LmhyZWZcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY29uc3QgeyByZXZpc2lvbiwgdXJsIH0gPSBlbnRyeTtcbiAgICBpZiAoIXVybCkge1xuICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiYWRkLXRvLWNhY2hlLWxpc3QtdW5leHBlY3RlZC10eXBlXCIsIHtcbiAgICAgICAgICAgIGVudHJ5XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoIXJldmlzaW9uKSB7XG4gICAgICAgIGNvbnN0IHVybE9iamVjdCA9IG5ldyBVUkwodXJsLCBsb2NhdGlvbi5ocmVmKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNhY2hlS2V5OiB1cmxPYmplY3QuaHJlZixcbiAgICAgICAgICAgIHVybDogdXJsT2JqZWN0LmhyZWZcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY29uc3QgY2FjaGVLZXlVUkwgPSBuZXcgVVJMKHVybCwgbG9jYXRpb24uaHJlZik7XG4gICAgY29uc3Qgb3JpZ2luYWxVUkwgPSBuZXcgVVJMKHVybCwgbG9jYXRpb24uaHJlZik7XG4gICAgY2FjaGVLZXlVUkwuc2VhcmNoUGFyYW1zLnNldChSRVZJU0lPTl9TRUFSQ0hfUEFSQU0sIHJldmlzaW9uKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBjYWNoZUtleTogY2FjaGVLZXlVUkwuaHJlZixcbiAgICAgICAgdXJsOiBvcmlnaW5hbFVSTC5ocmVmXG4gICAgfTtcbn07XG5cbmNsYXNzIFByZWNhY2hlSW5zdGFsbFJlcG9ydFBsdWdpbiB7XG4gICAgdXBkYXRlZFVSTHMgPSBbXTtcbiAgICBub3RVcGRhdGVkVVJMcyA9IFtdO1xuICAgIGhhbmRsZXJXaWxsU3RhcnQgPSBhc3luYyAoeyByZXF1ZXN0LCBzdGF0ZSB9KT0+e1xuICAgICAgICBpZiAoc3RhdGUpIHtcbiAgICAgICAgICAgIHN0YXRlLm9yaWdpbmFsUmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNhY2hlZFJlc3BvbnNlV2lsbEJlVXNlZCA9IGFzeW5jICh7IGV2ZW50LCBzdGF0ZSwgY2FjaGVkUmVzcG9uc2UgfSk9PntcbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IFwiaW5zdGFsbFwiKSB7XG4gICAgICAgICAgICBpZiAoc3RhdGU/Lm9yaWdpbmFsUmVxdWVzdCAmJiBzdGF0ZS5vcmlnaW5hbFJlcXVlc3QgaW5zdGFuY2VvZiBSZXF1ZXN0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdXJsID0gc3RhdGUub3JpZ2luYWxSZXF1ZXN0LnVybDtcbiAgICAgICAgICAgICAgICBpZiAoY2FjaGVkUmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ub3RVcGRhdGVkVVJMcy5wdXNoKHVybCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVkVVJMcy5wdXNoKHVybCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWNoZWRSZXNwb25zZTtcbiAgICB9O1xufVxuXG5jb25zdCBwYXJzZVJvdXRlID0gKGNhcHR1cmUsIGhhbmRsZXIsIG1ldGhvZCk9PntcbiAgICBpZiAodHlwZW9mIGNhcHR1cmUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgY29uc3QgY2FwdHVyZVVybCA9IG5ldyBVUkwoY2FwdHVyZSwgbG9jYXRpb24uaHJlZik7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGlmICghKGNhcHR1cmUuc3RhcnRzV2l0aChcIi9cIikgfHwgY2FwdHVyZS5zdGFydHNXaXRoKFwiaHR0cFwiKSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiaW52YWxpZC1zdHJpbmdcIiwge1xuICAgICAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICAgICAgZnVuY05hbWU6IFwicGFyc2VSb3V0ZVwiLFxuICAgICAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwiY2FwdHVyZVwiXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB2YWx1ZVRvQ2hlY2sgPSBjYXB0dXJlLnN0YXJ0c1dpdGgoXCJodHRwXCIpID8gY2FwdHVyZVVybC5wYXRobmFtZSA6IGNhcHR1cmU7XG4gICAgICAgICAgICBjb25zdCB3aWxkY2FyZHMgPSBcIlsqOj8rXVwiO1xuICAgICAgICAgICAgaWYgKG5ldyBSZWdFeHAoYCR7d2lsZGNhcmRzfWApLmV4ZWModmFsdWVUb0NoZWNrKSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgVGhlICckY2FwdHVyZScgcGFyYW1ldGVyIGNvbnRhaW5zIGFuIEV4cHJlc3Mtc3R5bGUgd2lsZGNhcmQgY2hhcmFjdGVyICgke3dpbGRjYXJkc30pLiBTdHJpbmdzIGFyZSBub3cgYWx3YXlzIGludGVycHJldGVkIGFzIGV4YWN0IG1hdGNoZXM7IHVzZSBhIFJlZ0V4cCBmb3IgcGFydGlhbCBvciB3aWxkY2FyZCBtYXRjaGVzLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1hdGNoQ2FsbGJhY2sgPSAoeyB1cmwgfSk9PntcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAodXJsLnBhdGhuYW1lID09PSBjYXB0dXJlVXJsLnBhdGhuYW1lICYmIHVybC5vcmlnaW4gIT09IGNhcHR1cmVVcmwub3JpZ2luKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgJHtjYXB0dXJlfSBvbmx5IHBhcnRpYWxseSBtYXRjaGVzIHRoZSBjcm9zcy1vcmlnaW4gVVJMICR7dXJsLnRvU3RyaW5nKCl9LiBUaGlzIHJvdXRlIHdpbGwgb25seSBoYW5kbGUgY3Jvc3Mtb3JpZ2luIHJlcXVlc3RzIGlmIHRoZXkgbWF0Y2ggdGhlIGVudGlyZSBVUkwuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHVybC5ocmVmID09PSBjYXB0dXJlVXJsLmhyZWY7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgUm91dGUobWF0Y2hDYWxsYmFjaywgaGFuZGxlciwgbWV0aG9kKTtcbiAgICB9XG4gICAgaWYgKGNhcHR1cmUgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZWdFeHBSb3V0ZShjYXB0dXJlLCBoYW5kbGVyLCBtZXRob2QpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGNhcHR1cmUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gbmV3IFJvdXRlKGNhcHR1cmUsIGhhbmRsZXIsIG1ldGhvZCk7XG4gICAgfVxuICAgIGlmIChjYXB0dXJlIGluc3RhbmNlb2YgUm91dGUpIHtcbiAgICAgICAgcmV0dXJuIGNhcHR1cmU7XG4gICAgfVxuICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJ1bnN1cHBvcnRlZC1yb3V0ZS10eXBlXCIsIHtcbiAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgIGZ1bmNOYW1lOiBcInBhcnNlUm91dGVcIixcbiAgICAgICAgcGFyYW1OYW1lOiBcImNhcHR1cmVcIlxuICAgIH0pO1xufTtcblxuY29uc3QgbG9nR3JvdXAgPSAoZ3JvdXBUaXRsZSwgZGVsZXRlZFVSTHMpPT57XG4gICAgbG9nZ2VyLmdyb3VwQ29sbGFwc2VkKGdyb3VwVGl0bGUpO1xuICAgIGZvciAoY29uc3QgdXJsIG9mIGRlbGV0ZWRVUkxzKXtcbiAgICAgICAgbG9nZ2VyLmxvZyh1cmwpO1xuICAgIH1cbiAgICBsb2dnZXIuZ3JvdXBFbmQoKTtcbn07XG5jb25zdCBwcmludENsZWFudXBEZXRhaWxzID0gKGRlbGV0ZWRVUkxzKT0+e1xuICAgIGNvbnN0IGRlbGV0aW9uQ291bnQgPSBkZWxldGVkVVJMcy5sZW5ndGg7XG4gICAgaWYgKGRlbGV0aW9uQ291bnQgPiAwKSB7XG4gICAgICAgIGxvZ2dlci5ncm91cENvbGxhcHNlZChgRHVyaW5nIHByZWNhY2hpbmcgY2xlYW51cCwgJHtkZWxldGlvbkNvdW50fSBjYWNoZWQgcmVxdWVzdCR7ZGVsZXRpb25Db3VudCA9PT0gMSA/IFwiIHdhc1wiIDogXCJzIHdlcmVcIn0gZGVsZXRlZC5gKTtcbiAgICAgICAgbG9nR3JvdXAoXCJEZWxldGVkIENhY2hlIFJlcXVlc3RzXCIsIGRlbGV0ZWRVUkxzKTtcbiAgICAgICAgbG9nZ2VyLmdyb3VwRW5kKCk7XG4gICAgfVxufTtcblxuZnVuY3Rpb24gX25lc3RlZEdyb3VwKGdyb3VwVGl0bGUsIHVybHMpIHtcbiAgICBpZiAodXJscy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsb2dnZXIuZ3JvdXBDb2xsYXBzZWQoZ3JvdXBUaXRsZSk7XG4gICAgZm9yIChjb25zdCB1cmwgb2YgdXJscyl7XG4gICAgICAgIGxvZ2dlci5sb2codXJsKTtcbiAgICB9XG4gICAgbG9nZ2VyLmdyb3VwRW5kKCk7XG59XG5jb25zdCBwcmludEluc3RhbGxEZXRhaWxzID0gKHVybHNUb1ByZWNhY2hlLCB1cmxzQWxyZWFkeVByZWNhY2hlZCk9PntcbiAgICBjb25zdCBwcmVjYWNoZWRDb3VudCA9IHVybHNUb1ByZWNhY2hlLmxlbmd0aDtcbiAgICBjb25zdCBhbHJlYWR5UHJlY2FjaGVkQ291bnQgPSB1cmxzQWxyZWFkeVByZWNhY2hlZC5sZW5ndGg7XG4gICAgaWYgKHByZWNhY2hlZENvdW50IHx8IGFscmVhZHlQcmVjYWNoZWRDb3VudCkge1xuICAgICAgICBsZXQgbWVzc2FnZSA9IGBQcmVjYWNoaW5nICR7cHJlY2FjaGVkQ291bnR9IGZpbGUke3ByZWNhY2hlZENvdW50ID09PSAxID8gXCJcIiA6IFwic1wifS5gO1xuICAgICAgICBpZiAoYWxyZWFkeVByZWNhY2hlZENvdW50ID4gMCkge1xuICAgICAgICAgICAgbWVzc2FnZSArPSBgICR7YWxyZWFkeVByZWNhY2hlZENvdW50fSBgICsgYGZpbGUke2FscmVhZHlQcmVjYWNoZWRDb3VudCA9PT0gMSA/IFwiIGlzXCIgOiBcInMgYXJlXCJ9IGFscmVhZHkgY2FjaGVkLmA7XG4gICAgICAgIH1cbiAgICAgICAgbG9nZ2VyLmdyb3VwQ29sbGFwc2VkKG1lc3NhZ2UpO1xuICAgICAgICBfbmVzdGVkR3JvdXAoXCJWaWV3IG5ld2x5IHByZWNhY2hlZCBVUkxzLlwiLCB1cmxzVG9QcmVjYWNoZSk7XG4gICAgICAgIF9uZXN0ZWRHcm91cChcIlZpZXcgcHJldmlvdXNseSBwcmVjYWNoZWQgVVJMcy5cIiwgdXJsc0FscmVhZHlQcmVjYWNoZWQpO1xuICAgICAgICBsb2dnZXIuZ3JvdXBFbmQoKTtcbiAgICB9XG59O1xuXG5leHBvcnQgeyBCYWNrZ3JvdW5kU3luY1BsdWdpbiBhcyBCLCBOZXR3b3JrRmlyc3QgYXMgTiwgUHJlY2FjaGVTdHJhdGVneSBhcyBQLCBSb3V0ZSBhcyBSLCBTdHJhdGVneSBhcyBTLCBOZXR3b3JrT25seSBhcyBhLCBOYXZpZ2F0aW9uUm91dGUgYXMgYiwgY2FjaGVPa0FuZE9wYXF1ZVBsdWdpbiBhcyBjLCBkaXNhYmxlRGV2TG9ncyBhcyBkLCBlbmFibGVOYXZpZ2F0aW9uUHJlbG9hZCBhcyBlLCBjcmVhdGVDYWNoZUtleSBhcyBmLCBnZW5lcmF0ZVVSTFZhcmlhdGlvbnMgYXMgZywgZGVmYXVsdE1ldGhvZCBhcyBoLCBQcmVjYWNoZUluc3RhbGxSZXBvcnRQbHVnaW4gYXMgaSwgcHJpbnRJbnN0YWxsRGV0YWlscyBhcyBqLCBwcmludENsZWFudXBEZXRhaWxzIGFzIGssIEJhY2tncm91bmRTeW5jUXVldWUgYXMgbCwgbWVzc2FnZXMgYXMgbSwgbm9ybWFsaXplSGFuZGxlciBhcyBuLCBCYWNrZ3JvdW5kU3luY1F1ZXVlU3RvcmUgYXMgbywgcGFyc2VSb3V0ZSBhcyBwLCBSZWdFeHBSb3V0ZSBhcyBxLCBTdG9yYWJsZVJlcXVlc3QgYXMgciwgc2V0Q2FjaGVOYW1lRGV0YWlscyBhcyBzLCBTdHJhdGVneUhhbmRsZXIgYXMgdCwgY29weVJlc3BvbnNlIGFzIHUsIGRpc2FibGVOYXZpZ2F0aW9uUHJlbG9hZCBhcyB2LCBpc05hdmlnYXRpb25QcmVsb2FkU3VwcG9ydGVkIGFzIHcgfTtcbiJdLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOlswXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/serwist/dist/chunks/printInstallDetails.js\n")); - -/***/ }), - -/***/ "./node_modules/serwist/dist/chunks/resultingClientExists.js": -/*!*******************************************************************!*\ - !*** ./node_modules/serwist/dist/chunks/resultingClientExists.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ r: () => (/* binding */ resultingClientExists)\n/* harmony export */ });\n/* harmony import */ var _waitUntil_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./waitUntil.js */ \"./node_modules/serwist/dist/chunks/waitUntil.js\");\n\n\nconst MAX_RETRY_TIME = 2000;\nasync function resultingClientExists(resultingClientId) {\n if (!resultingClientId) {\n return;\n }\n let existingWindows = await self.clients.matchAll({\n type: \"window\"\n });\n const existingWindowIds = new Set(existingWindows.map((w)=>w.id));\n let resultingWindow;\n const startTime = performance.now();\n while(performance.now() - startTime < MAX_RETRY_TIME){\n existingWindows = await self.clients.matchAll({\n type: \"window\"\n });\n resultingWindow = existingWindows.find((w)=>{\n if (resultingClientId) {\n return w.id === resultingClientId;\n }\n return !existingWindowIds.has(w.id);\n });\n if (resultingWindow) {\n break;\n }\n await (0,_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.t)(100);\n }\n return resultingWindow;\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvc2Vyd2lzdC9kaXN0L2NodW5rcy9yZXN1bHRpbmdDbGllbnRFeGlzdHMuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBOEM7O0FBRTlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLGNBQWMsZ0RBQU87QUFDckI7QUFDQTtBQUNBOztBQUVzQyIsInNvdXJjZXMiOlsiL1VzZXJzL3NkOTIzNS9jb2RlL215Z2gvbGVhcm5pbmdfYWlfY2xvY2svd2ViL25vZGVfbW9kdWxlcy9zZXJ3aXN0L2Rpc3QvY2h1bmtzL3Jlc3VsdGluZ0NsaWVudEV4aXN0cy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0IGFzIHRpbWVvdXQgfSBmcm9tICcuL3dhaXRVbnRpbC5qcyc7XG5cbmNvbnN0IE1BWF9SRVRSWV9USU1FID0gMjAwMDtcbmFzeW5jIGZ1bmN0aW9uIHJlc3VsdGluZ0NsaWVudEV4aXN0cyhyZXN1bHRpbmdDbGllbnRJZCkge1xuICAgIGlmICghcmVzdWx0aW5nQ2xpZW50SWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgZXhpc3RpbmdXaW5kb3dzID0gYXdhaXQgc2VsZi5jbGllbnRzLm1hdGNoQWxsKHtcbiAgICAgICAgdHlwZTogXCJ3aW5kb3dcIlxuICAgIH0pO1xuICAgIGNvbnN0IGV4aXN0aW5nV2luZG93SWRzID0gbmV3IFNldChleGlzdGluZ1dpbmRvd3MubWFwKCh3KT0+dy5pZCkpO1xuICAgIGxldCByZXN1bHRpbmdXaW5kb3c7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgd2hpbGUocGVyZm9ybWFuY2Uubm93KCkgLSBzdGFydFRpbWUgPCBNQVhfUkVUUllfVElNRSl7XG4gICAgICAgIGV4aXN0aW5nV2luZG93cyA9IGF3YWl0IHNlbGYuY2xpZW50cy5tYXRjaEFsbCh7XG4gICAgICAgICAgICB0eXBlOiBcIndpbmRvd1wiXG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHRpbmdXaW5kb3cgPSBleGlzdGluZ1dpbmRvd3MuZmluZCgodyk9PntcbiAgICAgICAgICAgIGlmIChyZXN1bHRpbmdDbGllbnRJZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB3LmlkID09PSByZXN1bHRpbmdDbGllbnRJZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAhZXhpc3RpbmdXaW5kb3dJZHMuaGFzKHcuaWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdGluZ1dpbmRvdykge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGltZW91dCgxMDApO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0aW5nV2luZG93O1xufVxuXG5leHBvcnQgeyByZXN1bHRpbmdDbGllbnRFeGlzdHMgYXMgciB9O1xuIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6WzBdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/serwist/dist/chunks/resultingClientExists.js\n")); - -/***/ }), - -/***/ "./node_modules/serwist/dist/chunks/waitUntil.js": -/*!*******************************************************!*\ - !*** ./node_modules/serwist/dist/chunks/waitUntil.js ***! - \*******************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ D: () => (/* binding */ Deferred),\n/* harmony export */ S: () => (/* binding */ SerwistError),\n/* harmony export */ a: () => (/* binding */ clientsClaim),\n/* harmony export */ b: () => (/* binding */ cleanupOutdatedCaches),\n/* harmony export */ c: () => (/* binding */ cacheNames),\n/* harmony export */ d: () => (/* binding */ canConstructResponseFromBodyStream),\n/* harmony export */ e: () => (/* binding */ cacheMatchIgnoreParams),\n/* harmony export */ f: () => (/* binding */ finalAssertExports),\n/* harmony export */ g: () => (/* binding */ getFriendlyURL),\n/* harmony export */ h: () => (/* binding */ executeQuotaErrorCallbacks),\n/* harmony export */ l: () => (/* binding */ logger),\n/* harmony export */ q: () => (/* binding */ quotaErrorCallbacks),\n/* harmony export */ t: () => (/* binding */ timeout),\n/* harmony export */ w: () => (/* binding */ waitUntil)\n/* harmony export */ });\nconst _cacheNameDetails = {\n googleAnalytics: \"googleAnalytics\",\n precache: \"precache-v2\",\n prefix: \"serwist\",\n runtime: \"runtime\",\n suffix: typeof registration !== \"undefined\" ? registration.scope : \"\"\n};\nconst _createCacheName = (cacheName)=>{\n return [\n _cacheNameDetails.prefix,\n cacheName,\n _cacheNameDetails.suffix\n ].filter((value)=>value && value.length > 0).join(\"-\");\n};\nconst eachCacheNameDetail = (fn)=>{\n for (const key of Object.keys(_cacheNameDetails)){\n fn(key);\n }\n};\nconst cacheNames = {\n updateDetails: (details)=>{\n eachCacheNameDetail((key)=>{\n const detail = details[key];\n if (typeof detail === \"string\") {\n _cacheNameDetails[key] = detail;\n }\n });\n },\n getGoogleAnalyticsName: (userCacheName)=>{\n return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics);\n },\n getPrecacheName: (userCacheName)=>{\n return userCacheName || _createCacheName(_cacheNameDetails.precache);\n },\n getPrefix: ()=>{\n return _cacheNameDetails.prefix;\n },\n getRuntimeName: (userCacheName)=>{\n return userCacheName || _createCacheName(_cacheNameDetails.runtime);\n },\n getSuffix: ()=>{\n return _cacheNameDetails.suffix;\n }\n};\n\nlet supportStatus;\nfunction canConstructResponseFromBodyStream() {\n if (supportStatus === undefined) {\n const testResponse = new Response(\"\");\n if (\"body\" in testResponse) {\n try {\n new Response(testResponse.body);\n supportStatus = true;\n } catch {\n supportStatus = false;\n }\n }\n supportStatus = false;\n }\n return supportStatus;\n}\n\nconst messages = {\n \"invalid-value\": ({ paramName, validValueDescription, value })=>{\n if (!paramName || !validValueDescription) {\n throw new Error(`Unexpected input to 'invalid-value' error.`);\n }\n return `The '${paramName}' parameter was given a value with an ` + `unexpected value. ${validValueDescription} Received a value of ` + `${JSON.stringify(value)}.`;\n },\n \"not-an-array\": ({ moduleName, className, funcName, paramName })=>{\n if (!moduleName || !className || !funcName || !paramName) {\n throw new Error(`Unexpected input to 'not-an-array' error.`);\n }\n return `The parameter '${paramName}' passed into ` + `'${moduleName}.${className}.${funcName}()' must be an array.`;\n },\n \"incorrect-type\": ({ expectedType, paramName, moduleName, className, funcName })=>{\n if (!expectedType || !paramName || !moduleName || !funcName) {\n throw new Error(`Unexpected input to 'incorrect-type' error.`);\n }\n const classNameStr = className ? `${className}.` : \"\";\n return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}` + `${funcName}()' must be of type ${expectedType}.`;\n },\n \"incorrect-class\": ({ expectedClassName, paramName, moduleName, className, funcName, isReturnValueProblem })=>{\n if (!expectedClassName || !moduleName || !funcName) {\n throw new Error(`Unexpected input to 'incorrect-class' error.`);\n }\n const classNameStr = className ? `${className}.` : \"\";\n if (isReturnValueProblem) {\n return `The return value from '${moduleName}.${classNameStr}${funcName}()' must be an instance of class ${expectedClassName}.`;\n }\n return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`;\n },\n \"missing-a-method\": ({ expectedMethod, paramName, moduleName, className, funcName })=>{\n if (!expectedMethod || !paramName || !moduleName || !className || !funcName) {\n throw new Error(`Unexpected input to 'missing-a-method' error.`);\n }\n return `${moduleName}.${className}.${funcName}() expected the ` + `'${paramName}' parameter to expose a '${expectedMethod}' method.`;\n },\n \"add-to-cache-list-unexpected-type\": ({ entry })=>{\n return `An unexpected entry was passed to 'serwist.Serwist.addToPrecacheList()' The entry '${JSON.stringify(entry)}' isn't supported. You must supply an array of strings with one or more characters, objects with a url property or Request objects.`;\n },\n \"add-to-cache-list-conflicting-entries\": ({ firstEntry, secondEntry })=>{\n if (!firstEntry || !secondEntry) {\n throw new Error(\"Unexpected input to \" + `'add-to-cache-list-duplicate-entries' error.`);\n }\n return `Two of the entries passed to 'serwist.Serwist.addToPrecacheList()' had the URL ${firstEntry} but different revision details. Serwist is unable to cache and version the asset correctly. Please remove one of the entries.`;\n },\n \"plugin-error-request-will-fetch\": ({ thrownErrorMessage })=>{\n if (!thrownErrorMessage) {\n throw new Error(\"Unexpected input to \" + `'plugin-error-request-will-fetch', error.`);\n }\n return `An error was thrown by a plugin's 'requestWillFetch()' method. The thrown error message was: '${thrownErrorMessage}'.`;\n },\n \"invalid-cache-name\": ({ cacheNameId, value })=>{\n if (!cacheNameId) {\n throw new Error(`Expected a 'cacheNameId' for error 'invalid-cache-name'`);\n }\n return `You must provide a name containing at least one character for setCacheDetails({${cacheNameId}: '...'}). Received a value of '${JSON.stringify(value)}'`;\n },\n \"unregister-route-but-not-found-with-method\": ({ method })=>{\n if (!method) {\n throw new Error(\"Unexpected input to \" + `'unregister-route-but-not-found-with-method' error.`);\n }\n return `The route you're trying to unregister was not previously registered for the method type '${method}'.`;\n },\n \"unregister-route-route-not-registered\": ()=>{\n return `The route you're trying to unregister was not previously ` + \"registered.\";\n },\n \"queue-replay-failed\": ({ name })=>{\n return `Replaying the background sync queue '${name}' failed.`;\n },\n \"duplicate-queue-name\": ({ name })=>{\n return `The queue name '${name}' is already being used. All instances of 'serwist.BackgroundSyncQueue' must be given unique names.`;\n },\n \"expired-test-without-max-age\": ({ methodName, paramName })=>{\n return `The '${methodName}()' method can only be used when the ` + `'${paramName}' is used in the constructor.`;\n },\n \"unsupported-route-type\": ({ moduleName, className, funcName, paramName })=>{\n return `The supplied '${paramName}' parameter was an unsupported type. Please check the docs for ${moduleName}.${className}.${funcName} for valid input types.`;\n },\n \"not-array-of-class\": ({ value, expectedClass, moduleName, className, funcName, paramName })=>{\n return `The supplied '${paramName}' parameter must be an array of '${expectedClass}' objects. Received '${JSON.stringify(value)},'. Please check the call to ${moduleName}.${className}.${funcName}() to fix the issue.`;\n },\n \"max-entries-or-age-required\": ({ moduleName, className, funcName })=>{\n return `You must define either 'config.maxEntries' or 'config.maxAgeSeconds' in '${moduleName}.${className}.${funcName}'`;\n },\n \"statuses-or-headers-required\": ({ moduleName, className, funcName })=>{\n return `You must define either 'config.statuses' or 'config.headers' in '${moduleName}.${className}.${funcName}'`;\n },\n \"invalid-string\": ({ moduleName, funcName, paramName })=>{\n if (!paramName || !moduleName || !funcName) {\n throw new Error(`Unexpected input to 'invalid-string' error.`);\n }\n return `When using strings, the '${paramName}' parameter must start with 'http' (for cross-origin matches) or '/' (for same-origin matches). Please see the docs for ${moduleName}.${funcName}() for more info.`;\n },\n \"channel-name-required\": ()=>{\n return \"You must provide a channelName to construct a \" + \"BroadcastCacheUpdate instance.\";\n },\n \"invalid-responses-are-same-args\": ()=>{\n return \"The arguments passed into responsesAreSame() appear to be \" + \"invalid. Please ensure valid Responses are used.\";\n },\n \"expire-custom-caches-only\": ()=>{\n return `You must provide a 'cacheName' property when using the ` + \"expiration plugin with a runtime caching strategy.\";\n },\n \"unit-must-be-bytes\": ({ normalizedRangeHeader })=>{\n if (!normalizedRangeHeader) {\n throw new Error(`Unexpected input to 'unit-must-be-bytes' error.`);\n }\n return `The 'unit' portion of the Range header must be set to 'bytes'. The Range header provided was \"${normalizedRangeHeader}\"`;\n },\n \"single-range-only\": ({ normalizedRangeHeader })=>{\n if (!normalizedRangeHeader) {\n throw new Error(`Unexpected input to 'single-range-only' error.`);\n }\n return `Multiple ranges are not supported. Please use a single start value, and optional end value. The Range header provided was \"${normalizedRangeHeader}\"`;\n },\n \"invalid-range-values\": ({ normalizedRangeHeader })=>{\n if (!normalizedRangeHeader) {\n throw new Error(`Unexpected input to 'invalid-range-values' error.`);\n }\n return `The Range header is missing both start and end values. At least one of those values is needed. The Range header provided was \"${normalizedRangeHeader}\"`;\n },\n \"no-range-header\": ()=>{\n return \"No Range header was found in the Request provided.\";\n },\n \"range-not-satisfiable\": ({ size, start, end })=>{\n return `The start (${start}) and end (${end}) values in the Range are ` + `not satisfiable by the cached response, which is ${size} bytes.`;\n },\n \"attempt-to-cache-non-get-request\": ({ url, method })=>{\n return `Unable to cache '${url}' because it is a '${method}' request and only 'GET' requests can be cached.`;\n },\n \"cache-put-with-no-response\": ({ url })=>{\n return `There was an attempt to cache '${url}' but the response was not defined.`;\n },\n \"no-response\": ({ url, error })=>{\n let message = `The strategy could not generate a response for '${url}'.`;\n if (error) {\n message += ` The underlying error is ${error}.`;\n }\n return message;\n },\n \"bad-precaching-response\": ({ url, status })=>{\n return `The precaching request for '${url}' failed${status ? ` with an HTTP status of ${status}.` : \".\"}`;\n },\n \"non-precached-url\": ({ url })=>{\n return `'createHandlerBoundToURL(\"${url}\")' was called, but that URL is not precached. Please pass in a URL that is precached instead.`;\n },\n \"add-to-cache-list-conflicting-integrities\": ({ url })=>{\n return `Two of the entries passed to 'serwist.Serwist.addToPrecacheList()' had the URL ${url} with different integrity values. Please remove one of them.`;\n },\n \"missing-precache-entry\": ({ cacheName, url })=>{\n return `Unable to find a precached response in ${cacheName} for ${url}.`;\n },\n \"cross-origin-copy-response\": ({ origin })=>{\n return `'@serwist/core.copyResponse()' can only be used with same-origin responses. It was passed a response with origin ${origin}.`;\n },\n \"opaque-streams-source\": ({ type })=>{\n const message = `One of the '@serwist/streams' sources resulted in an '${type}' response.`;\n if (type === \"opaqueredirect\") {\n return `${message} Please do not use a navigation request that results in a redirect as a source.`;\n }\n return `${message} Please ensure your sources are CORS-enabled.`;\n }\n};\n\nconst fallback = (code, ...args)=>{\n let msg = code;\n if (args.length > 0) {\n msg += ` :: ${JSON.stringify(args)}`;\n }\n return msg;\n};\nconst generatorFunction = (code, details = {})=>{\n const message = messages[code];\n if (!message) {\n throw new Error(`Unable to find message for code '${code}'.`);\n }\n return message(details);\n};\nconst messageGenerator = false ? 0 : generatorFunction;\n\nclass SerwistError extends Error {\n details;\n constructor(errorCode, details){\n const message = messageGenerator(errorCode, details);\n super(message);\n this.name = errorCode;\n this.details = details;\n }\n}\n\nconst isArray = (value, details)=>{\n if (!Array.isArray(value)) {\n throw new SerwistError(\"not-an-array\", details);\n }\n};\nconst hasMethod = (object, expectedMethod, details)=>{\n const type = typeof object[expectedMethod];\n if (type !== \"function\") {\n details.expectedMethod = expectedMethod;\n throw new SerwistError(\"missing-a-method\", details);\n }\n};\nconst isType = (object, expectedType, details)=>{\n if (typeof object !== expectedType) {\n details.expectedType = expectedType;\n throw new SerwistError(\"incorrect-type\", details);\n }\n};\nconst isInstance = (object, expectedClass, details)=>{\n if (!(object instanceof expectedClass)) {\n details.expectedClassName = expectedClass.name;\n throw new SerwistError(\"incorrect-class\", details);\n }\n};\nconst isOneOf = (value, validValues, details)=>{\n if (!validValues.includes(value)) {\n details.validValueDescription = `Valid values are ${JSON.stringify(validValues)}.`;\n throw new SerwistError(\"invalid-value\", details);\n }\n};\nconst isArrayOfClass = (value, expectedClass, details)=>{\n const error = new SerwistError(\"not-array-of-class\", details);\n if (!Array.isArray(value)) {\n throw error;\n }\n for (const item of value){\n if (!(item instanceof expectedClass)) {\n throw error;\n }\n }\n};\nconst finalAssertExports = false ? 0 : {\n hasMethod,\n isArray,\n isInstance,\n isOneOf,\n isType,\n isArrayOfClass\n};\n\nconst getFriendlyURL = (url)=>{\n const urlObj = new URL(String(url), location.href);\n return urlObj.href.replace(new RegExp(`^${location.origin}`), \"\");\n};\n\nconst logger = false || typeof self === \"undefined\" ? null : (()=>{\n if (!(\"__WB_DISABLE_DEV_LOGS\" in globalThis)) {\n self.__WB_DISABLE_DEV_LOGS = false;\n }\n let inGroup = false;\n const methodToColorMap = {\n debug: \"#7f8c8d\",\n log: \"#2ecc71\",\n warn: \"#f39c12\",\n error: \"#c0392b\",\n groupCollapsed: \"#3498db\",\n groupEnd: null\n };\n const print = (method, args)=>{\n if (self.__WB_DISABLE_DEV_LOGS) {\n return;\n }\n if (method === \"groupCollapsed\") {\n if (typeof navigator !== \"undefined\" && /^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {\n console[method](...args);\n return;\n }\n }\n const styles = [\n `background: ${methodToColorMap[method]}`,\n \"border-radius: 0.5em\",\n \"color: white\",\n \"font-weight: bold\",\n \"padding: 2px 0.5em\"\n ];\n const logPrefix = inGroup ? [] : [\n \"%cserwist\",\n styles.join(\";\")\n ];\n console[method](...logPrefix, ...args);\n if (method === \"groupCollapsed\") {\n inGroup = true;\n }\n if (method === \"groupEnd\") {\n inGroup = false;\n }\n };\n const loggerMethods = Object.keys(methodToColorMap);\n return loggerMethods.reduce((api, method)=>{\n api[method] = (...args)=>{\n print(method, args);\n };\n return api;\n }, {});\n})();\n\nfunction timeout(ms) {\n return new Promise((resolve)=>setTimeout(resolve, ms));\n}\n\nconst quotaErrorCallbacks = new Set();\n\nfunction stripParams(fullURL, ignoreParams) {\n const strippedURL = new URL(fullURL);\n for (const param of ignoreParams){\n strippedURL.searchParams.delete(param);\n }\n return strippedURL.href;\n}\nasync function cacheMatchIgnoreParams(cache, request, ignoreParams, matchOptions) {\n const strippedRequestURL = stripParams(request.url, ignoreParams);\n if (request.url === strippedRequestURL) {\n return cache.match(request, matchOptions);\n }\n const keysOptions = {\n ...matchOptions,\n ignoreSearch: true\n };\n const cacheKeys = await cache.keys(request, keysOptions);\n for (const cacheKey of cacheKeys){\n const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams);\n if (strippedRequestURL === strippedCacheKeyURL) {\n return cache.match(cacheKey, matchOptions);\n }\n }\n return;\n}\n\nclass Deferred {\n promise;\n resolve;\n reject;\n constructor(){\n this.promise = new Promise((resolve, reject)=>{\n this.resolve = resolve;\n this.reject = reject;\n });\n }\n}\n\nconst executeQuotaErrorCallbacks = async ()=>{\n if (true) {\n logger.log(`About to run ${quotaErrorCallbacks.size} callbacks to clean up caches.`);\n }\n for (const callback of quotaErrorCallbacks){\n await callback();\n if (true) {\n logger.log(callback, \"is complete.\");\n }\n }\n if (true) {\n logger.log(\"Finished running callbacks.\");\n }\n};\n\nconst SUBSTRING_TO_FIND = \"-precache-\";\nconst deleteOutdatedCaches = async (currentPrecacheName, substringToFind = SUBSTRING_TO_FIND)=>{\n const cacheNames = await self.caches.keys();\n const cacheNamesToDelete = cacheNames.filter((cacheName)=>{\n return cacheName.includes(substringToFind) && cacheName.includes(self.registration.scope) && cacheName !== currentPrecacheName;\n });\n await Promise.all(cacheNamesToDelete.map((cacheName)=>self.caches.delete(cacheName)));\n return cacheNamesToDelete;\n};\n\nconst cleanupOutdatedCaches = (cacheName)=>{\n self.addEventListener(\"activate\", (event)=>{\n event.waitUntil(deleteOutdatedCaches(cacheNames.getPrecacheName(cacheName)).then((cachesDeleted)=>{\n if (true) {\n if (cachesDeleted.length > 0) {\n logger.log(\"The following out-of-date precaches were cleaned up automatically:\", cachesDeleted);\n }\n }\n }));\n });\n};\n\nconst clientsClaim = ()=>{\n self.addEventListener(\"activate\", ()=>self.clients.claim());\n};\n\nconst waitUntil = (event, asyncFn)=>{\n const returnPromise = asyncFn();\n event.waitUntil(returnPromise);\n return returnPromise;\n};\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvc2Vyd2lzdC9kaXN0L2NodW5rcy93YWl0VW50aWwuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx3QkFBd0IseUNBQXlDO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixVQUFVLCtEQUErRCx1QkFBdUIsMkJBQTJCLHNCQUFzQjtBQUN4SyxLQUFLO0FBQ0wsdUJBQXVCLDRDQUE0QztBQUNuRTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsVUFBVSxzQkFBc0IsV0FBVyxHQUFHLFVBQVUsR0FBRyxTQUFTO0FBQ3JHLEtBQUs7QUFDTCx5QkFBeUIsMERBQTBEO0FBQ25GO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QyxVQUFVO0FBQ3RELGlDQUFpQyxVQUFVLHNCQUFzQixXQUFXLEdBQUcsYUFBYSxPQUFPLFNBQVMsc0JBQXNCLGFBQWE7QUFDL0ksS0FBSztBQUNMLDBCQUEwQixxRkFBcUY7QUFDL0c7QUFDQTtBQUNBO0FBQ0EsNENBQTRDLFVBQVU7QUFDdEQ7QUFDQSw2Q0FBNkMsV0FBVyxHQUFHLGFBQWEsRUFBRSxTQUFTLG1DQUFtQyxrQkFBa0I7QUFDeEk7QUFDQSxpQ0FBaUMsVUFBVSxzQkFBc0IsV0FBVyxHQUFH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QUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUssSUFBSTtBQUNULENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBLFFBQVEsSUFBcUM7QUFDN0MsbUNBQW1DLDBCQUEwQjtBQUM3RDtBQUNBO0FBQ0E7QUFDQSxZQUFZLElBQXFDO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBLFFBQVEsSUFBcUM7QUFDN0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixJQUFxQztBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRXNVIiwic291cmNlcyI6WyIvVXNlcnMvc2Q5MjM1L2NvZGUvbXlnaC9sZWFybmluZ19haV9jbG9jay93ZWIvbm9kZV9tb2R1bGVzL3Nlcndpc3QvZGlzdC9jaHVua3Mvd2FpdFVudGlsLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IF9jYWNoZU5hbWVEZXRhaWxzID0ge1xuICAgIGdvb2dsZUFuYWx5dGljczogXCJnb29nbGVBbmFseXRpY3NcIixcbiAgICBwcmVjYWNoZTogXCJwcmVjYWNoZS12MlwiLFxuICAgIHByZWZpeDogXCJzZXJ3aXN0XCIsXG4gICAgcnVudGltZTogXCJydW50aW1lXCIsXG4gICAgc3VmZml4OiB0eXBlb2YgcmVnaXN0cmF0aW9uICE9PSBcInVuZGVmaW5lZFwiID8gcmVnaXN0cmF0aW9uLnNjb3BlIDogXCJcIlxufTtcbmNvbnN0IF9jcmVhdGVDYWNoZU5hbWUgPSAoY2FjaGVOYW1lKT0+e1xuICAgIHJldHVybiBbXG4gICAgICAgIF9jYWNoZU5hbWVEZXRhaWxzLnByZWZpeCxcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICBfY2FjaGVOYW1lRGV0YWlscy5zdWZmaXhcbiAgICBdLmZpbHRlcigodmFsdWUpPT52YWx1ZSAmJiB2YWx1ZS5sZW5ndGggPiAwKS5qb2luKFwiLVwiKTtcbn07XG5jb25zdCBlYWNoQ2FjaGVOYW1lRGV0YWlsID0gKGZuKT0+e1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKF9jYWNoZU5hbWVEZXRhaWxzKSl7XG4gICAgICAgIGZuKGtleSk7XG4gICAgfVxufTtcbmNvbnN0IGNhY2hlTmFtZXMgPSB7XG4gICAgdXBkYXRlRGV0YWlsczogKGRldGFpbHMpPT57XG4gICAgICAgIGVhY2hDYWNoZU5hbWVEZXRhaWwoKGtleSk9PntcbiAgICAgICAgICAgIGNvbnN0IGRldGFpbCA9IGRldGFpbHNba2V5XTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGV0YWlsID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgX2NhY2hlTmFtZURldGFpbHNba2V5XSA9IGRldGFpbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICBnZXRHb29nbGVBbmFseXRpY3NOYW1lOiAodXNlckNhY2hlTmFtZSk9PntcbiAgICAgICAgcmV0dXJuIHVzZXJDYWNoZU5hbWUgfHwgX2NyZWF0ZUNhY2hlTmFtZShfY2FjaGVOYW1lRGV0YWlscy5nb29nbGVBbmFseXRpY3MpO1xuICAgIH0sXG4gICAgZ2V0UHJlY2FjaGVOYW1lOiAodXNlckNhY2hlTmFtZSk9PntcbiAgICAgICAgcmV0dXJuIHVzZXJDYWNoZU5hbWUgfHwgX2NyZWF0ZUNhY2hlTmFtZShfY2FjaGVOYW1lRGV0YWlscy5wcmVjYWNoZSk7XG4gICAgfSxcbiAgICBnZXRQcmVmaXg6ICgpPT57XG4gICAgICAgIHJldHVybiBfY2FjaGVOYW1lRGV0YWlscy5wcmVmaXg7XG4gICAgfSxcbiAgICBnZXRSdW50aW1lTmFtZTogKHVzZXJDYWNoZU5hbWUpPT57XG4gICAgICAgIHJldHVybiB1c2VyQ2FjaGVOYW1lIHx8IF9jcmVhdGVDYWNoZU5hbWUoX2NhY2hlTmFtZURldGFpbHMucnVudGltZSk7XG4gICAgfSxcbiAgICBnZXRTdWZmaXg6ICgpPT57XG4gICAgICAgIHJldHVybiBfY2FjaGVOYW1lRGV0YWlscy5zdWZmaXg7XG4gICAgfVxufTtcblxubGV0IHN1cHBvcnRTdGF0dXM7XG5mdW5jdGlvbiBjYW5Db25zdHJ1Y3RSZXNwb25zZUZyb21Cb2R5U3RyZWFtKCkge1xuICAgIGlmIChzdXBwb3J0U3RhdHVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgdGVzdFJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKFwiXCIpO1xuICAgICAgICBpZiAoXCJib2R5XCIgaW4gdGVzdFJlc3BvbnNlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5ldyBSZXNwb25zZSh0ZXN0UmVzcG9uc2UuYm9keSk7XG4gICAgICAgICAgICAgICAgc3VwcG9ydFN0YXR1cyA9IHRydWU7XG4gICAgICAgICAgICB9IGNhdGNoICB7XG4gICAgICAgICAgICAgICAgc3VwcG9ydFN0YXR1cyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN1cHBvcnRTdGF0dXMgPSBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHN1cHBvcnRTdGF0dXM7XG59XG5cbmNvbnN0IG1lc3NhZ2VzID0ge1xuICAgIFwiaW52YWxpZC12YWx1ZVwiOiAoeyBwYXJhbU5hbWUsIHZhbGlkVmFsdWVEZXNjcmlwdGlvbiwgdmFsdWUgfSk9PntcbiAgICAgICAgaWYgKCFwYXJhbU5hbWUgfHwgIXZhbGlkVmFsdWVEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIGlucHV0IHRvICdpbnZhbGlkLXZhbHVlJyBlcnJvci5gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYFRoZSAnJHtwYXJhbU5hbWV9JyBwYXJhbWV0ZXIgd2FzIGdpdmVuIGEgdmFsdWUgd2l0aCBhbiBgICsgYHVuZXhwZWN0ZWQgdmFsdWUuICR7dmFsaWRWYWx1ZURlc2NyaXB0aW9ufSBSZWNlaXZlZCBhIHZhbHVlIG9mIGAgKyBgJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9LmA7XG4gICAgfSxcbiAgICBcIm5vdC1hbi1hcnJheVwiOiAoeyBtb2R1bGVOYW1lLCBjbGFzc05hbWUsIGZ1bmNOYW1lLCBwYXJhbU5hbWUgfSk9PntcbiAgICAgICAgaWYgKCFtb2R1bGVOYW1lIHx8ICFjbGFzc05hbWUgfHwgIWZ1bmNOYW1lIHx8ICFwYXJhbU5hbWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBpbnB1dCB0byAnbm90LWFuLWFycmF5JyBlcnJvci5gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYFRoZSBwYXJhbWV0ZXIgJyR7cGFyYW1OYW1lfScgcGFzc2VkIGludG8gYCArIGAnJHttb2R1bGVOYW1lfS4ke2NsYXNzTmFtZX0uJHtmdW5jTmFtZX0oKScgbXVzdCBiZSBhbiBhcnJheS5gO1xuICAgIH0sXG4gICAgXCJpbmNvcnJlY3QtdHlwZVwiOiAoeyBleHBlY3RlZFR5cGUsIHBhcmFtTmFtZSwgbW9kdWxlTmFtZSwgY2xhc3NOYW1lLCBmdW5jTmFtZSB9KT0+e1xuICAgICAgICBpZiAoIWV4cGVjdGVkVHlwZSB8fCAhcGFyYW1OYW1lIHx8ICFtb2R1bGVOYW1lIHx8ICFmdW5jTmFtZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIGlucHV0IHRvICdpbmNvcnJlY3QtdHlwZScgZXJyb3IuYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2xhc3NOYW1lU3RyID0gY2xhc3NOYW1lID8gYCR7Y2xhc3NOYW1lfS5gIDogXCJcIjtcbiAgICAgICAgcmV0dXJuIGBUaGUgcGFyYW1ldGVyICcke3BhcmFtTmFtZX0nIHBhc3NlZCBpbnRvIGAgKyBgJyR7bW9kdWxlTmFtZX0uJHtjbGFzc05hbWVTdHJ9YCArIGAke2Z1bmNOYW1lfSgpJyBtdXN0IGJlIG9mIHR5cGUgJHtleHBlY3RlZFR5cGV9LmA7XG4gICAgfSxcbiAgICBcImluY29ycmVjdC1jbGFzc1wiOiAoeyBleHBlY3RlZENsYXNzTmFtZSwgcGFyYW1OYW1lLCBtb2R1bGVOYW1lLCBjbGFzc05hbWUsIGZ1bmNOYW1lLCBpc1JldHVyblZhbHVlUHJvYmxlbSB9KT0+e1xuICAgICAgICBpZiAoIWV4cGVjdGVkQ2xhc3NOYW1lIHx8ICFtb2R1bGVOYW1lIHx8ICFmdW5jTmFtZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIGlucHV0IHRvICdpbmNvcnJlY3QtY2xhc3MnIGVycm9yLmApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsYXNzTmFtZVN0ciA9IGNsYXNzTmFtZSA/IGAke2NsYXNzTmFtZX0uYCA6IFwiXCI7XG4gICAgICAgIGlmIChpc1JldHVyblZhbHVlUHJvYmxlbSkge1xuICAgICAgICAgICAgcmV0dXJuIGBUaGUgcmV0dXJuIHZhbHVlIGZyb20gJyR7bW9kdWxlTmFtZX0uJHtjbGFzc05hbWVTdHJ9JHtmdW5jTmFtZX0oKScgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBjbGFzcyAke2V4cGVjdGVkQ2xhc3NOYW1lfS5gO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgVGhlIHBhcmFtZXRlciAnJHtwYXJhbU5hbWV9JyBwYXNzZWQgaW50byBgICsgYCcke21vZHVsZU5hbWV9LiR7Y2xhc3NOYW1lU3RyfSR7ZnVuY05hbWV9KCknIGAgKyBgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBjbGFzcyAke2V4cGVjdGVkQ2xhc3NOYW1lfS5gO1xuICAgIH0sXG4gICAgXCJtaXNzaW5nLWEtbWV0aG9kXCI6ICh7IGV4cGVjdGVkTWV0aG9kLCBwYXJhbU5hbWUsIG1vZHVsZU5hbWUsIGNsYXNzTmFtZSwgZnVuY05hbWUgfSk9PntcbiAgICAgICAgaWYgKCFleHBlY3RlZE1ldGhvZCB8fCAhcGFyYW1OYW1lIHx8ICFtb2R1bGVOYW1lIHx8ICFjbGFzc05hbWUgfHwgIWZ1bmNOYW1lKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgaW5wdXQgdG8gJ21pc3NpbmctYS1tZXRob2QnIGVycm9yLmApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgJHttb2R1bGVOYW1lfS4ke2NsYXNzTmFtZX0uJHtmdW5jTmFtZX0oKSBleHBlY3RlZCB0aGUgYCArIGAnJHtwYXJhbU5hbWV9JyBwYXJhbWV0ZXIgdG8gZXhwb3NlIGEgJyR7ZXhwZWN0ZWRNZXRob2R9JyBtZXRob2QuYDtcbiAgICB9LFxuICAgIFwiYWRkLXRvLWNhY2hlLWxpc3QtdW5leHBlY3RlZC10eXBlXCI6ICh7IGVudHJ5IH0pPT57XG4gICAgICAgIHJldHVybiBgQW4gdW5leHBlY3RlZCBlbnRyeSB3YXMgcGFzc2VkIHRvICdzZXJ3aXN0LlNlcndpc3QuYWRkVG9QcmVjYWNoZUxpc3QoKScgVGhlIGVudHJ5ICcke0pTT04uc3RyaW5naWZ5KGVudHJ5KX0nIGlzbid0IHN1cHBvcnRlZC4gWW91IG11c3Qgc3VwcGx5IGFuIGFycmF5IG9mIHN0cmluZ3Mgd2l0aCBvbmUgb3IgbW9yZSBjaGFyYWN0ZXJzLCBvYmplY3RzIHdpdGggYSB1cmwgcHJvcGVydHkgb3IgUmVxdWVzdCBvYmplY3RzLmA7XG4gICAgfSxcbiAgICBcImFkZC10by1jYWNoZS1saXN0LWNvbmZsaWN0aW5nLWVudHJpZXNcIjogKHsgZmlyc3RFbnRyeSwgc2Vjb25kRW50cnkgfSk9PntcbiAgICAgICAgaWYgKCFmaXJzdEVudHJ5IHx8ICFzZWNvbmRFbnRyeSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5leHBlY3RlZCBpbnB1dCB0byBcIiArIGAnYWRkLXRvLWNhY2hlLWxpc3QtZHVwbGljYXRlLWVudHJpZXMnIGVycm9yLmApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgVHdvIG9mIHRoZSBlbnRyaWVzIHBhc3NlZCB0byAnc2Vyd2lzdC5TZXJ3aXN0LmFkZFRvUHJlY2FjaGVMaXN0KCknIGhhZCB0aGUgVVJMICR7Zmlyc3RFbnRyeX0gYnV0IGRpZmZlcmVudCByZXZpc2lvbiBkZXRhaWxzLiBTZXJ3aXN0IGlzIHVuYWJsZSB0byBjYWNoZSBhbmQgdmVyc2lvbiB0aGUgYXNzZXQgY29ycmVjdGx5LiBQbGVhc2UgcmVtb3ZlIG9uZSBvZiB0aGUgZW50cmllcy5gO1xuICAgIH0sXG4gICAgXCJwbHVnaW4tZXJyb3ItcmVxdWVzdC13aWxsLWZldGNoXCI6ICh7IHRocm93bkVycm9yTWVzc2FnZSB9KT0+e1xuICAgICAgICBpZiAoIXRocm93bkVycm9yTWVzc2FnZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5leHBlY3RlZCBpbnB1dCB0byBcIiArIGAncGx1Z2luLWVycm9yLXJlcXVlc3Qtd2lsbC1mZXRjaCcsIGVycm9yLmApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgQW4gZXJyb3Igd2FzIHRocm93biBieSBhIHBsdWdpbidzICdyZXF1ZXN0V2lsbEZldGNoKCknIG1ldGhvZC4gVGhlIHRocm93biBlcnJvciBtZXNzYWdlIHdhczogJyR7dGhyb3duRXJyb3JNZXNzYWdlfScuYDtcbiAgICB9LFxuICAgIFwiaW52YWxpZC1jYWNoZS1uYW1lXCI6ICh7IGNhY2hlTmFtZUlkLCB2YWx1ZSB9KT0+e1xuICAgICAgICBpZiAoIWNhY2hlTmFtZUlkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGEgJ2NhY2hlTmFtZUlkJyBmb3IgZXJyb3IgJ2ludmFsaWQtY2FjaGUtbmFtZSdgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYFlvdSBtdXN0IHByb3ZpZGUgYSBuYW1lIGNvbnRhaW5pbmcgYXQgbGVhc3Qgb25lIGNoYXJhY3RlciBmb3Igc2V0Q2FjaGVEZXRhaWxzKHske2NhY2hlTmFtZUlkfTogJy4uLid9KS4gUmVjZWl2ZWQgYSB2YWx1ZSBvZiAnJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9J2A7XG4gICAgfSxcbiAgICBcInVucmVnaXN0ZXItcm91dGUtYnV0LW5vdC1mb3VuZC13aXRoLW1ldGhvZFwiOiAoeyBtZXRob2QgfSk9PntcbiAgICAgICAgaWYgKCFtZXRob2QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVuZXhwZWN0ZWQgaW5wdXQgdG8gXCIgKyBgJ3VucmVnaXN0ZXItcm91dGUtYnV0LW5vdC1mb3VuZC13aXRoLW1ldGhvZCcgZXJyb3IuYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGBUaGUgcm91dGUgeW91J3JlIHRyeWluZyB0byB1bnJlZ2lzdGVyIHdhcyBub3QgIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCBmb3IgdGhlIG1ldGhvZCB0eXBlICcke21ldGhvZH0nLmA7XG4gICAgfSxcbiAgICBcInVucmVnaXN0ZXItcm91dGUtcm91dGUtbm90LXJlZ2lzdGVyZWRcIjogKCk9PntcbiAgICAgICAgcmV0dXJuIGBUaGUgcm91dGUgeW91J3JlIHRyeWluZyB0byB1bnJlZ2lzdGVyIHdhcyBub3QgcHJldmlvdXNseSBgICsgXCJyZWdpc3RlcmVkLlwiO1xuICAgIH0sXG4gICAgXCJxdWV1ZS1yZXBsYXktZmFpbGVkXCI6ICh7IG5hbWUgfSk9PntcbiAgICAgICAgcmV0dXJuIGBSZXBsYXlpbmcgdGhlIGJhY2tncm91bmQgc3luYyBxdWV1ZSAnJHtuYW1lfScgZmFpbGVkLmA7XG4gICAgfSxcbiAgICBcImR1cGxpY2F0ZS1xdWV1ZS1uYW1lXCI6ICh7IG5hbWUgfSk9PntcbiAgICAgICAgcmV0dXJuIGBUaGUgcXVldWUgbmFtZSAnJHtuYW1lfScgaXMgYWxyZWFkeSBiZWluZyB1c2VkLiBBbGwgaW5zdGFuY2VzIG9mICdzZXJ3aXN0LkJhY2tncm91bmRTeW5jUXVldWUnIG11c3QgYmUgZ2l2ZW4gdW5pcXVlIG5hbWVzLmA7XG4gICAgfSxcbiAgICBcImV4cGlyZWQtdGVzdC13aXRob3V0LW1heC1hZ2VcIjogKHsgbWV0aG9kTmFtZSwgcGFyYW1OYW1lIH0pPT57XG4gICAgICAgIHJldHVybiBgVGhlICcke21ldGhvZE5hbWV9KCknIG1ldGhvZCBjYW4gb25seSBiZSB1c2VkIHdoZW4gdGhlIGAgKyBgJyR7cGFyYW1OYW1lfScgaXMgdXNlZCBpbiB0aGUgY29uc3RydWN0b3IuYDtcbiAgICB9LFxuICAgIFwidW5zdXBwb3J0ZWQtcm91dGUtdHlwZVwiOiAoeyBtb2R1bGVOYW1lLCBjbGFzc05hbWUsIGZ1bmNOYW1lLCBwYXJhbU5hbWUgfSk9PntcbiAgICAgICAgcmV0dXJuIGBUaGUgc3VwcGxpZWQgJyR7cGFyYW1OYW1lfScgcGFyYW1ldGVyIHdhcyBhbiB1bnN1cHBvcnRlZCB0eXBlLiBQbGVhc2UgY2hlY2sgdGhlIGRvY3MgZm9yICR7bW9kdWxlTmFtZX0uJHtjbGFzc05hbWV9LiR7ZnVuY05hbWV9IGZvciB2YWxpZCBpbnB1dCB0eXBlcy5gO1xuICAgIH0sXG4gICAgXCJub3QtYXJyYXktb2YtY2xhc3NcIjogKHsgdmFsdWUsIGV4cGVjdGVkQ2xhc3MsIG1vZHVsZU5hbWUsIGNsYXNzTmFtZSwgZnVuY05hbWUsIHBhcmFtTmFtZSB9KT0+e1xuICAgICAgICByZXR1cm4gYFRoZSBzdXBwbGllZCAnJHtwYXJhbU5hbWV9JyBwYXJhbWV0ZXIgbXVzdCBiZSBhbiBhcnJheSBvZiAnJHtleHBlY3RlZENsYXNzfScgb2JqZWN0cy4gUmVjZWl2ZWQgJyR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfSwnLiBQbGVhc2UgY2hlY2sgdGhlIGNhbGwgdG8gJHttb2R1bGVOYW1lfS4ke2NsYXNzTmFtZX0uJHtmdW5jTmFtZX0oKSB0byBmaXggdGhlIGlzc3VlLmA7XG4gICAgfSxcbiAgICBcIm1heC1lbnRyaWVzLW9yLWFnZS1yZXF1aXJlZFwiOiAoeyBtb2R1bGVOYW1lLCBjbGFzc05hbWUsIGZ1bmNOYW1lIH0pPT57XG4gICAgICAgIHJldHVybiBgWW91IG11c3QgZGVmaW5lIGVpdGhlciAnY29uZmlnLm1heEVudHJpZXMnIG9yICdjb25maWcubWF4QWdlU2Vjb25kcycgaW4gJyR7bW9kdWxlTmFtZX0uJHtjbGFzc05hbWV9LiR7ZnVuY05hbWV9J2A7XG4gICAgfSxcbiAgICBcInN0YXR1c2VzLW9yLWhlYWRlcnMtcmVxdWlyZWRcIjogKHsgbW9kdWxlTmFtZSwgY2xhc3NOYW1lLCBmdW5jTmFtZSB9KT0+e1xuICAgICAgICByZXR1cm4gYFlvdSBtdXN0IGRlZmluZSBlaXRoZXIgJ2NvbmZpZy5zdGF0dXNlcycgb3IgJ2NvbmZpZy5oZWFkZXJzJyBpbiAnJHttb2R1bGVOYW1lfS4ke2NsYXNzTmFtZX0uJHtmdW5jTmFtZX0nYDtcbiAgICB9LFxuICAgIFwiaW52YWxpZC1zdHJpbmdcIjogKHsgbW9kdWxlTmFtZSwgZnVuY05hbWUsIHBhcmFtTmFtZSB9KT0+e1xuICAgICAgICBpZiAoIXBhcmFtTmFtZSB8fCAhbW9kdWxlTmFtZSB8fCAhZnVuY05hbWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBpbnB1dCB0byAnaW52YWxpZC1zdHJpbmcnIGVycm9yLmApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgV2hlbiB1c2luZyBzdHJpbmdzLCB0aGUgJyR7cGFyYW1OYW1lfScgcGFyYW1ldGVyIG11c3Qgc3RhcnQgd2l0aCAnaHR0cCcgKGZvciBjcm9zcy1vcmlnaW4gbWF0Y2hlcykgb3IgJy8nIChmb3Igc2FtZS1vcmlnaW4gbWF0Y2hlcykuIFBsZWFzZSBzZWUgdGhlIGRvY3MgZm9yICR7bW9kdWxlTmFtZX0uJHtmdW5jTmFtZX0oKSBmb3IgbW9yZSBpbmZvLmA7XG4gICAgfSxcbiAgICBcImNoYW5uZWwtbmFtZS1yZXF1aXJlZFwiOiAoKT0+e1xuICAgICAgICByZXR1cm4gXCJZb3UgbXVzdCBwcm92aWRlIGEgY2hhbm5lbE5hbWUgdG8gY29uc3RydWN0IGEgXCIgKyBcIkJyb2FkY2FzdENhY2hlVXBkYXRlIGluc3RhbmNlLlwiO1xuICAgIH0sXG4gICAgXCJpbnZhbGlkLXJlc3BvbnNlcy1hcmUtc2FtZS1hcmdzXCI6ICgpPT57XG4gICAgICAgIHJldHVybiBcIlRoZSBhcmd1bWVudHMgcGFzc2VkIGludG8gcmVzcG9uc2VzQXJlU2FtZSgpIGFwcGVhciB0byBiZSBcIiArIFwiaW52YWxpZC4gUGxlYXNlIGVuc3VyZSB2YWxpZCBSZXNwb25zZXMgYXJlIHVzZWQuXCI7XG4gICAgfSxcbiAgICBcImV4cGlyZS1jdXN0b20tY2FjaGVzLW9ubHlcIjogKCk9PntcbiAgICAgICAgcmV0dXJuIGBZb3UgbXVzdCBwcm92aWRlIGEgJ2NhY2hlTmFtZScgcHJvcGVydHkgd2hlbiB1c2luZyB0aGUgYCArIFwiZXhwaXJhdGlvbiBwbHVnaW4gd2l0aCBhIHJ1bnRpbWUgY2FjaGluZyBzdHJhdGVneS5cIjtcbiAgICB9LFxuICAgIFwidW5pdC1tdXN0LWJlLWJ5dGVzXCI6ICh7IG5vcm1hbGl6ZWRSYW5nZUhlYWRlciB9KT0+e1xuICAgICAgICBpZiAoIW5vcm1hbGl6ZWRSYW5nZUhlYWRlcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIGlucHV0IHRvICd1bml0LW11c3QtYmUtYnl0ZXMnIGVycm9yLmApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgVGhlICd1bml0JyBwb3J0aW9uIG9mIHRoZSBSYW5nZSBoZWFkZXIgbXVzdCBiZSBzZXQgdG8gJ2J5dGVzJy4gVGhlIFJhbmdlIGhlYWRlciBwcm92aWRlZCB3YXMgXCIke25vcm1hbGl6ZWRSYW5nZUhlYWRlcn1cImA7XG4gICAgfSxcbiAgICBcInNpbmdsZS1yYW5nZS1vbmx5XCI6ICh7IG5vcm1hbGl6ZWRSYW5nZUhlYWRlciB9KT0+e1xuICAgICAgICBpZiAoIW5vcm1hbGl6ZWRSYW5nZUhlYWRlcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIGlucHV0IHRvICdzaW5nbGUtcmFuZ2Utb25seScgZXJyb3IuYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGBNdWx0aXBsZSByYW5nZXMgYXJlIG5vdCBzdXBwb3J0ZWQuIFBsZWFzZSB1c2UgYSAgc2luZ2xlIHN0YXJ0IHZhbHVlLCBhbmQgb3B0aW9uYWwgZW5kIHZhbHVlLiBUaGUgUmFuZ2UgaGVhZGVyIHByb3ZpZGVkIHdhcyBcIiR7bm9ybWFsaXplZFJhbmdlSGVhZGVyfVwiYDtcbiAgICB9LFxuICAgIFwiaW52YWxpZC1yYW5nZS12YWx1ZXNcIjogKHsgbm9ybWFsaXplZFJhbmdlSGVhZGVyIH0pPT57XG4gICAgICAgIGlmICghbm9ybWFsaXplZFJhbmdlSGVhZGVyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgaW5wdXQgdG8gJ2ludmFsaWQtcmFuZ2UtdmFsdWVzJyBlcnJvci5gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYFRoZSBSYW5nZSBoZWFkZXIgaXMgbWlzc2luZyBib3RoIHN0YXJ0IGFuZCBlbmQgdmFsdWVzLiBBdCBsZWFzdCBvbmUgb2YgdGhvc2UgdmFsdWVzIGlzIG5lZWRlZC4gVGhlIFJhbmdlIGhlYWRlciBwcm92aWRlZCB3YXMgXCIke25vcm1hbGl6ZWRSYW5nZUhlYWRlcn1cImA7XG4gICAgfSxcbiAgICBcIm5vLXJhbmdlLWhlYWRlclwiOiAoKT0+e1xuICAgICAgICByZXR1cm4gXCJObyBSYW5nZSBoZWFkZXIgd2FzIGZvdW5kIGluIHRoZSBSZXF1ZXN0IHByb3ZpZGVkLlwiO1xuICAgIH0sXG4gICAgXCJyYW5nZS1ub3Qtc2F0aXNmaWFibGVcIjogKHsgc2l6ZSwgc3RhcnQsIGVuZCB9KT0+e1xuICAgICAgICByZXR1cm4gYFRoZSBzdGFydCAoJHtzdGFydH0pIGFuZCBlbmQgKCR7ZW5kfSkgdmFsdWVzIGluIHRoZSBSYW5nZSBhcmUgYCArIGBub3Qgc2F0aXNmaWFibGUgYnkgdGhlIGNhY2hlZCByZXNwb25zZSwgd2hpY2ggaXMgJHtzaXplfSBieXRlcy5gO1xuICAgIH0sXG4gICAgXCJhdHRlbXB0LXRvLWNhY2hlLW5vbi1nZXQtcmVxdWVzdFwiOiAoeyB1cmwsIG1ldGhvZCB9KT0+e1xuICAgICAgICByZXR1cm4gYFVuYWJsZSB0byBjYWNoZSAnJHt1cmx9JyBiZWNhdXNlIGl0IGlzIGEgJyR7bWV0aG9kfScgcmVxdWVzdCBhbmQgb25seSAnR0VUJyByZXF1ZXN0cyBjYW4gYmUgY2FjaGVkLmA7XG4gICAgfSxcbiAgICBcImNhY2hlLXB1dC13aXRoLW5vLXJlc3BvbnNlXCI6ICh7IHVybCB9KT0+e1xuICAgICAgICByZXR1cm4gYFRoZXJlIHdhcyBhbiBhdHRlbXB0IHRvIGNhY2hlICcke3VybH0nIGJ1dCB0aGUgcmVzcG9uc2Ugd2FzIG5vdCBkZWZpbmVkLmA7XG4gICAgfSxcbiAgICBcIm5vLXJlc3BvbnNlXCI6ICh7IHVybCwgZXJyb3IgfSk9PntcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSBgVGhlIHN0cmF0ZWd5IGNvdWxkIG5vdCBnZW5lcmF0ZSBhIHJlc3BvbnNlIGZvciAnJHt1cmx9Jy5gO1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgKz0gYCBUaGUgdW5kZXJseWluZyBlcnJvciBpcyAke2Vycm9yfS5gO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH0sXG4gICAgXCJiYWQtcHJlY2FjaGluZy1yZXNwb25zZVwiOiAoeyB1cmwsIHN0YXR1cyB9KT0+e1xuICAgICAgICByZXR1cm4gYFRoZSBwcmVjYWNoaW5nIHJlcXVlc3QgZm9yICcke3VybH0nIGZhaWxlZCR7c3RhdHVzID8gYCB3aXRoIGFuIEhUVFAgc3RhdHVzIG9mICR7c3RhdHVzfS5gIDogXCIuXCJ9YDtcbiAgICB9LFxuICAgIFwibm9uLXByZWNhY2hlZC11cmxcIjogKHsgdXJsIH0pPT57XG4gICAgICAgIHJldHVybiBgJ2NyZWF0ZUhhbmRsZXJCb3VuZFRvVVJMKFwiJHt1cmx9XCIpJyB3YXMgY2FsbGVkLCBidXQgdGhhdCBVUkwgaXMgbm90IHByZWNhY2hlZC4gUGxlYXNlIHBhc3MgaW4gYSBVUkwgdGhhdCBpcyBwcmVjYWNoZWQgaW5zdGVhZC5gO1xuICAgIH0sXG4gICAgXCJhZGQtdG8tY2FjaGUtbGlzdC1jb25mbGljdGluZy1pbnRlZ3JpdGllc1wiOiAoeyB1cmwgfSk9PntcbiAgICAgICAgcmV0dXJuIGBUd28gb2YgdGhlIGVudHJpZXMgcGFzc2VkIHRvICdzZXJ3aXN0LlNlcndpc3QuYWRkVG9QcmVjYWNoZUxpc3QoKScgaGFkIHRoZSBVUkwgJHt1cmx9IHdpdGggZGlmZmVyZW50IGludGVncml0eSB2YWx1ZXMuIFBsZWFzZSByZW1vdmUgb25lIG9mIHRoZW0uYDtcbiAgICB9LFxuICAgIFwibWlzc2luZy1wcmVjYWNoZS1lbnRyeVwiOiAoeyBjYWNoZU5hbWUsIHVybCB9KT0+e1xuICAgICAgICByZXR1cm4gYFVuYWJsZSB0byBmaW5kIGEgcHJlY2FjaGVkIHJlc3BvbnNlIGluICR7Y2FjaGVOYW1lfSBmb3IgJHt1cmx9LmA7XG4gICAgfSxcbiAgICBcImNyb3NzLW9yaWdpbi1jb3B5LXJlc3BvbnNlXCI6ICh7IG9yaWdpbiB9KT0+e1xuICAgICAgICByZXR1cm4gYCdAc2Vyd2lzdC9jb3JlLmNvcHlSZXNwb25zZSgpJyBjYW4gb25seSBiZSB1c2VkIHdpdGggc2FtZS1vcmlnaW4gcmVzcG9uc2VzLiBJdCB3YXMgcGFzc2VkIGEgcmVzcG9uc2Ugd2l0aCBvcmlnaW4gJHtvcmlnaW59LmA7XG4gICAgfSxcbiAgICBcIm9wYXF1ZS1zdHJlYW1zLXNvdXJjZVwiOiAoeyB0eXBlIH0pPT57XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBgT25lIG9mIHRoZSAnQHNlcndpc3Qvc3RyZWFtcycgc291cmNlcyByZXN1bHRlZCBpbiBhbiAnJHt0eXBlfScgcmVzcG9uc2UuYDtcbiAgICAgICAgaWYgKHR5cGUgPT09IFwib3BhcXVlcmVkaXJlY3RcIikge1xuICAgICAgICAgICAgcmV0dXJuIGAke21lc3NhZ2V9IFBsZWFzZSBkbyBub3QgdXNlIGEgbmF2aWdhdGlvbiByZXF1ZXN0IHRoYXQgcmVzdWx0cyBpbiBhIHJlZGlyZWN0IGFzIGEgc291cmNlLmA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGAke21lc3NhZ2V9IFBsZWFzZSBlbnN1cmUgeW91ciBzb3VyY2VzIGFyZSBDT1JTLWVuYWJsZWQuYDtcbiAgICB9XG59O1xuXG5jb25zdCBmYWxsYmFjayA9IChjb2RlLCAuLi5hcmdzKT0+e1xuICAgIGxldCBtc2cgPSBjb2RlO1xuICAgIGlmIChhcmdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbXNnICs9IGAgOjogJHtKU09OLnN0cmluZ2lmeShhcmdzKX1gO1xuICAgIH1cbiAgICByZXR1cm4gbXNnO1xufTtcbmNvbnN0IGdlbmVyYXRvckZ1bmN0aW9uID0gKGNvZGUsIGRldGFpbHMgPSB7fSk9PntcbiAgICBjb25zdCBtZXNzYWdlID0gbWVzc2FnZXNbY29kZV07XG4gICAgaWYgKCFtZXNzYWdlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGZpbmQgbWVzc2FnZSBmb3IgY29kZSAnJHtjb2RlfScuYCk7XG4gICAgfVxuICAgIHJldHVybiBtZXNzYWdlKGRldGFpbHMpO1xufTtcbmNvbnN0IG1lc3NhZ2VHZW5lcmF0b3IgPSBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJwcm9kdWN0aW9uXCIgPyBmYWxsYmFjayA6IGdlbmVyYXRvckZ1bmN0aW9uO1xuXG5jbGFzcyBTZXJ3aXN0RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgZGV0YWlscztcbiAgICBjb25zdHJ1Y3RvcihlcnJvckNvZGUsIGRldGFpbHMpe1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gbWVzc2FnZUdlbmVyYXRvcihlcnJvckNvZGUsIGRldGFpbHMpO1xuICAgICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICAgICAgdGhpcy5uYW1lID0gZXJyb3JDb2RlO1xuICAgICAgICB0aGlzLmRldGFpbHMgPSBkZXRhaWxzO1xuICAgIH1cbn1cblxuY29uc3QgaXNBcnJheSA9ICh2YWx1ZSwgZGV0YWlscyk9PntcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJub3QtYW4tYXJyYXlcIiwgZGV0YWlscyk7XG4gICAgfVxufTtcbmNvbnN0IGhhc01ldGhvZCA9IChvYmplY3QsIGV4cGVjdGVkTWV0aG9kLCBkZXRhaWxzKT0+e1xuICAgIGNvbnN0IHR5cGUgPSB0eXBlb2Ygb2JqZWN0W2V4cGVjdGVkTWV0aG9kXTtcbiAgICBpZiAodHlwZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGRldGFpbHMuZXhwZWN0ZWRNZXRob2QgPSBleHBlY3RlZE1ldGhvZDtcbiAgICAgICAgdGhyb3cgbmV3IFNlcndpc3RFcnJvcihcIm1pc3NpbmctYS1tZXRob2RcIiwgZGV0YWlscyk7XG4gICAgfVxufTtcbmNvbnN0IGlzVHlwZSA9IChvYmplY3QsIGV4cGVjdGVkVHlwZSwgZGV0YWlscyk9PntcbiAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gZXhwZWN0ZWRUeXBlKSB7XG4gICAgICAgIGRldGFpbHMuZXhwZWN0ZWRUeXBlID0gZXhwZWN0ZWRUeXBlO1xuICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiaW5jb3JyZWN0LXR5cGVcIiwgZGV0YWlscyk7XG4gICAgfVxufTtcbmNvbnN0IGlzSW5zdGFuY2UgPSAob2JqZWN0LCBleHBlY3RlZENsYXNzLCBkZXRhaWxzKT0+e1xuICAgIGlmICghKG9iamVjdCBpbnN0YW5jZW9mIGV4cGVjdGVkQ2xhc3MpKSB7XG4gICAgICAgIGRldGFpbHMuZXhwZWN0ZWRDbGFzc05hbWUgPSBleHBlY3RlZENsYXNzLm5hbWU7XG4gICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJpbmNvcnJlY3QtY2xhc3NcIiwgZGV0YWlscyk7XG4gICAgfVxufTtcbmNvbnN0IGlzT25lT2YgPSAodmFsdWUsIHZhbGlkVmFsdWVzLCBkZXRhaWxzKT0+e1xuICAgIGlmICghdmFsaWRWYWx1ZXMuaW5jbHVkZXModmFsdWUpKSB7XG4gICAgICAgIGRldGFpbHMudmFsaWRWYWx1ZURlc2NyaXB0aW9uID0gYFZhbGlkIHZhbHVlcyBhcmUgJHtKU09OLnN0cmluZ2lmeSh2YWxpZFZhbHVlcyl9LmA7XG4gICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJpbnZhbGlkLXZhbHVlXCIsIGRldGFpbHMpO1xuICAgIH1cbn07XG5jb25zdCBpc0FycmF5T2ZDbGFzcyA9ICh2YWx1ZSwgZXhwZWN0ZWRDbGFzcywgZGV0YWlscyk9PntcbiAgICBjb25zdCBlcnJvciA9IG5ldyBTZXJ3aXN0RXJyb3IoXCJub3QtYXJyYXktb2YtY2xhc3NcIiwgZGV0YWlscyk7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIHZhbHVlKXtcbiAgICAgICAgaWYgKCEoaXRlbSBpbnN0YW5jZW9mIGV4cGVjdGVkQ2xhc3MpKSB7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cbn07XG5jb25zdCBmaW5hbEFzc2VydEV4cG9ydHMgPSBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJwcm9kdWN0aW9uXCIgPyBudWxsIDoge1xuICAgIGhhc01ldGhvZCxcbiAgICBpc0FycmF5LFxuICAgIGlzSW5zdGFuY2UsXG4gICAgaXNPbmVPZixcbiAgICBpc1R5cGUsXG4gICAgaXNBcnJheU9mQ2xhc3Ncbn07XG5cbmNvbnN0IGdldEZyaWVuZGx5VVJMID0gKHVybCk9PntcbiAgICBjb25zdCB1cmxPYmogPSBuZXcgVVJMKFN0cmluZyh1cmwpLCBsb2NhdGlvbi5ocmVmKTtcbiAgICByZXR1cm4gdXJsT2JqLmhyZWYucmVwbGFjZShuZXcgUmVnRXhwKGBeJHtsb2NhdGlvbi5vcmlnaW59YCksIFwiXCIpO1xufTtcblxuY29uc3QgbG9nZ2VyID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwicHJvZHVjdGlvblwiIHx8IHR5cGVvZiBzZWxmID09PSBcInVuZGVmaW5lZFwiID8gbnVsbCA6ICgoKT0+e1xuICAgIGlmICghKFwiX19XQl9ESVNBQkxFX0RFVl9MT0dTXCIgaW4gZ2xvYmFsVGhpcykpIHtcbiAgICAgICAgc2VsZi5fX1dCX0RJU0FCTEVfREVWX0xPR1MgPSBmYWxzZTtcbiAgICB9XG4gICAgbGV0IGluR3JvdXAgPSBmYWxzZTtcbiAgICBjb25zdCBtZXRob2RUb0NvbG9yTWFwID0ge1xuICAgICAgICBkZWJ1ZzogXCIjN2Y4YzhkXCIsXG4gICAgICAgIGxvZzogXCIjMmVjYzcxXCIsXG4gICAgICAgIHdhcm46IFwiI2YzOWMxMlwiLFxuICAgICAgICBlcnJvcjogXCIjYzAzOTJiXCIsXG4gICAgICAgIGdyb3VwQ29sbGFwc2VkOiBcIiMzNDk4ZGJcIixcbiAgICAgICAgZ3JvdXBFbmQ6IG51bGxcbiAgICB9O1xuICAgIGNvbnN0IHByaW50ID0gKG1ldGhvZCwgYXJncyk9PntcbiAgICAgICAgaWYgKHNlbGYuX19XQl9ESVNBQkxFX0RFVl9MT0dTKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1ldGhvZCA9PT0gXCJncm91cENvbGxhcHNlZFwiKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gXCJ1bmRlZmluZWRcIiAmJiAvXigoPyFjaHJvbWV8YW5kcm9pZCkuKSpzYWZhcmkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZVttZXRob2RdKC4uLmFyZ3MpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdHlsZXMgPSBbXG4gICAgICAgICAgICBgYmFja2dyb3VuZDogJHttZXRob2RUb0NvbG9yTWFwW21ldGhvZF19YCxcbiAgICAgICAgICAgIFwiYm9yZGVyLXJhZGl1czogMC41ZW1cIixcbiAgICAgICAgICAgIFwiY29sb3I6IHdoaXRlXCIsXG4gICAgICAgICAgICBcImZvbnQtd2VpZ2h0OiBib2xkXCIsXG4gICAgICAgICAgICBcInBhZGRpbmc6IDJweCAwLjVlbVwiXG4gICAgICAgIF07XG4gICAgICAgIGNvbnN0IGxvZ1ByZWZpeCA9IGluR3JvdXAgPyBbXSA6IFtcbiAgICAgICAgICAgIFwiJWNzZXJ3aXN0XCIsXG4gICAgICAgICAgICBzdHlsZXMuam9pbihcIjtcIilcbiAgICAgICAgXTtcbiAgICAgICAgY29uc29sZVttZXRob2RdKC4uLmxvZ1ByZWZpeCwgLi4uYXJncyk7XG4gICAgICAgIGlmIChtZXRob2QgPT09IFwiZ3JvdXBDb2xsYXBzZWRcIikge1xuICAgICAgICAgICAgaW5Hcm91cCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1ldGhvZCA9PT0gXCJncm91cEVuZFwiKSB7XG4gICAgICAgICAgICBpbkdyb3VwID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IGxvZ2dlck1ldGhvZHMgPSBPYmplY3Qua2V5cyhtZXRob2RUb0NvbG9yTWFwKTtcbiAgICByZXR1cm4gbG9nZ2VyTWV0aG9kcy5yZWR1Y2UoKGFwaSwgbWV0aG9kKT0+e1xuICAgICAgICBhcGlbbWV0aG9kXSA9ICguLi5hcmdzKT0+e1xuICAgICAgICAgICAgcHJpbnQobWV0aG9kLCBhcmdzKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGFwaTtcbiAgICB9LCB7fSk7XG59KSgpO1xuXG5mdW5jdGlvbiB0aW1lb3V0KG1zKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKT0+c2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xufVxuXG5jb25zdCBxdW90YUVycm9yQ2FsbGJhY2tzID0gbmV3IFNldCgpO1xuXG5mdW5jdGlvbiBzdHJpcFBhcmFtcyhmdWxsVVJMLCBpZ25vcmVQYXJhbXMpIHtcbiAgICBjb25zdCBzdHJpcHBlZFVSTCA9IG5ldyBVUkwoZnVsbFVSTCk7XG4gICAgZm9yIChjb25zdCBwYXJhbSBvZiBpZ25vcmVQYXJhbXMpe1xuICAgICAgICBzdHJpcHBlZFVSTC5zZWFyY2hQYXJhbXMuZGVsZXRlKHBhcmFtKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0cmlwcGVkVVJMLmhyZWY7XG59XG5hc3luYyBmdW5jdGlvbiBjYWNoZU1hdGNoSWdub3JlUGFyYW1zKGNhY2hlLCByZXF1ZXN0LCBpZ25vcmVQYXJhbXMsIG1hdGNoT3B0aW9ucykge1xuICAgIGNvbnN0IHN0cmlwcGVkUmVxdWVzdFVSTCA9IHN0cmlwUGFyYW1zKHJlcXVlc3QudXJsLCBpZ25vcmVQYXJhbXMpO1xuICAgIGlmIChyZXF1ZXN0LnVybCA9PT0gc3RyaXBwZWRSZXF1ZXN0VVJMKSB7XG4gICAgICAgIHJldHVybiBjYWNoZS5tYXRjaChyZXF1ZXN0LCBtYXRjaE9wdGlvbnMpO1xuICAgIH1cbiAgICBjb25zdCBrZXlzT3B0aW9ucyA9IHtcbiAgICAgICAgLi4ubWF0Y2hPcHRpb25zLFxuICAgICAgICBpZ25vcmVTZWFyY2g6IHRydWVcbiAgICB9O1xuICAgIGNvbnN0IGNhY2hlS2V5cyA9IGF3YWl0IGNhY2hlLmtleXMocmVxdWVzdCwga2V5c09wdGlvbnMpO1xuICAgIGZvciAoY29uc3QgY2FjaGVLZXkgb2YgY2FjaGVLZXlzKXtcbiAgICAgICAgY29uc3Qgc3RyaXBwZWRDYWNoZUtleVVSTCA9IHN0cmlwUGFyYW1zKGNhY2hlS2V5LnVybCwgaWdub3JlUGFyYW1zKTtcbiAgICAgICAgaWYgKHN0cmlwcGVkUmVxdWVzdFVSTCA9PT0gc3RyaXBwZWRDYWNoZUtleVVSTCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhY2hlLm1hdGNoKGNhY2hlS2V5LCBtYXRjaE9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybjtcbn1cblxuY2xhc3MgRGVmZXJyZWQge1xuICAgIHByb21pc2U7XG4gICAgcmVzb2x2ZTtcbiAgICByZWplY3Q7XG4gICAgY29uc3RydWN0b3IoKXtcbiAgICAgICAgdGhpcy5wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCk9PntcbiAgICAgICAgICAgIHRoaXMucmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgICAgICB0aGlzLnJlamVjdCA9IHJlamVjdDtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5jb25zdCBleGVjdXRlUXVvdGFFcnJvckNhbGxiYWNrcyA9IGFzeW5jICgpPT57XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICBsb2dnZXIubG9nKGBBYm91dCB0byBydW4gJHtxdW90YUVycm9yQ2FsbGJhY2tzLnNpemV9IGNhbGxiYWNrcyB0byBjbGVhbiB1cCBjYWNoZXMuYCk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgY2FsbGJhY2sgb2YgcXVvdGFFcnJvckNhbGxiYWNrcyl7XG4gICAgICAgIGF3YWl0IGNhbGxiYWNrKCk7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGxvZ2dlci5sb2coY2FsbGJhY2ssIFwiaXMgY29tcGxldGUuXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgbG9nZ2VyLmxvZyhcIkZpbmlzaGVkIHJ1bm5pbmcgY2FsbGJhY2tzLlwiKTtcbiAgICB9XG59O1xuXG5jb25zdCBTVUJTVFJJTkdfVE9fRklORCA9IFwiLXByZWNhY2hlLVwiO1xuY29uc3QgZGVsZXRlT3V0ZGF0ZWRDYWNoZXMgPSBhc3luYyAoY3VycmVudFByZWNhY2hlTmFtZSwgc3Vic3RyaW5nVG9GaW5kID0gU1VCU1RSSU5HX1RPX0ZJTkQpPT57XG4gICAgY29uc3QgY2FjaGVOYW1lcyA9IGF3YWl0IHNlbGYuY2FjaGVzLmtleXMoKTtcbiAgICBjb25zdCBjYWNoZU5hbWVzVG9EZWxldGUgPSBjYWNoZU5hbWVzLmZpbHRlcigoY2FjaGVOYW1lKT0+e1xuICAgICAgICByZXR1cm4gY2FjaGVOYW1lLmluY2x1ZGVzKHN1YnN0cmluZ1RvRmluZCkgJiYgY2FjaGVOYW1lLmluY2x1ZGVzKHNlbGYucmVnaXN0cmF0aW9uLnNjb3BlKSAmJiBjYWNoZU5hbWUgIT09IGN1cnJlbnRQcmVjYWNoZU5hbWU7XG4gICAgfSk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoY2FjaGVOYW1lc1RvRGVsZXRlLm1hcCgoY2FjaGVOYW1lKT0+c2VsZi5jYWNoZXMuZGVsZXRlKGNhY2hlTmFtZSkpKTtcbiAgICByZXR1cm4gY2FjaGVOYW1lc1RvRGVsZXRlO1xufTtcblxuY29uc3QgY2xlYW51cE91dGRhdGVkQ2FjaGVzID0gKGNhY2hlTmFtZSk9PntcbiAgICBzZWxmLmFkZEV2ZW50TGlzdGVuZXIoXCJhY3RpdmF0ZVwiLCAoZXZlbnQpPT57XG4gICAgICAgIGV2ZW50LndhaXRVbnRpbChkZWxldGVPdXRkYXRlZENhY2hlcyhjYWNoZU5hbWVzLmdldFByZWNhY2hlTmFtZShjYWNoZU5hbWUpKS50aGVuKChjYWNoZXNEZWxldGVkKT0+e1xuICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGlmIChjYWNoZXNEZWxldGVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhcIlRoZSBmb2xsb3dpbmcgb3V0LW9mLWRhdGUgcHJlY2FjaGVzIHdlcmUgY2xlYW5lZCB1cCBhdXRvbWF0aWNhbGx5OlwiLCBjYWNoZXNEZWxldGVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbiAgICB9KTtcbn07XG5cbmNvbnN0IGNsaWVudHNDbGFpbSA9ICgpPT57XG4gICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKFwiYWN0aXZhdGVcIiwgKCk9PnNlbGYuY2xpZW50cy5jbGFpbSgpKTtcbn07XG5cbmNvbnN0IHdhaXRVbnRpbCA9IChldmVudCwgYXN5bmNGbik9PntcbiAgICBjb25zdCByZXR1cm5Qcm9taXNlID0gYXN5bmNGbigpO1xuICAgIGV2ZW50LndhaXRVbnRpbChyZXR1cm5Qcm9taXNlKTtcbiAgICByZXR1cm4gcmV0dXJuUHJvbWlzZTtcbn07XG5cbmV4cG9ydCB7IERlZmVycmVkIGFzIEQsIFNlcndpc3RFcnJvciBhcyBTLCBjbGllbnRzQ2xhaW0gYXMgYSwgY2xlYW51cE91dGRhdGVkQ2FjaGVzIGFzIGIsIGNhY2hlTmFtZXMgYXMgYywgY2FuQ29uc3RydWN0UmVzcG9uc2VGcm9tQm9keVN0cmVhbSBhcyBkLCBjYWNoZU1hdGNoSWdub3JlUGFyYW1zIGFzIGUsIGZpbmFsQXNzZXJ0RXhwb3J0cyBhcyBmLCBnZXRGcmllbmRseVVSTCBhcyBnLCBleGVjdXRlUXVvdGFFcnJvckNhbGxiYWNrcyBhcyBoLCBsb2dnZXIgYXMgbCwgcXVvdGFFcnJvckNhbGxiYWNrcyBhcyBxLCB0aW1lb3V0IGFzIHQsIHdhaXRVbnRpbCBhcyB3IH07XG4iXSwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbMF0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/serwist/dist/chunks/waitUntil.js\n")); - -/***/ }), - -/***/ "./node_modules/serwist/dist/index.js": -/*!********************************************!*\ - !*** ./node_modules/serwist/dist/index.js ***! - \********************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ BROADCAST_UPDATE_DEFAULT_HEADERS: () => (/* binding */ BROADCAST_UPDATE_DEFAULT_HEADERS),\n/* harmony export */ BackgroundSyncPlugin: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.B),\n/* harmony export */ BackgroundSyncQueue: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.l),\n/* harmony export */ BackgroundSyncQueueStore: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.o),\n/* harmony export */ BroadcastCacheUpdate: () => (/* binding */ BroadcastCacheUpdate),\n/* harmony export */ BroadcastUpdatePlugin: () => (/* binding */ BroadcastUpdatePlugin),\n/* harmony export */ CacheExpiration: () => (/* binding */ CacheExpiration),\n/* harmony export */ CacheFirst: () => (/* binding */ CacheFirst),\n/* harmony export */ CacheOnly: () => (/* binding */ CacheOnly),\n/* harmony export */ CacheableResponse: () => (/* binding */ CacheableResponse),\n/* harmony export */ CacheableResponsePlugin: () => (/* binding */ CacheableResponsePlugin),\n/* harmony export */ ExpirationPlugin: () => (/* binding */ ExpirationPlugin),\n/* harmony export */ NavigationRoute: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.b),\n/* harmony export */ NetworkFirst: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.N),\n/* harmony export */ NetworkOnly: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.a),\n/* harmony export */ PrecacheFallbackPlugin: () => (/* binding */ PrecacheFallbackPlugin),\n/* harmony export */ PrecacheRoute: () => (/* binding */ PrecacheRoute),\n/* harmony export */ PrecacheStrategy: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.P),\n/* harmony export */ RangeRequestsPlugin: () => (/* binding */ RangeRequestsPlugin),\n/* harmony export */ RegExpRoute: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.q),\n/* harmony export */ Route: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.R),\n/* harmony export */ Serwist: () => (/* binding */ Serwist),\n/* harmony export */ StaleWhileRevalidate: () => (/* binding */ StaleWhileRevalidate),\n/* harmony export */ StorableRequest: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.r),\n/* harmony export */ Strategy: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.S),\n/* harmony export */ StrategyHandler: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.t),\n/* harmony export */ cacheNames: () => (/* binding */ cacheNames),\n/* harmony export */ copyResponse: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.u),\n/* harmony export */ createPartialResponse: () => (/* binding */ createPartialResponse),\n/* harmony export */ disableDevLogs: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.d),\n/* harmony export */ disableNavigationPreload: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.v),\n/* harmony export */ enableNavigationPreload: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.e),\n/* harmony export */ initializeGoogleAnalytics: () => (/* binding */ initializeGoogleAnalytics),\n/* harmony export */ isNavigationPreloadSupported: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.w),\n/* harmony export */ registerQuotaErrorCallback: () => (/* binding */ registerQuotaErrorCallback),\n/* harmony export */ responsesAreSame: () => (/* binding */ responsesAreSame),\n/* harmony export */ setCacheNameDetails: () => (/* reexport safe */ _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.s)\n/* harmony export */ });\n/* harmony import */ var _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./chunks/waitUntil.js */ \"./node_modules/serwist/dist/chunks/waitUntil.js\");\n/* harmony import */ var _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./chunks/printInstallDetails.js */ \"./node_modules/serwist/dist/chunks/printInstallDetails.js\");\n/* harmony import */ var _chunks_resultingClientExists_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./chunks/resultingClientExists.js */ \"./node_modules/serwist/dist/chunks/resultingClientExists.js\");\n/* harmony import */ var idb__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! idb */ \"./node_modules/idb/build/index.js\");\n/* harmony import */ var _serwist_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @serwist/utils */ \"./node_modules/@serwist/utils/dist/index.js\");\n\n\n\n\n\n\n\nconst cacheNames = {\n get googleAnalytics () {\n return _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.c.getGoogleAnalyticsName();\n },\n get precache () {\n return _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.c.getPrecacheName();\n },\n get prefix () {\n return _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.c.getPrefix();\n },\n get runtime () {\n return _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.c.getRuntimeName();\n },\n get suffix () {\n return _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.c.getSuffix();\n }\n};\n\nconst BROADCAST_UPDATE_MESSAGE_TYPE = \"CACHE_UPDATED\";\nconst BROADCAST_UPDATE_MESSAGE_META = \"serwist-broadcast-update\";\nconst BROADCAST_UPDATE_DEFAULT_NOTIFY = true;\nconst BROADCAST_UPDATE_DEFAULT_HEADERS = [\n \"content-length\",\n \"etag\",\n \"last-modified\"\n];\n\nconst responsesAreSame = (firstResponse, secondResponse, headersToCheck)=>{\n if (true) {\n if (!(firstResponse instanceof Response && secondResponse instanceof Response)) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"invalid-responses-are-same-args\");\n }\n }\n const atLeastOneHeaderAvailable = headersToCheck.some((header)=>{\n return firstResponse.headers.has(header) && secondResponse.headers.has(header);\n });\n if (!atLeastOneHeaderAvailable) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.warn(\"Unable to determine where the response has been updated because none of the headers that would be checked are present.\");\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(\"Attempting to compare the following: \", firstResponse, secondResponse, headersToCheck);\n }\n return true;\n }\n return headersToCheck.every((header)=>{\n const headerStateComparison = firstResponse.headers.has(header) === secondResponse.headers.has(header);\n const headerValueComparison = firstResponse.headers.get(header) === secondResponse.headers.get(header);\n return headerStateComparison && headerValueComparison;\n });\n};\n\nconst isSafari = typeof navigator !== \"undefined\" && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\nconst defaultPayloadGenerator = (data)=>{\n return {\n cacheName: data.cacheName,\n updatedURL: data.request.url\n };\n};\nclass BroadcastCacheUpdate {\n _headersToCheck;\n _generatePayload;\n _notifyAllClients;\n constructor({ generatePayload, headersToCheck, notifyAllClients } = {}){\n this._headersToCheck = headersToCheck || BROADCAST_UPDATE_DEFAULT_HEADERS;\n this._generatePayload = generatePayload || defaultPayloadGenerator;\n this._notifyAllClients = notifyAllClients ?? BROADCAST_UPDATE_DEFAULT_NOTIFY;\n }\n async notifyIfUpdated(options) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(options.cacheName, \"string\", {\n moduleName: \"serwist\",\n className: \"BroadcastCacheUpdate\",\n funcName: \"notifyIfUpdated\",\n paramName: \"cacheName\"\n });\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(options.newResponse, Response, {\n moduleName: \"serwist\",\n className: \"BroadcastCacheUpdate\",\n funcName: \"notifyIfUpdated\",\n paramName: \"newResponse\"\n });\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(options.request, Request, {\n moduleName: \"serwist\",\n className: \"BroadcastCacheUpdate\",\n funcName: \"notifyIfUpdated\",\n paramName: \"request\"\n });\n }\n if (!options.oldResponse) {\n return;\n }\n if (!responsesAreSame(options.oldResponse, options.newResponse, this._headersToCheck)) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(\"Newer response found (and cached) for:\", options.request.url);\n }\n const messageData = {\n type: BROADCAST_UPDATE_MESSAGE_TYPE,\n meta: BROADCAST_UPDATE_MESSAGE_META,\n payload: this._generatePayload(options)\n };\n if (options.request.mode === \"navigate\") {\n let resultingClientId;\n if (options.event instanceof FetchEvent) {\n resultingClientId = options.event.resultingClientId;\n }\n const resultingWin = await (0,_chunks_resultingClientExists_js__WEBPACK_IMPORTED_MODULE_2__.r)(resultingClientId);\n if (!resultingWin || isSafari) {\n await (0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.t)(3500);\n }\n }\n if (this._notifyAllClients) {\n const windows = await self.clients.matchAll({\n type: \"window\"\n });\n for (const win of windows){\n win.postMessage(messageData);\n }\n } else {\n if (options.event instanceof FetchEvent) {\n const client = await self.clients.get(options.event.clientId);\n client?.postMessage(messageData);\n }\n }\n }\n }\n}\n\nclass BroadcastUpdatePlugin {\n _broadcastUpdate;\n constructor(options){\n this._broadcastUpdate = new BroadcastCacheUpdate(options);\n }\n cacheDidUpdate(options) {\n void this._broadcastUpdate.notifyIfUpdated(options);\n }\n}\n\nclass CacheableResponse {\n _statuses;\n _headers;\n constructor(config = {}){\n if (true) {\n if (!(config.statuses || config.headers)) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"statuses-or-headers-required\", {\n moduleName: \"serwist\",\n className: \"CacheableResponse\",\n funcName: \"constructor\"\n });\n }\n if (config.statuses) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isArray(config.statuses, {\n moduleName: \"serwist\",\n className: \"CacheableResponse\",\n funcName: \"constructor\",\n paramName: \"config.statuses\"\n });\n }\n if (config.headers) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(config.headers, \"object\", {\n moduleName: \"serwist\",\n className: \"CacheableResponse\",\n funcName: \"constructor\",\n paramName: \"config.headers\"\n });\n }\n }\n this._statuses = config.statuses;\n if (config.headers) {\n this._headers = new Headers(config.headers);\n }\n }\n isResponseCacheable(response) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(response, Response, {\n moduleName: \"serwist\",\n className: \"CacheableResponse\",\n funcName: \"isResponseCacheable\",\n paramName: \"response\"\n });\n }\n let cacheable = true;\n if (this._statuses) {\n cacheable = this._statuses.includes(response.status);\n }\n if (this._headers && cacheable) {\n for (const [headerName, headerValue] of this._headers.entries()){\n if (response.headers.get(headerName) !== headerValue) {\n cacheable = false;\n break;\n }\n }\n }\n if (true) {\n if (!cacheable) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(`The request for '${(0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(response.url)}' returned a response that does not meet the criteria for being cached.`);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(\"View cacheability criteria here.\");\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Cacheable statuses: ${JSON.stringify(this._statuses)}`);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Cacheable headers: ${JSON.stringify(this._headers, null, 2)}`);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n const logFriendlyHeaders = {};\n response.headers.forEach((value, key)=>{\n logFriendlyHeaders[key] = value;\n });\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(\"View response status and headers here.\");\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Response status: ${response.status}`);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Response headers: ${JSON.stringify(logFriendlyHeaders, null, 2)}`);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(\"View full response details here.\");\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(response.headers);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(response);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n }\n return cacheable;\n }\n}\n\nclass CacheableResponsePlugin {\n _cacheableResponse;\n constructor(config){\n this._cacheableResponse = new CacheableResponse(config);\n }\n cacheWillUpdate = async ({ response })=>{\n if (this._cacheableResponse.isResponseCacheable(response)) {\n return response;\n }\n return null;\n };\n}\n\nconst DB_NAME = \"serwist-expiration\";\nconst CACHE_OBJECT_STORE = \"cache-entries\";\nconst normalizeURL = (unNormalizedUrl)=>{\n const url = new URL(unNormalizedUrl, location.href);\n url.hash = \"\";\n return url.href;\n};\nclass CacheTimestampsModel {\n _cacheName;\n _db = null;\n constructor(cacheName){\n this._cacheName = cacheName;\n }\n _getId(url) {\n return `${this._cacheName}|${normalizeURL(url)}`;\n }\n _upgradeDb(db) {\n const objStore = db.createObjectStore(CACHE_OBJECT_STORE, {\n keyPath: \"id\"\n });\n objStore.createIndex(\"cacheName\", \"cacheName\", {\n unique: false\n });\n objStore.createIndex(\"timestamp\", \"timestamp\", {\n unique: false\n });\n }\n _upgradeDbAndDeleteOldDbs(db) {\n this._upgradeDb(db);\n if (this._cacheName) {\n void (0,idb__WEBPACK_IMPORTED_MODULE_3__.deleteDB)(this._cacheName);\n }\n }\n async setTimestamp(url, timestamp) {\n url = normalizeURL(url);\n const entry = {\n id: this._getId(url),\n cacheName: this._cacheName,\n url,\n timestamp\n };\n const db = await this.getDb();\n const tx = db.transaction(CACHE_OBJECT_STORE, \"readwrite\", {\n durability: \"relaxed\"\n });\n await tx.store.put(entry);\n await tx.done;\n }\n async getTimestamp(url) {\n const db = await this.getDb();\n const entry = await db.get(CACHE_OBJECT_STORE, this._getId(url));\n return entry?.timestamp;\n }\n async expireEntries(minTimestamp, maxCount) {\n const db = await this.getDb();\n let cursor = await db.transaction(CACHE_OBJECT_STORE, \"readwrite\").store.index(\"timestamp\").openCursor(null, \"prev\");\n const urlsDeleted = [];\n let entriesNotDeletedCount = 0;\n while(cursor){\n const result = cursor.value;\n if (result.cacheName === this._cacheName) {\n if (minTimestamp && result.timestamp < minTimestamp || maxCount && entriesNotDeletedCount >= maxCount) {\n cursor.delete();\n urlsDeleted.push(result.url);\n } else {\n entriesNotDeletedCount++;\n }\n }\n cursor = await cursor.continue();\n }\n return urlsDeleted;\n }\n async getDb() {\n if (!this._db) {\n this._db = await (0,idb__WEBPACK_IMPORTED_MODULE_3__.openDB)(DB_NAME, 1, {\n upgrade: this._upgradeDbAndDeleteOldDbs.bind(this)\n });\n }\n return this._db;\n }\n}\n\nclass CacheExpiration {\n _isRunning = false;\n _rerunRequested = false;\n _maxEntries;\n _maxAgeSeconds;\n _matchOptions;\n _cacheName;\n _timestampModel;\n constructor(cacheName, config = {}){\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(cacheName, \"string\", {\n moduleName: \"serwist\",\n className: \"CacheExpiration\",\n funcName: \"constructor\",\n paramName: \"cacheName\"\n });\n if (!(config.maxEntries || config.maxAgeSeconds)) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"max-entries-or-age-required\", {\n moduleName: \"serwist\",\n className: \"CacheExpiration\",\n funcName: \"constructor\"\n });\n }\n if (config.maxEntries) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(config.maxEntries, \"number\", {\n moduleName: \"serwist\",\n className: \"CacheExpiration\",\n funcName: \"constructor\",\n paramName: \"config.maxEntries\"\n });\n }\n if (config.maxAgeSeconds) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(config.maxAgeSeconds, \"number\", {\n moduleName: \"serwist\",\n className: \"CacheExpiration\",\n funcName: \"constructor\",\n paramName: \"config.maxAgeSeconds\"\n });\n }\n }\n this._maxEntries = config.maxEntries;\n this._maxAgeSeconds = config.maxAgeSeconds;\n this._matchOptions = config.matchOptions;\n this._cacheName = cacheName;\n this._timestampModel = new CacheTimestampsModel(cacheName);\n }\n async expireEntries() {\n if (this._isRunning) {\n this._rerunRequested = true;\n return;\n }\n this._isRunning = true;\n const minTimestamp = this._maxAgeSeconds ? Date.now() - this._maxAgeSeconds * 1000 : 0;\n const urlsExpired = await this._timestampModel.expireEntries(minTimestamp, this._maxEntries);\n const cache = await self.caches.open(this._cacheName);\n for (const url of urlsExpired){\n await cache.delete(url, this._matchOptions);\n }\n if (true) {\n if (urlsExpired.length > 0) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(`Expired ${urlsExpired.length} ` + `${urlsExpired.length === 1 ? \"entry\" : \"entries\"} and removed ` + `${urlsExpired.length === 1 ? \"it\" : \"them\"} from the ` + `'${this._cacheName}' cache.`);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Expired the following ${urlsExpired.length === 1 ? \"URL\" : \"URLs\"}:`);\n for (const url of urlsExpired){\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(` ${url}`);\n }\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n } else {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(\"Cache expiration ran and found no entries to remove.\");\n }\n }\n this._isRunning = false;\n if (this._rerunRequested) {\n this._rerunRequested = false;\n void this.expireEntries();\n }\n }\n async updateTimestamp(url) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(url, \"string\", {\n moduleName: \"serwist\",\n className: \"CacheExpiration\",\n funcName: \"updateTimestamp\",\n paramName: \"url\"\n });\n }\n await this._timestampModel.setTimestamp(url, Date.now());\n }\n async isURLExpired(url) {\n if (!this._maxAgeSeconds) {\n if (true) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"expired-test-without-max-age\", {\n methodName: \"isURLExpired\",\n paramName: \"maxAgeSeconds\"\n });\n }\n return false;\n }\n const timestamp = await this._timestampModel.getTimestamp(url);\n const expireOlderThan = Date.now() - this._maxAgeSeconds * 1000;\n return timestamp !== undefined ? timestamp < expireOlderThan : true;\n }\n async delete() {\n this._rerunRequested = false;\n await this._timestampModel.expireEntries(Number.POSITIVE_INFINITY);\n }\n}\n\nconst registerQuotaErrorCallback = (callback)=>{\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(callback, \"function\", {\n moduleName: \"@serwist/core\",\n funcName: \"register\",\n paramName: \"callback\"\n });\n }\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.q.add(callback);\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(\"Registered a callback to respond to quota errors.\", callback);\n }\n};\n\nclass ExpirationPlugin {\n _config;\n _cacheExpirations;\n constructor(config = {}){\n if (true) {\n if (!(config.maxEntries || config.maxAgeSeconds)) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"max-entries-or-age-required\", {\n moduleName: \"serwist\",\n className: \"ExpirationPlugin\",\n funcName: \"constructor\"\n });\n }\n if (config.maxEntries) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(config.maxEntries, \"number\", {\n moduleName: \"serwist\",\n className: \"ExpirationPlugin\",\n funcName: \"constructor\",\n paramName: \"config.maxEntries\"\n });\n }\n if (config.maxAgeSeconds) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(config.maxAgeSeconds, \"number\", {\n moduleName: \"serwist\",\n className: \"ExpirationPlugin\",\n funcName: \"constructor\",\n paramName: \"config.maxAgeSeconds\"\n });\n }\n if (config.maxAgeFrom) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(config.maxAgeFrom, \"string\", {\n moduleName: \"serwist\",\n className: \"ExpirationPlugin\",\n funcName: \"constructor\",\n paramName: \"config.maxAgeFrom\"\n });\n }\n }\n this._config = config;\n this._cacheExpirations = new Map();\n if (!this._config.maxAgeFrom) {\n this._config.maxAgeFrom = \"last-fetched\";\n }\n if (this._config.purgeOnQuotaError) {\n registerQuotaErrorCallback(()=>this.deleteCacheAndMetadata());\n }\n }\n _getCacheExpiration(cacheName) {\n if (cacheName === _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.c.getRuntimeName()) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"expire-custom-caches-only\");\n }\n let cacheExpiration = this._cacheExpirations.get(cacheName);\n if (!cacheExpiration) {\n cacheExpiration = new CacheExpiration(cacheName, this._config);\n this._cacheExpirations.set(cacheName, cacheExpiration);\n }\n return cacheExpiration;\n }\n cachedResponseWillBeUsed({ event, cacheName, request, cachedResponse }) {\n if (!cachedResponse) {\n return null;\n }\n const isFresh = this._isResponseDateFresh(cachedResponse);\n const cacheExpiration = this._getCacheExpiration(cacheName);\n const isMaxAgeFromLastUsed = this._config.maxAgeFrom === \"last-used\";\n const done = (async ()=>{\n if (isMaxAgeFromLastUsed) {\n await cacheExpiration.updateTimestamp(request.url);\n }\n await cacheExpiration.expireEntries();\n })();\n try {\n event.waitUntil(done);\n } catch {\n if (true) {\n if (event instanceof FetchEvent) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.warn(`Unable to ensure service worker stays alive when updating cache entry for '${(0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(event.request.url)}'.`);\n }\n }\n }\n return isFresh ? cachedResponse : null;\n }\n _isResponseDateFresh(cachedResponse) {\n const isMaxAgeFromLastUsed = this._config.maxAgeFrom === \"last-used\";\n if (isMaxAgeFromLastUsed) {\n return true;\n }\n const now = Date.now();\n if (!this._config.maxAgeSeconds) {\n return true;\n }\n const dateHeaderTimestamp = this._getDateHeaderTimestamp(cachedResponse);\n if (dateHeaderTimestamp === null) {\n return true;\n }\n return dateHeaderTimestamp >= now - this._config.maxAgeSeconds * 1000;\n }\n _getDateHeaderTimestamp(cachedResponse) {\n if (!cachedResponse.headers.has(\"date\")) {\n return null;\n }\n const dateHeader = cachedResponse.headers.get(\"date\");\n const parsedDate = new Date(dateHeader);\n const headerTime = parsedDate.getTime();\n if (Number.isNaN(headerTime)) {\n return null;\n }\n return headerTime;\n }\n async cacheDidUpdate({ cacheName, request }) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(cacheName, \"string\", {\n moduleName: \"serwist\",\n className: \"Plugin\",\n funcName: \"cacheDidUpdate\",\n paramName: \"cacheName\"\n });\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(request, Request, {\n moduleName: \"serwist\",\n className: \"Plugin\",\n funcName: \"cacheDidUpdate\",\n paramName: \"request\"\n });\n }\n const cacheExpiration = this._getCacheExpiration(cacheName);\n await cacheExpiration.updateTimestamp(request.url);\n await cacheExpiration.expireEntries();\n }\n async deleteCacheAndMetadata() {\n for (const [cacheName, cacheExpiration] of this._cacheExpirations){\n await self.caches.delete(cacheName);\n await cacheExpiration.delete();\n }\n this._cacheExpirations = new Map();\n }\n}\n\nconst QUEUE_NAME = \"serwist-google-analytics\";\nconst MAX_RETENTION_TIME = 60 * 48;\nconst GOOGLE_ANALYTICS_HOST = \"www.google-analytics.com\";\nconst GTM_HOST = \"www.googletagmanager.com\";\nconst ANALYTICS_JS_PATH = \"/analytics.js\";\nconst GTAG_JS_PATH = \"/gtag/js\";\nconst GTM_JS_PATH = \"/gtm.js\";\nconst COLLECT_PATHS_REGEX = /^\\/(\\w+\\/)?collect/;\n\nconst createOnSyncCallback = (config)=>{\n return async ({ queue })=>{\n let entry;\n while(entry = await queue.shiftRequest()){\n const { request, timestamp } = entry;\n const url = new URL(request.url);\n try {\n const params = request.method === \"POST\" ? new URLSearchParams(await request.clone().text()) : url.searchParams;\n const originalHitTime = timestamp - (Number(params.get(\"qt\")) || 0);\n const queueTime = Date.now() - originalHitTime;\n params.set(\"qt\", String(queueTime));\n if (config.parameterOverrides) {\n for (const param of Object.keys(config.parameterOverrides)){\n const value = config.parameterOverrides[param];\n params.set(param, value);\n }\n }\n if (typeof config.hitFilter === \"function\") {\n config.hitFilter.call(null, params);\n }\n await fetch(new Request(url.origin + url.pathname, {\n body: params.toString(),\n method: \"POST\",\n mode: \"cors\",\n credentials: \"omit\",\n headers: {\n \"Content-Type\": \"text/plain\"\n }\n }));\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Request for '${(0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(url.href)}' has been replayed`);\n }\n } catch (err) {\n await queue.unshiftRequest(entry);\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Request for '${(0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(url.href)}' failed to replay, putting it back in the queue.`);\n }\n throw err;\n }\n }\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(\"All Google Analytics request successfully replayed; \" + \"the queue is now empty!\");\n }\n };\n};\nconst createCollectRoutes = (bgSyncPlugin)=>{\n const match = ({ url })=>url.hostname === GOOGLE_ANALYTICS_HOST && COLLECT_PATHS_REGEX.test(url.pathname);\n const handler = new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.a({\n plugins: [\n bgSyncPlugin\n ]\n });\n return [\n new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.R(match, handler, \"GET\"),\n new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.R(match, handler, \"POST\")\n ];\n};\nconst createAnalyticsJsRoute = (cacheName)=>{\n const match = ({ url })=>url.hostname === GOOGLE_ANALYTICS_HOST && url.pathname === ANALYTICS_JS_PATH;\n const handler = new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.N({\n cacheName\n });\n return new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.R(match, handler, \"GET\");\n};\nconst createGtagJsRoute = (cacheName)=>{\n const match = ({ url })=>url.hostname === GTM_HOST && url.pathname === GTAG_JS_PATH;\n const handler = new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.N({\n cacheName\n });\n return new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.R(match, handler, \"GET\");\n};\nconst createGtmJsRoute = (cacheName)=>{\n const match = ({ url })=>url.hostname === GTM_HOST && url.pathname === GTM_JS_PATH;\n const handler = new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.N({\n cacheName\n });\n return new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.R(match, handler, \"GET\");\n};\nconst initializeGoogleAnalytics = ({ serwist, cacheName, ...options })=>{\n const resolvedCacheName = _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.c.getGoogleAnalyticsName(cacheName);\n const bgSyncPlugin = new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.B(QUEUE_NAME, {\n maxRetentionTime: MAX_RETENTION_TIME,\n onSync: createOnSyncCallback(options)\n });\n const routes = [\n createGtmJsRoute(resolvedCacheName),\n createAnalyticsJsRoute(resolvedCacheName),\n createGtagJsRoute(resolvedCacheName),\n ...createCollectRoutes(bgSyncPlugin)\n ];\n for (const route of routes){\n serwist.registerRoute(route);\n }\n};\n\nclass PrecacheFallbackPlugin {\n _fallbackUrls;\n _serwist;\n constructor({ fallbackUrls, serwist }){\n this._fallbackUrls = fallbackUrls;\n this._serwist = serwist;\n }\n async handlerDidError(param) {\n for (const fallback of this._fallbackUrls){\n if (typeof fallback === \"string\") {\n const fallbackResponse = await this._serwist.matchPrecache(fallback);\n if (fallbackResponse !== undefined) {\n return fallbackResponse;\n }\n } else if (fallback.matcher(param)) {\n const fallbackResponse = await this._serwist.matchPrecache(fallback.url);\n if (fallbackResponse !== undefined) {\n return fallbackResponse;\n }\n }\n }\n return undefined;\n }\n}\n\nconst calculateEffectiveBoundaries = (blob, start, end)=>{\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(blob, Blob, {\n moduleName: \"@serwist/range-requests\",\n funcName: \"calculateEffectiveBoundaries\",\n paramName: \"blob\"\n });\n }\n const blobSize = blob.size;\n if (end && end > blobSize || start && start < 0) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"range-not-satisfiable\", {\n size: blobSize,\n end,\n start\n });\n }\n let effectiveStart;\n let effectiveEnd;\n if (start !== undefined && end !== undefined) {\n effectiveStart = start;\n effectiveEnd = end + 1;\n } else if (start !== undefined && end === undefined) {\n effectiveStart = start;\n effectiveEnd = blobSize;\n } else if (end !== undefined && start === undefined) {\n effectiveStart = blobSize - end;\n effectiveEnd = blobSize;\n }\n return {\n start: effectiveStart,\n end: effectiveEnd\n };\n};\n\nconst parseRangeHeader = (rangeHeader)=>{\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(rangeHeader, \"string\", {\n moduleName: \"@serwist/range-requests\",\n funcName: \"parseRangeHeader\",\n paramName: \"rangeHeader\"\n });\n }\n const normalizedRangeHeader = rangeHeader.trim().toLowerCase();\n if (!normalizedRangeHeader.startsWith(\"bytes=\")) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"unit-must-be-bytes\", {\n normalizedRangeHeader\n });\n }\n if (normalizedRangeHeader.includes(\",\")) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"single-range-only\", {\n normalizedRangeHeader\n });\n }\n const rangeParts = /(\\d*)-(\\d*)/.exec(normalizedRangeHeader);\n if (!rangeParts || !(rangeParts[1] || rangeParts[2])) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"invalid-range-values\", {\n normalizedRangeHeader\n });\n }\n return {\n start: rangeParts[1] === \"\" ? undefined : Number(rangeParts[1]),\n end: rangeParts[2] === \"\" ? undefined : Number(rangeParts[2])\n };\n};\n\nconst createPartialResponse = async (request, originalResponse)=>{\n try {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(request, Request, {\n moduleName: \"@serwist/range-requests\",\n funcName: \"createPartialResponse\",\n paramName: \"request\"\n });\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(originalResponse, Response, {\n moduleName: \"@serwist/range-requests\",\n funcName: \"createPartialResponse\",\n paramName: \"originalResponse\"\n });\n }\n if (originalResponse.status === 206) {\n return originalResponse;\n }\n const rangeHeader = request.headers.get(\"range\");\n if (!rangeHeader) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"no-range-header\");\n }\n const boundaries = parseRangeHeader(rangeHeader);\n const originalBlob = await originalResponse.blob();\n const effectiveBoundaries = calculateEffectiveBoundaries(originalBlob, boundaries.start, boundaries.end);\n const slicedBlob = originalBlob.slice(effectiveBoundaries.start, effectiveBoundaries.end);\n const slicedBlobSize = slicedBlob.size;\n const slicedResponse = new Response(slicedBlob, {\n status: 206,\n statusText: \"Partial Content\",\n headers: originalResponse.headers\n });\n slicedResponse.headers.set(\"Content-Length\", String(slicedBlobSize));\n slicedResponse.headers.set(\"Content-Range\", `bytes ${effectiveBoundaries.start}-${effectiveBoundaries.end - 1}/` + `${originalBlob.size}`);\n return slicedResponse;\n } catch (error) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.warn(\"Unable to construct a partial response; returning a \" + \"416 Range Not Satisfiable response instead.\");\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(\"View details here.\");\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(error);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(request);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(originalResponse);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n return new Response(\"\", {\n status: 416,\n statusText: \"Range Not Satisfiable\"\n });\n }\n};\n\nclass RangeRequestsPlugin {\n cachedResponseWillBeUsed = async ({ request, cachedResponse })=>{\n if (cachedResponse && request.headers.has(\"range\")) {\n return await createPartialResponse(request, cachedResponse);\n }\n return cachedResponse;\n };\n}\n\nclass CacheFirst extends _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.S {\n async _handle(request, handler) {\n const logs = [];\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(request, Request, {\n moduleName: \"serwist\",\n className: this.constructor.name,\n funcName: \"makeRequest\",\n paramName: \"request\"\n });\n }\n let response = await handler.cacheMatch(request);\n let error;\n if (!response) {\n if (true) {\n logs.push(`No response found in the '${this.cacheName}' cache. Will respond with a network request.`);\n }\n try {\n response = await handler.fetchAndCachePut(request);\n } catch (err) {\n if (err instanceof Error) {\n error = err;\n }\n }\n if (true) {\n if (response) {\n logs.push(\"Got response from network.\");\n } else {\n logs.push(\"Unable to get a response from the network.\");\n }\n }\n } else {\n if (true) {\n logs.push(`Found a cached response in the '${this.cacheName}' cache.`);\n }\n }\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.m.strategyStart(this.constructor.name, request));\n for (const log of logs){\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(log);\n }\n _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.m.printFinalResponse(response);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n if (!response) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"no-response\", {\n url: request.url,\n error\n });\n }\n return response;\n }\n}\n\nclass CacheOnly extends _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.S {\n async _handle(request, handler) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(request, Request, {\n moduleName: \"serwist\",\n className: this.constructor.name,\n funcName: \"makeRequest\",\n paramName: \"request\"\n });\n }\n const response = await handler.cacheMatch(request);\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.m.strategyStart(this.constructor.name, request));\n if (response) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`Found a cached response in the '${this.cacheName}' cache.`);\n _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.m.printFinalResponse(response);\n } else {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(`No response found in the '${this.cacheName}' cache.`);\n }\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n if (!response) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"no-response\", {\n url: request.url\n });\n }\n return response;\n }\n}\n\nclass StaleWhileRevalidate extends _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.S {\n constructor(options = {}){\n super(options);\n if (!this.plugins.some((p)=>\"cacheWillUpdate\" in p)) {\n this.plugins.unshift(_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.c);\n }\n }\n async _handle(request, handler) {\n const logs = [];\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(request, Request, {\n moduleName: \"serwist\",\n className: this.constructor.name,\n funcName: \"handle\",\n paramName: \"request\"\n });\n }\n const fetchAndCachePromise = handler.fetchAndCachePut(request).catch(()=>{});\n void handler.waitUntil(fetchAndCachePromise);\n let response = await handler.cacheMatch(request);\n let error;\n if (response) {\n if (true) {\n logs.push(`Found a cached response in the '${this.cacheName}' cache. Will update with the network response in the background.`);\n }\n } else {\n if (true) {\n logs.push(`No response found in the '${this.cacheName}' cache. Will wait for the network response.`);\n }\n try {\n response = await fetchAndCachePromise;\n } catch (err) {\n if (err instanceof Error) {\n error = err;\n }\n }\n }\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.m.strategyStart(this.constructor.name, request));\n for (const log of logs){\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(log);\n }\n _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.m.printFinalResponse(response);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n if (!response) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"no-response\", {\n url: request.url,\n error\n });\n }\n return response;\n }\n}\n\nclass PrecacheRoute extends _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.R {\n constructor(serwist, options){\n const match = ({ request })=>{\n const urlsToCacheKeys = serwist.getUrlsToPrecacheKeys();\n for (const possibleURL of (0,_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.g)(request.url, options)){\n const cacheKey = urlsToCacheKeys.get(possibleURL);\n if (cacheKey) {\n const integrity = serwist.getIntegrityForPrecacheKey(cacheKey);\n return {\n cacheKey,\n integrity\n };\n }\n }\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`Precaching did not find a match for ${(0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(request.url)}.`);\n }\n return;\n };\n super(match, serwist.precacheStrategy);\n }\n}\n\nclass PrecacheCacheKeyPlugin {\n _precacheController;\n constructor({ precacheController }){\n this._precacheController = precacheController;\n }\n cacheKeyWillBeUsed = async ({ request, params })=>{\n const cacheKey = params?.cacheKey || this._precacheController.getPrecacheKeyForUrl(request.url);\n return cacheKey ? new Request(cacheKey, {\n headers: request.headers\n }) : request;\n };\n}\n\nconst parsePrecacheOptions = (serwist, precacheOptions = {})=>{\n const { cacheName: precacheCacheName, plugins: precachePlugins = [], fetchOptions: precacheFetchOptions, matchOptions: precacheMatchOptions, fallbackToNetwork: precacheFallbackToNetwork, directoryIndex: precacheDirectoryIndex, ignoreURLParametersMatching: precacheIgnoreUrls, cleanURLs: precacheCleanUrls, urlManipulation: precacheUrlManipulation, cleanupOutdatedCaches, concurrency = 10, navigateFallback, navigateFallbackAllowlist, navigateFallbackDenylist } = precacheOptions ?? {};\n return {\n precacheStrategyOptions: {\n cacheName: _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.c.getPrecacheName(precacheCacheName),\n plugins: [\n ...precachePlugins,\n new PrecacheCacheKeyPlugin({\n precacheController: serwist\n })\n ],\n fetchOptions: precacheFetchOptions,\n matchOptions: precacheMatchOptions,\n fallbackToNetwork: precacheFallbackToNetwork\n },\n precacheRouteOptions: {\n directoryIndex: precacheDirectoryIndex,\n ignoreURLParametersMatching: precacheIgnoreUrls,\n cleanURLs: precacheCleanUrls,\n urlManipulation: precacheUrlManipulation\n },\n precacheMiscOptions: {\n cleanupOutdatedCaches,\n concurrency,\n navigateFallback,\n navigateFallbackAllowlist,\n navigateFallbackDenylist\n }\n };\n};\n\nclass Serwist {\n _urlsToCacheKeys = new Map();\n _urlsToCacheModes = new Map();\n _cacheKeysToIntegrities = new Map();\n _concurrentPrecaching;\n _precacheStrategy;\n _routes;\n _defaultHandlerMap;\n _catchHandler;\n _requestRules;\n constructor({ precacheEntries, precacheOptions, skipWaiting = false, importScripts, navigationPreload = false, cacheId, clientsClaim: clientsClaim$1 = false, runtimeCaching, offlineAnalyticsConfig, disableDevLogs: disableDevLogs$1 = false, fallbacks, requestRules } = {}){\n const { precacheStrategyOptions, precacheRouteOptions, precacheMiscOptions } = parsePrecacheOptions(this, precacheOptions);\n this._concurrentPrecaching = precacheMiscOptions.concurrency;\n this._precacheStrategy = new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.P(precacheStrategyOptions);\n this._routes = new Map();\n this._defaultHandlerMap = new Map();\n this._requestRules = requestRules;\n this.handleInstall = this.handleInstall.bind(this);\n this.handleActivate = this.handleActivate.bind(this);\n this.handleFetch = this.handleFetch.bind(this);\n this.handleCache = this.handleCache.bind(this);\n if (!!importScripts && importScripts.length > 0) self.importScripts(...importScripts);\n if (navigationPreload) (0,_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.e)();\n if (cacheId !== undefined) {\n (0,_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.s)({\n prefix: cacheId\n });\n }\n if (skipWaiting) {\n self.skipWaiting();\n } else {\n self.addEventListener(\"message\", (event)=>{\n if (event.data && event.data.type === \"SKIP_WAITING\") {\n self.skipWaiting();\n }\n });\n }\n if (clientsClaim$1) (0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.a)();\n if (!!precacheEntries && precacheEntries.length > 0) {\n this.addToPrecacheList(precacheEntries);\n }\n if (precacheMiscOptions.cleanupOutdatedCaches) {\n (0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.b)(precacheStrategyOptions.cacheName);\n }\n this.registerRoute(new PrecacheRoute(this, precacheRouteOptions));\n if (precacheMiscOptions.navigateFallback) {\n this.registerRoute(new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.b(this.createHandlerBoundToUrl(precacheMiscOptions.navigateFallback), {\n allowlist: precacheMiscOptions.navigateFallbackAllowlist,\n denylist: precacheMiscOptions.navigateFallbackDenylist\n }));\n }\n if (offlineAnalyticsConfig !== undefined) {\n if (typeof offlineAnalyticsConfig === \"boolean\") {\n offlineAnalyticsConfig && initializeGoogleAnalytics({\n serwist: this\n });\n } else {\n initializeGoogleAnalytics({\n ...offlineAnalyticsConfig,\n serwist: this\n });\n }\n }\n if (runtimeCaching !== undefined) {\n if (fallbacks !== undefined) {\n const fallbackPlugin = new PrecacheFallbackPlugin({\n fallbackUrls: fallbacks.entries,\n serwist: this\n });\n runtimeCaching.forEach((cacheEntry)=>{\n if (cacheEntry.handler instanceof _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.S && !cacheEntry.handler.plugins.some((plugin)=>\"handlerDidError\" in plugin)) {\n cacheEntry.handler.plugins.push(fallbackPlugin);\n }\n });\n }\n for (const entry of runtimeCaching){\n this.registerCapture(entry.matcher, entry.handler, entry.method);\n }\n }\n if (disableDevLogs$1) (0,_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.d)();\n }\n get precacheStrategy() {\n return this._precacheStrategy;\n }\n get routes() {\n return this._routes;\n }\n addEventListeners() {\n self.addEventListener(\"install\", this.handleInstall);\n self.addEventListener(\"activate\", this.handleActivate);\n self.addEventListener(\"fetch\", this.handleFetch);\n self.addEventListener(\"message\", this.handleCache);\n }\n addToPrecacheList(entries) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isArray(entries, {\n moduleName: \"serwist\",\n className: \"Serwist\",\n funcName: \"addToCacheList\",\n paramName: \"entries\"\n });\n }\n const urlsToWarnAbout = [];\n for (const entry of entries){\n if (typeof entry === \"string\") {\n urlsToWarnAbout.push(entry);\n } else if (entry && !entry.integrity && entry.revision === undefined) {\n urlsToWarnAbout.push(entry.url);\n }\n const { cacheKey, url } = (0,_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.f)(entry);\n const cacheMode = typeof entry !== \"string\" && entry.revision ? \"reload\" : \"default\";\n if (this._urlsToCacheKeys.has(url) && this._urlsToCacheKeys.get(url) !== cacheKey) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"add-to-cache-list-conflicting-entries\", {\n firstEntry: this._urlsToCacheKeys.get(url),\n secondEntry: cacheKey\n });\n }\n if (typeof entry !== \"string\" && entry.integrity) {\n if (this._cacheKeysToIntegrities.has(cacheKey) && this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"add-to-cache-list-conflicting-integrities\", {\n url\n });\n }\n this._cacheKeysToIntegrities.set(cacheKey, entry.integrity);\n }\n this._urlsToCacheKeys.set(url, cacheKey);\n this._urlsToCacheModes.set(url, cacheMode);\n }\n if (urlsToWarnAbout.length > 0) {\n const warningMessage = `Serwist is precaching URLs without revision info: ${urlsToWarnAbout.join(\", \")}\\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;\n if (false) {} else {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.warn(warningMessage);\n }\n }\n }\n handleInstall(event) {\n void this.registerRequestRules(event);\n return (0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.w)(event, async ()=>{\n const installReportPlugin = new _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.i();\n this.precacheStrategy.plugins.push(installReportPlugin);\n await (0,_serwist_utils__WEBPACK_IMPORTED_MODULE_4__.parallel)(this._concurrentPrecaching, Array.from(this._urlsToCacheKeys.entries()), async ([url, cacheKey])=>{\n const integrity = this._cacheKeysToIntegrities.get(cacheKey);\n const cacheMode = this._urlsToCacheModes.get(url);\n const request = new Request(url, {\n integrity,\n cache: cacheMode,\n credentials: \"same-origin\"\n });\n await Promise.all(this.precacheStrategy.handleAll({\n event,\n request,\n url: new URL(request.url),\n params: {\n cacheKey\n }\n }));\n });\n const { updatedURLs, notUpdatedURLs } = installReportPlugin;\n if (true) {\n (0,_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.j)(updatedURLs, notUpdatedURLs);\n }\n return {\n updatedURLs,\n notUpdatedURLs\n };\n });\n }\n async registerRequestRules(event) {\n if (!this._requestRules) {\n return;\n }\n if (!event?.addRoutes) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.warn(\"Request rules ignored as the Static Routing API is not supported in this browser. \" + \"See https://caniuse.com/mdn-api_installevent_addroutes for more information.\");\n }\n return;\n }\n try {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.warn(\"Request rules may not be supported in all browsers as the Static Routing API is experimental. \" + \"This feature allows bypassing the service worker for specific requests to improve performance. \" + \"See https://developer.mozilla.org/en-US/docs/Web/API/InstallEvent/addRoutes for more information.\");\n }\n await event.addRoutes(this._requestRules);\n this._requestRules = undefined;\n } catch (error) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.error(`Failed to register request rules: ${error instanceof Error ? error.message : String(error)}. ` + \"This may occur if the browser doesn't support the Static Routing API or if the request rules are invalid.\");\n }\n throw error;\n }\n }\n handleActivate(event) {\n return (0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.w)(event, async ()=>{\n const cache = await self.caches.open(this.precacheStrategy.cacheName);\n const currentlyCachedRequests = await cache.keys();\n const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());\n const deletedCacheRequests = [];\n for (const request of currentlyCachedRequests){\n if (!expectedCacheKeys.has(request.url)) {\n await cache.delete(request);\n deletedCacheRequests.push(request.url);\n }\n }\n if (true) {\n (0,_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.k)(deletedCacheRequests);\n }\n return {\n deletedCacheRequests\n };\n });\n }\n handleFetch(event) {\n const { request } = event;\n const responsePromise = this.handleRequest({\n request,\n event\n });\n if (responsePromise) {\n event.respondWith(responsePromise);\n }\n }\n handleCache(event) {\n if (event.data && event.data.type === \"CACHE_URLS\") {\n const { payload } = event.data;\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(\"Caching URLs from the window\", payload.urlsToCache);\n }\n const requestPromises = Promise.all(payload.urlsToCache.map((entry)=>{\n let request;\n if (typeof entry === \"string\") {\n request = new Request(entry);\n } else {\n request = new Request(...entry);\n }\n return this.handleRequest({\n request,\n event\n });\n }));\n event.waitUntil(requestPromises);\n if (event.ports?.[0]) {\n void requestPromises.then(()=>event.ports[0].postMessage(true));\n }\n }\n }\n setDefaultHandler(handler, method = _chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.h) {\n this._defaultHandlerMap.set(method, (0,_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.n)(handler));\n }\n setCatchHandler(handler) {\n this._catchHandler = (0,_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.n)(handler);\n }\n registerCapture(capture, handler, method) {\n const route = (0,_chunks_printInstallDetails_js__WEBPACK_IMPORTED_MODULE_1__.p)(capture, handler, method);\n this.registerRoute(route);\n return route;\n }\n registerRoute(route) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(route, \"object\", {\n moduleName: \"serwist\",\n className: \"Serwist\",\n funcName: \"registerRoute\",\n paramName: \"route\"\n });\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.hasMethod(route, \"match\", {\n moduleName: \"serwist\",\n className: \"Serwist\",\n funcName: \"registerRoute\",\n paramName: \"route\"\n });\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(route.handler, \"object\", {\n moduleName: \"serwist\",\n className: \"Serwist\",\n funcName: \"registerRoute\",\n paramName: \"route\"\n });\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.hasMethod(route.handler, \"handle\", {\n moduleName: \"serwist\",\n className: \"Serwist\",\n funcName: \"registerRoute\",\n paramName: \"route.handler\"\n });\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isType(route.method, \"string\", {\n moduleName: \"serwist\",\n className: \"Serwist\",\n funcName: \"registerRoute\",\n paramName: \"route.method\"\n });\n }\n if (!this._routes.has(route.method)) {\n this._routes.set(route.method, []);\n }\n this._routes.get(route.method).push(route);\n }\n unregisterRoute(route) {\n if (!this._routes.has(route.method)) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"unregister-route-but-not-found-with-method\", {\n method: route.method\n });\n }\n const routeIndex = this._routes.get(route.method).indexOf(route);\n if (routeIndex > -1) {\n this._routes.get(route.method).splice(routeIndex, 1);\n } else {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"unregister-route-route-not-registered\");\n }\n }\n getUrlsToPrecacheKeys() {\n return this._urlsToCacheKeys;\n }\n getPrecachedUrls() {\n return [\n ...this._urlsToCacheKeys.keys()\n ];\n }\n getPrecacheKeyForUrl(url) {\n const urlObject = new URL(url, location.href);\n return this._urlsToCacheKeys.get(urlObject.href);\n }\n getIntegrityForPrecacheKey(cacheKey) {\n return this._cacheKeysToIntegrities.get(cacheKey);\n }\n async matchPrecache(request) {\n const url = request instanceof Request ? request.url : request;\n const cacheKey = this.getPrecacheKeyForUrl(url);\n if (cacheKey) {\n const cache = await self.caches.open(this.precacheStrategy.cacheName);\n return cache.match(cacheKey);\n }\n return undefined;\n }\n createHandlerBoundToUrl(url) {\n const cacheKey = this.getPrecacheKeyForUrl(url);\n if (!cacheKey) {\n throw new _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.S(\"non-precached-url\", {\n url\n });\n }\n return (options)=>{\n options.request = new Request(url);\n options.params = {\n cacheKey,\n ...options.params\n };\n return this.precacheStrategy.handle(options);\n };\n }\n handleRequest({ request, event }) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.f.isInstance(request, Request, {\n moduleName: \"serwist\",\n className: \"Serwist\",\n funcName: \"handleRequest\",\n paramName: \"options.request\"\n });\n }\n const url = new URL(request.url, location.href);\n if (!url.protocol.startsWith(\"http\")) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(\"Router only supports URLs that start with 'http'.\");\n }\n return;\n }\n const sameOrigin = url.origin === location.origin;\n const { params, route } = this.findMatchingRoute({\n event,\n request,\n sameOrigin,\n url\n });\n let handler = route?.handler;\n const debugMessages = [];\n if (true) {\n if (handler) {\n debugMessages.push([\n \"Found a route to handle this request:\",\n route\n ]);\n if (params) {\n debugMessages.push([\n `Passing the following params to the route's handler:`,\n params\n ]);\n }\n }\n }\n const method = request.method;\n if (!handler && this._defaultHandlerMap.has(method)) {\n if (true) {\n debugMessages.push(`Failed to find a matching route. Falling back to the default handler for ${method}.`);\n }\n handler = this._defaultHandlerMap.get(method);\n }\n if (!handler) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.debug(`No route found for: ${(0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(url)}`);\n }\n return;\n }\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(`Router is responding to: ${(0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(url)}`);\n for (const msg of debugMessages){\n if (Array.isArray(msg)) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(...msg);\n } else {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.log(msg);\n }\n }\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n let responsePromise;\n try {\n responsePromise = handler.handle({\n url,\n request,\n event,\n params\n });\n } catch (err) {\n responsePromise = Promise.reject(err);\n }\n const catchHandler = route?.catchHandler;\n if (responsePromise instanceof Promise && (this._catchHandler || catchHandler)) {\n responsePromise = responsePromise.catch(async (err)=>{\n if (catchHandler) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(`Error thrown when responding to: ${(0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(url)}. Falling back to route's Catch Handler.`);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.error(\"Error thrown by:\", route);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.error(err);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n try {\n return await catchHandler.handle({\n url,\n request,\n event,\n params\n });\n } catch (catchErr) {\n if (catchErr instanceof Error) {\n err = catchErr;\n }\n }\n }\n if (this._catchHandler) {\n if (true) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupCollapsed(`Error thrown when responding to: ${(0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(url)}. Falling back to global Catch Handler.`);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.error(\"Error thrown by:\", route);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.error(err);\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.groupEnd();\n }\n return this._catchHandler.handle({\n url,\n request,\n event\n });\n }\n throw err;\n });\n }\n return responsePromise;\n }\n findMatchingRoute({ url, sameOrigin, request, event }) {\n const routes = this._routes.get(request.method) || [];\n for (const route of routes){\n let params;\n const matchResult = route.match({\n url,\n sameOrigin,\n request,\n event\n });\n if (matchResult) {\n if (true) {\n if (matchResult instanceof Promise) {\n _chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.l.warn(`While routing ${(0,_chunks_waitUntil_js__WEBPACK_IMPORTED_MODULE_0__.g)(url)}, an async matchCallback function was used. Please convert the following route to use a synchronous matchCallback function:`, route);\n }\n }\n params = matchResult;\n if (Array.isArray(params) && params.length === 0) {\n params = undefined;\n } else if (matchResult.constructor === Object && Object.keys(matchResult).length === 0) {\n params = undefined;\n } else if (typeof matchResult === \"boolean\") {\n params = undefined;\n }\n return {\n route,\n params\n };\n }\n }\n return {};\n }\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvc2Vyd2lzdC9kaXN0L2luZGV4LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUErTztBQUNzUTtBQUN4UDtBQUM5SztBQUN4QztBQUNHOztBQUUxQztBQUNBO0FBQ0EsZUFBZSxtREFBWTtBQUMzQixLQUFLO0FBQ0w7QUFDQSxlQUFlLG1EQUFZO0FBQzNCLEtBQUs7QUFDTDtBQUNBLGVBQWUsbURBQVk7QUFDM0IsS0FBSztBQUNMO0FBQ0EsZUFBZSxtREFBWTtBQUMzQixLQUFLO0FBQ0w7QUFDQSxlQUFlLG1EQUFZO0FBQzNCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFFBQVEsSUFBcUM7QUFDN0M7QUFDQSxzQkFBc0IsbURBQVk7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxZQUFZLElBQXFDO0FBQ2pELFlBQVksbURBQU07QUFDbEIsWUFBWSxtREFBTTtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLG9EQUFvRCxJQUFJO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLElBQXFDO0FBQ2pELFlBQVksbURBQWtCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFlBQVksbURBQWtCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFlBQVksbURBQWtCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsSUFBcUM7QUFDckQsZ0JBQWdCLG1EQUFNO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QkFBd0IsbURBQU07QUFDOUIsd0JBQXdCLG1EQUFNO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsSUFBcUM7QUFDN0Qsd0JBQXdCLG1EQUFNLHFEQUFxRCx1REFBYyxNQUFNO0FBQ3ZHLHdCQUF3QixtREFBTTtBQUM5Qix3QkFBd0IsbURBQU07QUFDOUIsd0JBQXdCLG1EQUFNO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUNBQWlDO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQSxvQkFBb0IsSUFBcUM7QUFDekQ7QUFDQSx3QkFBd0IsbURBQU0sdUJBQXVCLHVEQUFjLE1BQU07QUFDekU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUV5aUIiLCJzb3VyY2VzIjpbIi9Vc2Vycy9zZDkyMzUvY29kZS9teWdoL2xlYXJuaW5nX2FpX2Nsb2NrL3dlYi9ub2RlX21vZHVsZXMvc2Vyd2lzdC9kaXN0L2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGMgYXMgY2FjaGVOYW1lcyQxLCBTIGFzIFNlcndpc3RFcnJvciwgbCBhcyBsb2dnZXIsIGYgYXMgZmluYWxBc3NlcnRFeHBvcnRzLCB0IGFzIHRpbWVvdXQsIGcgYXMgZ2V0RnJpZW5kbHlVUkwsIHEgYXMgcXVvdGFFcnJvckNhbGxiYWNrcywgYSBhcyBjbGllbnRzQ2xhaW0sIGIgYXMgY2xlYW51cE91dGRhdGVkQ2FjaGVzLCB3IGFzIHdhaXRVbnRpbCB9IGZyb20gJy4vY2h1bmtzL3dhaXRVbnRpbC5qcyc7XG5pbXBvcnQgeyBCIGFzIEJhY2tncm91bmRTeW5jUGx1Z2luLCBOIGFzIE5ldHdvcmtGaXJzdCwgUiBhcyBSb3V0ZSwgYSBhcyBOZXR3b3JrT25seSwgUyBhcyBTdHJhdGVneSwgbSBhcyBtZXNzYWdlcywgYyBhcyBjYWNoZU9rQW5kT3BhcXVlUGx1Z2luLCBnIGFzIGdlbmVyYXRlVVJMVmFyaWF0aW9ucywgUCBhcyBQcmVjYWNoZVN0cmF0ZWd5LCBlIGFzIGVuYWJsZU5hdmlnYXRpb25QcmVsb2FkLCBzIGFzIHNldENhY2hlTmFtZURldGFpbHMsIGIgYXMgTmF2aWdhdGlvblJvdXRlLCBkIGFzIGRpc2FibGVEZXZMb2dzLCBmIGFzIGNyZWF0ZUNhY2hlS2V5LCBoIGFzIGRlZmF1bHRNZXRob2QsIG4gYXMgbm9ybWFsaXplSGFuZGxlciwgcCBhcyBwYXJzZVJvdXRlLCBpIGFzIFByZWNhY2hlSW5zdGFsbFJlcG9ydFBsdWdpbiwgaiBhcyBwcmludEluc3RhbGxEZXRhaWxzLCBrIGFzIHByaW50Q2xlYW51cERldGFpbHMgfSBmcm9tICcuL2NodW5rcy9wcmludEluc3RhbGxEZXRhaWxzLmpzJztcbmV4cG9ydCB7IGwgYXMgQmFja2dyb3VuZFN5bmNRdWV1ZSwgbyBhcyBCYWNrZ3JvdW5kU3luY1F1ZXVlU3RvcmUsIHEgYXMgUmVnRXhwUm91dGUsIHIgYXMgU3RvcmFibGVSZXF1ZXN0LCB0IGFzIFN0cmF0ZWd5SGFuZGxlciwgdSBhcyBjb3B5UmVzcG9uc2UsIHYgYXMgZGlzYWJsZU5hdmlnYXRpb25QcmVsb2FkLCB3IGFzIGlzTmF2aWdhdGlvblByZWxvYWRTdXBwb3J0ZWQgfSBmcm9tICcuL2NodW5rcy9wcmludEluc3RhbGxEZXRhaWxzLmpzJztcbmltcG9ydCB7IHIgYXMgcmVzdWx0aW5nQ2xpZW50RXhpc3RzIH0gZnJvbSAnLi9jaHVua3MvcmVzdWx0aW5nQ2xpZW50RXhpc3RzLmpzJztcbmltcG9ydCB7IGRlbGV0ZURCLCBvcGVuREIgfSBmcm9tICdpZGInO1xuaW1wb3J0IHsgcGFyYWxsZWwgfSBmcm9tICdAc2Vyd2lzdC91dGlscyc7XG5cbmNvbnN0IGNhY2hlTmFtZXMgPSB7XG4gICAgZ2V0IGdvb2dsZUFuYWx5dGljcyAoKSB7XG4gICAgICAgIHJldHVybiBjYWNoZU5hbWVzJDEuZ2V0R29vZ2xlQW5hbHl0aWNzTmFtZSgpO1xuICAgIH0sXG4gICAgZ2V0IHByZWNhY2hlICgpIHtcbiAgICAgICAgcmV0dXJuIGNhY2hlTmFtZXMkMS5nZXRQcmVjYWNoZU5hbWUoKTtcbiAgICB9LFxuICAgIGdldCBwcmVmaXggKCkge1xuICAgICAgICByZXR1cm4gY2FjaGVOYW1lcyQxLmdldFByZWZpeCgpO1xuICAgIH0sXG4gICAgZ2V0IHJ1bnRpbWUgKCkge1xuICAgICAgICByZXR1cm4gY2FjaGVOYW1lcyQxLmdldFJ1bnRpbWVOYW1lKCk7XG4gICAgfSxcbiAgICBnZXQgc3VmZml4ICgpIHtcbiAgICAgICAgcmV0dXJuIGNhY2hlTmFtZXMkMS5nZXRTdWZmaXgoKTtcbiAgICB9XG59O1xuXG5jb25zdCBCUk9BRENBU1RfVVBEQVRFX01FU1NBR0VfVFlQRSA9IFwiQ0FDSEVfVVBEQVRFRFwiO1xuY29uc3QgQlJPQURDQVNUX1VQREFURV9NRVNTQUdFX01FVEEgPSBcInNlcndpc3QtYnJvYWRjYXN0LXVwZGF0ZVwiO1xuY29uc3QgQlJPQURDQVNUX1VQREFURV9ERUZBVUxUX05PVElGWSA9IHRydWU7XG5jb25zdCBCUk9BRENBU1RfVVBEQVRFX0RFRkFVTFRfSEVBREVSUyA9IFtcbiAgICBcImNvbnRlbnQtbGVuZ3RoXCIsXG4gICAgXCJldGFnXCIsXG4gICAgXCJsYXN0LW1vZGlmaWVkXCJcbl07XG5cbmNvbnN0IHJlc3BvbnNlc0FyZVNhbWUgPSAoZmlyc3RSZXNwb25zZSwgc2Vjb25kUmVzcG9uc2UsIGhlYWRlcnNUb0NoZWNrKT0+e1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgaWYgKCEoZmlyc3RSZXNwb25zZSBpbnN0YW5jZW9mIFJlc3BvbnNlICYmIHNlY29uZFJlc3BvbnNlIGluc3RhbmNlb2YgUmVzcG9uc2UpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiaW52YWxpZC1yZXNwb25zZXMtYXJlLXNhbWUtYXJnc1wiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBhdExlYXN0T25lSGVhZGVyQXZhaWxhYmxlID0gaGVhZGVyc1RvQ2hlY2suc29tZSgoaGVhZGVyKT0+e1xuICAgICAgICByZXR1cm4gZmlyc3RSZXNwb25zZS5oZWFkZXJzLmhhcyhoZWFkZXIpICYmIHNlY29uZFJlc3BvbnNlLmhlYWRlcnMuaGFzKGhlYWRlcik7XG4gICAgfSk7XG4gICAgaWYgKCFhdExlYXN0T25lSGVhZGVyQXZhaWxhYmxlKSB7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKFwiVW5hYmxlIHRvIGRldGVybWluZSB3aGVyZSB0aGUgcmVzcG9uc2UgaGFzIGJlZW4gdXBkYXRlZCBiZWNhdXNlIG5vbmUgb2YgdGhlIGhlYWRlcnMgdGhhdCB3b3VsZCBiZSBjaGVja2VkIGFyZSBwcmVzZW50LlwiKTtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhcIkF0dGVtcHRpbmcgdG8gY29tcGFyZSB0aGUgZm9sbG93aW5nOiBcIiwgZmlyc3RSZXNwb25zZSwgc2Vjb25kUmVzcG9uc2UsIGhlYWRlcnNUb0NoZWNrKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGhlYWRlcnNUb0NoZWNrLmV2ZXJ5KChoZWFkZXIpPT57XG4gICAgICAgIGNvbnN0IGhlYWRlclN0YXRlQ29tcGFyaXNvbiA9IGZpcnN0UmVzcG9uc2UuaGVhZGVycy5oYXMoaGVhZGVyKSA9PT0gc2Vjb25kUmVzcG9uc2UuaGVhZGVycy5oYXMoaGVhZGVyKTtcbiAgICAgICAgY29uc3QgaGVhZGVyVmFsdWVDb21wYXJpc29uID0gZmlyc3RSZXNwb25zZS5oZWFkZXJzLmdldChoZWFkZXIpID09PSBzZWNvbmRSZXNwb25zZS5oZWFkZXJzLmdldChoZWFkZXIpO1xuICAgICAgICByZXR1cm4gaGVhZGVyU3RhdGVDb21wYXJpc29uICYmIGhlYWRlclZhbHVlQ29tcGFyaXNvbjtcbiAgICB9KTtcbn07XG5cbmNvbnN0IGlzU2FmYXJpID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gXCJ1bmRlZmluZWRcIiAmJiAvXigoPyFjaHJvbWV8YW5kcm9pZCkuKSpzYWZhcmkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuY29uc3QgZGVmYXVsdFBheWxvYWRHZW5lcmF0b3IgPSAoZGF0YSk9PntcbiAgICByZXR1cm4ge1xuICAgICAgICBjYWNoZU5hbWU6IGRhdGEuY2FjaGVOYW1lLFxuICAgICAgICB1cGRhdGVkVVJMOiBkYXRhLnJlcXVlc3QudXJsXG4gICAgfTtcbn07XG5jbGFzcyBCcm9hZGNhc3RDYWNoZVVwZGF0ZSB7XG4gICAgX2hlYWRlcnNUb0NoZWNrO1xuICAgIF9nZW5lcmF0ZVBheWxvYWQ7XG4gICAgX25vdGlmeUFsbENsaWVudHM7XG4gICAgY29uc3RydWN0b3IoeyBnZW5lcmF0ZVBheWxvYWQsIGhlYWRlcnNUb0NoZWNrLCBub3RpZnlBbGxDbGllbnRzIH0gPSB7fSl7XG4gICAgICAgIHRoaXMuX2hlYWRlcnNUb0NoZWNrID0gaGVhZGVyc1RvQ2hlY2sgfHwgQlJPQURDQVNUX1VQREFURV9ERUZBVUxUX0hFQURFUlM7XG4gICAgICAgIHRoaXMuX2dlbmVyYXRlUGF5bG9hZCA9IGdlbmVyYXRlUGF5bG9hZCB8fCBkZWZhdWx0UGF5bG9hZEdlbmVyYXRvcjtcbiAgICAgICAgdGhpcy5fbm90aWZ5QWxsQ2xpZW50cyA9IG5vdGlmeUFsbENsaWVudHMgPz8gQlJPQURDQVNUX1VQREFURV9ERUZBVUxUX05PVElGWTtcbiAgICB9XG4gICAgYXN5bmMgbm90aWZ5SWZVcGRhdGVkKG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzVHlwZShvcHRpb25zLmNhY2hlTmFtZSwgXCJzdHJpbmdcIiwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJCcm9hZGNhc3RDYWNoZVVwZGF0ZVwiLFxuICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcIm5vdGlmeUlmVXBkYXRlZFwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJjYWNoZU5hbWVcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNJbnN0YW5jZShvcHRpb25zLm5ld1Jlc3BvbnNlLCBSZXNwb25zZSwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJCcm9hZGNhc3RDYWNoZVVwZGF0ZVwiLFxuICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcIm5vdGlmeUlmVXBkYXRlZFwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJuZXdSZXNwb25zZVwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc0luc3RhbmNlKG9wdGlvbnMucmVxdWVzdCwgUmVxdWVzdCwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJCcm9hZGNhc3RDYWNoZVVwZGF0ZVwiLFxuICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcIm5vdGlmeUlmVXBkYXRlZFwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJyZXF1ZXN0XCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghb3B0aW9ucy5vbGRSZXNwb25zZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVzcG9uc2VzQXJlU2FtZShvcHRpb25zLm9sZFJlc3BvbnNlLCBvcHRpb25zLm5ld1Jlc3BvbnNlLCB0aGlzLl9oZWFkZXJzVG9DaGVjaykpIHtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIubG9nKFwiTmV3ZXIgcmVzcG9uc2UgZm91bmQgKGFuZCBjYWNoZWQpIGZvcjpcIiwgb3B0aW9ucy5yZXF1ZXN0LnVybCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlRGF0YSA9IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBCUk9BRENBU1RfVVBEQVRFX01FU1NBR0VfVFlQRSxcbiAgICAgICAgICAgICAgICBtZXRhOiBCUk9BRENBU1RfVVBEQVRFX01FU1NBR0VfTUVUQSxcbiAgICAgICAgICAgICAgICBwYXlsb2FkOiB0aGlzLl9nZW5lcmF0ZVBheWxvYWQob3B0aW9ucylcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5yZXF1ZXN0Lm1vZGUgPT09IFwibmF2aWdhdGVcIikge1xuICAgICAgICAgICAgICAgIGxldCByZXN1bHRpbmdDbGllbnRJZDtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5ldmVudCBpbnN0YW5jZW9mIEZldGNoRXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0aW5nQ2xpZW50SWQgPSBvcHRpb25zLmV2ZW50LnJlc3VsdGluZ0NsaWVudElkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHRpbmdXaW4gPSBhd2FpdCByZXN1bHRpbmdDbGllbnRFeGlzdHMocmVzdWx0aW5nQ2xpZW50SWQpO1xuICAgICAgICAgICAgICAgIGlmICghcmVzdWx0aW5nV2luIHx8IGlzU2FmYXJpKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRpbWVvdXQoMzUwMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuX25vdGlmeUFsbENsaWVudHMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB3aW5kb3dzID0gYXdhaXQgc2VsZi5jbGllbnRzLm1hdGNoQWxsKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJ3aW5kb3dcIlxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgd2luIG9mIHdpbmRvd3Mpe1xuICAgICAgICAgICAgICAgICAgICB3aW4ucG9zdE1lc3NhZ2UobWVzc2FnZURhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuZXZlbnQgaW5zdGFuY2VvZiBGZXRjaEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHNlbGYuY2xpZW50cy5nZXQob3B0aW9ucy5ldmVudC5jbGllbnRJZCk7XG4gICAgICAgICAgICAgICAgICAgIGNsaWVudD8ucG9zdE1lc3NhZ2UobWVzc2FnZURhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgQnJvYWRjYXN0VXBkYXRlUGx1Z2luIHtcbiAgICBfYnJvYWRjYXN0VXBkYXRlO1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpe1xuICAgICAgICB0aGlzLl9icm9hZGNhc3RVcGRhdGUgPSBuZXcgQnJvYWRjYXN0Q2FjaGVVcGRhdGUob3B0aW9ucyk7XG4gICAgfVxuICAgIGNhY2hlRGlkVXBkYXRlKG9wdGlvbnMpIHtcbiAgICAgICAgdm9pZCB0aGlzLl9icm9hZGNhc3RVcGRhdGUubm90aWZ5SWZVcGRhdGVkKG9wdGlvbnMpO1xuICAgIH1cbn1cblxuY2xhc3MgQ2FjaGVhYmxlUmVzcG9uc2Uge1xuICAgIF9zdGF0dXNlcztcbiAgICBfaGVhZGVycztcbiAgICBjb25zdHJ1Y3Rvcihjb25maWcgPSB7fSl7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGlmICghKGNvbmZpZy5zdGF0dXNlcyB8fCBjb25maWcuaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwic3RhdHVzZXMtb3ItaGVhZGVycy1yZXF1aXJlZFwiLCB7XG4gICAgICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiQ2FjaGVhYmxlUmVzcG9uc2VcIixcbiAgICAgICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiY29uc3RydWN0b3JcIlxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvbmZpZy5zdGF0dXNlcykge1xuICAgICAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc0FycmF5KGNvbmZpZy5zdGF0dXNlcywge1xuICAgICAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIkNhY2hlYWJsZVJlc3BvbnNlXCIsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNvbnN0cnVjdG9yXCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJjb25maWcuc3RhdHVzZXNcIlxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvbmZpZy5oZWFkZXJzKSB7XG4gICAgICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzVHlwZShjb25maWcuaGVhZGVycywgXCJvYmplY3RcIiwge1xuICAgICAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIkNhY2hlYWJsZVJlc3BvbnNlXCIsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNvbnN0cnVjdG9yXCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJjb25maWcuaGVhZGVyc1wiXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3RhdHVzZXMgPSBjb25maWcuc3RhdHVzZXM7XG4gICAgICAgIGlmIChjb25maWcuaGVhZGVycykge1xuICAgICAgICAgICAgdGhpcy5faGVhZGVycyA9IG5ldyBIZWFkZXJzKGNvbmZpZy5oZWFkZXJzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpc1Jlc3BvbnNlQ2FjaGVhYmxlKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc0luc3RhbmNlKHJlc3BvbnNlLCBSZXNwb25zZSwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJDYWNoZWFibGVSZXNwb25zZVwiLFxuICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcImlzUmVzcG9uc2VDYWNoZWFibGVcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwicmVzcG9uc2VcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGNhY2hlYWJsZSA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0dXNlcykge1xuICAgICAgICAgICAgY2FjaGVhYmxlID0gdGhpcy5fc3RhdHVzZXMuaW5jbHVkZXMocmVzcG9uc2Uuc3RhdHVzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5faGVhZGVycyAmJiBjYWNoZWFibGUpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgW2hlYWRlck5hbWUsIGhlYWRlclZhbHVlXSBvZiB0aGlzLl9oZWFkZXJzLmVudHJpZXMoKSl7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KGhlYWRlck5hbWUpICE9PSBoZWFkZXJWYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBjYWNoZWFibGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGlmICghY2FjaGVhYmxlKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmdyb3VwQ29sbGFwc2VkKGBUaGUgcmVxdWVzdCBmb3IgJyR7Z2V0RnJpZW5kbHlVUkwocmVzcG9uc2UudXJsKX0nIHJldHVybmVkIGEgcmVzcG9uc2UgdGhhdCBkb2VzIG5vdCBtZWV0IHRoZSBjcml0ZXJpYSBmb3IgYmVpbmcgY2FjaGVkLmApO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5ncm91cENvbGxhcHNlZChcIlZpZXcgY2FjaGVhYmlsaXR5IGNyaXRlcmlhIGhlcmUuXCIpO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coYENhY2hlYWJsZSBzdGF0dXNlczogJHtKU09OLnN0cmluZ2lmeSh0aGlzLl9zdGF0dXNlcyl9YCk7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhgQ2FjaGVhYmxlIGhlYWRlcnM6ICR7SlNPTi5zdHJpbmdpZnkodGhpcy5faGVhZGVycywgbnVsbCwgMil9YCk7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmdyb3VwRW5kKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgbG9nRnJpZW5kbHlIZWFkZXJzID0ge307XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UuaGVhZGVycy5mb3JFYWNoKCh2YWx1ZSwga2V5KT0+e1xuICAgICAgICAgICAgICAgICAgICBsb2dGcmllbmRseUhlYWRlcnNba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5ncm91cENvbGxhcHNlZChcIlZpZXcgcmVzcG9uc2Ugc3RhdHVzIGFuZCBoZWFkZXJzIGhlcmUuXCIpO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coYFJlc3BvbnNlIHN0YXR1czogJHtyZXNwb25zZS5zdGF0dXN9YCk7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhgUmVzcG9uc2UgaGVhZGVyczogJHtKU09OLnN0cmluZ2lmeShsb2dGcmllbmRseUhlYWRlcnMsIG51bGwsIDIpfWApO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5ncm91cEVuZCgpO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5ncm91cENvbGxhcHNlZChcIlZpZXcgZnVsbCByZXNwb25zZSBkZXRhaWxzIGhlcmUuXCIpO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5sb2cocmVzcG9uc2UuaGVhZGVycyk7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmdyb3VwRW5kKCk7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmdyb3VwRW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhY2hlYWJsZTtcbiAgICB9XG59XG5cbmNsYXNzIENhY2hlYWJsZVJlc3BvbnNlUGx1Z2luIHtcbiAgICBfY2FjaGVhYmxlUmVzcG9uc2U7XG4gICAgY29uc3RydWN0b3IoY29uZmlnKXtcbiAgICAgICAgdGhpcy5fY2FjaGVhYmxlUmVzcG9uc2UgPSBuZXcgQ2FjaGVhYmxlUmVzcG9uc2UoY29uZmlnKTtcbiAgICB9XG4gICAgY2FjaGVXaWxsVXBkYXRlID0gYXN5bmMgKHsgcmVzcG9uc2UgfSk9PntcbiAgICAgICAgaWYgKHRoaXMuX2NhY2hlYWJsZVJlc3BvbnNlLmlzUmVzcG9uc2VDYWNoZWFibGUocmVzcG9uc2UpKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbn1cblxuY29uc3QgREJfTkFNRSA9IFwic2Vyd2lzdC1leHBpcmF0aW9uXCI7XG5jb25zdCBDQUNIRV9PQkpFQ1RfU1RPUkUgPSBcImNhY2hlLWVudHJpZXNcIjtcbmNvbnN0IG5vcm1hbGl6ZVVSTCA9ICh1bk5vcm1hbGl6ZWRVcmwpPT57XG4gICAgY29uc3QgdXJsID0gbmV3IFVSTCh1bk5vcm1hbGl6ZWRVcmwsIGxvY2F0aW9uLmhyZWYpO1xuICAgIHVybC5oYXNoID0gXCJcIjtcbiAgICByZXR1cm4gdXJsLmhyZWY7XG59O1xuY2xhc3MgQ2FjaGVUaW1lc3RhbXBzTW9kZWwge1xuICAgIF9jYWNoZU5hbWU7XG4gICAgX2RiID0gbnVsbDtcbiAgICBjb25zdHJ1Y3RvcihjYWNoZU5hbWUpe1xuICAgICAgICB0aGlzLl9jYWNoZU5hbWUgPSBjYWNoZU5hbWU7XG4gICAgfVxuICAgIF9nZXRJZCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIGAke3RoaXMuX2NhY2hlTmFtZX18JHtub3JtYWxpemVVUkwodXJsKX1gO1xuICAgIH1cbiAgICBfdXBncmFkZURiKGRiKSB7XG4gICAgICAgIGNvbnN0IG9ialN0b3JlID0gZGIuY3JlYXRlT2JqZWN0U3RvcmUoQ0FDSEVfT0JKRUNUX1NUT1JFLCB7XG4gICAgICAgICAgICBrZXlQYXRoOiBcImlkXCJcbiAgICAgICAgfSk7XG4gICAgICAgIG9ialN0b3JlLmNyZWF0ZUluZGV4KFwiY2FjaGVOYW1lXCIsIFwiY2FjaGVOYW1lXCIsIHtcbiAgICAgICAgICAgIHVuaXF1ZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICAgIG9ialN0b3JlLmNyZWF0ZUluZGV4KFwidGltZXN0YW1wXCIsIFwidGltZXN0YW1wXCIsIHtcbiAgICAgICAgICAgIHVuaXF1ZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIF91cGdyYWRlRGJBbmREZWxldGVPbGREYnMoZGIpIHtcbiAgICAgICAgdGhpcy5fdXBncmFkZURiKGRiKTtcbiAgICAgICAgaWYgKHRoaXMuX2NhY2hlTmFtZSkge1xuICAgICAgICAgICAgdm9pZCBkZWxldGVEQih0aGlzLl9jYWNoZU5hbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIHNldFRpbWVzdGFtcCh1cmwsIHRpbWVzdGFtcCkge1xuICAgICAgICB1cmwgPSBub3JtYWxpemVVUkwodXJsKTtcbiAgICAgICAgY29uc3QgZW50cnkgPSB7XG4gICAgICAgICAgICBpZDogdGhpcy5fZ2V0SWQodXJsKSxcbiAgICAgICAgICAgIGNhY2hlTmFtZTogdGhpcy5fY2FjaGVOYW1lLFxuICAgICAgICAgICAgdXJsLFxuICAgICAgICAgICAgdGltZXN0YW1wXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGRiID0gYXdhaXQgdGhpcy5nZXREYigpO1xuICAgICAgICBjb25zdCB0eCA9IGRiLnRyYW5zYWN0aW9uKENBQ0hFX09CSkVDVF9TVE9SRSwgXCJyZWFkd3JpdGVcIiwge1xuICAgICAgICAgICAgZHVyYWJpbGl0eTogXCJyZWxheGVkXCJcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHR4LnN0b3JlLnB1dChlbnRyeSk7XG4gICAgICAgIGF3YWl0IHR4LmRvbmU7XG4gICAgfVxuICAgIGFzeW5jIGdldFRpbWVzdGFtcCh1cmwpIHtcbiAgICAgICAgY29uc3QgZGIgPSBhd2FpdCB0aGlzLmdldERiKCk7XG4gICAgICAgIGNvbnN0IGVudHJ5ID0gYXdhaXQgZGIuZ2V0KENBQ0hFX09CSkVDVF9TVE9SRSwgdGhpcy5fZ2V0SWQodXJsKSk7XG4gICAgICAgIHJldHVybiBlbnRyeT8udGltZXN0YW1wO1xuICAgIH1cbiAgICBhc3luYyBleHBpcmVFbnRyaWVzKG1pblRpbWVzdGFtcCwgbWF4Q291bnQpIHtcbiAgICAgICAgY29uc3QgZGIgPSBhd2FpdCB0aGlzLmdldERiKCk7XG4gICAgICAgIGxldCBjdXJzb3IgPSBhd2FpdCBkYi50cmFuc2FjdGlvbihDQUNIRV9PQkpFQ1RfU1RPUkUsIFwicmVhZHdyaXRlXCIpLnN0b3JlLmluZGV4KFwidGltZXN0YW1wXCIpLm9wZW5DdXJzb3IobnVsbCwgXCJwcmV2XCIpO1xuICAgICAgICBjb25zdCB1cmxzRGVsZXRlZCA9IFtdO1xuICAgICAgICBsZXQgZW50cmllc05vdERlbGV0ZWRDb3VudCA9IDA7XG4gICAgICAgIHdoaWxlKGN1cnNvcil7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjdXJzb3IudmFsdWU7XG4gICAgICAgICAgICBpZiAocmVzdWx0LmNhY2hlTmFtZSA9PT0gdGhpcy5fY2FjaGVOYW1lKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1pblRpbWVzdGFtcCAmJiByZXN1bHQudGltZXN0YW1wIDwgbWluVGltZXN0YW1wIHx8IG1heENvdW50ICYmIGVudHJpZXNOb3REZWxldGVkQ291bnQgPj0gbWF4Q291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY3Vyc29yLmRlbGV0ZSgpO1xuICAgICAgICAgICAgICAgICAgICB1cmxzRGVsZXRlZC5wdXNoKHJlc3VsdC51cmwpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVudHJpZXNOb3REZWxldGVkQ291bnQrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJzb3IgPSBhd2FpdCBjdXJzb3IuY29udGludWUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXJsc0RlbGV0ZWQ7XG4gICAgfVxuICAgIGFzeW5jIGdldERiKCkge1xuICAgICAgICBpZiAoIXRoaXMuX2RiKSB7XG4gICAgICAgICAgICB0aGlzLl9kYiA9IGF3YWl0IG9wZW5EQihEQl9OQU1FLCAxLCB7XG4gICAgICAgICAgICAgICAgdXBncmFkZTogdGhpcy5fdXBncmFkZURiQW5kRGVsZXRlT2xkRGJzLmJpbmQodGhpcylcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9kYjtcbiAgICB9XG59XG5cbmNsYXNzIENhY2hlRXhwaXJhdGlvbiB7XG4gICAgX2lzUnVubmluZyA9IGZhbHNlO1xuICAgIF9yZXJ1blJlcXVlc3RlZCA9IGZhbHNlO1xuICAgIF9tYXhFbnRyaWVzO1xuICAgIF9tYXhBZ2VTZWNvbmRzO1xuICAgIF9tYXRjaE9wdGlvbnM7XG4gICAgX2NhY2hlTmFtZTtcbiAgICBfdGltZXN0YW1wTW9kZWw7XG4gICAgY29uc3RydWN0b3IoY2FjaGVOYW1lLCBjb25maWcgPSB7fSl7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc1R5cGUoY2FjaGVOYW1lLCBcInN0cmluZ1wiLCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIkNhY2hlRXhwaXJhdGlvblwiLFxuICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNvbnN0cnVjdG9yXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcImNhY2hlTmFtZVwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghKGNvbmZpZy5tYXhFbnRyaWVzIHx8IGNvbmZpZy5tYXhBZ2VTZWNvbmRzKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJtYXgtZW50cmllcy1vci1hZ2UtcmVxdWlyZWRcIiwge1xuICAgICAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIkNhY2hlRXhwaXJhdGlvblwiLFxuICAgICAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJjb25zdHJ1Y3RvclwiXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY29uZmlnLm1heEVudHJpZXMpIHtcbiAgICAgICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNUeXBlKGNvbmZpZy5tYXhFbnRyaWVzLCBcIm51bWJlclwiLCB7XG4gICAgICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiQ2FjaGVFeHBpcmF0aW9uXCIsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNvbnN0cnVjdG9yXCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJjb25maWcubWF4RW50cmllc1wiXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY29uZmlnLm1heEFnZVNlY29uZHMpIHtcbiAgICAgICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNUeXBlKGNvbmZpZy5tYXhBZ2VTZWNvbmRzLCBcIm51bWJlclwiLCB7XG4gICAgICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiQ2FjaGVFeHBpcmF0aW9uXCIsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNvbnN0cnVjdG9yXCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJjb25maWcubWF4QWdlU2Vjb25kc1wiXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbWF4RW50cmllcyA9IGNvbmZpZy5tYXhFbnRyaWVzO1xuICAgICAgICB0aGlzLl9tYXhBZ2VTZWNvbmRzID0gY29uZmlnLm1heEFnZVNlY29uZHM7XG4gICAgICAgIHRoaXMuX21hdGNoT3B0aW9ucyA9IGNvbmZpZy5tYXRjaE9wdGlvbnM7XG4gICAgICAgIHRoaXMuX2NhY2hlTmFtZSA9IGNhY2hlTmFtZTtcbiAgICAgICAgdGhpcy5fdGltZXN0YW1wTW9kZWwgPSBuZXcgQ2FjaGVUaW1lc3RhbXBzTW9kZWwoY2FjaGVOYW1lKTtcbiAgICB9XG4gICAgYXN5bmMgZXhwaXJlRW50cmllcygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzUnVubmluZykge1xuICAgICAgICAgICAgdGhpcy5fcmVydW5SZXF1ZXN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2lzUnVubmluZyA9IHRydWU7XG4gICAgICAgIGNvbnN0IG1pblRpbWVzdGFtcCA9IHRoaXMuX21heEFnZVNlY29uZHMgPyBEYXRlLm5vdygpIC0gdGhpcy5fbWF4QWdlU2Vjb25kcyAqIDEwMDAgOiAwO1xuICAgICAgICBjb25zdCB1cmxzRXhwaXJlZCA9IGF3YWl0IHRoaXMuX3RpbWVzdGFtcE1vZGVsLmV4cGlyZUVudHJpZXMobWluVGltZXN0YW1wLCB0aGlzLl9tYXhFbnRyaWVzKTtcbiAgICAgICAgY29uc3QgY2FjaGUgPSBhd2FpdCBzZWxmLmNhY2hlcy5vcGVuKHRoaXMuX2NhY2hlTmFtZSk7XG4gICAgICAgIGZvciAoY29uc3QgdXJsIG9mIHVybHNFeHBpcmVkKXtcbiAgICAgICAgICAgIGF3YWl0IGNhY2hlLmRlbGV0ZSh1cmwsIHRoaXMuX21hdGNoT3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgaWYgKHVybHNFeHBpcmVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZ3JvdXBDb2xsYXBzZWQoYEV4cGlyZWQgJHt1cmxzRXhwaXJlZC5sZW5ndGh9IGAgKyBgJHt1cmxzRXhwaXJlZC5sZW5ndGggPT09IDEgPyBcImVudHJ5XCIgOiBcImVudHJpZXNcIn0gYW5kIHJlbW92ZWQgYCArIGAke3VybHNFeHBpcmVkLmxlbmd0aCA9PT0gMSA/IFwiaXRcIiA6IFwidGhlbVwifSBmcm9tIHRoZSBgICsgYCcke3RoaXMuX2NhY2hlTmFtZX0nIGNhY2hlLmApO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coYEV4cGlyZWQgdGhlIGZvbGxvd2luZyAke3VybHNFeHBpcmVkLmxlbmd0aCA9PT0gMSA/IFwiVVJMXCIgOiBcIlVSTHNcIn06YCk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCB1cmwgb2YgdXJsc0V4cGlyZWQpe1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKGAgICAgJHt1cmx9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxvZ2dlci5ncm91cEVuZCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoXCJDYWNoZSBleHBpcmF0aW9uIHJhbiBhbmQgZm91bmQgbm8gZW50cmllcyB0byByZW1vdmUuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2lzUnVubmluZyA9IGZhbHNlO1xuICAgICAgICBpZiAodGhpcy5fcmVydW5SZXF1ZXN0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlcnVuUmVxdWVzdGVkID0gZmFsc2U7XG4gICAgICAgICAgICB2b2lkIHRoaXMuZXhwaXJlRW50cmllcygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIHVwZGF0ZVRpbWVzdGFtcCh1cmwpIHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzVHlwZSh1cmwsIFwic3RyaW5nXCIsIHtcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiQ2FjaGVFeHBpcmF0aW9uXCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwidXBkYXRlVGltZXN0YW1wXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcInVybFwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLl90aW1lc3RhbXBNb2RlbC5zZXRUaW1lc3RhbXAodXJsLCBEYXRlLm5vdygpKTtcbiAgICB9XG4gICAgYXN5bmMgaXNVUkxFeHBpcmVkKHVybCkge1xuICAgICAgICBpZiAoIXRoaXMuX21heEFnZVNlY29uZHMpIHtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiZXhwaXJlZC10ZXN0LXdpdGhvdXQtbWF4LWFnZVwiLCB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZE5hbWU6IFwiaXNVUkxFeHBpcmVkXCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJtYXhBZ2VTZWNvbmRzXCJcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0aW1lc3RhbXAgPSBhd2FpdCB0aGlzLl90aW1lc3RhbXBNb2RlbC5nZXRUaW1lc3RhbXAodXJsKTtcbiAgICAgICAgY29uc3QgZXhwaXJlT2xkZXJUaGFuID0gRGF0ZS5ub3coKSAtIHRoaXMuX21heEFnZVNlY29uZHMgKiAxMDAwO1xuICAgICAgICByZXR1cm4gdGltZXN0YW1wICE9PSB1bmRlZmluZWQgPyB0aW1lc3RhbXAgPCBleHBpcmVPbGRlclRoYW4gOiB0cnVlO1xuICAgIH1cbiAgICBhc3luYyBkZWxldGUoKSB7XG4gICAgICAgIHRoaXMuX3JlcnVuUmVxdWVzdGVkID0gZmFsc2U7XG4gICAgICAgIGF3YWl0IHRoaXMuX3RpbWVzdGFtcE1vZGVsLmV4cGlyZUVudHJpZXMoTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKTtcbiAgICB9XG59XG5cbmNvbnN0IHJlZ2lzdGVyUXVvdGFFcnJvckNhbGxiYWNrID0gKGNhbGxiYWNrKT0+e1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzVHlwZShjYWxsYmFjaywgXCJmdW5jdGlvblwiLCB7XG4gICAgICAgICAgICBtb2R1bGVOYW1lOiBcIkBzZXJ3aXN0L2NvcmVcIixcbiAgICAgICAgICAgIGZ1bmNOYW1lOiBcInJlZ2lzdGVyXCIsXG4gICAgICAgICAgICBwYXJhbU5hbWU6IFwiY2FsbGJhY2tcIlxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcXVvdGFFcnJvckNhbGxiYWNrcy5hZGQoY2FsbGJhY2spO1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgbG9nZ2VyLmxvZyhcIlJlZ2lzdGVyZWQgYSBjYWxsYmFjayB0byByZXNwb25kIHRvIHF1b3RhIGVycm9ycy5cIiwgY2FsbGJhY2spO1xuICAgIH1cbn07XG5cbmNsYXNzIEV4cGlyYXRpb25QbHVnaW4ge1xuICAgIF9jb25maWc7XG4gICAgX2NhY2hlRXhwaXJhdGlvbnM7XG4gICAgY29uc3RydWN0b3IoY29uZmlnID0ge30pe1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBpZiAoIShjb25maWcubWF4RW50cmllcyB8fCBjb25maWcubWF4QWdlU2Vjb25kcykpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwibWF4LWVudHJpZXMtb3ItYWdlLXJlcXVpcmVkXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJFeHBpcmF0aW9uUGx1Z2luXCIsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNvbnN0cnVjdG9yXCJcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjb25maWcubWF4RW50cmllcykge1xuICAgICAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc1R5cGUoY29uZmlnLm1heEVudHJpZXMsIFwibnVtYmVyXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJFeHBpcmF0aW9uUGx1Z2luXCIsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNvbnN0cnVjdG9yXCIsXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJjb25maWcubWF4RW50cmllc1wiXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY29uZmlnLm1heEFnZVNlY29uZHMpIHtcbiAgICAgICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNUeXBlKGNvbmZpZy5tYXhBZ2VTZWNvbmRzLCBcIm51bWJlclwiLCB7XG4gICAgICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiRXhwaXJhdGlvblBsdWdpblwiLFxuICAgICAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJjb25zdHJ1Y3RvclwiLFxuICAgICAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwiY29uZmlnLm1heEFnZVNlY29uZHNcIlxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvbmZpZy5tYXhBZ2VGcm9tKSB7XG4gICAgICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzVHlwZShjb25maWcubWF4QWdlRnJvbSwgXCJzdHJpbmdcIiwge1xuICAgICAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIkV4cGlyYXRpb25QbHVnaW5cIixcbiAgICAgICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiY29uc3RydWN0b3JcIixcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcImNvbmZpZy5tYXhBZ2VGcm9tXCJcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG4gICAgICAgIHRoaXMuX2NhY2hlRXhwaXJhdGlvbnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGlmICghdGhpcy5fY29uZmlnLm1heEFnZUZyb20pIHtcbiAgICAgICAgICAgIHRoaXMuX2NvbmZpZy5tYXhBZ2VGcm9tID0gXCJsYXN0LWZldGNoZWRcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fY29uZmlnLnB1cmdlT25RdW90YUVycm9yKSB7XG4gICAgICAgICAgICByZWdpc3RlclF1b3RhRXJyb3JDYWxsYmFjaygoKT0+dGhpcy5kZWxldGVDYWNoZUFuZE1ldGFkYXRhKCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIF9nZXRDYWNoZUV4cGlyYXRpb24oY2FjaGVOYW1lKSB7XG4gICAgICAgIGlmIChjYWNoZU5hbWUgPT09IGNhY2hlTmFtZXMkMS5nZXRSdW50aW1lTmFtZSgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiZXhwaXJlLWN1c3RvbS1jYWNoZXMtb25seVwiKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY2FjaGVFeHBpcmF0aW9uID0gdGhpcy5fY2FjaGVFeHBpcmF0aW9ucy5nZXQoY2FjaGVOYW1lKTtcbiAgICAgICAgaWYgKCFjYWNoZUV4cGlyYXRpb24pIHtcbiAgICAgICAgICAgIGNhY2hlRXhwaXJhdGlvbiA9IG5ldyBDYWNoZUV4cGlyYXRpb24oY2FjaGVOYW1lLCB0aGlzLl9jb25maWcpO1xuICAgICAgICAgICAgdGhpcy5fY2FjaGVFeHBpcmF0aW9ucy5zZXQoY2FjaGVOYW1lLCBjYWNoZUV4cGlyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWNoZUV4cGlyYXRpb247XG4gICAgfVxuICAgIGNhY2hlZFJlc3BvbnNlV2lsbEJlVXNlZCh7IGV2ZW50LCBjYWNoZU5hbWUsIHJlcXVlc3QsIGNhY2hlZFJlc3BvbnNlIH0pIHtcbiAgICAgICAgaWYgKCFjYWNoZWRSZXNwb25zZSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXNGcmVzaCA9IHRoaXMuX2lzUmVzcG9uc2VEYXRlRnJlc2goY2FjaGVkUmVzcG9uc2UpO1xuICAgICAgICBjb25zdCBjYWNoZUV4cGlyYXRpb24gPSB0aGlzLl9nZXRDYWNoZUV4cGlyYXRpb24oY2FjaGVOYW1lKTtcbiAgICAgICAgY29uc3QgaXNNYXhBZ2VGcm9tTGFzdFVzZWQgPSB0aGlzLl9jb25maWcubWF4QWdlRnJvbSA9PT0gXCJsYXN0LXVzZWRcIjtcbiAgICAgICAgY29uc3QgZG9uZSA9IChhc3luYyAoKT0+e1xuICAgICAgICAgICAgaWYgKGlzTWF4QWdlRnJvbUxhc3RVc2VkKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY2FjaGVFeHBpcmF0aW9uLnVwZGF0ZVRpbWVzdGFtcChyZXF1ZXN0LnVybCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCBjYWNoZUV4cGlyYXRpb24uZXhwaXJlRW50cmllcygpO1xuICAgICAgICB9KSgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZXZlbnQud2FpdFVudGlsKGRvbmUpO1xuICAgICAgICB9IGNhdGNoICB7XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgRmV0Y2hFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybihgVW5hYmxlIHRvIGVuc3VyZSBzZXJ2aWNlIHdvcmtlciBzdGF5cyBhbGl2ZSB3aGVuIHVwZGF0aW5nIGNhY2hlIGVudHJ5IGZvciAnJHtnZXRGcmllbmRseVVSTChldmVudC5yZXF1ZXN0LnVybCl9Jy5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlzRnJlc2ggPyBjYWNoZWRSZXNwb25zZSA6IG51bGw7XG4gICAgfVxuICAgIF9pc1Jlc3BvbnNlRGF0ZUZyZXNoKGNhY2hlZFJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnN0IGlzTWF4QWdlRnJvbUxhc3RVc2VkID0gdGhpcy5fY29uZmlnLm1heEFnZUZyb20gPT09IFwibGFzdC11c2VkXCI7XG4gICAgICAgIGlmIChpc01heEFnZUZyb21MYXN0VXNlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgaWYgKCF0aGlzLl9jb25maWcubWF4QWdlU2Vjb25kcykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGF0ZUhlYWRlclRpbWVzdGFtcCA9IHRoaXMuX2dldERhdGVIZWFkZXJUaW1lc3RhbXAoY2FjaGVkUmVzcG9uc2UpO1xuICAgICAgICBpZiAoZGF0ZUhlYWRlclRpbWVzdGFtcCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGVIZWFkZXJUaW1lc3RhbXAgPj0gbm93IC0gdGhpcy5fY29uZmlnLm1heEFnZVNlY29uZHMgKiAxMDAwO1xuICAgIH1cbiAgICBfZ2V0RGF0ZUhlYWRlclRpbWVzdGFtcChjYWNoZWRSZXNwb25zZSkge1xuICAgICAgICBpZiAoIWNhY2hlZFJlc3BvbnNlLmhlYWRlcnMuaGFzKFwiZGF0ZVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGF0ZUhlYWRlciA9IGNhY2hlZFJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiZGF0ZVwiKTtcbiAgICAgICAgY29uc3QgcGFyc2VkRGF0ZSA9IG5ldyBEYXRlKGRhdGVIZWFkZXIpO1xuICAgICAgICBjb25zdCBoZWFkZXJUaW1lID0gcGFyc2VkRGF0ZS5nZXRUaW1lKCk7XG4gICAgICAgIGlmIChOdW1iZXIuaXNOYU4oaGVhZGVyVGltZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoZWFkZXJUaW1lO1xuICAgIH1cbiAgICBhc3luYyBjYWNoZURpZFVwZGF0ZSh7IGNhY2hlTmFtZSwgcmVxdWVzdCB9KSB7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc1R5cGUoY2FjaGVOYW1lLCBcInN0cmluZ1wiLCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIlBsdWdpblwiLFxuICAgICAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNhY2hlRGlkVXBkYXRlXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcImNhY2hlTmFtZVwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc0luc3RhbmNlKHJlcXVlc3QsIFJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiUGx1Z2luXCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiY2FjaGVEaWRVcGRhdGVcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwicmVxdWVzdFwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjYWNoZUV4cGlyYXRpb24gPSB0aGlzLl9nZXRDYWNoZUV4cGlyYXRpb24oY2FjaGVOYW1lKTtcbiAgICAgICAgYXdhaXQgY2FjaGVFeHBpcmF0aW9uLnVwZGF0ZVRpbWVzdGFtcChyZXF1ZXN0LnVybCk7XG4gICAgICAgIGF3YWl0IGNhY2hlRXhwaXJhdGlvbi5leHBpcmVFbnRyaWVzKCk7XG4gICAgfVxuICAgIGFzeW5jIGRlbGV0ZUNhY2hlQW5kTWV0YWRhdGEoKSB7XG4gICAgICAgIGZvciAoY29uc3QgW2NhY2hlTmFtZSwgY2FjaGVFeHBpcmF0aW9uXSBvZiB0aGlzLl9jYWNoZUV4cGlyYXRpb25zKXtcbiAgICAgICAgICAgIGF3YWl0IHNlbGYuY2FjaGVzLmRlbGV0ZShjYWNoZU5hbWUpO1xuICAgICAgICAgICAgYXdhaXQgY2FjaGVFeHBpcmF0aW9uLmRlbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NhY2hlRXhwaXJhdGlvbnMgPSBuZXcgTWFwKCk7XG4gICAgfVxufVxuXG5jb25zdCBRVUVVRV9OQU1FID0gXCJzZXJ3aXN0LWdvb2dsZS1hbmFseXRpY3NcIjtcbmNvbnN0IE1BWF9SRVRFTlRJT05fVElNRSA9IDYwICogNDg7XG5jb25zdCBHT09HTEVfQU5BTFlUSUNTX0hPU1QgPSBcInd3dy5nb29nbGUtYW5hbHl0aWNzLmNvbVwiO1xuY29uc3QgR1RNX0hPU1QgPSBcInd3dy5nb29nbGV0YWdtYW5hZ2VyLmNvbVwiO1xuY29uc3QgQU5BTFlUSUNTX0pTX1BBVEggPSBcIi9hbmFseXRpY3MuanNcIjtcbmNvbnN0IEdUQUdfSlNfUEFUSCA9IFwiL2d0YWcvanNcIjtcbmNvbnN0IEdUTV9KU19QQVRIID0gXCIvZ3RtLmpzXCI7XG5jb25zdCBDT0xMRUNUX1BBVEhTX1JFR0VYID0gL15cXC8oXFx3K1xcLyk/Y29sbGVjdC87XG5cbmNvbnN0IGNyZWF0ZU9uU3luY0NhbGxiYWNrID0gKGNvbmZpZyk9PntcbiAgICByZXR1cm4gYXN5bmMgKHsgcXVldWUgfSk9PntcbiAgICAgICAgbGV0IGVudHJ5O1xuICAgICAgICB3aGlsZShlbnRyeSA9IGF3YWl0IHF1ZXVlLnNoaWZ0UmVxdWVzdCgpKXtcbiAgICAgICAgICAgIGNvbnN0IHsgcmVxdWVzdCwgdGltZXN0YW1wIH0gPSBlbnRyeTtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxdWVzdC51cmwpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJhbXMgPSByZXF1ZXN0Lm1ldGhvZCA9PT0gXCJQT1NUXCIgPyBuZXcgVVJMU2VhcmNoUGFyYW1zKGF3YWl0IHJlcXVlc3QuY2xvbmUoKS50ZXh0KCkpIDogdXJsLnNlYXJjaFBhcmFtcztcbiAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW5hbEhpdFRpbWUgPSB0aW1lc3RhbXAgLSAoTnVtYmVyKHBhcmFtcy5nZXQoXCJxdFwiKSkgfHwgMCk7XG4gICAgICAgICAgICAgICAgY29uc3QgcXVldWVUaW1lID0gRGF0ZS5ub3coKSAtIG9yaWdpbmFsSGl0VGltZTtcbiAgICAgICAgICAgICAgICBwYXJhbXMuc2V0KFwicXRcIiwgU3RyaW5nKHF1ZXVlVGltZSkpO1xuICAgICAgICAgICAgICAgIGlmIChjb25maWcucGFyYW1ldGVyT3ZlcnJpZGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcGFyYW0gb2YgT2JqZWN0LmtleXMoY29uZmlnLnBhcmFtZXRlck92ZXJyaWRlcykpe1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjb25maWcucGFyYW1ldGVyT3ZlcnJpZGVzW3BhcmFtXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcy5zZXQocGFyYW0sIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5oaXRGaWx0ZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcuaGl0RmlsdGVyLmNhbGwobnVsbCwgcGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXdhaXQgZmV0Y2gobmV3IFJlcXVlc3QodXJsLm9yaWdpbiArIHVybC5wYXRobmFtZSwge1xuICAgICAgICAgICAgICAgICAgICBib2R5OiBwYXJhbXMudG9TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICAgICAgbW9kZTogXCJjb3JzXCIsXG4gICAgICAgICAgICAgICAgICAgIGNyZWRlbnRpYWxzOiBcIm9taXRcIixcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJ0ZXh0L3BsYWluXCJcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coYFJlcXVlc3QgZm9yICcke2dldEZyaWVuZGx5VVJMKHVybC5ocmVmKX0nIGhhcyBiZWVuIHJlcGxheWVkYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcXVldWUudW5zaGlmdFJlcXVlc3QoZW50cnkpO1xuICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhgUmVxdWVzdCBmb3IgJyR7Z2V0RnJpZW5kbHlVUkwodXJsLmhyZWYpfScgZmFpbGVkIHRvIHJlcGxheSwgcHV0dGluZyBpdCBiYWNrIGluIHRoZSBxdWV1ZS5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGxvZ2dlci5sb2coXCJBbGwgR29vZ2xlIEFuYWx5dGljcyByZXF1ZXN0IHN1Y2Nlc3NmdWxseSByZXBsYXllZDsgXCIgKyBcInRoZSBxdWV1ZSBpcyBub3cgZW1wdHkhXCIpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5jb25zdCBjcmVhdGVDb2xsZWN0Um91dGVzID0gKGJnU3luY1BsdWdpbik9PntcbiAgICBjb25zdCBtYXRjaCA9ICh7IHVybCB9KT0+dXJsLmhvc3RuYW1lID09PSBHT09HTEVfQU5BTFlUSUNTX0hPU1QgJiYgQ09MTEVDVF9QQVRIU19SRUdFWC50ZXN0KHVybC5wYXRobmFtZSk7XG4gICAgY29uc3QgaGFuZGxlciA9IG5ldyBOZXR3b3JrT25seSh7XG4gICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgIGJnU3luY1BsdWdpblxuICAgICAgICBdXG4gICAgfSk7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgbmV3IFJvdXRlKG1hdGNoLCBoYW5kbGVyLCBcIkdFVFwiKSxcbiAgICAgICAgbmV3IFJvdXRlKG1hdGNoLCBoYW5kbGVyLCBcIlBPU1RcIilcbiAgICBdO1xufTtcbmNvbnN0IGNyZWF0ZUFuYWx5dGljc0pzUm91dGUgPSAoY2FjaGVOYW1lKT0+e1xuICAgIGNvbnN0IG1hdGNoID0gKHsgdXJsIH0pPT51cmwuaG9zdG5hbWUgPT09IEdPT0dMRV9BTkFMWVRJQ1NfSE9TVCAmJiB1cmwucGF0aG5hbWUgPT09IEFOQUxZVElDU19KU19QQVRIO1xuICAgIGNvbnN0IGhhbmRsZXIgPSBuZXcgTmV0d29ya0ZpcnN0KHtcbiAgICAgICAgY2FjaGVOYW1lXG4gICAgfSk7XG4gICAgcmV0dXJuIG5ldyBSb3V0ZShtYXRjaCwgaGFuZGxlciwgXCJHRVRcIik7XG59O1xuY29uc3QgY3JlYXRlR3RhZ0pzUm91dGUgPSAoY2FjaGVOYW1lKT0+e1xuICAgIGNvbnN0IG1hdGNoID0gKHsgdXJsIH0pPT51cmwuaG9zdG5hbWUgPT09IEdUTV9IT1NUICYmIHVybC5wYXRobmFtZSA9PT0gR1RBR19KU19QQVRIO1xuICAgIGNvbnN0IGhhbmRsZXIgPSBuZXcgTmV0d29ya0ZpcnN0KHtcbiAgICAgICAgY2FjaGVOYW1lXG4gICAgfSk7XG4gICAgcmV0dXJuIG5ldyBSb3V0ZShtYXRjaCwgaGFuZGxlciwgXCJHRVRcIik7XG59O1xuY29uc3QgY3JlYXRlR3RtSnNSb3V0ZSA9IChjYWNoZU5hbWUpPT57XG4gICAgY29uc3QgbWF0Y2ggPSAoeyB1cmwgfSk9PnVybC5ob3N0bmFtZSA9PT0gR1RNX0hPU1QgJiYgdXJsLnBhdGhuYW1lID09PSBHVE1fSlNfUEFUSDtcbiAgICBjb25zdCBoYW5kbGVyID0gbmV3IE5ldHdvcmtGaXJzdCh7XG4gICAgICAgIGNhY2hlTmFtZVxuICAgIH0pO1xuICAgIHJldHVybiBuZXcgUm91dGUobWF0Y2gsIGhhbmRsZXIsIFwiR0VUXCIpO1xufTtcbmNvbnN0IGluaXRpYWxpemVHb29nbGVBbmFseXRpY3MgPSAoeyBzZXJ3aXN0LCBjYWNoZU5hbWUsIC4uLm9wdGlvbnMgfSk9PntcbiAgICBjb25zdCByZXNvbHZlZENhY2hlTmFtZSA9IGNhY2hlTmFtZXMkMS5nZXRHb29nbGVBbmFseXRpY3NOYW1lKGNhY2hlTmFtZSk7XG4gICAgY29uc3QgYmdTeW5jUGx1Z2luID0gbmV3IEJhY2tncm91bmRTeW5jUGx1Z2luKFFVRVVFX05BTUUsIHtcbiAgICAgICAgbWF4UmV0ZW50aW9uVGltZTogTUFYX1JFVEVOVElPTl9USU1FLFxuICAgICAgICBvblN5bmM6IGNyZWF0ZU9uU3luY0NhbGxiYWNrKG9wdGlvbnMpXG4gICAgfSk7XG4gICAgY29uc3Qgcm91dGVzID0gW1xuICAgICAgICBjcmVhdGVHdG1Kc1JvdXRlKHJlc29sdmVkQ2FjaGVOYW1lKSxcbiAgICAgICAgY3JlYXRlQW5hbHl0aWNzSnNSb3V0ZShyZXNvbHZlZENhY2hlTmFtZSksXG4gICAgICAgIGNyZWF0ZUd0YWdKc1JvdXRlKHJlc29sdmVkQ2FjaGVOYW1lKSxcbiAgICAgICAgLi4uY3JlYXRlQ29sbGVjdFJvdXRlcyhiZ1N5bmNQbHVnaW4pXG4gICAgXTtcbiAgICBmb3IgKGNvbnN0IHJvdXRlIG9mIHJvdXRlcyl7XG4gICAgICAgIHNlcndpc3QucmVnaXN0ZXJSb3V0ZShyb3V0ZSk7XG4gICAgfVxufTtcblxuY2xhc3MgUHJlY2FjaGVGYWxsYmFja1BsdWdpbiB7XG4gICAgX2ZhbGxiYWNrVXJscztcbiAgICBfc2Vyd2lzdDtcbiAgICBjb25zdHJ1Y3Rvcih7IGZhbGxiYWNrVXJscywgc2Vyd2lzdCB9KXtcbiAgICAgICAgdGhpcy5fZmFsbGJhY2tVcmxzID0gZmFsbGJhY2tVcmxzO1xuICAgICAgICB0aGlzLl9zZXJ3aXN0ID0gc2Vyd2lzdDtcbiAgICB9XG4gICAgYXN5bmMgaGFuZGxlckRpZEVycm9yKHBhcmFtKSB7XG4gICAgICAgIGZvciAoY29uc3QgZmFsbGJhY2sgb2YgdGhpcy5fZmFsbGJhY2tVcmxzKXtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZmFsbGJhY2sgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmYWxsYmFja1Jlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2Vyd2lzdC5tYXRjaFByZWNhY2hlKGZhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICBpZiAoZmFsbGJhY2tSZXNwb25zZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxsYmFja1Jlc3BvbnNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZmFsbGJhY2subWF0Y2hlcihwYXJhbSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmYWxsYmFja1Jlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2Vyd2lzdC5tYXRjaFByZWNhY2hlKGZhbGxiYWNrLnVybCk7XG4gICAgICAgICAgICAgICAgaWYgKGZhbGxiYWNrUmVzcG9uc2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsbGJhY2tSZXNwb25zZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG59XG5cbmNvbnN0IGNhbGN1bGF0ZUVmZmVjdGl2ZUJvdW5kYXJpZXMgPSAoYmxvYiwgc3RhcnQsIGVuZCk9PntcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc0luc3RhbmNlKGJsb2IsIEJsb2IsIHtcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwiQHNlcndpc3QvcmFuZ2UtcmVxdWVzdHNcIixcbiAgICAgICAgICAgIGZ1bmNOYW1lOiBcImNhbGN1bGF0ZUVmZmVjdGl2ZUJvdW5kYXJpZXNcIixcbiAgICAgICAgICAgIHBhcmFtTmFtZTogXCJibG9iXCJcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IGJsb2JTaXplID0gYmxvYi5zaXplO1xuICAgIGlmIChlbmQgJiYgZW5kID4gYmxvYlNpemUgfHwgc3RhcnQgJiYgc3RhcnQgPCAwKSB7XG4gICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJyYW5nZS1ub3Qtc2F0aXNmaWFibGVcIiwge1xuICAgICAgICAgICAgc2l6ZTogYmxvYlNpemUsXG4gICAgICAgICAgICBlbmQsXG4gICAgICAgICAgICBzdGFydFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbGV0IGVmZmVjdGl2ZVN0YXJ0O1xuICAgIGxldCBlZmZlY3RpdmVFbmQ7XG4gICAgaWYgKHN0YXJ0ICE9PSB1bmRlZmluZWQgJiYgZW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZWZmZWN0aXZlU3RhcnQgPSBzdGFydDtcbiAgICAgICAgZWZmZWN0aXZlRW5kID0gZW5kICsgMTtcbiAgICB9IGVsc2UgaWYgKHN0YXJ0ICE9PSB1bmRlZmluZWQgJiYgZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZWZmZWN0aXZlU3RhcnQgPSBzdGFydDtcbiAgICAgICAgZWZmZWN0aXZlRW5kID0gYmxvYlNpemU7XG4gICAgfSBlbHNlIGlmIChlbmQgIT09IHVuZGVmaW5lZCAmJiBzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGVmZmVjdGl2ZVN0YXJ0ID0gYmxvYlNpemUgLSBlbmQ7XG4gICAgICAgIGVmZmVjdGl2ZUVuZCA9IGJsb2JTaXplO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFydDogZWZmZWN0aXZlU3RhcnQsXG4gICAgICAgIGVuZDogZWZmZWN0aXZlRW5kXG4gICAgfTtcbn07XG5cbmNvbnN0IHBhcnNlUmFuZ2VIZWFkZXIgPSAocmFuZ2VIZWFkZXIpPT57XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNUeXBlKHJhbmdlSGVhZGVyLCBcInN0cmluZ1wiLCB7XG4gICAgICAgICAgICBtb2R1bGVOYW1lOiBcIkBzZXJ3aXN0L3JhbmdlLXJlcXVlc3RzXCIsXG4gICAgICAgICAgICBmdW5jTmFtZTogXCJwYXJzZVJhbmdlSGVhZGVyXCIsXG4gICAgICAgICAgICBwYXJhbU5hbWU6IFwicmFuZ2VIZWFkZXJcIlxuICAgICAgICB9KTtcbiAgICB9XG4gICAgY29uc3Qgbm9ybWFsaXplZFJhbmdlSGVhZGVyID0gcmFuZ2VIZWFkZXIudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKCFub3JtYWxpemVkUmFuZ2VIZWFkZXIuc3RhcnRzV2l0aChcImJ5dGVzPVwiKSkge1xuICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwidW5pdC1tdXN0LWJlLWJ5dGVzXCIsIHtcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRSYW5nZUhlYWRlclxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKG5vcm1hbGl6ZWRSYW5nZUhlYWRlci5pbmNsdWRlcyhcIixcIikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFNlcndpc3RFcnJvcihcInNpbmdsZS1yYW5nZS1vbmx5XCIsIHtcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRSYW5nZUhlYWRlclxuICAgICAgICB9KTtcbiAgICB9XG4gICAgY29uc3QgcmFuZ2VQYXJ0cyA9IC8oXFxkKiktKFxcZCopLy5leGVjKG5vcm1hbGl6ZWRSYW5nZUhlYWRlcik7XG4gICAgaWYgKCFyYW5nZVBhcnRzIHx8ICEocmFuZ2VQYXJ0c1sxXSB8fCByYW5nZVBhcnRzWzJdKSkge1xuICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiaW52YWxpZC1yYW5nZS12YWx1ZXNcIiwge1xuICAgICAgICAgICAgbm9ybWFsaXplZFJhbmdlSGVhZGVyXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFydDogcmFuZ2VQYXJ0c1sxXSA9PT0gXCJcIiA/IHVuZGVmaW5lZCA6IE51bWJlcihyYW5nZVBhcnRzWzFdKSxcbiAgICAgICAgZW5kOiByYW5nZVBhcnRzWzJdID09PSBcIlwiID8gdW5kZWZpbmVkIDogTnVtYmVyKHJhbmdlUGFydHNbMl0pXG4gICAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZVBhcnRpYWxSZXNwb25zZSA9IGFzeW5jIChyZXF1ZXN0LCBvcmlnaW5hbFJlc3BvbnNlKT0+e1xuICAgIHRyeSB7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc0luc3RhbmNlKHJlcXVlc3QsIFJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcIkBzZXJ3aXN0L3JhbmdlLXJlcXVlc3RzXCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiY3JlYXRlUGFydGlhbFJlc3BvbnNlXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcInJlcXVlc3RcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNJbnN0YW5jZShvcmlnaW5hbFJlc3BvbnNlLCBSZXNwb25zZSwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwiQHNlcndpc3QvcmFuZ2UtcmVxdWVzdHNcIixcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJjcmVhdGVQYXJ0aWFsUmVzcG9uc2VcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwib3JpZ2luYWxSZXNwb25zZVwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3JpZ2luYWxSZXNwb25zZS5zdGF0dXMgPT09IDIwNikge1xuICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsUmVzcG9uc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmFuZ2VIZWFkZXIgPSByZXF1ZXN0LmhlYWRlcnMuZ2V0KFwicmFuZ2VcIik7XG4gICAgICAgIGlmICghcmFuZ2VIZWFkZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJuby1yYW5nZS1oZWFkZXJcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYm91bmRhcmllcyA9IHBhcnNlUmFuZ2VIZWFkZXIocmFuZ2VIZWFkZXIpO1xuICAgICAgICBjb25zdCBvcmlnaW5hbEJsb2IgPSBhd2FpdCBvcmlnaW5hbFJlc3BvbnNlLmJsb2IoKTtcbiAgICAgICAgY29uc3QgZWZmZWN0aXZlQm91bmRhcmllcyA9IGNhbGN1bGF0ZUVmZmVjdGl2ZUJvdW5kYXJpZXMob3JpZ2luYWxCbG9iLCBib3VuZGFyaWVzLnN0YXJ0LCBib3VuZGFyaWVzLmVuZCk7XG4gICAgICAgIGNvbnN0IHNsaWNlZEJsb2IgPSBvcmlnaW5hbEJsb2Iuc2xpY2UoZWZmZWN0aXZlQm91bmRhcmllcy5zdGFydCwgZWZmZWN0aXZlQm91bmRhcmllcy5lbmQpO1xuICAgICAgICBjb25zdCBzbGljZWRCbG9iU2l6ZSA9IHNsaWNlZEJsb2Iuc2l6ZTtcbiAgICAgICAgY29uc3Qgc2xpY2VkUmVzcG9uc2UgPSBuZXcgUmVzcG9uc2Uoc2xpY2VkQmxvYiwge1xuICAgICAgICAgICAgc3RhdHVzOiAyMDYsXG4gICAgICAgICAgICBzdGF0dXNUZXh0OiBcIlBhcnRpYWwgQ29udGVudFwiLFxuICAgICAgICAgICAgaGVhZGVyczogb3JpZ2luYWxSZXNwb25zZS5oZWFkZXJzXG4gICAgICAgIH0pO1xuICAgICAgICBzbGljZWRSZXNwb25zZS5oZWFkZXJzLnNldChcIkNvbnRlbnQtTGVuZ3RoXCIsIFN0cmluZyhzbGljZWRCbG9iU2l6ZSkpO1xuICAgICAgICBzbGljZWRSZXNwb25zZS5oZWFkZXJzLnNldChcIkNvbnRlbnQtUmFuZ2VcIiwgYGJ5dGVzICR7ZWZmZWN0aXZlQm91bmRhcmllcy5zdGFydH0tJHtlZmZlY3RpdmVCb3VuZGFyaWVzLmVuZCAtIDF9L2AgKyBgJHtvcmlnaW5hbEJsb2Iuc2l6ZX1gKTtcbiAgICAgICAgcmV0dXJuIHNsaWNlZFJlc3BvbnNlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKFwiVW5hYmxlIHRvIGNvbnN0cnVjdCBhIHBhcnRpYWwgcmVzcG9uc2U7IHJldHVybmluZyBhIFwiICsgXCI0MTYgUmFuZ2UgTm90IFNhdGlzZmlhYmxlIHJlc3BvbnNlIGluc3RlYWQuXCIpO1xuICAgICAgICAgICAgbG9nZ2VyLmdyb3VwQ29sbGFwc2VkKFwiVmlldyBkZXRhaWxzIGhlcmUuXCIpO1xuICAgICAgICAgICAgbG9nZ2VyLmxvZyhlcnJvcik7XG4gICAgICAgICAgICBsb2dnZXIubG9nKHJlcXVlc3QpO1xuICAgICAgICAgICAgbG9nZ2VyLmxvZyhvcmlnaW5hbFJlc3BvbnNlKTtcbiAgICAgICAgICAgIGxvZ2dlci5ncm91cEVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoXCJcIiwge1xuICAgICAgICAgICAgc3RhdHVzOiA0MTYsXG4gICAgICAgICAgICBzdGF0dXNUZXh0OiBcIlJhbmdlIE5vdCBTYXRpc2ZpYWJsZVwiXG4gICAgICAgIH0pO1xuICAgIH1cbn07XG5cbmNsYXNzIFJhbmdlUmVxdWVzdHNQbHVnaW4ge1xuICAgIGNhY2hlZFJlc3BvbnNlV2lsbEJlVXNlZCA9IGFzeW5jICh7IHJlcXVlc3QsIGNhY2hlZFJlc3BvbnNlIH0pPT57XG4gICAgICAgIGlmIChjYWNoZWRSZXNwb25zZSAmJiByZXF1ZXN0LmhlYWRlcnMuaGFzKFwicmFuZ2VcIikpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCBjcmVhdGVQYXJ0aWFsUmVzcG9uc2UocmVxdWVzdCwgY2FjaGVkUmVzcG9uc2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWNoZWRSZXNwb25zZTtcbiAgICB9O1xufVxuXG5jbGFzcyBDYWNoZUZpcnN0IGV4dGVuZHMgU3RyYXRlZ3kge1xuICAgIGFzeW5jIF9oYW5kbGUocmVxdWVzdCwgaGFuZGxlcikge1xuICAgICAgICBjb25zdCBsb2dzID0gW107XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGZpbmFsQXNzZXJ0RXhwb3J0cy5pc0luc3RhbmNlKHJlcXVlc3QsIFJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBcInNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IHRoaXMuY29uc3RydWN0b3IubmFtZSxcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJtYWtlUmVxdWVzdFwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJyZXF1ZXN0XCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXNwb25zZSA9IGF3YWl0IGhhbmRsZXIuY2FjaGVNYXRjaChyZXF1ZXN0KTtcbiAgICAgICAgbGV0IGVycm9yO1xuICAgICAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgbG9ncy5wdXNoKGBObyByZXNwb25zZSBmb3VuZCBpbiB0aGUgJyR7dGhpcy5jYWNoZU5hbWV9JyBjYWNoZS4gV2lsbCByZXNwb25kIHdpdGggYSBuZXR3b3JrIHJlcXVlc3QuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgaGFuZGxlci5mZXRjaEFuZENhY2hlUHV0KHJlcXVlc3QpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gZXJyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9ncy5wdXNoKFwiR290IHJlc3BvbnNlIGZyb20gbmV0d29yay5cIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbG9ncy5wdXNoKFwiVW5hYmxlIHRvIGdldCBhIHJlc3BvbnNlIGZyb20gdGhlIG5ldHdvcmsuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBsb2dzLnB1c2goYEZvdW5kIGEgY2FjaGVkIHJlc3BvbnNlIGluIHRoZSAnJHt0aGlzLmNhY2hlTmFtZX0nIGNhY2hlLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGxvZ2dlci5ncm91cENvbGxhcHNlZChtZXNzYWdlcy5zdHJhdGVneVN0YXJ0KHRoaXMuY29uc3RydWN0b3IubmFtZSwgcmVxdWVzdCkpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBsb2cgb2YgbG9ncyl7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhsb2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWVzc2FnZXMucHJpbnRGaW5hbFJlc3BvbnNlKHJlc3BvbnNlKTtcbiAgICAgICAgICAgIGxvZ2dlci5ncm91cEVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJuby1yZXNwb25zZVwiLCB7XG4gICAgICAgICAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cbn1cblxuY2xhc3MgQ2FjaGVPbmx5IGV4dGVuZHMgU3RyYXRlZ3kge1xuICAgIGFzeW5jIF9oYW5kbGUocmVxdWVzdCwgaGFuZGxlcikge1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNJbnN0YW5jZShyZXF1ZXN0LCBSZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwibWFrZVJlcXVlc3RcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwicmVxdWVzdFwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGhhbmRsZXIuY2FjaGVNYXRjaChyZXF1ZXN0KTtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgbG9nZ2VyLmdyb3VwQ29sbGFwc2VkKG1lc3NhZ2VzLnN0cmF0ZWd5U3RhcnQodGhpcy5jb25zdHJ1Y3Rvci5uYW1lLCByZXF1ZXN0KSk7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIubG9nKGBGb3VuZCBhIGNhY2hlZCByZXNwb25zZSBpbiB0aGUgJyR7dGhpcy5jYWNoZU5hbWV9JyBjYWNoZS5gKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlcy5wcmludEZpbmFsUmVzcG9uc2UocmVzcG9uc2UpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIubG9nKGBObyByZXNwb25zZSBmb3VuZCBpbiB0aGUgJyR7dGhpcy5jYWNoZU5hbWV9JyBjYWNoZS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxvZ2dlci5ncm91cEVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJuby1yZXNwb25zZVwiLCB7XG4gICAgICAgICAgICAgICAgdXJsOiByZXF1ZXN0LnVybFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cbn1cblxuY2xhc3MgU3RhbGVXaGlsZVJldmFsaWRhdGUgZXh0ZW5kcyBTdHJhdGVneSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KXtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIGlmICghdGhpcy5wbHVnaW5zLnNvbWUoKHApPT5cImNhY2hlV2lsbFVwZGF0ZVwiIGluIHApKSB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMudW5zaGlmdChjYWNoZU9rQW5kT3BhcXVlUGx1Z2luKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBfaGFuZGxlKHJlcXVlc3QsIGhhbmRsZXIpIHtcbiAgICAgICAgY29uc3QgbG9ncyA9IFtdO1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNJbnN0YW5jZShyZXF1ZXN0LCBSZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiaGFuZGxlXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcInJlcXVlc3RcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmV0Y2hBbmRDYWNoZVByb21pc2UgPSBoYW5kbGVyLmZldGNoQW5kQ2FjaGVQdXQocmVxdWVzdCkuY2F0Y2goKCk9Pnt9KTtcbiAgICAgICAgdm9pZCBoYW5kbGVyLndhaXRVbnRpbChmZXRjaEFuZENhY2hlUHJvbWlzZSk7XG4gICAgICAgIGxldCByZXNwb25zZSA9IGF3YWl0IGhhbmRsZXIuY2FjaGVNYXRjaChyZXF1ZXN0KTtcbiAgICAgICAgbGV0IGVycm9yO1xuICAgICAgICBpZiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBsb2dzLnB1c2goYEZvdW5kIGEgY2FjaGVkIHJlc3BvbnNlIGluIHRoZSAnJHt0aGlzLmNhY2hlTmFtZX0nIGNhY2hlLiBXaWxsIHVwZGF0ZSB3aXRoIHRoZSBuZXR3b3JrIHJlc3BvbnNlIGluIHRoZSBiYWNrZ3JvdW5kLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGxvZ3MucHVzaChgTm8gcmVzcG9uc2UgZm91bmQgaW4gdGhlICcke3RoaXMuY2FjaGVOYW1lfScgY2FjaGUuIFdpbGwgd2FpdCBmb3IgdGhlIG5ldHdvcmsgcmVzcG9uc2UuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgZmV0Y2hBbmRDYWNoZVByb21pc2U7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBlcnI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGxvZ2dlci5ncm91cENvbGxhcHNlZChtZXNzYWdlcy5zdHJhdGVneVN0YXJ0KHRoaXMuY29uc3RydWN0b3IubmFtZSwgcmVxdWVzdCkpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBsb2cgb2YgbG9ncyl7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhsb2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWVzc2FnZXMucHJpbnRGaW5hbFJlc3BvbnNlKHJlc3BvbnNlKTtcbiAgICAgICAgICAgIGxvZ2dlci5ncm91cEVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJuby1yZXNwb25zZVwiLCB7XG4gICAgICAgICAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cbn1cblxuY2xhc3MgUHJlY2FjaGVSb3V0ZSBleHRlbmRzIFJvdXRlIHtcbiAgICBjb25zdHJ1Y3RvcihzZXJ3aXN0LCBvcHRpb25zKXtcbiAgICAgICAgY29uc3QgbWF0Y2ggPSAoeyByZXF1ZXN0IH0pPT57XG4gICAgICAgICAgICBjb25zdCB1cmxzVG9DYWNoZUtleXMgPSBzZXJ3aXN0LmdldFVybHNUb1ByZWNhY2hlS2V5cygpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBwb3NzaWJsZVVSTCBvZiBnZW5lcmF0ZVVSTFZhcmlhdGlvbnMocmVxdWVzdC51cmwsIG9wdGlvbnMpKXtcbiAgICAgICAgICAgICAgICBjb25zdCBjYWNoZUtleSA9IHVybHNUb0NhY2hlS2V5cy5nZXQocG9zc2libGVVUkwpO1xuICAgICAgICAgICAgICAgIGlmIChjYWNoZUtleSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlZ3JpdHkgPSBzZXJ3aXN0LmdldEludGVncml0eUZvclByZWNhY2hlS2V5KGNhY2hlS2V5KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlS2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgaW50ZWdyaXR5XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgUHJlY2FjaGluZyBkaWQgbm90IGZpbmQgYSBtYXRjaCBmb3IgJHtnZXRGcmllbmRseVVSTChyZXF1ZXN0LnVybCl9LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9O1xuICAgICAgICBzdXBlcihtYXRjaCwgc2Vyd2lzdC5wcmVjYWNoZVN0cmF0ZWd5KTtcbiAgICB9XG59XG5cbmNsYXNzIFByZWNhY2hlQ2FjaGVLZXlQbHVnaW4ge1xuICAgIF9wcmVjYWNoZUNvbnRyb2xsZXI7XG4gICAgY29uc3RydWN0b3IoeyBwcmVjYWNoZUNvbnRyb2xsZXIgfSl7XG4gICAgICAgIHRoaXMuX3ByZWNhY2hlQ29udHJvbGxlciA9IHByZWNhY2hlQ29udHJvbGxlcjtcbiAgICB9XG4gICAgY2FjaGVLZXlXaWxsQmVVc2VkID0gYXN5bmMgKHsgcmVxdWVzdCwgcGFyYW1zIH0pPT57XG4gICAgICAgIGNvbnN0IGNhY2hlS2V5ID0gcGFyYW1zPy5jYWNoZUtleSB8fCB0aGlzLl9wcmVjYWNoZUNvbnRyb2xsZXIuZ2V0UHJlY2FjaGVLZXlGb3JVcmwocmVxdWVzdC51cmwpO1xuICAgICAgICByZXR1cm4gY2FjaGVLZXkgPyBuZXcgUmVxdWVzdChjYWNoZUtleSwge1xuICAgICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzXG4gICAgICAgIH0pIDogcmVxdWVzdDtcbiAgICB9O1xufVxuXG5jb25zdCBwYXJzZVByZWNhY2hlT3B0aW9ucyA9IChzZXJ3aXN0LCBwcmVjYWNoZU9wdGlvbnMgPSB7fSk9PntcbiAgICBjb25zdCB7IGNhY2hlTmFtZTogcHJlY2FjaGVDYWNoZU5hbWUsIHBsdWdpbnM6IHByZWNhY2hlUGx1Z2lucyA9IFtdLCBmZXRjaE9wdGlvbnM6IHByZWNhY2hlRmV0Y2hPcHRpb25zLCBtYXRjaE9wdGlvbnM6IHByZWNhY2hlTWF0Y2hPcHRpb25zLCBmYWxsYmFja1RvTmV0d29yazogcHJlY2FjaGVGYWxsYmFja1RvTmV0d29yaywgZGlyZWN0b3J5SW5kZXg6IHByZWNhY2hlRGlyZWN0b3J5SW5kZXgsIGlnbm9yZVVSTFBhcmFtZXRlcnNNYXRjaGluZzogcHJlY2FjaGVJZ25vcmVVcmxzLCBjbGVhblVSTHM6IHByZWNhY2hlQ2xlYW5VcmxzLCB1cmxNYW5pcHVsYXRpb246IHByZWNhY2hlVXJsTWFuaXB1bGF0aW9uLCBjbGVhbnVwT3V0ZGF0ZWRDYWNoZXMsIGNvbmN1cnJlbmN5ID0gMTAsIG5hdmlnYXRlRmFsbGJhY2ssIG5hdmlnYXRlRmFsbGJhY2tBbGxvd2xpc3QsIG5hdmlnYXRlRmFsbGJhY2tEZW55bGlzdCB9ID0gcHJlY2FjaGVPcHRpb25zID8/IHt9O1xuICAgIHJldHVybiB7XG4gICAgICAgIHByZWNhY2hlU3RyYXRlZ3lPcHRpb25zOiB7XG4gICAgICAgICAgICBjYWNoZU5hbWU6IGNhY2hlTmFtZXMkMS5nZXRQcmVjYWNoZU5hbWUocHJlY2FjaGVDYWNoZU5hbWUpLFxuICAgICAgICAgICAgcGx1Z2luczogW1xuICAgICAgICAgICAgICAgIC4uLnByZWNhY2hlUGx1Z2lucyxcbiAgICAgICAgICAgICAgICBuZXcgUHJlY2FjaGVDYWNoZUtleVBsdWdpbih7XG4gICAgICAgICAgICAgICAgICAgIHByZWNhY2hlQ29udHJvbGxlcjogc2Vyd2lzdFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgZmV0Y2hPcHRpb25zOiBwcmVjYWNoZUZldGNoT3B0aW9ucyxcbiAgICAgICAgICAgIG1hdGNoT3B0aW9uczogcHJlY2FjaGVNYXRjaE9wdGlvbnMsXG4gICAgICAgICAgICBmYWxsYmFja1RvTmV0d29yazogcHJlY2FjaGVGYWxsYmFja1RvTmV0d29ya1xuICAgICAgICB9LFxuICAgICAgICBwcmVjYWNoZVJvdXRlT3B0aW9uczoge1xuICAgICAgICAgICAgZGlyZWN0b3J5SW5kZXg6IHByZWNhY2hlRGlyZWN0b3J5SW5kZXgsXG4gICAgICAgICAgICBpZ25vcmVVUkxQYXJhbWV0ZXJzTWF0Y2hpbmc6IHByZWNhY2hlSWdub3JlVXJscyxcbiAgICAgICAgICAgIGNsZWFuVVJMczogcHJlY2FjaGVDbGVhblVybHMsXG4gICAgICAgICAgICB1cmxNYW5pcHVsYXRpb246IHByZWNhY2hlVXJsTWFuaXB1bGF0aW9uXG4gICAgICAgIH0sXG4gICAgICAgIHByZWNhY2hlTWlzY09wdGlvbnM6IHtcbiAgICAgICAgICAgIGNsZWFudXBPdXRkYXRlZENhY2hlcyxcbiAgICAgICAgICAgIGNvbmN1cnJlbmN5LFxuICAgICAgICAgICAgbmF2aWdhdGVGYWxsYmFjayxcbiAgICAgICAgICAgIG5hdmlnYXRlRmFsbGJhY2tBbGxvd2xpc3QsXG4gICAgICAgICAgICBuYXZpZ2F0ZUZhbGxiYWNrRGVueWxpc3RcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG5jbGFzcyBTZXJ3aXN0IHtcbiAgICBfdXJsc1RvQ2FjaGVLZXlzID0gbmV3IE1hcCgpO1xuICAgIF91cmxzVG9DYWNoZU1vZGVzID0gbmV3IE1hcCgpO1xuICAgIF9jYWNoZUtleXNUb0ludGVncml0aWVzID0gbmV3IE1hcCgpO1xuICAgIF9jb25jdXJyZW50UHJlY2FjaGluZztcbiAgICBfcHJlY2FjaGVTdHJhdGVneTtcbiAgICBfcm91dGVzO1xuICAgIF9kZWZhdWx0SGFuZGxlck1hcDtcbiAgICBfY2F0Y2hIYW5kbGVyO1xuICAgIF9yZXF1ZXN0UnVsZXM7XG4gICAgY29uc3RydWN0b3IoeyBwcmVjYWNoZUVudHJpZXMsIHByZWNhY2hlT3B0aW9ucywgc2tpcFdhaXRpbmcgPSBmYWxzZSwgaW1wb3J0U2NyaXB0cywgbmF2aWdhdGlvblByZWxvYWQgPSBmYWxzZSwgY2FjaGVJZCwgY2xpZW50c0NsYWltOiBjbGllbnRzQ2xhaW0kMSA9IGZhbHNlLCBydW50aW1lQ2FjaGluZywgb2ZmbGluZUFuYWx5dGljc0NvbmZpZywgZGlzYWJsZURldkxvZ3M6IGRpc2FibGVEZXZMb2dzJDEgPSBmYWxzZSwgZmFsbGJhY2tzLCByZXF1ZXN0UnVsZXMgfSA9IHt9KXtcbiAgICAgICAgY29uc3QgeyBwcmVjYWNoZVN0cmF0ZWd5T3B0aW9ucywgcHJlY2FjaGVSb3V0ZU9wdGlvbnMsIHByZWNhY2hlTWlzY09wdGlvbnMgfSA9IHBhcnNlUHJlY2FjaGVPcHRpb25zKHRoaXMsIHByZWNhY2hlT3B0aW9ucyk7XG4gICAgICAgIHRoaXMuX2NvbmN1cnJlbnRQcmVjYWNoaW5nID0gcHJlY2FjaGVNaXNjT3B0aW9ucy5jb25jdXJyZW5jeTtcbiAgICAgICAgdGhpcy5fcHJlY2FjaGVTdHJhdGVneSA9IG5ldyBQcmVjYWNoZVN0cmF0ZWd5KHByZWNhY2hlU3RyYXRlZ3lPcHRpb25zKTtcbiAgICAgICAgdGhpcy5fcm91dGVzID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLl9kZWZhdWx0SGFuZGxlck1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgdGhpcy5fcmVxdWVzdFJ1bGVzID0gcmVxdWVzdFJ1bGVzO1xuICAgICAgICB0aGlzLmhhbmRsZUluc3RhbGwgPSB0aGlzLmhhbmRsZUluc3RhbGwuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5oYW5kbGVBY3RpdmF0ZSA9IHRoaXMuaGFuZGxlQWN0aXZhdGUuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5oYW5kbGVGZXRjaCA9IHRoaXMuaGFuZGxlRmV0Y2guYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5oYW5kbGVDYWNoZSA9IHRoaXMuaGFuZGxlQ2FjaGUuYmluZCh0aGlzKTtcbiAgICAgICAgaWYgKCEhaW1wb3J0U2NyaXB0cyAmJiBpbXBvcnRTY3JpcHRzLmxlbmd0aCA+IDApIHNlbGYuaW1wb3J0U2NyaXB0cyguLi5pbXBvcnRTY3JpcHRzKTtcbiAgICAgICAgaWYgKG5hdmlnYXRpb25QcmVsb2FkKSBlbmFibGVOYXZpZ2F0aW9uUHJlbG9hZCgpO1xuICAgICAgICBpZiAoY2FjaGVJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzZXRDYWNoZU5hbWVEZXRhaWxzKHtcbiAgICAgICAgICAgICAgICBwcmVmaXg6IGNhY2hlSWRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChza2lwV2FpdGluZykge1xuICAgICAgICAgICAgc2VsZi5za2lwV2FpdGluZygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCAoZXZlbnQpPT57XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGEgJiYgZXZlbnQuZGF0YS50eXBlID09PSBcIlNLSVBfV0FJVElOR1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2tpcFdhaXRpbmcoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2xpZW50c0NsYWltJDEpIGNsaWVudHNDbGFpbSgpO1xuICAgICAgICBpZiAoISFwcmVjYWNoZUVudHJpZXMgJiYgcHJlY2FjaGVFbnRyaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkVG9QcmVjYWNoZUxpc3QocHJlY2FjaGVFbnRyaWVzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJlY2FjaGVNaXNjT3B0aW9ucy5jbGVhbnVwT3V0ZGF0ZWRDYWNoZXMpIHtcbiAgICAgICAgICAgIGNsZWFudXBPdXRkYXRlZENhY2hlcyhwcmVjYWNoZVN0cmF0ZWd5T3B0aW9ucy5jYWNoZU5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVnaXN0ZXJSb3V0ZShuZXcgUHJlY2FjaGVSb3V0ZSh0aGlzLCBwcmVjYWNoZVJvdXRlT3B0aW9ucykpO1xuICAgICAgICBpZiAocHJlY2FjaGVNaXNjT3B0aW9ucy5uYXZpZ2F0ZUZhbGxiYWNrKSB7XG4gICAgICAgICAgICB0aGlzLnJlZ2lzdGVyUm91dGUobmV3IE5hdmlnYXRpb25Sb3V0ZSh0aGlzLmNyZWF0ZUhhbmRsZXJCb3VuZFRvVXJsKHByZWNhY2hlTWlzY09wdGlvbnMubmF2aWdhdGVGYWxsYmFjayksIHtcbiAgICAgICAgICAgICAgICBhbGxvd2xpc3Q6IHByZWNhY2hlTWlzY09wdGlvbnMubmF2aWdhdGVGYWxsYmFja0FsbG93bGlzdCxcbiAgICAgICAgICAgICAgICBkZW55bGlzdDogcHJlY2FjaGVNaXNjT3B0aW9ucy5uYXZpZ2F0ZUZhbGxiYWNrRGVueWxpc3RcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob2ZmbGluZUFuYWx5dGljc0NvbmZpZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZmxpbmVBbmFseXRpY3NDb25maWcgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgICAgICAgICAgb2ZmbGluZUFuYWx5dGljc0NvbmZpZyAmJiBpbml0aWFsaXplR29vZ2xlQW5hbHl0aWNzKHtcbiAgICAgICAgICAgICAgICAgICAgc2Vyd2lzdDogdGhpc1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbml0aWFsaXplR29vZ2xlQW5hbHl0aWNzKHtcbiAgICAgICAgICAgICAgICAgICAgLi4ub2ZmbGluZUFuYWx5dGljc0NvbmZpZyxcbiAgICAgICAgICAgICAgICAgICAgc2Vyd2lzdDogdGhpc1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChydW50aW1lQ2FjaGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAoZmFsbGJhY2tzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmYWxsYmFja1BsdWdpbiA9IG5ldyBQcmVjYWNoZUZhbGxiYWNrUGx1Z2luKHtcbiAgICAgICAgICAgICAgICAgICAgZmFsbGJhY2tVcmxzOiBmYWxsYmFja3MuZW50cmllcyxcbiAgICAgICAgICAgICAgICAgICAgc2Vyd2lzdDogdGhpc1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJ1bnRpbWVDYWNoaW5nLmZvckVhY2goKGNhY2hlRW50cnkpPT57XG4gICAgICAgICAgICAgICAgICAgIGlmIChjYWNoZUVudHJ5LmhhbmRsZXIgaW5zdGFuY2VvZiBTdHJhdGVneSAmJiAhY2FjaGVFbnRyeS5oYW5kbGVyLnBsdWdpbnMuc29tZSgocGx1Z2luKT0+XCJoYW5kbGVyRGlkRXJyb3JcIiBpbiBwbHVnaW4pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYWNoZUVudHJ5LmhhbmRsZXIucGx1Z2lucy5wdXNoKGZhbGxiYWNrUGx1Z2luKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBydW50aW1lQ2FjaGluZyl7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWdpc3RlckNhcHR1cmUoZW50cnkubWF0Y2hlciwgZW50cnkuaGFuZGxlciwgZW50cnkubWV0aG9kKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZGlzYWJsZURldkxvZ3MkMSkgZGlzYWJsZURldkxvZ3MoKTtcbiAgICB9XG4gICAgZ2V0IHByZWNhY2hlU3RyYXRlZ3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcmVjYWNoZVN0cmF0ZWd5O1xuICAgIH1cbiAgICBnZXQgcm91dGVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcm91dGVzO1xuICAgIH1cbiAgICBhZGRFdmVudExpc3RlbmVycygpIHtcbiAgICAgICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKFwiaW5zdGFsbFwiLCB0aGlzLmhhbmRsZUluc3RhbGwpO1xuICAgICAgICBzZWxmLmFkZEV2ZW50TGlzdGVuZXIoXCJhY3RpdmF0ZVwiLCB0aGlzLmhhbmRsZUFjdGl2YXRlKTtcbiAgICAgICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKFwiZmV0Y2hcIiwgdGhpcy5oYW5kbGVGZXRjaCk7XG4gICAgICAgIHNlbGYuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgdGhpcy5oYW5kbGVDYWNoZSk7XG4gICAgfVxuICAgIGFkZFRvUHJlY2FjaGVMaXN0KGVudHJpZXMpIHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzQXJyYXkoZW50cmllcywge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJTZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiYWRkVG9DYWNoZUxpc3RcIixcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWU6IFwiZW50cmllc1wiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cmxzVG9XYXJuQWJvdXQgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKXtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW50cnkgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICB1cmxzVG9XYXJuQWJvdXQucHVzaChlbnRyeSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVudHJ5ICYmICFlbnRyeS5pbnRlZ3JpdHkgJiYgZW50cnkucmV2aXNpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHVybHNUb1dhcm5BYm91dC5wdXNoKGVudHJ5LnVybCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB7IGNhY2hlS2V5LCB1cmwgfSA9IGNyZWF0ZUNhY2hlS2V5KGVudHJ5KTtcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlTW9kZSA9IHR5cGVvZiBlbnRyeSAhPT0gXCJzdHJpbmdcIiAmJiBlbnRyeS5yZXZpc2lvbiA/IFwicmVsb2FkXCIgOiBcImRlZmF1bHRcIjtcbiAgICAgICAgICAgIGlmICh0aGlzLl91cmxzVG9DYWNoZUtleXMuaGFzKHVybCkgJiYgdGhpcy5fdXJsc1RvQ2FjaGVLZXlzLmdldCh1cmwpICE9PSBjYWNoZUtleSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJhZGQtdG8tY2FjaGUtbGlzdC1jb25mbGljdGluZy1lbnRyaWVzXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RFbnRyeTogdGhpcy5fdXJsc1RvQ2FjaGVLZXlzLmdldCh1cmwpLFxuICAgICAgICAgICAgICAgICAgICBzZWNvbmRFbnRyeTogY2FjaGVLZXlcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW50cnkgIT09IFwic3RyaW5nXCIgJiYgZW50cnkuaW50ZWdyaXR5KSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NhY2hlS2V5c1RvSW50ZWdyaXRpZXMuaGFzKGNhY2hlS2V5KSAmJiB0aGlzLl9jYWNoZUtleXNUb0ludGVncml0aWVzLmdldChjYWNoZUtleSkgIT09IGVudHJ5LmludGVncml0eSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2Vyd2lzdEVycm9yKFwiYWRkLXRvLWNhY2hlLWxpc3QtY29uZmxpY3RpbmctaW50ZWdyaXRpZXNcIiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdXJsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUtleXNUb0ludGVncml0aWVzLnNldChjYWNoZUtleSwgZW50cnkuaW50ZWdyaXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3VybHNUb0NhY2hlS2V5cy5zZXQodXJsLCBjYWNoZUtleSk7XG4gICAgICAgICAgICB0aGlzLl91cmxzVG9DYWNoZU1vZGVzLnNldCh1cmwsIGNhY2hlTW9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVybHNUb1dhcm5BYm91dC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCB3YXJuaW5nTWVzc2FnZSA9IGBTZXJ3aXN0IGlzIHByZWNhY2hpbmcgVVJMcyB3aXRob3V0IHJldmlzaW9uIGluZm86ICR7dXJsc1RvV2FybkFib3V0LmpvaW4oXCIsIFwiKX1cXG5UaGlzIGlzIGdlbmVyYWxseSBOT1Qgc2FmZS4gTGVhcm4gbW9yZSBhdCBodHRwczovL2JpdC5seS93Yi1wcmVjYWNoZWA7XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHdhcm5pbmdNZXNzYWdlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4od2FybmluZ01lc3NhZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGhhbmRsZUluc3RhbGwoZXZlbnQpIHtcbiAgICAgICAgdm9pZCB0aGlzLnJlZ2lzdGVyUmVxdWVzdFJ1bGVzKGV2ZW50KTtcbiAgICAgICAgcmV0dXJuIHdhaXRVbnRpbChldmVudCwgYXN5bmMgKCk9PntcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbGxSZXBvcnRQbHVnaW4gPSBuZXcgUHJlY2FjaGVJbnN0YWxsUmVwb3J0UGx1Z2luKCk7XG4gICAgICAgICAgICB0aGlzLnByZWNhY2hlU3RyYXRlZ3kucGx1Z2lucy5wdXNoKGluc3RhbGxSZXBvcnRQbHVnaW4pO1xuICAgICAgICAgICAgYXdhaXQgcGFyYWxsZWwodGhpcy5fY29uY3VycmVudFByZWNhY2hpbmcsIEFycmF5LmZyb20odGhpcy5fdXJsc1RvQ2FjaGVLZXlzLmVudHJpZXMoKSksIGFzeW5jIChbdXJsLCBjYWNoZUtleV0pPT57XG4gICAgICAgICAgICAgICAgY29uc3QgaW50ZWdyaXR5ID0gdGhpcy5fY2FjaGVLZXlzVG9JbnRlZ3JpdGllcy5nZXQoY2FjaGVLZXkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhY2hlTW9kZSA9IHRoaXMuX3VybHNUb0NhY2hlTW9kZXMuZ2V0KHVybCk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KHVybCwge1xuICAgICAgICAgICAgICAgICAgICBpbnRlZ3JpdHksXG4gICAgICAgICAgICAgICAgICAgIGNhY2hlOiBjYWNoZU1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNyZWRlbnRpYWxzOiBcInNhbWUtb3JpZ2luXCJcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbCh0aGlzLnByZWNhY2hlU3RyYXRlZ3kuaGFuZGxlQWxsKHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICAgICAgICAgIHVybDogbmV3IFVSTChyZXF1ZXN0LnVybCksXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGVLZXlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgeyB1cGRhdGVkVVJMcywgbm90VXBkYXRlZFVSTHMgfSA9IGluc3RhbGxSZXBvcnRQbHVnaW47XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgcHJpbnRJbnN0YWxsRGV0YWlscyh1cGRhdGVkVVJMcywgbm90VXBkYXRlZFVSTHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVkVVJMcyxcbiAgICAgICAgICAgICAgICBub3RVcGRhdGVkVVJMc1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGFzeW5jIHJlZ2lzdGVyUmVxdWVzdFJ1bGVzKGV2ZW50KSB7XG4gICAgICAgIGlmICghdGhpcy5fcmVxdWVzdFJ1bGVzKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFldmVudD8uYWRkUm91dGVzKSB7XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oXCJSZXF1ZXN0IHJ1bGVzIGlnbm9yZWQgYXMgdGhlIFN0YXRpYyBSb3V0aW5nIEFQSSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3Nlci4gXCIgKyBcIlNlZSBodHRwczovL2Nhbml1c2UuY29tL21kbi1hcGlfaW5zdGFsbGV2ZW50X2FkZHJvdXRlcyBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIud2FybihcIlJlcXVlc3QgcnVsZXMgbWF5IG5vdCBiZSBzdXBwb3J0ZWQgaW4gYWxsIGJyb3dzZXJzIGFzIHRoZSBTdGF0aWMgUm91dGluZyBBUEkgaXMgZXhwZXJpbWVudGFsLiBcIiArIFwiVGhpcyBmZWF0dXJlIGFsbG93cyBieXBhc3NpbmcgdGhlIHNlcnZpY2Ugd29ya2VyIGZvciBzcGVjaWZpYyByZXF1ZXN0cyB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLiBcIiArIFwiU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9JbnN0YWxsRXZlbnQvYWRkUm91dGVzIGZvciBtb3JlIGluZm9ybWF0aW9uLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IGV2ZW50LmFkZFJvdXRlcyh0aGlzLl9yZXF1ZXN0UnVsZXMpO1xuICAgICAgICAgICAgdGhpcy5fcmVxdWVzdFJ1bGVzID0gdW5kZWZpbmVkO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHJlZ2lzdGVyIHJlcXVlc3QgcnVsZXM6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfS4gYCArIFwiVGhpcyBtYXkgb2NjdXIgaWYgdGhlIGJyb3dzZXIgZG9lc24ndCBzdXBwb3J0IHRoZSBTdGF0aWMgUm91dGluZyBBUEkgb3IgaWYgdGhlIHJlcXVlc3QgcnVsZXMgYXJlIGludmFsaWQuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaGFuZGxlQWN0aXZhdGUoZXZlbnQpIHtcbiAgICAgICAgcmV0dXJuIHdhaXRVbnRpbChldmVudCwgYXN5bmMgKCk9PntcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlID0gYXdhaXQgc2VsZi5jYWNoZXMub3Blbih0aGlzLnByZWNhY2hlU3RyYXRlZ3kuY2FjaGVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRseUNhY2hlZFJlcXVlc3RzID0gYXdhaXQgY2FjaGUua2V5cygpO1xuICAgICAgICAgICAgY29uc3QgZXhwZWN0ZWRDYWNoZUtleXMgPSBuZXcgU2V0KHRoaXMuX3VybHNUb0NhY2hlS2V5cy52YWx1ZXMoKSk7XG4gICAgICAgICAgICBjb25zdCBkZWxldGVkQ2FjaGVSZXF1ZXN0cyA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCByZXF1ZXN0IG9mIGN1cnJlbnRseUNhY2hlZFJlcXVlc3RzKXtcbiAgICAgICAgICAgICAgICBpZiAoIWV4cGVjdGVkQ2FjaGVLZXlzLmhhcyhyZXF1ZXN0LnVybCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgY2FjaGUuZGVsZXRlKHJlcXVlc3QpO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGVkQ2FjaGVSZXF1ZXN0cy5wdXNoKHJlcXVlc3QudXJsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgcHJpbnRDbGVhbnVwRGV0YWlscyhkZWxldGVkQ2FjaGVSZXF1ZXN0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGRlbGV0ZWRDYWNoZVJlcXVlc3RzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgaGFuZGxlRmV0Y2goZXZlbnQpIHtcbiAgICAgICAgY29uc3QgeyByZXF1ZXN0IH0gPSBldmVudDtcbiAgICAgICAgY29uc3QgcmVzcG9uc2VQcm9taXNlID0gdGhpcy5oYW5kbGVSZXF1ZXN0KHtcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBldmVudFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3BvbnNlUHJvbWlzZSkge1xuICAgICAgICAgICAgZXZlbnQucmVzcG9uZFdpdGgocmVzcG9uc2VQcm9taXNlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBoYW5kbGVDYWNoZShldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQuZGF0YSAmJiBldmVudC5kYXRhLnR5cGUgPT09IFwiQ0FDSEVfVVJMU1wiKSB7XG4gICAgICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGV2ZW50LmRhdGE7XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKFwiQ2FjaGluZyBVUkxzIGZyb20gdGhlIHdpbmRvd1wiLCBwYXlsb2FkLnVybHNUb0NhY2hlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3RQcm9taXNlcyA9IFByb21pc2UuYWxsKHBheWxvYWQudXJsc1RvQ2FjaGUubWFwKChlbnRyeSk9PntcbiAgICAgICAgICAgICAgICBsZXQgcmVxdWVzdDtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGVudHJ5ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3QgPSBuZXcgUmVxdWVzdChlbnRyeSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KC4uLmVudHJ5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlUmVxdWVzdCh7XG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBldmVudC53YWl0VW50aWwocmVxdWVzdFByb21pc2VzKTtcbiAgICAgICAgICAgIGlmIChldmVudC5wb3J0cz8uWzBdKSB7XG4gICAgICAgICAgICAgICAgdm9pZCByZXF1ZXN0UHJvbWlzZXMudGhlbigoKT0+ZXZlbnQucG9ydHNbMF0ucG9zdE1lc3NhZ2UodHJ1ZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHNldERlZmF1bHRIYW5kbGVyKGhhbmRsZXIsIG1ldGhvZCA9IGRlZmF1bHRNZXRob2QpIHtcbiAgICAgICAgdGhpcy5fZGVmYXVsdEhhbmRsZXJNYXAuc2V0KG1ldGhvZCwgbm9ybWFsaXplSGFuZGxlcihoYW5kbGVyKSk7XG4gICAgfVxuICAgIHNldENhdGNoSGFuZGxlcihoYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuX2NhdGNoSGFuZGxlciA9IG5vcm1hbGl6ZUhhbmRsZXIoaGFuZGxlcik7XG4gICAgfVxuICAgIHJlZ2lzdGVyQ2FwdHVyZShjYXB0dXJlLCBoYW5kbGVyLCBtZXRob2QpIHtcbiAgICAgICAgY29uc3Qgcm91dGUgPSBwYXJzZVJvdXRlKGNhcHR1cmUsIGhhbmRsZXIsIG1ldGhvZCk7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJSb3V0ZShyb3V0ZSk7XG4gICAgICAgIHJldHVybiByb3V0ZTtcbiAgICB9XG4gICAgcmVnaXN0ZXJSb3V0ZShyb3V0ZSkge1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNUeXBlKHJvdXRlLCBcIm9iamVjdFwiLCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIlNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJyZWdpc3RlclJvdXRlXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcInJvdXRlXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmhhc01ldGhvZChyb3V0ZSwgXCJtYXRjaFwiLCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIlNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJyZWdpc3RlclJvdXRlXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcInJvdXRlXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzVHlwZShyb3V0ZS5oYW5kbGVyLCBcIm9iamVjdFwiLCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIlNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJyZWdpc3RlclJvdXRlXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcInJvdXRlXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmhhc01ldGhvZChyb3V0ZS5oYW5kbGVyLCBcImhhbmRsZVwiLCB7XG4gICAgICAgICAgICAgICAgbW9kdWxlTmFtZTogXCJzZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcIlNlcndpc3RcIixcbiAgICAgICAgICAgICAgICBmdW5jTmFtZTogXCJyZWdpc3RlclJvdXRlXCIsXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lOiBcInJvdXRlLmhhbmRsZXJcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmaW5hbEFzc2VydEV4cG9ydHMuaXNUeXBlKHJvdXRlLm1ldGhvZCwgXCJzdHJpbmdcIiwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJTZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwicmVnaXN0ZXJSb3V0ZVwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJyb3V0ZS5tZXRob2RcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLl9yb3V0ZXMuaGFzKHJvdXRlLm1ldGhvZCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3JvdXRlcy5zZXQocm91dGUubWV0aG9kLCBbXSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcm91dGVzLmdldChyb3V0ZS5tZXRob2QpLnB1c2gocm91dGUpO1xuICAgIH1cbiAgICB1bnJlZ2lzdGVyUm91dGUocm91dGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb3V0ZXMuaGFzKHJvdXRlLm1ldGhvZCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJ1bnJlZ2lzdGVyLXJvdXRlLWJ1dC1ub3QtZm91bmQtd2l0aC1tZXRob2RcIiwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogcm91dGUubWV0aG9kXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByb3V0ZUluZGV4ID0gdGhpcy5fcm91dGVzLmdldChyb3V0ZS5tZXRob2QpLmluZGV4T2Yocm91dGUpO1xuICAgICAgICBpZiAocm91dGVJbmRleCA+IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9yb3V0ZXMuZ2V0KHJvdXRlLm1ldGhvZCkuc3BsaWNlKHJvdXRlSW5kZXgsIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFNlcndpc3RFcnJvcihcInVucmVnaXN0ZXItcm91dGUtcm91dGUtbm90LXJlZ2lzdGVyZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0VXJsc1RvUHJlY2FjaGVLZXlzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdXJsc1RvQ2FjaGVLZXlzO1xuICAgIH1cbiAgICBnZXRQcmVjYWNoZWRVcmxzKCkge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgLi4udGhpcy5fdXJsc1RvQ2FjaGVLZXlzLmtleXMoKVxuICAgICAgICBdO1xuICAgIH1cbiAgICBnZXRQcmVjYWNoZUtleUZvclVybCh1cmwpIHtcbiAgICAgICAgY29uc3QgdXJsT2JqZWN0ID0gbmV3IFVSTCh1cmwsIGxvY2F0aW9uLmhyZWYpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdXJsc1RvQ2FjaGVLZXlzLmdldCh1cmxPYmplY3QuaHJlZik7XG4gICAgfVxuICAgIGdldEludGVncml0eUZvclByZWNhY2hlS2V5KGNhY2hlS2V5KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYWNoZUtleXNUb0ludGVncml0aWVzLmdldChjYWNoZUtleSk7XG4gICAgfVxuICAgIGFzeW5jIG1hdGNoUHJlY2FjaGUocmVxdWVzdCkge1xuICAgICAgICBjb25zdCB1cmwgPSByZXF1ZXN0IGluc3RhbmNlb2YgUmVxdWVzdCA/IHJlcXVlc3QudXJsIDogcmVxdWVzdDtcbiAgICAgICAgY29uc3QgY2FjaGVLZXkgPSB0aGlzLmdldFByZWNhY2hlS2V5Rm9yVXJsKHVybCk7XG4gICAgICAgIGlmIChjYWNoZUtleSkge1xuICAgICAgICAgICAgY29uc3QgY2FjaGUgPSBhd2FpdCBzZWxmLmNhY2hlcy5vcGVuKHRoaXMucHJlY2FjaGVTdHJhdGVneS5jYWNoZU5hbWUpO1xuICAgICAgICAgICAgcmV0dXJuIGNhY2hlLm1hdGNoKGNhY2hlS2V5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjcmVhdGVIYW5kbGVyQm91bmRUb1VybCh1cmwpIHtcbiAgICAgICAgY29uc3QgY2FjaGVLZXkgPSB0aGlzLmdldFByZWNhY2hlS2V5Rm9yVXJsKHVybCk7XG4gICAgICAgIGlmICghY2FjaGVLZXkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTZXJ3aXN0RXJyb3IoXCJub24tcHJlY2FjaGVkLXVybFwiLCB7XG4gICAgICAgICAgICAgICAgdXJsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKG9wdGlvbnMpPT57XG4gICAgICAgICAgICBvcHRpb25zLnJlcXVlc3QgPSBuZXcgUmVxdWVzdCh1cmwpO1xuICAgICAgICAgICAgb3B0aW9ucy5wYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgY2FjaGVLZXksXG4gICAgICAgICAgICAgICAgLi4ub3B0aW9ucy5wYXJhbXNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcmVjYWNoZVN0cmF0ZWd5LmhhbmRsZShvcHRpb25zKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaGFuZGxlUmVxdWVzdCh7IHJlcXVlc3QsIGV2ZW50IH0pIHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgZmluYWxBc3NlcnRFeHBvcnRzLmlzSW5zdGFuY2UocmVxdWVzdCwgUmVxdWVzdCwge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IFwic2Vyd2lzdFwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJTZXJ3aXN0XCIsXG4gICAgICAgICAgICAgICAgZnVuY05hbWU6IFwiaGFuZGxlUmVxdWVzdFwiLFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZTogXCJvcHRpb25zLnJlcXVlc3RcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJsID0gbmV3IFVSTChyZXF1ZXN0LnVybCwgbG9jYXRpb24uaHJlZik7XG4gICAgICAgIGlmICghdXJsLnByb3RvY29sLnN0YXJ0c1dpdGgoXCJodHRwXCIpKSB7XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKFwiUm91dGVyIG9ubHkgc3VwcG9ydHMgVVJMcyB0aGF0IHN0YXJ0IHdpdGggJ2h0dHAnLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzYW1lT3JpZ2luID0gdXJsLm9yaWdpbiA9PT0gbG9jYXRpb24ub3JpZ2luO1xuICAgICAgICBjb25zdCB7IHBhcmFtcywgcm91dGUgfSA9IHRoaXMuZmluZE1hdGNoaW5nUm91dGUoe1xuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgc2FtZU9yaWdpbixcbiAgICAgICAgICAgIHVybFxuICAgICAgICB9KTtcbiAgICAgICAgbGV0IGhhbmRsZXIgPSByb3V0ZT8uaGFuZGxlcjtcbiAgICAgICAgY29uc3QgZGVidWdNZXNzYWdlcyA9IFtdO1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICAgICAgICAgIGRlYnVnTWVzc2FnZXMucHVzaChbXG4gICAgICAgICAgICAgICAgICAgIFwiRm91bmQgYSByb3V0ZSB0byBoYW5kbGUgdGhpcyByZXF1ZXN0OlwiLFxuICAgICAgICAgICAgICAgICAgICByb3V0ZVxuICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgIGlmIChwYXJhbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVidWdNZXNzYWdlcy5wdXNoKFtcbiAgICAgICAgICAgICAgICAgICAgICAgIGBQYXNzaW5nIHRoZSBmb2xsb3dpbmcgcGFyYW1zIHRvIHRoZSByb3V0ZSdzIGhhbmRsZXI6YCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtc1xuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWV0aG9kID0gcmVxdWVzdC5tZXRob2Q7XG4gICAgICAgIGlmICghaGFuZGxlciAmJiB0aGlzLl9kZWZhdWx0SGFuZGxlck1hcC5oYXMobWV0aG9kKSkge1xuICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGRlYnVnTWVzc2FnZXMucHVzaChgRmFpbGVkIHRvIGZpbmQgYSBtYXRjaGluZyByb3V0ZS4gRmFsbGluZyBiYWNrIHRvIHRoZSBkZWZhdWx0IGhhbmRsZXIgZm9yICR7bWV0aG9kfS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIgPSB0aGlzLl9kZWZhdWx0SGFuZGxlck1hcC5nZXQobWV0aG9kKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYE5vIHJvdXRlIGZvdW5kIGZvcjogJHtnZXRGcmllbmRseVVSTCh1cmwpfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIGxvZ2dlci5ncm91cENvbGxhcHNlZChgUm91dGVyIGlzIHJlc3BvbmRpbmcgdG86ICR7Z2V0RnJpZW5kbHlVUkwodXJsKX1gKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgbXNnIG9mIGRlYnVnTWVzc2FnZXMpe1xuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KG1zZykpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyguLi5tc2cpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2cobXNnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2dnZXIuZ3JvdXBFbmQoKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzcG9uc2VQcm9taXNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVzcG9uc2VQcm9taXNlID0gaGFuZGxlci5oYW5kbGUoe1xuICAgICAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgICAgIHBhcmFtc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgcmVzcG9uc2VQcm9taXNlID0gUHJvbWlzZS5yZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjYXRjaEhhbmRsZXIgPSByb3V0ZT8uY2F0Y2hIYW5kbGVyO1xuICAgICAgICBpZiAocmVzcG9uc2VQcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSAmJiAodGhpcy5fY2F0Y2hIYW5kbGVyIHx8IGNhdGNoSGFuZGxlcikpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlUHJvbWlzZSA9IHJlc3BvbnNlUHJvbWlzZS5jYXRjaChhc3luYyAoZXJyKT0+e1xuICAgICAgICAgICAgICAgIGlmIChjYXRjaEhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmdyb3VwQ29sbGFwc2VkKGBFcnJvciB0aHJvd24gd2hlbiByZXNwb25kaW5nIHRvOiAgJHtnZXRGcmllbmRseVVSTCh1cmwpfS4gRmFsbGluZyBiYWNrIHRvIHJvdXRlJ3MgQ2F0Y2ggSGFuZGxlci5gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcIkVycm9yIHRocm93biBieTpcIiwgcm91dGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZ3JvdXBFbmQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGNhdGNoSGFuZGxlci5oYW5kbGUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtc1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGNhdGNoRXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2F0Y2hFcnIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyciA9IGNhdGNoRXJyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jYXRjaEhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmdyb3VwQ29sbGFwc2VkKGBFcnJvciB0aHJvd24gd2hlbiByZXNwb25kaW5nIHRvOiAgJHtnZXRGcmllbmRseVVSTCh1cmwpfS4gRmFsbGluZyBiYWNrIHRvIGdsb2JhbCBDYXRjaCBIYW5kbGVyLmApO1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiRXJyb3IgdGhyb3duIGJ5OlwiLCByb3V0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5ncm91cEVuZCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9jYXRjaEhhbmRsZXIuaGFuZGxlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlUHJvbWlzZTtcbiAgICB9XG4gICAgZmluZE1hdGNoaW5nUm91dGUoeyB1cmwsIHNhbWVPcmlnaW4sIHJlcXVlc3QsIGV2ZW50IH0pIHtcbiAgICAgICAgY29uc3Qgcm91dGVzID0gdGhpcy5fcm91dGVzLmdldChyZXF1ZXN0Lm1ldGhvZCkgfHwgW107XG4gICAgICAgIGZvciAoY29uc3Qgcm91dGUgb2Ygcm91dGVzKXtcbiAgICAgICAgICAgIGxldCBwYXJhbXM7XG4gICAgICAgICAgICBjb25zdCBtYXRjaFJlc3VsdCA9IHJvdXRlLm1hdGNoKHtcbiAgICAgICAgICAgICAgICB1cmwsXG4gICAgICAgICAgICAgICAgc2FtZU9yaWdpbixcbiAgICAgICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgICAgIGV2ZW50XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChtYXRjaFJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoUmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oYFdoaWxlIHJvdXRpbmcgJHtnZXRGcmllbmRseVVSTCh1cmwpfSwgYW4gYXN5bmMgbWF0Y2hDYWxsYmFjayBmdW5jdGlvbiB3YXMgdXNlZC4gUGxlYXNlIGNvbnZlcnQgdGhlIGZvbGxvd2luZyByb3V0ZSB0byB1c2UgYSBzeW5jaHJvbm91cyBtYXRjaENhbGxiYWNrIGZ1bmN0aW9uOmAsIHJvdXRlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYXJhbXMgPSBtYXRjaFJlc3VsdDtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwYXJhbXMpICYmIHBhcmFtcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2hSZXN1bHQuY29uc3RydWN0b3IgPT09IE9iamVjdCAmJiBPYmplY3Qua2V5cyhtYXRjaFJlc3VsdCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBtYXRjaFJlc3VsdCA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICByb3V0ZSxcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge307XG4gICAgfVxufVxuXG5leHBvcnQgeyBCUk9BRENBU1RfVVBEQVRFX0RFRkFVTFRfSEVBREVSUywgQmFja2dyb3VuZFN5bmNQbHVnaW4sIEJyb2FkY2FzdENhY2hlVXBkYXRlLCBCcm9hZGNhc3RVcGRhdGVQbHVnaW4sIENhY2hlRXhwaXJhdGlvbiwgQ2FjaGVGaXJzdCwgQ2FjaGVPbmx5LCBDYWNoZWFibGVSZXNwb25zZSwgQ2FjaGVhYmxlUmVzcG9uc2VQbHVnaW4sIEV4cGlyYXRpb25QbHVnaW4sIE5hdmlnYXRpb25Sb3V0ZSwgTmV0d29ya0ZpcnN0LCBOZXR3b3JrT25seSwgUHJlY2FjaGVGYWxsYmFja1BsdWdpbiwgUHJlY2FjaGVSb3V0ZSwgUHJlY2FjaGVTdHJhdGVneSwgUmFuZ2VSZXF1ZXN0c1BsdWdpbiwgUm91dGUsIFNlcndpc3QsIFN0YWxlV2hpbGVSZXZhbGlkYXRlLCBTdHJhdGVneSwgY2FjaGVOYW1lcywgY3JlYXRlUGFydGlhbFJlc3BvbnNlLCBkaXNhYmxlRGV2TG9ncywgZW5hYmxlTmF2aWdhdGlvblByZWxvYWQsIGluaXRpYWxpemVHb29nbGVBbmFseXRpY3MsIHJlZ2lzdGVyUXVvdGFFcnJvckNhbGxiYWNrLCByZXNwb25zZXNBcmVTYW1lLCBzZXRDYWNoZU5hbWVEZXRhaWxzIH07XG4iXSwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbMF0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/serwist/dist/index.js\n")); - -/***/ }), - -/***/ "./src/app/sw.ts": -/*!***********************!*\ - !*** ./src/app/sw.ts ***! - \***********************/ -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _serwist_next_worker__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @serwist/next/worker */ \"./node_modules/@serwist/next/dist/index.worker.js\");\n/* harmony import */ var serwist__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! serwist */ \"./node_modules/serwist/dist/index.js\");\n\n\nconst serwist = new serwist__WEBPACK_IMPORTED_MODULE_1__.Serwist({\n precacheEntries: undefined,\n skipWaiting: true,\n clientsClaim: true,\n navigationPreload: true,\n runtimeCaching: _serwist_next_worker__WEBPACK_IMPORTED_MODULE_0__.defaultCache\n});\nserwist.addEventListeners();\n\n\n;\n // Wrapped in an IIFE to avoid polluting the global scope\n ;\n (function () {\n var _a, _b;\n // Legacy CSS implementations will `eval` browser code in a Node.js context\n // to extract CSS. For backwards compatibility, we need to check we're in a\n // browser context before continuing.\n if (typeof self !== 'undefined' &&\n // No-JS mode does not inject these helpers:\n '$RefreshHelpers$' in self) {\n // @ts-ignore __webpack_module__ is global\n var currentExports = module.exports;\n // @ts-ignore __webpack_module__ is global\n var prevSignature = (_b = (_a = module.hot.data) === null || _a === void 0 ? void 0 : _a.prevSignature) !== null && _b !== void 0 ? _b : null;\n // This cannot happen in MainTemplate because the exports mismatch between\n // templating and execution.\n self.$RefreshHelpers$.registerExportsForReactRefresh(currentExports, module.id);\n // A module can be accepted automatically based on its exports, e.g. when\n // it is a Refresh Boundary.\n if (self.$RefreshHelpers$.isReactRefreshBoundary(currentExports)) {\n // Save the previous exports signature on update so we can compare the boundary\n // signatures. We avoid saving exports themselves since it causes memory leaks (https://github.com/vercel/next.js/pull/53797)\n module.hot.dispose(function (data) {\n data.prevSignature =\n self.$RefreshHelpers$.getRefreshBoundarySignature(currentExports);\n });\n // Unconditionally accept an update to this module, we'll check if it's\n // still a Refresh Boundary later.\n // @ts-ignore importMeta is replaced in the loader\n /* unsupported import.meta.webpackHot */ undefined.accept();\n // This field is set when the previous version of this module was a\n // Refresh Boundary, letting us know we need to check for invalidation or\n // enqueue an update.\n if (prevSignature !== null) {\n // A boundary can become ineligible if its exports are incompatible\n // with the previous exports.\n //\n // For example, if you add/remove/change exports, we'll want to\n // re-execute the importing modules, and force those components to\n // re-render. Similarly, if you convert a class component to a\n // function, we want to invalidate the boundary.\n if (self.$RefreshHelpers$.shouldInvalidateReactRefreshBoundary(prevSignature, self.$RefreshHelpers$.getRefreshBoundarySignature(currentExports))) {\n module.hot.invalidate();\n }\n else {\n self.$RefreshHelpers$.scheduleUpdate();\n }\n }\n }\n else {\n // Since we just executed the code for the module, it's possible that the\n // new exports made it ineligible for being a boundary.\n // We only care about the case when we were _previously_ a boundary,\n // because we already accepted this update (accidental side effect).\n var isNoLongerABoundary = prevSignature !== null;\n if (isNoLongerABoundary) {\n module.hot.invalidate();\n }\n }\n }\n })();\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvYXBwL3N3LnRzIiwibWFwcGluZ3MiOiI7OztBQUFvRDtBQUVsQjtBQVVsQyxNQUFNRSxVQUFVLElBQUlELDRDQUFPQSxDQUFDO0lBQzFCRSxpQkFBaUJDLEtBQUtDLGFBQWE7SUFDbkNDLGFBQWE7SUFDYkMsY0FBYztJQUNkQyxtQkFBbUI7SUFDbkJDLGdCQUFnQlQsOERBQVlBO0FBQzlCO0FBRUFFLFFBQVFRLGlCQUFpQiIsInNvdXJjZXMiOlsiL1VzZXJzL3NkOTIzNS9jb2RlL215Z2gvbGVhcm5pbmdfYWlfY2xvY2svd2ViL3NyYy9hcHAvc3cudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGVmYXVsdENhY2hlIH0gZnJvbSAnQHNlcndpc3QvbmV4dC93b3JrZXInO1xuaW1wb3J0IHR5cGUgeyBQcmVjYWNoZUVudHJ5LCBTZXJ3aXN0R2xvYmFsQ29uZmlnIH0gZnJvbSAnc2Vyd2lzdCc7XG5pbXBvcnQgeyBTZXJ3aXN0IH0gZnJvbSAnc2Vyd2lzdCc7XG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIFdvcmtlckdsb2JhbFNjb3BlIGV4dGVuZHMgU2Vyd2lzdEdsb2JhbENvbmZpZyB7XG4gICAgX19TV19NQU5JRkVTVDogKFByZWNhY2hlRW50cnkgfCBzdHJpbmcpW10gfCB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZGVjbGFyZSBjb25zdCBzZWxmOiBXb3JrZXJHbG9iYWxTY29wZSAmIHR5cGVvZiBnbG9iYWxUaGlzO1xuXG5jb25zdCBzZXJ3aXN0ID0gbmV3IFNlcndpc3Qoe1xuICBwcmVjYWNoZUVudHJpZXM6IHNlbGYuX19TV19NQU5JRkVTVCxcbiAgc2tpcFdhaXRpbmc6IHRydWUsXG4gIGNsaWVudHNDbGFpbTogdHJ1ZSxcbiAgbmF2aWdhdGlvblByZWxvYWQ6IHRydWUsXG4gIHJ1bnRpbWVDYWNoaW5nOiBkZWZhdWx0Q2FjaGUsXG59KTtcblxuc2Vyd2lzdC5hZGRFdmVudExpc3RlbmVycygpO1xuIl0sIm5hbWVzIjpbImRlZmF1bHRDYWNoZSIsIlNlcndpc3QiLCJzZXJ3aXN0IiwicHJlY2FjaGVFbnRyaWVzIiwic2VsZiIsIl9fU1dfTUFOSUZFU1QiLCJza2lwV2FpdGluZyIsImNsaWVudHNDbGFpbSIsIm5hdmlnYXRpb25QcmVsb2FkIiwicnVudGltZUNhY2hpbmciLCJhZGRFdmVudExpc3RlbmVycyJdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/app/sw.ts\n")); - -/***/ }) - -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ if (cachedModule.error !== undefined) throw cachedModule.error; -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ id: moduleId, -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ var threw = true; -/******/ try { -/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); -/******/ threw = false; -/******/ } finally { -/******/ if(threw) delete __webpack_module_cache__[moduleId]; -/******/ } -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/define property getters */ -/******/ (() => { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = (exports, definition) => { -/******/ for(var key in definition) { -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); -/******/ } -/******/ } -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -/******/ })(); -/******/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/trusted types policy */ -/******/ (() => { -/******/ var policy; -/******/ __webpack_require__.tt = () => { -/******/ // Create Trusted Type policy if Trusted Types are available and the policy doesn't exist yet. -/******/ if (policy === undefined) { -/******/ policy = { -/******/ createScript: (script) => (script) -/******/ }; -/******/ if (typeof trustedTypes !== "undefined" && trustedTypes.createPolicy) { -/******/ policy = trustedTypes.createPolicy("nextjs#bundler", policy); -/******/ } -/******/ } -/******/ return policy; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/trusted types script */ -/******/ (() => { -/******/ __webpack_require__.ts = (script) => (__webpack_require__.tt().createScript(script)); -/******/ })(); -/******/ -/******/ /* webpack/runtime/react refresh */ -/******/ (() => { -/******/ if (__webpack_require__.i) { -/******/ __webpack_require__.i.push((options) => { -/******/ const originalFactory = options.factory; -/******/ options.factory = (moduleObject, moduleExports, webpackRequire) => { -/******/ if (!originalFactory) { -/******/ document.location.reload(); -/******/ return; -/******/ } -/******/ const hasRefresh = typeof self !== "undefined" && !!self.$RefreshInterceptModuleExecution$; -/******/ const cleanup = hasRefresh ? self.$RefreshInterceptModuleExecution$(moduleObject.id) : () => {}; -/******/ try { -/******/ originalFactory.call(this, moduleObject, moduleExports, webpackRequire); -/******/ } finally { -/******/ cleanup(); -/******/ } -/******/ } -/******/ }) -/******/ } -/******/ })(); -/******/ -/******/ /* webpack/runtime/compat */ -/******/ -/******/ -/******/ // noop fns to prevent runtime errors during initialization -/******/ if (typeof self !== "undefined") { -/******/ self.$RefreshReg$ = function () {}; -/******/ self.$RefreshSig$ = function () { -/******/ return function (type) { -/******/ return type; -/******/ }; -/******/ }; -/******/ } -/******/ -/************************************************************************/ -/******/ -/******/ // startup -/******/ // Load entry module and return exports -/******/ // This entry module can't be inlined because the eval-source-map devtool is used. -/******/ var __webpack_exports__ = __webpack_require__("./src/app/sw.ts"); -/******/ -/******/ })() -; \ No newline at end of file diff --git a/web/src/components/RoutineEditor.tsx b/web/src/components/RoutineEditor.tsx index 4eaf046..cfbd808 100644 --- a/web/src/components/RoutineEditor.tsx +++ b/web/src/components/RoutineEditor.tsx @@ -255,6 +255,86 @@ export function RoutineEditor({ + {/* Timeline Preview */} + {steps.length > 0 && totalMinutes > 0 && ( +
+ +
+ {/* Bar segments */} +
+ {steps.map((step, idx) => { + const pct = totalMinutes > 0 ? (step.durationMinutes / totalMinutes) * 100 : 0; + const hue = (idx * 137) % 360; // golden-angle distribution for distinct colors + return ( +
+ {pct > 10 ? (step.label || `#${idx + 1}`) : ''} +
+ ); + })} +
+ {/* Time markers */} +
+ 0:00 + {(() => { + let cumulative = 0; + return steps.slice(0, -1).map((step, idx) => { + cumulative += step.durationMinutes; + const pct = (cumulative / totalMinutes) * 100; + const h = Math.floor(cumulative / 60); + const m = cumulative % 60; + return ( + + {h > 0 ? `${h}:${String(m).padStart(2, '0')}` : `${m}m`} + + ); + }); + })()} + + {Math.floor(totalMinutes / 60) > 0 + ? `${Math.floor(totalMinutes / 60)}:${String(totalMinutes % 60).padStart(2, '0')}` + : `${totalMinutes}m`} + +
+ {/* Step legend */} +
+ {steps.map((step, idx) => { + const hue = (idx * 137) % 360; + return ( +
+
+ + {step.label || `Step ${idx + 1}`} ({step.durationMinutes}m) + +
+ ); + })} +
+
+
+ )} + {/* Save as template toggle */}