vite-plugin-opencode-assistant 1.0.1 → 1.0.3
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/dist/constants.d.ts +2 -5
- package/dist/constants.js +3 -6
- package/dist/constants.js.map +1 -0
- package/dist/logger.d.ts +64 -0
- package/dist/logger.js +311 -0
- package/dist/logger.js.map +1 -0
- package/dist/{plugins → opencode/plugins}/page-context.d.ts +0 -13
- package/dist/opencode/plugins/page-context.js +345 -0
- package/dist/opencode/plugins/page-context.js.map +1 -0
- package/dist/opencode/web.d.ts +3 -0
- package/dist/opencode/web.js +81 -0
- package/dist/opencode/web.js.map +1 -0
- package/dist/types.d.ts +0 -6
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -0
- package/dist/vite/client.js +2288 -0
- package/dist/vite/client.js.map +1 -0
- package/dist/vite/index.d.ts +3 -0
- package/dist/vite/index.js +520 -0
- package/dist/vite/index.js.map +1 -0
- package/dist/vite/injector.d.ts +2 -0
- package/dist/vite/injector.js +6 -0
- package/dist/vite/injector.js.map +1 -0
- package/dist/vite/utils.d.ts +5 -0
- package/dist/vite/utils.js +206 -0
- package/dist/vite/utils.js.map +1 -0
- package/package.json +14 -6
- package/dist/client.js +0 -1549
- package/dist/index.d.ts +0 -23
- package/dist/index.js +0 -448
- package/dist/injector.d.ts +0 -20
- package/dist/injector.js +0 -24
- package/dist/plugins/page-context.js +0 -121
- package/dist/utils.d.ts +0 -42
- package/dist/utils.js +0 -156
- package/dist/web.d.ts +0 -18
- package/dist/web.js +0 -95
- /package/dist/{client.d.ts → vite/client.d.ts} +0 -0
package/dist/index.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from 'vite';
|
|
2
|
-
import { OpenCodeOptions } from './types.js';
|
|
3
|
-
/**
|
|
4
|
-
* OpenCode Vite 插件
|
|
5
|
-
* @param options - 插件配置选项
|
|
6
|
-
* @returns Vite 插件实例
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* // vite.config.ts
|
|
10
|
-
* import opencode from 'vite-plugin-opencode'
|
|
11
|
-
*
|
|
12
|
-
* export default {
|
|
13
|
-
* plugins: [
|
|
14
|
-
* opencode({
|
|
15
|
-
* webPort: 4097,
|
|
16
|
-
* position: 'bottom-right',
|
|
17
|
-
* theme: 'auto'
|
|
18
|
-
* })
|
|
19
|
-
* ]
|
|
20
|
-
* }
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
export default function opencodePlugin(options?: OpenCodeOptions): Plugin;
|
package/dist/index.js
DELETED
|
@@ -1,448 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import http from 'http';
|
|
4
|
-
import { startOpenCodeWeb } from './web.js';
|
|
5
|
-
import { injectWidget } from './injector.js';
|
|
6
|
-
import { checkOpenCodeInstalled, findAvailablePort, killProcessOnPort, checkOpenCodeProcess } from './utils.js';
|
|
7
|
-
import { DEFAULT_CONFIG, DEFAULT_RETRIES, RETRY_DELAY, PROCESS_KILL_DELAY, LOG_PREFIX, WIDGET_SCRIPT_PATH, CONTEXT_API_PATH, START_API_PATH, SESSIONS_API_PATH, } from './constants.js';
|
|
8
|
-
/**
|
|
9
|
-
* OpenCode Vite 插件
|
|
10
|
-
* @param options - 插件配置选项
|
|
11
|
-
* @returns Vite 插件实例
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* // vite.config.ts
|
|
15
|
-
* import opencode from 'vite-plugin-opencode'
|
|
16
|
-
*
|
|
17
|
-
* export default {
|
|
18
|
-
* plugins: [
|
|
19
|
-
* opencode({
|
|
20
|
-
* webPort: 4097,
|
|
21
|
-
* position: 'bottom-right',
|
|
22
|
-
* theme: 'auto'
|
|
23
|
-
* })
|
|
24
|
-
* ]
|
|
25
|
-
* }
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
export default function opencodePlugin(options = {}) {
|
|
29
|
-
let webProcess = null;
|
|
30
|
-
let sessionUrl = null;
|
|
31
|
-
let actualWebPort = DEFAULT_CONFIG.webPort;
|
|
32
|
-
let isStarted = false;
|
|
33
|
-
let startPromise = null;
|
|
34
|
-
let pageContext = { url: '', title: '' };
|
|
35
|
-
const config = { ...DEFAULT_CONFIG, ...options };
|
|
36
|
-
/**
|
|
37
|
-
* 输出日志(仅在 verbose 模式下)
|
|
38
|
-
*/
|
|
39
|
-
function log(message, ...args) {
|
|
40
|
-
if (config.verbose) {
|
|
41
|
-
console.log(`${LOG_PREFIX} ${message}`, ...args);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* 输出错误日志
|
|
46
|
-
*/
|
|
47
|
-
function logError(message, ...args) {
|
|
48
|
-
console.error(`${LOG_PREFIX} ${message}`, ...args);
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Base64 编码字符串
|
|
52
|
-
*/
|
|
53
|
-
function base64Encode(str) {
|
|
54
|
-
return Buffer.from(str).toString('base64');
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* 延迟执行
|
|
58
|
-
*/
|
|
59
|
-
function sleep(ms) {
|
|
60
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* 创建 HTTP 请求 Promise
|
|
64
|
-
*/
|
|
65
|
-
function createHttpRequest(options, body) {
|
|
66
|
-
return new Promise((resolve, reject) => {
|
|
67
|
-
const req = http.request(options, (res) => {
|
|
68
|
-
let data = '';
|
|
69
|
-
res.on('data', chunk => data += chunk);
|
|
70
|
-
res.on('end', () => {
|
|
71
|
-
try {
|
|
72
|
-
resolve(JSON.parse(data));
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
reject(new Error(`JSON parse error: ${data.substring(0, 100)}`));
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
req.on('error', reject);
|
|
80
|
-
if (body)
|
|
81
|
-
req.write(body);
|
|
82
|
-
req.end();
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* 获取会话列表
|
|
87
|
-
*/
|
|
88
|
-
async function getSessions(retries = DEFAULT_RETRIES) {
|
|
89
|
-
let lastError = null;
|
|
90
|
-
for (let i = 0; i < retries; i++) {
|
|
91
|
-
try {
|
|
92
|
-
return await createHttpRequest({
|
|
93
|
-
hostname: config.hostname,
|
|
94
|
-
port: actualWebPort,
|
|
95
|
-
path: '/session',
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
catch (e) {
|
|
99
|
-
lastError = e instanceof Error ? e : new Error(String(e));
|
|
100
|
-
if (i < retries - 1)
|
|
101
|
-
await sleep(RETRY_DELAY);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
throw lastError;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* 创建新会话
|
|
108
|
-
*/
|
|
109
|
-
async function createSession(retries = DEFAULT_RETRIES) {
|
|
110
|
-
let lastError = null;
|
|
111
|
-
for (let i = 0; i < retries; i++) {
|
|
112
|
-
try {
|
|
113
|
-
return await createHttpRequest({
|
|
114
|
-
hostname: config.hostname,
|
|
115
|
-
port: actualWebPort,
|
|
116
|
-
path: '/session',
|
|
117
|
-
method: 'POST',
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
catch (e) {
|
|
121
|
-
lastError = e instanceof Error ? e : new Error(String(e));
|
|
122
|
-
if (i < retries - 1)
|
|
123
|
-
await sleep(RETRY_DELAY);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
throw lastError;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* 删除会话
|
|
130
|
-
*/
|
|
131
|
-
async function deleteSession(sessionId, retries = DEFAULT_RETRIES) {
|
|
132
|
-
let lastError = null;
|
|
133
|
-
for (let i = 0; i < retries; i++) {
|
|
134
|
-
try {
|
|
135
|
-
await createHttpRequest({
|
|
136
|
-
hostname: config.hostname,
|
|
137
|
-
port: actualWebPort,
|
|
138
|
-
path: `/session/${sessionId}`,
|
|
139
|
-
method: 'DELETE',
|
|
140
|
-
});
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
catch (e) {
|
|
144
|
-
lastError = e instanceof Error ? e : new Error(String(e));
|
|
145
|
-
if (i < retries - 1)
|
|
146
|
-
await sleep(RETRY_DELAY);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
throw lastError;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* 获取或创建会话
|
|
153
|
-
*/
|
|
154
|
-
async function getOrCreateSession() {
|
|
155
|
-
const projectDir = process.cwd();
|
|
156
|
-
log('Getting sessions...');
|
|
157
|
-
const sessions = await getSessions();
|
|
158
|
-
log(`Found ${sessions.length} sessions`);
|
|
159
|
-
const matchingSession = sessions.find(s => s.directory === projectDir);
|
|
160
|
-
if (matchingSession) {
|
|
161
|
-
return `http://${config.hostname}:${actualWebPort}/${base64Encode(projectDir)}/session/${matchingSession.id}`;
|
|
162
|
-
}
|
|
163
|
-
log('Creating new session...');
|
|
164
|
-
const newSession = await createSession();
|
|
165
|
-
return `http://${config.hostname}:${actualWebPort}/${base64Encode(projectDir)}/session/${newSession.id}`;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* 设置 OpenCode 插件
|
|
169
|
-
*/
|
|
170
|
-
function setupOpenCodePlugin() {
|
|
171
|
-
const projectDir = process.cwd();
|
|
172
|
-
const cacheDir = path.join(projectDir, 'node_modules', '.cache', 'opencode');
|
|
173
|
-
const pluginsDir = path.join(cacheDir, 'plugins');
|
|
174
|
-
if (!fs.existsSync(pluginsDir)) {
|
|
175
|
-
fs.mkdirSync(pluginsDir, { recursive: true });
|
|
176
|
-
}
|
|
177
|
-
const pluginSourcePath = path.join(__dirname, 'plugins', 'page-context.js');
|
|
178
|
-
const pluginTargetPath = path.join(pluginsDir, 'page-context.js');
|
|
179
|
-
if (fs.existsSync(pluginSourcePath)) {
|
|
180
|
-
fs.copyFileSync(pluginSourcePath, pluginTargetPath);
|
|
181
|
-
log(`Plugin installed to ${pluginTargetPath}`);
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
console.warn(`${LOG_PREFIX} Plugin source not found: ${pluginSourcePath}`);
|
|
185
|
-
}
|
|
186
|
-
return cacheDir;
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* 启动服务
|
|
190
|
-
*/
|
|
191
|
-
async function startServices(corsOrigins, contextApiUrl) {
|
|
192
|
-
if (isStarted)
|
|
193
|
-
return;
|
|
194
|
-
if (startPromise)
|
|
195
|
-
return startPromise;
|
|
196
|
-
startPromise = (async () => {
|
|
197
|
-
log('Starting OpenCode services...');
|
|
198
|
-
if (!await checkOpenCodeInstalled()) {
|
|
199
|
-
logError(`OpenCode is not installed!
|
|
200
|
-
|
|
201
|
-
Please install OpenCode first:
|
|
202
|
-
|
|
203
|
-
# Using Homebrew (macOS)
|
|
204
|
-
brew install opencode-ai/tap/opencode
|
|
205
|
-
|
|
206
|
-
# Or using the install script
|
|
207
|
-
curl -fsSL https://opencode.ai/install | bash
|
|
208
|
-
`);
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
actualWebPort = await findAvailablePort(config.webPort, config.hostname);
|
|
212
|
-
if (actualWebPort !== config.webPort) {
|
|
213
|
-
log(`Port ${config.webPort} is in use, using ${actualWebPort} instead`);
|
|
214
|
-
}
|
|
215
|
-
const existingProcess = await checkOpenCodeProcess(actualWebPort);
|
|
216
|
-
if (existingProcess) {
|
|
217
|
-
log(`Found existing OpenCode process on port ${actualWebPort}`);
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
const killed = await killProcessOnPort(actualWebPort, config.hostname);
|
|
221
|
-
if (killed) {
|
|
222
|
-
log(`Killed stale process on port ${actualWebPort}`);
|
|
223
|
-
await sleep(PROCESS_KILL_DELAY);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
const configDir = setupOpenCodePlugin();
|
|
227
|
-
if (!existingProcess) {
|
|
228
|
-
webProcess = await startOpenCodeWeb({
|
|
229
|
-
port: actualWebPort,
|
|
230
|
-
hostname: config.hostname,
|
|
231
|
-
serverUrl: '',
|
|
232
|
-
cwd: process.cwd(),
|
|
233
|
-
configDir,
|
|
234
|
-
corsOrigins,
|
|
235
|
-
contextApiUrl,
|
|
236
|
-
});
|
|
237
|
-
log(`OpenCode Web started at http://${config.hostname}:${actualWebPort}`);
|
|
238
|
-
}
|
|
239
|
-
try {
|
|
240
|
-
sessionUrl = await getOrCreateSession();
|
|
241
|
-
log(`Session URL: ${sessionUrl}`);
|
|
242
|
-
}
|
|
243
|
-
catch (e) {
|
|
244
|
-
console.warn(`${LOG_PREFIX} Failed to get/create session:`, e);
|
|
245
|
-
}
|
|
246
|
-
isStarted = true;
|
|
247
|
-
})();
|
|
248
|
-
return startPromise;
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* 停止服务
|
|
252
|
-
*/
|
|
253
|
-
async function stopServices() {
|
|
254
|
-
log('Stopping OpenCode services...');
|
|
255
|
-
if (webProcess) {
|
|
256
|
-
webProcess.kill('SIGTERM');
|
|
257
|
-
await new Promise(resolve => {
|
|
258
|
-
webProcess?.on('exit', () => resolve());
|
|
259
|
-
setTimeout(() => {
|
|
260
|
-
webProcess?.kill('SIGKILL');
|
|
261
|
-
resolve();
|
|
262
|
-
}, 3000);
|
|
263
|
-
});
|
|
264
|
-
webProcess = null;
|
|
265
|
-
}
|
|
266
|
-
if (isStarted) {
|
|
267
|
-
await killProcessOnPort(actualWebPort, config.hostname);
|
|
268
|
-
}
|
|
269
|
-
isStarted = false;
|
|
270
|
-
startPromise = null;
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* 处理上下文 API 请求
|
|
274
|
-
*/
|
|
275
|
-
function handleContextRequest(req, res) {
|
|
276
|
-
res.setHeader('Content-Type', 'application/json');
|
|
277
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
278
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
|
|
279
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
280
|
-
if (req.method === 'OPTIONS') {
|
|
281
|
-
res.writeHead(200);
|
|
282
|
-
res.end();
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
if (req.method === 'GET') {
|
|
286
|
-
res.writeHead(200);
|
|
287
|
-
res.end(JSON.stringify(pageContext));
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
if (req.method === 'DELETE') {
|
|
291
|
-
pageContext.selectedElements = [];
|
|
292
|
-
log('Selected elements cleared');
|
|
293
|
-
res.writeHead(200);
|
|
294
|
-
res.end(JSON.stringify({ success: true }));
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
if (req.method === 'POST') {
|
|
298
|
-
let body = '';
|
|
299
|
-
req.on('data', chunk => body += chunk);
|
|
300
|
-
req.on('end', () => {
|
|
301
|
-
try {
|
|
302
|
-
const data = JSON.parse(body);
|
|
303
|
-
pageContext = {
|
|
304
|
-
url: data.url || '',
|
|
305
|
-
title: data.title || '',
|
|
306
|
-
selectedElements: data.selectedElements || [],
|
|
307
|
-
};
|
|
308
|
-
log(`Context updated: ${pageContext.url}`, data.selectedElements?.length ? `elements: ${data.selectedElements.length}` : '');
|
|
309
|
-
res.writeHead(200);
|
|
310
|
-
res.end(JSON.stringify({ success: true }));
|
|
311
|
-
}
|
|
312
|
-
catch {
|
|
313
|
-
res.writeHead(400);
|
|
314
|
-
res.end(JSON.stringify({ error: 'Invalid JSON' }));
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
res.writeHead(405);
|
|
320
|
-
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
321
|
-
}
|
|
322
|
-
return {
|
|
323
|
-
name: 'vite-plugin-opencode',
|
|
324
|
-
async configureServer(server) {
|
|
325
|
-
if (!config.enabled)
|
|
326
|
-
return;
|
|
327
|
-
const vitePort = server.config.server.port || 5173;
|
|
328
|
-
const viteHost = server.config.server.host || 'localhost';
|
|
329
|
-
const viteOrigin = `http://${viteHost}:${vitePort}`;
|
|
330
|
-
const contextApiUrl = `http://${viteHost}:${vitePort}${CONTEXT_API_PATH}`;
|
|
331
|
-
if (!config.lazy) {
|
|
332
|
-
await startServices([viteOrigin], contextApiUrl);
|
|
333
|
-
}
|
|
334
|
-
server.middlewares.use(WIDGET_SCRIPT_PATH, async (_req, res) => {
|
|
335
|
-
if (config.lazy && !isStarted) {
|
|
336
|
-
await startServices([viteOrigin], contextApiUrl);
|
|
337
|
-
}
|
|
338
|
-
const widgetPath = path.join(__dirname, 'client.js');
|
|
339
|
-
if (fs.existsSync(widgetPath)) {
|
|
340
|
-
res.setHeader('Content-Type', 'application/javascript');
|
|
341
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
342
|
-
fs.createReadStream(widgetPath).pipe(res);
|
|
343
|
-
}
|
|
344
|
-
else {
|
|
345
|
-
res.writeHead(404);
|
|
346
|
-
res.end('Widget script not found');
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
server.middlewares.use(CONTEXT_API_PATH, async (req, res) => {
|
|
350
|
-
if (config.lazy && !isStarted) {
|
|
351
|
-
await startServices([viteOrigin], contextApiUrl);
|
|
352
|
-
}
|
|
353
|
-
handleContextRequest(req, res);
|
|
354
|
-
});
|
|
355
|
-
server.middlewares.use(START_API_PATH, async (_req, res) => {
|
|
356
|
-
res.setHeader('Content-Type', 'application/json');
|
|
357
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
358
|
-
if (config.lazy && !isStarted) {
|
|
359
|
-
try {
|
|
360
|
-
await startServices([viteOrigin], contextApiUrl);
|
|
361
|
-
res.writeHead(200);
|
|
362
|
-
res.end(JSON.stringify({ success: true, sessionUrl }));
|
|
363
|
-
}
|
|
364
|
-
catch (e) {
|
|
365
|
-
res.writeHead(500);
|
|
366
|
-
res.end(JSON.stringify({ error: String(e) }));
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
else {
|
|
370
|
-
res.writeHead(200);
|
|
371
|
-
res.end(JSON.stringify({ success: true, sessionUrl }));
|
|
372
|
-
}
|
|
373
|
-
});
|
|
374
|
-
server.middlewares.use(SESSIONS_API_PATH, async (req, res) => {
|
|
375
|
-
res.setHeader('Content-Type', 'application/json');
|
|
376
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
377
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
|
|
378
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
379
|
-
if (req.method === 'OPTIONS') {
|
|
380
|
-
res.writeHead(200);
|
|
381
|
-
res.end();
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
if (config.lazy && !isStarted) {
|
|
385
|
-
await startServices([viteOrigin], contextApiUrl);
|
|
386
|
-
}
|
|
387
|
-
try {
|
|
388
|
-
if (req.method === 'GET') {
|
|
389
|
-
const sessions = await getSessions();
|
|
390
|
-
res.writeHead(200);
|
|
391
|
-
res.end(JSON.stringify(sessions));
|
|
392
|
-
}
|
|
393
|
-
else if (req.method === 'POST') {
|
|
394
|
-
const newSession = await createSession();
|
|
395
|
-
res.writeHead(200);
|
|
396
|
-
res.end(JSON.stringify(newSession));
|
|
397
|
-
}
|
|
398
|
-
else if (req.method === 'DELETE') {
|
|
399
|
-
const url = new URL(req.url || '', `http://${req.headers.host}`);
|
|
400
|
-
const sessionId = url.searchParams.get('id');
|
|
401
|
-
if (!sessionId) {
|
|
402
|
-
res.writeHead(400);
|
|
403
|
-
res.end(JSON.stringify({ error: 'Session ID is required' }));
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
await deleteSession(sessionId);
|
|
407
|
-
res.writeHead(200);
|
|
408
|
-
res.end(JSON.stringify({ success: true }));
|
|
409
|
-
}
|
|
410
|
-
else {
|
|
411
|
-
res.writeHead(405);
|
|
412
|
-
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
catch (e) {
|
|
416
|
-
res.writeHead(500);
|
|
417
|
-
res.end(JSON.stringify({ error: String(e) }));
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
server.httpServer?.on('close', stopServices);
|
|
421
|
-
const cleanup = async () => {
|
|
422
|
-
await stopServices();
|
|
423
|
-
process.exit(0);
|
|
424
|
-
};
|
|
425
|
-
process.on('SIGINT', cleanup);
|
|
426
|
-
process.on('SIGTERM', cleanup);
|
|
427
|
-
process.on('exit', () => {
|
|
428
|
-
webProcess?.kill('SIGKILL');
|
|
429
|
-
});
|
|
430
|
-
},
|
|
431
|
-
transformIndexHtml(html) {
|
|
432
|
-
const widget = injectWidget({
|
|
433
|
-
webUrl: `http://${config.hostname}:${actualWebPort}`,
|
|
434
|
-
serverUrl: `http://${config.hostname}:${actualWebPort}`,
|
|
435
|
-
position: config.position,
|
|
436
|
-
theme: config.theme,
|
|
437
|
-
open: config.open,
|
|
438
|
-
autoReload: config.autoReload,
|
|
439
|
-
cwd: process.cwd(),
|
|
440
|
-
sessionUrl: sessionUrl || undefined,
|
|
441
|
-
lazy: config.lazy,
|
|
442
|
-
hotkey: config.hotkey,
|
|
443
|
-
});
|
|
444
|
-
return html.replace('</body>', `${widget}</body>`);
|
|
445
|
-
},
|
|
446
|
-
};
|
|
447
|
-
}
|
|
448
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQTtBQUNuQixPQUFPLElBQUksTUFBTSxNQUFNLENBQUE7QUFDdkIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sVUFBVSxDQUFBO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDNUMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLGlCQUFpQixFQUFFLGlCQUFpQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sWUFBWSxDQUFBO0FBRS9HLE9BQU8sRUFDTCxjQUFjLEVBQ2QsZUFBZSxFQUNmLFdBQVcsRUFDWCxrQkFBa0IsRUFDbEIsVUFBVSxFQUNWLGtCQUFrQixFQUNsQixnQkFBZ0IsRUFDaEIsY0FBYyxFQUNkLGlCQUFpQixHQUNsQixNQUFNLGdCQUFnQixDQUFBO0FBRXZCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sVUFBVSxjQUFjLENBQUMsVUFBMkIsRUFBRTtJQUNsRSxJQUFJLFVBQVUsR0FBd0IsSUFBSSxDQUFBO0lBQzFDLElBQUksVUFBVSxHQUFrQixJQUFJLENBQUE7SUFDcEMsSUFBSSxhQUFhLEdBQVcsY0FBYyxDQUFDLE9BQU8sQ0FBQTtJQUNsRCxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUE7SUFDckIsSUFBSSxZQUFZLEdBQXlCLElBQUksQ0FBQTtJQUM3QyxJQUFJLFdBQVcsR0FBZ0IsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQTtJQUVyRCxNQUFNLE1BQU0sR0FBRyxFQUFFLEdBQUcsY0FBYyxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUE7SUFFaEQ7O09BRUc7SUFDSCxTQUFTLEdBQUcsQ0FBQyxPQUFlLEVBQUUsR0FBRyxJQUFlO1FBQzlDLElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ25CLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxVQUFVLElBQUksT0FBTyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQTtRQUNsRCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsU0FBUyxRQUFRLENBQUMsT0FBZSxFQUFFLEdBQUcsSUFBZTtRQUNuRCxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsVUFBVSxJQUFJLE9BQU8sRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUE7SUFDcEQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsU0FBUyxZQUFZLENBQUMsR0FBVztRQUMvQixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQzVDLENBQUM7SUFFRDs7T0FFRztJQUNILFNBQVMsS0FBSyxDQUFDLEVBQVU7UUFDdkIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQTtJQUN4RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxTQUFTLGlCQUFpQixDQUFJLE9BQTRCLEVBQUUsSUFBYTtRQUN2RSxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQ3hDLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQTtnQkFDYixHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksSUFBSSxLQUFLLENBQUMsQ0FBQTtnQkFDdEMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFO29CQUNqQixJQUFJLENBQUM7d0JBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtvQkFDM0IsQ0FBQztvQkFBQyxNQUFNLENBQUM7d0JBQ1AsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLHFCQUFxQixJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtvQkFDbEUsQ0FBQztnQkFDSCxDQUFDLENBQUMsQ0FBQTtZQUNKLENBQUMsQ0FBQyxDQUFBO1lBQ0YsR0FBRyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUE7WUFDdkIsSUFBSSxJQUFJO2dCQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUE7WUFDekIsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFBO1FBQ1gsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLFVBQVUsV0FBVyxDQUFDLE9BQU8sR0FBRyxlQUFlO1FBQ2xELElBQUksU0FBUyxHQUFpQixJQUFJLENBQUE7UUFFbEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQztnQkFDSCxPQUFPLE1BQU0saUJBQWlCLENBQWdCO29CQUM1QyxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7b0JBQ3pCLElBQUksRUFBRSxhQUFhO29CQUNuQixJQUFJLEVBQUUsVUFBVTtpQkFDakIsQ0FBQyxDQUFBO1lBQ0osQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1gsU0FBUyxHQUFHLENBQUMsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7Z0JBQ3pELElBQUksQ0FBQyxHQUFHLE9BQU8sR0FBRyxDQUFDO29CQUFFLE1BQU0sS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFBO1lBQy9DLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxTQUFTLENBQUE7SUFDakIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxVQUFVLGFBQWEsQ0FBQyxPQUFPLEdBQUcsZUFBZTtRQUNwRCxJQUFJLFNBQVMsR0FBaUIsSUFBSSxDQUFBO1FBRWxDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUM7Z0JBQ0gsT0FBTyxNQUFNLGlCQUFpQixDQUFjO29CQUMxQyxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7b0JBQ3pCLElBQUksRUFBRSxhQUFhO29CQUNuQixJQUFJLEVBQUUsVUFBVTtvQkFDaEIsTUFBTSxFQUFFLE1BQU07aUJBQ2YsQ0FBQyxDQUFBO1lBQ0osQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1gsU0FBUyxHQUFHLENBQUMsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7Z0JBQ3pELElBQUksQ0FBQyxHQUFHLE9BQU8sR0FBRyxDQUFDO29CQUFFLE1BQU0sS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFBO1lBQy9DLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxTQUFTLENBQUE7SUFDakIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxVQUFVLGFBQWEsQ0FBQyxTQUFpQixFQUFFLE9BQU8sR0FBRyxlQUFlO1FBQ3ZFLElBQUksU0FBUyxHQUFpQixJQUFJLENBQUE7UUFFbEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQztnQkFDSCxNQUFNLGlCQUFpQixDQUFPO29CQUM1QixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7b0JBQ3pCLElBQUksRUFBRSxhQUFhO29CQUNuQixJQUFJLEVBQUUsWUFBWSxTQUFTLEVBQUU7b0JBQzdCLE1BQU0sRUFBRSxRQUFRO2lCQUNqQixDQUFDLENBQUE7Z0JBQ0YsT0FBTTtZQUNSLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNYLFNBQVMsR0FBRyxDQUFDLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO2dCQUN6RCxJQUFJLENBQUMsR0FBRyxPQUFPLEdBQUcsQ0FBQztvQkFBRSxNQUFNLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQTtZQUMvQyxDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sU0FBUyxDQUFBO0lBQ2pCLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssVUFBVSxrQkFBa0I7UUFDL0IsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFBO1FBQ2hDLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFBO1FBQzFCLE1BQU0sUUFBUSxHQUFHLE1BQU0sV0FBVyxFQUFFLENBQUE7UUFDcEMsR0FBRyxDQUFDLFNBQVMsUUFBUSxDQUFDLE1BQU0sV0FBVyxDQUFDLENBQUE7UUFFeEMsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLEtBQUssVUFBVSxDQUFDLENBQUE7UUFFdEUsSUFBSSxlQUFlLEVBQUUsQ0FBQztZQUNwQixPQUFPLFVBQVUsTUFBTSxDQUFDLFFBQVEsSUFBSSxhQUFhLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxZQUFZLGVBQWUsQ0FBQyxFQUFFLEVBQUUsQ0FBQTtRQUMvRyxDQUFDO1FBRUQsR0FBRyxDQUFDLHlCQUF5QixDQUFDLENBQUE7UUFDOUIsTUFBTSxVQUFVLEdBQUcsTUFBTSxhQUFhLEVBQUUsQ0FBQTtRQUN4QyxPQUFPLFVBQVUsTUFBTSxDQUFDLFFBQVEsSUFBSSxhQUFhLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxZQUFZLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQTtJQUMxRyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxTQUFTLG1CQUFtQjtRQUMxQixNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUE7UUFDaEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQTtRQUM1RSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQTtRQUVqRCxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQy9CLEVBQUUsQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7UUFDL0MsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixDQUFDLENBQUE7UUFDM0UsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxDQUFBO1FBRWpFLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7WUFDcEMsRUFBRSxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFBO1lBQ25ELEdBQUcsQ0FBQyx1QkFBdUIsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFBO1FBQ2hELENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLFVBQVUsNkJBQTZCLGdCQUFnQixFQUFFLENBQUMsQ0FBQTtRQUM1RSxDQUFDO1FBRUQsT0FBTyxRQUFRLENBQUE7SUFDakIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxVQUFVLGFBQWEsQ0FBQyxXQUFzQixFQUFFLGFBQXNCO1FBQ3pFLElBQUksU0FBUztZQUFFLE9BQU07UUFDckIsSUFBSSxZQUFZO1lBQUUsT0FBTyxZQUFZLENBQUE7UUFFckMsWUFBWSxHQUFHLENBQUMsS0FBSyxJQUFJLEVBQUU7WUFDekIsR0FBRyxDQUFDLCtCQUErQixDQUFDLENBQUE7WUFFcEMsSUFBSSxDQUFDLE1BQU0sc0JBQXNCLEVBQUUsRUFBRSxDQUFDO2dCQUNwQyxRQUFRLENBQUM7Ozs7Ozs7OztTQVNSLENBQUMsQ0FBQTtnQkFDRixPQUFNO1lBQ1IsQ0FBQztZQUVELGFBQWEsR0FBRyxNQUFNLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1lBQ3hFLElBQUksYUFBYSxLQUFLLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDckMsR0FBRyxDQUFDLFFBQVEsTUFBTSxDQUFDLE9BQU8scUJBQXFCLGFBQWEsVUFBVSxDQUFDLENBQUE7WUFDekUsQ0FBQztZQUVELE1BQU0sZUFBZSxHQUFHLE1BQU0sb0JBQW9CLENBQUMsYUFBYSxDQUFDLENBQUE7WUFDakUsSUFBSSxlQUFlLEVBQUUsQ0FBQztnQkFDcEIsR0FBRyxDQUFDLDJDQUEyQyxhQUFhLEVBQUUsQ0FBQyxDQUFBO1lBQ2pFLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLE1BQU0sR0FBRyxNQUFNLGlCQUFpQixDQUFDLGFBQWEsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUE7Z0JBQ3RFLElBQUksTUFBTSxFQUFFLENBQUM7b0JBQ1gsR0FBRyxDQUFDLGdDQUFnQyxhQUFhLEVBQUUsQ0FBQyxDQUFBO29CQUNwRCxNQUFNLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFBO2dCQUNqQyxDQUFDO1lBQ0gsQ0FBQztZQUVELE1BQU0sU0FBUyxHQUFHLG1CQUFtQixFQUFFLENBQUE7WUFFdkMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUNyQixVQUFVLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQztvQkFDbEMsSUFBSSxFQUFFLGFBQWE7b0JBQ25CLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtvQkFDekIsU0FBUyxFQUFFLEVBQUU7b0JBQ2IsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUU7b0JBQ2xCLFNBQVM7b0JBQ1QsV0FBVztvQkFDWCxhQUFhO2lCQUNkLENBQUMsQ0FBQTtnQkFDRixHQUFHLENBQUMsa0NBQWtDLE1BQU0sQ0FBQyxRQUFRLElBQUksYUFBYSxFQUFFLENBQUMsQ0FBQTtZQUMzRSxDQUFDO1lBRUQsSUFBSSxDQUFDO2dCQUNILFVBQVUsR0FBRyxNQUFNLGtCQUFrQixFQUFFLENBQUE7Z0JBQ3ZDLEdBQUcsQ0FBQyxnQkFBZ0IsVUFBVSxFQUFFLENBQUMsQ0FBQTtZQUNuQyxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDWCxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsVUFBVSxnQ0FBZ0MsRUFBRSxDQUFDLENBQUMsQ0FBQTtZQUNoRSxDQUFDO1lBRUQsU0FBUyxHQUFHLElBQUksQ0FBQTtRQUNsQixDQUFDLENBQUMsRUFBRSxDQUFBO1FBRUosT0FBTyxZQUFZLENBQUE7SUFDckIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxVQUFVLFlBQVk7UUFDekIsR0FBRyxDQUFDLCtCQUErQixDQUFDLENBQUE7UUFFcEMsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNmLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUE7WUFDMUIsTUFBTSxJQUFJLE9BQU8sQ0FBTyxPQUFPLENBQUMsRUFBRTtnQkFDaEMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQTtnQkFDdkMsVUFBVSxDQUFDLEdBQUcsRUFBRTtvQkFDZCxVQUFVLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFBO29CQUMzQixPQUFPLEVBQUUsQ0FBQTtnQkFDWCxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFDVixDQUFDLENBQUMsQ0FBQTtZQUNGLFVBQVUsR0FBRyxJQUFJLENBQUE7UUFDbkIsQ0FBQztRQUVELElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxNQUFNLGlCQUFpQixDQUFDLGFBQWEsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDekQsQ0FBQztRQUVELFNBQVMsR0FBRyxLQUFLLENBQUE7UUFDakIsWUFBWSxHQUFHLElBQUksQ0FBQTtJQUNyQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxTQUFTLG9CQUFvQixDQUFDLEdBQXlCLEVBQUUsR0FBd0I7UUFDL0UsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtRQUNqRCxHQUFHLENBQUMsU0FBUyxDQUFDLDZCQUE2QixFQUFFLEdBQUcsQ0FBQyxDQUFBO1FBQ2pELEdBQUcsQ0FBQyxTQUFTLENBQUMsOEJBQThCLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTtRQUMzRSxHQUFHLENBQUMsU0FBUyxDQUFDLDhCQUE4QixFQUFFLGNBQWMsQ0FBQyxDQUFBO1FBRTdELElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM3QixHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ2xCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQTtZQUNULE9BQU07UUFDUixDQUFDO1FBRUQsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEtBQUssRUFBRSxDQUFDO1lBQ3pCLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDbEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUE7WUFDcEMsT0FBTTtRQUNSLENBQUM7UUFFRCxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDNUIsV0FBVyxDQUFDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQTtZQUNqQyxHQUFHLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtZQUNoQyxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ2xCLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUE7WUFDMUMsT0FBTTtRQUNSLENBQUM7UUFFRCxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDMUIsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFBO1lBQ2IsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLENBQUE7WUFDdEMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFO2dCQUNqQixJQUFJLENBQUM7b0JBQ0gsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtvQkFDN0IsV0FBVyxHQUFHO3dCQUNaLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLEVBQUU7d0JBQ25CLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUU7d0JBQ3ZCLGdCQUFnQixFQUFFLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxFQUFFO3FCQUM5QyxDQUFBO29CQUNELEdBQUcsQ0FBQyxvQkFBb0IsV0FBVyxDQUFDLEdBQUcsRUFBRSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLGFBQWEsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQTtvQkFDNUgsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQTtvQkFDbEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQTtnQkFDNUMsQ0FBQztnQkFBQyxNQUFNLENBQUM7b0JBQ1AsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQTtvQkFDbEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQTtnQkFDcEQsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFBO1lBQ0YsT0FBTTtRQUNSLENBQUM7UUFFRCxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ2xCLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxvQkFBb0IsRUFBRSxDQUFDLENBQUMsQ0FBQTtJQUMxRCxDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksRUFBRSxzQkFBc0I7UUFFNUIsS0FBSyxDQUFDLGVBQWUsQ0FBQyxNQUFxQjtZQUN6QyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU87Z0JBQUUsT0FBTTtZQUUzQixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFBO1lBQ2xELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxXQUFXLENBQUE7WUFDekQsTUFBTSxVQUFVLEdBQUcsVUFBVSxRQUFRLElBQUksUUFBUSxFQUFFLENBQUE7WUFDbkQsTUFBTSxhQUFhLEdBQUcsVUFBVSxRQUFRLElBQUksUUFBUSxHQUFHLGdCQUFnQixFQUFFLENBQUE7WUFFekUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDakIsTUFBTSxhQUFhLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQTtZQUNsRCxDQUFDO1lBRUQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRTtnQkFDN0QsSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7b0JBQzlCLE1BQU0sYUFBYSxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUE7Z0JBQ2xELENBQUM7Z0JBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsV0FBVyxDQUFDLENBQUE7Z0JBQ3BELElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO29CQUM5QixHQUFHLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSx3QkFBd0IsQ0FBQyxDQUFBO29CQUN2RCxHQUFHLENBQUMsU0FBUyxDQUFDLDZCQUE2QixFQUFFLEdBQUcsQ0FBQyxDQUFBO29CQUNqRCxFQUFFLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUMzQyxDQUFDO3FCQUFNLENBQUM7b0JBQ04sR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQTtvQkFDbEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFBO2dCQUNwQyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUE7WUFFRixNQUFNLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO2dCQUMxRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztvQkFDOUIsTUFBTSxhQUFhLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQTtnQkFDbEQsQ0FBQztnQkFDRCxvQkFBb0IsQ0FBQyxHQUEyQixFQUFFLEdBQUcsQ0FBQyxDQUFBO1lBQ3hELENBQUMsQ0FBQyxDQUFBO1lBRUYsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUU7Z0JBQ3pELEdBQUcsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLGtCQUFrQixDQUFDLENBQUE7Z0JBQ2pELEdBQUcsQ0FBQyxTQUFTLENBQUMsNkJBQTZCLEVBQUUsR0FBRyxDQUFDLENBQUE7Z0JBRWpELElBQUksTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO29CQUM5QixJQUFJLENBQUM7d0JBQ0gsTUFBTSxhQUFhLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQTt3QkFDaEQsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQTt3QkFDbEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUE7b0JBQ3hELENBQUM7b0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQzt3QkFDWCxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFBO3dCQUNsQixHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO29CQUMvQyxDQUFDO2dCQUNILENBQUM7cUJBQU0sQ0FBQztvQkFDTixHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFBO29CQUNsQixHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQTtnQkFDeEQsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFBO1lBRUYsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtnQkFDM0QsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtnQkFDakQsR0FBRyxDQUFDLFNBQVMsQ0FBQyw2QkFBNkIsRUFBRSxHQUFHLENBQUMsQ0FBQTtnQkFDakQsR0FBRyxDQUFDLFNBQVMsQ0FBQyw4QkFBOEIsRUFBRSw0QkFBNEIsQ0FBQyxDQUFBO2dCQUMzRSxHQUFHLENBQUMsU0FBUyxDQUFDLDhCQUE4QixFQUFFLGNBQWMsQ0FBQyxDQUFBO2dCQUU3RCxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQzdCLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUE7b0JBQ2xCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQTtvQkFDVCxPQUFNO2dCQUNSLENBQUM7Z0JBRUQsSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7b0JBQzlCLE1BQU0sYUFBYSxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUE7Z0JBQ2xELENBQUM7Z0JBRUQsSUFBSSxDQUFDO29CQUNILElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxLQUFLLEVBQUUsQ0FBQzt3QkFDekIsTUFBTSxRQUFRLEdBQUcsTUFBTSxXQUFXLEVBQUUsQ0FBQTt3QkFDcEMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQTt3QkFDbEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUE7b0JBQ25DLENBQUM7eUJBQU0sSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLE1BQU0sRUFBRSxDQUFDO3dCQUNqQyxNQUFNLFVBQVUsR0FBRyxNQUFNLGFBQWEsRUFBRSxDQUFBO3dCQUN4QyxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFBO3dCQUNsQixHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQTtvQkFDckMsQ0FBQzt5QkFBTSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7d0JBQ25DLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFFLFVBQVUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFBO3dCQUNoRSxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQTt3QkFFNUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDOzRCQUNmLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUE7NEJBQ2xCLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSx3QkFBd0IsRUFBRSxDQUFDLENBQUMsQ0FBQTs0QkFDNUQsT0FBTTt3QkFDUixDQUFDO3dCQUVELE1BQU0sYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFBO3dCQUM5QixHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFBO3dCQUNsQixHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFBO29CQUM1QyxDQUFDO3lCQUFNLENBQUM7d0JBQ04sR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQTt3QkFDbEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxDQUFBO29CQUMxRCxDQUFDO2dCQUNILENBQUM7Z0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztvQkFDWCxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFBO29CQUNsQixHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO2dCQUMvQyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUE7WUFFRixNQUFNLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUE7WUFFNUMsTUFBTSxPQUFPLEdBQUcsS0FBSyxJQUFJLEVBQUU7Z0JBQ3pCLE1BQU0sWUFBWSxFQUFFLENBQUE7Z0JBQ3BCLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFDakIsQ0FBQyxDQUFBO1lBRUQsT0FBTyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUE7WUFDN0IsT0FBTyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUE7WUFDOUIsT0FBTyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFO2dCQUN0QixVQUFVLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1lBQzdCLENBQUMsQ0FBQyxDQUFBO1FBQ0osQ0FBQztRQUVELGtCQUFrQixDQUFDLElBQUk7WUFDckIsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDO2dCQUMxQixNQUFNLEVBQUUsVUFBVSxNQUFNLENBQUMsUUFBUSxJQUFJLGFBQWEsRUFBRTtnQkFDcEQsU0FBUyxFQUFFLFVBQVUsTUFBTSxDQUFDLFFBQVEsSUFBSSxhQUFhLEVBQUU7Z0JBQ3ZELFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtnQkFDekIsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO2dCQUNuQixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7Z0JBQ2pCLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtnQkFDN0IsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUU7Z0JBQ2xCLFVBQVUsRUFBRSxVQUFVLElBQUksU0FBUztnQkFDbkMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO2dCQUNqQixNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU07YUFDdEIsQ0FBQyxDQUFBO1lBQ0YsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxHQUFHLE1BQU0sU0FBUyxDQUFDLENBQUE7UUFDcEQsQ0FBQztLQUNGLENBQUE7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBQbHVnaW4sIFZpdGVEZXZTZXJ2ZXIgfSBmcm9tICd2aXRlJ1xuaW1wb3J0IHsgc3Bhd24sIENoaWxkUHJvY2VzcyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnXG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJ1xuaW1wb3J0IGZzIGZyb20gJ2ZzJ1xuaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCdcbmltcG9ydCB7IHN0YXJ0T3BlbkNvZGVXZWIgfSBmcm9tICcuL3dlYi5qcydcbmltcG9ydCB7IGluamVjdFdpZGdldCB9IGZyb20gJy4vaW5qZWN0b3IuanMnXG5pbXBvcnQgeyBjaGVja09wZW5Db2RlSW5zdGFsbGVkLCBmaW5kQXZhaWxhYmxlUG9ydCwga2lsbFByb2Nlc3NPblBvcnQsIGNoZWNrT3BlbkNvZGVQcm9jZXNzIH0gZnJvbSAnLi91dGlscy5qcydcbmltcG9ydCB7IE9wZW5Db2RlT3B0aW9ucywgU2Vzc2lvbkluZm8sIFBhZ2VDb250ZXh0IH0gZnJvbSAnLi90eXBlcy5qcydcbmltcG9ydCB7XG4gIERFRkFVTFRfQ09ORklHLFxuICBERUZBVUxUX1JFVFJJRVMsXG4gIFJFVFJZX0RFTEFZLFxuICBQUk9DRVNTX0tJTExfREVMQVksXG4gIExPR19QUkVGSVgsXG4gIFdJREdFVF9TQ1JJUFRfUEFUSCxcbiAgQ09OVEVYVF9BUElfUEFUSCxcbiAgU1RBUlRfQVBJX1BBVEgsXG4gIFNFU1NJT05TX0FQSV9QQVRILFxufSBmcm9tICcuL2NvbnN0YW50cy5qcydcblxuLyoqXG4gKiBPcGVuQ29kZSBWaXRlIOaPkuS7tlxuICogQHBhcmFtIG9wdGlvbnMgLSDmj5Lku7bphY3nva7pgInpoblcbiAqIEByZXR1cm5zIFZpdGUg5o+S5Lu25a6e5L6LXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIC8vIHZpdGUuY29uZmlnLnRzXG4gKiBpbXBvcnQgb3BlbmNvZGUgZnJvbSAndml0ZS1wbHVnaW4tb3BlbmNvZGUnXG4gKlxuICogZXhwb3J0IGRlZmF1bHQge1xuICogICBwbHVnaW5zOiBbXG4gKiAgICAgb3BlbmNvZGUoe1xuICogICAgICAgd2ViUG9ydDogNDA5NyxcbiAqICAgICAgIHBvc2l0aW9uOiAnYm90dG9tLXJpZ2h0JyxcbiAqICAgICAgIHRoZW1lOiAnYXV0bydcbiAqICAgICB9KVxuICogICBdXG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gb3BlbmNvZGVQbHVnaW4ob3B0aW9uczogT3BlbkNvZGVPcHRpb25zID0ge30pOiBQbHVnaW4ge1xuICBsZXQgd2ViUHJvY2VzczogQ2hpbGRQcm9jZXNzIHwgbnVsbCA9IG51bGxcbiAgbGV0IHNlc3Npb25Vcmw6IHN0cmluZyB8IG51bGwgPSBudWxsXG4gIGxldCBhY3R1YWxXZWJQb3J0OiBudW1iZXIgPSBERUZBVUxUX0NPTkZJRy53ZWJQb3J0XG4gIGxldCBpc1N0YXJ0ZWQgPSBmYWxzZVxuICBsZXQgc3RhcnRQcm9taXNlOiBQcm9taXNlPHZvaWQ+IHwgbnVsbCA9IG51bGxcbiAgbGV0IHBhZ2VDb250ZXh0OiBQYWdlQ29udGV4dCA9IHsgdXJsOiAnJywgdGl0bGU6ICcnIH1cblxuICBjb25zdCBjb25maWcgPSB7IC4uLkRFRkFVTFRfQ09ORklHLCAuLi5vcHRpb25zIH1cblxuICAvKipcbiAgICog6L6T5Ye65pel5b+X77yI5LuF5ZyoIHZlcmJvc2Ug5qih5byP5LiL77yJXG4gICAqL1xuICBmdW5jdGlvbiBsb2cobWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICBpZiAoY29uZmlnLnZlcmJvc2UpIHtcbiAgICAgIGNvbnNvbGUubG9nKGAke0xPR19QUkVGSVh9ICR7bWVzc2FnZX1gLCAuLi5hcmdzKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDovpPlh7rplJnor6/ml6Xlv5dcbiAgICovXG4gIGZ1bmN0aW9uIGxvZ0Vycm9yKG1lc3NhZ2U6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKTogdm9pZCB7XG4gICAgY29uc29sZS5lcnJvcihgJHtMT0dfUFJFRklYfSAke21lc3NhZ2V9YCwgLi4uYXJncylcbiAgfVxuXG4gIC8qKlxuICAgKiBCYXNlNjQg57yW56CB5a2X56ym5LiyXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlNjRFbmNvZGUoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShzdHIpLnRvU3RyaW5nKCdiYXNlNjQnKVxuICB9XG5cbiAgLyoqXG4gICAqIOW7tui/n+aJp+ihjFxuICAgKi9cbiAgZnVuY3Rpb24gc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKVxuICB9XG5cbiAgLyoqXG4gICAqIOWIm+W7uiBIVFRQIOivt+axgiBQcm9taXNlXG4gICAqL1xuICBmdW5jdGlvbiBjcmVhdGVIdHRwUmVxdWVzdDxUPihvcHRpb25zOiBodHRwLlJlcXVlc3RPcHRpb25zLCBib2R5Pzogc3RyaW5nKTogUHJvbWlzZTxUPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHJlcSA9IGh0dHAucmVxdWVzdChvcHRpb25zLCAocmVzKSA9PiB7XG4gICAgICAgIGxldCBkYXRhID0gJydcbiAgICAgICAgcmVzLm9uKCdkYXRhJywgY2h1bmsgPT4gZGF0YSArPSBjaHVuaylcbiAgICAgICAgcmVzLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc29sdmUoSlNPTi5wYXJzZShkYXRhKSlcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEpTT04gcGFyc2UgZXJyb3I6ICR7ZGF0YS5zdWJzdHJpbmcoMCwgMTAwKX1gKSlcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgICAgcmVxLm9uKCdlcnJvcicsIHJlamVjdClcbiAgICAgIGlmIChib2R5KSByZXEud3JpdGUoYm9keSlcbiAgICAgIHJlcS5lbmQoKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICog6I635Y+W5Lya6K+d5YiX6KGoXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBnZXRTZXNzaW9ucyhyZXRyaWVzID0gREVGQVVMVF9SRVRSSUVTKTogUHJvbWlzZTxTZXNzaW9uSW5mb1tdPiB7XG4gICAgbGV0IGxhc3RFcnJvcjogRXJyb3IgfCBudWxsID0gbnVsbFxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXRyaWVzOyBpKyspIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBjcmVhdGVIdHRwUmVxdWVzdDxTZXNzaW9uSW5mb1tdPih7XG4gICAgICAgICAgaG9zdG5hbWU6IGNvbmZpZy5ob3N0bmFtZSxcbiAgICAgICAgICBwb3J0OiBhY3R1YWxXZWJQb3J0LFxuICAgICAgICAgIHBhdGg6ICcvc2Vzc2lvbicsXG4gICAgICAgIH0pXG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGxhc3RFcnJvciA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUgOiBuZXcgRXJyb3IoU3RyaW5nKGUpKVxuICAgICAgICBpZiAoaSA8IHJldHJpZXMgLSAxKSBhd2FpdCBzbGVlcChSRVRSWV9ERUxBWSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBsYXN0RXJyb3JcbiAgfVxuXG4gIC8qKlxuICAgKiDliJvlu7rmlrDkvJror51cbiAgICovXG4gIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVNlc3Npb24ocmV0cmllcyA9IERFRkFVTFRfUkVUUklFUyk6IFByb21pc2U8U2Vzc2lvbkluZm8+IHtcbiAgICBsZXQgbGFzdEVycm9yOiBFcnJvciB8IG51bGwgPSBudWxsXG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJldHJpZXM7IGkrKykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGNyZWF0ZUh0dHBSZXF1ZXN0PFNlc3Npb25JbmZvPih7XG4gICAgICAgICAgaG9zdG5hbWU6IGNvbmZpZy5ob3N0bmFtZSxcbiAgICAgICAgICBwb3J0OiBhY3R1YWxXZWJQb3J0LFxuICAgICAgICAgIHBhdGg6ICcvc2Vzc2lvbicsXG4gICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIH0pXG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGxhc3RFcnJvciA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUgOiBuZXcgRXJyb3IoU3RyaW5nKGUpKVxuICAgICAgICBpZiAoaSA8IHJldHJpZXMgLSAxKSBhd2FpdCBzbGVlcChSRVRSWV9ERUxBWSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBsYXN0RXJyb3JcbiAgfVxuXG4gIC8qKlxuICAgKiDliKDpmaTkvJror51cbiAgICovXG4gIGFzeW5jIGZ1bmN0aW9uIGRlbGV0ZVNlc3Npb24oc2Vzc2lvbklkOiBzdHJpbmcsIHJldHJpZXMgPSBERUZBVUxUX1JFVFJJRVMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsZXQgbGFzdEVycm9yOiBFcnJvciB8IG51bGwgPSBudWxsXG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJldHJpZXM7IGkrKykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgY3JlYXRlSHR0cFJlcXVlc3Q8dm9pZD4oe1xuICAgICAgICAgIGhvc3RuYW1lOiBjb25maWcuaG9zdG5hbWUsXG4gICAgICAgICAgcG9ydDogYWN0dWFsV2ViUG9ydCxcbiAgICAgICAgICBwYXRoOiBgL3Nlc3Npb24vJHtzZXNzaW9uSWR9YCxcbiAgICAgICAgICBtZXRob2Q6ICdERUxFVEUnLFxuICAgICAgICB9KVxuICAgICAgICByZXR1cm5cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbGFzdEVycm9yID0gZSBpbnN0YW5jZW9mIEVycm9yID8gZSA6IG5ldyBFcnJvcihTdHJpbmcoZSkpXG4gICAgICAgIGlmIChpIDwgcmV0cmllcyAtIDEpIGF3YWl0IHNsZWVwKFJFVFJZX0RFTEFZKVxuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IGxhc3RFcnJvclxuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPluaIluWIm+W7uuS8muivnVxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gZ2V0T3JDcmVhdGVTZXNzaW9uKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgcHJvamVjdERpciA9IHByb2Nlc3MuY3dkKClcbiAgICBsb2coJ0dldHRpbmcgc2Vzc2lvbnMuLi4nKVxuICAgIGNvbnN0IHNlc3Npb25zID0gYXdhaXQgZ2V0U2Vzc2lvbnMoKVxuICAgIGxvZyhgRm91bmQgJHtzZXNzaW9ucy5sZW5ndGh9IHNlc3Npb25zYClcblxuICAgIGNvbnN0IG1hdGNoaW5nU2Vzc2lvbiA9IHNlc3Npb25zLmZpbmQocyA9PiBzLmRpcmVjdG9yeSA9PT0gcHJvamVjdERpcilcblxuICAgIGlmIChtYXRjaGluZ1Nlc3Npb24pIHtcbiAgICAgIHJldHVybiBgaHR0cDovLyR7Y29uZmlnLmhvc3RuYW1lfToke2FjdHVhbFdlYlBvcnR9LyR7YmFzZTY0RW5jb2RlKHByb2plY3REaXIpfS9zZXNzaW9uLyR7bWF0Y2hpbmdTZXNzaW9uLmlkfWBcbiAgICB9XG5cbiAgICBsb2coJ0NyZWF0aW5nIG5ldyBzZXNzaW9uLi4uJylcbiAgICBjb25zdCBuZXdTZXNzaW9uID0gYXdhaXQgY3JlYXRlU2Vzc2lvbigpXG4gICAgcmV0dXJuIGBodHRwOi8vJHtjb25maWcuaG9zdG5hbWV9OiR7YWN0dWFsV2ViUG9ydH0vJHtiYXNlNjRFbmNvZGUocHJvamVjdERpcil9L3Nlc3Npb24vJHtuZXdTZXNzaW9uLmlkfWBcbiAgfVxuXG4gIC8qKlxuICAgKiDorr7nva4gT3BlbkNvZGUg5o+S5Lu2XG4gICAqL1xuICBmdW5jdGlvbiBzZXR1cE9wZW5Db2RlUGx1Z2luKCk6IHN0cmluZyB7XG4gICAgY29uc3QgcHJvamVjdERpciA9IHByb2Nlc3MuY3dkKClcbiAgICBjb25zdCBjYWNoZURpciA9IHBhdGguam9pbihwcm9qZWN0RGlyLCAnbm9kZV9tb2R1bGVzJywgJy5jYWNoZScsICdvcGVuY29kZScpXG4gICAgY29uc3QgcGx1Z2luc0RpciA9IHBhdGguam9pbihjYWNoZURpciwgJ3BsdWdpbnMnKVxuXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHBsdWdpbnNEaXIpKSB7XG4gICAgICBmcy5ta2RpclN5bmMocGx1Z2luc0RpciwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgICB9XG5cbiAgICBjb25zdCBwbHVnaW5Tb3VyY2VQYXRoID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJ3BsdWdpbnMnLCAncGFnZS1jb250ZXh0LmpzJylcbiAgICBjb25zdCBwbHVnaW5UYXJnZXRQYXRoID0gcGF0aC5qb2luKHBsdWdpbnNEaXIsICdwYWdlLWNvbnRleHQuanMnKVxuXG4gICAgaWYgKGZzLmV4aXN0c1N5bmMocGx1Z2luU291cmNlUGF0aCkpIHtcbiAgICAgIGZzLmNvcHlGaWxlU3luYyhwbHVnaW5Tb3VyY2VQYXRoLCBwbHVnaW5UYXJnZXRQYXRoKVxuICAgICAgbG9nKGBQbHVnaW4gaW5zdGFsbGVkIHRvICR7cGx1Z2luVGFyZ2V0UGF0aH1gKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLndhcm4oYCR7TE9HX1BSRUZJWH0gUGx1Z2luIHNvdXJjZSBub3QgZm91bmQ6ICR7cGx1Z2luU291cmNlUGF0aH1gKVxuICAgIH1cblxuICAgIHJldHVybiBjYWNoZURpclxuICB9XG5cbiAgLyoqXG4gICAqIOWQr+WKqOacjeWKoVxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gc3RhcnRTZXJ2aWNlcyhjb3JzT3JpZ2lucz86IHN0cmluZ1tdLCBjb250ZXh0QXBpVXJsPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKGlzU3RhcnRlZCkgcmV0dXJuXG4gICAgaWYgKHN0YXJ0UHJvbWlzZSkgcmV0dXJuIHN0YXJ0UHJvbWlzZVxuXG4gICAgc3RhcnRQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgIGxvZygnU3RhcnRpbmcgT3BlbkNvZGUgc2VydmljZXMuLi4nKVxuXG4gICAgICBpZiAoIWF3YWl0IGNoZWNrT3BlbkNvZGVJbnN0YWxsZWQoKSkge1xuICAgICAgICBsb2dFcnJvcihgT3BlbkNvZGUgaXMgbm90IGluc3RhbGxlZCFcblxuUGxlYXNlIGluc3RhbGwgT3BlbkNvZGUgZmlyc3Q6XG5cbiAgIyBVc2luZyBIb21lYnJldyAobWFjT1MpXG4gIGJyZXcgaW5zdGFsbCBvcGVuY29kZS1haS90YXAvb3BlbmNvZGVcblxuICAjIE9yIHVzaW5nIHRoZSBpbnN0YWxsIHNjcmlwdFxuICBjdXJsIC1mc1NMIGh0dHBzOi8vb3BlbmNvZGUuYWkvaW5zdGFsbCB8IGJhc2hcbiAgICAgICAgYClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGFjdHVhbFdlYlBvcnQgPSBhd2FpdCBmaW5kQXZhaWxhYmxlUG9ydChjb25maWcud2ViUG9ydCwgY29uZmlnLmhvc3RuYW1lKVxuICAgICAgaWYgKGFjdHVhbFdlYlBvcnQgIT09IGNvbmZpZy53ZWJQb3J0KSB7XG4gICAgICAgIGxvZyhgUG9ydCAke2NvbmZpZy53ZWJQb3J0fSBpcyBpbiB1c2UsIHVzaW5nICR7YWN0dWFsV2ViUG9ydH0gaW5zdGVhZGApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4aXN0aW5nUHJvY2VzcyA9IGF3YWl0IGNoZWNrT3BlbkNvZGVQcm9jZXNzKGFjdHVhbFdlYlBvcnQpXG4gICAgICBpZiAoZXhpc3RpbmdQcm9jZXNzKSB7XG4gICAgICAgIGxvZyhgRm91bmQgZXhpc3RpbmcgT3BlbkNvZGUgcHJvY2VzcyBvbiBwb3J0ICR7YWN0dWFsV2ViUG9ydH1gKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qga2lsbGVkID0gYXdhaXQga2lsbFByb2Nlc3NPblBvcnQoYWN0dWFsV2ViUG9ydCwgY29uZmlnLmhvc3RuYW1lKVxuICAgICAgICBpZiAoa2lsbGVkKSB7XG4gICAgICAgICAgbG9nKGBLaWxsZWQgc3RhbGUgcHJvY2VzcyBvbiBwb3J0ICR7YWN0dWFsV2ViUG9ydH1gKVxuICAgICAgICAgIGF3YWl0IHNsZWVwKFBST0NFU1NfS0lMTF9ERUxBWSlcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBjb25maWdEaXIgPSBzZXR1cE9wZW5Db2RlUGx1Z2luKClcblxuICAgICAgaWYgKCFleGlzdGluZ1Byb2Nlc3MpIHtcbiAgICAgICAgd2ViUHJvY2VzcyA9IGF3YWl0IHN0YXJ0T3BlbkNvZGVXZWIoe1xuICAgICAgICAgIHBvcnQ6IGFjdHVhbFdlYlBvcnQsXG4gICAgICAgICAgaG9zdG5hbWU6IGNvbmZpZy5ob3N0bmFtZSxcbiAgICAgICAgICBzZXJ2ZXJVcmw6ICcnLFxuICAgICAgICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgICAgICAgICBjb25maWdEaXIsXG4gICAgICAgICAgY29yc09yaWdpbnMsXG4gICAgICAgICAgY29udGV4dEFwaVVybCxcbiAgICAgICAgfSlcbiAgICAgICAgbG9nKGBPcGVuQ29kZSBXZWIgc3RhcnRlZCBhdCBodHRwOi8vJHtjb25maWcuaG9zdG5hbWV9OiR7YWN0dWFsV2ViUG9ydH1gKVxuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBzZXNzaW9uVXJsID0gYXdhaXQgZ2V0T3JDcmVhdGVTZXNzaW9uKClcbiAgICAgICAgbG9nKGBTZXNzaW9uIFVSTDogJHtzZXNzaW9uVXJsfWApXG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgJHtMT0dfUFJFRklYfSBGYWlsZWQgdG8gZ2V0L2NyZWF0ZSBzZXNzaW9uOmAsIGUpXG4gICAgICB9XG5cbiAgICAgIGlzU3RhcnRlZCA9IHRydWVcbiAgICB9KSgpXG5cbiAgICByZXR1cm4gc3RhcnRQcm9taXNlXG4gIH1cblxuICAvKipcbiAgICog5YGc5q2i5pyN5YqhXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBzdG9wU2VydmljZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKCdTdG9wcGluZyBPcGVuQ29kZSBzZXJ2aWNlcy4uLicpXG4gICAgXG4gICAgaWYgKHdlYlByb2Nlc3MpIHtcbiAgICAgIHdlYlByb2Nlc3Mua2lsbCgnU0lHVEVSTScpXG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPihyZXNvbHZlID0+IHtcbiAgICAgICAgd2ViUHJvY2Vzcz8ub24oJ2V4aXQnLCAoKSA9PiByZXNvbHZlKCkpXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHdlYlByb2Nlc3M/LmtpbGwoJ1NJR0tJTEwnKVxuICAgICAgICAgIHJlc29sdmUoKVxuICAgICAgICB9LCAzMDAwKVxuICAgICAgfSlcbiAgICAgIHdlYlByb2Nlc3MgPSBudWxsXG4gICAgfVxuICAgIFxuICAgIGlmIChpc1N0YXJ0ZWQpIHtcbiAgICAgIGF3YWl0IGtpbGxQcm9jZXNzT25Qb3J0KGFjdHVhbFdlYlBvcnQsIGNvbmZpZy5ob3N0bmFtZSlcbiAgICB9XG4gICAgXG4gICAgaXNTdGFydGVkID0gZmFsc2VcbiAgICBzdGFydFByb21pc2UgPSBudWxsXG4gIH1cblxuICAvKipcbiAgICog5aSE55CG5LiK5LiL5paHIEFQSSDor7fmsYJcbiAgICovXG4gIGZ1bmN0aW9uIGhhbmRsZUNvbnRleHRSZXF1ZXN0KHJlcTogaHR0cC5JbmNvbWluZ01lc3NhZ2UsIHJlczogaHR0cC5TZXJ2ZXJSZXNwb25zZSk6IHZvaWQge1xuICAgIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJylcbiAgICByZXMuc2V0SGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4nLCAnKicpXG4gICAgcmVzLnNldEhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctTWV0aG9kcycsICdHRVQsIFBPU1QsIERFTEVURSwgT1BUSU9OUycpXG4gICAgcmVzLnNldEhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycycsICdDb250ZW50LVR5cGUnKVxuXG4gICAgaWYgKHJlcS5tZXRob2QgPT09ICdPUFRJT05TJykge1xuICAgICAgcmVzLndyaXRlSGVhZCgyMDApXG4gICAgICByZXMuZW5kKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChyZXEubWV0aG9kID09PSAnR0VUJykge1xuICAgICAgcmVzLndyaXRlSGVhZCgyMDApXG4gICAgICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KHBhZ2VDb250ZXh0KSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChyZXEubWV0aG9kID09PSAnREVMRVRFJykge1xuICAgICAgcGFnZUNvbnRleHQuc2VsZWN0ZWRFbGVtZW50cyA9IFtdXG4gICAgICBsb2coJ1NlbGVjdGVkIGVsZW1lbnRzIGNsZWFyZWQnKVxuICAgICAgcmVzLndyaXRlSGVhZCgyMDApXG4gICAgICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KHsgc3VjY2VzczogdHJ1ZSB9KSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChyZXEubWV0aG9kID09PSAnUE9TVCcpIHtcbiAgICAgIGxldCBib2R5ID0gJydcbiAgICAgIHJlcS5vbignZGF0YScsIGNodW5rID0+IGJvZHkgKz0gY2h1bmspXG4gICAgICByZXEub24oJ2VuZCcsICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gSlNPTi5wYXJzZShib2R5KVxuICAgICAgICAgIHBhZ2VDb250ZXh0ID0ge1xuICAgICAgICAgICAgdXJsOiBkYXRhLnVybCB8fCAnJyxcbiAgICAgICAgICAgIHRpdGxlOiBkYXRhLnRpdGxlIHx8ICcnLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50czogZGF0YS5zZWxlY3RlZEVsZW1lbnRzIHx8IFtdLFxuICAgICAgICAgIH1cbiAgICAgICAgICBsb2coYENvbnRleHQgdXBkYXRlZDogJHtwYWdlQ29udGV4dC51cmx9YCwgZGF0YS5zZWxlY3RlZEVsZW1lbnRzPy5sZW5ndGggPyBgZWxlbWVudHM6ICR7ZGF0YS5zZWxlY3RlZEVsZW1lbnRzLmxlbmd0aH1gIDogJycpXG4gICAgICAgICAgcmVzLndyaXRlSGVhZCgyMDApXG4gICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IHN1Y2Nlc3M6IHRydWUgfSkpXG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHJlcy53cml0ZUhlYWQoNDAwKVxuICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogJ0ludmFsaWQgSlNPTicgfSkpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICByZXMud3JpdGVIZWFkKDQwNSlcbiAgICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KHsgZXJyb3I6ICdNZXRob2Qgbm90IGFsbG93ZWQnIH0pKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAndml0ZS1wbHVnaW4tb3BlbmNvZGUnLFxuXG4gICAgYXN5bmMgY29uZmlndXJlU2VydmVyKHNlcnZlcjogVml0ZURldlNlcnZlcikge1xuICAgICAgaWYgKCFjb25maWcuZW5hYmxlZCkgcmV0dXJuXG5cbiAgICAgIGNvbnN0IHZpdGVQb3J0ID0gc2VydmVyLmNvbmZpZy5zZXJ2ZXIucG9ydCB8fCA1MTczXG4gICAgICBjb25zdCB2aXRlSG9zdCA9IHNlcnZlci5jb25maWcuc2VydmVyLmhvc3QgfHwgJ2xvY2FsaG9zdCdcbiAgICAgIGNvbnN0IHZpdGVPcmlnaW4gPSBgaHR0cDovLyR7dml0ZUhvc3R9OiR7dml0ZVBvcnR9YFxuICAgICAgY29uc3QgY29udGV4dEFwaVVybCA9IGBodHRwOi8vJHt2aXRlSG9zdH06JHt2aXRlUG9ydH0ke0NPTlRFWFRfQVBJX1BBVEh9YFxuXG4gICAgICBpZiAoIWNvbmZpZy5sYXp5KSB7XG4gICAgICAgIGF3YWl0IHN0YXJ0U2VydmljZXMoW3ZpdGVPcmlnaW5dLCBjb250ZXh0QXBpVXJsKVxuICAgICAgfVxuXG4gICAgICBzZXJ2ZXIubWlkZGxld2FyZXMudXNlKFdJREdFVF9TQ1JJUFRfUEFUSCwgYXN5bmMgKF9yZXEsIHJlcykgPT4ge1xuICAgICAgICBpZiAoY29uZmlnLmxhenkgJiYgIWlzU3RhcnRlZCkge1xuICAgICAgICAgIGF3YWl0IHN0YXJ0U2VydmljZXMoW3ZpdGVPcmlnaW5dLCBjb250ZXh0QXBpVXJsKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgd2lkZ2V0UGF0aCA9IHBhdGguam9pbihfX2Rpcm5hbWUsICdjbGllbnQuanMnKVxuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyh3aWRnZXRQYXRoKSkge1xuICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0JylcbiAgICAgICAgICByZXMuc2V0SGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4nLCAnKicpXG4gICAgICAgICAgZnMuY3JlYXRlUmVhZFN0cmVhbSh3aWRnZXRQYXRoKS5waXBlKHJlcylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXMud3JpdGVIZWFkKDQwNClcbiAgICAgICAgICByZXMuZW5kKCdXaWRnZXQgc2NyaXB0IG5vdCBmb3VuZCcpXG4gICAgICAgIH1cbiAgICAgIH0pXG5cbiAgICAgIHNlcnZlci5taWRkbGV3YXJlcy51c2UoQ09OVEVYVF9BUElfUEFUSCwgYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgICAgIGlmIChjb25maWcubGF6eSAmJiAhaXNTdGFydGVkKSB7XG4gICAgICAgICAgYXdhaXQgc3RhcnRTZXJ2aWNlcyhbdml0ZU9yaWdpbl0sIGNvbnRleHRBcGlVcmwpXG4gICAgICAgIH1cbiAgICAgICAgaGFuZGxlQ29udGV4dFJlcXVlc3QocmVxIGFzIGh0dHAuSW5jb21pbmdNZXNzYWdlLCByZXMpXG4gICAgICB9KVxuXG4gICAgICBzZXJ2ZXIubWlkZGxld2FyZXMudXNlKFNUQVJUX0FQSV9QQVRILCBhc3luYyAoX3JlcSwgcmVzKSA9PiB7XG4gICAgICAgIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJylcbiAgICAgICAgcmVzLnNldEhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJywgJyonKVxuXG4gICAgICAgIGlmIChjb25maWcubGF6eSAmJiAhaXNTdGFydGVkKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHN0YXJ0U2VydmljZXMoW3ZpdGVPcmlnaW5dLCBjb250ZXh0QXBpVXJsKVxuICAgICAgICAgICAgcmVzLndyaXRlSGVhZCgyMDApXG4gICAgICAgICAgICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KHsgc3VjY2VzczogdHJ1ZSwgc2Vzc2lvblVybCB9KSlcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDUwMClcbiAgICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogU3RyaW5nKGUpIH0pKVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXMud3JpdGVIZWFkKDIwMClcbiAgICAgICAgICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KHsgc3VjY2VzczogdHJ1ZSwgc2Vzc2lvblVybCB9KSlcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAgc2VydmVyLm1pZGRsZXdhcmVzLnVzZShTRVNTSU9OU19BUElfUEFUSCwgYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgICAgIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJylcbiAgICAgICAgcmVzLnNldEhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJywgJyonKVxuICAgICAgICByZXMuc2V0SGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJywgJ0dFVCwgUE9TVCwgREVMRVRFLCBPUFRJT05TJylcbiAgICAgICAgcmVzLnNldEhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycycsICdDb250ZW50LVR5cGUnKVxuXG4gICAgICAgIGlmIChyZXEubWV0aG9kID09PSAnT1BUSU9OUycpIHtcbiAgICAgICAgICByZXMud3JpdGVIZWFkKDIwMClcbiAgICAgICAgICByZXMuZW5kKClcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb25maWcubGF6eSAmJiAhaXNTdGFydGVkKSB7XG4gICAgICAgICAgYXdhaXQgc3RhcnRTZXJ2aWNlcyhbdml0ZU9yaWdpbl0sIGNvbnRleHRBcGlVcmwpXG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChyZXEubWV0aG9kID09PSAnR0VUJykge1xuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbnMgPSBhd2FpdCBnZXRTZXNzaW9ucygpXG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDIwMClcbiAgICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoc2Vzc2lvbnMpKVxuICAgICAgICAgIH0gZWxzZSBpZiAocmVxLm1ldGhvZCA9PT0gJ1BPU1QnKSB7XG4gICAgICAgICAgICBjb25zdCBuZXdTZXNzaW9uID0gYXdhaXQgY3JlYXRlU2Vzc2lvbigpXG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDIwMClcbiAgICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkobmV3U2Vzc2lvbikpXG4gICAgICAgICAgfSBlbHNlIGlmIChyZXEubWV0aG9kID09PSAnREVMRVRFJykge1xuICAgICAgICAgICAgY29uc3QgdXJsID0gbmV3IFVSTChyZXEudXJsIHx8ICcnLCBgaHR0cDovLyR7cmVxLmhlYWRlcnMuaG9zdH1gKVxuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gdXJsLnNlYXJjaFBhcmFtcy5nZXQoJ2lkJylcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKCFzZXNzaW9uSWQpIHtcbiAgICAgICAgICAgICAgcmVzLndyaXRlSGVhZCg0MDApXG4gICAgICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogJ1Nlc3Npb24gSUQgaXMgcmVxdWlyZWQnIH0pKVxuICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgYXdhaXQgZGVsZXRlU2Vzc2lvbihzZXNzaW9uSWQpXG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDIwMClcbiAgICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBzdWNjZXNzOiB0cnVlIH0pKVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDQwNSlcbiAgICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogJ01ldGhvZCBub3QgYWxsb3dlZCcgfSkpXG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcmVzLndyaXRlSGVhZCg1MDApXG4gICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiBTdHJpbmcoZSkgfSkpXG4gICAgICAgIH1cbiAgICAgIH0pXG5cbiAgICAgIHNlcnZlci5odHRwU2VydmVyPy5vbignY2xvc2UnLCBzdG9wU2VydmljZXMpXG4gICAgICBcbiAgICAgIGNvbnN0IGNsZWFudXAgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHN0b3BTZXJ2aWNlcygpXG4gICAgICAgIHByb2Nlc3MuZXhpdCgwKVxuICAgICAgfVxuICAgICAgXG4gICAgICBwcm9jZXNzLm9uKCdTSUdJTlQnLCBjbGVhbnVwKVxuICAgICAgcHJvY2Vzcy5vbignU0lHVEVSTScsIGNsZWFudXApXG4gICAgICBwcm9jZXNzLm9uKCdleGl0JywgKCkgPT4ge1xuICAgICAgICB3ZWJQcm9jZXNzPy5raWxsKCdTSUdLSUxMJylcbiAgICAgIH0pXG4gICAgfSxcblxuICAgIHRyYW5zZm9ybUluZGV4SHRtbChodG1sKSB7XG4gICAgICBjb25zdCB3aWRnZXQgPSBpbmplY3RXaWRnZXQoe1xuICAgICAgICB3ZWJVcmw6IGBodHRwOi8vJHtjb25maWcuaG9zdG5hbWV9OiR7YWN0dWFsV2ViUG9ydH1gLFxuICAgICAgICBzZXJ2ZXJVcmw6IGBodHRwOi8vJHtjb25maWcuaG9zdG5hbWV9OiR7YWN0dWFsV2ViUG9ydH1gLFxuICAgICAgICBwb3NpdGlvbjogY29uZmlnLnBvc2l0aW9uLFxuICAgICAgICB0aGVtZTogY29uZmlnLnRoZW1lLFxuICAgICAgICBvcGVuOiBjb25maWcub3BlbixcbiAgICAgICAgYXV0b1JlbG9hZDogY29uZmlnLmF1dG9SZWxvYWQsXG4gICAgICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgICAgICAgc2Vzc2lvblVybDogc2Vzc2lvblVybCB8fCB1bmRlZmluZWQsXG4gICAgICAgIGxhenk6IGNvbmZpZy5sYXp5LFxuICAgICAgICBob3RrZXk6IGNvbmZpZy5ob3RrZXksXG4gICAgICB9KVxuICAgICAgcmV0dXJuIGh0bWwucmVwbGFjZSgnPC9ib2R5PicsIGAke3dpZGdldH08L2JvZHk+YClcbiAgICB9LFxuICB9XG59XG4iXX0=
|
package/dist/injector.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { WidgetOptions } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* 生成挂件注入脚本标签
|
|
4
|
-
* @param options - 挂件配置选项
|
|
5
|
-
* @returns HTML 脚本标签字符串
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* const widget = injectWidget({
|
|
9
|
-
* webUrl: 'http://127.0.0.1:4097',
|
|
10
|
-
* serverUrl: 'http://127.0.0.1:4097',
|
|
11
|
-
* position: 'bottom-right',
|
|
12
|
-
* theme: 'auto',
|
|
13
|
-
* open: false,
|
|
14
|
-
* autoReload: true,
|
|
15
|
-
* cwd: process.cwd()
|
|
16
|
-
* })
|
|
17
|
-
* // 返回: '<script src="/__opencode_widget__.js" data-opencode-config="..."></script>'
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
export declare function injectWidget(options: WidgetOptions): string;
|
package/dist/injector.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { WIDGET_SCRIPT_PATH, CONFIG_DATA_ATTR } from './constants.js';
|
|
2
|
-
/**
|
|
3
|
-
* 生成挂件注入脚本标签
|
|
4
|
-
* @param options - 挂件配置选项
|
|
5
|
-
* @returns HTML 脚本标签字符串
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* const widget = injectWidget({
|
|
9
|
-
* webUrl: 'http://127.0.0.1:4097',
|
|
10
|
-
* serverUrl: 'http://127.0.0.1:4097',
|
|
11
|
-
* position: 'bottom-right',
|
|
12
|
-
* theme: 'auto',
|
|
13
|
-
* open: false,
|
|
14
|
-
* autoReload: true,
|
|
15
|
-
* cwd: process.cwd()
|
|
16
|
-
* })
|
|
17
|
-
* // 返回: '<script src="/__opencode_widget__.js" data-opencode-config="..."></script>'
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
export function injectWidget(options) {
|
|
21
|
-
const configBase64 = Buffer.from(JSON.stringify(options)).toString('base64');
|
|
22
|
-
return `<script src="${WIDGET_SCRIPT_PATH}" ${CONFIG_DATA_ATTR}="${configBase64}"></script>`;
|
|
23
|
-
}
|
|
24
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5qZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5qZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFFckU7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FBQyxPQUFzQjtJQUNqRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDNUUsT0FBTyxnQkFBZ0Isa0JBQWtCLEtBQUssZ0JBQWdCLEtBQUssWUFBWSxhQUFhLENBQUE7QUFDOUYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFdpZGdldE9wdGlvbnMgfSBmcm9tICcuL3R5cGVzLmpzJ1xuaW1wb3J0IHsgV0lER0VUX1NDUklQVF9QQVRILCBDT05GSUdfREFUQV9BVFRSIH0gZnJvbSAnLi9jb25zdGFudHMuanMnXG5cbi8qKlxuICog55Sf5oiQ5oyC5Lu25rOo5YWl6ISa5pys5qCH562+XG4gKiBAcGFyYW0gb3B0aW9ucyAtIOaMguS7tumFjee9rumAiemhuVxuICogQHJldHVybnMgSFRNTCDohJrmnKzmoIfnrb7lrZfnrKbkuLJcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogY29uc3Qgd2lkZ2V0ID0gaW5qZWN0V2lkZ2V0KHtcbiAqICAgd2ViVXJsOiAnaHR0cDovLzEyNy4wLjAuMTo0MDk3JyxcbiAqICAgc2VydmVyVXJsOiAnaHR0cDovLzEyNy4wLjAuMTo0MDk3JyxcbiAqICAgcG9zaXRpb246ICdib3R0b20tcmlnaHQnLFxuICogICB0aGVtZTogJ2F1dG8nLFxuICogICBvcGVuOiBmYWxzZSxcbiAqICAgYXV0b1JlbG9hZDogdHJ1ZSxcbiAqICAgY3dkOiBwcm9jZXNzLmN3ZCgpXG4gKiB9KVxuICogLy8g6L+U5ZueOiAnPHNjcmlwdCBzcmM9XCIvX19vcGVuY29kZV93aWRnZXRfXy5qc1wiIGRhdGEtb3BlbmNvZGUtY29uZmlnPVwiLi4uXCI+PC9zY3JpcHQ+J1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RXaWRnZXQob3B0aW9uczogV2lkZ2V0T3B0aW9ucyk6IHN0cmluZyB7XG4gIGNvbnN0IGNvbmZpZ0Jhc2U2NCA9IEJ1ZmZlci5mcm9tKEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpKS50b1N0cmluZygnYmFzZTY0JylcbiAgcmV0dXJuIGA8c2NyaXB0IHNyYz1cIiR7V0lER0VUX1NDUklQVF9QQVRIfVwiICR7Q09ORklHX0RBVEFfQVRUUn09XCIke2NvbmZpZ0Jhc2U2NH1cIj48L3NjcmlwdD5gXG59XG4iXX0=
|