@pharaoh-so/mcp 0.1.3 → 0.1.5
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/auth.js.map +1 -0
- package/dist/credentials.js.map +1 -0
- package/dist/index.js +138 -60
- package/dist/index.js.map +1 -0
- package/dist/proxy.d.ts +0 -4
- package/dist/proxy.js +17 -14
- package/dist/proxy.js.map +1 -0
- package/inspect-tools.json +856 -0
- package/package.json +32 -31
- package/dist/helpers.d.ts +0 -36
- package/dist/helpers.js +0 -124
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,wEAAwE;AACxE,MAAM,cAAc,GAAG,CAAC,CAAC;AAgBzB,oCAAoC;AACpC,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAEzE;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAI,GAAG,gBAAgB;IACtD,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7C,OAAO,MAAM,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkB,EAAE,IAAI,GAAG,gBAAgB;IAC3E,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,iBAAiB,CAAC,IAAI,GAAG,gBAAgB;IACxD,IAAI,CAAC;QACJ,UAAU,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACR,yCAAyC;IAC1C,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC3C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;IACvD,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;IAC3C,MAAM,QAAQ,GAAG,UAAU,GAAG,GAAG,CAAC;IAElC,OAAO,GAAG,IAAI,SAAS,GAAG,QAAQ,CAAC;AACpC,CAAC;AAED,+CAA+C;AAC/C,SAAS,kBAAkB,CAAC,KAAc;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,OAAO,CACN,GAAG,CAAC,OAAO,KAAK,cAAc;QAC9B,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ;QACpC,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;QAClC,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;QAClC,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;QAC/B,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CACxB,CAAC;AACH,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,92 +5,170 @@
|
|
|
5
5
|
* Presents as an MCP server on stdio (for Claude Code) and relays messages
|
|
6
6
|
* to a remote Pharaoh SSE server. Authenticates via RFC 8628 device flow
|
|
7
7
|
* so the user can authorize on any device with a browser.
|
|
8
|
-
*
|
|
9
|
-
* Two modes determined by whether stdin is a TTY:
|
|
10
|
-
* - Interactive (TTY): authenticate, print setup instructions, exit.
|
|
11
|
-
* - Proxy (pipe): require pre-existing credentials, bridge stdio ↔ SSE.
|
|
12
8
|
*/
|
|
13
9
|
import { printActivationPrompt, printAuthSuccess, pollForToken, requestDeviceCode, } from "./auth.js";
|
|
14
|
-
import { deleteCredentials, isExpired, readCredentials, writeCredentials } from "./credentials.js";
|
|
15
|
-
import { formatIdentity, formatTtl, parseArgs, printLines, printSetupInstructions, printUsage, resolveSseUrl, tokenToCredentials, } from "./helpers.js";
|
|
10
|
+
import { deleteCredentials, isExpired, readCredentials, writeCredentials, } from "./credentials.js";
|
|
16
11
|
import { TokenExpiredError, TenantSuspendedError, startProxy } from "./proxy.js";
|
|
17
|
-
|
|
12
|
+
const DEFAULT_SERVER = "https://mcp.pharaoh.so";
|
|
13
|
+
/** Parse CLI arguments. */
|
|
14
|
+
function parseArgs() {
|
|
18
15
|
const args = process.argv.slice(2);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
let server = DEFAULT_SERVER;
|
|
17
|
+
let logout = false;
|
|
18
|
+
for (let i = 0; i < args.length; i++) {
|
|
19
|
+
if (args[i] === "--server" && args[i + 1]) {
|
|
20
|
+
server = args[i + 1];
|
|
21
|
+
i++;
|
|
22
|
+
}
|
|
23
|
+
else if (args[i] === "--logout") {
|
|
24
|
+
logout = true;
|
|
25
|
+
}
|
|
26
|
+
else if (args[i] === "--help" || args[i] === "-h") {
|
|
27
|
+
printUsage();
|
|
28
|
+
process.exit(0);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Strip trailing slash
|
|
32
|
+
server = server.replace(/\/+$/, "");
|
|
33
|
+
return { server, logout };
|
|
34
|
+
}
|
|
35
|
+
function printUsage() {
|
|
36
|
+
process.stderr.write([
|
|
37
|
+
"Usage: pharaoh-mcp [options]",
|
|
38
|
+
"",
|
|
39
|
+
"Options:",
|
|
40
|
+
" --server <url> Pharaoh server URL (default: https://mcp.pharaoh.so)",
|
|
41
|
+
" --logout Clear stored credentials and exit",
|
|
42
|
+
" --help, -h Show this help",
|
|
43
|
+
"",
|
|
44
|
+
"Add to Claude Code:",
|
|
45
|
+
" claude mcp add pharaoh -- npx @pharaoh-so/mcp",
|
|
46
|
+
"",
|
|
47
|
+
].join("\n") + "\n");
|
|
48
|
+
}
|
|
49
|
+
/** Run the device flow and return a token response. */
|
|
50
|
+
async function authenticate(server) {
|
|
51
|
+
const deviceCode = await requestDeviceCode(server);
|
|
52
|
+
printActivationPrompt(deviceCode.user_code, deviceCode.verification_uri);
|
|
53
|
+
return pollForToken(server, deviceCode.device_code, deviceCode.interval);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Validate that a server-supplied SSE URL shares the same origin as the configured server.
|
|
57
|
+
* Prevents a compromised auth response from redirecting the Bearer token to an attacker's host.
|
|
58
|
+
* Falls back to `${server}/sse` if the URL is missing, malformed, or cross-origin.
|
|
59
|
+
*/
|
|
60
|
+
function resolveSseUrl(tokenSseUrl, server) {
|
|
61
|
+
const fallback = `${server}/sse`;
|
|
62
|
+
if (!tokenSseUrl)
|
|
63
|
+
return fallback;
|
|
64
|
+
try {
|
|
65
|
+
const sseOrigin = new URL(tokenSseUrl).origin;
|
|
66
|
+
const serverOrigin = new URL(server).origin;
|
|
67
|
+
if (sseOrigin !== serverOrigin) {
|
|
68
|
+
process.stderr.write(`Pharaoh: ignoring cross-origin sse_url (${sseOrigin} ≠ ${serverOrigin})\n`);
|
|
69
|
+
return fallback;
|
|
70
|
+
}
|
|
71
|
+
return tokenSseUrl;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return fallback;
|
|
22
75
|
}
|
|
23
|
-
|
|
76
|
+
}
|
|
77
|
+
/** Convert a token response to storable credentials. */
|
|
78
|
+
function tokenToCredentials(token, sseUrl) {
|
|
79
|
+
return {
|
|
80
|
+
version: 1,
|
|
81
|
+
access_token: token.access_token,
|
|
82
|
+
expires_at: new Date(Date.now() + token.expires_in * 1000).toISOString(),
|
|
83
|
+
expires_in: token.expires_in,
|
|
84
|
+
sse_url: sseUrl,
|
|
85
|
+
github_login: token.github_login ?? null,
|
|
86
|
+
tenant_name: token.tenant_name ?? null,
|
|
87
|
+
repos: token.repos ?? [],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** Format remaining TTL as human-readable string (e.g. "5d 12h"). */
|
|
91
|
+
function formatTtl(expiresAt) {
|
|
92
|
+
const remainingMs = new Date(expiresAt).getTime() - Date.now();
|
|
93
|
+
if (remainingMs <= 0)
|
|
94
|
+
return "expired";
|
|
95
|
+
const hours = Math.floor(remainingMs / 3_600_000);
|
|
96
|
+
const days = Math.floor(hours / 24);
|
|
97
|
+
const remHours = hours % 24;
|
|
98
|
+
if (days > 0)
|
|
99
|
+
return `${days}d ${remHours}h`;
|
|
100
|
+
if (hours > 0)
|
|
101
|
+
return `${hours}h`;
|
|
102
|
+
return `${Math.floor(remainingMs / 60_000)}m`;
|
|
103
|
+
}
|
|
104
|
+
async function main() {
|
|
105
|
+
const { server, logout } = parseArgs();
|
|
106
|
+
// --logout: clear credentials and exit
|
|
24
107
|
if (logout) {
|
|
25
108
|
deleteCredentials();
|
|
26
|
-
|
|
109
|
+
process.stderr.write("Pharaoh: credentials cleared\n");
|
|
27
110
|
process.exit(0);
|
|
28
111
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
112
|
+
let creds = readCredentials();
|
|
113
|
+
// If we have valid credentials, try to connect directly
|
|
114
|
+
if (creds && !isExpired(creds)) {
|
|
115
|
+
process.stderr.write(`Pharaoh: token valid for ${formatTtl(creds.expires_at)} — connecting\n`);
|
|
116
|
+
try {
|
|
117
|
+
await startProxy(creds.sse_url, creds.access_token);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
if (err instanceof TokenExpiredError) {
|
|
122
|
+
process.stderr.write("Pharaoh: token rejected by server — re-authenticating\n");
|
|
123
|
+
deleteCredentials();
|
|
124
|
+
creds = null;
|
|
125
|
+
}
|
|
126
|
+
else if (err instanceof TenantSuspendedError) {
|
|
127
|
+
process.stderr.write(`Pharaoh: ${err.message}\n`);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
39
133
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const token = await
|
|
134
|
+
}
|
|
135
|
+
// No valid credentials — run device flow
|
|
136
|
+
if (!creds || isExpired(creds)) {
|
|
137
|
+
process.stderr.write("Pharaoh: no valid credentials — starting device authorization\n");
|
|
138
|
+
const token = await authenticate(server);
|
|
45
139
|
if (token.provisional) {
|
|
46
|
-
|
|
140
|
+
process.stderr.write(`Pharaoh: provisional access — install the GitHub App to map your repos: ${token.install_url ?? ""}\n`);
|
|
47
141
|
}
|
|
48
142
|
const sseUrl = resolveSseUrl(token.sse_url, server);
|
|
49
|
-
|
|
50
|
-
writeCredentials(
|
|
143
|
+
creds = tokenToCredentials(token, sseUrl);
|
|
144
|
+
writeCredentials(creds);
|
|
51
145
|
printAuthSuccess(token.github_login ?? null, token.tenant_name ?? null, token.repos?.length ?? 0);
|
|
52
|
-
printSetupInstructions();
|
|
53
|
-
process.exit(0);
|
|
54
|
-
}
|
|
55
|
-
// ── Proxy mode (Claude Code spawned us as a stdio MCP server) ──
|
|
56
|
-
// If no credentials, we can't run the device flow (no TTY for user interaction).
|
|
57
|
-
if (!creds || isExpired(creds)) {
|
|
58
|
-
printLines("Pharaoh: no valid credentials — cannot start proxy.", "Run this command first to authenticate:", " npx @pharaoh-so/mcp", "");
|
|
59
|
-
process.exit(1);
|
|
60
146
|
}
|
|
61
|
-
//
|
|
62
|
-
printLines(`Pharaoh: token valid for ${formatTtl(creds.expires_at)} — connecting`);
|
|
147
|
+
// Start proxy with fresh credentials
|
|
63
148
|
try {
|
|
64
149
|
await startProxy(creds.sse_url, creds.access_token);
|
|
65
150
|
}
|
|
66
151
|
catch (err) {
|
|
67
152
|
if (err instanceof TokenExpiredError) {
|
|
68
|
-
|
|
153
|
+
// Token expired during session — delete creds and re-auth
|
|
154
|
+
process.stderr.write("Pharaoh: session expired — re-authenticating\n");
|
|
69
155
|
deleteCredentials();
|
|
70
|
-
|
|
156
|
+
const token = await authenticate(server);
|
|
157
|
+
const sseUrl = resolveSseUrl(token.sse_url, server);
|
|
158
|
+
creds = tokenToCredentials(token, sseUrl);
|
|
159
|
+
writeCredentials(creds);
|
|
160
|
+
await startProxy(creds.sse_url, creds.access_token);
|
|
71
161
|
}
|
|
72
|
-
if (err instanceof TenantSuspendedError) {
|
|
73
|
-
|
|
162
|
+
else if (err instanceof TenantSuspendedError) {
|
|
163
|
+
process.stderr.write(`Pharaoh: ${err.message}\n`);
|
|
74
164
|
process.exit(1);
|
|
75
165
|
}
|
|
76
|
-
|
|
166
|
+
else {
|
|
167
|
+
throw err;
|
|
168
|
+
}
|
|
77
169
|
}
|
|
78
170
|
}
|
|
79
171
|
main().catch((err) => {
|
|
80
|
-
|
|
81
|
-
// or stack fragments that persist in CI logs. Full message behind PHARAOH_DEBUG.
|
|
82
|
-
if (process.env.PHARAOH_DEBUG === "1" && err instanceof Error) {
|
|
83
|
-
// Use main's comprehensive redaction patterns when showing the full message
|
|
84
|
-
const safeMsg = err.message
|
|
85
|
-
.replace(/Bearer\s+\S+/gi, "Bearer [REDACTED]")
|
|
86
|
-
.replace(/(?:phat|phrt|ghp|gho|ghs|ghu)_\S+/gi, "[REDACTED_TOKEN]")
|
|
87
|
-
.replace(/[?&](?:code|token|key|secret|password|state)=[^&\s]+/gi, "?[REDACTED_PARAM]")
|
|
88
|
-
.replace(/\b[0-9a-f]{32,}\b/gi, "[REDACTED_HEX]");
|
|
89
|
-
printLines(`Pharaoh: fatal — ${safeMsg}`);
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
const label = err instanceof Error ? err.name : "Error";
|
|
93
|
-
printLines(`Pharaoh: fatal — ${label}. Set PHARAOH_DEBUG=1 for details.`);
|
|
94
|
-
}
|
|
172
|
+
process.stderr.write(`Pharaoh: fatal — ${err instanceof Error ? err.message : String(err)}\n`);
|
|
95
173
|
process.exit(1);
|
|
96
174
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/proxy.d.ts
CHANGED
|
@@ -18,10 +18,6 @@ export declare function classifySSEError(err: Error): void;
|
|
|
18
18
|
* Claude Code → stdin → StdioServerTransport.onmessage → SSEClientTransport.send → POST /message
|
|
19
19
|
* Pharaoh → SSE stream → SSEClientTransport.onmessage → StdioServerTransport.send → stdout
|
|
20
20
|
*
|
|
21
|
-
* CRITICAL ordering: SSE must be connected BEFORE stdio starts reading stdin.
|
|
22
|
-
* Otherwise the MCP `initialize` message arrives before the remote transport is ready,
|
|
23
|
-
* gets permanently lost ("send error — Not connected"), and the client times out.
|
|
24
|
-
*
|
|
25
21
|
* On SSE disconnect, attempts reconnect with exponential backoff (5 retries, ~62s total).
|
|
26
22
|
* Throws TokenExpiredError on 401, TenantSuspendedError on 403.
|
|
27
23
|
*/
|
package/dist/proxy.js
CHANGED
|
@@ -67,10 +67,6 @@ function createSSETransport(sseUrl, token) {
|
|
|
67
67
|
* Claude Code → stdin → StdioServerTransport.onmessage → SSEClientTransport.send → POST /message
|
|
68
68
|
* Pharaoh → SSE stream → SSEClientTransport.onmessage → StdioServerTransport.send → stdout
|
|
69
69
|
*
|
|
70
|
-
* CRITICAL ordering: SSE must be connected BEFORE stdio starts reading stdin.
|
|
71
|
-
* Otherwise the MCP `initialize` message arrives before the remote transport is ready,
|
|
72
|
-
* gets permanently lost ("send error — Not connected"), and the client times out.
|
|
73
|
-
*
|
|
74
70
|
* On SSE disconnect, attempts reconnect with exponential backoff (5 retries, ~62s total).
|
|
75
71
|
* Throws TokenExpiredError on 401, TenantSuspendedError on 403.
|
|
76
72
|
*/
|
|
@@ -78,7 +74,6 @@ export async function startProxy(sseUrl, token) {
|
|
|
78
74
|
const stdio = new StdioServerTransport();
|
|
79
75
|
let sse = createSSETransport(sseUrl, token);
|
|
80
76
|
let reconnectAttempt = 0;
|
|
81
|
-
let stdioStarted = false;
|
|
82
77
|
/** Wire up bidirectional message relay between the two transports. */
|
|
83
78
|
function bridge(sseTransport) {
|
|
84
79
|
stdio.onmessage = (msg) => {
|
|
@@ -94,7 +89,22 @@ export async function startProxy(sseUrl, token) {
|
|
|
94
89
|
}
|
|
95
90
|
/** Handle SSE errors — delegates to classifySSEError for 401/403 detection. */
|
|
96
91
|
const handleSSEError = classifySSEError;
|
|
97
|
-
//
|
|
92
|
+
// Wire up initial bridge
|
|
93
|
+
bridge(sse);
|
|
94
|
+
// Handle SSE connection drops with reconnect
|
|
95
|
+
sse.onerror = (err) => {
|
|
96
|
+
try {
|
|
97
|
+
handleSSEError(err);
|
|
98
|
+
}
|
|
99
|
+
catch (typed) {
|
|
100
|
+
// TokenExpiredError or TenantSuspendedError — propagate via close
|
|
101
|
+
sse.close().catch(() => { });
|
|
102
|
+
throw typed;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
// Start both transports
|
|
106
|
+
await stdio.start();
|
|
107
|
+
// Connect SSE with reconnect loop
|
|
98
108
|
await connectWithReconnect();
|
|
99
109
|
/** Attempt SSE connection with exponential backoff on failure. */
|
|
100
110
|
async function connectWithReconnect() {
|
|
@@ -105,17 +115,10 @@ export async function startProxy(sseUrl, token) {
|
|
|
105
115
|
process.stderr.write(`Pharaoh: reconnecting in ${delay / 1000}s (attempt ${reconnectAttempt}/${BACKOFF_MS.length})...\n`);
|
|
106
116
|
await sleep(delay);
|
|
107
117
|
sse = createSSETransport(sseUrl, token);
|
|
118
|
+
bridge(sse);
|
|
108
119
|
}
|
|
109
120
|
await sse.start();
|
|
110
121
|
reconnectAttempt = 0; // Reset on successful connection
|
|
111
|
-
// Bridge AFTER SSE is connected — messages can now be forwarded
|
|
112
|
-
bridge(sse);
|
|
113
|
-
// Start stdio AFTER first SSE connection — prevents initialize race
|
|
114
|
-
if (!stdioStarted) {
|
|
115
|
-
process.stderr.write("Pharaoh: connected\n");
|
|
116
|
-
await stdio.start();
|
|
117
|
-
stdioStarted = true;
|
|
118
|
-
}
|
|
119
122
|
// Wait for close — this promise resolves when SSE disconnects
|
|
120
123
|
await new Promise((resolve, reject) => {
|
|
121
124
|
sse.onclose = () => resolve();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
|