@dollhousemcp/mcp-server 2.0.18 → 2.0.20
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/CHANGELOG.md +8 -0
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/handlers/ElementCRUDHandler.d.ts +30 -0
- package/dist/handlers/ElementCRUDHandler.d.ts.map +1 -1
- package/dist/handlers/ElementCRUDHandler.js +141 -2
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts +3 -0
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/MCPAQLHandler.js +98 -1
- package/dist/handlers/mcp-aql/OperationRouter.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/OperationRouter.js +6 -1
- package/dist/handlers/mcp-aql/OperationSchema.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/OperationSchema.js +17 -1
- package/dist/handlers/mcp-aql/policies/AgentToolPolicyTranslator.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/AgentToolPolicyTranslator.js +2 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.js +2 -1
- package/dist/handlers/mcp-aql/policies/OperationPolicies.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/OperationPolicies.js +6 -1
- package/dist/handlers/mcp-aql/policies/ToolClassification.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/ToolClassification.js +2 -1
- package/dist/server/tools/MCPAQLTools.js +2 -1
- package/dist/web/console/IngestRoutes.d.ts +6 -0
- package/dist/web/console/IngestRoutes.d.ts.map +1 -1
- package/dist/web/console/IngestRoutes.js +38 -9
- package/dist/web/console/LeaderElection.d.ts +39 -0
- package/dist/web/console/LeaderElection.d.ts.map +1 -1
- package/dist/web/console/LeaderElection.js +147 -29
- package/dist/web/console/LeaderForwardingSink.d.ts.map +1 -1
- package/dist/web/console/LeaderForwardingSink.js +5 -1
- package/dist/web/console/PromotionManager.d.ts.map +1 -1
- package/dist/web/console/PromotionManager.js +3 -11
- package/dist/web/console/StaleProcessRecovery.d.ts +11 -0
- package/dist/web/console/StaleProcessRecovery.d.ts.map +1 -1
- package/dist/web/console/StaleProcessRecovery.js +229 -63
- package/dist/web/console/UnifiedConsole.d.ts +22 -1
- package/dist/web/console/UnifiedConsole.d.ts.map +1 -1
- package/dist/web/console/UnifiedConsole.js +172 -11
- package/dist/web/public/app.js +62 -1
- package/dist/web/public/index.html +19 -17
- package/dist/web/public/sessions.js +111 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +12 -10
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StaleProcessRecovery.d.ts","sourceRoot":"","sources":["../../../src/web/console/StaleProcessRecovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"StaleProcessRecovery.d.ts","sourceRoot":"","sources":["../../../src/web/console/StaleProcessRecovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA8DH,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EACF,gBAAgB,GAChB,gBAAgB,GAChB,uBAAuB,GACvB,oBAAoB,GACpB,YAAY,GACZ,cAAc,GACd,aAAa,GACb,eAAe,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGlE;AA8LD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxE;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGlF;AAED,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAyB1G;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoCrE"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* Extracted to a standalone module so it can be tested without importing
|
|
9
9
|
* the full Express server and its dependency chain.
|
|
10
10
|
*/
|
|
11
|
+
import { UnicodeValidator } from '../../security/validators/unicodeValidator.js';
|
|
11
12
|
// Use lazy import for logger to avoid pulling in the full env.ts/config chain
|
|
12
13
|
// at module load time. This keeps the module independently testable.
|
|
13
14
|
/** Timeout for lsof/fuser/ps system calls (ms) */
|
|
@@ -20,6 +21,12 @@ const KILL_POLL_COUNT = 10;
|
|
|
20
21
|
const SIGKILL_WAIT_MS = 500;
|
|
21
22
|
/** Wait between lock file reads for TOCTOU mitigation (ms) */
|
|
22
23
|
const LOCK_RECHECK_DELAY_MS = 500;
|
|
24
|
+
/** Number of lock-file checks before deciding the port holder is not a fresh leader. */
|
|
25
|
+
const LOCK_RECHECK_ATTEMPTS = 2;
|
|
26
|
+
/** PID used by the OS init/launchd process; direct children are effectively orphaned. */
|
|
27
|
+
const ROOT_PARENT_PID = 1;
|
|
28
|
+
/** Number of `ps` columns requested by inspectProcess: user, pid, ppid, command. */
|
|
29
|
+
const PROCESS_INSPECTION_FIELD_COUNT = 4;
|
|
23
30
|
let _logger = null;
|
|
24
31
|
async function getLogger() {
|
|
25
32
|
if (!_logger) {
|
|
@@ -31,10 +38,190 @@ async function getLogger() {
|
|
|
31
38
|
return _logger;
|
|
32
39
|
}
|
|
33
40
|
const logger = {
|
|
34
|
-
warn: async (...args) => {
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
warn: async (...args) => {
|
|
42
|
+
const l = await getLogger();
|
|
43
|
+
if (l)
|
|
44
|
+
l.warn(args[0], args[1]);
|
|
45
|
+
else
|
|
46
|
+
console.error('[WARN]', ...args);
|
|
47
|
+
},
|
|
48
|
+
info: async (...args) => {
|
|
49
|
+
const l = await getLogger();
|
|
50
|
+
if (l)
|
|
51
|
+
l.info(args[0], args[1]);
|
|
52
|
+
else
|
|
53
|
+
console.error('[INFO]', ...args);
|
|
54
|
+
},
|
|
55
|
+
debug: async (...args) => {
|
|
56
|
+
const l = await getLogger();
|
|
57
|
+
if (l)
|
|
58
|
+
l.debug(args[0], args[1]);
|
|
59
|
+
},
|
|
37
60
|
};
|
|
61
|
+
const MCP_HOST_PARENT_PATTERNS = [
|
|
62
|
+
/Claude\.app\/Contents\/Helpers\/disclaimer/i,
|
|
63
|
+
/Codex\.app\/Contents\/Resources\/codex app-server/i,
|
|
64
|
+
/Cursor\.app\//i,
|
|
65
|
+
/Windsurf\.app\//i,
|
|
66
|
+
];
|
|
67
|
+
export function isRecognizedMcpHostParent(command) {
|
|
68
|
+
const normalizedCommand = UnicodeValidator.normalize(command).normalizedContent;
|
|
69
|
+
return MCP_HOST_PARENT_PATTERNS.some((pattern) => pattern.test(normalizedCommand));
|
|
70
|
+
}
|
|
71
|
+
function isDollhouseProcessCommand(cmdLine) {
|
|
72
|
+
const normalizedCommand = UnicodeValidator.normalize(cmdLine).normalizedContent;
|
|
73
|
+
const isDollhouseBin = /(?:^|\/)dollhousemcp(?:\s|$)/.test(normalizedCommand) ||
|
|
74
|
+
normalizedCommand.includes('.bin/dollhousemcp');
|
|
75
|
+
const isMcpServerBin = normalizedCommand.includes('.bin/mcp-server') ||
|
|
76
|
+
/(?:dollhousemcp|mcp-server)[/\\]dist[/\\]index\.js/.test(normalizedCommand);
|
|
77
|
+
return isDollhouseBin || isMcpServerBin;
|
|
78
|
+
}
|
|
79
|
+
function parsePidToken(value) {
|
|
80
|
+
if (!value)
|
|
81
|
+
return null;
|
|
82
|
+
for (let i = 0; i < value.length; i++) {
|
|
83
|
+
const codePoint = value.codePointAt(i);
|
|
84
|
+
if (codePoint === undefined || codePoint < 48 || codePoint > 57) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const parsed = Number.parseInt(value, 10);
|
|
89
|
+
if (!Number.isSafeInteger(parsed) || parsed < ROOT_PARENT_PID) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
return parsed;
|
|
93
|
+
}
|
|
94
|
+
function isWhitespaceChar(value) {
|
|
95
|
+
return value === ' ' || value === '\t' || value === '\n' || value === '\r' || value === '\f' || value === '\v';
|
|
96
|
+
}
|
|
97
|
+
function buildKillOutcome(killed, reason, processInfo, parentCommand, detail) {
|
|
98
|
+
return {
|
|
99
|
+
killed,
|
|
100
|
+
reason,
|
|
101
|
+
pid: processInfo.pid,
|
|
102
|
+
parentPid: processInfo.parentPid,
|
|
103
|
+
command: processInfo.command,
|
|
104
|
+
parentCommand,
|
|
105
|
+
...(detail ? { detail } : {}),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async function getKillGuardFailure(processInfo, port) {
|
|
109
|
+
const currentUser = (await import('node:os')).userInfo().username;
|
|
110
|
+
if (processInfo.user !== currentUser) {
|
|
111
|
+
await logger.warn(`[WebUI] Port ${port} held by different user (pid ${processInfo.pid}) — not killing`);
|
|
112
|
+
return buildKillOutcome(false, 'different_user', processInfo);
|
|
113
|
+
}
|
|
114
|
+
if (!isDollhouseProcessCommand(processInfo.command)) {
|
|
115
|
+
await logger.warn(`[WebUI] Port ${port} held by non-DollhouseMCP process (pid ${processInfo.pid}) — not killing`, {
|
|
116
|
+
cmdLine: processInfo.command,
|
|
117
|
+
});
|
|
118
|
+
return buildKillOutcome(false, 'not_dollhouse_process', processInfo);
|
|
119
|
+
}
|
|
120
|
+
if (processInfo.parentPid <= ROOT_PARENT_PID || !isPidAlive(processInfo.parentPid)) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const parentCommand = (await getProcessCommand(processInfo.parentPid)) ?? undefined;
|
|
124
|
+
if (parentCommand && isRecognizedMcpHostParent(parentCommand)) {
|
|
125
|
+
await logger.warn(`[WebUI] Port ${port} held by active client-backed DollhouseMCP process (pid ${processInfo.pid}) — not killing`, {
|
|
126
|
+
cmdLine: processInfo.command,
|
|
127
|
+
parentPid: processInfo.parentPid,
|
|
128
|
+
parentCommand,
|
|
129
|
+
});
|
|
130
|
+
return buildKillOutcome(false, 'active_host_parent', processInfo, parentCommand);
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
async function terminateProcess(processInfo, port, parentCommand) {
|
|
135
|
+
process.kill(processInfo.pid, 'SIGTERM');
|
|
136
|
+
logger.warn(`[WebUI] Sent SIGTERM to stale process ${processInfo.pid} on port ${port}`, {
|
|
137
|
+
cmdLine: processInfo.command,
|
|
138
|
+
parentPid: processInfo.parentPid,
|
|
139
|
+
parentCommand,
|
|
140
|
+
});
|
|
141
|
+
for (let i = 0; i < KILL_POLL_COUNT; i++) {
|
|
142
|
+
await new Promise(r => setTimeout(r, SIGTERM_POLL_MS));
|
|
143
|
+
if (!isPidAlive(processInfo.pid)) {
|
|
144
|
+
return buildKillOutcome(true, 'terminated', processInfo, parentCommand);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
process.kill(processInfo.pid, 'SIGKILL');
|
|
148
|
+
logger.warn(`[WebUI] Sent SIGKILL to stale process ${processInfo.pid} on port ${port}`);
|
|
149
|
+
await new Promise(r => setTimeout(r, SIGKILL_WAIT_MS));
|
|
150
|
+
return isPidAlive(processInfo.pid)
|
|
151
|
+
? buildKillOutcome(false, 'still_alive', processInfo, parentCommand)
|
|
152
|
+
: buildKillOutcome(true, 'terminated', processInfo, parentCommand);
|
|
153
|
+
}
|
|
154
|
+
function splitProcessInspectionFields(line) {
|
|
155
|
+
const fields = [];
|
|
156
|
+
let index = 0;
|
|
157
|
+
const normalizedLine = UnicodeValidator.normalize(line).normalizedContent.trim();
|
|
158
|
+
while (index < normalizedLine.length && fields.length < PROCESS_INSPECTION_FIELD_COUNT - 1) {
|
|
159
|
+
while (index < normalizedLine.length && isWhitespaceChar(normalizedLine[index])) {
|
|
160
|
+
index++;
|
|
161
|
+
}
|
|
162
|
+
if (index >= normalizedLine.length)
|
|
163
|
+
break;
|
|
164
|
+
const fieldStart = index;
|
|
165
|
+
while (index < normalizedLine.length && !isWhitespaceChar(normalizedLine[index])) {
|
|
166
|
+
index++;
|
|
167
|
+
}
|
|
168
|
+
fields.push(normalizedLine.slice(fieldStart, index));
|
|
169
|
+
}
|
|
170
|
+
while (index < normalizedLine.length && isWhitespaceChar(normalizedLine[index])) {
|
|
171
|
+
index++;
|
|
172
|
+
}
|
|
173
|
+
if (index < normalizedLine.length) {
|
|
174
|
+
fields.push(normalizedLine.slice(index));
|
|
175
|
+
}
|
|
176
|
+
return fields.length === PROCESS_INSPECTION_FIELD_COUNT ? fields : null;
|
|
177
|
+
}
|
|
178
|
+
async function inspectProcess(pid) {
|
|
179
|
+
const { execFile: execFileCb } = await import('node:child_process');
|
|
180
|
+
const { promisify } = await import('node:util');
|
|
181
|
+
const execFileAsync = promisify(execFileCb);
|
|
182
|
+
try {
|
|
183
|
+
const { stdout } = await execFileAsync('ps', ['-p', String(pid), '-o', 'user=,pid=,ppid=,command='], { timeout: COMMAND_TIMEOUT_MS });
|
|
184
|
+
const fields = splitProcessInspectionFields(stdout);
|
|
185
|
+
if (!fields)
|
|
186
|
+
return null;
|
|
187
|
+
const [user, pidToken, parentPidToken, command] = fields;
|
|
188
|
+
const parsedPid = parsePidToken(pidToken);
|
|
189
|
+
const parsedParentPid = parsePidToken(parentPidToken);
|
|
190
|
+
if (parsedPid === null || parsedParentPid === null)
|
|
191
|
+
return null;
|
|
192
|
+
return {
|
|
193
|
+
user: UnicodeValidator.normalize(user).normalizedContent,
|
|
194
|
+
pid: parsedPid,
|
|
195
|
+
parentPid: parsedParentPid,
|
|
196
|
+
command: UnicodeValidator.normalize(command).normalizedContent,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async function getProcessCommand(pid) {
|
|
204
|
+
const { execFile: execFileCb } = await import('node:child_process');
|
|
205
|
+
const { promisify } = await import('node:util');
|
|
206
|
+
const execFileAsync = promisify(execFileCb);
|
|
207
|
+
try {
|
|
208
|
+
const { stdout } = await execFileAsync('ps', ['-p', String(pid), '-o', 'command='], { timeout: COMMAND_TIMEOUT_MS });
|
|
209
|
+
const normalized = UnicodeValidator.normalize(stdout).normalizedContent.trim();
|
|
210
|
+
return normalized || null;
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function isPidAlive(pid) {
|
|
217
|
+
try {
|
|
218
|
+
process.kill(pid, 0);
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
38
225
|
/**
|
|
39
226
|
* Find the PID of the process listening on a given port.
|
|
40
227
|
* Uses lsof on macOS/Linux. Returns null if not found or on error.
|
|
@@ -56,7 +243,10 @@ export async function findPidOnPort(port) {
|
|
|
56
243
|
const { stdout, stderr } = await execFileAsync(cmd.bin, cmd.args, { timeout: COMMAND_TIMEOUT_MS });
|
|
57
244
|
// fuser outputs to stderr on some systems
|
|
58
245
|
const output = (stdout || stderr || '').trim();
|
|
59
|
-
const pids = output
|
|
246
|
+
const pids = output
|
|
247
|
+
.split(/\s+/)
|
|
248
|
+
.map((token) => parsePidToken(token))
|
|
249
|
+
.filter((pid) => pid !== null);
|
|
60
250
|
const otherPid = pids.find(p => p !== process.pid);
|
|
61
251
|
if (otherPid)
|
|
62
252
|
return otherPid;
|
|
@@ -76,63 +266,31 @@ export async function findPidOnPort(port) {
|
|
|
76
266
|
* before escalating to SIGKILL. Total worst case: ~4s.
|
|
77
267
|
*/
|
|
78
268
|
export async function killStaleProcess(pid, port) {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
try {
|
|
88
|
-
const { stdout } = await execFileAsync('ps', ['-p', String(pid), '-o', 'user=,command='], { timeout: COMMAND_TIMEOUT_MS });
|
|
89
|
-
// Check 1: User ownership — only kill our own processes
|
|
90
|
-
const currentUser = (await import('node:os')).userInfo().username;
|
|
91
|
-
if (!stdout.trim().startsWith(currentUser)) {
|
|
92
|
-
await logger.warn(`[WebUI] Port ${port} held by different user (pid ${pid}) — not killing`);
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
// Check 2: Binary identity — must be .bin/mcp-server, .bin/dollhousemcp,
|
|
96
|
-
// /bin/dollhousemcp (global install), or dist/index.js (direct node execution).
|
|
97
|
-
// NOT just 'mcp-server' anywhere in the path — that would match Jest workers
|
|
98
|
-
// running from within the mcp-server project directory.
|
|
99
|
-
cmdLine = stdout.trim();
|
|
100
|
-
const isDollhouseBin = /(?:^|\/)dollhousemcp(?:\s|$)/.test(cmdLine) ||
|
|
101
|
-
cmdLine.includes('.bin/dollhousemcp');
|
|
102
|
-
const isMcpServerBin = cmdLine.includes('.bin/mcp-server') ||
|
|
103
|
-
/(?:dollhousemcp|mcp-server)[/\\]dist[/\\]index\.js/.test(cmdLine);
|
|
104
|
-
if (!isDollhouseBin && !isMcpServerBin) {
|
|
105
|
-
await logger.warn(`[WebUI] Port ${port} held by non-DollhouseMCP process (pid ${pid}) — not killing`, { cmdLine });
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
await logger.debug(`[WebUI] Verified stale process ${pid} is DollhouseMCP`, { cmdLine });
|
|
269
|
+
const outcome = await killStaleProcessDetailed(pid, port);
|
|
270
|
+
return outcome.killed;
|
|
271
|
+
}
|
|
272
|
+
export async function killStaleProcessDetailed(pid, port) {
|
|
273
|
+
const processInfo = await inspectProcess(pid);
|
|
274
|
+
if (!processInfo) {
|
|
275
|
+
await logger.debug(`[WebUI] Cannot verify process ${pid} — skipping kill`);
|
|
276
|
+
return { killed: false, reason: 'inspect_failed', pid };
|
|
109
277
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
error: err instanceof Error ? err.message : String(err),
|
|
114
|
-
});
|
|
115
|
-
return false;
|
|
278
|
+
const guardFailure = await getKillGuardFailure(processInfo, port);
|
|
279
|
+
if (guardFailure) {
|
|
280
|
+
return guardFailure;
|
|
116
281
|
}
|
|
282
|
+
const parentCommand = processInfo.parentPid > ROOT_PARENT_PID
|
|
283
|
+
? (await getProcessCommand(processInfo.parentPid)) ?? undefined
|
|
284
|
+
: undefined;
|
|
285
|
+
await logger.debug(`[WebUI] Verified stale process ${pid} is DollhouseMCP`, { cmdLine: processInfo.command, parentPid: processInfo.parentPid, parentCommand });
|
|
117
286
|
try {
|
|
118
|
-
|
|
119
|
-
logger.warn(`[WebUI] Sent SIGTERM to stale process ${pid} on port ${port}`, { cmdLine });
|
|
120
|
-
for (let i = 0; i < KILL_POLL_COUNT; i++) {
|
|
121
|
-
await new Promise(r => setTimeout(r, SIGTERM_POLL_MS));
|
|
122
|
-
try {
|
|
123
|
-
process.kill(pid, 0);
|
|
124
|
-
}
|
|
125
|
-
catch {
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
process.kill(pid, 'SIGKILL');
|
|
130
|
-
logger.warn(`[WebUI] Sent SIGKILL to stale process ${pid} on port ${port}`);
|
|
131
|
-
await new Promise(r => setTimeout(r, SIGKILL_WAIT_MS));
|
|
132
|
-
return true;
|
|
287
|
+
return await terminateProcess(processInfo, port, parentCommand);
|
|
133
288
|
}
|
|
134
|
-
catch {
|
|
135
|
-
|
|
289
|
+
catch (err) {
|
|
290
|
+
if (!isPidAlive(pid)) {
|
|
291
|
+
return buildKillOutcome(true, 'already_dead', processInfo, parentCommand);
|
|
292
|
+
}
|
|
293
|
+
return buildKillOutcome(false, 'signal_failed', processInfo, parentCommand, err instanceof Error ? err.message : String(err));
|
|
136
294
|
}
|
|
137
295
|
}
|
|
138
296
|
/**
|
|
@@ -150,7 +308,7 @@ export async function recoverStalePort(port) {
|
|
|
150
308
|
// written its lock file. Read the lock, pause, re-read. If the second read
|
|
151
309
|
// now matches the port holder, it's a fresh leader — don't kill.
|
|
152
310
|
const { readLeaderLock } = await import('./LeaderElection.js');
|
|
153
|
-
for (let check = 0; check <
|
|
311
|
+
for (let check = 0; check < LOCK_RECHECK_ATTEMPTS; check++) {
|
|
154
312
|
try {
|
|
155
313
|
const lock = await readLeaderLock();
|
|
156
314
|
if (lock?.pid === stalePid && lock?.port === port && lock.pid !== process.pid) {
|
|
@@ -161,15 +319,23 @@ export async function recoverStalePort(port) {
|
|
|
161
319
|
catch {
|
|
162
320
|
// Can't read lock file — continue to next check or kill
|
|
163
321
|
}
|
|
164
|
-
if (check
|
|
322
|
+
if (check < LOCK_RECHECK_ATTEMPTS - 1) {
|
|
165
323
|
await new Promise(r => setTimeout(r, LOCK_RECHECK_DELAY_MS));
|
|
166
324
|
}
|
|
167
325
|
}
|
|
168
|
-
const
|
|
169
|
-
if (killed) {
|
|
326
|
+
const outcome = await killStaleProcessDetailed(stalePid, port);
|
|
327
|
+
if (outcome.killed) {
|
|
170
328
|
logger.info(`[WebUI] Stale process ${stalePid} removed from port ${port}`);
|
|
171
329
|
await new Promise(r => setTimeout(r, SIGKILL_WAIT_MS)); // brief pause for port release
|
|
172
330
|
}
|
|
173
|
-
|
|
331
|
+
else {
|
|
332
|
+
await logger.debug(`[WebUI] Stale-port recovery skipped for pid ${stalePid}`, {
|
|
333
|
+
reason: outcome.reason,
|
|
334
|
+
parentPid: outcome.parentPid,
|
|
335
|
+
parentCommand: outcome.parentCommand,
|
|
336
|
+
detail: outcome.detail,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
return outcome.killed;
|
|
174
340
|
}
|
|
175
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RhbGVQcm9jZXNzUmVjb3ZlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2ViL2NvbnNvbGUvU3RhbGVQcm9jZXNzUmVjb3ZlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7OztHQVNHO0FBRUgsOEVBQThFO0FBQzlFLHFFQUFxRTtBQUNyRSxrREFBa0Q7QUFDbEQsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUM7QUFDaEMsb0VBQW9FO0FBQ3BFLE1BQU0sZUFBZSxHQUFHLEdBQUcsQ0FBQztBQUM1QixtREFBbUQ7QUFDbkQsTUFBTSxlQUFlLEdBQUcsRUFBRSxDQUFDO0FBQzNCLCtDQUErQztBQUMvQyxNQUFNLGVBQWUsR0FBRyxHQUFHLENBQUM7QUFDNUIsOERBQThEO0FBQzlELE1BQU0scUJBQXFCLEdBQUcsR0FBRyxDQUFDO0FBRWxDLElBQUksT0FBTyxHQUF5RCxJQUFJLENBQUM7QUFDekUsS0FBSyxVQUFVLFNBQVM7SUFDdEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2IsSUFBSSxDQUFDO1lBQUMsT0FBTyxHQUFHLENBQUMsTUFBTSxNQUFNLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUFDLENBQUM7UUFDakUsTUFBTSxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBQ0QsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQUNELE1BQU0sTUFBTSxHQUFHO0lBQ2IsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLElBQWUsRUFBRSxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsTUFBTSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFXLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFL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QU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCx3REFBd0Q7UUFDMUQsQ0FBQztRQUNELElBQUksS0FBSyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLHFCQUFxQixDQUFDLENBQUMsQ0FBQztRQUMvRCxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3RELElBQUksTUFBTSxFQUFFLENBQUM7UUFDWCxNQUFNLENBQUMsSUFBSSxDQUFDLHlCQUF5QixRQUFRLHNCQUFzQixJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzNFLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQywrQkFBK0I7SUFDekYsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFN0YWxlIHByb2Nlc3MgZGV0ZWN0aW9uIGFuZCByZWNvdmVyeSAoIzE4NTApLlxuICpcbiAqIEZpbmRzIGFuZCBraWxscyB6b21iaWUgRG9sbGhvdXNlTUNQIHByb2Nlc3NlcyB0aGF0IHNxdWF0IG9uIHRoZSBjb25zb2xlXG4gKiBwb3J0IGFmdGVyIHRoZWlyIHNlc3Npb24gaGFzIGVuZGVkLiBVc2VkIGJ5IGJpbmRBbmRMaXN0ZW4gaW4gc2VydmVyLnRzXG4gKiB3aGVuIEVBRERSSU5VU0Ugb2NjdXJzLlxuICpcbiAqIEV4dHJhY3RlZCB0byBhIHN0YW5kYWxvbmUgbW9kdWxlIHNvIGl0IGNhbiBiZSB0ZXN0ZWQgd2l0aG91dCBpbXBvcnRpbmdcbiAqIHRoZSBmdWxsIEV4cHJlc3Mgc2VydmVyIGFuZCBpdHMgZGVwZW5kZW5jeSBjaGFpbi5cbiAqL1xuXG4vLyBVc2UgbGF6eSBpbXBvcnQgZm9yIGxvZ2dlciB0byBhdm9pZCBwdWxsaW5nIGluIHRoZSBmdWxsIGVudi50cy9jb25maWcgY2hhaW5cbi8vIGF0IG1vZHVsZSBsb2FkIHRpbWUuIFRoaXMga2VlcHMgdGhlIG1vZHVsZSBpbmRlcGVuZGVudGx5IHRlc3RhYmxlLlxuLyoqIFRpbWVvdXQgZm9yIGxzb2YvZnVzZXIvcHMgc3lzdGVtIGNhbGxzIChtcykgKi9cbmNvbnN0IENPTU1BTkRfVElNRU9VVF9NUyA9IDEwMDA7XG4vKiogUG9sbGluZyBpbnRlcnZhbCB3aGVuIHdhaXRpbmcgZm9yIFNJR1RFUk0gdG8gdGFrZSBlZmZlY3QgKG1zKSAqL1xuY29uc3QgU0lHVEVSTV9QT0xMX01TID0gMzAwO1xuLyoqIE51bWJlciBvZiBwb2xscyBiZWZvcmUgZXNjYWxhdGluZyB0byBTSUdLSUxMICovXG5jb25zdCBLSUxMX1BPTExfQ09VTlQgPSAxMDtcbi8qKiBXYWl0IGFmdGVyIFNJR0tJTEwgYmVmb3JlIHJldHVybmluZyAobXMpICovXG5jb25zdCBTSUdLSUxMX1dBSVRfTVMgPSA1MDA7XG4vKiogV2FpdCBiZXR3ZWVuIGxvY2sgZmlsZSByZWFkcyBmb3IgVE9DVE9VIG1pdGlnYXRpb24gKG1zKSAqL1xuY29uc3QgTE9DS19SRUNIRUNLX0RFTEFZX01TID0gNTAwO1xuXG5sZXQgX2xvZ2dlcjogdHlwZW9mIGltcG9ydCgnLi4vLi4vdXRpbHMvbG9nZ2VyLmpzJykubG9nZ2VyIHwgbnVsbCA9IG51bGw7XG5hc3luYyBmdW5jdGlvbiBnZXRMb2dnZXIoKSB7XG4gIGlmICghX2xvZ2dlcikge1xuICAgIHRyeSB7IF9sb2dnZXIgPSAoYXdhaXQgaW1wb3J0KCcuLi8uLi91dGlscy9sb2dnZXIuanMnKSkubG9nZ2VyOyB9XG4gICAgY2F0Y2ggeyAvKiBmYWxsYmFjayBiZWxvdyAqLyB9XG4gIH1cbiAgcmV0dXJuIF9sb2dnZXI7XG59XG5jb25zdCBsb2dnZXIgPSB7XG4gIHdhcm46IGFzeW5jICguLi5hcmdzOiB1bmtub3duW10pID0+IHsgY29uc3QgbCA9IGF3YWl0IGdldExvZ2dlcigpOyBsID8gbC53YXJuKGFyZ3NbMF0gYXMgc3RyaW5nLCBhcmdzWzFdKSA6IGNvbnNvbGUuZXJyb3IoJ1tXQVJOXScsIC4uLmFyZ3MpOyB9LFxuICBpbmZvOiBhc3luYyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7IGNvbnN0IGwgPSBhd2FpdCBnZXRMb2dnZXIoKTsgbCA/IGwuaW5mbyhhcmdzWzBdIGFzIHN0cmluZywgYXJnc1sxXSkgOiBjb25zb2xlLmVycm9yKCdbSU5GT10nLCAuLi5hcmdzKTsgfSxcbiAgZGVidWc6IGFzeW5jICguLi5hcmdzOiB1bmtub3duW10pID0+IHsgY29uc3QgbCA9IGF3YWl0IGdldExvZ2dlcigpOyBsID8gbC5kZWJ1ZyhhcmdzWzBdIGFzIHN0cmluZywgYXJnc1sxXSkgOiB2b2lkIDA7IH0sXG59O1xuXG4vKipcbiAqIEZpbmQgdGhlIFBJRCBvZiB0aGUgcHJvY2VzcyBsaXN0ZW5pbmcgb24gYSBnaXZlbiBwb3J0LlxuICogVXNlcyBsc29mIG9uIG1hY09TL0xpbnV4LiBSZXR1cm5zIG51bGwgaWYgbm90IGZvdW5kIG9yIG9uIGVycm9yLlxuICpcbiAqIFRpbWVvdXQ6IDFzIOKAlCBsc29mIG9uIGxvY2FsaG9zdCBpcyB0eXBpY2FsbHkgPDEwMG1zLiBUaGUgMXMgY2VpbGluZ1xuICogaGFuZGxlcyBzbG93IE5GUy1tb3VudGVkIC9kZXYvZmQgb3Igb3ZlcmxvYWRlZCBDSSBydW5uZXJzIHdpdGhvdXRcbiAqIGRlbGF5aW5nIHN0YXJ0dXAgbm90aWNlYWJseS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpbmRQaWRPblBvcnQocG9ydDogbnVtYmVyKTogUHJvbWlzZTxudW1iZXIgfCBudWxsPiB7XG4gIGNvbnN0IHsgZXhlY0ZpbGU6IGV4ZWNGaWxlQ2IgfSA9IGF3YWl0IGltcG9ydCgnbm9kZTpjaGlsZF9wcm9jZXNzJyk7XG4gIGNvbnN0IHsgcHJvbWlzaWZ5IH0gPSBhd2FpdCBpbXBvcnQoJ25vZGU6dXRpbCcpO1xuICBjb25zdCBleGVjRmlsZUFzeW5jID0gcHJvbWlzaWZ5KGV4ZWNGaWxlQ2IpO1xuXG4gIC8vIFRyeSBsc29mIGZpcnN0IChtYWNPUyArIG1vc3QgTGludXgpLCBmYWxsIGJhY2sgdG8gZnVzZXIgKG1pbmltYWwgTGludXgvRG9ja2VyKVxuICBmb3IgKGNvbnN0IGNtZCBvZiBbXG4gICAgeyBiaW46ICdsc29mJywgYXJnczogWyctdGknLCBgOiR7cG9ydH1gXSB9LFxuICAgIHsgYmluOiAnZnVzZXInLCBhcmdzOiBbYCR7cG9ydH0vdGNwYF0gfSxcbiAgXSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IHN0ZG91dCwgc3RkZXJyIH0gPSBhd2FpdCBleGVjRmlsZUFzeW5jKGNtZC5iaW4sIGNtZC5hcmdzLCB7IHRpbWVvdXQ6IENPTU1BTkRfVElNRU9VVF9NUyB9KTtcbiAgICAgIC8vIGZ1c2VyIG91dHB1dHMgdG8gc3RkZXJyIG9uIHNvbWUgc3lzdGVtc1xuICAgICAgY29uc3Qgb3V0cHV0ID0gKHN0ZG91dCB8fCBzdGRlcnIgfHwgJycpLnRyaW0oKTtcbiAgICAgIGNvbnN0IHBpZHMgPSBvdXRwdXQuc3BsaXQoL1xccysvKS5tYXAoTnVtYmVyKS5maWx0ZXIobiA9PiAhTnVtYmVyLmlzTmFOKG4pICYmIG4gPiAwKTtcbiAgICAgIGNvbnN0IG90aGVyUGlkID0gcGlkcy5maW5kKHAgPT4gcCAhPT0gcHJvY2Vzcy5waWQpO1xuICAgICAgaWYgKG90aGVyUGlkKSByZXR1cm4gb3RoZXJQaWQ7XG4gICAgfSBjYXRjaCB7XG4gICAgICBjb250aW51ZTsgLy8gY29tbWFuZCBub3QgZm91bmQgb3Igbm8gcmVzdWx0cyDigJQgdHJ5IG5leHRcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogS2lsbCBhIHN0YWxlIHByb2Nlc3MgaG9sZGluZyBhIHBvcnQuIFNlbmRzIFNJR1RFUk0sIHdhaXRzIGJyaWVmbHksXG4gKiB0aGVuIFNJR0tJTEwgaWYgc3RpbGwgYWxpdmUuIE9ubHkga2lsbHMgRG9sbGhvdXNlTUNQIHByb2Nlc3Nlc1xuICogKHZlcmlmaWVkIGJ5IGNoZWNraW5nIHRoZSBjb21tYW5kIGxpbmUgYW5kIHVzZXIgb3duZXJzaGlwKS5cbiAqXG4gKiBUaW1lb3V0OiAxcyBmb3IgcHMgdmVyaWZpY2F0aW9uLiBLaWxsIHdhaXQ6IDMwMG1zIMOXIDEwIHBvbGxzID0gM3NcbiAqIGJlZm9yZSBlc2NhbGF0aW5nIHRvIFNJR0tJTEwuIFRvdGFsIHdvcnN0IGNhc2U6IH40cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGtpbGxTdGFsZVByb2Nlc3MocGlkOiBudW1iZXIsIHBvcnQ6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBjb25zdCB7IGV4ZWNGaWxlOiBleGVjRmlsZUNiIH0gPSBhd2FpdCBpbXBvcnQoJ25vZGU6Y2hpbGRfcHJvY2VzcycpO1xuICBjb25zdCB7IHByb21pc2lmeSB9ID0gYXdhaXQgaW1wb3J0KCdub2RlOnV0aWwnKTtcbiAgY29uc3QgZXhlY0ZpbGVBc3luYyA9IHByb21pc2lmeShleGVjRmlsZUNiKTtcblxuICAvLyBTZWN1cml0eSB2ZXJpZmljYXRpb24gZmxvdyDigJQgdGhyZWUgY2hlY2tzIG11c3QgcGFzcyBiZWZvcmUgd2Uga2lsbDpcbiAgLy8gMS4gUHJvY2VzcyBtdXN0IGJlIG93bmVkIGJ5IHRoZSBjdXJyZW50IE9TIHVzZXIgKHByZXZlbnRzIGNyb3NzLXVzZXIga2lsbHMpXG4gIC8vIDIuIENvbW1hbmQgbGluZSBtdXN0IG1hdGNoIGEgRG9sbGhvdXNlTUNQIGJpbmFyeSBwYXRoIChwcmV2ZW50cyBraWxsaW5nIG90aGVyIHNlcnZpY2VzKVxuICAvLyAzLiBJZiBib3RoIGZhaWwgb3IgcHMgY2FuJ3QgcnVuLCB3ZSByZWZ1c2Ug4oCUIHNhZmUgZGVmYXVsdCBpcyB0byBub3Qga2lsbFxuICBsZXQgY21kTGluZSA9ICcnO1xuICB0cnkge1xuICAgIGNvbnN0IHsgc3Rkb3V0IH0gPSBhd2FpdCBleGVjRmlsZUFzeW5jKCdwcycsIFsnLXAnLCBTdHJpbmcocGlkKSwgJy1vJywgJ3VzZXI9LGNvbW1hbmQ9J10sIHsgdGltZW91dDogQ09NTUFORF9USU1FT1VUX01TIH0pO1xuXG4gICAgLy8gQ2hlY2sgMTogVXNlciBvd25lcnNoaXAg4oCUIG9ubHkga2lsbCBvdXIgb3duIHByb2Nlc3Nlc1xuICAgIGNvbnN0IGN1cnJlbnRVc2VyID0gKGF3YWl0IGltcG9ydCgnbm9kZTpvcycpKS51c2VySW5mbygpLnVzZXJuYW1lO1xuICAgIGlmICghc3Rkb3V0LnRyaW0oKS5zdGFydHNXaXRoKGN1cnJlbnRVc2VyKSkge1xuICAgICAgYXdhaXQgbG9nZ2VyLndhcm4oYFtXZWJVSV0gUG9ydCAke3BvcnR9IGhlbGQgYnkgZGlmZmVyZW50IHVzZXIgKHBpZCAke3BpZH0pIOKAlCBub3Qga2lsbGluZ2ApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIENoZWNrIDI6IEJpbmFyeSBpZGVudGl0eSDigJQgbXVzdCBiZSAuYmluL21jcC1zZXJ2ZXIsIC5iaW4vZG9sbGhvdXNlbWNwLFxuICAgIC8vIC9iaW4vZG9sbGhvdXNlbWNwIChnbG9iYWwgaW5zdGFsbCksIG9yIGRpc3QvaW5kZXguanMgKGRpcmVjdCBub2RlIGV4ZWN1dGlvbikuXG4gICAgLy8gTk9UIGp1c3QgJ21jcC1zZXJ2ZXInIGFueXdoZXJlIGluIHRoZSBwYXRoIOKAlCB0aGF0IHdvdWxkIG1hdGNoIEplc3Qgd29ya2Vyc1xuICAgIC8vIHJ1bm5pbmcgZnJvbSB3aXRoaW4gdGhlIG1jcC1zZXJ2ZXIgcHJvamVjdCBkaXJlY3RvcnkuXG4gICAgY21kTGluZSA9IHN0ZG91dC50cmltKCk7XG4gICAgY29uc3QgaXNEb2xsaG91c2VCaW4gPSAvKD86XnxcXC8pZG9sbGhvdXNlbWNwKD86XFxzfCQpLy50ZXN0KGNtZExpbmUpIHx8XG4gICAgICBjbWRMaW5lLmluY2x1ZGVzKCcuYmluL2RvbGxob3VzZW1jcCcpO1xuICAgIGNvbnN0IGlzTWNwU2VydmVyQmluID0gY21kTGluZS5pbmNsdWRlcygnLmJpbi9tY3Atc2VydmVyJykgfHxcbiAgICAgIC8oPzpkb2xsaG91c2VtY3B8bWNwLXNlcnZlcilbL1xcXFxdZGlzdFsvXFxcXF1pbmRleFxcLmpzLy50ZXN0KGNtZExpbmUpO1xuICAgIGlmICghaXNEb2xsaG91c2VCaW4gJiYgIWlzTWNwU2VydmVyQmluKSB7XG4gICAgICBhd2FpdCBsb2dnZXIud2FybihgW1dlYlVJXSBQb3J0ICR7cG9ydH0gaGVsZCBieSBub24tRG9sbGhvdXNlTUNQIHByb2Nlc3MgKHBpZCAke3BpZH0pIOKAlCBub3Qga2lsbGluZ2AsIHsgY21kTGluZSB9KTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgYXdhaXQgbG9nZ2VyLmRlYnVnKGBbV2ViVUldIFZlcmlmaWVkIHN0YWxlIHByb2Nlc3MgJHtwaWR9IGlzIERvbGxob3VzZU1DUGAsIHsgY21kTGluZSB9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgLy8gQ2hlY2sgMzogSWYgd2UgY2FuJ3QgdmVyaWZ5LCBkb24ndCBraWxsIOKAlCBzYWZlIGRlZmF1bHRcbiAgICBhd2FpdCBsb2dnZXIuZGVidWcoYFtXZWJVSV0gQ2Fubm90IHZlcmlmeSBwcm9jZXNzICR7cGlkfSDigJQgc2tpcHBpbmcga2lsbGAsIHtcbiAgICAgIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgfSk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBwcm9jZXNzLmtpbGwocGlkLCAnU0lHVEVSTScpO1xuICAgIGxvZ2dlci53YXJuKGBbV2ViVUldIFNlbnQgU0lHVEVSTSB0byBzdGFsZSBwcm9jZXNzICR7cGlkfSBvbiBwb3J0ICR7cG9ydH1gLCB7IGNtZExpbmUgfSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBLSUxMX1BPTExfQ09VTlQ7IGkrKykge1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIFNJR1RFUk1fUE9MTF9NUykpO1xuICAgICAgdHJ5IHsgcHJvY2Vzcy5raWxsKHBpZCwgMCk7IH0gY2F0Y2ggeyByZXR1cm4gdHJ1ZTsgfVxuICAgIH1cbiAgICBwcm9jZXNzLmtpbGwocGlkLCAnU0lHS0lMTCcpO1xuICAgIGxvZ2dlci53YXJuKGBbV2ViVUldIFNlbnQgU0lHS0lMTCB0byBzdGFsZSBwcm9jZXNzICR7cGlkfSBvbiBwb3J0ICR7cG9ydH1gKTtcbiAgICBhd2FpdCBuZXcgUHJvbWlzZShyID0+IHNldFRpbWVvdXQociwgU0lHS0lMTF9XQUlUX01TKSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB0cnVlOyAvLyBwcm9jZXNzIGFscmVhZHkgZGVhZFxuICB9XG59XG5cbi8qKlxuICogRGV0ZWN0IGFuZCByZWNvdmVyIGZyb20gYSBzdGFsZSBwcm9jZXNzIHNxdWF0dGluZyBvbiB0aGUgcG9ydC5cbiAqIENvbXBhcmVzIHRoZSBwb3J0IGhvbGRlcidzIFBJRCBhZ2FpbnN0IHRoZSBsZWFkZXIgbG9jayBmaWxlIHRvIGRldGVybWluZVxuICogaWYgaXQncyBhIHNxdWF0dGVyLiBSZXR1cm5zIHRydWUgaWYgdGhlIHNxdWF0dGVyIHdhcyBraWxsZWQuXG4gKlxuICogVGltZW91dHM6IGxzb2YgMXMsIHBzIDFzLCBTSUdURVJNIHdhaXQgM3Mg4oCUIG1heCB+NXMgdG90YWwuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWNvdmVyU3RhbGVQb3J0KHBvcnQ6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBjb25zdCBzdGFsZVBpZCA9IGF3YWl0IGZpbmRQaWRPblBvcnQocG9ydCk7XG4gIGlmICghc3RhbGVQaWQpIHJldHVybiBmYWxzZTtcblxuICAvLyBUT0NUT1UgbWl0aWdhdGlvbjogYSBuZXcgcHJvY2VzcyBtYXkgaGF2ZSBqdXN0IGJvdW5kIHRoZSBwb3J0IGJ1dCBub3QgeWV0XG4gIC8vIHdyaXR0ZW4gaXRzIGxvY2sgZmlsZS4gUmVhZCB0aGUgbG9jaywgcGF1c2UsIHJlLXJlYWQuIElmIHRoZSBzZWNvbmQgcmVhZFxuICAvLyBub3cgbWF0Y2hlcyB0aGUgcG9ydCBob2xkZXIsIGl0J3MgYSBmcmVzaCBsZWFkZXIg4oCUIGRvbid0IGtpbGwuXG4gIGNvbnN0IHsgcmVhZExlYWRlckxvY2sgfSA9IGF3YWl0IGltcG9ydCgnLi9MZWFkZXJFbGVjdGlvbi5qcycpO1xuICBmb3IgKGxldCBjaGVjayA9IDA7IGNoZWNrIDwgMjsgY2hlY2srKykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBsb2NrID0gYXdhaXQgcmVhZExlYWRlckxvY2soKTtcbiAgICAgIGlmIChsb2NrPy5waWQgPT09IHN0YWxlUGlkICYmIGxvY2s/LnBvcnQgPT09IHBvcnQgJiYgbG9jay5waWQgIT09IHByb2Nlc3MucGlkKSB7XG4gICAgICAgIGF3YWl0IGxvZ2dlci53YXJuKGBbV2ViVUldIFBvcnQgJHtwb3J0fSBoZWxkIGJ5IGxlZ2l0aW1hdGUgbGVhZGVyIChwaWQgJHtzdGFsZVBpZH0pIOKAlCBub3Qga2lsbGluZ2ApO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBDYW4ndCByZWFkIGxvY2sgZmlsZSDigJQgY29udGludWUgdG8gbmV4dCBjaGVjayBvciBraWxsXG4gICAgfVxuICAgIGlmIChjaGVjayA9PT0gMCkge1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIExPQ0tfUkVDSEVDS19ERUxBWV9NUykpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGtpbGxlZCA9IGF3YWl0IGtpbGxTdGFsZVByb2Nlc3Moc3RhbGVQaWQsIHBvcnQpO1xuICBpZiAoa2lsbGVkKSB7XG4gICAgbG9nZ2VyLmluZm8oYFtXZWJVSV0gU3RhbGUgcHJvY2VzcyAke3N0YWxlUGlkfSByZW1vdmVkIGZyb20gcG9ydCAke3BvcnR9YCk7XG4gICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIFNJR0tJTExfV0FJVF9NUykpOyAvLyBicmllZiBwYXVzZSBmb3IgcG9ydCByZWxlYXNlXG4gIH1cbiAgcmV0dXJuIGtpbGxlZDtcbn1cbiJdfQ==
|
|
341
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RhbGVQcm9jZXNzUmVjb3ZlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2ViL2NvbnNvbGUvU3RhbGVQcm9jZXNzUmVjb3ZlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7OztHQVNHO0FBRUgsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFFakYsOEVBQThFO0FBQzlFLHFFQUFxRTtBQUNyRSxrREFBa0Q7QUFDbEQsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUM7QUFDaEMsb0VBQW9FO0FBQ3BFLE1BQU0sZUFBZSxHQUFHLEdBQUcsQ0FBQztBQUM1QixtREFBbUQ7QUFDbkQsTUFBTSxlQUFlLEdBQUcsRUFBRSxDQUFDO0FBQzNCLCtDQUErQztBQUMvQyxNQUFNLGVBQWUsR0FBRyxHQUFHLENBQUM7QUFDNUIsOERBQThEO0FBQzlELE1BQU0scUJBQXFCLEdBQUcsR0FBRyxDQUFDO0FBQ2xDLHdGQUF3RjtBQUN4RixNQUFNLHFCQUFxQixHQUFHLENBQUMsQ0FBQztBQUNoQyx5RkFBeUY7QUFDekYsTUFBTSxlQUFlLEdBQUcsQ0FBQyxDQUFDO0FBQzFCLG9GQUFvRjtBQUNwRixNQUFNLDhCQUE4QixHQUFHLENBQUMsQ0FBQztBQUV6QyxJQUFJLE9BQU8sR0FBeUQsSUFBSSxDQUFDO0FBQ3pFLEtBQUssVUFBVSxTQUFTO0lBQ3RCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQztZQUFDLE9BQU8sR0FBRyxDQUFDLE1BQU0sTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFBQyxDQUFDO1FBQ2pFLE1BQU0sQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUM7QUFDRCxNQUFNLE1BQU0sR0FBRztJQUNiLElBQUksRUFBRSxLQUFLLEVBQUUsR0FB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QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTdGFsZSBwcm9jZXNzIGRldGVjdGlvbiBhbmQgcmVjb3ZlcnkgKCMxODUwKS5cbiAqXG4gKiBGaW5kcyBhbmQga2lsbHMgem9tYmllIERvbGxob3VzZU1DUCBwcm9jZXNzZXMgdGhhdCBzcXVhdCBvbiB0aGUgY29uc29sZVxuICogcG9ydCBhZnRlciB0aGVpciBzZXNzaW9uIGhhcyBlbmRlZC4gVXNlZCBieSBiaW5kQW5kTGlzdGVuIGluIHNlcnZlci50c1xuICogd2hlbiBFQUREUklOVVNFIG9jY3Vycy5cbiAqXG4gKiBFeHRyYWN0ZWQgdG8gYSBzdGFuZGFsb25lIG1vZHVsZSBzbyBpdCBjYW4gYmUgdGVzdGVkIHdpdGhvdXQgaW1wb3J0aW5nXG4gKiB0aGUgZnVsbCBFeHByZXNzIHNlcnZlciBhbmQgaXRzIGRlcGVuZGVuY3kgY2hhaW4uXG4gKi9cblxuaW1wb3J0IHsgVW5pY29kZVZhbGlkYXRvciB9IGZyb20gJy4uLy4uL3NlY3VyaXR5L3ZhbGlkYXRvcnMvdW5pY29kZVZhbGlkYXRvci5qcyc7XG5cbi8vIFVzZSBsYXp5IGltcG9ydCBmb3IgbG9nZ2VyIHRvIGF2b2lkIHB1bGxpbmcgaW4gdGhlIGZ1bGwgZW52LnRzL2NvbmZpZyBjaGFpblxuLy8gYXQgbW9kdWxlIGxvYWQgdGltZS4gVGhpcyBrZWVwcyB0aGUgbW9kdWxlIGluZGVwZW5kZW50bHkgdGVzdGFibGUuXG4vKiogVGltZW91dCBmb3IgbHNvZi9mdXNlci9wcyBzeXN0ZW0gY2FsbHMgKG1zKSAqL1xuY29uc3QgQ09NTUFORF9USU1FT1VUX01TID0gMTAwMDtcbi8qKiBQb2xsaW5nIGludGVydmFsIHdoZW4gd2FpdGluZyBmb3IgU0lHVEVSTSB0byB0YWtlIGVmZmVjdCAobXMpICovXG5jb25zdCBTSUdURVJNX1BPTExfTVMgPSAzMDA7XG4vKiogTnVtYmVyIG9mIHBvbGxzIGJlZm9yZSBlc2NhbGF0aW5nIHRvIFNJR0tJTEwgKi9cbmNvbnN0IEtJTExfUE9MTF9DT1VOVCA9IDEwO1xuLyoqIFdhaXQgYWZ0ZXIgU0lHS0lMTCBiZWZvcmUgcmV0dXJuaW5nIChtcykgKi9cbmNvbnN0IFNJR0tJTExfV0FJVF9NUyA9IDUwMDtcbi8qKiBXYWl0IGJldHdlZW4gbG9jayBmaWxlIHJlYWRzIGZvciBUT0NUT1UgbWl0aWdhdGlvbiAobXMpICovXG5jb25zdCBMT0NLX1JFQ0hFQ0tfREVMQVlfTVMgPSA1MDA7XG4vKiogTnVtYmVyIG9mIGxvY2stZmlsZSBjaGVja3MgYmVmb3JlIGRlY2lkaW5nIHRoZSBwb3J0IGhvbGRlciBpcyBub3QgYSBmcmVzaCBsZWFkZXIuICovXG5jb25zdCBMT0NLX1JFQ0hFQ0tfQVRURU1QVFMgPSAyO1xuLyoqIFBJRCB1c2VkIGJ5IHRoZSBPUyBpbml0L2xhdW5jaGQgcHJvY2VzczsgZGlyZWN0IGNoaWxkcmVuIGFyZSBlZmZlY3RpdmVseSBvcnBoYW5lZC4gKi9cbmNvbnN0IFJPT1RfUEFSRU5UX1BJRCA9IDE7XG4vKiogTnVtYmVyIG9mIGBwc2AgY29sdW1ucyByZXF1ZXN0ZWQgYnkgaW5zcGVjdFByb2Nlc3M6IHVzZXIsIHBpZCwgcHBpZCwgY29tbWFuZC4gKi9cbmNvbnN0IFBST0NFU1NfSU5TUEVDVElPTl9GSUVMRF9DT1VOVCA9IDQ7XG5cbmxldCBfbG9nZ2VyOiB0eXBlb2YgaW1wb3J0KCcuLi8uLi91dGlscy9sb2dnZXIuanMnKS5sb2dnZXIgfCBudWxsID0gbnVsbDtcbmFzeW5jIGZ1bmN0aW9uIGdldExvZ2dlcigpIHtcbiAgaWYgKCFfbG9nZ2VyKSB7XG4gICAgdHJ5IHsgX2xvZ2dlciA9IChhd2FpdCBpbXBvcnQoJy4uLy4uL3V0aWxzL2xvZ2dlci5qcycpKS5sb2dnZXI7IH1cbiAgICBjYXRjaCB7IC8qIGZhbGxiYWNrIGJlbG93ICovIH1cbiAgfVxuICByZXR1cm4gX2xvZ2dlcjtcbn1cbmNvbnN0IGxvZ2dlciA9IHtcbiAgd2FybjogYXN5bmMgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICAgIGNvbnN0IGwgPSBhd2FpdCBnZXRMb2dnZXIoKTtcbiAgICBpZiAobCkgbC53YXJuKGFyZ3NbMF0gYXMgc3RyaW5nLCBhcmdzWzFdKTtcbiAgICBlbHNlIGNvbnNvbGUuZXJyb3IoJ1tXQVJOXScsIC4uLmFyZ3MpO1xuICB9LFxuICBpbmZvOiBhc3luYyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgY29uc3QgbCA9IGF3YWl0IGdldExvZ2dlcigpO1xuICAgIGlmIChsKSBsLmluZm8oYXJnc1swXSBhcyBzdHJpbmcsIGFyZ3NbMV0pO1xuICAgIGVsc2UgY29uc29sZS5lcnJvcignW0lORk9dJywgLi4uYXJncyk7XG4gIH0sXG4gIGRlYnVnOiBhc3luYyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgY29uc3QgbCA9IGF3YWl0IGdldExvZ2dlcigpO1xuICAgIGlmIChsKSBsLmRlYnVnKGFyZ3NbMF0gYXMgc3RyaW5nLCBhcmdzWzFdKTtcbiAgfSxcbn07XG5cbmNvbnN0IE1DUF9IT1NUX1BBUkVOVF9QQVRURVJOUyA9IFtcbiAgL0NsYXVkZVxcLmFwcFxcL0NvbnRlbnRzXFwvSGVscGVyc1xcL2Rpc2NsYWltZXIvaSxcbiAgL0NvZGV4XFwuYXBwXFwvQ29udGVudHNcXC9SZXNvdXJjZXNcXC9jb2RleCBhcHAtc2VydmVyL2ksXG4gIC9DdXJzb3JcXC5hcHBcXC8vaSxcbiAgL1dpbmRzdXJmXFwuYXBwXFwvL2ksXG5dO1xuXG5pbnRlcmZhY2UgUHJvY2Vzc0luc3BlY3Rpb24ge1xuICB1c2VyOiBzdHJpbmc7XG4gIHBpZDogbnVtYmVyO1xuICBwYXJlbnRQaWQ6IG51bWJlcjtcbiAgY29tbWFuZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEtpbGxTdGFsZVByb2Nlc3NPdXRjb21lIHtcbiAga2lsbGVkOiBib29sZWFuO1xuICByZWFzb246XG4gICAgfCAnaW5zcGVjdF9mYWlsZWQnXG4gICAgfCAnZGlmZmVyZW50X3VzZXInXG4gICAgfCAnbm90X2RvbGxob3VzZV9wcm9jZXNzJ1xuICAgIHwgJ2FjdGl2ZV9ob3N0X3BhcmVudCdcbiAgICB8ICd0ZXJtaW5hdGVkJ1xuICAgIHwgJ2FscmVhZHlfZGVhZCdcbiAgICB8ICdzdGlsbF9hbGl2ZSdcbiAgICB8ICdzaWduYWxfZmFpbGVkJztcbiAgcGlkOiBudW1iZXI7XG4gIHBhcmVudFBpZD86IG51bWJlcjtcbiAgY29tbWFuZD86IHN0cmluZztcbiAgcGFyZW50Q29tbWFuZD86IHN0cmluZztcbiAgZGV0YWlsPzogc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSZWNvZ25pemVkTWNwSG9zdFBhcmVudChjb21tYW5kOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3Qgbm9ybWFsaXplZENvbW1hbmQgPSBVbmljb2RlVmFsaWRhdG9yLm5vcm1hbGl6ZShjb21tYW5kKS5ub3JtYWxpemVkQ29udGVudDtcbiAgcmV0dXJuIE1DUF9IT1NUX1BBUkVOVF9QQVRURVJOUy5zb21lKChwYXR0ZXJuKSA9PiBwYXR0ZXJuLnRlc3Qobm9ybWFsaXplZENvbW1hbmQpKTtcbn1cblxuZnVuY3Rpb24gaXNEb2xsaG91c2VQcm9jZXNzQ29tbWFuZChjbWRMaW5lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3Qgbm9ybWFsaXplZENvbW1hbmQgPSBVbmljb2RlVmFsaWRhdG9yLm5vcm1hbGl6ZShjbWRMaW5lKS5ub3JtYWxpemVkQ29udGVudDtcbiAgY29uc3QgaXNEb2xsaG91c2VCaW4gPSAvKD86XnxcXC8pZG9sbGhvdXNlbWNwKD86XFxzfCQpLy50ZXN0KG5vcm1hbGl6ZWRDb21tYW5kKSB8fFxuICAgIG5vcm1hbGl6ZWRDb21tYW5kLmluY2x1ZGVzKCcuYmluL2RvbGxob3VzZW1jcCcpO1xuICBjb25zdCBpc01jcFNlcnZlckJpbiA9IG5vcm1hbGl6ZWRDb21tYW5kLmluY2x1ZGVzKCcuYmluL21jcC1zZXJ2ZXInKSB8fFxuICAgIC8oPzpkb2xsaG91c2VtY3B8bWNwLXNlcnZlcilbL1xcXFxdZGlzdFsvXFxcXF1pbmRleFxcLmpzLy50ZXN0KG5vcm1hbGl6ZWRDb21tYW5kKTtcbiAgcmV0dXJuIGlzRG9sbGhvdXNlQmluIHx8IGlzTWNwU2VydmVyQmluO1xufVxuXG5mdW5jdGlvbiBwYXJzZVBpZFRva2VuKHZhbHVlOiBzdHJpbmcpOiBudW1iZXIgfCBudWxsIHtcbiAgaWYgKCF2YWx1ZSkgcmV0dXJuIG51bGw7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjb2RlUG9pbnQgPSB2YWx1ZS5jb2RlUG9pbnRBdChpKTtcbiAgICBpZiAoY29kZVBvaW50ID09PSB1bmRlZmluZWQgfHwgY29kZVBvaW50IDwgNDggfHwgY29kZVBvaW50ID4gNTcpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHBhcnNlZCA9IE51bWJlci5wYXJzZUludCh2YWx1ZSwgMTApO1xuICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKHBhcnNlZCkgfHwgcGFyc2VkIDwgUk9PVF9QQVJFTlRfUElEKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuZnVuY3Rpb24gaXNXaGl0ZXNwYWNlQ2hhcih2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiB2YWx1ZSA9PT0gJyAnIHx8IHZhbHVlID09PSAnXFx0JyB8fCB2YWx1ZSA9PT0gJ1xcbicgfHwgdmFsdWUgPT09ICdcXHInIHx8IHZhbHVlID09PSAnXFxmJyB8fCB2YWx1ZSA9PT0gJ1xcdic7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkS2lsbE91dGNvbWUoXG4gIGtpbGxlZDogYm9vbGVhbixcbiAgcmVhc29uOiBLaWxsU3RhbGVQcm9jZXNzT3V0Y29tZVsncmVhc29uJ10sXG4gIHByb2Nlc3NJbmZvOiBQcm9jZXNzSW5zcGVjdGlvbixcbiAgcGFyZW50Q29tbWFuZD86IHN0cmluZyxcbiAgZGV0YWlsPzogc3RyaW5nLFxuKTogS2lsbFN0YWxlUHJvY2Vzc091dGNvbWUge1xuICByZXR1cm4ge1xuICAgIGtpbGxlZCxcbiAgICByZWFzb24sXG4gICAgcGlkOiBwcm9jZXNzSW5mby5waWQsXG4gICAgcGFyZW50UGlkOiBwcm9jZXNzSW5mby5wYXJlbnRQaWQsXG4gICAgY29tbWFuZDogcHJvY2Vzc0luZm8uY29tbWFuZCxcbiAgICBwYXJlbnRDb21tYW5kLFxuICAgIC4uLihkZXRhaWwgPyB7IGRldGFpbCB9IDoge30pLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRLaWxsR3VhcmRGYWlsdXJlKFxuICBwcm9jZXNzSW5mbzogUHJvY2Vzc0luc3BlY3Rpb24sXG4gIHBvcnQ6IG51bWJlcixcbik6IFByb21pc2U8S2lsbFN0YWxlUHJvY2Vzc091dGNvbWUgfCBudWxsPiB7XG4gIGNvbnN0IGN1cnJlbnRVc2VyID0gKGF3YWl0IGltcG9ydCgnbm9kZTpvcycpKS51c2VySW5mbygpLnVzZXJuYW1lO1xuICBpZiAocHJvY2Vzc0luZm8udXNlciAhPT0gY3VycmVudFVzZXIpIHtcbiAgICBhd2FpdCBsb2dnZXIud2FybihgW1dlYlVJXSBQb3J0ICR7cG9ydH0gaGVsZCBieSBkaWZmZXJlbnQgdXNlciAocGlkICR7cHJvY2Vzc0luZm8ucGlkfSkg4oCUIG5vdCBraWxsaW5nYCk7XG4gICAgcmV0dXJuIGJ1aWxkS2lsbE91dGNvbWUoZmFsc2UsICdkaWZmZXJlbnRfdXNlcicsIHByb2Nlc3NJbmZvKTtcbiAgfVxuXG4gIGlmICghaXNEb2xsaG91c2VQcm9jZXNzQ29tbWFuZChwcm9jZXNzSW5mby5jb21tYW5kKSkge1xuICAgIGF3YWl0IGxvZ2dlci53YXJuKGBbV2ViVUldIFBvcnQgJHtwb3J0fSBoZWxkIGJ5IG5vbi1Eb2xsaG91c2VNQ1AgcHJvY2VzcyAocGlkICR7cHJvY2Vzc0luZm8ucGlkfSkg4oCUIG5vdCBraWxsaW5nYCwge1xuICAgICAgY21kTGluZTogcHJvY2Vzc0luZm8uY29tbWFuZCxcbiAgICB9KTtcbiAgICByZXR1cm4gYnVpbGRLaWxsT3V0Y29tZShmYWxzZSwgJ25vdF9kb2xsaG91c2VfcHJvY2VzcycsIHByb2Nlc3NJbmZvKTtcbiAgfVxuXG4gIGlmIChwcm9jZXNzSW5mby5wYXJlbnRQaWQgPD0gUk9PVF9QQVJFTlRfUElEIHx8ICFpc1BpZEFsaXZlKHByb2Nlc3NJbmZvLnBhcmVudFBpZCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHBhcmVudENvbW1hbmQgPSAoYXdhaXQgZ2V0UHJvY2Vzc0NvbW1hbmQocHJvY2Vzc0luZm8ucGFyZW50UGlkKSkgPz8gdW5kZWZpbmVkO1xuICBpZiAocGFyZW50Q29tbWFuZCAmJiBpc1JlY29nbml6ZWRNY3BIb3N0UGFyZW50KHBhcmVudENvbW1hbmQpKSB7XG4gICAgYXdhaXQgbG9nZ2VyLndhcm4oYFtXZWJVSV0gUG9ydCAke3BvcnR9IGhlbGQgYnkgYWN0aXZlIGNsaWVudC1iYWNrZWQgRG9sbGhvdXNlTUNQIHByb2Nlc3MgKHBpZCAke3Byb2Nlc3NJbmZvLnBpZH0pIOKAlCBub3Qga2lsbGluZ2AsIHtcbiAgICAgIGNtZExpbmU6IHByb2Nlc3NJbmZvLmNvbW1hbmQsXG4gICAgICBwYXJlbnRQaWQ6IHByb2Nlc3NJbmZvLnBhcmVudFBpZCxcbiAgICAgIHBhcmVudENvbW1hbmQsXG4gICAgfSk7XG4gICAgcmV0dXJuIGJ1aWxkS2lsbE91dGNvbWUoZmFsc2UsICdhY3RpdmVfaG9zdF9wYXJlbnQnLCBwcm9jZXNzSW5mbywgcGFyZW50Q29tbWFuZCk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdGVybWluYXRlUHJvY2VzcyhcbiAgcHJvY2Vzc0luZm86IFByb2Nlc3NJbnNwZWN0aW9uLFxuICBwb3J0OiBudW1iZXIsXG4gIHBhcmVudENvbW1hbmQ/OiBzdHJpbmcsXG4pOiBQcm9taXNlPEtpbGxTdGFsZVByb2Nlc3NPdXRjb21lPiB7XG4gIHByb2Nlc3Mua2lsbChwcm9jZXNzSW5mby5waWQsICdTSUdURVJNJyk7XG4gIGxvZ2dlci53YXJuKGBbV2ViVUldIFNlbnQgU0lHVEVSTSB0byBzdGFsZSBwcm9jZXNzICR7cHJvY2Vzc0luZm8ucGlkfSBvbiBwb3J0ICR7cG9ydH1gLCB7XG4gICAgY21kTGluZTogcHJvY2Vzc0luZm8uY29tbWFuZCxcbiAgICBwYXJlbnRQaWQ6IHByb2Nlc3NJbmZvLnBhcmVudFBpZCxcbiAgICBwYXJlbnRDb21tYW5kLFxuICB9KTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IEtJTExfUE9MTF9DT1VOVDsgaSsrKSB7XG4gICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIFNJR1RFUk1fUE9MTF9NUykpO1xuICAgIGlmICghaXNQaWRBbGl2ZShwcm9jZXNzSW5mby5waWQpKSB7XG4gICAgICByZXR1cm4gYnVpbGRLaWxsT3V0Y29tZSh0cnVlLCAndGVybWluYXRlZCcsIHByb2Nlc3NJbmZvLCBwYXJlbnRDb21tYW5kKTtcbiAgICB9XG4gIH1cblxuICBwcm9jZXNzLmtpbGwocHJvY2Vzc0luZm8ucGlkLCAnU0lHS0lMTCcpO1xuICBsb2dnZXIud2FybihgW1dlYlVJXSBTZW50IFNJR0tJTEwgdG8gc3RhbGUgcHJvY2VzcyAke3Byb2Nlc3NJbmZvLnBpZH0gb24gcG9ydCAke3BvcnR9YCk7XG4gIGF3YWl0IG5ldyBQcm9taXNlKHIgPT4gc2V0VGltZW91dChyLCBTSUdLSUxMX1dBSVRfTVMpKTtcbiAgcmV0dXJuIGlzUGlkQWxpdmUocHJvY2Vzc0luZm8ucGlkKVxuICAgID8gYnVpbGRLaWxsT3V0Y29tZShmYWxzZSwgJ3N0aWxsX2FsaXZlJywgcHJvY2Vzc0luZm8sIHBhcmVudENvbW1hbmQpXG4gICAgOiBidWlsZEtpbGxPdXRjb21lKHRydWUsICd0ZXJtaW5hdGVkJywgcHJvY2Vzc0luZm8sIHBhcmVudENvbW1hbmQpO1xufVxuXG5mdW5jdGlvbiBzcGxpdFByb2Nlc3NJbnNwZWN0aW9uRmllbGRzKGxpbmU6IHN0cmluZyk6IHN0cmluZ1tdIHwgbnVsbCB7XG4gIGNvbnN0IGZpZWxkczogc3RyaW5nW10gPSBbXTtcbiAgbGV0IGluZGV4ID0gMDtcbiAgY29uc3Qgbm9ybWFsaXplZExpbmUgPSBVbmljb2RlVmFsaWRhdG9yLm5vcm1hbGl6ZShsaW5lKS5ub3JtYWxpemVkQ29udGVudC50cmltKCk7XG5cbiAgd2hpbGUgKGluZGV4IDwgbm9ybWFsaXplZExpbmUubGVuZ3RoICYmIGZpZWxkcy5sZW5ndGggPCBQUk9DRVNTX0lOU1BFQ1RJT05fRklFTERfQ09VTlQgLSAxKSB7XG4gICAgd2hpbGUgKGluZGV4IDwgbm9ybWFsaXplZExpbmUubGVuZ3RoICYmIGlzV2hpdGVzcGFjZUNoYXIobm9ybWFsaXplZExpbmVbaW5kZXhdKSkge1xuICAgICAgaW5kZXgrKztcbiAgICB9XG4gICAgaWYgKGluZGV4ID49IG5vcm1hbGl6ZWRMaW5lLmxlbmd0aCkgYnJlYWs7XG5cbiAgICBjb25zdCBmaWVsZFN0YXJ0ID0gaW5kZXg7XG4gICAgd2hpbGUgKGluZGV4IDwgbm9ybWFsaXplZExpbmUubGVuZ3RoICYmICFpc1doaXRlc3BhY2VDaGFyKG5vcm1hbGl6ZWRMaW5lW2luZGV4XSkpIHtcbiAgICAgIGluZGV4Kys7XG4gICAgfVxuICAgIGZpZWxkcy5wdXNoKG5vcm1hbGl6ZWRMaW5lLnNsaWNlKGZpZWxkU3RhcnQsIGluZGV4KSk7XG4gIH1cblxuICB3aGlsZSAoaW5kZXggPCBub3JtYWxpemVkTGluZS5sZW5ndGggJiYgaXNXaGl0ZXNwYWNlQ2hhcihub3JtYWxpemVkTGluZVtpbmRleF0pKSB7XG4gICAgaW5kZXgrKztcbiAgfVxuICBpZiAoaW5kZXggPCBub3JtYWxpemVkTGluZS5sZW5ndGgpIHtcbiAgICBmaWVsZHMucHVzaChub3JtYWxpemVkTGluZS5zbGljZShpbmRleCkpO1xuICB9XG5cbiAgcmV0dXJuIGZpZWxkcy5sZW5ndGggPT09IFBST0NFU1NfSU5TUEVDVElPTl9GSUVMRF9DT1VOVCA/IGZpZWxkcyA6IG51bGw7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGluc3BlY3RQcm9jZXNzKHBpZDogbnVtYmVyKTogUHJvbWlzZTxQcm9jZXNzSW5zcGVjdGlvbiB8IG51bGw+IHtcbiAgY29uc3QgeyBleGVjRmlsZTogZXhlY0ZpbGVDYiB9ID0gYXdhaXQgaW1wb3J0KCdub2RlOmNoaWxkX3Byb2Nlc3MnKTtcbiAgY29uc3QgeyBwcm9taXNpZnkgfSA9IGF3YWl0IGltcG9ydCgnbm9kZTp1dGlsJyk7XG4gIGNvbnN0IGV4ZWNGaWxlQXN5bmMgPSBwcm9taXNpZnkoZXhlY0ZpbGVDYik7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB7IHN0ZG91dCB9ID0gYXdhaXQgZXhlY0ZpbGVBc3luYyhcbiAgICAgICdwcycsXG4gICAgICBbJy1wJywgU3RyaW5nKHBpZCksICctbycsICd1c2VyPSxwaWQ9LHBwaWQ9LGNvbW1hbmQ9J10sXG4gICAgICB7IHRpbWVvdXQ6IENPTU1BTkRfVElNRU9VVF9NUyB9LFxuICAgICk7XG4gICAgY29uc3QgZmllbGRzID0gc3BsaXRQcm9jZXNzSW5zcGVjdGlvbkZpZWxkcyhzdGRvdXQpO1xuICAgIGlmICghZmllbGRzKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBbdXNlciwgcGlkVG9rZW4sIHBhcmVudFBpZFRva2VuLCBjb21tYW5kXSA9IGZpZWxkcztcbiAgICBjb25zdCBwYXJzZWRQaWQgPSBwYXJzZVBpZFRva2VuKHBpZFRva2VuKTtcbiAgICBjb25zdCBwYXJzZWRQYXJlbnRQaWQgPSBwYXJzZVBpZFRva2VuKHBhcmVudFBpZFRva2VuKTtcbiAgICBpZiAocGFyc2VkUGlkID09PSBudWxsIHx8IHBhcnNlZFBhcmVudFBpZCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdXNlcjogVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUodXNlcikubm9ybWFsaXplZENvbnRlbnQsXG4gICAgICBwaWQ6IHBhcnNlZFBpZCxcbiAgICAgIHBhcmVudFBpZDogcGFyc2VkUGFyZW50UGlkLFxuICAgICAgY29tbWFuZDogVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUoY29tbWFuZCkubm9ybWFsaXplZENvbnRlbnQsXG4gICAgfTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0UHJvY2Vzc0NvbW1hbmQocGlkOiBudW1iZXIpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgY29uc3QgeyBleGVjRmlsZTogZXhlY0ZpbGVDYiB9ID0gYXdhaXQgaW1wb3J0KCdub2RlOmNoaWxkX3Byb2Nlc3MnKTtcbiAgY29uc3QgeyBwcm9taXNpZnkgfSA9IGF3YWl0IGltcG9ydCgnbm9kZTp1dGlsJyk7XG4gIGNvbnN0IGV4ZWNGaWxlQXN5bmMgPSBwcm9taXNpZnkoZXhlY0ZpbGVDYik7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB7IHN0ZG91dCB9ID0gYXdhaXQgZXhlY0ZpbGVBc3luYygncHMnLCBbJy1wJywgU3RyaW5nKHBpZCksICctbycsICdjb21tYW5kPSddLCB7IHRpbWVvdXQ6IENPTU1BTkRfVElNRU9VVF9NUyB9KTtcbiAgICBjb25zdCBub3JtYWxpemVkID0gVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUoc3Rkb3V0KS5ub3JtYWxpemVkQ29udGVudC50cmltKCk7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZWQgfHwgbnVsbDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNQaWRBbGl2ZShwaWQ6IG51bWJlcik6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIHByb2Nlc3Mua2lsbChwaWQsIDApO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBGaW5kIHRoZSBQSUQgb2YgdGhlIHByb2Nlc3MgbGlzdGVuaW5nIG9uIGEgZ2l2ZW4gcG9ydC5cbiAqIFVzZXMgbHNvZiBvbiBtYWNPUy9MaW51eC4gUmV0dXJucyBudWxsIGlmIG5vdCBmb3VuZCBvciBvbiBlcnJvci5cbiAqXG4gKiBUaW1lb3V0OiAxcyDigJQgbHNvZiBvbiBsb2NhbGhvc3QgaXMgdHlwaWNhbGx5IDwxMDBtcy4gVGhlIDFzIGNlaWxpbmdcbiAqIGhhbmRsZXMgc2xvdyBORlMtbW91bnRlZCAvZGV2L2ZkIG9yIG92ZXJsb2FkZWQgQ0kgcnVubmVycyB3aXRob3V0XG4gKiBkZWxheWluZyBzdGFydHVwIG5vdGljZWFibHkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmaW5kUGlkT25Qb3J0KHBvcnQ6IG51bWJlcik6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICBjb25zdCB7IGV4ZWNGaWxlOiBleGVjRmlsZUNiIH0gPSBhd2FpdCBpbXBvcnQoJ25vZGU6Y2hpbGRfcHJvY2VzcycpO1xuICBjb25zdCB7IHByb21pc2lmeSB9ID0gYXdhaXQgaW1wb3J0KCdub2RlOnV0aWwnKTtcbiAgY29uc3QgZXhlY0ZpbGVBc3luYyA9IHByb21pc2lmeShleGVjRmlsZUNiKTtcblxuICAvLyBUcnkgbHNvZiBmaXJzdCAobWFjT1MgKyBtb3N0IExpbnV4KSwgZmFsbCBiYWNrIHRvIGZ1c2VyIChtaW5pbWFsIExpbnV4L0RvY2tlcilcbiAgZm9yIChjb25zdCBjbWQgb2YgW1xuICAgIHsgYmluOiAnbHNvZicsIGFyZ3M6IFsnLXRpJywgYDoke3BvcnR9YF0gfSxcbiAgICB7IGJpbjogJ2Z1c2VyJywgYXJnczogW2Ake3BvcnR9L3RjcGBdIH0sXG4gIF0pIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBzdGRvdXQsIHN0ZGVyciB9ID0gYXdhaXQgZXhlY0ZpbGVBc3luYyhjbWQuYmluLCBjbWQuYXJncywgeyB0aW1lb3V0OiBDT01NQU5EX1RJTUVPVVRfTVMgfSk7XG4gICAgICAvLyBmdXNlciBvdXRwdXRzIHRvIHN0ZGVyciBvbiBzb21lIHN5c3RlbXNcbiAgICAgIGNvbnN0IG91dHB1dCA9IChzdGRvdXQgfHwgc3RkZXJyIHx8ICcnKS50cmltKCk7XG4gICAgICBjb25zdCBwaWRzID0gb3V0cHV0XG4gICAgICAgIC5zcGxpdCgvXFxzKy8pXG4gICAgICAgIC5tYXAoKHRva2VuKSA9PiBwYXJzZVBpZFRva2VuKHRva2VuKSlcbiAgICAgICAgLmZpbHRlcigocGlkKTogcGlkIGlzIG51bWJlciA9PiBwaWQgIT09IG51bGwpO1xuICAgICAgY29uc3Qgb3RoZXJQaWQgPSBwaWRzLmZpbmQocCA9PiBwICE9PSBwcm9jZXNzLnBpZCk7XG4gICAgICBpZiAob3RoZXJQaWQpIHJldHVybiBvdGhlclBpZDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBjb21tYW5kIG5vdCBmb3VuZCBvciBubyByZXN1bHRzIOKAlCB0cnkgbmV4dFxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBLaWxsIGEgc3RhbGUgcHJvY2VzcyBob2xkaW5nIGEgcG9ydC4gU2VuZHMgU0lHVEVSTSwgd2FpdHMgYnJpZWZseSxcbiAqIHRoZW4gU0lHS0lMTCBpZiBzdGlsbCBhbGl2ZS4gT25seSBraWxscyBEb2xsaG91c2VNQ1AgcHJvY2Vzc2VzXG4gKiAodmVyaWZpZWQgYnkgY2hlY2tpbmcgdGhlIGNvbW1hbmQgbGluZSBhbmQgdXNlciBvd25lcnNoaXApLlxuICpcbiAqIFRpbWVvdXQ6IDFzIGZvciBwcyB2ZXJpZmljYXRpb24uIEtpbGwgd2FpdDogMzAwbXMgw5cgMTAgcG9sbHMgPSAzc1xuICogYmVmb3JlIGVzY2FsYXRpbmcgdG8gU0lHS0lMTC4gVG90YWwgd29yc3QgY2FzZTogfjRzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24ga2lsbFN0YWxlUHJvY2VzcyhwaWQ6IG51bWJlciwgcG9ydDogbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IG91dGNvbWUgPSBhd2FpdCBraWxsU3RhbGVQcm9jZXNzRGV0YWlsZWQocGlkLCBwb3J0KTtcbiAgcmV0dXJuIG91dGNvbWUua2lsbGVkO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24ga2lsbFN0YWxlUHJvY2Vzc0RldGFpbGVkKHBpZDogbnVtYmVyLCBwb3J0OiBudW1iZXIpOiBQcm9taXNlPEtpbGxTdGFsZVByb2Nlc3NPdXRjb21lPiB7XG4gIGNvbnN0IHByb2Nlc3NJbmZvID0gYXdhaXQgaW5zcGVjdFByb2Nlc3MocGlkKTtcbiAgaWYgKCFwcm9jZXNzSW5mbykge1xuICAgIGF3YWl0IGxvZ2dlci5kZWJ1ZyhgW1dlYlVJXSBDYW5ub3QgdmVyaWZ5IHByb2Nlc3MgJHtwaWR9IOKAlCBza2lwcGluZyBraWxsYCk7XG4gICAgcmV0dXJuIHsga2lsbGVkOiBmYWxzZSwgcmVhc29uOiAnaW5zcGVjdF9mYWlsZWQnLCBwaWQgfTtcbiAgfVxuXG4gIGNvbnN0IGd1YXJkRmFpbHVyZSA9IGF3YWl0IGdldEtpbGxHdWFyZEZhaWx1cmUocHJvY2Vzc0luZm8sIHBvcnQpO1xuICBpZiAoZ3VhcmRGYWlsdXJlKSB7XG4gICAgcmV0dXJuIGd1YXJkRmFpbHVyZTtcbiAgfVxuICBjb25zdCBwYXJlbnRDb21tYW5kID0gcHJvY2Vzc0luZm8ucGFyZW50UGlkID4gUk9PVF9QQVJFTlRfUElEXG4gICAgPyAoYXdhaXQgZ2V0UHJvY2Vzc0NvbW1hbmQocHJvY2Vzc0luZm8ucGFyZW50UGlkKSkgPz8gdW5kZWZpbmVkXG4gICAgOiB1bmRlZmluZWQ7XG5cbiAgYXdhaXQgbG9nZ2VyLmRlYnVnKGBbV2ViVUldIFZlcmlmaWVkIHN0YWxlIHByb2Nlc3MgJHtwaWR9IGlzIERvbGxob3VzZU1DUGAsIHsgY21kTGluZTogcHJvY2Vzc0luZm8uY29tbWFuZCwgcGFyZW50UGlkOiBwcm9jZXNzSW5mby5wYXJlbnRQaWQsIHBhcmVudENvbW1hbmQgfSk7XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgdGVybWluYXRlUHJvY2Vzcyhwcm9jZXNzSW5mbywgcG9ydCwgcGFyZW50Q29tbWFuZCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGlmICghaXNQaWRBbGl2ZShwaWQpKSB7XG4gICAgICByZXR1cm4gYnVpbGRLaWxsT3V0Y29tZSh0cnVlLCAnYWxyZWFkeV9kZWFkJywgcHJvY2Vzc0luZm8sIHBhcmVudENvbW1hbmQpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRLaWxsT3V0Y29tZShmYWxzZSwgJ3NpZ25hbF9mYWlsZWQnLCBwcm9jZXNzSW5mbywgcGFyZW50Q29tbWFuZCwgZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpKTtcbiAgfVxufVxuXG4vKipcbiAqIERldGVjdCBhbmQgcmVjb3ZlciBmcm9tIGEgc3RhbGUgcHJvY2VzcyBzcXVhdHRpbmcgb24gdGhlIHBvcnQuXG4gKiBDb21wYXJlcyB0aGUgcG9ydCBob2xkZXIncyBQSUQgYWdhaW5zdCB0aGUgbGVhZGVyIGxvY2sgZmlsZSB0byBkZXRlcm1pbmVcbiAqIGlmIGl0J3MgYSBzcXVhdHRlci4gUmV0dXJucyB0cnVlIGlmIHRoZSBzcXVhdHRlciB3YXMga2lsbGVkLlxuICpcbiAqIFRpbWVvdXRzOiBsc29mIDFzLCBwcyAxcywgU0lHVEVSTSB3YWl0IDNzIOKAlCBtYXggfjVzIHRvdGFsLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVjb3ZlclN0YWxlUG9ydChwb3J0OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3Qgc3RhbGVQaWQgPSBhd2FpdCBmaW5kUGlkT25Qb3J0KHBvcnQpO1xuICBpZiAoIXN0YWxlUGlkKSByZXR1cm4gZmFsc2U7XG5cbiAgLy8gVE9DVE9VIG1pdGlnYXRpb246IGEgbmV3IHByb2Nlc3MgbWF5IGhhdmUganVzdCBib3VuZCB0aGUgcG9ydCBidXQgbm90IHlldFxuICAvLyB3cml0dGVuIGl0cyBsb2NrIGZpbGUuIFJlYWQgdGhlIGxvY2ssIHBhdXNlLCByZS1yZWFkLiBJZiB0aGUgc2Vjb25kIHJlYWRcbiAgLy8gbm93IG1hdGNoZXMgdGhlIHBvcnQgaG9sZGVyLCBpdCdzIGEgZnJlc2ggbGVhZGVyIOKAlCBkb24ndCBraWxsLlxuICBjb25zdCB7IHJlYWRMZWFkZXJMb2NrIH0gPSBhd2FpdCBpbXBvcnQoJy4vTGVhZGVyRWxlY3Rpb24uanMnKTtcbiAgZm9yIChsZXQgY2hlY2sgPSAwOyBjaGVjayA8IExPQ0tfUkVDSEVDS19BVFRFTVBUUzsgY2hlY2srKykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBsb2NrID0gYXdhaXQgcmVhZExlYWRlckxvY2soKTtcbiAgICAgIGlmIChsb2NrPy5waWQgPT09IHN0YWxlUGlkICYmIGxvY2s/LnBvcnQgPT09IHBvcnQgJiYgbG9jay5waWQgIT09IHByb2Nlc3MucGlkKSB7XG4gICAgICAgIGF3YWl0IGxvZ2dlci53YXJuKGBbV2ViVUldIFBvcnQgJHtwb3J0fSBoZWxkIGJ5IGxlZ2l0aW1hdGUgbGVhZGVyIChwaWQgJHtzdGFsZVBpZH0pIOKAlCBub3Qga2lsbGluZ2ApO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBDYW4ndCByZWFkIGxvY2sgZmlsZSDigJQgY29udGludWUgdG8gbmV4dCBjaGVjayBvciBraWxsXG4gICAgfVxuICAgIGlmIChjaGVjayA8IExPQ0tfUkVDSEVDS19BVFRFTVBUUyAtIDEpIHtcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHIgPT4gc2V0VGltZW91dChyLCBMT0NLX1JFQ0hFQ0tfREVMQVlfTVMpKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBvdXRjb21lID0gYXdhaXQga2lsbFN0YWxlUHJvY2Vzc0RldGFpbGVkKHN0YWxlUGlkLCBwb3J0KTtcbiAgaWYgKG91dGNvbWUua2lsbGVkKSB7XG4gICAgbG9nZ2VyLmluZm8oYFtXZWJVSV0gU3RhbGUgcHJvY2VzcyAke3N0YWxlUGlkfSByZW1vdmVkIGZyb20gcG9ydCAke3BvcnR9YCk7XG4gICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIFNJR0tJTExfV0FJVF9NUykpOyAvLyBicmllZiBwYXVzZSBmb3IgcG9ydCByZWxlYXNlXG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgbG9nZ2VyLmRlYnVnKGBbV2ViVUldIFN0YWxlLXBvcnQgcmVjb3Zlcnkgc2tpcHBlZCBmb3IgcGlkICR7c3RhbGVQaWR9YCwge1xuICAgICAgcmVhc29uOiBvdXRjb21lLnJlYXNvbixcbiAgICAgIHBhcmVudFBpZDogb3V0Y29tZS5wYXJlbnRQaWQsXG4gICAgICBwYXJlbnRDb21tYW5kOiBvdXRjb21lLnBhcmVudENvbW1hbmQsXG4gICAgICBkZXRhaWw6IG91dGNvbWUuZGV0YWlsLFxuICAgIH0pO1xuICB9XG4gIHJldHVybiBvdXRjb21lLmtpbGxlZDtcbn1cbiJdfQ==
|
|
@@ -17,7 +17,8 @@ import type { MetricSnapshot } from '../../metrics/types.js';
|
|
|
17
17
|
import type { MemoryLogSink } from '../../logging/sinks/MemoryLogSink.js';
|
|
18
18
|
import type { MemoryMetricsSink } from '../../metrics/sinks/MemoryMetricsSink.js';
|
|
19
19
|
import { logger } from '../../utils/logger.js';
|
|
20
|
-
import { detectLegacyLeader, type ElectionResult } from './LeaderElection.js';
|
|
20
|
+
import { detectLegacyLeader, readLeaderLock, deleteLeaderLock, type ElectionResult, type ConsoleLeaderInfo } from './LeaderElection.js';
|
|
21
|
+
import { findPidOnPort } from './StaleProcessRecovery.js';
|
|
21
22
|
/**
|
|
22
23
|
* Options for starting the unified console.
|
|
23
24
|
*/
|
|
@@ -79,6 +80,25 @@ export interface UnifiedConsoleResult {
|
|
|
79
80
|
* threw. Exposed so tests can assert the full result shape.
|
|
80
81
|
*/
|
|
81
82
|
export declare function warnIfLegacyConsolePresent(currentPort: number, detect?: typeof detectLegacyLeader, log?: typeof logger): Promise<Awaited<ReturnType<typeof detectLegacyLeader>> | null>;
|
|
83
|
+
export interface PortLeaderDiscovery {
|
|
84
|
+
leaderInfo: ConsoleLeaderInfo | null;
|
|
85
|
+
ownerPid: number | null;
|
|
86
|
+
source: 'api' | 'lock' | 'synthetic' | 'none';
|
|
87
|
+
}
|
|
88
|
+
export interface BindFailureRecoveryResult extends PortLeaderDiscovery {
|
|
89
|
+
lockCleanupAttempted: boolean;
|
|
90
|
+
lockCleanupPerformed: boolean;
|
|
91
|
+
}
|
|
92
|
+
interface DiscoveryDependencies {
|
|
93
|
+
fetchImpl?: typeof fetch;
|
|
94
|
+
findPidOnPortImpl?: typeof findPidOnPort;
|
|
95
|
+
readLeaderLockImpl?: typeof readLeaderLock;
|
|
96
|
+
}
|
|
97
|
+
export declare function discoverLeaderServingPort(port: number, authToken: string | null, deps?: DiscoveryDependencies): Promise<PortLeaderDiscovery>;
|
|
98
|
+
interface BindFailureRecoveryDependencies extends DiscoveryDependencies {
|
|
99
|
+
deleteLeaderLockImpl?: typeof deleteLeaderLock;
|
|
100
|
+
}
|
|
101
|
+
export declare function recoverLeaderBindFailure(provisionalLeader: ConsoleLeaderInfo, port: number, authToken: string | null, deps?: BindFailureRecoveryDependencies): Promise<BindFailureRecoveryResult>;
|
|
82
102
|
/**
|
|
83
103
|
* Start the unified web console.
|
|
84
104
|
*
|
|
@@ -86,4 +106,5 @@ export declare function warnIfLegacyConsolePresent(currentPort: number, detect?:
|
|
|
86
106
|
* or sets up event forwarding (follower).
|
|
87
107
|
*/
|
|
88
108
|
export declare function startUnifiedConsole(options: UnifiedConsoleOptions): Promise<UnifiedConsoleResult>;
|
|
109
|
+
export {};
|
|
89
110
|
//# sourceMappingURL=UnifiedConsole.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UnifiedConsole.d.ts","sourceRoot":"","sources":["../../../src/web/console/UnifiedConsole.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"UnifiedConsole.d.ts","sourceRoot":"","sources":["../../../src/web/console/UnifiedConsole.ts"],"names":[],"mappings":"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"}
|