@withpica/mcp-server 2.33.0 → 2.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +261 -0
- package/dist/apps/release.d.ts +2 -0
- package/dist/apps/release.d.ts.map +1 -0
- package/dist/apps/release.js +69 -0
- package/dist/apps/release.js.map +1 -0
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +16 -0
- package/dist/resources/index.js.map +1 -1
- package/dist/server-instructions.d.ts +28 -0
- package/dist/server-instructions.d.ts.map +1 -1
- package/dist/server-instructions.js +34 -0
- package/dist/server-instructions.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +11 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/app-tools.d.ts.map +1 -1
- package/dist/tools/app-tools.js +39 -18
- package/dist/tools/app-tools.js.map +1 -1
- package/dist/tools/credits.d.ts +23 -0
- package/dist/tools/credits.d.ts.map +1 -1
- package/dist/tools/credits.js +199 -0
- package/dist/tools/credits.js.map +1 -1
- package/dist/tools/discovery.d.ts.map +1 -1
- package/dist/tools/discovery.js +24 -2
- package/dist/tools/discovery.js.map +1 -1
- package/dist/tools/index.d.ts +15 -6
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +64 -9
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/metadata.d.ts.map +1 -1
- package/dist/tools/metadata.js +39 -0
- package/dist/tools/metadata.js.map +1 -1
- package/dist/tools/public-filter.d.ts.map +1 -1
- package/dist/tools/public-filter.js +2 -0
- package/dist/tools/public-filter.js.map +1 -1
- package/dist/tools/recording-attribution-hints.d.ts +24 -0
- package/dist/tools/recording-attribution-hints.d.ts.map +1 -0
- package/dist/tools/recording-attribution-hints.js +27 -0
- package/dist/tools/recording-attribution-hints.js.map +1 -0
- package/dist/tools/recordings.d.ts.map +1 -1
- package/dist/tools/recordings.js +30 -3
- package/dist/tools/recordings.js.map +1 -1
- package/dist/tools/release-rich.d.ts +31 -0
- package/dist/tools/release-rich.d.ts.map +1 -0
- package/dist/tools/release-rich.js +240 -0
- package/dist/tools/release-rich.js.map +1 -0
- package/dist/tools/signup.d.ts +26 -0
- package/dist/tools/signup.d.ts.map +1 -0
- package/dist/tools/signup.js +265 -0
- package/dist/tools/signup.js.map +1 -0
- package/dist/tools/subscription.d.ts +60 -0
- package/dist/tools/subscription.d.ts.map +1 -0
- package/dist/tools/subscription.js +440 -0
- package/dist/tools/subscription.js.map +1 -0
- package/package.json +3 -3
- package/server.json +2 -2
- package/dist/__mocks__/mppx-mcp-sdk-server.d.ts +0 -6
- package/dist/__mocks__/mppx-mcp-sdk-server.d.ts.map +0 -1
- package/dist/__mocks__/mppx-mcp-sdk-server.js +0 -6
- package/dist/__mocks__/mppx-mcp-sdk-server.js.map +0 -1
- package/dist/__mocks__/mppx-server.d.ts +0 -12
- package/dist/__mocks__/mppx-server.d.ts.map +0 -1
- package/dist/__mocks__/mppx-server.js +0 -12
- package/dist/__mocks__/mppx-server.js.map +0 -1
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
// Copyright (c) 2024-2026 Withpica Ltd. All rights reserved.
|
|
2
|
+
/**
|
|
3
|
+
* Signup Tools — `pica_signup_start` (ADR-211 Phase 1).
|
|
4
|
+
*
|
|
5
|
+
* The single MCP-discoverable signup verb. Available unauthenticated on
|
|
6
|
+
* BOTH transports (stdio binary's lobby + HTTP `/api/mcp` anonymous mode)
|
|
7
|
+
* per ADR-211 § Primitive A (amended 2026-04-30 to expose alongside
|
|
8
|
+
* `pica_sign_in` / `pica_sign_out` rather than replace them in Phase 1).
|
|
9
|
+
*
|
|
10
|
+
* Mints nothing locally — every invocation calls the public backend
|
|
11
|
+
* endpoint `POST /api/public/onboarding/signup-start`. The signing secret
|
|
12
|
+
* (`ONBOARDING_TOKEN_SECRET`) lives only on the backend; customer-
|
|
13
|
+
* distributed `npx @withpica/mcp-server` binaries can never see it. Same
|
|
14
|
+
* pattern that `pica_sign_in` (auth.ts) uses to call the public
|
|
15
|
+
* `/api/public/mcp-auth/authorize` magic-link endpoint.
|
|
16
|
+
*
|
|
17
|
+
* Returns the JWT-bound URL via:
|
|
18
|
+
* - `resource_link` (universal floor — every MCP client can render this)
|
|
19
|
+
* - capability-gated `elicitation/create url` (mode: "url"; for clients
|
|
20
|
+
* advertising `capabilities.elicitation.url`, server-issued consent
|
|
21
|
+
* prompt to open the link in-line). See ADR-200 + `pica_upload`.
|
|
22
|
+
*
|
|
23
|
+
* Construction takes the API base URL + transport + optional DCR
|
|
24
|
+
* client_id. The stdio binary stamps `transport: "stdio"`; the HTTP
|
|
25
|
+
* carve-out in `app/api/mcp/route.ts` stamps `transport: "http"` and
|
|
26
|
+
* passes `client_id` from the OAuth-protected-resource discovery context
|
|
27
|
+
* when one is present.
|
|
28
|
+
*/
|
|
29
|
+
import { randomUUID } from "node:crypto";
|
|
30
|
+
import { clientSupportsUrlElicitation } from "@withpica/mcp-utils";
|
|
31
|
+
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
32
|
+
export class SignupTools {
|
|
33
|
+
apiUrl;
|
|
34
|
+
transport;
|
|
35
|
+
clientId;
|
|
36
|
+
constructor(config) {
|
|
37
|
+
if (!config.apiUrl) {
|
|
38
|
+
throw new Error("SignupTools requires apiUrl");
|
|
39
|
+
}
|
|
40
|
+
if (config.transport !== "stdio" && config.transport !== "http") {
|
|
41
|
+
throw new Error(`SignupTools.transport must be "stdio" or "http" (got: ${config.transport})`);
|
|
42
|
+
}
|
|
43
|
+
if (config.transport === "stdio" && config.clientId) {
|
|
44
|
+
// stdio has no DCR client identifier. Constructor enforces the
|
|
45
|
+
// invariant locally so the public endpoint never sees a confused
|
|
46
|
+
// pairing in the first place.
|
|
47
|
+
throw new Error("clientId must be null for stdio transport");
|
|
48
|
+
}
|
|
49
|
+
this.apiUrl = config.apiUrl.replace(/\/+$/, "");
|
|
50
|
+
this.transport = config.transport;
|
|
51
|
+
this.clientId = config.clientId ?? null;
|
|
52
|
+
}
|
|
53
|
+
getTools() {
|
|
54
|
+
return [
|
|
55
|
+
{
|
|
56
|
+
definition: {
|
|
57
|
+
name: "pica_signup_start",
|
|
58
|
+
description: "Sign up for withPICA from inside the agent, without leaving the chat. " +
|
|
59
|
+
"Use this when the user wants to create a new withPICA account / catalog " +
|
|
60
|
+
"and you're talking to them through an unauthenticated MCP connection " +
|
|
61
|
+
"(stdio without an API key, or HTTP without a Bearer token). The tool " +
|
|
62
|
+
"mints a single-use signup link valid for 15 minutes — surface the URL " +
|
|
63
|
+
"to the user as a clickable resource_link. The link opens a page that " +
|
|
64
|
+
"verifies their email by magic-link, creates their organisation, starts " +
|
|
65
|
+
"the 14-day free trial, and (for stdio) shows a connection key to paste " +
|
|
66
|
+
"into Claude Desktop's MCP config or (for HTTP) resumes the OAuth flow. " +
|
|
67
|
+
"ADR-211 Phase 1. For existing users, prefer pica_sign_in.",
|
|
68
|
+
inputSchema: {
|
|
69
|
+
type: "object",
|
|
70
|
+
properties: {
|
|
71
|
+
email: {
|
|
72
|
+
type: "string",
|
|
73
|
+
description: "The user's email address. The signup link is sent to this " +
|
|
74
|
+
"inbox; the user clicks it to verify ownership before any " +
|
|
75
|
+
"account is created. Required.",
|
|
76
|
+
},
|
|
77
|
+
org_name: {
|
|
78
|
+
type: "string",
|
|
79
|
+
description: "Optional human name for the user's catalog/organisation. " +
|
|
80
|
+
"Defaults to '<email-localpart>'s catalog' if omitted. " +
|
|
81
|
+
"Editable later in settings.",
|
|
82
|
+
},
|
|
83
|
+
purpose: {
|
|
84
|
+
type: "string",
|
|
85
|
+
description: "Optional free-text — what the user is trying to do with " +
|
|
86
|
+
"PICA, captured for product analytics (e.g. 'managing my " +
|
|
87
|
+
"first album credits', 'exporting royalty statements'). " +
|
|
88
|
+
"Not surfaced to the user.",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
required: ["email"],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
executor: this.signupStart.bind(this),
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
}
|
|
98
|
+
async signupStart(args, ctx) {
|
|
99
|
+
const email = typeof args.email === "string" ? args.email.trim().toLowerCase() : "";
|
|
100
|
+
if (!email || !EMAIL_REGEX.test(email)) {
|
|
101
|
+
return {
|
|
102
|
+
content: [
|
|
103
|
+
{
|
|
104
|
+
type: "text",
|
|
105
|
+
text: "that doesn't look like an email address — please ask the user to confirm and try again.",
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
isError: true,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const orgName = typeof args.org_name === "string" && args.org_name.trim().length > 0
|
|
112
|
+
? args.org_name.trim()
|
|
113
|
+
: undefined;
|
|
114
|
+
const purpose = typeof args.purpose === "string" && args.purpose.trim().length > 0
|
|
115
|
+
? args.purpose.trim()
|
|
116
|
+
: undefined;
|
|
117
|
+
// The public endpoint is unauthenticated — same fetch shape as
|
|
118
|
+
// pica_sign_in's call to /api/public/mcp-auth/authorize.
|
|
119
|
+
const endpoint = `${this.apiUrl}/public/onboarding/signup-start`;
|
|
120
|
+
let response;
|
|
121
|
+
try {
|
|
122
|
+
response = await fetch(endpoint, {
|
|
123
|
+
method: "POST",
|
|
124
|
+
headers: { "Content-Type": "application/json" },
|
|
125
|
+
body: JSON.stringify({
|
|
126
|
+
email,
|
|
127
|
+
...(orgName ? { org_name: orgName } : {}),
|
|
128
|
+
...(purpose ? { purpose } : {}),
|
|
129
|
+
transport: this.transport,
|
|
130
|
+
...(this.clientId ? { client_id: this.clientId } : {}),
|
|
131
|
+
}),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
const message = err instanceof Error ? err.message : "network error";
|
|
136
|
+
return {
|
|
137
|
+
content: [
|
|
138
|
+
{
|
|
139
|
+
type: "text",
|
|
140
|
+
text: `couldn't reach withPICA to mint your signup link (${message}). check your internet connection and try again.`,
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
isError: true,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if (response.status === 429) {
|
|
147
|
+
const retryAfter = response.headers.get("Retry-After") ?? "a few minutes";
|
|
148
|
+
return {
|
|
149
|
+
content: [
|
|
150
|
+
{
|
|
151
|
+
type: "text",
|
|
152
|
+
text: `too many signup attempts — please wait ${retryAfter} seconds before trying again. if the user just requested a link, ask them to check their inbox first.`,
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
isError: true,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
if (!response.ok) {
|
|
159
|
+
let detail = "unknown error";
|
|
160
|
+
try {
|
|
161
|
+
const body = (await response.json());
|
|
162
|
+
if (typeof body.error === "string")
|
|
163
|
+
detail = body.error;
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// body wasn't JSON — fall back to status text
|
|
167
|
+
detail = response.statusText || detail;
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
content: [
|
|
171
|
+
{
|
|
172
|
+
type: "text",
|
|
173
|
+
text: `couldn't mint your signup link: ${detail}. please try again or report this if it keeps happening.`,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
isError: true,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
let body;
|
|
180
|
+
try {
|
|
181
|
+
body = (await response.json());
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return {
|
|
185
|
+
content: [
|
|
186
|
+
{
|
|
187
|
+
type: "text",
|
|
188
|
+
text: "the signup endpoint returned a malformed response. please try again.",
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
isError: true,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
if (!body.url || !body.expires_at) {
|
|
195
|
+
return {
|
|
196
|
+
content: [
|
|
197
|
+
{
|
|
198
|
+
type: "text",
|
|
199
|
+
text: "the signup endpoint returned an incomplete response. please try again.",
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
isError: true,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const url = body.url;
|
|
206
|
+
const expiresAt = body.expires_at;
|
|
207
|
+
const textSummary = `signup link minted for ${email}. surface this URL to the user — they should click it to verify ownership of the email, ` +
|
|
208
|
+
`pick an organisation name, and start their 14-day trial. the link expires at ${expiresAt} (15 minutes from now). ` +
|
|
209
|
+
(this.transport === "stdio"
|
|
210
|
+
? "after they finish signup the page will show a connection key to paste into Claude Desktop's MCP config; they'll then need to reconnect the PICA MCP server."
|
|
211
|
+
: "after they finish signup the OAuth flow resumes automatically.");
|
|
212
|
+
const resourceLink = {
|
|
213
|
+
type: "resource_link",
|
|
214
|
+
uri: url,
|
|
215
|
+
name: "Sign up for withPICA",
|
|
216
|
+
description: "Open this link to verify your email, create your catalog, and start a 14-day trial.",
|
|
217
|
+
mimeType: "text/html",
|
|
218
|
+
};
|
|
219
|
+
const baseContent = [
|
|
220
|
+
{
|
|
221
|
+
type: "text",
|
|
222
|
+
text: JSON.stringify({
|
|
223
|
+
text_summary: textSummary,
|
|
224
|
+
signup_url: url,
|
|
225
|
+
expires_at: expiresAt,
|
|
226
|
+
surface: body.surface ?? "onboarding",
|
|
227
|
+
}),
|
|
228
|
+
},
|
|
229
|
+
resourceLink,
|
|
230
|
+
];
|
|
231
|
+
// Capability-gated `elicitation/create url` — clients advertising
|
|
232
|
+
// `capabilities.elicitation.url` get a server-issued consent prompt
|
|
233
|
+
// to open the link in-line. Without the gate, calling elicitInput
|
|
234
|
+
// against a non-supporter throws synchronously per
|
|
235
|
+
// `feedback_mcp_sdk_capability_gates_elicitation.md`.
|
|
236
|
+
if (clientSupportsUrlElicitation(ctx?.server)) {
|
|
237
|
+
try {
|
|
238
|
+
await ctx.server.elicitInput({
|
|
239
|
+
mode: "url",
|
|
240
|
+
url,
|
|
241
|
+
elicitationId: `pica-signup-${randomUUID()}`,
|
|
242
|
+
message: `Open this URL to finish signing up for withPICA. Expires at ${expiresAt}.`,
|
|
243
|
+
}, { timeout: 60_000 });
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
// user declined / cancelled / timed out — `resource_link` remains
|
|
247
|
+
// usable so we degrade silently rather than fail the tool.
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
content: baseContent,
|
|
252
|
+
structuredContent: {
|
|
253
|
+
kind: "pica.card.signup_start",
|
|
254
|
+
version: 1,
|
|
255
|
+
data: {
|
|
256
|
+
signup_url: url,
|
|
257
|
+
expires_at: expiresAt,
|
|
258
|
+
email,
|
|
259
|
+
transport: this.transport,
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=signup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signup.js","sourceRoot":"","sources":["../../src/tools/signup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { PicaClient, type BillingTier, type SubscriptionStatusResponse } from "@withpica/mcp-sdk";
|
|
2
|
+
import { ToolDefinition, ToolExecutor } from "./index.js";
|
|
3
|
+
interface SubscriptionStatusFlat {
|
|
4
|
+
billing_state: "trial" | "active" | "hibernated";
|
|
5
|
+
trial_days_remaining: number | null;
|
|
6
|
+
trial_ends_at: string | null;
|
|
7
|
+
current_tier: BillingTier | null;
|
|
8
|
+
capacity_used: number;
|
|
9
|
+
capacity_limit: number | null;
|
|
10
|
+
capacity_pct: number;
|
|
11
|
+
recommended_tier: BillingTier | null;
|
|
12
|
+
summary: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Compose the flat 9-field response from the existing GET admin route's
|
|
16
|
+
* shape. Mirrors `getOrgBillingSlice`'s "no meaningful cap" rule for
|
|
17
|
+
* `capacity_pct` (0 whenever current_tier is null OR enterprise) and
|
|
18
|
+
* carries through `overflow.recommendedTier` (already
|
|
19
|
+
* `inferTierFromCount`-derived) per Stage 1 Q2.
|
|
20
|
+
*
|
|
21
|
+
* Exported for unit tests.
|
|
22
|
+
*/
|
|
23
|
+
export declare function flattenStatus(status: SubscriptionStatusResponse): SubscriptionStatusFlat;
|
|
24
|
+
/**
|
|
25
|
+
* Server-side template per Stage 1 Q1 option A. Predictable wording,
|
|
26
|
+
* less variance across connectors. Phase 2.5 may add agent
|
|
27
|
+
* paraphrasing if telemetry shows demand.
|
|
28
|
+
*
|
|
29
|
+
* Exported for unit tests.
|
|
30
|
+
*/
|
|
31
|
+
export declare function composeSummary(fields: {
|
|
32
|
+
billing_state: "trial" | "active" | "hibernated";
|
|
33
|
+
trial_days_remaining: number | null;
|
|
34
|
+
current_tier: BillingTier | null;
|
|
35
|
+
capacity_used: number;
|
|
36
|
+
capacity_limit: number | null;
|
|
37
|
+
recommended_tier: BillingTier | null;
|
|
38
|
+
}): string;
|
|
39
|
+
export declare class SubscriptionTools {
|
|
40
|
+
private pica;
|
|
41
|
+
constructor(pica: PicaClient);
|
|
42
|
+
getTools(): Array<{
|
|
43
|
+
definition: ToolDefinition;
|
|
44
|
+
executor: ToolExecutor;
|
|
45
|
+
}>;
|
|
46
|
+
private status;
|
|
47
|
+
private manage;
|
|
48
|
+
/**
|
|
49
|
+
* Universal-floor return per ADR-200 Phase 1: every successful manage
|
|
50
|
+
* response carries a `resource_link` so any compliant MCP client can
|
|
51
|
+
* render or open the URL. Clients that advertise
|
|
52
|
+
* `capabilities.elicitation.url` additionally receive a server-issued
|
|
53
|
+
* elicitation/create request — the gate is mandatory because
|
|
54
|
+
* `elicitInput` with `mode: "url"` throws synchronously against
|
|
55
|
+
* non-supporters (`feedback_mcp_sdk_capability_gates_elicitation.md`).
|
|
56
|
+
*/
|
|
57
|
+
private buildLinkResult;
|
|
58
|
+
}
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=subscription.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../src/tools/subscription.ts"],"names":[],"mappings":"AA8BA,OAAO,EACL,UAAU,EACV,KAAK,WAAW,EAChB,KAAK,0BAA0B,EAChC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,cAAc,EACd,YAAY,EAGb,MAAM,YAAY,CAAC;AAoBpB,UAAU,sBAAsB;IAC9B,aAAa,EAAE,OAAO,GAAG,QAAQ,GAAG,YAAY,CAAC;IACjD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,0BAA0B,GACjC,sBAAsB,CA+CxB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,aAAa,EAAE,OAAO,GAAG,QAAQ,GAAG,YAAY,CAAC;IACjD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,WAAW,GAAG,IAAI,CAAC;CACtC,GAAG,MAAM,CA6CT;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,IAAI,CAAa;gBAEb,IAAI,EAAE,UAAU;IAI5B,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;YAmF3D,MAAM;YAkCN,MAAM;IA4JpB;;;;;;;;OAQG;YACW,eAAe;CA2D9B"}
|