@clipform/mcp-server 2.10.2 → 2.10.4
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/caps-DBnfcEyJ.d.ts +20 -0
- package/dist/{chunk-UBJ7CZL2.js → chunk-A5RVUIGS.js} +17 -7
- package/dist/chunk-A5RVUIGS.js.map +1 -0
- package/dist/{chunk-NCWQ42GI.js → chunk-EMQPJPF4.js} +35 -33
- package/dist/{chunk-NCWQ42GI.js.map → chunk-EMQPJPF4.js.map} +1 -1
- package/dist/{chunk-IL26A4IN.js → chunk-O35IVA4L.js} +20 -6
- package/dist/chunk-O35IVA4L.js.map +1 -0
- package/dist/{chunk-4QF4KGPE.js → chunk-QZO6MGNN.js} +230 -186
- package/dist/{chunk-4QF4KGPE.js.map → chunk-QZO6MGNN.js.map} +1 -1
- package/dist/index.js +4 -4
- package/dist/instrument.d.ts +15 -3
- package/dist/instrument.js +4 -4
- package/dist/instrument.js.map +1 -1
- package/dist/prompts.d.ts +3 -2
- package/dist/prompts.js +2 -2
- package/dist/resources.d.ts +3 -1
- package/dist/resources.js +2 -2
- package/dist/server.d.ts +24 -1
- package/dist/server.js +8 -4
- package/package.json +1 -1
- package/dist/chunk-IL26A4IN.js.map +0 -1
- package/dist/chunk-UBJ7CZL2.js.map +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a connected surface can actually do, derived from the connect-time
|
|
3
|
+
* toolset filter (#3309) so the guidance layers (server instructions, prompt
|
|
4
|
+
* recipes, `clipform_get_workflow`, craft guides) never reference a tool the
|
|
5
|
+
* surface doesn't register (#3681).
|
|
6
|
+
*
|
|
7
|
+
* The Claude Connectors Directory surface (`mcp.clipform.io/forms`) is
|
|
8
|
+
* account + forms only: no media generation and no research helpers. A
|
|
9
|
+
* workflow that still says "call clipform_generate_tts" there sends the model
|
|
10
|
+
* at a tool that doesn't exist, which shows up in review as failed tool
|
|
11
|
+
* calls. Every guidance producer takes a ServerCaps and gates on it.
|
|
12
|
+
*/
|
|
13
|
+
interface ServerCaps {
|
|
14
|
+
/** Narration, video, image, music, render, and asset tools are registered. */
|
|
15
|
+
media: boolean;
|
|
16
|
+
/** News lookup and the generation audit log are registered. */
|
|
17
|
+
research: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type { ServerCaps as S };
|
|
@@ -2,9 +2,10 @@ import {
|
|
|
2
2
|
ALL_VARIANTS,
|
|
3
3
|
FORM_TYPES,
|
|
4
4
|
FORM_TYPE_KEYS,
|
|
5
|
+
FULL_CAPS,
|
|
5
6
|
callApi,
|
|
6
7
|
getSessionContext
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-O35IVA4L.js";
|
|
8
9
|
|
|
9
10
|
// src/lib/guides.ts
|
|
10
11
|
var guidesPromise = null;
|
|
@@ -42,6 +43,14 @@ function guideFallbackText(uri) {
|
|
|
42
43
|
`forms tight - every question must earn its place.`
|
|
43
44
|
].join("\n");
|
|
44
45
|
}
|
|
46
|
+
function applyCapsToGuide(text, caps) {
|
|
47
|
+
if (caps.media) return text;
|
|
48
|
+
return [
|
|
49
|
+
"> **This connection exposes form-building tools only** - no narration, video, image, or music tools. Where this guide mentions narration, media, or rendering, skip that part and carry the same craft into the written question text.",
|
|
50
|
+
"",
|
|
51
|
+
text
|
|
52
|
+
].join("\n");
|
|
53
|
+
}
|
|
45
54
|
|
|
46
55
|
// src/resources.ts
|
|
47
56
|
var GUIDE_TYPES = FORM_TYPE_KEYS;
|
|
@@ -62,10 +71,10 @@ function getGuideUri(type, variant) {
|
|
|
62
71
|
}
|
|
63
72
|
return `clipform://guides/${type}`;
|
|
64
73
|
}
|
|
65
|
-
async function readGuide(uri) {
|
|
66
|
-
return await fetchGuideText(uri) ?? guideFallbackText(uri);
|
|
74
|
+
async function readGuide(uri, caps) {
|
|
75
|
+
return applyCapsToGuide(await fetchGuideText(uri) ?? guideFallbackText(uri), caps);
|
|
67
76
|
}
|
|
68
|
-
function registerResources(server) {
|
|
77
|
+
function registerResources(server, caps = FULL_CAPS) {
|
|
69
78
|
for (const type of GUIDE_TYPES) {
|
|
70
79
|
server.registerResource(
|
|
71
80
|
`guide-${type}`,
|
|
@@ -79,7 +88,7 @@ function registerResources(server) {
|
|
|
79
88
|
contents: [{
|
|
80
89
|
uri: getGuideUri(type),
|
|
81
90
|
mimeType: "text/markdown",
|
|
82
|
-
text: await readGuide(getGuideUri(type))
|
|
91
|
+
text: await readGuide(getGuideUri(type), caps)
|
|
83
92
|
}]
|
|
84
93
|
})
|
|
85
94
|
);
|
|
@@ -97,7 +106,7 @@ function registerResources(server) {
|
|
|
97
106
|
contents: [{
|
|
98
107
|
uri: getGuideUri("quiz", variant),
|
|
99
108
|
mimeType: "text/markdown",
|
|
100
|
-
text: await readGuide(getGuideUri("quiz", variant))
|
|
109
|
+
text: await readGuide(getGuideUri("quiz", variant), caps)
|
|
101
110
|
}]
|
|
102
111
|
})
|
|
103
112
|
);
|
|
@@ -128,9 +137,10 @@ function registerResources(server) {
|
|
|
128
137
|
export {
|
|
129
138
|
fetchGuideText,
|
|
130
139
|
guideFallbackText,
|
|
140
|
+
applyCapsToGuide,
|
|
131
141
|
GUIDE_TYPES,
|
|
132
142
|
QUIZ_VARIANTS,
|
|
133
143
|
getGuideUri,
|
|
134
144
|
registerResources
|
|
135
145
|
};
|
|
136
|
-
//# sourceMappingURL=chunk-
|
|
146
|
+
//# sourceMappingURL=chunk-A5RVUIGS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/guides.ts","../src/resources.ts"],"sourcesContent":["import { callApi } from \"./api-client.js\";\nimport type { ServerCaps } from \"./caps.js\";\n\n/**\n * Craft guide bodies live server-side (#470) - the npm package is a shim\n * that fetches them at runtime instead of bundling them in the tarball.\n * One fetch per process (all ~30KB of guides in a single response), cached;\n * a failed fetch is NOT cached so the next read retries.\n */\n\nexport interface RemoteGuide {\n type: string;\n variant: string | null;\n uri: string;\n mimeType: string;\n text: string;\n}\n\nlet guidesPromise: Promise<Map<string, RemoteGuide>> | null = null;\n\nasync function loadGuides(): Promise<Map<string, RemoteGuide>> {\n const result = await callApi(\"/internal/mcp/guides\", { method: \"GET\" });\n if (!result.ok) {\n throw new Error(`Failed to load guides: ${result.error}`);\n }\n const guides = (result.data as { guides?: RemoteGuide[] }).guides ?? [];\n return new Map(guides.map((g) => [g.uri, g]));\n}\n\n/** Fetch a guide body by its clipform:// URI. Returns null when unavailable. */\nexport async function fetchGuideText(uri: string): Promise<string | null> {\n if (!guidesPromise) {\n guidesPromise = loadGuides();\n }\n try {\n const guides = await guidesPromise;\n return guides.get(uri)?.text ?? null;\n } catch (err) {\n guidesPromise = null; // don't cache failures - retry on the next read\n // Loud, not silent: a misconfigured API_URL/key otherwise degrades every\n // guide to the stub with nothing in the logs.\n console.error(`[guides] Failed to fetch ${uri}: ${err instanceof Error ? err.message : String(err)}`);\n return null;\n }\n}\n\n/** Shown in place of a guide when the API is unreachable or unauthenticated. */\nexport function guideFallbackText(uri: string): string {\n return [\n `# Guide unavailable`,\n ``,\n `The craft guide (${uri}) could not be loaded from the Clipform API.`,\n `Guides are served at runtime and need a reachable API with a valid key -`,\n `check API_URL and CLIPFORM_API_KEY, then try again.`,\n ``,\n `General principles in the meantime: write narration for the ear (short,`,\n `conversational), never reveal answers in narration or media, and keep`,\n `forms tight - every question must earn its place.`,\n ].join(\"\\n\");\n}\n\n/**\n * Craft guide bodies are written for the full tool surface and mention the\n * narration/video tools by name. On a surface that doesn't register them\n * (the Claude Connectors Directory resource, #3681) prefix the guide with a\n * note so the model doesn't chase tools it can't call. The body itself is\n * untouched - the craft (question design, pacing) is the same either way.\n */\nexport function applyCapsToGuide(text: string, caps: ServerCaps): string {\n if (caps.media) return text;\n return [\n \"> **This connection exposes form-building tools only** - no narration, video, image, or music tools. Where this guide mentions narration, media, or rendering, skip that part and carry the same craft into the written question text.\",\n \"\",\n text,\n ].join(\"\\n\");\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { getSessionContext } from \"./lib/session-context.js\";\nimport { FORM_TYPE_KEYS, FORM_TYPES, ALL_VARIANTS } from \"@vid-master/config\";\n\nexport const GUIDE_TYPES = FORM_TYPE_KEYS as readonly string[] as readonly [string, ...string[]];\nexport type GuideType = (typeof FORM_TYPE_KEYS)[number];\n\nexport const QUIZ_VARIANTS = ALL_VARIANTS as readonly string[] as readonly [string, ...string[]];\nexport type QuizVariant = (typeof ALL_VARIANTS)[number];\n// Guide BODIES are not bundled here (#470): the npm tarball ships only this\n// registration metadata. Text is fetched from the API at runtime - see\n// lib/guides.ts (cached per process, stub fallback when unreachable).\nimport { fetchGuideText, guideFallbackText, applyCapsToGuide } from \"./lib/guides.js\";\nimport { FULL_CAPS, type ServerCaps } from \"./lib/caps.js\";\n\nconst GUIDE_DESCRIPTIONS: Record<GuideType, string> = {\n \"quiz\": \"Craft knowledge for writing engaging quizzes - difficulty curves, question psychology, narration style, scoring\",\n \"survey\": \"Craft knowledge for feedback surveys, NPS, and research forms - brevity, rating scales, respondent fatigue\",\n \"interview\": \"Craft knowledge for building interview forms - warm-up pacing, open questions, consent, video responses\",\n \"funnel\": \"Craft knowledge for lead qualification funnels - planned feature, conditional routing coming soon\",\n \"testimonial\": \"Craft knowledge for collecting testimonials and customer stories on video - storytelling prompts, comfort techniques, consent\",\n \"application\": \"Craft knowledge for application and evaluation forms - multi-section structure, video responses for behavioural questions, screening\",\n \"booking\": \"Craft knowledge for event registration and booking forms - minimal friction, video welcome, confirmation flow\",\n};\n\n// Sourced from config (single source of truth) so the agent-facing resource\n// descriptions can't drift from FORM_TYPES.quiz.variant_descriptions (#2534,\n// the exact pair packages/config/CLAUDE.md warns about).\nconst QUIZ_VARIANT_DESCRIPTIONS = FORM_TYPES.quiz.variant_descriptions;\n\nexport function getGuideUri(type: GuideType, variant?: QuizVariant): string {\n if (type === \"quiz\" && variant) {\n return `clipform://guides/quiz/${variant}`;\n }\n return `clipform://guides/${type}`;\n}\n\nasync function readGuide(uri: string, caps: ServerCaps): Promise<string> {\n return applyCapsToGuide((await fetchGuideText(uri)) ?? guideFallbackText(uri), caps);\n}\n\nexport function registerResources(server: McpServer, caps: ServerCaps = FULL_CAPS) {\n for (const type of GUIDE_TYPES) {\n server.registerResource(\n `guide-${type}`,\n getGuideUri(type),\n {\n description: GUIDE_DESCRIPTIONS[type],\n mimeType: \"text/markdown\",\n annotations: { audience: [\"assistant\" as const], priority: 0.8 },\n },\n async () => ({\n contents: [{\n uri: getGuideUri(type),\n mimeType: \"text/markdown\",\n text: await readGuide(getGuideUri(type), caps),\n }],\n }),\n );\n }\n\n for (const variant of QUIZ_VARIANTS) {\n server.registerResource(\n `guide-quiz-${variant}`,\n getGuideUri(\"quiz\", variant),\n {\n description: QUIZ_VARIANT_DESCRIPTIONS[variant],\n mimeType: \"text/markdown\",\n annotations: { audience: [\"assistant\" as const], priority: 0.8 },\n },\n async () => ({\n contents: [{\n uri: getGuideUri(\"quiz\", variant),\n mimeType: \"text/markdown\",\n text: await readGuide(getGuideUri(\"quiz\", variant), caps),\n }],\n }),\n );\n }\n\n server.registerResource(\n \"context-session\",\n \"clipform://context/session\",\n {\n description:\n \"Current session info: auth mode, workspace name, plan name, and node/form limits. Read this before planning content to know your constraints.\",\n mimeType: \"text/markdown\",\n annotations: { audience: [\"assistant\"], priority: 1.0 },\n },\n async () => {\n const text = await getSessionContext();\n return {\n contents: [\n {\n uri: \"clipform://context/session\",\n mimeType: \"text/markdown\",\n text: text || \"Session context unavailable - API may not be reachable.\",\n },\n ],\n };\n }\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -6,20 +6,22 @@ import {
|
|
|
6
6
|
getWorkflowText,
|
|
7
7
|
objectType,
|
|
8
8
|
registerPrompts
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-QZO6MGNN.js";
|
|
10
10
|
import {
|
|
11
11
|
GUIDE_TYPES,
|
|
12
12
|
QUIZ_VARIANTS,
|
|
13
|
+
applyCapsToGuide,
|
|
13
14
|
fetchGuideText,
|
|
14
15
|
getGuideUri,
|
|
15
16
|
guideFallbackText,
|
|
16
17
|
registerResources
|
|
17
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-A5RVUIGS.js";
|
|
18
19
|
import {
|
|
19
20
|
ACTIVE_NODE_TYPES,
|
|
20
21
|
CONTACT_FIELDS,
|
|
21
22
|
FEATURE_FLAGS,
|
|
22
23
|
FORM_TYPE_ALIASES,
|
|
24
|
+
FULL_CAPS,
|
|
23
25
|
KEN_BURNS_EFFECTS,
|
|
24
26
|
KEN_BURNS_FIT_MODES,
|
|
25
27
|
KEN_BURNS_PRESETS,
|
|
@@ -30,13 +32,14 @@ import {
|
|
|
30
32
|
SLIDESHOW_TRANSITIONS,
|
|
31
33
|
bfsOrder,
|
|
32
34
|
callApi,
|
|
35
|
+
capsFromToolsets,
|
|
33
36
|
defaultTarget,
|
|
34
37
|
errorResult,
|
|
35
38
|
exposedCompositionIds,
|
|
36
39
|
resolveFormType,
|
|
37
40
|
structuredResult,
|
|
38
41
|
textResult
|
|
39
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-O35IVA4L.js";
|
|
40
43
|
import {
|
|
41
44
|
getMcpAuth,
|
|
42
45
|
runWithMcpTool
|
|
@@ -20456,7 +20459,7 @@ mainlandOnly excludes small islands and overseas territories (e.g. Corsica for F
|
|
|
20456
20459
|
}
|
|
20457
20460
|
|
|
20458
20461
|
// src/tools/get-guide.ts
|
|
20459
|
-
function registerGetGuideTool(server) {
|
|
20462
|
+
function registerGetGuideTool(server, caps = FULL_CAPS) {
|
|
20460
20463
|
const aliasHint = Object.entries(FORM_TYPE_ALIASES).map(([alias, target]) => `${alias} \u2192 ${target}`).join(", ");
|
|
20461
20464
|
server.registerTool(
|
|
20462
20465
|
"clipform_get_guide",
|
|
@@ -20491,7 +20494,7 @@ Quiz variants (optional): ${QUIZ_VARIANTS.join(", ")} - appends variant-specific
|
|
|
20491
20494
|
const type = resolved;
|
|
20492
20495
|
const validVariant = type === "quiz" ? variant : void 0;
|
|
20493
20496
|
const uri = getGuideUri(type, validVariant);
|
|
20494
|
-
const content = await fetchGuideText(uri) ?? guideFallbackText(uri);
|
|
20497
|
+
const content = applyCapsToGuide(await fetchGuideText(uri) ?? guideFallbackText(uri), caps);
|
|
20495
20498
|
return {
|
|
20496
20499
|
content: [{
|
|
20497
20500
|
type: "resource",
|
|
@@ -20507,7 +20510,7 @@ Quiz variants (optional): ${QUIZ_VARIANTS.join(", ")} - appends variant-specific
|
|
|
20507
20510
|
}
|
|
20508
20511
|
|
|
20509
20512
|
// src/tools/get-workflow.ts
|
|
20510
|
-
function registerGetWorkflowTool(server) {
|
|
20513
|
+
function registerGetWorkflowTool(server, caps = FULL_CAPS) {
|
|
20511
20514
|
const aliasHint = Object.entries(FORM_TYPE_ALIASES).map(([alias, target]) => `${alias} \u2192 ${target}`).join(", ");
|
|
20512
20515
|
server.registerTool(
|
|
20513
20516
|
"clipform_get_workflow",
|
|
@@ -20567,7 +20570,7 @@ Optional args by type:
|
|
|
20567
20570
|
}
|
|
20568
20571
|
const type = resolved;
|
|
20569
20572
|
const validVariant = type === "quiz" ? variant : void 0;
|
|
20570
|
-
const text = await getWorkflowText(type, args, validVariant);
|
|
20573
|
+
const text = await getWorkflowText(type, args, validVariant, caps);
|
|
20571
20574
|
return textResult(text);
|
|
20572
20575
|
}
|
|
20573
20576
|
);
|
|
@@ -20577,29 +20580,26 @@ Optional args by type:
|
|
|
20577
20580
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20578
20581
|
var pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
|
|
20579
20582
|
var MCP_VERSION = pkg.version;
|
|
20583
|
+
var MCP_SERVER_IDENTITY = Object.freeze({
|
|
20584
|
+
name: "clipform-mcp-server",
|
|
20585
|
+
version: MCP_VERSION
|
|
20586
|
+
});
|
|
20587
|
+
function buildInstructions(caps) {
|
|
20588
|
+
return [
|
|
20589
|
+
"Clipform builds interactive video-style forms. When the brief is clear, build the form directly; when it's vague, ask one or two short questions first.",
|
|
20590
|
+
caps.media && "Prefer rich media: video over images over plain text.",
|
|
20591
|
+
caps.media ? "Before building, derive a register from the topic and audience (e.g. hype, playful, warm, considered, elegant, sombre); if the user states a mood explicitly, that wins. State the register once, then apply it to every rendering choice - narration tone, motion preset, music, pacing. Never mix registers in one form." : "Before building, derive a register from the topic and audience (e.g. hype, playful, warm, considered, elegant, sombre); if the user states a mood explicitly, that wins. State the register once, then apply it to every question, option, and end-screen line. Never mix registers in one form.",
|
|
20592
|
+
"At the start of a build, call clipform_get_workflow to load the recipe for the form type, and clipform_get_guide for craft detail.",
|
|
20593
|
+
"Every *_id argument is a UUID returned by the tools - not the short share_id from a form URL.",
|
|
20594
|
+
"For an account-scoped request, call clipform_whoami first to confirm the active workspace and plan.",
|
|
20595
|
+
caps.media ? "Deleting a form, node, or its media is permanent; those tools ask the user to confirm before running." : "Deleting a form or node is permanent; those tools ask the user to confirm before running."
|
|
20596
|
+
].filter((line) => typeof line === "string").join(" ");
|
|
20597
|
+
}
|
|
20580
20598
|
function createServer(options) {
|
|
20599
|
+
const caps = capsFromToolsets(options?.toolsets);
|
|
20581
20600
|
const server = new McpServer(
|
|
20582
|
-
{
|
|
20583
|
-
|
|
20584
|
-
version: MCP_VERSION
|
|
20585
|
-
},
|
|
20586
|
-
{
|
|
20587
|
-
// Lands directly in the client's system prompt. This is the only
|
|
20588
|
-
// high-level guidance external clients (claude.ai, Desktop, ChatGPT App)
|
|
20589
|
-
// receive - they have no equivalent of the bot's system prompt. It is
|
|
20590
|
-
// also the correct home for cross-tool / sequencing guidance, which must
|
|
20591
|
-
// NOT go in individual tool descriptions (treated as prompt injection at
|
|
20592
|
-
// directory review).
|
|
20593
|
-
instructions: [
|
|
20594
|
-
"Clipform builds interactive video-style forms. When the brief is clear, build the form directly; when it's vague, ask one or two short questions first.",
|
|
20595
|
-
"Prefer rich media: video over images over plain text.",
|
|
20596
|
-
"Before building, derive a register from the topic and audience (e.g. hype, playful, warm, considered, elegant, sombre); if the user states a mood explicitly, that wins. State the register once, then apply it to every rendering choice - narration tone, motion preset, music, pacing. Never mix registers in one form.",
|
|
20597
|
-
"At the start of a build, call clipform_get_workflow to load the recipe for the form type, and clipform_get_guide for craft detail.",
|
|
20598
|
-
"Every *_id argument is a UUID returned by the tools - not the short share_id from a form URL.",
|
|
20599
|
-
"For an account-scoped request, call clipform_whoami first to confirm the active workspace and plan.",
|
|
20600
|
-
"Deleting a form, node, or its media is permanent; those tools ask the user to confirm before running."
|
|
20601
|
-
].join(" ")
|
|
20602
|
-
}
|
|
20601
|
+
{ ...MCP_SERVER_IDENTITY },
|
|
20602
|
+
{ instructions: buildInstructions(caps) }
|
|
20603
20603
|
);
|
|
20604
20604
|
const _registerTool = server.registerTool.bind(server);
|
|
20605
20605
|
server.registerTool = (name, config2, handler) => {
|
|
@@ -20658,16 +20658,18 @@ function createServer(options) {
|
|
|
20658
20658
|
registerListAssetsTool(server);
|
|
20659
20659
|
registerCheckRenderTool(server);
|
|
20660
20660
|
registerFetchBoundaryTool(server);
|
|
20661
|
-
registerGetGuideTool(server);
|
|
20662
|
-
registerGetWorkflowTool(server);
|
|
20663
|
-
registerPrompts(server);
|
|
20664
|
-
registerResources(server);
|
|
20661
|
+
registerGetGuideTool(server, caps);
|
|
20662
|
+
registerGetWorkflowTool(server, caps);
|
|
20663
|
+
registerPrompts(server, caps);
|
|
20664
|
+
registerResources(server, caps);
|
|
20665
20665
|
return server;
|
|
20666
20666
|
}
|
|
20667
20667
|
|
|
20668
20668
|
export {
|
|
20669
20669
|
JSONRPCMessageSchema,
|
|
20670
20670
|
RENDER_TIMING,
|
|
20671
|
+
MCP_SERVER_IDENTITY,
|
|
20672
|
+
buildInstructions,
|
|
20671
20673
|
createServer
|
|
20672
20674
|
};
|
|
20673
|
-
//# sourceMappingURL=chunk-
|
|
20675
|
+
//# sourceMappingURL=chunk-EMQPJPF4.js.map
|