xhs-mcp 0.8.8 → 0.8.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,344 @@
1
+ #!/usr/bin/env node
2
+ /*
3
+ * ATTENTION: An "eval-source-map" devtool has been used.
4
+ * This devtool is neither made for production nor for readable output files.
5
+ * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
6
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
7
+ * or disable the default devtool with "devtool: false".
8
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
9
+ */
10
+ /******/ (() => { // webpackBootstrap
11
+ /******/ "use strict";
12
+ /******/ var __webpack_modules__ = ({
13
+
14
+ /***/ 103:
15
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
16
+
17
+ eval("{/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ d: () => (/* binding */ BaseService)\n/* harmony export */ });\n/* harmony import */ var _core_browser_browser_manager__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3977);\n\nclass BaseService {\n config;\n browserManager;\n constructor(config, browserManager) {\n this.config = config;\n this.browserManager = browserManager ?? new _core_browser_browser_manager__WEBPACK_IMPORTED_MODULE_0__/* .BrowserManager */ .Gd(config);\n }\n getBrowserManager() {\n return this.browserManager;\n }\n getConfig() {\n return this.config;\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTAzLmpzIiwibWFwcGluZ3MiOiI7Ozs7QUFDaUU7QUFFMUQsTUFBZSxXQUFXO0lBQ1osTUFBTSxDQUFTO0lBQ2YsY0FBYyxDQUFpQjtJQUVsRCxZQUFZLE1BQWMsRUFBRSxjQUErQjtRQUN6RCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsSUFBSSxJQUFJLG1GQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVTLGlCQUFpQjtRQUN6QixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQUVTLFNBQVM7UUFDakIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7Q0FDRiIsInNvdXJjZXMiOlsid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2hhcmVkL2Jhc2Uuc2VydmljZS50cz9hMzRkIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgQnJvd3Nlck1hbmFnZXIgfSBmcm9tICcuLi9jb3JlL2Jyb3dzZXIvYnJvd3Nlci5tYW5hZ2VyJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VTZXJ2aWNlIHtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbmZpZzogQ29uZmlnO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYnJvd3Nlck1hbmFnZXI6IEJyb3dzZXJNYW5hZ2VyO1xuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnLCBicm93c2VyTWFuYWdlcj86IEJyb3dzZXJNYW5hZ2VyKSB7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgdGhpcy5icm93c2VyTWFuYWdlciA9IGJyb3dzZXJNYW5hZ2VyID8/IG5ldyBCcm93c2VyTWFuYWdlcihjb25maWcpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldEJyb3dzZXJNYW5hZ2VyKCk6IEJyb3dzZXJNYW5hZ2VyIHtcbiAgICByZXR1cm4gdGhpcy5icm93c2VyTWFuYWdlcjtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRDb25maWcoKTogQ29uZmlnIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWc7XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///103\n\n}");
18
+
19
+ /***/ }),
20
+
21
+ /***/ 181:
22
+ /***/ ((module) => {
23
+
24
+ module.exports = require("buffer");
25
+
26
+ /***/ }),
27
+
28
+ /***/ 290:
29
+ /***/ ((module) => {
30
+
31
+ module.exports = require("async_hooks");
32
+
33
+ /***/ }),
34
+
35
+ /***/ 805:
36
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
37
+
38
+ eval("{/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ TK: () => (/* binding */ COMMON_MODAL_SELECTORS),\n/* harmony export */ aB: () => (/* binding */ COMMON_STATUS_SELECTORS),\n/* harmony export */ mR: () => (/* binding */ COMMON_FILE_SELECTORS),\n/* harmony export */ mu: () => (/* binding */ COMMON_TEXT_PATTERNS),\n/* harmony export */ ox: () => (/* binding */ COMMON_BUTTON_SELECTORS)\n/* harmony export */ });\n/**\n * Shared CSS selectors and constants for XHS operations\n * Centralized location for all selector definitions to improve maintainability\n */\n/**\n * Common button selectors used across different services\n */\nconst COMMON_BUTTON_SELECTORS = {\n CONFIRM: [\n '.confirm-btn',\n 'button.confirm-btn',\n 'button[class*=\"confirm\"]',\n '.ok-btn',\n 'button:contains(\"确认\")',\n 'button:contains(\"确定\")',\n 'button:contains(\"confirm\")',\n 'button:contains(\"ok\")',\n '[aria-label*=\"确认\"]',\n '[aria-label*=\"确定\"]',\n ],\n CANCEL: [\n 'button[class*=\"cancel\"]',\n '.cancel-btn',\n 'button:contains(\"取消\")',\n 'button:contains(\"cancel\")',\n '[aria-label*=\"取消\"]',\n ],\n DELETE: [\n 'button[class*=\"delete\"]',\n '.delete-btn',\n '[class*=\"remove\"]',\n '.remove-btn',\n 'button[title*=\"删除\"]',\n 'button[title*=\"delete\"]',\n '[aria-label*=\"删除\"]',\n '[aria-label*=\"delete\"]',\n 'button:contains(\"删除\")',\n 'button:contains(\"delete\")',\n ],\n MORE_OPTIONS: [\n 'button[class*=\"more\"]',\n '.more-btn',\n '[class*=\"menu\"]',\n '.menu-btn',\n 'button[class*=\"action\"]',\n '.action-btn',\n 'button[class*=\"option\"]',\n '.option-btn',\n 'button[title*=\"更多\"]',\n 'button[title*=\"more\"]',\n '[aria-label*=\"更多\"]',\n '[aria-label*=\"more\"]',\n 'button:contains(\"⋯\")',\n 'button:contains(\"...\")',\n '.three-dots',\n '.ellipsis',\n ],\n};\n/**\n * Common modal and dialog selectors\n */\nconst COMMON_MODAL_SELECTORS = {\n CONFIRM: [\n '.modal button[class*=\"confirm\"]',\n '.dialog button[class*=\"confirm\"]',\n '[class*=\"modal\"] button[class*=\"confirm\"]',\n '.ant-modal button[class*=\"confirm\"]',\n '.el-dialog button[class*=\"confirm\"]',\n ],\n CANCEL: [\n '.modal button[class*=\"cancel\"]',\n '.dialog button[class*=\"cancel\"]',\n '[class*=\"modal\"] button[class*=\"cancel\"]',\n '.ant-modal button[class*=\"cancel\"]',\n '.el-dialog button[class*=\"cancel\"]',\n ],\n DROPDOWN_MENU: [\n '.dropdown-menu',\n '.menu-list',\n '[class*=\"dropdown\"]',\n '.context-menu',\n '.action-menu',\n '.options-menu',\n '[role=\"menu\"]',\n '.popover-menu',\n ],\n};\n/**\n * Common status and indicator selectors\n */\nconst COMMON_STATUS_SELECTORS = {\n SUCCESS: [\n '.success-message',\n '.publish-success',\n '[data-testid=\"publish-success\"]',\n '.toast-success',\n '.upload-success',\n '.video-upload-success',\n '.video-processing-complete',\n '.upload-complete',\n ],\n ERROR: [\n '.error-message',\n '.publish-error',\n '[data-testid=\"publish-error\"]',\n '.toast-error',\n '.error-toast',\n '.upload-error',\n '.video-upload-error',\n ],\n PROCESSING: [\n '.video-processing',\n '.upload-progress',\n '.processing-indicator',\n '[class*=\"processing\"]',\n '[class*=\"uploading\"]',\n '.progress-bar',\n '.upload-status',\n ],\n TOAST: ['.toast', '.message', '.notification', '[role=\"alert\"]', '.ant-message', '.el-message'],\n};\n/**\n * Common text patterns for status detection\n */\nconst COMMON_TEXT_PATTERNS = {\n SUCCESS: ['成功', 'success', '完成'],\n ERROR: ['失败', 'error', '错误'],\n PROCESSING: ['处理中', '上传中', 'processing', 'uploading', '进度'],\n};\n/**\n * Common file input selectors\n */\nconst COMMON_FILE_SELECTORS = {\n FILE_INPUT: [\n 'input[type=file]',\n '.upload-input',\n 'input[accept*=\"video\"]',\n 'input[accept*=\"mp4\"]',\n 'input[class*=\"upload\"]',\n 'input[class*=\"file\"]',\n ],\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QkFBc0I7S0FDdkI7Q0FDTyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQvc2VsZWN0b3JzLnRzP2RhZGEiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTaGFyZWQgQ1NTIHNlbGVjdG9ycyBhbmQgY29uc3RhbnRzIGZvciBYSFMgb3BlcmF0aW9uc1xuICogQ2VudHJhbGl6ZWQgbG9jYXRpb24gZm9yIGFsbCBzZWxlY3RvciBkZWZpbml0aW9ucyB0byBpbXByb3ZlIG1haW50YWluYWJpbGl0eVxuICovXG5cbi8qKlxuICogQ29tbW9uIGJ1dHRvbiBzZWxlY3RvcnMgdXNlZCBhY3Jvc3MgZGlmZmVyZW50IHNlcnZpY2VzXG4gKi9cbmV4cG9ydCBjb25zdCBDT01NT05fQlVUVE9OX1NFTEVDVE9SUyA9IHtcbiAgQ09ORklSTTogW1xuICAgICcuY29uZmlybS1idG4nLFxuICAgICdidXR0b24uY29uZmlybS1idG4nLFxuICAgICdidXR0b25bY2xhc3MqPVwiY29uZmlybVwiXScsXG4gICAgJy5vay1idG4nLFxuICAgICdidXR0b246Y29udGFpbnMoXCLnoa7orqRcIiknLFxuICAgICdidXR0b246Y29udGFpbnMoXCLnoa7lrppcIiknLFxuICAgICdidXR0b246Y29udGFpbnMoXCJjb25maXJtXCIpJyxcbiAgICAnYnV0dG9uOmNvbnRhaW5zKFwib2tcIiknLFxuICAgICdbYXJpYS1sYWJlbCo9XCLnoa7orqRcIl0nLFxuICAgICdbYXJpYS1sYWJlbCo9XCLnoa7lrppcIl0nLFxuICBdLFxuICBDQU5DRUw6IFtcbiAgICAnYnV0dG9uW2NsYXNzKj1cImNhbmNlbFwiXScsXG4gICAgJy5jYW5jZWwtYnRuJyxcbiAgICAnYnV0dG9uOmNvbnRhaW5zKFwi5Y+W5raIXCIpJyxcbiAgICAnYnV0dG9uOmNvbnRhaW5zKFwiY2FuY2VsXCIpJyxcbiAgICAnW2FyaWEtbGFiZWwqPVwi5Y+W5raIXCJdJyxcbiAgXSxcbiAgREVMRVRFOiBbXG4gICAgJ2J1dHRvbltjbGFzcyo9XCJkZWxldGVcIl0nLFxuICAgICcuZGVsZXRlLWJ0bicsXG4gICAgJ1tjbGFzcyo9XCJyZW1vdmVcIl0nLFxuICAgICcucmVtb3ZlLWJ0bicsXG4gICAgJ2J1dHRvblt0aXRsZSo9XCLliKDpmaRcIl0nLFxuICAgICdidXR0b25bdGl0bGUqPVwiZGVsZXRlXCJdJyxcbiAgICAnW2FyaWEtbGFiZWwqPVwi5Yig6ZmkXCJdJyxcbiAgICAnW2FyaWEtbGFiZWwqPVwiZGVsZXRlXCJdJyxcbiAgICAnYnV0dG9uOmNvbnRhaW5zKFwi5Yig6ZmkXCIpJyxcbiAgICAnYnV0dG9uOmNvbnRhaW5zKFwiZGVsZXRlXCIpJyxcbiAgXSxcbiAgTU9SRV9PUFRJT05TOiBbXG4gICAgJ2J1dHRvbltjbGFzcyo9XCJtb3JlXCJdJyxcbiAgICAnLm1vcmUtYnRuJyxcbiAgICAnW2NsYXNzKj1cIm1lbnVcIl0nLFxuICAgICcubWVudS1idG4nLFxuICAgICdidXR0b25bY2xhc3MqPVwiYWN0aW9uXCJdJyxcbiAgICAnLmFjdGlvbi1idG4nLFxuICAgICdidXR0b25bY2xhc3MqPVwib3B0aW9uXCJdJyxcbiAgICAnLm9wdGlvbi1idG4nLFxuICAgICdidXR0b25bdGl0bGUqPVwi5pu05aSaXCJdJyxcbiAgICAnYnV0dG9uW3RpdGxlKj1cIm1vcmVcIl0nLFxuICAgICdbYXJpYS1sYWJlbCo9XCLmm7TlpJpcIl0nLFxuICAgICdbYXJpYS1sYWJlbCo9XCJtb3JlXCJdJyxcbiAgICAnYnV0dG9uOmNvbnRhaW5zKFwi4ouvXCIpJyxcbiAgICAnYnV0dG9uOmNvbnRhaW5zKFwiLi4uXCIpJyxcbiAgICAnLnRocmVlLWRvdHMnLFxuICAgICcuZWxsaXBzaXMnLFxuICBdLFxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBDb21tb24gbW9kYWwgYW5kIGRpYWxvZyBzZWxlY3RvcnNcbiAqL1xuZXhwb3J0IGNvbnN0IENPTU1PTl9NT0RBTF9TRUxFQ1RPUlMgPSB7XG4gIENPTkZJUk06IFtcbiAgICAnLm1vZGFsIGJ1dHRvbltjbGFzcyo9XCJjb25maXJtXCJdJyxcbiAgICAnLmRpYWxvZyBidXR0b25bY2xhc3MqPVwiY29uZmlybVwiXScsXG4gICAgJ1tjbGFzcyo9XCJtb2RhbFwiXSBidXR0b25bY2xhc3MqPVwiY29uZmlybVwiXScsXG4gICAgJy5hbnQtbW9kYWwgYnV0dG9uW2NsYXNzKj1cImNvbmZpcm1cIl0nLFxuICAgICcuZWwtZGlhbG9nIGJ1dHRvbltjbGFzcyo9XCJjb25maXJtXCJdJyxcbiAgXSxcbiAgQ0FOQ0VMOiBbXG4gICAgJy5tb2RhbCBidXR0b25bY2xhc3MqPVwiY2FuY2VsXCJdJyxcbiAgICAnLmRpYWxvZyBidXR0b25bY2xhc3MqPVwiY2FuY2VsXCJdJyxcbiAgICAnW2NsYXNzKj1cIm1vZGFsXCJdIGJ1dHRvbltjbGFzcyo9XCJjYW5jZWxcIl0nLFxuICAgICcuYW50LW1vZGFsIGJ1dHRvbltjbGFzcyo9XCJjYW5jZWxcIl0nLFxuICAgICcuZWwtZGlhbG9nIGJ1dHRvbltjbGFzcyo9XCJjYW5jZWxcIl0nLFxuICBdLFxuICBEUk9QRE9XTl9NRU5VOiBbXG4gICAgJy5kcm9wZG93bi1tZW51JyxcbiAgICAnLm1lbnUtbGlzdCcsXG4gICAgJ1tjbGFzcyo9XCJkcm9wZG93blwiXScsXG4gICAgJy5jb250ZXh0LW1lbnUnLFxuICAgICcuYWN0aW9uLW1lbnUnLFxuICAgICcub3B0aW9ucy1tZW51JyxcbiAgICAnW3JvbGU9XCJtZW51XCJdJyxcbiAgICAnLnBvcG92ZXItbWVudScsXG4gIF0sXG59IGFzIGNvbnN0O1xuXG4vKipcbiAqIENvbW1vbiBzdGF0dXMgYW5kIGluZGljYXRvciBzZWxlY3RvcnNcbiAqL1xuZXhwb3J0IGNvbnN0IENPTU1PTl9TVEFUVVNfU0VMRUNUT1JTID0ge1xuICBTVUNDRVNTOiBbXG4gICAgJy5zdWNjZXNzLW1lc3NhZ2UnLFxuICAgICcucHVibGlzaC1zdWNjZXNzJyxcbiAgICAnW2RhdGEtdGVzdGlkPVwicHVibGlzaC1zdWNjZXNzXCJdJyxcbiAgICAnLnRvYXN0LXN1Y2Nlc3MnLFxuICAgICcudXBsb2FkLXN1Y2Nlc3MnLFxuICAgICcudmlkZW8tdXBsb2FkLXN1Y2Nlc3MnLFxuICAgICcudmlkZW8tcHJvY2Vzc2luZy1jb21wbGV0ZScsXG4gICAgJy51cGxvYWQtY29tcGxldGUnLFxuICBdLFxuICBFUlJPUjogW1xuICAgICcuZXJyb3ItbWVzc2FnZScsXG4gICAgJy5wdWJsaXNoLWVycm9yJyxcbiAgICAnW2RhdGEtdGVzdGlkPVwicHVibGlzaC1lcnJvclwiXScsXG4gICAgJy50b2FzdC1lcnJvcicsXG4gICAgJy5lcnJvci10b2FzdCcsXG4gICAgJy51cGxvYWQtZXJyb3InLFxuICAgICcudmlkZW8tdXBsb2FkLWVycm9yJyxcbiAgXSxcbiAgUFJPQ0VTU0lORzogW1xuICAgICcudmlkZW8tcHJvY2Vzc2luZycsXG4gICAgJy51cGxvYWQtcHJvZ3Jlc3MnLFxuICAgICcucHJvY2Vzc2luZy1pbmRpY2F0b3InLFxuICAgICdbY2xhc3MqPVwicHJvY2Vzc2luZ1wiXScsXG4gICAgJ1tjbGFzcyo9XCJ1cGxvYWRpbmdcIl0nLFxuICAgICcucHJvZ3Jlc3MtYmFyJyxcbiAgICAnLnVwbG9hZC1zdGF0dXMnLFxuICBdLFxuICBUT0FTVDogWycudG9hc3QnLCAnLm1lc3NhZ2UnLCAnLm5vdGlmaWNhdGlvbicsICdbcm9sZT1cImFsZXJ0XCJdJywgJy5hbnQtbWVzc2FnZScsICcuZWwtbWVzc2FnZSddLFxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBDb21tb24gdGV4dCBwYXR0ZXJucyBmb3Igc3RhdHVzIGRldGVjdGlvblxuICovXG5leHBvcnQgY29uc3QgQ09NTU9OX1RFWFRfUEFUVEVSTlMgPSB7XG4gIFNVQ0NFU1M6IFsn5oiQ5YqfJywgJ3N1Y2Nlc3MnLCAn5a6M5oiQJ10sXG4gIEVSUk9SOiBbJ+Wksei0pScsICdlcnJvcicsICfplJnor68nXSxcbiAgUFJPQ0VTU0lORzogWyflpITnkIbkuK0nLCAn5LiK5Lyg5LitJywgJ3Byb2Nlc3NpbmcnLCAndXBsb2FkaW5nJywgJ+i/m+W6piddLFxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBDb21tb24gZmlsZSBpbnB1dCBzZWxlY3RvcnNcbiAqL1xuZXhwb3J0IGNvbnN0IENPTU1PTl9GSUxFX1NFTEVDVE9SUyA9IHtcbiAgRklMRV9JTlBVVDogW1xuICAgICdpbnB1dFt0eXBlPWZpbGVdJyxcbiAgICAnLnVwbG9hZC1pbnB1dCcsXG4gICAgJ2lucHV0W2FjY2VwdCo9XCJ2aWRlb1wiXScsXG4gICAgJ2lucHV0W2FjY2VwdCo9XCJtcDRcIl0nLFxuICAgICdpbnB1dFtjbGFzcyo9XCJ1cGxvYWRcIl0nLFxuICAgICdpbnB1dFtjbGFzcyo9XCJmaWxlXCJdJyxcbiAgXSxcbn0gYXMgY29uc3Q7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///805\n\n}");
39
+
40
+ /***/ }),
41
+
42
+ /***/ 1708:
43
+ /***/ ((module) => {
44
+
45
+ module.exports = require("node:process");
46
+
47
+ /***/ }),
48
+
49
+ /***/ 2094:
50
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
51
+
52
+ eval("{/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ IB: () => (/* binding */ validateRequiredParams),\n/* harmony export */ ah: () => (/* binding */ safeErrorHandler),\n/* harmony export */ mo: () => (/* binding */ createMcpErrorResponse),\n/* harmony export */ q$: () => (/* binding */ createMcpToolResponse),\n/* harmony export */ yy: () => (/* binding */ sleep)\n/* harmony export */ });\n/* unused harmony exports isString, isNumber, isArray, safeJsonParse, validatePublishNoteParams, createApiResponse, retryWithBackoff */\n/**\n * Common utility functions for XHS MCP Server\n */\n/**\n * Sleep utility function\n * @param ms - Milliseconds to sleep\n * @returns Promise that resolves after the specified time\n */\nfunction sleep(ms) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n/**\n * Safe error handler that logs errors without throwing\n * @param error - Error to handle\n * @param context - Additional context for the error\n * @param logger - Logger instance to use\n */\nfunction safeErrorHandler(error, context, logger) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`${context}: ${errorMessage}`);\n}\n/**\n * Validate required parameters\n * @param params - Object containing parameters to validate\n * @param requiredKeys - Array of required parameter keys\n * @throws Error if any required parameter is missing\n */\nfunction validateRequiredParams(params, requiredKeys) {\n const missingKeys = requiredKeys.filter((key) => params[key] === undefined || params[key] === null || params[key] === '');\n if (missingKeys.length > 0) {\n throw new Error(`Missing required parameters: ${missingKeys.join(', ')}`);\n }\n}\n/**\n * Type guard to check if a value is a string\n */\nfunction isString(value) {\n return typeof value === 'string';\n}\n/**\n * Type guard to check if a value is a number\n */\nfunction isNumber(value) {\n return typeof value === 'number' && !Number.isNaN(value);\n}\n/**\n * Type guard to check if a value is an array\n */\nfunction isArray(value) {\n return Array.isArray(value);\n}\n/**\n * Safely parse JSON string\n * @param jsonString - JSON string to parse\n * @param fallback - Fallback value if parsing fails\n * @returns Parsed object or fallback value\n */\nfunction safeJsonParse(jsonString, fallback) {\n try {\n return JSON.parse(jsonString);\n }\n catch {\n return fallback;\n }\n}\n/**\n * Validate publish note parameters with length constraints\n * @param title - Note title\n * @param note - Note content\n * @param imagePaths - Array of image paths\n * @throws Error if any parameter violates constraints\n */\nfunction validatePublishNoteParams(title, note, imagePaths) {\n // Validate title length (max 20 characters)\n if (title && title.length > 20) {\n throw new Error(`Title length cannot exceed 20 characters. Current length: ${title.length}`);\n }\n // Validate note content length (max 1000 characters)\n if (note && note.length > 1000) {\n throw new Error(`Note content length cannot exceed 1000 characters. Current length: ${note.length}`);\n }\n // Validate image count (max 18 images)\n if (imagePaths && imagePaths.length > 18) {\n throw new Error(`Maximum 18 images allowed. Current count: ${imagePaths.length}`);\n }\n}\n/**\n * Create a standardized response object\n * @param success - Whether the operation was successful\n * @param data - Optional data to include\n * @param message - Optional message\n * @param error - Optional error information\n * @returns Standardized response object\n */\nfunction createApiResponse(success, data, message, error) {\n const response = { success };\n if (data !== undefined)\n response.data = data;\n if (message !== undefined)\n response.message = message;\n if (error !== undefined)\n response.error = error;\n return response;\n}\n/**\n * Retry a function with exponential backoff\n * @param fn - Function to retry\n * @param maxRetries - Maximum number of retries\n * @param baseDelay - Base delay in milliseconds\n * @returns Promise that resolves with the function result\n */\nasync function retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) {\n let lastError;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n }\n catch (error) {\n lastError = error;\n if (attempt === maxRetries) {\n throw lastError;\n }\n const delay = baseDelay * Math.pow(2, attempt);\n await sleep(delay);\n }\n }\n throw lastError;\n}\n/**\n * Create a standardized MCP tool response\n * @param data - Data to include in the response\n * @returns Standardized MCP response format\n */\nfunction createMcpToolResponse(data) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(data, null, 2),\n },\n ],\n };\n}\n/**\n * Create a standardized MCP error response\n * @param error - Error to format\n * @returns Standardized MCP error response format\n */\nfunction createMcpErrorResponse(error) {\n const errorData = error instanceof Error\n ? {\n success: false,\n error: 'UnknownError',\n message: error.message,\n }\n : {\n success: false,\n error: 'UnknownError',\n message: String(error),\n };\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(errorData, null, 2),\n },\n ],\n };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O1FBQ0wsT0FBTyxFQUFFO1lBQ1A7Z0JBQ0UsSUFBSSxFQUFFLE1BQU07Z0JBQ1osSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7YUFDcEM7U0FDRjtLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNJLFNBQVMsc0JBQXNCLENBQUMsS0FBYztJQUduRCxNQUFNLFNBQVMsR0FDYixLQUFLLFlBQVksS0FBSztRQUNwQixDQUFDLENBQUM7WUFDRSxPQUFPLEVBQUUsS0FBSztZQUNkLEtBQUssRUFBRSxjQUFjO1lBQ3JCLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztTQUN2QjtRQUNILENBQUMsQ0FBQztZQUNFLE9BQU8sRUFBRSxLQUFLO1lBQ2QsS0FBSyxFQUFFLGNBQWM7WUFDckIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUM7U0FDdkIsQ0FBQztJQUVSLE9BQU87UUFDTCxPQUFPLEVBQUU7WUFDUDtnQkFDRSxJQUFJLEVBQUUsTUFBTTtnQkFDWixJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQzthQUN6QztTQUNGO0tBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NoYXJlZC91dGlscy50cz85YzVjIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29tbW9uIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbi8qKlxuICogU2xlZXAgdXRpbGl0eSBmdW5jdGlvblxuICogQHBhcmFtIG1zIC0gTWlsbGlzZWNvbmRzIHRvIHNsZWVwXG4gKiBAcmV0dXJucyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIHNwZWNpZmllZCB0aW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xufVxuXG4vKipcbiAqIFNhZmUgZXJyb3IgaGFuZGxlciB0aGF0IGxvZ3MgZXJyb3JzIHdpdGhvdXQgdGhyb3dpbmdcbiAqIEBwYXJhbSBlcnJvciAtIEVycm9yIHRvIGhhbmRsZVxuICogQHBhcmFtIGNvbnRleHQgLSBBZGRpdGlvbmFsIGNvbnRleHQgZm9yIHRoZSBlcnJvclxuICogQHBhcmFtIGxvZ2dlciAtIExvZ2dlciBpbnN0YW5jZSB0byB1c2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNhZmVFcnJvckhhbmRsZXIoXG4gIGVycm9yOiB1bmtub3duLFxuICBjb250ZXh0OiBzdHJpbmcsXG4gIGxvZ2dlcjogeyBlcnJvcjogKG1lc3NhZ2U6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkIH1cbik6IHZvaWQge1xuICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gIGxvZ2dlci5lcnJvcihgJHtjb250ZXh0fTogJHtlcnJvck1lc3NhZ2V9YCk7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgcmVxdWlyZWQgcGFyYW1ldGVyc1xuICogQHBhcmFtIHBhcmFtcyAtIE9iamVjdCBjb250YWluaW5nIHBhcmFtZXRlcnMgdG8gdmFsaWRhdGVcbiAqIEBwYXJhbSByZXF1aXJlZEtleXMgLSBBcnJheSBvZiByZXF1aXJlZCBwYXJhbWV0ZXIga2V5c1xuICogQHRocm93cyBFcnJvciBpZiBhbnkgcmVxdWlyZWQgcGFyYW1ldGVyIGlzIG1pc3NpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUmVxdWlyZWRQYXJhbXMoXG4gIHBhcmFtczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIHJlcXVpcmVkS2V5czogc3RyaW5nW11cbik6IHZvaWQge1xuICBjb25zdCBtaXNzaW5nS2V5cyA9IHJlcXVpcmVkS2V5cy5maWx0ZXIoXG4gICAgKGtleSkgPT4gcGFyYW1zW2tleV0gPT09IHVuZGVmaW5lZCB8fCBwYXJhbXNba2V5XSA9PT0gbnVsbCB8fCBwYXJhbXNba2V5XSA9PT0gJydcbiAgKTtcblxuICBpZiAobWlzc2luZ0tleXMubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXJzOiAke21pc3NpbmdLZXlzLmpvaW4oJywgJyl9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgYSBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgc3RyaW5nIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZyc7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgbnVtYmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlciB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmICFOdW1iZXIuaXNOYU4odmFsdWUpO1xufVxuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBhbiBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBcnJheTxUPih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFRbXSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKTtcbn1cblxuLyoqXG4gKiBTYWZlbHkgcGFyc2UgSlNPTiBzdHJpbmdcbiAqIEBwYXJhbSBqc29uU3RyaW5nIC0gSlNPTiBzdHJpbmcgdG8gcGFyc2VcbiAqIEBwYXJhbSBmYWxsYmFjayAtIEZhbGxiYWNrIHZhbHVlIGlmIHBhcnNpbmcgZmFpbHNcbiAqIEByZXR1cm5zIFBhcnNlZCBvYmplY3Qgb3IgZmFsbGJhY2sgdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNhZmVKc29uUGFyc2U8VD4oanNvblN0cmluZzogc3RyaW5nLCBmYWxsYmFjazogVCk6IFQge1xuICB0cnkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGpzb25TdHJpbmcpIGFzIFQ7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxsYmFjaztcbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlIHB1Ymxpc2ggbm90ZSBwYXJhbWV0ZXJzIHdpdGggbGVuZ3RoIGNvbnN0cmFpbnRzXG4gKiBAcGFyYW0gdGl0bGUgLSBOb3RlIHRpdGxlXG4gKiBAcGFyYW0gbm90ZSAtIE5vdGUgY29udGVudFxuICogQHBhcmFtIGltYWdlUGF0aHMgLSBBcnJheSBvZiBpbWFnZSBwYXRoc1xuICogQHRocm93cyBFcnJvciBpZiBhbnkgcGFyYW1ldGVyIHZpb2xhdGVzIGNvbnN0cmFpbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVB1Ymxpc2hOb3RlUGFyYW1zKHRpdGxlOiBzdHJpbmcsIG5vdGU6IHN0cmluZywgaW1hZ2VQYXRoczogc3RyaW5nW10pOiB2b2lkIHtcbiAgLy8gVmFsaWRhdGUgdGl0bGUgbGVuZ3RoIChtYXggMjAgY2hhcmFjdGVycylcbiAgaWYgKHRpdGxlICYmIHRpdGxlLmxlbmd0aCA+IDIwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBUaXRsZSBsZW5ndGggY2Fubm90IGV4Y2VlZCAyMCBjaGFyYWN0ZXJzLiBDdXJyZW50IGxlbmd0aDogJHt0aXRsZS5sZW5ndGh9YCk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZSBub3RlIGNvbnRlbnQgbGVuZ3RoIChtYXggMTAwMCBjaGFyYWN0ZXJzKVxuICBpZiAobm90ZSAmJiBub3RlLmxlbmd0aCA+IDEwMDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTm90ZSBjb250ZW50IGxlbmd0aCBjYW5ub3QgZXhjZWVkIDEwMDAgY2hhcmFjdGVycy4gQ3VycmVudCBsZW5ndGg6ICR7bm90ZS5sZW5ndGh9YFxuICAgICk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZSBpbWFnZSBjb3VudCAobWF4IDE4IGltYWdlcylcbiAgaWYgKGltYWdlUGF0aHMgJiYgaW1hZ2VQYXRocy5sZW5ndGggPiAxOCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgTWF4aW11bSAxOCBpbWFnZXMgYWxsb3dlZC4gQ3VycmVudCBjb3VudDogJHtpbWFnZVBhdGhzLmxlbmd0aH1gKTtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZSBhIHN0YW5kYXJkaXplZCByZXNwb25zZSBvYmplY3RcbiAqIEBwYXJhbSBzdWNjZXNzIC0gV2hldGhlciB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsXG4gKiBAcGFyYW0gZGF0YSAtIE9wdGlvbmFsIGRhdGEgdG8gaW5jbHVkZVxuICogQHBhcmFtIG1lc3NhZ2UgLSBPcHRpb25hbCBtZXNzYWdlXG4gKiBAcGFyYW0gZXJyb3IgLSBPcHRpb25hbCBlcnJvciBpbmZvcm1hdGlvblxuICogQHJldHVybnMgU3RhbmRhcmRpemVkIHJlc3BvbnNlIG9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXBpUmVzcG9uc2U8VCA9IHVua25vd24+KFxuICBzdWNjZXNzOiBib29sZWFuLFxuICBkYXRhPzogVCxcbiAgbWVzc2FnZT86IHN0cmluZyxcbiAgZXJyb3I/OiBzdHJpbmdcbik6IHsgc3VjY2VzczogYm9vbGVhbjsgZGF0YT86IFQ7IG1lc3NhZ2U/OiBzdHJpbmc7IGVycm9yPzogc3RyaW5nIH0ge1xuICBjb25zdCByZXNwb25zZTogeyBzdWNjZXNzOiBib29sZWFuOyBkYXRhPzogVDsgbWVzc2FnZT86IHN0cmluZzsgZXJyb3I/OiBzdHJpbmcgfSA9IHsgc3VjY2VzcyB9O1xuXG4gIGlmIChkYXRhICE9PSB1bmRlZmluZWQpIHJlc3BvbnNlLmRhdGEgPSBkYXRhO1xuICBpZiAobWVzc2FnZSAhPT0gdW5kZWZpbmVkKSByZXNwb25zZS5tZXNzYWdlID0gbWVzc2FnZTtcbiAgaWYgKGVycm9yICE9PSB1bmRlZmluZWQpIHJlc3BvbnNlLmVycm9yID0gZXJyb3I7XG5cbiAgcmV0dXJuIHJlc3BvbnNlO1xufVxuXG4vKipcbiAqIFJldHJ5IGEgZnVuY3Rpb24gd2l0aCBleHBvbmVudGlhbCBiYWNrb2ZmXG4gKiBAcGFyYW0gZm4gLSBGdW5jdGlvbiB0byByZXRyeVxuICogQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzXG4gKiBAcGFyYW0gYmFzZURlbGF5IC0gQmFzZSBkZWxheSBpbiBtaWxsaXNlY29uZHNcbiAqIEByZXR1cm5zIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBmdW5jdGlvbiByZXN1bHRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJldHJ5V2l0aEJhY2tvZmY8VD4oXG4gIGZuOiAoKSA9PiBQcm9taXNlPFQ+LFxuICBtYXhSZXRyaWVzOiBudW1iZXIgPSAzLFxuICBiYXNlRGVsYXk6IG51bWJlciA9IDEwMDBcbik6IFByb21pc2U8VD4ge1xuICBsZXQgbGFzdEVycm9yOiBFcnJvcjtcblxuICBmb3IgKGxldCBhdHRlbXB0ID0gMDsgYXR0ZW1wdCA8PSBtYXhSZXRyaWVzOyBhdHRlbXB0KyspIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGZuKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxhc3RFcnJvciA9IGVycm9yIGFzIEVycm9yO1xuXG4gICAgICBpZiAoYXR0ZW1wdCA9PT0gbWF4UmV0cmllcykge1xuICAgICAgICB0aHJvdyBsYXN0RXJyb3I7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlbGF5ID0gYmFzZURlbGF5ICogTWF0aC5wb3coMiwgYXR0ZW1wdCk7XG4gICAgICBhd2FpdCBzbGVlcChkZWxheSk7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbGFzdEVycm9yITtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBzdGFuZGFyZGl6ZWQgTUNQIHRvb2wgcmVzcG9uc2VcbiAqIEBwYXJhbSBkYXRhIC0gRGF0YSB0byBpbmNsdWRlIGluIHRoZSByZXNwb25zZVxuICogQHJldHVybnMgU3RhbmRhcmRpemVkIE1DUCByZXNwb25zZSBmb3JtYXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1jcFRvb2xSZXNwb25zZTxUID0gdW5rbm93bj4oXG4gIGRhdGE6IFRcbik6IHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9IHtcbiAgcmV0dXJuIHtcbiAgICBjb250ZW50OiBbXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgMiksXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgc3RhbmRhcmRpemVkIE1DUCBlcnJvciByZXNwb25zZVxuICogQHBhcmFtIGVycm9yIC0gRXJyb3IgdG8gZm9ybWF0XG4gKiBAcmV0dXJucyBTdGFuZGFyZGl6ZWQgTUNQIGVycm9yIHJlc3BvbnNlIGZvcm1hdFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTWNwRXJyb3JSZXNwb25zZShlcnJvcjogdW5rbm93bik6IHtcbiAgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9Pjtcbn0ge1xuICBjb25zdCBlcnJvckRhdGEgPVxuICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3JcbiAgICAgID8ge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIGVycm9yOiAnVW5rbm93bkVycm9yJyxcbiAgICAgICAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLFxuICAgICAgICB9XG4gICAgICA6IHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvcjogJ1Vua25vd25FcnJvcicsXG4gICAgICAgICAgbWVzc2FnZTogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgfTtcblxuICByZXR1cm4ge1xuICAgIGNvbnRlbnQ6IFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeShlcnJvckRhdGEsIG51bGwsIDIpLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2094\n\n}");
53
+
54
+ /***/ }),
55
+
56
+ /***/ 2203:
57
+ /***/ ((module) => {
58
+
59
+ module.exports = require("stream");
60
+
61
+ /***/ }),
62
+
63
+ /***/ 2207:
64
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
65
+
66
+ eval("{\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n zj: () => (/* binding */ getConfig)\n});\n\n// UNUSED EXPORTS: ConfigManager, setConfig\n\n;// external \"os\"\nconst external_os_namespaceObject = require(\"os\");\n// EXTERNAL MODULE: external \"path\"\nvar external_path_ = __webpack_require__(6928);\n// EXTERNAL MODULE: external \"fs\"\nvar external_fs_ = __webpack_require__(9896);\n// EXTERNAL MODULE: external \"url\"\nvar external_url_ = __webpack_require__(7016);\n;// ./src/shared/config.ts\n/**\n * Configuration management for XHS MCP Server\n */\n\n\n\n\nclass ConfigManager {\n static instance;\n config;\n constructor() {\n this.config = this.createDefaultConfig();\n }\n static getInstance() {\n if (!ConfigManager.instance) {\n ConfigManager.instance = new ConfigManager();\n }\n return ConfigManager.instance;\n }\n getConfig() {\n return this.config;\n }\n updateConfig(updates) {\n this.config = { ...this.config, ...updates };\n }\n createDefaultConfig() {\n const appDataDir = (0,external_path_.join)((0,external_os_namespaceObject.homedir)(), '.xhs-mcp');\n const cookiesFile = (0,external_path_.join)(appDataDir, 'cookies.json');\n // Resolve package version from package.json (fallback to env or default)\n function resolvePackageVersion() {\n try {\n const hereFilePath = (0,external_url_.fileURLToPath)(\"file:///Users/rodin/Workspace/algovate/xhs/xhs-mcp/src/shared/config.ts\");\n const hereDir = (0,external_path_.dirname)(hereFilePath);\n // From src/lib/shared/config.ts → dist/lib/shared/config.js at runtime\n // package.json resides at project root relative to compiled file: ../../../package.json\n const pkgPath = (0,external_path_.join)(hereDir, '../../../package.json');\n const pkgRaw = (0,external_fs_.readFileSync)(pkgPath, 'utf-8');\n const pkg = JSON.parse(pkgRaw);\n if (pkg?.version && typeof pkg.version === 'string')\n return pkg.version;\n }\n catch {\n // ignore and fallback\n }\n return process.env.XHS_VERSION ?? '0.1.0';\n }\n const headlessEnv = process.env.XHS_HEADLESS;\n const browserConfig = {\n defaultTimeout: parseInt(process.env.XHS_BROWSER_TIMEOUT ?? '30000'),\n loginTimeout: parseInt(process.env.XHS_LOGIN_TIMEOUT ?? '300'),\n pageLoadTimeout: 30000,\n navigationTimeout: 30000,\n slowmo: 0,\n headlessDefault: headlessEnv == null ? true : headlessEnv.toLowerCase() === 'true',\n };\n const serverConfig = {\n name: process.env.XHS_SERVER_NAME ?? 'xhs-mcp',\n version: resolvePackageVersion(),\n description: 'XiaoHongShu MCP Server - TypeScript Version',\n defaultHost: process.env.XHS_HOST ?? '127.0.0.1',\n defaultPort: parseInt(process.env.XHS_PORT ?? '8000'),\n defaultTransport: 'stdio',\n };\n const logFileEnv = process.env.XHS_LOG_FILE;\n const logFileEnabled = logFileEnv == null ? false : logFileEnv.toLowerCase() === 'true';\n const loggingConfig = {\n level: process.env.XHS_LOG_LEVEL ?? 'INFO',\n format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s',\n fileEnabled: logFileEnabled,\n filePath: logFileEnabled ? (0,external_path_.join)(appDataDir, 'xhs-mcp.log') : undefined,\n };\n const pathsConfig = {\n appDataDir,\n cookiesFile,\n };\n const xhsConfig = {\n homeUrl: 'https://www.xiaohongshu.com',\n exploreUrl: 'https://www.xiaohongshu.com/explore',\n searchUrl: 'https://www.xiaohongshu.com/search_result',\n creatorPublishUrl: 'https://creator.xiaohongshu.com/publish/publish?source=official',\n creatorVideoPublishUrl: 'https://creator.xiaohongshu.com/publish/publish?source=official&from=tab_switch&target=video',\n loginOkSelector: '.main-container .user .link-wrapper .channel',\n requestDelay: 1.0,\n maxRetries: 3,\n retryDelay: 2.0,\n };\n return {\n browser: browserConfig,\n server: serverConfig,\n logging: loggingConfig,\n paths: pathsConfig,\n xhs: xhsConfig,\n };\n }\n toDict() {\n return {\n browser: {\n defaultTimeout: this.config.browser.defaultTimeout,\n loginTimeout: this.config.browser.loginTimeout,\n headlessDefault: this.config.browser.headlessDefault,\n },\n server: {\n name: this.config.server.name,\n version: this.config.server.version,\n defaultHost: this.config.server.defaultHost,\n defaultPort: this.config.server.defaultPort,\n },\n logging: {\n level: this.config.logging.level,\n fileEnabled: this.config.logging.fileEnabled,\n },\n paths: {\n appDataDir: this.config.paths.appDataDir,\n cookiesFile: this.config.paths.cookiesFile,\n },\n xhs: {\n homeUrl: this.config.xhs.homeUrl,\n exploreUrl: this.config.xhs.exploreUrl,\n maxRetries: this.config.xhs.maxRetries,\n },\n };\n }\n}\n// Global configuration instance\nlet globalConfig = null;\nfunction getConfig() {\n globalConfig ??= ConfigManager.getInstance().getConfig();\n return globalConfig;\n}\nfunction setConfig(config) {\n globalConfig = config;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUM7QUFFaEMsU0FBUyxTQUFTO0lBQ3ZCLFlBQVksS0FBSyxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDekQsT0FBTyxZQUFZLENBQUM7QUFDdEIsQ0FBQztBQUVNLFNBQVMsU0FBUyxDQUFDLE1BQWM7SUFDdEMsWUFBWSxHQUFHLE1BQU0sQ0FBQztBQUN4QixDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwib3NcIj9lZjUzIiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2hhcmVkL2NvbmZpZy50cz9kNTZmIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IF9fV0VCUEFDS19OQU1FU1BBQ0VfT0JKRUNUX18gPSByZXF1aXJlKFwib3NcIik7IiwiLyoqXG4gKiBDb25maWd1cmF0aW9uIG1hbmFnZW1lbnQgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuaW1wb3J0IHtcbiAgQ29uZmlnLFxuICBCcm93c2VyQ29uZmlnLFxuICBTZXJ2ZXJDb25maWcsXG4gIExvZ2dpbmdDb25maWcsXG4gIFBhdGhzQ29uZmlnLFxuICBYSFNDb25maWcsXG59IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgaG9tZWRpciB9IGZyb20gJ29zJztcbmltcG9ydCB7IGpvaW4sIGRpcm5hbWUgfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IHJlYWRGaWxlU3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tICd1cmwnO1xuXG5leHBvcnQgY2xhc3MgQ29uZmlnTWFuYWdlciB7XG4gIHByaXZhdGUgc3RhdGljIGluc3RhbmNlOiBDb25maWdNYW5hZ2VyO1xuICBwcml2YXRlIGNvbmZpZzogQ29uZmlnO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5jb25maWcgPSB0aGlzLmNyZWF0ZURlZmF1bHRDb25maWcoKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgZ2V0SW5zdGFuY2UoKTogQ29uZmlnTWFuYWdlciB7XG4gICAgaWYgKCFDb25maWdNYW5hZ2VyLmluc3RhbmNlKSB7XG4gICAgICBDb25maWdNYW5hZ2VyLmluc3RhbmNlID0gbmV3IENvbmZpZ01hbmFnZXIoKTtcbiAgICB9XG4gICAgcmV0dXJuIENvbmZpZ01hbmFnZXIuaW5zdGFuY2U7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q29uZmlnKCk6IENvbmZpZyB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnO1xuICB9XG5cbiAgcHVibGljIHVwZGF0ZUNvbmZpZyh1cGRhdGVzOiBQYXJ0aWFsPENvbmZpZz4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbmZpZyA9IHsgLi4udGhpcy5jb25maWcsIC4uLnVwZGF0ZXMgfTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRGVmYXVsdENvbmZpZygpOiBDb25maWcge1xuICAgIGNvbnN0IGFwcERhdGFEaXIgPSBqb2luKGhvbWVkaXIoKSwgJy54aHMtbWNwJyk7XG4gICAgY29uc3QgY29va2llc0ZpbGUgPSBqb2luKGFwcERhdGFEaXIsICdjb29raWVzLmpzb24nKTtcblxuICAgIC8vIFJlc29sdmUgcGFja2FnZSB2ZXJzaW9uIGZyb20gcGFja2FnZS5qc29uIChmYWxsYmFjayB0byBlbnYgb3IgZGVmYXVsdClcbiAgICBmdW5jdGlvbiByZXNvbHZlUGFja2FnZVZlcnNpb24oKTogc3RyaW5nIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGhlcmVGaWxlUGF0aCA9IGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKTtcbiAgICAgICAgY29uc3QgaGVyZURpciA9IGRpcm5hbWUoaGVyZUZpbGVQYXRoKTtcbiAgICAgICAgLy8gRnJvbSBzcmMvbGliL3NoYXJlZC9jb25maWcudHMg4oaSIGRpc3QvbGliL3NoYXJlZC9jb25maWcuanMgYXQgcnVudGltZVxuICAgICAgICAvLyBwYWNrYWdlLmpzb24gcmVzaWRlcyBhdCBwcm9qZWN0IHJvb3QgcmVsYXRpdmUgdG8gY29tcGlsZWQgZmlsZTogLi4vLi4vLi4vcGFja2FnZS5qc29uXG4gICAgICAgIGNvbnN0IHBrZ1BhdGggPSBqb2luKGhlcmVEaXIsICcuLi8uLi8uLi9wYWNrYWdlLmpzb24nKTtcbiAgICAgICAgY29uc3QgcGtnUmF3ID0gcmVhZEZpbGVTeW5jKHBrZ1BhdGgsICd1dGYtOCcpO1xuICAgICAgICBjb25zdCBwa2cgPSBKU09OLnBhcnNlKHBrZ1JhdykgYXMgeyB2ZXJzaW9uPzogc3RyaW5nIH07XG4gICAgICAgIGlmIChwa2c/LnZlcnNpb24gJiYgdHlwZW9mIHBrZy52ZXJzaW9uID09PSAnc3RyaW5nJykgcmV0dXJuIHBrZy52ZXJzaW9uO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIGlnbm9yZSBhbmQgZmFsbGJhY2tcbiAgICAgIH1cbiAgICAgIHJldHVybiBwcm9jZXNzLmVudi5YSFNfVkVSU0lPTiA/PyAnMC4xLjAnO1xuICAgIH1cblxuICAgIGNvbnN0IGhlYWRsZXNzRW52ID0gcHJvY2Vzcy5lbnYuWEhTX0hFQURMRVNTO1xuICAgIGNvbnN0IGJyb3dzZXJDb25maWc6IEJyb3dzZXJDb25maWcgPSB7XG4gICAgICBkZWZhdWx0VGltZW91dDogcGFyc2VJbnQocHJvY2Vzcy5lbnYuWEhTX0JST1dTRVJfVElNRU9VVCA/PyAnMzAwMDAnKSxcbiAgICAgIGxvZ2luVGltZW91dDogcGFyc2VJbnQocHJvY2Vzcy5lbnYuWEhTX0xPR0lOX1RJTUVPVVQgPz8gJzMwMCcpLFxuICAgICAgcGFnZUxvYWRUaW1lb3V0OiAzMDAwMCxcbiAgICAgIG5hdmlnYXRpb25UaW1lb3V0OiAzMDAwMCxcbiAgICAgIHNsb3dtbzogMCxcbiAgICAgIGhlYWRsZXNzRGVmYXVsdDogaGVhZGxlc3NFbnYgPT0gbnVsbCA/IHRydWUgOiBoZWFkbGVzc0Vudi50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZScsXG4gICAgfTtcblxuICAgIGNvbnN0IHNlcnZlckNvbmZpZzogU2VydmVyQ29uZmlnID0ge1xuICAgICAgbmFtZTogcHJvY2Vzcy5lbnYuWEhTX1NFUlZFUl9OQU1FID8/ICd4aHMtbWNwJyxcbiAgICAgIHZlcnNpb246IHJlc29sdmVQYWNrYWdlVmVyc2lvbigpLFxuICAgICAgZGVzY3JpcHRpb246ICdYaWFvSG9uZ1NodSBNQ1AgU2VydmVyIC0gVHlwZVNjcmlwdCBWZXJzaW9uJyxcbiAgICAgIGRlZmF1bHRIb3N0OiBwcm9jZXNzLmVudi5YSFNfSE9TVCA/PyAnMTI3LjAuMC4xJyxcbiAgICAgIGRlZmF1bHRQb3J0OiBwYXJzZUludChwcm9jZXNzLmVudi5YSFNfUE9SVCA/PyAnODAwMCcpLFxuICAgICAgZGVmYXVsdFRyYW5zcG9ydDogJ3N0ZGlvJyxcbiAgICB9O1xuXG4gICAgY29uc3QgbG9nRmlsZUVudiA9IHByb2Nlc3MuZW52LlhIU19MT0dfRklMRTtcbiAgICBjb25zdCBsb2dGaWxlRW5hYmxlZCA9IGxvZ0ZpbGVFbnYgPT0gbnVsbCA/IGZhbHNlIDogbG9nRmlsZUVudi50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZSc7XG4gICAgY29uc3QgbG9nZ2luZ0NvbmZpZzogTG9nZ2luZ0NvbmZpZyA9IHtcbiAgICAgIGxldmVsOiBwcm9jZXNzLmVudi5YSFNfTE9HX0xFVkVMID8/ICdJTkZPJyxcbiAgICAgIGZvcm1hdDogJyUoYXNjdGltZSlzIC0gJShuYW1lKXMgLSAlKGxldmVsbmFtZSlzIC0gJShtZXNzYWdlKXMnLFxuICAgICAgZmlsZUVuYWJsZWQ6IGxvZ0ZpbGVFbmFibGVkLFxuICAgICAgZmlsZVBhdGg6IGxvZ0ZpbGVFbmFibGVkID8gam9pbihhcHBEYXRhRGlyLCAneGhzLW1jcC5sb2cnKSA6IHVuZGVmaW5lZCxcbiAgICB9O1xuXG4gICAgY29uc3QgcGF0aHNDb25maWc6IFBhdGhzQ29uZmlnID0ge1xuICAgICAgYXBwRGF0YURpcixcbiAgICAgIGNvb2tpZXNGaWxlLFxuICAgIH07XG5cbiAgICBjb25zdCB4aHNDb25maWc6IFhIU0NvbmZpZyA9IHtcbiAgICAgIGhvbWVVcmw6ICdodHRwczovL3d3dy54aWFvaG9uZ3NodS5jb20nLFxuICAgICAgZXhwbG9yZVVybDogJ2h0dHBzOi8vd3d3LnhpYW9ob25nc2h1LmNvbS9leHBsb3JlJyxcbiAgICAgIHNlYXJjaFVybDogJ2h0dHBzOi8vd3d3LnhpYW9ob25nc2h1LmNvbS9zZWFyY2hfcmVzdWx0JyxcbiAgICAgIGNyZWF0b3JQdWJsaXNoVXJsOiAnaHR0cHM6Ly9jcmVhdG9yLnhpYW9ob25nc2h1LmNvbS9wdWJsaXNoL3B1Ymxpc2g/c291cmNlPW9mZmljaWFsJyxcbiAgICAgIGNyZWF0b3JWaWRlb1B1Ymxpc2hVcmw6XG4gICAgICAgICdodHRwczovL2NyZWF0b3IueGlhb2hvbmdzaHUuY29tL3B1Ymxpc2gvcHVibGlzaD9zb3VyY2U9b2ZmaWNpYWwmZnJvbT10YWJfc3dpdGNoJnRhcmdldD12aWRlbycsXG4gICAgICBsb2dpbk9rU2VsZWN0b3I6ICcubWFpbi1jb250YWluZXIgLnVzZXIgLmxpbmstd3JhcHBlciAuY2hhbm5lbCcsXG4gICAgICByZXF1ZXN0RGVsYXk6IDEuMCxcbiAgICAgIG1heFJldHJpZXM6IDMsXG4gICAgICByZXRyeURlbGF5OiAyLjAsXG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBicm93c2VyOiBicm93c2VyQ29uZmlnLFxuICAgICAgc2VydmVyOiBzZXJ2ZXJDb25maWcsXG4gICAgICBsb2dnaW5nOiBsb2dnaW5nQ29uZmlnLFxuICAgICAgcGF0aHM6IHBhdGhzQ29uZmlnLFxuICAgICAgeGhzOiB4aHNDb25maWcsXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyB0b0RpY3QoKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIHJldHVybiB7XG4gICAgICBicm93c2VyOiB7XG4gICAgICAgIGRlZmF1bHRUaW1lb3V0OiB0aGlzLmNvbmZpZy5icm93c2VyLmRlZmF1bHRUaW1lb3V0LFxuICAgICAgICBsb2dpblRpbWVvdXQ6IHRoaXMuY29uZmlnLmJyb3dzZXIubG9naW5UaW1lb3V0LFxuICAgICAgICBoZWFkbGVzc0RlZmF1bHQ6IHRoaXMuY29uZmlnLmJyb3dzZXIuaGVhZGxlc3NEZWZhdWx0LFxuICAgICAgfSxcbiAgICAgIHNlcnZlcjoge1xuICAgICAgICBuYW1lOiB0aGlzLmNvbmZpZy5zZXJ2ZXIubmFtZSxcbiAgICAgICAgdmVyc2lvbjogdGhpcy5jb25maWcuc2VydmVyLnZlcnNpb24sXG4gICAgICAgIGRlZmF1bHRIb3N0OiB0aGlzLmNvbmZpZy5zZXJ2ZXIuZGVmYXVsdEhvc3QsXG4gICAgICAgIGRlZmF1bHRQb3J0OiB0aGlzLmNvbmZpZy5zZXJ2ZXIuZGVmYXVsdFBvcnQsXG4gICAgICB9LFxuICAgICAgbG9nZ2luZzoge1xuICAgICAgICBsZXZlbDogdGhpcy5jb25maWcubG9nZ2luZy5sZXZlbCxcbiAgICAgICAgZmlsZUVuYWJsZWQ6IHRoaXMuY29uZmlnLmxvZ2dpbmcuZmlsZUVuYWJsZWQsXG4gICAgICB9LFxuICAgICAgcGF0aHM6IHtcbiAgICAgICAgYXBwRGF0YURpcjogdGhpcy5jb25maWcucGF0aHMuYXBwRGF0YURpcixcbiAgICAgICAgY29va2llc0ZpbGU6IHRoaXMuY29uZmlnLnBhdGhzLmNvb2tpZXNGaWxlLFxuICAgICAgfSxcbiAgICAgIHhoczoge1xuICAgICAgICBob21lVXJsOiB0aGlzLmNvbmZpZy54aHMuaG9tZVVybCxcbiAgICAgICAgZXhwbG9yZVVybDogdGhpcy5jb25maWcueGhzLmV4cGxvcmVVcmwsXG4gICAgICAgIG1heFJldHJpZXM6IHRoaXMuY29uZmlnLnhocy5tYXhSZXRyaWVzLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG5cbi8vIEdsb2JhbCBjb25maWd1cmF0aW9uIGluc3RhbmNlXG5sZXQgZ2xvYmFsQ29uZmlnOiBDb25maWcgfCBudWxsID0gbnVsbDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbmZpZygpOiBDb25maWcge1xuICBnbG9iYWxDb25maWcgPz89IENvbmZpZ01hbmFnZXIuZ2V0SW5zdGFuY2UoKS5nZXRDb25maWcoKTtcbiAgcmV0dXJuIGdsb2JhbENvbmZpZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldENvbmZpZyhjb25maWc6IENvbmZpZyk6IHZvaWQge1xuICBnbG9iYWxDb25maWcgPSBjb25maWc7XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2207\n\n}");
67
+
68
+ /***/ }),
69
+
70
+ /***/ 3193:
71
+ /***/ ((module) => {
72
+
73
+ module.exports = require("string_decoder");
74
+
75
+ /***/ }),
76
+
77
+ /***/ 3977:
78
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
79
+
80
+ eval("{\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n Gd: () => (/* binding */ BrowserManager)\n});\n\n// UNUSED EXPORTS: cleanupGlobalBrowserManager, getBrowserManager, getPooledBrowserManager\n\n// EXTERNAL MODULE: external \"puppeteer\"\nvar external_puppeteer_ = __webpack_require__(9916);\nvar external_puppeteer_default = /*#__PURE__*/__webpack_require__.n(external_puppeteer_);\n// EXTERNAL MODULE: ./src/shared/errors.ts\nvar errors = __webpack_require__(7636);\n// EXTERNAL MODULE: ./src/shared/config.ts + 1 modules\nvar shared_config = __webpack_require__(2207);\n// EXTERNAL MODULE: ./src/shared/cookies.ts\nvar shared_cookies = __webpack_require__(4760);\n// EXTERNAL MODULE: ./src/shared/logger.ts\nvar logger = __webpack_require__(9135);\n// EXTERNAL MODULE: ./src/shared/utils.ts\nvar utils = __webpack_require__(2094);\n;// ./src/core/browser/browser-pool.service.ts\n/**\n * Browser Pool Service for XHS Operations\n * Manages browser instance lifecycle with pooling, health monitoring, and automatic cleanup\n */\n\n\n\n\n\nclass BrowserPoolService {\n config;\n pool = new Map();\n options;\n healthCheckTimer = null;\n cleanupTimer = null;\n isShuttingDown = false;\n constructor(config, options) {\n this.config = config || (0,shared_config/* getConfig */.zj)();\n // Set default options with configuration from environment or defaults\n const idleTimeout = options?.idleTimeout ?? 300000;\n this.options = {\n minInstances: options?.minInstances ?? 2,\n maxInstances: options?.maxInstances ?? 5,\n idleTimeout,\n maxAge: options?.maxAge ?? 1800000, // 30 minutes\n healthCheckInterval: options?.healthCheckInterval ?? 60000, // 1 minute\n maxUsageCount: options?.maxUsageCount ?? 100,\n stuckTimeout: options?.stuckTimeout ?? 600000, // 10 minutes\n };\n this.startHealthMonitoring();\n this.startCleanupMonitoring();\n }\n /**\n * Acquire a browser instance from the pool\n */\n async acquireBrowser(options) {\n if (this.isShuttingDown) {\n throw new errors/* XHSError */.a_('Browser pool is shutting down', 'BrowserPoolError');\n }\n const timeout = options?.timeout ?? 30000;\n const startTime = Date.now();\n while (Date.now() - startTime < timeout) {\n // Try to find an available healthy browser\n const availableBrowser = this.findAvailableBrowser();\n if (availableBrowser) {\n availableBrowser.isAvailable = false;\n availableBrowser.lastUsed = new Date();\n availableBrowser.usageCount++;\n logger/* logger */.v.debug(`Acquired browser ${availableBrowser.id} from pool`);\n return availableBrowser;\n }\n // If no available browser and we can create more, create one\n if (this.pool.size < this.options.maxInstances) {\n try {\n const newBrowser = await this.createBrowserInstance();\n newBrowser.isAvailable = false;\n newBrowser.lastUsed = new Date();\n newBrowser.usageCount++;\n logger/* logger */.v.info(`Created new browser ${newBrowser.id} for pool`);\n return newBrowser;\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to create new browser instance: ${error}`);\n }\n }\n // Wait a bit before retrying\n await (0,utils/* sleep */.yy)(100);\n }\n throw new errors/* XHSError */.a_(`Failed to acquire browser within ${timeout}ms timeout`, 'BrowserPoolTimeout', { timeout, poolSize: this.pool.size, availableCount: this.getAvailableCount() });\n }\n /**\n * Release a browser instance back to the pool\n */\n async releaseBrowser(browser) {\n const managedBrowser = this.pool.get(browser.id);\n if (!managedBrowser) {\n logger/* logger */.v.warn(`Attempted to release unknown browser ${browser.id}`);\n return;\n }\n // If idleTimeout <= 0, close browser immediately instead of returning to pool\n if (this.options.idleTimeout <= 0) {\n logger/* logger */.v.debug(`Browser ${browser.id} released with idleTimeout=0, closing immediately`);\n await this.removeBrowserFromPool(browser.id);\n await this.ensureMinimumInstances();\n return;\n }\n // Check if browser should be retired due to age or usage\n const shouldRetire = this.shouldRetireBrowser(managedBrowser);\n if (shouldRetire) {\n logger/* logger */.v.info(`Retiring browser ${browser.id} due to ${shouldRetire}`);\n await this.removeBrowserFromPool(browser.id);\n // Ensure we maintain minimum instances\n await this.ensureMinimumInstances();\n return;\n }\n // Perform health check before returning to pool\n const isHealthy = await this.checkBrowserHealth(managedBrowser);\n if (!isHealthy) {\n logger/* logger */.v.warn(`Browser ${browser.id} failed health check, removing from pool`);\n await this.removeBrowserFromPool(browser.id);\n await this.ensureMinimumInstances();\n return;\n }\n // Return to pool\n managedBrowser.isAvailable = true;\n managedBrowser.isHealthy = true;\n logger/* logger */.v.debug(`Released browser ${browser.id} back to pool`);\n }\n /**\n * Get current pool statistics\n */\n getPoolStats() {\n const instances = Array.from(this.pool.values());\n const availableInstances = instances.filter((b) => b.isAvailable && b.isHealthy).length;\n const busyInstances = instances.filter((b) => !b.isAvailable).length;\n const unhealthyInstances = instances.filter((b) => !b.isHealthy).length;\n const totalUsage = instances.reduce((sum, b) => sum + b.usageCount, 0);\n const ages = instances.map((b) => Date.now() - b.createdAt.getTime());\n const averageAge = ages.length > 0 ? ages.reduce((sum, age) => sum + age, 0) / ages.length : 0;\n const oldestInstance = instances.length > 0\n ? instances.reduce((oldest, current) => current.createdAt < oldest.createdAt ? current : oldest).createdAt\n : null;\n const newestInstance = instances.length > 0\n ? instances.reduce((newest, current) => current.createdAt > newest.createdAt ? current : newest).createdAt\n : null;\n return {\n totalInstances: instances.length,\n availableInstances,\n busyInstances,\n unhealthyInstances,\n totalUsage,\n averageAge,\n oldestInstance,\n newestInstance,\n };\n }\n /**\n * Cleanup and shutdown the browser pool\n */\n async cleanup() {\n this.isShuttingDown = true;\n // Stop monitoring timers\n if (this.healthCheckTimer) {\n clearInterval(this.healthCheckTimer);\n this.healthCheckTimer = null;\n }\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = null;\n }\n // Close all browsers\n const closePromises = Array.from(this.pool.values()).map(async (managedBrowser) => {\n try {\n await managedBrowser.browser.close();\n logger/* logger */.v.debug(`Closed browser ${managedBrowser.id}`);\n }\n catch (error) {\n logger/* logger */.v.warn(`Error closing browser ${managedBrowser.id}: ${error}`);\n }\n });\n await Promise.allSettled(closePromises);\n this.pool.clear();\n logger/* logger */.v.info('Browser pool cleanup completed');\n }\n /**\n * Create a new browser instance\n */\n async createBrowserInstance() {\n try {\n const launchOptions = {\n headless: this.config.browser.headlessDefault,\n slowMo: this.config.browser.slowmo,\n args: [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-dev-shm-usage',\n '--disable-accelerated-2d-canvas',\n '--no-first-run',\n '--no-zygote',\n '--disable-gpu',\n '--disable-background-timer-throttling',\n '--disable-backgrounding-occluded-windows',\n '--disable-renderer-backgrounding',\n ],\n };\n const browser = await external_puppeteer_default().launch(launchOptions);\n const context = await browser.createBrowserContext();\n const id = this.generateBrowserId();\n const managedBrowser = {\n browser,\n context,\n id,\n createdAt: new Date(),\n lastUsed: new Date(),\n isAvailable: true,\n isHealthy: true,\n usageCount: 0,\n };\n this.pool.set(id, managedBrowser);\n // Set up browser event handlers\n browser.on('disconnected', () => {\n logger/* logger */.v.warn(`Browser ${id} disconnected unexpectedly`);\n this.handleBrowserDisconnection(id);\n });\n return managedBrowser;\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to create browser instance: ${error}`);\n throw new errors/* BrowserLaunchError */.EE(`Failed to create browser instance: ${error}`, { poolSize: this.pool.size }, error);\n }\n }\n /**\n * Find an available healthy browser in the pool\n */\n findAvailableBrowser() {\n for (const browser of this.pool.values()) {\n if (browser.isAvailable && browser.isHealthy) {\n return browser;\n }\n }\n return null;\n }\n /**\n * Check if a browser should be retired\n */\n shouldRetireBrowser(browser) {\n const age = Date.now() - browser.createdAt.getTime();\n if (age > this.options.maxAge) {\n return 'max age exceeded';\n }\n if (browser.usageCount >= this.options.maxUsageCount) {\n return 'max usage count exceeded';\n }\n return null;\n }\n /**\n * Perform health check on a browser instance\n */\n async checkBrowserHealth(browser) {\n try {\n // Check if browser is connected\n if (!browser.browser.isConnected()) {\n return false;\n }\n // Try to create and close a test page\n const page = await browser.context.newPage();\n await page.close();\n return true;\n }\n catch (error) {\n logger/* logger */.v.debug(`Browser ${browser.id} health check failed: ${error}`);\n return false;\n }\n }\n /**\n * Remove a browser from the pool\n */\n async removeBrowserFromPool(browserId) {\n const browser = this.pool.get(browserId);\n if (!browser) {\n return;\n }\n try {\n await browser.browser.close();\n }\n catch (error) {\n logger/* logger */.v.warn(`Error closing browser ${browserId}: ${error}`);\n }\n this.pool.delete(browserId);\n logger/* logger */.v.debug(`Removed browser ${browserId} from pool`);\n }\n /**\n * Handle browser disconnection\n */\n async handleBrowserDisconnection(browserId) {\n const browser = this.pool.get(browserId);\n if (browser) {\n browser.isHealthy = false;\n browser.isAvailable = false;\n }\n // Remove the disconnected browser and ensure minimum instances\n await this.removeBrowserFromPool(browserId);\n await this.ensureMinimumInstances();\n }\n /**\n * Ensure minimum number of instances are available\n */\n async ensureMinimumInstances() {\n if (this.isShuttingDown) {\n return;\n }\n const healthyCount = Array.from(this.pool.values()).filter((b) => b.isHealthy).length;\n const needed = this.options.minInstances - healthyCount;\n if (needed > 0) {\n logger/* logger */.v.info(`Creating ${needed} browser instances to maintain minimum pool size`);\n const createPromises = Array.from({ length: needed }, () => this.createBrowserInstance().catch((error) => {\n logger/* logger */.v.error(`Failed to create browser for minimum instances: ${error}`);\n return null;\n }));\n await Promise.allSettled(createPromises);\n }\n }\n /**\n * Get count of available browsers\n */\n getAvailableCount() {\n return Array.from(this.pool.values()).filter((b) => b.isAvailable && b.isHealthy).length;\n }\n /**\n * Start health monitoring\n */\n startHealthMonitoring() {\n this.healthCheckTimer = setInterval(async () => {\n if (this.isShuttingDown) {\n return;\n }\n const unhealthyBrowsers = [];\n for (const [id, browser] of this.pool.entries()) {\n if (!browser.isAvailable) {\n continue; // Skip browsers currently in use\n }\n const isHealthy = await this.checkBrowserHealth(browser);\n if (!isHealthy) {\n unhealthyBrowsers.push(id);\n browser.isHealthy = false;\n }\n }\n // Remove unhealthy browsers\n for (const id of unhealthyBrowsers) {\n logger/* logger */.v.warn(`Removing unhealthy browser ${id} during health check`);\n await this.removeBrowserFromPool(id);\n }\n // Ensure minimum instances after cleanup\n if (unhealthyBrowsers.length > 0) {\n await this.ensureMinimumInstances();\n }\n }, this.options.healthCheckInterval);\n }\n /**\n * Start cleanup monitoring for idle and stuck browsers\n */\n startCleanupMonitoring() {\n this.cleanupTimer = setInterval(async () => {\n if (this.isShuttingDown) {\n return;\n }\n const now = Date.now();\n const browsersToRemove = [];\n for (const [id, browser] of this.pool.entries()) {\n const idleTime = now - browser.lastUsed.getTime();\n const shouldRetire = this.shouldRetireBrowser(browser);\n // Also check stuck browsers (busy but stuck timeout exceeded)\n // These are usually caused by unhandled exceptions preventing releaseBrowser from being called\n const isStuck = !browser.isAvailable && idleTime > this.options.stuckTimeout;\n if (idleTime > this.options.idleTimeout || shouldRetire || isStuck) {\n const healthyCount = Array.from(this.pool.values()).filter((b) => b.isHealthy).length;\n // Force removal for stuck browsers (don't check minimum instance count)\n // Otherwise only remove if above minimum instances\n if (isStuck || healthyCount > this.options.minInstances) {\n browsersToRemove.push(id);\n }\n }\n }\n // Remove idle/old/stuck browsers\n for (const id of browsersToRemove) {\n const browser = this.pool.get(id);\n const isStuck = browser && !browser.isAvailable;\n const reason = this.shouldRetireBrowser(browser) || (isStuck ? 'stuck browser timeout' : 'idle timeout');\n logger/* logger */.v.info(`Removing browser ${id} due to ${reason}`);\n // For stuck browsers, try to close any open pages first\n if (isStuck && browser) {\n try {\n const pages = await browser.context.pages();\n for (const p of pages) {\n try {\n if (!p.isClosed()) {\n await p.close();\n }\n }\n catch (e) {\n // ignore\n }\n }\n }\n catch (e) {\n // ignore\n }\n }\n await this.removeBrowserFromPool(id);\n }\n // Ensure minimum instances after cleanup only if browsers were removed\n if (browsersToRemove.length > 0) {\n await this.ensureMinimumInstances();\n }\n }, this.options.healthCheckInterval);\n }\n /**\n * Generate unique browser ID\n */\n generateBrowserId() {\n return `browser_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n }\n}\n// Global browser pool instance\nlet globalBrowserPool = null;\nfunction getBrowserPool() {\n if (!globalBrowserPool) {\n globalBrowserPool = new BrowserPoolService();\n }\n return globalBrowserPool;\n}\nasync function cleanupBrowserPool() {\n if (globalBrowserPool) {\n await globalBrowserPool.cleanup();\n globalBrowserPool = null;\n }\n}\n\n;// ./src/core/browser/browser.manager.ts\n/**\n * Browser Manager for XHS Operations\n */\n\n\n\n\n\n\n\nclass BrowserManager {\n config;\n browser = null;\n browserPool = null;\n usePool = false;\n poolOptions;\n trackedPages = new Set();\n maxTrackedPages = 10;\n constructor(config, usePool = false, poolOptions) {\n this.config = config || (0,shared_config/* getConfig */.zj)();\n this.usePool = usePool;\n this.poolOptions = poolOptions;\n if (this.usePool) {\n this.browserPool = new BrowserPoolService(this.config, poolOptions);\n }\n }\n async createPage(headless, executablePath, shouldLoadCookies = true) {\n try {\n // Use browser pool if enabled\n if (this.usePool && this.browserPool) {\n return await this.createPageFromPool(shouldLoadCookies);\n }\n // Fallback to traditional browser management\n // Launch browser if not already launched\n if (!this.browser) {\n this.browser = await this.launchBrowser(headless, executablePath);\n }\n // Create new page\n const page = await this.browser.newPage();\n // Track page for cleanup\n this.trackedPages.add(page);\n page.once('close', () => {\n this.trackedPages.delete(page);\n });\n // Auto-cleanup if too many pages are open (leak detection)\n if (this.trackedPages.size > this.maxTrackedPages) {\n logger/* logger */.v.warn(`Tracked pages (${this.trackedPages.size}) exceeds threshold (${this.maxTrackedPages}), forcing cleanup`);\n await this.closeAllPages();\n }\n // Configure page timeouts\n page.setDefaultTimeout(this.config.browser.defaultTimeout);\n page.setDefaultNavigationTimeout(this.config.browser.navigationTimeout);\n // Load cookies if requested\n if (shouldLoadCookies) {\n await this.loadCookiesIntoPage(page);\n }\n return page;\n }\n catch (error) {\n logger/* logger */.v.error(`Browser page creation error: ${error}`);\n throw this.handlePuppeteerError(error, 'create_page');\n }\n }\n /**\n * Create a page using the browser pool\n */\n async createPageFromPool(shouldLoadCookies = true) {\n if (!this.browserPool) {\n throw new errors/* XHSError */.a_('Browser pool not initialized', 'BrowserPoolError');\n }\n const managedBrowser = await this.browserPool.acquireBrowser();\n try {\n // Create new page from the managed browser context\n const page = await managedBrowser.context.newPage();\n // Configure page timeouts\n page.setDefaultTimeout(this.config.browser.defaultTimeout);\n page.setDefaultNavigationTimeout(this.config.browser.navigationTimeout);\n // Load cookies if requested\n if (shouldLoadCookies) {\n await this.loadCookiesIntoPage(page);\n }\n // Store reference to managed browser for cleanup\n page._managedBrowser = managedBrowser;\n // Set up page close handler to release browser back to pool\n let released = false;\n const releaseBrowser = async () => {\n if (released)\n return;\n released = true;\n try {\n await this.browserPool.releaseBrowser(managedBrowser);\n }\n catch (error) {\n logger/* logger */.v.warn(`Error releasing browser back to pool: ${error}`);\n }\n };\n page.once('close', releaseBrowser);\n return page;\n }\n catch (error) {\n // Release browser back to pool on error\n try {\n await this.browserPool.releaseBrowser(managedBrowser);\n }\n catch (releaseError) {\n logger/* logger */.v.warn(`Error releasing browser after page creation failure: ${releaseError}`);\n }\n throw error;\n }\n }\n async launchBrowser(headless, executablePath) {\n const isHeadless = headless ?? this.config.browser.headlessDefault;\n try {\n const launchOptions = {\n headless: isHeadless,\n slowMo: this.config.browser.slowmo,\n args: [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-dev-shm-usage',\n '--disable-accelerated-2d-canvas',\n '--no-first-run',\n '--no-zygote',\n '--disable-gpu',\n ],\n };\n if (executablePath) {\n launchOptions.executablePath = executablePath;\n }\n const browser = await external_puppeteer_default().launch(launchOptions);\n return browser;\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to launch browser: ${error}`);\n throw new errors/* BrowserLaunchError */.EE(`Failed to launch browser: ${error}`, { headless: isHeadless, executablePath }, error);\n }\n }\n async loadCookiesIntoPage(page) {\n try {\n const cookies = (0,shared_cookies/* loadCookies */.O4)();\n if (!cookies) {\n return false;\n }\n // Convert our cookie format to Puppeteer format\n const puppeteerCookies = cookies.map((cookie) => ({\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain,\n path: cookie.path,\n expires: cookie.expires,\n httpOnly: cookie.httpOnly,\n secure: cookie.secure,\n sameSite: cookie.sameSite,\n }));\n await page.setCookie(...puppeteerCookies);\n return true;\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to load cookies: ${error}`);\n return false;\n }\n }\n async saveCookiesFromPage(page) {\n try {\n const cookies = await page.cookies();\n // Convert Puppeteer cookie format to app format\n const appCookies = cookies.map((cookie) => ({\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain,\n path: cookie.path,\n expires: cookie.expires,\n httpOnly: cookie.httpOnly,\n secure: cookie.secure,\n sameSite: cookie.sameSite,\n }));\n (0,shared_cookies/* saveCookies */.XM)(appCookies);\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to save cookies: ${error}`);\n throw this.handlePuppeteerError(error, 'save_cookies');\n }\n }\n async navigateWithRetry(page, url, waitUntil = 'load', maxRetries) {\n const retries = maxRetries || this.config.xhs.maxRetries;\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n await page.goto(url, {\n waitUntil,\n timeout: this.config.browser.navigationTimeout,\n });\n return;\n }\n catch (error) {\n if (error instanceof Error && error.name === 'TimeoutError') {\n if (attempt === retries) {\n throw new errors/* BrowserNavigationError */.Jk(`Failed to navigate to ${url} after ${retries + 1} attempts`, { url, attempts: attempt + 1 }, error);\n }\n await (0,utils/* sleep */.yy)(this.config.xhs.retryDelay * 1000);\n }\n else {\n throw error;\n }\n }\n }\n }\n async tryWaitForSelector(page, selector, timeout, visible = true) {\n try {\n await page.waitForSelector(selector, {\n timeout: timeout || this.config.browser.defaultTimeout,\n visible,\n });\n return true;\n }\n catch (error) {\n if (error instanceof Error && error.name === 'TimeoutError') {\n return false;\n }\n throw error;\n }\n }\n async waitForSelectorVisible(page, selector, timeout) {\n return this.tryWaitForSelector(page, selector, timeout, true);\n }\n async waitForSelectorHidden(page, selector, timeout) {\n return this.tryWaitForSelector(page, selector, timeout, false);\n }\n async cleanup() {\n // Cleanup browser pool if using it\n if (this.usePool && this.browserPool) {\n try {\n await this.browserPool.cleanup();\n }\n catch (error) {\n logger/* logger */.v.warn(`Error cleaning up browser pool: ${error}`);\n }\n finally {\n this.browserPool = null;\n }\n }\n // Close all tracked pages before closing browser\n await this.closeAllPages();\n // Cleanup traditional browser instance\n if (this.browser) {\n try {\n await this.browser.close();\n }\n catch (error) {\n logger/* logger */.v.warn(`Error closing browser: ${error}`);\n }\n finally {\n this.browser = null;\n }\n }\n }\n /**\n * Close all tracked pages that are still open\n */\n async closeAllPages() {\n const closePromises = [];\n for (const page of this.trackedPages) {\n if (!page.isClosed()) {\n closePromises.push(page.close().catch((error) => {\n logger/* logger */.v.warn(`Error closing tracked page: ${error}`);\n }));\n }\n }\n await Promise.allSettled(closePromises);\n this.trackedPages.clear();\n }\n /**\n * Get browser pool statistics (if using pool)\n */\n getBrowserPoolStats() {\n if (this.usePool && this.browserPool) {\n return this.browserPool.getPoolStats();\n }\n return null;\n }\n /**\n * Get the number of tracked pages (for monitoring leaks)\n */\n getTrackedPageCount() {\n return this.trackedPages.size;\n }\n /**\n * Enable browser pooling\n */\n enableBrowserPool() {\n if (!this.usePool) {\n this.usePool = true;\n this.browserPool = new BrowserPoolService(this.config, this.poolOptions);\n }\n }\n /**\n * Disable browser pooling\n */\n async disableBrowserPool() {\n if (this.usePool && this.browserPool) {\n await this.browserPool.cleanup();\n this.browserPool = null;\n this.usePool = false;\n }\n }\n handlePuppeteerError(error, operationName) {\n const context = { operationName };\n if (error.name === 'TimeoutError') {\n if (operationName.toLowerCase().includes('login')) {\n return new errors/* XHSError */.a_(`Login operation timed out during ${operationName}`, 'LoginTimeoutError', context, error);\n }\n else {\n return new errors/* XHSError */.a_(`Browser operation timed out: ${operationName}`, 'BrowserError', context, error);\n }\n }\n else {\n if (error.message.toLowerCase().includes('navigation')) {\n return new errors/* BrowserNavigationError */.Jk(`Navigation failed during ${operationName}: ${error.message}`, context, error);\n }\n else {\n return new errors/* XHSError */.a_(`Browser error during ${operationName}: ${error.message}`, 'BrowserError', context, error);\n }\n }\n }\n}\n// Global browser manager instance\nlet globalBrowserManager = null;\nfunction getBrowserManager(usePool = false) {\n if (!globalBrowserManager) {\n globalBrowserManager = new BrowserManager(undefined, usePool);\n }\n return globalBrowserManager;\n}\nfunction getPooledBrowserManager() {\n return getBrowserManager(true);\n}\nasync function cleanupGlobalBrowserManager() {\n if (globalBrowserManager) {\n await globalBrowserManager.cleanup();\n globalBrowserManager = null;\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LElBQUksQ0FBQztJQUM5QixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9icm93c2VyL2Jyb3dzZXItcG9vbC5zZXJ2aWNlLnRzPzRjNTQiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL2Jyb3dzZXIvYnJvd3Nlci5tYW5hZ2VyLnRzPzRjMGYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCcm93c2VyIFBvb2wgU2VydmljZSBmb3IgWEhTIE9wZXJhdGlvbnNcbiAqIE1hbmFnZXMgYnJvd3NlciBpbnN0YW5jZSBsaWZlY3ljbGUgd2l0aCBwb29saW5nLCBoZWFsdGggbW9uaXRvcmluZywgYW5kIGF1dG9tYXRpYyBjbGVhbnVwXG4gKi9cblxuaW1wb3J0IHB1cHBldGVlciwgeyBCcm93c2VyLCBCcm93c2VyQ29udGV4dCwgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgQnJvd3NlckxhdW5jaEVycm9yLCBYSFNFcnJvciB9IGZyb20gJy4uLy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IHsgZ2V0Q29uZmlnIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2NvbmZpZyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvbG9nZ2VyJztcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBNYW5hZ2VkQnJvd3NlciB7XG4gIGJyb3dzZXI6IEJyb3dzZXI7XG4gIGNvbnRleHQ6IEJyb3dzZXJDb250ZXh0O1xuICBpZDogc3RyaW5nO1xuICBjcmVhdGVkQXQ6IERhdGU7XG4gIGxhc3RVc2VkOiBEYXRlO1xuICBpc0F2YWlsYWJsZTogYm9vbGVhbjtcbiAgaXNIZWFsdGh5OiBib29sZWFuO1xuICB1c2FnZUNvdW50OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnJvd3NlclBvb2xTdGF0cyB7XG4gIHRvdGFsSW5zdGFuY2VzOiBudW1iZXI7XG4gIGF2YWlsYWJsZUluc3RhbmNlczogbnVtYmVyO1xuICBidXN5SW5zdGFuY2VzOiBudW1iZXI7XG4gIHVuaGVhbHRoeUluc3RhbmNlczogbnVtYmVyO1xuICB0b3RhbFVzYWdlOiBudW1iZXI7XG4gIGF2ZXJhZ2VBZ2U6IG51bWJlcjtcbiAgb2xkZXN0SW5zdGFuY2U6IERhdGUgfCBudWxsO1xuICBuZXdlc3RJbnN0YW5jZTogRGF0ZSB8IG51bGw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnJvd3NlclBvb2xPcHRpb25zIHtcbiAgbWluSW5zdGFuY2VzPzogbnVtYmVyO1xuICBtYXhJbnN0YW5jZXM/OiBudW1iZXI7XG4gIGlkbGVUaW1lb3V0PzogbnVtYmVyO1xuICBtYXhBZ2U/OiBudW1iZXI7XG4gIGhlYWx0aENoZWNrSW50ZXJ2YWw/OiBudW1iZXI7XG4gIG1heFVzYWdlQ291bnQ/OiBudW1iZXI7XG4gIHN0dWNrVGltZW91dD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGNsYXNzIEJyb3dzZXJQb29sU2VydmljZSB7XG4gIHByaXZhdGUgY29uZmlnOiBDb25maWc7XG4gIHByaXZhdGUgcG9vbDogTWFwPHN0cmluZywgTWFuYWdlZEJyb3dzZXI+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIG9wdGlvbnM6IFJlcXVpcmVkPEJyb3dzZXJQb29sT3B0aW9ucz47XG4gIHByaXZhdGUgaGVhbHRoQ2hlY2tUaW1lcjogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjbGVhbnVwVGltZXI6IE5vZGVKUy5UaW1lb3V0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaXNTaHV0dGluZ0Rvd24gPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc/OiBDb25maWcsIG9wdGlvbnM/OiBCcm93c2VyUG9vbE9wdGlvbnMpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyB8fCBnZXRDb25maWcoKTtcblxuICAgIC8vIFNldCBkZWZhdWx0IG9wdGlvbnMgd2l0aCBjb25maWd1cmF0aW9uIGZyb20gZW52aXJvbm1lbnQgb3IgZGVmYXVsdHNcbiAgICBjb25zdCBpZGxlVGltZW91dCA9IG9wdGlvbnM/LmlkbGVUaW1lb3V0ID8/IDMwMDAwMDtcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBtaW5JbnN0YW5jZXM6IG9wdGlvbnM/Lm1pbkluc3RhbmNlcyA/PyAyLFxuICAgICAgbWF4SW5zdGFuY2VzOiBvcHRpb25zPy5tYXhJbnN0YW5jZXMgPz8gNSxcbiAgICAgIGlkbGVUaW1lb3V0LFxuICAgICAgbWF4QWdlOiBvcHRpb25zPy5tYXhBZ2UgPz8gMTgwMDAwMCwgLy8gMzAgbWludXRlc1xuICAgICAgaGVhbHRoQ2hlY2tJbnRlcnZhbDogb3B0aW9ucz8uaGVhbHRoQ2hlY2tJbnRlcnZhbCA/PyA2MDAwMCwgLy8gMSBtaW51dGVcbiAgICAgIG1heFVzYWdlQ291bnQ6IG9wdGlvbnM/Lm1heFVzYWdlQ291bnQgPz8gMTAwLFxuICAgICAgc3R1Y2tUaW1lb3V0OiBvcHRpb25zPy5zdHVja1RpbWVvdXQgPz8gNjAwMDAwLCAvLyAxMCBtaW51dGVzXG4gICAgfTtcblxuICAgIHRoaXMuc3RhcnRIZWFsdGhNb25pdG9yaW5nKCk7XG4gICAgdGhpcy5zdGFydENsZWFudXBNb25pdG9yaW5nKCk7XG4gIH1cblxuICAvKipcbiAgICogQWNxdWlyZSBhIGJyb3dzZXIgaW5zdGFuY2UgZnJvbSB0aGUgcG9vbFxuICAgKi9cbiAgYXN5bmMgYWNxdWlyZUJyb3dzZXIob3B0aW9ucz86IHsgdGltZW91dD86IG51bWJlciB9KTogUHJvbWlzZTxNYW5hZ2VkQnJvd3Nlcj4ge1xuICAgIGlmICh0aGlzLmlzU2h1dHRpbmdEb3duKSB7XG4gICAgICB0aHJvdyBuZXcgWEhTRXJyb3IoJ0Jyb3dzZXIgcG9vbCBpcyBzaHV0dGluZyBkb3duJywgJ0Jyb3dzZXJQb29sRXJyb3InKTtcbiAgICB9XG5cbiAgICBjb25zdCB0aW1lb3V0ID0gb3B0aW9ucz8udGltZW91dCA/PyAzMDAwMDtcbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPCB0aW1lb3V0KSB7XG4gICAgICAvLyBUcnkgdG8gZmluZCBhbiBhdmFpbGFibGUgaGVhbHRoeSBicm93c2VyXG4gICAgICBjb25zdCBhdmFpbGFibGVCcm93c2VyID0gdGhpcy5maW5kQXZhaWxhYmxlQnJvd3NlcigpO1xuICAgICAgaWYgKGF2YWlsYWJsZUJyb3dzZXIpIHtcbiAgICAgICAgYXZhaWxhYmxlQnJvd3Nlci5pc0F2YWlsYWJsZSA9IGZhbHNlO1xuICAgICAgICBhdmFpbGFibGVCcm93c2VyLmxhc3RVc2VkID0gbmV3IERhdGUoKTtcbiAgICAgICAgYXZhaWxhYmxlQnJvd3Nlci51c2FnZUNvdW50Kys7XG5cbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBBY3F1aXJlZCBicm93c2VyICR7YXZhaWxhYmxlQnJvd3Nlci5pZH0gZnJvbSBwb29sYCk7XG4gICAgICAgIHJldHVybiBhdmFpbGFibGVCcm93c2VyO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiBubyBhdmFpbGFibGUgYnJvd3NlciBhbmQgd2UgY2FuIGNyZWF0ZSBtb3JlLCBjcmVhdGUgb25lXG4gICAgICBpZiAodGhpcy5wb29sLnNpemUgPCB0aGlzLm9wdGlvbnMubWF4SW5zdGFuY2VzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgbmV3QnJvd3NlciA9IGF3YWl0IHRoaXMuY3JlYXRlQnJvd3Nlckluc3RhbmNlKCk7XG4gICAgICAgICAgbmV3QnJvd3Nlci5pc0F2YWlsYWJsZSA9IGZhbHNlO1xuICAgICAgICAgIG5ld0Jyb3dzZXIubGFzdFVzZWQgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgIG5ld0Jyb3dzZXIudXNhZ2VDb3VudCsrO1xuXG4gICAgICAgICAgbG9nZ2VyLmluZm8oYENyZWF0ZWQgbmV3IGJyb3dzZXIgJHtuZXdCcm93c2VyLmlkfSBmb3IgcG9vbGApO1xuICAgICAgICAgIHJldHVybiBuZXdCcm93c2VyO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBuZXcgYnJvd3NlciBpbnN0YW5jZTogJHtlcnJvcn1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBXYWl0IGEgYml0IGJlZm9yZSByZXRyeWluZ1xuICAgICAgYXdhaXQgc2xlZXAoMTAwKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgWEhTRXJyb3IoXG4gICAgICBgRmFpbGVkIHRvIGFjcXVpcmUgYnJvd3NlciB3aXRoaW4gJHt0aW1lb3V0fW1zIHRpbWVvdXRgLFxuICAgICAgJ0Jyb3dzZXJQb29sVGltZW91dCcsXG4gICAgICB7IHRpbWVvdXQsIHBvb2xTaXplOiB0aGlzLnBvb2wuc2l6ZSwgYXZhaWxhYmxlQ291bnQ6IHRoaXMuZ2V0QXZhaWxhYmxlQ291bnQoKSB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxlYXNlIGEgYnJvd3NlciBpbnN0YW5jZSBiYWNrIHRvIHRoZSBwb29sXG4gICAqL1xuICBhc3luYyByZWxlYXNlQnJvd3Nlcihicm93c2VyOiBNYW5hZ2VkQnJvd3Nlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG1hbmFnZWRCcm93c2VyID0gdGhpcy5wb29sLmdldChicm93c2VyLmlkKTtcbiAgICBpZiAoIW1hbmFnZWRCcm93c2VyKSB7XG4gICAgICBsb2dnZXIud2FybihgQXR0ZW1wdGVkIHRvIHJlbGVhc2UgdW5rbm93biBicm93c2VyICR7YnJvd3Nlci5pZH1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJZiBpZGxlVGltZW91dCA8PSAwLCBjbG9zZSBicm93c2VyIGltbWVkaWF0ZWx5IGluc3RlYWQgb2YgcmV0dXJuaW5nIHRvIHBvb2xcbiAgICBpZiAodGhpcy5vcHRpb25zLmlkbGVUaW1lb3V0IDw9IDApIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQnJvd3NlciAke2Jyb3dzZXIuaWR9IHJlbGVhc2VkIHdpdGggaWRsZVRpbWVvdXQ9MCwgY2xvc2luZyBpbW1lZGlhdGVseWApO1xuICAgICAgYXdhaXQgdGhpcy5yZW1vdmVCcm93c2VyRnJvbVBvb2woYnJvd3Nlci5pZCk7XG4gICAgICBhd2FpdCB0aGlzLmVuc3VyZU1pbmltdW1JbnN0YW5jZXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBicm93c2VyIHNob3VsZCBiZSByZXRpcmVkIGR1ZSB0byBhZ2Ugb3IgdXNhZ2VcbiAgICBjb25zdCBzaG91bGRSZXRpcmUgPSB0aGlzLnNob3VsZFJldGlyZUJyb3dzZXIobWFuYWdlZEJyb3dzZXIpO1xuICAgIGlmIChzaG91bGRSZXRpcmUpIHtcbiAgICAgIGxvZ2dlci5pbmZvKGBSZXRpcmluZyBicm93c2VyICR7YnJvd3Nlci5pZH0gZHVlIHRvICR7c2hvdWxkUmV0aXJlfWApO1xuICAgICAgYXdhaXQgdGhpcy5yZW1vdmVCcm93c2VyRnJvbVBvb2woYnJvd3Nlci5pZCk7XG5cbiAgICAgIC8vIEVuc3VyZSB3ZSBtYWludGFpbiBtaW5pbXVtIGluc3RhbmNlc1xuICAgICAgYXdhaXQgdGhpcy5lbnN1cmVNaW5pbXVtSW5zdGFuY2VzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUGVyZm9ybSBoZWFsdGggY2hlY2sgYmVmb3JlIHJldHVybmluZyB0byBwb29sXG4gICAgY29uc3QgaXNIZWFsdGh5ID0gYXdhaXQgdGhpcy5jaGVja0Jyb3dzZXJIZWFsdGgobWFuYWdlZEJyb3dzZXIpO1xuICAgIGlmICghaXNIZWFsdGh5KSB7XG4gICAgICBsb2dnZXIud2FybihgQnJvd3NlciAke2Jyb3dzZXIuaWR9IGZhaWxlZCBoZWFsdGggY2hlY2ssIHJlbW92aW5nIGZyb20gcG9vbGApO1xuICAgICAgYXdhaXQgdGhpcy5yZW1vdmVCcm93c2VyRnJvbVBvb2woYnJvd3Nlci5pZCk7XG4gICAgICBhd2FpdCB0aGlzLmVuc3VyZU1pbmltdW1JbnN0YW5jZXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gdG8gcG9vbFxuICAgIG1hbmFnZWRCcm93c2VyLmlzQXZhaWxhYmxlID0gdHJ1ZTtcbiAgICBtYW5hZ2VkQnJvd3Nlci5pc0hlYWx0aHkgPSB0cnVlO1xuXG4gICAgbG9nZ2VyLmRlYnVnKGBSZWxlYXNlZCBicm93c2VyICR7YnJvd3Nlci5pZH0gYmFjayB0byBwb29sYCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGN1cnJlbnQgcG9vbCBzdGF0aXN0aWNzXG4gICAqL1xuICBnZXRQb29sU3RhdHMoKTogQnJvd3NlclBvb2xTdGF0cyB7XG4gICAgY29uc3QgaW5zdGFuY2VzID0gQXJyYXkuZnJvbSh0aGlzLnBvb2wudmFsdWVzKCkpO1xuICAgIGNvbnN0IGF2YWlsYWJsZUluc3RhbmNlcyA9IGluc3RhbmNlcy5maWx0ZXIoKGIpID0+IGIuaXNBdmFpbGFibGUgJiYgYi5pc0hlYWx0aHkpLmxlbmd0aDtcbiAgICBjb25zdCBidXN5SW5zdGFuY2VzID0gaW5zdGFuY2VzLmZpbHRlcigoYikgPT4gIWIuaXNBdmFpbGFibGUpLmxlbmd0aDtcbiAgICBjb25zdCB1bmhlYWx0aHlJbnN0YW5jZXMgPSBpbnN0YW5jZXMuZmlsdGVyKChiKSA9PiAhYi5pc0hlYWx0aHkpLmxlbmd0aDtcbiAgICBjb25zdCB0b3RhbFVzYWdlID0gaW5zdGFuY2VzLnJlZHVjZSgoc3VtLCBiKSA9PiBzdW0gKyBiLnVzYWdlQ291bnQsIDApO1xuXG4gICAgY29uc3QgYWdlcyA9IGluc3RhbmNlcy5tYXAoKGIpID0+IERhdGUubm93KCkgLSBiLmNyZWF0ZWRBdC5nZXRUaW1lKCkpO1xuICAgIGNvbnN0IGF2ZXJhZ2VBZ2UgPSBhZ2VzLmxlbmd0aCA+IDAgPyBhZ2VzLnJlZHVjZSgoc3VtLCBhZ2UpID0+IHN1bSArIGFnZSwgMCkgLyBhZ2VzLmxlbmd0aCA6IDA7XG5cbiAgICBjb25zdCBvbGRlc3RJbnN0YW5jZSA9XG4gICAgICBpbnN0YW5jZXMubGVuZ3RoID4gMFxuICAgICAgICA/IGluc3RhbmNlcy5yZWR1Y2UoKG9sZGVzdCwgY3VycmVudCkgPT5cbiAgICAgICAgICAgIGN1cnJlbnQuY3JlYXRlZEF0IDwgb2xkZXN0LmNyZWF0ZWRBdCA/IGN1cnJlbnQgOiBvbGRlc3RcbiAgICAgICAgICApLmNyZWF0ZWRBdFxuICAgICAgICA6IG51bGw7XG5cbiAgICBjb25zdCBuZXdlc3RJbnN0YW5jZSA9XG4gICAgICBpbnN0YW5jZXMubGVuZ3RoID4gMFxuICAgICAgICA/IGluc3RhbmNlcy5yZWR1Y2UoKG5ld2VzdCwgY3VycmVudCkgPT5cbiAgICAgICAgICAgIGN1cnJlbnQuY3JlYXRlZEF0ID4gbmV3ZXN0LmNyZWF0ZWRBdCA/IGN1cnJlbnQgOiBuZXdlc3RcbiAgICAgICAgICApLmNyZWF0ZWRBdFxuICAgICAgICA6IG51bGw7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG90YWxJbnN0YW5jZXM6IGluc3RhbmNlcy5sZW5ndGgsXG4gICAgICBhdmFpbGFibGVJbnN0YW5jZXMsXG4gICAgICBidXN5SW5zdGFuY2VzLFxuICAgICAgdW5oZWFsdGh5SW5zdGFuY2VzLFxuICAgICAgdG90YWxVc2FnZSxcbiAgICAgIGF2ZXJhZ2VBZ2UsXG4gICAgICBvbGRlc3RJbnN0YW5jZSxcbiAgICAgIG5ld2VzdEluc3RhbmNlLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW51cCBhbmQgc2h1dGRvd24gdGhlIGJyb3dzZXIgcG9vbFxuICAgKi9cbiAgYXN5bmMgY2xlYW51cCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmlzU2h1dHRpbmdEb3duID0gdHJ1ZTtcblxuICAgIC8vIFN0b3AgbW9uaXRvcmluZyB0aW1lcnNcbiAgICBpZiAodGhpcy5oZWFsdGhDaGVja1RpbWVyKSB7XG4gICAgICBjbGVhckludGVydmFsKHRoaXMuaGVhbHRoQ2hlY2tUaW1lcik7XG4gICAgICB0aGlzLmhlYWx0aENoZWNrVGltZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNsZWFudXBUaW1lcikge1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmNsZWFudXBUaW1lcik7XG4gICAgICB0aGlzLmNsZWFudXBUaW1lciA9IG51bGw7XG4gICAgfVxuXG4gICAgLy8gQ2xvc2UgYWxsIGJyb3dzZXJzXG4gICAgY29uc3QgY2xvc2VQcm9taXNlcyA9IEFycmF5LmZyb20odGhpcy5wb29sLnZhbHVlcygpKS5tYXAoYXN5bmMgKG1hbmFnZWRCcm93c2VyKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBtYW5hZ2VkQnJvd3Nlci5icm93c2VyLmNsb3NlKCk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgQ2xvc2VkIGJyb3dzZXIgJHttYW5hZ2VkQnJvd3Nlci5pZH1gKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBFcnJvciBjbG9zaW5nIGJyb3dzZXIgJHttYW5hZ2VkQnJvd3Nlci5pZH06ICR7ZXJyb3J9YCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoY2xvc2VQcm9taXNlcyk7XG4gICAgdGhpcy5wb29sLmNsZWFyKCk7XG5cbiAgICBsb2dnZXIuaW5mbygnQnJvd3NlciBwb29sIGNsZWFudXAgY29tcGxldGVkJyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGJyb3dzZXIgaW5zdGFuY2VcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY3JlYXRlQnJvd3Nlckluc3RhbmNlKCk6IFByb21pc2U8TWFuYWdlZEJyb3dzZXI+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbGF1bmNoT3B0aW9uczogYW55ID0ge1xuICAgICAgICBoZWFkbGVzczogdGhpcy5jb25maWcuYnJvd3Nlci5oZWFkbGVzc0RlZmF1bHQsXG4gICAgICAgIHNsb3dNbzogdGhpcy5jb25maWcuYnJvd3Nlci5zbG93bW8sXG4gICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICAnLS1uby1zYW5kYm94JyxcbiAgICAgICAgICAnLS1kaXNhYmxlLXNldHVpZC1zYW5kYm94JyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWRldi1zaG0tdXNhZ2UnLFxuICAgICAgICAgICctLWRpc2FibGUtYWNjZWxlcmF0ZWQtMmQtY2FudmFzJyxcbiAgICAgICAgICAnLS1uby1maXJzdC1ydW4nLFxuICAgICAgICAgICctLW5vLXp5Z290ZScsXG4gICAgICAgICAgJy0tZGlzYWJsZS1ncHUnLFxuICAgICAgICAgICctLWRpc2FibGUtYmFja2dyb3VuZC10aW1lci10aHJvdHRsaW5nJyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWJhY2tncm91bmRpbmctb2NjbHVkZWQtd2luZG93cycsXG4gICAgICAgICAgJy0tZGlzYWJsZS1yZW5kZXJlci1iYWNrZ3JvdW5kaW5nJyxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGJyb3dzZXIgPSBhd2FpdCBwdXBwZXRlZXIubGF1bmNoKGxhdW5jaE9wdGlvbnMpO1xuICAgICAgY29uc3QgY29udGV4dCA9IGF3YWl0IGJyb3dzZXIuY3JlYXRlQnJvd3NlckNvbnRleHQoKTtcblxuICAgICAgY29uc3QgaWQgPSB0aGlzLmdlbmVyYXRlQnJvd3NlcklkKCk7XG4gICAgICBjb25zdCBtYW5hZ2VkQnJvd3NlcjogTWFuYWdlZEJyb3dzZXIgPSB7XG4gICAgICAgIGJyb3dzZXIsXG4gICAgICAgIGNvbnRleHQsXG4gICAgICAgIGlkLFxuICAgICAgICBjcmVhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgIGxhc3RVc2VkOiBuZXcgRGF0ZSgpLFxuICAgICAgICBpc0F2YWlsYWJsZTogdHJ1ZSxcbiAgICAgICAgaXNIZWFsdGh5OiB0cnVlLFxuICAgICAgICB1c2FnZUNvdW50OiAwLFxuICAgICAgfTtcblxuICAgICAgdGhpcy5wb29sLnNldChpZCwgbWFuYWdlZEJyb3dzZXIpO1xuXG4gICAgICAvLyBTZXQgdXAgYnJvd3NlciBldmVudCBoYW5kbGVyc1xuICAgICAgYnJvd3Nlci5vbignZGlzY29ubmVjdGVkJywgKCkgPT4ge1xuICAgICAgICBsb2dnZXIud2FybihgQnJvd3NlciAke2lkfSBkaXNjb25uZWN0ZWQgdW5leHBlY3RlZGx5YCk7XG4gICAgICAgIHRoaXMuaGFuZGxlQnJvd3NlckRpc2Nvbm5lY3Rpb24oaWQpO1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBtYW5hZ2VkQnJvd3NlcjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIGJyb3dzZXIgaW5zdGFuY2U6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgQnJvd3NlckxhdW5jaEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGNyZWF0ZSBicm93c2VyIGluc3RhbmNlOiAke2Vycm9yfWAsXG4gICAgICAgIHsgcG9vbFNpemU6IHRoaXMucG9vbC5zaXplIH0sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGFuIGF2YWlsYWJsZSBoZWFsdGh5IGJyb3dzZXIgaW4gdGhlIHBvb2xcbiAgICovXG4gIHByaXZhdGUgZmluZEF2YWlsYWJsZUJyb3dzZXIoKTogTWFuYWdlZEJyb3dzZXIgfCBudWxsIHtcbiAgICBmb3IgKGNvbnN0IGJyb3dzZXIgb2YgdGhpcy5wb29sLnZhbHVlcygpKSB7XG4gICAgICBpZiAoYnJvd3Nlci5pc0F2YWlsYWJsZSAmJiBicm93c2VyLmlzSGVhbHRoeSkge1xuICAgICAgICByZXR1cm4gYnJvd3NlcjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBicm93c2VyIHNob3VsZCBiZSByZXRpcmVkXG4gICAqL1xuICBwcml2YXRlIHNob3VsZFJldGlyZUJyb3dzZXIoYnJvd3NlcjogTWFuYWdlZEJyb3dzZXIpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBjb25zdCBhZ2UgPSBEYXRlLm5vdygpIC0gYnJvd3Nlci5jcmVhdGVkQXQuZ2V0VGltZSgpO1xuXG4gICAgaWYgKGFnZSA+IHRoaXMub3B0aW9ucy5tYXhBZ2UpIHtcbiAgICAgIHJldHVybiAnbWF4IGFnZSBleGNlZWRlZCc7XG4gICAgfVxuXG4gICAgaWYgKGJyb3dzZXIudXNhZ2VDb3VudCA+PSB0aGlzLm9wdGlvbnMubWF4VXNhZ2VDb3VudCkge1xuICAgICAgcmV0dXJuICdtYXggdXNhZ2UgY291bnQgZXhjZWVkZWQnO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gaGVhbHRoIGNoZWNrIG9uIGEgYnJvd3NlciBpbnN0YW5jZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjaGVja0Jyb3dzZXJIZWFsdGgoYnJvd3NlcjogTWFuYWdlZEJyb3dzZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICB0cnkge1xuICAgICAgLy8gQ2hlY2sgaWYgYnJvd3NlciBpcyBjb25uZWN0ZWRcbiAgICAgIGlmICghYnJvd3Nlci5icm93c2VyLmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyBUcnkgdG8gY3JlYXRlIGFuZCBjbG9zZSBhIHRlc3QgcGFnZVxuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IGJyb3dzZXIuY29udGV4dC5uZXdQYWdlKCk7XG4gICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZGVidWcoYEJyb3dzZXIgJHticm93c2VyLmlkfSBoZWFsdGggY2hlY2sgZmFpbGVkOiAke2Vycm9yfWApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYSBicm93c2VyIGZyb20gdGhlIHBvb2xcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVtb3ZlQnJvd3NlckZyb21Qb29sKGJyb3dzZXJJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYnJvd3NlciA9IHRoaXMucG9vbC5nZXQoYnJvd3NlcklkKTtcbiAgICBpZiAoIWJyb3dzZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgYnJvd3Nlci5icm93c2VyLmNsb3NlKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBFcnJvciBjbG9zaW5nIGJyb3dzZXIgJHticm93c2VySWR9OiAke2Vycm9yfWApO1xuICAgIH1cblxuICAgIHRoaXMucG9vbC5kZWxldGUoYnJvd3NlcklkKTtcbiAgICBsb2dnZXIuZGVidWcoYFJlbW92ZWQgYnJvd3NlciAke2Jyb3dzZXJJZH0gZnJvbSBwb29sYCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIGJyb3dzZXIgZGlzY29ubmVjdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVCcm93c2VyRGlzY29ubmVjdGlvbihicm93c2VySWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGJyb3dzZXIgPSB0aGlzLnBvb2wuZ2V0KGJyb3dzZXJJZCk7XG4gICAgaWYgKGJyb3dzZXIpIHtcbiAgICAgIGJyb3dzZXIuaXNIZWFsdGh5ID0gZmFsc2U7XG4gICAgICBicm93c2VyLmlzQXZhaWxhYmxlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUmVtb3ZlIHRoZSBkaXNjb25uZWN0ZWQgYnJvd3NlciBhbmQgZW5zdXJlIG1pbmltdW0gaW5zdGFuY2VzXG4gICAgYXdhaXQgdGhpcy5yZW1vdmVCcm93c2VyRnJvbVBvb2woYnJvd3NlcklkKTtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZU1pbmltdW1JbnN0YW5jZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmUgbWluaW11bSBudW1iZXIgb2YgaW5zdGFuY2VzIGFyZSBhdmFpbGFibGVcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlTWluaW11bUluc3RhbmNlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5pc1NodXR0aW5nRG93bikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGhlYWx0aHlDb3VudCA9IEFycmF5LmZyb20odGhpcy5wb29sLnZhbHVlcygpKS5maWx0ZXIoKGIpID0+IGIuaXNIZWFsdGh5KS5sZW5ndGg7XG5cbiAgICBjb25zdCBuZWVkZWQgPSB0aGlzLm9wdGlvbnMubWluSW5zdGFuY2VzIC0gaGVhbHRoeUNvdW50O1xuXG4gICAgaWYgKG5lZWRlZCA+IDApIHtcbiAgICAgIGxvZ2dlci5pbmZvKGBDcmVhdGluZyAke25lZWRlZH0gYnJvd3NlciBpbnN0YW5jZXMgdG8gbWFpbnRhaW4gbWluaW11bSBwb29sIHNpemVgKTtcblxuICAgICAgY29uc3QgY3JlYXRlUHJvbWlzZXMgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiBuZWVkZWQgfSwgKCkgPT5cbiAgICAgICAgdGhpcy5jcmVhdGVCcm93c2VySW5zdGFuY2UoKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgYnJvd3NlciBmb3IgbWluaW11bSBpbnN0YW5jZXM6ICR7ZXJyb3J9YCk7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH0pXG4gICAgICApO1xuXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoY3JlYXRlUHJvbWlzZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgY291bnQgb2YgYXZhaWxhYmxlIGJyb3dzZXJzXG4gICAqL1xuICBwcml2YXRlIGdldEF2YWlsYWJsZUNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5wb29sLnZhbHVlcygpKS5maWx0ZXIoKGIpID0+IGIuaXNBdmFpbGFibGUgJiYgYi5pc0hlYWx0aHkpLmxlbmd0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBoZWFsdGggbW9uaXRvcmluZ1xuICAgKi9cbiAgcHJpdmF0ZSBzdGFydEhlYWx0aE1vbml0b3JpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5oZWFsdGhDaGVja1RpbWVyID0gc2V0SW50ZXJ2YWwoYXN5bmMgKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNTaHV0dGluZ0Rvd24pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB1bmhlYWx0aHlCcm93c2Vyczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBbaWQsIGJyb3dzZXJdIG9mIHRoaXMucG9vbC5lbnRyaWVzKCkpIHtcbiAgICAgICAgaWYgKCFicm93c2VyLmlzQXZhaWxhYmxlKSB7XG4gICAgICAgICAgY29udGludWU7IC8vIFNraXAgYnJvd3NlcnMgY3VycmVudGx5IGluIHVzZVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXNIZWFsdGh5ID0gYXdhaXQgdGhpcy5jaGVja0Jyb3dzZXJIZWFsdGgoYnJvd3Nlcik7XG4gICAgICAgIGlmICghaXNIZWFsdGh5KSB7XG4gICAgICAgICAgdW5oZWFsdGh5QnJvd3NlcnMucHVzaChpZCk7XG4gICAgICAgICAgYnJvd3Nlci5pc0hlYWx0aHkgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBSZW1vdmUgdW5oZWFsdGh5IGJyb3dzZXJzXG4gICAgICBmb3IgKGNvbnN0IGlkIG9mIHVuaGVhbHRoeUJyb3dzZXJzKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBSZW1vdmluZyB1bmhlYWx0aHkgYnJvd3NlciAke2lkfSBkdXJpbmcgaGVhbHRoIGNoZWNrYCk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVtb3ZlQnJvd3NlckZyb21Qb29sKGlkKTtcbiAgICAgIH1cblxuICAgICAgLy8gRW5zdXJlIG1pbmltdW0gaW5zdGFuY2VzIGFmdGVyIGNsZWFudXBcbiAgICAgIGlmICh1bmhlYWx0aHlCcm93c2Vycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZW5zdXJlTWluaW11bUluc3RhbmNlcygpO1xuICAgICAgfVxuICAgIH0sIHRoaXMub3B0aW9ucy5oZWFsdGhDaGVja0ludGVydmFsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBjbGVhbnVwIG1vbml0b3JpbmcgZm9yIGlkbGUgYW5kIHN0dWNrIGJyb3dzZXJzXG4gICAqL1xuICBwcml2YXRlIHN0YXJ0Q2xlYW51cE1vbml0b3JpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhbnVwVGltZXIgPSBzZXRJbnRlcnZhbChhc3luYyAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5pc1NodXR0aW5nRG93bikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICBjb25zdCBicm93c2Vyc1RvUmVtb3ZlOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IFtpZCwgYnJvd3Nlcl0gb2YgdGhpcy5wb29sLmVudHJpZXMoKSkge1xuICAgICAgICBjb25zdCBpZGxlVGltZSA9IG5vdyAtIGJyb3dzZXIubGFzdFVzZWQuZ2V0VGltZSgpO1xuICAgICAgICBjb25zdCBzaG91bGRSZXRpcmUgPSB0aGlzLnNob3VsZFJldGlyZUJyb3dzZXIoYnJvd3Nlcik7XG5cbiAgICAgICAgLy8gQWxzbyBjaGVjayBzdHVjayBicm93c2VycyAoYnVzeSBidXQgc3R1Y2sgdGltZW91dCBleGNlZWRlZClcbiAgICAgICAgLy8gVGhlc2UgYXJlIHVzdWFsbHkgY2F1c2VkIGJ5IHVuaGFuZGxlZCBleGNlcHRpb25zIHByZXZlbnRpbmcgcmVsZWFzZUJyb3dzZXIgZnJvbSBiZWluZyBjYWxsZWRcbiAgICAgICAgY29uc3QgaXNTdHVjayA9ICFicm93c2VyLmlzQXZhaWxhYmxlICYmIGlkbGVUaW1lID4gdGhpcy5vcHRpb25zLnN0dWNrVGltZW91dDtcblxuICAgICAgICBpZiAoaWRsZVRpbWUgPiB0aGlzLm9wdGlvbnMuaWRsZVRpbWVvdXQgfHwgc2hvdWxkUmV0aXJlIHx8IGlzU3R1Y2spIHtcbiAgICAgICAgICBjb25zdCBoZWFsdGh5Q291bnQgPSBBcnJheS5mcm9tKHRoaXMucG9vbC52YWx1ZXMoKSkuZmlsdGVyKChiKSA9PiBiLmlzSGVhbHRoeSkubGVuZ3RoO1xuXG4gICAgICAgICAgLy8gRm9yY2UgcmVtb3ZhbCBmb3Igc3R1Y2sgYnJvd3NlcnMgKGRvbid0IGNoZWNrIG1pbmltdW0gaW5zdGFuY2UgY291bnQpXG4gICAgICAgICAgLy8gT3RoZXJ3aXNlIG9ubHkgcmVtb3ZlIGlmIGFib3ZlIG1pbmltdW0gaW5zdGFuY2VzXG4gICAgICAgICAgaWYgKGlzU3R1Y2sgfHwgaGVhbHRoeUNvdW50ID4gdGhpcy5vcHRpb25zLm1pbkluc3RhbmNlcykge1xuICAgICAgICAgICAgYnJvd3NlcnNUb1JlbW92ZS5wdXNoKGlkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gUmVtb3ZlIGlkbGUvb2xkL3N0dWNrIGJyb3dzZXJzXG4gICAgICBmb3IgKGNvbnN0IGlkIG9mIGJyb3dzZXJzVG9SZW1vdmUpIHtcbiAgICAgICAgY29uc3QgYnJvd3NlciA9IHRoaXMucG9vbC5nZXQoaWQpO1xuICAgICAgICBjb25zdCBpc1N0dWNrID0gYnJvd3NlciAmJiAhYnJvd3Nlci5pc0F2YWlsYWJsZTtcbiAgICAgICAgY29uc3QgcmVhc29uID0gdGhpcy5zaG91bGRSZXRpcmVCcm93c2VyKGJyb3dzZXIhKSB8fCAoaXNTdHVjayA/ICdzdHVjayBicm93c2VyIHRpbWVvdXQnIDogJ2lkbGUgdGltZW91dCcpO1xuICAgICAgICBsb2dnZXIuaW5mbyhgUmVtb3ZpbmcgYnJvd3NlciAke2lkfSBkdWUgdG8gJHtyZWFzb259YCk7XG5cbiAgICAgICAgLy8gRm9yIHN0dWNrIGJyb3dzZXJzLCB0cnkgdG8gY2xvc2UgYW55IG9wZW4gcGFnZXMgZmlyc3RcbiAgICAgICAgaWYgKGlzU3R1Y2sgJiYgYnJvd3Nlcikge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBwYWdlcyA9IGF3YWl0IGJyb3dzZXIuY29udGV4dC5wYWdlcygpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBwIG9mIHBhZ2VzKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKCFwLmlzQ2xvc2VkKCkpIHtcbiAgICAgICAgICAgICAgICAgIGF3YWl0IHAuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBpZ25vcmVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIGlnbm9yZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHRoaXMucmVtb3ZlQnJvd3NlckZyb21Qb29sKGlkKTtcbiAgICAgIH1cblxuICAgICAgLy8gRW5zdXJlIG1pbmltdW0gaW5zdGFuY2VzIGFmdGVyIGNsZWFudXAgb25seSBpZiBicm93c2VycyB3ZXJlIHJlbW92ZWRcbiAgICAgIGlmIChicm93c2Vyc1RvUmVtb3ZlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5lbnN1cmVNaW5pbXVtSW5zdGFuY2VzKCk7XG4gICAgICB9XG4gICAgfSwgdGhpcy5vcHRpb25zLmhlYWx0aENoZWNrSW50ZXJ2YWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIHVuaXF1ZSBicm93c2VyIElEXG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlQnJvd3NlcklkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBicm93c2VyXyR7RGF0ZS5ub3coKX1fJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMiwgMTEpfWA7XG4gIH1cbn1cblxuLy8gR2xvYmFsIGJyb3dzZXIgcG9vbCBpbnN0YW5jZVxubGV0IGdsb2JhbEJyb3dzZXJQb29sOiBCcm93c2VyUG9vbFNlcnZpY2UgfCBudWxsID0gbnVsbDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJyb3dzZXJQb29sKCk6IEJyb3dzZXJQb29sU2VydmljZSB7XG4gIGlmICghZ2xvYmFsQnJvd3NlclBvb2wpIHtcbiAgICBnbG9iYWxCcm93c2VyUG9vbCA9IG5ldyBCcm93c2VyUG9vbFNlcnZpY2UoKTtcbiAgfVxuICByZXR1cm4gZ2xvYmFsQnJvd3NlclBvb2w7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGVhbnVwQnJvd3NlclBvb2woKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChnbG9iYWxCcm93c2VyUG9vbCkge1xuICAgIGF3YWl0IGdsb2JhbEJyb3dzZXJQb29sLmNsZWFudXAoKTtcbiAgICBnbG9iYWxCcm93c2VyUG9vbCA9IG51bGw7XG4gIH1cbn1cbiIsIi8qKlxuICogQnJvd3NlciBNYW5hZ2VyIGZvciBYSFMgT3BlcmF0aW9uc1xuICovXG5cbmltcG9ydCBwdXBwZXRlZXIsIHsgQnJvd3NlciwgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBDb25maWcsIENvb2tpZSB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBCcm93c2VyTGF1bmNoRXJyb3IsIEJyb3dzZXJOYXZpZ2F0aW9uRXJyb3IsIFhIU0Vycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IGxvYWRDb29raWVzLCBzYXZlQ29va2llcyB9IGZyb20gJy4uLy4uL3NoYXJlZC9jb29raWVzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgQnJvd3NlclBvb2xTZXJ2aWNlLCBNYW5hZ2VkQnJvd3NlciwgQnJvd3NlclBvb2xPcHRpb25zIH0gZnJvbSAnLi9icm93c2VyLXBvb2wuc2VydmljZSc7XG5cbmV4cG9ydCBjbGFzcyBCcm93c2VyTWFuYWdlciB7XG4gIHByaXZhdGUgY29uZmlnOiBDb25maWc7XG4gIHByaXZhdGUgYnJvd3NlcjogQnJvd3NlciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGJyb3dzZXJQb29sOiBCcm93c2VyUG9vbFNlcnZpY2UgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB1c2VQb29sOiBib29sZWFuID0gZmFsc2U7XG4gIHByaXZhdGUgcG9vbE9wdGlvbnM/OiBCcm93c2VyUG9vbE9wdGlvbnM7XG4gIHByaXZhdGUgdHJhY2tlZFBhZ2VzOiBTZXQ8UGFnZT4gPSBuZXcgU2V0KCk7XG4gIHByaXZhdGUgbWF4VHJhY2tlZFBhZ2VzOiBudW1iZXIgPSAxMDtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc/OiBDb25maWcsIHVzZVBvb2w6IGJvb2xlYW4gPSBmYWxzZSwgcG9vbE9wdGlvbnM/OiBCcm93c2VyUG9vbE9wdGlvbnMpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyB8fCBnZXRDb25maWcoKTtcbiAgICB0aGlzLnVzZVBvb2wgPSB1c2VQb29sO1xuICAgIHRoaXMucG9vbE9wdGlvbnMgPSBwb29sT3B0aW9ucztcblxuICAgIGlmICh0aGlzLnVzZVBvb2wpIHtcbiAgICAgIHRoaXMuYnJvd3NlclBvb2wgPSBuZXcgQnJvd3NlclBvb2xTZXJ2aWNlKHRoaXMuY29uZmlnLCBwb29sT3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY3JlYXRlUGFnZShcbiAgICBoZWFkbGVzcz86IGJvb2xlYW4sXG4gICAgZXhlY3V0YWJsZVBhdGg/OiBzdHJpbmcsXG4gICAgc2hvdWxkTG9hZENvb2tpZXM6IGJvb2xlYW4gPSB0cnVlXG4gICk6IFByb21pc2U8UGFnZT4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBVc2UgYnJvd3NlciBwb29sIGlmIGVuYWJsZWRcbiAgICAgIGlmICh0aGlzLnVzZVBvb2wgJiYgdGhpcy5icm93c2VyUG9vbCkge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jcmVhdGVQYWdlRnJvbVBvb2woc2hvdWxkTG9hZENvb2tpZXMpO1xuICAgICAgfVxuXG4gICAgICAvLyBGYWxsYmFjayB0byB0cmFkaXRpb25hbCBicm93c2VyIG1hbmFnZW1lbnRcbiAgICAgIC8vIExhdW5jaCBicm93c2VyIGlmIG5vdCBhbHJlYWR5IGxhdW5jaGVkXG4gICAgICBpZiAoIXRoaXMuYnJvd3Nlcikge1xuICAgICAgICB0aGlzLmJyb3dzZXIgPSBhd2FpdCB0aGlzLmxhdW5jaEJyb3dzZXIoaGVhZGxlc3MsIGV4ZWN1dGFibGVQYXRoKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ3JlYXRlIG5ldyBwYWdlXG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5icm93c2VyLm5ld1BhZ2UoKTtcblxuICAgICAgLy8gVHJhY2sgcGFnZSBmb3IgY2xlYW51cFxuICAgICAgdGhpcy50cmFja2VkUGFnZXMuYWRkKHBhZ2UpO1xuICAgICAgcGFnZS5vbmNlKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgdGhpcy50cmFja2VkUGFnZXMuZGVsZXRlKHBhZ2UpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIEF1dG8tY2xlYW51cCBpZiB0b28gbWFueSBwYWdlcyBhcmUgb3BlbiAobGVhayBkZXRlY3Rpb24pXG4gICAgICBpZiAodGhpcy50cmFja2VkUGFnZXMuc2l6ZSA+IHRoaXMubWF4VHJhY2tlZFBhZ2VzKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBUcmFja2VkIHBhZ2VzICgke3RoaXMudHJhY2tlZFBhZ2VzLnNpemV9KSBleGNlZWRzIHRocmVzaG9sZCAoJHt0aGlzLm1heFRyYWNrZWRQYWdlc30pLCBmb3JjaW5nIGNsZWFudXBgKTtcbiAgICAgICAgYXdhaXQgdGhpcy5jbG9zZUFsbFBhZ2VzKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIENvbmZpZ3VyZSBwYWdlIHRpbWVvdXRzXG4gICAgICBwYWdlLnNldERlZmF1bHRUaW1lb3V0KHRoaXMuY29uZmlnLmJyb3dzZXIuZGVmYXVsdFRpbWVvdXQpO1xuICAgICAgcGFnZS5zZXREZWZhdWx0TmF2aWdhdGlvblRpbWVvdXQodGhpcy5jb25maWcuYnJvd3Nlci5uYXZpZ2F0aW9uVGltZW91dCk7XG5cbiAgICAgIC8vIExvYWQgY29va2llcyBpZiByZXF1ZXN0ZWRcbiAgICAgIGlmIChzaG91bGRMb2FkQ29va2llcykge1xuICAgICAgICBhd2FpdCB0aGlzLmxvYWRDb29raWVzSW50b1BhZ2UocGFnZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYWdlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEJyb3dzZXIgcGFnZSBjcmVhdGlvbiBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IHRoaXMuaGFuZGxlUHVwcGV0ZWVyRXJyb3IoZXJyb3IgYXMgRXJyb3IsICdjcmVhdGVfcGFnZScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBwYWdlIHVzaW5nIHRoZSBicm93c2VyIHBvb2xcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY3JlYXRlUGFnZUZyb21Qb29sKHNob3VsZExvYWRDb29raWVzOiBib29sZWFuID0gdHJ1ZSk6IFByb21pc2U8UGFnZT4ge1xuICAgIGlmICghdGhpcy5icm93c2VyUG9vbCkge1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKCdCcm93c2VyIHBvb2wgbm90IGluaXRpYWxpemVkJywgJ0Jyb3dzZXJQb29sRXJyb3InKTtcbiAgICB9XG5cbiAgICBjb25zdCBtYW5hZ2VkQnJvd3NlciA9IGF3YWl0IHRoaXMuYnJvd3NlclBvb2wuYWNxdWlyZUJyb3dzZXIoKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBDcmVhdGUgbmV3IHBhZ2UgZnJvbSB0aGUgbWFuYWdlZCBicm93c2VyIGNvbnRleHRcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBtYW5hZ2VkQnJvd3Nlci5jb250ZXh0Lm5ld1BhZ2UoKTtcblxuICAgICAgLy8gQ29uZmlndXJlIHBhZ2UgdGltZW91dHNcbiAgICAgIHBhZ2Uuc2V0RGVmYXVsdFRpbWVvdXQodGhpcy5jb25maWcuYnJvd3Nlci5kZWZhdWx0VGltZW91dCk7XG4gICAgICBwYWdlLnNldERlZmF1bHROYXZpZ2F0aW9uVGltZW91dCh0aGlzLmNvbmZpZy5icm93c2VyLm5hdmlnYXRpb25UaW1lb3V0KTtcblxuICAgICAgLy8gTG9hZCBjb29raWVzIGlmIHJlcXVlc3RlZFxuICAgICAgaWYgKHNob3VsZExvYWRDb29raWVzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMubG9hZENvb2tpZXNJbnRvUGFnZShwYWdlKTtcbiAgICAgIH1cblxuICAgICAgLy8gU3RvcmUgcmVmZXJlbmNlIHRvIG1hbmFnZWQgYnJvd3NlciBmb3IgY2xlYW51cFxuICAgICAgKHBhZ2UgYXMgUGFnZSAmIHsgX21hbmFnZWRCcm93c2VyPzogTWFuYWdlZEJyb3dzZXIgfSkuX21hbmFnZWRCcm93c2VyID0gbWFuYWdlZEJyb3dzZXI7XG5cbiAgICAgIC8vIFNldCB1cCBwYWdlIGNsb3NlIGhhbmRsZXIgdG8gcmVsZWFzZSBicm93c2VyIGJhY2sgdG8gcG9vbFxuICAgICAgbGV0IHJlbGVhc2VkID0gZmFsc2U7XG4gICAgICBjb25zdCByZWxlYXNlQnJvd3NlciA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgaWYgKHJlbGVhc2VkKSByZXR1cm47XG4gICAgICAgIHJlbGVhc2VkID0gdHJ1ZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmJyb3dzZXJQb29sIS5yZWxlYXNlQnJvd3NlcihtYW5hZ2VkQnJvd3Nlcik7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgbG9nZ2VyLndhcm4oYEVycm9yIHJlbGVhc2luZyBicm93c2VyIGJhY2sgdG8gcG9vbDogJHtlcnJvcn1gKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgcGFnZS5vbmNlKCdjbG9zZScsIHJlbGVhc2VCcm93c2VyKTtcblxuICAgICAgcmV0dXJuIHBhZ2U7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIFJlbGVhc2UgYnJvd3NlciBiYWNrIHRvIHBvb2wgb24gZXJyb3JcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuYnJvd3NlclBvb2wucmVsZWFzZUJyb3dzZXIobWFuYWdlZEJyb3dzZXIpO1xuICAgICAgfSBjYXRjaCAocmVsZWFzZUVycm9yKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBFcnJvciByZWxlYXNpbmcgYnJvd3NlciBhZnRlciBwYWdlIGNyZWF0aW9uIGZhaWx1cmU6ICR7cmVsZWFzZUVycm9yfWApO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBsYXVuY2hCcm93c2VyKGhlYWRsZXNzPzogYm9vbGVhbiwgZXhlY3V0YWJsZVBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPEJyb3dzZXI+IHtcbiAgICBjb25zdCBpc0hlYWRsZXNzID0gaGVhZGxlc3MgPz8gdGhpcy5jb25maWcuYnJvd3Nlci5oZWFkbGVzc0RlZmF1bHQ7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgbGF1bmNoT3B0aW9uczogYW55ID0ge1xuICAgICAgICBoZWFkbGVzczogaXNIZWFkbGVzcyxcbiAgICAgICAgc2xvd01vOiB0aGlzLmNvbmZpZy5icm93c2VyLnNsb3dtbyxcbiAgICAgICAgYXJnczogW1xuICAgICAgICAgICctLW5vLXNhbmRib3gnLFxuICAgICAgICAgICctLWRpc2FibGUtc2V0dWlkLXNhbmRib3gnLFxuICAgICAgICAgICctLWRpc2FibGUtZGV2LXNobS11c2FnZScsXG4gICAgICAgICAgJy0tZGlzYWJsZS1hY2NlbGVyYXRlZC0yZC1jYW52YXMnLFxuICAgICAgICAgICctLW5vLWZpcnN0LXJ1bicsXG4gICAgICAgICAgJy0tbm8tenlnb3RlJyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWdwdScsXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBpZiAoZXhlY3V0YWJsZVBhdGgpIHtcbiAgICAgICAgbGF1bmNoT3B0aW9ucy5leGVjdXRhYmxlUGF0aCA9IGV4ZWN1dGFibGVQYXRoO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBicm93c2VyID0gYXdhaXQgcHVwcGV0ZWVyLmxhdW5jaChsYXVuY2hPcHRpb25zKTtcblxuICAgICAgcmV0dXJuIGJyb3dzZXI7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGxhdW5jaCBicm93c2VyOiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IEJyb3dzZXJMYXVuY2hFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBsYXVuY2ggYnJvd3NlcjogJHtlcnJvcn1gLFxuICAgICAgICB7IGhlYWRsZXNzOiBpc0hlYWRsZXNzLCBleGVjdXRhYmxlUGF0aCB9LFxuICAgICAgICBlcnJvciBhcyBFcnJvclxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRDb29raWVzSW50b1BhZ2UocGFnZTogUGFnZSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb29raWVzID0gbG9hZENvb2tpZXMoKTtcblxuICAgICAgaWYgKCFjb29raWVzKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gQ29udmVydCBvdXIgY29va2llIGZvcm1hdCB0byBQdXBwZXRlZXIgZm9ybWF0XG4gICAgICBjb25zdCBwdXBwZXRlZXJDb29raWVzID0gY29va2llcy5tYXAoKGNvb2tpZSkgPT4gKHtcbiAgICAgICAgbmFtZTogY29va2llLm5hbWUsXG4gICAgICAgIHZhbHVlOiBjb29raWUudmFsdWUsXG4gICAgICAgIGRvbWFpbjogY29va2llLmRvbWFpbixcbiAgICAgICAgcGF0aDogY29va2llLnBhdGgsXG4gICAgICAgIGV4cGlyZXM6IGNvb2tpZS5leHBpcmVzLFxuICAgICAgICBodHRwT25seTogY29va2llLmh0dHBPbmx5LFxuICAgICAgICBzZWN1cmU6IGNvb2tpZS5zZWN1cmUsXG4gICAgICAgIHNhbWVTaXRlOiBjb29raWUuc2FtZVNpdGUgYXMgJ1N0cmljdCcgfCAnTGF4JyB8ICdOb25lJyB8IHVuZGVmaW5lZCxcbiAgICAgIH0pKTtcblxuICAgICAgYXdhaXQgcGFnZS5zZXRDb29raWUoLi4ucHVwcGV0ZWVyQ29va2llcyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBsb2FkIGNvb2tpZXM6ICR7ZXJyb3J9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc2F2ZUNvb2tpZXNGcm9tUGFnZShwYWdlOiBQYWdlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvb2tpZXMgPSBhd2FpdCBwYWdlLmNvb2tpZXMoKTtcblxuICAgICAgLy8gQ29udmVydCBQdXBwZXRlZXIgY29va2llIGZvcm1hdCB0byBhcHAgZm9ybWF0XG4gICAgICBjb25zdCBhcHBDb29raWVzOiBDb29raWVbXSA9IGNvb2tpZXMubWFwKChjb29raWUpID0+ICh7XG4gICAgICAgIG5hbWU6IGNvb2tpZS5uYW1lLFxuICAgICAgICB2YWx1ZTogY29va2llLnZhbHVlLFxuICAgICAgICBkb21haW46IGNvb2tpZS5kb21haW4sXG4gICAgICAgIHBhdGg6IGNvb2tpZS5wYXRoLFxuICAgICAgICBleHBpcmVzOiBjb29raWUuZXhwaXJlcyxcbiAgICAgICAgaHR0cE9ubHk6IGNvb2tpZS5odHRwT25seSxcbiAgICAgICAgc2VjdXJlOiBjb29raWUuc2VjdXJlLFxuICAgICAgICBzYW1lU2l0ZTogY29va2llLnNhbWVTaXRlIGFzICdTdHJpY3QnIHwgJ0xheCcgfCAnTm9uZScsXG4gICAgICB9KSk7XG5cbiAgICAgIHNhdmVDb29raWVzKGFwcENvb2tpZXMpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBzYXZlIGNvb2tpZXM6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyB0aGlzLmhhbmRsZVB1cHBldGVlckVycm9yKGVycm9yIGFzIEVycm9yLCAnc2F2ZV9jb29raWVzJyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgbmF2aWdhdGVXaXRoUmV0cnkoXG4gICAgcGFnZTogUGFnZSxcbiAgICB1cmw6IHN0cmluZyxcbiAgICB3YWl0VW50aWw6ICdsb2FkJyB8ICdkb21jb250ZW50bG9hZGVkJyB8ICduZXR3b3JraWRsZTAnIHwgJ25ldHdvcmtpZGxlMicgPSAnbG9hZCcsXG4gICAgbWF4UmV0cmllcz86IG51bWJlclxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCByZXRyaWVzID0gbWF4UmV0cmllcyB8fCB0aGlzLmNvbmZpZy54aHMubWF4UmV0cmllcztcblxuICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDw9IHJldHJpZXM7IGF0dGVtcHQrKykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgcGFnZS5nb3RvKHVybCwge1xuICAgICAgICAgIHdhaXRVbnRpbCxcbiAgICAgICAgICB0aW1lb3V0OiB0aGlzLmNvbmZpZy5icm93c2VyLm5hdmlnYXRpb25UaW1lb3V0LFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubmFtZSA9PT0gJ1RpbWVvdXRFcnJvcicpIHtcbiAgICAgICAgICBpZiAoYXR0ZW1wdCA9PT0gcmV0cmllcykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEJyb3dzZXJOYXZpZ2F0aW9uRXJyb3IoXG4gICAgICAgICAgICAgIGBGYWlsZWQgdG8gbmF2aWdhdGUgdG8gJHt1cmx9IGFmdGVyICR7cmV0cmllcyArIDF9IGF0dGVtcHRzYCxcbiAgICAgICAgICAgICAgeyB1cmwsIGF0dGVtcHRzOiBhdHRlbXB0ICsgMSB9LFxuICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhd2FpdCBzbGVlcCh0aGlzLmNvbmZpZy54aHMucmV0cnlEZWxheSAqIDEwMDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgdHJ5V2FpdEZvclNlbGVjdG9yKFxuICAgIHBhZ2U6IFBhZ2UsXG4gICAgc2VsZWN0b3I6IHN0cmluZyxcbiAgICB0aW1lb3V0PzogbnVtYmVyLFxuICAgIHZpc2libGU6IGJvb2xlYW4gPSB0cnVlXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBwYWdlLndhaXRGb3JTZWxlY3RvcihzZWxlY3Rvciwge1xuICAgICAgICB0aW1lb3V0OiB0aW1lb3V0IHx8IHRoaXMuY29uZmlnLmJyb3dzZXIuZGVmYXVsdFRpbWVvdXQsXG4gICAgICAgIHZpc2libGUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5uYW1lID09PSAnVGltZW91dEVycm9yJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBhc3luYyB3YWl0Rm9yU2VsZWN0b3JWaXNpYmxlKHBhZ2U6IFBhZ2UsIHNlbGVjdG9yOiBzdHJpbmcsIHRpbWVvdXQ/OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy50cnlXYWl0Rm9yU2VsZWN0b3IocGFnZSwgc2VsZWN0b3IsIHRpbWVvdXQsIHRydWUpO1xuICB9XG5cbiAgYXN5bmMgd2FpdEZvclNlbGVjdG9ySGlkZGVuKHBhZ2U6IFBhZ2UsIHNlbGVjdG9yOiBzdHJpbmcsIHRpbWVvdXQ/OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy50cnlXYWl0Rm9yU2VsZWN0b3IocGFnZSwgc2VsZWN0b3IsIHRpbWVvdXQsIGZhbHNlKTtcbiAgfVxuXG4gIGFzeW5jIGNsZWFudXAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQ2xlYW51cCBicm93c2VyIHBvb2wgaWYgdXNpbmcgaXRcbiAgICBpZiAodGhpcy51c2VQb29sICYmIHRoaXMuYnJvd3NlclBvb2wpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuYnJvd3NlclBvb2wuY2xlYW51cCgpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYEVycm9yIGNsZWFuaW5nIHVwIGJyb3dzZXIgcG9vbDogJHtlcnJvcn1gKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHRoaXMuYnJvd3NlclBvb2wgPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENsb3NlIGFsbCB0cmFja2VkIHBhZ2VzIGJlZm9yZSBjbG9zaW5nIGJyb3dzZXJcbiAgICBhd2FpdCB0aGlzLmNsb3NlQWxsUGFnZXMoKTtcblxuICAgIC8vIENsZWFudXAgdHJhZGl0aW9uYWwgYnJvd3NlciBpbnN0YW5jZVxuICAgIGlmICh0aGlzLmJyb3dzZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5jbG9zZSgpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYEVycm9yIGNsb3NpbmcgYnJvd3NlcjogJHtlcnJvcn1gKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHRoaXMuYnJvd3NlciA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIGFsbCB0cmFja2VkIHBhZ2VzIHRoYXQgYXJlIHN0aWxsIG9wZW5cbiAgICovXG4gIGFzeW5jIGNsb3NlQWxsUGFnZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY2xvc2VQcm9taXNlczogUHJvbWlzZTx2b2lkPltdID0gW107XG4gICAgZm9yIChjb25zdCBwYWdlIG9mIHRoaXMudHJhY2tlZFBhZ2VzKSB7XG4gICAgICBpZiAoIXBhZ2UuaXNDbG9zZWQoKSkge1xuICAgICAgICBjbG9zZVByb21pc2VzLnB1c2goXG4gICAgICAgICAgcGFnZS5jbG9zZSgpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oYEVycm9yIGNsb3NpbmcgdHJhY2tlZCBwYWdlOiAke2Vycm9yfWApO1xuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChjbG9zZVByb21pc2VzKTtcbiAgICB0aGlzLnRyYWNrZWRQYWdlcy5jbGVhcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBicm93c2VyIHBvb2wgc3RhdGlzdGljcyAoaWYgdXNpbmcgcG9vbClcbiAgICovXG4gIGdldEJyb3dzZXJQb29sU3RhdHMoKSB7XG4gICAgaWYgKHRoaXMudXNlUG9vbCAmJiB0aGlzLmJyb3dzZXJQb29sKSB7XG4gICAgICByZXR1cm4gdGhpcy5icm93c2VyUG9vbC5nZXRQb29sU3RhdHMoKTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBudW1iZXIgb2YgdHJhY2tlZCBwYWdlcyAoZm9yIG1vbml0b3JpbmcgbGVha3MpXG4gICAqL1xuICBnZXRUcmFja2VkUGFnZUNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudHJhY2tlZFBhZ2VzLnNpemU7XG4gIH1cblxuICAvKipcbiAgICogRW5hYmxlIGJyb3dzZXIgcG9vbGluZ1xuICAgKi9cbiAgZW5hYmxlQnJvd3NlclBvb2woKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnVzZVBvb2wpIHtcbiAgICAgIHRoaXMudXNlUG9vbCA9IHRydWU7XG4gICAgICB0aGlzLmJyb3dzZXJQb29sID0gbmV3IEJyb3dzZXJQb29sU2VydmljZSh0aGlzLmNvbmZpZywgdGhpcy5wb29sT3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERpc2FibGUgYnJvd3NlciBwb29saW5nXG4gICAqL1xuICBhc3luYyBkaXNhYmxlQnJvd3NlclBvb2woKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMudXNlUG9vbCAmJiB0aGlzLmJyb3dzZXJQb29sKSB7XG4gICAgICBhd2FpdCB0aGlzLmJyb3dzZXJQb29sLmNsZWFudXAoKTtcbiAgICAgIHRoaXMuYnJvd3NlclBvb2wgPSBudWxsO1xuICAgICAgdGhpcy51c2VQb29sID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVQdXBwZXRlZXJFcnJvcihlcnJvcjogRXJyb3IsIG9wZXJhdGlvbk5hbWU6IHN0cmluZyk6IFhIU0Vycm9yIHtcbiAgICBjb25zdCBjb250ZXh0ID0geyBvcGVyYXRpb25OYW1lIH07XG5cbiAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ1RpbWVvdXRFcnJvcicpIHtcbiAgICAgIGlmIChvcGVyYXRpb25OYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2xvZ2luJykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBYSFNFcnJvcihcbiAgICAgICAgICBgTG9naW4gb3BlcmF0aW9uIHRpbWVkIG91dCBkdXJpbmcgJHtvcGVyYXRpb25OYW1lfWAsXG4gICAgICAgICAgJ0xvZ2luVGltZW91dEVycm9yJyxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIGVycm9yXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IFhIU0Vycm9yKFxuICAgICAgICAgIGBCcm93c2VyIG9wZXJhdGlvbiB0aW1lZCBvdXQ6ICR7b3BlcmF0aW9uTmFtZX1gLFxuICAgICAgICAgICdCcm93c2VyRXJyb3InLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgZXJyb3JcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGVycm9yLm1lc3NhZ2UudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnbmF2aWdhdGlvbicpKSB7XG4gICAgICAgIHJldHVybiBuZXcgQnJvd3Nlck5hdmlnYXRpb25FcnJvcihcbiAgICAgICAgICBgTmF2aWdhdGlvbiBmYWlsZWQgZHVyaW5nICR7b3BlcmF0aW9uTmFtZX06ICR7ZXJyb3IubWVzc2FnZX1gLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgZXJyb3JcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgWEhTRXJyb3IoXG4gICAgICAgICAgYEJyb3dzZXIgZXJyb3IgZHVyaW5nICR7b3BlcmF0aW9uTmFtZX06ICR7ZXJyb3IubWVzc2FnZX1gLFxuICAgICAgICAgICdCcm93c2VyRXJyb3InLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgZXJyb3JcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gR2xvYmFsIGJyb3dzZXIgbWFuYWdlciBpbnN0YW5jZVxubGV0IGdsb2JhbEJyb3dzZXJNYW5hZ2VyOiBCcm93c2VyTWFuYWdlciB8IG51bGwgPSBudWxsO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QnJvd3Nlck1hbmFnZXIodXNlUG9vbDogYm9vbGVhbiA9IGZhbHNlKTogQnJvd3Nlck1hbmFnZXIge1xuICBpZiAoIWdsb2JhbEJyb3dzZXJNYW5hZ2VyKSB7XG4gICAgZ2xvYmFsQnJvd3Nlck1hbmFnZXIgPSBuZXcgQnJvd3Nlck1hbmFnZXIodW5kZWZpbmVkLCB1c2VQb29sKTtcbiAgfVxuICByZXR1cm4gZ2xvYmFsQnJvd3Nlck1hbmFnZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQb29sZWRCcm93c2VyTWFuYWdlcigpOiBCcm93c2VyTWFuYWdlciB7XG4gIHJldHVybiBnZXRCcm93c2VyTWFuYWdlcih0cnVlKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsZWFudXBHbG9iYWxCcm93c2VyTWFuYWdlcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKGdsb2JhbEJyb3dzZXJNYW5hZ2VyKSB7XG4gICAgYXdhaXQgZ2xvYmFsQnJvd3Nlck1hbmFnZXIuY2xlYW51cCgpO1xuICAgIGdsb2JhbEJyb3dzZXJNYW5hZ2VyID0gbnVsbDtcbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3977\n\n}");
81
+
82
+ /***/ }),
83
+
84
+ /***/ 4760:
85
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
86
+
87
+ eval("{/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ O4: () => (/* binding */ loadCookies),\n/* harmony export */ XM: () => (/* binding */ saveCookies),\n/* harmony export */ ZR: () => (/* binding */ deleteCookiesFile),\n/* harmony export */ mL: () => (/* binding */ getCookiesInfo)\n/* harmony export */ });\n/* unused harmony export getCookiesFilePath */\n/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7636);\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2207);\n/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9896);\n/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6928);\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9135);\n/**\n * Cookie management for XHS MCP Server\n */\n\n\n\n\n\nfunction getCookiesFilePath() {\n return (0,_config__WEBPACK_IMPORTED_MODULE_1__/* .getConfig */ .zj)().paths.cookiesFile;\n}\nfunction loadCookies() {\n const path = getCookiesFilePath();\n if (!(0,fs__WEBPACK_IMPORTED_MODULE_2__.existsSync)(path)) {\n return null;\n }\n try {\n const content = (0,fs__WEBPACK_IMPORTED_MODULE_2__.readFileSync)(path, 'utf-8');\n const cookies = JSON.parse(content);\n return cookies;\n }\n catch (error) {\n if (error instanceof SyntaxError) {\n _logger__WEBPACK_IMPORTED_MODULE_4__/* .logger */ .v.error(`Invalid JSON in cookies file ${path}: ${error.message}`);\n }\n else {\n _logger__WEBPACK_IMPORTED_MODULE_4__/* .logger */ .v.error(`Failed to read cookies from ${path}: ${error}`);\n }\n return null;\n }\n}\nfunction saveCookies(cookies) {\n if (!cookies || cookies.length === 0) {\n return;\n }\n const path = getCookiesFilePath();\n try {\n // Ensure parent directory exists\n const dir = (0,path__WEBPACK_IMPORTED_MODULE_3__.dirname)(path);\n (0,fs__WEBPACK_IMPORTED_MODULE_2__.mkdirSync)(dir, { recursive: true });\n // Save cookies with pretty formatting\n const content = JSON.stringify(cookies, null, 2);\n (0,fs__WEBPACK_IMPORTED_MODULE_2__.writeFileSync)(path, content, 'utf-8');\n }\n catch (error) {\n _logger__WEBPACK_IMPORTED_MODULE_4__/* .logger */ .v.error(`Failed to save cookies to ${path}: ${error}`);\n throw new _errors__WEBPACK_IMPORTED_MODULE_0__/* .XHSError */ .a_(`Failed to save cookies: ${error}`, 'CookieSaveError', {}, error);\n }\n}\nfunction deleteCookiesFile() {\n const path = getCookiesFilePath();\n if (!(0,fs__WEBPACK_IMPORTED_MODULE_2__.existsSync)(path)) {\n return true;\n }\n try {\n (0,fs__WEBPACK_IMPORTED_MODULE_2__.unlinkSync)(path);\n return true;\n }\n catch (error) {\n _logger__WEBPACK_IMPORTED_MODULE_4__/* .logger */ .v.error(`Failed to delete cookies file ${path}: ${error}`);\n return false;\n }\n}\nfunction getCookiesInfo() {\n const path = getCookiesFilePath();\n const cookies = loadCookies();\n let lastModified;\n if ((0,fs__WEBPACK_IMPORTED_MODULE_2__.existsSync)(path)) {\n const stats = (0,fs__WEBPACK_IMPORTED_MODULE_2__.statSync)(path);\n lastModified = stats.mtime.getTime();\n }\n return {\n filePath: path,\n fileExists: (0,fs__WEBPACK_IMPORTED_MODULE_2__.existsSync)(path),\n cookieCount: cookies ? cookies.length : 0,\n lastModified,\n };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QWdDLENBQUM7SUFDckMsSUFBSSw4Q0FBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDckIsTUFBTSxLQUFLLEdBQUcsNENBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QixZQUFZLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUN2QyxDQUFDO0lBRUQsT0FBTztRQUNMLFFBQVEsRUFBRSxJQUFJO1FBQ2QsVUFBVSxFQUFFLDhDQUFVLENBQUMsSUFBSSxDQUFDO1FBQzVCLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekMsWUFBWTtLQUNiLENBQUM7QUFDSixDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQvY29va2llcy50cz9mMTExIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29va2llIG1hbmFnZW1lbnQgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuaW1wb3J0IHsgQ29va2llLCBDb29raWVzSW5mbyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgWEhTRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgeyByZWFkRmlsZVN5bmMsIHdyaXRlRmlsZVN5bmMsIGV4aXN0c1N5bmMsIHVubGlua1N5bmMsIHN0YXRTeW5jLCBta2RpclN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBkaXJuYW1lIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb29raWVzRmlsZVBhdGgoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGdldENvbmZpZygpLnBhdGhzLmNvb2tpZXNGaWxlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9hZENvb2tpZXMoKTogQ29va2llW10gfCBudWxsIHtcbiAgY29uc3QgcGF0aCA9IGdldENvb2tpZXNGaWxlUGF0aCgpO1xuXG4gIGlmICghZXhpc3RzU3luYyhwYXRoKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBjb250ZW50ID0gcmVhZEZpbGVTeW5jKHBhdGgsICd1dGYtOCcpO1xuICAgIGNvbnN0IGNvb2tpZXMgPSBKU09OLnBhcnNlKGNvbnRlbnQpIGFzIENvb2tpZVtdO1xuICAgIHJldHVybiBjb29raWVzO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFN5bnRheEVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEludmFsaWQgSlNPTiBpbiBjb29raWVzIGZpbGUgJHtwYXRofTogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byByZWFkIGNvb2tpZXMgZnJvbSAke3BhdGh9OiAke2Vycm9yfWApO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2F2ZUNvb2tpZXMoY29va2llczogQ29va2llW10pOiB2b2lkIHtcbiAgaWYgKCFjb29raWVzIHx8IGNvb2tpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgcGF0aCA9IGdldENvb2tpZXNGaWxlUGF0aCgpO1xuXG4gIHRyeSB7XG4gICAgLy8gRW5zdXJlIHBhcmVudCBkaXJlY3RvcnkgZXhpc3RzXG4gICAgY29uc3QgZGlyID0gZGlybmFtZShwYXRoKTtcbiAgICBta2RpclN5bmMoZGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICAgIC8vIFNhdmUgY29va2llcyB3aXRoIHByZXR0eSBmb3JtYXR0aW5nXG4gICAgY29uc3QgY29udGVudCA9IEpTT04uc3RyaW5naWZ5KGNvb2tpZXMsIG51bGwsIDIpO1xuICAgIHdyaXRlRmlsZVN5bmMocGF0aCwgY29udGVudCwgJ3V0Zi04Jyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc2F2ZSBjb29raWVzIHRvICR7cGF0aH06ICR7ZXJyb3J9YCk7XG4gICAgdGhyb3cgbmV3IFhIU0Vycm9yKGBGYWlsZWQgdG8gc2F2ZSBjb29raWVzOiAke2Vycm9yfWAsICdDb29raWVTYXZlRXJyb3InLCB7fSwgZXJyb3IgYXMgRXJyb3IpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVDb29raWVzRmlsZSgpOiBib29sZWFuIHtcbiAgY29uc3QgcGF0aCA9IGdldENvb2tpZXNGaWxlUGF0aCgpO1xuXG4gIGlmICghZXhpc3RzU3luYyhwYXRoKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgdHJ5IHtcbiAgICB1bmxpbmtTeW5jKHBhdGgpO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBjb29raWVzIGZpbGUgJHtwYXRofTogJHtlcnJvcn1gKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvb2tpZXNJbmZvKCk6IENvb2tpZXNJbmZvIHtcbiAgY29uc3QgcGF0aCA9IGdldENvb2tpZXNGaWxlUGF0aCgpO1xuICBjb25zdCBjb29raWVzID0gbG9hZENvb2tpZXMoKTtcblxuICBsZXQgbGFzdE1vZGlmaWVkOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGlmIChleGlzdHNTeW5jKHBhdGgpKSB7XG4gICAgY29uc3Qgc3RhdHMgPSBzdGF0U3luYyhwYXRoKTtcbiAgICBsYXN0TW9kaWZpZWQgPSBzdGF0cy5tdGltZS5nZXRUaW1lKCk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGZpbGVQYXRoOiBwYXRoLFxuICAgIGZpbGVFeGlzdHM6IGV4aXN0c1N5bmMocGF0aCksXG4gICAgY29va2llQ291bnQ6IGNvb2tpZXMgPyBjb29raWVzLmxlbmd0aCA6IDAsXG4gICAgbGFzdE1vZGlmaWVkLFxuICB9O1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4760\n\n}");
88
+
89
+ /***/ }),
90
+
91
+ /***/ 5582:
92
+ /***/ ((__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) => {
93
+
94
+ eval("{\n;// external \"commander\"\nconst external_commander_namespaceObject = require(\"commander\");\n// EXTERNAL MODULE: ./src/shared/config.ts + 1 modules\nvar shared_config = __webpack_require__(2207);\n// EXTERNAL MODULE: ./src/shared/errors.ts\nvar shared_errors = __webpack_require__(7636);\n// EXTERNAL MODULE: ./src/shared/base.service.ts\nvar base_service = __webpack_require__(103);\n// EXTERNAL MODULE: ./src/shared/cookies.ts\nvar cookies = __webpack_require__(4760);\n// EXTERNAL MODULE: ./src/shared/logger.ts\nvar logger = __webpack_require__(9135);\n;// ./src/shared/xhs.utils.ts\n/**\n * Utility functions for XHS operations\n */\n\nconst XHS_HOME_URL = 'https://www.xiaohongshu.com';\nconst XHS_EXPLORE_URL = `${XHS_HOME_URL}/explore`;\nconst XHS_SEARCH_URL = `${XHS_HOME_URL}/search_result`;\nconst XHS_CREATOR_PUBLISH_URL = 'https://creator.xiaohongshu.com/publish/publish?source=official';\nconst LOGIN_OK_SELECTOR = '.main-container .user .link-wrapper .channel';\nfunction makeSearchUrl(keyword) {\n const params = new URLSearchParams({\n keyword,\n source: 'web_explore_feed',\n });\n return `${XHS_SEARCH_URL}?${params.toString()}`;\n}\nfunction makeFeedDetailUrl(feedId, xsecToken) {\n const params = new URLSearchParams({\n xsec_token: xsecToken,\n xsec_source: 'pc_feed',\n });\n return `${XHS_EXPLORE_URL}/${feedId}?${params.toString()}`;\n}\nasync function extractInitialState(page) {\n try {\n // Wait for page to be fully loaded - Puppeteer doesn't have waitForLoadState\n // We'll just wait a bit for the page to settle\n await new Promise((resolve) => globalThis.setTimeout(resolve, 1000));\n }\n catch {\n // Ignore load state errors\n }\n try {\n const result = await page.evaluate(`\n (() => {\n // Try multiple possible state objects\n const possibleStates = [\n window.__INITIAL_STATE__,\n window.__INITIAL_SSR_STATE__,\n window.__NEXT_DATA__,\n window.__NUXT__,\n window.__VUE__,\n window.__REACT_QUERY_STATE__\n ];\n\n for (const state of possibleStates) {\n if (state && typeof state === 'object') {\n try {\n // Use a more robust JSON serialization that handles circular references\n const seen = new WeakSet();\n return JSON.stringify(state, (key, val) => {\n if (val != null && typeof val === \"object\") {\n if (seen.has(val)) {\n return \"[Circular]\";\n }\n seen.add(val);\n }\n return val;\n });\n } catch (e) {\n logger.warn('JSON.stringify failed for state:', e.message);\n continue;\n }\n }\n }\n\n // If no state found, try to find any global state\n const globalKeys = Object.keys(window).filter(key =>\n key.includes('STATE') || key.includes('DATA') || key.includes('INITIAL')\n );\n\n for (const key of globalKeys) {\n const value = window[key];\n if (value && typeof value === 'object') {\n try {\n const seen = new WeakSet();\n return JSON.stringify(value, (key, val) => {\n if (val != null && typeof val === \"object\") {\n if (seen.has(val)) {\n return \"[Circular]\";\n }\n seen.add(val);\n }\n return val;\n });\n } catch (e) {\n logger.warn('JSON.stringify failed for global key:', key, e.message);\n continue;\n }\n }\n }\n\n return '';\n })()\n `);\n if (!result) {\n return null;\n }\n return JSON.parse(result);\n }\n catch {\n return null;\n }\n}\nasync function isLoggedIn(page) {\n try {\n const elements = await page.$$(LOGIN_OK_SELECTOR);\n return elements.length > 0;\n }\n catch {\n return false;\n }\n}\nasync function getLoginStatusWithProfile(page) {\n try {\n // First check if logged in using the existing method\n const elements = await page.$$(LOGIN_OK_SELECTOR);\n const isLoggedIn = elements.length > 0;\n if (!isLoggedIn) {\n return { isLoggedIn: false };\n }\n // If logged in, try to extract profile information from current page\n let profileData = {};\n try {\n profileData = await page.evaluate(() => {\n const profile = {};\n // Extract user ID from URL if on profile page\n // eslint-disable-next-line no-undef\n const urlMatch = window.location.href.match(/\\/user\\/profile\\/([a-f0-9]+)/);\n if (urlMatch) {\n profile.userId = urlMatch[1];\n }\n // Try to find user nickname\n // eslint-disable-next-line no-undef\n const nameElement = document.querySelector('.user-name, [class*=\"user-name\"], [class*=\"nickname\"]');\n if (nameElement) {\n profile.nickname = nameElement.textContent?.trim();\n }\n // Try to find user info text that might contain stats\n // eslint-disable-next-line no-undef\n const infoElement = document.querySelector('.user-info, [class*=\"user-info\"]');\n if (infoElement) {\n const infoText = infoElement.textContent || '';\n profile.infoText = infoText;\n // Try to extract numbers from the info text (followers, following, likes)\n const numbers = infoText.match(/\\d+/g);\n if (numbers && numbers.length >= 3) {\n // Common pattern: followers, following, likes\n profile.following = parseInt(numbers[0]) || 0;\n profile.followers = parseInt(numbers[1]) || 0;\n profile.likes = parseInt(numbers[2]) || 0;\n }\n // Extract 小红书号 (XHS number)\n const xhsMatch = infoText.match(/小红书号:(\\d+)/);\n if (xhsMatch) {\n profile.xhsNumber = xhsMatch[1];\n }\n // Extract IP属地 (IP location)\n const ipMatch = infoText.match(/IP属地:([^0-9]+)/);\n if (ipMatch) {\n profile.ipLocation = ipMatch[1].trim();\n }\n }\n // Try to find avatar\n // eslint-disable-next-line no-undef\n const avatarElement = document.querySelector('img[class*=\"avatar\"], img[class*=\"profile\"], .avatar img, .profile img');\n if (avatarElement) {\n profile.avatar = avatarElement.src;\n }\n return profile;\n });\n }\n catch {\n logger/* logger */.v.error('Error in page.evaluate');\n profileData = {};\n }\n return {\n isLoggedIn: true,\n profile: Object.keys(profileData).length > 0 ? profileData : undefined,\n };\n }\n catch {\n // If there's an error, fall back to basic login check\n try {\n const elements = await page.$$(LOGIN_OK_SELECTOR);\n return { isLoggedIn: elements.length > 0 };\n }\n catch {\n return { isLoggedIn: false };\n }\n }\n}\n\n// EXTERNAL MODULE: ./src/shared/utils.ts\nvar utils = __webpack_require__(2094);\n;// ./src/core/auth/auth.service.ts\n/**\n * Authentication service for XHS MCP Server\n */\n\n\n\n\n\n\nclass AuthService extends base_service/* BaseService */.d {\n constructor(config, browserManager) {\n super(config, browserManager);\n }\n /**\n * Extract profile URL and user ID from the current page\n */\n async extractProfileFromPage(page) {\n try {\n const profileUrl = await page.evaluate(() => {\n const userLinks = Array.from(document.querySelectorAll('a[href*=\"/user/profile/\"]'));\n const currentUserLink = userLinks.find((link) => {\n const text = link.textContent?.trim();\n return (text === '我' ||\n (text && text.includes('profile')) ||\n (text && text.includes('用户')));\n });\n return currentUserLink ? currentUserLink.href : null;\n });\n if (profileUrl) {\n const userIdMatch = profileUrl.match(/\\/user\\/profile\\/([a-f0-9]+)/);\n if (userIdMatch) {\n return { userId: userIdMatch[1], profileUrl };\n }\n }\n }\n catch (profileError) {\n logger/* logger */.v.warn('Failed to get profile information:', profileError);\n }\n return undefined;\n }\n async login(browserPath, timeout = 300) {\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n // Navigate to explore page\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.exploreUrl);\n // Check if already logged in\n if (await isLoggedIn(page)) {\n let profile = undefined;\n try {\n const extracted = await this.extractProfileFromPage(page);\n const loginStatus = await getLoginStatusWithProfile(page);\n profile = { ...extracted, ...loginStatus.profile };\n }\n catch (profileError) {\n logger/* logger */.v.warn('Failed to get profile information:', profileError);\n }\n return {\n success: true,\n message: 'Already logged in',\n status: 'logged_in',\n action: 'none',\n profile,\n };\n }\n // Wait for login completion\n const checkInterval = 5;\n const maxChecks = timeout / checkInterval;\n for (let checkCount = 0; checkCount < maxChecks; checkCount++) {\n try {\n await page.waitForSelector(this.getConfig().xhs.loginOkSelector, {\n timeout: checkInterval * 1000,\n });\n break;\n }\n catch (error) {\n const elapsed = (checkCount + 1) * checkInterval;\n if (checkCount === maxChecks - 1) {\n throw new shared_errors/* LoginTimeoutError */.H7(`Login timed out after ${timeout} seconds. Please complete QR code scanning or manual login in the browser window.`, {\n timeout,\n url: this.getConfig().xhs.exploreUrl,\n elapsedTime: elapsed,\n suggestion: 'Increase timeout parameter or complete login faster',\n });\n }\n }\n }\n // Save cookies after successful login\n await this.getBrowserManager().saveCookiesFromPage(page);\n // Verify login success and get profile information\n await (0,utils/* sleep */.yy)(1000);\n const loginStatus = await getLoginStatusWithProfile(page);\n if (loginStatus.isLoggedIn) {\n let profile = loginStatus.profile;\n try {\n const extracted = await this.extractProfileFromPage(page);\n if (extracted) {\n profile = { ...profile, ...extracted };\n }\n }\n catch (profileError) {\n logger/* logger */.v.warn('Failed to get additional profile information:', profileError);\n }\n return {\n success: true,\n message: 'Login successful',\n status: 'logged_in',\n action: 'logged_in',\n profile,\n };\n }\n else {\n throw new shared_errors/* LoginFailedError */.f6('Login process completed but authentication verification failed');\n }\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* LoginTimeoutError */.H7 || error instanceof shared_errors/* LoginFailedError */.f6) {\n throw error;\n }\n logger/* logger */.v.error(`Login failed with unexpected error: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Login failed: ${error}`, 'LoginError', { timeout }, error);\n }\n }\n async logout() {\n try {\n const success = (0,cookies/* deleteCookiesFile */.ZR)();\n if (success) {\n return {\n success: true,\n message: 'Logged out successfully (cookies deleted)',\n status: 'logged_out',\n action: 'logged_out',\n };\n }\n else {\n return {\n success: false,\n message: 'Failed to delete cookies file',\n status: 'logged_out',\n action: 'none',\n };\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Logout failed: ${error}`);\n return {\n success: false,\n message: `Logout failed: ${error}`,\n status: 'logged_out',\n action: 'none',\n };\n }\n }\n async checkStatus(browserPath) {\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.exploreUrl);\n await (0,utils/* sleep */.yy)(1000);\n const loggedIn = await isLoggedIn(page);\n if (!loggedIn) {\n return {\n success: true,\n loggedIn: false,\n status: 'logged_out',\n urlChecked: this.getConfig().xhs.exploreUrl,\n };\n }\n const profile = await this.extractProfileFromPage(page);\n return {\n success: true,\n loggedIn: true,\n status: 'logged_in',\n urlChecked: this.getConfig().xhs.exploreUrl,\n profile,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Status check failed: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Status check failed: ${error}`, 'StatusCheckError', {}, error);\n }\n }\n}\n\n// EXTERNAL MODULE: external \"puppeteer\"\nvar external_puppeteer_ = __webpack_require__(9916);\nvar external_puppeteer_default = /*#__PURE__*/__webpack_require__.n(external_puppeteer_);\n;// external \"node:child_process\"\nconst external_node_child_process_namespaceObject = require(\"node:child_process\");\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js + 1 modules\nvar esm_server = __webpack_require__(2028);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js + 1 modules\nvar stdio = __webpack_require__(7862);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/types.js + 7 modules\nvar types = __webpack_require__(2780);\n;// ./src/core/feeds/feed.service.ts\n/**\n * Feed operations service for XHS MCP Server\n */\n\n\n\n\n\nclass FeedService extends base_service/* BaseService */.d {\n constructor(config, browserManager) {\n super(config, browserManager);\n }\n async getFeedList(browserPath) {\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.homeUrl);\n await (0,utils/* sleep */.yy)(1000);\n // Check if logged in\n if (!(await isLoggedIn(page))) {\n throw new shared_errors/* NotLoggedInError */.bG('Must be logged in to access feed list', {\n operation: 'get_feed_list',\n });\n }\n // Extract feed data using a more targeted approach\n let feedData = null;\n let attempts = 0;\n const maxAttempts = 10;\n while (attempts < maxAttempts && !feedData) {\n await (0,utils/* sleep */.yy)(2000); // Wait 2 seconds between attempts\n attempts++;\n feedData = (await page.evaluate(`\n (() => {\n if (window.__INITIAL_STATE__ && window.__INITIAL_STATE__.feed && window.__INITIAL_STATE__.feed.feeds && window.__INITIAL_STATE__.feed.feeds._value) {\n try {\n // Try to serialize just the feeds data to avoid circular reference issues\n const feedsData = window.__INITIAL_STATE__.feed.feeds._value;\n return JSON.stringify(feedsData);\n } catch (e) {\n logger.warn('Failed to serialize feeds data:', e.message);\n return null;\n }\n }\n return null;\n })()\n `));\n if (feedData) {\n logger/* logger */.v.info(`Feed results loaded after ${attempts} attempts`);\n break;\n }\n }\n if (!feedData) {\n throw new shared_errors/* FeedParsingError */.TG(`Could not extract feed data after ${maxAttempts} attempts. The page may not be fully loaded or the state structure has changed.`, {\n url: this.getConfig().xhs.homeUrl,\n suggestion: 'Try logging in first using xhs_auth_login tool',\n });\n }\n const feedsValue = JSON.parse(feedData);\n return {\n success: true,\n feeds: feedsValue,\n count: feedsValue.length,\n source: 'home_page',\n url: this.getConfig().xhs.homeUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* NotLoggedInError */.bG || error instanceof shared_errors/* FeedParsingError */.TG) {\n throw error;\n }\n logger/* logger */.v.error(`Failed to get feed list: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Failed to get feed list: ${error}`, 'GetFeedListError', {}, error);\n }\n }\n async searchFeeds(keyword, browserPath) {\n if (!keyword || !keyword.trim()) {\n throw new shared_errors/* FeedError */.lS('Search keyword cannot be empty');\n }\n const trimmedKeyword = keyword.trim();\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n const searchUrl = makeSearchUrl(trimmedKeyword);\n await this.getBrowserManager().navigateWithRetry(page, searchUrl);\n // Wait for search results to load with multiple attempts\n let searchData = null;\n let attempts = 0;\n const maxAttempts = 10;\n while (attempts < maxAttempts && !searchData) {\n await (0,utils/* sleep */.yy)(2000); // Wait 2 seconds between attempts\n attempts++;\n searchData = (await page.evaluate(`\n (() => {\n if (window.__INITIAL_STATE__ && window.__INITIAL_STATE__.search && window.__INITIAL_STATE__.search.feeds && window.__INITIAL_STATE__.search.feeds._value) {\n try {\n // Try to serialize just the feeds data to avoid circular reference issues\n const feedsData = window.__INITIAL_STATE__.search.feeds._value;\n return JSON.stringify(feedsData);\n } catch (e) {\n logger.warn('Failed to serialize feeds data:', e.message);\n return null;\n }\n }\n return null;\n })()\n `));\n if (searchData) {\n logger/* logger */.v.info(`Search results loaded after ${attempts} attempts`);\n break;\n }\n }\n if (!searchData) {\n throw new shared_errors/* FeedParsingError */.TG(`Could not extract search results for keyword: ${trimmedKeyword} after ${maxAttempts} attempts`, {\n keyword: trimmedKeyword,\n url: searchUrl,\n });\n }\n const feedsValue = JSON.parse(searchData);\n return {\n success: true,\n keyword: trimmedKeyword,\n feeds: feedsValue,\n count: feedsValue.length,\n searchUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* FeedError */.lS) {\n throw error;\n }\n logger/* logger */.v.error(`Feed search failed for keyword '${trimmedKeyword}': ${error}`);\n throw new shared_errors/* XHSError */.a_(`Feed search failed: ${error}`, 'SearchFeedsError', { keyword: trimmedKeyword }, error);\n }\n }\n async getFeedDetail(feedId, xsecToken, browserPath) {\n if (!feedId || !xsecToken) {\n throw new shared_errors/* FeedError */.lS('Both feed_id and xsec_token are required');\n }\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n const detailUrl = makeFeedDetailUrl(feedId, xsecToken);\n await this.getBrowserManager().navigateWithRetry(page, detailUrl);\n await (0,utils/* sleep */.yy)(1000);\n const state = await extractInitialState(page);\n const noteData = state?.note;\n if (!state || !noteData || !noteData.noteDetailMap) {\n throw new shared_errors/* FeedParsingError */.TG(`Could not extract note details for feed: ${feedId}`, {\n feedId,\n url: detailUrl,\n });\n }\n const noteDetailMap = noteData.noteDetailMap;\n if (!(feedId in noteDetailMap)) {\n throw new shared_errors/* FeedNotFoundError */.aW(`Feed ${feedId} not found in note details`, {\n feedId,\n availableFeeds: Object.keys(noteDetailMap),\n });\n }\n const detail = noteDetailMap[feedId];\n return {\n success: true,\n feedId,\n detail,\n url: detailUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* FeedError */.lS ||\n error instanceof shared_errors/* FeedNotFoundError */.aW ||\n error instanceof shared_errors/* FeedParsingError */.TG) {\n throw error;\n }\n logger/* logger */.v.error(`Failed to get feed detail for ${feedId}: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Failed to get feed detail: ${error}`, 'GetFeedDetailError', { feedId }, error);\n }\n }\n async commentOnFeed(feedId, xsecToken, note, browserPath) {\n if (!feedId || !xsecToken || !note) {\n throw new shared_errors/* FeedError */.lS('feed_id, xsec_token, and note are all required');\n }\n if (note.trim().length === 0) {\n throw new shared_errors/* FeedError */.lS('Comment note cannot be empty');\n }\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n const detailUrl = makeFeedDetailUrl(feedId, xsecToken);\n await this.getBrowserManager().navigateWithRetry(page, detailUrl);\n await (0,utils/* sleep */.yy)(1000);\n // Check if logged in\n if (!(await isLoggedIn(page))) {\n throw new shared_errors/* NotLoggedInError */.bG('Must be logged in to comment on feeds', {\n operation: 'comment_on_feed',\n feedId,\n });\n }\n // Click on comment input\n const commentInputSelector = 'div.input-box div.content-edit span';\n if (!(await this.getBrowserManager().tryWaitForSelector(page, commentInputSelector))) {\n throw new shared_errors/* FeedError */.lS('Comment input not found on page', {\n feedId,\n selector: commentInputSelector,\n });\n }\n const commentInput = await page.$(commentInputSelector);\n if (commentInput) {\n await commentInput.click();\n }\n // Fill comment note\n const editorSelector = 'div.input-box div.content-edit p.content-input';\n const editor = await page.$(editorSelector);\n if (editor) {\n await editor.click();\n await editor.type(note, { delay: 30 });\n }\n await (0,utils/* sleep */.yy)(1000);\n // Submit comment\n const submitSelector = 'div.bottom button.submit';\n const submitButton = await page.$(submitSelector);\n if (submitButton) {\n await submitButton.click();\n }\n await (0,utils/* sleep */.yy)(2000); // Wait for submission\n return {\n success: true,\n message: 'Comment submitted successfully',\n feedId,\n note,\n url: detailUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* FeedError */.lS || error instanceof shared_errors/* NotLoggedInError */.bG) {\n throw error;\n }\n logger/* logger */.v.error(`Failed to comment on feed ${feedId}: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Failed to comment on feed: ${error}`, 'CommentOnFeedError', { feedId }, error);\n }\n }\n}\n\n// EXTERNAL MODULE: ./node_modules/string-width/index.js + 4 modules\nvar string_width = __webpack_require__(6904);\n;// ./src/shared/title-validator.ts\n/**\n * Title validation utility for XHS MCP Server\n * Validates title width according to XiaoHongShu's display width rules\n *\n * XHS Rules:\n * - Max width: 40 units\n * - CJK characters (Chinese/Japanese/Korean): 2 units each\n * - Other characters (English/Numbers): 1 unit each\n */\n\n\n/**\n * XiaoHongShu title constraints\n */\nconst XHS_TITLE_CONSTRAINTS = {\n MAX_WIDTH: 40, // Maximum display width in units\n MAX_LENGTH: 20, // Approximate max character count (for reference)\n};\n/**\n * Validate title width according to XHS display rules\n *\n * @param title - The title to validate\n * @returns Validation result with width information\n *\n * @example\n * ```typescript\n * const result = validateTitleWidth('Hello世界');\n * console.log(result.width); // 10 (5 + 2*2 + 1 = 10)\n * console.log(result.valid); // true\n * ```\n */\nfunction validateTitleWidth(title) {\n if (!title) {\n return {\n valid: false,\n width: 0,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n message: 'Title cannot be empty',\n suggestion: 'Please provide a valid title',\n };\n }\n // Calculate display width using string-width\n // This correctly handles CJK characters, emoji, and other Unicode\n const width = (0,string_width/* default */.A)(title);\n if (width > XHS_TITLE_CONSTRAINTS.MAX_WIDTH) {\n return {\n valid: false,\n width,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n message: `Title width exceeds limit: ${width} units (max: ${XHS_TITLE_CONSTRAINTS.MAX_WIDTH} units)`,\n suggestion: `Current title is too long. CJK characters count as 2 units, English/numbers as 1 unit. Please shorten your title.`,\n };\n }\n return {\n valid: true,\n width,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n };\n}\n/**\n * Validate and throw error if title width is invalid\n *\n * @param title - The title to validate\n * @throws PublishError if title width is invalid\n *\n * @example\n * ```typescript\n * try {\n * assertTitleWidthValid('很长很长的标题'.repeat(10));\n * } catch (error) {\n * console.error(error.message);\n * }\n * ```\n */\nfunction assertTitleWidthValid(title) {\n const result = validateTitleWidth(title);\n if (!result.valid) {\n throw new shared_errors/* PublishError */.S1(result.message, {\n title,\n width: result.width,\n maxWidth: result.maxWidth,\n suggestion: result.suggestion,\n details: {\n titleLength: title.length,\n displayWidth: result.width,\n maxDisplayWidth: result.maxWidth,\n exceeded: result.width - result.maxWidth,\n },\n });\n }\n}\n/**\n * Get the display width of a title\n *\n * @param title - The title to measure\n * @returns Display width in units\n *\n * @example\n * ```typescript\n * console.log(getTitleWidth('Hello')); // 5\n * console.log(getTitleWidth('你好')); // 4 (2*2)\n * console.log(getTitleWidth('Hello世界')); // 10 (5 + 2*2 + 1)\n * console.log(getTitleWidth('👋Hello')); // 7 (2 + 5)\n * ```\n */\nfunction getTitleWidth(title) {\n return (0,string_width/* default */.A)(title);\n}\n/**\n * Calculate how many characters can be added to the title\n *\n * @param title - Current title\n * @returns Remaining width units available\n *\n * @example\n * ```typescript\n * const remaining = getRemainingTitleWidth('Hello'); // 35\n * console.log(`You can add ${remaining} more units`);\n * ```\n */\nfunction calculateRemainingTitleWidth(title) {\n const currentWidth = getTitleWidth(title);\n return Math.max(0, XHS_TITLE_CONSTRAINTS.MAX_WIDTH - currentWidth);\n}\n/**\n * Truncate title to fit within width limit\n *\n * @param title - The title to truncate\n * @param maxWidth - Maximum width (default: XHS_TITLE_CONSTRAINTS.MAX_WIDTH)\n * @returns Truncated title that fits within width limit\n *\n * @example\n * ```typescript\n * const long = '这是一个很长很长的标题'.repeat(5);\n * const truncated = truncateTitleToWidth(long);\n * console.log(getTitleWidth(truncated)); // <= 40\n * ```\n */\nfunction truncateTitleToWidth(title, maxWidth = XHS_TITLE_CONSTRAINTS.MAX_WIDTH) {\n if (getTitleWidth(title) <= maxWidth) {\n return title;\n }\n let truncated = '';\n let currentWidth = 0;\n for (const char of title) {\n const charWidth = stringWidth(char);\n if (currentWidth + charWidth > maxWidth) {\n break;\n }\n truncated += char;\n currentWidth += charWidth;\n }\n return truncated;\n}\n/**\n * Get human-readable width breakdown\n * Useful for debugging and user feedback\n *\n * @param title - The title to analyze\n * @returns Width breakdown information\n */\nfunction getTitleWidthBreakdown(title) {\n const totalWidth = getTitleWidth(title);\n const breakdown = [];\n for (const char of title) {\n const charWidth = stringWidth(char);\n let type = 'Other';\n const code = char.charCodeAt(0);\n if (char.match(/[\\u4e00-\\u9fff\\u3400-\\u4dbf\\uf900-\\ufaff]/)) {\n type = 'CJK';\n }\n else if (code < 128) {\n type = 'ASCII';\n }\n else if (char.match(/[\\u{1F300}-\\u{1F9FF}]/u)) {\n type = 'Emoji';\n }\n breakdown.push({ char, width: charWidth, type });\n }\n return {\n title,\n totalWidth,\n totalChars: title.length,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n remaining: calculateRemainingTitleWidth(title),\n valid: totalWidth <= XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n breakdown,\n };\n}\n\n// EXTERNAL MODULE: external \"fs\"\nvar external_fs_ = __webpack_require__(9896);\n// EXTERNAL MODULE: external \"path\"\nvar external_path_ = __webpack_require__(6928);\n;// external \"crypto\"\nconst external_crypto_namespaceObject = require(\"crypto\");\n;// external \"node-fetch\"\nconst external_node_fetch_namespaceObject = require(\"node-fetch\");\nvar external_node_fetch_default = /*#__PURE__*/__webpack_require__.n(external_node_fetch_namespaceObject);\n;// ./src/shared/image-downloader.ts\n/**\n * Image downloader utility for XHS MCP Server\n * Supports downloading images from HTTP/HTTPS URLs\n */\n\n\n\n\n\n\nclass ImageDownloader {\n saveDir;\n timeout;\n maxFileSize;\n constructor(saveDir = './temp_images', timeout = 30000, maxFileSize = 10 * 1024 * 1024 // 10MB default\n ) {\n this.saveDir = saveDir;\n this.timeout = timeout;\n this.maxFileSize = maxFileSize;\n // Ensure save directory exists\n if (!(0,external_fs_.existsSync)(this.saveDir)) {\n (0,external_fs_.mkdirSync)(this.saveDir, { recursive: true });\n }\n }\n /**\n * Check if a string is a valid HTTP/HTTPS URL\n */\n static isImageUrl(path) {\n if (!path)\n return false;\n const lowerPath = path.toLowerCase().trim();\n return lowerPath.startsWith('http://') || lowerPath.startsWith('https://');\n }\n /**\n * Generate a unique filename for an image URL\n * Uses only URL hash for consistent caching\n */\n generateFileName(imageUrl) {\n // Use SHA256 hash of URL for uniqueness\n const hash = (0,external_crypto_namespaceObject.createHash)('sha256').update(imageUrl).digest('hex');\n const shortHash = hash.substring(0, 16);\n // Try to extract extension from URL\n let extension = 'jpg'; // default\n try {\n const url = new URL(imageUrl);\n const pathname = url.pathname.toLowerCase();\n const match = pathname.match(/\\.(jpg|jpeg|png|gif|webp|bmp)$/i);\n if (match) {\n extension = match[1];\n }\n }\n catch {\n // Use default extension\n }\n // Fixed filename for proper caching (no timestamp)\n return `img_${shortHash}.${extension}`;\n }\n /**\n * Validate that downloaded data is actually an image\n */\n validateImageData(buffer) {\n // Check file signatures (magic numbers)\n if (buffer.length < 12) {\n return { isValid: false, extension: '' };\n }\n // JPEG\n if (buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff) {\n return { isValid: true, extension: 'jpg' };\n }\n // PNG\n if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4e && buffer[3] === 0x47) {\n return { isValid: true, extension: 'png' };\n }\n // GIF\n if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46) {\n return { isValid: true, extension: 'gif' };\n }\n // WebP\n if (buffer[0] === 0x52 &&\n buffer[1] === 0x49 &&\n buffer[2] === 0x46 &&\n buffer[3] === 0x46 &&\n buffer[8] === 0x57 &&\n buffer[9] === 0x45 &&\n buffer[10] === 0x42 &&\n buffer[11] === 0x50) {\n return { isValid: true, extension: 'webp' };\n }\n // BMP\n if (buffer[0] === 0x42 && buffer[1] === 0x4d) {\n return { isValid: true, extension: 'bmp' };\n }\n return { isValid: false, extension: '' };\n }\n /**\n * Download a single image from URL\n */\n async downloadImage(imageUrl) {\n // Validate URL format\n if (!ImageDownloader.isImageUrl(imageUrl)) {\n throw new shared_errors/* InvalidImageError */.TD(`Invalid image URL format: ${imageUrl}`, {\n url: imageUrl,\n suggestion: 'URL must start with http:// or https://',\n });\n }\n // Generate filename and path\n const fileName = this.generateFileName(imageUrl);\n const localPath = (0,external_path_.join)(this.saveDir, fileName);\n // Check if file already exists (cache)\n if ((0,external_fs_.existsSync)(localPath)) {\n const stats = (0,external_fs_.statSync)(localPath);\n logger/* logger */.v.debug(`Using cached image: ${localPath}`);\n return {\n originalUrl: imageUrl,\n localPath,\n cached: true,\n fileSize: stats.size,\n };\n }\n logger/* logger */.v.debug(`Downloading image from: ${imageUrl}`);\n try {\n // Download image with timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n const response = await external_node_fetch_default()(imageUrl, {\n signal: controller.signal,\n headers: {\n 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',\n },\n });\n clearTimeout(timeoutId);\n if (!response.ok) {\n throw new shared_errors/* InvalidImageError */.TD(`Failed to download image: HTTP ${response.status} ${response.statusText}`, {\n url: imageUrl,\n statusCode: response.status,\n statusText: response.statusText,\n });\n }\n // Check Content-Length if available\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength) > this.maxFileSize) {\n throw new shared_errors/* InvalidImageError */.TD(`Image file too large: ${(parseInt(contentLength) / 1024 / 1024).toFixed(2)}MB (max: ${(this.maxFileSize / 1024 / 1024).toFixed(2)}MB)`, {\n url: imageUrl,\n fileSize: parseInt(contentLength),\n maxSize: this.maxFileSize,\n suggestion: 'Try using a smaller image or increase maxFileSize',\n });\n }\n // Get image data\n const arrayBuffer = await response.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n // Verify actual size\n if (buffer.length > this.maxFileSize) {\n throw new shared_errors/* InvalidImageError */.TD(`Downloaded file too large: ${(buffer.length / 1024 / 1024).toFixed(2)}MB (max: ${(this.maxFileSize /\n 1024 /\n 1024).toFixed(2)}MB)`, {\n url: imageUrl,\n fileSize: buffer.length,\n maxSize: this.maxFileSize,\n });\n }\n // Validate it's actually an image\n const validation = this.validateImageData(buffer);\n if (!validation.isValid) {\n throw new shared_errors/* InvalidImageError */.TD(`Downloaded file is not a valid image: ${imageUrl}`, {\n url: imageUrl,\n suggestion: 'Make sure the URL points to an actual image file',\n });\n }\n // Save to file\n (0,external_fs_.writeFileSync)(localPath, buffer);\n logger/* logger */.v.debug(`Image downloaded successfully: ${localPath} (${buffer.length} bytes)`);\n return {\n originalUrl: imageUrl,\n localPath,\n cached: false,\n fileSize: buffer.length,\n };\n }\n catch (error) {\n if (error instanceof shared_errors/* InvalidImageError */.TD) {\n throw error;\n }\n // Handle abort error\n if (error instanceof Error && error.name === 'AbortError') {\n throw new shared_errors/* InvalidImageError */.TD(`Image download timeout after ${this.timeout}ms: ${imageUrl}`, {\n url: imageUrl,\n timeout: this.timeout,\n suggestion: 'The image may be too large or the network is slow',\n }, error);\n }\n throw new shared_errors/* InvalidImageError */.TD(`Failed to download image: ${imageUrl}`, {\n url: imageUrl,\n }, error);\n }\n }\n /**\n * Download multiple images from URLs (parallel download for better performance)\n */\n async downloadImages(imageUrls) {\n // Download all images in parallel\n const downloadPromises = imageUrls.map((url) => this.downloadImage(url).catch((error) => ({ error, url })));\n const results = await Promise.all(downloadPromises);\n const successResults = [];\n const errors = [];\n results.forEach((result) => {\n if ('error' in result) {\n errors.push({ url: result.url, error: result.error });\n }\n else {\n successResults.push(result);\n }\n });\n // If any downloads failed, throw an error with details\n if (errors.length > 0) {\n const errorMessages = errors.map((e) => `${e.url}: ${e.error.message}`).join('\\n');\n throw new shared_errors/* InvalidImageError */.TD(`Failed to download ${errors.length} of ${imageUrls.length} images:\\n${errorMessages}`, {\n totalCount: imageUrls.length,\n failedCount: errors.length,\n successCount: successResults.length,\n failedUrls: errors.map((e) => e.url),\n });\n }\n return successResults;\n }\n /**\n * Process a list of image paths - download URLs and keep local paths as-is\n */\n async processImagePaths(imagePaths) {\n const localPaths = [];\n const urlsToDownload = [];\n // Separate URLs from local paths\n for (const path of imagePaths) {\n if (ImageDownloader.isImageUrl(path)) {\n urlsToDownload.push(path);\n }\n else {\n // Validate local path exists\n if (!(0,external_fs_.existsSync)(path)) {\n throw new shared_errors/* InvalidImageError */.TD(`Local image file not found: ${path}`, {\n path,\n suggestion: 'Make sure the file path is correct and the file exists',\n });\n }\n localPaths.push(path);\n }\n }\n // Download URLs if any\n if (urlsToDownload.length > 0) {\n logger/* logger */.v.debug(`Downloading ${urlsToDownload.length} images from URLs...`);\n const downloadResults = await this.downloadImages(urlsToDownload);\n const downloadedPaths = downloadResults.map((r) => r.localPath);\n localPaths.push(...downloadedPaths);\n // Log download summary\n const cachedCount = downloadResults.filter((r) => r.cached).length;\n const newCount = downloadResults.filter((r) => !r.cached).length;\n logger/* logger */.v.debug(`Downloaded ${newCount} new images, used ${cachedCount} cached images`);\n }\n if (localPaths.length === 0) {\n throw new shared_errors/* InvalidImageError */.TD('No valid images found', {\n providedPaths: imagePaths.length,\n suggestion: 'Provide at least one valid image URL or local file path',\n });\n }\n return localPaths;\n }\n /**\n * Get the save directory path\n */\n getSaveDir() {\n return this.saveDir;\n }\n}\n// Export a default instance\nlet defaultDownloader = null;\nfunction getImageDownloader(saveDir) {\n if (!defaultDownloader || (saveDir && defaultDownloader.getSaveDir() !== saveDir)) {\n defaultDownloader = new ImageDownloader(saveDir);\n }\n return defaultDownloader;\n}\n\n// EXTERNAL MODULE: ./src/shared/selectors.ts\nvar selectors = __webpack_require__(805);\n;// ./src/core/publishing/publish-base.service.ts\n/**\n * Publishing service for XHS MCP Server\n */\n\n\n\n\n\n\n// Constants for video publishing\nconst VIDEO_TIMEOUTS = {\n PAGE_LOAD: 3000,\n TAB_SWITCH: 2000,\n VIDEO_PROCESSING: 10000,\n CONTENT_WAIT: 1000,\n UPLOAD_READY: 1000,\n UPLOAD_START: 3000,\n PROCESSING_CHECK: 3000,\n COMPLETION_CHECK: 2000,\n PROCESSING_TIMEOUT: 120000, // 2 minutes\n COMPLETION_TIMEOUT: 300000, // 5 minutes\n};\nconst SELECTORS = {\n FILE_INPUT: selectors/* COMMON_FILE_SELECTORS */.mR.FILE_INPUT,\n SUCCESS_INDICATORS: selectors/* COMMON_STATUS_SELECTORS */.aB.SUCCESS,\n ERROR_INDICATORS: selectors/* COMMON_STATUS_SELECTORS */.aB.ERROR,\n PROCESSING_INDICATORS: selectors/* COMMON_STATUS_SELECTORS */.aB.PROCESSING,\n COMPLETION_INDICATORS: [\n '.upload-complete',\n '.processing-complete',\n '.video-ready',\n '[class*=\"complete\"]',\n '[class*=\"ready\"]',\n ],\n TOAST_SELECTORS: selectors/* COMMON_STATUS_SELECTORS */.aB.TOAST,\n PUBLISH_PAGE_INDICATORS: [\n 'div.upload-content',\n 'div.submit',\n '.creator-editor',\n '.video-upload-container',\n 'input[type=\"file\"]',\n ],\n};\nconst TEXT_PATTERNS = selectors/* COMMON_TEXT_PATTERNS */.mu;\nclass PublishBaseService extends base_service/* BaseService */.d {\n imageDownloader;\n constructor(config, browserManager) {\n super(config, browserManager);\n this.imageDownloader = new ImageDownloader('./temp_images');\n }\n // Helper methods for element detection and text matching\n async findElementBySelectors(page, selectors) {\n for (const selector of selectors) {\n const element = await page.$(selector);\n if (element) {\n logger/* logger */.v.debug(`Found element with selector: ${selector}`);\n return element;\n }\n }\n return null;\n }\n async getElementText(element) {\n try {\n return await element.page().evaluate((el) => el.textContent, element);\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to get element text: ${error}`);\n return null;\n }\n }\n async checkTextPatterns(text, patterns) {\n if (!text)\n return false;\n return patterns.some((pattern) => text.includes(pattern));\n }\n async checkElementForPatterns(page, selectors, patterns) {\n for (const selector of selectors) {\n const element = await page.$(selector);\n if (element) {\n const text = await this.getElementText(element);\n if (text && (await this.checkTextPatterns(text, patterns))) {\n return { found: true, text, element };\n }\n }\n }\n return { found: false };\n }\n async waitForCondition(condition, timeout, checkInterval = 1000, errorMessage) {\n const startTime = Date.now();\n while (Date.now() - startTime < timeout) {\n if (await condition()) {\n return;\n }\n await (0,utils/* sleep */.yy)(checkInterval);\n }\n throw new shared_errors/* PublishError */.S1(errorMessage);\n }\n async fillTitle(page, title) {\n // Wait for a likely title input to appear\n try {\n await page.waitForSelector('input.c-input_inner, input.c-input, input[placeholder*=\"标题\"], .title-input input, input[class*=\"title\"]', { timeout: 10000 });\n }\n catch (error) {\n // Continue without waiting if not found purely by selector\n }\n const titleSelectors = [\n 'input.c-input_inner', // specific for recent Xiaohongshu creator UI\n 'input.c-input',\n 'input[placeholder*=\"标题\"]',\n 'input[placeholder*=\"填写标题会有更多赞哦\"]',\n 'input[placeholder*=\"title\"]',\n 'input[data-placeholder*=\"标题\"]',\n '.title-input input',\n 'input[placeholder*=\"请输入标题\"]',\n 'input[name=\"title\"]',\n 'input[id*=\"title\"]',\n 'input[class*=\"title\"]',\n 'input[type=\"text\"]', // Fallbacks\n 'div[contenteditable=\"true\"]',\n 'textarea[placeholder*=\"标题\"]',\n 'textarea[placeholder*=\"title\"]',\n ];\n for (const selector of titleSelectors) {\n try {\n const titleInput = await page.$(selector);\n if (titleInput) {\n // Scroll into view just in case it's off screen\n await page.evaluate((el) => {\n if (el && typeof el.scrollIntoView === 'function') {\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n }, titleInput);\n await (0,utils/* sleep */.yy)(500);\n const isVisible = await titleInput.isIntersectingViewport();\n if (isVisible) {\n await titleInput.click();\n await (0,utils/* sleep */.yy)(500); // Wait for focus\n // clear existing input if any\n await titleInput.click({ clickCount: 3 });\n await titleInput.press('Backspace');\n await titleInput.type(title);\n return;\n }\n }\n }\n catch (error) {\n // Continue to next selector\n }\n }\n // If no specific input found, try to find any visible input or textarea on the page\n try {\n const allInputs = await page.$$('input, textarea');\n for (let i = 0; i < allInputs.length; i++) {\n const input = allInputs[i];\n try {\n const type = await page.evaluate((el) => el.getAttribute('type'), input);\n // avoid file inputs or hidden inputs\n if (type !== 'file' && type !== 'hidden') {\n await page.evaluate((el) => {\n if (el && typeof el.scrollIntoView === 'function') {\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n }, input);\n await (0,utils/* sleep */.yy)(500);\n const isVisible = await input.isIntersectingViewport();\n if (isVisible) {\n await input.click();\n await (0,utils/* sleep */.yy)(500);\n // clear existing input if any\n await input.click({ clickCount: 3 });\n await input.press('Backspace');\n await input.type(title);\n return;\n }\n }\n }\n catch (error) {\n // Continue to next input\n }\n }\n }\n catch (error) {\n // Fall through to error\n }\n throw new shared_errors/* PublishError */.S1('Could not find title input field');\n }\n async findContentElement(page) {\n try {\n // Strategy 1: Try div[contenteditable=\"true\"] (simple and direct)\n const contentEditable = await page.$('div[contenteditable=\"true\"]');\n if (contentEditable) {\n const isVisible = await contentEditable.isIntersectingViewport();\n if (isVisible) {\n return contentEditable;\n }\n }\n // Strategy 2: Try div.tiptap.ProseMirror (primary selector for creator platform)\n const tiptapEditor = await page.$('div.tiptap.ProseMirror');\n if (tiptapEditor) {\n const isVisible = await tiptapEditor.isIntersectingViewport();\n if (isVisible) {\n return tiptapEditor;\n }\n }\n // Strategy 3: Try div[role=\"textbox\"][contenteditable=\"true\"] (specific selector)\n const roleTextbox = await page.$('div[role=\"textbox\"][contenteditable=\"true\"]');\n if (roleTextbox) {\n const isVisible = await roleTextbox.isIntersectingViewport();\n if (isVisible) {\n return roleTextbox;\n }\n }\n // Strategy 4: Try div.ql-editor (legacy selector)\n const qlEditor = await page.$('div.ql-editor');\n if (qlEditor) {\n return qlEditor;\n }\n // Strategy 5: Try to find textarea or contenteditable\n const contentSelectors = [\n '.tiptap.ProseMirror',\n 'textarea[placeholder*=\"正文\"]',\n 'textarea[multiline]',\n 'div[data-placeholder*=\"正文\"]',\n '.content-editor',\n 'div[role=\"textbox\"]',\n 'textbox[role=\"textbox\"]',\n 'textbox[multiline]',\n ];\n for (const selector of contentSelectors) {\n const element = await page.$(selector);\n if (element) {\n return element;\n }\n }\n // Strategy 6: Try to find any multiline textbox (fallback)\n const multilineTextboxes = await page.$$('textbox[multiline]');\n for (const element of multilineTextboxes) {\n const isVisible = await element.isIntersectingViewport();\n if (isVisible) {\n return element;\n }\n }\n return null;\n }\n catch (error) {\n return null;\n }\n }\n async findTextboxByPlaceholder(page) {\n try {\n // Find all p elements\n const pElements = await page.$$('p');\n // Look for element with data-placeholder containing \"输入正文描述\"\n for (const p of pElements) {\n const placeholder = await page.evaluate((el) => el.getAttribute('data-placeholder'), p);\n if (placeholder?.includes('输入正文描述')) {\n return p;\n }\n }\n return null;\n }\n catch (error) {\n return null;\n }\n }\n async findTextboxParent(page, element) {\n try {\n return await page.evaluateHandle((el) => el.parentElement, element);\n }\n catch (error) {\n return null;\n }\n }\n async fillContent(page, content) {\n // Wait for content area to appear\n try {\n await page.waitForSelector('div[role=\"textbox\"][contenteditable=\"true\"], .tiptap.ProseMirror, div[contenteditable=\"true\"], textarea, [role=\"textbox\"], .ql-editor, textbox[multiline]', { timeout: 10000 });\n }\n catch (error) {\n // Continue without waiting\n }\n let contentElement = await this.findContentElement(page);\n if (!contentElement) {\n // Try alternative approach\n const textboxElement = await this.findTextboxByPlaceholder(page);\n if (textboxElement) {\n contentElement = await this.findTextboxParent(page, textboxElement);\n }\n }\n if (!contentElement) {\n // Try to find any contenteditable or textarea element\n try {\n const allContentElements = await page.$$('div[role=\"textbox\"][contenteditable=\"true\"], .tiptap.ProseMirror, div[contenteditable=\"true\"], textarea, [role=\"textbox\"], .ql-editor, p[contenteditable=\"true\"], textbox[multiline]');\n for (let i = 0; i < allContentElements.length; i++) {\n const element = allContentElements[i];\n try {\n const isVisible = await element.isIntersectingViewport();\n const tagName = await page.evaluate((el) => el.tagName, element);\n const contentEditable = await page.evaluate((el) => el.getAttribute('contenteditable'), element);\n const role = await page.evaluate((el) => el.getAttribute('role'), element);\n const className = await page.evaluate((el) => el.className, element);\n const multiline = await page.evaluate((el) => el.getAttribute('multiline'), element);\n if (isVisible &&\n (contentEditable === 'true' ||\n tagName === 'TEXTAREA' ||\n role === 'textbox' ||\n className.includes('ql-editor') ||\n className.includes('tiptap') ||\n multiline === '')) {\n contentElement = element;\n break;\n }\n }\n catch (error) {\n // Continue to next element\n }\n }\n }\n catch (error) {\n // Continue to next strategy\n }\n }\n if (!contentElement) {\n // Last resort: try to find any element that might be for content\n try {\n const allElements = await page.$$('*');\n for (let i = 0; i < Math.min(allElements.length, 50); i++) {\n // Limit to first 50 elements\n const element = allElements[i];\n try {\n const isVisible = await element.isIntersectingViewport();\n const tagName = await page.evaluate((el) => el.tagName, element);\n const contentEditable = await page.evaluate((el) => el.getAttribute('contenteditable'), element);\n const className = await page.evaluate((el) => el.className, element);\n const placeholder = await page.evaluate((el) => el.getAttribute('placeholder'), element);\n if (isVisible &&\n (contentEditable === 'true' ||\n tagName === 'TEXTAREA' ||\n className.includes('content') ||\n className.includes('editor') ||\n placeholder?.includes('内容') ||\n placeholder?.includes('正文'))) {\n contentElement = element;\n break;\n }\n }\n catch (error) {\n // Ignore errors for individual elements\n }\n }\n }\n catch (error) {\n // Fall through to error\n }\n }\n if (!contentElement) {\n throw new shared_errors/* PublishError */.S1('Could not find content input field');\n }\n try {\n await contentElement.click();\n await (0,utils/* sleep */.yy)(500); // Wait for focus\n await contentElement.type(content);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to fill content: ${error}`);\n }\n }\n async inputTags(page, contentElement, tags) {\n const tagList = tags\n .split(',')\n .map((tag) => tag.trim())\n .filter((tag) => tag.length > 0);\n for (const tag of tagList) {\n await this.inputTag(page, contentElement, tag);\n }\n }\n async inputTag(page, contentElement, tag) {\n try {\n // Type the tag\n await contentElement.type(`#${tag}`);\n await (0,utils/* sleep */.yy)(1000);\n // Try to find topic suggestion container\n const topicContainer = await page.$('#creator-editor-topic-container');\n if (topicContainer) {\n const firstItem = await topicContainer.$('.item');\n if (firstItem) {\n await firstItem.click();\n await (0,utils/* sleep */.yy)(500);\n }\n }\n else {\n // Press Enter to confirm the tag\n await contentElement.press('Enter');\n await (0,utils/* sleep */.yy)(500);\n // Press Space to separate tags\n await contentElement.press('Space');\n await (0,utils/* sleep */.yy)(200);\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to add tag ${tag}: ${error}`);\n }\n }\n async addTags(page, tags) {\n try {\n const contentElement = await this.findContentElement(page);\n if (contentElement) {\n await this.inputTags(page, contentElement, tags);\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to add tags: ${error}`);\n }\n }\n async submitPost(page) {\n try {\n // Strategy 1: Look for the <xhs-publish-btn> custom element (new XHS UI)\n let submitButton = null;\n const customBtn = await page.$('xhs-publish-btn');\n if (customBtn) {\n // Verify it has the right attributes (is-publish=\"true\", submit-text=\"发布\")\n const attrs = await customBtn.evaluate((el) => ({\n isPublish: el.getAttribute('is-publish'),\n submitText: el.getAttribute('submit-text'),\n submitDisabled: el.getAttribute('submit-disabled'),\n }));\n logger/* logger */.v.debug(`Found xhs-publish-btn custom element: ${JSON.stringify(attrs)}`);\n if (attrs.isPublish === 'true' || attrs.submitText === '发布') {\n submitButton = customBtn;\n }\n }\n // Strategy 2: Look for standard button elements containing \"发布\"\n if (!submitButton) {\n const buttons = await page.$$('button');\n for (const btn of buttons) {\n const text = await btn.evaluate(el => el.textContent?.trim());\n if (text?.includes('发布')) {\n submitButton = btn;\n break;\n }\n }\n }\n if (!submitButton) {\n // Strategy 3: search all visible div/span elements containing \"发布\" text\n const textCandidates = await page.$$('div, span');\n for (const el of textCandidates) {\n try {\n const text = await el.evaluate(el => el.textContent?.trim());\n if (text?.includes('发布') && text.length < 20) {\n const isVisible = await el.isIntersectingViewport().catch(() => false);\n if (isVisible) {\n submitButton = el;\n break;\n }\n }\n }\n catch {\n continue;\n }\n }\n }\n if (!submitButton) {\n const submitSelector = 'div.submit, .submit-btn, .publish-btn, [class*=\"publish\"], [class*=\"btn-\"], .btn-text';\n submitButton = await page.$(submitSelector);\n }\n // Strategy 5: XPath text match\n if (!submitButton) {\n const publishTexts = ['发布笔记', '发布', '发表'];\n for (const text of publishTexts) {\n const elements = await page.$x(`//*[contains(text(), '${text}')]`);\n for (const el of elements) {\n try {\n const rect = await el.evaluate((el) => {\n const r = el.getBoundingClientRect();\n return { w: r.width, h: r.height };\n });\n if (rect.w > 0 && rect.h > 0) {\n submitButton = el;\n break;\n }\n }\n catch {\n continue;\n }\n }\n if (submitButton)\n break;\n }\n }\n // Strategy 6: Find .btn-text span and click parent\n if (!submitButton) {\n const btnTextEl = await page.$('.btn-text');\n if (btnTextEl) {\n const text = await btnTextEl.evaluate(el => el.textContent?.trim());\n if (text?.includes('发布')) {\n const parent = await btnTextEl.evaluateHandle(el => el.closest('[class*=\"publish\"], [class*=\"btn-\"]') || el.parentElement);\n if (parent) {\n submitButton = parent;\n }\n }\n }\n }\n if (!submitButton) {\n // Debug: dump key info about the page state\n const debugInfo = await page.evaluate(() => {\n // Find all elements mentioning 发布\n const publishElements = [];\n document.querySelectorAll('*').forEach(el => {\n const text = el.textContent?.trim();\n if (text?.includes('发布')) {\n const rect = el.getBoundingClientRect();\n publishElements.push({\n tag: el.tagName,\n text: text.substring(0, 30),\n class: el.className?.substring(0, 80),\n visible: rect.width > 0 && rect.height > 0,\n rect: `${rect.width.toFixed(0)}x${rect.height.toFixed(0)} at ${rect.top.toFixed(0)},${rect.left.toFixed(0)}`,\n });\n }\n });\n return {\n url: window.location.href,\n bodyHeight: document.body.scrollHeight,\n viewportHeight: window.innerHeight,\n publishElements: publishElements.slice(0, 40),\n };\n });\n throw new shared_errors/* PublishError */.S1(`Could not find submit button. URL=${debugInfo.url}, body=${debugInfo.bodyHeight}, vp=${debugInfo.viewportHeight}, publishElems=${JSON.stringify(debugInfo.publishElements)}`);\n }\n // Pre-click checks: ensure button is enabled and clickable\n const buttonState = await page.evaluate((el) => {\n if (!el)\n return { exists: false };\n const htmlEl = el;\n const style = window.getComputedStyle(htmlEl);\n return {\n exists: true,\n disabled: htmlEl.hasAttribute('disabled') || htmlEl.getAttribute('aria-disabled') === 'true',\n pointerEvents: style.pointerEvents,\n opacity: style.opacity,\n visibility: style.visibility,\n display: style.display,\n tagName: htmlEl.tagName,\n className: htmlEl.className,\n text: htmlEl.textContent?.trim().substring(0, 20),\n };\n }, submitButton);\n logger/* logger */.v.debug(`Submit button state: ${JSON.stringify(buttonState)}`);\n if (buttonState.disabled) {\n logger/* logger */.v.warn('Submit button is disabled - publishing may fail');\n }\n // Scroll to button before clicking\n await page.evaluate((el) => {\n if (el && typeof el.scrollIntoView === 'function') {\n el.scrollIntoView({ behavior: 'instant', block: 'center' });\n }\n }, submitButton);\n await (0,utils/* sleep */.yy)(500);\n // Helper to check if publish was triggered (page navigating away or showing success)\n const isPublishTriggered = async () => {\n try {\n const currentUrl = page.url();\n const bodyText = await page.evaluate(() => document.body?.textContent || '');\n return !currentUrl.includes('/publish/publish') ||\n bodyText.includes('发布成功') ||\n bodyText.includes('审核中');\n }\n catch {\n return false;\n }\n };\n // Strategy A: For xhs-publish-btn custom element, dispatch a CustomEvent('publish')\n const isCustomElement = await submitButton.evaluate((el) => el.tagName === 'XHS-PUBLISH-BTN');\n if (isCustomElement) {\n try {\n await page.evaluate((el) => {\n if (!el)\n return;\n el.dispatchEvent(new CustomEvent('publish', { bubbles: true, composed: true }));\n }, submitButton);\n logger/* logger */.v.debug('Dispatched CustomEvent(\"publish\") on xhs-publish-btn');\n }\n catch (customEventError) {\n logger/* logger */.v.debug(`CustomEvent dispatch failed: ${customEventError}`);\n }\n await (0,utils/* sleep */.yy)(1500);\n if (await isPublishTriggered())\n return;\n }\n // Strategy B: Full React event chain via evaluate (fallback for standard elements)\n try {\n await page.evaluate((el) => {\n if (!el)\n return;\n const htmlEl = el;\n const rect = htmlEl.getBoundingClientRect();\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n const eventInit = { bubbles: true, cancelable: true, composed: true, clientX: x, clientY: y, screenX: x, screenY: y };\n const events = [\n new MouseEvent('mouseenter', eventInit),\n new MouseEvent('mouseover', eventInit),\n new MouseEvent('mousemove', eventInit),\n new MouseEvent('mousedown', { ...eventInit, button: 0, buttons: 1 }),\n new FocusEvent('focus', { bubbles: true }),\n new MouseEvent('mouseup', { ...eventInit, button: 0, buttons: 0 }),\n new MouseEvent('click', { ...eventInit, button: 0, buttons: 0 }),\n ];\n events.forEach((ev) => htmlEl.dispatchEvent(ev));\n }, submitButton);\n logger/* logger */.v.debug('Dispatched full React event chain on submit button');\n }\n catch (chainError) {\n logger/* logger */.v.debug(`React event chain failed: ${chainError}`);\n }\n await (0,utils/* sleep */.yy)(1000);\n if (await isPublishTriggered())\n return;\n // Strategy C: Puppeteer native click as fallback\n try {\n await submitButton.click();\n logger/* logger */.v.debug('Clicked submit button via Puppeteer native click');\n }\n catch (clickError) {\n logger/* logger */.v.debug(`Puppeteer click failed: ${clickError}`);\n }\n await (0,utils/* sleep */.yy)(800);\n if (await isPublishTriggered())\n return;\n // Strategy D: JavaScript click via evaluate\n try {\n await page.evaluate((el) => { if (el)\n el.click(); }, submitButton);\n logger/* logger */.v.debug('Clicked submit button via JS evaluate click');\n }\n catch (jsClickError) {\n logger/* logger */.v.debug(`JS evaluate click failed: ${jsClickError}`);\n }\n await (0,utils/* sleep */.yy)(800);\n if (await isPublishTriggered())\n return;\n // Strategy E: Try clicking via page.mouse at element center coordinates\n try {\n const box = await submitButton.boundingBox();\n if (box) {\n await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);\n await page.mouse.down();\n await (0,utils/* sleep */.yy)(50);\n await page.mouse.up();\n logger/* logger */.v.debug('Clicked submit button via mouse coordinates');\n }\n }\n catch (mouseError) {\n logger/* logger */.v.debug(`Mouse click failed: ${mouseError}`);\n }\n await (0,utils/* sleep */.yy)(1500);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to click submit button: ${error}`);\n }\n }\n async isElementVisible(element) {\n try {\n return await element.isIntersectingViewport();\n }\n catch (error) {\n return false;\n }\n }\n async waitForPublishCompletion(page) {\n const maxWaitTime = 30000; // 30 seconds (reduced from 60s)\n const startTime = Date.now();\n const publishStartUrl = page.url();\n while (Date.now() - startTime < maxWaitTime) {\n const currentUrl = page.url();\n // Strategy 1: Check for success indicators via CSS selectors\n const successIndicators = [\n '.success-message',\n '.publish-success',\n '[data-testid=\"publish-success\"]',\n '.toast-success',\n ];\n for (const selector of successIndicators) {\n const element = await page.$(selector);\n if (element) {\n logger/* logger */.v.debug(`Found success indicator: ${selector}`);\n await (0,utils/* sleep */.yy)(2000);\n return await this.extractNoteIdFromPage(page);\n }\n }\n // Strategy 2: Check for error indicators\n const errorIndicators = [\n '.error-message',\n '.publish-error',\n '[data-testid=\"publish-error\"]',\n '.toast-error',\n '.error-toast',\n ];\n for (const selector of errorIndicators) {\n const element = await page.$(selector);\n if (element) {\n const errorText = await page.evaluate((el) => el.textContent, element);\n throw new shared_errors/* PublishError */.S1(`Publish failed with error: ${errorText}`);\n }\n }\n // Strategy 3: Check if we're still on the publish page\n const publishPageIndicators = ['div.upload-content', 'div.submit', '.creator-editor'];\n let stillOnPublishPage = false;\n for (const selector of publishPageIndicators) {\n const element = await page.$(selector);\n if (element) {\n stillOnPublishPage = true;\n break;\n }\n }\n if (!stillOnPublishPage) {\n logger/* logger */.v.debug('Left publish page, assuming success');\n return await this.extractNoteIdFromPage(page);\n }\n // Strategy 4: Check for toast/popup messages with text content\n const toastSelectors = ['.toast', '.message', '.notification', '[role=\"alert\"]'];\n for (const selector of toastSelectors) {\n const element = await page.$(selector);\n if (element) {\n const toastText = await page.evaluate((el) => el.textContent, element);\n if (toastText) {\n if (toastText.includes('成功') || toastText.includes('success')) {\n logger/* logger */.v.debug(`Found success toast: ${toastText}`);\n return await this.extractNoteIdFromPage(page);\n }\n else if (toastText.includes('失败') ||\n toastText.includes('error') ||\n toastText.includes('错误')) {\n throw new shared_errors/* PublishError */.S1(`Publish failed: ${toastText}`);\n }\n }\n }\n }\n // Strategy 5: Broad text-based success detection\n const textSuccessElements = await page.$$('div, span, p, h1, h2, h3, button');\n for (const el of textSuccessElements) {\n try {\n const text = await el.evaluate((e) => e.textContent?.trim());\n if (text && text.length < 50) {\n if (text.includes('发布成功') || text.includes('投稿成功') || text.includes('审核中')) {\n logger/* logger */.v.debug(`Found text success indicator: ${text}`);\n return await this.extractNoteIdFromPage(page);\n }\n if (text.includes('发布失败') || text.includes('投稿失败')) {\n throw new shared_errors/* PublishError */.S1(`Publish failed: ${text}`);\n }\n }\n }\n catch {\n continue;\n }\n }\n // Strategy 6: URL change detection (navigated away from publish page)\n if (currentUrl !== publishStartUrl) {\n const isPublishUrl = currentUrl.includes('/publish') || currentUrl.includes('/creator');\n if (!isPublishUrl) {\n logger/* logger */.v.debug(`URL changed from publish page to ${currentUrl}, assuming success`);\n return await this.extractNoteIdFromPage(page);\n }\n }\n // Strategy 7: Check for loading/success overlays\n const overlaySelectors = ['.modal', '.popup', '.dialog', '.overlay', '[class*=\"success\"]', '[class*=\"modal\"]'];\n for (const selector of overlaySelectors) {\n const element = await page.$(selector);\n if (element) {\n try {\n const isVisible = await element.isIntersectingViewport().catch(() => false);\n if (isVisible) {\n const text = await element.evaluate((e) => e.textContent?.trim());\n if (text && (text.includes('成功') || text.includes('发布'))) {\n logger/* logger */.v.debug(`Found overlay with success text: ${text.substring(0, 50)}`);\n return await this.extractNoteIdFromPage(page);\n }\n }\n }\n catch {\n continue;\n }\n }\n }\n await (0,utils/* sleep */.yy)(800); // Wait before next check\n }\n // Timeout: collect debug info\n const debugInfo = await page.evaluate(() => {\n const allTexts = [];\n document.querySelectorAll('div, span, p, h1, h2, h3, button').forEach((el) => {\n const text = el.textContent?.trim();\n if (text && text.length > 0 && text.length < 100) {\n allTexts.push(text);\n }\n });\n return {\n url: window.location.href,\n bodyText: document.body?.textContent?.substring(0, 500) || '',\n visibleTexts: allTexts.filter((t, i, arr) => arr.indexOf(t) === i).slice(0, 30),\n };\n });\n logger/* logger */.v.debug(`Publish timeout debug - URL: ${debugInfo.url}`);\n logger/* logger */.v.debug(`Visible texts: ${debugInfo.visibleTexts.join(' | ')}`);\n // Check if page left publish URL (even if not detected earlier) - assume success\n const isStillOnPublishUrl = debugInfo.url.includes('/publish');\n const hasErrorText = debugInfo.visibleTexts.some((t) => t.includes('失败') || t.includes('错误') || t.includes('error') || t.includes('无法'));\n if (!isStillOnPublishUrl || !hasErrorText) {\n logger/* logger */.v.warn(`Publish completion timed out but no error detected. Assuming success. URL=${debugInfo.url}`);\n return await this.extractNoteIdFromPage(page);\n }\n throw new shared_errors/* PublishError */.S1(`Publish completion timeout - could not determine result. URL=${debugInfo.url}, texts=${debugInfo.visibleTexts.join(', ').substring(0, 200)}`);\n }\n async extractNoteIdFromPage(page) {\n try {\n // Method 1: Try to extract from URL if redirected to note page\n const currentUrl = page.url();\n logger/* logger */.v.debug(`Current URL after publish: ${currentUrl}`);\n // Check if we're on a note page (URL contains /explore/ or /discovery/)\n const noteIdMatch = currentUrl.match(/\\/explore\\/([a-f0-9]+)/i) ||\n currentUrl.match(/\\/discovery\\/([a-f0-9]+)/i);\n if (noteIdMatch && noteIdMatch[1]) {\n const noteId = noteIdMatch[1];\n logger/* logger */.v.debug(`Extracted note ID from URL: ${noteId}`);\n return noteId;\n }\n // Method 2: Try to find note ID in page content or data attributes\n const noteIdFromPage = await page.evaluate(() => {\n // Look for data attributes that might contain note ID\n const elementsWithData = document.querySelectorAll('[data-note-id], [data-id], [data-impression]');\n for (let i = 0; i < elementsWithData.length; i++) {\n const element = elementsWithData[i];\n const noteId = element.getAttribute('data-note-id') ||\n element.getAttribute('data-id') ||\n element.getAttribute('data-impression');\n if (noteId && noteId.length > 10) { // Note IDs are typically long\n return noteId;\n }\n }\n // Look for links to note pages\n const noteLinks = document.querySelectorAll('a[href*=\"/explore/\"], a[href*=\"/discovery/\"]');\n for (let i = 0; i < noteLinks.length; i++) {\n const link = noteLinks[i];\n const href = link.getAttribute('href');\n if (href) {\n const match = href.match(/\\/explore\\/([a-f0-9]+)/i) ||\n href.match(/\\/discovery\\/([a-f0-9]+)/i);\n if (match && match[1]) {\n return match[1];\n }\n }\n }\n // Look for any text that looks like a note ID (long hex string)\n const textContent = document.body.textContent || '';\n const noteIdPattern = /[a-f0-9]{20,}/gi;\n const matches = textContent.match(noteIdPattern);\n if (matches && matches.length > 0) {\n // Return the first long hex string found\n return matches[0];\n }\n return null;\n });\n if (noteIdFromPage) {\n logger/* logger */.v.debug(`Extracted note ID from page content: ${noteIdFromPage}`);\n return noteIdFromPage;\n }\n // Method 3: Try to get the latest note ID using NoteService (fallback)\n logger/* logger */.v.debug('Could not extract note ID from page, trying fallback method');\n try {\n // Wait a bit for the note to be processed\n await (0,utils/* sleep */.yy)(5000);\n // Use NoteService to get the latest note ID\n const { NoteService } = await Promise.resolve(/* import() */).then(__webpack_require__.bind(__webpack_require__, 9113));\n const noteService = new NoteService(this.getConfig());\n const userNotes = await noteService.getUserNotes(1); // Get only the latest note\n if (userNotes.success && userNotes.data && userNotes.data.length > 0) {\n const latestNoteId = userNotes.data[0].id;\n logger/* logger */.v.debug(`Extracted note ID from NoteService: ${latestNoteId}`);\n return latestNoteId;\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Fallback note ID extraction failed: ${error}`);\n }\n logger/* logger */.v.debug('Could not extract note ID from any method');\n return null;\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to extract note ID: ${error}`);\n return null;\n }\n }\n}\n\n;// ./src/core/publishing/publish-image.service.ts\n\n\n\n\n\n\n\nclass ImagePublishService extends PublishBaseService {\n async publishNote(title, content, imagePaths, tags = '', browserPath) {\n // Validate inputs\n if (!title?.trim()) {\n throw new shared_errors/* PublishError */.S1('Note title cannot be empty');\n }\n // Validate title width (CJK characters count as 2 units, ASCII as 1)\n assertTitleWidthValid(title);\n logger/* logger */.v.debug(`Title width validation passed: \"${title}\" (${getTitleWidth(title)} units)`);\n if (!content?.trim()) {\n throw new shared_errors/* PublishError */.S1('Note content cannot be empty');\n }\n if (!imagePaths || imagePaths.length === 0) {\n throw new shared_errors/* PublishError */.S1('At least one image is required');\n }\n // Process image paths - download URLs and validate local paths\n const resolvedPaths = await this.validateAndResolveImagePaths(imagePaths);\n // Wait for upload container selector\n const uploadSelector = 'div.upload-content';\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.creatorPublishUrl);\n // Wait for page to load\n await (0,utils/* sleep */.yy)(2000);\n // First, try to switch to the image/text upload tab\n await this.clickUploadTab(page);\n // Wait for tab switch to complete\n await (0,utils/* sleep */.yy)(2000);\n let hasUploadContainer = await this.getBrowserManager().tryWaitForSelector(page, uploadSelector, 30000);\n if (!hasUploadContainer) {\n // Try alternative selectors for upload container\n const alternativeSelectors = [\n 'div.upload-content',\n '.upload-content',\n 'div[class*=\"upload\"]',\n 'div[class*=\"image\"]',\n 'input[type=\"file\"]',\n ];\n for (const selector of alternativeSelectors) {\n hasUploadContainer = await this.getBrowserManager().tryWaitForSelector(page, selector, 10000);\n if (hasUploadContainer) {\n break;\n }\n }\n }\n if (!hasUploadContainer) {\n throw new shared_errors/* PublishError */.S1('Could not find upload container on publish page');\n }\n // Upload images\n await this.uploadImages(page, resolvedPaths);\n // Wait for images to be processed (large files need more time on XHS)\n logger/* logger */.v.debug('Waiting 10 seconds for images to be uploaded and processed...');\n await (0,utils/* sleep */.yy)(10000);\n // Wait for page to transition to edit mode (check for title or content input)\n try {\n await page.waitForSelector('input[placeholder*=\"标题\"], div[contenteditable=\"true\"], .tiptap.ProseMirror', { timeout: 15000 });\n }\n catch (error) {\n // Continue without waiting\n }\n // Wait a bit for the page to settle after image upload\n await (0,utils/* sleep */.yy)(1000);\n // Fill in title\n await this.fillTitle(page, title);\n // Wait a bit more for content area to appear\n await (0,utils/* sleep */.yy)(1000);\n // Fill in content\n await this.fillContent(page, content);\n // Add tags if provided\n if (tags) {\n await this.addTags(page, tags);\n }\n // Submit the note\n await this.submitPost(page);\n // Wait for completion and check result\n const noteId = await this.waitForPublishCompletion(page);\n // Save cookies\n await this.getBrowserManager().saveCookiesFromPage(page);\n return {\n success: true,\n message: 'Note published successfully',\n title,\n content,\n imageCount: resolvedPaths.length,\n tags,\n url: this.getConfig().xhs.creatorPublishUrl,\n noteId: noteId || undefined,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Publish error: ${error}`);\n throw error;\n }\n }\n /**\n * Process image paths - download URLs and validate local paths\n */\n async validateAndResolveImagePaths(imagePaths) {\n // Use ImageDownloader to process paths (downloads URLs, validates local paths)\n const resolvedPaths = await this.imageDownloader.processImagePaths(imagePaths);\n // Validate resolved paths\n for (const resolvedPath of resolvedPaths) {\n // For local paths that aren't absolute, resolve them\n const fullPath = resolvedPath.startsWith('/') || resolvedPath.match(/^[a-zA-Z]:/)\n ? resolvedPath\n : (0,external_path_.join)(process.cwd(), resolvedPath);\n if (!(0,external_fs_.existsSync)(fullPath)) {\n throw new shared_errors/* InvalidImageError */.TD(`Image file not found: ${resolvedPath}`);\n }\n const stats = (0,external_fs_.statSync)(fullPath);\n if (!stats.isFile()) {\n throw new shared_errors/* InvalidImageError */.TD(`Path is not a file: ${resolvedPath}`);\n }\n // Check file extension\n const ext = resolvedPath.toLowerCase().split('.').pop();\n const allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'];\n if (!ext || !allowedExtensions.includes(ext)) {\n throw new shared_errors/* InvalidImageError */.TD(`Unsupported image format: ${resolvedPath}. Supported: ${allowedExtensions.join(', ')}`);\n }\n }\n if (resolvedPaths.length > 18) {\n throw new shared_errors/* PublishError */.S1('Maximum 18 images allowed');\n }\n return resolvedPaths;\n }\n async clickUploadTab(page) {\n try {\n logger/* logger */.v.debug('Attempting to switch to \"上传图文\" tab');\n // Strategy 1: Navigate directly to image publish URL\n const imagePublishUrl = 'https://creator.xiaohongshu.com/publish/publish?source=official&from=menu&target=image';\n await page.goto(imagePublishUrl, { waitUntil: 'networkidle2', timeout: 30000 });\n logger/* logger */.v.debug(`Navigated directly to image publish URL: ${imagePublishUrl}`);\n await (0,utils/* sleep */.yy)(2000);\n // Verify we're on the image tab by checking page content\n const pageState = await page.evaluate(() => {\n const bodyText = document.body?.textContent || '';\n return {\n hasImageUpload: bodyText.includes('上传图文') || bodyText.includes('拖拽图片'),\n hasVideoUpload: bodyText.includes('上传视频') || bodyText.includes('拖拽视频'),\n url: window.location.href,\n };\n });\n logger/* logger */.v.debug(`Page state after navigation: ${JSON.stringify(pageState)}`);\n if (!pageState.hasImageUpload && pageState.hasVideoUpload) {\n logger/* logger */.v.warn('Still on video upload page after navigation. Trying tab click...');\n // Strategy 2: Click the image tab explicitly\n const tabs = await page.$$('div[class*=\"tab\"], .creator-tab, [role=\"tab\"]');\n for (const tab of tabs) {\n const text = await tab.evaluate(el => el.textContent?.trim());\n if (text && (text.includes('上传图文') || text.includes('图文'))) {\n const isVisible = await tab.isIntersectingViewport().catch(() => false);\n if (!isVisible)\n continue;\n // Full event chain for React\n await tab.evaluate((el) => {\n const htmlEl = el;\n const events = ['mouseenter', 'mouseover', 'mousedown', 'mouseup', 'click'];\n events.forEach(ev => {\n htmlEl.dispatchEvent(new MouseEvent(ev, { bubbles: true, cancelable: true }));\n });\n });\n await (0,utils/* sleep */.yy)(500);\n await tab.click();\n logger/* logger */.v.debug('Clicked image tab via Puppeteer');\n await (0,utils/* sleep */.yy)(1000);\n break;\n }\n }\n }\n await (0,utils/* sleep */.yy)(1000);\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to switch to image tab: ${error}`);\n }\n }\n async uploadImages(page, imagePaths) {\n try {\n logger/* logger */.v.debug('Uploading images using direct input element targeting');\n const fileInput = await page.$('input[type=\"file\"]');\n if (!fileInput) {\n throw new shared_errors/* PublishError */.S1('Could not find file upload input on page');\n }\n // Ensure the input accepts multiple files and any type to avoid frontend blocks\n await page.evaluate((el) => {\n if (el) {\n el.setAttribute('multiple', 'multiple');\n el.removeAttribute('accept');\n }\n }, fileInput);\n logger/* logger */.v.debug(`Submitting ${imagePaths.length} image paths to file input element`);\n await fileInput.uploadFile(...imagePaths);\n // Dispatch a change event manually in case the framework missed it\n await page.evaluate((el) => {\n if (el) {\n el.dispatchEvent(new Event('change', { bubbles: true }));\n }\n }, fileInput);\n await (0,utils/* sleep */.yy)(8000);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to upload images: ${error}`);\n }\n }\n}\n\n;// ./src/core/publishing/publish-video.service.ts\n\n\n\n\n\n\n\n\nclass VideoPublishService extends PublishBaseService {\n async waitForVideoPublishCompletion(page) {\n logger/* logger */.v.debug('Waiting for video publish completion...');\n let isProcessing = false;\n await this.waitForCondition(async () => {\n // Check for success indicators\n const successResult = await this.checkElementForPatterns(page, SELECTORS.SUCCESS_INDICATORS, TEXT_PATTERNS.SUCCESS);\n if (successResult.found) {\n logger/* logger */.v.debug(`Found success indicator: ${successResult.text}`);\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.COMPLETION_CHECK);\n return true;\n }\n // Check for error indicators\n const errorResult = await this.checkElementForPatterns(page, SELECTORS.ERROR_INDICATORS, TEXT_PATTERNS.ERROR);\n if (errorResult.found) {\n throw new shared_errors/* PublishError */.S1(`Video publish failed with error: ${errorResult.text}`);\n }\n // Check if we've left the publish page (likely success)\n const stillOnPage = await this.findElementBySelectors(page, SELECTORS.PUBLISH_PAGE_INDICATORS);\n if (!stillOnPage) {\n logger/* logger */.v.debug('Left publish page, assuming video publish success');\n return true;\n }\n // Check for processing status\n const processingResult = await this.checkElementForPatterns(page, SELECTORS.PROCESSING_INDICATORS, TEXT_PATTERNS.PROCESSING);\n isProcessing = processingResult.found;\n if (isProcessing) {\n logger/* logger */.v.debug(`Video still processing: ${processingResult.text}`);\n }\n // Check for toast messages\n const toastResult = await this.checkElementForPatterns(page, SELECTORS.TOAST_SELECTORS, TEXT_PATTERNS.SUCCESS);\n if (toastResult.found) {\n logger/* logger */.v.debug(`Found success toast: ${toastResult.text}`);\n return true;\n }\n const errorToastResult = await this.checkElementForPatterns(page, SELECTORS.TOAST_SELECTORS, TEXT_PATTERNS.ERROR);\n if (errorToastResult.found) {\n throw new shared_errors/* PublishError */.S1(`Video publish failed: ${errorToastResult.text}`);\n }\n return false;\n }, VIDEO_TIMEOUTS.COMPLETION_TIMEOUT, isProcessing ? 5000 : VIDEO_TIMEOUTS.COMPLETION_CHECK, 'Video publish completion timeout - could not determine result after 5 minutes');\n // Extract note ID after successful completion\n return await this.extractNoteIdFromPage(page);\n }\n async publishVideo(title, content, videoPath, tags = '', browserPath) {\n // Validate inputs\n this.validateVideoInputs(title, content, videoPath);\n // Validate and resolve video path\n const resolvedVideoPath = this.validateAndResolveVideoPath(videoPath);\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n const noteId = await this.executeVideoPublishWorkflow(page, title, content, resolvedVideoPath, tags);\n // Save cookies\n await this.getBrowserManager().saveCookiesFromPage(page);\n return {\n success: true,\n message: 'Video published successfully',\n title,\n content,\n imageCount: 0, // Videos don't have image count\n tags,\n url: this.getConfig().xhs.creatorVideoPublishUrl,\n noteId: noteId || undefined,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Video publish error: ${error}`);\n throw error;\n }\n }\n validateVideoInputs(title, content, videoPath) {\n if (!title?.trim()) {\n throw new shared_errors/* PublishError */.S1('Video title cannot be empty');\n }\n // Validate title width for video posts too\n assertTitleWidthValid(title);\n logger/* logger */.v.debug(`Video title width validation passed: \"${title}\" (${getTitleWidth(title)} units)`);\n if (!content?.trim()) {\n throw new shared_errors/* PublishError */.S1('Video content cannot be empty');\n }\n if (!videoPath?.trim()) {\n throw new shared_errors/* PublishError */.S1('Video path is required');\n }\n }\n async executeVideoPublishWorkflow(page, title, content, videoPath, tags) {\n // Navigate to video upload page\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.creatorVideoPublishUrl);\n // Wait for page to load\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.PAGE_LOAD);\n // Switch to video upload tab if needed\n await this.clickVideoUploadTab(page);\n // Wait for tab switch to complete\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.TAB_SWITCH);\n // Upload video\n await this.uploadVideo(page, videoPath);\n // Wait for video to be processed (videos take longer than images)\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.VIDEO_PROCESSING);\n // Fill in title\n await this.fillTitle(page, title);\n // Wait a bit for content area to appear\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.CONTENT_WAIT);\n // Fill in content\n await this.fillContent(page, content);\n // Add tags if provided\n if (tags) {\n await this.addTags(page, tags);\n }\n // Submit the video\n await this.submitPost(page);\n // Wait for completion and check result (videos need longer timeout)\n return await this.waitForVideoPublishCompletion(page);\n }\n validateAndResolveVideoPath(videoPath) {\n const resolvedPath = videoPath.startsWith('/') || videoPath.match(/^[a-zA-Z]:/)\n ? videoPath\n : (0,external_path_.join)(process.cwd(), videoPath);\n if (!(0,external_fs_.existsSync)(resolvedPath)) {\n throw new shared_errors/* PublishError */.S1(`Video file not found: ${videoPath}`);\n }\n const stats = (0,external_fs_.statSync)(resolvedPath);\n if (!stats.isFile()) {\n throw new shared_errors/* PublishError */.S1(`Path is not a file: ${videoPath}`);\n }\n // Check file extension\n const ext = videoPath.toLowerCase().split('.').pop();\n const allowedExtensions = ['mp4', 'mov', 'avi', 'mkv', 'webm', 'flv', 'wmv'];\n if (!ext || !allowedExtensions.includes(ext)) {\n throw new shared_errors/* PublishError */.S1(`Unsupported video format: ${videoPath}. Supported: ${allowedExtensions.join(', ')}`);\n }\n // Check file size (XHS typically has limits)\n const maxSizeInMB = 500; // 500MB limit\n const fileSizeInMB = stats.size / (1024 * 1024);\n if (fileSizeInMB > maxSizeInMB) {\n throw new shared_errors/* PublishError */.S1(`Video file too large: ${fileSizeInMB.toFixed(2)}MB. Maximum allowed: ${maxSizeInMB}MB`);\n }\n return resolvedPath;\n }\n async clickVideoUploadTab(page) {\n try {\n // Try multiple selectors for video tab\n const videoTabSelectors = [\n 'div.creator-tab',\n '.creator-tab',\n '[role=\"tab\"]',\n '.tab',\n 'div[class*=\"tab\"]',\n ];\n let tabs = [];\n for (const selector of videoTabSelectors) {\n const foundTabs = await page.$$(selector);\n if (foundTabs.length > 0) {\n tabs = foundTabs;\n break;\n }\n }\n if (tabs.length === 0) {\n logger/* logger */.v.warn('No tabs found for video upload');\n return;\n }\n // Look for the video upload tab specifically\n let videoTab = null;\n for (let i = 0; i < tabs.length; i++) {\n const tab = tabs[i];\n try {\n const isVisible = await tab.isIntersectingViewport();\n if (!isVisible)\n continue;\n const text = await page.evaluate((el) => el.textContent, tab);\n // Check if this is the video upload tab\n if (text &&\n (text.includes('上传视频') || text.includes('视频') || text.includes('video'))) {\n videoTab = tab;\n break;\n }\n }\n catch (error) {\n // Ignore individual tab errors\n }\n }\n if (videoTab) {\n await videoTab.click();\n await (0,utils/* sleep */.yy)(2000); // Wait for tab switch\n }\n else {\n // Fallback: click the first tab (usually video upload)\n const visibleTabs = [];\n for (const tab of tabs) {\n const isVisible = await tab.isIntersectingViewport();\n if (isVisible) {\n visibleTabs.push(tab);\n }\n }\n if (visibleTabs.length > 0) {\n await visibleTabs[0].click(); // Usually the first tab is video upload\n await (0,utils/* sleep */.yy)(2000);\n }\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to click video upload tab: ${error}`);\n }\n }\n async uploadVideo(page, videoPath) {\n logger/* logger */.v.debug(`Uploading video: ${videoPath}`);\n // Find file input element\n const fileInput = await this.findElementBySelectors(page, SELECTORS.FILE_INPUT);\n if (!fileInput) {\n throw new shared_errors/* PublishError */.S1('Could not find file upload input on video upload page');\n }\n try {\n // Wait for the input to be ready\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.UPLOAD_READY);\n // Upload the video file\n await fileInput.uploadFile(videoPath);\n logger/* logger */.v.debug('Video file uploaded, waiting for processing...');\n // Wait for upload to start and show progress\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.UPLOAD_START);\n // Wait for video processing to complete (this can take a while)\n await this.waitForVideoProcessing(page);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to upload video ${videoPath}: ${error}`);\n }\n }\n async waitForVideoProcessing(page) {\n logger/* logger */.v.debug('Waiting for video processing to complete...');\n try {\n await this.waitForCondition(async () => {\n // Check if processing is complete\n const completeResult = await this.checkElementForPatterns(page, SELECTORS.COMPLETION_INDICATORS, TEXT_PATTERNS.SUCCESS);\n if (completeResult.found) {\n logger/* logger */.v.debug(`Video processing complete: ${completeResult.text}`);\n return true;\n }\n // Check if still processing\n const processingResult = await this.checkElementForPatterns(page, SELECTORS.PROCESSING_INDICATORS, TEXT_PATTERNS.PROCESSING);\n if (processingResult.found) {\n logger/* logger */.v.debug(`Video processing: ${processingResult.text}`);\n return false; // Still processing, continue waiting\n }\n // If not processing and no completion indicator, assume it's done\n logger/* logger */.v.debug('No processing indicators found, assuming video processing complete');\n return true;\n }, VIDEO_TIMEOUTS.PROCESSING_TIMEOUT, VIDEO_TIMEOUTS.PROCESSING_CHECK, 'Video processing timeout');\n }\n catch (error) {\n logger/* logger */.v.warn('Video processing timeout, continuing anyway...');\n }\n }\n}\n\n;// ./src/core/publishing/publish.service.ts\n\n\n\nclass PublishService extends base_service/* BaseService */.d {\n imageService;\n videoService;\n constructor(config, browserManager) {\n super(config, browserManager);\n this.imageService = new ImagePublishService(config, this.browserManager);\n this.videoService = new VideoPublishService(config, this.browserManager);\n }\n async publishNote(title, content, imagePaths, tags = '', browserPath) {\n return this.imageService.publishNote(title, content, imagePaths, tags, browserPath);\n }\n async publishVideo(title, content, videoPath, tags = '', browserPath) {\n return this.videoService.publishVideo(title, content, videoPath, tags, browserPath);\n }\n async publishContent(type, title, content, mediaPaths, tags = '', browserPath) {\n if (type === 'image') {\n return this.publishNote(title, content, mediaPaths, tags, browserPath);\n }\n else {\n return this.publishVideo(title, content, mediaPaths[0], tags, browserPath);\n }\n }\n}\n\n// EXTERNAL MODULE: ./src/core/notes/note.service.ts + 2 modules\nvar note_service = __webpack_require__(9113);\n// EXTERNAL MODULE: ./src/core/browser/browser.manager.ts + 1 modules\nvar browser_manager = __webpack_require__(3977);\n;// ./src/server/handlers/tool.handlers.ts\n/**\n * Tool request handlers for XHS MCP Server\n */\n\n\n\n\n\n\n\n\n\n\nclass ToolHandlers {\n authService;\n feedService;\n publishService;\n noteService;\n browserManager;\n constructor() {\n const config = (0,shared_config/* getConfig */.zj)();\n this.browserManager = new browser_manager/* BrowserManager */.Gd(config);\n this.authService = new AuthService(config, this.browserManager);\n this.feedService = new FeedService(config, this.browserManager);\n this.publishService = new PublishService(config, this.browserManager);\n this.noteService = new note_service.NoteService(config, this.browserManager);\n }\n async handleAuthLogin(browserPath) {\n // Start login process in background and return immediately\n // This follows the \"instant response\" pattern described in README\n this.authService.login(browserPath).catch((error) => {\n (0,utils/* safeErrorHandler */.ah)(error, 'Background login error', logger/* logger */.v);\n });\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n success: true,\n message: 'Login process started. A browser window will open for you to complete the login.',\n status: 'login_started',\n action: 'browser_opened',\n instructions: [\n '1. Complete the login process in the opened browser window',\n '2. Scan QR code or enter your credentials',\n '3. Login will be automatically verified and cookies saved',\n '4. Use xhs_auth_status to check if login completed',\n ],\n note: 'The login process runs in the background. You can continue using other tools while login completes.',\n }, null, 2),\n },\n ],\n };\n }\n async handleAuthLogout() {\n const result = await this.authService.logout();\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleAuthStatus(browserPath) {\n const result = await this.authService.checkStatus(browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleDiscoverFeeds(browserPath) {\n const result = await this.feedService.getFeedList(browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleSearchNote(keyword, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ keyword }, ['keyword']);\n const result = await this.feedService.searchFeeds(keyword, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleGetNoteDetail(feedId, xsecToken, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ feedId, xsecToken }, ['feedId', 'xsecToken']);\n const result = await this.feedService.getFeedDetail(feedId, xsecToken, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleCommentOnNote(feedId, xsecToken, note, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ feedId, xsecToken, note }, ['feedId', 'xsecToken', 'note']);\n const result = await this.feedService.commentOnFeed(feedId, xsecToken, note, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handlePublishContent(type, title, content, mediaPaths, tags, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ type, title, content, mediaPaths }, [\n 'type',\n 'title',\n 'content',\n 'mediaPaths',\n ]);\n // Validate content type\n if (type !== 'image' && type !== 'video') {\n throw new Error('Content type must be \"image\" or \"video\"');\n }\n // Validate parameter constraints using width-aware title validation\n assertTitleWidthValid(title);\n if (content.length > 1000) {\n throw new Error('Content must be 1000 characters or less');\n }\n // Execute unified publishing process\n const result = await this.publishService.publishContent(type, title, content, mediaPaths, tags, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleGetUserNotes(limit, cursor, browserPath) {\n const result = await this.noteService.getUserNotes(limit, cursor, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleDeleteNote(noteId, lastPublished, browserPath) {\n if (lastPublished) {\n const result = await this.noteService.deleteLastPublishedNote(browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n else if (noteId) {\n const result = await this.noteService.deleteNote(noteId, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n else {\n throw new Error('Either note_id or last_published must be specified');\n }\n }\n async handleToolRequest(name, args = {}) {\n try {\n switch (name) {\n case 'xhs_auth_login':\n return await this.handleAuthLogin(args?.browser_path);\n case 'xhs_auth_logout':\n return await this.handleAuthLogout();\n case 'xhs_auth_status':\n return await this.handleAuthStatus(args?.browser_path);\n case 'xhs_discover_feeds':\n return await this.handleDiscoverFeeds(args?.browser_path);\n case 'xhs_search_note':\n return await this.handleSearchNote(args?.keyword, args?.browser_path);\n case 'xhs_get_note_detail':\n return await this.handleGetNoteDetail(args?.feed_id, args?.xsec_token, args?.browser_path);\n case 'xhs_comment_on_note':\n return await this.handleCommentOnNote(args?.feed_id, args?.xsec_token, args?.note, args?.browser_path);\n case 'xhs_publish_content':\n return await this.handlePublishContent(args?.type, args?.title, args?.content, args?.media_paths, args?.tags, args?.browser_path);\n case 'xhs_get_user_notes':\n return await this.handleGetUserNotes(args?.limit, args?.cursor, args?.browser_path);\n case 'xhs_delete_note':\n return await this.handleDeleteNote(args?.note_id, args?.last_published, args?.browser_path);\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* XHSError */.a_) {\n return (0,utils/* createMcpToolResponse */.q$)(error.toJSON());\n }\n return (0,utils/* createMcpErrorResponse */.mo)(error);\n }\n }\n}\n\n;// ./src/shared/index.ts\n/**\n * Shared utilities, types, and services for XHS MCP Server\n */\n// Configuration and types\n\n\n// Utilities\n\n\n\n\n\n// Error handling and logging\n\n\n// Base service\n\n\n;// ./src/server/handlers/resource.handlers.ts\n/**\n * Resource request handlers for XHS MCP Server\n */\n\n\nclass ResourceHandlers {\n authService;\n constructor() {\n const config = (0,shared_config/* getConfig */.zj)();\n this.authService = new AuthService(config);\n }\n async getCookiesResource() {\n try {\n const cookiesInfo = (0,cookies/* getCookiesInfo */.mL)();\n return JSON.stringify(cookiesInfo, null, 2);\n }\n catch (error) {\n return JSON.stringify({ error: String(error) }, null, 2);\n }\n }\n async getConfigResource() {\n try {\n const configDict = (0,shared_config/* getConfig */.zj)();\n const configWithFramework = {\n ...configDict,\n framework: 'MCP TypeScript',\n version: configDict.server.version,\n };\n return JSON.stringify(configWithFramework, null, 2);\n }\n catch (error) {\n return JSON.stringify({ error: String(error) }, null, 2);\n }\n }\n async getStatusResource() {\n try {\n // Quick status check (but don't fail if it errors)\n let authStatus = { status: 'unknown', error: 'Status check not performed' };\n try {\n authStatus = await this.authService.checkStatus();\n }\n catch (error) {\n authStatus = { status: 'error', error: String(error) };\n }\n const cookiesInfo = (0,cookies/* getCookiesInfo */.mL)();\n const config = (0,shared_config/* getConfig */.zj)();\n const statusData = {\n server: {\n status: 'running',\n name: config.server.name,\n version: config.server.version,\n framework: 'MCP TypeScript',\n },\n authentication: authStatus,\n cookies: {\n fileExists: cookiesInfo.fileExists,\n cookieCount: cookiesInfo.cookieCount,\n },\n capabilities: {\n toolsAvailable: 8,\n promptsAvailable: 0,\n resourcesAvailable: 3,\n },\n };\n return JSON.stringify(statusData, null, 2);\n }\n catch (error) {\n return JSON.stringify({\n server: { status: 'error', error: String(error) },\n framework: 'MCP TypeScript',\n }, null, 2);\n }\n }\n async handleResourceRequest(uri) {\n try {\n let content;\n switch (uri) {\n case 'xhs://cookies':\n content = await this.getCookiesResource();\n break;\n case 'xhs://config':\n content = await this.getConfigResource();\n break;\n case 'xhs://status':\n content = await this.getStatusResource();\n break;\n default:\n throw new Error(`Unknown resource: ${uri}`);\n }\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: content,\n },\n ],\n };\n }\n catch (error) {\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify({ error: String(error) }, null, 2),\n },\n ],\n };\n }\n }\n}\n\n;// ./src/server/schemas/tool.schemas.ts\n/**\n * Tool schemas for XHS MCP Server\n */\nconst XHS_TOOL_SCHEMAS = [\n {\n name: 'xhs_auth_login',\n description: 'Start XiaoHongShu login process.',\n inputSchema: {\n type: 'object',\n properties: {\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_auth_logout',\n description: 'Logout from XiaoHongShu (clears saved cookies).',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n },\n {\n name: 'xhs_auth_status',\n description: 'Check XiaoHongShu login status (fast check with browser).',\n inputSchema: {\n type: 'object',\n properties: {\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_discover_feeds',\n description: 'Get home page feed list.',\n inputSchema: {\n type: 'object',\n properties: {\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_search_note',\n description: 'Search for notes by keyword.',\n inputSchema: {\n type: 'object',\n properties: {\n keyword: {\n type: 'string',\n description: 'Search keyword (required)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['keyword'],\n },\n },\n {\n name: 'xhs_get_note_detail',\n description: 'Get detailed information about a specific note.',\n inputSchema: {\n type: 'object',\n properties: {\n feed_id: {\n type: 'string',\n description: 'Feed ID (required)',\n },\n xsec_token: {\n type: 'string',\n description: 'Security token for the feed (required)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['feed_id', 'xsec_token'],\n },\n },\n {\n name: 'xhs_comment_on_note',\n description: 'Comment on a note.',\n inputSchema: {\n type: 'object',\n properties: {\n feed_id: {\n type: 'string',\n description: 'Feed ID (required)',\n },\n xsec_token: {\n type: 'string',\n description: 'Security token for the feed (required)',\n },\n note: {\n type: 'string',\n description: 'Comment note (required)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['feed_id', 'xsec_token', 'note'],\n },\n },\n {\n name: 'xhs_publish_content',\n description: 'Publish content to XiaoHongShu (supports both images and videos).',\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: ['image', 'video'],\n description: 'Content type: \"image\" for images, \"video\" for videos (required)',\n },\n title: {\n type: 'string',\n description: 'Content title (required, max 20 characters)',\n maxLength: 20,\n },\n content: {\n type: 'string',\n description: 'Content description (required, max 1000 characters)',\n maxLength: 1000,\n },\n media_paths: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of media file paths (required, non-empty). For images: 1-18 image files. For videos: exactly 1 video file.',\n maxItems: 18,\n },\n tags: {\n type: 'string',\n description: 'Comma-separated tags (optional)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['type', 'title', 'content', 'media_paths'],\n },\n },\n {\n name: 'xhs_get_user_notes',\n description: 'Get current user notes list.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Number of notes to fetch (default: 20)',\n },\n cursor: {\n type: 'string',\n description: 'Pagination cursor for next page',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_delete_note',\n description: 'Delete a user note by ID or delete the last published note.',\n inputSchema: {\n type: 'object',\n properties: {\n note_id: {\n type: 'string',\n description: 'Specific note ID to delete (optional if last_published is true)',\n },\n last_published: {\n type: 'boolean',\n description: 'Delete the last published note (optional if note_id is provided)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n];\nconst XHS_RESOURCE_SCHEMAS = [\n {\n uri: 'xhs://cookies',\n name: 'XHS Authentication Cookies',\n description: 'Current XiaoHongShu authentication cookies and info',\n mimeType: 'application/json',\n },\n {\n uri: 'xhs://config',\n name: 'XHS Server Configuration',\n description: 'XHS MCP server configuration',\n mimeType: 'application/json',\n },\n {\n uri: 'xhs://status',\n name: 'XHS Server Status',\n description: 'Current server and authentication status',\n mimeType: 'application/json',\n },\n];\n\n;// ./src/server/mcp.server.ts\n/**\n * MCP Server for XiaoHongShu Operations\n */\n\n\n\n\n\n\n\nclass XHSMCPServer {\n server;\n toolHandlers;\n resourceHandlers;\n config;\n constructor() {\n this.config = (0,shared_config/* getConfig */.zj)();\n this.toolHandlers = new ToolHandlers();\n this.resourceHandlers = new ResourceHandlers();\n this.server = new esm_server/* Server */.g({\n name: this.config.server.name,\n version: this.config.server.version,\n }, {\n capabilities: {\n tools: {},\n resources: {},\n },\n });\n this.setupToolHandlers();\n this.setupResourceHandlers();\n }\n setupToolHandlers() {\n this.server.setRequestHandler(types/* CallToolRequestSchema */.FT, async (request) => {\n const { name, arguments: args } = request.params;\n return await this.toolHandlers.handleToolRequest(name, args);\n });\n this.server.setRequestHandler(types/* ListToolsRequestSchema */.gW, async () => {\n return {\n tools: XHS_TOOL_SCHEMAS,\n };\n });\n }\n setupResourceHandlers() {\n this.server.setRequestHandler(types/* ListResourcesRequestSchema */.OI, async () => {\n return {\n resources: XHS_RESOURCE_SCHEMAS,\n };\n });\n this.server.setRequestHandler(types/* ReadResourceRequestSchema */.R6, async (request) => {\n const { uri } = request.params;\n return await this.resourceHandlers.handleResourceRequest(uri);\n });\n }\n async start() {\n const transport = new stdio/* StdioServerTransport */.S();\n await this.server.connect(transport);\n // Don't log to stderr in stdio mode to avoid interfering with MCP protocol\n }\n}\n\n;// external \"express\"\nconst external_express_namespaceObject = require(\"express\");\nvar external_express_default = /*#__PURE__*/__webpack_require__.n(external_express_namespaceObject);\n;// external \"cors\"\nconst external_cors_namespaceObject = require(\"cors\");\nvar external_cors_default = /*#__PURE__*/__webpack_require__.n(external_cors_namespaceObject);\n// EXTERNAL MODULE: external \"node:crypto\"\nvar external_node_crypto_ = __webpack_require__(7598);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/sse.js\nvar sse = __webpack_require__(4375);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/streamableHttp.js\nvar streamableHttp = __webpack_require__(8144);\n;// ./src/server/http.server.ts\n/**\n * HTTP Server with SSE and Streamable HTTP Transport Support\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\nclass XHSHTTPMCPServer {\n app;\n config;\n toolHandlers;\n resourceHandlers;\n transports = new Map();\n port;\n constructor(port = 3000) {\n this.port = port;\n this.config = (0,shared_config/* getConfig */.zj)();\n this.toolHandlers = new ToolHandlers();\n this.resourceHandlers = new ResourceHandlers();\n this.app = external_express_default()();\n this.setupMiddleware();\n this.setupRoutes();\n }\n setupMiddleware() {\n // Parse JSON bodies\n this.app.use(external_express_default().json());\n // Configure CORS to expose Mcp-Session-Id header for browser-based clients\n this.app.use(external_cors_default()({\n origin: '*', // Allow all origins - adjust as needed for production\n exposedHeaders: ['Mcp-Session-Id'],\n }));\n }\n setupRoutes() {\n // Streamable HTTP Transport (Protocol version 2025-03-26)\n this.app.all('/mcp', this.handleStreamableHTTP.bind(this));\n // Deprecated HTTP+SSE Transport (Protocol version 2024-11-05)\n this.app.get('/sse', this.handleSSEConnection.bind(this));\n this.app.post('/messages', this.handleSSEMessage.bind(this));\n // Health check endpoint\n this.app.get('/health', (req, res) => {\n res.json({\n status: 'healthy',\n server: this.config.server.name,\n version: this.config.server.version,\n transports: ['streamable-http', 'sse'],\n });\n });\n }\n async handleStreamableHTTP(req, res) {\n logger/* logger */.v.info(`Received ${req.method} request to /mcp`);\n try {\n // Check for existing session ID\n const sessionId = req.headers['mcp-session-id'];\n let transport;\n if (sessionId && this.transports.has(sessionId)) {\n const existingTransport = this.transports.get(sessionId);\n if (existingTransport instanceof streamableHttp/* StreamableHTTPServerTransport */.D) {\n transport = existingTransport;\n }\n else {\n res.status(400).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: Session exists but uses a different transport protocol',\n },\n id: null,\n });\n return;\n }\n }\n else if (!sessionId && req.method === 'POST' && (0,types/* isInitializeRequest */.eK)(req.body)) {\n // Create new Streamable HTTP transport\n transport = new streamableHttp/* StreamableHTTPServerTransport */.D({\n sessionIdGenerator: () => (0,external_node_crypto_.randomUUID)(),\n onsessioninitialized: (sessionId) => {\n logger/* logger */.v.info(`StreamableHTTP session initialized with ID: ${sessionId}`);\n this.transports.set(sessionId, transport);\n },\n onsessionclosed: (sessionId) => {\n logger/* logger */.v.info(`StreamableHTTP session closed: ${sessionId}`);\n this.transports.delete(sessionId);\n },\n });\n // Set up onclose handler to clean up transport when closed\n transport.onclose = () => {\n const sid = transport.sessionId;\n if (sid && this.transports.has(sid)) {\n logger/* logger */.v.info(`Transport closed for session ${sid}, removing from transports map`);\n this.transports.delete(sid);\n }\n };\n // Connect the transport to the MCP server\n const server = this.createMCPServer();\n await server.connect(transport);\n }\n else {\n // Invalid request - no session ID or not initialization request\n res.status(400).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: No valid session ID provided',\n },\n id: null,\n });\n return;\n }\n // Handle the request with the transport\n await transport.handleRequest(req, res, req.body);\n }\n catch (error) {\n logger/* logger */.v.error('Error handling Streamable HTTP request:', error);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n }\n async handleSSEConnection(req, res) {\n logger/* logger */.v.info('Received GET request to /sse (deprecated SSE transport)');\n try {\n const transport = new sse/* SSEServerTransport */.K('/messages', res);\n this.transports.set(transport.sessionId, transport);\n res.on('close', () => {\n this.transports.delete(transport.sessionId);\n });\n const server = this.createMCPServer();\n await server.connect(transport);\n }\n catch (error) {\n logger/* logger */.v.error('Error handling SSE connection:', error);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n }\n async handleSSEMessage(req, res) {\n const sessionId = req.query.sessionId;\n try {\n const transport = this.transports.get(sessionId);\n if (!transport || !(transport instanceof sse/* SSEServerTransport */.K)) {\n res.status(400).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: Session exists but uses a different transport protocol',\n },\n id: null,\n });\n return;\n }\n await transport.handlePostMessage(req, res, req.body);\n }\n catch (error) {\n logger/* logger */.v.error('Error handling SSE message:', error);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n }\n createMCPServer() {\n const server = new esm_server/* Server */.g({\n name: this.config.server.name,\n version: this.config.server.version,\n }, {\n capabilities: {\n tools: {},\n resources: {},\n },\n });\n // Setup tool handlers\n server.setRequestHandler(types/* CallToolRequestSchema */.FT, async (request) => {\n const { name, arguments: args } = request.params;\n return await this.toolHandlers.handleToolRequest(name, args);\n });\n server.setRequestHandler(types/* ListToolsRequestSchema */.gW, async () => {\n return {\n tools: XHS_TOOL_SCHEMAS,\n };\n });\n // Setup resource handlers\n server.setRequestHandler(types/* ListResourcesRequestSchema */.OI, async () => {\n return {\n resources: XHS_RESOURCE_SCHEMAS,\n };\n });\n server.setRequestHandler(types/* ReadResourceRequestSchema */.R6, async (request) => {\n const { uri } = request.params;\n return await this.resourceHandlers.handleResourceRequest(uri);\n });\n return server;\n }\n async start() {\n return new Promise((resolve, reject) => {\n const server = this.app.listen(this.port, (error) => {\n if (error) {\n logger/* logger */.v.error('Failed to start HTTP server:', error);\n reject(error);\n return;\n }\n console.log(`XHS MCP HTTP Server listening on port ${this.port}`);\n console.log(`\n==============================================\nSUPPORTED TRANSPORT OPTIONS:\n\n1. Streamable HTTP (Protocol version: 2025-03-26)\n Endpoint: /mcp\n Methods: GET, POST, DELETE\n Usage:\n - Initialize with POST to /mcp\n - Establish SSE stream with GET to /mcp\n - Send requests with POST to /mcp\n - Terminate session with DELETE to /mcp\n\n2. HTTP + SSE (Protocol version: 2024-11-05)\n Endpoints: /sse (GET) and /messages (POST)\n Usage:\n - Establish SSE stream with GET to /sse\n - Send requests with POST to /messages?sessionId=<id>\n\n3. Health Check\n Endpoint: /health\n Method: GET\n Usage: Check server status and supported transports\n==============================================\n`);\n resolve();\n });\n // Handle server shutdown\n process.on('SIGINT', async () => {\n logger/* logger */.v.info('Shutting down HTTP server...');\n for (const [sessionId, transport] of this.transports) {\n try {\n logger/* logger */.v.info(`Closing transport for session ${sessionId}`);\n await transport.close();\n }\n catch (error) {\n logger/* logger */.v.error(`Error closing transport for session ${sessionId}:`, error);\n }\n }\n this.transports.clear();\n server.close(() => {\n logger/* logger */.v.info('HTTP server shutdown complete');\n process.exit(0);\n });\n });\n process.on('SIGTERM', async () => {\n logger/* logger */.v.info('Shutting down HTTP server...');\n for (const [sessionId, transport] of this.transports) {\n try {\n logger/* logger */.v.info(`Closing transport for session ${sessionId}`);\n await transport.close();\n }\n catch (error) {\n logger/* logger */.v.error(`Error closing transport for session ${sessionId}:`, error);\n }\n }\n this.transports.clear();\n server.close(() => {\n logger/* logger */.v.info('HTTP server shutdown complete');\n process.exit(0);\n });\n });\n });\n }\n async stop() {\n // Close all active transports\n for (const [sessionId, transport] of this.transports) {\n try {\n await transport.close();\n }\n catch (error) {\n logger/* logger */.v.error(`Error closing transport for session ${sessionId}:`, error);\n }\n }\n this.transports.clear();\n }\n}\n\n;// ./src/server/handlers/index.ts\n/**\n * Request handlers for XHS MCP Server\n */\n\n\n\n;// ./src/server/index.ts\n/**\n * Server implementation for XHS MCP Server\n */\n\n\n\n\n;// ./src/cli/cli.ts\n//#!/usr/bin/env node\n/**\n * Unified CLI for XiaoHongShu operations\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * CLI utility functions\n */\nclass CLIUtils {\n program;\n constructor(program) {\n this.program = program;\n }\n formatErrorMessage(error) {\n const raw = error instanceof Error ? (error.stack ?? error.message) : String(error);\n // Handle specific error patterns\n if (/Executable doesn't exist|puppeteer browsers install/i.test(raw)) {\n return 'Chromium is not installed. Run: npx puppeteer browsers install chrome or xhs-mcp browser';\n }\n // For user-facing errors, just return the message without stack trace\n if (error instanceof Error) {\n // Check if it's a known error type that should show just the message\n if (error.message.includes('Either --note-id or --last-published must be specified') ||\n error.message.includes('Please specify either') ||\n error.message.includes('User not logged in') ||\n error.message.includes('Note not found') ||\n error.message.includes('Delete button not found')) {\n return error.message;\n }\n // For other errors, show a cleaner version\n const condensed = raw\n .replace(/[\\s\\S]*?Looks like Puppeteer[\\s\\S]*?Please run the following command to download new browsers:[\\s\\S]*?npx puppeteer browsers install[\\s\\S]*?(Puppeteer Team[\\s\\S]*?)*?/m, '')\n .replace(/[\\u2500-\\u257F]+/g, '') // box-drawing characters\n .replace(/\\s+at\\s+.*$/gm, '') // Remove stack trace lines\n .trim();\n return condensed || error.message;\n }\n return String(error);\n }\n writeJson(output, exitCode = 0) {\n const compact = this.program.getOptionValue?.('compact') === true;\n const json = compact ? JSON.stringify(output) : JSON.stringify(output, null, 2);\n process.stdout.write(`${json}\\n`);\n // Flush stdout before exiting to ensure output is visible\n if (process.stdout.writable) {\n process.stdout.end();\n }\n process.exit(exitCode);\n }\n printSuccess(result, message) {\n // If result already has success field, print it directly\n if (result && typeof result === 'object' && 'success' in result) {\n this.writeJson(result, 0);\n }\n else {\n // Otherwise, wrap it\n const payload = {\n success: true,\n message: message ?? result?.message ?? undefined,\n data: result,\n };\n this.writeJson(payload, 0);\n }\n }\n printError(error, code) {\n const message = this.formatErrorMessage(error);\n const payload = { success: false, message, code: code ?? undefined, status: 'error' };\n this.writeJson(payload, 1);\n }\n printUsageError(command, message) {\n const payload = {\n success: false,\n message,\n status: 'error',\n usage: `Use 'xhs-mcp ${command} --help' for more information`,\n };\n this.writeJson(payload, 1);\n }\n}\nasync function main() {\n const config = (0,shared_config/* getConfig */.zj)();\n const program = new external_commander_namespaceObject.Command();\n const utils = new CLIUtils(program);\n program\n .name('xhs-mcp')\n .description('XiaoHongShu CLI with subcommands')\n .option('--compact', 'Output compact one-line JSON (no pretty print)')\n .showHelpAfterError();\n program\n .command('login')\n .description('Start XiaoHongShu login flow (opens browser, saves cookies)')\n .option('-t, --timeout <seconds>', 'Login timeout in seconds', `${config.browser.loginTimeout}`)\n .action(async (opts) => {\n const browserPath = undefined;\n const timeoutSec = opts.timeout ? parseInt(opts.timeout, 10) : config.browser.loginTimeout;\n const authService = new AuthService(config);\n try {\n const result = await authService.login(browserPath, timeoutSec);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('logout')\n .description('Logout from XiaoHongShu and clear saved cookies')\n .action(async () => {\n const authService = new AuthService(config);\n try {\n const result = await authService.logout();\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('status')\n .description('Check current XiaoHongShu login status')\n .action(async () => {\n const browserPath = undefined;\n const authService = new AuthService(config);\n try {\n const result = await authService.checkStatus(browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('browser')\n .description('Ensure Puppeteer Chromium is installed and launchable; installs if missing')\n .option('--with-deps', 'Install OS-level dependencies as well (may require sudo)')\n .action(async (opts) => {\n async function canLaunchChromium() {\n try {\n // Get the executable path before launching\n const executablePath = external_puppeteer_default().executablePath();\n const browser = await external_puppeteer_default().launch({ headless: true });\n await browser.close();\n return { canLaunch: true, executablePath };\n }\n catch {\n return { canLaunch: false };\n }\n }\n const browserInfo = await canLaunchChromium();\n if (browserInfo.canLaunch) {\n utils.printSuccess({\n installed: true,\n executablePath: browserInfo.executablePath,\n }, 'Chromium is ready');\n return;\n }\n const args = ['puppeteer', 'browsers', 'install', 'chrome'];\n if (opts.withDeps)\n args.push('--with-deps');\n const result = (0,external_node_child_process_namespaceObject.spawnSync)('npx', args, { stdio: 'inherit', env: process.env });\n const afterInstallInfo = await canLaunchChromium();\n if (afterInstallInfo.canLaunch) {\n utils.printSuccess({\n installed: true,\n executablePath: afterInstallInfo.executablePath,\n exitCode: result.status ?? null,\n }, 'Chromium installed and ready');\n }\n else {\n utils.printError(new Error('Failed to install or launch Chromium'));\n }\n });\n // Feeds: discover\n program\n .command('feeds')\n .description('Discover home page feeds')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const feedService = new FeedService(config);\n try {\n const result = await feedService.getFeedList(opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // Feeds: search note\n program\n .command('search')\n .description('Search notes by keyword')\n .requiredOption('-k, --keyword <keyword>', 'Search keyword')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const feedService = new FeedService(config);\n try {\n const result = await feedService.searchFeeds(opts.keyword, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // User Notes: unified command with subcommands\n const userNoteCommand = program\n .command('usernote')\n .description(\"Current user's note management operations\");\n // User Note list subcommand\n userNoteCommand\n .command('list')\n .description(\"List current user's published notes\")\n .option('-l, --limit <number>', 'Maximum number of notes to retrieve', '20')\n .option('-c, --cursor <cursor>', 'Pagination cursor for next page')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const noteService = new note_service.NoteService(config);\n try {\n const limit = parseInt(opts.limit) || 20;\n const result = await noteService.getUserNotes(limit, opts.cursor, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // User Note delete subcommand\n userNoteCommand\n .command('delete')\n .description('Delete user notes')\n .option('--note-id <id>', 'Specific note ID to delete')\n .option('--last-published', 'Delete the last published note')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const noteService = new note_service.NoteService(config);\n try {\n if (opts.lastPublished) {\n const result = await noteService.deleteLastPublishedNote(opts.browserPath);\n utils.printSuccess(result);\n }\n else if (opts.noteId) {\n const result = await noteService.deleteNote(opts.noteId, opts.browserPath);\n utils.printSuccess(result);\n }\n else {\n // Show help instead of JSON error when no arguments provided\n console.log('Usage: xhs-mcp usernote delete [options]\\n');\n console.log('Delete user notes\\n');\n console.log('Options:');\n console.log(' --note-id <id> Specific note ID to delete');\n console.log(' --last-published Delete the last published note');\n console.log(' -b, --browser-path <path> Custom browser binary path');\n console.log(' -h, --help display help for command');\n process.exit(0);\n }\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // Feeds: comment on note\n program\n .command('comment')\n .description('Comment on a note')\n .requiredOption('--feed-id <id>', 'Feed ID')\n .requiredOption('--xsec-token <token>', 'Security token for the feed')\n .requiredOption('-n, --note <text>', 'Comment content')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const feedService = new FeedService(config);\n try {\n const result = await feedService.commentOnFeed(opts.feedId, opts.xsecToken, opts.note, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // Publishing: unified publish command\n program\n .command('publish')\n .description('Publish content to XiaoHongShu (supports both images and videos)')\n .requiredOption('-t, --type <type>', 'Content type: \"image\" for images, \"video\" for videos')\n .requiredOption('--title <title>', 'Content title (<= 20 chars)')\n .requiredOption('--content <content>', 'Content description (<= 1000 chars)')\n .requiredOption('-m, --media <paths>', 'Comma-separated media file paths (1-18 images for image posts, exactly 1 video for videos)')\n .option('--tags <tags>', 'Comma-separated tags')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const publishService = new PublishService(config);\n try {\n if (opts.type !== 'image' && opts.type !== 'video') {\n utils.printError(new Error('Type must be \"image\" or \"video\"'));\n return;\n }\n const mediaPaths = opts.media\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const result = await publishService.publishContent(opts.type, opts.title, opts.content, mediaPaths, opts.tags, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('mcp')\n .description('Start XHS MCP server (stdio or http mode)')\n .option('-m, --mode <mode>', 'Server mode: stdio or http', 'stdio')\n .option('-p, --port <port>', 'HTTP server port (only for http mode)', '3000')\n .action(async (opts) => {\n try {\n if (opts.mode === 'http') {\n const port = opts.port ? parseInt(opts.port, 10) : 3000;\n const httpServer = new XHSHTTPMCPServer(port);\n await httpServer.start();\n }\n else {\n // In stdio mode, we must not output anything to stdout/stderr except MCP protocol messages\n // This prevents interference with MCP communication\n const server = new XHSMCPServer();\n await server.start();\n }\n }\n catch (error) {\n // Only log to stderr if logging is explicitly enabled\n if (process.env.XHS_ENABLE_LOGGING === 'true') {\n process.stderr.write(`Server failed to start: ${error}\\n`);\n }\n process.exit(1);\n }\n });\n // List MCP tools\n program\n .command('tools')\n .description('List available MCP tools')\n .option('-j, --json', 'Output in JSON format')\n .option('-d, --detailed', 'Show detailed tool information')\n .action(async (opts) => {\n try {\n const toolSchemas = XHS_TOOL_SCHEMAS;\n if (opts.json) {\n if (opts.detailed) {\n console.log(JSON.stringify(toolSchemas, null, 2));\n }\n else {\n const toolNames = toolSchemas.map((tool) => ({\n name: tool.name,\n description: tool.description,\n }));\n console.log(JSON.stringify(toolNames, null, 2));\n }\n }\n else {\n console.log('\\n📋 Available MCP Tools:\\n');\n toolSchemas.forEach((tool, index) => {\n console.log(`${index + 1}. ${tool.name}`);\n console.log(` ${tool.description}`);\n if (opts.detailed) {\n const required = tool.inputSchema.required ?? [];\n const properties = tool.inputSchema.properties ?? {};\n if (Object.keys(properties).length > 0) {\n console.log(' Parameters:');\n Object.entries(properties).forEach(([key, prop]) => {\n const requiredMark = required.includes(key) ? ' (required)' : ' (optional)';\n const propDesc = prop.description;\n console.log(` - ${key}: ${propDesc ?? 'No description'}${requiredMark}`);\n });\n }\n }\n console.log('');\n });\n console.log(`Total: ${toolSchemas.length} tools available`);\n console.log('\\nUse --detailed for parameter information');\n console.log('Use --json for machine-readable output');\n }\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program.parseAsync(process.argv);\n}\n// Handle graceful shutdown for MCP server mode\nprocess.on('SIGINT', () => {\n // Don't log to stderr in stdio mode to avoid interfering with MCP protocol\n process.exit(0);\n});\nprocess.on('SIGTERM', () => {\n // Don't log to stderr in stdio mode to avoid interfering with MCP protocol\n process.exit(0);\n});\n// Start the CLI\nmain().catch((error) => {\n // Only log to stderr if logging is explicitly enabled\n if (process.env.XHS_ENABLE_LOGGING === 'true') {\n process.stderr.write(`Fatal error: ${error}\\n`);\n }\n process.exit(1);\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LEVBQUUsRUFBRSxDQUFDO1FBQzNDLENBQUM7UUFFRCxPQUFPO1FBQ1AsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ25FLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUM3QyxDQUFDO1FBRUQsTUFBTTtRQUNOLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3pGLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUM3QyxDQUFDO1FBRUQsTUFBTTtRQUNOLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNuRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDN0MsQ0FBQztRQUVELE9BQU87UUFDUCxJQUNFLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxJQUFJO1lBQ25CLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxJQUFJLEVBQ25CLENBQUM7WUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUM7UUFDOUMsQ0FBQztRQUVELE1BQU07UUFDTixJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUM3QyxDQUFDO1FBRUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxhQUFhLENBQUMsUUFBZ0I7UUFDbEMsc0JBQXNCO1FBQ3RCLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDMUMsTUFBTSxJQUFJLHVDQUFpQixDQUFDLDZCQUE2QixRQUFRLEVBQUUsRUFBRTtnQkFDbkUsR0FBRyxFQUFFLFFBQVE7Z0JBQ2IsVUFBVSxFQUFFLHlDQUF5QzthQUN0RCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsNkJBQTZCO1FBQzdCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqRCxNQUFNLFNBQVMsR0FBRyx1QkFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFL0MsdUNBQXVDO1FBQ3ZDLElBQUksMkJBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQzFCLE1BQU0sS0FBSyxHQUFHLHlCQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbEMsb0JBQU0sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLFNBQVMsRUFBRSxDQUFDLENBQUM7WUFDakQsT0FBTztnQkFDTCxXQUFXLEVBQUUsUUFBUTtnQkFDckIsU0FBUztnQkFDVCxNQUFNLEVBQUUsSUFBSTtnQkFDWixRQUFRLEVBQUUsS0FBSyxDQUFDLElBQUk7YUFDckIsQ0FBQztRQUNKLENBQUM7UUFFRCxvQkFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUVwRCxJQUFJLENBQUM7WUFDSCw4QkFBOEI7WUFDOUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztZQUN6QyxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUVyRSxNQUFNLFFBQVEsR0FBRyxNQUFNLDZCQUFLLENBQUMsUUFBUSxFQUFFO2dCQUNyQyxNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU07Z0JBQ3pCLE9BQU8sRUFBRTtvQkFDUCxZQUFZLEVBQUUsb0VBQW9FO2lCQUNuRjthQUNGLENBQUMsQ0FBQztZQUVILFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUV4QixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUNqQixNQUFNLElBQUksdUNBQWlCLENBQ3pCLGtDQUFrQyxRQUFRLENBQUMsTUFBTSxJQUFJLFFBQVEsQ0FBQyxVQUFVLEVBQUUsRUFDMUU7b0JBQ0UsR0FBRyxFQUFFLFFBQVE7b0JBQ2IsVUFBVSxFQUFFLFFBQVEsQ0FBQyxNQUFNO29CQUMzQixVQUFVLEVBQUUsUUFBUSxDQUFDLFVBQVU7aUJBQ2hDLENBQ0YsQ0FBQztZQUNKLENBQUM7WUFFRCxvQ0FBb0M7WUFDcEMsTUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUM3RCxJQUFJLGFBQWEsSUFBSSxRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNoRSxNQUFNLElBQUksdUNBQWlCLENBQ3pCLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUN0RSxDQUFDLENBQ0YsWUFBWSxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUM3RDtvQkFDRSxHQUFHLEVBQUUsUUFBUTtvQkFDYixRQUFRLEVBQUUsUUFBUSxDQUFDLGFBQWEsQ0FBQztvQkFDakMsT0FBTyxFQUFFLElBQUksQ0FBQyxXQUFXO29CQUN6QixVQUFVLEVBQUUsbURBQW1EO2lCQUNoRSxDQUNGLENBQUM7WUFDSixDQUFDO1lBRUQsaUJBQWlCO1lBQ2pCLE1BQU0sV0FBVyxHQUFHLE1BQU0sUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2pELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFFeEMscUJBQXFCO1lBQ3JCLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3JDLE1BQU0sSUFBSSx1Q0FBaUIsQ0FDekIsOEJBQThCLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQ2hGLElBQUksQ0FBQyxXQUFXO29CQUNoQixJQUFJO29CQUNKLElBQUksQ0FDTCxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUNqQjtvQkFDRSxHQUFHLEVBQUUsUUFBUTtvQkFDYixRQUFRLEVBQUUsTUFBTSxDQUFDLE1BQU07b0JBQ3ZCLE9BQU8sRUFBRSxJQUFJLENBQUMsV0FBVztpQkFDMUIsQ0FDRixDQUFDO1lBQ0osQ0FBQztZQUVELGtDQUFrQztZQUNsQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDeEIsTUFBTSxJQUFJLHVDQUFpQixDQUFDLHlDQUF5QyxRQUFRLEVBQUUsRUFBRTtvQkFDL0UsR0FBRyxFQUFFLFFBQVE7b0JBQ2IsVUFBVSxFQUFFLGtEQUFrRDtpQkFDL0QsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELGVBQWU7WUFDZiw4QkFBYSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUVqQyxvQkFBTSxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsU0FBUyxLQUFLLE1BQU0sQ0FBQyxNQUFNLFNBQVMsQ0FBQyxDQUFDO1lBRXJGLE9BQU87Z0JBQ0wsV0FBVyxFQUFFLFFBQVE7Z0JBQ3JCLFNBQVM7Z0JBQ1QsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsUUFBUSxFQUFFLE1BQU0sQ0FBQyxNQUFNO2FBQ3hCLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxZQUFZLHVDQUFpQixFQUFFLENBQUM7Z0JBQ3ZDLE1BQU0sS0FBSyxDQUFDO1lBQ2QsQ0FBQztZQUVELHFCQUFxQjtZQUNyQixJQUFJLEtBQUssWUFBWSxLQUFLLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUUsQ0FBQztnQkFDMUQsTUFBTSxJQUFJLHVDQUFpQixDQUN6QixnQ0FBZ0MsSUFBSSxDQUFDLE9BQU8sT0FBTyxRQUFRLEVBQUUsRUFDN0Q7b0JBQ0UsR0FBRyxFQUFFLFFBQVE7b0JBQ2IsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO29CQUNyQixVQUFVLEVBQUUsbURBQW1EO2lCQUNoRSxFQUNELEtBQUssQ0FDTixDQUFDO1lBQ0osQ0FBQztZQUVELE1BQU0sSUFBSSx1Q0FBaUIsQ0FDekIsNkJBQTZCLFFBQVEsRUFBRSxFQUN2QztnQkFDRSxHQUFHLEVBQUUsUUFBUTthQUNkLEVBQ0QsS0FBYyxDQUNmLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBQyxTQUFtQjtRQUN0QyxrQ0FBa0M7UUFDbEMsTUFBTSxnQkFBZ0IsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FDN0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUMzRCxDQUFDO1FBRUYsTUFBTSxPQUFPLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFcEQsTUFBTSxjQUFjLEdBQXFCLEVBQUUsQ0FBQztRQUM1QyxNQUFNLE1BQU0sR0FBeUMsRUFBRSxDQUFDO1FBRXhELE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUN6QixJQUFJLE9BQU8sSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDdEIsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBYyxFQUFFLENBQUMsQ0FBQztZQUNqRSxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM5QixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCx1REFBdUQ7UUFDdkQsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ25GLE1BQU0sSUFBSSx1Q0FBaUIsQ0FDekIsc0JBQXNCLE1BQU0sQ0FBQyxNQUFNLE9BQU8sU0FBUyxDQUFDLE1BQU0sYUFBYSxhQUFhLEVBQUUsRUFDdEY7Z0JBQ0UsVUFBVSxFQUFFLFNBQVMsQ0FBQyxNQUFNO2dCQUM1QixXQUFXLEVBQUUsTUFBTSxDQUFDLE1BQU07Z0JBQzFCLFlBQVksRUFBRSxjQUFjLENBQUMsTUFBTTtnQkFDbkMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7YUFDckMsQ0FDRixDQUFDO1FBQ0osQ0FBQztRQUVELE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxVQUFvQjtRQUMxQyxNQUFNLFVBQVUsR0FBYSxFQUFFLENBQUM7UUFDaEMsTUFBTSxjQUFjLEdBQWEsRUFBRSxDQUFDO1FBRXBDLGlDQUFpQztRQUNqQyxLQUFLLE1BQU0sSUFBSSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQzlCLElBQUksZUFBZSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNyQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzVCLENBQUM7aUJBQU0sQ0FBQztnQkFDTiw2QkFBNkI7Z0JBQzdCLElBQUksQ0FBQywyQkFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQ3RCLE1BQU0sSUFBSSx1Q0FBaUIsQ0FBQywrQkFBK0IsSUFBSSxFQUFFLEVBQUU7d0JBQ2pFLElBQUk7d0JBQ0osVUFBVSxFQUFFLHdEQUF3RDtxQkFDckUsQ0FBQyxDQUFDO2dCQUNMLENBQUM7Z0JBQ0QsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4QixDQUFDO1FBQ0gsQ0FBQztRQUVELHVCQUF1QjtRQUN2QixJQUFJLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDOUIsb0JBQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxjQUFjLENBQUMsTUFBTSxzQkFBc0IsQ0FBQyxDQUFDO1lBQ3pFLE1BQU0sZUFBZSxHQUFHLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUNsRSxNQUFNLGVBQWUsR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDaEUsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLGVBQWUsQ0FBQyxDQUFDO1lBRXBDLHVCQUF1QjtZQUN2QixNQUFNLFdBQVcsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDO1lBQ25FLE1BQU0sUUFBUSxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUNqRSxvQkFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLFFBQVEscUJBQXFCLFdBQVcsZ0JBQWdCLENBQUMsQ0FBQztRQUN2RixDQUFDO1FBRUQsSUFBSSxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzVCLE1BQU0sSUFBSSx1Q0FBaUIsQ0FBQyx1QkFBdUIsRUFBRTtnQkFDbkQsYUFBYSxFQUFFLFVBQVUsQ0FBQyxNQUFNO2dCQUNoQyxVQUFVLEVBQUUseURBQXlEO2FBQ3RFLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxVQUFVO1FBQ1IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3RCLENBQUM7Q0FDRjtBQUVELDRCQUE0QjtBQUM1QixJQUFJLGlCQUFpQixHQUEyQixJQUFJLENBQUM7QUFFOUMsU0FBUyxrQkFBa0IsQ0FBQyxPQUFnQjtJQUNqRCxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxPQUFPLElBQUksaUJBQWlCLENBQUMsVUFBVSxFQUFFLEtBQUssT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUNsRixpQkFBaUIsR0FBRyxJQUFJLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBQ0QsT0FBTyxpQkFBaUIsQ0FBQztBQUMzQixDQUFDOzs7OztBQ3hXRDs7R0FFRztBQUlnRDtBQUNLO0FBRVg7QUFDRjtBQUNxQjtBQUM4QztBQUU5RyxpQ0FBaUM7QUFDMUIsTUFBTSxjQUFjLEdBQUc7SUFDNUIsU0FBUyxFQUFFLElBQUk7SUFDZixVQUFVLEVBQUUsSUFBSTtJQUNoQixnQkFBZ0IsRUFBRSxLQUFLO0lBQ3ZCLFlBQVksRUFBRSxJQUFJO0lBQ2xCLFlBQVksRUFBRSxJQUFJO0lBQ2xCLFlBQVksRUFBRSxJQUFJO0lBQ2xCLGdCQUFnQixFQUFFLElBQUk7SUFDdEIsZ0JBQWdCLEVBQUUsSUFBSTtJQUN0QixrQkFBa0IsRUFBRSxNQUFNLEVBQUUsWUFBWTtJQUN4QyxrQkFBa0IsRUFBRSxNQUFNLEVBQUUsWUFBWTtDQUNoQyxDQUFDO0FBRUosTUFBTSxTQUFTLEdBQUc7SUFDdkIsVUFBVSxFQUFFLHVDQUFxQixDQUFDLFVBQVU7SUFDNUMsa0JBQWtCLEVBQUUseUNBQXVCLENBQUMsT0FBTztJQUNuRCxnQkFBZ0IsRUFBRSx5Q0FBdUIsQ0FBQyxLQUFLO0lBQy9DLHFCQUFxQixFQUFFLHlDQUF1QixDQUFDLFVBQVU7SUFDekQscUJBQXFCLEVBQUU7UUFDckIsa0JBQWtCO1FBQ2xCLHNCQUFzQjtRQUN0QixjQUFjO1FBQ2QscUJBQXFCO1FBQ3JCLGtCQUFrQjtLQUNuQjtJQUNELGVBQWUsRUFBRSx5Q0FBdUIsQ0FBQyxLQUFLO0lBQzlDLHVCQUF1QixFQUFFO1FBQ3ZCLG9CQUFvQjtRQUNwQixZQUFZO1FBQ1osaUJBQWlCO1FBQ2pCLHlCQUF5QjtRQUN6QixvQkFBb0I7S0FDckI7Q0FDTyxDQUFDO0FBRUosTUFBTSxhQUFhLEdBQUcsc0NBQW9CLENBQUM7QUFHM0MsTUFBZSxrQkFBbUIsU0FBUSwrQkFBVztJQUNoRCxlQUFlLENBQWtCO0lBRTNDLFlBQVksTUFBYyxFQUFFLGNBQStCO1FBQ3pELEtBQUssQ0FBQyxNQUFNLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQseURBQXlEO0lBQy9DLEtBQUssQ0FBQyxzQkFBc0IsQ0FDcEMsSUFBVSxFQUNWLFNBQTRCO1FBRTVCLEtBQUssTUFBTSxRQUFRLElBQUksU0FBUyxFQUFFLENBQUM7WUFDakMsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZDLElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQ1osb0JBQU0sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQ3pELE9BQU8sT0FBTyxDQUFDO1lBQ2pCLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRVMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxPQUFnQjtRQUM3QyxJQUFJLENBQUM7WUFDSCxPQUFPLE1BQU8sT0FBZSxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQVcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMxRixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG9CQUFNLENBQUMsSUFBSSxDQUFDLCtCQUErQixLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ3BELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFUyxLQUFLLENBQUMsaUJBQWlCLENBQy9CLElBQW1CLEVBQ25CLFFBQTJCO1FBRTNCLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDeEIsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVTLEtBQUssQ0FBQyx1QkFBdUIsQ0FDckMsSUFBVSxFQUNWLFNBQTRCLEVBQzVCLFFBQTJCO1FBRTNCLEtBQUssTUFBTSxRQUFRLElBQUksU0FBUyxFQUFFLENBQUM7WUFDakMsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZDLElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQ1osTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQTZCLENBQUMsQ0FBQztnQkFDdEUsSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUMzRCxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7Z0JBQ3hDLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVTLEtBQUssQ0FBQyxnQkFBZ0IsQ0FDOUIsU0FBaUMsRUFDakMsT0FBZSxFQUNmLGdCQUF3QixJQUFJLEVBQzVCLFlBQW9CO1FBRXBCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUU3QixPQUFPLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTLEdBQUcsT0FBTyxFQUFFLENBQUM7WUFDeEMsSUFBSSxNQUFNLFNBQVMsRUFBRSxFQUFFLENBQUM7Z0JBQ3RCLE9BQU87WUFDVCxDQUFDO1lBQ0QsTUFBTSx1QkFBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFFRCxNQUFNLElBQUksa0NBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRVMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFVLEVBQUUsS0FBYTtRQUNqRCwwQ0FBMEM7UUFDMUMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUN4Qix5R0FBeUcsRUFDekcsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQ25CLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLDJEQUEyRDtRQUM3RCxDQUFDO1FBRUQsTUFBTSxjQUFjLEdBQUc7WUFDckIscUJBQXFCLEVBQUUsNkNBQTZDO1lBQ3BFLGVBQWU7WUFDZiwwQkFBMEI7WUFDMUIsa0NBQWtDO1lBQ2xDLDZCQUE2QjtZQUM3QiwrQkFBK0I7WUFDL0Isb0JBQW9CO1lBQ3BCLDZCQUE2QjtZQUM3QixxQkFBcUI7WUFDckIsb0JBQW9CO1lBQ3BCLHVCQUF1QjtZQUN2QixvQkFBb0IsRUFBRSxZQUFZO1lBQ2xDLDZCQUE2QjtZQUM3Qiw2QkFBNkI7WUFDN0IsZ0NBQWdDO1NBQ2pDLENBQUM7UUFFRixLQUFLLE1BQU0sUUFBUSxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQztnQkFDSCxNQUFNLFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQzFDLElBQUksVUFBVSxFQUFFLENBQUM7b0JBQ2YsZ0RBQWdEO29CQUNoRCxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTt3QkFDekIsSUFBSSxFQUFFLElBQUksT0FBTyxFQUFFLENBQUMsY0FBYyxLQUFLLFVBQVUsRUFBRSxDQUFDOzRCQUNsRCxFQUFFLENBQUMsY0FBYyxDQUFDLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQzt3QkFDN0QsQ0FBQztvQkFDSCxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7b0JBQ2YsTUFBTSx1QkFBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUVqQixNQUFNLFNBQVMsR0FBRyxNQUFNLFVBQVUsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO29CQUU1RCxJQUFJLFNBQVMsRUFBRSxDQUFDO3dCQUNkLE1BQU0sVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO3dCQUN6QixNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxpQkFBaUI7d0JBRW5DLDhCQUE4Qjt3QkFDOUIsTUFBTSxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7d0JBQzFDLE1BQU0sVUFBVSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQzt3QkFFcEMsTUFBTSxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO3dCQUM3QixPQUFPO29CQUNULENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLDRCQUE0QjtZQUM5QixDQUFDO1FBQ0gsQ0FBQztRQUVELG9GQUFvRjtRQUNwRixJQUFJLENBQUM7WUFDSCxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUVuRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUMxQyxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNCLElBQUksQ0FBQztvQkFDSCxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBRXpFLHFDQUFxQztvQkFDckMsSUFBSSxJQUFJLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQzt3QkFDekMsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7NEJBQ3pCLElBQUksRUFBRSxJQUFJLE9BQU8sRUFBRSxDQUFDLGNBQWMsS0FBSyxVQUFVLEVBQUUsQ0FBQztnQ0FDbEQsRUFBRSxDQUFDLGNBQWMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7NEJBQzdELENBQUM7d0JBQ0gsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO3dCQUNWLE1BQU0sdUJBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQzt3QkFFakIsTUFBTSxTQUFTLEdBQUcsTUFBTSxLQUFLLENBQUMsc0JBQXNCLEVBQUUsQ0FBQzt3QkFFdkQsSUFBSSxTQUFTLEVBQUUsQ0FBQzs0QkFDZCxNQUFNLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQzs0QkFDcEIsTUFBTSx1QkFBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDOzRCQUVqQiw4QkFBOEI7NEJBQzlCLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDOzRCQUNyQyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7NEJBRS9CLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzs0QkFDeEIsT0FBTzt3QkFDVCxDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztnQkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO29CQUNmLHlCQUF5QjtnQkFDM0IsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLHdCQUF3QjtRQUMxQixDQUFDO1FBRUQsTUFBTSxJQUFJLGtDQUFZLENBQUMsa0NBQWtDLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRVMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLElBQVU7UUFDM0MsSUFBSSxDQUFDO1lBQ0gsa0VBQWtFO1lBQ2xFLE1BQU0sZUFBZSxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1lBQ3BFLElBQUksZUFBZSxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sU0FBUyxHQUFHLE1BQU0sZUFBZSxDQUFDLHNCQUFzQixFQUFFLENBQUM7Z0JBQ2pFLElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ2QsT0FBTyxlQUFlLENBQUM7Z0JBQ3pCLENBQUM7WUFDSCxDQUFDO1lBRUQsaUZBQWlGO1lBQ2pGLE1BQU0sWUFBWSxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQzVELElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ2pCLE1BQU0sU0FBUyxHQUFHLE1BQU0sWUFBWSxDQUFDLHNCQUFzQixFQUFFLENBQUM7Z0JBQzlELElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ2QsT0FBTyxZQUFZLENBQUM7Z0JBQ3RCLENBQUM7WUFDSCxDQUFDO1lBRUQsa0ZBQWtGO1lBQ2xGLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1lBQ2hGLElBQUksV0FBVyxFQUFFLENBQUM7Z0JBQ2hCLE1BQU0sU0FBUyxHQUFHLE1BQU0sV0FBVyxDQUFDLHNCQUFzQixFQUFFLENBQUM7Z0JBQzdELElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ2QsT0FBTyxXQUFXLENBQUM7Z0JBQ3JCLENBQUM7WUFDSCxDQUFDO1lBRUQsa0RBQWtEO1lBQ2xELE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUMvQyxJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUNiLE9BQU8sUUFBUSxDQUFDO1lBQ2xCLENBQUM7WUFFRCxzREFBc0Q7WUFDdEQsTUFBTSxnQkFBZ0IsR0FBRztnQkFDdkIscUJBQXFCO2dCQUNyQiw2QkFBNkI7Z0JBQzdCLHFCQUFxQjtnQkFDckIsNkJBQTZCO2dCQUM3QixpQkFBaUI7Z0JBQ2pCLHFCQUFxQjtnQkFDckIseUJBQXlCO2dCQUN6QixvQkFBb0I7YUFDckIsQ0FBQztZQUVGLEtBQUssTUFBTSxRQUFRLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztnQkFDeEMsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLE9BQU8sRUFBRSxDQUFDO29CQUNaLE9BQU8sT0FBTyxDQUFDO2dCQUNqQixDQUFDO1lBQ0gsQ0FBQztZQUVELDJEQUEyRDtZQUMzRCxNQUFNLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBQy9ELEtBQUssTUFBTSxPQUFPLElBQUksa0JBQWtCLEVBQUUsQ0FBQztnQkFDekMsTUFBTSxTQUFTLEdBQUcsTUFBTSxPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztnQkFDekQsSUFBSSxTQUFTLEVBQUUsQ0FBQztvQkFDZCxPQUFPLE9BQU8sQ0FBQztnQkFDakIsQ0FBQztZQUNILENBQUM7WUFFRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxJQUFVO1FBQ2pELElBQUksQ0FBQztZQUNILHNCQUFzQjtZQUN0QixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFckMsNkRBQTZEO1lBQzdELEtBQUssTUFBTSxDQUFDLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQzFCLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUN4RixJQUFJLFdBQVcsRUFBRSxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztvQkFDcEMsT0FBTyxDQUFDLENBQUM7Z0JBQ1gsQ0FBQztZQUNILENBQUM7WUFFRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFVLEVBQUUsT0FBZ0I7UUFDNUQsSUFBSSxDQUFDO1lBQ0gsT0FBTyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDdEUsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRVMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFVLEVBQUUsT0FBZTtRQUNyRCxrQ0FBa0M7UUFDbEMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUN4QiwySkFBMkosRUFDM0osRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQ25CLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLDJCQUEyQjtRQUM3QixDQUFDO1FBRUQsSUFBSSxjQUFjLEdBQUcsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFekQsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3BCLDJCQUEyQjtZQUMzQixNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNqRSxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNuQixjQUFjLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3BCLHNEQUFzRDtZQUN0RCxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQ3RDLHNMQUFzTCxDQUN2TCxDQUFDO2dCQUVGLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDbkQsTUFBTSxPQUFPLEdBQUcsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3RDLElBQUksQ0FBQzt3QkFDSCxNQUFNLFNBQVMsR0FBRyxNQUFNLE9BQU8sQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO3dCQUN6RCxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7d0JBQ2pFLE1BQU0sZUFBZSxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FDekMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsRUFDMUMsT0FBTyxDQUNSLENBQUM7d0JBQ0YsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO3dCQUMzRSxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7d0JBQ3JFLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQzt3QkFFckYsSUFDRSxTQUFTOzRCQUNULENBQUMsZUFBZSxLQUFLLE1BQU07Z0NBQ3pCLE9BQU8sS0FBSyxVQUFVO2dDQUN0QixJQUFJLEtBQUssU0FBUztnQ0FDbEIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUM7Z0NBQy9CLFNBQVMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO2dDQUM1QixTQUFTLEtBQUssRUFBRSxDQUFDLEVBQ25CLENBQUM7NEJBQ0QsY0FBYyxHQUFHLE9BQU8sQ0FBQzs0QkFDekIsTUFBTTt3QkFDUixDQUFDO29CQUNILENBQUM7b0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQzt3QkFDZiwyQkFBMkI7b0JBQzdCLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLDRCQUE0QjtZQUM5QixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNwQixpRUFBaUU7WUFDakUsSUFBSSxDQUFDO2dCQUNILE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFFdkMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO29CQUMxRCw2QkFBNkI7b0JBQzdCLE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDL0IsSUFBSSxDQUFDO3dCQUNILE1BQU0sU0FBUyxHQUFHLE1BQU0sT0FBTyxDQUFDLHNCQUFzQixFQUFFLENBQUM7d0JBQ3pELE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQzt3QkFDakUsTUFBTSxlQUFlLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUN6QyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxFQUMxQyxPQUFPLENBQ1IsQ0FBQzt3QkFDRixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7d0JBQ3JFLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FDckMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLEVBQ3RDLE9BQU8sQ0FDUixDQUFDO3dCQUVGLElBQ0UsU0FBUzs0QkFDVCxDQUFDLGVBQWUsS0FBSyxNQUFNO2dDQUN6QixPQUFPLEtBQUssVUFBVTtnQ0FDdEIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7Z0NBQzdCLFNBQVMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO2dDQUM1QixXQUFXLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQztnQ0FDM0IsV0FBVyxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUM5QixDQUFDOzRCQUNELGNBQWMsR0FBRyxPQUFPLENBQUM7NEJBQ3pCLE1BQU07d0JBQ1IsQ0FBQztvQkFDSCxDQUFDO29CQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7d0JBQ2Ysd0NBQXdDO29CQUMxQyxDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZix3QkFBd0I7WUFDMUIsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLGtDQUFZLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUMvRCxDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxjQUFjLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDN0IsTUFBTSx1QkFBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsaUJBQWlCO1lBQ25DLE1BQU8sY0FBc0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksa0NBQVksQ0FBQywyQkFBMkIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM3RCxDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBVSxFQUFFLGNBQW1CLEVBQUUsSUFBWTtRQUNyRSxNQUFNLE9BQU8sR0FBRyxJQUFJO2FBQ2pCLEtBQUssQ0FBQyxHQUFHLENBQUM7YUFDVixHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUN4QixNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFbkMsS0FBSyxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUMxQixNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNqRCxDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBVSxFQUFFLGNBQW1CLEVBQUUsR0FBVztRQUNuRSxJQUFJLENBQUM7WUFDSCxlQUFlO1lBQ2YsTUFBTSxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQztZQUNyQyxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFbEIseUNBQXlDO1lBQ3pDLE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1lBRXZFLElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ25CLE1BQU0sU0FBUyxHQUFHLE1BQU0sY0FBYyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDbEQsSUFBSSxTQUFTLEVBQUUsQ0FBQztvQkFDZCxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDeEIsTUFBTSx1QkFBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNuQixDQUFDO1lBQ0gsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGlDQUFpQztnQkFDakMsTUFBTSxjQUFjLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNwQyxNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2pCLCtCQUErQjtnQkFDL0IsTUFBTSxjQUFjLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNwQyxNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbkIsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2Ysb0JBQU0sQ0FBQyxJQUFJLENBQUMscUJBQXFCLEdBQUcsS0FBSyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELENBQUM7SUFDSCxDQUFDO0lBRVMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFVLEVBQUUsSUFBWTtRQUM5QyxJQUFJLENBQUM7WUFDSCxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMzRCxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNuQixNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNuRCxDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixvQkFBTSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM5QyxDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBVTtRQUNuQyxJQUFJLENBQUM7WUFDSCx5RUFBeUU7WUFDekUsSUFBSSxZQUFZLEdBQWdFLElBQUksQ0FBQztZQUNyRixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUNsRCxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNkLDJFQUEyRTtnQkFDM0UsTUFBTSxLQUFLLEdBQUcsTUFBTSxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUM5QyxTQUFTLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUM7b0JBQ3hDLFVBQVUsRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQztvQkFDMUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUM7aUJBQ25ELENBQUMsQ0FBQyxDQUFDO2dCQUNKLG9CQUFNLENBQUMsS0FBSyxDQUFDLHlDQUF5QyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDL0UsSUFBSSxLQUFLLENBQUMsU0FBUyxLQUFLLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxLQUFLLElBQUksRUFBRSxDQUFDO29CQUM1RCxZQUFZLEdBQUcsU0FBaUUsQ0FBQztnQkFDbkYsQ0FBQztZQUNILENBQUM7WUFFRCxnRUFBZ0U7WUFDaEUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUNsQixNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3hDLEtBQUssTUFBTSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7b0JBQzFCLE1BQU0sSUFBSSxHQUFHLE1BQU0sR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztvQkFDOUQsSUFBSSxJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7d0JBQ3pCLFlBQVksR0FBRyxHQUEyRCxDQUFDO3dCQUMzRSxNQUFNO29CQUNSLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFFRCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ2xCLHdFQUF3RTtnQkFDeEUsTUFBTSxjQUFjLEdBQUcsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUNsRCxLQUFLLE1BQU0sRUFBRSxJQUFJLGNBQWMsRUFBRSxDQUFDO29CQUNoQyxJQUFJLENBQUM7d0JBQ0gsTUFBTSxJQUFJLEdBQUcsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO3dCQUM3RCxJQUFJLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLEVBQUUsQ0FBQzs0QkFDN0MsTUFBTSxTQUFTLEdBQUcsTUFBTSxFQUFFLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7NEJBQ3ZFLElBQUksU0FBUyxFQUFFLENBQUM7Z0NBQ2QsWUFBWSxHQUFHLEVBQTBELENBQUM7Z0NBQzFFLE1BQU07NEJBQ1IsQ0FBQzt3QkFDSCxDQUFDO29CQUNILENBQUM7b0JBQUMsTUFBTSxDQUFDO3dCQUNQLFNBQVM7b0JBQ1gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDbEIsTUFBTSxjQUFjLEdBQUcsdUZBQXVGLENBQUM7Z0JBQy9HLFlBQVksR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFnRSxDQUFDO1lBQzdHLENBQUM7WUFFRCwrQkFBK0I7WUFDL0IsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUNsQixNQUFNLFlBQVksR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQzFDLEtBQUssTUFBTSxJQUFJLElBQUksWUFBWSxFQUFFLENBQUM7b0JBQ2hDLE1BQU0sUUFBUSxHQUFHLE1BQU8sSUFBWSxDQUFDLEVBQUUsQ0FBQyx5QkFBeUIsSUFBSSxLQUFLLENBQUMsQ0FBQztvQkFDNUUsS0FBSyxNQUFNLEVBQUUsSUFBSSxRQUFRLEVBQUUsQ0FBQzt3QkFDMUIsSUFBSSxDQUFDOzRCQUNILE1BQU0sSUFBSSxHQUFHLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQVcsRUFBRSxFQUFFO2dDQUM3QyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMscUJBQXFCLEVBQUUsQ0FBQztnQ0FDckMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7NEJBQ3JDLENBQUMsQ0FBQyxDQUFDOzRCQUNILElBQUksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQ0FDN0IsWUFBWSxHQUFHLEVBQTBELENBQUM7Z0NBQzFFLE1BQU07NEJBQ1IsQ0FBQzt3QkFDSCxDQUFDO3dCQUFDLE1BQU0sQ0FBQzs0QkFDUCxTQUFTO3dCQUNYLENBQUM7b0JBQ0gsQ0FBQztvQkFDRCxJQUFJLFlBQVk7d0JBQUUsTUFBTTtnQkFDMUIsQ0FBQztZQUNILENBQUM7WUFFRCxtREFBbUQ7WUFDbkQsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUNsQixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQzVDLElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ2QsTUFBTSxJQUFJLEdBQUcsTUFBTSxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUNwRSxJQUFJLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzt3QkFDekIsTUFBTSxNQUFNLEdBQUcsTUFBTSxTQUFTLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQ2pELEVBQUUsQ0FBQyxPQUFPLENBQUMscUNBQXFDLENBQUMsSUFBSSxFQUFFLENBQUMsYUFBYSxDQUN0RSxDQUFDO3dCQUNGLElBQUksTUFBTSxFQUFFLENBQUM7NEJBQ1gsWUFBWSxHQUFHLE1BQThELENBQUM7d0JBQ2hGLENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDbEIsNENBQTRDO2dCQUM1QyxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFO29CQUN6QyxrQ0FBa0M7b0JBQ2xDLE1BQU0sZUFBZSxHQUFpRixFQUFFLENBQUM7b0JBQ3pHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUU7d0JBQzFDLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUM7d0JBQ3BDLElBQUksSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDOzRCQUN6QixNQUFNLElBQUksR0FBRyxFQUFFLENBQUMscUJBQXFCLEVBQUUsQ0FBQzs0QkFDeEMsZUFBZSxDQUFDLElBQUksQ0FBQztnQ0FDbkIsR0FBRyxFQUFFLEVBQUUsQ0FBQyxPQUFPO2dDQUNmLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7Z0NBQzNCLEtBQUssRUFBRyxFQUFrQixDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQ0FDdEQsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQ0FDMUMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7NkJBQzdHLENBQUMsQ0FBQzt3QkFDTCxDQUFDO29CQUNILENBQUMsQ0FBQyxDQUFDO29CQUVILE9BQU87d0JBQ0wsR0FBRyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSTt3QkFDekIsVUFBVSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWTt3QkFDdEMsY0FBYyxFQUFFLE1BQU0sQ0FBQyxXQUFXO3dCQUNsQyxlQUFlLEVBQUUsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO3FCQUM5QyxDQUFDO2dCQUNKLENBQUMsQ0FBQyxDQUFDO2dCQUVILE1BQU0sSUFBSSxrQ0FBWSxDQUFDLHFDQUFxQyxTQUFTLENBQUMsR0FBRyxVQUFVLFNBQVMsQ0FBQyxVQUFVLFFBQVEsU0FBUyxDQUFDLGNBQWMsa0JBQWtCLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN4TSxDQUFDO1lBRUQsMkRBQTJEO1lBQzNELE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFO2dCQUM3QyxJQUFJLENBQUMsRUFBRTtvQkFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDO2dCQUNsQyxNQUFNLE1BQU0sR0FBRyxFQUFpQixDQUFDO2dCQUNqQyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzlDLE9BQU87b0JBQ0wsTUFBTSxFQUFFLElBQUk7b0JBQ1osUUFBUSxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLElBQUksTUFBTSxDQUFDLFlBQVksQ0FBQyxlQUFlLENBQUMsS0FBSyxNQUFNO29CQUM1RixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7b0JBQ2xDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztvQkFDdEIsVUFBVSxFQUFFLEtBQUssQ0FBQyxVQUFVO29CQUM1QixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87b0JBQ3RCLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztvQkFDdkIsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTO29CQUMzQixJQUFJLEVBQUUsTUFBTSxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztpQkFDbEQsQ0FBQztZQUNKLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNqQixvQkFBTSxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFcEUsSUFBSSxXQUFXLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ3pCLG9CQUFNLENBQUMsSUFBSSxDQUFDLGlEQUFpRCxDQUFDLENBQUM7WUFDakUsQ0FBQztZQUVELG1DQUFtQztZQUNuQyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTtnQkFDekIsSUFBSSxFQUFFLElBQUksT0FBTyxFQUFFLENBQUMsY0FBYyxLQUFLLFVBQVUsRUFBRSxDQUFDO29CQUNsRCxFQUFFLENBQUMsY0FBYyxDQUFDLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztnQkFDOUQsQ0FBQztZQUNILENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNqQixNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFakIscUZBQXFGO1lBQ3JGLE1BQU0sa0JBQWtCLEdBQUcsS0FBSyxJQUFzQixFQUFFO2dCQUN0RCxJQUFJLENBQUM7b0JBQ0gsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO29CQUM5QixNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxXQUFXLElBQUksRUFBRSxDQUFDLENBQUM7b0JBQzdFLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDO3dCQUM3QyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQzt3QkFDekIsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDN0IsQ0FBQztnQkFBQyxNQUFNLENBQUM7b0JBQ1AsT0FBTyxLQUFLLENBQUM7Z0JBQ2YsQ0FBQztZQUNILENBQUMsQ0FBQztZQUVGLG9GQUFvRjtZQUNwRixNQUFNLGVBQWUsR0FBRyxNQUFNLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssaUJBQWlCLENBQUMsQ0FBQztZQUM5RixJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUNwQixJQUFJLENBQUM7b0JBQ0gsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7d0JBQ3pCLElBQUksQ0FBQyxFQUFFOzRCQUFFLE9BQU87d0JBQ2hCLEVBQUUsQ0FBQyxhQUFhLENBQUMsSUFBSSxXQUFXLENBQUMsU0FBUyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUNsRixDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7b0JBQ2pCLG9CQUFNLENBQUMsS0FBSyxDQUFDLHNEQUFzRCxDQUFDLENBQUM7Z0JBQ3ZFLENBQUM7Z0JBQUMsT0FBTyxnQkFBZ0IsRUFBRSxDQUFDO29CQUMxQixvQkFBTSxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0MsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO2dCQUNuRSxDQUFDO2dCQUNELE1BQU0sdUJBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDbEIsSUFBSSxNQUFNLGtCQUFrQixFQUFFO29CQUFFLE9BQU87WUFDekMsQ0FBQztZQUVELG1GQUFtRjtZQUNuRixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7b0JBQ3pCLElBQUksQ0FBQyxFQUFFO3dCQUFFLE9BQU87b0JBQ2hCLE1BQU0sTUFBTSxHQUFHLEVBQWlCLENBQUM7b0JBQ2pDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO29CQUM1QyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO29CQUNyQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO29CQUNyQyxNQUFNLFNBQVMsR0FBRyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQztvQkFDdEgsTUFBTSxNQUFNLEdBQUc7d0JBQ2IsSUFBSSxVQUFVLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQzt3QkFDdkMsSUFBSSxVQUFVLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQzt3QkFDdEMsSUFBSSxVQUFVLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQzt3QkFDdEMsSUFBSSxVQUFVLENBQUMsV0FBVyxFQUFFLEVBQUUsR0FBRyxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUM7d0JBQ3BFLElBQUksVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQzt3QkFDMUMsSUFBSSxVQUFVLENBQUMsU0FBUyxFQUFFLEVBQUUsR0FBRyxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUM7d0JBQ2xFLElBQUksVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLEdBQUcsU0FBUyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO3FCQUNqRSxDQUFDO29CQUNGLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDbkQsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUNqQixvQkFBTSxDQUFDLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1lBQ3JFLENBQUM7WUFBQyxPQUFPLFVBQVUsRUFBRSxDQUFDO2dCQUNwQixvQkFBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUMxRCxDQUFDO1lBQ0QsTUFBTSx1QkFBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xCLElBQUksTUFBTSxrQkFBa0IsRUFBRTtnQkFBRSxPQUFPO1lBRXZDLGlEQUFpRDtZQUNqRCxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQzNCLG9CQUFNLENBQUMsS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUM7WUFDbkUsQ0FBQztZQUFDLE9BQU8sVUFBVSxFQUFFLENBQUM7Z0JBQ3BCLG9CQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixVQUFVLEVBQUUsQ0FBQyxDQUFDO1lBQ3hELENBQUM7WUFDRCxNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakIsSUFBSSxNQUFNLGtCQUFrQixFQUFFO2dCQUFFLE9BQU87WUFFdkMsNENBQTRDO1lBQzVDLElBQUksQ0FBQztnQkFDSCxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLElBQUksRUFBRTtvQkFBRyxFQUFrQixDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUNwRixvQkFBTSxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1lBQzlELENBQUM7WUFBQyxPQUFPLFlBQVksRUFBRSxDQUFDO2dCQUN0QixvQkFBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsWUFBWSxFQUFFLENBQUMsQ0FBQztZQUM1RCxDQUFDO1lBQ0QsTUFBTSx1QkFBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLElBQUksTUFBTSxrQkFBa0IsRUFBRTtnQkFBRSxPQUFPO1lBRXZDLHdFQUF3RTtZQUN4RSxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxHQUFHLEdBQUcsTUFBTSxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQzdDLElBQUksR0FBRyxFQUFFLENBQUM7b0JBQ1IsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztvQkFDckUsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO29CQUN4QixNQUFNLHVCQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ2hCLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDdEIsb0JBQU0sQ0FBQyxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztnQkFDOUQsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLFVBQVUsRUFBRSxDQUFDO2dCQUNwQixvQkFBTSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUNwRCxDQUFDO1lBQ0QsTUFBTSx1QkFBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxJQUFJLGtDQUFZLENBQUMsa0NBQWtDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDcEUsQ0FBQztJQUNILENBQUM7SUFFUyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsT0FBZ0I7UUFDL0MsSUFBSSxDQUFDO1lBQ0gsT0FBTyxNQUFPLE9BQWUsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQ3pELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxJQUFVO1FBQ2pELE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxDQUFDLGdDQUFnQztRQUMzRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDN0IsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRW5DLE9BQU8sSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVMsR0FBRyxXQUFXLEVBQUUsQ0FBQztZQUM1QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFFOUIsNkRBQTZEO1lBQzdELE1BQU0saUJBQWlCLEdBQUc7Z0JBQ3hCLGtCQUFrQjtnQkFDbEIsa0JBQWtCO2dCQUNsQixpQ0FBaUM7Z0JBQ2pDLGdCQUFnQjthQUNqQixDQUFDO1lBRUYsS0FBSyxNQUFNLFFBQVEsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO2dCQUN6QyxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3ZDLElBQUksT0FBTyxFQUFFLENBQUM7b0JBQ1osb0JBQU0sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLFFBQVEsRUFBRSxDQUFDLENBQUM7b0JBQ3JELE1BQU0sdUJBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDbEIsT0FBTyxNQUFNLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDaEQsQ0FBQztZQUNILENBQUM7WUFFRCx5Q0FBeUM7WUFDekMsTUFBTSxlQUFlLEdBQUc7Z0JBQ3RCLGdCQUFnQjtnQkFDaEIsZ0JBQWdCO2dCQUNoQiwrQkFBK0I7Z0JBQy9CLGNBQWM7Z0JBQ2QsY0FBYzthQUNmLENBQUM7WUFFRixLQUFLLE1BQU0sUUFBUSxJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUN2QyxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3ZDLElBQUksT0FBTyxFQUFFLENBQUM7b0JBQ1osTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDO29CQUN2RSxNQUFNLElBQUksa0NBQVksQ0FBQyw4QkFBOEIsU0FBUyxFQUFFLENBQUMsQ0FBQztnQkFDcEUsQ0FBQztZQUNILENBQUM7WUFFRCx1REFBdUQ7WUFDdkQsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLG9CQUFvQixFQUFFLFlBQVksRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1lBRXRGLElBQUksa0JBQWtCLEdBQUcsS0FBSyxDQUFDO1lBQy9CLEtBQUssTUFBTSxRQUFRLElBQUkscUJBQXFCLEVBQUUsQ0FBQztnQkFDN0MsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLE9BQU8sRUFBRSxDQUFDO29CQUNaLGtCQUFrQixHQUFHLElBQUksQ0FBQztvQkFDMUIsTUFBTTtnQkFDUixDQUFDO1lBQ0gsQ0FBQztZQUVELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO2dCQUN4QixvQkFBTSxDQUFDLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO2dCQUNwRCxPQUFPLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hELENBQUM7WUFFRCwrREFBK0Q7WUFDL0QsTUFBTSxjQUFjLEdBQUcsQ0FBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBRWpGLEtBQUssTUFBTSxRQUFRLElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ3RDLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDdkMsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDWixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUM7b0JBQ3ZFLElBQUksU0FBUyxFQUFFLENBQUM7d0JBQ2QsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLFNBQVMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQzs0QkFDOUQsb0JBQU0sQ0FBQyxLQUFLLENBQUMsd0JBQXdCLFNBQVMsRUFBRSxDQUFDLENBQUM7NEJBQ2xELE9BQU8sTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ2hELENBQUM7NkJBQU0sSUFDTCxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQzs0QkFDeEIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7NEJBQzNCLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQ3hCLENBQUM7NEJBQ0QsTUFBTSxJQUFJLGtDQUFZLENBQUMsbUJBQW1CLFNBQVMsRUFBRSxDQUFDLENBQUM7d0JBQ3pELENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELGlEQUFpRDtZQUNqRCxNQUFNLG1CQUFtQixHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1lBQzlFLEtBQUssTUFBTSxFQUFFLElBQUksbUJBQW1CLEVBQUUsQ0FBQztnQkFDckMsSUFBSSxDQUFDO29CQUNILE1BQU0sSUFBSSxHQUFHLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUM3RCxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRSxDQUFDO3dCQUM3QixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7NEJBQzNFLG9CQUFNLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxJQUFJLEVBQUUsQ0FBQyxDQUFDOzRCQUN0RCxPQUFPLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUNoRCxDQUFDO3dCQUNELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7NEJBQ25ELE1BQU0sSUFBSSxrQ0FBWSxDQUFDLG1CQUFtQixJQUFJLEVBQUUsQ0FBQyxDQUFDO3dCQUNwRCxDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztnQkFBQyxNQUFNLENBQUM7b0JBQ1AsU0FBUztnQkFDWCxDQUFDO1lBQ0gsQ0FBQztZQUVELHNFQUFzRTtZQUN0RSxJQUFJLFVBQVUsS0FBSyxlQUFlLEVBQUUsQ0FBQztnQkFDbkMsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxVQUFVLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUN4RixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7b0JBQ2xCLG9CQUFNLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxVQUFVLG9CQUFvQixDQUFDLENBQUM7b0JBQ2pGLE9BQU8sTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2hELENBQUM7WUFDSCxDQUFDO1lBRUQsaURBQWlEO1lBQ2pELE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsb0JBQW9CLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztZQUMvRyxLQUFLLE1BQU0sUUFBUSxJQUFJLGdCQUFnQixFQUFFLENBQUM7Z0JBQ3hDLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDdkMsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDWixJQUFJLENBQUM7d0JBQ0gsTUFBTSxTQUFTLEdBQUcsTUFBTSxPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBQzVFLElBQUksU0FBUyxFQUFFLENBQUM7NEJBQ2QsTUFBTSxJQUFJLEdBQUcsTUFBTSxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7NEJBQ2xFLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQ0FDekQsb0JBQU0sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQ0FDMUUsT0FBTyxNQUFNLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQzs0QkFDaEQsQ0FBQzt3QkFDSCxDQUFDO29CQUNILENBQUM7b0JBQUMsTUFBTSxDQUFDO3dCQUNQLFNBQVM7b0JBQ1gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELE1BQU0sdUJBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLHlCQUF5QjtRQUM3QyxDQUFDO1FBRUQsOEJBQThCO1FBQzlCLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDekMsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO1lBQzlCLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFO2dCQUMzRSxNQUFNLElBQUksR0FBRyxFQUFFLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDO2dCQUNwQyxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO29CQUNqRCxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN0QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7WUFDSCxPQUFPO2dCQUNMLEdBQUcsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUk7Z0JBQ3pCLFFBQVEsRUFBRSxRQUFRLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUU7Z0JBQzdELFlBQVksRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7YUFDaEYsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsb0JBQU0sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzlELG9CQUFNLENBQUMsS0FBSyxDQUFDLGtCQUFrQixTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFckUsaUZBQWlGO1FBQ2pGLE1BQU0sbUJBQW1CLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDL0QsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQzlDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUN2RixDQUFDO1FBRUYsSUFBSSxDQUFDLG1CQUFtQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDMUMsb0JBQU0sQ0FBQyxJQUFJLENBQUMsNkVBQTZFLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQzFHLE9BQU8sTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUVELE1BQU0sSUFBSSxrQ0FBWSxDQUNwQixnRUFBZ0UsU0FBUyxDQUFDLEdBQUcsV0FBVyxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQzlJLENBQUM7SUFDSixDQUFDO0lBRVMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLElBQVU7UUFDOUMsSUFBSSxDQUFDO1lBQ0gsK0RBQStEO1lBQy9ELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUM5QixvQkFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUV6RCx3RUFBd0U7WUFDeEUsTUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQztnQkFDN0QsVUFBVSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1lBRWhELElBQUksV0FBVyxJQUFJLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUNsQyxNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzlCLG9CQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixNQUFNLEVBQUUsQ0FBQyxDQUFDO2dCQUN0RCxPQUFPLE1BQU0sQ0FBQztZQUNoQixDQUFDO1lBRUQsbUVBQW1FO1lBQ25FLE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7Z0JBQzlDLHNEQUFzRDtnQkFDdEQsTUFBTSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsOENBQThDLENBQUMsQ0FBQztnQkFDbkcsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO29CQUNqRCxNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDcEMsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUM7d0JBQ2pELE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDO3dCQUMvQixPQUFPLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLENBQUM7b0JBQzFDLElBQUksTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyw4QkFBOEI7d0JBQ2hFLE9BQU8sTUFBTSxDQUFDO29CQUNoQixDQUFDO2dCQUNILENBQUM7Z0JBRUQsK0JBQStCO2dCQUMvQixNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsOENBQThDLENBQUMsQ0FBQztnQkFDNUYsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDMUMsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUMxQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUN2QyxJQUFJLElBQUksRUFBRSxDQUFDO3dCQUNULE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMseUJBQXlCLENBQUM7NEJBQ2pELElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQzt3QkFDMUMsSUFBSSxLQUFLLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7NEJBQ3RCLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUNsQixDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxnRUFBZ0U7Z0JBQ2hFLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQztnQkFDcEQsTUFBTSxhQUFhLEdBQUcsaUJBQWlCLENBQUM7Z0JBQ3hDLE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQ2pELElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQ2xDLHlDQUF5QztvQkFDekMsT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BCLENBQUM7Z0JBRUQsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDLENBQUMsQ0FBQztZQUVILElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ25CLG9CQUFNLENBQUMsS0FBSyxDQUFDLHdDQUF3QyxjQUFjLEVBQUUsQ0FBQyxDQUFDO2dCQUN2RSxPQUFPLGNBQWMsQ0FBQztZQUN4QixDQUFDO1lBRUQsdUVBQXVFO1lBQ3ZFLG9CQUFNLENBQUMsS0FBSyxDQUFDLDZEQUE2RCxDQUFDLENBQUM7WUFDNUUsSUFBSSxDQUFDO2dCQUNILDBDQUEwQztnQkFDMUMsTUFBTSx1QkFBSyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVsQiw0Q0FBNEM7Z0JBQzVDLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxNQUFNLHlGQUErQixDQUFDO2dCQUM5RCxNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztnQkFDdEQsTUFBTSxTQUFTLEdBQUcsTUFBTSxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsMkJBQTJCO2dCQUVoRixJQUFJLFNBQVMsQ0FBQyxPQUFPLElBQUksU0FBUyxDQUFDLElBQUksSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDckUsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQzFDLG9CQUFNLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxZQUFZLEVBQUUsQ0FBQyxDQUFDO29CQUNwRSxPQUFPLFlBQVksQ0FBQztnQkFDdEIsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLG9CQUFNLENBQUMsSUFBSSxDQUFDLHVDQUF1QyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQzlELENBQUM7WUFFRCxvQkFBTSxDQUFDLEtBQUssQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO1lBQzFELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixvQkFBTSxDQUFDLElBQUksQ0FBQyw4QkFBOEIsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNuRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0NBQ0Y7OztBQzkrQm1GO0FBR2Q7QUFDekI7QUFDRjtBQUNEO0FBQ2Q7QUFDZ0M7QUFFckQsTUFBTSxtQkFBb0IsU0FBUSxrQkFBa0I7SUFDekQsS0FBSyxDQUFDLFdBQVcsQ0FDZixLQUFhLEVBQ2IsT0FBZSxFQUNmLFVBQW9CLEVBQ3BCLE9BQWUsRUFBRSxFQUNqQixXQUFvQjtRQUVwQixrQkFBa0I7UUFDbEIsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ25CLE1BQU0sSUFBSSxrQ0FBWSxDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUVELHFFQUFxRTtRQUNyRSxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3QixvQkFBTSxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsS0FBSyxNQUFNLGFBQWEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFMUYsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ3JCLE1BQU0sSUFBSSxrQ0FBWSxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFDekQsQ0FBQztRQUVELElBQUksQ0FBQyxVQUFVLElBQUksVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMzQyxNQUFNLElBQUksa0NBQVksQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1FBQzNELENBQUM7UUFFRCwrREFBK0Q7UUFDL0QsTUFBTSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsNEJBQTRCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFMUUscUNBQXFDO1FBQ3JDLE1BQU0sY0FBYyxHQUFHLG9CQUFvQixDQUFDO1FBRTVDLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFFakYsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsaUJBQWlCLENBQzlDLElBQUksRUFDSixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUN2QyxDQUFDO2dCQUVGLHdCQUF3QjtnQkFDeEIsTUFBTSx1QkFBSyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVsQixvREFBb0Q7Z0JBQ3BELE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFaEMsa0NBQWtDO2dCQUNsQyxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRWxCLElBQUksa0JBQWtCLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxrQkFBa0IsQ0FDeEUsSUFBSSxFQUNKLGNBQWMsRUFDZCxLQUFLLENBQ04sQ0FBQztnQkFFRixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztvQkFDeEIsaURBQWlEO29CQUNqRCxNQUFNLG9CQUFvQixHQUFHO3dCQUMzQixvQkFBb0I7d0JBQ3BCLGlCQUFpQjt3QkFDakIsc0JBQXNCO3dCQUN0QixxQkFBcUI7d0JBQ3JCLG9CQUFvQjtxQkFDckIsQ0FBQztvQkFFRixLQUFLLE1BQU0sUUFBUSxJQUFJLG9CQUFvQixFQUFFLENBQUM7d0JBQzVDLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsa0JBQWtCLENBQ3BFLElBQUksRUFDSixRQUFRLEVBQ1IsS0FBSyxDQUNOLENBQUM7d0JBQ0YsSUFBSSxrQkFBa0IsRUFBRSxDQUFDOzRCQUN2QixNQUFNO3dCQUNSLENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO2dCQUVELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO29CQUN4QixNQUFNLElBQUksa0NBQVksQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO2dCQUM1RSxDQUFDO2dCQUVELGdCQUFnQjtnQkFDaEIsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsQ0FBQztnQkFFN0Msc0VBQXNFO2dCQUN0RSxvQkFBTSxDQUFDLEtBQUssQ0FBQywrREFBK0QsQ0FBQyxDQUFDO2dCQUM5RSxNQUFNLHVCQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBRW5CLDhFQUE4RTtnQkFDOUUsSUFBSSxDQUFDO29CQUNILE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FDeEIsNEVBQTRFLEVBQzVFLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUNuQixDQUFDO2dCQUNKLENBQUM7Z0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztvQkFDZiwyQkFBMkI7Z0JBQzdCLENBQUM7Z0JBRUQsdURBQXVEO2dCQUN2RCxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRWxCLGdCQUFnQjtnQkFDaEIsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFFbEMsNkNBQTZDO2dCQUM3QyxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRWxCLGtCQUFrQjtnQkFDbEIsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFFdEMsdUJBQXVCO2dCQUN2QixJQUFJLElBQUksRUFBRSxDQUFDO29CQUNULE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ2pDLENBQUM7Z0JBRUQsa0JBQWtCO2dCQUNsQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRTVCLHVDQUF1QztnQkFDdkMsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRXpELGVBQWU7Z0JBQ2YsTUFBTSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFekQsT0FBTztvQkFDTCxPQUFPLEVBQUUsSUFBSTtvQkFDYixPQUFPLEVBQUUsNkJBQTZCO29CQUN0QyxLQUFLO29CQUNMLE9BQU87b0JBQ1AsVUFBVSxFQUFFLGFBQWEsQ0FBQyxNQUFNO29CQUNoQyxJQUFJO29CQUNKLEdBQUcsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLGlCQUFpQjtvQkFDM0MsTUFBTSxFQUFFLE1BQU0sSUFBSSxTQUFTO2lCQUM1QixDQUFDO1lBQ0osQ0FBQztvQkFBUyxDQUFDO2dCQUNULE1BQU0sSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3JCLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG9CQUFNLENBQUMsS0FBSyxDQUFDLGtCQUFrQixLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ3hDLE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxVQUFvQjtRQUM3RCwrRUFBK0U7UUFDL0UsTUFBTSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRS9FLDBCQUEwQjtRQUMxQixLQUFLLE1BQU0sWUFBWSxJQUFJLGFBQWEsRUFBRSxDQUFDO1lBQ3pDLHFEQUFxRDtZQUNyRCxNQUFNLFFBQVEsR0FDWixZQUFZLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDO2dCQUM5RCxDQUFDLENBQUMsWUFBWTtnQkFDZCxDQUFDLENBQUMsdUJBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFFeEMsSUFBSSxDQUFDLDJCQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDMUIsTUFBTSxJQUFJLHVDQUFpQixDQUFDLHlCQUF5QixZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZFLENBQUM7WUFFRCxNQUFNLEtBQUssR0FBRyx5QkFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztnQkFDcEIsTUFBTSxJQUFJLHVDQUFpQixDQUFDLHVCQUF1QixZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQ3JFLENBQUM7WUFFRCx1QkFBdUI7WUFDdkIsTUFBTSxHQUFHLEdBQUcsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUN4RCxNQUFNLGlCQUFpQixHQUFHLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN2RSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzdDLE1BQU0sSUFBSSx1Q0FBaUIsQ0FDekIsNkJBQTZCLFlBQVksZ0JBQWdCLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUN4RixDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLGFBQWEsQ0FBQyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDOUIsTUFBTSxJQUFJLGtDQUFZLENBQUMsMkJBQTJCLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBRUQsT0FBTyxhQUFhLENBQUM7SUFDdkIsQ0FBQztJQUVPLEtBQUssQ0FBQyxjQUFjLENBQUMsSUFBVTtRQUNyQyxJQUFJLENBQUM7WUFDSCxvQkFBTSxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO1lBRW5ELHFEQUFxRDtZQUNyRCxNQUFNLGVBQWUsR0FBRyx3RkFBd0YsQ0FBQztZQUNqSCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNoRixvQkFBTSxDQUFDLEtBQUssQ0FBQyw0Q0FBNEMsZUFBZSxFQUFFLENBQUMsQ0FBQztZQUM1RSxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFbEIseURBQXlEO1lBQ3pELE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3pDLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxJQUFJLEVBQUUsV0FBVyxJQUFJLEVBQUUsQ0FBQztnQkFDbEQsT0FBTztvQkFDTCxjQUFjLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztvQkFDdEUsY0FBYyxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7b0JBQ3RFLEdBQUcsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUk7aUJBQzFCLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztZQUNILG9CQUFNLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUUxRSxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsSUFBSSxTQUFTLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQzFELG9CQUFNLENBQUMsSUFBSSxDQUFDLGtFQUFrRSxDQUFDLENBQUM7Z0JBRWhGLDZDQUE2QztnQkFDN0MsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLCtDQUErQyxDQUFDLENBQUM7Z0JBQzVFLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7b0JBQ3ZCLE1BQU0sSUFBSSxHQUFHLE1BQU0sR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztvQkFDOUQsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO3dCQUMzRCxNQUFNLFNBQVMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDeEUsSUFBSSxDQUFDLFNBQVM7NEJBQUUsU0FBUzt3QkFFekIsNkJBQTZCO3dCQUM3QixNQUFNLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTs0QkFDeEIsTUFBTSxNQUFNLEdBQUcsRUFBaUIsQ0FBQzs0QkFDakMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7NEJBQzVFLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0NBQ2xCLE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBSSxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDOzRCQUNoRixDQUFDLENBQUMsQ0FBQzt3QkFDTCxDQUFDLENBQUMsQ0FBQzt3QkFDSCxNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7d0JBRWpCLE1BQU0sR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDO3dCQUNsQixvQkFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO3dCQUNoRCxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ2xCLE1BQU07b0JBQ1IsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELE1BQU0sdUJBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG9CQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFVLEVBQUUsVUFBb0I7UUFDekQsSUFBSSxDQUFDO1lBQ0gsb0JBQU0sQ0FBQyxLQUFLLENBQUMsdURBQXVELENBQUMsQ0FBQztZQUV0RSxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQztZQUNyRCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxJQUFJLGtDQUFZLENBQUMsMENBQTBDLENBQUMsQ0FBQztZQUNyRSxDQUFDO1lBRUQsZ0ZBQWdGO1lBQ2hGLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQWtCLEVBQUUsRUFBRTtnQkFDekMsSUFBSSxFQUFFLEVBQUUsQ0FBQztvQkFDUCxFQUFFLENBQUMsWUFBWSxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztvQkFDeEMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDL0IsQ0FBQztZQUNILENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUVkLG9CQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsVUFBVSxDQUFDLE1BQU0sb0NBQW9DLENBQUMsQ0FBQztZQUNsRixNQUFNLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQztZQUUxQyxtRUFBbUU7WUFDbkUsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBa0IsRUFBRSxFQUFFO2dCQUN6QyxJQUFJLEVBQUUsRUFBRSxDQUFDO29CQUNQLEVBQUUsQ0FBQyxhQUFhLENBQUMsSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDM0QsQ0FBQztZQUNILENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUVkLE1BQU0sdUJBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxrQ0FBWSxDQUFDLDRCQUE0QixLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzlELENBQUM7SUFDSCxDQUFDO0NBRUY7OztBQzFSbUY7QUFDRjtBQUN0RDtBQUV1QjtBQUNOO0FBQ0Y7QUFDRDtBQUNrQjtBQUVyRCxNQUFNLG1CQUFvQixTQUFRLGtCQUFrQjtJQUNqRCxLQUFLLENBQUMsNkJBQTZCLENBQUMsSUFBVTtRQUNwRCxvQkFBTSxDQUFDLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO1FBRXhELElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQztRQUV6QixNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FDekIsS0FBSyxJQUFJLEVBQUU7WUFDVCwrQkFBK0I7WUFDL0IsTUFBTSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQ3RELElBQUksRUFDSixTQUFTLENBQUMsa0JBQWtCLEVBQzVCLGFBQWEsQ0FBQyxPQUFPLENBQ3RCLENBQUM7WUFFRixJQUFJLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDeEIsb0JBQU0sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUMvRCxNQUFNLHVCQUFLLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBQzdDLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztZQUVELDZCQUE2QjtZQUM3QixNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyx1QkFBdUIsQ0FDcEQsSUFBSSxFQUNKLFNBQVMsQ0FBQyxnQkFBZ0IsRUFDMUIsYUFBYSxDQUFDLEtBQUssQ0FDcEIsQ0FBQztZQUVGLElBQUksV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN0QixNQUFNLElBQUksa0NBQVksQ0FBQyxvQ0FBb0MsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDakYsQ0FBQztZQUVELHdEQUF3RDtZQUN4RCxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxzQkFBc0IsQ0FDbkQsSUFBSSxFQUNKLFNBQVMsQ0FBQyx1QkFBdUIsQ0FDbEMsQ0FBQztZQUNGLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDakIsb0JBQU0sQ0FBQyxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQztnQkFDbEUsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1lBRUQsOEJBQThCO1lBQzlCLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQ3pELElBQUksRUFDSixTQUFTLENBQUMscUJBQXFCLEVBQy9CLGFBQWEsQ0FBQyxVQUFVLENBQ3pCLENBQUM7WUFFRixZQUFZLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDO1lBQ3RDLElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ2pCLG9CQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ25FLENBQUM7WUFFRCwyQkFBMkI7WUFDM0IsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQ3BELElBQUksRUFDSixTQUFTLENBQUMsZUFBZSxFQUN6QixhQUFhLENBQUMsT0FBTyxDQUN0QixDQUFDO1lBRUYsSUFBSSxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3RCLG9CQUFNLENBQUMsS0FBSyxDQUFDLHdCQUF3QixXQUFXLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDekQsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1lBRUQsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLElBQUksQ0FBQyx1QkFBdUIsQ0FDekQsSUFBSSxFQUNKLFNBQVMsQ0FBQyxlQUFlLEVBQ3pCLGFBQWEsQ0FBQyxLQUFLLENBQ3BCLENBQUM7WUFFRixJQUFJLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUMzQixNQUFNLElBQUksa0NBQVksQ0FBQyx5QkFBeUIsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUMzRSxDQUFDO1lBRUQsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDLEVBQ0QsY0FBYyxDQUFDLGtCQUFrQixFQUNqQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLGdCQUFnQixFQUNyRCwrRUFBK0UsQ0FDaEYsQ0FBQztRQUVGLDhDQUE4QztRQUM5QyxPQUFPLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCxLQUFLLENBQUMsWUFBWSxDQUNoQixLQUFhLEVBQ2IsT0FBZSxFQUNmLFNBQWlCLEVBQ2pCLE9BQWUsRUFBRSxFQUNqQixXQUFvQjtRQUVwQixrQkFBa0I7UUFDbEIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFcEQsa0NBQWtDO1FBQ2xDLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXRFLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFFakYsSUFBSSxDQUFDO2dCQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLDJCQUEyQixDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUVyRyxlQUFlO2dCQUNmLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRXpELE9BQU87b0JBQ0wsT0FBTyxFQUFFLElBQUk7b0JBQ2IsT0FBTyxFQUFFLDhCQUE4QjtvQkFDdkMsS0FBSztvQkFDTCxPQUFPO29CQUNQLFVBQVUsRUFBRSxDQUFDLEVBQUUsZ0NBQWdDO29CQUMvQyxJQUFJO29CQUNKLEdBQUcsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLHNCQUFzQjtvQkFDaEQsTUFBTSxFQUFFLE1BQU0sSUFBSSxTQUFTO2lCQUM1QixDQUFDO1lBQ0osQ0FBQztvQkFBUyxDQUFDO2dCQUNULE1BQU0sSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3JCLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG9CQUFNLENBQUMsS0FBSyxDQUFDLHdCQUF3QixLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQzlDLE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFTyxtQkFBbUIsQ0FBQyxLQUFhLEVBQUUsT0FBZSxFQUFFLFNBQWlCO1FBQzNFLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUNuQixNQUFNLElBQUksa0NBQVksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1FBQ3hELENBQUM7UUFFRCwyQ0FBMkM7UUFDM0MscUJBQXFCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0Isb0JBQU0sQ0FBQyxLQUFLLENBQUMseUNBQXlDLEtBQUssTUFBTSxhQUFhLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRWhHLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUNyQixNQUFNLElBQUksa0NBQVksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBQzFELENBQUM7UUFFRCxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUM7WUFDdkIsTUFBTSxJQUFJLGtDQUFZLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUNuRCxDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQywyQkFBMkIsQ0FDdkMsSUFBVSxFQUNWLEtBQWEsRUFDYixPQUFlLEVBQ2YsU0FBaUIsRUFDakIsSUFBWTtRQUVaLGdDQUFnQztRQUNoQyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLGlCQUFpQixDQUM5QyxJQUFJLEVBQ0osSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FDNUMsQ0FBQztRQUVGLHdCQUF3QjtRQUN4QixNQUFNLHVCQUFLLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXRDLHVDQUF1QztRQUN2QyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVyQyxrQ0FBa0M7UUFDbEMsTUFBTSx1QkFBSyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUV2QyxlQUFlO1FBQ2YsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUV4QyxrRUFBa0U7UUFDbEUsTUFBTSx1QkFBSyxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBRTdDLGdCQUFnQjtRQUNoQixNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRWxDLHdDQUF3QztRQUN4QyxNQUFNLHVCQUFLLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRXpDLGtCQUFrQjtRQUNsQixNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRXRDLHVCQUF1QjtRQUN2QixJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNqQyxDQUFDO1FBRUQsbUJBQW1CO1FBQ25CLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUU1QixvRUFBb0U7UUFDcEUsT0FBTyxNQUFNLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRU8sMkJBQTJCLENBQUMsU0FBaUI7UUFDbkQsTUFBTSxZQUFZLEdBQ2hCLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksU0FBUyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUM7WUFDeEQsQ0FBQyxDQUFDLFNBQVM7WUFDWCxDQUFDLENBQUMsdUJBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFckMsSUFBSSxDQUFDLDJCQUFVLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUM5QixNQUFNLElBQUksa0NBQVksQ0FBQyx5QkFBeUIsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUMvRCxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcseUJBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLGtDQUFZLENBQUMsdUJBQXVCLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDN0QsQ0FBQztRQUVELHVCQUF1QjtRQUN2QixNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3JELE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM3RSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDN0MsTUFBTSxJQUFJLGtDQUFZLENBQ3BCLDZCQUE2QixTQUFTLGdCQUFnQixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDckYsQ0FBQztRQUNKLENBQUM7UUFFRCw2Q0FBNkM7UUFDN0MsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLENBQUMsY0FBYztRQUN2QyxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ2hELElBQUksWUFBWSxHQUFHLFdBQVcsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxrQ0FBWSxDQUNwQix5QkFBeUIsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsd0JBQXdCLFdBQVcsSUFBSSxDQUN4RixDQUFDO1FBQ0osQ0FBQztRQUVELE9BQU8sWUFBWSxDQUFDO0lBQ3RCLENBQUM7SUFFTyxLQUFLLENBQUMsbUJBQW1CLENBQUMsSUFBVTtRQUMxQyxJQUFJLENBQUM7WUFDSCx1Q0FBdUM7WUFDdkMsTUFBTSxpQkFBaUIsR0FBRztnQkFDeEIsaUJBQWlCO2dCQUNqQixjQUFjO2dCQUNkLGNBQWM7Z0JBQ2QsTUFBTTtnQkFDTixtQkFBbUI7YUFDcEIsQ0FBQztZQUVGLElBQUksSUFBSSxHQUFVLEVBQUUsQ0FBQztZQUNyQixLQUFLLE1BQU0sUUFBUSxJQUFJLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3pDLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDMUMsSUFBSSxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUN6QixJQUFJLEdBQUcsU0FBUyxDQUFDO29CQUNqQixNQUFNO2dCQUNSLENBQUM7WUFDSCxDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUN0QixvQkFBTSxDQUFDLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO2dCQUM5QyxPQUFPO1lBQ1QsQ0FBQztZQUVELDZDQUE2QztZQUM3QyxJQUFJLFFBQVEsR0FBUSxJQUFJLENBQUM7WUFDekIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDckMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNwQixJQUFJLENBQUM7b0JBQ0gsTUFBTSxTQUFTLEdBQUcsTUFBTSxHQUFHLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztvQkFDckQsSUFBSSxDQUFDLFNBQVM7d0JBQUUsU0FBUztvQkFFekIsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxDQUFDO29CQUU5RCx3Q0FBd0M7b0JBQ3hDLElBQ0UsSUFBSTt3QkFDSixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQ3hFLENBQUM7d0JBQ0QsUUFBUSxHQUFHLEdBQUcsQ0FBQzt3QkFDZixNQUFNO29CQUNSLENBQUM7Z0JBQ0gsQ0FBQztnQkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO29CQUNmLCtCQUErQjtnQkFDakMsQ0FBQztZQUNILENBQUM7WUFFRCxJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUNiLE1BQU0sUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN2QixNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxzQkFBc0I7WUFDM0MsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLHVEQUF1RDtnQkFDdkQsTUFBTSxXQUFXLEdBQVUsRUFBRSxDQUFDO2dCQUM5QixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO29CQUN2QixNQUFNLFNBQVMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO29CQUNyRCxJQUFJLFNBQVMsRUFBRSxDQUFDO3dCQUNkLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ3hCLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQzNCLE1BQU0sV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsd0NBQXdDO29CQUN0RSxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3BCLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixvQkFBTSxDQUFDLElBQUksQ0FBQyxxQ0FBcUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM1RCxDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBVSxFQUFFLFNBQWlCO1FBQ3JELG9CQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBRTlDLDBCQUEwQjtRQUMxQixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2hGLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxrQ0FBWSxDQUFDLHVEQUF1RCxDQUFDLENBQUM7UUFDbEYsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILGlDQUFpQztZQUNqQyxNQUFNLHVCQUFLLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRXpDLHdCQUF3QjtZQUN4QixNQUFNLFNBQVMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDdEMsb0JBQU0sQ0FBQyxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztZQUUvRCw2Q0FBNkM7WUFDN0MsTUFBTSx1QkFBSyxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUV6QyxnRUFBZ0U7WUFDaEUsTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksa0NBQVksQ0FBQywwQkFBMEIsU0FBUyxLQUFLLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDMUUsQ0FBQztJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsc0JBQXNCLENBQUMsSUFBVTtRQUM3QyxvQkFBTSxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1FBRTVELElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUN6QixLQUFLLElBQUksRUFBRTtnQkFDVCxrQ0FBa0M7Z0JBQ2xDLE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLHVCQUF1QixDQUN2RCxJQUFJLEVBQ0osU0FBUyxDQUFDLHFCQUFxQixFQUMvQixhQUFhLENBQUMsT0FBTyxDQUN0QixDQUFDO2dCQUVGLElBQUksY0FBYyxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUN6QixvQkFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7b0JBQ2xFLE9BQU8sSUFBSSxDQUFDO2dCQUNkLENBQUM7Z0JBRUQsNEJBQTRCO2dCQUM1QixNQUFNLGdCQUFnQixHQUFHLE1BQU0sSUFBSSxDQUFDLHVCQUF1QixDQUN6RCxJQUFJLEVBQ0osU0FBUyxDQUFDLHFCQUFxQixFQUMvQixhQUFhLENBQUMsVUFBVSxDQUN6QixDQUFDO2dCQUVGLElBQUksZ0JBQWdCLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQzNCLG9CQUFNLENBQUMsS0FBSyxDQUFDLHFCQUFxQixnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUMzRCxPQUFPLEtBQUssQ0FBQyxDQUFDLHFDQUFxQztnQkFDckQsQ0FBQztnQkFFRCxrRUFBa0U7Z0JBQ2xFLG9CQUFNLENBQUMsS0FBSyxDQUFDLG9FQUFvRSxDQUFDLENBQUM7Z0JBQ25GLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQyxFQUNELGNBQWMsQ0FBQyxrQkFBa0IsRUFDakMsY0FBYyxDQUFDLGdCQUFnQixFQUMvQiwwQkFBMEIsQ0FDM0IsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2Ysb0JBQU0sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELENBQUMsQ0FBQztRQUNoRSxDQUFDO0lBQ0gsQ0FBQztDQUVGOzs7QUM5WHVEO0FBRU07QUFDQTtBQUV2RCxNQUFNLGNBQWUsU0FBUSwrQkFBVztJQUNyQyxZQUFZLENBQXNCO0lBQ2xDLFlBQVksQ0FBc0I7SUFFMUMsWUFBWSxNQUFjLEVBQUUsY0FBK0I7UUFDekQsS0FBSyxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksbUJBQW1CLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN6RSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksbUJBQW1CLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRU0sS0FBSyxDQUFDLFdBQVcsQ0FDdEIsS0FBYSxFQUNiLE9BQWUsRUFDZixVQUFvQixFQUNwQixPQUFlLEVBQUUsRUFDakIsV0FBb0I7UUFFcEIsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDdEYsQ0FBQztJQUVNLEtBQUssQ0FBQyxZQUFZLENBQ3ZCLEtBQWEsRUFDYixPQUFlLEVBQ2YsU0FBaUIsRUFDakIsT0FBZSxFQUFFLEVBQ2pCLFdBQW9CO1FBRXBCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3RGLENBQUM7SUFFTSxLQUFLLENBQUMsY0FBYyxDQUN6QixJQUF1QixFQUN2QixLQUFhLEVBQ2IsT0FBZSxFQUNmLFVBQW9CLEVBQ3BCLE9BQWUsRUFBRSxFQUNqQixXQUFvQjtRQUVwQixJQUFJLElBQUksS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUNyQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3pFLENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztRQUM3RSxDQUFDO0lBQ0gsQ0FBQztDQUNGOzs7Ozs7O0FDbEREOztHQUVHO0FBRXdEO0FBQ0M7QUFDVztBQUNYO0FBQ1E7QUFDcEI7QUFDRDtBQU1uQjtBQUNpQjtBQUN3QjtBQXNCOUQsTUFBTSxZQUFZO0lBQ2YsV0FBVyxDQUFjO0lBQ3pCLFdBQVcsQ0FBYztJQUN6QixjQUFjLENBQWlCO0lBQy9CLFdBQVcsQ0FBYztJQUN6QixjQUFjLENBQWlCO0lBRXZDO1FBQ0UsTUFBTSxNQUFNLEdBQUcsbUNBQVMsRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxzQ0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3RFLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSx3QkFBVyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVELEtBQUssQ0FBQyxlQUFlLENBQ25CLFdBQW9CO1FBRXBCLDJEQUEyRDtRQUMzRCxrRUFBa0U7UUFDbEUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDbEQsa0NBQWdCLENBQUMsS0FBSyxFQUFFLHdCQUF3QixFQUFFLG9CQUFNLENBQUMsQ0FBQztRQUM1RCxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU87WUFDTCxPQUFPLEVBQUU7Z0JBQ1A7b0JBQ0UsSUFBSSxFQUFFLE1BQU07b0JBQ1osSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQ2xCO3dCQUNFLE9BQU8sRUFBRSxJQUFJO3dCQUNiLE9BQU8sRUFDTCxrRkFBa0Y7d0JBQ3BGLE1BQU0sRUFBRSxlQUFlO3dCQUN2QixNQUFNLEVBQUUsZ0JBQWdCO3dCQUN4QixZQUFZLEVBQUU7NEJBQ1osNERBQTREOzRCQUM1RCwyQ0FBMkM7NEJBQzNDLDJEQUEyRDs0QkFDM0Qsb0RBQW9EO3lCQUNyRDt3QkFDRCxJQUFJLEVBQUUscUdBQXFHO3FCQUM1RyxFQUNELElBQUksRUFDSixDQUFDLENBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsS0FBSyxDQUFDLGdCQUFnQjtRQUNwQixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDL0MsT0FBTyx1Q0FBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQsS0FBSyxDQUFDLGdCQUFnQixDQUNwQixXQUFvQjtRQUVwQixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQy9ELE9BQU8sdUNBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELEtBQUssQ0FBQyxtQkFBbUIsQ0FDdkIsV0FBb0I7UUFFcEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMvRCxPQUFPLHVDQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxLQUFLLENBQUMsZ0JBQWdCLENBQ3BCLE9BQWdCLEVBQ2hCLFdBQW9CO1FBRXBCLHdDQUFzQixDQUFDLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsT0FBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3pFLE9BQU8sdUNBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELEtBQUssQ0FBQyxtQkFBbUIsQ0FDdkIsTUFBZSxFQUNmLFNBQWtCLEVBQ2xCLFdBQW9CO1FBRXBCLHdDQUFzQixDQUFDLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxFQUFFLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDdkUsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxNQUFPLEVBQUUsU0FBVSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3RGLE9BQU8sdUNBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELEtBQUssQ0FBQyxtQkFBbUIsQ0FDdkIsTUFBZSxFQUNmLFNBQWtCLEVBQ2xCLElBQWEsRUFDYixXQUFvQjtRQUVwQix3Q0FBc0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDckYsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxNQUFPLEVBQUUsU0FBVSxFQUFFLElBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztRQUM3RixPQUFPLHVDQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxLQUFLLENBQUMsb0JBQW9CLENBQ3hCLElBQWEsRUFDYixLQUFjLEVBQ2QsT0FBZ0IsRUFDaEIsVUFBcUIsRUFDckIsSUFBYSxFQUNiLFdBQW9CO1FBRXBCLHdDQUFzQixDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLEVBQUU7WUFDM0QsTUFBTTtZQUNOLE9BQU87WUFDUCxTQUFTO1lBQ1QsWUFBWTtTQUNiLENBQUMsQ0FBQztRQUVILHdCQUF3QjtRQUN4QixJQUFJLElBQUksS0FBSyxPQUFPLElBQUksSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQ3pDLE1BQU0sSUFBSSxLQUFLLENBQUMseUNBQXlDLENBQUMsQ0FBQztRQUM3RCxDQUFDO1FBRUQsb0VBQW9FO1FBQ3BFLHFCQUFxQixDQUFDLEtBQU0sQ0FBQyxDQUFDO1FBQzlCLElBQUksT0FBUSxDQUFDLE1BQU0sR0FBRyxJQUFJLEVBQUUsQ0FBQztZQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxDQUFDLENBQUM7UUFDN0QsQ0FBQztRQUVELHFDQUFxQztRQUNyQyxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUNyRCxJQUF5QixFQUN6QixLQUFNLEVBQ04sT0FBUSxFQUNSLFVBQVcsRUFDWCxJQUFJLEVBQ0osV0FBVyxDQUNaLENBQUM7UUFDRixPQUFPLHVDQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxLQUFLLENBQUMsa0JBQWtCLENBQ3RCLEtBQWMsRUFDZCxNQUFlLEVBQ2YsV0FBb0I7UUFFcEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQy9FLE9BQU8sdUNBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FDcEIsTUFBZSxFQUNmLGFBQXVCLEVBQ3ZCLFdBQW9CO1FBRXBCLElBQUksYUFBYSxFQUFFLENBQUM7WUFDbEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLHVCQUF1QixDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzNFLE9BQU8sdUNBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkMsQ0FBQzthQUFNLElBQUksTUFBTSxFQUFFLENBQUM7WUFDbEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDdEUsT0FBTyx1Q0FBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2QyxDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUN4RSxDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxpQkFBaUIsQ0FDckIsSUFBWSxFQUNaLE9BQXdCLEVBQUU7UUFFMUIsSUFBSSxDQUFDO1lBQ0gsUUFBUSxJQUFJLEVBQUUsQ0FBQztnQkFDYixLQUFLLGdCQUFnQjtvQkFDbkIsT0FBTyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLFlBQXNCLENBQUMsQ0FBQztnQkFFbEUsS0FBSyxpQkFBaUI7b0JBQ3BCLE9BQU8sTUFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztnQkFFdkMsS0FBSyxpQkFBaUI7b0JBQ3BCLE9BQU8sTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLFlBQXNCLENBQUMsQ0FBQztnQkFFbkUsS0FBSyxvQkFBb0I7b0JBQ3ZCLE9BQU8sTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLFlBQXNCLENBQUMsQ0FBQztnQkFFdEUsS0FBSyxpQkFBaUI7b0JBQ3BCLE9BQU8sTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLE9BQWlCLEVBQUUsSUFBSSxFQUFFLFlBQXNCLENBQUMsQ0FBQztnQkFFNUYsS0FBSyxxQkFBcUI7b0JBQ3hCLE9BQU8sTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQ25DLElBQUksRUFBRSxPQUFpQixFQUN2QixJQUFJLEVBQUUsVUFBb0IsRUFDMUIsSUFBSSxFQUFFLFlBQXNCLENBQzdCLENBQUM7Z0JBRUosS0FBSyxxQkFBcUI7b0JBQ3hCLE9BQU8sTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQ25DLElBQUksRUFBRSxPQUFpQixFQUN2QixJQUFJLEVBQUUsVUFBb0IsRUFDMUIsSUFBSSxFQUFFLElBQWMsRUFDcEIsSUFBSSxFQUFFLFlBQXNCLENBQzdCLENBQUM7Z0JBRUosS0FBSyxxQkFBcUI7b0JBQ3hCLE9BQU8sTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQ3BDLElBQUksRUFBRSxJQUFjLEVBQ3BCLElBQUksRUFBRSxLQUFlLEVBQ3JCLElBQUksRUFBRSxPQUFpQixFQUN2QixJQUFJLEVBQUUsV0FBdUIsRUFDN0IsSUFBSSxFQUFFLElBQWMsRUFDcEIsSUFBSSxFQUFFLFlBQXNCLENBQzdCLENBQUM7Z0JBRUosS0FBSyxvQkFBb0I7b0JBQ3ZCLE9BQU8sTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQ2xDLElBQUksRUFBRSxLQUFlLEVBQ3JCLElBQUksRUFBRSxNQUFnQixFQUN0QixJQUFJLEVBQUUsWUFBc0IsQ0FDN0IsQ0FBQztnQkFFSixLQUFLLGlCQUFpQjtvQkFDcEIsT0FBTyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FDaEMsSUFBSSxFQUFFLE9BQWlCLEVBQ3ZCLElBQUksRUFBRSxjQUF5QixFQUMvQixJQUFJLEVBQUUsWUFBc0IsQ0FDN0IsQ0FBQztnQkFFSjtvQkFDRSxNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQzdDLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxZQUFZLDhCQUFRLEVBQUUsQ0FBQztnQkFDOUIsT0FBTyx1Q0FBcUIsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUMvQyxDQUFDO1lBQ0QsT0FBTyx3Q0FBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QyxDQUFDO0lBQ0gsQ0FBQztDQUNGOzs7QUNsUkQ7O0dBRUc7QUFFSCwwQkFBMEI7QUFDRDtBQUNEO0FBRXhCLFlBQVk7QUFDWTtBQUNJO0FBQ0Y7QUFDUztBQUNEO0FBRWxDLDZCQUE2QjtBQUNKO0FBQ0E7QUFFekIsZUFBZTtBQUNnQjs7O0FDcEIvQjs7R0FFRztBQUV3RDtBQUNJO0FBRXhELE1BQU0sZ0JBQWdCO0lBQ25CLFdBQVcsQ0FBYztJQUVqQztRQUNFLE1BQU0sTUFBTSxHQUFHLG1DQUFTLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCxLQUFLLENBQUMsa0JBQWtCO1FBQ3RCLElBQUksQ0FBQztZQUNILE1BQU0sV0FBVyxHQUFHLGtDQUFjLEVBQUUsQ0FBQztZQUNyQyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0QsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsaUJBQWlCO1FBQ3JCLElBQUksQ0FBQztZQUNILE1BQU0sVUFBVSxHQUFHLG1DQUFTLEVBQUUsQ0FBQztZQUMvQixNQUFNLG1CQUFtQixHQUFHO2dCQUMxQixHQUFHLFVBQVU7Z0JBQ2IsU0FBUyxFQUFFLGdCQUFnQjtnQkFDM0IsT0FBTyxFQUFFLFVBQVUsQ0FBQyxNQUFNLENBQUMsT0FBTzthQUNuQyxDQUFDO1lBQ0YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLG1CQUFtQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0QsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsaUJBQWlCO1FBQ3JCLElBQUksQ0FBQztZQUNILG1EQUFtRDtZQUNuRCxJQUFJLFVBQVUsR0FBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLDRCQUE0QixFQUFFLENBQUM7WUFDakYsSUFBSSxDQUFDO2dCQUNILFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDcEQsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsVUFBVSxHQUFHLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDekQsQ0FBQztZQUVELE1BQU0sV0FBVyxHQUFHLGtDQUFjLEVBQUUsQ0FBQztZQUNyQyxNQUFNLE1BQU0sR0FBRyxtQ0FBUyxFQUFFLENBQUM7WUFFM0IsTUFBTSxVQUFVLEdBQUc7Z0JBQ2pCLE1BQU0sRUFBRTtvQkFDTixNQUFNLEVBQUUsU0FBUztvQkFDakIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSTtvQkFDeEIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTztvQkFDOUIsU0FBUyxFQUFFLGdCQUFnQjtpQkFDNUI7Z0JBQ0QsY0FBYyxFQUFFLFVBQVU7Z0JBQzFCLE9BQU8sRUFBRTtvQkFDUCxVQUFVLEVBQUUsV0FBVyxDQUFDLFVBQVU7b0JBQ2xDLFdBQVcsRUFBRSxXQUFXLENBQUMsV0FBVztpQkFDckM7Z0JBQ0QsWUFBWSxFQUFFO29CQUNaLGNBQWMsRUFBRSxDQUFDO29CQUNqQixnQkFBZ0IsRUFBRSxDQUFDO29CQUNuQixrQkFBa0IsRUFBRSxDQUFDO2lCQUN0QjthQUNGLENBQUM7WUFFRixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FDbkI7Z0JBQ0UsTUFBTSxFQUFFLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUNqRCxTQUFTLEVBQUUsZ0JBQWdCO2FBQzVCLEVBQ0QsSUFBSSxFQUNKLENBQUMsQ0FDRixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMscUJBQXFCLENBQUMsR0FBVztRQUNyQyxJQUFJLENBQUM7WUFDSCxJQUFJLE9BQWUsQ0FBQztZQUVwQixRQUFRLEdBQUcsRUFBRSxDQUFDO2dCQUNaLEtBQUssZUFBZTtvQkFDbEIsT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7b0JBQzFDLE1BQU07Z0JBRVIsS0FBSyxjQUFjO29CQUNqQixPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztvQkFDekMsTUFBTTtnQkFFUixLQUFLLGNBQWM7b0JBQ2pCLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO29CQUN6QyxNQUFNO2dCQUVSO29CQUNFLE1BQU0sSUFBSSxLQUFLLENBQUMscUJBQXFCLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDaEQsQ0FBQztZQUVELE9BQU87Z0JBQ0wsUUFBUSxFQUFFO29CQUNSO3dCQUNFLEdBQUc7d0JBQ0gsUUFBUSxFQUFFLGtCQUFrQjt3QkFDNUIsSUFBSSxFQUFFLE9BQU87cUJBQ2Q7aUJBQ0Y7YUFDRixDQUFDO1FBQ0osQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPO2dCQUNMLFFBQVEsRUFBRTtvQkFDUjt3QkFDRSxHQUFHO3dCQUNILFFBQVEsRUFBRSxrQkFBa0I7d0JBQzVCLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7cUJBQ3hEO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0NBQ0Y7OztBQzdIRDs7R0FFRztBQVlJLE1BQU0sZ0JBQWdCLEdBQWlCO0lBQzVDO1FBQ0UsSUFBSSxFQUFFLGdCQUFnQjtRQUN0QixXQUFXLEVBQUUsa0NBQWtDO1FBQy9DLFdBQVcsRUFBRTtZQUNYLElBQUksRUFBRSxRQUFRO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLFlBQVksRUFBRTtvQkFDWixJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUscUNBQXFDO2lCQUNuRDthQUNGO1NBQ0Y7S0FDRjtJQUNEO1FBQ0UsSUFBSSxFQUFFLGlCQUFpQjtRQUN2QixXQUFXLEVBQUUsaURBQWlEO1FBQzlELFdBQVcsRUFBRTtZQUNYLElBQUksRUFBRSxRQUFRO1lBQ2QsVUFBVSxFQUFFLEVBQUU7U0FDZjtLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsaUJBQWlCO1FBQ3ZCLFdBQVcsRUFBRSwyREFBMkQ7UUFDeEUsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxxQ0FBcUM7aUJBQ25EO2FBQ0Y7U0FDRjtLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsb0JBQW9CO1FBQzFCLFdBQVcsRUFBRSwwQkFBMEI7UUFDdkMsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxxQ0FBcUM7aUJBQ25EO2FBQ0Y7U0FDRjtLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsaUJBQWlCO1FBQ3ZCLFdBQVcsRUFBRSw4QkFBOEI7UUFDM0MsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFO29CQUNQLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSwyQkFBMkI7aUJBQ3pDO2dCQUNELFlBQVksRUFBRTtvQkFDWixJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUscUNBQXFDO2lCQUNuRDthQUNGO1lBQ0QsUUFBUSxFQUFFLENBQUMsU0FBUyxDQUFDO1NBQ3RCO0tBQ0Y7SUFDRDtRQUNFLElBQUksRUFBRSxxQkFBcUI7UUFDM0IsV0FBVyxFQUFFLGlEQUFpRDtRQUM5RCxXQUFXLEVBQUU7WUFDWCxJQUFJLEVBQUUsUUFBUTtZQUNkLFVBQVUsRUFBRTtnQkFDVixPQUFPLEVBQUU7b0JBQ1AsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLG9CQUFvQjtpQkFDbEM7Z0JBQ0QsVUFBVSxFQUFFO29CQUNWLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSx3Q0FBd0M7aUJBQ3REO2dCQUNELFlBQVksRUFBRTtvQkFDWixJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUscUNBQXFDO2lCQUNuRDthQUNGO1lBQ0QsUUFBUSxFQUFFLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQztTQUNwQztLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUscUJBQXFCO1FBQzNCLFdBQVcsRUFBRSxvQkFBb0I7UUFDakMsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFO29CQUNQLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxvQkFBb0I7aUJBQ2xDO2dCQUNELFVBQVUsRUFBRTtvQkFDVixJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUsd0NBQXdDO2lCQUN0RDtnQkFDRCxJQUFJLEVBQUU7b0JBQ0osSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLHlCQUF5QjtpQkFDdkM7Z0JBQ0QsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxxQ0FBcUM7aUJBQ25EO2FBQ0Y7WUFDRCxRQUFRLEVBQUUsQ0FBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQztTQUM1QztLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUscUJBQXFCO1FBQzNCLFdBQVcsRUFBRSxtRUFBbUU7UUFDaEYsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSxFQUFFO29CQUNKLElBQUksRUFBRSxRQUFRO29CQUNkLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUM7b0JBQ3hCLFdBQVcsRUFBRSxpRUFBaUU7aUJBQy9FO2dCQUNELEtBQUssRUFBRTtvQkFDTCxJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUsNkNBQTZDO29CQUMxRCxTQUFTLEVBQUUsRUFBRTtpQkFDZDtnQkFDRCxPQUFPLEVBQUU7b0JBQ1AsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLHFEQUFxRDtvQkFDbEUsU0FBUyxFQUFFLElBQUk7aUJBQ2hCO2dCQUNELFdBQVcsRUFBRTtvQkFDWCxJQUFJLEVBQUUsT0FBTztvQkFDYixLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO29CQUN6QixXQUFXLEVBQ1QsaUhBQWlIO29CQUNuSCxRQUFRLEVBQUUsRUFBRTtpQkFDYjtnQkFDRCxJQUFJLEVBQUU7b0JBQ0osSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLGlDQUFpQztpQkFDL0M7Z0JBQ0QsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxxQ0FBcUM7aUJBQ25EO2FBQ0Y7WUFDRCxRQUFRLEVBQUUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLENBQUM7U0FDdEQ7S0FDRjtJQUNEO1FBQ0UsSUFBSSxFQUFFLG9CQUFvQjtRQUMxQixXQUFXLEVBQUUsOEJBQThCO1FBQzNDLFdBQVcsRUFBRTtZQUNYLElBQUksRUFBRSxRQUFRO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLEtBQUssRUFBRTtvQkFDTCxJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUsd0NBQXdDO2lCQUN0RDtnQkFDRCxNQUFNLEVBQUU7b0JBQ04sSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLGlDQUFpQztpQkFDL0M7Z0JBQ0QsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxxQ0FBcUM7aUJBQ25EO2FBQ0Y7U0FDRjtLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsaUJBQWlCO1FBQ3ZCLFdBQVcsRUFBRSw2REFBNkQ7UUFDMUUsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFO29CQUNQLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxpRUFBaUU7aUJBQy9FO2dCQUNELGNBQWMsRUFBRTtvQkFDZCxJQUFJLEVBQUUsU0FBUztvQkFDZixXQUFXLEVBQUUsa0VBQWtFO2lCQUNoRjtnQkFDRCxZQUFZLEVBQUU7b0JBQ1osSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLHFDQUFxQztpQkFDbkQ7YUFDRjtTQUNGO0tBQ0Y7Q0FDRixDQUFDO0FBRUssTUFBTSxvQkFBb0IsR0FBRztJQUNsQztRQUNFLEdBQUcsRUFBRSxlQUFlO1FBQ3BCLElBQUksRUFBRSw0QkFBNEI7UUFDbEMsV0FBVyxFQUFFLHFEQUFxRDtRQUNsRSxRQUFRLEVBQUUsa0JBQWtCO0tBQzdCO0lBQ0Q7UUFDRSxHQUFHLEVBQUUsY0FBYztRQUNuQixJQUFJLEVBQUUsMEJBQTBCO1FBQ2hDLFdBQVcsRUFBRSw4QkFBOEI7UUFDM0MsUUFBUSxFQUFFLGtCQUFrQjtLQUM3QjtJQUNEO1FBQ0UsR0FBRyxFQUFFLGNBQWM7UUFDbkIsSUFBSSxFQUFFLG1CQUFtQjtRQUN6QixXQUFXLEVBQUUsMENBQTBDO1FBQ3ZELFFBQVEsRUFBRSxrQkFBa0I7S0FDN0I7Q0FDRixDQUFDOzs7QUN2T0Y7O0dBRUc7QUFFZ0U7QUFDYztBQU1yQztBQUNDO0FBQ1c7QUFDUTtBQUNnQjtBQUV6RSxNQUFNLFlBQVk7SUFDZixNQUFNLENBQVM7SUFDZixZQUFZLENBQWU7SUFDM0IsZ0JBQWdCLENBQW1CO0lBQ25DLE1BQU0sQ0FBK0I7SUFFN0M7UUFDRSxJQUFJLENBQUMsTUFBTSxHQUFHLG1DQUFTLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksd0JBQU0sQ0FDdEI7WUFDRSxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSTtZQUM3QixPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTztTQUNwQyxFQUNEO1lBQ0UsWUFBWSxFQUFFO2dCQUNaLEtBQUssRUFBRSxFQUFFO2dCQUNULFNBQVMsRUFBRSxFQUFFO2FBQ2Q7U0FDRixDQUNGLENBQUM7UUFFRixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsbUNBQXFCLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ3JFLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFDakQsT0FBTyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxvQ0FBc0IsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMvRCxPQUFPO2dCQUNMLEtBQUssRUFBRSxnQkFBZ0I7YUFDeEIsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLHFCQUFxQjtRQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLHdDQUEwQixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ25FLE9BQU87Z0JBQ0wsU0FBUyxFQUFFLG9CQUFvQjthQUNoQyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLHVDQUF5QixFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUN6RSxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztZQUMvQixPQUFPLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2hFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFLO1FBQ1QsTUFBTSxTQUFTLEdBQUcsSUFBSSxpQ0FBb0IsRUFBRSxDQUFDO1FBQzdDLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckMsMkVBQTJFO0lBQzdFLENBQUM7Q0FDRjs7O0FDM0VELE1BQU0sZ0NBQTRCLHNCOzs7QUNBbEMsTUFBTSw2QkFBNEIsbUI7Ozs7Ozs7OztBQ0FsQzs7R0FFRztBQUUyQjtBQUNOO0FBQ2lCO0FBQzBCO0FBQ1U7QUFDc0I7QUFDMUI7QUFDNUI7QUFDSDtBQUNjO0FBQ1E7QUFDZ0I7QUFNcEM7QUFFckMsTUFBTSxnQkFBZ0I7SUFDbkIsR0FBRyxDQUFzQjtJQUN6QixNQUFNLENBQStCO0lBQ3JDLFlBQVksQ0FBZTtJQUMzQixnQkFBZ0IsQ0FBbUI7SUFDbkMsVUFBVSxHQUFvRSxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3hGLElBQUksQ0FBUztJQUVyQixZQUFZLE9BQWUsSUFBSTtRQUM3QixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLG1DQUFTLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMsR0FBRyxHQUFHLDBCQUFPLEVBQUUsQ0FBQztRQUVyQixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFTyxlQUFlO1FBQ3JCLG9CQUFvQjtRQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQywrQkFBWSxFQUFFLENBQUMsQ0FBQztRQUU3QiwyRUFBMkU7UUFDM0UsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQ1YsdUJBQUksQ0FBQztZQUNILE1BQU0sRUFBRSxHQUFHLEVBQUUsc0RBQXNEO1lBQ25FLGNBQWMsRUFBRSxDQUFDLGdCQUFnQixDQUFDO1NBQ25DLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVPLFdBQVc7UUFDakIsMERBQTBEO1FBQzFELElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFM0QsOERBQThEO1FBQzlELElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUU3RCx3QkFBd0I7UUFDeEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO1lBQ25DLEdBQUcsQ0FBQyxJQUFJLENBQUM7Z0JBQ1AsTUFBTSxFQUFFLFNBQVM7Z0JBQ2pCLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJO2dCQUMvQixPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTztnQkFDbkMsVUFBVSxFQUFFLENBQUMsaUJBQWlCLEVBQUUsS0FBSyxDQUFDO2FBQ3ZDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxHQUFvQixFQUFFLEdBQXFCO1FBQzVFLG9CQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLE1BQU0sa0JBQWtCLENBQUMsQ0FBQztRQUV0RCxJQUFJLENBQUM7WUFDSCxnQ0FBZ0M7WUFDaEMsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBVyxDQUFDO1lBQzFELElBQUksU0FBb0QsQ0FBQztZQUV6RCxJQUFJLFNBQVMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUNoRCxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUN6RCxJQUFJLGlCQUFpQixZQUFZLG1EQUE2QixFQUFFLENBQUM7b0JBQy9ELFNBQVMsR0FBRyxpQkFBaUIsQ0FBQztnQkFDaEMsQ0FBQztxQkFBTSxDQUFDO29CQUNOLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO3dCQUNuQixPQUFPLEVBQUUsS0FBSzt3QkFDZCxLQUFLLEVBQUU7NEJBQ0wsSUFBSSxFQUFFLENBQUMsS0FBSzs0QkFDWixPQUFPLEVBQUUscUVBQXFFO3lCQUMvRTt3QkFDRCxFQUFFLEVBQUUsSUFBSTtxQkFDVCxDQUFDLENBQUM7b0JBQ0gsT0FBTztnQkFDVCxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxJQUFJLENBQUMsU0FBUyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTSxJQUFJLHFDQUFtQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNoRix1Q0FBdUM7Z0JBQ3ZDLFNBQVMsR0FBRyxJQUFJLG1EQUE2QixDQUFDO29CQUM1QyxrQkFBa0IsRUFBRSxHQUFXLEVBQUUsQ0FBQyxvQ0FBVSxFQUFFO29CQUM5QyxvQkFBb0IsRUFBRSxDQUFDLFNBQWlCLEVBQVEsRUFBRTt3QkFDaEQsb0JBQU0sQ0FBQyxJQUFJLENBQUMsK0NBQStDLFNBQVMsRUFBRSxDQUFDLENBQUM7d0JBQ3hFLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxTQUFVLENBQUMsQ0FBQztvQkFDN0MsQ0FBQztvQkFDRCxlQUFlLEVBQUUsQ0FBQyxTQUFpQixFQUFRLEVBQUU7d0JBQzNDLG9CQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO3dCQUMzRCxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDcEMsQ0FBQztpQkFDRixDQUFDLENBQUM7Z0JBRUgsMkRBQTJEO2dCQUMzRCxTQUFTLENBQUMsT0FBTyxHQUFHLEdBQVMsRUFBRTtvQkFDN0IsTUFBTSxHQUFHLEdBQUcsU0FBVSxDQUFDLFNBQVMsQ0FBQztvQkFDakMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQzt3QkFDcEMsb0JBQU0sQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLEdBQUcsZ0NBQWdDLENBQUMsQ0FBQzt3QkFDakYsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQzlCLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDO2dCQUVGLDBDQUEwQztnQkFDMUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN0QyxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbEMsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGdFQUFnRTtnQkFDaEUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ25CLE9BQU8sRUFBRSxLQUFLO29CQUNkLEtBQUssRUFBRTt3QkFDTCxJQUFJLEVBQUUsQ0FBQyxLQUFLO3dCQUNaLE9BQU8sRUFBRSwyQ0FBMkM7cUJBQ3JEO29CQUNELEVBQUUsRUFBRSxJQUFJO2lCQUNULENBQUMsQ0FBQztnQkFDSCxPQUFPO1lBQ1QsQ0FBQztZQUVELHdDQUF3QztZQUN4QyxNQUFNLFNBQVMsQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEQsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixvQkFBTSxDQUFDLEtBQUssQ0FBQyx5Q0FBeUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMvRCxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNyQixHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztvQkFDbkIsT0FBTyxFQUFFLEtBQUs7b0JBQ2QsS0FBSyxFQUFFO3dCQUNMLElBQUksRUFBRSxDQUFDLEtBQUs7d0JBQ1osT0FBTyxFQUFFLHVCQUF1QjtxQkFDakM7b0JBQ0QsRUFBRSxFQUFFLElBQUk7aUJBQ1QsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLG1CQUFtQixDQUFDLEdBQW9CLEVBQUUsR0FBcUI7UUFDM0Usb0JBQU0sQ0FBQyxJQUFJLENBQUMseURBQXlELENBQUMsQ0FBQztRQUV2RSxJQUFJLENBQUM7WUFDSCxNQUFNLFNBQVMsR0FBRyxJQUFJLDZCQUFrQixDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMzRCxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBRXBELEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRTtnQkFDbkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzlDLENBQUMsQ0FBQyxDQUFDO1lBRUgsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3RDLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNsQyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG9CQUFNLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3RELElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3JCLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO29CQUNuQixPQUFPLEVBQUUsS0FBSztvQkFDZCxLQUFLLEVBQUU7d0JBQ0wsSUFBSSxFQUFFLENBQUMsS0FBSzt3QkFDWixPQUFPLEVBQUUsdUJBQXVCO3FCQUNqQztvQkFDRCxFQUFFLEVBQUUsSUFBSTtpQkFDVCxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsR0FBb0IsRUFBRSxHQUFxQjtRQUN4RSxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLFNBQW1CLENBQUM7UUFFaEQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFakQsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsU0FBUyxZQUFZLDZCQUFrQixDQUFDLEVBQUUsQ0FBQztnQkFDN0QsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ25CLE9BQU8sRUFBRSxLQUFLO29CQUNkLEtBQUssRUFBRTt3QkFDTCxJQUFJLEVBQUUsQ0FBQyxLQUFLO3dCQUNaLE9BQU8sRUFBRSxxRUFBcUU7cUJBQy9FO29CQUNELEVBQUUsRUFBRSxJQUFJO2lCQUNULENBQUMsQ0FBQztnQkFDSCxPQUFPO1lBQ1QsQ0FBQztZQUVELE1BQU0sU0FBUyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2Ysb0JBQU0sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDckIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ25CLE9BQU8sRUFBRSxLQUFLO29CQUNkLEtBQUssRUFBRTt3QkFDTCxJQUFJLEVBQUUsQ0FBQyxLQUFLO3dCQUNaLE9BQU8sRUFBRSx1QkFBdUI7cUJBQ2pDO29CQUNELEVBQUUsRUFBRSxJQUFJO2lCQUNULENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVPLGVBQWU7UUFDckIsTUFBTSxNQUFNLEdBQUcsSUFBSSx3QkFBTSxDQUN2QjtZQUNFLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJO1lBQzdCLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPO1NBQ3BDLEVBQ0Q7WUFDRSxZQUFZLEVBQUU7Z0JBQ1osS0FBSyxFQUFFLEVBQUU7Z0JBQ1QsU0FBUyxFQUFFLEVBQUU7YUFDZDtTQUNGLENBQ0YsQ0FBQztRQUVGLHNCQUFzQjtRQUN0QixNQUFNLENBQUMsaUJBQWlCLENBQUMsbUNBQXFCLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ2hFLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFDakQsT0FBTyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLGlCQUFpQixDQUFDLG9DQUFzQixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzFELE9BQU87Z0JBQ0wsS0FBSyxFQUFFLGdCQUFnQjthQUN4QixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCwwQkFBMEI7UUFDMUIsTUFBTSxDQUFDLGlCQUFpQixDQUFDLHdDQUEwQixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzlELE9BQU87Z0JBQ0wsU0FBUyxFQUFFLG9CQUFvQjthQUNoQyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsaUJBQWlCLENBQUMsdUNBQXlCLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ3BFLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO1lBQy9CLE9BQU8sTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsS0FBSyxDQUFDLEtBQUs7UUFDVCxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFhLEVBQUUsRUFBRTtnQkFDMUQsSUFBSSxLQUFLLEVBQUUsQ0FBQztvQkFDVixvQkFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDcEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNkLE9BQU87Z0JBQ1QsQ0FBQztnQkFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLHlDQUF5QyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDbEUsT0FBTyxDQUFDLEdBQUcsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBd0JuQixDQUFDLENBQUM7Z0JBQ0ssT0FBTyxFQUFFLENBQUM7WUFDWixDQUFDLENBQUMsQ0FBQztZQUVILHlCQUF5QjtZQUN6QixPQUFPLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDOUIsb0JBQU0sQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsQ0FBQztnQkFFNUMsS0FBSyxNQUFNLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztvQkFDckQsSUFBSSxDQUFDO3dCQUNILG9CQUFNLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO3dCQUMxRCxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDMUIsQ0FBQztvQkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO3dCQUNmLG9CQUFNLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxTQUFTLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDM0UsQ0FBQztnQkFDSCxDQUFDO2dCQUVELElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3hCLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFO29CQUNoQixvQkFBTSxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO29CQUM3QyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNsQixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1lBRUgsT0FBTyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQy9CLG9CQUFNLENBQUMsSUFBSSxDQUFDLDhCQUE4QixDQUFDLENBQUM7Z0JBRTVDLEtBQUssTUFBTSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7b0JBQ3JELElBQUksQ0FBQzt3QkFDSCxvQkFBTSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsU0FBUyxFQUFFLENBQUMsQ0FBQzt3QkFDMUQsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQzFCLENBQUM7b0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQzt3QkFDZixvQkFBTSxDQUFDLEtBQUssQ0FBQyx1Q0FBdUMsU0FBUyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQzNFLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN4QixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRTtvQkFDaEIsb0JBQU0sQ0FBQyxJQUFJLENBQUMsK0JBQStCLENBQUMsQ0FBQztvQkFDN0MsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbEIsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFJO1FBQ1IsOEJBQThCO1FBQzlCLEtBQUssTUFBTSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDckQsSUFBSSxDQUFDO2dCQUNILE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzFCLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLG9CQUFNLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxTQUFTLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMzRSxDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDMUIsQ0FBQztDQUNGOzs7QUMxVkQ7O0dBRUc7QUFFNkI7QUFDSTs7O0FDTHBDOztHQUVHO0FBRTBCO0FBQ0M7QUFDRzs7OztBQ0pqQzs7R0FFRztBQUVpQztBQUNTO0FBQ1c7QUFDdEI7QUFDYTtBQUNrQjtBQUNDO0FBQ1Q7QUFDVztBQUNYO0FBRXpEOztHQUVHO0FBQ0gsTUFBTSxRQUFRO0lBQ1E7SUFBcEIsWUFBb0IsT0FBZ0I7UUFBaEIsWUFBTyxHQUFQLE9BQU8sQ0FBUztJQUFHLENBQUM7SUFFeEMsa0JBQWtCLENBQUMsS0FBYztRQUMvQixNQUFNLEdBQUcsR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFcEYsaUNBQWlDO1FBQ2pDLElBQUksc0RBQXNELENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDckUsT0FBTywwRkFBMEYsQ0FBQztRQUNwRyxDQUFDO1FBRUQsc0VBQXNFO1FBQ3RFLElBQUksS0FBSyxZQUFZLEtBQUssRUFBRSxDQUFDO1lBQzNCLHFFQUFxRTtZQUNyRSxJQUNFLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLHdEQUF3RCxDQUFDO2dCQUNoRixLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQztnQkFDL0MsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUM7Z0JBQzVDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDO2dCQUN4QyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxFQUNqRCxDQUFDO2dCQUNELE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQztZQUN2QixDQUFDO1lBRUQsMkNBQTJDO1lBQzNDLE1BQU0sU0FBUyxHQUFHLEdBQUc7aUJBQ2xCLE9BQU8sQ0FDTix5S0FBeUssRUFDekssRUFBRSxDQUNIO2lCQUNBLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLENBQUMsQ0FBQyx5QkFBeUI7aUJBQzFELE9BQU8sQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUMsMkJBQTJCO2lCQUN4RCxJQUFJLEVBQUUsQ0FBQztZQUVWLE9BQU8sU0FBUyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDcEMsQ0FBQztRQUVELE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxTQUFTLENBQUMsTUFBZSxFQUFFLFFBQVEsR0FBRyxDQUFDO1FBQ3JDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssSUFBSSxDQUFDO1FBQ2xFLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hGLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQztRQUNsQywwREFBMEQ7UUFDMUQsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzVCLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdkIsQ0FBQztRQUNELE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVELFlBQVksQ0FBQyxNQUFlLEVBQUUsT0FBZ0I7UUFDNUMseURBQXlEO1FBQ3pELElBQUksTUFBTSxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsSUFBSSxTQUFTLElBQUksTUFBTSxFQUFFLENBQUM7WUFDaEUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDNUIsQ0FBQzthQUFNLENBQUM7WUFDTixxQkFBcUI7WUFDckIsTUFBTSxPQUFPLEdBQUc7Z0JBQ2QsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsT0FBTyxFQUFFLE9BQU8sSUFBSyxNQUErQixFQUFFLE9BQU8sSUFBSSxTQUFTO2dCQUMxRSxJQUFJLEVBQUUsTUFBTTthQUNiLENBQUM7WUFDRixJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM3QixDQUFDO0lBQ0gsQ0FBQztJQUVELFVBQVUsQ0FBQyxLQUFjLEVBQUUsSUFBYTtRQUN0QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0MsTUFBTSxPQUFPLEdBQUcsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxJQUFJLFNBQVMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFXLENBQUM7UUFDL0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVELGVBQWUsQ0FBQyxPQUFlLEVBQUUsT0FBZTtRQUM5QyxNQUFNLE9BQU8sR0FBRztZQUNkLE9BQU8sRUFBRSxLQUFLO1lBQ2QsT0FBTztZQUNQLE1BQU0sRUFBRSxPQUFPO1lBQ2YsS0FBSyxFQUFFLGdCQUFnQixPQUFPLCtCQUErQjtTQUNyRCxDQUFDO1FBQ1gsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDN0IsQ0FBQztDQUNGO0FBRUQsS0FBSyxVQUFVLElBQUk7SUFDakIsTUFBTSxNQUFNLEdBQUcsbUNBQVMsRUFBRSxDQUFDO0lBQzNCLE1BQU0sT0FBTyxHQUFHLElBQUksMENBQU8sRUFBRSxDQUFDO0lBQzlCLE1BQU0sS0FBSyxHQUFHLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRXBDLE9BQU87U0FDSixJQUFJLENBQUMsU0FBUyxDQUFDO1NBQ2YsV0FBVyxDQUFDLGtDQUFrQyxDQUFDO1NBQy9DLE1BQU0sQ0FBQyxXQUFXLEVBQUUsZ0RBQWdELENBQUM7U0FDckUsa0JBQWtCLEVBQUUsQ0FBQztJQUV4QixPQUFPO1NBQ0osT0FBTyxDQUFDLE9BQU8sQ0FBQztTQUNoQixXQUFXLENBQUMsNkRBQTZELENBQUM7U0FDMUUsTUFBTSxDQUFDLHlCQUF5QixFQUFFLDBCQUEwQixFQUFFLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQztTQUMvRixNQUFNLENBQUMsS0FBSyxFQUFFLElBQTBCLEVBQUUsRUFBRTtRQUMzQyxNQUFNLFdBQVcsR0FBRyxTQUFTLENBQUM7UUFDOUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDO1FBQzNGLE1BQU0sV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDaEUsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUwsT0FBTztTQUNKLE9BQU8sQ0FBQyxRQUFRLENBQUM7U0FDakIsV0FBVyxDQUFDLGlEQUFpRCxDQUFDO1NBQzlELE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRTtRQUNqQixNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUMxQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFTCxPQUFPO1NBQ0osT0FBTyxDQUFDLFFBQVEsQ0FBQztTQUNqQixXQUFXLENBQUMsd0NBQXdDLENBQUM7U0FDckQsTUFBTSxDQUFDLEtBQUssSUFBSSxFQUFFO1FBQ2pCLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQztRQUM5QixNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDMUQsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUwsT0FBTztTQUNKLE9BQU8sQ0FBQyxTQUFTLENBQUM7U0FDbEIsV0FBVyxDQUFDLDRFQUE0RSxDQUFDO1NBQ3pGLE1BQU0sQ0FBQyxhQUFhLEVBQUUsMERBQTBELENBQUM7U0FDakYsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUE0QixFQUFFLEVBQUU7UUFDN0MsS0FBSyxVQUFVLGlCQUFpQjtZQUM5QixJQUFJLENBQUM7Z0JBQ0gsMkNBQTJDO2dCQUMzQyxNQUFNLGNBQWMsR0FBRywyQ0FBd0IsRUFBRSxDQUFDO2dCQUVsRCxNQUFNLE9BQU8sR0FBRyxNQUFNLG1DQUFnQixDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQzNELE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUV0QixPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsQ0FBQztZQUM3QyxDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDOUIsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLFdBQVcsR0FBRyxNQUFNLGlCQUFpQixFQUFFLENBQUM7UUFDOUMsSUFBSSxXQUFXLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDMUIsS0FBSyxDQUFDLFlBQVksQ0FDaEI7Z0JBQ0UsU0FBUyxFQUFFLElBQUk7Z0JBQ2YsY0FBYyxFQUFFLFdBQVcsQ0FBQyxjQUFjO2FBQzNDLEVBQ0QsbUJBQW1CLENBQ3BCLENBQUM7WUFDRixPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLENBQUMsV0FBVyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDNUQsSUFBSSxJQUFJLENBQUMsUUFBUTtZQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDNUMsTUFBTSxNQUFNLEdBQUcseURBQVMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFFOUUsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLGlCQUFpQixFQUFFLENBQUM7UUFDbkQsSUFBSSxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUMvQixLQUFLLENBQUMsWUFBWSxDQUNoQjtnQkFDRSxTQUFTLEVBQUUsSUFBSTtnQkFDZixjQUFjLEVBQUUsZ0JBQWdCLENBQUMsY0FBYztnQkFDL0MsUUFBUSxFQUFFLE1BQU0sQ0FBQyxNQUFNLElBQUksSUFBSTthQUNoQyxFQUNELDhCQUE4QixDQUMvQixDQUFDO1FBQ0osQ0FBQzthQUFNLENBQUM7WUFDTixLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxDQUFDLHNDQUFzQyxDQUFDLENBQUMsQ0FBQztRQUN0RSxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFTCxrQkFBa0I7SUFDbEIsT0FBTztTQUNKLE9BQU8sQ0FBQyxPQUFPLENBQUM7U0FDaEIsV0FBVyxDQUFDLDBCQUEwQixDQUFDO1NBQ3ZDLE1BQU0sQ0FBQywyQkFBMkIsRUFBRSw0QkFBNEIsQ0FBQztTQUNqRSxNQUFNLENBQUMsS0FBSyxFQUFFLElBQThCLEVBQUUsRUFBRTtRQUMvQyxNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQy9ELEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDN0IsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVMLHFCQUFxQjtJQUNyQixPQUFPO1NBQ0osT0FBTyxDQUFDLFFBQVEsQ0FBQztTQUNqQixXQUFXLENBQUMseUJBQXlCLENBQUM7U0FDdEMsY0FBYyxDQUFDLHlCQUF5QixFQUFFLGdCQUFnQixDQUFDO1NBQzNELE1BQU0sQ0FBQywyQkFBMkIsRUFBRSw0QkFBNEIsQ0FBQztTQUNqRSxNQUFNLENBQUMsS0FBSyxFQUFFLElBQStDLEVBQUUsRUFBRTtRQUNoRSxNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDN0UsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUwsK0NBQStDO0lBQy9DLE1BQU0sZUFBZSxHQUFHLE9BQU87U0FDNUIsT0FBTyxDQUFDLFVBQVUsQ0FBQztTQUNuQixXQUFXLENBQUMsMkNBQTJDLENBQUMsQ0FBQztJQUU1RCw0QkFBNEI7SUFDNUIsZUFBZTtTQUNaLE9BQU8sQ0FBQyxNQUFNLENBQUM7U0FDZixXQUFXLENBQUMscUNBQXFDLENBQUM7U0FDbEQsTUFBTSxDQUFDLHNCQUFzQixFQUFFLHFDQUFxQyxFQUFFLElBQUksQ0FBQztTQUMzRSxNQUFNLENBQUMsdUJBQXVCLEVBQUUsaUNBQWlDLENBQUM7U0FDbEUsTUFBTSxDQUFDLDJCQUEyQixFQUFFLDRCQUE0QixDQUFDO1NBQ2pFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBOEQsRUFBRSxFQUFFO1FBQy9FLE1BQU0sV0FBVyxHQUFHLElBQUksd0JBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUM7WUFDSCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN6QyxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3BGLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDN0IsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVMLDhCQUE4QjtJQUM5QixlQUFlO1NBQ1osT0FBTyxDQUFDLFFBQVEsQ0FBQztTQUNqQixXQUFXLENBQUMsbUJBQW1CLENBQUM7U0FDaEMsTUFBTSxDQUFDLGdCQUFnQixFQUFFLDRCQUE0QixDQUFDO1NBQ3RELE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxnQ0FBZ0MsQ0FBQztTQUM1RCxNQUFNLENBQUMsMkJBQTJCLEVBQUUsNEJBQTRCLENBQUM7U0FDakUsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUF3RSxFQUFFLEVBQUU7UUFDekYsTUFBTSxXQUFXLEdBQUcsSUFBSSx3QkFBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQztZQUNILElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN2QixNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQzNFLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDN0IsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDdkIsTUFBTSxNQUFNLEdBQUcsTUFBTSxXQUFXLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUMzRSxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzdCLENBQUM7aUJBQU0sQ0FBQztnQkFDTiw2REFBNkQ7Z0JBQzdELE9BQU8sQ0FBQyxHQUFHLENBQUMsNENBQTRDLENBQUMsQ0FBQztnQkFDMUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO2dCQUNuQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUN4QixPQUFPLENBQUMsR0FBRyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7Z0JBQ3ZFLE9BQU8sQ0FBQyxHQUFHLENBQUMsNkRBQTZELENBQUMsQ0FBQztnQkFDM0UsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5REFBeUQsQ0FBQyxDQUFDO2dCQUN2RSxPQUFPLENBQUMsR0FBRyxDQUFDLHVEQUF1RCxDQUFDLENBQUM7Z0JBQ3JFLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEIsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFTCx5QkFBeUI7SUFDekIsT0FBTztTQUNKLE9BQU8sQ0FBQyxTQUFTLENBQUM7U0FDbEIsV0FBVyxDQUFDLG1CQUFtQixDQUFDO1NBQ2hDLGNBQWMsQ0FBQyxnQkFBZ0IsRUFBRSxTQUFTLENBQUM7U0FDM0MsY0FBYyxDQUFDLHNCQUFzQixFQUFFLDZCQUE2QixDQUFDO1NBQ3JFLGNBQWMsQ0FBQyxtQkFBbUIsRUFBRSxpQkFBaUIsQ0FBQztTQUN0RCxNQUFNLENBQUMsMkJBQTJCLEVBQUUsNEJBQTRCLENBQUM7U0FDakUsTUFBTSxDQUNMLEtBQUssRUFBRSxJQUErRSxFQUFFLEVBQUU7UUFDeEYsTUFBTSxXQUFXLEdBQUcsSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxXQUFXLENBQUMsYUFBYSxDQUM1QyxJQUFJLENBQUMsTUFBTSxFQUNYLElBQUksQ0FBQyxTQUFTLEVBQ2QsSUFBSSxDQUFDLElBQUksRUFDVCxJQUFJLENBQUMsV0FBVyxDQUNqQixDQUFDO1lBQ0YsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUMsQ0FDRixDQUFDO0lBRUosc0NBQXNDO0lBQ3RDLE9BQU87U0FDSixPQUFPLENBQUMsU0FBUyxDQUFDO1NBQ2xCLFdBQVcsQ0FBQyxrRUFBa0UsQ0FBQztTQUMvRSxjQUFjLENBQUMsbUJBQW1CLEVBQUUsc0RBQXNELENBQUM7U0FDM0YsY0FBYyxDQUFDLGlCQUFpQixFQUFFLDZCQUE2QixDQUFDO1NBQ2hFLGNBQWMsQ0FBQyxxQkFBcUIsRUFBRSxxQ0FBcUMsQ0FBQztTQUM1RSxjQUFjLENBQ2IscUJBQXFCLEVBQ3JCLDRGQUE0RixDQUM3RjtTQUNBLE1BQU0sQ0FBQyxlQUFlLEVBQUUsc0JBQXNCLENBQUM7U0FDL0MsTUFBTSxDQUFDLDJCQUEyQixFQUFFLDRCQUE0QixDQUFDO1NBQ2pFLE1BQU0sQ0FDTCxLQUFLLEVBQUUsSUFPTixFQUFFLEVBQUU7UUFDSCxNQUFNLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUM7WUFDSCxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFLENBQUM7Z0JBQ25ELEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQyxDQUFDO2dCQUMvRCxPQUFPO1lBQ1QsQ0FBQztZQUVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLO2lCQUMxQixLQUFLLENBQUMsR0FBRyxDQUFDO2lCQUNWLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO2lCQUNwQixNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbkIsTUFBTSxNQUFNLEdBQUcsTUFBTSxjQUFjLENBQUMsY0FBYyxDQUNoRCxJQUFJLENBQUMsSUFBSSxFQUNULElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLE9BQU8sRUFDWixVQUFVLEVBQ1YsSUFBSSxDQUFDLElBQUksRUFDVCxJQUFJLENBQUMsV0FBVyxDQUNqQixDQUFDO1lBQ0YsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUMsQ0FDRixDQUFDO0lBRUosT0FBTztTQUNKLE9BQU8sQ0FBQyxLQUFLLENBQUM7U0FDZCxXQUFXLENBQUMsMkNBQTJDLENBQUM7U0FDeEQsTUFBTSxDQUFDLG1CQUFtQixFQUFFLDRCQUE0QixFQUFFLE9BQU8sQ0FBQztTQUNsRSxNQUFNLENBQUMsbUJBQW1CLEVBQUUsdUNBQXVDLEVBQUUsTUFBTSxDQUFDO1NBQzVFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBc0MsRUFBRSxFQUFFO1FBQ3ZELElBQUksQ0FBQztZQUNILElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztnQkFDekIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztnQkFDeEQsTUFBTSxVQUFVLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDOUMsTUFBTSxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDM0IsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLDJGQUEyRjtnQkFDM0Ysb0RBQW9EO2dCQUNwRCxNQUFNLE1BQU0sR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO2dCQUNsQyxNQUFNLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN2QixDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixzREFBc0Q7WUFDdEQsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixLQUFLLE1BQU0sRUFBRSxDQUFDO2dCQUM5QyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsS0FBSyxJQUFJLENBQUMsQ0FBQztZQUM3RCxDQUFDO1lBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFTCxpQkFBaUI7SUFDakIsT0FBTztTQUNKLE9BQU8sQ0FBQyxPQUFPLENBQUM7U0FDaEIsV0FBVyxDQUFDLDBCQUEwQixDQUFDO1NBQ3ZDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsdUJBQXVCLENBQUM7U0FDN0MsTUFBTSxDQUFDLGdCQUFnQixFQUFFLGdDQUFnQyxDQUFDO1NBQzFELE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBNEMsRUFBRSxFQUFFO1FBQzdELElBQUksQ0FBQztZQUNILE1BQU0sV0FBVyxHQUFHLGdCQUFnQixDQUFDO1lBRXJDLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNkLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUNsQixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNwRCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQzt3QkFDM0MsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO3dCQUNmLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztxQkFDOUIsQ0FBQyxDQUFDLENBQUM7b0JBQ0osT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbEQsQ0FBQztZQUNILENBQUM7aUJBQU0sQ0FBQztnQkFDTixPQUFPLENBQUMsR0FBRyxDQUFDLDZCQUE2QixDQUFDLENBQUM7Z0JBRTNDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7b0JBQ2xDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUMxQyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7b0JBRXRDLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO3dCQUNsQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7d0JBQ2pELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQzt3QkFFckQsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQzs0QkFDdkMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDOzRCQUM5QixNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBb0IsRUFBRSxFQUFFO2dDQUNwRSxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQztnQ0FDNUUsTUFBTSxRQUFRLEdBQUksSUFBaUMsQ0FBQyxXQUFXLENBQUM7Z0NBQ2hFLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxHQUFHLEtBQUssUUFBUSxJQUFJLGdCQUFnQixHQUFHLFlBQVksRUFBRSxDQUFDLENBQUM7NEJBQy9FLENBQUMsQ0FBQyxDQUFDO3dCQUNMLENBQUM7b0JBQ0gsQ0FBQztvQkFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNsQixDQUFDLENBQUMsQ0FBQztnQkFFSCxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsV0FBVyxDQUFDLE1BQU0sa0JBQWtCLENBQUMsQ0FBQztnQkFDNUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO2dCQUMxRCxPQUFPLENBQUMsR0FBRyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7WUFDeEQsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFTCxPQUFPLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBRUQsK0NBQStDO0FBQy9DLE9BQU8sQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRTtJQUN4QiwyRUFBMkU7SUFDM0UsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixDQUFDLENBQUMsQ0FBQztBQUVILE9BQU8sQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRTtJQUN6QiwyRUFBMkU7SUFDM0UsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixDQUFDLENBQUMsQ0FBQztBQUVILGdCQUFnQjtBQUNoQixJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtJQUNyQixzREFBc0Q7SUFDdEQsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixLQUFLLE1BQU0sRUFBRSxDQUFDO1FBQzlDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixLQUFLLElBQUksQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC9leHRlcm5hbCBjb21tb25qczIgXCJjb21tYW5kZXJcIj9jNDQ4Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2hhcmVkL3hocy51dGlscy50cz9iMjVlIiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9hdXRoL2F1dGguc2VydmljZS50cz82OWZlIiwid2VicGFjazovL3hocy1tY3AvZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiPzk4NWQiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL2ZlZWRzL2ZlZWQuc2VydmljZS50cz82NGI3Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2hhcmVkL3RpdGxlLXZhbGlkYXRvci50cz8yNDM5Iiwid2VicGFjazovL3hocy1tY3AvZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImNyeXB0b1wiP2E4YjIiLCJ3ZWJwYWNrOi8veGhzLW1jcC9leHRlcm5hbCBjb21tb25qczIgXCJub2RlLWZldGNoXCI/MzZlNSIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NoYXJlZC9pbWFnZS1kb3dubG9hZGVyLnRzPzUzNTYiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL3B1Ymxpc2hpbmcvcHVibGlzaC1iYXNlLnNlcnZpY2UudHM/Njc4YyIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvcHVibGlzaGluZy9wdWJsaXNoLWltYWdlLnNlcnZpY2UudHM/ZDVmNCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvcHVibGlzaGluZy9wdWJsaXNoLXZpZGVvLnNlcnZpY2UudHM/NTQwNiIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvcHVibGlzaGluZy9wdWJsaXNoLnNlcnZpY2UudHM/MTdlOSIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NlcnZlci9oYW5kbGVycy90b29sLmhhbmRsZXJzLnRzPzdmNzQiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQvaW5kZXgudHM/ODQ1ZSIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NlcnZlci9oYW5kbGVycy9yZXNvdXJjZS5oYW5kbGVycy50cz9hYTM5Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2VydmVyL3NjaGVtYXMvdG9vbC5zY2hlbWFzLnRzP2RmOGYiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zZXJ2ZXIvbWNwLnNlcnZlci50cz8zMzk0Iiwid2VicGFjazovL3hocy1tY3AvZXh0ZXJuYWwgY29tbW9uanMyIFwiZXhwcmVzc1wiPzVlM2EiLCJ3ZWJwYWNrOi8veGhzLW1jcC9leHRlcm5hbCBjb21tb25qczIgXCJjb3JzXCI/OWM3ZCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NlcnZlci9odHRwLnNlcnZlci50cz84Y2Q0Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2VydmVyL2hhbmRsZXJzL2luZGV4LnRzPzFlOTQiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zZXJ2ZXIvaW5kZXgudHM/NWVlNiIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NsaS9jbGkudHM/Y2I5ZCJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBfX1dFQlBBQ0tfTkFNRVNQQUNFX09CSkVDVF9fID0gcmVxdWlyZShcImNvbW1hbmRlclwiKTsiLCIvKipcbiAqIFV0aWxpdHkgZnVuY3Rpb25zIGZvciBYSFMgb3BlcmF0aW9uc1xuICovXG5cbmltcG9ydCB7IFBhZ2UgfSBmcm9tICdwdXBwZXRlZXInO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuXG5leHBvcnQgY29uc3QgWEhTX0hPTUVfVVJMID0gJ2h0dHBzOi8vd3d3LnhpYW9ob25nc2h1LmNvbSc7XG5leHBvcnQgY29uc3QgWEhTX0VYUExPUkVfVVJMID0gYCR7WEhTX0hPTUVfVVJMfS9leHBsb3JlYDtcbmV4cG9ydCBjb25zdCBYSFNfU0VBUkNIX1VSTCA9IGAke1hIU19IT01FX1VSTH0vc2VhcmNoX3Jlc3VsdGA7XG5leHBvcnQgY29uc3QgWEhTX0NSRUFUT1JfUFVCTElTSF9VUkwgPVxuICAnaHR0cHM6Ly9jcmVhdG9yLnhpYW9ob25nc2h1LmNvbS9wdWJsaXNoL3B1Ymxpc2g/c291cmNlPW9mZmljaWFsJztcbmV4cG9ydCBjb25zdCBMT0dJTl9PS19TRUxFQ1RPUiA9ICcubWFpbi1jb250YWluZXIgLnVzZXIgLmxpbmstd3JhcHBlciAuY2hhbm5lbCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlU2VhcmNoVXJsKGtleXdvcmQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoe1xuICAgIGtleXdvcmQsXG4gICAgc291cmNlOiAnd2ViX2V4cGxvcmVfZmVlZCcsXG4gIH0pO1xuICByZXR1cm4gYCR7WEhTX1NFQVJDSF9VUkx9PyR7cGFyYW1zLnRvU3RyaW5nKCl9YDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1ha2VGZWVkRGV0YWlsVXJsKGZlZWRJZDogc3RyaW5nLCB4c2VjVG9rZW46IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoe1xuICAgIHhzZWNfdG9rZW46IHhzZWNUb2tlbixcbiAgICB4c2VjX3NvdXJjZTogJ3BjX2ZlZWQnLFxuICB9KTtcbiAgcmV0dXJuIGAke1hIU19FWFBMT1JFX1VSTH0vJHtmZWVkSWR9PyR7cGFyYW1zLnRvU3RyaW5nKCl9YDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RJbml0aWFsU3RhdGUocGFnZTogUGFnZSk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBudWxsPiB7XG4gIHRyeSB7XG4gICAgLy8gV2FpdCBmb3IgcGFnZSB0byBiZSBmdWxseSBsb2FkZWQgLSBQdXBwZXRlZXIgZG9lc24ndCBoYXZlIHdhaXRGb3JMb2FkU3RhdGVcbiAgICAvLyBXZSdsbCBqdXN0IHdhaXQgYSBiaXQgZm9yIHRoZSBwYWdlIHRvIHNldHRsZVxuICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiBnbG9iYWxUaGlzLnNldFRpbWVvdXQocmVzb2x2ZSwgMTAwMCkpO1xuICB9IGNhdGNoIHtcbiAgICAvLyBJZ25vcmUgbG9hZCBzdGF0ZSBlcnJvcnNcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZShgXG4gICAgICAoKCkgPT4ge1xuICAgICAgICAvLyBUcnkgbXVsdGlwbGUgcG9zc2libGUgc3RhdGUgb2JqZWN0c1xuICAgICAgICBjb25zdCBwb3NzaWJsZVN0YXRlcyA9IFtcbiAgICAgICAgICB3aW5kb3cuX19JTklUSUFMX1NUQVRFX18sXG4gICAgICAgICAgd2luZG93Ll9fSU5JVElBTF9TU1JfU1RBVEVfXyxcbiAgICAgICAgICB3aW5kb3cuX19ORVhUX0RBVEFfXyxcbiAgICAgICAgICB3aW5kb3cuX19OVVhUX18sXG4gICAgICAgICAgd2luZG93Ll9fVlVFX18sXG4gICAgICAgICAgd2luZG93Ll9fUkVBQ1RfUVVFUllfU1RBVEVfX1xuICAgICAgICBdO1xuXG4gICAgICAgIGZvciAoY29uc3Qgc3RhdGUgb2YgcG9zc2libGVTdGF0ZXMpIHtcbiAgICAgICAgICBpZiAoc3RhdGUgJiYgdHlwZW9mIHN0YXRlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgLy8gVXNlIGEgbW9yZSByb2J1c3QgSlNPTiBzZXJpYWxpemF0aW9uIHRoYXQgaGFuZGxlcyBjaXJjdWxhciByZWZlcmVuY2VzXG4gICAgICAgICAgICAgIGNvbnN0IHNlZW4gPSBuZXcgV2Vha1NldCgpO1xuICAgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc3RhdGUsIChrZXksIHZhbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWwgIT0gbnVsbCAmJiB0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICBpZiAoc2Vlbi5oYXModmFsKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJbQ2lyY3VsYXJdXCI7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBzZWVuLmFkZCh2YWwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0pTT04uc3RyaW5naWZ5IGZhaWxlZCBmb3Igc3RhdGU6JywgZS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgbm8gc3RhdGUgZm91bmQsIHRyeSB0byBmaW5kIGFueSBnbG9iYWwgc3RhdGVcbiAgICAgICAgY29uc3QgZ2xvYmFsS2V5cyA9IE9iamVjdC5rZXlzKHdpbmRvdykuZmlsdGVyKGtleSA9PlxuICAgICAgICAgIGtleS5pbmNsdWRlcygnU1RBVEUnKSB8fCBrZXkuaW5jbHVkZXMoJ0RBVEEnKSB8fCBrZXkuaW5jbHVkZXMoJ0lOSVRJQUwnKVxuICAgICAgICApO1xuXG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGdsb2JhbEtleXMpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHdpbmRvd1trZXldO1xuICAgICAgICAgIGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCBzZWVuID0gbmV3IFdlYWtTZXQoKTtcbiAgICAgICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlLCAoa2V5LCB2YWwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodmFsICE9IG51bGwgJiYgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgICAgaWYgKHNlZW4uaGFzKHZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiW0NpcmN1bGFyXVwiO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgc2Vlbi5hZGQodmFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdKU09OLnN0cmluZ2lmeSBmYWlsZWQgZm9yIGdsb2JhbCBrZXk6Jywga2V5LCBlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9KSgpXG4gICAgYCk7XG5cbiAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIEpTT04ucGFyc2UocmVzdWx0IGFzIHN0cmluZyk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpc0xvZ2dlZEluKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoTE9HSU5fT0tfU0VMRUNUT1IpO1xuICAgIHJldHVybiBlbGVtZW50cy5sZW5ndGggPiAwO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldExvZ2luU3RhdHVzV2l0aFByb2ZpbGUocGFnZTogUGFnZSk6IFByb21pc2U8e1xuICBpc0xvZ2dlZEluOiBib29sZWFuO1xuICBwcm9maWxlPzoge1xuICAgIHVzZXJJZD86IHN0cmluZztcbiAgICBuaWNrbmFtZT86IHN0cmluZztcbiAgICB1c2VybmFtZT86IHN0cmluZztcbiAgICBhdmF0YXI/OiBzdHJpbmc7XG4gICAgZm9sbG93ZXJzPzogbnVtYmVyO1xuICAgIGZvbGxvd2luZz86IG51bWJlcjtcbiAgICBsaWtlcz86IG51bWJlcjtcbiAgICB4aHNOdW1iZXI/OiBzdHJpbmc7XG4gICAgaXBMb2NhdGlvbj86IHN0cmluZztcbiAgICBwcm9maWxlVXJsPzogc3RyaW5nO1xuICB9O1xufT4ge1xuICB0cnkge1xuICAgIC8vIEZpcnN0IGNoZWNrIGlmIGxvZ2dlZCBpbiB1c2luZyB0aGUgZXhpc3RpbmcgbWV0aG9kXG4gICAgY29uc3QgZWxlbWVudHMgPSBhd2FpdCBwYWdlLiQkKExPR0lOX09LX1NFTEVDVE9SKTtcbiAgICBjb25zdCBpc0xvZ2dlZEluID0gZWxlbWVudHMubGVuZ3RoID4gMDtcblxuICAgIGlmICghaXNMb2dnZWRJbikge1xuICAgICAgcmV0dXJuIHsgaXNMb2dnZWRJbjogZmFsc2UgfTtcbiAgICB9XG5cbiAgICAvLyBJZiBsb2dnZWQgaW4sIHRyeSB0byBleHRyYWN0IHByb2ZpbGUgaW5mb3JtYXRpb24gZnJvbSBjdXJyZW50IHBhZ2VcbiAgICBsZXQgcHJvZmlsZURhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gICAgdHJ5IHtcbiAgICAgIHByb2ZpbGVEYXRhID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByb2ZpbGU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cbiAgICAgICAgLy8gRXh0cmFjdCB1c2VyIElEIGZyb20gVVJMIGlmIG9uIHByb2ZpbGUgcGFnZVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgY29uc3QgdXJsTWF0Y2ggPSB3aW5kb3cubG9jYXRpb24uaHJlZi5tYXRjaCgvXFwvdXNlclxcL3Byb2ZpbGVcXC8oW2EtZjAtOV0rKS8pO1xuICAgICAgICBpZiAodXJsTWF0Y2gpIHtcbiAgICAgICAgICBwcm9maWxlLnVzZXJJZCA9IHVybE1hdGNoWzFdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVHJ5IHRvIGZpbmQgdXNlciBuaWNrbmFtZVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgY29uc3QgbmFtZUVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgICcudXNlci1uYW1lLCBbY2xhc3MqPVwidXNlci1uYW1lXCJdLCBbY2xhc3MqPVwibmlja25hbWVcIl0nXG4gICAgICAgICk7XG4gICAgICAgIGlmIChuYW1lRWxlbWVudCkge1xuICAgICAgICAgIHByb2ZpbGUubmlja25hbWUgPSBuYW1lRWxlbWVudC50ZXh0Q29udGVudD8udHJpbSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVHJ5IHRvIGZpbmQgdXNlciBpbmZvIHRleHQgdGhhdCBtaWdodCBjb250YWluIHN0YXRzXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgICAgICBjb25zdCBpbmZvRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy51c2VyLWluZm8sIFtjbGFzcyo9XCJ1c2VyLWluZm9cIl0nKTtcbiAgICAgICAgaWYgKGluZm9FbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgaW5mb1RleHQgPSBpbmZvRWxlbWVudC50ZXh0Q29udGVudCB8fCAnJztcbiAgICAgICAgICBwcm9maWxlLmluZm9UZXh0ID0gaW5mb1RleHQ7XG5cbiAgICAgICAgICAvLyBUcnkgdG8gZXh0cmFjdCBudW1iZXJzIGZyb20gdGhlIGluZm8gdGV4dCAoZm9sbG93ZXJzLCBmb2xsb3dpbmcsIGxpa2VzKVxuICAgICAgICAgIGNvbnN0IG51bWJlcnMgPSBpbmZvVGV4dC5tYXRjaCgvXFxkKy9nKTtcbiAgICAgICAgICBpZiAobnVtYmVycyAmJiBudW1iZXJzLmxlbmd0aCA+PSAzKSB7XG4gICAgICAgICAgICAvLyBDb21tb24gcGF0dGVybjogZm9sbG93ZXJzLCBmb2xsb3dpbmcsIGxpa2VzXG4gICAgICAgICAgICBwcm9maWxlLmZvbGxvd2luZyA9IHBhcnNlSW50KG51bWJlcnNbMF0pIHx8IDA7XG4gICAgICAgICAgICBwcm9maWxlLmZvbGxvd2VycyA9IHBhcnNlSW50KG51bWJlcnNbMV0pIHx8IDA7XG4gICAgICAgICAgICBwcm9maWxlLmxpa2VzID0gcGFyc2VJbnQobnVtYmVyc1syXSkgfHwgMDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBFeHRyYWN0IOWwj+e6ouS5puWPtyAoWEhTIG51bWJlcilcbiAgICAgICAgICBjb25zdCB4aHNNYXRjaCA9IGluZm9UZXh0Lm1hdGNoKC/lsI/nuqLkuablj7fvvJooXFxkKykvKTtcbiAgICAgICAgICBpZiAoeGhzTWF0Y2gpIHtcbiAgICAgICAgICAgIHByb2ZpbGUueGhzTnVtYmVyID0geGhzTWF0Y2hbMV07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gRXh0cmFjdCBJUOWxnuWcsCAoSVAgbG9jYXRpb24pXG4gICAgICAgICAgY29uc3QgaXBNYXRjaCA9IGluZm9UZXh0Lm1hdGNoKC9JUOWxnuWcsO+8mihbXjAtOV0rKS8pO1xuICAgICAgICAgIGlmIChpcE1hdGNoKSB7XG4gICAgICAgICAgICBwcm9maWxlLmlwTG9jYXRpb24gPSBpcE1hdGNoWzFdLnRyaW0oKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUcnkgdG8gZmluZCBhdmF0YXJcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICAgIGNvbnN0IGF2YXRhckVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgICdpbWdbY2xhc3MqPVwiYXZhdGFyXCJdLCBpbWdbY2xhc3MqPVwicHJvZmlsZVwiXSwgLmF2YXRhciBpbWcsIC5wcm9maWxlIGltZydcbiAgICAgICAgKSBhcyBIVE1MSW1hZ2VFbGVtZW50O1xuICAgICAgICBpZiAoYXZhdGFyRWxlbWVudCkge1xuICAgICAgICAgIHByb2ZpbGUuYXZhdGFyID0gYXZhdGFyRWxlbWVudC5zcmM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcHJvZmlsZTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBpbiBwYWdlLmV2YWx1YXRlJyk7XG4gICAgICBwcm9maWxlRGF0YSA9IHt9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBpc0xvZ2dlZEluOiB0cnVlLFxuICAgICAgcHJvZmlsZTogT2JqZWN0LmtleXMocHJvZmlsZURhdGEpLmxlbmd0aCA+IDAgPyBwcm9maWxlRGF0YSA6IHVuZGVmaW5lZCxcbiAgICB9O1xuICB9IGNhdGNoIHtcbiAgICAvLyBJZiB0aGVyZSdzIGFuIGVycm9yLCBmYWxsIGJhY2sgdG8gYmFzaWMgbG9naW4gY2hlY2tcbiAgICB0cnkge1xuICAgICAgY29uc3QgZWxlbWVudHMgPSBhd2FpdCBwYWdlLiQkKExPR0lOX09LX1NFTEVDVE9SKTtcbiAgICAgIHJldHVybiB7IGlzTG9nZ2VkSW46IGVsZW1lbnRzLmxlbmd0aCA+IDAgfTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB7IGlzTG9nZ2VkSW46IGZhbHNlIH07XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIEF1dGhlbnRpY2F0aW9uIHNlcnZpY2UgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuaW1wb3J0IHsgQ29uZmlnLCBMb2dpblJlc3VsdCwgU3RhdHVzUmVzdWx0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7XG4gIExvZ2luVGltZW91dEVycm9yLFxuICBMb2dpbkZhaWxlZEVycm9yLFxuICBYSFNFcnJvcixcbn0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBCYXNlU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9iYXNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgQnJvd3Nlck1hbmFnZXIgfSBmcm9tICcuLi9icm93c2VyL2Jyb3dzZXIubWFuYWdlcic7XG5pbXBvcnQgeyBkZWxldGVDb29raWVzRmlsZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9jb29raWVzJztcbmltcG9ydCB7IGlzTG9nZ2VkSW4sIGdldExvZ2luU3RhdHVzV2l0aFByb2ZpbGUgfSBmcm9tICcuLi8uLi9zaGFyZWQveGhzLnV0aWxzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5cbmV4cG9ydCBjbGFzcyBBdXRoU2VydmljZSBleHRlbmRzIEJhc2VTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcsIGJyb3dzZXJNYW5hZ2VyPzogQnJvd3Nlck1hbmFnZXIpIHtcbiAgICBzdXBlcihjb25maWcsIGJyb3dzZXJNYW5hZ2VyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRyYWN0IHByb2ZpbGUgVVJMIGFuZCB1c2VyIElEIGZyb20gdGhlIGN1cnJlbnQgcGFnZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBleHRyYWN0UHJvZmlsZUZyb21QYWdlKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcHJvZmlsZVVybCA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgICBjb25zdCB1c2VyTGlua3MgPSBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2FbaHJlZio9XCIvdXNlci9wcm9maWxlL1wiXScpKTtcbiAgICAgICAgY29uc3QgY3VycmVudFVzZXJMaW5rID0gdXNlckxpbmtzLmZpbmQoKGxpbmspID0+IHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gbGluay50ZXh0Q29udGVudD8udHJpbSgpO1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0ZXh0ID09PSAn5oiRJyB8fFxuICAgICAgICAgICAgKHRleHQgJiYgdGV4dC5pbmNsdWRlcygncHJvZmlsZScpKSB8fFxuICAgICAgICAgICAgKHRleHQgJiYgdGV4dC5pbmNsdWRlcygn55So5oi3JykpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjdXJyZW50VXNlckxpbmsgPyAoY3VycmVudFVzZXJMaW5rIGFzIEhUTUxBbmNob3JFbGVtZW50KS5ocmVmIDogbnVsbDtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAocHJvZmlsZVVybCkge1xuICAgICAgICBjb25zdCB1c2VySWRNYXRjaCA9IHByb2ZpbGVVcmwubWF0Y2goL1xcL3VzZXJcXC9wcm9maWxlXFwvKFthLWYwLTldKykvKTtcbiAgICAgICAgaWYgKHVzZXJJZE1hdGNoKSB7XG4gICAgICAgICAgcmV0dXJuIHsgdXNlcklkOiB1c2VySWRNYXRjaFsxXSwgcHJvZmlsZVVybCB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAocHJvZmlsZUVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIGdldCBwcm9maWxlIGluZm9ybWF0aW9uOicsIHByb2ZpbGVFcnJvcik7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBhc3luYyBsb2dpbihicm93c2VyUGF0aD86IHN0cmluZywgdGltZW91dDogbnVtYmVyID0gMzAwKTogUHJvbWlzZTxMb2dpblJlc3VsdD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UoZmFsc2UsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gTmF2aWdhdGUgdG8gZXhwbG9yZSBwYWdlXG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5uYXZpZ2F0ZVdpdGhSZXRyeShwYWdlLCB0aGlzLmdldENvbmZpZygpLnhocy5leHBsb3JlVXJsKTtcblxuICAgICAgICAvLyBDaGVjayBpZiBhbHJlYWR5IGxvZ2dlZCBpblxuICAgICAgICBpZiAoYXdhaXQgaXNMb2dnZWRJbihwYWdlKSkge1xuICAgICAgICAgIGxldCBwcm9maWxlOiBhbnkgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGV4dHJhY3RlZCA9IGF3YWl0IHRoaXMuZXh0cmFjdFByb2ZpbGVGcm9tUGFnZShwYWdlKTtcbiAgICAgICAgICAgIGNvbnN0IGxvZ2luU3RhdHVzID0gYXdhaXQgZ2V0TG9naW5TdGF0dXNXaXRoUHJvZmlsZShwYWdlKTtcbiAgICAgICAgICAgIHByb2ZpbGUgPSB7IC4uLmV4dHJhY3RlZCwgLi4ubG9naW5TdGF0dXMucHJvZmlsZSB9O1xuICAgICAgICAgIH0gY2F0Y2ggKHByb2ZpbGVFcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBnZXQgcHJvZmlsZSBpbmZvcm1hdGlvbjonLCBwcm9maWxlRXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgbWVzc2FnZTogJ0FscmVhZHkgbG9nZ2VkIGluJyxcbiAgICAgICAgICAgIHN0YXR1czogJ2xvZ2dlZF9pbicsXG4gICAgICAgICAgICBhY3Rpb246ICdub25lJyxcbiAgICAgICAgICAgIHByb2ZpbGUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdhaXQgZm9yIGxvZ2luIGNvbXBsZXRpb25cbiAgICAgICAgY29uc3QgY2hlY2tJbnRlcnZhbCA9IDU7XG4gICAgICAgIGNvbnN0IG1heENoZWNrcyA9IHRpbWVvdXQgLyBjaGVja0ludGVydmFsO1xuXG4gICAgICAgIGZvciAobGV0IGNoZWNrQ291bnQgPSAwOyBjaGVja0NvdW50IDwgbWF4Q2hlY2tzOyBjaGVja0NvdW50KyspIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgcGFnZS53YWl0Rm9yU2VsZWN0b3IodGhpcy5nZXRDb25maWcoKS54aHMubG9naW5Pa1NlbGVjdG9yLCB7XG4gICAgICAgICAgICAgIHRpbWVvdXQ6IGNoZWNrSW50ZXJ2YWwgKiAxMDAwLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc3QgZWxhcHNlZCA9IChjaGVja0NvdW50ICsgMSkgKiBjaGVja0ludGVydmFsO1xuXG4gICAgICAgICAgICBpZiAoY2hlY2tDb3VudCA9PT0gbWF4Q2hlY2tzIC0gMSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgTG9naW5UaW1lb3V0RXJyb3IoXG4gICAgICAgICAgICAgICAgYExvZ2luIHRpbWVkIG91dCBhZnRlciAke3RpbWVvdXR9IHNlY29uZHMuIFBsZWFzZSBjb21wbGV0ZSBRUiBjb2RlIHNjYW5uaW5nIG9yIG1hbnVhbCBsb2dpbiBpbiB0aGUgYnJvd3NlciB3aW5kb3cuYCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICB0aW1lb3V0LFxuICAgICAgICAgICAgICAgICAgdXJsOiB0aGlzLmdldENvbmZpZygpLnhocy5leHBsb3JlVXJsLFxuICAgICAgICAgICAgICAgICAgZWxhcHNlZFRpbWU6IGVsYXBzZWQsXG4gICAgICAgICAgICAgICAgICBzdWdnZXN0aW9uOiAnSW5jcmVhc2UgdGltZW91dCBwYXJhbWV0ZXIgb3IgY29tcGxldGUgbG9naW4gZmFzdGVyJyxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2F2ZSBjb29raWVzIGFmdGVyIHN1Y2Nlc3NmdWwgbG9naW5cbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLnNhdmVDb29raWVzRnJvbVBhZ2UocGFnZSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGxvZ2luIHN1Y2Nlc3MgYW5kIGdldCBwcm9maWxlIGluZm9ybWF0aW9uXG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuICAgICAgICBjb25zdCBsb2dpblN0YXR1cyA9IGF3YWl0IGdldExvZ2luU3RhdHVzV2l0aFByb2ZpbGUocGFnZSk7XG4gICAgICAgIGlmIChsb2dpblN0YXR1cy5pc0xvZ2dlZEluKSB7XG4gICAgICAgICAgbGV0IHByb2ZpbGUgPSBsb2dpblN0YXR1cy5wcm9maWxlO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBleHRyYWN0ZWQgPSBhd2FpdCB0aGlzLmV4dHJhY3RQcm9maWxlRnJvbVBhZ2UocGFnZSk7XG4gICAgICAgICAgICBpZiAoZXh0cmFjdGVkKSB7XG4gICAgICAgICAgICAgIHByb2ZpbGUgPSB7IC4uLnByb2ZpbGUsIC4uLmV4dHJhY3RlZCB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKHByb2ZpbGVFcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBnZXQgYWRkaXRpb25hbCBwcm9maWxlIGluZm9ybWF0aW9uOicsIHByb2ZpbGVFcnJvcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICBtZXNzYWdlOiAnTG9naW4gc3VjY2Vzc2Z1bCcsXG4gICAgICAgICAgICBzdGF0dXM6ICdsb2dnZWRfaW4nLFxuICAgICAgICAgICAgYWN0aW9uOiAnbG9nZ2VkX2luJyxcbiAgICAgICAgICAgIHByb2ZpbGUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTG9naW5GYWlsZWRFcnJvcihcbiAgICAgICAgICAgICdMb2dpbiBwcm9jZXNzIGNvbXBsZXRlZCBidXQgYXV0aGVudGljYXRpb24gdmVyaWZpY2F0aW9uIGZhaWxlZCdcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIExvZ2luVGltZW91dEVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgTG9naW5GYWlsZWRFcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5lcnJvcihgTG9naW4gZmFpbGVkIHdpdGggdW5leHBlY3RlZCBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IG5ldyBYSFNFcnJvcihgTG9naW4gZmFpbGVkOiAke2Vycm9yfWAsICdMb2dpbkVycm9yJywgeyB0aW1lb3V0IH0sIGVycm9yIGFzIEVycm9yKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBsb2dvdXQoKTogUHJvbWlzZTxMb2dpblJlc3VsdD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzdWNjZXNzID0gZGVsZXRlQ29va2llc0ZpbGUoKTtcblxuICAgICAgaWYgKHN1Y2Nlc3MpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIG1lc3NhZ2U6ICdMb2dnZWQgb3V0IHN1Y2Nlc3NmdWxseSAoY29va2llcyBkZWxldGVkKScsXG4gICAgICAgICAgc3RhdHVzOiAnbG9nZ2VkX291dCcsXG4gICAgICAgICAgYWN0aW9uOiAnbG9nZ2VkX291dCcsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIG1lc3NhZ2U6ICdGYWlsZWQgdG8gZGVsZXRlIGNvb2tpZXMgZmlsZScsXG4gICAgICAgICAgc3RhdHVzOiAnbG9nZ2VkX291dCcsXG4gICAgICAgICAgYWN0aW9uOiAnbm9uZScsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgTG9nb3V0IGZhaWxlZDogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiBgTG9nb3V0IGZhaWxlZDogJHtlcnJvcn1gLFxuICAgICAgICBzdGF0dXM6ICdsb2dnZWRfb3V0JyxcbiAgICAgICAgYWN0aW9uOiAnbm9uZScsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNoZWNrU3RhdHVzKGJyb3dzZXJQYXRoPzogc3RyaW5nKTogUHJvbWlzZTxTdGF0dXNSZXN1bHQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKHRydWUsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIHRoaXMuZ2V0Q29uZmlnKCkueGhzLmV4cGxvcmVVcmwpO1xuICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcblxuICAgICAgICBjb25zdCBsb2dnZWRJbiA9IGF3YWl0IGlzTG9nZ2VkSW4ocGFnZSk7XG5cbiAgICAgICAgaWYgKCFsb2dnZWRJbikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgbG9nZ2VkSW46IGZhbHNlLFxuICAgICAgICAgICAgc3RhdHVzOiAnbG9nZ2VkX291dCcsXG4gICAgICAgICAgICB1cmxDaGVja2VkOiB0aGlzLmdldENvbmZpZygpLnhocy5leHBsb3JlVXJsLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcm9maWxlID0gYXdhaXQgdGhpcy5leHRyYWN0UHJvZmlsZUZyb21QYWdlKHBhZ2UpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBsb2dnZWRJbjogdHJ1ZSxcbiAgICAgICAgICBzdGF0dXM6ICdsb2dnZWRfaW4nLFxuICAgICAgICAgIHVybENoZWNrZWQ6IHRoaXMuZ2V0Q29uZmlnKCkueGhzLmV4cGxvcmVVcmwsXG4gICAgICAgICAgcHJvZmlsZSxcbiAgICAgICAgfTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBTdGF0dXMgY2hlY2sgZmFpbGVkOiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKGBTdGF0dXMgY2hlY2sgZmFpbGVkOiAke2Vycm9yfWAsICdTdGF0dXNDaGVja0Vycm9yJywge30sIGVycm9yIGFzIEVycm9yKTtcbiAgICB9XG4gIH1cbn1cbiIsImNvbnN0IF9fV0VCUEFDS19OQU1FU1BBQ0VfT0JKRUNUX18gPSByZXF1aXJlKFwibm9kZTpjaGlsZF9wcm9jZXNzXCIpOyIsIi8qKlxuICogRmVlZCBvcGVyYXRpb25zIHNlcnZpY2UgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuaW1wb3J0IHtcbiAgQ29uZmlnLFxuICBGZWVkTGlzdFJlc3VsdCxcbiAgU2VhcmNoUmVzdWx0LFxuICBGZWVkRGV0YWlsUmVzdWx0LFxuICBDb21tZW50UmVzdWx0LFxuICBGZWVkSXRlbSxcbn0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7XG4gIEZlZWRFcnJvcixcbiAgRmVlZFBhcnNpbmdFcnJvcixcbiAgRmVlZE5vdEZvdW5kRXJyb3IsXG4gIE5vdExvZ2dlZEluRXJyb3IsXG4gIFhIU0Vycm9yLFxufSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IEJhc2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Jhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBCcm93c2VyTWFuYWdlciB9IGZyb20gJy4uL2Jyb3dzZXIvYnJvd3Nlci5tYW5hZ2VyJztcbmltcG9ydCB7XG4gIG1ha2VTZWFyY2hVcmwsXG4gIG1ha2VGZWVkRGV0YWlsVXJsLFxuICBleHRyYWN0SW5pdGlhbFN0YXRlLFxuICBpc0xvZ2dlZEluLFxufSBmcm9tICcuLi8uLi9zaGFyZWQveGhzLnV0aWxzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgRmVlZFNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnLCBicm93c2VyTWFuYWdlcj86IEJyb3dzZXJNYW5hZ2VyKSB7XG4gICAgc3VwZXIoY29uZmlnLCBicm93c2VyTWFuYWdlcik7XG4gIH1cblxuICBhc3luYyBnZXRGZWVkTGlzdChicm93c2VyUGF0aD86IHN0cmluZyk6IFByb21pc2U8RmVlZExpc3RSZXN1bHQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKHRydWUsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIHRoaXMuZ2V0Q29uZmlnKCkueGhzLmhvbWVVcmwpO1xuICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcblxuICAgICAgICAvLyBDaGVjayBpZiBsb2dnZWQgaW5cbiAgICAgICAgaWYgKCEoYXdhaXQgaXNMb2dnZWRJbihwYWdlKSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm90TG9nZ2VkSW5FcnJvcignTXVzdCBiZSBsb2dnZWQgaW4gdG8gYWNjZXNzIGZlZWQgbGlzdCcsIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbjogJ2dldF9mZWVkX2xpc3QnLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRXh0cmFjdCBmZWVkIGRhdGEgdXNpbmcgYSBtb3JlIHRhcmdldGVkIGFwcHJvYWNoXG4gICAgICAgIGxldCBmZWVkRGF0YTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG4gICAgICAgIGNvbnN0IG1heEF0dGVtcHRzID0gMTA7XG5cbiAgICAgICAgd2hpbGUgKGF0dGVtcHRzIDwgbWF4QXR0ZW1wdHMgJiYgIWZlZWREYXRhKSB7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7IC8vIFdhaXQgMiBzZWNvbmRzIGJldHdlZW4gYXR0ZW1wdHNcbiAgICAgICAgICBhdHRlbXB0cysrO1xuXG4gICAgICAgICAgZmVlZERhdGEgPSAoYXdhaXQgcGFnZS5ldmFsdWF0ZShgXG4gICAgICAgICAgICAoKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAod2luZG93Ll9fSU5JVElBTF9TVEFURV9fICYmIHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5mZWVkICYmIHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5mZWVkLmZlZWRzICYmIHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5mZWVkLmZlZWRzLl92YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAvLyBUcnkgdG8gc2VyaWFsaXplIGp1c3QgdGhlIGZlZWRzIGRhdGEgdG8gYXZvaWQgY2lyY3VsYXIgcmVmZXJlbmNlIGlzc3Vlc1xuICAgICAgICAgICAgICAgICAgY29uc3QgZmVlZHNEYXRhID0gd2luZG93Ll9fSU5JVElBTF9TVEFURV9fLmZlZWQuZmVlZHMuX3ZhbHVlO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGZlZWRzRGF0YSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBzZXJpYWxpemUgZmVlZHMgZGF0YTonLCBlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfSkoKVxuICAgICAgICAgIGApKSBhcyBzdHJpbmcgfCBudWxsO1xuXG4gICAgICAgICAgaWYgKGZlZWREYXRhKSB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhgRmVlZCByZXN1bHRzIGxvYWRlZCBhZnRlciAke2F0dGVtcHRzfSBhdHRlbXB0c2ApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFmZWVkRGF0YSkge1xuICAgICAgICAgIHRocm93IG5ldyBGZWVkUGFyc2luZ0Vycm9yKFxuICAgICAgICAgICAgYENvdWxkIG5vdCBleHRyYWN0IGZlZWQgZGF0YSBhZnRlciAke21heEF0dGVtcHRzfSBhdHRlbXB0cy4gVGhlIHBhZ2UgbWF5IG5vdCBiZSBmdWxseSBsb2FkZWQgb3IgdGhlIHN0YXRlIHN0cnVjdHVyZSBoYXMgY2hhbmdlZC5gLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB1cmw6IHRoaXMuZ2V0Q29uZmlnKCkueGhzLmhvbWVVcmwsXG4gICAgICAgICAgICAgIHN1Z2dlc3Rpb246ICdUcnkgbG9nZ2luZyBpbiBmaXJzdCB1c2luZyB4aHNfYXV0aF9sb2dpbiB0b29sJyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmVlZHNWYWx1ZSA9IEpTT04ucGFyc2UoZmVlZERhdGEpIGFzIHVua25vd25bXTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgZmVlZHM6IGZlZWRzVmFsdWUgYXMgRmVlZEl0ZW1bXSxcbiAgICAgICAgICBjb3VudDogZmVlZHNWYWx1ZS5sZW5ndGgsXG4gICAgICAgICAgc291cmNlOiAnaG9tZV9wYWdlJyxcbiAgICAgICAgICB1cmw6IHRoaXMuZ2V0Q29uZmlnKCkueGhzLmhvbWVVcmwsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vdExvZ2dlZEluRXJyb3IgfHwgZXJyb3IgaW5zdGFuY2VvZiBGZWVkUGFyc2luZ0Vycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IGZlZWQgbGlzdDogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IG5ldyBYSFNFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBnZXQgZmVlZCBsaXN0OiAke2Vycm9yfWAsXG4gICAgICAgICdHZXRGZWVkTGlzdEVycm9yJyxcbiAgICAgICAge30sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNlYXJjaEZlZWRzKGtleXdvcmQ6IHN0cmluZywgYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPFNlYXJjaFJlc3VsdD4ge1xuICAgIGlmICgha2V5d29yZCB8fCAha2V5d29yZC50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBGZWVkRXJyb3IoJ1NlYXJjaCBrZXl3b3JkIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cblxuICAgIGNvbnN0IHRyaW1tZWRLZXl3b3JkID0ga2V5d29yZC50cmltKCk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKHRydWUsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc2VhcmNoVXJsID0gbWFrZVNlYXJjaFVybCh0cmltbWVkS2V5d29yZCk7XG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5uYXZpZ2F0ZVdpdGhSZXRyeShwYWdlLCBzZWFyY2hVcmwpO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIHNlYXJjaCByZXN1bHRzIHRvIGxvYWQgd2l0aCBtdWx0aXBsZSBhdHRlbXB0c1xuICAgICAgICBsZXQgc2VhcmNoRGF0YTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG4gICAgICAgIGNvbnN0IG1heEF0dGVtcHRzID0gMTA7XG5cbiAgICAgICAgd2hpbGUgKGF0dGVtcHRzIDwgbWF4QXR0ZW1wdHMgJiYgIXNlYXJjaERhdGEpIHtcbiAgICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTsgLy8gV2FpdCAyIHNlY29uZHMgYmV0d2VlbiBhdHRlbXB0c1xuICAgICAgICAgIGF0dGVtcHRzKys7XG5cbiAgICAgICAgICBzZWFyY2hEYXRhID0gKGF3YWl0IHBhZ2UuZXZhbHVhdGUoYFxuICAgICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXyAmJiB3aW5kb3cuX19JTklUSUFMX1NUQVRFX18uc2VhcmNoICYmIHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5zZWFyY2guZmVlZHMgJiYgd2luZG93Ll9fSU5JVElBTF9TVEFURV9fLnNlYXJjaC5mZWVkcy5fdmFsdWUpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgLy8gVHJ5IHRvIHNlcmlhbGl6ZSBqdXN0IHRoZSBmZWVkcyBkYXRhIHRvIGF2b2lkIGNpcmN1bGFyIHJlZmVyZW5jZSBpc3N1ZXNcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZlZWRzRGF0YSA9IHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5zZWFyY2guZmVlZHMuX3ZhbHVlO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGZlZWRzRGF0YSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBzZXJpYWxpemUgZmVlZHMgZGF0YTonLCBlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfSkoKVxuICAgICAgICAgIGApKSBhcyBzdHJpbmcgfCBudWxsO1xuXG4gICAgICAgICAgaWYgKHNlYXJjaERhdGEpIHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBTZWFyY2ggcmVzdWx0cyBsb2FkZWQgYWZ0ZXIgJHthdHRlbXB0c30gYXR0ZW1wdHNgKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghc2VhcmNoRGF0YSkge1xuICAgICAgICAgIHRocm93IG5ldyBGZWVkUGFyc2luZ0Vycm9yKFxuICAgICAgICAgICAgYENvdWxkIG5vdCBleHRyYWN0IHNlYXJjaCByZXN1bHRzIGZvciBrZXl3b3JkOiAke3RyaW1tZWRLZXl3b3JkfSBhZnRlciAke21heEF0dGVtcHRzfSBhdHRlbXB0c2AsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGtleXdvcmQ6IHRyaW1tZWRLZXl3b3JkLFxuICAgICAgICAgICAgICB1cmw6IHNlYXJjaFVybCxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmVlZHNWYWx1ZSA9IEpTT04ucGFyc2Uoc2VhcmNoRGF0YSkgYXMgdW5rbm93bltdO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBrZXl3b3JkOiB0cmltbWVkS2V5d29yZCxcbiAgICAgICAgICBmZWVkczogZmVlZHNWYWx1ZSBhcyBGZWVkSXRlbVtdLFxuICAgICAgICAgIGNvdW50OiBmZWVkc1ZhbHVlLmxlbmd0aCxcbiAgICAgICAgICBzZWFyY2hVcmwsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEZlZWRFcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5lcnJvcihgRmVlZCBzZWFyY2ggZmFpbGVkIGZvciBrZXl3b3JkICcke3RyaW1tZWRLZXl3b3JkfSc6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgWEhTRXJyb3IoXG4gICAgICAgIGBGZWVkIHNlYXJjaCBmYWlsZWQ6ICR7ZXJyb3J9YCxcbiAgICAgICAgJ1NlYXJjaEZlZWRzRXJyb3InLFxuICAgICAgICB7IGtleXdvcmQ6IHRyaW1tZWRLZXl3b3JkIH0sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldEZlZWREZXRhaWwoXG4gICAgZmVlZElkOiBzdHJpbmcsXG4gICAgeHNlY1Rva2VuOiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxGZWVkRGV0YWlsUmVzdWx0PiB7XG4gICAgaWYgKCFmZWVkSWQgfHwgIXhzZWNUb2tlbikge1xuICAgICAgdGhyb3cgbmV3IEZlZWRFcnJvcignQm90aCBmZWVkX2lkIGFuZCB4c2VjX3Rva2VuIGFyZSByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UodHJ1ZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkZXRhaWxVcmwgPSBtYWtlRmVlZERldGFpbFVybChmZWVkSWQsIHhzZWNUb2tlbik7XG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5uYXZpZ2F0ZVdpdGhSZXRyeShwYWdlLCBkZXRhaWxVcmwpO1xuICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcblxuICAgICAgICBjb25zdCBzdGF0ZSA9IGF3YWl0IGV4dHJhY3RJbml0aWFsU3RhdGUocGFnZSk7XG5cbiAgICAgICAgY29uc3Qgbm90ZURhdGEgPSBzdGF0ZT8ubm90ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgaWYgKCFzdGF0ZSB8fCAhbm90ZURhdGEgfHwgIW5vdGVEYXRhLm5vdGVEZXRhaWxNYXApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRmVlZFBhcnNpbmdFcnJvcihgQ291bGQgbm90IGV4dHJhY3Qgbm90ZSBkZXRhaWxzIGZvciBmZWVkOiAke2ZlZWRJZH1gLCB7XG4gICAgICAgICAgICBmZWVkSWQsXG4gICAgICAgICAgICB1cmw6IGRldGFpbFVybCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5vdGVEZXRhaWxNYXAgPSBub3RlRGF0YS5ub3RlRGV0YWlsTWFwIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICBpZiAoIShmZWVkSWQgaW4gbm90ZURldGFpbE1hcCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRmVlZE5vdEZvdW5kRXJyb3IoYEZlZWQgJHtmZWVkSWR9IG5vdCBmb3VuZCBpbiBub3RlIGRldGFpbHNgLCB7XG4gICAgICAgICAgICBmZWVkSWQsXG4gICAgICAgICAgICBhdmFpbGFibGVGZWVkczogT2JqZWN0LmtleXMobm90ZURldGFpbE1hcCksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZXRhaWwgPSBub3RlRGV0YWlsTWFwW2ZlZWRJZF0gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIGZlZWRJZCxcbiAgICAgICAgICBkZXRhaWwsXG4gICAgICAgICAgdXJsOiBkZXRhaWxVcmwsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBGZWVkRXJyb3IgfHxcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBGZWVkTm90Rm91bmRFcnJvciB8fFxuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEZlZWRQYXJzaW5nRXJyb3JcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGdldCBmZWVkIGRldGFpbCBmb3IgJHtmZWVkSWR9OiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGdldCBmZWVkIGRldGFpbDogJHtlcnJvcn1gLFxuICAgICAgICAnR2V0RmVlZERldGFpbEVycm9yJyxcbiAgICAgICAgeyBmZWVkSWQgfSxcbiAgICAgICAgZXJyb3IgYXMgRXJyb3JcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY29tbWVudE9uRmVlZChcbiAgICBmZWVkSWQ6IHN0cmluZyxcbiAgICB4c2VjVG9rZW46IHN0cmluZyxcbiAgICBub3RlOiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxDb21tZW50UmVzdWx0PiB7XG4gICAgaWYgKCFmZWVkSWQgfHwgIXhzZWNUb2tlbiB8fCAhbm90ZSkge1xuICAgICAgdGhyb3cgbmV3IEZlZWRFcnJvcignZmVlZF9pZCwgeHNlY190b2tlbiwgYW5kIG5vdGUgYXJlIGFsbCByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGlmIChub3RlLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBGZWVkRXJyb3IoJ0NvbW1lbnQgbm90ZSBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKGZhbHNlLCBicm93c2VyUGF0aCwgdHJ1ZSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGRldGFpbFVybCA9IG1ha2VGZWVkRGV0YWlsVXJsKGZlZWRJZCwgeHNlY1Rva2VuKTtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIGRldGFpbFVybCk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAgIC8vIENoZWNrIGlmIGxvZ2dlZCBpblxuICAgICAgICBpZiAoIShhd2FpdCBpc0xvZ2dlZEluKHBhZ2UpKSkge1xuICAgICAgICAgIHRocm93IG5ldyBOb3RMb2dnZWRJbkVycm9yKCdNdXN0IGJlIGxvZ2dlZCBpbiB0byBjb21tZW50IG9uIGZlZWRzJywge1xuICAgICAgICAgICAgb3BlcmF0aW9uOiAnY29tbWVudF9vbl9mZWVkJyxcbiAgICAgICAgICAgIGZlZWRJZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENsaWNrIG9uIGNvbW1lbnQgaW5wdXRcbiAgICAgICAgY29uc3QgY29tbWVudElucHV0U2VsZWN0b3IgPSAnZGl2LmlucHV0LWJveCBkaXYuY29udGVudC1lZGl0IHNwYW4nO1xuICAgICAgICBpZiAoIShhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkudHJ5V2FpdEZvclNlbGVjdG9yKHBhZ2UsIGNvbW1lbnRJbnB1dFNlbGVjdG9yKSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRmVlZEVycm9yKCdDb21tZW50IGlucHV0IG5vdCBmb3VuZCBvbiBwYWdlJywge1xuICAgICAgICAgICAgZmVlZElkLFxuICAgICAgICAgICAgc2VsZWN0b3I6IGNvbW1lbnRJbnB1dFNlbGVjdG9yLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29tbWVudElucHV0ID0gYXdhaXQgcGFnZS4kKGNvbW1lbnRJbnB1dFNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGNvbW1lbnRJbnB1dCkge1xuICAgICAgICAgIGF3YWl0IGNvbW1lbnRJbnB1dC5jbGljaygpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmlsbCBjb21tZW50IG5vdGVcbiAgICAgICAgY29uc3QgZWRpdG9yU2VsZWN0b3IgPSAnZGl2LmlucHV0LWJveCBkaXYuY29udGVudC1lZGl0IHAuY29udGVudC1pbnB1dCc7XG4gICAgICAgIGNvbnN0IGVkaXRvciA9IGF3YWl0IHBhZ2UuJChlZGl0b3JTZWxlY3Rvcik7XG5cbiAgICAgICAgaWYgKGVkaXRvcikge1xuICAgICAgICAgIGF3YWl0IGVkaXRvci5jbGljaygpO1xuICAgICAgICAgIGF3YWl0IGVkaXRvci50eXBlKG5vdGUsIHsgZGVsYXk6IDMwIH0pO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAgIC8vIFN1Ym1pdCBjb21tZW50XG4gICAgICAgIGNvbnN0IHN1Ym1pdFNlbGVjdG9yID0gJ2Rpdi5ib3R0b20gYnV0dG9uLnN1Ym1pdCc7XG4gICAgICAgIGNvbnN0IHN1Ym1pdEJ1dHRvbiA9IGF3YWl0IHBhZ2UuJChzdWJtaXRTZWxlY3Rvcik7XG4gICAgICAgIGlmIChzdWJtaXRCdXR0b24pIHtcbiAgICAgICAgICBhd2FpdCBzdWJtaXRCdXR0b24uY2xpY2soKTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTsgLy8gV2FpdCBmb3Igc3VibWlzc2lvblxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBtZXNzYWdlOiAnQ29tbWVudCBzdWJtaXR0ZWQgc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICBmZWVkSWQsXG4gICAgICAgICAgbm90ZSxcbiAgICAgICAgICB1cmw6IGRldGFpbFVybCxcbiAgICAgICAgfTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRmVlZEVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgTm90TG9nZ2VkSW5FcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGNvbW1lbnQgb24gZmVlZCAke2ZlZWRJZH06ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgWEhTRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gY29tbWVudCBvbiBmZWVkOiAke2Vycm9yfWAsXG4gICAgICAgICdDb21tZW50T25GZWVkRXJyb3InLFxuICAgICAgICB7IGZlZWRJZCB9LFxuICAgICAgICBlcnJvciBhcyBFcnJvclxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICogVGl0bGUgdmFsaWRhdGlvbiB1dGlsaXR5IGZvciBYSFMgTUNQIFNlcnZlclxuICogVmFsaWRhdGVzIHRpdGxlIHdpZHRoIGFjY29yZGluZyB0byBYaWFvSG9uZ1NodSdzIGRpc3BsYXkgd2lkdGggcnVsZXNcbiAqXG4gKiBYSFMgUnVsZXM6XG4gKiAtIE1heCB3aWR0aDogNDAgdW5pdHNcbiAqIC0gQ0pLIGNoYXJhY3RlcnMgKENoaW5lc2UvSmFwYW5lc2UvS29yZWFuKTogMiB1bml0cyBlYWNoXG4gKiAtIE90aGVyIGNoYXJhY3RlcnMgKEVuZ2xpc2gvTnVtYmVycyk6IDEgdW5pdCBlYWNoXG4gKi9cblxuaW1wb3J0IHN0cmluZ1dpZHRoIGZyb20gJ3N0cmluZy13aWR0aCc7XG5pbXBvcnQgeyBQdWJsaXNoRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGl0bGVWYWxpZGF0aW9uUmVzdWx0IHtcbiAgdmFsaWQ6IGJvb2xlYW47XG4gIHdpZHRoOiBudW1iZXI7XG4gIG1heFdpZHRoOiBudW1iZXI7XG4gIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIHN1Z2dlc3Rpb24/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogWGlhb0hvbmdTaHUgdGl0bGUgY29uc3RyYWludHNcbiAqL1xuZXhwb3J0IGNvbnN0IFhIU19USVRMRV9DT05TVFJBSU5UUyA9IHtcbiAgTUFYX1dJRFRIOiA0MCwgLy8gTWF4aW11bSBkaXNwbGF5IHdpZHRoIGluIHVuaXRzXG4gIE1BWF9MRU5HVEg6IDIwLCAvLyBBcHByb3hpbWF0ZSBtYXggY2hhcmFjdGVyIGNvdW50IChmb3IgcmVmZXJlbmNlKVxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBWYWxpZGF0ZSB0aXRsZSB3aWR0aCBhY2NvcmRpbmcgdG8gWEhTIGRpc3BsYXkgcnVsZXNcbiAqXG4gKiBAcGFyYW0gdGl0bGUgLSBUaGUgdGl0bGUgdG8gdmFsaWRhdGVcbiAqIEByZXR1cm5zIFZhbGlkYXRpb24gcmVzdWx0IHdpdGggd2lkdGggaW5mb3JtYXRpb25cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVzdWx0ID0gdmFsaWRhdGVUaXRsZVdpZHRoKCdIZWxsb+S4lueVjCcpO1xuICogY29uc29sZS5sb2cocmVzdWx0LndpZHRoKTsgLy8gMTAgKDUgKyAyKjIgKyAxID0gMTApXG4gKiBjb25zb2xlLmxvZyhyZXN1bHQudmFsaWQpOyAvLyB0cnVlXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlVGl0bGVXaWR0aCh0aXRsZTogc3RyaW5nKTogVGl0bGVWYWxpZGF0aW9uUmVzdWx0IHtcbiAgaWYgKCF0aXRsZSkge1xuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogZmFsc2UsXG4gICAgICB3aWR0aDogMCxcbiAgICAgIG1heFdpZHRoOiBYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRILFxuICAgICAgbWVzc2FnZTogJ1RpdGxlIGNhbm5vdCBiZSBlbXB0eScsXG4gICAgICBzdWdnZXN0aW9uOiAnUGxlYXNlIHByb3ZpZGUgYSB2YWxpZCB0aXRsZScsXG4gICAgfTtcbiAgfVxuXG4gIC8vIENhbGN1bGF0ZSBkaXNwbGF5IHdpZHRoIHVzaW5nIHN0cmluZy13aWR0aFxuICAvLyBUaGlzIGNvcnJlY3RseSBoYW5kbGVzIENKSyBjaGFyYWN0ZXJzLCBlbW9qaSwgYW5kIG90aGVyIFVuaWNvZGVcbiAgY29uc3Qgd2lkdGggPSBzdHJpbmdXaWR0aCh0aXRsZSk7XG5cbiAgaWYgKHdpZHRoID4gWEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSCkge1xuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogZmFsc2UsXG4gICAgICB3aWR0aCxcbiAgICAgIG1heFdpZHRoOiBYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRILFxuICAgICAgbWVzc2FnZTogYFRpdGxlIHdpZHRoIGV4Y2VlZHMgbGltaXQ6ICR7d2lkdGh9IHVuaXRzIChtYXg6ICR7WEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSH0gdW5pdHMpYCxcbiAgICAgIHN1Z2dlc3Rpb246IGBDdXJyZW50IHRpdGxlIGlzIHRvbyBsb25nLiBDSksgY2hhcmFjdGVycyBjb3VudCBhcyAyIHVuaXRzLCBFbmdsaXNoL251bWJlcnMgYXMgMSB1bml0LiBQbGVhc2Ugc2hvcnRlbiB5b3VyIHRpdGxlLmAsXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdmFsaWQ6IHRydWUsXG4gICAgd2lkdGgsXG4gICAgbWF4V2lkdGg6IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEgsXG4gIH07XG59XG5cbi8qKlxuICogVmFsaWRhdGUgYW5kIHRocm93IGVycm9yIGlmIHRpdGxlIHdpZHRoIGlzIGludmFsaWRcbiAqXG4gKiBAcGFyYW0gdGl0bGUgLSBUaGUgdGl0bGUgdG8gdmFsaWRhdGVcbiAqIEB0aHJvd3MgUHVibGlzaEVycm9yIGlmIHRpdGxlIHdpZHRoIGlzIGludmFsaWRcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogdHJ5IHtcbiAqICAgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkKCflvojplb/lvojplb/nmoTmoIfpopgnLnJlcGVhdCgxMCkpO1xuICogfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgY29uc29sZS5lcnJvcihlcnJvci5tZXNzYWdlKTtcbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0VGl0bGVXaWR0aFZhbGlkKHRpdGxlOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgcmVzdWx0ID0gdmFsaWRhdGVUaXRsZVdpZHRoKHRpdGxlKTtcblxuICBpZiAoIXJlc3VsdC52YWxpZCkge1xuICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IocmVzdWx0Lm1lc3NhZ2UhLCB7XG4gICAgICB0aXRsZSxcbiAgICAgIHdpZHRoOiByZXN1bHQud2lkdGgsXG4gICAgICBtYXhXaWR0aDogcmVzdWx0Lm1heFdpZHRoLFxuICAgICAgc3VnZ2VzdGlvbjogcmVzdWx0LnN1Z2dlc3Rpb24sXG4gICAgICBkZXRhaWxzOiB7XG4gICAgICAgIHRpdGxlTGVuZ3RoOiB0aXRsZS5sZW5ndGgsXG4gICAgICAgIGRpc3BsYXlXaWR0aDogcmVzdWx0LndpZHRoLFxuICAgICAgICBtYXhEaXNwbGF5V2lkdGg6IHJlc3VsdC5tYXhXaWR0aCxcbiAgICAgICAgZXhjZWVkZWQ6IHJlc3VsdC53aWR0aCAtIHJlc3VsdC5tYXhXaWR0aCxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgdGhlIGRpc3BsYXkgd2lkdGggb2YgYSB0aXRsZVxuICpcbiAqIEBwYXJhbSB0aXRsZSAtIFRoZSB0aXRsZSB0byBtZWFzdXJlXG4gKiBAcmV0dXJucyBEaXNwbGF5IHdpZHRoIGluIHVuaXRzXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnNvbGUubG9nKGdldFRpdGxlV2lkdGgoJ0hlbGxvJykpOyAgICAgICAgLy8gNVxuICogY29uc29sZS5sb2coZ2V0VGl0bGVXaWR0aCgn5L2g5aW9JykpOyAgICAgICAgIC8vIDQgKDIqMilcbiAqIGNvbnNvbGUubG9nKGdldFRpdGxlV2lkdGgoJ0hlbGxv5LiW55WMJykpOyAgICAvLyAxMCAoNSArIDIqMiArIDEpXG4gKiBjb25zb2xlLmxvZyhnZXRUaXRsZVdpZHRoKCfwn5GLSGVsbG8nKSk7ICAgICAgLy8gNyAoMiArIDUpXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRpdGxlV2lkdGgodGl0bGU6IHN0cmluZyk6IG51bWJlciB7XG4gIHJldHVybiBzdHJpbmdXaWR0aCh0aXRsZSk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIGhvdyBtYW55IGNoYXJhY3RlcnMgY2FuIGJlIGFkZGVkIHRvIHRoZSB0aXRsZVxuICpcbiAqIEBwYXJhbSB0aXRsZSAtIEN1cnJlbnQgdGl0bGVcbiAqIEByZXR1cm5zIFJlbWFpbmluZyB3aWR0aCB1bml0cyBhdmFpbGFibGVcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVtYWluaW5nID0gZ2V0UmVtYWluaW5nVGl0bGVXaWR0aCgnSGVsbG8nKTsgLy8gMzVcbiAqIGNvbnNvbGUubG9nKGBZb3UgY2FuIGFkZCAke3JlbWFpbmluZ30gbW9yZSB1bml0c2ApO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVSZW1haW5pbmdUaXRsZVdpZHRoKHRpdGxlOiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCBjdXJyZW50V2lkdGggPSBnZXRUaXRsZVdpZHRoKHRpdGxlKTtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEggLSBjdXJyZW50V2lkdGgpO1xufVxuXG4vKipcbiAqIFRydW5jYXRlIHRpdGxlIHRvIGZpdCB3aXRoaW4gd2lkdGggbGltaXRcbiAqXG4gKiBAcGFyYW0gdGl0bGUgLSBUaGUgdGl0bGUgdG8gdHJ1bmNhdGVcbiAqIEBwYXJhbSBtYXhXaWR0aCAtIE1heGltdW0gd2lkdGggKGRlZmF1bHQ6IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEgpXG4gKiBAcmV0dXJucyBUcnVuY2F0ZWQgdGl0bGUgdGhhdCBmaXRzIHdpdGhpbiB3aWR0aCBsaW1pdFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBsb25nID0gJ+i/meaYr+S4gOS4quW+iOmVv+W+iOmVv+eahOagh+mimCcucmVwZWF0KDUpO1xuICogY29uc3QgdHJ1bmNhdGVkID0gdHJ1bmNhdGVUaXRsZVRvV2lkdGgobG9uZyk7XG4gKiBjb25zb2xlLmxvZyhnZXRUaXRsZVdpZHRoKHRydW5jYXRlZCkpOyAvLyA8PSA0MFxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cnVuY2F0ZVRpdGxlVG9XaWR0aChcbiAgdGl0bGU6IHN0cmluZyxcbiAgbWF4V2lkdGg6IG51bWJlciA9IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEhcbik6IHN0cmluZyB7XG4gIGlmIChnZXRUaXRsZVdpZHRoKHRpdGxlKSA8PSBtYXhXaWR0aCkge1xuICAgIHJldHVybiB0aXRsZTtcbiAgfVxuXG4gIGxldCB0cnVuY2F0ZWQgPSAnJztcbiAgbGV0IGN1cnJlbnRXaWR0aCA9IDA7XG5cbiAgZm9yIChjb25zdCBjaGFyIG9mIHRpdGxlKSB7XG4gICAgY29uc3QgY2hhcldpZHRoID0gc3RyaW5nV2lkdGgoY2hhcik7XG5cbiAgICBpZiAoY3VycmVudFdpZHRoICsgY2hhcldpZHRoID4gbWF4V2lkdGgpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHRydW5jYXRlZCArPSBjaGFyO1xuICAgIGN1cnJlbnRXaWR0aCArPSBjaGFyV2lkdGg7XG4gIH1cblxuICByZXR1cm4gdHJ1bmNhdGVkO1xufVxuXG4vKipcbiAqIEdldCBodW1hbi1yZWFkYWJsZSB3aWR0aCBicmVha2Rvd25cbiAqIFVzZWZ1bCBmb3IgZGVidWdnaW5nIGFuZCB1c2VyIGZlZWRiYWNrXG4gKlxuICogQHBhcmFtIHRpdGxlIC0gVGhlIHRpdGxlIHRvIGFuYWx5emVcbiAqIEByZXR1cm5zIFdpZHRoIGJyZWFrZG93biBpbmZvcm1hdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGl0bGVXaWR0aEJyZWFrZG93bih0aXRsZTogc3RyaW5nKToge1xuICB0aXRsZTogc3RyaW5nO1xuICB0b3RhbFdpZHRoOiBudW1iZXI7XG4gIHRvdGFsQ2hhcnM6IG51bWJlcjtcbiAgbWF4V2lkdGg6IG51bWJlcjtcbiAgcmVtYWluaW5nOiBudW1iZXI7XG4gIHZhbGlkOiBib29sZWFuO1xuICBicmVha2Rvd246IEFycmF5PHtcbiAgICBjaGFyOiBzdHJpbmc7XG4gICAgd2lkdGg6IG51bWJlcjtcbiAgICB0eXBlOiAnQ0pLJyB8ICdBU0NJSScgfCAnRW1vamknIHwgJ090aGVyJztcbiAgfT47XG59IHtcbiAgY29uc3QgdG90YWxXaWR0aCA9IGdldFRpdGxlV2lkdGgodGl0bGUpO1xuICBjb25zdCBicmVha2Rvd246IEFycmF5PHtcbiAgICBjaGFyOiBzdHJpbmc7XG4gICAgd2lkdGg6IG51bWJlcjtcbiAgICB0eXBlOiAnQ0pLJyB8ICdBU0NJSScgfCAnRW1vamknIHwgJ090aGVyJztcbiAgfT4gPSBbXTtcblxuICBmb3IgKGNvbnN0IGNoYXIgb2YgdGl0bGUpIHtcbiAgICBjb25zdCBjaGFyV2lkdGggPSBzdHJpbmdXaWR0aChjaGFyKTtcbiAgICBsZXQgdHlwZTogJ0NKSycgfCAnQVNDSUknIHwgJ0Vtb2ppJyB8ICdPdGhlcicgPSAnT3RoZXInO1xuXG4gICAgY29uc3QgY29kZSA9IGNoYXIuY2hhckNvZGVBdCgwKTtcbiAgICBpZiAoY2hhci5tYXRjaCgvW1xcdTRlMDAtXFx1OWZmZlxcdTM0MDAtXFx1NGRiZlxcdWY5MDAtXFx1ZmFmZl0vKSkge1xuICAgICAgdHlwZSA9ICdDSksnO1xuICAgIH0gZWxzZSBpZiAoY29kZSA8IDEyOCkge1xuICAgICAgdHlwZSA9ICdBU0NJSSc7XG4gICAgfSBlbHNlIGlmIChjaGFyLm1hdGNoKC9bXFx1ezFGMzAwfS1cXHV7MUY5RkZ9XS91KSkge1xuICAgICAgdHlwZSA9ICdFbW9qaSc7XG4gICAgfVxuXG4gICAgYnJlYWtkb3duLnB1c2goeyBjaGFyLCB3aWR0aDogY2hhcldpZHRoLCB0eXBlIH0pO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0aXRsZSxcbiAgICB0b3RhbFdpZHRoLFxuICAgIHRvdGFsQ2hhcnM6IHRpdGxlLmxlbmd0aCxcbiAgICBtYXhXaWR0aDogWEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSCxcbiAgICByZW1haW5pbmc6IGNhbGN1bGF0ZVJlbWFpbmluZ1RpdGxlV2lkdGgodGl0bGUpLFxuICAgIHZhbGlkOiB0b3RhbFdpZHRoIDw9IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEgsXG4gICAgYnJlYWtkb3duLFxuICB9O1xufVxuIiwiY29uc3QgX19XRUJQQUNLX05BTUVTUEFDRV9PQkpFQ1RfXyA9IHJlcXVpcmUoXCJjcnlwdG9cIik7IiwiY29uc3QgX19XRUJQQUNLX05BTUVTUEFDRV9PQkpFQ1RfXyA9IHJlcXVpcmUoXCJub2RlLWZldGNoXCIpOyIsIi8qKlxuICogSW1hZ2UgZG93bmxvYWRlciB1dGlsaXR5IGZvciBYSFMgTUNQIFNlcnZlclxuICogU3VwcG9ydHMgZG93bmxvYWRpbmcgaW1hZ2VzIGZyb20gSFRUUC9IVFRQUyBVUkxzXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBleGlzdHNTeW5jLCBta2RpclN5bmMsIHdyaXRlRmlsZVN5bmMsIHN0YXRTeW5jIH0gZnJvbSAnZnMnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IGZldGNoIGZyb20gJ25vZGUtZmV0Y2gnO1xuaW1wb3J0IHsgSW52YWxpZEltYWdlRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRG93bmxvYWRSZXN1bHQge1xuICBvcmlnaW5hbFVybDogc3RyaW5nO1xuICBsb2NhbFBhdGg6IHN0cmluZztcbiAgY2FjaGVkOiBib29sZWFuO1xuICBmaWxlU2l6ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgSW1hZ2VEb3dubG9hZGVyIHtcbiAgcHJpdmF0ZSBzYXZlRGlyOiBzdHJpbmc7XG4gIHByaXZhdGUgdGltZW91dDogbnVtYmVyO1xuICBwcml2YXRlIG1heEZpbGVTaXplOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2F2ZURpcjogc3RyaW5nID0gJy4vdGVtcF9pbWFnZXMnLFxuICAgIHRpbWVvdXQ6IG51bWJlciA9IDMwMDAwLFxuICAgIG1heEZpbGVTaXplOiBudW1iZXIgPSAxMCAqIDEwMjQgKiAxMDI0IC8vIDEwTUIgZGVmYXVsdFxuICApIHtcbiAgICB0aGlzLnNhdmVEaXIgPSBzYXZlRGlyO1xuICAgIHRoaXMudGltZW91dCA9IHRpbWVvdXQ7XG4gICAgdGhpcy5tYXhGaWxlU2l6ZSA9IG1heEZpbGVTaXplO1xuXG4gICAgLy8gRW5zdXJlIHNhdmUgZGlyZWN0b3J5IGV4aXN0c1xuICAgIGlmICghZXhpc3RzU3luYyh0aGlzLnNhdmVEaXIpKSB7XG4gICAgICBta2RpclN5bmModGhpcy5zYXZlRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBIVFRQL0hUVFBTIFVSTFxuICAgKi9cbiAgc3RhdGljIGlzSW1hZ2VVcmwocGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCFwYXRoKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgbG93ZXJQYXRoID0gcGF0aC50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcbiAgICByZXR1cm4gbG93ZXJQYXRoLnN0YXJ0c1dpdGgoJ2h0dHA6Ly8nKSB8fCBsb3dlclBhdGguc3RhcnRzV2l0aCgnaHR0cHM6Ly8nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBhIHVuaXF1ZSBmaWxlbmFtZSBmb3IgYW4gaW1hZ2UgVVJMXG4gICAqIFVzZXMgb25seSBVUkwgaGFzaCBmb3IgY29uc2lzdGVudCBjYWNoaW5nXG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlRmlsZU5hbWUoaW1hZ2VVcmw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgLy8gVXNlIFNIQTI1NiBoYXNoIG9mIFVSTCBmb3IgdW5pcXVlbmVzc1xuICAgIGNvbnN0IGhhc2ggPSBjcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUoaW1hZ2VVcmwpLmRpZ2VzdCgnaGV4Jyk7XG4gICAgY29uc3Qgc2hvcnRIYXNoID0gaGFzaC5zdWJzdHJpbmcoMCwgMTYpO1xuXG4gICAgLy8gVHJ5IHRvIGV4dHJhY3QgZXh0ZW5zaW9uIGZyb20gVVJMXG4gICAgbGV0IGV4dGVuc2lvbiA9ICdqcGcnOyAvLyBkZWZhdWx0XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHVybCA9IG5ldyBVUkwoaW1hZ2VVcmwpO1xuICAgICAgY29uc3QgcGF0aG5hbWUgPSB1cmwucGF0aG5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICAgIGNvbnN0IG1hdGNoID0gcGF0aG5hbWUubWF0Y2goL1xcLihqcGd8anBlZ3xwbmd8Z2lmfHdlYnB8Ym1wKSQvaSk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgZXh0ZW5zaW9uID0gbWF0Y2hbMV07XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBVc2UgZGVmYXVsdCBleHRlbnNpb25cbiAgICB9XG5cbiAgICAvLyBGaXhlZCBmaWxlbmFtZSBmb3IgcHJvcGVyIGNhY2hpbmcgKG5vIHRpbWVzdGFtcClcbiAgICByZXR1cm4gYGltZ18ke3Nob3J0SGFzaH0uJHtleHRlbnNpb259YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGF0IGRvd25sb2FkZWQgZGF0YSBpcyBhY3R1YWxseSBhbiBpbWFnZVxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUltYWdlRGF0YShidWZmZXI6IEJ1ZmZlcik6IHsgaXNWYWxpZDogYm9vbGVhbjsgZXh0ZW5zaW9uOiBzdHJpbmcgfSB7XG4gICAgLy8gQ2hlY2sgZmlsZSBzaWduYXR1cmVzIChtYWdpYyBudW1iZXJzKVxuICAgIGlmIChidWZmZXIubGVuZ3RoIDwgMTIpIHtcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCBleHRlbnNpb246ICcnIH07XG4gICAgfVxuXG4gICAgLy8gSlBFR1xuICAgIGlmIChidWZmZXJbMF0gPT09IDB4ZmYgJiYgYnVmZmVyWzFdID09PSAweGQ4ICYmIGJ1ZmZlclsyXSA9PT0gMHhmZikge1xuICAgICAgcmV0dXJuIHsgaXNWYWxpZDogdHJ1ZSwgZXh0ZW5zaW9uOiAnanBnJyB9O1xuICAgIH1cblxuICAgIC8vIFBOR1xuICAgIGlmIChidWZmZXJbMF0gPT09IDB4ODkgJiYgYnVmZmVyWzFdID09PSAweDUwICYmIGJ1ZmZlclsyXSA9PT0gMHg0ZSAmJiBidWZmZXJbM10gPT09IDB4NDcpIHtcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IHRydWUsIGV4dGVuc2lvbjogJ3BuZycgfTtcbiAgICB9XG5cbiAgICAvLyBHSUZcbiAgICBpZiAoYnVmZmVyWzBdID09PSAweDQ3ICYmIGJ1ZmZlclsxXSA9PT0gMHg0OSAmJiBidWZmZXJbMl0gPT09IDB4NDYpIHtcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IHRydWUsIGV4dGVuc2lvbjogJ2dpZicgfTtcbiAgICB9XG5cbiAgICAvLyBXZWJQXG4gICAgaWYgKFxuICAgICAgYnVmZmVyWzBdID09PSAweDUyICYmXG4gICAgICBidWZmZXJbMV0gPT09IDB4NDkgJiZcbiAgICAgIGJ1ZmZlclsyXSA9PT0gMHg0NiAmJlxuICAgICAgYnVmZmVyWzNdID09PSAweDQ2ICYmXG4gICAgICBidWZmZXJbOF0gPT09IDB4NTcgJiZcbiAgICAgIGJ1ZmZlcls5XSA9PT0gMHg0NSAmJlxuICAgICAgYnVmZmVyWzEwXSA9PT0gMHg0MiAmJlxuICAgICAgYnVmZmVyWzExXSA9PT0gMHg1MFxuICAgICkge1xuICAgICAgcmV0dXJuIHsgaXNWYWxpZDogdHJ1ZSwgZXh0ZW5zaW9uOiAnd2VicCcgfTtcbiAgICB9XG5cbiAgICAvLyBCTVBcbiAgICBpZiAoYnVmZmVyWzBdID09PSAweDQyICYmIGJ1ZmZlclsxXSA9PT0gMHg0ZCkge1xuICAgICAgcmV0dXJuIHsgaXNWYWxpZDogdHJ1ZSwgZXh0ZW5zaW9uOiAnYm1wJyB9O1xuICAgIH1cblxuICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCBleHRlbnNpb246ICcnIH07XG4gIH1cblxuICAvKipcbiAgICogRG93bmxvYWQgYSBzaW5nbGUgaW1hZ2UgZnJvbSBVUkxcbiAgICovXG4gIGFzeW5jIGRvd25sb2FkSW1hZ2UoaW1hZ2VVcmw6IHN0cmluZyk6IFByb21pc2U8RG93bmxvYWRSZXN1bHQ+IHtcbiAgICAvLyBWYWxpZGF0ZSBVUkwgZm9ybWF0XG4gICAgaWYgKCFJbWFnZURvd25sb2FkZXIuaXNJbWFnZVVybChpbWFnZVVybCkpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihgSW52YWxpZCBpbWFnZSBVUkwgZm9ybWF0OiAke2ltYWdlVXJsfWAsIHtcbiAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgc3VnZ2VzdGlvbjogJ1VSTCBtdXN0IHN0YXJ0IHdpdGggaHR0cDovLyBvciBodHRwczovLycsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZSBmaWxlbmFtZSBhbmQgcGF0aFxuICAgIGNvbnN0IGZpbGVOYW1lID0gdGhpcy5nZW5lcmF0ZUZpbGVOYW1lKGltYWdlVXJsKTtcbiAgICBjb25zdCBsb2NhbFBhdGggPSBqb2luKHRoaXMuc2F2ZURpciwgZmlsZU5hbWUpO1xuXG4gICAgLy8gQ2hlY2sgaWYgZmlsZSBhbHJlYWR5IGV4aXN0cyAoY2FjaGUpXG4gICAgaWYgKGV4aXN0c1N5bmMobG9jYWxQYXRoKSkge1xuICAgICAgY29uc3Qgc3RhdHMgPSBzdGF0U3luYyhsb2NhbFBhdGgpO1xuICAgICAgbG9nZ2VyLmRlYnVnKGBVc2luZyBjYWNoZWQgaW1hZ2U6ICR7bG9jYWxQYXRofWApO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3JpZ2luYWxVcmw6IGltYWdlVXJsLFxuICAgICAgICBsb2NhbFBhdGgsXG4gICAgICAgIGNhY2hlZDogdHJ1ZSxcbiAgICAgICAgZmlsZVNpemU6IHN0YXRzLnNpemUsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGxvZ2dlci5kZWJ1ZyhgRG93bmxvYWRpbmcgaW1hZ2UgZnJvbTogJHtpbWFnZVVybH1gKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBEb3dubG9hZCBpbWFnZSB3aXRoIHRpbWVvdXRcbiAgICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICBjb25zdCB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KCgpID0+IGNvbnRyb2xsZXIuYWJvcnQoKSwgdGhpcy50aW1lb3V0KTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChpbWFnZVVybCwge1xuICAgICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ1VzZXItQWdlbnQnOiAnTW96aWxsYS81LjAgKE1hY2ludG9zaDsgSW50ZWwgTWFjIE9TIFggMTBfMTVfNykgQXBwbGVXZWJLaXQvNTM3LjM2JyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcblxuICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgICAgYEZhaWxlZCB0byBkb3dubG9hZCBpbWFnZTogSFRUUCAke3Jlc3BvbnNlLnN0YXR1c30gJHtyZXNwb25zZS5zdGF0dXNUZXh0fWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgICAgIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBDb250ZW50LUxlbmd0aCBpZiBhdmFpbGFibGVcbiAgICAgIGNvbnN0IGNvbnRlbnRMZW5ndGggPSByZXNwb25zZS5oZWFkZXJzLmdldCgnY29udGVudC1sZW5ndGgnKTtcbiAgICAgIGlmIChjb250ZW50TGVuZ3RoICYmIHBhcnNlSW50KGNvbnRlbnRMZW5ndGgpID4gdGhpcy5tYXhGaWxlU2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgICAgYEltYWdlIGZpbGUgdG9vIGxhcmdlOiAkeyhwYXJzZUludChjb250ZW50TGVuZ3RoKSAvIDEwMjQgLyAxMDI0KS50b0ZpeGVkKFxuICAgICAgICAgICAgMlxuICAgICAgICAgICl9TUIgKG1heDogJHsodGhpcy5tYXhGaWxlU2l6ZSAvIDEwMjQgLyAxMDI0KS50b0ZpeGVkKDIpfU1CKWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgICAgIGZpbGVTaXplOiBwYXJzZUludChjb250ZW50TGVuZ3RoKSxcbiAgICAgICAgICAgIG1heFNpemU6IHRoaXMubWF4RmlsZVNpemUsXG4gICAgICAgICAgICBzdWdnZXN0aW9uOiAnVHJ5IHVzaW5nIGEgc21hbGxlciBpbWFnZSBvciBpbmNyZWFzZSBtYXhGaWxlU2l6ZScsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBHZXQgaW1hZ2UgZGF0YVxuICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSBhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpO1xuICAgICAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmZyb20oYXJyYXlCdWZmZXIpO1xuXG4gICAgICAvLyBWZXJpZnkgYWN0dWFsIHNpemVcbiAgICAgIGlmIChidWZmZXIubGVuZ3RoID4gdGhpcy5tYXhGaWxlU2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgICAgYERvd25sb2FkZWQgZmlsZSB0b28gbGFyZ2U6ICR7KGJ1ZmZlci5sZW5ndGggLyAxMDI0IC8gMTAyNCkudG9GaXhlZCgyKX1NQiAobWF4OiAkeyhcbiAgICAgICAgICAgIHRoaXMubWF4RmlsZVNpemUgL1xuICAgICAgICAgICAgMTAyNCAvXG4gICAgICAgICAgICAxMDI0XG4gICAgICAgICAgKS50b0ZpeGVkKDIpfU1CKWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgICAgIGZpbGVTaXplOiBidWZmZXIubGVuZ3RoLFxuICAgICAgICAgICAgbWF4U2l6ZTogdGhpcy5tYXhGaWxlU2l6ZSxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIFZhbGlkYXRlIGl0J3MgYWN0dWFsbHkgYW4gaW1hZ2VcbiAgICAgIGNvbnN0IHZhbGlkYXRpb24gPSB0aGlzLnZhbGlkYXRlSW1hZ2VEYXRhKGJ1ZmZlcik7XG4gICAgICBpZiAoIXZhbGlkYXRpb24uaXNWYWxpZCkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoYERvd25sb2FkZWQgZmlsZSBpcyBub3QgYSB2YWxpZCBpbWFnZTogJHtpbWFnZVVybH1gLCB7XG4gICAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgICBzdWdnZXN0aW9uOiAnTWFrZSBzdXJlIHRoZSBVUkwgcG9pbnRzIHRvIGFuIGFjdHVhbCBpbWFnZSBmaWxlJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNhdmUgdG8gZmlsZVxuICAgICAgd3JpdGVGaWxlU3luYyhsb2NhbFBhdGgsIGJ1ZmZlcik7XG5cbiAgICAgIGxvZ2dlci5kZWJ1ZyhgSW1hZ2UgZG93bmxvYWRlZCBzdWNjZXNzZnVsbHk6ICR7bG9jYWxQYXRofSAoJHtidWZmZXIubGVuZ3RofSBieXRlcylgKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3JpZ2luYWxVcmw6IGltYWdlVXJsLFxuICAgICAgICBsb2NhbFBhdGgsXG4gICAgICAgIGNhY2hlZDogZmFsc2UsXG4gICAgICAgIGZpbGVTaXplOiBidWZmZXIubGVuZ3RoLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgSW52YWxpZEltYWdlRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG5cbiAgICAgIC8vIEhhbmRsZSBhYm9ydCBlcnJvclxuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubmFtZSA9PT0gJ0Fib3J0RXJyb3InKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihcbiAgICAgICAgICBgSW1hZ2UgZG93bmxvYWQgdGltZW91dCBhZnRlciAke3RoaXMudGltZW91dH1tczogJHtpbWFnZVVybH1gLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVybDogaW1hZ2VVcmwsXG4gICAgICAgICAgICB0aW1lb3V0OiB0aGlzLnRpbWVvdXQsXG4gICAgICAgICAgICBzdWdnZXN0aW9uOiAnVGhlIGltYWdlIG1heSBiZSB0b28gbGFyZ2Ugb3IgdGhlIG5ldHdvcmsgaXMgc2xvdycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gZG93bmxvYWQgaW1hZ2U6ICR7aW1hZ2VVcmx9YCxcbiAgICAgICAge1xuICAgICAgICAgIHVybDogaW1hZ2VVcmwsXG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEb3dubG9hZCBtdWx0aXBsZSBpbWFnZXMgZnJvbSBVUkxzIChwYXJhbGxlbCBkb3dubG9hZCBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlKVxuICAgKi9cbiAgYXN5bmMgZG93bmxvYWRJbWFnZXMoaW1hZ2VVcmxzOiBzdHJpbmdbXSk6IFByb21pc2U8RG93bmxvYWRSZXN1bHRbXT4ge1xuICAgIC8vIERvd25sb2FkIGFsbCBpbWFnZXMgaW4gcGFyYWxsZWxcbiAgICBjb25zdCBkb3dubG9hZFByb21pc2VzID0gaW1hZ2VVcmxzLm1hcCgodXJsKSA9PlxuICAgICAgdGhpcy5kb3dubG9hZEltYWdlKHVybCkuY2F0Y2goKGVycm9yKSA9PiAoeyBlcnJvciwgdXJsIH0pKVxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoZG93bmxvYWRQcm9taXNlcyk7XG5cbiAgICBjb25zdCBzdWNjZXNzUmVzdWx0czogRG93bmxvYWRSZXN1bHRbXSA9IFtdO1xuICAgIGNvbnN0IGVycm9yczogQXJyYXk8eyB1cmw6IHN0cmluZzsgZXJyb3I6IEVycm9yIH0+ID0gW107XG5cbiAgICByZXN1bHRzLmZvckVhY2goKHJlc3VsdCkgPT4ge1xuICAgICAgaWYgKCdlcnJvcicgaW4gcmVzdWx0KSB7XG4gICAgICAgIGVycm9ycy5wdXNoKHsgdXJsOiByZXN1bHQudXJsLCBlcnJvcjogcmVzdWx0LmVycm9yIGFzIEVycm9yIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3VjY2Vzc1Jlc3VsdHMucHVzaChyZXN1bHQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gSWYgYW55IGRvd25sb2FkcyBmYWlsZWQsIHRocm93IGFuIGVycm9yIHdpdGggZGV0YWlsc1xuICAgIGlmIChlcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgZXJyb3JNZXNzYWdlcyA9IGVycm9ycy5tYXAoKGUpID0+IGAke2UudXJsfTogJHtlLmVycm9yLm1lc3NhZ2V9YCkuam9pbignXFxuJyk7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gZG93bmxvYWQgJHtlcnJvcnMubGVuZ3RofSBvZiAke2ltYWdlVXJscy5sZW5ndGh9IGltYWdlczpcXG4ke2Vycm9yTWVzc2FnZXN9YCxcbiAgICAgICAge1xuICAgICAgICAgIHRvdGFsQ291bnQ6IGltYWdlVXJscy5sZW5ndGgsXG4gICAgICAgICAgZmFpbGVkQ291bnQ6IGVycm9ycy5sZW5ndGgsXG4gICAgICAgICAgc3VjY2Vzc0NvdW50OiBzdWNjZXNzUmVzdWx0cy5sZW5ndGgsXG4gICAgICAgICAgZmFpbGVkVXJsczogZXJyb3JzLm1hcCgoZSkgPT4gZS51cmwpLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBzdWNjZXNzUmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzIGEgbGlzdCBvZiBpbWFnZSBwYXRocyAtIGRvd25sb2FkIFVSTHMgYW5kIGtlZXAgbG9jYWwgcGF0aHMgYXMtaXNcbiAgICovXG4gIGFzeW5jIHByb2Nlc3NJbWFnZVBhdGhzKGltYWdlUGF0aHM6IHN0cmluZ1tdKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IGxvY2FsUGF0aHM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgdXJsc1RvRG93bmxvYWQ6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyBTZXBhcmF0ZSBVUkxzIGZyb20gbG9jYWwgcGF0aHNcbiAgICBmb3IgKGNvbnN0IHBhdGggb2YgaW1hZ2VQYXRocykge1xuICAgICAgaWYgKEltYWdlRG93bmxvYWRlci5pc0ltYWdlVXJsKHBhdGgpKSB7XG4gICAgICAgIHVybHNUb0Rvd25sb2FkLnB1c2gocGF0aCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBWYWxpZGF0ZSBsb2NhbCBwYXRoIGV4aXN0c1xuICAgICAgICBpZiAoIWV4aXN0c1N5bmMocGF0aCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoYExvY2FsIGltYWdlIGZpbGUgbm90IGZvdW5kOiAke3BhdGh9YCwge1xuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHN1Z2dlc3Rpb246ICdNYWtlIHN1cmUgdGhlIGZpbGUgcGF0aCBpcyBjb3JyZWN0IGFuZCB0aGUgZmlsZSBleGlzdHMnLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGxvY2FsUGF0aHMucHVzaChwYXRoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBEb3dubG9hZCBVUkxzIGlmIGFueVxuICAgIGlmICh1cmxzVG9Eb3dubG9hZC5sZW5ndGggPiAwKSB7XG4gICAgICBsb2dnZXIuZGVidWcoYERvd25sb2FkaW5nICR7dXJsc1RvRG93bmxvYWQubGVuZ3RofSBpbWFnZXMgZnJvbSBVUkxzLi4uYCk7XG4gICAgICBjb25zdCBkb3dubG9hZFJlc3VsdHMgPSBhd2FpdCB0aGlzLmRvd25sb2FkSW1hZ2VzKHVybHNUb0Rvd25sb2FkKTtcbiAgICAgIGNvbnN0IGRvd25sb2FkZWRQYXRocyA9IGRvd25sb2FkUmVzdWx0cy5tYXAoKHIpID0+IHIubG9jYWxQYXRoKTtcbiAgICAgIGxvY2FsUGF0aHMucHVzaCguLi5kb3dubG9hZGVkUGF0aHMpO1xuXG4gICAgICAvLyBMb2cgZG93bmxvYWQgc3VtbWFyeVxuICAgICAgY29uc3QgY2FjaGVkQ291bnQgPSBkb3dubG9hZFJlc3VsdHMuZmlsdGVyKChyKSA9PiByLmNhY2hlZCkubGVuZ3RoO1xuICAgICAgY29uc3QgbmV3Q291bnQgPSBkb3dubG9hZFJlc3VsdHMuZmlsdGVyKChyKSA9PiAhci5jYWNoZWQpLmxlbmd0aDtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgRG93bmxvYWRlZCAke25ld0NvdW50fSBuZXcgaW1hZ2VzLCB1c2VkICR7Y2FjaGVkQ291bnR9IGNhY2hlZCBpbWFnZXNgKTtcbiAgICB9XG5cbiAgICBpZiAobG9jYWxQYXRocy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcignTm8gdmFsaWQgaW1hZ2VzIGZvdW5kJywge1xuICAgICAgICBwcm92aWRlZFBhdGhzOiBpbWFnZVBhdGhzLmxlbmd0aCxcbiAgICAgICAgc3VnZ2VzdGlvbjogJ1Byb3ZpZGUgYXQgbGVhc3Qgb25lIHZhbGlkIGltYWdlIFVSTCBvciBsb2NhbCBmaWxlIHBhdGgnLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxvY2FsUGF0aHM7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBzYXZlIGRpcmVjdG9yeSBwYXRoXG4gICAqL1xuICBnZXRTYXZlRGlyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2F2ZURpcjtcbiAgfVxufVxuXG4vLyBFeHBvcnQgYSBkZWZhdWx0IGluc3RhbmNlXG5sZXQgZGVmYXVsdERvd25sb2FkZXI6IEltYWdlRG93bmxvYWRlciB8IG51bGwgPSBudWxsO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW1hZ2VEb3dubG9hZGVyKHNhdmVEaXI/OiBzdHJpbmcpOiBJbWFnZURvd25sb2FkZXIge1xuICBpZiAoIWRlZmF1bHREb3dubG9hZGVyIHx8IChzYXZlRGlyICYmIGRlZmF1bHREb3dubG9hZGVyLmdldFNhdmVEaXIoKSAhPT0gc2F2ZURpcikpIHtcbiAgICBkZWZhdWx0RG93bmxvYWRlciA9IG5ldyBJbWFnZURvd25sb2FkZXIoc2F2ZURpcik7XG4gIH1cbiAgcmV0dXJuIGRlZmF1bHREb3dubG9hZGVyO1xufVxuIiwiLyoqXG4gKiBQdWJsaXNoaW5nIHNlcnZpY2UgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgUHVibGlzaEVycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBCYXNlU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9iYXNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgQnJvd3Nlck1hbmFnZXIgfSBmcm9tICcuLi9icm93c2VyL2Jyb3dzZXIubWFuYWdlcic7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvbG9nZ2VyJztcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7IEltYWdlRG93bmxvYWRlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9pbWFnZS1kb3dubG9hZGVyJztcbmltcG9ydCB7IENPTU1PTl9TVEFUVVNfU0VMRUNUT1JTLCBDT01NT05fVEVYVF9QQVRURVJOUywgQ09NTU9OX0ZJTEVfU0VMRUNUT1JTIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3NlbGVjdG9ycyc7XG5cbi8vIENvbnN0YW50cyBmb3IgdmlkZW8gcHVibGlzaGluZ1xuZXhwb3J0IGNvbnN0IFZJREVPX1RJTUVPVVRTID0ge1xuICBQQUdFX0xPQUQ6IDMwMDAsXG4gIFRBQl9TV0lUQ0g6IDIwMDAsXG4gIFZJREVPX1BST0NFU1NJTkc6IDEwMDAwLFxuICBDT05URU5UX1dBSVQ6IDEwMDAsXG4gIFVQTE9BRF9SRUFEWTogMTAwMCxcbiAgVVBMT0FEX1NUQVJUOiAzMDAwLFxuICBQUk9DRVNTSU5HX0NIRUNLOiAzMDAwLFxuICBDT01QTEVUSU9OX0NIRUNLOiAyMDAwLFxuICBQUk9DRVNTSU5HX1RJTUVPVVQ6IDEyMDAwMCwgLy8gMiBtaW51dGVzXG4gIENPTVBMRVRJT05fVElNRU9VVDogMzAwMDAwLCAvLyA1IG1pbnV0ZXNcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBTRUxFQ1RPUlMgPSB7XG4gIEZJTEVfSU5QVVQ6IENPTU1PTl9GSUxFX1NFTEVDVE9SUy5GSUxFX0lOUFVULFxuICBTVUNDRVNTX0lORElDQVRPUlM6IENPTU1PTl9TVEFUVVNfU0VMRUNUT1JTLlNVQ0NFU1MsXG4gIEVSUk9SX0lORElDQVRPUlM6IENPTU1PTl9TVEFUVVNfU0VMRUNUT1JTLkVSUk9SLFxuICBQUk9DRVNTSU5HX0lORElDQVRPUlM6IENPTU1PTl9TVEFUVVNfU0VMRUNUT1JTLlBST0NFU1NJTkcsXG4gIENPTVBMRVRJT05fSU5ESUNBVE9SUzogW1xuICAgICcudXBsb2FkLWNvbXBsZXRlJyxcbiAgICAnLnByb2Nlc3NpbmctY29tcGxldGUnLFxuICAgICcudmlkZW8tcmVhZHknLFxuICAgICdbY2xhc3MqPVwiY29tcGxldGVcIl0nLFxuICAgICdbY2xhc3MqPVwicmVhZHlcIl0nLFxuICBdLFxuICBUT0FTVF9TRUxFQ1RPUlM6IENPTU1PTl9TVEFUVVNfU0VMRUNUT1JTLlRPQVNULFxuICBQVUJMSVNIX1BBR0VfSU5ESUNBVE9SUzogW1xuICAgICdkaXYudXBsb2FkLWNvbnRlbnQnLFxuICAgICdkaXYuc3VibWl0JyxcbiAgICAnLmNyZWF0b3ItZWRpdG9yJyxcbiAgICAnLnZpZGVvLXVwbG9hZC1jb250YWluZXInLFxuICAgICdpbnB1dFt0eXBlPVwiZmlsZVwiXScsXG4gIF0sXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgVEVYVF9QQVRURVJOUyA9IENPTU1PTl9URVhUX1BBVFRFUk5TO1xuXG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBQdWJsaXNoQmFzZVNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gIHByb3RlY3RlZCBpbWFnZURvd25sb2FkZXI6IEltYWdlRG93bmxvYWRlcjtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IENvbmZpZywgYnJvd3Nlck1hbmFnZXI/OiBCcm93c2VyTWFuYWdlcikge1xuICAgIHN1cGVyKGNvbmZpZywgYnJvd3Nlck1hbmFnZXIpO1xuICAgIHRoaXMuaW1hZ2VEb3dubG9hZGVyID0gbmV3IEltYWdlRG93bmxvYWRlcignLi90ZW1wX2ltYWdlcycpO1xuICB9XG5cbiAgLy8gSGVscGVyIG1ldGhvZHMgZm9yIGVsZW1lbnQgZGV0ZWN0aW9uIGFuZCB0ZXh0IG1hdGNoaW5nXG4gIHByb3RlY3RlZCBhc3luYyBmaW5kRWxlbWVudEJ5U2VsZWN0b3JzKFxuICAgIHBhZ2U6IFBhZ2UsXG4gICAgc2VsZWN0b3JzOiByZWFkb25seSBzdHJpbmdbXVxuICApOiBQcm9taXNlPGFueSB8IG51bGw+IHtcbiAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGVsZW1lbnQgd2l0aCBzZWxlY3RvcjogJHtzZWxlY3Rvcn1gKTtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldEVsZW1lbnRUZXh0KGVsZW1lbnQ6IEVsZW1lbnQpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IChlbGVtZW50IGFzIGFueSkucGFnZSgpLmV2YWx1YXRlKChlbDogRWxlbWVudCkgPT4gZWwudGV4dENvbnRlbnQsIGVsZW1lbnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRmFpbGVkIHRvIGdldCBlbGVtZW50IHRleHQ6ICR7ZXJyb3J9YCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgY2hlY2tUZXh0UGF0dGVybnMoXG4gICAgdGV4dDogc3RyaW5nIHwgbnVsbCxcbiAgICBwYXR0ZXJuczogcmVhZG9ubHkgc3RyaW5nW11cbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKCF0ZXh0KSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHBhdHRlcm5zLnNvbWUoKHBhdHRlcm4pID0+IHRleHQuaW5jbHVkZXMocGF0dGVybikpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgIHBhZ2U6IFBhZ2UsXG4gICAgc2VsZWN0b3JzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgICBwYXR0ZXJuczogcmVhZG9ubHkgc3RyaW5nW11cbiAgKTogUHJvbWlzZTx7IGZvdW5kOiBib29sZWFuOyB0ZXh0Pzogc3RyaW5nOyBlbGVtZW50PzogYW55IH0+IHtcbiAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgdGhpcy5nZXRFbGVtZW50VGV4dChlbGVtZW50IGFzIHVua25vd24gYXMgRWxlbWVudCk7XG4gICAgICAgIGlmICh0ZXh0ICYmIChhd2FpdCB0aGlzLmNoZWNrVGV4dFBhdHRlcm5zKHRleHQsIHBhdHRlcm5zKSkpIHtcbiAgICAgICAgICByZXR1cm4geyBmb3VuZDogdHJ1ZSwgdGV4dCwgZWxlbWVudCB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGZvdW5kOiBmYWxzZSB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHdhaXRGb3JDb25kaXRpb24oXG4gICAgY29uZGl0aW9uOiAoKSA9PiBQcm9taXNlPGJvb2xlYW4+LFxuICAgIHRpbWVvdXQ6IG51bWJlcixcbiAgICBjaGVja0ludGVydmFsOiBudW1iZXIgPSAxMDAwLFxuICAgIGVycm9yTWVzc2FnZTogc3RyaW5nXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSA8IHRpbWVvdXQpIHtcbiAgICAgIGlmIChhd2FpdCBjb25kaXRpb24oKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBhd2FpdCBzbGVlcChjaGVja0ludGVydmFsKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGVycm9yTWVzc2FnZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZmlsbFRpdGxlKHBhZ2U6IFBhZ2UsIHRpdGxlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBXYWl0IGZvciBhIGxpa2VseSB0aXRsZSBpbnB1dCB0byBhcHBlYXJcbiAgICB0cnkge1xuICAgICAgYXdhaXQgcGFnZS53YWl0Rm9yU2VsZWN0b3IoXG4gICAgICAgICdpbnB1dC5jLWlucHV0X2lubmVyLCBpbnB1dC5jLWlucHV0LCBpbnB1dFtwbGFjZWhvbGRlcio9XCLmoIfpophcIl0sIC50aXRsZS1pbnB1dCBpbnB1dCwgaW5wdXRbY2xhc3MqPVwidGl0bGVcIl0nLFxuICAgICAgICB7IHRpbWVvdXQ6IDEwMDAwIH1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIENvbnRpbnVlIHdpdGhvdXQgd2FpdGluZyBpZiBub3QgZm91bmQgcHVyZWx5IGJ5IHNlbGVjdG9yXG4gICAgfVxuXG4gICAgY29uc3QgdGl0bGVTZWxlY3RvcnMgPSBbXG4gICAgICAnaW5wdXQuYy1pbnB1dF9pbm5lcicsIC8vIHNwZWNpZmljIGZvciByZWNlbnQgWGlhb2hvbmdzaHUgY3JlYXRvciBVSVxuICAgICAgJ2lucHV0LmMtaW5wdXQnLFxuICAgICAgJ2lucHV0W3BsYWNlaG9sZGVyKj1cIuagh+mimFwiXScsXG4gICAgICAnaW5wdXRbcGxhY2Vob2xkZXIqPVwi5aGr5YaZ5qCH6aKY5Lya5pyJ5pu05aSa6LWe5ZOmXCJdJyxcbiAgICAgICdpbnB1dFtwbGFjZWhvbGRlcio9XCJ0aXRsZVwiXScsXG4gICAgICAnaW5wdXRbZGF0YS1wbGFjZWhvbGRlcio9XCLmoIfpophcIl0nLFxuICAgICAgJy50aXRsZS1pbnB1dCBpbnB1dCcsXG4gICAgICAnaW5wdXRbcGxhY2Vob2xkZXIqPVwi6K+36L6T5YWl5qCH6aKYXCJdJyxcbiAgICAgICdpbnB1dFtuYW1lPVwidGl0bGVcIl0nLFxuICAgICAgJ2lucHV0W2lkKj1cInRpdGxlXCJdJyxcbiAgICAgICdpbnB1dFtjbGFzcyo9XCJ0aXRsZVwiXScsXG4gICAgICAnaW5wdXRbdHlwZT1cInRleHRcIl0nLCAvLyBGYWxsYmFja3NcbiAgICAgICdkaXZbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXScsXG4gICAgICAndGV4dGFyZWFbcGxhY2Vob2xkZXIqPVwi5qCH6aKYXCJdJyxcbiAgICAgICd0ZXh0YXJlYVtwbGFjZWhvbGRlcio9XCJ0aXRsZVwiXScsXG4gICAgXTtcblxuICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgdGl0bGVTZWxlY3RvcnMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHRpdGxlSW5wdXQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAodGl0bGVJbnB1dCkge1xuICAgICAgICAgIC8vIFNjcm9sbCBpbnRvIHZpZXcganVzdCBpbiBjYXNlIGl0J3Mgb2ZmIHNjcmVlblxuICAgICAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgICAgICBpZiAoZWwgJiYgdHlwZW9mIGVsLnNjcm9sbEludG9WaWV3ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIGVsLnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnLCBibG9jazogJ2NlbnRlcicgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgdGl0bGVJbnB1dCk7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcblxuICAgICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IHRpdGxlSW5wdXQuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuXG4gICAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgICAgYXdhaXQgdGl0bGVJbnB1dC5jbGljaygpO1xuICAgICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTsgLy8gV2FpdCBmb3IgZm9jdXNcblxuICAgICAgICAgICAgLy8gY2xlYXIgZXhpc3RpbmcgaW5wdXQgaWYgYW55XG4gICAgICAgICAgICBhd2FpdCB0aXRsZUlucHV0LmNsaWNrKHsgY2xpY2tDb3VudDogMyB9KTtcbiAgICAgICAgICAgIGF3YWl0IHRpdGxlSW5wdXQucHJlc3MoJ0JhY2tzcGFjZScpO1xuXG4gICAgICAgICAgICBhd2FpdCB0aXRsZUlucHV0LnR5cGUodGl0bGUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gQ29udGludWUgdG8gbmV4dCBzZWxlY3RvclxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIG5vIHNwZWNpZmljIGlucHV0IGZvdW5kLCB0cnkgdG8gZmluZCBhbnkgdmlzaWJsZSBpbnB1dCBvciB0ZXh0YXJlYSBvbiB0aGUgcGFnZVxuICAgIHRyeSB7XG4gICAgICBjb25zdCBhbGxJbnB1dHMgPSBhd2FpdCBwYWdlLiQkKCdpbnB1dCwgdGV4dGFyZWEnKTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhbGxJbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBhbGxJbnB1dHNbaV07XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgdHlwZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC5nZXRBdHRyaWJ1dGUoJ3R5cGUnKSwgaW5wdXQpO1xuXG4gICAgICAgICAgLy8gYXZvaWQgZmlsZSBpbnB1dHMgb3IgaGlkZGVuIGlucHV0c1xuICAgICAgICAgIGlmICh0eXBlICE9PSAnZmlsZScgJiYgdHlwZSAhPT0gJ2hpZGRlbicpIHtcbiAgICAgICAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChlbCAmJiB0eXBlb2YgZWwuc2Nyb2xsSW50b1ZpZXcgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBlbC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdjZW50ZXInIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCBpbnB1dCk7XG4gICAgICAgICAgICBhd2FpdCBzbGVlcCg1MDApO1xuXG4gICAgICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCBpbnB1dC5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG5cbiAgICAgICAgICAgIGlmIChpc1Zpc2libGUpIHtcbiAgICAgICAgICAgICAgYXdhaXQgaW5wdXQuY2xpY2soKTtcbiAgICAgICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcblxuICAgICAgICAgICAgICAvLyBjbGVhciBleGlzdGluZyBpbnB1dCBpZiBhbnlcbiAgICAgICAgICAgICAgYXdhaXQgaW5wdXQuY2xpY2soeyBjbGlja0NvdW50OiAzIH0pO1xuICAgICAgICAgICAgICBhd2FpdCBpbnB1dC5wcmVzcygnQmFja3NwYWNlJyk7XG5cbiAgICAgICAgICAgICAgYXdhaXQgaW5wdXQudHlwZSh0aXRsZSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgLy8gQ29udGludWUgdG8gbmV4dCBpbnB1dFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIEZhbGwgdGhyb3VnaCB0byBlcnJvclxuICAgIH1cblxuICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIHRpdGxlIGlucHV0IGZpZWxkJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZmluZENvbnRlbnRFbGVtZW50KHBhZ2U6IFBhZ2UpOiBQcm9taXNlPGFueSB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgLy8gU3RyYXRlZ3kgMTogVHJ5IGRpdltjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdIChzaW1wbGUgYW5kIGRpcmVjdClcbiAgICAgIGNvbnN0IGNvbnRlbnRFZGl0YWJsZSA9IGF3YWl0IHBhZ2UuJCgnZGl2W2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0nKTtcbiAgICAgIGlmIChjb250ZW50RWRpdGFibGUpIHtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgY29udGVudEVkaXRhYmxlLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgIHJldHVybiBjb250ZW50RWRpdGFibGU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgMjogVHJ5IGRpdi50aXB0YXAuUHJvc2VNaXJyb3IgKHByaW1hcnkgc2VsZWN0b3IgZm9yIGNyZWF0b3IgcGxhdGZvcm0pXG4gICAgICBjb25zdCB0aXB0YXBFZGl0b3IgPSBhd2FpdCBwYWdlLiQoJ2Rpdi50aXB0YXAuUHJvc2VNaXJyb3InKTtcbiAgICAgIGlmICh0aXB0YXBFZGl0b3IpIHtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgdGlwdGFwRWRpdG9yLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgIHJldHVybiB0aXB0YXBFZGl0b3I7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgMzogVHJ5IGRpdltyb2xlPVwidGV4dGJveFwiXVtjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdIChzcGVjaWZpYyBzZWxlY3RvcilcbiAgICAgIGNvbnN0IHJvbGVUZXh0Ym94ID0gYXdhaXQgcGFnZS4kKCdkaXZbcm9sZT1cInRleHRib3hcIl1bY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXScpO1xuICAgICAgaWYgKHJvbGVUZXh0Ym94KSB7XG4gICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IHJvbGVUZXh0Ym94LmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgIHJldHVybiByb2xlVGV4dGJveDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSA0OiBUcnkgZGl2LnFsLWVkaXRvciAobGVnYWN5IHNlbGVjdG9yKVxuICAgICAgY29uc3QgcWxFZGl0b3IgPSBhd2FpdCBwYWdlLiQoJ2Rpdi5xbC1lZGl0b3InKTtcbiAgICAgIGlmIChxbEVkaXRvcikge1xuICAgICAgICByZXR1cm4gcWxFZGl0b3I7XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDU6IFRyeSB0byBmaW5kIHRleHRhcmVhIG9yIGNvbnRlbnRlZGl0YWJsZVxuICAgICAgY29uc3QgY29udGVudFNlbGVjdG9ycyA9IFtcbiAgICAgICAgJy50aXB0YXAuUHJvc2VNaXJyb3InLFxuICAgICAgICAndGV4dGFyZWFbcGxhY2Vob2xkZXIqPVwi5q2j5paHXCJdJyxcbiAgICAgICAgJ3RleHRhcmVhW211bHRpbGluZV0nLFxuICAgICAgICAnZGl2W2RhdGEtcGxhY2Vob2xkZXIqPVwi5q2j5paHXCJdJyxcbiAgICAgICAgJy5jb250ZW50LWVkaXRvcicsXG4gICAgICAgICdkaXZbcm9sZT1cInRleHRib3hcIl0nLFxuICAgICAgICAndGV4dGJveFtyb2xlPVwidGV4dGJveFwiXScsXG4gICAgICAgICd0ZXh0Ym94W211bHRpbGluZV0nLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBjb250ZW50U2VsZWN0b3JzKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDY6IFRyeSB0byBmaW5kIGFueSBtdWx0aWxpbmUgdGV4dGJveCAoZmFsbGJhY2spXG4gICAgICBjb25zdCBtdWx0aWxpbmVUZXh0Ym94ZXMgPSBhd2FpdCBwYWdlLiQkKCd0ZXh0Ym94W211bHRpbGluZV0nKTtcbiAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBtdWx0aWxpbmVUZXh0Ym94ZXMpIHtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgZWxlbWVudC5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG4gICAgICAgIGlmIChpc1Zpc2libGUpIHtcbiAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGZpbmRUZXh0Ym94QnlQbGFjZWhvbGRlcihwYWdlOiBQYWdlKTogUHJvbWlzZTxhbnkgfCBudWxsPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEZpbmQgYWxsIHAgZWxlbWVudHNcbiAgICAgIGNvbnN0IHBFbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoJ3AnKTtcblxuICAgICAgLy8gTG9vayBmb3IgZWxlbWVudCB3aXRoIGRhdGEtcGxhY2Vob2xkZXIgY29udGFpbmluZyBcIui+k+WFpeato+aWh+aPj+i/sFwiXG4gICAgICBmb3IgKGNvbnN0IHAgb2YgcEVsZW1lbnRzKSB7XG4gICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLmdldEF0dHJpYnV0ZSgnZGF0YS1wbGFjZWhvbGRlcicpLCBwKTtcbiAgICAgICAgaWYgKHBsYWNlaG9sZGVyPy5pbmNsdWRlcygn6L6T5YWl5q2j5paH5o+P6L+wJykpIHtcbiAgICAgICAgICByZXR1cm4gcDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGZpbmRUZXh0Ym94UGFyZW50KHBhZ2U6IFBhZ2UsIGVsZW1lbnQ6IEVsZW1lbnQpOiBQcm9taXNlPGFueT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgcGFnZS5ldmFsdWF0ZUhhbmRsZSgoZWwpID0+IGVsLnBhcmVudEVsZW1lbnQsIGVsZW1lbnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZmlsbENvbnRlbnQocGFnZTogUGFnZSwgY29udGVudDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gV2FpdCBmb3IgY29udGVudCBhcmVhIHRvIGFwcGVhclxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBwYWdlLndhaXRGb3JTZWxlY3RvcihcbiAgICAgICAgJ2Rpdltyb2xlPVwidGV4dGJveFwiXVtjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdLCAudGlwdGFwLlByb3NlTWlycm9yLCBkaXZbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSwgdGV4dGFyZWEsIFtyb2xlPVwidGV4dGJveFwiXSwgLnFsLWVkaXRvciwgdGV4dGJveFttdWx0aWxpbmVdJyxcbiAgICAgICAgeyB0aW1lb3V0OiAxMDAwMCB9XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBDb250aW51ZSB3aXRob3V0IHdhaXRpbmdcbiAgICB9XG5cbiAgICBsZXQgY29udGVudEVsZW1lbnQgPSBhd2FpdCB0aGlzLmZpbmRDb250ZW50RWxlbWVudChwYWdlKTtcblxuICAgIGlmICghY29udGVudEVsZW1lbnQpIHtcbiAgICAgIC8vIFRyeSBhbHRlcm5hdGl2ZSBhcHByb2FjaFxuICAgICAgY29uc3QgdGV4dGJveEVsZW1lbnQgPSBhd2FpdCB0aGlzLmZpbmRUZXh0Ym94QnlQbGFjZWhvbGRlcihwYWdlKTtcbiAgICAgIGlmICh0ZXh0Ym94RWxlbWVudCkge1xuICAgICAgICBjb250ZW50RWxlbWVudCA9IGF3YWl0IHRoaXMuZmluZFRleHRib3hQYXJlbnQocGFnZSwgdGV4dGJveEVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghY29udGVudEVsZW1lbnQpIHtcbiAgICAgIC8vIFRyeSB0byBmaW5kIGFueSBjb250ZW50ZWRpdGFibGUgb3IgdGV4dGFyZWEgZWxlbWVudFxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYWxsQ29udGVudEVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJChcbiAgICAgICAgICAnZGl2W3JvbGU9XCJ0ZXh0Ym94XCJdW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0sIC50aXB0YXAuUHJvc2VNaXJyb3IsIGRpdltjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdLCB0ZXh0YXJlYSwgW3JvbGU9XCJ0ZXh0Ym94XCJdLCAucWwtZWRpdG9yLCBwW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0sIHRleHRib3hbbXVsdGlsaW5lXSdcbiAgICAgICAgKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFsbENvbnRlbnRFbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhbGxDb250ZW50RWxlbWVudHNbaV07XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IGVsZW1lbnQuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuICAgICAgICAgICAgY29uc3QgdGFnTmFtZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC50YWdOYW1lLCBlbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRFZGl0YWJsZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoXG4gICAgICAgICAgICAgIChlbCkgPT4gZWwuZ2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnKSxcbiAgICAgICAgICAgICAgZWxlbWVudFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHJvbGUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwuZ2V0QXR0cmlidXRlKCdyb2xlJyksIGVsZW1lbnQpO1xuICAgICAgICAgICAgY29uc3QgY2xhc3NOYW1lID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLmNsYXNzTmFtZSwgZWxlbWVudCk7XG4gICAgICAgICAgICBjb25zdCBtdWx0aWxpbmUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwuZ2V0QXR0cmlidXRlKCdtdWx0aWxpbmUnKSwgZWxlbWVudCk7XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgaXNWaXNpYmxlICYmXG4gICAgICAgICAgICAgIChjb250ZW50RWRpdGFibGUgPT09ICd0cnVlJyB8fFxuICAgICAgICAgICAgICAgIHRhZ05hbWUgPT09ICdURVhUQVJFQScgfHxcbiAgICAgICAgICAgICAgICByb2xlID09PSAndGV4dGJveCcgfHxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUuaW5jbHVkZXMoJ3FsLWVkaXRvcicpIHx8XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lLmluY2x1ZGVzKCd0aXB0YXAnKSB8fFxuICAgICAgICAgICAgICAgIG11bHRpbGluZSA9PT0gJycpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgY29udGVudEVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgLy8gQ29udGludWUgdG8gbmV4dCBlbGVtZW50XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBDb250aW51ZSB0byBuZXh0IHN0cmF0ZWd5XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjb250ZW50RWxlbWVudCkge1xuICAgICAgLy8gTGFzdCByZXNvcnQ6IHRyeSB0byBmaW5kIGFueSBlbGVtZW50IHRoYXQgbWlnaHQgYmUgZm9yIGNvbnRlbnRcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGFsbEVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJCgnKicpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTWF0aC5taW4oYWxsRWxlbWVudHMubGVuZ3RoLCA1MCk7IGkrKykge1xuICAgICAgICAgIC8vIExpbWl0IHRvIGZpcnN0IDUwIGVsZW1lbnRzXG4gICAgICAgICAgY29uc3QgZWxlbWVudCA9IGFsbEVsZW1lbnRzW2ldO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCBlbGVtZW50LmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgICAgIGNvbnN0IHRhZ05hbWUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwudGFnTmFtZSwgZWxlbWVudCk7XG4gICAgICAgICAgICBjb25zdCBjb250ZW50RWRpdGFibGUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKFxuICAgICAgICAgICAgICAoZWwpID0+IGVsLmdldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJyksXG4gICAgICAgICAgICAgIGVsZW1lbnRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBjbGFzc05hbWUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwuY2xhc3NOYW1lLCBlbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gYXdhaXQgcGFnZS5ldmFsdWF0ZShcbiAgICAgICAgICAgICAgKGVsKSA9PiBlbC5nZXRBdHRyaWJ1dGUoJ3BsYWNlaG9sZGVyJyksXG4gICAgICAgICAgICAgIGVsZW1lbnRcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgaXNWaXNpYmxlICYmXG4gICAgICAgICAgICAgIChjb250ZW50RWRpdGFibGUgPT09ICd0cnVlJyB8fFxuICAgICAgICAgICAgICAgIHRhZ05hbWUgPT09ICdURVhUQVJFQScgfHxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUuaW5jbHVkZXMoJ2NvbnRlbnQnKSB8fFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZS5pbmNsdWRlcygnZWRpdG9yJykgfHxcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj8uaW5jbHVkZXMoJ+WGheWuuScpIHx8XG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI/LmluY2x1ZGVzKCfmraPmlocnKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBjb250ZW50RWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzIGZvciBpbmRpdmlkdWFsIGVsZW1lbnRzXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBGYWxsIHRocm91Z2ggdG8gZXJyb3JcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWNvbnRlbnRFbGVtZW50KSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdDb3VsZCBub3QgZmluZCBjb250ZW50IGlucHV0IGZpZWxkJyk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNvbnRlbnRFbGVtZW50LmNsaWNrKCk7XG4gICAgICBhd2FpdCBzbGVlcCg1MDApOyAvLyBXYWl0IGZvciBmb2N1c1xuICAgICAgYXdhaXQgKGNvbnRlbnRFbGVtZW50IGFzIGFueSkudHlwZShjb250ZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgRmFpbGVkIHRvIGZpbGwgY29udGVudDogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaW5wdXRUYWdzKHBhZ2U6IFBhZ2UsIGNvbnRlbnRFbGVtZW50OiBhbnksIHRhZ3M6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRhZ0xpc3QgPSB0YWdzXG4gICAgICAuc3BsaXQoJywnKVxuICAgICAgLm1hcCgodGFnKSA9PiB0YWcudHJpbSgpKVxuICAgICAgLmZpbHRlcigodGFnKSA9PiB0YWcubGVuZ3RoID4gMCk7XG5cbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdMaXN0KSB7XG4gICAgICBhd2FpdCB0aGlzLmlucHV0VGFnKHBhZ2UsIGNvbnRlbnRFbGVtZW50LCB0YWcpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBpbnB1dFRhZyhwYWdlOiBQYWdlLCBjb250ZW50RWxlbWVudDogYW55LCB0YWc6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBUeXBlIHRoZSB0YWdcbiAgICAgIGF3YWl0IGNvbnRlbnRFbGVtZW50LnR5cGUoYCMke3RhZ31gKTtcbiAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAvLyBUcnkgdG8gZmluZCB0b3BpYyBzdWdnZXN0aW9uIGNvbnRhaW5lclxuICAgICAgY29uc3QgdG9waWNDb250YWluZXIgPSBhd2FpdCBwYWdlLiQoJyNjcmVhdG9yLWVkaXRvci10b3BpYy1jb250YWluZXInKTtcblxuICAgICAgaWYgKHRvcGljQ29udGFpbmVyKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0SXRlbSA9IGF3YWl0IHRvcGljQ29udGFpbmVyLiQoJy5pdGVtJyk7XG4gICAgICAgIGlmIChmaXJzdEl0ZW0pIHtcbiAgICAgICAgICBhd2FpdCBmaXJzdEl0ZW0uY2xpY2soKTtcbiAgICAgICAgICBhd2FpdCBzbGVlcCg1MDApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBQcmVzcyBFbnRlciB0byBjb25maXJtIHRoZSB0YWdcbiAgICAgICAgYXdhaXQgY29udGVudEVsZW1lbnQucHJlc3MoJ0VudGVyJyk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDUwMCk7XG4gICAgICAgIC8vIFByZXNzIFNwYWNlIHRvIHNlcGFyYXRlIHRhZ3NcbiAgICAgICAgYXdhaXQgY29udGVudEVsZW1lbnQucHJlc3MoJ1NwYWNlJyk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDIwMCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gYWRkIHRhZyAke3RhZ306ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGFkZFRhZ3MocGFnZTogUGFnZSwgdGFnczogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbnRlbnRFbGVtZW50ID0gYXdhaXQgdGhpcy5maW5kQ29udGVudEVsZW1lbnQocGFnZSk7XG4gICAgICBpZiAoY29udGVudEVsZW1lbnQpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbnB1dFRhZ3MocGFnZSwgY29udGVudEVsZW1lbnQsIHRhZ3MpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRmFpbGVkIHRvIGFkZCB0YWdzOiAke2Vycm9yfWApO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBzdWJtaXRQb3N0KHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgLy8gU3RyYXRlZ3kgMTogTG9vayBmb3IgdGhlIDx4aHMtcHVibGlzaC1idG4+IGN1c3RvbSBlbGVtZW50IChuZXcgWEhTIFVJKVxuICAgICAgbGV0IHN1Ym1pdEJ1dHRvbjogaW1wb3J0KCdwdXBwZXRlZXInKS5FbGVtZW50SGFuZGxlPEhUTUxCdXR0b25FbGVtZW50PiB8IG51bGwgPSBudWxsO1xuICAgICAgY29uc3QgY3VzdG9tQnRuID0gYXdhaXQgcGFnZS4kKCd4aHMtcHVibGlzaC1idG4nKTtcbiAgICAgIGlmIChjdXN0b21CdG4pIHtcbiAgICAgICAgLy8gVmVyaWZ5IGl0IGhhcyB0aGUgcmlnaHQgYXR0cmlidXRlcyAoaXMtcHVibGlzaD1cInRydWVcIiwgc3VibWl0LXRleHQ9XCLlj5HluINcIilcbiAgICAgICAgY29uc3QgYXR0cnMgPSBhd2FpdCBjdXN0b21CdG4uZXZhbHVhdGUoKGVsKSA9PiAoe1xuICAgICAgICAgIGlzUHVibGlzaDogZWwuZ2V0QXR0cmlidXRlKCdpcy1wdWJsaXNoJyksXG4gICAgICAgICAgc3VibWl0VGV4dDogZWwuZ2V0QXR0cmlidXRlKCdzdWJtaXQtdGV4dCcpLFxuICAgICAgICAgIHN1Ym1pdERpc2FibGVkOiBlbC5nZXRBdHRyaWJ1dGUoJ3N1Ym1pdC1kaXNhYmxlZCcpLFxuICAgICAgICB9KSk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgeGhzLXB1Ymxpc2gtYnRuIGN1c3RvbSBlbGVtZW50OiAke0pTT04uc3RyaW5naWZ5KGF0dHJzKX1gKTtcbiAgICAgICAgaWYgKGF0dHJzLmlzUHVibGlzaCA9PT0gJ3RydWUnIHx8IGF0dHJzLnN1Ym1pdFRleHQgPT09ICflj5HluIMnKSB7XG4gICAgICAgICAgc3VibWl0QnV0dG9uID0gY3VzdG9tQnRuIGFzIGltcG9ydCgncHVwcGV0ZWVyJykuRWxlbWVudEhhbmRsZTxIVE1MQnV0dG9uRWxlbWVudD47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgMjogTG9vayBmb3Igc3RhbmRhcmQgYnV0dG9uIGVsZW1lbnRzIGNvbnRhaW5pbmcgXCLlj5HluINcIlxuICAgICAgaWYgKCFzdWJtaXRCdXR0b24pIHtcbiAgICAgICAgY29uc3QgYnV0dG9ucyA9IGF3YWl0IHBhZ2UuJCQoJ2J1dHRvbicpO1xuICAgICAgICBmb3IgKGNvbnN0IGJ0biBvZiBidXR0b25zKSB7XG4gICAgICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IGJ0bi5ldmFsdWF0ZShlbCA9PiBlbC50ZXh0Q29udGVudD8udHJpbSgpKTtcbiAgICAgICAgICBpZiAodGV4dD8uaW5jbHVkZXMoJ+WPkeW4gycpKSB7XG4gICAgICAgICAgICBzdWJtaXRCdXR0b24gPSBidG4gYXMgaW1wb3J0KCdwdXBwZXRlZXInKS5FbGVtZW50SGFuZGxlPEhUTUxCdXR0b25FbGVtZW50PjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIXN1Ym1pdEJ1dHRvbikge1xuICAgICAgICAvLyBTdHJhdGVneSAzOiBzZWFyY2ggYWxsIHZpc2libGUgZGl2L3NwYW4gZWxlbWVudHMgY29udGFpbmluZyBcIuWPkeW4g1wiIHRleHRcbiAgICAgICAgY29uc3QgdGV4dENhbmRpZGF0ZXMgPSBhd2FpdCBwYWdlLiQkKCdkaXYsIHNwYW4nKTtcbiAgICAgICAgZm9yIChjb25zdCBlbCBvZiB0ZXh0Q2FuZGlkYXRlcykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgZWwuZXZhbHVhdGUoZWwgPT4gZWwudGV4dENvbnRlbnQ/LnRyaW0oKSk7XG4gICAgICAgICAgICBpZiAodGV4dD8uaW5jbHVkZXMoJ+WPkeW4gycpICYmIHRleHQubGVuZ3RoIDwgMjApIHtcbiAgICAgICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgZWwuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpLmNhdGNoKCgpID0+IGZhbHNlKTtcbiAgICAgICAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgICAgICAgIHN1Ym1pdEJ1dHRvbiA9IGVsIGFzIGltcG9ydCgncHVwcGV0ZWVyJykuRWxlbWVudEhhbmRsZTxIVE1MQnV0dG9uRWxlbWVudD47XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIXN1Ym1pdEJ1dHRvbikge1xuICAgICAgICBjb25zdCBzdWJtaXRTZWxlY3RvciA9ICdkaXYuc3VibWl0LCAuc3VibWl0LWJ0biwgLnB1Ymxpc2gtYnRuLCBbY2xhc3MqPVwicHVibGlzaFwiXSwgW2NsYXNzKj1cImJ0bi1cIl0sIC5idG4tdGV4dCc7XG4gICAgICAgIHN1Ym1pdEJ1dHRvbiA9IGF3YWl0IHBhZ2UuJChzdWJtaXRTZWxlY3RvcikgYXMgaW1wb3J0KCdwdXBwZXRlZXInKS5FbGVtZW50SGFuZGxlPEhUTUxCdXR0b25FbGVtZW50PiB8IG51bGw7XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDU6IFhQYXRoIHRleHQgbWF0Y2hcbiAgICAgIGlmICghc3VibWl0QnV0dG9uKSB7XG4gICAgICAgIGNvbnN0IHB1Ymxpc2hUZXh0cyA9IFsn5Y+R5biD56yU6K6wJywgJ+WPkeW4gycsICflj5HooagnXTtcbiAgICAgICAgZm9yIChjb25zdCB0ZXh0IG9mIHB1Ymxpc2hUZXh0cykge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gYXdhaXQgKHBhZ2UgYXMgYW55KS4keChgLy8qW2NvbnRhaW5zKHRleHQoKSwgJyR7dGV4dH0nKV1gKTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGVsIG9mIGVsZW1lbnRzKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCByZWN0ID0gYXdhaXQgZWwuZXZhbHVhdGUoKGVsOiBFbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgciA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHc6IHIud2lkdGgsIGg6IHIuaGVpZ2h0IH07XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBpZiAocmVjdC53ID4gMCAmJiByZWN0LmggPiAwKSB7XG4gICAgICAgICAgICAgICAgc3VibWl0QnV0dG9uID0gZWwgYXMgaW1wb3J0KCdwdXBwZXRlZXInKS5FbGVtZW50SGFuZGxlPEhUTUxCdXR0b25FbGVtZW50PjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc3VibWl0QnV0dG9uKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSA2OiBGaW5kIC5idG4tdGV4dCBzcGFuIGFuZCBjbGljayBwYXJlbnRcbiAgICAgIGlmICghc3VibWl0QnV0dG9uKSB7XG4gICAgICAgIGNvbnN0IGJ0blRleHRFbCA9IGF3YWl0IHBhZ2UuJCgnLmJ0bi10ZXh0Jyk7XG4gICAgICAgIGlmIChidG5UZXh0RWwpIHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgYnRuVGV4dEVsLmV2YWx1YXRlKGVsID0+IGVsLnRleHRDb250ZW50Py50cmltKCkpO1xuICAgICAgICAgIGlmICh0ZXh0Py5pbmNsdWRlcygn5Y+R5biDJykpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudCA9IGF3YWl0IGJ0blRleHRFbC5ldmFsdWF0ZUhhbmRsZShlbCA9PlxuICAgICAgICAgICAgICBlbC5jbG9zZXN0KCdbY2xhc3MqPVwicHVibGlzaFwiXSwgW2NsYXNzKj1cImJ0bi1cIl0nKSB8fCBlbC5wYXJlbnRFbGVtZW50XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICAgICAgICBzdWJtaXRCdXR0b24gPSBwYXJlbnQgYXMgaW1wb3J0KCdwdXBwZXRlZXInKS5FbGVtZW50SGFuZGxlPEhUTUxCdXR0b25FbGVtZW50PjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFzdWJtaXRCdXR0b24pIHtcbiAgICAgICAgLy8gRGVidWc6IGR1bXAga2V5IGluZm8gYWJvdXQgdGhlIHBhZ2Ugc3RhdGVcbiAgICAgICAgY29uc3QgZGVidWdJbmZvID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAgICAgLy8gRmluZCBhbGwgZWxlbWVudHMgbWVudGlvbmluZyDlj5HluINcbiAgICAgICAgICBjb25zdCBwdWJsaXNoRWxlbWVudHM6IHt0YWc6IHN0cmluZzsgdGV4dDogc3RyaW5nOyBjbGFzczogc3RyaW5nOyB2aXNpYmxlOiBib29sZWFuOyByZWN0OiBzdHJpbmd9W10gPSBbXTtcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcqJykuZm9yRWFjaChlbCA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZXh0ID0gZWwudGV4dENvbnRlbnQ/LnRyaW0oKTtcbiAgICAgICAgICAgIGlmICh0ZXh0Py5pbmNsdWRlcygn5Y+R5biDJykpIHtcbiAgICAgICAgICAgICAgY29uc3QgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgICBwdWJsaXNoRWxlbWVudHMucHVzaCh7XG4gICAgICAgICAgICAgICAgdGFnOiBlbC50YWdOYW1lLFxuICAgICAgICAgICAgICAgIHRleHQ6IHRleHQuc3Vic3RyaW5nKDAsIDMwKSxcbiAgICAgICAgICAgICAgICBjbGFzczogKGVsIGFzIEhUTUxFbGVtZW50KS5jbGFzc05hbWU/LnN1YnN0cmluZygwLCA4MCksXG4gICAgICAgICAgICAgICAgdmlzaWJsZTogcmVjdC53aWR0aCA+IDAgJiYgcmVjdC5oZWlnaHQgPiAwLFxuICAgICAgICAgICAgICAgIHJlY3Q6IGAke3JlY3Qud2lkdGgudG9GaXhlZCgwKX14JHtyZWN0LmhlaWdodC50b0ZpeGVkKDApfSBhdCAke3JlY3QudG9wLnRvRml4ZWQoMCl9LCR7cmVjdC5sZWZ0LnRvRml4ZWQoMCl9YCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHVybDogd2luZG93LmxvY2F0aW9uLmhyZWYsXG4gICAgICAgICAgICBib2R5SGVpZ2h0OiBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodCxcbiAgICAgICAgICAgIHZpZXdwb3J0SGVpZ2h0OiB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgICAgICAgICBwdWJsaXNoRWxlbWVudHM6IHB1Ymxpc2hFbGVtZW50cy5zbGljZSgwLCA0MCksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBDb3VsZCBub3QgZmluZCBzdWJtaXQgYnV0dG9uLiBVUkw9JHtkZWJ1Z0luZm8udXJsfSwgYm9keT0ke2RlYnVnSW5mby5ib2R5SGVpZ2h0fSwgdnA9JHtkZWJ1Z0luZm8udmlld3BvcnRIZWlnaHR9LCBwdWJsaXNoRWxlbXM9JHtKU09OLnN0cmluZ2lmeShkZWJ1Z0luZm8ucHVibGlzaEVsZW1lbnRzKX1gKTtcbiAgICAgIH1cblxuICAgICAgLy8gUHJlLWNsaWNrIGNoZWNrczogZW5zdXJlIGJ1dHRvbiBpcyBlbmFibGVkIGFuZCBjbGlja2FibGVcbiAgICAgIGNvbnN0IGJ1dHRvblN0YXRlID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IHtcbiAgICAgICAgaWYgKCFlbCkgcmV0dXJuIHsgZXhpc3RzOiBmYWxzZSB9O1xuICAgICAgICBjb25zdCBodG1sRWwgPSBlbCBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgY29uc3Qgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShodG1sRWwpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGV4aXN0czogdHJ1ZSxcbiAgICAgICAgICBkaXNhYmxlZDogaHRtbEVsLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKSB8fCBodG1sRWwuZ2V0QXR0cmlidXRlKCdhcmlhLWRpc2FibGVkJykgPT09ICd0cnVlJyxcbiAgICAgICAgICBwb2ludGVyRXZlbnRzOiBzdHlsZS5wb2ludGVyRXZlbnRzLFxuICAgICAgICAgIG9wYWNpdHk6IHN0eWxlLm9wYWNpdHksXG4gICAgICAgICAgdmlzaWJpbGl0eTogc3R5bGUudmlzaWJpbGl0eSxcbiAgICAgICAgICBkaXNwbGF5OiBzdHlsZS5kaXNwbGF5LFxuICAgICAgICAgIHRhZ05hbWU6IGh0bWxFbC50YWdOYW1lLFxuICAgICAgICAgIGNsYXNzTmFtZTogaHRtbEVsLmNsYXNzTmFtZSxcbiAgICAgICAgICB0ZXh0OiBodG1sRWwudGV4dENvbnRlbnQ/LnRyaW0oKS5zdWJzdHJpbmcoMCwgMjApLFxuICAgICAgICB9O1xuICAgICAgfSwgc3VibWl0QnV0dG9uKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgU3VibWl0IGJ1dHRvbiBzdGF0ZTogJHtKU09OLnN0cmluZ2lmeShidXR0b25TdGF0ZSl9YCk7XG5cbiAgICAgIGlmIChidXR0b25TdGF0ZS5kaXNhYmxlZCkge1xuICAgICAgICBsb2dnZXIud2FybignU3VibWl0IGJ1dHRvbiBpcyBkaXNhYmxlZCAtIHB1Ymxpc2hpbmcgbWF5IGZhaWwnKTtcbiAgICAgIH1cblxuICAgICAgLy8gU2Nyb2xsIHRvIGJ1dHRvbiBiZWZvcmUgY2xpY2tpbmdcbiAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgIGlmIChlbCAmJiB0eXBlb2YgZWwuc2Nyb2xsSW50b1ZpZXcgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBlbC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnaW5zdGFudCcsIGJsb2NrOiAnY2VudGVyJyB9KTtcbiAgICAgICAgfVxuICAgICAgfSwgc3VibWl0QnV0dG9uKTtcbiAgICAgIGF3YWl0IHNsZWVwKDUwMCk7XG5cbiAgICAgIC8vIEhlbHBlciB0byBjaGVjayBpZiBwdWJsaXNoIHdhcyB0cmlnZ2VyZWQgKHBhZ2UgbmF2aWdhdGluZyBhd2F5IG9yIHNob3dpbmcgc3VjY2VzcylcbiAgICAgIGNvbnN0IGlzUHVibGlzaFRyaWdnZXJlZCA9IGFzeW5jICgpOiBQcm9taXNlPGJvb2xlYW4+ID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50VXJsID0gcGFnZS51cmwoKTtcbiAgICAgICAgICBjb25zdCBib2R5VGV4dCA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gZG9jdW1lbnQuYm9keT8udGV4dENvbnRlbnQgfHwgJycpO1xuICAgICAgICAgIHJldHVybiAhY3VycmVudFVybC5pbmNsdWRlcygnL3B1Ymxpc2gvcHVibGlzaCcpIHx8XG4gICAgICAgICAgICBib2R5VGV4dC5pbmNsdWRlcygn5Y+R5biD5oiQ5YqfJykgfHxcbiAgICAgICAgICAgIGJvZHlUZXh0LmluY2x1ZGVzKCflrqHmoLjkuK0nKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICAvLyBTdHJhdGVneSBBOiBGb3IgeGhzLXB1Ymxpc2gtYnRuIGN1c3RvbSBlbGVtZW50LCBkaXNwYXRjaCBhIEN1c3RvbUV2ZW50KCdwdWJsaXNoJylcbiAgICAgIGNvbnN0IGlzQ3VzdG9tRWxlbWVudCA9IGF3YWl0IHN1Ym1pdEJ1dHRvbi5ldmFsdWF0ZSgoZWwpID0+IGVsLnRhZ05hbWUgPT09ICdYSFMtUFVCTElTSC1CVE4nKTtcbiAgICAgIGlmIChpc0N1c3RvbUVsZW1lbnQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFlbCkgcmV0dXJuO1xuICAgICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoJ3B1Ymxpc2gnLCB7IGJ1YmJsZXM6IHRydWUsIGNvbXBvc2VkOiB0cnVlIH0pKTtcbiAgICAgICAgICB9LCBzdWJtaXRCdXR0b24pO1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnRGlzcGF0Y2hlZCBDdXN0b21FdmVudChcInB1Ymxpc2hcIikgb24geGhzLXB1Ymxpc2gtYnRuJyk7XG4gICAgICAgIH0gY2F0Y2ggKGN1c3RvbUV2ZW50RXJyb3IpIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoYEN1c3RvbUV2ZW50IGRpc3BhdGNoIGZhaWxlZDogJHtjdXN0b21FdmVudEVycm9yfWApO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKDE1MDApO1xuICAgICAgICBpZiAoYXdhaXQgaXNQdWJsaXNoVHJpZ2dlcmVkKCkpIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgQjogRnVsbCBSZWFjdCBldmVudCBjaGFpbiB2aWEgZXZhbHVhdGUgKGZhbGxiYWNrIGZvciBzdGFuZGFyZCBlbGVtZW50cylcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgICAgaWYgKCFlbCkgcmV0dXJuO1xuICAgICAgICAgIGNvbnN0IGh0bWxFbCA9IGVsIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgIGNvbnN0IHJlY3QgPSBodG1sRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgY29uc3QgeCA9IHJlY3QubGVmdCArIHJlY3Qud2lkdGggLyAyO1xuICAgICAgICAgIGNvbnN0IHkgPSByZWN0LnRvcCArIHJlY3QuaGVpZ2h0IC8gMjtcbiAgICAgICAgICBjb25zdCBldmVudEluaXQgPSB7IGJ1YmJsZXM6IHRydWUsIGNhbmNlbGFibGU6IHRydWUsIGNvbXBvc2VkOiB0cnVlLCBjbGllbnRYOiB4LCBjbGllbnRZOiB5LCBzY3JlZW5YOiB4LCBzY3JlZW5ZOiB5IH07XG4gICAgICAgICAgY29uc3QgZXZlbnRzID0gW1xuICAgICAgICAgICAgbmV3IE1vdXNlRXZlbnQoJ21vdXNlZW50ZXInLCBldmVudEluaXQpLFxuICAgICAgICAgICAgbmV3IE1vdXNlRXZlbnQoJ21vdXNlb3ZlcicsIGV2ZW50SW5pdCksXG4gICAgICAgICAgICBuZXcgTW91c2VFdmVudCgnbW91c2Vtb3ZlJywgZXZlbnRJbml0KSxcbiAgICAgICAgICAgIG5ldyBNb3VzZUV2ZW50KCdtb3VzZWRvd24nLCB7IC4uLmV2ZW50SW5pdCwgYnV0dG9uOiAwLCBidXR0b25zOiAxIH0pLFxuICAgICAgICAgICAgbmV3IEZvY3VzRXZlbnQoJ2ZvY3VzJywgeyBidWJibGVzOiB0cnVlIH0pLFxuICAgICAgICAgICAgbmV3IE1vdXNlRXZlbnQoJ21vdXNldXAnLCB7IC4uLmV2ZW50SW5pdCwgYnV0dG9uOiAwLCBidXR0b25zOiAwIH0pLFxuICAgICAgICAgICAgbmV3IE1vdXNlRXZlbnQoJ2NsaWNrJywgeyAuLi5ldmVudEluaXQsIGJ1dHRvbjogMCwgYnV0dG9uczogMCB9KSxcbiAgICAgICAgICBdO1xuICAgICAgICAgIGV2ZW50cy5mb3JFYWNoKChldikgPT4gaHRtbEVsLmRpc3BhdGNoRXZlbnQoZXYpKTtcbiAgICAgICAgfSwgc3VibWl0QnV0dG9uKTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdEaXNwYXRjaGVkIGZ1bGwgUmVhY3QgZXZlbnQgY2hhaW4gb24gc3VibWl0IGJ1dHRvbicpO1xuICAgICAgfSBjYXRjaCAoY2hhaW5FcnJvcikge1xuICAgICAgICBsb2dnZXIuZGVidWcoYFJlYWN0IGV2ZW50IGNoYWluIGZhaWxlZDogJHtjaGFpbkVycm9yfWApO1xuICAgICAgfVxuICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG4gICAgICBpZiAoYXdhaXQgaXNQdWJsaXNoVHJpZ2dlcmVkKCkpIHJldHVybjtcblxuICAgICAgLy8gU3RyYXRlZ3kgQzogUHVwcGV0ZWVyIG5hdGl2ZSBjbGljayBhcyBmYWxsYmFja1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc3VibWl0QnV0dG9uLmNsaWNrKCk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnQ2xpY2tlZCBzdWJtaXQgYnV0dG9uIHZpYSBQdXBwZXRlZXIgbmF0aXZlIGNsaWNrJyk7XG4gICAgICB9IGNhdGNoIChjbGlja0Vycm9yKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgUHVwcGV0ZWVyIGNsaWNrIGZhaWxlZDogJHtjbGlja0Vycm9yfWApO1xuICAgICAgfVxuICAgICAgYXdhaXQgc2xlZXAoODAwKTtcbiAgICAgIGlmIChhd2FpdCBpc1B1Ymxpc2hUcmlnZ2VyZWQoKSkgcmV0dXJuO1xuXG4gICAgICAvLyBTdHJhdGVneSBEOiBKYXZhU2NyaXB0IGNsaWNrIHZpYSBldmFsdWF0ZVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IHsgaWYgKGVsKSAoZWwgYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCk7IH0sIHN1Ym1pdEJ1dHRvbik7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnQ2xpY2tlZCBzdWJtaXQgYnV0dG9uIHZpYSBKUyBldmFsdWF0ZSBjbGljaycpO1xuICAgICAgfSBjYXRjaCAoanNDbGlja0Vycm9yKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgSlMgZXZhbHVhdGUgY2xpY2sgZmFpbGVkOiAke2pzQ2xpY2tFcnJvcn1gKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHNsZWVwKDgwMCk7XG4gICAgICBpZiAoYXdhaXQgaXNQdWJsaXNoVHJpZ2dlcmVkKCkpIHJldHVybjtcblxuICAgICAgLy8gU3RyYXRlZ3kgRTogVHJ5IGNsaWNraW5nIHZpYSBwYWdlLm1vdXNlIGF0IGVsZW1lbnQgY2VudGVyIGNvb3JkaW5hdGVzXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBib3ggPSBhd2FpdCBzdWJtaXRCdXR0b24uYm91bmRpbmdCb3goKTtcbiAgICAgICAgaWYgKGJveCkge1xuICAgICAgICAgIGF3YWl0IHBhZ2UubW91c2UubW92ZShib3gueCArIGJveC53aWR0aCAvIDIsIGJveC55ICsgYm94LmhlaWdodCAvIDIpO1xuICAgICAgICAgIGF3YWl0IHBhZ2UubW91c2UuZG93bigpO1xuICAgICAgICAgIGF3YWl0IHNsZWVwKDUwKTtcbiAgICAgICAgICBhd2FpdCBwYWdlLm1vdXNlLnVwKCk7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdDbGlja2VkIHN1Ym1pdCBidXR0b24gdmlhIG1vdXNlIGNvb3JkaW5hdGVzJyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKG1vdXNlRXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBNb3VzZSBjbGljayBmYWlsZWQ6ICR7bW91c2VFcnJvcn1gKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHNsZWVwKDE1MDApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBGYWlsZWQgdG8gY2xpY2sgc3VibWl0IGJ1dHRvbjogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaXNFbGVtZW50VmlzaWJsZShlbGVtZW50OiBFbGVtZW50KTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCAoZWxlbWVudCBhcyBhbnkpLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB3YWl0Rm9yUHVibGlzaENvbXBsZXRpb24ocGFnZTogUGFnZSk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGNvbnN0IG1heFdhaXRUaW1lID0gMzAwMDA7IC8vIDMwIHNlY29uZHMgKHJlZHVjZWQgZnJvbSA2MHMpXG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBwdWJsaXNoU3RhcnRVcmwgPSBwYWdlLnVybCgpO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPCBtYXhXYWl0VGltZSkge1xuICAgICAgY29uc3QgY3VycmVudFVybCA9IHBhZ2UudXJsKCk7XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDE6IENoZWNrIGZvciBzdWNjZXNzIGluZGljYXRvcnMgdmlhIENTUyBzZWxlY3RvcnNcbiAgICAgIGNvbnN0IHN1Y2Nlc3NJbmRpY2F0b3JzID0gW1xuICAgICAgICAnLnN1Y2Nlc3MtbWVzc2FnZScsXG4gICAgICAgICcucHVibGlzaC1zdWNjZXNzJyxcbiAgICAgICAgJ1tkYXRhLXRlc3RpZD1cInB1Ymxpc2gtc3VjY2Vzc1wiXScsXG4gICAgICAgICcudG9hc3Qtc3VjY2VzcycsXG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHN1Y2Nlc3NJbmRpY2F0b3JzKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgc3VjY2VzcyBpbmRpY2F0b3I6ICR7c2VsZWN0b3J9YCk7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDI6IENoZWNrIGZvciBlcnJvciBpbmRpY2F0b3JzXG4gICAgICBjb25zdCBlcnJvckluZGljYXRvcnMgPSBbXG4gICAgICAgICcuZXJyb3ItbWVzc2FnZScsXG4gICAgICAgICcucHVibGlzaC1lcnJvcicsXG4gICAgICAgICdbZGF0YS10ZXN0aWQ9XCJwdWJsaXNoLWVycm9yXCJdJyxcbiAgICAgICAgJy50b2FzdC1lcnJvcicsXG4gICAgICAgICcuZXJyb3ItdG9hc3QnLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBlcnJvckluZGljYXRvcnMpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgZXJyb3JUZXh0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLnRleHRDb250ZW50LCBlbGVtZW50KTtcbiAgICAgICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBQdWJsaXNoIGZhaWxlZCB3aXRoIGVycm9yOiAke2Vycm9yVGV4dH1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSAzOiBDaGVjayBpZiB3ZSdyZSBzdGlsbCBvbiB0aGUgcHVibGlzaCBwYWdlXG4gICAgICBjb25zdCBwdWJsaXNoUGFnZUluZGljYXRvcnMgPSBbJ2Rpdi51cGxvYWQtY29udGVudCcsICdkaXYuc3VibWl0JywgJy5jcmVhdG9yLWVkaXRvciddO1xuXG4gICAgICBsZXQgc3RpbGxPblB1Ymxpc2hQYWdlID0gZmFsc2U7XG4gICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHB1Ymxpc2hQYWdlSW5kaWNhdG9ycykge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICBzdGlsbE9uUHVibGlzaFBhZ2UgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghc3RpbGxPblB1Ymxpc2hQYWdlKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnTGVmdCBwdWJsaXNoIHBhZ2UsIGFzc3VtaW5nIHN1Y2Nlc3MnKTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2UpO1xuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSA0OiBDaGVjayBmb3IgdG9hc3QvcG9wdXAgbWVzc2FnZXMgd2l0aCB0ZXh0IGNvbnRlbnRcbiAgICAgIGNvbnN0IHRvYXN0U2VsZWN0b3JzID0gWycudG9hc3QnLCAnLm1lc3NhZ2UnLCAnLm5vdGlmaWNhdGlvbicsICdbcm9sZT1cImFsZXJ0XCJdJ107XG5cbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgdG9hc3RTZWxlY3RvcnMpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgdG9hc3RUZXh0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLnRleHRDb250ZW50LCBlbGVtZW50KTtcbiAgICAgICAgICBpZiAodG9hc3RUZXh0KSB7XG4gICAgICAgICAgICBpZiAodG9hc3RUZXh0LmluY2x1ZGVzKCfmiJDlip8nKSB8fCB0b2FzdFRleHQuaW5jbHVkZXMoJ3N1Y2Nlc3MnKSkge1xuICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIHN1Y2Nlc3MgdG9hc3Q6ICR7dG9hc3RUZXh0fWApO1xuICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5leHRyYWN0Tm90ZUlkRnJvbVBhZ2UocGFnZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICB0b2FzdFRleHQuaW5jbHVkZXMoJ+Wksei0pScpIHx8XG4gICAgICAgICAgICAgIHRvYXN0VGV4dC5pbmNsdWRlcygnZXJyb3InKSB8fFxuICAgICAgICAgICAgICB0b2FzdFRleHQuaW5jbHVkZXMoJ+mUmeivrycpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgUHVibGlzaCBmYWlsZWQ6ICR7dG9hc3RUZXh0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSA1OiBCcm9hZCB0ZXh0LWJhc2VkIHN1Y2Nlc3MgZGV0ZWN0aW9uXG4gICAgICBjb25zdCB0ZXh0U3VjY2Vzc0VsZW1lbnRzID0gYXdhaXQgcGFnZS4kJCgnZGl2LCBzcGFuLCBwLCBoMSwgaDIsIGgzLCBidXR0b24nKTtcbiAgICAgIGZvciAoY29uc3QgZWwgb2YgdGV4dFN1Y2Nlc3NFbGVtZW50cykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCBlbC5ldmFsdWF0ZSgoZSkgPT4gZS50ZXh0Q29udGVudD8udHJpbSgpKTtcbiAgICAgICAgICBpZiAodGV4dCAmJiB0ZXh0Lmxlbmd0aCA8IDUwKSB7XG4gICAgICAgICAgICBpZiAodGV4dC5pbmNsdWRlcygn5Y+R5biD5oiQ5YqfJykgfHwgdGV4dC5pbmNsdWRlcygn5oqV56i/5oiQ5YqfJykgfHwgdGV4dC5pbmNsdWRlcygn5a6h5qC45LitJykpIHtcbiAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBGb3VuZCB0ZXh0IHN1Y2Nlc3MgaW5kaWNhdG9yOiAke3RleHR9YCk7XG4gICAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmV4dHJhY3ROb3RlSWRGcm9tUGFnZShwYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0ZXh0LmluY2x1ZGVzKCflj5HluIPlpLHotKUnKSB8fCB0ZXh0LmluY2x1ZGVzKCfmipXnqL/lpLHotKUnKSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBQdWJsaXNoIGZhaWxlZDogJHt0ZXh0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgNjogVVJMIGNoYW5nZSBkZXRlY3Rpb24gKG5hdmlnYXRlZCBhd2F5IGZyb20gcHVibGlzaCBwYWdlKVxuICAgICAgaWYgKGN1cnJlbnRVcmwgIT09IHB1Ymxpc2hTdGFydFVybCkge1xuICAgICAgICBjb25zdCBpc1B1Ymxpc2hVcmwgPSBjdXJyZW50VXJsLmluY2x1ZGVzKCcvcHVibGlzaCcpIHx8IGN1cnJlbnRVcmwuaW5jbHVkZXMoJy9jcmVhdG9yJyk7XG4gICAgICAgIGlmICghaXNQdWJsaXNoVXJsKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKGBVUkwgY2hhbmdlZCBmcm9tIHB1Ymxpc2ggcGFnZSB0byAke2N1cnJlbnRVcmx9LCBhc3N1bWluZyBzdWNjZXNzYCk7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDc6IENoZWNrIGZvciBsb2FkaW5nL3N1Y2Nlc3Mgb3ZlcmxheXNcbiAgICAgIGNvbnN0IG92ZXJsYXlTZWxlY3RvcnMgPSBbJy5tb2RhbCcsICcucG9wdXAnLCAnLmRpYWxvZycsICcub3ZlcmxheScsICdbY2xhc3MqPVwic3VjY2Vzc1wiXScsICdbY2xhc3MqPVwibW9kYWxcIl0nXTtcbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2Ygb3ZlcmxheVNlbGVjdG9ycykge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgZWxlbWVudC5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCkuY2F0Y2goKCkgPT4gZmFsc2UpO1xuICAgICAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgZWxlbWVudC5ldmFsdWF0ZSgoZSkgPT4gZS50ZXh0Q29udGVudD8udHJpbSgpKTtcbiAgICAgICAgICAgICAgaWYgKHRleHQgJiYgKHRleHQuaW5jbHVkZXMoJ+aIkOWKnycpIHx8IHRleHQuaW5jbHVkZXMoJ+WPkeW4gycpKSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgb3ZlcmxheSB3aXRoIHN1Y2Nlc3MgdGV4dDogJHt0ZXh0LnN1YnN0cmluZygwLCA1MCl9YCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYXdhaXQgc2xlZXAoODAwKTsgLy8gV2FpdCBiZWZvcmUgbmV4dCBjaGVja1xuICAgIH1cblxuICAgIC8vIFRpbWVvdXQ6IGNvbGxlY3QgZGVidWcgaW5mb1xuICAgIGNvbnN0IGRlYnVnSW5mbyA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgY29uc3QgYWxsVGV4dHM6IHN0cmluZ1tdID0gW107XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdkaXYsIHNwYW4sIHAsIGgxLCBoMiwgaDMsIGJ1dHRvbicpLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBlbC50ZXh0Q29udGVudD8udHJpbSgpO1xuICAgICAgICBpZiAodGV4dCAmJiB0ZXh0Lmxlbmd0aCA+IDAgJiYgdGV4dC5sZW5ndGggPCAxMDApIHtcbiAgICAgICAgICBhbGxUZXh0cy5wdXNoKHRleHQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHVybDogd2luZG93LmxvY2F0aW9uLmhyZWYsXG4gICAgICAgIGJvZHlUZXh0OiBkb2N1bWVudC5ib2R5Py50ZXh0Q29udGVudD8uc3Vic3RyaW5nKDAsIDUwMCkgfHwgJycsXG4gICAgICAgIHZpc2libGVUZXh0czogYWxsVGV4dHMuZmlsdGVyKCh0LCBpLCBhcnIpID0+IGFyci5pbmRleE9mKHQpID09PSBpKS5zbGljZSgwLCAzMCksXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgbG9nZ2VyLmRlYnVnKGBQdWJsaXNoIHRpbWVvdXQgZGVidWcgLSBVUkw6ICR7ZGVidWdJbmZvLnVybH1gKTtcbiAgICBsb2dnZXIuZGVidWcoYFZpc2libGUgdGV4dHM6ICR7ZGVidWdJbmZvLnZpc2libGVUZXh0cy5qb2luKCcgfCAnKX1gKTtcblxuICAgIC8vIENoZWNrIGlmIHBhZ2UgbGVmdCBwdWJsaXNoIFVSTCAoZXZlbiBpZiBub3QgZGV0ZWN0ZWQgZWFybGllcikgLSBhc3N1bWUgc3VjY2Vzc1xuICAgIGNvbnN0IGlzU3RpbGxPblB1Ymxpc2hVcmwgPSBkZWJ1Z0luZm8udXJsLmluY2x1ZGVzKCcvcHVibGlzaCcpO1xuICAgIGNvbnN0IGhhc0Vycm9yVGV4dCA9IGRlYnVnSW5mby52aXNpYmxlVGV4dHMuc29tZShcbiAgICAgICh0KSA9PiB0LmluY2x1ZGVzKCflpLHotKUnKSB8fCB0LmluY2x1ZGVzKCfplJnor68nKSB8fCB0LmluY2x1ZGVzKCdlcnJvcicpIHx8IHQuaW5jbHVkZXMoJ+aXoOazlScpXG4gICAgKTtcblxuICAgIGlmICghaXNTdGlsbE9uUHVibGlzaFVybCB8fCAhaGFzRXJyb3JUZXh0KSB7XG4gICAgICBsb2dnZXIud2FybihgUHVibGlzaCBjb21wbGV0aW9uIHRpbWVkIG91dCBidXQgbm8gZXJyb3IgZGV0ZWN0ZWQuIEFzc3VtaW5nIHN1Y2Nlc3MuIFVSTD0ke2RlYnVnSW5mby51cmx9YCk7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5leHRyYWN0Tm90ZUlkRnJvbVBhZ2UocGFnZSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihcbiAgICAgIGBQdWJsaXNoIGNvbXBsZXRpb24gdGltZW91dCAtIGNvdWxkIG5vdCBkZXRlcm1pbmUgcmVzdWx0LiBVUkw9JHtkZWJ1Z0luZm8udXJsfSwgdGV4dHM9JHtkZWJ1Z0luZm8udmlzaWJsZVRleHRzLmpvaW4oJywgJykuc3Vic3RyaW5nKDAsIDIwMCl9YFxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgLy8gTWV0aG9kIDE6IFRyeSB0byBleHRyYWN0IGZyb20gVVJMIGlmIHJlZGlyZWN0ZWQgdG8gbm90ZSBwYWdlXG4gICAgICBjb25zdCBjdXJyZW50VXJsID0gcGFnZS51cmwoKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQ3VycmVudCBVUkwgYWZ0ZXIgcHVibGlzaDogJHtjdXJyZW50VXJsfWApO1xuXG4gICAgICAvLyBDaGVjayBpZiB3ZSdyZSBvbiBhIG5vdGUgcGFnZSAoVVJMIGNvbnRhaW5zIC9leHBsb3JlLyBvciAvZGlzY292ZXJ5LylcbiAgICAgIGNvbnN0IG5vdGVJZE1hdGNoID0gY3VycmVudFVybC5tYXRjaCgvXFwvZXhwbG9yZVxcLyhbYS1mMC05XSspL2kpIHx8XG4gICAgICAgIGN1cnJlbnRVcmwubWF0Y2goL1xcL2Rpc2NvdmVyeVxcLyhbYS1mMC05XSspL2kpO1xuXG4gICAgICBpZiAobm90ZUlkTWF0Y2ggJiYgbm90ZUlkTWF0Y2hbMV0pIHtcbiAgICAgICAgY29uc3Qgbm90ZUlkID0gbm90ZUlkTWF0Y2hbMV07XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgRXh0cmFjdGVkIG5vdGUgSUQgZnJvbSBVUkw6ICR7bm90ZUlkfWApO1xuICAgICAgICByZXR1cm4gbm90ZUlkO1xuICAgICAgfVxuXG4gICAgICAvLyBNZXRob2QgMjogVHJ5IHRvIGZpbmQgbm90ZSBJRCBpbiBwYWdlIGNvbnRlbnQgb3IgZGF0YSBhdHRyaWJ1dGVzXG4gICAgICBjb25zdCBub3RlSWRGcm9tUGFnZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgICAvLyBMb29rIGZvciBkYXRhIGF0dHJpYnV0ZXMgdGhhdCBtaWdodCBjb250YWluIG5vdGUgSURcbiAgICAgICAgY29uc3QgZWxlbWVudHNXaXRoRGF0YSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLW5vdGUtaWRdLCBbZGF0YS1pZF0sIFtkYXRhLWltcHJlc3Npb25dJyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHNXaXRoRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBlbGVtZW50c1dpdGhEYXRhW2ldO1xuICAgICAgICAgIGNvbnN0IG5vdGVJZCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLW5vdGUtaWQnKSB8fFxuICAgICAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSB8fFxuICAgICAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaW1wcmVzc2lvbicpO1xuICAgICAgICAgIGlmIChub3RlSWQgJiYgbm90ZUlkLmxlbmd0aCA+IDEwKSB7IC8vIE5vdGUgSURzIGFyZSB0eXBpY2FsbHkgbG9uZ1xuICAgICAgICAgICAgcmV0dXJuIG5vdGVJZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMb29rIGZvciBsaW5rcyB0byBub3RlIHBhZ2VzXG4gICAgICAgIGNvbnN0IG5vdGVMaW5rcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2FbaHJlZio9XCIvZXhwbG9yZS9cIl0sIGFbaHJlZio9XCIvZGlzY292ZXJ5L1wiXScpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vdGVMaW5rcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGxpbmsgPSBub3RlTGlua3NbaV07XG4gICAgICAgICAgY29uc3QgaHJlZiA9IGxpbmsuZ2V0QXR0cmlidXRlKCdocmVmJyk7XG4gICAgICAgICAgaWYgKGhyZWYpIHtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gaHJlZi5tYXRjaCgvXFwvZXhwbG9yZVxcLyhbYS1mMC05XSspL2kpIHx8XG4gICAgICAgICAgICAgIGhyZWYubWF0Y2goL1xcL2Rpc2NvdmVyeVxcLyhbYS1mMC05XSspL2kpO1xuICAgICAgICAgICAgaWYgKG1hdGNoICYmIG1hdGNoWzFdKSB7XG4gICAgICAgICAgICAgIHJldHVybiBtYXRjaFsxXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMb29rIGZvciBhbnkgdGV4dCB0aGF0IGxvb2tzIGxpa2UgYSBub3RlIElEIChsb25nIGhleCBzdHJpbmcpXG4gICAgICAgIGNvbnN0IHRleHRDb250ZW50ID0gZG9jdW1lbnQuYm9keS50ZXh0Q29udGVudCB8fCAnJztcbiAgICAgICAgY29uc3Qgbm90ZUlkUGF0dGVybiA9IC9bYS1mMC05XXsyMCx9L2dpO1xuICAgICAgICBjb25zdCBtYXRjaGVzID0gdGV4dENvbnRlbnQubWF0Y2gobm90ZUlkUGF0dGVybik7XG4gICAgICAgIGlmIChtYXRjaGVzICYmIG1hdGNoZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIC8vIFJldHVybiB0aGUgZmlyc3QgbG9uZyBoZXggc3RyaW5nIGZvdW5kXG4gICAgICAgICAgcmV0dXJuIG1hdGNoZXNbMF07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAobm90ZUlkRnJvbVBhZ2UpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBFeHRyYWN0ZWQgbm90ZSBJRCBmcm9tIHBhZ2UgY29udGVudDogJHtub3RlSWRGcm9tUGFnZX1gKTtcbiAgICAgICAgcmV0dXJuIG5vdGVJZEZyb21QYWdlO1xuICAgICAgfVxuXG4gICAgICAvLyBNZXRob2QgMzogVHJ5IHRvIGdldCB0aGUgbGF0ZXN0IG5vdGUgSUQgdXNpbmcgTm90ZVNlcnZpY2UgKGZhbGxiYWNrKVxuICAgICAgbG9nZ2VyLmRlYnVnKCdDb3VsZCBub3QgZXh0cmFjdCBub3RlIElEIGZyb20gcGFnZSwgdHJ5aW5nIGZhbGxiYWNrIG1ldGhvZCcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gV2FpdCBhIGJpdCBmb3IgdGhlIG5vdGUgdG8gYmUgcHJvY2Vzc2VkXG4gICAgICAgIGF3YWl0IHNsZWVwKDUwMDApO1xuXG4gICAgICAgIC8vIFVzZSBOb3RlU2VydmljZSB0byBnZXQgdGhlIGxhdGVzdCBub3RlIElEXG4gICAgICAgIGNvbnN0IHsgTm90ZVNlcnZpY2UgfSA9IGF3YWl0IGltcG9ydCgnLi4vbm90ZXMvbm90ZS5zZXJ2aWNlJyk7XG4gICAgICAgIGNvbnN0IG5vdGVTZXJ2aWNlID0gbmV3IE5vdGVTZXJ2aWNlKHRoaXMuZ2V0Q29uZmlnKCkpO1xuICAgICAgICBjb25zdCB1c2VyTm90ZXMgPSBhd2FpdCBub3RlU2VydmljZS5nZXRVc2VyTm90ZXMoMSk7IC8vIEdldCBvbmx5IHRoZSBsYXRlc3Qgbm90ZVxuXG4gICAgICAgIGlmICh1c2VyTm90ZXMuc3VjY2VzcyAmJiB1c2VyTm90ZXMuZGF0YSAmJiB1c2VyTm90ZXMuZGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgbGF0ZXN0Tm90ZUlkID0gdXNlck5vdGVzLmRhdGFbMF0uaWQ7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKGBFeHRyYWN0ZWQgbm90ZSBJRCBmcm9tIE5vdGVTZXJ2aWNlOiAke2xhdGVzdE5vdGVJZH1gKTtcbiAgICAgICAgICByZXR1cm4gbGF0ZXN0Tm90ZUlkO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihgRmFsbGJhY2sgbm90ZSBJRCBleHRyYWN0aW9uIGZhaWxlZDogJHtlcnJvcn1gKTtcbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLmRlYnVnKCdDb3VsZCBub3QgZXh0cmFjdCBub3RlIElEIGZyb20gYW55IG1ldGhvZCcpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gZXh0cmFjdCBub3RlIElEOiAke2Vycm9yfWApO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG59IiwiaW1wb3J0IHsgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkLCBnZXRUaXRsZVdpZHRoIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3RpdGxlLXZhbGlkYXRvcic7XG5pbXBvcnQgeyBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IFB1Ymxpc2hSZXN1bHQgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgUHVibGlzaEVycm9yLCBJbnZhbGlkSW1hZ2VFcnJvciB9IGZyb20gJy4uLy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2xvZ2dlcic7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBleGlzdHNTeW5jLCBzdGF0U3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IFB1Ymxpc2hCYXNlU2VydmljZSB9IGZyb20gJy4vcHVibGlzaC1iYXNlLnNlcnZpY2UnO1xuXG5leHBvcnQgY2xhc3MgSW1hZ2VQdWJsaXNoU2VydmljZSBleHRlbmRzIFB1Ymxpc2hCYXNlU2VydmljZSB7XG4gIGFzeW5jIHB1Ymxpc2hOb3RlKFxuICAgIHRpdGxlOiBzdHJpbmcsXG4gICAgY29udGVudDogc3RyaW5nLFxuICAgIGltYWdlUGF0aHM6IHN0cmluZ1tdLFxuICAgIHRhZ3M6IHN0cmluZyA9ICcnLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8UHVibGlzaFJlc3VsdD4ge1xuICAgIC8vIFZhbGlkYXRlIGlucHV0c1xuICAgIGlmICghdGl0bGU/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignTm90ZSB0aXRsZSBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSB0aXRsZSB3aWR0aCAoQ0pLIGNoYXJhY3RlcnMgY291bnQgYXMgMiB1bml0cywgQVNDSUkgYXMgMSlcbiAgICBhc3NlcnRUaXRsZVdpZHRoVmFsaWQodGl0bGUpO1xuICAgIGxvZ2dlci5kZWJ1ZyhgVGl0bGUgd2lkdGggdmFsaWRhdGlvbiBwYXNzZWQ6IFwiJHt0aXRsZX1cIiAoJHtnZXRUaXRsZVdpZHRoKHRpdGxlKX0gdW5pdHMpYCk7XG5cbiAgICBpZiAoIWNvbnRlbnQ/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignTm90ZSBjb250ZW50IGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cblxuICAgIGlmICghaW1hZ2VQYXRocyB8fCBpbWFnZVBhdGhzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignQXQgbGVhc3Qgb25lIGltYWdlIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgLy8gUHJvY2VzcyBpbWFnZSBwYXRocyAtIGRvd25sb2FkIFVSTHMgYW5kIHZhbGlkYXRlIGxvY2FsIHBhdGhzXG4gICAgY29uc3QgcmVzb2x2ZWRQYXRocyA9IGF3YWl0IHRoaXMudmFsaWRhdGVBbmRSZXNvbHZlSW1hZ2VQYXRocyhpbWFnZVBhdGhzKTtcblxuICAgIC8vIFdhaXQgZm9yIHVwbG9hZCBjb250YWluZXIgc2VsZWN0b3JcbiAgICBjb25zdCB1cGxvYWRTZWxlY3RvciA9ICdkaXYudXBsb2FkLWNvbnRlbnQnO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZShmYWxzZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkubmF2aWdhdGVXaXRoUmV0cnkoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICB0aGlzLmdldENvbmZpZygpLnhocy5jcmVhdG9yUHVibGlzaFVybFxuICAgICAgICApO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIHBhZ2UgdG8gbG9hZFxuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcblxuICAgICAgICAvLyBGaXJzdCwgdHJ5IHRvIHN3aXRjaCB0byB0aGUgaW1hZ2UvdGV4dCB1cGxvYWQgdGFiXG4gICAgICAgIGF3YWl0IHRoaXMuY2xpY2tVcGxvYWRUYWIocGFnZSk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgdGFiIHN3aXRjaCB0byBjb21wbGV0ZVxuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcblxuICAgICAgICBsZXQgaGFzVXBsb2FkQ29udGFpbmVyID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLnRyeVdhaXRGb3JTZWxlY3RvcihcbiAgICAgICAgICBwYWdlLFxuICAgICAgICAgIHVwbG9hZFNlbGVjdG9yLFxuICAgICAgICAgIDMwMDAwXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKCFoYXNVcGxvYWRDb250YWluZXIpIHtcbiAgICAgICAgICAvLyBUcnkgYWx0ZXJuYXRpdmUgc2VsZWN0b3JzIGZvciB1cGxvYWQgY29udGFpbmVyXG4gICAgICAgICAgY29uc3QgYWx0ZXJuYXRpdmVTZWxlY3RvcnMgPSBbXG4gICAgICAgICAgICAnZGl2LnVwbG9hZC1jb250ZW50JyxcbiAgICAgICAgICAgICcudXBsb2FkLWNvbnRlbnQnLFxuICAgICAgICAgICAgJ2RpdltjbGFzcyo9XCJ1cGxvYWRcIl0nLFxuICAgICAgICAgICAgJ2RpdltjbGFzcyo9XCJpbWFnZVwiXScsXG4gICAgICAgICAgICAnaW5wdXRbdHlwZT1cImZpbGVcIl0nLFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIGFsdGVybmF0aXZlU2VsZWN0b3JzKSB7XG4gICAgICAgICAgICBoYXNVcGxvYWRDb250YWluZXIgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkudHJ5V2FpdEZvclNlbGVjdG9yKFxuICAgICAgICAgICAgICBwYWdlLFxuICAgICAgICAgICAgICBzZWxlY3RvcixcbiAgICAgICAgICAgICAgMTAwMDBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoaGFzVXBsb2FkQ29udGFpbmVyKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaGFzVXBsb2FkQ29udGFpbmVyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignQ291bGQgbm90IGZpbmQgdXBsb2FkIGNvbnRhaW5lciBvbiBwdWJsaXNoIHBhZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVwbG9hZCBpbWFnZXNcbiAgICAgICAgYXdhaXQgdGhpcy51cGxvYWRJbWFnZXMocGFnZSwgcmVzb2x2ZWRQYXRocyk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgaW1hZ2VzIHRvIGJlIHByb2Nlc3NlZCAobGFyZ2UgZmlsZXMgbmVlZCBtb3JlIHRpbWUgb24gWEhTKVxuICAgICAgICBsb2dnZXIuZGVidWcoJ1dhaXRpbmcgMTAgc2Vjb25kcyBmb3IgaW1hZ2VzIHRvIGJlIHVwbG9hZGVkIGFuZCBwcm9jZXNzZWQuLi4nKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMDApO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIHBhZ2UgdG8gdHJhbnNpdGlvbiB0byBlZGl0IG1vZGUgKGNoZWNrIGZvciB0aXRsZSBvciBjb250ZW50IGlucHV0KVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclNlbGVjdG9yKFxuICAgICAgICAgICAgJ2lucHV0W3BsYWNlaG9sZGVyKj1cIuagh+mimFwiXSwgZGl2W2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0sIC50aXB0YXAuUHJvc2VNaXJyb3InLFxuICAgICAgICAgICAgeyB0aW1lb3V0OiAxNTAwMCB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAvLyBDb250aW51ZSB3aXRob3V0IHdhaXRpbmdcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdhaXQgYSBiaXQgZm9yIHRoZSBwYWdlIHRvIHNldHRsZSBhZnRlciBpbWFnZSB1cGxvYWRcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG5cbiAgICAgICAgLy8gRmlsbCBpbiB0aXRsZVxuICAgICAgICBhd2FpdCB0aGlzLmZpbGxUaXRsZShwYWdlLCB0aXRsZSk7XG5cbiAgICAgICAgLy8gV2FpdCBhIGJpdCBtb3JlIGZvciBjb250ZW50IGFyZWEgdG8gYXBwZWFyXG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAgIC8vIEZpbGwgaW4gY29udGVudFxuICAgICAgICBhd2FpdCB0aGlzLmZpbGxDb250ZW50KHBhZ2UsIGNvbnRlbnQpO1xuXG4gICAgICAgIC8vIEFkZCB0YWdzIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0YWdzKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5hZGRUYWdzKHBhZ2UsIHRhZ3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3VibWl0IHRoZSBub3RlXG4gICAgICAgIGF3YWl0IHRoaXMuc3VibWl0UG9zdChwYWdlKTtcblxuICAgICAgICAvLyBXYWl0IGZvciBjb21wbGV0aW9uIGFuZCBjaGVjayByZXN1bHRcbiAgICAgICAgY29uc3Qgbm90ZUlkID0gYXdhaXQgdGhpcy53YWl0Rm9yUHVibGlzaENvbXBsZXRpb24ocGFnZSk7XG5cbiAgICAgICAgLy8gU2F2ZSBjb29raWVzXG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5zYXZlQ29va2llc0Zyb21QYWdlKHBhZ2UpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBtZXNzYWdlOiAnTm90ZSBwdWJsaXNoZWQgc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICBjb250ZW50LFxuICAgICAgICAgIGltYWdlQ291bnQ6IHJlc29sdmVkUGF0aHMubGVuZ3RoLFxuICAgICAgICAgIHRhZ3MsXG4gICAgICAgICAgdXJsOiB0aGlzLmdldENvbmZpZygpLnhocy5jcmVhdG9yUHVibGlzaFVybCxcbiAgICAgICAgICBub3RlSWQ6IG5vdGVJZCB8fCB1bmRlZmluZWQsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgUHVibGlzaCBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzIGltYWdlIHBhdGhzIC0gZG93bmxvYWQgVVJMcyBhbmQgdmFsaWRhdGUgbG9jYWwgcGF0aHNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgdmFsaWRhdGVBbmRSZXNvbHZlSW1hZ2VQYXRocyhpbWFnZVBhdGhzOiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAvLyBVc2UgSW1hZ2VEb3dubG9hZGVyIHRvIHByb2Nlc3MgcGF0aHMgKGRvd25sb2FkcyBVUkxzLCB2YWxpZGF0ZXMgbG9jYWwgcGF0aHMpXG4gICAgY29uc3QgcmVzb2x2ZWRQYXRocyA9IGF3YWl0IHRoaXMuaW1hZ2VEb3dubG9hZGVyLnByb2Nlc3NJbWFnZVBhdGhzKGltYWdlUGF0aHMpO1xuXG4gICAgLy8gVmFsaWRhdGUgcmVzb2x2ZWQgcGF0aHNcbiAgICBmb3IgKGNvbnN0IHJlc29sdmVkUGF0aCBvZiByZXNvbHZlZFBhdGhzKSB7XG4gICAgICAvLyBGb3IgbG9jYWwgcGF0aHMgdGhhdCBhcmVuJ3QgYWJzb2x1dGUsIHJlc29sdmUgdGhlbVxuICAgICAgY29uc3QgZnVsbFBhdGggPVxuICAgICAgICByZXNvbHZlZFBhdGguc3RhcnRzV2l0aCgnLycpIHx8IHJlc29sdmVkUGF0aC5tYXRjaCgvXlthLXpBLVpdOi8pXG4gICAgICAgICAgPyByZXNvbHZlZFBhdGhcbiAgICAgICAgICA6IGpvaW4ocHJvY2Vzcy5jd2QoKSwgcmVzb2x2ZWRQYXRoKTtcblxuICAgICAgaWYgKCFleGlzdHNTeW5jKGZ1bGxQYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoYEltYWdlIGZpbGUgbm90IGZvdW5kOiAke3Jlc29sdmVkUGF0aH1gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhdHMgPSBzdGF0U3luYyhmdWxsUGF0aCk7XG4gICAgICBpZiAoIXN0YXRzLmlzRmlsZSgpKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihgUGF0aCBpcyBub3QgYSBmaWxlOiAke3Jlc29sdmVkUGF0aH1gKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgZmlsZSBleHRlbnNpb25cbiAgICAgIGNvbnN0IGV4dCA9IHJlc29sdmVkUGF0aC50b0xvd2VyQ2FzZSgpLnNwbGl0KCcuJykucG9wKCk7XG4gICAgICBjb25zdCBhbGxvd2VkRXh0ZW5zaW9ucyA9IFsnanBnJywgJ2pwZWcnLCAncG5nJywgJ2dpZicsICd3ZWJwJywgJ2JtcCddO1xuICAgICAgaWYgKCFleHQgfHwgIWFsbG93ZWRFeHRlbnNpb25zLmluY2x1ZGVzKGV4dCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKFxuICAgICAgICAgIGBVbnN1cHBvcnRlZCBpbWFnZSBmb3JtYXQ6ICR7cmVzb2x2ZWRQYXRofS4gU3VwcG9ydGVkOiAke2FsbG93ZWRFeHRlbnNpb25zLmpvaW4oJywgJyl9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyZXNvbHZlZFBhdGhzLmxlbmd0aCA+IDE4KSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdNYXhpbXVtIDE4IGltYWdlcyBhbGxvd2VkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc29sdmVkUGF0aHM7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNsaWNrVXBsb2FkVGFiKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdBdHRlbXB0aW5nIHRvIHN3aXRjaCB0byBcIuS4iuS8oOWbvuaWh1wiIHRhYicpO1xuXG4gICAgICAvLyBTdHJhdGVneSAxOiBOYXZpZ2F0ZSBkaXJlY3RseSB0byBpbWFnZSBwdWJsaXNoIFVSTFxuICAgICAgY29uc3QgaW1hZ2VQdWJsaXNoVXJsID0gJ2h0dHBzOi8vY3JlYXRvci54aWFvaG9uZ3NodS5jb20vcHVibGlzaC9wdWJsaXNoP3NvdXJjZT1vZmZpY2lhbCZmcm9tPW1lbnUmdGFyZ2V0PWltYWdlJztcbiAgICAgIGF3YWl0IHBhZ2UuZ290byhpbWFnZVB1Ymxpc2hVcmwsIHsgd2FpdFVudGlsOiAnbmV0d29ya2lkbGUyJywgdGltZW91dDogMzAwMDAgfSk7XG4gICAgICBsb2dnZXIuZGVidWcoYE5hdmlnYXRlZCBkaXJlY3RseSB0byBpbWFnZSBwdWJsaXNoIFVSTDogJHtpbWFnZVB1Ymxpc2hVcmx9YCk7XG4gICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcblxuICAgICAgLy8gVmVyaWZ5IHdlJ3JlIG9uIHRoZSBpbWFnZSB0YWIgYnkgY2hlY2tpbmcgcGFnZSBjb250ZW50XG4gICAgICBjb25zdCBwYWdlU3RhdGUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHtcbiAgICAgICAgY29uc3QgYm9keVRleHQgPSBkb2N1bWVudC5ib2R5Py50ZXh0Q29udGVudCB8fCAnJztcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBoYXNJbWFnZVVwbG9hZDogYm9keVRleHQuaW5jbHVkZXMoJ+S4iuS8oOWbvuaWhycpIHx8IGJvZHlUZXh0LmluY2x1ZGVzKCfmi5bmi73lm77niYcnKSxcbiAgICAgICAgICBoYXNWaWRlb1VwbG9hZDogYm9keVRleHQuaW5jbHVkZXMoJ+S4iuS8oOinhumikScpIHx8IGJvZHlUZXh0LmluY2x1ZGVzKCfmi5bmi73op4bpopEnKSxcbiAgICAgICAgICB1cmw6IHdpbmRvdy5sb2NhdGlvbi5ocmVmLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICBsb2dnZXIuZGVidWcoYFBhZ2Ugc3RhdGUgYWZ0ZXIgbmF2aWdhdGlvbjogJHtKU09OLnN0cmluZ2lmeShwYWdlU3RhdGUpfWApO1xuXG4gICAgICBpZiAoIXBhZ2VTdGF0ZS5oYXNJbWFnZVVwbG9hZCAmJiBwYWdlU3RhdGUuaGFzVmlkZW9VcGxvYWQpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1N0aWxsIG9uIHZpZGVvIHVwbG9hZCBwYWdlIGFmdGVyIG5hdmlnYXRpb24uIFRyeWluZyB0YWIgY2xpY2suLi4nKTtcblxuICAgICAgICAvLyBTdHJhdGVneSAyOiBDbGljayB0aGUgaW1hZ2UgdGFiIGV4cGxpY2l0bHlcbiAgICAgICAgY29uc3QgdGFicyA9IGF3YWl0IHBhZ2UuJCQoJ2RpdltjbGFzcyo9XCJ0YWJcIl0sIC5jcmVhdG9yLXRhYiwgW3JvbGU9XCJ0YWJcIl0nKTtcbiAgICAgICAgZm9yIChjb25zdCB0YWIgb2YgdGFicykge1xuICAgICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCB0YWIuZXZhbHVhdGUoZWwgPT4gZWwudGV4dENvbnRlbnQ/LnRyaW0oKSk7XG4gICAgICAgICAgaWYgKHRleHQgJiYgKHRleHQuaW5jbHVkZXMoJ+S4iuS8oOWbvuaWhycpIHx8IHRleHQuaW5jbHVkZXMoJ+WbvuaWhycpKSkge1xuICAgICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgdGFiLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKS5jYXRjaCgoKSA9PiBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoIWlzVmlzaWJsZSkgY29udGludWU7XG5cbiAgICAgICAgICAgIC8vIEZ1bGwgZXZlbnQgY2hhaW4gZm9yIFJlYWN0XG4gICAgICAgICAgICBhd2FpdCB0YWIuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGh0bWxFbCA9IGVsIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgICAgICBjb25zdCBldmVudHMgPSBbJ21vdXNlZW50ZXInLCAnbW91c2VvdmVyJywgJ21vdXNlZG93bicsICdtb3VzZXVwJywgJ2NsaWNrJ107XG4gICAgICAgICAgICAgIGV2ZW50cy5mb3JFYWNoKGV2ID0+IHtcbiAgICAgICAgICAgICAgICBodG1sRWwuZGlzcGF0Y2hFdmVudChuZXcgTW91c2VFdmVudChldiwgeyBidWJibGVzOiB0cnVlLCBjYW5jZWxhYmxlOiB0cnVlIH0pKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGF3YWl0IHNsZWVwKDUwMCk7XG5cbiAgICAgICAgICAgIGF3YWl0IHRhYi5jbGljaygpO1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdDbGlja2VkIGltYWdlIHRhYiB2aWEgUHVwcGV0ZWVyJyk7XG4gICAgICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBzd2l0Y2ggdG8gaW1hZ2UgdGFiOiAke2Vycm9yfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBsb2FkSW1hZ2VzKHBhZ2U6IFBhZ2UsIGltYWdlUGF0aHM6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnVXBsb2FkaW5nIGltYWdlcyB1c2luZyBkaXJlY3QgaW5wdXQgZWxlbWVudCB0YXJnZXRpbmcnKTtcblxuICAgICAgY29uc3QgZmlsZUlucHV0ID0gYXdhaXQgcGFnZS4kKCdpbnB1dFt0eXBlPVwiZmlsZVwiXScpO1xuICAgICAgaWYgKCFmaWxlSW5wdXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignQ291bGQgbm90IGZpbmQgZmlsZSB1cGxvYWQgaW5wdXQgb24gcGFnZScpO1xuICAgICAgfVxuXG4gICAgICAvLyBFbnN1cmUgdGhlIGlucHV0IGFjY2VwdHMgbXVsdGlwbGUgZmlsZXMgYW5kIGFueSB0eXBlIHRvIGF2b2lkIGZyb250ZW5kIGJsb2Nrc1xuICAgICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWw6IEVsZW1lbnQgfCBudWxsKSA9PiB7XG4gICAgICAgIGlmIChlbCkge1xuICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnbXVsdGlwbGUnLCAnbXVsdGlwbGUnKTtcbiAgICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2FjY2VwdCcpO1xuICAgICAgICB9XG4gICAgICB9LCBmaWxlSW5wdXQpO1xuXG4gICAgICBsb2dnZXIuZGVidWcoYFN1Ym1pdHRpbmcgJHtpbWFnZVBhdGhzLmxlbmd0aH0gaW1hZ2UgcGF0aHMgdG8gZmlsZSBpbnB1dCBlbGVtZW50YCk7XG4gICAgICBhd2FpdCBmaWxlSW5wdXQudXBsb2FkRmlsZSguLi5pbWFnZVBhdGhzKTtcblxuICAgICAgLy8gRGlzcGF0Y2ggYSBjaGFuZ2UgZXZlbnQgbWFudWFsbHkgaW4gY2FzZSB0aGUgZnJhbWV3b3JrIG1pc3NlZCBpdFxuICAgICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWw6IEVsZW1lbnQgfCBudWxsKSA9PiB7XG4gICAgICAgIGlmIChlbCkge1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdjaGFuZ2UnLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgICB9XG4gICAgICB9LCBmaWxlSW5wdXQpO1xuXG4gICAgICBhd2FpdCBzbGVlcCg4MDAwKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgRmFpbGVkIHRvIHVwbG9hZCBpbWFnZXM6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbn1cbiIsImltcG9ydCB7IFBhZ2UgfSBmcm9tICdwdXBwZXRlZXInO1xuaW1wb3J0IHsgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkLCBnZXRUaXRsZVdpZHRoIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3RpdGxlLXZhbGlkYXRvcic7XG5pbXBvcnQgeyBTRUxFQ1RPUlMsIFRFWFRfUEFUVEVSTlMsIFZJREVPX1RJTUVPVVRTIH0gZnJvbSAnLi9wdWJsaXNoLWJhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBQdWJsaXNoUmVzdWx0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IFB1Ymxpc2hFcnJvciB9IGZyb20gJy4uLy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2xvZ2dlcic7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBleGlzdHNTeW5jLCBzdGF0U3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IFB1Ymxpc2hCYXNlU2VydmljZSB9IGZyb20gJy4vcHVibGlzaC1iYXNlLnNlcnZpY2UnO1xuXG5leHBvcnQgY2xhc3MgVmlkZW9QdWJsaXNoU2VydmljZSBleHRlbmRzIFB1Ymxpc2hCYXNlU2VydmljZSB7XG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvclZpZGVvUHVibGlzaENvbXBsZXRpb24ocGFnZTogUGFnZSk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGxvZ2dlci5kZWJ1ZygnV2FpdGluZyBmb3IgdmlkZW8gcHVibGlzaCBjb21wbGV0aW9uLi4uJyk7XG5cbiAgICBsZXQgaXNQcm9jZXNzaW5nID0gZmFsc2U7XG5cbiAgICBhd2FpdCB0aGlzLndhaXRGb3JDb25kaXRpb24oXG4gICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIENoZWNrIGZvciBzdWNjZXNzIGluZGljYXRvcnNcbiAgICAgICAgY29uc3Qgc3VjY2Vzc1Jlc3VsdCA9IGF3YWl0IHRoaXMuY2hlY2tFbGVtZW50Rm9yUGF0dGVybnMoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICBTRUxFQ1RPUlMuU1VDQ0VTU19JTkRJQ0FUT1JTLFxuICAgICAgICAgIFRFWFRfUEFUVEVSTlMuU1VDQ0VTU1xuICAgICAgICApO1xuXG4gICAgICAgIGlmIChzdWNjZXNzUmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKGBGb3VuZCBzdWNjZXNzIGluZGljYXRvcjogJHtzdWNjZXNzUmVzdWx0LnRleHR9YCk7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoVklERU9fVElNRU9VVFMuQ09NUExFVElPTl9DSEVDSyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBmb3IgZXJyb3IgaW5kaWNhdG9yc1xuICAgICAgICBjb25zdCBlcnJvclJlc3VsdCA9IGF3YWl0IHRoaXMuY2hlY2tFbGVtZW50Rm9yUGF0dGVybnMoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICBTRUxFQ1RPUlMuRVJST1JfSU5ESUNBVE9SUyxcbiAgICAgICAgICBURVhUX1BBVFRFUk5TLkVSUk9SXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGVycm9yUmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgVmlkZW8gcHVibGlzaCBmYWlsZWQgd2l0aCBlcnJvcjogJHtlcnJvclJlc3VsdC50ZXh0fWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UndmUgbGVmdCB0aGUgcHVibGlzaCBwYWdlIChsaWtlbHkgc3VjY2VzcylcbiAgICAgICAgY29uc3Qgc3RpbGxPblBhZ2UgPSBhd2FpdCB0aGlzLmZpbmRFbGVtZW50QnlTZWxlY3RvcnMoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICBTRUxFQ1RPUlMuUFVCTElTSF9QQUdFX0lORElDQVRPUlNcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFzdGlsbE9uUGFnZSkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnTGVmdCBwdWJsaXNoIHBhZ2UsIGFzc3VtaW5nIHZpZGVvIHB1Ymxpc2ggc3VjY2VzcycpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIHByb2Nlc3Npbmcgc3RhdHVzXG4gICAgICAgIGNvbnN0IHByb2Nlc3NpbmdSZXN1bHQgPSBhd2FpdCB0aGlzLmNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgU0VMRUNUT1JTLlBST0NFU1NJTkdfSU5ESUNBVE9SUyxcbiAgICAgICAgICBURVhUX1BBVFRFUk5TLlBST0NFU1NJTkdcbiAgICAgICAgKTtcblxuICAgICAgICBpc1Byb2Nlc3NpbmcgPSBwcm9jZXNzaW5nUmVzdWx0LmZvdW5kO1xuICAgICAgICBpZiAoaXNQcm9jZXNzaW5nKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKGBWaWRlbyBzdGlsbCBwcm9jZXNzaW5nOiAke3Byb2Nlc3NpbmdSZXN1bHQudGV4dH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGZvciB0b2FzdCBtZXNzYWdlc1xuICAgICAgICBjb25zdCB0b2FzdFJlc3VsdCA9IGF3YWl0IHRoaXMuY2hlY2tFbGVtZW50Rm9yUGF0dGVybnMoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICBTRUxFQ1RPUlMuVE9BU1RfU0VMRUNUT1JTLFxuICAgICAgICAgIFRFWFRfUEFUVEVSTlMuU1VDQ0VTU1xuICAgICAgICApO1xuXG4gICAgICAgIGlmICh0b2FzdFJlc3VsdC5mb3VuZCkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgc3VjY2VzcyB0b2FzdDogJHt0b2FzdFJlc3VsdC50ZXh0fWApO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZXJyb3JUb2FzdFJlc3VsdCA9IGF3YWl0IHRoaXMuY2hlY2tFbGVtZW50Rm9yUGF0dGVybnMoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICBTRUxFQ1RPUlMuVE9BU1RfU0VMRUNUT1JTLFxuICAgICAgICAgIFRFWFRfUEFUVEVSTlMuRVJST1JcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZXJyb3JUb2FzdFJlc3VsdC5mb3VuZCkge1xuICAgICAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYFZpZGVvIHB1Ymxpc2ggZmFpbGVkOiAke2Vycm9yVG9hc3RSZXN1bHQudGV4dH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0sXG4gICAgICBWSURFT19USU1FT1VUUy5DT01QTEVUSU9OX1RJTUVPVVQsXG4gICAgICBpc1Byb2Nlc3NpbmcgPyA1MDAwIDogVklERU9fVElNRU9VVFMuQ09NUExFVElPTl9DSEVDSyxcbiAgICAgICdWaWRlbyBwdWJsaXNoIGNvbXBsZXRpb24gdGltZW91dCAtIGNvdWxkIG5vdCBkZXRlcm1pbmUgcmVzdWx0IGFmdGVyIDUgbWludXRlcydcbiAgICApO1xuXG4gICAgLy8gRXh0cmFjdCBub3RlIElEIGFmdGVyIHN1Y2Nlc3NmdWwgY29tcGxldGlvblxuICAgIHJldHVybiBhd2FpdCB0aGlzLmV4dHJhY3ROb3RlSWRGcm9tUGFnZShwYWdlKTtcbiAgfVxuXG4gIGFzeW5jIHB1Ymxpc2hWaWRlbyhcbiAgICB0aXRsZTogc3RyaW5nLFxuICAgIGNvbnRlbnQ6IHN0cmluZyxcbiAgICB2aWRlb1BhdGg6IHN0cmluZyxcbiAgICB0YWdzOiBzdHJpbmcgPSAnJyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPFB1Ymxpc2hSZXN1bHQ+IHtcbiAgICAvLyBWYWxpZGF0ZSBpbnB1dHNcbiAgICB0aGlzLnZhbGlkYXRlVmlkZW9JbnB1dHModGl0bGUsIGNvbnRlbnQsIHZpZGVvUGF0aCk7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbmQgcmVzb2x2ZSB2aWRlbyBwYXRoXG4gICAgY29uc3QgcmVzb2x2ZWRWaWRlb1BhdGggPSB0aGlzLnZhbGlkYXRlQW5kUmVzb2x2ZVZpZGVvUGF0aCh2aWRlb1BhdGgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZShmYWxzZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBub3RlSWQgPSBhd2FpdCB0aGlzLmV4ZWN1dGVWaWRlb1B1Ymxpc2hXb3JrZmxvdyhwYWdlLCB0aXRsZSwgY29udGVudCwgcmVzb2x2ZWRWaWRlb1BhdGgsIHRhZ3MpO1xuXG4gICAgICAgIC8vIFNhdmUgY29va2llc1xuICAgICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuc2F2ZUNvb2tpZXNGcm9tUGFnZShwYWdlKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgbWVzc2FnZTogJ1ZpZGVvIHB1Ymxpc2hlZCBzdWNjZXNzZnVsbHknLFxuICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgIGNvbnRlbnQsXG4gICAgICAgICAgaW1hZ2VDb3VudDogMCwgLy8gVmlkZW9zIGRvbid0IGhhdmUgaW1hZ2UgY291bnRcbiAgICAgICAgICB0YWdzLFxuICAgICAgICAgIHVybDogdGhpcy5nZXRDb25maWcoKS54aHMuY3JlYXRvclZpZGVvUHVibGlzaFVybCxcbiAgICAgICAgICBub3RlSWQ6IG5vdGVJZCB8fCB1bmRlZmluZWQsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgVmlkZW8gcHVibGlzaCBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVWaWRlb0lucHV0cyh0aXRsZTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcsIHZpZGVvUGF0aDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0aXRsZT8udHJpbSgpKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdWaWRlbyB0aXRsZSBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSB0aXRsZSB3aWR0aCBmb3IgdmlkZW8gcG9zdHMgdG9vXG4gICAgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkKHRpdGxlKTtcbiAgICBsb2dnZXIuZGVidWcoYFZpZGVvIHRpdGxlIHdpZHRoIHZhbGlkYXRpb24gcGFzc2VkOiBcIiR7dGl0bGV9XCIgKCR7Z2V0VGl0bGVXaWR0aCh0aXRsZSl9IHVuaXRzKWApO1xuXG4gICAgaWYgKCFjb250ZW50Py50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ1ZpZGVvIGNvbnRlbnQgY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgfVxuXG4gICAgaWYgKCF2aWRlb1BhdGg/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignVmlkZW8gcGF0aCBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZXhlY3V0ZVZpZGVvUHVibGlzaFdvcmtmbG93KFxuICAgIHBhZ2U6IFBhZ2UsXG4gICAgdGl0bGU6IHN0cmluZyxcbiAgICBjb250ZW50OiBzdHJpbmcsXG4gICAgdmlkZW9QYXRoOiBzdHJpbmcsXG4gICAgdGFnczogc3RyaW5nXG4gICk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIC8vIE5hdmlnYXRlIHRvIHZpZGVvIHVwbG9hZCBwYWdlXG4gICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KFxuICAgICAgcGFnZSxcbiAgICAgIHRoaXMuZ2V0Q29uZmlnKCkueGhzLmNyZWF0b3JWaWRlb1B1Ymxpc2hVcmxcbiAgICApO1xuXG4gICAgLy8gV2FpdCBmb3IgcGFnZSB0byBsb2FkXG4gICAgYXdhaXQgc2xlZXAoVklERU9fVElNRU9VVFMuUEFHRV9MT0FEKTtcblxuICAgIC8vIFN3aXRjaCB0byB2aWRlbyB1cGxvYWQgdGFiIGlmIG5lZWRlZFxuICAgIGF3YWl0IHRoaXMuY2xpY2tWaWRlb1VwbG9hZFRhYihwYWdlKTtcblxuICAgIC8vIFdhaXQgZm9yIHRhYiBzd2l0Y2ggdG8gY29tcGxldGVcbiAgICBhd2FpdCBzbGVlcChWSURFT19USU1FT1VUUy5UQUJfU1dJVENIKTtcblxuICAgIC8vIFVwbG9hZCB2aWRlb1xuICAgIGF3YWl0IHRoaXMudXBsb2FkVmlkZW8ocGFnZSwgdmlkZW9QYXRoKTtcblxuICAgIC8vIFdhaXQgZm9yIHZpZGVvIHRvIGJlIHByb2Nlc3NlZCAodmlkZW9zIHRha2UgbG9uZ2VyIHRoYW4gaW1hZ2VzKVxuICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLlZJREVPX1BST0NFU1NJTkcpO1xuXG4gICAgLy8gRmlsbCBpbiB0aXRsZVxuICAgIGF3YWl0IHRoaXMuZmlsbFRpdGxlKHBhZ2UsIHRpdGxlKTtcblxuICAgIC8vIFdhaXQgYSBiaXQgZm9yIGNvbnRlbnQgYXJlYSB0byBhcHBlYXJcbiAgICBhd2FpdCBzbGVlcChWSURFT19USU1FT1VUUy5DT05URU5UX1dBSVQpO1xuXG4gICAgLy8gRmlsbCBpbiBjb250ZW50XG4gICAgYXdhaXQgdGhpcy5maWxsQ29udGVudChwYWdlLCBjb250ZW50KTtcblxuICAgIC8vIEFkZCB0YWdzIGlmIHByb3ZpZGVkXG4gICAgaWYgKHRhZ3MpIHtcbiAgICAgIGF3YWl0IHRoaXMuYWRkVGFncyhwYWdlLCB0YWdzKTtcbiAgICB9XG5cbiAgICAvLyBTdWJtaXQgdGhlIHZpZGVvXG4gICAgYXdhaXQgdGhpcy5zdWJtaXRQb3N0KHBhZ2UpO1xuXG4gICAgLy8gV2FpdCBmb3IgY29tcGxldGlvbiBhbmQgY2hlY2sgcmVzdWx0ICh2aWRlb3MgbmVlZCBsb25nZXIgdGltZW91dClcbiAgICByZXR1cm4gYXdhaXQgdGhpcy53YWl0Rm9yVmlkZW9QdWJsaXNoQ29tcGxldGlvbihwYWdlKTtcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVBbmRSZXNvbHZlVmlkZW9QYXRoKHZpZGVvUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCByZXNvbHZlZFBhdGggPVxuICAgICAgdmlkZW9QYXRoLnN0YXJ0c1dpdGgoJy8nKSB8fCB2aWRlb1BhdGgubWF0Y2goL15bYS16QS1aXTovKVxuICAgICAgICA/IHZpZGVvUGF0aFxuICAgICAgICA6IGpvaW4ocHJvY2Vzcy5jd2QoKSwgdmlkZW9QYXRoKTtcblxuICAgIGlmICghZXhpc3RzU3luYyhyZXNvbHZlZFBhdGgpKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBWaWRlbyBmaWxlIG5vdCBmb3VuZDogJHt2aWRlb1BhdGh9YCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhdHMgPSBzdGF0U3luYyhyZXNvbHZlZFBhdGgpO1xuICAgIGlmICghc3RhdHMuaXNGaWxlKCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYFBhdGggaXMgbm90IGEgZmlsZTogJHt2aWRlb1BhdGh9YCk7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZmlsZSBleHRlbnNpb25cbiAgICBjb25zdCBleHQgPSB2aWRlb1BhdGgudG9Mb3dlckNhc2UoKS5zcGxpdCgnLicpLnBvcCgpO1xuICAgIGNvbnN0IGFsbG93ZWRFeHRlbnNpb25zID0gWydtcDQnLCAnbW92JywgJ2F2aScsICdta3YnLCAnd2VibScsICdmbHYnLCAnd212J107XG4gICAgaWYgKCFleHQgfHwgIWFsbG93ZWRFeHRlbnNpb25zLmluY2x1ZGVzKGV4dCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoXG4gICAgICAgIGBVbnN1cHBvcnRlZCB2aWRlbyBmb3JtYXQ6ICR7dmlkZW9QYXRofS4gU3VwcG9ydGVkOiAke2FsbG93ZWRFeHRlbnNpb25zLmpvaW4oJywgJyl9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBmaWxlIHNpemUgKFhIUyB0eXBpY2FsbHkgaGFzIGxpbWl0cylcbiAgICBjb25zdCBtYXhTaXplSW5NQiA9IDUwMDsgLy8gNTAwTUIgbGltaXRcbiAgICBjb25zdCBmaWxlU2l6ZUluTUIgPSBzdGF0cy5zaXplIC8gKDEwMjQgKiAxMDI0KTtcbiAgICBpZiAoZmlsZVNpemVJbk1CID4gbWF4U2l6ZUluTUIpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoXG4gICAgICAgIGBWaWRlbyBmaWxlIHRvbyBsYXJnZTogJHtmaWxlU2l6ZUluTUIudG9GaXhlZCgyKX1NQi4gTWF4aW11bSBhbGxvd2VkOiAke21heFNpemVJbk1CfU1CYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzb2x2ZWRQYXRoO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjbGlja1ZpZGVvVXBsb2FkVGFiKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgLy8gVHJ5IG11bHRpcGxlIHNlbGVjdG9ycyBmb3IgdmlkZW8gdGFiXG4gICAgICBjb25zdCB2aWRlb1RhYlNlbGVjdG9ycyA9IFtcbiAgICAgICAgJ2Rpdi5jcmVhdG9yLXRhYicsXG4gICAgICAgICcuY3JlYXRvci10YWInLFxuICAgICAgICAnW3JvbGU9XCJ0YWJcIl0nLFxuICAgICAgICAnLnRhYicsXG4gICAgICAgICdkaXZbY2xhc3MqPVwidGFiXCJdJyxcbiAgICAgIF07XG5cbiAgICAgIGxldCB0YWJzOiBhbnlbXSA9IFtdO1xuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiB2aWRlb1RhYlNlbGVjdG9ycykge1xuICAgICAgICBjb25zdCBmb3VuZFRhYnMgPSBhd2FpdCBwYWdlLiQkKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGZvdW5kVGFicy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGFicyA9IGZvdW5kVGFicztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGFicy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ05vIHRhYnMgZm91bmQgZm9yIHZpZGVvIHVwbG9hZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIExvb2sgZm9yIHRoZSB2aWRlbyB1cGxvYWQgdGFiIHNwZWNpZmljYWxseVxuICAgICAgbGV0IHZpZGVvVGFiOiBhbnkgPSBudWxsO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YWJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHRhYiA9IHRhYnNbaV07XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgdGFiLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgICBpZiAoIWlzVmlzaWJsZSkgY29udGludWU7XG5cbiAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLnRleHRDb250ZW50LCB0YWIpO1xuXG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyB0aGUgdmlkZW8gdXBsb2FkIHRhYlxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRleHQgJiZcbiAgICAgICAgICAgICh0ZXh0LmluY2x1ZGVzKCfkuIrkvKDop4bpopEnKSB8fCB0ZXh0LmluY2x1ZGVzKCfop4bpopEnKSB8fCB0ZXh0LmluY2x1ZGVzKCd2aWRlbycpKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdmlkZW9UYWIgPSB0YWI7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgLy8gSWdub3JlIGluZGl2aWR1YWwgdGFiIGVycm9yc1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh2aWRlb1RhYikge1xuICAgICAgICBhd2FpdCB2aWRlb1RhYi5jbGljaygpO1xuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTsgLy8gV2FpdCBmb3IgdGFiIHN3aXRjaFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRmFsbGJhY2s6IGNsaWNrIHRoZSBmaXJzdCB0YWIgKHVzdWFsbHkgdmlkZW8gdXBsb2FkKVxuICAgICAgICBjb25zdCB2aXNpYmxlVGFiczogYW55W10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCB0YWIgb2YgdGFicykge1xuICAgICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IHRhYi5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG4gICAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgICAgdmlzaWJsZVRhYnMucHVzaCh0YWIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2aXNpYmxlVGFicy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgYXdhaXQgdmlzaWJsZVRhYnNbMF0uY2xpY2soKTsgLy8gVXN1YWxseSB0aGUgZmlyc3QgdGFiIGlzIHZpZGVvIHVwbG9hZFxuICAgICAgICAgIGF3YWl0IHNsZWVwKDIwMDApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gY2xpY2sgdmlkZW8gdXBsb2FkIHRhYjogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwbG9hZFZpZGVvKHBhZ2U6IFBhZ2UsIHZpZGVvUGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nZ2VyLmRlYnVnKGBVcGxvYWRpbmcgdmlkZW86ICR7dmlkZW9QYXRofWApO1xuXG4gICAgLy8gRmluZCBmaWxlIGlucHV0IGVsZW1lbnRcbiAgICBjb25zdCBmaWxlSW5wdXQgPSBhd2FpdCB0aGlzLmZpbmRFbGVtZW50QnlTZWxlY3RvcnMocGFnZSwgU0VMRUNUT1JTLkZJTEVfSU5QVVQpO1xuICAgIGlmICghZmlsZUlucHV0KSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdDb3VsZCBub3QgZmluZCBmaWxlIHVwbG9hZCBpbnB1dCBvbiB2aWRlbyB1cGxvYWQgcGFnZScpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAvLyBXYWl0IGZvciB0aGUgaW5wdXQgdG8gYmUgcmVhZHlcbiAgICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLlVQTE9BRF9SRUFEWSk7XG5cbiAgICAgIC8vIFVwbG9hZCB0aGUgdmlkZW8gZmlsZVxuICAgICAgYXdhaXQgZmlsZUlucHV0LnVwbG9hZEZpbGUodmlkZW9QYXRoKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnVmlkZW8gZmlsZSB1cGxvYWRlZCwgd2FpdGluZyBmb3IgcHJvY2Vzc2luZy4uLicpO1xuXG4gICAgICAvLyBXYWl0IGZvciB1cGxvYWQgdG8gc3RhcnQgYW5kIHNob3cgcHJvZ3Jlc3NcbiAgICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLlVQTE9BRF9TVEFSVCk7XG5cbiAgICAgIC8vIFdhaXQgZm9yIHZpZGVvIHByb2Nlc3NpbmcgdG8gY29tcGxldGUgKHRoaXMgY2FuIHRha2UgYSB3aGlsZSlcbiAgICAgIGF3YWl0IHRoaXMud2FpdEZvclZpZGVvUHJvY2Vzc2luZyhwYWdlKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgRmFpbGVkIHRvIHVwbG9hZCB2aWRlbyAke3ZpZGVvUGF0aH06ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yVmlkZW9Qcm9jZXNzaW5nKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2dnZXIuZGVidWcoJ1dhaXRpbmcgZm9yIHZpZGVvIHByb2Nlc3NpbmcgdG8gY29tcGxldGUuLi4nKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JDb25kaXRpb24oXG4gICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAvLyBDaGVjayBpZiBwcm9jZXNzaW5nIGlzIGNvbXBsZXRlXG4gICAgICAgICAgY29uc3QgY29tcGxldGVSZXN1bHQgPSBhd2FpdCB0aGlzLmNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgICAgICAgICAgcGFnZSxcbiAgICAgICAgICAgIFNFTEVDVE9SUy5DT01QTEVUSU9OX0lORElDQVRPUlMsXG4gICAgICAgICAgICBURVhUX1BBVFRFUk5TLlNVQ0NFU1NcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKGNvbXBsZXRlUmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYFZpZGVvIHByb2Nlc3NpbmcgY29tcGxldGU6ICR7Y29tcGxldGVSZXN1bHQudGV4dH1gKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIENoZWNrIGlmIHN0aWxsIHByb2Nlc3NpbmdcbiAgICAgICAgICBjb25zdCBwcm9jZXNzaW5nUmVzdWx0ID0gYXdhaXQgdGhpcy5jaGVja0VsZW1lbnRGb3JQYXR0ZXJucyhcbiAgICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgICBTRUxFQ1RPUlMuUFJPQ0VTU0lOR19JTkRJQ0FUT1JTLFxuICAgICAgICAgICAgVEVYVF9QQVRURVJOUy5QUk9DRVNTSU5HXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChwcm9jZXNzaW5nUmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYFZpZGVvIHByb2Nlc3Npbmc6ICR7cHJvY2Vzc2luZ1Jlc3VsdC50ZXh0fWApO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBTdGlsbCBwcm9jZXNzaW5nLCBjb250aW51ZSB3YWl0aW5nXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gSWYgbm90IHByb2Nlc3NpbmcgYW5kIG5vIGNvbXBsZXRpb24gaW5kaWNhdG9yLCBhc3N1bWUgaXQncyBkb25lXG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdObyBwcm9jZXNzaW5nIGluZGljYXRvcnMgZm91bmQsIGFzc3VtaW5nIHZpZGVvIHByb2Nlc3NpbmcgY29tcGxldGUnKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgVklERU9fVElNRU9VVFMuUFJPQ0VTU0lOR19USU1FT1VULFxuICAgICAgICBWSURFT19USU1FT1VUUy5QUk9DRVNTSU5HX0NIRUNLLFxuICAgICAgICAnVmlkZW8gcHJvY2Vzc2luZyB0aW1lb3V0J1xuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oJ1ZpZGVvIHByb2Nlc3NpbmcgdGltZW91dCwgY29udGludWluZyBhbnl3YXkuLi4nKTtcbiAgICB9XG4gIH1cblxufVxuIiwiaW1wb3J0IHsgQ29uZmlnLCBQdWJsaXNoUmVzdWx0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IEJhc2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Jhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBCcm93c2VyTWFuYWdlciB9IGZyb20gJy4uL2Jyb3dzZXIvYnJvd3Nlci5tYW5hZ2VyJztcbmltcG9ydCB7IEltYWdlUHVibGlzaFNlcnZpY2UgfSBmcm9tICcuL3B1Ymxpc2gtaW1hZ2Uuc2VydmljZSc7XG5pbXBvcnQgeyBWaWRlb1B1Ymxpc2hTZXJ2aWNlIH0gZnJvbSAnLi9wdWJsaXNoLXZpZGVvLnNlcnZpY2UnO1xuXG5leHBvcnQgY2xhc3MgUHVibGlzaFNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gIHByaXZhdGUgaW1hZ2VTZXJ2aWNlOiBJbWFnZVB1Ymxpc2hTZXJ2aWNlO1xuICBwcml2YXRlIHZpZGVvU2VydmljZTogVmlkZW9QdWJsaXNoU2VydmljZTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IENvbmZpZywgYnJvd3Nlck1hbmFnZXI/OiBCcm93c2VyTWFuYWdlcikge1xuICAgIHN1cGVyKGNvbmZpZywgYnJvd3Nlck1hbmFnZXIpO1xuICAgIHRoaXMuaW1hZ2VTZXJ2aWNlID0gbmV3IEltYWdlUHVibGlzaFNlcnZpY2UoY29uZmlnLCB0aGlzLmJyb3dzZXJNYW5hZ2VyKTtcbiAgICB0aGlzLnZpZGVvU2VydmljZSA9IG5ldyBWaWRlb1B1Ymxpc2hTZXJ2aWNlKGNvbmZpZywgdGhpcy5icm93c2VyTWFuYWdlcik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcHVibGlzaE5vdGUoXG4gICAgdGl0bGU6IHN0cmluZyxcbiAgICBjb250ZW50OiBzdHJpbmcsXG4gICAgaW1hZ2VQYXRoczogc3RyaW5nW10sXG4gICAgdGFnczogc3RyaW5nID0gJycsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxQdWJsaXNoUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VTZXJ2aWNlLnB1Ymxpc2hOb3RlKHRpdGxlLCBjb250ZW50LCBpbWFnZVBhdGhzLCB0YWdzLCBicm93c2VyUGF0aCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcHVibGlzaFZpZGVvKFxuICAgIHRpdGxlOiBzdHJpbmcsXG4gICAgY29udGVudDogc3RyaW5nLFxuICAgIHZpZGVvUGF0aDogc3RyaW5nLFxuICAgIHRhZ3M6IHN0cmluZyA9ICcnLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8UHVibGlzaFJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnZpZGVvU2VydmljZS5wdWJsaXNoVmlkZW8odGl0bGUsIGNvbnRlbnQsIHZpZGVvUGF0aCwgdGFncywgYnJvd3NlclBhdGgpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHB1Ymxpc2hDb250ZW50KFxuICAgIHR5cGU6ICdpbWFnZScgfCAndmlkZW8nLFxuICAgIHRpdGxlOiBzdHJpbmcsXG4gICAgY29udGVudDogc3RyaW5nLFxuICAgIG1lZGlhUGF0aHM6IHN0cmluZ1tdLFxuICAgIHRhZ3M6IHN0cmluZyA9ICcnLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8UHVibGlzaFJlc3VsdD4ge1xuICAgIGlmICh0eXBlID09PSAnaW1hZ2UnKSB7XG4gICAgICByZXR1cm4gdGhpcy5wdWJsaXNoTm90ZSh0aXRsZSwgY29udGVudCwgbWVkaWFQYXRocywgdGFncywgYnJvd3NlclBhdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5wdWJsaXNoVmlkZW8odGl0bGUsIGNvbnRlbnQsIG1lZGlhUGF0aHNbMF0sIHRhZ3MsIGJyb3dzZXJQYXRoKTtcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICogVG9vbCByZXF1ZXN0IGhhbmRsZXJzIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9hdXRoL2F1dGguc2VydmljZSc7XG5pbXBvcnQgeyBGZWVkU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvZmVlZHMvZmVlZC5zZXJ2aWNlJztcbmltcG9ydCB7IFB1Ymxpc2hTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9wdWJsaXNoaW5nL3B1Ymxpc2guc2VydmljZSc7XG5pbXBvcnQgeyBOb3RlU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvbm90ZXMvbm90ZS5zZXJ2aWNlJztcbmltcG9ydCB7IEJyb3dzZXJNYW5hZ2VyIH0gZnJvbSAnLi4vLi4vY29yZS9icm93c2VyL2Jyb3dzZXIubWFuYWdlcic7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IFhIU0Vycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQge1xuICB2YWxpZGF0ZVJlcXVpcmVkUGFyYW1zLFxuICBzYWZlRXJyb3JIYW5kbGVyLFxuICBjcmVhdGVNY3BUb29sUmVzcG9uc2UsXG4gIGNyZWF0ZU1jcEVycm9yUmVzcG9uc2UsXG59IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvbG9nZ2VyJztcbmltcG9ydCB7IGFzc2VydFRpdGxlV2lkdGhWYWxpZCB9IGZyb20gJy4uLy4uL3NoYXJlZC90aXRsZS12YWxpZGF0b3InO1xuXG4vKipcbiAqIFRvb2wgcmVxdWVzdCBhcmd1bWVudHMgaW50ZXJmYWNlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVG9vbFJlcXVlc3RBcmdzIHtcbiAgYnJvd3Nlcl9wYXRoPzogc3RyaW5nO1xuICBrZXl3b3JkPzogc3RyaW5nO1xuICBmZWVkX2lkPzogc3RyaW5nO1xuICB4c2VjX3Rva2VuPzogc3RyaW5nO1xuICBub3RlPzogc3RyaW5nO1xuICB0eXBlPzogc3RyaW5nO1xuICB0aXRsZT86IHN0cmluZztcbiAgY29udGVudD86IHN0cmluZztcbiAgbWVkaWFfcGF0aHM/OiBzdHJpbmdbXTtcbiAgdGFncz86IHN0cmluZztcbiAgbGltaXQ/OiBudW1iZXI7XG4gIGN1cnNvcj86IHN0cmluZztcbiAgbm90ZV9pZD86IHN0cmluZztcbiAgbGFzdF9wdWJsaXNoZWQ/OiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgVG9vbEhhbmRsZXJzIHtcbiAgcHJpdmF0ZSBhdXRoU2VydmljZTogQXV0aFNlcnZpY2U7XG4gIHByaXZhdGUgZmVlZFNlcnZpY2U6IEZlZWRTZXJ2aWNlO1xuICBwcml2YXRlIHB1Ymxpc2hTZXJ2aWNlOiBQdWJsaXNoU2VydmljZTtcbiAgcHJpdmF0ZSBub3RlU2VydmljZTogTm90ZVNlcnZpY2U7XG4gIHByaXZhdGUgYnJvd3Nlck1hbmFnZXI6IEJyb3dzZXJNYW5hZ2VyO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGNvbnN0IGNvbmZpZyA9IGdldENvbmZpZygpO1xuICAgIHRoaXMuYnJvd3Nlck1hbmFnZXIgPSBuZXcgQnJvd3Nlck1hbmFnZXIoY29uZmlnKTtcbiAgICB0aGlzLmF1dGhTZXJ2aWNlID0gbmV3IEF1dGhTZXJ2aWNlKGNvbmZpZywgdGhpcy5icm93c2VyTWFuYWdlcik7XG4gICAgdGhpcy5mZWVkU2VydmljZSA9IG5ldyBGZWVkU2VydmljZShjb25maWcsIHRoaXMuYnJvd3Nlck1hbmFnZXIpO1xuICAgIHRoaXMucHVibGlzaFNlcnZpY2UgPSBuZXcgUHVibGlzaFNlcnZpY2UoY29uZmlnLCB0aGlzLmJyb3dzZXJNYW5hZ2VyKTtcbiAgICB0aGlzLm5vdGVTZXJ2aWNlID0gbmV3IE5vdGVTZXJ2aWNlKGNvbmZpZywgdGhpcy5icm93c2VyTWFuYWdlcik7XG4gIH1cblxuICBhc3luYyBoYW5kbGVBdXRoTG9naW4oXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIC8vIFN0YXJ0IGxvZ2luIHByb2Nlc3MgaW4gYmFja2dyb3VuZCBhbmQgcmV0dXJuIGltbWVkaWF0ZWx5XG4gICAgLy8gVGhpcyBmb2xsb3dzIHRoZSBcImluc3RhbnQgcmVzcG9uc2VcIiBwYXR0ZXJuIGRlc2NyaWJlZCBpbiBSRUFETUVcbiAgICB0aGlzLmF1dGhTZXJ2aWNlLmxvZ2luKGJyb3dzZXJQYXRoKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgIHNhZmVFcnJvckhhbmRsZXIoZXJyb3IsICdCYWNrZ3JvdW5kIGxvZ2luIGVycm9yJywgbG9nZ2VyKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgICAgICAgJ0xvZ2luIHByb2Nlc3Mgc3RhcnRlZC4gQSBicm93c2VyIHdpbmRvdyB3aWxsIG9wZW4gZm9yIHlvdSB0byBjb21wbGV0ZSB0aGUgbG9naW4uJyxcbiAgICAgICAgICAgICAgc3RhdHVzOiAnbG9naW5fc3RhcnRlZCcsXG4gICAgICAgICAgICAgIGFjdGlvbjogJ2Jyb3dzZXJfb3BlbmVkJyxcbiAgICAgICAgICAgICAgaW5zdHJ1Y3Rpb25zOiBbXG4gICAgICAgICAgICAgICAgJzEuIENvbXBsZXRlIHRoZSBsb2dpbiBwcm9jZXNzIGluIHRoZSBvcGVuZWQgYnJvd3NlciB3aW5kb3cnLFxuICAgICAgICAgICAgICAgICcyLiBTY2FuIFFSIGNvZGUgb3IgZW50ZXIgeW91ciBjcmVkZW50aWFscycsXG4gICAgICAgICAgICAgICAgJzMuIExvZ2luIHdpbGwgYmUgYXV0b21hdGljYWxseSB2ZXJpZmllZCBhbmQgY29va2llcyBzYXZlZCcsXG4gICAgICAgICAgICAgICAgJzQuIFVzZSB4aHNfYXV0aF9zdGF0dXMgdG8gY2hlY2sgaWYgbG9naW4gY29tcGxldGVkJyxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgbm90ZTogJ1RoZSBsb2dpbiBwcm9jZXNzIHJ1bnMgaW4gdGhlIGJhY2tncm91bmQuIFlvdSBjYW4gY29udGludWUgdXNpbmcgb3RoZXIgdG9vbHMgd2hpbGUgbG9naW4gY29tcGxldGVzLicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIDJcbiAgICAgICAgICApLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlQXV0aExvZ291dCgpOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5hdXRoU2VydmljZS5sb2dvdXQoKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVBdXRoU3RhdHVzKFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmF1dGhTZXJ2aWNlLmNoZWNrU3RhdHVzKGJyb3dzZXJQYXRoKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVEaXNjb3ZlckZlZWRzKFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmZlZWRTZXJ2aWNlLmdldEZlZWRMaXN0KGJyb3dzZXJQYXRoKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVTZWFyY2hOb3RlKFxuICAgIGtleXdvcmQ/OiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIHZhbGlkYXRlUmVxdWlyZWRQYXJhbXMoeyBrZXl3b3JkIH0sIFsna2V5d29yZCddKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmZlZWRTZXJ2aWNlLnNlYXJjaEZlZWRzKGtleXdvcmQhLCBicm93c2VyUGF0aCk7XG4gICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlR2V0Tm90ZURldGFpbChcbiAgICBmZWVkSWQ/OiBzdHJpbmcsXG4gICAgeHNlY1Rva2VuPzogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICB2YWxpZGF0ZVJlcXVpcmVkUGFyYW1zKHsgZmVlZElkLCB4c2VjVG9rZW4gfSwgWydmZWVkSWQnLCAneHNlY1Rva2VuJ10pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZmVlZFNlcnZpY2UuZ2V0RmVlZERldGFpbChmZWVkSWQhLCB4c2VjVG9rZW4hLCBicm93c2VyUGF0aCk7XG4gICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlQ29tbWVudE9uTm90ZShcbiAgICBmZWVkSWQ/OiBzdHJpbmcsXG4gICAgeHNlY1Rva2VuPzogc3RyaW5nLFxuICAgIG5vdGU/OiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIHZhbGlkYXRlUmVxdWlyZWRQYXJhbXMoeyBmZWVkSWQsIHhzZWNUb2tlbiwgbm90ZSB9LCBbJ2ZlZWRJZCcsICd4c2VjVG9rZW4nLCAnbm90ZSddKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmZlZWRTZXJ2aWNlLmNvbW1lbnRPbkZlZWQoZmVlZElkISwgeHNlY1Rva2VuISwgbm90ZSEsIGJyb3dzZXJQYXRoKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVQdWJsaXNoQ29udGVudChcbiAgICB0eXBlPzogc3RyaW5nLFxuICAgIHRpdGxlPzogc3RyaW5nLFxuICAgIGNvbnRlbnQ/OiBzdHJpbmcsXG4gICAgbWVkaWFQYXRocz86IHN0cmluZ1tdLFxuICAgIHRhZ3M/OiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIHZhbGlkYXRlUmVxdWlyZWRQYXJhbXMoeyB0eXBlLCB0aXRsZSwgY29udGVudCwgbWVkaWFQYXRocyB9LCBbXG4gICAgICAndHlwZScsXG4gICAgICAndGl0bGUnLFxuICAgICAgJ2NvbnRlbnQnLFxuICAgICAgJ21lZGlhUGF0aHMnLFxuICAgIF0pO1xuXG4gICAgLy8gVmFsaWRhdGUgY29udGVudCB0eXBlXG4gICAgaWYgKHR5cGUgIT09ICdpbWFnZScgJiYgdHlwZSAhPT0gJ3ZpZGVvJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb250ZW50IHR5cGUgbXVzdCBiZSBcImltYWdlXCIgb3IgXCJ2aWRlb1wiJyk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgcGFyYW1ldGVyIGNvbnN0cmFpbnRzIHVzaW5nIHdpZHRoLWF3YXJlIHRpdGxlIHZhbGlkYXRpb25cbiAgICBhc3NlcnRUaXRsZVdpZHRoVmFsaWQodGl0bGUhKTtcbiAgICBpZiAoY29udGVudCEubGVuZ3RoID4gMTAwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb250ZW50IG11c3QgYmUgMTAwMCBjaGFyYWN0ZXJzIG9yIGxlc3MnKTtcbiAgICB9XG5cbiAgICAvLyBFeGVjdXRlIHVuaWZpZWQgcHVibGlzaGluZyBwcm9jZXNzXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5wdWJsaXNoU2VydmljZS5wdWJsaXNoQ29udGVudChcbiAgICAgIHR5cGUgYXMgJ2ltYWdlJyB8ICd2aWRlbycsXG4gICAgICB0aXRsZSEsXG4gICAgICBjb250ZW50ISxcbiAgICAgIG1lZGlhUGF0aHMhLFxuICAgICAgdGFncyxcbiAgICAgIGJyb3dzZXJQYXRoXG4gICAgKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVHZXRVc2VyTm90ZXMoXG4gICAgbGltaXQ/OiBudW1iZXIsXG4gICAgY3Vyc29yPzogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLm5vdGVTZXJ2aWNlLmdldFVzZXJOb3RlcyhsaW1pdCwgY3Vyc29yLCBicm93c2VyUGF0aCk7XG4gICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlRGVsZXRlTm90ZShcbiAgICBub3RlSWQ/OiBzdHJpbmcsXG4gICAgbGFzdFB1Ymxpc2hlZD86IGJvb2xlYW4sXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIGlmIChsYXN0UHVibGlzaGVkKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLm5vdGVTZXJ2aWNlLmRlbGV0ZUxhc3RQdWJsaXNoZWROb3RlKGJyb3dzZXJQYXRoKTtcbiAgICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UocmVzdWx0KTtcbiAgICB9IGVsc2UgaWYgKG5vdGVJZCkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ub3RlU2VydmljZS5kZWxldGVOb3RlKG5vdGVJZCwgYnJvd3NlclBhdGgpO1xuICAgICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VpdGhlciBub3RlX2lkIG9yIGxhc3RfcHVibGlzaGVkIG11c3QgYmUgc3BlY2lmaWVkJyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgaGFuZGxlVG9vbFJlcXVlc3QoXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGFyZ3M6IFRvb2xSZXF1ZXN0QXJncyA9IHt9XG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICB0cnkge1xuICAgICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICAgIGNhc2UgJ3hoc19hdXRoX2xvZ2luJzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVBdXRoTG9naW4oYXJncz8uYnJvd3Nlcl9wYXRoIGFzIHN0cmluZyk7XG5cbiAgICAgICAgY2FzZSAneGhzX2F1dGhfbG9nb3V0JzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVBdXRoTG9nb3V0KCk7XG5cbiAgICAgICAgY2FzZSAneGhzX2F1dGhfc3RhdHVzJzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVBdXRoU3RhdHVzKGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmcpO1xuXG4gICAgICAgIGNhc2UgJ3hoc19kaXNjb3Zlcl9mZWVkcyc6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlRGlzY292ZXJGZWVkcyhhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nKTtcblxuICAgICAgICBjYXNlICd4aHNfc2VhcmNoX25vdGUnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZVNlYXJjaE5vdGUoYXJncz8ua2V5d29yZCBhcyBzdHJpbmcsIGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmcpO1xuXG4gICAgICAgIGNhc2UgJ3hoc19nZXRfbm90ZV9kZXRhaWwnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZUdldE5vdGVEZXRhaWwoXG4gICAgICAgICAgICBhcmdzPy5mZWVkX2lkIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/LnhzZWNfdG9rZW4gYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8uYnJvd3Nlcl9wYXRoIGFzIHN0cmluZ1xuICAgICAgICAgICk7XG5cbiAgICAgICAgY2FzZSAneGhzX2NvbW1lbnRfb25fbm90ZSc6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlQ29tbWVudE9uTm90ZShcbiAgICAgICAgICAgIGFyZ3M/LmZlZWRfaWQgYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8ueHNlY190b2tlbiBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5ub3RlIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmdcbiAgICAgICAgICApO1xuXG4gICAgICAgIGNhc2UgJ3hoc19wdWJsaXNoX2NvbnRlbnQnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZVB1Ymxpc2hDb250ZW50KFxuICAgICAgICAgICAgYXJncz8udHlwZSBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy50aXRsZSBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5jb250ZW50IGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/Lm1lZGlhX3BhdGhzIGFzIHN0cmluZ1tdLFxuICAgICAgICAgICAgYXJncz8udGFncyBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nXG4gICAgICAgICAgKTtcblxuICAgICAgICBjYXNlICd4aHNfZ2V0X3VzZXJfbm90ZXMnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZUdldFVzZXJOb3RlcyhcbiAgICAgICAgICAgIGFyZ3M/LmxpbWl0IGFzIG51bWJlcixcbiAgICAgICAgICAgIGFyZ3M/LmN1cnNvciBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nXG4gICAgICAgICAgKTtcblxuICAgICAgICBjYXNlICd4aHNfZGVsZXRlX25vdGUnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZURlbGV0ZU5vdGUoXG4gICAgICAgICAgICBhcmdzPy5ub3RlX2lkIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/Lmxhc3RfcHVibGlzaGVkIGFzIGJvb2xlYW4sXG4gICAgICAgICAgICBhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nXG4gICAgICAgICAgKTtcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB0b29sOiAke25hbWV9YCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFhIU0Vycm9yKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UoZXJyb3IudG9KU09OKCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNyZWF0ZU1jcEVycm9yUmVzcG9uc2UoZXJyb3IpO1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBTaGFyZWQgdXRpbGl0aWVzLCB0eXBlcywgYW5kIHNlcnZpY2VzIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbi8vIENvbmZpZ3VyYXRpb24gYW5kIHR5cGVzXG5leHBvcnQgKiBmcm9tICcuL2NvbmZpZyc7XG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcblxuLy8gVXRpbGl0aWVzXG5leHBvcnQgKiBmcm9tICcuL3V0aWxzJztcbmV4cG9ydCAqIGZyb20gJy4veGhzLnV0aWxzJztcbmV4cG9ydCAqIGZyb20gJy4vY29va2llcyc7XG5leHBvcnQgKiBmcm9tICcuL2ltYWdlLWRvd25sb2FkZXInO1xuZXhwb3J0ICogZnJvbSAnLi90aXRsZS12YWxpZGF0b3InO1xuXG4vLyBFcnJvciBoYW5kbGluZyBhbmQgbG9nZ2luZ1xuZXhwb3J0ICogZnJvbSAnLi9lcnJvcnMnO1xuZXhwb3J0ICogZnJvbSAnLi9sb2dnZXInO1xuXG4vLyBCYXNlIHNlcnZpY2VcbmV4cG9ydCAqIGZyb20gJy4vYmFzZS5zZXJ2aWNlJztcbiIsIi8qKlxuICogUmVzb3VyY2UgcmVxdWVzdCBoYW5kbGVycyBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG5pbXBvcnQgeyBBdXRoU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvYXV0aC9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgZ2V0Q29uZmlnLCBnZXRDb29raWVzSW5mbyB9IGZyb20gJy4uLy4uL3NoYXJlZC9pbmRleCc7XG5cbmV4cG9ydCBjbGFzcyBSZXNvdXJjZUhhbmRsZXJzIHtcbiAgcHJpdmF0ZSBhdXRoU2VydmljZTogQXV0aFNlcnZpY2U7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgY29uc3QgY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy5hdXRoU2VydmljZSA9IG5ldyBBdXRoU2VydmljZShjb25maWcpO1xuICB9XG5cbiAgYXN5bmMgZ2V0Q29va2llc1Jlc291cmNlKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvb2tpZXNJbmZvID0gZ2V0Q29va2llc0luZm8oKTtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShjb29raWVzSW5mbywgbnVsbCwgMik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7IGVycm9yOiBTdHJpbmcoZXJyb3IpIH0sIG51bGwsIDIpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldENvbmZpZ1Jlc291cmNlKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbmZpZ0RpY3QgPSBnZXRDb25maWcoKTtcbiAgICAgIGNvbnN0IGNvbmZpZ1dpdGhGcmFtZXdvcmsgPSB7XG4gICAgICAgIC4uLmNvbmZpZ0RpY3QsXG4gICAgICAgIGZyYW1ld29yazogJ01DUCBUeXBlU2NyaXB0JyxcbiAgICAgICAgdmVyc2lvbjogY29uZmlnRGljdC5zZXJ2ZXIudmVyc2lvbixcbiAgICAgIH07XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoY29uZmlnV2l0aEZyYW1ld29yaywgbnVsbCwgMik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7IGVycm9yOiBTdHJpbmcoZXJyb3IpIH0sIG51bGwsIDIpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldFN0YXR1c1Jlc291cmNlKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFF1aWNrIHN0YXR1cyBjaGVjayAoYnV0IGRvbid0IGZhaWwgaWYgaXQgZXJyb3JzKVxuICAgICAgbGV0IGF1dGhTdGF0dXM6IGFueSA9IHsgc3RhdHVzOiAndW5rbm93bicsIGVycm9yOiAnU3RhdHVzIGNoZWNrIG5vdCBwZXJmb3JtZWQnIH07XG4gICAgICB0cnkge1xuICAgICAgICBhdXRoU3RhdHVzID0gYXdhaXQgdGhpcy5hdXRoU2VydmljZS5jaGVja1N0YXR1cygpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYXV0aFN0YXR1cyA9IHsgc3RhdHVzOiAnZXJyb3InLCBlcnJvcjogU3RyaW5nKGVycm9yKSB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjb29raWVzSW5mbyA9IGdldENvb2tpZXNJbmZvKCk7XG4gICAgICBjb25zdCBjb25maWcgPSBnZXRDb25maWcoKTtcblxuICAgICAgY29uc3Qgc3RhdHVzRGF0YSA9IHtcbiAgICAgICAgc2VydmVyOiB7XG4gICAgICAgICAgc3RhdHVzOiAncnVubmluZycsXG4gICAgICAgICAgbmFtZTogY29uZmlnLnNlcnZlci5uYW1lLFxuICAgICAgICAgIHZlcnNpb246IGNvbmZpZy5zZXJ2ZXIudmVyc2lvbixcbiAgICAgICAgICBmcmFtZXdvcms6ICdNQ1AgVHlwZVNjcmlwdCcsXG4gICAgICAgIH0sXG4gICAgICAgIGF1dGhlbnRpY2F0aW9uOiBhdXRoU3RhdHVzLFxuICAgICAgICBjb29raWVzOiB7XG4gICAgICAgICAgZmlsZUV4aXN0czogY29va2llc0luZm8uZmlsZUV4aXN0cyxcbiAgICAgICAgICBjb29raWVDb3VudDogY29va2llc0luZm8uY29va2llQ291bnQsXG4gICAgICAgIH0sXG4gICAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICAgIHRvb2xzQXZhaWxhYmxlOiA4LFxuICAgICAgICAgIHByb21wdHNBdmFpbGFibGU6IDAsXG4gICAgICAgICAgcmVzb3VyY2VzQXZhaWxhYmxlOiAzLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHN0YXR1c0RhdGEsIG51bGwsIDIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIHtcbiAgICAgICAgICBzZXJ2ZXI6IHsgc3RhdHVzOiAnZXJyb3InLCBlcnJvcjogU3RyaW5nKGVycm9yKSB9LFxuICAgICAgICAgIGZyYW1ld29yazogJ01DUCBUeXBlU2NyaXB0JyxcbiAgICAgICAgfSxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgMlxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBoYW5kbGVSZXNvdXJjZVJlcXVlc3QodXJpOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGNvbnRlbnQ6IHN0cmluZztcblxuICAgICAgc3dpdGNoICh1cmkpIHtcbiAgICAgICAgY2FzZSAneGhzOi8vY29va2llcyc6XG4gICAgICAgICAgY29udGVudCA9IGF3YWl0IHRoaXMuZ2V0Q29va2llc1Jlc291cmNlKCk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAneGhzOi8vY29uZmlnJzpcbiAgICAgICAgICBjb250ZW50ID0gYXdhaXQgdGhpcy5nZXRDb25maWdSZXNvdXJjZSgpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ3hoczovL3N0YXR1cyc6XG4gICAgICAgICAgY29udGVudCA9IGF3YWl0IHRoaXMuZ2V0U3RhdHVzUmVzb3VyY2UoKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biByZXNvdXJjZTogJHt1cml9YCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgbWltZVR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgIHRleHQ6IGNvbnRlbnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgbWltZVR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KHsgZXJyb3I6IFN0cmluZyhlcnJvcikgfSwgbnVsbCwgMiksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIFRvb2wgc2NoZW1hcyBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG5leHBvcnQgaW50ZXJmYWNlIFRvb2xTY2hlbWEge1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGlucHV0U2NoZW1hOiB7XG4gICAgdHlwZTogJ29iamVjdCc7XG4gICAgcHJvcGVydGllczogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICByZXF1aXJlZD86IHN0cmluZ1tdO1xuICB9O1xufVxuXG5leHBvcnQgY29uc3QgWEhTX1RPT0xfU0NIRU1BUzogVG9vbFNjaGVtYVtdID0gW1xuICB7XG4gICAgbmFtZTogJ3hoc19hdXRoX2xvZ2luJyxcbiAgICBkZXNjcmlwdGlvbjogJ1N0YXJ0IFhpYW9Ib25nU2h1IGxvZ2luIHByb2Nlc3MuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19hdXRoX2xvZ291dCcsXG4gICAgZGVzY3JpcHRpb246ICdMb2dvdXQgZnJvbSBYaWFvSG9uZ1NodSAoY2xlYXJzIHNhdmVkIGNvb2tpZXMpLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge30sXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICd4aHNfYXV0aF9zdGF0dXMnLFxuICAgIGRlc2NyaXB0aW9uOiAnQ2hlY2sgWGlhb0hvbmdTaHUgbG9naW4gc3RhdHVzIChmYXN0IGNoZWNrIHdpdGggYnJvd3NlcikuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19kaXNjb3Zlcl9mZWVkcycsXG4gICAgZGVzY3JpcHRpb246ICdHZXQgaG9tZSBwYWdlIGZlZWQgbGlzdC4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYnJvd3Nlcl9wYXRoOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPcHRpb25hbCBjdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAneGhzX3NlYXJjaF9ub3RlJyxcbiAgICBkZXNjcmlwdGlvbjogJ1NlYXJjaCBmb3Igbm90ZXMgYnkga2V5d29yZC4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAga2V5d29yZDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnU2VhcmNoIGtleXdvcmQgKHJlcXVpcmVkKScsXG4gICAgICAgIH0sXG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2tleXdvcmQnXSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19nZXRfbm90ZV9kZXRhaWwnLFxuICAgIGRlc2NyaXB0aW9uOiAnR2V0IGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IGEgc3BlY2lmaWMgbm90ZS4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgZmVlZF9pZDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRmVlZCBJRCAocmVxdWlyZWQpJyxcbiAgICAgICAgfSxcbiAgICAgICAgeHNlY190b2tlbjoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnU2VjdXJpdHkgdG9rZW4gZm9yIHRoZSBmZWVkIChyZXF1aXJlZCknLFxuICAgICAgICB9LFxuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWydmZWVkX2lkJywgJ3hzZWNfdG9rZW4nXSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19jb21tZW50X29uX25vdGUnLFxuICAgIGRlc2NyaXB0aW9uOiAnQ29tbWVudCBvbiBhIG5vdGUuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGZlZWRfaWQ6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0ZlZWQgSUQgKHJlcXVpcmVkKScsXG4gICAgICAgIH0sXG4gICAgICAgIHhzZWNfdG9rZW46IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1NlY3VyaXR5IHRva2VuIGZvciB0aGUgZmVlZCAocmVxdWlyZWQpJyxcbiAgICAgICAgfSxcbiAgICAgICAgbm90ZToge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQ29tbWVudCBub3RlIChyZXF1aXJlZCknLFxuICAgICAgICB9LFxuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWydmZWVkX2lkJywgJ3hzZWNfdG9rZW4nLCAnbm90ZSddLFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAneGhzX3B1Ymxpc2hfY29udGVudCcsXG4gICAgZGVzY3JpcHRpb246ICdQdWJsaXNoIGNvbnRlbnQgdG8gWGlhb0hvbmdTaHUgKHN1cHBvcnRzIGJvdGggaW1hZ2VzIGFuZCB2aWRlb3MpLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICB0eXBlOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZW51bTogWydpbWFnZScsICd2aWRlbyddLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQ29udGVudCB0eXBlOiBcImltYWdlXCIgZm9yIGltYWdlcywgXCJ2aWRlb1wiIGZvciB2aWRlb3MgKHJlcXVpcmVkKScsXG4gICAgICAgIH0sXG4gICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdDb250ZW50IHRpdGxlIChyZXF1aXJlZCwgbWF4IDIwIGNoYXJhY3RlcnMpJyxcbiAgICAgICAgICBtYXhMZW5ndGg6IDIwLFxuICAgICAgICB9LFxuICAgICAgICBjb250ZW50OiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdDb250ZW50IGRlc2NyaXB0aW9uIChyZXF1aXJlZCwgbWF4IDEwMDAgY2hhcmFjdGVycyknLFxuICAgICAgICAgIG1heExlbmd0aDogMTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVkaWFfcGF0aHM6IHtcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIGl0ZW1zOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICAnTGlzdCBvZiBtZWRpYSBmaWxlIHBhdGhzIChyZXF1aXJlZCwgbm9uLWVtcHR5KS4gRm9yIGltYWdlczogMS0xOCBpbWFnZSBmaWxlcy4gRm9yIHZpZGVvczogZXhhY3RseSAxIHZpZGVvIGZpbGUuJyxcbiAgICAgICAgICBtYXhJdGVtczogMTgsXG4gICAgICAgIH0sXG4gICAgICAgIHRhZ3M6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0NvbW1hLXNlcGFyYXRlZCB0YWdzIChvcHRpb25hbCknLFxuICAgICAgICB9LFxuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWyd0eXBlJywgJ3RpdGxlJywgJ2NvbnRlbnQnLCAnbWVkaWFfcGF0aHMnXSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19nZXRfdXNlcl9ub3RlcycsXG4gICAgZGVzY3JpcHRpb246ICdHZXQgY3VycmVudCB1c2VyIG5vdGVzIGxpc3QuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGxpbWl0OiB7XG4gICAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdOdW1iZXIgb2Ygbm90ZXMgdG8gZmV0Y2ggKGRlZmF1bHQ6IDIwKScsXG4gICAgICAgIH0sXG4gICAgICAgIGN1cnNvcjoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUGFnaW5hdGlvbiBjdXJzb3IgZm9yIG5leHQgcGFnZScsXG4gICAgICAgIH0sXG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19kZWxldGVfbm90ZScsXG4gICAgZGVzY3JpcHRpb246ICdEZWxldGUgYSB1c2VyIG5vdGUgYnkgSUQgb3IgZGVsZXRlIHRoZSBsYXN0IHB1Ymxpc2hlZCBub3RlLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBub3RlX2lkOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdTcGVjaWZpYyBub3RlIElEIHRvIGRlbGV0ZSAob3B0aW9uYWwgaWYgbGFzdF9wdWJsaXNoZWQgaXMgdHJ1ZSknLFxuICAgICAgICB9LFxuICAgICAgICBsYXN0X3B1Ymxpc2hlZDoge1xuICAgICAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0RlbGV0ZSB0aGUgbGFzdCBwdWJsaXNoZWQgbm90ZSAob3B0aW9uYWwgaWYgbm90ZV9pZCBpcyBwcm92aWRlZCknLFxuICAgICAgICB9LFxuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbl07XG5cbmV4cG9ydCBjb25zdCBYSFNfUkVTT1VSQ0VfU0NIRU1BUyA9IFtcbiAge1xuICAgIHVyaTogJ3hoczovL2Nvb2tpZXMnLFxuICAgIG5hbWU6ICdYSFMgQXV0aGVudGljYXRpb24gQ29va2llcycsXG4gICAgZGVzY3JpcHRpb246ICdDdXJyZW50IFhpYW9Ib25nU2h1IGF1dGhlbnRpY2F0aW9uIGNvb2tpZXMgYW5kIGluZm8nLFxuICAgIG1pbWVUeXBlOiAnYXBwbGljYXRpb24vanNvbicsXG4gIH0sXG4gIHtcbiAgICB1cmk6ICd4aHM6Ly9jb25maWcnLFxuICAgIG5hbWU6ICdYSFMgU2VydmVyIENvbmZpZ3VyYXRpb24nLFxuICAgIGRlc2NyaXB0aW9uOiAnWEhTIE1DUCBzZXJ2ZXIgY29uZmlndXJhdGlvbicsXG4gICAgbWltZVR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgfSxcbiAge1xuICAgIHVyaTogJ3hoczovL3N0YXR1cycsXG4gICAgbmFtZTogJ1hIUyBTZXJ2ZXIgU3RhdHVzJyxcbiAgICBkZXNjcmlwdGlvbjogJ0N1cnJlbnQgc2VydmVyIGFuZCBhdXRoZW50aWNhdGlvbiBzdGF0dXMnLFxuICAgIG1pbWVUeXBlOiAnYXBwbGljYXRpb24vanNvbicsXG4gIH0sXG5dO1xuIiwiLyoqXG4gKiBNQ1AgU2VydmVyIGZvciBYaWFvSG9uZ1NodSBPcGVyYXRpb25zXG4gKi9cblxuaW1wb3J0IHsgU2VydmVyIH0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zZXJ2ZXIvaW5kZXguanMnO1xuaW1wb3J0IHsgU3RkaW9TZXJ2ZXJUcmFuc3BvcnQgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9zdGRpby5qcyc7XG5pbXBvcnQge1xuICBDYWxsVG9vbFJlcXVlc3RTY2hlbWEsXG4gIExpc3RUb29sc1JlcXVlc3RTY2hlbWEsXG4gIExpc3RSZXNvdXJjZXNSZXF1ZXN0U2NoZW1hLFxuICBSZWFkUmVzb3VyY2VSZXF1ZXN0U2NoZW1hLFxufSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3R5cGVzLmpzJztcbmltcG9ydCB7IGdldENvbmZpZyB9IGZyb20gJy4uL3NoYXJlZC9jb25maWcnO1xuaW1wb3J0IHsgVG9vbEhhbmRsZXJzIH0gZnJvbSAnLi9oYW5kbGVycy90b29sLmhhbmRsZXJzJztcbmltcG9ydCB7IFJlc291cmNlSGFuZGxlcnMgfSBmcm9tICcuL2hhbmRsZXJzL3Jlc291cmNlLmhhbmRsZXJzJztcbmltcG9ydCB7IFhIU19UT09MX1NDSEVNQVMsIFhIU19SRVNPVVJDRV9TQ0hFTUFTIH0gZnJvbSAnLi9zY2hlbWFzL3Rvb2wuc2NoZW1hcyc7XG5cbmV4cG9ydCBjbGFzcyBYSFNNQ1BTZXJ2ZXIge1xuICBwcml2YXRlIHNlcnZlcjogU2VydmVyO1xuICBwcml2YXRlIHRvb2xIYW5kbGVyczogVG9vbEhhbmRsZXJzO1xuICBwcml2YXRlIHJlc291cmNlSGFuZGxlcnM6IFJlc291cmNlSGFuZGxlcnM7XG4gIHByaXZhdGUgY29uZmlnOiBSZXR1cm5UeXBlPHR5cGVvZiBnZXRDb25maWc+O1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy50b29sSGFuZGxlcnMgPSBuZXcgVG9vbEhhbmRsZXJzKCk7XG4gICAgdGhpcy5yZXNvdXJjZUhhbmRsZXJzID0gbmV3IFJlc291cmNlSGFuZGxlcnMoKTtcbiAgICB0aGlzLnNlcnZlciA9IG5ldyBTZXJ2ZXIoXG4gICAgICB7XG4gICAgICAgIG5hbWU6IHRoaXMuY29uZmlnLnNlcnZlci5uYW1lLFxuICAgICAgICB2ZXJzaW9uOiB0aGlzLmNvbmZpZy5zZXJ2ZXIudmVyc2lvbixcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICAgIHRvb2xzOiB7fSxcbiAgICAgICAgICByZXNvdXJjZXM6IHt9LFxuICAgICAgICB9LFxuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnNldHVwVG9vbEhhbmRsZXJzKCk7XG4gICAgdGhpcy5zZXR1cFJlc291cmNlSGFuZGxlcnMoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBUb29sSGFuZGxlcnMoKTogdm9pZCB7XG4gICAgdGhpcy5zZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoQ2FsbFRvb2xSZXF1ZXN0U2NoZW1hLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgY29uc3QgeyBuYW1lLCBhcmd1bWVudHM6IGFyZ3MgfSA9IHJlcXVlc3QucGFyYW1zO1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMudG9vbEhhbmRsZXJzLmhhbmRsZVRvb2xSZXF1ZXN0KG5hbWUsIGFyZ3MpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoTGlzdFRvb2xzUmVxdWVzdFNjaGVtYSwgYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9vbHM6IFhIU19UT09MX1NDSEVNQVMsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cFJlc291cmNlSGFuZGxlcnMoKTogdm9pZCB7XG4gICAgdGhpcy5zZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoTGlzdFJlc291cmNlc1JlcXVlc3RTY2hlbWEsIGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc291cmNlczogWEhTX1JFU09VUkNFX1NDSEVNQVMsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoUmVhZFJlc291cmNlUmVxdWVzdFNjaGVtYSwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgIGNvbnN0IHsgdXJpIH0gPSByZXF1ZXN0LnBhcmFtcztcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlc291cmNlSGFuZGxlcnMuaGFuZGxlUmVzb3VyY2VSZXF1ZXN0KHVyaSk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0cmFuc3BvcnQgPSBuZXcgU3RkaW9TZXJ2ZXJUcmFuc3BvcnQoKTtcbiAgICBhd2FpdCB0aGlzLnNlcnZlci5jb25uZWN0KHRyYW5zcG9ydCk7XG4gICAgLy8gRG9uJ3QgbG9nIHRvIHN0ZGVyciBpbiBzdGRpbyBtb2RlIHRvIGF2b2lkIGludGVyZmVyaW5nIHdpdGggTUNQIHByb3RvY29sXG4gIH1cbn1cbiIsImNvbnN0IF9fV0VCUEFDS19OQU1FU1BBQ0VfT0JKRUNUX18gPSByZXF1aXJlKFwiZXhwcmVzc1wiKTsiLCJjb25zdCBfX1dFQlBBQ0tfTkFNRVNQQUNFX09CSkVDVF9fID0gcmVxdWlyZShcImNvcnNcIik7IiwiLyoqXG4gKiBIVFRQIFNlcnZlciB3aXRoIFNTRSBhbmQgU3RyZWFtYWJsZSBIVFRQIFRyYW5zcG9ydCBTdXBwb3J0XG4gKi9cblxuaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgY29ycyBmcm9tICdjb3JzJztcbmltcG9ydCB7IHJhbmRvbVVVSUQgfSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQgeyBTZXJ2ZXIgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9pbmRleC5qcyc7XG5pbXBvcnQgeyBTU0VTZXJ2ZXJUcmFuc3BvcnQgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9zc2UuanMnO1xuaW1wb3J0IHsgU3RyZWFtYWJsZUhUVFBTZXJ2ZXJUcmFuc3BvcnQgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9zdHJlYW1hYmxlSHR0cC5qcyc7XG5pbXBvcnQgeyBpc0luaXRpYWxpemVSZXF1ZXN0IH0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay90eXBlcy5qcyc7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgVG9vbEhhbmRsZXJzIH0gZnJvbSAnLi9oYW5kbGVycy90b29sLmhhbmRsZXJzJztcbmltcG9ydCB7IFJlc291cmNlSGFuZGxlcnMgfSBmcm9tICcuL2hhbmRsZXJzL3Jlc291cmNlLmhhbmRsZXJzJztcbmltcG9ydCB7IFhIU19UT09MX1NDSEVNQVMsIFhIU19SRVNPVVJDRV9TQ0hFTUFTIH0gZnJvbSAnLi9zY2hlbWFzL3Rvb2wuc2NoZW1hcyc7XG5pbXBvcnQge1xuICBDYWxsVG9vbFJlcXVlc3RTY2hlbWEsXG4gIExpc3RUb29sc1JlcXVlc3RTY2hlbWEsXG4gIExpc3RSZXNvdXJjZXNSZXF1ZXN0U2NoZW1hLFxuICBSZWFkUmVzb3VyY2VSZXF1ZXN0U2NoZW1hLFxufSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3R5cGVzLmpzJztcblxuZXhwb3J0IGNsYXNzIFhIU0hUVFBNQ1BTZXJ2ZXIge1xuICBwcml2YXRlIGFwcDogZXhwcmVzcy5BcHBsaWNhdGlvbjtcbiAgcHJpdmF0ZSBjb25maWc6IFJldHVyblR5cGU8dHlwZW9mIGdldENvbmZpZz47XG4gIHByaXZhdGUgdG9vbEhhbmRsZXJzOiBUb29sSGFuZGxlcnM7XG4gIHByaXZhdGUgcmVzb3VyY2VIYW5kbGVyczogUmVzb3VyY2VIYW5kbGVycztcbiAgcHJpdmF0ZSB0cmFuc3BvcnRzOiBNYXA8c3RyaW5nLCBTU0VTZXJ2ZXJUcmFuc3BvcnQgfCBTdHJlYW1hYmxlSFRUUFNlcnZlclRyYW5zcG9ydD4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgcG9ydDogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHBvcnQ6IG51bWJlciA9IDMwMDApIHtcbiAgICB0aGlzLnBvcnQgPSBwb3J0O1xuICAgIHRoaXMuY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy50b29sSGFuZGxlcnMgPSBuZXcgVG9vbEhhbmRsZXJzKCk7XG4gICAgdGhpcy5yZXNvdXJjZUhhbmRsZXJzID0gbmV3IFJlc291cmNlSGFuZGxlcnMoKTtcbiAgICB0aGlzLmFwcCA9IGV4cHJlc3MoKTtcblxuICAgIHRoaXMuc2V0dXBNaWRkbGV3YXJlKCk7XG4gICAgdGhpcy5zZXR1cFJvdXRlcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cE1pZGRsZXdhcmUoKTogdm9pZCB7XG4gICAgLy8gUGFyc2UgSlNPTiBib2RpZXNcbiAgICB0aGlzLmFwcC51c2UoZXhwcmVzcy5qc29uKCkpO1xuXG4gICAgLy8gQ29uZmlndXJlIENPUlMgdG8gZXhwb3NlIE1jcC1TZXNzaW9uLUlkIGhlYWRlciBmb3IgYnJvd3Nlci1iYXNlZCBjbGllbnRzXG4gICAgdGhpcy5hcHAudXNlKFxuICAgICAgY29ycyh7XG4gICAgICAgIG9yaWdpbjogJyonLCAvLyBBbGxvdyBhbGwgb3JpZ2lucyAtIGFkanVzdCBhcyBuZWVkZWQgZm9yIHByb2R1Y3Rpb25cbiAgICAgICAgZXhwb3NlZEhlYWRlcnM6IFsnTWNwLVNlc3Npb24tSWQnXSxcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBSb3V0ZXMoKTogdm9pZCB7XG4gICAgLy8gU3RyZWFtYWJsZSBIVFRQIFRyYW5zcG9ydCAoUHJvdG9jb2wgdmVyc2lvbiAyMDI1LTAzLTI2KVxuICAgIHRoaXMuYXBwLmFsbCgnL21jcCcsIHRoaXMuaGFuZGxlU3RyZWFtYWJsZUhUVFAuYmluZCh0aGlzKSk7XG5cbiAgICAvLyBEZXByZWNhdGVkIEhUVFArU1NFIFRyYW5zcG9ydCAoUHJvdG9jb2wgdmVyc2lvbiAyMDI0LTExLTA1KVxuICAgIHRoaXMuYXBwLmdldCgnL3NzZScsIHRoaXMuaGFuZGxlU1NFQ29ubmVjdGlvbi5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLmFwcC5wb3N0KCcvbWVzc2FnZXMnLCB0aGlzLmhhbmRsZVNTRU1lc3NhZ2UuYmluZCh0aGlzKSk7XG5cbiAgICAvLyBIZWFsdGggY2hlY2sgZW5kcG9pbnRcbiAgICB0aGlzLmFwcC5nZXQoJy9oZWFsdGgnLCAocmVxLCByZXMpID0+IHtcbiAgICAgIHJlcy5qc29uKHtcbiAgICAgICAgc3RhdHVzOiAnaGVhbHRoeScsXG4gICAgICAgIHNlcnZlcjogdGhpcy5jb25maWcuc2VydmVyLm5hbWUsXG4gICAgICAgIHZlcnNpb246IHRoaXMuY29uZmlnLnNlcnZlci52ZXJzaW9uLFxuICAgICAgICB0cmFuc3BvcnRzOiBbJ3N0cmVhbWFibGUtaHR0cCcsICdzc2UnXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVTdHJlYW1hYmxlSFRUUChyZXE6IGV4cHJlc3MuUmVxdWVzdCwgcmVzOiBleHByZXNzLlJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nZ2VyLmluZm8oYFJlY2VpdmVkICR7cmVxLm1ldGhvZH0gcmVxdWVzdCB0byAvbWNwYCk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gQ2hlY2sgZm9yIGV4aXN0aW5nIHNlc3Npb24gSURcbiAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHJlcS5oZWFkZXJzWydtY3Atc2Vzc2lvbi1pZCddIGFzIHN0cmluZztcbiAgICAgIGxldCB0cmFuc3BvcnQ6IFN0cmVhbWFibGVIVFRQU2VydmVyVHJhbnNwb3J0IHwgdW5kZWZpbmVkO1xuXG4gICAgICBpZiAoc2Vzc2lvbklkICYmIHRoaXMudHJhbnNwb3J0cy5oYXMoc2Vzc2lvbklkKSkge1xuICAgICAgICBjb25zdCBleGlzdGluZ1RyYW5zcG9ydCA9IHRoaXMudHJhbnNwb3J0cy5nZXQoc2Vzc2lvbklkKTtcbiAgICAgICAgaWYgKGV4aXN0aW5nVHJhbnNwb3J0IGluc3RhbmNlb2YgU3RyZWFtYWJsZUhUVFBTZXJ2ZXJUcmFuc3BvcnQpIHtcbiAgICAgICAgICB0cmFuc3BvcnQgPSBleGlzdGluZ1RyYW5zcG9ydDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXMuc3RhdHVzKDQwMCkuanNvbih7XG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICAgIGNvZGU6IC0zMjAwMCxcbiAgICAgICAgICAgICAgbWVzc2FnZTogJ0JhZCBSZXF1ZXN0OiBTZXNzaW9uIGV4aXN0cyBidXQgdXNlcyBhIGRpZmZlcmVudCB0cmFuc3BvcnQgcHJvdG9jb2wnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGlkOiBudWxsLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghc2Vzc2lvbklkICYmIHJlcS5tZXRob2QgPT09ICdQT1NUJyAmJiBpc0luaXRpYWxpemVSZXF1ZXN0KHJlcS5ib2R5KSkge1xuICAgICAgICAvLyBDcmVhdGUgbmV3IFN0cmVhbWFibGUgSFRUUCB0cmFuc3BvcnRcbiAgICAgICAgdHJhbnNwb3J0ID0gbmV3IFN0cmVhbWFibGVIVFRQU2VydmVyVHJhbnNwb3J0KHtcbiAgICAgICAgICBzZXNzaW9uSWRHZW5lcmF0b3I6ICgpOiBzdHJpbmcgPT4gcmFuZG9tVVVJRCgpLFxuICAgICAgICAgIG9uc2Vzc2lvbmluaXRpYWxpemVkOiAoc2Vzc2lvbklkOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBTdHJlYW1hYmxlSFRUUCBzZXNzaW9uIGluaXRpYWxpemVkIHdpdGggSUQ6ICR7c2Vzc2lvbklkfWApO1xuICAgICAgICAgICAgdGhpcy50cmFuc3BvcnRzLnNldChzZXNzaW9uSWQsIHRyYW5zcG9ydCEpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgb25zZXNzaW9uY2xvc2VkOiAoc2Vzc2lvbklkOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBTdHJlYW1hYmxlSFRUUCBzZXNzaW9uIGNsb3NlZDogJHtzZXNzaW9uSWR9YCk7XG4gICAgICAgICAgICB0aGlzLnRyYW5zcG9ydHMuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IHVwIG9uY2xvc2UgaGFuZGxlciB0byBjbGVhbiB1cCB0cmFuc3BvcnQgd2hlbiBjbG9zZWRcbiAgICAgICAgdHJhbnNwb3J0Lm9uY2xvc2UgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgY29uc3Qgc2lkID0gdHJhbnNwb3J0IS5zZXNzaW9uSWQ7XG4gICAgICAgICAgaWYgKHNpZCAmJiB0aGlzLnRyYW5zcG9ydHMuaGFzKHNpZCkpIHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBUcmFuc3BvcnQgY2xvc2VkIGZvciBzZXNzaW9uICR7c2lkfSwgcmVtb3ZpbmcgZnJvbSB0cmFuc3BvcnRzIG1hcGApO1xuICAgICAgICAgICAgdGhpcy50cmFuc3BvcnRzLmRlbGV0ZShzaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyBDb25uZWN0IHRoZSB0cmFuc3BvcnQgdG8gdGhlIE1DUCBzZXJ2ZXJcbiAgICAgICAgY29uc3Qgc2VydmVyID0gdGhpcy5jcmVhdGVNQ1BTZXJ2ZXIoKTtcbiAgICAgICAgYXdhaXQgc2VydmVyLmNvbm5lY3QodHJhbnNwb3J0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEludmFsaWQgcmVxdWVzdCAtIG5vIHNlc3Npb24gSUQgb3Igbm90IGluaXRpYWxpemF0aW9uIHJlcXVlc3RcbiAgICAgICAgcmVzLnN0YXR1cyg0MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzIwMDAsXG4gICAgICAgICAgICBtZXNzYWdlOiAnQmFkIFJlcXVlc3Q6IE5vIHZhbGlkIHNlc3Npb24gSUQgcHJvdmlkZWQnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaWQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIEhhbmRsZSB0aGUgcmVxdWVzdCB3aXRoIHRoZSB0cmFuc3BvcnRcbiAgICAgIGF3YWl0IHRyYW5zcG9ydC5oYW5kbGVSZXF1ZXN0KHJlcSwgcmVzLCByZXEuYm9keSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgaGFuZGxpbmcgU3RyZWFtYWJsZSBIVFRQIHJlcXVlc3Q6JywgZXJyb3IpO1xuICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzI2MDMsXG4gICAgICAgICAgICBtZXNzYWdlOiAnSW50ZXJuYWwgc2VydmVyIGVycm9yJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGhhbmRsZVNTRUNvbm5lY3Rpb24ocmVxOiBleHByZXNzLlJlcXVlc3QsIHJlczogZXhwcmVzcy5SZXNwb25zZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZ2dlci5pbmZvKCdSZWNlaXZlZCBHRVQgcmVxdWVzdCB0byAvc3NlIChkZXByZWNhdGVkIFNTRSB0cmFuc3BvcnQpJyk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJhbnNwb3J0ID0gbmV3IFNTRVNlcnZlclRyYW5zcG9ydCgnL21lc3NhZ2VzJywgcmVzKTtcbiAgICAgIHRoaXMudHJhbnNwb3J0cy5zZXQodHJhbnNwb3J0LnNlc3Npb25JZCwgdHJhbnNwb3J0KTtcblxuICAgICAgcmVzLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgdGhpcy50cmFuc3BvcnRzLmRlbGV0ZSh0cmFuc3BvcnQuc2Vzc2lvbklkKTtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzZXJ2ZXIgPSB0aGlzLmNyZWF0ZU1DUFNlcnZlcigpO1xuICAgICAgYXdhaXQgc2VydmVyLmNvbm5lY3QodHJhbnNwb3J0KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBoYW5kbGluZyBTU0UgY29ubmVjdGlvbjonLCBlcnJvcik7XG4gICAgICBpZiAoIXJlcy5oZWFkZXJzU2VudCkge1xuICAgICAgICByZXMuc3RhdHVzKDUwMCkuanNvbih7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgIGNvZGU6IC0zMjYwMyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdJbnRlcm5hbCBzZXJ2ZXIgZXJyb3InLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaWQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlU1NFTWVzc2FnZShyZXE6IGV4cHJlc3MuUmVxdWVzdCwgcmVzOiBleHByZXNzLlJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc2Vzc2lvbklkID0gcmVxLnF1ZXJ5LnNlc3Npb25JZCBhcyBzdHJpbmc7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJhbnNwb3J0ID0gdGhpcy50cmFuc3BvcnRzLmdldChzZXNzaW9uSWQpO1xuXG4gICAgICBpZiAoIXRyYW5zcG9ydCB8fCAhKHRyYW5zcG9ydCBpbnN0YW5jZW9mIFNTRVNlcnZlclRyYW5zcG9ydCkpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg0MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzIwMDAsXG4gICAgICAgICAgICBtZXNzYWdlOiAnQmFkIFJlcXVlc3Q6IFNlc3Npb24gZXhpc3RzIGJ1dCB1c2VzIGEgZGlmZmVyZW50IHRyYW5zcG9ydCBwcm90b2NvbCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBpZDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgdHJhbnNwb3J0LmhhbmRsZVBvc3RNZXNzYWdlKHJlcSwgcmVzLCByZXEuYm9keSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgaGFuZGxpbmcgU1NFIG1lc3NhZ2U6JywgZXJyb3IpO1xuICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzI2MDMsXG4gICAgICAgICAgICBtZXNzYWdlOiAnSW50ZXJuYWwgc2VydmVyIGVycm9yJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZU1DUFNlcnZlcigpOiBTZXJ2ZXIge1xuICAgIGNvbnN0IHNlcnZlciA9IG5ldyBTZXJ2ZXIoXG4gICAgICB7XG4gICAgICAgIG5hbWU6IHRoaXMuY29uZmlnLnNlcnZlci5uYW1lLFxuICAgICAgICB2ZXJzaW9uOiB0aGlzLmNvbmZpZy5zZXJ2ZXIudmVyc2lvbixcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICAgIHRvb2xzOiB7fSxcbiAgICAgICAgICByZXNvdXJjZXM6IHt9LFxuICAgICAgICB9LFxuICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBTZXR1cCB0b29sIGhhbmRsZXJzXG4gICAgc2VydmVyLnNldFJlcXVlc3RIYW5kbGVyKENhbGxUb29sUmVxdWVzdFNjaGVtYSwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgIGNvbnN0IHsgbmFtZSwgYXJndW1lbnRzOiBhcmdzIH0gPSByZXF1ZXN0LnBhcmFtcztcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnRvb2xIYW5kbGVycy5oYW5kbGVUb29sUmVxdWVzdChuYW1lLCBhcmdzKTtcbiAgICB9KTtcblxuICAgIHNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihMaXN0VG9vbHNSZXF1ZXN0U2NoZW1hLCBhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b29sczogWEhTX1RPT0xfU0NIRU1BUyxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBTZXR1cCByZXNvdXJjZSBoYW5kbGVyc1xuICAgIHNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihMaXN0UmVzb3VyY2VzUmVxdWVzdFNjaGVtYSwgYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVzb3VyY2VzOiBYSFNfUkVTT1VSQ0VfU0NIRU1BUyxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBzZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoUmVhZFJlc291cmNlUmVxdWVzdFNjaGVtYSwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgIGNvbnN0IHsgdXJpIH0gPSByZXF1ZXN0LnBhcmFtcztcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlc291cmNlSGFuZGxlcnMuaGFuZGxlUmVzb3VyY2VSZXF1ZXN0KHVyaSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2VydmVyO1xuICB9XG5cbiAgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHNlcnZlciA9IHRoaXMuYXBwLmxpc3Rlbih0aGlzLnBvcnQsIChlcnJvcj86IEVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignRmFpbGVkIHRvIHN0YXJ0IEhUVFAgc2VydmVyOicsIGVycm9yKTtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUubG9nKGBYSFMgTUNQIEhUVFAgU2VydmVyIGxpc3RlbmluZyBvbiBwb3J0ICR7dGhpcy5wb3J0fWApO1xuICAgICAgICBjb25zb2xlLmxvZyhgXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5TVVBQT1JURUQgVFJBTlNQT1JUIE9QVElPTlM6XG5cbjEuIFN0cmVhbWFibGUgSFRUUCAoUHJvdG9jb2wgdmVyc2lvbjogMjAyNS0wMy0yNilcbiAgIEVuZHBvaW50OiAvbWNwXG4gICBNZXRob2RzOiBHRVQsIFBPU1QsIERFTEVURVxuICAgVXNhZ2U6XG4gICAgIC0gSW5pdGlhbGl6ZSB3aXRoIFBPU1QgdG8gL21jcFxuICAgICAtIEVzdGFibGlzaCBTU0Ugc3RyZWFtIHdpdGggR0VUIHRvIC9tY3BcbiAgICAgLSBTZW5kIHJlcXVlc3RzIHdpdGggUE9TVCB0byAvbWNwXG4gICAgIC0gVGVybWluYXRlIHNlc3Npb24gd2l0aCBERUxFVEUgdG8gL21jcFxuXG4yLiBIVFRQICsgU1NFIChQcm90b2NvbCB2ZXJzaW9uOiAyMDI0LTExLTA1KVxuICAgRW5kcG9pbnRzOiAvc3NlIChHRVQpIGFuZCAvbWVzc2FnZXMgKFBPU1QpXG4gICBVc2FnZTpcbiAgICAgLSBFc3RhYmxpc2ggU1NFIHN0cmVhbSB3aXRoIEdFVCB0byAvc3NlXG4gICAgIC0gU2VuZCByZXF1ZXN0cyB3aXRoIFBPU1QgdG8gL21lc3NhZ2VzP3Nlc3Npb25JZD08aWQ+XG5cbjMuIEhlYWx0aCBDaGVja1xuICAgRW5kcG9pbnQ6IC9oZWFsdGhcbiAgIE1ldGhvZDogR0VUXG4gICBVc2FnZTogQ2hlY2sgc2VydmVyIHN0YXR1cyBhbmQgc3VwcG9ydGVkIHRyYW5zcG9ydHNcbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmApO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gSGFuZGxlIHNlcnZlciBzaHV0ZG93blxuICAgICAgcHJvY2Vzcy5vbignU0lHSU5UJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBsb2dnZXIuaW5mbygnU2h1dHRpbmcgZG93biBIVFRQIHNlcnZlci4uLicpO1xuXG4gICAgICAgIGZvciAoY29uc3QgW3Nlc3Npb25JZCwgdHJhbnNwb3J0XSBvZiB0aGlzLnRyYW5zcG9ydHMpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYENsb3NpbmcgdHJhbnNwb3J0IGZvciBzZXNzaW9uICR7c2Vzc2lvbklkfWApO1xuICAgICAgICAgICAgYXdhaXQgdHJhbnNwb3J0LmNsb3NlKCk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgRXJyb3IgY2xvc2luZyB0cmFuc3BvcnQgZm9yIHNlc3Npb24gJHtzZXNzaW9uSWR9OmAsIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRyYW5zcG9ydHMuY2xlYXIoKTtcbiAgICAgICAgc2VydmVyLmNsb3NlKCgpID0+IHtcbiAgICAgICAgICBsb2dnZXIuaW5mbygnSFRUUCBzZXJ2ZXIgc2h1dGRvd24gY29tcGxldGUnKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHByb2Nlc3Mub24oJ1NJR1RFUk0nLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdTaHV0dGluZyBkb3duIEhUVFAgc2VydmVyLi4uJyk7XG5cbiAgICAgICAgZm9yIChjb25zdCBbc2Vzc2lvbklkLCB0cmFuc3BvcnRdIG9mIHRoaXMudHJhbnNwb3J0cykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhgQ2xvc2luZyB0cmFuc3BvcnQgZm9yIHNlc3Npb24gJHtzZXNzaW9uSWR9YCk7XG4gICAgICAgICAgICBhd2FpdCB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBFcnJvciBjbG9zaW5nIHRyYW5zcG9ydCBmb3Igc2Vzc2lvbiAke3Nlc3Npb25JZH06YCwgZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudHJhbnNwb3J0cy5jbGVhcigpO1xuICAgICAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4ge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKCdIVFRQIHNlcnZlciBzaHV0ZG93biBjb21wbGV0ZScpO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQ2xvc2UgYWxsIGFjdGl2ZSB0cmFuc3BvcnRzXG4gICAgZm9yIChjb25zdCBbc2Vzc2lvbklkLCB0cmFuc3BvcnRdIG9mIHRoaXMudHJhbnNwb3J0cykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdHJhbnNwb3J0LmNsb3NlKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYEVycm9yIGNsb3NpbmcgdHJhbnNwb3J0IGZvciBzZXNzaW9uICR7c2Vzc2lvbklkfTpgLCBlcnJvcik7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudHJhbnNwb3J0cy5jbGVhcigpO1xuICB9XG59XG4iLCIvKipcbiAqIFJlcXVlc3QgaGFuZGxlcnMgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi90b29sLmhhbmRsZXJzJztcbmV4cG9ydCAqIGZyb20gJy4vcmVzb3VyY2UuaGFuZGxlcnMnO1xuIiwiLyoqXG4gKiBTZXJ2ZXIgaW1wbGVtZW50YXRpb24gZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9tY3Auc2VydmVyJztcbmV4cG9ydCAqIGZyb20gJy4vaHR0cC5zZXJ2ZXInO1xuZXhwb3J0ICogZnJvbSAnLi9oYW5kbGVycy9pbmRleCc7XG4iLCIjIS91c3IvYmluL2VudiBub2RlXG5cbi8qKlxuICogVW5pZmllZCBDTEkgZm9yIFhpYW9Ib25nU2h1IG9wZXJhdGlvbnNcbiAqL1xuXG5pbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnY29tbWFuZGVyJztcbmltcG9ydCB7IGdldENvbmZpZyB9IGZyb20gJy4uL3NoYXJlZC9jb25maWcnO1xuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuLi9jb3JlL2F1dGgvYXV0aC5zZXJ2aWNlJztcbmltcG9ydCBwdXBwZXRlZXIgZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IHNwYXduU3luYyB9IGZyb20gJ25vZGU6Y2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgeyBYSFNNQ1BTZXJ2ZXIsIFhIU0hUVFBNQ1BTZXJ2ZXIgfSBmcm9tICcuLi9zZXJ2ZXIvaW5kZXgnO1xuaW1wb3J0IHsgWEhTX1RPT0xfU0NIRU1BUyB9IGZyb20gJy4uL3NlcnZlci9zY2hlbWFzL3Rvb2wuc2NoZW1hcyc7XG5pbXBvcnQgeyBGZWVkU2VydmljZSB9IGZyb20gJy4uL2NvcmUvZmVlZHMvZmVlZC5zZXJ2aWNlJztcbmltcG9ydCB7IFB1Ymxpc2hTZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9wdWJsaXNoaW5nL3B1Ymxpc2guc2VydmljZSc7XG5pbXBvcnQgeyBOb3RlU2VydmljZSB9IGZyb20gJy4uL2NvcmUvbm90ZXMvbm90ZS5zZXJ2aWNlJztcblxuLyoqXG4gKiBDTEkgdXRpbGl0eSBmdW5jdGlvbnNcbiAqL1xuY2xhc3MgQ0xJVXRpbHMge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHByb2dyYW06IENvbW1hbmQpIHt9XG5cbiAgZm9ybWF0RXJyb3JNZXNzYWdlKGVycm9yOiB1bmtub3duKTogc3RyaW5nIHtcbiAgICBjb25zdCByYXcgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gKGVycm9yLnN0YWNrID8/IGVycm9yLm1lc3NhZ2UpIDogU3RyaW5nKGVycm9yKTtcblxuICAgIC8vIEhhbmRsZSBzcGVjaWZpYyBlcnJvciBwYXR0ZXJuc1xuICAgIGlmICgvRXhlY3V0YWJsZSBkb2Vzbid0IGV4aXN0fHB1cHBldGVlciBicm93c2VycyBpbnN0YWxsL2kudGVzdChyYXcpKSB7XG4gICAgICByZXR1cm4gJ0Nocm9taXVtIGlzIG5vdCBpbnN0YWxsZWQuIFJ1bjogbnB4IHB1cHBldGVlciBicm93c2VycyBpbnN0YWxsIGNocm9tZSBvciB4aHMtbWNwIGJyb3dzZXInO1xuICAgIH1cblxuICAgIC8vIEZvciB1c2VyLWZhY2luZyBlcnJvcnMsIGp1c3QgcmV0dXJuIHRoZSBtZXNzYWdlIHdpdGhvdXQgc3RhY2sgdHJhY2VcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIGtub3duIGVycm9yIHR5cGUgdGhhdCBzaG91bGQgc2hvdyBqdXN0IHRoZSBtZXNzYWdlXG4gICAgICBpZiAoXG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ0VpdGhlciAtLW5vdGUtaWQgb3IgLS1sYXN0LXB1Ymxpc2hlZCBtdXN0IGJlIHNwZWNpZmllZCcpIHx8XG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ1BsZWFzZSBzcGVjaWZ5IGVpdGhlcicpIHx8XG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ1VzZXIgbm90IGxvZ2dlZCBpbicpIHx8XG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ05vdGUgbm90IGZvdW5kJykgfHxcbiAgICAgICAgZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnRGVsZXRlIGJ1dHRvbiBub3QgZm91bmQnKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBlcnJvci5tZXNzYWdlO1xuICAgICAgfVxuXG4gICAgICAvLyBGb3Igb3RoZXIgZXJyb3JzLCBzaG93IGEgY2xlYW5lciB2ZXJzaW9uXG4gICAgICBjb25zdCBjb25kZW5zZWQgPSByYXdcbiAgICAgICAgLnJlcGxhY2UoXG4gICAgICAgICAgL1tcXHNcXFNdKj9Mb29rcyBsaWtlIFB1cHBldGVlcltcXHNcXFNdKj9QbGVhc2UgcnVuIHRoZSBmb2xsb3dpbmcgY29tbWFuZCB0byBkb3dubG9hZCBuZXcgYnJvd3NlcnM6W1xcc1xcU10qP25weCBwdXBwZXRlZXIgYnJvd3NlcnMgaW5zdGFsbFtcXHNcXFNdKj8oUHVwcGV0ZWVyIFRlYW1bXFxzXFxTXSo/KSo/L20sXG4gICAgICAgICAgJydcbiAgICAgICAgKVxuICAgICAgICAucmVwbGFjZSgvW1xcdTI1MDAtXFx1MjU3Rl0rL2csICcnKSAvLyBib3gtZHJhd2luZyBjaGFyYWN0ZXJzXG4gICAgICAgIC5yZXBsYWNlKC9cXHMrYXRcXHMrLiokL2dtLCAnJykgLy8gUmVtb3ZlIHN0YWNrIHRyYWNlIGxpbmVzXG4gICAgICAgIC50cmltKCk7XG5cbiAgICAgIHJldHVybiBjb25kZW5zZWQgfHwgZXJyb3IubWVzc2FnZTtcbiAgICB9XG5cbiAgICByZXR1cm4gU3RyaW5nKGVycm9yKTtcbiAgfVxuXG4gIHdyaXRlSnNvbihvdXRwdXQ6IHVua25vd24sIGV4aXRDb2RlID0gMCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbXBhY3QgPSB0aGlzLnByb2dyYW0uZ2V0T3B0aW9uVmFsdWU/LignY29tcGFjdCcpID09PSB0cnVlO1xuICAgIGNvbnN0IGpzb24gPSBjb21wYWN0ID8gSlNPTi5zdHJpbmdpZnkob3V0cHV0KSA6IEpTT04uc3RyaW5naWZ5KG91dHB1dCwgbnVsbCwgMik7XG4gICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoYCR7anNvbn1cXG5gKTtcbiAgICAvLyBGbHVzaCBzdGRvdXQgYmVmb3JlIGV4aXRpbmcgdG8gZW5zdXJlIG91dHB1dCBpcyB2aXNpYmxlXG4gICAgaWYgKHByb2Nlc3Muc3Rkb3V0LndyaXRhYmxlKSB7XG4gICAgICBwcm9jZXNzLnN0ZG91dC5lbmQoKTtcbiAgICB9XG4gICAgcHJvY2Vzcy5leGl0KGV4aXRDb2RlKTtcbiAgfVxuXG4gIHByaW50U3VjY2VzcyhyZXN1bHQ6IHVua25vd24sIG1lc3NhZ2U/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAvLyBJZiByZXN1bHQgYWxyZWFkeSBoYXMgc3VjY2VzcyBmaWVsZCwgcHJpbnQgaXQgZGlyZWN0bHlcbiAgICBpZiAocmVzdWx0ICYmIHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnICYmICdzdWNjZXNzJyBpbiByZXN1bHQpIHtcbiAgICAgIHRoaXMud3JpdGVKc29uKHJlc3VsdCwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE90aGVyd2lzZSwgd3JhcCBpdFxuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSA/PyAocmVzdWx0IGFzIHsgbWVzc2FnZT86IHN0cmluZyB9KT8ubWVzc2FnZSA/PyB1bmRlZmluZWQsXG4gICAgICAgIGRhdGE6IHJlc3VsdCxcbiAgICAgIH07XG4gICAgICB0aGlzLndyaXRlSnNvbihwYXlsb2FkLCAwKTtcbiAgICB9XG4gIH1cblxuICBwcmludEVycm9yKGVycm9yOiB1bmtub3duLCBjb2RlPzogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgbWVzc2FnZSA9IHRoaXMuZm9ybWF0RXJyb3JNZXNzYWdlKGVycm9yKTtcbiAgICBjb25zdCBwYXlsb2FkID0geyBzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZSwgY29kZTogY29kZSA/PyB1bmRlZmluZWQsIHN0YXR1czogJ2Vycm9yJyB9IGFzIGNvbnN0O1xuICAgIHRoaXMud3JpdGVKc29uKHBheWxvYWQsIDEpO1xuICB9XG5cbiAgcHJpbnRVc2FnZUVycm9yKGNvbW1hbmQ6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIHN0YXR1czogJ2Vycm9yJyxcbiAgICAgIHVzYWdlOiBgVXNlICd4aHMtbWNwICR7Y29tbWFuZH0gLS1oZWxwJyBmb3IgbW9yZSBpbmZvcm1hdGlvbmAsXG4gICAgfSBhcyBjb25zdDtcbiAgICB0aGlzLndyaXRlSnNvbihwYXlsb2FkLCAxKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBtYWluKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjb25maWcgPSBnZXRDb25maWcoKTtcbiAgY29uc3QgcHJvZ3JhbSA9IG5ldyBDb21tYW5kKCk7XG4gIGNvbnN0IHV0aWxzID0gbmV3IENMSVV0aWxzKHByb2dyYW0pO1xuXG4gIHByb2dyYW1cbiAgICAubmFtZSgneGhzLW1jcCcpXG4gICAgLmRlc2NyaXB0aW9uKCdYaWFvSG9uZ1NodSBDTEkgd2l0aCBzdWJjb21tYW5kcycpXG4gICAgLm9wdGlvbignLS1jb21wYWN0JywgJ091dHB1dCBjb21wYWN0IG9uZS1saW5lIEpTT04gKG5vIHByZXR0eSBwcmludCknKVxuICAgIC5zaG93SGVscEFmdGVyRXJyb3IoKTtcblxuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ2xvZ2luJylcbiAgICAuZGVzY3JpcHRpb24oJ1N0YXJ0IFhpYW9Ib25nU2h1IGxvZ2luIGZsb3cgKG9wZW5zIGJyb3dzZXIsIHNhdmVzIGNvb2tpZXMpJylcbiAgICAub3B0aW9uKCctdCwgLS10aW1lb3V0IDxzZWNvbmRzPicsICdMb2dpbiB0aW1lb3V0IGluIHNlY29uZHMnLCBgJHtjb25maWcuYnJvd3Nlci5sb2dpblRpbWVvdXR9YClcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRzOiB7IHRpbWVvdXQ/OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgY29uc3QgYnJvd3NlclBhdGggPSB1bmRlZmluZWQ7XG4gICAgICBjb25zdCB0aW1lb3V0U2VjID0gb3B0cy50aW1lb3V0ID8gcGFyc2VJbnQob3B0cy50aW1lb3V0LCAxMCkgOiBjb25maWcuYnJvd3Nlci5sb2dpblRpbWVvdXQ7XG4gICAgICBjb25zdCBhdXRoU2VydmljZSA9IG5ldyBBdXRoU2VydmljZShjb25maWcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXV0aFNlcnZpY2UubG9naW4oYnJvd3NlclBhdGgsIHRpbWVvdXRTZWMpO1xuICAgICAgICB1dGlscy5wcmludFN1Y2Nlc3MocmVzdWx0KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHV0aWxzLnByaW50RXJyb3IoZXJyb3IpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnbG9nb3V0JylcbiAgICAuZGVzY3JpcHRpb24oJ0xvZ291dCBmcm9tIFhpYW9Ib25nU2h1IGFuZCBjbGVhciBzYXZlZCBjb29raWVzJylcbiAgICAuYWN0aW9uKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGF1dGhTZXJ2aWNlID0gbmV3IEF1dGhTZXJ2aWNlKGNvbmZpZyk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhdXRoU2VydmljZS5sb2dvdXQoKTtcbiAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ3N0YXR1cycpXG4gICAgLmRlc2NyaXB0aW9uKCdDaGVjayBjdXJyZW50IFhpYW9Ib25nU2h1IGxvZ2luIHN0YXR1cycpXG4gICAgLmFjdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBicm93c2VyUGF0aCA9IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IGF1dGhTZXJ2aWNlID0gbmV3IEF1dGhTZXJ2aWNlKGNvbmZpZyk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhdXRoU2VydmljZS5jaGVja1N0YXR1cyhicm93c2VyUGF0aCk7XG4gICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhyZXN1bHQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCdicm93c2VyJylcbiAgICAuZGVzY3JpcHRpb24oJ0Vuc3VyZSBQdXBwZXRlZXIgQ2hyb21pdW0gaXMgaW5zdGFsbGVkIGFuZCBsYXVuY2hhYmxlOyBpbnN0YWxscyBpZiBtaXNzaW5nJylcbiAgICAub3B0aW9uKCctLXdpdGgtZGVwcycsICdJbnN0YWxsIE9TLWxldmVsIGRlcGVuZGVuY2llcyBhcyB3ZWxsIChtYXkgcmVxdWlyZSBzdWRvKScpXG4gICAgLmFjdGlvbihhc3luYyAob3B0czogeyB3aXRoRGVwcz86IGJvb2xlYW4gfSkgPT4ge1xuICAgICAgYXN5bmMgZnVuY3Rpb24gY2FuTGF1bmNoQ2hyb21pdW0oKTogUHJvbWlzZTx7IGNhbkxhdW5jaDogYm9vbGVhbjsgZXhlY3V0YWJsZVBhdGg/OiBzdHJpbmcgfT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIEdldCB0aGUgZXhlY3V0YWJsZSBwYXRoIGJlZm9yZSBsYXVuY2hpbmdcbiAgICAgICAgICBjb25zdCBleGVjdXRhYmxlUGF0aCA9IHB1cHBldGVlci5leGVjdXRhYmxlUGF0aCgpO1xuXG4gICAgICAgICAgY29uc3QgYnJvd3NlciA9IGF3YWl0IHB1cHBldGVlci5sYXVuY2goeyBoZWFkbGVzczogdHJ1ZSB9KTtcbiAgICAgICAgICBhd2FpdCBicm93c2VyLmNsb3NlKCk7XG5cbiAgICAgICAgICByZXR1cm4geyBjYW5MYXVuY2g6IHRydWUsIGV4ZWN1dGFibGVQYXRoIH07XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHJldHVybiB7IGNhbkxhdW5jaDogZmFsc2UgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBicm93c2VySW5mbyA9IGF3YWl0IGNhbkxhdW5jaENocm9taXVtKCk7XG4gICAgICBpZiAoYnJvd3NlckluZm8uY2FuTGF1bmNoKSB7XG4gICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpbnN0YWxsZWQ6IHRydWUsXG4gICAgICAgICAgICBleGVjdXRhYmxlUGF0aDogYnJvd3NlckluZm8uZXhlY3V0YWJsZVBhdGgsXG4gICAgICAgICAgfSxcbiAgICAgICAgICAnQ2hyb21pdW0gaXMgcmVhZHknXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYXJncyA9IFsncHVwcGV0ZWVyJywgJ2Jyb3dzZXJzJywgJ2luc3RhbGwnLCAnY2hyb21lJ107XG4gICAgICBpZiAob3B0cy53aXRoRGVwcykgYXJncy5wdXNoKCctLXdpdGgtZGVwcycpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gc3Bhd25TeW5jKCducHgnLCBhcmdzLCB7IHN0ZGlvOiAnaW5oZXJpdCcsIGVudjogcHJvY2Vzcy5lbnYgfSk7XG5cbiAgICAgIGNvbnN0IGFmdGVySW5zdGFsbEluZm8gPSBhd2FpdCBjYW5MYXVuY2hDaHJvbWl1bSgpO1xuICAgICAgaWYgKGFmdGVySW5zdGFsbEluZm8uY2FuTGF1bmNoKSB7XG4gICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpbnN0YWxsZWQ6IHRydWUsXG4gICAgICAgICAgICBleGVjdXRhYmxlUGF0aDogYWZ0ZXJJbnN0YWxsSW5mby5leGVjdXRhYmxlUGF0aCxcbiAgICAgICAgICAgIGV4aXRDb2RlOiByZXN1bHQuc3RhdHVzID8/IG51bGwsXG4gICAgICAgICAgfSxcbiAgICAgICAgICAnQ2hyb21pdW0gaW5zdGFsbGVkIGFuZCByZWFkeSdcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHV0aWxzLnByaW50RXJyb3IobmV3IEVycm9yKCdGYWlsZWQgdG8gaW5zdGFsbCBvciBsYXVuY2ggQ2hyb21pdW0nKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgLy8gRmVlZHM6IGRpc2NvdmVyXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnZmVlZHMnKVxuICAgIC5kZXNjcmlwdGlvbignRGlzY292ZXIgaG9tZSBwYWdlIGZlZWRzJylcbiAgICAub3B0aW9uKCctYiwgLS1icm93c2VyLXBhdGggPHBhdGg+JywgJ0N1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJylcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRzOiB7IGJyb3dzZXJQYXRoPzogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IGZlZWRTZXJ2aWNlID0gbmV3IEZlZWRTZXJ2aWNlKGNvbmZpZyk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmZWVkU2VydmljZS5nZXRGZWVkTGlzdChvcHRzLmJyb3dzZXJQYXRoKTtcbiAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAvLyBGZWVkczogc2VhcmNoIG5vdGVcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCdzZWFyY2gnKVxuICAgIC5kZXNjcmlwdGlvbignU2VhcmNoIG5vdGVzIGJ5IGtleXdvcmQnKVxuICAgIC5yZXF1aXJlZE9wdGlvbignLWssIC0ta2V5d29yZCA8a2V5d29yZD4nLCAnU2VhcmNoIGtleXdvcmQnKVxuICAgIC5vcHRpb24oJy1iLCAtLWJyb3dzZXItcGF0aCA8cGF0aD4nLCAnQ3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdHM6IHsga2V5d29yZDogc3RyaW5nOyBicm93c2VyUGF0aD86IHN0cmluZyB9KSA9PiB7XG4gICAgICBjb25zdCBmZWVkU2VydmljZSA9IG5ldyBGZWVkU2VydmljZShjb25maWcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZmVlZFNlcnZpY2Uuc2VhcmNoRmVlZHMob3B0cy5rZXl3b3JkLCBvcHRzLmJyb3dzZXJQYXRoKTtcbiAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAvLyBVc2VyIE5vdGVzOiB1bmlmaWVkIGNvbW1hbmQgd2l0aCBzdWJjb21tYW5kc1xuICBjb25zdCB1c2VyTm90ZUNvbW1hbmQgPSBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ3VzZXJub3RlJylcbiAgICAuZGVzY3JpcHRpb24oXCJDdXJyZW50IHVzZXIncyBub3RlIG1hbmFnZW1lbnQgb3BlcmF0aW9uc1wiKTtcblxuICAvLyBVc2VyIE5vdGUgbGlzdCBzdWJjb21tYW5kXG4gIHVzZXJOb3RlQ29tbWFuZFxuICAgIC5jb21tYW5kKCdsaXN0JylcbiAgICAuZGVzY3JpcHRpb24oXCJMaXN0IGN1cnJlbnQgdXNlcidzIHB1Ymxpc2hlZCBub3Rlc1wiKVxuICAgIC5vcHRpb24oJy1sLCAtLWxpbWl0IDxudW1iZXI+JywgJ01heGltdW0gbnVtYmVyIG9mIG5vdGVzIHRvIHJldHJpZXZlJywgJzIwJylcbiAgICAub3B0aW9uKCctYywgLS1jdXJzb3IgPGN1cnNvcj4nLCAnUGFnaW5hdGlvbiBjdXJzb3IgZm9yIG5leHQgcGFnZScpXG4gICAgLm9wdGlvbignLWIsIC0tYnJvd3Nlci1wYXRoIDxwYXRoPicsICdDdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcpXG4gICAgLmFjdGlvbihhc3luYyAob3B0czogeyBsaW1pdDogc3RyaW5nOyBjdXJzb3I/OiBzdHJpbmc7IGJyb3dzZXJQYXRoPzogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IG5vdGVTZXJ2aWNlID0gbmV3IE5vdGVTZXJ2aWNlKGNvbmZpZyk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBsaW1pdCA9IHBhcnNlSW50KG9wdHMubGltaXQpIHx8IDIwO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBub3RlU2VydmljZS5nZXRVc2VyTm90ZXMobGltaXQsIG9wdHMuY3Vyc29yLCBvcHRzLmJyb3dzZXJQYXRoKTtcbiAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAvLyBVc2VyIE5vdGUgZGVsZXRlIHN1YmNvbW1hbmRcbiAgdXNlck5vdGVDb21tYW5kXG4gICAgLmNvbW1hbmQoJ2RlbGV0ZScpXG4gICAgLmRlc2NyaXB0aW9uKCdEZWxldGUgdXNlciBub3RlcycpXG4gICAgLm9wdGlvbignLS1ub3RlLWlkIDxpZD4nLCAnU3BlY2lmaWMgbm90ZSBJRCB0byBkZWxldGUnKVxuICAgIC5vcHRpb24oJy0tbGFzdC1wdWJsaXNoZWQnLCAnRGVsZXRlIHRoZSBsYXN0IHB1Ymxpc2hlZCBub3RlJylcbiAgICAub3B0aW9uKCctYiwgLS1icm93c2VyLXBhdGggPHBhdGg+JywgJ0N1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJylcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRzOiB7IG5vdGVJZD86IHN0cmluZzsgbGFzdFB1Ymxpc2hlZD86IGJvb2xlYW47IGJyb3dzZXJQYXRoPzogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IG5vdGVTZXJ2aWNlID0gbmV3IE5vdGVTZXJ2aWNlKGNvbmZpZyk7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAob3B0cy5sYXN0UHVibGlzaGVkKSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbm90ZVNlcnZpY2UuZGVsZXRlTGFzdFB1Ymxpc2hlZE5vdGUob3B0cy5icm93c2VyUGF0aCk7XG4gICAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICAgIH0gZWxzZSBpZiAob3B0cy5ub3RlSWQpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBub3RlU2VydmljZS5kZWxldGVOb3RlKG9wdHMubm90ZUlkLCBvcHRzLmJyb3dzZXJQYXRoKTtcbiAgICAgICAgICB1dGlscy5wcmludFN1Y2Nlc3MocmVzdWx0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBTaG93IGhlbHAgaW5zdGVhZCBvZiBKU09OIGVycm9yIHdoZW4gbm8gYXJndW1lbnRzIHByb3ZpZGVkXG4gICAgICAgICAgY29uc29sZS5sb2coJ1VzYWdlOiB4aHMtbWNwIHVzZXJub3RlIGRlbGV0ZSBbb3B0aW9uc11cXG4nKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnRGVsZXRlIHVzZXIgbm90ZXNcXG4nKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnT3B0aW9uczonKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnICAtLW5vdGUtaWQgPGlkPiAgICAgICAgICAgICBTcGVjaWZpYyBub3RlIElEIHRvIGRlbGV0ZScpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCcgIC0tbGFzdC1wdWJsaXNoZWQgICAgICAgICAgIERlbGV0ZSB0aGUgbGFzdCBwdWJsaXNoZWQgbm90ZScpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCcgIC1iLCAtLWJyb3dzZXItcGF0aCA8cGF0aD4gIEN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyk7XG4gICAgICAgICAgY29uc29sZS5sb2coJyAgLWgsIC0taGVscCAgICAgICAgICAgICAgICAgZGlzcGxheSBoZWxwIGZvciBjb21tYW5kJyk7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAvLyBGZWVkczogY29tbWVudCBvbiBub3RlXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnY29tbWVudCcpXG4gICAgLmRlc2NyaXB0aW9uKCdDb21tZW50IG9uIGEgbm90ZScpXG4gICAgLnJlcXVpcmVkT3B0aW9uKCctLWZlZWQtaWQgPGlkPicsICdGZWVkIElEJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy0teHNlYy10b2tlbiA8dG9rZW4+JywgJ1NlY3VyaXR5IHRva2VuIGZvciB0aGUgZmVlZCcpXG4gICAgLnJlcXVpcmVkT3B0aW9uKCctbiwgLS1ub3RlIDx0ZXh0PicsICdDb21tZW50IGNvbnRlbnQnKVxuICAgIC5vcHRpb24oJy1iLCAtLWJyb3dzZXItcGF0aCA8cGF0aD4nLCAnQ3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnKVxuICAgIC5hY3Rpb24oXG4gICAgICBhc3luYyAob3B0czogeyBmZWVkSWQ6IHN0cmluZzsgeHNlY1Rva2VuOiBzdHJpbmc7IG5vdGU6IHN0cmluZzsgYnJvd3NlclBhdGg/OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICBjb25zdCBmZWVkU2VydmljZSA9IG5ldyBGZWVkU2VydmljZShjb25maWcpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZlZWRTZXJ2aWNlLmNvbW1lbnRPbkZlZWQoXG4gICAgICAgICAgICBvcHRzLmZlZWRJZCxcbiAgICAgICAgICAgIG9wdHMueHNlY1Rva2VuLFxuICAgICAgICAgICAgb3B0cy5ub3RlLFxuICAgICAgICAgICAgb3B0cy5icm93c2VyUGF0aFxuICAgICAgICAgICk7XG4gICAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuXG4gIC8vIFB1Ymxpc2hpbmc6IHVuaWZpZWQgcHVibGlzaCBjb21tYW5kXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgncHVibGlzaCcpXG4gICAgLmRlc2NyaXB0aW9uKCdQdWJsaXNoIGNvbnRlbnQgdG8gWGlhb0hvbmdTaHUgKHN1cHBvcnRzIGJvdGggaW1hZ2VzIGFuZCB2aWRlb3MpJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy10LCAtLXR5cGUgPHR5cGU+JywgJ0NvbnRlbnQgdHlwZTogXCJpbWFnZVwiIGZvciBpbWFnZXMsIFwidmlkZW9cIiBmb3IgdmlkZW9zJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy0tdGl0bGUgPHRpdGxlPicsICdDb250ZW50IHRpdGxlICg8PSAyMCBjaGFycyknKVxuICAgIC5yZXF1aXJlZE9wdGlvbignLS1jb250ZW50IDxjb250ZW50PicsICdDb250ZW50IGRlc2NyaXB0aW9uICg8PSAxMDAwIGNoYXJzKScpXG4gICAgLnJlcXVpcmVkT3B0aW9uKFxuICAgICAgJy1tLCAtLW1lZGlhIDxwYXRocz4nLFxuICAgICAgJ0NvbW1hLXNlcGFyYXRlZCBtZWRpYSBmaWxlIHBhdGhzICgxLTE4IGltYWdlcyBmb3IgaW1hZ2UgcG9zdHMsIGV4YWN0bHkgMSB2aWRlbyBmb3IgdmlkZW9zKSdcbiAgICApXG4gICAgLm9wdGlvbignLS10YWdzIDx0YWdzPicsICdDb21tYS1zZXBhcmF0ZWQgdGFncycpXG4gICAgLm9wdGlvbignLWIsIC0tYnJvd3Nlci1wYXRoIDxwYXRoPicsICdDdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcpXG4gICAgLmFjdGlvbihcbiAgICAgIGFzeW5jIChvcHRzOiB7XG4gICAgICAgIHR5cGU6IHN0cmluZztcbiAgICAgICAgdGl0bGU6IHN0cmluZztcbiAgICAgICAgY29udGVudDogc3RyaW5nO1xuICAgICAgICBtZWRpYTogc3RyaW5nO1xuICAgICAgICB0YWdzPzogc3RyaW5nO1xuICAgICAgICBicm93c2VyUGF0aD86IHN0cmluZztcbiAgICAgIH0pID0+IHtcbiAgICAgICAgY29uc3QgcHVibGlzaFNlcnZpY2UgPSBuZXcgUHVibGlzaFNlcnZpY2UoY29uZmlnKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAob3B0cy50eXBlICE9PSAnaW1hZ2UnICYmIG9wdHMudHlwZSAhPT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgdXRpbHMucHJpbnRFcnJvcihuZXcgRXJyb3IoJ1R5cGUgbXVzdCBiZSBcImltYWdlXCIgb3IgXCJ2aWRlb1wiJykpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IG1lZGlhUGF0aHMgPSBvcHRzLm1lZGlhXG4gICAgICAgICAgICAuc3BsaXQoJywnKVxuICAgICAgICAgICAgLm1hcCgocykgPT4gcy50cmltKCkpXG4gICAgICAgICAgICAuZmlsdGVyKEJvb2xlYW4pO1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHB1Ymxpc2hTZXJ2aWNlLnB1Ymxpc2hDb250ZW50KFxuICAgICAgICAgICAgb3B0cy50eXBlLFxuICAgICAgICAgICAgb3B0cy50aXRsZSxcbiAgICAgICAgICAgIG9wdHMuY29udGVudCxcbiAgICAgICAgICAgIG1lZGlhUGF0aHMsXG4gICAgICAgICAgICBvcHRzLnRhZ3MsXG4gICAgICAgICAgICBvcHRzLmJyb3dzZXJQYXRoXG4gICAgICAgICAgKTtcbiAgICAgICAgICB1dGlscy5wcmludFN1Y2Nlc3MocmVzdWx0KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG5cbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCdtY3AnKVxuICAgIC5kZXNjcmlwdGlvbignU3RhcnQgWEhTIE1DUCBzZXJ2ZXIgKHN0ZGlvIG9yIGh0dHAgbW9kZSknKVxuICAgIC5vcHRpb24oJy1tLCAtLW1vZGUgPG1vZGU+JywgJ1NlcnZlciBtb2RlOiBzdGRpbyBvciBodHRwJywgJ3N0ZGlvJylcbiAgICAub3B0aW9uKCctcCwgLS1wb3J0IDxwb3J0PicsICdIVFRQIHNlcnZlciBwb3J0IChvbmx5IGZvciBodHRwIG1vZGUpJywgJzMwMDAnKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdHM6IHsgbW9kZT86IHN0cmluZzsgcG9ydD86IHN0cmluZyB9KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAob3B0cy5tb2RlID09PSAnaHR0cCcpIHtcbiAgICAgICAgICBjb25zdCBwb3J0ID0gb3B0cy5wb3J0ID8gcGFyc2VJbnQob3B0cy5wb3J0LCAxMCkgOiAzMDAwO1xuICAgICAgICAgIGNvbnN0IGh0dHBTZXJ2ZXIgPSBuZXcgWEhTSFRUUE1DUFNlcnZlcihwb3J0KTtcbiAgICAgICAgICBhd2FpdCBodHRwU2VydmVyLnN0YXJ0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gSW4gc3RkaW8gbW9kZSwgd2UgbXVzdCBub3Qgb3V0cHV0IGFueXRoaW5nIHRvIHN0ZG91dC9zdGRlcnIgZXhjZXB0IE1DUCBwcm90b2NvbCBtZXNzYWdlc1xuICAgICAgICAgIC8vIFRoaXMgcHJldmVudHMgaW50ZXJmZXJlbmNlIHdpdGggTUNQIGNvbW11bmljYXRpb25cbiAgICAgICAgICBjb25zdCBzZXJ2ZXIgPSBuZXcgWEhTTUNQU2VydmVyKCk7XG4gICAgICAgICAgYXdhaXQgc2VydmVyLnN0YXJ0KCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIE9ubHkgbG9nIHRvIHN0ZGVyciBpZiBsb2dnaW5nIGlzIGV4cGxpY2l0bHkgZW5hYmxlZFxuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuWEhTX0VOQUJMRV9MT0dHSU5HID09PSAndHJ1ZScpIHtcbiAgICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShgU2VydmVyIGZhaWxlZCB0byBzdGFydDogJHtlcnJvcn1cXG5gKTtcbiAgICAgICAgfVxuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgLy8gTGlzdCBNQ1AgdG9vbHNcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCd0b29scycpXG4gICAgLmRlc2NyaXB0aW9uKCdMaXN0IGF2YWlsYWJsZSBNQ1AgdG9vbHMnKVxuICAgIC5vcHRpb24oJy1qLCAtLWpzb24nLCAnT3V0cHV0IGluIEpTT04gZm9ybWF0JylcbiAgICAub3B0aW9uKCctZCwgLS1kZXRhaWxlZCcsICdTaG93IGRldGFpbGVkIHRvb2wgaW5mb3JtYXRpb24nKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdHM6IHsganNvbj86IGJvb2xlYW47IGRldGFpbGVkPzogYm9vbGVhbiB9KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0b29sU2NoZW1hcyA9IFhIU19UT09MX1NDSEVNQVM7XG5cbiAgICAgICAgaWYgKG9wdHMuanNvbikge1xuICAgICAgICAgIGlmIChvcHRzLmRldGFpbGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeSh0b29sU2NoZW1hcywgbnVsbCwgMikpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0b29sTmFtZXMgPSB0b29sU2NoZW1hcy5tYXAoKHRvb2wpID0+ICh7XG4gICAgICAgICAgICAgIG5hbWU6IHRvb2wubmFtZSxcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHRvb2wuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeSh0b29sTmFtZXMsIG51bGwsIDIpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ1xcbvCfk4sgQXZhaWxhYmxlIE1DUCBUb29sczpcXG4nKTtcblxuICAgICAgICAgIHRvb2xTY2hlbWFzLmZvckVhY2goKHRvb2wsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgJHtpbmRleCArIDF9LiAke3Rvb2wubmFtZX1gKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGAgICAke3Rvb2wuZGVzY3JpcHRpb259YCk7XG5cbiAgICAgICAgICAgIGlmIChvcHRzLmRldGFpbGVkKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlcXVpcmVkID0gdG9vbC5pbnB1dFNjaGVtYS5yZXF1aXJlZCA/PyBbXTtcbiAgICAgICAgICAgICAgY29uc3QgcHJvcGVydGllcyA9IHRvb2wuaW5wdXRTY2hlbWEucHJvcGVydGllcyA/PyB7fTtcblxuICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMocHJvcGVydGllcykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCcgICBQYXJhbWV0ZXJzOicpO1xuICAgICAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHByb3BlcnRpZXMpLmZvckVhY2goKFtrZXksIHByb3BdOiBbc3RyaW5nLCB1bmtub3duXSkgPT4ge1xuICAgICAgICAgICAgICAgICAgY29uc3QgcmVxdWlyZWRNYXJrID0gcmVxdWlyZWQuaW5jbHVkZXMoa2V5KSA/ICcgKHJlcXVpcmVkKScgOiAnIChvcHRpb25hbCknO1xuICAgICAgICAgICAgICAgICAgY29uc3QgcHJvcERlc2MgPSAocHJvcCBhcyB7IGRlc2NyaXB0aW9uPzogc3RyaW5nIH0pLmRlc2NyaXB0aW9uO1xuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYCAgICAgLSAke2tleX06ICR7cHJvcERlc2MgPz8gJ05vIGRlc2NyaXB0aW9uJ30ke3JlcXVpcmVkTWFya31gKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc29sZS5sb2coYFRvdGFsOiAke3Rvb2xTY2hlbWFzLmxlbmd0aH0gdG9vbHMgYXZhaWxhYmxlYCk7XG4gICAgICAgICAgY29uc29sZS5sb2coJ1xcblVzZSAtLWRldGFpbGVkIGZvciBwYXJhbWV0ZXIgaW5mb3JtYXRpb24nKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnVXNlIC0tanNvbiBmb3IgbWFjaGluZS1yZWFkYWJsZSBvdXRwdXQnKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgcHJvZ3JhbS5wYXJzZUFzeW5jKHByb2Nlc3MuYXJndik7XG59XG5cbi8vIEhhbmRsZSBncmFjZWZ1bCBzaHV0ZG93biBmb3IgTUNQIHNlcnZlciBtb2RlXG5wcm9jZXNzLm9uKCdTSUdJTlQnLCAoKSA9PiB7XG4gIC8vIERvbid0IGxvZyB0byBzdGRlcnIgaW4gc3RkaW8gbW9kZSB0byBhdm9pZCBpbnRlcmZlcmluZyB3aXRoIE1DUCBwcm90b2NvbFxuICBwcm9jZXNzLmV4aXQoMCk7XG59KTtcblxucHJvY2Vzcy5vbignU0lHVEVSTScsICgpID0+IHtcbiAgLy8gRG9uJ3QgbG9nIHRvIHN0ZGVyciBpbiBzdGRpbyBtb2RlIHRvIGF2b2lkIGludGVyZmVyaW5nIHdpdGggTUNQIHByb3RvY29sXG4gIHByb2Nlc3MuZXhpdCgwKTtcbn0pO1xuXG4vLyBTdGFydCB0aGUgQ0xJXG5tYWluKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gIC8vIE9ubHkgbG9nIHRvIHN0ZGVyciBpZiBsb2dnaW5nIGlzIGV4cGxpY2l0bHkgZW5hYmxlZFxuICBpZiAocHJvY2Vzcy5lbnYuWEhTX0VOQUJMRV9MT0dHSU5HID09PSAndHJ1ZScpIHtcbiAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShgRmF0YWwgZXJyb3I6ICR7ZXJyb3J9XFxuYCk7XG4gIH1cbiAgcHJvY2Vzcy5leGl0KDEpO1xufSk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5582\n\n}");
95
+
96
+ /***/ }),
97
+
98
+ /***/ 6928:
99
+ /***/ ((module) => {
100
+
101
+ module.exports = require("path");
102
+
103
+ /***/ }),
104
+
105
+ /***/ 7016:
106
+ /***/ ((module) => {
107
+
108
+ module.exports = require("url");
109
+
110
+ /***/ }),
111
+
112
+ /***/ 7598:
113
+ /***/ ((module) => {
114
+
115
+ module.exports = require("node:crypto");
116
+
117
+ /***/ }),
118
+
119
+ /***/ 7636:
120
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
121
+
122
+ eval("{/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ EE: () => (/* binding */ BrowserLaunchError),\n/* harmony export */ GU: () => (/* binding */ DeleteError),\n/* harmony export */ H7: () => (/* binding */ LoginTimeoutError),\n/* harmony export */ Jk: () => (/* binding */ BrowserNavigationError),\n/* harmony export */ S1: () => (/* binding */ PublishError),\n/* harmony export */ TD: () => (/* binding */ InvalidImageError),\n/* harmony export */ TG: () => (/* binding */ FeedParsingError),\n/* harmony export */ Vb: () => (/* binding */ NoteParsingError),\n/* harmony export */ aW: () => (/* binding */ FeedNotFoundError),\n/* harmony export */ a_: () => (/* binding */ XHSError),\n/* harmony export */ bG: () => (/* binding */ NotLoggedInError),\n/* harmony export */ f6: () => (/* binding */ LoginFailedError),\n/* harmony export */ lS: () => (/* binding */ FeedError)\n/* harmony export */ });\n/* unused harmony exports AuthenticationError, BrowserError, PublishFailedError, NoteError, ProfileError */\n/**\n * Error classes for XHS MCP Server\n */\nclass XHSError extends Error {\n errorCode;\n context;\n originalError;\n constructor(message, errorCode, context, originalError) {\n super(message);\n this.name = 'XHSError';\n this.errorCode = errorCode ?? this.constructor.name;\n this.context = context ?? {};\n this.originalError = originalError;\n }\n toJSON() {\n const result = {\n success: false,\n error: this.errorCode,\n message: this.message,\n context: this.originalError\n ? { ...this.context, originalError: this.originalError.message }\n : this.context,\n };\n return result;\n }\n}\nclass AuthenticationError extends XHSError {\n constructor(message, context, originalError) {\n super(message, 'AuthenticationError', context, originalError);\n }\n}\nclass LoginTimeoutError extends AuthenticationError {\n constructor(message, context, originalError) {\n super(message, context, originalError);\n }\n}\nclass LoginFailedError extends AuthenticationError {\n constructor(message, context, originalError) {\n super(message, context, originalError);\n }\n}\nclass NotLoggedInError extends AuthenticationError {\n constructor(message, context, originalError) {\n super(message, context, originalError);\n }\n}\nclass BrowserError extends XHSError {\n constructor(message, context, originalError) {\n super(message, 'BrowserError', context, originalError);\n }\n}\nclass BrowserLaunchError extends BrowserError {\n constructor(message, context, originalError) {\n super(message, context, originalError);\n }\n}\nclass BrowserNavigationError extends BrowserError {\n constructor(message, context, originalError) {\n super(message, context, originalError);\n }\n}\nclass FeedError extends XHSError {\n constructor(message, context, originalError) {\n super(message, 'FeedError', context, originalError);\n }\n}\nclass FeedNotFoundError extends FeedError {\n constructor(message, context, originalError) {\n super(message, context, originalError);\n }\n}\nclass FeedParsingError extends FeedError {\n constructor(message, context, originalError) {\n super(message, context, originalError);\n }\n}\nclass PublishError extends XHSError {\n constructor(message, context, originalError) {\n super(message, 'PublishError', context, originalError);\n }\n}\nclass InvalidImageError extends PublishError {\n constructor(message, context, originalError) {\n super(message, context, originalError);\n }\n}\nclass PublishFailedError extends PublishError {\n constructor(message, context, originalError) {\n super(message, context, originalError);\n }\n}\nclass NoteError extends XHSError {\n constructor(message, context, originalError) {\n super(message, 'NoteError', context, originalError);\n }\n}\nclass ProfileError extends NoteError {\n constructor(message, context, originalError) {\n super(message, context, originalError);\n }\n}\nclass NoteParsingError extends NoteError {\n constructor(message, context, originalError) {\n super(message, context, originalError);\n }\n}\nclass DeleteError extends XHSError {\n constructor(message, context, originalError) {\n super(message, 'DeleteError', context, originalError);\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQztJQUN6QyxDQUFDO0NBQ0Y7QUFFTSxNQUFNLGdCQUFpQixTQUFRLFNBQVM7SUFDN0MsWUFBWSxPQUFlLEVBQUUsT0FBeUIsRUFBRSxhQUFxQjtRQUMzRSxLQUFLLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQztJQUN6QyxDQUFDO0NBQ0Y7QUFFTSxNQUFNLFdBQVksU0FBUSxRQUFRO0lBQ3ZDLFlBQVksT0FBZSxFQUFFLE9BQXlCLEVBQUUsYUFBcUI7UUFDM0UsS0FBSyxDQUFDLE9BQU8sRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ3hELENBQUM7Q0FDRiIsInNvdXJjZXMiOlsid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2hhcmVkL2Vycm9ycy50cz9hOTMxIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRXJyb3IgY2xhc3NlcyBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG5pbXBvcnQgeyBYSFNSZXNwb25zZSwgWEhTRXJyb3JDb250ZXh0IH0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBYSFNFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgcHVibGljIHJlYWRvbmx5IGVycm9yQ29kZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgY29udGV4dDogWEhTRXJyb3JDb250ZXh0O1xuICBwdWJsaWMgcmVhZG9ubHkgb3JpZ2luYWxFcnJvcj86IEVycm9yO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICBlcnJvckNvZGU/OiBzdHJpbmcsXG4gICAgY29udGV4dD86IFhIU0Vycm9yQ29udGV4dCxcbiAgICBvcmlnaW5hbEVycm9yPzogRXJyb3JcbiAgKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gJ1hIU0Vycm9yJztcbiAgICB0aGlzLmVycm9yQ29kZSA9IGVycm9yQ29kZSA/PyB0aGlzLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dCA/PyB7fTtcbiAgICB0aGlzLm9yaWdpbmFsRXJyb3IgPSBvcmlnaW5hbEVycm9yO1xuICB9XG5cbiAgdG9KU09OKCk6IFhIU1Jlc3BvbnNlIHtcbiAgICBjb25zdCByZXN1bHQ6IFhIU1Jlc3BvbnNlID0ge1xuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBlcnJvcjogdGhpcy5lcnJvckNvZGUsXG4gICAgICBtZXNzYWdlOiB0aGlzLm1lc3NhZ2UsXG4gICAgICBjb250ZXh0OiB0aGlzLm9yaWdpbmFsRXJyb3JcbiAgICAgICAgPyB7IC4uLnRoaXMuY29udGV4dCwgb3JpZ2luYWxFcnJvcjogdGhpcy5vcmlnaW5hbEVycm9yLm1lc3NhZ2UgfVxuICAgICAgICA6IHRoaXMuY29udGV4dCxcbiAgICB9O1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEF1dGhlbnRpY2F0aW9uRXJyb3IgZXh0ZW5kcyBYSFNFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgY29udGV4dD86IFhIU0Vycm9yQ29udGV4dCwgb3JpZ2luYWxFcnJvcj86IEVycm9yKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgJ0F1dGhlbnRpY2F0aW9uRXJyb3InLCBjb250ZXh0LCBvcmlnaW5hbEVycm9yKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTG9naW5UaW1lb3V0RXJyb3IgZXh0ZW5kcyBBdXRoZW50aWNhdGlvbkVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nLCBjb250ZXh0PzogWEhTRXJyb3JDb250ZXh0LCBvcmlnaW5hbEVycm9yPzogRXJyb3IpIHtcbiAgICBzdXBlcihtZXNzYWdlLCBjb250ZXh0LCBvcmlnaW5hbEVycm9yKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTG9naW5GYWlsZWRFcnJvciBleHRlbmRzIEF1dGhlbnRpY2F0aW9uRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcsIGNvbnRleHQ/OiBYSFNFcnJvckNvbnRleHQsIG9yaWdpbmFsRXJyb3I/OiBFcnJvcikge1xuICAgIHN1cGVyKG1lc3NhZ2UsIGNvbnRleHQsIG9yaWdpbmFsRXJyb3IpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBOb3RMb2dnZWRJbkVycm9yIGV4dGVuZHMgQXV0aGVudGljYXRpb25FcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgY29udGV4dD86IFhIU0Vycm9yQ29udGV4dCwgb3JpZ2luYWxFcnJvcj86IEVycm9yKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgY29udGV4dCwgb3JpZ2luYWxFcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEJyb3dzZXJFcnJvciBleHRlbmRzIFhIU0Vycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nLCBjb250ZXh0PzogWEhTRXJyb3JDb250ZXh0LCBvcmlnaW5hbEVycm9yPzogRXJyb3IpIHtcbiAgICBzdXBlcihtZXNzYWdlLCAnQnJvd3NlckVycm9yJywgY29udGV4dCwgb3JpZ2luYWxFcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEJyb3dzZXJMYXVuY2hFcnJvciBleHRlbmRzIEJyb3dzZXJFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgY29udGV4dD86IFhIU0Vycm9yQ29udGV4dCwgb3JpZ2luYWxFcnJvcj86IEVycm9yKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgY29udGV4dCwgb3JpZ2luYWxFcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEJyb3dzZXJOYXZpZ2F0aW9uRXJyb3IgZXh0ZW5kcyBCcm93c2VyRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcsIGNvbnRleHQ/OiBYSFNFcnJvckNvbnRleHQsIG9yaWdpbmFsRXJyb3I/OiBFcnJvcikge1xuICAgIHN1cGVyKG1lc3NhZ2UsIGNvbnRleHQsIG9yaWdpbmFsRXJyb3IpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGZWVkRXJyb3IgZXh0ZW5kcyBYSFNFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgY29udGV4dD86IFhIU0Vycm9yQ29udGV4dCwgb3JpZ2luYWxFcnJvcj86IEVycm9yKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgJ0ZlZWRFcnJvcicsIGNvbnRleHQsIG9yaWdpbmFsRXJyb3IpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGZWVkTm90Rm91bmRFcnJvciBleHRlbmRzIEZlZWRFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgY29udGV4dD86IFhIU0Vycm9yQ29udGV4dCwgb3JpZ2luYWxFcnJvcj86IEVycm9yKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgY29udGV4dCwgb3JpZ2luYWxFcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEZlZWRQYXJzaW5nRXJyb3IgZXh0ZW5kcyBGZWVkRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcsIGNvbnRleHQ/OiBYSFNFcnJvckNvbnRleHQsIG9yaWdpbmFsRXJyb3I/OiBFcnJvcikge1xuICAgIHN1cGVyKG1lc3NhZ2UsIGNvbnRleHQsIG9yaWdpbmFsRXJyb3IpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQdWJsaXNoRXJyb3IgZXh0ZW5kcyBYSFNFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgY29udGV4dD86IFhIU0Vycm9yQ29udGV4dCwgb3JpZ2luYWxFcnJvcj86IEVycm9yKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgJ1B1Ymxpc2hFcnJvcicsIGNvbnRleHQsIG9yaWdpbmFsRXJyb3IpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBJbnZhbGlkSW1hZ2VFcnJvciBleHRlbmRzIFB1Ymxpc2hFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgY29udGV4dD86IFhIU0Vycm9yQ29udGV4dCwgb3JpZ2luYWxFcnJvcj86IEVycm9yKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgY29udGV4dCwgb3JpZ2luYWxFcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFB1Ymxpc2hGYWlsZWRFcnJvciBleHRlbmRzIFB1Ymxpc2hFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgY29udGV4dD86IFhIU0Vycm9yQ29udGV4dCwgb3JpZ2luYWxFcnJvcj86IEVycm9yKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgY29udGV4dCwgb3JpZ2luYWxFcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIE5vdGVFcnJvciBleHRlbmRzIFhIU0Vycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nLCBjb250ZXh0PzogWEhTRXJyb3JDb250ZXh0LCBvcmlnaW5hbEVycm9yPzogRXJyb3IpIHtcbiAgICBzdXBlcihtZXNzYWdlLCAnTm90ZUVycm9yJywgY29udGV4dCwgb3JpZ2luYWxFcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFByb2ZpbGVFcnJvciBleHRlbmRzIE5vdGVFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgY29udGV4dD86IFhIU0Vycm9yQ29udGV4dCwgb3JpZ2luYWxFcnJvcj86IEVycm9yKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgY29udGV4dCwgb3JpZ2luYWxFcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIE5vdGVQYXJzaW5nRXJyb3IgZXh0ZW5kcyBOb3RlRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcsIGNvbnRleHQ/OiBYSFNFcnJvckNvbnRleHQsIG9yaWdpbmFsRXJyb3I/OiBFcnJvcikge1xuICAgIHN1cGVyKG1lc3NhZ2UsIGNvbnRleHQsIG9yaWdpbmFsRXJyb3IpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEZWxldGVFcnJvciBleHRlbmRzIFhIU0Vycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nLCBjb250ZXh0PzogWEhTRXJyb3JDb250ZXh0LCBvcmlnaW5hbEVycm9yPzogRXJyb3IpIHtcbiAgICBzdXBlcihtZXNzYWdlLCAnRGVsZXRlRXJyb3InLCBjb250ZXh0LCBvcmlnaW5hbEVycm9yKTtcbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7636\n\n}");
123
+
124
+ /***/ }),
125
+
126
+ /***/ 9023:
127
+ /***/ ((module) => {
128
+
129
+ module.exports = require("util");
130
+
131
+ /***/ }),
132
+
133
+ /***/ 9113:
134
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
135
+
136
+ eval("{\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n NoteService: () => (/* binding */ NoteService)\n});\n\n// EXTERNAL MODULE: ./src/shared/base.service.ts\nvar base_service = __webpack_require__(103);\n// EXTERNAL MODULE: ./src/shared/logger.ts\nvar logger = __webpack_require__(9135);\n// EXTERNAL MODULE: ./src/shared/errors.ts\nvar errors = __webpack_require__(7636);\n// EXTERNAL MODULE: ./src/shared/utils.ts\nvar utils = __webpack_require__(2094);\n;// ./src/shared/creator-center.ts\n/**\n * Shared helpers for Creator Center page operations\n */\n\n\nconst CREATOR_CENTER_URL = 'https://creator.xiaohongshu.com/new/note-manager?source=official';\nasync function navigateToCreatorCenter(page) {\n try {\n await page.goto(CREATOR_CENTER_URL, { waitUntil: 'load', timeout: 30000 });\n await (0,utils/* sleep */.yy)(3000);\n }\n catch (error) {\n throw new errors/* XHSError */.a_('Failed to navigate to creator center', 'CreatorCenterError', { url: CREATOR_CENTER_URL }, error instanceof Error ? error : new Error(String(error)));\n }\n}\nasync function verifyCreatorAuth(page, loginOkSelector) {\n try {\n const loginElements = await page.$$(loginOkSelector);\n const creatorElements = await page.$$('[class*=\"user\"], [class*=\"profile\"], [class*=\"avatar\"]');\n if (loginElements.length === 0 && creatorElements.length === 0) {\n const currentUrl = page.url();\n if (currentUrl.includes('login') || currentUrl.includes('signin')) {\n throw new errors/* NotLoggedInError */.bG('User not logged in', { url: currentUrl });\n }\n const noteElements = await page.$$('div.note');\n if (noteElements.length === 0) {\n throw new errors/* NotLoggedInError */.bG('User not logged in or no notes found', { url: currentUrl });\n }\n }\n }\n catch (error) {\n if (error instanceof errors/* NotLoggedInError */.bG) {\n throw error;\n }\n throw new errors/* XHSError */.a_('Failed to verify authentication', 'CreatorCenterError', { operation: 'verifyAuth' }, error instanceof Error ? error : new Error(String(error)));\n }\n}\n\n// EXTERNAL MODULE: ./src/shared/selectors.ts\nvar selectors = __webpack_require__(805);\n;// ./src/core/deleting/delete.service.ts\n/**\n * Delete service for XHS MCP Server\n * Handles note deletion operations\n */\n\n\n\n\n\n\n/**\n * CSS selectors for delete operations - updated for current XiaoHongShu interface\n */\nconst DELETE_SELECTORS = {\n NOTE_ITEM: [\n 'div.note',\n '.note-item',\n '[class*=\"note\"]',\n '[data-impression]',\n '.creator-note-item',\n '.note-card',\n '.content-item'\n ],\n DELETE_BUTTON: [\n '.control.data-del',\n 'span.control.data-del',\n ...selectors/* COMMON_BUTTON_SELECTORS */.ox.DELETE\n ],\n CONFIRM_BUTTON: selectors/* COMMON_BUTTON_SELECTORS */.ox.CONFIRM,\n CANCEL_BUTTON: selectors/* COMMON_BUTTON_SELECTORS */.ox.CANCEL,\n MORE_OPTIONS: selectors/* COMMON_BUTTON_SELECTORS */.ox.MORE_OPTIONS,\n DROPDOWN_MENU: selectors/* COMMON_MODAL_SELECTORS */.TK.DROPDOWN_MENU,\n MODAL_CONFIRM: selectors/* COMMON_MODAL_SELECTORS */.TK.CONFIRM,\n MODAL_CANCEL: selectors/* COMMON_MODAL_SELECTORS */.TK.CANCEL,\n};\nclass DeleteService extends base_service/* BaseService */.d {\n constructor(config, browserManager) {\n super(config, browserManager);\n }\n /**\n * Delete a specific note by ID\n * @param noteId - The ID of the note to delete\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteNote(noteId, browserPath) {\n this.validateDeleteParams(noteId);\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n // Navigate to creator center note manager\n await navigateToCreatorCenter(page);\n await verifyCreatorAuth(page, this.getConfig().xhs.loginOkSelector);\n // Find and delete the specific note\n const result = await this.findAndDeleteNote(page, noteId);\n return {\n success: true,\n data: null,\n noteId: result.noteId,\n title: result.title,\n deletedAt: Date.now(),\n message: `Successfully deleted note \"${result.title}\" (ID: ${result.noteId})`,\n operation: 'deleteNote',\n };\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to delete note ${noteId}: ${error}`);\n return {\n success: false,\n data: null,\n error: error instanceof Error ? error.message : String(error),\n message: `Failed to delete note: ${error instanceof Error ? error.message : String(error)}`,\n deletedAt: Date.now(),\n operation: 'deleteNote',\n };\n }\n finally {\n await page.close();\n }\n }\n /**\n * Delete the last published note\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteLastPublishedNote(browserPath) {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n // Navigate to creator center note manager\n await navigateToCreatorCenter(page);\n await verifyCreatorAuth(page, this.getConfig().xhs.loginOkSelector);\n // Find and delete the last published note\n const result = await this.findAndDeleteLastNote(page);\n return {\n success: true,\n data: null,\n noteId: result.noteId,\n title: result.title,\n deletedAt: Date.now(),\n message: `Successfully deleted last published note \"${result.title}\" (ID: ${result.noteId})`,\n operation: 'deleteLastPublishedNote',\n };\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to delete last published note: ${error}`);\n return {\n success: false,\n data: null,\n error: error instanceof Error ? error.message : String(error),\n message: `Failed to delete last published note: ${error instanceof Error ? error.message : String(error)}`,\n deletedAt: Date.now(),\n operation: 'deleteLastPublishedNote',\n };\n }\n finally {\n await page.close();\n }\n }\n /**\n * Validate delete parameters\n */\n validateDeleteParams(noteId) {\n if (!noteId || noteId.trim().length === 0) {\n throw new errors/* DeleteError */.GU('Note ID is required', { noteId });\n }\n }\n /**\n * Find and delete a specific note by ID\n */\n async findAndDeleteNote(page, noteId) {\n try {\n // Step 1: Locate the note and try to find a direct delete button or more-options button\n const result = await page.evaluate((selectors, targetNoteId) => {\n let noteElements = [];\n for (const selector of selectors.NOTE_ITEM) {\n const elements = Array.from(document.querySelectorAll(selector));\n if (elements.length > 0) {\n noteElements = elements;\n break;\n }\n }\n if (noteElements.length === 0) {\n return { noteId: targetNoteId, title: '', found: false, error: 'No note elements found on page' };\n }\n for (const noteElement of noteElements) {\n const impressionData = noteElement.getAttribute('data-impression');\n let currentNoteId = '';\n if (impressionData) {\n try {\n const parsed = JSON.parse(impressionData);\n currentNoteId = parsed?.noteTarget?.value?.noteId || '';\n }\n catch {\n // Ignore parsing errors\n }\n }\n if (!currentNoteId) {\n const linkElement = noteElement.querySelector('a[href*=\"/explore/\"], a[href*=\"/note/\"]');\n if (linkElement) {\n const href = linkElement.getAttribute('href') || '';\n const match = href.match(/\\/explore\\/([a-zA-Z0-9]+)/);\n if (match) {\n currentNoteId = match[1];\n }\n }\n }\n if (currentNoteId === targetNoteId) {\n const titleElement = noteElement.querySelector('[class*=\"title\"], [class*=\"name\"]');\n const title = titleElement?.textContent?.trim() || 'Unknown';\n // Try to find a direct delete button first\n for (const selector of selectors.DELETE_BUTTON) {\n const deleteButton = noteElement.querySelector(selector);\n if (deleteButton) {\n deleteButton.click();\n return { noteId: currentNoteId, title, found: true, needsDropdown: false };\n }\n }\n // No direct delete button — check for a more-options button\n for (const selector of selectors.MORE_OPTIONS) {\n const moreButton = noteElement.querySelector(selector);\n if (moreButton) {\n moreButton.click();\n return { noteId: currentNoteId, title, found: true, needsDropdown: true };\n }\n }\n return { noteId: currentNoteId, title, found: false, error: 'Delete button not found' };\n }\n }\n return { noteId: targetNoteId, title: '', found: false, error: 'Note not found' };\n }, DELETE_SELECTORS, noteId);\n if (!result.found) {\n throw new errors/* DeleteError */.GU(result.error || 'Note not found', { noteId });\n }\n // Step 2: If we clicked \"more options\", wait for dropdown then click delete in it\n if (result.needsDropdown) {\n await (0,utils/* sleep */.yy)(1000);\n let clicked = false;\n for (const selector of DELETE_SELECTORS.DROPDOWN_MENU) {\n const dropdown = await page.$(selector);\n if (dropdown) {\n for (const deleteSelector of DELETE_SELECTORS.DELETE_BUTTON) {\n const deleteBtn = await dropdown.$(deleteSelector);\n if (deleteBtn) {\n await deleteBtn.click();\n clicked = true;\n break;\n }\n }\n if (clicked)\n break;\n }\n }\n if (!clicked) {\n throw new errors/* DeleteError */.GU('Delete button not found in dropdown menu', { noteId });\n }\n }\n await (0,utils/* sleep */.yy)(1000);\n await this.handleConfirmationDialog(page);\n return { noteId: result.noteId, title: result.title };\n }\n catch (error) {\n throw new errors/* DeleteError */.GU('Failed to find and delete note', { noteId }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Find and delete the last published note\n */\n async findAndDeleteLastNote(page) {\n try {\n const result = await page.evaluate((selectors) => {\n // Try each note item selector\n let noteElements = [];\n for (const selector of selectors.NOTE_ITEM) {\n const elements = Array.from(document.querySelectorAll(selector));\n if (elements.length > 0) {\n noteElements = elements;\n break;\n }\n }\n if (noteElements.length === 0) {\n return { noteId: '', title: '', found: false, error: 'No notes found' };\n }\n // Get the first note (most recent)\n const firstNote = noteElements[0];\n // Extract note ID\n let noteId = '';\n const impressionData = firstNote.getAttribute('data-impression');\n if (impressionData) {\n try {\n const parsed = JSON.parse(impressionData);\n noteId = parsed?.noteTarget?.value?.noteId || '';\n }\n catch (e) {\n // Ignore parsing errors\n }\n }\n // Also try to find note ID in link\n if (!noteId) {\n const linkElement = firstNote.querySelector('a[href*=\"/explore/\"], a[href*=\"/note/\"]');\n if (linkElement) {\n const href = linkElement.getAttribute('href') || '';\n const match = href.match(/\\/explore\\/([a-zA-Z0-9]+)/);\n if (match) {\n noteId = match[1];\n }\n }\n }\n // Extract title\n const titleElement = firstNote.querySelector('[class*=\"title\"], [class*=\"name\"]');\n const title = titleElement?.textContent?.trim() || 'Unknown';\n // Try to find a direct delete button first\n for (const selector of selectors.DELETE_BUTTON) {\n const deleteButton = firstNote.querySelector(selector);\n if (deleteButton) {\n deleteButton.click();\n return { noteId, title, found: true, needsDropdown: false };\n }\n }\n // No direct delete button — check for a more-options button\n for (const selector of selectors.MORE_OPTIONS) {\n const moreButton = firstNote.querySelector(selector);\n if (moreButton) {\n moreButton.click();\n return { noteId, title, found: true, needsDropdown: true };\n }\n }\n return { noteId, title, found: false, error: 'Delete button not found' };\n }, DELETE_SELECTORS);\n if (!result.found) {\n throw new errors/* DeleteError */.GU(result.error || 'Failed to find delete button', {});\n }\n // If we clicked \"more options\", wait for dropdown then click delete in it\n if (result.needsDropdown) {\n await (0,utils/* sleep */.yy)(1000);\n let clicked = false;\n for (const selector of DELETE_SELECTORS.DROPDOWN_MENU) {\n const dropdown = await page.$(selector);\n if (dropdown) {\n for (const deleteSelector of DELETE_SELECTORS.DELETE_BUTTON) {\n const deleteBtn = await dropdown.$(deleteSelector);\n if (deleteBtn) {\n await deleteBtn.click();\n clicked = true;\n break;\n }\n }\n if (clicked)\n break;\n }\n }\n if (!clicked) {\n throw new errors/* DeleteError */.GU('Delete button not found in dropdown menu', {});\n }\n }\n // Wait for confirmation dialog if it appears\n await (0,utils/* sleep */.yy)(1000);\n // Handle confirmation dialog\n await this.handleConfirmationDialog(page);\n return { noteId: result.noteId, title: result.title };\n }\n catch (error) {\n throw new errors/* DeleteError */.GU('Failed to find and delete last note', {}, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Handle confirmation dialog for delete operation\n */\n async handleConfirmationDialog(page) {\n try {\n // Wait for confirmation dialog to appear\n await (0,utils/* sleep */.yy)(2000);\n // Look for confirmation buttons using all possible selectors\n let confirmButton = null;\n // Try each confirm button selector\n for (const selector of DELETE_SELECTORS.CONFIRM_BUTTON) {\n confirmButton = await page.$(selector);\n if (confirmButton) {\n logger/* logger */.v.info(`Found confirm button with selector: ${selector}`);\n break;\n }\n }\n // If not found, try modal confirm selectors\n if (!confirmButton) {\n for (const selector of DELETE_SELECTORS.MODAL_CONFIRM) {\n confirmButton = await page.$(selector);\n if (confirmButton) {\n logger/* logger */.v.info(`Found modal confirm button with selector: ${selector}`);\n break;\n }\n }\n }\n if (confirmButton) {\n logger/* logger */.v.info('Clicking confirmation button');\n await confirmButton.click();\n await (0,utils/* sleep */.yy)(2000);\n }\n else {\n // If no confirmation dialog, the delete might have been immediate\n logger/* logger */.v.info('No confirmation dialog found, delete might be immediate');\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to handle confirmation dialog: ${error}`);\n // Continue anyway as the delete might still work\n }\n }\n}\n\n;// ./src/core/notes/note.service.ts\n/**\n * Note service for XHS MCP Server\n * Handles user notes/feeds operations\n */\n\n\n\n\n\n/**\n * CSS selectors for note extraction from Creator Center\n */\nconst NOTE_SELECTORS = {\n NOTE_ELEMENTS: 'div.note',\n TITLE_ELEMENTS: '[class*=\"raw\"], [class*=\"title\"], [class*=\"name\"]',\n IMAGE_ELEMENTS: 'img[class*=\"media\"], img[class*=\"cover\"], img[class*=\"thumbnail\"]',\n STAT_ELEMENTS: '[class*=\"count\"], [class*=\"stat\"], [class*=\"number\"]',\n TAG_ELEMENTS: '[class*=\"tag\"], [class*=\"label\"]',\n NOTE_LINK: 'a[href*=\"/explore/\"], a[href*=\"/note/\"]',\n VISIBILITY_INDICATORS: '[class*=\"private\"], [class*=\"visibility\"], [class*=\"lock\"], [class*=\"eye\"], [class*=\"public\"], [class*=\"friends\"], [class*=\"status\"]',\n PUBLISH_TIME: '[class*=\"time\"], [class*=\"date\"], [class*=\"publish-time\"]',\n};\nclass NoteService extends base_service/* BaseService */.d {\n deleteService;\n constructor(config, browserManager) {\n super(config, browserManager);\n this.deleteService = new DeleteService(config, this.browserManager);\n }\n /**\n * Get current user's published notes from creator center\n * @param limit - Maximum number of notes to return (default: 20)\n * @param cursor - Pagination cursor for next page\n * @param browserPath - Optional custom browser path\n * @returns Promise<UserNotesResult> - User notes with pagination info\n */\n async getUserNotes(limit = 20, cursor, browserPath) {\n this.validateGetUserNotesParams(limit);\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n // Navigate to creator center note manager\n await navigateToCreatorCenter(page);\n await verifyCreatorAuth(page, this.getConfig().xhs.loginOkSelector);\n // Extract notes from creator center\n const notesData = await this.extractNotesFromCreatorCenter(page);\n const limitedNotes = this.limitNotes(notesData, limit);\n return {\n success: true,\n data: limitedNotes,\n total: notesData.length,\n hasMore: notesData.length > limit,\n nextCursor: this.getNextCursor(limitedNotes),\n operation: 'getUserNotes',\n };\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to get user notes: ${error}`);\n return {\n success: false,\n data: [],\n total: 0,\n hasMore: false,\n error: error instanceof Error ? error.message : String(error),\n operation: 'getUserNotes',\n };\n }\n finally {\n await page.close();\n }\n }\n /**\n * Validate parameters for getUserNotes method\n */\n validateGetUserNotesParams(limit) {\n if (limit <= 0) {\n throw new errors/* NoteParsingError */.Vb('Limit must be greater than 0', { limit });\n }\n if (limit > 100) {\n throw new errors/* NoteParsingError */.Vb('Limit cannot exceed 100', { limit });\n }\n }\n /**\n * Extract notes from creator center page\n */\n async extractNotesFromCreatorCenter(page) {\n try {\n const notesData = await page.evaluate((selectors) => {\n const notes = [];\n // Find note elements using the creator center selector\n const noteElements = Array.from(document.querySelectorAll(selectors.NOTE_ELEMENTS));\n noteElements.forEach((element) => {\n try {\n // Extract note data from element\n const publishTime = Date.now();\n const note = {\n id: '',\n title: '',\n content: '',\n images: [],\n publishTime,\n updateTime: publishTime,\n likeCount: 0,\n commentCount: 0,\n shareCount: 0,\n collectCount: 0,\n tags: [],\n url: '',\n visibility: 'unknown',\n visibilityText: '',\n };\n // Extract note ID from data attributes or impression data\n const impressionData = element.getAttribute('data-impression');\n if (impressionData) {\n try {\n const parsed = JSON.parse(impressionData);\n const noteId = parsed?.noteTarget?.value?.noteId;\n if (noteId) {\n note.id = noteId;\n note.url = `https://www.xiaohongshu.com/explore/${noteId}`;\n }\n }\n catch (e) {\n // Ignore parsing errors\n }\n }\n // Extract title/content\n const titleElement = element.querySelector(selectors.TITLE_ELEMENTS);\n if (titleElement) {\n const title = titleElement.textContent?.trim() ?? '';\n note.title = title;\n note.content = title;\n }\n // Extract images - try multiple approaches for creator center\n const imageSelectors = [\n selectors.IMAGE_ELEMENTS,\n 'img', // Try all img elements\n '[class*=\"image\"]',\n '[class*=\"photo\"]',\n '[class*=\"pic\"]',\n '[class*=\"img\"]',\n '[style*=\"background-image\"]', // Background images\n 'div[class*=\"cover\"] img',\n 'div[class*=\"thumbnail\"] img',\n 'div[class*=\"media\"] img',\n ];\n let imageElements = [];\n for (const selector of imageSelectors) {\n const elements = element.querySelectorAll(selector);\n if (elements.length > 0) {\n imageElements = Array.from(elements);\n break;\n }\n }\n imageElements.forEach((img) => {\n let src = '';\n // Try different ways to get image source\n const htmlImg = img;\n if (htmlImg.src) {\n src = htmlImg.src;\n }\n else if (htmlImg.style && htmlImg.style.backgroundImage) {\n // Extract from background-image CSS\n const bgMatch = htmlImg.style.backgroundImage.match(/url\\(['\"]?([^'\"]+)['\"]?\\)/);\n if (bgMatch) {\n src = bgMatch[1];\n }\n }\n else if (img.getAttribute('data-src')) {\n // Lazy loaded images\n src = img.getAttribute('data-src') || '';\n }\n else if (img.getAttribute('data-original')) {\n // Another lazy loading attribute\n src = img.getAttribute('data-original') || '';\n }\n if (src &&\n !src.includes('avatar') &&\n !src.includes('icon') &&\n !src.includes('logo') &&\n !src.includes('placeholder') &&\n src.startsWith('http')) {\n note.images.push(src);\n }\n });\n // Extract stats - look for numbers in the element\n const allText = element.textContent || '';\n const numbers = allText.match(/\\d+/g) || [];\n // Try to extract stats from text content\n if (numbers.length >= 4) {\n // Assuming order: like, comment, share, collect, view\n note.likeCount = parseInt(numbers[0] || '0') || 0;\n note.commentCount = parseInt(numbers[1]) || 0;\n note.shareCount = parseInt(numbers[2]) || 0;\n note.collectCount = parseInt(numbers[3]) || 0;\n }\n // Extract publish time\n const timeElement = element.querySelector(selectors.PUBLISH_TIME);\n if (timeElement) {\n const timeText = timeElement.textContent?.trim() || '';\n if (timeText.includes('发布于')) {\n // Parse Chinese date format\n const dateMatch = timeText.match(/(\\d{4})年(\\d{1,2})月(\\d{1,2})日\\s+(\\d{1,2}):(\\d{2})/);\n if (dateMatch) {\n const [, year, month, day, hour, minute] = dateMatch;\n const publishDate = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute));\n note.publishTime = publishDate.getTime();\n note.updateTime = publishDate.getTime();\n }\n }\n }\n // Extract visibility information\n const elementText = element.textContent?.toLowerCase() || '';\n if (elementText.includes('仅自己可见')) {\n note.visibility = 'private';\n note.visibilityText = '仅自己可见';\n }\n else if (elementText.includes('朋友可见')) {\n note.visibility = 'friends';\n note.visibilityText = '朋友可见';\n }\n else if (elementText.includes('公开')) {\n note.visibility = 'public';\n note.visibilityText = '公开';\n }\n else {\n // Default to public for notes without explicit visibility indicators\n note.visibility = 'public';\n note.visibilityText = '公开';\n }\n // Extract tags\n const tagElements = element.querySelectorAll(selectors.TAG_ELEMENTS);\n tagElements.forEach((tag) => {\n const tagText = tag.textContent?.trim();\n if (tagText?.startsWith('#')) {\n note.tags.push(tagText);\n }\n });\n if (note.id) {\n notes.push(note);\n }\n }\n catch (error) {\n // Ignore extraction errors for individual notes\n }\n });\n return notes;\n }, NOTE_SELECTORS);\n return notesData;\n }\n catch (error) {\n throw new errors/* NoteParsingError */.Vb('Failed to extract notes from creator center', { operation: 'extractNotesFromCreatorCenter' }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Limit notes array to specified count\n */\n limitNotes(notes, limit) {\n return notes.slice(0, limit).map((note) => ({\n id: note.id,\n title: note.title,\n content: note.content,\n images: Object.freeze([...note.images]),\n publishTime: note.publishTime,\n updateTime: note.updateTime,\n likeCount: note.likeCount,\n commentCount: note.commentCount,\n shareCount: note.shareCount,\n collectCount: note.collectCount,\n tags: Object.freeze([...note.tags]),\n url: note.url,\n visibility: note.visibility,\n visibilityText: note.visibilityText,\n }));\n }\n /**\n * Get next cursor for pagination\n */\n getNextCursor(notes) {\n return notes.length > 0 ? notes[notes.length - 1].id : undefined;\n }\n /**\n * Delete a specific note by ID\n * @param noteId - The ID of the note to delete\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteNote(noteId, browserPath) {\n return this.deleteService.deleteNote(noteId, browserPath);\n }\n /**\n * Delete the last published note\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteLastPublishedNote(browserPath) {\n return this.deleteService.deleteLastPublishedNote(browserPath);\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUNuRSxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQWMsRUFBRSxXQUFvQjtRQUNuRCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxXQUFvQjtRQUNoRCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsdUJBQXVCLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDakUsQ0FBQztDQUNGIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQvY3JlYXRvci1jZW50ZXIudHM/MWQ4NCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvZGVsZXRpbmcvZGVsZXRlLnNlcnZpY2UudHM/MDMwOSIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvbm90ZXMvbm90ZS5zZXJ2aWNlLnRzPzFiNjYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTaGFyZWQgaGVscGVycyBmb3IgQ3JlYXRvciBDZW50ZXIgcGFnZSBvcGVyYXRpb25zXG4gKi9cblxuaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBOb3RMb2dnZWRJbkVycm9yLCBYSFNFcnJvciB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSAnLi91dGlscyc7XG5cbmV4cG9ydCBjb25zdCBDUkVBVE9SX0NFTlRFUl9VUkwgPVxuICAnaHR0cHM6Ly9jcmVhdG9yLnhpYW9ob25nc2h1LmNvbS9uZXcvbm90ZS1tYW5hZ2VyP3NvdXJjZT1vZmZpY2lhbCc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBuYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlcihwYWdlOiBQYWdlKTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgcGFnZS5nb3RvKENSRUFUT1JfQ0VOVEVSX1VSTCwgeyB3YWl0VW50aWw6ICdsb2FkJywgdGltZW91dDogMzAwMDAgfSk7XG4gICAgYXdhaXQgc2xlZXAoMzAwMCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IFhIU0Vycm9yKFxuICAgICAgJ0ZhaWxlZCB0byBuYXZpZ2F0ZSB0byBjcmVhdG9yIGNlbnRlcicsXG4gICAgICAnQ3JlYXRvckNlbnRlckVycm9yJyxcbiAgICAgIHsgdXJsOiBDUkVBVE9SX0NFTlRFUl9VUkwgfSxcbiAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKVxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHZlcmlmeUNyZWF0b3JBdXRoKHBhZ2U6IFBhZ2UsIGxvZ2luT2tTZWxlY3Rvcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgbG9naW5FbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQobG9naW5Pa1NlbGVjdG9yKTtcbiAgICBjb25zdCBjcmVhdG9yRWxlbWVudHMgPSBhd2FpdCBwYWdlLiQkKCdbY2xhc3MqPVwidXNlclwiXSwgW2NsYXNzKj1cInByb2ZpbGVcIl0sIFtjbGFzcyo9XCJhdmF0YXJcIl0nKTtcblxuICAgIGlmIChsb2dpbkVsZW1lbnRzLmxlbmd0aCA9PT0gMCAmJiBjcmVhdG9yRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zdCBjdXJyZW50VXJsID0gcGFnZS51cmwoKTtcbiAgICAgIGlmIChjdXJyZW50VXJsLmluY2x1ZGVzKCdsb2dpbicpIHx8IGN1cnJlbnRVcmwuaW5jbHVkZXMoJ3NpZ25pbicpKSB7XG4gICAgICAgIHRocm93IG5ldyBOb3RMb2dnZWRJbkVycm9yKCdVc2VyIG5vdCBsb2dnZWQgaW4nLCB7IHVybDogY3VycmVudFVybCB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgbm90ZUVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJCgnZGl2Lm5vdGUnKTtcbiAgICAgIGlmIChub3RlRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBOb3RMb2dnZWRJbkVycm9yKCdVc2VyIG5vdCBsb2dnZWQgaW4gb3Igbm8gbm90ZXMgZm91bmQnLCB7IHVybDogY3VycmVudFVybCB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTm90TG9nZ2VkSW5FcnJvcikge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIHRocm93IG5ldyBYSFNFcnJvcihcbiAgICAgICdGYWlsZWQgdG8gdmVyaWZ5IGF1dGhlbnRpY2F0aW9uJyxcbiAgICAgICdDcmVhdG9yQ2VudGVyRXJyb3InLFxuICAgICAgeyBvcGVyYXRpb246ICd2ZXJpZnlBdXRoJyB9LFxuICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpXG4gICAgKTtcbiAgfVxufVxuIiwiLyoqXG4gKiBEZWxldGUgc2VydmljZSBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqIEhhbmRsZXMgbm90ZSBkZWxldGlvbiBvcGVyYXRpb25zXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBDb25maWcsIFhIU1Jlc3BvbnNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IEJhc2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Jhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBCcm93c2VyTWFuYWdlciB9IGZyb20gJy4uL2Jyb3dzZXIvYnJvd3Nlci5tYW5hZ2VyJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgRGVsZXRlRXJyb3IgfSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IG5hdmlnYXRlVG9DcmVhdG9yQ2VudGVyLCB2ZXJpZnlDcmVhdG9yQXV0aCB9IGZyb20gJy4uLy4uL3NoYXJlZC9jcmVhdG9yLWNlbnRlcic7XG5pbXBvcnQgeyBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IENPTU1PTl9CVVRUT05fU0VMRUNUT1JTLCBDT01NT05fTU9EQUxfU0VMRUNUT1JTIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3NlbGVjdG9ycyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVsZXRlUmVzdWx0IGV4dGVuZHMgWEhTUmVzcG9uc2U8bnVsbD4ge1xuICByZWFkb25seSBub3RlSWQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRpdGxlPzogc3RyaW5nO1xuICByZWFkb25seSBkZWxldGVkQXQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEZWxldGVPcHRpb25zIHtcbiAgbm90ZUlkPzogc3RyaW5nO1xuICBsYXN0UHVibGlzaGVkPzogYm9vbGVhbjtcbiAgYnJvd3NlclBhdGg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ1NTIHNlbGVjdG9ycyBmb3IgZGVsZXRlIG9wZXJhdGlvbnMgLSB1cGRhdGVkIGZvciBjdXJyZW50IFhpYW9Ib25nU2h1IGludGVyZmFjZVxuICovXG5jb25zdCBERUxFVEVfU0VMRUNUT1JTID0ge1xuICBOT1RFX0lURU06IFtcbiAgICAnZGl2Lm5vdGUnLFxuICAgICcubm90ZS1pdGVtJyxcbiAgICAnW2NsYXNzKj1cIm5vdGVcIl0nLFxuICAgICdbZGF0YS1pbXByZXNzaW9uXScsXG4gICAgJy5jcmVhdG9yLW5vdGUtaXRlbScsXG4gICAgJy5ub3RlLWNhcmQnLFxuICAgICcuY29udGVudC1pdGVtJ1xuICBdLFxuICBERUxFVEVfQlVUVE9OOiBbXG4gICAgJy5jb250cm9sLmRhdGEtZGVsJyxcbiAgICAnc3Bhbi5jb250cm9sLmRhdGEtZGVsJyxcbiAgICAuLi5DT01NT05fQlVUVE9OX1NFTEVDVE9SUy5ERUxFVEVcbiAgXSxcbiAgQ09ORklSTV9CVVRUT046IENPTU1PTl9CVVRUT05fU0VMRUNUT1JTLkNPTkZJUk0sXG4gIENBTkNFTF9CVVRUT046IENPTU1PTl9CVVRUT05fU0VMRUNUT1JTLkNBTkNFTCxcbiAgTU9SRV9PUFRJT05TOiBDT01NT05fQlVUVE9OX1NFTEVDVE9SUy5NT1JFX09QVElPTlMsXG4gIERST1BET1dOX01FTlU6IENPTU1PTl9NT0RBTF9TRUxFQ1RPUlMuRFJPUERPV05fTUVOVSxcbiAgTU9EQUxfQ09ORklSTTogQ09NTU9OX01PREFMX1NFTEVDVE9SUy5DT05GSVJNLFxuICBNT0RBTF9DQU5DRUw6IENPTU1PTl9NT0RBTF9TRUxFQ1RPUlMuQ0FOQ0VMLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IGNsYXNzIERlbGV0ZVNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnLCBicm93c2VyTWFuYWdlcj86IEJyb3dzZXJNYW5hZ2VyKSB7XG4gICAgc3VwZXIoY29uZmlnLCBicm93c2VyTWFuYWdlcik7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGEgc3BlY2lmaWMgbm90ZSBieSBJRFxuICAgKiBAcGFyYW0gbm90ZUlkIC0gVGhlIElEIG9mIHRoZSBub3RlIHRvIGRlbGV0ZVxuICAgKiBAcGFyYW0gYnJvd3NlclBhdGggLSBPcHRpb25hbCBjdXN0b20gYnJvd3NlciBwYXRoXG4gICAqIEByZXR1cm5zIFByb21pc2U8RGVsZXRlUmVzdWx0PiAtIERlbGV0ZSBvcGVyYXRpb24gcmVzdWx0XG4gICAqL1xuICBhc3luYyBkZWxldGVOb3RlKG5vdGVJZDogc3RyaW5nLCBicm93c2VyUGF0aD86IHN0cmluZyk6IFByb21pc2U8RGVsZXRlUmVzdWx0PiB7XG4gICAgdGhpcy52YWxpZGF0ZURlbGV0ZVBhcmFtcyhub3RlSWQpO1xuXG4gICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKHRydWUsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBOYXZpZ2F0ZSB0byBjcmVhdG9yIGNlbnRlciBub3RlIG1hbmFnZXJcbiAgICAgIGF3YWl0IG5hdmlnYXRlVG9DcmVhdG9yQ2VudGVyKHBhZ2UpO1xuICAgICAgYXdhaXQgdmVyaWZ5Q3JlYXRvckF1dGgocGFnZSwgdGhpcy5nZXRDb25maWcoKS54aHMubG9naW5Pa1NlbGVjdG9yKTtcblxuICAgICAgLy8gRmluZCBhbmQgZGVsZXRlIHRoZSBzcGVjaWZpYyBub3RlXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmZpbmRBbmREZWxldGVOb3RlKHBhZ2UsIG5vdGVJZCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIGRhdGE6IG51bGwsXG4gICAgICAgIG5vdGVJZDogcmVzdWx0Lm5vdGVJZCxcbiAgICAgICAgdGl0bGU6IHJlc3VsdC50aXRsZSxcbiAgICAgICAgZGVsZXRlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgICBtZXNzYWdlOiBgU3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgbm90ZSBcIiR7cmVzdWx0LnRpdGxlfVwiIChJRDogJHtyZXN1bHQubm90ZUlkfSlgLFxuICAgICAgICBvcGVyYXRpb246ICdkZWxldGVOb3RlJyxcbiAgICAgIH0gYXMgdW5rbm93biBhcyBEZWxldGVSZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBub3RlICR7bm90ZUlkfTogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBkYXRhOiBudWxsLFxuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICBtZXNzYWdlOiBgRmFpbGVkIHRvIGRlbGV0ZSBub3RlOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gLFxuICAgICAgICBkZWxldGVkQXQ6IERhdGUubm93KCksXG4gICAgICAgIG9wZXJhdGlvbjogJ2RlbGV0ZU5vdGUnLFxuICAgICAgfSBhcyB1bmtub3duIGFzIERlbGV0ZVJlc3VsdDtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIGxhc3QgcHVibGlzaGVkIG5vdGVcbiAgICogQHBhcmFtIGJyb3dzZXJQYXRoIC0gT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgcGF0aFxuICAgKiBAcmV0dXJucyBQcm9taXNlPERlbGV0ZVJlc3VsdD4gLSBEZWxldGUgb3BlcmF0aW9uIHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgZGVsZXRlTGFzdFB1Ymxpc2hlZE5vdGUoYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPERlbGV0ZVJlc3VsdD4ge1xuICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZSh0cnVlLCBicm93c2VyUGF0aCwgdHJ1ZSk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gTmF2aWdhdGUgdG8gY3JlYXRvciBjZW50ZXIgbm90ZSBtYW5hZ2VyXG4gICAgICBhd2FpdCBuYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlcihwYWdlKTtcbiAgICAgIGF3YWl0IHZlcmlmeUNyZWF0b3JBdXRoKHBhZ2UsIHRoaXMuZ2V0Q29uZmlnKCkueGhzLmxvZ2luT2tTZWxlY3Rvcik7XG5cbiAgICAgIC8vIEZpbmQgYW5kIGRlbGV0ZSB0aGUgbGFzdCBwdWJsaXNoZWQgbm90ZVxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5maW5kQW5kRGVsZXRlTGFzdE5vdGUocGFnZSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIGRhdGE6IG51bGwsXG4gICAgICAgIG5vdGVJZDogcmVzdWx0Lm5vdGVJZCxcbiAgICAgICAgdGl0bGU6IHJlc3VsdC50aXRsZSxcbiAgICAgICAgZGVsZXRlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgICBtZXNzYWdlOiBgU3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgbGFzdCBwdWJsaXNoZWQgbm90ZSBcIiR7cmVzdWx0LnRpdGxlfVwiIChJRDogJHtyZXN1bHQubm90ZUlkfSlgLFxuICAgICAgICBvcGVyYXRpb246ICdkZWxldGVMYXN0UHVibGlzaGVkTm90ZScsXG4gICAgICB9IGFzIHVua25vd24gYXMgRGVsZXRlUmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBkZWxldGUgbGFzdCBwdWJsaXNoZWQgbm90ZTogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBkYXRhOiBudWxsLFxuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICBtZXNzYWdlOiBgRmFpbGVkIHRvIGRlbGV0ZSBsYXN0IHB1Ymxpc2hlZCBub3RlOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gLFxuICAgICAgICBkZWxldGVkQXQ6IERhdGUubm93KCksXG4gICAgICAgIG9wZXJhdGlvbjogJ2RlbGV0ZUxhc3RQdWJsaXNoZWROb3RlJyxcbiAgICAgIH0gYXMgdW5rbm93biBhcyBEZWxldGVSZXN1bHQ7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgZGVsZXRlIHBhcmFtZXRlcnNcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVEZWxldGVQYXJhbXMobm90ZUlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIW5vdGVJZCB8fCBub3RlSWQudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IERlbGV0ZUVycm9yKCdOb3RlIElEIGlzIHJlcXVpcmVkJywgeyBub3RlSWQgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgYW5kIGRlbGV0ZSBhIHNwZWNpZmljIG5vdGUgYnkgSURcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmluZEFuZERlbGV0ZU5vdGUocGFnZTogUGFnZSwgbm90ZUlkOiBzdHJpbmcpOiBQcm9taXNlPHsgbm90ZUlkOiBzdHJpbmc7IHRpdGxlOiBzdHJpbmcgfT4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBTdGVwIDE6IExvY2F0ZSB0aGUgbm90ZSBhbmQgdHJ5IHRvIGZpbmQgYSBkaXJlY3QgZGVsZXRlIGJ1dHRvbiBvciBtb3JlLW9wdGlvbnMgYnV0dG9uXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKFxuICAgICAgICAoc2VsZWN0b3JzOiB0eXBlb2YgREVMRVRFX1NFTEVDVE9SUywgdGFyZ2V0Tm90ZUlkOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICBsZXQgbm90ZUVsZW1lbnRzOiBFbGVtZW50W10gPSBbXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycy5OT1RFX0lURU0pIHtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XG4gICAgICAgICAgICBpZiAoZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBub3RlRWxlbWVudHMgPSBlbGVtZW50cztcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG5vdGVFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogdGFyZ2V0Tm90ZUlkLCB0aXRsZTogJycsIGZvdW5kOiBmYWxzZSwgZXJyb3I6ICdObyBub3RlIGVsZW1lbnRzIGZvdW5kIG9uIHBhZ2UnIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yIChjb25zdCBub3RlRWxlbWVudCBvZiBub3RlRWxlbWVudHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGltcHJlc3Npb25EYXRhID0gbm90ZUVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWltcHJlc3Npb24nKTtcbiAgICAgICAgICAgIGxldCBjdXJyZW50Tm90ZUlkID0gJyc7XG5cbiAgICAgICAgICAgIGlmIChpbXByZXNzaW9uRGF0YSkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoaW1wcmVzc2lvbkRhdGEpO1xuICAgICAgICAgICAgICAgIGN1cnJlbnROb3RlSWQgPSBwYXJzZWQ/Lm5vdGVUYXJnZXQ/LnZhbHVlPy5ub3RlSWQgfHwgJyc7XG4gICAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgIC8vIElnbm9yZSBwYXJzaW5nIGVycm9yc1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghY3VycmVudE5vdGVJZCkge1xuICAgICAgICAgICAgICBjb25zdCBsaW5rRWxlbWVudCA9IG5vdGVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ2FbaHJlZio9XCIvZXhwbG9yZS9cIl0sIGFbaHJlZio9XCIvbm90ZS9cIl0nKTtcbiAgICAgICAgICAgICAgaWYgKGxpbmtFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHJlZiA9IGxpbmtFbGVtZW50LmdldEF0dHJpYnV0ZSgnaHJlZicpIHx8ICcnO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gaHJlZi5tYXRjaCgvXFwvZXhwbG9yZVxcLyhbYS16QS1aMC05XSspLyk7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICBjdXJyZW50Tm90ZUlkID0gbWF0Y2hbMV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjdXJyZW50Tm90ZUlkID09PSB0YXJnZXROb3RlSWQpIHtcbiAgICAgICAgICAgICAgY29uc3QgdGl0bGVFbGVtZW50ID0gbm90ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignW2NsYXNzKj1cInRpdGxlXCJdLCBbY2xhc3MqPVwibmFtZVwiXScpO1xuICAgICAgICAgICAgICBjb25zdCB0aXRsZSA9IHRpdGxlRWxlbWVudD8udGV4dENvbnRlbnQ/LnRyaW0oKSB8fCAnVW5rbm93bic7XG5cbiAgICAgICAgICAgICAgLy8gVHJ5IHRvIGZpbmQgYSBkaXJlY3QgZGVsZXRlIGJ1dHRvbiBmaXJzdFxuICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycy5ERUxFVEVfQlVUVE9OKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVsZXRlQnV0dG9uID0gbm90ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgICAgICAgICAgICAgaWYgKGRlbGV0ZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgICAgKGRlbGV0ZUJ1dHRvbiBhcyBIVE1MRWxlbWVudCkuY2xpY2soKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogY3VycmVudE5vdGVJZCwgdGl0bGUsIGZvdW5kOiB0cnVlLCBuZWVkc0Ryb3Bkb3duOiBmYWxzZSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIE5vIGRpcmVjdCBkZWxldGUgYnV0dG9uIOKAlCBjaGVjayBmb3IgYSBtb3JlLW9wdGlvbnMgYnV0dG9uXG4gICAgICAgICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2Ygc2VsZWN0b3JzLk1PUkVfT1BUSU9OUykge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1vcmVCdXR0b24gPSBub3RlRWxlbWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgICAgICAgICBpZiAobW9yZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgICAgKG1vcmVCdXR0b24gYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4geyBub3RlSWQ6IGN1cnJlbnROb3RlSWQsIHRpdGxlLCBmb3VuZDogdHJ1ZSwgbmVlZHNEcm9wZG93bjogdHJ1ZSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogY3VycmVudE5vdGVJZCwgdGl0bGUsIGZvdW5kOiBmYWxzZSwgZXJyb3I6ICdEZWxldGUgYnV0dG9uIG5vdCBmb3VuZCcgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4geyBub3RlSWQ6IHRhcmdldE5vdGVJZCwgdGl0bGU6ICcnLCBmb3VuZDogZmFsc2UsIGVycm9yOiAnTm90ZSBub3QgZm91bmQnIH07XG4gICAgICAgIH0sXG4gICAgICAgIERFTEVURV9TRUxFQ1RPUlMsXG4gICAgICAgIG5vdGVJZFxuICAgICAgKTtcblxuICAgICAgaWYgKCFyZXN1bHQuZm91bmQpIHtcbiAgICAgICAgdGhyb3cgbmV3IERlbGV0ZUVycm9yKHJlc3VsdC5lcnJvciB8fCAnTm90ZSBub3QgZm91bmQnLCB7IG5vdGVJZCB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gU3RlcCAyOiBJZiB3ZSBjbGlja2VkIFwibW9yZSBvcHRpb25zXCIsIHdhaXQgZm9yIGRyb3Bkb3duIHRoZW4gY2xpY2sgZGVsZXRlIGluIGl0XG4gICAgICBpZiAocmVzdWx0Lm5lZWRzRHJvcGRvd24pIHtcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG4gICAgICAgIGxldCBjbGlja2VkID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgREVMRVRFX1NFTEVDVE9SUy5EUk9QRE9XTl9NRU5VKSB7XG4gICAgICAgICAgY29uc3QgZHJvcGRvd24gPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICAgIGlmIChkcm9wZG93bikge1xuICAgICAgICAgICAgZm9yIChjb25zdCBkZWxldGVTZWxlY3RvciBvZiBERUxFVEVfU0VMRUNUT1JTLkRFTEVURV9CVVRUT04pIHtcbiAgICAgICAgICAgICAgY29uc3QgZGVsZXRlQnRuID0gYXdhaXQgZHJvcGRvd24uJChkZWxldGVTZWxlY3Rvcik7XG4gICAgICAgICAgICAgIGlmIChkZWxldGVCdG4pIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBkZWxldGVCdG4uY2xpY2soKTtcbiAgICAgICAgICAgICAgICBjbGlja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNsaWNrZWQpIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNsaWNrZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IoJ0RlbGV0ZSBidXR0b24gbm90IGZvdW5kIGluIGRyb3Bkb3duIG1lbnUnLCB7IG5vdGVJZCB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQ29uZmlybWF0aW9uRGlhbG9nKHBhZ2UpO1xuXG4gICAgICByZXR1cm4geyBub3RlSWQ6IHJlc3VsdC5ub3RlSWQsIHRpdGxlOiByZXN1bHQudGl0bGUgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IERlbGV0ZUVycm9yKFxuICAgICAgICAnRmFpbGVkIHRvIGZpbmQgYW5kIGRlbGV0ZSBub3RlJyxcbiAgICAgICAgeyBub3RlSWQgfSxcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGFuZCBkZWxldGUgdGhlIGxhc3QgcHVibGlzaGVkIG5vdGVcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmluZEFuZERlbGV0ZUxhc3ROb3RlKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHsgbm90ZUlkOiBzdHJpbmc7IHRpdGxlOiBzdHJpbmcgfT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChzZWxlY3RvcnM6IHR5cGVvZiBERUxFVEVfU0VMRUNUT1JTKSA9PiB7XG5cbiAgICAgICAgLy8gVHJ5IGVhY2ggbm90ZSBpdGVtIHNlbGVjdG9yXG4gICAgICAgIGxldCBub3RlRWxlbWVudHM6IEVsZW1lbnRbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycy5OT1RFX0lURU0pIHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikpO1xuICAgICAgICAgIGlmIChlbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBub3RlRWxlbWVudHMgPSBlbGVtZW50cztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChub3RlRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHsgbm90ZUlkOiAnJywgdGl0bGU6ICcnLCBmb3VuZDogZmFsc2UsIGVycm9yOiAnTm8gbm90ZXMgZm91bmQnIH07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIGZpcnN0IG5vdGUgKG1vc3QgcmVjZW50KVxuICAgICAgICBjb25zdCBmaXJzdE5vdGUgPSBub3RlRWxlbWVudHNbMF07XG5cbiAgICAgICAgLy8gRXh0cmFjdCBub3RlIElEXG4gICAgICAgIGxldCBub3RlSWQgPSAnJztcbiAgICAgICAgY29uc3QgaW1wcmVzc2lvbkRhdGEgPSBmaXJzdE5vdGUuZ2V0QXR0cmlidXRlKCdkYXRhLWltcHJlc3Npb24nKTtcblxuICAgICAgICBpZiAoaW1wcmVzc2lvbkRhdGEpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShpbXByZXNzaW9uRGF0YSk7XG4gICAgICAgICAgICBub3RlSWQgPSBwYXJzZWQ/Lm5vdGVUYXJnZXQ/LnZhbHVlPy5ub3RlSWQgfHwgJyc7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gSWdub3JlIHBhcnNpbmcgZXJyb3JzXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWxzbyB0cnkgdG8gZmluZCBub3RlIElEIGluIGxpbmtcbiAgICAgICAgaWYgKCFub3RlSWQpIHtcbiAgICAgICAgICBjb25zdCBsaW5rRWxlbWVudCA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKCdhW2hyZWYqPVwiL2V4cGxvcmUvXCJdLCBhW2hyZWYqPVwiL25vdGUvXCJdJyk7XG4gICAgICAgICAgaWYgKGxpbmtFbGVtZW50KSB7XG4gICAgICAgICAgICBjb25zdCBocmVmID0gbGlua0VsZW1lbnQuZ2V0QXR0cmlidXRlKCdocmVmJykgfHwgJyc7XG4gICAgICAgICAgICBjb25zdCBtYXRjaCA9IGhyZWYubWF0Y2goL1xcL2V4cGxvcmVcXC8oW2EtekEtWjAtOV0rKS8pO1xuICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgIG5vdGVJZCA9IG1hdGNoWzFdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEV4dHJhY3QgdGl0bGVcbiAgICAgICAgY29uc3QgdGl0bGVFbGVtZW50ID0gZmlyc3ROb3RlLnF1ZXJ5U2VsZWN0b3IoJ1tjbGFzcyo9XCJ0aXRsZVwiXSwgW2NsYXNzKj1cIm5hbWVcIl0nKTtcbiAgICAgICAgY29uc3QgdGl0bGUgPSB0aXRsZUVsZW1lbnQ/LnRleHRDb250ZW50Py50cmltKCkgfHwgJ1Vua25vd24nO1xuXG4gICAgICAgIC8vIFRyeSB0byBmaW5kIGEgZGlyZWN0IGRlbGV0ZSBidXR0b24gZmlyc3RcbiAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuREVMRVRFX0JVVFRPTikge1xuICAgICAgICAgIGNvbnN0IGRlbGV0ZUJ1dHRvbiA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgICBpZiAoZGVsZXRlQnV0dG9uKSB7XG4gICAgICAgICAgICAoZGVsZXRlQnV0dG9uIGFzIEhUTUxFbGVtZW50KS5jbGljaygpO1xuICAgICAgICAgICAgcmV0dXJuIHsgbm90ZUlkLCB0aXRsZSwgZm91bmQ6IHRydWUsIG5lZWRzRHJvcGRvd246IGZhbHNlIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gTm8gZGlyZWN0IGRlbGV0ZSBidXR0b24g4oCUIGNoZWNrIGZvciBhIG1vcmUtb3B0aW9ucyBidXR0b25cbiAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuTU9SRV9PUFRJT05TKSB7XG4gICAgICAgICAgY29uc3QgbW9yZUJ1dHRvbiA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgICBpZiAobW9yZUJ1dHRvbikge1xuICAgICAgICAgICAgKG1vcmVCdXR0b24gYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCk7XG4gICAgICAgICAgICByZXR1cm4geyBub3RlSWQsIHRpdGxlLCBmb3VuZDogdHJ1ZSwgbmVlZHNEcm9wZG93bjogdHJ1ZSB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IG5vdGVJZCwgdGl0bGUsIGZvdW5kOiBmYWxzZSwgZXJyb3I6ICdEZWxldGUgYnV0dG9uIG5vdCBmb3VuZCcgfTtcbiAgICAgIH0sIERFTEVURV9TRUxFQ1RPUlMpO1xuXG4gICAgICBpZiAoIXJlc3VsdC5mb3VuZCkge1xuICAgICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IocmVzdWx0LmVycm9yIHx8ICdGYWlsZWQgdG8gZmluZCBkZWxldGUgYnV0dG9uJywge30pO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiB3ZSBjbGlja2VkIFwibW9yZSBvcHRpb25zXCIsIHdhaXQgZm9yIGRyb3Bkb3duIHRoZW4gY2xpY2sgZGVsZXRlIGluIGl0XG4gICAgICBpZiAocmVzdWx0Lm5lZWRzRHJvcGRvd24pIHtcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG4gICAgICAgIGxldCBjbGlja2VkID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgREVMRVRFX1NFTEVDVE9SUy5EUk9QRE9XTl9NRU5VKSB7XG4gICAgICAgICAgY29uc3QgZHJvcGRvd24gPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICAgIGlmIChkcm9wZG93bikge1xuICAgICAgICAgICAgZm9yIChjb25zdCBkZWxldGVTZWxlY3RvciBvZiBERUxFVEVfU0VMRUNUT1JTLkRFTEVURV9CVVRUT04pIHtcbiAgICAgICAgICAgICAgY29uc3QgZGVsZXRlQnRuID0gYXdhaXQgZHJvcGRvd24uJChkZWxldGVTZWxlY3Rvcik7XG4gICAgICAgICAgICAgIGlmIChkZWxldGVCdG4pIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBkZWxldGVCdG4uY2xpY2soKTtcbiAgICAgICAgICAgICAgICBjbGlja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNsaWNrZWQpIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNsaWNrZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IoJ0RlbGV0ZSBidXR0b24gbm90IGZvdW5kIGluIGRyb3Bkb3duIG1lbnUnLCB7fSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gV2FpdCBmb3IgY29uZmlybWF0aW9uIGRpYWxvZyBpZiBpdCBhcHBlYXJzXG4gICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcblxuICAgICAgLy8gSGFuZGxlIGNvbmZpcm1hdGlvbiBkaWFsb2dcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQ29uZmlybWF0aW9uRGlhbG9nKHBhZ2UpO1xuXG4gICAgICByZXR1cm4geyBub3RlSWQ6IHJlc3VsdC5ub3RlSWQsIHRpdGxlOiByZXN1bHQudGl0bGUgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IERlbGV0ZUVycm9yKFxuICAgICAgICAnRmFpbGVkIHRvIGZpbmQgYW5kIGRlbGV0ZSBsYXN0IG5vdGUnLFxuICAgICAgICB7fSxcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgY29uZmlybWF0aW9uIGRpYWxvZyBmb3IgZGVsZXRlIG9wZXJhdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVDb25maXJtYXRpb25EaWFsb2cocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBXYWl0IGZvciBjb25maXJtYXRpb24gZGlhbG9nIHRvIGFwcGVhclxuICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7XG5cbiAgICAgIC8vIExvb2sgZm9yIGNvbmZpcm1hdGlvbiBidXR0b25zIHVzaW5nIGFsbCBwb3NzaWJsZSBzZWxlY3RvcnNcbiAgICAgIGxldCBjb25maXJtQnV0dG9uOiBpbXBvcnQoJ3B1cHBldGVlcicpLkVsZW1lbnRIYW5kbGU8RWxlbWVudD4gfCBudWxsID0gbnVsbDtcblxuICAgICAgLy8gVHJ5IGVhY2ggY29uZmlybSBidXR0b24gc2VsZWN0b3JcbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgREVMRVRFX1NFTEVDVE9SUy5DT05GSVJNX0JVVFRPTikge1xuICAgICAgICBjb25maXJtQnV0dG9uID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGNvbmZpcm1CdXR0b24pIHtcbiAgICAgICAgICBsb2dnZXIuaW5mbyhgRm91bmQgY29uZmlybSBidXR0b24gd2l0aCBzZWxlY3RvcjogJHtzZWxlY3Rvcn1gKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBJZiBub3QgZm91bmQsIHRyeSBtb2RhbCBjb25maXJtIHNlbGVjdG9yc1xuICAgICAgaWYgKCFjb25maXJtQnV0dG9uKSB7XG4gICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgREVMRVRFX1NFTEVDVE9SUy5NT0RBTF9DT05GSVJNKSB7XG4gICAgICAgICAgY29uZmlybUJ1dHRvbiA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICAgICAgaWYgKGNvbmZpcm1CdXR0b24pIHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBGb3VuZCBtb2RhbCBjb25maXJtIGJ1dHRvbiB3aXRoIHNlbGVjdG9yOiAke3NlbGVjdG9yfWApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maXJtQnV0dG9uKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdDbGlja2luZyBjb25maXJtYXRpb24gYnV0dG9uJyk7XG4gICAgICAgIGF3YWl0IGNvbmZpcm1CdXR0b24uY2xpY2soKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZiBubyBjb25maXJtYXRpb24gZGlhbG9nLCB0aGUgZGVsZXRlIG1pZ2h0IGhhdmUgYmVlbiBpbW1lZGlhdGVcbiAgICAgICAgbG9nZ2VyLmluZm8oJ05vIGNvbmZpcm1hdGlvbiBkaWFsb2cgZm91bmQsIGRlbGV0ZSBtaWdodCBiZSBpbW1lZGlhdGUnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBoYW5kbGUgY29uZmlybWF0aW9uIGRpYWxvZzogJHtlcnJvcn1gKTtcbiAgICAgIC8vIENvbnRpbnVlIGFueXdheSBhcyB0aGUgZGVsZXRlIG1pZ2h0IHN0aWxsIHdvcmtcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICogTm90ZSBzZXJ2aWNlIGZvciBYSFMgTUNQIFNlcnZlclxuICogSGFuZGxlcyB1c2VyIG5vdGVzL2ZlZWRzIG9wZXJhdGlvbnNcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IENvbmZpZywgWEhTUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgQmFzZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvYmFzZS5zZXJ2aWNlJztcbmltcG9ydCB7IEJyb3dzZXJNYW5hZ2VyIH0gZnJvbSAnLi4vYnJvd3Nlci9icm93c2VyLm1hbmFnZXInO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2xvZ2dlcic7XG5pbXBvcnQgeyBOb3RlUGFyc2luZ0Vycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBuYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlciwgdmVyaWZ5Q3JlYXRvckF1dGggfSBmcm9tICcuLi8uLi9zaGFyZWQvY3JlYXRvci1jZW50ZXInO1xuaW1wb3J0IHsgRGVsZXRlU2VydmljZSwgRGVsZXRlUmVzdWx0IH0gZnJvbSAnLi4vZGVsZXRpbmcvZGVsZXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlck5vdGUge1xuICByZWFkb25seSBpZDogc3RyaW5nO1xuICByZWFkb25seSB0aXRsZTogc3RyaW5nO1xuICByZWFkb25seSBjb250ZW50OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGltYWdlczogcmVhZG9ubHkgc3RyaW5nW107XG4gIHJlYWRvbmx5IHZpZGVvPzogc3RyaW5nO1xuICByZWFkb25seSBwdWJsaXNoVGltZTogbnVtYmVyO1xuICByZWFkb25seSB1cGRhdGVUaW1lOiBudW1iZXI7XG4gIHJlYWRvbmx5IGxpa2VDb3VudDogbnVtYmVyO1xuICByZWFkb25seSBjb21tZW50Q291bnQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgc2hhcmVDb3VudDogbnVtYmVyO1xuICByZWFkb25seSBjb2xsZWN0Q291bnQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgdGFnczogcmVhZG9ubHkgc3RyaW5nW107XG4gIHJlYWRvbmx5IHVybDogc3RyaW5nO1xuICByZWFkb25seSB2aXNpYmlsaXR5OiAncHVibGljJyB8ICdwcml2YXRlJyB8ICdmcmllbmRzJyB8ICd1bmtub3duJztcbiAgcmVhZG9ubHkgdmlzaWJpbGl0eVRleHQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlck5vdGVzUmVzdWx0IGV4dGVuZHMgWEhTUmVzcG9uc2U8VXNlck5vdGVbXT4ge1xuICByZWFkb25seSB0b3RhbDogbnVtYmVyO1xuICByZWFkb25seSBoYXNNb3JlOiBib29sZWFuO1xuICByZWFkb25seSBuZXh0Q3Vyc29yPzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgTm90ZUV4dHJhY3Rpb25EYXRhIHtcbiAgaWQ6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgY29udGVudDogc3RyaW5nO1xuICBpbWFnZXM6IHN0cmluZ1tdO1xuICBwdWJsaXNoVGltZTogbnVtYmVyO1xuICB1cGRhdGVUaW1lOiBudW1iZXI7XG4gIGxpa2VDb3VudDogbnVtYmVyO1xuICBjb21tZW50Q291bnQ6IG51bWJlcjtcbiAgc2hhcmVDb3VudDogbnVtYmVyO1xuICBjb2xsZWN0Q291bnQ6IG51bWJlcjtcbiAgdGFnczogc3RyaW5nW107XG4gIHVybDogc3RyaW5nO1xuICB2aXNpYmlsaXR5OiAncHVibGljJyB8ICdwcml2YXRlJyB8ICdmcmllbmRzJyB8ICd1bmtub3duJztcbiAgdmlzaWJpbGl0eVRleHQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBDU1Mgc2VsZWN0b3JzIGZvciBub3RlIGV4dHJhY3Rpb24gZnJvbSBDcmVhdG9yIENlbnRlclxuICovXG5jb25zdCBOT1RFX1NFTEVDVE9SUyA9IHtcbiAgTk9URV9FTEVNRU5UUzogJ2Rpdi5ub3RlJyxcbiAgVElUTEVfRUxFTUVOVFM6ICdbY2xhc3MqPVwicmF3XCJdLCBbY2xhc3MqPVwidGl0bGVcIl0sIFtjbGFzcyo9XCJuYW1lXCJdJyxcbiAgSU1BR0VfRUxFTUVOVFM6ICdpbWdbY2xhc3MqPVwibWVkaWFcIl0sIGltZ1tjbGFzcyo9XCJjb3ZlclwiXSwgaW1nW2NsYXNzKj1cInRodW1ibmFpbFwiXScsXG4gIFNUQVRfRUxFTUVOVFM6ICdbY2xhc3MqPVwiY291bnRcIl0sIFtjbGFzcyo9XCJzdGF0XCJdLCBbY2xhc3MqPVwibnVtYmVyXCJdJyxcbiAgVEFHX0VMRU1FTlRTOiAnW2NsYXNzKj1cInRhZ1wiXSwgW2NsYXNzKj1cImxhYmVsXCJdJyxcbiAgTk9URV9MSU5LOiAnYVtocmVmKj1cIi9leHBsb3JlL1wiXSwgYVtocmVmKj1cIi9ub3RlL1wiXScsXG4gIFZJU0lCSUxJVFlfSU5ESUNBVE9SUzpcbiAgICAnW2NsYXNzKj1cInByaXZhdGVcIl0sIFtjbGFzcyo9XCJ2aXNpYmlsaXR5XCJdLCBbY2xhc3MqPVwibG9ja1wiXSwgW2NsYXNzKj1cImV5ZVwiXSwgW2NsYXNzKj1cInB1YmxpY1wiXSwgW2NsYXNzKj1cImZyaWVuZHNcIl0sIFtjbGFzcyo9XCJzdGF0dXNcIl0nLFxuICBQVUJMSVNIX1RJTUU6ICdbY2xhc3MqPVwidGltZVwiXSwgW2NsYXNzKj1cImRhdGVcIl0sIFtjbGFzcyo9XCJwdWJsaXNoLXRpbWVcIl0nLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IGNsYXNzIE5vdGVTZXJ2aWNlIGV4dGVuZHMgQmFzZVNlcnZpY2Uge1xuICBwcml2YXRlIGRlbGV0ZVNlcnZpY2U6IERlbGV0ZVNlcnZpY2U7XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcsIGJyb3dzZXJNYW5hZ2VyPzogQnJvd3Nlck1hbmFnZXIpIHtcbiAgICBzdXBlcihjb25maWcsIGJyb3dzZXJNYW5hZ2VyKTtcbiAgICB0aGlzLmRlbGV0ZVNlcnZpY2UgPSBuZXcgRGVsZXRlU2VydmljZShjb25maWcsIHRoaXMuYnJvd3Nlck1hbmFnZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHVzZXIncyBwdWJsaXNoZWQgbm90ZXMgZnJvbSBjcmVhdG9yIGNlbnRlclxuICAgKiBAcGFyYW0gbGltaXQgLSBNYXhpbXVtIG51bWJlciBvZiBub3RlcyB0byByZXR1cm4gKGRlZmF1bHQ6IDIwKVxuICAgKiBAcGFyYW0gY3Vyc29yIC0gUGFnaW5hdGlvbiBjdXJzb3IgZm9yIG5leHQgcGFnZVxuICAgKiBAcGFyYW0gYnJvd3NlclBhdGggLSBPcHRpb25hbCBjdXN0b20gYnJvd3NlciBwYXRoXG4gICAqIEByZXR1cm5zIFByb21pc2U8VXNlck5vdGVzUmVzdWx0PiAtIFVzZXIgbm90ZXMgd2l0aCBwYWdpbmF0aW9uIGluZm9cbiAgICovXG4gIGFzeW5jIGdldFVzZXJOb3RlcyhcbiAgICBsaW1pdDogbnVtYmVyID0gMjAsXG4gICAgY3Vyc29yPzogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8VXNlck5vdGVzUmVzdWx0PiB7XG4gICAgdGhpcy52YWxpZGF0ZUdldFVzZXJOb3Rlc1BhcmFtcyhsaW1pdCk7XG5cbiAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UodHJ1ZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIE5hdmlnYXRlIHRvIGNyZWF0b3IgY2VudGVyIG5vdGUgbWFuYWdlclxuICAgICAgYXdhaXQgbmF2aWdhdGVUb0NyZWF0b3JDZW50ZXIocGFnZSk7XG4gICAgICBhd2FpdCB2ZXJpZnlDcmVhdG9yQXV0aChwYWdlLCB0aGlzLmdldENvbmZpZygpLnhocy5sb2dpbk9rU2VsZWN0b3IpO1xuXG4gICAgICAvLyBFeHRyYWN0IG5vdGVzIGZyb20gY3JlYXRvciBjZW50ZXJcbiAgICAgIGNvbnN0IG5vdGVzRGF0YSA9IGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVzRnJvbUNyZWF0b3JDZW50ZXIocGFnZSk7XG4gICAgICBjb25zdCBsaW1pdGVkTm90ZXMgPSB0aGlzLmxpbWl0Tm90ZXMobm90ZXNEYXRhLCBsaW1pdCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIGRhdGE6IGxpbWl0ZWROb3RlcyxcbiAgICAgICAgdG90YWw6IG5vdGVzRGF0YS5sZW5ndGgsXG4gICAgICAgIGhhc01vcmU6IG5vdGVzRGF0YS5sZW5ndGggPiBsaW1pdCxcbiAgICAgICAgbmV4dEN1cnNvcjogdGhpcy5nZXROZXh0Q3Vyc29yKGxpbWl0ZWROb3RlcyksXG4gICAgICAgIG9wZXJhdGlvbjogJ2dldFVzZXJOb3RlcycsXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlck5vdGVzUmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBnZXQgdXNlciBub3RlczogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBkYXRhOiBbXSxcbiAgICAgICAgdG90YWw6IDAsXG4gICAgICAgIGhhc01vcmU6IGZhbHNlLFxuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICBvcGVyYXRpb246ICdnZXRVc2VyTm90ZXMnLFxuICAgICAgfSBhcyB1bmtub3duIGFzIFVzZXJOb3Rlc1Jlc3VsdDtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBwYXJhbWV0ZXJzIGZvciBnZXRVc2VyTm90ZXMgbWV0aG9kXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlR2V0VXNlck5vdGVzUGFyYW1zKGxpbWl0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAobGltaXQgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IE5vdGVQYXJzaW5nRXJyb3IoJ0xpbWl0IG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnLCB7IGxpbWl0IH0pO1xuICAgIH1cbiAgICBpZiAobGltaXQgPiAxMDApIHtcbiAgICAgIHRocm93IG5ldyBOb3RlUGFyc2luZ0Vycm9yKCdMaW1pdCBjYW5ub3QgZXhjZWVkIDEwMCcsIHsgbGltaXQgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3Qgbm90ZXMgZnJvbSBjcmVhdG9yIGNlbnRlciBwYWdlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4dHJhY3ROb3Rlc0Zyb21DcmVhdG9yQ2VudGVyKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPE5vdGVFeHRyYWN0aW9uRGF0YVtdPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG5vdGVzRGF0YSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKHNlbGVjdG9yczogdHlwZW9mIE5PVEVfU0VMRUNUT1JTKSA9PiB7XG4gICAgICAgIGNvbnN0IG5vdGVzOiBOb3RlRXh0cmFjdGlvbkRhdGFbXSA9IFtdO1xuXG4gICAgICAgIC8vIEZpbmQgbm90ZSBlbGVtZW50cyB1c2luZyB0aGUgY3JlYXRvciBjZW50ZXIgc2VsZWN0b3JcbiAgICAgICAgY29uc3Qgbm90ZUVsZW1lbnRzID0gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9ycy5OT1RFX0VMRU1FTlRTKSk7XG5cbiAgICAgICAgbm90ZUVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQ6IEVsZW1lbnQpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gRXh0cmFjdCBub3RlIGRhdGEgZnJvbSBlbGVtZW50XG4gICAgICAgICAgICBjb25zdCBwdWJsaXNoVGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICBjb25zdCBub3RlOiBOb3RlRXh0cmFjdGlvbkRhdGEgPSB7XG4gICAgICAgICAgICAgIGlkOiAnJyxcbiAgICAgICAgICAgICAgdGl0bGU6ICcnLFxuICAgICAgICAgICAgICBjb250ZW50OiAnJyxcbiAgICAgICAgICAgICAgaW1hZ2VzOiBbXSxcbiAgICAgICAgICAgICAgcHVibGlzaFRpbWUsXG4gICAgICAgICAgICAgIHVwZGF0ZVRpbWU6IHB1Ymxpc2hUaW1lLFxuICAgICAgICAgICAgICBsaWtlQ291bnQ6IDAsXG4gICAgICAgICAgICAgIGNvbW1lbnRDb3VudDogMCxcbiAgICAgICAgICAgICAgc2hhcmVDb3VudDogMCxcbiAgICAgICAgICAgICAgY29sbGVjdENvdW50OiAwLFxuICAgICAgICAgICAgICB0YWdzOiBbXSxcbiAgICAgICAgICAgICAgdXJsOiAnJyxcbiAgICAgICAgICAgICAgdmlzaWJpbGl0eTogJ3Vua25vd24nLFxuICAgICAgICAgICAgICB2aXNpYmlsaXR5VGV4dDogJycsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IG5vdGUgSUQgZnJvbSBkYXRhIGF0dHJpYnV0ZXMgb3IgaW1wcmVzc2lvbiBkYXRhXG4gICAgICAgICAgICBjb25zdCBpbXByZXNzaW9uRGF0YSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWltcHJlc3Npb24nKTtcbiAgICAgICAgICAgIGlmIChpbXByZXNzaW9uRGF0YSkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoaW1wcmVzc2lvbkRhdGEpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG5vdGVJZCA9IHBhcnNlZD8ubm90ZVRhcmdldD8udmFsdWU/Lm5vdGVJZDtcbiAgICAgICAgICAgICAgICBpZiAobm90ZUlkKSB7XG4gICAgICAgICAgICAgICAgICBub3RlLmlkID0gbm90ZUlkO1xuICAgICAgICAgICAgICAgICAgbm90ZS51cmwgPSBgaHR0cHM6Ly93d3cueGlhb2hvbmdzaHUuY29tL2V4cGxvcmUvJHtub3RlSWR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBJZ25vcmUgcGFyc2luZyBlcnJvcnNcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IHRpdGxlL2NvbnRlbnRcbiAgICAgICAgICAgIGNvbnN0IHRpdGxlRWxlbWVudCA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcnMuVElUTEVfRUxFTUVOVFMpO1xuICAgICAgICAgICAgaWYgKHRpdGxlRWxlbWVudCkge1xuICAgICAgICAgICAgICBjb25zdCB0aXRsZSA9IHRpdGxlRWxlbWVudC50ZXh0Q29udGVudD8udHJpbSgpID8/ICcnO1xuICAgICAgICAgICAgICBub3RlLnRpdGxlID0gdGl0bGU7XG4gICAgICAgICAgICAgIG5vdGUuY29udGVudCA9IHRpdGxlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IGltYWdlcyAtIHRyeSBtdWx0aXBsZSBhcHByb2FjaGVzIGZvciBjcmVhdG9yIGNlbnRlclxuICAgICAgICAgICAgY29uc3QgaW1hZ2VTZWxlY3RvcnMgPSBbXG4gICAgICAgICAgICAgIHNlbGVjdG9ycy5JTUFHRV9FTEVNRU5UUyxcbiAgICAgICAgICAgICAgJ2ltZycsIC8vIFRyeSBhbGwgaW1nIGVsZW1lbnRzXG4gICAgICAgICAgICAgICdbY2xhc3MqPVwiaW1hZ2VcIl0nLFxuICAgICAgICAgICAgICAnW2NsYXNzKj1cInBob3RvXCJdJyxcbiAgICAgICAgICAgICAgJ1tjbGFzcyo9XCJwaWNcIl0nLFxuICAgICAgICAgICAgICAnW2NsYXNzKj1cImltZ1wiXScsXG4gICAgICAgICAgICAgICdbc3R5bGUqPVwiYmFja2dyb3VuZC1pbWFnZVwiXScsIC8vIEJhY2tncm91bmQgaW1hZ2VzXG4gICAgICAgICAgICAgICdkaXZbY2xhc3MqPVwiY292ZXJcIl0gaW1nJyxcbiAgICAgICAgICAgICAgJ2RpdltjbGFzcyo9XCJ0aHVtYm5haWxcIl0gaW1nJyxcbiAgICAgICAgICAgICAgJ2RpdltjbGFzcyo9XCJtZWRpYVwiXSBpbWcnLFxuICAgICAgICAgICAgXTtcblxuICAgICAgICAgICAgbGV0IGltYWdlRWxlbWVudHM6IGFueVtdID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIGltYWdlU2VsZWN0b3JzKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcbiAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBpbWFnZUVsZW1lbnRzID0gQXJyYXkuZnJvbShlbGVtZW50cyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaW1hZ2VFbGVtZW50cy5mb3JFYWNoKChpbWc6IEVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgbGV0IHNyYyA9ICcnO1xuXG4gICAgICAgICAgICAgIC8vIFRyeSBkaWZmZXJlbnQgd2F5cyB0byBnZXQgaW1hZ2Ugc291cmNlXG4gICAgICAgICAgICAgIGNvbnN0IGh0bWxJbWcgPSBpbWcgYXMgSFRNTEltYWdlRWxlbWVudDtcbiAgICAgICAgICAgICAgaWYgKGh0bWxJbWcuc3JjKSB7XG4gICAgICAgICAgICAgICAgc3JjID0gaHRtbEltZy5zcmM7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoaHRtbEltZy5zdHlsZSAmJiBodG1sSW1nLnN0eWxlLmJhY2tncm91bmRJbWFnZSkge1xuICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgZnJvbSBiYWNrZ3JvdW5kLWltYWdlIENTU1xuICAgICAgICAgICAgICAgIGNvbnN0IGJnTWF0Y2ggPSBodG1sSW1nLnN0eWxlLmJhY2tncm91bmRJbWFnZS5tYXRjaCgvdXJsXFwoWydcIl0/KFteJ1wiXSspWydcIl0/XFwpLyk7XG4gICAgICAgICAgICAgICAgaWYgKGJnTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgIHNyYyA9IGJnTWF0Y2hbMV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGltZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtc3JjJykpIHtcbiAgICAgICAgICAgICAgICAvLyBMYXp5IGxvYWRlZCBpbWFnZXNcbiAgICAgICAgICAgICAgICBzcmMgPSBpbWcuZ2V0QXR0cmlidXRlKCdkYXRhLXNyYycpIHx8ICcnO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGltZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JpZ2luYWwnKSkge1xuICAgICAgICAgICAgICAgIC8vIEFub3RoZXIgbGF6eSBsb2FkaW5nIGF0dHJpYnV0ZVxuICAgICAgICAgICAgICAgIHNyYyA9IGltZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JpZ2luYWwnKSB8fCAnJztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBzcmMgJiZcbiAgICAgICAgICAgICAgICAhc3JjLmluY2x1ZGVzKCdhdmF0YXInKSAmJlxuICAgICAgICAgICAgICAgICFzcmMuaW5jbHVkZXMoJ2ljb24nKSAmJlxuICAgICAgICAgICAgICAgICFzcmMuaW5jbHVkZXMoJ2xvZ28nKSAmJlxuICAgICAgICAgICAgICAgICFzcmMuaW5jbHVkZXMoJ3BsYWNlaG9sZGVyJykgJiZcbiAgICAgICAgICAgICAgICBzcmMuc3RhcnRzV2l0aCgnaHR0cCcpXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIG5vdGUuaW1hZ2VzLnB1c2goc3JjKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cblxuICAgICAgICAgICAgLy8gRXh0cmFjdCBzdGF0cyAtIGxvb2sgZm9yIG51bWJlcnMgaW4gdGhlIGVsZW1lbnRcbiAgICAgICAgICAgIGNvbnN0IGFsbFRleHQgPSBlbGVtZW50LnRleHRDb250ZW50IHx8ICcnO1xuICAgICAgICAgICAgY29uc3QgbnVtYmVycyA9IGFsbFRleHQubWF0Y2goL1xcZCsvZykgfHwgW107XG5cbiAgICAgICAgICAgIC8vIFRyeSB0byBleHRyYWN0IHN0YXRzIGZyb20gdGV4dCBjb250ZW50XG4gICAgICAgICAgICBpZiAobnVtYmVycy5sZW5ndGggPj0gNCkge1xuICAgICAgICAgICAgICAvLyBBc3N1bWluZyBvcmRlcjogbGlrZSwgY29tbWVudCwgc2hhcmUsIGNvbGxlY3QsIHZpZXdcbiAgICAgICAgICAgICAgbm90ZS5saWtlQ291bnQgPSBwYXJzZUludChudW1iZXJzWzBdIHx8ICcwJykgfHwgMDtcbiAgICAgICAgICAgICAgbm90ZS5jb21tZW50Q291bnQgPSBwYXJzZUludChudW1iZXJzWzFdKSB8fCAwO1xuICAgICAgICAgICAgICBub3RlLnNoYXJlQ291bnQgPSBwYXJzZUludChudW1iZXJzWzJdKSB8fCAwO1xuICAgICAgICAgICAgICBub3RlLmNvbGxlY3RDb3VudCA9IHBhcnNlSW50KG51bWJlcnNbM10pIHx8IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEV4dHJhY3QgcHVibGlzaCB0aW1lXG4gICAgICAgICAgICBjb25zdCB0aW1lRWxlbWVudCA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcnMuUFVCTElTSF9USU1FKTtcbiAgICAgICAgICAgIGlmICh0aW1lRWxlbWVudCkge1xuICAgICAgICAgICAgICBjb25zdCB0aW1lVGV4dCA9IHRpbWVFbGVtZW50LnRleHRDb250ZW50Py50cmltKCkgfHwgJyc7XG4gICAgICAgICAgICAgIGlmICh0aW1lVGV4dC5pbmNsdWRlcygn5Y+R5biD5LqOJykpIHtcbiAgICAgICAgICAgICAgICAvLyBQYXJzZSBDaGluZXNlIGRhdGUgZm9ybWF0XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZU1hdGNoID0gdGltZVRleHQubWF0Y2goXG4gICAgICAgICAgICAgICAgICAvKFxcZHs0fSnlubQoXFxkezEsMn0p5pyIKFxcZHsxLDJ9KeaXpVxccysoXFxkezEsMn0pOihcXGR7Mn0pL1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGVNYXRjaCkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgWywgeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlXSA9IGRhdGVNYXRjaDtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHB1Ymxpc2hEYXRlID0gbmV3IERhdGUoXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlSW50KHllYXIpLFxuICAgICAgICAgICAgICAgICAgICBwYXJzZUludChtb250aCkgLSAxLFxuICAgICAgICAgICAgICAgICAgICBwYXJzZUludChkYXkpLFxuICAgICAgICAgICAgICAgICAgICBwYXJzZUludChob3VyKSxcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VJbnQobWludXRlKVxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIG5vdGUucHVibGlzaFRpbWUgPSBwdWJsaXNoRGF0ZS5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgICBub3RlLnVwZGF0ZVRpbWUgPSBwdWJsaXNoRGF0ZS5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEV4dHJhY3QgdmlzaWJpbGl0eSBpbmZvcm1hdGlvblxuICAgICAgICAgICAgY29uc3QgZWxlbWVudFRleHQgPSBlbGVtZW50LnRleHRDb250ZW50Py50b0xvd2VyQ2FzZSgpIHx8ICcnO1xuICAgICAgICAgICAgaWYgKGVsZW1lbnRUZXh0LmluY2x1ZGVzKCfku4Xoh6rlt7Hlj6/op4EnKSkge1xuICAgICAgICAgICAgICBub3RlLnZpc2liaWxpdHkgPSAncHJpdmF0ZSc7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eVRleHQgPSAn5LuF6Ieq5bex5Y+v6KeBJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudFRleHQuaW5jbHVkZXMoJ+aci+WPi+WPr+ingScpKSB7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eSA9ICdmcmllbmRzJztcbiAgICAgICAgICAgICAgbm90ZS52aXNpYmlsaXR5VGV4dCA9ICfmnIvlj4vlj6/op4EnO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50VGV4dC5pbmNsdWRlcygn5YWs5byAJykpIHtcbiAgICAgICAgICAgICAgbm90ZS52aXNpYmlsaXR5ID0gJ3B1YmxpYyc7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eVRleHQgPSAn5YWs5byAJztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIERlZmF1bHQgdG8gcHVibGljIGZvciBub3RlcyB3aXRob3V0IGV4cGxpY2l0IHZpc2liaWxpdHkgaW5kaWNhdG9yc1xuICAgICAgICAgICAgICBub3RlLnZpc2liaWxpdHkgPSAncHVibGljJztcbiAgICAgICAgICAgICAgbm90ZS52aXNpYmlsaXR5VGV4dCA9ICflhazlvIAnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IHRhZ3NcbiAgICAgICAgICAgIGNvbnN0IHRhZ0VsZW1lbnRzID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9ycy5UQUdfRUxFTUVOVFMpO1xuICAgICAgICAgICAgdGFnRWxlbWVudHMuZm9yRWFjaCgodGFnOiBFbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHRhZ1RleHQgPSB0YWcudGV4dENvbnRlbnQ/LnRyaW0oKTtcbiAgICAgICAgICAgICAgaWYgKHRhZ1RleHQ/LnN0YXJ0c1dpdGgoJyMnKSkge1xuICAgICAgICAgICAgICAgIG5vdGUudGFncy5wdXNoKHRhZ1RleHQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKG5vdGUuaWQpIHtcbiAgICAgICAgICAgICAgbm90ZXMucHVzaChub3RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgLy8gSWdub3JlIGV4dHJhY3Rpb24gZXJyb3JzIGZvciBpbmRpdmlkdWFsIG5vdGVzXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbm90ZXM7XG4gICAgICB9LCBOT1RFX1NFTEVDVE9SUyk7XG5cbiAgICAgIHJldHVybiBub3Rlc0RhdGE7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBOb3RlUGFyc2luZ0Vycm9yKFxuICAgICAgICAnRmFpbGVkIHRvIGV4dHJhY3Qgbm90ZXMgZnJvbSBjcmVhdG9yIGNlbnRlcicsXG4gICAgICAgIHsgb3BlcmF0aW9uOiAnZXh0cmFjdE5vdGVzRnJvbUNyZWF0b3JDZW50ZXInIH0sXG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGltaXQgbm90ZXMgYXJyYXkgdG8gc3BlY2lmaWVkIGNvdW50XG4gICAqL1xuICBwcml2YXRlIGxpbWl0Tm90ZXMobm90ZXM6IE5vdGVFeHRyYWN0aW9uRGF0YVtdLCBsaW1pdDogbnVtYmVyKTogVXNlck5vdGVbXSB7XG4gICAgcmV0dXJuIG5vdGVzLnNsaWNlKDAsIGxpbWl0KS5tYXAoKG5vdGUpID0+ICh7XG4gICAgICBpZDogbm90ZS5pZCxcbiAgICAgIHRpdGxlOiBub3RlLnRpdGxlLFxuICAgICAgY29udGVudDogbm90ZS5jb250ZW50LFxuICAgICAgaW1hZ2VzOiBPYmplY3QuZnJlZXplKFsuLi5ub3RlLmltYWdlc10pLFxuICAgICAgcHVibGlzaFRpbWU6IG5vdGUucHVibGlzaFRpbWUsXG4gICAgICB1cGRhdGVUaW1lOiBub3RlLnVwZGF0ZVRpbWUsXG4gICAgICBsaWtlQ291bnQ6IG5vdGUubGlrZUNvdW50LFxuICAgICAgY29tbWVudENvdW50OiBub3RlLmNvbW1lbnRDb3VudCxcbiAgICAgIHNoYXJlQ291bnQ6IG5vdGUuc2hhcmVDb3VudCxcbiAgICAgIGNvbGxlY3RDb3VudDogbm90ZS5jb2xsZWN0Q291bnQsXG4gICAgICB0YWdzOiBPYmplY3QuZnJlZXplKFsuLi5ub3RlLnRhZ3NdKSxcbiAgICAgIHVybDogbm90ZS51cmwsXG4gICAgICB2aXNpYmlsaXR5OiBub3RlLnZpc2liaWxpdHksXG4gICAgICB2aXNpYmlsaXR5VGV4dDogbm90ZS52aXNpYmlsaXR5VGV4dCxcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IG5leHQgY3Vyc29yIGZvciBwYWdpbmF0aW9uXG4gICAqL1xuICBwcml2YXRlIGdldE5leHRDdXJzb3Iobm90ZXM6IFVzZXJOb3RlW10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBub3Rlcy5sZW5ndGggPiAwID8gbm90ZXNbbm90ZXMubGVuZ3RoIC0gMV0uaWQgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGEgc3BlY2lmaWMgbm90ZSBieSBJRFxuICAgKiBAcGFyYW0gbm90ZUlkIC0gVGhlIElEIG9mIHRoZSBub3RlIHRvIGRlbGV0ZVxuICAgKiBAcGFyYW0gYnJvd3NlclBhdGggLSBPcHRpb25hbCBjdXN0b20gYnJvd3NlciBwYXRoXG4gICAqIEByZXR1cm5zIFByb21pc2U8RGVsZXRlUmVzdWx0PiAtIERlbGV0ZSBvcGVyYXRpb24gcmVzdWx0XG4gICAqL1xuICBhc3luYyBkZWxldGVOb3RlKG5vdGVJZDogc3RyaW5nLCBicm93c2VyUGF0aD86IHN0cmluZyk6IFByb21pc2U8RGVsZXRlUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZXRlU2VydmljZS5kZWxldGVOb3RlKG5vdGVJZCwgYnJvd3NlclBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgbGFzdCBwdWJsaXNoZWQgbm90ZVxuICAgKiBAcGFyYW0gYnJvd3NlclBhdGggLSBPcHRpb25hbCBjdXN0b20gYnJvd3NlciBwYXRoXG4gICAqIEByZXR1cm5zIFByb21pc2U8RGVsZXRlUmVzdWx0PiAtIERlbGV0ZSBvcGVyYXRpb24gcmVzdWx0XG4gICAqL1xuICBhc3luYyBkZWxldGVMYXN0UHVibGlzaGVkTm90ZShicm93c2VyUGF0aD86IHN0cmluZyk6IFByb21pc2U8RGVsZXRlUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZXRlU2VydmljZS5kZWxldGVMYXN0UHVibGlzaGVkTm90ZShicm93c2VyUGF0aCk7XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9113\n\n}");
137
+
138
+ /***/ }),
139
+
140
+ /***/ 9135:
141
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
142
+
143
+ eval("{/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ v: () => (/* binding */ logger)\n/* harmony export */ });\n/* unused harmony export Logger */\n/**\n * Logger for XHS MCP Server\n * Avoids logging to stderr in stdio mode to prevent interference with MCP protocol\n */\nclass Logger {\n static instance;\n enabled = false;\n constructor() {\n // Only enable logging if not in stdio mode\n // In stdio mode, we suppress all logging to avoid interfering with MCP protocol\n this.enabled = process.env.XHS_ENABLE_LOGGING === 'true';\n }\n static getInstance() {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n return Logger.instance;\n }\n debug(message, ...args) {\n if (this.enabled) {\n console.error(`[DEBUG] ${message}`, ...args);\n }\n }\n info(message, ...args) {\n if (this.enabled) {\n console.error(`[INFO] ${message}`, ...args);\n }\n }\n warn(message, ...args) {\n if (this.enabled) {\n console.error(`[WARN] ${message}`, ...args);\n }\n }\n error(message, ...args) {\n if (this.enabled) {\n console.error(`[ERROR] ${message}`, ...args);\n }\n }\n}\nconst logger = Logger.getInstance();\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTEzNS5qcyIsIm1hcHBpbmdzIjoiOzs7O0FBQUE7OztHQUdHO0FBRUksTUFBTSxNQUFNO0lBQ1QsTUFBTSxDQUFDLFFBQVEsQ0FBUztJQUN4QixPQUFPLEdBQVksS0FBSyxDQUFDO0lBRWpDO1FBQ0UsMkNBQTJDO1FBQzNDLGdGQUFnRjtRQUNoRixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEtBQUssTUFBTSxDQUFDO0lBQzNELENBQUM7SUFFTSxNQUFNLENBQUMsV0FBVztRQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3JCLE1BQU0sQ0FBQyxRQUFRLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUNqQyxDQUFDO1FBQ0QsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDO0lBQ3pCLENBQUM7SUFFTSxLQUFLLENBQUMsT0FBZSxFQUFFLEdBQUcsSUFBZTtRQUM5QyxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQixPQUFPLENBQUMsS0FBSyxDQUFDLFdBQVcsT0FBTyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztRQUMvQyxDQUFDO0lBQ0gsQ0FBQztJQUVNLElBQUksQ0FBQyxPQUFlLEVBQUUsR0FBRyxJQUFlO1FBQzdDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxPQUFPLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQzlDLENBQUM7SUFDSCxDQUFDO0lBRU0sSUFBSSxDQUFDLE9BQWUsRUFBRSxHQUFHLElBQWU7UUFDN0MsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsT0FBTyxDQUFDLEtBQUssQ0FBQyxVQUFVLE9BQU8sRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDOUMsQ0FBQztJQUNILENBQUM7SUFFTSxLQUFLLENBQUMsT0FBZSxFQUFFLEdBQUcsSUFBZTtRQUM5QyxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQixPQUFPLENBQUMsS0FBSyxDQUFDLFdBQVcsT0FBTyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztRQUMvQyxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBRU0sTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQvbG9nZ2VyLnRzPzEzOTIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBMb2dnZXIgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKiBBdm9pZHMgbG9nZ2luZyB0byBzdGRlcnIgaW4gc3RkaW8gbW9kZSB0byBwcmV2ZW50IGludGVyZmVyZW5jZSB3aXRoIE1DUCBwcm90b2NvbFxuICovXG5cbmV4cG9ydCBjbGFzcyBMb2dnZXIge1xuICBwcml2YXRlIHN0YXRpYyBpbnN0YW5jZTogTG9nZ2VyO1xuICBwcml2YXRlIGVuYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIE9ubHkgZW5hYmxlIGxvZ2dpbmcgaWYgbm90IGluIHN0ZGlvIG1vZGVcbiAgICAvLyBJbiBzdGRpbyBtb2RlLCB3ZSBzdXBwcmVzcyBhbGwgbG9nZ2luZyB0byBhdm9pZCBpbnRlcmZlcmluZyB3aXRoIE1DUCBwcm90b2NvbFxuICAgIHRoaXMuZW5hYmxlZCA9IHByb2Nlc3MuZW52LlhIU19FTkFCTEVfTE9HR0lORyA9PT0gJ3RydWUnO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBnZXRJbnN0YW5jZSgpOiBMb2dnZXIge1xuICAgIGlmICghTG9nZ2VyLmluc3RhbmNlKSB7XG4gICAgICBMb2dnZXIuaW5zdGFuY2UgPSBuZXcgTG9nZ2VyKCk7XG4gICAgfVxuICAgIHJldHVybiBMb2dnZXIuaW5zdGFuY2U7XG4gIH1cblxuICBwdWJsaWMgZGVidWcobWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lbmFibGVkKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBbREVCVUddICR7bWVzc2FnZX1gLCAuLi5hcmdzKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgaW5mbyhtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmVuYWJsZWQpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFtJTkZPXSAke21lc3NhZ2V9YCwgLi4uYXJncyk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHdhcm4obWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lbmFibGVkKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBbV0FSTl0gJHttZXNzYWdlfWAsIC4uLmFyZ3MpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBlcnJvcihtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmVuYWJsZWQpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFtFUlJPUl0gJHttZXNzYWdlfWAsIC4uLmFyZ3MpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgbG9nZ2VyID0gTG9nZ2VyLmdldEluc3RhbmNlKCk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9135\n\n}");
144
+
145
+ /***/ }),
146
+
147
+ /***/ 9896:
148
+ /***/ ((module) => {
149
+
150
+ module.exports = require("fs");
151
+
152
+ /***/ }),
153
+
154
+ /***/ 9916:
155
+ /***/ ((module) => {
156
+
157
+ module.exports = require("puppeteer");
158
+
159
+ /***/ })
160
+
161
+ /******/ });
162
+ /************************************************************************/
163
+ /******/ // The module cache
164
+ /******/ var __webpack_module_cache__ = {};
165
+ /******/
166
+ /******/ // The require function
167
+ /******/ function __webpack_require__(moduleId) {
168
+ /******/ // Check if module is in cache
169
+ /******/ var cachedModule = __webpack_module_cache__[moduleId];
170
+ /******/ if (cachedModule !== undefined) {
171
+ /******/ return cachedModule.exports;
172
+ /******/ }
173
+ /******/ // Create a new module (and put it into the cache)
174
+ /******/ var module = __webpack_module_cache__[moduleId] = {
175
+ /******/ // no module.id needed
176
+ /******/ // no module.loaded needed
177
+ /******/ exports: {}
178
+ /******/ };
179
+ /******/
180
+ /******/ // Execute the module function
181
+ /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
182
+ /******/
183
+ /******/ // Return the exports of the module
184
+ /******/ return module.exports;
185
+ /******/ }
186
+ /******/
187
+ /******/ // expose the modules object (__webpack_modules__)
188
+ /******/ __webpack_require__.m = __webpack_modules__;
189
+ /******/
190
+ /******/ // the startup function
191
+ /******/ __webpack_require__.x = () => {
192
+ /******/ // Load entry module and return exports
193
+ /******/ // This entry module depends on other loaded chunks and execution need to be delayed
194
+ /******/ var __webpack_exports__ = __webpack_require__.O(undefined, [449], () => (__webpack_require__(5582)))
195
+ /******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
196
+ /******/ return __webpack_exports__;
197
+ /******/ };
198
+ /******/
199
+ /************************************************************************/
200
+ /******/ /* webpack/runtime/chunk loaded */
201
+ /******/ (() => {
202
+ /******/ var deferred = [];
203
+ /******/ __webpack_require__.O = (result, chunkIds, fn, priority) => {
204
+ /******/ if(chunkIds) {
205
+ /******/ priority = priority || 0;
206
+ /******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
207
+ /******/ deferred[i] = [chunkIds, fn, priority];
208
+ /******/ return;
209
+ /******/ }
210
+ /******/ var notFulfilled = Infinity;
211
+ /******/ for (var i = 0; i < deferred.length; i++) {
212
+ /******/ var [chunkIds, fn, priority] = deferred[i];
213
+ /******/ var fulfilled = true;
214
+ /******/ for (var j = 0; j < chunkIds.length; j++) {
215
+ /******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
216
+ /******/ chunkIds.splice(j--, 1);
217
+ /******/ } else {
218
+ /******/ fulfilled = false;
219
+ /******/ if(priority < notFulfilled) notFulfilled = priority;
220
+ /******/ }
221
+ /******/ }
222
+ /******/ if(fulfilled) {
223
+ /******/ deferred.splice(i--, 1)
224
+ /******/ var r = fn();
225
+ /******/ if (r !== undefined) result = r;
226
+ /******/ }
227
+ /******/ }
228
+ /******/ return result;
229
+ /******/ };
230
+ /******/ })();
231
+ /******/
232
+ /******/ /* webpack/runtime/compat get default export */
233
+ /******/ (() => {
234
+ /******/ // getDefaultExport function for compatibility with non-harmony modules
235
+ /******/ __webpack_require__.n = (module) => {
236
+ /******/ var getter = module && module.__esModule ?
237
+ /******/ () => (module['default']) :
238
+ /******/ () => (module);
239
+ /******/ __webpack_require__.d(getter, { a: getter });
240
+ /******/ return getter;
241
+ /******/ };
242
+ /******/ })();
243
+ /******/
244
+ /******/ /* webpack/runtime/define property getters */
245
+ /******/ (() => {
246
+ /******/ // define getter functions for harmony exports
247
+ /******/ __webpack_require__.d = (exports, definition) => {
248
+ /******/ for(var key in definition) {
249
+ /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
250
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
251
+ /******/ }
252
+ /******/ }
253
+ /******/ };
254
+ /******/ })();
255
+ /******/
256
+ /******/ /* webpack/runtime/ensure chunk */
257
+ /******/ (() => {
258
+ /******/ __webpack_require__.f = {};
259
+ /******/ // This file contains only the entry chunk.
260
+ /******/ // The chunk loading function for additional chunks
261
+ /******/ __webpack_require__.e = (chunkId) => {
262
+ /******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
263
+ /******/ __webpack_require__.f[key](chunkId, promises);
264
+ /******/ return promises;
265
+ /******/ }, []));
266
+ /******/ };
267
+ /******/ })();
268
+ /******/
269
+ /******/ /* webpack/runtime/get javascript chunk filename */
270
+ /******/ (() => {
271
+ /******/ // This function allow to reference async chunks and chunks that the entrypoint depends on
272
+ /******/ __webpack_require__.u = (chunkId) => {
273
+ /******/ // return url for filenames based on template
274
+ /******/ return "" + chunkId + ".cjs";
275
+ /******/ };
276
+ /******/ })();
277
+ /******/
278
+ /******/ /* webpack/runtime/hasOwnProperty shorthand */
279
+ /******/ (() => {
280
+ /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
281
+ /******/ })();
282
+ /******/
283
+ /******/ /* webpack/runtime/require chunk loading */
284
+ /******/ (() => {
285
+ /******/ // no baseURI
286
+ /******/
287
+ /******/ // object to store loaded chunks
288
+ /******/ // "1" means "loaded", otherwise not loaded yet
289
+ /******/ var installedChunks = {
290
+ /******/ 753: 1
291
+ /******/ };
292
+ /******/
293
+ /******/ __webpack_require__.O.require = (chunkId) => (installedChunks[chunkId]);
294
+ /******/
295
+ /******/ var installChunk = (chunk) => {
296
+ /******/ var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;
297
+ /******/ for(var moduleId in moreModules) {
298
+ /******/ if(__webpack_require__.o(moreModules, moduleId)) {
299
+ /******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
300
+ /******/ }
301
+ /******/ }
302
+ /******/ if(runtime) runtime(__webpack_require__);
303
+ /******/ for(var i = 0; i < chunkIds.length; i++)
304
+ /******/ installedChunks[chunkIds[i]] = 1;
305
+ /******/ __webpack_require__.O();
306
+ /******/ };
307
+ /******/
308
+ /******/ // require() chunk loading for javascript
309
+ /******/ __webpack_require__.f.require = (chunkId, promises) => {
310
+ /******/ // "1" is the signal for "already loaded"
311
+ /******/ if(!installedChunks[chunkId]) {
312
+ /******/ if(true) { // all chunks have JS
313
+ /******/ var installedChunk = require("./" + __webpack_require__.u(chunkId));
314
+ /******/ if (!installedChunks[chunkId]) {
315
+ /******/ installChunk(installedChunk);
316
+ /******/ }
317
+ /******/ } else installedChunks[chunkId] = 1;
318
+ /******/ }
319
+ /******/ };
320
+ /******/
321
+ /******/ // no external install chunk
322
+ /******/
323
+ /******/ // no HMR
324
+ /******/
325
+ /******/ // no HMR manifest
326
+ /******/ })();
327
+ /******/
328
+ /******/ /* webpack/runtime/startup chunk dependencies */
329
+ /******/ (() => {
330
+ /******/ var next = __webpack_require__.x;
331
+ /******/ __webpack_require__.x = () => {
332
+ /******/ __webpack_require__.e(449);
333
+ /******/ return next();
334
+ /******/ };
335
+ /******/ })();
336
+ /******/
337
+ /************************************************************************/
338
+ /******/
339
+ /******/ // run startup
340
+ /******/ var __webpack_exports__ = __webpack_require__.x();
341
+ /******/ module.exports = __webpack_exports__;
342
+ /******/
343
+ /******/ })()
344
+ ;