@nastechai/agent 0.16.0 → 0.17.0
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/eslint.config.js +23 -0
- package/index.html +24 -0
- package/package.json +54 -26
- package/package.json.bak +89 -0
- package/package.json.pub +88 -0
- package/src/App.tsx +1173 -0
- package/src/components/AuthWidget.tsx +150 -0
- package/src/components/AutoField.tsx +206 -0
- package/src/components/Backdrop.tsx +93 -0
- package/src/components/ChatSidebar.tsx +394 -0
- package/src/components/DeleteConfirmDialog.tsx +40 -0
- package/src/components/LanguageSwitcher.tsx +186 -0
- package/src/components/Markdown.tsx +383 -0
- package/src/components/ModelInfoCard.tsx +112 -0
- package/src/components/ModelPickerDialog.tsx +470 -0
- package/src/components/OAuthLoginModal.tsx +374 -0
- package/src/components/OAuthProvidersCard.tsx +287 -0
- package/src/components/PlatformsCard.tsx +97 -0
- package/src/components/ScheduleBuilder.tsx +273 -0
- package/src/components/SidebarFooter.tsx +42 -0
- package/src/components/SidebarStatusStrip.tsx +72 -0
- package/src/components/SlashPopover.tsx +171 -0
- package/src/components/ThemeSwitcher.tsx +243 -0
- package/src/components/ToolCall.tsx +228 -0
- package/src/components/ToolsetConfigDrawer.tsx +448 -0
- package/src/contexts/PageHeaderProvider.tsx +139 -0
- package/src/contexts/SystemActions.tsx +120 -0
- package/src/contexts/page-header-context.ts +12 -0
- package/src/contexts/system-actions-context.ts +18 -0
- package/src/contexts/usePageHeader.ts +10 -0
- package/src/contexts/useSystemActions.ts +15 -0
- package/src/hooks/useModalBehavior.ts +44 -0
- package/src/hooks/useSidebarStatus.ts +27 -0
- package/src/i18n/af.ts +702 -0
- package/src/i18n/context.tsx +123 -0
- package/src/i18n/de.ts +701 -0
- package/src/i18n/en.ts +708 -0
- package/src/i18n/es.ts +701 -0
- package/src/i18n/fr.ts +701 -0
- package/src/i18n/ga.ts +702 -0
- package/src/i18n/hu.ts +702 -0
- package/src/i18n/index.ts +2 -0
- package/src/i18n/it.ts +701 -0
- package/src/i18n/ja.ts +702 -0
- package/src/i18n/ko.ts +702 -0
- package/src/i18n/pt.ts +702 -0
- package/src/i18n/ru.ts +702 -0
- package/src/i18n/tr.ts +702 -0
- package/src/i18n/types.ts +710 -0
- package/src/i18n/uk.ts +702 -0
- package/src/i18n/zh-hant.ts +702 -0
- package/src/i18n/zh.ts +698 -0
- package/src/index.css +274 -0
- package/src/lib/api.ts +1585 -0
- package/src/lib/dashboard-flags.ts +15 -0
- package/src/lib/format.ts +9 -0
- package/src/lib/fuzzy.ts +192 -0
- package/src/lib/gatewayClient.ts +253 -0
- package/src/lib/nested.ts +23 -0
- package/src/lib/resolve-page-title.ts +41 -0
- package/src/lib/schedule.ts +382 -0
- package/src/lib/slashExec.ts +163 -0
- package/src/lib/utils.ts +35 -0
- package/src/main.tsx +25 -0
- package/src/pages/AnalyticsPage.tsx +601 -0
- package/src/pages/ChannelsPage.tsx +772 -0
- package/src/pages/ChatPage.tsx +889 -0
- package/src/pages/ConfigPage.tsx +660 -0
- package/src/pages/CronPage.tsx +524 -0
- package/src/pages/DocsPage.tsx +69 -0
- package/src/pages/EnvPage.tsx +918 -0
- package/src/pages/LogsPage.tsx +246 -0
- package/src/pages/McpPage.tsx +757 -0
- package/src/pages/ModelsPage.tsx +994 -0
- package/src/pages/PairingPage.tsx +276 -0
- package/src/pages/PluginsPage.tsx +580 -0
- package/src/pages/ProfilesPage.tsx +559 -0
- package/src/pages/SessionsPage.tsx +936 -0
- package/src/pages/SkillsPage.tsx +557 -0
- package/src/pages/SystemPage.tsx +1259 -0
- package/src/pages/WebhooksPage.tsx +483 -0
- package/src/plugins/PluginPage.tsx +64 -0
- package/src/plugins/index.ts +6 -0
- package/src/plugins/registry.ts +151 -0
- package/src/plugins/sdk.d.ts +160 -0
- package/src/plugins/slots.ts +199 -0
- package/src/plugins/types.ts +37 -0
- package/src/plugins/usePlugins.ts +133 -0
- package/src/themes/context.tsx +443 -0
- package/src/themes/fonts.ts +160 -0
- package/src/themes/index.ts +3 -0
- package/src/themes/presets.ts +477 -0
- package/src/themes/types.ts +187 -0
- package/tsconfig.app.json +34 -0
- package/tsconfig.json +7 -0
- package/tsconfig.node.json +26 -0
- package/vite.config.ts +124 -0
- package/vite.config.ts.timestamp-1780999102396-af6b77b30ebd8.mjs +105 -0
package/tsconfig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
4
|
+
"target": "ES2023",
|
|
5
|
+
"lib": ["ES2023"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"types": ["node"],
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
|
|
10
|
+
/* Bundler mode */
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"allowImportingTsExtensions": true,
|
|
13
|
+
"verbatimModuleSyntax": true,
|
|
14
|
+
"moduleDetection": "force",
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"erasableSyntaxOnly": true,
|
|
22
|
+
"noFallthroughCasesInSwitch": true,
|
|
23
|
+
"noUncheckedSideEffectImports": true
|
|
24
|
+
},
|
|
25
|
+
"include": ["vite.config.ts"]
|
|
26
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { defineConfig, type Plugin } from "vite";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
4
|
+
import path from "path";
|
|
5
|
+
|
|
6
|
+
const BACKEND = process.env.NASTECH_DASHBOARD_URL ?? "http://127.0.0.1:9119";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* In production the Python `nastech dashboard` server injects a one-shot
|
|
10
|
+
* session token into `index.html` (see `nastech_cli/web_server.py`). The
|
|
11
|
+
* Vite dev server serves its own `index.html`, so unless we forward that
|
|
12
|
+
* token, every protected `/api/*` call 401s.
|
|
13
|
+
*
|
|
14
|
+
* This plugin fetches the running dashboard's `index.html` on each dev page
|
|
15
|
+
* load, scrapes the `window.__NASTECH_SESSION_TOKEN__` assignment, and
|
|
16
|
+
* re-injects it into the dev HTML. No-op in production builds.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Remap @nastechai/ui → @nastechai/ui so Vite's module resolver
|
|
20
|
+
* follows the package's exports map instead of a raw filesystem path.
|
|
21
|
+
*/
|
|
22
|
+
function nastechUiAlias(): Plugin {
|
|
23
|
+
return {
|
|
24
|
+
name: "nastech:ui-alias",
|
|
25
|
+
enforce: "pre",
|
|
26
|
+
resolveId(id, importer, options) {
|
|
27
|
+
if (id.startsWith("@nastechai/ui")) {
|
|
28
|
+
return this.resolve(
|
|
29
|
+
id.replace("@nastechai/ui", "@nastechai/ui"),
|
|
30
|
+
importer,
|
|
31
|
+
options,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function nastechDevToken(): Plugin {
|
|
39
|
+
const TOKEN_RE = /window\.__NASTECH_SESSION_TOKEN__\s*=\s*"([^"]+)"/;
|
|
40
|
+
const EMBEDDED_RE =
|
|
41
|
+
/window\.__NASTECH_DASHBOARD_EMBEDDED_CHAT__\s*=\s*(true|false)/;
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
name: "nastech:dev-session-token",
|
|
45
|
+
apply: "serve",
|
|
46
|
+
async transformIndexHtml() {
|
|
47
|
+
try {
|
|
48
|
+
const res = await fetch(BACKEND, { headers: { accept: "text/html" } });
|
|
49
|
+
const html = await res.text();
|
|
50
|
+
const match = html.match(TOKEN_RE);
|
|
51
|
+
if (!match) {
|
|
52
|
+
console.warn(
|
|
53
|
+
`[nastech] Could not find session token in ${BACKEND} — ` +
|
|
54
|
+
`is \`nastech dashboard\` running? /api calls will 401.`,
|
|
55
|
+
);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const embeddedMatch = html.match(EMBEDDED_RE);
|
|
59
|
+
const embeddedJs = embeddedMatch ? embeddedMatch[1] : "true";
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
tag: "script",
|
|
63
|
+
injectTo: "head",
|
|
64
|
+
children:
|
|
65
|
+
`window.__NASTECH_SESSION_TOKEN__="${match[1]}";` +
|
|
66
|
+
`window.__NASTECH_DASHBOARD_EMBEDDED_CHAT__=${embeddedJs};`,
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
} catch (err) {
|
|
70
|
+
console.warn(
|
|
71
|
+
`[nastech] Dashboard at ${BACKEND} unreachable — ` +
|
|
72
|
+
`start it with \`nastech dashboard\` or set NASTECH_DASHBOARD_URL. ` +
|
|
73
|
+
`(${(err as Error).message})`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export default defineConfig({
|
|
81
|
+
plugins: [react(), tailwindcss(), nastechUiAlias(), nastechDevToken()],
|
|
82
|
+
resolve: {
|
|
83
|
+
alias: {
|
|
84
|
+
"@": path.resolve(__dirname, "./src"),
|
|
85
|
+
},
|
|
86
|
+
// When @nastechai/ui is symlinked via `file:../../design-language`,
|
|
87
|
+
// Node's module resolution would pick up shared deps from
|
|
88
|
+
// design-language/node_modules/*, giving us two copies + breaking
|
|
89
|
+
// hooks (useRef-of-null), webgl contexts, etc. Force everything that
|
|
90
|
+
// exists in BOTH places to use the dashboard's copy.
|
|
91
|
+
//
|
|
92
|
+
// Don't list packages here that only exist in the DS (nanostores,
|
|
93
|
+
// @nanostores/react) — Vite dedupe errors out when it can't find
|
|
94
|
+
// them at the project root.
|
|
95
|
+
dedupe: [
|
|
96
|
+
"react",
|
|
97
|
+
"react-dom",
|
|
98
|
+
"@react-three/fiber",
|
|
99
|
+
"@observablehq/plot",
|
|
100
|
+
"three",
|
|
101
|
+
"leva",
|
|
102
|
+
"gsap",
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
build: {
|
|
106
|
+
outDir: "../nastech_cli/web_dist",
|
|
107
|
+
emptyOutDir: true,
|
|
108
|
+
},
|
|
109
|
+
server: {
|
|
110
|
+
host: "0.0.0.0",
|
|
111
|
+
port: 5000,
|
|
112
|
+
allowedHosts: true,
|
|
113
|
+
proxy: {
|
|
114
|
+
"/api": {
|
|
115
|
+
target: BACKEND,
|
|
116
|
+
ws: true,
|
|
117
|
+
},
|
|
118
|
+
// Same host as `nastech dashboard` must serve these; Vite has no
|
|
119
|
+
// dashboard-plugins/* files, so without this, plugin scripts 404
|
|
120
|
+
// or receive index.html in dev.
|
|
121
|
+
"/dashboard-plugins": BACKEND,
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// vite.config.ts
|
|
2
|
+
import { defineConfig } from "file:///home/runner/workspace/web/node_modules/vite/dist/node/index.js";
|
|
3
|
+
import react from "file:///home/runner/workspace/web/node_modules/@vitejs/plugin-react/dist/index.js";
|
|
4
|
+
import tailwindcss from "file:///home/runner/workspace/node_modules/@tailwindcss/vite/dist/index.mjs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
var __vite_injected_original_dirname = "/home/runner/workspace/web";
|
|
7
|
+
var BACKEND = process.env.NASTECH_DASHBOARD_URL ?? "http://127.0.0.1:9119";
|
|
8
|
+
function nastechUiAlias() {
|
|
9
|
+
return {
|
|
10
|
+
name: "nastech:ui-alias",
|
|
11
|
+
enforce: "pre",
|
|
12
|
+
resolveId(id, importer, options) {
|
|
13
|
+
if (id.startsWith("@nastech-ai/ui")) {
|
|
14
|
+
return this.resolve(
|
|
15
|
+
id.replace("@nastech-ai/ui", "@nastechai/ui"),
|
|
16
|
+
importer,
|
|
17
|
+
options
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function nastechDevToken() {
|
|
24
|
+
const TOKEN_RE = /window\.__NASTECH_SESSION_TOKEN__\s*=\s*"([^"]+)"/;
|
|
25
|
+
const EMBEDDED_RE = /window\.__NASTECH_DASHBOARD_EMBEDDED_CHAT__\s*=\s*(true|false)/;
|
|
26
|
+
return {
|
|
27
|
+
name: "nastech:dev-session-token",
|
|
28
|
+
apply: "serve",
|
|
29
|
+
async transformIndexHtml() {
|
|
30
|
+
try {
|
|
31
|
+
const res = await fetch(BACKEND, { headers: { accept: "text/html" } });
|
|
32
|
+
const html = await res.text();
|
|
33
|
+
const match = html.match(TOKEN_RE);
|
|
34
|
+
if (!match) {
|
|
35
|
+
console.warn(
|
|
36
|
+
`[nastech] Could not find session token in ${BACKEND} \u2014 is \`nastech dashboard\` running? /api calls will 401.`
|
|
37
|
+
);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const embeddedMatch = html.match(EMBEDDED_RE);
|
|
41
|
+
const embeddedJs = embeddedMatch ? embeddedMatch[1] : "true";
|
|
42
|
+
return [
|
|
43
|
+
{
|
|
44
|
+
tag: "script",
|
|
45
|
+
injectTo: "head",
|
|
46
|
+
children: `window.__NASTECH_SESSION_TOKEN__="${match[1]}";window.__NASTECH_DASHBOARD_EMBEDDED_CHAT__=${embeddedJs};`
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
} catch (err) {
|
|
50
|
+
console.warn(
|
|
51
|
+
`[nastech] Dashboard at ${BACKEND} unreachable \u2014 start it with \`nastech dashboard\` or set NASTECH_DASHBOARD_URL. (${err.message})`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
var vite_config_default = defineConfig({
|
|
58
|
+
plugins: [react(), tailwindcss(), nastechUiAlias(), nastechDevToken()],
|
|
59
|
+
resolve: {
|
|
60
|
+
alias: {
|
|
61
|
+
"@": path.resolve(__vite_injected_original_dirname, "./src")
|
|
62
|
+
},
|
|
63
|
+
// When @nastech-ai/ui is symlinked via `file:../../design-language`,
|
|
64
|
+
// Node's module resolution would pick up shared deps from
|
|
65
|
+
// design-language/node_modules/*, giving us two copies + breaking
|
|
66
|
+
// hooks (useRef-of-null), webgl contexts, etc. Force everything that
|
|
67
|
+
// exists in BOTH places to use the dashboard's copy.
|
|
68
|
+
//
|
|
69
|
+
// Don't list packages here that only exist in the DS (nanostores,
|
|
70
|
+
// @nanostores/react) — Vite dedupe errors out when it can't find
|
|
71
|
+
// them at the project root.
|
|
72
|
+
dedupe: [
|
|
73
|
+
"react",
|
|
74
|
+
"react-dom",
|
|
75
|
+
"@react-three/fiber",
|
|
76
|
+
"@observablehq/plot",
|
|
77
|
+
"three",
|
|
78
|
+
"leva",
|
|
79
|
+
"gsap"
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
build: {
|
|
83
|
+
outDir: "../nastech_cli/web_dist",
|
|
84
|
+
emptyOutDir: true
|
|
85
|
+
},
|
|
86
|
+
server: {
|
|
87
|
+
host: "0.0.0.0",
|
|
88
|
+
port: 5e3,
|
|
89
|
+
allowedHosts: true,
|
|
90
|
+
proxy: {
|
|
91
|
+
"/api": {
|
|
92
|
+
target: BACKEND,
|
|
93
|
+
ws: true
|
|
94
|
+
},
|
|
95
|
+
// Same host as `nastech dashboard` must serve these; Vite has no
|
|
96
|
+
// dashboard-plugins/* files, so without this, plugin scripts 404
|
|
97
|
+
// or receive index.html in dev.
|
|
98
|
+
"/dashboard-plugins": BACKEND
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
export {
|
|
103
|
+
vite_config_default as default
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvaG9tZS9ydW5uZXIvd29ya3NwYWNlL3dlYlwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiL2hvbWUvcnVubmVyL3dvcmtzcGFjZS93ZWIvdml0ZS5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL2hvbWUvcnVubmVyL3dvcmtzcGFjZS93ZWIvdml0ZS5jb25maWcudHNcIjtpbXBvcnQgeyBkZWZpbmVDb25maWcsIHR5cGUgUGx1Z2luIH0gZnJvbSBcInZpdGVcIjtcbmltcG9ydCByZWFjdCBmcm9tIFwiQHZpdGVqcy9wbHVnaW4tcmVhY3RcIjtcbmltcG9ydCB0YWlsd2luZGNzcyBmcm9tIFwiQHRhaWx3aW5kY3NzL3ZpdGVcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmNvbnN0IEJBQ0tFTkQgPSBwcm9jZXNzLmVudi5OQVNURUNIX0RBU0hCT0FSRF9VUkwgPz8gXCJodHRwOi8vMTI3LjAuMC4xOjkxMTlcIjtcblxuLyoqXG4gKiBJbiBwcm9kdWN0aW9uIHRoZSBQeXRob24gYG5hc3RlY2ggZGFzaGJvYXJkYCBzZXJ2ZXIgaW5qZWN0cyBhIG9uZS1zaG90XG4gKiBzZXNzaW9uIHRva2VuIGludG8gYGluZGV4Lmh0bWxgIChzZWUgYG5hc3RlY2hfY2xpL3dlYl9zZXJ2ZXIucHlgKS4gVGhlXG4gKiBWaXRlIGRldiBzZXJ2ZXIgc2VydmVzIGl0cyBvd24gYGluZGV4Lmh0bWxgLCBzbyB1bmxlc3Mgd2UgZm9yd2FyZCB0aGF0XG4gKiB0b2tlbiwgZXZlcnkgcHJvdGVjdGVkIGAvYXBpLypgIGNhbGwgNDAxcy5cbiAqXG4gKiBUaGlzIHBsdWdpbiBmZXRjaGVzIHRoZSBydW5uaW5nIGRhc2hib2FyZCdzIGBpbmRleC5odG1sYCBvbiBlYWNoIGRldiBwYWdlXG4gKiBsb2FkLCBzY3JhcGVzIHRoZSBgd2luZG93Ll9fTkFTVEVDSF9TRVNTSU9OX1RPS0VOX19gIGFzc2lnbm1lbnQsIGFuZFxuICogcmUtaW5qZWN0cyBpdCBpbnRvIHRoZSBkZXYgSFRNTC4gTm8tb3AgaW4gcHJvZHVjdGlvbiBidWlsZHMuXG4gKi9cbi8qKlxuICogUmVtYXAgQG5hc3RlY2gtYWkvdWkgXHUyMTkyIEBuYXN0ZWNoYWkvdWkgc28gVml0ZSdzIG1vZHVsZSByZXNvbHZlclxuICogZm9sbG93cyB0aGUgcGFja2FnZSdzIGV4cG9ydHMgbWFwIGluc3RlYWQgb2YgYSByYXcgZmlsZXN5c3RlbSBwYXRoLlxuICovXG5mdW5jdGlvbiBuYXN0ZWNoVWlBbGlhcygpOiBQbHVnaW4ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6IFwibmFzdGVjaDp1aS1hbGlhc1wiLFxuICAgIGVuZm9yY2U6IFwicHJlXCIsXG4gICAgcmVzb2x2ZUlkKGlkLCBpbXBvcnRlciwgb3B0aW9ucykge1xuICAgICAgaWYgKGlkLnN0YXJ0c1dpdGgoXCJAbmFzdGVjaC1haS91aVwiKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNvbHZlKFxuICAgICAgICAgIGlkLnJlcGxhY2UoXCJAbmFzdGVjaC1haS91aVwiLCBcIkBuYXN0ZWNoYWkvdWlcIiksXG4gICAgICAgICAgaW1wb3J0ZXIsXG4gICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBuYXN0ZWNoRGV2VG9rZW4oKTogUGx1Z2luIHtcbiAgY29uc3QgVE9LRU5fUkUgPSAvd2luZG93XFwuX19OQVNURUNIX1NFU1NJT05fVE9LRU5fX1xccyo9XFxzKlwiKFteXCJdKylcIi87XG4gIGNvbnN0IEVNQkVEREVEX1JFID1cbiAgICAvd2luZG93XFwuX19OQVNURUNIX0RBU0hCT0FSRF9FTUJFRERFRF9DSEFUX19cXHMqPVxccyoodHJ1ZXxmYWxzZSkvO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJuYXN0ZWNoOmRldi1zZXNzaW9uLXRva2VuXCIsXG4gICAgYXBwbHk6IFwic2VydmVcIixcbiAgICBhc3luYyB0cmFuc2Zvcm1JbmRleEh0bWwoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaChCQUNLRU5ELCB7IGhlYWRlcnM6IHsgYWNjZXB0OiBcInRleHQvaHRtbFwiIH0gfSk7XG4gICAgICAgIGNvbnN0IGh0bWwgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgICAgICBjb25zdCBtYXRjaCA9IGh0bWwubWF0Y2goVE9LRU5fUkUpO1xuICAgICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgYFtuYXN0ZWNoXSBDb3VsZCBub3QgZmluZCBzZXNzaW9uIHRva2VuIGluICR7QkFDS0VORH0gXHUyMDE0IGAgK1xuICAgICAgICAgICAgICBgaXMgXFxgbmFzdGVjaCBkYXNoYm9hcmRcXGAgcnVubmluZz8gL2FwaSBjYWxscyB3aWxsIDQwMS5gLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVtYmVkZGVkTWF0Y2ggPSBodG1sLm1hdGNoKEVNQkVEREVEX1JFKTtcbiAgICAgICAgY29uc3QgZW1iZWRkZWRKcyA9IGVtYmVkZGVkTWF0Y2ggPyBlbWJlZGRlZE1hdGNoWzFdIDogXCJ0cnVlXCI7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGFnOiBcInNjcmlwdFwiLFxuICAgICAgICAgICAgaW5qZWN0VG86IFwiaGVhZFwiLFxuICAgICAgICAgICAgY2hpbGRyZW46XG4gICAgICAgICAgICAgIGB3aW5kb3cuX19OQVNURUNIX1NFU1NJT05fVE9LRU5fXz1cIiR7bWF0Y2hbMV19XCI7YCArXG4gICAgICAgICAgICAgIGB3aW5kb3cuX19OQVNURUNIX0RBU0hCT0FSRF9FTUJFRERFRF9DSEFUX189JHtlbWJlZGRlZEpzfTtgLFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGBbbmFzdGVjaF0gRGFzaGJvYXJkIGF0ICR7QkFDS0VORH0gdW5yZWFjaGFibGUgXHUyMDE0IGAgK1xuICAgICAgICAgICAgYHN0YXJ0IGl0IHdpdGggXFxgbmFzdGVjaCBkYXNoYm9hcmRcXGAgb3Igc2V0IE5BU1RFQ0hfREFTSEJPQVJEX1VSTC4gYCArXG4gICAgICAgICAgICBgKCR7KGVyciBhcyBFcnJvcikubWVzc2FnZX0pYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xuICBwbHVnaW5zOiBbcmVhY3QoKSwgdGFpbHdpbmRjc3MoKSwgbmFzdGVjaFVpQWxpYXMoKSwgbmFzdGVjaERldlRva2VuKCldLFxuICByZXNvbHZlOiB7XG4gICAgYWxpYXM6IHtcbiAgICAgIFwiQFwiOiBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCBcIi4vc3JjXCIpLFxuICAgIH0sXG4gICAgLy8gV2hlbiBAbmFzdGVjaC1haS91aSBpcyBzeW1saW5rZWQgdmlhIGBmaWxlOi4uLy4uL2Rlc2lnbi1sYW5ndWFnZWAsXG4gICAgLy8gTm9kZSdzIG1vZHVsZSByZXNvbHV0aW9uIHdvdWxkIHBpY2sgdXAgc2hhcmVkIGRlcHMgZnJvbVxuICAgIC8vIGRlc2lnbi1sYW5ndWFnZS9ub2RlX21vZHVsZXMvKiwgZ2l2aW5nIHVzIHR3byBjb3BpZXMgKyBicmVha2luZ1xuICAgIC8vIGhvb2tzICh1c2VSZWYtb2YtbnVsbCksIHdlYmdsIGNvbnRleHRzLCBldGMuIEZvcmNlIGV2ZXJ5dGhpbmcgdGhhdFxuICAgIC8vIGV4aXN0cyBpbiBCT1RIIHBsYWNlcyB0byB1c2UgdGhlIGRhc2hib2FyZCdzIGNvcHkuXG4gICAgLy9cbiAgICAvLyBEb24ndCBsaXN0IHBhY2thZ2VzIGhlcmUgdGhhdCBvbmx5IGV4aXN0IGluIHRoZSBEUyAobmFub3N0b3JlcyxcbiAgICAvLyBAbmFub3N0b3Jlcy9yZWFjdCkgXHUyMDE0IFZpdGUgZGVkdXBlIGVycm9ycyBvdXQgd2hlbiBpdCBjYW4ndCBmaW5kXG4gICAgLy8gdGhlbSBhdCB0aGUgcHJvamVjdCByb290LlxuICAgIGRlZHVwZTogW1xuICAgICAgXCJyZWFjdFwiLFxuICAgICAgXCJyZWFjdC1kb21cIixcbiAgICAgIFwiQHJlYWN0LXRocmVlL2ZpYmVyXCIsXG4gICAgICBcIkBvYnNlcnZhYmxlaHEvcGxvdFwiLFxuICAgICAgXCJ0aHJlZVwiLFxuICAgICAgXCJsZXZhXCIsXG4gICAgICBcImdzYXBcIixcbiAgICBdLFxuICB9LFxuICBidWlsZDoge1xuICAgIG91dERpcjogXCIuLi9uYXN0ZWNoX2NsaS93ZWJfZGlzdFwiLFxuICAgIGVtcHR5T3V0RGlyOiB0cnVlLFxuICB9LFxuICBzZXJ2ZXI6IHtcbiAgICBob3N0OiBcIjAuMC4wLjBcIixcbiAgICBwb3J0OiA1MDAwLFxuICAgIGFsbG93ZWRIb3N0czogdHJ1ZSxcbiAgICBwcm94eToge1xuICAgICAgXCIvYXBpXCI6IHtcbiAgICAgICAgdGFyZ2V0OiBCQUNLRU5ELFxuICAgICAgICB3czogdHJ1ZSxcbiAgICAgIH0sXG4gICAgICAvLyBTYW1lIGhvc3QgYXMgYG5hc3RlY2ggZGFzaGJvYXJkYCBtdXN0IHNlcnZlIHRoZXNlOyBWaXRlIGhhcyBub1xuICAgICAgLy8gZGFzaGJvYXJkLXBsdWdpbnMvKiBmaWxlcywgc28gd2l0aG91dCB0aGlzLCBwbHVnaW4gc2NyaXB0cyA0MDRcbiAgICAgIC8vIG9yIHJlY2VpdmUgaW5kZXguaHRtbCBpbiBkZXYuXG4gICAgICBcIi9kYXNoYm9hcmQtcGx1Z2luc1wiOiBCQUNLRU5ELFxuICAgIH0sXG4gIH0sXG59KTtcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFB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
|