Skip to main content
Glama
route.js63.3 kB
"use strict"; /* * ATTENTION: An "eval-source-map" devtool has been used. * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ (() => { var exports = {}; exports.id = "app/api/line-webhook/route"; exports.ids = ["app/api/line-webhook/route"]; exports.modules = { /***/ "next/dist/compiled/next-server/app-page.runtime.dev.js": /*!*************************************************************************!*\ !*** external "next/dist/compiled/next-server/app-page.runtime.dev.js" ***! \*************************************************************************/ /***/ ((module) => { module.exports = require("next/dist/compiled/next-server/app-page.runtime.dev.js"); /***/ }), /***/ "next/dist/compiled/next-server/app-route.runtime.dev.js": /*!**************************************************************************!*\ !*** external "next/dist/compiled/next-server/app-route.runtime.dev.js" ***! \**************************************************************************/ /***/ ((module) => { module.exports = require("next/dist/compiled/next-server/app-route.runtime.dev.js"); /***/ }), /***/ "child_process": /*!********************************!*\ !*** external "child_process" ***! \********************************/ /***/ ((module) => { module.exports = require("child_process"); /***/ }), /***/ "crypto": /*!*************************!*\ !*** external "crypto" ***! \*************************/ /***/ ((module) => { module.exports = require("crypto"); /***/ }), /***/ "fs": /*!*********************!*\ !*** external "fs" ***! \*********************/ /***/ ((module) => { module.exports = require("fs"); /***/ }), /***/ "path": /*!***********************!*\ !*** external "path" ***! \***********************/ /***/ ((module) => { module.exports = require("path"); /***/ }), /***/ "node:process": /*!*******************************!*\ !*** external "node:process" ***! \*******************************/ /***/ ((module) => { module.exports = require("node:process"); /***/ }), /***/ "node:stream": /*!******************************!*\ !*** external "node:stream" ***! \******************************/ /***/ ((module) => { module.exports = require("node:stream"); /***/ }), /***/ "(rsc)/./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fline-webhook%2Froute&page=%2Fapi%2Fline-webhook%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Fline-webhook%2Froute.ts&appDir=D%3A%5Cfame%5Cnon-project%5Cline-bot-mcp-server%5Cui-next%5Capp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=D%3A%5Cfame%5Cnon-project%5Cline-bot-mcp-server%5Cui-next&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=standalone&preferredRegion=&middlewareConfig=e30%3D!": /*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\ !*** ./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fline-webhook%2Froute&page=%2Fapi%2Fline-webhook%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Fline-webhook%2Froute.ts&appDir=D%3A%5Cfame%5Cnon-project%5Cline-bot-mcp-server%5Cui-next%5Capp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=D%3A%5Cfame%5Cnon-project%5Cline-bot-mcp-server%5Cui-next&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=standalone&preferredRegion=&middlewareConfig=e30%3D! ***! \********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ originalPathname: () => (/* binding */ originalPathname),\n/* harmony export */ patchFetch: () => (/* binding */ patchFetch),\n/* harmony export */ requestAsyncStorage: () => (/* binding */ requestAsyncStorage),\n/* harmony export */ routeModule: () => (/* binding */ routeModule),\n/* harmony export */ serverHooks: () => (/* binding */ serverHooks),\n/* harmony export */ staticGenerationAsyncStorage: () => (/* binding */ staticGenerationAsyncStorage)\n/* harmony export */ });\n/* harmony import */ var next_dist_server_future_route_modules_app_route_module_compiled__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! next/dist/server/future/route-modules/app-route/module.compiled */ \"(rsc)/./node_modules/next/dist/server/future/route-modules/app-route/module.compiled.js\");\n/* harmony import */ var next_dist_server_future_route_modules_app_route_module_compiled__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(next_dist_server_future_route_modules_app_route_module_compiled__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var next_dist_server_future_route_kind__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! next/dist/server/future/route-kind */ \"(rsc)/./node_modules/next/dist/server/future/route-kind.js\");\n/* harmony import */ var next_dist_server_lib_patch_fetch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! next/dist/server/lib/patch-fetch */ \"(rsc)/./node_modules/next/dist/server/lib/patch-fetch.js\");\n/* harmony import */ var next_dist_server_lib_patch_fetch__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(next_dist_server_lib_patch_fetch__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var D_fame_non_project_line_bot_mcp_server_ui_next_app_api_line_webhook_route_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./app/api/line-webhook/route.ts */ \"(rsc)/./app/api/line-webhook/route.ts\");\n\n\n\n\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\nconst nextConfigOutput = \"standalone\"\nconst routeModule = new next_dist_server_future_route_modules_app_route_module_compiled__WEBPACK_IMPORTED_MODULE_0__.AppRouteRouteModule({\n definition: {\n kind: next_dist_server_future_route_kind__WEBPACK_IMPORTED_MODULE_1__.RouteKind.APP_ROUTE,\n page: \"/api/line-webhook/route\",\n pathname: \"/api/line-webhook\",\n filename: \"route\",\n bundlePath: \"app/api/line-webhook/route\"\n },\n resolvedPagePath: \"D:\\\\fame\\\\non-project\\\\line-bot-mcp-server\\\\ui-next\\\\app\\\\api\\\\line-webhook\\\\route.ts\",\n nextConfigOutput,\n userland: D_fame_non_project_line_bot_mcp_server_ui_next_app_api_line_webhook_route_ts__WEBPACK_IMPORTED_MODULE_3__\n});\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { requestAsyncStorage, staticGenerationAsyncStorage, serverHooks } = routeModule;\nconst originalPathname = \"/api/line-webhook/route\";\nfunction patchFetch() {\n return (0,next_dist_server_lib_patch_fetch__WEBPACK_IMPORTED_MODULE_2__.patchFetch)({\n serverHooks,\n staticGenerationAsyncStorage\n });\n}\n\n\n//# sourceMappingURL=app-route.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHJzYykvLi9ub2RlX21vZHVsZXMvbmV4dC9kaXN0L2J1aWxkL3dlYnBhY2svbG9hZGVycy9uZXh0LWFwcC1sb2FkZXIuanM/bmFtZT1hcHAlMkZhcGklMkZsaW5lLXdlYmhvb2slMkZyb3V0ZSZwYWdlPSUyRmFwaSUyRmxpbmUtd2ViaG9vayUyRnJvdXRlJmFwcFBhdGhzPSZwYWdlUGF0aD1wcml2YXRlLW5leHQtYXBwLWRpciUyRmFwaSUyRmxpbmUtd2ViaG9vayUyRnJvdXRlLnRzJmFwcERpcj1EJTNBJTVDZmFtZSU1Q25vbi1wcm9qZWN0JTVDbGluZS1ib3QtbWNwLXNlcnZlciU1Q3VpLW5leHQlNUNhcHAmcGFnZUV4dGVuc2lvbnM9dHN4JnBhZ2VFeHRlbnNpb25zPXRzJnBhZ2VFeHRlbnNpb25zPWpzeCZwYWdlRXh0ZW5zaW9ucz1qcyZyb290RGlyPUQlM0ElNUNmYW1lJTVDbm9uLXByb2plY3QlNUNsaW5lLWJvdC1tY3Atc2VydmVyJTVDdWktbmV4dCZpc0Rldj10cnVlJnRzY29uZmlnUGF0aD10c2NvbmZpZy5qc29uJmJhc2VQYXRoPSZhc3NldFByZWZpeD0mbmV4dENvbmZpZ091dHB1dD1zdGFuZGFsb25lJnByZWZlcnJlZFJlZ2lvbj0mbWlkZGxld2FyZUNvbmZpZz1lMzAlM0QhIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUFzRztBQUN2QztBQUNjO0FBQ3FDO0FBQ2xIO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixnSEFBbUI7QUFDM0M7QUFDQSxjQUFjLHlFQUFTO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxZQUFZO0FBQ1osQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLFFBQVEsaUVBQWlFO0FBQ3pFO0FBQ0E7QUFDQSxXQUFXLDRFQUFXO0FBQ3RCO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDdUg7O0FBRXZIIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vbGluZS1ib3QtbWNwLXVpLz8yMTZjIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFwcFJvdXRlUm91dGVNb2R1bGUgfSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9mdXR1cmUvcm91dGUtbW9kdWxlcy9hcHAtcm91dGUvbW9kdWxlLmNvbXBpbGVkXCI7XG5pbXBvcnQgeyBSb3V0ZUtpbmQgfSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9mdXR1cmUvcm91dGUta2luZFwiO1xuaW1wb3J0IHsgcGF0Y2hGZXRjaCBhcyBfcGF0Y2hGZXRjaCB9IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL2xpYi9wYXRjaC1mZXRjaFwiO1xuaW1wb3J0ICogYXMgdXNlcmxhbmQgZnJvbSBcIkQ6XFxcXGZhbWVcXFxcbm9uLXByb2plY3RcXFxcbGluZS1ib3QtbWNwLXNlcnZlclxcXFx1aS1uZXh0XFxcXGFwcFxcXFxhcGlcXFxcbGluZS13ZWJob29rXFxcXHJvdXRlLnRzXCI7XG4vLyBXZSBpbmplY3QgdGhlIG5leHRDb25maWdPdXRwdXQgaGVyZSBzbyB0aGF0IHdlIGNhbiB1c2UgdGhlbSBpbiB0aGUgcm91dGVcbi8vIG1vZHVsZS5cbmNvbnN0IG5leHRDb25maWdPdXRwdXQgPSBcInN0YW5kYWxvbmVcIlxuY29uc3Qgcm91dGVNb2R1bGUgPSBuZXcgQXBwUm91dGVSb3V0ZU1vZHVsZSh7XG4gICAgZGVmaW5pdGlvbjoge1xuICAgICAgICBraW5kOiBSb3V0ZUtpbmQuQVBQX1JPVVRFLFxuICAgICAgICBwYWdlOiBcIi9hcGkvbGluZS13ZWJob29rL3JvdXRlXCIsXG4gICAgICAgIHBhdGhuYW1lOiBcIi9hcGkvbGluZS13ZWJob29rXCIsXG4gICAgICAgIGZpbGVuYW1lOiBcInJvdXRlXCIsXG4gICAgICAgIGJ1bmRsZVBhdGg6IFwiYXBwL2FwaS9saW5lLXdlYmhvb2svcm91dGVcIlxuICAgIH0sXG4gICAgcmVzb2x2ZWRQYWdlUGF0aDogXCJEOlxcXFxmYW1lXFxcXG5vbi1wcm9qZWN0XFxcXGxpbmUtYm90LW1jcC1zZXJ2ZXJcXFxcdWktbmV4dFxcXFxhcHBcXFxcYXBpXFxcXGxpbmUtd2ViaG9va1xcXFxyb3V0ZS50c1wiLFxuICAgIG5leHRDb25maWdPdXRwdXQsXG4gICAgdXNlcmxhbmRcbn0pO1xuLy8gUHVsbCBvdXQgdGhlIGV4cG9ydHMgdGhhdCB3ZSBuZWVkIHRvIGV4cG9zZSBmcm9tIHRoZSBtb2R1bGUuIFRoaXMgc2hvdWxkXG4vLyBiZSBlbGltaW5hdGVkIHdoZW4gd2UndmUgbW92ZWQgdGhlIG90aGVyIHJvdXRlcyB0byB0aGUgbmV3IGZvcm1hdC4gVGhlc2Vcbi8vIGFyZSB1c2VkIHRvIGhvb2sgaW50byB0aGUgcm91dGUuXG5jb25zdCB7IHJlcXVlc3RBc3luY1N0b3JhZ2UsIHN0YXRpY0dlbmVyYXRpb25Bc3luY1N0b3JhZ2UsIHNlcnZlckhvb2tzIH0gPSByb3V0ZU1vZHVsZTtcbmNvbnN0IG9yaWdpbmFsUGF0aG5hbWUgPSBcIi9hcGkvbGluZS13ZWJob29rL3JvdXRlXCI7XG5mdW5jdGlvbiBwYXRjaEZldGNoKCkge1xuICAgIHJldHVybiBfcGF0Y2hGZXRjaCh7XG4gICAgICAgIHNlcnZlckhvb2tzLFxuICAgICAgICBzdGF0aWNHZW5lcmF0aW9uQXN5bmNTdG9yYWdlXG4gICAgfSk7XG59XG5leHBvcnQgeyByb3V0ZU1vZHVsZSwgcmVxdWVzdEFzeW5jU3RvcmFnZSwgc3RhdGljR2VuZXJhdGlvbkFzeW5jU3RvcmFnZSwgc2VydmVySG9va3MsIG9yaWdpbmFsUGF0aG5hbWUsIHBhdGNoRmV0Y2gsICB9O1xuXG4vLyMgc291cmNlTWFwcGluZ1VSTD1hcHAtcm91dGUuanMubWFwIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(rsc)/./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fline-webhook%2Froute&page=%2Fapi%2Fline-webhook%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Fline-webhook%2Froute.ts&appDir=D%3A%5Cfame%5Cnon-project%5Cline-bot-mcp-server%5Cui-next%5Capp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=D%3A%5Cfame%5Cnon-project%5Cline-bot-mcp-server%5Cui-next&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=standalone&preferredRegion=&middlewareConfig=e30%3D!\n"); /***/ }), /***/ "(rsc)/./app/api/line-webhook/route.ts": /*!***************************************!*\ !*** ./app/api/line-webhook/route.ts ***! \***************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ POST: () => (/* binding */ POST),\n/* harmony export */ dynamic: () => (/* binding */ dynamic),\n/* harmony export */ runtime: () => (/* binding */ runtime)\n/* harmony export */ });\n/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! crypto */ \"crypto\");\n/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs */ \"fs\");\n/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! path */ \"path\");\n/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _modelcontextprotocol_sdk_client_index_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @modelcontextprotocol/sdk/client/index.js */ \"(rsc)/../node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js\");\n/* harmony import */ var _modelcontextprotocol_sdk_client_stdio_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @modelcontextprotocol/sdk/client/stdio.js */ \"(rsc)/../node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.js\");\nconst runtime = \"nodejs\";\nconst dynamic = \"force-dynamic\";\n\n\n\n\n\nfunction loadParentEnvOnce() {\n try {\n const loadedFlag = globalThis.__parentEnvLoaded;\n if (loadedFlag) return;\n const parentEnv = path__WEBPACK_IMPORTED_MODULE_2___default().resolve(process.cwd(), \"..\", \".env\");\n if (fs__WEBPACK_IMPORTED_MODULE_1___default().existsSync(parentEnv)) {\n const text = fs__WEBPACK_IMPORTED_MODULE_1___default().readFileSync(parentEnv, \"utf8\");\n for (const line of text.split(/\\r?\\n/)){\n if (!line || line.trim().startsWith(\"#\")) continue;\n const idx = line.indexOf(\"=\");\n if (idx <= 0) continue;\n const key = line.slice(0, idx).trim();\n let val = line.slice(idx + 1).trim();\n if (val.startsWith('\"') && val.endsWith('\"') || val.startsWith(\"'\") && val.endsWith(\"'\")) {\n val = val.slice(1, -1);\n }\n if (!process.env[key]) process.env[key] = val;\n }\n }\n globalThis.__parentEnvLoaded = true;\n } catch {\n // ignore\n }\n}\nloadParentEnvOnce();\nasync function getClient() {\n if (globalThis.__mcpClientWebhook) return globalThis.__mcpClientWebhook;\n const projectRoot = path__WEBPACK_IMPORTED_MODULE_2___default().resolve(process.cwd(), \"..\");\n const transport = new _modelcontextprotocol_sdk_client_stdio_js__WEBPACK_IMPORTED_MODULE_4__.StdioClientTransport({\n command: \"node\",\n args: [\n \"dist/index.js\"\n ],\n cwd: projectRoot,\n env: process.env\n });\n const client = new _modelcontextprotocol_sdk_client_index_js__WEBPACK_IMPORTED_MODULE_3__.Client({\n name: \"line-bot-webhook\",\n version: \"0.1.0\"\n });\n await client.connect(transport);\n globalThis.__mcpClientWebhook = client;\n return client;\n}\nfunction verifyLineSignature(rawBody, signature) {\n try {\n const secret = process.env.CHANNEL_SECRET || \"\";\n if (!secret || !signature) return false;\n const hmac = crypto__WEBPACK_IMPORTED_MODULE_0___default().createHmac(\"sha256\", secret);\n hmac.update(rawBody);\n const digest = hmac.digest(\"base64\");\n return crypto__WEBPACK_IMPORTED_MODULE_0___default().timingSafeEqual(Buffer.from(digest), Buffer.from(signature));\n } catch {\n return false;\n }\n}\nasync function POST(req) {\n try {\n const signature = req.headers.get(\"x-line-signature\");\n const raw = await req.text();\n const disableVerify = String(process.env.DISABLE_LINE_SIGNATURE_VERIFY || \"\").toLowerCase() === \"true\";\n if (!disableVerify && !verifyLineSignature(raw, signature)) {\n return new Response(JSON.stringify({\n error: \"invalid signature\"\n }), {\n status: 401,\n headers: {\n \"Content-Type\": \"application/json\"\n }\n });\n }\n const body = JSON.parse(raw);\n const events = Array.isArray(body?.events) ? body.events : [];\n const client = await getClient();\n if (!globalThis.__userPrefs) globalThis.__userPrefs = new Map();\n const prefs = globalThis.__userPrefs;\n for (const ev of events){\n const userId = ev?.source?.userId || \"\";\n if (ev?.type === \"message\" && ev?.message?.type === \"text\") {\n let text = ev.message.text || \"\";\n const dest = userId || process.env.DESTINATION_USER_ID || \"\";\n let t = text.toLowerCase();\n if (t.includes(\"login db\")) {\n if (userId) prefs.set(userId, {\n knowledgeSource: \"mssql\"\n });\n try {\n await client.callTool({\n name: \"push_text_message\",\n arguments: {\n userId,\n message: {\n type: \"text\",\n text: \"เชื่อมต่อฐานข้อมูล (MSSQL) สำหรับโหมดถาม/ตอบแล้ว\"\n }\n }\n });\n } catch {}\n continue;\n }\n if (t.includes(\"logout db\")) {\n if (userId) prefs.set(userId, {\n knowledgeSource: \"file\"\n });\n try {\n await client.callTool({\n name: \"push_text_message\",\n arguments: {\n userId,\n message: {\n type: \"text\",\n text: \"ยกเลิกโหมดฐานข้อมูล ใช้ไฟล์ความรู้แทน\"\n }\n }\n });\n } catch {}\n continue;\n }\n const pref = userId && prefs.get(userId) || {\n knowledgeSource: \"file\"\n };\n const knowledgeSource = pref.knowledgeSource;\n // Heuristic: remember explicit table mentions and support pronoun \"ตารางนี้/table นี้/this table\"\n const explicitTableMatch = t.match(/(?:table|จาก|เข้าไป|ไป|from)\\s+([a-z0-9_\\.]+)/i);\n if (explicitTableMatch && explicitTableMatch[1] && userId) {\n const raw = explicitTableMatch[1];\n const full = raw.includes(\".\") ? raw : `dbo.${raw}`;\n prefs.set(userId, {\n ...pref,\n lastTable: full\n });\n }\n if (/(ตารางนี้|table\\s*นี้|this\\s*table)/i.test(text) && pref.lastTable) {\n text = text.replace(/ตารางนี้|table\\s*นี้|this\\s*table/gi, pref.lastTable);\n t = text.toLowerCase();\n }\n if (knowledgeSource === \"mssql\" && /(ทั้งหมดกี่รายการ|มีกี่รายการ|count\\s*(all)?)/i.test(text)) {\n if (pref.lastTable) {\n try {\n const q = await client.callTool({\n name: \"query_mssql\",\n arguments: {\n sql: `SELECT COUNT(1) AS total_count FROM ${pref.lastTable}`,\n limit: 1\n }\n });\n const parsed = JSON.parse(q.content?.[0]?.text || \"{}\");\n const rows = Array.isArray(parsed?.rows) ? parsed.rows : [];\n const cnt = rows[0]?.total_count ?? pref.lastRowCount ?? 0;\n const msg = `ทั้งหมด ${cnt} รายการ (จาก ${pref.lastTable})`;\n await client.callTool({\n name: \"push_text_message\",\n arguments: {\n userId: dest,\n message: {\n type: \"text\",\n text: msg\n }\n }\n });\n continue;\n } catch {\n // ignore and fall through\n }\n }\n }\n // 2) Ask which table?\n if (knowledgeSource === \"mssql\" && /(จากตารางไหน|what\\s*table)/i.test(text)) {\n const msg = pref.lastTable ? `จากตาราง ${pref.lastTable}` : \"ยังไม่ทราบตาราง (โปรดระบุ)\";\n try {\n await client.callTool({\n name: \"push_text_message\",\n arguments: {\n userId: dest,\n message: {\n type: \"text\",\n text: msg\n }\n }\n });\n continue;\n } catch {}\n }\n // If user asks for all tables summary\n if (knowledgeSource === \"mssql\" && /(แสดงข้อมูล.*ตาราง.*ทั้งหมด|แสดงข้อมูลแต่ละ\\s*ตาราง|ทุก\\s*ตาราง)/i.test(text)) {\n try {\n // Use MCP tool query_mssql to fetch table list\n const q = await client.callTool({\n name: \"query_mssql\",\n arguments: {\n sql: \"SELECT TOP 50 s.name AS schema_name, t.name AS table_name FROM sys.tables t JOIN sys.schemas s ON t.schema_id = s.schema_id WHERE t.is_ms_shipped = 0 ORDER BY s.name, t.name\",\n limit: 50\n }\n });\n const parsed = JSON.parse(q.content?.[0]?.text || \"{}\");\n const rows = Array.isArray(parsed?.rows) ? parsed.rows : [];\n const out = rows.map((r)=>`- ${r.schema_name}.${r.table_name}`).slice(0, 50).join(\"\\n\");\n const textMsg = out || \"(ไม่พบตาราง)\";\n await client.callTool({\n name: \"push_text_message\",\n arguments: {\n userId,\n message: {\n type: \"text\",\n text: textMsg\n }\n }\n });\n continue;\n } catch {}\n }\n // If user says \"แสดงมา/โชว์หน่อย/เอามา\" and we have lastTable (+ optional lastLimit)\n if (knowledgeSource === \"mssql\" && /(แสดงมา|โชว์หน่อย|เอามา)/i.test(text) && pref.lastTable) {\n const lim = pref.lastLimit && pref.lastLimit > 0 ? pref.lastLimit : 10;\n text = `เข้าไป ${pref.lastTable} แสดง${lim} ข้อมูล`;\n t = text.toLowerCase();\n }\n // If user says \"แสดง {N} (รายการ|แถว)\" and we have lastTable, rewrite\n const mShowN = t.match(/แสดง(?:ข้อมูล)?\\s*(\\d{1,4})\\s*(?:รายการ|แถว)?/i);\n if (knowledgeSource === \"mssql\" && mShowN && pref.lastTable) {\n const lim = parseInt(mShowN[1], 10);\n text = `เข้าไป ${pref.lastTable} แสดง${lim} ข้อมูล`;\n prefs.set(userId, {\n ...pref,\n lastLimit: lim\n });\n }\n // Try AI-driven SQL first when using DB knowledge\n if (knowledgeSource === \"mssql\") {\n try {\n const q = await client.callTool({\n name: \"ai_query_mssql\",\n arguments: {\n instruction: text,\n maxRows: 10,\n allowedTables: pref.lastTable ? [\n pref.lastTable\n ] : undefined\n }\n });\n const raw = q?.content?.[0]?.text || \"\";\n try {\n const payload = raw ? JSON.parse(raw) : null;\n if (payload && Array.isArray(payload.rows)) {\n const rows = payload.rows;\n const cols = Array.isArray(payload.columns) ? payload.columns : rows[0] ? Object.keys(rows[0]) : [];\n const previewCols = cols.slice(0, 3);\n const head = `ผลลัพธ์ ${Math.min(rows.length, 10)} / ${payload.rowCount ?? rows.length} แถว`;\n const body = rows.slice(0, 10).map((r, i)=>`${i + 1}. ${previewCols.map((c)=>`${c}: ${String(r[c] ?? \"\")}`).join(\", \")}`).join(\"\\n\");\n const txt = [\n head,\n body\n ].filter(Boolean).join(\"\\n\").slice(0, 2000);\n await client.callTool({\n name: \"push_text_message\",\n arguments: {\n userId: dest,\n message: {\n type: \"text\",\n text: txt\n }\n }\n });\n // Try to extract table name from SQL and store context\n try {\n const sql = String(payload.sql || \"\");\n const mFrom = sql.match(/from\\s+([a-z0-9_\\.]+)/i);\n const tbl = mFrom && mFrom[1] ? mFrom[1] : pref.lastTable;\n const newPref = {\n ...pref,\n lastTable: tbl,\n lastLimit: 10,\n lastRowCount: payload.rowCount ?? rows.length\n };\n if (userId) prefs.set(userId, newPref);\n } catch {}\n continue;\n }\n } catch {\n // parsing failed; fall back below\n }\n } catch {\n // ai_query_mssql failed; fall back below\n }\n }\n const args = {\n instruction: text,\n model: \"gemini-2.0-flash\",\n mode: \"auto\",\n userId: dest,\n knowledgeSource\n };\n if (knowledgeSource === \"file\") {\n const defaultKnowledge = process.env.DEFAULT_KNOWLEDGE_FILE || \"docs/data-learning/knowledge.md\";\n args.filePath = defaultKnowledge;\n }\n try {\n await client.callTool({\n name: \"gemini_command\",\n arguments: args\n });\n } catch (e) {\n // swallow to not break webhook pipeline\n }\n }\n }\n return new Response(JSON.stringify({\n ok: true\n }), {\n headers: {\n \"Content-Type\": \"application/json\"\n }\n });\n } catch (e) {\n return new Response(JSON.stringify({\n error: e?.message || String(e)\n }), {\n status: 500,\n headers: {\n \"Content-Type\": \"application/json\"\n }\n });\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHJzYykvLi9hcHAvYXBpL2xpbmUtd2ViaG9vay9yb3V0ZS50cyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFPLE1BQU1BLFVBQVUsU0FBUztBQUN6QixNQUFNQyxVQUFVLGdCQUFnQjtBQUVYO0FBQ1I7QUFDSTtBQUMyQztBQUNjO0FBbUJqRixTQUFTTTtJQUNQLElBQUk7UUFDRixNQUFNQyxhQUFhLFdBQW9CRSxpQkFBaUI7UUFDeEQsSUFBSUYsWUFBWTtRQUNoQixNQUFNRyxZQUFZUCxtREFBWSxDQUFDUyxRQUFRQyxHQUFHLElBQUksTUFBTTtRQUNwRCxJQUFJWCxvREFBYSxDQUFDUSxZQUFZO1lBQzVCLE1BQU1LLE9BQU9iLHNEQUFlLENBQUNRLFdBQVc7WUFDeEMsS0FBSyxNQUFNTyxRQUFRRixLQUFLRyxLQUFLLENBQUMsU0FBVTtnQkFDdEMsSUFBSSxDQUFDRCxRQUFRQSxLQUFLRSxJQUFJLEdBQUdDLFVBQVUsQ0FBQyxNQUFNO2dCQUMxQyxNQUFNQyxNQUFNSixLQUFLSyxPQUFPLENBQUM7Z0JBQ3pCLElBQUlELE9BQU8sR0FBRztnQkFDZCxNQUFNRSxNQUFNTixLQUFLTyxLQUFLLENBQUMsR0FBR0gsS0FBS0YsSUFBSTtnQkFDbkMsSUFBSU0sTUFBTVIsS0FBS08sS0FBSyxDQUFDSCxNQUFNLEdBQUdGLElBQUk7Z0JBQ2xDLElBQUksSUFBS0MsVUFBVSxDQUFDLFFBQVFLLElBQUlDLFFBQVEsQ0FBQyxRQUFVRCxJQUFJTCxVQUFVLENBQUMsUUFBUUssSUFBSUMsUUFBUSxDQUFDLE1BQU87b0JBQzVGRCxNQUFNQSxJQUFJRCxLQUFLLENBQUMsR0FBRyxDQUFDO2dCQUN0QjtnQkFDQSxJQUFJLENBQUNaLFFBQVFlLEdBQUcsQ0FBQ0osSUFBSSxFQUFFWCxRQUFRZSxHQUFHLENBQUNKLElBQUksR0FBR0U7WUFDNUM7UUFDRjtRQUNDakIsV0FBbUJDLGlCQUFpQixHQUFHO0lBQzFDLEVBQUUsT0FBTTtJQUNOLFNBQVM7SUFDWDtBQUNGO0FBQ0FIO0FBRUEsZUFBZXNCO0lBQ2IsSUFBSXBCLFdBQVdxQixrQkFBa0IsRUFBRSxPQUFPckIsV0FBV3FCLGtCQUFrQjtJQUV2RSxNQUFNQyxjQUFjM0IsbURBQVksQ0FBQ1MsUUFBUUMsR0FBRyxJQUFJO0lBQ2hELE1BQU1rQixZQUFZLElBQUkxQiwyRkFBb0JBLENBQUM7UUFDekMyQixTQUFTO1FBQ1RDLE1BQU07WUFBQztTQUFnQjtRQUN2QnBCLEtBQUtpQjtRQUNMSCxLQUFLZixRQUFRZSxHQUFHO0lBQ2xCO0lBQ0EsTUFBTU8sU0FBUyxJQUFJOUIsNkVBQU1BLENBQUM7UUFBRStCLE1BQU07UUFBb0JDLFNBQVM7SUFBUTtJQUN2RSxNQUFNRixPQUFPRyxPQUFPLENBQUNOO0lBQ3JCdkIsV0FBV3FCLGtCQUFrQixHQUFHSztJQUNoQyxPQUFPQTtBQUNUO0FBRUEsU0FBU0ksb0JBQW9CQyxPQUFlLEVBQUVDLFNBQXdCO0lBQ3BFLElBQUk7UUFDRixNQUFNQyxTQUFTN0IsUUFBUWUsR0FBRyxDQUFDZSxjQUFjLElBQUk7UUFDN0MsSUFBSSxDQUFDRCxVQUFVLENBQUNELFdBQVcsT0FBTztRQUNsQyxNQUFNRyxPQUFPMUMsd0RBQWlCLENBQUMsVUFBVXdDO1FBQ3pDRSxLQUFLRSxNQUFNLENBQUNOO1FBQ1osTUFBTU8sU0FBU0gsS0FBS0csTUFBTSxDQUFDO1FBQzNCLE9BQU83Qyw2REFBc0IsQ0FBQytDLE9BQU9DLElBQUksQ0FBQ0gsU0FBU0UsT0FBT0MsSUFBSSxDQUFDVDtJQUNqRSxFQUFFLE9BQU07UUFDTixPQUFPO0lBQ1Q7QUFDRjtBQVNPLGVBQWVVLEtBQUtDLEdBQVk7SUFDckMsSUFBSTtRQUNGLE1BQU1YLFlBQVlXLElBQUlDLE9BQU8sQ0FBQ0MsR0FBRyxDQUFDO1FBQ2xDLE1BQU1DLE1BQU0sTUFBTUgsSUFBSXBDLElBQUk7UUFDMUIsTUFBTXdDLGdCQUFnQkMsT0FBTzVDLFFBQVFlLEdBQUcsQ0FBQzhCLDZCQUE2QixJQUFJLElBQUlDLFdBQVcsT0FBTztRQUNoRyxJQUFJLENBQUNILGlCQUFpQixDQUFDakIsb0JBQW9CZ0IsS0FBS2QsWUFBWTtZQUMxRCxPQUFPLElBQUltQixTQUFTQyxLQUFLQyxTQUFTLENBQUM7Z0JBQUVDLE9BQU87WUFBb0IsSUFBSTtnQkFDbEVDLFFBQVE7Z0JBQ1JYLFNBQVM7b0JBQUUsZ0JBQWdCO2dCQUFtQjtZQUNoRDtRQUNGO1FBRUEsTUFBTVksT0FBT0osS0FBS0ssS0FBSyxDQUFDWDtRQUN4QixNQUFNWSxTQUFTQyxNQUFNQyxPQUFPLENBQUNKLE1BQU1FLFVBQVVGLEtBQUtFLE1BQU0sR0FBRyxFQUFFO1FBRTdELE1BQU1oQyxTQUFTLE1BQU1OO1FBQ3JCLElBQUksQ0FBQ3BCLFdBQVc2RCxXQUFXLEVBQUU3RCxXQUFXNkQsV0FBVyxHQUFHLElBQUlDO1FBQzFELE1BQU1DLFFBQVEvRCxXQUFXNkQsV0FBVztRQUVwQyxLQUFLLE1BQU1HLE1BQU1OLE9BQVE7WUFDdkIsTUFBTU8sU0FBU0QsSUFBSUUsUUFBUUQsVUFBVTtZQUNyQyxJQUFJRCxJQUFJRyxTQUFTLGFBQWFILElBQUlJLFNBQVNELFNBQVMsUUFBUTtnQkFDMUQsSUFBSTVELE9BQU95RCxHQUFHSSxPQUFPLENBQUM3RCxJQUFJLElBQUk7Z0JBQzlCLE1BQU04RCxPQUFPSixVQUFXN0QsUUFBUWUsR0FBRyxDQUFDbUQsbUJBQW1CLElBQUk7Z0JBQzNELElBQUlDLElBQUloRSxLQUFLMkMsV0FBVztnQkFDeEIsSUFBSXFCLEVBQUVDLFFBQVEsQ0FBQyxhQUFhO29CQUMxQixJQUFJUCxRQUFRRixNQUFPVSxHQUFHLENBQUNSLFFBQVE7d0JBQUVTLGlCQUFpQjtvQkFBUTtvQkFDMUQsSUFBSTt3QkFDRixNQUFNaEQsT0FBT2lELFFBQVEsQ0FBQzs0QkFDcEJoRCxNQUFNOzRCQUNOaUQsV0FBVztnQ0FDVFg7Z0NBQ0FHLFNBQVM7b0NBQUVELE1BQU07b0NBQVE1RCxNQUFNO2dDQUFtRDs0QkFDcEY7d0JBQ0Y7b0JBQ0YsRUFBRSxPQUFNLENBQUM7b0JBQ1Q7Z0JBQ0Y7Z0JBQ0EsSUFBSWdFLEVBQUVDLFFBQVEsQ0FBQyxjQUFjO29CQUMzQixJQUFJUCxRQUFRRixNQUFPVSxHQUFHLENBQUNSLFFBQVE7d0JBQUVTLGlCQUFpQjtvQkFBTztvQkFDekQsSUFBSTt3QkFDRixNQUFNaEQsT0FBT2lELFFBQVEsQ0FBQzs0QkFDcEJoRCxNQUFNOzRCQUNOaUQsV0FBVztnQ0FDVFg7Z0NBQ0FHLFNBQVM7b0NBQUVELE1BQU07b0NBQVE1RCxNQUFNO2dDQUF3Qzs0QkFDekU7d0JBQ0Y7b0JBQ0YsRUFBRSxPQUFNLENBQUM7b0JBQ1Q7Z0JBQ0Y7Z0JBRUEsTUFBTXNFLE9BQ0osVUFBV2QsTUFBT2xCLEdBQUcsQ0FBQ29CLFdBQ3JCO29CQUFFUyxpQkFBaUI7Z0JBQU87Z0JBTTdCLE1BQU1BLGtCQUFrQkcsS0FBS0gsZUFBZTtnQkFFNUMsa0dBQWtHO2dCQUNsRyxNQUFNSSxxQkFBcUJQLEVBQUVRLEtBQUssQ0FBQztnQkFDbkMsSUFBSUQsc0JBQXNCQSxrQkFBa0IsQ0FBQyxFQUFFLElBQUliLFFBQVE7b0JBQ3pELE1BQU1uQixNQUFNZ0Msa0JBQWtCLENBQUMsRUFBRTtvQkFDakMsTUFBTUUsT0FBT2xDLElBQUkwQixRQUFRLENBQUMsT0FBTzFCLE1BQU0sQ0FBQyxJQUFJLEVBQUVBLElBQUksQ0FBQztvQkFDbkRpQixNQUFPVSxHQUFHLENBQUNSLFFBQVE7d0JBQUUsR0FBR1ksSUFBSTt3QkFBRUksV0FBV0Q7b0JBQUs7Z0JBQ2hEO2dCQUNBLElBQUksdUNBQXVDRSxJQUFJLENBQUMzRSxTQUFTc0UsS0FBS0ksU0FBUyxFQUFFO29CQUN2RTFFLE9BQU9BLEtBQUs0RSxPQUFPLENBQUMsdUNBQXVDTixLQUFLSSxTQUFTO29CQUN6RVYsSUFBSWhFLEtBQUsyQyxXQUFXO2dCQUN0QjtnQkFHQSxJQUNFd0Isb0JBQW9CLFdBQ3BCLGlEQUFpRFEsSUFBSSxDQUFDM0UsT0FDdEQ7b0JBQ0EsSUFBSXNFLEtBQUtJLFNBQVMsRUFBRTt3QkFDbEIsSUFBSTs0QkFDRixNQUFNRyxJQUFJLE1BQU0xRCxPQUFPaUQsUUFBUSxDQUFDO2dDQUM5QmhELE1BQU07Z0NBQ05pRCxXQUFXO29DQUFFUyxLQUFLLENBQUMsb0NBQW9DLEVBQUVSLEtBQUtJLFNBQVMsQ0FBQyxDQUFDO29DQUFFSyxPQUFPO2dDQUFFOzRCQUN0Rjs0QkFDQSxNQUFNQyxTQUFTbkMsS0FBS0ssS0FBSyxDQUFDLEVBQVcrQixPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUVqRixRQUFROzRCQUMzRCxNQUFNa0YsT0FBYzlCLE1BQU1DLE9BQU8sQ0FBQzJCLFFBQVFFLFFBQVFGLE9BQU9FLElBQUksR0FBRyxFQUFFOzRCQUNsRSxNQUFNQyxNQUFNRCxJQUFJLENBQUMsRUFBRSxFQUFFRSxlQUFlZCxLQUFLZSxZQUFZLElBQUk7NEJBQ3pELE1BQU1DLE1BQU0sQ0FBQyxRQUFRLEVBQUVILElBQUksYUFBYSxFQUFFYixLQUFLSSxTQUFTLENBQUMsQ0FBQyxDQUFDOzRCQUMzRCxNQUFNdkQsT0FBT2lELFFBQVEsQ0FBQztnQ0FDcEJoRCxNQUFNO2dDQUNOaUQsV0FBVztvQ0FBRVgsUUFBUUk7b0NBQU1ELFNBQVM7d0NBQUVELE1BQU07d0NBQVE1RCxNQUFNc0Y7b0NBQUk7Z0NBQUU7NEJBQ2xFOzRCQUNBO3dCQUNGLEVBQUUsT0FBTTt3QkFDTiwwQkFBMEI7d0JBQzVCO29CQUNGO2dCQUNGO2dCQUVBLHNCQUFzQjtnQkFDdEIsSUFBSW5CLG9CQUFvQixXQUFXLDhCQUE4QlEsSUFBSSxDQUFDM0UsT0FBTztvQkFDM0UsTUFBTXNGLE1BQU1oQixLQUFLSSxTQUFTLEdBQUcsQ0FBQyxTQUFTLEVBQUVKLEtBQUtJLFNBQVMsQ0FBQyxDQUFDLEdBQUc7b0JBQzVELElBQUk7d0JBQ0YsTUFBTXZELE9BQU9pRCxRQUFRLENBQUM7NEJBQ3BCaEQsTUFBTTs0QkFDTmlELFdBQVc7Z0NBQUVYLFFBQVFJO2dDQUFNRCxTQUFTO29DQUFFRCxNQUFNO29DQUFRNUQsTUFBTXNGO2dDQUFJOzRCQUFFO3dCQUNsRTt3QkFDQTtvQkFDRixFQUFFLE9BQU0sQ0FBQztnQkFDWDtnQkFFQSxzQ0FBc0M7Z0JBQ3RDLElBQUluQixvQkFBb0IsV0FBVyxvRUFBb0VRLElBQUksQ0FBQzNFLE9BQU87b0JBQ2pILElBQUk7d0JBQ0YsK0NBQStDO3dCQUMvQyxNQUFNNkUsSUFBSSxNQUFNMUQsT0FBT2lELFFBQVEsQ0FBQzs0QkFDOUJoRCxNQUFNOzRCQUNOaUQsV0FBVztnQ0FDVFMsS0FDRTtnQ0FDRkMsT0FBTzs0QkFDVDt3QkFDRjt3QkFDQSxNQUFNQyxTQUFTbkMsS0FBS0ssS0FBSyxDQUFDLEVBQVcrQixPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUVqRixRQUFRO3dCQUMzRCxNQUFNa0YsT0FBYzlCLE1BQU1DLE9BQU8sQ0FBQzJCLFFBQVFFLFFBQVFGLE9BQU9FLElBQUksR0FBRyxFQUFFO3dCQUNsRSxNQUFNSyxNQUFNTCxLQUNUTSxHQUFHLENBQUMsQ0FBQ0MsSUFBVyxDQUFDLEVBQUUsRUFBRUEsRUFBRUMsV0FBVyxDQUFDLENBQUMsRUFBRUQsRUFBRUUsVUFBVSxDQUFDLENBQUMsRUFDcERsRixLQUFLLENBQUMsR0FBRyxJQUNUbUYsSUFBSSxDQUFDO3dCQUNSLE1BQU1DLFVBQVVOLE9BQU87d0JBQ3ZCLE1BQU1wRSxPQUFPaUQsUUFBUSxDQUFDOzRCQUNwQmhELE1BQU07NEJBQ05pRCxXQUFXO2dDQUFFWDtnQ0FBUUcsU0FBUztvQ0FBRUQsTUFBTTtvQ0FBUTVELE1BQU02RjtnQ0FBUTs0QkFBRTt3QkFDaEU7d0JBQ0E7b0JBQ0YsRUFBRSxPQUFNLENBQUM7Z0JBQ1g7Z0JBRUEscUZBQXFGO2dCQUNyRixJQUFJMUIsb0JBQW9CLFdBQVcsNEJBQTRCUSxJQUFJLENBQUMzRSxTQUFTc0UsS0FBS0ksU0FBUyxFQUFFO29CQUMzRixNQUFNb0IsTUFBTXhCLEtBQUt5QixTQUFTLElBQUl6QixLQUFLeUIsU0FBUyxHQUFHLElBQUl6QixLQUFLeUIsU0FBUyxHQUFHO29CQUNwRS9GLE9BQU8sQ0FBQyxPQUFPLEVBQUVzRSxLQUFLSSxTQUFTLENBQUMsS0FBSyxFQUFFb0IsSUFBSSxPQUFPLENBQUM7b0JBQ25EOUIsSUFBSWhFLEtBQUsyQyxXQUFXO2dCQUN0QjtnQkFFQSxzRUFBc0U7Z0JBQ3RFLE1BQU1xRCxTQUFTaEMsRUFBRVEsS0FBSyxDQUFDO2dCQUN2QixJQUFJTCxvQkFBb0IsV0FBVzZCLFVBQVUxQixLQUFLSSxTQUFTLEVBQUU7b0JBQzNELE1BQU1vQixNQUFNRyxTQUFTRCxNQUFNLENBQUMsRUFBRSxFQUFFO29CQUNoQ2hHLE9BQU8sQ0FBQyxPQUFPLEVBQUVzRSxLQUFLSSxTQUFTLENBQUMsS0FBSyxFQUFFb0IsSUFBSSxPQUFPLENBQUM7b0JBQ25EdEMsTUFBT1UsR0FBRyxDQUFDUixRQUFRO3dCQUFFLEdBQUdZLElBQUk7d0JBQUV5QixXQUFXRDtvQkFBSTtnQkFDL0M7Z0JBQ0Esa0RBQWtEO2dCQUNsRCxJQUFJM0Isb0JBQW9CLFNBQVM7b0JBQy9CLElBQUk7d0JBQ0YsTUFBTVUsSUFBSSxNQUFNMUQsT0FBT2lELFFBQVEsQ0FBQzs0QkFDOUJoRCxNQUFNOzRCQUNOaUQsV0FBVztnQ0FDVDZCLGFBQWFsRztnQ0FDYm1HLFNBQVM7Z0NBQ1RDLGVBQWU5QixLQUFLSSxTQUFTLEdBQUc7b0NBQUNKLEtBQUtJLFNBQVM7aUNBQUMsR0FBRzJCOzRCQUNyRDt3QkFDRjt3QkFDQSxNQUFNOUQsTUFBTSxHQUFZMEMsU0FBUyxDQUFDLEVBQUUsRUFBRWpGLFFBQVE7d0JBQzlDLElBQUk7NEJBQ0YsTUFBTXNHLFVBQVUvRCxNQUFNTSxLQUFLSyxLQUFLLENBQUNYLE9BQU87NEJBQ3hDLElBQUkrRCxXQUFXbEQsTUFBTUMsT0FBTyxDQUFDaUQsUUFBUXBCLElBQUksR0FBRztnQ0FDMUMsTUFBTUEsT0FBY29CLFFBQVFwQixJQUFJO2dDQUNoQyxNQUFNcUIsT0FBaUJuRCxNQUFNQyxPQUFPLENBQUNpRCxRQUFRRSxPQUFPLElBQy9DRixRQUFRRSxPQUFPLEdBQ2hCdEIsSUFBSSxDQUFDLEVBQUUsR0FDTHVCLE9BQU9DLElBQUksQ0FBQ3hCLElBQUksQ0FBQyxFQUFFLElBQ25CLEVBQUU7Z0NBQ1IsTUFBTXlCLGNBQWNKLEtBQUs5RixLQUFLLENBQUMsR0FBRztnQ0FDbEMsTUFBTW1HLE9BQU8sQ0FBQyxRQUFRLEVBQUVDLEtBQUtDLEdBQUcsQ0FBQzVCLEtBQUs2QixNQUFNLEVBQUUsSUFBSSxHQUFHLEVBQUVULFFBQVFVLFFBQVEsSUFBSTlCLEtBQUs2QixNQUFNLENBQUMsSUFBSSxDQUFDO2dDQUM1RixNQUFNOUQsT0FBT2lDLEtBQ1Z6RSxLQUFLLENBQUMsR0FBRyxJQUNUK0UsR0FBRyxDQUFDLENBQUNDLEdBQUd3QixJQUFNLENBQUMsRUFBRUEsSUFBSSxFQUFFLEVBQUUsRUFBRU4sWUFBWW5CLEdBQUcsQ0FBQzBCLENBQUFBLElBQUssQ0FBQyxFQUFFQSxFQUFFLEVBQUUsRUFBRXpFLE9BQU9nRCxDQUFDLENBQUN5QixFQUFFLElBQUksSUFBSSxDQUFDLEVBQUV0QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQzNGQSxJQUFJLENBQUM7Z0NBQ1IsTUFBTXVCLE1BQU07b0NBQUNQO29DQUFNM0Q7aUNBQUssQ0FBQ21FLE1BQU0sQ0FBQ0MsU0FBU3pCLElBQUksQ0FBQyxNQUFNbkYsS0FBSyxDQUFDLEdBQUc7Z0NBQzdELE1BQU1VLE9BQU9pRCxRQUFRLENBQUM7b0NBQ3BCaEQsTUFBTTtvQ0FDTmlELFdBQVc7d0NBQUVYLFFBQVFJO3dDQUFNRCxTQUFTOzRDQUFFRCxNQUFNOzRDQUFRNUQsTUFBTW1IO3dDQUFJO29DQUFFO2dDQUNsRTtnQ0FDQSx1REFBdUQ7Z0NBQ3ZELElBQUk7b0NBQ0YsTUFBTXJDLE1BQWNyQyxPQUFPNkQsUUFBUXhCLEdBQUcsSUFBSTtvQ0FDMUMsTUFBTXdDLFFBQVF4QyxJQUFJTixLQUFLLENBQUM7b0NBQ3hCLE1BQU0rQyxNQUFNRCxTQUFTQSxLQUFLLENBQUMsRUFBRSxHQUFHQSxLQUFLLENBQUMsRUFBRSxHQUFHaEQsS0FBS0ksU0FBUztvQ0FDekQsTUFBTThDLFVBQVU7d0NBQUUsR0FBR2xELElBQUk7d0NBQUVJLFdBQVc2Qzt3Q0FBS3hCLFdBQVc7d0NBQUlWLGNBQWNpQixRQUFRVSxRQUFRLElBQUk5QixLQUFLNkIsTUFBTTtvQ0FBQztvQ0FDeEcsSUFBSXJELFFBQVFGLE1BQU9VLEdBQUcsQ0FBQ1IsUUFBUThEO2dDQUNqQyxFQUFFLE9BQU0sQ0FBQztnQ0FDVDs0QkFDRjt3QkFDRixFQUFFLE9BQU07d0JBQ04sa0NBQWtDO3dCQUNwQztvQkFDRixFQUFFLE9BQU07b0JBQ04seUNBQXlDO29CQUMzQztnQkFDRjtnQkFFQSxNQUFNdEcsT0FBWTtvQkFDaEJnRixhQUFhbEc7b0JBQ2J5SCxPQUFPO29CQUNQQyxNQUFNO29CQUNOaEUsUUFBUUk7b0JBQ1JLO2dCQUNGO2dCQUNBLElBQUlBLG9CQUFvQixRQUFRO29CQUM5QixNQUFNd0QsbUJBQW1COUgsUUFBUWUsR0FBRyxDQUFDZ0gsc0JBQXNCLElBQUk7b0JBQy9EMUcsS0FBSzJHLFFBQVEsR0FBR0Y7Z0JBQ2xCO2dCQUVBLElBQUk7b0JBQ0YsTUFBTXhHLE9BQU9pRCxRQUFRLENBQUM7d0JBQUVoRCxNQUFNO3dCQUFrQmlELFdBQVduRDtvQkFBSztnQkFDbEUsRUFBRSxPQUFPNEcsR0FBRztnQkFDVix3Q0FBd0M7Z0JBQzFDO1lBQ0Y7UUFDRjtRQUVBLE9BQU8sSUFBSWxGLFNBQVNDLEtBQUtDLFNBQVMsQ0FBQztZQUFFaUYsSUFBSTtRQUFLLElBQUk7WUFDaEQxRixTQUFTO2dCQUFFLGdCQUFnQjtZQUFtQjtRQUNoRDtJQUNGLEVBQUUsT0FBT3lGLEdBQVE7UUFDZixPQUFPLElBQUlsRixTQUFTQyxLQUFLQyxTQUFTLENBQUM7WUFBRUMsT0FBTytFLEdBQUdqRSxXQUFXcEIsT0FBT3FGO1FBQUcsSUFBSTtZQUN0RTlFLFFBQVE7WUFDUlgsU0FBUztnQkFBRSxnQkFBZ0I7WUFBbUI7UUFDaEQ7SUFDRjtBQUNGIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vbGluZS1ib3QtbWNwLXVpLy4vYXBwL2FwaS9saW5lLXdlYmhvb2svcm91dGUudHM/MjMwNSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgcnVudGltZSA9IFwibm9kZWpzXCI7XG5leHBvcnQgY29uc3QgZHluYW1pYyA9IFwiZm9yY2UtZHluYW1pY1wiO1xuXG5pbXBvcnQgY3J5cHRvIGZyb20gXCJjcnlwdG9cIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBDbGllbnQgfSBmcm9tIFwiQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9jbGllbnQvaW5kZXguanNcIjtcbmltcG9ydCB7IFN0ZGlvQ2xpZW50VHJhbnNwb3J0IH0gZnJvbSBcIkBtb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvY2xpZW50L3N0ZGlvLmpzXCI7XG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXZhclxuICB2YXIgX19tY3BDbGllbnRXZWJob29rOiBDbGllbnQgfCB1bmRlZmluZWQ7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby12YXJcbiAgdmFyIF9fdXNlclByZWZzOlxuICAgIHwgTWFwPFxuICAgICAgICBzdHJpbmcsXG4gICAgICAgIHtcbiAgICAgICAgICBrbm93bGVkZ2VTb3VyY2U6IFwiZmlsZVwiIHwgXCJtc3NxbFwiO1xuICAgICAgICAgIGxhc3RUYWJsZT86IHN0cmluZztcbiAgICAgICAgICBsYXN0TGltaXQ/OiBudW1iZXI7XG4gICAgICAgICAgbGFzdFJvd0NvdW50PzogbnVtYmVyO1xuICAgICAgICB9XG4gICAgICA+XG4gICAgfCB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGxvYWRQYXJlbnRFbnZPbmNlKCkge1xuICB0cnkge1xuICAgIGNvbnN0IGxvYWRlZEZsYWcgPSAoZ2xvYmFsVGhpcyBhcyBhbnkpLl9fcGFyZW50RW52TG9hZGVkO1xuICAgIGlmIChsb2FkZWRGbGFnKSByZXR1cm47XG4gICAgY29uc3QgcGFyZW50RW52ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIFwiLi5cIiwgXCIuZW52XCIpO1xuICAgIGlmIChmcy5leGlzdHNTeW5jKHBhcmVudEVudikpIHtcbiAgICAgIGNvbnN0IHRleHQgPSBmcy5yZWFkRmlsZVN5bmMocGFyZW50RW52LCBcInV0ZjhcIik7XG4gICAgICBmb3IgKGNvbnN0IGxpbmUgb2YgdGV4dC5zcGxpdCgvXFxyP1xcbi8pKSB7XG4gICAgICAgIGlmICghbGluZSB8fCBsaW5lLnRyaW0oKS5zdGFydHNXaXRoKFwiI1wiKSkgY29udGludWU7XG4gICAgICAgIGNvbnN0IGlkeCA9IGxpbmUuaW5kZXhPZihcIj1cIik7XG4gICAgICAgIGlmIChpZHggPD0gMCkgY29udGludWU7XG4gICAgICAgIGNvbnN0IGtleSA9IGxpbmUuc2xpY2UoMCwgaWR4KS50cmltKCk7XG4gICAgICAgIGxldCB2YWwgPSBsaW5lLnNsaWNlKGlkeCArIDEpLnRyaW0oKTtcbiAgICAgICAgaWYgKCh2YWwuc3RhcnRzV2l0aCgnXCInKSAmJiB2YWwuZW5kc1dpdGgoJ1wiJykpIHx8ICh2YWwuc3RhcnRzV2l0aChcIidcIikgJiYgdmFsLmVuZHNXaXRoKFwiJ1wiKSkpIHtcbiAgICAgICAgICB2YWwgPSB2YWwuc2xpY2UoMSwgLTEpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcHJvY2Vzcy5lbnZba2V5XSkgcHJvY2Vzcy5lbnZba2V5XSA9IHZhbDtcbiAgICAgIH1cbiAgICB9XG4gICAgKGdsb2JhbFRoaXMgYXMgYW55KS5fX3BhcmVudEVudkxvYWRlZCA9IHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIC8vIGlnbm9yZVxuICB9XG59XG5sb2FkUGFyZW50RW52T25jZSgpO1xuXG5hc3luYyBmdW5jdGlvbiBnZXRDbGllbnQoKTogUHJvbWlzZTxDbGllbnQ+IHtcbiAgaWYgKGdsb2JhbFRoaXMuX19tY3BDbGllbnRXZWJob29rKSByZXR1cm4gZ2xvYmFsVGhpcy5fX21jcENsaWVudFdlYmhvb2s7XG5cbiAgY29uc3QgcHJvamVjdFJvb3QgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgXCIuLlwiKTtcbiAgY29uc3QgdHJhbnNwb3J0ID0gbmV3IFN0ZGlvQ2xpZW50VHJhbnNwb3J0KHtcbiAgICBjb21tYW5kOiBcIm5vZGVcIixcbiAgICBhcmdzOiBbXCJkaXN0L2luZGV4LmpzXCJdLFxuICAgIGN3ZDogcHJvamVjdFJvb3QsXG4gICAgZW52OiBwcm9jZXNzLmVudiBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuICB9KTtcbiAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudCh7IG5hbWU6IFwibGluZS1ib3Qtd2ViaG9va1wiLCB2ZXJzaW9uOiBcIjAuMS4wXCIgfSk7XG4gIGF3YWl0IGNsaWVudC5jb25uZWN0KHRyYW5zcG9ydCk7XG4gIGdsb2JhbFRoaXMuX19tY3BDbGllbnRXZWJob29rID0gY2xpZW50O1xuICByZXR1cm4gY2xpZW50O1xufVxuXG5mdW5jdGlvbiB2ZXJpZnlMaW5lU2lnbmF0dXJlKHJhd0JvZHk6IHN0cmluZywgc2lnbmF0dXJlOiBzdHJpbmcgfCBudWxsKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc2VjcmV0ID0gcHJvY2Vzcy5lbnYuQ0hBTk5FTF9TRUNSRVQgfHwgXCJcIjtcbiAgICBpZiAoIXNlY3JldCB8fCAhc2lnbmF0dXJlKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgaG1hYyA9IGNyeXB0by5jcmVhdGVIbWFjKFwic2hhMjU2XCIsIHNlY3JldCk7XG4gICAgaG1hYy51cGRhdGUocmF3Qm9keSk7XG4gICAgY29uc3QgZGlnZXN0ID0gaG1hYy5kaWdlc3QoXCJiYXNlNjRcIik7XG4gICAgcmV0dXJuIGNyeXB0by50aW1pbmdTYWZlRXF1YWwoQnVmZmVyLmZyb20oZGlnZXN0KSwgQnVmZmVyLmZyb20oc2lnbmF0dXJlKSk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG50eXBlIExpbmVFdmVudCA9IHtcbiAgdHlwZTogc3RyaW5nO1xuICByZXBseVRva2VuPzogc3RyaW5nO1xuICBzb3VyY2U/OiB7IHVzZXJJZD86IHN0cmluZyB9O1xuICBtZXNzYWdlPzogeyB0eXBlPzogc3RyaW5nOyB0ZXh0Pzogc3RyaW5nIH07XG59O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gUE9TVChyZXE6IFJlcXVlc3QpIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBzaWduYXR1cmUgPSByZXEuaGVhZGVycy5nZXQoXCJ4LWxpbmUtc2lnbmF0dXJlXCIpO1xuICAgIGNvbnN0IHJhdyA9IGF3YWl0IHJlcS50ZXh0KCk7XG4gICAgY29uc3QgZGlzYWJsZVZlcmlmeSA9IFN0cmluZyhwcm9jZXNzLmVudi5ESVNBQkxFX0xJTkVfU0lHTkFUVVJFX1ZFUklGWSB8fCBcIlwiKS50b0xvd2VyQ2FzZSgpID09PSBcInRydWVcIjtcbiAgICBpZiAoIWRpc2FibGVWZXJpZnkgJiYgIXZlcmlmeUxpbmVTaWduYXR1cmUocmF3LCBzaWduYXR1cmUpKSB7XG4gICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KHsgZXJyb3I6IFwiaW52YWxpZCBzaWduYXR1cmVcIiB9KSwge1xuICAgICAgICBzdGF0dXM6IDQwMSxcbiAgICAgICAgaGVhZGVyczogeyBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIiB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgYm9keSA9IEpTT04ucGFyc2UocmF3KSBhcyB7IGV2ZW50cz86IExpbmVFdmVudFtdIH07XG4gICAgY29uc3QgZXZlbnRzID0gQXJyYXkuaXNBcnJheShib2R5Py5ldmVudHMpID8gYm9keS5ldmVudHMgOiBbXTtcblxuICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IGdldENsaWVudCgpO1xuICAgIGlmICghZ2xvYmFsVGhpcy5fX3VzZXJQcmVmcykgZ2xvYmFsVGhpcy5fX3VzZXJQcmVmcyA9IG5ldyBNYXAoKTtcbiAgICBjb25zdCBwcmVmcyA9IGdsb2JhbFRoaXMuX191c2VyUHJlZnM7XG5cbiAgICBmb3IgKGNvbnN0IGV2IG9mIGV2ZW50cykge1xuICAgICAgY29uc3QgdXNlcklkID0gZXY/LnNvdXJjZT8udXNlcklkIHx8IFwiXCI7XG4gICAgICBpZiAoZXY/LnR5cGUgPT09IFwibWVzc2FnZVwiICYmIGV2Py5tZXNzYWdlPy50eXBlID09PSBcInRleHRcIikge1xuICAgICAgICBsZXQgdGV4dCA9IGV2Lm1lc3NhZ2UudGV4dCB8fCBcIlwiO1xuICAgICAgICBjb25zdCBkZXN0ID0gdXNlcklkIHx8IChwcm9jZXNzLmVudi5ERVNUSU5BVElPTl9VU0VSX0lEIHx8IFwiXCIpO1xuICAgICAgICBsZXQgdCA9IHRleHQudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgaWYgKHQuaW5jbHVkZXMoXCJsb2dpbiBkYlwiKSkge1xuICAgICAgICAgIGlmICh1c2VySWQpIHByZWZzIS5zZXQodXNlcklkLCB7IGtub3dsZWRnZVNvdXJjZTogXCJtc3NxbFwiIH0pO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBjbGllbnQuY2FsbFRvb2woe1xuICAgICAgICAgICAgICBuYW1lOiBcInB1c2hfdGV4dF9tZXNzYWdlXCIsXG4gICAgICAgICAgICAgIGFyZ3VtZW50czoge1xuICAgICAgICAgICAgICAgIHVzZXJJZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiB7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBcIuC5gOC4iuC4t+C5iOC4reC4oeC4leC5iOC4reC4kOC4suC4meC4guC5ieC4reC4oeC4ueC4pSAoTVNTUUwpIOC4quC4s+C4q+C4o+C4seC4muC5guC4q+C4oeC4lOC4luC4suC4oS/guJXguK3guJrguYHguKXguYnguKdcIiB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBjYXRjaCB7fVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0LmluY2x1ZGVzKFwibG9nb3V0IGRiXCIpKSB7XG4gICAgICAgICAgaWYgKHVzZXJJZCkgcHJlZnMhLnNldCh1c2VySWQsIHsga25vd2xlZGdlU291cmNlOiBcImZpbGVcIiB9KTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgY2xpZW50LmNhbGxUb29sKHtcbiAgICAgICAgICAgICAgbmFtZTogXCJwdXNoX3RleHRfbWVzc2FnZVwiLFxuICAgICAgICAgICAgICBhcmd1bWVudHM6IHtcbiAgICAgICAgICAgICAgICB1c2VySWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCLguKLguIHguYDguKXguLTguIHguYLguKvguKHguJTguJDguLLguJnguILguYnguK3guKHguLnguKUg4LmD4LiK4LmJ4LmE4Lif4Lil4LmM4LiE4Lin4Liy4Lih4Lij4Li54LmJ4LmB4LiX4LiZXCIgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gY2F0Y2gge31cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHByZWYgPVxuICAgICAgICAgICh1c2VySWQgJiYgcHJlZnMhLmdldCh1c2VySWQpKSB8fFxuICAgICAgICAgICh7IGtub3dsZWRnZVNvdXJjZTogXCJmaWxlXCIgfSBhcyB7XG4gICAgICAgICAgICBrbm93bGVkZ2VTb3VyY2U6IFwiZmlsZVwiIHwgXCJtc3NxbFwiO1xuICAgICAgICAgICAgbGFzdFRhYmxlPzogc3RyaW5nO1xuICAgICAgICAgICAgbGFzdExpbWl0PzogbnVtYmVyO1xuICAgICAgICAgICAgbGFzdFJvd0NvdW50PzogbnVtYmVyO1xuICAgICAgICAgIH0pO1xuICAgICAgICBjb25zdCBrbm93bGVkZ2VTb3VyY2UgPSBwcmVmLmtub3dsZWRnZVNvdXJjZTtcblxuICAgICAgICAvLyBIZXVyaXN0aWM6IHJlbWVtYmVyIGV4cGxpY2l0IHRhYmxlIG1lbnRpb25zIGFuZCBzdXBwb3J0IHByb25vdW4gXCLguJXguLLguKPguLLguIfguJnguLXguYkvdGFibGUg4LiZ4Li14LmJL3RoaXMgdGFibGVcIlxuICAgICAgICBjb25zdCBleHBsaWNpdFRhYmxlTWF0Y2ggPSB0Lm1hdGNoKC8oPzp0YWJsZXzguIjguLLguIF84LmA4LiC4LmJ4Liy4LmE4LibfOC5hOC4m3xmcm9tKVxccysoW2EtejAtOV9cXC5dKykvaSk7XG4gICAgICAgIGlmIChleHBsaWNpdFRhYmxlTWF0Y2ggJiYgZXhwbGljaXRUYWJsZU1hdGNoWzFdICYmIHVzZXJJZCkge1xuICAgICAgICAgIGNvbnN0IHJhdyA9IGV4cGxpY2l0VGFibGVNYXRjaFsxXTtcbiAgICAgICAgICBjb25zdCBmdWxsID0gcmF3LmluY2x1ZGVzKFwiLlwiKSA/IHJhdyA6IGBkYm8uJHtyYXd9YDtcbiAgICAgICAgICBwcmVmcyEuc2V0KHVzZXJJZCwgeyAuLi5wcmVmLCBsYXN0VGFibGU6IGZ1bGwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKC8o4LiV4Liy4Lij4Liy4LiH4LiZ4Li14LmJfHRhYmxlXFxzKuC4meC4teC5iXx0aGlzXFxzKnRhYmxlKS9pLnRlc3QodGV4dCkgJiYgcHJlZi5sYXN0VGFibGUpIHtcbiAgICAgICAgICB0ZXh0ID0gdGV4dC5yZXBsYWNlKC/guJXguLLguKPguLLguIfguJnguLXguYl8dGFibGVcXHMq4LiZ4Li14LmJfHRoaXNcXHMqdGFibGUvZ2ksIHByZWYubGFzdFRhYmxlKTtcbiAgICAgICAgICB0ID0gdGV4dC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICB9XG5cblxuICAgICAgICBpZiAoXG4gICAgICAgICAga25vd2xlZGdlU291cmNlID09PSBcIm1zc3FsXCIgJiZcbiAgICAgICAgICAvKOC4l+C4seC5ieC4h+C4q+C4oeC4lOC4geC4teC5iOC4o+C4suC4ouC4geC4suC4o3zguKHguLXguIHguLXguYjguKPguLLguKLguIHguLLguKN8Y291bnRcXHMqKGFsbCk/KS9pLnRlc3QodGV4dClcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKHByZWYubGFzdFRhYmxlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCBxID0gYXdhaXQgY2xpZW50LmNhbGxUb29sKHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcInF1ZXJ5X21zc3FsXCIsXG4gICAgICAgICAgICAgICAgYXJndW1lbnRzOiB7IHNxbDogYFNFTEVDVCBDT1VOVCgxKSBBUyB0b3RhbF9jb3VudCBGUk9NICR7cHJlZi5sYXN0VGFibGV9YCwgbGltaXQ6IDEgfSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoKHEgYXMgYW55KS5jb250ZW50Py5bMF0/LnRleHQgfHwgXCJ7fVwiKTtcbiAgICAgICAgICAgICAgY29uc3Qgcm93czogYW55W10gPSBBcnJheS5pc0FycmF5KHBhcnNlZD8ucm93cykgPyBwYXJzZWQucm93cyA6IFtdO1xuICAgICAgICAgICAgICBjb25zdCBjbnQgPSByb3dzWzBdPy50b3RhbF9jb3VudCA/PyBwcmVmLmxhc3RSb3dDb3VudCA/PyAwO1xuICAgICAgICAgICAgICBjb25zdCBtc2cgPSBg4LiX4Lix4LmJ4LiH4Lir4Lih4LiUICR7Y250fSDguKPguLLguKLguIHguLLguKMgKOC4iOC4suC4gSAke3ByZWYubGFzdFRhYmxlfSlgO1xuICAgICAgICAgICAgICBhd2FpdCBjbGllbnQuY2FsbFRvb2woe1xuICAgICAgICAgICAgICAgIG5hbWU6IFwicHVzaF90ZXh0X21lc3NhZ2VcIixcbiAgICAgICAgICAgICAgICBhcmd1bWVudHM6IHsgdXNlcklkOiBkZXN0LCBtZXNzYWdlOiB7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBtc2cgfSB9LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgLy8gaWdub3JlIGFuZCBmYWxsIHRocm91Z2hcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyAyKSBBc2sgd2hpY2ggdGFibGU/XG4gICAgICAgIGlmIChrbm93bGVkZ2VTb3VyY2UgPT09IFwibXNzcWxcIiAmJiAvKOC4iOC4suC4geC4leC4suC4o+C4suC4h+C5hOC4q+C4mXx3aGF0XFxzKnRhYmxlKS9pLnRlc3QodGV4dCkpIHtcbiAgICAgICAgICBjb25zdCBtc2cgPSBwcmVmLmxhc3RUYWJsZSA/IGDguIjguLLguIHguJXguLLguKPguLLguIcgJHtwcmVmLmxhc3RUYWJsZX1gIDogXCLguKLguLHguIfguYTguKHguYjguJfguKPguLLguJrguJXguLLguKPguLLguIcgKOC5guC4m+C4o+C4lOC4o+C4sOC4muC4uClcIjtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgY2xpZW50LmNhbGxUb29sKHtcbiAgICAgICAgICAgICAgbmFtZTogXCJwdXNoX3RleHRfbWVzc2FnZVwiLFxuICAgICAgICAgICAgICBhcmd1bWVudHM6IHsgdXNlcklkOiBkZXN0LCBtZXNzYWdlOiB7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBtc2cgfSB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9IGNhdGNoIHt9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB1c2VyIGFza3MgZm9yIGFsbCB0YWJsZXMgc3VtbWFyeVxuICAgICAgICBpZiAoa25vd2xlZGdlU291cmNlID09PSBcIm1zc3FsXCIgJiYgLyjguYHguKrguJTguIfguILguYnguK3guKHguLnguKUuKuC4leC4suC4o+C4suC4hy4q4LiX4Lix4LmJ4LiH4Lir4Lih4LiUfOC5geC4quC4lOC4h+C4guC5ieC4reC4oeC4ueC4peC5geC4leC5iOC4peC4sFxccyrguJXguLLguKPguLLguId84LiX4Li44LiBXFxzKuC4leC4suC4o+C4suC4hykvaS50ZXN0KHRleHQpKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFVzZSBNQ1AgdG9vbCBxdWVyeV9tc3NxbCB0byBmZXRjaCB0YWJsZSBsaXN0XG4gICAgICAgICAgICBjb25zdCBxID0gYXdhaXQgY2xpZW50LmNhbGxUb29sKHtcbiAgICAgICAgICAgICAgbmFtZTogXCJxdWVyeV9tc3NxbFwiLFxuICAgICAgICAgICAgICBhcmd1bWVudHM6IHtcbiAgICAgICAgICAgICAgICBzcWw6XG4gICAgICAgICAgICAgICAgICBcIlNFTEVDVCBUT1AgNTAgcy5uYW1lIEFTIHNjaGVtYV9uYW1lLCB0Lm5hbWUgQVMgdGFibGVfbmFtZSBGUk9NIHN5cy50YWJsZXMgdCBKT0lOIHN5cy5zY2hlbWFzIHMgT04gdC5zY2hlbWFfaWQgPSBzLnNjaGVtYV9pZCBXSEVSRSB0LmlzX21zX3NoaXBwZWQgPSAwIE9SREVSIEJZIHMubmFtZSwgdC5uYW1lXCIsXG4gICAgICAgICAgICAgICAgbGltaXQ6IDUwLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKChxIGFzIGFueSkuY29udGVudD8uWzBdPy50ZXh0IHx8IFwie31cIik7XG4gICAgICAgICAgICBjb25zdCByb3dzOiBhbnlbXSA9IEFycmF5LmlzQXJyYXkocGFyc2VkPy5yb3dzKSA/IHBhcnNlZC5yb3dzIDogW107XG4gICAgICAgICAgICBjb25zdCBvdXQgPSByb3dzXG4gICAgICAgICAgICAgIC5tYXAoKHI6IGFueSkgPT4gYC0gJHtyLnNjaGVtYV9uYW1lfS4ke3IudGFibGVfbmFtZX1gKVxuICAgICAgICAgICAgICAuc2xpY2UoMCwgNTApXG4gICAgICAgICAgICAgIC5qb2luKFwiXFxuXCIpO1xuICAgICAgICAgICAgY29uc3QgdGV4dE1zZyA9IG91dCB8fCBcIijguYTguKHguYjguJ7guJrguJXguLLguKPguLLguIcpXCI7XG4gICAgICAgICAgICBhd2FpdCBjbGllbnQuY2FsbFRvb2woe1xuICAgICAgICAgICAgICBuYW1lOiBcInB1c2hfdGV4dF9tZXNzYWdlXCIsXG4gICAgICAgICAgICAgIGFyZ3VtZW50czogeyB1c2VySWQsIG1lc3NhZ2U6IHsgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IHRleHRNc2cgfSB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9IGNhdGNoIHt9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB1c2VyIHNheXMgXCLguYHguKrguJTguIfguKHguLIv4LmC4LiK4Lin4LmM4Lir4LiZ4LmI4Lit4LiiL+C5gOC4reC4suC4oeC4slwiIGFuZCB3ZSBoYXZlIGxhc3RUYWJsZSAoKyBvcHRpb25hbCBsYXN0TGltaXQpXG4gICAgICAgIGlmIChrbm93bGVkZ2VTb3VyY2UgPT09IFwibXNzcWxcIiAmJiAvKOC5geC4quC4lOC4h+C4oeC4snzguYLguIrguKfguYzguKvguJnguYjguK3guKJ84LmA4Lit4Liy4Lih4LiyKS9pLnRlc3QodGV4dCkgJiYgcHJlZi5sYXN0VGFibGUpIHtcbiAgICAgICAgICBjb25zdCBsaW0gPSBwcmVmLmxhc3RMaW1pdCAmJiBwcmVmLmxhc3RMaW1pdCA+IDAgPyBwcmVmLmxhc3RMaW1pdCA6IDEwO1xuICAgICAgICAgIHRleHQgPSBg4LmA4LiC4LmJ4Liy4LmE4LibICR7cHJlZi5sYXN0VGFibGV9IOC5geC4quC4lOC4hyR7bGltfSDguILguYnguK3guKHguLnguKVgO1xuICAgICAgICAgIHQgPSB0ZXh0LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB1c2VyIHNheXMgXCLguYHguKrguJTguIcge059ICjguKPguLLguKLguIHguLLguKN84LmB4LiW4LinKVwiIGFuZCB3ZSBoYXZlIGxhc3RUYWJsZSwgcmV3cml0ZVxuICAgICAgICBjb25zdCBtU2hvd04gPSB0Lm1hdGNoKC/guYHguKrguJTguIcoPzrguILguYnguK3guKHguLnguKUpP1xccyooXFxkezEsNH0pXFxzKig/OuC4o+C4suC4ouC4geC4suC4o3zguYHguJbguKcpPy9pKTtcbiAgICAgICAgaWYgKGtub3dsZWRnZVNvdXJjZSA9PT0gXCJtc3NxbFwiICYmIG1TaG93TiAmJiBwcmVmLmxhc3RUYWJsZSkge1xuICAgICAgICAgIGNvbnN0IGxpbSA9IHBhcnNlSW50KG1TaG93TlsxXSwgMTApO1xuICAgICAgICAgIHRleHQgPSBg4LmA4LiC4LmJ4Liy4LmE4LibICR7cHJlZi5sYXN0VGFibGV9IOC5geC4quC4lOC4hyR7bGltfSDguILguYnguK3guKHguLnguKVgO1xuICAgICAgICAgIHByZWZzIS5zZXQodXNlcklkLCB7IC4uLnByZWYsIGxhc3RMaW1pdDogbGltIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRyeSBBSS1kcml2ZW4gU1FMIGZpcnN0IHdoZW4gdXNpbmcgREIga25vd2xlZGdlXG4gICAgICAgIGlmIChrbm93bGVkZ2VTb3VyY2UgPT09IFwibXNzcWxcIikge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBxID0gYXdhaXQgY2xpZW50LmNhbGxUb29sKHtcbiAgICAgICAgICAgICAgbmFtZTogXCJhaV9xdWVyeV9tc3NxbFwiLFxuICAgICAgICAgICAgICBhcmd1bWVudHM6IHtcbiAgICAgICAgICAgICAgICBpbnN0cnVjdGlvbjogdGV4dCxcbiAgICAgICAgICAgICAgICBtYXhSb3dzOiAxMCxcbiAgICAgICAgICAgICAgICBhbGxvd2VkVGFibGVzOiBwcmVmLmxhc3RUYWJsZSA/IFtwcmVmLmxhc3RUYWJsZV0gOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IHJhdyA9IChxIGFzIGFueSk/LmNvbnRlbnQ/LlswXT8udGV4dCB8fCBcIlwiO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHJhdyA/IEpTT04ucGFyc2UocmF3KSA6IG51bGw7XG4gICAgICAgICAgICAgIGlmIChwYXlsb2FkICYmIEFycmF5LmlzQXJyYXkocGF5bG9hZC5yb3dzKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJvd3M6IGFueVtdID0gcGF5bG9hZC5yb3dzIGFzIGFueVtdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbHM6IHN0cmluZ1tdID0gQXJyYXkuaXNBcnJheShwYXlsb2FkLmNvbHVtbnMpXG4gICAgICAgICAgICAgICAgICA/IChwYXlsb2FkLmNvbHVtbnMgYXMgc3RyaW5nW10pXG4gICAgICAgICAgICAgICAgICA6IHJvd3NbMF1cbiAgICAgICAgICAgICAgICAgICAgPyBPYmplY3Qua2V5cyhyb3dzWzBdKVxuICAgICAgICAgICAgICAgICAgICA6IFtdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHByZXZpZXdDb2xzID0gY29scy5zbGljZSgwLCAzKTtcbiAgICAgICAgICAgICAgICBjb25zdCBoZWFkID0gYOC4nOC4peC4peC4seC4nuC4mOC5jCAke01hdGgubWluKHJvd3MubGVuZ3RoLCAxMCl9IC8gJHtwYXlsb2FkLnJvd0NvdW50ID8/IHJvd3MubGVuZ3RofSDguYHguJbguKdgO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJvZHkgPSByb3dzXG4gICAgICAgICAgICAgICAgICAuc2xpY2UoMCwgMTApXG4gICAgICAgICAgICAgICAgICAubWFwKChyLCBpKSA9PiBgJHtpICsgMX0uICR7cHJldmlld0NvbHMubWFwKGMgPT4gYCR7Y306ICR7U3RyaW5nKHJbY10gPz8gXCJcIil9YCkuam9pbihcIiwgXCIpfWApXG4gICAgICAgICAgICAgICAgICAuam9pbihcIlxcblwiKTtcbiAgICAgICAgICAgICAgICBjb25zdCB0eHQgPSBbaGVhZCwgYm9keV0uZmlsdGVyKEJvb2xlYW4pLmpvaW4oXCJcXG5cIikuc2xpY2UoMCwgMjAwMCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY2xpZW50LmNhbGxUb29sKHtcbiAgICAgICAgICAgICAgICAgIG5hbWU6IFwicHVzaF90ZXh0X21lc3NhZ2VcIixcbiAgICAgICAgICAgICAgICAgIGFyZ3VtZW50czogeyB1c2VySWQ6IGRlc3QsIG1lc3NhZ2U6IHsgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IHR4dCB9IH0sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgLy8gVHJ5IHRvIGV4dHJhY3QgdGFibGUgbmFtZSBmcm9tIFNRTCBhbmQgc3RvcmUgY29udGV4dFxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBzcWw6IHN0cmluZyA9IFN0cmluZyhwYXlsb2FkLnNxbCB8fCBcIlwiKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG1Gcm9tID0gc3FsLm1hdGNoKC9mcm9tXFxzKyhbYS16MC05X1xcLl0rKS9pKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHRibCA9IG1Gcm9tICYmIG1Gcm9tWzFdID8gbUZyb21bMV0gOiBwcmVmLmxhc3RUYWJsZTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ByZWYgPSB7IC4uLnByZWYsIGxhc3RUYWJsZTogdGJsLCBsYXN0TGltaXQ6IDEwLCBsYXN0Um93Q291bnQ6IHBheWxvYWQucm93Q291bnQgPz8gcm93cy5sZW5ndGggfTtcbiAgICAgICAgICAgICAgICAgIGlmICh1c2VySWQpIHByZWZzIS5zZXQodXNlcklkLCBuZXdQcmVmKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIHt9XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAvLyBwYXJzaW5nIGZhaWxlZDsgZmFsbCBiYWNrIGJlbG93XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBhaV9xdWVyeV9tc3NxbCBmYWlsZWQ7IGZhbGwgYmFjayBiZWxvd1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgICBpbnN0cnVjdGlvbjogdGV4dCxcbiAgICAgICAgICBtb2RlbDogXCJnZW1pbmktMi4wLWZsYXNoXCIsXG4gICAgICAgICAgbW9kZTogXCJhdXRvXCIsXG4gICAgICAgICAgdXNlcklkOiBkZXN0LFxuICAgICAgICAgIGtub3dsZWRnZVNvdXJjZSxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGtub3dsZWRnZVNvdXJjZSA9PT0gXCJmaWxlXCIpIHtcbiAgICAgICAgICBjb25zdCBkZWZhdWx0S25vd2xlZGdlID0gcHJvY2Vzcy5lbnYuREVGQVVMVF9LTk9XTEVER0VfRklMRSB8fCBcImRvY3MvZGF0YS1sZWFybmluZy9rbm93bGVkZ2UubWRcIjtcbiAgICAgICAgICBhcmdzLmZpbGVQYXRoID0gZGVmYXVsdEtub3dsZWRnZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgY2xpZW50LmNhbGxUb29sKHsgbmFtZTogXCJnZW1pbmlfY29tbWFuZFwiLCBhcmd1bWVudHM6IGFyZ3MgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAvLyBzd2FsbG93IHRvIG5vdCBicmVhayB3ZWJob29rIHBpcGVsaW5lXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KHsgb2s6IHRydWUgfSksIHtcbiAgICAgIGhlYWRlcnM6IHsgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIgfSxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgcmV0dXJuIG5ldyBSZXNwb25zZShKU09OLnN0cmluZ2lmeSh7IGVycm9yOiBlPy5tZXNzYWdlIHx8IFN0cmluZyhlKSB9KSwge1xuICAgICAgc3RhdHVzOiA1MDAsXG4gICAgICBoZWFkZXJzOiB7IFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiIH0sXG4gICAgfSk7XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJydW50aW1lIiwiZHluYW1pYyIsImNyeXB0byIsImZzIiwicGF0aCIsIkNsaWVudCIsIlN0ZGlvQ2xpZW50VHJhbnNwb3J0IiwibG9hZFBhcmVudEVudk9uY2UiLCJsb2FkZWRGbGFnIiwiZ2xvYmFsVGhpcyIsIl9fcGFyZW50RW52TG9hZGVkIiwicGFyZW50RW52IiwicmVzb2x2ZSIsInByb2Nlc3MiLCJjd2QiLCJleGlzdHNTeW5jIiwidGV4dCIsInJlYWRGaWxlU3luYyIsImxpbmUiLCJzcGxpdCIsInRyaW0iLCJzdGFydHNXaXRoIiwiaWR4IiwiaW5kZXhPZiIsImtleSIsInNsaWNlIiwidmFsIiwiZW5kc1dpdGgiLCJlbnYiLCJnZXRDbGllbnQiLCJfX21jcENsaWVudFdlYmhvb2siLCJwcm9qZWN0Um9vdCIsInRyYW5zcG9ydCIsImNvbW1hbmQiLCJhcmdzIiwiY2xpZW50IiwibmFtZSIsInZlcnNpb24iLCJjb25uZWN0IiwidmVyaWZ5TGluZVNpZ25hdHVyZSIsInJhd0JvZHkiLCJzaWduYXR1cmUiLCJzZWNyZXQiLCJDSEFOTkVMX1NFQ1JFVCIsImhtYWMiLCJjcmVhdGVIbWFjIiwidXBkYXRlIiwiZGlnZXN0IiwidGltaW5nU2FmZUVxdWFsIiwiQnVmZmVyIiwiZnJvbSIsIlBPU1QiLCJyZXEiLCJoZWFkZXJzIiwiZ2V0IiwicmF3IiwiZGlzYWJsZVZlcmlmeSIsIlN0cmluZyIsIkRJU0FCTEVfTElORV9TSUdOQVRVUkVfVkVSSUZZIiwidG9Mb3dlckNhc2UiLCJSZXNwb25zZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJlcnJvciIsInN0YXR1cyIsImJvZHkiLCJwYXJzZSIsImV2ZW50cyIsIkFycmF5IiwiaXNBcnJheSIsIl9fdXNlclByZWZzIiwiTWFwIiwicHJlZnMiLCJldiIsInVzZXJJZCIsInNvdXJjZSIsInR5cGUiLCJtZXNzYWdlIiwiZGVzdCIsIkRFU1RJTkFUSU9OX1VTRVJfSUQiLCJ0IiwiaW5jbHVkZXMiLCJzZXQiLCJrbm93bGVkZ2VTb3VyY2UiLCJjYWxsVG9vbCIsImFyZ3VtZW50cyIsInByZWYiLCJleHBsaWNpdFRhYmxlTWF0Y2giLCJtYXRjaCIsImZ1bGwiLCJsYXN0VGFibGUiLCJ0ZXN0IiwicmVwbGFjZSIsInEiLCJzcWwiLCJsaW1pdCIsInBhcnNlZCIsImNvbnRlbnQiLCJyb3dzIiwiY250IiwidG90YWxfY291bnQiLCJsYXN0Um93Q291bnQiLCJtc2ciLCJvdXQiLCJtYXAiLCJyIiwic2NoZW1hX25hbWUiLCJ0YWJsZV9uYW1lIiwiam9pbiIsInRleHRNc2ciLCJsaW0iLCJsYXN0TGltaXQiLCJtU2hvd04iLCJwYXJzZUludCIsImluc3RydWN0aW9uIiwibWF4Um93cyIsImFsbG93ZWRUYWJsZXMiLCJ1bmRlZmluZWQiLCJwYXlsb2FkIiwiY29scyIsImNvbHVtbnMiLCJPYmplY3QiLCJrZXlzIiwicHJldmlld0NvbHMiLCJoZWFkIiwiTWF0aCIsIm1pbiIsImxlbmd0aCIsInJvd0NvdW50IiwiaSIsImMiLCJ0eHQiLCJmaWx0ZXIiLCJCb29sZWFuIiwibUZyb20iLCJ0YmwiLCJuZXdQcmVmIiwibW9kZWwiLCJtb2RlIiwiZGVmYXVsdEtub3dsZWRnZSIsIkRFRkFVTFRfS05PV0xFREdFX0ZJTEUiLCJmaWxlUGF0aCIsImUiLCJvayJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(rsc)/./app/api/line-webhook/route.ts\n"); /***/ }) }; ; // load runtime var __webpack_require__ = require("../../../webpack-runtime.js"); __webpack_require__.C(exports); var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) var __webpack_exports__ = __webpack_require__.X(0, ["vendor-chunks/ajv","vendor-chunks/zod","vendor-chunks/next","vendor-chunks/@modelcontextprotocol","vendor-chunks/uri-js","vendor-chunks/cross-spawn","vendor-chunks/which","vendor-chunks/isexe","vendor-chunks/json-schema-traverse","vendor-chunks/fast-json-stable-stringify","vendor-chunks/fast-deep-equal","vendor-chunks/path-key","vendor-chunks/shebang-command","vendor-chunks/shebang-regex"], () => (__webpack_exec__("(rsc)/./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fline-webhook%2Froute&page=%2Fapi%2Fline-webhook%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Fline-webhook%2Froute.ts&appDir=D%3A%5Cfame%5Cnon-project%5Cline-bot-mcp-server%5Cui-next%5Capp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=D%3A%5Cfame%5Cnon-project%5Cline-bot-mcp-server%5Cui-next&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=standalone&preferredRegion=&middlewareConfig=e30%3D!"))); module.exports = __webpack_exports__; })();

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tndfame/mcp_management'

If you have feedback or need assistance with the MCP directory API, please join our Discord server