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.
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/dist/xhs-mcp.cjs +344 -0
- package/package.json +4 -4
- package/dist/xhs-mcp.js +0 -337
- /package/dist/{449.js → 449.cjs} +0 -0
package/dist/xhs-mcp.js
DELETED
|
@@ -1,337 +0,0 @@
|
|
|
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
|
-
/***/ 181:
|
|
15
|
-
/***/ ((module) => {
|
|
16
|
-
|
|
17
|
-
module.exports = require("buffer");
|
|
18
|
-
|
|
19
|
-
/***/ }),
|
|
20
|
-
|
|
21
|
-
/***/ 290:
|
|
22
|
-
/***/ ((module) => {
|
|
23
|
-
|
|
24
|
-
module.exports = require("async_hooks");
|
|
25
|
-
|
|
26
|
-
/***/ }),
|
|
27
|
-
|
|
28
|
-
/***/ 805:
|
|
29
|
-
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
30
|
-
|
|
31
|
-
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}");
|
|
32
|
-
|
|
33
|
-
/***/ }),
|
|
34
|
-
|
|
35
|
-
/***/ 1708:
|
|
36
|
-
/***/ ((module) => {
|
|
37
|
-
|
|
38
|
-
module.exports = require("node:process");
|
|
39
|
-
|
|
40
|
-
/***/ }),
|
|
41
|
-
|
|
42
|
-
/***/ 2094:
|
|
43
|
-
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
44
|
-
|
|
45
|
-
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 stack: error.stack,\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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O1FBQ0wsT0FBTyxFQUFFO1lBQ1A7Z0JBQ0UsSUFBSSxFQUFFLE1BQU07Z0JBQ1osSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7YUFDcEM7U0FDRjtLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNJLFNBQVMsc0JBQXNCLENBQUMsS0FBYztJQUduRCxNQUFNLFNBQVMsR0FDYixLQUFLLFlBQVksS0FBSztRQUNwQixDQUFDLENBQUM7WUFDRSxPQUFPLEVBQUUsS0FBSztZQUNkLEtBQUssRUFBRSxjQUFjO1lBQ3JCLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztZQUN0QixLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUs7U0FDbkI7UUFDSCxDQUFDLENBQUM7WUFDRSxPQUFPLEVBQUUsS0FBSztZQUNkLEtBQUssRUFBRSxjQUFjO1lBQ3JCLE9BQU8sRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDO1NBQ3ZCLENBQUM7SUFFUixPQUFPO1FBQ0wsT0FBTyxFQUFFO1lBQ1A7Z0JBQ0UsSUFBSSxFQUFFLE1BQU07Z0JBQ1osSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7YUFDekM7U0FDRjtLQUNGLENBQUM7QUFDSixDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQvdXRpbHMudHM/OWM1YyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbW1vbiB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG4vKipcbiAqIFNsZWVwIHV0aWxpdHkgZnVuY3Rpb25cbiAqIEBwYXJhbSBtcyAtIE1pbGxpc2Vjb25kcyB0byBzbGVlcFxuICogQHJldHVybnMgUHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIHRoZSBzcGVjaWZpZWQgdGltZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbn1cblxuLyoqXG4gKiBTYWZlIGVycm9yIGhhbmRsZXIgdGhhdCBsb2dzIGVycm9ycyB3aXRob3V0IHRocm93aW5nXG4gKiBAcGFyYW0gZXJyb3IgLSBFcnJvciB0byBoYW5kbGVcbiAqIEBwYXJhbSBjb250ZXh0IC0gQWRkaXRpb25hbCBjb250ZXh0IGZvciB0aGUgZXJyb3JcbiAqIEBwYXJhbSBsb2dnZXIgLSBMb2dnZXIgaW5zdGFuY2UgdG8gdXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzYWZlRXJyb3JIYW5kbGVyKFxuICBlcnJvcjogdW5rbm93bixcbiAgY29udGV4dDogc3RyaW5nLFxuICBsb2dnZXI6IHsgZXJyb3I6IChtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdm9pZCB9XG4pOiB2b2lkIHtcbiAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICBsb2dnZXIuZXJyb3IoYCR7Y29udGV4dH06ICR7ZXJyb3JNZXNzYWdlfWApO1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIHJlcXVpcmVkIHBhcmFtZXRlcnNcbiAqIEBwYXJhbSBwYXJhbXMgLSBPYmplY3QgY29udGFpbmluZyBwYXJhbWV0ZXJzIHRvIHZhbGlkYXRlXG4gKiBAcGFyYW0gcmVxdWlyZWRLZXlzIC0gQXJyYXkgb2YgcmVxdWlyZWQgcGFyYW1ldGVyIGtleXNcbiAqIEB0aHJvd3MgRXJyb3IgaWYgYW55IHJlcXVpcmVkIHBhcmFtZXRlciBpcyBtaXNzaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVJlcXVpcmVkUGFyYW1zKFxuICBwYXJhbXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICByZXF1aXJlZEtleXM6IHN0cmluZ1tdXG4pOiB2b2lkIHtcbiAgY29uc3QgbWlzc2luZ0tleXMgPSByZXF1aXJlZEtleXMuZmlsdGVyKFxuICAgIChrZXkpID0+IHBhcmFtc1trZXldID09PSB1bmRlZmluZWQgfHwgcGFyYW1zW2tleV0gPT09IG51bGwgfHwgcGFyYW1zW2tleV0gPT09ICcnXG4gICk7XG5cbiAgaWYgKG1pc3NpbmdLZXlzLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyczogJHttaXNzaW5nS2V5cy5qb2luKCcsICcpfWApO1xuICB9XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnO1xufVxuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBhIG51bWJlclxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOdW1iZXIodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBudW1iZXIge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiAhTnVtYmVyLmlzTmFOKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgYW4gYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXJyYXk8VD4odmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBUW10ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG5cbi8qKlxuICogU2FmZWx5IHBhcnNlIEpTT04gc3RyaW5nXG4gKiBAcGFyYW0ganNvblN0cmluZyAtIEpTT04gc3RyaW5nIHRvIHBhcnNlXG4gKiBAcGFyYW0gZmFsbGJhY2sgLSBGYWxsYmFjayB2YWx1ZSBpZiBwYXJzaW5nIGZhaWxzXG4gKiBAcmV0dXJucyBQYXJzZWQgb2JqZWN0IG9yIGZhbGxiYWNrIHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzYWZlSnNvblBhcnNlPFQ+KGpzb25TdHJpbmc6IHN0cmluZywgZmFsbGJhY2s6IFQpOiBUIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShqc29uU3RyaW5nKSBhcyBUO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsbGJhY2s7XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBwdWJsaXNoIG5vdGUgcGFyYW1ldGVycyB3aXRoIGxlbmd0aCBjb25zdHJhaW50c1xuICogQHBhcmFtIHRpdGxlIC0gTm90ZSB0aXRsZVxuICogQHBhcmFtIG5vdGUgLSBOb3RlIGNvbnRlbnRcbiAqIEBwYXJhbSBpbWFnZVBhdGhzIC0gQXJyYXkgb2YgaW1hZ2UgcGF0aHNcbiAqIEB0aHJvd3MgRXJyb3IgaWYgYW55IHBhcmFtZXRlciB2aW9sYXRlcyBjb25zdHJhaW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVQdWJsaXNoTm90ZVBhcmFtcyh0aXRsZTogc3RyaW5nLCBub3RlOiBzdHJpbmcsIGltYWdlUGF0aHM6IHN0cmluZ1tdKTogdm9pZCB7XG4gIC8vIFZhbGlkYXRlIHRpdGxlIGxlbmd0aCAobWF4IDIwIGNoYXJhY3RlcnMpXG4gIGlmICh0aXRsZSAmJiB0aXRsZS5sZW5ndGggPiAyMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGl0bGUgbGVuZ3RoIGNhbm5vdCBleGNlZWQgMjAgY2hhcmFjdGVycy4gQ3VycmVudCBsZW5ndGg6ICR7dGl0bGUubGVuZ3RofWApO1xuICB9XG5cbiAgLy8gVmFsaWRhdGUgbm90ZSBjb250ZW50IGxlbmd0aCAobWF4IDEwMDAgY2hhcmFjdGVycylcbiAgaWYgKG5vdGUgJiYgbm90ZS5sZW5ndGggPiAxMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYE5vdGUgY29udGVudCBsZW5ndGggY2Fubm90IGV4Y2VlZCAxMDAwIGNoYXJhY3RlcnMuIEN1cnJlbnQgbGVuZ3RoOiAke25vdGUubGVuZ3RofWBcbiAgICApO1xuICB9XG5cbiAgLy8gVmFsaWRhdGUgaW1hZ2UgY291bnQgKG1heCAxOCBpbWFnZXMpXG4gIGlmIChpbWFnZVBhdGhzICYmIGltYWdlUGF0aHMubGVuZ3RoID4gMTgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYE1heGltdW0gMTggaW1hZ2VzIGFsbG93ZWQuIEN1cnJlbnQgY291bnQ6ICR7aW1hZ2VQYXRocy5sZW5ndGh9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBzdGFuZGFyZGl6ZWQgcmVzcG9uc2Ugb2JqZWN0XG4gKiBAcGFyYW0gc3VjY2VzcyAtIFdoZXRoZXIgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bFxuICogQHBhcmFtIGRhdGEgLSBPcHRpb25hbCBkYXRhIHRvIGluY2x1ZGVcbiAqIEBwYXJhbSBtZXNzYWdlIC0gT3B0aW9uYWwgbWVzc2FnZVxuICogQHBhcmFtIGVycm9yIC0gT3B0aW9uYWwgZXJyb3IgaW5mb3JtYXRpb25cbiAqIEByZXR1cm5zIFN0YW5kYXJkaXplZCByZXNwb25zZSBvYmplY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFwaVJlc3BvbnNlPFQgPSB1bmtub3duPihcbiAgc3VjY2VzczogYm9vbGVhbixcbiAgZGF0YT86IFQsXG4gIG1lc3NhZ2U/OiBzdHJpbmcsXG4gIGVycm9yPzogc3RyaW5nXG4pOiB7IHN1Y2Nlc3M6IGJvb2xlYW47IGRhdGE/OiBUOyBtZXNzYWdlPzogc3RyaW5nOyBlcnJvcj86IHN0cmluZyB9IHtcbiAgY29uc3QgcmVzcG9uc2U6IHsgc3VjY2VzczogYm9vbGVhbjsgZGF0YT86IFQ7IG1lc3NhZ2U/OiBzdHJpbmc7IGVycm9yPzogc3RyaW5nIH0gPSB7IHN1Y2Nlc3MgfTtcblxuICBpZiAoZGF0YSAhPT0gdW5kZWZpbmVkKSByZXNwb25zZS5kYXRhID0gZGF0YTtcbiAgaWYgKG1lc3NhZ2UgIT09IHVuZGVmaW5lZCkgcmVzcG9uc2UubWVzc2FnZSA9IG1lc3NhZ2U7XG4gIGlmIChlcnJvciAhPT0gdW5kZWZpbmVkKSByZXNwb25zZS5lcnJvciA9IGVycm9yO1xuXG4gIHJldHVybiByZXNwb25zZTtcbn1cblxuLyoqXG4gKiBSZXRyeSBhIGZ1bmN0aW9uIHdpdGggZXhwb25lbnRpYWwgYmFja29mZlxuICogQHBhcmFtIGZuIC0gRnVuY3Rpb24gdG8gcmV0cnlcbiAqIEBwYXJhbSBtYXhSZXRyaWVzIC0gTWF4aW11bSBudW1iZXIgb2YgcmV0cmllc1xuICogQHBhcmFtIGJhc2VEZWxheSAtIEJhc2UgZGVsYXkgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcmV0dXJucyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgZnVuY3Rpb24gcmVzdWx0XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXRyeVdpdGhCYWNrb2ZmPFQ+KFxuICBmbjogKCkgPT4gUHJvbWlzZTxUPixcbiAgbWF4UmV0cmllczogbnVtYmVyID0gMyxcbiAgYmFzZURlbGF5OiBudW1iZXIgPSAxMDAwXG4pOiBQcm9taXNlPFQ+IHtcbiAgbGV0IGxhc3RFcnJvcjogRXJyb3I7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPD0gbWF4UmV0cmllczsgYXR0ZW1wdCsrKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBmbigpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsYXN0RXJyb3IgPSBlcnJvciBhcyBFcnJvcjtcblxuICAgICAgaWYgKGF0dGVtcHQgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgdGhyb3cgbGFzdEVycm9yO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkZWxheSA9IGJhc2VEZWxheSAqIE1hdGgucG93KDIsIGF0dGVtcHQpO1xuICAgICAgYXdhaXQgc2xlZXAoZGVsYXkpO1xuICAgIH1cbiAgfVxuXG4gIHRocm93IGxhc3RFcnJvciE7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgc3RhbmRhcmRpemVkIE1DUCB0b29sIHJlc3BvbnNlXG4gKiBAcGFyYW0gZGF0YSAtIERhdGEgdG8gaW5jbHVkZSBpbiB0aGUgcmVzcG9uc2VcbiAqIEByZXR1cm5zIFN0YW5kYXJkaXplZCBNQ1AgcmVzcG9uc2UgZm9ybWF0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNY3BUb29sUmVzcG9uc2U8VCA9IHVua25vd24+KFxuICBkYXRhOiBUXG4pOiB7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfSB7XG4gIHJldHVybiB7XG4gICAgY29udGVudDogW1xuICAgICAge1xuICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIHN0YW5kYXJkaXplZCBNQ1AgZXJyb3IgcmVzcG9uc2VcbiAqIEBwYXJhbSBlcnJvciAtIEVycm9yIHRvIGZvcm1hdFxuICogQHJldHVybnMgU3RhbmRhcmRpemVkIE1DUCBlcnJvciByZXNwb25zZSBmb3JtYXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1jcEVycm9yUmVzcG9uc2UoZXJyb3I6IHVua25vd24pOiB7XG4gIGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT47XG59IHtcbiAgY29uc3QgZXJyb3JEYXRhID1cbiAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yXG4gICAgICA/IHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvcjogJ1Vua25vd25FcnJvcicsXG4gICAgICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZSxcbiAgICAgICAgICBzdGFjazogZXJyb3Iuc3RhY2ssXG4gICAgICAgIH1cbiAgICAgIDoge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIGVycm9yOiAnVW5rbm93bkVycm9yJyxcbiAgICAgICAgICBtZXNzYWdlOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICB9O1xuXG4gIHJldHVybiB7XG4gICAgY29udGVudDogW1xuICAgICAge1xuICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KGVycm9yRGF0YSwgbnVsbCwgMiksXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2094\n\n}");
|
|
46
|
-
|
|
47
|
-
/***/ }),
|
|
48
|
-
|
|
49
|
-
/***/ 2203:
|
|
50
|
-
/***/ ((module) => {
|
|
51
|
-
|
|
52
|
-
module.exports = require("stream");
|
|
53
|
-
|
|
54
|
-
/***/ }),
|
|
55
|
-
|
|
56
|
-
/***/ 2207:
|
|
57
|
-
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
58
|
-
|
|
59
|
-
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}");
|
|
60
|
-
|
|
61
|
-
/***/ }),
|
|
62
|
-
|
|
63
|
-
/***/ 3100:
|
|
64
|
-
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
65
|
-
|
|
66
|
-
eval("{\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n d: () => (/* binding */ BaseService)\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 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 this.options = {\n minInstances: options?.minInstances ?? 2,\n maxInstances: options?.maxInstances ?? 5,\n idleTimeout: options?.idleTimeout ?? 300000, // 5 minutes\n maxAge: options?.maxAge ?? 1800000, // 30 minutes\n healthCheckInterval: options?.healthCheckInterval ?? 60000, // 1 minute\n maxUsageCount: options?.maxUsageCount ?? 100,\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 // 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 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 if (!browser.isAvailable) {\n continue; // Skip browsers currently in use\n }\n const idleTime = now - browser.lastUsed.getTime();\n const shouldRetire = this.shouldRetireBrowser(browser);\n if (idleTime > this.options.idleTimeout || shouldRetire) {\n // Only remove if we have more than minimum instances\n const healthyCount = Array.from(this.pool.values()).filter((b) => b.isHealthy).length;\n if (healthyCount > this.options.minInstances) {\n browsersToRemove.push(id);\n }\n }\n }\n // Remove idle/old browsers\n for (const id of browsersToRemove) {\n const reason = this.shouldRetireBrowser(this.pool.get(id)) || 'idle timeout';\n logger/* logger */.v.info(`Removing browser ${id} due to ${reason}`);\n await this.removeBrowserFromPool(id);\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 constructor(config, usePool = false) {\n this.config = config || (0,shared_config/* getConfig */.zj)();\n this.usePool = usePool;\n if (this.usePool) {\n this.browserPool = new BrowserPoolService(this.config);\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 // 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 page.once('close', async () => {\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 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 = false; // temporarily disable headless mode for debugging\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 // 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 * 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 * Enable browser pooling\n */\n enableBrowserPool() {\n if (!this.usePool) {\n this.usePool = true;\n this.browserPool = new BrowserPoolService(this.config);\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\n;// ./src/shared/base.service.ts\n/**\n * Base service class for XHS MCP Server services\n */\n\n/**\n * Base service class that provides common functionality for all services\n */\nclass BaseService {\n config;\n browserManager;\n constructor(config) {\n this.config = config;\n this.browserManager = new BrowserManager(config);\n }\n /**\n * Get the browser manager instance\n */\n getBrowserManager() {\n return this.browserManager;\n }\n /**\n * Get the configuration\n */\n getConfig() {\n return this.config;\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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SUFBSSxvQkFBb0IsR0FBMEIsSUFBSSxDQUFDO0FBRWhELFNBQVMsaUJBQWlCLENBQUMsVUFBbUIsS0FBSztJQUN4RCxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUMxQixvQkFBb0IsR0FBRyxJQUFJLGNBQWMsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUNELE9BQU8sb0JBQW9CLENBQUM7QUFDOUIsQ0FBQztBQUVNLFNBQVMsdUJBQXVCO0lBQ3JDLE9BQU8saUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDakMsQ0FBQztBQUVNLEtBQUssVUFBVSwyQkFBMkI7SUFDL0MsSUFBSSxvQkFBb0IsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sb0JBQW9CLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDckMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO0lBQzlCLENBQUM7QUFDSCxDQUFDOzs7QUNsWEQ7O0dBRUc7QUFHOEQ7QUFFakU7O0dBRUc7QUFDSSxNQUFlLFdBQVc7SUFDWixNQUFNLENBQVM7SUFDZixjQUFjLENBQWlCO0lBRWxELFlBQVksTUFBYztRQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRDs7T0FFRztJQUNPLGlCQUFpQjtRQUN6QixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQUVEOztPQUVHO0lBQ08sU0FBUztRQUNqQixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztDQUNGIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL2Jyb3dzZXIvYnJvd3Nlci1wb29sLnNlcnZpY2UudHM/NGM1NCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvYnJvd3Nlci9icm93c2VyLm1hbmFnZXIudHM/NGMwZiIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NoYXJlZC9iYXNlLnNlcnZpY2UudHM/YTM0ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEJyb3dzZXIgUG9vbCBTZXJ2aWNlIGZvciBYSFMgT3BlcmF0aW9uc1xuICogTWFuYWdlcyBicm93c2VyIGluc3RhbmNlIGxpZmVjeWNsZSB3aXRoIHBvb2xpbmcsIGhlYWx0aCBtb25pdG9yaW5nLCBhbmQgYXV0b21hdGljIGNsZWFudXBcbiAqL1xuXG5pbXBvcnQgcHVwcGV0ZWVyLCB7IEJyb3dzZXIsIEJyb3dzZXJDb250ZXh0LCBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBCcm93c2VyTGF1bmNoRXJyb3IsIFhIU0Vycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE1hbmFnZWRCcm93c2VyIHtcbiAgYnJvd3NlcjogQnJvd3NlcjtcbiAgY29udGV4dDogQnJvd3NlckNvbnRleHQ7XG4gIGlkOiBzdHJpbmc7XG4gIGNyZWF0ZWRBdDogRGF0ZTtcbiAgbGFzdFVzZWQ6IERhdGU7XG4gIGlzQXZhaWxhYmxlOiBib29sZWFuO1xuICBpc0hlYWx0aHk6IGJvb2xlYW47XG4gIHVzYWdlQ291bnQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCcm93c2VyUG9vbFN0YXRzIHtcbiAgdG90YWxJbnN0YW5jZXM6IG51bWJlcjtcbiAgYXZhaWxhYmxlSW5zdGFuY2VzOiBudW1iZXI7XG4gIGJ1c3lJbnN0YW5jZXM6IG51bWJlcjtcbiAgdW5oZWFsdGh5SW5zdGFuY2VzOiBudW1iZXI7XG4gIHRvdGFsVXNhZ2U6IG51bWJlcjtcbiAgYXZlcmFnZUFnZTogbnVtYmVyO1xuICBvbGRlc3RJbnN0YW5jZTogRGF0ZSB8IG51bGw7XG4gIG5ld2VzdEluc3RhbmNlOiBEYXRlIHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCcm93c2VyUG9vbE9wdGlvbnMge1xuICBtaW5JbnN0YW5jZXM/OiBudW1iZXI7XG4gIG1heEluc3RhbmNlcz86IG51bWJlcjtcbiAgaWRsZVRpbWVvdXQ/OiBudW1iZXI7XG4gIG1heEFnZT86IG51bWJlcjtcbiAgaGVhbHRoQ2hlY2tJbnRlcnZhbD86IG51bWJlcjtcbiAgbWF4VXNhZ2VDb3VudD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGNsYXNzIEJyb3dzZXJQb29sU2VydmljZSB7XG4gIHByaXZhdGUgY29uZmlnOiBDb25maWc7XG4gIHByaXZhdGUgcG9vbDogTWFwPHN0cmluZywgTWFuYWdlZEJyb3dzZXI+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIG9wdGlvbnM6IFJlcXVpcmVkPEJyb3dzZXJQb29sT3B0aW9ucz47XG4gIHByaXZhdGUgaGVhbHRoQ2hlY2tUaW1lcjogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjbGVhbnVwVGltZXI6IE5vZGVKUy5UaW1lb3V0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaXNTaHV0dGluZ0Rvd24gPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc/OiBDb25maWcsIG9wdGlvbnM/OiBCcm93c2VyUG9vbE9wdGlvbnMpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyB8fCBnZXRDb25maWcoKTtcblxuICAgIC8vIFNldCBkZWZhdWx0IG9wdGlvbnMgd2l0aCBjb25maWd1cmF0aW9uIGZyb20gZW52aXJvbm1lbnQgb3IgZGVmYXVsdHNcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBtaW5JbnN0YW5jZXM6IG9wdGlvbnM/Lm1pbkluc3RhbmNlcyA/PyAyLFxuICAgICAgbWF4SW5zdGFuY2VzOiBvcHRpb25zPy5tYXhJbnN0YW5jZXMgPz8gNSxcbiAgICAgIGlkbGVUaW1lb3V0OiBvcHRpb25zPy5pZGxlVGltZW91dCA/PyAzMDAwMDAsIC8vIDUgbWludXRlc1xuICAgICAgbWF4QWdlOiBvcHRpb25zPy5tYXhBZ2UgPz8gMTgwMDAwMCwgLy8gMzAgbWludXRlc1xuICAgICAgaGVhbHRoQ2hlY2tJbnRlcnZhbDogb3B0aW9ucz8uaGVhbHRoQ2hlY2tJbnRlcnZhbCA/PyA2MDAwMCwgLy8gMSBtaW51dGVcbiAgICAgIG1heFVzYWdlQ291bnQ6IG9wdGlvbnM/Lm1heFVzYWdlQ291bnQgPz8gMTAwLFxuICAgIH07XG5cbiAgICB0aGlzLnN0YXJ0SGVhbHRoTW9uaXRvcmluZygpO1xuICAgIHRoaXMuc3RhcnRDbGVhbnVwTW9uaXRvcmluZygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjcXVpcmUgYSBicm93c2VyIGluc3RhbmNlIGZyb20gdGhlIHBvb2xcbiAgICovXG4gIGFzeW5jIGFjcXVpcmVCcm93c2VyKG9wdGlvbnM/OiB7IHRpbWVvdXQ/OiBudW1iZXIgfSk6IFByb21pc2U8TWFuYWdlZEJyb3dzZXI+IHtcbiAgICBpZiAodGhpcy5pc1NodXR0aW5nRG93bikge1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKCdCcm93c2VyIHBvb2wgaXMgc2h1dHRpbmcgZG93bicsICdCcm93c2VyUG9vbEVycm9yJyk7XG4gICAgfVxuXG4gICAgY29uc3QgdGltZW91dCA9IG9wdGlvbnM/LnRpbWVvdXQgPz8gMzAwMDA7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIC0gc3RhcnRUaW1lIDwgdGltZW91dCkge1xuICAgICAgLy8gVHJ5IHRvIGZpbmQgYW4gYXZhaWxhYmxlIGhlYWx0aHkgYnJvd3NlclxuICAgICAgY29uc3QgYXZhaWxhYmxlQnJvd3NlciA9IHRoaXMuZmluZEF2YWlsYWJsZUJyb3dzZXIoKTtcbiAgICAgIGlmIChhdmFpbGFibGVCcm93c2VyKSB7XG4gICAgICAgIGF2YWlsYWJsZUJyb3dzZXIuaXNBdmFpbGFibGUgPSBmYWxzZTtcbiAgICAgICAgYXZhaWxhYmxlQnJvd3Nlci5sYXN0VXNlZCA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGF2YWlsYWJsZUJyb3dzZXIudXNhZ2VDb3VudCsrO1xuXG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgQWNxdWlyZWQgYnJvd3NlciAke2F2YWlsYWJsZUJyb3dzZXIuaWR9IGZyb20gcG9vbGApO1xuICAgICAgICByZXR1cm4gYXZhaWxhYmxlQnJvd3NlcjtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgbm8gYXZhaWxhYmxlIGJyb3dzZXIgYW5kIHdlIGNhbiBjcmVhdGUgbW9yZSwgY3JlYXRlIG9uZVxuICAgICAgaWYgKHRoaXMucG9vbC5zaXplIDwgdGhpcy5vcHRpb25zLm1heEluc3RhbmNlcykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IG5ld0Jyb3dzZXIgPSBhd2FpdCB0aGlzLmNyZWF0ZUJyb3dzZXJJbnN0YW5jZSgpO1xuICAgICAgICAgIG5ld0Jyb3dzZXIuaXNBdmFpbGFibGUgPSBmYWxzZTtcbiAgICAgICAgICBuZXdCcm93c2VyLmxhc3RVc2VkID0gbmV3IERhdGUoKTtcbiAgICAgICAgICBuZXdCcm93c2VyLnVzYWdlQ291bnQrKztcblxuICAgICAgICAgIGxvZ2dlci5pbmZvKGBDcmVhdGVkIG5ldyBicm93c2VyICR7bmV3QnJvd3Nlci5pZH0gZm9yIHBvb2xgKTtcbiAgICAgICAgICByZXR1cm4gbmV3QnJvd3NlcjtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgbmV3IGJyb3dzZXIgaW5zdGFuY2U6ICR7ZXJyb3J9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gV2FpdCBhIGJpdCBiZWZvcmUgcmV0cnlpbmdcbiAgICAgIGF3YWl0IHNsZWVwKDEwMCk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFhIU0Vycm9yKFxuICAgICAgYEZhaWxlZCB0byBhY3F1aXJlIGJyb3dzZXIgd2l0aGluICR7dGltZW91dH1tcyB0aW1lb3V0YCxcbiAgICAgICdCcm93c2VyUG9vbFRpbWVvdXQnLFxuICAgICAgeyB0aW1lb3V0LCBwb29sU2l6ZTogdGhpcy5wb29sLnNpemUsIGF2YWlsYWJsZUNvdW50OiB0aGlzLmdldEF2YWlsYWJsZUNvdW50KCkgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVsZWFzZSBhIGJyb3dzZXIgaW5zdGFuY2UgYmFjayB0byB0aGUgcG9vbFxuICAgKi9cbiAgYXN5bmMgcmVsZWFzZUJyb3dzZXIoYnJvd3NlcjogTWFuYWdlZEJyb3dzZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtYW5hZ2VkQnJvd3NlciA9IHRoaXMucG9vbC5nZXQoYnJvd3Nlci5pZCk7XG4gICAgaWYgKCFtYW5hZ2VkQnJvd3Nlcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEF0dGVtcHRlZCB0byByZWxlYXNlIHVua25vd24gYnJvd3NlciAke2Jyb3dzZXIuaWR9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgYnJvd3NlciBzaG91bGQgYmUgcmV0aXJlZCBkdWUgdG8gYWdlIG9yIHVzYWdlXG4gICAgY29uc3Qgc2hvdWxkUmV0aXJlID0gdGhpcy5zaG91bGRSZXRpcmVCcm93c2VyKG1hbmFnZWRCcm93c2VyKTtcbiAgICBpZiAoc2hvdWxkUmV0aXJlKSB7XG4gICAgICBsb2dnZXIuaW5mbyhgUmV0aXJpbmcgYnJvd3NlciAke2Jyb3dzZXIuaWR9IGR1ZSB0byAke3Nob3VsZFJldGlyZX1gKTtcbiAgICAgIGF3YWl0IHRoaXMucmVtb3ZlQnJvd3NlckZyb21Qb29sKGJyb3dzZXIuaWQpO1xuXG4gICAgICAvLyBFbnN1cmUgd2UgbWFpbnRhaW4gbWluaW11bSBpbnN0YW5jZXNcbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlTWluaW11bUluc3RhbmNlcygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFBlcmZvcm0gaGVhbHRoIGNoZWNrIGJlZm9yZSByZXR1cm5pbmcgdG8gcG9vbFxuICAgIGNvbnN0IGlzSGVhbHRoeSA9IGF3YWl0IHRoaXMuY2hlY2tCcm93c2VySGVhbHRoKG1hbmFnZWRCcm93c2VyKTtcbiAgICBpZiAoIWlzSGVhbHRoeSkge1xuICAgICAgbG9nZ2VyLndhcm4oYEJyb3dzZXIgJHticm93c2VyLmlkfSBmYWlsZWQgaGVhbHRoIGNoZWNrLCByZW1vdmluZyBmcm9tIHBvb2xgKTtcbiAgICAgIGF3YWl0IHRoaXMucmVtb3ZlQnJvd3NlckZyb21Qb29sKGJyb3dzZXIuaWQpO1xuICAgICAgYXdhaXQgdGhpcy5lbnN1cmVNaW5pbXVtSW5zdGFuY2VzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIHRvIHBvb2xcbiAgICBtYW5hZ2VkQnJvd3Nlci5pc0F2YWlsYWJsZSA9IHRydWU7XG4gICAgbWFuYWdlZEJyb3dzZXIuaXNIZWFsdGh5ID0gdHJ1ZTtcblxuICAgIGxvZ2dlci5kZWJ1ZyhgUmVsZWFzZWQgYnJvd3NlciAke2Jyb3dzZXIuaWR9IGJhY2sgdG8gcG9vbGApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHBvb2wgc3RhdGlzdGljc1xuICAgKi9cbiAgZ2V0UG9vbFN0YXRzKCk6IEJyb3dzZXJQb29sU3RhdHMge1xuICAgIGNvbnN0IGluc3RhbmNlcyA9IEFycmF5LmZyb20odGhpcy5wb29sLnZhbHVlcygpKTtcbiAgICBjb25zdCBhdmFpbGFibGVJbnN0YW5jZXMgPSBpbnN0YW5jZXMuZmlsdGVyKChiKSA9PiBiLmlzQXZhaWxhYmxlICYmIGIuaXNIZWFsdGh5KS5sZW5ndGg7XG4gICAgY29uc3QgYnVzeUluc3RhbmNlcyA9IGluc3RhbmNlcy5maWx0ZXIoKGIpID0+ICFiLmlzQXZhaWxhYmxlKS5sZW5ndGg7XG4gICAgY29uc3QgdW5oZWFsdGh5SW5zdGFuY2VzID0gaW5zdGFuY2VzLmZpbHRlcigoYikgPT4gIWIuaXNIZWFsdGh5KS5sZW5ndGg7XG4gICAgY29uc3QgdG90YWxVc2FnZSA9IGluc3RhbmNlcy5yZWR1Y2UoKHN1bSwgYikgPT4gc3VtICsgYi51c2FnZUNvdW50LCAwKTtcblxuICAgIGNvbnN0IGFnZXMgPSBpbnN0YW5jZXMubWFwKChiKSA9PiBEYXRlLm5vdygpIC0gYi5jcmVhdGVkQXQuZ2V0VGltZSgpKTtcbiAgICBjb25zdCBhdmVyYWdlQWdlID0gYWdlcy5sZW5ndGggPiAwID8gYWdlcy5yZWR1Y2UoKHN1bSwgYWdlKSA9PiBzdW0gKyBhZ2UsIDApIC8gYWdlcy5sZW5ndGggOiAwO1xuXG4gICAgY29uc3Qgb2xkZXN0SW5zdGFuY2UgPVxuICAgICAgaW5zdGFuY2VzLmxlbmd0aCA+IDBcbiAgICAgICAgPyBpbnN0YW5jZXMucmVkdWNlKChvbGRlc3QsIGN1cnJlbnQpID0+XG4gICAgICAgICAgICBjdXJyZW50LmNyZWF0ZWRBdCA8IG9sZGVzdC5jcmVhdGVkQXQgPyBjdXJyZW50IDogb2xkZXN0XG4gICAgICAgICAgKS5jcmVhdGVkQXRcbiAgICAgICAgOiBudWxsO1xuXG4gICAgY29uc3QgbmV3ZXN0SW5zdGFuY2UgPVxuICAgICAgaW5zdGFuY2VzLmxlbmd0aCA+IDBcbiAgICAgICAgPyBpbnN0YW5jZXMucmVkdWNlKChuZXdlc3QsIGN1cnJlbnQpID0+XG4gICAgICAgICAgICBjdXJyZW50LmNyZWF0ZWRBdCA+IG5ld2VzdC5jcmVhdGVkQXQgPyBjdXJyZW50IDogbmV3ZXN0XG4gICAgICAgICAgKS5jcmVhdGVkQXRcbiAgICAgICAgOiBudWxsO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvdGFsSW5zdGFuY2VzOiBpbnN0YW5jZXMubGVuZ3RoLFxuICAgICAgYXZhaWxhYmxlSW5zdGFuY2VzLFxuICAgICAgYnVzeUluc3RhbmNlcyxcbiAgICAgIHVuaGVhbHRoeUluc3RhbmNlcyxcbiAgICAgIHRvdGFsVXNhZ2UsXG4gICAgICBhdmVyYWdlQWdlLFxuICAgICAgb2xkZXN0SW5zdGFuY2UsXG4gICAgICBuZXdlc3RJbnN0YW5jZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFudXAgYW5kIHNodXRkb3duIHRoZSBicm93c2VyIHBvb2xcbiAgICovXG4gIGFzeW5jIGNsZWFudXAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5pc1NodXR0aW5nRG93biA9IHRydWU7XG5cbiAgICAvLyBTdG9wIG1vbml0b3JpbmcgdGltZXJzXG4gICAgaWYgKHRoaXMuaGVhbHRoQ2hlY2tUaW1lcikge1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmhlYWx0aENoZWNrVGltZXIpO1xuICAgICAgdGhpcy5oZWFsdGhDaGVja1RpbWVyID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jbGVhbnVwVGltZXIpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jbGVhbnVwVGltZXIpO1xuICAgICAgdGhpcy5jbGVhbnVwVGltZXIgPSBudWxsO1xuICAgIH1cblxuICAgIC8vIENsb3NlIGFsbCBicm93c2Vyc1xuICAgIGNvbnN0IGNsb3NlUHJvbWlzZXMgPSBBcnJheS5mcm9tKHRoaXMucG9vbC52YWx1ZXMoKSkubWFwKGFzeW5jIChtYW5hZ2VkQnJvd3NlcikgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgbWFuYWdlZEJyb3dzZXIuYnJvd3Nlci5jbG9zZSgpO1xuICAgICAgICBsb2dnZXIuZGVidWcoYENsb3NlZCBicm93c2VyICR7bWFuYWdlZEJyb3dzZXIuaWR9YCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihgRXJyb3IgY2xvc2luZyBicm93c2VyICR7bWFuYWdlZEJyb3dzZXIuaWR9OiAke2Vycm9yfWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKGNsb3NlUHJvbWlzZXMpO1xuICAgIHRoaXMucG9vbC5jbGVhcigpO1xuXG4gICAgbG9nZ2VyLmluZm8oJ0Jyb3dzZXIgcG9vbCBjbGVhbnVwIGNvbXBsZXRlZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBicm93c2VyIGluc3RhbmNlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNyZWF0ZUJyb3dzZXJJbnN0YW5jZSgpOiBQcm9taXNlPE1hbmFnZWRCcm93c2VyPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGxhdW5jaE9wdGlvbnM6IGFueSA9IHtcbiAgICAgICAgaGVhZGxlc3M6IHRoaXMuY29uZmlnLmJyb3dzZXIuaGVhZGxlc3NEZWZhdWx0LFxuICAgICAgICBzbG93TW86IHRoaXMuY29uZmlnLmJyb3dzZXIuc2xvd21vLFxuICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgJy0tbm8tc2FuZGJveCcsXG4gICAgICAgICAgJy0tZGlzYWJsZS1zZXR1aWQtc2FuZGJveCcsXG4gICAgICAgICAgJy0tZGlzYWJsZS1kZXYtc2htLXVzYWdlJyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWFjY2VsZXJhdGVkLTJkLWNhbnZhcycsXG4gICAgICAgICAgJy0tbm8tZmlyc3QtcnVuJyxcbiAgICAgICAgICAnLS1uby16eWdvdGUnLFxuICAgICAgICAgICctLWRpc2FibGUtZ3B1JyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWJhY2tncm91bmQtdGltZXItdGhyb3R0bGluZycsXG4gICAgICAgICAgJy0tZGlzYWJsZS1iYWNrZ3JvdW5kaW5nLW9jY2x1ZGVkLXdpbmRvd3MnLFxuICAgICAgICAgICctLWRpc2FibGUtcmVuZGVyZXItYmFja2dyb3VuZGluZycsXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBicm93c2VyID0gYXdhaXQgcHVwcGV0ZWVyLmxhdW5jaChsYXVuY2hPcHRpb25zKTtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBhd2FpdCBicm93c2VyLmNyZWF0ZUJyb3dzZXJDb250ZXh0KCk7XG5cbiAgICAgIGNvbnN0IGlkID0gdGhpcy5nZW5lcmF0ZUJyb3dzZXJJZCgpO1xuICAgICAgY29uc3QgbWFuYWdlZEJyb3dzZXI6IE1hbmFnZWRCcm93c2VyID0ge1xuICAgICAgICBicm93c2VyLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgICBpZCxcbiAgICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICBsYXN0VXNlZDogbmV3IERhdGUoKSxcbiAgICAgICAgaXNBdmFpbGFibGU6IHRydWUsXG4gICAgICAgIGlzSGVhbHRoeTogdHJ1ZSxcbiAgICAgICAgdXNhZ2VDb3VudDogMCxcbiAgICAgIH07XG5cbiAgICAgIHRoaXMucG9vbC5zZXQoaWQsIG1hbmFnZWRCcm93c2VyKTtcblxuICAgICAgLy8gU2V0IHVwIGJyb3dzZXIgZXZlbnQgaGFuZGxlcnNcbiAgICAgIGJyb3dzZXIub24oJ2Rpc2Nvbm5lY3RlZCcsICgpID0+IHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYEJyb3dzZXIgJHtpZH0gZGlzY29ubmVjdGVkIHVuZXhwZWN0ZWRseWApO1xuICAgICAgICB0aGlzLmhhbmRsZUJyb3dzZXJEaXNjb25uZWN0aW9uKGlkKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbWFuYWdlZEJyb3dzZXI7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBicm93c2VyIGluc3RhbmNlOiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IEJyb3dzZXJMYXVuY2hFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBjcmVhdGUgYnJvd3NlciBpbnN0YW5jZTogJHtlcnJvcn1gLFxuICAgICAgICB7IHBvb2xTaXplOiB0aGlzLnBvb2wuc2l6ZSB9LFxuICAgICAgICBlcnJvciBhcyBFcnJvclxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmluZCBhbiBhdmFpbGFibGUgaGVhbHRoeSBicm93c2VyIGluIHRoZSBwb29sXG4gICAqL1xuICBwcml2YXRlIGZpbmRBdmFpbGFibGVCcm93c2VyKCk6IE1hbmFnZWRCcm93c2VyIHwgbnVsbCB7XG4gICAgZm9yIChjb25zdCBicm93c2VyIG9mIHRoaXMucG9vbC52YWx1ZXMoKSkge1xuICAgICAgaWYgKGJyb3dzZXIuaXNBdmFpbGFibGUgJiYgYnJvd3Nlci5pc0hlYWx0aHkpIHtcbiAgICAgICAgcmV0dXJuIGJyb3dzZXI7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgYnJvd3NlciBzaG91bGQgYmUgcmV0aXJlZFxuICAgKi9cbiAgcHJpdmF0ZSBzaG91bGRSZXRpcmVCcm93c2VyKGJyb3dzZXI6IE1hbmFnZWRCcm93c2VyKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgY29uc3QgYWdlID0gRGF0ZS5ub3coKSAtIGJyb3dzZXIuY3JlYXRlZEF0LmdldFRpbWUoKTtcblxuICAgIGlmIChhZ2UgPiB0aGlzLm9wdGlvbnMubWF4QWdlKSB7XG4gICAgICByZXR1cm4gJ21heCBhZ2UgZXhjZWVkZWQnO1xuICAgIH1cblxuICAgIGlmIChicm93c2VyLnVzYWdlQ291bnQgPj0gdGhpcy5vcHRpb25zLm1heFVzYWdlQ291bnQpIHtcbiAgICAgIHJldHVybiAnbWF4IHVzYWdlIGNvdW50IGV4Y2VlZGVkJztcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIGhlYWx0aCBjaGVjayBvbiBhIGJyb3dzZXIgaW5zdGFuY2VcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY2hlY2tCcm93c2VySGVhbHRoKGJyb3dzZXI6IE1hbmFnZWRCcm93c2VyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIENoZWNrIGlmIGJyb3dzZXIgaXMgY29ubmVjdGVkXG4gICAgICBpZiAoIWJyb3dzZXIuYnJvd3Nlci5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gVHJ5IHRvIGNyZWF0ZSBhbmQgY2xvc2UgYSB0ZXN0IHBhZ2VcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBicm93c2VyLmNvbnRleHQubmV3UGFnZSgpO1xuICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmRlYnVnKGBCcm93c2VyICR7YnJvd3Nlci5pZH0gaGVhbHRoIGNoZWNrIGZhaWxlZDogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGEgYnJvd3NlciBmcm9tIHRoZSBwb29sXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlbW92ZUJyb3dzZXJGcm9tUG9vbChicm93c2VySWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGJyb3dzZXIgPSB0aGlzLnBvb2wuZ2V0KGJyb3dzZXJJZCk7XG4gICAgaWYgKCFicm93c2VyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGJyb3dzZXIuYnJvd3Nlci5jbG9zZSgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRXJyb3IgY2xvc2luZyBicm93c2VyICR7YnJvd3NlcklkfTogJHtlcnJvcn1gKTtcbiAgICB9XG5cbiAgICB0aGlzLnBvb2wuZGVsZXRlKGJyb3dzZXJJZCk7XG4gICAgbG9nZ2VyLmRlYnVnKGBSZW1vdmVkIGJyb3dzZXIgJHticm93c2VySWR9IGZyb20gcG9vbGApO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBicm93c2VyIGRpc2Nvbm5lY3Rpb25cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlQnJvd3NlckRpc2Nvbm5lY3Rpb24oYnJvd3NlcklkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBicm93c2VyID0gdGhpcy5wb29sLmdldChicm93c2VySWQpO1xuICAgIGlmIChicm93c2VyKSB7XG4gICAgICBicm93c2VyLmlzSGVhbHRoeSA9IGZhbHNlO1xuICAgICAgYnJvd3Nlci5pc0F2YWlsYWJsZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFJlbW92ZSB0aGUgZGlzY29ubmVjdGVkIGJyb3dzZXIgYW5kIGVuc3VyZSBtaW5pbXVtIGluc3RhbmNlc1xuICAgIGF3YWl0IHRoaXMucmVtb3ZlQnJvd3NlckZyb21Qb29sKGJyb3dzZXJJZCk7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVNaW5pbXVtSW5zdGFuY2VzKCk7XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlIG1pbmltdW0gbnVtYmVyIG9mIGluc3RhbmNlcyBhcmUgYXZhaWxhYmxlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGVuc3VyZU1pbmltdW1JbnN0YW5jZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaXNTaHV0dGluZ0Rvd24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBoZWFsdGh5Q291bnQgPSBBcnJheS5mcm9tKHRoaXMucG9vbC52YWx1ZXMoKSkuZmlsdGVyKChiKSA9PiBiLmlzSGVhbHRoeSkubGVuZ3RoO1xuXG4gICAgY29uc3QgbmVlZGVkID0gdGhpcy5vcHRpb25zLm1pbkluc3RhbmNlcyAtIGhlYWx0aHlDb3VudDtcblxuICAgIGlmIChuZWVkZWQgPiAwKSB7XG4gICAgICBsb2dnZXIuaW5mbyhgQ3JlYXRpbmcgJHtuZWVkZWR9IGJyb3dzZXIgaW5zdGFuY2VzIHRvIG1haW50YWluIG1pbmltdW0gcG9vbCBzaXplYCk7XG5cbiAgICAgIGNvbnN0IGNyZWF0ZVByb21pc2VzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogbmVlZGVkIH0sICgpID0+XG4gICAgICAgIHRoaXMuY3JlYXRlQnJvd3Nlckluc3RhbmNlKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIGJyb3dzZXIgZm9yIG1pbmltdW0gaW5zdGFuY2VzOiAke2Vycm9yfWApO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKGNyZWF0ZVByb21pc2VzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNvdW50IG9mIGF2YWlsYWJsZSBicm93c2Vyc1xuICAgKi9cbiAgcHJpdmF0ZSBnZXRBdmFpbGFibGVDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMucG9vbC52YWx1ZXMoKSkuZmlsdGVyKChiKSA9PiBiLmlzQXZhaWxhYmxlICYmIGIuaXNIZWFsdGh5KS5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgaGVhbHRoIG1vbml0b3JpbmdcbiAgICovXG4gIHByaXZhdGUgc3RhcnRIZWFsdGhNb25pdG9yaW5nKCk6IHZvaWQge1xuICAgIHRoaXMuaGVhbHRoQ2hlY2tUaW1lciA9IHNldEludGVydmFsKGFzeW5jICgpID0+IHtcbiAgICAgIGlmICh0aGlzLmlzU2h1dHRpbmdEb3duKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdW5oZWFsdGh5QnJvd3NlcnM6IHN0cmluZ1tdID0gW107XG5cbiAgICAgIGZvciAoY29uc3QgW2lkLCBicm93c2VyXSBvZiB0aGlzLnBvb2wuZW50cmllcygpKSB7XG4gICAgICAgIGlmICghYnJvd3Nlci5pc0F2YWlsYWJsZSkge1xuICAgICAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIGJyb3dzZXJzIGN1cnJlbnRseSBpbiB1c2VcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlzSGVhbHRoeSA9IGF3YWl0IHRoaXMuY2hlY2tCcm93c2VySGVhbHRoKGJyb3dzZXIpO1xuICAgICAgICBpZiAoIWlzSGVhbHRoeSkge1xuICAgICAgICAgIHVuaGVhbHRoeUJyb3dzZXJzLnB1c2goaWQpO1xuICAgICAgICAgIGJyb3dzZXIuaXNIZWFsdGh5ID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gUmVtb3ZlIHVuaGVhbHRoeSBicm93c2Vyc1xuICAgICAgZm9yIChjb25zdCBpZCBvZiB1bmhlYWx0aHlCcm93c2Vycykge1xuICAgICAgICBsb2dnZXIud2FybihgUmVtb3ZpbmcgdW5oZWFsdGh5IGJyb3dzZXIgJHtpZH0gZHVyaW5nIGhlYWx0aCBjaGVja2ApO1xuICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUJyb3dzZXJGcm9tUG9vbChpZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEVuc3VyZSBtaW5pbXVtIGluc3RhbmNlcyBhZnRlciBjbGVhbnVwXG4gICAgICBpZiAodW5oZWFsdGh5QnJvd3NlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZU1pbmltdW1JbnN0YW5jZXMoKTtcbiAgICAgIH1cbiAgICB9LCB0aGlzLm9wdGlvbnMuaGVhbHRoQ2hlY2tJbnRlcnZhbCk7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgY2xlYW51cCBtb25pdG9yaW5nIGZvciBpZGxlIGJyb3dzZXJzXG4gICAqL1xuICBwcml2YXRlIHN0YXJ0Q2xlYW51cE1vbml0b3JpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhbnVwVGltZXIgPSBzZXRJbnRlcnZhbChhc3luYyAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5pc1NodXR0aW5nRG93bikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICBjb25zdCBicm93c2Vyc1RvUmVtb3ZlOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IFtpZCwgYnJvd3Nlcl0gb2YgdGhpcy5wb29sLmVudHJpZXMoKSkge1xuICAgICAgICBpZiAoIWJyb3dzZXIuaXNBdmFpbGFibGUpIHtcbiAgICAgICAgICBjb250aW51ZTsgLy8gU2tpcCBicm93c2VycyBjdXJyZW50bHkgaW4gdXNlXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpZGxlVGltZSA9IG5vdyAtIGJyb3dzZXIubGFzdFVzZWQuZ2V0VGltZSgpO1xuICAgICAgICBjb25zdCBzaG91bGRSZXRpcmUgPSB0aGlzLnNob3VsZFJldGlyZUJyb3dzZXIoYnJvd3Nlcik7XG5cbiAgICAgICAgaWYgKGlkbGVUaW1lID4gdGhpcy5vcHRpb25zLmlkbGVUaW1lb3V0IHx8IHNob3VsZFJldGlyZSkge1xuICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGlmIHdlIGhhdmUgbW9yZSB0aGFuIG1pbmltdW0gaW5zdGFuY2VzXG4gICAgICAgICAgY29uc3QgaGVhbHRoeUNvdW50ID0gQXJyYXkuZnJvbSh0aGlzLnBvb2wudmFsdWVzKCkpLmZpbHRlcigoYikgPT4gYi5pc0hlYWx0aHkpLmxlbmd0aDtcblxuICAgICAgICAgIGlmIChoZWFsdGh5Q291bnQgPiB0aGlzLm9wdGlvbnMubWluSW5zdGFuY2VzKSB7XG4gICAgICAgICAgICBicm93c2Vyc1RvUmVtb3ZlLnB1c2goaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBSZW1vdmUgaWRsZS9vbGQgYnJvd3NlcnNcbiAgICAgIGZvciAoY29uc3QgaWQgb2YgYnJvd3NlcnNUb1JlbW92ZSkge1xuICAgICAgICBjb25zdCByZWFzb24gPSB0aGlzLnNob3VsZFJldGlyZUJyb3dzZXIodGhpcy5wb29sLmdldChpZCkhKSB8fCAnaWRsZSB0aW1lb3V0JztcbiAgICAgICAgbG9nZ2VyLmluZm8oYFJlbW92aW5nIGJyb3dzZXIgJHtpZH0gZHVlIHRvICR7cmVhc29ufWApO1xuICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUJyb3dzZXJGcm9tUG9vbChpZCk7XG4gICAgICB9XG4gICAgfSwgdGhpcy5vcHRpb25zLmhlYWx0aENoZWNrSW50ZXJ2YWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIHVuaXF1ZSBicm93c2VyIElEXG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlQnJvd3NlcklkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBicm93c2VyXyR7RGF0ZS5ub3coKX1fJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMiwgMTEpfWA7XG4gIH1cbn1cblxuLy8gR2xvYmFsIGJyb3dzZXIgcG9vbCBpbnN0YW5jZVxubGV0IGdsb2JhbEJyb3dzZXJQb29sOiBCcm93c2VyUG9vbFNlcnZpY2UgfCBudWxsID0gbnVsbDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJyb3dzZXJQb29sKCk6IEJyb3dzZXJQb29sU2VydmljZSB7XG4gIGlmICghZ2xvYmFsQnJvd3NlclBvb2wpIHtcbiAgICBnbG9iYWxCcm93c2VyUG9vbCA9IG5ldyBCcm93c2VyUG9vbFNlcnZpY2UoKTtcbiAgfVxuICByZXR1cm4gZ2xvYmFsQnJvd3NlclBvb2w7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGVhbnVwQnJvd3NlclBvb2woKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChnbG9iYWxCcm93c2VyUG9vbCkge1xuICAgIGF3YWl0IGdsb2JhbEJyb3dzZXJQb29sLmNsZWFudXAoKTtcbiAgICBnbG9iYWxCcm93c2VyUG9vbCA9IG51bGw7XG4gIH1cbn1cbiIsIi8qKlxuICogQnJvd3NlciBNYW5hZ2VyIGZvciBYSFMgT3BlcmF0aW9uc1xuICovXG5cbmltcG9ydCBwdXBwZXRlZXIsIHsgQnJvd3NlciwgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBDb25maWcsIENvb2tpZSB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBCcm93c2VyTGF1bmNoRXJyb3IsIEJyb3dzZXJOYXZpZ2F0aW9uRXJyb3IsIFhIU0Vycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IGxvYWRDb29raWVzLCBzYXZlQ29va2llcyB9IGZyb20gJy4uLy4uL3NoYXJlZC9jb29raWVzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgQnJvd3NlclBvb2xTZXJ2aWNlLCBNYW5hZ2VkQnJvd3NlciB9IGZyb20gJy4vYnJvd3Nlci1wb29sLnNlcnZpY2UnO1xuXG5leHBvcnQgY2xhc3MgQnJvd3Nlck1hbmFnZXIge1xuICBwcml2YXRlIGNvbmZpZzogQ29uZmlnO1xuICBwcml2YXRlIGJyb3dzZXI6IEJyb3dzZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBicm93c2VyUG9vbDogQnJvd3NlclBvb2xTZXJ2aWNlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgdXNlUG9vbDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZz86IENvbmZpZywgdXNlUG9vbDogYm9vbGVhbiA9IGZhbHNlKSB7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWcgfHwgZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy51c2VQb29sID0gdXNlUG9vbDtcblxuICAgIGlmICh0aGlzLnVzZVBvb2wpIHtcbiAgICAgIHRoaXMuYnJvd3NlclBvb2wgPSBuZXcgQnJvd3NlclBvb2xTZXJ2aWNlKHRoaXMuY29uZmlnKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjcmVhdGVQYWdlKFxuICAgIGhlYWRsZXNzPzogYm9vbGVhbixcbiAgICBleGVjdXRhYmxlUGF0aD86IHN0cmluZyxcbiAgICBzaG91bGRMb2FkQ29va2llczogYm9vbGVhbiA9IHRydWVcbiAgKTogUHJvbWlzZTxQYWdlPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFVzZSBicm93c2VyIHBvb2wgaWYgZW5hYmxlZFxuICAgICAgaWYgKHRoaXMudXNlUG9vbCAmJiB0aGlzLmJyb3dzZXJQb29sKSB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNyZWF0ZVBhZ2VGcm9tUG9vbChzaG91bGRMb2FkQ29va2llcyk7XG4gICAgICB9XG5cbiAgICAgIC8vIEZhbGxiYWNrIHRvIHRyYWRpdGlvbmFsIGJyb3dzZXIgbWFuYWdlbWVudFxuICAgICAgLy8gTGF1bmNoIGJyb3dzZXIgaWYgbm90IGFscmVhZHkgbGF1bmNoZWRcbiAgICAgIGlmICghdGhpcy5icm93c2VyKSB7XG4gICAgICAgIHRoaXMuYnJvd3NlciA9IGF3YWl0IHRoaXMubGF1bmNoQnJvd3NlcihoZWFkbGVzcywgZXhlY3V0YWJsZVBhdGgpO1xuICAgICAgfVxuXG4gICAgICAvLyBDcmVhdGUgbmV3IHBhZ2VcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmJyb3dzZXIubmV3UGFnZSgpO1xuXG4gICAgICAvLyBDb25maWd1cmUgcGFnZSB0aW1lb3V0c1xuICAgICAgcGFnZS5zZXREZWZhdWx0VGltZW91dCh0aGlzLmNvbmZpZy5icm93c2VyLmRlZmF1bHRUaW1lb3V0KTtcbiAgICAgIHBhZ2Uuc2V0RGVmYXVsdE5hdmlnYXRpb25UaW1lb3V0KHRoaXMuY29uZmlnLmJyb3dzZXIubmF2aWdhdGlvblRpbWVvdXQpO1xuXG4gICAgICAvLyBMb2FkIGNvb2tpZXMgaWYgcmVxdWVzdGVkXG4gICAgICBpZiAoc2hvdWxkTG9hZENvb2tpZXMpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5sb2FkQ29va2llc0ludG9QYWdlKHBhZ2UpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGFnZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBCcm93c2VyIHBhZ2UgY3JlYXRpb24gZXJyb3I6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyB0aGlzLmhhbmRsZVB1cHBldGVlckVycm9yKGVycm9yIGFzIEVycm9yLCAnY3JlYXRlX3BhZ2UnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgcGFnZSB1c2luZyB0aGUgYnJvd3NlciBwb29sXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNyZWF0ZVBhZ2VGcm9tUG9vbChzaG91bGRMb2FkQ29va2llczogYm9vbGVhbiA9IHRydWUpOiBQcm9taXNlPFBhZ2U+IHtcbiAgICBpZiAoIXRoaXMuYnJvd3NlclBvb2wpIHtcbiAgICAgIHRocm93IG5ldyBYSFNFcnJvcignQnJvd3NlciBwb29sIG5vdCBpbml0aWFsaXplZCcsICdCcm93c2VyUG9vbEVycm9yJyk7XG4gICAgfVxuXG4gICAgY29uc3QgbWFuYWdlZEJyb3dzZXIgPSBhd2FpdCB0aGlzLmJyb3dzZXJQb29sLmFjcXVpcmVCcm93c2VyKCk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gQ3JlYXRlIG5ldyBwYWdlIGZyb20gdGhlIG1hbmFnZWQgYnJvd3NlciBjb250ZXh0XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgbWFuYWdlZEJyb3dzZXIuY29udGV4dC5uZXdQYWdlKCk7XG5cbiAgICAgIC8vIENvbmZpZ3VyZSBwYWdlIHRpbWVvdXRzXG4gICAgICBwYWdlLnNldERlZmF1bHRUaW1lb3V0KHRoaXMuY29uZmlnLmJyb3dzZXIuZGVmYXVsdFRpbWVvdXQpO1xuICAgICAgcGFnZS5zZXREZWZhdWx0TmF2aWdhdGlvblRpbWVvdXQodGhpcy5jb25maWcuYnJvd3Nlci5uYXZpZ2F0aW9uVGltZW91dCk7XG5cbiAgICAgIC8vIExvYWQgY29va2llcyBpZiByZXF1ZXN0ZWRcbiAgICAgIGlmIChzaG91bGRMb2FkQ29va2llcykge1xuICAgICAgICBhd2FpdCB0aGlzLmxvYWRDb29raWVzSW50b1BhZ2UocGFnZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFN0b3JlIHJlZmVyZW5jZSB0byBtYW5hZ2VkIGJyb3dzZXIgZm9yIGNsZWFudXBcbiAgICAgIChwYWdlIGFzIFBhZ2UgJiB7IF9tYW5hZ2VkQnJvd3Nlcj86IE1hbmFnZWRCcm93c2VyIH0pLl9tYW5hZ2VkQnJvd3NlciA9IG1hbmFnZWRCcm93c2VyO1xuXG4gICAgICAvLyBTZXQgdXAgcGFnZSBjbG9zZSBoYW5kbGVyIHRvIHJlbGVhc2UgYnJvd3NlciBiYWNrIHRvIHBvb2xcbiAgICAgIHBhZ2Uub25jZSgnY2xvc2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyUG9vbCEucmVsZWFzZUJyb3dzZXIobWFuYWdlZEJyb3dzZXIpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGxvZ2dlci53YXJuKGBFcnJvciByZWxlYXNpbmcgYnJvd3NlciBiYWNrIHRvIHBvb2w6ICR7ZXJyb3J9YCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcGFnZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gUmVsZWFzZSBicm93c2VyIGJhY2sgdG8gcG9vbCBvbiBlcnJvclxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyUG9vbC5yZWxlYXNlQnJvd3NlcihtYW5hZ2VkQnJvd3Nlcik7XG4gICAgICB9IGNhdGNoIChyZWxlYXNlRXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYEVycm9yIHJlbGVhc2luZyBicm93c2VyIGFmdGVyIHBhZ2UgY3JlYXRpb24gZmFpbHVyZTogJHtyZWxlYXNlRXJyb3J9YCk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxhdW5jaEJyb3dzZXIoaGVhZGxlc3M/OiBib29sZWFuLCBleGVjdXRhYmxlUGF0aD86IHN0cmluZyk6IFByb21pc2U8QnJvd3Nlcj4ge1xuICAgIGNvbnN0IGlzSGVhZGxlc3MgPSBmYWxzZTsgLy8gdGVtcG9yYXJpbHkgZGlzYWJsZSBoZWFkbGVzcyBtb2RlIGZvciBkZWJ1Z2dpbmdcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBsYXVuY2hPcHRpb25zOiBhbnkgPSB7XG4gICAgICAgIGhlYWRsZXNzOiBpc0hlYWRsZXNzLFxuICAgICAgICBzbG93TW86IHRoaXMuY29uZmlnLmJyb3dzZXIuc2xvd21vLFxuICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgJy0tbm8tc2FuZGJveCcsXG4gICAgICAgICAgJy0tZGlzYWJsZS1zZXR1aWQtc2FuZGJveCcsXG4gICAgICAgICAgJy0tZGlzYWJsZS1kZXYtc2htLXVzYWdlJyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWFjY2VsZXJhdGVkLTJkLWNhbnZhcycsXG4gICAgICAgICAgJy0tbm8tZmlyc3QtcnVuJyxcbiAgICAgICAgICAnLS1uby16eWdvdGUnLFxuICAgICAgICAgICctLWRpc2FibGUtZ3B1JyxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGlmIChleGVjdXRhYmxlUGF0aCkge1xuICAgICAgICBsYXVuY2hPcHRpb25zLmV4ZWN1dGFibGVQYXRoID0gZXhlY3V0YWJsZVBhdGg7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGJyb3dzZXIgPSBhd2FpdCBwdXBwZXRlZXIubGF1bmNoKGxhdW5jaE9wdGlvbnMpO1xuXG4gICAgICByZXR1cm4gYnJvd3NlcjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gbGF1bmNoIGJyb3dzZXI6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgQnJvd3NlckxhdW5jaEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGxhdW5jaCBicm93c2VyOiAke2Vycm9yfWAsXG4gICAgICAgIHsgaGVhZGxlc3M6IGlzSGVhZGxlc3MsIGV4ZWN1dGFibGVQYXRoIH0sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9hZENvb2tpZXNJbnRvUGFnZShwYWdlOiBQYWdlKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvb2tpZXMgPSBsb2FkQ29va2llcygpO1xuXG4gICAgICBpZiAoIWNvb2tpZXMpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyBDb252ZXJ0IG91ciBjb29raWUgZm9ybWF0IHRvIFB1cHBldGVlciBmb3JtYXRcbiAgICAgIGNvbnN0IHB1cHBldGVlckNvb2tpZXMgPSBjb29raWVzLm1hcCgoY29va2llKSA9PiAoe1xuICAgICAgICBuYW1lOiBjb29raWUubmFtZSxcbiAgICAgICAgdmFsdWU6IGNvb2tpZS52YWx1ZSxcbiAgICAgICAgZG9tYWluOiBjb29raWUuZG9tYWluLFxuICAgICAgICBwYXRoOiBjb29raWUucGF0aCxcbiAgICAgICAgZXhwaXJlczogY29va2llLmV4cGlyZXMsXG4gICAgICAgIGh0dHBPbmx5OiBjb29raWUuaHR0cE9ubHksXG4gICAgICAgIHNlY3VyZTogY29va2llLnNlY3VyZSxcbiAgICAgICAgc2FtZVNpdGU6IGNvb2tpZS5zYW1lU2l0ZSBhcyAnU3RyaWN0JyB8ICdMYXgnIHwgJ05vbmUnIHwgdW5kZWZpbmVkLFxuICAgICAgfSkpO1xuXG4gICAgICBhd2FpdCBwYWdlLnNldENvb2tpZSguLi5wdXBwZXRlZXJDb29raWVzKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRmFpbGVkIHRvIGxvYWQgY29va2llczogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlQ29va2llc0Zyb21QYWdlKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29va2llcyA9IGF3YWl0IHBhZ2UuY29va2llcygpO1xuXG4gICAgICAvLyBDb252ZXJ0IFB1cHBldGVlciBjb29raWUgZm9ybWF0IHRvIGFwcCBmb3JtYXRcbiAgICAgIGNvbnN0IGFwcENvb2tpZXM6IENvb2tpZVtdID0gY29va2llcy5tYXAoKGNvb2tpZSkgPT4gKHtcbiAgICAgICAgbmFtZTogY29va2llLm5hbWUsXG4gICAgICAgIHZhbHVlOiBjb29raWUudmFsdWUsXG4gICAgICAgIGRvbWFpbjogY29va2llLmRvbWFpbixcbiAgICAgICAgcGF0aDogY29va2llLnBhdGgsXG4gICAgICAgIGV4cGlyZXM6IGNvb2tpZS5leHBpcmVzLFxuICAgICAgICBodHRwT25seTogY29va2llLmh0dHBPbmx5LFxuICAgICAgICBzZWN1cmU6IGNvb2tpZS5zZWN1cmUsXG4gICAgICAgIHNhbWVTaXRlOiBjb29raWUuc2FtZVNpdGUgYXMgJ1N0cmljdCcgfCAnTGF4JyB8ICdOb25lJyxcbiAgICAgIH0pKTtcblxuICAgICAgc2F2ZUNvb2tpZXMoYXBwQ29va2llcyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHNhdmUgY29va2llczogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IHRoaXMuaGFuZGxlUHVwcGV0ZWVyRXJyb3IoZXJyb3IgYXMgRXJyb3IsICdzYXZlX2Nvb2tpZXMnKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBuYXZpZ2F0ZVdpdGhSZXRyeShcbiAgICBwYWdlOiBQYWdlLFxuICAgIHVybDogc3RyaW5nLFxuICAgIHdhaXRVbnRpbDogJ2xvYWQnIHwgJ2RvbWNvbnRlbnRsb2FkZWQnIHwgJ25ldHdvcmtpZGxlMCcgfCAnbmV0d29ya2lkbGUyJyA9ICdsb2FkJyxcbiAgICBtYXhSZXRyaWVzPzogbnVtYmVyXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJldHJpZXMgPSBtYXhSZXRyaWVzIHx8IHRoaXMuY29uZmlnLnhocy5tYXhSZXRyaWVzO1xuXG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPD0gcmV0cmllczsgYXR0ZW1wdCsrKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBwYWdlLmdvdG8odXJsLCB7XG4gICAgICAgICAgd2FpdFVudGlsLFxuICAgICAgICAgIHRpbWVvdXQ6IHRoaXMuY29uZmlnLmJyb3dzZXIubmF2aWdhdGlvblRpbWVvdXQsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5uYW1lID09PSAnVGltZW91dEVycm9yJykge1xuICAgICAgICAgIGlmIChhdHRlbXB0ID09PSByZXRyaWVzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQnJvd3Nlck5hdmlnYXRpb25FcnJvcihcbiAgICAgICAgICAgICAgYEZhaWxlZCB0byBuYXZpZ2F0ZSB0byAke3VybH0gYWZ0ZXIgJHtyZXRyaWVzICsgMX0gYXR0ZW1wdHNgLFxuICAgICAgICAgICAgICB7IHVybCwgYXR0ZW1wdHM6IGF0dGVtcHQgKyAxIH0sXG4gICAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGF3YWl0IHNsZWVwKHRoaXMuY29uZmlnLnhocy5yZXRyeURlbGF5ICogMTAwMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyB0cnlXYWl0Rm9yU2VsZWN0b3IoXG4gICAgcGFnZTogUGFnZSxcbiAgICBzZWxlY3Rvcjogc3RyaW5nLFxuICAgIHRpbWVvdXQ/OiBudW1iZXIsXG4gICAgdmlzaWJsZTogYm9vbGVhbiA9IHRydWVcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclNlbGVjdG9yKHNlbGVjdG9yLCB7XG4gICAgICAgIHRpbWVvdXQ6IHRpbWVvdXQgfHwgdGhpcy5jb25maWcuYnJvd3Nlci5kZWZhdWx0VGltZW91dCxcbiAgICAgICAgdmlzaWJsZSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm5hbWUgPT09ICdUaW1lb3V0RXJyb3InKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHdhaXRGb3JTZWxlY3RvclZpc2libGUocGFnZTogUGFnZSwgc2VsZWN0b3I6IHN0cmluZywgdGltZW91dD86IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnRyeVdhaXRGb3JTZWxlY3RvcihwYWdlLCBzZWxlY3RvciwgdGltZW91dCwgdHJ1ZSk7XG4gIH1cblxuICBhc3luYyB3YWl0Rm9yU2VsZWN0b3JIaWRkZW4ocGFnZTogUGFnZSwgc2VsZWN0b3I6IHN0cmluZywgdGltZW91dD86IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnRyeVdhaXRGb3JTZWxlY3RvcihwYWdlLCBzZWxlY3RvciwgdGltZW91dCwgZmFsc2UpO1xuICB9XG5cbiAgYXN5bmMgY2xlYW51cCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBDbGVhbnVwIGJyb3dzZXIgcG9vbCBpZiB1c2luZyBpdFxuICAgIGlmICh0aGlzLnVzZVBvb2wgJiYgdGhpcy5icm93c2VyUG9vbCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyUG9vbC5jbGVhbnVwKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihgRXJyb3IgY2xlYW5pbmcgdXAgYnJvd3NlciBwb29sOiAke2Vycm9yfWApO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdGhpcy5icm93c2VyUG9vbCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2xlYW51cCB0cmFkaXRpb25hbCBicm93c2VyIGluc3RhbmNlXG4gICAgaWYgKHRoaXMuYnJvd3Nlcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyLmNsb3NlKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihgRXJyb3IgY2xvc2luZyBicm93c2VyOiAke2Vycm9yfWApO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdGhpcy5icm93c2VyID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGJyb3dzZXIgcG9vbCBzdGF0aXN0aWNzIChpZiB1c2luZyBwb29sKVxuICAgKi9cbiAgZ2V0QnJvd3NlclBvb2xTdGF0cygpIHtcbiAgICBpZiAodGhpcy51c2VQb29sICYmIHRoaXMuYnJvd3NlclBvb2wpIHtcbiAgICAgIHJldHVybiB0aGlzLmJyb3dzZXJQb29sLmdldFBvb2xTdGF0cygpO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmFibGUgYnJvd3NlciBwb29saW5nXG4gICAqL1xuICBlbmFibGVCcm93c2VyUG9vbCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMudXNlUG9vbCkge1xuICAgICAgdGhpcy51c2VQb29sID0gdHJ1ZTtcbiAgICAgIHRoaXMuYnJvd3NlclBvb2wgPSBuZXcgQnJvd3NlclBvb2xTZXJ2aWNlKHRoaXMuY29uZmlnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGlzYWJsZSBicm93c2VyIHBvb2xpbmdcbiAgICovXG4gIGFzeW5jIGRpc2FibGVCcm93c2VyUG9vbCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy51c2VQb29sICYmIHRoaXMuYnJvd3NlclBvb2wpIHtcbiAgICAgIGF3YWl0IHRoaXMuYnJvd3NlclBvb2wuY2xlYW51cCgpO1xuICAgICAgdGhpcy5icm93c2VyUG9vbCA9IG51bGw7XG4gICAgICB0aGlzLnVzZVBvb2wgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVB1cHBldGVlckVycm9yKGVycm9yOiBFcnJvciwgb3BlcmF0aW9uTmFtZTogc3RyaW5nKTogWEhTRXJyb3Ige1xuICAgIGNvbnN0IGNvbnRleHQgPSB7IG9wZXJhdGlvbk5hbWUgfTtcblxuICAgIGlmIChlcnJvci5uYW1lID09PSAnVGltZW91dEVycm9yJykge1xuICAgICAgaWYgKG9wZXJhdGlvbk5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnbG9naW4nKSkge1xuICAgICAgICByZXR1cm4gbmV3IFhIU0Vycm9yKFxuICAgICAgICAgIGBMb2dpbiBvcGVyYXRpb24gdGltZWQgb3V0IGR1cmluZyAke29wZXJhdGlvbk5hbWV9YCxcbiAgICAgICAgICAnTG9naW5UaW1lb3V0RXJyb3InLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgZXJyb3JcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgWEhTRXJyb3IoXG4gICAgICAgICAgYEJyb3dzZXIgb3BlcmF0aW9uIHRpbWVkIG91dDogJHtvcGVyYXRpb25OYW1lfWAsXG4gICAgICAgICAgJ0Jyb3dzZXJFcnJvcicsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZXJyb3IubWVzc2FnZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCduYXZpZ2F0aW9uJykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBCcm93c2VyTmF2aWdhdGlvbkVycm9yKFxuICAgICAgICAgIGBOYXZpZ2F0aW9uIGZhaWxlZCBkdXJpbmcgJHtvcGVyYXRpb25OYW1lfTogJHtlcnJvci5tZXNzYWdlfWAsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBYSFNFcnJvcihcbiAgICAgICAgICBgQnJvd3NlciBlcnJvciBkdXJpbmcgJHtvcGVyYXRpb25OYW1lfTogJHtlcnJvci5tZXNzYWdlfWAsXG4gICAgICAgICAgJ0Jyb3dzZXJFcnJvcicsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vLyBHbG9iYWwgYnJvd3NlciBtYW5hZ2VyIGluc3RhbmNlXG5sZXQgZ2xvYmFsQnJvd3Nlck1hbmFnZXI6IEJyb3dzZXJNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCcm93c2VyTWFuYWdlcih1c2VQb29sOiBib29sZWFuID0gZmFsc2UpOiBCcm93c2VyTWFuYWdlciB7XG4gIGlmICghZ2xvYmFsQnJvd3Nlck1hbmFnZXIpIHtcbiAgICBnbG9iYWxCcm93c2VyTWFuYWdlciA9IG5ldyBCcm93c2VyTWFuYWdlcih1bmRlZmluZWQsIHVzZVBvb2wpO1xuICB9XG4gIHJldHVybiBnbG9iYWxCcm93c2VyTWFuYWdlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBvb2xlZEJyb3dzZXJNYW5hZ2VyKCk6IEJyb3dzZXJNYW5hZ2VyIHtcbiAgcmV0dXJuIGdldEJyb3dzZXJNYW5hZ2VyKHRydWUpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2xlYW51cEdsb2JhbEJyb3dzZXJNYW5hZ2VyKCk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoZ2xvYmFsQnJvd3Nlck1hbmFnZXIpIHtcbiAgICBhd2FpdCBnbG9iYWxCcm93c2VyTWFuYWdlci5jbGVhbnVwKCk7XG4gICAgZ2xvYmFsQnJvd3Nlck1hbmFnZXIgPSBudWxsO1xuICB9XG59XG4iLCIvKipcbiAqIEJhc2Ugc2VydmljZSBjbGFzcyBmb3IgWEhTIE1DUCBTZXJ2ZXIgc2VydmljZXNcbiAqL1xuXG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IEJyb3dzZXJNYW5hZ2VyIH0gZnJvbSAnLi4vY29yZS9icm93c2VyL2Jyb3dzZXIubWFuYWdlcic7XG5cbi8qKlxuICogQmFzZSBzZXJ2aWNlIGNsYXNzIHRoYXQgcHJvdmlkZXMgY29tbW9uIGZ1bmN0aW9uYWxpdHkgZm9yIGFsbCBzZXJ2aWNlc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZVNlcnZpY2Uge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY29uZmlnOiBDb25maWc7XG4gIHByb3RlY3RlZCByZWFkb25seSBicm93c2VyTWFuYWdlcjogQnJvd3Nlck1hbmFnZXI7XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLmJyb3dzZXJNYW5hZ2VyID0gbmV3IEJyb3dzZXJNYW5hZ2VyKGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBicm93c2VyIG1hbmFnZXIgaW5zdGFuY2VcbiAgICovXG4gIHByb3RlY3RlZCBnZXRCcm93c2VyTWFuYWdlcigpOiBCcm93c2VyTWFuYWdlciB7XG4gICAgcmV0dXJuIHRoaXMuYnJvd3Nlck1hbmFnZXI7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjb25maWd1cmF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0Q29uZmlnKCk6IENvbmZpZyB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnO1xuICB9XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3100\n\n}");
|
|
67
|
-
|
|
68
|
-
/***/ }),
|
|
69
|
-
|
|
70
|
-
/***/ 3193:
|
|
71
|
-
/***/ ((module) => {
|
|
72
|
-
|
|
73
|
-
module.exports = require("string_decoder");
|
|
74
|
-
|
|
75
|
-
/***/ }),
|
|
76
|
-
|
|
77
|
-
/***/ 4760:
|
|
78
|
-
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
79
|
-
|
|
80
|
-
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}");
|
|
81
|
-
|
|
82
|
-
/***/ }),
|
|
83
|
-
|
|
84
|
-
/***/ 5582:
|
|
85
|
-
/***/ ((__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) => {
|
|
86
|
-
|
|
87
|
-
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 + 2 modules\nvar base_service = __webpack_require__(3100);\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) {\n super(config);\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 // Get profile information if already logged in\n let profile = undefined;\n try {\n // Find current user's profile link and extract user ID from URL\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 // Extract user ID from profile URL\n const userIdMatch = profileUrl.match(/\\/user\\/profile\\/([a-f0-9]+)/);\n if (userIdMatch) {\n profile = {\n userId: userIdMatch[1],\n profileUrl: profileUrl,\n };\n }\n }\n // Also try to get additional profile info from current page\n const loginStatus = await getLoginStatusWithProfile(page);\n if (loginStatus.profile) {\n profile = { ...profile, ...loginStatus.profile };\n }\n }\n catch (profileError) {\n logger/* logger */.v.warn('Failed to get profile information:', profileError);\n // Continue without profile info\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; // Check every 5 seconds\n const maxChecks = timeout / checkInterval;\n for (let checkCount = 0; checkCount < maxChecks; checkCount++) {\n try {\n // Check if login completed with short timeout\n await page.waitForSelector(this.getConfig().xhs.loginOkSelector, {\n timeout: checkInterval * 1000,\n });\n // Login completed successfully\n break;\n }\n catch (error) {\n // Login not yet complete, continue checking\n const elapsed = (checkCount + 1) * checkInterval;\n const remaining = timeout - elapsed;\n if (checkCount === maxChecks - 1) {\n // Final timeout reached\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); // Brief wait for page to update\n const loginStatus = await getLoginStatusWithProfile(page);\n if (loginStatus.isLoggedIn) {\n // Try to get additional profile information\n let profile = loginStatus.profile;\n try {\n // Find current user's profile link and extract user ID from URL\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 // Extract user ID from profile URL\n const userIdMatch = profileUrl.match(/\\/user\\/profile\\/([a-f0-9]+)/);\n if (userIdMatch) {\n profile = {\n ...profile,\n userId: userIdMatch[1],\n profileUrl: profileUrl,\n };\n }\n }\n }\n catch (profileError) {\n logger/* logger */.v.warn('Failed to get additional profile information:', profileError);\n // Continue with existing profile info\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); // Wait for page to load\n // First check if logged in\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 // If logged in, try to get profile information\n let profile = undefined;\n try {\n // Find current user's profile link and extract user ID from URL\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 // Extract user ID from profile URL\n const userIdMatch = profileUrl.match(/\\/user\\/profile\\/([a-f0-9]+)/);\n if (userIdMatch) {\n profile = {\n userId: userIdMatch[1],\n profileUrl: profileUrl,\n };\n }\n }\n }\n catch (profileError) {\n console.error('❌ Failed to get profile information:', profileError);\n // Continue without profile info\n }\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) {\n super(config);\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) {\n super(config);\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 const titleSelectors = [\n 'input[placeholder*=\"标题\"]',\n 'input[placeholder*=\"title\"]',\n 'input[data-placeholder*=\"标题\"]',\n '.title-input input',\n 'input[type=\"text\"]',\n 'input[placeholder*=\"请输入标题\"]',\n 'input[placeholder*=\"标题\"]',\n 'input[name=\"title\"]',\n 'input[id*=\"title\"]',\n 'input[class*=\"title\"]',\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 const isVisible = await titleInput.isIntersectingViewport();\n if (isVisible) {\n await titleInput.click();\n await (0,utils/* sleep */.yy)(500); // Wait for focus\n await titleInput.type(title);\n return;\n }\n }\n }\n catch (error) {\n // Continue to next selector\n }\n }\n // If no input found, try to find any input or textarea on the page\n try {\n const allInputs = await page.$$('input, textarea, [contenteditable=\"true\"]');\n for (let i = 0; i < allInputs.length; i++) {\n const input = allInputs[i];\n try {\n const isVisible = await input.isIntersectingViewport();\n const tagName = await page.evaluate((el) => el.tagName, input);\n if (isVisible && (tagName === 'INPUT' || tagName === 'TEXTAREA')) {\n await input.click();\n await (0,utils/* sleep */.yy)(500);\n await input.type(title);\n return;\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 // Find the submit button by text \"发布\"\n const buttons = await page.$$('button');\n let submitButton = null;\n for (const btn of buttons) {\n const text = await btn.evaluate(el => el.textContent?.trim());\n if (text === '发布') {\n submitButton = btn;\n break;\n }\n }\n if (!submitButton) {\n // Try span or div as fallback\n const submitSelector = 'div.submit, .submit-btn, .publish-btn';\n submitButton = await page.$(submitSelector);\n if (!submitButton) {\n throw new shared_errors/* PublishError */.S1('Could not find submit button');\n }\n }\n await submitButton.click();\n logger/* logger */.v.debug('Clicked submit button natively');\n await (0,utils/* sleep */.yy)(2000);\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 = 60000; // 60 seconds\n const startTime = Date.now();\n while (Date.now() - startTime < maxWaitTime) {\n // Check for success indicators\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 await (0,utils/* sleep */.yy)(2000); // Wait a bit more for any final processing\n return await this.extractNoteIdFromPage(page);\n }\n }\n // 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 // 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 // We've left the publish page, likely successful\n logger/* logger */.v.debug('Left publish page, assuming success');\n return await this.extractNoteIdFromPage(page);\n }\n // Check for toast messages\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 await (0,utils/* sleep */.yy)(1000); // Wait before next check\n }\n throw new shared_errors/* PublishError */.S1('Publish completion timeout - could not determine result');\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__, 7482));\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 validateContentInputs(type, title, content, mediaPaths) {\n if (!title?.trim()) {\n throw new shared_errors/* PublishError */.S1(`${type === 'image' ? 'Image' : 'Video'} title cannot be empty`);\n }\n if (!content?.trim()) {\n throw new shared_errors/* PublishError */.S1(`${type === 'image' ? 'Image' : 'Video'} content cannot be empty`);\n }\n if (!mediaPaths || mediaPaths.length === 0) {\n throw new shared_errors/* PublishError */.S1(`${type === 'image' ? 'Image' : 'Video'} paths are required`);\n }\n if (type === 'image' && mediaPaths.length > 18) {\n throw new shared_errors/* PublishError */.S1('Maximum 18 images allowed for image posts');\n }\n if (type === 'video' && mediaPaths.length !== 1) {\n throw new shared_errors/* PublishError */.S1('Video publishing requires exactly one video file');\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)(3000);\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)(3000);\n // Check if tab switch was successful and retry if needed\n const pageState = await page.evaluate(() => {\n return {\n buttonTexts: Array.from(document.querySelectorAll('button, div[role=\"button\"]'))\n .map((el) => el.textContent?.trim())\n .filter((t) => t),\n };\n });\n // If still showing video upload, try clicking the tab again\n if (pageState.buttonTexts.includes('上传视频') &&\n !pageState.buttonTexts.includes('上传图文')) {\n await this.clickUploadTab(page);\n await (0,utils/* sleep */.yy)(3000);\n }\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 15 seconds for images to be uploaded and processed...');\n await (0,utils/* sleep */.yy)(15000);\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)(2000);\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)(2000);\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 using Puppeteer outer native click');\n // Wait for tabs to render\n await page.waitForSelector('.creator-tab', { timeout: 10000 });\n const tabs = await page.$$('.creator-tab');\n let clicked = false;\n for (const tab of tabs) {\n const text = await tab.evaluate(el => el.textContent);\n if (text && (text.includes('上传图文') || text.includes('图文'))) {\n const isVisible = await tab.isIntersectingViewport();\n if (!isVisible) {\n logger/* logger */.v.debug('Found a matching tab, but it is not visible in the viewport. Skipping...');\n continue; // Skip hidden elements\n }\n // Try native click first\n try {\n await tab.click({ delay: 150 });\n logger/* logger */.v.debug('Native Puppeteer click succeeded on tab.');\n }\n catch (e) {\n logger/* logger */.v.debug(`Puppeteer native click failed on visible tab: ${e}`);\n }\n await (0,utils/* sleep */.yy)(500);\n // Force a secondary click on the text itself via evaluate just in case hit area missed\n await tab.evaluate((el) => {\n const span = el.querySelector('span') || el;\n span.click();\n });\n clicked = true;\n logger/* logger */.v.debug('Successfully clicked image tab text match.');\n break;\n }\n }\n if (!clicked) {\n logger/* logger */.v.warn('Could not find visible image tab via textual matching.');\n }\n await (0,utils/* sleep */.yy)(2000);\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to click upload 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)(15000);\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 = (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) {\n super(config);\n this.imageService = new ImagePublishService(config);\n this.videoService = new VideoPublishService(config);\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 + 1 modules\nvar note_service = __webpack_require__(7482);\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\nclass ToolHandlers {\n authService;\n feedService;\n publishService;\n noteService;\n constructor() {\n const config = (0,shared_config/* getConfig */.zj)();\n this.authService = new AuthService(config);\n this.feedService = new FeedService(config);\n this.publishService = new PublishService(config);\n this.noteService = new note_service.NoteService(config);\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\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 console.log(`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 console.log(`StreamableHTTP session initialized with ID: ${sessionId}`);\n this.transports.set(sessionId, transport);\n },\n onsessionclosed: (sessionId) => {\n console.log(`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 console.log(`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 console.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 console.log('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 console.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 console.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 console.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 console.log('Shutting down HTTP server...');\n // Close all active transports to properly clean up resources\n for (const [sessionId, transport] of this.transports) {\n try {\n console.log(`Closing transport for session ${sessionId}`);\n await transport.close();\n }\n catch (error) {\n console.error(`Error closing transport for session ${sessionId}:`, error);\n }\n }\n this.transports.clear();\n server.close(() => {\n console.log('HTTP server shutdown complete');\n process.exit(0);\n });\n });\n process.on('SIGTERM', async () => {\n console.log('Shutting down HTTP server...');\n // Close all active transports to properly clean up resources\n for (const [sessionId, transport] of this.transports) {\n try {\n console.log(`Closing transport for session ${sessionId}`);\n await transport.close();\n }\n catch (error) {\n console.error(`Error closing transport for session ${sessionId}:`, error);\n }\n }\n this.transports.clear();\n server.close(() => {\n console.log('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 console.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 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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QUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3pGLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUM3QyxDQUFDO1FBRUQsTUFBTTtRQUNOLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNuRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDN0MsQ0FBQztRQUVELE9BQU87UUFDUCxJQUNFLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxJQUFJO1lBQ25CLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxJQUFJLEVBQ25CLENBQUM7WUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUM7UUFDOUMsQ0FBQztRQUVELE1BQU07UUFDTixJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFD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QU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEtBQUssSUFBSSxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUNELE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly94aHMtbWNwL2V4dGVybmFsIGNvbW1vbmpzMiBcImNvbW1hbmRlclwiP2M0NDgiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQveGhzLnV0aWxzLnRzP2IyNWUiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL2F1dGgvYXV0aC5zZXJ2aWNlLnRzPzY5ZmUiLCJ3ZWJwYWNrOi8veGhzLW1jcC9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI/OTg1ZCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvZmVlZHMvZmVlZC5zZXJ2aWNlLnRzPzY0YjciLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQvdGl0bGUtdmFsaWRhdG9yLnRzPzI0MzkiLCJ3ZWJwYWNrOi8veGhzLW1jcC9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwiY3J5cHRvXCI/YThiMiIsIndlYnBhY2s6Ly94aHMtbWNwL2V4dGVybmFsIGNvbW1vbmpzMiBcIm5vZGUtZmV0Y2hcIj8zNmU1Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2hhcmVkL2ltYWdlLWRvd25sb2FkZXIudHM/NTM1NiIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvcHVibGlzaGluZy9wdWJsaXNoLWJhc2Uuc2VydmljZS50cz82NzhjIiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9wdWJsaXNoaW5nL3B1Ymxpc2gtaW1hZ2Uuc2VydmljZS50cz9kNWY0Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9wdWJsaXNoaW5nL3B1Ymxpc2gtdmlkZW8uc2VydmljZS50cz81NDA2Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9wdWJsaXNoaW5nL3B1Ymxpc2guc2VydmljZS50cz8xN2U5Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2VydmVyL2hhbmRsZXJzL3Rvb2wuaGFuZGxlcnMudHM/N2Y3NCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NoYXJlZC9pbmRleC50cz84NDVlIiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2VydmVyL2hhbmRsZXJzL3Jlc291cmNlLmhhbmRsZXJzLnRzP2FhMzkiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zZXJ2ZXIvc2NoZW1hcy90b29sLnNjaGVtYXMudHM/ZGY4ZiIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NlcnZlci9tY3Auc2VydmVyLnRzPzMzOTQiLCJ3ZWJwYWNrOi8veGhzLW1jcC9leHRlcm5hbCBjb21tb25qczIgXCJleHByZXNzXCI/NWUzYSIsIndlYnBhY2s6Ly94aHMtbWNwL2V4dGVybmFsIGNvbW1vbmpzMiBcImNvcnNcIj85YzdkIiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2VydmVyL2h0dHAuc2VydmVyLnRzPzhjZDQiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zZXJ2ZXIvaGFuZGxlcnMvaW5kZXgudHM/MWU5NCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NlcnZlci9pbmRleC50cz81ZWU2Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvY2xpL2NsaS50cz9jYjlkIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IF9fV0VCUEFDS19OQU1FU1BBQ0VfT0JKRUNUX18gPSByZXF1aXJlKFwiY29tbWFuZGVyXCIpOyIsIi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIFhIUyBvcGVyYXRpb25zXG4gKi9cblxuaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlcic7XG5cbmV4cG9ydCBjb25zdCBYSFNfSE9NRV9VUkwgPSAnaHR0cHM6Ly93d3cueGlhb2hvbmdzaHUuY29tJztcbmV4cG9ydCBjb25zdCBYSFNfRVhQTE9SRV9VUkwgPSBgJHtYSFNfSE9NRV9VUkx9L2V4cGxvcmVgO1xuZXhwb3J0IGNvbnN0IFhIU19TRUFSQ0hfVVJMID0gYCR7WEhTX0hPTUVfVVJMfS9zZWFyY2hfcmVzdWx0YDtcbmV4cG9ydCBjb25zdCBYSFNfQ1JFQVRPUl9QVUJMSVNIX1VSTCA9XG4gICdodHRwczovL2NyZWF0b3IueGlhb2hvbmdzaHUuY29tL3B1Ymxpc2gvcHVibGlzaD9zb3VyY2U9b2ZmaWNpYWwnO1xuZXhwb3J0IGNvbnN0IExPR0lOX09LX1NFTEVDVE9SID0gJy5tYWluLWNvbnRhaW5lciAudXNlciAubGluay13cmFwcGVyIC5jaGFubmVsJztcblxuZXhwb3J0IGZ1bmN0aW9uIG1ha2VTZWFyY2hVcmwoa2V5d29yZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAga2V5d29yZCxcbiAgICBzb3VyY2U6ICd3ZWJfZXhwbG9yZV9mZWVkJyxcbiAgfSk7XG4gIHJldHVybiBgJHtYSFNfU0VBUkNIX1VSTH0/JHtwYXJhbXMudG9TdHJpbmcoKX1gO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWFrZUZlZWREZXRhaWxVcmwoZmVlZElkOiBzdHJpbmcsIHhzZWNUb2tlbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgeHNlY190b2tlbjogeHNlY1Rva2VuLFxuICAgIHhzZWNfc291cmNlOiAncGNfZmVlZCcsXG4gIH0pO1xuICByZXR1cm4gYCR7WEhTX0VYUExPUkVfVVJMfS8ke2ZlZWRJZH0/JHtwYXJhbXMudG9TdHJpbmcoKX1gO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXh0cmFjdEluaXRpYWxTdGF0ZShwYWdlOiBQYWdlKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IG51bGw+IHtcbiAgdHJ5IHtcbiAgICAvLyBXYWl0IGZvciBwYWdlIHRvIGJlIGZ1bGx5IGxvYWRlZCAtIFB1cHBldGVlciBkb2Vzbid0IGhhdmUgd2FpdEZvckxvYWRTdGF0ZVxuICAgIC8vIFdlJ2xsIGp1c3Qgd2FpdCBhIGJpdCBmb3IgdGhlIHBhZ2UgdG8gc2V0dGxlXG4gICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IGdsb2JhbFRoaXMuc2V0VGltZW91dChyZXNvbHZlLCAxMDAwKSk7XG4gIH0gY2F0Y2gge1xuICAgIC8vIElnbm9yZSBsb2FkIHN0YXRlIGVycm9yc1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKGBcbiAgICAgICgoKSA9PiB7XG4gICAgICAgIC8vIFRyeSBtdWx0aXBsZSBwb3NzaWJsZSBzdGF0ZSBvYmplY3RzXG4gICAgICAgIGNvbnN0IHBvc3NpYmxlU3RhdGVzID0gW1xuICAgICAgICAgIHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXyxcbiAgICAgICAgICB3aW5kb3cuX19JTklUSUFMX1NTUl9TVEFURV9fLFxuICAgICAgICAgIHdpbmRvdy5fX05FWFRfREFUQV9fLFxuICAgICAgICAgIHdpbmRvdy5fX05VWFRfXyxcbiAgICAgICAgICB3aW5kb3cuX19WVUVfXyxcbiAgICAgICAgICB3aW5kb3cuX19SRUFDVF9RVUVSWV9TVEFURV9fXG4gICAgICAgIF07XG5cbiAgICAgICAgZm9yIChjb25zdCBzdGF0ZSBvZiBwb3NzaWJsZVN0YXRlcykge1xuICAgICAgICAgIGlmIChzdGF0ZSAmJiB0eXBlb2Ygc3RhdGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAvLyBVc2UgYSBtb3JlIHJvYnVzdCBKU09OIHNlcmlhbGl6YXRpb24gdGhhdCBoYW5kbGVzIGNpcmN1bGFyIHJlZmVyZW5jZXNcbiAgICAgICAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBXZWFrU2V0KCk7XG4gICAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShzdGF0ZSwgKGtleSwgdmFsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbCAhPSBudWxsICYmIHR5cGVvZiB2YWwgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICAgIGlmIChzZWVuLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIltDaXJjdWxhcl1cIjtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIHNlZW4uYWRkKHZhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBsb2dnZXIud2FybignSlNPTi5zdHJpbmdpZnkgZmFpbGVkIGZvciBzdGF0ZTonLCBlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBubyBzdGF0ZSBmb3VuZCwgdHJ5IHRvIGZpbmQgYW55IGdsb2JhbCBzdGF0ZVxuICAgICAgICBjb25zdCBnbG9iYWxLZXlzID0gT2JqZWN0LmtleXMod2luZG93KS5maWx0ZXIoa2V5ID0+XG4gICAgICAgICAga2V5LmluY2x1ZGVzKCdTVEFURScpIHx8IGtleS5pbmNsdWRlcygnREFUQScpIHx8IGtleS5pbmNsdWRlcygnSU5JVElBTCcpXG4gICAgICAgICk7XG5cbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgZ2xvYmFsS2V5cykge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gd2luZG93W2tleV07XG4gICAgICAgICAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGNvbnN0IHNlZW4gPSBuZXcgV2Vha1NldCgpO1xuICAgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUsIChrZXksIHZhbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWwgIT0gbnVsbCAmJiB0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICBpZiAoc2Vlbi5oYXModmFsKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJbQ2lyY3VsYXJdXCI7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBzZWVuLmFkZCh2YWwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0pTT04uc3RyaW5naWZ5IGZhaWxlZCBmb3IgZ2xvYmFsIGtleTonLCBrZXksIGUubWVzc2FnZSk7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH0pKClcbiAgICBgKTtcblxuICAgIGlmICghcmVzdWx0KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gSlNPTi5wYXJzZShyZXN1bHQgYXMgc3RyaW5nKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGlzTG9nZ2VkSW4ocGFnZTogUGFnZSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICB0cnkge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJChMT0dJTl9PS19TRUxFQ1RPUik7XG4gICAgcmV0dXJuIGVsZW1lbnRzLmxlbmd0aCA+IDA7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0TG9naW5TdGF0dXNXaXRoUHJvZmlsZShwYWdlOiBQYWdlKTogUHJvbWlzZTx7XG4gIGlzTG9nZ2VkSW46IGJvb2xlYW47XG4gIHByb2ZpbGU/OiB7XG4gICAgdXNlcklkPzogc3RyaW5nO1xuICAgIG5pY2tuYW1lPzogc3RyaW5nO1xuICAgIHVzZXJuYW1lPzogc3RyaW5nO1xuICAgIGF2YXRhcj86IHN0cmluZztcbiAgICBmb2xsb3dlcnM/OiBudW1iZXI7XG4gICAgZm9sbG93aW5nPzogbnVtYmVyO1xuICAgIGxpa2VzPzogbnVtYmVyO1xuICAgIHhoc051bWJlcj86IHN0cmluZztcbiAgICBpcExvY2F0aW9uPzogc3RyaW5nO1xuICAgIHByb2ZpbGVVcmw/OiBzdHJpbmc7XG4gIH07XG59PiB7XG4gIHRyeSB7XG4gICAgLy8gRmlyc3QgY2hlY2sgaWYgbG9nZ2VkIGluIHVzaW5nIHRoZSBleGlzdGluZyBtZXRob2RcbiAgICBjb25zdCBlbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoTE9HSU5fT0tfU0VMRUNUT1IpO1xuICAgIGNvbnN0IGlzTG9nZ2VkSW4gPSBlbGVtZW50cy5sZW5ndGggPiAwO1xuXG4gICAgaWYgKCFpc0xvZ2dlZEluKSB7XG4gICAgICByZXR1cm4geyBpc0xvZ2dlZEluOiBmYWxzZSB9O1xuICAgIH1cblxuICAgIC8vIElmIGxvZ2dlZCBpbiwgdHJ5IHRvIGV4dHJhY3QgcHJvZmlsZSBpbmZvcm1hdGlvbiBmcm9tIGN1cnJlbnQgcGFnZVxuICAgIGxldCBwcm9maWxlRGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICB0cnkge1xuICAgICAgcHJvZmlsZURhdGEgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHtcbiAgICAgICAgY29uc3QgcHJvZmlsZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgICAgICAvLyBFeHRyYWN0IHVzZXIgSUQgZnJvbSBVUkwgaWYgb24gcHJvZmlsZSBwYWdlXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgICAgICBjb25zdCB1cmxNYXRjaCA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLm1hdGNoKC9cXC91c2VyXFwvcHJvZmlsZVxcLyhbYS1mMC05XSspLyk7XG4gICAgICAgIGlmICh1cmxNYXRjaCkge1xuICAgICAgICAgIHByb2ZpbGUudXNlcklkID0gdXJsTWF0Y2hbMV07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUcnkgdG8gZmluZCB1c2VyIG5pY2tuYW1lXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgICAgICBjb25zdCBuYW1lRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgJy51c2VyLW5hbWUsIFtjbGFzcyo9XCJ1c2VyLW5hbWVcIl0sIFtjbGFzcyo9XCJuaWNrbmFtZVwiXSdcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKG5hbWVFbGVtZW50KSB7XG4gICAgICAgICAgcHJvZmlsZS5uaWNrbmFtZSA9IG5hbWVFbGVtZW50LnRleHRDb250ZW50Py50cmltKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUcnkgdG8gZmluZCB1c2VyIGluZm8gdGV4dCB0aGF0IG1pZ2h0IGNvbnRhaW4gc3RhdHNcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICAgIGNvbnN0IGluZm9FbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnVzZXItaW5mbywgW2NsYXNzKj1cInVzZXItaW5mb1wiXScpO1xuICAgICAgICBpZiAoaW5mb0VsZW1lbnQpIHtcbiAgICAgICAgICBjb25zdCBpbmZvVGV4dCA9IGluZm9FbGVtZW50LnRleHRDb250ZW50IHx8ICcnO1xuICAgICAgICAgIHByb2ZpbGUuaW5mb1RleHQgPSBpbmZvVGV4dDtcblxuICAgICAgICAgIC8vIFRyeSB0byBleHRyYWN0IG51bWJlcnMgZnJvbSB0aGUgaW5mbyB0ZXh0IChmb2xsb3dlcnMsIGZvbGxvd2luZywgbGlrZXMpXG4gICAgICAgICAgY29uc3QgbnVtYmVycyA9IGluZm9UZXh0Lm1hdGNoKC9cXGQrL2cpO1xuICAgICAgICAgIGlmIChudW1iZXJzICYmIG51bWJlcnMubGVuZ3RoID49IDMpIHtcbiAgICAgICAgICAgIC8vIENvbW1vbiBwYXR0ZXJuOiBmb2xsb3dlcnMsIGZvbGxvd2luZywgbGlrZXNcbiAgICAgICAgICAgIHByb2ZpbGUuZm9sbG93aW5nID0gcGFyc2VJbnQobnVtYmVyc1swXSkgfHwgMDtcbiAgICAgICAgICAgIHByb2ZpbGUuZm9sbG93ZXJzID0gcGFyc2VJbnQobnVtYmVyc1sxXSkgfHwgMDtcbiAgICAgICAgICAgIHByb2ZpbGUubGlrZXMgPSBwYXJzZUludChudW1iZXJzWzJdKSB8fCAwO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEV4dHJhY3Qg5bCP57qi5Lmm5Y+3IChYSFMgbnVtYmVyKVxuICAgICAgICAgIGNvbnN0IHhoc01hdGNoID0gaW5mb1RleHQubWF0Y2goL+Wwj+e6ouS5puWPt++8mihcXGQrKS8pO1xuICAgICAgICAgIGlmICh4aHNNYXRjaCkge1xuICAgICAgICAgICAgcHJvZmlsZS54aHNOdW1iZXIgPSB4aHNNYXRjaFsxXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBFeHRyYWN0IElQ5bGe5ZywIChJUCBsb2NhdGlvbilcbiAgICAgICAgICBjb25zdCBpcE1hdGNoID0gaW5mb1RleHQubWF0Y2goL0lQ5bGe5Zyw77yaKFteMC05XSspLyk7XG4gICAgICAgICAgaWYgKGlwTWF0Y2gpIHtcbiAgICAgICAgICAgIHByb2ZpbGUuaXBMb2NhdGlvbiA9IGlwTWF0Y2hbMV0udHJpbSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyeSB0byBmaW5kIGF2YXRhclxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgY29uc3QgYXZhdGFyRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgJ2ltZ1tjbGFzcyo9XCJhdmF0YXJcIl0sIGltZ1tjbGFzcyo9XCJwcm9maWxlXCJdLCAuYXZhdGFyIGltZywgLnByb2ZpbGUgaW1nJ1xuICAgICAgICApIGFzIEhUTUxJbWFnZUVsZW1lbnQ7XG4gICAgICAgIGlmIChhdmF0YXJFbGVtZW50KSB7XG4gICAgICAgICAgcHJvZmlsZS5hdmF0YXIgPSBhdmF0YXJFbGVtZW50LnNyYztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwcm9maWxlO1xuICAgICAgfSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGluIHBhZ2UuZXZhbHVhdGUnKTtcbiAgICAgIHByb2ZpbGVEYXRhID0ge307XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlzTG9nZ2VkSW46IHRydWUsXG4gICAgICBwcm9maWxlOiBPYmplY3Qua2V5cyhwcm9maWxlRGF0YSkubGVuZ3RoID4gMCA/IHByb2ZpbGVEYXRhIDogdW5kZWZpbmVkLFxuICAgIH07XG4gIH0gY2F0Y2gge1xuICAgIC8vIElmIHRoZXJlJ3MgYW4gZXJyb3IsIGZhbGwgYmFjayB0byBiYXNpYyBsb2dpbiBjaGVja1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBlbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoTE9HSU5fT0tfU0VMRUNUT1IpO1xuICAgICAgcmV0dXJuIHsgaXNMb2dnZWRJbjogZWxlbWVudHMubGVuZ3RoID4gMCB9O1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHsgaXNMb2dnZWRJbjogZmFsc2UgfTtcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICogQXV0aGVudGljYXRpb24gc2VydmljZSBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG5pbXBvcnQgeyBDb25maWcsIExvZ2luUmVzdWx0LCBTdGF0dXNSZXN1bHQgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHtcbiAgTG9naW5UaW1lb3V0RXJyb3IsXG4gIExvZ2luRmFpbGVkRXJyb3IsXG4gIE5vdExvZ2dlZEluRXJyb3IsXG4gIFhIU0Vycm9yLFxufSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IEJhc2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Jhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBkZWxldGVDb29raWVzRmlsZSwgZ2V0Q29va2llc0luZm8gfSBmcm9tICcuLi8uLi9zaGFyZWQvY29va2llcyc7XG5pbXBvcnQgeyBpc0xvZ2dlZEluLCBnZXRMb2dpblN0YXR1c1dpdGhQcm9maWxlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3hocy51dGlscyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvbG9nZ2VyJztcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3V0aWxzJztcblxuZXhwb3J0IGNsYXNzIEF1dGhTZXJ2aWNlIGV4dGVuZHMgQmFzZVNlcnZpY2Uge1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IENvbmZpZykge1xuICAgIHN1cGVyKGNvbmZpZyk7XG4gIH1cblxuICBhc3luYyBsb2dpbihicm93c2VyUGF0aD86IHN0cmluZywgdGltZW91dDogbnVtYmVyID0gMzAwKTogUHJvbWlzZTxMb2dpblJlc3VsdD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UoZmFsc2UsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gTmF2aWdhdGUgdG8gZXhwbG9yZSBwYWdlXG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5uYXZpZ2F0ZVdpdGhSZXRyeShwYWdlLCB0aGlzLmdldENvbmZpZygpLnhocy5leHBsb3JlVXJsKTtcblxuICAgICAgICAvLyBDaGVjayBpZiBhbHJlYWR5IGxvZ2dlZCBpblxuICAgICAgICBpZiAoYXdhaXQgaXNMb2dnZWRJbihwYWdlKSkge1xuICAgICAgICAgIC8vIEdldCBwcm9maWxlIGluZm9ybWF0aW9uIGlmIGFscmVhZHkgbG9nZ2VkIGluXG4gICAgICAgICAgbGV0IHByb2ZpbGU6IGFueSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gRmluZCBjdXJyZW50IHVzZXIncyBwcm9maWxlIGxpbmsgYW5kIGV4dHJhY3QgdXNlciBJRCBmcm9tIFVSTFxuICAgICAgICAgICAgY29uc3QgcHJvZmlsZVVybCA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB1c2VyTGlua3MgPSBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2FbaHJlZio9XCIvdXNlci9wcm9maWxlL1wiXScpKTtcbiAgICAgICAgICAgICAgY29uc3QgY3VycmVudFVzZXJMaW5rID0gdXNlckxpbmtzLmZpbmQoKGxpbmspID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gbGluay50ZXh0Q29udGVudD8udHJpbSgpO1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICB0ZXh0ID09PSAn5oiRJyB8fFxuICAgICAgICAgICAgICAgICAgKHRleHQgJiYgdGV4dC5pbmNsdWRlcygncHJvZmlsZScpKSB8fFxuICAgICAgICAgICAgICAgICAgKHRleHQgJiYgdGV4dC5pbmNsdWRlcygn55So5oi3JykpXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJldHVybiBjdXJyZW50VXNlckxpbmsgPyAoY3VycmVudFVzZXJMaW5rIGFzIEhUTUxBbmNob3JFbGVtZW50KS5ocmVmIDogbnVsbDtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAocHJvZmlsZVVybCkge1xuICAgICAgICAgICAgICAvLyBFeHRyYWN0IHVzZXIgSUQgZnJvbSBwcm9maWxlIFVSTFxuICAgICAgICAgICAgICBjb25zdCB1c2VySWRNYXRjaCA9IHByb2ZpbGVVcmwubWF0Y2goL1xcL3VzZXJcXC9wcm9maWxlXFwvKFthLWYwLTldKykvKTtcbiAgICAgICAgICAgICAgaWYgKHVzZXJJZE1hdGNoKSB7XG4gICAgICAgICAgICAgICAgcHJvZmlsZSA9IHtcbiAgICAgICAgICAgICAgICAgIHVzZXJJZDogdXNlcklkTWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgICBwcm9maWxlVXJsOiBwcm9maWxlVXJsLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWxzbyB0cnkgdG8gZ2V0IGFkZGl0aW9uYWwgcHJvZmlsZSBpbmZvIGZyb20gY3VycmVudCBwYWdlXG4gICAgICAgICAgICBjb25zdCBsb2dpblN0YXR1cyA9IGF3YWl0IGdldExvZ2luU3RhdHVzV2l0aFByb2ZpbGUocGFnZSk7XG4gICAgICAgICAgICBpZiAobG9naW5TdGF0dXMucHJvZmlsZSkge1xuICAgICAgICAgICAgICBwcm9maWxlID0geyAuLi5wcm9maWxlLCAuLi5sb2dpblN0YXR1cy5wcm9maWxlIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAocHJvZmlsZUVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIGdldCBwcm9maWxlIGluZm9ybWF0aW9uOicsIHByb2ZpbGVFcnJvcik7XG4gICAgICAgICAgICAvLyBDb250aW51ZSB3aXRob3V0IHByb2ZpbGUgaW5mb1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgbWVzc2FnZTogJ0FscmVhZHkgbG9nZ2VkIGluJyxcbiAgICAgICAgICAgIHN0YXR1czogJ2xvZ2dlZF9pbicsXG4gICAgICAgICAgICBhY3Rpb246ICdub25lJyxcbiAgICAgICAgICAgIHByb2ZpbGUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdhaXQgZm9yIGxvZ2luIGNvbXBsZXRpb25cbiAgICAgICAgY29uc3QgY2hlY2tJbnRlcnZhbCA9IDU7IC8vIENoZWNrIGV2ZXJ5IDUgc2Vjb25kc1xuICAgICAgICBjb25zdCBtYXhDaGVja3MgPSB0aW1lb3V0IC8gY2hlY2tJbnRlcnZhbDtcblxuICAgICAgICBmb3IgKGxldCBjaGVja0NvdW50ID0gMDsgY2hlY2tDb3VudCA8IG1heENoZWNrczsgY2hlY2tDb3VudCsrKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGxvZ2luIGNvbXBsZXRlZCB3aXRoIHNob3J0IHRpbWVvdXRcbiAgICAgICAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclNlbGVjdG9yKHRoaXMuZ2V0Q29uZmlnKCkueGhzLmxvZ2luT2tTZWxlY3Rvciwge1xuICAgICAgICAgICAgICB0aW1lb3V0OiBjaGVja0ludGVydmFsICogMTAwMCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gTG9naW4gY29tcGxldGVkIHN1Y2Nlc3NmdWxseVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIExvZ2luIG5vdCB5ZXQgY29tcGxldGUsIGNvbnRpbnVlIGNoZWNraW5nXG4gICAgICAgICAgICBjb25zdCBlbGFwc2VkID0gKGNoZWNrQ291bnQgKyAxKSAqIGNoZWNrSW50ZXJ2YWw7XG4gICAgICAgICAgICBjb25zdCByZW1haW5pbmcgPSB0aW1lb3V0IC0gZWxhcHNlZDtcblxuICAgICAgICAgICAgaWYgKGNoZWNrQ291bnQgPT09IG1heENoZWNrcyAtIDEpIHtcbiAgICAgICAgICAgICAgLy8gRmluYWwgdGltZW91dCByZWFjaGVkXG4gICAgICAgICAgICAgIHRocm93IG5ldyBMb2dpblRpbWVvdXRFcnJvcihcbiAgICAgICAgICAgICAgICBgTG9naW4gdGltZWQgb3V0IGFmdGVyICR7dGltZW91dH0gc2Vjb25kcy4gUGxlYXNlIGNvbXBsZXRlIFFSIGNvZGUgc2Nhbm5pbmcgb3IgbWFudWFsIGxvZ2luIGluIHRoZSBicm93c2VyIHdpbmRvdy5gLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHRpbWVvdXQsXG4gICAgICAgICAgICAgICAgICB1cmw6IHRoaXMuZ2V0Q29uZmlnKCkueGhzLmV4cGxvcmVVcmwsXG4gICAgICAgICAgICAgICAgICBlbGFwc2VkVGltZTogZWxhcHNlZCxcbiAgICAgICAgICAgICAgICAgIHN1Z2dlc3Rpb246ICdJbmNyZWFzZSB0aW1lb3V0IHBhcmFtZXRlciBvciBjb21wbGV0ZSBsb2dpbiBmYXN0ZXInLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTYXZlIGNvb2tpZXMgYWZ0ZXIgc3VjY2Vzc2Z1bCBsb2dpblxuICAgICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuc2F2ZUNvb2tpZXNGcm9tUGFnZShwYWdlKTtcblxuICAgICAgICAvLyBWZXJpZnkgbG9naW4gc3VjY2VzcyBhbmQgZ2V0IHByb2ZpbGUgaW5mb3JtYXRpb25cbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7IC8vIEJyaWVmIHdhaXQgZm9yIHBhZ2UgdG8gdXBkYXRlXG4gICAgICAgIGNvbnN0IGxvZ2luU3RhdHVzID0gYXdhaXQgZ2V0TG9naW5TdGF0dXNXaXRoUHJvZmlsZShwYWdlKTtcbiAgICAgICAgaWYgKGxvZ2luU3RhdHVzLmlzTG9nZ2VkSW4pIHtcbiAgICAgICAgICAvLyBUcnkgdG8gZ2V0IGFkZGl0aW9uYWwgcHJvZmlsZSBpbmZvcm1hdGlvblxuICAgICAgICAgIGxldCBwcm9maWxlID0gbG9naW5TdGF0dXMucHJvZmlsZTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gRmluZCBjdXJyZW50IHVzZXIncyBwcm9maWxlIGxpbmsgYW5kIGV4dHJhY3QgdXNlciBJRCBmcm9tIFVSTFxuICAgICAgICAgICAgY29uc3QgcHJvZmlsZVVybCA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB1c2VyTGlua3MgPSBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2FbaHJlZio9XCIvdXNlci9wcm9maWxlL1wiXScpKTtcbiAgICAgICAgICAgICAgY29uc3QgY3VycmVudFVzZXJMaW5rID0gdXNlckxpbmtzLmZpbmQoKGxpbmspID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gbGluay50ZXh0Q29udGVudD8udHJpbSgpO1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICB0ZXh0ID09PSAn5oiRJyB8fFxuICAgICAgICAgICAgICAgICAgKHRleHQgJiYgdGV4dC5pbmNsdWRlcygncHJvZmlsZScpKSB8fFxuICAgICAgICAgICAgICAgICAgKHRleHQgJiYgdGV4dC5pbmNsdWRlcygn55So5oi3JykpXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJldHVybiBjdXJyZW50VXNlckxpbmsgPyAoY3VycmVudFVzZXJMaW5rIGFzIEhUTUxBbmNob3JFbGVtZW50KS5ocmVmIDogbnVsbDtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAocHJvZmlsZVVybCkge1xuICAgICAgICAgICAgICAvLyBFeHRyYWN0IHVzZXIgSUQgZnJvbSBwcm9maWxlIFVSTFxuICAgICAgICAgICAgICBjb25zdCB1c2VySWRNYXRjaCA9IHByb2ZpbGVVcmwubWF0Y2goL1xcL3VzZXJcXC9wcm9maWxlXFwvKFthLWYwLTldKykvKTtcbiAgICAgICAgICAgICAgaWYgKHVzZXJJZE1hdGNoKSB7XG4gICAgICAgICAgICAgICAgcHJvZmlsZSA9IHtcbiAgICAgICAgICAgICAgICAgIC4uLnByb2ZpbGUsXG4gICAgICAgICAgICAgICAgICB1c2VySWQ6IHVzZXJJZE1hdGNoWzFdLFxuICAgICAgICAgICAgICAgICAgcHJvZmlsZVVybDogcHJvZmlsZVVybCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAocHJvZmlsZUVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIGdldCBhZGRpdGlvbmFsIHByb2ZpbGUgaW5mb3JtYXRpb246JywgcHJvZmlsZUVycm9yKTtcbiAgICAgICAgICAgIC8vIENvbnRpbnVlIHdpdGggZXhpc3RpbmcgcHJvZmlsZSBpbmZvXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICBtZXNzYWdlOiAnTG9naW4gc3VjY2Vzc2Z1bCcsXG4gICAgICAgICAgICBzdGF0dXM6ICdsb2dnZWRfaW4nLFxuICAgICAgICAgICAgYWN0aW9uOiAnbG9nZ2VkX2luJyxcbiAgICAgICAgICAgIHByb2ZpbGUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTG9naW5GYWlsZWRFcnJvcihcbiAgICAgICAgICAgICdMb2dpbiBwcm9jZXNzIGNvbXBsZXRlZCBidXQgYXV0aGVudGljYXRpb24gdmVyaWZpY2F0aW9uIGZhaWxlZCdcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIExvZ2luVGltZW91dEVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgTG9naW5GYWlsZWRFcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5lcnJvcihgTG9naW4gZmFpbGVkIHdpdGggdW5leHBlY3RlZCBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IG5ldyBYSFNFcnJvcihgTG9naW4gZmFpbGVkOiAke2Vycm9yfWAsICdMb2dpbkVycm9yJywgeyB0aW1lb3V0IH0sIGVycm9yIGFzIEVycm9yKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBsb2dvdXQoKTogUHJvbWlzZTxMb2dpblJlc3VsdD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzdWNjZXNzID0gZGVsZXRlQ29va2llc0ZpbGUoKTtcblxuICAgICAgaWYgKHN1Y2Nlc3MpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIG1lc3NhZ2U6ICdMb2dnZWQgb3V0IHN1Y2Nlc3NmdWxseSAoY29va2llcyBkZWxldGVkKScsXG4gICAgICAgICAgc3RhdHVzOiAnbG9nZ2VkX291dCcsXG4gICAgICAgICAgYWN0aW9uOiAnbG9nZ2VkX291dCcsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIG1lc3NhZ2U6ICdGYWlsZWQgdG8gZGVsZXRlIGNvb2tpZXMgZmlsZScsXG4gICAgICAgICAgc3RhdHVzOiAnbG9nZ2VkX291dCcsXG4gICAgICAgICAgYWN0aW9uOiAnbm9uZScsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgTG9nb3V0IGZhaWxlZDogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiBgTG9nb3V0IGZhaWxlZDogJHtlcnJvcn1gLFxuICAgICAgICBzdGF0dXM6ICdsb2dnZWRfb3V0JyxcbiAgICAgICAgYWN0aW9uOiAnbm9uZScsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNoZWNrU3RhdHVzKGJyb3dzZXJQYXRoPzogc3RyaW5nKTogUHJvbWlzZTxTdGF0dXNSZXN1bHQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKHRydWUsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIHRoaXMuZ2V0Q29uZmlnKCkueGhzLmV4cGxvcmVVcmwpO1xuICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTsgLy8gV2FpdCBmb3IgcGFnZSB0byBsb2FkXG5cbiAgICAgICAgLy8gRmlyc3QgY2hlY2sgaWYgbG9nZ2VkIGluXG4gICAgICAgIGNvbnN0IGxvZ2dlZEluID0gYXdhaXQgaXNMb2dnZWRJbihwYWdlKTtcblxuICAgICAgICBpZiAoIWxvZ2dlZEluKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICBsb2dnZWRJbjogZmFsc2UsXG4gICAgICAgICAgICBzdGF0dXM6ICdsb2dnZWRfb3V0JyxcbiAgICAgICAgICAgIHVybENoZWNrZWQ6IHRoaXMuZ2V0Q29uZmlnKCkueGhzLmV4cGxvcmVVcmwsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIGxvZ2dlZCBpbiwgdHJ5IHRvIGdldCBwcm9maWxlIGluZm9ybWF0aW9uXG4gICAgICAgIGxldCBwcm9maWxlOiBhbnkgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gRmluZCBjdXJyZW50IHVzZXIncyBwcm9maWxlIGxpbmsgYW5kIGV4dHJhY3QgdXNlciBJRCBmcm9tIFVSTFxuICAgICAgICAgIGNvbnN0IHByb2ZpbGVVcmwgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHVzZXJMaW5rcyA9IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnYVtocmVmKj1cIi91c2VyL3Byb2ZpbGUvXCJdJykpO1xuICAgICAgICAgICAgY29uc3QgY3VycmVudFVzZXJMaW5rID0gdXNlckxpbmtzLmZpbmQoKGxpbmspID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgdGV4dCA9IGxpbmsudGV4dENvbnRlbnQ/LnRyaW0oKTtcbiAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICB0ZXh0ID09PSAn5oiRJyB8fFxuICAgICAgICAgICAgICAgICh0ZXh0ICYmIHRleHQuaW5jbHVkZXMoJ3Byb2ZpbGUnKSkgfHxcbiAgICAgICAgICAgICAgICAodGV4dCAmJiB0ZXh0LmluY2x1ZGVzKCfnlKjmiLcnKSlcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRVc2VyTGluayA/IChjdXJyZW50VXNlckxpbmsgYXMgSFRNTEFuY2hvckVsZW1lbnQpLmhyZWYgOiBudWxsO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKHByb2ZpbGVVcmwpIHtcbiAgICAgICAgICAgIC8vIEV4dHJhY3QgdXNlciBJRCBmcm9tIHByb2ZpbGUgVVJMXG4gICAgICAgICAgICBjb25zdCB1c2VySWRNYXRjaCA9IHByb2ZpbGVVcmwubWF0Y2goL1xcL3VzZXJcXC9wcm9maWxlXFwvKFthLWYwLTldKykvKTtcbiAgICAgICAgICAgIGlmICh1c2VySWRNYXRjaCkge1xuICAgICAgICAgICAgICBwcm9maWxlID0ge1xuICAgICAgICAgICAgICAgIHVzZXJJZDogdXNlcklkTWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgcHJvZmlsZVVybDogcHJvZmlsZVVybCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKHByb2ZpbGVFcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ+KdjCBGYWlsZWQgdG8gZ2V0IHByb2ZpbGUgaW5mb3JtYXRpb246JywgcHJvZmlsZUVycm9yKTtcbiAgICAgICAgICAvLyBDb250aW51ZSB3aXRob3V0IHByb2ZpbGUgaW5mb1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIGxvZ2dlZEluOiB0cnVlLFxuICAgICAgICAgIHN0YXR1czogJ2xvZ2dlZF9pbicsXG4gICAgICAgICAgdXJsQ2hlY2tlZDogdGhpcy5nZXRDb25maWcoKS54aHMuZXhwbG9yZVVybCxcbiAgICAgICAgICBwcm9maWxlLFxuICAgICAgICB9O1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYFN0YXR1cyBjaGVjayBmYWlsZWQ6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgWEhTRXJyb3IoYFN0YXR1cyBjaGVjayBmYWlsZWQ6ICR7ZXJyb3J9YCwgJ1N0YXR1c0NoZWNrRXJyb3InLCB7fSwgZXJyb3IgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxufVxuIiwiY29uc3QgX19XRUJQQUNLX05BTUVTUEFDRV9PQkpFQ1RfXyA9IHJlcXVpcmUoXCJub2RlOmNoaWxkX3Byb2Nlc3NcIik7IiwiLyoqXG4gKiBGZWVkIG9wZXJhdGlvbnMgc2VydmljZSBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG5pbXBvcnQge1xuICBDb25maWcsXG4gIEZlZWRMaXN0UmVzdWx0LFxuICBTZWFyY2hSZXN1bHQsXG4gIEZlZWREZXRhaWxSZXN1bHQsXG4gIENvbW1lbnRSZXN1bHQsXG4gIEZlZWRJdGVtLFxufSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHtcbiAgRmVlZEVycm9yLFxuICBGZWVkUGFyc2luZ0Vycm9yLFxuICBGZWVkTm90Rm91bmRFcnJvcixcbiAgTm90TG9nZ2VkSW5FcnJvcixcbiAgWEhTRXJyb3IsXG59IGZyb20gJy4uLy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IHsgQmFzZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvYmFzZS5zZXJ2aWNlJztcbmltcG9ydCB7XG4gIG1ha2VTZWFyY2hVcmwsXG4gIG1ha2VGZWVkRGV0YWlsVXJsLFxuICBleHRyYWN0SW5pdGlhbFN0YXRlLFxuICBpc0xvZ2dlZEluLFxufSBmcm9tICcuLi8uLi9zaGFyZWQveGhzLnV0aWxzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgRmVlZFNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnKSB7XG4gICAgc3VwZXIoY29uZmlnKTtcbiAgfVxuXG4gIGFzeW5jIGdldEZlZWRMaXN0KGJyb3dzZXJQYXRoPzogc3RyaW5nKTogUHJvbWlzZTxGZWVkTGlzdFJlc3VsdD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UodHJ1ZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkubmF2aWdhdGVXaXRoUmV0cnkocGFnZSwgdGhpcy5nZXRDb25maWcoKS54aHMuaG9tZVVybCk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAgIC8vIENoZWNrIGlmIGxvZ2dlZCBpblxuICAgICAgICBpZiAoIShhd2FpdCBpc0xvZ2dlZEluKHBhZ2UpKSkge1xuICAgICAgICAgIHRocm93IG5ldyBOb3RMb2dnZWRJbkVycm9yKCdNdXN0IGJlIGxvZ2dlZCBpbiB0byBhY2Nlc3MgZmVlZCBsaXN0Jywge1xuICAgICAgICAgICAgb3BlcmF0aW9uOiAnZ2V0X2ZlZWRfbGlzdCcsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFeHRyYWN0IGZlZWQgZGF0YSB1c2luZyBhIG1vcmUgdGFyZ2V0ZWQgYXBwcm9hY2hcbiAgICAgICAgbGV0IGZlZWREYXRhOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICAgICAgbGV0IGF0dGVtcHRzID0gMDtcbiAgICAgICAgY29uc3QgbWF4QXR0ZW1wdHMgPSAxMDtcblxuICAgICAgICB3aGlsZSAoYXR0ZW1wdHMgPCBtYXhBdHRlbXB0cyAmJiAhZmVlZERhdGEpIHtcbiAgICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTsgLy8gV2FpdCAyIHNlY29uZHMgYmV0d2VlbiBhdHRlbXB0c1xuICAgICAgICAgIGF0dGVtcHRzKys7XG5cbiAgICAgICAgICBmZWVkRGF0YSA9IChhd2FpdCBwYWdlLmV2YWx1YXRlKGBcbiAgICAgICAgICAgICgoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICh3aW5kb3cuX19JTklUSUFMX1NUQVRFX18gJiYgd2luZG93Ll9fSU5JVElBTF9TVEFURV9fLmZlZWQgJiYgd2luZG93Ll9fSU5JVElBTF9TVEFURV9fLmZlZWQuZmVlZHMgJiYgd2luZG93Ll9fSU5JVElBTF9TVEFURV9fLmZlZWQuZmVlZHMuX3ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIC8vIFRyeSB0byBzZXJpYWxpemUganVzdCB0aGUgZmVlZHMgZGF0YSB0byBhdm9pZCBjaXJjdWxhciByZWZlcmVuY2UgaXNzdWVzXG4gICAgICAgICAgICAgICAgICBjb25zdCBmZWVkc0RhdGEgPSB3aW5kb3cuX19JTklUSUFMX1NUQVRFX18uZmVlZC5mZWVkcy5fdmFsdWU7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZmVlZHNEYXRhKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIHNlcmlhbGl6ZSBmZWVkcyBkYXRhOicsIGUubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9KSgpXG4gICAgICAgICAgYCkpIGFzIHN0cmluZyB8IG51bGw7XG5cbiAgICAgICAgICBpZiAoZmVlZERhdGEpIHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBGZWVkIHJlc3VsdHMgbG9hZGVkIGFmdGVyICR7YXR0ZW1wdHN9IGF0dGVtcHRzYCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWZlZWREYXRhKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZlZWRQYXJzaW5nRXJyb3IoXG4gICAgICAgICAgICBgQ291bGQgbm90IGV4dHJhY3QgZmVlZCBkYXRhIGFmdGVyICR7bWF4QXR0ZW1wdHN9IGF0dGVtcHRzLiBUaGUgcGFnZSBtYXkgbm90IGJlIGZ1bGx5IGxvYWRlZCBvciB0aGUgc3RhdGUgc3RydWN0dXJlIGhhcyBjaGFuZ2VkLmAsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHVybDogdGhpcy5nZXRDb25maWcoKS54aHMuaG9tZVVybCxcbiAgICAgICAgICAgICAgc3VnZ2VzdGlvbjogJ1RyeSBsb2dnaW5nIGluIGZpcnN0IHVzaW5nIHhoc19hdXRoX2xvZ2luIHRvb2wnLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmZWVkc1ZhbHVlID0gSlNPTi5wYXJzZShmZWVkRGF0YSkgYXMgdW5rbm93bltdO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBmZWVkczogZmVlZHNWYWx1ZSBhcyBGZWVkSXRlbVtdLFxuICAgICAgICAgIGNvdW50OiBmZWVkc1ZhbHVlLmxlbmd0aCxcbiAgICAgICAgICBzb3VyY2U6ICdob21lX3BhZ2UnLFxuICAgICAgICAgIHVybDogdGhpcy5nZXRDb25maWcoKS54aHMuaG9tZVVybCxcbiAgICAgICAgfTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTm90TG9nZ2VkSW5FcnJvciB8fCBlcnJvciBpbnN0YW5jZW9mIEZlZWRQYXJzaW5nRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBnZXQgZmVlZCBsaXN0OiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGdldCBmZWVkIGxpc3Q6ICR7ZXJyb3J9YCxcbiAgICAgICAgJ0dldEZlZWRMaXN0RXJyb3InLFxuICAgICAgICB7fSxcbiAgICAgICAgZXJyb3IgYXMgRXJyb3JcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc2VhcmNoRmVlZHMoa2V5d29yZDogc3RyaW5nLCBicm93c2VyUGF0aD86IHN0cmluZyk6IFByb21pc2U8U2VhcmNoUmVzdWx0PiB7XG4gICAgaWYgKCFrZXl3b3JkIHx8ICFrZXl3b3JkLnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IEZlZWRFcnJvcignU2VhcmNoIGtleXdvcmQgY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgdHJpbW1lZEtleXdvcmQgPSBrZXl3b3JkLnRyaW0oKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UodHJ1ZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBzZWFyY2hVcmwgPSBtYWtlU2VhcmNoVXJsKHRyaW1tZWRLZXl3b3JkKTtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIHNlYXJjaFVybCk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3Igc2VhcmNoIHJlc3VsdHMgdG8gbG9hZCB3aXRoIG11bHRpcGxlIGF0dGVtcHRzXG4gICAgICAgIGxldCBzZWFyY2hEYXRhOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICAgICAgbGV0IGF0dGVtcHRzID0gMDtcbiAgICAgICAgY29uc3QgbWF4QXR0ZW1wdHMgPSAxMDtcblxuICAgICAgICB3aGlsZSAoYXR0ZW1wdHMgPCBtYXhBdHRlbXB0cyAmJiAhc2VhcmNoRGF0YSkge1xuICAgICAgICAgIGF3YWl0IHNsZWVwKDIwMDApOyAvLyBXYWl0IDIgc2Vjb25kcyBiZXR3ZWVuIGF0dGVtcHRzXG4gICAgICAgICAgYXR0ZW1wdHMrKztcblxuICAgICAgICAgIHNlYXJjaERhdGEgPSAoYXdhaXQgcGFnZS5ldmFsdWF0ZShgXG4gICAgICAgICAgICAoKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAod2luZG93Ll9fSU5JVElBTF9TVEFURV9fICYmIHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5zZWFyY2ggJiYgd2luZG93Ll9fSU5JVElBTF9TVEFURV9fLnNlYXJjaC5mZWVkcyAmJiB3aW5kb3cuX19JTklUSUFMX1NUQVRFX18uc2VhcmNoLmZlZWRzLl92YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAvLyBUcnkgdG8gc2VyaWFsaXplIGp1c3QgdGhlIGZlZWRzIGRhdGEgdG8gYXZvaWQgY2lyY3VsYXIgcmVmZXJlbmNlIGlzc3Vlc1xuICAgICAgICAgICAgICAgICAgY29uc3QgZmVlZHNEYXRhID0gd2luZG93Ll9fSU5JVElBTF9TVEFURV9fLnNlYXJjaC5mZWVkcy5fdmFsdWU7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZmVlZHNEYXRhKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIHNlcmlhbGl6ZSBmZWVkcyBkYXRhOicsIGUubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9KSgpXG4gICAgICAgICAgYCkpIGFzIHN0cmluZyB8IG51bGw7XG5cbiAgICAgICAgICBpZiAoc2VhcmNoRGF0YSkge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYFNlYXJjaCByZXN1bHRzIGxvYWRlZCBhZnRlciAke2F0dGVtcHRzfSBhdHRlbXB0c2ApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFzZWFyY2hEYXRhKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZlZWRQYXJzaW5nRXJyb3IoXG4gICAgICAgICAgICBgQ291bGQgbm90IGV4dHJhY3Qgc2VhcmNoIHJlc3VsdHMgZm9yIGtleXdvcmQ6ICR7dHJpbW1lZEtleXdvcmR9IGFmdGVyICR7bWF4QXR0ZW1wdHN9IGF0dGVtcHRzYCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAga2V5d29yZDogdHJpbW1lZEtleXdvcmQsXG4gICAgICAgICAgICAgIHVybDogc2VhcmNoVXJsLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmZWVkc1ZhbHVlID0gSlNPTi5wYXJzZShzZWFyY2hEYXRhKSBhcyB1bmtub3duW107XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIGtleXdvcmQ6IHRyaW1tZWRLZXl3b3JkLFxuICAgICAgICAgIGZlZWRzOiBmZWVkc1ZhbHVlIGFzIEZlZWRJdGVtW10sXG4gICAgICAgICAgY291bnQ6IGZlZWRzVmFsdWUubGVuZ3RoLFxuICAgICAgICAgIHNlYXJjaFVybCxcbiAgICAgICAgfTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRmVlZEVycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmVycm9yKGBGZWVkIHNlYXJjaCBmYWlsZWQgZm9yIGtleXdvcmQgJyR7dHJpbW1lZEtleXdvcmR9JzogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IG5ldyBYSFNFcnJvcihcbiAgICAgICAgYEZlZWQgc2VhcmNoIGZhaWxlZDogJHtlcnJvcn1gLFxuICAgICAgICAnU2VhcmNoRmVlZHNFcnJvcicsXG4gICAgICAgIHsga2V5d29yZDogdHJpbW1lZEtleXdvcmQgfSxcbiAgICAgICAgZXJyb3IgYXMgRXJyb3JcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0RmVlZERldGFpbChcbiAgICBmZWVkSWQ6IHN0cmluZyxcbiAgICB4c2VjVG9rZW46IHN0cmluZyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPEZlZWREZXRhaWxSZXN1bHQ+IHtcbiAgICBpZiAoIWZlZWRJZCB8fCAheHNlY1Rva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgRmVlZEVycm9yKCdCb3RoIGZlZWRfaWQgYW5kIHhzZWNfdG9rZW4gYXJlIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZSh0cnVlLCBicm93c2VyUGF0aCwgdHJ1ZSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGRldGFpbFVybCA9IG1ha2VGZWVkRGV0YWlsVXJsKGZlZWRJZCwgeHNlY1Rva2VuKTtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIGRldGFpbFVybCk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAgIGNvbnN0IHN0YXRlID0gYXdhaXQgZXh0cmFjdEluaXRpYWxTdGF0ZShwYWdlKTtcblxuICAgICAgICBjb25zdCBub3RlRGF0YSA9IHN0YXRlPy5ub3RlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICBpZiAoIXN0YXRlIHx8ICFub3RlRGF0YSB8fCAhbm90ZURhdGEubm90ZURldGFpbE1hcCkge1xuICAgICAgICAgIHRocm93IG5ldyBGZWVkUGFyc2luZ0Vycm9yKGBDb3VsZCBub3QgZXh0cmFjdCBub3RlIGRldGFpbHMgZm9yIGZlZWQ6ICR7ZmVlZElkfWAsIHtcbiAgICAgICAgICAgIGZlZWRJZCxcbiAgICAgICAgICAgIHVybDogZGV0YWlsVXJsLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgbm90ZURldGFpbE1hcCA9IG5vdGVEYXRhLm5vdGVEZXRhaWxNYXAgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgIGlmICghKGZlZWRJZCBpbiBub3RlRGV0YWlsTWFwKSkge1xuICAgICAgICAgIHRocm93IG5ldyBGZWVkTm90Rm91bmRFcnJvcihgRmVlZCAke2ZlZWRJZH0gbm90IGZvdW5kIGluIG5vdGUgZGV0YWlsc2AsIHtcbiAgICAgICAgICAgIGZlZWRJZCxcbiAgICAgICAgICAgIGF2YWlsYWJsZUZlZWRzOiBPYmplY3Qua2V5cyhub3RlRGV0YWlsTWFwKSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGRldGFpbCA9IG5vdGVEZXRhaWxNYXBbZmVlZElkXSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgZmVlZElkLFxuICAgICAgICAgIGRldGFpbCxcbiAgICAgICAgICB1cmw6IGRldGFpbFVybCxcbiAgICAgICAgfTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKFxuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEZlZWRFcnJvciB8fFxuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEZlZWROb3RGb3VuZEVycm9yIHx8XG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRmVlZFBhcnNpbmdFcnJvclxuICAgICAgKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IGZlZWQgZGV0YWlsIGZvciAke2ZlZWRJZH06ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgWEhTRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gZ2V0IGZlZWQgZGV0YWlsOiAke2Vycm9yfWAsXG4gICAgICAgICdHZXRGZWVkRGV0YWlsRXJyb3InLFxuICAgICAgICB7IGZlZWRJZCB9LFxuICAgICAgICBlcnJvciBhcyBFcnJvclxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjb21tZW50T25GZWVkKFxuICAgIGZlZWRJZDogc3RyaW5nLFxuICAgIHhzZWNUb2tlbjogc3RyaW5nLFxuICAgIG5vdGU6IHN0cmluZyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPENvbW1lbnRSZXN1bHQ+IHtcbiAgICBpZiAoIWZlZWRJZCB8fCAheHNlY1Rva2VuIHx8ICFub3RlKSB7XG4gICAgICB0aHJvdyBuZXcgRmVlZEVycm9yKCdmZWVkX2lkLCB4c2VjX3Rva2VuLCBhbmQgbm90ZSBhcmUgYWxsIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgaWYgKG5vdGUudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEZlZWRFcnJvcignQ29tbWVudCBub3RlIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UoZmFsc2UsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGV0YWlsVXJsID0gbWFrZUZlZWREZXRhaWxVcmwoZmVlZElkLCB4c2VjVG9rZW4pO1xuICAgICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkubmF2aWdhdGVXaXRoUmV0cnkocGFnZSwgZGV0YWlsVXJsKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgbG9nZ2VkIGluXG4gICAgICAgIGlmICghKGF3YWl0IGlzTG9nZ2VkSW4ocGFnZSkpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vdExvZ2dlZEluRXJyb3IoJ011c3QgYmUgbG9nZ2VkIGluIHRvIGNvbW1lbnQgb24gZmVlZHMnLCB7XG4gICAgICAgICAgICBvcGVyYXRpb246ICdjb21tZW50X29uX2ZlZWQnLFxuICAgICAgICAgICAgZmVlZElkLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2xpY2sgb24gY29tbWVudCBpbnB1dFxuICAgICAgICBjb25zdCBjb21tZW50SW5wdXRTZWxlY3RvciA9ICdkaXYuaW5wdXQtYm94IGRpdi5jb250ZW50LWVkaXQgc3Bhbic7XG4gICAgICAgIGlmICghKGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS50cnlXYWl0Rm9yU2VsZWN0b3IocGFnZSwgY29tbWVudElucHV0U2VsZWN0b3IpKSkge1xuICAgICAgICAgIHRocm93IG5ldyBGZWVkRXJyb3IoJ0NvbW1lbnQgaW5wdXQgbm90IGZvdW5kIG9uIHBhZ2UnLCB7XG4gICAgICAgICAgICBmZWVkSWQsXG4gICAgICAgICAgICBzZWxlY3RvcjogY29tbWVudElucHV0U2VsZWN0b3IsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb21tZW50SW5wdXQgPSBhd2FpdCBwYWdlLiQoY29tbWVudElucHV0U2VsZWN0b3IpO1xuICAgICAgICBpZiAoY29tbWVudElucHV0KSB7XG4gICAgICAgICAgYXdhaXQgY29tbWVudElucHV0LmNsaWNrKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaWxsIGNvbW1lbnQgbm90ZVxuICAgICAgICBjb25zdCBlZGl0b3JTZWxlY3RvciA9ICdkaXYuaW5wdXQtYm94IGRpdi5jb250ZW50LWVkaXQgcC5jb250ZW50LWlucHV0JztcbiAgICAgICAgY29uc3QgZWRpdG9yID0gYXdhaXQgcGFnZS4kKGVkaXRvclNlbGVjdG9yKTtcblxuICAgICAgICBpZiAoZWRpdG9yKSB7XG4gICAgICAgICAgYXdhaXQgZWRpdG9yLmNsaWNrKCk7XG4gICAgICAgICAgYXdhaXQgZWRpdG9yLnR5cGUobm90ZSwgeyBkZWxheTogMzAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG5cbiAgICAgICAgLy8gU3VibWl0IGNvbW1lbnRcbiAgICAgICAgY29uc3Qgc3VibWl0U2VsZWN0b3IgPSAnZGl2LmJvdHRvbSBidXR0b24uc3VibWl0JztcbiAgICAgICAgY29uc3Qgc3VibWl0QnV0dG9uID0gYXdhaXQgcGFnZS4kKHN1Ym1pdFNlbGVjdG9yKTtcbiAgICAgICAgaWYgKHN1Ym1pdEJ1dHRvbikge1xuICAgICAgICAgIGF3YWl0IHN1Ym1pdEJ1dHRvbi5jbGljaygpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKDIwMDApOyAvLyBXYWl0IGZvciBzdWJtaXNzaW9uXG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIG1lc3NhZ2U6ICdDb21tZW50IHN1Ym1pdHRlZCBzdWNjZXNzZnVsbHknLFxuICAgICAgICAgIGZlZWRJZCxcbiAgICAgICAgICBub3RlLFxuICAgICAgICAgIHVybDogZGV0YWlsVXJsLFxuICAgICAgICB9O1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBGZWVkRXJyb3IgfHwgZXJyb3IgaW5zdGFuY2VvZiBOb3RMb2dnZWRJbkVycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gY29tbWVudCBvbiBmZWVkICR7ZmVlZElkfTogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IG5ldyBYSFNFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBjb21tZW50IG9uIGZlZWQ6ICR7ZXJyb3J9YCxcbiAgICAgICAgJ0NvbW1lbnRPbkZlZWRFcnJvcicsXG4gICAgICAgIHsgZmVlZElkIH0sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBUaXRsZSB2YWxpZGF0aW9uIHV0aWxpdHkgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKiBWYWxpZGF0ZXMgdGl0bGUgd2lkdGggYWNjb3JkaW5nIHRvIFhpYW9Ib25nU2h1J3MgZGlzcGxheSB3aWR0aCBydWxlc1xuICpcbiAqIFhIUyBSdWxlczpcbiAqIC0gTWF4IHdpZHRoOiA0MCB1bml0c1xuICogLSBDSksgY2hhcmFjdGVycyAoQ2hpbmVzZS9KYXBhbmVzZS9Lb3JlYW4pOiAyIHVuaXRzIGVhY2hcbiAqIC0gT3RoZXIgY2hhcmFjdGVycyAoRW5nbGlzaC9OdW1iZXJzKTogMSB1bml0IGVhY2hcbiAqL1xuXG5pbXBvcnQgc3RyaW5nV2lkdGggZnJvbSAnc3RyaW5nLXdpZHRoJztcbmltcG9ydCB7IFB1Ymxpc2hFcnJvciB9IGZyb20gJy4vZXJyb3JzJztcblxuZXhwb3J0IGludGVyZmFjZSBUaXRsZVZhbGlkYXRpb25SZXN1bHQge1xuICB2YWxpZDogYm9vbGVhbjtcbiAgd2lkdGg6IG51bWJlcjtcbiAgbWF4V2lkdGg6IG51bWJlcjtcbiAgbWVzc2FnZT86IHN0cmluZztcbiAgc3VnZ2VzdGlvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBYaWFvSG9uZ1NodSB0aXRsZSBjb25zdHJhaW50c1xuICovXG5leHBvcnQgY29uc3QgWEhTX1RJVExFX0NPTlNUUkFJTlRTID0ge1xuICBNQVhfV0lEVEg6IDQwLCAvLyBNYXhpbXVtIGRpc3BsYXkgd2lkdGggaW4gdW5pdHNcbiAgTUFYX0xFTkdUSDogMjAsIC8vIEFwcHJveGltYXRlIG1heCBjaGFyYWN0ZXIgY291bnQgKGZvciByZWZlcmVuY2UpXG59IGFzIGNvbnN0O1xuXG4vKipcbiAqIFZhbGlkYXRlIHRpdGxlIHdpZHRoIGFjY29yZGluZyB0byBYSFMgZGlzcGxheSBydWxlc1xuICpcbiAqIEBwYXJhbSB0aXRsZSAtIFRoZSB0aXRsZSB0byB2YWxpZGF0ZVxuICogQHJldHVybnMgVmFsaWRhdGlvbiByZXN1bHQgd2l0aCB3aWR0aCBpbmZvcm1hdGlvblxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZXN1bHQgPSB2YWxpZGF0ZVRpdGxlV2lkdGgoJ0hlbGxv5LiW55WMJyk7XG4gKiBjb25zb2xlLmxvZyhyZXN1bHQud2lkdGgpOyAvLyAxMCAoNSArIDIqMiArIDEgPSAxMClcbiAqIGNvbnNvbGUubG9nKHJlc3VsdC52YWxpZCk7IC8vIHRydWVcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVUaXRsZVdpZHRoKHRpdGxlOiBzdHJpbmcpOiBUaXRsZVZhbGlkYXRpb25SZXN1bHQge1xuICBpZiAoIXRpdGxlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgIHdpZHRoOiAwLFxuICAgICAgbWF4V2lkdGg6IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEgsXG4gICAgICBtZXNzYWdlOiAnVGl0bGUgY2Fubm90IGJlIGVtcHR5JyxcbiAgICAgIHN1Z2dlc3Rpb246ICdQbGVhc2UgcHJvdmlkZSBhIHZhbGlkIHRpdGxlJyxcbiAgICB9O1xuICB9XG5cbiAgLy8gQ2FsY3VsYXRlIGRpc3BsYXkgd2lkdGggdXNpbmcgc3RyaW5nLXdpZHRoXG4gIC8vIFRoaXMgY29ycmVjdGx5IGhhbmRsZXMgQ0pLIGNoYXJhY3RlcnMsIGVtb2ppLCBhbmQgb3RoZXIgVW5pY29kZVxuICBjb25zdCB3aWR0aCA9IHN0cmluZ1dpZHRoKHRpdGxlKTtcblxuICBpZiAod2lkdGggPiBYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRIKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgIHdpZHRoLFxuICAgICAgbWF4V2lkdGg6IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEgsXG4gICAgICBtZXNzYWdlOiBgVGl0bGUgd2lkdGggZXhjZWVkcyBsaW1pdDogJHt3aWR0aH0gdW5pdHMgKG1heDogJHtYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRIfSB1bml0cylgLFxuICAgICAgc3VnZ2VzdGlvbjogYEN1cnJlbnQgdGl0bGUgaXMgdG9vIGxvbmcuIENKSyBjaGFyYWN0ZXJzIGNvdW50IGFzIDIgdW5pdHMsIEVuZ2xpc2gvbnVtYmVycyBhcyAxIHVuaXQuIFBsZWFzZSBzaG9ydGVuIHlvdXIgdGl0bGUuYCxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB2YWxpZDogdHJ1ZSxcbiAgICB3aWR0aCxcbiAgICBtYXhXaWR0aDogWEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSCxcbiAgfTtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBhbmQgdGhyb3cgZXJyb3IgaWYgdGl0bGUgd2lkdGggaXMgaW52YWxpZFxuICpcbiAqIEBwYXJhbSB0aXRsZSAtIFRoZSB0aXRsZSB0byB2YWxpZGF0ZVxuICogQHRocm93cyBQdWJsaXNoRXJyb3IgaWYgdGl0bGUgd2lkdGggaXMgaW52YWxpZFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiB0cnkge1xuICogICBhc3NlcnRUaXRsZVdpZHRoVmFsaWQoJ+W+iOmVv+W+iOmVv+eahOagh+mimCcucmVwZWF0KDEwKSk7XG4gKiB9IGNhdGNoIChlcnJvcikge1xuICogICBjb25zb2xlLmVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRUaXRsZVdpZHRoVmFsaWQodGl0bGU6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCByZXN1bHQgPSB2YWxpZGF0ZVRpdGxlV2lkdGgodGl0bGUpO1xuXG4gIGlmICghcmVzdWx0LnZhbGlkKSB7XG4gICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihyZXN1bHQubWVzc2FnZSEsIHtcbiAgICAgIHRpdGxlLFxuICAgICAgd2lkdGg6IHJlc3VsdC53aWR0aCxcbiAgICAgIG1heFdpZHRoOiByZXN1bHQubWF4V2lkdGgsXG4gICAgICBzdWdnZXN0aW9uOiByZXN1bHQuc3VnZ2VzdGlvbixcbiAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgdGl0bGVMZW5ndGg6IHRpdGxlLmxlbmd0aCxcbiAgICAgICAgZGlzcGxheVdpZHRoOiByZXN1bHQud2lkdGgsXG4gICAgICAgIG1heERpc3BsYXlXaWR0aDogcmVzdWx0Lm1heFdpZHRoLFxuICAgICAgICBleGNlZWRlZDogcmVzdWx0LndpZHRoIC0gcmVzdWx0Lm1heFdpZHRoLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIEdldCB0aGUgZGlzcGxheSB3aWR0aCBvZiBhIHRpdGxlXG4gKlxuICogQHBhcmFtIHRpdGxlIC0gVGhlIHRpdGxlIHRvIG1lYXN1cmVcbiAqIEByZXR1cm5zIERpc3BsYXkgd2lkdGggaW4gdW5pdHNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc29sZS5sb2coZ2V0VGl0bGVXaWR0aCgnSGVsbG8nKSk7ICAgICAgICAvLyA1XG4gKiBjb25zb2xlLmxvZyhnZXRUaXRsZVdpZHRoKCfkvaDlpb0nKSk7ICAgICAgICAgLy8gNCAoMioyKVxuICogY29uc29sZS5sb2coZ2V0VGl0bGVXaWR0aCgnSGVsbG/kuJbnlYwnKSk7ICAgIC8vIDEwICg1ICsgMioyICsgMSlcbiAqIGNvbnNvbGUubG9nKGdldFRpdGxlV2lkdGgoJ/CfkYtIZWxsbycpKTsgICAgICAvLyA3ICgyICsgNSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGl0bGVXaWR0aCh0aXRsZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgcmV0dXJuIHN0cmluZ1dpZHRoKHRpdGxlKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgaG93IG1hbnkgY2hhcmFjdGVycyBjYW4gYmUgYWRkZWQgdG8gdGhlIHRpdGxlXG4gKlxuICogQHBhcmFtIHRpdGxlIC0gQ3VycmVudCB0aXRsZVxuICogQHJldHVybnMgUmVtYWluaW5nIHdpZHRoIHVuaXRzIGF2YWlsYWJsZVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZW1haW5pbmcgPSBnZXRSZW1haW5pbmdUaXRsZVdpZHRoKCdIZWxsbycpOyAvLyAzNVxuICogY29uc29sZS5sb2coYFlvdSBjYW4gYWRkICR7cmVtYWluaW5nfSBtb3JlIHVuaXRzYCk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVJlbWFpbmluZ1RpdGxlV2lkdGgodGl0bGU6IHN0cmluZyk6IG51bWJlciB7XG4gIGNvbnN0IGN1cnJlbnRXaWR0aCA9IGdldFRpdGxlV2lkdGgodGl0bGUpO1xuICByZXR1cm4gTWF0aC5tYXgoMCwgWEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSCAtIGN1cnJlbnRXaWR0aCk7XG59XG5cbi8qKlxuICogVHJ1bmNhdGUgdGl0bGUgdG8gZml0IHdpdGhpbiB3aWR0aCBsaW1pdFxuICpcbiAqIEBwYXJhbSB0aXRsZSAtIFRoZSB0aXRsZSB0byB0cnVuY2F0ZVxuICogQHBhcmFtIG1heFdpZHRoIC0gTWF4aW11bSB3aWR0aCAoZGVmYXVsdDogWEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSClcbiAqIEByZXR1cm5zIFRydW5jYXRlZCB0aXRsZSB0aGF0IGZpdHMgd2l0aGluIHdpZHRoIGxpbWl0XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGxvbmcgPSAn6L+Z5piv5LiA5Liq5b6I6ZW/5b6I6ZW/55qE5qCH6aKYJy5yZXBlYXQoNSk7XG4gKiBjb25zdCB0cnVuY2F0ZWQgPSB0cnVuY2F0ZVRpdGxlVG9XaWR0aChsb25nKTtcbiAqIGNvbnNvbGUubG9nKGdldFRpdGxlV2lkdGgodHJ1bmNhdGVkKSk7IC8vIDw9IDQwXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRydW5jYXRlVGl0bGVUb1dpZHRoKFxuICB0aXRsZTogc3RyaW5nLFxuICBtYXhXaWR0aDogbnVtYmVyID0gWEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSFxuKTogc3RyaW5nIHtcbiAgaWYgKGdldFRpdGxlV2lkdGgodGl0bGUpIDw9IG1heFdpZHRoKSB7XG4gICAgcmV0dXJuIHRpdGxlO1xuICB9XG5cbiAgbGV0IHRydW5jYXRlZCA9ICcnO1xuICBsZXQgY3VycmVudFdpZHRoID0gMDtcblxuICBmb3IgKGNvbnN0IGNoYXIgb2YgdGl0bGUpIHtcbiAgICBjb25zdCBjaGFyV2lkdGggPSBzdHJpbmdXaWR0aChjaGFyKTtcblxuICAgIGlmIChjdXJyZW50V2lkdGggKyBjaGFyV2lkdGggPiBtYXhXaWR0aCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgdHJ1bmNhdGVkICs9IGNoYXI7XG4gICAgY3VycmVudFdpZHRoICs9IGNoYXJXaWR0aDtcbiAgfVxuXG4gIHJldHVybiB0cnVuY2F0ZWQ7XG59XG5cbi8qKlxuICogR2V0IGh1bWFuLXJlYWRhYmxlIHdpZHRoIGJyZWFrZG93blxuICogVXNlZnVsIGZvciBkZWJ1Z2dpbmcgYW5kIHVzZXIgZmVlZGJhY2tcbiAqXG4gKiBAcGFyYW0gdGl0bGUgLSBUaGUgdGl0bGUgdG8gYW5hbHl6ZVxuICogQHJldHVybnMgV2lkdGggYnJlYWtkb3duIGluZm9ybWF0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUaXRsZVdpZHRoQnJlYWtkb3duKHRpdGxlOiBzdHJpbmcpOiB7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIHRvdGFsV2lkdGg6IG51bWJlcjtcbiAgdG90YWxDaGFyczogbnVtYmVyO1xuICBtYXhXaWR0aDogbnVtYmVyO1xuICByZW1haW5pbmc6IG51bWJlcjtcbiAgdmFsaWQ6IGJvb2xlYW47XG4gIGJyZWFrZG93bjogQXJyYXk8e1xuICAgIGNoYXI6IHN0cmluZztcbiAgICB3aWR0aDogbnVtYmVyO1xuICAgIHR5cGU6ICdDSksnIHwgJ0FTQ0lJJyB8ICdFbW9qaScgfCAnT3RoZXInO1xuICB9Pjtcbn0ge1xuICBjb25zdCB0b3RhbFdpZHRoID0gZ2V0VGl0bGVXaWR0aCh0aXRsZSk7XG4gIGNvbnN0IGJyZWFrZG93bjogQXJyYXk8e1xuICAgIGNoYXI6IHN0cmluZztcbiAgICB3aWR0aDogbnVtYmVyO1xuICAgIHR5cGU6ICdDSksnIHwgJ0FTQ0lJJyB8ICdFbW9qaScgfCAnT3RoZXInO1xuICB9PiA9IFtdO1xuXG4gIGZvciAoY29uc3QgY2hhciBvZiB0aXRsZSkge1xuICAgIGNvbnN0IGNoYXJXaWR0aCA9IHN0cmluZ1dpZHRoKGNoYXIpO1xuICAgIGxldCB0eXBlOiAnQ0pLJyB8ICdBU0NJSScgfCAnRW1vamknIHwgJ090aGVyJyA9ICdPdGhlcic7XG5cbiAgICBjb25zdCBjb2RlID0gY2hhci5jaGFyQ29kZUF0KDApO1xuICAgIGlmIChjaGFyLm1hdGNoKC9bXFx1NGUwMC1cXHU5ZmZmXFx1MzQwMC1cXHU0ZGJmXFx1ZjkwMC1cXHVmYWZmXS8pKSB7XG4gICAgICB0eXBlID0gJ0NKSyc7XG4gICAgfSBlbHNlIGlmIChjb2RlIDwgMTI4KSB7XG4gICAgICB0eXBlID0gJ0FTQ0lJJztcbiAgICB9IGVsc2UgaWYgKGNoYXIubWF0Y2goL1tcXHV7MUYzMDB9LVxcdXsxRjlGRn1dL3UpKSB7XG4gICAgICB0eXBlID0gJ0Vtb2ppJztcbiAgICB9XG5cbiAgICBicmVha2Rvd24ucHVzaCh7IGNoYXIsIHdpZHRoOiBjaGFyV2lkdGgsIHR5cGUgfSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHRpdGxlLFxuICAgIHRvdGFsV2lkdGgsXG4gICAgdG90YWxDaGFyczogdGl0bGUubGVuZ3RoLFxuICAgIG1heFdpZHRoOiBYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRILFxuICAgIHJlbWFpbmluZzogY2FsY3VsYXRlUmVtYWluaW5nVGl0bGVXaWR0aCh0aXRsZSksXG4gICAgdmFsaWQ6IHRvdGFsV2lkdGggPD0gWEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSCxcbiAgICBicmVha2Rvd24sXG4gIH07XG59XG4iLCJjb25zdCBfX1dFQlBBQ0tfTkFNRVNQQUNFX09CSkVDVF9fID0gcmVxdWlyZShcImNyeXB0b1wiKTsiLCJjb25zdCBfX1dFQlBBQ0tfTkFNRVNQQUNFX09CSkVDVF9fID0gcmVxdWlyZShcIm5vZGUtZmV0Y2hcIik7IiwiLyoqXG4gKiBJbWFnZSBkb3dubG9hZGVyIHV0aWxpdHkgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKiBTdXBwb3J0cyBkb3dubG9hZGluZyBpbWFnZXMgZnJvbSBIVFRQL0hUVFBTIFVSTHNcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IGV4aXN0c1N5bmMsIG1rZGlyU3luYywgd3JpdGVGaWxlU3luYywgc3RhdFN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgZmV0Y2ggZnJvbSAnbm9kZS1mZXRjaCc7XG5pbXBvcnQgeyBJbnZhbGlkSW1hZ2VFcnJvciB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcblxuZXhwb3J0IGludGVyZmFjZSBEb3dubG9hZFJlc3VsdCB7XG4gIG9yaWdpbmFsVXJsOiBzdHJpbmc7XG4gIGxvY2FsUGF0aDogc3RyaW5nO1xuICBjYWNoZWQ6IGJvb2xlYW47XG4gIGZpbGVTaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBJbWFnZURvd25sb2FkZXIge1xuICBwcml2YXRlIHNhdmVEaXI6IHN0cmluZztcbiAgcHJpdmF0ZSB0aW1lb3V0OiBudW1iZXI7XG4gIHByaXZhdGUgbWF4RmlsZVNpemU6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzYXZlRGlyOiBzdHJpbmcgPSAnLi90ZW1wX2ltYWdlcycsXG4gICAgdGltZW91dDogbnVtYmVyID0gMzAwMDAsXG4gICAgbWF4RmlsZVNpemU6IG51bWJlciA9IDEwICogMTAyNCAqIDEwMjQgLy8gMTBNQiBkZWZhdWx0XG4gICkge1xuICAgIHRoaXMuc2F2ZURpciA9IHNhdmVEaXI7XG4gICAgdGhpcy50aW1lb3V0ID0gdGltZW91dDtcbiAgICB0aGlzLm1heEZpbGVTaXplID0gbWF4RmlsZVNpemU7XG5cbiAgICAvLyBFbnN1cmUgc2F2ZSBkaXJlY3RvcnkgZXhpc3RzXG4gICAgaWYgKCFleGlzdHNTeW5jKHRoaXMuc2F2ZURpcikpIHtcbiAgICAgIG1rZGlyU3luYyh0aGlzLnNhdmVEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIHN0cmluZyBpcyBhIHZhbGlkIEhUVFAvSFRUUFMgVVJMXG4gICAqL1xuICBzdGF0aWMgaXNJbWFnZVVybChwYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoIXBhdGgpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBsb3dlclBhdGggPSBwYXRoLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xuICAgIHJldHVybiBsb3dlclBhdGguc3RhcnRzV2l0aCgnaHR0cDovLycpIHx8IGxvd2VyUGF0aC5zdGFydHNXaXRoKCdodHRwczovLycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGEgdW5pcXVlIGZpbGVuYW1lIGZvciBhbiBpbWFnZSBVUkxcbiAgICogVXNlcyBvbmx5IFVSTCBoYXNoIGZvciBjb25zaXN0ZW50IGNhY2hpbmdcbiAgICovXG4gIHByaXZhdGUgZ2VuZXJhdGVGaWxlTmFtZShpbWFnZVVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAvLyBVc2UgU0hBMjU2IGhhc2ggb2YgVVJMIGZvciB1bmlxdWVuZXNzXG4gICAgY29uc3QgaGFzaCA9IGNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShpbWFnZVVybCkuZGlnZXN0KCdoZXgnKTtcbiAgICBjb25zdCBzaG9ydEhhc2ggPSBoYXNoLnN1YnN0cmluZygwLCAxNik7XG5cbiAgICAvLyBUcnkgdG8gZXh0cmFjdCBleHRlbnNpb24gZnJvbSBVUkxcbiAgICBsZXQgZXh0ZW5zaW9uID0gJ2pwZyc7IC8vIGRlZmF1bHRcbiAgICB0cnkge1xuICAgICAgY29uc3QgdXJsID0gbmV3IFVSTChpbWFnZVVybCk7XG4gICAgICBjb25zdCBwYXRobmFtZSA9IHVybC5wYXRobmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgY29uc3QgbWF0Y2ggPSBwYXRobmFtZS5tYXRjaCgvXFwuKGpwZ3xqcGVnfHBuZ3xnaWZ8d2VicHxibXApJC9pKTtcbiAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICBleHRlbnNpb24gPSBtYXRjaFsxXTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFVzZSBkZWZhdWx0IGV4dGVuc2lvblxuICAgIH1cblxuICAgIC8vIEZpeGVkIGZpbGVuYW1lIGZvciBwcm9wZXIgY2FjaGluZyAobm8gdGltZXN0YW1wKVxuICAgIHJldHVybiBgaW1nXyR7c2hvcnRIYXNofS4ke2V4dGVuc2lvbn1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHRoYXQgZG93bmxvYWRlZCBkYXRhIGlzIGFjdHVhbGx5IGFuIGltYWdlXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlSW1hZ2VEYXRhKGJ1ZmZlcjogQnVmZmVyKTogeyBpc1ZhbGlkOiBib29sZWFuOyBleHRlbnNpb246IHN0cmluZyB9IHtcbiAgICAvLyBDaGVjayBmaWxlIHNpZ25hdHVyZXMgKG1hZ2ljIG51bWJlcnMpXG4gICAgaWYgKGJ1ZmZlci5sZW5ndGggPCAxMikge1xuICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIGV4dGVuc2lvbjogJycgfTtcbiAgICB9XG5cbiAgICAvLyBKUEVHXG4gICAgaWYgKGJ1ZmZlclswXSA9PT0gMHhmZiAmJiBidWZmZXJbMV0gPT09IDB4ZDggJiYgYnVmZmVyWzJdID09PSAweGZmKSB7XG4gICAgICByZXR1cm4geyBpc1ZhbGlkOiB0cnVlLCBleHRlbnNpb246ICdqcGcnIH07XG4gICAgfVxuXG4gICAgLy8gUE5HXG4gICAgaWYgKGJ1ZmZlclswXSA9PT0gMHg4OSAmJiBidWZmZXJbMV0gPT09IDB4NTAgJiYgYnVmZmVyWzJdID09PSAweDRlICYmIGJ1ZmZlclszXSA9PT0gMHg0Nykge1xuICAgICAgcmV0dXJuIHsgaXNWYWxpZDogdHJ1ZSwgZXh0ZW5zaW9uOiAncG5nJyB9O1xuICAgIH1cblxuICAgIC8vIEdJRlxuICAgIGlmIChidWZmZXJbMF0gPT09IDB4NDcgJiYgYnVmZmVyWzFdID09PSAweDQ5ICYmIGJ1ZmZlclsyXSA9PT0gMHg0Nikge1xuICAgICAgcmV0dXJuIHsgaXNWYWxpZDogdHJ1ZSwgZXh0ZW5zaW9uOiAnZ2lmJyB9O1xuICAgIH1cblxuICAgIC8vIFdlYlBcbiAgICBpZiAoXG4gICAgICBidWZmZXJbMF0gPT09IDB4NTIgJiZcbiAgICAgIGJ1ZmZlclsxXSA9PT0gMHg0OSAmJlxuICAgICAgYnVmZmVyWzJdID09PSAweDQ2ICYmXG4gICAgICBidWZmZXJbM10gPT09IDB4NDYgJiZcbiAgICAgIGJ1ZmZlcls4XSA9PT0gMHg1NyAmJlxuICAgICAgYnVmZmVyWzldID09PSAweDQ1ICYmXG4gICAgICBidWZmZXJbMTBdID09PSAweDQyICYmXG4gICAgICBidWZmZXJbMTFdID09PSAweDUwXG4gICAgKSB7XG4gICAgICByZXR1cm4geyBpc1ZhbGlkOiB0cnVlLCBleHRlbnNpb246ICd3ZWJwJyB9O1xuICAgIH1cblxuICAgIC8vIEJNUFxuICAgIGlmIChidWZmZXJbMF0gPT09IDB4NDIgJiYgYnVmZmVyWzFdID09PSAweDRkKSB7XG4gICAgICByZXR1cm4geyBpc1ZhbGlkOiB0cnVlLCBleHRlbnNpb246ICdibXAnIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIGV4dGVuc2lvbjogJycgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEb3dubG9hZCBhIHNpbmdsZSBpbWFnZSBmcm9tIFVSTFxuICAgKi9cbiAgYXN5bmMgZG93bmxvYWRJbWFnZShpbWFnZVVybDogc3RyaW5nKTogUHJvbWlzZTxEb3dubG9hZFJlc3VsdD4ge1xuICAgIC8vIFZhbGlkYXRlIFVSTCBmb3JtYXRcbiAgICBpZiAoIUltYWdlRG93bmxvYWRlci5pc0ltYWdlVXJsKGltYWdlVXJsKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKGBJbnZhbGlkIGltYWdlIFVSTCBmb3JtYXQ6ICR7aW1hZ2VVcmx9YCwge1xuICAgICAgICB1cmw6IGltYWdlVXJsLFxuICAgICAgICBzdWdnZXN0aW9uOiAnVVJMIG11c3Qgc3RhcnQgd2l0aCBodHRwOi8vIG9yIGh0dHBzOi8vJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEdlbmVyYXRlIGZpbGVuYW1lIGFuZCBwYXRoXG4gICAgY29uc3QgZmlsZU5hbWUgPSB0aGlzLmdlbmVyYXRlRmlsZU5hbWUoaW1hZ2VVcmwpO1xuICAgIGNvbnN0IGxvY2FsUGF0aCA9IGpvaW4odGhpcy5zYXZlRGlyLCBmaWxlTmFtZSk7XG5cbiAgICAvLyBDaGVjayBpZiBmaWxlIGFscmVhZHkgZXhpc3RzIChjYWNoZSlcbiAgICBpZiAoZXhpc3RzU3luYyhsb2NhbFBhdGgpKSB7XG4gICAgICBjb25zdCBzdGF0cyA9IHN0YXRTeW5jKGxvY2FsUGF0aCk7XG4gICAgICBsb2dnZXIuZGVidWcoYFVzaW5nIGNhY2hlZCBpbWFnZTogJHtsb2NhbFBhdGh9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvcmlnaW5hbFVybDogaW1hZ2VVcmwsXG4gICAgICAgIGxvY2FsUGF0aCxcbiAgICAgICAgY2FjaGVkOiB0cnVlLFxuICAgICAgICBmaWxlU2l6ZTogc3RhdHMuc2l6ZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgbG9nZ2VyLmRlYnVnKGBEb3dubG9hZGluZyBpbWFnZSBmcm9tOiAke2ltYWdlVXJsfWApO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIERvd25sb2FkIGltYWdlIHdpdGggdGltZW91dFxuICAgICAgY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICAgIGNvbnN0IHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4gY29udHJvbGxlci5hYm9ydCgpLCB0aGlzLnRpbWVvdXQpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGltYWdlVXJsLCB7XG4gICAgICAgIHNpZ25hbDogY29udHJvbGxlci5zaWduYWwsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAnVXNlci1BZ2VudCc6ICdNb3ppbGxhLzUuMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMF8xNV83KSBBcHBsZVdlYktpdC81MzcuMzYnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihcbiAgICAgICAgICBgRmFpbGVkIHRvIGRvd25sb2FkIGltYWdlOiBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfSAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1cmw6IGltYWdlVXJsLFxuICAgICAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICAgICAgc3RhdHVzVGV4dDogcmVzcG9uc2Uuc3RhdHVzVGV4dCxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIENvbnRlbnQtTGVuZ3RoIGlmIGF2YWlsYWJsZVxuICAgICAgY29uc3QgY29udGVudExlbmd0aCA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdjb250ZW50LWxlbmd0aCcpO1xuICAgICAgaWYgKGNvbnRlbnRMZW5ndGggJiYgcGFyc2VJbnQoY29udGVudExlbmd0aCkgPiB0aGlzLm1heEZpbGVTaXplKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihcbiAgICAgICAgICBgSW1hZ2UgZmlsZSB0b28gbGFyZ2U6ICR7KHBhcnNlSW50KGNvbnRlbnRMZW5ndGgpIC8gMTAyNCAvIDEwMjQpLnRvRml4ZWQoXG4gICAgICAgICAgICAyXG4gICAgICAgICAgKX1NQiAobWF4OiAkeyh0aGlzLm1heEZpbGVTaXplIC8gMTAyNCAvIDEwMjQpLnRvRml4ZWQoMil9TUIpYCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1cmw6IGltYWdlVXJsLFxuICAgICAgICAgICAgZmlsZVNpemU6IHBhcnNlSW50KGNvbnRlbnRMZW5ndGgpLFxuICAgICAgICAgICAgbWF4U2l6ZTogdGhpcy5tYXhGaWxlU2l6ZSxcbiAgICAgICAgICAgIHN1Z2dlc3Rpb246ICdUcnkgdXNpbmcgYSBzbWFsbGVyIGltYWdlIG9yIGluY3JlYXNlIG1heEZpbGVTaXplJyxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIEdldCBpbWFnZSBkYXRhXG4gICAgICBjb25zdCBhcnJheUJ1ZmZlciA9IGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCk7XG4gICAgICBjb25zdCBidWZmZXIgPSBCdWZmZXIuZnJvbShhcnJheUJ1ZmZlcik7XG5cbiAgICAgIC8vIFZlcmlmeSBhY3R1YWwgc2l6ZVxuICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPiB0aGlzLm1heEZpbGVTaXplKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihcbiAgICAgICAgICBgRG93bmxvYWRlZCBmaWxlIHRvbyBsYXJnZTogJHsoYnVmZmVyLmxlbmd0aCAvIDEwMjQgLyAxMDI0KS50b0ZpeGVkKDIpfU1CIChtYXg6ICR7KFxuICAgICAgICAgICAgdGhpcy5tYXhGaWxlU2l6ZSAvXG4gICAgICAgICAgICAxMDI0IC9cbiAgICAgICAgICAgIDEwMjRcbiAgICAgICAgICApLnRvRml4ZWQoMil9TUIpYCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1cmw6IGltYWdlVXJsLFxuICAgICAgICAgICAgZmlsZVNpemU6IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICAgICBtYXhTaXplOiB0aGlzLm1heEZpbGVTaXplLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gVmFsaWRhdGUgaXQncyBhY3R1YWxseSBhbiBpbWFnZVxuICAgICAgY29uc3QgdmFsaWRhdGlvbiA9IHRoaXMudmFsaWRhdGVJbWFnZURhdGEoYnVmZmVyKTtcbiAgICAgIGlmICghdmFsaWRhdGlvbi5pc1ZhbGlkKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihgRG93bmxvYWRlZCBmaWxlIGlzIG5vdCBhIHZhbGlkIGltYWdlOiAke2ltYWdlVXJsfWAsIHtcbiAgICAgICAgICB1cmw6IGltYWdlVXJsLFxuICAgICAgICAgIHN1Z2dlc3Rpb246ICdNYWtlIHN1cmUgdGhlIFVSTCBwb2ludHMgdG8gYW4gYWN0dWFsIGltYWdlIGZpbGUnLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gU2F2ZSB0byBmaWxlXG4gICAgICB3cml0ZUZpbGVTeW5jKGxvY2FsUGF0aCwgYnVmZmVyKTtcblxuICAgICAgbG9nZ2VyLmRlYnVnKGBJbWFnZSBkb3dubG9hZGVkIHN1Y2Nlc3NmdWxseTogJHtsb2NhbFBhdGh9ICgke2J1ZmZlci5sZW5ndGh9IGJ5dGVzKWApO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBvcmlnaW5hbFVybDogaW1hZ2VVcmwsXG4gICAgICAgIGxvY2FsUGF0aCxcbiAgICAgICAgY2FjaGVkOiBmYWxzZSxcbiAgICAgICAgZmlsZVNpemU6IGJ1ZmZlci5sZW5ndGgsXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBJbnZhbGlkSW1hZ2VFcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgLy8gSGFuZGxlIGFib3J0IGVycm9yXG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5uYW1lID09PSAnQWJvcnRFcnJvcicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKFxuICAgICAgICAgIGBJbWFnZSBkb3dubG9hZCB0aW1lb3V0IGFmdGVyICR7dGhpcy50aW1lb3V0fW1zOiAke2ltYWdlVXJsfWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgICAgIHRpbWVvdXQ6IHRoaXMudGltZW91dCxcbiAgICAgICAgICAgIHN1Z2dlc3Rpb246ICdUaGUgaW1hZ2UgbWF5IGJlIHRvbyBsYXJnZSBvciB0aGUgbmV0d29yayBpcyBzbG93JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVycm9yXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBkb3dubG9hZCBpbWFnZTogJHtpbWFnZVVybH1gLFxuICAgICAgICB7XG4gICAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3IgYXMgRXJyb3JcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERvd25sb2FkIG11bHRpcGxlIGltYWdlcyBmcm9tIFVSTHMgKHBhcmFsbGVsIGRvd25sb2FkIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UpXG4gICAqL1xuICBhc3luYyBkb3dubG9hZEltYWdlcyhpbWFnZVVybHM6IHN0cmluZ1tdKTogUHJvbWlzZTxEb3dubG9hZFJlc3VsdFtdPiB7XG4gICAgLy8gRG93bmxvYWQgYWxsIGltYWdlcyBpbiBwYXJhbGxlbFxuICAgIGNvbnN0IGRvd25sb2FkUHJvbWlzZXMgPSBpbWFnZVVybHMubWFwKCh1cmwpID0+XG4gICAgICB0aGlzLmRvd25sb2FkSW1hZ2UodXJsKS5jYXRjaCgoZXJyb3IpID0+ICh7IGVycm9yLCB1cmwgfSkpXG4gICAgKTtcblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChkb3dubG9hZFByb21pc2VzKTtcblxuICAgIGNvbnN0IHN1Y2Nlc3NSZXN1bHRzOiBEb3dubG9hZFJlc3VsdFtdID0gW107XG4gICAgY29uc3QgZXJyb3JzOiBBcnJheTx7IHVybDogc3RyaW5nOyBlcnJvcjogRXJyb3IgfT4gPSBbXTtcblxuICAgIHJlc3VsdHMuZm9yRWFjaCgocmVzdWx0KSA9PiB7XG4gICAgICBpZiAoJ2Vycm9yJyBpbiByZXN1bHQpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goeyB1cmw6IHJlc3VsdC51cmwsIGVycm9yOiByZXN1bHQuZXJyb3IgYXMgRXJyb3IgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdWNjZXNzUmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBJZiBhbnkgZG93bmxvYWRzIGZhaWxlZCwgdGhyb3cgYW4gZXJyb3Igd2l0aCBkZXRhaWxzXG4gICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBlcnJvck1lc3NhZ2VzID0gZXJyb3JzLm1hcCgoZSkgPT4gYCR7ZS51cmx9OiAke2UuZXJyb3IubWVzc2FnZX1gKS5qb2luKCdcXG4nKTtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBkb3dubG9hZCAke2Vycm9ycy5sZW5ndGh9IG9mICR7aW1hZ2VVcmxzLmxlbmd0aH0gaW1hZ2VzOlxcbiR7ZXJyb3JNZXNzYWdlc31gLFxuICAgICAgICB7XG4gICAgICAgICAgdG90YWxDb3VudDogaW1hZ2VVcmxzLmxlbmd0aCxcbiAgICAgICAgICBmYWlsZWRDb3VudDogZXJyb3JzLmxlbmd0aCxcbiAgICAgICAgICBzdWNjZXNzQ291bnQ6IHN1Y2Nlc3NSZXN1bHRzLmxlbmd0aCxcbiAgICAgICAgICBmYWlsZWRVcmxzOiBlcnJvcnMubWFwKChlKSA9PiBlLnVybCksXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN1Y2Nlc3NSZXN1bHRzO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2Nlc3MgYSBsaXN0IG9mIGltYWdlIHBhdGhzIC0gZG93bmxvYWQgVVJMcyBhbmQga2VlcCBsb2NhbCBwYXRocyBhcy1pc1xuICAgKi9cbiAgYXN5bmMgcHJvY2Vzc0ltYWdlUGF0aHMoaW1hZ2VQYXRoczogc3RyaW5nW10pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgbG9jYWxQYXRoczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCB1cmxzVG9Eb3dubG9hZDogc3RyaW5nW10gPSBbXTtcblxuICAgIC8vIFNlcGFyYXRlIFVSTHMgZnJvbSBsb2NhbCBwYXRoc1xuICAgIGZvciAoY29uc3QgcGF0aCBvZiBpbWFnZVBhdGhzKSB7XG4gICAgICBpZiAoSW1hZ2VEb3dubG9hZGVyLmlzSW1hZ2VVcmwocGF0aCkpIHtcbiAgICAgICAgdXJsc1RvRG93bmxvYWQucHVzaChwYXRoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIGxvY2FsIHBhdGggZXhpc3RzXG4gICAgICAgIGlmICghZXhpc3RzU3luYyhwYXRoKSkge1xuICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihgTG9jYWwgaW1hZ2UgZmlsZSBub3QgZm91bmQ6ICR7cGF0aH1gLCB7XG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgc3VnZ2VzdGlvbjogJ01ha2Ugc3VyZSB0aGUgZmlsZSBwYXRoIGlzIGNvcnJlY3QgYW5kIHRoZSBmaWxlIGV4aXN0cycsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgbG9jYWxQYXRocy5wdXNoKHBhdGgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIERvd25sb2FkIFVSTHMgaWYgYW55XG4gICAgaWYgKHVybHNUb0Rvd25sb2FkLmxlbmd0aCA+IDApIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgRG93bmxvYWRpbmcgJHt1cmxzVG9Eb3dubG9hZC5sZW5ndGh9IGltYWdlcyBmcm9tIFVSTHMuLi5gKTtcbiAgICAgIGNvbnN0IGRvd25sb2FkUmVzdWx0cyA9IGF3YWl0IHRoaXMuZG93bmxvYWRJbWFnZXModXJsc1RvRG93bmxvYWQpO1xuICAgICAgY29uc3QgZG93bmxvYWRlZFBhdGhzID0gZG93bmxvYWRSZXN1bHRzLm1hcCgocikgPT4gci5sb2NhbFBhdGgpO1xuICAgICAgbG9jYWxQYXRocy5wdXNoKC4uLmRvd25sb2FkZWRQYXRocyk7XG5cbiAgICAgIC8vIExvZyBkb3dubG9hZCBzdW1tYXJ5XG4gICAgICBjb25zdCBjYWNoZWRDb3VudCA9IGRvd25sb2FkUmVzdWx0cy5maWx0ZXIoKHIpID0+IHIuY2FjaGVkKS5sZW5ndGg7XG4gICAgICBjb25zdCBuZXdDb3VudCA9IGRvd25sb2FkUmVzdWx0cy5maWx0ZXIoKHIpID0+ICFyLmNhY2hlZCkubGVuZ3RoO1xuICAgICAgbG9nZ2VyLmRlYnVnKGBEb3dubG9hZGVkICR7bmV3Q291bnR9IG5ldyBpbWFnZXMsIHVzZWQgJHtjYWNoZWRDb3VudH0gY2FjaGVkIGltYWdlc2ApO1xuICAgIH1cblxuICAgIGlmIChsb2NhbFBhdGhzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKCdObyB2YWxpZCBpbWFnZXMgZm91bmQnLCB7XG4gICAgICAgIHByb3ZpZGVkUGF0aHM6IGltYWdlUGF0aHMubGVuZ3RoLFxuICAgICAgICBzdWdnZXN0aW9uOiAnUHJvdmlkZSBhdCBsZWFzdCBvbmUgdmFsaWQgaW1hZ2UgVVJMIG9yIGxvY2FsIGZpbGUgcGF0aCcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbG9jYWxQYXRocztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHNhdmUgZGlyZWN0b3J5IHBhdGhcbiAgICovXG4gIGdldFNhdmVEaXIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5zYXZlRGlyO1xuICB9XG59XG5cbi8vIEV4cG9ydCBhIGRlZmF1bHQgaW5zdGFuY2VcbmxldCBkZWZhdWx0RG93bmxvYWRlcjogSW1hZ2VEb3dubG9hZGVyIHwgbnVsbCA9IG51bGw7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRJbWFnZURvd25sb2FkZXIoc2F2ZURpcj86IHN0cmluZyk6IEltYWdlRG93bmxvYWRlciB7XG4gIGlmICghZGVmYXVsdERvd25sb2FkZXIgfHwgKHNhdmVEaXIgJiYgZGVmYXVsdERvd25sb2FkZXIuZ2V0U2F2ZURpcigpICE9PSBzYXZlRGlyKSkge1xuICAgIGRlZmF1bHREb3dubG9hZGVyID0gbmV3IEltYWdlRG93bmxvYWRlcihzYXZlRGlyKTtcbiAgfVxuICByZXR1cm4gZGVmYXVsdERvd25sb2FkZXI7XG59XG4iLCIvKipcbiAqIFB1Ymxpc2hpbmcgc2VydmljZSBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG5pbXBvcnQgeyBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IENvbmZpZywgUHVibGlzaFJlc3VsdCB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBQdWJsaXNoRXJyb3IsIEludmFsaWRJbWFnZUVycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBCYXNlU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9iYXNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgZXhpc3RzU3luYywgc3RhdFN5bmMsIHdyaXRlRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvbG9nZ2VyJztcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7IEltYWdlRG93bmxvYWRlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9pbWFnZS1kb3dubG9hZGVyJztcbmltcG9ydCB7IGFzc2VydFRpdGxlV2lkdGhWYWxpZCwgZ2V0VGl0bGVXaWR0aCB9IGZyb20gJy4uLy4uL3NoYXJlZC90aXRsZS12YWxpZGF0b3InO1xuaW1wb3J0IHsgQ09NTU9OX1NUQVRVU19TRUxFQ1RPUlMsIENPTU1PTl9URVhUX1BBVFRFUk5TLCBDT01NT05fRklMRV9TRUxFQ1RPUlMgfSBmcm9tICcuLi8uLi9zaGFyZWQvc2VsZWN0b3JzJztcblxuLy8gQ29uc3RhbnRzIGZvciB2aWRlbyBwdWJsaXNoaW5nXG5leHBvcnQgY29uc3QgVklERU9fVElNRU9VVFMgPSB7XG4gIFBBR0VfTE9BRDogMzAwMCxcbiAgVEFCX1NXSVRDSDogMjAwMCxcbiAgVklERU9fUFJPQ0VTU0lORzogMTAwMDAsXG4gIENPTlRFTlRfV0FJVDogMTAwMCxcbiAgVVBMT0FEX1JFQURZOiAxMDAwLFxuICBVUExPQURfU1RBUlQ6IDMwMDAsXG4gIFBST0NFU1NJTkdfQ0hFQ0s6IDMwMDAsXG4gIENPTVBMRVRJT05fQ0hFQ0s6IDIwMDAsXG4gIFBST0NFU1NJTkdfVElNRU9VVDogMTIwMDAwLCAvLyAyIG1pbnV0ZXNcbiAgQ09NUExFVElPTl9USU1FT1VUOiAzMDAwMDAsIC8vIDUgbWludXRlc1xufSBhcyBjb25zdDtcblxuZXhwb3J0IGNvbnN0IFNFTEVDVE9SUyA9IHtcbiAgRklMRV9JTlBVVDogQ09NTU9OX0ZJTEVfU0VMRUNUT1JTLkZJTEVfSU5QVVQsXG4gIFNVQ0NFU1NfSU5ESUNBVE9SUzogQ09NTU9OX1NUQVRVU19TRUxFQ1RPUlMuU1VDQ0VTUyxcbiAgRVJST1JfSU5ESUNBVE9SUzogQ09NTU9OX1NUQVRVU19TRUxFQ1RPUlMuRVJST1IsXG4gIFBST0NFU1NJTkdfSU5ESUNBVE9SUzogQ09NTU9OX1NUQVRVU19TRUxFQ1RPUlMuUFJPQ0VTU0lORyxcbiAgQ09NUExFVElPTl9JTkRJQ0FUT1JTOiBbXG4gICAgJy51cGxvYWQtY29tcGxldGUnLFxuICAgICcucHJvY2Vzc2luZy1jb21wbGV0ZScsXG4gICAgJy52aWRlby1yZWFkeScsXG4gICAgJ1tjbGFzcyo9XCJjb21wbGV0ZVwiXScsXG4gICAgJ1tjbGFzcyo9XCJyZWFkeVwiXScsXG4gIF0sXG4gIFRPQVNUX1NFTEVDVE9SUzogQ09NTU9OX1NUQVRVU19TRUxFQ1RPUlMuVE9BU1QsXG4gIFBVQkxJU0hfUEFHRV9JTkRJQ0FUT1JTOiBbXG4gICAgJ2Rpdi51cGxvYWQtY29udGVudCcsXG4gICAgJ2Rpdi5zdWJtaXQnLFxuICAgICcuY3JlYXRvci1lZGl0b3InLFxuICAgICcudmlkZW8tdXBsb2FkLWNvbnRhaW5lcicsXG4gICAgJ2lucHV0W3R5cGU9XCJmaWxlXCJdJyxcbiAgXSxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBURVhUX1BBVFRFUk5TID0gQ09NTU9OX1RFWFRfUEFUVEVSTlM7XG5cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFB1Ymxpc2hCYXNlU2VydmljZSBleHRlbmRzIEJhc2VTZXJ2aWNlIHtcbiAgcHJvdGVjdGVkIGltYWdlRG93bmxvYWRlcjogSW1hZ2VEb3dubG9hZGVyO1xuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnKSB7XG4gICAgc3VwZXIoY29uZmlnKTtcbiAgICB0aGlzLmltYWdlRG93bmxvYWRlciA9IG5ldyBJbWFnZURvd25sb2FkZXIoJy4vdGVtcF9pbWFnZXMnKTtcbiAgfVxuXG4gIC8vIEhlbHBlciBtZXRob2RzIGZvciBlbGVtZW50IGRldGVjdGlvbiBhbmQgdGV4dCBtYXRjaGluZ1xuICBwcm90ZWN0ZWQgYXN5bmMgZmluZEVsZW1lbnRCeVNlbGVjdG9ycyhcbiAgICBwYWdlOiBQYWdlLFxuICAgIHNlbGVjdG9yczogcmVhZG9ubHkgc3RyaW5nW11cbiAgKTogUHJvbWlzZTxhbnkgfCBudWxsPiB7XG4gICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBGb3VuZCBlbGVtZW50IHdpdGggc2VsZWN0b3I6ICR7c2VsZWN0b3J9YCk7XG4gICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBnZXRFbGVtZW50VGV4dChlbGVtZW50OiBFbGVtZW50KTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCAoZWxlbWVudCBhcyBhbnkpLnBhZ2UoKS5ldmFsdWF0ZSgoZWw6IEVsZW1lbnQpID0+IGVsLnRleHRDb250ZW50LCBlbGVtZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBnZXQgZWxlbWVudCB0ZXh0OiAke2Vycm9yfWApO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGNoZWNrVGV4dFBhdHRlcm5zKFxuICAgIHRleHQ6IHN0cmluZyB8IG51bGwsXG4gICAgcGF0dGVybnM6IHJlYWRvbmx5IHN0cmluZ1tdXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICghdGV4dCkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBwYXR0ZXJucy5zb21lKChwYXR0ZXJuKSA9PiB0ZXh0LmluY2x1ZGVzKHBhdHRlcm4pKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBjaGVja0VsZW1lbnRGb3JQYXR0ZXJucyhcbiAgICBwYWdlOiBQYWdlLFxuICAgIHNlbGVjdG9yczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgcGF0dGVybnM6IHJlYWRvbmx5IHN0cmluZ1tdXG4gICk6IFByb21pc2U8eyBmb3VuZDogYm9vbGVhbjsgdGV4dD86IHN0cmluZzsgZWxlbWVudD86IGFueSB9PiB7XG4gICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IHRoaXMuZ2V0RWxlbWVudFRleHQoZWxlbWVudCBhcyB1bmtub3duIGFzIEVsZW1lbnQpO1xuICAgICAgICBpZiAodGV4dCAmJiAoYXdhaXQgdGhpcy5jaGVja1RleHRQYXR0ZXJucyh0ZXh0LCBwYXR0ZXJucykpKSB7XG4gICAgICAgICAgcmV0dXJuIHsgZm91bmQ6IHRydWUsIHRleHQsIGVsZW1lbnQgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyBmb3VuZDogZmFsc2UgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB3YWl0Rm9yQ29uZGl0aW9uKFxuICAgIGNvbmRpdGlvbjogKCkgPT4gUHJvbWlzZTxib29sZWFuPixcbiAgICB0aW1lb3V0OiBudW1iZXIsXG4gICAgY2hlY2tJbnRlcnZhbDogbnVtYmVyID0gMTAwMCxcbiAgICBlcnJvck1lc3NhZ2U6IHN0cmluZ1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPCB0aW1lb3V0KSB7XG4gICAgICBpZiAoYXdhaXQgY29uZGl0aW9uKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYXdhaXQgc2xlZXAoY2hlY2tJbnRlcnZhbCk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihlcnJvck1lc3NhZ2UpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGZpbGxUaXRsZShwYWdlOiBQYWdlLCB0aXRsZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdGl0bGVTZWxlY3RvcnMgPSBbXG4gICAgICAnaW5wdXRbcGxhY2Vob2xkZXIqPVwi5qCH6aKYXCJdJyxcbiAgICAgICdpbnB1dFtwbGFjZWhvbGRlcio9XCJ0aXRsZVwiXScsXG4gICAgICAnaW5wdXRbZGF0YS1wbGFjZWhvbGRlcio9XCLmoIfpophcIl0nLFxuICAgICAgJy50aXRsZS1pbnB1dCBpbnB1dCcsXG4gICAgICAnaW5wdXRbdHlwZT1cInRleHRcIl0nLFxuICAgICAgJ2lucHV0W3BsYWNlaG9sZGVyKj1cIuivt+i+k+WFpeagh+mimFwiXScsXG4gICAgICAnaW5wdXRbcGxhY2Vob2xkZXIqPVwi5qCH6aKYXCJdJyxcbiAgICAgICdpbnB1dFtuYW1lPVwidGl0bGVcIl0nLFxuICAgICAgJ2lucHV0W2lkKj1cInRpdGxlXCJdJyxcbiAgICAgICdpbnB1dFtjbGFzcyo9XCJ0aXRsZVwiXScsXG4gICAgICAnZGl2W2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0nLFxuICAgICAgJ3RleHRhcmVhW3BsYWNlaG9sZGVyKj1cIuagh+mimFwiXScsXG4gICAgICAndGV4dGFyZWFbcGxhY2Vob2xkZXIqPVwidGl0bGVcIl0nLFxuICAgIF07XG5cbiAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHRpdGxlU2VsZWN0b3JzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0aXRsZUlucHV0ID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKHRpdGxlSW5wdXQpIHtcbiAgICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCB0aXRsZUlucHV0LmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcblxuICAgICAgICAgIGlmIChpc1Zpc2libGUpIHtcbiAgICAgICAgICAgIGF3YWl0IHRpdGxlSW5wdXQuY2xpY2soKTtcbiAgICAgICAgICAgIGF3YWl0IHNsZWVwKDUwMCk7IC8vIFdhaXQgZm9yIGZvY3VzXG4gICAgICAgICAgICBhd2FpdCB0aXRsZUlucHV0LnR5cGUodGl0bGUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gQ29udGludWUgdG8gbmV4dCBzZWxlY3RvclxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIG5vIGlucHV0IGZvdW5kLCB0cnkgdG8gZmluZCBhbnkgaW5wdXQgb3IgdGV4dGFyZWEgb24gdGhlIHBhZ2VcbiAgICB0cnkge1xuICAgICAgY29uc3QgYWxsSW5wdXRzID0gYXdhaXQgcGFnZS4kJCgnaW5wdXQsIHRleHRhcmVhLCBbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXScpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFsbElucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBpbnB1dCA9IGFsbElucHV0c1tpXTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCBpbnB1dC5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG4gICAgICAgICAgY29uc3QgdGFnTmFtZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC50YWdOYW1lLCBpbnB1dCk7XG5cbiAgICAgICAgICBpZiAoaXNWaXNpYmxlICYmICh0YWdOYW1lID09PSAnSU5QVVQnIHx8IHRhZ05hbWUgPT09ICdURVhUQVJFQScpKSB7XG4gICAgICAgICAgICBhd2FpdCBpbnB1dC5jbGljaygpO1xuICAgICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcbiAgICAgICAgICAgIGF3YWl0IGlucHV0LnR5cGUodGl0bGUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAvLyBDb250aW51ZSB0byBuZXh0IGlucHV0XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gRmFsbCB0aHJvdWdoIHRvIGVycm9yXG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignQ291bGQgbm90IGZpbmQgdGl0bGUgaW5wdXQgZmllbGQnKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBmaW5kQ29udGVudEVsZW1lbnQocGFnZTogUGFnZSk6IFByb21pc2U8YW55IHwgbnVsbD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBTdHJhdGVneSAxOiBUcnkgZGl2W2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0gKHNpbXBsZSBhbmQgZGlyZWN0KVxuICAgICAgY29uc3QgY29udGVudEVkaXRhYmxlID0gYXdhaXQgcGFnZS4kKCdkaXZbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXScpO1xuICAgICAgaWYgKGNvbnRlbnRFZGl0YWJsZSkge1xuICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCBjb250ZW50RWRpdGFibGUuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuICAgICAgICBpZiAoaXNWaXNpYmxlKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbnRlbnRFZGl0YWJsZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSAyOiBUcnkgZGl2LnRpcHRhcC5Qcm9zZU1pcnJvciAocHJpbWFyeSBzZWxlY3RvciBmb3IgY3JlYXRvciBwbGF0Zm9ybSlcbiAgICAgIGNvbnN0IHRpcHRhcEVkaXRvciA9IGF3YWl0IHBhZ2UuJCgnZGl2LnRpcHRhcC5Qcm9zZU1pcnJvcicpO1xuICAgICAgaWYgKHRpcHRhcEVkaXRvcikge1xuICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCB0aXB0YXBFZGl0b3IuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuICAgICAgICBpZiAoaXNWaXNpYmxlKSB7XG4gICAgICAgICAgcmV0dXJuIHRpcHRhcEVkaXRvcjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSAzOiBUcnkgZGl2W3JvbGU9XCJ0ZXh0Ym94XCJdW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0gKHNwZWNpZmljIHNlbGVjdG9yKVxuICAgICAgY29uc3Qgcm9sZVRleHRib3ggPSBhd2FpdCBwYWdlLiQoJ2Rpdltyb2xlPVwidGV4dGJveFwiXVtjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdJyk7XG4gICAgICBpZiAocm9sZVRleHRib3gpIHtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgcm9sZVRleHRib3guaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuICAgICAgICBpZiAoaXNWaXNpYmxlKSB7XG4gICAgICAgICAgcmV0dXJuIHJvbGVUZXh0Ym94O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDQ6IFRyeSBkaXYucWwtZWRpdG9yIChsZWdhY3kgc2VsZWN0b3IpXG4gICAgICBjb25zdCBxbEVkaXRvciA9IGF3YWl0IHBhZ2UuJCgnZGl2LnFsLWVkaXRvcicpO1xuICAgICAgaWYgKHFsRWRpdG9yKSB7XG4gICAgICAgIHJldHVybiBxbEVkaXRvcjtcbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgNTogVHJ5IHRvIGZpbmQgdGV4dGFyZWEgb3IgY29udGVudGVkaXRhYmxlXG4gICAgICBjb25zdCBjb250ZW50U2VsZWN0b3JzID0gW1xuICAgICAgICAnLnRpcHRhcC5Qcm9zZU1pcnJvcicsXG4gICAgICAgICd0ZXh0YXJlYVtwbGFjZWhvbGRlcio9XCLmraPmlodcIl0nLFxuICAgICAgICAndGV4dGFyZWFbbXVsdGlsaW5lXScsXG4gICAgICAgICdkaXZbZGF0YS1wbGFjZWhvbGRlcio9XCLmraPmlodcIl0nLFxuICAgICAgICAnLmNvbnRlbnQtZWRpdG9yJyxcbiAgICAgICAgJ2Rpdltyb2xlPVwidGV4dGJveFwiXScsXG4gICAgICAgICd0ZXh0Ym94W3JvbGU9XCJ0ZXh0Ym94XCJdJyxcbiAgICAgICAgJ3RleHRib3hbbXVsdGlsaW5lXScsXG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIGNvbnRlbnRTZWxlY3RvcnMpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgNjogVHJ5IHRvIGZpbmQgYW55IG11bHRpbGluZSB0ZXh0Ym94IChmYWxsYmFjaylcbiAgICAgIGNvbnN0IG11bHRpbGluZVRleHRib3hlcyA9IGF3YWl0IHBhZ2UuJCQoJ3RleHRib3hbbXVsdGlsaW5lXScpO1xuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIG11bHRpbGluZVRleHRib3hlcykge1xuICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCBlbGVtZW50LmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZmluZFRleHRib3hCeVBsYWNlaG9sZGVyKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPGFueSB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgLy8gRmluZCBhbGwgcCBlbGVtZW50c1xuICAgICAgY29uc3QgcEVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJCgncCcpO1xuXG4gICAgICAvLyBMb29rIGZvciBlbGVtZW50IHdpdGggZGF0YS1wbGFjZWhvbGRlciBjb250YWluaW5nIFwi6L6T5YWl5q2j5paH5o+P6L+wXCJcbiAgICAgIGZvciAoY29uc3QgcCBvZiBwRWxlbWVudHMpIHtcbiAgICAgICAgY29uc3QgcGxhY2Vob2xkZXIgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwuZ2V0QXR0cmlidXRlKCdkYXRhLXBsYWNlaG9sZGVyJyksIHApO1xuICAgICAgICBpZiAocGxhY2Vob2xkZXI/LmluY2x1ZGVzKCfovpPlhaXmraPmlofmj4/ov7AnKSkge1xuICAgICAgICAgIHJldHVybiBwO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZmluZFRleHRib3hQYXJlbnQocGFnZTogUGFnZSwgZWxlbWVudDogRWxlbWVudCk6IFByb21pc2U8YW55PiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBwYWdlLmV2YWx1YXRlSGFuZGxlKChlbCkgPT4gZWwucGFyZW50RWxlbWVudCwgZWxlbWVudCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBmaWxsQ29udGVudChwYWdlOiBQYWdlLCBjb250ZW50OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBXYWl0IGZvciBjb250ZW50IGFyZWEgdG8gYXBwZWFyXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclNlbGVjdG9yKFxuICAgICAgICAnZGl2W3JvbGU9XCJ0ZXh0Ym94XCJdW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0sIC50aXB0YXAuUHJvc2VNaXJyb3IsIGRpdltjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdLCB0ZXh0YXJlYSwgW3JvbGU9XCJ0ZXh0Ym94XCJdLCAucWwtZWRpdG9yLCB0ZXh0Ym94W211bHRpbGluZV0nLFxuICAgICAgICB7IHRpbWVvdXQ6IDEwMDAwIH1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIENvbnRpbnVlIHdpdGhvdXQgd2FpdGluZ1xuICAgIH1cblxuICAgIGxldCBjb250ZW50RWxlbWVudCA9IGF3YWl0IHRoaXMuZmluZENvbnRlbnRFbGVtZW50KHBhZ2UpO1xuXG4gICAgaWYgKCFjb250ZW50RWxlbWVudCkge1xuICAgICAgLy8gVHJ5IGFsdGVybmF0aXZlIGFwcHJvYWNoXG4gICAgICBjb25zdCB0ZXh0Ym94RWxlbWVudCA9IGF3YWl0IHRoaXMuZmluZFRleHRib3hCeVBsYWNlaG9sZGVyKHBhZ2UpO1xuICAgICAgaWYgKHRleHRib3hFbGVtZW50KSB7XG4gICAgICAgIGNvbnRlbnRFbGVtZW50ID0gYXdhaXQgdGhpcy5maW5kVGV4dGJveFBhcmVudChwYWdlLCB0ZXh0Ym94RWxlbWVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjb250ZW50RWxlbWVudCkge1xuICAgICAgLy8gVHJ5IHRvIGZpbmQgYW55IGNvbnRlbnRlZGl0YWJsZSBvciB0ZXh0YXJlYSBlbGVtZW50XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBhbGxDb250ZW50RWxlbWVudHMgPSBhd2FpdCBwYWdlLiQkKFxuICAgICAgICAgICdkaXZbcm9sZT1cInRleHRib3hcIl1bY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSwgLnRpcHRhcC5Qcm9zZU1pcnJvciwgZGl2W2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0sIHRleHRhcmVhLCBbcm9sZT1cInRleHRib3hcIl0sIC5xbC1lZGl0b3IsIHBbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSwgdGV4dGJveFttdWx0aWxpbmVdJ1xuICAgICAgICApO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWxsQ29udGVudEVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgZWxlbWVudCA9IGFsbENvbnRlbnRFbGVtZW50c1tpXTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgZWxlbWVudC5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG4gICAgICAgICAgICBjb25zdCB0YWdOYW1lID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLnRhZ05hbWUsIGVsZW1lbnQpO1xuICAgICAgICAgICAgY29uc3QgY29udGVudEVkaXRhYmxlID0gYXdhaXQgcGFnZS5ldmFsdWF0ZShcbiAgICAgICAgICAgICAgKGVsKSA9PiBlbC5nZXRBdHRyaWJ1dGUoJ2NvbnRlbnRlZGl0YWJsZScpLFxuICAgICAgICAgICAgICBlbGVtZW50XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3Qgcm9sZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC5nZXRBdHRyaWJ1dGUoJ3JvbGUnKSwgZWxlbWVudCk7XG4gICAgICAgICAgICBjb25zdCBjbGFzc05hbWUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwuY2xhc3NOYW1lLCBlbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnN0IG11bHRpbGluZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC5nZXRBdHRyaWJ1dGUoJ211bHRpbGluZScpLCBlbGVtZW50KTtcblxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBpc1Zpc2libGUgJiZcbiAgICAgICAgICAgICAgKGNvbnRlbnRFZGl0YWJsZSA9PT0gJ3RydWUnIHx8XG4gICAgICAgICAgICAgICAgdGFnTmFtZSA9PT0gJ1RFWFRBUkVBJyB8fFxuICAgICAgICAgICAgICAgIHJvbGUgPT09ICd0ZXh0Ym94JyB8fFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZS5pbmNsdWRlcygncWwtZWRpdG9yJykgfHxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUuaW5jbHVkZXMoJ3RpcHRhcCcpIHx8XG4gICAgICAgICAgICAgICAgbXVsdGlsaW5lID09PSAnJylcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBjb250ZW50RWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAvLyBDb250aW51ZSB0byBuZXh0IGVsZW1lbnRcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIENvbnRpbnVlIHRvIG5leHQgc3RyYXRlZ3lcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWNvbnRlbnRFbGVtZW50KSB7XG4gICAgICAvLyBMYXN0IHJlc29ydDogdHJ5IHRvIGZpbmQgYW55IGVsZW1lbnQgdGhhdCBtaWdodCBiZSBmb3IgY29udGVudFxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYWxsRWxlbWVudHMgPSBhd2FpdCBwYWdlLiQkKCcqJyk7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBNYXRoLm1pbihhbGxFbGVtZW50cy5sZW5ndGgsIDUwKTsgaSsrKSB7XG4gICAgICAgICAgLy8gTGltaXQgdG8gZmlyc3QgNTAgZWxlbWVudHNcbiAgICAgICAgICBjb25zdCBlbGVtZW50ID0gYWxsRWxlbWVudHNbaV07XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IGVsZW1lbnQuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuICAgICAgICAgICAgY29uc3QgdGFnTmFtZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC50YWdOYW1lLCBlbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRFZGl0YWJsZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoXG4gICAgICAgICAgICAgIChlbCkgPT4gZWwuZ2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnKSxcbiAgICAgICAgICAgICAgZWxlbWVudFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC5jbGFzc05hbWUsIGVsZW1lbnQpO1xuICAgICAgICAgICAgY29uc3QgcGxhY2Vob2xkZXIgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKFxuICAgICAgICAgICAgICAoZWwpID0+IGVsLmdldEF0dHJpYnV0ZSgncGxhY2Vob2xkZXInKSxcbiAgICAgICAgICAgICAgZWxlbWVudFxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBpc1Zpc2libGUgJiZcbiAgICAgICAgICAgICAgKGNvbnRlbnRFZGl0YWJsZSA9PT0gJ3RydWUnIHx8XG4gICAgICAgICAgICAgICAgdGFnTmFtZSA9PT0gJ1RFWFRBUkVBJyB8fFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZS5pbmNsdWRlcygnY29udGVudCcpIHx8XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lLmluY2x1ZGVzKCdlZGl0b3InKSB8fFxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPy5pbmNsdWRlcygn5YaF5a65JykgfHxcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj8uaW5jbHVkZXMoJ+ato+aWhycpKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBlcnJvcnMgZm9yIGluZGl2aWR1YWwgZWxlbWVudHNcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIEZhbGwgdGhyb3VnaCB0byBlcnJvclxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghY29udGVudEVsZW1lbnQpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIGNvbnRlbnQgaW5wdXQgZmllbGQnKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29udGVudEVsZW1lbnQuY2xpY2soKTtcbiAgICAgIGF3YWl0IHNsZWVwKDUwMCk7IC8vIFdhaXQgZm9yIGZvY3VzXG4gICAgICBhd2FpdCAoY29udGVudEVsZW1lbnQgYXMgYW55KS50eXBlKGNvbnRlbnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBGYWlsZWQgdG8gZmlsbCBjb250ZW50OiAke2Vycm9yfWApO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBpbnB1dFRhZ3MocGFnZTogUGFnZSwgY29udGVudEVsZW1lbnQ6IGFueSwgdGFnczogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdGFnTGlzdCA9IHRhZ3NcbiAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAubWFwKCh0YWcpID0+IHRhZy50cmltKCkpXG4gICAgICAuZmlsdGVyKCh0YWcpID0+IHRhZy5sZW5ndGggPiAwKTtcblxuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ0xpc3QpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW5wdXRUYWcocGFnZSwgY29udGVudEVsZW1lbnQsIHRhZyk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGlucHV0VGFnKHBhZ2U6IFBhZ2UsIGNvbnRlbnRFbGVtZW50OiBhbnksIHRhZzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFR5cGUgdGhlIHRhZ1xuICAgICAgYXdhaXQgY29udGVudEVsZW1lbnQudHlwZShgIyR7dGFnfWApO1xuICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG5cbiAgICAgIC8vIFRyeSB0byBmaW5kIHRvcGljIHN1Z2dlc3Rpb24gY29udGFpbmVyXG4gICAgICBjb25zdCB0b3BpY0NvbnRhaW5lciA9IGF3YWl0IHBhZ2UuJCgnI2NyZWF0b3ItZWRpdG9yLXRvcGljLWNvbnRhaW5lcicpO1xuXG4gICAgICBpZiAodG9waWNDb250YWluZXIpIHtcbiAgICAgICAgY29uc3QgZmlyc3RJdGVtID0gYXdhaXQgdG9waWNDb250YWluZXIuJCgnLml0ZW0nKTtcbiAgICAgICAgaWYgKGZpcnN0SXRlbSkge1xuICAgICAgICAgIGF3YWl0IGZpcnN0SXRlbS5jbGljaygpO1xuICAgICAgICAgIGF3YWl0IHNsZWVwKDUwMCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFByZXNzIEVudGVyIHRvIGNvbmZpcm0gdGhlIHRhZ1xuICAgICAgICBhd2FpdCBjb250ZW50RWxlbWVudC5wcmVzcygnRW50ZXInKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcbiAgICAgICAgLy8gUHJlc3MgU3BhY2UgdG8gc2VwYXJhdGUgdGFnc1xuICAgICAgICBhd2FpdCBjb250ZW50RWxlbWVudC5wcmVzcygnU3BhY2UnKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoMjAwKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBhZGQgdGFnICR7dGFnfTogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgYWRkVGFncyhwYWdlOiBQYWdlLCB0YWdzOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29udGVudEVsZW1lbnQgPSBhd2FpdCB0aGlzLmZpbmRDb250ZW50RWxlbWVudChwYWdlKTtcbiAgICAgIGlmIChjb250ZW50RWxlbWVudCkge1xuICAgICAgICBhd2FpdCB0aGlzLmlucHV0VGFncyhwYWdlLCBjb250ZW50RWxlbWVudCwgdGFncyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gYWRkIHRhZ3M6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHN1Ym1pdFBvc3QocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBGaW5kIHRoZSBzdWJtaXQgYnV0dG9uIGJ5IHRleHQgXCLlj5HluINcIlxuICAgICAgY29uc3QgYnV0dG9ucyA9IGF3YWl0IHBhZ2UuJCQoJ2J1dHRvbicpO1xuICAgICAgbGV0IHN1Ym1pdEJ1dHRvbiA9IG51bGw7XG4gICAgICBmb3IgKGNvbnN0IGJ0biBvZiBidXR0b25zKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCBidG4uZXZhbHVhdGUoZWwgPT4gZWwudGV4dENvbnRlbnQ/LnRyaW0oKSk7XG4gICAgICAgIGlmICh0ZXh0ID09PSAn5Y+R5biDJykge1xuICAgICAgICAgIHN1Ym1pdEJ1dHRvbiA9IGJ0bjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIXN1Ym1pdEJ1dHRvbikge1xuICAgICAgICAvLyBUcnkgc3BhbiBvciBkaXYgYXMgZmFsbGJhY2tcbiAgICAgICAgY29uc3Qgc3VibWl0U2VsZWN0b3IgPSAnZGl2LnN1Ym1pdCwgLnN1Ym1pdC1idG4sIC5wdWJsaXNoLWJ0bic7XG4gICAgICAgIHN1Ym1pdEJ1dHRvbiA9IGF3YWl0IHBhZ2UuJChzdWJtaXRTZWxlY3Rvcik7XG4gICAgICAgIGlmICghc3VibWl0QnV0dG9uKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignQ291bGQgbm90IGZpbmQgc3VibWl0IGJ1dHRvbicpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHN1Ym1pdEJ1dHRvbi5jbGljaygpO1xuICAgICAgbG9nZ2VyLmRlYnVnKCdDbGlja2VkIHN1Ym1pdCBidXR0b24gbmF0aXZlbHknKTtcbiAgICAgIGF3YWl0IHNsZWVwKDIwMDApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBGYWlsZWQgdG8gY2xpY2sgc3VibWl0IGJ1dHRvbjogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaXNFbGVtZW50VmlzaWJsZShlbGVtZW50OiBFbGVtZW50KTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCAoZWxlbWVudCBhcyBhbnkpLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB3YWl0Rm9yUHVibGlzaENvbXBsZXRpb24ocGFnZTogUGFnZSk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGNvbnN0IG1heFdhaXRUaW1lID0gNjAwMDA7IC8vIDYwIHNlY29uZHNcbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPCBtYXhXYWl0VGltZSkge1xuICAgICAgLy8gQ2hlY2sgZm9yIHN1Y2Nlc3MgaW5kaWNhdG9yc1xuICAgICAgY29uc3Qgc3VjY2Vzc0luZGljYXRvcnMgPSBbXG4gICAgICAgICcuc3VjY2Vzcy1tZXNzYWdlJyxcbiAgICAgICAgJy5wdWJsaXNoLXN1Y2Nlc3MnLFxuICAgICAgICAnW2RhdGEtdGVzdGlkPVwicHVibGlzaC1zdWNjZXNzXCJdJyxcbiAgICAgICAgJy50b2FzdC1zdWNjZXNzJyxcbiAgICAgIF07XG5cbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2Ygc3VjY2Vzc0luZGljYXRvcnMpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7IC8vIFdhaXQgYSBiaXQgbW9yZSBmb3IgYW55IGZpbmFsIHByb2Nlc3NpbmdcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5leHRyYWN0Tm90ZUlkRnJvbVBhZ2UocGFnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgZm9yIGVycm9yIGluZGljYXRvcnNcbiAgICAgIGNvbnN0IGVycm9ySW5kaWNhdG9ycyA9IFtcbiAgICAgICAgJy5lcnJvci1tZXNzYWdlJyxcbiAgICAgICAgJy5wdWJsaXNoLWVycm9yJyxcbiAgICAgICAgJ1tkYXRhLXRlc3RpZD1cInB1Ymxpc2gtZXJyb3JcIl0nLFxuICAgICAgICAnLnRvYXN0LWVycm9yJyxcbiAgICAgICAgJy5lcnJvci10b2FzdCcsXG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIGVycm9ySW5kaWNhdG9ycykge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICBjb25zdCBlcnJvclRleHQgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwudGV4dENvbnRlbnQsIGVsZW1lbnQpO1xuICAgICAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYFB1Ymxpc2ggZmFpbGVkIHdpdGggZXJyb3I6ICR7ZXJyb3JUZXh0fWApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGlmIHdlJ3JlIHN0aWxsIG9uIHRoZSBwdWJsaXNoIHBhZ2VcbiAgICAgIGNvbnN0IHB1Ymxpc2hQYWdlSW5kaWNhdG9ycyA9IFsnZGl2LnVwbG9hZC1jb250ZW50JywgJ2Rpdi5zdWJtaXQnLCAnLmNyZWF0b3ItZWRpdG9yJ107XG5cbiAgICAgIGxldCBzdGlsbE9uUHVibGlzaFBhZ2UgPSBmYWxzZTtcbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgcHVibGlzaFBhZ2VJbmRpY2F0b3JzKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgIHN0aWxsT25QdWJsaXNoUGFnZSA9IHRydWU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFzdGlsbE9uUHVibGlzaFBhZ2UpIHtcbiAgICAgICAgLy8gV2UndmUgbGVmdCB0aGUgcHVibGlzaCBwYWdlLCBsaWtlbHkgc3VjY2Vzc2Z1bFxuICAgICAgICBsb2dnZXIuZGVidWcoJ0xlZnQgcHVibGlzaCBwYWdlLCBhc3N1bWluZyBzdWNjZXNzJyk7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmV4dHJhY3ROb3RlSWRGcm9tUGFnZShwYWdlKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgZm9yIHRvYXN0IG1lc3NhZ2VzXG4gICAgICBjb25zdCB0b2FzdFNlbGVjdG9ycyA9IFsnLnRvYXN0JywgJy5tZXNzYWdlJywgJy5ub3RpZmljYXRpb24nLCAnW3JvbGU9XCJhbGVydFwiXSddO1xuXG4gICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHRvYXN0U2VsZWN0b3JzKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgIGNvbnN0IHRvYXN0VGV4dCA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC50ZXh0Q29udGVudCwgZWxlbWVudCk7XG4gICAgICAgICAgaWYgKHRvYXN0VGV4dCkge1xuICAgICAgICAgICAgaWYgKHRvYXN0VGV4dC5pbmNsdWRlcygn5oiQ5YqfJykgfHwgdG9hc3RUZXh0LmluY2x1ZGVzKCdzdWNjZXNzJykpIHtcbiAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBGb3VuZCBzdWNjZXNzIHRvYXN0OiAke3RvYXN0VGV4dH1gKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2UpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgdG9hc3RUZXh0LmluY2x1ZGVzKCflpLHotKUnKSB8fFxuICAgICAgICAgICAgICB0b2FzdFRleHQuaW5jbHVkZXMoJ2Vycm9yJykgfHxcbiAgICAgICAgICAgICAgdG9hc3RUZXh0LmluY2x1ZGVzKCfplJnor68nKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYFB1Ymxpc2ggZmFpbGVkOiAke3RvYXN0VGV4dH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7IC8vIFdhaXQgYmVmb3JlIG5leHQgY2hlY2tcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdQdWJsaXNoIGNvbXBsZXRpb24gdGltZW91dCAtIGNvdWxkIG5vdCBkZXRlcm1pbmUgcmVzdWx0Jyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgLy8gTWV0aG9kIDE6IFRyeSB0byBleHRyYWN0IGZyb20gVVJMIGlmIHJlZGlyZWN0ZWQgdG8gbm90ZSBwYWdlXG4gICAgICBjb25zdCBjdXJyZW50VXJsID0gcGFnZS51cmwoKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQ3VycmVudCBVUkwgYWZ0ZXIgcHVibGlzaDogJHtjdXJyZW50VXJsfWApO1xuXG4gICAgICAvLyBDaGVjayBpZiB3ZSdyZSBvbiBhIG5vdGUgcGFnZSAoVVJMIGNvbnRhaW5zIC9leHBsb3JlLyBvciAvZGlzY292ZXJ5LylcbiAgICAgIGNvbnN0IG5vdGVJZE1hdGNoID0gY3VycmVudFVybC5tYXRjaCgvXFwvZXhwbG9yZVxcLyhbYS1mMC05XSspL2kpIHx8XG4gICAgICAgIGN1cnJlbnRVcmwubWF0Y2goL1xcL2Rpc2NvdmVyeVxcLyhbYS1mMC05XSspL2kpO1xuXG4gICAgICBpZiAobm90ZUlkTWF0Y2ggJiYgbm90ZUlkTWF0Y2hbMV0pIHtcbiAgICAgICAgY29uc3Qgbm90ZUlkID0gbm90ZUlkTWF0Y2hbMV07XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgRXh0cmFjdGVkIG5vdGUgSUQgZnJvbSBVUkw6ICR7bm90ZUlkfWApO1xuICAgICAgICByZXR1cm4gbm90ZUlkO1xuICAgICAgfVxuXG4gICAgICAvLyBNZXRob2QgMjogVHJ5IHRvIGZpbmQgbm90ZSBJRCBpbiBwYWdlIGNvbnRlbnQgb3IgZGF0YSBhdHRyaWJ1dGVzXG4gICAgICBjb25zdCBub3RlSWRGcm9tUGFnZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgICAvLyBMb29rIGZvciBkYXRhIGF0dHJpYnV0ZXMgdGhhdCBtaWdodCBjb250YWluIG5vdGUgSURcbiAgICAgICAgY29uc3QgZWxlbWVudHNXaXRoRGF0YSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLW5vdGUtaWRdLCBbZGF0YS1pZF0sIFtkYXRhLWltcHJlc3Npb25dJyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHNXaXRoRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBlbGVtZW50c1dpdGhEYXRhW2ldO1xuICAgICAgICAgIGNvbnN0IG5vdGVJZCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLW5vdGUtaWQnKSB8fFxuICAgICAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSB8fFxuICAgICAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaW1wcmVzc2lvbicpO1xuICAgICAgICAgIGlmIChub3RlSWQgJiYgbm90ZUlkLmxlbmd0aCA+IDEwKSB7IC8vIE5vdGUgSURzIGFyZSB0eXBpY2FsbHkgbG9uZ1xuICAgICAgICAgICAgcmV0dXJuIG5vdGVJZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMb29rIGZvciBsaW5rcyB0byBub3RlIHBhZ2VzXG4gICAgICAgIGNvbnN0IG5vdGVMaW5rcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2FbaHJlZio9XCIvZXhwbG9yZS9cIl0sIGFbaHJlZio9XCIvZGlzY292ZXJ5L1wiXScpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vdGVMaW5rcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGxpbmsgPSBub3RlTGlua3NbaV07XG4gICAgICAgICAgY29uc3QgaHJlZiA9IGxpbmsuZ2V0QXR0cmlidXRlKCdocmVmJyk7XG4gICAgICAgICAgaWYgKGhyZWYpIHtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gaHJlZi5tYXRjaCgvXFwvZXhwbG9yZVxcLyhbYS1mMC05XSspL2kpIHx8XG4gICAgICAgICAgICAgIGhyZWYubWF0Y2goL1xcL2Rpc2NvdmVyeVxcLyhbYS1mMC05XSspL2kpO1xuICAgICAgICAgICAgaWYgKG1hdGNoICYmIG1hdGNoWzFdKSB7XG4gICAgICAgICAgICAgIHJldHVybiBtYXRjaFsxXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMb29rIGZvciBhbnkgdGV4dCB0aGF0IGxvb2tzIGxpa2UgYSBub3RlIElEIChsb25nIGhleCBzdHJpbmcpXG4gICAgICAgIGNvbnN0IHRleHRDb250ZW50ID0gZG9jdW1lbnQuYm9keS50ZXh0Q29udGVudCB8fCAnJztcbiAgICAgICAgY29uc3Qgbm90ZUlkUGF0dGVybiA9IC9bYS1mMC05XXsyMCx9L2dpO1xuICAgICAgICBjb25zdCBtYXRjaGVzID0gdGV4dENvbnRlbnQubWF0Y2gobm90ZUlkUGF0dGVybik7XG4gICAgICAgIGlmIChtYXRjaGVzICYmIG1hdGNoZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIC8vIFJldHVybiB0aGUgZmlyc3QgbG9uZyBoZXggc3RyaW5nIGZvdW5kXG4gICAgICAgICAgcmV0dXJuIG1hdGNoZXNbMF07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAobm90ZUlkRnJvbVBhZ2UpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBFeHRyYWN0ZWQgbm90ZSBJRCBmcm9tIHBhZ2UgY29udGVudDogJHtub3RlSWRGcm9tUGFnZX1gKTtcbiAgICAgICAgcmV0dXJuIG5vdGVJZEZyb21QYWdlO1xuICAgICAgfVxuXG4gICAgICAvLyBNZXRob2QgMzogVHJ5IHRvIGdldCB0aGUgbGF0ZXN0IG5vdGUgSUQgdXNpbmcgTm90ZVNlcnZpY2UgKGZhbGxiYWNrKVxuICAgICAgbG9nZ2VyLmRlYnVnKCdDb3VsZCBub3QgZXh0cmFjdCBub3RlIElEIGZyb20gcGFnZSwgdHJ5aW5nIGZhbGxiYWNrIG1ldGhvZCcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gV2FpdCBhIGJpdCBmb3IgdGhlIG5vdGUgdG8gYmUgcHJvY2Vzc2VkXG4gICAgICAgIGF3YWl0IHNsZWVwKDUwMDApO1xuXG4gICAgICAgIC8vIFVzZSBOb3RlU2VydmljZSB0byBnZXQgdGhlIGxhdGVzdCBub3RlIElEXG4gICAgICAgIGNvbnN0IHsgTm90ZVNlcnZpY2UgfSA9IGF3YWl0IGltcG9ydCgnLi4vbm90ZXMvbm90ZS5zZXJ2aWNlJyk7XG4gICAgICAgIGNvbnN0IG5vdGVTZXJ2aWNlID0gbmV3IE5vdGVTZXJ2aWNlKHRoaXMuZ2V0Q29uZmlnKCkpO1xuICAgICAgICBjb25zdCB1c2VyTm90ZXMgPSBhd2FpdCBub3RlU2VydmljZS5nZXRVc2VyTm90ZXMoMSk7IC8vIEdldCBvbmx5IHRoZSBsYXRlc3Qgbm90ZVxuXG4gICAgICAgIGlmICh1c2VyTm90ZXMuc3VjY2VzcyAmJiB1c2VyTm90ZXMuZGF0YSAmJiB1c2VyTm90ZXMuZGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgbGF0ZXN0Tm90ZUlkID0gdXNlck5vdGVzLmRhdGFbMF0uaWQ7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKGBFeHRyYWN0ZWQgbm90ZSBJRCBmcm9tIE5vdGVTZXJ2aWNlOiAke2xhdGVzdE5vdGVJZH1gKTtcbiAgICAgICAgICByZXR1cm4gbGF0ZXN0Tm90ZUlkO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihgRmFsbGJhY2sgbm90ZSBJRCBleHRyYWN0aW9uIGZhaWxlZDogJHtlcnJvcn1gKTtcbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLmRlYnVnKCdDb3VsZCBub3QgZXh0cmFjdCBub3RlIElEIGZyb20gYW55IG1ldGhvZCcpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gZXh0cmFjdCBub3RlIElEOiAke2Vycm9yfWApO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHZhbGlkYXRlQ29udGVudElucHV0cyhcbiAgICB0eXBlOiAnaW1hZ2UnIHwgJ3ZpZGVvJyxcbiAgICB0aXRsZTogc3RyaW5nLFxuICAgIGNvbnRlbnQ6IHN0cmluZyxcbiAgICBtZWRpYVBhdGhzOiBzdHJpbmdbXVxuICApOiB2b2lkIHtcbiAgICBpZiAoIXRpdGxlPy50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYCR7dHlwZSA9PT0gJ2ltYWdlJyA/ICdJbWFnZScgOiAnVmlkZW8nfSB0aXRsZSBjYW5ub3QgYmUgZW1wdHlgKTtcbiAgICB9XG5cbiAgICBpZiAoIWNvbnRlbnQ/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgJHt0eXBlID09PSAnaW1hZ2UnID8gJ0ltYWdlJyA6ICdWaWRlbyd9IGNvbnRlbnQgY2Fubm90IGJlIGVtcHR5YCk7XG4gICAgfVxuXG4gICAgaWYgKCFtZWRpYVBhdGhzIHx8IG1lZGlhUGF0aHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGAke3R5cGUgPT09ICdpbWFnZScgPyAnSW1hZ2UnIDogJ1ZpZGVvJ30gcGF0aHMgYXJlIHJlcXVpcmVkYCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICdpbWFnZScgJiYgbWVkaWFQYXRocy5sZW5ndGggPiAxOCkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignTWF4aW11bSAxOCBpbWFnZXMgYWxsb3dlZCBmb3IgaW1hZ2UgcG9zdHMnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZSA9PT0gJ3ZpZGVvJyAmJiBtZWRpYVBhdGhzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignVmlkZW8gcHVibGlzaGluZyByZXF1aXJlcyBleGFjdGx5IG9uZSB2aWRlbyBmaWxlJyk7XG4gICAgfVxuICB9XG59IiwiaW1wb3J0IHsgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkLCBnZXRUaXRsZVdpZHRoIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3RpdGxlLXZhbGlkYXRvcic7XG5pbXBvcnQgeyBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IFB1Ymxpc2hSZXN1bHQgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgUHVibGlzaEVycm9yLCBJbnZhbGlkSW1hZ2VFcnJvciB9IGZyb20gJy4uLy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2xvZ2dlcic7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBleGlzdHNTeW5jLCBzdGF0U3luYywgd3JpdGVGaWxlU3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IFB1Ymxpc2hCYXNlU2VydmljZSB9IGZyb20gJy4vcHVibGlzaC1iYXNlLnNlcnZpY2UnO1xuXG5leHBvcnQgY2xhc3MgSW1hZ2VQdWJsaXNoU2VydmljZSBleHRlbmRzIFB1Ymxpc2hCYXNlU2VydmljZSB7XG4gIGFzeW5jIHB1Ymxpc2hOb3RlKFxuICAgIHRpdGxlOiBzdHJpbmcsXG4gICAgY29udGVudDogc3RyaW5nLFxuICAgIGltYWdlUGF0aHM6IHN0cmluZ1tdLFxuICAgIHRhZ3M6IHN0cmluZyA9ICcnLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8UHVibGlzaFJlc3VsdD4ge1xuICAgIC8vIFZhbGlkYXRlIGlucHV0c1xuICAgIGlmICghdGl0bGU/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignTm90ZSB0aXRsZSBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSB0aXRsZSB3aWR0aCAoQ0pLIGNoYXJhY3RlcnMgY291bnQgYXMgMiB1bml0cywgQVNDSUkgYXMgMSlcbiAgICBhc3NlcnRUaXRsZVdpZHRoVmFsaWQodGl0bGUpO1xuICAgIGxvZ2dlci5kZWJ1ZyhgVGl0bGUgd2lkdGggdmFsaWRhdGlvbiBwYXNzZWQ6IFwiJHt0aXRsZX1cIiAoJHtnZXRUaXRsZVdpZHRoKHRpdGxlKX0gdW5pdHMpYCk7XG5cbiAgICBpZiAoIWNvbnRlbnQ/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignTm90ZSBjb250ZW50IGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cblxuICAgIGlmICghaW1hZ2VQYXRocyB8fCBpbWFnZVBhdGhzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignQXQgbGVhc3Qgb25lIGltYWdlIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgLy8gUHJvY2VzcyBpbWFnZSBwYXRocyAtIGRvd25sb2FkIFVSTHMgYW5kIHZhbGlkYXRlIGxvY2FsIHBhdGhzXG4gICAgY29uc3QgcmVzb2x2ZWRQYXRocyA9IGF3YWl0IHRoaXMudmFsaWRhdGVBbmRSZXNvbHZlSW1hZ2VQYXRocyhpbWFnZVBhdGhzKTtcblxuICAgIC8vIFdhaXQgZm9yIHVwbG9hZCBjb250YWluZXIgc2VsZWN0b3JcbiAgICBjb25zdCB1cGxvYWRTZWxlY3RvciA9ICdkaXYudXBsb2FkLWNvbnRlbnQnO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZShmYWxzZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkubmF2aWdhdGVXaXRoUmV0cnkoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICB0aGlzLmdldENvbmZpZygpLnhocy5jcmVhdG9yUHVibGlzaFVybFxuICAgICAgICApO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIHBhZ2UgdG8gbG9hZFxuICAgICAgICBhd2FpdCBzbGVlcCgzMDAwKTtcblxuICAgICAgICAvLyBGaXJzdCwgdHJ5IHRvIHN3aXRjaCB0byB0aGUgaW1hZ2UvdGV4dCB1cGxvYWQgdGFiXG4gICAgICAgIGF3YWl0IHRoaXMuY2xpY2tVcGxvYWRUYWIocGFnZSk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgdGFiIHN3aXRjaCB0byBjb21wbGV0ZVxuICAgICAgICBhd2FpdCBzbGVlcCgzMDAwKTtcblxuICAgICAgICAvLyBDaGVjayBpZiB0YWIgc3dpdGNoIHdhcyBzdWNjZXNzZnVsIGFuZCByZXRyeSBpZiBuZWVkZWRcbiAgICAgICAgY29uc3QgcGFnZVN0YXRlID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGJ1dHRvblRleHRzOiBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2J1dHRvbiwgZGl2W3JvbGU9XCJidXR0b25cIl0nKSlcbiAgICAgICAgICAgICAgLm1hcCgoZWw6IEVsZW1lbnQpID0+IGVsLnRleHRDb250ZW50Py50cmltKCkpXG4gICAgICAgICAgICAgIC5maWx0ZXIoKHQ6IHN0cmluZyB8IHVuZGVmaW5lZCkgPT4gdCksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSWYgc3RpbGwgc2hvd2luZyB2aWRlbyB1cGxvYWQsIHRyeSBjbGlja2luZyB0aGUgdGFiIGFnYWluXG4gICAgICAgIGlmIChcbiAgICAgICAgICBwYWdlU3RhdGUuYnV0dG9uVGV4dHMuaW5jbHVkZXMoJ+S4iuS8oOinhumikScpICYmXG4gICAgICAgICAgIXBhZ2VTdGF0ZS5idXR0b25UZXh0cy5pbmNsdWRlcygn5LiK5Lyg5Zu+5paHJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5jbGlja1VwbG9hZFRhYihwYWdlKTtcbiAgICAgICAgICBhd2FpdCBzbGVlcCgzMDAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBoYXNVcGxvYWRDb250YWluZXIgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkudHJ5V2FpdEZvclNlbGVjdG9yKFxuICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgdXBsb2FkU2VsZWN0b3IsXG4gICAgICAgICAgMzAwMDBcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoIWhhc1VwbG9hZENvbnRhaW5lcikge1xuICAgICAgICAgIC8vIFRyeSBhbHRlcm5hdGl2ZSBzZWxlY3RvcnMgZm9yIHVwbG9hZCBjb250YWluZXJcbiAgICAgICAgICBjb25zdCBhbHRlcm5hdGl2ZVNlbGVjdG9ycyA9IFtcbiAgICAgICAgICAgICdkaXYudXBsb2FkLWNvbnRlbnQnLFxuICAgICAgICAgICAgJy51cGxvYWQtY29udGVudCcsXG4gICAgICAgICAgICAnZGl2W2NsYXNzKj1cInVwbG9hZFwiXScsXG4gICAgICAgICAgICAnZGl2W2NsYXNzKj1cImltYWdlXCJdJyxcbiAgICAgICAgICAgICdpbnB1dFt0eXBlPVwiZmlsZVwiXScsXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgYWx0ZXJuYXRpdmVTZWxlY3RvcnMpIHtcbiAgICAgICAgICAgIGhhc1VwbG9hZENvbnRhaW5lciA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS50cnlXYWl0Rm9yU2VsZWN0b3IoXG4gICAgICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgICAgIHNlbGVjdG9yLFxuICAgICAgICAgICAgICAxMDAwMFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChoYXNVcGxvYWRDb250YWluZXIpIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFoYXNVcGxvYWRDb250YWluZXIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdDb3VsZCBub3QgZmluZCB1cGxvYWQgY29udGFpbmVyIG9uIHB1Ymxpc2ggcGFnZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXBsb2FkIGltYWdlc1xuICAgICAgICBhd2FpdCB0aGlzLnVwbG9hZEltYWdlcyhwYWdlLCByZXNvbHZlZFBhdGhzKTtcblxuICAgICAgICAvLyBXYWl0IGZvciBpbWFnZXMgdG8gYmUgcHJvY2Vzc2VkIChsYXJnZSBmaWxlcyBuZWVkIG1vcmUgdGltZSBvbiBYSFMpXG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnV2FpdGluZyAxNSBzZWNvbmRzIGZvciBpbWFnZXMgdG8gYmUgdXBsb2FkZWQgYW5kIHByb2Nlc3NlZC4uLicpO1xuICAgICAgICBhd2FpdCBzbGVlcCgxNTAwMCk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgcGFnZSB0byB0cmFuc2l0aW9uIHRvIGVkaXQgbW9kZSAoY2hlY2sgZm9yIHRpdGxlIG9yIGNvbnRlbnQgaW5wdXQpXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgcGFnZS53YWl0Rm9yU2VsZWN0b3IoXG4gICAgICAgICAgICAnaW5wdXRbcGxhY2Vob2xkZXIqPVwi5qCH6aKYXCJdLCBkaXZbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSwgLnRpcHRhcC5Qcm9zZU1pcnJvcicsXG4gICAgICAgICAgICB7IHRpbWVvdXQ6IDE1MDAwIH1cbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIC8vIENvbnRpbnVlIHdpdGhvdXQgd2FpdGluZ1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gV2FpdCBhIGJpdCBmb3IgdGhlIHBhZ2UgdG8gc2V0dGxlIGFmdGVyIGltYWdlIHVwbG9hZFxuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcblxuICAgICAgICAvLyBGaWxsIGluIHRpdGxlXG4gICAgICAgIGF3YWl0IHRoaXMuZmlsbFRpdGxlKHBhZ2UsIHRpdGxlKTtcblxuICAgICAgICAvLyBXYWl0IGEgYml0IG1vcmUgZm9yIGNvbnRlbnQgYXJlYSB0byBhcHBlYXJcbiAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7XG5cbiAgICAgICAgLy8gRmlsbCBpbiBjb250ZW50XG4gICAgICAgIGF3YWl0IHRoaXMuZmlsbENvbnRlbnQocGFnZSwgY29udGVudCk7XG5cbiAgICAgICAgLy8gQWRkIHRhZ3MgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRhZ3MpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmFkZFRhZ3MocGFnZSwgdGFncyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTdWJtaXQgdGhlIG5vdGVcbiAgICAgICAgYXdhaXQgdGhpcy5zdWJtaXRQb3N0KHBhZ2UpO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIGNvbXBsZXRpb24gYW5kIGNoZWNrIHJlc3VsdFxuICAgICAgICBjb25zdCBub3RlSWQgPSBhd2FpdCB0aGlzLndhaXRGb3JQdWJsaXNoQ29tcGxldGlvbihwYWdlKTtcblxuICAgICAgICAvLyBTYXZlIGNvb2tpZXNcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLnNhdmVDb29raWVzRnJvbVBhZ2UocGFnZSk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIG1lc3NhZ2U6ICdOb3RlIHB1Ymxpc2hlZCBzdWNjZXNzZnVsbHknLFxuICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgIGNvbnRlbnQsXG4gICAgICAgICAgaW1hZ2VDb3VudDogcmVzb2x2ZWRQYXRocy5sZW5ndGgsXG4gICAgICAgICAgdGFncyxcbiAgICAgICAgICB1cmw6IHRoaXMuZ2V0Q29uZmlnKCkueGhzLmNyZWF0b3JQdWJsaXNoVXJsLFxuICAgICAgICAgIG5vdGVJZDogbm90ZUlkIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgfTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBQdWJsaXNoIGVycm9yOiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFByb2Nlc3MgaW1hZ2UgcGF0aHMgLSBkb3dubG9hZCBVUkxzIGFuZCB2YWxpZGF0ZSBsb2NhbCBwYXRoc1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB2YWxpZGF0ZUFuZFJlc29sdmVJbWFnZVBhdGhzKGltYWdlUGF0aHM6IHN0cmluZ1tdKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIC8vIFVzZSBJbWFnZURvd25sb2FkZXIgdG8gcHJvY2VzcyBwYXRocyAoZG93bmxvYWRzIFVSTHMsIHZhbGlkYXRlcyBsb2NhbCBwYXRocylcbiAgICBjb25zdCByZXNvbHZlZFBhdGhzID0gYXdhaXQgdGhpcy5pbWFnZURvd25sb2FkZXIucHJvY2Vzc0ltYWdlUGF0aHMoaW1hZ2VQYXRocyk7XG5cbiAgICAvLyBWYWxpZGF0ZSByZXNvbHZlZCBwYXRoc1xuICAgIGZvciAoY29uc3QgcmVzb2x2ZWRQYXRoIG9mIHJlc29sdmVkUGF0aHMpIHtcbiAgICAgIC8vIEZvciBsb2NhbCBwYXRocyB0aGF0IGFyZW4ndCBhYnNvbHV0ZSwgcmVzb2x2ZSB0aGVtXG4gICAgICBjb25zdCBmdWxsUGF0aCA9XG4gICAgICAgIHJlc29sdmVkUGF0aC5zdGFydHNXaXRoKCcvJykgfHwgcmVzb2x2ZWRQYXRoLm1hdGNoKC9eW2EtekEtWl06LylcbiAgICAgICAgICA/IHJlc29sdmVkUGF0aFxuICAgICAgICAgIDogam9pbihwcm9jZXNzLmN3ZCgpLCByZXNvbHZlZFBhdGgpO1xuXG4gICAgICBpZiAoIWV4aXN0c1N5bmMoZnVsbFBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihgSW1hZ2UgZmlsZSBub3QgZm91bmQ6ICR7cmVzb2x2ZWRQYXRofWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdGF0cyA9IHN0YXRTeW5jKGZ1bGxQYXRoKTtcbiAgICAgIGlmICghc3RhdHMuaXNGaWxlKCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKGBQYXRoIGlzIG5vdCBhIGZpbGU6ICR7cmVzb2x2ZWRQYXRofWApO1xuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBmaWxlIGV4dGVuc2lvblxuICAgICAgY29uc3QgZXh0ID0gcmVzb2x2ZWRQYXRoLnRvTG93ZXJDYXNlKCkuc3BsaXQoJy4nKS5wb3AoKTtcbiAgICAgIGNvbnN0IGFsbG93ZWRFeHRlbnNpb25zID0gWydqcGcnLCAnanBlZycsICdwbmcnLCAnZ2lmJywgJ3dlYnAnLCAnYm1wJ107XG4gICAgICBpZiAoIWV4dCB8fCAhYWxsb3dlZEV4dGVuc2lvbnMuaW5jbHVkZXMoZXh0KSkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgICAgYFVuc3VwcG9ydGVkIGltYWdlIGZvcm1hdDogJHtyZXNvbHZlZFBhdGh9LiBTdXBwb3J0ZWQ6ICR7YWxsb3dlZEV4dGVuc2lvbnMuam9pbignLCAnKX1gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHJlc29sdmVkUGF0aHMubGVuZ3RoID4gMTgpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ01heGltdW0gMTggaW1hZ2VzIGFsbG93ZWQnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzb2x2ZWRQYXRocztcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2xpY2tVcGxvYWRUYWIocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBsb2dnZXIuZGVidWcoJ0F0dGVtcHRpbmcgdG8gc3dpdGNoIHRvIFwi5LiK5Lyg5Zu+5paHXCIgdGFiIHVzaW5nIFB1cHBldGVlciBvdXRlciBuYXRpdmUgY2xpY2snKTtcblxuICAgICAgLy8gV2FpdCBmb3IgdGFicyB0byByZW5kZXJcbiAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclNlbGVjdG9yKCcuY3JlYXRvci10YWInLCB7IHRpbWVvdXQ6IDEwMDAwIH0pO1xuXG4gICAgICBjb25zdCB0YWJzID0gYXdhaXQgcGFnZS4kJCgnLmNyZWF0b3ItdGFiJyk7XG4gICAgICBsZXQgY2xpY2tlZCA9IGZhbHNlO1xuXG4gICAgICBmb3IgKGNvbnN0IHRhYiBvZiB0YWJzKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCB0YWIuZXZhbHVhdGUoZWwgPT4gZWwudGV4dENvbnRlbnQpO1xuICAgICAgICBpZiAodGV4dCAmJiAodGV4dC5pbmNsdWRlcygn5LiK5Lyg5Zu+5paHJykgfHwgdGV4dC5pbmNsdWRlcygn5Zu+5paHJykpKSB7XG5cbiAgICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCB0YWIuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuICAgICAgICAgIGlmICghaXNWaXNpYmxlKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ0ZvdW5kIGEgbWF0Y2hpbmcgdGFiLCBidXQgaXQgaXMgbm90IHZpc2libGUgaW4gdGhlIHZpZXdwb3J0LiBTa2lwcGluZy4uLicpO1xuICAgICAgICAgICAgY29udGludWU7IC8vIFNraXAgaGlkZGVuIGVsZW1lbnRzXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gVHJ5IG5hdGl2ZSBjbGljayBmaXJzdFxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCAodGFiIGFzIGFueSkuY2xpY2soeyBkZWxheTogMTUwIH0pO1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdOYXRpdmUgUHVwcGV0ZWVyIGNsaWNrIHN1Y2NlZWRlZCBvbiB0YWIuJyk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBQdXBwZXRlZXIgbmF0aXZlIGNsaWNrIGZhaWxlZCBvbiB2aXNpYmxlIHRhYjogJHtlfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBhd2FpdCBzbGVlcCg1MDApO1xuXG4gICAgICAgICAgLy8gRm9yY2UgYSBzZWNvbmRhcnkgY2xpY2sgb24gdGhlIHRleHQgaXRzZWxmIHZpYSBldmFsdWF0ZSBqdXN0IGluIGNhc2UgaGl0IGFyZWEgbWlzc2VkXG4gICAgICAgICAgYXdhaXQgdGFiLmV2YWx1YXRlKChlbCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3BhbiA9IGVsLnF1ZXJ5U2VsZWN0b3IoJ3NwYW4nKSB8fCBlbDtcbiAgICAgICAgICAgIChzcGFuIGFzIEhUTUxFbGVtZW50KS5jbGljaygpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY2xpY2tlZCA9IHRydWU7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdTdWNjZXNzZnVsbHkgY2xpY2tlZCBpbWFnZSB0YWIgdGV4dCBtYXRjaC4nKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWNsaWNrZWQpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0NvdWxkIG5vdCBmaW5kIHZpc2libGUgaW1hZ2UgdGFiIHZpYSB0ZXh0dWFsIG1hdGNoaW5nLicpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBjbGljayB1cGxvYWQgdGFiOiAke2Vycm9yfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBsb2FkSW1hZ2VzKHBhZ2U6IFBhZ2UsIGltYWdlUGF0aHM6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnVXBsb2FkaW5nIGltYWdlcyB1c2luZyBkaXJlY3QgaW5wdXQgZWxlbWVudCB0YXJnZXRpbmcnKTtcblxuICAgICAgY29uc3QgZmlsZUlucHV0ID0gYXdhaXQgcGFnZS4kKCdpbnB1dFt0eXBlPVwiZmlsZVwiXScpO1xuICAgICAgaWYgKCFmaWxlSW5wdXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignQ291bGQgbm90IGZpbmQgZmlsZSB1cGxvYWQgaW5wdXQgb24gcGFnZScpO1xuICAgICAgfVxuXG4gICAgICAvLyBFbnN1cmUgdGhlIGlucHV0IGFjY2VwdHMgbXVsdGlwbGUgZmlsZXMgYW5kIGFueSB0eXBlIHRvIGF2b2lkIGZyb250ZW5kIGJsb2Nrc1xuICAgICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWw6IEVsZW1lbnQgfCBudWxsKSA9PiB7XG4gICAgICAgIGlmIChlbCkge1xuICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnbXVsdGlwbGUnLCAnbXVsdGlwbGUnKTtcbiAgICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2FjY2VwdCcpO1xuICAgICAgICB9XG4gICAgICB9LCBmaWxlSW5wdXQpO1xuXG4gICAgICBsb2dnZXIuZGVidWcoYFN1Ym1pdHRpbmcgJHtpbWFnZVBhdGhzLmxlbmd0aH0gaW1hZ2UgcGF0aHMgdG8gZmlsZSBpbnB1dCBlbGVtZW50YCk7XG4gICAgICBhd2FpdCBmaWxlSW5wdXQudXBsb2FkRmlsZSguLi5pbWFnZVBhdGhzKTtcblxuICAgICAgLy8gRGlzcGF0Y2ggYSBjaGFuZ2UgZXZlbnQgbWFudWFsbHkgaW4gY2FzZSB0aGUgZnJhbWV3b3JrIG1pc3NlZCBpdFxuICAgICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWw6IEVsZW1lbnQgfCBudWxsKSA9PiB7XG4gICAgICAgIGlmIChlbCkge1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdjaGFuZ2UnLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgICB9XG4gICAgICB9LCBmaWxlSW5wdXQpO1xuXG4gICAgICBhd2FpdCBzbGVlcCgxNTAwMCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYEZhaWxlZCB0byB1cGxvYWQgaW1hZ2VzOiAke2Vycm9yfWApO1xuICAgIH1cbiAgfVxuXG59XG4iLCJpbXBvcnQgeyBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IGFzc2VydFRpdGxlV2lkdGhWYWxpZCwgZ2V0VGl0bGVXaWR0aCB9IGZyb20gJy4uLy4uL3NoYXJlZC90aXRsZS12YWxpZGF0b3InO1xuaW1wb3J0IHsgU0VMRUNUT1JTLCBURVhUX1BBVFRFUk5TLCBWSURFT19USU1FT1VUUyB9IGZyb20gJy4vcHVibGlzaC1iYXNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgUHVibGlzaFJlc3VsdCB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBQdWJsaXNoRXJyb3IgfSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgZXhpc3RzU3luYywgc3RhdFN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBQdWJsaXNoQmFzZVNlcnZpY2UgfSBmcm9tICcuL3B1Ymxpc2gtYmFzZS5zZXJ2aWNlJztcblxuZXhwb3J0IGNsYXNzIFZpZGVvUHVibGlzaFNlcnZpY2UgZXh0ZW5kcyBQdWJsaXNoQmFzZVNlcnZpY2Uge1xuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JWaWRlb1B1Ymxpc2hDb21wbGV0aW9uKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICBsb2dnZXIuZGVidWcoJ1dhaXRpbmcgZm9yIHZpZGVvIHB1Ymxpc2ggY29tcGxldGlvbi4uLicpO1xuXG4gICAgbGV0IGlzUHJvY2Vzc2luZyA9IGZhbHNlO1xuXG4gICAgYXdhaXQgdGhpcy53YWl0Rm9yQ29uZGl0aW9uKFxuICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBDaGVjayBmb3Igc3VjY2VzcyBpbmRpY2F0b3JzXG4gICAgICAgIGNvbnN0IHN1Y2Nlc3NSZXN1bHQgPSBhd2FpdCB0aGlzLmNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgU0VMRUNUT1JTLlNVQ0NFU1NfSU5ESUNBVE9SUyxcbiAgICAgICAgICBURVhUX1BBVFRFUk5TLlNVQ0NFU1NcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoc3VjY2Vzc1Jlc3VsdC5mb3VuZCkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgc3VjY2VzcyBpbmRpY2F0b3I6ICR7c3VjY2Vzc1Jlc3VsdC50ZXh0fWApO1xuICAgICAgICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLkNPTVBMRVRJT05fQ0hFQ0spO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIGVycm9yIGluZGljYXRvcnNcbiAgICAgICAgY29uc3QgZXJyb3JSZXN1bHQgPSBhd2FpdCB0aGlzLmNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgU0VMRUNUT1JTLkVSUk9SX0lORElDQVRPUlMsXG4gICAgICAgICAgVEVYVF9QQVRURVJOUy5FUlJPUlxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChlcnJvclJlc3VsdC5mb3VuZCkge1xuICAgICAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYFZpZGVvIHB1Ymxpc2ggZmFpbGVkIHdpdGggZXJyb3I6ICR7ZXJyb3JSZXN1bHQudGV4dH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGlmIHdlJ3ZlIGxlZnQgdGhlIHB1Ymxpc2ggcGFnZSAobGlrZWx5IHN1Y2Nlc3MpXG4gICAgICAgIGNvbnN0IHN0aWxsT25QYWdlID0gYXdhaXQgdGhpcy5maW5kRWxlbWVudEJ5U2VsZWN0b3JzKFxuICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgU0VMRUNUT1JTLlBVQkxJU0hfUEFHRV9JTkRJQ0FUT1JTXG4gICAgICAgICk7XG4gICAgICAgIGlmICghc3RpbGxPblBhZ2UpIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ0xlZnQgcHVibGlzaCBwYWdlLCBhc3N1bWluZyB2aWRlbyBwdWJsaXNoIHN1Y2Nlc3MnKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGZvciBwcm9jZXNzaW5nIHN0YXR1c1xuICAgICAgICBjb25zdCBwcm9jZXNzaW5nUmVzdWx0ID0gYXdhaXQgdGhpcy5jaGVja0VsZW1lbnRGb3JQYXR0ZXJucyhcbiAgICAgICAgICBwYWdlLFxuICAgICAgICAgIFNFTEVDVE9SUy5QUk9DRVNTSU5HX0lORElDQVRPUlMsXG4gICAgICAgICAgVEVYVF9QQVRURVJOUy5QUk9DRVNTSU5HXG4gICAgICAgICk7XG5cbiAgICAgICAgaXNQcm9jZXNzaW5nID0gcHJvY2Vzc2luZ1Jlc3VsdC5mb3VuZDtcbiAgICAgICAgaWYgKGlzUHJvY2Vzc2luZykge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgVmlkZW8gc3RpbGwgcHJvY2Vzc2luZzogJHtwcm9jZXNzaW5nUmVzdWx0LnRleHR9YCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBmb3IgdG9hc3QgbWVzc2FnZXNcbiAgICAgICAgY29uc3QgdG9hc3RSZXN1bHQgPSBhd2FpdCB0aGlzLmNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgU0VMRUNUT1JTLlRPQVNUX1NFTEVDVE9SUyxcbiAgICAgICAgICBURVhUX1BBVFRFUk5TLlNVQ0NFU1NcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAodG9hc3RSZXN1bHQuZm91bmQpIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIHN1Y2Nlc3MgdG9hc3Q6ICR7dG9hc3RSZXN1bHQudGV4dH1gKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVycm9yVG9hc3RSZXN1bHQgPSBhd2FpdCB0aGlzLmNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgU0VMRUNUT1JTLlRPQVNUX1NFTEVDVE9SUyxcbiAgICAgICAgICBURVhUX1BBVFRFUk5TLkVSUk9SXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGVycm9yVG9hc3RSZXN1bHQuZm91bmQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBWaWRlbyBwdWJsaXNoIGZhaWxlZDogJHtlcnJvclRvYXN0UmVzdWx0LnRleHR9YCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9LFxuICAgICAgVklERU9fVElNRU9VVFMuQ09NUExFVElPTl9USU1FT1VULFxuICAgICAgaXNQcm9jZXNzaW5nID8gNTAwMCA6IFZJREVPX1RJTUVPVVRTLkNPTVBMRVRJT05fQ0hFQ0ssXG4gICAgICAnVmlkZW8gcHVibGlzaCBjb21wbGV0aW9uIHRpbWVvdXQgLSBjb3VsZCBub3QgZGV0ZXJtaW5lIHJlc3VsdCBhZnRlciA1IG1pbnV0ZXMnXG4gICAgKTtcblxuICAgIC8vIEV4dHJhY3Qgbm90ZSBJRCBhZnRlciBzdWNjZXNzZnVsIGNvbXBsZXRpb25cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5leHRyYWN0Tm90ZUlkRnJvbVBhZ2UocGFnZSk7XG4gIH1cblxuICBhc3luYyBwdWJsaXNoVmlkZW8oXG4gICAgdGl0bGU6IHN0cmluZyxcbiAgICBjb250ZW50OiBzdHJpbmcsXG4gICAgdmlkZW9QYXRoOiBzdHJpbmcsXG4gICAgdGFnczogc3RyaW5nID0gJycsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxQdWJsaXNoUmVzdWx0PiB7XG4gICAgLy8gVmFsaWRhdGUgaW5wdXRzXG4gICAgdGhpcy52YWxpZGF0ZVZpZGVvSW5wdXRzKHRpdGxlLCBjb250ZW50LCB2aWRlb1BhdGgpO1xuXG4gICAgLy8gVmFsaWRhdGUgYW5kIHJlc29sdmUgdmlkZW8gcGF0aFxuICAgIGNvbnN0IHJlc29sdmVkVmlkZW9QYXRoID0gdGhpcy52YWxpZGF0ZUFuZFJlc29sdmVWaWRlb1BhdGgodmlkZW9QYXRoKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UoZmFsc2UsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgbm90ZUlkID0gYXdhaXQgdGhpcy5leGVjdXRlVmlkZW9QdWJsaXNoV29ya2Zsb3cocGFnZSwgdGl0bGUsIGNvbnRlbnQsIHJlc29sdmVkVmlkZW9QYXRoLCB0YWdzKTtcblxuICAgICAgICAvLyBTYXZlIGNvb2tpZXNcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLnNhdmVDb29raWVzRnJvbVBhZ2UocGFnZSk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIG1lc3NhZ2U6ICdWaWRlbyBwdWJsaXNoZWQgc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICBjb250ZW50LFxuICAgICAgICAgIGltYWdlQ291bnQ6IDAsIC8vIFZpZGVvcyBkb24ndCBoYXZlIGltYWdlIGNvdW50XG4gICAgICAgICAgdGFncyxcbiAgICAgICAgICB1cmw6IHRoaXMuZ2V0Q29uZmlnKCkueGhzLmNyZWF0b3JWaWRlb1B1Ymxpc2hVcmwsXG4gICAgICAgICAgbm90ZUlkOiBub3RlSWQgfHwgdW5kZWZpbmVkLFxuICAgICAgICB9O1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYFZpZGVvIHB1Ymxpc2ggZXJyb3I6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlVmlkZW9JbnB1dHModGl0bGU6IHN0cmluZywgY29udGVudDogc3RyaW5nLCB2aWRlb1BhdGg6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGl0bGU/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignVmlkZW8gdGl0bGUgY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgdGl0bGUgd2lkdGggZm9yIHZpZGVvIHBvc3RzIHRvb1xuICAgIGFzc2VydFRpdGxlV2lkdGhWYWxpZCh0aXRsZSk7XG4gICAgbG9nZ2VyLmRlYnVnKGBWaWRlbyB0aXRsZSB3aWR0aCB2YWxpZGF0aW9uIHBhc3NlZDogXCIke3RpdGxlfVwiICgke2dldFRpdGxlV2lkdGgodGl0bGUpfSB1bml0cylgKTtcblxuICAgIGlmICghY29udGVudD8udHJpbSgpKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdWaWRlbyBjb250ZW50IGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cblxuICAgIGlmICghdmlkZW9QYXRoPy50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ1ZpZGVvIHBhdGggaXMgcmVxdWlyZWQnKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVWaWRlb1B1Ymxpc2hXb3JrZmxvdyhcbiAgICBwYWdlOiBQYWdlLFxuICAgIHRpdGxlOiBzdHJpbmcsXG4gICAgY29udGVudDogc3RyaW5nLFxuICAgIHZpZGVvUGF0aDogc3RyaW5nLFxuICAgIHRhZ3M6IHN0cmluZ1xuICApOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICAvLyBOYXZpZ2F0ZSB0byB2aWRlbyB1cGxvYWQgcGFnZVxuICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5uYXZpZ2F0ZVdpdGhSZXRyeShcbiAgICAgIHBhZ2UsXG4gICAgICB0aGlzLmdldENvbmZpZygpLnhocy5jcmVhdG9yVmlkZW9QdWJsaXNoVXJsXG4gICAgKTtcblxuICAgIC8vIFdhaXQgZm9yIHBhZ2UgdG8gbG9hZFxuICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLlBBR0VfTE9BRCk7XG5cbiAgICAvLyBTd2l0Y2ggdG8gdmlkZW8gdXBsb2FkIHRhYiBpZiBuZWVkZWRcbiAgICBhd2FpdCB0aGlzLmNsaWNrVmlkZW9VcGxvYWRUYWIocGFnZSk7XG5cbiAgICAvLyBXYWl0IGZvciB0YWIgc3dpdGNoIHRvIGNvbXBsZXRlXG4gICAgYXdhaXQgc2xlZXAoVklERU9fVElNRU9VVFMuVEFCX1NXSVRDSCk7XG5cbiAgICAvLyBVcGxvYWQgdmlkZW9cbiAgICBhd2FpdCB0aGlzLnVwbG9hZFZpZGVvKHBhZ2UsIHZpZGVvUGF0aCk7XG5cbiAgICAvLyBXYWl0IGZvciB2aWRlbyB0byBiZSBwcm9jZXNzZWQgKHZpZGVvcyB0YWtlIGxvbmdlciB0aGFuIGltYWdlcylcbiAgICBhd2FpdCBzbGVlcChWSURFT19USU1FT1VUUy5WSURFT19QUk9DRVNTSU5HKTtcblxuICAgIC8vIEZpbGwgaW4gdGl0bGVcbiAgICBhd2FpdCB0aGlzLmZpbGxUaXRsZShwYWdlLCB0aXRsZSk7XG5cbiAgICAvLyBXYWl0IGEgYml0IGZvciBjb250ZW50IGFyZWEgdG8gYXBwZWFyXG4gICAgYXdhaXQgc2xlZXAoVklERU9fVElNRU9VVFMuQ09OVEVOVF9XQUlUKTtcblxuICAgIC8vIEZpbGwgaW4gY29udGVudFxuICAgIGF3YWl0IHRoaXMuZmlsbENvbnRlbnQocGFnZSwgY29udGVudCk7XG5cbiAgICAvLyBBZGQgdGFncyBpZiBwcm92aWRlZFxuICAgIGlmICh0YWdzKSB7XG4gICAgICBhd2FpdCB0aGlzLmFkZFRhZ3MocGFnZSwgdGFncyk7XG4gICAgfVxuXG4gICAgLy8gU3VibWl0IHRoZSB2aWRlb1xuICAgIGF3YWl0IHRoaXMuc3VibWl0UG9zdChwYWdlKTtcblxuICAgIC8vIFdhaXQgZm9yIGNvbXBsZXRpb24gYW5kIGNoZWNrIHJlc3VsdCAodmlkZW9zIG5lZWQgbG9uZ2VyIHRpbWVvdXQpXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMud2FpdEZvclZpZGVvUHVibGlzaENvbXBsZXRpb24ocGFnZSk7XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlQW5kUmVzb2x2ZVZpZGVvUGF0aCh2aWRlb1BhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgcmVzb2x2ZWRQYXRoID0gam9pbihwcm9jZXNzLmN3ZCgpLCB2aWRlb1BhdGgpO1xuXG4gICAgaWYgKCFleGlzdHNTeW5jKHJlc29sdmVkUGF0aCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYFZpZGVvIGZpbGUgbm90IGZvdW5kOiAke3ZpZGVvUGF0aH1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdGF0cyA9IHN0YXRTeW5jKHJlc29sdmVkUGF0aCk7XG4gICAgaWYgKCFzdGF0cy5pc0ZpbGUoKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgUGF0aCBpcyBub3QgYSBmaWxlOiAke3ZpZGVvUGF0aH1gKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBmaWxlIGV4dGVuc2lvblxuICAgIGNvbnN0IGV4dCA9IHZpZGVvUGF0aC50b0xvd2VyQ2FzZSgpLnNwbGl0KCcuJykucG9wKCk7XG4gICAgY29uc3QgYWxsb3dlZEV4dGVuc2lvbnMgPSBbJ21wNCcsICdtb3YnLCAnYXZpJywgJ21rdicsICd3ZWJtJywgJ2ZsdicsICd3bXYnXTtcbiAgICBpZiAoIWV4dCB8fCAhYWxsb3dlZEV4dGVuc2lvbnMuaW5jbHVkZXMoZXh0KSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihcbiAgICAgICAgYFVuc3VwcG9ydGVkIHZpZGVvIGZvcm1hdDogJHt2aWRlb1BhdGh9LiBTdXBwb3J0ZWQ6ICR7YWxsb3dlZEV4dGVuc2lvbnMuam9pbignLCAnKX1gXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGZpbGUgc2l6ZSAoWEhTIHR5cGljYWxseSBoYXMgbGltaXRzKVxuICAgIGNvbnN0IG1heFNpemVJbk1CID0gNTAwOyAvLyA1MDBNQiBsaW1pdFxuICAgIGNvbnN0IGZpbGVTaXplSW5NQiA9IHN0YXRzLnNpemUgLyAoMTAyNCAqIDEwMjQpO1xuICAgIGlmIChmaWxlU2l6ZUluTUIgPiBtYXhTaXplSW5NQikge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihcbiAgICAgICAgYFZpZGVvIGZpbGUgdG9vIGxhcmdlOiAke2ZpbGVTaXplSW5NQi50b0ZpeGVkKDIpfU1CLiBNYXhpbXVtIGFsbG93ZWQ6ICR7bWF4U2l6ZUluTUJ9TUJgXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiByZXNvbHZlZFBhdGg7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNsaWNrVmlkZW9VcGxvYWRUYWIocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBUcnkgbXVsdGlwbGUgc2VsZWN0b3JzIGZvciB2aWRlbyB0YWJcbiAgICAgIGNvbnN0IHZpZGVvVGFiU2VsZWN0b3JzID0gW1xuICAgICAgICAnZGl2LmNyZWF0b3ItdGFiJyxcbiAgICAgICAgJy5jcmVhdG9yLXRhYicsXG4gICAgICAgICdbcm9sZT1cInRhYlwiXScsXG4gICAgICAgICcudGFiJyxcbiAgICAgICAgJ2RpdltjbGFzcyo9XCJ0YWJcIl0nLFxuICAgICAgXTtcblxuICAgICAgbGV0IHRhYnM6IGFueVtdID0gW107XG4gICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHZpZGVvVGFiU2VsZWN0b3JzKSB7XG4gICAgICAgIGNvbnN0IGZvdW5kVGFicyA9IGF3YWl0IHBhZ2UuJCQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAoZm91bmRUYWJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0YWJzID0gZm91bmRUYWJzO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0YWJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBsb2dnZXIud2FybignTm8gdGFicyBmb3VuZCBmb3IgdmlkZW8gdXBsb2FkJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gTG9vayBmb3IgdGhlIHZpZGVvIHVwbG9hZCB0YWIgc3BlY2lmaWNhbGx5XG4gICAgICBsZXQgdmlkZW9UYWI6IGFueSA9IG51bGw7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRhYnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgdGFiID0gdGFic1tpXTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCB0YWIuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuICAgICAgICAgIGlmICghaXNWaXNpYmxlKSBjb250aW51ZTtcblxuICAgICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwudGV4dENvbnRlbnQsIHRhYik7XG5cbiAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIHRoZSB2aWRlbyB1cGxvYWQgdGFiXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGV4dCAmJlxuICAgICAgICAgICAgKHRleHQuaW5jbHVkZXMoJ+S4iuS8oOinhumikScpIHx8IHRleHQuaW5jbHVkZXMoJ+inhumikScpIHx8IHRleHQuaW5jbHVkZXMoJ3ZpZGVvJykpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB2aWRlb1RhYiA9IHRhYjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAvLyBJZ25vcmUgaW5kaXZpZHVhbCB0YWIgZXJyb3JzXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHZpZGVvVGFiKSB7XG4gICAgICAgIGF3YWl0IHZpZGVvVGFiLmNsaWNrKCk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDIwMDApOyAvLyBXYWl0IGZvciB0YWIgc3dpdGNoXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBGYWxsYmFjazogY2xpY2sgdGhlIGZpcnN0IHRhYiAodXN1YWxseSB2aWRlbyB1cGxvYWQpXG4gICAgICAgIGNvbnN0IHZpc2libGVUYWJzOiBhbnlbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHRhYiBvZiB0YWJzKSB7XG4gICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgdGFiLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgICBpZiAoaXNWaXNpYmxlKSB7XG4gICAgICAgICAgICB2aXNpYmxlVGFicy5wdXNoKHRhYik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZpc2libGVUYWJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBhd2FpdCB2aXNpYmxlVGFic1swXS5jbGljaygpOyAvLyBVc3VhbGx5IHRoZSBmaXJzdCB0YWIgaXMgdmlkZW8gdXBsb2FkXG4gICAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBjbGljayB2aWRlbyB1cGxvYWQgdGFiOiAke2Vycm9yfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBsb2FkVmlkZW8ocGFnZTogUGFnZSwgdmlkZW9QYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2dnZXIuZGVidWcoYFVwbG9hZGluZyB2aWRlbzogJHt2aWRlb1BhdGh9YCk7XG5cbiAgICAvLyBGaW5kIGZpbGUgaW5wdXQgZWxlbWVudFxuICAgIGNvbnN0IGZpbGVJbnB1dCA9IGF3YWl0IHRoaXMuZmluZEVsZW1lbnRCeVNlbGVjdG9ycyhwYWdlLCBTRUxFQ1RPUlMuRklMRV9JTlBVVCk7XG4gICAgaWYgKCFmaWxlSW5wdXQpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIGZpbGUgdXBsb2FkIGlucHV0IG9uIHZpZGVvIHVwbG9hZCBwYWdlJyk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFdhaXQgZm9yIHRoZSBpbnB1dCB0byBiZSByZWFkeVxuICAgICAgYXdhaXQgc2xlZXAoVklERU9fVElNRU9VVFMuVVBMT0FEX1JFQURZKTtcblxuICAgICAgLy8gVXBsb2FkIHRoZSB2aWRlbyBmaWxlXG4gICAgICBhd2FpdCBmaWxlSW5wdXQudXBsb2FkRmlsZSh2aWRlb1BhdGgpO1xuICAgICAgbG9nZ2VyLmRlYnVnKCdWaWRlbyBmaWxlIHVwbG9hZGVkLCB3YWl0aW5nIGZvciBwcm9jZXNzaW5nLi4uJyk7XG5cbiAgICAgIC8vIFdhaXQgZm9yIHVwbG9hZCB0byBzdGFydCBhbmQgc2hvdyBwcm9ncmVzc1xuICAgICAgYXdhaXQgc2xlZXAoVklERU9fVElNRU9VVFMuVVBMT0FEX1NUQVJUKTtcblxuICAgICAgLy8gV2FpdCBmb3IgdmlkZW8gcHJvY2Vzc2luZyB0byBjb21wbGV0ZSAodGhpcyBjYW4gdGFrZSBhIHdoaWxlKVxuICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yVmlkZW9Qcm9jZXNzaW5nKHBhZ2UpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBGYWlsZWQgdG8gdXBsb2FkIHZpZGVvICR7dmlkZW9QYXRofTogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JWaWRlb1Byb2Nlc3NpbmcocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZ2dlci5kZWJ1ZygnV2FpdGluZyBmb3IgdmlkZW8gcHJvY2Vzc2luZyB0byBjb21wbGV0ZS4uLicpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMud2FpdEZvckNvbmRpdGlvbihcbiAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIC8vIENoZWNrIGlmIHByb2Nlc3NpbmcgaXMgY29tcGxldGVcbiAgICAgICAgICBjb25zdCBjb21wbGV0ZVJlc3VsdCA9IGF3YWl0IHRoaXMuY2hlY2tFbGVtZW50Rm9yUGF0dGVybnMoXG4gICAgICAgICAgICBwYWdlLFxuICAgICAgICAgICAgU0VMRUNUT1JTLkNPTVBMRVRJT05fSU5ESUNBVE9SUyxcbiAgICAgICAgICAgIFRFWFRfUEFUVEVSTlMuU1VDQ0VTU1xuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAoY29tcGxldGVSZXN1bHQuZm91bmQpIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgVmlkZW8gcHJvY2Vzc2luZyBjb21wbGV0ZTogJHtjb21wbGV0ZVJlc3VsdC50ZXh0fWApO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gQ2hlY2sgaWYgc3RpbGwgcHJvY2Vzc2luZ1xuICAgICAgICAgIGNvbnN0IHByb2Nlc3NpbmdSZXN1bHQgPSBhd2FpdCB0aGlzLmNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgICAgICAgICAgcGFnZSxcbiAgICAgICAgICAgIFNFTEVDVE9SUy5QUk9DRVNTSU5HX0lORElDQVRPUlMsXG4gICAgICAgICAgICBURVhUX1BBVFRFUk5TLlBST0NFU1NJTkdcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKHByb2Nlc3NpbmdSZXN1bHQuZm91bmQpIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgVmlkZW8gcHJvY2Vzc2luZzogJHtwcm9jZXNzaW5nUmVzdWx0LnRleHR9YCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIFN0aWxsIHByb2Nlc3NpbmcsIGNvbnRpbnVlIHdhaXRpbmdcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBJZiBub3QgcHJvY2Vzc2luZyBhbmQgbm8gY29tcGxldGlvbiBpbmRpY2F0b3IsIGFzc3VtZSBpdCdzIGRvbmVcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ05vIHByb2Nlc3NpbmcgaW5kaWNhdG9ycyBmb3VuZCwgYXNzdW1pbmcgdmlkZW8gcHJvY2Vzc2luZyBjb21wbGV0ZScpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuICAgICAgICBWSURFT19USU1FT1VUUy5QUk9DRVNTSU5HX1RJTUVPVVQsXG4gICAgICAgIFZJREVPX1RJTUVPVVRTLlBST0NFU1NJTkdfQ0hFQ0ssXG4gICAgICAgICdWaWRlbyBwcm9jZXNzaW5nIHRpbWVvdXQnXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybignVmlkZW8gcHJvY2Vzc2luZyB0aW1lb3V0LCBjb250aW51aW5nIGFueXdheS4uLicpO1xuICAgIH1cbiAgfVxuXG59XG4iLCJpbXBvcnQgeyBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IENvbmZpZywgUHVibGlzaFJlc3VsdCB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBCYXNlU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9iYXNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgSW1hZ2VQdWJsaXNoU2VydmljZSB9IGZyb20gJy4vcHVibGlzaC1pbWFnZS5zZXJ2aWNlJztcbmltcG9ydCB7IFZpZGVvUHVibGlzaFNlcnZpY2UgfSBmcm9tICcuL3B1Ymxpc2gtdmlkZW8uc2VydmljZSc7XG5cbmV4cG9ydCBjbGFzcyBQdWJsaXNoU2VydmljZSBleHRlbmRzIEJhc2VTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBpbWFnZVNlcnZpY2U6IEltYWdlUHVibGlzaFNlcnZpY2U7XG4gIHByaXZhdGUgdmlkZW9TZXJ2aWNlOiBWaWRlb1B1Ymxpc2hTZXJ2aWNlO1xuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnKSB7XG4gICAgc3VwZXIoY29uZmlnKTtcbiAgICB0aGlzLmltYWdlU2VydmljZSA9IG5ldyBJbWFnZVB1Ymxpc2hTZXJ2aWNlKGNvbmZpZyk7XG4gICAgdGhpcy52aWRlb1NlcnZpY2UgPSBuZXcgVmlkZW9QdWJsaXNoU2VydmljZShjb25maWcpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHB1Ymxpc2hOb3RlKFxuICAgIHRpdGxlOiBzdHJpbmcsXG4gICAgY29udGVudDogc3RyaW5nLFxuICAgIGltYWdlUGF0aHM6IHN0cmluZ1tdLFxuICAgIHRhZ3M6IHN0cmluZyA9ICcnLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8UHVibGlzaFJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLmltYWdlU2VydmljZS5wdWJsaXNoTm90ZSh0aXRsZSwgY29udGVudCwgaW1hZ2VQYXRocywgdGFncywgYnJvd3NlclBhdGgpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHB1Ymxpc2hWaWRlbyhcbiAgICB0aXRsZTogc3RyaW5nLFxuICAgIGNvbnRlbnQ6IHN0cmluZyxcbiAgICB2aWRlb1BhdGg6IHN0cmluZyxcbiAgICB0YWdzOiBzdHJpbmcgPSAnJyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPFB1Ymxpc2hSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy52aWRlb1NlcnZpY2UucHVibGlzaFZpZGVvKHRpdGxlLCBjb250ZW50LCB2aWRlb1BhdGgsIHRhZ3MsIGJyb3dzZXJQYXRoKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBwdWJsaXNoQ29udGVudChcbiAgICB0eXBlOiAnaW1hZ2UnIHwgJ3ZpZGVvJyxcbiAgICB0aXRsZTogc3RyaW5nLFxuICAgIGNvbnRlbnQ6IHN0cmluZyxcbiAgICBtZWRpYVBhdGhzOiBzdHJpbmdbXSxcbiAgICB0YWdzOiBzdHJpbmcgPSAnJyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPFB1Ymxpc2hSZXN1bHQ+IHtcbiAgICBpZiAodHlwZSA9PT0gJ2ltYWdlJykge1xuICAgICAgcmV0dXJuIHRoaXMucHVibGlzaE5vdGUodGl0bGUsIGNvbnRlbnQsIG1lZGlhUGF0aHMsIHRhZ3MsIGJyb3dzZXJQYXRoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMucHVibGlzaFZpZGVvKHRpdGxlLCBjb250ZW50LCBtZWRpYVBhdGhzWzBdLCB0YWdzLCBicm93c2VyUGF0aCk7XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIFRvb2wgcmVxdWVzdCBoYW5kbGVycyBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG5pbXBvcnQgeyBBdXRoU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvYXV0aC9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgRmVlZFNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL2ZlZWRzL2ZlZWQuc2VydmljZSc7XG5pbXBvcnQgeyBQdWJsaXNoU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvcHVibGlzaGluZy9wdWJsaXNoLnNlcnZpY2UnO1xuaW1wb3J0IHsgTm90ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL25vdGVzL25vdGUuc2VydmljZSc7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IFhIU0Vycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQge1xuICB2YWxpZGF0ZVJlcXVpcmVkUGFyYW1zLFxuICB2YWxpZGF0ZVB1Ymxpc2hOb3RlUGFyYW1zLFxuICBzYWZlRXJyb3JIYW5kbGVyLFxuICBjcmVhdGVNY3BUb29sUmVzcG9uc2UsXG4gIGNyZWF0ZU1jcEVycm9yUmVzcG9uc2UsXG59IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvbG9nZ2VyJztcbmltcG9ydCB7IGFzc2VydFRpdGxlV2lkdGhWYWxpZCB9IGZyb20gJy4uLy4uL3NoYXJlZC90aXRsZS12YWxpZGF0b3InO1xuXG4vKipcbiAqIFRvb2wgcmVxdWVzdCBhcmd1bWVudHMgaW50ZXJmYWNlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVG9vbFJlcXVlc3RBcmdzIHtcbiAgYnJvd3Nlcl9wYXRoPzogc3RyaW5nO1xuICBrZXl3b3JkPzogc3RyaW5nO1xuICBmZWVkX2lkPzogc3RyaW5nO1xuICB4c2VjX3Rva2VuPzogc3RyaW5nO1xuICBub3RlPzogc3RyaW5nO1xuICB0eXBlPzogc3RyaW5nO1xuICB0aXRsZT86IHN0cmluZztcbiAgY29udGVudD86IHN0cmluZztcbiAgbWVkaWFfcGF0aHM/OiBzdHJpbmdbXTtcbiAgdGFncz86IHN0cmluZztcbiAgbGltaXQ/OiBudW1iZXI7XG4gIGN1cnNvcj86IHN0cmluZztcbiAgbm90ZV9pZD86IHN0cmluZztcbiAgbGFzdF9wdWJsaXNoZWQ/OiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgVG9vbEhhbmRsZXJzIHtcbiAgcHJpdmF0ZSBhdXRoU2VydmljZTogQXV0aFNlcnZpY2U7XG4gIHByaXZhdGUgZmVlZFNlcnZpY2U6IEZlZWRTZXJ2aWNlO1xuICBwcml2YXRlIHB1Ymxpc2hTZXJ2aWNlOiBQdWJsaXNoU2VydmljZTtcbiAgcHJpdmF0ZSBub3RlU2VydmljZTogTm90ZVNlcnZpY2U7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgY29uc3QgY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy5hdXRoU2VydmljZSA9IG5ldyBBdXRoU2VydmljZShjb25maWcpO1xuICAgIHRoaXMuZmVlZFNlcnZpY2UgPSBuZXcgRmVlZFNlcnZpY2UoY29uZmlnKTtcbiAgICB0aGlzLnB1Ymxpc2hTZXJ2aWNlID0gbmV3IFB1Ymxpc2hTZXJ2aWNlKGNvbmZpZyk7XG4gICAgdGhpcy5ub3RlU2VydmljZSA9IG5ldyBOb3RlU2VydmljZShjb25maWcpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlQXV0aExvZ2luKFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICAvLyBTdGFydCBsb2dpbiBwcm9jZXNzIGluIGJhY2tncm91bmQgYW5kIHJldHVybiBpbW1lZGlhdGVseVxuICAgIC8vIFRoaXMgZm9sbG93cyB0aGUgXCJpbnN0YW50IHJlc3BvbnNlXCIgcGF0dGVybiBkZXNjcmliZWQgaW4gUkVBRE1FXG4gICAgdGhpcy5hdXRoU2VydmljZS5sb2dpbihicm93c2VyUGF0aCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICBzYWZlRXJyb3JIYW5kbGVyKGVycm9yLCAnQmFja2dyb3VuZCBsb2dpbiBlcnJvcicsIGxvZ2dlcik7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgICAgICAgICdMb2dpbiBwcm9jZXNzIHN0YXJ0ZWQuIEEgYnJvd3NlciB3aW5kb3cgd2lsbCBvcGVuIGZvciB5b3UgdG8gY29tcGxldGUgdGhlIGxvZ2luLicsXG4gICAgICAgICAgICAgIHN0YXR1czogJ2xvZ2luX3N0YXJ0ZWQnLFxuICAgICAgICAgICAgICBhY3Rpb246ICdicm93c2VyX29wZW5lZCcsXG4gICAgICAgICAgICAgIGluc3RydWN0aW9uczogW1xuICAgICAgICAgICAgICAgICcxLiBDb21wbGV0ZSB0aGUgbG9naW4gcHJvY2VzcyBpbiB0aGUgb3BlbmVkIGJyb3dzZXIgd2luZG93JyxcbiAgICAgICAgICAgICAgICAnMi4gU2NhbiBRUiBjb2RlIG9yIGVudGVyIHlvdXIgY3JlZGVudGlhbHMnLFxuICAgICAgICAgICAgICAgICczLiBMb2dpbiB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgdmVyaWZpZWQgYW5kIGNvb2tpZXMgc2F2ZWQnLFxuICAgICAgICAgICAgICAgICc0LiBVc2UgeGhzX2F1dGhfc3RhdHVzIHRvIGNoZWNrIGlmIGxvZ2luIGNvbXBsZXRlZCcsXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIG5vdGU6ICdUaGUgbG9naW4gcHJvY2VzcyBydW5zIGluIHRoZSBiYWNrZ3JvdW5kLiBZb3UgY2FuIGNvbnRpbnVlIHVzaW5nIG90aGVyIHRvb2xzIHdoaWxlIGxvZ2luIGNvbXBsZXRlcy4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAyXG4gICAgICAgICAgKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUF1dGhMb2dvdXQoKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuYXV0aFNlcnZpY2UubG9nb3V0KCk7XG4gICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlQXV0aFN0YXR1cyhcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5hdXRoU2VydmljZS5jaGVja1N0YXR1cyhicm93c2VyUGF0aCk7XG4gICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlRGlzY292ZXJGZWVkcyhcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5mZWVkU2VydmljZS5nZXRGZWVkTGlzdChicm93c2VyUGF0aCk7XG4gICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlU2VhcmNoTm90ZShcbiAgICBrZXl3b3JkPzogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICB2YWxpZGF0ZVJlcXVpcmVkUGFyYW1zKHsga2V5d29yZCB9LCBbJ2tleXdvcmQnXSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5mZWVkU2VydmljZS5zZWFyY2hGZWVkcyhrZXl3b3JkISwgYnJvd3NlclBhdGgpO1xuICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UocmVzdWx0KTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUdldE5vdGVEZXRhaWwoXG4gICAgZmVlZElkPzogc3RyaW5nLFxuICAgIHhzZWNUb2tlbj86IHN0cmluZyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgdmFsaWRhdGVSZXF1aXJlZFBhcmFtcyh7IGZlZWRJZCwgeHNlY1Rva2VuIH0sIFsnZmVlZElkJywgJ3hzZWNUb2tlbiddKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmZlZWRTZXJ2aWNlLmdldEZlZWREZXRhaWwoZmVlZElkISwgeHNlY1Rva2VuISwgYnJvd3NlclBhdGgpO1xuICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UocmVzdWx0KTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUNvbW1lbnRPbk5vdGUoXG4gICAgZmVlZElkPzogc3RyaW5nLFxuICAgIHhzZWNUb2tlbj86IHN0cmluZyxcbiAgICBub3RlPzogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICB2YWxpZGF0ZVJlcXVpcmVkUGFyYW1zKHsgZmVlZElkLCB4c2VjVG9rZW4sIG5vdGUgfSwgWydmZWVkSWQnLCAneHNlY1Rva2VuJywgJ25vdGUnXSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5mZWVkU2VydmljZS5jb21tZW50T25GZWVkKGZlZWRJZCEsIHhzZWNUb2tlbiEsIG5vdGUhLCBicm93c2VyUGF0aCk7XG4gICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlUHVibGlzaENvbnRlbnQoXG4gICAgdHlwZT86IHN0cmluZyxcbiAgICB0aXRsZT86IHN0cmluZyxcbiAgICBjb250ZW50Pzogc3RyaW5nLFxuICAgIG1lZGlhUGF0aHM/OiBzdHJpbmdbXSxcbiAgICB0YWdzPzogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICB2YWxpZGF0ZVJlcXVpcmVkUGFyYW1zKHsgdHlwZSwgdGl0bGUsIGNvbnRlbnQsIG1lZGlhUGF0aHMgfSwgW1xuICAgICAgJ3R5cGUnLFxuICAgICAgJ3RpdGxlJyxcbiAgICAgICdjb250ZW50JyxcbiAgICAgICdtZWRpYVBhdGhzJyxcbiAgICBdKTtcblxuICAgIC8vIFZhbGlkYXRlIGNvbnRlbnQgdHlwZVxuICAgIGlmICh0eXBlICE9PSAnaW1hZ2UnICYmIHR5cGUgIT09ICd2aWRlbycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ29udGVudCB0eXBlIG11c3QgYmUgXCJpbWFnZVwiIG9yIFwidmlkZW9cIicpO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIHBhcmFtZXRlciBjb25zdHJhaW50cyB1c2luZyB3aWR0aC1hd2FyZSB0aXRsZSB2YWxpZGF0aW9uXG4gICAgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkKHRpdGxlISk7XG4gICAgaWYgKGNvbnRlbnQhLmxlbmd0aCA+IDEwMDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ29udGVudCBtdXN0IGJlIDEwMDAgY2hhcmFjdGVycyBvciBsZXNzJyk7XG4gICAgfVxuXG4gICAgLy8gRXhlY3V0ZSB1bmlmaWVkIHB1Ymxpc2hpbmcgcHJvY2Vzc1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucHVibGlzaFNlcnZpY2UucHVibGlzaENvbnRlbnQoXG4gICAgICB0eXBlIGFzICdpbWFnZScgfCAndmlkZW8nLFxuICAgICAgdGl0bGUhLFxuICAgICAgY29udGVudCEsXG4gICAgICBtZWRpYVBhdGhzISxcbiAgICAgIHRhZ3MsXG4gICAgICBicm93c2VyUGF0aFxuICAgICk7XG4gICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlR2V0VXNlck5vdGVzKFxuICAgIGxpbWl0PzogbnVtYmVyLFxuICAgIGN1cnNvcj86IHN0cmluZyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ub3RlU2VydmljZS5nZXRVc2VyTm90ZXMobGltaXQsIGN1cnNvciwgYnJvd3NlclBhdGgpO1xuICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UocmVzdWx0KTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZURlbGV0ZU5vdGUoXG4gICAgbm90ZUlkPzogc3RyaW5nLFxuICAgIGxhc3RQdWJsaXNoZWQ/OiBib29sZWFuLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICBpZiAobGFzdFB1Ymxpc2hlZCkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ub3RlU2VydmljZS5kZWxldGVMYXN0UHVibGlzaGVkTm90ZShicm93c2VyUGF0aCk7XG4gICAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gICAgfSBlbHNlIGlmIChub3RlSWQpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMubm90ZVNlcnZpY2UuZGVsZXRlTm90ZShub3RlSWQsIGJyb3dzZXJQYXRoKTtcbiAgICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UocmVzdWx0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgbm90ZV9pZCBvciBsYXN0X3B1Ymxpc2hlZCBtdXN0IGJlIHNwZWNpZmllZCcpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGhhbmRsZVRvb2xSZXF1ZXN0KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBhcmdzOiBUb29sUmVxdWVzdEFyZ3MgPSB7fVxuICApOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgdHJ5IHtcbiAgICAgIHN3aXRjaCAobmFtZSkge1xuICAgICAgICBjYXNlICd4aHNfYXV0aF9sb2dpbic6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlQXV0aExvZ2luKGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmcpO1xuXG4gICAgICAgIGNhc2UgJ3hoc19hdXRoX2xvZ291dCc6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlQXV0aExvZ291dCgpO1xuXG4gICAgICAgIGNhc2UgJ3hoc19hdXRoX3N0YXR1cyc6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlQXV0aFN0YXR1cyhhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nKTtcblxuICAgICAgICBjYXNlICd4aHNfZGlzY292ZXJfZmVlZHMnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZURpc2NvdmVyRmVlZHMoYXJncz8uYnJvd3Nlcl9wYXRoIGFzIHN0cmluZyk7XG5cbiAgICAgICAgY2FzZSAneGhzX3NlYXJjaF9ub3RlJzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVTZWFyY2hOb3RlKGFyZ3M/LmtleXdvcmQgYXMgc3RyaW5nLCBhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nKTtcblxuICAgICAgICBjYXNlICd4aHNfZ2V0X25vdGVfZGV0YWlsJzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVHZXROb3RlRGV0YWlsKFxuICAgICAgICAgICAgYXJncz8uZmVlZF9pZCBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy54c2VjX3Rva2VuIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmdcbiAgICAgICAgICApO1xuXG4gICAgICAgIGNhc2UgJ3hoc19jb21tZW50X29uX25vdGUnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZUNvbW1lbnRPbk5vdGUoXG4gICAgICAgICAgICBhcmdzPy5mZWVkX2lkIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/LnhzZWNfdG9rZW4gYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8ubm90ZSBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nXG4gICAgICAgICAgKTtcblxuICAgICAgICBjYXNlICd4aHNfcHVibGlzaF9jb250ZW50JzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVQdWJsaXNoQ29udGVudChcbiAgICAgICAgICAgIGFyZ3M/LnR5cGUgYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8udGl0bGUgYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8uY29udGVudCBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5tZWRpYV9wYXRocyBhcyBzdHJpbmdbXSxcbiAgICAgICAgICAgIGFyZ3M/LnRhZ3MgYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8uYnJvd3Nlcl9wYXRoIGFzIHN0cmluZ1xuICAgICAgICAgICk7XG5cbiAgICAgICAgY2FzZSAneGhzX2dldF91c2VyX25vdGVzJzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVHZXRVc2VyTm90ZXMoXG4gICAgICAgICAgICBhcmdzPy5saW1pdCBhcyBudW1iZXIsXG4gICAgICAgICAgICBhcmdzPy5jdXJzb3IgYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8uYnJvd3Nlcl9wYXRoIGFzIHN0cmluZ1xuICAgICAgICAgICk7XG5cbiAgICAgICAgY2FzZSAneGhzX2RlbGV0ZV9ub3RlJzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVEZWxldGVOb3RlKFxuICAgICAgICAgICAgYXJncz8ubm90ZV9pZCBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5sYXN0X3B1Ymxpc2hlZCBhcyBib29sZWFuLFxuICAgICAgICAgICAgYXJncz8uYnJvd3Nlcl9wYXRoIGFzIHN0cmluZ1xuICAgICAgICAgICk7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdG9vbDogJHtuYW1lfWApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBYSFNFcnJvcikge1xuICAgICAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKGVycm9yLnRvSlNPTigpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjcmVhdGVNY3BFcnJvclJlc3BvbnNlKGVycm9yKTtcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICogU2hhcmVkIHV0aWxpdGllcywgdHlwZXMsIGFuZCBzZXJ2aWNlcyBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG4vLyBDb25maWd1cmF0aW9uIGFuZCB0eXBlc1xuZXhwb3J0ICogZnJvbSAnLi9jb25maWcnO1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG5cbi8vIFV0aWxpdGllc1xuZXhwb3J0ICogZnJvbSAnLi91dGlscyc7XG5leHBvcnQgKiBmcm9tICcuL3hocy51dGlscyc7XG5leHBvcnQgKiBmcm9tICcuL2Nvb2tpZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9pbWFnZS1kb3dubG9hZGVyJztcbmV4cG9ydCAqIGZyb20gJy4vdGl0bGUtdmFsaWRhdG9yJztcblxuLy8gRXJyb3IgaGFuZGxpbmcgYW5kIGxvZ2dpbmdcbmV4cG9ydCAqIGZyb20gJy4vZXJyb3JzJztcbmV4cG9ydCAqIGZyb20gJy4vbG9nZ2VyJztcblxuLy8gQmFzZSBzZXJ2aWNlXG5leHBvcnQgKiBmcm9tICcuL2Jhc2Uuc2VydmljZSc7XG4iLCIvKipcbiAqIFJlc291cmNlIHJlcXVlc3QgaGFuZGxlcnMgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL2F1dGgvYXV0aC5zZXJ2aWNlJztcbmltcG9ydCB7IGdldENvbmZpZywgZ2V0Q29va2llc0luZm8gfSBmcm9tICcuLi8uLi9zaGFyZWQvaW5kZXgnO1xuXG5leHBvcnQgY2xhc3MgUmVzb3VyY2VIYW5kbGVycyB7XG4gIHByaXZhdGUgYXV0aFNlcnZpY2U6IEF1dGhTZXJ2aWNlO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGNvbnN0IGNvbmZpZyA9IGdldENvbmZpZygpO1xuICAgIHRoaXMuYXV0aFNlcnZpY2UgPSBuZXcgQXV0aFNlcnZpY2UoY29uZmlnKTtcbiAgfVxuXG4gIGFzeW5jIGdldENvb2tpZXNSZXNvdXJjZSgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb29raWVzSW5mbyA9IGdldENvb2tpZXNJbmZvKCk7XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoY29va2llc0luZm8sIG51bGwsIDIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogU3RyaW5nKGVycm9yKSB9LCBudWxsLCAyKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBnZXRDb25maWdSZXNvdXJjZSgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb25maWdEaWN0ID0gZ2V0Q29uZmlnKCk7XG4gICAgICBjb25zdCBjb25maWdXaXRoRnJhbWV3b3JrID0ge1xuICAgICAgICAuLi5jb25maWdEaWN0LFxuICAgICAgICBmcmFtZXdvcms6ICdNQ1AgVHlwZVNjcmlwdCcsXG4gICAgICAgIHZlcnNpb246IGNvbmZpZ0RpY3Quc2VydmVyLnZlcnNpb24sXG4gICAgICB9O1xuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGNvbmZpZ1dpdGhGcmFtZXdvcmssIG51bGwsIDIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogU3RyaW5nKGVycm9yKSB9LCBudWxsLCAyKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBnZXRTdGF0dXNSZXNvdXJjZSgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBRdWljayBzdGF0dXMgY2hlY2sgKGJ1dCBkb24ndCBmYWlsIGlmIGl0IGVycm9ycylcbiAgICAgIGxldCBhdXRoU3RhdHVzOiBhbnkgPSB7IHN0YXR1czogJ3Vua25vd24nLCBlcnJvcjogJ1N0YXR1cyBjaGVjayBub3QgcGVyZm9ybWVkJyB9O1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXV0aFN0YXR1cyA9IGF3YWl0IHRoaXMuYXV0aFNlcnZpY2UuY2hlY2tTdGF0dXMoKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGF1dGhTdGF0dXMgPSB7IHN0YXR1czogJ2Vycm9yJywgZXJyb3I6IFN0cmluZyhlcnJvcikgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY29va2llc0luZm8gPSBnZXRDb29raWVzSW5mbygpO1xuICAgICAgY29uc3QgY29uZmlnID0gZ2V0Q29uZmlnKCk7XG5cbiAgICAgIGNvbnN0IHN0YXR1c0RhdGEgPSB7XG4gICAgICAgIHNlcnZlcjoge1xuICAgICAgICAgIHN0YXR1czogJ3J1bm5pbmcnLFxuICAgICAgICAgIG5hbWU6IGNvbmZpZy5zZXJ2ZXIubmFtZSxcbiAgICAgICAgICB2ZXJzaW9uOiBjb25maWcuc2VydmVyLnZlcnNpb24sXG4gICAgICAgICAgZnJhbWV3b3JrOiAnTUNQIFR5cGVTY3JpcHQnLFxuICAgICAgICB9LFxuICAgICAgICBhdXRoZW50aWNhdGlvbjogYXV0aFN0YXR1cyxcbiAgICAgICAgY29va2llczoge1xuICAgICAgICAgIGZpbGVFeGlzdHM6IGNvb2tpZXNJbmZvLmZpbGVFeGlzdHMsXG4gICAgICAgICAgY29va2llQ291bnQ6IGNvb2tpZXNJbmZvLmNvb2tpZUNvdW50LFxuICAgICAgICB9LFxuICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICB0b29sc0F2YWlsYWJsZTogOCxcbiAgICAgICAgICBwcm9tcHRzQXZhaWxhYmxlOiAwLFxuICAgICAgICAgIHJlc291cmNlc0F2YWlsYWJsZTogMyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShzdGF0dXNEYXRhLCBudWxsLCAyKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KFxuICAgICAgICB7XG4gICAgICAgICAgc2VydmVyOiB7IHN0YXR1czogJ2Vycm9yJywgZXJyb3I6IFN0cmluZyhlcnJvcikgfSxcbiAgICAgICAgICBmcmFtZXdvcms6ICdNQ1AgVHlwZVNjcmlwdCcsXG4gICAgICAgIH0sXG4gICAgICAgIG51bGwsXG4gICAgICAgIDJcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgaGFuZGxlUmVzb3VyY2VSZXF1ZXN0KHVyaTogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBjb250ZW50OiBzdHJpbmc7XG5cbiAgICAgIHN3aXRjaCAodXJpKSB7XG4gICAgICAgIGNhc2UgJ3hoczovL2Nvb2tpZXMnOlxuICAgICAgICAgIGNvbnRlbnQgPSBhd2FpdCB0aGlzLmdldENvb2tpZXNSZXNvdXJjZSgpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ3hoczovL2NvbmZpZyc6XG4gICAgICAgICAgY29udGVudCA9IGF3YWl0IHRoaXMuZ2V0Q29uZmlnUmVzb3VyY2UoKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICd4aHM6Ly9zdGF0dXMnOlxuICAgICAgICAgIGNvbnRlbnQgPSBhd2FpdCB0aGlzLmdldFN0YXR1c1Jlc291cmNlKCk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gcmVzb3VyY2U6ICR7dXJpfWApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIG1pbWVUeXBlOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICB0ZXh0OiBjb250ZW50LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIG1pbWVUeXBlOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeSh7IGVycm9yOiBTdHJpbmcoZXJyb3IpIH0sIG51bGwsIDIpLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBUb29sIHNjaGVtYXMgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuZXhwb3J0IGludGVyZmFjZSBUb29sU2NoZW1hIHtcbiAgbmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICBpbnB1dFNjaGVtYToge1xuICAgIHR5cGU6ICdvYmplY3QnO1xuICAgIHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgcmVxdWlyZWQ/OiBzdHJpbmdbXTtcbiAgfTtcbn1cblxuZXhwb3J0IGNvbnN0IFhIU19UT09MX1NDSEVNQVM6IFRvb2xTY2hlbWFbXSA9IFtcbiAge1xuICAgIG5hbWU6ICd4aHNfYXV0aF9sb2dpbicsXG4gICAgZGVzY3JpcHRpb246ICdTdGFydCBYaWFvSG9uZ1NodSBsb2dpbiBwcm9jZXNzLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICd4aHNfYXV0aF9sb2dvdXQnLFxuICAgIGRlc2NyaXB0aW9uOiAnTG9nb3V0IGZyb20gWGlhb0hvbmdTaHUgKGNsZWFycyBzYXZlZCBjb29raWVzKS4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHt9LFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAneGhzX2F1dGhfc3RhdHVzJyxcbiAgICBkZXNjcmlwdGlvbjogJ0NoZWNrIFhpYW9Ib25nU2h1IGxvZ2luIHN0YXR1cyAoZmFzdCBjaGVjayB3aXRoIGJyb3dzZXIpLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICd4aHNfZGlzY292ZXJfZmVlZHMnLFxuICAgIGRlc2NyaXB0aW9uOiAnR2V0IGhvbWUgcGFnZSBmZWVkIGxpc3QuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19zZWFyY2hfbm90ZScsXG4gICAgZGVzY3JpcHRpb246ICdTZWFyY2ggZm9yIG5vdGVzIGJ5IGtleXdvcmQuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGtleXdvcmQ6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1NlYXJjaCBrZXl3b3JkIChyZXF1aXJlZCknLFxuICAgICAgICB9LFxuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWydrZXl3b3JkJ10sXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICd4aHNfZ2V0X25vdGVfZGV0YWlsJyxcbiAgICBkZXNjcmlwdGlvbjogJ0dldCBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBhIHNwZWNpZmljIG5vdGUuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGZlZWRfaWQ6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0ZlZWQgSUQgKHJlcXVpcmVkKScsXG4gICAgICAgIH0sXG4gICAgICAgIHhzZWNfdG9rZW46IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1NlY3VyaXR5IHRva2VuIGZvciB0aGUgZmVlZCAocmVxdWlyZWQpJyxcbiAgICAgICAgfSxcbiAgICAgICAgYnJvd3Nlcl9wYXRoOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPcHRpb25hbCBjdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgcmVxdWlyZWQ6IFsnZmVlZF9pZCcsICd4c2VjX3Rva2VuJ10sXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICd4aHNfY29tbWVudF9vbl9ub3RlJyxcbiAgICBkZXNjcmlwdGlvbjogJ0NvbW1lbnQgb24gYSBub3RlLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBmZWVkX2lkOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdGZWVkIElEIChyZXF1aXJlZCknLFxuICAgICAgICB9LFxuICAgICAgICB4c2VjX3Rva2VuOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdTZWN1cml0eSB0b2tlbiBmb3IgdGhlIGZlZWQgKHJlcXVpcmVkKScsXG4gICAgICAgIH0sXG4gICAgICAgIG5vdGU6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0NvbW1lbnQgbm90ZSAocmVxdWlyZWQpJyxcbiAgICAgICAgfSxcbiAgICAgICAgYnJvd3Nlcl9wYXRoOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPcHRpb25hbCBjdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgcmVxdWlyZWQ6IFsnZmVlZF9pZCcsICd4c2VjX3Rva2VuJywgJ25vdGUnXSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19wdWJsaXNoX2NvbnRlbnQnLFxuICAgIGRlc2NyaXB0aW9uOiAnUHVibGlzaCBjb250ZW50IHRvIFhpYW9Ib25nU2h1IChzdXBwb3J0cyBib3RoIGltYWdlcyBhbmQgdmlkZW9zKS4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgdHlwZToge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGVudW06IFsnaW1hZ2UnLCAndmlkZW8nXSxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0NvbnRlbnQgdHlwZTogXCJpbWFnZVwiIGZvciBpbWFnZXMsIFwidmlkZW9cIiBmb3IgdmlkZW9zIChyZXF1aXJlZCknLFxuICAgICAgICB9LFxuICAgICAgICB0aXRsZToge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQ29udGVudCB0aXRsZSAocmVxdWlyZWQsIG1heCAyMCBjaGFyYWN0ZXJzKScsXG4gICAgICAgICAgbWF4TGVuZ3RoOiAyMCxcbiAgICAgICAgfSxcbiAgICAgICAgY29udGVudDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQ29udGVudCBkZXNjcmlwdGlvbiAocmVxdWlyZWQsIG1heCAxMDAwIGNoYXJhY3RlcnMpJyxcbiAgICAgICAgICBtYXhMZW5ndGg6IDEwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lZGlhX3BhdGhzOiB7XG4gICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICBpdGVtczogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgJ0xpc3Qgb2YgbWVkaWEgZmlsZSBwYXRocyAocmVxdWlyZWQsIG5vbi1lbXB0eSkuIEZvciBpbWFnZXM6IDEtMTggaW1hZ2UgZmlsZXMuIEZvciB2aWRlb3M6IGV4YWN0bHkgMSB2aWRlbyBmaWxlLicsXG4gICAgICAgICAgbWF4SXRlbXM6IDE4LFxuICAgICAgICB9LFxuICAgICAgICB0YWdzOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdDb21tYS1zZXBhcmF0ZWQgdGFncyAob3B0aW9uYWwpJyxcbiAgICAgICAgfSxcbiAgICAgICAgYnJvd3Nlcl9wYXRoOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPcHRpb25hbCBjdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgcmVxdWlyZWQ6IFsndHlwZScsICd0aXRsZScsICdjb250ZW50JywgJ21lZGlhX3BhdGhzJ10sXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICd4aHNfZ2V0X3VzZXJfbm90ZXMnLFxuICAgIGRlc2NyaXB0aW9uOiAnR2V0IGN1cnJlbnQgdXNlciBub3RlcyBsaXN0LicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBsaW1pdDoge1xuICAgICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnTnVtYmVyIG9mIG5vdGVzIHRvIGZldGNoIChkZWZhdWx0OiAyMCknLFxuICAgICAgICB9LFxuICAgICAgICBjdXJzb3I6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1BhZ2luYXRpb24gY3Vyc29yIGZvciBuZXh0IHBhZ2UnLFxuICAgICAgICB9LFxuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICd4aHNfZGVsZXRlX25vdGUnLFxuICAgIGRlc2NyaXB0aW9uOiAnRGVsZXRlIGEgdXNlciBub3RlIGJ5IElEIG9yIGRlbGV0ZSB0aGUgbGFzdCBwdWJsaXNoZWQgbm90ZS4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgbm90ZV9pZDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnU3BlY2lmaWMgbm90ZSBJRCB0byBkZWxldGUgKG9wdGlvbmFsIGlmIGxhc3RfcHVibGlzaGVkIGlzIHRydWUpJyxcbiAgICAgICAgfSxcbiAgICAgICAgbGFzdF9wdWJsaXNoZWQ6IHtcbiAgICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdEZWxldGUgdGhlIGxhc3QgcHVibGlzaGVkIG5vdGUgKG9wdGlvbmFsIGlmIG5vdGVfaWQgaXMgcHJvdmlkZWQpJyxcbiAgICAgICAgfSxcbiAgICAgICAgYnJvd3Nlcl9wYXRoOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPcHRpb25hbCBjdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG5dO1xuXG5leHBvcnQgY29uc3QgWEhTX1JFU09VUkNFX1NDSEVNQVMgPSBbXG4gIHtcbiAgICB1cmk6ICd4aHM6Ly9jb29raWVzJyxcbiAgICBuYW1lOiAnWEhTIEF1dGhlbnRpY2F0aW9uIENvb2tpZXMnLFxuICAgIGRlc2NyaXB0aW9uOiAnQ3VycmVudCBYaWFvSG9uZ1NodSBhdXRoZW50aWNhdGlvbiBjb29raWVzIGFuZCBpbmZvJyxcbiAgICBtaW1lVHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICB9LFxuICB7XG4gICAgdXJpOiAneGhzOi8vY29uZmlnJyxcbiAgICBuYW1lOiAnWEhTIFNlcnZlciBDb25maWd1cmF0aW9uJyxcbiAgICBkZXNjcmlwdGlvbjogJ1hIUyBNQ1Agc2VydmVyIGNvbmZpZ3VyYXRpb24nLFxuICAgIG1pbWVUeXBlOiAnYXBwbGljYXRpb24vanNvbicsXG4gIH0sXG4gIHtcbiAgICB1cmk6ICd4aHM6Ly9zdGF0dXMnLFxuICAgIG5hbWU6ICdYSFMgU2VydmVyIFN0YXR1cycsXG4gICAgZGVzY3JpcHRpb246ICdDdXJyZW50IHNlcnZlciBhbmQgYXV0aGVudGljYXRpb24gc3RhdHVzJyxcbiAgICBtaW1lVHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICB9LFxuXTtcbiIsIi8qKlxuICogTUNQIFNlcnZlciBmb3IgWGlhb0hvbmdTaHUgT3BlcmF0aW9uc1xuICovXG5cbmltcG9ydCB7IFNlcnZlciB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc2VydmVyL2luZGV4LmpzJztcbmltcG9ydCB7IFN0ZGlvU2VydmVyVHJhbnNwb3J0IH0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zZXJ2ZXIvc3RkaW8uanMnO1xuaW1wb3J0IHtcbiAgQ2FsbFRvb2xSZXF1ZXN0U2NoZW1hLFxuICBMaXN0VG9vbHNSZXF1ZXN0U2NoZW1hLFxuICBMaXN0UmVzb3VyY2VzUmVxdWVzdFNjaGVtYSxcbiAgUmVhZFJlc291cmNlUmVxdWVzdFNjaGVtYSxcbn0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay90eXBlcy5qcyc7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IFRvb2xIYW5kbGVycyB9IGZyb20gJy4vaGFuZGxlcnMvdG9vbC5oYW5kbGVycyc7XG5pbXBvcnQgeyBSZXNvdXJjZUhhbmRsZXJzIH0gZnJvbSAnLi9oYW5kbGVycy9yZXNvdXJjZS5oYW5kbGVycyc7XG5pbXBvcnQgeyBYSFNfVE9PTF9TQ0hFTUFTLCBYSFNfUkVTT1VSQ0VfU0NIRU1BUyB9IGZyb20gJy4vc2NoZW1hcy90b29sLnNjaGVtYXMnO1xuXG5leHBvcnQgY2xhc3MgWEhTTUNQU2VydmVyIHtcbiAgcHJpdmF0ZSBzZXJ2ZXI6IFNlcnZlcjtcbiAgcHJpdmF0ZSB0b29sSGFuZGxlcnM6IFRvb2xIYW5kbGVycztcbiAgcHJpdmF0ZSByZXNvdXJjZUhhbmRsZXJzOiBSZXNvdXJjZUhhbmRsZXJzO1xuICBwcml2YXRlIGNvbmZpZzogUmV0dXJuVHlwZTx0eXBlb2YgZ2V0Q29uZmlnPjtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGdldENvbmZpZygpO1xuICAgIHRoaXMudG9vbEhhbmRsZXJzID0gbmV3IFRvb2xIYW5kbGVycygpO1xuICAgIHRoaXMucmVzb3VyY2VIYW5kbGVycyA9IG5ldyBSZXNvdXJjZUhhbmRsZXJzKCk7XG4gICAgdGhpcy5zZXJ2ZXIgPSBuZXcgU2VydmVyKFxuICAgICAge1xuICAgICAgICBuYW1lOiB0aGlzLmNvbmZpZy5zZXJ2ZXIubmFtZSxcbiAgICAgICAgdmVyc2lvbjogdGhpcy5jb25maWcuc2VydmVyLnZlcnNpb24sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICB0b29sczoge30sXG4gICAgICAgICAgcmVzb3VyY2VzOiB7fSxcbiAgICAgICAgfSxcbiAgICAgIH1cbiAgICApO1xuXG4gICAgdGhpcy5zZXR1cFRvb2xIYW5kbGVycygpO1xuICAgIHRoaXMuc2V0dXBSZXNvdXJjZUhhbmRsZXJzKCk7XG4gIH1cblxuICBwcml2YXRlIHNldHVwVG9vbEhhbmRsZXJzKCk6IHZvaWQge1xuICAgIHRoaXMuc2VydmVyLnNldFJlcXVlc3RIYW5kbGVyKENhbGxUb29sUmVxdWVzdFNjaGVtYSwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgIGNvbnN0IHsgbmFtZSwgYXJndW1lbnRzOiBhcmdzIH0gPSByZXF1ZXN0LnBhcmFtcztcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnRvb2xIYW5kbGVycy5oYW5kbGVUb29sUmVxdWVzdChuYW1lLCBhcmdzKTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2VydmVyLnNldFJlcXVlc3RIYW5kbGVyKExpc3RUb29sc1JlcXVlc3RTY2hlbWEsIGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvb2xzOiBYSFNfVE9PTF9TQ0hFTUFTLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBSZXNvdXJjZUhhbmRsZXJzKCk6IHZvaWQge1xuICAgIHRoaXMuc2VydmVyLnNldFJlcXVlc3RIYW5kbGVyKExpc3RSZXNvdXJjZXNSZXF1ZXN0U2NoZW1hLCBhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXNvdXJjZXM6IFhIU19SRVNPVVJDRV9TQ0hFTUFTLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2VydmVyLnNldFJlcXVlc3RIYW5kbGVyKFJlYWRSZXNvdXJjZVJlcXVlc3RTY2hlbWEsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICBjb25zdCB7IHVyaSB9ID0gcmVxdWVzdC5wYXJhbXM7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5yZXNvdXJjZUhhbmRsZXJzLmhhbmRsZVJlc291cmNlUmVxdWVzdCh1cmkpO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdHJhbnNwb3J0ID0gbmV3IFN0ZGlvU2VydmVyVHJhbnNwb3J0KCk7XG4gICAgYXdhaXQgdGhpcy5zZXJ2ZXIuY29ubmVjdCh0cmFuc3BvcnQpO1xuICAgIC8vIERvbid0IGxvZyB0byBzdGRlcnIgaW4gc3RkaW8gbW9kZSB0byBhdm9pZCBpbnRlcmZlcmluZyB3aXRoIE1DUCBwcm90b2NvbFxuICB9XG59XG4iLCJjb25zdCBfX1dFQlBBQ0tfTkFNRVNQQUNFX09CSkVDVF9fID0gcmVxdWlyZShcImV4cHJlc3NcIik7IiwiY29uc3QgX19XRUJQQUNLX05BTUVTUEFDRV9PQkpFQ1RfXyA9IHJlcXVpcmUoXCJjb3JzXCIpOyIsIi8qKlxuICogSFRUUCBTZXJ2ZXIgd2l0aCBTU0UgYW5kIFN0cmVhbWFibGUgSFRUUCBUcmFuc3BvcnQgU3VwcG9ydFxuICovXG5cbmltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IGNvcnMgZnJvbSAnY29ycyc7XG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHsgU2VydmVyIH0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zZXJ2ZXIvaW5kZXguanMnO1xuaW1wb3J0IHsgU1NFU2VydmVyVHJhbnNwb3J0IH0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zZXJ2ZXIvc3NlLmpzJztcbmltcG9ydCB7IFN0cmVhbWFibGVIVFRQU2VydmVyVHJhbnNwb3J0IH0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zZXJ2ZXIvc3RyZWFtYWJsZUh0dHAuanMnO1xuaW1wb3J0IHsgaXNJbml0aWFsaXplUmVxdWVzdCB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvdHlwZXMuanMnO1xuaW1wb3J0IHsgZ2V0Q29uZmlnIH0gZnJvbSAnLi4vc2hhcmVkL2NvbmZpZyc7XG5pbXBvcnQgeyBUb29sSGFuZGxlcnMgfSBmcm9tICcuL2hhbmRsZXJzL3Rvb2wuaGFuZGxlcnMnO1xuaW1wb3J0IHsgUmVzb3VyY2VIYW5kbGVycyB9IGZyb20gJy4vaGFuZGxlcnMvcmVzb3VyY2UuaGFuZGxlcnMnO1xuaW1wb3J0IHsgWEhTX1RPT0xfU0NIRU1BUywgWEhTX1JFU09VUkNFX1NDSEVNQVMgfSBmcm9tICcuL3NjaGVtYXMvdG9vbC5zY2hlbWFzJztcbmltcG9ydCB7XG4gIENhbGxUb29sUmVxdWVzdFNjaGVtYSxcbiAgTGlzdFRvb2xzUmVxdWVzdFNjaGVtYSxcbiAgTGlzdFJlc291cmNlc1JlcXVlc3RTY2hlbWEsXG4gIFJlYWRSZXNvdXJjZVJlcXVlc3RTY2hlbWEsXG59IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvdHlwZXMuanMnO1xuXG5leHBvcnQgY2xhc3MgWEhTSFRUUE1DUFNlcnZlciB7XG4gIHByaXZhdGUgYXBwOiBleHByZXNzLkFwcGxpY2F0aW9uO1xuICBwcml2YXRlIGNvbmZpZzogUmV0dXJuVHlwZTx0eXBlb2YgZ2V0Q29uZmlnPjtcbiAgcHJpdmF0ZSB0b29sSGFuZGxlcnM6IFRvb2xIYW5kbGVycztcbiAgcHJpdmF0ZSByZXNvdXJjZUhhbmRsZXJzOiBSZXNvdXJjZUhhbmRsZXJzO1xuICBwcml2YXRlIHRyYW5zcG9ydHM6IE1hcDxzdHJpbmcsIFNTRVNlcnZlclRyYW5zcG9ydCB8IFN0cmVhbWFibGVIVFRQU2VydmVyVHJhbnNwb3J0PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBwb3J0OiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IocG9ydDogbnVtYmVyID0gMzAwMCkge1xuICAgIHRoaXMucG9ydCA9IHBvcnQ7XG4gICAgdGhpcy5jb25maWcgPSBnZXRDb25maWcoKTtcbiAgICB0aGlzLnRvb2xIYW5kbGVycyA9IG5ldyBUb29sSGFuZGxlcnMoKTtcbiAgICB0aGlzLnJlc291cmNlSGFuZGxlcnMgPSBuZXcgUmVzb3VyY2VIYW5kbGVycygpO1xuICAgIHRoaXMuYXBwID0gZXhwcmVzcygpO1xuXG4gICAgdGhpcy5zZXR1cE1pZGRsZXdhcmUoKTtcbiAgICB0aGlzLnNldHVwUm91dGVzKCk7XG4gIH1cblxuICBwcml2YXRlIHNldHVwTWlkZGxld2FyZSgpOiB2b2lkIHtcbiAgICAvLyBQYXJzZSBKU09OIGJvZGllc1xuICAgIHRoaXMuYXBwLnVzZShleHByZXNzLmpzb24oKSk7XG5cbiAgICAvLyBDb25maWd1cmUgQ09SUyB0byBleHBvc2UgTWNwLVNlc3Npb24tSWQgaGVhZGVyIGZvciBicm93c2VyLWJhc2VkIGNsaWVudHNcbiAgICB0aGlzLmFwcC51c2UoXG4gICAgICBjb3JzKHtcbiAgICAgICAgb3JpZ2luOiAnKicsIC8vIEFsbG93IGFsbCBvcmlnaW5zIC0gYWRqdXN0IGFzIG5lZWRlZCBmb3IgcHJvZHVjdGlvblxuICAgICAgICBleHBvc2VkSGVhZGVyczogWydNY3AtU2Vzc2lvbi1JZCddLFxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cFJvdXRlcygpOiB2b2lkIHtcbiAgICAvLyBTdHJlYW1hYmxlIEhUVFAgVHJhbnNwb3J0IChQcm90b2NvbCB2ZXJzaW9uIDIwMjUtMDMtMjYpXG4gICAgdGhpcy5hcHAuYWxsKCcvbWNwJywgdGhpcy5oYW5kbGVTdHJlYW1hYmxlSFRUUC5iaW5kKHRoaXMpKTtcblxuICAgIC8vIERlcHJlY2F0ZWQgSFRUUCtTU0UgVHJhbnNwb3J0IChQcm90b2NvbCB2ZXJzaW9uIDIwMjQtMTEtMDUpXG4gICAgdGhpcy5hcHAuZ2V0KCcvc3NlJywgdGhpcy5oYW5kbGVTU0VDb25uZWN0aW9uLmJpbmQodGhpcykpO1xuICAgIHRoaXMuYXBwLnBvc3QoJy9tZXNzYWdlcycsIHRoaXMuaGFuZGxlU1NFTWVzc2FnZS5iaW5kKHRoaXMpKTtcblxuICAgIC8vIEhlYWx0aCBjaGVjayBlbmRwb2ludFxuICAgIHRoaXMuYXBwLmdldCgnL2hlYWx0aCcsIChyZXEsIHJlcykgPT4ge1xuICAgICAgcmVzLmpzb24oe1xuICAgICAgICBzdGF0dXM6ICdoZWFsdGh5JyxcbiAgICAgICAgc2VydmVyOiB0aGlzLmNvbmZpZy5zZXJ2ZXIubmFtZSxcbiAgICAgICAgdmVyc2lvbjogdGhpcy5jb25maWcuc2VydmVyLnZlcnNpb24sXG4gICAgICAgIHRyYW5zcG9ydHM6IFsnc3RyZWFtYWJsZS1odHRwJywgJ3NzZSddLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGhhbmRsZVN0cmVhbWFibGVIVFRQKHJlcTogZXhwcmVzcy5SZXF1ZXN0LCByZXM6IGV4cHJlc3MuUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zb2xlLmxvZyhgUmVjZWl2ZWQgJHtyZXEubWV0aG9kfSByZXF1ZXN0IHRvIC9tY3BgKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBDaGVjayBmb3IgZXhpc3Rpbmcgc2Vzc2lvbiBJRFxuICAgICAgY29uc3Qgc2Vzc2lvbklkID0gcmVxLmhlYWRlcnNbJ21jcC1zZXNzaW9uLWlkJ10gYXMgc3RyaW5nO1xuICAgICAgbGV0IHRyYW5zcG9ydDogU3RyZWFtYWJsZUhUVFBTZXJ2ZXJUcmFuc3BvcnQgfCB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChzZXNzaW9uSWQgJiYgdGhpcy50cmFuc3BvcnRzLmhhcyhzZXNzaW9uSWQpKSB7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nVHJhbnNwb3J0ID0gdGhpcy50cmFuc3BvcnRzLmdldChzZXNzaW9uSWQpO1xuICAgICAgICBpZiAoZXhpc3RpbmdUcmFuc3BvcnQgaW5zdGFuY2VvZiBTdHJlYW1hYmxlSFRUUFNlcnZlclRyYW5zcG9ydCkge1xuICAgICAgICAgIHRyYW5zcG9ydCA9IGV4aXN0aW5nVHJhbnNwb3J0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgICAgY29kZTogLTMyMDAwLFxuICAgICAgICAgICAgICBtZXNzYWdlOiAnQmFkIFJlcXVlc3Q6IFNlc3Npb24gZXhpc3RzIGJ1dCB1c2VzIGEgZGlmZmVyZW50IHRyYW5zcG9ydCBwcm90b2NvbCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaWQ6IG51bGwsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCFzZXNzaW9uSWQgJiYgcmVxLm1ldGhvZCA9PT0gJ1BPU1QnICYmIGlzSW5pdGlhbGl6ZVJlcXVlc3QocmVxLmJvZHkpKSB7XG4gICAgICAgIC8vIENyZWF0ZSBuZXcgU3RyZWFtYWJsZSBIVFRQIHRyYW5zcG9ydFxuICAgICAgICB0cmFuc3BvcnQgPSBuZXcgU3RyZWFtYWJsZUhUVFBTZXJ2ZXJUcmFuc3BvcnQoe1xuICAgICAgICAgIHNlc3Npb25JZEdlbmVyYXRvcjogKCk6IHN0cmluZyA9PiByYW5kb21VVUlEKCksXG4gICAgICAgICAgb25zZXNzaW9uaW5pdGlhbGl6ZWQ6IChzZXNzaW9uSWQ6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFN0cmVhbWFibGVIVFRQIHNlc3Npb24gaW5pdGlhbGl6ZWQgd2l0aCBJRDogJHtzZXNzaW9uSWR9YCk7XG4gICAgICAgICAgICB0aGlzLnRyYW5zcG9ydHMuc2V0KHNlc3Npb25JZCwgdHJhbnNwb3J0ISk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBvbnNlc3Npb25jbG9zZWQ6IChzZXNzaW9uSWQ6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFN0cmVhbWFibGVIVFRQIHNlc3Npb24gY2xvc2VkOiAke3Nlc3Npb25JZH1gKTtcbiAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0cy5kZWxldGUoc2Vzc2lvbklkKTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXQgdXAgb25jbG9zZSBoYW5kbGVyIHRvIGNsZWFuIHVwIHRyYW5zcG9ydCB3aGVuIGNsb3NlZFxuICAgICAgICB0cmFuc3BvcnQub25jbG9zZSA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgICBjb25zdCBzaWQgPSB0cmFuc3BvcnQhLnNlc3Npb25JZDtcbiAgICAgICAgICBpZiAoc2lkICYmIHRoaXMudHJhbnNwb3J0cy5oYXMoc2lkKSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFRyYW5zcG9ydCBjbG9zZWQgZm9yIHNlc3Npb24gJHtzaWR9LCByZW1vdmluZyBmcm9tIHRyYW5zcG9ydHMgbWFwYCk7XG4gICAgICAgICAgICB0aGlzLnRyYW5zcG9ydHMuZGVsZXRlKHNpZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIENvbm5lY3QgdGhlIHRyYW5zcG9ydCB0byB0aGUgTUNQIHNlcnZlclxuICAgICAgICBjb25zdCBzZXJ2ZXIgPSB0aGlzLmNyZWF0ZU1DUFNlcnZlcigpO1xuICAgICAgICBhd2FpdCBzZXJ2ZXIuY29ubmVjdCh0cmFuc3BvcnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSW52YWxpZCByZXF1ZXN0IC0gbm8gc2Vzc2lvbiBJRCBvciBub3QgaW5pdGlhbGl6YXRpb24gcmVxdWVzdFxuICAgICAgICByZXMuc3RhdHVzKDQwMCkuanNvbih7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgIGNvZGU6IC0zMjAwMCxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdCYWQgUmVxdWVzdDogTm8gdmFsaWQgc2Vzc2lvbiBJRCBwcm92aWRlZCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBpZDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gSGFuZGxlIHRoZSByZXF1ZXN0IHdpdGggdGhlIHRyYW5zcG9ydFxuICAgICAgYXdhaXQgdHJhbnNwb3J0LmhhbmRsZVJlcXVlc3QocmVxLCByZXMsIHJlcS5ib2R5KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaGFuZGxpbmcgU3RyZWFtYWJsZSBIVFRQIHJlcXVlc3Q6JywgZXJyb3IpO1xuICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzI2MDMsXG4gICAgICAgICAgICBtZXNzYWdlOiAnSW50ZXJuYWwgc2VydmVyIGVycm9yJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGhhbmRsZVNTRUNvbm5lY3Rpb24ocmVxOiBleHByZXNzLlJlcXVlc3QsIHJlczogZXhwcmVzcy5SZXNwb25zZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnNvbGUubG9nKCdSZWNlaXZlZCBHRVQgcmVxdWVzdCB0byAvc3NlIChkZXByZWNhdGVkIFNTRSB0cmFuc3BvcnQpJyk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJhbnNwb3J0ID0gbmV3IFNTRVNlcnZlclRyYW5zcG9ydCgnL21lc3NhZ2VzJywgcmVzKTtcbiAgICAgIHRoaXMudHJhbnNwb3J0cy5zZXQodHJhbnNwb3J0LnNlc3Npb25JZCwgdHJhbnNwb3J0KTtcblxuICAgICAgcmVzLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgdGhpcy50cmFuc3BvcnRzLmRlbGV0ZSh0cmFuc3BvcnQuc2Vzc2lvbklkKTtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzZXJ2ZXIgPSB0aGlzLmNyZWF0ZU1DUFNlcnZlcigpO1xuICAgICAgYXdhaXQgc2VydmVyLmNvbm5lY3QodHJhbnNwb3J0KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaGFuZGxpbmcgU1NFIGNvbm5lY3Rpb246JywgZXJyb3IpO1xuICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzI2MDMsXG4gICAgICAgICAgICBtZXNzYWdlOiAnSW50ZXJuYWwgc2VydmVyIGVycm9yJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGhhbmRsZVNTRU1lc3NhZ2UocmVxOiBleHByZXNzLlJlcXVlc3QsIHJlczogZXhwcmVzcy5SZXNwb25zZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHNlc3Npb25JZCA9IHJlcS5xdWVyeS5zZXNzaW9uSWQgYXMgc3RyaW5nO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRyYW5zcG9ydCA9IHRoaXMudHJhbnNwb3J0cy5nZXQoc2Vzc2lvbklkKTtcblxuICAgICAgaWYgKCF0cmFuc3BvcnQgfHwgISh0cmFuc3BvcnQgaW5zdGFuY2VvZiBTU0VTZXJ2ZXJUcmFuc3BvcnQpKSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtcbiAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgY29kZTogLTMyMDAwLFxuICAgICAgICAgICAgbWVzc2FnZTogJ0JhZCBSZXF1ZXN0OiBTZXNzaW9uIGV4aXN0cyBidXQgdXNlcyBhIGRpZmZlcmVudCB0cmFuc3BvcnQgcHJvdG9jb2wnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaWQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRyYW5zcG9ydC5oYW5kbGVQb3N0TWVzc2FnZShyZXEsIHJlcywgcmVxLmJvZHkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBoYW5kbGluZyBTU0UgbWVzc2FnZTonLCBlcnJvcik7XG4gICAgICBpZiAoIXJlcy5oZWFkZXJzU2VudCkge1xuICAgICAgICByZXMuc3RhdHVzKDUwMCkuanNvbih7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgIGNvZGU6IC0zMjYwMyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdJbnRlcm5hbCBzZXJ2ZXIgZXJyb3InLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaWQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlTUNQU2VydmVyKCk6IFNlcnZlciB7XG4gICAgY29uc3Qgc2VydmVyID0gbmV3IFNlcnZlcihcbiAgICAgIHtcbiAgICAgICAgbmFtZTogdGhpcy5jb25maWcuc2VydmVyLm5hbWUsXG4gICAgICAgIHZlcnNpb246IHRoaXMuY29uZmlnLnNlcnZlci52ZXJzaW9uLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgY2FwYWJpbGl0aWVzOiB7XG4gICAgICAgICAgdG9vbHM6IHt9LFxuICAgICAgICAgIHJlc291cmNlczoge30sXG4gICAgICAgIH0sXG4gICAgICB9XG4gICAgKTtcblxuICAgIC8vIFNldHVwIHRvb2wgaGFuZGxlcnNcbiAgICBzZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoQ2FsbFRvb2xSZXF1ZXN0U2NoZW1hLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgY29uc3QgeyBuYW1lLCBhcmd1bWVudHM6IGFyZ3MgfSA9IHJlcXVlc3QucGFyYW1zO1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMudG9vbEhhbmRsZXJzLmhhbmRsZVRvb2xSZXF1ZXN0KG5hbWUsIGFyZ3MpO1xuICAgIH0pO1xuXG4gICAgc2VydmVyLnNldFJlcXVlc3RIYW5kbGVyKExpc3RUb29sc1JlcXVlc3RTY2hlbWEsIGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvb2xzOiBYSFNfVE9PTF9TQ0hFTUFTLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIFNldHVwIHJlc291cmNlIGhhbmRsZXJzXG4gICAgc2VydmVyLnNldFJlcXVlc3RIYW5kbGVyKExpc3RSZXNvdXJjZXNSZXF1ZXN0U2NoZW1hLCBhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXNvdXJjZXM6IFhIU19SRVNPVVJDRV9TQ0hFTUFTLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihSZWFkUmVzb3VyY2VSZXF1ZXN0U2NoZW1hLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgY29uc3QgeyB1cmkgfSA9IHJlcXVlc3QucGFyYW1zO1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmVzb3VyY2VIYW5kbGVycy5oYW5kbGVSZXNvdXJjZVJlcXVlc3QodXJpKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBzZXJ2ZXI7XG4gIH1cblxuICBhc3luYyBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3Qgc2VydmVyID0gdGhpcy5hcHAubGlzdGVuKHRoaXMucG9ydCwgKGVycm9yPzogRXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIHN0YXJ0IEhUVFAgc2VydmVyOicsIGVycm9yKTtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUubG9nKGBYSFMgTUNQIEhUVFAgU2VydmVyIGxpc3RlbmluZyBvbiBwb3J0ICR7dGhpcy5wb3J0fWApO1xuICAgICAgICBjb25zb2xlLmxvZyhgXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5TVVBQT1JURUQgVFJBTlNQT1JUIE9QVElPTlM6XG5cbjEuIFN0cmVhbWFibGUgSFRUUCAoUHJvdG9jb2wgdmVyc2lvbjogMjAyNS0wMy0yNilcbiAgIEVuZHBvaW50OiAvbWNwXG4gICBNZXRob2RzOiBHRVQsIFBPU1QsIERFTEVURVxuICAgVXNhZ2U6XG4gICAgIC0gSW5pdGlhbGl6ZSB3aXRoIFBPU1QgdG8gL21jcFxuICAgICAtIEVzdGFibGlzaCBTU0Ugc3RyZWFtIHdpdGggR0VUIHRvIC9tY3BcbiAgICAgLSBTZW5kIHJlcXVlc3RzIHdpdGggUE9TVCB0byAvbWNwXG4gICAgIC0gVGVybWluYXRlIHNlc3Npb24gd2l0aCBERUxFVEUgdG8gL21jcFxuXG4yLiBIVFRQICsgU1NFIChQcm90b2NvbCB2ZXJzaW9uOiAyMDI0LTExLTA1KVxuICAgRW5kcG9pbnRzOiAvc3NlIChHRVQpIGFuZCAvbWVzc2FnZXMgKFBPU1QpXG4gICBVc2FnZTpcbiAgICAgLSBFc3RhYmxpc2ggU1NFIHN0cmVhbSB3aXRoIEdFVCB0byAvc3NlXG4gICAgIC0gU2VuZCByZXF1ZXN0cyB3aXRoIFBPU1QgdG8gL21lc3NhZ2VzP3Nlc3Npb25JZD08aWQ+XG5cbjMuIEhlYWx0aCBDaGVja1xuICAgRW5kcG9pbnQ6IC9oZWFsdGhcbiAgIE1ldGhvZDogR0VUXG4gICBVc2FnZTogQ2hlY2sgc2VydmVyIHN0YXR1cyBhbmQgc3VwcG9ydGVkIHRyYW5zcG9ydHNcbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmApO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gSGFuZGxlIHNlcnZlciBzaHV0ZG93blxuICAgICAgcHJvY2Vzcy5vbignU0lHSU5UJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnU2h1dHRpbmcgZG93biBIVFRQIHNlcnZlci4uLicpO1xuXG4gICAgICAgIC8vIENsb3NlIGFsbCBhY3RpdmUgdHJhbnNwb3J0cyB0byBwcm9wZXJseSBjbGVhbiB1cCByZXNvdXJjZXNcbiAgICAgICAgZm9yIChjb25zdCBbc2Vzc2lvbklkLCB0cmFuc3BvcnRdIG9mIHRoaXMudHJhbnNwb3J0cykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgQ2xvc2luZyB0cmFuc3BvcnQgZm9yIHNlc3Npb24gJHtzZXNzaW9uSWR9YCk7XG4gICAgICAgICAgICBhd2FpdCB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgY2xvc2luZyB0cmFuc3BvcnQgZm9yIHNlc3Npb24gJHtzZXNzaW9uSWR9OmAsIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRyYW5zcG9ydHMuY2xlYXIoKTtcbiAgICAgICAgc2VydmVyLmNsb3NlKCgpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnSFRUUCBzZXJ2ZXIgc2h1dGRvd24gY29tcGxldGUnKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHByb2Nlc3Mub24oJ1NJR1RFUk0nLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdTaHV0dGluZyBkb3duIEhUVFAgc2VydmVyLi4uJyk7XG5cbiAgICAgICAgLy8gQ2xvc2UgYWxsIGFjdGl2ZSB0cmFuc3BvcnRzIHRvIHByb3Blcmx5IGNsZWFuIHVwIHJlc291cmNlc1xuICAgICAgICBmb3IgKGNvbnN0IFtzZXNzaW9uSWQsIHRyYW5zcG9ydF0gb2YgdGhpcy50cmFuc3BvcnRzKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDbG9zaW5nIHRyYW5zcG9ydCBmb3Igc2Vzc2lvbiAke3Nlc3Npb25JZH1gKTtcbiAgICAgICAgICAgIGF3YWl0IHRyYW5zcG9ydC5jbG9zZSgpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciBjbG9zaW5nIHRyYW5zcG9ydCBmb3Igc2Vzc2lvbiAke3Nlc3Npb25JZH06YCwgZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudHJhbnNwb3J0cy5jbGVhcigpO1xuICAgICAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4ge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdIVFRQIHNlcnZlciBzaHV0ZG93biBjb21wbGV0ZScpO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQ2xvc2UgYWxsIGFjdGl2ZSB0cmFuc3BvcnRzXG4gICAgZm9yIChjb25zdCBbc2Vzc2lvbklkLCB0cmFuc3BvcnRdIG9mIHRoaXMudHJhbnNwb3J0cykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdHJhbnNwb3J0LmNsb3NlKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciBjbG9zaW5nIHRyYW5zcG9ydCBmb3Igc2Vzc2lvbiAke3Nlc3Npb25JZH06YCwgZXJyb3IpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnRyYW5zcG9ydHMuY2xlYXIoKTtcbiAgfVxufVxuIiwiLyoqXG4gKiBSZXF1ZXN0IGhhbmRsZXJzIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vdG9vbC5oYW5kbGVycyc7XG5leHBvcnQgKiBmcm9tICcuL3Jlc291cmNlLmhhbmRsZXJzJztcbiIsIi8qKlxuICogU2VydmVyIGltcGxlbWVudGF0aW9uIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vbWNwLnNlcnZlcic7XG5leHBvcnQgKiBmcm9tICcuL2h0dHAuc2VydmVyJztcbmV4cG9ydCAqIGZyb20gJy4vaGFuZGxlcnMvaW5kZXgnO1xuIiwiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuXG4vKipcbiAqIFVuaWZpZWQgQ0xJIGZvciBYaWFvSG9uZ1NodSBvcGVyYXRpb25zXG4gKi9cblxuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9hdXRoL2F1dGguc2VydmljZSc7XG5pbXBvcnQgcHVwcGV0ZWVyIGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBzcGF3blN5bmMgfSBmcm9tICdub2RlOmNoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0IHsgWEhTTUNQU2VydmVyLCBYSFNIVFRQTUNQU2VydmVyIH0gZnJvbSAnLi4vc2VydmVyL2luZGV4JztcbmltcG9ydCB7IFhIU19UT09MX1NDSEVNQVMgfSBmcm9tICcuLi9zZXJ2ZXIvc2NoZW1hcy90b29sLnNjaGVtYXMnO1xuaW1wb3J0IHsgRmVlZFNlcnZpY2UgfSBmcm9tICcuLi9jb3JlL2ZlZWRzL2ZlZWQuc2VydmljZSc7XG5pbXBvcnQgeyBQdWJsaXNoU2VydmljZSB9IGZyb20gJy4uL2NvcmUvcHVibGlzaGluZy9wdWJsaXNoLnNlcnZpY2UnO1xuaW1wb3J0IHsgTm90ZVNlcnZpY2UgfSBmcm9tICcuLi9jb3JlL25vdGVzL25vdGUuc2VydmljZSc7XG5cbi8qKlxuICogQ0xJIHV0aWxpdHkgZnVuY3Rpb25zXG4gKi9cbmNsYXNzIENMSVV0aWxzIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBwcm9ncmFtOiBDb21tYW5kKSB7fVxuXG4gIGZvcm1hdEVycm9yTWVzc2FnZShlcnJvcjogdW5rbm93bik6IHN0cmluZyB7XG4gICAgY29uc3QgcmF3ID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IChlcnJvci5zdGFjayA/PyBlcnJvci5tZXNzYWdlKSA6IFN0cmluZyhlcnJvcik7XG5cbiAgICAvLyBIYW5kbGUgc3BlY2lmaWMgZXJyb3IgcGF0dGVybnNcbiAgICBpZiAoL0V4ZWN1dGFibGUgZG9lc24ndCBleGlzdHxwdXBwZXRlZXIgYnJvd3NlcnMgaW5zdGFsbC9pLnRlc3QocmF3KSkge1xuICAgICAgcmV0dXJuICdDaHJvbWl1bSBpcyBub3QgaW5zdGFsbGVkLiBSdW46IG5weCBwdXBwZXRlZXIgYnJvd3NlcnMgaW5zdGFsbCBjaHJvbWUgb3IgeGhzLW1jcCBicm93c2VyJztcbiAgICB9XG5cbiAgICAvLyBGb3IgdXNlci1mYWNpbmcgZXJyb3JzLCBqdXN0IHJldHVybiB0aGUgbWVzc2FnZSB3aXRob3V0IHN0YWNrIHRyYWNlXG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIC8vIENoZWNrIGlmIGl0J3MgYSBrbm93biBlcnJvciB0eXBlIHRoYXQgc2hvdWxkIHNob3cganVzdCB0aGUgbWVzc2FnZVxuICAgICAgaWYgKFxuICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKCdFaXRoZXIgLS1ub3RlLWlkIG9yIC0tbGFzdC1wdWJsaXNoZWQgbXVzdCBiZSBzcGVjaWZpZWQnKSB8fFxuICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKCdQbGVhc2Ugc3BlY2lmeSBlaXRoZXInKSB8fFxuICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKCdVc2VyIG5vdCBsb2dnZWQgaW4nKSB8fFxuICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKCdOb3RlIG5vdCBmb3VuZCcpIHx8XG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ0RlbGV0ZSBidXR0b24gbm90IGZvdW5kJylcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gZXJyb3IubWVzc2FnZTtcbiAgICAgIH1cblxuICAgICAgLy8gRm9yIG90aGVyIGVycm9ycywgc2hvdyBhIGNsZWFuZXIgdmVyc2lvblxuICAgICAgY29uc3QgY29uZGVuc2VkID0gcmF3XG4gICAgICAgIC5yZXBsYWNlKFxuICAgICAgICAgIC9bXFxzXFxTXSo/TG9va3MgbGlrZSBQdXBwZXRlZXJbXFxzXFxTXSo/UGxlYXNlIHJ1biB0aGUgZm9sbG93aW5nIGNvbW1hbmQgdG8gZG93bmxvYWQgbmV3IGJyb3dzZXJzOltcXHNcXFNdKj9ucHggcHVwcGV0ZWVyIGJyb3dzZXJzIGluc3RhbGxbXFxzXFxTXSo/KFB1cHBldGVlciBUZWFtW1xcc1xcU10qPykqPy9tLFxuICAgICAgICAgICcnXG4gICAgICAgIClcbiAgICAgICAgLnJlcGxhY2UoL1tcXHUyNTAwLVxcdTI1N0ZdKy9nLCAnJykgLy8gYm94LWRyYXdpbmcgY2hhcmFjdGVyc1xuICAgICAgICAucmVwbGFjZSgvXFxzK2F0XFxzKy4qJC9nbSwgJycpIC8vIFJlbW92ZSBzdGFjayB0cmFjZSBsaW5lc1xuICAgICAgICAudHJpbSgpO1xuXG4gICAgICByZXR1cm4gY29uZGVuc2VkIHx8IGVycm9yLm1lc3NhZ2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIFN0cmluZyhlcnJvcik7XG4gIH1cblxuICB3cml0ZUpzb24ob3V0cHV0OiB1bmtub3duLCBleGl0Q29kZSA9IDApOiB2b2lkIHtcbiAgICBjb25zdCBjb21wYWN0ID0gdGhpcy5wcm9ncmFtLmdldE9wdGlvblZhbHVlPy4oJ2NvbXBhY3QnKSA9PT0gdHJ1ZTtcbiAgICBjb25zdCBqc29uID0gY29tcGFjdCA/IEpTT04uc3RyaW5naWZ5KG91dHB1dCkgOiBKU09OLnN0cmluZ2lmeShvdXRwdXQsIG51bGwsIDIpO1xuICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGAke2pzb259XFxuYCk7XG4gICAgcHJvY2Vzcy5leGl0KGV4aXRDb2RlKTtcbiAgfVxuXG4gIHByaW50U3VjY2VzcyhyZXN1bHQ6IHVua25vd24sIG1lc3NhZ2U/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}");
|
|
88
|
-
|
|
89
|
-
/***/ }),
|
|
90
|
-
|
|
91
|
-
/***/ 6928:
|
|
92
|
-
/***/ ((module) => {
|
|
93
|
-
|
|
94
|
-
module.exports = require("path");
|
|
95
|
-
|
|
96
|
-
/***/ }),
|
|
97
|
-
|
|
98
|
-
/***/ 7016:
|
|
99
|
-
/***/ ((module) => {
|
|
100
|
-
|
|
101
|
-
module.exports = require("url");
|
|
102
|
-
|
|
103
|
-
/***/ }),
|
|
104
|
-
|
|
105
|
-
/***/ 7482:
|
|
106
|
-
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
107
|
-
|
|
108
|
-
eval("{\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n NoteService: () => (/* binding */ NoteService)\n});\n\n// EXTERNAL MODULE: ./src/shared/base.service.ts + 2 modules\nvar base_service = __webpack_require__(3100);\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// EXTERNAL MODULE: ./src/shared/errors.ts\nvar errors = __webpack_require__(7636);\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 * 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) {\n super(config);\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 this.navigateToCreatorCenter(page);\n await this.verifyUserAuthentication(page);\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 this.navigateToCreatorCenter(page);\n await this.verifyUserAuthentication(page);\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 * Navigate to creator center note manager\n */\n async navigateToCreatorCenter(page) {\n try {\n const creatorCenterUrl = 'https://creator.xiaohongshu.com/new/note-manager?source=official';\n await this.getBrowserManager().navigateWithRetry(page, creatorCenterUrl);\n await (0,utils/* sleep */.yy)(5000); // Wait longer for page to load completely\n // Debug: Log page content to understand the structure\n const pageContent = await page.evaluate(() => {\n const noteElements = document.querySelectorAll('div.note, [class*=\"note\"], [data-impression]');\n const allButtons = document.querySelectorAll('button, [role=\"button\"], .btn, [class*=\"button\"]');\n const allLinks = document.querySelectorAll('a[href*=\"/explore/\"]');\n return {\n totalNoteElements: noteElements.length,\n noteElementClasses: Array.from(noteElements).map(el => el.className),\n totalButtons: allButtons.length,\n buttonTexts: Array.from(allButtons).slice(0, 10).map(btn => btn.textContent?.trim()).filter(Boolean),\n buttonClasses: Array.from(allButtons).slice(0, 10).map(btn => btn.className),\n exploreLinks: Array.from(allLinks).map(link => link.getAttribute('href')),\n pageTitle: document.title,\n currentUrl: window.location.href\n };\n });\n logger/* logger */.v.info(`Page loaded: ${JSON.stringify(pageContent, null, 2)}`);\n }\n catch (error) {\n throw new errors/* DeleteError */.GU('Failed to navigate to creator center', { url: 'https://creator.xiaohongshu.com/new/note-manager?source=official' }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Verify user is authenticated\n */\n async verifyUserAuthentication(page) {\n try {\n // Check for login elements on the current page\n const loginElements = await page.$$(this.getConfig().xhs.loginOkSelector);\n // Also check for creator center specific elements\n const creatorElements = await page.$$('[class*=\"user\"], [class*=\"profile\"], [class*=\"avatar\"]');\n if (loginElements.length === 0 && creatorElements.length === 0) {\n // Check if we're on a login page\n const currentUrl = page.url();\n if (currentUrl.includes('login') || currentUrl.includes('signin')) {\n throw new errors/* NotLoggedInError */.bG('User not logged in', {\n operation: 'deleteNote',\n url: currentUrl,\n });\n }\n // For creator center, check if we can see note management elements\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', {\n operation: 'deleteNote',\n url: currentUrl,\n });\n }\n }\n }\n catch (error) {\n if (error instanceof errors/* NotLoggedInError */.bG) {\n throw error;\n }\n throw new errors/* DeleteError */.GU('Failed to verify authentication', { operation: 'verifyAuth' }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Find and delete a specific note by ID\n */\n async findAndDeleteNote(page, noteId) {\n try {\n const result = await page.evaluate((selectors, targetNoteId) => {\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: targetNoteId, title: '', found: false, error: 'No note elements found on page' };\n }\n for (const noteElement of noteElements) {\n // Check if this is the note we want to delete\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 (e) {\n // Ignore parsing errors\n }\n }\n // Also try to find note ID in other attributes or data\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 // Found the target note, try to delete it\n const titleElement = noteElement.querySelector('[class*=\"title\"], [class*=\"name\"]');\n const title = titleElement?.textContent?.trim() || 'Unknown';\n // Look for delete button or more options button\n let deleteButton = null;\n // Try each delete button selector\n for (const selector of selectors.DELETE_BUTTON) {\n deleteButton = noteElement.querySelector(selector);\n if (deleteButton) {\n break;\n }\n }\n if (!deleteButton) {\n // Try to find more options button first\n let moreButton = null;\n for (const selector of selectors.MORE_OPTIONS) {\n moreButton = noteElement.querySelector(selector);\n if (moreButton) {\n break;\n }\n }\n if (moreButton) {\n moreButton.click();\n // Wait for dropdown to appear and look for delete option\n setTimeout(() => {\n for (const selector of selectors.DROPDOWN_MENU) {\n const dropdown = document.querySelector(selector);\n if (dropdown) {\n for (const deleteSelector of selectors.DELETE_BUTTON) {\n deleteButton = dropdown.querySelector(deleteSelector);\n if (deleteButton) {\n break;\n }\n }\n if (deleteButton)\n break;\n }\n }\n }, 1000);\n }\n }\n if (deleteButton) {\n deleteButton.click();\n return { noteId: currentNoteId, title, found: true };\n }\n else {\n return { noteId: currentNoteId, title, found: false, error: 'Delete button not found' };\n }\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 // 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 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 // Look for delete button or more options button\n let deleteButton = null;\n // Try each delete button selector\n for (const selector of selectors.DELETE_BUTTON) {\n deleteButton = firstNote.querySelector(selector);\n if (deleteButton) {\n break;\n }\n }\n if (!deleteButton) {\n // Try to find more options button first\n let moreButton = null;\n for (const selector of selectors.MORE_OPTIONS) {\n moreButton = firstNote.querySelector(selector);\n if (moreButton) {\n break;\n }\n }\n if (moreButton) {\n moreButton.click();\n // Wait for dropdown to appear and look for delete option\n setTimeout(() => {\n for (const selector of selectors.DROPDOWN_MENU) {\n const dropdown = document.querySelector(selector);\n if (dropdown) {\n for (const deleteSelector of selectors.DELETE_BUTTON) {\n deleteButton = dropdown.querySelector(deleteSelector);\n if (deleteButton) {\n break;\n }\n }\n if (deleteButton)\n break;\n }\n }\n }, 1000);\n }\n }\n if (deleteButton) {\n deleteButton.click();\n return { noteId, title, found: true };\n }\n else {\n return { noteId, title, found: false, error: 'Delete button not found' };\n }\n }, DELETE_SELECTORS);\n if (!result.found) {\n throw new errors/* DeleteError */.GU(result.error || 'Failed to find delete button', {});\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) {\n super(config);\n this.deleteService = new DeleteService(config);\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 this.navigateToCreatorCenter(page);\n await this.verifyUserAuthentication(page);\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 * Navigate to creator center note manager\n */\n async navigateToCreatorCenter(page) {\n try {\n const creatorCenterUrl = 'https://creator.xiaohongshu.com/new/note-manager?source=official';\n await this.getBrowserManager().navigateWithRetry(page, creatorCenterUrl);\n await (0,utils/* sleep */.yy)(3000); // Wait for page to load completely\n }\n catch (error) {\n throw new errors/* NoteParsingError */.Vb('Failed to navigate to creator center', { url: 'https://creator.xiaohongshu.com/new/note-manager?source=official' }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Verify user is authenticated\n */\n async verifyUserAuthentication(page) {\n try {\n // Check for login elements on the current page\n const loginElements = await page.$$(this.getConfig().xhs.loginOkSelector);\n // Also check for creator center specific elements\n const creatorElements = await page.$$('[class*=\"user\"], [class*=\"profile\"], [class*=\"avatar\"]');\n if (loginElements.length === 0 && creatorElements.length === 0) {\n // Check if we're on a login page\n const currentUrl = page.url();\n if (currentUrl.includes('login') || currentUrl.includes('signin')) {\n throw new errors/* NotLoggedInError */.bG('User not logged in', {\n operation: 'getUserNotes',\n url: currentUrl,\n });\n }\n // For creator center, check if we can see note management elements\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', {\n operation: 'getUserNotes',\n url: currentUrl,\n });\n }\n }\n }\n catch (error) {\n if (error instanceof errors/* NotLoggedInError */.bG) {\n throw error;\n }\n throw new errors/* NoteParsingError */.Vb('Failed to verify authentication', { operation: 'verifyAuth' }, error instanceof Error ? error : new Error(String(error)));\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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aEQsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLHVCQUF1QixDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7Q0FDRiIsInNvdXJjZXMiOlsid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9kZWxldGluZy9kZWxldGUuc2VydmljZS50cz8wMzA5Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9ub3Rlcy9ub3RlLnNlcnZpY2UudHM/MWI2NiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIERlbGV0ZSBzZXJ2aWNlIGZvciBYSFMgTUNQIFNlcnZlclxuICogSGFuZGxlcyBub3RlIGRlbGV0aW9uIG9wZXJhdGlvbnNcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IENvbmZpZywgWEhTUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgQmFzZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvYmFzZS5zZXJ2aWNlJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgRGVsZXRlRXJyb3IsIE5vdExvZ2dlZEluRXJyb3IgfSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IFBhZ2UgfSBmcm9tICdwdXBwZXRlZXInO1xuaW1wb3J0IHsgQ09NTU9OX0JVVFRPTl9TRUxFQ1RPUlMsIENPTU1PTl9NT0RBTF9TRUxFQ1RPUlMgfSBmcm9tICcuLi8uLi9zaGFyZWQvc2VsZWN0b3JzJztcblxuZXhwb3J0IGludGVyZmFjZSBEZWxldGVSZXN1bHQgZXh0ZW5kcyBYSFNSZXNwb25zZTxudWxsPiB7XG4gIHJlYWRvbmx5IG5vdGVJZD86IHN0cmluZztcbiAgcmVhZG9ubHkgdGl0bGU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRlbGV0ZWRBdDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlbGV0ZU9wdGlvbnMge1xuICBub3RlSWQ/OiBzdHJpbmc7XG4gIGxhc3RQdWJsaXNoZWQ/OiBib29sZWFuO1xuICBicm93c2VyUGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBDU1Mgc2VsZWN0b3JzIGZvciBkZWxldGUgb3BlcmF0aW9ucyAtIHVwZGF0ZWQgZm9yIGN1cnJlbnQgWGlhb0hvbmdTaHUgaW50ZXJmYWNlXG4gKi9cbmNvbnN0IERFTEVURV9TRUxFQ1RPUlMgPSB7XG4gIE5PVEVfSVRFTTogW1xuICAgICdkaXYubm90ZScsXG4gICAgJy5ub3RlLWl0ZW0nLFxuICAgICdbY2xhc3MqPVwibm90ZVwiXScsXG4gICAgJ1tkYXRhLWltcHJlc3Npb25dJyxcbiAgICAnLmNyZWF0b3Itbm90ZS1pdGVtJyxcbiAgICAnLm5vdGUtY2FyZCcsXG4gICAgJy5jb250ZW50LWl0ZW0nXG4gIF0sXG4gIERFTEVURV9CVVRUT046IFtcbiAgICAnLmNvbnRyb2wuZGF0YS1kZWwnLFxuICAgICdzcGFuLmNvbnRyb2wuZGF0YS1kZWwnLFxuICAgIC4uLkNPTU1PTl9CVVRUT05fU0VMRUNUT1JTLkRFTEVURVxuICBdLFxuICBDT05GSVJNX0JVVFRPTjogQ09NTU9OX0JVVFRPTl9TRUxFQ1RPUlMuQ09ORklSTSxcbiAgQ0FOQ0VMX0JVVFRPTjogQ09NTU9OX0JVVFRPTl9TRUxFQ1RPUlMuQ0FOQ0VMLFxuICBNT1JFX09QVElPTlM6IENPTU1PTl9CVVRUT05fU0VMRUNUT1JTLk1PUkVfT1BUSU9OUyxcbiAgRFJPUERPV05fTUVOVTogQ09NTU9OX01PREFMX1NFTEVDVE9SUy5EUk9QRE9XTl9NRU5VLFxuICBNT0RBTF9DT05GSVJNOiBDT01NT05fTU9EQUxfU0VMRUNUT1JTLkNPTkZJUk0sXG4gIE1PREFMX0NBTkNFTDogQ09NTU9OX01PREFMX1NFTEVDVE9SUy5DQU5DRUwsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgY2xhc3MgRGVsZXRlU2VydmljZSBleHRlbmRzIEJhc2VTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcpIHtcbiAgICBzdXBlcihjb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBhIHNwZWNpZmljIG5vdGUgYnkgSURcbiAgICogQHBhcmFtIG5vdGVJZCAtIFRoZSBJRCBvZiB0aGUgbm90ZSB0byBkZWxldGVcbiAgICogQHBhcmFtIGJyb3dzZXJQYXRoIC0gT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgcGF0aFxuICAgKiBAcmV0dXJucyBQcm9taXNlPERlbGV0ZVJlc3VsdD4gLSBEZWxldGUgb3BlcmF0aW9uIHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgZGVsZXRlTm90ZShub3RlSWQ6IHN0cmluZywgYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPERlbGV0ZVJlc3VsdD4ge1xuICAgIHRoaXMudmFsaWRhdGVEZWxldGVQYXJhbXMobm90ZUlkKTtcblxuICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZSh0cnVlLCBicm93c2VyUGF0aCwgdHJ1ZSk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gTmF2aWdhdGUgdG8gY3JlYXRvciBjZW50ZXIgbm90ZSBtYW5hZ2VyXG4gICAgICBhd2FpdCB0aGlzLm5hdmlnYXRlVG9DcmVhdG9yQ2VudGVyKHBhZ2UpO1xuICAgICAgYXdhaXQgdGhpcy52ZXJpZnlVc2VyQXV0aGVudGljYXRpb24ocGFnZSk7XG5cbiAgICAgIC8vIEZpbmQgYW5kIGRlbGV0ZSB0aGUgc3BlY2lmaWMgbm90ZVxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5maW5kQW5kRGVsZXRlTm90ZShwYWdlLCBub3RlSWQpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICBkYXRhOiBudWxsLFxuICAgICAgICBub3RlSWQ6IHJlc3VsdC5ub3RlSWQsXG4gICAgICAgIHRpdGxlOiByZXN1bHQudGl0bGUsXG4gICAgICAgIGRlbGV0ZWRBdDogRGF0ZS5ub3coKSxcbiAgICAgICAgbWVzc2FnZTogYFN1Y2Nlc3NmdWxseSBkZWxldGVkIG5vdGUgXCIke3Jlc3VsdC50aXRsZX1cIiAoSUQ6ICR7cmVzdWx0Lm5vdGVJZH0pYCxcbiAgICAgICAgb3BlcmF0aW9uOiAnZGVsZXRlTm90ZScsXG4gICAgICB9IGFzIHVua25vd24gYXMgRGVsZXRlUmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBkZWxldGUgbm90ZSAke25vdGVJZH06ICR7ZXJyb3J9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgZGF0YTogbnVsbCxcbiAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgbWVzc2FnZTogYEZhaWxlZCB0byBkZWxldGUgbm90ZTogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCxcbiAgICAgICAgZGVsZXRlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgICBvcGVyYXRpb246ICdkZWxldGVOb3RlJyxcbiAgICAgIH0gYXMgdW5rbm93biBhcyBEZWxldGVSZXN1bHQ7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIHRoZSBsYXN0IHB1Ymxpc2hlZCBub3RlXG4gICAqIEBwYXJhbSBicm93c2VyUGF0aCAtIE9wdGlvbmFsIGN1c3RvbSBicm93c2VyIHBhdGhcbiAgICogQHJldHVybnMgUHJvbWlzZTxEZWxldGVSZXN1bHQ+IC0gRGVsZXRlIG9wZXJhdGlvbiByZXN1bHRcbiAgICovXG4gIGFzeW5jIGRlbGV0ZUxhc3RQdWJsaXNoZWROb3RlKGJyb3dzZXJQYXRoPzogc3RyaW5nKTogUHJvbWlzZTxEZWxldGVSZXN1bHQ+IHtcbiAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UodHJ1ZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIE5hdmlnYXRlIHRvIGNyZWF0b3IgY2VudGVyIG5vdGUgbWFuYWdlclxuICAgICAgYXdhaXQgdGhpcy5uYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlcihwYWdlKTtcbiAgICAgIGF3YWl0IHRoaXMudmVyaWZ5VXNlckF1dGhlbnRpY2F0aW9uKHBhZ2UpO1xuXG4gICAgICAvLyBGaW5kIGFuZCBkZWxldGUgdGhlIGxhc3QgcHVibGlzaGVkIG5vdGVcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZmluZEFuZERlbGV0ZUxhc3ROb3RlKHBhZ2UpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICBkYXRhOiBudWxsLFxuICAgICAgICBub3RlSWQ6IHJlc3VsdC5ub3RlSWQsXG4gICAgICAgIHRpdGxlOiByZXN1bHQudGl0bGUsXG4gICAgICAgIGRlbGV0ZWRBdDogRGF0ZS5ub3coKSxcbiAgICAgICAgbWVzc2FnZTogYFN1Y2Nlc3NmdWxseSBkZWxldGVkIGxhc3QgcHVibGlzaGVkIG5vdGUgXCIke3Jlc3VsdC50aXRsZX1cIiAoSUQ6ICR7cmVzdWx0Lm5vdGVJZH0pYCxcbiAgICAgICAgb3BlcmF0aW9uOiAnZGVsZXRlTGFzdFB1Ymxpc2hlZE5vdGUnLFxuICAgICAgfSBhcyB1bmtub3duIGFzIERlbGV0ZVJlc3VsdDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZGVsZXRlIGxhc3QgcHVibGlzaGVkIG5vdGU6ICR7ZXJyb3J9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgZGF0YTogbnVsbCxcbiAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgbWVzc2FnZTogYEZhaWxlZCB0byBkZWxldGUgbGFzdCBwdWJsaXNoZWQgbm90ZTogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCxcbiAgICAgICAgZGVsZXRlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgICBvcGVyYXRpb246ICdkZWxldGVMYXN0UHVibGlzaGVkTm90ZScsXG4gICAgICB9IGFzIHVua25vd24gYXMgRGVsZXRlUmVzdWx0O1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGRlbGV0ZSBwYXJhbWV0ZXJzXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlRGVsZXRlUGFyYW1zKG5vdGVJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFub3RlSWQgfHwgbm90ZUlkLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBEZWxldGVFcnJvcignTm90ZSBJRCBpcyByZXF1aXJlZCcsIHsgbm90ZUlkIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOYXZpZ2F0ZSB0byBjcmVhdG9yIGNlbnRlciBub3RlIG1hbmFnZXJcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgbmF2aWdhdGVUb0NyZWF0b3JDZW50ZXIocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjcmVhdG9yQ2VudGVyVXJsID0gJ2h0dHBzOi8vY3JlYXRvci54aWFvaG9uZ3NodS5jb20vbmV3L25vdGUtbWFuYWdlcj9zb3VyY2U9b2ZmaWNpYWwnO1xuICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIGNyZWF0b3JDZW50ZXJVcmwpO1xuICAgICAgYXdhaXQgc2xlZXAoNTAwMCk7IC8vIFdhaXQgbG9uZ2VyIGZvciBwYWdlIHRvIGxvYWQgY29tcGxldGVseVxuXG4gICAgICAvLyBEZWJ1ZzogTG9nIHBhZ2UgY29udGVudCB0byB1bmRlcnN0YW5kIHRoZSBzdHJ1Y3R1cmVcbiAgICAgIGNvbnN0IHBhZ2VDb250ZW50ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAgIGNvbnN0IG5vdGVFbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2Rpdi5ub3RlLCBbY2xhc3MqPVwibm90ZVwiXSwgW2RhdGEtaW1wcmVzc2lvbl0nKTtcbiAgICAgICAgY29uc3QgYWxsQnV0dG9ucyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2J1dHRvbiwgW3JvbGU9XCJidXR0b25cIl0sIC5idG4sIFtjbGFzcyo9XCJidXR0b25cIl0nKTtcbiAgICAgICAgY29uc3QgYWxsTGlua3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdhW2hyZWYqPVwiL2V4cGxvcmUvXCJdJyk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0b3RhbE5vdGVFbGVtZW50czogbm90ZUVsZW1lbnRzLmxlbmd0aCxcbiAgICAgICAgICBub3RlRWxlbWVudENsYXNzZXM6IEFycmF5LmZyb20obm90ZUVsZW1lbnRzKS5tYXAoZWwgPT4gZWwuY2xhc3NOYW1lKSxcbiAgICAgICAgICB0b3RhbEJ1dHRvbnM6IGFsbEJ1dHRvbnMubGVuZ3RoLFxuICAgICAgICAgIGJ1dHRvblRleHRzOiBBcnJheS5mcm9tKGFsbEJ1dHRvbnMpLnNsaWNlKDAsIDEwKS5tYXAoYnRuID0+IGJ0bi50ZXh0Q29udGVudD8udHJpbSgpKS5maWx0ZXIoQm9vbGVhbiksXG4gICAgICAgICAgYnV0dG9uQ2xhc3NlczogQXJyYXkuZnJvbShhbGxCdXR0b25zKS5zbGljZSgwLCAxMCkubWFwKGJ0biA9PiBidG4uY2xhc3NOYW1lKSxcbiAgICAgICAgICBleHBsb3JlTGlua3M6IEFycmF5LmZyb20oYWxsTGlua3MpLm1hcChsaW5rID0+IGxpbmsuZ2V0QXR0cmlidXRlKCdocmVmJykpLFxuICAgICAgICAgIHBhZ2VUaXRsZTogZG9jdW1lbnQudGl0bGUsXG4gICAgICAgICAgY3VycmVudFVybDogd2luZG93LmxvY2F0aW9uLmhyZWZcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuXG4gICAgICBsb2dnZXIuaW5mbyhgUGFnZSBsb2FkZWQ6ICR7SlNPTi5zdHJpbmdpZnkocGFnZUNvbnRlbnQsIG51bGwsIDIpfWApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IoXG4gICAgICAgICdGYWlsZWQgdG8gbmF2aWdhdGUgdG8gY3JlYXRvciBjZW50ZXInLFxuICAgICAgICB7IHVybDogJ2h0dHBzOi8vY3JlYXRvci54aWFvaG9uZ3NodS5jb20vbmV3L25vdGUtbWFuYWdlcj9zb3VyY2U9b2ZmaWNpYWwnIH0sXG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IHVzZXIgaXMgYXV0aGVudGljYXRlZFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB2ZXJpZnlVc2VyQXV0aGVudGljYXRpb24ocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBDaGVjayBmb3IgbG9naW4gZWxlbWVudHMgb24gdGhlIGN1cnJlbnQgcGFnZVxuICAgICAgY29uc3QgbG9naW5FbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQodGhpcy5nZXRDb25maWcoKS54aHMubG9naW5Pa1NlbGVjdG9yKTtcblxuICAgICAgLy8gQWxzbyBjaGVjayBmb3IgY3JlYXRvciBjZW50ZXIgc3BlY2lmaWMgZWxlbWVudHNcbiAgICAgIGNvbnN0IGNyZWF0b3JFbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoXG4gICAgICAgICdbY2xhc3MqPVwidXNlclwiXSwgW2NsYXNzKj1cInByb2ZpbGVcIl0sIFtjbGFzcyo9XCJhdmF0YXJcIl0nXG4gICAgICApO1xuXG4gICAgICBpZiAobG9naW5FbGVtZW50cy5sZW5ndGggPT09IDAgJiYgY3JlYXRvckVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAvLyBDaGVjayBpZiB3ZSdyZSBvbiBhIGxvZ2luIHBhZ2VcbiAgICAgICAgY29uc3QgY3VycmVudFVybCA9IHBhZ2UudXJsKCk7XG4gICAgICAgIGlmIChjdXJyZW50VXJsLmluY2x1ZGVzKCdsb2dpbicpIHx8IGN1cnJlbnRVcmwuaW5jbHVkZXMoJ3NpZ25pbicpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vdExvZ2dlZEluRXJyb3IoJ1VzZXIgbm90IGxvZ2dlZCBpbicsIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbjogJ2RlbGV0ZU5vdGUnLFxuICAgICAgICAgICAgdXJsOiBjdXJyZW50VXJsLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIGNyZWF0b3IgY2VudGVyLCBjaGVjayBpZiB3ZSBjYW4gc2VlIG5vdGUgbWFuYWdlbWVudCBlbGVtZW50c1xuICAgICAgICBjb25zdCBub3RlRWxlbWVudHMgPSBhd2FpdCBwYWdlLiQkKCdkaXYubm90ZScpO1xuICAgICAgICBpZiAobm90ZUVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBOb3RMb2dnZWRJbkVycm9yKCdVc2VyIG5vdCBsb2dnZWQgaW4gb3Igbm8gbm90ZXMgZm91bmQnLCB7XG4gICAgICAgICAgICBvcGVyYXRpb246ICdkZWxldGVOb3RlJyxcbiAgICAgICAgICAgIHVybDogY3VycmVudFVybCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb3RMb2dnZWRJbkVycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IERlbGV0ZUVycm9yKFxuICAgICAgICAnRmFpbGVkIHRvIHZlcmlmeSBhdXRoZW50aWNhdGlvbicsXG4gICAgICAgIHsgb3BlcmF0aW9uOiAndmVyaWZ5QXV0aCcgfSxcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGFuZCBkZWxldGUgYSBzcGVjaWZpYyBub3RlIGJ5IElEXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGZpbmRBbmREZWxldGVOb3RlKHBhZ2U6IFBhZ2UsIG5vdGVJZDogc3RyaW5nKTogUHJvbWlzZTx7IG5vdGVJZDogc3RyaW5nOyB0aXRsZTogc3RyaW5nIH0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZShcbiAgICAgICAgKHNlbGVjdG9yczogdHlwZW9mIERFTEVURV9TRUxFQ1RPUlMsIHRhcmdldE5vdGVJZDogc3RyaW5nKSA9PiB7XG5cbiAgICAgICAgICAvLyBUcnkgZWFjaCBub3RlIGl0ZW0gc2VsZWN0b3JcbiAgICAgICAgICBsZXQgbm90ZUVsZW1lbnRzOiBFbGVtZW50W10gPSBbXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycy5OT1RFX0lURU0pIHtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XG4gICAgICAgICAgICBpZiAoZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBub3RlRWxlbWVudHMgPSBlbGVtZW50cztcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG5vdGVFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogdGFyZ2V0Tm90ZUlkLCB0aXRsZTogJycsIGZvdW5kOiBmYWxzZSwgZXJyb3I6ICdObyBub3RlIGVsZW1lbnRzIGZvdW5kIG9uIHBhZ2UnIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yIChjb25zdCBub3RlRWxlbWVudCBvZiBub3RlRWxlbWVudHMpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgdGhlIG5vdGUgd2Ugd2FudCB0byBkZWxldGVcbiAgICAgICAgICAgIGNvbnN0IGltcHJlc3Npb25EYXRhID0gbm90ZUVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWltcHJlc3Npb24nKTtcbiAgICAgICAgICAgIGxldCBjdXJyZW50Tm90ZUlkID0gJyc7XG5cbiAgICAgICAgICAgIGlmIChpbXByZXNzaW9uRGF0YSkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoaW1wcmVzc2lvbkRhdGEpO1xuICAgICAgICAgICAgICAgIGN1cnJlbnROb3RlSWQgPSBwYXJzZWQ/Lm5vdGVUYXJnZXQ/LnZhbHVlPy5ub3RlSWQgfHwgJyc7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBJZ25vcmUgcGFyc2luZyBlcnJvcnNcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBbHNvIHRyeSB0byBmaW5kIG5vdGUgSUQgaW4gb3RoZXIgYXR0cmlidXRlcyBvciBkYXRhXG4gICAgICAgICAgICBpZiAoIWN1cnJlbnROb3RlSWQpIHtcbiAgICAgICAgICAgICAgY29uc3QgbGlua0VsZW1lbnQgPSBub3RlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdhW2hyZWYqPVwiL2V4cGxvcmUvXCJdLCBhW2hyZWYqPVwiL25vdGUvXCJdJyk7XG4gICAgICAgICAgICAgIGlmIChsaW5rRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhyZWYgPSBsaW5rRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSB8fCAnJztcbiAgICAgICAgICAgICAgICBjb25zdCBtYXRjaCA9IGhyZWYubWF0Y2goL1xcL2V4cGxvcmVcXC8oW2EtekEtWjAtOV0rKS8pO1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgY3VycmVudE5vdGVJZCA9IG1hdGNoWzFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY3VycmVudE5vdGVJZCA9PT0gdGFyZ2V0Tm90ZUlkKSB7XG4gICAgICAgICAgICAgIC8vIEZvdW5kIHRoZSB0YXJnZXQgbm90ZSwgdHJ5IHRvIGRlbGV0ZSBpdFxuICAgICAgICAgICAgICBjb25zdCB0aXRsZUVsZW1lbnQgPSBub3RlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdbY2xhc3MqPVwidGl0bGVcIl0sIFtjbGFzcyo9XCJuYW1lXCJdJyk7XG4gICAgICAgICAgICAgIGNvbnN0IHRpdGxlID0gdGl0bGVFbGVtZW50Py50ZXh0Q29udGVudD8udHJpbSgpIHx8ICdVbmtub3duJztcblxuICAgICAgICAgICAgICAvLyBMb29rIGZvciBkZWxldGUgYnV0dG9uIG9yIG1vcmUgb3B0aW9ucyBidXR0b25cbiAgICAgICAgICAgICAgbGV0IGRlbGV0ZUJ1dHRvbjogRWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gICAgICAgICAgICAgIC8vIFRyeSBlYWNoIGRlbGV0ZSBidXR0b24gc2VsZWN0b3JcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuREVMRVRFX0JVVFRPTikge1xuICAgICAgICAgICAgICAgIGRlbGV0ZUJ1dHRvbiA9IG5vdGVFbGVtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgIGlmIChkZWxldGVCdXR0b24pIHtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmICghZGVsZXRlQnV0dG9uKSB7XG4gICAgICAgICAgICAgICAgLy8gVHJ5IHRvIGZpbmQgbW9yZSBvcHRpb25zIGJ1dHRvbiBmaXJzdFxuICAgICAgICAgICAgICAgIGxldCBtb3JlQnV0dG9uOiBFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuTU9SRV9PUFRJT05TKSB7XG4gICAgICAgICAgICAgICAgICBtb3JlQnV0dG9uID0gbm90ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgICAgICAgICAgICAgICBpZiAobW9yZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAobW9yZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgICAgKG1vcmVCdXR0b24gYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCk7XG5cbiAgICAgICAgICAgICAgICAgIC8vIFdhaXQgZm9yIGRyb3Bkb3duIHRvIGFwcGVhciBhbmQgbG9vayBmb3IgZGVsZXRlIG9wdGlvblxuICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2Ygc2VsZWN0b3JzLkRST1BET1dOX01FTlUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkcm9wZG93biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChkcm9wZG93bikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBkZWxldGVTZWxlY3RvciBvZiBzZWxlY3RvcnMuREVMRVRFX0JVVFRPTikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGVCdXR0b24gPSBkcm9wZG93bi5xdWVyeVNlbGVjdG9yKGRlbGV0ZVNlbGVjdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGV0ZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVsZXRlQnV0dG9uKSBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0sIDEwMDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChkZWxldGVCdXR0b24pIHtcbiAgICAgICAgICAgICAgICAoZGVsZXRlQnV0dG9uIGFzIEhUTUxFbGVtZW50KS5jbGljaygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogY3VycmVudE5vdGVJZCwgdGl0bGUsIGZvdW5kOiB0cnVlIH07XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgbm90ZUlkOiBjdXJyZW50Tm90ZUlkLCB0aXRsZSwgZm91bmQ6IGZhbHNlLCBlcnJvcjogJ0RlbGV0ZSBidXR0b24gbm90IGZvdW5kJyB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHsgbm90ZUlkOiB0YXJnZXROb3RlSWQsIHRpdGxlOiAnJywgZm91bmQ6IGZhbHNlLCBlcnJvcjogJ05vdGUgbm90IGZvdW5kJyB9O1xuICAgICAgICB9LFxuICAgICAgICBERUxFVEVfU0VMRUNUT1JTLFxuICAgICAgICBub3RlSWRcbiAgICAgICk7XG5cbiAgICAgIGlmICghcmVzdWx0LmZvdW5kKSB7XG4gICAgICAgIHRocm93IG5ldyBEZWxldGVFcnJvcihyZXN1bHQuZXJyb3IgfHwgJ05vdGUgbm90IGZvdW5kJywgeyBub3RlSWQgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFdhaXQgZm9yIGNvbmZpcm1hdGlvbiBkaWFsb2cgaWYgaXQgYXBwZWFyc1xuICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG5cbiAgICAgIC8vIEhhbmRsZSBjb25maXJtYXRpb24gZGlhbG9nXG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZUNvbmZpcm1hdGlvbkRpYWxvZyhwYWdlKTtcblxuICAgICAgcmV0dXJuIHsgbm90ZUlkOiByZXN1bHQubm90ZUlkLCB0aXRsZTogcmVzdWx0LnRpdGxlIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBEZWxldGVFcnJvcihcbiAgICAgICAgJ0ZhaWxlZCB0byBmaW5kIGFuZCBkZWxldGUgbm90ZScsXG4gICAgICAgIHsgbm90ZUlkIH0sXG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmluZCBhbmQgZGVsZXRlIHRoZSBsYXN0IHB1Ymxpc2hlZCBub3RlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGZpbmRBbmREZWxldGVMYXN0Tm90ZShwYWdlOiBQYWdlKTogUHJvbWlzZTx7IG5vdGVJZDogc3RyaW5nOyB0aXRsZTogc3RyaW5nIH0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoc2VsZWN0b3JzOiB0eXBlb2YgREVMRVRFX1NFTEVDVE9SUykgPT4ge1xuXG4gICAgICAgIC8vIFRyeSBlYWNoIG5vdGUgaXRlbSBzZWxlY3RvclxuICAgICAgICBsZXQgbm90ZUVsZW1lbnRzOiBFbGVtZW50W10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuTk9URV9JVEVNKSB7XG4gICAgICAgICAgY29uc3QgZWxlbWVudHMgPSBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKTtcbiAgICAgICAgICBpZiAoZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbm90ZUVsZW1lbnRzID0gZWxlbWVudHM7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobm90ZUVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogJycsIHRpdGxlOiAnJywgZm91bmQ6IGZhbHNlLCBlcnJvcjogJ05vIG5vdGVzIGZvdW5kJyB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IHRoZSBmaXJzdCBub3RlIChtb3N0IHJlY2VudClcbiAgICAgICAgY29uc3QgZmlyc3ROb3RlID0gbm90ZUVsZW1lbnRzWzBdO1xuXG4gICAgICAgIC8vIEV4dHJhY3Qgbm90ZSBJRFxuICAgICAgICBsZXQgbm90ZUlkID0gJyc7XG4gICAgICAgIGNvbnN0IGltcHJlc3Npb25EYXRhID0gZmlyc3ROb3RlLmdldEF0dHJpYnV0ZSgnZGF0YS1pbXByZXNzaW9uJyk7XG5cbiAgICAgICAgaWYgKGltcHJlc3Npb25EYXRhKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoaW1wcmVzc2lvbkRhdGEpO1xuICAgICAgICAgICAgbm90ZUlkID0gcGFyc2VkPy5ub3RlVGFyZ2V0Py52YWx1ZT8ubm90ZUlkIHx8ICcnO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBwYXJzaW5nIGVycm9yc1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFsc28gdHJ5IHRvIGZpbmQgbm90ZSBJRCBpbiBsaW5rXG4gICAgICAgIGlmICghbm90ZUlkKSB7XG4gICAgICAgICAgY29uc3QgbGlua0VsZW1lbnQgPSBmaXJzdE5vdGUucXVlcnlTZWxlY3RvcignYVtocmVmKj1cIi9leHBsb3JlL1wiXSwgYVtocmVmKj1cIi9ub3RlL1wiXScpO1xuICAgICAgICAgIGlmIChsaW5rRWxlbWVudCkge1xuICAgICAgICAgICAgY29uc3QgaHJlZiA9IGxpbmtFbGVtZW50LmdldEF0dHJpYnV0ZSgnaHJlZicpIHx8ICcnO1xuICAgICAgICAgICAgY29uc3QgbWF0Y2ggPSBocmVmLm1hdGNoKC9cXC9leHBsb3JlXFwvKFthLXpBLVowLTldKykvKTtcbiAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICBub3RlSWQgPSBtYXRjaFsxXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFeHRyYWN0IHRpdGxlXG4gICAgICAgIGNvbnN0IHRpdGxlRWxlbWVudCA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKCdbY2xhc3MqPVwidGl0bGVcIl0sIFtjbGFzcyo9XCJuYW1lXCJdJyk7XG4gICAgICAgIGNvbnN0IHRpdGxlID0gdGl0bGVFbGVtZW50Py50ZXh0Q29udGVudD8udHJpbSgpIHx8ICdVbmtub3duJztcblxuICAgICAgICAvLyBMb29rIGZvciBkZWxldGUgYnV0dG9uIG9yIG1vcmUgb3B0aW9ucyBidXR0b25cbiAgICAgICAgbGV0IGRlbGV0ZUJ1dHRvbjogRWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gICAgICAgIC8vIFRyeSBlYWNoIGRlbGV0ZSBidXR0b24gc2VsZWN0b3JcbiAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuREVMRVRFX0JVVFRPTikge1xuICAgICAgICAgIGRlbGV0ZUJ1dHRvbiA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgICBpZiAoZGVsZXRlQnV0dG9uKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWRlbGV0ZUJ1dHRvbikge1xuICAgICAgICAgIC8vIFRyeSB0byBmaW5kIG1vcmUgb3B0aW9ucyBidXR0b24gZmlyc3RcbiAgICAgICAgICBsZXQgbW9yZUJ1dHRvbjogRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICAgICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2Ygc2VsZWN0b3JzLk1PUkVfT1BUSU9OUykge1xuICAgICAgICAgICAgbW9yZUJ1dHRvbiA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgICAgIGlmIChtb3JlQnV0dG9uKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChtb3JlQnV0dG9uKSB7XG4gICAgICAgICAgICAobW9yZUJ1dHRvbiBhcyBIVE1MRWxlbWVudCkuY2xpY2soKTtcblxuICAgICAgICAgICAgLy8gV2FpdCBmb3IgZHJvcGRvd24gdG8gYXBwZWFyIGFuZCBsb29rIGZvciBkZWxldGUgb3B0aW9uXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuRFJPUERPV05fTUVOVSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRyb3Bkb3duID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgICAgICAgICAgICAgaWYgKGRyb3Bkb3duKSB7XG4gICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGRlbGV0ZVNlbGVjdG9yIG9mIHNlbGVjdG9ycy5ERUxFVEVfQlVUVE9OKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZUJ1dHRvbiA9IGRyb3Bkb3duLnF1ZXJ5U2VsZWN0b3IoZGVsZXRlU2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZGVsZXRlQnV0dG9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGlmIChkZWxldGVCdXR0b24pIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgMTAwMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRlbGV0ZUJ1dHRvbikge1xuICAgICAgICAgIChkZWxldGVCdXR0b24gYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCk7XG4gICAgICAgICAgcmV0dXJuIHsgbm90ZUlkLCB0aXRsZSwgZm91bmQ6IHRydWUgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4geyBub3RlSWQsIHRpdGxlLCBmb3VuZDogZmFsc2UsIGVycm9yOiAnRGVsZXRlIGJ1dHRvbiBub3QgZm91bmQnIH07XG4gICAgICAgIH1cbiAgICAgIH0sIERFTEVURV9TRUxFQ1RPUlMpO1xuXG4gICAgICBpZiAoIXJlc3VsdC5mb3VuZCkge1xuICAgICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IocmVzdWx0LmVycm9yIHx8ICdGYWlsZWQgdG8gZmluZCBkZWxldGUgYnV0dG9uJywge30pO1xuICAgICAgfVxuXG4gICAgICAvLyBXYWl0IGZvciBjb25maXJtYXRpb24gZGlhbG9nIGlmIGl0IGFwcGVhcnNcbiAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAvLyBIYW5kbGUgY29uZmlybWF0aW9uIGRpYWxvZ1xuICAgICAgYXdhaXQgdGhpcy5oYW5kbGVDb25maXJtYXRpb25EaWFsb2cocGFnZSk7XG5cbiAgICAgIHJldHVybiB7IG5vdGVJZDogcmVzdWx0Lm5vdGVJZCwgdGl0bGU6IHJlc3VsdC50aXRsZSB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IoXG4gICAgICAgICdGYWlsZWQgdG8gZmluZCBhbmQgZGVsZXRlIGxhc3Qgbm90ZScsXG4gICAgICAgIHt9LFxuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBjb25maXJtYXRpb24gZGlhbG9nIGZvciBkZWxldGUgb3BlcmF0aW9uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGhhbmRsZUNvbmZpcm1hdGlvbkRpYWxvZyhwYWdlOiBQYWdlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFdhaXQgZm9yIGNvbmZpcm1hdGlvbiBkaWFsb2cgdG8gYXBwZWFyXG4gICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcblxuICAgICAgLy8gTG9vayBmb3IgY29uZmlybWF0aW9uIGJ1dHRvbnMgdXNpbmcgYWxsIHBvc3NpYmxlIHNlbGVjdG9yc1xuICAgICAgbGV0IGNvbmZpcm1CdXR0b24gPSBudWxsO1xuXG4gICAgICAvLyBUcnkgZWFjaCBjb25maXJtIGJ1dHRvbiBzZWxlY3RvclxuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBERUxFVEVfU0VMRUNUT1JTLkNPTkZJUk1fQlVUVE9OKSB7XG4gICAgICAgIGNvbmZpcm1CdXR0b24gPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAoY29uZmlybUJ1dHRvbikge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKGBGb3VuZCBjb25maXJtIGJ1dHRvbiB3aXRoIHNlbGVjdG9yOiAke3NlbGVjdG9yfWApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIElmIG5vdCBmb3VuZCwgdHJ5IG1vZGFsIGNvbmZpcm0gc2VsZWN0b3JzXG4gICAgICBpZiAoIWNvbmZpcm1CdXR0b24pIHtcbiAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBERUxFVEVfU0VMRUNUT1JTLk1PREFMX0NPTkZJUk0pIHtcbiAgICAgICAgICBjb25maXJtQnV0dG9uID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgICBpZiAoY29uZmlybUJ1dHRvbikge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYEZvdW5kIG1vZGFsIGNvbmZpcm0gYnV0dG9uIHdpdGggc2VsZWN0b3I6ICR7c2VsZWN0b3J9YCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpcm1CdXR0b24pIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ0NsaWNraW5nIGNvbmZpcm1hdGlvbiBidXR0b24nKTtcbiAgICAgICAgYXdhaXQgY29uZmlybUJ1dHRvbi5jbGljaygpO1xuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIElmIG5vIGNvbmZpcm1hdGlvbiBkaWFsb2csIHRoZSBkZWxldGUgbWlnaHQgaGF2ZSBiZWVuIGltbWVkaWF0ZVxuICAgICAgICBsb2dnZXIuaW5mbygnTm8gY29uZmlybWF0aW9uIGRpYWxvZyBmb3VuZCwgZGVsZXRlIG1pZ2h0IGJlIGltbWVkaWF0ZScpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRmFpbGVkIHRvIGhhbmRsZSBjb25maXJtYXRpb24gZGlhbG9nOiAke2Vycm9yfWApO1xuICAgICAgLy8gQ29udGludWUgYW55d2F5IGFzIHRoZSBkZWxldGUgbWlnaHQgc3RpbGwgd29ya1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBOb3RlIHNlcnZpY2UgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKiBIYW5kbGVzIHVzZXIgbm90ZXMvZmVlZHMgb3BlcmF0aW9uc1xuICovXG5cbmltcG9ydCB0eXBlIHsgQ29uZmlnLCBYSFNSZXNwb25zZSB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBCYXNlU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9iYXNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2xvZ2dlcic7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBQcm9maWxlRXJyb3IsIE5vdGVQYXJzaW5nRXJyb3IsIE5vdExvZ2dlZEluRXJyb3IgfSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IERlbGV0ZVNlcnZpY2UsIERlbGV0ZVJlc3VsdCB9IGZyb20gJy4uL2RlbGV0aW5nL2RlbGV0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IFBhZ2UgfSBmcm9tICdwdXBwZXRlZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVzZXJOb3RlIHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcbiAgcmVhZG9ubHkgY29udGVudDogc3RyaW5nO1xuICByZWFkb25seSBpbWFnZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICByZWFkb25seSB2aWRlbz86IHN0cmluZztcbiAgcmVhZG9ubHkgcHVibGlzaFRpbWU6IG51bWJlcjtcbiAgcmVhZG9ubHkgdXBkYXRlVGltZTogbnVtYmVyO1xuICByZWFkb25seSBsaWtlQ291bnQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgY29tbWVudENvdW50OiBudW1iZXI7XG4gIHJlYWRvbmx5IHNoYXJlQ291bnQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgY29sbGVjdENvdW50OiBudW1iZXI7XG4gIHJlYWRvbmx5IHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICByZWFkb25seSB1cmw6IHN0cmluZztcbiAgcmVhZG9ubHkgdmlzaWJpbGl0eTogJ3B1YmxpYycgfCAncHJpdmF0ZScgfCAnZnJpZW5kcycgfCAndW5rbm93bic7XG4gIHJlYWRvbmx5IHZpc2liaWxpdHlUZXh0Pzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVzZXJOb3Rlc1Jlc3VsdCBleHRlbmRzIFhIU1Jlc3BvbnNlPFVzZXJOb3RlW10+IHtcbiAgcmVhZG9ubHkgdG90YWw6IG51bWJlcjtcbiAgcmVhZG9ubHkgaGFzTW9yZTogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbmV4dEN1cnNvcj86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIE5vdGVFeHRyYWN0aW9uRGF0YSB7XG4gIGlkOiBzdHJpbmc7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGNvbnRlbnQ6IHN0cmluZztcbiAgaW1hZ2VzOiBzdHJpbmdbXTtcbiAgcHVibGlzaFRpbWU6IG51bWJlcjtcbiAgdXBkYXRlVGltZTogbnVtYmVyO1xuICBsaWtlQ291bnQ6IG51bWJlcjtcbiAgY29tbWVudENvdW50OiBudW1iZXI7XG4gIHNoYXJlQ291bnQ6IG51bWJlcjtcbiAgY29sbGVjdENvdW50OiBudW1iZXI7XG4gIHRhZ3M6IHN0cmluZ1tdO1xuICB1cmw6IHN0cmluZztcbiAgdmlzaWJpbGl0eTogJ3B1YmxpYycgfCAncHJpdmF0ZScgfCAnZnJpZW5kcycgfCAndW5rbm93bic7XG4gIHZpc2liaWxpdHlUZXh0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ1NTIHNlbGVjdG9ycyBmb3Igbm90ZSBleHRyYWN0aW9uIGZyb20gQ3JlYXRvciBDZW50ZXJcbiAqL1xuY29uc3QgTk9URV9TRUxFQ1RPUlMgPSB7XG4gIE5PVEVfRUxFTUVOVFM6ICdkaXYubm90ZScsXG4gIFRJVExFX0VMRU1FTlRTOiAnW2NsYXNzKj1cInJhd1wiXSwgW2NsYXNzKj1cInRpdGxlXCJdLCBbY2xhc3MqPVwibmFtZVwiXScsXG4gIElNQUdFX0VMRU1FTlRTOiAnaW1nW2NsYXNzKj1cIm1lZGlhXCJdLCBpbWdbY2xhc3MqPVwiY292ZXJcIl0sIGltZ1tjbGFzcyo9XCJ0aHVtYm5haWxcIl0nLFxuICBTVEFUX0VMRU1FTlRTOiAnW2NsYXNzKj1cImNvdW50XCJdLCBbY2xhc3MqPVwic3RhdFwiXSwgW2NsYXNzKj1cIm51bWJlclwiXScsXG4gIFRBR19FTEVNRU5UUzogJ1tjbGFzcyo9XCJ0YWdcIl0sIFtjbGFzcyo9XCJsYWJlbFwiXScsXG4gIE5PVEVfTElOSzogJ2FbaHJlZio9XCIvZXhwbG9yZS9cIl0sIGFbaHJlZio9XCIvbm90ZS9cIl0nLFxuICBWSVNJQklMSVRZX0lORElDQVRPUlM6XG4gICAgJ1tjbGFzcyo9XCJwcml2YXRlXCJdLCBbY2xhc3MqPVwidmlzaWJpbGl0eVwiXSwgW2NsYXNzKj1cImxvY2tcIl0sIFtjbGFzcyo9XCJleWVcIl0sIFtjbGFzcyo9XCJwdWJsaWNcIl0sIFtjbGFzcyo9XCJmcmllbmRzXCJdLCBbY2xhc3MqPVwic3RhdHVzXCJdJyxcbiAgUFVCTElTSF9USU1FOiAnW2NsYXNzKj1cInRpbWVcIl0sIFtjbGFzcyo9XCJkYXRlXCJdLCBbY2xhc3MqPVwicHVibGlzaC10aW1lXCJdJyxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjbGFzcyBOb3RlU2VydmljZSBleHRlbmRzIEJhc2VTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBkZWxldGVTZXJ2aWNlOiBEZWxldGVTZXJ2aWNlO1xuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnKSB7XG4gICAgc3VwZXIoY29uZmlnKTtcbiAgICB0aGlzLmRlbGV0ZVNlcnZpY2UgPSBuZXcgRGVsZXRlU2VydmljZShjb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHVzZXIncyBwdWJsaXNoZWQgbm90ZXMgZnJvbSBjcmVhdG9yIGNlbnRlclxuICAgKiBAcGFyYW0gbGltaXQgLSBNYXhpbXVtIG51bWJlciBvZiBub3RlcyB0byByZXR1cm4gKGRlZmF1bHQ6IDIwKVxuICAgKiBAcGFyYW0gY3Vyc29yIC0gUGFnaW5hdGlvbiBjdXJzb3IgZm9yIG5leHQgcGFnZVxuICAgKiBAcGFyYW0gYnJvd3NlclBhdGggLSBPcHRpb25hbCBjdXN0b20gYnJvd3NlciBwYXRoXG4gICAqIEByZXR1cm5zIFByb21pc2U8VXNlck5vdGVzUmVzdWx0PiAtIFVzZXIgbm90ZXMgd2l0aCBwYWdpbmF0aW9uIGluZm9cbiAgICovXG4gIGFzeW5jIGdldFVzZXJOb3RlcyhcbiAgICBsaW1pdDogbnVtYmVyID0gMjAsXG4gICAgY3Vyc29yPzogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8VXNlck5vdGVzUmVzdWx0PiB7XG4gICAgdGhpcy52YWxpZGF0ZUdldFVzZXJOb3Rlc1BhcmFtcyhsaW1pdCk7XG5cbiAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UodHJ1ZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIE5hdmlnYXRlIHRvIGNyZWF0b3IgY2VudGVyIG5vdGUgbWFuYWdlclxuICAgICAgYXdhaXQgdGhpcy5uYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlcihwYWdlKTtcbiAgICAgIGF3YWl0IHRoaXMudmVyaWZ5VXNlckF1dGhlbnRpY2F0aW9uKHBhZ2UpO1xuXG4gICAgICAvLyBFeHRyYWN0IG5vdGVzIGZyb20gY3JlYXRvciBjZW50ZXJcbiAgICAgIGNvbnN0IG5vdGVzRGF0YSA9IGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVzRnJvbUNyZWF0b3JDZW50ZXIocGFnZSk7XG4gICAgICBjb25zdCBsaW1pdGVkTm90ZXMgPSB0aGlzLmxpbWl0Tm90ZXMobm90ZXNEYXRhLCBsaW1pdCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIGRhdGE6IGxpbWl0ZWROb3RlcyxcbiAgICAgICAgdG90YWw6IG5vdGVzRGF0YS5sZW5ndGgsXG4gICAgICAgIGhhc01vcmU6IG5vdGVzRGF0YS5sZW5ndGggPiBsaW1pdCxcbiAgICAgICAgbmV4dEN1cnNvcjogdGhpcy5nZXROZXh0Q3Vyc29yKGxpbWl0ZWROb3RlcyksXG4gICAgICAgIG9wZXJhdGlvbjogJ2dldFVzZXJOb3RlcycsXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlck5vdGVzUmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBnZXQgdXNlciBub3RlczogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBkYXRhOiBbXSxcbiAgICAgICAgdG90YWw6IDAsXG4gICAgICAgIGhhc01vcmU6IGZhbHNlLFxuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICBvcGVyYXRpb246ICdnZXRVc2VyTm90ZXMnLFxuICAgICAgfSBhcyB1bmtub3duIGFzIFVzZXJOb3Rlc1Jlc3VsdDtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBwYXJhbWV0ZXJzIGZvciBnZXRVc2VyTm90ZXMgbWV0aG9kXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlR2V0VXNlck5vdGVzUGFyYW1zKGxpbWl0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAobGltaXQgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IE5vdGVQYXJzaW5nRXJyb3IoJ0xpbWl0IG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnLCB7IGxpbWl0IH0pO1xuICAgIH1cbiAgICBpZiAobGltaXQgPiAxMDApIHtcbiAgICAgIHRocm93IG5ldyBOb3RlUGFyc2luZ0Vycm9yKCdMaW1pdCBjYW5ub3QgZXhjZWVkIDEwMCcsIHsgbGltaXQgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE5hdmlnYXRlIHRvIGNyZWF0b3IgY2VudGVyIG5vdGUgbWFuYWdlclxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBuYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlcihwYWdlOiBQYWdlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNyZWF0b3JDZW50ZXJVcmwgPSAnaHR0cHM6Ly9jcmVhdG9yLnhpYW9ob25nc2h1LmNvbS9uZXcvbm90ZS1tYW5hZ2VyP3NvdXJjZT1vZmZpY2lhbCc7XG4gICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkubmF2aWdhdGVXaXRoUmV0cnkocGFnZSwgY3JlYXRvckNlbnRlclVybCk7XG4gICAgICBhd2FpdCBzbGVlcCgzMDAwKTsgLy8gV2FpdCBmb3IgcGFnZSB0byBsb2FkIGNvbXBsZXRlbHlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IE5vdGVQYXJzaW5nRXJyb3IoXG4gICAgICAgICdGYWlsZWQgdG8gbmF2aWdhdGUgdG8gY3JlYXRvciBjZW50ZXInLFxuICAgICAgICB7IHVybDogJ2h0dHBzOi8vY3JlYXRvci54aWFvaG9uZ3NodS5jb20vbmV3L25vdGUtbWFuYWdlcj9zb3VyY2U9b2ZmaWNpYWwnIH0sXG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IHVzZXIgaXMgYXV0aGVudGljYXRlZFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB2ZXJpZnlVc2VyQXV0aGVudGljYXRpb24ocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBDaGVjayBmb3IgbG9naW4gZWxlbWVudHMgb24gdGhlIGN1cnJlbnQgcGFnZVxuICAgICAgY29uc3QgbG9naW5FbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQodGhpcy5nZXRDb25maWcoKS54aHMubG9naW5Pa1NlbGVjdG9yKTtcblxuICAgICAgLy8gQWxzbyBjaGVjayBmb3IgY3JlYXRvciBjZW50ZXIgc3BlY2lmaWMgZWxlbWVudHNcbiAgICAgIGNvbnN0IGNyZWF0b3JFbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoXG4gICAgICAgICdbY2xhc3MqPVwidXNlclwiXSwgW2NsYXNzKj1cInByb2ZpbGVcIl0sIFtjbGFzcyo9XCJhdmF0YXJcIl0nXG4gICAgICApO1xuXG4gICAgICBpZiAobG9naW5FbGVtZW50cy5sZW5ndGggPT09IDAgJiYgY3JlYXRvckVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAvLyBDaGVjayBpZiB3ZSdyZSBvbiBhIGxvZ2luIHBhZ2VcbiAgICAgICAgY29uc3QgY3VycmVudFVybCA9IHBhZ2UudXJsKCk7XG4gICAgICAgIGlmIChjdXJyZW50VXJsLmluY2x1ZGVzKCdsb2dpbicpIHx8IGN1cnJlbnRVcmwuaW5jbHVkZXMoJ3NpZ25pbicpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vdExvZ2dlZEluRXJyb3IoJ1VzZXIgbm90IGxvZ2dlZCBpbicsIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbjogJ2dldFVzZXJOb3RlcycsXG4gICAgICAgICAgICB1cmw6IGN1cnJlbnRVcmwsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb3IgY3JlYXRvciBjZW50ZXIsIGNoZWNrIGlmIHdlIGNhbiBzZWUgbm90ZSBtYW5hZ2VtZW50IGVsZW1lbnRzXG4gICAgICAgIGNvbnN0IG5vdGVFbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoJ2Rpdi5ub3RlJyk7XG4gICAgICAgIGlmIChub3RlRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vdExvZ2dlZEluRXJyb3IoJ1VzZXIgbm90IGxvZ2dlZCBpbiBvciBubyBub3RlcyBmb3VuZCcsIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbjogJ2dldFVzZXJOb3RlcycsXG4gICAgICAgICAgICB1cmw6IGN1cnJlbnRVcmwsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTm90TG9nZ2VkSW5FcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBOb3RlUGFyc2luZ0Vycm9yKFxuICAgICAgICAnRmFpbGVkIHRvIHZlcmlmeSBhdXRoZW50aWNhdGlvbicsXG4gICAgICAgIHsgb3BlcmF0aW9uOiAndmVyaWZ5QXV0aCcgfSxcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRyYWN0IG5vdGVzIGZyb20gY3JlYXRvciBjZW50ZXIgcGFnZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBleHRyYWN0Tm90ZXNGcm9tQ3JlYXRvckNlbnRlcihwYWdlOiBQYWdlKTogUHJvbWlzZTxOb3RlRXh0cmFjdGlvbkRhdGFbXT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBub3Rlc0RhdGEgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChzZWxlY3RvcnM6IHR5cGVvZiBOT1RFX1NFTEVDVE9SUykgPT4ge1xuICAgICAgICBjb25zdCBub3RlczogTm90ZUV4dHJhY3Rpb25EYXRhW10gPSBbXTtcblxuICAgICAgICAvLyBGaW5kIG5vdGUgZWxlbWVudHMgdXNpbmcgdGhlIGNyZWF0b3IgY2VudGVyIHNlbGVjdG9yXG4gICAgICAgIGNvbnN0IG5vdGVFbGVtZW50cyA9IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcnMuTk9URV9FTEVNRU5UUykpO1xuXG4gICAgICAgIG5vdGVFbGVtZW50cy5mb3JFYWNoKChlbGVtZW50OiBFbGVtZW50KSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEV4dHJhY3Qgbm90ZSBkYXRhIGZyb20gZWxlbWVudFxuICAgICAgICAgICAgY29uc3QgcHVibGlzaFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgY29uc3Qgbm90ZTogTm90ZUV4dHJhY3Rpb25EYXRhID0ge1xuICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgIHRpdGxlOiAnJyxcbiAgICAgICAgICAgICAgY29udGVudDogJycsXG4gICAgICAgICAgICAgIGltYWdlczogW10sXG4gICAgICAgICAgICAgIHB1Ymxpc2hUaW1lLFxuICAgICAgICAgICAgICB1cGRhdGVUaW1lOiBwdWJsaXNoVGltZSxcbiAgICAgICAgICAgICAgbGlrZUNvdW50OiAwLFxuICAgICAgICAgICAgICBjb21tZW50Q291bnQ6IDAsXG4gICAgICAgICAgICAgIHNoYXJlQ291bnQ6IDAsXG4gICAgICAgICAgICAgIGNvbGxlY3RDb3VudDogMCxcbiAgICAgICAgICAgICAgdGFnczogW10sXG4gICAgICAgICAgICAgIHVybDogJycsXG4gICAgICAgICAgICAgIHZpc2liaWxpdHk6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgdmlzaWJpbGl0eVRleHQ6ICcnLFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gRXh0cmFjdCBub3RlIElEIGZyb20gZGF0YSBhdHRyaWJ1dGVzIG9yIGltcHJlc3Npb24gZGF0YVxuICAgICAgICAgICAgY29uc3QgaW1wcmVzc2lvbkRhdGEgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1pbXByZXNzaW9uJyk7XG4gICAgICAgICAgICBpZiAoaW1wcmVzc2lvbkRhdGEpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGltcHJlc3Npb25EYXRhKTtcbiAgICAgICAgICAgICAgICBjb25zdCBub3RlSWQgPSBwYXJzZWQ/Lm5vdGVUYXJnZXQ/LnZhbHVlPy5ub3RlSWQ7XG4gICAgICAgICAgICAgICAgaWYgKG5vdGVJZCkge1xuICAgICAgICAgICAgICAgICAgbm90ZS5pZCA9IG5vdGVJZDtcbiAgICAgICAgICAgICAgICAgIG5vdGUudXJsID0gYGh0dHBzOi8vd3d3LnhpYW9ob25nc2h1LmNvbS9leHBsb3JlLyR7bm90ZUlkfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gSWdub3JlIHBhcnNpbmcgZXJyb3JzXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRXh0cmFjdCB0aXRsZS9jb250ZW50XG4gICAgICAgICAgICBjb25zdCB0aXRsZUVsZW1lbnQgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3JzLlRJVExFX0VMRU1FTlRTKTtcbiAgICAgICAgICAgIGlmICh0aXRsZUVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgY29uc3QgdGl0bGUgPSB0aXRsZUVsZW1lbnQudGV4dENvbnRlbnQ/LnRyaW0oKSA/PyAnJztcbiAgICAgICAgICAgICAgbm90ZS50aXRsZSA9IHRpdGxlO1xuICAgICAgICAgICAgICBub3RlLmNvbnRlbnQgPSB0aXRsZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRXh0cmFjdCBpbWFnZXMgLSB0cnkgbXVsdGlwbGUgYXBwcm9hY2hlcyBmb3IgY3JlYXRvciBjZW50ZXJcbiAgICAgICAgICAgIGNvbnN0IGltYWdlU2VsZWN0b3JzID0gW1xuICAgICAgICAgICAgICBzZWxlY3RvcnMuSU1BR0VfRUxFTUVOVFMsXG4gICAgICAgICAgICAgICdpbWcnLCAvLyBUcnkgYWxsIGltZyBlbGVtZW50c1xuICAgICAgICAgICAgICAnW2NsYXNzKj1cImltYWdlXCJdJyxcbiAgICAgICAgICAgICAgJ1tjbGFzcyo9XCJwaG90b1wiXScsXG4gICAgICAgICAgICAgICdbY2xhc3MqPVwicGljXCJdJyxcbiAgICAgICAgICAgICAgJ1tjbGFzcyo9XCJpbWdcIl0nLFxuICAgICAgICAgICAgICAnW3N0eWxlKj1cImJhY2tncm91bmQtaW1hZ2VcIl0nLCAvLyBCYWNrZ3JvdW5kIGltYWdlc1xuICAgICAgICAgICAgICAnZGl2W2NsYXNzKj1cImNvdmVyXCJdIGltZycsXG4gICAgICAgICAgICAgICdkaXZbY2xhc3MqPVwidGh1bWJuYWlsXCJdIGltZycsXG4gICAgICAgICAgICAgICdkaXZbY2xhc3MqPVwibWVkaWFcIl0gaW1nJyxcbiAgICAgICAgICAgIF07XG5cbiAgICAgICAgICAgIGxldCBpbWFnZUVsZW1lbnRzOiBhbnlbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBpbWFnZVNlbGVjdG9ycykge1xuICAgICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG4gICAgICAgICAgICAgIGlmIChlbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgaW1hZ2VFbGVtZW50cyA9IEFycmF5LmZyb20oZWxlbWVudHMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGltYWdlRWxlbWVudHMuZm9yRWFjaCgoaW1nOiBFbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgIGxldCBzcmMgPSAnJztcblxuICAgICAgICAgICAgICAvLyBUcnkgZGlmZmVyZW50IHdheXMgdG8gZ2V0IGltYWdlIHNvdXJjZVxuICAgICAgICAgICAgICBjb25zdCBodG1sSW1nID0gaW1nIGFzIEhUTUxJbWFnZUVsZW1lbnQ7XG4gICAgICAgICAgICAgIGlmIChodG1sSW1nLnNyYykge1xuICAgICAgICAgICAgICAgIHNyYyA9IGh0bWxJbWcuc3JjO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGh0bWxJbWcuc3R5bGUgJiYgaHRtbEltZy5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UpIHtcbiAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IGZyb20gYmFja2dyb3VuZC1pbWFnZSBDU1NcbiAgICAgICAgICAgICAgICBjb25zdCBiZ01hdGNoID0gaHRtbEltZy5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UubWF0Y2goL3VybFxcKFsnXCJdPyhbXidcIl0rKVsnXCJdP1xcKS8pO1xuICAgICAgICAgICAgICAgIGlmIChiZ01hdGNoKSB7XG4gICAgICAgICAgICAgICAgICBzcmMgPSBiZ01hdGNoWzFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbWcuZ2V0QXR0cmlidXRlKCdkYXRhLXNyYycpKSB7XG4gICAgICAgICAgICAgICAgLy8gTGF6eSBsb2FkZWQgaW1hZ2VzXG4gICAgICAgICAgICAgICAgc3JjID0gaW1nLmdldEF0dHJpYnV0ZSgnZGF0YS1zcmMnKSB8fCAnJztcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbWcuZ2V0QXR0cmlidXRlKCdkYXRhLW9yaWdpbmFsJykpIHtcbiAgICAgICAgICAgICAgICAvLyBBbm90aGVyIGxhenkgbG9hZGluZyBhdHRyaWJ1dGVcbiAgICAgICAgICAgICAgICBzcmMgPSBpbWcuZ2V0QXR0cmlidXRlKCdkYXRhLW9yaWdpbmFsJykgfHwgJyc7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgc3JjICYmXG4gICAgICAgICAgICAgICAgIXNyYy5pbmNsdWRlcygnYXZhdGFyJykgJiZcbiAgICAgICAgICAgICAgICAhc3JjLmluY2x1ZGVzKCdpY29uJykgJiZcbiAgICAgICAgICAgICAgICAhc3JjLmluY2x1ZGVzKCdsb2dvJykgJiZcbiAgICAgICAgICAgICAgICAhc3JjLmluY2x1ZGVzKCdwbGFjZWhvbGRlcicpICYmXG4gICAgICAgICAgICAgICAgc3JjLnN0YXJ0c1dpdGgoJ2h0dHAnKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBub3RlLmltYWdlcy5wdXNoKHNyYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgICAgIC8vIEV4dHJhY3Qgc3RhdHMgLSBsb29rIGZvciBudW1iZXJzIGluIHRoZSBlbGVtZW50XG4gICAgICAgICAgICBjb25zdCBhbGxUZXh0ID0gZWxlbWVudC50ZXh0Q29udGVudCB8fCAnJztcbiAgICAgICAgICAgIGNvbnN0IG51bWJlcnMgPSBhbGxUZXh0Lm1hdGNoKC9cXGQrL2cpIHx8IFtdO1xuXG4gICAgICAgICAgICAvLyBUcnkgdG8gZXh0cmFjdCBzdGF0cyBmcm9tIHRleHQgY29udGVudFxuICAgICAgICAgICAgaWYgKG51bWJlcnMubGVuZ3RoID49IDQpIHtcbiAgICAgICAgICAgICAgLy8gQXNzdW1pbmcgb3JkZXI6IGxpa2UsIGNvbW1lbnQsIHNoYXJlLCBjb2xsZWN0LCB2aWV3XG4gICAgICAgICAgICAgIG5vdGUubGlrZUNvdW50ID0gcGFyc2VJbnQobnVtYmVyc1swXSB8fCAnMCcpIHx8IDA7XG4gICAgICAgICAgICAgIG5vdGUuY29tbWVudENvdW50ID0gcGFyc2VJbnQobnVtYmVyc1sxXSkgfHwgMDtcbiAgICAgICAgICAgICAgbm90ZS5zaGFyZUNvdW50ID0gcGFyc2VJbnQobnVtYmVyc1syXSkgfHwgMDtcbiAgICAgICAgICAgICAgbm90ZS5jb2xsZWN0Q291bnQgPSBwYXJzZUludChudW1iZXJzWzNdKSB8fCAwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IHB1Ymxpc2ggdGltZVxuICAgICAgICAgICAgY29uc3QgdGltZUVsZW1lbnQgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3JzLlBVQkxJU0hfVElNRSk7XG4gICAgICAgICAgICBpZiAodGltZUVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgY29uc3QgdGltZVRleHQgPSB0aW1lRWxlbWVudC50ZXh0Q29udGVudD8udHJpbSgpIHx8ICcnO1xuICAgICAgICAgICAgICBpZiAodGltZVRleHQuaW5jbHVkZXMoJ+WPkeW4g+S6jicpKSB7XG4gICAgICAgICAgICAgICAgLy8gUGFyc2UgQ2hpbmVzZSBkYXRlIGZvcm1hdFxuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGVNYXRjaCA9IHRpbWVUZXh0Lm1hdGNoKFxuICAgICAgICAgICAgICAgICAgLyhcXGR7NH0p5bm0KFxcZHsxLDJ9KeaciChcXGR7MSwyfSnml6VcXHMrKFxcZHsxLDJ9KTooXFxkezJ9KS9cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGlmIChkYXRlTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IFssIHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZV0gPSBkYXRlTWF0Y2g7XG4gICAgICAgICAgICAgICAgICBjb25zdCBwdWJsaXNoRGF0ZSA9IG5ldyBEYXRlKFxuICAgICAgICAgICAgICAgICAgICBwYXJzZUludCh5ZWFyKSxcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VJbnQobW9udGgpIC0gMSxcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VJbnQoZGF5KSxcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VJbnQoaG91ciksXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlSW50KG1pbnV0ZSlcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICBub3RlLnB1Ymxpc2hUaW1lID0gcHVibGlzaERhdGUuZ2V0VGltZSgpO1xuICAgICAgICAgICAgICAgICAgbm90ZS51cGRhdGVUaW1lID0gcHVibGlzaERhdGUuZ2V0VGltZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IHZpc2liaWxpdHkgaW5mb3JtYXRpb25cbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRUZXh0ID0gZWxlbWVudC50ZXh0Q29udGVudD8udG9Mb3dlckNhc2UoKSB8fCAnJztcbiAgICAgICAgICAgIGlmIChlbGVtZW50VGV4dC5pbmNsdWRlcygn5LuF6Ieq5bex5Y+v6KeBJykpIHtcbiAgICAgICAgICAgICAgbm90ZS52aXNpYmlsaXR5ID0gJ3ByaXZhdGUnO1xuICAgICAgICAgICAgICBub3RlLnZpc2liaWxpdHlUZXh0ID0gJ+S7heiHquW3seWPr+ingSc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVsZW1lbnRUZXh0LmluY2x1ZGVzKCfmnIvlj4vlj6/op4EnKSkge1xuICAgICAgICAgICAgICBub3RlLnZpc2liaWxpdHkgPSAnZnJpZW5kcyc7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eVRleHQgPSAn5pyL5Y+L5Y+v6KeBJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudFRleHQuaW5jbHVkZXMoJ+WFrOW8gCcpKSB7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eSA9ICdwdWJsaWMnO1xuICAgICAgICAgICAgICBub3RlLnZpc2liaWxpdHlUZXh0ID0gJ+WFrOW8gCc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBEZWZhdWx0IHRvIHB1YmxpYyBmb3Igbm90ZXMgd2l0aG91dCBleHBsaWNpdCB2aXNpYmlsaXR5IGluZGljYXRvcnNcbiAgICAgICAgICAgICAgbm90ZS52aXNpYmlsaXR5ID0gJ3B1YmxpYyc7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eVRleHQgPSAn5YWs5byAJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRXh0cmFjdCB0YWdzXG4gICAgICAgICAgICBjb25zdCB0YWdFbGVtZW50cyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcnMuVEFHX0VMRU1FTlRTKTtcbiAgICAgICAgICAgIHRhZ0VsZW1lbnRzLmZvckVhY2goKHRhZzogRWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB0YWdUZXh0ID0gdGFnLnRleHRDb250ZW50Py50cmltKCk7XG4gICAgICAgICAgICAgIGlmICh0YWdUZXh0Py5zdGFydHNXaXRoKCcjJykpIHtcbiAgICAgICAgICAgICAgICBub3RlLnRhZ3MucHVzaCh0YWdUZXh0KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChub3RlLmlkKSB7XG4gICAgICAgICAgICAgIG5vdGVzLnB1c2gobm90ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBleHRyYWN0aW9uIGVycm9ycyBmb3IgaW5kaXZpZHVhbCBub3Rlc1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIG5vdGVzO1xuICAgICAgfSwgTk9URV9TRUxFQ1RPUlMpO1xuXG4gICAgICByZXR1cm4gbm90ZXNEYXRhO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgTm90ZVBhcnNpbmdFcnJvcihcbiAgICAgICAgJ0ZhaWxlZCB0byBleHRyYWN0IG5vdGVzIGZyb20gY3JlYXRvciBjZW50ZXInLFxuICAgICAgICB7IG9wZXJhdGlvbjogJ2V4dHJhY3ROb3Rlc0Zyb21DcmVhdG9yQ2VudGVyJyB9LFxuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExpbWl0IG5vdGVzIGFycmF5IHRvIHNwZWNpZmllZCBjb3VudFxuICAgKi9cbiAgcHJpdmF0ZSBsaW1pdE5vdGVzKG5vdGVzOiBOb3RlRXh0cmFjdGlvbkRhdGFbXSwgbGltaXQ6IG51bWJlcik6IFVzZXJOb3RlW10ge1xuICAgIHJldHVybiBub3Rlcy5zbGljZSgwLCBsaW1pdCkubWFwKChub3RlKSA9PiAoe1xuICAgICAgaWQ6IG5vdGUuaWQsXG4gICAgICB0aXRsZTogbm90ZS50aXRsZSxcbiAgICAgIGNvbnRlbnQ6IG5vdGUuY29udGVudCxcbiAgICAgIGltYWdlczogT2JqZWN0LmZyZWV6ZShbLi4ubm90ZS5pbWFnZXNdKSxcbiAgICAgIHB1Ymxpc2hUaW1lOiBub3RlLnB1Ymxpc2hUaW1lLFxuICAgICAgdXBkYXRlVGltZTogbm90ZS51cGRhdGVUaW1lLFxuICAgICAgbGlrZUNvdW50OiBub3RlLmxpa2VDb3VudCxcbiAgICAgIGNvbW1lbnRDb3VudDogbm90ZS5jb21tZW50Q291bnQsXG4gICAgICBzaGFyZUNvdW50OiBub3RlLnNoYXJlQ291bnQsXG4gICAgICBjb2xsZWN0Q291bnQ6IG5vdGUuY29sbGVjdENvdW50LFxuICAgICAgdGFnczogT2JqZWN0LmZyZWV6ZShbLi4ubm90ZS50YWdzXSksXG4gICAgICB1cmw6IG5vdGUudXJsLFxuICAgICAgdmlzaWJpbGl0eTogbm90ZS52aXNpYmlsaXR5LFxuICAgICAgdmlzaWJpbGl0eVRleHQ6IG5vdGUudmlzaWJpbGl0eVRleHQsXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBuZXh0IGN1cnNvciBmb3IgcGFnaW5hdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBnZXROZXh0Q3Vyc29yKG5vdGVzOiBVc2VyTm90ZVtdKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gbm90ZXMubGVuZ3RoID4gMCA/IG5vdGVzW25vdGVzLmxlbmd0aCAtIDFdLmlkIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBhIHNwZWNpZmljIG5vdGUgYnkgSURcbiAgICogQHBhcmFtIG5vdGVJZCAtIFRoZSBJRCBvZiB0aGUgbm90ZSB0byBkZWxldGVcbiAgICogQHBhcmFtIGJyb3dzZXJQYXRoIC0gT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgcGF0aFxuICAgKiBAcmV0dXJucyBQcm9taXNlPERlbGV0ZVJlc3VsdD4gLSBEZWxldGUgb3BlcmF0aW9uIHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgZGVsZXRlTm90ZShub3RlSWQ6IHN0cmluZywgYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPERlbGV0ZVJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLmRlbGV0ZVNlcnZpY2UuZGVsZXRlTm90ZShub3RlSWQsIGJyb3dzZXJQYXRoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIGxhc3QgcHVibGlzaGVkIG5vdGVcbiAgICogQHBhcmFtIGJyb3dzZXJQYXRoIC0gT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgcGF0aFxuICAgKiBAcmV0dXJucyBQcm9taXNlPERlbGV0ZVJlc3VsdD4gLSBEZWxldGUgb3BlcmF0aW9uIHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgZGVsZXRlTGFzdFB1Ymxpc2hlZE5vdGUoYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPERlbGV0ZVJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLmRlbGV0ZVNlcnZpY2UuZGVsZXRlTGFzdFB1Ymxpc2hlZE5vdGUoYnJvd3NlclBhdGgpO1xuICB9XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7482\n\n}");
|
|
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
|
-
/***/ 9135:
|
|
134
|
-
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
135
|
-
|
|
136
|
-
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}");
|
|
137
|
-
|
|
138
|
-
/***/ }),
|
|
139
|
-
|
|
140
|
-
/***/ 9896:
|
|
141
|
-
/***/ ((module) => {
|
|
142
|
-
|
|
143
|
-
module.exports = require("fs");
|
|
144
|
-
|
|
145
|
-
/***/ }),
|
|
146
|
-
|
|
147
|
-
/***/ 9916:
|
|
148
|
-
/***/ ((module) => {
|
|
149
|
-
|
|
150
|
-
module.exports = require("puppeteer");
|
|
151
|
-
|
|
152
|
-
/***/ })
|
|
153
|
-
|
|
154
|
-
/******/ });
|
|
155
|
-
/************************************************************************/
|
|
156
|
-
/******/ // The module cache
|
|
157
|
-
/******/ var __webpack_module_cache__ = {};
|
|
158
|
-
/******/
|
|
159
|
-
/******/ // The require function
|
|
160
|
-
/******/ function __webpack_require__(moduleId) {
|
|
161
|
-
/******/ // Check if module is in cache
|
|
162
|
-
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
163
|
-
/******/ if (cachedModule !== undefined) {
|
|
164
|
-
/******/ return cachedModule.exports;
|
|
165
|
-
/******/ }
|
|
166
|
-
/******/ // Create a new module (and put it into the cache)
|
|
167
|
-
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
168
|
-
/******/ // no module.id needed
|
|
169
|
-
/******/ // no module.loaded needed
|
|
170
|
-
/******/ exports: {}
|
|
171
|
-
/******/ };
|
|
172
|
-
/******/
|
|
173
|
-
/******/ // Execute the module function
|
|
174
|
-
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
175
|
-
/******/
|
|
176
|
-
/******/ // Return the exports of the module
|
|
177
|
-
/******/ return module.exports;
|
|
178
|
-
/******/ }
|
|
179
|
-
/******/
|
|
180
|
-
/******/ // expose the modules object (__webpack_modules__)
|
|
181
|
-
/******/ __webpack_require__.m = __webpack_modules__;
|
|
182
|
-
/******/
|
|
183
|
-
/******/ // the startup function
|
|
184
|
-
/******/ __webpack_require__.x = () => {
|
|
185
|
-
/******/ // Load entry module and return exports
|
|
186
|
-
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
|
|
187
|
-
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, [449], () => (__webpack_require__(5582)))
|
|
188
|
-
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
|
|
189
|
-
/******/ return __webpack_exports__;
|
|
190
|
-
/******/ };
|
|
191
|
-
/******/
|
|
192
|
-
/************************************************************************/
|
|
193
|
-
/******/ /* webpack/runtime/chunk loaded */
|
|
194
|
-
/******/ (() => {
|
|
195
|
-
/******/ var deferred = [];
|
|
196
|
-
/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => {
|
|
197
|
-
/******/ if(chunkIds) {
|
|
198
|
-
/******/ priority = priority || 0;
|
|
199
|
-
/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
|
|
200
|
-
/******/ deferred[i] = [chunkIds, fn, priority];
|
|
201
|
-
/******/ return;
|
|
202
|
-
/******/ }
|
|
203
|
-
/******/ var notFulfilled = Infinity;
|
|
204
|
-
/******/ for (var i = 0; i < deferred.length; i++) {
|
|
205
|
-
/******/ var [chunkIds, fn, priority] = deferred[i];
|
|
206
|
-
/******/ var fulfilled = true;
|
|
207
|
-
/******/ for (var j = 0; j < chunkIds.length; j++) {
|
|
208
|
-
/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
|
|
209
|
-
/******/ chunkIds.splice(j--, 1);
|
|
210
|
-
/******/ } else {
|
|
211
|
-
/******/ fulfilled = false;
|
|
212
|
-
/******/ if(priority < notFulfilled) notFulfilled = priority;
|
|
213
|
-
/******/ }
|
|
214
|
-
/******/ }
|
|
215
|
-
/******/ if(fulfilled) {
|
|
216
|
-
/******/ deferred.splice(i--, 1)
|
|
217
|
-
/******/ var r = fn();
|
|
218
|
-
/******/ if (r !== undefined) result = r;
|
|
219
|
-
/******/ }
|
|
220
|
-
/******/ }
|
|
221
|
-
/******/ return result;
|
|
222
|
-
/******/ };
|
|
223
|
-
/******/ })();
|
|
224
|
-
/******/
|
|
225
|
-
/******/ /* webpack/runtime/compat get default export */
|
|
226
|
-
/******/ (() => {
|
|
227
|
-
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
228
|
-
/******/ __webpack_require__.n = (module) => {
|
|
229
|
-
/******/ var getter = module && module.__esModule ?
|
|
230
|
-
/******/ () => (module['default']) :
|
|
231
|
-
/******/ () => (module);
|
|
232
|
-
/******/ __webpack_require__.d(getter, { a: getter });
|
|
233
|
-
/******/ return getter;
|
|
234
|
-
/******/ };
|
|
235
|
-
/******/ })();
|
|
236
|
-
/******/
|
|
237
|
-
/******/ /* webpack/runtime/define property getters */
|
|
238
|
-
/******/ (() => {
|
|
239
|
-
/******/ // define getter functions for harmony exports
|
|
240
|
-
/******/ __webpack_require__.d = (exports, definition) => {
|
|
241
|
-
/******/ for(var key in definition) {
|
|
242
|
-
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
|
243
|
-
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
244
|
-
/******/ }
|
|
245
|
-
/******/ }
|
|
246
|
-
/******/ };
|
|
247
|
-
/******/ })();
|
|
248
|
-
/******/
|
|
249
|
-
/******/ /* webpack/runtime/ensure chunk */
|
|
250
|
-
/******/ (() => {
|
|
251
|
-
/******/ __webpack_require__.f = {};
|
|
252
|
-
/******/ // This file contains only the entry chunk.
|
|
253
|
-
/******/ // The chunk loading function for additional chunks
|
|
254
|
-
/******/ __webpack_require__.e = (chunkId) => {
|
|
255
|
-
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
|
|
256
|
-
/******/ __webpack_require__.f[key](chunkId, promises);
|
|
257
|
-
/******/ return promises;
|
|
258
|
-
/******/ }, []));
|
|
259
|
-
/******/ };
|
|
260
|
-
/******/ })();
|
|
261
|
-
/******/
|
|
262
|
-
/******/ /* webpack/runtime/get javascript chunk filename */
|
|
263
|
-
/******/ (() => {
|
|
264
|
-
/******/ // This function allow to reference async chunks and chunks that the entrypoint depends on
|
|
265
|
-
/******/ __webpack_require__.u = (chunkId) => {
|
|
266
|
-
/******/ // return url for filenames based on template
|
|
267
|
-
/******/ return "" + chunkId + ".js";
|
|
268
|
-
/******/ };
|
|
269
|
-
/******/ })();
|
|
270
|
-
/******/
|
|
271
|
-
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
272
|
-
/******/ (() => {
|
|
273
|
-
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
274
|
-
/******/ })();
|
|
275
|
-
/******/
|
|
276
|
-
/******/ /* webpack/runtime/require chunk loading */
|
|
277
|
-
/******/ (() => {
|
|
278
|
-
/******/ // no baseURI
|
|
279
|
-
/******/
|
|
280
|
-
/******/ // object to store loaded chunks
|
|
281
|
-
/******/ // "1" means "loaded", otherwise not loaded yet
|
|
282
|
-
/******/ var installedChunks = {
|
|
283
|
-
/******/ 753: 1
|
|
284
|
-
/******/ };
|
|
285
|
-
/******/
|
|
286
|
-
/******/ __webpack_require__.O.require = (chunkId) => (installedChunks[chunkId]);
|
|
287
|
-
/******/
|
|
288
|
-
/******/ var installChunk = (chunk) => {
|
|
289
|
-
/******/ var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;
|
|
290
|
-
/******/ for(var moduleId in moreModules) {
|
|
291
|
-
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
|
|
292
|
-
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
|
|
293
|
-
/******/ }
|
|
294
|
-
/******/ }
|
|
295
|
-
/******/ if(runtime) runtime(__webpack_require__);
|
|
296
|
-
/******/ for(var i = 0; i < chunkIds.length; i++)
|
|
297
|
-
/******/ installedChunks[chunkIds[i]] = 1;
|
|
298
|
-
/******/ __webpack_require__.O();
|
|
299
|
-
/******/ };
|
|
300
|
-
/******/
|
|
301
|
-
/******/ // require() chunk loading for javascript
|
|
302
|
-
/******/ __webpack_require__.f.require = (chunkId, promises) => {
|
|
303
|
-
/******/ // "1" is the signal for "already loaded"
|
|
304
|
-
/******/ if(!installedChunks[chunkId]) {
|
|
305
|
-
/******/ if(true) { // all chunks have JS
|
|
306
|
-
/******/ var installedChunk = require("./" + __webpack_require__.u(chunkId));
|
|
307
|
-
/******/ if (!installedChunks[chunkId]) {
|
|
308
|
-
/******/ installChunk(installedChunk);
|
|
309
|
-
/******/ }
|
|
310
|
-
/******/ } else installedChunks[chunkId] = 1;
|
|
311
|
-
/******/ }
|
|
312
|
-
/******/ };
|
|
313
|
-
/******/
|
|
314
|
-
/******/ // no external install chunk
|
|
315
|
-
/******/
|
|
316
|
-
/******/ // no HMR
|
|
317
|
-
/******/
|
|
318
|
-
/******/ // no HMR manifest
|
|
319
|
-
/******/ })();
|
|
320
|
-
/******/
|
|
321
|
-
/******/ /* webpack/runtime/startup chunk dependencies */
|
|
322
|
-
/******/ (() => {
|
|
323
|
-
/******/ var next = __webpack_require__.x;
|
|
324
|
-
/******/ __webpack_require__.x = () => {
|
|
325
|
-
/******/ __webpack_require__.e(449);
|
|
326
|
-
/******/ return next();
|
|
327
|
-
/******/ };
|
|
328
|
-
/******/ })();
|
|
329
|
-
/******/
|
|
330
|
-
/************************************************************************/
|
|
331
|
-
/******/
|
|
332
|
-
/******/ // run startup
|
|
333
|
-
/******/ var __webpack_exports__ = __webpack_require__.x();
|
|
334
|
-
/******/ module.exports = __webpack_exports__;
|
|
335
|
-
/******/
|
|
336
|
-
/******/ })()
|
|
337
|
-
;
|